🐛 fix: forward ref the component to fix console error

This commit is contained in:
Wahyu Kurniawan 2024-02-24 13:48:20 +07:00
parent d181e6ba98
commit 410def0750
No known key found for this signature in database
GPG Key ID: 040A1549143A8E33
2 changed files with 81 additions and 69 deletions

View File

@ -1,4 +1,4 @@
import React, { ComponentPropsWithoutRef, useMemo } from 'react'; import React, { forwardRef, ComponentPropsWithoutRef, useMemo } from 'react';
import { Overwrite, UseComboboxGetItemPropsReturnValue } from 'downshift'; import { Overwrite, UseComboboxGetItemPropsReturnValue } from 'downshift';
import { SelectOption, SelectOrientation } from 'components/shared/Select'; import { SelectOption, SelectOrientation } from 'components/shared/Select';
import { selectItemTheme, SelectItemTheme } from './SelectItem.theme'; import { selectItemTheme, SelectItemTheme } from './SelectItem.theme';
@ -29,58 +29,70 @@ export interface SelectItemProps
empty?: boolean; empty?: boolean;
} }
export const SelectItem = ({ const SelectItem = forwardRef<HTMLLIElement, SelectItemProps>(
className, (
selected, {
option, className,
orientation, selected,
hovered, option,
empty, orientation,
variant, hovered,
...props empty,
}: SelectItemProps) => { variant,
const theme = selectItemTheme({ active: hovered, orientation, variant }); ...props
},
ref,
) => {
const theme = selectItemTheme({ active: hovered, orientation, variant });
const { label, description, leftIcon, rightIcon, disabled } = option; const { label, description, leftIcon, rightIcon, disabled } = option;
const renderRightIcon = useMemo(() => { const renderRightIcon = useMemo(() => {
if (rightIcon) { if (rightIcon) {
return cloneIcon(rightIcon, { className: theme.icon() }); return cloneIcon(rightIcon, { className: theme.icon() });
} else if (selected) { } else if (selected) {
return (
<CheckRadioIcon
className={cn(theme.icon(), 'text-controls-primary')}
/>
);
}
return null;
}, [rightIcon]);
if (empty) {
return ( return (
<CheckRadioIcon className={cn(theme.icon(), 'text-controls-primary')} /> <li {...props} className={theme.wrapper()}>
No results found
</li>
); );
} }
return null;
}, [rightIcon]);
if (empty) {
return ( return (
<li {...props} className={theme.wrapper()}> <li
No results found {...props}
ref={ref}
className={theme.wrapper({ className })}
data-disabled={disabled}
>
{leftIcon && cloneIcon(leftIcon, { className: theme.icon() })}
<div className={theme.content()}>
<p className={theme.label()} data-disabled={disabled}>
{label}
</p>
{orientation === 'horizontal' && <span className={theme.dot()} />}
{description && (
<p className={theme.description()} data-disabled={disabled}>
{description}
</p>
)}
</div>
{renderRightIcon}
</li> </li>
); );
} },
);
return ( SelectItem.displayName = 'SelectItem';
<li
{...props} export { SelectItem };
className={theme.wrapper({ className })}
data-disabled={disabled}
>
{leftIcon && cloneIcon(leftIcon, { className: theme.icon() })}
<div className={theme.content()}>
<p className={theme.label()} data-disabled={disabled}>
{label}
</p>
{orientation === 'horizontal' && <span className={theme.dot()} />}
{description && (
<p className={theme.description()} data-disabled={disabled}>
{description}
</p>
)}
</div>
{renderRightIcon}
</li>
);
};

View File

@ -1,4 +1,4 @@
import React, { ComponentPropsWithoutRef } from 'react'; import React, { forwardRef, ComponentPropsWithoutRef } from 'react';
import { import {
Overwrite, Overwrite,
UseMultipleSelectionGetSelectedItemReturnValue, UseMultipleSelectionGetSelectedItemReturnValue,
@ -35,26 +35,26 @@ export interface SelectValueProps
/** /**
* The SelectValue component is used to display the selected value of a select component * The SelectValue component is used to display the selected value of a select component
*/ */
export const SelectValue = ({ const SelectValue = forwardRef<HTMLSpanElement, SelectValueProps>(
className, ({ className, size, option, onDelete, ...props }, ref) => {
size, const theme = selectValueTheme();
option,
onDelete,
...props
}: SelectValueProps) => {
const theme = selectValueTheme();
return ( return (
<span {...props} className={theme.wrapper({ className, size })}> <span {...props} ref={ref} className={theme.wrapper({ className, size })}>
{option.label} {option.label}
<Button <Button
onClick={() => onDelete?.(option)} onClick={() => onDelete?.(option)}
iconOnly iconOnly
variant="unstyled" variant="unstyled"
size="xs" size="xs"
> >
<CrossIcon className={theme.icon()} /> <CrossIcon className={theme.icon()} />
</Button> </Button>
</span> </span>
); );
}; },
);
SelectValue.displayName = 'SelectValue';
export { SelectValue };