@tachui/forms 0.7.1-alpha → 0.8.1-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +87 -272
  2. package/dist/DatePicker-D5nRFTUm.js +475 -0
  3. package/dist/DatePicker-D5nRFTUm.js.map +1 -0
  4. package/dist/Select-yZyKooXk.js +945 -0
  5. package/dist/Select-yZyKooXk.js.map +1 -0
  6. package/dist/Slider-0-oal5YR.js +644 -0
  7. package/dist/Slider-0-oal5YR.js.map +1 -0
  8. package/dist/TextField-hX15dY3U.js +509 -0
  9. package/dist/TextField-hX15dY3U.js.map +1 -0
  10. package/dist/components/advanced/Slider.d.ts +190 -0
  11. package/dist/components/advanced/Slider.d.ts.map +1 -0
  12. package/dist/components/advanced/Stepper.d.ts +161 -0
  13. package/dist/components/advanced/Stepper.d.ts.map +1 -0
  14. package/dist/components/advanced/index.d.ts +15 -0
  15. package/dist/components/advanced/index.d.ts.map +1 -0
  16. package/dist/components/advanced/index.js +6 -0
  17. package/dist/components/advanced/index.js.map +1 -0
  18. package/dist/components/date-picker/DatePicker.d.ts +126 -0
  19. package/dist/components/date-picker/DatePicker.d.ts.map +1 -0
  20. package/dist/components/date-picker/index.d.ts +14 -0
  21. package/dist/components/date-picker/index.d.ts.map +1 -0
  22. package/dist/components/date-picker/index.js +5 -0
  23. package/dist/components/date-picker/index.js.map +1 -0
  24. package/dist/components/form-container/index.d.ts +58 -0
  25. package/dist/components/form-container/index.d.ts.map +1 -0
  26. package/dist/components/selection/Checkbox.d.ts.map +1 -0
  27. package/dist/components/selection/Radio.d.ts.map +1 -0
  28. package/dist/components/selection/Select.d.ts.map +1 -0
  29. package/dist/components/selection/index.d.ts +68 -0
  30. package/dist/components/selection/index.d.ts.map +1 -0
  31. package/dist/components/selection/index.js +12 -0
  32. package/dist/components/selection/index.js.map +1 -0
  33. package/dist/components/text-input/TextField.d.ts.map +1 -0
  34. package/dist/components/text-input/index.d.ts +8 -0
  35. package/dist/components/text-input/index.d.ts.map +1 -0
  36. package/dist/components/text-input/index.js +18 -0
  37. package/dist/components/text-input/index.js.map +1 -0
  38. package/dist/{state/index.js → index-D3WfkqVv.js} +15 -8
  39. package/dist/index-D3WfkqVv.js.map +1 -0
  40. package/dist/index.d.ts +10 -15
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +198 -376
  43. package/dist/index.js.map +1 -0
  44. package/dist/state/index.d.ts.map +1 -1
  45. package/dist/types/index.d.ts.map +1 -1
  46. package/dist/utils/index.d.ts +19 -0
  47. package/dist/utils/index.d.ts.map +1 -0
  48. package/dist/validation/component-validation.d.ts +11 -2
  49. package/dist/validation/component-validation.d.ts.map +1 -1
  50. package/dist/validation/index.d.ts.map +1 -1
  51. package/dist/validation/index.js +282 -191
  52. package/dist/validation/index.js.map +1 -0
  53. package/package.json +53 -39
  54. package/src/components/advanced/Slider.ts +722 -0
  55. package/src/components/advanced/Stepper.ts +715 -0
  56. package/src/components/advanced/index.ts +20 -0
  57. package/src/components/date-picker/DatePicker.ts +925 -0
  58. package/src/components/date-picker/index.ts +20 -0
  59. package/src/components/form-container/index.ts +266 -0
  60. package/src/components/selection/Checkbox.ts +478 -0
  61. package/src/components/selection/Radio.ts +470 -0
  62. package/src/components/selection/Select.ts +620 -0
  63. package/src/components/selection/index.ts +81 -0
  64. package/src/components/text-input/TextField.ts +728 -0
  65. package/src/components/text-input/index.ts +35 -0
  66. package/src/index.ts +48 -0
  67. package/src/state/index.ts +544 -0
  68. package/src/types/index.ts +579 -0
  69. package/src/utils/formatters.ts +184 -0
  70. package/src/utils/index.ts +57 -0
  71. package/src/validation/component-validation.ts +429 -0
  72. package/src/validation/index.ts +641 -0
  73. package/dist/TextField-CGBM3x7K.js +0 -1799
  74. package/dist/components/Form.d.ts +0 -76
  75. package/dist/components/Form.d.ts.map +0 -1
  76. package/dist/components/index.d.ts +0 -9
  77. package/dist/components/index.d.ts.map +0 -1
  78. package/dist/components/index.js +0 -28
  79. package/dist/components/input/Checkbox.d.ts.map +0 -1
  80. package/dist/components/input/Radio.d.ts.map +0 -1
  81. package/dist/components/input/Select.d.ts.map +0 -1
  82. package/dist/components/input/TextField.d.ts.map +0 -1
  83. package/dist/components/input/index.d.ts +0 -11
  84. package/dist/components/input/index.d.ts.map +0 -1
  85. package/dist/utils/validators.d.ts +0 -101
  86. package/dist/utils/validators.d.ts.map +0 -1
  87. /package/dist/components/{input → selection}/Checkbox.d.ts +0 -0
  88. /package/dist/components/{input → selection}/Radio.d.ts +0 -0
  89. /package/dist/components/{input → selection}/Select.d.ts +0 -0
  90. /package/dist/components/{input → text-input}/TextField.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider-0-oal5YR.js","sources":["../src/components/advanced/Stepper.ts","../src/components/advanced/Slider.ts"],"sourcesContent":["/**\n * Stepper Component (TachUI)\n *\n * SwiftUI-inspired stepper component for numeric input with increment/decrement controls.\n * Provides bounded value adjustment with customizable step intervals and formatting.\n */\n\nimport type { ModifiableComponent, ModifierBuilder } from '@tachui/core'\nimport { createEffect, getSignalImpl, isSignal } from '@tachui/core'\nimport type { Signal } from '@tachui/core'\nimport { h } from '@tachui/core'\nimport type { ComponentInstance, ComponentProps, DOMNode } from '@tachui/core'\nimport { withModifiers } from '@tachui/core'\n\n/**\n * Stepper value types - supports integers and floating point numbers\n */\nexport type StepperValue = number\n\n/**\n * Stepper component properties\n */\nexport interface StepperProps extends ComponentProps {\n // Core properties\n title?: string\n value: Signal<StepperValue> | StepperValue\n\n // Range and stepping\n minimumValue?: StepperValue\n maximumValue?: StepperValue\n step?: StepperValue\n\n // Custom actions (alternative to value binding)\n onIncrement?: () => void\n onDecrement?: () => void\n\n // Event handling\n onChange?: (value: StepperValue) => void\n onEditingChanged?: (editing: boolean) => void\n\n // Behavior\n disabled?: boolean | Signal<boolean>\n allowsEmptyValue?: boolean\n\n // Formatting\n valueFormatter?: (value: StepperValue) => string\n displayValueInLabel?: boolean\n\n // Accessibility\n accessibilityLabel?: string\n accessibilityHint?: string\n incrementAccessibilityLabel?: string\n decrementAccessibilityLabel?: string\n}\n\n/**\n * Stepper theme configuration\n */\nexport interface StepperTheme {\n colors: {\n background: string\n border: string\n buttonBackground: string\n buttonHover: string\n buttonPress: string\n buttonDisabled: string\n text: string\n buttonText: string\n disabledText: string\n focusRing: string\n }\n spacing: {\n padding: number\n gap: number\n borderRadius: number\n buttonSize: number\n }\n typography: {\n labelSize: number\n buttonSize: number\n labelWeight: string\n buttonWeight: string\n fontFamily: string\n }\n transitions: {\n duration: number\n easing: string\n }\n}\n\n/**\n * Default Stepper theme\n */\nconst defaultStepperTheme: StepperTheme = {\n colors: {\n background: '#FFFFFF',\n border: '#D1D1D6',\n buttonBackground: '#F2F2F7',\n buttonHover: '#E5E5EA',\n buttonPress: '#D1D1D6',\n buttonDisabled: '#F2F2F7',\n text: '#000000',\n buttonText: '#007AFF',\n disabledText: '#8E8E93',\n focusRing: '#007AFF',\n },\n spacing: {\n padding: 12,\n gap: 8,\n borderRadius: 8,\n buttonSize: 32,\n },\n typography: {\n labelSize: 16,\n buttonSize: 18,\n labelWeight: '400',\n buttonWeight: '600',\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n },\n transitions: {\n duration: 150,\n easing: 'cubic-bezier(0.2, 0.8, 0.2, 1)',\n },\n}\n\n/**\n * Stepper component implementation\n */\nexport class StepperComponent implements ComponentInstance<StepperProps> {\n public readonly type = 'component' as const\n public readonly id: string\n public readonly props: StepperProps\n private theme: StepperTheme = defaultStepperTheme\n private incrementButton: HTMLElement | null = null\n private decrementButton: HTMLElement | null = null\n private isEditing = false\n private longPressTimer: ReturnType<typeof setTimeout> | null = null\n private longPressInterval: ReturnType<typeof setInterval> | null = null\n\n constructor(props: StepperProps) {\n this.props = props\n this.id = `stepper-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n }\n\n private resolveValue<T>(value: T | Signal<T>): T {\n return isSignal(value) ? value() : value\n }\n\n private getValue(): StepperValue {\n return this.resolveValue(this.props.value)\n }\n\n private setValue(newValue: StepperValue): void {\n const constrainedValue = this.constrainValue(newValue)\n\n if (isSignal(this.props.value)) {\n const signalImpl = getSignalImpl(this.props.value as any)\n if (signalImpl) {\n signalImpl.set(constrainedValue)\n }\n }\n\n if (this.props.onChange) {\n this.props.onChange(constrainedValue)\n }\n }\n\n private getMinimumValue(): StepperValue {\n return this.props.minimumValue ?? -Infinity\n }\n\n private getMaximumValue(): StepperValue {\n return this.props.maximumValue ?? Infinity\n }\n\n private getStep(): StepperValue {\n return this.props.step ?? 1\n }\n\n private isDisabled(): boolean {\n return this.resolveValue(this.props.disabled ?? false)\n }\n\n private constrainValue(value: StepperValue): StepperValue {\n const min = this.getMinimumValue()\n const max = this.getMaximumValue()\n return Math.min(Math.max(value, min), max)\n }\n\n private canIncrement(): boolean {\n if (this.isDisabled()) return false\n const currentValue = this.getValue()\n const maxValue = this.getMaximumValue()\n return currentValue < maxValue\n }\n\n private canDecrement(): boolean {\n if (this.isDisabled()) return false\n const currentValue = this.getValue()\n const minValue = this.getMinimumValue()\n return currentValue > minValue\n }\n\n private increment(): void {\n if (!this.canIncrement()) return\n\n if (this.props.onIncrement) {\n this.props.onIncrement()\n } else {\n const currentValue = this.getValue()\n const step = this.getStep()\n this.setValue(currentValue + step)\n }\n }\n\n private decrement(): void {\n if (!this.canDecrement()) return\n\n if (this.props.onDecrement) {\n this.props.onDecrement()\n } else {\n const currentValue = this.getValue()\n const step = this.getStep()\n this.setValue(currentValue - step)\n }\n }\n\n private formatValue(value: StepperValue): string {\n if (this.props.valueFormatter) {\n return this.props.valueFormatter(value)\n }\n\n // Default formatting with appropriate decimal places\n if (Number.isInteger(value)) {\n return value.toString()\n } else {\n // For decimal values, show up to 2 decimal places, removing trailing zeros\n return parseFloat(value.toFixed(2)).toString()\n }\n }\n\n private startLongPress(action: () => void): void {\n this.stopLongPress()\n this.setEditing(true)\n\n // Initial delay before starting continuous increment\n this.longPressTimer = setTimeout(() => {\n // Start continuous increment/decrement\n this.longPressInterval = setInterval(() => {\n action()\n }, 100) // 100ms interval for smooth continuous changes\n }, 500) // 500ms initial delay\n }\n\n private stopLongPress(): void {\n if (this.longPressTimer) {\n clearTimeout(this.longPressTimer)\n this.longPressTimer = null\n }\n\n if (this.longPressInterval) {\n clearInterval(this.longPressInterval)\n this.longPressInterval = null\n }\n\n this.setEditing(false)\n }\n\n private setEditing(editing: boolean): void {\n if (this.isEditing !== editing) {\n this.isEditing = editing\n if (this.props.onEditingChanged) {\n this.props.onEditingChanged(editing)\n }\n }\n }\n\n private createButton(\n type: 'increment' | 'decrement',\n symbol: string,\n action: () => void,\n canPerformAction: boolean\n ): DOMNode {\n const button = h('button', {\n type: 'button',\n disabled: !canPerformAction,\n 'aria-label':\n type === 'increment'\n ? this.props.incrementAccessibilityLabel || 'Increment'\n : this.props.decrementAccessibilityLabel || 'Decrement',\n style: {\n width: `${this.theme.spacing.buttonSize}px`,\n height: `${this.theme.spacing.buttonSize}px`,\n border: `1px solid ${this.theme.colors.border}`,\n borderRadius: `${this.theme.spacing.borderRadius}px`,\n backgroundColor: canPerformAction\n ? this.theme.colors.buttonBackground\n : this.theme.colors.buttonDisabled,\n color: canPerformAction\n ? this.theme.colors.buttonText\n : this.theme.colors.disabledText,\n fontSize: `${this.theme.typography.buttonSize}px`,\n fontWeight: this.theme.typography.buttonWeight,\n fontFamily: this.theme.typography.fontFamily,\n cursor: canPerformAction ? 'pointer' : 'not-allowed',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n userSelect: 'none',\n outline: 'none',\n transition: `all ${this.theme.transitions.duration}ms ${this.theme.transitions.easing}`,\n touchAction: 'manipulation', // Prevent double-tap zoom on mobile\n },\n onclick: (e: Event) => {\n e.preventDefault()\n if (canPerformAction) {\n action()\n }\n },\n onmousedown: (e: Event) => {\n e.preventDefault()\n if (canPerformAction) {\n this.startLongPress(action)\n }\n },\n onmouseup: () => {\n this.stopLongPress()\n },\n ontouchstart: (e: Event) => {\n e.preventDefault()\n if (canPerformAction) {\n this.startLongPress(action)\n }\n },\n ontouchend: (e: Event) => {\n e.preventDefault()\n this.stopLongPress()\n },\n onmouseenter: (e: Event) => {\n if (canPerformAction) {\n const target = e.target as HTMLElement\n target.style.backgroundColor = this.theme.colors.buttonHover\n }\n },\n onmouseleave: (e: Event) => {\n const target = e.target as HTMLElement\n target.style.backgroundColor = canPerformAction\n ? this.theme.colors.buttonBackground\n : this.theme.colors.buttonDisabled\n this.stopLongPress()\n },\n onkeydown: (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (canPerformAction) {\n action()\n }\n }\n },\n onfocus: (e: Event) => {\n const target = e.target as HTMLElement\n target.style.boxShadow = `0 0 0 2px ${this.theme.colors.focusRing}40`\n },\n onblur: (e: Event) => {\n const target = e.target as HTMLElement\n target.style.boxShadow = 'none'\n this.stopLongPress()\n },\n })\n\n const buttonDOM = button.element as HTMLElement\n if (buttonDOM) {\n buttonDOM.textContent = symbol\n buttonDOM.setAttribute('tabindex', '0')\n\n if (type === 'increment') {\n this.incrementButton = buttonDOM\n } else {\n this.decrementButton = buttonDOM\n }\n }\n\n return button\n }\n\n private createLabel(): DOMNode {\n const currentValue = this.getValue()\n const formattedValue = this.formatValue(currentValue)\n\n let labelText = this.props.title || ''\n if (this.props.displayValueInLabel !== false && this.props.title) {\n labelText = `${this.props.title}: ${formattedValue}`\n } else if (!this.props.title && this.props.displayValueInLabel !== false) {\n labelText = formattedValue\n }\n\n const label = h('span', {\n style: {\n fontSize: `${this.theme.typography.labelSize}px`,\n fontWeight: this.theme.typography.labelWeight,\n fontFamily: this.theme.typography.fontFamily,\n color: this.isDisabled()\n ? this.theme.colors.disabledText\n : this.theme.colors.text,\n userSelect: 'none',\n display: 'flex',\n alignItems: 'center',\n minHeight: `${this.theme.spacing.buttonSize}px`,\n },\n })\n\n const labelDOM = label.element as HTMLElement\n if (labelDOM) {\n labelDOM.textContent = labelText\n }\n\n return label\n }\n\n render(): DOMNode {\n const container = h('div', {\n id: this.id,\n 'data-component': 'stepper',\n role: 'group',\n 'aria-label':\n this.props.accessibilityLabel || this.props.title || 'Numeric stepper',\n 'aria-describedby': this.props.accessibilityHint\n ? `${this.id}-hint`\n : undefined,\n style: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: `${this.theme.spacing.gap}px`,\n padding: `${this.theme.spacing.padding}px`,\n backgroundColor: this.theme.colors.background,\n border: `1px solid ${this.theme.colors.border}`,\n borderRadius: `${this.theme.spacing.borderRadius}px`,\n fontFamily: this.theme.typography.fontFamily,\n },\n })\n\n // Create components\n const decrementButton = this.createButton(\n 'decrement',\n '−', // Using minus sign (U+2212) instead of hyphen for better visual appearance\n () => this.decrement(),\n this.canDecrement()\n )\n\n const label = this.createLabel()\n\n const incrementButton = this.createButton(\n 'increment',\n '+',\n () => this.increment(),\n this.canIncrement()\n )\n\n // Assemble container\n const containerDOM = container.element as HTMLElement\n if (containerDOM) {\n const decrementDOM = decrementButton.element as HTMLElement\n const labelDOM = label.element as HTMLElement\n const incrementDOM = incrementButton.element as HTMLElement\n\n if (decrementDOM) containerDOM.appendChild(decrementDOM)\n if (labelDOM) containerDOM.appendChild(labelDOM)\n if (incrementDOM) containerDOM.appendChild(incrementDOM)\n\n // Add accessibility hint if provided\n if (this.props.accessibilityHint) {\n const hint = h('span', {\n id: `${this.id}-hint`,\n style: {\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: '0',\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n border: '0',\n },\n })\n\n const hintDOM = hint.element as HTMLElement\n if (hintDOM) {\n hintDOM.textContent = this.props.accessibilityHint\n containerDOM.appendChild(hintDOM)\n }\n }\n }\n\n // Set up reactive effects for value changes\n createEffect(() => {\n // Update button states when value changes\n if (this.incrementButton) {\n const canInc: boolean = this.canIncrement()\n ;(this.incrementButton as any).disabled = !canInc\n this.incrementButton.style.backgroundColor = canInc\n ? this.theme.colors.buttonBackground\n : this.theme.colors.buttonDisabled\n this.incrementButton.style.color = canInc\n ? this.theme.colors.buttonText\n : this.theme.colors.disabledText\n this.incrementButton.style.cursor = canInc ? 'pointer' : 'not-allowed'\n }\n\n if (this.decrementButton) {\n const canDec: boolean = this.canDecrement()\n ;(this.decrementButton as any).disabled = !canDec\n this.decrementButton.style.backgroundColor = canDec\n ? this.theme.colors.buttonBackground\n : this.theme.colors.buttonDisabled\n this.decrementButton.style.color = canDec\n ? this.theme.colors.buttonText\n : this.theme.colors.disabledText\n this.decrementButton.style.cursor = canDec ? 'pointer' : 'not-allowed'\n }\n\n // Update label text\n const labelElement = containerDOM?.querySelector(\n 'span:not([id$=\"-hint\"])'\n ) as HTMLElement\n if (labelElement) {\n const currentValue = this.getValue()\n const formattedValue = this.formatValue(currentValue)\n\n let labelText = this.props.title || ''\n if (this.props.displayValueInLabel !== false && this.props.title) {\n labelText = `${this.props.title}: ${formattedValue}`\n } else if (\n !this.props.title &&\n this.props.displayValueInLabel !== false\n ) {\n labelText = formattedValue\n }\n\n labelElement.textContent = labelText\n labelElement.style.color = this.isDisabled()\n ? this.theme.colors.disabledText\n : this.theme.colors.text\n }\n })\n\n return container\n }\n}\n\n/**\n * Create a Stepper component\n */\nexport function Stepper(\n props: StepperProps\n): ModifiableComponent<StepperProps> & {\n modifier: ModifierBuilder<ModifiableComponent<StepperProps>>\n} {\n return withModifiers(new StepperComponent(props))\n}\n\n/**\n * Stepper utility functions and presets\n */\nexport const StepperUtils = {\n /**\n * Create a quantity stepper (1-99, integer values)\n */\n quantity(\n value: Signal<number>,\n onChange?: (value: number) => void\n ): Omit<StepperProps, 'value'> & { value: Signal<number> } {\n return {\n title: 'Quantity',\n value,\n minimumValue: 1,\n maximumValue: 99,\n step: 1,\n onChange,\n displayValueInLabel: true,\n accessibilityLabel: 'Product quantity',\n incrementAccessibilityLabel: 'Increase quantity',\n decrementAccessibilityLabel: 'Decrease quantity',\n }\n },\n\n /**\n * Create an age stepper (0-120, integer values)\n */\n age(\n value: Signal<number>,\n onChange?: (value: number) => void\n ): Omit<StepperProps, 'value'> & { value: Signal<number> } {\n return {\n title: 'Age',\n value,\n minimumValue: 0,\n maximumValue: 120,\n step: 1,\n onChange,\n displayValueInLabel: true,\n accessibilityLabel: 'Age in years',\n incrementAccessibilityLabel: 'Increase age',\n decrementAccessibilityLabel: 'Decrease age',\n }\n },\n\n /**\n * Create a percentage stepper (0-100%, integer values)\n */\n percentage(\n value: Signal<number>,\n onChange?: (value: number) => void\n ): Omit<StepperProps, 'value'> & { value: Signal<number> } {\n return {\n title: 'Percentage',\n value,\n minimumValue: 0,\n maximumValue: 100,\n step: 1,\n onChange,\n displayValueInLabel: true,\n valueFormatter: (val: number) => `${val}%`,\n accessibilityLabel: 'Percentage value',\n incrementAccessibilityLabel: 'Increase percentage',\n decrementAccessibilityLabel: 'Decrease percentage',\n }\n },\n\n /**\n * Create a rating stepper (1-5 or 1-10, decimal values allowed)\n */\n rating(\n value: Signal<number>,\n maxRating: number = 5,\n step: number = 0.5,\n onChange?: (value: number) => void\n ): Omit<StepperProps, 'value'> & { value: Signal<number> } {\n return {\n title: 'Rating',\n value,\n minimumValue: 0,\n maximumValue: maxRating,\n step,\n onChange,\n displayValueInLabel: true,\n valueFormatter: (val: number) => `${val}/${maxRating}`,\n accessibilityLabel: `Rating out of ${maxRating}`,\n incrementAccessibilityLabel: 'Increase rating',\n decrementAccessibilityLabel: 'Decrease rating',\n }\n },\n\n /**\n * Create a price stepper (0+, decimal values with currency formatting)\n */\n price(\n value: Signal<number>,\n currency: string = '$',\n step: number = 0.01,\n maxValue?: number,\n onChange?: (value: number) => void\n ): Omit<StepperProps, 'value'> & { value: Signal<number> } {\n return {\n title: 'Price',\n value,\n minimumValue: 0,\n maximumValue: maxValue,\n step,\n onChange,\n displayValueInLabel: true,\n valueFormatter: (val: number) => `${currency}${val.toFixed(2)}`,\n accessibilityLabel: 'Price amount',\n incrementAccessibilityLabel: 'Increase price',\n decrementAccessibilityLabel: 'Decrease price',\n }\n },\n\n /**\n * Create a font size stepper (8-72pt, integer values)\n */\n fontSize(\n value: Signal<number>,\n onChange?: (value: number) => void\n ): Omit<StepperProps, 'value'> & { value: Signal<number> } {\n return {\n title: 'Font Size',\n value,\n minimumValue: 8,\n maximumValue: 72,\n step: 1,\n onChange,\n displayValueInLabel: true,\n valueFormatter: (val: number) => `${val}pt`,\n accessibilityLabel: 'Font size in points',\n incrementAccessibilityLabel: 'Increase font size',\n decrementAccessibilityLabel: 'Decrease font size',\n }\n },\n}\n\n/**\n * Stepper styles and theming\n */\nexport const StepperStyles = {\n theme: defaultStepperTheme,\n\n /**\n * Create a custom theme\n */\n createTheme(overrides: Partial<StepperTheme>): StepperTheme {\n return { ...defaultStepperTheme, ...overrides }\n },\n}\n","/**\n * Enhanced Slider Component (Phase 6.4.4)\n *\n * SwiftUI-inspired Slider component with range selection, formatting,\n * and precise value control for numeric input.\n */\n\nimport type { ModifiableComponent, ModifierBuilder } from '@tachui/core'\nimport { createEffect, createSignal, isSignal } from '@tachui/core'\nimport type { Signal } from '@tachui/core'\nimport { h, text } from '@tachui/core'\nimport type { ComponentInstance, ComponentProps } from '@tachui/core'\nimport { withModifiers } from '@tachui/core'\n\n/**\n * Slider component properties\n */\nexport interface SliderProps extends ComponentProps {\n // Value binding\n value: number | Signal<number>\n onValueChange?: (value: number) => void\n\n // Range\n min?: number\n max?: number\n step?: number\n\n // Formatting\n formatter?: (value: number) => string\n minimumValueLabel?: string\n maximumValueLabel?: string\n\n // Appearance\n variant?: 'default' | 'filled' | 'minimal'\n trackColor?: string\n thumbColor?: string\n activeTrackColor?: string\n size?: 'small' | 'medium' | 'large'\n\n // Behavior\n disabled?: boolean | Signal<boolean>\n showValue?: boolean\n showLabels?: boolean\n\n // Advanced features\n marks?: SliderMark[]\n range?: boolean\n vertical?: boolean\n\n // Accessibility\n accessibilityLabel?: string\n accessibilityHint?: string\n accessibilityValueDescription?: (value: number) => string\n}\n\n/**\n * Slider mark configuration\n */\nexport interface SliderMark {\n value: number\n label?: string\n color?: string\n}\n\n/**\n * Enhanced Slider component class\n */\nexport class EnhancedSlider implements ComponentInstance<SliderProps> {\n public readonly type = 'component' as const\n public readonly id: string\n public mounted = false\n public cleanup: (() => void)[] = []\n private sliderElement: HTMLInputElement | null = null\n private isDragging: () => boolean\n private setIsDragging: (dragging: boolean) => boolean\n\n constructor(public props: SliderProps) {\n this.id = `slider-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n\n // Initialize internal state\n const [dragging, setDragging] = createSignal(false)\n this.isDragging = dragging\n this.setIsDragging = setDragging\n\n // Handle value changes reactively\n createEffect(() => {\n const currentValue = this.getValue()\n if (this.sliderElement && !this.isDragging()) {\n this.sliderElement.value = String(currentValue)\n this.updateTrackFill()\n }\n })\n }\n\n /**\n * Get current value\n */\n private getValue(): number {\n const { value } = this.props\n if (isSignal(value)) {\n return (value as () => number)()\n }\n return value as number\n }\n\n /**\n * Check if slider is disabled\n */\n private isDisabled(): boolean {\n const { disabled } = this.props\n if (typeof disabled === 'boolean') return disabled\n if (isSignal(disabled)) return (disabled as () => boolean)()\n return false\n }\n\n /**\n * Format value for display\n */\n private formatValue(value: number): string {\n const { formatter } = this.props\n if (formatter) {\n return formatter(value)\n }\n\n // Default formatting based on step\n const step = this.props.step || 1\n if (step < 1) {\n const decimals = String(step).split('.')[1]?.length || 0\n return value.toFixed(decimals)\n }\n\n return String(Math.round(value))\n }\n\n /**\n * Handle value change\n */\n private handleValueChange = (newValue: number) => {\n const { min = 0, max = 100, step = 1 } = this.props\n\n // Clamp value to range\n let clampedValue = Math.max(min, Math.min(max, newValue))\n\n // Snap to step\n if (step > 0) {\n clampedValue = Math.round((clampedValue - min) / step) * step + min\n }\n\n // Update value\n if (this.props.onValueChange) {\n this.props.onValueChange(clampedValue)\n }\n\n this.updateTrackFill()\n }\n\n /**\n * Update track fill visual\n */\n private updateTrackFill() {\n if (!this.sliderElement) return\n\n const { min = 0, max = 100 } = this.props\n const value = this.getValue()\n const percentage = ((value - min) / (max - min)) * 100\n\n // Update CSS custom property for track fill\n this.sliderElement.style.setProperty('--slider-progress', `${percentage}%`)\n }\n\n /**\n * Handle input events\n */\n private handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement\n const value = parseFloat(target.value)\n\n if (!Number.isNaN(value)) {\n this.handleValueChange(value)\n }\n }\n\n /**\n * Handle mouse/touch start\n */\n private handleStart = () => {\n if (!this.isDisabled()) {\n this.setIsDragging(true)\n }\n }\n\n /**\n * Handle mouse/touch end\n */\n private handleEnd = () => {\n this.setIsDragging(false)\n }\n\n /**\n * Get slider size styles\n */\n private getSizeStyles() {\n const { size = 'medium' } = this.props\n\n switch (size) {\n case 'small':\n return {\n height: '4px',\n thumbSize: '16px',\n }\n case 'large':\n return {\n height: '8px',\n thumbSize: '24px',\n }\n default:\n return {\n height: '6px',\n thumbSize: '20px',\n }\n }\n }\n\n /**\n * Get slider variant styles\n */\n private getVariantStyles() {\n const {\n variant = 'default',\n trackColor = '#e2e8f0',\n activeTrackColor = '#007AFF',\n thumbColor = '#ffffff',\n } = this.props\n const sizeStyles = this.getSizeStyles()\n\n const baseStyles = {\n '--slider-track-color': trackColor,\n '--slider-active-track-color': activeTrackColor,\n '--slider-thumb-color': thumbColor,\n '--slider-height': sizeStyles.height,\n '--slider-thumb-size': sizeStyles.thumbSize,\n }\n\n switch (variant) {\n case 'filled':\n return {\n ...baseStyles,\n '--slider-track-color': '#f1f5f9',\n '--slider-active-track-color': activeTrackColor,\n backgroundColor: '#f8fafc',\n borderRadius: '12px',\n padding: '8px',\n }\n\n case 'minimal':\n return {\n ...baseStyles,\n '--slider-track-color': 'transparent',\n '--slider-active-track-color': activeTrackColor,\n border: `1px solid ${trackColor}`,\n }\n default:\n return baseStyles\n }\n }\n\n /**\n * Render slider marks\n */\n private renderMarks() {\n const { marks, min = 0, max = 100 } = this.props\n\n if (!marks || marks.length === 0) {\n return []\n }\n\n return marks.map(mark => {\n const percentage = ((mark.value - min) / (max - min)) * 100\n\n return h(\n 'div',\n {\n key: String(mark.value),\n style: {\n position: 'absolute',\n left: `${percentage}%`,\n top: '50%',\n transform: 'translate(-50%, -50%)',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n pointerEvents: 'none',\n },\n },\n // Mark indicator\n h('div', {\n style: {\n width: '2px',\n height: '12px',\n backgroundColor: mark.color || '#666',\n marginBottom: '4px',\n },\n }),\n\n // Mark label\n ...(mark.label\n ? [\n h(\n 'span',\n {\n style: {\n fontSize: '12px',\n color: '#666',\n whiteSpace: 'nowrap',\n },\n },\n text(mark.label)\n ),\n ]\n : [])\n )\n })\n }\n\n /**\n * Render value labels\n */\n private renderLabels() {\n const {\n showLabels,\n min = 0,\n max = 100,\n minimumValueLabel,\n maximumValueLabel,\n } = this.props\n\n if (!showLabels) return []\n\n return [\n h(\n 'div',\n {\n style: {\n display: 'flex',\n justifyContent: 'space-between',\n marginTop: '8px',\n fontSize: '12px',\n color: '#666',\n },\n },\n h('span', {}, text(minimumValueLabel || this.formatValue(min))),\n h('span', {}, text(maximumValueLabel || this.formatValue(max)))\n ),\n ]\n }\n\n /**\n * Render value display\n */\n private renderValueDisplay() {\n const { showValue } = this.props\n\n if (!showValue) return []\n\n const currentValue = this.getValue()\n\n return [\n h(\n 'div',\n {\n style: {\n display: 'flex',\n justifyContent: 'center',\n marginBottom: '8px',\n fontSize: '14px',\n fontWeight: '600',\n color: '#1a1a1a',\n },\n },\n text(this.formatValue(currentValue))\n ),\n ]\n }\n\n render() {\n const {\n min = 0,\n max = 100,\n step = 1,\n vertical = false,\n accessibilityLabel,\n accessibilityHint,\n accessibilityValueDescription,\n } = this.props\n\n const currentValue = this.getValue()\n const variantStyles = this.getVariantStyles()\n const isDisabled = this.isDisabled()\n\n // Slider CSS styles\n const sliderStyles = {\n appearance: 'none' as const,\n width: vertical ? '6px' : '100%',\n height: vertical ? '200px' : 'var(--slider-height)',\n background: `linear-gradient(to ${vertical ? 'top' : 'right'}, var(--slider-active-track-color) 0%, var(--slider-active-track-color) var(--slider-progress, 0%), var(--slider-track-color) var(--slider-progress, 0%), var(--slider-track-color) 100%)`,\n borderRadius: 'calc(var(--slider-height) / 2)',\n outline: 'none',\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n opacity: isDisabled ? 0.5 : 1,\n transition: 'all 0.2s ease',\n\n // Webkit styles\n WebkitAppearance: 'none' as const,\n\n // Thumb styles\n '&::-webkit-slider-thumb': {\n appearance: 'none',\n width: 'var(--slider-thumb-size)',\n height: 'var(--slider-thumb-size)',\n borderRadius: '50%',\n background: 'var(--slider-thumb-color)',\n border: '2px solid var(--slider-active-track-color)',\n cursor: isDisabled ? 'not-allowed' : 'grab',\n boxShadow: '0 2px 4px rgba(0,0,0,0.1)',\n transition: 'all 0.2s ease',\n },\n\n '&::-webkit-slider-thumb:hover': !isDisabled\n ? {\n transform: 'scale(1.1)',\n boxShadow: '0 4px 8px rgba(0,0,0,0.15)',\n }\n : {},\n\n '&::-webkit-slider-thumb:active': !isDisabled\n ? {\n cursor: 'grabbing',\n transform: 'scale(1.05)',\n }\n : {},\n\n // Firefox styles\n '&::-moz-range-thumb': {\n width: 'var(--slider-thumb-size)',\n height: 'var(--slider-thumb-size)',\n borderRadius: '50%',\n background: 'var(--slider-thumb-color)',\n border: '2px solid var(--slider-active-track-color)',\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n boxShadow: '0 2px 4px rgba(0,0,0,0.1)',\n },\n\n '&::-moz-range-track': {\n height: 'var(--slider-height)',\n borderRadius: 'calc(var(--slider-height) / 2)',\n background: 'var(--slider-track-color)',\n border: 'none',\n },\n }\n\n return h(\n 'div',\n {\n style: {\n ...variantStyles,\n position: 'relative',\n display: 'flex',\n flexDirection: vertical ? 'row' : 'column',\n alignItems: vertical ? 'center' : 'stretch',\n gap: vertical ? '12px' : '0',\n },\n 'aria-label': accessibilityLabel,\n 'aria-describedby': accessibilityHint ? `${this.id}-hint` : undefined,\n },\n // Value display\n ...this.renderValueDisplay(),\n\n // Slider container\n h(\n 'div',\n {\n style: {\n position: 'relative',\n width: vertical ? 'auto' : '100%',\n height: vertical ? '200px' : 'auto',\n },\n },\n // Slider input\n h('input', {\n ref: (el: HTMLInputElement) => {\n this.sliderElement = el\n\n if (el && !this.mounted) {\n // Set up event listeners\n el.addEventListener('input', this.handleInput)\n el.addEventListener('mousedown', this.handleStart)\n el.addEventListener('mouseup', this.handleEnd)\n el.addEventListener('touchstart', this.handleStart)\n el.addEventListener('touchend', this.handleEnd)\n\n this.cleanup.push(() => {\n el.removeEventListener('input', this.handleInput)\n el.removeEventListener('mousedown', this.handleStart)\n el.removeEventListener('mouseup', this.handleEnd)\n el.removeEventListener('touchstart', this.handleStart)\n el.removeEventListener('touchend', this.handleEnd)\n })\n\n // Initial setup\n this.updateTrackFill()\n this.mounted = true\n }\n },\n type: 'range',\n min: String(min),\n max: String(max),\n step: String(step),\n value: String(currentValue),\n disabled: isDisabled,\n orient: vertical ? 'vertical' : undefined,\n style: sliderStyles,\n 'aria-label': accessibilityLabel,\n 'aria-valuemin': min,\n 'aria-valuemax': max,\n 'aria-valuenow': currentValue,\n 'aria-valuetext': accessibilityValueDescription\n ? accessibilityValueDescription(currentValue)\n : this.formatValue(currentValue),\n }),\n\n // Slider marks\n ...this.renderMarks()\n ),\n\n // Labels\n ...this.renderLabels(),\n\n // Accessibility hint\n ...(accessibilityHint\n ? [\n h(\n 'div',\n {\n id: `${this.id}-hint`,\n style: {\n fontSize: '12px',\n color: '#666',\n marginTop: '4px',\n },\n },\n text(accessibilityHint)\n ),\n ]\n : [])\n )\n }\n}\n\n/**\n * Slider component function\n */\nexport function Slider(\n value: number | Signal<number>,\n props: Omit<SliderProps, 'value'> = {}\n): ModifiableComponent<SliderProps> & {\n modifier: ModifierBuilder<ModifiableComponent<SliderProps>>\n} {\n const sliderProps: SliderProps = { ...props, value }\n const component = new EnhancedSlider(sliderProps)\n return withModifiers(component)\n}\n\n/**\n * Slider style variants\n */\nexport const SliderStyles = {\n /**\n * Default slider (default)\n */\n Default(\n value: number | Signal<number>,\n props: Omit<SliderProps, 'value' | 'variant'> = {}\n ) {\n return Slider(value, { ...props, variant: 'default' })\n },\n\n /**\n * Filled slider with background\n */\n Filled(\n value: number | Signal<number>,\n props: Omit<SliderProps, 'value' | 'variant'> = {}\n ) {\n return Slider(value, { ...props, variant: 'filled' })\n },\n\n /**\n * Minimal slider with minimal styling\n */\n Minimal(\n value: number | Signal<number>,\n props: Omit<SliderProps, 'value' | 'variant'> = {}\n ) {\n return Slider(value, { ...props, variant: 'minimal' })\n },\n\n /**\n * Vertical slider\n */\n Vertical(\n value: number | Signal<number>,\n props: Omit<SliderProps, 'value' | 'vertical'> = {}\n ) {\n return Slider(value, { ...props, vertical: true })\n },\n\n /**\n * Range slider with marks\n */\n WithMarks(\n value: number | Signal<number>,\n marks: SliderMark[],\n props: Omit<SliderProps, 'value' | 'marks'> = {}\n ) {\n return Slider(value, { ...props, marks })\n },\n\n /**\n * Slider with value display\n */\n WithValue(\n value: number | Signal<number>,\n props: Omit<SliderProps, 'value' | 'showValue'> = {}\n ) {\n return Slider(value, { ...props, showValue: true })\n },\n\n /**\n * Slider with labels\n */\n WithLabels(\n value: number | Signal<number>,\n minimumLabel: string,\n maximumLabel: string,\n props: Omit<\n SliderProps,\n 'value' | 'showLabels' | 'minimumValueLabel' | 'maximumValueLabel'\n > = {}\n ) {\n return Slider(value, {\n ...props,\n showLabels: true,\n minimumValueLabel: minimumLabel,\n maximumValueLabel: maximumLabel,\n })\n },\n}\n\n/**\n * Slider utilities\n */\nexport const SliderUtils = {\n /**\n * Create marks for common ranges\n */\n createMarks(min: number, max: number, step: number): SliderMark[] {\n const marks: SliderMark[] = []\n\n for (let value = min; value <= max; value += step) {\n marks.push({\n value,\n label: String(value),\n })\n }\n\n return marks\n },\n\n /**\n * Create percentage marks\n */\n createPercentageMarks(): SliderMark[] {\n return [\n { value: 0, label: '0%' },\n { value: 25, label: '25%' },\n { value: 50, label: '50%' },\n { value: 75, label: '75%' },\n { value: 100, label: '100%' },\n ]\n },\n\n /**\n * Create custom formatter\n */\n createFormatter(\n unit: string,\n decimals: number = 0\n ): (value: number) => string {\n return (value: number) => `${value.toFixed(decimals)}${unit}`\n },\n\n /**\n * Snap value to step\n */\n snapToStep(value: number, min: number, step: number): number {\n return Math.round((value - min) / step) * step + min\n },\n\n /**\n * Convert slider value to different scale\n */\n mapToScale(\n value: number,\n fromMin: number,\n fromMax: number,\n toMin: number,\n toMax: number\n ): number {\n const percentage = (value - fromMin) / (fromMax - fromMin)\n return toMin + percentage * (toMax - toMin)\n },\n}\n"],"names":["defaultStepperTheme","StepperComponent","props","value","isSignal","newValue","constrainedValue","signalImpl","getSignalImpl","min","max","currentValue","maxValue","minValue","step","action","editing","type","symbol","canPerformAction","button","h","e","target","buttonDOM","formattedValue","labelText","label","labelDOM","container","decrementButton","incrementButton","containerDOM","decrementDOM","incrementDOM","hintDOM","createEffect","canInc","canDec","labelElement","Stepper","withModifiers","EnhancedSlider","dragging","setDragging","createSignal","disabled","formatter","decimals","clampedValue","percentage","event","size","variant","trackColor","activeTrackColor","thumbColor","sizeStyles","baseStyles","marks","mark","text","showLabels","minimumValueLabel","maximumValueLabel","showValue","vertical","accessibilityLabel","accessibilityHint","accessibilityValueDescription","variantStyles","isDisabled","sliderStyles","el","Slider","sliderProps","component"],"mappings":"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"}
@@ -0,0 +1,509 @@
1
+ import { createSignal as v, createEffect as x, h as u, isSignal as Ce, text as y } from "@tachui/core";
2
+ import { a as $e } from "./index-D3WfkqVv.js";
3
+ const h = {
4
+ /**
5
+ * Phone number formatter (US format)
6
+ */
7
+ phone: (e) => {
8
+ const t = e.replace(/\D/g, "");
9
+ return t.length <= 3 ? t : t.length <= 6 ? `(${t.slice(0, 3)}) ${t.slice(3)}` : `(${t.slice(0, 3)}) ${t.slice(3, 6)}-${t.slice(6, 10)}`;
10
+ },
11
+ /**
12
+ * Credit card formatter
13
+ */
14
+ creditCard: (e) => e.replace(/\D/g, "").replace(/(\d{4})(?=\d)/g, "$1 "),
15
+ /**
16
+ * Currency formatter
17
+ */
18
+ currency: (e) => {
19
+ const t = parseFloat(e.replace(/[^\d.]/g, ""));
20
+ return Number.isNaN(t) ? "" : new Intl.NumberFormat("en-US", {
21
+ style: "currency",
22
+ currency: "USD"
23
+ }).format(t);
24
+ },
25
+ /**
26
+ * Uppercase formatter
27
+ */
28
+ uppercase: (e) => e.toUpperCase(),
29
+ /**
30
+ * Lowercase formatter
31
+ */
32
+ lowercase: (e) => e.toLowerCase(),
33
+ /**
34
+ * Title case formatter
35
+ */
36
+ titleCase: (e) => e.replace(
37
+ /\w\S*/g,
38
+ (t) => t.charAt(0).toUpperCase() + t.substr(1).toLowerCase()
39
+ ),
40
+ /**
41
+ * Social Security Number formatter
42
+ */
43
+ ssn: (e) => {
44
+ const t = e.replace(/\D/g, "");
45
+ return t.length <= 3 ? t : t.length <= 5 ? `${t.slice(0, 3)}-${t.slice(3)}` : `${t.slice(0, 3)}-${t.slice(3, 5)}-${t.slice(5, 9)}`;
46
+ },
47
+ /**
48
+ * Postal code formatter (US ZIP)
49
+ */
50
+ postalCode: (e) => {
51
+ const t = e.replace(/\D/g, "");
52
+ return t.length <= 5 ? t : `${t.slice(0, 5)}-${t.slice(5, 9)}`;
53
+ },
54
+ /**
55
+ * Decimal number formatter
56
+ */
57
+ decimal: (e = 2) => (t) => {
58
+ const r = parseFloat(t.replace(/[^\d.-]/g, ""));
59
+ return Number.isNaN(r) ? "" : r.toFixed(e);
60
+ },
61
+ /**
62
+ * Percentage formatter
63
+ */
64
+ percentage: (e) => {
65
+ const t = parseFloat(e.replace(/[^\d.-]/g, ""));
66
+ return Number.isNaN(t) ? "" : `${t}%`;
67
+ },
68
+ /**
69
+ * Custom formatter factory
70
+ */
71
+ custom: (e) => e
72
+ }, p = {
73
+ /**
74
+ * Phone number parser - extracts digits only
75
+ */
76
+ phone: (e) => e.replace(/\D/g, ""),
77
+ /**
78
+ * Credit card parser - extracts digits only
79
+ */
80
+ creditCard: (e) => e.replace(/\D/g, ""),
81
+ /**
82
+ * Currency parser - extracts numeric value
83
+ */
84
+ currency: (e) => {
85
+ const t = e.match(/[\d.-]+/);
86
+ return t ? t[0] : "";
87
+ },
88
+ /**
89
+ * SSN parser - extracts digits only
90
+ */
91
+ ssn: (e) => e.replace(/\D/g, ""),
92
+ /**
93
+ * Postal code parser - extracts digits only
94
+ */
95
+ postalCode: (e) => e.replace(/\D/g, ""),
96
+ /**
97
+ * Decimal parser - extracts number
98
+ */
99
+ decimal: (e) => {
100
+ const t = e.match(/^-?\d*\.?\d*/);
101
+ return t ? t[0] : "";
102
+ }
103
+ }, O = (e, t) => e === void 0 ? t : typeof e == "function" || Ce(e) ? e() : e, l = (e) => {
104
+ const {
105
+ name: t,
106
+ label: r,
107
+ placeholder: b,
108
+ type: n = "text",
109
+ multiline: s = !1,
110
+ rows: m = 3,
111
+ minLength: W,
112
+ maxLength: g,
113
+ pattern: j,
114
+ autocomplete: G,
115
+ spellcheck: J = !0,
116
+ disabled: Q = !1,
117
+ required: $ = !1,
118
+ validation: z,
119
+ value: L,
120
+ defaultValue: X = "",
121
+ onChange: E,
122
+ onBlur: U,
123
+ onFocus: q,
124
+ error: Y,
125
+ helperText: T,
126
+ // New enhanced features
127
+ keyboardType: R = "default",
128
+ returnKeyType: Z,
129
+ autoCapitalize: ee,
130
+ autoFocus: te = !1,
131
+ accessibilityLabel: ae,
132
+ accessibilityHint: S,
133
+ accessibilityRole: ie = "textbox",
134
+ formatter: w,
135
+ parser: D,
136
+ validateOnChange: re = !1,
137
+ validateOnBlur: le = !0,
138
+ font: c,
139
+ textAlign: B,
140
+ text: P,
141
+ placeholderSignal: V,
142
+ disabledSignal: N,
143
+ ...F
144
+ } = e, o = e._formContext, a = $e(t, L ?? X, z);
145
+ o && o.register(t, z);
146
+ const [ne, I] = v(!1), [_, se] = v(0), [ce, oe] = v(""), [de, ue] = v(""), [be, me] = v(!1);
147
+ x(() => {
148
+ if (P) {
149
+ const i = O(P, "");
150
+ oe(i), i !== a.value() && a.setValue(i);
151
+ }
152
+ }), x(() => {
153
+ V && ue(O(V, ""));
154
+ }), x(() => {
155
+ N && me(O(N, !1));
156
+ }), L !== void 0 && x(() => {
157
+ a.value() !== L && a.setValue(L);
158
+ }), x(() => {
159
+ const i = a.value() || "";
160
+ se(String(i).length);
161
+ });
162
+ const A = (i) => {
163
+ if (w)
164
+ try {
165
+ return w(i);
166
+ } catch (d) {
167
+ return console.warn("TextField formatter error:", d), i;
168
+ }
169
+ return i;
170
+ }, fe = (i) => {
171
+ if (D)
172
+ try {
173
+ return D(i);
174
+ } catch (d) {
175
+ return console.warn("TextField parser error:", d), i;
176
+ }
177
+ return i;
178
+ }, ye = (i) => {
179
+ const d = i.target, K = d.value, C = fe(K), H = A(C);
180
+ if (a.setValue(C), H !== K && d) {
181
+ const M = d.selectionStart || 0;
182
+ d.value = H, d.setSelectionRange(M, M);
183
+ }
184
+ o && o.setValue(t, C), re && a.validate(), E && E(t, C, a);
185
+ }, he = (i) => {
186
+ I(!0), a.onFocus(), q && q(t, a.value());
187
+ }, pe = (i) => {
188
+ I(!1), a.onBlur(), le && a.validate(), U && U(t, a.value());
189
+ }, ge = (i) => {
190
+ i.key === "Enter" && !s && (i.preventDefault(), o?.submitForm && o.submitForm());
191
+ }, f = Y || a.error() || o?.getError(t), ve = V ? de() : b, xe = N ? be() : Q, Le = P ? ce() : a.value() || "", Fe = A(Le), k = {
192
+ id: F.id || t,
193
+ name: t,
194
+ value: Fe,
195
+ placeholder: ve,
196
+ disabled: xe,
197
+ required: $,
198
+ minlength: W,
199
+ maxlength: g,
200
+ pattern: j,
201
+ autocomplete: G,
202
+ spellcheck: J,
203
+ oninput: ye,
204
+ onfocus: he,
205
+ onblur: pe,
206
+ onkeydown: ge,
207
+ // Enhanced accessibility
208
+ "aria-invalid": !!f,
209
+ "aria-describedby": [
210
+ f ? `${t}-error` : null,
211
+ T ? `${t}-helper` : null,
212
+ g ? `${t}-counter` : null,
213
+ S ? `${t}-hint` : null
214
+ ].filter(Boolean).join(" ") || void 0,
215
+ "aria-label": ae,
216
+ role: ie,
217
+ // Mobile features
218
+ inputMode: R !== "default" ? R : void 0,
219
+ enterKeyHint: Z,
220
+ autoCapitalize: ee,
221
+ autoFocus: te,
222
+ // Data attributes for styling and debugging
223
+ "data-tachui-textfield": !0,
224
+ "data-field-name": t,
225
+ "data-field-type": n,
226
+ "data-field-valid": !f,
227
+ "data-field-touched": a.touched(),
228
+ "data-field-dirty": a.dirty(),
229
+ "data-field-focused": ne(),
230
+ "data-field-validating": a.validating(),
231
+ "data-field-has-formatter": !!w,
232
+ "data-field-has-parser": !!D,
233
+ // Typography styling
234
+ style: {
235
+ ...c?.family && { fontFamily: c.family },
236
+ ...c?.size && {
237
+ fontSize: typeof c.size == "number" ? `${c.size}px` : c.size
238
+ },
239
+ ...c?.weight && { fontWeight: c.weight },
240
+ ...c?.style && { fontStyle: c.style },
241
+ ...B && { textAlign: B }
242
+ // Additional styling can be applied via modifiers
243
+ }
244
+ };
245
+ return n && !s && (k.type = n), {
246
+ type: "component",
247
+ id: F.id || `textfield-${t}`,
248
+ render: () => u(
249
+ "div",
250
+ {
251
+ ...F,
252
+ class: `tachui-textfield ${F.class || ""}`.trim(),
253
+ "data-tachui-textfield-container": !0,
254
+ "data-field-state": f ? "error" : a.validating() ? "validating" : "valid"
255
+ },
256
+ ...r ? [
257
+ u(
258
+ "label",
259
+ {
260
+ for: k.id,
261
+ "data-tachui-label": !0,
262
+ "data-required": $
263
+ },
264
+ y(r),
265
+ ...$ ? [
266
+ u(
267
+ "span",
268
+ {
269
+ "aria-label": "required",
270
+ "data-required-indicator": !0
271
+ },
272
+ y(" *")
273
+ )
274
+ ] : []
275
+ )
276
+ ] : [],
277
+ // Input field
278
+ u(s ? "textarea" : "input", {
279
+ ...k,
280
+ ...s ? { rows: m } : {}
281
+ }),
282
+ ...g ? [
283
+ u(
284
+ "div",
285
+ {
286
+ id: `${t}-counter`,
287
+ "data-tachui-character-counter": !0,
288
+ "data-over-limit": _() > g
289
+ },
290
+ y(`${_()}/${g}`)
291
+ )
292
+ ] : [],
293
+ ...f ? [
294
+ u(
295
+ "div",
296
+ {
297
+ id: `${t}-error`,
298
+ role: "alert",
299
+ "aria-live": "polite",
300
+ "data-tachui-error": !0
301
+ },
302
+ y(f)
303
+ )
304
+ ] : [],
305
+ ...T && !f ? [
306
+ u(
307
+ "div",
308
+ {
309
+ id: `${t}-helper`,
310
+ "data-tachui-helper": !0
311
+ },
312
+ y(T)
313
+ )
314
+ ] : [],
315
+ ...S ? [
316
+ u(
317
+ "div",
318
+ {
319
+ id: `${t}-hint`,
320
+ "data-tachui-accessibility-hint": !0,
321
+ "aria-hidden": "true"
322
+ },
323
+ y(S)
324
+ )
325
+ ] : [],
326
+ ...a.validating() ? [
327
+ u(
328
+ "div",
329
+ {
330
+ "data-tachui-validation-spinner": !0,
331
+ "aria-label": "Validating...",
332
+ "aria-live": "polite"
333
+ },
334
+ y("⏳")
335
+ )
336
+ ] : []
337
+ ),
338
+ props: e,
339
+ cleanup: [
340
+ () => {
341
+ o && o.unregister(t);
342
+ }
343
+ ]
344
+ };
345
+ }, De = (e) => l({
346
+ ...e,
347
+ type: "email",
348
+ keyboardType: "email",
349
+ validation: {
350
+ rules: ["required", "email"],
351
+ validateOn: "blur",
352
+ ...e.validation
353
+ },
354
+ accessibilityRole: "textbox",
355
+ accessibilityLabel: e.accessibilityLabel || "Email address"
356
+ }), Pe = (e) => {
357
+ const {
358
+ showStrengthIndicator: t = !1,
359
+ strongValidation: r = !1,
360
+ minLength: b,
361
+ ...n
362
+ } = e, s = ["required"];
363
+ return r ? s.push("strongPassword") : (s.push("minLength"), s.push({ name: "minLength", options: { minLength: b || 6 } })), l({
364
+ ...n,
365
+ type: "password",
366
+ validation: {
367
+ rules: s,
368
+ validateOn: "change",
369
+ ...e.validation
370
+ },
371
+ accessibilityLabel: e.accessibilityLabel || "Password"
372
+ });
373
+ }, Ve = (e) => l({
374
+ ...e,
375
+ type: "search",
376
+ keyboardType: "search",
377
+ placeholder: e.placeholder || "Search...",
378
+ accessibilityRole: "searchbox",
379
+ accessibilityLabel: e.accessibilityLabel || "Search"
380
+ }), Ne = (e) => l({
381
+ ...e,
382
+ type: "url",
383
+ keyboardType: "url",
384
+ validation: {
385
+ rules: ["url"],
386
+ validateOn: "blur",
387
+ ...e.validation
388
+ },
389
+ accessibilityLabel: e.accessibilityLabel || "Website URL"
390
+ }), ke = (e) => {
391
+ const { format: t = "us", ...r } = e;
392
+ return l({
393
+ ...r,
394
+ type: "tel",
395
+ keyboardType: "phone",
396
+ formatter: h.phone,
397
+ parser: p.phone,
398
+ validation: {
399
+ rules: ["phone"],
400
+ validateOn: "blur",
401
+ ...e.validation
402
+ },
403
+ accessibilityLabel: e.accessibilityLabel || "Phone number"
404
+ });
405
+ }, Oe = (e) => {
406
+ const { min: t, max: r, precision: b = 0, currency: n = !1, ...s } = e, m = ["numeric"];
407
+ return t !== void 0 && (m.push("min"), m.push({ name: "min", options: { min: t } })), r !== void 0 && (m.push("max"), m.push({ name: "max", options: { max: r } })), l({
408
+ ...s,
409
+ type: "number",
410
+ keyboardType: "numeric",
411
+ formatter: n ? h.currency : b > 0 ? h.decimal(b) : void 0,
412
+ parser: n ? p.currency : p.decimal,
413
+ validation: {
414
+ rules: m,
415
+ validateOn: "blur",
416
+ ...e.validation
417
+ },
418
+ accessibilityLabel: e.accessibilityLabel || "Number"
419
+ });
420
+ }, ze = (e) => l({
421
+ ...e,
422
+ type: "text",
423
+ keyboardType: "numeric",
424
+ formatter: h.creditCard,
425
+ parser: p.creditCard,
426
+ maxLength: 19,
427
+ // 16 digits + 3 spaces
428
+ validation: {
429
+ rules: ["creditCard"],
430
+ validateOn: "blur",
431
+ ...e.validation
432
+ },
433
+ accessibilityLabel: e.accessibilityLabel || "Credit card number"
434
+ }), Ee = (e) => l({
435
+ ...e,
436
+ type: "text",
437
+ keyboardType: "numeric",
438
+ formatter: h.ssn,
439
+ parser: p.ssn,
440
+ maxLength: 11,
441
+ // 9 digits + 2 hyphens
442
+ validation: {
443
+ rules: ["ssn"],
444
+ validateOn: "blur",
445
+ ...e.validation
446
+ },
447
+ accessibilityLabel: e.accessibilityLabel || "Social Security Number"
448
+ }), Ue = (e) => l({
449
+ ...e,
450
+ type: "text",
451
+ keyboardType: "numeric",
452
+ formatter: h.postalCode,
453
+ parser: p.postalCode,
454
+ maxLength: 10,
455
+ // 5 or 9 digits + hyphen
456
+ validation: {
457
+ rules: ["zipCode"],
458
+ // Use zipCode to match test expectation
459
+ validateOn: "blur",
460
+ ...e.validation
461
+ },
462
+ accessibilityLabel: e.accessibilityLabel || "Postal code"
463
+ }), qe = (e) => l({
464
+ ...e,
465
+ multiline: !0,
466
+ accessibilityLabel: e.accessibilityLabel || "Text area"
467
+ }), Re = (e) => {
468
+ const { min: t, max: r, ...b } = e, n = ["date"];
469
+ return t && n.push({ name: "min", options: { min: new Date(t) } }), r && n.push({ name: "max", options: { max: new Date(r) } }), l({
470
+ ...b,
471
+ type: "date",
472
+ validation: {
473
+ rules: n,
474
+ validateOn: "blur",
475
+ ...e.validation
476
+ },
477
+ accessibilityLabel: e.accessibilityLabel || "Date"
478
+ });
479
+ }, Be = (e) => l({
480
+ ...e,
481
+ type: "time",
482
+ validation: {
483
+ rules: ["time"],
484
+ validateOn: "blur",
485
+ ...e.validation
486
+ },
487
+ accessibilityLabel: e.accessibilityLabel || "Time"
488
+ }), Ie = (e) => l({
489
+ ...e,
490
+ type: "color",
491
+ accessibilityLabel: e.accessibilityLabel || "Color picker"
492
+ });
493
+ export {
494
+ ze as C,
495
+ Re as D,
496
+ De as E,
497
+ Oe as N,
498
+ Pe as P,
499
+ Ve as S,
500
+ l as T,
501
+ Ne as U,
502
+ ke as a,
503
+ Ee as b,
504
+ Ue as c,
505
+ qe as d,
506
+ Be as e,
507
+ Ie as f
508
+ };
509
+ //# sourceMappingURL=TextField-hX15dY3U.js.map