asterui 0.12.24 → 0.12.26

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
- {"version":3,"file":"index43.js","sources":["../src/components/Input.tsx"],"sourcesContent":["import React, { forwardRef, useState, useCallback, useRef, useEffect } from 'react'\n\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix'> {\n type?: 'text' | 'password' | 'email' | 'number' | 'date' | 'datetime-local' | 'week' | 'month' | 'tel' | 'url' | 'search' | 'time'\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n color?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'\n /** Validation status */\n status?: 'error' | 'warning'\n ghost?: boolean\n bordered?: boolean\n className?: string\n /** Input mask pattern. Use # for digits, A for letters, * for alphanumeric */\n mask?: string\n /** Placeholder character shown in mask (default: _) */\n maskPlaceholder?: string\n /** Show clear button when input has value */\n allowClear?: boolean | { clearIcon?: React.ReactNode }\n /** Callback when clear button is clicked */\n onClear?: () => void\n /** Prefix icon or element (inside input) */\n prefix?: React.ReactNode\n /** Suffix icon or element (inside input) */\n suffix?: React.ReactNode\n /** Text/element before input (outside, using DaisyUI label) */\n addonBefore?: React.ReactNode\n /** Text/element after input (outside, using DaisyUI label) */\n addonAfter?: React.ReactNode\n /** Floating label text (uses DaisyUI floating-label) */\n floatingLabel?: string\n /** ID for error message element (for aria-describedby) */\n errorId?: string\n /** Render as unstyled input (for use inside styled wrappers) */\n unstyled?: boolean\n}\n\n// Helper to apply mask to raw value\nfunction applyMask(raw: string, mask: string, placeholder: string): string {\n let result = ''\n let rawIndex = 0\n\n for (let i = 0; i < mask.length && rawIndex <= raw.length; i++) {\n const maskChar = mask[i]\n if (maskChar === '#' || maskChar === 'A' || maskChar === '*') {\n if (rawIndex < raw.length) {\n result += raw[rawIndex]\n rawIndex++\n } else {\n result += placeholder\n }\n } else {\n result += maskChar\n }\n }\n\n return result\n}\n\n// Extract raw value from masked input\nfunction extractRaw(value: string, mask: string, placeholder: string): string {\n let raw = ''\n for (let i = 0; i < value.length && i < mask.length; i++) {\n const maskChar = mask[i]\n if ((maskChar === '#' || maskChar === 'A' || maskChar === '*') && value[i] !== placeholder) {\n raw += value[i]\n }\n }\n return raw\n}\n\n// Check if character is valid for mask position\nfunction isValidChar(char: string, maskChar: string): boolean {\n if (maskChar === '#') return /\\d/.test(char)\n if (maskChar === 'A') return /[a-zA-Z]/.test(char)\n if (maskChar === '*') return /[a-zA-Z0-9]/.test(char)\n return false\n}\n\n// Find next input position in mask\nfunction findNextInputPosition(mask: string, fromIndex: number): number {\n for (let i = fromIndex; i < mask.length; i++) {\n if (mask[i] === '#' || mask[i] === 'A' || mask[i] === '*') {\n return i\n }\n }\n return mask.length\n}\n\n// Clear icon component\nconst ClearIcon: React.FC<{ onClick: () => void; className?: string }> = ({ onClick, className }) => (\n <button\n type=\"button\"\n onClick={onClick}\n className={`flex items-center justify-center opacity-50 hover:opacity-100 transition-opacity ${className || ''}`}\n aria-label=\"Clear input\"\n tabIndex={-1}\n >\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n)\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n type = 'text',\n size,\n color,\n status,\n ghost = false,\n bordered = true,\n className = '',\n mask,\n maskPlaceholder = '_',\n allowClear,\n onClear,\n prefix,\n suffix,\n addonBefore,\n addonAfter,\n floatingLabel,\n errorId,\n unstyled = false,\n value,\n defaultValue,\n onChange,\n onKeyDown,\n disabled,\n required,\n ...props\n },\n ref\n ) => {\n const sizeClasses = {\n xs: 'input-xs',\n sm: 'input-sm',\n md: 'input-md',\n lg: 'input-lg',\n xl: 'input-xl',\n }\n\n const colorClasses = {\n neutral: 'input-neutral',\n primary: 'input-primary',\n secondary: 'input-secondary',\n accent: 'input-accent',\n info: 'input-info',\n success: 'input-success',\n warning: 'input-warning',\n error: 'input-error',\n }\n\n const statusClasses = {\n error: 'input-error',\n warning: 'input-warning',\n }\n\n // Status takes precedence over color for validation feedback\n const effectiveColorClass = status ? statusClasses[status] : (color ? colorClasses[color] : '')\n\n // When wrapped with external addons OR unstyled prop, the wrapper has the input styling\n // Inner input should be unstyled (grow to fill space)\n const hasExternalAddons = addonBefore || addonAfter\n const shouldBeUnstyled = hasExternalAddons || unstyled\n\n const inputClasses = shouldBeUnstyled\n ? ['grow', 'bg-transparent', 'border-0', 'outline-none', 'focus:outline-none', className].filter(Boolean).join(' ')\n : [\n 'input',\n !bordered && 'border-0',\n ghost && 'input-ghost',\n size && sizeClasses[size],\n effectiveColorClass,\n className,\n ].filter(Boolean).join(' ')\n\n // Mask handling\n const innerRef = useRef<HTMLInputElement>(null)\n const inputRef = (ref as React.RefObject<HTMLInputElement>) || innerRef\n\n const getInitialRaw = useCallback(() => {\n if (!mask) return ''\n const initial = (value ?? defaultValue ?? '') as string\n return extractRaw(initial, mask, maskPlaceholder)\n }, [mask, value, defaultValue, maskPlaceholder])\n\n const [rawValue, setRawValue] = useState(getInitialRaw)\n const [cursorPos, setCursorPos] = useState<number | null>(null)\n\n // Sync with controlled value\n useEffect(() => {\n if (mask && value !== undefined) {\n setRawValue(extractRaw(value as string, mask, maskPlaceholder))\n }\n }, [mask, value, maskPlaceholder])\n\n // Set cursor position after render\n useEffect(() => {\n if (cursorPos !== null && inputRef.current) {\n inputRef.current.setSelectionRange(cursorPos, cursorPos)\n setCursorPos(null)\n }\n }, [cursorPos, inputRef])\n\n const handleMaskedChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!mask) {\n onChange?.(e)\n return\n }\n\n const input = e.target\n const inputValue = input.value\n\n // Extract what the user is trying to type\n const newRaw = extractRaw(inputValue, mask, maskPlaceholder)\n\n // Filter to only valid characters\n let filteredRaw = ''\n let rawIdx = 0\n for (let i = 0; i < mask.length && rawIdx < newRaw.length; i++) {\n const maskChar = mask[i]\n if (maskChar === '#' || maskChar === 'A' || maskChar === '*') {\n if (isValidChar(newRaw[rawIdx], maskChar)) {\n filteredRaw += newRaw[rawIdx]\n }\n rawIdx++\n }\n }\n\n setRawValue(filteredRaw)\n\n // Calculate new cursor position\n const maskedValue = applyMask(filteredRaw, mask, maskPlaceholder)\n let newCursor = findNextInputPosition(mask, 0)\n let charsPlaced = 0\n for (let i = 0; i < mask.length; i++) {\n const maskChar = mask[i]\n if (maskChar === '#' || maskChar === 'A' || maskChar === '*') {\n if (charsPlaced < filteredRaw.length) {\n charsPlaced++\n newCursor = i + 1\n }\n }\n }\n // Skip to next input position if we're on a literal\n newCursor = findNextInputPosition(mask, newCursor)\n if (newCursor > mask.length) newCursor = mask.length\n\n setCursorPos(newCursor)\n\n // Create synthetic event with masked value\n const syntheticEvent = {\n ...e,\n target: { ...input, value: maskedValue },\n currentTarget: { ...input, value: maskedValue },\n } as React.ChangeEvent<HTMLInputElement>\n\n onChange?.(syntheticEvent)\n },\n [mask, maskPlaceholder, onChange]\n )\n\n const handleMaskedKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (!mask) {\n onKeyDown?.(e)\n return\n }\n\n if (e.key === 'Backspace') {\n e.preventDefault()\n const newRaw = rawValue.slice(0, -1)\n setRawValue(newRaw)\n\n // Calculate cursor position\n let newCursor = 0\n let charsPlaced = 0\n for (let i = 0; i < mask.length; i++) {\n const maskChar = mask[i]\n if (maskChar === '#' || maskChar === 'A' || maskChar === '*') {\n if (charsPlaced < newRaw.length) {\n charsPlaced++\n newCursor = i + 1\n } else {\n newCursor = i\n break\n }\n }\n }\n setCursorPos(newCursor)\n\n const maskedValue = applyMask(newRaw, mask, maskPlaceholder)\n const input = e.currentTarget\n const syntheticEvent = {\n target: { ...input, value: maskedValue },\n currentTarget: { ...input, value: maskedValue },\n } as unknown as React.ChangeEvent<HTMLInputElement>\n\n onChange?.(syntheticEvent)\n }\n\n onKeyDown?.(e)\n },\n [mask, maskPlaceholder, rawValue, onChange, onKeyDown]\n )\n\n // Track internal value for allowClear visibility\n const [internalValue, setInternalValue] = useState((value ?? defaultValue ?? '') as string)\n\n // Sync internal value with controlled value\n useEffect(() => {\n if (value !== undefined) {\n setInternalValue(value as string)\n }\n }, [value])\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n setInternalValue(e.target.value)\n onChange?.(e)\n }, [onChange])\n\n const handleClear = useCallback(() => {\n setInternalValue('')\n setRawValue('')\n onClear?.()\n // Create synthetic event for onChange\n if (onChange && inputRef.current) {\n const syntheticEvent = {\n target: { ...inputRef.current, value: '' },\n currentTarget: { ...inputRef.current, value: '' },\n } as React.ChangeEvent<HTMLInputElement>\n onChange(syntheticEvent)\n }\n }, [onClear, onChange, inputRef])\n\n // Determine if we should show clear button\n const currentValue = mask ? rawValue : internalValue\n const showClear = allowClear && currentValue && !disabled\n\n // Get custom clear icon if provided\n const clearIcon = typeof allowClear === 'object' && allowClear.clearIcon\n ? allowClear.clearIcon\n : null\n\n // Accessibility attributes\n const ariaProps: Record<string, string | boolean | undefined> = {}\n if (status === 'error') {\n ariaProps['aria-invalid'] = true\n }\n if (errorId) {\n ariaProps['aria-describedby'] = errorId\n }\n if (required) {\n ariaProps['aria-required'] = true\n }\n\n // If we have prefix, suffix, or allowClear, wrap in a container\n const hasInternalAddons = prefix || suffix || allowClear\n\n // Size class for floating label\n const floatingSizeClasses = {\n xs: 'input-xs',\n sm: 'input-sm',\n md: 'input-md',\n lg: 'input-lg',\n xl: 'input-xl',\n }\n\n // Build the masked value if needed\n const maskedValue = mask ? applyMask(rawValue, mask, maskPlaceholder) : undefined\n\n // Build the core input element\n const buildInput = (extraClasses?: string) => (\n <input\n ref={inputRef}\n type={mask ? 'text' : type}\n className={[\n inputClasses,\n hasInternalAddons && 'w-full',\n prefix && 'pl-10',\n (suffix || showClear) && 'pr-10',\n extraClasses,\n ].filter(Boolean).join(' ')}\n value={maskedValue ?? (value !== undefined ? value : (hasInternalAddons ? internalValue : value))}\n defaultValue={value === undefined && !mask ? defaultValue : undefined}\n onChange={mask ? handleMaskedChange : (hasInternalAddons ? handleChange : onChange)}\n onKeyDown={mask ? handleMaskedKeyDown : onKeyDown}\n disabled={disabled}\n required={required}\n {...ariaProps}\n {...props}\n />\n )\n\n // Build input with internal addons (prefix icon, suffix icon, clear button)\n const buildInputWithInternalAddons = (extraClasses?: string) => {\n if (!hasInternalAddons) {\n return buildInput(extraClasses)\n }\n\n return (\n <div className={`relative flex items-center ${extraClasses || ''}`}>\n {prefix && (\n <span className=\"absolute left-3 flex items-center text-base-content/70 pointer-events-none z-10\">\n {prefix}\n </span>\n )}\n {buildInput()}\n {(suffix || showClear) && (\n <span className=\"absolute right-3 flex items-center gap-1 z-10\">\n {showClear && (clearIcon || <ClearIcon onClick={handleClear} />)}\n {suffix && <span className=\"text-base-content/70\">{suffix}</span>}\n </span>\n )}\n </div>\n )\n }\n\n // Wrap with floating label if specified\n const wrapWithFloatingLabel = (input: React.ReactNode) => {\n if (!floatingLabel) return input\n\n const floatingClasses = [\n 'floating-label',\n size && floatingSizeClasses[size],\n ].filter(Boolean).join(' ')\n\n return (\n <label className={floatingClasses}>\n {input}\n <span>{floatingLabel}</span>\n </label>\n )\n }\n\n // Wrap with external addons (addonBefore/addonAfter) using DaisyUI input wrapper pattern\n const wrapWithExternalAddons = (input: React.ReactNode) => {\n if (!hasExternalAddons) return input\n\n const addonClasses = [\n 'input',\n 'input-bordered',\n 'flex',\n 'items-center',\n 'gap-2',\n size && sizeClasses[size],\n effectiveColorClass,\n ].filter(Boolean).join(' ')\n\n return (\n <label className={addonClasses}>\n {addonBefore && <span className=\"text-base-content/70\">{addonBefore}</span>}\n {input}\n {addonAfter && <span className=\"text-base-content/70\">{addonAfter}</span>}\n </label>\n )\n }\n\n // Build the final element\n const inputElement = buildInputWithInternalAddons(\n floatingLabel ? 'input input-bordered w-full' : undefined\n )\n\n // Apply wrappers\n return wrapWithExternalAddons(wrapWithFloatingLabel(\n floatingLabel ? (\n // For floating label, use raw input (label wrapper provides styling)\n <input\n ref={inputRef}\n type={mask ? 'text' : type}\n className=\"input input-bordered w-full\"\n value={maskedValue ?? (value !== undefined ? value : internalValue)}\n defaultValue={value === undefined && !mask ? defaultValue : undefined}\n onChange={mask ? handleMaskedChange : handleChange}\n onKeyDown={mask ? handleMaskedKeyDown : onKeyDown}\n disabled={disabled}\n required={required}\n {...ariaProps}\n {...props}\n />\n ) : inputElement\n ))\n }\n)\n\nInput.displayName = 'Input'\n"],"names":["applyMask","raw","mask","placeholder","result","rawIndex","i","maskChar","extractRaw","value","isValidChar","char","findNextInputPosition","fromIndex","ClearIcon","onClick","className","jsx","Input","forwardRef","type","size","color","status","ghost","bordered","maskPlaceholder","allowClear","onClear","prefix","suffix","addonBefore","addonAfter","floatingLabel","errorId","unstyled","defaultValue","onChange","onKeyDown","disabled","required","props","ref","sizeClasses","effectiveColorClass","hasExternalAddons","inputClasses","innerRef","useRef","inputRef","getInitialRaw","useCallback","rawValue","setRawValue","useState","cursorPos","setCursorPos","useEffect","handleMaskedChange","e","input","inputValue","newRaw","filteredRaw","rawIdx","maskedValue","newCursor","charsPlaced","syntheticEvent","handleMaskedKeyDown","internalValue","setInternalValue","handleChange","handleClear","showClear","clearIcon","ariaProps","hasInternalAddons","floatingSizeClasses","buildInput","extraClasses","buildInputWithInternalAddons","jsxs","wrapWithFloatingLabel","floatingClasses","wrapWithExternalAddons","addonClasses","inputElement"],"mappings":"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"}
1
+ {"version":3,"file":"index43.js","sources":["../src/components/Input.tsx"],"sourcesContent":["import React, { forwardRef, useState, useCallback, useRef, useEffect } from 'react'\n\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix'> {\n type?: 'text' | 'password' | 'email' | 'number' | 'date' | 'datetime-local' | 'week' | 'month' | 'tel' | 'url' | 'search' | 'time'\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n color?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'\n /** Validation status */\n status?: 'error' | 'warning'\n ghost?: boolean\n bordered?: boolean\n className?: string\n /** Input mask pattern. Use # for digits, A for letters, * for alphanumeric */\n mask?: string\n /** Placeholder character shown in mask (default: _) */\n maskPlaceholder?: string\n /** Show clear button when input has value */\n allowClear?: boolean | { clearIcon?: React.ReactNode }\n /** Callback when clear button is clicked */\n onClear?: () => void\n /** Prefix icon or element (inside input) */\n prefix?: React.ReactNode\n /** Suffix icon or element (inside input) */\n suffix?: React.ReactNode\n /** Text/element before input (outside, using DaisyUI label) */\n addonBefore?: React.ReactNode\n /** Text/element after input (outside, using DaisyUI label) */\n addonAfter?: React.ReactNode\n /** Floating label text (uses DaisyUI floating-label) */\n floatingLabel?: string\n /** ID for error message element (for aria-describedby) */\n errorId?: string\n /** Render as unstyled input (for use inside styled wrappers) */\n unstyled?: boolean\n}\n\n// Helper to apply mask to raw value\nfunction applyMask(raw: string, mask: string, placeholder: string): string {\n let result = ''\n let rawIndex = 0\n\n for (let i = 0; i < mask.length && rawIndex <= raw.length; i++) {\n const maskChar = mask[i]\n if (maskChar === '#' || maskChar === 'A' || maskChar === '*') {\n if (rawIndex < raw.length) {\n result += raw[rawIndex]\n rawIndex++\n } else {\n result += placeholder\n }\n } else {\n result += maskChar\n }\n }\n\n return result\n}\n\n// Extract raw value from masked input\nfunction extractRaw(value: string, mask: string, placeholder: string): string {\n let raw = ''\n for (let i = 0; i < value.length && i < mask.length; i++) {\n const maskChar = mask[i]\n if ((maskChar === '#' || maskChar === 'A' || maskChar === '*') && value[i] !== placeholder) {\n raw += value[i]\n }\n }\n return raw\n}\n\n// Check if character is valid for mask position\nfunction isValidChar(char: string, maskChar: string): boolean {\n if (maskChar === '#') return /\\d/.test(char)\n if (maskChar === 'A') return /[a-zA-Z]/.test(char)\n if (maskChar === '*') return /[a-zA-Z0-9]/.test(char)\n return false\n}\n\n// Find next input position in mask\nfunction findNextInputPosition(mask: string, fromIndex: number): number {\n for (let i = fromIndex; i < mask.length; i++) {\n if (mask[i] === '#' || mask[i] === 'A' || mask[i] === '*') {\n return i\n }\n }\n return mask.length\n}\n\n// Clear icon component\nconst ClearIcon: React.FC<{ onClick: () => void; className?: string }> = ({ onClick, className }) => (\n <button\n type=\"button\"\n onClick={onClick}\n className={`flex items-center justify-center opacity-50 hover:opacity-100 transition-opacity ${className || ''}`}\n aria-label=\"Clear input\"\n tabIndex={-1}\n >\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n)\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n type = 'text',\n size,\n color,\n status,\n ghost = false,\n bordered = true,\n className = '',\n mask,\n maskPlaceholder = '_',\n allowClear,\n onClear,\n prefix,\n suffix,\n addonBefore,\n addonAfter,\n floatingLabel,\n errorId,\n unstyled = false,\n value,\n defaultValue,\n onChange,\n onKeyDown,\n disabled,\n required,\n ...props\n },\n ref\n ) => {\n const sizeClasses = {\n xs: 'input-xs',\n sm: 'input-sm',\n md: 'input-md',\n lg: 'input-lg',\n xl: 'input-xl',\n }\n\n const colorClasses = {\n neutral: 'input-neutral',\n primary: 'input-primary',\n secondary: 'input-secondary',\n accent: 'input-accent',\n info: 'input-info',\n success: 'input-success',\n warning: 'input-warning',\n error: 'input-error',\n }\n\n const statusClasses = {\n error: 'input-error',\n warning: 'input-warning',\n }\n\n // Status takes precedence over color for validation feedback\n const effectiveColorClass = status ? statusClasses[status] : (color ? colorClasses[color] : '')\n\n // When wrapped with external addons OR unstyled prop, the wrapper has the input styling\n // Inner input should be unstyled (grow to fill space)\n const hasExternalAddons = addonBefore || addonAfter\n const shouldBeUnstyled = hasExternalAddons || unstyled\n\n const inputClasses = shouldBeUnstyled\n ? ['grow', 'bg-transparent', 'border-0', 'outline-none', 'focus:outline-none', className].filter(Boolean).join(' ')\n : [\n 'input',\n !bordered && 'border-0',\n ghost && 'input-ghost',\n size && sizeClasses[size],\n effectiveColorClass,\n className,\n ].filter(Boolean).join(' ')\n\n // Mask handling\n const innerRef = useRef<HTMLInputElement>(null)\n const inputRef = (ref as React.RefObject<HTMLInputElement>) || innerRef\n\n const getInitialRaw = useCallback(() => {\n if (!mask) return ''\n const initial = (value ?? defaultValue ?? '') as string\n return extractRaw(initial, mask, maskPlaceholder)\n }, [mask, value, defaultValue, maskPlaceholder])\n\n const [rawValue, setRawValue] = useState(getInitialRaw)\n const [cursorPos, setCursorPos] = useState<number | null>(null)\n\n // Sync with controlled value\n useEffect(() => {\n if (mask && value !== undefined) {\n setRawValue(extractRaw(value as string, mask, maskPlaceholder))\n }\n }, [mask, value, maskPlaceholder])\n\n // Set cursor position after render\n useEffect(() => {\n if (cursorPos !== null && inputRef.current) {\n inputRef.current.setSelectionRange(cursorPos, cursorPos)\n setCursorPos(null)\n }\n }, [cursorPos, inputRef])\n\n const handleMaskedChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!mask) {\n onChange?.(e)\n return\n }\n\n const input = e.target\n const inputValue = input.value\n\n // Extract what the user is trying to type\n const newRaw = extractRaw(inputValue, mask, maskPlaceholder)\n\n // Filter to only valid characters\n let filteredRaw = ''\n let rawIdx = 0\n for (let i = 0; i < mask.length && rawIdx < newRaw.length; i++) {\n const maskChar = mask[i]\n if (maskChar === '#' || maskChar === 'A' || maskChar === '*') {\n if (isValidChar(newRaw[rawIdx], maskChar)) {\n filteredRaw += newRaw[rawIdx]\n }\n rawIdx++\n }\n }\n\n setRawValue(filteredRaw)\n\n // Calculate new cursor position\n const maskedValue = applyMask(filteredRaw, mask, maskPlaceholder)\n let newCursor = findNextInputPosition(mask, 0)\n let charsPlaced = 0\n for (let i = 0; i < mask.length; i++) {\n const maskChar = mask[i]\n if (maskChar === '#' || maskChar === 'A' || maskChar === '*') {\n if (charsPlaced < filteredRaw.length) {\n charsPlaced++\n newCursor = i + 1\n }\n }\n }\n // Skip to next input position if we're on a literal\n newCursor = findNextInputPosition(mask, newCursor)\n if (newCursor > mask.length) newCursor = mask.length\n\n setCursorPos(newCursor)\n\n // Create synthetic event with masked value\n const syntheticEvent = {\n ...e,\n target: { ...input, value: maskedValue },\n currentTarget: { ...input, value: maskedValue },\n } as React.ChangeEvent<HTMLInputElement>\n\n onChange?.(syntheticEvent)\n },\n [mask, maskPlaceholder, onChange]\n )\n\n const handleMaskedKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (!mask) {\n onKeyDown?.(e)\n return\n }\n\n if (e.key === 'Backspace') {\n e.preventDefault()\n const newRaw = rawValue.slice(0, -1)\n setRawValue(newRaw)\n\n // Calculate cursor position\n let newCursor = 0\n let charsPlaced = 0\n for (let i = 0; i < mask.length; i++) {\n const maskChar = mask[i]\n if (maskChar === '#' || maskChar === 'A' || maskChar === '*') {\n if (charsPlaced < newRaw.length) {\n charsPlaced++\n newCursor = i + 1\n } else {\n newCursor = i\n break\n }\n }\n }\n setCursorPos(newCursor)\n\n const maskedValue = applyMask(newRaw, mask, maskPlaceholder)\n const input = e.currentTarget\n const syntheticEvent = {\n target: { ...input, value: maskedValue },\n currentTarget: { ...input, value: maskedValue },\n } as unknown as React.ChangeEvent<HTMLInputElement>\n\n onChange?.(syntheticEvent)\n }\n\n onKeyDown?.(e)\n },\n [mask, maskPlaceholder, rawValue, onChange, onKeyDown]\n )\n\n // Track internal value for allowClear visibility\n const [internalValue, setInternalValue] = useState((value ?? defaultValue ?? '') as string)\n\n // Sync internal value with controlled value\n useEffect(() => {\n if (value !== undefined) {\n setInternalValue(value as string)\n }\n }, [value])\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n setInternalValue(e.target.value)\n onChange?.(e)\n }, [onChange])\n\n const handleClear = useCallback(() => {\n setInternalValue('')\n setRawValue('')\n onClear?.()\n // Create synthetic event for onChange\n if (onChange && inputRef.current) {\n const syntheticEvent = {\n target: { ...inputRef.current, value: '' },\n currentTarget: { ...inputRef.current, value: '' },\n } as React.ChangeEvent<HTMLInputElement>\n onChange(syntheticEvent)\n }\n }, [onClear, onChange, inputRef])\n\n // Determine if we should show clear button\n const currentValue = mask ? rawValue : internalValue\n const showClear = allowClear && currentValue && !disabled\n\n // Get custom clear icon if provided\n const clearIcon = typeof allowClear === 'object' && allowClear.clearIcon\n ? allowClear.clearIcon\n : null\n\n // Accessibility attributes\n const ariaProps: Record<string, string | boolean | undefined> = {}\n if (status === 'error') {\n ariaProps['aria-invalid'] = true\n }\n if (errorId) {\n ariaProps['aria-describedby'] = errorId\n }\n if (required) {\n ariaProps['aria-required'] = true\n }\n\n // If we have prefix, suffix, or allowClear, wrap in a container\n const hasInternalAddons = prefix || suffix || allowClear\n\n // Size class for floating label\n const floatingSizeClasses = {\n xs: 'input-xs',\n sm: 'input-sm',\n md: 'input-md',\n lg: 'input-lg',\n xl: 'input-xl',\n }\n\n // Build the masked value if needed\n const maskedValue = mask ? applyMask(rawValue, mask, maskPlaceholder) : undefined\n\n // Build the core input element\n const buildInput = (extraClasses?: string) => (\n <input\n ref={inputRef}\n type={mask ? 'text' : type}\n className={[\n inputClasses,\n hasInternalAddons && 'w-full',\n prefix && 'pl-10',\n (suffix || showClear) && 'pr-10',\n extraClasses,\n ].filter(Boolean).join(' ')}\n value={maskedValue ?? (value !== undefined ? value : (hasInternalAddons ? internalValue : value))}\n defaultValue={value === undefined && !mask ? defaultValue : undefined}\n onChange={mask ? handleMaskedChange : (hasInternalAddons ? handleChange : onChange)}\n onKeyDown={mask ? handleMaskedKeyDown : onKeyDown}\n disabled={disabled}\n required={required}\n {...ariaProps}\n {...props}\n />\n )\n\n // Build input with internal addons (prefix icon, suffix icon, clear button)\n const buildInputWithInternalAddons = (extraClasses?: string) => {\n if (!hasInternalAddons) {\n return buildInput(extraClasses)\n }\n\n return (\n <div className={`relative flex items-center ${extraClasses || ''}`}>\n {prefix && (\n <span className=\"absolute left-3 flex items-center text-base-content/70 pointer-events-none z-10\">\n {prefix}\n </span>\n )}\n {buildInput()}\n {(suffix || showClear) && (\n <span className=\"absolute right-3 flex items-center gap-1 z-10\">\n {showClear && (clearIcon || <ClearIcon onClick={handleClear} />)}\n {suffix && <span className=\"text-base-content/70\">{suffix}</span>}\n </span>\n )}\n </div>\n )\n }\n\n // Wrap with floating label if specified\n const wrapWithFloatingLabel = (input: React.ReactNode) => {\n if (!floatingLabel) return input\n\n const floatingClasses = [\n 'floating-label',\n size && floatingSizeClasses[size],\n ].filter(Boolean).join(' ')\n\n return (\n <label className={floatingClasses}>\n {input}\n <span>{floatingLabel}</span>\n </label>\n )\n }\n\n // Wrap with external addons (addonBefore/addonAfter) using DaisyUI input wrapper pattern\n const wrapWithExternalAddons = (input: React.ReactNode) => {\n if (!hasExternalAddons) return input\n\n const addonClasses = [\n 'input',\n 'flex',\n 'items-center',\n 'gap-2',\n size && sizeClasses[size],\n effectiveColorClass,\n ].filter(Boolean).join(' ')\n\n return (\n <label className={addonClasses}>\n {addonBefore && <span className=\"text-base-content/70\">{addonBefore}</span>}\n {input}\n {addonAfter && <span className=\"text-base-content/70\">{addonAfter}</span>}\n </label>\n )\n }\n\n // Build the final element\n const inputElement = buildInputWithInternalAddons(\n floatingLabel ? 'input w-full' : undefined\n )\n\n // Apply wrappers\n return wrapWithExternalAddons(wrapWithFloatingLabel(\n floatingLabel ? (\n // For floating label, use raw input (label wrapper provides styling)\n <input\n ref={inputRef}\n type={mask ? 'text' : type}\n className=\"input w-full\"\n value={maskedValue ?? (value !== undefined ? value : internalValue)}\n defaultValue={value === undefined && !mask ? defaultValue : undefined}\n onChange={mask ? handleMaskedChange : handleChange}\n onKeyDown={mask ? handleMaskedKeyDown : onKeyDown}\n disabled={disabled}\n required={required}\n {...ariaProps}\n {...props}\n />\n ) : inputElement\n ))\n }\n)\n\nInput.displayName = 'Input'\n"],"names":["applyMask","raw","mask","placeholder","result","rawIndex","i","maskChar","extractRaw","value","isValidChar","char","findNextInputPosition","fromIndex","ClearIcon","onClick","className","jsx","Input","forwardRef","type","size","color","status","ghost","bordered","maskPlaceholder","allowClear","onClear","prefix","suffix","addonBefore","addonAfter","floatingLabel","errorId","unstyled","defaultValue","onChange","onKeyDown","disabled","required","props","ref","sizeClasses","effectiveColorClass","hasExternalAddons","inputClasses","innerRef","useRef","inputRef","getInitialRaw","useCallback","rawValue","setRawValue","useState","cursorPos","setCursorPos","useEffect","handleMaskedChange","e","input","inputValue","newRaw","filteredRaw","rawIdx","maskedValue","newCursor","charsPlaced","syntheticEvent","handleMaskedKeyDown","internalValue","setInternalValue","handleChange","handleClear","showClear","clearIcon","ariaProps","hasInternalAddons","floatingSizeClasses","buildInput","extraClasses","buildInputWithInternalAddons","jsxs","wrapWithFloatingLabel","floatingClasses","wrapWithExternalAddons","addonClasses","inputElement"],"mappings":"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"}
package/dist/index44.js CHANGED
@@ -6,11 +6,11 @@ const H = S(
6
6
  defaultValue: I,
7
7
  min: a = -1 / 0,
8
8
  max: u = 1 / 0,
9
- step: d = 1,
9
+ step: p = 1,
10
10
  precision: s,
11
11
  size: c,
12
12
  disabled: l = !1,
13
- onChange: p,
13
+ onChange: d,
14
14
  formatter: f,
15
15
  parser: h,
16
16
  className: w = "",
@@ -33,17 +33,17 @@ const H = S(
33
33
  return s !== void 0 && (n = Number(n.toFixed(s))), n;
34
34
  }, i = (e) => {
35
35
  if (e === null) {
36
- o === void 0 && m(null), p?.(null);
36
+ o === void 0 && m(null), d?.(null);
37
37
  return;
38
38
  }
39
39
  const n = x(e);
40
- o === void 0 && m(n), p?.(n);
40
+ o === void 0 && m(n), d?.(n);
41
41
  }, y = () => {
42
42
  if (l) return;
43
- i((t ?? 0) + d);
43
+ i((t ?? 0) + p);
44
44
  }, g = () => {
45
45
  if (l) return;
46
- i((t ?? 0) - d);
46
+ i((t ?? 0) - p);
47
47
  }, L = (e) => {
48
48
  const n = M(e.target.value);
49
49
  n !== null ? i(n) : e.target.value === "" && i(null);
@@ -53,7 +53,6 @@ const H = S(
53
53
  t !== null && (t < a || t > u) && i(x(t));
54
54
  }, R = [
55
55
  "input",
56
- "input-bordered",
57
56
  "w-full",
58
57
  c && {
59
58
  xs: "input-xs",
@@ -1 +1 @@
1
- {"version":3,"file":"index44.js","sources":["../src/components/InputNumber.tsx"],"sourcesContent":["import React, { useState, useRef, forwardRef, useImperativeHandle } from 'react'\n\nexport interface InputNumberProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'onChange' | 'value' | 'defaultValue'> {\n value?: number\n defaultValue?: number\n min?: number\n max?: number\n step?: number\n precision?: number\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n disabled?: boolean\n onChange?: (value: number | null) => void\n formatter?: (value: number | undefined) => string\n parser?: (displayValue: string) => number\n className?: string\n controls?: boolean\n block?: boolean\n}\n\nexport const InputNumber = forwardRef<HTMLInputElement, InputNumberProps>(\n (\n {\n value: controlledValue,\n defaultValue,\n min = -Infinity,\n max = Infinity,\n step = 1,\n precision,\n size,\n disabled = false,\n onChange,\n formatter,\n parser,\n className = '',\n controls = true,\n block = false,\n ...props\n },\n ref\n ) => {\n const [internalValue, setInternalValue] = useState<number | null>(defaultValue ?? null)\n const inputRef = useRef<HTMLInputElement>(null)\n\n useImperativeHandle(ref, () => inputRef.current!)\n\n const value = controlledValue !== undefined ? controlledValue : internalValue\n\n const formatValue = (num: number | null): string => {\n if (num === null) return ''\n let formatted = num\n if (precision !== undefined) {\n formatted = Number(num.toFixed(precision))\n }\n return formatter ? formatter(formatted) : String(formatted)\n }\n\n const parseValue = (str: string): number | null => {\n if (!str) return null\n const parsed = parser ? parser(str) : parseFloat(str)\n if (isNaN(parsed)) return null\n return parsed\n }\n\n const clampValue = (num: number): number => {\n let clamped = Math.max(min, Math.min(max, num))\n if (precision !== undefined) {\n clamped = Number(clamped.toFixed(precision))\n }\n return clamped\n }\n\n const updateValue = (newValue: number | null) => {\n if (newValue === null) {\n if (controlledValue === undefined) {\n setInternalValue(null)\n }\n onChange?.(null)\n return\n }\n\n const clamped = clampValue(newValue)\n if (controlledValue === undefined) {\n setInternalValue(clamped)\n }\n onChange?.(clamped)\n }\n\n const handleIncrement = () => {\n if (disabled) return\n const currentValue = value ?? 0\n updateValue(currentValue + step)\n }\n\n const handleDecrement = () => {\n if (disabled) return\n const currentValue = value ?? 0\n updateValue(currentValue - step)\n }\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const parsed = parseValue(e.target.value)\n if (parsed !== null) {\n updateValue(parsed)\n } else if (e.target.value === '') {\n updateValue(null)\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return\n\n if (e.key === 'ArrowUp') {\n e.preventDefault()\n handleIncrement()\n } else if (e.key === 'ArrowDown') {\n e.preventDefault()\n handleDecrement()\n }\n }\n\n const handleBlur = () => {\n // Ensure value is within bounds on blur\n if (value !== null && (value < min || value > max)) {\n updateValue(clampValue(value))\n }\n }\n\n const sizeClasses = {\n xs: 'input-xs',\n sm: 'input-sm',\n md: 'input-md',\n lg: 'input-lg',\n xl: 'input-xl',\n }\n\n const inputClasses = [\n 'input',\n 'input-bordered',\n 'w-full',\n size && sizeClasses[size],\n disabled && 'input-disabled',\n controls && 'pr-8',\n ]\n .filter(Boolean)\n .join(' ')\n\n const buttonSize = size === 'xs' || size === 'sm' ? 'btn-xs' : 'btn-sm'\n\n return (\n <div className={`relative ${block ? 'w-full' : 'inline-block'} group ${className}`}>\n <input\n ref={inputRef}\n type=\"text\"\n inputMode=\"decimal\"\n role=\"spinbutton\"\n aria-valuemin={min !== -Infinity ? min : undefined}\n aria-valuemax={max !== Infinity ? max : undefined}\n aria-valuenow={value ?? undefined}\n className={inputClasses}\n value={formatValue(value)}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n disabled={disabled}\n {...props}\n />\n {controls && (\n <div className=\"absolute right-1 top-1/2 -translate-y-1/2 flex flex-col gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity\">\n <button\n type=\"button\"\n aria-label=\"Increase value\"\n className={`btn ${buttonSize} btn-ghost px-1 min-h-0 h-3.5`}\n onClick={handleIncrement}\n disabled={disabled || (value !== null && value >= max)}\n tabIndex={-1}\n >\n <svg\n className=\"w-3 h-3\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 15l7-7 7 7\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n aria-label=\"Decrease value\"\n className={`btn ${buttonSize} btn-ghost px-1 min-h-0 h-3.5`}\n onClick={handleDecrement}\n disabled={disabled || (value !== null && value <= min)}\n tabIndex={-1}\n >\n <svg\n className=\"w-3 h-3\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 9l-7 7-7-7\"\n />\n </svg>\n </button>\n </div>\n )}\n </div>\n )\n }\n)\n\nInputNumber.displayName = 'InputNumber'\n\nexport default InputNumber\n"],"names":["InputNumber","forwardRef","controlledValue","defaultValue","min","max","step","precision","size","disabled","onChange","formatter","parser","className","controls","block","props","ref","internalValue","setInternalValue","useState","inputRef","useRef","useImperativeHandle","value","formatValue","num","formatted","parseValue","str","parsed","clampValue","clamped","updateValue","newValue","handleIncrement","handleDecrement","handleInputChange","handleKeyDown","handleBlur","inputClasses","buttonSize","jsxs","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"index44.js","sources":["../src/components/InputNumber.tsx"],"sourcesContent":["import React, { useState, useRef, forwardRef, useImperativeHandle } from 'react'\n\nexport interface InputNumberProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'onChange' | 'value' | 'defaultValue'> {\n value?: number\n defaultValue?: number\n min?: number\n max?: number\n step?: number\n precision?: number\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n disabled?: boolean\n onChange?: (value: number | null) => void\n formatter?: (value: number | undefined) => string\n parser?: (displayValue: string) => number\n className?: string\n controls?: boolean\n block?: boolean\n}\n\nexport const InputNumber = forwardRef<HTMLInputElement, InputNumberProps>(\n (\n {\n value: controlledValue,\n defaultValue,\n min = -Infinity,\n max = Infinity,\n step = 1,\n precision,\n size,\n disabled = false,\n onChange,\n formatter,\n parser,\n className = '',\n controls = true,\n block = false,\n ...props\n },\n ref\n ) => {\n const [internalValue, setInternalValue] = useState<number | null>(defaultValue ?? null)\n const inputRef = useRef<HTMLInputElement>(null)\n\n useImperativeHandle(ref, () => inputRef.current!)\n\n const value = controlledValue !== undefined ? controlledValue : internalValue\n\n const formatValue = (num: number | null): string => {\n if (num === null) return ''\n let formatted = num\n if (precision !== undefined) {\n formatted = Number(num.toFixed(precision))\n }\n return formatter ? formatter(formatted) : String(formatted)\n }\n\n const parseValue = (str: string): number | null => {\n if (!str) return null\n const parsed = parser ? parser(str) : parseFloat(str)\n if (isNaN(parsed)) return null\n return parsed\n }\n\n const clampValue = (num: number): number => {\n let clamped = Math.max(min, Math.min(max, num))\n if (precision !== undefined) {\n clamped = Number(clamped.toFixed(precision))\n }\n return clamped\n }\n\n const updateValue = (newValue: number | null) => {\n if (newValue === null) {\n if (controlledValue === undefined) {\n setInternalValue(null)\n }\n onChange?.(null)\n return\n }\n\n const clamped = clampValue(newValue)\n if (controlledValue === undefined) {\n setInternalValue(clamped)\n }\n onChange?.(clamped)\n }\n\n const handleIncrement = () => {\n if (disabled) return\n const currentValue = value ?? 0\n updateValue(currentValue + step)\n }\n\n const handleDecrement = () => {\n if (disabled) return\n const currentValue = value ?? 0\n updateValue(currentValue - step)\n }\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const parsed = parseValue(e.target.value)\n if (parsed !== null) {\n updateValue(parsed)\n } else if (e.target.value === '') {\n updateValue(null)\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return\n\n if (e.key === 'ArrowUp') {\n e.preventDefault()\n handleIncrement()\n } else if (e.key === 'ArrowDown') {\n e.preventDefault()\n handleDecrement()\n }\n }\n\n const handleBlur = () => {\n // Ensure value is within bounds on blur\n if (value !== null && (value < min || value > max)) {\n updateValue(clampValue(value))\n }\n }\n\n const sizeClasses = {\n xs: 'input-xs',\n sm: 'input-sm',\n md: 'input-md',\n lg: 'input-lg',\n xl: 'input-xl',\n }\n\n const inputClasses = [\n 'input',\n 'w-full',\n size && sizeClasses[size],\n disabled && 'input-disabled',\n controls && 'pr-8',\n ]\n .filter(Boolean)\n .join(' ')\n\n const buttonSize = size === 'xs' || size === 'sm' ? 'btn-xs' : 'btn-sm'\n\n return (\n <div className={`relative ${block ? 'w-full' : 'inline-block'} group ${className}`}>\n <input\n ref={inputRef}\n type=\"text\"\n inputMode=\"decimal\"\n role=\"spinbutton\"\n aria-valuemin={min !== -Infinity ? min : undefined}\n aria-valuemax={max !== Infinity ? max : undefined}\n aria-valuenow={value ?? undefined}\n className={inputClasses}\n value={formatValue(value)}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n disabled={disabled}\n {...props}\n />\n {controls && (\n <div className=\"absolute right-1 top-1/2 -translate-y-1/2 flex flex-col gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity\">\n <button\n type=\"button\"\n aria-label=\"Increase value\"\n className={`btn ${buttonSize} btn-ghost px-1 min-h-0 h-3.5`}\n onClick={handleIncrement}\n disabled={disabled || (value !== null && value >= max)}\n tabIndex={-1}\n >\n <svg\n className=\"w-3 h-3\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 15l7-7 7 7\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n aria-label=\"Decrease value\"\n className={`btn ${buttonSize} btn-ghost px-1 min-h-0 h-3.5`}\n onClick={handleDecrement}\n disabled={disabled || (value !== null && value <= min)}\n tabIndex={-1}\n >\n <svg\n className=\"w-3 h-3\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 9l-7 7-7-7\"\n />\n </svg>\n </button>\n </div>\n )}\n </div>\n )\n }\n)\n\nInputNumber.displayName = 'InputNumber'\n\nexport default InputNumber\n"],"names":["InputNumber","forwardRef","controlledValue","defaultValue","min","max","step","precision","size","disabled","onChange","formatter","parser","className","controls","block","props","ref","internalValue","setInternalValue","useState","inputRef","useRef","useImperativeHandle","value","formatValue","num","formatted","parseValue","str","parsed","clampValue","clamped","updateValue","newValue","handleIncrement","handleDecrement","handleInputChange","handleKeyDown","handleBlur","inputClasses","buttonSize","jsxs","jsx"],"mappings":"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"}
package/dist/index5.js CHANGED
@@ -36,22 +36,22 @@ const oe = ({ onClick: o, className: g }) => /* @__PURE__ */ r(
36
36
  }) => {
37
37
  const y = le(), G = `${y}-input`, E = `${y}-listbox`, I = V.map(
38
38
  (e) => typeof e == "string" ? { value: e, label: e } : e
39
- ), [b, h] = C(g), [J, Q] = C(P), [n, a] = C(-1), m = z(null), c = z(null), B = $ !== void 0, u = B ? $ : J, i = (e) => {
39
+ ), [h, b] = C(g), [J, Q] = C(P), [n, a] = C(-1), m = z(null), c = z(null), B = $ !== void 0, u = B ? $ : J, i = (e) => {
40
40
  B || Q(e), W?.(e);
41
41
  };
42
42
  A(() => {
43
43
  if (o !== void 0) {
44
44
  const e = I.find((t) => t.value === o);
45
- h(e?.label || o);
45
+ b(e?.label || o);
46
46
  }
47
47
  }, [o, I]);
48
48
  const X = (e, t) => e.label.toLowerCase().includes(t.toLowerCase()), l = I.filter(
49
- (e) => j ? j(e, b) : X(e, b)
49
+ (e) => j ? j(e, h) : X(e, h)
50
50
  ), d = l.filter((e) => !e.disabled), Y = (e) => {
51
51
  const t = e.target.value;
52
- h(t), i(!0), v && d.length > 0 ? a(0) : a(-1), T?.(t), D && w?.(t);
52
+ b(t), i(!0), v && d.length > 0 ? a(0) : a(-1), T?.(t), D && w?.(t);
53
53
  }, k = (e) => {
54
- e.disabled || (h(e.label), i(!1), a(-1), w?.(e.value), R?.(e.value, e), m.current?.focus());
54
+ e.disabled || (b(e.label), i(!1), a(-1), w?.(e.value), R?.(e.value, e), m.current?.focus());
55
55
  }, Z = (e) => {
56
56
  if (!u && (e.key === "ArrowDown" || e.key === "ArrowUp")) {
57
57
  i(!0), v && d.length > 0 && a(0);
@@ -84,7 +84,7 @@ const oe = ({ onClick: o, className: g }) => /* @__PURE__ */ r(
84
84
  }, ee = (e) => {
85
85
  c.current && c.current.contains(e.relatedTarget) || setTimeout(() => i(!1), 200);
86
86
  }, te = (e) => {
87
- e.stopPropagation(), h(""), w?.(""), H?.(), m.current?.focus();
87
+ e.stopPropagation(), b(""), w?.(""), H?.(), m.current?.focus();
88
88
  }, ne = {
89
89
  xs: "input-xs",
90
90
  sm: "input-sm",
@@ -107,8 +107,8 @@ const oe = ({ onClick: o, className: g }) => /* @__PURE__ */ r(
107
107
  A(() => {
108
108
  n >= 0 && c.current && c.current.children[n]?.scrollIntoView({ block: "nearest" });
109
109
  }, [n]);
110
- const L = f && b && !p, re = typeof f == "object" && f.clearIcon ? f.clearIcon : null, O = (e) => `${y}-option-${e}`, ae = [
111
- "input input-bordered w-full",
110
+ const L = f && h && !p, re = typeof f == "object" && f.clearIcon ? f.clearIcon : null, O = (e) => `${y}-option-${e}`, ae = [
111
+ "input w-full",
112
112
  ne[S],
113
113
  se,
114
114
  L && "pr-10"
@@ -134,7 +134,7 @@ const oe = ({ onClick: o, className: g }) => /* @__PURE__ */ r(
134
134
  "aria-autocomplete": "list",
135
135
  "aria-activedescendant": n >= 0 ? O(n) : void 0,
136
136
  "aria-invalid": x === "error" ? !0 : void 0,
137
- value: b,
137
+ value: h,
138
138
  onChange: Y,
139
139
  onKeyDown: Z,
140
140
  onFocus: _,
@@ -1 +1 @@
1
- {"version":3,"file":"index5.js","sources":["../src/components/Autocomplete.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId } from 'react'\n\nexport interface AutocompleteOption {\n value: string\n label: string\n disabled?: boolean\n}\n\nexport interface AutocompleteProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'onSelect'> {\n value?: string\n defaultValue?: string\n onChange?: (value: string) => void\n onSelect?: (value: string, option: AutocompleteOption) => void\n onSearch?: (value: string) => void\n options: AutocompleteOption[] | string[]\n placeholder?: string\n disabled?: boolean\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n color?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'\n /** Validation status */\n status?: 'error' | 'warning'\n allowCustomValue?: boolean\n filterOption?: (option: AutocompleteOption, inputValue: string) => boolean\n notFoundContent?: React.ReactNode\n /** Show clear button when input has value */\n allowClear?: boolean | { clearIcon?: React.ReactNode }\n /** Callback when clear button is clicked */\n onClear?: () => void\n /** Controlled open state */\n open?: boolean\n /** Default open state */\n defaultOpen?: boolean\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void\n /** Activate first option by default */\n defaultActiveFirstOption?: boolean\n}\n\n// Clear icon component\nconst ClearIcon: React.FC<{ onClick: (e: React.MouseEvent) => void; className?: string }> = ({ onClick, className }) => (\n <button\n type=\"button\"\n onClick={onClick}\n className={`flex items-center justify-center opacity-50 hover:opacity-100 transition-opacity ${className || ''}`}\n aria-label=\"Clear input\"\n tabIndex={-1}\n >\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n)\n\nexport const Autocomplete: React.FC<AutocompleteProps> = ({\n value,\n defaultValue = '',\n onChange,\n onSelect,\n onSearch,\n options: rawOptions,\n placeholder = 'Type to search...',\n disabled = false,\n size = 'md',\n color,\n status,\n className = '',\n allowCustomValue = true,\n filterOption,\n notFoundContent = 'No results found',\n allowClear,\n onClear,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n defaultActiveFirstOption = true,\n ...rest\n}) => {\n // Generate unique IDs for ARIA\n const baseId = useId()\n const inputId = `${baseId}-input`\n const listboxId = `${baseId}-listbox`\n\n // Normalize options to AutocompleteOption[]\n const options: AutocompleteOption[] = rawOptions.map((opt) =>\n typeof opt === 'string' ? { value: opt, label: opt } : opt\n )\n\n const [inputValue, setInputValue] = useState(defaultValue)\n const [internalOpen, setInternalOpen] = useState(defaultOpen)\n const [highlightedIndex, setHighlightedIndex] = useState(-1)\n const inputRef = useRef<HTMLInputElement>(null)\n const dropdownRef = useRef<HTMLUListElement>(null)\n\n // Determine if open state is controlled\n const isOpenControlled = controlledOpen !== undefined\n const isOpen = isOpenControlled ? controlledOpen : internalOpen\n\n const setIsOpen = (newOpen: boolean) => {\n if (!isOpenControlled) {\n setInternalOpen(newOpen)\n }\n onOpenChange?.(newOpen)\n }\n\n // Update input value when controlled value changes\n useEffect(() => {\n if (value !== undefined) {\n const selectedOption = options.find((opt) => opt.value === value)\n setInputValue(selectedOption?.label || value)\n }\n }, [value, options])\n\n // Filter options based on input\n const defaultFilter = (option: AutocompleteOption, input: string) =>\n option.label.toLowerCase().includes(input.toLowerCase())\n\n const filteredOptions = options.filter((option) =>\n filterOption ? filterOption(option, inputValue) : defaultFilter(option, inputValue)\n )\n\n // Get only enabled options for keyboard navigation\n const enabledOptions = filteredOptions.filter(opt => !opt.disabled)\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newInputValue = e.target.value\n setInputValue(newInputValue)\n setIsOpen(true)\n\n if (defaultActiveFirstOption && enabledOptions.length > 0) {\n setHighlightedIndex(0)\n } else {\n setHighlightedIndex(-1)\n }\n\n onSearch?.(newInputValue)\n\n if (allowCustomValue) {\n onChange?.(newInputValue)\n }\n }\n\n const handleOptionClick = (option: AutocompleteOption) => {\n if (option.disabled) return\n\n setInputValue(option.label)\n setIsOpen(false)\n setHighlightedIndex(-1)\n\n onChange?.(option.value)\n onSelect?.(option.value, option)\n inputRef.current?.focus()\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (!isOpen && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {\n setIsOpen(true)\n if (defaultActiveFirstOption && enabledOptions.length > 0) {\n setHighlightedIndex(0)\n }\n return\n }\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n setHighlightedIndex((prev) => {\n // Find next enabled option\n for (let i = prev + 1; i < filteredOptions.length; i++) {\n if (!filteredOptions[i].disabled) return i\n }\n return prev\n })\n break\n case 'ArrowUp':\n e.preventDefault()\n setHighlightedIndex((prev) => {\n // Find previous enabled option\n for (let i = prev - 1; i >= 0; i--) {\n if (!filteredOptions[i].disabled) return i\n }\n return prev\n })\n break\n case 'Enter':\n e.preventDefault()\n if (highlightedIndex >= 0 && filteredOptions[highlightedIndex] && !filteredOptions[highlightedIndex].disabled) {\n handleOptionClick(filteredOptions[highlightedIndex])\n } else if (!allowCustomValue && enabledOptions.length > 0) {\n handleOptionClick(enabledOptions[0])\n }\n break\n case 'Escape':\n setIsOpen(false)\n setHighlightedIndex(-1)\n inputRef.current?.blur()\n break\n }\n }\n\n const handleFocus = () => {\n setIsOpen(true)\n if (defaultActiveFirstOption && enabledOptions.length > 0) {\n setHighlightedIndex(0)\n }\n }\n\n const handleBlur = (e: React.FocusEvent) => {\n // Don't close if clicking inside dropdown\n if (dropdownRef.current && dropdownRef.current.contains(e.relatedTarget as Node)) {\n return\n }\n setTimeout(() => setIsOpen(false), 200)\n }\n\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation()\n setInputValue('')\n onChange?.('')\n onClear?.()\n inputRef.current?.focus()\n }\n\n const sizeClasses = {\n xs: 'input-xs',\n sm: 'input-sm',\n md: 'input-md',\n lg: 'input-lg',\n xl: 'input-xl',\n }\n\n const colorClasses = {\n neutral: 'input-neutral',\n primary: 'input-primary',\n secondary: 'input-secondary',\n accent: 'input-accent',\n info: 'input-info',\n success: 'input-success',\n warning: 'input-warning',\n error: 'input-error',\n }\n\n const statusClasses = {\n error: 'input-error',\n warning: 'input-warning',\n }\n\n // Status takes precedence over color for validation feedback\n const effectiveColorClass = status ? statusClasses[status] : (color ? colorClasses[color] : '')\n\n // Scroll highlighted option into view\n useEffect(() => {\n if (highlightedIndex >= 0 && dropdownRef.current) {\n const highlightedElement = dropdownRef.current.children[highlightedIndex] as HTMLElement\n highlightedElement?.scrollIntoView({ block: 'nearest' })\n }\n }, [highlightedIndex])\n\n // Determine if we should show clear button\n const showClear = allowClear && inputValue && !disabled\n\n // Get custom clear icon if provided\n const clearIcon = typeof allowClear === 'object' && allowClear.clearIcon\n ? allowClear.clearIcon\n : null\n\n // Get option ID for ARIA\n const getOptionId = (index: number) => `${baseId}-option-${index}`\n\n const inputClasses = [\n 'input input-bordered w-full',\n sizeClasses[size],\n effectiveColorClass,\n showClear && 'pr-10',\n ].filter(Boolean).join(' ')\n\n return (\n <div\n className={`dropdown dropdown-bottom w-full ${isOpen && !disabled ? 'dropdown-open' : ''} ${className}`}\n data-state={isOpen ? 'open' : 'closed'}\n {...rest}\n >\n <div className=\"relative w-full\">\n <input\n ref={inputRef}\n id={inputId}\n type=\"text\"\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-activedescendant={highlightedIndex >= 0 ? getOptionId(highlightedIndex) : undefined}\n aria-invalid={status === 'error' ? true : undefined}\n value={inputValue}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n placeholder={placeholder}\n disabled={disabled}\n className={inputClasses}\n />\n {showClear && (\n <span className=\"absolute right-3 top-1/2 -translate-y-1/2 z-10\">\n {clearIcon || <ClearIcon onClick={handleClear} />}\n </span>\n )}\n </div>\n\n {isOpen && !disabled && (\n <ul\n ref={dropdownRef}\n id={listboxId}\n role=\"listbox\"\n aria-label=\"Suggestions\"\n tabIndex={-1}\n className=\"dropdown-content menu bg-base-100 rounded-box z-50 w-full shadow-lg border border-base-300 max-h-60 overflow-auto flex-nowrap\"\n >\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option, index) => (\n <li key={option.value}>\n <a\n id={getOptionId(index)}\n role=\"option\"\n aria-selected={highlightedIndex === index}\n aria-disabled={option.disabled}\n onMouseDown={(e) => {\n e.preventDefault()\n handleOptionClick(option)\n }}\n onMouseEnter={() => !option.disabled && setHighlightedIndex(index)}\n className={[\n index === highlightedIndex && !option.disabled && 'active',\n option.disabled && 'disabled text-base-content/40 cursor-not-allowed',\n ].filter(Boolean).join(' ')}\n >\n {option.label}\n </a>\n </li>\n ))\n ) : (\n <li className=\"disabled\">\n <span className=\"text-base-content/60 text-center cursor-default\">{notFoundContent}</span>\n </li>\n )}\n </ul>\n )}\n </div>\n )\n}\n"],"names":["ClearIcon","onClick","className","jsx","Autocomplete","value","defaultValue","onChange","onSelect","onSearch","rawOptions","placeholder","disabled","size","color","status","allowCustomValue","filterOption","notFoundContent","allowClear","onClear","controlledOpen","defaultOpen","onOpenChange","defaultActiveFirstOption","rest","baseId","useId","inputId","listboxId","options","opt","inputValue","setInputValue","useState","internalOpen","setInternalOpen","highlightedIndex","setHighlightedIndex","inputRef","useRef","dropdownRef","isOpenControlled","isOpen","setIsOpen","newOpen","useEffect","selectedOption","defaultFilter","option","input","filteredOptions","enabledOptions","handleInputChange","newInputValue","handleOptionClick","handleKeyDown","prev","i","handleFocus","handleBlur","handleClear","sizeClasses","effectiveColorClass","showClear","clearIcon","getOptionId","index","inputClasses","jsxs","e"],"mappings":"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"}
1
+ {"version":3,"file":"index5.js","sources":["../src/components/Autocomplete.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId } from 'react'\n\nexport interface AutocompleteOption {\n value: string\n label: string\n disabled?: boolean\n}\n\nexport interface AutocompleteProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'onSelect'> {\n value?: string\n defaultValue?: string\n onChange?: (value: string) => void\n onSelect?: (value: string, option: AutocompleteOption) => void\n onSearch?: (value: string) => void\n options: AutocompleteOption[] | string[]\n placeholder?: string\n disabled?: boolean\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n color?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'\n /** Validation status */\n status?: 'error' | 'warning'\n allowCustomValue?: boolean\n filterOption?: (option: AutocompleteOption, inputValue: string) => boolean\n notFoundContent?: React.ReactNode\n /** Show clear button when input has value */\n allowClear?: boolean | { clearIcon?: React.ReactNode }\n /** Callback when clear button is clicked */\n onClear?: () => void\n /** Controlled open state */\n open?: boolean\n /** Default open state */\n defaultOpen?: boolean\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void\n /** Activate first option by default */\n defaultActiveFirstOption?: boolean\n}\n\n// Clear icon component\nconst ClearIcon: React.FC<{ onClick: (e: React.MouseEvent) => void; className?: string }> = ({ onClick, className }) => (\n <button\n type=\"button\"\n onClick={onClick}\n className={`flex items-center justify-center opacity-50 hover:opacity-100 transition-opacity ${className || ''}`}\n aria-label=\"Clear input\"\n tabIndex={-1}\n >\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n)\n\nexport const Autocomplete: React.FC<AutocompleteProps> = ({\n value,\n defaultValue = '',\n onChange,\n onSelect,\n onSearch,\n options: rawOptions,\n placeholder = 'Type to search...',\n disabled = false,\n size = 'md',\n color,\n status,\n className = '',\n allowCustomValue = true,\n filterOption,\n notFoundContent = 'No results found',\n allowClear,\n onClear,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n defaultActiveFirstOption = true,\n ...rest\n}) => {\n // Generate unique IDs for ARIA\n const baseId = useId()\n const inputId = `${baseId}-input`\n const listboxId = `${baseId}-listbox`\n\n // Normalize options to AutocompleteOption[]\n const options: AutocompleteOption[] = rawOptions.map((opt) =>\n typeof opt === 'string' ? { value: opt, label: opt } : opt\n )\n\n const [inputValue, setInputValue] = useState(defaultValue)\n const [internalOpen, setInternalOpen] = useState(defaultOpen)\n const [highlightedIndex, setHighlightedIndex] = useState(-1)\n const inputRef = useRef<HTMLInputElement>(null)\n const dropdownRef = useRef<HTMLUListElement>(null)\n\n // Determine if open state is controlled\n const isOpenControlled = controlledOpen !== undefined\n const isOpen = isOpenControlled ? controlledOpen : internalOpen\n\n const setIsOpen = (newOpen: boolean) => {\n if (!isOpenControlled) {\n setInternalOpen(newOpen)\n }\n onOpenChange?.(newOpen)\n }\n\n // Update input value when controlled value changes\n useEffect(() => {\n if (value !== undefined) {\n const selectedOption = options.find((opt) => opt.value === value)\n setInputValue(selectedOption?.label || value)\n }\n }, [value, options])\n\n // Filter options based on input\n const defaultFilter = (option: AutocompleteOption, input: string) =>\n option.label.toLowerCase().includes(input.toLowerCase())\n\n const filteredOptions = options.filter((option) =>\n filterOption ? filterOption(option, inputValue) : defaultFilter(option, inputValue)\n )\n\n // Get only enabled options for keyboard navigation\n const enabledOptions = filteredOptions.filter(opt => !opt.disabled)\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newInputValue = e.target.value\n setInputValue(newInputValue)\n setIsOpen(true)\n\n if (defaultActiveFirstOption && enabledOptions.length > 0) {\n setHighlightedIndex(0)\n } else {\n setHighlightedIndex(-1)\n }\n\n onSearch?.(newInputValue)\n\n if (allowCustomValue) {\n onChange?.(newInputValue)\n }\n }\n\n const handleOptionClick = (option: AutocompleteOption) => {\n if (option.disabled) return\n\n setInputValue(option.label)\n setIsOpen(false)\n setHighlightedIndex(-1)\n\n onChange?.(option.value)\n onSelect?.(option.value, option)\n inputRef.current?.focus()\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (!isOpen && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {\n setIsOpen(true)\n if (defaultActiveFirstOption && enabledOptions.length > 0) {\n setHighlightedIndex(0)\n }\n return\n }\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n setHighlightedIndex((prev) => {\n // Find next enabled option\n for (let i = prev + 1; i < filteredOptions.length; i++) {\n if (!filteredOptions[i].disabled) return i\n }\n return prev\n })\n break\n case 'ArrowUp':\n e.preventDefault()\n setHighlightedIndex((prev) => {\n // Find previous enabled option\n for (let i = prev - 1; i >= 0; i--) {\n if (!filteredOptions[i].disabled) return i\n }\n return prev\n })\n break\n case 'Enter':\n e.preventDefault()\n if (highlightedIndex >= 0 && filteredOptions[highlightedIndex] && !filteredOptions[highlightedIndex].disabled) {\n handleOptionClick(filteredOptions[highlightedIndex])\n } else if (!allowCustomValue && enabledOptions.length > 0) {\n handleOptionClick(enabledOptions[0])\n }\n break\n case 'Escape':\n setIsOpen(false)\n setHighlightedIndex(-1)\n inputRef.current?.blur()\n break\n }\n }\n\n const handleFocus = () => {\n setIsOpen(true)\n if (defaultActiveFirstOption && enabledOptions.length > 0) {\n setHighlightedIndex(0)\n }\n }\n\n const handleBlur = (e: React.FocusEvent) => {\n // Don't close if clicking inside dropdown\n if (dropdownRef.current && dropdownRef.current.contains(e.relatedTarget as Node)) {\n return\n }\n setTimeout(() => setIsOpen(false), 200)\n }\n\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation()\n setInputValue('')\n onChange?.('')\n onClear?.()\n inputRef.current?.focus()\n }\n\n const sizeClasses = {\n xs: 'input-xs',\n sm: 'input-sm',\n md: 'input-md',\n lg: 'input-lg',\n xl: 'input-xl',\n }\n\n const colorClasses = {\n neutral: 'input-neutral',\n primary: 'input-primary',\n secondary: 'input-secondary',\n accent: 'input-accent',\n info: 'input-info',\n success: 'input-success',\n warning: 'input-warning',\n error: 'input-error',\n }\n\n const statusClasses = {\n error: 'input-error',\n warning: 'input-warning',\n }\n\n // Status takes precedence over color for validation feedback\n const effectiveColorClass = status ? statusClasses[status] : (color ? colorClasses[color] : '')\n\n // Scroll highlighted option into view\n useEffect(() => {\n if (highlightedIndex >= 0 && dropdownRef.current) {\n const highlightedElement = dropdownRef.current.children[highlightedIndex] as HTMLElement\n highlightedElement?.scrollIntoView({ block: 'nearest' })\n }\n }, [highlightedIndex])\n\n // Determine if we should show clear button\n const showClear = allowClear && inputValue && !disabled\n\n // Get custom clear icon if provided\n const clearIcon = typeof allowClear === 'object' && allowClear.clearIcon\n ? allowClear.clearIcon\n : null\n\n // Get option ID for ARIA\n const getOptionId = (index: number) => `${baseId}-option-${index}`\n\n const inputClasses = [\n 'input w-full',\n sizeClasses[size],\n effectiveColorClass,\n showClear && 'pr-10',\n ].filter(Boolean).join(' ')\n\n return (\n <div\n className={`dropdown dropdown-bottom w-full ${isOpen && !disabled ? 'dropdown-open' : ''} ${className}`}\n data-state={isOpen ? 'open' : 'closed'}\n {...rest}\n >\n <div className=\"relative w-full\">\n <input\n ref={inputRef}\n id={inputId}\n type=\"text\"\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-activedescendant={highlightedIndex >= 0 ? getOptionId(highlightedIndex) : undefined}\n aria-invalid={status === 'error' ? true : undefined}\n value={inputValue}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n placeholder={placeholder}\n disabled={disabled}\n className={inputClasses}\n />\n {showClear && (\n <span className=\"absolute right-3 top-1/2 -translate-y-1/2 z-10\">\n {clearIcon || <ClearIcon onClick={handleClear} />}\n </span>\n )}\n </div>\n\n {isOpen && !disabled && (\n <ul\n ref={dropdownRef}\n id={listboxId}\n role=\"listbox\"\n aria-label=\"Suggestions\"\n tabIndex={-1}\n className=\"dropdown-content menu bg-base-100 rounded-box z-50 w-full shadow-lg border border-base-300 max-h-60 overflow-auto flex-nowrap\"\n >\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option, index) => (\n <li key={option.value}>\n <a\n id={getOptionId(index)}\n role=\"option\"\n aria-selected={highlightedIndex === index}\n aria-disabled={option.disabled}\n onMouseDown={(e) => {\n e.preventDefault()\n handleOptionClick(option)\n }}\n onMouseEnter={() => !option.disabled && setHighlightedIndex(index)}\n className={[\n index === highlightedIndex && !option.disabled && 'active',\n option.disabled && 'disabled text-base-content/40 cursor-not-allowed',\n ].filter(Boolean).join(' ')}\n >\n {option.label}\n </a>\n </li>\n ))\n ) : (\n <li className=\"disabled\">\n <span className=\"text-base-content/60 text-center cursor-default\">{notFoundContent}</span>\n </li>\n )}\n </ul>\n )}\n </div>\n )\n}\n"],"names":["ClearIcon","onClick","className","jsx","Autocomplete","value","defaultValue","onChange","onSelect","onSearch","rawOptions","placeholder","disabled","size","color","status","allowCustomValue","filterOption","notFoundContent","allowClear","onClear","controlledOpen","defaultOpen","onOpenChange","defaultActiveFirstOption","rest","baseId","useId","inputId","listboxId","options","opt","inputValue","setInputValue","useState","internalOpen","setInternalOpen","highlightedIndex","setHighlightedIndex","inputRef","useRef","dropdownRef","isOpenControlled","isOpen","setIsOpen","newOpen","useEffect","selectedOption","defaultFilter","option","input","filteredOptions","enabledOptions","handleInputChange","newInputValue","handleOptionClick","handleKeyDown","prev","i","handleFocus","handleBlur","handleClear","sizeClasses","effectiveColorClass","showClear","clearIcon","getOptionId","index","inputClasses","jsxs","e"],"mappings":"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"}
package/dist/index61.js CHANGED
@@ -12,9 +12,9 @@ const g = L(
12
12
  disabled: c = !1,
13
13
  error: P = !1,
14
14
  autoFocus: A = !1,
15
- placeholder: b = "",
16
- className: I = ""
17
- }, R) => {
15
+ placeholder: I = "",
16
+ className: R = ""
17
+ }, b) => {
18
18
  const [a, o] = M(() => {
19
19
  const t = p.split("").slice(0, s);
20
20
  return [...t, ...Array(s - t.length).fill("")];
@@ -25,7 +25,7 @@ const g = L(
25
25
  lg: "input-lg w-14 h-14 text-xl",
26
26
  xl: "w-16 h-16 text-2xl"
27
27
  };
28
- Z(R, () => ({
28
+ Z(b, () => ({
29
29
  focus: () => {
30
30
  u.current[0]?.focus();
31
31
  },
@@ -78,7 +78,7 @@ const g = L(
78
78
  ), T = i((t) => {
79
79
  t.target.select();
80
80
  }, []);
81
- return /* @__PURE__ */ v("div", { className: `flex gap-2 ${I}`, children: a.map((t, e) => /* @__PURE__ */ v(
81
+ return /* @__PURE__ */ v("div", { className: `flex gap-2 ${R}`, children: a.map((t, e) => /* @__PURE__ */ v(
82
82
  "input",
83
83
  {
84
84
  ref: (r) => {
@@ -88,14 +88,14 @@ const g = L(
88
88
  inputMode: f === "number" ? "numeric" : "text",
89
89
  maxLength: 1,
90
90
  value: t,
91
- placeholder: b,
91
+ placeholder: I,
92
92
  disabled: c,
93
93
  onChange: (r) => w(e, r.target.value),
94
94
  onKeyDown: (r) => z(e, r),
95
95
  onPaste: N,
96
96
  onFocus: T,
97
97
  className: `
98
- input input-bordered text-center font-mono
98
+ input text-center font-mono
99
99
  ${x[k]}
100
100
  ${P ? "input-error" : ""}
101
101
  ${c ? "input-disabled opacity-50" : ""}
@@ -1 +1 @@
1
- {"version":3,"file":"index61.js","sources":["../src/components/OTPInput.tsx"],"sourcesContent":["import React, { useRef, useState, useEffect, useCallback, forwardRef, useImperativeHandle } from 'react'\n\nexport interface OTPInputProps {\n /** Number of input fields */\n length?: number\n /** Current value */\n value?: string\n /** Callback when value changes */\n onChange?: (value: string) => void\n /** Callback when all fields are filled */\n onComplete?: (value: string) => void\n /** Input size */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n /** Input type - number only or alphanumeric */\n type?: 'number' | 'text'\n /** Mask input (show dots instead of characters) */\n mask?: boolean\n /** Disabled state */\n disabled?: boolean\n /** Error state */\n error?: boolean\n /** Auto focus first input on mount */\n autoFocus?: boolean\n /** Placeholder character */\n placeholder?: string\n /** Additional CSS classes */\n className?: string\n}\n\nexport interface OTPInputRef {\n focus: () => void\n clear: () => void\n}\n\nexport const OTPInput = forwardRef<OTPInputRef, OTPInputProps>(\n (\n {\n length = 6,\n value = '',\n onChange,\n onComplete,\n size = 'md',\n type = 'number',\n mask = false,\n disabled = false,\n error = false,\n autoFocus = false,\n placeholder = '',\n className = '',\n },\n ref\n ) => {\n const [otp, setOtp] = useState<string[]>(() => {\n const initial = value.split('').slice(0, length)\n return [...initial, ...Array(length - initial.length).fill('')]\n })\n\n const inputRefs = useRef<(HTMLInputElement | null)[]>([])\n\n const sizeClasses = {\n xs: 'input-xs w-8 h-8 text-sm',\n sm: 'input-sm w-10 h-10 text-base',\n md: 'w-12 h-12 text-lg',\n lg: 'input-lg w-14 h-14 text-xl',\n xl: 'w-16 h-16 text-2xl',\n }\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n inputRefs.current[0]?.focus()\n },\n clear: () => {\n setOtp(Array(length).fill(''))\n inputRefs.current[0]?.focus()\n },\n }))\n\n useEffect(() => {\n if (autoFocus) {\n inputRefs.current[0]?.focus()\n }\n }, [autoFocus])\n\n useEffect(() => {\n const newOtp = value.split('').slice(0, length)\n setOtp([...newOtp, ...Array(length - newOtp.length).fill('')])\n }, [value, length])\n\n const handleChange = useCallback(\n (index: number, char: string) => {\n if (disabled) return\n\n // Validate input\n if (type === 'number' && !/^\\d*$/.test(char)) return\n if (type === 'text' && !/^[a-zA-Z0-9]*$/.test(char)) return\n\n const newOtp = [...otp]\n\n // Handle paste of multiple characters\n if (char.length > 1) {\n const chars = char.slice(0, length - index).split('')\n chars.forEach((c, i) => {\n if (index + i < length) {\n newOtp[index + i] = c\n }\n })\n setOtp(newOtp)\n\n const newValue = newOtp.join('')\n onChange?.(newValue)\n\n // Focus appropriate field\n const nextIndex = Math.min(index + chars.length, length - 1)\n inputRefs.current[nextIndex]?.focus()\n\n if (newValue.length === length) {\n onComplete?.(newValue)\n }\n return\n }\n\n // Single character\n newOtp[index] = char\n setOtp(newOtp)\n\n const newValue = newOtp.join('')\n onChange?.(newValue)\n\n // Move to next input\n if (char && index < length - 1) {\n inputRefs.current[index + 1]?.focus()\n }\n\n if (newValue.length === length && !newValue.includes('')) {\n onComplete?.(newValue)\n }\n },\n [otp, length, type, disabled, onChange, onComplete]\n )\n\n const handleKeyDown = useCallback(\n (index: number, e: React.KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return\n\n if (e.key === 'Backspace') {\n e.preventDefault()\n const newOtp = [...otp]\n\n if (otp[index]) {\n // Clear current field\n newOtp[index] = ''\n setOtp(newOtp)\n onChange?.(newOtp.join(''))\n } else if (index > 0) {\n // Move to previous field and clear it\n newOtp[index - 1] = ''\n setOtp(newOtp)\n onChange?.(newOtp.join(''))\n inputRefs.current[index - 1]?.focus()\n }\n } else if (e.key === 'ArrowLeft' && index > 0) {\n e.preventDefault()\n inputRefs.current[index - 1]?.focus()\n } else if (e.key === 'ArrowRight' && index < length - 1) {\n e.preventDefault()\n inputRefs.current[index + 1]?.focus()\n }\n },\n [otp, length, disabled, onChange]\n )\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent) => {\n e.preventDefault()\n if (disabled) return\n\n const pastedData = e.clipboardData.getData('text')\n const filteredData =\n type === 'number'\n ? pastedData.replace(/\\D/g, '')\n : pastedData.replace(/[^a-zA-Z0-9]/g, '')\n\n if (filteredData) {\n handleChange(0, filteredData)\n }\n },\n [type, disabled, handleChange]\n )\n\n const handleFocus = useCallback((e: React.FocusEvent<HTMLInputElement>) => {\n e.target.select()\n }, [])\n\n return (\n <div className={`flex gap-2 ${className}`}>\n {otp.map((digit, index) => (\n <input\n key={index}\n ref={(el) => {\n inputRefs.current[index] = el\n }}\n type={mask ? 'password' : type === 'number' ? 'tel' : 'text'}\n inputMode={type === 'number' ? 'numeric' : 'text'}\n maxLength={1}\n value={digit}\n placeholder={placeholder}\n disabled={disabled}\n onChange={(e) => handleChange(index, e.target.value)}\n onKeyDown={(e) => handleKeyDown(index, e)}\n onPaste={handlePaste}\n onFocus={handleFocus}\n className={`\n input input-bordered text-center font-mono\n ${sizeClasses[size]}\n ${error ? 'input-error' : ''}\n ${disabled ? 'input-disabled opacity-50' : ''}\n `}\n aria-label={`OTP digit ${index + 1}`}\n />\n ))}\n </div>\n )\n }\n)\n\nOTPInput.displayName = 'OTPInput'\n"],"names":["OTPInput","forwardRef","length","value","onChange","onComplete","size","type","mask","disabled","error","autoFocus","placeholder","className","ref","otp","setOtp","useState","initial","inputRefs","useRef","sizeClasses","useImperativeHandle","useEffect","newOtp","handleChange","useCallback","index","char","chars","c","i","newValue","nextIndex","handleKeyDown","handlePaste","e","pastedData","filteredData","handleFocus","jsx","digit","el"],"mappings":"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"}
1
+ {"version":3,"file":"index61.js","sources":["../src/components/OTPInput.tsx"],"sourcesContent":["import React, { useRef, useState, useEffect, useCallback, forwardRef, useImperativeHandle } from 'react'\n\nexport interface OTPInputProps {\n /** Number of input fields */\n length?: number\n /** Current value */\n value?: string\n /** Callback when value changes */\n onChange?: (value: string) => void\n /** Callback when all fields are filled */\n onComplete?: (value: string) => void\n /** Input size */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n /** Input type - number only or alphanumeric */\n type?: 'number' | 'text'\n /** Mask input (show dots instead of characters) */\n mask?: boolean\n /** Disabled state */\n disabled?: boolean\n /** Error state */\n error?: boolean\n /** Auto focus first input on mount */\n autoFocus?: boolean\n /** Placeholder character */\n placeholder?: string\n /** Additional CSS classes */\n className?: string\n}\n\nexport interface OTPInputRef {\n focus: () => void\n clear: () => void\n}\n\nexport const OTPInput = forwardRef<OTPInputRef, OTPInputProps>(\n (\n {\n length = 6,\n value = '',\n onChange,\n onComplete,\n size = 'md',\n type = 'number',\n mask = false,\n disabled = false,\n error = false,\n autoFocus = false,\n placeholder = '',\n className = '',\n },\n ref\n ) => {\n const [otp, setOtp] = useState<string[]>(() => {\n const initial = value.split('').slice(0, length)\n return [...initial, ...Array(length - initial.length).fill('')]\n })\n\n const inputRefs = useRef<(HTMLInputElement | null)[]>([])\n\n const sizeClasses = {\n xs: 'input-xs w-8 h-8 text-sm',\n sm: 'input-sm w-10 h-10 text-base',\n md: 'w-12 h-12 text-lg',\n lg: 'input-lg w-14 h-14 text-xl',\n xl: 'w-16 h-16 text-2xl',\n }\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n inputRefs.current[0]?.focus()\n },\n clear: () => {\n setOtp(Array(length).fill(''))\n inputRefs.current[0]?.focus()\n },\n }))\n\n useEffect(() => {\n if (autoFocus) {\n inputRefs.current[0]?.focus()\n }\n }, [autoFocus])\n\n useEffect(() => {\n const newOtp = value.split('').slice(0, length)\n setOtp([...newOtp, ...Array(length - newOtp.length).fill('')])\n }, [value, length])\n\n const handleChange = useCallback(\n (index: number, char: string) => {\n if (disabled) return\n\n // Validate input\n if (type === 'number' && !/^\\d*$/.test(char)) return\n if (type === 'text' && !/^[a-zA-Z0-9]*$/.test(char)) return\n\n const newOtp = [...otp]\n\n // Handle paste of multiple characters\n if (char.length > 1) {\n const chars = char.slice(0, length - index).split('')\n chars.forEach((c, i) => {\n if (index + i < length) {\n newOtp[index + i] = c\n }\n })\n setOtp(newOtp)\n\n const newValue = newOtp.join('')\n onChange?.(newValue)\n\n // Focus appropriate field\n const nextIndex = Math.min(index + chars.length, length - 1)\n inputRefs.current[nextIndex]?.focus()\n\n if (newValue.length === length) {\n onComplete?.(newValue)\n }\n return\n }\n\n // Single character\n newOtp[index] = char\n setOtp(newOtp)\n\n const newValue = newOtp.join('')\n onChange?.(newValue)\n\n // Move to next input\n if (char && index < length - 1) {\n inputRefs.current[index + 1]?.focus()\n }\n\n if (newValue.length === length && !newValue.includes('')) {\n onComplete?.(newValue)\n }\n },\n [otp, length, type, disabled, onChange, onComplete]\n )\n\n const handleKeyDown = useCallback(\n (index: number, e: React.KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return\n\n if (e.key === 'Backspace') {\n e.preventDefault()\n const newOtp = [...otp]\n\n if (otp[index]) {\n // Clear current field\n newOtp[index] = ''\n setOtp(newOtp)\n onChange?.(newOtp.join(''))\n } else if (index > 0) {\n // Move to previous field and clear it\n newOtp[index - 1] = ''\n setOtp(newOtp)\n onChange?.(newOtp.join(''))\n inputRefs.current[index - 1]?.focus()\n }\n } else if (e.key === 'ArrowLeft' && index > 0) {\n e.preventDefault()\n inputRefs.current[index - 1]?.focus()\n } else if (e.key === 'ArrowRight' && index < length - 1) {\n e.preventDefault()\n inputRefs.current[index + 1]?.focus()\n }\n },\n [otp, length, disabled, onChange]\n )\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent) => {\n e.preventDefault()\n if (disabled) return\n\n const pastedData = e.clipboardData.getData('text')\n const filteredData =\n type === 'number'\n ? pastedData.replace(/\\D/g, '')\n : pastedData.replace(/[^a-zA-Z0-9]/g, '')\n\n if (filteredData) {\n handleChange(0, filteredData)\n }\n },\n [type, disabled, handleChange]\n )\n\n const handleFocus = useCallback((e: React.FocusEvent<HTMLInputElement>) => {\n e.target.select()\n }, [])\n\n return (\n <div className={`flex gap-2 ${className}`}>\n {otp.map((digit, index) => (\n <input\n key={index}\n ref={(el) => {\n inputRefs.current[index] = el\n }}\n type={mask ? 'password' : type === 'number' ? 'tel' : 'text'}\n inputMode={type === 'number' ? 'numeric' : 'text'}\n maxLength={1}\n value={digit}\n placeholder={placeholder}\n disabled={disabled}\n onChange={(e) => handleChange(index, e.target.value)}\n onKeyDown={(e) => handleKeyDown(index, e)}\n onPaste={handlePaste}\n onFocus={handleFocus}\n className={`\n input text-center font-mono\n ${sizeClasses[size]}\n ${error ? 'input-error' : ''}\n ${disabled ? 'input-disabled opacity-50' : ''}\n `}\n aria-label={`OTP digit ${index + 1}`}\n />\n ))}\n </div>\n )\n }\n)\n\nOTPInput.displayName = 'OTPInput'\n"],"names":["OTPInput","forwardRef","length","value","onChange","onComplete","size","type","mask","disabled","error","autoFocus","placeholder","className","ref","otp","setOtp","useState","initial","inputRefs","useRef","sizeClasses","useImperativeHandle","useEffect","newOtp","handleChange","useCallback","index","char","chars","c","i","newValue","nextIndex","handleKeyDown","handlePaste","e","pastedData","filteredData","handleFocus","jsx","digit","el"],"mappings":"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"}
package/dist/index62.js CHANGED
@@ -1,28 +1,28 @@
1
1
  import { jsxs as o, jsx as i } from "react/jsx-runtime";
2
- import f from "react";
2
+ import g from "react";
3
3
  const R = ({
4
- current: p,
4
+ current: h,
5
5
  defaultCurrent: P = 1,
6
6
  total: m,
7
- pageSize: h,
7
+ pageSize: p,
8
8
  defaultPageSize: C = 10,
9
9
  pageSizeOptions: j = [10, 20, 50, 100],
10
- onChange: g,
10
+ onChange: d,
11
11
  onShowSizeChange: k,
12
12
  showSizeChanger: y = !1,
13
13
  showQuickJumper: S = !1,
14
- showTotal: d = !1,
14
+ showTotal: f = !1,
15
15
  simple: I = !1,
16
16
  size: M = "md",
17
17
  disabled: a = !1,
18
18
  className: b = "",
19
19
  ...N
20
20
  }) => {
21
- const [w, v] = f.useState(P), [J, _] = f.useState(C), [x, $] = f.useState(""), t = p !== void 0 ? p : w, u = h !== void 0 ? h : J, n = Math.ceil(m / u), r = (e) => {
22
- e < 1 || e > n || a || (p === void 0 && v(e), g?.(e, u));
21
+ const [w, v] = g.useState(P), [J, _] = g.useState(C), [x, $] = g.useState(""), t = h !== void 0 ? h : w, u = p !== void 0 ? p : J, n = Math.ceil(m / u), r = (e) => {
22
+ e < 1 || e > n || a || (h === void 0 && v(e), d?.(e, u));
23
23
  }, D = (e) => {
24
24
  const c = Math.ceil(m / e), s = t > c ? c : t;
25
- h === void 0 && _(e), p === void 0 && s !== t && v(s), k?.(s, e), g?.(s, e);
25
+ p === void 0 && _(e), h === void 0 && s !== t && v(s), k?.(s, e), d?.(s, e);
26
26
  }, E = (e) => {
27
27
  if (e.key === "Enter") {
28
28
  const c = parseInt(x);
@@ -82,7 +82,7 @@ const R = ({
82
82
  }
83
83
  )
84
84
  ] }) : /* @__PURE__ */ o("div", { className: `flex flex-wrap items-center gap-4 ${b}`, ...N, children: [
85
- d && /* @__PURE__ */ i("div", { className: "text-sm text-base-content/70", children: typeof d == "function" ? d(m, G) : `Total ${m} items` }),
85
+ f && /* @__PURE__ */ i("div", { className: "text-sm text-base-content/70", children: typeof f == "function" ? f(m, G) : `Total ${m} items` }),
86
86
  y && /* @__PURE__ */ i(
87
87
  "select",
88
88
  {
@@ -154,7 +154,7 @@ const R = ({
154
154
  "input",
155
155
  {
156
156
  type: "number",
157
- className: `input input-bordered w-16 ${l}`,
157
+ className: `input w-16 ${l}`,
158
158
  min: 1,
159
159
  max: n,
160
160
  value: x,