@popsure/dirty-swan 0.66.0 → 0.66.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +30 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/hooks/useDropdownAlignment.d.ts +5 -0
- package/dist/esm/components/searchableDropdown/index.js +1 -1
- package/dist/esm/components/searchableDropdown/index.stories.js +1 -1
- package/dist/esm/components/searchableDropdown/index.test.js +1 -1
- package/dist/esm/{index-DgTZdYln.js → index-B18M6b67.js} +32 -5
- package/dist/esm/index-B18M6b67.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/lib/hooks/useDropdownAlignment.d.ts +5 -0
- package/package.json +1 -1
- package/src/lib/components/searchableDropdown/index.tsx +7 -2
- package/src/lib/components/searchableDropdown/style.module.scss +6 -6
- package/src/lib/hooks/useDropdownAlignment.test.ts +210 -0
- package/src/lib/hooks/useDropdownAlignment.ts +34 -0
- package/dist/esm/index-DgTZdYln.js.map +0 -1
|
@@ -4,7 +4,7 @@ import 'react';
|
|
|
4
4
|
import '../../index-DLQEsiym.js';
|
|
5
5
|
import '../input/index.js';
|
|
6
6
|
import '../icon/icons/ChevronDown.js';
|
|
7
|
-
export { S as SearchableDropdown } from '../../index-
|
|
7
|
+
export { S as SearchableDropdown } from '../../index-B18M6b67.js';
|
|
8
8
|
import '../../useOnClickOutside-B5hujnpp.js';
|
|
9
9
|
import '../../index-CNcEE5dn.js';
|
|
10
10
|
import '../../_commonjsHelpers-BFTU3MAI.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { b as __assign } from '../../tslib.es6-CVlKGIvp.js';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { useState } from 'react';
|
|
4
|
-
import { S as SearchableDropdown } from '../../index-
|
|
4
|
+
import { S as SearchableDropdown } from '../../index-B18M6b67.js';
|
|
5
5
|
import '../../index-DLQEsiym.js';
|
|
6
6
|
import '../../_commonjsHelpers-BFTU3MAI.js';
|
|
7
7
|
import '../input/index.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _ as __awaiter, a as __generator, b as __assign } from '../../tslib.es6-CVlKGIvp.js';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { s as screen, c as customRender } from '../../customRender-DzdqZxUd.js';
|
|
4
|
-
import { S as SearchableDropdown } from '../../index-
|
|
4
|
+
import { S as SearchableDropdown } from '../../index-B18M6b67.js';
|
|
5
5
|
import '../../_commonjsHelpers-BFTU3MAI.js';
|
|
6
6
|
import 'react';
|
|
7
7
|
import 'react-dom';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { d as __spreadArray } from './tslib.es6-CVlKGIvp.js';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useCallback, useEffect,
|
|
3
|
+
import { useState, useCallback, useEffect, useRef, useMemo } from 'react';
|
|
4
4
|
import { c as classNames } from './index-DLQEsiym.js';
|
|
5
5
|
import { Input } from './components/input/index.js';
|
|
6
6
|
import ChevronDownIcon from './components/icon/icons/ChevronDown.js';
|
|
@@ -8,6 +8,31 @@ import { u as useOnClickOutside } from './useOnClickOutside-B5hujnpp.js';
|
|
|
8
8
|
import { g as generateId } from './index-CNcEE5dn.js';
|
|
9
9
|
import { s as styleInject } from './style-inject.es-tgCJW-Cu.js';
|
|
10
10
|
|
|
11
|
+
var useDropdownAlignment = function (containerRef, dropdownRef, isOpen) {
|
|
12
|
+
var _a = useState('left'), alignX = _a[0], setAlignX = _a[1];
|
|
13
|
+
var _b = useState('bottom'), alignY = _b[0], setAlignY = _b[1];
|
|
14
|
+
var updateAlignment = useCallback(function () {
|
|
15
|
+
if (containerRef.current && dropdownRef.current) {
|
|
16
|
+
var containerRect = containerRef.current.getBoundingClientRect();
|
|
17
|
+
var dropdownWidth = dropdownRef.current.offsetWidth;
|
|
18
|
+
var dropdownHeight = dropdownRef.current.offsetHeight;
|
|
19
|
+
var spaceOnRight = window.innerWidth - containerRect.left;
|
|
20
|
+
var spaceBelow = window.innerHeight - containerRect.bottom;
|
|
21
|
+
setAlignX(spaceOnRight < dropdownWidth ? 'right' : 'left');
|
|
22
|
+
setAlignY(spaceBelow < dropdownHeight && containerRect.top > spaceBelow ? 'top' : 'bottom');
|
|
23
|
+
}
|
|
24
|
+
}, [containerRef, dropdownRef]);
|
|
25
|
+
useEffect(function () {
|
|
26
|
+
if (!isOpen)
|
|
27
|
+
return;
|
|
28
|
+
updateAlignment();
|
|
29
|
+
var observer = new ResizeObserver(updateAlignment);
|
|
30
|
+
observer.observe(document.documentElement);
|
|
31
|
+
return function () { return observer.disconnect(); };
|
|
32
|
+
}, [isOpen, updateAlignment]);
|
|
33
|
+
return { alignX: alignX, alignY: alignY };
|
|
34
|
+
};
|
|
35
|
+
|
|
11
36
|
var useEscapeKey = function (callback) {
|
|
12
37
|
var handleOnEscape = useCallback(function (e) {
|
|
13
38
|
if (e.key === 'Escape') {
|
|
@@ -20,8 +45,8 @@ var useEscapeKey = function (callback) {
|
|
|
20
45
|
}, [handleOnEscape]);
|
|
21
46
|
};
|
|
22
47
|
|
|
23
|
-
var css_248z = ".style-module_bs-xs__2KEsk {\n box-shadow: 0 2px 12px rgba(38, 38, 46, 0.03);\n}\n\n.style-module_bs-sm__3u9QM {\n box-shadow: 0 2px 20px 0 rgba(38, 38, 46, 0.04);\n}\n\n.style-module_bs-md__2LfxW {\n box-shadow: 0 2px 28px rgba(38, 38, 46, 0.08);\n}\n\n.style-module_bs-lg__2Qx0R {\n box-shadow: 0 2px 32px rgba(38, 38, 46, 0.1);\n}\n\n.style-module_bs-xl__kaOuM {\n box-shadow: 0 2px 50px rgba(38, 38, 46, 0.18);\n}\n\n.style-module_container__2064q {\n position: relative;\n}\n\n.style-module_selectTrigger__1GiSB {\n padding: 10px 12px;\n border: 1px solid #e7e7ed;\n}\n.style-module_selectTrigger__1GiSB:hover {\n border-color: #b8b8c0;\n}\n.style-module_selectTrigger__1GiSB:focus-visible {\n outline: 1px solid #26262e;\n outline-offset: 1px;\n}\n.style-module_selectTriggerOpen__29Kor {\n border-color: #26262e;\n box-shadow: 0 2px 12px rgba(38, 38, 46, 0.03);\n}\n\n.style-module_disabled__2BlO- {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.style-module_chevronOpen__Ot3RV {\n transform: rotate(180deg);\n}\n\n.style-module_condensed__GDq0d {\n width: auto;\n padding: 8px 10px;\n gap: 8px;\n}\n\n.style-module_bordered__tRh9H {\n border: 1px solid #e7e7ed;\n}\n.style-module_bordered__tRh9H:hover {\n border-color: #b8b8c0;\n}\n\n.style-module_dropdown__1A-wl {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n min-width: 280px;\n border: 1px solid #e7e7ed;\n box-shadow: 0 2px 28px rgba(38, 38, 46, 0.08);\n z-index: 10;\n}\n\n.style-
|
|
24
|
-
var styles = {"container":"style-module_container__2064q","selectTrigger":"style-module_selectTrigger__1GiSB","selectTriggerOpen":"style-module_selectTriggerOpen__29Kor","disabled":"style-module_disabled__2BlO-","chevronOpen":"style-module_chevronOpen__Ot3RV","condensed":"style-module_condensed__GDq0d","bordered":"style-module_bordered__tRh9H","dropdown":"style-module_dropdown__1A-wl","
|
|
48
|
+
var css_248z = ".style-module_bs-xs__2KEsk {\n box-shadow: 0 2px 12px rgba(38, 38, 46, 0.03);\n}\n\n.style-module_bs-sm__3u9QM {\n box-shadow: 0 2px 20px 0 rgba(38, 38, 46, 0.04);\n}\n\n.style-module_bs-md__2LfxW {\n box-shadow: 0 2px 28px rgba(38, 38, 46, 0.08);\n}\n\n.style-module_bs-lg__2Qx0R {\n box-shadow: 0 2px 32px rgba(38, 38, 46, 0.1);\n}\n\n.style-module_bs-xl__kaOuM {\n box-shadow: 0 2px 50px rgba(38, 38, 46, 0.18);\n}\n\n.style-module_container__2064q {\n position: relative;\n}\n\n.style-module_selectTrigger__1GiSB {\n padding: 10px 12px;\n border: 1px solid #e7e7ed;\n}\n.style-module_selectTrigger__1GiSB:hover {\n border-color: #b8b8c0;\n}\n.style-module_selectTrigger__1GiSB:focus-visible {\n outline: 1px solid #26262e;\n outline-offset: 1px;\n}\n.style-module_selectTriggerOpen__29Kor {\n border-color: #26262e;\n box-shadow: 0 2px 12px rgba(38, 38, 46, 0.03);\n}\n\n.style-module_disabled__2BlO- {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.style-module_chevronOpen__Ot3RV {\n transform: rotate(180deg);\n}\n\n.style-module_condensed__GDq0d {\n width: auto;\n padding: 8px 10px;\n gap: 8px;\n}\n\n.style-module_bordered__tRh9H {\n border: 1px solid #e7e7ed;\n}\n.style-module_bordered__tRh9H:hover {\n border-color: #b8b8c0;\n}\n\n.style-module_dropdown__1A-wl {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n min-width: 280px;\n border: 1px solid #e7e7ed;\n box-shadow: 0 2px 28px rgba(38, 38, 46, 0.08);\n z-index: 10;\n}\n\n.style-module_dropdownXRight__2LIci {\n left: auto;\n right: 0;\n}\n\n.style-module_dropdownYTop__Amnit {\n top: auto;\n bottom: calc(100% + 4px);\n}\n.style-module_dropdownYTop__Amnit .style-module_searchContainer__4O1qv {\n order: 2;\n padding-bottom: 0;\n padding-top: 8px;\n}\n.style-module_dropdownYTop__Amnit .style-module_optionList__-2I8l {\n order: 1;\n}\n\n.style-module_optionList__-2I8l {\n max-height: 308px;\n overflow-y: auto;\n scrollbar-width: none;\n}\n.style-module_optionList__-2I8l::-webkit-scrollbar {\n display: none;\n}\n\n.style-module_optionWrapper__3GVCB {\n position: relative;\n}\n\n.style-module_optionRadio__3GBog {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n.style-module_optionRadio__3GBog:focus-visible + label {\n outline: 2px solid #26262e;\n outline-offset: -2px;\n border-radius: 8px;\n}\n\n.style-module_option__1HkKR {\n padding: 10px 12px;\n border: none;\n background-color: transparent;\n}\n.style-module_option__1HkKR:hover {\n background-color: #f7f7fd;\n}\n.style-module_optionSelected__2pPt9 {\n background-color: #F6F6FE;\n}\n.style-module_optionSelected__2pPt9:hover {\n background-color: #F6F6FE;\n}\n\n.style-module_optionIcon__2hBSY {\n flex-shrink: 0;\n}\n\n.style-module_noResults__18exv {\n padding: 10px 12px;\n}";
|
|
49
|
+
var styles = {"container":"style-module_container__2064q","selectTrigger":"style-module_selectTrigger__1GiSB","selectTriggerOpen":"style-module_selectTriggerOpen__29Kor","disabled":"style-module_disabled__2BlO-","chevronOpen":"style-module_chevronOpen__Ot3RV","condensed":"style-module_condensed__GDq0d","bordered":"style-module_bordered__tRh9H","dropdown":"style-module_dropdown__1A-wl","dropdownXRight":"style-module_dropdownXRight__2LIci","dropdownYTop":"style-module_dropdownYTop__Amnit","optionList":"style-module_optionList__-2I8l","optionWrapper":"style-module_optionWrapper__3GVCB","optionRadio":"style-module_optionRadio__3GBog","option":"style-module_option__1HkKR","optionSelected":"style-module_optionSelected__2pPt9","optionIcon":"style-module_optionIcon__2hBSY","noResults":"style-module_noResults__18exv"};
|
|
25
50
|
styleInject(css_248z);
|
|
26
51
|
|
|
27
52
|
var SearchableDropdown = function (_a) {
|
|
@@ -34,6 +59,7 @@ var SearchableDropdown = function (_a) {
|
|
|
34
59
|
var searchInputRef = useRef(null);
|
|
35
60
|
var containerRef = useRef(null);
|
|
36
61
|
var triggerRef = useRef(null);
|
|
62
|
+
var dropdownRef = useRef(null);
|
|
37
63
|
var optionRefs = useRef(new Map());
|
|
38
64
|
var groupName = useState(function () { return groupNameProp !== null && groupNameProp !== void 0 ? groupNameProp : "sd-".concat(generateId()); })[0];
|
|
39
65
|
var dropdownId = "".concat(groupName, "-dropdown");
|
|
@@ -47,6 +73,7 @@ var SearchableDropdown = function (_a) {
|
|
|
47
73
|
if (isOpen)
|
|
48
74
|
closeAndRestoreFocus();
|
|
49
75
|
}, [isOpen, closeAndRestoreFocus]));
|
|
76
|
+
var _s = useDropdownAlignment(containerRef, dropdownRef, isOpen), alignX = _s.alignX, alignY = _s.alignY;
|
|
50
77
|
useEffect(function () {
|
|
51
78
|
if (isOpen && searchable && searchInputRef.current) {
|
|
52
79
|
searchInputRef.current.focus();
|
|
@@ -136,7 +163,7 @@ var SearchableDropdown = function (_a) {
|
|
|
136
163
|
_b[styles.condensed] = condensed,
|
|
137
164
|
_b[styles.bordered] = bordered,
|
|
138
165
|
_b[styles.disabled] = disabled,
|
|
139
|
-
_b)), onClick: handleTriggerClick, disabled: disabled, "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-controls": isOpen ? dropdownId : undefined, children: [jsxs("span", { className: 'd-flex ai-center gap8', children: [(selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.icon) && (jsx("span", { className: styles.optionIcon, children: selectedOption.icon })), !condensed && (jsx("span", { className: "p-p", children: (_e = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _e !== void 0 ? _e : triggerPlaceholder }))] }), showChevron && (jsx(ChevronDownIcon, { className: classNames('ml8', (_c = {}, _c[styles.chevronOpen] = isOpen, _c)), size: 20, noMargin: true, color: "neutral-600" }))] }), isOpen && (jsxs("div", { id: dropdownId, className: classNames(styles.dropdown, 'bg-white br8 p8 d-flex fd-column', (_d = {}, _d[styles.
|
|
166
|
+
_b)), onClick: handleTriggerClick, disabled: disabled, "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-controls": isOpen ? dropdownId : undefined, children: [jsxs("span", { className: 'd-flex ai-center gap8', children: [(selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.icon) && (jsx("span", { className: styles.optionIcon, children: selectedOption.icon })), !condensed && (jsx("span", { className: "p-p", children: (_e = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _e !== void 0 ? _e : triggerPlaceholder }))] }), showChevron && (jsx(ChevronDownIcon, { className: classNames('ml8', (_c = {}, _c[styles.chevronOpen] = isOpen, _c)), size: 20, noMargin: true, color: "neutral-600" }))] }), isOpen && (jsxs("div", { id: dropdownId, ref: dropdownRef, className: classNames(styles.dropdown, 'bg-white br8 p8 d-flex fd-column', (_d = {}, _d[styles.dropdownYTop] = dropUp || alignY === 'top', _d[styles.dropdownXRight] = alignX === 'right', _d)), children: [searchable && (jsx("div", { className: "pb8 bg-white", children: jsx(Input, { ref: searchInputRef, type: "text", placeholder: placeholder, value: searchTerm, onChange: function (e) { return setSearchTerm(e.target.value); }, label: placeholder, hideLabel: true, onKeyDown: handleSearchKeyDown }) })), jsxs("div", { className: styles.optionList, role: "radiogroup", "aria-label": groupName, children: [filteredOptions.map(function (option) {
|
|
140
167
|
var _a;
|
|
141
168
|
return (jsxs("div", { className: styles.optionWrapper, children: [jsx("input", { type: "radio", id: "".concat(groupName, "-").concat(option.id), name: groupName, value: option.id, checked: option.id === localValue, onChange: function () { return setLocalValue(option.id); }, onClick: function () { return handleOptionClick(option.id); }, tabIndex: option.id === localValue ? 0 : -1, className: styles.optionRadio, ref: function (el) { return handleOptionRef(option.id, el); }, onKeyDown: function (e) { return handleOptionKeyDown(e, option.id); } }), jsxs("label", { htmlFor: "".concat(groupName, "-").concat(option.id), className: classNames('d-flex ai-center gap8 w100 br8 c-pointer ta-left tc-neutral-900', styles.option, (_a = {},
|
|
142
169
|
_a[styles.optionSelected] = option.id === localValue,
|
|
@@ -145,4 +172,4 @@ var SearchableDropdown = function (_a) {
|
|
|
145
172
|
};
|
|
146
173
|
|
|
147
174
|
export { SearchableDropdown as S, useEscapeKey as u };
|
|
148
|
-
//# sourceMappingURL=index-
|
|
175
|
+
//# sourceMappingURL=index-B18M6b67.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-B18M6b67.js","sources":["../../../src/lib/hooks/useDropdownAlignment.ts","../../../src/lib/hooks/useEscapeKey.ts","../../../src/lib/components/searchableDropdown/index.tsx"],"sourcesContent":["import { RefObject, useCallback, useEffect, useState } from 'react';\n\nexport const useDropdownAlignment = (\n containerRef: RefObject<HTMLElement | null>,\n dropdownRef: RefObject<HTMLElement | null>,\n isOpen: boolean\n) => {\n const [alignX, setAlignX] = useState<'left' | 'right'>('left');\n const [alignY, setAlignY] = useState<'top' | 'bottom'>('bottom');\n\n const updateAlignment = useCallback(() => {\n if (containerRef.current && dropdownRef.current) {\n const containerRect = containerRef.current.getBoundingClientRect();\n const dropdownWidth = dropdownRef.current.offsetWidth;\n const dropdownHeight = dropdownRef.current.offsetHeight;\n const spaceOnRight = window.innerWidth - containerRect.left;\n const spaceBelow = window.innerHeight - containerRect.bottom;\n setAlignX(spaceOnRight < dropdownWidth ? 'right' : 'left');\n setAlignY(spaceBelow < dropdownHeight && containerRect.top > spaceBelow ? 'top' : 'bottom');\n }\n }, [containerRef, dropdownRef]);\n\n useEffect(() => {\n if (!isOpen) return;\n\n updateAlignment();\n\n const observer = new ResizeObserver(updateAlignment);\n observer.observe(document.documentElement);\n return () => observer.disconnect();\n }, [isOpen, updateAlignment]);\n\n return { alignX, alignY };\n};\n","import { useCallback, useEffect } from 'react';\n\nexport const useEscapeKey = (callback: () => void) => {\n const handleOnEscape = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n callback();\n }\n },\n [callback]\n );\n\n useEffect(() => {\n window.addEventListener('keydown', handleOnEscape);\n\n return () => window.removeEventListener('keydown', handleOnEscape);\n }, [handleOnEscape]);\n};\n","import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport classnames from 'classnames';\n\nimport { Input } from '../input';\nimport { ChevronDownIcon } from '../icon';\nimport { useDropdownAlignment } from '../../hooks/useDropdownAlignment';\nimport { useEscapeKey } from '../../hooks/useEscapeKey';\nimport { useOnClickOutside } from '../../hooks/useOnClickOutside';\nimport generateId from '../../util/generateId';\n\nimport styles from './style.module.scss';\n\nexport interface SearchableDropdownOption {\n id: string;\n label: string;\n icon?: ReactNode;\n}\n\nexport interface SearchableDropdownProps {\n options: SearchableDropdownOption[];\n value: string | null;\n onChange: (value: string) => void;\n searchable?: boolean;\n placeholder?: string;\n triggerPlaceholder?: string;\n noResultsText?: string;\n groupName?: string;\n dropUp?: boolean;\n condensed?: boolean;\n bordered?: boolean;\n showChevron?: boolean;\n disabled?: boolean;\n}\n\nexport const SearchableDropdown = ({\n options,\n value,\n onChange,\n searchable = false,\n placeholder = 'Search',\n triggerPlaceholder,\n noResultsText = 'No results found',\n groupName: groupNameProp,\n dropUp = false,\n condensed = false,\n bordered = false,\n showChevron = false,\n disabled = false,\n}: SearchableDropdownProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [searchTerm, setSearchTerm] = useState('');\n const [localValue, setLocalValue] = useState(value);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionRefs = useRef<Map<string, HTMLInputElement>>(new Map());\n const [groupName] = useState(() => groupNameProp ?? `sd-${generateId()}`);\n const dropdownId = `${groupName}-dropdown`;\n\n const closeAndRestoreFocus = useCallback(() => {\n setIsOpen(false);\n triggerRef.current?.focus();\n }, []);\n\n useOnClickOutside(containerRef, () => isOpen && closeAndRestoreFocus());\n useEscapeKey(\n useCallback(() => {\n if (isOpen) closeAndRestoreFocus();\n }, [isOpen, closeAndRestoreFocus])\n );\n\n const { alignX, alignY } = useDropdownAlignment(containerRef, dropdownRef, isOpen);\n\n useEffect(() => {\n if (isOpen && searchable && searchInputRef.current) {\n searchInputRef.current.focus();\n }\n }, [isOpen, searchable]);\n\n useEffect(() => {\n if (!isOpen) {\n setSearchTerm('');\n setLocalValue(value);\n }\n }, [isOpen, value]);\n\n const filteredOptions = useMemo(() => {\n if (!searchTerm) return options;\n return [...options]\n .filter((option) =>\n option.label.toLowerCase().includes(searchTerm.toLowerCase())\n )\n .sort((a, b) => {\n const term = searchTerm.toLowerCase();\n const aStartsWith = a.label.toLowerCase().startsWith(term);\n const bStartsWith = b.label.toLowerCase().startsWith(term);\n if (aStartsWith && !bStartsWith) return -1;\n if (!aStartsWith && bStartsWith) return 1;\n return 0;\n });\n }, [options, searchTerm]);\n\n const selectedOption = options.find((option) => option.id === value);\n\n const handleTriggerClick = () => {\n if (!disabled) setIsOpen(!isOpen);\n };\n\n const handleSearchKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n const target =\n e.key === 'ArrowDown'\n ? filteredOptions[0]\n : filteredOptions[filteredOptions.length - 1];\n if (target) {\n setLocalValue(target.id);\n optionRefs.current.get(target.id)?.focus();\n }\n } else if (e.key === 'Enter') {\n e.preventDefault();\n const target = filteredOptions[0];\n if (target) {\n onChange(target.id);\n closeAndRestoreFocus();\n }\n }\n };\n\n const handleOptionClick = (optionId: string) => {\n onChange(optionId);\n closeAndRestoreFocus();\n };\n\n const handleOptionRef = (optionId: string, el: HTMLInputElement | null) => {\n if (el) optionRefs.current.set(optionId, el);\n else optionRefs.current.delete(optionId);\n };\n\n const handleOptionKeyDown = (e: React.KeyboardEvent, optionId: string) => {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n const currentIndex = filteredOptions.findIndex(\n (o) => o.id === optionId\n );\n const nextIndex =\n e.key === 'ArrowDown'\n ? Math.min(currentIndex + 1, filteredOptions.length - 1)\n : Math.max(currentIndex - 1, 0);\n const next = filteredOptions[nextIndex];\n if (next) {\n setLocalValue(next.id);\n optionRefs.current.get(next.id)?.focus();\n }\n } else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onChange(optionId);\n closeAndRestoreFocus();\n }\n };\n\n return (\n <div className={classnames(styles.container, { 'd-inline-block': condensed })} ref={containerRef}>\n <button\n ref={triggerRef}\n type=\"button\"\n className={classnames(\n 'd-flex ai-center jc-between w100 br8 bg-white c-pointer ta-left tc-neutral-900',\n styles.selectTrigger, {\n [styles.selectTriggerOpen]: isOpen,\n [styles.condensed]: condensed,\n [styles.bordered]: bordered,\n [styles.disabled]: disabled,\n }\n )}\n onClick={handleTriggerClick}\n disabled={disabled}\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-controls={isOpen ? dropdownId : undefined}\n >\n <span className={'d-flex ai-center gap8'}>\n {selectedOption?.icon && (\n <span className={styles.optionIcon}>{selectedOption.icon}</span>\n )}\n {!condensed && (\n <span className=\"p-p\">\n {selectedOption?.label ?? triggerPlaceholder}\n </span>\n )}\n </span>\n {showChevron && (\n <ChevronDownIcon\n className={classnames('ml8', { [styles.chevronOpen]: isOpen })}\n size={20}\n noMargin\n color=\"neutral-600\"\n />\n )}\n </button>\n {isOpen && (\n <div\n id={dropdownId}\n ref={dropdownRef}\n className={classnames(\n styles.dropdown,\n 'bg-white br8 p8 d-flex fd-column',\n { [styles.dropdownYTop]: dropUp || alignY === 'top', [styles.dropdownXRight]: alignX === 'right' }\n )}\n >\n {searchable && (\n <div className=\"pb8 bg-white\">\n <Input\n ref={searchInputRef}\n type=\"text\"\n placeholder={placeholder}\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n label={placeholder}\n hideLabel\n onKeyDown={handleSearchKeyDown}\n />\n </div>\n )}\n <div className={styles.optionList} role=\"radiogroup\" aria-label={groupName}>\n {filteredOptions.map((option) => (\n <div key={option.id} className={styles.optionWrapper}>\n <input\n type=\"radio\"\n id={`${groupName}-${option.id}`}\n name={groupName}\n value={option.id}\n checked={option.id === localValue}\n onChange={() => setLocalValue(option.id)}\n onClick={() => handleOptionClick(option.id)}\n tabIndex={option.id === localValue ? 0 : -1}\n className={styles.optionRadio}\n ref={(el) => handleOptionRef(option.id, el)}\n onKeyDown={(e) => handleOptionKeyDown(e, option.id)}\n />\n <label\n htmlFor={`${groupName}-${option.id}`}\n className={classnames(\n 'd-flex ai-center gap8 w100 br8 c-pointer ta-left tc-neutral-900',\n styles.option, {\n [styles.optionSelected]: option.id === localValue,\n })}\n >\n {option.icon && (\n <span className={styles.optionIcon}>{option.icon}</span>\n )}\n <span className=\"p-p\">{option.label}</span>\n </label>\n </div>\n ))}\n {filteredOptions.length === 0 && (\n <p className={`p-p tc-neutral-500 ${styles.noResults}`}>\n {noResultsText}\n </p>\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n"],"names":["_jsxs","classnames","_jsx"],"mappings":";;;;;;;;;;AAEO,IAAM,oBAAoB,GAAG,UAClC,YAA2C,EAC3C,WAA0C,EAC1C,MAAe,EAAA;IAET,IAAA,EAAA,GAAsB,QAAQ,CAAmB,MAAM,CAAC,EAAvD,MAAM,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,SAAS,GAAA,EAAA,CAAA,CAAA,CAAsC;IACxD,IAAA,EAAA,GAAsB,QAAQ,CAAmB,QAAQ,CAAC,EAAzD,MAAM,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,SAAS,GAAA,EAAA,CAAA,CAAA,CAAwC;IAEhE,IAAM,eAAe,GAAG,WAAW,CAAC,YAAA;QAClC,IAAI,YAAY,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE;YAC/C,IAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,qBAAqB,EAAE;AAClE,YAAA,IAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,WAAW;AACrD,YAAA,IAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC,YAAY;YACvD,IAAM,YAAY,GAAG,MAAM,CAAC,UAAU,GAAG,aAAa,CAAC,IAAI;YAC3D,IAAM,UAAU,GAAG,MAAM,CAAC,WAAW,GAAG,aAAa,CAAC,MAAM;AAC5D,YAAA,SAAS,CAAC,YAAY,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;AAC1D,YAAA,SAAS,CAAC,UAAU,GAAG,cAAc,IAAI,aAAa,CAAC,GAAG,GAAG,UAAU,GAAG,KAAK,GAAG,QAAQ,CAAC;QAC7F;AACF,IAAA,CAAC,EAAE,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;AAE/B,IAAA,SAAS,CAAC,YAAA;AACR,QAAA,IAAI,CAAC,MAAM;YAAE;AAEb,QAAA,eAAe,EAAE;AAEjB,QAAA,IAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,eAAe,CAAC;AACpD,QAAA,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC1C,OAAO,YAAA,EAAM,OAAA,QAAQ,CAAC,UAAU,EAAE,CAAA,CAArB,CAAqB;AACpC,IAAA,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAE7B,IAAA,OAAO,EAAE,MAAM,EAAA,MAAA,EAAE,MAAM,EAAA,MAAA,EAAE;AAC3B,CAAC;;AC/BM,IAAM,YAAY,GAAG,UAAC,QAAoB,EAAA;AAC/C,IAAA,IAAM,cAAc,GAAG,WAAW,CAChC,UAAC,CAAgB,EAAA;AACf,QAAA,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE;AACtB,YAAA,QAAQ,EAAE;QACZ;AACF,IAAA,CAAC,EACD,CAAC,QAAQ,CAAC,CACX;AAED,IAAA,SAAS,CAAC,YAAA;AACR,QAAA,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,CAAC;AAElD,QAAA,OAAO,YAAA,EAAM,OAAA,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA,CAArD,CAAqD;AACpE,IAAA,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC;AACtB;;;;;;ACiBO,IAAM,kBAAkB,GAAG,UAAC,EAcT,EAAA;;;AAbxB,IAAA,IAAA,OAAO,GAAA,EAAA,CAAA,OAAA,EACP,KAAK,GAAA,EAAA,CAAA,KAAA,EACL,QAAQ,GAAA,EAAA,CAAA,QAAA,EACR,EAAA,GAAA,EAAA,CAAA,UAAkB,EAAlB,UAAU,GAAA,EAAA,KAAA,MAAA,GAAG,KAAK,KAAA,EAClB,EAAA,GAAA,EAAA,CAAA,WAAsB,EAAtB,WAAW,GAAA,EAAA,KAAA,MAAA,GAAG,QAAQ,GAAA,EAAA,EACtB,kBAAkB,GAAA,EAAA,CAAA,kBAAA,EAClB,EAAA,GAAA,EAAA,CAAA,aAAkC,EAAlC,aAAa,GAAA,EAAA,KAAA,MAAA,GAAG,kBAAkB,GAAA,EAAA,EACvB,aAAa,GAAA,EAAA,CAAA,SAAA,EACxB,EAAA,GAAA,EAAA,CAAA,MAAc,EAAd,MAAM,GAAA,EAAA,KAAA,MAAA,GAAG,KAAK,KAAA,EACd,EAAA,GAAA,EAAA,CAAA,SAAiB,EAAjB,SAAS,GAAA,EAAA,KAAA,MAAA,GAAG,KAAK,GAAA,EAAA,EACjB,gBAAgB,EAAhB,QAAQ,GAAA,EAAA,KAAA,MAAA,GAAG,KAAK,GAAA,EAAA,EAChB,EAAA,GAAA,EAAA,CAAA,WAAmB,EAAnB,WAAW,GAAA,EAAA,KAAA,MAAA,GAAG,KAAK,GAAA,EAAA,EACnB,EAAA,GAAA,EAAA,CAAA,QAAgB,EAAhB,QAAQ,GAAA,EAAA,KAAA,MAAA,GAAG,KAAK,GAAA,EAAA;IAEV,IAAA,EAAA,GAAsB,QAAQ,CAAC,KAAK,CAAC,EAApC,MAAM,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,SAAS,GAAA,EAAA,CAAA,CAAA,CAAmB;IACrC,IAAA,EAAA,GAA8B,QAAQ,CAAC,EAAE,CAAC,EAAzC,UAAU,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,aAAa,GAAA,EAAA,CAAA,CAAA,CAAgB;IAC1C,IAAA,EAAA,GAA8B,QAAQ,CAAC,KAAK,CAAC,EAA5C,UAAU,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,aAAa,GAAA,EAAA,CAAA,CAAA,CAAmB;AACnD,IAAA,IAAM,cAAc,GAAG,MAAM,CAAmB,IAAI,CAAC;AACrD,IAAA,IAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC;AACjD,IAAA,IAAM,UAAU,GAAG,MAAM,CAAoB,IAAI,CAAC;AAClD,IAAA,IAAM,WAAW,GAAG,MAAM,CAAiB,IAAI,CAAC;IAChD,IAAM,UAAU,GAAG,MAAM,CAAgC,IAAI,GAAG,EAAE,CAAC;IAC5D,IAAA,SAAS,GAAI,QAAQ,CAAC,cAAM,OAAA,aAAa,aAAb,aAAa,KAAA,MAAA,GAAb,aAAa,GAAI,KAAA,CAAA,MAAA,CAAM,UAAU,EAAE,CAAE,EAArC,CAAqC,CAAC,GAAzD;AAChB,IAAA,IAAM,UAAU,GAAG,EAAA,CAAA,MAAA,CAAG,SAAS,cAAW;IAE1C,IAAM,oBAAoB,GAAG,WAAW,CAAC,YAAA;;QACvC,SAAS,CAAC,KAAK,CAAC;AAChB,QAAA,CAAA,EAAA,GAAA,UAAU,CAAC,OAAO,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,KAAK,EAAE;IAC7B,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,iBAAiB,CAAC,YAAY,EAAE,YAAA,EAAM,OAAA,MAAM,IAAI,oBAAoB,EAAE,CAAA,CAAhC,CAAgC,CAAC;IACvE,YAAY,CACV,WAAW,CAAC,YAAA;AACV,QAAA,IAAI,MAAM;AAAE,YAAA,oBAAoB,EAAE;IACpC,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CACnC;AAEK,IAAA,IAAA,EAAA,GAAqB,oBAAoB,CAAC,YAAY,EAAE,WAAW,EAAE,MAAM,CAAC,EAA1E,MAAM,GAAA,EAAA,CAAA,MAAA,EAAE,MAAM,YAA4D;AAElF,IAAA,SAAS,CAAC,YAAA;QACR,IAAI,MAAM,IAAI,UAAU,IAAI,cAAc,CAAC,OAAO,EAAE;AAClD,YAAA,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE;QAChC;AACF,IAAA,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAExB,IAAA,SAAS,CAAC,YAAA;QACR,IAAI,CAAC,MAAM,EAAE;YACX,aAAa,CAAC,EAAE,CAAC;YACjB,aAAa,CAAC,KAAK,CAAC;QACtB;AACF,IAAA,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAEnB,IAAM,eAAe,GAAG,OAAO,CAAC,YAAA;AAC9B,QAAA,IAAI,CAAC,UAAU;AAAE,YAAA,OAAO,OAAO;AAC/B,QAAA,OAAO,kBAAI,OAAO,EAAA,IAAA,CAAA,CACf,MAAM,CAAC,UAAC,MAAM,EAAA;AACb,YAAA,OAAA,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;AAA7D,QAAA,CAA6D;AAE9D,aAAA,IAAI,CAAC,UAAC,CAAC,EAAE,CAAC,EAAA;AACT,YAAA,IAAM,IAAI,GAAG,UAAU,CAAC,WAAW,EAAE;AACrC,YAAA,IAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;AAC1D,YAAA,IAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAC1D,IAAI,WAAW,IAAI,CAAC,WAAW;gBAAE,OAAO,EAAE;YAC1C,IAAI,CAAC,WAAW,IAAI,WAAW;AAAE,gBAAA,OAAO,CAAC;AACzC,YAAA,OAAO,CAAC;AACV,QAAA,CAAC,CAAC;AACN,IAAA,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAEzB,IAAA,IAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,UAAC,MAAM,EAAA,EAAK,OAAA,MAAM,CAAC,EAAE,KAAK,KAAK,CAAA,CAAnB,CAAmB,CAAC;AAEpE,IAAA,IAAM,kBAAkB,GAAG,YAAA;AACzB,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,SAAS,CAAC,CAAC,MAAM,CAAC;AACnC,IAAA,CAAC;IAED,IAAM,mBAAmB,GAAG,UAAC,CAAsB,EAAA;;AACjD,QAAA,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,EAAE;YAChD,CAAC,CAAC,cAAc,EAAE;AAClB,YAAA,IAAM,MAAM,GACV,CAAC,CAAC,GAAG,KAAK;AACR,kBAAE,eAAe,CAAC,CAAC;kBACjB,eAAe,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC;YACjD,IAAI,MAAM,EAAE;AACV,gBAAA,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;AACxB,gBAAA,CAAA,EAAA,GAAA,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,KAAK,EAAE;YAC5C;QACF;AAAO,aAAA,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE;YAC5B,CAAC,CAAC,cAAc,EAAE;AAClB,YAAA,IAAM,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC;YACjC,IAAI,MAAM,EAAE;AACV,gBAAA,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;AACnB,gBAAA,oBAAoB,EAAE;YACxB;QACF;AACF,IAAA,CAAC;IAED,IAAM,iBAAiB,GAAG,UAAC,QAAgB,EAAA;QACzC,QAAQ,CAAC,QAAQ,CAAC;AAClB,QAAA,oBAAoB,EAAE;AACxB,IAAA,CAAC;AAED,IAAA,IAAM,eAAe,GAAG,UAAC,QAAgB,EAAE,EAA2B,EAAA;AACpE,QAAA,IAAI,EAAE;YAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;;AACvC,YAAA,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC1C,IAAA,CAAC;AAED,IAAA,IAAM,mBAAmB,GAAG,UAAC,CAAsB,EAAE,QAAgB,EAAA;;AACnE,QAAA,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,EAAE;YAChD,CAAC,CAAC,cAAc,EAAE;AAClB,YAAA,IAAM,YAAY,GAAG,eAAe,CAAC,SAAS,CAC5C,UAAC,CAAC,EAAA,EAAK,OAAA,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAA,CAAjB,CAAiB,CACzB;AACD,YAAA,IAAM,SAAS,GACb,CAAC,CAAC,GAAG,KAAK;AACR,kBAAE,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,EAAE,eAAe,CAAC,MAAM,GAAG,CAAC;kBACrD,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC,CAAC;AACnC,YAAA,IAAM,IAAI,GAAG,eAAe,CAAC,SAAS,CAAC;YACvC,IAAI,IAAI,EAAE;AACR,gBAAA,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;AACtB,gBAAA,CAAA,EAAA,GAAA,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,KAAK,EAAE;YAC1C;QACF;AAAO,aAAA,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE;YAC7C,CAAC,CAAC,cAAc,EAAE;YAClB,QAAQ,CAAC,QAAQ,CAAC;AAClB,YAAA,oBAAoB,EAAE;QACxB;AACF,IAAA,CAAC;AAED,IAAA,QACEA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAEC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,gBAAgB,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,EAAA,QAAA,EAAA,CAC9FD,iBACE,GAAG,EAAE,UAAU,EACf,IAAI,EAAC,QAAQ,EACb,SAAS,EAAEC,UAAU,CACnB,gFAAgF,EAChF,MAAM,CAAC,aAAa,GAAA,EAAA,GAAA,EAAA;AAClB,oBAAA,EAAA,CAAC,MAAM,CAAC,iBAAiB,CAAA,GAAG,MAAM;AAClC,oBAAA,EAAA,CAAC,MAAM,CAAC,SAAS,CAAA,GAAG,SAAS;AAC7B,oBAAA,EAAA,CAAC,MAAM,CAAC,QAAQ,CAAA,GAAG,QAAQ;AAC3B,oBAAA,EAAA,CAAC,MAAM,CAAC,QAAQ,CAAA,GAAG,QAAQ;wBAE9B,EACD,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,EAAE,QAAQ,EAAA,eAAA,EACH,MAAM,EAAA,eAAA,EACP,SAAS,EAAA,eAAA,EACR,MAAM,GAAG,UAAU,GAAG,SAAS,EAAA,QAAA,EAAA,CAE9CD,IAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,uBAAuB,aACrC,CAAA,cAAc,KAAA,IAAA,IAAd,cAAc,KAAA,MAAA,GAAA,MAAA,GAAd,cAAc,CAAE,IAAI,MACnBE,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,MAAM,CAAC,UAAU,EAAA,QAAA,EAAG,cAAc,CAAC,IAAI,EAAA,CAAQ,CACjE,EACA,CAAC,SAAS,KACTA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,KAAK,EAAA,QAAA,EAClB,CAAA,EAAA,GAAA,cAAc,KAAA,IAAA,IAAd,cAAc,KAAA,MAAA,GAAA,MAAA,GAAd,cAAc,CAAE,KAAK,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,EAAA,GAAI,kBAAkB,GACvC,CACR,CAAA,EAAA,CACI,EACN,WAAW,KACVA,IAAC,eAAe,EAAA,EACd,SAAS,EAAED,UAAU,CAAC,KAAK,GAAA,EAAA,GAAA,EAAA,EAAI,EAAA,CAAC,MAAM,CAAC,WAAW,CAAA,GAAG,MAAM,EAAA,EAAA,EAAG,EAC9D,IAAI,EAAE,EAAE,EACR,QAAQ,EAAA,IAAA,EACR,KAAK,EAAC,aAAa,EAAA,CACnB,CACH,CAAA,EAAA,CACM,EACR,MAAM,KACLD,IAAA,CAAA,KAAA,EAAA,EACE,EAAE,EAAE,UAAU,EACd,GAAG,EAAE,WAAW,EAChB,SAAS,EAAEC,UAAU,CACnB,MAAM,CAAC,QAAQ,EACf,kCAAkC,GAAA,EAAA,GAAA,EAAA,EAChC,EAAA,CAAC,MAAM,CAAC,YAAY,CAAA,GAAG,MAAM,IAAI,MAAM,KAAK,KAAK,EAAE,EAAA,CAAC,MAAM,CAAC,cAAc,CAAA,GAAG,MAAM,KAAK,OAAO,MACjG,EAAA,QAAA,EAAA,CAEA,UAAU,KACTC,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,cAAc,EAAA,QAAA,EAC3BA,GAAA,CAAC,KAAK,EAAA,EACJ,GAAG,EAAE,cAAc,EACnB,IAAI,EAAC,MAAM,EACX,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,UAAC,CAAC,EAAA,EAAK,OAAA,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAA7B,CAA6B,EAC9C,KAAK,EAAE,WAAW,EAClB,SAAS,EAAA,IAAA,EACT,SAAS,EAAE,mBAAmB,EAAA,CAC9B,EAAA,CACE,CACP,EACDF,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,EAAC,YAAY,EAAA,YAAA,EAAa,SAAS,EAAA,QAAA,EAAA,CACvE,eAAe,CAAC,GAAG,CAAC,UAAC,MAAM,EAAA;;AAAK,gCAAA,QAC/BA,IAAA,CAAA,KAAA,EAAA,EAAqB,SAAS,EAAE,MAAM,CAAC,aAAa,EAAA,QAAA,EAAA,CAClDE,GAAA,CAAA,OAAA,EAAA,EACE,IAAI,EAAC,OAAO,EACZ,EAAE,EAAE,EAAA,CAAA,MAAA,CAAG,SAAS,EAAA,GAAA,CAAA,CAAA,MAAA,CAAI,MAAM,CAAC,EAAE,CAAE,EAC/B,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,MAAM,CAAC,EAAE,EAChB,OAAO,EAAE,MAAM,CAAC,EAAE,KAAK,UAAU,EACjC,QAAQ,EAAE,YAAA,EAAM,OAAA,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA,CAAxB,CAAwB,EACxC,OAAO,EAAE,YAAA,EAAM,OAAA,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC,EAA5B,CAA4B,EAC3C,QAAQ,EAAE,MAAM,CAAC,EAAE,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,EAC3C,SAAS,EAAE,MAAM,CAAC,WAAW,EAC7B,GAAG,EAAE,UAAC,EAAE,EAAA,EAAK,OAAA,eAAe,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA,CAA9B,CAA8B,EAC3C,SAAS,EAAE,UAAC,CAAC,EAAA,EAAK,OAAA,mBAAmB,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAA,CAAjC,CAAiC,EAAA,CACnD,EACFF,IAAA,CAAA,OAAA,EAAA,EACE,OAAO,EAAE,EAAA,CAAA,MAAA,CAAG,SAAS,EAAA,GAAA,CAAA,CAAA,MAAA,CAAI,MAAM,CAAC,EAAE,CAAE,EACpC,SAAS,EAAEC,UAAU,CACnB,iEAAiE,EACjE,MAAM,CAAC,MAAM,GAAA,EAAA,GAAA,EAAA;gDACb,EAAA,CAAC,MAAM,CAAC,cAAc,CAAA,GAAG,MAAM,CAAC,EAAE,KAAK,UAAU;AACjD,gDAAA,EAAA,EAAA,EAAA,QAAA,EAAA,CAED,MAAM,CAAC,IAAI,KACVC,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,MAAM,CAAC,UAAU,EAAA,QAAA,EAAG,MAAM,CAAC,IAAI,EAAA,CAAQ,CACzD,EACDA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,KAAK,YAAE,MAAM,CAAC,KAAK,EAAA,CAAQ,IACrC,CAAA,EAAA,EA1BA,MAAM,CAAC,EAAE,CA2Bb;4BA5ByB,CA6BhC,CAAC,EACD,eAAe,CAAC,MAAM,KAAK,CAAC,KAC3BA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,qBAAA,CAAA,MAAA,CAAsB,MAAM,CAAC,SAAS,CAAE,EAAA,QAAA,EACnD,aAAa,EAAA,CACZ,CACL,CAAA,EAAA,CACG,CAAA,EAAA,CACF,CACP,CAAA,EAAA,CACG;AAEV;;;;"}
|
package/dist/esm/index.js
CHANGED
|
@@ -23,7 +23,7 @@ export { default as Chip } from './components/chip/index.js';
|
|
|
23
23
|
export { AutoSuggestInput } from './components/input/autoSuggestInput/index.js';
|
|
24
24
|
export { ComparisonTable } from './components/comparisonTable/index.js';
|
|
25
25
|
export { SegmentedControl } from './components/segmentedControl/index.js';
|
|
26
|
-
export { S as SearchableDropdown, u as useEscapeKey } from './index-
|
|
26
|
+
export { S as SearchableDropdown, u as useEscapeKey } from './index-B18M6b67.js';
|
|
27
27
|
export { Link } from './components/link/index.js';
|
|
28
28
|
export { a as illustrations, i as images } from './index-C4hs4X-e.js';
|
|
29
29
|
export { Spinner } from './components/spinner/index.js';
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import classnames from 'classnames';
|
|
|
3
3
|
|
|
4
4
|
import { Input } from '../input';
|
|
5
5
|
import { ChevronDownIcon } from '../icon';
|
|
6
|
+
import { useDropdownAlignment } from '../../hooks/useDropdownAlignment';
|
|
6
7
|
import { useEscapeKey } from '../../hooks/useEscapeKey';
|
|
7
8
|
import { useOnClickOutside } from '../../hooks/useOnClickOutside';
|
|
8
9
|
import generateId from '../../util/generateId';
|
|
@@ -52,6 +53,7 @@ export const SearchableDropdown = ({
|
|
|
52
53
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
|
53
54
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
54
55
|
const triggerRef = useRef<HTMLButtonElement>(null);
|
|
56
|
+
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
55
57
|
const optionRefs = useRef<Map<string, HTMLInputElement>>(new Map());
|
|
56
58
|
const [groupName] = useState(() => groupNameProp ?? `sd-${generateId()}`);
|
|
57
59
|
const dropdownId = `${groupName}-dropdown`;
|
|
@@ -68,6 +70,8 @@ export const SearchableDropdown = ({
|
|
|
68
70
|
}, [isOpen, closeAndRestoreFocus])
|
|
69
71
|
);
|
|
70
72
|
|
|
73
|
+
const { alignX, alignY } = useDropdownAlignment(containerRef, dropdownRef, isOpen);
|
|
74
|
+
|
|
71
75
|
useEffect(() => {
|
|
72
76
|
if (isOpen && searchable && searchInputRef.current) {
|
|
73
77
|
searchInputRef.current.focus();
|
|
@@ -198,14 +202,15 @@ export const SearchableDropdown = ({
|
|
|
198
202
|
{isOpen && (
|
|
199
203
|
<div
|
|
200
204
|
id={dropdownId}
|
|
205
|
+
ref={dropdownRef}
|
|
201
206
|
className={classnames(
|
|
202
207
|
styles.dropdown,
|
|
203
208
|
'bg-white br8 p8 d-flex fd-column',
|
|
204
|
-
{ [styles.
|
|
209
|
+
{ [styles.dropdownYTop]: dropUp || alignY === 'top', [styles.dropdownXRight]: alignX === 'right' }
|
|
205
210
|
)}
|
|
206
211
|
>
|
|
207
212
|
{searchable && (
|
|
208
|
-
<div className=
|
|
213
|
+
<div className="pb8 bg-white">
|
|
209
214
|
<Input
|
|
210
215
|
ref={searchInputRef}
|
|
211
216
|
type="text"
|
|
@@ -58,7 +58,12 @@
|
|
|
58
58
|
z-index: 10;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
.
|
|
61
|
+
.dropdownXRight {
|
|
62
|
+
left: auto;
|
|
63
|
+
right: 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.dropdownYTop {
|
|
62
67
|
top: auto;
|
|
63
68
|
bottom: calc(100% + 4px);
|
|
64
69
|
|
|
@@ -73,11 +78,6 @@
|
|
|
73
78
|
}
|
|
74
79
|
}
|
|
75
80
|
|
|
76
|
-
.searchContainer {
|
|
77
|
-
position: sticky;
|
|
78
|
-
top: 0;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
81
|
.optionList {
|
|
82
82
|
max-height: 308px;
|
|
83
83
|
overflow-y: auto;
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { renderHook, act } from '@testing-library/react-hooks';
|
|
2
|
+
import { RefObject } from 'react';
|
|
3
|
+
|
|
4
|
+
import { useDropdownAlignment } from './useDropdownAlignment';
|
|
5
|
+
|
|
6
|
+
const createRef = <T>(value: T | null = null): RefObject<T | null> => ({
|
|
7
|
+
current: value,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const mockContainerRect = (rect: Partial<DOMRect>) =>
|
|
11
|
+
({
|
|
12
|
+
top: 0,
|
|
13
|
+
bottom: 0,
|
|
14
|
+
left: 0,
|
|
15
|
+
right: 0,
|
|
16
|
+
width: 0,
|
|
17
|
+
height: 0,
|
|
18
|
+
x: 0,
|
|
19
|
+
y: 0,
|
|
20
|
+
toJSON: () => {},
|
|
21
|
+
...rect,
|
|
22
|
+
}) as DOMRect;
|
|
23
|
+
|
|
24
|
+
describe('useDropdownAlignment', () => {
|
|
25
|
+
let containerEl: HTMLElement;
|
|
26
|
+
let dropdownEl: HTMLElement;
|
|
27
|
+
let containerRef: RefObject<HTMLElement | null>;
|
|
28
|
+
let dropdownRef: RefObject<HTMLElement | null>;
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
jest.clearAllMocks();
|
|
32
|
+
|
|
33
|
+
window.innerWidth = 1024;
|
|
34
|
+
window.innerHeight = 768;
|
|
35
|
+
|
|
36
|
+
containerEl = document.createElement('div');
|
|
37
|
+
dropdownEl = document.createElement('div');
|
|
38
|
+
|
|
39
|
+
containerRef = createRef(containerEl);
|
|
40
|
+
dropdownRef = createRef(dropdownEl);
|
|
41
|
+
|
|
42
|
+
Object.defineProperty(dropdownEl, 'offsetWidth', {
|
|
43
|
+
value: 200,
|
|
44
|
+
configurable: true,
|
|
45
|
+
});
|
|
46
|
+
Object.defineProperty(dropdownEl, 'offsetHeight', {
|
|
47
|
+
value: 300,
|
|
48
|
+
configurable: true,
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should return alignX as left and alignY as bottom by default', () => {
|
|
53
|
+
const { result } = renderHook(() =>
|
|
54
|
+
useDropdownAlignment(containerRef, dropdownRef, false)
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
expect(result.current.alignX).toBe('left');
|
|
58
|
+
expect(result.current.alignY).toBe('bottom');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should not compute alignment when isOpen is false', () => {
|
|
62
|
+
jest
|
|
63
|
+
.spyOn(containerEl, 'getBoundingClientRect')
|
|
64
|
+
.mockReturnValue(mockContainerRect({ left: 900, bottom: 600, top: 600 }));
|
|
65
|
+
|
|
66
|
+
renderHook(() => useDropdownAlignment(containerRef, dropdownRef, false));
|
|
67
|
+
|
|
68
|
+
expect(containerEl.getBoundingClientRect).not.toHaveBeenCalled();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should not compute alignment when refs are null', () => {
|
|
72
|
+
const nullContainerRef = createRef<HTMLElement>(null);
|
|
73
|
+
const nullDropdownRef = createRef<HTMLElement>(null);
|
|
74
|
+
|
|
75
|
+
const { result } = renderHook(() =>
|
|
76
|
+
useDropdownAlignment(nullContainerRef, nullDropdownRef, true)
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
expect(result.current.alignX).toBe('left');
|
|
80
|
+
expect(result.current.alignY).toBe('bottom');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('horizontal alignment', () => {
|
|
84
|
+
it('should set alignX to left when there is enough space on the right', () => {
|
|
85
|
+
jest.spyOn(containerEl, 'getBoundingClientRect').mockReturnValue(
|
|
86
|
+
mockContainerRect({ left: 100, bottom: 100, top: 100 })
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const { result } = renderHook(() =>
|
|
90
|
+
useDropdownAlignment(containerRef, dropdownRef, true)
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// spaceOnRight = 1024 - 100 = 924, dropdownWidth = 200 → enough space
|
|
94
|
+
expect(result.current.alignX).toBe('left');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should set alignX to right when there is not enough space on the right', () => {
|
|
98
|
+
jest.spyOn(containerEl, 'getBoundingClientRect').mockReturnValue(
|
|
99
|
+
mockContainerRect({ left: 900, bottom: 100, top: 100 })
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const { result } = renderHook(() =>
|
|
103
|
+
useDropdownAlignment(containerRef, dropdownRef, true)
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
// spaceOnRight = 1024 - 900 = 124, dropdownWidth = 200 → not enough space
|
|
107
|
+
expect(result.current.alignX).toBe('right');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('vertical alignment', () => {
|
|
112
|
+
it('should set alignY to bottom when there is enough space below', () => {
|
|
113
|
+
jest.spyOn(containerEl, 'getBoundingClientRect').mockReturnValue(
|
|
114
|
+
mockContainerRect({ left: 100, bottom: 100, top: 100 })
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const { result } = renderHook(() =>
|
|
118
|
+
useDropdownAlignment(containerRef, dropdownRef, true)
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// spaceBelow = 768 - 100 = 668, dropdownHeight = 300 → enough space
|
|
122
|
+
expect(result.current.alignY).toBe('bottom');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should set alignY to top when not enough space below and more space above', () => {
|
|
126
|
+
jest.spyOn(containerEl, 'getBoundingClientRect').mockReturnValue(
|
|
127
|
+
mockContainerRect({ left: 100, bottom: 600, top: 600 })
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const { result } = renderHook(() =>
|
|
131
|
+
useDropdownAlignment(containerRef, dropdownRef, true)
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// spaceBelow = 768 - 600 = 168, dropdownHeight = 300 → not enough below
|
|
135
|
+
// containerRect.top = 600 > spaceBelow = 168 → more space above
|
|
136
|
+
expect(result.current.alignY).toBe('top');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should set alignY to bottom when not enough space below but more space below than above', () => {
|
|
140
|
+
jest.spyOn(containerEl, 'getBoundingClientRect').mockReturnValue(
|
|
141
|
+
mockContainerRect({ left: 100, bottom: 500, top: 100 })
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
const { result } = renderHook(() =>
|
|
145
|
+
useDropdownAlignment(containerRef, dropdownRef, true)
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// spaceBelow = 768 - 500 = 268, dropdownHeight = 300 → not enough below
|
|
149
|
+
// containerRect.top = 100 < spaceBelow = 268 → more space below
|
|
150
|
+
expect(result.current.alignY).toBe('bottom');
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('ResizeObserver', () => {
|
|
155
|
+
it('should observe document.documentElement when isOpen is true', () => {
|
|
156
|
+
jest
|
|
157
|
+
.spyOn(containerEl, 'getBoundingClientRect')
|
|
158
|
+
.mockReturnValue(mockContainerRect({ left: 100, bottom: 100, top: 100 }));
|
|
159
|
+
|
|
160
|
+
renderHook(() => useDropdownAlignment(containerRef, dropdownRef, true));
|
|
161
|
+
|
|
162
|
+
const observerInstance = (ResizeObserver as jest.Mock).mock.results[0].value;
|
|
163
|
+
expect(observerInstance.observe).toHaveBeenCalledWith(
|
|
164
|
+
document.documentElement
|
|
165
|
+
);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should disconnect observer when isOpen changes to false', () => {
|
|
169
|
+
jest
|
|
170
|
+
.spyOn(containerEl, 'getBoundingClientRect')
|
|
171
|
+
.mockReturnValue(mockContainerRect({ left: 100, bottom: 100, top: 100 }));
|
|
172
|
+
|
|
173
|
+
const { rerender } = renderHook(
|
|
174
|
+
({ isOpen }) => useDropdownAlignment(containerRef, dropdownRef, isOpen),
|
|
175
|
+
{ initialProps: { isOpen: true } }
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const observerInstance = (ResizeObserver as jest.Mock).mock.results[0].value;
|
|
179
|
+
|
|
180
|
+
rerender({ isOpen: false });
|
|
181
|
+
|
|
182
|
+
expect(observerInstance.disconnect).toHaveBeenCalled();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('should recalculate alignment when ResizeObserver fires', () => {
|
|
186
|
+
jest
|
|
187
|
+
.spyOn(containerEl, 'getBoundingClientRect')
|
|
188
|
+
.mockReturnValue(mockContainerRect({ left: 100, bottom: 100, top: 100 }));
|
|
189
|
+
|
|
190
|
+
const { result } = renderHook(() =>
|
|
191
|
+
useDropdownAlignment(containerRef, dropdownRef, true)
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
expect(result.current.alignX).toBe('left');
|
|
195
|
+
|
|
196
|
+
// Simulate viewport change: now not enough space on the right
|
|
197
|
+
jest
|
|
198
|
+
.spyOn(containerEl, 'getBoundingClientRect')
|
|
199
|
+
.mockReturnValue(mockContainerRect({ left: 900, bottom: 100, top: 100 }));
|
|
200
|
+
|
|
201
|
+
// Get the callback passed to ResizeObserver and invoke it
|
|
202
|
+
const observerCallback = (ResizeObserver as jest.Mock).mock.calls[0][0];
|
|
203
|
+
act(() => {
|
|
204
|
+
observerCallback();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
expect(result.current.alignX).toBe('right');
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { RefObject, useCallback, useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
export const useDropdownAlignment = (
|
|
4
|
+
containerRef: RefObject<HTMLElement | null>,
|
|
5
|
+
dropdownRef: RefObject<HTMLElement | null>,
|
|
6
|
+
isOpen: boolean
|
|
7
|
+
) => {
|
|
8
|
+
const [alignX, setAlignX] = useState<'left' | 'right'>('left');
|
|
9
|
+
const [alignY, setAlignY] = useState<'top' | 'bottom'>('bottom');
|
|
10
|
+
|
|
11
|
+
const updateAlignment = useCallback(() => {
|
|
12
|
+
if (containerRef.current && dropdownRef.current) {
|
|
13
|
+
const containerRect = containerRef.current.getBoundingClientRect();
|
|
14
|
+
const dropdownWidth = dropdownRef.current.offsetWidth;
|
|
15
|
+
const dropdownHeight = dropdownRef.current.offsetHeight;
|
|
16
|
+
const spaceOnRight = window.innerWidth - containerRect.left;
|
|
17
|
+
const spaceBelow = window.innerHeight - containerRect.bottom;
|
|
18
|
+
setAlignX(spaceOnRight < dropdownWidth ? 'right' : 'left');
|
|
19
|
+
setAlignY(spaceBelow < dropdownHeight && containerRect.top > spaceBelow ? 'top' : 'bottom');
|
|
20
|
+
}
|
|
21
|
+
}, [containerRef, dropdownRef]);
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!isOpen) return;
|
|
25
|
+
|
|
26
|
+
updateAlignment();
|
|
27
|
+
|
|
28
|
+
const observer = new ResizeObserver(updateAlignment);
|
|
29
|
+
observer.observe(document.documentElement);
|
|
30
|
+
return () => observer.disconnect();
|
|
31
|
+
}, [isOpen, updateAlignment]);
|
|
32
|
+
|
|
33
|
+
return { alignX, alignY };
|
|
34
|
+
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-DgTZdYln.js","sources":["../../../src/lib/hooks/useEscapeKey.ts","../../../src/lib/components/searchableDropdown/index.tsx"],"sourcesContent":["import { useCallback, useEffect } from 'react';\n\nexport const useEscapeKey = (callback: () => void) => {\n const handleOnEscape = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n callback();\n }\n },\n [callback]\n );\n\n useEffect(() => {\n window.addEventListener('keydown', handleOnEscape);\n\n return () => window.removeEventListener('keydown', handleOnEscape);\n }, [handleOnEscape]);\n};\n","import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport classnames from 'classnames';\n\nimport { Input } from '../input';\nimport { ChevronDownIcon } from '../icon';\nimport { useEscapeKey } from '../../hooks/useEscapeKey';\nimport { useOnClickOutside } from '../../hooks/useOnClickOutside';\nimport generateId from '../../util/generateId';\n\nimport styles from './style.module.scss';\n\nexport interface SearchableDropdownOption {\n id: string;\n label: string;\n icon?: ReactNode;\n}\n\nexport interface SearchableDropdownProps {\n options: SearchableDropdownOption[];\n value: string | null;\n onChange: (value: string) => void;\n searchable?: boolean;\n placeholder?: string;\n triggerPlaceholder?: string;\n noResultsText?: string;\n groupName?: string;\n dropUp?: boolean;\n condensed?: boolean;\n bordered?: boolean;\n showChevron?: boolean;\n disabled?: boolean;\n}\n\nexport const SearchableDropdown = ({\n options,\n value,\n onChange,\n searchable = false,\n placeholder = 'Search',\n triggerPlaceholder,\n noResultsText = 'No results found',\n groupName: groupNameProp,\n dropUp = false,\n condensed = false,\n bordered = false,\n showChevron = false,\n disabled = false,\n}: SearchableDropdownProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [searchTerm, setSearchTerm] = useState('');\n const [localValue, setLocalValue] = useState(value);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const optionRefs = useRef<Map<string, HTMLInputElement>>(new Map());\n const [groupName] = useState(() => groupNameProp ?? `sd-${generateId()}`);\n const dropdownId = `${groupName}-dropdown`;\n\n const closeAndRestoreFocus = useCallback(() => {\n setIsOpen(false);\n triggerRef.current?.focus();\n }, []);\n\n useOnClickOutside(containerRef, () => isOpen && closeAndRestoreFocus());\n useEscapeKey(\n useCallback(() => {\n if (isOpen) closeAndRestoreFocus();\n }, [isOpen, closeAndRestoreFocus])\n );\n\n useEffect(() => {\n if (isOpen && searchable && searchInputRef.current) {\n searchInputRef.current.focus();\n }\n }, [isOpen, searchable]);\n\n useEffect(() => {\n if (!isOpen) {\n setSearchTerm('');\n setLocalValue(value);\n }\n }, [isOpen, value]);\n\n const filteredOptions = useMemo(() => {\n if (!searchTerm) return options;\n return [...options]\n .filter((option) =>\n option.label.toLowerCase().includes(searchTerm.toLowerCase())\n )\n .sort((a, b) => {\n const term = searchTerm.toLowerCase();\n const aStartsWith = a.label.toLowerCase().startsWith(term);\n const bStartsWith = b.label.toLowerCase().startsWith(term);\n if (aStartsWith && !bStartsWith) return -1;\n if (!aStartsWith && bStartsWith) return 1;\n return 0;\n });\n }, [options, searchTerm]);\n\n const selectedOption = options.find((option) => option.id === value);\n\n const handleTriggerClick = () => {\n if (!disabled) setIsOpen(!isOpen);\n };\n\n const handleSearchKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n const target =\n e.key === 'ArrowDown'\n ? filteredOptions[0]\n : filteredOptions[filteredOptions.length - 1];\n if (target) {\n setLocalValue(target.id);\n optionRefs.current.get(target.id)?.focus();\n }\n } else if (e.key === 'Enter') {\n e.preventDefault();\n const target = filteredOptions[0];\n if (target) {\n onChange(target.id);\n closeAndRestoreFocus();\n }\n }\n };\n\n const handleOptionClick = (optionId: string) => {\n onChange(optionId);\n closeAndRestoreFocus();\n };\n\n const handleOptionRef = (optionId: string, el: HTMLInputElement | null) => {\n if (el) optionRefs.current.set(optionId, el);\n else optionRefs.current.delete(optionId);\n };\n\n const handleOptionKeyDown = (e: React.KeyboardEvent, optionId: string) => {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n const currentIndex = filteredOptions.findIndex(\n (o) => o.id === optionId\n );\n const nextIndex =\n e.key === 'ArrowDown'\n ? Math.min(currentIndex + 1, filteredOptions.length - 1)\n : Math.max(currentIndex - 1, 0);\n const next = filteredOptions[nextIndex];\n if (next) {\n setLocalValue(next.id);\n optionRefs.current.get(next.id)?.focus();\n }\n } else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onChange(optionId);\n closeAndRestoreFocus();\n }\n };\n\n return (\n <div className={classnames(styles.container, { 'd-inline-block': condensed })} ref={containerRef}>\n <button\n ref={triggerRef}\n type=\"button\"\n className={classnames(\n 'd-flex ai-center jc-between w100 br8 bg-white c-pointer ta-left tc-neutral-900',\n styles.selectTrigger, {\n [styles.selectTriggerOpen]: isOpen,\n [styles.condensed]: condensed,\n [styles.bordered]: bordered,\n [styles.disabled]: disabled,\n }\n )}\n onClick={handleTriggerClick}\n disabled={disabled}\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-controls={isOpen ? dropdownId : undefined}\n >\n <span className={'d-flex ai-center gap8'}>\n {selectedOption?.icon && (\n <span className={styles.optionIcon}>{selectedOption.icon}</span>\n )}\n {!condensed && (\n <span className=\"p-p\">\n {selectedOption?.label ?? triggerPlaceholder}\n </span>\n )}\n </span>\n {showChevron && (\n <ChevronDownIcon\n className={classnames('ml8', { [styles.chevronOpen]: isOpen })}\n size={20}\n noMargin\n color=\"neutral-600\"\n />\n )}\n </button>\n {isOpen && (\n <div\n id={dropdownId}\n className={classnames(\n styles.dropdown,\n 'bg-white br8 p8 d-flex fd-column',\n { [styles.dropdownUp]: dropUp }\n )}\n >\n {searchable && (\n <div className={classnames('pb8 bg-white', styles.searchContainer)}>\n <Input\n ref={searchInputRef}\n type=\"text\"\n placeholder={placeholder}\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n label={placeholder}\n hideLabel\n onKeyDown={handleSearchKeyDown}\n />\n </div>\n )}\n <div className={styles.optionList} role=\"radiogroup\" aria-label={groupName}>\n {filteredOptions.map((option) => (\n <div key={option.id} className={styles.optionWrapper}>\n <input\n type=\"radio\"\n id={`${groupName}-${option.id}`}\n name={groupName}\n value={option.id}\n checked={option.id === localValue}\n onChange={() => setLocalValue(option.id)}\n onClick={() => handleOptionClick(option.id)}\n tabIndex={option.id === localValue ? 0 : -1}\n className={styles.optionRadio}\n ref={(el) => handleOptionRef(option.id, el)}\n onKeyDown={(e) => handleOptionKeyDown(e, option.id)}\n />\n <label\n htmlFor={`${groupName}-${option.id}`}\n className={classnames(\n 'd-flex ai-center gap8 w100 br8 c-pointer ta-left tc-neutral-900',\n styles.option, {\n [styles.optionSelected]: option.id === localValue,\n })}\n >\n {option.icon && (\n <span className={styles.optionIcon}>{option.icon}</span>\n )}\n <span className=\"p-p\">{option.label}</span>\n </label>\n </div>\n ))}\n {filteredOptions.length === 0 && (\n <p className={`p-p tc-neutral-500 ${styles.noResults}`}>\n {noResultsText}\n </p>\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n"],"names":["_jsxs","classnames","_jsx"],"mappings":"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"}
|