@spark-ui/components 17.5.6-beta.0 → 17.5.6-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../input-DaShg4eE.js`);exports.Input=e.n,exports.InputGroup=e.t,exports.useInputGroup=e.r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../input-Cx5cfgE8.js`);exports.Input=e.n,exports.InputGroup=e.t,exports.useInputGroup=e.i;
@@ -1,2 +1,2 @@
1
- import { n as e, r as t, t as n } from "../input-Dtabf6Mp.mjs";
2
- export { e as Input, n as InputGroup, t as useInputGroup };
1
+ import { i as e, n as t, t as n } from "../input-BIuBpTEq.mjs";
2
+ export { t as Input, n as InputGroup, e as useInputGroup };
@@ -350,6 +350,6 @@ var L = Object.assign(w, {
350
350
  });
351
351
  L.displayName = "InputGroup", O.displayName = "InputGroup.LeadingAddon", M.displayName = "InputGroup.TrailingAddon", A.displayName = "InputGroup.LeadingIcon", N.displayName = "InputGroup.TrailingIcon", S.displayName = "InputGroup.ClearButton";
352
352
  //#endregion
353
- export { I as n, b as r, L as t };
353
+ export { b as i, I as n, C as r, L as t };
354
354
 
355
- //# sourceMappingURL=input-Dtabf6Mp.mjs.map
355
+ //# sourceMappingURL=input-BIuBpTEq.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"input-Dtabf6Mp.mjs","names":[],"sources":["../src/input/InputGroupContext.ts","../src/input/InputClearButton.tsx","../src/input/InputGroup.styles.ts","../src/input/InputGroup.tsx","../src/input/InputAddon.styles.ts","../src/input/InputAddon.tsx","../src/input/InputLeadingAddon.tsx","../src/input/InputIcon.tsx","../src/input/InputLeadingIcon.tsx","../src/input/InputTrailingAddon.tsx","../src/input/InputTrailingIcon.tsx","../src/input/Input.styles.ts","../src/input/Input.tsx","../src/input/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface InputGroupContextValue {\n disabled?: boolean\n readOnly?: boolean\n hasLeadingIcon: boolean\n hasTrailingIcon: boolean\n hasLeadingAddon: boolean\n hasTrailingAddon: boolean\n hasClearButton: boolean\n state: null | undefined | 'error' | 'alert' | 'success'\n isStandalone?: boolean\n onClear: () => void\n}\n\nexport const InputGroupContext = createContext<Partial<InputGroupContextValue> | null>(null)\n\nexport const useInputGroup = () => {\n const context = useContext(InputGroupContext)\n\n return context || { isStandalone: true }\n}\n","import { DeleteOutline } from '@spark-ui/icons/DeleteOutline'\nimport { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, MouseEventHandler, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport interface InputClearButtonProps extends ComponentPropsWithoutRef<'button'> {\n 'aria-label': string\n inline?: boolean\n ref?: Ref<HTMLButtonElement>\n}\n\nconst Root = ({\n className,\n tabIndex = -1,\n onClick,\n inline = false,\n ref,\n ...others\n}: InputClearButtonProps) => {\n const { onClear, hasTrailingIcon } = useInputGroup()\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = event => {\n if (onClick) {\n onClick(event)\n }\n\n if (onClear) {\n onClear()\n }\n }\n\n return (\n <button\n ref={ref}\n data-spark-component=\"input-clear-button\"\n className={cx(\n className,\n 'pointer-events-auto absolute',\n inline ? 'h-sz-44 top-0 -translate-y-0' : 'top-1/2 -translate-y-1/2',\n 'inline-flex h-full items-center justify-center outline-hidden',\n 'text-neutral hover:text-neutral-hovered',\n hasTrailingIcon ? 'right-3xl px-sz-12' : 'pl-md pr-lg right-0'\n )}\n tabIndex={tabIndex}\n onClick={handleClick}\n type=\"button\"\n {...others}\n >\n <Icon size=\"sm\">\n <DeleteOutline />\n </Icon>\n </button>\n )\n}\n\nexport const InputClearButton = Object.assign(Root, {\n id: 'ClearButton',\n})\n\nRoot.displayName = 'InputGroup.ClearButton'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputGroupStyles = cva(['relative inline-flex w-full'], {\n variants: {\n /**\n * When `true`, prevents the user from interacting.\n */\n disabled: {\n true: [\n 'cursor-not-allowed',\n 'relative',\n 'after:absolute',\n 'after:top-0',\n 'after:h-full',\n 'after:w-full',\n 'after:border-sm after:border-outline',\n 'after:rounded-lg',\n ],\n false: 'after:hidden',\n },\n /**\n * Sets the component as interactive or not.\n */\n readOnly: {\n true: [\n 'relative',\n 'after:absolute',\n 'after:top-0',\n 'after:h-full',\n 'after:w-full',\n 'after:border-sm after:border-outline',\n 'after:rounded-lg',\n ],\n false: 'after:hidden',\n },\n },\n})\n\nexport type InputGroupStylesProps = VariantProps<typeof inputGroupStyles>\n","/* eslint-disable max-lines-per-function */\n\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport {\n ChangeEventHandler,\n Children,\n cloneElement,\n ComponentPropsWithoutRef,\n DetailedReactHTMLElement,\n FC,\n isValidElement,\n PropsWithChildren,\n ReactElement,\n Ref,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from 'react'\n\nimport { InputProps } from './Input'\nimport { inputGroupStyles, InputGroupStylesProps } from './InputGroup.styles'\nimport { InputGroupContext } from './InputGroupContext'\n\nexport interface InputGroupProps extends ComponentPropsWithoutRef<'div'>, InputGroupStylesProps {\n /**\n * Use `state` prop to assign a specific state to the group, choosing from: `error`, `alert` and `success`. By doing so, the outline styles will be updated.\n */\n state?: 'error' | 'alert' | 'success'\n /**\n * Function handler to be executed after the input has been cleared.\n */\n onClear?: () => void\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputGroup = ({\n className,\n children: childrenProp,\n state: stateProp,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n onClear,\n ref: forwardedRef,\n ...others\n}: PropsWithChildren<InputGroupProps>) => {\n const getElementId = (element?: ReactElement) => {\n return element ? (element.type as FC & { id?: string }).id : ''\n }\n\n const findElement = (...values: string[]) => {\n return children.find(child => values.includes(getElementId(child) || ''))\n }\n\n const children = Children.toArray(childrenProp).filter(isValidElement)\n const input = findElement('Input') as\n | DetailedReactHTMLElement<InputProps, HTMLInputElement>\n | undefined\n const props = input?.props || {}\n\n const inputRef = useRef<HTMLInputElement>(null!)\n const onClearRef = useRef(onClear)\n const ref = useMergeRefs<HTMLInputElement>(input?.ref, inputRef)\n const [value, onChange] = useCombinedState(\n props.value as string,\n props.defaultValue as string,\n props.onValueChange\n )\n\n // Data derivated from FormField context\n const field = useFormFieldControl()\n const state = field.state ?? stateProp\n const disabled = field.disabled || !!disabledProp\n const readOnly = field.readOnly || !!readOnlyProp\n\n // InputGroup elements (in visual order)\n const leadingAddon = findElement('LeadingAddon')\n const leadingIcon = findElement('LeadingIcon')\n const clearButton = findElement('ClearButton')\n const trailingIcon = findElement('TrailingIcon')\n const trailingAddon = findElement('TrailingAddon')\n\n // Acknowledge which subComponents are used in the compound context\n const hasLeadingAddon = !!leadingAddon\n const hasTrailingAddon = !!trailingAddon\n const hasLeadingIcon = !!leadingIcon\n const hasTrailingIcon = !!trailingIcon\n const hasClearButton = !!value && !!clearButton && !disabled && !readOnly\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = event => {\n if (props.onChange) {\n props.onChange(event)\n }\n\n onChange(event.target.value)\n }\n\n const handleClear = useCallback(() => {\n if (onClearRef.current) {\n onClearRef.current()\n }\n\n onChange('')\n\n inputRef.current.focus()\n }, [onChange])\n\n const current = useMemo(() => {\n return {\n state,\n disabled,\n readOnly,\n hasLeadingIcon,\n hasTrailingIcon,\n hasLeadingAddon,\n hasTrailingAddon,\n hasClearButton,\n onClear: handleClear,\n }\n }, [\n state,\n disabled,\n readOnly,\n hasLeadingIcon,\n hasTrailingIcon,\n hasLeadingAddon,\n hasTrailingAddon,\n hasClearButton,\n handleClear,\n ])\n\n useEffect(() => {\n onClearRef.current = onClear\n }, [onClear])\n\n // Preserve the input value when cloning. Some libraries like React Hook Form\n // only expose a ref (via `register`) without direct value access, so we need\n // to manually retrieve the value from the ref to avoid losing it.\n const inputRefValue = inputRef.current?.value\n\n return (\n <InputGroupContext.Provider value={current}>\n <div\n data-spark-component=\"input-group\"\n ref={forwardedRef}\n className={inputGroupStyles({ disabled, readOnly, className })}\n {...others}\n >\n {hasLeadingAddon && leadingAddon}\n\n <div className=\"relative inline-flex w-full\">\n {input &&\n cloneElement(input, {\n value: value ?? inputRefValue ?? '',\n ref,\n defaultValue: undefined,\n onChange: handleChange,\n })}\n\n {leadingIcon}\n\n {hasClearButton && clearButton}\n\n {trailingIcon}\n </div>\n\n {hasTrailingAddon && trailingAddon}\n </div>\n </InputGroupContext.Provider>\n )\n}\n\nInputGroup.displayName = 'InputGroup'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputAddonStyles = cva(\n [\n 'overflow-hidden',\n 'border-sm',\n 'shrink-0',\n 'h-full',\n 'focus-visible:relative focus-visible:z-raised',\n 'mx-0',\n ],\n {\n variants: {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild: { false: ['flex', 'items-center', 'px-lg'] },\n intent: {\n neutral: 'border-outline',\n error: 'border-error',\n alert: 'border-alert',\n success: 'border-success',\n },\n /**\n * Disable the input addon, preventing user interaction and adding opacity.\n */\n disabled: {\n true: ['pointer-events-none border-outline!'],\n },\n /**\n * Changes input addon styles based on the read only status from the input.\n */\n readOnly: {\n true: ['pointer-events-none'],\n },\n /**\n * Main style of the input addon.\n */\n design: {\n text: '',\n solid: '',\n inline: '',\n },\n },\n compoundVariants: [\n {\n disabled: false,\n readOnly: false,\n design: 'text',\n class: ['bg-surface', 'text-on-surface'],\n },\n {\n disabled: true,\n design: 'text',\n class: ['text-on-surface/dim-3'],\n },\n {\n disabled: true,\n design: ['solid', 'inline'],\n class: ['opacity-dim-3'],\n },\n ],\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputAddonStylesProps = VariantProps<typeof inputAddonStyles>\n","import { Children, type ComponentPropsWithoutRef, type PropsWithChildren, Ref } from 'react'\n\nimport { Slot } from '../slot'\nimport { inputAddonStyles, type InputAddonStylesProps } from './InputAddon.styles'\nimport { useInputGroup } from './InputGroupContext'\n\nexport interface InputAddonProps\n extends ComponentPropsWithoutRef<'div'>, Omit<InputAddonStylesProps, 'intent' | 'disabled'> {\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputAddon = ({\n asChild: asChildProp,\n className,\n children,\n ref,\n ...others\n}: PropsWithChildren<InputAddonProps>) => {\n const { state, disabled, readOnly } = useInputGroup()\n\n const isRawText = typeof children === 'string'\n const asChild = !!(isRawText ? false : asChildProp)\n const child = isRawText ? children : Children.only(children)\n const Component = asChild && !isRawText ? Slot : 'div'\n\n const getDesign = (): InputAddonStylesProps['design'] => {\n if (isRawText) return 'text'\n\n return asChild ? 'solid' : 'inline'\n }\n\n const design = getDesign()\n\n return (\n <Component\n ref={ref}\n data-spark-component=\"input-addon\"\n className={inputAddonStyles({\n className,\n intent: state,\n disabled,\n readOnly,\n asChild,\n design,\n })}\n {...(disabled && { tabIndex: -1 })}\n {...others}\n >\n {child}\n </Component>\n )\n}\n\nInputAddon.displayName = 'InputGroup.Addon'\n","import { cx } from 'class-variance-authority'\nimport { Ref } from 'react'\n\nimport { InputAddon, InputAddonProps } from './InputAddon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputLeadingAddonProps = InputAddonProps & {\n ref?: Ref<HTMLDivElement>\n}\n\nconst Root = ({ className, ref, ...others }: InputLeadingAddonProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <div className={cx('rounded-l-lg', isInactive ? 'bg-on-surface/dim-5' : null)}>\n <InputAddon\n ref={ref}\n className={cx(className, 'rounded-r-0! mr-[-1px] rounded-l-lg')}\n {...others}\n />\n </div>\n )\n}\n\nexport const InputLeadingAddon = Object.assign(Root, {\n id: 'LeadingAddon',\n})\n\nRoot.displayName = 'InputGroup.LeadingAddon'\n","import { cx } from 'class-variance-authority'\n\nimport { Icon, type IconProps } from '../icon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputIconProps = IconProps\n\nexport const InputIcon = ({ className, intent, children, ...others }: InputIconProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <Icon\n data-spark-component=\"input-icon\"\n intent={intent}\n className={cx(\n className,\n 'pointer-events-none absolute top-[calc(var(--spacing-sz-44)/2)] -translate-y-1/2',\n intent ? undefined : 'text-neutral peer-focus:text-outline-high',\n isInactive ? 'opacity-dim-3' : undefined\n )}\n {...others}\n >\n {children}\n </Icon>\n )\n}\n\nInputIcon.displayName = 'InputGroup.Icon'\n","import { cx } from 'class-variance-authority'\n\nimport { InputIcon, InputIconProps } from './InputIcon'\n\nexport type InputLeadingIconProps = InputIconProps\n\nexport const InputLeadingIcon = ({ className, ...others }: InputLeadingIconProps) => (\n <InputIcon className={cx(className, 'left-lg text-body-1')} {...others} />\n)\n\nInputLeadingIcon.id = 'LeadingIcon'\nInputLeadingIcon.displayName = 'InputGroup.LeadingIcon'\n","import { cx } from 'class-variance-authority'\nimport { Ref } from 'react'\n\nimport { InputAddon, InputAddonProps } from './InputAddon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputTrailingAddonProps = InputAddonProps & {\n ref?: Ref<HTMLDivElement>\n}\n\nconst Root = ({ className, ref, ...others }: InputTrailingAddonProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <div className={cx('rounded-r-lg', isInactive ? 'bg-on-surface/dim-5' : null)}>\n <InputAddon\n ref={ref}\n className={cx(className, 'rounded-l-0! ml-[-1px] rounded-r-lg')}\n {...others}\n />\n </div>\n )\n}\n\nexport const InputTrailingAddon = Object.assign(Root, {\n id: 'TrailingAddon',\n})\n\nRoot.displayName = 'InputGroup.TrailingAddon'\n","import { cx } from 'class-variance-authority'\n\nimport { InputIcon, InputIconProps } from './InputIcon'\n\nexport type InputTrailingIconProps = InputIconProps\n\nexport const InputTrailingIcon = ({ className, ...others }: InputTrailingIconProps) => (\n <InputIcon className={cx(className, 'right-lg text-body-1')} {...others} />\n)\n\nInputTrailingIcon.id = 'TrailingIcon'\nInputTrailingIcon.displayName = 'InputGroup.TrailingIcon'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputStyles = cva(\n [\n 'relative',\n 'border-sm',\n 'peer',\n 'w-full',\n 'appearance-none outline-hidden',\n 'bg-surface',\n 'text-ellipsis text-body-1 text-on-surface',\n 'caret-neutral',\n '[&:-webkit-autofill]:[-webkit-text-fill-color:var(--color-on-surface)]',\n 'autofill:shadow-surface autofill:shadow-[inset_0_0_0px_1000px]',\n 'disabled:cursor-not-allowed disabled:border-outline disabled:bg-on-surface/dim-5 disabled:text-on-surface/dim-3',\n 'read-only:cursor-default read-only:pointer-events-none read-only:bg-on-surface/dim-5',\n 'focus:ring-1 focus:ring-inset focus:ring-focus focus:border-focus',\n ],\n {\n variants: {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild: {\n true: ['min-h-sz-44'],\n false: ['h-sz-44'],\n },\n /**\n * Color scheme of the button.\n */\n intent: {\n neutral: ['border-outline', 'default:hover:border-outline-high'],\n success: ['default:border-success'],\n alert: ['default:border-alert'],\n error: ['default:border-error'],\n },\n /**\n * Sets if there is an addon before the input text.\n */\n hasLeadingAddon: {\n true: ['rounded-l-0'],\n false: ['rounded-l-lg'],\n },\n /**\n * Sets if there is an addon after the input text.\n */\n hasTrailingAddon: {\n true: ['rounded-r-0'],\n false: ['rounded-r-lg'],\n },\n /**\n * Sets if there is an icon before the input text.\n */\n hasLeadingIcon: {\n true: ['pl-3xl'],\n false: ['pl-lg'],\n },\n /**\n * Sets if there is an icon after the input text.\n */\n hasTrailingIcon: { true: '' },\n /**\n * Sets if there is a button to clear the input text.\n */\n hasClearButton: { true: '' },\n },\n compoundVariants: [\n {\n hasTrailingIcon: false,\n hasClearButton: false,\n class: 'pr-lg',\n },\n {\n hasTrailingIcon: true,\n hasClearButton: false,\n class: 'pr-3xl',\n },\n {\n hasTrailingIcon: false,\n hasClearButton: true,\n class: 'pr-3xl',\n },\n {\n hasTrailingIcon: true,\n hasClearButton: true,\n class: 'pr-[calc(var(--spacing-3xl)*2)]',\n },\n ],\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputStylesProps = VariantProps<typeof inputStyles>\n","import { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { ChangeEventHandler, ComponentPropsWithoutRef, KeyboardEventHandler, Ref } from 'react'\n\nimport { Slot } from '../slot'\nimport { inputStyles } from './Input.styles'\nimport { useInputGroup } from './InputGroupContext'\n\ntype InputPrimitiveProps = ComponentPropsWithoutRef<'input'>\n\nexport interface InputProps extends InputPrimitiveProps {\n asChild?: boolean\n onValueChange?: (value: string) => void\n ref?: Ref<HTMLInputElement>\n}\n\nconst Root = ({\n className,\n asChild = false,\n onValueChange,\n onChange,\n onKeyDown,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n ref,\n ...others\n}: InputProps) => {\n const field = useFormFieldControl()\n const group = useInputGroup()\n\n const { id, name, isInvalid, isRequired, description } = field\n const {\n hasLeadingAddon,\n hasTrailingAddon,\n hasLeadingIcon,\n hasTrailingIcon,\n hasClearButton,\n onClear,\n } = group\n const Component = asChild ? Slot : 'input'\n const state = field.state || group.state\n const disabled = field.disabled || group.disabled || disabledProp\n const readOnly = field.readOnly || group.readOnly || readOnlyProp\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = event => {\n if (onChange) {\n onChange(event)\n }\n\n if (onValueChange) {\n onValueChange(event.target.value)\n }\n }\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = event => {\n if (onKeyDown) {\n onKeyDown(event)\n }\n\n if (hasClearButton && onClear && event.key === 'Escape') {\n onClear()\n }\n }\n\n return (\n <Component\n data-spark-component=\"input\"\n ref={ref}\n id={id}\n name={name}\n className={inputStyles({\n asChild,\n className,\n intent: state,\n hasLeadingAddon: !!hasLeadingAddon,\n hasTrailingAddon: !!hasTrailingAddon,\n hasLeadingIcon: !!hasLeadingIcon,\n hasTrailingIcon: !!hasTrailingIcon,\n hasClearButton: !!hasClearButton,\n })}\n disabled={disabled}\n readOnly={readOnly}\n required={isRequired}\n aria-describedby={description}\n aria-invalid={isInvalid}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...others}\n />\n )\n}\n\n/**\n * A text input field that allows users to enter and edit text content.\n */\nexport const Input = Object.assign(Root, {\n id: 'Input',\n})\n\nRoot.displayName = 'Input'\n","import { InputClearButton } from './InputClearButton'\nimport { InputGroup as Root } from './InputGroup'\nimport { InputLeadingAddon } from './InputLeadingAddon'\nimport { InputLeadingIcon } from './InputLeadingIcon'\nimport { InputTrailingAddon } from './InputTrailingAddon'\nimport { InputTrailingIcon } from './InputTrailingIcon'\n\nexport * from './Input'\n\n/**\n * A wrapper component that combines an Input with addons, icons, and interactive elements\n * to create more complex text input patterns like search bars, password fields, or URL inputs.\n */\nexport const InputGroup: typeof Root & {\n LeadingAddon: typeof InputLeadingAddon\n TrailingAddon: typeof InputTrailingAddon\n LeadingIcon: typeof InputLeadingIcon\n TrailingIcon: typeof InputTrailingIcon\n ClearButton: typeof InputClearButton\n} = Object.assign(Root, {\n LeadingAddon: InputLeadingAddon,\n TrailingAddon: InputTrailingAddon,\n LeadingIcon: InputLeadingIcon,\n TrailingIcon: InputTrailingIcon,\n ClearButton: InputClearButton,\n})\n\nInputGroup.displayName = 'InputGroup'\nInputLeadingAddon.displayName = 'InputGroup.LeadingAddon'\nInputTrailingAddon.displayName = 'InputGroup.TrailingAddon'\nInputLeadingIcon.displayName = 'InputGroup.LeadingIcon'\nInputTrailingIcon.displayName = 'InputGroup.TrailingIcon'\nInputClearButton.displayName = 'InputGroup.ClearButton'\n\nexport { useInputGroup } from './InputGroupContext'\nexport { type InputGroupProps } from './InputGroup'\nexport { type InputLeadingIconProps } from './InputLeadingIcon'\nexport { type InputTrailingIconProps } from './InputTrailingIcon'\nexport { type InputLeadingAddonProps } from './InputLeadingAddon'\nexport { type InputTrailingAddonProps } from './InputTrailingAddon'\nexport { type InputClearButtonProps } from './InputClearButton'\n"],"mappings":"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"}
1
+ {"version":3,"file":"input-BIuBpTEq.mjs","names":[],"sources":["../src/input/InputGroupContext.ts","../src/input/InputClearButton.tsx","../src/input/InputGroup.styles.ts","../src/input/InputGroup.tsx","../src/input/InputAddon.styles.ts","../src/input/InputAddon.tsx","../src/input/InputLeadingAddon.tsx","../src/input/InputIcon.tsx","../src/input/InputLeadingIcon.tsx","../src/input/InputTrailingAddon.tsx","../src/input/InputTrailingIcon.tsx","../src/input/Input.styles.ts","../src/input/Input.tsx","../src/input/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface InputGroupContextValue {\n disabled?: boolean\n readOnly?: boolean\n hasLeadingIcon: boolean\n hasTrailingIcon: boolean\n hasLeadingAddon: boolean\n hasTrailingAddon: boolean\n hasClearButton: boolean\n state: null | undefined | 'error' | 'alert' | 'success'\n isStandalone?: boolean\n onClear: () => void\n}\n\nexport const InputGroupContext = createContext<Partial<InputGroupContextValue> | null>(null)\n\nexport const useInputGroup = () => {\n const context = useContext(InputGroupContext)\n\n return context || { isStandalone: true }\n}\n","import { DeleteOutline } from '@spark-ui/icons/DeleteOutline'\nimport { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, MouseEventHandler, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport interface InputClearButtonProps extends ComponentPropsWithoutRef<'button'> {\n 'aria-label': string\n inline?: boolean\n ref?: Ref<HTMLButtonElement>\n}\n\nconst Root = ({\n className,\n tabIndex = -1,\n onClick,\n inline = false,\n ref,\n ...others\n}: InputClearButtonProps) => {\n const { onClear, hasTrailingIcon } = useInputGroup()\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = event => {\n if (onClick) {\n onClick(event)\n }\n\n if (onClear) {\n onClear()\n }\n }\n\n return (\n <button\n ref={ref}\n data-spark-component=\"input-clear-button\"\n className={cx(\n className,\n 'pointer-events-auto absolute',\n inline ? 'h-sz-44 top-0 -translate-y-0' : 'top-1/2 -translate-y-1/2',\n 'inline-flex h-full items-center justify-center outline-hidden',\n 'text-neutral hover:text-neutral-hovered',\n hasTrailingIcon ? 'right-3xl px-sz-12' : 'pl-md pr-lg right-0'\n )}\n tabIndex={tabIndex}\n onClick={handleClick}\n type=\"button\"\n {...others}\n >\n <Icon size=\"sm\">\n <DeleteOutline />\n </Icon>\n </button>\n )\n}\n\nexport const InputClearButton = Object.assign(Root, {\n id: 'ClearButton',\n})\n\nRoot.displayName = 'InputGroup.ClearButton'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputGroupStyles = cva(['relative inline-flex w-full'], {\n variants: {\n /**\n * When `true`, prevents the user from interacting.\n */\n disabled: {\n true: [\n 'cursor-not-allowed',\n 'relative',\n 'after:absolute',\n 'after:top-0',\n 'after:h-full',\n 'after:w-full',\n 'after:border-sm after:border-outline',\n 'after:rounded-lg',\n ],\n false: 'after:hidden',\n },\n /**\n * Sets the component as interactive or not.\n */\n readOnly: {\n true: [\n 'relative',\n 'after:absolute',\n 'after:top-0',\n 'after:h-full',\n 'after:w-full',\n 'after:border-sm after:border-outline',\n 'after:rounded-lg',\n ],\n false: 'after:hidden',\n },\n },\n})\n\nexport type InputGroupStylesProps = VariantProps<typeof inputGroupStyles>\n","/* eslint-disable max-lines-per-function */\n\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport {\n ChangeEventHandler,\n Children,\n cloneElement,\n ComponentPropsWithoutRef,\n DetailedReactHTMLElement,\n FC,\n isValidElement,\n PropsWithChildren,\n ReactElement,\n Ref,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from 'react'\n\nimport { InputProps } from './Input'\nimport { inputGroupStyles, InputGroupStylesProps } from './InputGroup.styles'\nimport { InputGroupContext } from './InputGroupContext'\n\nexport interface InputGroupProps extends ComponentPropsWithoutRef<'div'>, InputGroupStylesProps {\n /**\n * Use `state` prop to assign a specific state to the group, choosing from: `error`, `alert` and `success`. By doing so, the outline styles will be updated.\n */\n state?: 'error' | 'alert' | 'success'\n /**\n * Function handler to be executed after the input has been cleared.\n */\n onClear?: () => void\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputGroup = ({\n className,\n children: childrenProp,\n state: stateProp,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n onClear,\n ref: forwardedRef,\n ...others\n}: PropsWithChildren<InputGroupProps>) => {\n const getElementId = (element?: ReactElement) => {\n return element ? (element.type as FC & { id?: string }).id : ''\n }\n\n const findElement = (...values: string[]) => {\n return children.find(child => values.includes(getElementId(child) || ''))\n }\n\n const children = Children.toArray(childrenProp).filter(isValidElement)\n const input = findElement('Input') as\n | DetailedReactHTMLElement<InputProps, HTMLInputElement>\n | undefined\n const props = input?.props || {}\n\n const inputRef = useRef<HTMLInputElement>(null!)\n const onClearRef = useRef(onClear)\n const ref = useMergeRefs<HTMLInputElement>(input?.ref, inputRef)\n const [value, onChange] = useCombinedState(\n props.value as string,\n props.defaultValue as string,\n props.onValueChange\n )\n\n // Data derivated from FormField context\n const field = useFormFieldControl()\n const state = field.state ?? stateProp\n const disabled = field.disabled || !!disabledProp\n const readOnly = field.readOnly || !!readOnlyProp\n\n // InputGroup elements (in visual order)\n const leadingAddon = findElement('LeadingAddon')\n const leadingIcon = findElement('LeadingIcon')\n const clearButton = findElement('ClearButton')\n const trailingIcon = findElement('TrailingIcon')\n const trailingAddon = findElement('TrailingAddon')\n\n // Acknowledge which subComponents are used in the compound context\n const hasLeadingAddon = !!leadingAddon\n const hasTrailingAddon = !!trailingAddon\n const hasLeadingIcon = !!leadingIcon\n const hasTrailingIcon = !!trailingIcon\n const hasClearButton = !!value && !!clearButton && !disabled && !readOnly\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = event => {\n if (props.onChange) {\n props.onChange(event)\n }\n\n onChange(event.target.value)\n }\n\n const handleClear = useCallback(() => {\n if (onClearRef.current) {\n onClearRef.current()\n }\n\n onChange('')\n\n inputRef.current.focus()\n }, [onChange])\n\n const current = useMemo(() => {\n return {\n state,\n disabled,\n readOnly,\n hasLeadingIcon,\n hasTrailingIcon,\n hasLeadingAddon,\n hasTrailingAddon,\n hasClearButton,\n onClear: handleClear,\n }\n }, [\n state,\n disabled,\n readOnly,\n hasLeadingIcon,\n hasTrailingIcon,\n hasLeadingAddon,\n hasTrailingAddon,\n hasClearButton,\n handleClear,\n ])\n\n useEffect(() => {\n onClearRef.current = onClear\n }, [onClear])\n\n // Preserve the input value when cloning. Some libraries like React Hook Form\n // only expose a ref (via `register`) without direct value access, so we need\n // to manually retrieve the value from the ref to avoid losing it.\n const inputRefValue = inputRef.current?.value\n\n return (\n <InputGroupContext.Provider value={current}>\n <div\n data-spark-component=\"input-group\"\n ref={forwardedRef}\n className={inputGroupStyles({ disabled, readOnly, className })}\n {...others}\n >\n {hasLeadingAddon && leadingAddon}\n\n <div className=\"relative inline-flex w-full\">\n {input &&\n cloneElement(input, {\n value: value ?? inputRefValue ?? '',\n ref,\n defaultValue: undefined,\n onChange: handleChange,\n })}\n\n {leadingIcon}\n\n {hasClearButton && clearButton}\n\n {trailingIcon}\n </div>\n\n {hasTrailingAddon && trailingAddon}\n </div>\n </InputGroupContext.Provider>\n )\n}\n\nInputGroup.displayName = 'InputGroup'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputAddonStyles = cva(\n [\n 'overflow-hidden',\n 'border-sm',\n 'shrink-0',\n 'h-full',\n 'focus-visible:relative focus-visible:z-raised',\n 'mx-0',\n ],\n {\n variants: {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild: { false: ['flex', 'items-center', 'px-lg'] },\n intent: {\n neutral: 'border-outline',\n error: 'border-error',\n alert: 'border-alert',\n success: 'border-success',\n },\n /**\n * Disable the input addon, preventing user interaction and adding opacity.\n */\n disabled: {\n true: ['pointer-events-none border-outline!'],\n },\n /**\n * Changes input addon styles based on the read only status from the input.\n */\n readOnly: {\n true: ['pointer-events-none'],\n },\n /**\n * Main style of the input addon.\n */\n design: {\n text: '',\n solid: '',\n inline: '',\n },\n },\n compoundVariants: [\n {\n disabled: false,\n readOnly: false,\n design: 'text',\n class: ['bg-surface', 'text-on-surface'],\n },\n {\n disabled: true,\n design: 'text',\n class: ['text-on-surface/dim-3'],\n },\n {\n disabled: true,\n design: ['solid', 'inline'],\n class: ['opacity-dim-3'],\n },\n ],\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputAddonStylesProps = VariantProps<typeof inputAddonStyles>\n","import { Children, type ComponentPropsWithoutRef, type PropsWithChildren, Ref } from 'react'\n\nimport { Slot } from '../slot'\nimport { inputAddonStyles, type InputAddonStylesProps } from './InputAddon.styles'\nimport { useInputGroup } from './InputGroupContext'\n\nexport interface InputAddonProps\n extends ComponentPropsWithoutRef<'div'>, Omit<InputAddonStylesProps, 'intent' | 'disabled'> {\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputAddon = ({\n asChild: asChildProp,\n className,\n children,\n ref,\n ...others\n}: PropsWithChildren<InputAddonProps>) => {\n const { state, disabled, readOnly } = useInputGroup()\n\n const isRawText = typeof children === 'string'\n const asChild = !!(isRawText ? false : asChildProp)\n const child = isRawText ? children : Children.only(children)\n const Component = asChild && !isRawText ? Slot : 'div'\n\n const getDesign = (): InputAddonStylesProps['design'] => {\n if (isRawText) return 'text'\n\n return asChild ? 'solid' : 'inline'\n }\n\n const design = getDesign()\n\n return (\n <Component\n ref={ref}\n data-spark-component=\"input-addon\"\n className={inputAddonStyles({\n className,\n intent: state,\n disabled,\n readOnly,\n asChild,\n design,\n })}\n {...(disabled && { tabIndex: -1 })}\n {...others}\n >\n {child}\n </Component>\n )\n}\n\nInputAddon.displayName = 'InputGroup.Addon'\n","import { cx } from 'class-variance-authority'\nimport { Ref } from 'react'\n\nimport { InputAddon, InputAddonProps } from './InputAddon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputLeadingAddonProps = InputAddonProps & {\n ref?: Ref<HTMLDivElement>\n}\n\nconst Root = ({ className, ref, ...others }: InputLeadingAddonProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <div className={cx('rounded-l-lg', isInactive ? 'bg-on-surface/dim-5' : null)}>\n <InputAddon\n ref={ref}\n className={cx(className, 'rounded-r-0! mr-[-1px] rounded-l-lg')}\n {...others}\n />\n </div>\n )\n}\n\nexport const InputLeadingAddon = Object.assign(Root, {\n id: 'LeadingAddon',\n})\n\nRoot.displayName = 'InputGroup.LeadingAddon'\n","import { cx } from 'class-variance-authority'\n\nimport { Icon, type IconProps } from '../icon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputIconProps = IconProps\n\nexport const InputIcon = ({ className, intent, children, ...others }: InputIconProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <Icon\n data-spark-component=\"input-icon\"\n intent={intent}\n className={cx(\n className,\n 'pointer-events-none absolute top-[calc(var(--spacing-sz-44)/2)] -translate-y-1/2',\n intent ? undefined : 'text-neutral peer-focus:text-outline-high',\n isInactive ? 'opacity-dim-3' : undefined\n )}\n {...others}\n >\n {children}\n </Icon>\n )\n}\n\nInputIcon.displayName = 'InputGroup.Icon'\n","import { cx } from 'class-variance-authority'\n\nimport { InputIcon, InputIconProps } from './InputIcon'\n\nexport type InputLeadingIconProps = InputIconProps\n\nexport const InputLeadingIcon = ({ className, ...others }: InputLeadingIconProps) => (\n <InputIcon className={cx(className, 'left-lg text-body-1')} {...others} />\n)\n\nInputLeadingIcon.id = 'LeadingIcon'\nInputLeadingIcon.displayName = 'InputGroup.LeadingIcon'\n","import { cx } from 'class-variance-authority'\nimport { Ref } from 'react'\n\nimport { InputAddon, InputAddonProps } from './InputAddon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputTrailingAddonProps = InputAddonProps & {\n ref?: Ref<HTMLDivElement>\n}\n\nconst Root = ({ className, ref, ...others }: InputTrailingAddonProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <div className={cx('rounded-r-lg', isInactive ? 'bg-on-surface/dim-5' : null)}>\n <InputAddon\n ref={ref}\n className={cx(className, 'rounded-l-0! ml-[-1px] rounded-r-lg')}\n {...others}\n />\n </div>\n )\n}\n\nexport const InputTrailingAddon = Object.assign(Root, {\n id: 'TrailingAddon',\n})\n\nRoot.displayName = 'InputGroup.TrailingAddon'\n","import { cx } from 'class-variance-authority'\n\nimport { InputIcon, InputIconProps } from './InputIcon'\n\nexport type InputTrailingIconProps = InputIconProps\n\nexport const InputTrailingIcon = ({ className, ...others }: InputTrailingIconProps) => (\n <InputIcon className={cx(className, 'right-lg text-body-1')} {...others} />\n)\n\nInputTrailingIcon.id = 'TrailingIcon'\nInputTrailingIcon.displayName = 'InputGroup.TrailingIcon'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputStyles = cva(\n [\n 'relative',\n 'border-sm',\n 'peer',\n 'w-full',\n 'appearance-none outline-hidden',\n 'bg-surface',\n 'text-ellipsis text-body-1 text-on-surface',\n 'caret-neutral',\n '[&:-webkit-autofill]:[-webkit-text-fill-color:var(--color-on-surface)]',\n 'autofill:shadow-surface autofill:shadow-[inset_0_0_0px_1000px]',\n 'disabled:cursor-not-allowed disabled:border-outline disabled:bg-on-surface/dim-5 disabled:text-on-surface/dim-3',\n 'read-only:cursor-default read-only:pointer-events-none read-only:bg-on-surface/dim-5',\n 'focus:ring-1 focus:ring-inset focus:ring-focus focus:border-focus',\n ],\n {\n variants: {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild: {\n true: ['min-h-sz-44'],\n false: ['h-sz-44'],\n },\n /**\n * Color scheme of the button.\n */\n intent: {\n neutral: ['border-outline', 'default:hover:border-outline-high'],\n success: ['default:border-success'],\n alert: ['default:border-alert'],\n error: ['default:border-error'],\n },\n /**\n * Sets if there is an addon before the input text.\n */\n hasLeadingAddon: {\n true: ['rounded-l-0'],\n false: ['rounded-l-lg'],\n },\n /**\n * Sets if there is an addon after the input text.\n */\n hasTrailingAddon: {\n true: ['rounded-r-0'],\n false: ['rounded-r-lg'],\n },\n /**\n * Sets if there is an icon before the input text.\n */\n hasLeadingIcon: {\n true: ['pl-3xl'],\n false: ['pl-lg'],\n },\n /**\n * Sets if there is an icon after the input text.\n */\n hasTrailingIcon: { true: '' },\n /**\n * Sets if there is a button to clear the input text.\n */\n hasClearButton: { true: '' },\n },\n compoundVariants: [\n {\n hasTrailingIcon: false,\n hasClearButton: false,\n class: 'pr-lg',\n },\n {\n hasTrailingIcon: true,\n hasClearButton: false,\n class: 'pr-3xl',\n },\n {\n hasTrailingIcon: false,\n hasClearButton: true,\n class: 'pr-3xl',\n },\n {\n hasTrailingIcon: true,\n hasClearButton: true,\n class: 'pr-[calc(var(--spacing-3xl)*2)]',\n },\n ],\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputStylesProps = VariantProps<typeof inputStyles>\n","import { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { ChangeEventHandler, ComponentPropsWithoutRef, KeyboardEventHandler, Ref } from 'react'\n\nimport { Slot } from '../slot'\nimport { inputStyles } from './Input.styles'\nimport { useInputGroup } from './InputGroupContext'\n\ntype InputPrimitiveProps = ComponentPropsWithoutRef<'input'>\n\nexport interface InputProps extends InputPrimitiveProps {\n asChild?: boolean\n onValueChange?: (value: string) => void\n ref?: Ref<HTMLInputElement>\n}\n\nconst Root = ({\n className,\n asChild = false,\n onValueChange,\n onChange,\n onKeyDown,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n ref,\n ...others\n}: InputProps) => {\n const field = useFormFieldControl()\n const group = useInputGroup()\n\n const { id, name, isInvalid, isRequired, description } = field\n const {\n hasLeadingAddon,\n hasTrailingAddon,\n hasLeadingIcon,\n hasTrailingIcon,\n hasClearButton,\n onClear,\n } = group\n const Component = asChild ? Slot : 'input'\n const state = field.state || group.state\n const disabled = field.disabled || group.disabled || disabledProp\n const readOnly = field.readOnly || group.readOnly || readOnlyProp\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = event => {\n if (onChange) {\n onChange(event)\n }\n\n if (onValueChange) {\n onValueChange(event.target.value)\n }\n }\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = event => {\n if (onKeyDown) {\n onKeyDown(event)\n }\n\n if (hasClearButton && onClear && event.key === 'Escape') {\n onClear()\n }\n }\n\n return (\n <Component\n data-spark-component=\"input\"\n ref={ref}\n id={id}\n name={name}\n className={inputStyles({\n asChild,\n className,\n intent: state,\n hasLeadingAddon: !!hasLeadingAddon,\n hasTrailingAddon: !!hasTrailingAddon,\n hasLeadingIcon: !!hasLeadingIcon,\n hasTrailingIcon: !!hasTrailingIcon,\n hasClearButton: !!hasClearButton,\n })}\n disabled={disabled}\n readOnly={readOnly}\n required={isRequired}\n aria-describedby={description}\n aria-invalid={isInvalid}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...others}\n />\n )\n}\n\n/**\n * A text input field that allows users to enter and edit text content.\n */\nexport const Input = Object.assign(Root, {\n id: 'Input',\n})\n\nRoot.displayName = 'Input'\n","import { InputClearButton } from './InputClearButton'\nimport { InputGroup as Root } from './InputGroup'\nimport { InputLeadingAddon } from './InputLeadingAddon'\nimport { InputLeadingIcon } from './InputLeadingIcon'\nimport { InputTrailingAddon } from './InputTrailingAddon'\nimport { InputTrailingIcon } from './InputTrailingIcon'\n\nexport * from './Input'\n\n/**\n * A wrapper component that combines an Input with addons, icons, and interactive elements\n * to create more complex text input patterns like search bars, password fields, or URL inputs.\n */\nexport const InputGroup: typeof Root & {\n LeadingAddon: typeof InputLeadingAddon\n TrailingAddon: typeof InputTrailingAddon\n LeadingIcon: typeof InputLeadingIcon\n TrailingIcon: typeof InputTrailingIcon\n ClearButton: typeof InputClearButton\n} = Object.assign(Root, {\n LeadingAddon: InputLeadingAddon,\n TrailingAddon: InputTrailingAddon,\n LeadingIcon: InputLeadingIcon,\n TrailingIcon: InputTrailingIcon,\n ClearButton: InputClearButton,\n})\n\nInputGroup.displayName = 'InputGroup'\nInputLeadingAddon.displayName = 'InputGroup.LeadingAddon'\nInputTrailingAddon.displayName = 'InputGroup.TrailingAddon'\nInputLeadingIcon.displayName = 'InputGroup.LeadingIcon'\nInputTrailingIcon.displayName = 'InputGroup.TrailingIcon'\nInputClearButton.displayName = 'InputGroup.ClearButton'\n\nexport { useInputGroup } from './InputGroupContext'\nexport { type InputGroupProps } from './InputGroup'\nexport { type InputLeadingIconProps } from './InputLeadingIcon'\nexport { type InputTrailingIconProps } from './InputTrailingIcon'\nexport { type InputLeadingAddonProps } from './InputLeadingAddon'\nexport { type InputTrailingAddonProps } from './InputTrailingAddon'\nexport { type InputClearButtonProps } from './InputClearButton'\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- require(`./chunk-C91j1N6u.js`);const e=require(`./slot/index.js`),t=require(`./icon-CRPcdgYp.js`);let n=require(`class-variance-authority`),r=require(`react`),i=require(`react/jsx-runtime`),a=require(`@spark-ui/hooks/use-merge-refs`),o=require(`@spark-ui/components/form-field`),s=require(`@spark-ui/hooks/use-combined-state`),c=require(`@spark-ui/icons/DeleteOutline`);var l=(0,r.createContext)(null),u=()=>(0,r.useContext)(l)||{isStandalone:!0},d=({className:e,tabIndex:r=-1,onClick:a,inline:o=!1,ref:s,...l})=>{let{onClear:d,hasTrailingIcon:f}=u();return(0,i.jsx)(`button`,{ref:s,"data-spark-component":`input-clear-button`,className:(0,n.cx)(e,`pointer-events-auto absolute`,o?`h-sz-44 top-0 -translate-y-0`:`top-1/2 -translate-y-1/2`,`inline-flex h-full items-center justify-center outline-hidden`,`text-neutral hover:text-neutral-hovered`,f?`right-3xl px-sz-12`:`pl-md pr-lg right-0`),tabIndex:r,onClick:e=>{a&&a(e),d&&d()},type:`button`,...l,children:(0,i.jsx)(t.t,{size:`sm`,children:(0,i.jsx)(c.DeleteOutline,{})})})},f=Object.assign(d,{id:`ClearButton`});d.displayName=`InputGroup.ClearButton`;var p=(0,n.cva)([`relative inline-flex w-full`],{variants:{disabled:{true:[`cursor-not-allowed`,`relative`,`after:absolute`,`after:top-0`,`after:h-full`,`after:w-full`,`after:border-sm after:border-outline`,`after:rounded-lg`],false:`after:hidden`},readOnly:{true:[`relative`,`after:absolute`,`after:top-0`,`after:h-full`,`after:w-full`,`after:border-sm after:border-outline`,`after:rounded-lg`],false:`after:hidden`}}}),m=({className:e,children:t,state:n,disabled:c,readOnly:u,onClear:d,ref:f,...m})=>{let h=e=>e?e.type.id:``,g=(...e)=>_.find(t=>e.includes(h(t)||``)),_=r.Children.toArray(t).filter(r.isValidElement),v=g(`Input`),y=v?.props||{},b=(0,r.useRef)(null),x=(0,r.useRef)(d),S=(0,a.useMergeRefs)(v?.ref,b),[C,w]=(0,s.useCombinedState)(y.value,y.defaultValue,y.onValueChange),T=(0,o.useFormFieldControl)(),E=T.state??n,D=T.disabled||!!c,O=T.readOnly||!!u,k=g(`LeadingAddon`),A=g(`LeadingIcon`),j=g(`ClearButton`),M=g(`TrailingIcon`),N=g(`TrailingAddon`),P=!!k,F=!!N,I=!!A,L=!!M,R=!!C&&!!j&&!D&&!O,z=e=>{y.onChange&&y.onChange(e),w(e.target.value)},B=(0,r.useCallback)(()=>{x.current&&x.current(),w(``),b.current.focus()},[w]),V=(0,r.useMemo)(()=>({state:E,disabled:D,readOnly:O,hasLeadingIcon:I,hasTrailingIcon:L,hasLeadingAddon:P,hasTrailingAddon:F,hasClearButton:R,onClear:B}),[E,D,O,I,L,P,F,R,B]);(0,r.useEffect)(()=>{x.current=d},[d]);let H=b.current?.value;return(0,i.jsx)(l.Provider,{value:V,children:(0,i.jsxs)(`div`,{"data-spark-component":`input-group`,ref:f,className:p({disabled:D,readOnly:O,className:e}),...m,children:[P&&k,(0,i.jsxs)(`div`,{className:`relative inline-flex w-full`,children:[v&&(0,r.cloneElement)(v,{value:C??H??``,ref:S,defaultValue:void 0,onChange:z}),A,R&&j,M]}),F&&N]})})};m.displayName=`InputGroup`;var h=(0,n.cva)([`overflow-hidden`,`border-sm`,`shrink-0`,`h-full`,`focus-visible:relative focus-visible:z-raised`,`mx-0`],{variants:{asChild:{false:[`flex`,`items-center`,`px-lg`]},intent:{neutral:`border-outline`,error:`border-error`,alert:`border-alert`,success:`border-success`},disabled:{true:[`pointer-events-none border-outline!`]},readOnly:{true:[`pointer-events-none`]},design:{text:``,solid:``,inline:``}},compoundVariants:[{disabled:!1,readOnly:!1,design:`text`,class:[`bg-surface`,`text-on-surface`]},{disabled:!0,design:`text`,class:[`text-on-surface/dim-3`]},{disabled:!0,design:[`solid`,`inline`],class:[`opacity-dim-3`]}],defaultVariants:{intent:`neutral`}}),g=({asChild:t,className:n,children:a,ref:o,...s})=>{let{state:c,disabled:l,readOnly:d}=u(),f=typeof a==`string`,p=!!(!f&&t),m=f?a:r.Children.only(a),g=p&&!f?e.Slot:`div`;return(0,i.jsx)(g,{ref:o,"data-spark-component":`input-addon`,className:h({className:n,intent:c,disabled:l,readOnly:d,asChild:p,design:f?`text`:p?`solid`:`inline`}),...l&&{tabIndex:-1},...s,children:m})};g.displayName=`InputGroup.Addon`;var _=({className:e,ref:t,...r})=>{let{disabled:a,readOnly:o}=u();return(0,i.jsx)(`div`,{className:(0,n.cx)(`rounded-l-lg`,a||o?`bg-on-surface/dim-5`:null),children:(0,i.jsx)(g,{ref:t,className:(0,n.cx)(e,`rounded-r-0! mr-[-1px] rounded-l-lg`),...r})})},v=Object.assign(_,{id:`LeadingAddon`});_.displayName=`InputGroup.LeadingAddon`;var y=({className:e,intent:r,children:a,...o})=>{let{disabled:s,readOnly:c}=u();return(0,i.jsx)(t.t,{"data-spark-component":`input-icon`,intent:r,className:(0,n.cx)(e,`pointer-events-none absolute top-[calc(var(--spacing-sz-44)/2)] -translate-y-1/2`,r?void 0:`text-neutral peer-focus:text-outline-high`,s||c?`opacity-dim-3`:void 0),...o,children:a})};y.displayName=`InputGroup.Icon`;var b=({className:e,...t})=>(0,i.jsx)(y,{className:(0,n.cx)(e,`left-lg text-body-1`),...t});b.id=`LeadingIcon`,b.displayName=`InputGroup.LeadingIcon`;var x=({className:e,ref:t,...r})=>{let{disabled:a,readOnly:o}=u();return(0,i.jsx)(`div`,{className:(0,n.cx)(`rounded-r-lg`,a||o?`bg-on-surface/dim-5`:null),children:(0,i.jsx)(g,{ref:t,className:(0,n.cx)(e,`rounded-l-0! ml-[-1px] rounded-r-lg`),...r})})},S=Object.assign(x,{id:`TrailingAddon`});x.displayName=`InputGroup.TrailingAddon`;var C=({className:e,...t})=>(0,i.jsx)(y,{className:(0,n.cx)(e,`right-lg text-body-1`),...t});C.id=`TrailingIcon`,C.displayName=`InputGroup.TrailingIcon`;var w=(0,n.cva)([`relative`,`border-sm`,`peer`,`w-full`,`appearance-none outline-hidden`,`bg-surface`,`text-ellipsis text-body-1 text-on-surface`,`caret-neutral`,`[&:-webkit-autofill]:[-webkit-text-fill-color:var(--color-on-surface)]`,`autofill:shadow-surface autofill:shadow-[inset_0_0_0px_1000px]`,`disabled:cursor-not-allowed disabled:border-outline disabled:bg-on-surface/dim-5 disabled:text-on-surface/dim-3`,`read-only:cursor-default read-only:pointer-events-none read-only:bg-on-surface/dim-5`,`focus:ring-1 focus:ring-inset focus:ring-focus focus:border-focus`],{variants:{asChild:{true:[`min-h-sz-44`],false:[`h-sz-44`]},intent:{neutral:[`border-outline`,`default:hover:border-outline-high`],success:[`default:border-success`],alert:[`default:border-alert`],error:[`default:border-error`]},hasLeadingAddon:{true:[`rounded-l-0`],false:[`rounded-l-lg`]},hasTrailingAddon:{true:[`rounded-r-0`],false:[`rounded-r-lg`]},hasLeadingIcon:{true:[`pl-3xl`],false:[`pl-lg`]},hasTrailingIcon:{true:``},hasClearButton:{true:``}},compoundVariants:[{hasTrailingIcon:!1,hasClearButton:!1,class:`pr-lg`},{hasTrailingIcon:!0,hasClearButton:!1,class:`pr-3xl`},{hasTrailingIcon:!1,hasClearButton:!0,class:`pr-3xl`},{hasTrailingIcon:!0,hasClearButton:!0,class:`pr-[calc(var(--spacing-3xl)*2)]`}],defaultVariants:{intent:`neutral`}}),T=({className:t,asChild:n=!1,onValueChange:r,onChange:a,onKeyDown:s,disabled:c,readOnly:l,ref:d,...f})=>{let p=(0,o.useFormFieldControl)(),m=u(),{id:h,name:g,isInvalid:_,isRequired:v,description:y}=p,{hasLeadingAddon:b,hasTrailingAddon:x,hasLeadingIcon:S,hasTrailingIcon:C,hasClearButton:T,onClear:E}=m,D=n?e.Slot:`input`,O=p.state||m.state,k=p.disabled||m.disabled||c,A=p.readOnly||m.readOnly||l;return(0,i.jsx)(D,{"data-spark-component":`input`,ref:d,id:h,name:g,className:w({asChild:n,className:t,intent:O,hasLeadingAddon:!!b,hasTrailingAddon:!!x,hasLeadingIcon:!!S,hasTrailingIcon:!!C,hasClearButton:!!T}),disabled:k,readOnly:A,required:v,"aria-describedby":y,"aria-invalid":_,onChange:e=>{a&&a(e),r&&r(e.target.value)},onKeyDown:e=>{s&&s(e),T&&E&&e.key===`Escape`&&E()},...f})},E=Object.assign(T,{id:`Input`});T.displayName=`Input`;var D=Object.assign(m,{LeadingAddon:v,TrailingAddon:S,LeadingIcon:b,TrailingIcon:C,ClearButton:f});D.displayName=`InputGroup`,v.displayName=`InputGroup.LeadingAddon`,S.displayName=`InputGroup.TrailingAddon`,b.displayName=`InputGroup.LeadingIcon`,C.displayName=`InputGroup.TrailingIcon`,f.displayName=`InputGroup.ClearButton`,Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return D}});
2
- //# sourceMappingURL=input-DaShg4eE.js.map
1
+ require(`./chunk-C91j1N6u.js`);const e=require(`./slot/index.js`),t=require(`./icon-CRPcdgYp.js`);let n=require(`class-variance-authority`),r=require(`react`),i=require(`react/jsx-runtime`),a=require(`@spark-ui/hooks/use-merge-refs`),o=require(`@spark-ui/components/form-field`),s=require(`@spark-ui/hooks/use-combined-state`),c=require(`@spark-ui/icons/DeleteOutline`);var l=(0,r.createContext)(null),u=()=>(0,r.useContext)(l)||{isStandalone:!0},d=({className:e,tabIndex:r=-1,onClick:a,inline:o=!1,ref:s,...l})=>{let{onClear:d,hasTrailingIcon:f}=u();return(0,i.jsx)(`button`,{ref:s,"data-spark-component":`input-clear-button`,className:(0,n.cx)(e,`pointer-events-auto absolute`,o?`h-sz-44 top-0 -translate-y-0`:`top-1/2 -translate-y-1/2`,`inline-flex h-full items-center justify-center outline-hidden`,`text-neutral hover:text-neutral-hovered`,f?`right-3xl px-sz-12`:`pl-md pr-lg right-0`),tabIndex:r,onClick:e=>{a&&a(e),d&&d()},type:`button`,...l,children:(0,i.jsx)(t.t,{size:`sm`,children:(0,i.jsx)(c.DeleteOutline,{})})})},f=Object.assign(d,{id:`ClearButton`});d.displayName=`InputGroup.ClearButton`;var p=(0,n.cva)([`relative inline-flex w-full`],{variants:{disabled:{true:[`cursor-not-allowed`,`relative`,`after:absolute`,`after:top-0`,`after:h-full`,`after:w-full`,`after:border-sm after:border-outline`,`after:rounded-lg`],false:`after:hidden`},readOnly:{true:[`relative`,`after:absolute`,`after:top-0`,`after:h-full`,`after:w-full`,`after:border-sm after:border-outline`,`after:rounded-lg`],false:`after:hidden`}}}),m=({className:e,children:t,state:n,disabled:c,readOnly:u,onClear:d,ref:f,...m})=>{let h=e=>e?e.type.id:``,g=(...e)=>_.find(t=>e.includes(h(t)||``)),_=r.Children.toArray(t).filter(r.isValidElement),v=g(`Input`),y=v?.props||{},b=(0,r.useRef)(null),x=(0,r.useRef)(d),S=(0,a.useMergeRefs)(v?.ref,b),[C,w]=(0,s.useCombinedState)(y.value,y.defaultValue,y.onValueChange),T=(0,o.useFormFieldControl)(),E=T.state??n,D=T.disabled||!!c,O=T.readOnly||!!u,k=g(`LeadingAddon`),A=g(`LeadingIcon`),j=g(`ClearButton`),M=g(`TrailingIcon`),N=g(`TrailingAddon`),P=!!k,F=!!N,I=!!A,L=!!M,R=!!C&&!!j&&!D&&!O,z=e=>{y.onChange&&y.onChange(e),w(e.target.value)},B=(0,r.useCallback)(()=>{x.current&&x.current(),w(``),b.current.focus()},[w]),V=(0,r.useMemo)(()=>({state:E,disabled:D,readOnly:O,hasLeadingIcon:I,hasTrailingIcon:L,hasLeadingAddon:P,hasTrailingAddon:F,hasClearButton:R,onClear:B}),[E,D,O,I,L,P,F,R,B]);(0,r.useEffect)(()=>{x.current=d},[d]);let H=b.current?.value;return(0,i.jsx)(l.Provider,{value:V,children:(0,i.jsxs)(`div`,{"data-spark-component":`input-group`,ref:f,className:p({disabled:D,readOnly:O,className:e}),...m,children:[P&&k,(0,i.jsxs)(`div`,{className:`relative inline-flex w-full`,children:[v&&(0,r.cloneElement)(v,{value:C??H??``,ref:S,defaultValue:void 0,onChange:z}),A,R&&j,M]}),F&&N]})})};m.displayName=`InputGroup`;var h=(0,n.cva)([`overflow-hidden`,`border-sm`,`shrink-0`,`h-full`,`focus-visible:relative focus-visible:z-raised`,`mx-0`],{variants:{asChild:{false:[`flex`,`items-center`,`px-lg`]},intent:{neutral:`border-outline`,error:`border-error`,alert:`border-alert`,success:`border-success`},disabled:{true:[`pointer-events-none border-outline!`]},readOnly:{true:[`pointer-events-none`]},design:{text:``,solid:``,inline:``}},compoundVariants:[{disabled:!1,readOnly:!1,design:`text`,class:[`bg-surface`,`text-on-surface`]},{disabled:!0,design:`text`,class:[`text-on-surface/dim-3`]},{disabled:!0,design:[`solid`,`inline`],class:[`opacity-dim-3`]}],defaultVariants:{intent:`neutral`}}),g=({asChild:t,className:n,children:a,ref:o,...s})=>{let{state:c,disabled:l,readOnly:d}=u(),f=typeof a==`string`,p=!!(!f&&t),m=f?a:r.Children.only(a),g=p&&!f?e.Slot:`div`;return(0,i.jsx)(g,{ref:o,"data-spark-component":`input-addon`,className:h({className:n,intent:c,disabled:l,readOnly:d,asChild:p,design:f?`text`:p?`solid`:`inline`}),...l&&{tabIndex:-1},...s,children:m})};g.displayName=`InputGroup.Addon`;var _=({className:e,ref:t,...r})=>{let{disabled:a,readOnly:o}=u();return(0,i.jsx)(`div`,{className:(0,n.cx)(`rounded-l-lg`,a||o?`bg-on-surface/dim-5`:null),children:(0,i.jsx)(g,{ref:t,className:(0,n.cx)(e,`rounded-r-0! mr-[-1px] rounded-l-lg`),...r})})},v=Object.assign(_,{id:`LeadingAddon`});_.displayName=`InputGroup.LeadingAddon`;var y=({className:e,intent:r,children:a,...o})=>{let{disabled:s,readOnly:c}=u();return(0,i.jsx)(t.t,{"data-spark-component":`input-icon`,intent:r,className:(0,n.cx)(e,`pointer-events-none absolute top-[calc(var(--spacing-sz-44)/2)] -translate-y-1/2`,r?void 0:`text-neutral peer-focus:text-outline-high`,s||c?`opacity-dim-3`:void 0),...o,children:a})};y.displayName=`InputGroup.Icon`;var b=({className:e,...t})=>(0,i.jsx)(y,{className:(0,n.cx)(e,`left-lg text-body-1`),...t});b.id=`LeadingIcon`,b.displayName=`InputGroup.LeadingIcon`;var x=({className:e,ref:t,...r})=>{let{disabled:a,readOnly:o}=u();return(0,i.jsx)(`div`,{className:(0,n.cx)(`rounded-r-lg`,a||o?`bg-on-surface/dim-5`:null),children:(0,i.jsx)(g,{ref:t,className:(0,n.cx)(e,`rounded-l-0! ml-[-1px] rounded-r-lg`),...r})})},S=Object.assign(x,{id:`TrailingAddon`});x.displayName=`InputGroup.TrailingAddon`;var C=({className:e,...t})=>(0,i.jsx)(y,{className:(0,n.cx)(e,`right-lg text-body-1`),...t});C.id=`TrailingIcon`,C.displayName=`InputGroup.TrailingIcon`;var w=(0,n.cva)([`relative`,`border-sm`,`peer`,`w-full`,`appearance-none outline-hidden`,`bg-surface`,`text-ellipsis text-body-1 text-on-surface`,`caret-neutral`,`[&:-webkit-autofill]:[-webkit-text-fill-color:var(--color-on-surface)]`,`autofill:shadow-surface autofill:shadow-[inset_0_0_0px_1000px]`,`disabled:cursor-not-allowed disabled:border-outline disabled:bg-on-surface/dim-5 disabled:text-on-surface/dim-3`,`read-only:cursor-default read-only:pointer-events-none read-only:bg-on-surface/dim-5`,`focus:ring-1 focus:ring-inset focus:ring-focus focus:border-focus`],{variants:{asChild:{true:[`min-h-sz-44`],false:[`h-sz-44`]},intent:{neutral:[`border-outline`,`default:hover:border-outline-high`],success:[`default:border-success`],alert:[`default:border-alert`],error:[`default:border-error`]},hasLeadingAddon:{true:[`rounded-l-0`],false:[`rounded-l-lg`]},hasTrailingAddon:{true:[`rounded-r-0`],false:[`rounded-r-lg`]},hasLeadingIcon:{true:[`pl-3xl`],false:[`pl-lg`]},hasTrailingIcon:{true:``},hasClearButton:{true:``}},compoundVariants:[{hasTrailingIcon:!1,hasClearButton:!1,class:`pr-lg`},{hasTrailingIcon:!0,hasClearButton:!1,class:`pr-3xl`},{hasTrailingIcon:!1,hasClearButton:!0,class:`pr-3xl`},{hasTrailingIcon:!0,hasClearButton:!0,class:`pr-[calc(var(--spacing-3xl)*2)]`}],defaultVariants:{intent:`neutral`}}),T=({className:t,asChild:n=!1,onValueChange:r,onChange:a,onKeyDown:s,disabled:c,readOnly:l,ref:d,...f})=>{let p=(0,o.useFormFieldControl)(),m=u(),{id:h,name:g,isInvalid:_,isRequired:v,description:y}=p,{hasLeadingAddon:b,hasTrailingAddon:x,hasLeadingIcon:S,hasTrailingIcon:C,hasClearButton:T,onClear:E}=m,D=n?e.Slot:`input`,O=p.state||m.state,k=p.disabled||m.disabled||c,A=p.readOnly||m.readOnly||l;return(0,i.jsx)(D,{"data-spark-component":`input`,ref:d,id:h,name:g,className:w({asChild:n,className:t,intent:O,hasLeadingAddon:!!b,hasTrailingAddon:!!x,hasLeadingIcon:!!S,hasTrailingIcon:!!C,hasClearButton:!!T}),disabled:k,readOnly:A,required:v,"aria-describedby":y,"aria-invalid":_,onChange:e=>{a&&a(e),r&&r(e.target.value)},onKeyDown:e=>{s&&s(e),T&&E&&e.key===`Escape`&&E()},...f})},E=Object.assign(T,{id:`Input`});T.displayName=`Input`;var D=Object.assign(m,{LeadingAddon:v,TrailingAddon:S,LeadingIcon:b,TrailingIcon:C,ClearButton:f});D.displayName=`InputGroup`,v.displayName=`InputGroup.LeadingAddon`,S.displayName=`InputGroup.TrailingAddon`,b.displayName=`InputGroup.LeadingIcon`,C.displayName=`InputGroup.TrailingIcon`,f.displayName=`InputGroup.ClearButton`,Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return D}});
2
+ //# sourceMappingURL=input-Cx5cfgE8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"input-DaShg4eE.js","names":[],"sources":["../src/input/InputGroupContext.ts","../src/input/InputClearButton.tsx","../src/input/InputGroup.styles.ts","../src/input/InputGroup.tsx","../src/input/InputAddon.styles.ts","../src/input/InputAddon.tsx","../src/input/InputLeadingAddon.tsx","../src/input/InputIcon.tsx","../src/input/InputLeadingIcon.tsx","../src/input/InputTrailingAddon.tsx","../src/input/InputTrailingIcon.tsx","../src/input/Input.styles.ts","../src/input/Input.tsx","../src/input/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface InputGroupContextValue {\n disabled?: boolean\n readOnly?: boolean\n hasLeadingIcon: boolean\n hasTrailingIcon: boolean\n hasLeadingAddon: boolean\n hasTrailingAddon: boolean\n hasClearButton: boolean\n state: null | undefined | 'error' | 'alert' | 'success'\n isStandalone?: boolean\n onClear: () => void\n}\n\nexport const InputGroupContext = createContext<Partial<InputGroupContextValue> | null>(null)\n\nexport const useInputGroup = () => {\n const context = useContext(InputGroupContext)\n\n return context || { isStandalone: true }\n}\n","import { DeleteOutline } from '@spark-ui/icons/DeleteOutline'\nimport { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, MouseEventHandler, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport interface InputClearButtonProps extends ComponentPropsWithoutRef<'button'> {\n 'aria-label': string\n inline?: boolean\n ref?: Ref<HTMLButtonElement>\n}\n\nconst Root = ({\n className,\n tabIndex = -1,\n onClick,\n inline = false,\n ref,\n ...others\n}: InputClearButtonProps) => {\n const { onClear, hasTrailingIcon } = useInputGroup()\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = event => {\n if (onClick) {\n onClick(event)\n }\n\n if (onClear) {\n onClear()\n }\n }\n\n return (\n <button\n ref={ref}\n data-spark-component=\"input-clear-button\"\n className={cx(\n className,\n 'pointer-events-auto absolute',\n inline ? 'h-sz-44 top-0 -translate-y-0' : 'top-1/2 -translate-y-1/2',\n 'inline-flex h-full items-center justify-center outline-hidden',\n 'text-neutral hover:text-neutral-hovered',\n hasTrailingIcon ? 'right-3xl px-sz-12' : 'pl-md pr-lg right-0'\n )}\n tabIndex={tabIndex}\n onClick={handleClick}\n type=\"button\"\n {...others}\n >\n <Icon size=\"sm\">\n <DeleteOutline />\n </Icon>\n </button>\n )\n}\n\nexport const InputClearButton = Object.assign(Root, {\n id: 'ClearButton',\n})\n\nRoot.displayName = 'InputGroup.ClearButton'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputGroupStyles = cva(['relative inline-flex w-full'], {\n variants: {\n /**\n * When `true`, prevents the user from interacting.\n */\n disabled: {\n true: [\n 'cursor-not-allowed',\n 'relative',\n 'after:absolute',\n 'after:top-0',\n 'after:h-full',\n 'after:w-full',\n 'after:border-sm after:border-outline',\n 'after:rounded-lg',\n ],\n false: 'after:hidden',\n },\n /**\n * Sets the component as interactive or not.\n */\n readOnly: {\n true: [\n 'relative',\n 'after:absolute',\n 'after:top-0',\n 'after:h-full',\n 'after:w-full',\n 'after:border-sm after:border-outline',\n 'after:rounded-lg',\n ],\n false: 'after:hidden',\n },\n },\n})\n\nexport type InputGroupStylesProps = VariantProps<typeof inputGroupStyles>\n","/* eslint-disable max-lines-per-function */\n\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport {\n ChangeEventHandler,\n Children,\n cloneElement,\n ComponentPropsWithoutRef,\n DetailedReactHTMLElement,\n FC,\n isValidElement,\n PropsWithChildren,\n ReactElement,\n Ref,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from 'react'\n\nimport { InputProps } from './Input'\nimport { inputGroupStyles, InputGroupStylesProps } from './InputGroup.styles'\nimport { InputGroupContext } from './InputGroupContext'\n\nexport interface InputGroupProps extends ComponentPropsWithoutRef<'div'>, InputGroupStylesProps {\n /**\n * Use `state` prop to assign a specific state to the group, choosing from: `error`, `alert` and `success`. By doing so, the outline styles will be updated.\n */\n state?: 'error' | 'alert' | 'success'\n /**\n * Function handler to be executed after the input has been cleared.\n */\n onClear?: () => void\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputGroup = ({\n className,\n children: childrenProp,\n state: stateProp,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n onClear,\n ref: forwardedRef,\n ...others\n}: PropsWithChildren<InputGroupProps>) => {\n const getElementId = (element?: ReactElement) => {\n return element ? (element.type as FC & { id?: string }).id : ''\n }\n\n const findElement = (...values: string[]) => {\n return children.find(child => values.includes(getElementId(child) || ''))\n }\n\n const children = Children.toArray(childrenProp).filter(isValidElement)\n const input = findElement('Input') as\n | DetailedReactHTMLElement<InputProps, HTMLInputElement>\n | undefined\n const props = input?.props || {}\n\n const inputRef = useRef<HTMLInputElement>(null!)\n const onClearRef = useRef(onClear)\n const ref = useMergeRefs<HTMLInputElement>(input?.ref, inputRef)\n const [value, onChange] = useCombinedState(\n props.value as string,\n props.defaultValue as string,\n props.onValueChange\n )\n\n // Data derivated from FormField context\n const field = useFormFieldControl()\n const state = field.state ?? stateProp\n const disabled = field.disabled || !!disabledProp\n const readOnly = field.readOnly || !!readOnlyProp\n\n // InputGroup elements (in visual order)\n const leadingAddon = findElement('LeadingAddon')\n const leadingIcon = findElement('LeadingIcon')\n const clearButton = findElement('ClearButton')\n const trailingIcon = findElement('TrailingIcon')\n const trailingAddon = findElement('TrailingAddon')\n\n // Acknowledge which subComponents are used in the compound context\n const hasLeadingAddon = !!leadingAddon\n const hasTrailingAddon = !!trailingAddon\n const hasLeadingIcon = !!leadingIcon\n const hasTrailingIcon = !!trailingIcon\n const hasClearButton = !!value && !!clearButton && !disabled && !readOnly\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = event => {\n if (props.onChange) {\n props.onChange(event)\n }\n\n onChange(event.target.value)\n }\n\n const handleClear = useCallback(() => {\n if (onClearRef.current) {\n onClearRef.current()\n }\n\n onChange('')\n\n inputRef.current.focus()\n }, [onChange])\n\n const current = useMemo(() => {\n return {\n state,\n disabled,\n readOnly,\n hasLeadingIcon,\n hasTrailingIcon,\n hasLeadingAddon,\n hasTrailingAddon,\n hasClearButton,\n onClear: handleClear,\n }\n }, [\n state,\n disabled,\n readOnly,\n hasLeadingIcon,\n hasTrailingIcon,\n hasLeadingAddon,\n hasTrailingAddon,\n hasClearButton,\n handleClear,\n ])\n\n useEffect(() => {\n onClearRef.current = onClear\n }, [onClear])\n\n // Preserve the input value when cloning. Some libraries like React Hook Form\n // only expose a ref (via `register`) without direct value access, so we need\n // to manually retrieve the value from the ref to avoid losing it.\n const inputRefValue = inputRef.current?.value\n\n return (\n <InputGroupContext.Provider value={current}>\n <div\n data-spark-component=\"input-group\"\n ref={forwardedRef}\n className={inputGroupStyles({ disabled, readOnly, className })}\n {...others}\n >\n {hasLeadingAddon && leadingAddon}\n\n <div className=\"relative inline-flex w-full\">\n {input &&\n cloneElement(input, {\n value: value ?? inputRefValue ?? '',\n ref,\n defaultValue: undefined,\n onChange: handleChange,\n })}\n\n {leadingIcon}\n\n {hasClearButton && clearButton}\n\n {trailingIcon}\n </div>\n\n {hasTrailingAddon && trailingAddon}\n </div>\n </InputGroupContext.Provider>\n )\n}\n\nInputGroup.displayName = 'InputGroup'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputAddonStyles = cva(\n [\n 'overflow-hidden',\n 'border-sm',\n 'shrink-0',\n 'h-full',\n 'focus-visible:relative focus-visible:z-raised',\n 'mx-0',\n ],\n {\n variants: {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild: { false: ['flex', 'items-center', 'px-lg'] },\n intent: {\n neutral: 'border-outline',\n error: 'border-error',\n alert: 'border-alert',\n success: 'border-success',\n },\n /**\n * Disable the input addon, preventing user interaction and adding opacity.\n */\n disabled: {\n true: ['pointer-events-none border-outline!'],\n },\n /**\n * Changes input addon styles based on the read only status from the input.\n */\n readOnly: {\n true: ['pointer-events-none'],\n },\n /**\n * Main style of the input addon.\n */\n design: {\n text: '',\n solid: '',\n inline: '',\n },\n },\n compoundVariants: [\n {\n disabled: false,\n readOnly: false,\n design: 'text',\n class: ['bg-surface', 'text-on-surface'],\n },\n {\n disabled: true,\n design: 'text',\n class: ['text-on-surface/dim-3'],\n },\n {\n disabled: true,\n design: ['solid', 'inline'],\n class: ['opacity-dim-3'],\n },\n ],\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputAddonStylesProps = VariantProps<typeof inputAddonStyles>\n","import { Children, type ComponentPropsWithoutRef, type PropsWithChildren, Ref } from 'react'\n\nimport { Slot } from '../slot'\nimport { inputAddonStyles, type InputAddonStylesProps } from './InputAddon.styles'\nimport { useInputGroup } from './InputGroupContext'\n\nexport interface InputAddonProps\n extends ComponentPropsWithoutRef<'div'>, Omit<InputAddonStylesProps, 'intent' | 'disabled'> {\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputAddon = ({\n asChild: asChildProp,\n className,\n children,\n ref,\n ...others\n}: PropsWithChildren<InputAddonProps>) => {\n const { state, disabled, readOnly } = useInputGroup()\n\n const isRawText = typeof children === 'string'\n const asChild = !!(isRawText ? false : asChildProp)\n const child = isRawText ? children : Children.only(children)\n const Component = asChild && !isRawText ? Slot : 'div'\n\n const getDesign = (): InputAddonStylesProps['design'] => {\n if (isRawText) return 'text'\n\n return asChild ? 'solid' : 'inline'\n }\n\n const design = getDesign()\n\n return (\n <Component\n ref={ref}\n data-spark-component=\"input-addon\"\n className={inputAddonStyles({\n className,\n intent: state,\n disabled,\n readOnly,\n asChild,\n design,\n })}\n {...(disabled && { tabIndex: -1 })}\n {...others}\n >\n {child}\n </Component>\n )\n}\n\nInputAddon.displayName = 'InputGroup.Addon'\n","import { cx } from 'class-variance-authority'\nimport { Ref } from 'react'\n\nimport { InputAddon, InputAddonProps } from './InputAddon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputLeadingAddonProps = InputAddonProps & {\n ref?: Ref<HTMLDivElement>\n}\n\nconst Root = ({ className, ref, ...others }: InputLeadingAddonProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <div className={cx('rounded-l-lg', isInactive ? 'bg-on-surface/dim-5' : null)}>\n <InputAddon\n ref={ref}\n className={cx(className, 'rounded-r-0! mr-[-1px] rounded-l-lg')}\n {...others}\n />\n </div>\n )\n}\n\nexport const InputLeadingAddon = Object.assign(Root, {\n id: 'LeadingAddon',\n})\n\nRoot.displayName = 'InputGroup.LeadingAddon'\n","import { cx } from 'class-variance-authority'\n\nimport { Icon, type IconProps } from '../icon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputIconProps = IconProps\n\nexport const InputIcon = ({ className, intent, children, ...others }: InputIconProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <Icon\n data-spark-component=\"input-icon\"\n intent={intent}\n className={cx(\n className,\n 'pointer-events-none absolute top-[calc(var(--spacing-sz-44)/2)] -translate-y-1/2',\n intent ? undefined : 'text-neutral peer-focus:text-outline-high',\n isInactive ? 'opacity-dim-3' : undefined\n )}\n {...others}\n >\n {children}\n </Icon>\n )\n}\n\nInputIcon.displayName = 'InputGroup.Icon'\n","import { cx } from 'class-variance-authority'\n\nimport { InputIcon, InputIconProps } from './InputIcon'\n\nexport type InputLeadingIconProps = InputIconProps\n\nexport const InputLeadingIcon = ({ className, ...others }: InputLeadingIconProps) => (\n <InputIcon className={cx(className, 'left-lg text-body-1')} {...others} />\n)\n\nInputLeadingIcon.id = 'LeadingIcon'\nInputLeadingIcon.displayName = 'InputGroup.LeadingIcon'\n","import { cx } from 'class-variance-authority'\nimport { Ref } from 'react'\n\nimport { InputAddon, InputAddonProps } from './InputAddon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputTrailingAddonProps = InputAddonProps & {\n ref?: Ref<HTMLDivElement>\n}\n\nconst Root = ({ className, ref, ...others }: InputTrailingAddonProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <div className={cx('rounded-r-lg', isInactive ? 'bg-on-surface/dim-5' : null)}>\n <InputAddon\n ref={ref}\n className={cx(className, 'rounded-l-0! ml-[-1px] rounded-r-lg')}\n {...others}\n />\n </div>\n )\n}\n\nexport const InputTrailingAddon = Object.assign(Root, {\n id: 'TrailingAddon',\n})\n\nRoot.displayName = 'InputGroup.TrailingAddon'\n","import { cx } from 'class-variance-authority'\n\nimport { InputIcon, InputIconProps } from './InputIcon'\n\nexport type InputTrailingIconProps = InputIconProps\n\nexport const InputTrailingIcon = ({ className, ...others }: InputTrailingIconProps) => (\n <InputIcon className={cx(className, 'right-lg text-body-1')} {...others} />\n)\n\nInputTrailingIcon.id = 'TrailingIcon'\nInputTrailingIcon.displayName = 'InputGroup.TrailingIcon'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputStyles = cva(\n [\n 'relative',\n 'border-sm',\n 'peer',\n 'w-full',\n 'appearance-none outline-hidden',\n 'bg-surface',\n 'text-ellipsis text-body-1 text-on-surface',\n 'caret-neutral',\n '[&:-webkit-autofill]:[-webkit-text-fill-color:var(--color-on-surface)]',\n 'autofill:shadow-surface autofill:shadow-[inset_0_0_0px_1000px]',\n 'disabled:cursor-not-allowed disabled:border-outline disabled:bg-on-surface/dim-5 disabled:text-on-surface/dim-3',\n 'read-only:cursor-default read-only:pointer-events-none read-only:bg-on-surface/dim-5',\n 'focus:ring-1 focus:ring-inset focus:ring-focus focus:border-focus',\n ],\n {\n variants: {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild: {\n true: ['min-h-sz-44'],\n false: ['h-sz-44'],\n },\n /**\n * Color scheme of the button.\n */\n intent: {\n neutral: ['border-outline', 'default:hover:border-outline-high'],\n success: ['default:border-success'],\n alert: ['default:border-alert'],\n error: ['default:border-error'],\n },\n /**\n * Sets if there is an addon before the input text.\n */\n hasLeadingAddon: {\n true: ['rounded-l-0'],\n false: ['rounded-l-lg'],\n },\n /**\n * Sets if there is an addon after the input text.\n */\n hasTrailingAddon: {\n true: ['rounded-r-0'],\n false: ['rounded-r-lg'],\n },\n /**\n * Sets if there is an icon before the input text.\n */\n hasLeadingIcon: {\n true: ['pl-3xl'],\n false: ['pl-lg'],\n },\n /**\n * Sets if there is an icon after the input text.\n */\n hasTrailingIcon: { true: '' },\n /**\n * Sets if there is a button to clear the input text.\n */\n hasClearButton: { true: '' },\n },\n compoundVariants: [\n {\n hasTrailingIcon: false,\n hasClearButton: false,\n class: 'pr-lg',\n },\n {\n hasTrailingIcon: true,\n hasClearButton: false,\n class: 'pr-3xl',\n },\n {\n hasTrailingIcon: false,\n hasClearButton: true,\n class: 'pr-3xl',\n },\n {\n hasTrailingIcon: true,\n hasClearButton: true,\n class: 'pr-[calc(var(--spacing-3xl)*2)]',\n },\n ],\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputStylesProps = VariantProps<typeof inputStyles>\n","import { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { ChangeEventHandler, ComponentPropsWithoutRef, KeyboardEventHandler, Ref } from 'react'\n\nimport { Slot } from '../slot'\nimport { inputStyles } from './Input.styles'\nimport { useInputGroup } from './InputGroupContext'\n\ntype InputPrimitiveProps = ComponentPropsWithoutRef<'input'>\n\nexport interface InputProps extends InputPrimitiveProps {\n asChild?: boolean\n onValueChange?: (value: string) => void\n ref?: Ref<HTMLInputElement>\n}\n\nconst Root = ({\n className,\n asChild = false,\n onValueChange,\n onChange,\n onKeyDown,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n ref,\n ...others\n}: InputProps) => {\n const field = useFormFieldControl()\n const group = useInputGroup()\n\n const { id, name, isInvalid, isRequired, description } = field\n const {\n hasLeadingAddon,\n hasTrailingAddon,\n hasLeadingIcon,\n hasTrailingIcon,\n hasClearButton,\n onClear,\n } = group\n const Component = asChild ? Slot : 'input'\n const state = field.state || group.state\n const disabled = field.disabled || group.disabled || disabledProp\n const readOnly = field.readOnly || group.readOnly || readOnlyProp\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = event => {\n if (onChange) {\n onChange(event)\n }\n\n if (onValueChange) {\n onValueChange(event.target.value)\n }\n }\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = event => {\n if (onKeyDown) {\n onKeyDown(event)\n }\n\n if (hasClearButton && onClear && event.key === 'Escape') {\n onClear()\n }\n }\n\n return (\n <Component\n data-spark-component=\"input\"\n ref={ref}\n id={id}\n name={name}\n className={inputStyles({\n asChild,\n className,\n intent: state,\n hasLeadingAddon: !!hasLeadingAddon,\n hasTrailingAddon: !!hasTrailingAddon,\n hasLeadingIcon: !!hasLeadingIcon,\n hasTrailingIcon: !!hasTrailingIcon,\n hasClearButton: !!hasClearButton,\n })}\n disabled={disabled}\n readOnly={readOnly}\n required={isRequired}\n aria-describedby={description}\n aria-invalid={isInvalid}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...others}\n />\n )\n}\n\n/**\n * A text input field that allows users to enter and edit text content.\n */\nexport const Input = Object.assign(Root, {\n id: 'Input',\n})\n\nRoot.displayName = 'Input'\n","import { InputClearButton } from './InputClearButton'\nimport { InputGroup as Root } from './InputGroup'\nimport { InputLeadingAddon } from './InputLeadingAddon'\nimport { InputLeadingIcon } from './InputLeadingIcon'\nimport { InputTrailingAddon } from './InputTrailingAddon'\nimport { InputTrailingIcon } from './InputTrailingIcon'\n\nexport * from './Input'\n\n/**\n * A wrapper component that combines an Input with addons, icons, and interactive elements\n * to create more complex text input patterns like search bars, password fields, or URL inputs.\n */\nexport const InputGroup: typeof Root & {\n LeadingAddon: typeof InputLeadingAddon\n TrailingAddon: typeof InputTrailingAddon\n LeadingIcon: typeof InputLeadingIcon\n TrailingIcon: typeof InputTrailingIcon\n ClearButton: typeof InputClearButton\n} = Object.assign(Root, {\n LeadingAddon: InputLeadingAddon,\n TrailingAddon: InputTrailingAddon,\n LeadingIcon: InputLeadingIcon,\n TrailingIcon: InputTrailingIcon,\n ClearButton: InputClearButton,\n})\n\nInputGroup.displayName = 'InputGroup'\nInputLeadingAddon.displayName = 'InputGroup.LeadingAddon'\nInputTrailingAddon.displayName = 'InputGroup.TrailingAddon'\nInputLeadingIcon.displayName = 'InputGroup.LeadingIcon'\nInputTrailingIcon.displayName = 'InputGroup.TrailingIcon'\nInputClearButton.displayName = 'InputGroup.ClearButton'\n\nexport { useInputGroup } from './InputGroupContext'\nexport { type InputGroupProps } from './InputGroup'\nexport { type InputLeadingIconProps } from './InputLeadingIcon'\nexport { type InputTrailingIconProps } from './InputTrailingIcon'\nexport { type InputLeadingAddonProps } from './InputLeadingAddon'\nexport { type InputTrailingAddonProps } from './InputTrailingAddon'\nexport { type InputClearButtonProps } from './InputClearButton'\n"],"mappings":"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"}
1
+ {"version":3,"file":"input-Cx5cfgE8.js","names":[],"sources":["../src/input/InputGroupContext.ts","../src/input/InputClearButton.tsx","../src/input/InputGroup.styles.ts","../src/input/InputGroup.tsx","../src/input/InputAddon.styles.ts","../src/input/InputAddon.tsx","../src/input/InputLeadingAddon.tsx","../src/input/InputIcon.tsx","../src/input/InputLeadingIcon.tsx","../src/input/InputTrailingAddon.tsx","../src/input/InputTrailingIcon.tsx","../src/input/Input.styles.ts","../src/input/Input.tsx","../src/input/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface InputGroupContextValue {\n disabled?: boolean\n readOnly?: boolean\n hasLeadingIcon: boolean\n hasTrailingIcon: boolean\n hasLeadingAddon: boolean\n hasTrailingAddon: boolean\n hasClearButton: boolean\n state: null | undefined | 'error' | 'alert' | 'success'\n isStandalone?: boolean\n onClear: () => void\n}\n\nexport const InputGroupContext = createContext<Partial<InputGroupContextValue> | null>(null)\n\nexport const useInputGroup = () => {\n const context = useContext(InputGroupContext)\n\n return context || { isStandalone: true }\n}\n","import { DeleteOutline } from '@spark-ui/icons/DeleteOutline'\nimport { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, MouseEventHandler, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport interface InputClearButtonProps extends ComponentPropsWithoutRef<'button'> {\n 'aria-label': string\n inline?: boolean\n ref?: Ref<HTMLButtonElement>\n}\n\nconst Root = ({\n className,\n tabIndex = -1,\n onClick,\n inline = false,\n ref,\n ...others\n}: InputClearButtonProps) => {\n const { onClear, hasTrailingIcon } = useInputGroup()\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = event => {\n if (onClick) {\n onClick(event)\n }\n\n if (onClear) {\n onClear()\n }\n }\n\n return (\n <button\n ref={ref}\n data-spark-component=\"input-clear-button\"\n className={cx(\n className,\n 'pointer-events-auto absolute',\n inline ? 'h-sz-44 top-0 -translate-y-0' : 'top-1/2 -translate-y-1/2',\n 'inline-flex h-full items-center justify-center outline-hidden',\n 'text-neutral hover:text-neutral-hovered',\n hasTrailingIcon ? 'right-3xl px-sz-12' : 'pl-md pr-lg right-0'\n )}\n tabIndex={tabIndex}\n onClick={handleClick}\n type=\"button\"\n {...others}\n >\n <Icon size=\"sm\">\n <DeleteOutline />\n </Icon>\n </button>\n )\n}\n\nexport const InputClearButton = Object.assign(Root, {\n id: 'ClearButton',\n})\n\nRoot.displayName = 'InputGroup.ClearButton'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputGroupStyles = cva(['relative inline-flex w-full'], {\n variants: {\n /**\n * When `true`, prevents the user from interacting.\n */\n disabled: {\n true: [\n 'cursor-not-allowed',\n 'relative',\n 'after:absolute',\n 'after:top-0',\n 'after:h-full',\n 'after:w-full',\n 'after:border-sm after:border-outline',\n 'after:rounded-lg',\n ],\n false: 'after:hidden',\n },\n /**\n * Sets the component as interactive or not.\n */\n readOnly: {\n true: [\n 'relative',\n 'after:absolute',\n 'after:top-0',\n 'after:h-full',\n 'after:w-full',\n 'after:border-sm after:border-outline',\n 'after:rounded-lg',\n ],\n false: 'after:hidden',\n },\n },\n})\n\nexport type InputGroupStylesProps = VariantProps<typeof inputGroupStyles>\n","/* eslint-disable max-lines-per-function */\n\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport {\n ChangeEventHandler,\n Children,\n cloneElement,\n ComponentPropsWithoutRef,\n DetailedReactHTMLElement,\n FC,\n isValidElement,\n PropsWithChildren,\n ReactElement,\n Ref,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from 'react'\n\nimport { InputProps } from './Input'\nimport { inputGroupStyles, InputGroupStylesProps } from './InputGroup.styles'\nimport { InputGroupContext } from './InputGroupContext'\n\nexport interface InputGroupProps extends ComponentPropsWithoutRef<'div'>, InputGroupStylesProps {\n /**\n * Use `state` prop to assign a specific state to the group, choosing from: `error`, `alert` and `success`. By doing so, the outline styles will be updated.\n */\n state?: 'error' | 'alert' | 'success'\n /**\n * Function handler to be executed after the input has been cleared.\n */\n onClear?: () => void\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputGroup = ({\n className,\n children: childrenProp,\n state: stateProp,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n onClear,\n ref: forwardedRef,\n ...others\n}: PropsWithChildren<InputGroupProps>) => {\n const getElementId = (element?: ReactElement) => {\n return element ? (element.type as FC & { id?: string }).id : ''\n }\n\n const findElement = (...values: string[]) => {\n return children.find(child => values.includes(getElementId(child) || ''))\n }\n\n const children = Children.toArray(childrenProp).filter(isValidElement)\n const input = findElement('Input') as\n | DetailedReactHTMLElement<InputProps, HTMLInputElement>\n | undefined\n const props = input?.props || {}\n\n const inputRef = useRef<HTMLInputElement>(null!)\n const onClearRef = useRef(onClear)\n const ref = useMergeRefs<HTMLInputElement>(input?.ref, inputRef)\n const [value, onChange] = useCombinedState(\n props.value as string,\n props.defaultValue as string,\n props.onValueChange\n )\n\n // Data derivated from FormField context\n const field = useFormFieldControl()\n const state = field.state ?? stateProp\n const disabled = field.disabled || !!disabledProp\n const readOnly = field.readOnly || !!readOnlyProp\n\n // InputGroup elements (in visual order)\n const leadingAddon = findElement('LeadingAddon')\n const leadingIcon = findElement('LeadingIcon')\n const clearButton = findElement('ClearButton')\n const trailingIcon = findElement('TrailingIcon')\n const trailingAddon = findElement('TrailingAddon')\n\n // Acknowledge which subComponents are used in the compound context\n const hasLeadingAddon = !!leadingAddon\n const hasTrailingAddon = !!trailingAddon\n const hasLeadingIcon = !!leadingIcon\n const hasTrailingIcon = !!trailingIcon\n const hasClearButton = !!value && !!clearButton && !disabled && !readOnly\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = event => {\n if (props.onChange) {\n props.onChange(event)\n }\n\n onChange(event.target.value)\n }\n\n const handleClear = useCallback(() => {\n if (onClearRef.current) {\n onClearRef.current()\n }\n\n onChange('')\n\n inputRef.current.focus()\n }, [onChange])\n\n const current = useMemo(() => {\n return {\n state,\n disabled,\n readOnly,\n hasLeadingIcon,\n hasTrailingIcon,\n hasLeadingAddon,\n hasTrailingAddon,\n hasClearButton,\n onClear: handleClear,\n }\n }, [\n state,\n disabled,\n readOnly,\n hasLeadingIcon,\n hasTrailingIcon,\n hasLeadingAddon,\n hasTrailingAddon,\n hasClearButton,\n handleClear,\n ])\n\n useEffect(() => {\n onClearRef.current = onClear\n }, [onClear])\n\n // Preserve the input value when cloning. Some libraries like React Hook Form\n // only expose a ref (via `register`) without direct value access, so we need\n // to manually retrieve the value from the ref to avoid losing it.\n const inputRefValue = inputRef.current?.value\n\n return (\n <InputGroupContext.Provider value={current}>\n <div\n data-spark-component=\"input-group\"\n ref={forwardedRef}\n className={inputGroupStyles({ disabled, readOnly, className })}\n {...others}\n >\n {hasLeadingAddon && leadingAddon}\n\n <div className=\"relative inline-flex w-full\">\n {input &&\n cloneElement(input, {\n value: value ?? inputRefValue ?? '',\n ref,\n defaultValue: undefined,\n onChange: handleChange,\n })}\n\n {leadingIcon}\n\n {hasClearButton && clearButton}\n\n {trailingIcon}\n </div>\n\n {hasTrailingAddon && trailingAddon}\n </div>\n </InputGroupContext.Provider>\n )\n}\n\nInputGroup.displayName = 'InputGroup'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputAddonStyles = cva(\n [\n 'overflow-hidden',\n 'border-sm',\n 'shrink-0',\n 'h-full',\n 'focus-visible:relative focus-visible:z-raised',\n 'mx-0',\n ],\n {\n variants: {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild: { false: ['flex', 'items-center', 'px-lg'] },\n intent: {\n neutral: 'border-outline',\n error: 'border-error',\n alert: 'border-alert',\n success: 'border-success',\n },\n /**\n * Disable the input addon, preventing user interaction and adding opacity.\n */\n disabled: {\n true: ['pointer-events-none border-outline!'],\n },\n /**\n * Changes input addon styles based on the read only status from the input.\n */\n readOnly: {\n true: ['pointer-events-none'],\n },\n /**\n * Main style of the input addon.\n */\n design: {\n text: '',\n solid: '',\n inline: '',\n },\n },\n compoundVariants: [\n {\n disabled: false,\n readOnly: false,\n design: 'text',\n class: ['bg-surface', 'text-on-surface'],\n },\n {\n disabled: true,\n design: 'text',\n class: ['text-on-surface/dim-3'],\n },\n {\n disabled: true,\n design: ['solid', 'inline'],\n class: ['opacity-dim-3'],\n },\n ],\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputAddonStylesProps = VariantProps<typeof inputAddonStyles>\n","import { Children, type ComponentPropsWithoutRef, type PropsWithChildren, Ref } from 'react'\n\nimport { Slot } from '../slot'\nimport { inputAddonStyles, type InputAddonStylesProps } from './InputAddon.styles'\nimport { useInputGroup } from './InputGroupContext'\n\nexport interface InputAddonProps\n extends ComponentPropsWithoutRef<'div'>, Omit<InputAddonStylesProps, 'intent' | 'disabled'> {\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputAddon = ({\n asChild: asChildProp,\n className,\n children,\n ref,\n ...others\n}: PropsWithChildren<InputAddonProps>) => {\n const { state, disabled, readOnly } = useInputGroup()\n\n const isRawText = typeof children === 'string'\n const asChild = !!(isRawText ? false : asChildProp)\n const child = isRawText ? children : Children.only(children)\n const Component = asChild && !isRawText ? Slot : 'div'\n\n const getDesign = (): InputAddonStylesProps['design'] => {\n if (isRawText) return 'text'\n\n return asChild ? 'solid' : 'inline'\n }\n\n const design = getDesign()\n\n return (\n <Component\n ref={ref}\n data-spark-component=\"input-addon\"\n className={inputAddonStyles({\n className,\n intent: state,\n disabled,\n readOnly,\n asChild,\n design,\n })}\n {...(disabled && { tabIndex: -1 })}\n {...others}\n >\n {child}\n </Component>\n )\n}\n\nInputAddon.displayName = 'InputGroup.Addon'\n","import { cx } from 'class-variance-authority'\nimport { Ref } from 'react'\n\nimport { InputAddon, InputAddonProps } from './InputAddon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputLeadingAddonProps = InputAddonProps & {\n ref?: Ref<HTMLDivElement>\n}\n\nconst Root = ({ className, ref, ...others }: InputLeadingAddonProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <div className={cx('rounded-l-lg', isInactive ? 'bg-on-surface/dim-5' : null)}>\n <InputAddon\n ref={ref}\n className={cx(className, 'rounded-r-0! mr-[-1px] rounded-l-lg')}\n {...others}\n />\n </div>\n )\n}\n\nexport const InputLeadingAddon = Object.assign(Root, {\n id: 'LeadingAddon',\n})\n\nRoot.displayName = 'InputGroup.LeadingAddon'\n","import { cx } from 'class-variance-authority'\n\nimport { Icon, type IconProps } from '../icon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputIconProps = IconProps\n\nexport const InputIcon = ({ className, intent, children, ...others }: InputIconProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <Icon\n data-spark-component=\"input-icon\"\n intent={intent}\n className={cx(\n className,\n 'pointer-events-none absolute top-[calc(var(--spacing-sz-44)/2)] -translate-y-1/2',\n intent ? undefined : 'text-neutral peer-focus:text-outline-high',\n isInactive ? 'opacity-dim-3' : undefined\n )}\n {...others}\n >\n {children}\n </Icon>\n )\n}\n\nInputIcon.displayName = 'InputGroup.Icon'\n","import { cx } from 'class-variance-authority'\n\nimport { InputIcon, InputIconProps } from './InputIcon'\n\nexport type InputLeadingIconProps = InputIconProps\n\nexport const InputLeadingIcon = ({ className, ...others }: InputLeadingIconProps) => (\n <InputIcon className={cx(className, 'left-lg text-body-1')} {...others} />\n)\n\nInputLeadingIcon.id = 'LeadingIcon'\nInputLeadingIcon.displayName = 'InputGroup.LeadingIcon'\n","import { cx } from 'class-variance-authority'\nimport { Ref } from 'react'\n\nimport { InputAddon, InputAddonProps } from './InputAddon'\nimport { useInputGroup } from './InputGroupContext'\n\nexport type InputTrailingAddonProps = InputAddonProps & {\n ref?: Ref<HTMLDivElement>\n}\n\nconst Root = ({ className, ref, ...others }: InputTrailingAddonProps) => {\n const { disabled, readOnly } = useInputGroup()\n const isInactive = disabled || readOnly\n\n return (\n <div className={cx('rounded-r-lg', isInactive ? 'bg-on-surface/dim-5' : null)}>\n <InputAddon\n ref={ref}\n className={cx(className, 'rounded-l-0! ml-[-1px] rounded-r-lg')}\n {...others}\n />\n </div>\n )\n}\n\nexport const InputTrailingAddon = Object.assign(Root, {\n id: 'TrailingAddon',\n})\n\nRoot.displayName = 'InputGroup.TrailingAddon'\n","import { cx } from 'class-variance-authority'\n\nimport { InputIcon, InputIconProps } from './InputIcon'\n\nexport type InputTrailingIconProps = InputIconProps\n\nexport const InputTrailingIcon = ({ className, ...others }: InputTrailingIconProps) => (\n <InputIcon className={cx(className, 'right-lg text-body-1')} {...others} />\n)\n\nInputTrailingIcon.id = 'TrailingIcon'\nInputTrailingIcon.displayName = 'InputGroup.TrailingIcon'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputStyles = cva(\n [\n 'relative',\n 'border-sm',\n 'peer',\n 'w-full',\n 'appearance-none outline-hidden',\n 'bg-surface',\n 'text-ellipsis text-body-1 text-on-surface',\n 'caret-neutral',\n '[&:-webkit-autofill]:[-webkit-text-fill-color:var(--color-on-surface)]',\n 'autofill:shadow-surface autofill:shadow-[inset_0_0_0px_1000px]',\n 'disabled:cursor-not-allowed disabled:border-outline disabled:bg-on-surface/dim-5 disabled:text-on-surface/dim-3',\n 'read-only:cursor-default read-only:pointer-events-none read-only:bg-on-surface/dim-5',\n 'focus:ring-1 focus:ring-inset focus:ring-focus focus:border-focus',\n ],\n {\n variants: {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild: {\n true: ['min-h-sz-44'],\n false: ['h-sz-44'],\n },\n /**\n * Color scheme of the button.\n */\n intent: {\n neutral: ['border-outline', 'default:hover:border-outline-high'],\n success: ['default:border-success'],\n alert: ['default:border-alert'],\n error: ['default:border-error'],\n },\n /**\n * Sets if there is an addon before the input text.\n */\n hasLeadingAddon: {\n true: ['rounded-l-0'],\n false: ['rounded-l-lg'],\n },\n /**\n * Sets if there is an addon after the input text.\n */\n hasTrailingAddon: {\n true: ['rounded-r-0'],\n false: ['rounded-r-lg'],\n },\n /**\n * Sets if there is an icon before the input text.\n */\n hasLeadingIcon: {\n true: ['pl-3xl'],\n false: ['pl-lg'],\n },\n /**\n * Sets if there is an icon after the input text.\n */\n hasTrailingIcon: { true: '' },\n /**\n * Sets if there is a button to clear the input text.\n */\n hasClearButton: { true: '' },\n },\n compoundVariants: [\n {\n hasTrailingIcon: false,\n hasClearButton: false,\n class: 'pr-lg',\n },\n {\n hasTrailingIcon: true,\n hasClearButton: false,\n class: 'pr-3xl',\n },\n {\n hasTrailingIcon: false,\n hasClearButton: true,\n class: 'pr-3xl',\n },\n {\n hasTrailingIcon: true,\n hasClearButton: true,\n class: 'pr-[calc(var(--spacing-3xl)*2)]',\n },\n ],\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputStylesProps = VariantProps<typeof inputStyles>\n","import { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { ChangeEventHandler, ComponentPropsWithoutRef, KeyboardEventHandler, Ref } from 'react'\n\nimport { Slot } from '../slot'\nimport { inputStyles } from './Input.styles'\nimport { useInputGroup } from './InputGroupContext'\n\ntype InputPrimitiveProps = ComponentPropsWithoutRef<'input'>\n\nexport interface InputProps extends InputPrimitiveProps {\n asChild?: boolean\n onValueChange?: (value: string) => void\n ref?: Ref<HTMLInputElement>\n}\n\nconst Root = ({\n className,\n asChild = false,\n onValueChange,\n onChange,\n onKeyDown,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n ref,\n ...others\n}: InputProps) => {\n const field = useFormFieldControl()\n const group = useInputGroup()\n\n const { id, name, isInvalid, isRequired, description } = field\n const {\n hasLeadingAddon,\n hasTrailingAddon,\n hasLeadingIcon,\n hasTrailingIcon,\n hasClearButton,\n onClear,\n } = group\n const Component = asChild ? Slot : 'input'\n const state = field.state || group.state\n const disabled = field.disabled || group.disabled || disabledProp\n const readOnly = field.readOnly || group.readOnly || readOnlyProp\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = event => {\n if (onChange) {\n onChange(event)\n }\n\n if (onValueChange) {\n onValueChange(event.target.value)\n }\n }\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = event => {\n if (onKeyDown) {\n onKeyDown(event)\n }\n\n if (hasClearButton && onClear && event.key === 'Escape') {\n onClear()\n }\n }\n\n return (\n <Component\n data-spark-component=\"input\"\n ref={ref}\n id={id}\n name={name}\n className={inputStyles({\n asChild,\n className,\n intent: state,\n hasLeadingAddon: !!hasLeadingAddon,\n hasTrailingAddon: !!hasTrailingAddon,\n hasLeadingIcon: !!hasLeadingIcon,\n hasTrailingIcon: !!hasTrailingIcon,\n hasClearButton: !!hasClearButton,\n })}\n disabled={disabled}\n readOnly={readOnly}\n required={isRequired}\n aria-describedby={description}\n aria-invalid={isInvalid}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...others}\n />\n )\n}\n\n/**\n * A text input field that allows users to enter and edit text content.\n */\nexport const Input = Object.assign(Root, {\n id: 'Input',\n})\n\nRoot.displayName = 'Input'\n","import { InputClearButton } from './InputClearButton'\nimport { InputGroup as Root } from './InputGroup'\nimport { InputLeadingAddon } from './InputLeadingAddon'\nimport { InputLeadingIcon } from './InputLeadingIcon'\nimport { InputTrailingAddon } from './InputTrailingAddon'\nimport { InputTrailingIcon } from './InputTrailingIcon'\n\nexport * from './Input'\n\n/**\n * A wrapper component that combines an Input with addons, icons, and interactive elements\n * to create more complex text input patterns like search bars, password fields, or URL inputs.\n */\nexport const InputGroup: typeof Root & {\n LeadingAddon: typeof InputLeadingAddon\n TrailingAddon: typeof InputTrailingAddon\n LeadingIcon: typeof InputLeadingIcon\n TrailingIcon: typeof InputTrailingIcon\n ClearButton: typeof InputClearButton\n} = Object.assign(Root, {\n LeadingAddon: InputLeadingAddon,\n TrailingAddon: InputTrailingAddon,\n LeadingIcon: InputLeadingIcon,\n TrailingIcon: InputTrailingIcon,\n ClearButton: InputClearButton,\n})\n\nInputGroup.displayName = 'InputGroup'\nInputLeadingAddon.displayName = 'InputGroup.LeadingAddon'\nInputTrailingAddon.displayName = 'InputGroup.TrailingAddon'\nInputLeadingIcon.displayName = 'InputGroup.LeadingIcon'\nInputTrailingIcon.displayName = 'InputGroup.TrailingIcon'\nInputClearButton.displayName = 'InputGroup.ClearButton'\n\nexport { useInputGroup } from './InputGroupContext'\nexport { type InputGroupProps } from './InputGroup'\nexport { type InputLeadingIconProps } from './InputLeadingIcon'\nexport { type InputTrailingIconProps } from './InputTrailingIcon'\nexport { type InputLeadingAddonProps } from './InputLeadingAddon'\nexport { type InputTrailingAddonProps } from './InputTrailingAddon'\nexport { type InputClearButtonProps } from './InputClearButton'\n"],"mappings":"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"}
@@ -1,9 +1,15 @@
1
1
  import { PropsWithChildren, RefObject } from 'react';
