sunpeak 0.10.3 → 0.10.4

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 (40) hide show
  1. package/dist/server-310A1k9o.js.map +1 -1
  2. package/dist/server-CSybLAYo.cjs.map +1 -1
  3. package/dist/simulator-url-BZBcq5tc.js.map +1 -1
  4. package/dist/simulator-url-D4tFBjeu.cjs.map +1 -1
  5. package/package.json +11 -11
  6. package/template/dist/albums/albums.js +7 -7
  7. package/template/dist/albums/albums.json +1 -1
  8. package/template/dist/carousel/carousel.js +7 -7
  9. package/template/dist/carousel/carousel.json +1 -1
  10. package/template/dist/map/map.js +8 -8
  11. package/template/dist/map/map.json +1 -1
  12. package/template/dist/review/review.js +7 -7
  13. package/template/dist/review/review.json +1 -1
  14. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Avatar.js +1 -2
  15. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Avatar.js.map +1 -1
  16. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Button.js +618 -13
  17. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Button.js.map +4 -4
  18. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Checkbox.js +3 -3
  19. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Checkbox.js.map +1 -1
  20. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Input.js +2 -2
  21. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js +7 -7
  22. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js.map +1 -1
  23. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js +2812 -151
  24. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js.map +4 -4
  25. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js +6 -6
  26. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js.map +1 -1
  27. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_theme.js +1 -1
  28. package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_theme.js.map +1 -1
  29. package/template/node_modules/.vite/deps/_metadata.json +43 -43
  30. package/template/node_modules/.vite/deps/{chunk-TSEQUROC.js → chunk-2UDYPUBJ.js} +99 -99
  31. package/template/node_modules/.vite/deps/{chunk-TSEQUROC.js.map → chunk-2UDYPUBJ.js.map} +1 -1
  32. package/template/node_modules/.vite/deps/chunk-6QVG4F2X.js +93 -0
  33. package/template/node_modules/.vite/deps/chunk-6QVG4F2X.js.map +7 -0
  34. package/template/node_modules/.vite/deps/{chunk-2DZGWGIP.js → chunk-P5LK4A7U.js} +3 -3
  35. package/template/node_modules/.vite/deps/{chunk-2DZGWGIP.js.map → chunk-P5LK4A7U.js.map} +1 -1
  36. package/template/node_modules/.vite/deps/{chunk-DYQDWJMS.js → chunk-RYYR2YMB.js} +2 -6
  37. package/template/node_modules/.vite/deps/{chunk-DYQDWJMS.js.map → chunk-RYYR2YMB.js.map} +1 -1
  38. package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  39. package/template/node_modules/.vite/deps/chunk-LVZJNEGE.js +0 -628
  40. package/template/node_modules/.vite/deps/chunk-LVZJNEGE.js.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/src/components/Select/Select.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/src/hooks/useEscCloseStack.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/src/hooks/useLatestValue.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/src/components/SelectControl/SelectControl.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/src/components/Tooltip/CopyTooltip.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/src/components/Tooltip/Tooltip.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport clsx from \"clsx\"\nimport { Popover } from \"radix-ui\"\nimport React, {\n createContext,\n type ReactNode,\n use,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { preventDefaultHandler, toCssVariables, waitForAnimationFrame } from \"../../lib/helpers\"\nimport { Check, Info, Search } from \"../Icon\"\nimport { Input } from \"../Input\"\nimport { SelectControl, type SelectControlProps } from \"../SelectControl\"\nimport { Tooltip } from \"../Tooltip\"\nimport { TransitionGroup } from \"../Transition\"\nimport s from \"./Select.module.css\"\n\nexport type Option<T extends string = string> = {\n value: T\n label: string\n /** Disable the option */\n disabled?: boolean\n /** Displayed as secondary text below the option `label` */\n description?: React.ReactNode\n tooltip?: {\n content: React.ReactNode\n maxWidth?: number\n }\n}\n\nexport type OptionGroup<T extends Option> = {\n label: string\n options: T[]\n optionsLimit?: {\n label: string\n limit: number\n }\n}\n\nexport type Options<T extends Option> = T[] | OptionGroup<T>[]\n\ntype CallbackWithOption<T extends Option> = (option: T) => void\ntype CallbackWithOptions<T extends Option> = (options: T[]) => void\ntype CallbackWithActionId = (actionId: string) => void\ntype SearchPredicate<T extends Option> = (option: T, searchTerm: string) => boolean\n\ntype Action = {\n /** Unique ID to identify the action with */\n id: string\n /** Label display for the action */\n label: string\n /** Icon displayed to the left of the action */\n Icon?: React.ComponentType<React.SVGProps<SVGSVGElement>>\n /** Custom class applied to the action container */\n className?: string\n /** Callback invoked when the action is pressed */\n onSelect: CallbackWithActionId\n}\n\ntype Actions = Action[]\n\nexport type PopoverSide = \"top\" | \"bottom\"\nexport type PopoverAlign = \"start\" | \"center\" | \"end\"\n\ntype SingleSelectProps<T extends Option> = {\n /**\n * Determines if the select should support multiple selection\n * @default false\n */\n multiple?: false\n value: string\n onChange: CallbackWithOption<T>\n /**\n * Customize the rendered output of the trigger\n * NOTE: Must be passed as a stable reference, not created inline.\n */\n TriggerView?: React.FC<T>\n}\n\ntype MultiSelectTriggerViewProps<T extends Option> = {\n values: T[]\n selectedAll: boolean\n}\n\ntype MultiSelectProps<T extends Option> = {\n /**\n * Determines if the select should support multiple selection\n * @default false\n */\n multiple: true\n value: string[]\n onChange: CallbackWithOptions<T>\n /**\n * Customize the rendered output of the trigger\n * NOTE: Must be passed as a stable reference, not created line.\n */\n TriggerView?: React.FC<MultiSelectTriggerViewProps<T>>\n}\n\nexport type SelectProps<T extends Option> = (SingleSelectProps<T> | MultiSelectProps<T>) & {\n options: Options<T> // Should be passed as a stable reference\n /**\n * Disables the select visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Allows the select to be targeted with htmlFor\n */\n id?: string\n /**\n * Marks the select as a required field when using native form submission\n */\n required?: boolean\n /**\n * Creates the ability to query the value with `[name=\"${name}\"]`\n */\n name?: string\n /**\n * Placeholder text for the select\n * @default Select...\n */\n placeholder?: string\n /**\n * Placeholder text for the select while loading. Behaves exactly like `placeholder`, and `value` will be shown if provided.\n * @default Loading...\n */\n loadingPlaceholder?: string\n /**\n * Displays loading indicator on top of button contents\n * @default false\n */\n loading?: boolean\n /**\n * Style variant for the select trigger\n * @default outline\n */\n variant?: SelectControlProps[\"variant\"]\n /**\n * Determines if the select trigger should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Controls size of the select trigger, and several other aspects of trigger styling.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: SelectControlProps[\"size\"]\n /**\n * Icon displayed in the far right of the select trigger\n * @default dropdown\n */\n dropdownIconType?: SelectControlProps[\"dropdownIconType\"]\n /**\n * Actions to display below the options list.\n */\n actions?: Actions // Memoized by length, don't assume dynamic changes are supported\n /** Custom class applied to option containers */\n optionClassName?: string\n /**\n * Customize the rendered output of individual options\n * NOTE: Must be passed as a stable reference, not created line.\n */\n OptionView?: React.FC<T>\n /** Icon displayed at the start of the select trigger */\n TriggerStartIcon?: SelectControlProps[\"StartIcon\"]\n /**\n * Custom class applied to the select trigger\n */\n triggerClassName?: string // If consumers need deep customization of the trigger\n /**\n * Applies a negative margin using the current gutter to optically align the trigger\n * with surrounding content.\n */\n opticallyAlign?: \"start\" | \"end\"\n /**\n * Display a clear action that allows the select to be unset.\n * @default false\n */\n clearable?: boolean\n /**\n * Extends select to 100% of available width.\n * @default true\n */\n block?: boolean\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default bottom\n */\n side?: PopoverSide\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: PopoverAlign\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: number\n /**\n * Prevents collision detection in the custom menu. Use with caution.\n * @default true\n */\n avoidCollisions?: boolean\n /**\n * Set the width of the custom select menu\n * @default auto\n */\n listWidth?: number | \"auto\"\n /**\n * Defines the `min-width` property of the custom select menu, in pixels.\n * @default auto\n */\n listMinWidth?: number | \"auto\"\n /**\n * Defines the `max-width` property of the custom select menu, in pixels.\n * @default auto\n */\n listMaxWidth?: number | \"auto\"\n /** Predicate used to filter searches */\n searchPredicate?: SearchPredicate<T>\n /** Placeholder of the search input */\n searchPlaceholder?: string\n /**\n * Message displayed when search results are empty. Can be a simple string, or custom JSX.\n */\n searchEmptyMessage?: ReactNode\n}\n\ntype SingleSelectContextValue<T extends Option> = {\n multiple: false\n value: string\n TriggerView: React.FC<T>\n}\n\ntype MultiSelectContextValue<T extends Option> = {\n multiple: true\n value: string[]\n TriggerView: React.FC<MultiSelectTriggerViewProps<T>>\n}\n\ntype SelectContextValue<T extends Option> = (\n | SingleSelectContextValue<T>\n | MultiSelectContextValue<T>\n) & {\n triggerId: string\n // Props\n name?: string\n id?: string\n required?: boolean\n options: Options<T>\n disabled: boolean\n variant: SelectControlProps[\"variant\"]\n pill: boolean\n size: SelectControlProps[\"size\"]\n dropdownIconType: SelectControlProps[\"dropdownIconType\"]\n loading: boolean\n clearable: boolean\n placeholder: string\n loadingPlaceholder: string\n searchEmptyMessage: ReactNode\n searchPlaceholder: string\n TriggerStartIcon?: SelectControlProps[\"StartIcon\"]\n triggerClassName?: string\n opticallyAlign?: \"start\" | \"end\"\n optionClassName?: string\n OptionView: React.FC<T>\n actions: Actions\n onActionSelect: CallbackWithActionId\n block: boolean\n side: PopoverSide\n align: PopoverAlign\n alignOffset: number\n avoidCollisions: boolean\n listWidth?: number | \"auto\" // Default when not passed is to match the width of the trigger\n listMinWidth: number | \"auto\"\n listMaxWidth?: number | \"auto\"\n // References\n onSelectRef: React.MutableRefObject<(option: T, removeOption?: boolean) => void>\n searchPredicateRef: React.MutableRefObject<SearchPredicate<T>>\n // Derived\n searchable: boolean\n}\n\nconst SelectContext = createContext<SelectContextValue<Option> | null>(null)\n\nconst useSelectContext = () => {\n const context = use(SelectContext)\n\n if (!context) {\n throw new Error(\"Select components must be wrapped in <Select />\")\n }\n\n return context\n}\n\nconst DefaultOptionView = ({ label }: { label: string }) => <>{label}</>\nconst DefaultSingleTriggerView = ({ label }: { label: string }) => <>{label}</>\nconst DefaultMultiTriggerView = <T extends Option>({\n values,\n selectedAll,\n}: MultiSelectTriggerViewProps<T>) => {\n const displayValue = selectedAll\n ? \"All selected\"\n : values.length === 0\n ? // NOTE: Zero length is impossible - an empty option with `placeholder` is always returned\n \"Select...\"\n : values.length === 1\n ? values[0].label\n : `${values.length} selected`\n\n return <>{displayValue}</>\n}\n\nexport const Select = <T extends Option>(props: SelectProps<T>) => {\n const {\n id,\n required,\n value,\n name,\n multiple,\n variant = \"outline\",\n size = \"md\",\n dropdownIconType = \"dropdown\",\n loading = false,\n clearable = false,\n disabled = false,\n placeholder = \"Select...\",\n loadingPlaceholder = \"Loading...\",\n pill = true,\n listWidth,\n options,\n actions: propActions = [],\n side = \"bottom\",\n avoidCollisions = true,\n onChange,\n optionClassName,\n OptionView = DefaultOptionView,\n TriggerStartIcon,\n triggerClassName,\n opticallyAlign,\n TriggerView: TriggerViewFromProps,\n searchPlaceholder = \"\",\n searchPredicate = defaultSearchPredicate,\n searchEmptyMessage = \"No results found.\",\n listMaxWidth = \"auto\",\n } = props\n // Block default is dynamic, based on `variant`\n const block = props.block ?? variant !== \"ghost\"\n // Align default is dynamic, based on `block`\n const align = props.align ?? (block ? \"center\" : \"start\")\n const alignOffset = props.alignOffset ?? (align === \"center\" ? 0 : -5)\n // Default to \"auto\" for block selects and 300 for inline selects.\n const listMinWidth = props.listMinWidth ?? (block ? \"auto\" : 300)\n\n // Create stable, mutable references to avoid memoization requirements from consumers\n const onSelectRef = useLatestValue((selectedOption: T, removeOption?: boolean) => {\n if (multiple) {\n // When clearing values, the value is an\n if (!selectedOption.value) {\n onChange([])\n return\n }\n\n if (removeOption) {\n const nextValues = value.filter((v) => v !== selectedOption.value)\n const currentSelectedOptions = getOptionsByValues(options, nextValues)\n onChange(currentSelectedOptions)\n } else {\n const currentSelectedOptions = getOptionsByValues(options, value)\n onChange(currentSelectedOptions.concat(selectedOption))\n }\n } else {\n onChange(selectedOption)\n }\n })\n\n const searchPredicateRef = useRef<SearchPredicate<T>>(searchPredicate)\n searchPredicateRef.current = searchPredicate\n\n // It should be exceedingly uncommon to change actions dynamically, and they are unlikely to be a stable array reference from consumers\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Intentionally limiting when this stable value changes to length of actions\n const actions = useMemo<Actions>(() => propActions, [propActions.length])\n // We need to ensure that when action callbacks are called, we have fresh function references, even if the other action details did not change.\n const propActionsRef = useRef<Actions>(propActions)\n propActionsRef.current = propActions\n const onActionSelect = useCallback<CallbackWithActionId>((actionId: string) => {\n propActionsRef.current.find((a) => a.id === actionId)?.onSelect(actionId)\n }, [])\n\n // Determine when custom selects should be used\n const optionsCount = useMemo(\n () =>\n isOptionGroupArray(options)\n ? options.reduce((acc: number, group) => {\n return acc + group.options.length\n }, 0)\n : options.length,\n [options],\n )\n\n // Using ID for DOM selection instead of passing around and merging a ref. Pick your poison.\n const internalTriggerId = useId()\n const triggerId = `select-trigger-${internalTriggerId}`\n\n // Locking down searchable count to a single value. Could make this customizable in the future, but would want guardrails.\n const searchable = optionsCount > 15\n\n // Narrow known values for context\n const dynamicContextProps = useMemo<\n SingleSelectContextValue<T> | MultiSelectContextValue<T>\n >(() => {\n if (multiple) {\n return {\n multiple: true,\n value: value as string[],\n TriggerView: TriggerViewFromProps ?? DefaultMultiTriggerView,\n }\n }\n\n return {\n multiple: false,\n value: value as string,\n TriggerView: TriggerViewFromProps ?? DefaultSingleTriggerView,\n }\n }, [multiple, value, TriggerViewFromProps])\n\n const store = useMemo<SelectContextValue<T>>(\n () => ({\n ...dynamicContextProps,\n triggerId,\n id,\n // Forward props\n name,\n required,\n options,\n placeholder,\n loadingPlaceholder,\n loading,\n clearable,\n variant,\n pill,\n size,\n dropdownIconType,\n block,\n align,\n alignOffset,\n side,\n avoidCollisions,\n listWidth,\n listMinWidth,\n listMaxWidth,\n searchPlaceholder,\n searchEmptyMessage,\n TriggerStartIcon,\n triggerClassName,\n opticallyAlign,\n optionClassName,\n OptionView,\n actions,\n onActionSelect,\n onSelectRef,\n searchPredicateRef,\n // Derived state\n searchable,\n disabled,\n }),\n [\n dynamicContextProps,\n triggerId,\n id,\n required,\n name,\n options,\n placeholder,\n loadingPlaceholder,\n loading,\n clearable,\n variant,\n pill,\n size,\n dropdownIconType,\n block,\n align,\n alignOffset,\n side,\n avoidCollisions,\n listWidth,\n listMinWidth,\n listMaxWidth,\n searchPlaceholder,\n searchEmptyMessage,\n TriggerStartIcon,\n triggerClassName,\n opticallyAlign,\n optionClassName,\n OptionView,\n actions,\n onActionSelect,\n onSelectRef,\n searchable,\n disabled,\n ],\n )\n\n return (\n // NOTE: Cannot peacefully coerce SelectContextValue into a generic, so casting to any here.\n // This is safe because `store` is strongly typed above.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n <SelectContext.Provider value={store as any}>\n <CustomSelect />\n </SelectContext.Provider>\n )\n}\n\n// ============================================================\n// Trigger\n// ============================================================\ntype SelectTriggerProps = {\n onOpenChange?: (maybeNextState?: boolean) => void\n tabIndex?: number\n [\"aria-hidden\"]?: \"false\" | \"true\"\n ref?: React.Ref<HTMLButtonElement | null>\n}\n\nexport const SelectTrigger = (props: SelectTriggerProps) => {\n const {\n triggerId,\n id,\n required,\n value,\n multiple,\n options,\n loading,\n disabled,\n clearable,\n name,\n variant,\n pill,\n size,\n dropdownIconType,\n placeholder,\n loadingPlaceholder,\n block,\n opticallyAlign,\n triggerClassName,\n TriggerStartIcon,\n TriggerView,\n onSelectRef,\n } = useSelectContext()\n const {\n onOpenChange,\n // pass along props from Radix\n ...restProps\n } = props\n const firstValue = multiple ? value[0] : value\n const placeholderValue = loading ? loadingPlaceholder : placeholder\n\n const selectedItem = useMemo<Option>(\n () =>\n getOptionByValue(options, firstValue) || {\n value: \"\",\n label: placeholderValue,\n },\n [firstValue, options, placeholderValue],\n )\n const hasSelectedValue = multiple ? value.length > 0 : !!value\n const isPlaceholder = loading || !hasSelectedValue\n\n const typeahead = useMemo(() => createTypeahead(), [])\n\n const multipleTriggerViewProps = useMemo<MultiSelectTriggerViewProps<Option>>(() => {\n if (!multiple) {\n return { values: [], selectedAll: false }\n }\n\n const currentSelectedOptions = getOptionsByValues(options, value)\n const flatOptions = options.flatMap((o) => (\"options\" in o ? o.options : o))\n\n return {\n values: currentSelectedOptions.length\n ? currentSelectedOptions\n : [\n {\n value: \"\",\n label: placeholderValue,\n },\n ],\n selectedAll: flatOptions.length <= value.length,\n }\n }, [multiple, options, value, placeholderValue])\n\n const handleKeyDown = (evt: React.KeyboardEvent<HTMLButtonElement>) => {\n const key = evt.key\n\n // If not a command, check for typeahead\n // NOTE: Typeahead not supported in multi-select\n if (!multiple && isValidTypeaheadChar(key)) {\n const currentTypeaheadValue = typeahead(key)\n // Stop other listeners from reacting\n evt.stopPropagation()\n\n // Attempt to filter options based on the value\n // NOTE: We don't look at current highlighted value as a means to start the search\n const firstMatchingOption = getTypeaheadOption(options, currentTypeaheadValue, firstValue)\n\n if (firstMatchingOption) {\n onSelectRef.current(firstMatchingOption)\n }\n }\n }\n\n const handleClearClick = () => {\n onSelectRef.current({ value: \"\", label: \"\" })\n // Ensure open state is closed\n onOpenChange?.(false)\n }\n\n return (\n <SelectControl\n id={triggerId}\n className={triggerClassName}\n selected={!isPlaceholder}\n variant={variant}\n pill={pill}\n block={block}\n size={size}\n disabled={disabled}\n loading={loading}\n StartIcon={TriggerStartIcon}\n opticallyAlign={opticallyAlign}\n dropdownIconType={dropdownIconType}\n onClearClick={clearable ? handleClearClick : undefined}\n onInteract={onOpenChange}\n onKeyDown={handleKeyDown}\n {...restProps}\n >\n {multiple ? <TriggerView {...multipleTriggerViewProps} /> : <TriggerView {...selectedItem} />}\n {(name || id) && (\n <input\n id={id}\n name={name}\n value={firstValue}\n tabIndex={-1}\n onFocus={() => {\n document.getElementById(triggerId)?.focus()\n }}\n // keep react from complaining - don't make this readOnly because that\n // prevents the value from being required\n onChange={() => {}}\n required={required}\n className=\"sr-only w-full h-0 left-0 bottom-0 pointer-events-none\"\n aria-hidden=\"true\"\n />\n )}\n </SelectControl>\n )\n}\n\n// ============================================================\n// Custom Select\n// ============================================================\nconst CustomSelect = () => {\n const {\n triggerId,\n loading,\n side,\n align,\n alignOffset,\n avoidCollisions,\n listWidth,\n listMinWidth,\n listMaxWidth,\n } = useSelectContext()\n const [open, setOpen] = useState<boolean>(false)\n const selectContentRef = useRef<HTMLDivElement>(null)\n\n const handleOpenChange = (maybeNextState?: boolean) => {\n // Toggle the current state when called without a specific state\n const nextState = maybeNextState === undefined ? !open : maybeNextState\n setOpen(nextState)\n\n // When we're closing, manage focus back to trigger manually\n if (!nextState) {\n // Wait until the next tick to determine if another element has become focused\n setTimeout(() => {\n // This should never happen because TransitionGroup should keep the select content in the DOM long\n // enough for this callback to run. However, in the event that the ref is null, not focusing is safer.\n if (!selectContentRef.current) {\n return\n }\n\n const activeElement = document.activeElement\n\n // Don't restore focus to the trigger if focus has moved outside of the select menu\n if (activeElement && !selectContentRef.current.contains(activeElement)) {\n return\n }\n\n document.getElementById(triggerId)?.focus()\n })\n }\n }\n\n useEscCloseStack(open, () => {\n handleOpenChange(false)\n })\n\n return (\n <Popover.Root\n open={open}\n onOpenChange={(nextState) => {\n // Prevent opening while loading\n if (loading && nextState) {\n return\n }\n\n handleOpenChange(nextState)\n }}\n modal={false}\n >\n <Popover.Trigger asChild>\n <SelectTrigger onOpenChange={handleOpenChange} />\n </Popover.Trigger>\n <Popover.Portal forceMount>\n <TransitionGroup\n className={s.Menu}\n enterDuration={350}\n exitDuration={200}\n disableAnimations\n >\n {open && (\n <Popover.Content\n key=\"dropdown\"\n ref={selectContentRef}\n forceMount\n className={s.MenuList}\n side={side}\n sideOffset={5}\n align={align}\n alignOffset={alignOffset}\n avoidCollisions={avoidCollisions}\n collisionPadding={{ bottom: 30, top: 30 }}\n // Prevent Radix auto focus so we can handle our own from within <CustomSelectMenu />\n onOpenAutoFocus={preventDefaultHandler}\n // Radix waits until the animation completes before directing focus, which is janky.\n onCloseAutoFocus={preventDefaultHandler}\n onEscapeKeyDown={preventDefaultHandler}\n style={toCssVariables({\n \"select-list-width\": listWidth,\n \"select-list-min-width\": listMinWidth,\n \"select-list-max-width\": listMaxWidth,\n })}\n >\n <CustomSelectMenu onOpenChange={handleOpenChange} />\n </Popover.Content>\n )}\n </TransitionGroup>\n </Popover.Portal>\n </Popover.Root>\n )\n}\n\ntype CustomSelectMenuContextValue = {\n valueRef: React.RefObject<string | null>\n listId: string\n requestCloseRef: React.RefObject<() => void | null>\n listRef: React.RefObject<HTMLDivElement | null>\n // Highlighting\n highlightedValue: string\n setHighlightedValue: React.Dispatch<React.SetStateAction<string>>\n // Search\n searchTerm: string\n setSearchTerm: React.Dispatch<React.SetStateAction<string>>\n searchInputRef: React.RefObject<HTMLInputElement | null>\n}\n\nconst CustomSelectMenuContext = createContext<CustomSelectMenuContextValue | null>(null)\n\nconst useCustomSelectMenuContext = () => {\n const context = use(CustomSelectMenuContext)\n\n if (!context) {\n throw new Error(\"CustomSelectMenu components must be wrapped in <CustomSelectMenu />\")\n }\n\n return context\n}\n\ntype CustomSelectMenuProps = {\n onOpenChange: (maybeNextState?: boolean) => void\n}\n\nconst CustomSelectMenu = ({ onOpenChange }: CustomSelectMenuProps) => {\n const { multiple, value, options, searchable, searchPredicateRef } = useSelectContext()\n const requestCloseRef = useRef<() => void>(() => onOpenChange(false))\n const menuRef = useRef<HTMLDivElement>(null)\n const listRef = useRef<HTMLDivElement>(null)\n const searchInputRef = useRef<HTMLInputElement>(null)\n const [searchTerm, setSearchTerm] = useState(\"\")\n const [highlightedValue, setHighlightedValue] = useState<string>(() => {\n const selectedValue = multiple ? value[0] : value\n return (selectedValue || getFirstValidOption(options)?.value) ?? \"\"\n })\n const typeahead = useMemo(() => createTypeahead(), [])\n const internalListId = useId()\n const listId = `select-list-${internalListId}`\n\n // Lock `value` for a given open to prevent janky change during close animation\n // NOTE: This ref has no use in MultiSelect cases, set to empty string as a no-op\n const valueRef = useRef<string>(multiple ? \"\" : value)\n\n // Trim and lowercase search value\n const literalSearchTerm = useMemo(() => searchTerm.trim().toLocaleLowerCase(), [searchTerm])\n const filteredOptions = useMemo(\n () => filterOptions(options, literalSearchTerm, searchPredicateRef.current),\n [options, literalSearchTerm, searchPredicateRef],\n )\n const firstOption = useMemo(() => getFirstValidOption(filteredOptions), [filteredOptions])\n\n // Regrettable requirement for running an effect *after* mount\n const isMountStableRef = useRef<boolean>(false)\n\n const handleKeyDown = (evt: React.KeyboardEvent) => {\n const key = evt.key\n const firstValue = multiple ? value[0] : value\n const targetValue = highlightedValue || firstOption?.value || firstValue\n const isFocusedInSearch = document.activeElement === searchInputRef.current\n\n const menuElement = menuRef.current\n\n // Should be generally impossible for menuRef.current to not exist\n // unless we've unmounted and manage to fire this handler.\n if (!menuElement) {\n return\n }\n\n const triggerHighlightedOption = () => {\n const pointerUpEvent = new PointerEvent(\"pointerup\", {\n bubbles: true,\n cancelable: true,\n pointerType: \"mouse\",\n })\n\n // Find the current highlighted option\n const selectedOption = findOptionByValue(highlightedValue, menuElement)\n selectedOption?.dispatchEvent(pointerUpEvent)\n }\n\n const highlightOption = (val: string, element: Element) => {\n setHighlightedValue(val)\n element.scrollIntoView({ block: \"nearest\" })\n }\n\n const highlightSelectedOrFirstOption = () => {\n // Attempt to move highlight to selected item\n const maybeFirstValue = multiple ? value[0] : value\n\n if (maybeFirstValue) {\n const selectedElement = findOptionByValue(maybeFirstValue, menuElement)\n\n if (selectedElement) {\n highlightOption(maybeFirstValue, selectedElement)\n return\n }\n }\n\n // If value isn't set, or the selected node wasn't found in the DOM,\n // attempt to move focus to the first valid option.\n const firstValidOption = getFirstValidOption(options)\n\n if (firstValidOption) {\n const firstValidOptionElement = findOptionByValue(firstValidOption.value, menuElement)\n if (firstValidOptionElement) {\n highlightOption(firstValidOption.value, firstValidOptionElement)\n }\n }\n }\n\n // Commands\n switch (key) {\n case \"ArrowDown\": {\n evt.preventDefault()\n\n // If there's no highlighted value, or the highlighted value is not in the DOM\n if (!highlightedValue || !findOptionByValue(highlightedValue, menuElement)) {\n // Attempt to move highlight to selected item\n highlightSelectedOrFirstOption()\n\n // Short-circuit because we have no highlighted value to advance from\n return\n }\n\n // Otherwise, move to the next option\n const nextElement = findNextOption(highlightedValue, menuElement)\n const nextValue = nextElement?.getAttribute(\"data-option-id\")\n if (nextElement && nextValue) {\n highlightOption(nextValue, nextElement)\n }\n\n return\n }\n case \"ArrowUp\": {\n evt.preventDefault()\n\n // If there's no highlighted value, or the highlighted value is not in the DOM\n if (!highlightedValue || !findOptionByValue(highlightedValue, menuElement)) {\n // Attempt to move highlight to selected item\n highlightSelectedOrFirstOption()\n\n // Short-circuit because we have no highlighted value to advance from\n return\n }\n\n const previousElement = findPreviousOption(targetValue, menuElement)\n const previousValue = previousElement?.getAttribute(\"data-option-id\")\n if (previousElement && previousValue) {\n highlightOption(previousValue, previousElement)\n }\n\n return\n }\n case \"Enter\":\n // Prevent default enter behavior from the search input, if present\n evt.preventDefault()\n\n // Send a pointerDown event into the currently highlighted option\n triggerHighlightedOption()\n\n return\n case \" \":\n // Allow spaces in search, and don't treat as enter\n // if there is a valid literalSearchTerm.\n if (literalSearchTerm && isFocusedInSearch) {\n return\n }\n\n // Prevent space from entering search input\n evt.preventDefault()\n\n // Send a pointerDown event into the currently highlighted option\n triggerHighlightedOption()\n\n return\n default:\n break\n }\n\n // If not a command, check for typeahead\n if (isValidTypeaheadChar(key)) {\n // Skip typeahead logic when we're focused in the search input\n if (isFocusedInSearch) {\n return\n }\n\n // Extend the current typeahead and get the latest value\n const currentTypeaheadValue = typeahead(key)\n\n // Stop other listeners from reacting\n evt.stopPropagation()\n\n // Attempt to filter options based on the value, starting at the highlighted value\n const firstMatchingOption = getTypeaheadOption(\n options,\n currentTypeaheadValue,\n highlightedValue,\n )\n\n if (firstMatchingOption) {\n const matchedNode = findOptionByValue(firstMatchingOption.value, menuElement)\n\n // Only change the highlight if we found the actual node\n if (matchedNode) {\n setHighlightedValue(firstMatchingOption.value)\n // Ensure the newly highlighted option is scrolled into view\n matchedNode.scrollIntoView({ block: \"nearest\" })\n }\n }\n }\n }\n\n const store = useMemo(\n () => ({\n valueRef,\n listId,\n highlightedValue,\n setHighlightedValue,\n requestCloseRef,\n searchTerm,\n setSearchTerm,\n searchInputRef,\n listRef,\n }),\n [listId, highlightedValue, setHighlightedValue, searchTerm, setSearchTerm],\n )\n\n // On mount behavior\n useEffect(() => {\n // Ensure initial highlighted option is in view\n // NOTE: Allowing for a render frame ensures content is positioned correctly before scrolling it into view.\n waitForAnimationFrame(() => {\n if (!menuRef.current) {\n return\n }\n\n // Ensure the highlighted option is in view\n const currentOption = findOptionByValue(highlightedValue, menuRef.current)\n // Scroll the selected item into view, and its bottom edge.\n currentOption?.scrollIntoView({ block: \"center\" })\n })\n\n // Send initial focus to the menu container or search input, to capture key events\n const autoFocusTarget = searchInputRef.current || menuRef.current\n autoFocusTarget?.focus({ preventScroll: true })\n\n // Required for <StrictMode>, because we need to unset this token\n // when the hooks are re-run. It's an imperative effect that we need to manage.\n return () => {\n isMountStableRef.current = false\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Intentionally an onMount effect\n }, [])\n\n // On search behavior\n useLayoutEffect(() => {\n // This effect will run on mount, but we want to skip it.\n // The on mount effect is responsible for handling mount behavior,\n // but this effect is specifically responsible for handling search changes\n if (!isMountStableRef.current) {\n isMountStableRef.current = true\n return\n }\n\n // Impossible while mounted, list ref will exist\n if (!listRef.current) {\n return\n }\n\n // Reset scroll position to the top\n listRef.current.scrollTop = 0\n\n // Highlight first item in the list\n const maybeFirstOption = getFirstValidOption(filteredOptions)\n if (maybeFirstOption) setHighlightedValue(maybeFirstOption.value)\n }, [filteredOptions])\n\n return (\n <CustomSelectMenuContext value={store}>\n <div id={listId} className={s.MenuInner} onKeyDown={handleKeyDown} ref={menuRef} tabIndex={0}>\n {searchable && <CustomSelectSearch value={searchTerm} onChange={setSearchTerm} />}\n <CustomSelectList filteredOptions={filteredOptions} />\n <CustomSelectActions />\n </div>\n </CustomSelectMenuContext>\n )\n}\n\ntype CustomSelectSearchProps = {\n value: string\n onChange: (nextSearchTerm: string) => void\n}\n\nconst CustomSelectSearch = ({ value, onChange }: CustomSelectSearchProps) => {\n const { searchPlaceholder } = useSelectContext()\n const { listId, searchInputRef } = useCustomSelectMenuContext()\n\n const handleChange = (evt: React.ChangeEvent<HTMLInputElement>) => {\n onChange(evt.target.value)\n }\n\n return (\n <div className={s.Search}>\n <Input\n startAdornment={<Search width={16} height={16} className=\"fill-secondary\" />}\n ref={searchInputRef}\n value={value}\n placeholder={searchPlaceholder}\n onChange={handleChange}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n aria-autocomplete=\"list\"\n role=\"combobox\"\n aria-controls={listId}\n aria-expanded\n />\n </div>\n )\n}\n\nconst isOptionGroup = <T extends Option>(\n mixedOption: T | OptionGroup<T>,\n): mixedOption is OptionGroup<T> => {\n return \"options\" in mixedOption\n}\n\nconst isOptionGroupArray = <T extends Option>(arr: Options<T>): arr is OptionGroup<T>[] => {\n return arr[0] && isOptionGroup(arr[0])\n}\n\nconst HARD_OPTIONS_LIMIT = 300\n\nconst CustomSelectList = <T extends Option>({\n filteredOptions,\n}: {\n filteredOptions: Options<T>\n}) => {\n const { searchEmptyMessage } = useSelectContext()\n const { listRef } = useCustomSelectMenuContext()\n\n if (!filteredOptions.length) {\n return typeof searchEmptyMessage === \"string\" ? (\n <p className={s.SearchEmpty} data-text-only>\n {searchEmptyMessage}\n </p>\n ) : (\n <div className={s.SearchEmpty}>{searchEmptyMessage}</div>\n )\n }\n\n // We hard limit within groups, so at this level we will only limit flat arrays\n const isGrouped = isOptionGroupArray(filteredOptions)\n const hasHardLimit = !isGrouped && filteredOptions.length > HARD_OPTIONS_LIMIT\n\n const options = isGrouped\n ? filteredOptions.map((group) => <CustomSelectGroup key={group.label} {...group} />)\n : filteredOptions\n .slice(0, HARD_OPTIONS_LIMIT)\n .map((option) => <CustomSelectOption key={option.value} {...option} />)\n\n return (\n <div className={s.OptionsList} ref={listRef}>\n {options}\n {hasHardLimit && (\n <CustomSelectHardLimit numHidden={filteredOptions.length - HARD_OPTIONS_LIMIT} />\n )}\n </div>\n )\n}\n\nconst DEFAULT_OPTIONS_LIMIT = {\n limit: 100,\n label: \"Show all\",\n}\n\nconst CustomSelectGroup = <T extends Option>({\n label,\n options,\n optionsLimit = DEFAULT_OPTIONS_LIMIT,\n}: OptionGroup<T>) => {\n const groupId = useId()\n const { searchTerm, setHighlightedValue } = useCustomSelectMenuContext()\n const [limitExpanded, setLimitExpanded] = useState<boolean>(false)\n\n const hasExpandableLimit = optionsLimit.limit < options.length && !searchTerm && !limitExpanded\n const hasHardLimit = HARD_OPTIONS_LIMIT < options.length && !hasExpandableLimit\n\n let maybeLimitedOptions = options\n if (hasExpandableLimit) {\n maybeLimitedOptions = options.slice(0, optionsLimit.limit)\n } else if (hasHardLimit) {\n maybeLimitedOptions = options.slice(0, HARD_OPTIONS_LIMIT)\n }\n\n const handleLimitExpanded = () => {\n // Expand options\n setLimitExpanded(true)\n\n // Set highlight to the first option from the newly expanded list\n setHighlightedValue(options[optionsLimit.limit].value)\n }\n\n return (\n // NOTE: Important for crawling that groups are flat\n <>\n <div className={s.OptionGroupHeading}>\n <div className={s.OptionIndicatorSlot} />\n {label}\n </div>\n {maybeLimitedOptions.map((limitedOptions) => (\n <CustomSelectOption key={limitedOptions.value} {...limitedOptions} />\n ))}\n {hasExpandableLimit && (\n <CustomSelectExpandableLimit\n value={`group-limit-${groupId}`}\n label={optionsLimit.label}\n onPointerUp={handleLimitExpanded}\n />\n )}\n {hasHardLimit && <CustomSelectHardLimit numHidden={options.length - HARD_OPTIONS_LIMIT} />}\n </>\n )\n}\n\ntype CustomSelectHardLimitProps = {\n numHidden: number\n}\n\nconst CustomSelectHardLimit = ({ numHidden }: CustomSelectHardLimitProps) => {\n return (\n <div className={s.OptionHardLimitHeading}>\n <div className={s.OptionIndicatorSlot} />\n {`…and ${numHidden.toLocaleString()} more options. Use search to refine results further.`}\n </div>\n )\n}\n\ntype CustomSelectExpandableLimitProps = {\n value: string\n label: string\n onPointerUp: () => void\n}\n\nconst CustomSelectExpandableLimit = ({\n value,\n label,\n onPointerUp,\n}: CustomSelectExpandableLimitProps) => {\n const { highlightedValue, setHighlightedValue } = useCustomSelectMenuContext()\n\n const isHighlighted = value === highlightedValue\n\n const handlePointerMove = () => {\n if (isHighlighted) {\n return\n }\n\n setHighlightedValue(value)\n }\n\n const handlePointerLeave = () => {\n setHighlightedValue((currentHighlightedValue) => {\n // If the current value is not this one, don't do anything\n // Otherwise, clear the value, removing the active highlight on the menu.\n return currentHighlightedValue !== value ? currentHighlightedValue : \"\"\n })\n }\n\n // This component acts a LOT like an Option, but has enough bespoke behavior\n // that it cannot literally be one. We copy the important parts of Option for\n // keyboard navigation, UX, etc.\n return (\n <div\n className={clsx(s.Option, s.OptionsLimit)}\n data-option-id={value}\n data-highlight={isHighlighted ? \"\" : undefined}\n role=\"option\"\n aria-selected={isHighlighted}\n onPointerUp={onPointerUp}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n >\n <div className={clsx(s.PressableInner, s.OptionInner)}>\n <div className={s.OptionIndicatorSlot} />\n {label}\n </div>\n </div>\n )\n}\n\nconst INTERNAL_DOM_SELECTION_DATA_ATTR = \"data-option-id\"\n\nconst CustomSelectOption = (option: Option) => {\n const {\n optionClassName,\n OptionView,\n value: propsValue,\n multiple,\n onSelectRef,\n } = useSelectContext()\n const { valueRef, requestCloseRef, highlightedValue, setHighlightedValue } =\n useCustomSelectMenuContext()\n const { value, disabled, tooltip } = option\n\n // NOTE: SingleSelect mode looks at the ref instead of the live `propValue` intentionally\n // to avoid selecting the item as the select closes.\n const currentValue = valueRef.current\n const isSelected = multiple ? propsValue.includes(value) : value === currentValue\n const isHighlighted = value === highlightedValue\n\n const handlePointerUp = () => {\n if (multiple) {\n // Trigger the change ref, optionally as a remove\n onSelectRef.current(option, isSelected)\n } else {\n // Trigger the change ref\n onSelectRef.current(option)\n // Request the dropdown to close\n requestCloseRef.current?.()\n }\n }\n\n const handlePointerMove = () => {\n if (isHighlighted) {\n return\n }\n\n setHighlightedValue(value)\n }\n\n const handlePointerLeave = () => {\n setHighlightedValue((currentHighlightedValue) => {\n // If the current value is not this one, don't do anything\n // Otherwise, clear the value, removing the active highlight on the menu.\n return currentHighlightedValue !== value ? currentHighlightedValue : \"\"\n })\n }\n\n return (\n <div\n className={clsx(s.Option, optionClassName)}\n data-highlight={isHighlighted ? \"\" : undefined}\n role=\"option\"\n aria-selected={isHighlighted}\n data-selected={isSelected ? \"\" : undefined}\n // Internal attribute for selecting DOM nodes\n {...{ [INTERNAL_DOM_SELECTION_DATA_ATTR]: value }}\n // Allow options to behave like a native select, when you can open and select an item in a single click\n onPointerUp={disabled ? undefined : handlePointerUp}\n // Pointer move allows us to prevent contention from keyboard presses and a still mouse\n // which does trigger events like onMouseEnter, creating weird battles with mouse and keyboard focus.\n onPointerMove={disabled ? undefined : handlePointerMove}\n onPointerLeave={disabled ? undefined : handlePointerLeave}\n aria-disabled={disabled}\n data-disabled={disabled ? \"\" : undefined}\n >\n <div className={s.PressableInner}>\n <div className={s.OptionInner}>\n <div className={s.OptionIndicatorSlot}>\n {isSelected && <Check className={s.OptionCheck} />}\n </div>\n <OptionView {...option} />\n {tooltip && (\n <Tooltip content={tooltip.content} maxWidth={tooltip.maxWidth} side=\"right\">\n <Info />\n </Tooltip>\n )}\n </div>\n {option.description && (\n <div className={s.OptionInner}>\n <div className={s.OptionIndicatorSlot} />\n {option.description}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nconst CustomSelectActions = () => {\n const { actions } = useSelectContext()\n\n if (actions.length === 0) {\n return null\n }\n\n return (\n <div className={s.ActionsContainer}>\n {actions.map((action) => (\n <CustomSelectAction key={action.id} {...action} />\n ))}\n </div>\n )\n}\n\nconst CustomSelectAction = ({ id, label, Icon, className }: Action) => {\n const { onActionSelect } = useSelectContext()\n const { requestCloseRef } = useCustomSelectMenuContext()\n\n const handleKeyDown = (evt: React.KeyboardEvent<HTMLDivElement>) => {\n const key = evt.key\n\n switch (key) {\n case \"Tab\":\n // Allow tabbing to pass propagation as normal,\n // which bubbles up to the focus trap of Radix Popover\n break\n case \"Enter\":\n case \" \":\n evt.stopPropagation()\n handlePointerUp()\n break\n default:\n evt.stopPropagation()\n }\n }\n\n const handlePointerUp = () => {\n // Trigger the action's through our context helper, not the method on this action (it may be a stale reference)\n onActionSelect(id)\n // Request to close the dropdown\n requestCloseRef.current?.()\n }\n\n return (\n <div className={s.Action} onPointerUp={handlePointerUp} onKeyDown={handleKeyDown} tabIndex={0}>\n <div className={clsx(s.ActionInner, className)}>\n {Icon && <Icon role=\"presentation\" />}\n {label}\n </div>\n </div>\n )\n}\n\n// ============================================================\n// Utilities\n// ============================================================\nconst defaultSearchPredicate = (option: Option, searchTerm: string) =>\n option.label.toLowerCase().includes(searchTerm)\n\nconst filterOptions = <T extends Option>(\n options: Options<T>,\n searchTerm: string,\n searchIterator: SearchPredicate<T>,\n): Options<T> => {\n const searchValue = searchTerm.trim().toLocaleLowerCase()\n\n if (!searchValue) {\n return options\n }\n\n const filterOption = (option: T): boolean => searchIterator(option, searchValue)\n\n if (isOptionGroupArray(options)) {\n return options.reduce((acc, group) => {\n const filtered = group.options.filter(filterOption)\n\n if (filtered.length) {\n acc.push({\n ...group,\n options: filtered,\n })\n }\n return acc\n }, [] as OptionGroup<T>[])\n } else {\n return options.reduce((acc, option) => {\n if (filterOption(option)) acc.push(option)\n return acc\n }, [] as T[])\n }\n}\n\nconst getFirstValidOption = <T extends Option>(options: Options<T>): T | undefined => {\n if (!options.length) {\n return undefined\n }\n\n let found: T | undefined\n\n for (const opt of options) {\n if (isOptionGroup(opt)) {\n const firstNonDisabled = opt.options.find((i) => !i.disabled)\n if (firstNonDisabled) {\n found = firstNonDisabled\n break\n }\n } else {\n if (!opt.disabled) {\n found = opt\n break\n }\n }\n }\n\n return found\n}\n\nconst getOptionByValue = <T extends Option>(options: Options<T>, value: string): T | undefined => {\n let found: T | undefined\n\n for (const opt of options) {\n if (isOptionGroup(opt)) {\n const exists = opt.options.find((i) => i.value === value)\n if (exists) {\n found = exists\n break\n }\n } else {\n if (opt.value === value) {\n found = opt\n break\n }\n }\n }\n\n return found\n}\n\nconst getOptionsByValues = <T extends Option>(options: Options<T>, values: string[]): T[] => {\n let found: T[] = []\n const lookup = new Set(values)\n\n for (const opt of options) {\n if (isOptionGroup(opt)) {\n const exists = opt.options.filter((i) => lookup.has(i.value))\n found = found.concat(exists)\n } else {\n if (lookup.has(opt.value)) {\n found.push(opt)\n }\n }\n }\n\n return found\n}\n\nconst MAX_DOM_CRAWLS = 40\n\nconst findOptionByValue = (currentValue: string, container: HTMLElement) =>\n container.querySelector(`[data-option-id=\"${currentValue}\"]`)\n\nconst isValidOptionNode = (node: Element) => node.matches(\"[data-option-id]:not([data-disabled])\")\n\nconst findNextOption = (currentValue: string, container: HTMLElement) => {\n const currentOption = findOptionByValue(currentValue, container)\n\n let nextNode = currentOption?.nextElementSibling\n let maxSteps = 0\n\n while (nextNode && maxSteps < MAX_DOM_CRAWLS) {\n if (isValidOptionNode(nextNode)) {\n return nextNode\n }\n\n nextNode = nextNode.nextElementSibling\n maxSteps += 1\n }\n}\n\nconst findPreviousOption = (currentValue: string, container: HTMLElement) => {\n const currentOption = findOptionByValue(currentValue, container)\n\n let nextNode = currentOption?.previousElementSibling\n let maxSteps = 0\n\n while (nextNode && maxSteps < MAX_DOM_CRAWLS) {\n if (isValidOptionNode(nextNode)) {\n return nextNode\n }\n\n nextNode = nextNode.previousElementSibling\n maxSteps += 1\n }\n}\n\nconst createTypeahead = () => {\n let currentValue: string = \"\"\n let timeoutId: ReturnType<typeof setTimeout>\n\n return (char: string) => {\n // Searching is case-insensitive\n char = char.toLowerCase()\n\n // Add the new character to the current value\n currentValue += char\n\n // Clear the previous timeout if there was one\n if (timeoutId) clearTimeout(timeoutId)\n\n // Reset the value after a brief delay\n timeoutId = setTimeout(() => {\n currentValue = \"\"\n }, 500)\n\n // When a user is typing the same value, like \"llll\", assume they are cycling through items starting with \"l\"\n // We continue to build up the string in case another letter is typed, and then release the full value.\n // For example, if the user types \"ooog\", it will return \"o\", until \"g\" is typed, and then return the \"ooog\".\n const isCycling = char.repeat(currentValue.length) === currentValue\n\n // Return the typeahead value\n return isCycling ? char : currentValue\n }\n}\n\nconst isValidTypeaheadChar = (char: string): boolean => /^[a-zA-Z0-9]$/.test(char)\n\nconst getTypeaheadOption = <T extends Option>(\n options: Options<T>,\n typeaheadValue: string,\n currentHighlightValue?: string,\n): T | undefined => {\n // Ensure options actually exist\n if (!options.length) {\n return undefined\n }\n\n let matchBeforeHighlight: T | undefined\n let matchAfterHighlight: T | undefined\n // If we' aren't provided a highlighted value, start from the top (e.g., act like it's found)\n let foundHighlightedValue: boolean = !currentHighlightValue\n\n const optionValidAndMatches = ({ disabled, label, value }: T) => {\n // Side effect of looping\n if (value === currentHighlightValue) {\n foundHighlightedValue = true\n // Don't return highlighted value\n return false\n }\n\n return !disabled && label.toLowerCase().startsWith(typeaheadValue)\n }\n\n for (const opt of options) {\n if (isOptionGroup(opt)) {\n for (const option of opt.options) {\n if (optionValidAndMatches(option)) {\n if (foundHighlightedValue) {\n matchAfterHighlight = option\n // We're done after we've found an after match\n break\n } else {\n // Keep the first found \"before\" match\n matchBeforeHighlight = matchBeforeHighlight || option\n }\n }\n }\n } else {\n if (optionValidAndMatches(opt)) {\n if (foundHighlightedValue) {\n matchAfterHighlight = opt\n // We're done after we've found an after match\n break\n } else {\n // Keep the first found \"before\" match\n matchBeforeHighlight = matchBeforeHighlight || opt\n }\n }\n }\n }\n\n return matchAfterHighlight || matchBeforeHighlight\n}\n", "import { useEffect, useId } from \"react\"\nimport { useLatestValue } from \"./useLatestValue\"\n\ntype Handler = {\n id: string\n callback: React.MutableRefObject<() => void>\n}\n\nlet handlers: Handler[] = []\nlet listenerBound = false\n\nconst handleKeyDown = (evt: KeyboardEvent) => {\n if (evt.key === \"Escape\") {\n // Attempt to call the first handler in the stack, if it exists\n const [firstHandler] = handlers\n\n if (firstHandler) {\n evt.preventDefault()\n firstHandler.callback.current?.()\n }\n }\n}\n\nconst managerListener = () => {\n if (handlers.length > 0 && !listenerBound) {\n document.body.addEventListener(\"keydown\", handleKeyDown)\n listenerBound = true\n } else if (handlers.length === 0 && listenerBound) {\n document.body.removeEventListener(\"keydown\", handleKeyDown)\n listenerBound = false\n }\n}\n\nconst registerHandler = (handler: Handler) => {\n handlers.unshift(handler)\n managerListener()\n}\n\nconst unregisterHandler = ({ id }: Handler) => {\n handlers = handlers.filter((h) => h.id !== id)\n managerListener()\n}\n\nexport const useEscCloseStack = (listening: boolean, cb: () => void) => {\n const id = useId()\n const latestCallback = useLatestValue(cb)\n\n useEffect(() => {\n if (!listening) {\n return\n }\n\n const handler = { id, callback: latestCallback }\n registerHandler(handler)\n\n return () => unregisterHandler(handler)\n }, [id, listening, latestCallback])\n}\n", "import { useRef } from \"react\"\n\nexport function useLatestValue<T>(value: T) {\n const ref = useRef(value)\n ref.current = value\n return ref\n}\n", "\"use client\"\n\nimport clsx from \"clsx\"\nimport { useRef, type ReactNode } from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\nimport { handlePressableMouseEnter } from \"../../lib/helpers\"\nimport type { ControlSize, Variants } from \"../../types\"\nimport { Button } from \"../Button\"\nimport { ChevronDownVector, DropdownVector, X } from \"../Icon\"\nimport { LoadingIndicator } from \"../Indicator\"\nimport s from \"./SelectControl.module.css\"\n\nexport type DropdownIconType = \"chevronDown\" | \"dropdown\" | \"none\"\n\nexport type SelectControlProps = Omit<React.HTMLAttributes<HTMLSpanElement>, \"onClick\"> & {\n /**\n * Style variant for the Button\n * @default fill\n */\n variant?: Variants<\"soft\" | \"outline\" | \"ghost\">\n /**\n * Determines if the control should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Extends the control to 100% of available width.\n * @default true\n */\n block?: boolean\n /**\n * Applies a negative margin using the current gutter to optically align the control\n * with surrounding content.\n */\n opticallyAlign?: \"start\" | \"end\"\n /**\n * Disables the control visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Visually indicates that the control is in an invalid state\n * @default false\n */\n invalid?: boolean\n /**\n * Indicates that the control is selected. An unselected state will display placeholder styles.\n * @default false\n */\n selected?: boolean\n /**\n * Display a clear action that allows the select to be unset.\n * @default false\n */\n onClearClick?: () => void\n /**\n * Primary handler for when the control is selected with pointer or keyboard events\n */\n onInteract?: () => void\n /**\n * Determines size of the size and spacing of the control.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: ControlSize\n /**\n * Displays loading indicator on top of button contents\n * @default false\n */\n loading?: boolean\n /**\n * Icon displayed in the far right of the select trigger\n * @default dropdown\n */\n dropdownIconType?: DropdownIconType\n /** Icon displayed at the start of the control */\n StartIcon?: React.ComponentType<React.SVGProps<SVGSVGElement>>\n /** Custom class applied to the control element */\n className?: string\n /** Content rendered for the control */\n children: ReactNode\n ref?: React.Ref<HTMLSpanElement | null>\n}\n\nexport const SelectControl = ({\n ref,\n onPointerDown,\n onKeyDown,\n onPointerEnter,\n onInteract,\n invalid,\n disabled,\n children,\n className,\n variant = \"outline\",\n size = \"md\",\n block,\n opticallyAlign,\n pill = true,\n loading,\n onClearClick,\n selected = false,\n StartIcon,\n dropdownIconType = \"dropdown\",\n ...restProps\n}: SelectControlProps) => {\n const controlRef = useRef<HTMLSpanElement>(null)\n const clearable = !!onClearClick\n const showClearAction = clearable && selected && !loading && !disabled\n const hasDropdownIcon = dropdownIconType && dropdownIconType !== \"none\" && !loading\n const hasAnyTertiaryIndicator = showClearAction || loading || hasDropdownIcon\n const isInteractive = !loading && !disabled\n\n // Act like a <button> and fire the click handler on keyboard actions\n const handleKeyDown = (evt: React.KeyboardEvent<HTMLSpanElement>) => {\n switch (evt.key) {\n // NOTE: \"Enter\" does not open selects, as it may be an attempt to submit a form\n case \"ArrowDown\":\n case \"ArrowUp\":\n case \" \":\n evt.stopPropagation()\n evt.preventDefault()\n\n if (onInteract) {\n onInteract()\n } else {\n // Otherwise, send a synthetic trigger event to Radix (presumably)\n controlRef.current?.dispatchEvent(\n new PointerEvent(\"pointerdown\", {\n bubbles: true,\n cancelable: true,\n pointerType: \"mouse\", // mimic mouse interaction\n }),\n )\n }\n break\n case \"Enter\":\n // NOTE: \"Enter\" does not open selects, as it may be an attempt to submit a form\n break\n default:\n // Allow all other key presses through\n onKeyDown?.(evt)\n }\n }\n\n const handlePointerDown = (evt: React.PointerEvent<HTMLSpanElement>) => {\n // Don't trigger on right clicks\n if (evt.button === 2) {\n return\n }\n\n // Prevent focus from entering the click target of the select\n // so that focus correctly moves into the menu.\n evt.stopPropagation()\n\n if (onInteract) {\n evt.preventDefault()\n onInteract()\n } else {\n // NOTE: cannot preventDefault() here, for radix\n onPointerDown?.(evt)\n // @ts-expect-error -- `onClick` can only be present if Radix is trying to spread it.\n // An example would be `<Popover>`, but we specifically open this component on `onPointerDown`.\n // Trigger the handler, assuming that `onPointerDown` is not going to be responsible for opening.\n restProps.onClick?.(evt)\n }\n }\n\n return (\n // Intentionally not using <button> and rebuilding the semantics\n <span\n ref={mergeRefs([controlRef, ref])}\n className={clsx(s.SelectControl, className)}\n // Recreate <button> semantics\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onPointerEnter={(evt: React.PointerEvent<HTMLAnchorElement>) => {\n handlePressableMouseEnter(evt)\n onPointerEnter?.(evt)\n }}\n onPointerDown={isInteractive ? handlePointerDown : undefined}\n onKeyDown={isInteractive ? handleKeyDown : undefined}\n data-variant={variant}\n data-block={block ? \"\" : undefined}\n data-pill={pill ? \"\" : undefined}\n data-size={size}\n data-optically-align={opticallyAlign}\n aria-busy={loading ? \"true\" : undefined}\n data-selected={selected}\n data-loading={loading ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n data-disabled={disabled ? \"\" : undefined}\n aria-disabled={disabled}\n {...restProps}\n // Ignore onClick handler from Radix, because we use onPointerDown to mimic a native select\n onClick={undefined}\n >\n {StartIcon && <StartIcon className={s.StartIcon} />}\n <span className={s.TriggerText}>{children}</span>\n {hasAnyTertiaryIndicator && (\n <div className={s.IndicatorWrapper}>\n {showClearAction && (\n <Button\n aria-label=\"Clear current value\"\n className={s.Clear}\n onPointerDown={(evt: React.PointerEvent<HTMLButtonElement>) => {\n // Prevent pointerDown on trigger from being captured\n evt.stopPropagation()\n }}\n onClick={(evt) => {\n evt.stopPropagation()\n evt.preventDefault()\n onClearClick()\n }}\n color=\"secondary\"\n variant={hasDropdownIcon ? \"ghost\" : \"solid\"}\n // Mostly custom sizing through variables\n size=\"3xs\"\n uniform\n pill={pill}\n data-only-child={!hasDropdownIcon ? \"\" : undefined}\n >\n <X />\n </Button>\n )}\n {loading && <LoadingIndicator className={s.LoadingIndicator} />}\n {/* Using raw SVG canvases (opposed to fixed icon canvases) led to less pixelation. */}\n {hasDropdownIcon && <DropdownIcon iconType={dropdownIconType} />}\n </div>\n )}\n </span>\n )\n}\n\ntype DropdownIconProps = {\n iconType: Omit<DropdownIconType, \"none\">\n}\n\nexport const DropdownIcon = ({ iconType }: DropdownIconProps) => {\n return iconType === \"chevronDown\" ? (\n <ChevronDownVector className={clsx(s.DropdownIcon, s.DropdownIconChevron)} />\n ) : (\n <DropdownVector className={s.DropdownIcon} />\n )\n}\n", "\"use client\"\n\nimport { Tooltip as RadixTooltip } from \"radix-ui\"\nimport { useRef, useState } from \"react\"\nimport { copyText } from \"../../lib/copyToClipboard\"\nimport { Check, Copy } from \"../Icon\"\nimport { Tooltip } from \"./Tooltip\"\n\nexport type CopyTooltipProps = {\n children: React.ReactNode\n /** Value to copy to the clipboard */\n copyValue: string\n /**\n * Delay of when the tooltip is shown from first interaction, in milliseconds.\n * @default 150\n */\n openDelay?: number\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: RadixTooltip.TooltipContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: RadixTooltip.TooltipContentProps[\"alignOffset\"]\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default top\n */\n side?: RadixTooltip.TooltipContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 5\n */\n sideOffset?: RadixTooltip.TooltipContentProps[\"sideOffset\"]\n}\n\nexport const CopyTooltip = ({\n children,\n copyValue,\n openDelay = 150,\n align = \"center\",\n alignOffset = 0,\n side = \"top\",\n sideOffset = 5,\n}: CopyTooltipProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const [copied, setCopied] = useState<boolean>(false)\n const copiedTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined)\n\n const copy = () => {\n setCopied(true)\n\n // Not currently revealing the slight async nature of this operation,\n // nor indicating the failure state.\n copyText(copyValue)\n\n // Persist the copied state for a second, then close\n copiedTimerRef.current = setTimeout(() => {\n setOpen(false)\n }, 1000)\n }\n\n const handleOpenChange = (nextState: boolean) => {\n // When opening, ensure timer and copied state are cleared\n if (nextState) {\n clearTimeout(copiedTimerRef.current)\n setCopied(false)\n }\n\n setOpen(nextState)\n }\n\n return (\n <Tooltip.Root\n open={open}\n onOpenChange={handleOpenChange}\n delayDuration={openDelay}\n disableHoverableContent={false}\n >\n <Tooltip.Trigger\n onPointerDown={(evt) => {\n // Prevent tooltip listeners from closing\n evt.preventDefault()\n evt.stopPropagation()\n\n // Copy the value\n copy()\n }}\n // Prevent default behavior of closing on click from this handler\n onClick={(evt) => {\n evt.preventDefault()\n evt.stopPropagation()\n }}\n >\n {children}\n </Tooltip.Trigger>\n <Tooltip.Content\n compact\n clickable={!copied}\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n collisionPadding={15}\n onEscapeKeyDown={() => setOpen(false)}\n onPointerDown={copy}\n >\n {copied ? (\n // The <Check /> SVG canvas whitespace is larger than copy, so we use a smaller flexbox gap\n <div className=\"flex items-center gap-0.5\">\n <Check /> Copied!\n </div>\n ) : (\n <div className=\"flex items-center gap-1\">\n <Copy /> Copy\n </div>\n )}\n </Tooltip.Content>\n </Tooltip.Root>\n )\n}\n", "\"use client\"\n\nimport clsx from \"clsx\"\nimport { Tooltip as RadixTooltip, Slot } from \"radix-ui\"\nimport { useState, type MouseEventHandler, type PointerEventHandler } from \"react\"\nimport { useTimeout } from \"usehooks-ts\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { preventDefaultHandler } from \"../../lib/helpers\"\nimport s from \"./Tooltip.module.css\"\n\nexport type TooltipProps = {\n children: React.ReactNode\n /**\n * The content of the tooltip. If `null`, the tooltip will not render.\n */\n content: React.ReactNode\n /**\n * Defines the `max-width` of the tooltip content. `\"none\"` creates a single-line, naturally sized tooltip.\n * @default 300\n */\n maxWidth?: number | \"none\"\n /**\n * Forces the tooltip to remain open or closed\n */\n forceOpen?: boolean\n /**\n * Delay of when the tooltip is shown from first interaction, in milliseconds.\n * @default 150\n */\n openDelay?: number\n /** Indicates that the tooltip has interactive content, and should remain open when hovered. */\n interactive?: boolean\n /**\n * Short, 1-3 word tooltips, stylized inversely from normal tooltips\n */\n compact?: boolean\n /**\n * Prevents the tooltip from closing when the trigger is clicked right after opening\n * @default false\n */\n preventUnintentionalClickToClose?: true\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: RadixTooltip.TooltipContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: RadixTooltip.TooltipContentProps[\"alignOffset\"]\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default top\n */\n side?: RadixTooltip.TooltipContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 5\n */\n sideOffset?: RadixTooltip.TooltipContentProps[\"sideOffset\"]\n /**\n * Gutter sizing inside the tooltip content\n * @default md\n */\n gutterSize?: \"sm\" | \"md\" | \"lg\"\n /** Ref for the tooltip */\n ref?: React.Ref<HTMLDivElement | null>\n onPointerDown?: PointerEventHandler\n onClick?: MouseEventHandler\n /** Optional class name to apply to the tooltip content */\n contentClassName?: string\n}\n\nexport const Tooltip = (props: TooltipProps) => {\n const {\n ref: forwardedRef,\n children,\n content,\n forceOpen = content === null ? false : undefined,\n maxWidth = 300,\n openDelay = 150,\n interactive = false,\n compact = false,\n preventUnintentionalClickToClose,\n align,\n alignOffset = 0,\n side,\n sideOffset = 5,\n gutterSize = \"md\",\n contentClassName,\n onPointerDown,\n onClick,\n ...restProps\n } = props\n const [visible, setVisible] = useState<boolean>(false)\n const [temporarilyPreventClickToClose, setTemporarilyPreventClickToClose] =\n useState<boolean>(false)\n useTimeout(\n () => setTemporarilyPreventClickToClose(false),\n temporarilyPreventClickToClose ? 400 : null,\n )\n const open = forceOpen ?? visible\n\n const handleOpenChange = (nextState: boolean) => {\n // When forceOpen is passed, don't manage internal state\n if (typeof forceOpen === \"boolean\") return\n\n setVisible(nextState)\n\n if (preventUnintentionalClickToClose) {\n setTemporarilyPreventClickToClose(nextState)\n }\n }\n\n const maybePreventClickClose = (evt: React.MouseEvent) => {\n if (preventUnintentionalClickToClose && temporarilyPreventClickToClose) {\n // Prevents tooltip listeners from closing\n evt.preventDefault()\n evt.stopPropagation()\n }\n }\n\n return (\n <Root\n open={open}\n delayDuration={openDelay}\n onOpenChange={handleOpenChange}\n disableHoverableContent={!interactive}\n >\n <RadixTooltip.Trigger asChild>\n <Slot.Root\n {...restProps}\n ref={forwardedRef}\n onPointerDown={(evt) => {\n maybePreventClickClose(evt)\n onPointerDown?.(evt)\n }}\n onClick={(evt) => {\n maybePreventClickClose(evt)\n onClick?.(evt)\n }}\n >\n {children}\n </Slot.Root>\n </RadixTooltip.Trigger>\n <Content\n maxWidth={maxWidth}\n compact={compact}\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n gutterSize={gutterSize}\n className={contentClassName}\n >\n {content}\n </Content>\n </Root>\n )\n}\n\nconst Root = ({\n children,\n open,\n onOpenChange,\n ...restProps\n}: RadixTooltip.TooltipProps & {\n open: boolean\n onOpenChange: (nextState: boolean) => void\n}) => {\n useEscCloseStack(open, () => {\n onOpenChange(false)\n })\n\n return (\n <RadixTooltip.Provider>\n <RadixTooltip.Root open={open} onOpenChange={onOpenChange} {...restProps}>\n {children}\n </RadixTooltip.Root>\n </RadixTooltip.Provider>\n )\n}\n\ntype TooltipContentProps = RadixTooltip.TooltipContentProps & {\n children: React.ReactNode\n /**\n * Defines the `max-width` of the tooltip content. `\"none\"` creates a single-line, naturally sized tooltip.\n * @default 300\n */\n maxWidth?: number | \"none\"\n /**\n * Short, 1-3 word tooltips, stylized inversely from normal tooltips\n */\n compact?: boolean\n /**\n * Gutter sizing inside the tooltip content\n * @default md\n */\n gutterSize?: \"sm\" | \"md\" | \"lg\"\n /** Determines if the tooltip content should respond to click events */\n clickable?: boolean\n}\n\nexport const Content = ({\n children,\n maxWidth = 300,\n compact = false,\n clickable = undefined,\n alignOffset = 0,\n sideOffset = 5,\n gutterSize = \"md\",\n className,\n style,\n ...restProps\n}: TooltipContentProps) => {\n return (\n <RadixTooltip.Portal>\n <RadixTooltip.Content\n {...restProps}\n className={clsx(s.Tooltip, className)}\n data-compact={compact}\n data-clickable={clickable}\n data-gutter-size={gutterSize}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n collisionPadding={15}\n hideWhenDetached\n style={{\n ...style,\n maxWidth,\n }}\n onEscapeKeyDown={preventDefaultHandler}\n >\n {children}\n </RadixTooltip.Content>\n </RadixTooltip.Portal>\n )\n}\n\ntype TooltipTriggerProps = RadixTooltip.TooltipTriggerProps & {\n /**\n * Determines if `tabindex=0` is applied to the trigger\n * @default true\n */\n focusable?: boolean\n /**\n * Optional class name to apply to the trigger\n */\n className?: string\n /** Ref for the trigger */\n ref?: React.Ref<HTMLSpanElement | null>\n}\n\nexport const Trigger = ({\n children,\n asChild = true,\n ...restProps\n}: RadixTooltip.TooltipTriggerProps) => {\n return (\n <RadixTooltip.Trigger asChild={asChild} {...restProps}>\n {children}\n </RadixTooltip.Trigger>\n )\n}\n\n// Optional wrapper for tooltip trigger, if the visual content isn't already accessible or with built-in visual indications\nexport const TriggerDecorator = (props: TooltipTriggerProps) => {\n const { children, className, focusable = true, ref, ...restProps } = props\n const isPlainText = typeof children === \"string\"\n\n return (\n <Slot.Root\n ref={ref}\n {...restProps}\n className={clsx(s.TriggerDecorator, className)}\n tabIndex={focusable ? 0 : undefined}\n >\n {isPlainText ? <span>{children}</span> : children}\n </Slot.Root>\n )\n}\n\n// Building advanced tooltip behaviors can be achieved by using the\n// composed components, and wiring up bespoke behaviors.\nTooltip.Root = Root\nTooltip.Content = Content\nTooltip.Trigger = Trigger\n// Basic <Tooltip> usage can be done with the component directly,\n// without requiring controlled component composition.\n// <TriggerDecorator> is a helper component that creates an accessible trigger with a visual effect\nTooltip.TriggerDecorator = TriggerDecorator\n"],
