@puzzle-ui/ui 0.3.0 → 0.4.0

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.
Files changed (100) hide show
  1. package/README.md +71 -70
  2. package/dist/components/data-display/empty-state/empty-state.css +128 -0
  3. package/dist/components/data-display/empty-state/empty-state.utils.cjs +6 -0
  4. package/dist/components/data-display/empty-state/empty-state.utils.cjs.map +1 -0
  5. package/dist/components/data-display/empty-state/empty-state.utils.js +6 -0
  6. package/dist/components/data-display/empty-state/empty-state.utils.js.map +1 -0
  7. package/dist/components/data-display/empty-state/index.cjs +49 -0
  8. package/dist/components/data-display/empty-state/index.cjs.map +1 -0
  9. package/dist/components/data-display/empty-state/index.d.cts +19 -0
  10. package/dist/components/data-display/empty-state/index.d.ts +19 -0
  11. package/dist/components/data-display/empty-state/index.js +44 -0
  12. package/dist/components/data-display/empty-state/index.js.map +1 -0
  13. package/dist/components/editors/text-editor/editor.cjs.map +1 -1
  14. package/dist/components/editors/text-editor/editor.js.map +1 -1
  15. package/dist/components/editors/text-editor/text-document.cjs.map +1 -1
  16. package/dist/components/editors/text-editor/text-document.js.map +1 -1
  17. package/dist/components/editors/text-editor/text-parser.cjs.map +1 -1
  18. package/dist/components/editors/text-editor/text-parser.js.map +1 -1
  19. package/dist/components/editors/text-editor/text-renderer.cjs.map +1 -1
  20. package/dist/components/editors/text-editor/text-renderer.js.map +1 -1
  21. package/dist/components/forms/autocomplete/index.cjs.map +1 -1
  22. package/dist/components/forms/autocomplete/index.js.map +1 -1
  23. package/dist/components/forms/color-picker/color-picker.css +351 -0
  24. package/dist/components/forms/color-picker/color-picker.types.d.cts +25 -0
  25. package/dist/components/forms/color-picker/color-picker.types.d.ts +25 -0
  26. package/dist/components/forms/color-picker/color-picker.utils.cjs +116 -0
  27. package/dist/components/forms/color-picker/color-picker.utils.cjs.map +1 -0
  28. package/dist/components/forms/color-picker/color-picker.utils.js +109 -0
  29. package/dist/components/forms/color-picker/color-picker.utils.js.map +1 -0
  30. package/dist/components/forms/color-picker/index.cjs +340 -0
  31. package/dist/components/forms/color-picker/index.cjs.map +1 -0
  32. package/dist/components/forms/color-picker/index.d.cts +3 -0
  33. package/dist/components/forms/color-picker/index.d.ts +3 -0
  34. package/dist/components/forms/color-picker/index.js +340 -0
  35. package/dist/components/forms/color-picker/index.js.map +1 -0
  36. package/dist/components/forms/file-upload/file-upload.utils.cjs.map +1 -1
  37. package/dist/components/forms/file-upload/file-upload.utils.js.map +1 -1
  38. package/dist/components/forms/input/number-input.js +5 -5
  39. package/dist/components/forms/input/number-input.js.map +1 -1
  40. package/dist/components/forms/input-group/index.d.cts +3 -0
  41. package/dist/components/forms/input-group/index.d.ts +3 -0
  42. package/dist/components/forms/input-group/input-group.cjs +18 -0
  43. package/dist/components/forms/input-group/input-group.cjs.map +1 -0
  44. package/dist/components/forms/input-group/input-group.css +62 -0
  45. package/dist/components/forms/input-group/input-group.d.cts +5 -0
  46. package/dist/components/forms/input-group/input-group.d.ts +5 -0
  47. package/dist/components/forms/input-group/input-group.js +18 -0
  48. package/dist/components/forms/input-group/input-group.js.map +1 -0
  49. package/dist/components/forms/input-group/input-group.types.d.cts +7 -0
  50. package/dist/components/forms/input-group/input-group.types.d.ts +7 -0
  51. package/dist/components/forms/input-group/input-group.utils.cjs +5 -0
  52. package/dist/components/forms/input-group/input-group.utils.cjs.map +1 -0
  53. package/dist/components/forms/input-group/input-group.utils.js +5 -0
  54. package/dist/components/forms/input-group/input-group.utils.js.map +1 -0
  55. package/dist/components/forms/select/index.cjs.map +1 -1
  56. package/dist/components/forms/select/index.js.map +1 -1
  57. package/dist/components/forms/slider/index.cjs +1 -1
  58. package/dist/components/forms/slider/index.cjs.map +1 -1
  59. package/dist/components/forms/slider/index.js +1 -1
  60. package/dist/components/forms/slider/index.js.map +1 -1
  61. package/dist/components/layout/resizable-panels/index.cjs +1 -1
  62. package/dist/components/layout/resizable-panels/index.cjs.map +1 -1
  63. package/dist/components/layout/resizable-panels/index.js +1 -1
  64. package/dist/components/layout/resizable-panels/index.js.map +1 -1
  65. package/dist/components/layout/resizable-panels/resizable-panels.utils.cjs.map +1 -1
  66. package/dist/components/layout/resizable-panels/resizable-panels.utils.js.map +1 -1
  67. package/dist/components/navigation/accordion/index.cjs.map +1 -1
  68. package/dist/components/navigation/accordion/index.js.map +1 -1
  69. package/dist/components/navigation/carousel/index.cjs +1 -1
  70. package/dist/components/navigation/carousel/index.cjs.map +1 -1
  71. package/dist/components/navigation/carousel/index.js +1 -1
  72. package/dist/components/navigation/carousel/index.js.map +1 -1
  73. package/dist/components/navigation/pagination/index.cjs +146 -0
  74. package/dist/components/navigation/pagination/index.cjs.map +1 -0
  75. package/dist/components/navigation/pagination/index.d.cts +3 -0
  76. package/dist/components/navigation/pagination/index.d.ts +3 -0
  77. package/dist/components/navigation/pagination/index.js +146 -0
  78. package/dist/components/navigation/pagination/index.js.map +1 -0
  79. package/dist/components/navigation/pagination/pagination.css +134 -0
  80. package/dist/components/navigation/pagination/pagination.types.d.cts +38 -0
  81. package/dist/components/navigation/pagination/pagination.types.d.ts +38 -0
  82. package/dist/components/navigation/pagination/pagination.utils.cjs +54 -0
  83. package/dist/components/navigation/pagination/pagination.utils.cjs.map +1 -0
  84. package/dist/components/navigation/pagination/pagination.utils.js +53 -0
  85. package/dist/components/navigation/pagination/pagination.utils.js.map +1 -0
  86. package/dist/components/navigation/tree-view/index.cjs.map +1 -1
  87. package/dist/components/navigation/tree-view/index.js.map +1 -1
  88. package/dist/components/overlays/dropdown-menu/dropdown-menu-content.cjs.map +1 -1
  89. package/dist/components/overlays/dropdown-menu/dropdown-menu-content.js.map +1 -1
  90. package/dist/components/overlays/dropdown-menu/dropdown-menu.utils.cjs.map +1 -1
  91. package/dist/components/overlays/dropdown-menu/dropdown-menu.utils.js.map +1 -1
  92. package/dist/components/utilities/preview/index.cjs +1 -1
  93. package/dist/components/utilities/preview/index.cjs.map +1 -1
  94. package/dist/components/utilities/preview/index.js +1 -1
  95. package/dist/components/utilities/preview/index.js.map +1 -1
  96. package/dist/index.cjs +110 -97
  97. package/dist/index.d.cts +9 -1
  98. package/dist/index.d.ts +9 -1
  99. package/dist/index.js +5 -1
  100. package/package.json +6 -5
