@proyecto-viviana/solidaria-components 0.5.0 → 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/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/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/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/SharedElementTransition.d.ts.map +1 -1
- package/dist/SharedElementTransition.js.map +1 -1
- package/dist/SharedElementTransition.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/package.json +5 -3
- package/src/DateField.tsx +5 -7
- package/src/DatePicker.tsx +25 -25
- package/src/Form.tsx +18 -1
- package/src/ListBox.tsx +123 -124
- package/src/SearchField.tsx +1 -3
- package/src/SharedElementTransition.tsx +64 -67
- package/src/TimeField.tsx +3 -10
package/dist/SearchField.jsx.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchField.jsx","names":["mergeProps"],"sources":["../src/SearchField.tsx"],"sourcesContent":["/**\n * SearchField component for solidaria-components\n *\n * A pre-wired headless search field that combines state + aria hooks.\n * Port of react-aria-components/src/SearchField.tsx\n */\n\nimport {\n type JSX,\n type Context,\n createContext,\n createMemo,\n onCleanup,\n onMount,\n splitProps,\n useContext,\n Show,\n} from \"solid-js\";\nimport {\n createSearchField,\n createFocusRing,\n createHover,\n createPress,\n mergeProps,\n type AriaSearchFieldProps,\n} from \"@proyecto-viviana/solidaria\";\nimport {\n createSearchFieldState,\n VALID_VALIDITY_STATE,\n type SearchFieldState,\n type ValidationResult,\n} from \"@proyecto-viviana/solid-stately\";\nimport { FormContext, type FormProps } from \"./Form\";\nimport { FieldErrorContext, type FieldErrorContextValue } from \"./FieldError\";\nimport {\n type RenderChildren,\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n filterDOMProps,\n Provider,\n} from \"./utils\";\nimport { TextContext } from \"./Text\";\nimport { useAutocompleteInput } from \"./Autocomplete\";\n\nexport interface SearchFieldRenderProps {\n /** Whether the search field is empty. */\n isEmpty: boolean;\n /** Whether the search field is disabled. */\n isDisabled: boolean;\n /** Whether the search field is invalid. */\n isInvalid: boolean;\n /** Whether the search field is read-only. */\n isReadOnly: boolean;\n /** Whether the search field is required. */\n isRequired: boolean;\n /** The current value. */\n value: string;\n}\n\nexport interface SearchFieldProps extends Omit<AriaSearchFieldProps, \"label\">, SlotProps {\n /** The current value (controlled). */\n value?: string;\n /** The default value (uncontrolled). */\n defaultValue?: string;\n /** Handler called when the value changes. */\n onChange?: (value: string) => void;\n /** Handler called when the user submits the search. */\n onSubmit?: (value: string) => void;\n /** Handler called when the field is cleared. */\n onClear?: () => void;\n /** A visible label for the search field. */\n label?: JSX.Element;\n /** The children of the component. */\n children?: RenderChildren<SearchFieldRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SearchFieldRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SearchFieldRenderProps>;\n /** Ref for the outer search field element. */\n ref?: (el: HTMLDivElement) => void;\n}\n\nexport interface SearchFieldInputRenderProps {\n /** Whether the input is focused. */\n isFocused: boolean;\n /** Whether the input has keyboard focus. */\n isFocusVisible: boolean;\n /** Whether the input is hovered. */\n isHovered: boolean;\n /** Whether the input is disabled. */\n isDisabled: boolean;\n /** Whether the input is invalid. */\n isInvalid: boolean;\n}\n\nexport interface SearchFieldInputProps\n extends SlotProps, Omit<JSX.InputHTMLAttributes<HTMLInputElement>, \"class\" | \"style\"> {\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SearchFieldInputRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SearchFieldInputRenderProps>;\n}\n\nexport interface SearchFieldClearButtonRenderProps {\n /** Whether the button is pressed. */\n isPressed: boolean;\n /** Whether the button is hovered. */\n isHovered: boolean;\n /** Whether the button is disabled. */\n isDisabled: boolean;\n}\n\nexport interface SearchFieldClearButtonProps\n extends\n SlotProps,\n Omit<JSX.ButtonHTMLAttributes<HTMLButtonElement>, \"class\" | \"style\" | \"children\"> {\n /** The children of the button. */\n children?: RenderChildren<SearchFieldClearButtonRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SearchFieldClearButtonRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SearchFieldClearButtonRenderProps>;\n}\n\ninterface SearchFieldContextValue extends Partial<SearchFieldProps> {\n state?: SearchFieldState;\n inputProps?: JSX.InputHTMLAttributes<HTMLInputElement>;\n clearButtonProps?: {\n \"aria-label\": string;\n tabIndex: number;\n disabled?: boolean;\n onMouseDown: (e: MouseEvent) => void;\n onClick: () => void;\n };\n labelProps?: JSX.HTMLAttributes<HTMLElement>;\n descriptionProps?: JSX.HTMLAttributes<HTMLElement>;\n errorMessageProps?: JSX.HTMLAttributes<HTMLElement>;\n isDisabled?: boolean;\n isInvalid?: boolean;\n isRequired?: boolean;\n isReadOnly?: boolean;\n setInputRef?: (el: HTMLInputElement) => void;\n slots?: Record<string, SearchFieldProps>;\n}\n\nexport const SearchFieldContext = createContext<SearchFieldContextValue | null>(null);\n\nfunction withFormValidationBehavior(\n props: SearchFieldProps,\n formContext: FormProps | null,\n): SearchFieldProps {\n if (!formContext?.validationBehavior) {\n return props;\n }\n\n return new Proxy(props, {\n get(target, property, receiver) {\n const localValue = Reflect.get(target, property, receiver);\n if (property === \"validationBehavior\" && localValue === undefined) {\n return formContext.validationBehavior;\n }\n\n return localValue;\n },\n has(target, property) {\n return (\n Reflect.has(target, property) ||\n (property === \"validationBehavior\" && formContext.validationBehavior !== undefined)\n );\n },\n ownKeys(target) {\n const keys = new Set(Reflect.ownKeys(target));\n if (formContext.validationBehavior !== undefined) {\n keys.add(\"validationBehavior\");\n }\n\n return Array.from(keys);\n },\n getOwnPropertyDescriptor(target, property) {\n const descriptor = Reflect.getOwnPropertyDescriptor(target, property);\n if (descriptor) {\n return descriptor;\n }\n\n if (property === \"validationBehavior\" && formContext.validationBehavior !== undefined) {\n return {\n enumerable: true,\n configurable: true,\n get: () => formContext.validationBehavior,\n };\n }\n\n return undefined;\n },\n });\n}\n\nfunction eventWithCurrentTarget<T extends HTMLElement>(event: Event, element: T): Event {\n return new Proxy(event, {\n get(target, property, receiver) {\n if (property === \"target\" || property === \"currentTarget\") {\n return element;\n }\n\n const value = Reflect.get(target, property, receiver);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n });\n}\n\nfunction clearDelegatedTextEntryHandlers(element: HTMLElement) {\n const delegatedElement = element as HTMLElement & {\n $$input?: unknown;\n $$change?: unknown;\n };\n delete delegatedElement.$$input;\n delete delegatedElement.$$change;\n}\n\n/**\n * A search field allows a user to enter and clear a search query.\n */\nexport function SearchField(props: SearchFieldProps): JSX.Element {\n const formContext = useContext(FormContext);\n const contextProps = useContext(SearchFieldContext);\n const contextSlotProps = contextProps?.slots?.[props.slot ?? \"default\"];\n const contextBaseProps = createMemo<SearchFieldProps>(() => {\n if (!contextProps) return {};\n const {\n state: _state,\n inputProps: _inputProps,\n clearButtonProps: _clearButtonProps,\n labelProps: _labelProps,\n descriptionProps: _descriptionProps,\n errorMessageProps: _errorMessageProps,\n isDisabled: _isDisabled,\n isInvalid: _isInvalid,\n isRequired: _isRequired,\n isReadOnly: _isReadOnly,\n setInputRef: _setInputRef,\n slots: _slots,\n ...restContextProps\n } = contextProps;\n return restContextProps as SearchFieldProps;\n });\n const baseProps = (\n contextProps ? mergeProps(contextBaseProps(), contextSlotProps ?? {}, props) : props\n ) as SearchFieldProps;\n\n // When rendered inside an <Autocomplete>, the FieldInputContext (AutocompleteContext)\n // controls the input's value and keyboard handling: value + onChange make the field's\n // state controlled by the shared autocomplete state (which drives the collection\n // filter), and onKeyDown/onFocus/onBlur chain the autocomplete's virtual-focus\n // navigation into the input. This mirrors RAC's\n // useContextProps(props, inputRef, FieldInputContext). The remaining passthroughs\n // (aria-activedescendant/aria-controls/aria-autocomplete) and the input-ref\n // registration are applied at the <input> in SearchFieldInput.\n const autocompleteInput = useAutocompleteInput();\n const autocompleteProps = autocompleteInput\n ? ({\n get value() {\n return autocompleteInput.inputProps.value();\n },\n onChange: autocompleteInput.inputProps.onChange,\n onKeyDown: autocompleteInput.inputProps\n .onKeyDown as unknown as SearchFieldProps[\"onKeyDown\"],\n onFocus: autocompleteInput.inputProps.onFocus as unknown as SearchFieldProps[\"onFocus\"],\n onBlur: autocompleteInput.inputProps.onBlur as unknown as SearchFieldProps[\"onBlur\"],\n } as Partial<SearchFieldProps>)\n : undefined;\n\n const mergedProps = withFormValidationBehavior(\n autocompleteProps\n ? (mergeProps(baseProps, autocompleteProps) as SearchFieldProps)\n : baseProps,\n formContext,\n );\n\n const [local, stateProps, ariaProps, rest] = splitProps(\n mergedProps,\n [\"children\", \"class\", \"style\", \"slot\", \"ref\"],\n [\"value\", \"defaultValue\", \"onChange\", \"onSubmit\", \"onClear\"],\n [\n \"label\",\n \"aria-label\",\n \"aria-labelledby\",\n \"aria-describedby\",\n \"isDisabled\",\n \"isReadOnly\",\n \"isRequired\",\n \"isInvalid\",\n \"description\",\n \"errorMessage\",\n \"id\",\n \"autoFocus\",\n \"excludeFromTabOrder\",\n \"name\",\n \"form\",\n \"validationBehavior\",\n \"type\",\n \"placeholder\",\n \"autoComplete\",\n \"inputMode\",\n \"enterKeyHint\",\n \"autoCorrect\",\n \"autoCapitalize\",\n \"spellCheck\",\n \"maxLength\",\n \"minLength\",\n \"pattern\",\n \"onFocus\",\n \"onBlur\",\n \"onFocusChange\",\n \"onKeyDown\",\n \"onKeyUp\",\n \"onCopy\",\n \"onCut\",\n \"onPaste\",\n \"onCompositionStart\",\n \"onCompositionEnd\",\n \"onCompositionUpdate\",\n \"onSelect\",\n \"onBeforeInput\",\n \"onInput\",\n ],\n );\n\n const state = createSearchFieldState({\n get value() {\n return stateProps.value;\n },\n get defaultValue() {\n return stateProps.defaultValue;\n },\n get onChange() {\n return stateProps.onChange;\n },\n });\n\n let inputRef: HTMLInputElement | undefined;\n const setInputRef = (el: HTMLInputElement) => {\n inputRef = el;\n };\n\n const searchFieldAria = createSearchField(\n {\n get isDisabled() {\n return ariaProps.isDisabled;\n },\n get isReadOnly() {\n return ariaProps.isReadOnly;\n },\n get isRequired() {\n return ariaProps.isRequired;\n },\n get isInvalid() {\n return ariaProps.isInvalid;\n },\n get label() {\n return ariaProps.label;\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 description() {\n return ariaProps.description;\n },\n get errorMessage() {\n return ariaProps.errorMessage;\n },\n get placeholder() {\n return ariaProps.placeholder;\n },\n get name() {\n return ariaProps.name;\n },\n get form() {\n return ariaProps.form;\n },\n get validationBehavior() {\n return ariaProps.validationBehavior;\n },\n get type() {\n return ariaProps.type;\n },\n get autoFocus() {\n return ariaProps.autoFocus;\n },\n get excludeFromTabOrder() {\n return ariaProps.excludeFromTabOrder;\n },\n get autoComplete() {\n return ariaProps.autoComplete;\n },\n get inputMode() {\n return ariaProps.inputMode;\n },\n get enterKeyHint() {\n return ariaProps.enterKeyHint;\n },\n get autoCorrect() {\n return ariaProps.autoCorrect;\n },\n get autoCapitalize() {\n return ariaProps.autoCapitalize;\n },\n get spellCheck() {\n return ariaProps.spellCheck;\n },\n get maxLength() {\n return ariaProps.maxLength;\n },\n get minLength() {\n return ariaProps.minLength;\n },\n get pattern() {\n return ariaProps.pattern;\n },\n get onFocus() {\n return ariaProps.onFocus;\n },\n get onBlur() {\n return ariaProps.onBlur;\n },\n get onFocusChange() {\n return ariaProps.onFocusChange;\n },\n get onKeyDown() {\n return ariaProps.onKeyDown;\n },\n get onKeyUp() {\n return ariaProps.onKeyUp;\n },\n get onCopy() {\n return ariaProps.onCopy;\n },\n get onCut() {\n return ariaProps.onCut;\n },\n get onPaste() {\n return ariaProps.onPaste;\n },\n get onCompositionStart() {\n return ariaProps.onCompositionStart;\n },\n get onCompositionEnd() {\n return ariaProps.onCompositionEnd;\n },\n get onCompositionUpdate() {\n return ariaProps.onCompositionUpdate;\n },\n get onSelect() {\n return ariaProps.onSelect;\n },\n get onBeforeInput() {\n return ariaProps.onBeforeInput;\n },\n get onInput() {\n return ariaProps.onInput;\n },\n get onSubmit() {\n return stateProps.onSubmit;\n },\n get onClear() {\n return stateProps.onClear;\n },\n },\n state,\n () => inputRef ?? null,\n );\n\n const renderValues = createMemo<SearchFieldRenderProps>(() => ({\n isEmpty: state.value() === \"\",\n isDisabled: ariaProps.isDisabled ?? false,\n isInvalid: searchFieldAria.isInvalid ?? false,\n isRequired: ariaProps.isRequired ?? false,\n isReadOnly: ariaProps.isReadOnly ?? false,\n value: state.value(),\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-SearchField\",\n },\n renderValues,\n );\n const childRenderValues: SearchFieldRenderProps = {\n get isEmpty() {\n return state.value() === \"\";\n },\n get isDisabled() {\n return ariaProps.isDisabled ?? false;\n },\n get isInvalid() {\n return searchFieldAria.isInvalid ?? false;\n },\n get isRequired() {\n return ariaProps.isRequired ?? false;\n },\n get isReadOnly() {\n return ariaProps.isReadOnly ?? false;\n },\n get value() {\n return state.value();\n },\n };\n\n const domProps = createMemo(() =>\n filterDOMProps(rest as Record<string, unknown>, { global: true }),\n );\n\n const fieldValidation = createMemo<ValidationResult>(() => {\n const isInvalid = searchFieldAria.isInvalid;\n const errorMessage = ariaProps.errorMessage;\n const validationErrors = isInvalid && typeof errorMessage === \"string\" ? [errorMessage] : [];\n\n return {\n isInvalid,\n validationErrors,\n validationDetails: isInvalid\n ? { ...VALID_VALIDITY_STATE, customError: true, valid: false }\n : VALID_VALIDITY_STATE,\n };\n });\n const fieldErrorContext: FieldErrorContextValue = {\n get validation() {\n return fieldValidation();\n },\n get errorMessageProps() {\n return searchFieldAria.errorMessageProps;\n },\n };\n const contextValue: SearchFieldContextValue = {\n state,\n get inputProps() {\n return searchFieldAria.inputProps;\n },\n get clearButtonProps() {\n return searchFieldAria.clearButtonProps;\n },\n get labelProps() {\n return searchFieldAria.labelProps as JSX.HTMLAttributes<HTMLElement>;\n },\n get descriptionProps() {\n return searchFieldAria.descriptionProps;\n },\n get errorMessageProps() {\n return searchFieldAria.errorMessageProps;\n },\n get isDisabled() {\n return ariaProps.isDisabled ?? false;\n },\n get isInvalid() {\n return searchFieldAria.isInvalid ?? false;\n },\n get isRequired() {\n return ariaProps.isRequired ?? false;\n },\n get isReadOnly() {\n return ariaProps.isReadOnly ?? false;\n },\n setInputRef,\n };\n const fieldChildren = () => {\n const children = local.children;\n return typeof children === \"function\" ? children(childRenderValues) : children;\n };\n // Provide the description / errorMessage props as `TextContext` slots (mirrors\n // react-aria-components' SearchField), so a `<Text slot=\"description\">` /\n // `<Text slot=\"errorMessage\">` child picks up the `id` its `aria-describedby`\n // references. Additive: existing consumers reading these off\n // `SearchFieldContext` are unaffected.\n const textSlots = {\n slots: {\n get description() {\n return searchFieldAria.descriptionProps;\n },\n get errorMessage() {\n return searchFieldAria.errorMessageProps;\n },\n },\n };\n\n return (\n <FieldErrorContext.Provider value={fieldErrorContext}>\n <SearchFieldContext.Provider value={contextValue}>\n <div\n {...domProps()}\n ref={local.ref}\n class={renderProps.class()}\n style={renderProps.style()}\n data-empty={state.value() === \"\" || undefined}\n data-disabled={ariaProps.isDisabled || undefined}\n data-invalid={searchFieldAria.isInvalid || undefined}\n data-required={ariaProps.isRequired || undefined}\n data-readonly={ariaProps.isReadOnly || undefined}\n >\n <Provider values={[[TextContext, textSlots]] as Array<[Context<unknown>, unknown]>}>\n {fieldChildren()}\n </Provider>\n </div>\n </SearchFieldContext.Provider>\n </FieldErrorContext.Provider>\n );\n}\n\n/**\n * The label for a search field.\n */\nexport function SearchFieldLabel(props: {\n children?: JSX.Element;\n class?: string;\n style?: JSX.CSSProperties;\n}): JSX.Element {\n const context = useContext(SearchFieldContext);\n if (!context) {\n throw new Error(\"SearchFieldLabel must be used within a SearchField\");\n }\n\n const cleanLabelProps = () => {\n const { ref: _ref, ...rest } = context.labelProps as Record<string, unknown>;\n return rest;\n };\n\n return (\n <label\n {...cleanLabelProps()}\n class={props.class ?? \"solidaria-SearchField-label\"}\n style={props.style}\n >\n {props.children}\n </label>\n );\n}\n\n/**\n * The input element for a search field.\n */\nexport function SearchFieldInput(props: SearchFieldInputProps): JSX.Element {\n const [local, domProps] = splitProps(props, [\"class\", \"style\", \"slot\"]);\n let inputElement: HTMLInputElement | undefined;\n\n const context = useContext(SearchFieldContext);\n if (!context) {\n throw new Error(\"SearchFieldInput must be used within a SearchField\");\n }\n\n // Inside an <Autocomplete>, expose the ARIA attributes that identify the\n // controlled collection and its virtually-focused option. value/onChange and the\n // keyboard handlers are already merged upstream in SearchField(); here we only add\n // the passthrough attributes that createTextField doesn't forward, and register the\n // input element as the autocomplete inputRef so the beforeinput + reverse-path\n // (aria-activedescendant mirror) listeners bind. Mirrors RAC's\n // [InputContext, {...inputProps, ref: inputRef}].\n const autocompleteInput = useAutocompleteInput();\n\n const { isFocused, isFocusVisible, focusProps } = createFocusRing();\n\n const { isHovered, hoverProps } = createHover({\n get isDisabled() {\n return context.isDisabled;\n },\n });\n\n const renderValues = createMemo<SearchFieldInputRenderProps>(() => ({\n isFocused: isFocused(),\n isFocusVisible: isFocusVisible(),\n isHovered: isHovered(),\n isDisabled: !!context.isDisabled,\n isInvalid: !!context.isInvalid,\n }));\n\n const renderProps = useRenderProps(\n {\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-SearchField-input\",\n },\n renderValues,\n );\n\n const cleanInputProps = () => {\n const { ref: _ref, ...rest } = context.inputProps as Record<string, unknown>;\n return rest;\n };\n const cleanFocusProps = () => {\n const { ref: _ref, ...rest } = focusProps as Record<string, unknown>;\n return rest;\n };\n const cleanHoverProps = () => {\n const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;\n return rest;\n };\n\n const autocompleteInputAttrs = (): Record<string, unknown> => {\n if (!autocompleteInput) {\n return {};\n }\n const inputProps = autocompleteInput.inputProps;\n return {\n \"aria-controls\": inputProps[\"aria-controls\"],\n \"aria-autocomplete\": inputProps[\"aria-autocomplete\"],\n \"aria-activedescendant\": inputProps[\"aria-activedescendant\"](),\n };\n };\n\n const mergedInputProps = () =>\n ({\n ...domProps,\n ...cleanInputProps(),\n ...cleanFocusProps(),\n ...cleanHoverProps(),\n ...autocompleteInputAttrs(),\n }) as Record<string, unknown>;\n\n onMount(() => {\n const element = inputElement;\n if (!element) {\n return;\n }\n\n const inputHandler = (event: Event) => {\n const handler = mergedInputProps().onInput as\n | JSX.EventHandler<HTMLInputElement, InputEvent>\n | undefined;\n handler?.(\n eventWithCurrentTarget(event, element) as InputEvent & {\n currentTarget: HTMLInputElement;\n target: Element;\n },\n );\n clearDelegatedTextEntryHandlers(element);\n event.stopPropagation();\n };\n const changeHandler = (event: Event) => {\n const handler = mergedInputProps().onChange as\n | JSX.EventHandler<HTMLInputElement, Event>\n | undefined;\n handler?.(\n eventWithCurrentTarget(event, element) as Event & {\n currentTarget: HTMLInputElement;\n target: Element;\n },\n );\n clearDelegatedTextEntryHandlers(element);\n event.stopPropagation();\n };\n\n element.addEventListener(\"input\", inputHandler);\n element.addEventListener(\"change\", changeHandler);\n clearDelegatedTextEntryHandlers(element);\n onCleanup(() => {\n element.removeEventListener(\"input\", inputHandler);\n element.removeEventListener(\"change\", changeHandler);\n });\n });\n\n return (\n <input\n {...mergedInputProps()}\n ref={(element) => {\n inputElement = element;\n context.setInputRef?.(element);\n autocompleteInput?.inputRef(element);\n const ref = (domProps as { ref?: unknown }).ref;\n if (typeof ref === \"function\") {\n ref(element);\n }\n }}\n class={renderProps.class()}\n style={renderProps.style()}\n data-focused={isFocused() || undefined}\n data-focus-visible={isFocusVisible() || undefined}\n data-hovered={isHovered() || undefined}\n data-disabled={context.isDisabled || undefined}\n data-invalid={context.isInvalid || undefined}\n />\n );\n}\n\n/**\n * The clear button for a search field.\n */\nexport function SearchFieldClearButton(props: SearchFieldClearButtonProps): JSX.Element {\n const [local, domProps] = splitProps(props, [\"class\", \"style\", \"slot\", \"children\"]);\n\n const context = useContext(SearchFieldContext);\n if (!context) {\n throw new Error(\"SearchFieldClearButton must be used within a SearchField\");\n }\n\n const isDisabled = () => !!(context.isDisabled || context.isReadOnly);\n const isEmpty = () => (context.state?.value() ?? \"\") === \"\";\n const clear = () => {\n if (!isDisabled() && !isEmpty()) {\n context.clearButtonProps?.onClick();\n }\n };\n\n const { isPressed, pressProps } = createPress({\n get isDisabled() {\n return context.isDisabled || context.isReadOnly;\n },\n onClick: clear,\n onPress: clear,\n });\n\n const { isHovered, hoverProps } = createHover({\n get isDisabled() {\n return context.isDisabled || context.isReadOnly;\n },\n });\n\n const renderValues = createMemo<SearchFieldClearButtonRenderProps>(() => ({\n isPressed: isPressed(),\n isHovered: isHovered(),\n isDisabled: 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-SearchField-clear\",\n },\n renderValues,\n );\n\n const cleanPressProps = () => {\n const { ref: _ref, ...rest } = pressProps as Record<string, unknown>;\n return rest;\n };\n const cleanHoverProps = () => {\n const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;\n return rest;\n };\n\n return (\n <Show when={!isEmpty()}>\n <button\n {...domProps}\n type=\"button\"\n aria-label={context.clearButtonProps?.[\"aria-label\"] ?? \"Clear search\"}\n tabIndex={context.clearButtonProps?.tabIndex ?? -1}\n disabled={context.clearButtonProps?.disabled}\n onMouseDown={context.clearButtonProps?.onMouseDown}\n {...cleanPressProps()}\n onPointerUp={clear}\n onMouseUp={clear}\n onClick={clear}\n {...cleanHoverProps()}\n class={renderProps.class()}\n style={renderProps.style()}\n data-pressed={isPressed() || undefined}\n data-hovered={isHovered() || undefined}\n data-disabled={isDisabled() || undefined}\n >\n {renderProps.renderChildren()}\n </button>\n </Show>\n );\n}\n\nSearchField.Label = SearchFieldLabel;\nSearchField.Input = SearchFieldInput;\nSearchField.ClearButton = SearchFieldClearButton;\n"],"mappings":";;;;;;;;;;;;;;;AAmJA,MAAa,qBAAqB,cAA8C,IAAI;AAEpF,SAAS,2BACP,OACA,aACkB;CAClB,IAAI,CAAC,aAAa,oBAChB,OAAO;CAGT,OAAO,IAAI,MAAM,OAAO;EACtB,IAAI,QAAQ,UAAU,UAAU;GAC9B,MAAM,aAAa,QAAQ,IAAI,QAAQ,UAAU,QAAQ;GACzD,IAAI,aAAa,wBAAwB,eAAe,KAAA,GACtD,OAAO,YAAY;GAGrB,OAAO;EACT;EACA,IAAI,QAAQ,UAAU;GACpB,OACE,QAAQ,IAAI,QAAQ,QAAQ,KAC3B,aAAa,wBAAwB,YAAY,uBAAuB,KAAA;EAE7E;EACA,QAAQ,QAAQ;GACd,MAAM,OAAO,IAAI,IAAI,QAAQ,QAAQ,MAAM,CAAC;GAC5C,IAAI,YAAY,uBAAuB,KAAA,GACrC,KAAK,IAAI,oBAAoB;GAG/B,OAAO,MAAM,KAAK,IAAI;EACxB;EACA,yBAAyB,QAAQ,UAAU;GACzC,MAAM,aAAa,QAAQ,yBAAyB,QAAQ,QAAQ;GACpE,IAAI,YACF,OAAO;GAGT,IAAI,aAAa,wBAAwB,YAAY,uBAAuB,KAAA,GAC1E,OAAO;IACL,YAAY;IACZ,cAAc;IACd,WAAW,YAAY;GACzB;EAIJ;CACF,CAAC;AACH;AAEA,SAAS,uBAA8C,OAAc,SAAmB;CACtF,OAAO,IAAI,MAAM,OAAO,EACtB,IAAI,QAAQ,UAAU,UAAU;EAC9B,IAAI,aAAa,YAAY,aAAa,iBACxC,OAAO;EAGT,MAAM,QAAQ,QAAQ,IAAI,QAAQ,UAAU,QAAQ;EACpD,OAAO,OAAO,UAAU,aAAa,MAAM,KAAK,MAAM,IAAI;CAC5D,EACF,CAAC;AACH;AAEA,SAAS,gCAAgC,SAAsB;CAC7D,MAAM,mBAAmB;CAIzB,OAAO,iBAAiB;CACxB,OAAO,iBAAiB;AAC1B;;;;AAKA,SAAgB,YAAY,OAAsC;CAChE,MAAM,cAAc,WAAW,WAAW;CAC1C,MAAM,eAAe,WAAW,kBAAkB;CAClD,MAAM,mBAAmB,cAAc,QAAQ,MAAM,QAAQ;CAC7D,MAAM,mBAAmB,iBAAmC;EAC1D,IAAI,CAAC,cAAc,OAAO,CAAC;EAC3B,MAAM,EACJ,OAAO,QACP,YAAY,aACZ,kBAAkB,mBAClB,YAAY,aACZ,kBAAkB,mBAClB,mBAAmB,oBACnB,YAAY,aACZ,WAAW,YACX,YAAY,aACZ,YAAY,aACZ,aAAa,cACb,OAAO,QACP,GAAG,qBACD;EACJ,OAAO;CACT,CAAC;CACD,MAAM,YACJ,eAAeA,aAAW,iBAAiB,GAAG,oBAAoB,CAAC,GAAG,KAAK,IAAI;CAWjF,MAAM,oBAAoB,qBAAqB;CAC/C,MAAM,oBAAoB,oBACrB;EACC,IAAI,QAAQ;GACV,OAAO,kBAAkB,WAAW,MAAM;EAC5C;EACA,UAAU,kBAAkB,WAAW;EACvC,WAAW,kBAAkB,WAC1B;EACH,SAAS,kBAAkB,WAAW;EACtC,QAAQ,kBAAkB,WAAW;CACvC,IACA,KAAA;CASJ,MAAM,CAAC,OAAO,YAAY,WAAW,QAAQ,WAPzB,2BAClB,oBACKA,aAAW,WAAW,iBAAiB,IACxC,WACJ,WAIU,GACV;EAAC;EAAY;EAAS;EAAS;EAAQ;CAAK,GAC5C;EAAC;EAAS;EAAgB;EAAY;EAAY;CAAS,GAC3D;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,MAAM,QAAQ,uBAAuB;EACnC,IAAI,QAAQ;GACV,OAAO,WAAW;EACpB;EACA,IAAI,eAAe;GACjB,OAAO,WAAW;EACpB;EACA,IAAI,WAAW;GACb,OAAO,WAAW;EACpB;CACF,CAAC;CAED,IAAI;CACJ,MAAM,eAAe,OAAyB;EAC5C,WAAW;CACb;CAEA,MAAM,kBAAkB,kBACtB;EACE,IAAI,aAAa;GACf,OAAO,UAAU;EACnB;EACA,IAAI,aAAa;GACf,OAAO,UAAU;EACnB;EACA,IAAI,aAAa;GACf,OAAO,UAAU;EACnB;EACA,IAAI,YAAY;GACd,OAAO,UAAU;EACnB;EACA,IAAI,QAAQ;GACV,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,cAAc;GAChB,OAAO,UAAU;EACnB;EACA,IAAI,eAAe;GACjB,OAAO,UAAU;EACnB;EACA,IAAI,cAAc;GAChB,OAAO,UAAU;EACnB;EACA,IAAI,OAAO;GACT,OAAO,UAAU;EACnB;EACA,IAAI,OAAO;GACT,OAAO,UAAU;EACnB;EACA,IAAI,qBAAqB;GACvB,OAAO,UAAU;EACnB;EACA,IAAI,OAAO;GACT,OAAO,UAAU;EACnB;EACA,IAAI,YAAY;GACd,OAAO,UAAU;EACnB;EACA,IAAI,sBAAsB;GACxB,OAAO,UAAU;EACnB;EACA,IAAI,eAAe;GACjB,OAAO,UAAU;EACnB;EACA,IAAI,YAAY;GACd,OAAO,UAAU;EACnB;EACA,IAAI,eAAe;GACjB,OAAO,UAAU;EACnB;EACA,IAAI,cAAc;GAChB,OAAO,UAAU;EACnB;EACA,IAAI,iBAAiB;GACnB,OAAO,UAAU;EACnB;EACA,IAAI,aAAa;GACf,OAAO,UAAU;EACnB;EACA,IAAI,YAAY;GACd,OAAO,UAAU;EACnB;EACA,IAAI,YAAY;GACd,OAAO,UAAU;EACnB;EACA,IAAI,UAAU;GACZ,OAAO,UAAU;EACnB;EACA,IAAI,UAAU;GACZ,OAAO,UAAU;EACnB;EACA,IAAI,SAAS;GACX,OAAO,UAAU;EACnB;EACA,IAAI,gBAAgB;GAClB,OAAO,UAAU;EACnB;EACA,IAAI,YAAY;GACd,OAAO,UAAU;EACnB;EACA,IAAI,UAAU;GACZ,OAAO,UAAU;EACnB;EACA,IAAI,SAAS;GACX,OAAO,UAAU;EACnB;EACA,IAAI,QAAQ;GACV,OAAO,UAAU;EACnB;EACA,IAAI,UAAU;GACZ,OAAO,UAAU;EACnB;EACA,IAAI,qBAAqB;GACvB,OAAO,UAAU;EACnB;EACA,IAAI,mBAAmB;GACrB,OAAO,UAAU;EACnB;EACA,IAAI,sBAAsB;GACxB,OAAO,UAAU;EACnB;EACA,IAAI,WAAW;GACb,OAAO,UAAU;EACnB;EACA,IAAI,gBAAgB;GAClB,OAAO,UAAU;EACnB;EACA,IAAI,UAAU;GACZ,OAAO,UAAU;EACnB;EACA,IAAI,WAAW;GACb,OAAO,WAAW;EACpB;EACA,IAAI,UAAU;GACZ,OAAO,WAAW;EACpB;CACF,GACA,aACM,YAAY,IACpB;CAEA,MAAM,eAAe,kBAA0C;EAC7D,SAAS,MAAM,MAAM,MAAM;EAC3B,YAAY,UAAU,cAAc;EACpC,WAAW,gBAAgB,aAAa;EACxC,YAAY,UAAU,cAAc;EACpC,YAAY,UAAU,cAAc;EACpC,OAAO,MAAM,MAAM;CACrB,EAAE;CAEF,MAAM,cAAc,eAClB;EACE,IAAI,WAAW;GACb,OAAO,MAAM;EACf;EACA,OAAO,MAAM;EACb,OAAO,MAAM;EACb,kBAAkB;CACpB,GACA,YACF;CACA,MAAM,oBAA4C;EAChD,IAAI,UAAU;GACZ,OAAO,MAAM,MAAM,MAAM;EAC3B;EACA,IAAI,aAAa;GACf,OAAO,UAAU,cAAc;EACjC;EACA,IAAI,YAAY;GACd,OAAO,gBAAgB,aAAa;EACtC;EACA,IAAI,aAAa;GACf,OAAO,UAAU,cAAc;EACjC;EACA,IAAI,aAAa;GACf,OAAO,UAAU,cAAc;EACjC;EACA,IAAI,QAAQ;GACV,OAAO,MAAM,MAAM;EACrB;CACF;CAEA,MAAM,WAAW,iBACf,eAAe,MAAiC,EAAE,QAAQ,KAAK,CAAC,CAClE;CAEA,MAAM,kBAAkB,iBAAmC;EACzD,MAAM,YAAY,gBAAgB;EAClC,MAAM,eAAe,UAAU;EAG/B,OAAO;GACL;GACA,kBAJuB,aAAa,OAAO,iBAAiB,WAAW,CAAC,YAAY,IAAI,CAAC;GAKzF,mBAAmB,YACf;IAAE,GAAG;IAAsB,aAAa;IAAM,OAAO;GAAM,IAC3D;EACN;CACF,CAAC;CACD,MAAM,oBAA4C;EAChD,IAAI,aAAa;GACf,OAAO,gBAAgB;EACzB;EACA,IAAI,oBAAoB;GACtB,OAAO,gBAAgB;EACzB;CACF;CACA,MAAM,eAAwC;EAC5C;EACA,IAAI,aAAa;GACf,OAAO,gBAAgB;EACzB;EACA,IAAI,mBAAmB;GACrB,OAAO,gBAAgB;EACzB;EACA,IAAI,aAAa;GACf,OAAO,gBAAgB;EACzB;EACA,IAAI,mBAAmB;GACrB,OAAO,gBAAgB;EACzB;EACA,IAAI,oBAAoB;GACtB,OAAO,gBAAgB;EACzB;EACA,IAAI,aAAa;GACf,OAAO,UAAU,cAAc;EACjC;EACA,IAAI,YAAY;GACd,OAAO,gBAAgB,aAAa;EACtC;EACA,IAAI,aAAa;GACf,OAAO,UAAU,cAAc;EACjC;EACA,IAAI,aAAa;GACf,OAAO,UAAU,cAAc;EACjC;EACA;CACF;CACA,MAAM,sBAAsB;EAC1B,MAAM,WAAW,MAAM;EACvB,OAAO,OAAO,aAAa,aAAa,SAAS,iBAAiB,IAAI;CACxE;CAMA,MAAM,YAAY,EAChB,OAAO;EACL,IAAI,cAAc;GAChB,OAAO,gBAAgB;EACzB;EACA,IAAI,eAAe;GACjB,OAAO,gBAAgB;EACzB;CACF,EACF;CAEA,OACE,CAAC,kBAAkB,SAAS,OAAO,mBAAmB;MACpD,CAAC,mBAAmB,SAAS,OAAO,cAAc;QAChD,CAAC,QACK,SAAS,GACb,KAAK,MAAM,KACX,OAAO,YAAY,MAAM,GACzB,OAAO,YAAY,MAAM,GACzB,YAAY,MAAM,MAAM,MAAM,MAAM,KAAA,GACpC,eAAe,UAAU,cAAc,KAAA,GACvC,cAAc,gBAAgB,aAAa,KAAA,GAC3C,eAAe,UAAU,cAAc,KAAA,GACvC,eAAe,UAAU,cAAc,KAAA,GACxC;UACC,CAAC,SAAS,QAAQ,CAAC,CAAC,aAAa,SAAS,CAAC,GAAyC;aACjF,cAAc,EAAE;UACnB,EAAE,SAAS;QACb,EAAE,IAAI;MACR,EAAE,mBAAmB,SAAS;IAChC,EAAE,kBAAkB;AAExB;;;;AAKA,SAAgB,iBAAiB,OAIjB;CACd,MAAM,UAAU,WAAW,kBAAkB;CAC7C,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,oDAAoD;CAGtE,MAAM,wBAAwB;EAC5B,MAAM,EAAE,KAAK,MAAM,GAAG,SAAS,QAAQ;EACvC,OAAO;CACT;CAEA,OACE,CAAC,UACK,gBAAgB,GACpB,OAAO,MAAM,SAAS,+BACtB,OAAO,MAAM,OACd;OACE,MAAM,SAAS;IAClB,EAAE;AAEN;;;;AAKA,SAAgB,iBAAiB,OAA2C;CAC1E,MAAM,CAAC,OAAO,YAAY,WAAW,OAAO;EAAC;EAAS;EAAS;CAAM,CAAC;CACtE,IAAI;CAEJ,MAAM,UAAU,WAAW,kBAAkB;CAC7C,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,oDAAoD;CAUtE,MAAM,oBAAoB,qBAAqB;CAE/C,MAAM,EAAE,WAAW,gBAAgB,eAAe,gBAAgB;CAElE,MAAM,EAAE,WAAW,eAAe,YAAY,EAC5C,IAAI,aAAa;EACf,OAAO,QAAQ;CACjB,EACF,CAAC;CAED,MAAM,eAAe,kBAA+C;EAClE,WAAW,UAAU;EACrB,gBAAgB,eAAe;EAC/B,WAAW,UAAU;EACrB,YAAY,CAAC,CAAC,QAAQ;EACtB,WAAW,CAAC,CAAC,QAAQ;CACvB,EAAE;CAEF,MAAM,cAAc,eAClB;EACE,OAAO,MAAM;EACb,OAAO,MAAM;EACb,kBAAkB;CACpB,GACA,YACF;CAEA,MAAM,wBAAwB;EAC5B,MAAM,EAAE,KAAK,MAAM,GAAG,SAAS,QAAQ;EACvC,OAAO;CACT;CACA,MAAM,wBAAwB;EAC5B,MAAM,EAAE,KAAK,MAAM,GAAG,SAAS;EAC/B,OAAO;CACT;CACA,MAAM,wBAAwB;EAC5B,MAAM,EAAE,KAAK,MAAM,GAAG,SAAS;EAC/B,OAAO;CACT;CAEA,MAAM,+BAAwD;EAC5D,IAAI,CAAC,mBACH,OAAO,CAAC;EAEV,MAAM,aAAa,kBAAkB;EACrC,OAAO;GACL,iBAAiB,WAAW;GAC5B,qBAAqB,WAAW;GAChC,yBAAyB,WAAW,wBAAwB,CAAC;EAC/D;CACF;CAEA,MAAM,0BACH;EACC,GAAG;EACH,GAAG,gBAAgB;EACnB,GAAG,gBAAgB;EACnB,GAAG,gBAAgB;EACnB,GAAG,uBAAuB;CAC5B;CAEF,cAAc;EACZ,MAAM,UAAU;EAChB,IAAI,CAAC,SACH;EAGF,MAAM,gBAAgB,UAAiB;GACrC,MAAM,UAAU,iBAAiB,CAAC,CAAC;GAGnC,UACE,uBAAuB,OAAO,OAAO,CAIvC;GACA,gCAAgC,OAAO;GACvC,MAAM,gBAAgB;EACxB;EACA,MAAM,iBAAiB,UAAiB;GACtC,MAAM,UAAU,iBAAiB,CAAC,CAAC;GAGnC,UACE,uBAAuB,OAAO,OAAO,CAIvC;GACA,gCAAgC,OAAO;GACvC,MAAM,gBAAgB;EACxB;EAEA,QAAQ,iBAAiB,SAAS,YAAY;EAC9C,QAAQ,iBAAiB,UAAU,aAAa;EAChD,gCAAgC,OAAO;EACvC,gBAAgB;GACd,QAAQ,oBAAoB,SAAS,YAAY;GACjD,QAAQ,oBAAoB,UAAU,aAAa;EACrD,CAAC;CACH,CAAC;CAED,OACE,CAAC,UACK,iBAAiB,GACrB,MAAM,YAAY;EAChB,eAAe;EACf,QAAQ,cAAc,OAAO;EAC7B,mBAAmB,SAAS,OAAO;EACnC,MAAM,MAAO,SAA+B;EAC5C,IAAI,OAAO,QAAQ,YACjB,IAAI,OAAO;CAEf,GACA,OAAO,YAAY,MAAM,GACzB,OAAO,YAAY,MAAM,GACzB,cAAc,UAAU,KAAK,KAAA,GAC7B,oBAAoB,eAAe,KAAK,KAAA,GACxC,cAAc,UAAU,KAAK,KAAA,GAC7B,eAAe,QAAQ,cAAc,KAAA,GACrC,cAAc,QAAQ,aAAa,KAAA;AAGzC;;;;AAKA,SAAgB,uBAAuB,OAAiD;CACtF,MAAM,CAAC,OAAO,YAAY,WAAW,OAAO;EAAC;EAAS;EAAS;EAAQ;CAAU,CAAC;CAElF,MAAM,UAAU,WAAW,kBAAkB;CAC7C,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,0DAA0D;CAG5E,MAAM,mBAAmB,CAAC,EAAE,QAAQ,cAAc,QAAQ;CAC1D,MAAM,iBAAiB,QAAQ,OAAO,MAAM,KAAK,QAAQ;CACzD,MAAM,cAAc;EAClB,IAAI,CAAC,WAAW,KAAK,CAAC,QAAQ,GAC5B,QAAQ,kBAAkB,QAAQ;CAEtC;CAEA,MAAM,EAAE,WAAW,eAAe,YAAY;EAC5C,IAAI,aAAa;GACf,OAAO,QAAQ,cAAc,QAAQ;EACvC;EACA,SAAS;EACT,SAAS;CACX,CAAC;CAED,MAAM,EAAE,WAAW,eAAe,YAAY,EAC5C,IAAI,aAAa;EACf,OAAO,QAAQ,cAAc,QAAQ;CACvC,EACF,CAAC;CAED,MAAM,eAAe,kBAAqD;EACxE,WAAW,UAAU;EACrB,WAAW,UAAU;EACrB,YAAY,WAAW;CACzB,EAAE;CAEF,MAAM,cAAc,eAClB;EACE,IAAI,WAAW;GACb,OAAO,MAAM;EACf;EACA,OAAO,MAAM;EACb,OAAO,MAAM;EACb,kBAAkB;CACpB,GACA,YACF;CAEA,MAAM,wBAAwB;EAC5B,MAAM,EAAE,KAAK,MAAM,GAAG,SAAS;EAC/B,OAAO;CACT;CACA,MAAM,wBAAwB;EAC5B,MAAM,EAAE,KAAK,MAAM,GAAG,SAAS;EAC/B,OAAO;CACT;CAEA,OACE,CAAC,KAAK,MAAM,CAAC,QAAQ,GAAG;MACtB,CAAC,WACK,UACJ,cACA,YAAY,QAAQ,mBAAmB,iBAAiB,gBACxD,UAAU,QAAQ,kBAAkB,YAAY,IAChD,UAAU,QAAQ,kBAAkB,UACpC,aAAa,QAAQ,kBAAkB,iBACnC,gBAAgB,GACpB,aAAa,OACb,WAAW,OACX,SAAS,WACL,gBAAgB,GACpB,OAAO,YAAY,MAAM,GACzB,OAAO,YAAY,MAAM,GACzB,cAAc,UAAU,KAAK,KAAA,GAC7B,cAAc,UAAU,KAAK,KAAA,GAC7B,eAAe,WAAW,KAAK,KAAA,GAChC;SACE,YAAY,eAAe,EAAE;MAChC,EAAE,OAAO;IACX,EAAE;AAEN;AAEA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,cAAc"}
|
|
1
|
+
{"version":3,"file":"SearchField.jsx","names":["mergeProps"],"sources":["../src/SearchField.tsx"],"sourcesContent":["/**\n * SearchField component for solidaria-components\n *\n * A pre-wired headless search field that combines state + aria hooks.\n * Port of react-aria-components/src/SearchField.tsx\n */\n\nimport {\n type JSX,\n type Context,\n createContext,\n createMemo,\n onCleanup,\n onMount,\n splitProps,\n useContext,\n Show,\n} from \"solid-js\";\nimport {\n createSearchField,\n createFocusRing,\n createHover,\n createPress,\n mergeProps,\n type AriaSearchFieldProps,\n} from \"@proyecto-viviana/solidaria\";\nimport {\n createSearchFieldState,\n VALID_VALIDITY_STATE,\n type SearchFieldState,\n type ValidationResult,\n} from \"@proyecto-viviana/solid-stately\";\nimport { FormContext, type FormProps } from \"./Form\";\nimport { FieldErrorContext, type FieldErrorContextValue } from \"./FieldError\";\nimport {\n type RenderChildren,\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n filterDOMProps,\n Provider,\n} from \"./utils\";\nimport { TextContext } from \"./Text\";\nimport { useAutocompleteInput } from \"./Autocomplete\";\n\nexport interface SearchFieldRenderProps {\n /** Whether the search field is empty. */\n isEmpty: boolean;\n /** Whether the search field is disabled. */\n isDisabled: boolean;\n /** Whether the search field is invalid. */\n isInvalid: boolean;\n /** Whether the search field is read-only. */\n isReadOnly: boolean;\n /** Whether the search field is required. */\n isRequired: boolean;\n /** The current value. */\n value: string;\n}\n\nexport interface SearchFieldProps extends Omit<AriaSearchFieldProps, \"label\">, SlotProps {\n /** The current value (controlled). */\n value?: string;\n /** The default value (uncontrolled). */\n defaultValue?: string;\n /** Handler called when the value changes. */\n onChange?: (value: string) => void;\n /** Handler called when the user submits the search. */\n onSubmit?: (value: string) => void;\n /** Handler called when the field is cleared. */\n onClear?: () => void;\n /** A visible label for the search field. */\n label?: JSX.Element;\n /** The children of the component. */\n children?: RenderChildren<SearchFieldRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SearchFieldRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SearchFieldRenderProps>;\n /** Ref for the outer search field element. */\n ref?: (el: HTMLDivElement) => void;\n}\n\nexport interface SearchFieldInputRenderProps {\n /** Whether the input is focused. */\n isFocused: boolean;\n /** Whether the input has keyboard focus. */\n isFocusVisible: boolean;\n /** Whether the input is hovered. */\n isHovered: boolean;\n /** Whether the input is disabled. */\n isDisabled: boolean;\n /** Whether the input is invalid. */\n isInvalid: boolean;\n}\n\nexport interface SearchFieldInputProps\n extends SlotProps, Omit<JSX.InputHTMLAttributes<HTMLInputElement>, \"class\" | \"style\"> {\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SearchFieldInputRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SearchFieldInputRenderProps>;\n}\n\nexport interface SearchFieldClearButtonRenderProps {\n /** Whether the button is pressed. */\n isPressed: boolean;\n /** Whether the button is hovered. */\n isHovered: boolean;\n /** Whether the button is disabled. */\n isDisabled: boolean;\n}\n\nexport interface SearchFieldClearButtonProps\n extends\n SlotProps,\n Omit<JSX.ButtonHTMLAttributes<HTMLButtonElement>, \"class\" | \"style\" | \"children\"> {\n /** The children of the button. */\n children?: RenderChildren<SearchFieldClearButtonRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<SearchFieldClearButtonRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<SearchFieldClearButtonRenderProps>;\n}\n\ninterface SearchFieldContextValue extends Partial<SearchFieldProps> {\n state?: SearchFieldState;\n inputProps?: JSX.InputHTMLAttributes<HTMLInputElement>;\n clearButtonProps?: {\n \"aria-label\": string;\n tabIndex: number;\n disabled?: boolean;\n onMouseDown: (e: MouseEvent) => void;\n onClick: () => void;\n };\n labelProps?: JSX.HTMLAttributes<HTMLElement>;\n descriptionProps?: JSX.HTMLAttributes<HTMLElement>;\n errorMessageProps?: JSX.HTMLAttributes<HTMLElement>;\n isDisabled?: boolean;\n isInvalid?: boolean;\n isRequired?: boolean;\n isReadOnly?: boolean;\n setInputRef?: (el: HTMLInputElement) => void;\n slots?: Record<string, SearchFieldProps>;\n}\n\nexport const SearchFieldContext = createContext<SearchFieldContextValue | null>(null);\n\nfunction withFormValidationBehavior(\n props: SearchFieldProps,\n formContext: FormProps | null,\n): SearchFieldProps {\n if (!formContext?.validationBehavior) {\n return props;\n }\n\n return new Proxy(props, {\n get(target, property, receiver) {\n const localValue = Reflect.get(target, property, receiver);\n if (property === \"validationBehavior\" && localValue === undefined) {\n return formContext.validationBehavior;\n }\n\n return localValue;\n },\n has(target, property) {\n return (\n Reflect.has(target, property) ||\n (property === \"validationBehavior\" && formContext.validationBehavior !== undefined)\n );\n },\n ownKeys(target) {\n const keys = new Set(Reflect.ownKeys(target));\n if (formContext.validationBehavior !== undefined) {\n keys.add(\"validationBehavior\");\n }\n\n return Array.from(keys);\n },\n getOwnPropertyDescriptor(target, property) {\n const descriptor = Reflect.getOwnPropertyDescriptor(target, property);\n if (descriptor) {\n return descriptor;\n }\n\n if (property === \"validationBehavior\" && formContext.validationBehavior !== undefined) {\n return {\n enumerable: true,\n configurable: true,\n get: () => formContext.validationBehavior,\n };\n }\n\n return undefined;\n },\n });\n}\n\nfunction eventWithCurrentTarget<T extends HTMLElement>(event: Event, element: T): Event {\n return new Proxy(event, {\n get(target, property, receiver) {\n if (property === \"target\" || property === \"currentTarget\") {\n return element;\n }\n\n const value = Reflect.get(target, property, receiver);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n });\n}\n\nfunction clearDelegatedTextEntryHandlers(element: HTMLElement) {\n const delegatedElement = element as HTMLElement & {\n $$input?: unknown;\n $$change?: unknown;\n };\n delete delegatedElement.$$input;\n delete delegatedElement.$$change;\n}\n\n/**\n * A search field allows a user to enter and clear a search query.\n */\nexport function SearchField(props: SearchFieldProps): JSX.Element {\n const formContext = useContext(FormContext);\n const contextProps = useContext(SearchFieldContext);\n const contextSlotProps = contextProps?.slots?.[props.slot ?? \"default\"];\n const contextBaseProps = createMemo<SearchFieldProps>(() => {\n if (!contextProps) return {};\n const {\n state: _state,\n inputProps: _inputProps,\n clearButtonProps: _clearButtonProps,\n labelProps: _labelProps,\n descriptionProps: _descriptionProps,\n errorMessageProps: _errorMessageProps,\n isDisabled: _isDisabled,\n isInvalid: _isInvalid,\n isRequired: _isRequired,\n isReadOnly: _isReadOnly,\n setInputRef: _setInputRef,\n slots: _slots,\n ...restContextProps\n } = contextProps;\n return restContextProps as SearchFieldProps;\n });\n const baseProps = (\n contextProps ? mergeProps(contextBaseProps(), contextSlotProps ?? {}, props) : props\n ) as SearchFieldProps;\n\n // When rendered inside an <Autocomplete>, the FieldInputContext (AutocompleteContext)\n // controls the input's value and keyboard handling: value + onChange make the field's\n // state controlled by the shared autocomplete state (which drives the collection\n // filter), and onKeyDown/onFocus/onBlur chain the autocomplete's virtual-focus\n // navigation into the input. This mirrors RAC's\n // useContextProps(props, inputRef, FieldInputContext). The remaining passthroughs\n // (aria-activedescendant/aria-controls/aria-autocomplete) and the input-ref\n // registration are applied at the <input> in SearchFieldInput.\n const autocompleteInput = useAutocompleteInput();\n const autocompleteProps = autocompleteInput\n ? ({\n get value() {\n return autocompleteInput.inputProps.value();\n },\n onChange: autocompleteInput.inputProps.onChange,\n onKeyDown: autocompleteInput.inputProps\n .onKeyDown as unknown as SearchFieldProps[\"onKeyDown\"],\n onFocus: autocompleteInput.inputProps.onFocus as unknown as SearchFieldProps[\"onFocus\"],\n onBlur: autocompleteInput.inputProps.onBlur as unknown as SearchFieldProps[\"onBlur\"],\n } as Partial<SearchFieldProps>)\n : undefined;\n\n const mergedProps = withFormValidationBehavior(\n autocompleteProps ? (mergeProps(baseProps, autocompleteProps) as SearchFieldProps) : baseProps,\n formContext,\n );\n\n const [local, stateProps, ariaProps, rest] = splitProps(\n mergedProps,\n [\"children\", \"class\", \"style\", \"slot\", \"ref\"],\n [\"value\", \"defaultValue\", \"onChange\", \"onSubmit\", \"onClear\"],\n [\n \"label\",\n \"aria-label\",\n \"aria-labelledby\",\n \"aria-describedby\",\n \"isDisabled\",\n \"isReadOnly\",\n \"isRequired\",\n \"isInvalid\",\n \"description\",\n \"errorMessage\",\n \"id\",\n \"autoFocus\",\n \"excludeFromTabOrder\",\n \"name\",\n \"form\",\n \"validationBehavior\",\n \"type\",\n \"placeholder\",\n \"autoComplete\",\n \"inputMode\",\n \"enterKeyHint\",\n \"autoCorrect\",\n \"autoCapitalize\",\n \"spellCheck\",\n \"maxLength\",\n \"minLength\",\n \"pattern\",\n \"onFocus\",\n \"onBlur\",\n \"onFocusChange\",\n \"onKeyDown\",\n \"onKeyUp\",\n \"onCopy\",\n \"onCut\",\n \"onPaste\",\n \"onCompositionStart\",\n \"onCompositionEnd\",\n \"onCompositionUpdate\",\n \"onSelect\",\n \"onBeforeInput\",\n \"onInput\",\n ],\n );\n\n const state = createSearchFieldState({\n get value() {\n return stateProps.value;\n },\n get defaultValue() {\n return stateProps.defaultValue;\n },\n get onChange() {\n return stateProps.onChange;\n },\n });\n\n let inputRef: HTMLInputElement | undefined;\n const setInputRef = (el: HTMLInputElement) => {\n inputRef = el;\n };\n\n const searchFieldAria = createSearchField(\n {\n get isDisabled() {\n return ariaProps.isDisabled;\n },\n get isReadOnly() {\n return ariaProps.isReadOnly;\n },\n get isRequired() {\n return ariaProps.isRequired;\n },\n get isInvalid() {\n return ariaProps.isInvalid;\n },\n get label() {\n return ariaProps.label;\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 description() {\n return ariaProps.description;\n },\n get errorMessage() {\n return ariaProps.errorMessage;\n },\n get placeholder() {\n return ariaProps.placeholder;\n },\n get name() {\n return ariaProps.name;\n },\n get form() {\n return ariaProps.form;\n },\n get validationBehavior() {\n return ariaProps.validationBehavior;\n },\n get type() {\n return ariaProps.type;\n },\n get autoFocus() {\n return ariaProps.autoFocus;\n },\n get excludeFromTabOrder() {\n return ariaProps.excludeFromTabOrder;\n },\n get autoComplete() {\n return ariaProps.autoComplete;\n },\n get inputMode() {\n return ariaProps.inputMode;\n },\n get enterKeyHint() {\n return ariaProps.enterKeyHint;\n },\n get autoCorrect() {\n return ariaProps.autoCorrect;\n },\n get autoCapitalize() {\n return ariaProps.autoCapitalize;\n },\n get spellCheck() {\n return ariaProps.spellCheck;\n },\n get maxLength() {\n return ariaProps.maxLength;\n },\n get minLength() {\n return ariaProps.minLength;\n },\n get pattern() {\n return ariaProps.pattern;\n },\n get onFocus() {\n return ariaProps.onFocus;\n },\n get onBlur() {\n return ariaProps.onBlur;\n },\n get onFocusChange() {\n return ariaProps.onFocusChange;\n },\n get onKeyDown() {\n return ariaProps.onKeyDown;\n },\n get onKeyUp() {\n return ariaProps.onKeyUp;\n },\n get onCopy() {\n return ariaProps.onCopy;\n },\n get onCut() {\n return ariaProps.onCut;\n },\n get onPaste() {\n return ariaProps.onPaste;\n },\n get onCompositionStart() {\n return ariaProps.onCompositionStart;\n },\n get onCompositionEnd() {\n return ariaProps.onCompositionEnd;\n },\n get onCompositionUpdate() {\n return ariaProps.onCompositionUpdate;\n },\n get onSelect() {\n return ariaProps.onSelect;\n },\n get onBeforeInput() {\n return ariaProps.onBeforeInput;\n },\n get onInput() {\n return ariaProps.onInput;\n },\n get onSubmit() {\n return stateProps.onSubmit;\n },\n get onClear() {\n return stateProps.onClear;\n },\n },\n state,\n () => inputRef ?? null,\n );\n\n const renderValues = createMemo<SearchFieldRenderProps>(() => ({\n isEmpty: state.value() === \"\",\n isDisabled: ariaProps.isDisabled ?? false,\n isInvalid: searchFieldAria.isInvalid ?? false,\n isRequired: ariaProps.isRequired ?? false,\n isReadOnly: ariaProps.isReadOnly ?? false,\n value: state.value(),\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-SearchField\",\n },\n renderValues,\n );\n const childRenderValues: SearchFieldRenderProps = {\n get isEmpty() {\n return state.value() === \"\";\n },\n get isDisabled() {\n return ariaProps.isDisabled ?? false;\n },\n get isInvalid() {\n return searchFieldAria.isInvalid ?? false;\n },\n get isRequired() {\n return ariaProps.isRequired ?? false;\n },\n get isReadOnly() {\n return ariaProps.isReadOnly ?? false;\n },\n get value() {\n return state.value();\n },\n };\n\n const domProps = createMemo(() =>\n filterDOMProps(rest as Record<string, unknown>, { global: true }),\n );\n\n const fieldValidation = createMemo<ValidationResult>(() => {\n const isInvalid = searchFieldAria.isInvalid;\n const errorMessage = ariaProps.errorMessage;\n const validationErrors = isInvalid && typeof errorMessage === \"string\" ? [errorMessage] : [];\n\n return {\n isInvalid,\n validationErrors,\n validationDetails: isInvalid\n ? { ...VALID_VALIDITY_STATE, customError: true, valid: false }\n : VALID_VALIDITY_STATE,\n };\n });\n const fieldErrorContext: FieldErrorContextValue = {\n get validation() {\n return fieldValidation();\n },\n get errorMessageProps() {\n return searchFieldAria.errorMessageProps;\n },\n };\n const contextValue: SearchFieldContextValue = {\n state,\n get inputProps() {\n return searchFieldAria.inputProps;\n },\n get clearButtonProps() {\n return searchFieldAria.clearButtonProps;\n },\n get labelProps() {\n return searchFieldAria.labelProps as JSX.HTMLAttributes<HTMLElement>;\n },\n get descriptionProps() {\n return searchFieldAria.descriptionProps;\n },\n get errorMessageProps() {\n return searchFieldAria.errorMessageProps;\n },\n get isDisabled() {\n return ariaProps.isDisabled ?? false;\n },\n get isInvalid() {\n return searchFieldAria.isInvalid ?? false;\n },\n get isRequired() {\n return ariaProps.isRequired ?? false;\n },\n get isReadOnly() {\n return ariaProps.isReadOnly ?? false;\n },\n setInputRef,\n };\n const fieldChildren = () => {\n const children = local.children;\n return typeof children === \"function\" ? children(childRenderValues) : children;\n };\n // Provide the description / errorMessage props as `TextContext` slots (mirrors\n // react-aria-components' SearchField), so a `<Text slot=\"description\">` /\n // `<Text slot=\"errorMessage\">` child picks up the `id` its `aria-describedby`\n // references. Additive: existing consumers reading these off\n // `SearchFieldContext` are unaffected.\n const textSlots = {\n slots: {\n get description() {\n return searchFieldAria.descriptionProps;\n },\n get errorMessage() {\n return searchFieldAria.errorMessageProps;\n },\n },\n };\n\n return (\n <FieldErrorContext.Provider value={fieldErrorContext}>\n <SearchFieldContext.Provider value={contextValue}>\n <div\n {...domProps()}\n ref={local.ref}\n class={renderProps.class()}\n style={renderProps.style()}\n data-empty={state.value() === \"\" || undefined}\n data-disabled={ariaProps.isDisabled || undefined}\n data-invalid={searchFieldAria.isInvalid || undefined}\n data-required={ariaProps.isRequired || undefined}\n data-readonly={ariaProps.isReadOnly || undefined}\n >\n <Provider values={[[TextContext, textSlots]] as Array<[Context<unknown>, unknown]>}>\n {fieldChildren()}\n </Provider>\n </div>\n </SearchFieldContext.Provider>\n </FieldErrorContext.Provider>\n );\n}\n\n/**\n * The label for a search field.\n */\nexport function SearchFieldLabel(props: {\n children?: JSX.Element;\n class?: string;\n style?: JSX.CSSProperties;\n}): JSX.Element {\n const context = useContext(SearchFieldContext);\n if (!context) {\n throw new Error(\"SearchFieldLabel must be used within a SearchField\");\n }\n\n const cleanLabelProps = () => {\n const { ref: _ref, ...rest } = context.labelProps as Record<string, unknown>;\n return rest;\n };\n\n return (\n <label\n {...cleanLabelProps()}\n class={props.class ?? \"solidaria-SearchField-label\"}\n style={props.style}\n >\n {props.children}\n </label>\n );\n}\n\n/**\n * The input element for a search field.\n */\nexport function SearchFieldInput(props: SearchFieldInputProps): JSX.Element {\n const [local, domProps] = splitProps(props, [\"class\", \"style\", \"slot\"]);\n let inputElement: HTMLInputElement | undefined;\n\n const context = useContext(SearchFieldContext);\n if (!context) {\n throw new Error(\"SearchFieldInput must be used within a SearchField\");\n }\n\n // Inside an <Autocomplete>, expose the ARIA attributes that identify the\n // controlled collection and its virtually-focused option. value/onChange and the\n // keyboard handlers are already merged upstream in SearchField(); here we only add\n // the passthrough attributes that createTextField doesn't forward, and register the\n // input element as the autocomplete inputRef so the beforeinput + reverse-path\n // (aria-activedescendant mirror) listeners bind. Mirrors RAC's\n // [InputContext, {...inputProps, ref: inputRef}].\n const autocompleteInput = useAutocompleteInput();\n\n const { isFocused, isFocusVisible, focusProps } = createFocusRing();\n\n const { isHovered, hoverProps } = createHover({\n get isDisabled() {\n return context.isDisabled;\n },\n });\n\n const renderValues = createMemo<SearchFieldInputRenderProps>(() => ({\n isFocused: isFocused(),\n isFocusVisible: isFocusVisible(),\n isHovered: isHovered(),\n isDisabled: !!context.isDisabled,\n isInvalid: !!context.isInvalid,\n }));\n\n const renderProps = useRenderProps(\n {\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-SearchField-input\",\n },\n renderValues,\n );\n\n const cleanInputProps = () => {\n const { ref: _ref, ...rest } = context.inputProps as Record<string, unknown>;\n return rest;\n };\n const cleanFocusProps = () => {\n const { ref: _ref, ...rest } = focusProps as Record<string, unknown>;\n return rest;\n };\n const cleanHoverProps = () => {\n const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;\n return rest;\n };\n\n const autocompleteInputAttrs = (): Record<string, unknown> => {\n if (!autocompleteInput) {\n return {};\n }\n const inputProps = autocompleteInput.inputProps;\n return {\n \"aria-controls\": inputProps[\"aria-controls\"],\n \"aria-autocomplete\": inputProps[\"aria-autocomplete\"],\n \"aria-activedescendant\": inputProps[\"aria-activedescendant\"](),\n };\n };\n\n const mergedInputProps = () =>\n ({\n ...domProps,\n ...cleanInputProps(),\n ...cleanFocusProps(),\n ...cleanHoverProps(),\n ...autocompleteInputAttrs(),\n }) as Record<string, unknown>;\n\n onMount(() => {\n const element = inputElement;\n if (!element) {\n return;\n }\n\n const inputHandler = (event: Event) => {\n const handler = mergedInputProps().onInput as\n | JSX.EventHandler<HTMLInputElement, InputEvent>\n | undefined;\n handler?.(\n eventWithCurrentTarget(event, element) as InputEvent & {\n currentTarget: HTMLInputElement;\n target: Element;\n },\n );\n clearDelegatedTextEntryHandlers(element);\n event.stopPropagation();\n };\n const changeHandler = (event: Event) => {\n const handler = mergedInputProps().onChange as\n | JSX.EventHandler<HTMLInputElement, Event>\n | undefined;\n handler?.(\n eventWithCurrentTarget(event, element) as Event & {\n currentTarget: HTMLInputElement;\n target: Element;\n },\n );\n clearDelegatedTextEntryHandlers(element);\n event.stopPropagation();\n };\n\n element.addEventListener(\"input\", inputHandler);\n element.addEventListener(\"change\", changeHandler);\n clearDelegatedTextEntryHandlers(element);\n onCleanup(() => {\n element.removeEventListener(\"input\", inputHandler);\n element.removeEventListener(\"change\", changeHandler);\n });\n });\n\n return (\n <input\n {...mergedInputProps()}\n ref={(element) => {\n inputElement = element;\n context.setInputRef?.(element);\n autocompleteInput?.inputRef(element);\n const ref = (domProps as { ref?: unknown }).ref;\n if (typeof ref === \"function\") {\n ref(element);\n }\n }}\n class={renderProps.class()}\n style={renderProps.style()}\n data-focused={isFocused() || undefined}\n data-focus-visible={isFocusVisible() || undefined}\n data-hovered={isHovered() || undefined}\n data-disabled={context.isDisabled || undefined}\n data-invalid={context.isInvalid || undefined}\n />\n );\n}\n\n/**\n * The clear button for a search field.\n */\nexport function SearchFieldClearButton(props: SearchFieldClearButtonProps): JSX.Element {\n const [local, domProps] = splitProps(props, [\"class\", \"style\", \"slot\", \"children\"]);\n\n const context = useContext(SearchFieldContext);\n if (!context) {\n throw new Error(\"SearchFieldClearButton must be used within a SearchField\");\n }\n\n const isDisabled = () => !!(context.isDisabled || context.isReadOnly);\n const isEmpty = () => (context.state?.value() ?? \"\") === \"\";\n const clear = () => {\n if (!isDisabled() && !isEmpty()) {\n context.clearButtonProps?.onClick();\n }\n };\n\n const { isPressed, pressProps } = createPress({\n get isDisabled() {\n return context.isDisabled || context.isReadOnly;\n },\n onClick: clear,\n onPress: clear,\n });\n\n const { isHovered, hoverProps } = createHover({\n get isDisabled() {\n return context.isDisabled || context.isReadOnly;\n },\n });\n\n const renderValues = createMemo<SearchFieldClearButtonRenderProps>(() => ({\n isPressed: isPressed(),\n isHovered: isHovered(),\n isDisabled: 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-SearchField-clear\",\n },\n renderValues,\n );\n\n const cleanPressProps = () => {\n const { ref: _ref, ...rest } = pressProps as Record<string, unknown>;\n return rest;\n };\n const cleanHoverProps = () => {\n const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;\n return rest;\n };\n\n return (\n <Show when={!isEmpty()}>\n <button\n {...domProps}\n type=\"button\"\n aria-label={context.clearButtonProps?.[\"aria-label\"] ?? \"Clear search\"}\n tabIndex={context.clearButtonProps?.tabIndex ?? -1}\n disabled={context.clearButtonProps?.disabled}\n onMouseDown={context.clearButtonProps?.onMouseDown}\n {...cleanPressProps()}\n onPointerUp={clear}\n onMouseUp={clear}\n onClick={clear}\n {...cleanHoverProps()}\n class={renderProps.class()}\n style={renderProps.style()}\n data-pressed={isPressed() || undefined}\n data-hovered={isHovered() || undefined}\n data-disabled={isDisabled() || undefined}\n >\n {renderProps.renderChildren()}\n </button>\n </Show>\n );\n}\n\nSearchField.Label = SearchFieldLabel;\nSearchField.Input = SearchFieldInput;\nSearchField.ClearButton = SearchFieldClearButton;\n"],"mappings":"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"}
|
|
@@ -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":";;;;;;;;;;;;;AAmCA,SAAS,cAAc,IAA8B;CACnD,OAAO,OAAO,GAAG,kBAAkB,aAAa,GAAG,cAAc,IAAI,CAAC;AACxE;AAWA,MAAM,uBAAuB,cAAyC,IAAI;AAE1E,SAAgB,qCAA8C;CAC5D,OAAO,WAAW,oBAAoB,KAAK;AAC7C;;;;AASA,SAAgB,wBAAwB,OAAkD;CACxF,MAAM,QAA4B,EAChC,WAAW,CAAC,EACd;CAEA,OACE,CAAC,qBAAqB,SAAS,OAAO,QAAQ,MAAM,SAAS,EAAE,qBAAqB;AAExF;;;;;AA0BA,SAAgB,cAAc,OAA+C;CAC3E,MAAM,QAAQ,WAAW,oBAAoB;CAC7C,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,qEAAqE;CAGvF,MAAM,CAAC,OAAO,YAAY,WAAW,OAAO;EAC1C;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,CAAC,WAAW,gBAAgB,aAChC,MAAM,cAAc,QAAQ,WAAW,SACzC;CAOA,MAAM,CAAC,SAAS,cAAc,aAAyC;CACvE,IAAI;CAEJ,MAAM,UAAU,OAAuB;EACrC,WAAW,EAAE;EAEb,MAAM,UAAU,MAAM;EACtB,IAAI,OAAO,YAAY,YACrB,QAAQ,EAAE;OACL,IAAI,YAAY,KAAA,GACrB,QAAQ,UAAU;CAEtB;CAOA,MAAM,sBAAsB;EAC1B,MAAM,KAAK,QAAQ,OAAO;EAC1B,IAAI,MAAM,GAAG,eAAe,CAAC,GAAG,aAAa,cAAc,GAAG;GAE5D,MAAM,QAAQ,OAAO,iBAAiB,EAAE;GACxC,IAAI,MAAM,uBAAuB,QAAQ;IACvC,MAAM,qBAAqB,MAAM,mBAAmB,MAAM,SAAS;IACnE,MAAM,UAAU,MAAM,QAAQ;KAC5B,MAAM,GAAG,sBAAsB;KAC/B,OAAO,mBAAmB,KAAK,aAAa,CAAC,UAAU,MAAM,iBAAiB,QAAQ,CAAC,CAAC;IAC1F;GACF;EACF;CACF;CAUA,mBACE,SACQ,MAAM,cAAc,QACzB,cAAc;EACb,IAAI,aAAa,QAAQ,SAAS,MAAM,UACtC,aAAa,SAAS;CAE1B,CACF,CACF;CAWA,mBACE,SACQ,MAAM,cAAc,QACzB,cAAc;EACb,gBAAgB;GACd,IAAI,WACF,cAAc;EAElB,CAAC;CACH,CACF,CACF;CAWA,aACE,GACE,OAAO,MAAM,cAAc,OAAO,OAAO,IACxC,CAAC,WAAW,QAAQ;EACnB,MAAM,OAAO,MAAM;EAEnB,IAAI,SAAS,MAAM;GACjB,qBAAqB,KAAK;GAC1B,QAAQ,KAAA;EACV;EAEA,IAAI,aAAa,IAAI;GACnB,MAAM,eAAe,MAAM,UAAU;GAErC,IAAI,cAAc;IAEhB,aAAa,SAAS;IACtB,MAAM,aAAa,cAAc,EAAE;IAGnC,MAAM,SAAS,aAAa,MAAM,KAAK,CAAC,UAAU,eAAe;KAC/D,MAAM,QAAQ,GAAG,MAAM,iBAAiB,QAAQ;KAChD,IAAI,aAAa,aAAa;MAC5B,MAAM,WAAW,aAAa;MAC9B,MAAM,cAAc,GAAG,sBAAsB;MAC7C,MAAM,SAAS,SAAS,OAAO,YAAY;MAC3C,MAAM,SAAS,SAAS,MAAM,YAAY;MAC1C,GAAG,MAAM,YAAY,aAAa,GAAG,OAAO,KAAK,OAAO,GAAG;KAC7D,OACE,GAAG,MAAM,YAAY,UAAU,SAAS;KAE1C,OAAO,CAAC,UAAU,KAAK;IACzB,CAAC;IAGD,KAAK,MAAM,KAAK,cAAc,EAAE,GAC9B,IAAI,CAAC,WAAW,SAAS,CAAC,GACxB,EAAE,OAAO;IAKb,QAAQ,4BAA4B;KAClC,QAAQ,KAAA;KACR,KAAK,MAAM,CAAC,UAAU,UAAU,QAC9B,GAAG,MAAM,YAAY,UAAU,KAAK;IAExC,CAAC;IAED,OAAO,MAAM,UAAU;GACzB,OAAO;IAEL,qBAAqB,aAAa,UAAU,CAAC;IAC7C,QAAQ,4BAA4B;KAClC,QAAQ,KAAA;KACR,aAAa,SAAS;IACxB,CAAC;GACH;EACF,OAAO,IAAI,CAAC,aAAa,IAGvB,qBAAqB;GACnB,IAAI,MAAM,UAAU,OAAO;IACzB,OAAO,MAAM,UAAU;IACvB,aAAa,SAAS;IAEtB,QAAQ,IAAI,cAAc,EAAE,CAAC,CAAC,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC,CAClD,WAAW,aAAa,QAAQ,CAAC,CAAC,CAClC,YAAY,CAAC,CAAC;GACnB,OAEE,aAAa,QAAQ;EAEzB,CAAC;CAEL,CACF,CACF;CAIA,gBAAgB;EACd,IAAI,SAAS,MACX,qBAAqB,KAAK;CAE9B,CAAC;CAED,MAAM,cAAc,eAClB;EACE,IAAI,WAAW;GACb,OAAO,MAAM;EACf;EACA,OAAO,MAAM;EACb,OAAO,MAAM;EACb,kBAAkB;CACpB,UACO;EACL,YAAY,UAAU,MAAM;EAC5B,WAAW,UAAU,MAAM;CAC7B,EACF;CAEA,MAAM,mBAAmB,iBAAiB,eAAe,UAAU,EAAE,QAAQ,KAAK,CAAC,CAAC;CAEpF,OACE,CAAC,KAAK,MAAM,UAAU,MAAM,UAAU;MACpC,CAAC,IACC,KAAK,YACD,iBAAiB,GACrB,OAAO,YAAY,MAAM,GACzB,OAAO,YAAY,MAAM,GACzB,eAAe,UAAU,MAAM,cAAc,KAAA,GAC7C,cAAc,UAAU,MAAM,aAAa,KAAA,GAC5C;SACE,YAAY,eAAe,EAAE;MAChC,EAAE,IAAI;IACR,EAAE;AAEN"}
|
|
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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"}
|
package/dist/TimeField.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeField.d.ts","sourceRoot":"","sources":["../src/TimeField.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,KAAK,GAAG,EACR,KAAK,OAAO,EAOb,MAAM,UAAU,CAAC;AAClB,OAAO,EAA+B,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACnG,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,WAAW,IAAI,eAAe,EACnC,KAAK,SAAS,EACf,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"TimeField.d.ts","sourceRoot":"","sources":["../src/TimeField.tsx"],"names":[],"mappings":"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"}
|
package/dist/TimeField.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeField.js","names":["JSX","Context","createContext","createMemo","createSignal","splitProps","useContext","Show","createTimeField","mergeProps","AriaTimeFieldProps","createTimeFieldState","access","TimeFieldState","TimeFieldStateProps","TimeSegment","TimeSegmentType","TimeValue","DateFieldContext","DateFieldStateContext","DateFieldContextValue","ClassNameOrFunction","StyleOrFunction","SlotProps","useRenderProps","dataAttr","useIsHydrated","Provider","TextContext","FormContext","FormProps","TimeFieldRenderProps","isDisabled","isReadOnly","isRequired","isInvalid","TimeFieldProps","Omit","T","children","Element","segment","class","style","locale","TimeFieldContextValue","state","aria","labelProps","Record","inputProps","descriptionProps","errorMessageProps","TimeFieldContext","TimeFieldStateContext","withFormValidationBehavior","props","P","formContext","validationBehavior","Proxy","get","target","property","receiver","localValue","Reflect","undefined","has","ownKeys","keys","Set","add","Array","from","getOwnPropertyDescriptor","descriptor","enumerable","configurable","useTimeFieldContextValue","context","Error","useTimeFieldContext","TimeField","isHydrated","_$createComponent","when","fallback","_$getNextElement","_tmpl$","TimeFieldInner","_$mergeProps","__formContext","TimeFieldInnerProps","mergedProps","local","stateProps","rest","fieldRef","setFieldRef","HTMLDivElement","validationInputRef","setValidationInputRef","HTMLInputElement","fieldAria","description","errorMessage","inputRef","renderValues","renderProps","defaultClassName","textSlots","slots","dateFieldContextValue","fieldProps","hiddenInputProps","ref","value","_el$2","_tmpl$2","_$use","_$insert","values","_$effect","_p$","_v$","_v$2","_v$3","_v$4","_v$5","_v$6","e","_$className","t","_$style","a","_$setAttribute","o","i","n","TimeFieldLabelProps","TimeFieldLabel","_el$3","_tmpl$3","_$spread","_$runHydrationEvents","TimeFieldDescriptionProps","TimeFieldDescription","_el$4","TimeFieldErrorMessageProps","TimeFieldErrorMessage","_el$5"],"sources":["../src/TimeField.tsx"],"sourcesContent":["/**\n * TimeField component for solidaria-components\n *\n * Pre-wired headless time field. Faithful port of react-aria-components'\n * TimeField, which does NOT define its own segment primitives — it reuses\n * `DateInput`/`DateSegment` (there is no `TimeInput`/`TimeSegment` upstream).\n * `TimeFieldState` IS a `DateFieldState` (plus `timeValue`), so this component\n * drives the certified DateField segment/group stack directly: it provides the\n * shared `DateFieldContext`/`DateFieldStateContext` that `DateInput`/`DateSegment`\n * read, plus a `TimeFieldContext` for the time-field label/description/error\n * chrome. Unlike DateField, TimeField renders NO root hidden autofill input (RAC\n * TimeField renders none); its native-validation `<input>` is still emitted by\n * the inner DateInput sibling.\n */\n\nimport {\n type JSX,\n type Context,\n createContext,\n createMemo,\n createSignal,\n splitProps,\n useContext,\n Show,\n} from \"solid-js\";\nimport { createTimeField, mergeProps, type AriaTimeFieldProps } from \"@proyecto-viviana/solidaria\";\nimport {\n createTimeFieldState,\n access,\n type TimeFieldState,\n type TimeFieldStateProps,\n type TimeSegment as TimeSegmentType,\n type TimeValue,\n} from \"@proyecto-viviana/solid-stately\";\nimport {\n DateFieldContext,\n DateFieldStateContext,\n type DateFieldContextValue,\n} from \"./DateField\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n dataAttr,\n useIsHydrated,\n Provider,\n} from \"./utils\";\nimport { TextContext } from \"./Text\";\nimport { FormContext, type FormProps } from \"./Form\";\n\nexport interface TimeFieldRenderProps {\n /** Whether the field is disabled. */\n isDisabled: boolean;\n /** Whether the field is read-only. */\n isReadOnly: boolean;\n /** Whether the field is required. */\n isRequired: boolean;\n /** Whether the field is invalid. */\n isInvalid: boolean;\n}\n\nexport interface TimeFieldProps<T extends TimeValue = TimeValue>\n extends\n Omit<AriaTimeFieldProps, \"id\" | \"isDisabled\" | \"isReadOnly\" | \"isRequired\">,\n Omit<TimeFieldStateProps<T>, \"locale\">,\n SlotProps {\n /** The children of the component. */\n children?: JSX.Element | ((segment: TimeSegmentType) => JSX.Element);\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<TimeFieldRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<TimeFieldRenderProps>;\n /** The locale to use for formatting. */\n locale?: string;\n}\n\nexport interface TimeFieldContextValue {\n state: TimeFieldState<TimeValue>;\n aria: {\n labelProps: Record<string, unknown>;\n inputProps: Record<string, unknown>;\n descriptionProps: Record<string, unknown>;\n errorMessageProps: Record<string, unknown>;\n };\n}\n\nexport const TimeFieldContext = createContext<TimeFieldContextValue | null>(null);\nexport const TimeFieldStateContext = createContext<TimeFieldState<TimeValue> | null>(null);\n\nfunction withFormValidationBehavior<P extends object>(props: P, formContext: FormProps | null): P {\n if (!formContext?.validationBehavior) {\n return props;\n }\n\n return new Proxy(props, {\n get(target, property, receiver) {\n const localValue = Reflect.get(target, property, receiver);\n if (property === \"validationBehavior\" && localValue === undefined) {\n return formContext.validationBehavior;\n }\n\n return localValue;\n },\n has(target, property) {\n return (\n Reflect.has(target, property) ||\n (property === \"validationBehavior\" && formContext.validationBehavior !== undefined)\n );\n },\n ownKeys(target) {\n const keys = new Set(Reflect.ownKeys(target));\n if (formContext.validationBehavior !== undefined) {\n keys.add(\"validationBehavior\");\n }\n\n return Array.from(keys);\n },\n getOwnPropertyDescriptor(target, property) {\n const descriptor = Reflect.getOwnPropertyDescriptor(target, property);\n if (descriptor) {\n return descriptor;\n }\n\n if (property === \"validationBehavior\" && formContext.validationBehavior !== undefined) {\n return {\n enumerable: true,\n configurable: true,\n get: () => formContext.validationBehavior,\n };\n }\n\n return undefined;\n },\n });\n}\n\nfunction useTimeFieldContextValue(): TimeFieldContextValue {\n const context = useContext(TimeFieldContext);\n if (!context) {\n throw new Error(\"TimeField components must be used within a TimeField\");\n }\n return context;\n}\n\nexport function useTimeFieldContext(): TimeFieldState<TimeValue> {\n return useTimeFieldContextValue().state;\n}\n\n/**\n * A time field allows users to enter and edit time values using a keyboard.\n *\n * @example\n * ```tsx\n * <TimeField label=\"Time\">\n * <Label>Time</Label>\n * <DateInput>\n * {(segment) => <DateSegment segment={segment} />}\n * </DateInput>\n * </TimeField>\n * ```\n */\nexport function TimeField<T extends TimeValue = TimeValue>(props: TimeFieldProps<T>): JSX.Element {\n // Use hydration-safe pattern for client-only rendering\n const isHydrated = useIsHydrated();\n const formContext = useContext(FormContext);\n\n return (\n <Show\n when={isHydrated()}\n fallback={\n <div class=\"solidaria-TimeField solidaria-TimeField--placeholder\" aria-hidden=\"true\" />\n }\n >\n <TimeFieldInner {...props} __formContext={formContext} />\n </Show>\n );\n}\n\ntype TimeFieldInnerProps<T extends TimeValue = TimeValue> = TimeFieldProps<T> & {\n __formContext?: FormProps | null;\n};\n\n/**\n * Internal TimeField component that renders after client mount.\n */\nfunction TimeFieldInner<T extends TimeValue = TimeValue>(\n props: TimeFieldInnerProps<T>,\n): JSX.Element {\n const formContext = props.__formContext ?? useContext(FormContext);\n const mergedProps = withFormValidationBehavior(props, formContext);\n const [local, stateProps, rest] = splitProps(\n mergedProps,\n [\"children\", \"class\", \"style\", \"slot\", \"__formContext\"],\n [\n \"value\",\n \"defaultValue\",\n \"onChange\",\n \"minValue\",\n \"maxValue\",\n \"isInvalid\",\n \"isDisabled\",\n \"isReadOnly\",\n \"isRequired\",\n \"locale\",\n \"granularity\",\n \"hourCycle\",\n \"hideTimeZone\",\n \"shouldForceLeadingZeros\",\n \"validationState\",\n \"validationBehavior\",\n \"validate\",\n \"description\",\n \"errorMessage\",\n \"placeholderValue\",\n ],\n );\n\n const [fieldRef, setFieldRef] = createSignal<HTMLDivElement | null>(null);\n // Ref to the hidden validation <input> (the DateInput's `<Input>` sibling).\n // Mirrors DateField: create it here, hand it to createTimeField below, and\n // attach it to the same input through the DateFieldContext getter.\n const [validationInputRef, setValidationInputRef] =\n createSignal<HTMLInputElement | null>(null);\n\n const state = createTimeFieldState(stateProps);\n\n const fieldAria = createTimeField(\n () => ({\n ...(rest as Record<string, unknown>),\n // RAC threads these props into both useTimeFieldState and useTimeField;\n // they live in `stateProps` here, so forward them for the field hook's\n // aria-disabled and the native validation <input> (type/required).\n isDisabled: access(stateProps.isDisabled),\n isReadOnly: access(stateProps.isReadOnly),\n isRequired: access(stateProps.isRequired),\n // Standalone default flips the hidden input to type=\"text\" so an empty\n // required value blocks HTML form submission (mirrors DateField).\n validationBehavior: stateProps.validationBehavior ?? \"native\",\n description: stateProps.description,\n errorMessage: stateProps.errorMessage,\n inputRef: () => validationInputRef() ?? undefined,\n }),\n state as unknown as TimeFieldState<TimeValue>,\n fieldRef,\n );\n\n const renderValues = createMemo<TimeFieldRenderProps>(() => ({\n isDisabled: state.isDisabled(),\n isReadOnly: state.isReadOnly(),\n isRequired: state.isRequired(),\n isInvalid: state.isInvalid(),\n }));\n\n const renderProps = useRenderProps(\n {\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-TimeField\",\n },\n renderValues,\n );\n\n const textSlots = {\n slots: {\n get description() {\n return fieldAria.descriptionProps;\n },\n get errorMessage() {\n return fieldAria.errorMessageProps;\n },\n },\n };\n\n // The shared context read by the reused DateInput/DateSegment. Read through\n // getters so consumers see the LIVE memo values (createDescription appends the\n // value-description id via a deferred effect; a frozen snapshot would miss it).\n const dateFieldContextValue: DateFieldContextValue = {\n get state() {\n return state as unknown as DateFieldContextValue[\"state\"];\n },\n aria: {\n get labelProps() {\n return fieldAria.labelProps;\n },\n // The segment group props (role=\"group\", aria-labelledby, unicode-bidi\n // isolate, arrow-key nav, focus-within handlers) are routed to the\n // DateInput element; the outer wrapper stays roleless.\n get inputProps() {\n return fieldAria.fieldProps;\n },\n // The native validation <input> props (type/hidden/required/onChange under\n // native validation), rendered as the DateInput's sibling. Thread the\n // validation-input ref so createTimeField's form-reset/validation wiring\n // resolves to the mounted element.\n get hiddenInputProps() {\n return mergeProps(fieldAria.inputProps, { ref: setValidationInputRef });\n },\n get descriptionProps() {\n return fieldAria.descriptionProps;\n },\n get errorMessageProps() {\n return fieldAria.errorMessageProps;\n },\n },\n };\n\n return (\n <TimeFieldStateContext.Provider value={state as unknown as TimeFieldState<TimeValue>}>\n <DateFieldStateContext.Provider\n value={state as unknown as DateFieldContextValue[\"state\"]}\n >\n <DateFieldContext.Provider value={dateFieldContextValue}>\n <TimeFieldContext.Provider\n value={{\n state: state as unknown as TimeFieldState<TimeValue>,\n aria: {\n get labelProps() {\n return fieldAria.labelProps;\n },\n get inputProps() {\n return fieldAria.fieldProps;\n },\n get descriptionProps() {\n return fieldAria.descriptionProps;\n },\n get errorMessageProps() {\n return fieldAria.errorMessageProps;\n },\n },\n }}\n >\n <div\n ref={setFieldRef}\n class={renderProps.class()}\n style={renderProps.style()}\n data-disabled={dataAttr(state.isDisabled())}\n data-readonly={dataAttr(state.isReadOnly())}\n data-required={dataAttr(state.isRequired())}\n data-invalid={dataAttr(state.isInvalid())}\n >\n <Provider values={[[TextContext, textSlots]] as Array<[Context<unknown>, unknown]>}>\n {local.children as JSX.Element}\n </Provider>\n </div>\n {/*\n Unlike DateField, TimeField renders NO root hidden autofill input —\n RAC TimeField renders none (react-aria-components TimeField.mjs). The\n native-validation <input> is emitted by the inner DateInput sibling.\n */}\n </TimeFieldContext.Provider>\n </DateFieldContext.Provider>\n </DateFieldStateContext.Provider>\n </TimeFieldStateContext.Provider>\n );\n}\n\nexport interface TimeFieldLabelProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldLabel(props: TimeFieldLabelProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.labelProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport interface TimeFieldDescriptionProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldDescription(props: TimeFieldDescriptionProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.descriptionProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport interface TimeFieldErrorMessageProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldErrorMessage(props: TimeFieldErrorMessageProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.errorMessageProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport type { TimeFieldState, TimeSegmentType, TimeValue };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TimeField.js","names":["JSX","Context","createContext","createMemo","createSignal","splitProps","useContext","Show","createTimeField","mergeProps","AriaTimeFieldProps","createTimeFieldState","access","TimeFieldState","TimeFieldStateProps","TimeSegment","TimeSegmentType","TimeValue","DateFieldContext","DateFieldStateContext","DateFieldContextValue","ClassNameOrFunction","StyleOrFunction","SlotProps","useRenderProps","dataAttr","useIsHydrated","Provider","TextContext","FormContext","FormProps","TimeFieldRenderProps","isDisabled","isReadOnly","isRequired","isInvalid","TimeFieldProps","Omit","T","children","Element","segment","class","style","locale","TimeFieldContextValue","state","aria","labelProps","Record","inputProps","descriptionProps","errorMessageProps","TimeFieldContext","TimeFieldStateContext","withFormValidationBehavior","props","P","formContext","validationBehavior","Proxy","get","target","property","receiver","localValue","Reflect","undefined","has","ownKeys","keys","Set","add","Array","from","getOwnPropertyDescriptor","descriptor","enumerable","configurable","useTimeFieldContextValue","context","Error","useTimeFieldContext","TimeField","isHydrated","_$createComponent","when","fallback","_$getNextElement","_tmpl$","TimeFieldInner","_$mergeProps","__formContext","TimeFieldInnerProps","mergedProps","local","stateProps","rest","fieldRef","setFieldRef","HTMLDivElement","validationInputRef","setValidationInputRef","HTMLInputElement","fieldAria","description","errorMessage","inputRef","renderValues","renderProps","defaultClassName","textSlots","slots","dateFieldContextValue","fieldProps","hiddenInputProps","ref","value","_el$2","_tmpl$2","_$use","_$insert","values","_$effect","_p$","_v$","_v$2","_v$3","_v$4","_v$5","_v$6","e","_$className","t","_$style","a","_$setAttribute","o","i","n","TimeFieldLabelProps","TimeFieldLabel","_el$3","_tmpl$3","_$spread","_$runHydrationEvents","TimeFieldDescriptionProps","TimeFieldDescription","_el$4","TimeFieldErrorMessageProps","TimeFieldErrorMessage","_el$5"],"sources":["../src/TimeField.tsx"],"sourcesContent":["/**\n * TimeField component for solidaria-components\n *\n * Pre-wired headless time field. Faithful port of react-aria-components'\n * TimeField, which does NOT define its own segment primitives — it reuses\n * `DateInput`/`DateSegment` (there is no `TimeInput`/`TimeSegment` upstream).\n * `TimeFieldState` IS a `DateFieldState` (plus `timeValue`), so this component\n * drives the certified DateField segment/group stack directly: it provides the\n * shared `DateFieldContext`/`DateFieldStateContext` that `DateInput`/`DateSegment`\n * read, plus a `TimeFieldContext` for the time-field label/description/error\n * chrome. Unlike DateField, TimeField renders NO root hidden autofill input (RAC\n * TimeField renders none); its native-validation `<input>` is still emitted by\n * the inner DateInput sibling.\n */\n\nimport {\n type JSX,\n type Context,\n createContext,\n createMemo,\n createSignal,\n splitProps,\n useContext,\n Show,\n} from \"solid-js\";\nimport { createTimeField, mergeProps, type AriaTimeFieldProps } from \"@proyecto-viviana/solidaria\";\nimport {\n createTimeFieldState,\n access,\n type TimeFieldState,\n type TimeFieldStateProps,\n type TimeSegment as TimeSegmentType,\n type TimeValue,\n} from \"@proyecto-viviana/solid-stately\";\nimport { DateFieldContext, DateFieldStateContext, type DateFieldContextValue } from \"./DateField\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n dataAttr,\n useIsHydrated,\n Provider,\n} from \"./utils\";\nimport { TextContext } from \"./Text\";\nimport { FormContext, type FormProps } from \"./Form\";\n\nexport interface TimeFieldRenderProps {\n /** Whether the field is disabled. */\n isDisabled: boolean;\n /** Whether the field is read-only. */\n isReadOnly: boolean;\n /** Whether the field is required. */\n isRequired: boolean;\n /** Whether the field is invalid. */\n isInvalid: boolean;\n}\n\nexport interface TimeFieldProps<T extends TimeValue = TimeValue>\n extends\n Omit<AriaTimeFieldProps, \"id\" | \"isDisabled\" | \"isReadOnly\" | \"isRequired\">,\n Omit<TimeFieldStateProps<T>, \"locale\">,\n SlotProps {\n /** The children of the component. */\n children?: JSX.Element | ((segment: TimeSegmentType) => JSX.Element);\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<TimeFieldRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<TimeFieldRenderProps>;\n /** The locale to use for formatting. */\n locale?: string;\n}\n\nexport interface TimeFieldContextValue {\n state: TimeFieldState<TimeValue>;\n aria: {\n labelProps: Record<string, unknown>;\n inputProps: Record<string, unknown>;\n descriptionProps: Record<string, unknown>;\n errorMessageProps: Record<string, unknown>;\n };\n}\n\nexport const TimeFieldContext = createContext<TimeFieldContextValue | null>(null);\nexport const TimeFieldStateContext = createContext<TimeFieldState<TimeValue> | null>(null);\n\nfunction withFormValidationBehavior<P extends object>(props: P, formContext: FormProps | null): P {\n if (!formContext?.validationBehavior) {\n return props;\n }\n\n return new Proxy(props, {\n get(target, property, receiver) {\n const localValue = Reflect.get(target, property, receiver);\n if (property === \"validationBehavior\" && localValue === undefined) {\n return formContext.validationBehavior;\n }\n\n return localValue;\n },\n has(target, property) {\n return (\n Reflect.has(target, property) ||\n (property === \"validationBehavior\" && formContext.validationBehavior !== undefined)\n );\n },\n ownKeys(target) {\n const keys = new Set(Reflect.ownKeys(target));\n if (formContext.validationBehavior !== undefined) {\n keys.add(\"validationBehavior\");\n }\n\n return Array.from(keys);\n },\n getOwnPropertyDescriptor(target, property) {\n const descriptor = Reflect.getOwnPropertyDescriptor(target, property);\n if (descriptor) {\n return descriptor;\n }\n\n if (property === \"validationBehavior\" && formContext.validationBehavior !== undefined) {\n return {\n enumerable: true,\n configurable: true,\n get: () => formContext.validationBehavior,\n };\n }\n\n return undefined;\n },\n });\n}\n\nfunction useTimeFieldContextValue(): TimeFieldContextValue {\n const context = useContext(TimeFieldContext);\n if (!context) {\n throw new Error(\"TimeField components must be used within a TimeField\");\n }\n return context;\n}\n\nexport function useTimeFieldContext(): TimeFieldState<TimeValue> {\n return useTimeFieldContextValue().state;\n}\n\n/**\n * A time field allows users to enter and edit time values using a keyboard.\n *\n * @example\n * ```tsx\n * <TimeField label=\"Time\">\n * <Label>Time</Label>\n * <DateInput>\n * {(segment) => <DateSegment segment={segment} />}\n * </DateInput>\n * </TimeField>\n * ```\n */\nexport function TimeField<T extends TimeValue = TimeValue>(props: TimeFieldProps<T>): JSX.Element {\n // Use hydration-safe pattern for client-only rendering\n const isHydrated = useIsHydrated();\n const formContext = useContext(FormContext);\n\n return (\n <Show\n when={isHydrated()}\n fallback={\n <div class=\"solidaria-TimeField solidaria-TimeField--placeholder\" aria-hidden=\"true\" />\n }\n >\n <TimeFieldInner {...props} __formContext={formContext} />\n </Show>\n );\n}\n\ntype TimeFieldInnerProps<T extends TimeValue = TimeValue> = TimeFieldProps<T> & {\n __formContext?: FormProps | null;\n};\n\n/**\n * Internal TimeField component that renders after client mount.\n */\nfunction TimeFieldInner<T extends TimeValue = TimeValue>(\n props: TimeFieldInnerProps<T>,\n): JSX.Element {\n const formContext = props.__formContext ?? useContext(FormContext);\n const mergedProps = withFormValidationBehavior(props, formContext);\n const [local, stateProps, rest] = splitProps(\n mergedProps,\n [\"children\", \"class\", \"style\", \"slot\", \"__formContext\"],\n [\n \"value\",\n \"defaultValue\",\n \"onChange\",\n \"minValue\",\n \"maxValue\",\n \"isInvalid\",\n \"isDisabled\",\n \"isReadOnly\",\n \"isRequired\",\n \"locale\",\n \"granularity\",\n \"hourCycle\",\n \"hideTimeZone\",\n \"shouldForceLeadingZeros\",\n \"validationState\",\n \"validationBehavior\",\n \"validate\",\n \"description\",\n \"errorMessage\",\n \"placeholderValue\",\n ],\n );\n\n const [fieldRef, setFieldRef] = createSignal<HTMLDivElement | null>(null);\n // Ref to the hidden validation <input> (the DateInput's `<Input>` sibling).\n // Mirrors DateField: create it here, hand it to createTimeField below, and\n // attach it to the same input through the DateFieldContext getter.\n const [validationInputRef, setValidationInputRef] = createSignal<HTMLInputElement | null>(null);\n\n const state = createTimeFieldState(stateProps);\n\n const fieldAria = createTimeField(\n () => ({\n ...(rest as Record<string, unknown>),\n // RAC threads these props into both useTimeFieldState and useTimeField;\n // they live in `stateProps` here, so forward them for the field hook's\n // aria-disabled and the native validation <input> (type/required).\n isDisabled: access(stateProps.isDisabled),\n isReadOnly: access(stateProps.isReadOnly),\n isRequired: access(stateProps.isRequired),\n // Standalone default flips the hidden input to type=\"text\" so an empty\n // required value blocks HTML form submission (mirrors DateField).\n validationBehavior: stateProps.validationBehavior ?? \"native\",\n description: stateProps.description,\n errorMessage: stateProps.errorMessage,\n inputRef: () => validationInputRef() ?? undefined,\n }),\n state as unknown as TimeFieldState<TimeValue>,\n fieldRef,\n );\n\n const renderValues = createMemo<TimeFieldRenderProps>(() => ({\n isDisabled: state.isDisabled(),\n isReadOnly: state.isReadOnly(),\n isRequired: state.isRequired(),\n isInvalid: state.isInvalid(),\n }));\n\n const renderProps = useRenderProps(\n {\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-TimeField\",\n },\n renderValues,\n );\n\n const textSlots = {\n slots: {\n get description() {\n return fieldAria.descriptionProps;\n },\n get errorMessage() {\n return fieldAria.errorMessageProps;\n },\n },\n };\n\n // The shared context read by the reused DateInput/DateSegment. Read through\n // getters so consumers see the LIVE memo values (createDescription appends the\n // value-description id via a deferred effect; a frozen snapshot would miss it).\n const dateFieldContextValue: DateFieldContextValue = {\n get state() {\n return state as unknown as DateFieldContextValue[\"state\"];\n },\n aria: {\n get labelProps() {\n return fieldAria.labelProps;\n },\n // The segment group props (role=\"group\", aria-labelledby, unicode-bidi\n // isolate, arrow-key nav, focus-within handlers) are routed to the\n // DateInput element; the outer wrapper stays roleless.\n get inputProps() {\n return fieldAria.fieldProps;\n },\n // The native validation <input> props (type/hidden/required/onChange under\n // native validation), rendered as the DateInput's sibling. Thread the\n // validation-input ref so createTimeField's form-reset/validation wiring\n // resolves to the mounted element.\n get hiddenInputProps() {\n return mergeProps(fieldAria.inputProps, { ref: setValidationInputRef });\n },\n get descriptionProps() {\n return fieldAria.descriptionProps;\n },\n get errorMessageProps() {\n return fieldAria.errorMessageProps;\n },\n },\n };\n\n return (\n <TimeFieldStateContext.Provider value={state as unknown as TimeFieldState<TimeValue>}>\n <DateFieldStateContext.Provider value={state as unknown as DateFieldContextValue[\"state\"]}>\n <DateFieldContext.Provider value={dateFieldContextValue}>\n <TimeFieldContext.Provider\n value={{\n state: state as unknown as TimeFieldState<TimeValue>,\n aria: {\n get labelProps() {\n return fieldAria.labelProps;\n },\n get inputProps() {\n return fieldAria.fieldProps;\n },\n get descriptionProps() {\n return fieldAria.descriptionProps;\n },\n get errorMessageProps() {\n return fieldAria.errorMessageProps;\n },\n },\n }}\n >\n <div\n ref={setFieldRef}\n class={renderProps.class()}\n style={renderProps.style()}\n data-disabled={dataAttr(state.isDisabled())}\n data-readonly={dataAttr(state.isReadOnly())}\n data-required={dataAttr(state.isRequired())}\n data-invalid={dataAttr(state.isInvalid())}\n >\n <Provider values={[[TextContext, textSlots]] as Array<[Context<unknown>, unknown]>}>\n {local.children as JSX.Element}\n </Provider>\n </div>\n {/*\n Unlike DateField, TimeField renders NO root hidden autofill input —\n RAC TimeField renders none (react-aria-components TimeField.mjs). The\n native-validation <input> is emitted by the inner DateInput sibling.\n */}\n </TimeFieldContext.Provider>\n </DateFieldContext.Provider>\n </DateFieldStateContext.Provider>\n </TimeFieldStateContext.Provider>\n );\n}\n\nexport interface TimeFieldLabelProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldLabel(props: TimeFieldLabelProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.labelProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport interface TimeFieldDescriptionProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldDescription(props: TimeFieldDescriptionProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.descriptionProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport interface TimeFieldErrorMessageProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldErrorMessage(props: TimeFieldErrorMessageProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.errorMessageProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport type { TimeFieldState, TimeSegmentType, TimeValue };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAmFA,MAAaqD,mBAAmBnD,cAA4C,IAAI;AAChF,MAAaoD,wBAAwBpD,cAAgD,IAAI;AAEzF,SAASqD,2BAA6CC,OAAUE,aAAkC;CAChG,IAAI,CAACA,aAAaC,oBAChB,OAAOH;CAGT,OAAO,IAAII,MAAMJ,OAAO;EACtBK,IAAIC,QAAQC,UAAUC,UAAU;GAC9B,MAAMC,aAAaC,QAAQL,IAAIC,QAAQC,UAAUC,QAAQ;GACzD,IAAID,aAAa,wBAAwBE,eAAeE,KAAAA,GACtD,OAAOT,YAAYC;GAGrB,OAAOM;EACT;EACAG,IAAIN,QAAQC,UAAU;GACpB,OACEG,QAAQE,IAAIN,QAAQC,QAAQ,KAC3BA,aAAa,wBAAwBL,YAAYC,uBAAuBQ,KAAAA;EAE7E;EACAE,QAAQP,QAAQ;GACd,MAAMQ,OAAO,IAAIC,IAAIL,QAAQG,QAAQP,MAAM,CAAC;GAC5C,IAAIJ,YAAYC,uBAAuBQ,KAAAA,GACrCG,KAAKE,IAAI,oBAAoB;GAG/B,OAAOC,MAAMC,KAAKJ,IAAI;EACxB;EACAK,yBAAyBb,QAAQC,UAAU;GACzC,MAAMa,aAAaV,QAAQS,yBAAyBb,QAAQC,QAAQ;GACpE,IAAIa,YACF,OAAOA;GAGT,IAAIb,aAAa,wBAAwBL,YAAYC,uBAAuBQ,KAAAA,GAC1E,OAAO;IACLU,YAAY;IACZC,cAAc;IACdjB,WAAWH,YAAYC;GACzB;EAIJ;CACF,CAAC;AACH;AAEA,SAASoB,2BAAkD;CACzD,MAAMC,UAAU1E,WAAW+C,gBAAgB;CAC3C,IAAI,CAAC2B,SACH,MAAM,IAAIC,MAAM,sDAAsD;CAExE,OAAOD;AACT;AAEA,SAAgBE,sBAAiD;CAC/D,OAAOH,yBAAyB,CAAC,CAACjC;AACpC;;;;;;;;;;;;;;AAeA,SAAgBqC,UAA2C3B,OAAuC;CAEhG,MAAM4B,aAAa1D,cAAc;CACjC,MAAMgC,cAAcpD,WAAWuB,WAAW;CAE1C,OAAAwD,gBACG9E,MAAI;EAAA,IACH+E,OAAI;GAAA,OAAEF,WAAW;EAAC;EAAA,IAClBG,WAAQ;GAAA,OAAAC,eAAAC,MAAA;EAAA;EAAA,IAAAlD,WAAA;GAAA,OAAA8C,gBAIPK,gBAAcC,WAAKnC,OAAK,EAAEoC,eAAelC,YAAW,CAAA,CAAA;EAAA;CAAA,CAAA;AAG3D;;;;AASA,SAASgC,eACPlC,OACa;CAGb,MAAM,CAACuC,OAAOC,YAAYC,QAAQ5F,WADdkD,2BAA2BC,OAD3BA,MAAMoC,iBAAiBtF,WAAWuB,WAAW,CAG/DiE,GACA;EAAC;EAAY;EAAS;EAAS;EAAQ;CAAe,GACtD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAAkB,CAEtB;CAEA,MAAM,CAACI,UAAUC,eAAe/F,aAAoC,IAAI;CAIxE,MAAM,CAACiG,oBAAoBC,yBAAyBlG,aAAsC,IAAI;CAE9F,MAAM0C,QAAQnC,qBAAqBqF,UAAU;CAE7C,MAAMQ,YAAYhG,uBACT;EACL,GAAIyF;EAIJjE,YAAYpB,OAAOoF,WAAWhE,UAAU;EACxCC,YAAYrB,OAAOoF,WAAW/D,UAAU;EACxCC,YAAYtB,OAAOoF,WAAW9D,UAAU;EAGxCyB,oBAAoBqC,WAAWrC,sBAAsB;EACrD8C,aAAaT,WAAWS;EACxBC,cAAcV,WAAWU;EACzBC,gBAAgBN,mBAAmB,KAAKlC,KAAAA;CAC1C,IACArB,OACAoD,QACF;CAEA,MAAMU,eAAezG,kBAAwC;EAC3D6B,YAAYc,MAAMd,WAAW;EAC7BC,YAAYa,MAAMb,WAAW;EAC7BC,YAAYY,MAAMZ,WAAW;EAC7BC,WAAWW,MAAMX,UAAU;CAC7B,EAAE;CAEF,MAAM0E,cAAcrF,eAClB;EACEkB,OAAOqD,MAAMrD;EACbC,OAAOoD,MAAMpD;EACbmE,kBAAkB;CACpB,GACAF,YACF;CAEA,MAAMG,YAAY,EAChBC,OAAO;EACL,IAAIP,cAAc;GAChB,OAAOD,UAAUrD;EACnB;EACA,IAAIuD,eAAe;GACjB,OAAOF,UAAUpD;EACnB;CACF,EACF;CAKA,MAAM6D,wBAA+C;EACnD,IAAInE,QAAQ;GACV,OAAOA;EACT;EACAC,MAAM;GACJ,IAAIC,aAAa;IACf,OAAOwD,UAAUxD;GACnB;GAIA,IAAIE,aAAa;IACf,OAAOsD,UAAUU;GACnB;GAKA,IAAIC,mBAAmB;IACrB,OAAO1G,aAAW+F,UAAUtD,YAAY,EAAEkE,KAAKd,sBAAsB,CAAC;GACxE;GACA,IAAInD,mBAAmB;IACrB,OAAOqD,UAAUrD;GACnB;GACA,IAAIC,oBAAoB;IACtB,OAAOoD,UAAUpD;GACnB;EACF;CACF;CAEA,OAAAiC,gBACG/B,sBAAsB3B,UAAQ;EAAC0F,OAAOvE;EAA6C,IAAAP,WAAA;GAAA,OAAA8C,gBACjFlE,sBAAsBQ,UAAQ;IAAC0F,OAAOvE;IAAkD,IAAAP,WAAA;KAAA,OAAA8C,gBACtFnE,iBAAiBS,UAAQ;MAAC0F,OAAOJ;MAAqB,IAAA1E,WAAA;OAAA,OAAA8C,gBACpDhC,iBAAiB1B,UAAQ;QACxB0F,OAAO;SACEvE;SACPC,MAAM;UACJ,IAAIC,aAAa;WACf,OAAOwD,UAAUxD;UACnB;UACA,IAAIE,aAAa;WACf,OAAOsD,UAAUU;UACnB;UACA,IAAI/D,mBAAmB;WACrB,OAAOqD,UAAUrD;UACnB;UACA,IAAIC,oBAAoB;WACtB,OAAOoD,UAAUpD;UACnB;SACF;QACF;QAAC,IAAAb,WAAA;SAAA,IAAA+E,QAAA9B,eAAA+B,OAAA;SAAAC,IAGMrB,aAAWmB,KAAA;SAAAG,OAAAH,OAAAjC,gBAQf1D,UAAQ;UAAC+F,QAAQ,CAAC,CAAC9F,aAAamF,SAAS,CAAC;UAAuC,IAAAxE,WAAA;WAAA,OAC/EwD,MAAMxD;UAAuB;SAAA,CAAA,CAAA;SAAAoF,QAAAC,QAAA;UAAA,IAAAC,MARzBhB,YAAYnE,MAAM,GAACoF,OACnBjB,YAAYlE,MAAM,GAACoF,OACXtG,SAASqB,MAAMd,WAAW,CAAC,GAACgG,OAC5BvG,SAASqB,MAAMb,WAAW,CAAC,GAACgG,OAC5BxG,SAASqB,MAAMZ,WAAW,CAAC,GAACgG,OAC7BzG,SAASqB,MAAMX,UAAU,CAAC;UAAC0F,QAAAD,IAAAO,KAAAC,UAAAd,OAAAM,IAAAO,IAAAN,GAAA;UAAAD,IAAAS,IAAAC,MAAAhB,OAAAQ,MAAAF,IAAAS,CAAA;UAAAN,SAAAH,IAAAW,KAAAC,aAAAlB,OAAA,iBAAAM,IAAAW,IAAAR,IAAA;UAAAC,SAAAJ,IAAAa,KAAAD,aAAAlB,OAAA,iBAAAM,IAAAa,IAAAT,IAAA;UAAAC,SAAAL,IAAAc,KAAAF,aAAAlB,OAAA,iBAAAM,IAAAc,IAAAT,IAAA;UAAAC,SAAAN,IAAAe,KAAAH,aAAAlB,OAAA,gBAAAM,IAAAe,IAAAT,IAAA;UAAA,OAAAN;SAAA,GAAA;UAAAO,GAAAhE,KAAAA;UAAAkE,GAAAlE,KAAAA;UAAAoE,GAAApE,KAAAA;UAAAsE,GAAAtE,KAAAA;UAAAuE,GAAAvE,KAAAA;UAAAwE,GAAAxE,KAAAA;SAAA,CAAA;SAAA,OAAAmD;QAAA;OAAA,CAAA;MAAA;KAAA,CAAA;IAAA;GAAA,CAAA;EAAA;CAAA,CAAA;AAgBvD;AAOA,SAAgBuB,eAAerF,OAAyC;CACtE,MAAM,EAAET,SAASgC,yBAAyB;CAC1C,cAAA;EAAA,IAAA+D,QAAAtD,eAAAuD,OAAA;EAAAC,OAAAF,OAAAnD,iBACY5C,KAAKC,YAAU,EAAA,KAAA,WAAA;GAAA,OAASQ,MAAMd;EAAK,EAAA,CAAA,GAAA,OAAA,IAAA;EAAA+E,OAAAqB,aAC1CtF,MAAMjB,QAAQ;EAAA0G,mBAAA;EAAA,OAAAH;CAAA,EAAA,CAAA;AAGrB;AAOA,SAAgBK,qBAAqB3F,OAA+C;CAClF,MAAM,EAAET,SAASgC,yBAAyB;CAC1C,cAAA;EAAA,IAAAqE,QAAA5D,eAAAuD,OAAA;EAAAC,OAAAI,OAAAzD,iBACY5C,KAAKI,kBAAgB,EAAA,KAAA,WAAA;GAAA,OAASK,MAAMd;EAAK,EAAA,CAAA,GAAA,OAAA,IAAA;EAAA+E,OAAA2B,aAChD5F,MAAMjB,QAAQ;EAAA0G,mBAAA;EAAA,OAAAG;CAAA,EAAA,CAAA;AAGrB;AAOA,SAAgBE,sBAAsB9F,OAAgD;CACpF,MAAM,EAAET,SAASgC,yBAAyB;CAC1C,cAAA;EAAA,IAAAwE,QAAA/D,eAAAuD,OAAA;EAAAC,OAAAO,OAAA5D,iBACY5C,KAAKK,mBAAiB,EAAA,KAAA,WAAA;GAAA,OAASI,MAAMd;EAAK,EAAA,CAAA,GAAA,OAAA,IAAA;EAAA+E,OAAA8B,aACjD/F,MAAMjB,QAAQ;EAAA0G,mBAAA;EAAA,OAAAM;CAAA,EAAA,CAAA;AAGrB"}
|
package/dist/TimeField.jsx.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeField.jsx","names":["mergeProps"],"sources":["../src/TimeField.tsx"],"sourcesContent":["/**\n * TimeField component for solidaria-components\n *\n * Pre-wired headless time field. Faithful port of react-aria-components'\n * TimeField, which does NOT define its own segment primitives — it reuses\n * `DateInput`/`DateSegment` (there is no `TimeInput`/`TimeSegment` upstream).\n * `TimeFieldState` IS a `DateFieldState` (plus `timeValue`), so this component\n * drives the certified DateField segment/group stack directly: it provides the\n * shared `DateFieldContext`/`DateFieldStateContext` that `DateInput`/`DateSegment`\n * read, plus a `TimeFieldContext` for the time-field label/description/error\n * chrome. Unlike DateField, TimeField renders NO root hidden autofill input (RAC\n * TimeField renders none); its native-validation `<input>` is still emitted by\n * the inner DateInput sibling.\n */\n\nimport {\n type JSX,\n type Context,\n createContext,\n createMemo,\n createSignal,\n splitProps,\n useContext,\n Show,\n} from \"solid-js\";\nimport { createTimeField, mergeProps, type AriaTimeFieldProps } from \"@proyecto-viviana/solidaria\";\nimport {\n createTimeFieldState,\n access,\n type TimeFieldState,\n type TimeFieldStateProps,\n type TimeSegment as TimeSegmentType,\n type TimeValue,\n} from \"@proyecto-viviana/solid-stately\";\nimport {\n DateFieldContext,\n DateFieldStateContext,\n type DateFieldContextValue,\n} from \"./DateField\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n dataAttr,\n useIsHydrated,\n Provider,\n} from \"./utils\";\nimport { TextContext } from \"./Text\";\nimport { FormContext, type FormProps } from \"./Form\";\n\nexport interface TimeFieldRenderProps {\n /** Whether the field is disabled. */\n isDisabled: boolean;\n /** Whether the field is read-only. */\n isReadOnly: boolean;\n /** Whether the field is required. */\n isRequired: boolean;\n /** Whether the field is invalid. */\n isInvalid: boolean;\n}\n\nexport interface TimeFieldProps<T extends TimeValue = TimeValue>\n extends\n Omit<AriaTimeFieldProps, \"id\" | \"isDisabled\" | \"isReadOnly\" | \"isRequired\">,\n Omit<TimeFieldStateProps<T>, \"locale\">,\n SlotProps {\n /** The children of the component. */\n children?: JSX.Element | ((segment: TimeSegmentType) => JSX.Element);\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<TimeFieldRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<TimeFieldRenderProps>;\n /** The locale to use for formatting. */\n locale?: string;\n}\n\nexport interface TimeFieldContextValue {\n state: TimeFieldState<TimeValue>;\n aria: {\n labelProps: Record<string, unknown>;\n inputProps: Record<string, unknown>;\n descriptionProps: Record<string, unknown>;\n errorMessageProps: Record<string, unknown>;\n };\n}\n\nexport const TimeFieldContext = createContext<TimeFieldContextValue | null>(null);\nexport const TimeFieldStateContext = createContext<TimeFieldState<TimeValue> | null>(null);\n\nfunction withFormValidationBehavior<P extends object>(props: P, formContext: FormProps | null): P {\n if (!formContext?.validationBehavior) {\n return props;\n }\n\n return new Proxy(props, {\n get(target, property, receiver) {\n const localValue = Reflect.get(target, property, receiver);\n if (property === \"validationBehavior\" && localValue === undefined) {\n return formContext.validationBehavior;\n }\n\n return localValue;\n },\n has(target, property) {\n return (\n Reflect.has(target, property) ||\n (property === \"validationBehavior\" && formContext.validationBehavior !== undefined)\n );\n },\n ownKeys(target) {\n const keys = new Set(Reflect.ownKeys(target));\n if (formContext.validationBehavior !== undefined) {\n keys.add(\"validationBehavior\");\n }\n\n return Array.from(keys);\n },\n getOwnPropertyDescriptor(target, property) {\n const descriptor = Reflect.getOwnPropertyDescriptor(target, property);\n if (descriptor) {\n return descriptor;\n }\n\n if (property === \"validationBehavior\" && formContext.validationBehavior !== undefined) {\n return {\n enumerable: true,\n configurable: true,\n get: () => formContext.validationBehavior,\n };\n }\n\n return undefined;\n },\n });\n}\n\nfunction useTimeFieldContextValue(): TimeFieldContextValue {\n const context = useContext(TimeFieldContext);\n if (!context) {\n throw new Error(\"TimeField components must be used within a TimeField\");\n }\n return context;\n}\n\nexport function useTimeFieldContext(): TimeFieldState<TimeValue> {\n return useTimeFieldContextValue().state;\n}\n\n/**\n * A time field allows users to enter and edit time values using a keyboard.\n *\n * @example\n * ```tsx\n * <TimeField label=\"Time\">\n * <Label>Time</Label>\n * <DateInput>\n * {(segment) => <DateSegment segment={segment} />}\n * </DateInput>\n * </TimeField>\n * ```\n */\nexport function TimeField<T extends TimeValue = TimeValue>(props: TimeFieldProps<T>): JSX.Element {\n // Use hydration-safe pattern for client-only rendering\n const isHydrated = useIsHydrated();\n const formContext = useContext(FormContext);\n\n return (\n <Show\n when={isHydrated()}\n fallback={\n <div class=\"solidaria-TimeField solidaria-TimeField--placeholder\" aria-hidden=\"true\" />\n }\n >\n <TimeFieldInner {...props} __formContext={formContext} />\n </Show>\n );\n}\n\ntype TimeFieldInnerProps<T extends TimeValue = TimeValue> = TimeFieldProps<T> & {\n __formContext?: FormProps | null;\n};\n\n/**\n * Internal TimeField component that renders after client mount.\n */\nfunction TimeFieldInner<T extends TimeValue = TimeValue>(\n props: TimeFieldInnerProps<T>,\n): JSX.Element {\n const formContext = props.__formContext ?? useContext(FormContext);\n const mergedProps = withFormValidationBehavior(props, formContext);\n const [local, stateProps, rest] = splitProps(\n mergedProps,\n [\"children\", \"class\", \"style\", \"slot\", \"__formContext\"],\n [\n \"value\",\n \"defaultValue\",\n \"onChange\",\n \"minValue\",\n \"maxValue\",\n \"isInvalid\",\n \"isDisabled\",\n \"isReadOnly\",\n \"isRequired\",\n \"locale\",\n \"granularity\",\n \"hourCycle\",\n \"hideTimeZone\",\n \"shouldForceLeadingZeros\",\n \"validationState\",\n \"validationBehavior\",\n \"validate\",\n \"description\",\n \"errorMessage\",\n \"placeholderValue\",\n ],\n );\n\n const [fieldRef, setFieldRef] = createSignal<HTMLDivElement | null>(null);\n // Ref to the hidden validation <input> (the DateInput's `<Input>` sibling).\n // Mirrors DateField: create it here, hand it to createTimeField below, and\n // attach it to the same input through the DateFieldContext getter.\n const [validationInputRef, setValidationInputRef] =\n createSignal<HTMLInputElement | null>(null);\n\n const state = createTimeFieldState(stateProps);\n\n const fieldAria = createTimeField(\n () => ({\n ...(rest as Record<string, unknown>),\n // RAC threads these props into both useTimeFieldState and useTimeField;\n // they live in `stateProps` here, so forward them for the field hook's\n // aria-disabled and the native validation <input> (type/required).\n isDisabled: access(stateProps.isDisabled),\n isReadOnly: access(stateProps.isReadOnly),\n isRequired: access(stateProps.isRequired),\n // Standalone default flips the hidden input to type=\"text\" so an empty\n // required value blocks HTML form submission (mirrors DateField).\n validationBehavior: stateProps.validationBehavior ?? \"native\",\n description: stateProps.description,\n errorMessage: stateProps.errorMessage,\n inputRef: () => validationInputRef() ?? undefined,\n }),\n state as unknown as TimeFieldState<TimeValue>,\n fieldRef,\n );\n\n const renderValues = createMemo<TimeFieldRenderProps>(() => ({\n isDisabled: state.isDisabled(),\n isReadOnly: state.isReadOnly(),\n isRequired: state.isRequired(),\n isInvalid: state.isInvalid(),\n }));\n\n const renderProps = useRenderProps(\n {\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-TimeField\",\n },\n renderValues,\n );\n\n const textSlots = {\n slots: {\n get description() {\n return fieldAria.descriptionProps;\n },\n get errorMessage() {\n return fieldAria.errorMessageProps;\n },\n },\n };\n\n // The shared context read by the reused DateInput/DateSegment. Read through\n // getters so consumers see the LIVE memo values (createDescription appends the\n // value-description id via a deferred effect; a frozen snapshot would miss it).\n const dateFieldContextValue: DateFieldContextValue = {\n get state() {\n return state as unknown as DateFieldContextValue[\"state\"];\n },\n aria: {\n get labelProps() {\n return fieldAria.labelProps;\n },\n // The segment group props (role=\"group\", aria-labelledby, unicode-bidi\n // isolate, arrow-key nav, focus-within handlers) are routed to the\n // DateInput element; the outer wrapper stays roleless.\n get inputProps() {\n return fieldAria.fieldProps;\n },\n // The native validation <input> props (type/hidden/required/onChange under\n // native validation), rendered as the DateInput's sibling. Thread the\n // validation-input ref so createTimeField's form-reset/validation wiring\n // resolves to the mounted element.\n get hiddenInputProps() {\n return mergeProps(fieldAria.inputProps, { ref: setValidationInputRef });\n },\n get descriptionProps() {\n return fieldAria.descriptionProps;\n },\n get errorMessageProps() {\n return fieldAria.errorMessageProps;\n },\n },\n };\n\n return (\n <TimeFieldStateContext.Provider value={state as unknown as TimeFieldState<TimeValue>}>\n <DateFieldStateContext.Provider\n value={state as unknown as DateFieldContextValue[\"state\"]}\n >\n <DateFieldContext.Provider value={dateFieldContextValue}>\n <TimeFieldContext.Provider\n value={{\n state: state as unknown as TimeFieldState<TimeValue>,\n aria: {\n get labelProps() {\n return fieldAria.labelProps;\n },\n get inputProps() {\n return fieldAria.fieldProps;\n },\n get descriptionProps() {\n return fieldAria.descriptionProps;\n },\n get errorMessageProps() {\n return fieldAria.errorMessageProps;\n },\n },\n }}\n >\n <div\n ref={setFieldRef}\n class={renderProps.class()}\n style={renderProps.style()}\n data-disabled={dataAttr(state.isDisabled())}\n data-readonly={dataAttr(state.isReadOnly())}\n data-required={dataAttr(state.isRequired())}\n data-invalid={dataAttr(state.isInvalid())}\n >\n <Provider values={[[TextContext, textSlots]] as Array<[Context<unknown>, unknown]>}>\n {local.children as JSX.Element}\n </Provider>\n </div>\n {/*\n Unlike DateField, TimeField renders NO root hidden autofill input —\n RAC TimeField renders none (react-aria-components TimeField.mjs). The\n native-validation <input> is emitted by the inner DateInput sibling.\n */}\n </TimeFieldContext.Provider>\n </DateFieldContext.Provider>\n </DateFieldStateContext.Provider>\n </TimeFieldStateContext.Provider>\n );\n}\n\nexport interface TimeFieldLabelProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldLabel(props: TimeFieldLabelProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.labelProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport interface TimeFieldDescriptionProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldDescription(props: TimeFieldDescriptionProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.descriptionProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport interface TimeFieldErrorMessageProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldErrorMessage(props: TimeFieldErrorMessageProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.errorMessageProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport type { TimeFieldState, TimeSegmentType, TimeValue };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TimeField.jsx","names":["mergeProps"],"sources":["../src/TimeField.tsx"],"sourcesContent":["/**\n * TimeField component for solidaria-components\n *\n * Pre-wired headless time field. Faithful port of react-aria-components'\n * TimeField, which does NOT define its own segment primitives — it reuses\n * `DateInput`/`DateSegment` (there is no `TimeInput`/`TimeSegment` upstream).\n * `TimeFieldState` IS a `DateFieldState` (plus `timeValue`), so this component\n * drives the certified DateField segment/group stack directly: it provides the\n * shared `DateFieldContext`/`DateFieldStateContext` that `DateInput`/`DateSegment`\n * read, plus a `TimeFieldContext` for the time-field label/description/error\n * chrome. Unlike DateField, TimeField renders NO root hidden autofill input (RAC\n * TimeField renders none); its native-validation `<input>` is still emitted by\n * the inner DateInput sibling.\n */\n\nimport {\n type JSX,\n type Context,\n createContext,\n createMemo,\n createSignal,\n splitProps,\n useContext,\n Show,\n} from \"solid-js\";\nimport { createTimeField, mergeProps, type AriaTimeFieldProps } from \"@proyecto-viviana/solidaria\";\nimport {\n createTimeFieldState,\n access,\n type TimeFieldState,\n type TimeFieldStateProps,\n type TimeSegment as TimeSegmentType,\n type TimeValue,\n} from \"@proyecto-viviana/solid-stately\";\nimport { DateFieldContext, DateFieldStateContext, type DateFieldContextValue } from \"./DateField\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n dataAttr,\n useIsHydrated,\n Provider,\n} from \"./utils\";\nimport { TextContext } from \"./Text\";\nimport { FormContext, type FormProps } from \"./Form\";\n\nexport interface TimeFieldRenderProps {\n /** Whether the field is disabled. */\n isDisabled: boolean;\n /** Whether the field is read-only. */\n isReadOnly: boolean;\n /** Whether the field is required. */\n isRequired: boolean;\n /** Whether the field is invalid. */\n isInvalid: boolean;\n}\n\nexport interface TimeFieldProps<T extends TimeValue = TimeValue>\n extends\n Omit<AriaTimeFieldProps, \"id\" | \"isDisabled\" | \"isReadOnly\" | \"isRequired\">,\n Omit<TimeFieldStateProps<T>, \"locale\">,\n SlotProps {\n /** The children of the component. */\n children?: JSX.Element | ((segment: TimeSegmentType) => JSX.Element);\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<TimeFieldRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<TimeFieldRenderProps>;\n /** The locale to use for formatting. */\n locale?: string;\n}\n\nexport interface TimeFieldContextValue {\n state: TimeFieldState<TimeValue>;\n aria: {\n labelProps: Record<string, unknown>;\n inputProps: Record<string, unknown>;\n descriptionProps: Record<string, unknown>;\n errorMessageProps: Record<string, unknown>;\n };\n}\n\nexport const TimeFieldContext = createContext<TimeFieldContextValue | null>(null);\nexport const TimeFieldStateContext = createContext<TimeFieldState<TimeValue> | null>(null);\n\nfunction withFormValidationBehavior<P extends object>(props: P, formContext: FormProps | null): P {\n if (!formContext?.validationBehavior) {\n return props;\n }\n\n return new Proxy(props, {\n get(target, property, receiver) {\n const localValue = Reflect.get(target, property, receiver);\n if (property === \"validationBehavior\" && localValue === undefined) {\n return formContext.validationBehavior;\n }\n\n return localValue;\n },\n has(target, property) {\n return (\n Reflect.has(target, property) ||\n (property === \"validationBehavior\" && formContext.validationBehavior !== undefined)\n );\n },\n ownKeys(target) {\n const keys = new Set(Reflect.ownKeys(target));\n if (formContext.validationBehavior !== undefined) {\n keys.add(\"validationBehavior\");\n }\n\n return Array.from(keys);\n },\n getOwnPropertyDescriptor(target, property) {\n const descriptor = Reflect.getOwnPropertyDescriptor(target, property);\n if (descriptor) {\n return descriptor;\n }\n\n if (property === \"validationBehavior\" && formContext.validationBehavior !== undefined) {\n return {\n enumerable: true,\n configurable: true,\n get: () => formContext.validationBehavior,\n };\n }\n\n return undefined;\n },\n });\n}\n\nfunction useTimeFieldContextValue(): TimeFieldContextValue {\n const context = useContext(TimeFieldContext);\n if (!context) {\n throw new Error(\"TimeField components must be used within a TimeField\");\n }\n return context;\n}\n\nexport function useTimeFieldContext(): TimeFieldState<TimeValue> {\n return useTimeFieldContextValue().state;\n}\n\n/**\n * A time field allows users to enter and edit time values using a keyboard.\n *\n * @example\n * ```tsx\n * <TimeField label=\"Time\">\n * <Label>Time</Label>\n * <DateInput>\n * {(segment) => <DateSegment segment={segment} />}\n * </DateInput>\n * </TimeField>\n * ```\n */\nexport function TimeField<T extends TimeValue = TimeValue>(props: TimeFieldProps<T>): JSX.Element {\n // Use hydration-safe pattern for client-only rendering\n const isHydrated = useIsHydrated();\n const formContext = useContext(FormContext);\n\n return (\n <Show\n when={isHydrated()}\n fallback={\n <div class=\"solidaria-TimeField solidaria-TimeField--placeholder\" aria-hidden=\"true\" />\n }\n >\n <TimeFieldInner {...props} __formContext={formContext} />\n </Show>\n );\n}\n\ntype TimeFieldInnerProps<T extends TimeValue = TimeValue> = TimeFieldProps<T> & {\n __formContext?: FormProps | null;\n};\n\n/**\n * Internal TimeField component that renders after client mount.\n */\nfunction TimeFieldInner<T extends TimeValue = TimeValue>(\n props: TimeFieldInnerProps<T>,\n): JSX.Element {\n const formContext = props.__formContext ?? useContext(FormContext);\n const mergedProps = withFormValidationBehavior(props, formContext);\n const [local, stateProps, rest] = splitProps(\n mergedProps,\n [\"children\", \"class\", \"style\", \"slot\", \"__formContext\"],\n [\n \"value\",\n \"defaultValue\",\n \"onChange\",\n \"minValue\",\n \"maxValue\",\n \"isInvalid\",\n \"isDisabled\",\n \"isReadOnly\",\n \"isRequired\",\n \"locale\",\n \"granularity\",\n \"hourCycle\",\n \"hideTimeZone\",\n \"shouldForceLeadingZeros\",\n \"validationState\",\n \"validationBehavior\",\n \"validate\",\n \"description\",\n \"errorMessage\",\n \"placeholderValue\",\n ],\n );\n\n const [fieldRef, setFieldRef] = createSignal<HTMLDivElement | null>(null);\n // Ref to the hidden validation <input> (the DateInput's `<Input>` sibling).\n // Mirrors DateField: create it here, hand it to createTimeField below, and\n // attach it to the same input through the DateFieldContext getter.\n const [validationInputRef, setValidationInputRef] = createSignal<HTMLInputElement | null>(null);\n\n const state = createTimeFieldState(stateProps);\n\n const fieldAria = createTimeField(\n () => ({\n ...(rest as Record<string, unknown>),\n // RAC threads these props into both useTimeFieldState and useTimeField;\n // they live in `stateProps` here, so forward them for the field hook's\n // aria-disabled and the native validation <input> (type/required).\n isDisabled: access(stateProps.isDisabled),\n isReadOnly: access(stateProps.isReadOnly),\n isRequired: access(stateProps.isRequired),\n // Standalone default flips the hidden input to type=\"text\" so an empty\n // required value blocks HTML form submission (mirrors DateField).\n validationBehavior: stateProps.validationBehavior ?? \"native\",\n description: stateProps.description,\n errorMessage: stateProps.errorMessage,\n inputRef: () => validationInputRef() ?? undefined,\n }),\n state as unknown as TimeFieldState<TimeValue>,\n fieldRef,\n );\n\n const renderValues = createMemo<TimeFieldRenderProps>(() => ({\n isDisabled: state.isDisabled(),\n isReadOnly: state.isReadOnly(),\n isRequired: state.isRequired(),\n isInvalid: state.isInvalid(),\n }));\n\n const renderProps = useRenderProps(\n {\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-TimeField\",\n },\n renderValues,\n );\n\n const textSlots = {\n slots: {\n get description() {\n return fieldAria.descriptionProps;\n },\n get errorMessage() {\n return fieldAria.errorMessageProps;\n },\n },\n };\n\n // The shared context read by the reused DateInput/DateSegment. Read through\n // getters so consumers see the LIVE memo values (createDescription appends the\n // value-description id via a deferred effect; a frozen snapshot would miss it).\n const dateFieldContextValue: DateFieldContextValue = {\n get state() {\n return state as unknown as DateFieldContextValue[\"state\"];\n },\n aria: {\n get labelProps() {\n return fieldAria.labelProps;\n },\n // The segment group props (role=\"group\", aria-labelledby, unicode-bidi\n // isolate, arrow-key nav, focus-within handlers) are routed to the\n // DateInput element; the outer wrapper stays roleless.\n get inputProps() {\n return fieldAria.fieldProps;\n },\n // The native validation <input> props (type/hidden/required/onChange under\n // native validation), rendered as the DateInput's sibling. Thread the\n // validation-input ref so createTimeField's form-reset/validation wiring\n // resolves to the mounted element.\n get hiddenInputProps() {\n return mergeProps(fieldAria.inputProps, { ref: setValidationInputRef });\n },\n get descriptionProps() {\n return fieldAria.descriptionProps;\n },\n get errorMessageProps() {\n return fieldAria.errorMessageProps;\n },\n },\n };\n\n return (\n <TimeFieldStateContext.Provider value={state as unknown as TimeFieldState<TimeValue>}>\n <DateFieldStateContext.Provider value={state as unknown as DateFieldContextValue[\"state\"]}>\n <DateFieldContext.Provider value={dateFieldContextValue}>\n <TimeFieldContext.Provider\n value={{\n state: state as unknown as TimeFieldState<TimeValue>,\n aria: {\n get labelProps() {\n return fieldAria.labelProps;\n },\n get inputProps() {\n return fieldAria.fieldProps;\n },\n get descriptionProps() {\n return fieldAria.descriptionProps;\n },\n get errorMessageProps() {\n return fieldAria.errorMessageProps;\n },\n },\n }}\n >\n <div\n ref={setFieldRef}\n class={renderProps.class()}\n style={renderProps.style()}\n data-disabled={dataAttr(state.isDisabled())}\n data-readonly={dataAttr(state.isReadOnly())}\n data-required={dataAttr(state.isRequired())}\n data-invalid={dataAttr(state.isInvalid())}\n >\n <Provider values={[[TextContext, textSlots]] as Array<[Context<unknown>, unknown]>}>\n {local.children as JSX.Element}\n </Provider>\n </div>\n {/*\n Unlike DateField, TimeField renders NO root hidden autofill input —\n RAC TimeField renders none (react-aria-components TimeField.mjs). The\n native-validation <input> is emitted by the inner DateInput sibling.\n */}\n </TimeFieldContext.Provider>\n </DateFieldContext.Provider>\n </DateFieldStateContext.Provider>\n </TimeFieldStateContext.Provider>\n );\n}\n\nexport interface TimeFieldLabelProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldLabel(props: TimeFieldLabelProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.labelProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport interface TimeFieldDescriptionProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldDescription(props: TimeFieldDescriptionProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.descriptionProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport interface TimeFieldErrorMessageProps {\n children?: JSX.Element;\n class?: string;\n}\n\nexport function TimeFieldErrorMessage(props: TimeFieldErrorMessageProps): JSX.Element {\n const { aria } = useTimeFieldContextValue();\n return (\n <span {...aria.errorMessageProps} class={props.class}>\n {props.children}\n </span>\n );\n}\n\nexport type { TimeFieldState, TimeSegmentType, TimeValue };\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proyecto-viviana/solidaria-components",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Pre-wired headless components for SolidJS - port of react-aria-components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
"solid",
|
|
11
11
|
"solidjs"
|
|
12
12
|
],
|
|
13
|
+
"homepage": "https://ui.proyectoviviana.org/solid-spectrum/ecosystem",
|
|
14
|
+
"bugs": "https://github.com/proyecto-viviana/ui/issues",
|
|
13
15
|
"license": "MIT",
|
|
14
16
|
"repository": {
|
|
15
17
|
"type": "git",
|
|
@@ -429,8 +431,8 @@
|
|
|
429
431
|
},
|
|
430
432
|
"dependencies": {
|
|
431
433
|
"@internationalized/date": "^3.8.0",
|
|
432
|
-
"@proyecto-viviana/solid-stately": "0.5.
|
|
433
|
-
"@proyecto-viviana/solidaria": "0.4.
|
|
434
|
+
"@proyecto-viviana/solid-stately": "0.5.1",
|
|
435
|
+
"@proyecto-viviana/solidaria": "0.4.3"
|
|
434
436
|
},
|
|
435
437
|
"devDependencies": {
|
|
436
438
|
"solid-js": "^1.9.11"
|