refactor: rename listbox to dropdown menu and apply it to autocomplete

This commit is contained in:
jinhojang6 2023-04-11 07:51:13 +09:00 committed by jeangovil
parent 724ac50229
commit 7ebdd00ff5
15 changed files with 84 additions and 63 deletions

View File

@ -6,7 +6,6 @@ export const autocompleteClasses = {
input: `lsd-autocomplete__input`,
icon: `lsd-autocomplete__icon`,
listBox: `lsd-autocomplete__list-box`,
dropdownItem: `lsd-autocomplete__dropdown-item`,
dropdownItemPlaceholder: `lsd-autocomplete__dropdown-item-placeholder`,

View File

@ -119,13 +119,6 @@ export const AutocompleteStyles = css`
border-bottom: 1px solid rgb(var(--lsd-border-primary));
}
.${autocompleteClasses.listBox} {
max-height: 400px;
overflow: auto;
border: 1px solid rgb(var(--lsd-border-primary));
border-top: 0;
}
.${autocompleteClasses.dropdownItem} {
border: 0;

View File

@ -3,7 +3,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'
import { useInput } from '../../utils/useInput'
import { DropdownItem } from '../DropdownItem'
import { CloseIcon, SearchIcon } from '../Icons'
import { ListBox } from '../ListBox'
import { DropdownMenu } from '../DropdownMenu'
import { Portal } from '../PortalProvider/Portal'
import { Typography } from '../Typography'
import { autocompleteClasses } from './Autocomplete.classes'
@ -136,11 +136,11 @@ export const Autocomplete: React.FC<AutocompleteProps> & {
) : null}
</div>
<Portal id="autocomplete">
<ListBox
<DropdownMenu
handleRef={containerRef}
open={isOpen}
onClose={() => setOpen(false)}
className={autocompleteClasses.listBox}
size={size}
>
{suggestions.map((opt, idx: number) => (
<DropdownItem
@ -162,7 +162,7 @@ export const Autocomplete: React.FC<AutocompleteProps> & {
}
/>
))}
</ListBox>
</DropdownMenu>
</Portal>
</div>
)

View File

@ -2,7 +2,7 @@ import clsx from 'clsx'
import React, { useEffect, useRef, useState } from 'react'
import { BreadcrumbItem } from '../BreadcrumbItem'
import { breadcrumbItemClasses } from '../BreadcrumbItem/BreadcrumbItem.classes'
import { ListBox } from '../ListBox'
import { DropdownMenu } from '../DropdownMenu'
import { Portal } from '../PortalProvider/Portal'
import { breadcrumbClasses } from './Breadcrumb.classes'
@ -94,7 +94,7 @@ export const Breadcrumb: React.FC<BreadcrumbProps> & {
</ul>
{ellipsisRef?.current != null && ellipsis && maxItems && (
<Portal id="breadcrumb">
<ListBox
<DropdownMenu
handleRef={ellipsisRef}
open={open}
onClose={() => setOpen(false)}
@ -109,7 +109,7 @@ export const Breadcrumb: React.FC<BreadcrumbProps> & {
linkComponent={opt?.linkComponent}
/>
))}
</ListBox>
</DropdownMenu>
</Portal>
)}
</div>

View File

@ -17,7 +17,7 @@ import { DropdownItemStyles } from '../DropdownItem/DropdownItem.styles'
import { IconButtonStyles } from '../IconButton/IconButton.styles'
import { IconButtonGroupStyles } from '../IconButtonGroup/IconButtonGroup.styles'
import { LsdIconStyles } from '../Icons/LsdIcon/LsdIcon.styles'
import { ListBoxStyles } from '../ListBox/ListBox.styles'
import { DropdownMenuStyles } from '../DropdownMenu/DropdownMenu.styles'
import { QuoteStyles } from '../Quote/Quote.styles'
import { RadioButtonStyles } from '../RadioButton/RadioButton.styles'
import { RadioButtonGroupStyles } from '../RadioButtonGroup/RadioButtonGroup.styles'
@ -42,7 +42,7 @@ const componentStyles: Array<ReturnType<typeof withTheme> | SerializedStyles> =
LsdIconStyles,
TabItemStyles,
TabsStyles,
ListBoxStyles,
DropdownMenuStyles,
DropdownStyles,
DropdownItemStyles,
BreadcrumbStyles,

View File

@ -3,7 +3,7 @@ import React, { useEffect, useRef, useState } from 'react'
import { SelectOption, useSelect } from '../../utils/useSelect'
import { DropdownItem } from '../DropdownItem'
import { ArrowDownIcon, ArrowUpIcon, ErrorIcon } from '../Icons'
import { ListBox } from '../ListBox'
import { DropdownMenu } from '../DropdownMenu'
import { Portal } from '../PortalProvider/Portal'
import { Typography } from '../Typography'
import { dropdownClasses } from './Dropdown.classes'
@ -138,11 +138,10 @@ export const Dropdown: React.FC<DropdownProps> & {
)}
<Portal id="dropdown">
<ListBox
<DropdownMenu
handleRef={containerRef}
open={open}
onClose={() => setOpen(false)}
className={dropdownClasses.listBox}
>
{options.map((opt) => (
<DropdownItem
@ -156,7 +155,7 @@ export const Dropdown: React.FC<DropdownProps> & {
onKeyDown={(e) => e.key === 'Enter' && select(opt)}
/>
))}
</ListBox>
</DropdownMenu>
</Portal>
</div>
)

View File

@ -10,7 +10,6 @@ export const DropdownItemStyles = css`
flex-direction: row;
align-items: center;
padding: 10px 14px;
border: 1px solid rgb(var(--lsd-border-primary));
:not(.${dropdownItemClasses.disabled}) {
@ -42,14 +41,17 @@ export const DropdownItemStyles = css`
}
.${dropdownItemClasses.small} {
padding: 6px 10px;
padding: 5px 9px;
height: 28px;
}
.${dropdownItemClasses.medium} {
padding: 6px 12px;
padding: 5px 11px;
height: 32px;
}
.${dropdownItemClasses.large} {
padding: 10px 14px;
padding: 5px 13px;
height: 40px;
}
`

View File

@ -0,0 +1,9 @@
export const dropdownMenuClasses = {
root: `lsd-dropdown-menu`,
open: 'lsd-dropdown-menu--open',
large: 'lsd-dropdown-menu--large',
medium: 'lsd-dropdown-menu--medium',
small: 'lsd-dropdown-menu--small',
}

View File

@ -0,0 +1,36 @@
import { css } from '@emotion/react'
import { dropdownMenuClasses } from './DropdownMenu.classes'
export const DropdownMenuStyles = css`
.${dropdownMenuClasses.root} {
position: absolute;
top: 0;
left: 0;
opacity: 0;
visibility: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
background: rgb(var(--lsd-surface-primary));
overflow: auto;
border: 1px solid rgb(var(--lsd-border-primary));
border-top: 0;
}
.${dropdownMenuClasses.open} {
opacity: 1;
visibility: visible;
}
.${dropdownMenuClasses.large} {
max-height: 220px;
}
.${dropdownMenuClasses.medium} {
max-height: 176px;
}
.${dropdownMenuClasses.small} {
max-height: 154px;
}
`

View File

@ -1,21 +1,30 @@
import clsx from 'clsx'
import React, { useEffect, useRef, useState } from 'react'
import { useClickAway } from 'react-use'
import { listBoxClasses } from './ListBox.classes'
import { dropdownMenuClasses } from './DropdownMenu.classes'
export type ListBoxProps = Omit<
export type DropdownMenuProps = Omit<
React.HTMLAttributes<HTMLUListElement>,
'label'
> & {
open?: boolean
label?: string
size?: 'small' | 'medium' | 'large'
onClose?: () => void
handleRef: React.RefObject<HTMLElement>
}
export const ListBox: React.FC<ListBoxProps> & {
classes: typeof listBoxClasses
} = ({ open, label, handleRef, onClose, children, ...props }) => {
export const DropdownMenu: React.FC<DropdownMenuProps> & {
classes: typeof dropdownMenuClasses
} = ({
size = 'large',
open,
label,
handleRef,
onClose,
children,
...props
}) => {
const ref = useRef<HTMLUListElement>(null)
const [style, setStyle] = useState<React.CSSProperties>({})
@ -44,13 +53,14 @@ export const ListBox: React.FC<ListBoxProps> & {
<ul
{...props}
ref={ref}
role="listbox"
role="dropdownMenu"
aria-label={label}
style={{ ...style, ...(props.style ?? {}) }}
className={clsx(
props.className,
listBoxClasses.root,
open && listBoxClasses.open,
dropdownMenuClasses.root,
dropdownMenuClasses[size],
open && dropdownMenuClasses.open,
)}
>
{children}
@ -58,4 +68,4 @@ export const ListBox: React.FC<ListBoxProps> & {
)
}
ListBox.classes = listBoxClasses
DropdownMenu.classes = dropdownMenuClasses

View File

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

View File

@ -1,6 +0,0 @@
export const listBoxClasses = {
root: `lsd-list-box`,
list: 'lsd-list-box-list',
open: 'lsd-list-box--open',
}

View File

@ -1,21 +0,0 @@
import { css } from '@emotion/react'
import { listBoxClasses } from './ListBox.classes'
export const ListBoxStyles = css`
.${listBoxClasses.root} {
position: absolute;
top: 0;
left: 0;
opacity: 0;
visibility: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
background: rgb(var(--lsd-surface-primary));
}
.${listBoxClasses.open} {
opacity: 1;
visibility: visible;
}
`

View File

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

View File

@ -13,7 +13,7 @@ export * from './components/DropdownItem'
export * from './components/IconButton'
export * from './components/IconButtonGroup'
export * from './components/Icons'
export * from './components/ListBox'
export * from './components/DropdownMenu'
export * from './components/Quote'
export * from './components/TabItem'
export * from './components/Tabs'