5
- "mappings": "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",
6
- "names": ["import_react", "import_react", "import_react", "handleKeyDown", "_jsxs", "_jsx", "import_react", "import_react", "s", "_jsxs", "_jsx", "dist_exports", "s", "_jsx", "_Fragment", "o", "handleKeyDown", "_jsxs", "dist_exports"]
3
+ "sources": ["../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Select/Select.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/hooks/useEscCloseStack.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/hooks/useLatestValue.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Icon/svg/Check.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Icon/svg/ChevronDownVector.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Icon/svg/DropdownVector.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Icon/svg/Info.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Icon/svg/Search.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Icon/svg/X.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/SelectControl/SelectControl.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Button/Button.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/lib/renderHelpers.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/AppsSDKUIProvider/internal.ts", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/AppsSDKUIProvider/AppsSDKUIContext.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Indicator/CircularProgress.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/hooks/useSimulatedProgress.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Indicator/LoadingDots.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Indicator/LoadingIndicator.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Transition/TransitionGroup.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Transition/getDisableAnimations.ts", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Transition/shared.ts", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Transition/transitionReducer.ts", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Button/CopyButton.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Transition/Animate.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Transition/AnimateLayout.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Transition/AnimateLayoutGroup.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Transition/SlotTransitionGroup.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Tooltip/CopyTooltip.tsx", "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.8__@types+react@19._10810175a7ab45acace17e46639bb69b/node_modules/@openai/apps-sdk-ui/src/components/Tooltip/Tooltip.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport clsx from \"clsx\"\nimport { Popover } from \"radix-ui\"\nimport React, {\n createContext,\n type ReactNode,\n use,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { preventDefaultHandler, toCssVariables, waitForAnimationFrame } from \"../../lib/helpers\"\nimport { Check, Info, Search } from \"../Icon\"\nimport { Input } from \"../Input\"\nimport { SelectControl, type SelectControlProps } from \"../SelectControl\"\nimport { Tooltip } from \"../Tooltip\"\nimport { TransitionGroup } from \"../Transition\"\nimport s from \"./Select.module.css\"\n\nexport type Option<T extends string = string> = {\n value: T\n label: string\n /** Disable the option */\n disabled?: boolean\n /** Displayed as secondary text below the option `label` */\n description?: React.ReactNode\n tooltip?: {\n content: React.ReactNode\n maxWidth?: number\n }\n}\n\nexport type OptionGroup<T extends Option> = {\n label: string\n options: T[]\n optionsLimit?: {\n label: string\n limit: number\n }\n}\n\nexport type Options<T extends Option> = T[] | OptionGroup<T>[]\n\ntype CallbackWithOption<T extends Option> = (option: T) => void\ntype CallbackWithOptions<T extends Option> = (options: T[]) => void\ntype CallbackWithActionId = (actionId: string) => void\ntype SearchPredicate<T extends Option> = (option: T, searchTerm: string) => boolean\n\ntype Action = {\n /** Unique ID to identify the action with */\n id: string\n /** Label display for the action */\n label: string\n /** Icon displayed to the left of the action */\n Icon?: React.ComponentType<React.SVGProps<SVGSVGElement>>\n /** Custom class applied to the action container */\n className?: string\n /** Callback invoked when the action is pressed */\n onSelect: CallbackWithActionId\n}\n\ntype Actions = Action[]\n\nexport type PopoverSide = \"top\" | \"bottom\"\nexport type PopoverAlign = \"start\" | \"center\" | \"end\"\n\ntype SingleSelectProps<T extends Option> = {\n /**\n * Determines if the select should support multiple selection\n * @default false\n */\n multiple?: false\n value: string\n onChange: CallbackWithOption<T>\n /**\n * Customize the rendered output of the trigger\n * NOTE: Must be passed as a stable reference, not created inline.\n */\n TriggerView?: React.FC<T>\n}\n\ntype MultiSelectTriggerViewProps<T extends Option> = {\n values: T[]\n selectedAll: boolean\n}\n\ntype MultiSelectProps<T extends Option> = {\n /**\n * Determines if the select should support multiple selection\n * @default false\n */\n multiple: true\n value: string[]\n onChange: CallbackWithOptions<T>\n /**\n * Customize the rendered output of the trigger\n * NOTE: Must be passed as a stable reference, not created line.\n */\n TriggerView?: React.FC<MultiSelectTriggerViewProps<T>>\n}\n\nexport type SelectProps<T extends Option> = (SingleSelectProps<T> | MultiSelectProps<T>) & {\n options: Options<T> // Should be passed as a stable reference\n /**\n * Disables the select visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Allows the select to be targeted with htmlFor\n */\n id?: string\n /**\n * Marks the select as a required field when using native form submission\n */\n required?: boolean\n /**\n * Creates the ability to query the value with `[name=\"${name}\"]`\n */\n name?: string\n /**\n * Placeholder text for the select\n * @default Select...\n */\n placeholder?: string\n /**\n * Placeholder text for the select while loading. Behaves exactly like `placeholder`, and `value` will be shown if provided.\n * @default Loading...\n */\n loadingPlaceholder?: string\n /**\n * Displays loading indicator on top of button contents\n * @default false\n */\n loading?: boolean\n /**\n * Style variant for the select trigger\n * @default outline\n */\n variant?: SelectControlProps[\"variant\"]\n /**\n * Determines if the select trigger should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Controls size of the select trigger, and several other aspects of trigger styling.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: SelectControlProps[\"size\"]\n /**\n * Icon displayed in the far right of the select trigger\n * @default dropdown\n */\n dropdownIconType?: SelectControlProps[\"dropdownIconType\"]\n /**\n * Actions to display below the options list.\n */\n actions?: Actions // Memoized by length, don't assume dynamic changes are supported\n /** Custom class applied to option containers */\n optionClassName?: string\n /**\n * Customize the rendered output of individual options\n * NOTE: Must be passed as a stable reference, not created line.\n */\n OptionView?: React.FC<T>\n /** Icon displayed at the start of the select trigger */\n TriggerStartIcon?: SelectControlProps[\"StartIcon\"]\n /**\n * Custom class applied to the select trigger\n */\n triggerClassName?: string // If consumers need deep customization of the trigger\n /**\n * Applies a negative margin using the current gutter to optically align the trigger\n * with surrounding content.\n */\n opticallyAlign?: \"start\" | \"end\"\n /**\n * Display a clear action that allows the select to be unset.\n * @default false\n */\n clearable?: boolean\n /**\n * Extends select to 100% of available width.\n * @default true\n */\n block?: boolean\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default bottom\n */\n side?: PopoverSide\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: PopoverAlign\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: number\n /**\n * Prevents collision detection in the custom menu. Use with caution.\n * @default true\n */\n avoidCollisions?: boolean\n /**\n * Set the width of the custom select menu\n * @default auto\n */\n listWidth?: number | \"auto\"\n /**\n * Defines the `min-width` property of the custom select menu, in pixels.\n * @default auto\n */\n listMinWidth?: number | \"auto\"\n /**\n * Defines the `max-width` property of the custom select menu, in pixels.\n * @default auto\n */\n listMaxWidth?: number | \"auto\"\n /** Predicate used to filter searches */\n searchPredicate?: SearchPredicate<T>\n /** Placeholder of the search input */\n searchPlaceholder?: string\n /**\n * Message displayed when search results are empty. Can be a simple string, or custom JSX.\n */\n searchEmptyMessage?: ReactNode\n}\n\ntype SingleSelectContextValue<T extends Option> = {\n multiple: false\n value: string\n TriggerView: React.FC<T>\n}\n\ntype MultiSelectContextValue<T extends Option> = {\n multiple: true\n value: string[]\n TriggerView: React.FC<MultiSelectTriggerViewProps<T>>\n}\n\ntype SelectContextValue<T extends Option> = (\n | SingleSelectContextValue<T>\n | MultiSelectContextValue<T>\n) & {\n triggerId: string\n // Props\n name?: string\n id?: string\n required?: boolean\n options: Options<T>\n disabled: boolean\n variant: SelectControlProps[\"variant\"]\n pill: boolean\n size: SelectControlProps[\"size\"]\n dropdownIconType: SelectControlProps[\"dropdownIconType\"]\n loading: boolean\n clearable: boolean\n placeholder: string\n loadingPlaceholder: string\n searchEmptyMessage: ReactNode\n searchPlaceholder: string\n TriggerStartIcon?: SelectControlProps[\"StartIcon\"]\n triggerClassName?: string\n opticallyAlign?: \"start\" | \"end\"\n optionClassName?: string\n OptionView: React.FC<T>\n actions: Actions\n onActionSelect: CallbackWithActionId\n block: boolean\n side: PopoverSide\n align: PopoverAlign\n alignOffset: number\n avoidCollisions: boolean\n listWidth?: number | \"auto\" // Default when not passed is to match the width of the trigger\n listMinWidth: number | \"auto\"\n listMaxWidth?: number | \"auto\"\n // References\n onSelectRef: React.MutableRefObject<(option: T, removeOption?: boolean) => void>\n searchPredicateRef: React.MutableRefObject<SearchPredicate<T>>\n // Derived\n searchable: boolean\n}\n\nconst SelectContext = createContext<SelectContextValue<Option> | null>(null)\n\nconst useSelectContext = () => {\n const context = use(SelectContext)\n\n if (!context) {\n throw new Error(\"Select components must be wrapped in <Select />\")\n }\n\n return context\n}\n\nconst DefaultOptionView = ({ label }: { label: string }) => <>{label}</>\nconst DefaultSingleTriggerView = ({ label }: { label: string }) => <>{label}</>\nconst DefaultMultiTriggerView = <T extends Option>({\n values,\n selectedAll,\n}: MultiSelectTriggerViewProps<T>) => {\n const displayValue = selectedAll\n ? \"All selected\"\n : values.length === 0\n ? // NOTE: Zero length is impossible - an empty option with `placeholder` is always returned\n \"Select...\"\n : values.length === 1\n ? values[0].label\n : `${values.length} selected`\n\n return <>{displayValue}</>\n}\n\nexport const Select = <T extends Option>(props: SelectProps<T>) => {\n const {\n id,\n required,\n value,\n name,\n multiple,\n variant = \"outline\",\n size = \"md\",\n dropdownIconType = \"dropdown\",\n loading = false,\n clearable = false,\n disabled = false,\n placeholder = \"Select...\",\n loadingPlaceholder = \"Loading...\",\n pill = true,\n listWidth,\n options,\n actions: propActions = [],\n side = \"bottom\",\n avoidCollisions = true,\n onChange,\n optionClassName,\n OptionView = DefaultOptionView,\n TriggerStartIcon,\n triggerClassName,\n opticallyAlign,\n TriggerView: TriggerViewFromProps,\n searchPlaceholder = \"\",\n searchPredicate = defaultSearchPredicate,\n searchEmptyMessage = \"No results found.\",\n listMaxWidth = \"auto\",\n } = props\n // Block default is dynamic, based on `variant`\n const block = props.block ?? variant !== \"ghost\"\n // Align default is dynamic, based on `block`\n const align = props.align ?? (block ? \"center\" : \"start\")\n const alignOffset = props.alignOffset ?? (align === \"center\" ? 0 : -5)\n // Default to \"auto\" for block selects and 300 for inline selects.\n const listMinWidth = props.listMinWidth ?? (block ? \"auto\" : 300)\n\n // Create stable, mutable references to avoid memoization requirements from consumers\n const onSelectRef = useLatestValue((selectedOption: T, removeOption?: boolean) => {\n if (multiple) {\n // When clearing values, the value is an\n if (!selectedOption.value) {\n onChange([])\n return\n }\n\n if (removeOption) {\n const nextValues = value.filter((v) => v !== selectedOption.value)\n const currentSelectedOptions = getOptionsByValues(options, nextValues)\n onChange(currentSelectedOptions)\n } else {\n const currentSelectedOptions = getOptionsByValues(options, value)\n onChange(currentSelectedOptions.concat(selectedOption))\n }\n } else {\n onChange(selectedOption)\n }\n })\n\n const searchPredicateRef = useRef<SearchPredicate<T>>(searchPredicate)\n searchPredicateRef.current = searchPredicate\n\n // It should be exceedingly uncommon to change actions dynamically, and they are unlikely to be a stable array reference from consumers\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Intentionally limiting when this stable value changes to length of actions\n const actions = useMemo<Actions>(() => propActions, [propActions.length])\n // We need to ensure that when action callbacks are called, we have fresh function references, even if the other action details did not change.\n const propActionsRef = useRef<Actions>(propActions)\n propActionsRef.current = propActions\n const onActionSelect = useCallback<CallbackWithActionId>((actionId: string) => {\n propActionsRef.current.find((a) => a.id === actionId)?.onSelect(actionId)\n }, [])\n\n // Determine when custom selects should be used\n const optionsCount = useMemo(\n () =>\n isOptionGroupArray(options)\n ? options.reduce((acc: number, group) => {\n return acc + group.options.length\n }, 0)\n : options.length,\n [options],\n )\n\n // Using ID for DOM selection instead of passing around and merging a ref. Pick your poison.\n const internalTriggerId = useId()\n const triggerId = `select-trigger-${internalTriggerId}`\n\n // Locking down searchable count to a single value. Could make this customizable in the future, but would want guardrails.\n const searchable = optionsCount > 15\n\n // Narrow known values for context\n const dynamicContextProps = useMemo<\n SingleSelectContextValue<T> | MultiSelectContextValue<T>\n >(() => {\n if (multiple) {\n return {\n multiple: true,\n value: value as string[],\n TriggerView: TriggerViewFromProps ?? DefaultMultiTriggerView,\n }\n }\n\n return {\n multiple: false,\n value: value as string,\n TriggerView: TriggerViewFromProps ?? DefaultSingleTriggerView,\n }\n }, [multiple, value, TriggerViewFromProps])\n\n const store = useMemo<SelectContextValue<T>>(\n () => ({\n ...dynamicContextProps,\n triggerId,\n id,\n // Forward props\n name,\n required,\n options,\n placeholder,\n loadingPlaceholder,\n loading,\n clearable,\n variant,\n pill,\n size,\n dropdownIconType,\n block,\n align,\n alignOffset,\n side,\n avoidCollisions,\n listWidth,\n listMinWidth,\n listMaxWidth,\n searchPlaceholder,\n searchEmptyMessage,\n TriggerStartIcon,\n triggerClassName,\n opticallyAlign,\n optionClassName,\n OptionView,\n actions,\n onActionSelect,\n onSelectRef,\n searchPredicateRef,\n // Derived state\n searchable,\n disabled,\n }),\n [\n dynamicContextProps,\n triggerId,\n id,\n required,\n name,\n options,\n placeholder,\n loadingPlaceholder,\n loading,\n clearable,\n variant,\n pill,\n size,\n dropdownIconType,\n block,\n align,\n alignOffset,\n side,\n avoidCollisions,\n listWidth,\n listMinWidth,\n listMaxWidth,\n searchPlaceholder,\n searchEmptyMessage,\n TriggerStartIcon,\n triggerClassName,\n opticallyAlign,\n optionClassName,\n OptionView,\n actions,\n onActionSelect,\n onSelectRef,\n searchable,\n disabled,\n ],\n )\n\n return (\n // NOTE: Cannot peacefully coerce SelectContextValue into a generic, so casting to any here.\n // This is safe because `store` is strongly typed above.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n <SelectContext.Provider value={store as any}>\n <CustomSelect />\n </SelectContext.Provider>\n )\n}\n\n// ============================================================\n// Trigger\n// ============================================================\ntype SelectTriggerProps = {\n onOpenChange?: (maybeNextState?: boolean) => void\n tabIndex?: number\n [\"aria-hidden\"]?: \"false\" | \"true\"\n ref?: React.Ref<HTMLButtonElement | null>\n}\n\nexport const SelectTrigger = (props: SelectTriggerProps) => {\n const {\n triggerId,\n id,\n required,\n value,\n multiple,\n options,\n loading,\n disabled,\n clearable,\n name,\n variant,\n pill,\n size,\n dropdownIconType,\n placeholder,\n loadingPlaceholder,\n block,\n opticallyAlign,\n triggerClassName,\n TriggerStartIcon,\n TriggerView,\n onSelectRef,\n } = useSelectContext()\n const {\n onOpenChange,\n // pass along props from Radix\n ...restProps\n } = props\n const firstValue = multiple ? value[0] : value\n const placeholderValue = loading ? loadingPlaceholder : placeholder\n\n const selectedItem = useMemo<Option>(\n () =>\n getOptionByValue(options, firstValue) || {\n value: \"\",\n label: placeholderValue,\n },\n [firstValue, options, placeholderValue],\n )\n const hasSelectedValue = multiple ? value.length > 0 : !!value\n const isPlaceholder = loading || !hasSelectedValue\n\n const typeahead = useMemo(() => createTypeahead(), [])\n\n const multipleTriggerViewProps = useMemo<MultiSelectTriggerViewProps<Option>>(() => {\n if (!multiple) {\n return { values: [], selectedAll: false }\n }\n\n const currentSelectedOptions = getOptionsByValues(options, value)\n const flatOptions = options.flatMap((o) => (\"options\" in o ? o.options : o))\n\n return {\n values: currentSelectedOptions.length\n ? currentSelectedOptions\n : [\n {\n value: \"\",\n label: placeholderValue,\n },\n ],\n selectedAll: flatOptions.length <= value.length,\n }\n }, [multiple, options, value, placeholderValue])\n\n const handleKeyDown = (evt: React.KeyboardEvent<HTMLButtonElement>) => {\n const key = evt.key\n\n // If not a command, check for typeahead\n // NOTE: Typeahead not supported in multi-select\n if (!multiple && isValidTypeaheadChar(key)) {\n const currentTypeaheadValue = typeahead(key)\n // Stop other listeners from reacting\n evt.stopPropagation()\n\n // Attempt to filter options based on the value\n // NOTE: We don't look at current highlighted value as a means to start the search\n const firstMatchingOption = getTypeaheadOption(options, currentTypeaheadValue, firstValue)\n\n if (firstMatchingOption) {\n onSelectRef.current(firstMatchingOption)\n }\n }\n }\n\n const handleClearClick = () => {\n onSelectRef.current({ value: \"\", label: \"\" })\n // Ensure open state is closed\n onOpenChange?.(false)\n }\n\n return (\n <SelectControl\n id={triggerId}\n className={triggerClassName}\n selected={!isPlaceholder}\n variant={variant}\n pill={pill}\n block={block}\n size={size}\n disabled={disabled}\n loading={loading}\n StartIcon={TriggerStartIcon}\n opticallyAlign={opticallyAlign}\n dropdownIconType={dropdownIconType}\n onClearClick={clearable ? handleClearClick : undefined}\n onInteract={onOpenChange}\n onKeyDown={handleKeyDown}\n {...restProps}\n >\n {multiple ? <TriggerView {...multipleTriggerViewProps} /> : <TriggerView {...selectedItem} />}\n {(name || id) && (\n <input\n id={id}\n name={name}\n value={firstValue}\n tabIndex={-1}\n onFocus={() => {\n document.getElementById(triggerId)?.focus()\n }}\n // keep react from complaining - don't make this readOnly because that\n // prevents the value from being required\n onChange={() => {}}\n required={required}\n className=\"sr-only w-full h-0 left-0 bottom-0 pointer-events-none\"\n aria-hidden=\"true\"\n />\n )}\n </SelectControl>\n )\n}\n\n// ============================================================\n// Custom Select\n// ============================================================\nconst CustomSelect = () => {\n const {\n triggerId,\n loading,\n side,\n align,\n alignOffset,\n avoidCollisions,\n listWidth,\n listMinWidth,\n listMaxWidth,\n } = useSelectContext()\n const [open, setOpen] = useState<boolean>(false)\n const selectContentRef = useRef<HTMLDivElement>(null)\n\n const handleOpenChange = (maybeNextState?: boolean) => {\n // Toggle the current state when called without a specific state\n const nextState = maybeNextState === undefined ? !open : maybeNextState\n setOpen(nextState)\n\n // When we're closing, manage focus back to trigger manually\n if (!nextState) {\n // Wait until the next tick to determine if another element has become focused\n setTimeout(() => {\n // This should never happen because TransitionGroup should keep the select content in the DOM long\n // enough for this callback to run. However, in the event that the ref is null, not focusing is safer.\n if (!selectContentRef.current) {\n return\n }\n\n const activeElement = document.activeElement\n\n // Don't restore focus to the trigger if focus has moved outside of the select menu\n if (activeElement && !selectContentRef.current.contains(activeElement)) {\n return\n }\n\n document.getElementById(triggerId)?.focus()\n })\n }\n }\n\n useEscCloseStack(open, () => {\n handleOpenChange(false)\n })\n\n return (\n <Popover.Root\n open={open}\n onOpenChange={(nextState) => {\n // Prevent opening while loading\n if (loading && nextState) {\n return\n }\n\n handleOpenChange(nextState)\n }}\n modal={false}\n >\n <Popover.Trigger asChild>\n <SelectTrigger onOpenChange={handleOpenChange} />\n </Popover.Trigger>\n <Popover.Portal forceMount>\n <TransitionGroup\n className={s.Menu}\n enterDuration={350}\n exitDuration={200}\n disableAnimations\n >\n {open && (\n <Popover.Content\n key=\"dropdown\"\n ref={selectContentRef}\n forceMount\n className={s.MenuList}\n side={side}\n sideOffset={5}\n align={align}\n alignOffset={alignOffset}\n avoidCollisions={avoidCollisions}\n collisionPadding={{ bottom: 30, top: 30 }}\n // Prevent Radix auto focus so we can handle our own from within <CustomSelectMenu />\n onOpenAutoFocus={preventDefaultHandler}\n // Radix waits until the animation completes before directing focus, which is janky.\n onCloseAutoFocus={preventDefaultHandler}\n onEscapeKeyDown={preventDefaultHandler}\n style={toCssVariables({\n \"select-list-width\": listWidth,\n \"select-list-min-width\": listMinWidth,\n \"select-list-max-width\": listMaxWidth,\n })}\n >\n <CustomSelectMenu onOpenChange={handleOpenChange} />\n </Popover.Content>\n )}\n </TransitionGroup>\n </Popover.Portal>\n </Popover.Root>\n )\n}\n\ntype CustomSelectMenuContextValue = {\n valueRef: React.RefObject<string | null>\n listId: string\n requestCloseRef: React.RefObject<() => void | null>\n listRef: React.RefObject<HTMLDivElement | null>\n // Highlighting\n highlightedValue: string\n setHighlightedValue: React.Dispatch<React.SetStateAction<string>>\n // Search\n searchTerm: string\n setSearchTerm: React.Dispatch<React.SetStateAction<string>>\n searchInputRef: React.RefObject<HTMLInputElement | null>\n}\n\nconst CustomSelectMenuContext = createContext<CustomSelectMenuContextValue | null>(null)\n\nconst useCustomSelectMenuContext = () => {\n const context = use(CustomSelectMenuContext)\n\n if (!context) {\n throw new Error(\"CustomSelectMenu components must be wrapped in <CustomSelectMenu />\")\n }\n\n return context\n}\n\ntype CustomSelectMenuProps = {\n onOpenChange: (maybeNextState?: boolean) => void\n}\n\nconst CustomSelectMenu = ({ onOpenChange }: CustomSelectMenuProps) => {\n const { multiple, value, options, searchable, searchPredicateRef } = useSelectContext()\n const requestCloseRef = useRef<() => void>(() => onOpenChange(false))\n const menuRef = useRef<HTMLDivElement>(null)\n const listRef = useRef<HTMLDivElement>(null)\n const searchInputRef = useRef<HTMLInputElement>(null)\n const [searchTerm, setSearchTerm] = useState(\"\")\n const [highlightedValue, setHighlightedValue] = useState<string>(() => {\n const selectedValue = multiple ? value[0] : value\n return (selectedValue || getFirstValidOption(options)?.value) ?? \"\"\n })\n const typeahead = useMemo(() => createTypeahead(), [])\n const internalListId = useId()\n const listId = `select-list-${internalListId}`\n\n // Lock `value` for a given open to prevent janky change during close animation\n // NOTE: This ref has no use in MultiSelect cases, set to empty string as a no-op\n const valueRef = useRef<string>(multiple ? \"\" : value)\n\n // Trim and lowercase search value\n const literalSearchTerm = useMemo(() => searchTerm.trim().toLocaleLowerCase(), [searchTerm])\n const filteredOptions = useMemo(\n () => filterOptions(options, literalSearchTerm, searchPredicateRef.current),\n [options, literalSearchTerm, searchPredicateRef],\n )\n const firstOption = useMemo(() => getFirstValidOption(filteredOptions), [filteredOptions])\n\n // Regrettable requirement for running an effect *after* mount\n const isMountStableRef = useRef<boolean>(false)\n\n const handleKeyDown = (evt: React.KeyboardEvent) => {\n const key = evt.key\n const firstValue = multiple ? value[0] : value\n const targetValue = highlightedValue || firstOption?.value || firstValue\n const isFocusedInSearch = document.activeElement === searchInputRef.current\n\n const menuElement = menuRef.current\n\n // Should be generally impossible for menuRef.current to not exist\n // unless we've unmounted and manage to fire this handler.\n if (!menuElement) {\n return\n }\n\n const triggerHighlightedOption = () => {\n const pointerUpEvent = new PointerEvent(\"pointerup\", {\n bubbles: true,\n cancelable: true,\n pointerType: \"mouse\",\n })\n\n // Find the current highlighted option\n const selectedOption = findOptionByValue(highlightedValue, menuElement)\n selectedOption?.dispatchEvent(pointerUpEvent)\n }\n\n const highlightOption = (val: string, element: Element) => {\n setHighlightedValue(val)\n element.scrollIntoView({ block: \"nearest\" })\n }\n\n const highlightSelectedOrFirstOption = () => {\n // Attempt to move highlight to selected item\n const maybeFirstValue = multiple ? value[0] : value\n\n if (maybeFirstValue) {\n const selectedElement = findOptionByValue(maybeFirstValue, menuElement)\n\n if (selectedElement) {\n highlightOption(maybeFirstValue, selectedElement)\n return\n }\n }\n\n // If value isn't set, or the selected node wasn't found in the DOM,\n // attempt to move focus to the first valid option.\n const firstValidOption = getFirstValidOption(options)\n\n if (firstValidOption) {\n const firstValidOptionElement = findOptionByValue(firstValidOption.value, menuElement)\n if (firstValidOptionElement) {\n highlightOption(firstValidOption.value, firstValidOptionElement)\n }\n }\n }\n\n // Commands\n switch (key) {\n case \"ArrowDown\": {\n evt.preventDefault()\n\n // If there's no highlighted value, or the highlighted value is not in the DOM\n if (!highlightedValue || !findOptionByValue(highlightedValue, menuElement)) {\n // Attempt to move highlight to selected item\n highlightSelectedOrFirstOption()\n\n // Short-circuit because we have no highlighted value to advance from\n return\n }\n\n // Otherwise, move to the next option\n const nextElement = findNextOption(highlightedValue, menuElement)\n const nextValue = nextElement?.getAttribute(\"data-option-id\")\n if (nextElement && nextValue) {\n highlightOption(nextValue, nextElement)\n }\n\n return\n }\n case \"ArrowUp\": {\n evt.preventDefault()\n\n // If there's no highlighted value, or the highlighted value is not in the DOM\n if (!highlightedValue || !findOptionByValue(highlightedValue, menuElement)) {\n // Attempt to move highlight to selected item\n highlightSelectedOrFirstOption()\n\n // Short-circuit because we have no highlighted value to advance from\n return\n }\n\n const previousElement = findPreviousOption(targetValue, menuElement)\n const previousValue = previousElement?.getAttribute(\"data-option-id\")\n if (previousElement && previousValue) {\n highlightOption(previousValue, previousElement)\n }\n\n return\n }\n case \"Enter\":\n // Prevent default enter behavior from the search input, if present\n evt.preventDefault()\n\n // Send a pointerDown event into the currently highlighted option\n triggerHighlightedOption()\n\n return\n case \" \":\n // Allow spaces in search, and don't treat as enter\n // if there is a valid literalSearchTerm.\n if (literalSearchTerm && isFocusedInSearch) {\n return\n }\n\n // Prevent space from entering search input\n evt.preventDefault()\n\n // Send a pointerDown event into the currently highlighted option\n triggerHighlightedOption()\n\n return\n default:\n break\n }\n\n // If not a command, check for typeahead\n if (isValidTypeaheadChar(key)) {\n // Skip typeahead logic when we're focused in the search input\n if (isFocusedInSearch) {\n return\n }\n\n // Extend the current typeahead and get the latest value\n const currentTypeaheadValue = typeahead(key)\n\n // Stop other listeners from reacting\n evt.stopPropagation()\n\n // Attempt to filter options based on the value, starting at the highlighted value\n const firstMatchingOption = getTypeaheadOption(\n options,\n currentTypeaheadValue,\n highlightedValue,\n )\n\n if (firstMatchingOption) {\n const matchedNode = findOptionByValue(firstMatchingOption.value, menuElement)\n\n // Only change the highlight if we found the actual node\n if (matchedNode) {\n setHighlightedValue(firstMatchingOption.value)\n // Ensure the newly highlighted option is scrolled into view\n matchedNode.scrollIntoView({ block: \"nearest\" })\n }\n }\n }\n }\n\n const store = useMemo(\n () => ({\n valueRef,\n listId,\n highlightedValue,\n setHighlightedValue,\n requestCloseRef,\n searchTerm,\n setSearchTerm,\n searchInputRef,\n listRef,\n }),\n [listId, highlightedValue, setHighlightedValue, searchTerm, setSearchTerm],\n )\n\n // On mount behavior\n useEffect(() => {\n // Ensure initial highlighted option is in view\n // NOTE: Allowing for a render frame ensures content is positioned correctly before scrolling it into view.\n waitForAnimationFrame(() => {\n if (!menuRef.current) {\n return\n }\n\n // Ensure the highlighted option is in view\n const currentOption = findOptionByValue(highlightedValue, menuRef.current)\n // Scroll the selected item into view, and its bottom edge.\n currentOption?.scrollIntoView({ block: \"center\" })\n })\n\n // Send initial focus to the menu container or search input, to capture key events\n const autoFocusTarget = searchInputRef.current || menuRef.current\n autoFocusTarget?.focus({ preventScroll: true })\n\n // Required for <StrictMode>, because we need to unset this token\n // when the hooks are re-run. It's an imperative effect that we need to manage.\n return () => {\n isMountStableRef.current = false\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- Intentionally an onMount effect\n }, [])\n\n // On search behavior\n useLayoutEffect(() => {\n // This effect will run on mount, but we want to skip it.\n // The on mount effect is responsible for handling mount behavior,\n // but this effect is specifically responsible for handling search changes\n if (!isMountStableRef.current) {\n isMountStableRef.current = true\n return\n }\n\n // Impossible while mounted, list ref will exist\n if (!listRef.current) {\n return\n }\n\n // Reset scroll position to the top\n listRef.current.scrollTop = 0\n\n // Highlight first item in the list\n const maybeFirstOption = getFirstValidOption(filteredOptions)\n if (maybeFirstOption) setHighlightedValue(maybeFirstOption.value)\n }, [filteredOptions])\n\n return (\n <CustomSelectMenuContext value={store}>\n <div id={listId} className={s.MenuInner} onKeyDown={handleKeyDown} ref={menuRef} tabIndex={0}>\n {searchable && <CustomSelectSearch value={searchTerm} onChange={setSearchTerm} />}\n <CustomSelectList filteredOptions={filteredOptions} />\n <CustomSelectActions />\n </div>\n </CustomSelectMenuContext>\n )\n}\n\ntype CustomSelectSearchProps = {\n value: string\n onChange: (nextSearchTerm: string) => void\n}\n\nconst CustomSelectSearch = ({ value, onChange }: CustomSelectSearchProps) => {\n const { searchPlaceholder } = useSelectContext()\n const { listId, searchInputRef } = useCustomSelectMenuContext()\n\n const handleChange = (evt: React.ChangeEvent<HTMLInputElement>) => {\n onChange(evt.target.value)\n }\n\n return (\n <div className={s.Search}>\n <Input\n startAdornment={<Search width={16} height={16} className=\"fill-secondary\" />}\n ref={searchInputRef}\n value={value}\n placeholder={searchPlaceholder}\n onChange={handleChange}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n aria-autocomplete=\"list\"\n role=\"combobox\"\n aria-controls={listId}\n aria-expanded\n />\n </div>\n )\n}\n\nconst isOptionGroup = <T extends Option>(\n mixedOption: T | OptionGroup<T>,\n): mixedOption is OptionGroup<T> => {\n return \"options\" in mixedOption\n}\n\nconst isOptionGroupArray = <T extends Option>(arr: Options<T>): arr is OptionGroup<T>[] => {\n return arr[0] && isOptionGroup(arr[0])\n}\n\nconst HARD_OPTIONS_LIMIT = 300\n\nconst CustomSelectList = <T extends Option>({\n filteredOptions,\n}: {\n filteredOptions: Options<T>\n}) => {\n const { searchEmptyMessage } = useSelectContext()\n const { listRef } = useCustomSelectMenuContext()\n\n if (!filteredOptions.length) {\n return typeof searchEmptyMessage === \"string\" ? (\n <p className={s.SearchEmpty} data-text-only>\n {searchEmptyMessage}\n </p>\n ) : (\n <div className={s.SearchEmpty}>{searchEmptyMessage}</div>\n )\n }\n\n // We hard limit within groups, so at this level we will only limit flat arrays\n const isGrouped = isOptionGroupArray(filteredOptions)\n const hasHardLimit = !isGrouped && filteredOptions.length > HARD_OPTIONS_LIMIT\n\n const options = isGrouped\n ? filteredOptions.map((group) => <CustomSelectGroup key={group.label} {...group} />)\n : filteredOptions\n .slice(0, HARD_OPTIONS_LIMIT)\n .map((option) => <CustomSelectOption key={option.value} {...option} />)\n\n return (\n <div className={s.OptionsList} ref={listRef}>\n {options}\n {hasHardLimit && (\n <CustomSelectHardLimit numHidden={filteredOptions.length - HARD_OPTIONS_LIMIT} />\n )}\n </div>\n )\n}\n\nconst DEFAULT_OPTIONS_LIMIT = {\n limit: 100,\n label: \"Show all\",\n}\n\nconst CustomSelectGroup = <T extends Option>({\n label,\n options,\n optionsLimit = DEFAULT_OPTIONS_LIMIT,\n}: OptionGroup<T>) => {\n const groupId = useId()\n const { searchTerm, setHighlightedValue } = useCustomSelectMenuContext()\n const [limitExpanded, setLimitExpanded] = useState<boolean>(false)\n\n const hasExpandableLimit = optionsLimit.limit < options.length && !searchTerm && !limitExpanded\n const hasHardLimit = HARD_OPTIONS_LIMIT < options.length && !hasExpandableLimit\n\n let maybeLimitedOptions = options\n if (hasExpandableLimit) {\n maybeLimitedOptions = options.slice(0, optionsLimit.limit)\n } else if (hasHardLimit) {\n maybeLimitedOptions = options.slice(0, HARD_OPTIONS_LIMIT)\n }\n\n const handleLimitExpanded = () => {\n // Expand options\n setLimitExpanded(true)\n\n // Set highlight to the first option from the newly expanded list\n setHighlightedValue(options[optionsLimit.limit].value)\n }\n\n return (\n // NOTE: Important for crawling that groups are flat\n <>\n <div className={s.OptionGroupHeading}>\n <div className={s.OptionIndicatorSlot} />\n {label}\n </div>\n {maybeLimitedOptions.map((limitedOptions) => (\n <CustomSelectOption key={limitedOptions.value} {...limitedOptions} />\n ))}\n {hasExpandableLimit && (\n <CustomSelectExpandableLimit\n value={`group-limit-${groupId}`}\n label={optionsLimit.label}\n onPointerUp={handleLimitExpanded}\n />\n )}\n {hasHardLimit && <CustomSelectHardLimit numHidden={options.length - HARD_OPTIONS_LIMIT} />}\n </>\n )\n}\n\ntype CustomSelectHardLimitProps = {\n numHidden: number\n}\n\nconst CustomSelectHardLimit = ({ numHidden }: CustomSelectHardLimitProps) => {\n return (\n <div className={s.OptionHardLimitHeading}>\n <div className={s.OptionIndicatorSlot} />\n {`…and ${numHidden.toLocaleString()} more options. Use search to refine results further.`}\n </div>\n )\n}\n\ntype CustomSelectExpandableLimitProps = {\n value: string\n label: string\n onPointerUp: () => void\n}\n\nconst CustomSelectExpandableLimit = ({\n value,\n label,\n onPointerUp,\n}: CustomSelectExpandableLimitProps) => {\n const { highlightedValue, setHighlightedValue } = useCustomSelectMenuContext()\n\n const isHighlighted = value === highlightedValue\n\n const handlePointerMove = () => {\n if (isHighlighted) {\n return\n }\n\n setHighlightedValue(value)\n }\n\n const handlePointerLeave = () => {\n setHighlightedValue((currentHighlightedValue) => {\n // If the current value is not this one, don't do anything\n // Otherwise, clear the value, removing the active highlight on the menu.\n return currentHighlightedValue !== value ? currentHighlightedValue : \"\"\n })\n }\n\n // This component acts a LOT like an Option, but has enough bespoke behavior\n // that it cannot literally be one. We copy the important parts of Option for\n // keyboard navigation, UX, etc.\n return (\n <div\n className={clsx(s.Option, s.OptionsLimit)}\n data-option-id={value}\n data-highlight={isHighlighted ? \"\" : undefined}\n role=\"option\"\n aria-selected={isHighlighted}\n onPointerUp={onPointerUp}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n >\n <div className={clsx(s.PressableInner, s.OptionInner)}>\n <div className={s.OptionIndicatorSlot} />\n {label}\n </div>\n </div>\n )\n}\n\nconst INTERNAL_DOM_SELECTION_DATA_ATTR = \"data-option-id\"\n\nconst CustomSelectOption = (option: Option) => {\n const {\n optionClassName,\n OptionView,\n value: propsValue,\n multiple,\n onSelectRef,\n } = useSelectContext()\n const { valueRef, requestCloseRef, highlightedValue, setHighlightedValue } =\n useCustomSelectMenuContext()\n const { value, disabled, tooltip } = option\n\n // NOTE: SingleSelect mode looks at the ref instead of the live `propValue` intentionally\n // to avoid selecting the item as the select closes.\n const currentValue = valueRef.current\n const isSelected = multiple ? propsValue.includes(value) : value === currentValue\n const isHighlighted = value === highlightedValue\n\n const handlePointerUp = () => {\n if (multiple) {\n // Trigger the change ref, optionally as a remove\n onSelectRef.current(option, isSelected)\n } else {\n // Trigger the change ref\n onSelectRef.current(option)\n // Request the dropdown to close\n requestCloseRef.current?.()\n }\n }\n\n const handlePointerMove = () => {\n if (isHighlighted) {\n return\n }\n\n setHighlightedValue(value)\n }\n\n const handlePointerLeave = () => {\n setHighlightedValue((currentHighlightedValue) => {\n // If the current value is not this one, don't do anything\n // Otherwise, clear the value, removing the active highlight on the menu.\n return currentHighlightedValue !== value ? currentHighlightedValue : \"\"\n })\n }\n\n return (\n <div\n className={clsx(s.Option, optionClassName)}\n data-highlight={isHighlighted ? \"\" : undefined}\n role=\"option\"\n aria-selected={isHighlighted}\n data-selected={isSelected ? \"\" : undefined}\n // Internal attribute for selecting DOM nodes\n {...{ [INTERNAL_DOM_SELECTION_DATA_ATTR]: value }}\n // Allow options to behave like a native select, when you can open and select an item in a single click\n onPointerUp={disabled ? undefined : handlePointerUp}\n // Pointer move allows us to prevent contention from keyboard presses and a still mouse\n // which does trigger events like onMouseEnter, creating weird battles with mouse and keyboard focus.\n onPointerMove={disabled ? undefined : handlePointerMove}\n onPointerLeave={disabled ? undefined : handlePointerLeave}\n aria-disabled={disabled}\n data-disabled={disabled ? \"\" : undefined}\n >\n <div className={s.PressableInner}>\n <div className={s.OptionInner}>\n <div className={s.OptionIndicatorSlot}>\n {isSelected && <Check className={s.OptionCheck} />}\n </div>\n <OptionView {...option} />\n {tooltip && (\n <Tooltip content={tooltip.content} maxWidth={tooltip.maxWidth} side=\"right\">\n <Info />\n </Tooltip>\n )}\n </div>\n {option.description && (\n <div className={s.OptionInner}>\n <div className={s.OptionIndicatorSlot} />\n {option.description}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nconst CustomSelectActions = () => {\n const { actions } = useSelectContext()\n\n if (actions.length === 0) {\n return null\n }\n\n return (\n <div className={s.ActionsContainer}>\n {actions.map((action) => (\n <CustomSelectAction key={action.id} {...action} />\n ))}\n </div>\n )\n}\n\nconst CustomSelectAction = ({ id, label, Icon, className }: Action) => {\n const { onActionSelect } = useSelectContext()\n const { requestCloseRef } = useCustomSelectMenuContext()\n\n const handleKeyDown = (evt: React.KeyboardEvent<HTMLDivElement>) => {\n const key = evt.key\n\n switch (key) {\n case \"Tab\":\n // Allow tabbing to pass propagation as normal,\n // which bubbles up to the focus trap of Radix Popover\n break\n case \"Enter\":\n case \" \":\n evt.stopPropagation()\n handlePointerUp()\n break\n default:\n evt.stopPropagation()\n }\n }\n\n const handlePointerUp = () => {\n // Trigger the action's through our context helper, not the method on this action (it may be a stale reference)\n onActionSelect(id)\n // Request to close the dropdown\n requestCloseRef.current?.()\n }\n\n return (\n <div className={s.Action} onPointerUp={handlePointerUp} onKeyDown={handleKeyDown} tabIndex={0}>\n <div className={clsx(s.ActionInner, className)}>\n {Icon && <Icon role=\"presentation\" />}\n {label}\n </div>\n </div>\n )\n}\n\n// ============================================================\n// Utilities\n// ============================================================\nconst defaultSearchPredicate = (option: Option, searchTerm: string) =>\n option.label.toLowerCase().includes(searchTerm)\n\nconst filterOptions = <T extends Option>(\n options: Options<T>,\n searchTerm: string,\n searchIterator: SearchPredicate<T>,\n): Options<T> => {\n const searchValue = searchTerm.trim().toLocaleLowerCase()\n\n if (!searchValue) {\n return options\n }\n\n const filterOption = (option: T): boolean => searchIterator(option, searchValue)\n\n if (isOptionGroupArray(options)) {\n return options.reduce((acc, group) => {\n const filtered = group.options.filter(filterOption)\n\n if (filtered.length) {\n acc.push({\n ...group,\n options: filtered,\n })\n }\n return acc\n }, [] as OptionGroup<T>[])\n } else {\n return options.reduce((acc, option) => {\n if (filterOption(option)) acc.push(option)\n return acc\n }, [] as T[])\n }\n}\n\nconst getFirstValidOption = <T extends Option>(options: Options<T>): T | undefined => {\n if (!options.length) {\n return undefined\n }\n\n let found: T | undefined\n\n for (const opt of options) {\n if (isOptionGroup(opt)) {\n const firstNonDisabled = opt.options.find((i) => !i.disabled)\n if (firstNonDisabled) {\n found = firstNonDisabled\n break\n }\n } else {\n if (!opt.disabled) {\n found = opt\n break\n }\n }\n }\n\n return found\n}\n\nconst getOptionByValue = <T extends Option>(options: Options<T>, value: string): T | undefined => {\n let found: T | undefined\n\n for (const opt of options) {\n if (isOptionGroup(opt)) {\n const exists = opt.options.find((i) => i.value === value)\n if (exists) {\n found = exists\n break\n }\n } else {\n if (opt.value === value) {\n found = opt\n break\n }\n }\n }\n\n return found\n}\n\nconst getOptionsByValues = <T extends Option>(options: Options<T>, values: string[]): T[] => {\n let found: T[] = []\n const lookup = new Set(values)\n\n for (const opt of options) {\n if (isOptionGroup(opt)) {\n const exists = opt.options.filter((i) => lookup.has(i.value))\n found = found.concat(exists)\n } else {\n if (lookup.has(opt.value)) {\n found.push(opt)\n }\n }\n }\n\n return found\n}\n\nconst MAX_DOM_CRAWLS = 40\n\nconst findOptionByValue = (currentValue: string, container: HTMLElement) =>\n container.querySelector(`[data-option-id=\"${currentValue}\"]`)\n\nconst isValidOptionNode = (node: Element) => node.matches(\"[data-option-id]:not([data-disabled])\")\n\nconst findNextOption = (currentValue: string, container: HTMLElement) => {\n const currentOption = findOptionByValue(currentValue, container)\n\n let nextNode = currentOption?.nextElementSibling\n let maxSteps = 0\n\n while (nextNode && maxSteps < MAX_DOM_CRAWLS) {\n if (isValidOptionNode(nextNode)) {\n return nextNode\n }\n\n nextNode = nextNode.nextElementSibling\n maxSteps += 1\n }\n}\n\nconst findPreviousOption = (currentValue: string, container: HTMLElement) => {\n const currentOption = findOptionByValue(currentValue, container)\n\n let nextNode = currentOption?.previousElementSibling\n let maxSteps = 0\n\n while (nextNode && maxSteps < MAX_DOM_CRAWLS) {\n if (isValidOptionNode(nextNode)) {\n return nextNode\n }\n\n nextNode = nextNode.previousElementSibling\n maxSteps += 1\n }\n}\n\nconst createTypeahead = () => {\n let currentValue: string = \"\"\n let timeoutId: ReturnType<typeof setTimeout>\n\n return (char: string) => {\n // Searching is case-insensitive\n char = char.toLowerCase()\n\n // Add the new character to the current value\n currentValue += char\n\n // Clear the previous timeout if there was one\n if (timeoutId) clearTimeout(timeoutId)\n\n // Reset the value after a brief delay\n timeoutId = setTimeout(() => {\n currentValue = \"\"\n }, 500)\n\n // When a user is typing the same value, like \"llll\", assume they are cycling through items starting with \"l\"\n // We continue to build up the string in case another letter is typed, and then release the full value.\n // For example, if the user types \"ooog\", it will return \"o\", until \"g\" is typed, and then return the \"ooog\".\n const isCycling = char.repeat(currentValue.length) === currentValue\n\n // Return the typeahead value\n return isCycling ? char : currentValue\n }\n}\n\nconst isValidTypeaheadChar = (char: string): boolean => /^[a-zA-Z0-9]$/.test(char)\n\nconst getTypeaheadOption = <T extends Option>(\n options: Options<T>,\n typeaheadValue: string,\n currentHighlightValue?: string,\n): T | undefined => {\n // Ensure options actually exist\n if (!options.length) {\n return undefined\n }\n\n let matchBeforeHighlight: T | undefined\n let matchAfterHighlight: T | undefined\n // If we' aren't provided a highlighted value, start from the top (e.g., act like it's found)\n let foundHighlightedValue: boolean = !currentHighlightValue\n\n const optionValidAndMatches = ({ disabled, label, value }: T) => {\n // Side effect of looping\n if (value === currentHighlightValue) {\n foundHighlightedValue = true\n // Don't return highlighted value\n return false\n }\n\n return !disabled && label.toLowerCase().startsWith(typeaheadValue)\n }\n\n for (const opt of options) {\n if (isOptionGroup(opt)) {\n for (const option of opt.options) {\n if (optionValidAndMatches(option)) {\n if (foundHighlightedValue) {\n matchAfterHighlight = option\n // We're done after we've found an after match\n break\n } else {\n // Keep the first found \"before\" match\n matchBeforeHighlight = matchBeforeHighlight || option\n }\n }\n }\n } else {\n if (optionValidAndMatches(opt)) {\n if (foundHighlightedValue) {\n matchAfterHighlight = opt\n // We're done after we've found an after match\n break\n } else {\n // Keep the first found \"before\" match\n matchBeforeHighlight = matchBeforeHighlight || opt\n }\n }\n }\n }\n\n return matchAfterHighlight || matchBeforeHighlight\n}\n", "import { useEffect, useId } from \"react\"\nimport { useLatestValue } from \"./useLatestValue\"\n\ntype Handler = {\n id: string\n callback: React.MutableRefObject<() => void>\n}\n\nlet handlers: Handler[] = []\nlet listenerBound = false\n\nconst handleKeyDown = (evt: KeyboardEvent) => {\n if (evt.key === \"Escape\") {\n // Attempt to call the first handler in the stack, if it exists\n const [firstHandler] = handlers\n\n if (firstHandler) {\n evt.preventDefault()\n firstHandler.callback.current?.()\n }\n }\n}\n\nconst managerListener = () => {\n if (handlers.length > 0 && !listenerBound) {\n document.body.addEventListener(\"keydown\", handleKeyDown)\n listenerBound = true\n } else if (handlers.length === 0 && listenerBound) {\n document.body.removeEventListener(\"keydown\", handleKeyDown)\n listenerBound = false\n }\n}\n\nconst registerHandler = (handler: Handler) => {\n handlers.unshift(handler)\n managerListener()\n}\n\nconst unregisterHandler = ({ id }: Handler) => {\n handlers = handlers.filter((h) => h.id !== id)\n managerListener()\n}\n\nexport const useEscCloseStack = (listening: boolean, cb: () => void) => {\n const id = useId()\n const latestCallback = useLatestValue(cb)\n\n useEffect(() => {\n if (!listening) {\n return\n }\n\n const handler = { id, callback: latestCallback }\n registerHandler(handler)\n\n return () => unregisterHandler(handler)\n }, [id, listening, latestCallback])\n}\n", "import { useRef } from \"react\"\n\nexport function useLatestValue<T>(value: T) {\n const ref = useRef(value)\n ref.current = value\n return ref\n}\n", "import type { SVGProps } from \"react\"\nconst Check = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" fill=\"currentColor\" {...props}>\n <path\n fillRule=\"evenodd\"\n d=\"M18.063 5.674a1 1 0 0 1 .263 1.39l-7.5 11a1 1 0 0 1-1.533.143l-4.5-4.5a1 1 0 1 1 1.414-1.414l3.647 3.647 6.82-10.003a1 1 0 0 1 1.39-.263Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n)\nexport default Check\n", "import type { SVGProps } from \"react\"\nconst ChevronDownVector = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"1em\" height=\"1em\" viewBox=\"0 0 16 9\" fill=\"currentColor\" {...props}>\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M0.292893 0.292893C0.683418 -0.0976311 1.31658 -0.0976311 1.70711 0.292893L8 6.58579L14.2929 0.292894C14.6834 -0.0976305 15.3166 -0.0976304 15.7071 0.292894C16.0976 0.683418 16.0976 1.31658 15.7071 1.70711L8.70711 8.70711C8.31658 9.09763 7.68342 9.09763 7.29289 8.70711L0.292893 1.70711C-0.0976311 1.31658 -0.0976311 0.683417 0.292893 0.292893Z\"\n />\n </svg>\n)\nexport default ChevronDownVector\n", "import type { SVGProps } from \"react\"\nconst DropdownVector = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"1em\" height=\"1em\" viewBox=\"0 0 10 16\" fill=\"currentColor\" {...props}>\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M4.34151 0.747423C4.71854 0.417526 5.28149 0.417526 5.65852 0.747423L9.65852 4.24742C10.0742 4.61111 10.1163 5.24287 9.75259 5.6585C9.38891 6.07414 8.75715 6.11626 8.34151 5.75258L5.00001 2.82877L1.65852 5.75258C1.24288 6.11626 0.61112 6.07414 0.247438 5.6585C-0.116244 5.24287 -0.0741267 4.61111 0.34151 4.24742L4.34151 0.747423ZM0.246065 10.3578C0.608879 9.94139 1.24055 9.89795 1.65695 10.2608L5.00001 13.1737L8.34308 10.2608C8.75948 9.89795 9.39115 9.94139 9.75396 10.3578C10.1168 10.7742 10.0733 11.4058 9.65695 11.7687L5.65695 15.2539C5.28043 15.582 4.7196 15.582 4.34308 15.2539L0.343082 11.7687C-0.0733128 11.4058 -0.116749 10.7742 0.246065 10.3578Z\"\n />\n </svg>\n)\nexport default DropdownVector\n", "import type { SVGProps } from \"react\"\nconst Info = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" fill=\"currentColor\" {...props}>\n <path d=\"M13 12a1 1 0 1 0-2 0v4a1 1 0 1 0 2 0v-4Zm-1-2.5A1.25 1.25 0 1 0 12 7a1.25 1.25 0 0 0 0 2.5Z\" />\n <path\n fillRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n)\nexport default Info\n", "import type { SVGProps } from \"react\"\nconst Search = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" fill=\"currentColor\" {...props}>\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M10.875 4.5C7.35418 4.5 4.5 7.35418 4.5 10.875C4.5 14.3958 7.35418 17.25 10.875 17.25C14.3958 17.25 17.25 14.3958 17.25 10.875C17.25 7.35418 14.3958 4.5 10.875 4.5ZM2.5 10.875C2.5 6.24962 6.24962 2.5 10.875 2.5C15.5004 2.5 19.25 6.24962 19.25 10.875C19.25 12.8273 18.582 14.6236 17.462 16.0478L21.2071 19.7929C21.5976 20.1834 21.5976 20.8166 21.2071 21.2071C20.8166 21.5976 20.1834 21.5976 19.7929 21.2071L16.0478 17.462C14.6236 18.582 12.8273 19.25 10.875 19.25C6.24962 19.25 2.5 15.5004 2.5 10.875Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\nexport default Search\n", "import type { SVGProps } from \"react\"\nconst X = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" fill=\"currentColor\" {...props}>\n <path\n fillRule=\"evenodd\"\n d=\"M5.636 5.636a1 1 0 0 1 1.414 0l4.95 4.95 4.95-4.95a1 1 0 0 1 1.414 1.414L13.414 12l4.95 4.95a1 1 0 0 1-1.414 1.414L12 13.414l-4.95 4.95a1 1 0 0 1-1.414-1.414l4.95-4.95-4.95-4.95a1 1 0 0 1 0-1.414Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n)\nexport default X\n", "\"use client\"\n\nimport clsx from \"clsx\"\nimport { useRef, type ReactNode } from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\nimport { handlePressableMouseEnter } from \"../../lib/helpers\"\nimport type { ControlSize, Variants } from \"../../types\"\nimport { Button } from \"../Button\"\nimport { ChevronDownVector, DropdownVector, X } from \"../Icon\"\nimport { LoadingIndicator } from \"../Indicator\"\nimport s from \"./SelectControl.module.css\"\n\nexport type DropdownIconType = \"chevronDown\" | \"dropdown\" | \"none\"\n\nexport type SelectControlProps = Omit<React.HTMLAttributes<HTMLSpanElement>, \"onClick\"> & {\n /**\n * Style variant for the Button\n * @default fill\n */\n variant?: Variants<\"soft\" | \"outline\" | \"ghost\">\n /**\n * Determines if the control should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Extends the control to 100% of available width.\n * @default true\n */\n block?: boolean\n /**\n * Applies a negative margin using the current gutter to optically align the control\n * with surrounding content.\n */\n opticallyAlign?: \"start\" | \"end\"\n /**\n * Disables the control visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Visually indicates that the control is in an invalid state\n * @default false\n */\n invalid?: boolean\n /**\n * Indicates that the control is selected. An unselected state will display placeholder styles.\n * @default false\n */\n selected?: boolean\n /**\n * Display a clear action that allows the select to be unset.\n * @default false\n */\n onClearClick?: () => void\n /**\n * Primary handler for when the control is selected with pointer or keyboard events\n */\n onInteract?: () => void\n /**\n * Determines size of the size and spacing of the control.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: ControlSize\n /**\n * Displays loading indicator on top of button contents\n * @default false\n */\n loading?: boolean\n /**\n * Icon displayed in the far right of the select trigger\n * @default dropdown\n */\n dropdownIconType?: DropdownIconType\n /** Icon displayed at the start of the control */\n StartIcon?: React.ComponentType<React.SVGProps<SVGSVGElement>>\n /** Custom class applied to the control element */\n className?: string\n /** Content rendered for the control */\n children: ReactNode\n ref?: React.Ref<HTMLSpanElement | null>\n}\n\nexport const SelectControl = ({\n ref,\n onPointerDown,\n onKeyDown,\n onPointerEnter,\n onInteract,\n invalid,\n disabled,\n children,\n className,\n variant = \"outline\",\n size = \"md\",\n block,\n opticallyAlign,\n pill = true,\n loading,\n onClearClick,\n selected = false,\n StartIcon,\n dropdownIconType = \"dropdown\",\n ...restProps\n}: SelectControlProps) => {\n const controlRef = useRef<HTMLSpanElement>(null)\n const clearable = !!onClearClick\n const showClearAction = clearable && selected && !loading && !disabled\n const hasDropdownIcon = dropdownIconType && dropdownIconType !== \"none\" && !loading\n const hasAnyTertiaryIndicator = showClearAction || loading || hasDropdownIcon\n const isInteractive = !loading && !disabled\n\n // Act like a <button> and fire the click handler on keyboard actions\n const handleKeyDown = (evt: React.KeyboardEvent<HTMLSpanElement>) => {\n switch (evt.key) {\n // NOTE: \"Enter\" does not open selects, as it may be an attempt to submit a form\n case \"ArrowDown\":\n case \"ArrowUp\":\n case \" \":\n evt.stopPropagation()\n evt.preventDefault()\n\n if (onInteract) {\n onInteract()\n } else {\n // Otherwise, send a synthetic trigger event to Radix (presumably)\n controlRef.current?.dispatchEvent(\n new PointerEvent(\"pointerdown\", {\n bubbles: true,\n cancelable: true,\n pointerType: \"mouse\", // mimic mouse interaction\n }),\n )\n }\n break\n case \"Enter\":\n // NOTE: \"Enter\" does not open selects, as it may be an attempt to submit a form\n break\n default:\n // Allow all other key presses through\n onKeyDown?.(evt)\n }\n }\n\n const handlePointerDown = (evt: React.PointerEvent<HTMLSpanElement>) => {\n // Don't trigger on right clicks\n if (evt.button === 2) {\n return\n }\n\n // Prevent focus from entering the click target of the select\n // so that focus correctly moves into the menu.\n evt.stopPropagation()\n\n if (onInteract) {\n evt.preventDefault()\n onInteract()\n } else {\n // NOTE: cannot preventDefault() here, for radix\n onPointerDown?.(evt)\n // @ts-expect-error -- `onClick` can only be present if Radix is trying to spread it.\n // An example would be `<Popover>`, but we specifically open this component on `onPointerDown`.\n // Trigger the handler, assuming that `onPointerDown` is not going to be responsible for opening.\n restProps.onClick?.(evt)\n }\n }\n\n return (\n // Intentionally not using <button> and rebuilding the semantics\n <span\n ref={mergeRefs([controlRef, ref])}\n className={clsx(s.SelectControl, className)}\n // Recreate <button> semantics\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onPointerEnter={(evt: React.PointerEvent<HTMLAnchorElement>) => {\n handlePressableMouseEnter(evt)\n onPointerEnter?.(evt)\n }}\n onPointerDown={isInteractive ? handlePointerDown : undefined}\n onKeyDown={isInteractive ? handleKeyDown : undefined}\n data-variant={variant}\n data-block={block ? \"\" : undefined}\n data-pill={pill ? \"\" : undefined}\n data-size={size}\n data-optically-align={opticallyAlign}\n aria-busy={loading ? \"true\" : undefined}\n data-selected={selected}\n data-loading={loading ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n data-disabled={disabled ? \"\" : undefined}\n aria-disabled={disabled}\n {...restProps}\n // Ignore onClick handler from Radix, because we use onPointerDown to mimic a native select\n onClick={undefined}\n >\n {StartIcon && <StartIcon className={s.StartIcon} />}\n <span className={s.TriggerText}>{children}</span>\n {hasAnyTertiaryIndicator && (\n <div className={s.IndicatorWrapper}>\n {showClearAction && (\n <Button\n aria-label=\"Clear current value\"\n className={s.Clear}\n onPointerDown={(evt: React.PointerEvent<HTMLButtonElement>) => {\n // Prevent pointerDown on trigger from being captured\n evt.stopPropagation()\n }}\n onClick={(evt) => {\n evt.stopPropagation()\n evt.preventDefault()\n onClearClick()\n }}\n color=\"secondary\"\n variant={hasDropdownIcon ? \"ghost\" : \"solid\"}\n // Mostly custom sizing through variables\n size=\"3xs\"\n uniform\n pill={pill}\n data-only-child={!hasDropdownIcon ? \"\" : undefined}\n >\n <X />\n </Button>\n )}\n {loading && <LoadingIndicator className={s.LoadingIndicator} />}\n {/* Using raw SVG canvases (opposed to fixed icon canvases) led to less pixelation. */}\n {hasDropdownIcon && <DropdownIcon iconType={dropdownIconType} />}\n </div>\n )}\n </span>\n )\n}\n\ntype DropdownIconProps = {\n iconType: Omit<DropdownIconType, \"none\">\n}\n\nexport const DropdownIcon = ({ iconType }: DropdownIconProps) => {\n return iconType === \"chevronDown\" ? (\n <ChevronDownVector className={clsx(s.DropdownIcon, s.DropdownIconChevron)} />\n ) : (\n <DropdownVector className={s.DropdownIcon} />\n )\n}\n", "\"use client\"\n\nimport clsx from \"clsx\"\nimport {\n type ButtonHTMLAttributes,\n type ComponentProps,\n type ComponentType,\n type MouseEventHandler,\n type ReactNode,\n useCallback,\n} from \"react\"\nimport { handlePressableMouseEnter } from \"../../lib/helpers\"\nimport { wrapTextNodeSiblings } from \"../../lib/renderHelpers\"\nimport { type ControlSize, type SemanticColors, type Sizes, type Variants } from \"../../types\"\nimport { useLinkComponent } from \"../AppsSDKUIProvider/internal\"\nimport { LoadingIndicator } from \"../Indicator\"\nimport { TransitionGroup } from \"../Transition/TransitionGroup\"\nimport s from \"./Button.module.css\"\n\ntype CommonProps = {\n /**\n * Color for the button\n * @default secondary\n */\n color: SemanticColors<\n \"primary\" | \"secondary\" | \"danger\" | \"success\" | \"info\" | \"discovery\" | \"caution\" | \"warning\"\n >\n /**\n * Style variant for the Button\n * @default \"solid\"\n */\n variant?: Variants<\"solid\" | \"soft\" | \"outline\" | \"ghost\">\n /**\n * Determines if the button should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Disables the button visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Controls the visual tone when the button is disabled. \"relaxed\" will use a default cursor instead of not-allowed.\n */\n disabledTone?: \"relaxed\"\n /**\n * Determines if the button should take up 100% of available width\n * @default false\n */\n block?: boolean\n /**\n * Applies a negative margin using the current gutter to optically align the button\n * with surrounding content.\n */\n opticallyAlign?: \"start\" | \"end\"\n /**\n * Controls size of the button, specifically height, but also includes defaults for `gutterSize`, `iconSize`, `font-size`, etc.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: ControlSize\n /**\n * Controls the size of icons within the button, defaults to value from `size`.\n *\n * | xs | sm | md | lg | xl | 2xl |\n * | ------ | ------ | ------ | ------ | ------ | ------ |\n * | `14px` | `16px` | `18px` | `20px` | `22px` | `24px` |\n */\n iconSize?: Sizes<\"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\">\n /**\n * Controls gutter on the edges of the button, defaults to value from `size`.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl |\n * | ------ | ------ | ------ | ------ | ------ | ------ | ------ |\n * | `4px` | `6px` | `8px` | `10px` | `12px` | `14px` | `16px` |\n */\n gutterSize?: Sizes<\"3xs\" | \"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\">\n /** Custom class applied to the Button element */\n className?: string\n /** Content rendered inside of the Button */\n children: React.ReactNode\n}\n\nexport type ButtonProps = CommonProps & {\n /**\n * Determines if the button should have matching width and height, based on the `size`.\n * @default false\n */\n uniform?: boolean\n /**\n * Displays selected styles on the button, varying by `variant\n * @default false\n */\n selected?: boolean\n /**\n * Displays loading indicator on top of button contents\n * @default false\n */\n loading?: boolean\n /**\n * Determines whether the button should be made inert, without introducing visual change.\n * @default false\n */\n inert?: boolean\n /** Ref for the button */\n ref?: React.Ref<HTMLButtonElement | null>\n} & ButtonHTMLAttributes<HTMLButtonElement>\n\nexport const Button = (props: ButtonProps) => {\n const {\n type = \"button\",\n color = \"primary\",\n variant = \"solid\",\n pill = true,\n uniform = false,\n size = \"md\",\n iconSize,\n gutterSize,\n loading,\n selected,\n block,\n opticallyAlign,\n children,\n className,\n onClick,\n disabled,\n disabledTone,\n // Defaults to `loading` state\n inert = loading,\n ...restProps\n } = props\n\n const isInert = disabled || inert\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n if (disabled) {\n return\n }\n onClick?.(e)\n },\n [onClick, disabled],\n )\n\n return (\n <button\n type={type}\n className={clsx(s.Button, className)}\n data-color={color}\n data-variant={variant}\n data-pill={pill ? \"\" : undefined}\n data-uniform={uniform ? \"\" : undefined}\n data-size={size}\n data-gutter-size={gutterSize}\n data-icon-size={iconSize}\n data-loading={loading ? \"\" : undefined}\n data-selected={selected ? \"\" : undefined}\n data-block={block ? \"\" : undefined}\n data-optically-align={opticallyAlign}\n onPointerEnter={handlePressableMouseEnter}\n // Non-visual, accessible disablement\n // NOTE: Do not use literal `inert` because that is incorrect semantically\n disabled={isInert}\n aria-disabled={isInert}\n tabIndex={isInert ? -1 : undefined}\n // Visual disablement\n data-disabled={disabled ? \"\" : undefined}\n data-disabled-tone={disabled ? disabledTone : undefined}\n onClick={handleClick}\n {...restProps}\n >\n <TransitionGroup className={s.ButtonLoader} enterDuration={250} exitDuration={150}>\n {loading && <LoadingIndicator key=\"loader\" />}\n </TransitionGroup>\n <span className={s.ButtonInner}>{wrapTextNodeSiblings(children)}</span>\n </button>\n )\n}\n\ntype ButtonLink = <\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends ComponentType<any> | \"a\" = AppsSDKUI.LinkComponent,\n>(\n props: Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n CommonProps & {\n /**\n * Explicity specify that the link is an external link. This should be\n * automatically detected based on the URL, but in some cases (e.g.\n * my-app://foo) you may want to explicitly set this.\n */\n external?: boolean\n /**\n * Override the default component used for the link. This is useful for\n * using a routing library, or SSR rendering.\n * purposes.\n *\n * @default 'a'\n */\n as?: T\n } & ComponentProps<T>,\n) => ReactNode\n\nexport const ButtonLink = ((\n props: Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n CommonProps & {\n href?: string\n to?: string\n external?: boolean\n as?: AppsSDKUI.LinkComponent\n },\n) => {\n const {\n color = \"primary\",\n variant = \"solid\",\n pill = true,\n size = \"md\",\n gutterSize,\n iconSize,\n external,\n block,\n opticallyAlign,\n children,\n className,\n disabled,\n disabledTone,\n onClick,\n onPointerEnter,\n as: OverrideComponent,\n href,\n to,\n ...restProps\n } = props\n\n const isExternal = external ?? /^https?:\\/\\//.test(href ?? to ?? \"\")\n const DefaultComponent = useLinkComponent()\n const LinkComponent = OverrideComponent || (isExternal ? \"a\" : DefaultComponent)\n\n const sharedProps = {\n \"className\": clsx(s.Button, className),\n disabled,\n \"aria-disabled\": disabled,\n \"tabIndex\": disabled ? -1 : undefined,\n // Visual disablement (inert not supported in links, always applied)\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-disabled-tone\": disabled ? disabledTone : undefined,\n \"data-color\": color,\n \"data-variant\": variant,\n \"data-pill\": pill ? \"\" : undefined,\n \"data-block\": block ? \"\" : undefined,\n \"data-optically-align\": opticallyAlign,\n \"data-size\": size,\n \"data-gutter-size\": gutterSize,\n \"data-icon-size\": iconSize,\n \"onClick\": disabled ? undefined : onClick,\n \"onPointerEnter\": (evt: React.PointerEvent<HTMLAnchorElement>) => {\n handlePressableMouseEnter(evt)\n onPointerEnter?.(evt)\n },\n }\n\n if (disabled) {\n // Don't thread down stuff that isn't valid for a span - just keep the event handlers\n const eventProps = Object.fromEntries(\n Object.entries(restProps).filter(\n ([key, value]) => key.startsWith(\"on\") && typeof value === \"function\",\n ),\n )\n return (\n <span role=\"link\" {...sharedProps} {...eventProps}>\n <span className={s.ButtonInner}>{wrapTextNodeSiblings(children)}</span>\n </span>\n )\n }\n\n const linkProps = {\n ...(isExternal\n ? { target: \"_blank\", rel: \"noopener noreferrer\", href: href ?? to }\n : { href, to }),\n ...sharedProps,\n ...restProps,\n }\n\n return (\n <LinkComponent {...linkProps}>\n <span className={s.ButtonInner}>{wrapTextNodeSiblings(children)}</span>\n </LinkComponent>\n )\n}) as ButtonLink\n", "import { Children, cloneElement, isValidElement, type ReactElement, type ReactNode } from \"react\"\n\nconst flattenTextNodes = (children: ReactNode): ReactNode[] => {\n const nodes = Children.toArray(children)\n const result: ReactNode[] = []\n let buffer = \"\"\n\n const flush = () => {\n if (buffer !== \"\") {\n result.push(buffer)\n buffer = \"\"\n }\n }\n\n for (const node of nodes) {\n if (node == null || typeof node === \"boolean\") {\n continue\n }\n\n if (typeof node === \"string\" || typeof node === \"number\") {\n buffer += String(node)\n continue\n }\n\n // Boundary encountered: output any accumulated text, then the node\n flush()\n result.push(node)\n }\n\n flush()\n return result\n}\n\n// Helper to wrap text node siblings of other elements in a tag,\n// which enables sibling selectors to behave as expected for certain conditions\nexport const wrapTextNodeSiblings = (children: ReactNode): ReactNode => {\n const flattenedChildren = flattenTextNodes(children)\n const childrenCount = Children.count(flattenedChildren)\n\n return Children.map(flattenedChildren, (child) => {\n if (typeof child === \"string\" && !!child.trim()) {\n // Children with no siblings can immediately return\n if (childrenCount <= 1) {\n return child\n }\n\n // Wrap text nodes that have siblings\n return <span>{child}</span>\n }\n\n // For valid elements, recursively render to capture wrapped children\n if (isValidElement(child)) {\n const element = child as ReactElement<{ children?: ReactNode }>\n const { children: innerChildren, ...restProps } = element.props\n\n if (innerChildren != null) {\n return cloneElement(element, restProps, wrapTextNodeSiblings(innerChildren))\n }\n\n return element\n }\n\n return child\n })\n}\n", "\"use client\"\n\nimport { useContext } from \"react\"\nimport { AppsSDKUIContext } from \"./AppsSDKUIContext\"\n\nexport function useLinkComponent() {\n const context = useContext(AppsSDKUIContext)\n return context?.linkComponent ?? \"a\"\n}\n", "\"use client\"\n\nimport { type ComponentType, createContext, type ForwardRefExoticComponent } from \"react\"\n\ntype AppsSDKUIContextValue = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n linkComponent: ComponentType<any> | ForwardRefExoticComponent<any> | \"a\"\n}\n\nexport const AppsSDKUIContext = createContext<AppsSDKUIContextValue | null>(null)\n", "\"use client\"\n\nimport clsx from \"clsx\"\nimport { useState, type ComponentProps } from \"react\"\nimport { useSimulatedProgress } from \"../../hooks/useSimulatedProgress\"\n\nimport { toCssVariables } from \"../../lib/helpers\"\nimport s from \"./CircularProgress.module.css\"\n\nexport type CircularProgressProps = Omit<ComponentProps<\"div\">, \"children\"> & {\n /**\n * Maximum duration to use for simulated upload progress in ms\n * @default 15000\n */\n maxDuration?: number\n /**\n * Sets the progress to full and resolves the simulated timer\n * @default false\n */\n done?: boolean\n /**\n * Sets the progress to full and resolves the simulated timer\n * @default false\n */\n progress?: number\n /** Size of the indicator, in pixels\n * @default 28px\n */\n size?: number | string\n /** Stroke width of the indicator, in pixels, between 1 and 4\n * @default 2\n */\n strokeWidth?: number\n /** Color of the active progress track (stroke) */\n trackActiveColor?: string\n /** Color of the base track (background stroke) */\n trackColor?: string\n}\n\nexport const CircularProgress = ({\n maxDuration = 15000, // 15 seconds\n done = false,\n className,\n progress: propProgress,\n size,\n strokeWidth,\n trackActiveColor,\n trackColor,\n style,\n ...restProps\n}: CircularProgressProps) => {\n const [currentTime] = useState(new Date())\n const simulatedProgressDone = propProgress !== undefined || done\n const simulatedProgress = useSimulatedProgress(+currentTime, maxDuration, simulatedProgressDone)\n const progress = propProgress ?? simulatedProgress\n\n return (\n <div\n {...restProps}\n className={clsx(s.Container, className)}\n style={\n style ||\n toCssVariables({\n \"circular-progress-size\": size,\n \"circular-progress-stroke\": strokeWidth ? Math.min(4, strokeWidth) : undefined,\n \"circular-progress-track-active-color\": trackActiveColor,\n \"circular-progress-track-color\": trackColor,\n })\n }\n >\n <svg viewBox=\"0 0 20 20\" className={s.Track} data-no-autosize>\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"none\" />\n </svg>\n <svg\n viewBox=\"0 0 20 20\"\n className={s.TrackProgress}\n style={{\n strokeDashoffset: 50 - 50 * (progress / 100),\n }}\n data-no-autosize\n >\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"none\" />\n </svg>\n </div>\n )\n}\n", "import { useState } from \"react\"\nimport { useInterval } from \"usehooks-ts\"\n\n/**\n * Deterministically returns a progress value between 0 and 100 that decays as it approaches 100,\n * based on a maximum duration and the elapsed time.\n *\n * @param maxTime - The maximum duration (in ms) after which the progress will be 100\n * @param elapsedTime - The elapsed time (in ms) since the start time\n * @returns The simulated progress percentage\n */\nexport function getSimulatedProgress(maxTime: number, elapsedTime: number) {\n // Parameters\n const P_max = 99.9 // Maximum percentage to approach (less than 100%)\n const P1 = 35 // Percentage at which the rate slows down\n const initialRate = (3 * 100) / maxTime // Initial rate (% per second)\n const t1 = P1 / initialRate // Time when progress reaches P1\n\n let percentage\n\n if (elapsedTime <= t1) {\n // **Phase 1:** Linear increase at the start to show consistency in progress\n percentage = initialRate * elapsedTime\n } else {\n // **Phase 2:** Progress slows down, approaching P_max\n const k = 4 // Controls how quickly progress approaches P_max\n const remainingTime = maxTime - t1\n const timeSinceT1 = elapsedTime - t1\n const exponent = -k * (timeSinceT1 / remainingTime)\n percentage = P1 + (P_max - P1) * (1 - Math.exp(exponent))\n }\n\n // Ensure the percentage does not exceed P_max\n return Math.min(percentage, P_max)\n}\n\n/**\n * Returns a number that will increase over time, decaying as it approaches 100,\n * withouth ever reaching the end.\n *\n * @param startAt - The time at which the progress started\n * @param maxDuration - The maximum duration (in ms) after which the progress will be 100\n * @param completed - Sets progress to 100% immediately\n */\nexport const useSimulatedProgress = (startAt: number, maxDuration: number, completed?: boolean) => {\n const elapsedStartTime = +new Date() - startAt\n const [progress, setProgress] = useState(getSimulatedProgress(maxDuration, elapsedStartTime))\n\n const incrementProgress = () => {\n const elapsedTime = +new Date() - startAt\n const newProgress =\n elapsedTime >= maxDuration ? 100 : getSimulatedProgress(maxDuration, elapsedTime)\n setProgress(newProgress)\n }\n\n useInterval(incrementProgress, completed ? null : 100)\n\n return completed ? 100 : progress\n}\n", "import clsx from \"clsx\"\nimport type { ComponentProps } from \"react\"\nimport s from \"./LoadingDots.module.css\"\n\nexport type LoadingDotsProps = Omit<ComponentProps<\"div\">, \"children\">\n\nexport const LoadingDots = ({ className, ...restProps }: LoadingDotsProps) => {\n return (\n <div className={clsx(s.LoadingDots, className)} {...restProps}>\n <div className={s.Dot} />\n <div className={s.Dot} />\n <div className={s.Dot} />\n </div>\n )\n}\n", "import clsx from \"clsx\"\nimport type { ComponentProps } from \"react\"\nimport { toCssVariables } from \"../../lib/helpers\"\nimport s from \"./LoadingIndicator.module.css\"\n\nexport type LoadingIndicatorProps = {\n /** Classname applied to the indicator */\n className?: string\n /** Size of the indicator, in pixels\n * @default 1em\n */\n size?: number | string\n /** Stroke width of the indicator, in pixels\n * @default 2\n */\n strokeWidth?: number\n} & Omit<ComponentProps<\"div\">, \"children\">\n\nexport const LoadingIndicator = ({\n className,\n size,\n strokeWidth,\n style,\n ...restProps\n}: LoadingIndicatorProps) => {\n return (\n <div\n {...restProps}\n className={clsx(s.LoadingIndicator, className)}\n style={\n style ||\n toCssVariables({\n \"indicator-size\": size,\n \"indicator-stroke\": strokeWidth,\n })\n }\n />\n )\n}\n", "\"use client\"\n\nimport React, {\n Children,\n useCallback,\n useEffect,\n useLayoutEffect,\n useReducer,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\n\nimport { waitForAnimationFrame } from \"../../lib/helpers\"\n\nimport clsx from \"clsx\"\nimport { useTimeout } from \"usehooks-ts\"\nimport getDisableAnimations from \"./getDisableAnimations\"\nimport {\n assertSingleChildWhenRef,\n ChildrenWithKeys,\n computeNextRenderChildren,\n noop,\n useChildCallback,\n type CallbackType,\n type ReactElementWithKey,\n type TransitionGroupChildCallbacks,\n} from \"./shared\"\nimport s from \"./TransitionGroup.module.css\"\nimport { getInitialTransitionState, transitionReducer } from \"./transitionReducer\"\n\ntype TransitionGroupChildProps = {\n as: \"div\" | \"span\"\n children: React.ReactNode\n className?: string\n transitionId?: string\n style?: CSSProperties\n preventMountTransition?: boolean\n shouldRender: boolean\n enterDuration: number\n exitDuration: number\n enterMountDelay?: number\n removeChild: () => void\n ref?: React.Ref<unknown>\n} & TransitionGroupChildCallbacks\n\nconst TransitionGroupChildInner = ({\n ref: forwardedRef,\n as: TagName,\n children,\n className,\n transitionId,\n style,\n preventMountTransition,\n shouldRender,\n enterDuration,\n exitDuration,\n removeChild,\n onEnter,\n onEnterActive,\n onEnterComplete,\n onExit,\n onExitActive,\n onExitComplete,\n}: TransitionGroupChildProps) => {\n const [state, dispatch] = useReducer(\n transitionReducer,\n getInitialTransitionState(preventMountTransition || false),\n )\n // Allow a child to prevent mount transition, but still experience\n // future enter transition events, when applicable.\n const preventedMountTransition = useRef<boolean>(false)\n const elementRef = useRef<HTMLDivElement | null>(null)\n // Duration values should not affect hook re-renders, so we create refs for them\n const enterDurationRef = useRef<number>(enterDuration)\n enterDurationRef.current = enterDuration\n const exitDurationRef = useRef<number>(exitDuration)\n exitDurationRef.current = exitDuration\n\n const lastCallbackRef = useRef<CallbackType>(null)\n const triggerCallback = useCallback(\n (callbackType: CallbackType) => {\n const element = elementRef.current\n\n if (!element || callbackType === lastCallbackRef.current) {\n return\n }\n\n lastCallbackRef.current = callbackType\n\n switch (callbackType) {\n case \"enter\":\n onEnter(element)\n break\n case \"enter-active\":\n onEnterActive(element)\n break\n case \"enter-complete\":\n onEnterComplete(element)\n break\n case \"exit\":\n onExit(element)\n break\n case \"exit-active\":\n onExitActive(element)\n break\n case \"exit-complete\":\n onExitComplete(element)\n break\n default:\n callbackType satisfies never\n break\n }\n },\n [onEnter, onEnterActive, onEnterComplete, onExit, onExitActive, onExitComplete],\n )\n\n React.useLayoutEffect(() => {\n // Exit transition\n if (!shouldRender) {\n let exitTimeout: number | undefined\n\n dispatch({ type: \"exit-before\" })\n triggerCallback(\"exit\")\n\n const cancelAnimationFrame = waitForAnimationFrame(() => {\n dispatch({ type: \"exit-active\" })\n triggerCallback(\"exit-active\")\n\n exitTimeout = window.setTimeout(() => {\n triggerCallback(\"exit-complete\")\n removeChild()\n }, exitDurationRef.current)\n })\n\n return () => {\n cancelAnimationFrame()\n if (exitTimeout !== undefined) clearTimeout(exitTimeout)\n }\n }\n\n // Enter transition\n\n // Check if we need to prevent this specific entering cycle\n if (preventMountTransition && !preventedMountTransition.current) {\n // Mark initial transition as prevented and short-circuit.\n preventedMountTransition.current = true\n return\n }\n\n let enterTimeout: number | undefined\n\n dispatch({ type: \"enter-before\" })\n triggerCallback(\"enter\")\n\n const cancelAnimationFrame = waitForAnimationFrame(() => {\n dispatch({ type: \"enter-active\" })\n triggerCallback(\"enter-active\")\n\n enterTimeout = window.setTimeout(() => {\n dispatch({ type: \"done\" })\n triggerCallback(\"enter-complete\")\n }, enterDurationRef.current)\n })\n\n return () => {\n cancelAnimationFrame()\n if (enterTimeout !== undefined) clearTimeout(enterTimeout)\n }\n }, [\n shouldRender,\n // This value is immutable after <TransitionGroup> is created, and does not change on re-renders.\n preventMountTransition,\n removeChild,\n triggerCallback,\n ])\n\n useEffect(() => {\n // Required for <StrictMode>, because we need to unset this token\n // when the hooks are re-run. It's an imperative effect that we need to manage.\n return () => {\n preventedMountTransition.current = false\n }\n }, [])\n\n return (\n <TagName\n ref={mergeRefs([elementRef, forwardedRef])}\n className={clsx(className, s.TransitionGroupChild)}\n data-transition-id={transitionId}\n style={style}\n data-entering={state.enter ? \"\" : undefined}\n data-entering-active={state.enterActive ? \"\" : undefined}\n data-exiting={state.exit ? \"\" : undefined}\n data-exiting-active={state.exitActive ? \"\" : undefined}\n data-interrupted={state.interrupted ? \"\" : undefined}\n >\n {children}\n </TagName>\n )\n}\n\nconst TransitionGroupChild = (props: TransitionGroupChildProps) => {\n // Don't spread these out of props - pass all props to inner child\n const { enterMountDelay, preventMountTransition } = props\n // Mount gating occurs when enterMountDelay exists, and isn't initial mount\n // Otherwise, this flag is a no-op and the TransitionChild mounts normally.\n const mountDelay = !preventMountTransition && enterMountDelay != null ? enterMountDelay : null\n const [mounted, setMounted] = useState(mountDelay == null)\n useTimeout(() => setMounted(true), mounted ? null : mountDelay)\n\n return mounted ? <TransitionGroupChildInner {...props} /> : null\n}\n\nexport type TransitionGroupProps = {\n /** Components controlled by TransitionGroup rendering */\n children: React.ReactNode\n /** Determines the tag used by wrapping elements */\n as?: \"div\" | \"span\"\n /** Class passed to wrapping elements */\n className?: string\n /** Identifier passed to wrapping elements as `[data-transition-id]` */\n transitionId?: string\n /** Determines the amount of time that the enter state is applied during mounting */\n enterDuration?: number\n /** Determines the amount of time that the exit state is applied before unmounting */\n exitDuration?: number\n /**\n * Determines if children should have an enter transition applied during mounting of the TransitionGroup.\n * @default true\n */\n preventInitialTransition?: boolean\n /** Delay in MS to wait before mounting a child. `null` for no delay (default). */\n enterMountDelay?: number\n /** Render children changes immediately, bypassing transition timings */\n disableAnimations?: boolean\n /** Determines how new children are added to the children array */\n insertMethod?: \"append\" | \"prepend\"\n /** Styles applied to wrapping elements */\n style?: CSSProperties\n /** Ref for the TransitionGroup */\n ref?: React.Ref<unknown>\n} & Partial<TransitionGroupChildCallbacks>\n\ntype RenderChild = {\n component: ReactElementWithKey\n shouldRender: boolean\n preventMountTransition?: boolean\n removeChild: () => void\n} & TransitionGroupChildCallbacks\n\nexport const TransitionGroup = (props: TransitionGroupProps) => {\n const {\n ref: forwardedRef,\n as: TagName = \"span\",\n children,\n className,\n transitionId,\n style,\n enterDuration = 0,\n exitDuration = 0,\n preventInitialTransition = true,\n enterMountDelay,\n insertMethod = \"append\",\n disableAnimations = getDisableAnimations(),\n } = props\n // Create stable, mutable references for all callbacks\n const onEnter = useChildCallback(props.onEnter ?? noop)\n const onEnterActive = useChildCallback(props.onEnterActive ?? noop)\n const onEnterComplete = useChildCallback(props.onEnterComplete ?? noop)\n const onExit = useChildCallback(props.onExit ?? noop)\n const onExitActive = useChildCallback(props.onExitActive ?? noop)\n const onExitComplete = useChildCallback(props.onExitComplete ?? noop)\n\n // Ensure all children are provided with keys.\n // Cannot reliably use Children.toArray() because `key` is processed: https://reactjs.org/docs/react-api.html#reactchildrentoarray\n Children.forEach(children, (child) => {\n // @ts-expect-error - We know `key` might not exist on certain types, that's why we're checking\n if (child && !child.key) {\n throw new Error(\"Child elements of <TransitionGroup /> must include a `key`\")\n }\n })\n\n const createDefaultRenderChildProps = useCallback(\n (child: ReactElementWithKey): RenderChild => ({\n component: child,\n shouldRender: true,\n removeChild: () => {\n setRenderChildren((currentRenderChildren) =>\n currentRenderChildren.filter((c) => child.key !== c.component.key),\n )\n },\n onEnter,\n onEnterActive,\n onEnterComplete,\n onExit,\n onExitActive,\n onExitComplete,\n }),\n [onEnter, onEnterActive, onEnterComplete, onExit, onExitActive, onExitComplete],\n )\n\n const [renderChildren, setRenderChildren] = useState<RenderChild[]>((): RenderChild[] => {\n return ChildrenWithKeys(children).map((child) => ({\n ...createDefaultRenderChildProps(child),\n // Lock this value to whatever the value was on initial render of the TransitionGroup.\n // It doesn't make sense to change this once it is mounted.\n preventMountTransition: preventInitialTransition,\n }))\n })\n\n useLayoutEffect(() => {\n setRenderChildren((currentRenderChildren): RenderChild[] => {\n const propChildrenArray = ChildrenWithKeys(children)\n return computeNextRenderChildren(\n propChildrenArray,\n currentRenderChildren,\n createDefaultRenderChildProps,\n insertMethod,\n )\n })\n }, [children, insertMethod, createDefaultRenderChildProps])\n\n // Prevent mistakes with forwardRef() by ensuring single child usage within the group.\n assertSingleChildWhenRef(\"TransitionGroup\", forwardedRef, Children.count(children))\n\n if (disableAnimations) {\n return (\n <>\n {Children.map(children, (child) => (\n <TagName\n // @ts-expect-error -- TS is not happy about this forwardedRef, but it's fine.\n ref={forwardedRef}\n className={className}\n style={style}\n data-transition-id={transitionId}\n >\n {child}\n </TagName>\n ))}\n </>\n )\n }\n\n return (\n <>\n {renderChildren.map(({ component, ...restProps }) => (\n <TransitionGroupChild\n key={component.key}\n {...restProps}\n as={TagName}\n className={className}\n transitionId={transitionId}\n enterDuration={enterDuration}\n exitDuration={exitDuration}\n enterMountDelay={enterMountDelay}\n style={style}\n ref={forwardedRef}\n >\n {component}\n </TransitionGroupChild>\n ))}\n </>\n )\n}\n", "import { isTest } from \"../../lib/constants\"\n\n// By default, all tests will treat <TransitionGroup> as `disableAnimations={true}`,\n// removing the need to be aware of misc. async animations happening across tests.\n// We could add support for things like `prefers-reduced-motion` in the future here as well.\nexport default () => isTest\n", "import React, { Children, useCallback, useRef } from \"react\"\nimport { isDev, isTest } from \"../../lib/constants\"\n\nexport type TransitionDefinition = {\n opacity?: number\n /** The horizontal translation value in pixels */\n x?: number\n /** The horizontal vertical value in pixels */\n y?: number\n /** The opacity value ranging from 0 to 1. */\n scale?: number\n rotate?: number | string\n skewX?: number | string\n skewY?: number | string\n blur?: number\n duration?: number\n delay?: number\n timingFunction?: string\n}\n\nexport type InitialTransitionDefinition = Omit<\n TransitionDefinition,\n \"duration\" | \"delay\" | \"timingFunction\"\n>\n\nexport type LayoutTransitionDefinition = {\n duration?: number\n delay?: number\n timingFunction?: string\n}\n\nexport type CallbackType =\n | \"enter\"\n | \"enter-active\"\n | \"enter-complete\"\n | \"exit\"\n | \"exit-active\"\n | \"exit-complete\"\n\n// Transition callbacks and types shared across implementations\nexport type TransitionGroupChildCallback = (element: HTMLDivElement) => void\n\nexport type TransitionGroupChildCallbacks = {\n /** Callback fired when an enter animation is staged (e.g., component mounted to the DOM) */\n onEnter: TransitionGroupChildCallback\n /** Callback fired when an enter animation starts */\n onEnterActive: TransitionGroupChildCallback\n /** Callback fired when an enter animation completes */\n onEnterComplete: TransitionGroupChildCallback\n /** Callback fired when an exit animation is staged */\n onExit: TransitionGroupChildCallback\n /** Callback fired when an exit animation starts */\n onExitActive: TransitionGroupChildCallback\n /** Callback fired when an exit animation completes (e.g., component unmounted from the DOM) */\n onExitComplete: TransitionGroupChildCallback\n}\n\nexport const NonNullChildren = (children: React.ReactNode) =>\n Children.toArray(children).filter((child) => child !== null && child !== undefined)\n\n// Shared keyed-children and transition helpers\nexport interface ReactElementWithKey extends React.ReactElement {\n key: string\n}\n\nexport const ChildrenWithKeys = (\n children: React.ReactNode,\n shouldThrow: boolean = false,\n componentName: string = \"TransitionGroup\",\n): ReactElementWithKey[] => {\n const validChildren: ReactElementWithKey[] = []\n Children.forEach(children, (child) => {\n if (child && typeof child === \"object\" && \"key\" in child && !!child.key) {\n // @ts-expect-error -- The above conditional is enough coercion that the component is valid\n validChildren.push(child)\n } else if (shouldThrow) {\n throw new Error(`Child elements of <${componentName} /> must include a \\`key\\``)\n }\n })\n return validChildren\n}\n\nexport const noop = () => {}\n\nexport const useChildCallback = (cb: (el: HTMLDivElement) => void) => {\n const ref = useRef(cb)\n ref.current = cb\n return useCallback<(el: HTMLDivElement) => void>((element) => ref.current(element), [])\n}\n\nexport type InsertMethod = \"append\" | \"prepend\"\n\nexport function computeNextRenderChildren<\n RenderChild extends { component: ReactElementWithKey; shouldRender: boolean },\n>(\n propChildrenArray: ReactElementWithKey[],\n currentRenderChildren: RenderChild[],\n createDefaultRenderChildProps: (child: ReactElementWithKey) => RenderChild,\n insertMethod: InsertMethod,\n): RenderChild[] {\n const propChildKeyMap = propChildrenArray.reduce<Record<string, number>>(\n (acc, child) => ({ ...acc, [child.key]: 1 }),\n {},\n )\n const currentRenderChildKeyMap = currentRenderChildren.reduce<Record<string, number>>(\n (acc, child) => ({ ...acc, [child.component.key]: 1 }),\n {},\n )\n\n const newRenderChildren: RenderChild[] = propChildrenArray\n .filter((propChild) => !currentRenderChildKeyMap[propChild.key])\n .map(createDefaultRenderChildProps)\n\n const updatedCurrentChildren: RenderChild[] = currentRenderChildren.map((childProps) => ({\n ...childProps,\n component:\n propChildrenArray.find(({ key }) => key === childProps.component.key) || childProps.component,\n shouldRender: !!propChildKeyMap[childProps.component.key],\n }))\n\n return insertMethod === \"append\"\n ? updatedCurrentChildren.concat(newRenderChildren)\n : newRenderChildren.concat(updatedCurrentChildren)\n}\n\nexport function assertSingleChildWhenRef(\n componentName: string,\n ref: React.Ref<unknown> | undefined,\n childrenCount: number,\n): void {\n if ((isTest || isDev) && ref && childrenCount > 1) {\n throw new Error(`Cannot use forwardRef with multiple children in <${componentName} />`)\n }\n}\n", "export type TransitionState = {\n enter: boolean\n enterActive: boolean\n exit: boolean\n exitActive: boolean\n interrupted: boolean\n}\n\nexport type TransitionStateAction =\n | { type: \"enter-before\" }\n | { type: \"enter-active\" }\n | { type: \"exit-before\" }\n | { type: \"exit-active\" }\n | { type: \"done\" }\n\nexport const RESTING_TRANSITION_STATE: TransitionState = {\n enter: false,\n enterActive: false,\n exit: false,\n exitActive: false,\n interrupted: false,\n}\n\nexport const getInitialTransitionState = (preventMountTransition: boolean): TransitionState => ({\n ...RESTING_TRANSITION_STATE,\n enter: !preventMountTransition,\n})\n\nexport const transitionReducer = (\n state: TransitionState,\n action: TransitionStateAction,\n): TransitionState => {\n switch (action.type) {\n case \"enter-before\":\n return {\n enter: true,\n enterActive: false,\n exit: false,\n exitActive: false,\n interrupted: state.interrupted || state.exit,\n }\n case \"enter-active\":\n return {\n enter: true,\n enterActive: true,\n exit: false,\n exitActive: false,\n interrupted: false,\n }\n case \"exit-before\":\n return {\n enter: false,\n enterActive: false,\n exit: true,\n exitActive: false,\n interrupted: state.interrupted || state.enter,\n }\n case \"exit-active\":\n return {\n enter: false,\n enterActive: false,\n exit: true,\n exitActive: true,\n interrupted: false,\n }\n case \"done\":\n default:\n return RESTING_TRANSITION_STATE\n }\n}\n", "\"use client\"\n\nimport { useEffect, useRef, useState, type MouseEvent } from \"react\"\nimport { copyToClipboard, type ClipboardContent } from \"../../lib/copyToClipboard\"\nimport { Check, Copy } from \"../Icon\"\nimport { Animate } from \"../Transition\"\nimport { Button, type ButtonProps } from \"./Button\"\n\nexport type CopyButtonProps = {\n copyValue: string | ClipboardContent | (() => string) | (() => ClipboardContent)\n children?: React.ReactNode | ((props: { copied: boolean }) => React.ReactNode)\n} & Omit<ButtonProps, \"children\">\n\nexport const CopyButton = ({ children, copyValue, onClick, ...restProps }: CopyButtonProps) => {\n const [copied, setCopied] = useState<boolean>(false)\n const copiedTimeout = useRef<number | null>(null)\n\n const handleClick = (evt: MouseEvent<HTMLButtonElement>) => {\n // No-op when copied is true\n if (copied) {\n return\n }\n\n setCopied(true)\n onClick?.(evt)\n\n // Copy content to clipboard\n // NOTE: Failures are a silent no-op\n copyToClipboard(typeof copyValue === \"function\" ? copyValue() : copyValue)\n\n copiedTimeout.current = window.setTimeout(() => {\n setCopied(false)\n }, 1300)\n }\n\n useEffect(() => {\n return () => {\n if (copiedTimeout.current) clearTimeout(copiedTimeout.current)\n }\n }, [])\n\n return (\n <Button {...restProps} onClick={handleClick}>\n <Animate\n className=\"w-[var(--button-icon-size)] h-[var(--button-icon-size)]\"\n initial={{ scale: 0.6 }}\n enter={{ scale: 1, delay: 150, duration: 300 }}\n exit={{ scale: 0.6, duration: 150 }}\n forceCompositeLayer\n >\n {copied ? <Check key=\"copied-icon\" /> : <Copy key=\"copy-icon\" />}\n </Animate>\n {typeof children === \"function\" ? children({ copied }) : children}\n </Button>\n )\n}\n", "\"use client\"\n\nimport clsx from \"clsx\"\nimport { TransitionGroup, type TransitionGroupProps } from \"./TransitionGroup\"\n\nimport { type CSSProperties } from \"react\"\nimport {\n toCssVariables,\n toFilterProperty,\n toMsDurationProperty,\n toOpacityProperty,\n toTransformProperty,\n} from \"../../lib/helpers\"\nimport s from \"./Animate.module.css\"\nimport { type InitialTransitionDefinition, type TransitionDefinition } from \"./shared\"\n\nexport type AnimateProps = Pick<\n TransitionGroupProps,\n \"as\" | \"children\" | \"className\" | \"insertMethod\" | \"preventInitialTransition\"\n> & {\n /** Class applied to the inner TransitionGroup */\n transitionClassName?: string\n /** Styles applied to the enter transition */\n enter?: TransitionDefinition\n /** Styles applied to the exit transition */\n exit?: TransitionDefinition\n /** Styles applied before the enter transition occurs */\n initial?: InitialTransitionDefinition\n /**\n * Determines how transition states are positioned\n * @default absolute\n */\n transitionPosition?: \"absolute\" | \"static\"\n /**\n * Applies `will-change` to force animating elements to composite layers. Use with caution!\n * @default false\n */\n forceCompositeLayer?: boolean\n}\n\nexport const Animate = (props: AnimateProps) => {\n const {\n as: TagName = \"span\",\n className,\n children,\n preventInitialTransition,\n insertMethod,\n transitionClassName,\n transitionPosition = \"absolute\",\n } = props\n const { enterTotalDuration, exitTotalDuration, variables } = getAnimationProperties(props)\n\n return (\n <TagName\n className={clsx(\"block\", transitionPosition === \"absolute\" && \"relative\", className)}\n data-transition-position={transitionPosition}\n style={variables}\n >\n <TransitionGroup\n as={TagName}\n className={clsx(s.TransitionItem, transitionClassName)}\n enterDuration={enterTotalDuration}\n exitDuration={exitTotalDuration}\n insertMethod={insertMethod}\n preventInitialTransition={preventInitialTransition}\n >\n {children}\n </TransitionGroup>\n </TagName>\n )\n}\n\n// Keep in sync with default values in Animate.module.css\nconst DEFAULT_ENTER_DURATION_MS_EASE = 400\nconst DEFAULT_ENTER_DURATION_MS_CUBIC = 500\nconst DEFAULT_EXIT_DURATION_MS_EASE = 200\nconst DEFAULT_EXIT_DURATION_MS_CUBIC = 300\n\nfunction getAnimationProperties({\n initial: initial,\n enter: enter,\n exit: exit,\n forceCompositeLayer,\n}: AnimateProps): {\n enterTotalDuration: number\n exitTotalDuration: number\n variables: CSSProperties\n} {\n // Dynamically inspect if we're transitioning transform properties, and apply cubic curves and timings as defaults\n const initialTransform = toTransformProperty(initial)\n const enterTransform = toTransformProperty(enter)\n const exitTransform = toTransformProperty(exit)\n const isCubicTransition = [initialTransform, exitTransform, enterTransform].some(\n (t) => t !== \"none\",\n )\n const enterDuration =\n enter?.duration ??\n (isCubicTransition ? DEFAULT_ENTER_DURATION_MS_CUBIC : DEFAULT_ENTER_DURATION_MS_EASE)\n const enterTimingFunction =\n enter?.timingFunction ?? (isCubicTransition ? \"var(--cubic-enter)\" : \"ease\")\n const exitDuration =\n exit?.duration ??\n (isCubicTransition ? DEFAULT_EXIT_DURATION_MS_CUBIC : DEFAULT_EXIT_DURATION_MS_EASE)\n const exitTimingFunction =\n exit?.timingFunction ?? (isCubicTransition ? \"var(--cubic-exit)\" : \"ease\")\n\n // Generate variable overrides from props\n const variables = toCssVariables({\n \"tg-will-change\": forceCompositeLayer ? \"transform, opacity\" : \"auto\",\n \"tg-enter-opacity\": toOpacityProperty(enter?.opacity ?? 1),\n \"tg-enter-transform\": enterTransform,\n \"tg-enter-filter\": toFilterProperty(enter),\n \"tg-enter-duration\": toMsDurationProperty(enterDuration),\n \"tg-enter-delay\": toMsDurationProperty(enter?.delay ?? 0),\n \"tg-enter-timing-function\": enterTimingFunction,\n \"tg-exit-opacity\": toOpacityProperty(exit?.opacity ?? 0),\n \"tg-exit-transform\": exitTransform,\n \"tg-exit-filter\": toFilterProperty(exit),\n \"tg-exit-duration\": toMsDurationProperty(exitDuration),\n \"tg-exit-delay\": toMsDurationProperty(exit?.delay ?? 0),\n \"tg-exit-timing-function\": exitTimingFunction,\n \"tg-initial-opacity\": toOpacityProperty(initial?.opacity ?? exit?.opacity ?? 0),\n \"tg-initial-transform\": initialTransform === \"none\" ? exitTransform : initialTransform,\n \"tg-initial-filter\": toFilterProperty(initial ?? exit ?? {}),\n } satisfies Record<string, string>)\n\n const enterTotalDuration = (enter?.delay ?? 0) + enterDuration\n const exitTotalDuration = (exit?.delay ?? 0) + exitDuration\n\n return { enterTotalDuration, exitTotalDuration, variables }\n}\n", "\"use client\"\n\nimport clsx from \"clsx\"\nimport { useRef, type CSSProperties } from \"react\"\nimport {\n toCssVariables,\n toFilterProperty,\n toMsDurationProperty,\n toOpacityProperty,\n toTransformProperty,\n waitForAnimationFrame,\n} from \"../../lib/helpers\"\nimport s from \"./AnimateLayout.module.css\"\nimport { TransitionGroup, type TransitionGroupProps } from \"./TransitionGroup\"\nimport {\n type InitialTransitionDefinition,\n type LayoutTransitionDefinition,\n type TransitionDefinition,\n} from \"./shared\"\n\nexport type AnimateLayoutProps = Pick<\n TransitionGroupProps,\n \"as\" | \"children\" | \"className\" | \"insertMethod\" | \"preventInitialTransition\"\n> & {\n /**\n * Determines if `overflow: hidden` is applied to the wrapper element\n * @default false\n */\n hideOverflow?: boolean\n /**\n * Determines which side of the container the items will pin to during enter/exit\n * @default \"start\"\n */\n itemAnchor?: \"start\" | \"end\"\n /**\n * Determines which property will be animated during transitions\n * @default \"height\"\n */\n dimension?: \"width\" | \"height\"\n layoutEnter?: LayoutTransitionDefinition\n layoutExit?: LayoutTransitionDefinition\n layoutMove?: LayoutTransitionDefinition\n\n enter?: TransitionDefinition\n exit?: TransitionDefinition\n initial?: InitialTransitionDefinition\n /** Class applied to the inner TransitionGroup */\n transitionClassName?: string\n /**\n * Applies `will-change` to force animating elements to composite layers. Use with caution!\n * @default false\n */\n forceCompositeLayer?: boolean\n}\n\nexport const AnimateLayout = (props: AnimateLayoutProps) => {\n const {\n as: TagName = \"span\",\n children,\n transitionClassName,\n insertMethod,\n className,\n hideOverflow = false,\n // An initial height animation will almost never be correct. Consider carefully when overriding.\n preventInitialTransition = true,\n itemAnchor = \"start\",\n dimension = \"height\",\n } = props\n const containerRef = useRef<HTMLDivElement | null>(null)\n const captainRef = useRef<HTMLDivElement | null>(null)\n const exitTimestampRef = useRef<number | null>(null)\n\n const { enterTotalDuration, exitTotalDuration, variables } = getAnimationProperties(props)\n\n const handleEnter = (element: HTMLDivElement) => {\n const container = containerRef.current\n\n if (!container) {\n return\n }\n\n // If handleExit() was called >50ms ago, consider this a \"move\" and don't touch \"interrupted\" state\n const justExited = exitTimestampRef.current && Date.now() - exitTimestampRef.current < 50\n\n const anotherCaptain = !!captainRef.current\n // Look at me, I'm the captain now\n captainRef.current = element\n\n // Recent exits are a near guarantee we are \"moving\" states\n container.dataset.direction = justExited || anotherCaptain ? \"move\" : \"in\"\n\n // If we just exited, don't touch the interrupted state. Exit just set it with the correct state of things\n if (!justExited) {\n container.dataset.interrupted = String(!!container.style[dimension])\n }\n\n const clientRect = container.getBoundingClientRect()\n container.style[dimension] = `${clientRect[dimension]}px`\n }\n\n const handleEnterActive = (element: HTMLDivElement) => {\n const container = containerRef.current\n\n if (!container) {\n return\n }\n\n // ~Impossible to not be the captain at this point, but check anyway.\n const amICaptain = captainRef.current === element\n if (!amICaptain) {\n return\n }\n\n // IMPORTANT: Use clientHeight/clientWidth to measure children, in case they have scale() applied\n const value = dimension === \"width\" ? element.clientWidth : element.clientHeight\n container.style[dimension] = `${value}px`\n }\n\n const handleEnterComplete = (element: HTMLDivElement) => {\n const container = containerRef.current\n\n // Wait for the next tick, to ensure React has cleared `[data-entering*]` state from the DOM\n // Without this, it's possible that we release the height from the container\n // before the children in the DOM are naturally positioned (non-absolute).\n waitForAnimationFrame(() => {\n const amICaptain = captainRef.current === element\n if (!container || !amICaptain) {\n return\n }\n\n // Restore natural height to the DOM node\n container.style[dimension] = \"\"\n })\n }\n\n const handleExit = (element: HTMLDivElement) => {\n const container = containerRef.current\n const amICaptain = !captainRef.current || captainRef.current === element\n\n if (!container || !amICaptain) {\n return\n }\n\n // o7\n captainRef.current = null\n exitTimestampRef.current = Date.now()\n\n container.dataset.direction = \"out\"\n container.dataset.interrupted = String(!!container.style[dimension])\n\n const clientRect = container.getBoundingClientRect()\n container.style[dimension] = `${clientRect[dimension]}px`\n }\n\n const handleExitActive = (_element: HTMLDivElement) => {\n const container = containerRef.current\n const newCaptainExists = !!captainRef.current\n\n // If another component has become the captain, exit early\n if (!container || newCaptainExists) {\n return\n }\n\n // Animate to zero layout\n container.style[dimension] = \"0\"\n }\n\n const handleExitComplete = (_element: HTMLDivElement) => {\n // Wait for the next tick, to ensure React has cleared `[data-exiting*]` state from the DOM\n waitForAnimationFrame(() => {\n const container = containerRef.current\n const newCaptainExists = !!captainRef.current\n\n // If another component has become the captain, exit early\n if (!container || newCaptainExists) {\n return\n }\n\n // Restore natural height to the DOM node\n container.style[dimension] = \"\"\n })\n }\n\n return (\n <TagName\n ref={containerRef}\n className={clsx(s.Layout, className)}\n style={variables}\n data-item-anchor={itemAnchor}\n data-clip={hideOverflow}\n data-dimension={dimension}\n >\n <TransitionGroup\n as={TagName}\n className={clsx(s.TransitionItem, transitionClassName)}\n insertMethod={insertMethod}\n enterDuration={enterTotalDuration}\n exitDuration={exitTotalDuration}\n preventInitialTransition={preventInitialTransition}\n onEnter={handleEnter}\n onEnterActive={handleEnterActive}\n onEnterComplete={handleEnterComplete}\n onExit={handleExit}\n onExitActive={handleExitActive}\n onExitComplete={handleExitComplete}\n >\n {children}\n </TransitionGroup>\n </TagName>\n )\n}\n\n// Keep in sync with default values in AnimateLayout.module.css\nconst DEFAULT_LAYOUT_ENTER_DURATION_MS = 300\nconst DEFAULT_LAYOUT_ENTER_DELAY_MS = 0\nconst DEFAULT_LAYOUT_EXIT_DURATION_MS = 300\nconst DEFAULT_LAYOUT_EXIT_DELAY_MS = 0\nconst DEFAULT_LAYOUT_MOVE_DURATION_MS = 300\nconst DEFAULT_LAYOUT_MOVE_DELAY_MS = 0\nconst DEFAULT_ENTER_DURATION_MS_EASE = 300\nconst DEFAULT_ENTER_DURATION_MS_CUBIC = 300\nconst DEFAULT_ENTER_DELAY_MS = 100\nconst DEFAULT_EXIT_DURATION_MS_EASE = 200\nconst DEFAULT_EXIT_DURATION_MS_CUBIC = 200\nconst DEFAULT_EXIT_DELAY_MS = 0\n\nfunction getAnimationProperties({\n initial,\n enter,\n exit,\n forceCompositeLayer,\n layoutEnter,\n layoutExit,\n layoutMove,\n}: AnimateLayoutProps): {\n enterTotalDuration: number\n exitTotalDuration: number\n variables: CSSProperties\n} {\n // Dynamically inspect if we're transitioning transform properties, and apply cubic curves and timings as defaults\n const initialTransform = toTransformProperty(initial)\n const enterTransform = toTransformProperty(enter)\n const exitTransform = toTransformProperty(exit)\n const isCubicTransition = [initialTransform, exitTransform, enterTransform].some(\n (t) => t !== \"none\",\n )\n const enterDuration =\n enter?.duration ??\n (isCubicTransition ? DEFAULT_ENTER_DURATION_MS_CUBIC : DEFAULT_ENTER_DURATION_MS_EASE)\n const enterTimingFunction =\n enter?.timingFunction ?? (isCubicTransition ? \"var(--cubic-enter)\" : \"ease\")\n const exitDuration =\n exit?.duration ??\n (isCubicTransition ? DEFAULT_EXIT_DURATION_MS_CUBIC : DEFAULT_EXIT_DURATION_MS_EASE)\n const exitTimingFunction =\n exit?.timingFunction ?? (isCubicTransition ? \"var(--cubic-exit)\" : \"ease\")\n\n // Generate variable overrides from props\n const variables = toCssVariables({\n \"tg-will-change\": forceCompositeLayer ? \"transform, opacity\" : \"auto\",\n \"tg-enter-opacity\": toOpacityProperty(enter?.opacity ?? 1),\n \"tg-enter-transform\": enterTransform,\n \"tg-enter-filter\": toFilterProperty(enter),\n \"tg-enter-duration\": toMsDurationProperty(enterDuration),\n \"tg-enter-delay\": toMsDurationProperty(enter?.delay ?? DEFAULT_ENTER_DELAY_MS),\n \"tg-enter-timing-function\": enterTimingFunction,\n \"tg-exit-opacity\": toOpacityProperty(exit?.opacity ?? 0),\n \"tg-exit-transform\": exitTransform,\n \"tg-exit-filter\": toFilterProperty(exit ?? {}),\n \"tg-exit-duration\": toMsDurationProperty(exitDuration),\n \"tg-exit-delay\": toMsDurationProperty(exit?.delay ?? DEFAULT_EXIT_DELAY_MS),\n \"tg-exit-timing-function\": exitTimingFunction,\n \"tg-initial-opacity\": toOpacityProperty(initial?.opacity ?? exit?.opacity ?? 0),\n \"tg-initial-transform\": initialTransform === \"none\" ? exitTransform : initialTransform,\n \"tg-initial-filter\": toFilterProperty(initial ?? exit ?? {}),\n \"tg-layout-enter-duration\": toMsDurationProperty(\n layoutEnter?.duration ?? DEFAULT_LAYOUT_ENTER_DURATION_MS,\n ),\n \"tg-layout-enter-delay\": toMsDurationProperty(\n layoutEnter?.delay ?? DEFAULT_LAYOUT_ENTER_DELAY_MS,\n ),\n \"tg-layout-enter-timing-function\": layoutEnter?.timingFunction ?? \"var(--cubic-move)\",\n \"tg-layout-exit-duration\": toMsDurationProperty(\n layoutExit?.duration ?? DEFAULT_LAYOUT_EXIT_DURATION_MS,\n ),\n \"tg-layout-exit-delay\": toMsDurationProperty(layoutExit?.delay ?? DEFAULT_LAYOUT_EXIT_DELAY_MS),\n \"tg-layout-exit-timing-function\": layoutExit?.timingFunction ?? \"var(--cubic-move)\",\n \"tg-layout-move-duration\": toMsDurationProperty(\n layoutMove?.duration ?? DEFAULT_LAYOUT_MOVE_DURATION_MS,\n ),\n \"tg-layout-move-delay\": toMsDurationProperty(layoutMove?.delay ?? DEFAULT_LAYOUT_MOVE_DELAY_MS),\n \"tg-layout-move-timing-function\": layoutMove?.timingFunction ?? \"var(--cubic-move)\",\n } satisfies Record<string, string>)\n\n const enterTotalDuration =\n (enter?.delay ?? DEFAULT_ENTER_DELAY_MS) + (enterDuration ?? DEFAULT_ENTER_DURATION_MS_EASE)\n const exitTotalDuration =\n (exit?.delay ?? DEFAULT_EXIT_DELAY_MS) + (exitDuration ?? DEFAULT_EXIT_DURATION_MS_EASE)\n const layoutEnterTotalDuration =\n (layoutEnter?.delay ?? DEFAULT_LAYOUT_ENTER_DELAY_MS) +\n (layoutEnter?.duration ?? DEFAULT_LAYOUT_ENTER_DURATION_MS)\n const layoutExitTotalDuration =\n (layoutExit?.delay ?? DEFAULT_LAYOUT_EXIT_DELAY_MS) +\n (layoutExit?.duration ?? DEFAULT_LAYOUT_EXIT_DURATION_MS)\n const layoutMoveTotalDuration =\n (layoutMove?.delay ?? DEFAULT_LAYOUT_MOVE_DELAY_MS) +\n (layoutMove?.duration ?? DEFAULT_LAYOUT_MOVE_DURATION_MS)\n\n return {\n // In order for us to release layout dimensions (e.g., height) to the natural DOM state,\n // we must ensure the behaviors from the TransitionGroup callbacks are synced with the outer layout `transitions`.\n // Setting TransitionGroup timing to the max of these durations is the simplest approach.\n // In practice, these should only vary by about 50-200ms at most; imperceivable to end-users.\n enterTotalDuration: Math.max(\n enterTotalDuration,\n layoutEnterTotalDuration,\n layoutMoveTotalDuration,\n ),\n exitTotalDuration: Math.max(\n exitTotalDuration,\n layoutExitTotalDuration,\n layoutMoveTotalDuration,\n ),\n variables,\n }\n}\n", "\"use client\"\n\nimport { TransitionGroup, type TransitionGroupProps } from \"./TransitionGroup\"\n\nimport clsx from \"clsx\"\nimport { type CSSProperties } from \"react\"\nimport {\n toCssVariables,\n toFilterProperty,\n toMsDurationProperty,\n toOpacityProperty,\n toTransformProperty,\n waitForAnimationFrame,\n} from \"../../lib/helpers\"\nimport s from \"./AnimateLayoutGroup.module.css\"\nimport {\n type InitialTransitionDefinition,\n type LayoutTransitionDefinition,\n NonNullChildren,\n type TransitionDefinition,\n} from \"./shared\"\n\nexport type AnimateLayoutGroupProps = Pick<\n TransitionGroupProps,\n \"as\" | \"children\" | \"className\" | \"insertMethod\" | \"preventInitialTransition\"\n> & {\n /**\n * Determines if `overflow: hidden` is applied to the wrapper element\n * @default false\n */\n hideOverflow?: boolean\n /**\n * Determines which side of the container the items will pin to during enter/exit\n * @default \"start\"\n */\n itemAnchor?: \"start\" | \"end\"\n /**\n * Determines which property will be animated during transitions\n * @default \"height\"\n */\n dimension?: \"width\" | \"height\"\n layoutEnter?: LayoutTransitionDefinition\n layoutExit?: LayoutTransitionDefinition\n layoutMove?: LayoutTransitionDefinition\n\n enter?: TransitionDefinition\n exit?: TransitionDefinition\n initial?: InitialTransitionDefinition\n /** Class applied to the inner TransitionGroup */\n transitionClassName?: string\n /**\n * Applies `will-change` to force animating elements to composite layers. Use with caution!\n * @default false\n */\n forceCompositeLayer?: boolean\n}\n\nexport const AnimateLayoutGroup = (props: AnimateLayoutGroupProps) => {\n const {\n as: TagName = \"span\",\n children,\n className,\n transitionClassName,\n dimension = \"height\",\n } = props\n const { enterTotalDuration, exitTotalDuration, variables } = getAnimationProperties(props)\n\n const handleEnter = (element: HTMLDivElement) => {\n // Stage zero layout\n element.style[dimension] = \"0\"\n }\n\n const handleEnterActive = (element: HTMLDivElement) => {\n waitForAnimationFrame(() => {\n // Animate to target height\n // IMPORTANT: Use clientHeight/clientWidth to measure children, in case they have scale() applied\n const value =\n dimension === \"width\"\n ? element.firstElementChild?.clientWidth\n : element.firstElementChild?.clientHeight\n\n element.style[dimension] = `${value ?? 0}px`\n })\n }\n\n const handleEnterComplete = (element: HTMLDivElement) => {\n waitForAnimationFrame(() => {\n // Restore natural layout to the DOM node\n element.style[dimension] = \"\"\n })\n }\n\n const handleExit = (element: HTMLDivElement) => {\n element.style[dimension] = `${element.getBoundingClientRect()[dimension]}px`\n }\n\n const handleExitActive = (element: HTMLDivElement) => {\n waitForAnimationFrame(() => {\n // Animate to zero layout\n element.style[dimension] = \"0\"\n })\n }\n\n return (\n <TransitionGroup\n as={TagName}\n className={clsx(s.LayoutItem, className)}\n style={variables}\n // Adding 32ms to timers because of the additional waitForAnimationFrame() calls\n enterDuration={enterTotalDuration + 32}\n exitDuration={exitTotalDuration + 32}\n onEnter={handleEnter}\n onEnterActive={handleEnterActive}\n onEnterComplete={handleEnterComplete}\n onExit={handleExit}\n onExitActive={handleExitActive}\n >\n {NonNullChildren(children).map((child) => (\n // Ensure any falsy child.key value is sent specifically as `undefined`.\n // This ensures that key is not misinterpreted as a string 'null', 'false', etc.\n <TagName\n className={clsx(s.TransitionItem, transitionClassName)}\n // @ts-expect-error Pass-through the validation of `key` to <TransitionGroup>\n key={child.key || undefined}\n data-dimension={dimension}\n >\n {child}\n </TagName>\n ))}\n </TransitionGroup>\n )\n}\n\n// Keep in sync with default values in AnimateLayout.module.css\nconst DEFAULT_LAYOUT_ENTER_DURATION_MS = 300\nconst DEFAULT_LAYOUT_ENTER_DELAY_MS = 0\nconst DEFAULT_LAYOUT_EXIT_DURATION_MS = 300\nconst DEFAULT_LAYOUT_EXIT_DELAY_MS = 50\nconst DEFAULT_LAYOUT_MOVE_DURATION_MS = 300\nconst DEFAULT_LAYOUT_MOVE_DELAY_MS = 0\nconst DEFAULT_ENTER_DURATION_MS_EASE = 400\nconst DEFAULT_ENTER_DURATION_MS_CUBIC = 400\nconst DEFAULT_ENTER_DELAY_MS = 150\nconst DEFAULT_EXIT_DURATION_MS_EASE = 200\nconst DEFAULT_EXIT_DURATION_MS_CUBIC = 300\nconst DEFAULT_EXIT_DELAY_MS = 0\n\nfunction getAnimationProperties({\n initial,\n enter,\n exit,\n forceCompositeLayer,\n layoutEnter,\n layoutExit,\n layoutMove,\n}: AnimateLayoutGroupProps): {\n enterTotalDuration: number\n exitTotalDuration: number\n variables: CSSProperties\n} {\n // Dynamically inspect if we're transitioning transform properties, and apply cubic curves and timings as defaults\n const initialTransform = toTransformProperty(initial)\n const enterTransform = toTransformProperty(enter)\n const exitTransform = toTransformProperty(exit)\n const isCubicTransition = [initialTransform, exitTransform, enterTransform].some(\n (t) => t !== \"none\",\n )\n const enterDuration =\n enter?.duration ??\n (isCubicTransition ? DEFAULT_ENTER_DURATION_MS_CUBIC : DEFAULT_ENTER_DURATION_MS_EASE)\n const enterTimingFunction =\n enter?.timingFunction ?? (isCubicTransition ? \"var(--cubic-enter)\" : \"ease\")\n const exitDuration =\n exit?.duration ??\n (isCubicTransition ? DEFAULT_EXIT_DURATION_MS_CUBIC : DEFAULT_EXIT_DURATION_MS_EASE)\n const exitTimingFunction =\n exit?.timingFunction ?? (isCubicTransition ? \"var(--cubic-exit)\" : \"ease\")\n\n // Generate variable overrides from props\n const variables = toCssVariables({\n \"tg-will-change\": forceCompositeLayer ? \"transform, opacity\" : \"auto\",\n \"tg-enter-opacity\": toOpacityProperty(enter?.opacity ?? 1),\n \"tg-enter-transform\": enterTransform,\n \"tg-enter-filter\": toFilterProperty(enter ?? {}),\n \"tg-enter-duration\": toMsDurationProperty(enterDuration),\n \"tg-enter-delay\": toMsDurationProperty(enter?.delay ?? DEFAULT_ENTER_DELAY_MS),\n \"tg-enter-timing-function\": enterTimingFunction,\n \"tg-exit-opacity\": toOpacityProperty(exit?.opacity ?? 0),\n \"tg-exit-transform\": exitTransform,\n \"tg-exit-filter\": toFilterProperty(exit ?? {}),\n \"tg-exit-duration\": toMsDurationProperty(exitDuration),\n \"tg-exit-delay\": toMsDurationProperty(exit?.delay ?? DEFAULT_EXIT_DELAY_MS),\n \"tg-exit-timing-function\": exitTimingFunction,\n \"tg-initial-opacity\": toOpacityProperty(initial?.opacity ?? exit?.opacity ?? 0),\n \"tg-initial-transform\": initialTransform === \"none\" ? exitTransform : initialTransform,\n \"tg-initial-filter\": toFilterProperty(initial ?? exit ?? {}),\n \"tg-layout-enter-duration\": toMsDurationProperty(\n layoutEnter?.duration ?? DEFAULT_LAYOUT_ENTER_DURATION_MS,\n ),\n \"tg-layout-enter-delay\": toMsDurationProperty(\n layoutEnter?.delay ?? DEFAULT_LAYOUT_ENTER_DELAY_MS,\n ),\n \"tg-layout-enter-timing-function\": layoutEnter?.timingFunction ?? \"var(--cubic-move)\",\n \"tg-layout-exit-duration\": toMsDurationProperty(\n layoutExit?.duration ?? DEFAULT_LAYOUT_EXIT_DURATION_MS,\n ),\n \"tg-layout-exit-delay\": toMsDurationProperty(layoutExit?.delay ?? DEFAULT_LAYOUT_EXIT_DELAY_MS),\n \"tg-layout-exit-timing-function\": layoutExit?.timingFunction ?? \"var(--cubic-move)\",\n \"tg-layout-move-duration\": toMsDurationProperty(\n layoutMove?.duration ?? DEFAULT_LAYOUT_MOVE_DURATION_MS,\n ),\n \"tg-layout-move-delay\": toMsDurationProperty(\n layoutMove?.delay ?? DEFAULT_LAYOUT_MOVE_DURATION_MS,\n ),\n \"tg-layout-move-timing-function\": layoutMove?.timingFunction ?? \"var(--cubic-move)\",\n } satisfies Record<string, string>)\n\n const enterTotalDuration =\n (enter?.delay ?? DEFAULT_ENTER_DELAY_MS) + (enterDuration ?? DEFAULT_ENTER_DURATION_MS_EASE)\n const exitTotalDuration =\n (exit?.delay ?? DEFAULT_EXIT_DELAY_MS) + (exitDuration ?? DEFAULT_EXIT_DURATION_MS_EASE)\n const layoutEnterTotalDuration =\n (layoutEnter?.delay ?? DEFAULT_LAYOUT_ENTER_DELAY_MS) +\n (layoutEnter?.duration ?? DEFAULT_LAYOUT_ENTER_DURATION_MS)\n const layoutExitTotalDuration =\n (layoutExit?.delay ?? DEFAULT_LAYOUT_EXIT_DELAY_MS) +\n (layoutExit?.duration ?? DEFAULT_LAYOUT_EXIT_DURATION_MS)\n const layoutMoveTotalDuration =\n (layoutMove?.delay ?? DEFAULT_LAYOUT_MOVE_DELAY_MS) +\n (layoutMove?.duration ?? DEFAULT_LAYOUT_MOVE_DURATION_MS)\n\n return {\n // In order for us to release layout dimensions (e.g., height) to the natural DOM state,\n // we must ensure the behaviors from the TransitionGroup callbacks are synced with the outer layout `transitions`.\n // Setting TransitionGroup timing to the max of these durations is the simplest approach.\n // In practice, these should only vary by about 50-200ms at most; imperceivable to end-users.\n enterTotalDuration: Math.max(\n enterTotalDuration,\n layoutEnterTotalDuration,\n layoutMoveTotalDuration,\n ),\n exitTotalDuration: Math.max(\n exitTotalDuration,\n layoutExitTotalDuration,\n layoutMoveTotalDuration,\n ),\n variables,\n }\n}\n", "\"use client\"\n\nimport React, {\n Children,\n useCallback,\n useEffect,\n useLayoutEffect,\n useReducer,\n useRef,\n useState,\n} from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\n\nimport { waitForAnimationFrame } from \"../../lib/helpers\"\n\n// (no-op) clsx removed: className is not managed at group-level for slotted children\nimport { useTimeout } from \"usehooks-ts\"\nimport getDisableAnimations from \"./getDisableAnimations\"\nimport {\n assertSingleChildWhenRef,\n ChildrenWithKeys,\n computeNextRenderChildren,\n noop,\n useChildCallback,\n type CallbackType,\n type ReactElementWithKey,\n type TransitionGroupChildCallbacks,\n} from \"./shared\"\nimport { getInitialTransitionState, transitionReducer } from \"./transitionReducer\"\n\ntype SlotTransitionGroupChildProps = {\n component: ReactElementWithKey\n preventMountTransition?: boolean\n shouldRender: boolean\n enterDuration: number\n exitDuration: number\n enterMountDelay?: number\n removeChild: () => void\n ref?: React.Ref<unknown>\n} & TransitionGroupChildCallbacks\n\nconst SlotTransitionGroupChildInner = ({\n ref,\n component,\n preventMountTransition,\n shouldRender,\n enterDuration,\n exitDuration,\n removeChild,\n onEnter,\n onEnterActive,\n onEnterComplete,\n onExit,\n onExitActive,\n onExitComplete,\n}: SlotTransitionGroupChildProps) => {\n const [state, dispatch] = useReducer(\n transitionReducer,\n getInitialTransitionState(preventMountTransition || false),\n )\n const preventedMountTransition = useRef<boolean>(false)\n const elementRef = useRef<HTMLDivElement | null>(null)\n const enterDurationRef = useRef<number>(enterDuration)\n enterDurationRef.current = enterDuration\n const exitDurationRef = useRef<number>(exitDuration)\n exitDurationRef.current = exitDuration\n\n const lastCallbackRef = useRef<CallbackType>(null as unknown as CallbackType)\n const triggerCallback = useCallback(\n (callbackType: CallbackType) => {\n const element = elementRef.current\n if (!element || callbackType === lastCallbackRef.current) {\n return\n }\n lastCallbackRef.current = callbackType\n switch (callbackType) {\n case \"enter\":\n onEnter(element)\n break\n case \"enter-active\":\n onEnterActive(element)\n break\n case \"enter-complete\":\n onEnterComplete(element)\n break\n case \"exit\":\n onExit(element)\n break\n case \"exit-active\":\n onExitActive(element)\n break\n case \"exit-complete\":\n onExitComplete(element)\n break\n default:\n callbackType satisfies never\n break\n }\n },\n [onEnter, onEnterActive, onEnterComplete, onExit, onExitActive, onExitComplete],\n )\n\n /**\n * IMPORTANT: `useLayoutEffect()` is used here to avoid race conditions between new SlotTransitionGroupChild components.\n */\n useLayoutEffect(() => {\n // Exit transition\n if (!shouldRender) {\n let exitTimeout: number | undefined\n\n dispatch({ type: \"exit-before\" })\n triggerCallback(\"exit\")\n\n const cancelAnimationFrame = waitForAnimationFrame(() => {\n dispatch({ type: \"exit-active\" })\n triggerCallback(\"exit-active\")\n\n exitTimeout = window.setTimeout(() => {\n triggerCallback(\"exit-complete\")\n removeChild()\n }, exitDurationRef.current)\n })\n\n return () => {\n cancelAnimationFrame()\n if (exitTimeout !== undefined) clearTimeout(exitTimeout)\n }\n }\n\n // Enter transition\n\n // Check if we need to prevent this specific entering cycle\n if (preventMountTransition && !preventedMountTransition.current) {\n // Mark initial transition as prevented and short-circuit.\n preventedMountTransition.current = true\n return\n }\n\n let enterTimeout: number | undefined\n\n dispatch({ type: \"enter-before\" })\n triggerCallback(\"enter\")\n\n const cancelAnimationFrame = waitForAnimationFrame(() => {\n dispatch({ type: \"enter-active\" })\n triggerCallback(\"enter-active\")\n\n enterTimeout = window.setTimeout(() => {\n dispatch({ type: \"done\" })\n triggerCallback(\"enter-complete\")\n }, enterDurationRef.current)\n })\n\n return () => {\n cancelAnimationFrame()\n if (enterTimeout !== undefined) clearTimeout(enterTimeout)\n }\n }, [\n shouldRender,\n // This value is immutable after <SlotTransitionGroup> is created, and does not change on re-renders.\n preventMountTransition,\n removeChild,\n triggerCallback,\n ])\n\n useEffect(() => {\n // Required for <StrictMode>\n return () => {\n preventedMountTransition.current = false\n }\n }, [])\n\n const original = component\n\n const mergedRef = mergeRefs<unknown>([\n elementRef as unknown as React.Ref<unknown>,\n ref as unknown as React.Ref<unknown>,\n ((original as unknown as { ref?: React.Ref<unknown> }).ref ?? null) as React.Ref<unknown>,\n ])\n\n const nextProps = {\n \"data-entering\": state.enter ? \"\" : undefined,\n \"data-entering-active\": state.enterActive ? \"\" : undefined,\n \"data-exiting\": state.exit ? \"\" : undefined,\n \"data-exiting-active\": state.exitActive ? \"\" : undefined,\n \"data-interrupted\": state.interrupted ? \"\" : undefined,\n \"ref\": mergedRef,\n }\n\n return React.isValidElement(original) ? React.cloneElement(original, nextProps) : null\n}\n\nconst SlotTransitionGroupChild = (props: SlotTransitionGroupChildProps) => {\n const { enterMountDelay, preventMountTransition } = props\n const mountDelay = !preventMountTransition && enterMountDelay != null ? enterMountDelay : null\n const [mounted, setMounted] = useState(mountDelay == null)\n useTimeout(() => setMounted(true), mounted ? null : mountDelay)\n\n return mounted ? <SlotTransitionGroupChildInner {...props} /> : null\n}\n\nexport type SlotTransitionGroupProps = {\n /** Components controlled by SlotTransitionGroup rendering */\n children: React.ReactNode\n /** Determines the amount of time that the enter state is applied during mounting */\n enterDuration?: number\n /** Determines the amount of time that the exit state is applied before unmounting */\n exitDuration?: number\n /**\n * Determines if children should have an enter transition applied during mounting of the group.\n * @default true\n */\n preventInitialTransition?: boolean\n /** Delay in MS to wait before mounting a child. `null` for no delay (default). */\n enterMountDelay?: number\n /** Render children changes immediately, bypassing transition timings */\n disableAnimations?: boolean\n /** Determines how new children are added to the children array */\n insertMethod?: \"append\" | \"prepend\"\n /** Ref for the SlotTransitionGroup (applied to the single child when possible) */\n ref?: React.Ref<unknown>\n} & Partial<TransitionGroupChildCallbacks>\n\ntype RenderChild = {\n component: ReactElementWithKey\n shouldRender: boolean\n preventMountTransition?: boolean\n removeChild: () => void\n} & TransitionGroupChildCallbacks\n\nexport const SlotTransitionGroup = (props: SlotTransitionGroupProps) => {\n const {\n ref,\n children,\n enterDuration = 0,\n exitDuration = 0,\n preventInitialTransition = true,\n enterMountDelay,\n insertMethod = \"append\",\n disableAnimations = getDisableAnimations(),\n } = props\n\n // Create stable, mutable references for all callbacks\n const onEnter = useChildCallback(props.onEnter ?? noop)\n const onEnterActive = useChildCallback(props.onEnterActive ?? noop)\n const onEnterComplete = useChildCallback(props.onEnterComplete ?? noop)\n const onExit = useChildCallback(props.onExit ?? noop)\n const onExitActive = useChildCallback(props.onExitActive ?? noop)\n const onExitComplete = useChildCallback(props.onExitComplete ?? noop)\n\n // Ensure all children are provided with keys.\n Children.forEach(children, (child) => {\n // @ts-expect-error - We know `key` might not exist on certain types, that's why we're checking\n if (child && !child.key) {\n throw new Error(\"Child elements of <SlotTransitionGroup /> must include a `key`\")\n }\n })\n\n const createDefaultRenderChildProps = useCallback(\n (child: ReactElementWithKey): RenderChild => ({\n component: child,\n shouldRender: true,\n removeChild: () => {\n setRenderChildren((currentRenderChildren) =>\n currentRenderChildren.filter((c) => child.key !== c.component.key),\n )\n },\n onEnter,\n onEnterActive,\n onEnterComplete,\n onExit,\n onExitActive,\n onExitComplete,\n }),\n [onEnter, onEnterActive, onEnterComplete, onExit, onExitActive, onExitComplete],\n )\n\n const [renderChildren, setRenderChildren] = useState<RenderChild[]>((): RenderChild[] => {\n return ChildrenWithKeys(children).map((child) => ({\n ...createDefaultRenderChildProps(child),\n // Lock this value to whatever the value was on initial render of the group.\n preventMountTransition: preventInitialTransition,\n }))\n })\n\n // IMPORTANT: useLayoutEffect is required to satisfy render timings for prop updates to input elements\n useLayoutEffect(() => {\n setRenderChildren((currentRenderChildren): RenderChild[] => {\n const propChildrenArray = ChildrenWithKeys(children, false, \"SlotTransitionGroup\")\n return computeNextRenderChildren(\n propChildrenArray,\n currentRenderChildren,\n createDefaultRenderChildProps,\n insertMethod,\n )\n })\n }, [children, insertMethod, createDefaultRenderChildProps])\n\n // Prevent mistakes with forwardRef() by ensuring single child usage within the group.\n assertSingleChildWhenRef(\"SlotTransitionGroup\", ref, Children.count(children))\n\n if (disableAnimations) {\n // Fast path: when animations are disabled and no ref is provided, render children as-is.\n if (!ref) {\n return <>{children}</>\n }\n\n // If a ref is provided, attach it to the (single) child by cloning.\n return (\n <>\n {Children.map(children, (child) => {\n if (!React.isValidElement(child)) return child\n const original = child as ReactElementWithKey\n const merged = mergeRefs<unknown>([\n ref as unknown as React.Ref<unknown>,\n ((original as unknown as { ref?: React.Ref<unknown> }).ref ??\n null) as React.Ref<unknown>,\n ])\n const nextProps = { ref: merged }\n return React.cloneElement(original, nextProps)\n })}\n </>\n )\n }\n\n return (\n <>\n {renderChildren.map(({ component, ...restProps }) => (\n <SlotTransitionGroupChild\n key={component.key}\n {...restProps}\n component={component}\n enterDuration={enterDuration}\n exitDuration={exitDuration}\n enterMountDelay={enterMountDelay}\n ref={ref}\n />\n ))}\n </>\n )\n}\n", "\"use client\"\n\nimport { Tooltip as RadixTooltip } from \"radix-ui\"\nimport { useRef, useState } from \"react\"\nimport { copyText } from \"../../lib/copyToClipboard\"\nimport { Check, Copy } from \"../Icon\"\nimport { Tooltip } from \"./Tooltip\"\n\nexport type CopyTooltipProps = {\n children: React.ReactNode\n /** Value to copy to the clipboard */\n copyValue: string\n /**\n * Delay of when the tooltip is shown from first interaction, in milliseconds.\n * @default 150\n */\n openDelay?: number\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: RadixTooltip.TooltipContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: RadixTooltip.TooltipContentProps[\"alignOffset\"]\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default top\n */\n side?: RadixTooltip.TooltipContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 5\n */\n sideOffset?: RadixTooltip.TooltipContentProps[\"sideOffset\"]\n}\n\nexport const CopyTooltip = ({\n children,\n copyValue,\n openDelay = 150,\n align = \"center\",\n alignOffset = 0,\n side = \"top\",\n sideOffset = 5,\n}: CopyTooltipProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const [copied, setCopied] = useState<boolean>(false)\n const copiedTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined)\n\n const copy = () => {\n setCopied(true)\n\n // Not currently revealing the slight async nature of this operation,\n // nor indicating the failure state.\n copyText(copyValue)\n\n // Persist the copied state for a second, then close\n copiedTimerRef.current = setTimeout(() => {\n setOpen(false)\n }, 1000)\n }\n\n const handleOpenChange = (nextState: boolean) => {\n // When opening, ensure timer and copied state are cleared\n if (nextState) {\n clearTimeout(copiedTimerRef.current)\n setCopied(false)\n }\n\n setOpen(nextState)\n }\n\n return (\n <Tooltip.Root\n open={open}\n onOpenChange={handleOpenChange}\n delayDuration={openDelay}\n disableHoverableContent={false}\n >\n <Tooltip.Trigger\n onPointerDown={(evt) => {\n // Prevent tooltip listeners from closing\n evt.preventDefault()\n evt.stopPropagation()\n\n // Copy the value\n copy()\n }}\n // Prevent default behavior of closing on click from this handler\n onClick={(evt) => {\n evt.preventDefault()\n evt.stopPropagation()\n }}\n >\n {children}\n </Tooltip.Trigger>\n <Tooltip.Content\n compact\n clickable={!copied}\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n collisionPadding={15}\n onEscapeKeyDown={() => setOpen(false)}\n onPointerDown={copy}\n >\n {copied ? (\n // The <Check /> SVG canvas whitespace is larger than copy, so we use a smaller flexbox gap\n <div className=\"flex items-center gap-0.5\">\n <Check /> Copied!\n </div>\n ) : (\n <div className=\"flex items-center gap-1\">\n <Copy /> Copy\n </div>\n )}\n </Tooltip.Content>\n </Tooltip.Root>\n )\n}\n", "\"use client\"\n\nimport clsx from \"clsx\"\nimport { Tooltip as RadixTooltip, Slot } from \"radix-ui\"\nimport { useState, type MouseEventHandler, type PointerEventHandler } from \"react\"\nimport { useTimeout } from \"usehooks-ts\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { preventDefaultHandler } from \"../../lib/helpers\"\nimport s from \"./Tooltip.module.css\"\n\nexport type TooltipProps = {\n children: React.ReactNode\n /**\n * The content of the tooltip. If `null`, the tooltip will not render.\n */\n content: React.ReactNode\n /**\n * Defines the `max-width` of the tooltip content. `\"none\"` creates a single-line, naturally sized tooltip.\n * @default 300\n */\n maxWidth?: number | \"none\"\n /**\n * Forces the tooltip to remain open or closed\n */\n forceOpen?: boolean\n /**\n * Delay of when the tooltip is shown from first interaction, in milliseconds.\n * @default 150\n */\n openDelay?: number\n /** Indicates that the tooltip has interactive content, and should remain open when hovered. */\n interactive?: boolean\n /**\n * Short, 1-3 word tooltips, stylized inversely from normal tooltips\n */\n compact?: boolean\n /**\n * Prevents the tooltip from closing when the trigger is clicked right after opening\n * @default false\n */\n preventUnintentionalClickToClose?: true\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: RadixTooltip.TooltipContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: RadixTooltip.TooltipContentProps[\"alignOffset\"]\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default top\n */\n side?: RadixTooltip.TooltipContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 5\n */\n sideOffset?: RadixTooltip.TooltipContentProps[\"sideOffset\"]\n /**\n * Gutter sizing inside the tooltip content\n * @default md\n */\n gutterSize?: \"sm\" | \"md\" | \"lg\"\n /** Ref for the tooltip */\n ref?: React.Ref<HTMLDivElement | null>\n onPointerDown?: PointerEventHandler\n onClick?: MouseEventHandler\n /** Optional class name to apply to the tooltip content */\n contentClassName?: string\n}\n\nexport const Tooltip = (props: TooltipProps) => {\n const {\n ref: forwardedRef,\n children,\n content,\n forceOpen = content === null ? false : undefined,\n maxWidth = 300,\n openDelay = 150,\n interactive = false,\n compact = false,\n preventUnintentionalClickToClose,\n align,\n alignOffset = 0,\n side,\n sideOffset = 5,\n gutterSize = \"md\",\n contentClassName,\n onPointerDown,\n onClick,\n ...restProps\n } = props\n const [visible, setVisible] = useState<boolean>(false)\n const [temporarilyPreventClickToClose, setTemporarilyPreventClickToClose] =\n useState<boolean>(false)\n useTimeout(\n () => setTemporarilyPreventClickToClose(false),\n temporarilyPreventClickToClose ? 400 : null,\n )\n const open = forceOpen ?? visible\n\n const handleOpenChange = (nextState: boolean) => {\n // When forceOpen is passed, don't manage internal state\n if (typeof forceOpen === \"boolean\") return\n\n setVisible(nextState)\n\n if (preventUnintentionalClickToClose) {\n setTemporarilyPreventClickToClose(nextState)\n }\n }\n\n const maybePreventClickClose = (evt: React.MouseEvent) => {\n if (preventUnintentionalClickToClose && temporarilyPreventClickToClose) {\n // Prevents tooltip listeners from closing\n evt.preventDefault()\n evt.stopPropagation()\n }\n }\n\n return (\n <Root\n open={open}\n delayDuration={openDelay}\n onOpenChange={handleOpenChange}\n disableHoverableContent={!interactive}\n >\n <RadixTooltip.Trigger asChild>\n <Slot.Root\n {...restProps}\n ref={forwardedRef}\n onPointerDown={(evt) => {\n maybePreventClickClose(evt)\n onPointerDown?.(evt)\n }}\n onClick={(evt) => {\n maybePreventClickClose(evt)\n onClick?.(evt)\n }}\n >\n {children}\n </Slot.Root>\n </RadixTooltip.Trigger>\n <Content\n maxWidth={maxWidth}\n compact={compact}\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n gutterSize={gutterSize}\n className={contentClassName}\n >\n {content}\n </Content>\n </Root>\n )\n}\n\nconst Root = ({\n children,\n open,\n onOpenChange,\n ...restProps\n}: RadixTooltip.TooltipProps & {\n open: boolean\n onOpenChange: (nextState: boolean) => void\n}) => {\n useEscCloseStack(open, () => {\n onOpenChange(false)\n })\n\n return (\n <RadixTooltip.Provider>\n <RadixTooltip.Root open={open} onOpenChange={onOpenChange} {...restProps}>\n {children}\n </RadixTooltip.Root>\n </RadixTooltip.Provider>\n )\n}\n\ntype TooltipContentProps = RadixTooltip.TooltipContentProps & {\n children: React.ReactNode\n /**\n * Defines the `max-width` of the tooltip content. `\"none\"` creates a single-line, naturally sized tooltip.\n * @default 300\n */\n maxWidth?: number | \"none\"\n /**\n * Short, 1-3 word tooltips, stylized inversely from normal tooltips\n */\n compact?: boolean\n /**\n * Gutter sizing inside the tooltip content\n * @default md\n */\n gutterSize?: \"sm\" | \"md\" | \"lg\"\n /** Determines if the tooltip content should respond to click events */\n clickable?: boolean\n}\n\nexport const Content = ({\n children,\n maxWidth = 300,\n compact = false,\n clickable = undefined,\n alignOffset = 0,\n sideOffset = 5,\n gutterSize = \"md\",\n className,\n style,\n ...restProps\n}: TooltipContentProps) => {\n return (\n <RadixTooltip.Portal>\n <RadixTooltip.Content\n {...restProps}\n className={clsx(s.Tooltip, className)}\n data-compact={compact}\n data-clickable={clickable}\n data-gutter-size={gutterSize}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n collisionPadding={15}\n hideWhenDetached\n style={{\n ...style,\n maxWidth,\n }}\n onEscapeKeyDown={preventDefaultHandler}\n >\n {children}\n </RadixTooltip.Content>\n </RadixTooltip.Portal>\n )\n}\n\ntype TooltipTriggerProps = RadixTooltip.TooltipTriggerProps & {\n /**\n * Determines if `tabindex=0` is applied to the trigger\n * @default true\n */\n focusable?: boolean\n /**\n * Optional class name to apply to the trigger\n */\n className?: string\n /** Ref for the trigger */\n ref?: React.Ref<HTMLSpanElement | null>\n}\n\nexport const Trigger = ({\n children,\n asChild = true,\n ...restProps\n}: RadixTooltip.TooltipTriggerProps) => {\n return (\n <RadixTooltip.Trigger asChild={asChild} {...restProps}>\n {children}\n </RadixTooltip.Trigger>\n )\n}\n\n// Optional wrapper for tooltip trigger, if the visual content isn't already accessible or with built-in visual indications\nexport const TriggerDecorator = (props: TooltipTriggerProps) => {\n const { children, className, focusable = true, ref, ...restProps } = props\n const isPlainText = typeof children === \"string\"\n\n return (\n <Slot.Root\n ref={ref}\n {...restProps}\n className={clsx(s.TriggerDecorator, className)}\n tabIndex={focusable ? 0 : undefined}\n >\n {isPlainText ? <span>{children}</span> : children}\n </Slot.Root>\n )\n}\n\n// Building advanced tooltip behaviors can be achieved by using the\n// composed components, and wiring up bespoke behaviors.\nTooltip.Root = Root\nTooltip.Content = Content\nTooltip.Trigger = Trigger\n// Basic <Tooltip> usage can be done with the component directly,\n// without requiring controlled component composition.\n// <TriggerDecorator> is a helper component that creates an accessible trigger with a visual effect\nTooltip.TriggerDecorator = TriggerDecorator\n"],
5
+ "mappings": "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",
6
+ "names": ["import_react", "import_react", "_jsx", "_jsx", "_jsx", "_jsxs", "_jsx", "_jsx", "_jsx", "import_react", "import_react", "import_react", "_jsx", "import_react", "import_react", "import_react", "import_react", "s", "s", "_jsx", "import_react", "import_react", "s", "React", "cancelAnimationFrame", "_jsx", "s", "_Fragment", "s", "_jsxs", "_jsx", "import_react", "import_react", "s", "import_react", "s", "import_react", "s", "import_react", "s", "handleKeyDown", "_jsxs", "_jsx", "import_react", "import_react", "s", "_jsxs", "_jsx", "dist_exports", "s", "_jsx", "_Fragment", "o", "handleKeyDown", "_jsxs", "dist_exports"]
7
7
  }