️ feat: separate select value to be a component

This commit is contained in:
Wahyu Kurniawan 2024-02-24 11:38:32 +07:00
parent 3bca06b590
commit 5d0dd93271
No known key found for this signature in database
GPG Key ID: 040A1549143A8E33
3 changed files with 91 additions and 0 deletions

View File

@ -0,0 +1,30 @@
import { tv, VariantProps } from 'tailwind-variants';
export const selectValueTheme = tv({
slots: {
wrapper: [
'flex',
'items-center',
'gap-1',
'pl-2',
'pr-2',
'rounded-md',
'text-elements-mid-em',
'bg-base-bg-emphasized',
'hover:bg-base-bg-emphasized/80',
],
icon: ['h-3.5', 'w-3.5'],
},
variants: {
size: {
sm: {
wrapper: ['pl-1', 'pr-0.5', 'gap-0.5'],
},
md: {
wrapper: ['pl-2', 'pr-1', 'gap-1'],
},
},
},
});
export type SelectValueTheme = VariantProps<typeof selectValueTheme>;

View File

@ -0,0 +1,60 @@
import React, { ComponentPropsWithoutRef } from 'react';
import {
Overwrite,
UseMultipleSelectionGetSelectedItemReturnValue,
} from 'downshift';
import { SelectValueTheme, selectValueTheme } from './SelectValue.theme';
import { OmitCommon } from 'types/common';
import { SelectOption } from 'components/shared/Select';
import { Button } from 'components/shared/Button';
import { CrossIcon } from 'components/shared/CustomIcon';
type MergedComponentPropsWithoutRef = OmitCommon<
ComponentPropsWithoutRef<'span'>,
Omit<
Overwrite<UseMultipleSelectionGetSelectedItemReturnValue, SelectOption[]>,
'index' | 'selectedItem'
>
>;
export interface SelectValueProps
extends MergedComponentPropsWithoutRef,
SelectValueTheme {
/**
* The option of the select value
*/
option: SelectOption;
/**
* The function to call when the delete button is clicked
* @param item
* @returns none;
*/
onDelete?: (item: SelectOption) => void;
}
/**
* The SelectValue component is used to display the selected value of a select component
*/
export const SelectValue = ({
className,
size,
option,
onDelete,
...props
}: SelectValueProps) => {
const theme = selectValueTheme();
return (
<span {...props} className={theme.wrapper({ className, size })}>
{option.label}
<Button
onClick={() => onDelete?.(option)}
iconOnly
variant="unstyled"
size="xs"
>
<CrossIcon className={theme.icon()} />
</Button>
</span>
);
};

View File

@ -0,0 +1 @@
export * from './SelectValue';