@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
1 lines • 27.3 kB
Source Map (JSON)
{"version":3,"file":"listbox.cjs","sources":["../../../../../src/components/ui/listbox/listbox.tsx"],"sourcesContent":["import { useTheme } from \"@/theme/context\";\nimport { type StyledProps, getColorVariant } from \"@/theme/styled\";\nimport { css } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\nimport React, {\n\tuseState,\n\tuseRef,\n\tuseEffect,\n\tuseCallback,\n\tuseMemo,\n} from \"react\";\n\nexport interface ListboxItem {\n\t/** Unique identifier */\n\tkey: string | number;\n\t/** Display label */\n\tlabel: string;\n\t/** Value for the item */\n\tvalue?: any;\n\t/** Description text */\n\tdescription?: string;\n\t/** Start content (icon, avatar) */\n\tstartContent?: React.ReactNode;\n\t/** End content (icon, badge) */\n\tendContent?: React.ReactNode;\n\t/** Disabled state */\n\tisDisabled?: boolean;\n\t/** Custom class name */\n\tclassName?: string;\n\t/** Text value for search */\n\ttextValue?: string;\n}\n\nexport interface ListboxProps\n\textends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n\t/** Listbox items */\n\titems?: ListboxItem[];\n\t/** Selected keys */\n\tselectedKeys?: Set<string | number> | \"all\";\n\t/** Default selected keys */\n\tdefaultSelectedKeys?: Set<string | number> | \"all\";\n\t/** Disabled keys */\n\tdisabledKeys?: Set<string | number>;\n\t/** Selection mode */\n\tselectionMode?: \"none\" | \"single\" | \"multiple\";\n\t/** Selection behavior */\n\tselectionBehavior?: \"toggle\" | \"replace\";\n\t/** Empty content */\n\temptyContent?: React.ReactNode;\n\t/** Loading state */\n\tisLoading?: boolean;\n\t/** Loading content */\n\tloadingContent?: React.ReactNode;\n\t/** Listbox variant */\n\tvariant?: \"flat\" | \"bordered\" | \"light\" | \"solid\";\n\t/** Listbox color */\n\tcolor?: \"primary\" | \"secondary\" | \"success\" | \"warning\" | \"danger\";\n\t/** Item height */\n\titemHeight?: \"sm\" | \"md\" | \"lg\";\n\t/** Max height */\n\tmaxHeight?: string | number;\n\t/** Hide selected icon */\n\thideSelectedIcon?: boolean;\n\t/** Show dividers */\n\tshowDividers?: boolean;\n\t/** Keyboard navigation */\n\tshouldFocusWrap?: boolean;\n\t/** Auto focus */\n\tautoFocus?: boolean;\n\t/** Custom class name */\n\tclassName?: string;\n\t/** Custom styles */\n\tcss?: any;\n\t/** Selection change handler */\n\tonSelectionChange?: (keys: Set<string | number> | \"all\") => void;\n\t/** Item action handler */\n\tonAction?: (key: string | number) => void;\n}\n\nexport interface ListboxItemProps extends React.HTMLAttributes<HTMLDivElement> {\n\t/** Item data */\n\titem: ListboxItem;\n\t/** Selected state */\n\tisSelected?: boolean;\n\t/** Focused state */\n\tisFocused?: boolean;\n\t/** Disabled state */\n\tisDisabled?: boolean;\n\t/** Selection mode */\n\tselectionMode?: \"none\" | \"single\" | \"multiple\";\n\t/** Hide selected icon */\n\thideSelectedIcon?: boolean;\n\t/** Item height */\n\titemHeight?: \"sm\" | \"md\" | \"lg\";\n\t/** Color theme */\n\tcolor?: \"primary\" | \"secondary\" | \"success\" | \"warning\" | \"danger\";\n\t/** Custom class name */\n\tclassName?: string;\n\t/** Custom styles */\n\tcss?: any;\n\t/** Click handler */\n\tonPress?: () => void;\n}\n\ntype StyledListboxProps = StyledProps<ListboxProps>;\ntype StyledListboxItemProps = StyledProps<ListboxItemProps>;\n\nconst getListboxVariantStyles = (props: StyledListboxProps) => {\n\tconst { theme, variant = \"flat\", color = \"primary\" } = props;\n\tconst baseColor = getColorVariant(theme, color, 500);\n\n\tswitch (variant) {\n\t\tcase \"flat\":\n\t\t\treturn css`\n background-color: ${theme.colors.background.secondary};\n border: 1px solid transparent;\n `;\n\t\tcase \"bordered\":\n\t\t\treturn css`\n background-color: ${theme.colors.background.primary};\n border: 1px solid ${theme.colors.border.primary};\n `;\n\t\tcase \"light\":\n\t\t\treturn css`\n background-color: ${getColorVariant(theme, color, 50)};\n border: 1px solid transparent;\n `;\n\t\tcase \"solid\":\n\t\t\treturn css`\n background-color: ${baseColor};\n border: 1px solid ${baseColor};\n color: ${theme.colors.text.inverse};\n `;\n\t\tdefault:\n\t\t\treturn css``;\n\t}\n};\n\nconst getListboxItemHeightStyles = (props: StyledListboxItemProps) => {\n\tconst { theme, itemHeight = \"md\" } = props;\n\n\tswitch (itemHeight) {\n\t\tcase \"sm\":\n\t\t\treturn css`\n min-height: ${theme.spacing[8]};\n padding: ${theme.spacing[2]} ${theme.spacing[3]};\n font-size: ${theme.fontSizes.sm};\n `;\n\t\tcase \"md\":\n\t\t\treturn css`\n min-height: ${theme.spacing[10]};\n padding: ${theme.spacing[3]} ${theme.spacing[4]};\n font-size: ${theme.fontSizes.base};\n `;\n\t\tcase \"lg\":\n\t\t\treturn css`\n min-height: ${theme.spacing[12]};\n padding: ${theme.spacing[4]} ${theme.spacing[6]};\n font-size: ${theme.fontSizes.lg};\n `;\n\t\tdefault:\n\t\t\treturn css``;\n\t}\n};\n\nconst getListboxItemStateStyles = (props: StyledListboxItemProps) => {\n\tconst { theme, isSelected, isFocused, isDisabled, color = \"primary\" } = props;\n\tconst baseColor = getColorVariant(theme, color, 500);\n\tconst lightColor = getColorVariant(theme, color, 50);\n\n\tif (isDisabled) {\n\t\treturn css`\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n `;\n\t}\n\n\tlet styles = css`\n cursor: pointer;\n transition: all ${theme.transitions.fast};\n \n &:hover {\n background-color: ${theme.colors.background.tertiary};\n }\n `;\n\n\tif (isSelected) {\n\t\tstyles = css`\n ${styles}\n background-color: ${lightColor};\n color: ${getColorVariant(theme, color, 700)};\n \n &:hover {\n background-color: ${getColorVariant(theme, color, 100)};\n }\n `;\n\t}\n\n\tif (isFocused) {\n\t\tstyles = css`\n ${styles}\n outline: 2px solid ${baseColor};\n outline-offset: -2px;\n `;\n\t}\n\n\treturn styles;\n};\n\nconst StyledListbox = styled.div<StyledListboxProps>`\n position: relative;\n border-radius: ${(props) => props.theme.borderRadius.lg};\n overflow: hidden;\n outline: none;\n \n ${getListboxVariantStyles}\n\n ${(props) =>\n\t\tprops.maxHeight &&\n\t\tcss`\n max-height: ${typeof props.maxHeight === \"number\" ? `${props.maxHeight}px` : props.maxHeight};\n overflow-y: auto;\n `}\n\n /* Custom scrollbar */\n &::-webkit-scrollbar {\n width: 6px;\n }\n\n &::-webkit-scrollbar-track {\n background: ${(props) => props.theme.colors.neutral[100]};\n }\n\n &::-webkit-scrollbar-thumb {\n background: ${(props) => props.theme.colors.neutral[300]};\n border-radius: 3px;\n }\n\n &::-webkit-scrollbar-thumb:hover {\n background: ${(props) => props.theme.colors.neutral[400]};\n }\n\n /* Custom CSS prop */\n ${(props) => props.css}\n`;\n\nconst StyledListboxItem = styled.div<StyledListboxItemProps>`\n display: flex;\n align-items: center;\n gap: ${(props) => props.theme.spacing[3]};\n position: relative;\n user-select: none;\n\n ${getListboxItemHeightStyles}\n ${getListboxItemStateStyles}\n\n ${(props) => props.css}\n`;\n\nconst ItemContent = styled.div<StyledProps>`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n gap: ${(props) => props.theme.spacing[1]};\n`;\n\nconst ItemLabel = styled.div<StyledProps>`\n font-weight: ${(props) => props.theme.fontWeights.medium};\n color: inherit;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nconst ItemDescription = styled.div<StyledProps>`\n font-size: ${(props) => props.theme.fontSizes.sm};\n color: ${(props) => props.theme.colors.text.secondary};\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nconst EmptyContent = styled.div<StyledProps>`\n display: flex;\n align-items: center;\n justify-content: center;\n padding: ${(props) => props.theme.spacing[8]} ${(props) => props.theme.spacing[4]};\n color: ${(props) => props.theme.colors.text.secondary};\n font-size: ${(props) => props.theme.fontSizes.sm};\n text-align: center;\n`;\n\nconst LoadingContent = styled.div<StyledProps>`\n display: flex;\n align-items: center;\n justify-content: center;\n padding: ${(props) => props.theme.spacing[6]} ${(props) => props.theme.spacing[4]};\n gap: ${(props) => props.theme.spacing[2]};\n color: ${(props) => props.theme.colors.text.secondary};\n font-size: ${(props) => props.theme.fontSizes.sm};\n`;\n\nconst Divider = styled.div<StyledProps>`\n height: 1px;\n background-color: ${(props) => props.theme.colors.border.primary};\n margin: ${(props) => props.theme.spacing[1]} 0;\n`;\n\nconst SelectedIcon = () => (\n\t// biome-ignore lint/a11y/noSvgWithoutTitle: <explanation>\n\t<svg\n\t\twidth=\"16\"\n\t\theight=\"16\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"none\"\n\t\tstroke=\"currentColor\"\n\t\tstrokeWidth=\"2\"\n\t\tstrokeLinecap=\"round\"\n\t\tstrokeLinejoin=\"round\"\n\t>\n\t\t<polyline points=\"20,6 9,17 4,12\" />\n\t</svg>\n);\n\nconst LoadingSpinner = () => (\n\t// biome-ignore lint/a11y/noSvgWithoutTitle: <explanation>\n\t<svg\n\t\twidth=\"16\"\n\t\theight=\"16\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"none\"\n\t\tstroke=\"currentColor\"\n\t\tstrokeWidth=\"2\"\n\t\tstyle={{ animation: \"spin 1s linear infinite\" }}\n\t>\n\t\t<path d=\"M21 12a9 9 0 11-6.219-8.56\" />\n\t</svg>\n);\n\nexport const ListboxItem: React.FC<ListboxItemProps> = ({\n\titem,\n\tisSelected = false,\n\tisFocused = false,\n\tisDisabled = false,\n\tselectionMode = \"single\",\n\thideSelectedIcon = false,\n\titemHeight = \"md\",\n\tcolor = \"primary\",\n\tclassName,\n\tcss,\n\tonPress,\n\t...props\n}) => {\n\tconst { theme } = useTheme();\n\n\tconst itemProps = {\n\t\titem,\n\t\tisSelected,\n\t\tisFocused,\n\t\tisDisabled: isDisabled || item.isDisabled,\n\t\tselectionMode,\n\t\thideSelectedIcon,\n\t\titemHeight,\n\t\tcolor,\n\t\tclassName,\n\t\ttheme: theme,\n\t\tcss,\n\t};\n\n\tconst handleClick = () => {\n\t\tif (!itemProps.isDisabled) {\n\t\t\tonPress?.();\n\t\t}\n\t};\n\n\tconst handleKeyDown = (e: React.KeyboardEvent) => {\n\t\tif ((e.key === \"Enter\" || e.key === \" \") && !itemProps.isDisabled) {\n\t\t\te.preventDefault();\n\t\t\tonPress?.();\n\t\t}\n\t};\n\n\treturn (\n\t\t<StyledListboxItem\n\t\t\t{...itemProps}\n\t\t\t{...props}\n\t\t\tonClick={handleClick}\n\t\t\tonKeyDown={handleKeyDown}\n\t\t\ttabIndex={isFocused ? 0 : -1}\n\t\t\trole=\"option\"\n\t\t\taria-selected={isSelected}\n\t\t\taria-disabled={itemProps.isDisabled}\n\t\t>\n\t\t\t{item.startContent}\n\t\t\t<ItemContent theme={theme}>\n\t\t\t\t<ItemLabel theme={theme}>{item.label}</ItemLabel>\n\t\t\t\t{item.description && (\n\t\t\t\t\t<ItemDescription theme={theme}>{item.description}</ItemDescription>\n\t\t\t\t)}\n\t\t\t</ItemContent>\n\t\t\t{item.endContent}\n\t\t\t{!hideSelectedIcon && selectionMode !== \"none\" && isSelected && (\n\t\t\t\t<SelectedIcon />\n\t\t\t)}\n\t\t</StyledListboxItem>\n\t);\n};\n\nexport const Listbox = React.forwardRef<HTMLDivElement, ListboxProps>(\n\t(\n\t\t{\n\t\t\titems = [],\n\t\t\tselectedKeys: controlledSelectedKeys,\n\t\t\tdefaultSelectedKeys,\n\t\t\tdisabledKeys = new Set(),\n\t\t\tselectionMode = \"single\",\n\t\t\tselectionBehavior = \"toggle\",\n\t\t\temptyContent = \"No items found\",\n\t\t\tisLoading = false,\n\t\t\tloadingContent,\n\t\t\tvariant = \"flat\",\n\t\t\tcolor = \"primary\",\n\t\t\titemHeight = \"md\",\n\t\t\tmaxHeight,\n\t\t\thideSelectedIcon = false,\n\t\t\tshowDividers = false,\n\t\t\tshouldFocusWrap = true,\n\t\t\tautoFocus = false,\n\t\t\tclassName,\n\t\t\tcss,\n\t\t\tonSelectionChange,\n\t\t\tonAction,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst { theme } = useTheme();\n\t\tconst [internalSelectedKeys, setInternalSelectedKeys] = useState<\n\t\t\tSet<string | number> | \"all\"\n\t\t>(defaultSelectedKeys || new Set());\n\t\tconst [focusedKey, setFocusedKey] = useState<string | number | null>(null);\n\t\tconst listboxRef = useRef<HTMLDivElement>(null);\n\n\t\tconst isControlled = controlledSelectedKeys !== undefined;\n\t\tconst selectedKeys = isControlled\n\t\t\t? controlledSelectedKeys\n\t\t\t: internalSelectedKeys;\n\n\t\t// Auto focus first item\n\t\tuseEffect(() => {\n\t\t\tif (autoFocus && items.length > 0) {\n\t\t\t\tconst firstEnabledItem = items.find(\n\t\t\t\t\t(item) => !item.isDisabled && !disabledKeys.has(item.key),\n\t\t\t\t);\n\t\t\t\tif (firstEnabledItem) {\n\t\t\t\t\tsetFocusedKey(firstEnabledItem.key);\n\t\t\t\t}\n\t\t\t}\n\t\t}, [autoFocus, items, disabledKeys]);\n\n\t\t// Get enabled items\n\t\tconst enabledItems = useMemo(\n\t\t\t() =>\n\t\t\t\titems.filter((item) => !item.isDisabled && !disabledKeys.has(item.key)),\n\t\t\t[items, disabledKeys],\n\t\t);\n\n\t\tconst handleSelectionChange = useCallback(\n\t\t\t(keys: Set<string | number> | \"all\") => {\n\t\t\t\tif (!isControlled) {\n\t\t\t\t\tsetInternalSelectedKeys(keys);\n\t\t\t\t}\n\t\t\t\tonSelectionChange?.(keys);\n\t\t\t},\n\t\t\t[isControlled, onSelectionChange],\n\t\t);\n\n\t\tconst handleItemPress = useCallback(\n\t\t\t(key: string | number) => {\n\t\t\t\tif (selectionMode === \"none\") {\n\t\t\t\t\tonAction?.(key);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet newSelectedKeys: Set<string | number> | \"all\";\n\n\t\t\t\tif (selectionMode === \"single\") {\n\t\t\t\t\tif (\n\t\t\t\t\t\tselectionBehavior === \"toggle\" &&\n\t\t\t\t\t\tselectedKeys !== \"all\" &&\n\t\t\t\t\t\tselectedKeys.has(key)\n\t\t\t\t\t) {\n\t\t\t\t\t\tnewSelectedKeys = new Set();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewSelectedKeys = new Set([key]);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Multiple selection\n\t\t\t\t\tif (selectedKeys === \"all\") {\n\t\t\t\t\t\tnewSelectedKeys = new Set(\n\t\t\t\t\t\t\titems.map((item) => item.key).filter((k) => k !== key),\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewSelectedKeys = new Set(selectedKeys);\n\t\t\t\t\t\tif (newSelectedKeys.has(key)) {\n\t\t\t\t\t\t\tif (selectionBehavior === \"toggle\") {\n\t\t\t\t\t\t\t\tnewSelectedKeys.delete(key);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnewSelectedKeys.add(key);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\thandleSelectionChange(newSelectedKeys);\n\t\t\t\tonAction?.(key);\n\t\t\t},\n\t\t\t[\n\t\t\t\tselectionMode,\n\t\t\t\tselectionBehavior,\n\t\t\t\tselectedKeys,\n\t\t\t\titems,\n\t\t\t\thandleSelectionChange,\n\t\t\t\tonAction,\n\t\t\t],\n\t\t);\n\n\t\tconst handleKeyDown = useCallback(\n\t\t\t(e: React.KeyboardEvent) => {\n\t\t\t\tif (enabledItems.length === 0) return;\n\n\t\t\t\tconst currentIndex = focusedKey\n\t\t\t\t\t? enabledItems.findIndex((item) => item.key === focusedKey)\n\t\t\t\t\t: -1;\n\t\t\t\tlet newIndex = currentIndex;\n\n\t\t\t\tswitch (e.key) {\n\t\t\t\t\tcase \"ArrowDown\":\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tnewIndex = currentIndex + 1;\n\t\t\t\t\t\tif (newIndex >= enabledItems.length) {\n\t\t\t\t\t\t\tnewIndex = shouldFocusWrap ? 0 : enabledItems.length - 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"ArrowUp\":\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tnewIndex = currentIndex - 1;\n\t\t\t\t\t\tif (newIndex < 0) {\n\t\t\t\t\t\t\tnewIndex = shouldFocusWrap ? enabledItems.length - 1 : 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Home\":\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tnewIndex = 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"End\":\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tnewIndex = enabledItems.length - 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Enter\":\n\t\t\t\t\tcase \" \":\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tif (focusedKey !== null) {\n\t\t\t\t\t\t\thandleItemPress(focusedKey);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase \"a\":\n\t\t\t\t\t\tif (e.ctrlKey || e.metaKey) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tif (selectionMode === \"multiple\") {\n\t\t\t\t\t\t\t\thandleSelectionChange(\"all\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (newIndex !== currentIndex && enabledItems[newIndex]) {\n\t\t\t\t\tsetFocusedKey(enabledItems[newIndex].key);\n\t\t\t\t}\n\t\t\t},\n\t\t\t[\n\t\t\t\tenabledItems,\n\t\t\t\tfocusedKey,\n\t\t\t\tshouldFocusWrap,\n\t\t\t\thandleItemPress,\n\t\t\t\tselectionMode,\n\t\t\t\thandleSelectionChange,\n\t\t\t],\n\t\t);\n\n\t\tconst listboxProps = {\n\t\t\tvariant,\n\t\t\tcolor,\n\t\t\tmaxHeight,\n\t\t\tclassName,\n\t\t\tcss,\n\t\t};\n\n\t\tconst isItemSelected = (key: string | number) => {\n\t\t\tif (selectedKeys === \"all\") return true;\n\t\t\treturn selectedKeys.has(key);\n\t\t};\n\n\t\tconst renderContent = () => {\n\t\t\tif (isLoading) {\n\t\t\t\treturn (\n\t\t\t\t\t<LoadingContent theme={theme}>\n\t\t\t\t\t\t<LoadingSpinner />\n\t\t\t\t\t\t{loadingContent || \"Loading...\"}\n\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t{/* biome-ignore lint/style/noUnusedTemplateLiteral: <explanation> */}\n\t\t\t\t\t\t\t{`@keyframes spin { to { transform: rotate(360deg); } }`}\n\t\t\t\t\t\t</style>\n\t\t\t\t\t</LoadingContent>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (items.length === 0) {\n\t\t\t\treturn <EmptyContent theme={theme}>{emptyContent}</EmptyContent>;\n\t\t\t}\n\n\t\t\treturn items.map((item, index) => (\n\t\t\t\t<React.Fragment key={item.key}>\n\t\t\t\t\t{showDividers && index > 0 && <Divider theme={theme} />}\n\t\t\t\t\t<ListboxItem\n\t\t\t\t\t\titem={item}\n\t\t\t\t\t\tisSelected={isItemSelected(item.key)}\n\t\t\t\t\t\tisFocused={focusedKey === item.key}\n\t\t\t\t\t\tisDisabled={item.isDisabled || disabledKeys.has(item.key)}\n\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\thideSelectedIcon={hideSelectedIcon}\n\t\t\t\t\t\titemHeight={itemHeight}\n\t\t\t\t\t\tcolor={color}\n\t\t\t\t\t\tonPress={() => handleItemPress(item.key)}\n\t\t\t\t\t/>\n\t\t\t\t</React.Fragment>\n\t\t\t));\n\t\t};\n\n\t\treturn (\n\t\t\t<StyledListbox\n\t\t\t\tref={ref || listboxRef}\n\t\t\t\ttheme={theme}\n\t\t\t\t{...listboxProps}\n\t\t\t\t{...props}\n\t\t\t\trole=\"listbox\"\n\t\t\t\taria-multiselectable={selectionMode === \"multiple\"}\n\t\t\t\ttabIndex={0}\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t>\n\t\t\t\t{renderContent()}\n\t\t\t</StyledListbox>\n\t\t);\n\t},\n);\n\nListbox.displayName = \"Listbox\";\nListboxItem.displayName = \"ListboxItem\";\n"],"names":["getListboxVariantStyles","props","theme","variant","color","baseColor","getColorVariant","css","getListboxItemHeightStyles","itemHeight","getListboxItemStateStyles","isSelected","isFocused","isDisabled","lightColor","styles","StyledListbox","styled","StyledListboxItem","ItemContent","ItemLabel","ItemDescription","EmptyContent","LoadingContent","Divider","SelectedIcon","jsx","LoadingSpinner","ListboxItem","item","selectionMode","hideSelectedIcon","className","onPress","useTheme","itemProps","handleClick","handleKeyDown","e","jsxs","Listbox","React","items","controlledSelectedKeys","defaultSelectedKeys","disabledKeys","selectionBehavior","emptyContent","isLoading","loadingContent","maxHeight","showDividers","shouldFocusWrap","autoFocus","onSelectionChange","onAction","ref","internalSelectedKeys","setInternalSelectedKeys","useState","focusedKey","setFocusedKey","listboxRef","useRef","isControlled","selectedKeys","useEffect","firstEnabledItem","enabledItems","useMemo","handleSelectionChange","useCallback","keys","handleItemPress","key","newSelectedKeys","k","currentIndex","newIndex","listboxProps","isItemSelected","renderContent","index"],"mappings":"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"}