2
- import { StepperProps, UseStepperReturn } from './types';
2
+ import { StepperProps } from './types';
3
+ interface StepperContextValue {
4
+ inputRef: RefObject<HTMLInputElement | null>;
5
+ fieldId?: string;
6
+ fieldIsInvalid?: boolean;
7
+ fieldIsRequired?: boolean;
8
+ state?: 'error' | 'alert' | 'success';
9
+ }
3
10
  export declare const Stepper: {
4
- ({ children, formatOptions, minValue, maxValue, ref: forwardedRef, ...stepperProps }: PropsWithChildren<StepperProps>): import("react/jsx-runtime").JSX.Element;
11
+ ({ children, formatOptions, minValue, maxValue, ref: forwardedRef, onValueChange, locale, name: nameProp, ...stepperProps }: PropsWithChildren<StepperProps>): import("react/jsx-runtime").JSX.Element;
5
12
  displayName: string;
6
13
  };
7
- export declare const useStepperContext: () => Omit<UseStepperReturn, "groupProps"> & {
8
- inputRef: RefObject<HTMLInputElement | null>;
9
- };
14
+ export declare const useStepperContext: () => StepperContextValue;
15
+ export {};
@@ -1,14 +1,10 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
  import { StepperButtonProps } from './types';
3
3
  export declare const StepperIncrementButton: {
4
- ({ children, design, intent, className, ref: forwardedRef, ...rest }: PropsWithChildren<StepperButtonProps>): import("react/jsx-runtime").JSX.Element;
4
+ ({ children, design, intent, className, ref: forwardedRef, disabled, ...rest }: PropsWithChildren<StepperButtonProps>): import("react/jsx-runtime").JSX.Element;
5
5
  displayName: string;
6
- } & {
7
- id: string;
8
6
  };
