mirror of https://github.com/acid-info/lsd.git
feat: add label element to Dropdown component and adjust styles
This commit is contained in:
parent
3369e8aaf2
commit
0a98af2441
|
@ -1,15 +1,18 @@
|
|||
export const dropdownClasses = {
|
||||
root: `lsd-dropdown`,
|
||||
|
||||
trigger: `lsd-dropdown-trigger`,
|
||||
triggerLabel: `lsd-dropdown-trigger__label`,
|
||||
triggerIcons: `lsd-dropdown-trigger-icons`,
|
||||
triggerIcon: `lsd-dropdown-trigger-icons__icon`,
|
||||
triggerMenuIcon: `lsd-dropdown-trigger-icons__menu-icon`,
|
||||
label: 'lsd-dropdown__label',
|
||||
buttonContainer: `lsd-dropdown__button-container`,
|
||||
|
||||
trigger: `lsd-dropdown__trigger`,
|
||||
triggerLabel: `lsd-dropdown__trigger-label`,
|
||||
triggerIcons: `lsd-dropdown__trigger-icons`,
|
||||
triggerIcon: `lsd-dropdown__trigger-icons__icon`,
|
||||
triggerMenuIcon: `lsd-dropdown__trigger-icons__menu-icon`,
|
||||
|
||||
supportingText: 'lsd-dropdown__supporting-text',
|
||||
|
||||
listBox: 'lsd-dropdown-list-box',
|
||||
listBox: 'lsd-dropdown__list-box',
|
||||
|
||||
open: 'lsd-dropdown--open',
|
||||
error: 'lsd-dropdown--error',
|
||||
|
|
|
@ -22,8 +22,9 @@ export const Root: Story<DropdownProps> = (args) => (
|
|||
)
|
||||
|
||||
Root.args = {
|
||||
id: 'cryptocurrency',
|
||||
size: 'large',
|
||||
label: 'Choose an option',
|
||||
triggerLabel: 'Choose an option',
|
||||
supportingText: '',
|
||||
disabled: false,
|
||||
error: false,
|
||||
|
@ -34,4 +35,5 @@ Root.args = {
|
|||
value: `${index}`,
|
||||
name: `Option ${index + 1}`,
|
||||
})),
|
||||
label: 'Cryptocurrency',
|
||||
}
|
||||
|
|
|
@ -19,13 +19,21 @@ export const DropdownStyles = css`
|
|||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.label} {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.${dropdownClasses.buttonContainer} {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.${dropdownClasses.trigger} {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 14px 10px 18px;
|
||||
border: none;
|
||||
|
||||
cursor: pointer;
|
||||
|
@ -48,11 +56,12 @@ export const DropdownStyles = css`
|
|||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
min-width: 60px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.${dropdownClasses.triggerIcon} {
|
||||
margin-right: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.${dropdownClasses.triggerMenuIcon} {
|
||||
|
@ -69,11 +78,9 @@ export const DropdownStyles = css`
|
|||
}
|
||||
|
||||
.${dropdownClasses.disabled} {
|
||||
.${dropdownClasses.trigger} {
|
||||
opacity: 0.34;
|
||||
cursor: initial;
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.listBox} {
|
||||
max-height: 400px;
|
||||
|
@ -90,23 +97,63 @@ export const DropdownStyles = css`
|
|||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.small} {
|
||||
.${dropdownClasses.large} {
|
||||
width: 208px;
|
||||
|
||||
.${dropdownClasses.label} {
|
||||
margin: 0 0 6px 18px;
|
||||
}
|
||||
|
||||
.${dropdownClasses.buttonContainer} {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.${dropdownClasses.trigger} {
|
||||
padding: 6px 10px;
|
||||
padding: 9px 17px;
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.medium} {
|
||||
width: 188px;
|
||||
|
||||
.${dropdownClasses.label} {
|
||||
margin: 0 0 6px 14px;
|
||||
}
|
||||
|
||||
.${dropdownClasses.buttonContainer} {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.${dropdownClasses.trigger} {
|
||||
padding: 6px 12px;
|
||||
padding: 5px 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.small} {
|
||||
width: 164px;
|
||||
|
||||
.${dropdownClasses.label} {
|
||||
margin: 0 0 6px 12px;
|
||||
}
|
||||
|
||||
.${dropdownClasses.buttonContainer} {
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.${dropdownClasses.trigger} {
|
||||
padding: 5px 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.outlined} {
|
||||
.${dropdownClasses.buttonContainer} {
|
||||
border: 1px solid rgb(var(--lsd-border-primary));
|
||||
}
|
||||
}
|
||||
|
||||
.${dropdownClasses.outlinedBottom} {
|
||||
.${dropdownClasses.buttonContainer} {
|
||||
border-bottom: 1px solid rgb(var(--lsd-border-primary));
|
||||
}
|
||||
}
|
||||
`
|
||||
|
|
|
@ -14,11 +14,12 @@ export type DropdownProps = Omit<
|
|||
React.HTMLAttributes<HTMLDivElement>,
|
||||
'label' | 'disabled' | 'value' | 'onChange'
|
||||
> & {
|
||||
label: string
|
||||
label?: React.ReactNode
|
||||
error?: boolean
|
||||
disabled?: boolean
|
||||
supportingText?: string
|
||||
size?: 'small' | 'medium' | 'large'
|
||||
triggerLabel: string
|
||||
|
||||
multi?: boolean
|
||||
options?: DropdownOption[]
|
||||
|
@ -35,6 +36,7 @@ export const Dropdown: React.FC<DropdownProps> & {
|
|||
error = false,
|
||||
disabled = false,
|
||||
supportingText,
|
||||
triggerLabel,
|
||||
|
||||
value = [],
|
||||
onChange,
|
||||
|
@ -43,7 +45,7 @@ export const Dropdown: React.FC<DropdownProps> & {
|
|||
variant = 'outlined',
|
||||
...props
|
||||
}) => {
|
||||
const ref = useRef<HTMLButtonElement>(null)
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const { select, isSelected, selected } = useSelect(options, value, {
|
||||
|
@ -62,8 +64,11 @@ export const Dropdown: React.FC<DropdownProps> & {
|
|||
if (disabled && open) setOpen(false)
|
||||
}, [open, disabled])
|
||||
|
||||
const buttonId = props?.id ?? (props.id || 'dropdown') + '-input'
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
{...props}
|
||||
className={clsx(
|
||||
props.className,
|
||||
|
@ -72,16 +77,25 @@ export const Dropdown: React.FC<DropdownProps> & {
|
|||
error && dropdownClasses.error,
|
||||
disabled && dropdownClasses.disabled,
|
||||
open && dropdownClasses.open,
|
||||
)}
|
||||
>
|
||||
<button
|
||||
ref={ref}
|
||||
className={clsx(
|
||||
dropdownClasses.trigger,
|
||||
variant === 'outlined'
|
||||
? dropdownClasses.outlined
|
||||
: dropdownClasses.outlinedBottom,
|
||||
)}
|
||||
>
|
||||
{label && (
|
||||
<Typography
|
||||
htmlFor={buttonId}
|
||||
className={dropdownClasses.label}
|
||||
variant="label2"
|
||||
component="label"
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
)}
|
||||
<div className={dropdownClasses.buttonContainer}>
|
||||
<button
|
||||
id={buttonId}
|
||||
className={clsx(dropdownClasses.trigger)}
|
||||
onClick={onTrigger}
|
||||
>
|
||||
<Typography
|
||||
|
@ -92,7 +106,7 @@ export const Dropdown: React.FC<DropdownProps> & {
|
|||
>
|
||||
{selected.length > 0
|
||||
? selected.map((opt) => opt.name).join(', ')
|
||||
: label}
|
||||
: triggerLabel}
|
||||
</Typography>
|
||||
<div className={dropdownClasses.triggerIcons}>
|
||||
{error && (
|
||||
|
@ -115,7 +129,7 @@ export const Dropdown: React.FC<DropdownProps> & {
|
|||
)}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
{supportingText && (
|
||||
<Typography
|
||||
variant={size === 'large' ? 'label1' : 'label2'}
|
||||
|
@ -128,7 +142,7 @@ export const Dropdown: React.FC<DropdownProps> & {
|
|||
|
||||
<Portal id="dropdown">
|
||||
<ListBox
|
||||
handleRef={ref}
|
||||
handleRef={containerRef}
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
className={dropdownClasses.listBox}
|
||||
|
|
Loading…
Reference in New Issue