@proyecto-viviana/solidaria-components 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Breadcrumbs.d.ts.map +1 -1
- package/dist/Breadcrumbs.js +3 -2
- package/dist/Breadcrumbs.js.map +1 -1
- package/dist/Breadcrumbs.jsx +3 -3
- package/dist/Breadcrumbs.jsx.map +1 -1
- package/dist/DateField.d.ts.map +1 -1
- package/dist/DateField2.js.map +1 -1
- package/dist/DateField2.jsx.map +1 -1
- package/dist/DatePicker2.js.map +1 -1
- package/dist/DatePicker2.jsx.map +1 -1
- package/dist/ElementTag.d.ts +29 -0
- package/dist/ElementTag.d.ts.map +1 -0
- package/dist/ElementTag.js +220 -0
- package/dist/ElementTag.js.map +1 -0
- package/dist/ElementTag.jsx +67 -0
- package/dist/ElementTag.jsx.map +1 -0
- package/dist/Form.d.ts.map +1 -1
- package/dist/Form.js +2 -6
- package/dist/Form.js.map +1 -1
- package/dist/Form.jsx +2 -4
- package/dist/Form.jsx.map +1 -1
- package/dist/Landmark.js +4 -3
- package/dist/Landmark.js.map +1 -1
- package/dist/Landmark.jsx +3 -3
- package/dist/Landmark.jsx.map +1 -1
- package/dist/Link.js +3 -2
- package/dist/Link.js.map +1 -1
- package/dist/Link.jsx +3 -3
- package/dist/Link.jsx.map +1 -1
- package/dist/ListBox.d.ts.map +1 -1
- package/dist/ListBox.js.map +1 -1
- package/dist/ListBox.jsx +51 -51
- package/dist/ListBox.jsx.map +1 -1
- package/dist/SearchField.d.ts.map +1 -1
- package/dist/SearchField.js.map +1 -1
- package/dist/SearchField.jsx.map +1 -1
- package/dist/Select.d.ts.map +1 -1
- package/dist/Select.js +2 -2
- package/dist/Select.js.map +1 -1
- package/dist/Select.jsx +2 -2
- package/dist/Select.jsx.map +1 -1
- package/dist/Separator.js +3 -2
- package/dist/Separator.js.map +1 -1
- package/dist/Separator.jsx +2 -2
- package/dist/Separator.jsx.map +1 -1
- package/dist/SharedElementTransition.d.ts.map +1 -1
- package/dist/SharedElementTransition.js.map +1 -1
- package/dist/SharedElementTransition.jsx.map +1 -1
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +9 -8
- package/dist/Text.js.map +1 -1
- package/dist/Text.jsx +3 -3
- package/dist/Text.jsx.map +1 -1
- package/dist/TimeField.d.ts.map +1 -1
- package/dist/TimeField.js.map +1 -1
- package/dist/TimeField.jsx.map +1 -1
- package/dist/VisuallyHidden.d.ts.map +1 -1
- package/dist/VisuallyHidden.js +3 -11
- package/dist/VisuallyHidden.js.map +1 -1
- package/dist/VisuallyHidden.jsx +3 -4
- package/dist/VisuallyHidden.jsx.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.jsx +2 -1
- package/package.json +5 -3
- package/src/Breadcrumbs.tsx +5 -7
- package/src/DateField.tsx +5 -7
- package/src/DatePicker.tsx +25 -25
- package/src/ElementTag.tsx +116 -0
- package/src/Form.tsx +18 -1
- package/src/Landmark.tsx +4 -4
- package/src/Link.tsx +4 -4
- package/src/ListBox.tsx +123 -124
- package/src/SearchField.tsx +1 -3
- package/src/Select.tsx +13 -2
- package/src/Separator.tsx +3 -3
- package/src/SharedElementTransition.tsx +64 -67
- package/src/Text.tsx +5 -4
- package/src/TimeField.tsx +3 -10
- package/src/VisuallyHidden.tsx +8 -12
- package/src/index.ts +2 -0
package/dist/Select.jsx.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.jsx","names":["mergeProps"],"sources":["../src/Select.tsx"],"sourcesContent":["/**\n * Select component for solidaria-components\n *\n * A pre-wired headless select that combines state + aria hooks.\n * Port of react-aria-components/src/Select.tsx\n */\n\nimport {\n type JSX,\n type Accessor,\n createContext,\n createEffect,\n createMemo,\n createSignal,\n createUniqueId,\n splitProps,\n useContext,\n For,\n Show,\n untrack,\n} from \"solid-js\";\nimport {\n createSelect,\n createHiddenSelect,\n createListBox,\n createOption,\n createHover,\n createInteractOutside,\n FocusScope,\n focusSafely,\n mergeProps,\n type AriaSelectProps,\n type AriaListBoxProps,\n type AriaOptionProps,\n} from \"@proyecto-viviana/solidaria\";\nimport {\n createSelectState,\n type ListState,\n type SelectState,\n type Key,\n type CollectionNode,\n DEFAULT_VALIDATION_RESULT,\n type ValidationResult,\n} from \"@proyecto-viviana/solid-stately\";\nimport { FieldErrorContext, type FieldErrorContextValue } from \"./FieldError\";\nimport {\n type RenderChildren,\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\nimport {\n SelectionIndicatorContext,\n type SelectionIndicatorContextValue,\n} from \"./SelectionIndicator\";\nimport { ListBoxLoadMoreItem } from \"./ListBox\";\n\ntype RefLike<T> = ((el: T) => void) | { current?: T | null } | undefined;\n\nfunction assignRef<T>(ref: RefLike<T>, el: T): void {\n if (!ref) return;\n if (typeof ref === \"function\") {\n ref(el);\n } else {\n ref.current = el;\n }\n}\n\nfunction getNativeSelectValidation(select: HTMLSelectElement): ValidationResult {\n return {\n isInvalid: !select.validity.valid,\n validationDetails: {\n badInput: select.validity.badInput,\n customError: select.validity.customError,\n patternMismatch: select.validity.patternMismatch,\n rangeOverflow: select.validity.rangeOverflow,\n rangeUnderflow: select.validity.rangeUnderflow,\n stepMismatch: select.validity.stepMismatch,\n tooLong: select.validity.tooLong,\n tooShort: select.validity.tooShort,\n typeMismatch: select.validity.typeMismatch,\n valueMissing: select.validity.valueMissing,\n valid: select.validity.valid,\n },\n validationErrors: select.validationMessage ? [select.validationMessage] : [],\n };\n}\n\nexport interface SelectRenderProps {\n /** Whether the select is open. */\n isOpen: boolean;\n /** Whether the select is focused. */\n isFocused: boolean;\n /** Whether the select has keyboard focus. */\n isFocusVisible: boolean;\n /** Whether the select is disabled. */\n isDisabled: boolean;\n /** Whether the select is required. */\n isRequired: boolean;\n /** Whether a value is selected. */\n isSelected: boolean;\n}\n\nexport interface SelectProps<T> extends Omit<AriaSelectProps, \"children\">, SlotProps {\n /** The items to render in the select. */\n items: T[];\n /** Function to get the key from an item. */\n getKey?: (item: T) => Key;\n /** Function to get the text value from an item. */\n getTextValue?: (item: T) => string;\n /** Function to check if an item is disabled. */\n getDisabled?: (item: T) => boolean;\n /** Keys of disabled items. */\n disabledKeys?: Iterable<Key>;\n /** Selection mode. */\n selectionMode?: \"single\" | \"multiple\";\n /** The currently selected key (controlled). */\n selectedKey?: Key | null;\n /** The default selected key (uncontrolled). */\n defaultSelectedKey?: Key | null;\n /** Currently selected keys (controlled, for multiple selection). */\n selectedKeys?: \"all\" | Iterable<Key>;\n /** Default selected keys (uncontrolled, for multiple selection). */\n defaultSelectedKeys?: \"all\" | Iterable<Key>;\n /** Handler called when selection changes. */\n onSelectionChange?: (key: Key | null) => void;\n /** Handler called when selected keys change. */\n onSelectionChangeKeys?: (keys: \"all\" | Set<Key>) => void;\n /** Whether the select is open (controlled). */\n isOpen?: boolean;\n /** Whether the select is open by default (uncontrolled). */\n defaultOpen?: boolean;\n /** Handler called when the open state changes. */\n onOpenChange?: (isOpen: boolean) => void;\n /** Placeholder text when no option is selected. */\n placeholder?: string;\n /** The name of the select, used when submitting an HTML form. */\n name?: string;\n /** The children of the component (compound components: SelectTrigger, SelectListBox). */\n children: RenderChildren<SelectRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SelectRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SelectRenderProps>;\n /** Custom renderer for the outer select element. */\n render?: (\n props: JSX.HTMLAttributes<HTMLDivElement>,\n renderProps: SelectRenderProps,\n ) => JSX.Element;\n /** Ref for the outer select element. */\n ref?: RefLike<HTMLDivElement>;\n}\n\nexport interface SelectValueRenderProps<T> {\n /** The selected item. */\n selectedItem: CollectionNode<T> | null;\n /** The selected items. */\n selectedItems: CollectionNode<T>[];\n /** The text value of the selected item. */\n selectedText: string | null;\n /** Whether a value is selected. */\n isSelected: boolean;\n /** The placeholder text. */\n placeholder: string | undefined;\n}\n\nexport interface SelectValueProps<T> extends SlotProps {\n /** The children of the value. A function may be provided to receive render props. */\n children?: RenderChildren<SelectValueRenderProps<T>>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SelectValueRenderProps<T>>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SelectValueRenderProps<T>>;\n /** Placeholder text when no option is selected. Overrides the placeholder from Select. */\n placeholder?: string;\n}\n\nexport interface SelectTriggerRenderProps {\n /** Whether the select is open. */\n isOpen: boolean;\n /** Whether the trigger is focused. */\n isFocused: boolean;\n /** Whether the trigger has keyboard focus. */\n isFocusVisible: boolean;\n /** Whether the trigger is hovered. */\n isHovered: boolean;\n /** Whether the trigger is pressed. */\n isPressed: boolean;\n /** Whether the trigger is disabled. */\n isDisabled: boolean;\n}\n\nexport interface SelectTriggerProps extends SlotProps {\n /** A ref callback/object for the underlying trigger button element. */\n ref?: RefLike<HTMLButtonElement>;\n /** The children of the trigger. A function may be provided to receive render props. */\n children?: RenderChildren<SelectTriggerRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SelectTriggerRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SelectTriggerRenderProps>;\n}\n\nexport interface SelectListBoxRenderProps {\n /** Whether the listbox is focused. */\n isFocused: boolean;\n}\n\nexport interface SelectListBoxProps<T> extends SlotProps {\n /** The children of the listbox. A function may be provided to render each item. */\n children?: (item: T) => JSX.Element;\n /** Content to display when the listbox has no items. */\n renderEmptyState?: () => JSX.Element;\n /** Called when the load more sentinel becomes visible. */\n onLoadMore?: () => void | Promise<void>;\n /** Whether additional items are currently loading. */\n isLoading?: boolean;\n /** Content to display in the load more sentinel row. */\n renderLoadMore?: () => JSX.Element | undefined;\n /** CSS class for the load more sentinel row. */\n loadMoreClass?: ClassNameOrFunction<{ isLoading: boolean }>;\n /** Whether the listbox is rendered inside an overlay popover. */\n isInPopover?: boolean;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SelectListBoxRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SelectListBoxRenderProps>;\n}\n\nexport interface SelectOptionRenderProps {\n /** Whether the option is selected. */\n isSelected: boolean;\n /** Whether the option is focused. */\n isFocused: boolean;\n /** Whether the option has keyboard focus. */\n isFocusVisible: boolean;\n /** Whether the option is pressed. */\n isPressed: boolean;\n /** Whether the option is hovered. */\n isHovered: boolean;\n /** Whether the option is disabled. */\n isDisabled: boolean;\n}\n\nexport interface SelectOptionProps<T> extends Omit<AriaOptionProps, \"children\" | \"key\">, SlotProps {\n /** A ref callback/object for the underlying option element. */\n ref?: RefLike<HTMLDivElement>;\n /** The unique key for the option. */\n id: Key;\n /** The item value. */\n item?: T;\n /** The children of the option. A function may be provided to receive render props. */\n children?: RenderChildren<SelectOptionRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SelectOptionRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SelectOptionRenderProps>;\n /** The text value of the option (for typeahead). */\n textValue?: string;\n}\n\ninterface SelectContextValue<T> {\n state: SelectState<T>;\n rootRef: Accessor<HTMLElement | null>;\n triggerRef: Accessor<HTMLElement | null>;\n setTriggerRef: (el: HTMLElement | null) => void;\n triggerProps: JSX.HTMLAttributes<HTMLElement>;\n valueProps: JSX.HTMLAttributes<HTMLElement>;\n labelProps: JSX.HTMLAttributes<HTMLElement>;\n menuProps: JSX.HTMLAttributes<HTMLElement>;\n errorMessageProps?: JSX.HTMLAttributes<HTMLElement>;\n validation?: ValidationResult;\n isOpen: Accessor<boolean>;\n isFocused: Accessor<boolean>;\n isFocusVisible: Accessor<boolean>;\n isPressed: Accessor<boolean>;\n isDisabled: Accessor<boolean>;\n placeholder?: string;\n items: T[];\n renderItem?: (item: T) => JSX.Element;\n slots?: Record<string, Partial<SelectProps<T>>>;\n autoFocus?: boolean;\n}\n\nexport const SelectContext = createContext<SelectContextValue<unknown> | null>(null);\nexport const SelectStateContext = createContext<SelectState<unknown> | null>(null);\nexport const SelectValueContext = SelectContext;\n\nconst selectRootLabelProps = new Set([\n \"aria-label\",\n \"aria-labelledby\",\n \"aria-describedby\",\n \"aria-details\",\n]);\n\n/**\n * A select displays a collapsible list of options and allows a user to select one of them.\n */\nexport function Select<T>(props: SelectProps<T>): JSX.Element {\n const parentContext = useContext(SelectContext) as SelectContextValue<T> | null;\n const contextSlotProps = parentContext?.slots?.[props.slot ?? \"default\"] as\n | Partial<SelectProps<T>>\n | undefined;\n const mergedSelectProps = (\n contextSlotProps ? mergeProps(contextSlotProps, props) : props\n ) as SelectProps<T>;\n const [local, stateProps, ariaProps] = splitProps(\n mergedSelectProps,\n [\"class\", \"style\", \"render\", \"ref\", \"slot\", \"children\"],\n [\n \"items\",\n \"getKey\",\n \"getTextValue\",\n \"getDisabled\",\n \"disabledKeys\",\n \"selectionMode\",\n \"selectedKey\",\n \"defaultSelectedKey\",\n \"selectedKeys\",\n \"defaultSelectedKeys\",\n \"onSelectionChange\",\n \"onSelectionChangeKeys\",\n \"isOpen\",\n \"defaultOpen\",\n \"onOpenChange\",\n \"name\",\n ],\n );\n let rootRef: HTMLDivElement | undefined;\n const [selectValidation, setSelectValidation] =\n createSignal<ValidationResult>(DEFAULT_VALIDATION_RESULT);\n const errorMessageId = createUniqueId();\n\n const resolveDisabled = (): boolean => {\n const disabled = ariaProps.isDisabled;\n if (typeof disabled === \"function\") {\n return (disabled as () => boolean)();\n }\n return !!disabled;\n };\n\n const state = createSelectState<T>({\n get items() {\n return stateProps.items;\n },\n get getKey() {\n return stateProps.getKey;\n },\n get getTextValue() {\n return stateProps.getTextValue;\n },\n get getDisabled() {\n return stateProps.getDisabled;\n },\n get disabledKeys() {\n return stateProps.disabledKeys;\n },\n get selectionMode() {\n return stateProps.selectionMode;\n },\n get selectedKey() {\n return stateProps.selectedKey;\n },\n get defaultSelectedKey() {\n return stateProps.defaultSelectedKey;\n },\n get selectedKeys() {\n return stateProps.selectedKeys;\n },\n get defaultSelectedKeys() {\n return stateProps.defaultSelectedKeys;\n },\n get onSelectionChange() {\n return stateProps.onSelectionChange;\n },\n get onSelectionChangeKeys() {\n return stateProps.onSelectionChangeKeys;\n },\n get isOpen() {\n return stateProps.isOpen;\n },\n get defaultOpen() {\n return stateProps.defaultOpen;\n },\n get onOpenChange() {\n return stateProps.onOpenChange;\n },\n get isDisabled() {\n return resolveDisabled();\n },\n get isRequired() {\n return ariaProps.isRequired;\n },\n });\n\n const selectAriaProps = createMemo(() => {\n const clean: Record<string, unknown> = {};\n for (const key in ariaProps as Record<string, unknown>) {\n if (!key.startsWith(\"data-\")) {\n clean[key] = (ariaProps as Record<string, unknown>)[key];\n }\n }\n return clean as typeof ariaProps;\n });\n\n const {\n labelProps,\n triggerProps,\n valueProps,\n menuProps,\n isFocused,\n isFocusVisible,\n isOpen,\n isPressed,\n } = createSelect<T>(selectAriaProps, state);\n\n const { isHovered, hoverProps } = createHover({\n get isDisabled() {\n return resolveDisabled();\n },\n });\n\n const renderValues = createMemo<SelectRenderProps>(() => ({\n isOpen: isOpen(),\n isFocused: isFocused(),\n isFocusVisible: isFocusVisible(),\n isDisabled: resolveDisabled(),\n isRequired: !!ariaProps.isRequired,\n isSelected:\n state.selectionMode() === \"multiple\"\n ? state.selectedKeys() === \"all\" || (state.selectedKeys() as Set<Key>).size > 0\n : state.selectedKey() != null,\n }));\n const childRenderValues: SelectRenderProps = {\n get isOpen() {\n return isOpen();\n },\n get isFocused() {\n return isFocused();\n },\n get isFocusVisible() {\n return isFocusVisible();\n },\n get isDisabled() {\n return resolveDisabled();\n },\n get isRequired() {\n return !!ariaProps.isRequired;\n },\n get isSelected() {\n return hasSelection();\n },\n };\n\n const renderProps = useRenderProps(\n {\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Select\",\n },\n renderValues,\n );\n\n const domProps = createMemo(() => {\n const filtered = filterDOMProps(ariaProps as Record<string, unknown>, { global: true });\n for (const key of selectRootLabelProps) {\n delete filtered[key];\n }\n return filtered;\n });\n\n const cleanHoverProps = () => {\n const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;\n return rest;\n };\n const cleanLabelProps = () => {\n const { ref: _ref, ...rest } = labelProps as Record<string, unknown>;\n return rest;\n };\n const setRootRef = (el: HTMLDivElement) => {\n rootRef = el;\n assignRef(local.ref, el);\n };\n const validation = createMemo<ValidationResult>(() => {\n const current = selectValidation();\n if (current.isInvalid || !ariaProps.isInvalid) {\n return current;\n }\n\n return {\n ...DEFAULT_VALIDATION_RESULT,\n isInvalid: true,\n };\n });\n const isInvalid = createMemo(() => validation().isInvalid);\n const triggerDescribedBy = () => {\n const ids = [\n (triggerProps as { \"aria-describedby\"?: string })[\"aria-describedby\"],\n isInvalid() ? errorMessageId : undefined,\n ]\n .filter(Boolean)\n .join(\" \")\n .split(\" \")\n .filter(Boolean);\n return ids.length ? Array.from(new Set(ids)).join(\" \") : undefined;\n };\n const triggerPropsWithValidation = () =>\n ({\n ...triggerProps,\n \"aria-describedby\": triggerDescribedBy(),\n }) as JSX.HTMLAttributes<HTMLElement>;\n const fieldErrorContext: FieldErrorContextValue = {\n get validation() {\n return validation();\n },\n get errorMessageProps() {\n return { id: errorMessageId };\n },\n };\n const focusTrigger = () => {\n triggerRef?.focus();\n };\n const hasSelection = () =>\n state.selectionMode() === \"multiple\"\n ? state.selectedKeys() === \"all\" || (state.selectedKeys() as Set<Key>).size > 0\n : state.selectedKey() != null;\n const hasNativeValidation = () => (ariaProps.validationBehavior ?? \"native\") === \"native\";\n const getSelectValidation = (select: HTMLSelectElement): ValidationResult => {\n if (ariaProps.isRequired && !hasSelection()) {\n return {\n isInvalid: true,\n validationDetails: {\n badInput: false,\n customError: false,\n patternMismatch: false,\n rangeOverflow: false,\n rangeUnderflow: false,\n stepMismatch: false,\n tooLong: false,\n tooShort: false,\n typeMismatch: false,\n valueMissing: true,\n valid: false,\n },\n validationErrors: [select.validationMessage || \"Constraints not satisfied\"],\n };\n }\n return getNativeSelectValidation(select);\n };\n\n const { containerProps, selectProps: hiddenSelectProps } = createHiddenSelect({\n state,\n name: stateProps.name,\n form: ariaProps.form,\n isRequired: ariaProps.isRequired,\n validationBehavior: ariaProps.validationBehavior ?? \"native\",\n get isDisabled() {\n return resolveDisabled();\n },\n });\n const handleHiddenSelectInvalid: JSX.EventHandler<HTMLSelectElement, Event> = (event) => {\n setSelectValidation(getSelectValidation(event.currentTarget));\n focusTrigger();\n event.preventDefault();\n };\n const handleHiddenSelectChange: JSX.EventHandler<HTMLSelectElement, Event> = (event) => {\n (hiddenSelectProps as { onChange?: JSX.EventHandler<HTMLSelectElement, Event> }).onChange?.(\n event,\n );\n setSelectValidation(\n hasSelection() && event.currentTarget.validity.valid\n ? DEFAULT_VALIDATION_RESULT\n : getSelectValidation(event.currentTarget),\n );\n };\n createEffect(() => {\n if (hasSelection() && selectValidation().isInvalid) {\n setSelectValidation(DEFAULT_VALIDATION_RESULT);\n }\n });\n let triggerRef: HTMLElement | null = null;\n const setTriggerRef = (el: HTMLElement | null) => {\n triggerRef = el;\n };\n\n const RootChildren = () => {\n const selectChildren = untrack(() =>\n typeof local.children === \"function\"\n ? (local.children as (values: SelectRenderProps) => JSX.Element)(childRenderValues)\n : local.children,\n );\n\n return (\n <>\n <Show when={ariaProps.label}>\n <span {...cleanLabelProps()}>{ariaProps.label as JSX.Element}</span>\n </Show>\n {selectChildren}\n {/*\n The HiddenSelect (native `<select>` for form autofill/submission) renders\n AFTER the trigger button, mirroring upstream RAC `Select` which emits\n `{renderProps.children}` then `<HiddenSelect>` (Select.tsx:288-289). Order\n matters for the DOM tab/focus trail: the visible button must precede the\n form-only hidden control.\n */}\n <div {...containerProps}>\n <select\n {...hiddenSelectProps}\n name={hasSelection() ? undefined : stateProps.name}\n required={\n (hasNativeValidation() && ariaProps.isRequired && !hasSelection()) || undefined\n }\n onInvalid={handleHiddenSelectInvalid}\n onChange={handleHiddenSelectChange}\n >\n <Show when={state.selectionMode() !== \"multiple\"}>\n <option selected={state.selectedKey() == null} />\n </Show>\n <For each={stateProps.items}>\n {(item) => {\n const itemRecord = isObjectRecord(item) ? item : null;\n const fallbackKey =\n itemRecord != null ? (toKey(itemRecord.key) ?? toKey(itemRecord.id)) : undefined;\n const key = stateProps.getKey?.(item) ?? fallbackKey ?? String(item);\n const fallbackTextValue =\n itemRecord != null\n ? (toTextValue(itemRecord.textValue) ?? toTextValue(itemRecord.label))\n : undefined;\n const textValue =\n stateProps.getTextValue?.(item) ?? fallbackTextValue ?? String(item);\n const selectedKeys = state.selectedKeys();\n const isSelected =\n state.selectionMode() === \"multiple\"\n ? selectedKeys === \"all\"\n ? true\n : (selectedKeys as Set<Key>).has(key)\n : key === state.selectedKey();\n return (\n <option value={String(key)} selected={isSelected}>\n {textValue}\n </option>\n );\n }}\n </For>\n </select>\n <Show when={state.selectionMode() === \"multiple\" && stateProps.name}>\n <For\n each={\n state.selectedKeys() === \"all\"\n ? Array.from(state.collection()).map((item) => item.key)\n : Array.from(state.selectedKeys() as Set<Key>)\n }\n >\n {(key) => (\n <input\n type=\"hidden\"\n name={stateProps.name}\n form={ariaProps.form}\n value={String(key)}\n disabled={resolveDisabled()}\n />\n )}\n </For>\n </Show>\n <Show\n when={\n state.selectionMode() !== \"multiple\" && stateProps.name && state.selectedKey() != null\n }\n >\n <input\n type=\"hidden\"\n name={stateProps.name}\n form={ariaProps.form}\n value={String(state.selectedKey())}\n disabled={resolveDisabled()}\n />\n </Show>\n </div>\n </>\n );\n };\n const baseRootProps = () =>\n ({\n ...domProps(),\n ...cleanHoverProps(),\n ref: setRootRef,\n class: renderProps.class(),\n style: renderProps.style(),\n slot: local.slot,\n \"data-open\": isOpen() || undefined,\n \"data-disabled\": resolveDisabled() || undefined,\n \"data-required\": ariaProps.isRequired || undefined,\n \"data-invalid\": isInvalid() || undefined,\n \"data-hovered\": isHovered() || undefined,\n }) as JSX.HTMLAttributes<HTMLDivElement>;\n const RootContent = () => {\n const renderedRootChildren = <RootChildren />;\n const rootProps = () =>\n ({\n ...baseRootProps(),\n children: renderedRootChildren,\n }) as JSX.HTMLAttributes<HTMLDivElement>;\n\n return local.render ? (\n local.render(rootProps(), renderValues())\n ) : (\n <div {...baseRootProps()}>{renderedRootChildren}</div>\n );\n };\n\n return (\n <SelectContext.Provider\n value={\n {\n state,\n rootRef: () => rootRef ?? null,\n triggerRef: () => triggerRef,\n setTriggerRef,\n get triggerProps() {\n return triggerPropsWithValidation();\n },\n valueProps,\n labelProps,\n menuProps,\n get errorMessageProps() {\n return { id: errorMessageId };\n },\n get validation() {\n return validation();\n },\n isOpen,\n isFocused,\n isFocusVisible,\n isPressed,\n isDisabled: resolveDisabled,\n placeholder: ariaProps.placeholder,\n items: stateProps.items,\n autoFocus: !!ariaProps.autoFocus,\n } as SelectContextValue<unknown>\n }\n >\n <SelectStateContext.Provider value={state}>\n <FieldErrorContext.Provider value={fieldErrorContext}>\n <RootContent />\n </FieldErrorContext.Provider>\n </SelectStateContext.Provider>\n </SelectContext.Provider>\n );\n}\n\n/**\n * The trigger button for a select.\n */\nexport function SelectTrigger(props: SelectTriggerProps): JSX.Element {\n const [local, domProps] = splitProps(props, [\"class\", \"style\", \"slot\", \"children\", \"ref\"]);\n\n const context = useContext(SelectContext);\n if (!context) {\n throw new Error(\"SelectTrigger must be used within a Select\");\n }\n const { isOpen, isFocused, isFocusVisible, isPressed, state } = context;\n let triggerRef: HTMLButtonElement | undefined;\n const setTriggerRef = (el: HTMLButtonElement) => {\n triggerRef = el;\n context.setTriggerRef(el);\n assignRef(local.ref, el);\n };\n\n createEffect(() => {\n if (context.autoFocus) {\n triggerRef?.focus();\n }\n });\n\n const { isHovered, hoverProps } = createHover({\n get isDisabled() {\n return state.isDisabled;\n },\n });\n\n const renderValues = createMemo<SelectTriggerRenderProps>(() => ({\n isOpen: isOpen(),\n isFocused: isFocused(),\n isFocusVisible: isFocusVisible(),\n isHovered: isHovered(),\n isPressed: isPressed(),\n isDisabled: state.isDisabled,\n }));\n\n const renderProps = useRenderProps(\n {\n get children() {\n return props.children;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Select-trigger\",\n },\n renderValues,\n );\n\n const cleanTriggerProps = () => {\n const { ref: _ref1, ...rest } = context.triggerProps as Record<string, unknown>;\n return rest;\n };\n const cleanHoverProps = () => {\n const { ref: _ref2, ...rest } = hoverProps as Record<string, unknown>;\n return rest;\n };\n const triggerAriaProps = () => context.triggerProps as Record<string, unknown>;\n const menuAriaProps = () => context.menuProps as Record<string, unknown>;\n return (\n <button\n ref={setTriggerRef}\n {...domProps}\n {...cleanTriggerProps()}\n {...cleanHoverProps()}\n type=\"button\"\n id={triggerAriaProps().id as string | undefined}\n tabIndex={state.isDisabled ? undefined : 0}\n aria-label={triggerAriaProps()[\"aria-label\"] as string | undefined}\n aria-labelledby={triggerAriaProps()[\"aria-labelledby\"] as string | undefined}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen()}\n aria-controls={isOpen() ? (menuAriaProps().id as string | undefined) : undefined}\n aria-disabled={state.isDisabled || undefined}\n aria-required={triggerAriaProps()[\"aria-required\"] as boolean | undefined}\n aria-describedby={triggerAriaProps()[\"aria-describedby\"] as string | undefined}\n class={renderProps.class()}\n style={renderProps.style()}\n data-open={isOpen() || undefined}\n data-focused={isFocused() || undefined}\n data-focus-visible={isFocusVisible() || undefined}\n data-hovered={isHovered() || undefined}\n data-disabled={state.isDisabled || undefined}\n >\n {renderProps.renderChildren()}\n </button>\n );\n}\n\n// Default children function for SelectValue - defined at module level for SSR stability\nfunction defaultSelectValueChildren<T>(values: SelectValueRenderProps<T>) {\n return values.selectedText ?? values.placeholder ?? \"\";\n}\n\n/**\n * Displays the selected value in a select.\n */\nexport function SelectValue<T>(props: SelectValueProps<T>): JSX.Element {\n const [local, domProps] = splitProps(props, [\n \"class\",\n \"style\",\n \"slot\",\n \"placeholder\",\n \"children\",\n ]);\n\n const context = useContext(SelectContext);\n if (!context) {\n throw new Error(\"SelectValue must be used within a Select\");\n }\n const { valueProps, placeholder: contextPlaceholder } = context;\n const state = context.state as SelectState<T>;\n\n const placeholder = () => local.placeholder ?? contextPlaceholder;\n\n const renderValues = createMemo<SelectValueRenderProps<T>>(() => {\n const collection = state.collection();\n const selectedItem =\n state.selectedKey() == null ? null : collection.getItem(state.selectedKey() as Key);\n const selectedKeys = state.selectedKeys();\n const selectedItems =\n selectedKeys === \"all\"\n ? Array.from(collection)\n : Array.from(selectedKeys as Set<Key>)\n .map((key) => collection.getItem(key))\n .filter((item): item is CollectionNode<T> => item != null);\n const selectedText =\n state.selectionMode() === \"multiple\"\n ? selectedItems.length > 0\n ? new Intl.ListFormat(undefined, { style: \"long\", type: \"conjunction\" }).format(\n selectedItems.map((item) => item.textValue),\n )\n : null\n : (selectedItem?.textValue ?? null);\n return {\n selectedItem,\n selectedItems,\n selectedText,\n isSelected:\n state.selectionMode() === \"multiple\" ? selectedItems.length > 0 : selectedItem != null,\n placeholder: placeholder(),\n };\n });\n\n const renderProps = useRenderProps(\n {\n get children() {\n return props.children ?? defaultSelectValueChildren;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Select-value\",\n },\n renderValues,\n );\n\n return (\n <span\n {...domProps}\n {...valueProps}\n class={renderProps.class()}\n style={renderProps.style()}\n data-placeholder={!renderValues().isSelected || undefined}\n >\n {props.children == null\n ? (renderValues().selectedText ?? renderValues().placeholder ?? \"\")\n : renderProps.renderChildren()}\n </span>\n );\n}\n\n/**\n * The listbox popup for a select.\n */\nexport function SelectListBox<T>(props: SelectListBoxProps<T>): JSX.Element {\n const [local, domProps] = splitProps(props, [\n \"class\",\n \"style\",\n \"slot\",\n \"children\",\n \"renderEmptyState\",\n \"onLoadMore\",\n \"isLoading\",\n \"renderLoadMore\",\n \"loadMoreClass\",\n \"isInPopover\",\n ]);\n\n const context = useContext(SelectContext);\n if (!context) {\n throw new Error(\"SelectListBox must be used within a Select\");\n }\n const { menuProps, rootRef, state: selectState, isOpen } = context;\n const state = selectState as SelectState<T>;\n\n createEffect(() => {\n if (!isOpen()) {\n return;\n }\n // On open the listbox takes collection focus. Upstream `useSelect` sets\n // `menuProps.autoFocus = state.focusStrategy || true`, so the ListBox's\n // `useSelectableCollection` auto-focuses on mount — setting the selection\n // manager's `isFocused` true and focusing the selected option. Our\n // `createListBox` reimplements keyboard nav inline (no `autoFocus` effect),\n // so we set the manager focus here to match. Without it the selected option\n // never paints its focus-visible background (`data-focused` stays unset).\n state.selectionManager.setFocused(true);\n if (state.focusedKey() != null) {\n return;\n }\n const selectedKey = state.selectedKey();\n if (selectedKey != null && !state.collection().getItem(selectedKey)?.isDisabled) {\n state.setFocusedKey(selectedKey);\n }\n });\n\n let listBoxRef: HTMLDivElement | undefined;\n\n createInteractOutside({\n ref: () => rootRef() ?? listBoxRef ?? null,\n onInteractOutside: () => {\n if (isOpen()) {\n state.close();\n }\n },\n get isDisabled() {\n return !isOpen() || local.isInPopover === true;\n },\n });\n\n // Keep the hook result intact — destructuring `{ listBoxProps }` invokes the\n // `get listBoxProps()` getter ONCE and freezes it (the Solid \"destructuring a\n // get-prop freezes reactivity\" gotcha). The listbox `tabIndex` is computed from\n // `focusedKey` (`focusedKey != null ? -1 : 0`); on open the effect above sets a\n // focused key, so a frozen snapshot would leave the listbox tabbable (`0`) when\n // upstream flips it to `-1`. Reading `listBoxHook.listBoxProps` per access keeps\n // it reactive.\n const listBoxHook = createListBox(\n {\n ...(menuProps as unknown as AriaListBoxProps),\n shouldSelectOnPressUp: true,\n shouldFocusOnHover: true,\n shouldSelectOnFocus: local.isInPopover === true ? false : undefined,\n get isDisabled() {\n return state.isDisabled;\n },\n },\n createSelectListStateAdapter(state),\n );\n\n const renderValues = createMemo<SelectListBoxRenderProps>(() => ({\n // Focus within the listbox itself (the selection manager's focus state),\n // not the select-level trigger focus.\n isFocused: state.selectionManager.isFocused,\n }));\n\n const renderProps = useRenderProps(\n {\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Select-listbox\",\n },\n renderValues,\n );\n\n const cleanMenuProps = () => {\n const { ref: _ref1, ...rest } = menuProps as Record<string, unknown>;\n return rest;\n };\n const cleanListBoxProps = () => {\n const {\n ref: _ref2,\n \"aria-activedescendant\": _activeDescendant,\n onFocus: _onFocus,\n ...rest\n } = listBoxHook.listBoxProps as Record<string, unknown>;\n // Faithful Select listbox focus model: the focused option receives REAL DOM\n // focus (the open effect above + `createSelectableItem`'s self-focus move\n // `document.activeElement` onto it), mirroring upstream `useSelect`. So the\n // listbox must (a) leave the tab sequence once an option is focused —\n // `useSelectableCollection` uses `tabIndex = focusedKey == null ? 0 : -1`\n // (useSelectableCollection.ts:687-690) — and (b) NOT expose\n // `aria-activedescendant`, which is the virtual-focus channel upstream Select\n // never uses. These are overridden here, not in the shared `createListBox`,\n // because the standalone `ListBox` keeps its container-focus model (focus\n // stays on the listbox, `aria-activedescendant` is its AT channel).\n //\n // We also drop `createListBox`'s container-focus TRAMPOLINE (`onFocus`): it\n // marshals the first key when the container is focused with `focusedKey ==\n // null`, which is exactly Select's deliberate click-open state (the open\n // effect sets `isFocused` true but leaves `focusedKey` null when nothing is\n // selected, so the first arrow enters the first item). Upstream's own\n // trampoline no-ops in this case because it guards on `manager.isFocused`\n // (already true); our shared guard uses `focusedKey == null` for the\n // standalone ListBox, so we strip it here to preserve Select's faithful\n // model. (Auto-selecting on focus under replace behavior would also toggle\n // the first item selected on open — the bug this override prevents.)\n return {\n ...rest,\n tabIndex: state.isDisabled ? undefined : state.focusedKey() != null ? -1 : 0,\n };\n };\n\n const items = () => Array.from(state.collection());\n createEffect(() => {\n if (!isOpen()) return;\n const focusedKey = state.focusedKey();\n if (focusedKey == null) return;\n\n queueMicrotask(() => {\n const option = Array.from(\n listBoxRef?.querySelectorAll<HTMLElement>(\"[role='option']\") ?? [],\n ).find((element) => element.id === String(focusedKey));\n if (option && document.activeElement !== option) {\n focusSafely(option);\n }\n });\n });\n\n const listBox = () => (\n // Upstream RAC ListBox (and our own Menu.tsx) render a `<div role=\"listbox\">`\n // over `<div role=\"option\">` rows, NOT `<ul>`/`<li>` — the collection is\n // div-based for virtualization parity. `<ul>`/`<li>` here was a self-inflicted\n // structural divergence surfaced by the Picker recertification (D5/D6/D8 saw\n // `li[option]`/`ul[listbox]` where the React oracle sees `div`).\n <div\n ref={(el) => (listBoxRef = el)}\n {...domProps}\n {...cleanMenuProps()}\n {...cleanListBoxProps()}\n class={renderProps.class()}\n style={renderProps.style()}\n data-focused={state.selectionManager.isFocused || undefined}\n data-empty={state.collection().size === 0 || undefined}\n >\n {state.collection().size === 0 && local.renderEmptyState ? (\n <div role=\"option\" style={{ display: \"contents\" }} data-empty-state>\n {local.renderEmptyState()}\n </div>\n ) : (\n <Show\n when={local.children}\n fallback={\n <For each={items()}>\n {(node) => <SelectOption id={node.key}>{node.textValue}</SelectOption>}\n </For>\n }\n >\n <For each={items()}>\n {(node) => (node.value != null ? local.children!(node.value) : null)}\n </For>\n </Show>\n )}\n <Show when={local.onLoadMore}>\n <ListBoxLoadMoreItem\n onLoadMore={local.onLoadMore!}\n isLoading={local.isLoading}\n class={local.loadMoreClass}\n >\n {local.renderLoadMore?.()}\n </ListBoxLoadMoreItem>\n </Show>\n </div>\n );\n\n return (\n <Show when={isOpen()}>\n <Show\n when={local.isInPopover}\n fallback={\n <FocusScope restoreFocus autoFocus>\n {listBox()}\n </FocusScope>\n }\n >\n {listBox()}\n </Show>\n </Show>\n );\n}\n\n/**\n * An option in a select listbox.\n */\nexport function SelectOption<T>(props: SelectOptionProps<T>): JSX.Element {\n const [local, ariaProps] = splitProps(props, [\n \"class\",\n \"style\",\n \"slot\",\n \"id\",\n \"item\",\n \"textValue\",\n \"ref\",\n ]);\n\n const context = useContext(SelectStateContext);\n if (!context) {\n throw new Error(\"SelectOption must be used within a Select\");\n }\n const state = context as SelectState<T>;\n const selectContext = useContext(SelectContext) as SelectContextValue<T> | null;\n const [ref, setRefSignal] = createSignal<HTMLDivElement | null>(null);\n const setRef = (el: HTMLDivElement | null) => {\n setRefSignal(el);\n assignRef(local.ref, el as HTMLDivElement);\n };\n\n const optionAria = createOption<T>(\n {\n key: local.id,\n get isDisabled() {\n return Boolean(ariaProps.isDisabled || selectContext?.isDisabled());\n },\n get \"aria-label\"() {\n return ariaProps[\"aria-label\"] ?? local.textValue;\n },\n shouldSelectOnPressUp: true,\n shouldFocusOnHover: true,\n get onHoverStart() {\n return ariaProps.onHoverStart;\n },\n get onHoverEnd() {\n return ariaProps.onHoverEnd;\n },\n get onHoverChange() {\n return ariaProps.onHoverChange;\n },\n },\n {\n ...createSelectListStateAdapter(state),\n select: (key: Key) => {\n if (state.selectionMode() === \"multiple\") {\n const keys = state.selectedKeys();\n if (keys === \"all\") return;\n state.setSelectedKeys(new Set([...keys, key]));\n return;\n }\n state.setSelectedKey(key);\n state.close();\n },\n toggleSelection: (key: Key) => {\n if (state.selectionMode() === \"multiple\") {\n const keys = state.selectedKeys();\n if (keys === \"all\") return;\n const next = new Set(keys);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n state.setSelectedKeys(next);\n return;\n }\n state.setSelectedKey(key);\n state.close();\n },\n replaceSelection: (key: Key) => {\n state.setSelectedKey(key);\n if (state.selectionMode() !== \"multiple\") {\n state.close();\n }\n },\n },\n () => ref(),\n );\n const isOptionFocusVisible = () =>\n optionAria.isFocused() && (selectContext?.isFocusVisible() ?? optionAria.isFocusVisible());\n\n const renderValues = createMemo<SelectOptionRenderProps>(() => ({\n isSelected: optionAria.isSelected(),\n isFocused: optionAria.isFocused(),\n isFocusVisible: isOptionFocusVisible(),\n isPressed: optionAria.isPressed(),\n isHovered: optionAria.isHovered(),\n isDisabled: optionAria.isDisabled(),\n }));\n\n const renderProps = useRenderProps(\n {\n get children() {\n return props.children;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Select-option\",\n },\n renderValues,\n );\n const hasPrimitiveLabel = () => {\n return typeof props.children === \"string\" || typeof props.children === \"number\";\n };\n\n const selectionIndicatorContext = createMemo<SelectionIndicatorContextValue>(() => ({\n isSelected: optionAria.isSelected,\n }));\n\n const cleanOptionProps = () => {\n const {\n ref: _ref1,\n \"aria-describedby\": _ariaDescribedby,\n ...rest\n } = optionAria.optionProps as Record<string, unknown>;\n if (!hasPrimitiveLabel() && rest[\"aria-label\"] == null) {\n delete rest[\"aria-labelledby\"];\n }\n const onClick = rest.onClick as ((event: MouseEvent) => void) | undefined;\n rest.onClick = ((event: MouseEvent) => {\n const wasSelected = optionAria.isSelected();\n onClick?.(event);\n if (typeof PointerEvent === \"undefined\") {\n return;\n }\n queueMicrotask(() => {\n if (state.selectionMode() !== \"multiple\" || optionAria.isSelected() === wasSelected) {\n selectOption();\n }\n });\n }) as JSX.EventHandler<HTMLDivElement, MouseEvent>;\n return rest;\n };\n const selectOption = () => {\n if (optionAria.isDisabled()) {\n return;\n }\n if (state.selectionMode() === \"multiple\") {\n const keys = state.selectedKeys();\n if (keys === \"all\") return;\n const next = new Set(keys);\n if (next.has(local.id)) next.delete(local.id);\n else next.add(local.id);\n state.setSelectedKeys(next);\n return;\n }\n state.setSelectedKey(local.id);\n state.close();\n };\n\n return (\n <SelectionIndicatorContext.Provider value={selectionIndicatorContext()}>\n {/* `<div role=\"option\">`, not `<li>` — see the SelectListBox note; upstream\n RAC options are div-based. */}\n <div\n ref={setRef}\n {...cleanOptionProps()}\n class={renderProps.class()}\n style={renderProps.style()}\n data-selected={optionAria.isSelected() || undefined}\n data-focused={optionAria.isFocused() || undefined}\n data-focus-visible={isOptionFocusVisible() || undefined}\n data-pressed={optionAria.isPressed() || undefined}\n data-hovered={optionAria.isHovered() || undefined}\n data-disabled={optionAria.isDisabled() || undefined}\n >\n {hasPrimitiveLabel() ? (\n <span {...optionAria.labelProps}>{renderProps.renderChildren()}</span>\n ) : (\n renderProps.renderChildren()\n )}\n </div>\n </SelectionIndicatorContext.Provider>\n );\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction toKey(value: unknown): Key | undefined {\n if (typeof value === \"string\" || typeof value === \"number\") {\n return value;\n }\n return undefined;\n}\n\nfunction toTextValue(value: unknown): string | undefined {\n if (typeof value === \"string\" || typeof value === \"number\") {\n return String(value);\n }\n return undefined;\n}\n\nfunction createSelectListStateAdapter<T>(state: SelectState<T>): ListState<T> {\n const selectedKeys = createMemo(() => {\n const keys = state.selectedKeys();\n return keys === \"all\" ? new Set(Array.from(state.collection()).map((item) => item.key)) : keys;\n });\n\n const disabledKeys = createMemo(() => {\n const keys = new Set<Key>();\n for (const node of state.collection()) {\n if (node.isDisabled) keys.add(node.key);\n }\n return keys;\n });\n\n return {\n collection: state.collection,\n selectionManager: state.selectionManager,\n // Collection-level focus (the selection manager's), not the select-level\n // trigger focus — upstream listbox internals only ever read\n // state.selectionManager.isFocused.\n isFocused: () => state.selectionManager.isFocused,\n setFocused: (isFocused) => state.selectionManager.setFocused(isFocused),\n focusedKey: state.focusedKey,\n setFocusedKey: (key) => state.setFocusedKey(key ?? null),\n childFocusStrategy: () => null,\n selectionMode: () => state.selectionMode(),\n selectionBehavior: () => \"replace\",\n disallowEmptySelection: () => true,\n selectedKeys,\n disabledKeys,\n disabledBehavior: () => \"all\",\n isEmpty: () => selectedKeys().size === 0,\n isSelectAll: () => state.selectedKeys() === \"all\",\n isSelected: (key) => selectedKeys().has(key),\n isDisabled: state.isKeyDisabled,\n setSelectionBehavior: () => {},\n toggleSelection: (key) => {\n if (state.selectionMode() !== \"multiple\") {\n state.setSelectedKey(key);\n return;\n }\n const keys = state.selectedKeys();\n if (keys === \"all\") return;\n const next = new Set(keys);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n state.setSelectedKeys(next);\n },\n replaceSelection: (key) => state.setSelectedKey(key),\n setSelectedKeys: (keys) => state.setSelectedKeys(keys),\n selectAll: () => {},\n clearSelection: () =>\n state.selectionMode() === \"multiple\" ? state.setSelectedKeys([]) : state.setSelectedKey(null),\n toggleSelectAll: () => {},\n extendSelection: (toKey) => state.setSelectedKey(toKey),\n select: (key) =>\n state.selectionMode() === \"multiple\"\n ? state.setSelectedKeys([\n ...(state.selectedKeys() === \"all\" ? [] : (state.selectedKeys() as Set<Key>)),\n key,\n ])\n : state.setSelectedKey(key),\n };\n}\n\nSelect.Trigger = SelectTrigger;\nSelect.Value = SelectValue;\nSelect.ListBox = SelectListBox;\nSelect.Option = SelectOption;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Select.jsx","names":["mergeProps"],"sources":["../src/Select.tsx"],"sourcesContent":["/**\n * Select component for solidaria-components\n *\n * A pre-wired headless select that combines state + aria hooks.\n * Port of react-aria-components/src/Select.tsx\n */\n\nimport {\n type JSX,\n type Accessor,\n createContext,\n createEffect,\n createMemo,\n createSignal,\n createUniqueId,\n splitProps,\n useContext,\n For,\n Show,\n untrack,\n} from \"solid-js\";\nimport {\n createSelect,\n createHiddenSelect,\n createListBox,\n createOption,\n createHover,\n createInteractOutside,\n FocusScope,\n focusSafely,\n mergeProps,\n type AriaSelectProps,\n type AriaListBoxProps,\n type AriaOptionProps,\n} from \"@proyecto-viviana/solidaria\";\nimport {\n createSelectState,\n type ListState,\n type SelectState,\n type Key,\n type CollectionNode,\n DEFAULT_VALIDATION_RESULT,\n type ValidationResult,\n} from \"@proyecto-viviana/solid-stately\";\nimport { FieldErrorContext, type FieldErrorContextValue } from \"./FieldError\";\nimport {\n type RenderChildren,\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\nimport {\n SelectionIndicatorContext,\n type SelectionIndicatorContextValue,\n} from \"./SelectionIndicator\";\nimport { ListBoxLoadMoreItem } from \"./ListBox\";\n\ntype RefLike<T> = ((el: T) => void) | { current?: T | null } | undefined;\n\nfunction assignRef<T>(ref: RefLike<T>, el: T): void {\n if (!ref) return;\n if (typeof ref === \"function\") {\n ref(el);\n } else {\n ref.current = el;\n }\n}\n\nfunction getNativeSelectValidation(select: HTMLSelectElement): ValidationResult {\n return {\n isInvalid: !select.validity.valid,\n validationDetails: {\n badInput: select.validity.badInput,\n customError: select.validity.customError,\n patternMismatch: select.validity.patternMismatch,\n rangeOverflow: select.validity.rangeOverflow,\n rangeUnderflow: select.validity.rangeUnderflow,\n stepMismatch: select.validity.stepMismatch,\n tooLong: select.validity.tooLong,\n tooShort: select.validity.tooShort,\n typeMismatch: select.validity.typeMismatch,\n valueMissing: select.validity.valueMissing,\n valid: select.validity.valid,\n },\n validationErrors: select.validationMessage ? [select.validationMessage] : [],\n };\n}\n\nexport interface SelectRenderProps {\n /** Whether the select is open. */\n isOpen: boolean;\n /** Whether the select is focused. */\n isFocused: boolean;\n /** Whether the select has keyboard focus. */\n isFocusVisible: boolean;\n /** Whether the select is disabled. */\n isDisabled: boolean;\n /** Whether the select is required. */\n isRequired: boolean;\n /** Whether a value is selected. */\n isSelected: boolean;\n}\n\nexport interface SelectProps<T> extends Omit<AriaSelectProps, \"children\">, SlotProps {\n /** The items to render in the select. */\n items: T[];\n /** Function to get the key from an item. */\n getKey?: (item: T) => Key;\n /** Function to get the text value from an item. */\n getTextValue?: (item: T) => string;\n /** Function to check if an item is disabled. */\n getDisabled?: (item: T) => boolean;\n /** Keys of disabled items. */\n disabledKeys?: Iterable<Key>;\n /** Selection mode. */\n selectionMode?: \"single\" | \"multiple\";\n /** The currently selected key (controlled). */\n selectedKey?: Key | null;\n /** The default selected key (uncontrolled). */\n defaultSelectedKey?: Key | null;\n /** Currently selected keys (controlled, for multiple selection). */\n selectedKeys?: \"all\" | Iterable<Key>;\n /** Default selected keys (uncontrolled, for multiple selection). */\n defaultSelectedKeys?: \"all\" | Iterable<Key>;\n /** Handler called when selection changes. */\n onSelectionChange?: (key: Key | null) => void;\n /** Handler called when selected keys change. */\n onSelectionChangeKeys?: (keys: \"all\" | Set<Key>) => void;\n /** Whether the select is open (controlled). */\n isOpen?: boolean;\n /** Whether the select is open by default (uncontrolled). */\n defaultOpen?: boolean;\n /** Handler called when the open state changes. */\n onOpenChange?: (isOpen: boolean) => void;\n /** Placeholder text when no option is selected. */\n placeholder?: string;\n /** The name of the select, used when submitting an HTML form. */\n name?: string;\n /** The children of the component (compound components: SelectTrigger, SelectListBox). */\n children: RenderChildren<SelectRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SelectRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SelectRenderProps>;\n /** Custom renderer for the outer select element. */\n render?: (\n props: JSX.HTMLAttributes<HTMLDivElement>,\n renderProps: SelectRenderProps,\n ) => JSX.Element;\n /** Ref for the outer select element. */\n ref?: RefLike<HTMLDivElement>;\n}\n\nexport interface SelectValueRenderProps<T> {\n /** The selected item. */\n selectedItem: CollectionNode<T> | null;\n /** The selected items. */\n selectedItems: CollectionNode<T>[];\n /** The text value of the selected item. */\n selectedText: string | null;\n /** Whether a value is selected. */\n isSelected: boolean;\n /** The placeholder text. */\n placeholder: string | undefined;\n}\n\nexport interface SelectValueProps<T> extends SlotProps {\n /** The children of the value. A function may be provided to receive render props. */\n children?: RenderChildren<SelectValueRenderProps<T>>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SelectValueRenderProps<T>>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SelectValueRenderProps<T>>;\n /** Placeholder text when no option is selected. Overrides the placeholder from Select. */\n placeholder?: string;\n}\n\nexport interface SelectTriggerRenderProps {\n /** Whether the select is open. */\n isOpen: boolean;\n /** Whether the trigger is focused. */\n isFocused: boolean;\n /** Whether the trigger has keyboard focus. */\n isFocusVisible: boolean;\n /** Whether the trigger is hovered. */\n isHovered: boolean;\n /** Whether the trigger is pressed. */\n isPressed: boolean;\n /** Whether the trigger is disabled. */\n isDisabled: boolean;\n}\n\nexport interface SelectTriggerProps extends SlotProps {\n /** A ref callback/object for the underlying trigger button element. */\n ref?: RefLike<HTMLButtonElement>;\n /** The children of the trigger. A function may be provided to receive render props. */\n children?: RenderChildren<SelectTriggerRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SelectTriggerRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SelectTriggerRenderProps>;\n}\n\nexport interface SelectListBoxRenderProps {\n /** Whether the listbox is focused. */\n isFocused: boolean;\n}\n\nexport interface SelectListBoxProps<T> extends SlotProps {\n /** The children of the listbox. A function may be provided to render each item. */\n children?: (item: T) => JSX.Element;\n /** Content to display when the listbox has no items. */\n renderEmptyState?: () => JSX.Element;\n /** Called when the load more sentinel becomes visible. */\n onLoadMore?: () => void | Promise<void>;\n /** Whether additional items are currently loading. */\n isLoading?: boolean;\n /** Content to display in the load more sentinel row. */\n renderLoadMore?: () => JSX.Element | undefined;\n /** CSS class for the load more sentinel row. */\n loadMoreClass?: ClassNameOrFunction<{ isLoading: boolean }>;\n /** Whether the listbox is rendered inside an overlay popover. */\n isInPopover?: boolean;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SelectListBoxRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SelectListBoxRenderProps>;\n}\n\nexport interface SelectOptionRenderProps {\n /** Whether the option is selected. */\n isSelected: boolean;\n /** Whether the option is focused. */\n isFocused: boolean;\n /** Whether the option has keyboard focus. */\n isFocusVisible: boolean;\n /** Whether the option is pressed. */\n isPressed: boolean;\n /** Whether the option is hovered. */\n isHovered: boolean;\n /** Whether the option is disabled. */\n isDisabled: boolean;\n}\n\nexport interface SelectOptionProps<T> extends Omit<AriaOptionProps, \"children\" | \"key\">, SlotProps {\n /** A ref callback/object for the underlying option element. */\n ref?: RefLike<HTMLDivElement>;\n /** The unique key for the option. */\n id: Key;\n /** The item value. */\n item?: T;\n /** The children of the option. A function may be provided to receive render props. */\n children?: RenderChildren<SelectOptionRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SelectOptionRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SelectOptionRenderProps>;\n /** The text value of the option (for typeahead). */\n textValue?: string;\n}\n\ninterface SelectContextValue<T> {\n state: SelectState<T>;\n rootRef: Accessor<HTMLElement | null>;\n triggerRef: Accessor<HTMLElement | null>;\n setTriggerRef: (el: HTMLElement | null) => void;\n triggerProps: JSX.HTMLAttributes<HTMLElement>;\n valueProps: JSX.HTMLAttributes<HTMLElement>;\n labelProps: JSX.HTMLAttributes<HTMLElement>;\n menuProps: JSX.HTMLAttributes<HTMLElement>;\n errorMessageProps?: JSX.HTMLAttributes<HTMLElement>;\n validation?: ValidationResult;\n isOpen: Accessor<boolean>;\n isFocused: Accessor<boolean>;\n isFocusVisible: Accessor<boolean>;\n isPressed: Accessor<boolean>;\n isDisabled: Accessor<boolean>;\n placeholder?: string;\n items: T[];\n renderItem?: (item: T) => JSX.Element;\n slots?: Record<string, Partial<SelectProps<T>>>;\n autoFocus?: boolean;\n}\n\nexport const SelectContext = createContext<SelectContextValue<unknown> | null>(null);\nexport const SelectStateContext = createContext<SelectState<unknown> | null>(null);\nexport const SelectValueContext = SelectContext;\n\nconst selectRootLabelProps = new Set([\n \"aria-label\",\n \"aria-labelledby\",\n \"aria-describedby\",\n \"aria-details\",\n]);\n\n/**\n * A select displays a collapsible list of options and allows a user to select one of them.\n */\nexport function Select<T>(props: SelectProps<T>): JSX.Element {\n const parentContext = useContext(SelectContext) as SelectContextValue<T> | null;\n const contextSlotProps = parentContext?.slots?.[props.slot ?? \"default\"] as\n | Partial<SelectProps<T>>\n | undefined;\n const mergedSelectProps = (\n contextSlotProps ? mergeProps(contextSlotProps, props) : props\n ) as SelectProps<T>;\n const [local, stateProps, ariaProps] = splitProps(\n mergedSelectProps,\n [\"class\", \"style\", \"render\", \"ref\", \"slot\", \"children\"],\n [\n \"items\",\n \"getKey\",\n \"getTextValue\",\n \"getDisabled\",\n \"disabledKeys\",\n \"selectionMode\",\n \"selectedKey\",\n \"defaultSelectedKey\",\n \"selectedKeys\",\n \"defaultSelectedKeys\",\n \"onSelectionChange\",\n \"onSelectionChangeKeys\",\n \"isOpen\",\n \"defaultOpen\",\n \"onOpenChange\",\n \"name\",\n ],\n );\n let rootRef: HTMLDivElement | undefined;\n const [selectValidation, setSelectValidation] =\n createSignal<ValidationResult>(DEFAULT_VALIDATION_RESULT);\n const errorMessageId = createUniqueId();\n\n const resolveDisabled = (): boolean => {\n const disabled = ariaProps.isDisabled;\n if (typeof disabled === \"function\") {\n return (disabled as () => boolean)();\n }\n return !!disabled;\n };\n\n const state = createSelectState<T>({\n get items() {\n return stateProps.items;\n },\n get getKey() {\n return stateProps.getKey;\n },\n get getTextValue() {\n return stateProps.getTextValue;\n },\n get getDisabled() {\n return stateProps.getDisabled;\n },\n get disabledKeys() {\n return stateProps.disabledKeys;\n },\n get selectionMode() {\n return stateProps.selectionMode;\n },\n get selectedKey() {\n return stateProps.selectedKey;\n },\n get defaultSelectedKey() {\n return stateProps.defaultSelectedKey;\n },\n get selectedKeys() {\n return stateProps.selectedKeys;\n },\n get defaultSelectedKeys() {\n return stateProps.defaultSelectedKeys;\n },\n get onSelectionChange() {\n return stateProps.onSelectionChange;\n },\n get onSelectionChangeKeys() {\n return stateProps.onSelectionChangeKeys;\n },\n get isOpen() {\n return stateProps.isOpen;\n },\n get defaultOpen() {\n return stateProps.defaultOpen;\n },\n get onOpenChange() {\n return stateProps.onOpenChange;\n },\n get isDisabled() {\n return resolveDisabled();\n },\n get isRequired() {\n return ariaProps.isRequired;\n },\n });\n\n const selectAriaProps = createMemo(() => {\n const clean: Record<string, unknown> = {};\n for (const key in ariaProps as Record<string, unknown>) {\n if (!key.startsWith(\"data-\")) {\n clean[key] = (ariaProps as Record<string, unknown>)[key];\n }\n }\n return clean as typeof ariaProps;\n });\n\n const {\n labelProps,\n triggerProps,\n valueProps,\n menuProps,\n isFocused,\n isFocusVisible,\n isOpen,\n isPressed,\n } = createSelect<T>(selectAriaProps, state);\n\n const { isHovered, hoverProps } = createHover({\n get isDisabled() {\n return resolveDisabled();\n },\n });\n\n const renderValues = createMemo<SelectRenderProps>(() => ({\n isOpen: isOpen(),\n isFocused: isFocused(),\n isFocusVisible: isFocusVisible(),\n isDisabled: resolveDisabled(),\n isRequired: !!ariaProps.isRequired,\n isSelected:\n state.selectionMode() === \"multiple\"\n ? state.selectedKeys() === \"all\" || (state.selectedKeys() as Set<Key>).size > 0\n : state.selectedKey() != null,\n }));\n const childRenderValues: SelectRenderProps = {\n get isOpen() {\n return isOpen();\n },\n get isFocused() {\n return isFocused();\n },\n get isFocusVisible() {\n return isFocusVisible();\n },\n get isDisabled() {\n return resolveDisabled();\n },\n get isRequired() {\n return !!ariaProps.isRequired;\n },\n get isSelected() {\n return hasSelection();\n },\n };\n\n const renderProps = useRenderProps(\n {\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Select\",\n },\n renderValues,\n );\n\n const domProps = createMemo(() => {\n const filtered = filterDOMProps(ariaProps as Record<string, unknown>, { global: true });\n for (const key of selectRootLabelProps) {\n delete filtered[key];\n }\n return filtered;\n });\n\n const cleanHoverProps = () => {\n const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;\n return rest;\n };\n const cleanLabelProps = () => {\n const { ref: _ref, ...rest } = labelProps as Record<string, unknown>;\n return rest;\n };\n const setRootRef = (el: HTMLDivElement) => {\n rootRef = el;\n assignRef(local.ref, el);\n };\n const validation = createMemo<ValidationResult>(() => {\n const current = selectValidation();\n if (current.isInvalid || !ariaProps.isInvalid) {\n return current;\n }\n\n return {\n ...DEFAULT_VALIDATION_RESULT,\n isInvalid: true,\n };\n });\n const isInvalid = createMemo(() => validation().isInvalid);\n const triggerDescribedBy = () => {\n const ids = [\n (triggerProps as { \"aria-describedby\"?: string })[\"aria-describedby\"],\n isInvalid() ? errorMessageId : undefined,\n ]\n .filter(Boolean)\n .join(\" \")\n .split(\" \")\n .filter(Boolean);\n return ids.length ? Array.from(new Set(ids)).join(\" \") : undefined;\n };\n const triggerPropsWithValidation = () =>\n ({\n ...triggerProps,\n \"aria-describedby\": triggerDescribedBy(),\n }) as JSX.HTMLAttributes<HTMLElement>;\n const fieldErrorContext: FieldErrorContextValue = {\n get validation() {\n return validation();\n },\n get errorMessageProps() {\n return { id: errorMessageId };\n },\n };\n const focusTrigger = () => {\n triggerRef?.focus();\n };\n const hasSelection = () =>\n state.selectionMode() === \"multiple\"\n ? state.selectedKeys() === \"all\" || (state.selectedKeys() as Set<Key>).size > 0\n : state.selectedKey() != null;\n const hasNativeValidation = () => (ariaProps.validationBehavior ?? \"native\") === \"native\";\n const getSelectValidation = (select: HTMLSelectElement): ValidationResult => {\n if (ariaProps.isRequired && !hasSelection()) {\n return {\n isInvalid: true,\n validationDetails: {\n badInput: false,\n customError: false,\n patternMismatch: false,\n rangeOverflow: false,\n rangeUnderflow: false,\n stepMismatch: false,\n tooLong: false,\n tooShort: false,\n typeMismatch: false,\n valueMissing: true,\n valid: false,\n },\n validationErrors: [select.validationMessage || \"Constraints not satisfied\"],\n };\n }\n return getNativeSelectValidation(select);\n };\n\n const { containerProps, selectProps: hiddenSelectProps } = createHiddenSelect({\n state,\n name: stateProps.name,\n form: ariaProps.form,\n isRequired: ariaProps.isRequired,\n validationBehavior: ariaProps.validationBehavior ?? \"native\",\n get isDisabled() {\n return resolveDisabled();\n },\n });\n const handleHiddenSelectInvalid: JSX.EventHandler<HTMLSelectElement, Event> = (event) => {\n setSelectValidation(getSelectValidation(event.currentTarget));\n focusTrigger();\n event.preventDefault();\n };\n const handleHiddenSelectChange: JSX.EventHandler<HTMLSelectElement, Event> = (event) => {\n (hiddenSelectProps as { onChange?: JSX.EventHandler<HTMLSelectElement, Event> }).onChange?.(\n event,\n );\n setSelectValidation(\n hasSelection() && event.currentTarget.validity.valid\n ? DEFAULT_VALIDATION_RESULT\n : getSelectValidation(event.currentTarget),\n );\n };\n createEffect(() => {\n if (hasSelection() && selectValidation().isInvalid) {\n setSelectValidation(DEFAULT_VALIDATION_RESULT);\n }\n });\n let triggerRef: HTMLElement | null = null;\n const setTriggerRef = (el: HTMLElement | null) => {\n triggerRef = el;\n };\n\n const RootChildren = () => {\n const selectChildren = untrack(() =>\n typeof local.children === \"function\"\n ? (local.children as (values: SelectRenderProps) => JSX.Element)(childRenderValues)\n : local.children,\n );\n\n return (\n <>\n <Show when={ariaProps.label}>\n <span {...cleanLabelProps()}>{ariaProps.label as JSX.Element}</span>\n </Show>\n {selectChildren}\n {/*\n The HiddenSelect (native `<select>` for form autofill/submission) renders\n AFTER the trigger button, mirroring upstream RAC `Select` which emits\n `{renderProps.children}` then `<HiddenSelect>` (Select.tsx:288-289). Order\n matters for the DOM tab/focus trail: the visible button must precede the\n form-only hidden control.\n */}\n <div {...containerProps}>\n <select\n {...hiddenSelectProps}\n name={hasSelection() ? undefined : stateProps.name}\n required={\n (hasNativeValidation() && ariaProps.isRequired && !hasSelection()) || undefined\n }\n onInvalid={handleHiddenSelectInvalid}\n onChange={handleHiddenSelectChange}\n >\n <Show when={state.selectionMode() !== \"multiple\"}>\n <option selected={state.selectedKey() == null} />\n </Show>\n <For each={stateProps.items}>\n {(item) => {\n const itemRecord = isObjectRecord(item) ? item : null;\n const fallbackKey =\n itemRecord != null ? (toKey(itemRecord.key) ?? toKey(itemRecord.id)) : undefined;\n const key = stateProps.getKey?.(item) ?? fallbackKey ?? String(item);\n // This hidden <select> re-derives each option's label straight\n // from the raw items array, bypassing the collection's textValue.\n // Mirror createListState's derivation: read the conventional\n // display fields (textValue/label/name/title) and, for an object\n // item with none of them, fall back to the key rather than\n // String(item) — which would render the useless \"[object Object]\".\n const fallbackTextValue =\n itemRecord != null\n ? (toTextValue(itemRecord.textValue) ??\n toTextValue(itemRecord.label) ??\n toTextValue(itemRecord.name) ??\n toTextValue(itemRecord.title))\n : undefined;\n const textValue =\n stateProps.getTextValue?.(item) ??\n fallbackTextValue ??\n (itemRecord != null ? String(key) : String(item));\n const selectedKeys = state.selectedKeys();\n const isSelected =\n state.selectionMode() === \"multiple\"\n ? selectedKeys === \"all\"\n ? true\n : (selectedKeys as Set<Key>).has(key)\n : key === state.selectedKey();\n return (\n <option value={String(key)} selected={isSelected}>\n {textValue}\n </option>\n );\n }}\n </For>\n </select>\n <Show when={state.selectionMode() === \"multiple\" && stateProps.name}>\n <For\n each={\n state.selectedKeys() === \"all\"\n ? Array.from(state.collection()).map((item) => item.key)\n : Array.from(state.selectedKeys() as Set<Key>)\n }\n >\n {(key) => (\n <input\n type=\"hidden\"\n name={stateProps.name}\n form={ariaProps.form}\n value={String(key)}\n disabled={resolveDisabled()}\n />\n )}\n </For>\n </Show>\n <Show\n when={\n state.selectionMode() !== \"multiple\" && stateProps.name && state.selectedKey() != null\n }\n >\n <input\n type=\"hidden\"\n name={stateProps.name}\n form={ariaProps.form}\n value={String(state.selectedKey())}\n disabled={resolveDisabled()}\n />\n </Show>\n </div>\n </>\n );\n };\n const baseRootProps = () =>\n ({\n ...domProps(),\n ...cleanHoverProps(),\n ref: setRootRef,\n class: renderProps.class(),\n style: renderProps.style(),\n slot: local.slot,\n \"data-open\": isOpen() || undefined,\n \"data-disabled\": resolveDisabled() || undefined,\n \"data-required\": ariaProps.isRequired || undefined,\n \"data-invalid\": isInvalid() || undefined,\n \"data-hovered\": isHovered() || undefined,\n }) as JSX.HTMLAttributes<HTMLDivElement>;\n const RootContent = () => {\n const renderedRootChildren = <RootChildren />;\n const rootProps = () =>\n ({\n ...baseRootProps(),\n children: renderedRootChildren,\n }) as JSX.HTMLAttributes<HTMLDivElement>;\n\n return local.render ? (\n local.render(rootProps(), renderValues())\n ) : (\n <div {...baseRootProps()}>{renderedRootChildren}</div>\n );\n };\n\n return (\n <SelectContext.Provider\n value={\n {\n state,\n rootRef: () => rootRef ?? null,\n triggerRef: () => triggerRef,\n setTriggerRef,\n get triggerProps() {\n return triggerPropsWithValidation();\n },\n valueProps,\n labelProps,\n menuProps,\n get errorMessageProps() {\n return { id: errorMessageId };\n },\n get validation() {\n return validation();\n },\n isOpen,\n isFocused,\n isFocusVisible,\n isPressed,\n isDisabled: resolveDisabled,\n placeholder: ariaProps.placeholder,\n items: stateProps.items,\n autoFocus: !!ariaProps.autoFocus,\n } as SelectContextValue<unknown>\n }\n >\n <SelectStateContext.Provider value={state}>\n <FieldErrorContext.Provider value={fieldErrorContext}>\n <RootContent />\n </FieldErrorContext.Provider>\n </SelectStateContext.Provider>\n </SelectContext.Provider>\n );\n}\n\n/**\n * The trigger button for a select.\n */\nexport function SelectTrigger(props: SelectTriggerProps): JSX.Element {\n const [local, domProps] = splitProps(props, [\"class\", \"style\", \"slot\", \"children\", \"ref\"]);\n\n const context = useContext(SelectContext);\n if (!context) {\n throw new Error(\"SelectTrigger must be used within a Select\");\n }\n const { isOpen, isFocused, isFocusVisible, isPressed, state } = context;\n let triggerRef: HTMLButtonElement | undefined;\n const setTriggerRef = (el: HTMLButtonElement) => {\n triggerRef = el;\n context.setTriggerRef(el);\n assignRef(local.ref, el);\n };\n\n createEffect(() => {\n if (context.autoFocus) {\n triggerRef?.focus();\n }\n });\n\n const { isHovered, hoverProps } = createHover({\n get isDisabled() {\n return state.isDisabled;\n },\n });\n\n const renderValues = createMemo<SelectTriggerRenderProps>(() => ({\n isOpen: isOpen(),\n isFocused: isFocused(),\n isFocusVisible: isFocusVisible(),\n isHovered: isHovered(),\n isPressed: isPressed(),\n isDisabled: state.isDisabled,\n }));\n\n const renderProps = useRenderProps(\n {\n get children() {\n return props.children;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Select-trigger\",\n },\n renderValues,\n );\n\n const cleanTriggerProps = () => {\n const { ref: _ref1, ...rest } = context.triggerProps as Record<string, unknown>;\n return rest;\n };\n const cleanHoverProps = () => {\n const { ref: _ref2, ...rest } = hoverProps as Record<string, unknown>;\n return rest;\n };\n const triggerAriaProps = () => context.triggerProps as Record<string, unknown>;\n const menuAriaProps = () => context.menuProps as Record<string, unknown>;\n return (\n <button\n ref={setTriggerRef}\n {...domProps}\n {...cleanTriggerProps()}\n {...cleanHoverProps()}\n type=\"button\"\n id={triggerAriaProps().id as string | undefined}\n tabIndex={state.isDisabled ? undefined : 0}\n aria-label={triggerAriaProps()[\"aria-label\"] as string | undefined}\n aria-labelledby={triggerAriaProps()[\"aria-labelledby\"] as string | undefined}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen()}\n aria-controls={isOpen() ? (menuAriaProps().id as string | undefined) : undefined}\n aria-disabled={state.isDisabled || undefined}\n aria-required={triggerAriaProps()[\"aria-required\"] as boolean | undefined}\n aria-describedby={triggerAriaProps()[\"aria-describedby\"] as string | undefined}\n class={renderProps.class()}\n style={renderProps.style()}\n data-open={isOpen() || undefined}\n data-focused={isFocused() || undefined}\n data-focus-visible={isFocusVisible() || undefined}\n data-hovered={isHovered() || undefined}\n data-disabled={state.isDisabled || undefined}\n >\n {renderProps.renderChildren()}\n </button>\n );\n}\n\n// Default children function for SelectValue - defined at module level for SSR stability\nfunction defaultSelectValueChildren<T>(values: SelectValueRenderProps<T>) {\n return values.selectedText ?? values.placeholder ?? \"\";\n}\n\n/**\n * Displays the selected value in a select.\n */\nexport function SelectValue<T>(props: SelectValueProps<T>): JSX.Element {\n const [local, domProps] = splitProps(props, [\n \"class\",\n \"style\",\n \"slot\",\n \"placeholder\",\n \"children\",\n ]);\n\n const context = useContext(SelectContext);\n if (!context) {\n throw new Error(\"SelectValue must be used within a Select\");\n }\n const { valueProps, placeholder: contextPlaceholder } = context;\n const state = context.state as SelectState<T>;\n\n const placeholder = () => local.placeholder ?? contextPlaceholder;\n\n const renderValues = createMemo<SelectValueRenderProps<T>>(() => {\n const collection = state.collection();\n const selectedItem =\n state.selectedKey() == null ? null : collection.getItem(state.selectedKey() as Key);\n const selectedKeys = state.selectedKeys();\n const selectedItems =\n selectedKeys === \"all\"\n ? Array.from(collection)\n : Array.from(selectedKeys as Set<Key>)\n .map((key) => collection.getItem(key))\n .filter((item): item is CollectionNode<T> => item != null);\n const selectedText =\n state.selectionMode() === \"multiple\"\n ? selectedItems.length > 0\n ? new Intl.ListFormat(undefined, { style: \"long\", type: \"conjunction\" }).format(\n selectedItems.map((item) => item.textValue),\n )\n : null\n : (selectedItem?.textValue ?? null);\n return {\n selectedItem,\n selectedItems,\n selectedText,\n isSelected:\n state.selectionMode() === \"multiple\" ? selectedItems.length > 0 : selectedItem != null,\n placeholder: placeholder(),\n };\n });\n\n const renderProps = useRenderProps(\n {\n get children() {\n return props.children ?? defaultSelectValueChildren;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Select-value\",\n },\n renderValues,\n );\n\n return (\n <span\n {...domProps}\n {...valueProps}\n class={renderProps.class()}\n style={renderProps.style()}\n data-placeholder={!renderValues().isSelected || undefined}\n >\n {props.children == null\n ? (renderValues().selectedText ?? renderValues().placeholder ?? \"\")\n : renderProps.renderChildren()}\n </span>\n );\n}\n\n/**\n * The listbox popup for a select.\n */\nexport function SelectListBox<T>(props: SelectListBoxProps<T>): JSX.Element {\n const [local, domProps] = splitProps(props, [\n \"class\",\n \"style\",\n \"slot\",\n \"children\",\n \"renderEmptyState\",\n \"onLoadMore\",\n \"isLoading\",\n \"renderLoadMore\",\n \"loadMoreClass\",\n \"isInPopover\",\n ]);\n\n const context = useContext(SelectContext);\n if (!context) {\n throw new Error(\"SelectListBox must be used within a Select\");\n }\n const { menuProps, rootRef, state: selectState, isOpen } = context;\n const state = selectState as SelectState<T>;\n\n createEffect(() => {\n if (!isOpen()) {\n return;\n }\n // On open the listbox takes collection focus. Upstream `useSelect` sets\n // `menuProps.autoFocus = state.focusStrategy || true`, so the ListBox's\n // `useSelectableCollection` auto-focuses on mount — setting the selection\n // manager's `isFocused` true and focusing the selected option. Our\n // `createListBox` reimplements keyboard nav inline (no `autoFocus` effect),\n // so we set the manager focus here to match. Without it the selected option\n // never paints its focus-visible background (`data-focused` stays unset).\n state.selectionManager.setFocused(true);\n if (state.focusedKey() != null) {\n return;\n }\n const selectedKey = state.selectedKey();\n if (selectedKey != null && !state.collection().getItem(selectedKey)?.isDisabled) {\n state.setFocusedKey(selectedKey);\n }\n });\n\n let listBoxRef: HTMLDivElement | undefined;\n\n createInteractOutside({\n ref: () => rootRef() ?? listBoxRef ?? null,\n onInteractOutside: () => {\n if (isOpen()) {\n state.close();\n }\n },\n get isDisabled() {\n return !isOpen() || local.isInPopover === true;\n },\n });\n\n // Keep the hook result intact — destructuring `{ listBoxProps }` invokes the\n // `get listBoxProps()` getter ONCE and freezes it (the Solid \"destructuring a\n // get-prop freezes reactivity\" gotcha). The listbox `tabIndex` is computed from\n // `focusedKey` (`focusedKey != null ? -1 : 0`); on open the effect above sets a\n // focused key, so a frozen snapshot would leave the listbox tabbable (`0`) when\n // upstream flips it to `-1`. Reading `listBoxHook.listBoxProps` per access keeps\n // it reactive.\n const listBoxHook = createListBox(\n {\n ...(menuProps as unknown as AriaListBoxProps),\n shouldSelectOnPressUp: true,\n shouldFocusOnHover: true,\n shouldSelectOnFocus: local.isInPopover === true ? false : undefined,\n get isDisabled() {\n return state.isDisabled;\n },\n },\n createSelectListStateAdapter(state),\n );\n\n const renderValues = createMemo<SelectListBoxRenderProps>(() => ({\n // Focus within the listbox itself (the selection manager's focus state),\n // not the select-level trigger focus.\n isFocused: state.selectionManager.isFocused,\n }));\n\n const renderProps = useRenderProps(\n {\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Select-listbox\",\n },\n renderValues,\n );\n\n const cleanMenuProps = () => {\n const { ref: _ref1, ...rest } = menuProps as Record<string, unknown>;\n return rest;\n };\n const cleanListBoxProps = () => {\n const {\n ref: _ref2,\n \"aria-activedescendant\": _activeDescendant,\n onFocus: _onFocus,\n ...rest\n } = listBoxHook.listBoxProps as Record<string, unknown>;\n // Faithful Select listbox focus model: the focused option receives REAL DOM\n // focus (the open effect above + `createSelectableItem`'s self-focus move\n // `document.activeElement` onto it), mirroring upstream `useSelect`. So the\n // listbox must (a) leave the tab sequence once an option is focused —\n // `useSelectableCollection` uses `tabIndex = focusedKey == null ? 0 : -1`\n // (useSelectableCollection.ts:687-690) — and (b) NOT expose\n // `aria-activedescendant`, which is the virtual-focus channel upstream Select\n // never uses. These are overridden here, not in the shared `createListBox`,\n // because the standalone `ListBox` keeps its container-focus model (focus\n // stays on the listbox, `aria-activedescendant` is its AT channel).\n //\n // We also drop `createListBox`'s container-focus TRAMPOLINE (`onFocus`): it\n // marshals the first key when the container is focused with `focusedKey ==\n // null`, which is exactly Select's deliberate click-open state (the open\n // effect sets `isFocused` true but leaves `focusedKey` null when nothing is\n // selected, so the first arrow enters the first item). Upstream's own\n // trampoline no-ops in this case because it guards on `manager.isFocused`\n // (already true); our shared guard uses `focusedKey == null` for the\n // standalone ListBox, so we strip it here to preserve Select's faithful\n // model. (Auto-selecting on focus under replace behavior would also toggle\n // the first item selected on open — the bug this override prevents.)\n return {\n ...rest,\n tabIndex: state.isDisabled ? undefined : state.focusedKey() != null ? -1 : 0,\n };\n };\n\n const items = () => Array.from(state.collection());\n createEffect(() => {\n if (!isOpen()) return;\n const focusedKey = state.focusedKey();\n if (focusedKey == null) return;\n\n queueMicrotask(() => {\n const option = Array.from(\n listBoxRef?.querySelectorAll<HTMLElement>(\"[role='option']\") ?? [],\n ).find((element) => element.id === String(focusedKey));\n if (option && document.activeElement !== option) {\n focusSafely(option);\n }\n });\n });\n\n const listBox = () => (\n // Upstream RAC ListBox (and our own Menu.tsx) render a `<div role=\"listbox\">`\n // over `<div role=\"option\">` rows, NOT `<ul>`/`<li>` — the collection is\n // div-based for virtualization parity. `<ul>`/`<li>` here was a self-inflicted\n // structural divergence surfaced by the Picker recertification (D5/D6/D8 saw\n // `li[option]`/`ul[listbox]` where the React oracle sees `div`).\n <div\n ref={(el) => (listBoxRef = el)}\n {...domProps}\n {...cleanMenuProps()}\n {...cleanListBoxProps()}\n class={renderProps.class()}\n style={renderProps.style()}\n data-focused={state.selectionManager.isFocused || undefined}\n data-empty={state.collection().size === 0 || undefined}\n >\n {state.collection().size === 0 && local.renderEmptyState ? (\n <div role=\"option\" style={{ display: \"contents\" }} data-empty-state>\n {local.renderEmptyState()}\n </div>\n ) : (\n <Show\n when={local.children}\n fallback={\n <For each={items()}>\n {(node) => <SelectOption id={node.key}>{node.textValue}</SelectOption>}\n </For>\n }\n >\n <For each={items()}>\n {(node) => (node.value != null ? local.children!(node.value) : null)}\n </For>\n </Show>\n )}\n <Show when={local.onLoadMore}>\n <ListBoxLoadMoreItem\n onLoadMore={local.onLoadMore!}\n isLoading={local.isLoading}\n class={local.loadMoreClass}\n >\n {local.renderLoadMore?.()}\n </ListBoxLoadMoreItem>\n </Show>\n </div>\n );\n\n return (\n <Show when={isOpen()}>\n <Show\n when={local.isInPopover}\n fallback={\n <FocusScope restoreFocus autoFocus>\n {listBox()}\n </FocusScope>\n }\n >\n {listBox()}\n </Show>\n </Show>\n );\n}\n\n/**\n * An option in a select listbox.\n */\nexport function SelectOption<T>(props: SelectOptionProps<T>): JSX.Element {\n const [local, ariaProps] = splitProps(props, [\n \"class\",\n \"style\",\n \"slot\",\n \"id\",\n \"item\",\n \"textValue\",\n \"ref\",\n ]);\n\n const context = useContext(SelectStateContext);\n if (!context) {\n throw new Error(\"SelectOption must be used within a Select\");\n }\n const state = context as SelectState<T>;\n const selectContext = useContext(SelectContext) as SelectContextValue<T> | null;\n const [ref, setRefSignal] = createSignal<HTMLDivElement | null>(null);\n const setRef = (el: HTMLDivElement | null) => {\n setRefSignal(el);\n assignRef(local.ref, el as HTMLDivElement);\n };\n\n const optionAria = createOption<T>(\n {\n key: local.id,\n get isDisabled() {\n return Boolean(ariaProps.isDisabled || selectContext?.isDisabled());\n },\n get \"aria-label\"() {\n return ariaProps[\"aria-label\"] ?? local.textValue;\n },\n shouldSelectOnPressUp: true,\n shouldFocusOnHover: true,\n get onHoverStart() {\n return ariaProps.onHoverStart;\n },\n get onHoverEnd() {\n return ariaProps.onHoverEnd;\n },\n get onHoverChange() {\n return ariaProps.onHoverChange;\n },\n },\n {\n ...createSelectListStateAdapter(state),\n select: (key: Key) => {\n if (state.selectionMode() === \"multiple\") {\n const keys = state.selectedKeys();\n if (keys === \"all\") return;\n state.setSelectedKeys(new Set([...keys, key]));\n return;\n }\n state.setSelectedKey(key);\n state.close();\n },\n toggleSelection: (key: Key) => {\n if (state.selectionMode() === \"multiple\") {\n const keys = state.selectedKeys();\n if (keys === \"all\") return;\n const next = new Set(keys);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n state.setSelectedKeys(next);\n return;\n }\n state.setSelectedKey(key);\n state.close();\n },\n replaceSelection: (key: Key) => {\n state.setSelectedKey(key);\n if (state.selectionMode() !== \"multiple\") {\n state.close();\n }\n },\n },\n () => ref(),\n );\n const isOptionFocusVisible = () =>\n optionAria.isFocused() && (selectContext?.isFocusVisible() ?? optionAria.isFocusVisible());\n\n const renderValues = createMemo<SelectOptionRenderProps>(() => ({\n isSelected: optionAria.isSelected(),\n isFocused: optionAria.isFocused(),\n isFocusVisible: isOptionFocusVisible(),\n isPressed: optionAria.isPressed(),\n isHovered: optionAria.isHovered(),\n isDisabled: optionAria.isDisabled(),\n }));\n\n const renderProps = useRenderProps(\n {\n get children() {\n return props.children;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Select-option\",\n },\n renderValues,\n );\n const hasPrimitiveLabel = () => {\n return typeof props.children === \"string\" || typeof props.children === \"number\";\n };\n\n const selectionIndicatorContext = createMemo<SelectionIndicatorContextValue>(() => ({\n isSelected: optionAria.isSelected,\n }));\n\n const cleanOptionProps = () => {\n const {\n ref: _ref1,\n \"aria-describedby\": _ariaDescribedby,\n ...rest\n } = optionAria.optionProps as Record<string, unknown>;\n if (!hasPrimitiveLabel() && rest[\"aria-label\"] == null) {\n delete rest[\"aria-labelledby\"];\n }\n const onClick = rest.onClick as ((event: MouseEvent) => void) | undefined;\n rest.onClick = ((event: MouseEvent) => {\n const wasSelected = optionAria.isSelected();\n onClick?.(event);\n if (typeof PointerEvent === \"undefined\") {\n return;\n }\n queueMicrotask(() => {\n if (state.selectionMode() !== \"multiple\" || optionAria.isSelected() === wasSelected) {\n selectOption();\n }\n });\n }) as JSX.EventHandler<HTMLDivElement, MouseEvent>;\n return rest;\n };\n const selectOption = () => {\n if (optionAria.isDisabled()) {\n return;\n }\n if (state.selectionMode() === \"multiple\") {\n const keys = state.selectedKeys();\n if (keys === \"all\") return;\n const next = new Set(keys);\n if (next.has(local.id)) next.delete(local.id);\n else next.add(local.id);\n state.setSelectedKeys(next);\n return;\n }\n state.setSelectedKey(local.id);\n state.close();\n };\n\n return (\n <SelectionIndicatorContext.Provider value={selectionIndicatorContext()}>\n {/* `<div role=\"option\">`, not `<li>` — see the SelectListBox note; upstream\n RAC options are div-based. */}\n <div\n ref={setRef}\n {...cleanOptionProps()}\n class={renderProps.class()}\n style={renderProps.style()}\n data-selected={optionAria.isSelected() || undefined}\n data-focused={optionAria.isFocused() || undefined}\n data-focus-visible={isOptionFocusVisible() || undefined}\n data-pressed={optionAria.isPressed() || undefined}\n data-hovered={optionAria.isHovered() || undefined}\n data-disabled={optionAria.isDisabled() || undefined}\n >\n {hasPrimitiveLabel() ? (\n <span {...optionAria.labelProps}>{renderProps.renderChildren()}</span>\n ) : (\n renderProps.renderChildren()\n )}\n </div>\n </SelectionIndicatorContext.Provider>\n );\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction toKey(value: unknown): Key | undefined {\n if (typeof value === \"string\" || typeof value === \"number\") {\n return value;\n }\n return undefined;\n}\n\nfunction toTextValue(value: unknown): string | undefined {\n if (typeof value === \"string\" || typeof value === \"number\") {\n return String(value);\n }\n return undefined;\n}\n\nfunction createSelectListStateAdapter<T>(state: SelectState<T>): ListState<T> {\n const selectedKeys = createMemo(() => {\n const keys = state.selectedKeys();\n return keys === \"all\" ? new Set(Array.from(state.collection()).map((item) => item.key)) : keys;\n });\n\n const disabledKeys = createMemo(() => {\n const keys = new Set<Key>();\n for (const node of state.collection()) {\n if (node.isDisabled) keys.add(node.key);\n }\n return keys;\n });\n\n return {\n collection: state.collection,\n selectionManager: state.selectionManager,\n // Collection-level focus (the selection manager's), not the select-level\n // trigger focus — upstream listbox internals only ever read\n // state.selectionManager.isFocused.\n isFocused: () => state.selectionManager.isFocused,\n setFocused: (isFocused) => state.selectionManager.setFocused(isFocused),\n focusedKey: state.focusedKey,\n setFocusedKey: (key) => state.setFocusedKey(key ?? null),\n childFocusStrategy: () => null,\n selectionMode: () => state.selectionMode(),\n selectionBehavior: () => \"replace\",\n disallowEmptySelection: () => true,\n selectedKeys,\n disabledKeys,\n disabledBehavior: () => \"all\",\n isEmpty: () => selectedKeys().size === 0,\n isSelectAll: () => state.selectedKeys() === \"all\",\n isSelected: (key) => selectedKeys().has(key),\n isDisabled: state.isKeyDisabled,\n setSelectionBehavior: () => {},\n toggleSelection: (key) => {\n if (state.selectionMode() !== \"multiple\") {\n state.setSelectedKey(key);\n return;\n }\n const keys = state.selectedKeys();\n if (keys === \"all\") return;\n const next = new Set(keys);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n state.setSelectedKeys(next);\n },\n replaceSelection: (key) => state.setSelectedKey(key),\n setSelectedKeys: (keys) => state.setSelectedKeys(keys),\n selectAll: () => {},\n clearSelection: () =>\n state.selectionMode() === \"multiple\" ? state.setSelectedKeys([]) : state.setSelectedKey(null),\n toggleSelectAll: () => {},\n extendSelection: (toKey) => state.setSelectedKey(toKey),\n select: (key) =>\n state.selectionMode() === \"multiple\"\n ? state.setSelectedKeys([\n ...(state.selectedKeys() === \"all\" ? [] : (state.selectedKeys() as Set<Key>)),\n key,\n ])\n : state.setSelectedKey(key),\n };\n}\n\nSelect.Trigger = SelectTrigger;\nSelect.Value = SelectValue;\nSelect.ListBox = SelectListBox;\nSelect.Option = SelectOption;\n"],"mappings":"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"}
|
package/dist/Separator.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { filterDOMProps } from "./utils.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ElementTag } from "./ElementTag.js";
|
|
3
|
+
import { createComponent, mergeProps } from "solid-js/web";
|
|
3
4
|
import { createContext, createMemo, splitProps } from "solid-js";
|
|
4
5
|
import { createSeparator } from "@proyecto-viviana/solidaria";
|
|
5
6
|
//#region src/Separator.tsx
|
|
@@ -76,7 +77,7 @@ function Separator(props) {
|
|
|
76
77
|
if (typeof style === "function") return style(renderValues());
|
|
77
78
|
return style;
|
|
78
79
|
});
|
|
79
|
-
return createComponent(
|
|
80
|
+
return createComponent(ElementTag, mergeProps({ get tag() {
|
|
80
81
|
return elementType();
|
|
81
82
|
} }, createMemo(() => filterDOMProps(ariaProps, { global: true })), () => separatorAria.separatorProps, {
|
|
82
83
|
ref: (el) => assignRef(local.ref, el),
|
package/dist/Separator.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Separator.js","names":["JSX","createContext","createMemo","splitProps","
|
|
1
|
+
{"version":3,"file":"Separator.js","names":["JSX","createContext","createMemo","splitProps","ElementTag","createSeparator","AriaSeparatorProps","Orientation","SlotProps","filterDOMProps","RefLike","el","T","current","assignRef","ref","SeparatorRenderProps","orientation","SeparatorProps","class","renderProps","style","CSSProperties","HTMLElement","SeparatorContext","Separator","props","Element","local","ariaProps","elementType","element","separatorAria","aria-label","aria-labelledby","aria-describedby","aria-details","id","renderValues","resolvedClass","cls","resolvedStyle","domProps","global","_$createComponent","_$mergeProps","tag","separatorProps","slot"],"sources":["../src/Separator.tsx"],"sourcesContent":["/**\n * Separator component for solidaria-components\n *\n * Pre-wired headless separator component that combines aria hooks.\n * Port of react-aria-components/src/Separator.tsx\n */\n\nimport { type JSX, createContext, createMemo, splitProps } from \"solid-js\";\nimport { ElementTag } from \"./ElementTag\";\nimport {\n createSeparator,\n type AriaSeparatorProps,\n type Orientation,\n} from \"@proyecto-viviana/solidaria\";\nimport { type SlotProps, filterDOMProps } from \"./utils\";\n\ntype RefLike<T> = ((el: T) => void) | { current?: T | null } | undefined;\n\nfunction assignRef<T>(ref: RefLike<T>, el: T): void {\n if (!ref) return;\n if (typeof ref === \"function\") {\n ref(el);\n } else {\n ref.current = el;\n }\n}\n\nexport interface SeparatorRenderProps {\n /** The orientation of the separator. */\n orientation: Orientation;\n}\n\nexport interface SeparatorProps extends AriaSeparatorProps, SlotProps {\n /** The CSS className for the element. A function may be provided to receive render props. */\n class?: string | ((renderProps: SeparatorRenderProps) => string);\n /** The inline style for the element. A function may be provided to receive render props. */\n style?: JSX.CSSProperties | ((renderProps: SeparatorRenderProps) => JSX.CSSProperties);\n /** Ref for the underlying separator element. */\n ref?: RefLike<HTMLElement>;\n}\n\nexport const SeparatorContext = createContext<SeparatorProps | null>(null);\n\n/**\n * A separator is a visual divider between two groups of content,\n * e.g. groups of menu items or sections of a page.\n *\n * @example\n * ```tsx\n * <Separator />\n *\n * // Vertical separator\n * <Separator orientation=\"vertical\" />\n *\n * // Custom element type\n * <Separator elementType=\"div\" />\n * ```\n */\nexport function Separator(props: SeparatorProps): JSX.Element {\n const [local, ariaProps] = splitProps(props, [\"class\", \"style\", \"ref\", \"slot\"]);\n\n const elementType = createMemo(() => {\n let element = ariaProps.elementType || \"hr\";\n // If vertical and using hr, switch to div since hr is inherently horizontal\n if (element === \"hr\" && ariaProps.orientation === \"vertical\") {\n element = \"div\";\n }\n return element;\n });\n\n const separatorAria = createSeparator({\n get orientation() {\n return ariaProps.orientation;\n },\n get elementType() {\n return ariaProps.elementType;\n },\n get \"aria-label\"() {\n return ariaProps[\"aria-label\"];\n },\n get \"aria-labelledby\"() {\n return ariaProps[\"aria-labelledby\"];\n },\n get \"aria-describedby\"() {\n return ariaProps[\"aria-describedby\"];\n },\n get \"aria-details\"() {\n return ariaProps[\"aria-details\"];\n },\n get id() {\n return ariaProps.id;\n },\n });\n\n const renderValues = createMemo<SeparatorRenderProps>(() => ({\n orientation: ariaProps.orientation ?? \"horizontal\",\n }));\n\n const resolvedClass = createMemo(() => {\n const cls = local.class;\n if (typeof cls === \"function\") {\n return cls(renderValues());\n }\n return cls ?? \"solidaria-Separator\";\n });\n\n const resolvedStyle = createMemo(() => {\n const style = local.style;\n if (typeof style === \"function\") {\n return style(renderValues());\n }\n return style;\n });\n\n const domProps = createMemo(() => filterDOMProps(ariaProps, { global: true }));\n\n return (\n <ElementTag\n tag={elementType()}\n {...domProps()}\n {...separatorAria.separatorProps}\n ref={(el: HTMLElement) => assignRef(local.ref, el)}\n class={resolvedClass()}\n style={resolvedStyle()}\n slot={local.slot}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;AAkBA,SAASc,UAAaC,KAAiBJ,IAAa;CAClD,IAAI,CAACI,KAAK;CACV,IAAI,OAAOA,QAAQ,YACjBA,IAAIJ,EAAE;MAENI,IAAIF,UAAUF;AAElB;AAgBA,MAAaa,mBAAmBvB,cAAqC,IAAI;;;;;;;;;;;;;;;;AAiBzE,SAAgBwB,UAAUC,OAAoC;CAC5D,MAAM,CAACE,OAAOC,aAAa1B,WAAWuB,OAAO;EAAC;EAAS;EAAS;EAAO;CAAM,CAAC;CAE9E,MAAMI,cAAc5B,iBAAiB;EACnC,IAAI6B,UAAUF,UAAUC,eAAe;EAEvC,IAAIC,YAAY,QAAQF,UAAUZ,gBAAgB,YAChDc,UAAU;EAEZ,OAAOA;CACT,CAAC;CAED,MAAMC,gBAAgB3B,gBAAgB;EACpC,IAAIY,cAAc;GAChB,OAAOY,UAAUZ;EACnB;EACA,IAAIa,cAAc;GAChB,OAAOD,UAAUC;EACnB;EACA,IAAI,eAAe;GACjB,OAAOD,UAAU;EACnB;EACA,IAAI,oBAAoB;GACtB,OAAOA,UAAU;EACnB;EACA,IAAI,qBAAqB;GACvB,OAAOA,UAAU;EACnB;EACA,IAAI,iBAAiB;GACnB,OAAOA,UAAU;EACnB;EACA,IAAIQ,KAAK;GACP,OAAOR,UAAUQ;EACnB;CACF,CAAC;CAED,MAAMC,eAAepC,kBAAwC,EAC3De,aAAaY,UAAUZ,eAAe,aACxC,EAAE;CAEF,MAAMsB,gBAAgBrC,iBAAiB;EACrC,MAAMsC,MAAMZ,MAAMT;EAClB,IAAI,OAAOqB,QAAQ,YACjB,OAAOA,IAAIF,aAAa,CAAC;EAE3B,OAAOE,OAAO;CAChB,CAAC;CAED,MAAMC,gBAAgBvC,iBAAiB;EACrC,MAAMmB,QAAQO,MAAMP;EACpB,IAAI,OAAOA,UAAU,YACnB,OAAOA,MAAMiB,aAAa,CAAC;EAE7B,OAAOjB;CACT,CAAC;CAID,OAAAuB,gBACGxC,YAAUyC,WAAA,EAAA,IACTC,MAAG;EAAA,OAAEhB,YAAY;CAAC,EAAA,GAJL5B,iBAAiBO,eAAeoB,WAAW,EAAEc,QAAQ,KAAK,CAAC,CAKpED,SACAV,cAAce,gBAAc;EAAAhC,MAC1BJ,OAAoBG,UAAUc,MAAMb,KAAKJ,EAAE;EAAC,KAAA,WAAA;GAAA,OAC3C4B,cAAc;EAAC;EAAA,IACtBlB,QAAK;GAAA,OAAEoB,cAAc;EAAC;EAAA,IACtBO,OAAI;GAAA,OAAEpB,MAAMoB;EAAI;CAAA,CAAA,CAAA;AAGtB"}
|
package/dist/Separator.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { filterDOMProps } from "./utils.jsx";
|
|
2
|
+
import { ElementTag } from "./ElementTag.jsx";
|
|
2
3
|
import { createContext, createMemo, splitProps } from "solid-js";
|
|
3
|
-
import { Dynamic } from "solid-js/web";
|
|
4
4
|
import { createSeparator } from "@proyecto-viviana/solidaria";
|
|
5
5
|
//#region src/Separator.tsx
|
|
6
6
|
/**
|
|
@@ -77,7 +77,7 @@ function Separator(props) {
|
|
|
77
77
|
return style;
|
|
78
78
|
});
|
|
79
79
|
const domProps = createMemo(() => filterDOMProps(ariaProps, { global: true }));
|
|
80
|
-
return <
|
|
80
|
+
return <ElementTag tag={elementType()} {...domProps()} {...separatorAria.separatorProps} ref={(el) => assignRef(local.ref, el)} class={resolvedClass()} style={resolvedStyle()} slot={local.slot} />;
|
|
81
81
|
}
|
|
82
82
|
//#endregion
|
|
83
83
|
export { Separator, SeparatorContext };
|
package/dist/Separator.jsx.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Separator.jsx","names":[],"sources":["../src/Separator.tsx"],"sourcesContent":["/**\n * Separator component for solidaria-components\n *\n * Pre-wired headless separator component that combines aria hooks.\n * Port of react-aria-components/src/Separator.tsx\n */\n\nimport { type JSX, createContext, createMemo, splitProps } from \"solid-js\";\nimport {
|
|
1
|
+
{"version":3,"file":"Separator.jsx","names":[],"sources":["../src/Separator.tsx"],"sourcesContent":["/**\n * Separator component for solidaria-components\n *\n * Pre-wired headless separator component that combines aria hooks.\n * Port of react-aria-components/src/Separator.tsx\n */\n\nimport { type JSX, createContext, createMemo, splitProps } from \"solid-js\";\nimport { ElementTag } from \"./ElementTag\";\nimport {\n createSeparator,\n type AriaSeparatorProps,\n type Orientation,\n} from \"@proyecto-viviana/solidaria\";\nimport { type SlotProps, filterDOMProps } from \"./utils\";\n\ntype RefLike<T> = ((el: T) => void) | { current?: T | null } | undefined;\n\nfunction assignRef<T>(ref: RefLike<T>, el: T): void {\n if (!ref) return;\n if (typeof ref === \"function\") {\n ref(el);\n } else {\n ref.current = el;\n }\n}\n\nexport interface SeparatorRenderProps {\n /** The orientation of the separator. */\n orientation: Orientation;\n}\n\nexport interface SeparatorProps extends AriaSeparatorProps, SlotProps {\n /** The CSS className for the element. A function may be provided to receive render props. */\n class?: string | ((renderProps: SeparatorRenderProps) => string);\n /** The inline style for the element. A function may be provided to receive render props. */\n style?: JSX.CSSProperties | ((renderProps: SeparatorRenderProps) => JSX.CSSProperties);\n /** Ref for the underlying separator element. */\n ref?: RefLike<HTMLElement>;\n}\n\nexport const SeparatorContext = createContext<SeparatorProps | null>(null);\n\n/**\n * A separator is a visual divider between two groups of content,\n * e.g. groups of menu items or sections of a page.\n *\n * @example\n * ```tsx\n * <Separator />\n *\n * // Vertical separator\n * <Separator orientation=\"vertical\" />\n *\n * // Custom element type\n * <Separator elementType=\"div\" />\n * ```\n */\nexport function Separator(props: SeparatorProps): JSX.Element {\n const [local, ariaProps] = splitProps(props, [\"class\", \"style\", \"ref\", \"slot\"]);\n\n const elementType = createMemo(() => {\n let element = ariaProps.elementType || \"hr\";\n // If vertical and using hr, switch to div since hr is inherently horizontal\n if (element === \"hr\" && ariaProps.orientation === \"vertical\") {\n element = \"div\";\n }\n return element;\n });\n\n const separatorAria = createSeparator({\n get orientation() {\n return ariaProps.orientation;\n },\n get elementType() {\n return ariaProps.elementType;\n },\n get \"aria-label\"() {\n return ariaProps[\"aria-label\"];\n },\n get \"aria-labelledby\"() {\n return ariaProps[\"aria-labelledby\"];\n },\n get \"aria-describedby\"() {\n return ariaProps[\"aria-describedby\"];\n },\n get \"aria-details\"() {\n return ariaProps[\"aria-details\"];\n },\n get id() {\n return ariaProps.id;\n },\n });\n\n const renderValues = createMemo<SeparatorRenderProps>(() => ({\n orientation: ariaProps.orientation ?? \"horizontal\",\n }));\n\n const resolvedClass = createMemo(() => {\n const cls = local.class;\n if (typeof cls === \"function\") {\n return cls(renderValues());\n }\n return cls ?? \"solidaria-Separator\";\n });\n\n const resolvedStyle = createMemo(() => {\n const style = local.style;\n if (typeof style === \"function\") {\n return style(renderValues());\n }\n return style;\n });\n\n const domProps = createMemo(() => filterDOMProps(ariaProps, { global: true }));\n\n return (\n <ElementTag\n tag={elementType()}\n {...domProps()}\n {...separatorAria.separatorProps}\n ref={(el: HTMLElement) => assignRef(local.ref, el)}\n class={resolvedClass()}\n style={resolvedStyle()}\n slot={local.slot}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;AAkBA,SAAS,UAAa,KAAiB,IAAa;CAClD,IAAI,CAAC,KAAK;CACV,IAAI,OAAO,QAAQ,YACjB,IAAI,EAAE;MAEN,IAAI,UAAU;AAElB;AAgBA,MAAa,mBAAmB,cAAqC,IAAI;;;;;;;;;;;;;;;;AAiBzE,SAAgB,UAAU,OAAoC;CAC5D,MAAM,CAAC,OAAO,aAAa,WAAW,OAAO;EAAC;EAAS;EAAS;EAAO;CAAM,CAAC;CAE9E,MAAM,cAAc,iBAAiB;EACnC,IAAI,UAAU,UAAU,eAAe;EAEvC,IAAI,YAAY,QAAQ,UAAU,gBAAgB,YAChD,UAAU;EAEZ,OAAO;CACT,CAAC;CAED,MAAM,gBAAgB,gBAAgB;EACpC,IAAI,cAAc;GAChB,OAAO,UAAU;EACnB;EACA,IAAI,cAAc;GAChB,OAAO,UAAU;EACnB;EACA,IAAI,eAAe;GACjB,OAAO,UAAU;EACnB;EACA,IAAI,oBAAoB;GACtB,OAAO,UAAU;EACnB;EACA,IAAI,qBAAqB;GACvB,OAAO,UAAU;EACnB;EACA,IAAI,iBAAiB;GACnB,OAAO,UAAU;EACnB;EACA,IAAI,KAAK;GACP,OAAO,UAAU;EACnB;CACF,CAAC;CAED,MAAM,eAAe,kBAAwC,EAC3D,aAAa,UAAU,eAAe,aACxC,EAAE;CAEF,MAAM,gBAAgB,iBAAiB;EACrC,MAAM,MAAM,MAAM;EAClB,IAAI,OAAO,QAAQ,YACjB,OAAO,IAAI,aAAa,CAAC;EAE3B,OAAO,OAAO;CAChB,CAAC;CAED,MAAM,gBAAgB,iBAAiB;EACrC,MAAM,QAAQ,MAAM;EACpB,IAAI,OAAO,UAAU,YACnB,OAAO,MAAM,aAAa,CAAC;EAE7B,OAAO;CACT,CAAC;CAED,MAAM,WAAW,iBAAiB,eAAe,WAAW,EAAE,QAAQ,KAAK,CAAC,CAAC;CAE7E,OACE,CAAC,WACC,KAAK,YAAY,OACb,SAAS,OACT,cAAc,gBAClB,MAAM,OAAoB,UAAU,MAAM,KAAK,EAAE,GACjD,OAAO,cAAc,GACrB,OAAO,cAAc,GACrB,MAAM,MAAM;AAGlB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedElementTransition.d.ts","sourceRoot":"","sources":["../src/SharedElementTransition.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,KAAK,GAAG,EAYT,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,cAAc,EAGpB,MAAM,SAAS,CAAC;AAoBjB,wBAAgB,kCAAkC,IAAI,OAAO,CAE5D;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,GAAG,GAAG,CAAC,OAAO,CAQxF;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAClD,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,EAClC,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CACvC;IACC,QAAQ,CAAC,EAAE,cAAc,CAAC,wBAAwB,CAAC,CAAC;IACpD,KAAK,CAAC,EAAE,mBAAmB,CAAC,wBAAwB,CAAC,CAAC;IACtD,KAAK,CAAC,EAAE,eAAe,CAAC,wBAAwB,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,kBAAmB,SAAQ,sBAAsB;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,cAAc,KAAK,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,cAAc,CAAA;KAAE,CAAC;CACrE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"SharedElementTransition.d.ts","sourceRoot":"","sources":["../src/SharedElementTransition.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,KAAK,GAAG,EAYT,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,cAAc,EAGpB,MAAM,SAAS,CAAC;AAoBjB,wBAAgB,kCAAkC,IAAI,OAAO,CAE5D;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,GAAG,GAAG,CAAC,OAAO,CAQxF;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAClD,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,EAClC,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CACvC;IACC,QAAQ,CAAC,EAAE,cAAc,CAAC,wBAAwB,CAAC,CAAC;IACpD,KAAK,CAAC,EAAE,mBAAmB,CAAC,wBAAwB,CAAC,CAAC;IACtD,KAAK,CAAC,EAAE,eAAe,CAAC,wBAAwB,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,kBAAmB,SAAQ,sBAAsB;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,cAAc,KAAK,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,cAAc,CAAA;KAAE,CAAC;CACrE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CA+N3E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedElementTransition.js","names":["JSX","createContext","createEffect","createMemo","createRenderEffect","createSignal","onCleanup","splitProps","untrack","useContext","Show","on","ClassNameOrFunction","StyleOrFunction","RenderChildren","useRenderProps","filterDOMProps","SharedElementLifecycle","getAnimations","el","HTMLElement","Animation","Snapshot","rect","DOMRect","style","SharedElementScope","snapshots","name","SharedElementContext","useHasSharedElementTransitionScope","SharedElementTransitionProps","children","Element","SharedElementTransition","props","scope","_$createComponent","Provider","value","SharedElementRenderProps","isEntering","isExiting","SharedElementPropsBase","Omit","HTMLAttributes","HTMLDivElement","class","SharedElementProps","isVisible","ref","current","SharedElement","Error","local","domProps","lifecycle","setLifecycle","element","setElement","frame","setRef","userRef","undefined","storeSnapshot","isConnected","hasAttribute","window","getComputedStyle","transitionProperty","split","getBoundingClientRect","map","property","getPropertyValue","const","cancelAnimationFrame","prevSnapshot","animations","values","prevValue","prevRect","currentRect","deltaX","left","deltaY","top","setProperty","a","includes","cancel","requestAnimationFrame","queueMicrotask","Promise","all","finished","then","catch","renderProps","defaultClassName","filteredDomProps","global","when","_el$","_$getNextElement","_tmpl$","_$use","_$spread","_$mergeProps","data-entering","data-exiting","_$insert","renderChildren","_$runHydrationEvents"],"sources":["../src/SharedElementTransition.tsx"],"sourcesContent":["/**\n * SharedElementTransition primitives for solidaria-components.\n *\n * Provides FLIP-based shared element animations when elements move between\n * parents within a scope. Captures geometry snapshots on unmount and applies\n * transition animations on mount.\n *\n * Parity target: react-aria-components/src/SharedElementTransition.tsx\n */\n\nimport {\n type JSX,\n createContext,\n createEffect,\n createMemo,\n createRenderEffect,\n createSignal,\n onCleanup,\n splitProps,\n untrack,\n useContext,\n Show,\n on,\n} from \"solid-js\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type RenderChildren,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\n\ntype SharedElementLifecycle = \"hidden\" | \"entering\" | \"visible\" | \"exiting\";\n\n/** Safe wrapper — jsdom doesn't implement the Web Animations API. */\nfunction getAnimations(el: HTMLElement): Animation[] {\n return typeof el.getAnimations === \"function\" ? el.getAnimations() : [];\n}\n\ninterface Snapshot {\n rect: DOMRect;\n style: [string, string][];\n}\n\ninterface SharedElementScope {\n snapshots: { [name: string]: Snapshot };\n}\n\nconst SharedElementContext = createContext<SharedElementScope | null>(null);\n\nexport function useHasSharedElementTransitionScope(): boolean {\n return useContext(SharedElementContext) != null;\n}\n\nexport interface SharedElementTransitionProps {\n children?: JSX.Element;\n}\n\n/**\n * A scope for SharedElements, which animate between parents.\n */\nexport function SharedElementTransition(props: SharedElementTransitionProps): JSX.Element {\n const scope: SharedElementScope = {\n snapshots: {},\n };\n\n return (\n <SharedElementContext.Provider value={scope}>{props.children}</SharedElementContext.Provider>\n );\n}\n\nexport interface SharedElementRenderProps {\n isEntering: boolean;\n isExiting: boolean;\n}\n\nexport interface SharedElementPropsBase extends Omit<\n JSX.HTMLAttributes<HTMLDivElement>,\n \"children\" | \"class\" | \"style\" | \"ref\"\n> {\n children?: RenderChildren<SharedElementRenderProps>;\n class?: ClassNameOrFunction<SharedElementRenderProps>;\n style?: StyleOrFunction<SharedElementRenderProps>;\n}\n\nexport interface SharedElementProps extends SharedElementPropsBase {\n name: string;\n isVisible?: boolean;\n ref?: ((el: HTMLDivElement) => void) | { current?: HTMLDivElement };\n}\n\n/**\n * An element that animates between its old and new position when moving\n * between parents within a SharedElementTransition scope.\n */\nexport function SharedElement(props: SharedElementProps): JSX.Element | null {\n const scope = useContext(SharedElementContext);\n if (!scope) {\n throw new Error(\"<SharedElement> must be rendered inside a <SharedElementTransition>\");\n }\n\n const [local, domProps] = splitProps(props, [\n \"name\",\n \"isVisible\",\n \"children\",\n \"class\",\n \"style\",\n \"ref\",\n ]);\n\n const [lifecycle, setLifecycle] = createSignal<SharedElementLifecycle>(\n local.isVisible === false ? \"hidden\" : \"visible\",\n );\n\n // The mounted div, tracked as a signal so the FLIP-read effect below REACTS to\n // it appearing. React guarantees `ref.current` is committed before the layout\n // effect body runs; Solid gives no such ordering between the `<Show>`'s\n // insertion render-effect and a plain createEffect, so we make the read depend\n // on the element instead of racing its mount (see READ PHASE).\n const [element, setElement] = createSignal<HTMLDivElement | undefined>();\n let frame: number | undefined;\n\n const setRef = (el: HTMLDivElement) => {\n setElement(el);\n // Forward ref to consumer\n const userRef = local.ref;\n if (typeof userRef === \"function\") {\n userRef(el);\n } else if (userRef !== undefined) {\n userRef.current = el;\n }\n };\n\n // Store a geometry + transition-style snapshot of the currently-mounted\n // element, so a sibling SharedElement with the same `name` can FLIP from it.\n // Mirrors upstream's layout-effect *cleanup*\n // (react-aria-components/src/SharedElementTransition.tsx), which runs for\n // every `isVisible` flip — not only on unmount.\n const storeSnapshot = () => {\n const el = untrack(element);\n if (el && el.isConnected && !el.hasAttribute(\"data-exiting\")) {\n // Store a snapshot of the rectangle and computed style for transitioning properties.\n const style = window.getComputedStyle(el);\n if (style.transitionProperty !== \"none\") {\n const transitionProperty = style.transitionProperty.split(/\\s*,\\s*/);\n scope.snapshots[local.name] = {\n rect: el.getBoundingClientRect(),\n style: transitionProperty.map((property) => [property, style.getPropertyValue(property)]),\n };\n }\n }\n };\n\n // MOUNT-IN-RENDER — mirrors upstream's render-phase\n // `if (isVisible && state === 'hidden') setState('visible')`. Promoting a\n // hidden element to visible in the render phase mounts its div (via the\n // `<Show>` below) BEFORE the FLIP-read createEffect runs, so the incoming\n // element is in the DOM to be measured and translated. Without this the\n // incoming element's ref is still null when the read effect fires and it can\n // only enter fresh — never FLIP. Keyed on `isVisible` (untracked lifecycle\n // read) so it cannot loop.\n createRenderEffect(\n on(\n () => local.isVisible !== false,\n (isVisible) => {\n if (isVisible && untrack(lifecycle) === \"hidden\") {\n setLifecycle(\"visible\");\n }\n },\n ),\n );\n\n // STORE PHASE — a render effect runs before user effects within a Solid\n // batch, exactly as React runs all layout-effect destroys before any create.\n // The cleanup registered here fires on the *next* `isVisible` change (and on\n // disposal), capturing the outgoing snapshot BEFORE any sibling's FLIP-read\n // createEffect below runs — React's two-phase commit. Only the cleanup\n // registered while VISIBLE stores (an outgoing element); an incoming\n // element's prior cleanup was registered while hidden and must not clobber\n // the outgoing snapshot. This mirrors React closing over `element =\n // ref.current`, which is null while hidden.\n createRenderEffect(\n on(\n () => local.isVisible !== false,\n (isVisible) => {\n onCleanup(() => {\n if (isVisible) {\n storeSnapshot();\n }\n });\n },\n ),\n );\n\n // READ PHASE — mirrors upstream's layout-effect body, which reads the freshly\n // committed `ref.current`. Keying on the `element` signal (not just isVisible)\n // makes this run only once the incoming div is actually mounted: when isVisible\n // flips true the mount-in-render effect above mounts the div, `setRef` sets the\n // signal, and this effect runs with `el` present — never against a null ref.\n // (Solid batches, so an isVisible flip + the resulting mount coalesce into one\n // run with the mounted element.) There is therefore no \"element not yet in DOM\"\n // fresh-enter branch: with no committed div there is nothing to measure, so we\n // wait — exactly as React never runs the body before commit.\n createEffect(\n on(\n [() => local.isVisible !== false, element] as const,\n ([isVisible, el]) => {\n const name = local.name;\n\n if (frame != null) {\n cancelAnimationFrame(frame);\n frame = undefined;\n }\n\n if (isVisible && el) {\n const prevSnapshot = scope.snapshots[name];\n\n if (prevSnapshot) {\n // FLIP: Element is transitioning from a previous instance.\n setLifecycle(\"visible\");\n const animations = getAnimations(el);\n\n // Set properties to animate from.\n const values = prevSnapshot.style.map(([property, prevValue]) => {\n const value = el.style.getPropertyValue(property);\n if (property === \"translate\") {\n const prevRect = prevSnapshot.rect;\n const currentRect = el.getBoundingClientRect();\n const deltaX = prevRect.left - currentRect.left;\n const deltaY = prevRect.top - currentRect.top;\n el.style.setProperty(\"translate\", `${deltaX}px ${deltaY}px`);\n } else {\n el.style.setProperty(property, prevValue);\n }\n return [property, value] as [string, string];\n });\n\n // Cancel any new animations triggered by these properties.\n for (const a of getAnimations(el)) {\n if (!animations.includes(a)) {\n a.cancel();\n }\n }\n\n // Remove overrides after one frame to animate to the current values.\n frame = requestAnimationFrame(() => {\n frame = undefined;\n for (const [property, value] of values) {\n el.style.setProperty(property, value);\n }\n });\n\n delete scope.snapshots[name];\n } else {\n // No previous instance exists, apply the entering state.\n queueMicrotask(() => setLifecycle(\"entering\"));\n frame = requestAnimationFrame(() => {\n frame = undefined;\n setLifecycle(\"visible\");\n });\n }\n } else if (!isVisible && el) {\n // Wait a microtask to check if a snapshot still exists (meaning no new\n // SharedElement consumed it), then enter exiting state.\n queueMicrotask(() => {\n if (scope.snapshots[name]) {\n delete scope.snapshots[name];\n setLifecycle(\"exiting\");\n // Wait for animations to finish before hiding.\n Promise.all(getAnimations(el).map((a) => a.finished))\n .then(() => setLifecycle(\"hidden\"))\n .catch(() => {});\n } else {\n // Snapshot was consumed by another instance, unmount immediately.\n setLifecycle(\"hidden\");\n }\n });\n }\n },\n ),\n );\n\n // Cancel any pending FLIP frame on disposal. The snapshot store lives in the\n // render-effect cleanup above, which also fires on disposal.\n onCleanup(() => {\n if (frame != null) {\n cancelAnimationFrame(frame);\n }\n });\n\n const renderProps = useRenderProps(\n {\n get children() {\n return local.children;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-SharedElement\",\n },\n () => ({\n isEntering: lifecycle() === \"entering\",\n isExiting: lifecycle() === \"exiting\",\n }),\n );\n\n const filteredDomProps = createMemo(() => filterDOMProps(domProps, { global: true }));\n\n return (\n <Show when={lifecycle() !== \"hidden\"}>\n <div\n ref={setRef}\n {...filteredDomProps()}\n class={renderProps.class()}\n style={renderProps.style()}\n data-entering={lifecycle() === \"entering\" || undefined}\n data-exiting={lifecycle() === \"exiting\" || undefined}\n >\n {renderProps.renderChildren()}\n </div>\n </Show>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SharedElementTransition.js","names":["JSX","createContext","createEffect","createMemo","createRenderEffect","createSignal","onCleanup","splitProps","untrack","useContext","Show","on","ClassNameOrFunction","StyleOrFunction","RenderChildren","useRenderProps","filterDOMProps","SharedElementLifecycle","getAnimations","el","HTMLElement","Animation","Snapshot","rect","DOMRect","style","SharedElementScope","snapshots","name","SharedElementContext","useHasSharedElementTransitionScope","SharedElementTransitionProps","children","Element","SharedElementTransition","props","scope","_$createComponent","Provider","value","SharedElementRenderProps","isEntering","isExiting","SharedElementPropsBase","Omit","HTMLAttributes","HTMLDivElement","class","SharedElementProps","isVisible","ref","current","SharedElement","Error","local","domProps","lifecycle","setLifecycle","element","setElement","frame","setRef","userRef","undefined","storeSnapshot","isConnected","hasAttribute","window","getComputedStyle","transitionProperty","split","getBoundingClientRect","map","property","getPropertyValue","const","cancelAnimationFrame","prevSnapshot","animations","values","prevValue","prevRect","currentRect","deltaX","left","deltaY","top","setProperty","a","includes","cancel","requestAnimationFrame","queueMicrotask","Promise","all","finished","then","catch","renderProps","defaultClassName","filteredDomProps","global","when","_el$","_$getNextElement","_tmpl$","_$use","_$spread","_$mergeProps","data-entering","data-exiting","_$insert","renderChildren","_$runHydrationEvents"],"sources":["../src/SharedElementTransition.tsx"],"sourcesContent":["/**\n * SharedElementTransition primitives for solidaria-components.\n *\n * Provides FLIP-based shared element animations when elements move between\n * parents within a scope. Captures geometry snapshots on unmount and applies\n * transition animations on mount.\n *\n * Parity target: react-aria-components/src/SharedElementTransition.tsx\n */\n\nimport {\n type JSX,\n createContext,\n createEffect,\n createMemo,\n createRenderEffect,\n createSignal,\n onCleanup,\n splitProps,\n untrack,\n useContext,\n Show,\n on,\n} from \"solid-js\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type RenderChildren,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\n\ntype SharedElementLifecycle = \"hidden\" | \"entering\" | \"visible\" | \"exiting\";\n\n/** Safe wrapper — jsdom doesn't implement the Web Animations API. */\nfunction getAnimations(el: HTMLElement): Animation[] {\n return typeof el.getAnimations === \"function\" ? el.getAnimations() : [];\n}\n\ninterface Snapshot {\n rect: DOMRect;\n style: [string, string][];\n}\n\ninterface SharedElementScope {\n snapshots: { [name: string]: Snapshot };\n}\n\nconst SharedElementContext = createContext<SharedElementScope | null>(null);\n\nexport function useHasSharedElementTransitionScope(): boolean {\n return useContext(SharedElementContext) != null;\n}\n\nexport interface SharedElementTransitionProps {\n children?: JSX.Element;\n}\n\n/**\n * A scope for SharedElements, which animate between parents.\n */\nexport function SharedElementTransition(props: SharedElementTransitionProps): JSX.Element {\n const scope: SharedElementScope = {\n snapshots: {},\n };\n\n return (\n <SharedElementContext.Provider value={scope}>{props.children}</SharedElementContext.Provider>\n );\n}\n\nexport interface SharedElementRenderProps {\n isEntering: boolean;\n isExiting: boolean;\n}\n\nexport interface SharedElementPropsBase extends Omit<\n JSX.HTMLAttributes<HTMLDivElement>,\n \"children\" | \"class\" | \"style\" | \"ref\"\n> {\n children?: RenderChildren<SharedElementRenderProps>;\n class?: ClassNameOrFunction<SharedElementRenderProps>;\n style?: StyleOrFunction<SharedElementRenderProps>;\n}\n\nexport interface SharedElementProps extends SharedElementPropsBase {\n name: string;\n isVisible?: boolean;\n ref?: ((el: HTMLDivElement) => void) | { current?: HTMLDivElement };\n}\n\n/**\n * An element that animates between its old and new position when moving\n * between parents within a SharedElementTransition scope.\n */\nexport function SharedElement(props: SharedElementProps): JSX.Element | null {\n const scope = useContext(SharedElementContext);\n if (!scope) {\n throw new Error(\"<SharedElement> must be rendered inside a <SharedElementTransition>\");\n }\n\n const [local, domProps] = splitProps(props, [\n \"name\",\n \"isVisible\",\n \"children\",\n \"class\",\n \"style\",\n \"ref\",\n ]);\n\n const [lifecycle, setLifecycle] = createSignal<SharedElementLifecycle>(\n local.isVisible === false ? \"hidden\" : \"visible\",\n );\n\n // The mounted div, tracked as a signal so the FLIP-read effect below REACTS to\n // it appearing. React guarantees `ref.current` is committed before the layout\n // effect body runs; Solid gives no such ordering between the `<Show>`'s\n // insertion render-effect and a plain createEffect, so we make the read depend\n // on the element instead of racing its mount (see READ PHASE).\n const [element, setElement] = createSignal<HTMLDivElement | undefined>();\n let frame: number | undefined;\n\n const setRef = (el: HTMLDivElement) => {\n setElement(el);\n // Forward ref to consumer\n const userRef = local.ref;\n if (typeof userRef === \"function\") {\n userRef(el);\n } else if (userRef !== undefined) {\n userRef.current = el;\n }\n };\n\n // Store a geometry + transition-style snapshot of the currently-mounted\n // element, so a sibling SharedElement with the same `name` can FLIP from it.\n // Mirrors upstream's layout-effect *cleanup*\n // (react-aria-components/src/SharedElementTransition.tsx), which runs for\n // every `isVisible` flip — not only on unmount.\n const storeSnapshot = () => {\n const el = untrack(element);\n if (el && el.isConnected && !el.hasAttribute(\"data-exiting\")) {\n // Store a snapshot of the rectangle and computed style for transitioning properties.\n const style = window.getComputedStyle(el);\n if (style.transitionProperty !== \"none\") {\n const transitionProperty = style.transitionProperty.split(/\\s*,\\s*/);\n scope.snapshots[local.name] = {\n rect: el.getBoundingClientRect(),\n style: transitionProperty.map((property) => [property, style.getPropertyValue(property)]),\n };\n }\n }\n };\n\n // MOUNT-IN-RENDER — mirrors upstream's render-phase\n // `if (isVisible && state === 'hidden') setState('visible')`. Promoting a\n // hidden element to visible in the render phase mounts its div (via the\n // `<Show>` below) BEFORE the FLIP-read createEffect runs, so the incoming\n // element is in the DOM to be measured and translated. Without this the\n // incoming element's ref is still null when the read effect fires and it can\n // only enter fresh — never FLIP. Keyed on `isVisible` (untracked lifecycle\n // read) so it cannot loop.\n createRenderEffect(\n on(\n () => local.isVisible !== false,\n (isVisible) => {\n if (isVisible && untrack(lifecycle) === \"hidden\") {\n setLifecycle(\"visible\");\n }\n },\n ),\n );\n\n // STORE PHASE — a render effect runs before user effects within a Solid\n // batch, exactly as React runs all layout-effect destroys before any create.\n // The cleanup registered here fires on the *next* `isVisible` change (and on\n // disposal), capturing the outgoing snapshot BEFORE any sibling's FLIP-read\n // createEffect below runs — React's two-phase commit. Only the cleanup\n // registered while VISIBLE stores (an outgoing element); an incoming\n // element's prior cleanup was registered while hidden and must not clobber\n // the outgoing snapshot. This mirrors React closing over `element =\n // ref.current`, which is null while hidden.\n createRenderEffect(\n on(\n () => local.isVisible !== false,\n (isVisible) => {\n onCleanup(() => {\n if (isVisible) {\n storeSnapshot();\n }\n });\n },\n ),\n );\n\n // READ PHASE — mirrors upstream's layout-effect body, which reads the freshly\n // committed `ref.current`. Keying on the `element` signal (not just isVisible)\n // makes this run only once the incoming div is actually mounted: when isVisible\n // flips true the mount-in-render effect above mounts the div, `setRef` sets the\n // signal, and this effect runs with `el` present — never against a null ref.\n // (Solid batches, so an isVisible flip + the resulting mount coalesce into one\n // run with the mounted element.) There is therefore no \"element not yet in DOM\"\n // fresh-enter branch: with no committed div there is nothing to measure, so we\n // wait — exactly as React never runs the body before commit.\n createEffect(\n on([() => local.isVisible !== false, element] as const, ([isVisible, el]) => {\n const name = local.name;\n\n if (frame != null) {\n cancelAnimationFrame(frame);\n frame = undefined;\n }\n\n if (isVisible && el) {\n const prevSnapshot = scope.snapshots[name];\n\n if (prevSnapshot) {\n // FLIP: Element is transitioning from a previous instance.\n setLifecycle(\"visible\");\n const animations = getAnimations(el);\n\n // Set properties to animate from.\n const values = prevSnapshot.style.map(([property, prevValue]) => {\n const value = el.style.getPropertyValue(property);\n if (property === \"translate\") {\n const prevRect = prevSnapshot.rect;\n const currentRect = el.getBoundingClientRect();\n const deltaX = prevRect.left - currentRect.left;\n const deltaY = prevRect.top - currentRect.top;\n el.style.setProperty(\"translate\", `${deltaX}px ${deltaY}px`);\n } else {\n el.style.setProperty(property, prevValue);\n }\n return [property, value] as [string, string];\n });\n\n // Cancel any new animations triggered by these properties.\n for (const a of getAnimations(el)) {\n if (!animations.includes(a)) {\n a.cancel();\n }\n }\n\n // Remove overrides after one frame to animate to the current values.\n frame = requestAnimationFrame(() => {\n frame = undefined;\n for (const [property, value] of values) {\n el.style.setProperty(property, value);\n }\n });\n\n delete scope.snapshots[name];\n } else {\n // No previous instance exists, apply the entering state.\n queueMicrotask(() => setLifecycle(\"entering\"));\n frame = requestAnimationFrame(() => {\n frame = undefined;\n setLifecycle(\"visible\");\n });\n }\n } else if (!isVisible && el) {\n // Wait a microtask to check if a snapshot still exists (meaning no new\n // SharedElement consumed it), then enter exiting state.\n queueMicrotask(() => {\n if (scope.snapshots[name]) {\n delete scope.snapshots[name];\n setLifecycle(\"exiting\");\n // Wait for animations to finish before hiding.\n Promise.all(getAnimations(el).map((a) => a.finished))\n .then(() => setLifecycle(\"hidden\"))\n .catch(() => {});\n } else {\n // Snapshot was consumed by another instance, unmount immediately.\n setLifecycle(\"hidden\");\n }\n });\n }\n }),\n );\n\n // Cancel any pending FLIP frame on disposal. The snapshot store lives in the\n // render-effect cleanup above, which also fires on disposal.\n onCleanup(() => {\n if (frame != null) {\n cancelAnimationFrame(frame);\n }\n });\n\n const renderProps = useRenderProps(\n {\n get children() {\n return local.children;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-SharedElement\",\n },\n () => ({\n isEntering: lifecycle() === \"entering\",\n isExiting: lifecycle() === \"exiting\",\n }),\n );\n\n const filteredDomProps = createMemo(() => filterDOMProps(domProps, { global: true }));\n\n return (\n <Show when={lifecycle() !== \"hidden\"}>\n <div\n ref={setRef}\n {...filteredDomProps()}\n class={renderProps.class()}\n style={renderProps.style()}\n data-entering={lifecycle() === \"entering\" || undefined}\n data-exiting={lifecycle() === \"exiting\" || undefined}\n >\n {renderProps.renderChildren()}\n </div>\n </Show>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedElementTransition.jsx","names":[],"sources":["../src/SharedElementTransition.tsx"],"sourcesContent":["/**\n * SharedElementTransition primitives for solidaria-components.\n *\n * Provides FLIP-based shared element animations when elements move between\n * parents within a scope. Captures geometry snapshots on unmount and applies\n * transition animations on mount.\n *\n * Parity target: react-aria-components/src/SharedElementTransition.tsx\n */\n\nimport {\n type JSX,\n createContext,\n createEffect,\n createMemo,\n createRenderEffect,\n createSignal,\n onCleanup,\n splitProps,\n untrack,\n useContext,\n Show,\n on,\n} from \"solid-js\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type RenderChildren,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\n\ntype SharedElementLifecycle = \"hidden\" | \"entering\" | \"visible\" | \"exiting\";\n\n/** Safe wrapper — jsdom doesn't implement the Web Animations API. */\nfunction getAnimations(el: HTMLElement): Animation[] {\n return typeof el.getAnimations === \"function\" ? el.getAnimations() : [];\n}\n\ninterface Snapshot {\n rect: DOMRect;\n style: [string, string][];\n}\n\ninterface SharedElementScope {\n snapshots: { [name: string]: Snapshot };\n}\n\nconst SharedElementContext = createContext<SharedElementScope | null>(null);\n\nexport function useHasSharedElementTransitionScope(): boolean {\n return useContext(SharedElementContext) != null;\n}\n\nexport interface SharedElementTransitionProps {\n children?: JSX.Element;\n}\n\n/**\n * A scope for SharedElements, which animate between parents.\n */\nexport function SharedElementTransition(props: SharedElementTransitionProps): JSX.Element {\n const scope: SharedElementScope = {\n snapshots: {},\n };\n\n return (\n <SharedElementContext.Provider value={scope}>{props.children}</SharedElementContext.Provider>\n );\n}\n\nexport interface SharedElementRenderProps {\n isEntering: boolean;\n isExiting: boolean;\n}\n\nexport interface SharedElementPropsBase extends Omit<\n JSX.HTMLAttributes<HTMLDivElement>,\n \"children\" | \"class\" | \"style\" | \"ref\"\n> {\n children?: RenderChildren<SharedElementRenderProps>;\n class?: ClassNameOrFunction<SharedElementRenderProps>;\n style?: StyleOrFunction<SharedElementRenderProps>;\n}\n\nexport interface SharedElementProps extends SharedElementPropsBase {\n name: string;\n isVisible?: boolean;\n ref?: ((el: HTMLDivElement) => void) | { current?: HTMLDivElement };\n}\n\n/**\n * An element that animates between its old and new position when moving\n * between parents within a SharedElementTransition scope.\n */\nexport function SharedElement(props: SharedElementProps): JSX.Element | null {\n const scope = useContext(SharedElementContext);\n if (!scope) {\n throw new Error(\"<SharedElement> must be rendered inside a <SharedElementTransition>\");\n }\n\n const [local, domProps] = splitProps(props, [\n \"name\",\n \"isVisible\",\n \"children\",\n \"class\",\n \"style\",\n \"ref\",\n ]);\n\n const [lifecycle, setLifecycle] = createSignal<SharedElementLifecycle>(\n local.isVisible === false ? \"hidden\" : \"visible\",\n );\n\n // The mounted div, tracked as a signal so the FLIP-read effect below REACTS to\n // it appearing. React guarantees `ref.current` is committed before the layout\n // effect body runs; Solid gives no such ordering between the `<Show>`'s\n // insertion render-effect and a plain createEffect, so we make the read depend\n // on the element instead of racing its mount (see READ PHASE).\n const [element, setElement] = createSignal<HTMLDivElement | undefined>();\n let frame: number | undefined;\n\n const setRef = (el: HTMLDivElement) => {\n setElement(el);\n // Forward ref to consumer\n const userRef = local.ref;\n if (typeof userRef === \"function\") {\n userRef(el);\n } else if (userRef !== undefined) {\n userRef.current = el;\n }\n };\n\n // Store a geometry + transition-style snapshot of the currently-mounted\n // element, so a sibling SharedElement with the same `name` can FLIP from it.\n // Mirrors upstream's layout-effect *cleanup*\n // (react-aria-components/src/SharedElementTransition.tsx), which runs for\n // every `isVisible` flip — not only on unmount.\n const storeSnapshot = () => {\n const el = untrack(element);\n if (el && el.isConnected && !el.hasAttribute(\"data-exiting\")) {\n // Store a snapshot of the rectangle and computed style for transitioning properties.\n const style = window.getComputedStyle(el);\n if (style.transitionProperty !== \"none\") {\n const transitionProperty = style.transitionProperty.split(/\\s*,\\s*/);\n scope.snapshots[local.name] = {\n rect: el.getBoundingClientRect(),\n style: transitionProperty.map((property) => [property, style.getPropertyValue(property)]),\n };\n }\n }\n };\n\n // MOUNT-IN-RENDER — mirrors upstream's render-phase\n // `if (isVisible && state === 'hidden') setState('visible')`. Promoting a\n // hidden element to visible in the render phase mounts its div (via the\n // `<Show>` below) BEFORE the FLIP-read createEffect runs, so the incoming\n // element is in the DOM to be measured and translated. Without this the\n // incoming element's ref is still null when the read effect fires and it can\n // only enter fresh — never FLIP. Keyed on `isVisible` (untracked lifecycle\n // read) so it cannot loop.\n createRenderEffect(\n on(\n () => local.isVisible !== false,\n (isVisible) => {\n if (isVisible && untrack(lifecycle) === \"hidden\") {\n setLifecycle(\"visible\");\n }\n },\n ),\n );\n\n // STORE PHASE — a render effect runs before user effects within a Solid\n // batch, exactly as React runs all layout-effect destroys before any create.\n // The cleanup registered here fires on the *next* `isVisible` change (and on\n // disposal), capturing the outgoing snapshot BEFORE any sibling's FLIP-read\n // createEffect below runs — React's two-phase commit. Only the cleanup\n // registered while VISIBLE stores (an outgoing element); an incoming\n // element's prior cleanup was registered while hidden and must not clobber\n // the outgoing snapshot. This mirrors React closing over `element =\n // ref.current`, which is null while hidden.\n createRenderEffect(\n on(\n () => local.isVisible !== false,\n (isVisible) => {\n onCleanup(() => {\n if (isVisible) {\n storeSnapshot();\n }\n });\n },\n ),\n );\n\n // READ PHASE — mirrors upstream's layout-effect body, which reads the freshly\n // committed `ref.current`. Keying on the `element` signal (not just isVisible)\n // makes this run only once the incoming div is actually mounted: when isVisible\n // flips true the mount-in-render effect above mounts the div, `setRef` sets the\n // signal, and this effect runs with `el` present — never against a null ref.\n // (Solid batches, so an isVisible flip + the resulting mount coalesce into one\n // run with the mounted element.) There is therefore no \"element not yet in DOM\"\n // fresh-enter branch: with no committed div there is nothing to measure, so we\n // wait — exactly as React never runs the body before commit.\n createEffect(\n on(\n [() => local.isVisible !== false, element] as const,\n ([isVisible, el]) => {\n const name = local.name;\n\n if (frame != null) {\n cancelAnimationFrame(frame);\n frame = undefined;\n }\n\n if (isVisible && el) {\n const prevSnapshot = scope.snapshots[name];\n\n if (prevSnapshot) {\n // FLIP: Element is transitioning from a previous instance.\n setLifecycle(\"visible\");\n const animations = getAnimations(el);\n\n // Set properties to animate from.\n const values = prevSnapshot.style.map(([property, prevValue]) => {\n const value = el.style.getPropertyValue(property);\n if (property === \"translate\") {\n const prevRect = prevSnapshot.rect;\n const currentRect = el.getBoundingClientRect();\n const deltaX = prevRect.left - currentRect.left;\n const deltaY = prevRect.top - currentRect.top;\n el.style.setProperty(\"translate\", `${deltaX}px ${deltaY}px`);\n } else {\n el.style.setProperty(property, prevValue);\n }\n return [property, value] as [string, string];\n });\n\n // Cancel any new animations triggered by these properties.\n for (const a of getAnimations(el)) {\n if (!animations.includes(a)) {\n a.cancel();\n }\n }\n\n // Remove overrides after one frame to animate to the current values.\n frame = requestAnimationFrame(() => {\n frame = undefined;\n for (const [property, value] of values) {\n el.style.setProperty(property, value);\n }\n });\n\n delete scope.snapshots[name];\n } else {\n // No previous instance exists, apply the entering state.\n queueMicrotask(() => setLifecycle(\"entering\"));\n frame = requestAnimationFrame(() => {\n frame = undefined;\n setLifecycle(\"visible\");\n });\n }\n } else if (!isVisible && el) {\n // Wait a microtask to check if a snapshot still exists (meaning no new\n // SharedElement consumed it), then enter exiting state.\n queueMicrotask(() => {\n if (scope.snapshots[name]) {\n delete scope.snapshots[name];\n setLifecycle(\"exiting\");\n // Wait for animations to finish before hiding.\n Promise.all(getAnimations(el).map((a) => a.finished))\n .then(() => setLifecycle(\"hidden\"))\n .catch(() => {});\n } else {\n // Snapshot was consumed by another instance, unmount immediately.\n setLifecycle(\"hidden\");\n }\n });\n }\n },\n ),\n );\n\n // Cancel any pending FLIP frame on disposal. The snapshot store lives in the\n // render-effect cleanup above, which also fires on disposal.\n onCleanup(() => {\n if (frame != null) {\n cancelAnimationFrame(frame);\n }\n });\n\n const renderProps = useRenderProps(\n {\n get children() {\n return local.children;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-SharedElement\",\n },\n () => ({\n isEntering: lifecycle() === \"entering\",\n isExiting: lifecycle() === \"exiting\",\n }),\n );\n\n const filteredDomProps = createMemo(() => filterDOMProps(domProps, { global: true }));\n\n return (\n <Show when={lifecycle() !== \"hidden\"}>\n <div\n ref={setRef}\n {...filteredDomProps()}\n class={renderProps.class()}\n style={renderProps.style()}\n data-entering={lifecycle() === \"entering\" || undefined}\n data-exiting={lifecycle() === \"exiting\" || undefined}\n >\n {renderProps.renderChildren()}\n </div>\n </Show>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SharedElementTransition.jsx","names":[],"sources":["../src/SharedElementTransition.tsx"],"sourcesContent":["/**\n * SharedElementTransition primitives for solidaria-components.\n *\n * Provides FLIP-based shared element animations when elements move between\n * parents within a scope. Captures geometry snapshots on unmount and applies\n * transition animations on mount.\n *\n * Parity target: react-aria-components/src/SharedElementTransition.tsx\n */\n\nimport {\n type JSX,\n createContext,\n createEffect,\n createMemo,\n createRenderEffect,\n createSignal,\n onCleanup,\n splitProps,\n untrack,\n useContext,\n Show,\n on,\n} from \"solid-js\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type RenderChildren,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\n\ntype SharedElementLifecycle = \"hidden\" | \"entering\" | \"visible\" | \"exiting\";\n\n/** Safe wrapper — jsdom doesn't implement the Web Animations API. */\nfunction getAnimations(el: HTMLElement): Animation[] {\n return typeof el.getAnimations === \"function\" ? el.getAnimations() : [];\n}\n\ninterface Snapshot {\n rect: DOMRect;\n style: [string, string][];\n}\n\ninterface SharedElementScope {\n snapshots: { [name: string]: Snapshot };\n}\n\nconst SharedElementContext = createContext<SharedElementScope | null>(null);\n\nexport function useHasSharedElementTransitionScope(): boolean {\n return useContext(SharedElementContext) != null;\n}\n\nexport interface SharedElementTransitionProps {\n children?: JSX.Element;\n}\n\n/**\n * A scope for SharedElements, which animate between parents.\n */\nexport function SharedElementTransition(props: SharedElementTransitionProps): JSX.Element {\n const scope: SharedElementScope = {\n snapshots: {},\n };\n\n return (\n <SharedElementContext.Provider value={scope}>{props.children}</SharedElementContext.Provider>\n );\n}\n\nexport interface SharedElementRenderProps {\n isEntering: boolean;\n isExiting: boolean;\n}\n\nexport interface SharedElementPropsBase extends Omit<\n JSX.HTMLAttributes<HTMLDivElement>,\n \"children\" | \"class\" | \"style\" | \"ref\"\n> {\n children?: RenderChildren<SharedElementRenderProps>;\n class?: ClassNameOrFunction<SharedElementRenderProps>;\n style?: StyleOrFunction<SharedElementRenderProps>;\n}\n\nexport interface SharedElementProps extends SharedElementPropsBase {\n name: string;\n isVisible?: boolean;\n ref?: ((el: HTMLDivElement) => void) | { current?: HTMLDivElement };\n}\n\n/**\n * An element that animates between its old and new position when moving\n * between parents within a SharedElementTransition scope.\n */\nexport function SharedElement(props: SharedElementProps): JSX.Element | null {\n const scope = useContext(SharedElementContext);\n if (!scope) {\n throw new Error(\"<SharedElement> must be rendered inside a <SharedElementTransition>\");\n }\n\n const [local, domProps] = splitProps(props, [\n \"name\",\n \"isVisible\",\n \"children\",\n \"class\",\n \"style\",\n \"ref\",\n ]);\n\n const [lifecycle, setLifecycle] = createSignal<SharedElementLifecycle>(\n local.isVisible === false ? \"hidden\" : \"visible\",\n );\n\n // The mounted div, tracked as a signal so the FLIP-read effect below REACTS to\n // it appearing. React guarantees `ref.current` is committed before the layout\n // effect body runs; Solid gives no such ordering between the `<Show>`'s\n // insertion render-effect and a plain createEffect, so we make the read depend\n // on the element instead of racing its mount (see READ PHASE).\n const [element, setElement] = createSignal<HTMLDivElement | undefined>();\n let frame: number | undefined;\n\n const setRef = (el: HTMLDivElement) => {\n setElement(el);\n // Forward ref to consumer\n const userRef = local.ref;\n if (typeof userRef === \"function\") {\n userRef(el);\n } else if (userRef !== undefined) {\n userRef.current = el;\n }\n };\n\n // Store a geometry + transition-style snapshot of the currently-mounted\n // element, so a sibling SharedElement with the same `name` can FLIP from it.\n // Mirrors upstream's layout-effect *cleanup*\n // (react-aria-components/src/SharedElementTransition.tsx), which runs for\n // every `isVisible` flip — not only on unmount.\n const storeSnapshot = () => {\n const el = untrack(element);\n if (el && el.isConnected && !el.hasAttribute(\"data-exiting\")) {\n // Store a snapshot of the rectangle and computed style for transitioning properties.\n const style = window.getComputedStyle(el);\n if (style.transitionProperty !== \"none\") {\n const transitionProperty = style.transitionProperty.split(/\\s*,\\s*/);\n scope.snapshots[local.name] = {\n rect: el.getBoundingClientRect(),\n style: transitionProperty.map((property) => [property, style.getPropertyValue(property)]),\n };\n }\n }\n };\n\n // MOUNT-IN-RENDER — mirrors upstream's render-phase\n // `if (isVisible && state === 'hidden') setState('visible')`. Promoting a\n // hidden element to visible in the render phase mounts its div (via the\n // `<Show>` below) BEFORE the FLIP-read createEffect runs, so the incoming\n // element is in the DOM to be measured and translated. Without this the\n // incoming element's ref is still null when the read effect fires and it can\n // only enter fresh — never FLIP. Keyed on `isVisible` (untracked lifecycle\n // read) so it cannot loop.\n createRenderEffect(\n on(\n () => local.isVisible !== false,\n (isVisible) => {\n if (isVisible && untrack(lifecycle) === \"hidden\") {\n setLifecycle(\"visible\");\n }\n },\n ),\n );\n\n // STORE PHASE — a render effect runs before user effects within a Solid\n // batch, exactly as React runs all layout-effect destroys before any create.\n // The cleanup registered here fires on the *next* `isVisible` change (and on\n // disposal), capturing the outgoing snapshot BEFORE any sibling's FLIP-read\n // createEffect below runs — React's two-phase commit. Only the cleanup\n // registered while VISIBLE stores (an outgoing element); an incoming\n // element's prior cleanup was registered while hidden and must not clobber\n // the outgoing snapshot. This mirrors React closing over `element =\n // ref.current`, which is null while hidden.\n createRenderEffect(\n on(\n () => local.isVisible !== false,\n (isVisible) => {\n onCleanup(() => {\n if (isVisible) {\n storeSnapshot();\n }\n });\n },\n ),\n );\n\n // READ PHASE — mirrors upstream's layout-effect body, which reads the freshly\n // committed `ref.current`. Keying on the `element` signal (not just isVisible)\n // makes this run only once the incoming div is actually mounted: when isVisible\n // flips true the mount-in-render effect above mounts the div, `setRef` sets the\n // signal, and this effect runs with `el` present — never against a null ref.\n // (Solid batches, so an isVisible flip + the resulting mount coalesce into one\n // run with the mounted element.) There is therefore no \"element not yet in DOM\"\n // fresh-enter branch: with no committed div there is nothing to measure, so we\n // wait — exactly as React never runs the body before commit.\n createEffect(\n on([() => local.isVisible !== false, element] as const, ([isVisible, el]) => {\n const name = local.name;\n\n if (frame != null) {\n cancelAnimationFrame(frame);\n frame = undefined;\n }\n\n if (isVisible && el) {\n const prevSnapshot = scope.snapshots[name];\n\n if (prevSnapshot) {\n // FLIP: Element is transitioning from a previous instance.\n setLifecycle(\"visible\");\n const animations = getAnimations(el);\n\n // Set properties to animate from.\n const values = prevSnapshot.style.map(([property, prevValue]) => {\n const value = el.style.getPropertyValue(property);\n if (property === \"translate\") {\n const prevRect = prevSnapshot.rect;\n const currentRect = el.getBoundingClientRect();\n const deltaX = prevRect.left - currentRect.left;\n const deltaY = prevRect.top - currentRect.top;\n el.style.setProperty(\"translate\", `${deltaX}px ${deltaY}px`);\n } else {\n el.style.setProperty(property, prevValue);\n }\n return [property, value] as [string, string];\n });\n\n // Cancel any new animations triggered by these properties.\n for (const a of getAnimations(el)) {\n if (!animations.includes(a)) {\n a.cancel();\n }\n }\n\n // Remove overrides after one frame to animate to the current values.\n frame = requestAnimationFrame(() => {\n frame = undefined;\n for (const [property, value] of values) {\n el.style.setProperty(property, value);\n }\n });\n\n delete scope.snapshots[name];\n } else {\n // No previous instance exists, apply the entering state.\n queueMicrotask(() => setLifecycle(\"entering\"));\n frame = requestAnimationFrame(() => {\n frame = undefined;\n setLifecycle(\"visible\");\n });\n }\n } else if (!isVisible && el) {\n // Wait a microtask to check if a snapshot still exists (meaning no new\n // SharedElement consumed it), then enter exiting state.\n queueMicrotask(() => {\n if (scope.snapshots[name]) {\n delete scope.snapshots[name];\n setLifecycle(\"exiting\");\n // Wait for animations to finish before hiding.\n Promise.all(getAnimations(el).map((a) => a.finished))\n .then(() => setLifecycle(\"hidden\"))\n .catch(() => {});\n } else {\n // Snapshot was consumed by another instance, unmount immediately.\n setLifecycle(\"hidden\");\n }\n });\n }\n }),\n );\n\n // Cancel any pending FLIP frame on disposal. The snapshot store lives in the\n // render-effect cleanup above, which also fires on disposal.\n onCleanup(() => {\n if (frame != null) {\n cancelAnimationFrame(frame);\n }\n });\n\n const renderProps = useRenderProps(\n {\n get children() {\n return local.children;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-SharedElement\",\n },\n () => ({\n isEntering: lifecycle() === \"entering\",\n isExiting: lifecycle() === \"exiting\",\n }),\n );\n\n const filteredDomProps = createMemo(() => filterDOMProps(domProps, { global: true }));\n\n return (\n <Show when={lifecycle() !== \"hidden\"}>\n <div\n ref={setRef}\n {...filteredDomProps()}\n class={renderProps.class()}\n style={renderProps.style()}\n data-entering={lifecycle() === \"entering\" || undefined}\n data-exiting={lifecycle() === \"exiting\" || undefined}\n >\n {renderProps.renderChildren()}\n </div>\n </Show>\n );\n}\n"],"mappings":"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"}
|