9
7
  export declare const StepperDecrementButton: {
10
- ({ children, design, intent, className, ref: forwardedRef, ...rest }: PropsWithChildren<StepperButtonProps>): import("react/jsx-runtime").JSX.Element;
8
+ ({ children, design, intent, className, ref: forwardedRef, disabled, ...rest }: PropsWithChildren<StepperButtonProps>): import("react/jsx-runtime").JSX.Element;
11
9
  displayName: string;
12
- } & {
13
- id: string;
14
10
  };
@@ -2,6 +2,4 @@ import { StepperInputProps } from './types';
2
2
  export declare const StepperInput: {
3
3
  ({ ref: forwardedRef, ...props }: StepperInputProps): import("react/jsx-runtime").JSX.Element;
4
4
  displayName: string;
5
- } & {
6
- id: string;
7
5
  };
@@ -1,46 +1,49 @@
1
- import { AriaButtonOptions } from '@react-aria/button';
2
- import { NumberFieldAria } from '@react-aria/numberfield';
3
- import { NumberFieldStateOptions } from '@react-stately/numberfield';
4
- import { AriaNumberFieldProps } from '@react-types/numberfield';
5
- import { Ref, RefObject } from 'react';
1
+ import { NumberField } from '@base-ui/react/number-field';
2
+ import { ComponentProps, Ref, RefObject } from 'react';
6
3
  import { IconButtonProps } from '../icon-button';
