From 54c2e8ec0bc85a2c65b9172f046e2c4e8b3cffd0 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Sat, 24 Feb 2024 13:48:57 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20add=20`hideValues`?= =?UTF-8?q?=20prop=20to=20hide=20the=20values=20when=20on=20multiple?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/shared/Select/Select.theme.ts | 16 +- .../src/components/shared/Select/Select.tsx | 52 ++-- .../frontend/src/pages/components/index.tsx | 9 + .../src/pages/components/renders/dropdown.tsx | 240 ++++++++++++++++++ 4 files changed, 294 insertions(+), 23 deletions(-) create mode 100644 packages/frontend/src/pages/components/renders/dropdown.tsx diff --git a/packages/frontend/src/components/shared/Select/Select.theme.ts b/packages/frontend/src/components/shared/Select/Select.theme.ts index a0324fd1..43d4b0f4 100644 --- a/packages/frontend/src/components/shared/Select/Select.theme.ts +++ b/packages/frontend/src/components/shared/Select/Select.theme.ts @@ -34,7 +34,7 @@ export const selectTheme = tv({ ], icon: ['text-elements-mid-em'], helperIcon: [], - helperText: ['flex', 'gap-2', 'items-center', 'text-elements-danger'], + helperText: ['flex', 'gap-2', 'items-center', 'text-elements-low-em'], popover: [ 'z-20', 'absolute', @@ -70,12 +70,8 @@ export const selectTheme = tv({ container: [], }, }, - state: { - default: { - inputWrapper: '', - helperText: ['text-elements-low-em'], - }, - error: { + error: { + true: { inputWrapper: [ 'outline', 'outline-offset-0', @@ -121,6 +117,11 @@ export const selectTheme = tv({ input: ['cursor-pointer'], }, }, + hideValues: { + true: { + input: ['placeholder:text-elements-mid-em'], + }, + }, }, compoundVariants: [ { @@ -143,6 +144,7 @@ export const selectTheme = tv({ variant: 'default', size: 'md', state: 'default', + error: false, isOpen: false, hasValue: false, }, diff --git a/packages/frontend/src/components/shared/Select/Select.tsx b/packages/frontend/src/components/shared/Select/Select.tsx index a8debbb4..02e1eab3 100644 --- a/packages/frontend/src/components/shared/Select/Select.tsx +++ b/packages/frontend/src/components/shared/Select/Select.tsx @@ -91,6 +91,10 @@ interface SelectProps * The helper text of the select */ helperText?: string; + /** + * Show the values of the select if it's multiple + */ + hideValues?: boolean; } export const Select = ({ @@ -99,7 +103,7 @@ export const Select = ({ searchable = false, clearable, size, - state, + error, orientation = 'horizontal', variant, label, @@ -107,9 +111,10 @@ export const Select = ({ leftIcon, rightIcon, helperText, + hideValues = false, placeholder: placeholderProp = 'Select an option', }: SelectProps) => { - const theme = selectTheme({ size, state, variant, orientation }); + const theme = selectTheme({ size, error, variant, orientation }); const [inputValue, setInputValue] = useState(''); const [selectedItem, setSelectedItem] = useState(null); @@ -273,20 +278,28 @@ export const Select = ({ const renderHelperText = useMemo( () => (
- {state === 'error' && + {error && cloneIcon(, { 'aria-hidden': true, })}

{helperText}

), - [cloneIcon, state, theme, helperText], + [cloneIcon, error, theme, helperText], ); const isMultipleHasValue = multiple && selectedItems.length > 0; const isMultipleHasValueButNotSearchable = multiple && !searchable && selectedItems.length > 0; - const placeholder = isMultipleHasValueButNotSearchable ? '' : placeholderProp; + const displayPlaceholder = useMemo(() => { + if (hideValues && isMultipleHasValue) { + return `${selectedItems.length} selected`; + } + if (isMultipleHasValueButNotSearchable) { + return ''; + } + return placeholderProp; + }, [hideValues, multiple, selectedItems.length, placeholderProp]); return (
@@ -297,7 +310,7 @@ export const Select = ({
!dropdownOpen && openMenu()} > @@ -306,6 +319,7 @@ export const Select = ({ {/* Multiple input values */} {isMultipleHasValue && + !hideValues && selectedItems.map((item, index) => ( 0, + }), + { + // Make the input width smaller because we don't need it (not searchable) + 'w-6': isMultipleHasValueButNotSearchable && !hideValues, + // Add margin to the X icon + 'ml-6': isMultipleHasValueButNotSearchable && clearable, + }, + )} /> {/* Right icon */} @@ -339,12 +359,12 @@ export const Select = ({ {/* Popover */}
    {
    + {/* Dropdown */} +
    +

    Dropdown / Select

    + {renderDropdowns()} +
    + +
    + {/* Inline notification */}

    Inline Notification

    diff --git a/packages/frontend/src/pages/components/renders/dropdown.tsx b/packages/frontend/src/pages/components/renders/dropdown.tsx new file mode 100644 index 00000000..127cc4f9 --- /dev/null +++ b/packages/frontend/src/pages/components/renders/dropdown.tsx @@ -0,0 +1,240 @@ +import React from 'react'; +import { PencilIcon } from 'components/shared/CustomIcon'; +import { SelectOption, Select } from 'components/shared/Select'; + +export const DROPDOWN_ITEMS: SelectOption[] = [ + { + value: 'apple', + label: 'Apple', + description: 'Apple is fruit', + leftIcon: , + }, + { + value: 'banana', + label: 'Banana', + description: 'Banana is fruit', + leftIcon: , + }, + { + value: 'orange', + label: 'Orange', + description: 'Orange is fruit', + leftIcon: , + }, + { + value: 'watermelon', + label: 'Watermelon', + description: 'Watermelon is fruit', + disabled: true, + leftIcon: , + }, +]; + +export const renderDropdowns = () => ( + <> +

    Single – Small

    +
    + + +
    +

    Single – Medium

    +
    + + +
    +

    Multiple – Small

    +
    + + + + + +
    +

    + Single – With label, description, and helper text +

    +
    + + +
    +

    + Multiple – With label, description, and helper text +

    +
    + + +
    +

    + Error – With label, description, and helper text +

    +
    + + +
    + +);