@@ -0,0 +1,62 @@
1
+ .puzzle-input-group {
2
+ box-sizing: border-box;
3
+ border: var(--puzzle-border-width, 1px) solid var(--puzzle-color-border);
4
+ border-radius: var(--puzzle-radius-md, .5rem);
5
+ background: var(--puzzle-color-surface);
6
+ width: 100%;
7
+ min-width: 0;
8
+ color: var(--puzzle-color-text);
9
+ transition: border-color var(--puzzle-duration-fast, .15s) var(--puzzle-easing-standard, ease),
10
+ box-shadow var(--puzzle-duration-fast, .15s) var(--puzzle-easing-standard, ease);
11
+ align-items: stretch;
12
+ display: flex;
13
+ }
14
+
15
+ .puzzle-input-group:focus-within {
16
+ border-color: var(--puzzle-color-ring);
17
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--puzzle-color-ring), transparent 82%);
18
+ }
19
+
20
+ .puzzle-input-group > .puzzle-input {
21
+ width: auto;
22
+ min-width: 0;
23
+ min-height: 2.375rem;
24
+ box-shadow: none;
25
+ background: none;
26
+ border: 0;
27
+ border-radius: 0;
28
+ flex: 1 1 0;
29
+ }
30
+
31
+ .puzzle-input-group > .puzzle-input:focus-within {
32
+ box-shadow: none;
33
+ border-color: #0000;
34
+ }
35
+
36
+ .puzzle-input-group__addon {
37
+ min-width: 0;
38
+ min-height: 2.375rem;
39
+ padding-inline: var(--puzzle-space-2, .5rem);
40
+ color: var(--puzzle-color-text-muted);
41
+ white-space: nowrap;
42
+ flex: none;
43
+ justify-content: center;
44
+ align-items: center;
45
+ display: inline-flex;
46
+ }
47
+
48
+ .puzzle-input-group__addon[data-align="start"] {
49
+ border-inline-end: 1px solid var(--puzzle-color-border);
50
+ order: -1;
51
+ }
52
+
53
+ .puzzle-input-group__addon[data-align="end"] {
54
+ border-inline-start: 1px solid var(--puzzle-color-border);
55
+ order: 1;
56
+ }
57
+
58
+ @media (prefers-reduced-motion: reduce) {
59
+ .puzzle-input-group {
60
+ transition: none;
61
+ }
62
+ }
@@ -0,0 +1,5 @@
1
+ import { InputGroupAddonProps, InputGroupProps } from "./input-group.types.cjs";
2
+ declare const InputGroup: (({ className, ...props }: InputGroupProps) => import("react").JSX.Element) & {
3
+ Addon: ({ align, className, ...props }: InputGroupAddonProps) => import("react").JSX.Element;
4
+ };
5
+ export { InputGroup };
@@ -0,0 +1,5 @@
1
+ import { InputGroupAddonProps, InputGroupProps } from "./input-group.types.js";
2
+ declare const InputGroup: (({ className, ...props }: InputGroupProps) => import("react").JSX.Element) & {
3
+ Addon: ({ align, className, ...props }: InputGroupAddonProps) => import("react").JSX.Element;
4
+ };
5
+ export { InputGroup };
@@ -0,0 +1,18 @@
1
+ import { resolveInputGroupAddonAlign } from "./input-group.utils.js";
2
+ import "./input-group.css";
3
+ import { cn } from "@puzzle-ui/core";
4
+ import { jsx } from "react/jsx-runtime";
5
+ // src/components/forms/input-group/input-group.tsx
6
+ const InputGroupAddon = ({ align, className, ...props }) => /* @__PURE__ */ jsx("div", {
7
+ ...props,
8
+ className: cn("puzzle-input-group__addon", className),
9
+ "data-align": resolveInputGroupAddonAlign(align)
10
+ });
11
+ const InputGroupRoot = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
12
+ ...props,
13
+ className: cn("puzzle-input-group", className)
14
+ });
15
+ const InputGroup = Object.assign(InputGroupRoot, { Addon: InputGroupAddon });
16
+ export { InputGroup };
17
+
18
+ //# sourceMappingURL=input-group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-group.js","names":[],"sources":["../../../../src/components/forms/input-group/input-group.tsx"],"sourcesContent":["import { cn } from \"@puzzle-ui/core\";\n\nimport { resolveInputGroupAddonAlign } from \"./input-group.utils\";\nimport type {\n InputGroupAddonProps,\n InputGroupProps,\n} from \"./input-group.types\";\n\nimport \"./input-group.css\";\n\nconst InputGroupAddon = ({\n align,\n className,\n ...props\n}: InputGroupAddonProps) => (\n <div\n {...props}\n className={cn(\"puzzle-input-group__addon\", className)}\n data-align={resolveInputGroupAddonAlign(align)}\n />\n);\n\nconst InputGroupRoot = ({ className, ...props }: InputGroupProps) => (\n <div {...props} className={cn(\"puzzle-input-group\", className)} />\n);\n\nconst InputGroup = Object.assign(InputGroupRoot, {\n Addon: InputGroupAddon,\n});\n\nexport { InputGroup };\n"],"mappings":";;;;;AAUA,MAAM,mBAAmB,EACvB,OACA,WACA,GAAG,YAEH,oBAAC,OAAD;CACE,GAAI;CACJ,WAAW,GAAG,6BAA6B,SAAS;CACpD,cAAY,4BAA4B,KAAK;AAC9C,CAAA;AAGH,MAAM,kBAAkB,EAAE,WAAW,GAAG,YACtC,oBAAC,OAAD;CAAK,GAAI;CAAO,WAAW,GAAG,sBAAsB,SAAS;AAAI,CAAA;AAGnE,MAAM,aAAa,OAAO,OAAO,gBAAgB,EAC/C,OAAO,gBACT,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { ComponentPropsWithRef } from "react";
2
+ type InputGroupAddonAlign = "start" | "end";
3
+ type InputGroupProps = ComponentPropsWithRef<"div">;
4
+ type InputGroupAddonProps = Omit<ComponentPropsWithRef<"div">, "align"> & {
5
+ align?: InputGroupAddonAlign;
6
+ };
7
+ export type { InputGroupAddonAlign, InputGroupAddonProps, InputGroupProps };
@@ -0,0 +1,7 @@
1
+ import { ComponentPropsWithRef } from "react";
2
+ type InputGroupAddonAlign = "start" | "end";
3
+ type InputGroupProps = ComponentPropsWithRef<"div">;
4
+ type InputGroupAddonProps = Omit<ComponentPropsWithRef<"div">, "align"> & {
5
+ align?: InputGroupAddonAlign;
6
+ };
7
+ export type { InputGroupAddonAlign, InputGroupAddonProps, InputGroupProps };
@@ -0,0 +1,5 @@
1
+ // src/components/forms/input-group/input-group.utils.ts
2
+ const resolveInputGroupAddonAlign = (align) => align ?? "start";
3
+ exports.resolveInputGroupAddonAlign = resolveInputGroupAddonAlign;
4
+
5
+ //# sourceMappingURL=input-group.utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-group.utils.cjs","names":[],"sources":["../../../../src/components/forms/input-group/input-group.utils.ts"],"sourcesContent":["import type { InputGroupAddonAlign } from \"./input-group.types\";\n\nconst resolveInputGroupAddonAlign = (\n align?: InputGroupAddonAlign,\n): InputGroupAddonAlign => align ?? \"start\";\n\nexport { resolveInputGroupAddonAlign };\n"],"mappings":";AAEA,MAAM,+BACJ,UACyB,SAAS"}
@@ -0,0 +1,5 @@
1
+ // src/components/forms/input-group/input-group.utils.ts
2
+ const resolveInputGroupAddonAlign = (align) => align ?? "start";
3
+ export { resolveInputGroupAddonAlign };
4
+
5
+ //# sourceMappingURL=input-group.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-group.utils.js","names":[],"sources":["../../../../src/components/forms/input-group/input-group.utils.ts"],"sourcesContent":["import type { InputGroupAddonAlign } from \"./input-group.types\";\n\nconst resolveInputGroupAddonAlign = (\n align?: InputGroupAddonAlign,\n): InputGroupAddonAlign => align ?? \"start\";\n\nexport { resolveInputGroupAddonAlign };\n"],"mappings":";AAEA,MAAM,+BACJ,UACyB,SAAS"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useId","useRef","useState","resolveResponsiveValue","useMemo","useCallback","cn","Popout"],"sources":["../../../../src/components/forms/select/index.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type ChangeEvent,\n type CSSProperties,\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n} from \"react\";\n\nimport { cn, resolveResponsiveValue, type ResponsiveValue } from \"@puzzle-ui/core\";\n\nimport {\n Popout,\n type PopoutAlignment,\n type PopoutPosition,\n type PopoutTriggerProps,\n} from \"../../overlays/popout\";\n\nimport \"./select.css\";\n\ntype SelectSize = \"sm\" | \"md\" | \"lg\";\n\ntype SelectOption<T = string> = {\n /** Stable identifier, useful when options are reordered. */\n id?: string | number;\n\n /** The value returned by onChange. */\n value: T;\n\n /** Plain-text label, also used for typeahead and accessibility. */\n label: string;\n\n /** Optional supporting text. */\n description?: ReactNode;\n\n /** Optional group heading. */\n group?: string;\n\n /** Prevents this option from being selected. */\n disabled?: boolean;\n};\n\ntype SelectOptionRenderState = {\n selected: boolean;\n active: boolean;\n multiple: boolean;\n};\n\ntype SelectBaseProps<T> = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\" | \"value\" | \"disabled\" | \"form\" | \"size\" | \"type\" | \"onChange\"\n> & {\n /** Available options. */\n options: readonly SelectOption<T>[];\n\n /** Optional visible field label. */\n label?: ReactNode;\n\n /** Text shown when no value is selected. */\n placeholder?: ReactNode;\n\n /** Supporting text below the control. */\n description?: ReactNode;\n\n /** Error message. Set to true to use the default message. */\n error?: ReactNode | boolean;\n\n /** Disables the entire control. */\n disabled?: boolean;\n\n /** Makes the field required. */\n required?: boolean;\n\n /** Allows the selected value(s) to be cleared. */\n clearable?: boolean;\n\n /** Accessible name of the clear button. */\n clearLabel?: string;\n\n /** Form field name. Adds a visually hidden native select. */\n name?: string;\n\n /** Form ID for form association. */\n form?: string;\n\n /** Native autocomplete attribute. */\n autoComplete?: string;\n\n /** Serializes generic values for native form submission. */\n serializeValue?: (value: T) => string;\n\n /** Custom comparison for object values. */\n isOptionEqualToValue?: (option: SelectOption<T>, value: T) => boolean;\n\n /** Custom rendering of the selected value(s). */\n renderValue?: (\n selected: SelectOption<T> | readonly SelectOption<T>[] | undefined,\n ) => ReactNode;\n\n /** Custom rendering of an option. */\n renderOption?: (\n option: SelectOption<T>,\n state: SelectOptionRenderState,\n ) => ReactNode;\n\n /** Responsive control size. */\n size?: ResponsiveValue<SelectSize>;\n\n /** Responsive full-width layout. */\n fullWidth?: ResponsiveValue<boolean>;\n\n /** Controls the dropdown visibility. */\n open?: boolean;\n\n /** Initial dropdown visibility. */\n defaultOpen?: boolean;\n\n /** Called when the dropdown visibility changes. */\n onOpenChange?: (open: boolean) => void;\n\n /** Dropdown placement. */\n position?: PopoutPosition;\n\n /** Dropdown alignment. */\n align?: PopoutAlignment;\n\n /** Distance between the trigger and dropdown. */\n offset?: number;\n\n /** Minimum distance from the viewport edges. */\n collisionPadding?: number;\n\n /** Whether the dropdown closes after selecting an option. */\n closeOnSelect?: boolean;\n\n /** Maximum number of simultaneously selected options. */\n maxSelected?: number;\n\n /** Match the dropdown's minimum width to the trigger. */\n matchTriggerWidth?: boolean;\n\n /** Maximum dropdown height. */\n menuMaxHeight?: CSSProperties[\"maxHeight\"];\n\n /** Content displayed when there are no options. */\n noOptionsText?: ReactNode;\n\n /** Additional class on the outer field. */\n rootClassName?: string;\n\n /** Additional class on the Popout content. */\n popoverClassName?: string;\n\n /** Additional class on the listbox. */\n menuClassName?: string;\n};\n\ntype SelectSingleProps<T = string> = SelectBaseProps<T> & {\n multiple?: false;\n\n /** Controlled selected value. Undefined represents no selection. */\n value?: T | undefined;\n\n /** Initial selected value. Undefined represents no selection. */\n defaultValue?: T | undefined;\n\n /** Called when the selected value changes. */\n onChange?: (value: T | undefined) => void;\n};\n\ntype SelectMultipleProps<T = string> = SelectBaseProps<T> & {\n multiple: true;\n\n /** Controlled selected values. */\n value?: readonly T[];\n\n /** Initial selected values. */\n defaultValue?: readonly T[];\n\n /** Called when the selected values change. */\n onChange?: (value: T[]) => void;\n};\n\ntype SelectProps<T = string> = SelectSingleProps<T> | SelectMultipleProps<T>;\n\nconst findEnabledIndex = <T,>(\n options: readonly SelectOption<T>[],\n startIndex: number,\n direction: -1 | 1,\n wrap = true,\n): number => {\n const length = options.length;\n\n for (let step = 1; step <= length; step++) {\n let index = startIndex + step * direction;\n\n if (wrap) {\n index = (index + length) % length;\n } else if (index < 0 || index >= length) {\n break;\n }\n\n if (!options[index].disabled) {\n return index;\n }\n }\n\n return -1;\n};\n\ntype IndexedOption<T> = {\n option: SelectOption<T>;\n index: number;\n};\n\ntype SelectGroup<T> = {\n label: string | null;\n options: IndexedOption<T>[];\n};\n\nconst groupOptions = <T,>(\n options: readonly SelectOption<T>[],\n): SelectGroup<T>[] => {\n const groups = new Map<string | null, SelectGroup<T>>();\n\n options.forEach((option, index) => {\n const label = option.group ?? null;\n\n let group = groups.get(label);\n\n if (!group) {\n group = {\n label,\n options: [],\n };\n\n groups.set(label, group);\n }\n\n group.options.push({ option, index });\n });\n\n return Array.from(groups.values());\n};\n\nconst Select = <T,>(props: SelectProps<T>) => {\n const {\n options,\n label,\n placeholder = \"Select an option\",\n description,\n error,\n disabled = false,\n required = false,\n clearable = false,\n clearLabel = \"Clear selection\",\n name,\n form,\n autoComplete,\n serializeValue,\n isOptionEqualToValue,\n renderValue,\n renderOption,\n size = \"md\",\n fullWidth = false,\n open,\n defaultOpen = false,\n onOpenChange,\n position = \"bottom\",\n align = \"start\",\n offset = 8,\n collisionPadding = 8,\n closeOnSelect: closeOnSelectProp,\n maxSelected,\n matchTriggerWidth = true,\n menuMaxHeight = \"18rem\",\n noOptionsText = \"No options\",\n rootClassName,\n popoverClassName,\n menuClassName,\n value,\n onChange,\n id,\n className,\n onClick,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n ...buttonProps\n } = props;\n\n const multiple = props.multiple === true;\n\n // Property presence matters because value={undefined} is a controlled\n // single-select with no selected value.\n const controlledValue = Object.prototype.hasOwnProperty.call(props, \"value\");\n\n const controlledOpen = open !== undefined;\n\n const baseId = useId();\n const triggerId = id ?? `${baseId}-trigger`;\n const labelId = `${baseId}-label`;\n const descriptionId = `${baseId}-description`;\n const errorId = `${baseId}-error`;\n const listboxId = `${baseId}-listbox`;\n\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const listboxRef = useRef<HTMLDivElement | null>(null);\n\n const typeaheadRef = useRef({\n query: \"\",\n timestamp: 0,\n });\n\n const [internalValue, setInternalValue] = useState<\n T | readonly T[] | undefined\n >(() =>\n multiple\n ? ((props as SelectMultipleProps<T>).defaultValue ?? [])\n : (props as SelectSingleProps<T>).defaultValue,\n );\n\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [triggerWidth, setTriggerWidth] = useState(0);\n\n const selectedValue = controlledValue ? value : internalValue;\n\n const selectedValues: readonly T[] = multiple\n ? ((selectedValue as readonly T[] | undefined) ?? [])\n : selectedValue === undefined\n ? []\n : [selectedValue as T];\n\n const isOpen = open ?? internalOpen;\n const hasSelection = selectedValues.length > 0;\n\n const hasError = error !== undefined && error !== null && error !== false;\n\n const isAriaInvalid =\n ariaInvalid !== undefined &&\n ariaInvalid !== false &&\n ariaInvalid !== \"false\";\n\n const isInvalid = hasError || isAriaInvalid;\n\n const resolvedAriaInvalid = isInvalid\n ? hasError || ariaInvalid === true\n ? true\n : ariaInvalid\n : ariaInvalid;\n\n const errorContent = error === true ? \"Invalid value\" : error;\n\n const closeOnSelect = closeOnSelectProp ?? !multiple;\n\n const responsiveSize = resolveResponsiveValue(size, \"md\");\n const responsiveFullWidth = resolveResponsiveValue(fullWidth, false);\n\n const groups = useMemo(() => groupOptions(options), [options]);\n\n const isEqual = useCallback(\n (option: SelectOption<T>, selected: T) =>\n isOptionEqualToValue\n ? isOptionEqualToValue(option, selected)\n : Object.is(option.value, selected),\n [isOptionEqualToValue],\n );\n\n const selectedOptions = selectedValues\n .map((selected) => options.find((option) => isEqual(option, selected)))\n .filter((option): option is SelectOption<T> => option !== undefined);\n\n const isSelected = (option: SelectOption<T>) =>\n selectedValues.some((selected) => isEqual(option, selected));\n\n const initialActiveIndex = useCallback(\n (direction: -1 | 1 = 1) => {\n const selectedIndex = options.findIndex(\n (option) =>\n !option.disabled &&\n selectedValues.some((selected) => isEqual(option, selected)),\n );\n\n if (selectedIndex !== -1) {\n return selectedIndex;\n }\n\n return direction === 1\n ? findEnabledIndex(options, -1, 1, false)\n : findEnabledIndex(options, options.length, -1, false);\n },\n [options, selectedValues, isEqual],\n );\n\n const changeOpenState = useCallback(\n (nextOpen: boolean) => {\n if (!controlledOpen) {\n setInternalOpen(nextOpen);\n }\n\n onOpenChange?.(nextOpen);\n },\n [controlledOpen, onOpenChange],\n );\n\n const updateValue = useCallback(\n (nextValue: T | readonly T[] | undefined) => {\n if (!controlledValue) {\n setInternalValue(nextValue);\n }\n\n if (multiple) {\n const callback = onChange as\n | SelectMultipleProps<T>[\"onChange\"]\n | undefined;\n\n callback?.([...(nextValue as readonly T[])]);\n } else {\n const callback = onChange as\n | SelectSingleProps<T>[\"onChange\"]\n | undefined;\n\n callback?.(nextValue as T | undefined);\n }\n },\n [controlledValue, multiple, onChange],\n );\n\n const getSerializedValue = useCallback(\n (selected: T) =>\n serializeValue ? serializeValue(selected) : String(selected),\n [serializeValue],\n );\n\n const findTypeaheadMatch = (\n character: string,\n startIndex: number,\n ): number => {\n if (options.length === 0) {\n return -1;\n }\n\n const now = Date.now();\n const previous = typeaheadRef.current;\n\n const query =\n now - previous.timestamp > 700 ? character : previous.query + character;\n\n typeaheadRef.current = {\n query,\n timestamp: now,\n };\n\n const repeatedCharacter =\n query.length > 1 &&\n Array.from(query).every(\n (item) => item.toLowerCase() === query[0].toLowerCase(),\n );\n\n const search = repeatedCharacter ? character : query;\n const normalizedSearch = search.toLocaleLowerCase();\n\n for (let offset = 1; offset <= options.length; offset++) {\n const index = (startIndex + offset + options.length) % options.length;\n const option = options[index];\n\n if (\n !option.disabled &&\n option.label.toLocaleLowerCase().startsWith(normalizedSearch)\n ) {\n return index;\n }\n }\n\n return -1;\n };\n\n const focusTrigger = () => {\n triggerRef.current?.focus({ preventScroll: true });\n };\n\n const handleOptionSelect = (option: SelectOption<T>) => {\n if (disabled || option.disabled) {\n return;\n }\n\n const currentlySelected = isSelected(option);\n\n if (multiple) {\n if (\n !currentlySelected &&\n maxSelected !== undefined &&\n selectedValues.length >= maxSelected\n ) {\n return;\n }\n\n const nextValues = currentlySelected\n ? selectedValues.filter((selected) => !isEqual(option, selected))\n : [...selectedValues, option.value];\n\n updateValue(nextValues);\n } else {\n updateValue(option.value);\n }\n\n if (closeOnSelect) {\n changeOpenState(false);\n focusTrigger();\n }\n };\n\n const handleClear = () => {\n if (!hasSelection || disabled) {\n return;\n }\n\n updateValue(multiple ? [] : undefined);\n focusTrigger();\n };\n\n const handleTriggerRef = useCallback((node: HTMLElement | null) => {\n triggerRef.current = node as HTMLButtonElement | null;\n }, []);\n\n const handleListboxRef = useCallback((node: HTMLDivElement | null) => {\n listboxRef.current = node;\n }, []);\n\n const handleTriggerClick = (event: ReactMouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (event.defaultPrevented || disabled) {\n return;\n }\n\n // Prevent Popout's default click action. We control its state here\n // so that the trigger correctly toggles the dropdown.\n event.preventDefault();\n\n if (!isOpen) {\n setActiveIndex(initialActiveIndex());\n }\n\n changeOpenState(!isOpen);\n };\n\n const handleTriggerKeyDown = (\n event: ReactKeyboardEvent<HTMLButtonElement>,\n ) => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented || disabled) {\n return;\n }\n\n if (isOpen) {\n handleComboboxKeyDown(event);\n return;\n }\n\n if (\n event.key === \"ArrowDown\" ||\n event.key === \"ArrowUp\" ||\n event.key === \"Enter\" ||\n event.key === \" \"\n ) {\n event.preventDefault();\n\n setActiveIndex(initialActiveIndex(event.key === \"ArrowUp\" ? -1 : 1));\n changeOpenState(true);\n\n return;\n }\n\n if (\n event.key.length === 1 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n const index = findTypeaheadMatch(event.key, activeIndex);\n\n if (index !== -1) {\n event.preventDefault();\n setActiveIndex(index);\n\n if (!isOpen) {\n changeOpenState(true);\n }\n }\n }\n };\n\n const handleTriggerKeyUp = (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n onKeyUp?.(event);\n\n // Prevent Space from producing a second click in Firefox.\n if (event.key === \" \") {\n event.preventDefault();\n }\n };\n\n const moveActive = (direction: -1 | 1, amount = 1, wrap = true) => {\n let nextIndex = activeIndex;\n\n for (let step = 0; step < amount; step++) {\n const startIndex =\n nextIndex === -1 ? (direction === 1 ? -1 : options.length) : nextIndex;\n\n const next = findEnabledIndex(options, startIndex, direction, wrap);\n\n if (next === -1) {\n break;\n }\n\n nextIndex = next;\n }\n\n if (nextIndex !== -1) {\n setActiveIndex(nextIndex);\n }\n };\n\n const handleComboboxKeyDown = (event: ReactKeyboardEvent<HTMLElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n moveActive(1);\n return;\n\n case \"ArrowUp\":\n event.preventDefault();\n moveActive(-1);\n return;\n\n case \"Home\":\n event.preventDefault();\n setActiveIndex(findEnabledIndex(options, -1, 1, false));\n return;\n\n case \"End\":\n event.preventDefault();\n setActiveIndex(findEnabledIndex(options, options.length, -1, false));\n return;\n\n case \"PageDown\":\n event.preventDefault();\n moveActive(1, 10, false);\n return;\n\n case \"PageUp\":\n event.preventDefault();\n moveActive(-1, 10, false);\n return;\n\n case \"Enter\":\n case \" \":\n event.preventDefault();\n\n if (activeIndex >= 0 && options[activeIndex]) {\n handleOptionSelect(options[activeIndex]);\n }\n\n return;\n\n case \"Escape\":\n event.preventDefault();\n event.stopPropagation();\n\n changeOpenState(false);\n focusTrigger();\n return;\n\n case \"Tab\":\n changeOpenState(false);\n return;\n\n default:\n break;\n }\n\n if (\n event.key.length === 1 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n event.preventDefault();\n\n const index = findTypeaheadMatch(event.key, activeIndex);\n\n if (index !== -1) {\n setActiveIndex(index);\n }\n }\n };\n\n const handleNativeChange = (event: ChangeEvent<HTMLSelectElement>) => {\n const serializedValues = new Set(\n Array.from(event.currentTarget.selectedOptions, (option) => option.value),\n );\n\n const nextValues = options\n .filter((option) =>\n serializedValues.has(getSerializedValue(option.value)),\n )\n .map((option) => option.value);\n\n updateValue(multiple ? nextValues : nextValues[0]);\n };\n\n // Initialize or recover the active option when opening.\n useEffect(() => {\n if (\n isOpen &&\n (activeIndex < 0 ||\n !options[activeIndex] ||\n options[activeIndex].disabled)\n ) {\n setActiveIndex(initialActiveIndex());\n }\n }, [isOpen, activeIndex, options, initialActiveIndex]);\n\n // Keep the active option visible during keyboard navigation.\n useEffect(() => {\n if (!isOpen || activeIndex < 0) {\n return;\n }\n\n const option = listboxRef.current?.ownerDocument.getElementById(\n `${listboxId}-option-${activeIndex}`,\n );\n\n option?.scrollIntoView({ block: \"nearest\" });\n }, [isOpen, activeIndex, listboxId]);\n\n // Match the menu's minimum width to the trigger.\n useLayoutEffect(() => {\n if (!isOpen || !matchTriggerWidth) {\n return;\n }\n\n const trigger = triggerRef.current;\n const ownerWindow = trigger?.ownerDocument.defaultView;\n\n if (!trigger || !ownerWindow) {\n return;\n }\n\n const updateWidth = () => {\n setTriggerWidth(trigger.getBoundingClientRect().width);\n };\n\n updateWidth();\n\n const ResizeObserverConstructor =\n ownerWindow.ResizeObserver ?? ResizeObserver;\n\n const observer = new ResizeObserverConstructor(updateWidth);\n observer.observe(trigger);\n\n ownerWindow.addEventListener(\"resize\", updateWidth);\n\n return () => {\n observer.disconnect();\n ownerWindow.removeEventListener(\"resize\", updateWidth);\n };\n }, [isOpen, matchTriggerWidth]);\n\n const activeOptionId =\n activeIndex >= 0 && options[activeIndex] && !options[activeIndex].disabled\n ? `${listboxId}-option-${activeIndex}`\n : undefined;\n\n const resolvedLabelledBy =\n ariaLabelledBy ?? (label != null ? labelId : undefined);\n\n const resolvedDescribedBy =\n [\n ariaDescribedBy,\n description != null ? descriptionId : undefined,\n hasError ? errorId : undefined,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n const displayValue = hasSelection\n ? renderValue\n ? renderValue(multiple ? selectedOptions : selectedOptions[0])\n : multiple\n ? selectedOptions.length\n ? selectedOptions.map((option) => option.label).join(\", \")\n : selectedValues.map(String).join(\", \")\n : (selectedOptions[0]?.label ?? String(selectedValues[0]))\n : placeholder;\n\n const listboxStyle: CSSProperties = {\n minWidth: matchTriggerWidth && triggerWidth > 0 ? triggerWidth : undefined,\n maxHeight: menuMaxHeight,\n };\n\n const triggerElement = (\n <button\n {...buttonProps}\n ref={handleTriggerRef}\n id={triggerId}\n type=\"button\"\n role=\"combobox\"\n disabled={disabled}\n className={cn(\"puzzle-select__trigger\", className)}\n onClick={handleTriggerClick}\n onKeyDown={handleTriggerKeyDown}\n onKeyUp={handleTriggerKeyUp}\n aria-label={ariaLabel}\n aria-labelledby={resolvedLabelledBy}\n aria-describedby={resolvedDescribedBy}\n aria-autocomplete=\"none\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? listboxId : undefined}\n aria-activedescendant={isOpen ? activeOptionId : undefined}\n aria-required={required || undefined}\n aria-invalid={resolvedAriaInvalid}\n >\n <span\n className={cn(\n \"puzzle-select__value\",\n !hasSelection && \"puzzle-select__placeholder\",\n )}\n >\n {displayValue}\n </span>\n\n <span className=\"puzzle-select__icon\" aria-hidden=\"true\" />\n </button>\n ) as ReactElement<PopoutTriggerProps>;\n\n const renderOptionElement = ({ option, index }: IndexedOption<T>) => {\n const selected = isSelected(option);\n const active = activeIndex === index;\n\n const content = renderOption ? (\n renderOption(option, {\n selected,\n active,\n multiple,\n })\n ) : option.description != null ? (\n <span className=\"puzzle-select__option-content\">\n <span className=\"puzzle-select__option-label\">{option.label}</span>\n\n <span\n id={`${listboxId}-description-${index}`}\n className=\"puzzle-select__option-description\"\n >\n {option.description}\n </span>\n </span>\n ) : (\n option.label\n );\n\n return (\n <div\n key={option.id ?? index}\n id={`${listboxId}-option-${index}`}\n className=\"puzzle-select__option\"\n role=\"option\"\n aria-label={option.label}\n aria-selected={selected}\n aria-disabled={option.disabled || undefined}\n aria-describedby={\n !renderOption && option.description != null\n ? `${listboxId}-description-${index}`\n : undefined\n }\n data-index={index}\n data-active={active ? \"true\" : undefined}\n onPointerDown={(event) => event.preventDefault()}\n onPointerMove={(event) => {\n if (event.pointerType !== \"touch\" && !option.disabled) {\n setActiveIndex(index);\n }\n }}\n onClick={() => handleOptionSelect(option)}\n >\n {content}\n </div>\n );\n };\n\n return (\n <div\n className={cn(\"puzzle-select\", rootClassName)}\n data-open={isOpen ? \"true\" : \"false\"}\n data-disabled={disabled ? \"true\" : undefined}\n data-invalid={isInvalid ? \"true\" : undefined}\n data-multiple={multiple ? \"true\" : undefined}\n data-size-mobile={responsiveSize.mobile}\n data-size-tablet={responsiveSize.tablet}\n data-size-desktop={responsiveSize.desktop}\n data-full-width-mobile={String(responsiveFullWidth.mobile)}\n data-full-width-tablet={String(responsiveFullWidth.tablet)}\n data-full-width-desktop={String(responsiveFullWidth.desktop)}\n >\n {label != null && (\n <label\n id={labelId}\n htmlFor={triggerId}\n className=\"puzzle-select__label\"\n >\n {label}\n\n {required && (\n <span className=\"puzzle-select__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div className=\"puzzle-select__control\">\n <Popout\n trigger={triggerElement}\n open={isOpen}\n onOpenChange={changeOpenState}\n action=\"click\"\n position={position}\n align={align}\n offset={offset}\n collisionPadding={collisionPadding}\n contentClassName={cn(\"puzzle-select__popover\", popoverClassName)}\n >\n <div\n ref={handleListboxRef}\n id={listboxId}\n className={cn(\"puzzle-select__listbox\", menuClassName)}\n role=\"listbox\"\n aria-label={\n label == null && ariaLabelledBy == null ? ariaLabel : undefined\n }\n aria-labelledby={\n ariaLabelledBy ?? (label != null ? labelId : undefined)\n }\n aria-multiselectable={multiple || undefined}\n style={listboxStyle}\n >\n {options.length === 0 ? (\n <div className=\"puzzle-select__empty\" role=\"presentation\">\n {noOptionsText}\n </div>\n ) : (\n groups.map((group) =>\n group.label != null ? (\n <div\n key={group.label}\n className=\"puzzle-select__group\"\n role=\"group\"\n aria-label={group.label}\n >\n <div\n className=\"puzzle-select__group-label\"\n aria-hidden=\"true\"\n >\n {group.label}\n </div>\n\n {group.options.map(renderOptionElement)}\n </div>\n ) : (\n group.options.map(renderOptionElement)\n ),\n )\n )}\n </div>\n </Popout>\n\n {clearable && hasSelection && (\n <button\n type=\"button\"\n className=\"puzzle-select__clear\"\n disabled={disabled}\n aria-label={clearLabel}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleClear();\n }}\n >\n <span aria-hidden=\"true\">×</span>\n </button>\n )}\n </div>\n\n {description != null && (\n <div id={descriptionId} className=\"puzzle-select__description\">\n {description}\n </div>\n )}\n\n {hasError && (\n <div id={errorId} className=\"puzzle-select__error\" role=\"alert\">\n {errorContent}\n </div>\n )}\n\n {name != null && (\n <select\n className=\"puzzle-select__native\"\n aria-hidden=\"true\"\n tabIndex={-1}\n name={name}\n form={form}\n autoComplete={autoComplete}\n disabled={disabled}\n required={required}\n multiple={multiple}\n value={\n multiple\n ? selectedValues.map(getSerializedValue)\n : selectedValues.length\n ? getSerializedValue(selectedValues[0])\n : \"\"\n }\n onChange={handleNativeChange}\n onInvalid={(event) => {\n event.preventDefault();\n focusTrigger();\n }}\n >\n {!multiple && <option value=\"\"> </option>}\n\n {groups.map((group) =>\n group.label != null ? (\n <optgroup key={group.label} label={group.label}>\n {group.options.map(({ option, index }) => (\n <option\n key={option.id ?? index}\n value={getSerializedValue(option.value)}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))}\n </optgroup>\n ) : (\n group.options.map(({ option, index }) => (\n <option\n key={option.id ?? index}\n value={getSerializedValue(option.value)}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))\n ),\n )}\n </select>\n )}\n </div>\n );\n};\n\nexport {\n Select,\n type SelectOption,\n type SelectProps,\n type SelectSingleProps,\n type SelectMultipleProps,\n type SelectSize,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["useId","useRef","useState","resolveResponsiveValue","useMemo","useCallback","cn","Popout"],"sources":["../../../../src/components/forms/select/index.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type ChangeEvent,\n type CSSProperties,\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n} from \"react\";\n\nimport { cn, resolveResponsiveValue, type ResponsiveValue } from \"@puzzle-ui/core\";\n\nimport {\n Popout,\n type PopoutAlignment,\n type PopoutPosition,\n type PopoutTriggerProps,\n} from \"../../overlays/popout\";\n\nimport \"./select.css\";\n\ntype SelectSize = \"sm\" | \"md\" | \"lg\";\n\ntype SelectOption<T = string> = {\n /** Stable identifier, useful when options are reordered. */\n id?: string | number;\n\n /** The value returned by onChange. */\n value: T;\n\n /** Plain-text label, also used for typeahead and accessibility. */\n label: string;\n\n /** Optional supporting text. */\n description?: ReactNode;\n\n /** Optional group heading. */\n group?: string;\n\n /** Prevents this option from being selected. */\n disabled?: boolean;\n};\n\ntype SelectOptionRenderState = {\n selected: boolean;\n active: boolean;\n multiple: boolean;\n};\n\ntype SelectBaseProps<T> = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\" | \"value\" | \"disabled\" | \"form\" | \"size\" | \"type\" | \"onChange\"\n> & {\n /** Available options. */\n options: readonly SelectOption<T>[];\n\n /** Optional visible field label. */\n label?: ReactNode;\n\n /** Text shown when no value is selected. */\n placeholder?: ReactNode;\n\n /** Supporting text below the control. */\n description?: ReactNode;\n\n /** Error message. Set to true to use the default message. */\n error?: ReactNode | boolean;\n\n /** Disables the entire control. */\n disabled?: boolean;\n\n /** Makes the field required. */\n required?: boolean;\n\n /** Allows the selected value(s) to be cleared. */\n clearable?: boolean;\n\n /** Accessible name of the clear button. */\n clearLabel?: string;\n\n /** Form field name. Adds a visually hidden native select. */\n name?: string;\n\n /** Form ID for form association. */\n form?: string;\n\n /** Native autocomplete attribute. */\n autoComplete?: string;\n\n /** Serializes generic values for native form submission. */\n serializeValue?: (value: T) => string;\n\n /** Custom comparison for object values. */\n isOptionEqualToValue?: (option: SelectOption<T>, value: T) => boolean;\n\n /** Custom rendering of the selected value(s). */\n renderValue?: (\n selected: SelectOption<T> | readonly SelectOption<T>[] | undefined,\n ) => ReactNode;\n\n /** Custom rendering of an option. */\n renderOption?: (\n option: SelectOption<T>,\n state: SelectOptionRenderState,\n ) => ReactNode;\n\n /** Responsive control size. */\n size?: ResponsiveValue<SelectSize>;\n\n /** Responsive full-width layout. */\n fullWidth?: ResponsiveValue<boolean>;\n\n /** Controls the dropdown visibility. */\n open?: boolean;\n\n /** Initial dropdown visibility. */\n defaultOpen?: boolean;\n\n /** Called when the dropdown visibility changes. */\n onOpenChange?: (open: boolean) => void;\n\n /** Dropdown placement. */\n position?: PopoutPosition;\n\n /** Dropdown alignment. */\n align?: PopoutAlignment;\n\n /** Distance between the trigger and dropdown. */\n offset?: number;\n\n /** Minimum distance from the viewport edges. */\n collisionPadding?: number;\n\n /** Whether the dropdown closes after selecting an option. */\n closeOnSelect?: boolean;\n\n /** Maximum number of simultaneously selected options. */\n maxSelected?: number;\n\n /** Match the dropdown's minimum width to the trigger. */\n matchTriggerWidth?: boolean;\n\n /** Maximum dropdown height. */\n menuMaxHeight?: CSSProperties[\"maxHeight\"];\n\n /** Content displayed when there are no options. */\n noOptionsText?: ReactNode;\n\n /** Additional class on the outer field. */\n rootClassName?: string;\n\n /** Additional class on the Popout content. */\n popoverClassName?: string;\n\n /** Additional class on the listbox. */\n menuClassName?: string;\n};\n\ntype SelectSingleProps<T = string> = SelectBaseProps<T> & {\n multiple?: false;\n\n /** Controlled selected value. Undefined represents no selection. */\n value?: T | undefined;\n\n /** Initial selected value. Undefined represents no selection. */\n defaultValue?: T | undefined;\n\n /** Called when the selected value changes. */\n onChange?: (value: T | undefined) => void;\n};\n\ntype SelectMultipleProps<T = string> = SelectBaseProps<T> & {\n multiple: true;\n\n /** Controlled selected values. */\n value?: readonly T[];\n\n /** Initial selected values. */\n defaultValue?: readonly T[];\n\n /** Called when the selected values change. */\n onChange?: (value: T[]) => void;\n};\n\ntype SelectProps<T = string> = SelectSingleProps<T> | SelectMultipleProps<T>;\n\nconst findEnabledIndex = <T,>(\n options: readonly SelectOption<T>[],\n startIndex: number,\n direction: -1 | 1,\n wrap = true,\n): number => {\n const length = options.length;\n\n for (let step = 1; step <= length; step++) {\n let index = startIndex + step * direction;\n\n if (wrap) {\n index = (index + length) % length;\n } else if (index < 0 || index >= length) {\n break;\n }\n\n if (!options[index]!.disabled) {\n return index;\n }\n }\n\n return -1;\n};\n\ntype IndexedOption<T> = {\n option: SelectOption<T>;\n index: number;\n};\n\ntype SelectGroup<T> = {\n label: string | null;\n options: IndexedOption<T>[];\n};\n\nconst groupOptions = <T,>(\n options: readonly SelectOption<T>[],\n): SelectGroup<T>[] => {\n const groups = new Map<string | null, SelectGroup<T>>();\n\n options.forEach((option, index) => {\n const label = option.group ?? null;\n\n let group = groups.get(label);\n\n if (!group) {\n group = {\n label,\n options: [],\n };\n\n groups.set(label, group);\n }\n\n group.options.push({ option, index });\n });\n\n return Array.from(groups.values());\n};\n\nconst Select = <T,>(props: SelectProps<T>) => {\n const {\n options,\n label,\n placeholder = \"Select an option\",\n description,\n error,\n disabled = false,\n required = false,\n clearable = false,\n clearLabel = \"Clear selection\",\n name,\n form,\n autoComplete,\n serializeValue,\n isOptionEqualToValue,\n renderValue,\n renderOption,\n size = \"md\",\n fullWidth = false,\n open,\n defaultOpen = false,\n onOpenChange,\n position = \"bottom\",\n align = \"start\",\n offset = 8,\n collisionPadding = 8,\n closeOnSelect: closeOnSelectProp,\n maxSelected,\n matchTriggerWidth = true,\n menuMaxHeight = \"18rem\",\n noOptionsText = \"No options\",\n rootClassName,\n popoverClassName,\n menuClassName,\n value,\n onChange,\n id,\n className,\n onClick,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n ...buttonProps\n } = props;\n\n const multiple = props.multiple === true;\n\n // Property presence matters because value={undefined} is a controlled\n // single-select with no selected value.\n const controlledValue = Object.prototype.hasOwnProperty.call(props, \"value\");\n\n const controlledOpen = open !== undefined;\n\n const baseId = useId();\n const triggerId = id ?? `${baseId}-trigger`;\n const labelId = `${baseId}-label`;\n const descriptionId = `${baseId}-description`;\n const errorId = `${baseId}-error`;\n const listboxId = `${baseId}-listbox`;\n\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const listboxRef = useRef<HTMLDivElement | null>(null);\n\n const typeaheadRef = useRef({\n query: \"\",\n timestamp: 0,\n });\n\n const [internalValue, setInternalValue] = useState<\n T | readonly T[] | undefined\n >(() =>\n multiple\n ? ((props as SelectMultipleProps<T>).defaultValue ?? [])\n : (props as SelectSingleProps<T>).defaultValue,\n );\n\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [triggerWidth, setTriggerWidth] = useState(0);\n\n const selectedValue = controlledValue ? value : internalValue;\n\n const selectedValues: readonly T[] = multiple\n ? ((selectedValue as readonly T[] | undefined) ?? [])\n : selectedValue === undefined\n ? []\n : [selectedValue as T];\n\n const isOpen = open ?? internalOpen;\n const hasSelection = selectedValues.length > 0;\n\n const hasError = error !== undefined && error !== null && error !== false;\n\n const isAriaInvalid =\n ariaInvalid !== undefined &&\n ariaInvalid !== false &&\n ariaInvalid !== \"false\";\n\n const isInvalid = hasError || isAriaInvalid;\n\n const resolvedAriaInvalid = isInvalid\n ? hasError || ariaInvalid === true\n ? true\n : ariaInvalid\n : ariaInvalid;\n\n const errorContent = error === true ? \"Invalid value\" : error;\n\n const closeOnSelect = closeOnSelectProp ?? !multiple;\n\n const responsiveSize = resolveResponsiveValue(size, \"md\");\n const responsiveFullWidth = resolveResponsiveValue(fullWidth, false);\n\n const groups = useMemo(() => groupOptions(options), [options]);\n\n const isEqual = useCallback(\n (option: SelectOption<T>, selected: T) =>\n isOptionEqualToValue\n ? isOptionEqualToValue(option, selected)\n : Object.is(option.value, selected),\n [isOptionEqualToValue],\n );\n\n const selectedOptions = selectedValues\n .map((selected) => options.find((option) => isEqual(option, selected)))\n .filter((option): option is SelectOption<T> => option !== undefined);\n\n const isSelected = (option: SelectOption<T>) =>\n selectedValues.some((selected) => isEqual(option, selected));\n\n const initialActiveIndex = useCallback(\n (direction: -1 | 1 = 1) => {\n const selectedIndex = options.findIndex(\n (option) =>\n !option.disabled &&\n selectedValues.some((selected) => isEqual(option, selected)),\n );\n\n if (selectedIndex !== -1) {\n return selectedIndex;\n }\n\n return direction === 1\n ? findEnabledIndex(options, -1, 1, false)\n : findEnabledIndex(options, options.length, -1, false);\n },\n [options, selectedValues, isEqual],\n );\n\n const changeOpenState = useCallback(\n (nextOpen: boolean) => {\n if (!controlledOpen) {\n setInternalOpen(nextOpen);\n }\n\n onOpenChange?.(nextOpen);\n },\n [controlledOpen, onOpenChange],\n );\n\n const updateValue = useCallback(\n (nextValue: T | readonly T[] | undefined) => {\n if (!controlledValue) {\n setInternalValue(nextValue);\n }\n\n if (multiple) {\n const callback = onChange as\n | SelectMultipleProps<T>[\"onChange\"]\n | undefined;\n\n callback?.([...(nextValue as readonly T[])]);\n } else {\n const callback = onChange as\n | SelectSingleProps<T>[\"onChange\"]\n | undefined;\n\n callback?.(nextValue as T | undefined);\n }\n },\n [controlledValue, multiple, onChange],\n );\n\n const getSerializedValue = useCallback(\n (selected: T) =>\n serializeValue ? serializeValue(selected) : String(selected),\n [serializeValue],\n );\n\n const findTypeaheadMatch = (\n character: string,\n startIndex: number,\n ): number => {\n if (options.length === 0) {\n return -1;\n }\n\n const now = Date.now();\n const previous = typeaheadRef.current;\n\n const query =\n now - previous.timestamp > 700 ? character : previous.query + character;\n\n typeaheadRef.current = {\n query,\n timestamp: now,\n };\n\n const repeatedCharacter =\n query.length > 1 &&\n Array.from(query).every(\n (item) => item.toLowerCase() === query[0]!.toLowerCase(),\n );\n\n const search = repeatedCharacter ? character : query;\n const normalizedSearch = search.toLocaleLowerCase();\n\n for (let offset = 1; offset <= options.length; offset++) {\n const index = (startIndex + offset + options.length) % options.length;\n const option = options[index]!;\n\n if (\n !option.disabled &&\n option.label.toLocaleLowerCase().startsWith(normalizedSearch)\n ) {\n return index;\n }\n }\n\n return -1;\n };\n\n const focusTrigger = () => {\n triggerRef.current?.focus({ preventScroll: true });\n };\n\n const handleOptionSelect = (option: SelectOption<T>) => {\n if (disabled || option.disabled) {\n return;\n }\n\n const currentlySelected = isSelected(option);\n\n if (multiple) {\n if (\n !currentlySelected &&\n maxSelected !== undefined &&\n selectedValues.length >= maxSelected\n ) {\n return;\n }\n\n const nextValues = currentlySelected\n ? selectedValues.filter((selected) => !isEqual(option, selected))\n : [...selectedValues, option.value];\n\n updateValue(nextValues);\n } else {\n updateValue(option.value);\n }\n\n if (closeOnSelect) {\n changeOpenState(false);\n focusTrigger();\n }\n };\n\n const handleClear = () => {\n if (!hasSelection || disabled) {\n return;\n }\n\n updateValue(multiple ? [] : undefined);\n focusTrigger();\n };\n\n const handleTriggerRef = useCallback((node: HTMLElement | null) => {\n triggerRef.current = node as HTMLButtonElement | null;\n }, []);\n\n const handleListboxRef = useCallback((node: HTMLDivElement | null) => {\n listboxRef.current = node;\n }, []);\n\n const handleTriggerClick = (event: ReactMouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (event.defaultPrevented || disabled) {\n return;\n }\n\n // Prevent Popout's default click action. We control its state here\n // so that the trigger correctly toggles the dropdown.\n event.preventDefault();\n\n if (!isOpen) {\n setActiveIndex(initialActiveIndex());\n }\n\n changeOpenState(!isOpen);\n };\n\n const handleTriggerKeyDown = (\n event: ReactKeyboardEvent<HTMLButtonElement>,\n ) => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented || disabled) {\n return;\n }\n\n if (isOpen) {\n handleComboboxKeyDown(event);\n return;\n }\n\n if (\n event.key === \"ArrowDown\" ||\n event.key === \"ArrowUp\" ||\n event.key === \"Enter\" ||\n event.key === \" \"\n ) {\n event.preventDefault();\n\n setActiveIndex(initialActiveIndex(event.key === \"ArrowUp\" ? -1 : 1));\n changeOpenState(true);\n\n return;\n }\n\n if (\n event.key.length === 1 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n const index = findTypeaheadMatch(event.key, activeIndex);\n\n if (index !== -1) {\n event.preventDefault();\n setActiveIndex(index);\n\n if (!isOpen) {\n changeOpenState(true);\n }\n }\n }\n };\n\n const handleTriggerKeyUp = (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n onKeyUp?.(event);\n\n // Prevent Space from producing a second click in Firefox.\n if (event.key === \" \") {\n event.preventDefault();\n }\n };\n\n const moveActive = (direction: -1 | 1, amount = 1, wrap = true) => {\n let nextIndex = activeIndex;\n\n for (let step = 0; step < amount; step++) {\n const startIndex =\n nextIndex === -1 ? (direction === 1 ? -1 : options.length) : nextIndex;\n\n const next = findEnabledIndex(options, startIndex, direction, wrap);\n\n if (next === -1) {\n break;\n }\n\n nextIndex = next;\n }\n\n if (nextIndex !== -1) {\n setActiveIndex(nextIndex);\n }\n };\n\n const handleComboboxKeyDown = (event: ReactKeyboardEvent<HTMLElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n moveActive(1);\n return;\n\n case \"ArrowUp\":\n event.preventDefault();\n moveActive(-1);\n return;\n\n case \"Home\":\n event.preventDefault();\n setActiveIndex(findEnabledIndex(options, -1, 1, false));\n return;\n\n case \"End\":\n event.preventDefault();\n setActiveIndex(findEnabledIndex(options, options.length, -1, false));\n return;\n\n case \"PageDown\":\n event.preventDefault();\n moveActive(1, 10, false);\n return;\n\n case \"PageUp\":\n event.preventDefault();\n moveActive(-1, 10, false);\n return;\n\n case \"Enter\":\n case \" \":\n event.preventDefault();\n\n if (activeIndex >= 0 && options[activeIndex]) {\n handleOptionSelect(options[activeIndex]);\n }\n\n return;\n\n case \"Escape\":\n event.preventDefault();\n event.stopPropagation();\n\n changeOpenState(false);\n focusTrigger();\n return;\n\n case \"Tab\":\n changeOpenState(false);\n return;\n\n default:\n break;\n }\n\n if (\n event.key.length === 1 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n event.preventDefault();\n\n const index = findTypeaheadMatch(event.key, activeIndex);\n\n if (index !== -1) {\n setActiveIndex(index);\n }\n }\n };\n\n const handleNativeChange = (event: ChangeEvent<HTMLSelectElement>) => {\n const serializedValues = new Set(\n Array.from(event.currentTarget.selectedOptions, (option) => option.value),\n );\n\n const nextValues = options\n .filter((option) =>\n serializedValues.has(getSerializedValue(option.value)),\n )\n .map((option) => option.value);\n\n updateValue(multiple ? nextValues : nextValues[0]);\n };\n\n // Initialize or recover the active option when opening.\n useEffect(() => {\n if (\n isOpen &&\n (activeIndex < 0 ||\n !options[activeIndex] ||\n options[activeIndex].disabled)\n ) {\n setActiveIndex(initialActiveIndex());\n }\n }, [isOpen, activeIndex, options, initialActiveIndex]);\n\n // Keep the active option visible during keyboard navigation.\n useEffect(() => {\n if (!isOpen || activeIndex < 0) {\n return;\n }\n\n const option = listboxRef.current?.ownerDocument.getElementById(\n `${listboxId}-option-${activeIndex}`,\n );\n\n option?.scrollIntoView({ block: \"nearest\" });\n }, [isOpen, activeIndex, listboxId]);\n\n // Match the menu's minimum width to the trigger.\n useLayoutEffect(() => {\n if (!isOpen || !matchTriggerWidth) {\n return;\n }\n\n const trigger = triggerRef.current;\n const ownerWindow = trigger?.ownerDocument.defaultView;\n\n if (!trigger || !ownerWindow) {\n return;\n }\n\n const updateWidth = () => {\n setTriggerWidth(trigger.getBoundingClientRect().width);\n };\n\n updateWidth();\n\n const ResizeObserverConstructor =\n ownerWindow.ResizeObserver ?? ResizeObserver;\n\n const observer = new ResizeObserverConstructor(updateWidth);\n observer.observe(trigger);\n\n ownerWindow.addEventListener(\"resize\", updateWidth);\n\n return () => {\n observer.disconnect();\n ownerWindow.removeEventListener(\"resize\", updateWidth);\n };\n }, [isOpen, matchTriggerWidth]);\n\n const activeOptionId =\n activeIndex >= 0 && options[activeIndex] && !options[activeIndex].disabled\n ? `${listboxId}-option-${activeIndex}`\n : undefined;\n\n const resolvedLabelledBy =\n ariaLabelledBy ?? (label != null ? labelId : undefined);\n\n const resolvedDescribedBy =\n [\n ariaDescribedBy,\n description != null ? descriptionId : undefined,\n hasError ? errorId : undefined,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n const displayValue = hasSelection\n ? renderValue\n ? renderValue(multiple ? selectedOptions : selectedOptions[0])\n : multiple\n ? selectedOptions.length\n ? selectedOptions.map((option) => option.label).join(\", \")\n : selectedValues.map(String).join(\", \")\n : (selectedOptions[0]?.label ?? String(selectedValues[0]))\n : placeholder;\n\n const listboxStyle: CSSProperties = {\n minWidth: matchTriggerWidth && triggerWidth > 0 ? triggerWidth : undefined,\n maxHeight: menuMaxHeight,\n };\n\n const triggerElement = (\n <button\n {...buttonProps}\n ref={handleTriggerRef}\n id={triggerId}\n type=\"button\"\n role=\"combobox\"\n disabled={disabled}\n className={cn(\"puzzle-select__trigger\", className)}\n onClick={handleTriggerClick}\n onKeyDown={handleTriggerKeyDown}\n onKeyUp={handleTriggerKeyUp}\n aria-label={ariaLabel}\n aria-labelledby={resolvedLabelledBy}\n aria-describedby={resolvedDescribedBy}\n aria-autocomplete=\"none\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? listboxId : undefined}\n aria-activedescendant={isOpen ? activeOptionId : undefined}\n aria-required={required || undefined}\n aria-invalid={resolvedAriaInvalid}\n >\n <span\n className={cn(\n \"puzzle-select__value\",\n !hasSelection && \"puzzle-select__placeholder\",\n )}\n >\n {displayValue}\n </span>\n\n <span className=\"puzzle-select__icon\" aria-hidden=\"true\" />\n </button>\n ) as ReactElement<PopoutTriggerProps>;\n\n const renderOptionElement = ({ option, index }: IndexedOption<T>) => {\n const selected = isSelected(option);\n const active = activeIndex === index;\n\n const content = renderOption ? (\n renderOption(option, {\n selected,\n active,\n multiple,\n })\n ) : option.description != null ? (\n <span className=\"puzzle-select__option-content\">\n <span className=\"puzzle-select__option-label\">{option.label}</span>\n\n <span\n id={`${listboxId}-description-${index}`}\n className=\"puzzle-select__option-description\"\n >\n {option.description}\n </span>\n </span>\n ) : (\n option.label\n );\n\n return (\n <div\n key={option.id ?? index}\n id={`${listboxId}-option-${index}`}\n className=\"puzzle-select__option\"\n role=\"option\"\n aria-label={option.label}\n aria-selected={selected}\n aria-disabled={option.disabled || undefined}\n aria-describedby={\n !renderOption && option.description != null\n ? `${listboxId}-description-${index}`\n : undefined\n }\n data-index={index}\n data-active={active ? \"true\" : undefined}\n onPointerDown={(event) => event.preventDefault()}\n onPointerMove={(event) => {\n if (event.pointerType !== \"touch\" && !option.disabled) {\n setActiveIndex(index);\n }\n }}\n onClick={() => handleOptionSelect(option)}\n >\n {content}\n </div>\n );\n };\n\n return (\n <div\n className={cn(\"puzzle-select\", rootClassName)}\n data-open={isOpen ? \"true\" : \"false\"}\n data-disabled={disabled ? \"true\" : undefined}\n data-invalid={isInvalid ? \"true\" : undefined}\n data-multiple={multiple ? \"true\" : undefined}\n data-size-mobile={responsiveSize.mobile}\n data-size-tablet={responsiveSize.tablet}\n data-size-desktop={responsiveSize.desktop}\n data-full-width-mobile={String(responsiveFullWidth.mobile)}\n data-full-width-tablet={String(responsiveFullWidth.tablet)}\n data-full-width-desktop={String(responsiveFullWidth.desktop)}\n >\n {label != null && (\n <label\n id={labelId}\n htmlFor={triggerId}\n className=\"puzzle-select__label\"\n >\n {label}\n\n {required && (\n <span className=\"puzzle-select__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div className=\"puzzle-select__control\">\n <Popout\n trigger={triggerElement}\n open={isOpen}\n onOpenChange={changeOpenState}\n action=\"click\"\n position={position}\n align={align}\n offset={offset}\n collisionPadding={collisionPadding}\n contentClassName={cn(\"puzzle-select__popover\", popoverClassName)}\n >\n <div\n ref={handleListboxRef}\n id={listboxId}\n className={cn(\"puzzle-select__listbox\", menuClassName)}\n role=\"listbox\"\n aria-label={\n label == null && ariaLabelledBy == null ? ariaLabel : undefined\n }\n aria-labelledby={\n ariaLabelledBy ?? (label != null ? labelId : undefined)\n }\n aria-multiselectable={multiple || undefined}\n style={listboxStyle}\n >\n {options.length === 0 ? (\n <div className=\"puzzle-select__empty\" role=\"presentation\">\n {noOptionsText}\n </div>\n ) : (\n groups.map((group) =>\n group.label != null ? (\n <div\n key={group.label}\n className=\"puzzle-select__group\"\n role=\"group\"\n aria-label={group.label}\n >\n <div\n className=\"puzzle-select__group-label\"\n aria-hidden=\"true\"\n >\n {group.label}\n </div>\n\n {group.options.map(renderOptionElement)}\n </div>\n ) : (\n group.options.map(renderOptionElement)\n ),\n )\n )}\n </div>\n </Popout>\n\n {clearable && hasSelection && (\n <button\n type=\"button\"\n className=\"puzzle-select__clear\"\n disabled={disabled}\n aria-label={clearLabel}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleClear();\n }}\n >\n <span aria-hidden=\"true\">×</span>\n </button>\n )}\n </div>\n\n {description != null && (\n <div id={descriptionId} className=\"puzzle-select__description\">\n {description}\n </div>\n )}\n\n {hasError && (\n <div id={errorId} className=\"puzzle-select__error\" role=\"alert\">\n {errorContent}\n </div>\n )}\n\n {name != null && (\n <select\n className=\"puzzle-select__native\"\n aria-hidden=\"true\"\n tabIndex={-1}\n name={name}\n form={form}\n autoComplete={autoComplete}\n disabled={disabled}\n required={required}\n multiple={multiple}\n value={\n multiple\n ? selectedValues.map(getSerializedValue)\n : selectedValues.length\n ? getSerializedValue(selectedValues[0]!)\n : \"\"\n }\n onChange={handleNativeChange}\n onInvalid={(event) => {\n event.preventDefault();\n focusTrigger();\n }}\n >\n {!multiple && <option value=\"\"> </option>}\n\n {groups.map((group) =>\n group.label != null ? (\n <optgroup key={group.label} label={group.label}>\n {group.options.map(({ option, index }) => (\n <option\n key={option.id ?? index}\n value={getSerializedValue(option.value)}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))}\n </optgroup>\n ) : (\n group.options.map(({ option, index }) => (\n <option\n key={option.id ?? index}\n value={getSerializedValue(option.value)}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))\n ),\n )}\n </select>\n )}\n </div>\n );\n};\n\nexport {\n Select,\n type SelectOption,\n type SelectProps,\n type SelectSingleProps,\n type SelectMultipleProps,\n type SelectSize,\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/forms/select/index.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type ChangeEvent,\n type CSSProperties,\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n} from \"react\";\n\nimport { cn, resolveResponsiveValue, type ResponsiveValue } from \"@puzzle-ui/core\";\n\nimport {\n Popout,\n type PopoutAlignment,\n type PopoutPosition,\n type PopoutTriggerProps,\n} from \"../../overlays/popout\";\n\nimport \"./select.css\";\n\ntype SelectSize = \"sm\" | \"md\" | \"lg\";\n\ntype SelectOption<T = string> = {\n /** Stable identifier, useful when options are reordered. */\n id?: string | number;\n\n /** The value returned by onChange. */\n value: T;\n\n /** Plain-text label, also used for typeahead and accessibility. */\n label: string;\n\n /** Optional supporting text. */\n description?: ReactNode;\n\n /** Optional group heading. */\n group?: string;\n\n /** Prevents this option from being selected. */\n disabled?: boolean;\n};\n\ntype SelectOptionRenderState = {\n selected: boolean;\n active: boolean;\n multiple: boolean;\n};\n\ntype SelectBaseProps<T> = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\" | \"value\" | \"disabled\" | \"form\" | \"size\" | \"type\" | \"onChange\"\n> & {\n /** Available options. */\n options: readonly SelectOption<T>[];\n\n /** Optional visible field label. */\n label?: ReactNode;\n\n /** Text shown when no value is selected. */\n placeholder?: ReactNode;\n\n /** Supporting text below the control. */\n description?: ReactNode;\n\n /** Error message. Set to true to use the default message. */\n error?: ReactNode | boolean;\n\n /** Disables the entire control. */\n disabled?: boolean;\n\n /** Makes the field required. */\n required?: boolean;\n\n /** Allows the selected value(s) to be cleared. */\n clearable?: boolean;\n\n /** Accessible name of the clear button. */\n clearLabel?: string;\n\n /** Form field name. Adds a visually hidden native select. */\n name?: string;\n\n /** Form ID for form association. */\n form?: string;\n\n /** Native autocomplete attribute. */\n autoComplete?: string;\n\n /** Serializes generic values for native form submission. */\n serializeValue?: (value: T) => string;\n\n /** Custom comparison for object values. */\n isOptionEqualToValue?: (option: SelectOption<T>, value: T) => boolean;\n\n /** Custom rendering of the selected value(s). */\n renderValue?: (\n selected: SelectOption<T> | readonly SelectOption<T>[] | undefined,\n ) => ReactNode;\n\n /** Custom rendering of an option. */\n renderOption?: (\n option: SelectOption<T>,\n state: SelectOptionRenderState,\n ) => ReactNode;\n\n /** Responsive control size. */\n size?: ResponsiveValue<SelectSize>;\n\n /** Responsive full-width layout. */\n fullWidth?: ResponsiveValue<boolean>;\n\n /** Controls the dropdown visibility. */\n open?: boolean;\n\n /** Initial dropdown visibility. */\n defaultOpen?: boolean;\n\n /** Called when the dropdown visibility changes. */\n onOpenChange?: (open: boolean) => void;\n\n /** Dropdown placement. */\n position?: PopoutPosition;\n\n /** Dropdown alignment. */\n align?: PopoutAlignment;\n\n /** Distance between the trigger and dropdown. */\n offset?: number;\n\n /** Minimum distance from the viewport edges. */\n collisionPadding?: number;\n\n /** Whether the dropdown closes after selecting an option. */\n closeOnSelect?: boolean;\n\n /** Maximum number of simultaneously selected options. */\n maxSelected?: number;\n\n /** Match the dropdown's minimum width to the trigger. */\n matchTriggerWidth?: boolean;\n\n /** Maximum dropdown height. */\n menuMaxHeight?: CSSProperties[\"maxHeight\"];\n\n /** Content displayed when there are no options. */\n noOptionsText?: ReactNode;\n\n /** Additional class on the outer field. */\n rootClassName?: string;\n\n /** Additional class on the Popout content. */\n popoverClassName?: string;\n\n /** Additional class on the listbox. */\n menuClassName?: string;\n};\n\ntype SelectSingleProps<T = string> = SelectBaseProps<T> & {\n multiple?: false;\n\n /** Controlled selected value. Undefined represents no selection. */\n value?: T | undefined;\n\n /** Initial selected value. Undefined represents no selection. */\n defaultValue?: T | undefined;\n\n /** Called when the selected value changes. */\n onChange?: (value: T | undefined) => void;\n};\n\ntype SelectMultipleProps<T = string> = SelectBaseProps<T> & {\n multiple: true;\n\n /** Controlled selected values. */\n value?: readonly T[];\n\n /** Initial selected values. */\n defaultValue?: readonly T[];\n\n /** Called when the selected values change. */\n onChange?: (value: T[]) => void;\n};\n\ntype SelectProps<T = string> = SelectSingleProps<T> | SelectMultipleProps<T>;\n\nconst findEnabledIndex = <T,>(\n options: readonly SelectOption<T>[],\n startIndex: number,\n direction: -1 | 1,\n wrap = true,\n): number => {\n const length = options.length;\n\n for (let step = 1; step <= length; step++) {\n let index = startIndex + step * direction;\n\n if (wrap) {\n index = (index + length) % length;\n } else if (index < 0 || index >= length) {\n break;\n }\n\n if (!options[index].disabled) {\n return index;\n }\n }\n\n return -1;\n};\n\ntype IndexedOption<T> = {\n option: SelectOption<T>;\n index: number;\n};\n\ntype SelectGroup<T> = {\n label: string | null;\n options: IndexedOption<T>[];\n};\n\nconst groupOptions = <T,>(\n options: readonly SelectOption<T>[],\n): SelectGroup<T>[] => {\n const groups = new Map<string | null, SelectGroup<T>>();\n\n options.forEach((option, index) => {\n const label = option.group ?? null;\n\n let group = groups.get(label);\n\n if (!group) {\n group = {\n label,\n options: [],\n };\n\n groups.set(label, group);\n }\n\n group.options.push({ option, index });\n });\n\n return Array.from(groups.values());\n};\n\nconst Select = <T,>(props: SelectProps<T>) => {\n const {\n options,\n label,\n placeholder = \"Select an option\",\n description,\n error,\n disabled = false,\n required = false,\n clearable = false,\n clearLabel = \"Clear selection\",\n name,\n form,\n autoComplete,\n serializeValue,\n isOptionEqualToValue,\n renderValue,\n renderOption,\n size = \"md\",\n fullWidth = false,\n open,\n defaultOpen = false,\n onOpenChange,\n position = \"bottom\",\n align = \"start\",\n offset = 8,\n collisionPadding = 8,\n closeOnSelect: closeOnSelectProp,\n maxSelected,\n matchTriggerWidth = true,\n menuMaxHeight = \"18rem\",\n noOptionsText = \"No options\",\n rootClassName,\n popoverClassName,\n menuClassName,\n value,\n onChange,\n id,\n className,\n onClick,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n ...buttonProps\n } = props;\n\n const multiple = props.multiple === true;\n\n // Property presence matters because value={undefined} is a controlled\n // single-select with no selected value.\n const controlledValue = Object.prototype.hasOwnProperty.call(props, \"value\");\n\n const controlledOpen = open !== undefined;\n\n const baseId = useId();\n const triggerId = id ?? `${baseId}-trigger`;\n const labelId = `${baseId}-label`;\n const descriptionId = `${baseId}-description`;\n const errorId = `${baseId}-error`;\n const listboxId = `${baseId}-listbox`;\n\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const listboxRef = useRef<HTMLDivElement | null>(null);\n\n const typeaheadRef = useRef({\n query: \"\",\n timestamp: 0,\n });\n\n const [internalValue, setInternalValue] = useState<\n T | readonly T[] | undefined\n >(() =>\n multiple\n ? ((props as SelectMultipleProps<T>).defaultValue ?? [])\n : (props as SelectSingleProps<T>).defaultValue,\n );\n\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [triggerWidth, setTriggerWidth] = useState(0);\n\n const selectedValue = controlledValue ? value : internalValue;\n\n const selectedValues: readonly T[] = multiple\n ? ((selectedValue as readonly T[] | undefined) ?? [])\n : selectedValue === undefined\n ? []\n : [selectedValue as T];\n\n const isOpen = open ?? internalOpen;\n const hasSelection = selectedValues.length > 0;\n\n const hasError = error !== undefined && error !== null && error !== false;\n\n const isAriaInvalid =\n ariaInvalid !== undefined &&\n ariaInvalid !== false &&\n ariaInvalid !== \"false\";\n\n const isInvalid = hasError || isAriaInvalid;\n\n const resolvedAriaInvalid = isInvalid\n ? hasError || ariaInvalid === true\n ? true\n : ariaInvalid\n : ariaInvalid;\n\n const errorContent = error === true ? \"Invalid value\" : error;\n\n const closeOnSelect = closeOnSelectProp ?? !multiple;\n\n const responsiveSize = resolveResponsiveValue(size, \"md\");\n const responsiveFullWidth = resolveResponsiveValue(fullWidth, false);\n\n const groups = useMemo(() => groupOptions(options), [options]);\n\n const isEqual = useCallback(\n (option: SelectOption<T>, selected: T) =>\n isOptionEqualToValue\n ? isOptionEqualToValue(option, selected)\n : Object.is(option.value, selected),\n [isOptionEqualToValue],\n );\n\n const selectedOptions = selectedValues\n .map((selected) => options.find((option) => isEqual(option, selected)))\n .filter((option): option is SelectOption<T> => option !== undefined);\n\n const isSelected = (option: SelectOption<T>) =>\n selectedValues.some((selected) => isEqual(option, selected));\n\n const initialActiveIndex = useCallback(\n (direction: -1 | 1 = 1) => {\n const selectedIndex = options.findIndex(\n (option) =>\n !option.disabled &&\n selectedValues.some((selected) => isEqual(option, selected)),\n );\n\n if (selectedIndex !== -1) {\n return selectedIndex;\n }\n\n return direction === 1\n ? findEnabledIndex(options, -1, 1, false)\n : findEnabledIndex(options, options.length, -1, false);\n },\n [options, selectedValues, isEqual],\n );\n\n const changeOpenState = useCallback(\n (nextOpen: boolean) => {\n if (!controlledOpen) {\n setInternalOpen(nextOpen);\n }\n\n onOpenChange?.(nextOpen);\n },\n [controlledOpen, onOpenChange],\n );\n\n const updateValue = useCallback(\n (nextValue: T | readonly T[] | undefined) => {\n if (!controlledValue) {\n setInternalValue(nextValue);\n }\n\n if (multiple) {\n const callback = onChange as\n | SelectMultipleProps<T>[\"onChange\"]\n | undefined;\n\n callback?.([...(nextValue as readonly T[])]);\n } else {\n const callback = onChange as\n | SelectSingleProps<T>[\"onChange\"]\n | undefined;\n\n callback?.(nextValue as T | undefined);\n }\n },\n [controlledValue, multiple, onChange],\n );\n\n const getSerializedValue = useCallback(\n (selected: T) =>\n serializeValue ? serializeValue(selected) : String(selected),\n [serializeValue],\n );\n\n const findTypeaheadMatch = (\n character: string,\n startIndex: number,\n ): number => {\n if (options.length === 0) {\n return -1;\n }\n\n const now = Date.now();\n const previous = typeaheadRef.current;\n\n const query =\n now - previous.timestamp > 700 ? character : previous.query + character;\n\n typeaheadRef.current = {\n query,\n timestamp: now,\n };\n\n const repeatedCharacter =\n query.length > 1 &&\n Array.from(query).every(\n (item) => item.toLowerCase() === query[0].toLowerCase(),\n );\n\n const search = repeatedCharacter ? character : query;\n const normalizedSearch = search.toLocaleLowerCase();\n\n for (let offset = 1; offset <= options.length; offset++) {\n const index = (startIndex + offset + options.length) % options.length;\n const option = options[index];\n\n if (\n !option.disabled &&\n option.label.toLocaleLowerCase().startsWith(normalizedSearch)\n ) {\n return index;\n }\n }\n\n return -1;\n };\n\n const focusTrigger = () => {\n triggerRef.current?.focus({ preventScroll: true });\n };\n\n const handleOptionSelect = (option: SelectOption<T>) => {\n if (disabled || option.disabled) {\n return;\n }\n\n const currentlySelected = isSelected(option);\n\n if (multiple) {\n if (\n !currentlySelected &&\n maxSelected !== undefined &&\n selectedValues.length >= maxSelected\n ) {\n return;\n }\n\n const nextValues = currentlySelected\n ? selectedValues.filter((selected) => !isEqual(option, selected))\n : [...selectedValues, option.value];\n\n updateValue(nextValues);\n } else {\n updateValue(option.value);\n }\n\n if (closeOnSelect) {\n changeOpenState(false);\n focusTrigger();\n }\n };\n\n const handleClear = () => {\n if (!hasSelection || disabled) {\n return;\n }\n\n updateValue(multiple ? [] : undefined);\n focusTrigger();\n };\n\n const handleTriggerRef = useCallback((node: HTMLElement | null) => {\n triggerRef.current = node as HTMLButtonElement | null;\n }, []);\n\n const handleListboxRef = useCallback((node: HTMLDivElement | null) => {\n listboxRef.current = node;\n }, []);\n\n const handleTriggerClick = (event: ReactMouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (event.defaultPrevented || disabled) {\n return;\n }\n\n // Prevent Popout's default click action. We control its state here\n // so that the trigger correctly toggles the dropdown.\n event.preventDefault();\n\n if (!isOpen) {\n setActiveIndex(initialActiveIndex());\n }\n\n changeOpenState(!isOpen);\n };\n\n const handleTriggerKeyDown = (\n event: ReactKeyboardEvent<HTMLButtonElement>,\n ) => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented || disabled) {\n return;\n }\n\n if (isOpen) {\n handleComboboxKeyDown(event);\n return;\n }\n\n if (\n event.key === \"ArrowDown\" ||\n event.key === \"ArrowUp\" ||\n event.key === \"Enter\" ||\n event.key === \" \"\n ) {\n event.preventDefault();\n\n setActiveIndex(initialActiveIndex(event.key === \"ArrowUp\" ? -1 : 1));\n changeOpenState(true);\n\n return;\n }\n\n if (\n event.key.length === 1 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n const index = findTypeaheadMatch(event.key, activeIndex);\n\n if (index !== -1) {\n event.preventDefault();\n setActiveIndex(index);\n\n if (!isOpen) {\n changeOpenState(true);\n }\n }\n }\n };\n\n const handleTriggerKeyUp = (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n onKeyUp?.(event);\n\n // Prevent Space from producing a second click in Firefox.\n if (event.key === \" \") {\n event.preventDefault();\n }\n };\n\n const moveActive = (direction: -1 | 1, amount = 1, wrap = true) => {\n let nextIndex = activeIndex;\n\n for (let step = 0; step < amount; step++) {\n const startIndex =\n nextIndex === -1 ? (direction === 1 ? -1 : options.length) : nextIndex;\n\n const next = findEnabledIndex(options, startIndex, direction, wrap);\n\n if (next === -1) {\n break;\n }\n\n nextIndex = next;\n }\n\n if (nextIndex !== -1) {\n setActiveIndex(nextIndex);\n }\n };\n\n const handleComboboxKeyDown = (event: ReactKeyboardEvent<HTMLElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n moveActive(1);\n return;\n\n case \"ArrowUp\":\n event.preventDefault();\n moveActive(-1);\n return;\n\n case \"Home\":\n event.preventDefault();\n setActiveIndex(findEnabledIndex(options, -1, 1, false));\n return;\n\n case \"End\":\n event.preventDefault();\n setActiveIndex(findEnabledIndex(options, options.length, -1, false));\n return;\n\n case \"PageDown\":\n event.preventDefault();\n moveActive(1, 10, false);\n return;\n\n case \"PageUp\":\n event.preventDefault();\n moveActive(-1, 10, false);\n return;\n\n case \"Enter\":\n case \" \":\n event.preventDefault();\n\n if (activeIndex >= 0 && options[activeIndex]) {\n handleOptionSelect(options[activeIndex]);\n }\n\n return;\n\n case \"Escape\":\n event.preventDefault();\n event.stopPropagation();\n\n changeOpenState(false);\n focusTrigger();\n return;\n\n case \"Tab\":\n changeOpenState(false);\n return;\n\n default:\n break;\n }\n\n if (\n event.key.length === 1 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n event.preventDefault();\n\n const index = findTypeaheadMatch(event.key, activeIndex);\n\n if (index !== -1) {\n setActiveIndex(index);\n }\n }\n };\n\n const handleNativeChange = (event: ChangeEvent<HTMLSelectElement>) => {\n const serializedValues = new Set(\n Array.from(event.currentTarget.selectedOptions, (option) => option.value),\n );\n\n const nextValues = options\n .filter((option) =>\n serializedValues.has(getSerializedValue(option.value)),\n )\n .map((option) => option.value);\n\n updateValue(multiple ? nextValues : nextValues[0]);\n };\n\n // Initialize or recover the active option when opening.\n useEffect(() => {\n if (\n isOpen &&\n (activeIndex < 0 ||\n !options[activeIndex] ||\n options[activeIndex].disabled)\n ) {\n setActiveIndex(initialActiveIndex());\n }\n }, [isOpen, activeIndex, options, initialActiveIndex]);\n\n // Keep the active option visible during keyboard navigation.\n useEffect(() => {\n if (!isOpen || activeIndex < 0) {\n return;\n }\n\n const option = listboxRef.current?.ownerDocument.getElementById(\n `${listboxId}-option-${activeIndex}`,\n );\n\n option?.scrollIntoView({ block: \"nearest\" });\n }, [isOpen, activeIndex, listboxId]);\n\n // Match the menu's minimum width to the trigger.\n useLayoutEffect(() => {\n if (!isOpen || !matchTriggerWidth) {\n return;\n }\n\n const trigger = triggerRef.current;\n const ownerWindow = trigger?.ownerDocument.defaultView;\n\n if (!trigger || !ownerWindow) {\n return;\n }\n\n const updateWidth = () => {\n setTriggerWidth(trigger.getBoundingClientRect().width);\n };\n\n updateWidth();\n\n const ResizeObserverConstructor =\n ownerWindow.ResizeObserver ?? ResizeObserver;\n\n const observer = new ResizeObserverConstructor(updateWidth);\n observer.observe(trigger);\n\n ownerWindow.addEventListener(\"resize\", updateWidth);\n\n return () => {\n observer.disconnect();\n ownerWindow.removeEventListener(\"resize\", updateWidth);\n };\n }, [isOpen, matchTriggerWidth]);\n\n const activeOptionId =\n activeIndex >= 0 && options[activeIndex] && !options[activeIndex].disabled\n ? `${listboxId}-option-${activeIndex}`\n : undefined;\n\n const resolvedLabelledBy =\n ariaLabelledBy ?? (label != null ? labelId : undefined);\n\n const resolvedDescribedBy =\n [\n ariaDescribedBy,\n description != null ? descriptionId : undefined,\n hasError ? errorId : undefined,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n const displayValue = hasSelection\n ? renderValue\n ? renderValue(multiple ? selectedOptions : selectedOptions[0])\n : multiple\n ? selectedOptions.length\n ? selectedOptions.map((option) => option.label).join(\", \")\n : selectedValues.map(String).join(\", \")\n : (selectedOptions[0]?.label ?? String(selectedValues[0]))\n : placeholder;\n\n const listboxStyle: CSSProperties = {\n minWidth: matchTriggerWidth && triggerWidth > 0 ? triggerWidth : undefined,\n maxHeight: menuMaxHeight,\n };\n\n const triggerElement = (\n <button\n {...buttonProps}\n ref={handleTriggerRef}\n id={triggerId}\n type=\"button\"\n role=\"combobox\"\n disabled={disabled}\n className={cn(\"puzzle-select__trigger\", className)}\n onClick={handleTriggerClick}\n onKeyDown={handleTriggerKeyDown}\n onKeyUp={handleTriggerKeyUp}\n aria-label={ariaLabel}\n aria-labelledby={resolvedLabelledBy}\n aria-describedby={resolvedDescribedBy}\n aria-autocomplete=\"none\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? listboxId : undefined}\n aria-activedescendant={isOpen ? activeOptionId : undefined}\n aria-required={required || undefined}\n aria-invalid={resolvedAriaInvalid}\n >\n <span\n className={cn(\n \"puzzle-select__value\",\n !hasSelection && \"puzzle-select__placeholder\",\n )}\n >\n {displayValue}\n </span>\n\n <span className=\"puzzle-select__icon\" aria-hidden=\"true\" />\n </button>\n ) as ReactElement<PopoutTriggerProps>;\n\n const renderOptionElement = ({ option, index }: IndexedOption<T>) => {\n const selected = isSelected(option);\n const active = activeIndex === index;\n\n const content = renderOption ? (\n renderOption(option, {\n selected,\n active,\n multiple,\n })\n ) : option.description != null ? (\n <span className=\"puzzle-select__option-content\">\n <span className=\"puzzle-select__option-label\">{option.label}</span>\n\n <span\n id={`${listboxId}-description-${index}`}\n className=\"puzzle-select__option-description\"\n >\n {option.description}\n </span>\n </span>\n ) : (\n option.label\n );\n\n return (\n <div\n key={option.id ?? index}\n id={`${listboxId}-option-${index}`}\n className=\"puzzle-select__option\"\n role=\"option\"\n aria-label={option.label}\n aria-selected={selected}\n aria-disabled={option.disabled || undefined}\n aria-describedby={\n !renderOption && option.description != null\n ? `${listboxId}-description-${index}`\n : undefined\n }\n data-index={index}\n data-active={active ? \"true\" : undefined}\n onPointerDown={(event) => event.preventDefault()}\n onPointerMove={(event) => {\n if (event.pointerType !== \"touch\" && !option.disabled) {\n setActiveIndex(index);\n }\n }}\n onClick={() => handleOptionSelect(option)}\n >\n {content}\n </div>\n );\n };\n\n return (\n <div\n className={cn(\"puzzle-select\", rootClassName)}\n data-open={isOpen ? \"true\" : \"false\"}\n data-disabled={disabled ? \"true\" : undefined}\n data-invalid={isInvalid ? \"true\" : undefined}\n data-multiple={multiple ? \"true\" : undefined}\n data-size-mobile={responsiveSize.mobile}\n data-size-tablet={responsiveSize.tablet}\n data-size-desktop={responsiveSize.desktop}\n data-full-width-mobile={String(responsiveFullWidth.mobile)}\n data-full-width-tablet={String(responsiveFullWidth.tablet)}\n data-full-width-desktop={String(responsiveFullWidth.desktop)}\n >\n {label != null && (\n <label\n id={labelId}\n htmlFor={triggerId}\n className=\"puzzle-select__label\"\n >\n {label}\n\n {required && (\n <span className=\"puzzle-select__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div className=\"puzzle-select__control\">\n <Popout\n trigger={triggerElement}\n open={isOpen}\n onOpenChange={changeOpenState}\n action=\"click\"\n position={position}\n align={align}\n offset={offset}\n collisionPadding={collisionPadding}\n contentClassName={cn(\"puzzle-select__popover\", popoverClassName)}\n >\n <div\n ref={handleListboxRef}\n id={listboxId}\n className={cn(\"puzzle-select__listbox\", menuClassName)}\n role=\"listbox\"\n aria-label={\n label == null && ariaLabelledBy == null ? ariaLabel : undefined\n }\n aria-labelledby={\n ariaLabelledBy ?? (label != null ? labelId : undefined)\n }\n aria-multiselectable={multiple || undefined}\n style={listboxStyle}\n >\n {options.length === 0 ? (\n <div className=\"puzzle-select__empty\" role=\"presentation\">\n {noOptionsText}\n </div>\n ) : (\n groups.map((group) =>\n group.label != null ? (\n <div\n key={group.label}\n className=\"puzzle-select__group\"\n role=\"group\"\n aria-label={group.label}\n >\n <div\n className=\"puzzle-select__group-label\"\n aria-hidden=\"true\"\n >\n {group.label}\n </div>\n\n {group.options.map(renderOptionElement)}\n </div>\n ) : (\n group.options.map(renderOptionElement)\n ),\n )\n )}\n </div>\n </Popout>\n\n {clearable && hasSelection && (\n <button\n type=\"button\"\n className=\"puzzle-select__clear\"\n disabled={disabled}\n aria-label={clearLabel}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleClear();\n }}\n >\n <span aria-hidden=\"true\">×</span>\n </button>\n )}\n </div>\n\n {description != null && (\n <div id={descriptionId} className=\"puzzle-select__description\">\n {description}\n </div>\n )}\n\n {hasError && (\n <div id={errorId} className=\"puzzle-select__error\" role=\"alert\">\n {errorContent}\n </div>\n )}\n\n {name != null && (\n <select\n className=\"puzzle-select__native\"\n aria-hidden=\"true\"\n tabIndex={-1}\n name={name}\n form={form}\n autoComplete={autoComplete}\n disabled={disabled}\n required={required}\n multiple={multiple}\n value={\n multiple\n ? selectedValues.map(getSerializedValue)\n : selectedValues.length\n ? getSerializedValue(selectedValues[0])\n : \"\"\n }\n onChange={handleNativeChange}\n onInvalid={(event) => {\n event.preventDefault();\n focusTrigger();\n }}\n >\n {!multiple && <option value=\"\"> </option>}\n\n {groups.map((group) =>\n group.label != null ? (\n <optgroup key={group.label} label={group.label}>\n {group.options.map(({ option, index }) => (\n <option\n key={option.id ?? index}\n value={getSerializedValue(option.value)}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))}\n </optgroup>\n ) : (\n group.options.map(({ option, index }) => (\n <option\n key={option.id ?? index}\n value={getSerializedValue(option.value)}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))\n ),\n )}\n </select>\n )}\n </div>\n );\n};\n\nexport {\n Select,\n type SelectOption,\n type SelectProps,\n type SelectSingleProps,\n type SelectMultipleProps,\n type SelectSize,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/forms/select/index.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type ChangeEvent,\n type CSSProperties,\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n} from \"react\";\n\nimport { cn, resolveResponsiveValue, type ResponsiveValue } from \"@puzzle-ui/core\";\n\nimport {\n Popout,\n type PopoutAlignment,\n type PopoutPosition,\n type PopoutTriggerProps,\n} from \"../../overlays/popout\";\n\nimport \"./select.css\";\n\ntype SelectSize = \"sm\" | \"md\" | \"lg\";\n\ntype SelectOption<T = string> = {\n /** Stable identifier, useful when options are reordered. */\n id?: string | number;\n\n /** The value returned by onChange. */\n value: T;\n\n /** Plain-text label, also used for typeahead and accessibility. */\n label: string;\n\n /** Optional supporting text. */\n description?: ReactNode;\n\n /** Optional group heading. */\n group?: string;\n\n /** Prevents this option from being selected. */\n disabled?: boolean;\n};\n\ntype SelectOptionRenderState = {\n selected: boolean;\n active: boolean;\n multiple: boolean;\n};\n\ntype SelectBaseProps<T> = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\" | \"value\" | \"disabled\" | \"form\" | \"size\" | \"type\" | \"onChange\"\n> & {\n /** Available options. */\n options: readonly SelectOption<T>[];\n\n /** Optional visible field label. */\n label?: ReactNode;\n\n /** Text shown when no value is selected. */\n placeholder?: ReactNode;\n\n /** Supporting text below the control. */\n description?: ReactNode;\n\n /** Error message. Set to true to use the default message. */\n error?: ReactNode | boolean;\n\n /** Disables the entire control. */\n disabled?: boolean;\n\n /** Makes the field required. */\n required?: boolean;\n\n /** Allows the selected value(s) to be cleared. */\n clearable?: boolean;\n\n /** Accessible name of the clear button. */\n clearLabel?: string;\n\n /** Form field name. Adds a visually hidden native select. */\n name?: string;\n\n /** Form ID for form association. */\n form?: string;\n\n /** Native autocomplete attribute. */\n autoComplete?: string;\n\n /** Serializes generic values for native form submission. */\n serializeValue?: (value: T) => string;\n\n /** Custom comparison for object values. */\n isOptionEqualToValue?: (option: SelectOption<T>, value: T) => boolean;\n\n /** Custom rendering of the selected value(s). */\n renderValue?: (\n selected: SelectOption<T> | readonly SelectOption<T>[] | undefined,\n ) => ReactNode;\n\n /** Custom rendering of an option. */\n renderOption?: (\n option: SelectOption<T>,\n state: SelectOptionRenderState,\n ) => ReactNode;\n\n /** Responsive control size. */\n size?: ResponsiveValue<SelectSize>;\n\n /** Responsive full-width layout. */\n fullWidth?: ResponsiveValue<boolean>;\n\n /** Controls the dropdown visibility. */\n open?: boolean;\n\n /** Initial dropdown visibility. */\n defaultOpen?: boolean;\n\n /** Called when the dropdown visibility changes. */\n onOpenChange?: (open: boolean) => void;\n\n /** Dropdown placement. */\n position?: PopoutPosition;\n\n /** Dropdown alignment. */\n align?: PopoutAlignment;\n\n /** Distance between the trigger and dropdown. */\n offset?: number;\n\n /** Minimum distance from the viewport edges. */\n collisionPadding?: number;\n\n /** Whether the dropdown closes after selecting an option. */\n closeOnSelect?: boolean;\n\n /** Maximum number of simultaneously selected options. */\n maxSelected?: number;\n\n /** Match the dropdown's minimum width to the trigger. */\n matchTriggerWidth?: boolean;\n\n /** Maximum dropdown height. */\n menuMaxHeight?: CSSProperties[\"maxHeight\"];\n\n /** Content displayed when there are no options. */\n noOptionsText?: ReactNode;\n\n /** Additional class on the outer field. */\n rootClassName?: string;\n\n /** Additional class on the Popout content. */\n popoverClassName?: string;\n\n /** Additional class on the listbox. */\n menuClassName?: string;\n};\n\ntype SelectSingleProps<T = string> = SelectBaseProps<T> & {\n multiple?: false;\n\n /** Controlled selected value. Undefined represents no selection. */\n value?: T | undefined;\n\n /** Initial selected value. Undefined represents no selection. */\n defaultValue?: T | undefined;\n\n /** Called when the selected value changes. */\n onChange?: (value: T | undefined) => void;\n};\n\ntype SelectMultipleProps<T = string> = SelectBaseProps<T> & {\n multiple: true;\n\n /** Controlled selected values. */\n value?: readonly T[];\n\n /** Initial selected values. */\n defaultValue?: readonly T[];\n\n /** Called when the selected values change. */\n onChange?: (value: T[]) => void;\n};\n\ntype SelectProps<T = string> = SelectSingleProps<T> | SelectMultipleProps<T>;\n\nconst findEnabledIndex = <T,>(\n options: readonly SelectOption<T>[],\n startIndex: number,\n direction: -1 | 1,\n wrap = true,\n): number => {\n const length = options.length;\n\n for (let step = 1; step <= length; step++) {\n let index = startIndex + step * direction;\n\n if (wrap) {\n index = (index + length) % length;\n } else if (index < 0 || index >= length) {\n break;\n }\n\n if (!options[index]!.disabled) {\n return index;\n }\n }\n\n return -1;\n};\n\ntype IndexedOption<T> = {\n option: SelectOption<T>;\n index: number;\n};\n\ntype SelectGroup<T> = {\n label: string | null;\n options: IndexedOption<T>[];\n};\n\nconst groupOptions = <T,>(\n options: readonly SelectOption<T>[],\n): SelectGroup<T>[] => {\n const groups = new Map<string | null, SelectGroup<T>>();\n\n options.forEach((option, index) => {\n const label = option.group ?? null;\n\n let group = groups.get(label);\n\n if (!group) {\n group = {\n label,\n options: [],\n };\n\n groups.set(label, group);\n }\n\n group.options.push({ option, index });\n });\n\n return Array.from(groups.values());\n};\n\nconst Select = <T,>(props: SelectProps<T>) => {\n const {\n options,\n label,\n placeholder = \"Select an option\",\n description,\n error,\n disabled = false,\n required = false,\n clearable = false,\n clearLabel = \"Clear selection\",\n name,\n form,\n autoComplete,\n serializeValue,\n isOptionEqualToValue,\n renderValue,\n renderOption,\n size = \"md\",\n fullWidth = false,\n open,\n defaultOpen = false,\n onOpenChange,\n position = \"bottom\",\n align = \"start\",\n offset = 8,\n collisionPadding = 8,\n closeOnSelect: closeOnSelectProp,\n maxSelected,\n matchTriggerWidth = true,\n menuMaxHeight = \"18rem\",\n noOptionsText = \"No options\",\n rootClassName,\n popoverClassName,\n menuClassName,\n value,\n onChange,\n id,\n className,\n onClick,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n ...buttonProps\n } = props;\n\n const multiple = props.multiple === true;\n\n // Property presence matters because value={undefined} is a controlled\n // single-select with no selected value.\n const controlledValue = Object.prototype.hasOwnProperty.call(props, \"value\");\n\n const controlledOpen = open !== undefined;\n\n const baseId = useId();\n const triggerId = id ?? `${baseId}-trigger`;\n const labelId = `${baseId}-label`;\n const descriptionId = `${baseId}-description`;\n const errorId = `${baseId}-error`;\n const listboxId = `${baseId}-listbox`;\n\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const listboxRef = useRef<HTMLDivElement | null>(null);\n\n const typeaheadRef = useRef({\n query: \"\",\n timestamp: 0,\n });\n\n const [internalValue, setInternalValue] = useState<\n T | readonly T[] | undefined\n >(() =>\n multiple\n ? ((props as SelectMultipleProps<T>).defaultValue ?? [])\n : (props as SelectSingleProps<T>).defaultValue,\n );\n\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [triggerWidth, setTriggerWidth] = useState(0);\n\n const selectedValue = controlledValue ? value : internalValue;\n\n const selectedValues: readonly T[] = multiple\n ? ((selectedValue as readonly T[] | undefined) ?? [])\n : selectedValue === undefined\n ? []\n : [selectedValue as T];\n\n const isOpen = open ?? internalOpen;\n const hasSelection = selectedValues.length > 0;\n\n const hasError = error !== undefined && error !== null && error !== false;\n\n const isAriaInvalid =\n ariaInvalid !== undefined &&\n ariaInvalid !== false &&\n ariaInvalid !== \"false\";\n\n const isInvalid = hasError || isAriaInvalid;\n\n const resolvedAriaInvalid = isInvalid\n ? hasError || ariaInvalid === true\n ? true\n : ariaInvalid\n : ariaInvalid;\n\n const errorContent = error === true ? \"Invalid value\" : error;\n\n const closeOnSelect = closeOnSelectProp ?? !multiple;\n\n const responsiveSize = resolveResponsiveValue(size, \"md\");\n const responsiveFullWidth = resolveResponsiveValue(fullWidth, false);\n\n const groups = useMemo(() => groupOptions(options), [options]);\n\n const isEqual = useCallback(\n (option: SelectOption<T>, selected: T) =>\n isOptionEqualToValue\n ? isOptionEqualToValue(option, selected)\n : Object.is(option.value, selected),\n [isOptionEqualToValue],\n );\n\n const selectedOptions = selectedValues\n .map((selected) => options.find((option) => isEqual(option, selected)))\n .filter((option): option is SelectOption<T> => option !== undefined);\n\n const isSelected = (option: SelectOption<T>) =>\n selectedValues.some((selected) => isEqual(option, selected));\n\n const initialActiveIndex = useCallback(\n (direction: -1 | 1 = 1) => {\n const selectedIndex = options.findIndex(\n (option) =>\n !option.disabled &&\n selectedValues.some((selected) => isEqual(option, selected)),\n );\n\n if (selectedIndex !== -1) {\n return selectedIndex;\n }\n\n return direction === 1\n ? findEnabledIndex(options, -1, 1, false)\n : findEnabledIndex(options, options.length, -1, false);\n },\n [options, selectedValues, isEqual],\n );\n\n const changeOpenState = useCallback(\n (nextOpen: boolean) => {\n if (!controlledOpen) {\n setInternalOpen(nextOpen);\n }\n\n onOpenChange?.(nextOpen);\n },\n [controlledOpen, onOpenChange],\n );\n\n const updateValue = useCallback(\n (nextValue: T | readonly T[] | undefined) => {\n if (!controlledValue) {\n setInternalValue(nextValue);\n }\n\n if (multiple) {\n const callback = onChange as\n | SelectMultipleProps<T>[\"onChange\"]\n | undefined;\n\n callback?.([...(nextValue as readonly T[])]);\n } else {\n const callback = onChange as\n | SelectSingleProps<T>[\"onChange\"]\n | undefined;\n\n callback?.(nextValue as T | undefined);\n }\n },\n [controlledValue, multiple, onChange],\n );\n\n const getSerializedValue = useCallback(\n (selected: T) =>\n serializeValue ? serializeValue(selected) : String(selected),\n [serializeValue],\n );\n\n const findTypeaheadMatch = (\n character: string,\n startIndex: number,\n ): number => {\n if (options.length === 0) {\n return -1;\n }\n\n const now = Date.now();\n const previous = typeaheadRef.current;\n\n const query =\n now - previous.timestamp > 700 ? character : previous.query + character;\n\n typeaheadRef.current = {\n query,\n timestamp: now,\n };\n\n const repeatedCharacter =\n query.length > 1 &&\n Array.from(query).every(\n (item) => item.toLowerCase() === query[0]!.toLowerCase(),\n );\n\n const search = repeatedCharacter ? character : query;\n const normalizedSearch = search.toLocaleLowerCase();\n\n for (let offset = 1; offset <= options.length; offset++) {\n const index = (startIndex + offset + options.length) % options.length;\n const option = options[index]!;\n\n if (\n !option.disabled &&\n option.label.toLocaleLowerCase().startsWith(normalizedSearch)\n ) {\n return index;\n }\n }\n\n return -1;\n };\n\n const focusTrigger = () => {\n triggerRef.current?.focus({ preventScroll: true });\n };\n\n const handleOptionSelect = (option: SelectOption<T>) => {\n if (disabled || option.disabled) {\n return;\n }\n\n const currentlySelected = isSelected(option);\n\n if (multiple) {\n if (\n !currentlySelected &&\n maxSelected !== undefined &&\n selectedValues.length >= maxSelected\n ) {\n return;\n }\n\n const nextValues = currentlySelected\n ? selectedValues.filter((selected) => !isEqual(option, selected))\n : [...selectedValues, option.value];\n\n updateValue(nextValues);\n } else {\n updateValue(option.value);\n }\n\n if (closeOnSelect) {\n changeOpenState(false);\n focusTrigger();\n }\n };\n\n const handleClear = () => {\n if (!hasSelection || disabled) {\n return;\n }\n\n updateValue(multiple ? [] : undefined);\n focusTrigger();\n };\n\n const handleTriggerRef = useCallback((node: HTMLElement | null) => {\n triggerRef.current = node as HTMLButtonElement | null;\n }, []);\n\n const handleListboxRef = useCallback((node: HTMLDivElement | null) => {\n listboxRef.current = node;\n }, []);\n\n const handleTriggerClick = (event: ReactMouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (event.defaultPrevented || disabled) {\n return;\n }\n\n // Prevent Popout's default click action. We control its state here\n // so that the trigger correctly toggles the dropdown.\n event.preventDefault();\n\n if (!isOpen) {\n setActiveIndex(initialActiveIndex());\n }\n\n changeOpenState(!isOpen);\n };\n\n const handleTriggerKeyDown = (\n event: ReactKeyboardEvent<HTMLButtonElement>,\n ) => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented || disabled) {\n return;\n }\n\n if (isOpen) {\n handleComboboxKeyDown(event);\n return;\n }\n\n if (\n event.key === \"ArrowDown\" ||\n event.key === \"ArrowUp\" ||\n event.key === \"Enter\" ||\n event.key === \" \"\n ) {\n event.preventDefault();\n\n setActiveIndex(initialActiveIndex(event.key === \"ArrowUp\" ? -1 : 1));\n changeOpenState(true);\n\n return;\n }\n\n if (\n event.key.length === 1 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n const index = findTypeaheadMatch(event.key, activeIndex);\n\n if (index !== -1) {\n event.preventDefault();\n setActiveIndex(index);\n\n if (!isOpen) {\n changeOpenState(true);\n }\n }\n }\n };\n\n const handleTriggerKeyUp = (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n onKeyUp?.(event);\n\n // Prevent Space from producing a second click in Firefox.\n if (event.key === \" \") {\n event.preventDefault();\n }\n };\n\n const moveActive = (direction: -1 | 1, amount = 1, wrap = true) => {\n let nextIndex = activeIndex;\n\n for (let step = 0; step < amount; step++) {\n const startIndex =\n nextIndex === -1 ? (direction === 1 ? -1 : options.length) : nextIndex;\n\n const next = findEnabledIndex(options, startIndex, direction, wrap);\n\n if (next === -1) {\n break;\n }\n\n nextIndex = next;\n }\n\n if (nextIndex !== -1) {\n setActiveIndex(nextIndex);\n }\n };\n\n const handleComboboxKeyDown = (event: ReactKeyboardEvent<HTMLElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n moveActive(1);\n return;\n\n case \"ArrowUp\":\n event.preventDefault();\n moveActive(-1);\n return;\n\n case \"Home\":\n event.preventDefault();\n setActiveIndex(findEnabledIndex(options, -1, 1, false));\n return;\n\n case \"End\":\n event.preventDefault();\n setActiveIndex(findEnabledIndex(options, options.length, -1, false));\n return;\n\n case \"PageDown\":\n event.preventDefault();\n moveActive(1, 10, false);\n return;\n\n case \"PageUp\":\n event.preventDefault();\n moveActive(-1, 10, false);\n return;\n\n case \"Enter\":\n case \" \":\n event.preventDefault();\n\n if (activeIndex >= 0 && options[activeIndex]) {\n handleOptionSelect(options[activeIndex]);\n }\n\n return;\n\n case \"Escape\":\n event.preventDefault();\n event.stopPropagation();\n\n changeOpenState(false);\n focusTrigger();\n return;\n\n case \"Tab\":\n changeOpenState(false);\n return;\n\n default:\n break;\n }\n\n if (\n event.key.length === 1 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n event.preventDefault();\n\n const index = findTypeaheadMatch(event.key, activeIndex);\n\n if (index !== -1) {\n setActiveIndex(index);\n }\n }\n };\n\n const handleNativeChange = (event: ChangeEvent<HTMLSelectElement>) => {\n const serializedValues = new Set(\n Array.from(event.currentTarget.selectedOptions, (option) => option.value),\n );\n\n const nextValues = options\n .filter((option) =>\n serializedValues.has(getSerializedValue(option.value)),\n )\n .map((option) => option.value);\n\n updateValue(multiple ? nextValues : nextValues[0]);\n };\n\n // Initialize or recover the active option when opening.\n useEffect(() => {\n if (\n isOpen &&\n (activeIndex < 0 ||\n !options[activeIndex] ||\n options[activeIndex].disabled)\n ) {\n setActiveIndex(initialActiveIndex());\n }\n }, [isOpen, activeIndex, options, initialActiveIndex]);\n\n // Keep the active option visible during keyboard navigation.\n useEffect(() => {\n if (!isOpen || activeIndex < 0) {\n return;\n }\n\n const option = listboxRef.current?.ownerDocument.getElementById(\n `${listboxId}-option-${activeIndex}`,\n );\n\n option?.scrollIntoView({ block: \"nearest\" });\n }, [isOpen, activeIndex, listboxId]);\n\n // Match the menu's minimum width to the trigger.\n useLayoutEffect(() => {\n if (!isOpen || !matchTriggerWidth) {\n return;\n }\n\n const trigger = triggerRef.current;\n const ownerWindow = trigger?.ownerDocument.defaultView;\n\n if (!trigger || !ownerWindow) {\n return;\n }\n\n const updateWidth = () => {\n setTriggerWidth(trigger.getBoundingClientRect().width);\n };\n\n updateWidth();\n\n const ResizeObserverConstructor =\n ownerWindow.ResizeObserver ?? ResizeObserver;\n\n const observer = new ResizeObserverConstructor(updateWidth);\n observer.observe(trigger);\n\n ownerWindow.addEventListener(\"resize\", updateWidth);\n\n return () => {\n observer.disconnect();\n ownerWindow.removeEventListener(\"resize\", updateWidth);\n };\n }, [isOpen, matchTriggerWidth]);\n\n const activeOptionId =\n activeIndex >= 0 && options[activeIndex] && !options[activeIndex].disabled\n ? `${listboxId}-option-${activeIndex}`\n : undefined;\n\n const resolvedLabelledBy =\n ariaLabelledBy ?? (label != null ? labelId : undefined);\n\n const resolvedDescribedBy =\n [\n ariaDescribedBy,\n description != null ? descriptionId : undefined,\n hasError ? errorId : undefined,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n const displayValue = hasSelection\n ? renderValue\n ? renderValue(multiple ? selectedOptions : selectedOptions[0])\n : multiple\n ? selectedOptions.length\n ? selectedOptions.map((option) => option.label).join(\", \")\n : selectedValues.map(String).join(\", \")\n : (selectedOptions[0]?.label ?? String(selectedValues[0]))\n : placeholder;\n\n const listboxStyle: CSSProperties = {\n minWidth: matchTriggerWidth && triggerWidth > 0 ? triggerWidth : undefined,\n maxHeight: menuMaxHeight,\n };\n\n const triggerElement = (\n <button\n {...buttonProps}\n ref={handleTriggerRef}\n id={triggerId}\n type=\"button\"\n role=\"combobox\"\n disabled={disabled}\n className={cn(\"puzzle-select__trigger\", className)}\n onClick={handleTriggerClick}\n onKeyDown={handleTriggerKeyDown}\n onKeyUp={handleTriggerKeyUp}\n aria-label={ariaLabel}\n aria-labelledby={resolvedLabelledBy}\n aria-describedby={resolvedDescribedBy}\n aria-autocomplete=\"none\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? listboxId : undefined}\n aria-activedescendant={isOpen ? activeOptionId : undefined}\n aria-required={required || undefined}\n aria-invalid={resolvedAriaInvalid}\n >\n <span\n className={cn(\n \"puzzle-select__value\",\n !hasSelection && \"puzzle-select__placeholder\",\n )}\n >\n {displayValue}\n </span>\n\n <span className=\"puzzle-select__icon\" aria-hidden=\"true\" />\n </button>\n ) as ReactElement<PopoutTriggerProps>;\n\n const renderOptionElement = ({ option, index }: IndexedOption<T>) => {\n const selected = isSelected(option);\n const active = activeIndex === index;\n\n const content = renderOption ? (\n renderOption(option, {\n selected,\n active,\n multiple,\n })\n ) : option.description != null ? (\n <span className=\"puzzle-select__option-content\">\n <span className=\"puzzle-select__option-label\">{option.label}</span>\n\n <span\n id={`${listboxId}-description-${index}`}\n className=\"puzzle-select__option-description\"\n >\n {option.description}\n </span>\n </span>\n ) : (\n option.label\n );\n\n return (\n <div\n key={option.id ?? index}\n id={`${listboxId}-option-${index}`}\n className=\"puzzle-select__option\"\n role=\"option\"\n aria-label={option.label}\n aria-selected={selected}\n aria-disabled={option.disabled || undefined}\n aria-describedby={\n !renderOption && option.description != null\n ? `${listboxId}-description-${index}`\n : undefined\n }\n data-index={index}\n data-active={active ? \"true\" : undefined}\n onPointerDown={(event) => event.preventDefault()}\n onPointerMove={(event) => {\n if (event.pointerType !== \"touch\" && !option.disabled) {\n setActiveIndex(index);\n }\n }}\n onClick={() => handleOptionSelect(option)}\n >\n {content}\n </div>\n );\n };\n\n return (\n <div\n className={cn(\"puzzle-select\", rootClassName)}\n data-open={isOpen ? \"true\" : \"false\"}\n data-disabled={disabled ? \"true\" : undefined}\n data-invalid={isInvalid ? \"true\" : undefined}\n data-multiple={multiple ? \"true\" : undefined}\n data-size-mobile={responsiveSize.mobile}\n data-size-tablet={responsiveSize.tablet}\n data-size-desktop={responsiveSize.desktop}\n data-full-width-mobile={String(responsiveFullWidth.mobile)}\n data-full-width-tablet={String(responsiveFullWidth.tablet)}\n data-full-width-desktop={String(responsiveFullWidth.desktop)}\n >\n {label != null && (\n <label\n id={labelId}\n htmlFor={triggerId}\n className=\"puzzle-select__label\"\n >\n {label}\n\n {required && (\n <span className=\"puzzle-select__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div className=\"puzzle-select__control\">\n <Popout\n trigger={triggerElement}\n open={isOpen}\n onOpenChange={changeOpenState}\n action=\"click\"\n position={position}\n align={align}\n offset={offset}\n collisionPadding={collisionPadding}\n contentClassName={cn(\"puzzle-select__popover\", popoverClassName)}\n >\n <div\n ref={handleListboxRef}\n id={listboxId}\n className={cn(\"puzzle-select__listbox\", menuClassName)}\n role=\"listbox\"\n aria-label={\n label == null && ariaLabelledBy == null ? ariaLabel : undefined\n }\n aria-labelledby={\n ariaLabelledBy ?? (label != null ? labelId : undefined)\n }\n aria-multiselectable={multiple || undefined}\n style={listboxStyle}\n >\n {options.length === 0 ? (\n <div className=\"puzzle-select__empty\" role=\"presentation\">\n {noOptionsText}\n </div>\n ) : (\n groups.map((group) =>\n group.label != null ? (\n <div\n key={group.label}\n className=\"puzzle-select__group\"\n role=\"group\"\n aria-label={group.label}\n >\n <div\n className=\"puzzle-select__group-label\"\n aria-hidden=\"true\"\n >\n {group.label}\n </div>\n\n {group.options.map(renderOptionElement)}\n </div>\n ) : (\n group.options.map(renderOptionElement)\n ),\n )\n )}\n </div>\n </Popout>\n\n {clearable && hasSelection && (\n <button\n type=\"button\"\n className=\"puzzle-select__clear\"\n disabled={disabled}\n aria-label={clearLabel}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleClear();\n }}\n >\n <span aria-hidden=\"true\">×</span>\n </button>\n )}\n </div>\n\n {description != null && (\n <div id={descriptionId} className=\"puzzle-select__description\">\n {description}\n </div>\n )}\n\n {hasError && (\n <div id={errorId} className=\"puzzle-select__error\" role=\"alert\">\n {errorContent}\n </div>\n )}\n\n {name != null && (\n <select\n className=\"puzzle-select__native\"\n aria-hidden=\"true\"\n tabIndex={-1}\n name={name}\n form={form}\n autoComplete={autoComplete}\n disabled={disabled}\n required={required}\n multiple={multiple}\n value={\n multiple\n ? selectedValues.map(getSerializedValue)\n : selectedValues.length\n ? getSerializedValue(selectedValues[0]!)\n : \"\"\n }\n onChange={handleNativeChange}\n onInvalid={(event) => {\n event.preventDefault();\n focusTrigger();\n }}\n >\n {!multiple && <option value=\"\"> </option>}\n\n {groups.map((group) =>\n group.label != null ? (\n <optgroup key={group.label} label={group.label}>\n {group.options.map(({ option, index }) => (\n <option\n key={option.id ?? index}\n value={getSerializedValue(option.value)}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))}\n </optgroup>\n ) : (\n group.options.map(({ option, index }) => (\n <option\n key={option.id ?? index}\n value={getSerializedValue(option.value)}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))\n ),\n )}\n </select>\n )}\n </div>\n );\n};\n\nexport {\n Select,\n type SelectOption,\n type SelectProps,\n type SelectSingleProps,\n type SelectMultipleProps,\n type SelectSize,\n};\n"],"mappings":"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"}
@@ -5,7 +5,7 @@ let react = require("react");
5
5
  let react_jsx_runtime = require("react/jsx-runtime");
6
6
  // src/components/forms/slider/index.tsx
7
7
  const getPrecision = (value) => {
8
- const [coefficient, exponent = "0"] = String(value).toLowerCase().split("e");
8
+ const [coefficient = "", exponent = "0"] = String(value).toLowerCase().split("e");
9
9
  const decimals = coefficient.split(".")[1]?.length ?? 0;
10
10
  return Math.min(12, Math.max(0, decimals - Number(exponent)));
11
11
  };