mirror of https://github.com/acid-info/lsd.git
refactor: rename listbox to dropdown menu and apply it to autocomplete
This commit is contained in:
parent
724ac50229
commit
7ebdd00ff5
|
@ -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`,
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
`
|
||||
|
|
|
@ -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',
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
`
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
export * from './DropdownMenu'
|
|
@ -1,6 +0,0 @@
|
|||
export const listBoxClasses = {
|
||||
root: `lsd-list-box`,
|
||||
list: 'lsd-list-box-list',
|
||||
|
||||
open: 'lsd-list-box--open',
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
`
|
|
@ -1 +0,0 @@
|
|||
export * from './ListBox'
|
|
@ -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'
|
||||
|
|
Loading…
Reference in New Issue