7
4
  import { InputGroupProps, InputProps } from '../input';
8
- /**
9
- * As we're using React Spectrum library to build this component, we also want
10
- * to build our typing uppon theirs.
11
- * Still, we have to adapt it to avoid exposing useless props.
12
- */
13
- export type StepperButtonProps = Omit<IconButtonProps, 'shape' | 'size' | 'disabled' | 'asChild' | 'isLoading' | 'loadingLabel'> & Omit<AriaButtonOptions<'button'>, 'elementType' | 'href' | 'target' | 'isDisabled' | 'excludeFromTabOrder' | 'aria-label' | 'preventFocusOnPress'> & {
5
+ export type StepperButtonProps = Omit<IconButtonProps, 'shape' | 'size' | 'disabled' | 'asChild' | 'isLoading' | 'loadingLabel'> & {
14
6
  disabled?: boolean;
15
7
  ref?: Ref<HTMLButtonElement>;
16
8
  };
17
- type SpectrumNumberFieldPropsFilter = 'isDisabled' | 'isReadOnly' | 'isRequired' | 'isInvalid' | 'validationState' | 'validationBehavior' | 'validate' | 'label' | 'description' | 'errorMessage' | 'isWheelDisabled' | 'id' | 'onCopy' | 'onCut' | 'onPaste' | 'onCompositionStart' | 'onCompositionEnd' | 'onCompositionUpdate' | 'onSelect' | 'onBeforeInput' | 'onInput';
18
- export interface UseStepperArgs extends Omit<Omit<NumberFieldStateOptions, 'locale'> & Omit<AriaNumberFieldProps, 'incrementAriaLabel' | 'decrementAriaLabel'>, SpectrumNumberFieldPropsFilter> {
9
+ export interface UseStepperArgs extends Omit<ComponentProps<typeof NumberField.Root>, 'render' | 'children' | 'onValueChange' | 'onValueCommitted' | 'allowWheelScrub' | 'allowOutOfRange' | 'snapOnStep' | 'smallStep' | 'largeStep' | 'inputRef' | 'form' | 'min' | 'max' | 'format'> {
19
10
  inputRef: RefObject<HTMLInputElement | null>;
20
11
  /**
21
- * Sets the component as interactive or not.
12
+ * The minimum allowed value.
22
13
  */
23
- disabled?: boolean;
14
+ minValue?: number;
15
+ /**
16
+ * The maximum allowed value.
17
+ */
18
+ maxValue?: number;
24
19
  /**
25
- * Sets the component as editable or not.
20
+ * Formatting options for number display.
26
21
  */
27
- readOnly?: boolean;
22
+ formatOptions?: Intl.NumberFormatOptions;
28
23
  /**
29
- * Sets the component as mandatory for form validation.
24
+ * Callback fired when the value changes.
30
25
  */
31
- required?: boolean;
26
+ onValueChange?: (value: number) => void;
32
27
  /**
33
28
  * The [BCP47](https://www.ietf.org/rfc/bcp/bcp47.txt) language code for the locale.
34
29
  * @default 'fr'
35
30
  */
36
31
  locale?: string;
37
32
  }
38
- export type UseStepperReturn = Pick<NumberFieldAria, 'groupProps' | 'inputProps' | 'incrementButtonProps' | 'decrementButtonProps'>;
39
- export type StepperProps = Omit<Omit<UseStepperArgs, 'inputRef' | 'aria-label'> & Omit<InputGroupProps, 'onClear'>, 'onChange'> & {
40
- onValueChange?: (e: number) => void;
33
+ export interface UseStepperReturn {
34
+ groupProps: ComponentProps<typeof NumberField.Group>;
35
+ inputProps: ComponentProps<typeof NumberField.Input>;
36
+ incrementButtonProps: ComponentProps<typeof NumberField.Increment>;
37
+ decrementButtonProps: ComponentProps<typeof NumberField.Decrement>;
38
+ }
39
+ export type StepperProps = Omit<Omit<UseStepperArgs, 'inputRef'> & Omit<InputGroupProps, 'onClear'>, 'id' | 'name'> & {
41
40
  ref?: Ref<HTMLDivElement>;
41
+ /**
42
+ * The name of the stepper. Submitted with its owning form as part of a name/value pair.
43
+ * If wrapped with a FormField with a name, will be inherited from it.
44
+ */
45
+ name?: string;
42
46
  };
43
47
  export type StepperInputProps = Omit<InputProps, 'asChild'> & {
44
48
  ref?: Ref<HTMLInputElement>;
45
49
  };
46
- export {};
@@ -1,2 +1,2 @@
1
1
  import { UseStepperArgs, UseStepperReturn } from './types';
2
- export declare const useStepper: ({ inputRef, locale, ...rest }: UseStepperArgs) => UseStepperReturn;
2
+ export declare const useStepper: (_args: UseStepperArgs) => UseStepperReturn;
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);const e=require(`../icon-CRPcdgYp.js`),t=require(`../icon-button-CYz_Fitz.js`),n=require(`../input-DaShg4eE.js`);let r=require(`react`),i=require(`react/jsx-runtime`),a=require(`@spark-ui/hooks/use-merge-refs`),o=require(`@spark-ui/components/form-field`),s=require(`@spark-ui/icons/Minus`),c=require(`@react-aria/numberfield`),l=require(`@react-stately/numberfield`),u=require(`@react-aria/button`),d=require(`@spark-ui/icons/Plus`);var f=({inputRef:e,locale:t=`fr`,...n})=>{let r=(0,l.useNumberFieldState)({...n,isDisabled:n.disabled,isReadOnly:n.readOnly,isRequired:n.required,locale:t}),{groupProps:i,inputProps:a,incrementButtonProps:o,decrementButtonProps:s}=(0,c.useNumberField)({isWheelDisabled:!1,...n,isDisabled:n.disabled,isReadOnly:n.readOnly,isRequired:n.required},r,e);return{groupProps:i,inputProps:a,incrementButtonProps:o,decrementButtonProps:s}},p=(0,r.createContext)(null),m=({children:e,formatOptions:t,minValue:a,maxValue:s,ref:c,...l})=>{let u=(0,r.useRef)(null),{groupProps:d,inputProps:m,incrementButtonProps:h,decrementButtonProps:g}=f({...l,...`value`in l&&{value:l.value??NaN},onChange:l.onValueChange,formatOptions:t,minValue:a,maxValue:s,inputRef:u}),_=(0,o.useFormFieldControl)(),v=!!_.id,y={...h,...v&&{"aria-controls":_.id}},b={...g,...v&&{"aria-controls":_.id}},x={...m,...v&&{id:_.id,required:_.isRequired,"aria-invalid":_.isInvalid?!0:void 0}},{onValueChange:S,...C}=l;return(0,i.jsx)(p.Provider,{value:{incrementButtonProps:y,decrementButtonProps:b,inputProps:x,inputRef:u},children:(0,i.jsx)(n.t,{...C,...d,"data-spark-component":`stepper`,ref:c,children:e})})};m.displayName=`Stepper`;var h=()=>{let e=(0,r.useContext)(p);if(!e)throw Error(`useStepperContext must be used within a Stepper provider`);return e},g=({children:a,design:o=`ghost`,intent:s=`neutral`,className:c,ref:l,...f})=>{let p=(0,r.useRef)(null),m=l&&typeof l!=`function`?l:p,{incrementButtonProps:g}=h(),{buttonProps:_}=(0,u.useButton)({...g,...f},m);return(0,i.jsx)(n.t.TrailingAddon,{asChild:!0,"data-spark-component":`stepper-increment-button`,children:(0,i.jsx)(t.t,{ref:m,design:o,intent:s,className:c,"aria-label":_[`aria-label`],..._,disabled:f.disabled||_.disabled,children:a||(0,i.jsx)(e.t,{children:(0,i.jsx)(d.Plus,{})})})})},_=({children:a,design:o=`ghost`,intent:c=`neutral`,className:l,ref:d,...f})=>{let p=(0,r.useRef)(null),m=d&&typeof d!=`function`?d:p,{decrementButtonProps:g}=h(),{buttonProps:_}=(0,u.useButton)({...g,...f},m);return(0,i.jsx)(n.t.LeadingAddon,{asChild:!0,"data-spark-component":`stepper-decrement-button`,children:(0,i.jsx)(t.t,{ref:m,design:o,intent:c,className:l,"aria-label":_[`aria-label`],..._,disabled:f.disabled||_.disabled,children:a||(0,i.jsx)(e.t,{children:(0,i.jsx)(s.Minus,{})})})})},v=Object.assign(g,{id:`TrailingAddon`}),y=Object.assign(_,{id:`LeadingAddon`});g.displayName=`Stepper.DecrementButton`,_.displayName=`Stepper.DecrementButton`;var b=({ref:e,...t})=>{let{inputRef:r,inputProps:o}=h(),s=(0,a.useMergeRefs)(e,r),{className:c=``,...l}=t;return(0,i.jsx)(n.n,{ref:s,...l,...o,className:`min-w-sz-56 text-center ${c}`})},x=Object.assign(b,{id:`Input`});b.displayName=`Stepper.Input`;var S=Object.assign(m,{IncrementButton:v,DecrementButton:y,Input:x});S.displayName=`Stepper`,v.displayName=`Stepper.IncrementButton`,y.displayName=`Stepper.DecrementButton`,x.displayName=`Stepper.Input`,exports.Stepper=S;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);const e=require(`../icon-CRPcdgYp.js`),t=require(`../icon-button-CYz_Fitz.js`),n=require(`../input-Cx5cfgE8.js`);let r=require(`class-variance-authority`),i=require(`react`),a=require(`react/jsx-runtime`),o=require(`@spark-ui/hooks/use-merge-refs`),s=require(`@spark-ui/components/form-field`),c=require(`@spark-ui/icons/Minus`),l=require(`@base-ui/react/number-field`),u=require(`@spark-ui/icons/Plus`);var d=(0,i.createContext)(null),f=({children:e,formatOptions:t,minValue:o,maxValue:c,ref:u,onValueChange:f,locale:p=`fr`,name:m,...h})=>{let g=(0,i.useRef)(null),_=(0,s.useFormFieldControl)(),v=(0,i.useRef)(null),y=_.name??m,b=_.disabled??h.disabled,x=_.readOnly??h.readOnly,S=_.isRequired??h.required,C=e=>{f&&e!==null&&e!==v.current&&(v.current=e,f(e))};return(0,a.jsx)(d.Provider,{value:{inputRef:g,fieldId:_.id,fieldIsInvalid:_.isInvalid,fieldIsRequired:S,state:h.state},children:(0,a.jsx)(l.NumberField.Root,{...h,format:t,min:o,max:c,locale:p,disabled:b,readOnly:x,required:S,name:y,inputRef:g,onValueCommitted:C,"aria-describedby":_.description,children:(0,a.jsx)(`div`,{"data-spark-component":`stepper`,ref:u,className:(0,r.cx)(n.r({disabled:b,readOnly:x}),h.className),children:e})})})};f.displayName=`Stepper`;var p=()=>{let e=(0,i.useContext)(d);if(!e)throw Error(`useStepperContext must be used within a Stepper provider`);return e},m=({children:n,design:i=`ghost`,intent:o=`neutral`,className:s,ref:c,disabled:d,...f})=>{let{fieldId:m,state:h}=p();return(0,a.jsx)(l.NumberField.Increment,{render:l=>{let p=d||`disabled`in l&&l.disabled,g=`readOnly`in l&&l.readOnly;return(0,a.jsx)(`div`,{className:(0,r.cx)(`rounded-r-lg`,p||g?`bg-on-surface/dim-5`:null),"data-spark-component":`stepper-increment-button`,children:(0,a.jsx)(t.t,{ref:c,design:i,intent:o,className:(0,r.cx)(`overflow-hidden border-sm shrink-0 h-full focus-visible:relative focus-visible:z-raised mx-0`,`rounded-l-0! -ml-px rounded-r-lg`,h===`error`&&`border-error`,h===`alert`&&`border-alert`,h===`success`&&`border-success`,!h&&`border-outline`,s),...f,...l,"aria-label":f[`aria-label`]||l[`aria-label`],"aria-controls":m,disabled:p,children:n||(0,a.jsx)(e.t,{children:(0,a.jsx)(u.Plus,{})})})})}})},h=({children:n,design:i=`ghost`,intent:o=`neutral`,className:s,ref:u,disabled:d,...f})=>{let{fieldId:m,state:h}=p();return(0,a.jsx)(l.NumberField.Decrement,{render:l=>{let p=d||`disabled`in l&&l.disabled,g=`readOnly`in l&&l.readOnly;return(0,a.jsx)(`div`,{className:(0,r.cx)(`rounded-l-lg`,p||g?`bg-on-surface/dim-5`:null),"data-spark-component":`stepper-decrement-button`,children:(0,a.jsx)(t.t,{ref:u,design:i,intent:o,className:(0,r.cx)(`overflow-hidden border-sm shrink-0 h-full focus-visible:relative focus-visible:z-raised mx-0`,`rounded-r-0! -mr-px rounded-l-lg`,h===`error`&&`border-error`,h===`alert`&&`border-alert`,h===`success`&&`border-success`,!h&&`border-outline`,s),...f,...l,"aria-label":f[`aria-label`]||l[`aria-label`],"aria-controls":m,disabled:p,children:n||(0,a.jsx)(e.t,{children:(0,a.jsx)(c.Minus,{})})})})}})},g=m,_=h;m.displayName=`Stepper.IncrementButton`,h.displayName=`Stepper.DecrementButton`;var v=({ref:e,...t})=>{let{inputRef:r,fieldId:i,fieldIsInvalid:s,fieldIsRequired:c}=p(),u=(0,o.useMergeRefs)(e,r),{className:d=``,...f}=t;return(0,a.jsx)(`div`,{className:`relative inline-flex w-full`,children:(0,a.jsx)(l.NumberField.Input,{render:e=>{let t;c===void 0?`required`in e&&(t=e.required):t=c;let r=s===void 0?e[`aria-invalid`]:s;return(0,a.jsx)(n.n,{ref:u,...e,...f,id:i||e.id,required:t,"aria-invalid":r,className:`min-w-sz-56 text-center rounded-none! ${d}`})}})})},y=v;v.displayName=`Stepper.Input`;var b=Object.assign(f,{IncrementButton:g,DecrementButton:_,Input:y});b.displayName=`Stepper`,g.displayName=`Stepper.IncrementButton`,_.displayName=`Stepper.DecrementButton`,y.displayName=`Stepper.Input`,exports.Stepper=b;
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/stepper/useStepper.ts","../../src/stepper/Stepper.tsx","../../src/stepper/StepperButton.tsx","../../src/stepper/StepperInput.tsx","../../src/stepper/index.ts"],"sourcesContent":["import { useNumberField } from '@react-aria/numberfield'\nimport { useNumberFieldState } from '@react-stately/numberfield'\n\nimport type { UseStepperArgs, UseStepperReturn } from './types'\n\nexport const useStepper = ({\n inputRef,\n locale = 'fr',\n ...rest\n}: UseStepperArgs): UseStepperReturn => {\n const state = useNumberFieldState({\n ...rest,\n isDisabled: rest.disabled,\n isReadOnly: rest.readOnly,\n isRequired: rest.required,\n locale,\n })\n\n const { groupProps, inputProps, incrementButtonProps, decrementButtonProps } = useNumberField(\n {\n isWheelDisabled: false,\n ...rest,\n isDisabled: rest.disabled,\n isReadOnly: rest.readOnly,\n isRequired: rest.required,\n },\n state,\n inputRef\n )\n\n return {\n groupProps,\n inputProps,\n incrementButtonProps,\n decrementButtonProps,\n }\n}\n","import { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { createContext, type PropsWithChildren, RefObject, useContext, useRef } from 'react'\n\nimport { InputGroup } from '../input'\nimport type { StepperProps, UseStepperReturn } from './types'\nimport { useStepper } from './useStepper'\n\nconst StepperContext = createContext<\n (Omit<UseStepperReturn, 'groupProps'> & { inputRef: RefObject<HTMLInputElement | null> }) | null\n>(null)\n\nexport const Stepper = ({\n children,\n formatOptions,\n minValue,\n maxValue,\n ref: forwardedRef,\n ...stepperProps\n}: PropsWithChildren<StepperProps>) => {\n const inputRef = useRef<HTMLInputElement>(null)\n\n const {\n groupProps,\n inputProps: _inputProps,\n incrementButtonProps: _incrementButtonProps,\n decrementButtonProps: _decrementButtonProps,\n } = useStepper({\n ...{\n ...stepperProps,\n /**\n * To enable the possibility to init the stepper with empty (undefined) value,\n * we need to force the empty value to NaN.\n * Cf. https://github.com/adobe/react-spectrum/issues/5524\n */\n ...('value' in stepperProps && { value: stepperProps.value ?? NaN }),\n onChange: stepperProps.onValueChange,\n },\n formatOptions,\n minValue,\n maxValue,\n inputRef,\n })\n\n const formFieldControlProps = useFormFieldControl()\n const isWrappedInFormField = !!formFieldControlProps.id\n\n const incrementButtonProps = {\n ..._incrementButtonProps,\n ...(isWrappedInFormField && { 'aria-controls': formFieldControlProps.id }),\n }\n\n const decrementButtonProps = {\n ..._decrementButtonProps,\n ...(isWrappedInFormField && { 'aria-controls': formFieldControlProps.id }),\n }\n\n const inputProps = {\n ..._inputProps,\n ...(isWrappedInFormField && {\n id: formFieldControlProps.id,\n required: formFieldControlProps.isRequired,\n 'aria-invalid': formFieldControlProps.isInvalid ? true : undefined,\n }),\n }\n\n const { onValueChange: _, ...remainingStepperProps } = stepperProps\n\n return (\n <StepperContext.Provider\n value={{ incrementButtonProps, decrementButtonProps, inputProps, inputRef }}\n >\n <InputGroup\n {...remainingStepperProps}\n {...groupProps}\n data-spark-component=\"stepper\"\n ref={forwardedRef}\n >\n {children}\n </InputGroup>\n </StepperContext.Provider>\n )\n}\n\nStepper.displayName = 'Stepper'\n\nexport const useStepperContext = () => {\n const context = useContext(StepperContext)\n\n if (!context) {\n throw Error('useStepperContext must be used within a Stepper provider')\n }\n\n return context\n}\n","import { useButton } from '@react-aria/button'\nimport { Minus } from '@spark-ui/icons/Minus'\nimport { Plus } from '@spark-ui/icons/Plus'\nimport { type PropsWithChildren, useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { InputGroup } from '../input'\nimport { useStepperContext } from './Stepper'\nimport type { StepperButtonProps } from './types'\n\nconst IncrementButton = ({\n children,\n design = 'ghost',\n intent = 'neutral',\n className,\n ref: forwardedRef,\n ...rest\n}: PropsWithChildren<StepperButtonProps>) => {\n const innerRef = useRef<HTMLButtonElement>(null)\n const ref = forwardedRef && typeof forwardedRef !== 'function' ? forwardedRef : innerRef\n\n const { incrementButtonProps } = useStepperContext()\n const { buttonProps } = useButton({ ...incrementButtonProps, ...rest }, ref)\n\n return (\n <InputGroup.TrailingAddon asChild data-spark-component=\"stepper-increment-button\">\n <IconButton\n ref={ref}\n design={design}\n intent={intent}\n className={className}\n aria-label={buttonProps['aria-label'] as string}\n {...buttonProps}\n disabled={rest.disabled || buttonProps.disabled}\n >\n {children || (\n <Icon>\n <Plus />\n </Icon>\n )}\n </IconButton>\n </InputGroup.TrailingAddon>\n )\n}\n\nconst DecrementButton = ({\n children,\n design = 'ghost',\n intent = 'neutral',\n className,\n ref: forwardedRef,\n ...rest\n}: PropsWithChildren<StepperButtonProps>) => {\n const innerRef = useRef<HTMLButtonElement>(null)\n const ref = forwardedRef && typeof forwardedRef !== 'function' ? forwardedRef : innerRef\n\n const { decrementButtonProps } = useStepperContext()\n const { buttonProps } = useButton({ ...decrementButtonProps, ...rest }, ref)\n\n return (\n <InputGroup.LeadingAddon asChild data-spark-component=\"stepper-decrement-button\">\n <IconButton\n ref={ref}\n design={design}\n intent={intent}\n className={className}\n aria-label={buttonProps['aria-label'] as string}\n {...buttonProps}\n disabled={rest.disabled || buttonProps.disabled}\n >\n {children || (\n <Icon>\n <Minus />\n </Icon>\n )}\n </IconButton>\n </InputGroup.LeadingAddon>\n )\n}\n\nexport const StepperIncrementButton = Object.assign(IncrementButton, {\n id: 'TrailingAddon',\n})\n\nexport const StepperDecrementButton = Object.assign(DecrementButton, {\n id: 'LeadingAddon',\n})\n\nIncrementButton.displayName = 'Stepper.DecrementButton'\nDecrementButton.displayName = 'Stepper.DecrementButton'\n","import { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\n\nimport { Input as SparkInput } from '../input'\nimport { useStepperContext } from './Stepper'\nimport type { StepperInputProps } from './types'\n\nconst Input = ({ ref: forwardedRef, ...props }: StepperInputProps) => {\n const { inputRef, inputProps } = useStepperContext()\n const ref = useMergeRefs(forwardedRef, inputRef)\n const { className = '', ...remainingProps } = props\n\n return (\n <SparkInput\n ref={ref}\n {...remainingProps}\n {...inputProps}\n className={`min-w-sz-56 text-center ${className}`}\n />\n )\n}\n\nexport const StepperInput = Object.assign(Input, {\n id: 'Input',\n})\n\nInput.displayName = 'Stepper.Input'\n","import { Stepper as Root } from './Stepper'\nimport {\n StepperDecrementButton as DecrementButton,\n StepperIncrementButton as IncrementButton,\n} from './StepperButton'\nimport { StepperInput as Input } from './StepperInput'\n\n/**\n * A numeric input component with increment and decrement buttons for adjusting values.\n */\nexport const Stepper: typeof Root & {\n IncrementButton: typeof IncrementButton\n DecrementButton: typeof DecrementButton\n Input: typeof Input\n} = Object.assign(Root, { IncrementButton, DecrementButton, Input })\n\nStepper.displayName = 'Stepper'\nIncrementButton.displayName = 'Stepper.IncrementButton'\nDecrementButton.displayName = 'Stepper.DecrementButton'\nInput.displayName = 'Stepper.Input'\n\nexport type { StepperProps, StepperButtonProps, StepperInputProps } from './types'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/stepper/Stepper.tsx","../../src/stepper/StepperButton.tsx","../../src/stepper/StepperInput.tsx","../../src/stepper/index.ts"],"sourcesContent":["import { NumberField } from '@base-ui/react/number-field'\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { cx } from 'class-variance-authority'\nimport { createContext, type PropsWithChildren, RefObject, useContext, useRef } from 'react'\n\nimport { inputGroupStyles } from '../input/InputGroup.styles'\nimport type { StepperProps } from './types'\n\ninterface StepperContextValue {\n inputRef: RefObject<HTMLInputElement | null>\n fieldId?: string\n fieldIsInvalid?: boolean\n fieldIsRequired?: boolean\n state?: 'error' | 'alert' | 'success'\n}\n\nconst StepperContext = createContext<StepperContextValue | null>(null)\n\nexport const Stepper = ({\n children,\n formatOptions,\n minValue,\n maxValue,\n ref: forwardedRef,\n onValueChange,\n locale = 'fr',\n name: nameProp,\n ...stepperProps\n}: PropsWithChildren<StepperProps>) => {\n const inputRef = useRef<HTMLInputElement>(null)\n const formFieldControlProps = useFormFieldControl()\n const lastCommittedValueRef = useRef<number | null>(null)\n\n const name = formFieldControlProps.name ?? nameProp\n const disabled = formFieldControlProps.disabled ?? stepperProps.disabled\n const readOnly = formFieldControlProps.readOnly ?? stepperProps.readOnly\n const required = formFieldControlProps.isRequired ?? stepperProps.required\n\n // Base UI calls onValueChange on every keystroke, but react-aria only called it on blur.\n // We use onValueCommitted to preserve the old behavior where onValueChange is only called on blur for input changes,\n // but immediately for button clicks.\n const handleValueCommit = (value: number | null) => {\n if (onValueChange && value !== null && value !== lastCommittedValueRef.current) {\n lastCommittedValueRef.current = value\n onValueChange(value)\n }\n }\n\n return (\n <StepperContext.Provider\n value={{\n inputRef,\n fieldId: formFieldControlProps.id,\n fieldIsInvalid: formFieldControlProps.isInvalid,\n fieldIsRequired: required,\n state: stepperProps.state,\n }}\n >\n <NumberField.Root\n {...stepperProps}\n format={formatOptions}\n min={minValue}\n max={maxValue}\n locale={locale}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n name={name}\n inputRef={inputRef}\n onValueCommitted={handleValueCommit}\n aria-describedby={formFieldControlProps.description}\n >\n <div\n data-spark-component=\"stepper\"\n ref={forwardedRef}\n className={cx(inputGroupStyles({ disabled, readOnly }), stepperProps.className)}\n >\n {children}\n </div>\n </NumberField.Root>\n </StepperContext.Provider>\n )\n}\n\nStepper.displayName = 'Stepper'\n\nexport const useStepperContext = () => {\n const context = useContext(StepperContext)\n\n if (!context) {\n throw Error('useStepperContext must be used within a Stepper provider')\n }\n\n return context\n}\n","import { NumberField } from '@base-ui/react/number-field'\nimport { Minus } from '@spark-ui/icons/Minus'\nimport { Plus } from '@spark-ui/icons/Plus'\nimport { cx } from 'class-variance-authority'\nimport { type PropsWithChildren } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useStepperContext } from './Stepper'\nimport type { StepperButtonProps } from './types'\n\nconst IncrementButton = ({\n children,\n design = 'ghost',\n intent = 'neutral',\n className,\n ref: forwardedRef,\n disabled,\n ...rest\n}: PropsWithChildren<StepperButtonProps>) => {\n const { fieldId, state } = useStepperContext()\n\n return (\n <NumberField.Increment\n render={buttonProps => {\n const isDisabled = disabled || ('disabled' in buttonProps && (buttonProps as any).disabled)\n const isReadOnly = 'readOnly' in buttonProps && (buttonProps as any).readOnly\n const isInactive = isDisabled || isReadOnly\n\n return (\n <div\n className={cx('rounded-r-lg', isInactive ? 'bg-on-surface/dim-5' : null)}\n data-spark-component=\"stepper-increment-button\"\n >\n <IconButton\n ref={forwardedRef}\n design={design}\n intent={intent}\n className={cx(\n 'overflow-hidden border-sm shrink-0 h-full focus-visible:relative focus-visible:z-raised mx-0',\n 'rounded-l-0! -ml-px rounded-r-lg',\n state === 'error' && 'border-error',\n state === 'alert' && 'border-alert',\n state === 'success' && 'border-success',\n !state && 'border-outline',\n className\n )}\n {...rest}\n {...buttonProps}\n aria-label={rest['aria-label'] || (buttonProps['aria-label'] as string)}\n aria-controls={fieldId}\n disabled={isDisabled}\n >\n {children || (\n <Icon>\n <Plus />\n </Icon>\n )}\n </IconButton>\n </div>\n )\n }}\n />\n )\n}\n\nconst DecrementButton = ({\n children,\n design = 'ghost',\n intent = 'neutral',\n className,\n ref: forwardedRef,\n disabled,\n ...rest\n}: PropsWithChildren<StepperButtonProps>) => {\n const { fieldId, state } = useStepperContext()\n\n return (\n <NumberField.Decrement\n render={buttonProps => {\n const isDisabled = disabled || ('disabled' in buttonProps && (buttonProps as any).disabled)\n const isReadOnly = 'readOnly' in buttonProps && (buttonProps as any).readOnly\n const isInactive = isDisabled || isReadOnly\n\n return (\n <div\n className={cx('rounded-l-lg', isInactive ? 'bg-on-surface/dim-5' : null)}\n data-spark-component=\"stepper-decrement-button\"\n >\n <IconButton\n ref={forwardedRef}\n design={design}\n intent={intent}\n className={cx(\n 'overflow-hidden border-sm shrink-0 h-full focus-visible:relative focus-visible:z-raised mx-0',\n 'rounded-r-0! -mr-px rounded-l-lg',\n state === 'error' && 'border-error',\n state === 'alert' && 'border-alert',\n state === 'success' && 'border-success',\n !state && 'border-outline',\n className\n )}\n {...rest}\n {...buttonProps}\n aria-label={rest['aria-label'] || (buttonProps['aria-label'] as string)}\n aria-controls={fieldId}\n disabled={isDisabled}\n >\n {children || (\n <Icon>\n <Minus />\n </Icon>\n )}\n </IconButton>\n </div>\n )\n }}\n />\n )\n}\n\nexport const StepperIncrementButton = IncrementButton\n\nexport const StepperDecrementButton = DecrementButton\n\nIncrementButton.displayName = 'Stepper.IncrementButton'\nDecrementButton.displayName = 'Stepper.DecrementButton'\n","import { NumberField } from '@base-ui/react/number-field'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\n\nimport { Input as SparkInput } from '../input'\nimport { useStepperContext } from './Stepper'\nimport type { StepperInputProps } from './types'\n\nconst Input = ({ ref: forwardedRef, ...props }: StepperInputProps) => {\n const { inputRef, fieldId, fieldIsInvalid, fieldIsRequired } = useStepperContext()\n const ref = useMergeRefs(forwardedRef, inputRef)\n const { className = '', ...remainingProps } = props\n\n return (\n <div className=\"relative inline-flex w-full\">\n <NumberField.Input\n render={inputProps => {\n // Determine required attribute\n let required: boolean | undefined = undefined\n if (fieldIsRequired !== undefined) {\n required = fieldIsRequired\n } else if ('required' in inputProps) {\n required = (inputProps as any).required\n }\n\n // Determine aria-invalid attribute\n const ariaInvalid =\n fieldIsInvalid !== undefined ? fieldIsInvalid : inputProps['aria-invalid']\n\n return (\n <SparkInput\n ref={ref}\n {...inputProps}\n {...remainingProps}\n id={fieldId || inputProps.id}\n required={required}\n aria-invalid={ariaInvalid}\n className={`min-w-sz-56 text-center rounded-none! ${className}`}\n />\n )\n }}\n />\n </div>\n )\n}\n\nexport const StepperInput = Input\n\nInput.displayName = 'Stepper.Input'\n","import { Stepper as Root } from './Stepper'\nimport {\n StepperDecrementButton as DecrementButton,\n StepperIncrementButton as IncrementButton,\n} from './StepperButton'\nimport { StepperInput as Input } from './StepperInput'\n\n/**\n * A numeric input component with increment and decrement buttons for adjusting values.\n */\nexport const Stepper: typeof Root & {\n IncrementButton: typeof IncrementButton\n DecrementButton: typeof DecrementButton\n Input: typeof Input\n} = Object.assign(Root, { IncrementButton, DecrementButton, Input })\n\nStepper.displayName = 'Stepper'\nIncrementButton.displayName = 'Stepper.IncrementButton'\nDecrementButton.displayName = 'Stepper.DecrementButton'\nInput.displayName = 'Stepper.Input'\n\nexport type { StepperProps, StepperButtonProps, StepperInputProps } from './types'\n"],"mappings":"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"}
@@ -1,141 +1,133 @@
1
1
  import { t as e } from "../icon-D05Uqh8_.mjs";
2
2
  import { t } from "../icon-button-DpucUC_L.mjs";
3
- import { n, t as r } from "../input-Dtabf6Mp.mjs";
4
- import { createContext as i, useContext as a, useRef as o } from "react";
5
- import { jsx as s } from "react/jsx-runtime";
6
- import { useMergeRefs as c } from "@spark-ui/hooks/use-merge-refs";
7
- import { useFormFieldControl as l } from "@spark-ui/components/form-field";
8
- import { Minus as u } from "@spark-ui/icons/Minus";
9
- import { useNumberField as d } from "@react-aria/numberfield";
10
- import { useNumberFieldState as f } from "@react-stately/numberfield";
11
- import { useButton as p } from "@react-aria/button";
12
- import { Plus as m } from "@spark-ui/icons/Plus";
13
- //#region src/stepper/useStepper.ts
14
- var h = ({ inputRef: e, locale: t = "fr", ...n }) => {
15
- let r = f({
16
- ...n,
17
- isDisabled: n.disabled,
18
- isReadOnly: n.readOnly,
19
- isRequired: n.required,
20
- locale: t
21
- }), { groupProps: i, inputProps: a, incrementButtonProps: o, decrementButtonProps: s } = d({
22
- isWheelDisabled: !1,
23
- ...n,
24
- isDisabled: n.disabled,
25
- isReadOnly: n.readOnly,
26
- isRequired: n.required
27
- }, r, e);
28
- return {
29
- groupProps: i,
30
- inputProps: a,
31
- incrementButtonProps: o,
32
- decrementButtonProps: s
3
+ import { n, r } from "../input-BIuBpTEq.mjs";
4
+ import { cx as i } from "class-variance-authority";
5
+ import { createContext as a, useContext as o, useRef as s } from "react";
6
+ import { jsx as c } from "react/jsx-runtime";
7
+ import { useMergeRefs as l } from "@spark-ui/hooks/use-merge-refs";
8
+ import { useFormFieldControl as u } from "@spark-ui/components/form-field";
9
+ import { Minus as d } from "@spark-ui/icons/Minus";
10
+ import { NumberField as f } from "@base-ui/react/number-field";
11
+ import { Plus as p } from "@spark-ui/icons/Plus";
12
+ //#region src/stepper/Stepper.tsx
13
+ var m = a(null), h = ({ children: e, formatOptions: t, minValue: n, maxValue: a, ref: o, onValueChange: l, locale: d = "fr", name: p, ...h }) => {
14
+ let g = s(null), _ = u(), v = s(null), y = _.name ?? p, b = _.disabled ?? h.disabled, x = _.readOnly ?? h.readOnly, S = _.isRequired ?? h.required, C = (e) => {
15
+ l && e !== null && e !== v.current && (v.current = e, l(e));
33
16
  };
34
- }, g = i(null), _ = ({ children: e, formatOptions: t, minValue: n, maxValue: i, ref: a, ...c }) => {
35
- let u = o(null), { groupProps: d, inputProps: f, incrementButtonProps: p, decrementButtonProps: m } = h({
36
- ...c,
37
- ..."value" in c && { value: c.value ?? NaN },
38
- onChange: c.onValueChange,
39
- formatOptions: t,
40
- minValue: n,
41
- maxValue: i,
42
- inputRef: u
43
- }), _ = l(), v = !!_.id, y = {
44
- ...p,
45
- ...v && { "aria-controls": _.id }
46
- }, b = {
47
- ...m,
48
- ...v && { "aria-controls": _.id }
49
- }, x = {
50
- ...f,
51
- ...v && {
52
- id: _.id,
53
- required: _.isRequired,
54
- "aria-invalid": _.isInvalid ? !0 : void 0
55
- }
56
- }, { onValueChange: S, ...C } = c;
57
- return /* @__PURE__ */ s(g.Provider, {
17
+ return /* @__PURE__ */ c(m.Provider, {
58
18
  value: {
59
- incrementButtonProps: y,
60
- decrementButtonProps: b,
61
- inputProps: x,
62
- inputRef: u
19
+ inputRef: g,
20
+ fieldId: _.id,
21
+ fieldIsInvalid: _.isInvalid,
22
+ fieldIsRequired: S,
23
+ state: h.state
63
24
  },
64
- children: /* @__PURE__ */ s(r, {
65
- ...C,
66
- ...d,
67
- "data-spark-component": "stepper",
68
- ref: a,
69
- children: e
25
+ children: /* @__PURE__ */ c(f.Root, {
26
+ ...h,
27
+ format: t,
28
+ min: n,
29
+ max: a,
30
+ locale: d,
31
+ disabled: b,
32
+ readOnly: x,
33
+ required: S,
34
+ name: y,
35
+ inputRef: g,
36
+ onValueCommitted: C,
37
+ "aria-describedby": _.description,
38
+ children: /* @__PURE__ */ c("div", {
39
+ "data-spark-component": "stepper",
40
+ ref: o,
41
+ className: i(r({
42
+ disabled: b,
43
+ readOnly: x
44
+ }), h.className),
45
+ children: e
46
+ })
70
47
  })
71
48
  });
72
49
  };
73
- _.displayName = "Stepper";
74
- var v = () => {
75
- let e = a(g);
50
+ h.displayName = "Stepper";
51
+ var g = () => {
52
+ let e = o(m);
76
53
  if (!e) throw Error("useStepperContext must be used within a Stepper provider");
77
54
  return e;
78
- }, y = ({ children: n, design: i = "ghost", intent: a = "neutral", className: c, ref: l, ...u }) => {
79
- let d = o(null), f = l && typeof l != "function" ? l : d, { incrementButtonProps: h } = v(), { buttonProps: g } = p({
80
- ...h,
81
- ...u
82
- }, f);
83
- return /* @__PURE__ */ s(r.TrailingAddon, {
84
- asChild: !0,
85
- "data-spark-component": "stepper-increment-button",
86
- children: /* @__PURE__ */ s(t, {
87
- ref: f,
88
- design: i,
89
- intent: a,
90
- className: c,
91
- "aria-label": g["aria-label"],
92
- ...g,
93
- disabled: u.disabled || g.disabled,
94
- children: n || /* @__PURE__ */ s(e, { children: /* @__PURE__ */ s(m, {}) })
95
- })
96
- });
97
- }, b = ({ children: n, design: i = "ghost", intent: a = "neutral", className: c, ref: l, ...d }) => {
98
- let f = o(null), m = l && typeof l != "function" ? l : f, { decrementButtonProps: h } = v(), { buttonProps: g } = p({
99
- ...h,
100
- ...d
101
- }, m);
102
- return /* @__PURE__ */ s(r.LeadingAddon, {
103
- asChild: !0,
104
- "data-spark-component": "stepper-decrement-button",
105
- children: /* @__PURE__ */ s(t, {
106
- ref: m,
107
- design: i,
108
- intent: a,
109
- className: c,
110
- "aria-label": g["aria-label"],
111
- ...g,
112
- disabled: d.disabled || g.disabled,
113
- children: n || /* @__PURE__ */ s(e, { children: /* @__PURE__ */ s(u, {}) })
114
- })
115
- });
116
- }, x = Object.assign(y, { id: "TrailingAddon" }), S = Object.assign(b, { id: "LeadingAddon" });
117
- y.displayName = "Stepper.DecrementButton", b.displayName = "Stepper.DecrementButton";
55
+ }, _ = ({ children: n, design: r = "ghost", intent: a = "neutral", className: o, ref: s, disabled: l, ...u }) => {
56
+ let { fieldId: d, state: m } = g();
57
+ return /* @__PURE__ */ c(f.Increment, { render: (f) => {
58
+ let h = l || "disabled" in f && f.disabled, g = "readOnly" in f && f.readOnly;
59
+ return /* @__PURE__ */ c("div", {
60
+ className: i("rounded-r-lg", h || g ? "bg-on-surface/dim-5" : null),
61
+ "data-spark-component": "stepper-increment-button",
62
+ children: /* @__PURE__ */ c(t, {
63
+ ref: s,
64
+ design: r,
65
+ intent: a,
66
+ className: i("overflow-hidden border-sm shrink-0 h-full focus-visible:relative focus-visible:z-raised mx-0", "rounded-l-0! -ml-px rounded-r-lg", m === "error" && "border-error", m === "alert" && "border-alert", m === "success" && "border-success", !m && "border-outline", o),
67
+ ...u,
68
+ ...f,
69
+ "aria-label": u["aria-label"] || f["aria-label"],
70
+ "aria-controls": d,
71
+ disabled: h,
72
+ children: n || /* @__PURE__ */ c(e, { children: /* @__PURE__ */ c(p, {}) })
73
+ })
74
+ });
75
+ } });
76
+ }, v = ({ children: n, design: r = "ghost", intent: a = "neutral", className: o, ref: s, disabled: l, ...u }) => {
77
+ let { fieldId: p, state: m } = g();
78
+ return /* @__PURE__ */ c(f.Decrement, { render: (f) => {
79
+ let h = l || "disabled" in f && f.disabled, g = "readOnly" in f && f.readOnly;
80
+ return /* @__PURE__ */ c("div", {
81
+ className: i("rounded-l-lg", h || g ? "bg-on-surface/dim-5" : null),
82
+ "data-spark-component": "stepper-decrement-button",
83
+ children: /* @__PURE__ */ c(t, {
84
+ ref: s,
85
+ design: r,
86
+ intent: a,
87
+ className: i("overflow-hidden border-sm shrink-0 h-full focus-visible:relative focus-visible:z-raised mx-0", "rounded-r-0! -mr-px rounded-l-lg", m === "error" && "border-error", m === "alert" && "border-alert", m === "success" && "border-success", !m && "border-outline", o),
88
+ ...u,
89
+ ...f,
90
+ "aria-label": u["aria-label"] || f["aria-label"],
91
+ "aria-controls": p,
92
+ disabled: h,
93
+ children: n || /* @__PURE__ */ c(e, { children: /* @__PURE__ */ c(d, {}) })
94
+ })
95
+ });
96
+ } });
97
+ }, y = _, b = v;
98
+ _.displayName = "Stepper.IncrementButton", v.displayName = "Stepper.DecrementButton";
118
99
  //#endregion
119
100
  //#region src/stepper/StepperInput.tsx
120
- var C = ({ ref: e, ...t }) => {
121
- let { inputRef: r, inputProps: i } = v(), a = c(e, r), { className: o = "", ...l } = t;
122
- return /* @__PURE__ */ s(n, {
123
- ref: a,
124
- ...l,
125
- ...i,
126
- className: `min-w-sz-56 text-center ${o}`
101
+ var x = ({ ref: e, ...t }) => {
102
+ let { inputRef: r, fieldId: i, fieldIsInvalid: a, fieldIsRequired: o } = g(), s = l(e, r), { className: u = "", ...d } = t;
103
+ return /* @__PURE__ */ c("div", {
104
+ className: "relative inline-flex w-full",
105
+ children: /* @__PURE__ */ c(f.Input, { render: (e) => {
106
+ let t;
107
+ o === void 0 ? "required" in e && (t = e.required) : t = o;
108
+ let r = a === void 0 ? e["aria-invalid"] : a;
109
+ return /* @__PURE__ */ c(n, {
110
+ ref: s,
111
+ ...e,
112
+ ...d,
113
+ id: i || e.id,
114
+ required: t,
115
+ "aria-invalid": r,
116
+ className: `min-w-sz-56 text-center rounded-none! ${u}`
117
+ });
118
+ } })
127
119
  });
128
- }, w = Object.assign(C, { id: "Input" });
129
- C.displayName = "Stepper.Input";
120
+ }, S = x;
121
+ x.displayName = "Stepper.Input";
130
122
  //#endregion
131
123
  //#region src/stepper/index.ts
132
- var T = Object.assign(_, {
133
- IncrementButton: x,
134
- DecrementButton: S,
135
- Input: w
124
+ var C = Object.assign(h, {
125
+ IncrementButton: y,
126
+ DecrementButton: b,
127
+ Input: S
136
128
  });
137
- T.displayName = "Stepper", x.displayName = "Stepper.IncrementButton", S.displayName = "Stepper.DecrementButton", w.displayName = "Stepper.Input";
129
+ C.displayName = "Stepper", y.displayName = "Stepper.IncrementButton", b.displayName = "Stepper.DecrementButton", S.displayName = "Stepper.Input";
138
130
  //#endregion
139
- export { T as Stepper };
131
+ export { C as Stepper };
140
132
 
141
133
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/stepper/useStepper.ts","../../src/stepper/Stepper.tsx","../../src/stepper/StepperButton.tsx","../../src/stepper/StepperInput.tsx","../../src/stepper/index.ts"],"sourcesContent":["import { useNumberField } from '@react-aria/numberfield'\nimport { useNumberFieldState } from '@react-stately/numberfield'\n\nimport type { UseStepperArgs, UseStepperReturn } from './types'\n\nexport const useStepper = ({\n inputRef,\n locale = 'fr',\n ...rest\n}: UseStepperArgs): UseStepperReturn => {\n const state = useNumberFieldState({\n ...rest,\n isDisabled: rest.disabled,\n isReadOnly: rest.readOnly,\n isRequired: rest.required,\n locale,\n })\n\n const { groupProps, inputProps, incrementButtonProps, decrementButtonProps } = useNumberField(\n {\n isWheelDisabled: false,\n ...rest,\n isDisabled: rest.disabled,\n isReadOnly: rest.readOnly,\n isRequired: rest.required,\n },\n state,\n inputRef\n )\n\n return {\n groupProps,\n inputProps,\n incrementButtonProps,\n decrementButtonProps,\n }\n}\n","import { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { createContext, type PropsWithChildren, RefObject, useContext, useRef } from 'react'\n\nimport { InputGroup } from '../input'\nimport type { StepperProps, UseStepperReturn } from './types'\nimport { useStepper } from './useStepper'\n\nconst StepperContext = createContext<\n (Omit<UseStepperReturn, 'groupProps'> & { inputRef: RefObject<HTMLInputElement | null> }) | null\n>(null)\n\nexport const Stepper = ({\n children,\n formatOptions,\n minValue,\n maxValue,\n ref: forwardedRef,\n ...stepperProps\n}: PropsWithChildren<StepperProps>) => {\n const inputRef = useRef<HTMLInputElement>(null)\n\n const {\n groupProps,\n inputProps: _inputProps,\n incrementButtonProps: _incrementButtonProps,\n decrementButtonProps: _decrementButtonProps,\n } = useStepper({\n ...{\n ...stepperProps,\n /**\n * To enable the possibility to init the stepper with empty (undefined) value,\n * we need to force the empty value to NaN.\n * Cf. https://github.com/adobe/react-spectrum/issues/5524\n */\n ...('value' in stepperProps && { value: stepperProps.value ?? NaN }),\n onChange: stepperProps.onValueChange,\n },\n formatOptions,\n minValue,\n maxValue,\n inputRef,\n })\n\n const formFieldControlProps = useFormFieldControl()\n const isWrappedInFormField = !!formFieldControlProps.id\n\n const incrementButtonProps = {\n ..._incrementButtonProps,\n ...(isWrappedInFormField && { 'aria-controls': formFieldControlProps.id }),\n }\n\n const decrementButtonProps = {\n ..._decrementButtonProps,\n ...(isWrappedInFormField && { 'aria-controls': formFieldControlProps.id }),\n }\n\n const inputProps = {\n ..._inputProps,\n ...(isWrappedInFormField && {\n id: formFieldControlProps.id,\n required: formFieldControlProps.isRequired,\n 'aria-invalid': formFieldControlProps.isInvalid ? true : undefined,\n }),\n }\n\n const { onValueChange: _, ...remainingStepperProps } = stepperProps\n\n return (\n <StepperContext.Provider\n value={{ incrementButtonProps, decrementButtonProps, inputProps, inputRef }}\n >\n <InputGroup\n {...remainingStepperProps}\n {...groupProps}\n data-spark-component=\"stepper\"\n ref={forwardedRef}\n >\n {children}\n </InputGroup>\n </StepperContext.Provider>\n )\n}\n\nStepper.displayName = 'Stepper'\n\nexport const useStepperContext = () => {\n const context = useContext(StepperContext)\n\n if (!context) {\n throw Error('useStepperContext must be used within a Stepper provider')\n }\n\n return context\n}\n","import { useButton } from '@react-aria/button'\nimport { Minus } from '@spark-ui/icons/Minus'\nimport { Plus } from '@spark-ui/icons/Plus'\nimport { type PropsWithChildren, useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { InputGroup } from '../input'\nimport { useStepperContext } from './Stepper'\nimport type { StepperButtonProps } from './types'\n\nconst IncrementButton = ({\n children,\n design = 'ghost',\n intent = 'neutral',\n className,\n ref: forwardedRef,\n ...rest\n}: PropsWithChildren<StepperButtonProps>) => {\n const innerRef = useRef<HTMLButtonElement>(null)\n const ref = forwardedRef && typeof forwardedRef !== 'function' ? forwardedRef : innerRef\n\n const { incrementButtonProps } = useStepperContext()\n const { buttonProps } = useButton({ ...incrementButtonProps, ...rest }, ref)\n\n return (\n <InputGroup.TrailingAddon asChild data-spark-component=\"stepper-increment-button\">\n <IconButton\n ref={ref}\n design={design}\n intent={intent}\n className={className}\n aria-label={buttonProps['aria-label'] as string}\n {...buttonProps}\n disabled={rest.disabled || buttonProps.disabled}\n >\n {children || (\n <Icon>\n <Plus />\n </Icon>\n )}\n </IconButton>\n </InputGroup.TrailingAddon>\n )\n}\n\nconst DecrementButton = ({\n children,\n design = 'ghost',\n intent = 'neutral',\n className,\n ref: forwardedRef,\n ...rest\n}: PropsWithChildren<StepperButtonProps>) => {\n const innerRef = useRef<HTMLButtonElement>(null)\n const ref = forwardedRef && typeof forwardedRef !== 'function' ? forwardedRef : innerRef\n\n const { decrementButtonProps } = useStepperContext()\n const { buttonProps } = useButton({ ...decrementButtonProps, ...rest }, ref)\n\n return (\n <InputGroup.LeadingAddon asChild data-spark-component=\"stepper-decrement-button\">\n <IconButton\n ref={ref}\n design={design}\n intent={intent}\n className={className}\n aria-label={buttonProps['aria-label'] as string}\n {...buttonProps}\n disabled={rest.disabled || buttonProps.disabled}\n >\n {children || (\n <Icon>\n <Minus />\n </Icon>\n )}\n </IconButton>\n </InputGroup.LeadingAddon>\n )\n}\n\nexport const StepperIncrementButton = Object.assign(IncrementButton, {\n id: 'TrailingAddon',\n})\n\nexport const StepperDecrementButton = Object.assign(DecrementButton, {\n id: 'LeadingAddon',\n})\n\nIncrementButton.displayName = 'Stepper.DecrementButton'\nDecrementButton.displayName = 'Stepper.DecrementButton'\n","import { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\n\nimport { Input as SparkInput } from '../input'\nimport { useStepperContext } from './Stepper'\nimport type { StepperInputProps } from './types'\n\nconst Input = ({ ref: forwardedRef, ...props }: StepperInputProps) => {\n const { inputRef, inputProps } = useStepperContext()\n const ref = useMergeRefs(forwardedRef, inputRef)\n const { className = '', ...remainingProps } = props\n\n return (\n <SparkInput\n ref={ref}\n {...remainingProps}\n {...inputProps}\n className={`min-w-sz-56 text-center ${className}`}\n />\n )\n}\n\nexport const StepperInput = Object.assign(Input, {\n id: 'Input',\n})\n\nInput.displayName = 'Stepper.Input'\n","import { Stepper as Root } from './Stepper'\nimport {\n StepperDecrementButton as DecrementButton,\n StepperIncrementButton as IncrementButton,\n} from './StepperButton'\nimport { StepperInput as Input } from './StepperInput'\n\n/**\n * A numeric input component with increment and decrement buttons for adjusting values.\n */\nexport const Stepper: typeof Root & {\n IncrementButton: typeof IncrementButton\n DecrementButton: typeof DecrementButton\n Input: typeof Input\n} = Object.assign(Root, { IncrementButton, DecrementButton, Input })\n\nStepper.displayName = 'Stepper'\nIncrementButton.displayName = 'Stepper.IncrementButton'\nDecrementButton.displayName = 'Stepper.DecrementButton'\nInput.displayName = 'Stepper.Input'\n\nexport type { StepperProps, StepperButtonProps, StepperInputProps } from './types'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/stepper/Stepper.tsx","../../src/stepper/StepperButton.tsx","../../src/stepper/StepperInput.tsx","../../src/stepper/index.ts"],"sourcesContent":["import { NumberField } from '@base-ui/react/number-field'\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { cx } from 'class-variance-authority'\nimport { createContext, type PropsWithChildren, RefObject, useContext, useRef } from 'react'\n\nimport { inputGroupStyles } from '../input/InputGroup.styles'\nimport type { StepperProps } from './types'\n\ninterface StepperContextValue {\n inputRef: RefObject<HTMLInputElement | null>\n fieldId?: string\n fieldIsInvalid?: boolean\n fieldIsRequired?: boolean\n state?: 'error' | 'alert' | 'success'\n}\n\nconst StepperContext = createContext<StepperContextValue | null>(null)\n\nexport const Stepper = ({\n children,\n formatOptions,\n minValue,\n maxValue,\n ref: forwardedRef,\n onValueChange,\n locale = 'fr',\n name: nameProp,\n ...stepperProps\n}: PropsWithChildren<StepperProps>) => {\n const inputRef = useRef<HTMLInputElement>(null)\n const formFieldControlProps = useFormFieldControl()\n const lastCommittedValueRef = useRef<number | null>(null)\n\n const name = formFieldControlProps.name ?? nameProp\n const disabled = formFieldControlProps.disabled ?? stepperProps.disabled\n const readOnly = formFieldControlProps.readOnly ?? stepperProps.readOnly\n const required = formFieldControlProps.isRequired ?? stepperProps.required\n\n // Base UI calls onValueChange on every keystroke, but react-aria only called it on blur.\n // We use onValueCommitted to preserve the old behavior where onValueChange is only called on blur for input changes,\n // but immediately for button clicks.\n const handleValueCommit = (value: number | null) => {\n if (onValueChange && value !== null && value !== lastCommittedValueRef.current) {\n lastCommittedValueRef.current = value\n onValueChange(value)\n }\n }\n\n return (\n <StepperContext.Provider\n value={{\n inputRef,\n fieldId: formFieldControlProps.id,\n fieldIsInvalid: formFieldControlProps.isInvalid,\n fieldIsRequired: required,\n state: stepperProps.state,\n }}\n >\n <NumberField.Root\n {...stepperProps}\n format={formatOptions}\n min={minValue}\n max={maxValue}\n locale={locale}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n name={name}\n inputRef={inputRef}\n onValueCommitted={handleValueCommit}\n aria-describedby={formFieldControlProps.description}\n >\n <div\n data-spark-component=\"stepper\"\n ref={forwardedRef}\n className={cx(inputGroupStyles({ disabled, readOnly }), stepperProps.className)}\n >\n {children}\n </div>\n </NumberField.Root>\n </StepperContext.Provider>\n )\n}\n\nStepper.displayName = 'Stepper'\n\nexport const useStepperContext = () => {\n const context = useContext(StepperContext)\n\n if (!context) {\n throw Error('useStepperContext must be used within a Stepper provider')\n }\n\n return context\n}\n","import { NumberField } from '@base-ui/react/number-field'\nimport { Minus } from '@spark-ui/icons/Minus'\nimport { Plus } from '@spark-ui/icons/Plus'\nimport { cx } from 'class-variance-authority'\nimport { type PropsWithChildren } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useStepperContext } from './Stepper'\nimport type { StepperButtonProps } from './types'\n\nconst IncrementButton = ({\n children,\n design = 'ghost',\n intent = 'neutral',\n className,\n ref: forwardedRef,\n disabled,\n ...rest\n}: PropsWithChildren<StepperButtonProps>) => {\n const { fieldId, state } = useStepperContext()\n\n return (\n <NumberField.Increment\n render={buttonProps => {\n const isDisabled = disabled || ('disabled' in buttonProps && (buttonProps as any).disabled)\n const isReadOnly = 'readOnly' in buttonProps && (buttonProps as any).readOnly\n const isInactive = isDisabled || isReadOnly\n\n return (\n <div\n className={cx('rounded-r-lg', isInactive ? 'bg-on-surface/dim-5' : null)}\n data-spark-component=\"stepper-increment-button\"\n >\n <IconButton\n ref={forwardedRef}\n design={design}\n intent={intent}\n className={cx(\n 'overflow-hidden border-sm shrink-0 h-full focus-visible:relative focus-visible:z-raised mx-0',\n 'rounded-l-0! -ml-px rounded-r-lg',\n state === 'error' && 'border-error',\n state === 'alert' && 'border-alert',\n state === 'success' && 'border-success',\n !state && 'border-outline',\n className\n )}\n {...rest}\n {...buttonProps}\n aria-label={rest['aria-label'] || (buttonProps['aria-label'] as string)}\n aria-controls={fieldId}\n disabled={isDisabled}\n >\n {children || (\n <Icon>\n <Plus />\n </Icon>\n )}\n </IconButton>\n </div>\n )\n }}\n />\n )\n}\n\nconst DecrementButton = ({\n children,\n design = 'ghost',\n intent = 'neutral',\n className,\n ref: forwardedRef,\n disabled,\n ...rest\n}: PropsWithChildren<StepperButtonProps>) => {\n const { fieldId, state } = useStepperContext()\n\n return (\n <NumberField.Decrement\n render={buttonProps => {\n const isDisabled = disabled || ('disabled' in buttonProps && (buttonProps as any).disabled)\n const isReadOnly = 'readOnly' in buttonProps && (buttonProps as any).readOnly\n const isInactive = isDisabled || isReadOnly\n\n return (\n <div\n className={cx('rounded-l-lg', isInactive ? 'bg-on-surface/dim-5' : null)}\n data-spark-component=\"stepper-decrement-button\"\n >\n <IconButton\n ref={forwardedRef}\n design={design}\n intent={intent}\n className={cx(\n 'overflow-hidden border-sm shrink-0 h-full focus-visible:relative focus-visible:z-raised mx-0',\n 'rounded-r-0! -mr-px rounded-l-lg',\n state === 'error' && 'border-error',\n state === 'alert' && 'border-alert',\n state === 'success' && 'border-success',\n !state && 'border-outline',\n className\n )}\n {...rest}\n {...buttonProps}\n aria-label={rest['aria-label'] || (buttonProps['aria-label'] as string)}\n aria-controls={fieldId}\n disabled={isDisabled}\n >\n {children || (\n <Icon>\n <Minus />\n </Icon>\n )}\n </IconButton>\n </div>\n )\n }}\n />\n )\n}\n\nexport const StepperIncrementButton = IncrementButton\n\nexport const StepperDecrementButton = DecrementButton\n\nIncrementButton.displayName = 'Stepper.IncrementButton'\nDecrementButton.displayName = 'Stepper.DecrementButton'\n","import { NumberField } from '@base-ui/react/number-field'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\n\nimport { Input as SparkInput } from '../input'\nimport { useStepperContext } from './Stepper'\nimport type { StepperInputProps } from './types'\n\nconst Input = ({ ref: forwardedRef, ...props }: StepperInputProps) => {\n const { inputRef, fieldId, fieldIsInvalid, fieldIsRequired } = useStepperContext()\n const ref = useMergeRefs(forwardedRef, inputRef)\n const { className = '', ...remainingProps } = props\n\n return (\n <div className=\"relative inline-flex w-full\">\n <NumberField.Input\n render={inputProps => {\n // Determine required attribute\n let required: boolean | undefined = undefined\n if (fieldIsRequired !== undefined) {\n required = fieldIsRequired\n } else if ('required' in inputProps) {\n required = (inputProps as any).required\n }\n\n // Determine aria-invalid attribute\n const ariaInvalid =\n fieldIsInvalid !== undefined ? fieldIsInvalid : inputProps['aria-invalid']\n\n return (\n <SparkInput\n ref={ref}\n {...inputProps}\n {...remainingProps}\n id={fieldId || inputProps.id}\n required={required}\n aria-invalid={ariaInvalid}\n className={`min-w-sz-56 text-center rounded-none! ${className}`}\n />\n )\n }}\n />\n </div>\n )\n}\n\nexport const StepperInput = Input\n\nInput.displayName = 'Stepper.Input'\n","import { Stepper as Root } from './Stepper'\nimport {\n StepperDecrementButton as DecrementButton,\n StepperIncrementButton as IncrementButton,\n} from './StepperButton'\nimport { StepperInput as Input } from './StepperInput'\n\n/**\n * A numeric input component with increment and decrement buttons for adjusting values.\n */\nexport const Stepper: typeof Root & {\n IncrementButton: typeof IncrementButton\n DecrementButton: typeof DecrementButton\n Input: typeof Input\n} = Object.assign(Root, { IncrementButton, DecrementButton, Input })\n\nStepper.displayName = 'Stepper'\nIncrementButton.displayName = 'Stepper.IncrementButton'\nDecrementButton.displayName = 'Stepper.DecrementButton'\nInput.displayName = 'Stepper.Input'\n\nexport type { StepperProps, StepperButtonProps, StepperInputProps } from './types'\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);const e=require(`../input-DaShg4eE.js`);let t=require(`class-variance-authority`),n=require(`react/jsx-runtime`);var r=t=>(0,n.jsx)(e.t.ClearButton,{inline:!0,"data-spark-component":`textarea-group-trailing-icon`,...t});r.id=e.t.ClearButton.id,r.displayName=`TextareaGroup.ClearButton`;var i=t=>(0,n.jsx)(e.t,{...t});i.displayName=`TextareaGroup`;var a=t=>(0,n.jsx)(e.t.LeadingIcon,{"data-spark-component":`textarea-group-leading-icon`,...t});a.id=e.t.LeadingIcon.id,a.displayName=`TextareaGroup.LeadingIcon`;var o=t=>(0,n.jsx)(e.t.TrailingIcon,{"data-spark-component":`textarea-group-trailing-icon`,...t});o.id=e.t.TrailingIcon.id,o.displayName=`TextareaGroup.TrailingIcon`;var s=({className:r,disabled:i,rows:a=1,isResizable:o=!0,ref:s,onValueChange:c,...l})=>(0,n.jsx)(e.n,{className:(0,t.cx)(r,`py-[var(--spacing-sz-10)]`,o?`resize-y`:`resize-none`),"data-spark-component":`textarea`,disabled:i,asChild:!0,onValueChange:c,children:(0,n.jsx)(`textarea`,{ref:s,rows:a,...l})}),c=Object.assign(s,{id:e.n.id});s.displayName=`Textarea`;var l=Object.assign(i,{LeadingIcon:a,TrailingIcon:o,ClearButton:r});l.displayName=`TextareaGroup`,a.displayName=`TextareaGroup.LeadingIcon`,o.displayName=`TextareaGroup.TrailingIcon`,r.displayName=`TextareaGroup.ClearButton`,exports.Textarea=c,exports.TextareaGroup=l;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);const e=require(`../input-Cx5cfgE8.js`);let t=require(`class-variance-authority`),n=require(`react/jsx-runtime`);var r=t=>(0,n.jsx)(e.t.ClearButton,{inline:!0,"data-spark-component":`textarea-group-trailing-icon`,...t});r.id=e.t.ClearButton.id,r.displayName=`TextareaGroup.ClearButton`;var i=t=>(0,n.jsx)(e.t,{...t});i.displayName=`TextareaGroup`;var a=t=>(0,n.jsx)(e.t.LeadingIcon,{"data-spark-component":`textarea-group-leading-icon`,...t});a.id=e.t.LeadingIcon.id,a.displayName=`TextareaGroup.LeadingIcon`;var o=t=>(0,n.jsx)(e.t.TrailingIcon,{"data-spark-component":`textarea-group-trailing-icon`,...t});o.id=e.t.TrailingIcon.id,o.displayName=`TextareaGroup.TrailingIcon`;var s=({className:r,disabled:i,rows:a=1,isResizable:o=!0,ref:s,onValueChange:c,...l})=>(0,n.jsx)(e.n,{className:(0,t.cx)(r,`py-[var(--spacing-sz-10)]`,o?`resize-y`:`resize-none`),"data-spark-component":`textarea`,disabled:i,asChild:!0,onValueChange:c,children:(0,n.jsx)(`textarea`,{ref:s,rows:a,...l})}),c=Object.assign(s,{id:e.n.id});s.displayName=`Textarea`;var l=Object.assign(i,{LeadingIcon:a,TrailingIcon:o,ClearButton:r});l.displayName=`TextareaGroup`,a.displayName=`TextareaGroup.LeadingIcon`,o.displayName=`TextareaGroup.TrailingIcon`,r.displayName=`TextareaGroup.ClearButton`,exports.Textarea=c,exports.TextareaGroup=l;
2
2
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { n as e, t } from "../input-Dtabf6Mp.mjs";
1
+ import { n as e, t } from "../input-BIuBpTEq.mjs";
2
2
  import { cx as n } from "class-variance-authority";
3
3
  import { jsx as r } from "react/jsx-runtime";
4
4
  //#region src/textarea/TextareaClearButton.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spark-ui/components",
3
- "version": "17.5.6-beta.0",
3
+ "version": "17.5.6-beta.2",
4
4
  "license": "MIT",
5
5
  "description": "Spark (Leboncoin design system) components.",
6
6
  "exports": {
@@ -48,29 +48,24 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "@base-ui/react": "1.0.0",
51
- "@react-aria/button": "3.13.0",
52
- "@react-aria/numberfield": "3.11.13",
53
- "@react-aria/toast": "^3.0.0-beta.18",
54
- "@react-stately/numberfield": "3.9.11",
55
- "@react-stately/toast": "^3.0.0-beta.7",
56
- "@spark-ui/hooks": "^17.5.6-beta.0",
57
- "@spark-ui/icons": "^17.5.6-beta.0",
58
- "@spark-ui/internal-utils": "^17.5.6-beta.0",
51
+ "@spark-ui/hooks": "17.5.6-beta.2",
52
+ "@spark-ui/icons": "17.5.6-beta.2",
53
+ "@spark-ui/internal-utils": "17.5.6-beta.2",
59
54
  "@zag-js/pagination": "1.30.0",
60
55
  "@zag-js/react": "1.30.0",
61
56
  "class-variance-authority": "0.7.1",
62
- "downshift": "9.0.10",
63
- "emulate-tab": "^1.2.1",
64
- "motion": "^12.34.3",
57
+ "downshift": "9.0.13",
58
+ "emulate-tab": "1.2.1",
59
+ "motion": "12.34.5",
65
60
  "radix-ui": "1.4.3",
66
- "react-aria-components": "^1.15.0",
67
- "react-snap-carousel": "^0.5.1"
61
+ "react-aria-components": "1.15.1",
62
+ "react-snap-carousel": "0.5.1"
68
63
  },
69
64
  "peerDependencies": {
70
- "@spark-ui/theme-utils": "17.5.6-beta.0",
71
- "react": "^19.1.1",
72
- "react-dom": "^19.1.1",
73
- "tailwindcss": "^4.1.13"
65
+ "@spark-ui/theme-utils": "17.5.6-beta.2",
66
+ "react": "19.2.4",
67
+ "react-dom": "19.2.4",
68
+ "tailwindcss": "4.1.18"
74
69
  },
75
70
  "devDependencies": {
76
71
  "jsdom-testing-mocks": "1.16.0"