@fuf-stack/uniform 0.22.0 → 0.23.0

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 (80) hide show
  1. package/dist/CheckboxGroup/index.cjs +2 -2
  2. package/dist/CheckboxGroup/index.js +2 -2
  3. package/dist/FieldArray/index.cjs +2 -2
  4. package/dist/FieldArray/index.js +2 -2
  5. package/dist/Form/index.cjs +2 -2
  6. package/dist/Form/index.js +2 -2
  7. package/dist/Input/index.cjs +4 -4
  8. package/dist/Input/index.d.cts +2 -2
  9. package/dist/Input/index.d.ts +2 -2
  10. package/dist/Input/index.js +3 -3
  11. package/dist/{Input-DsBWaOSk.d.ts → Input-BpsVvxwO.d.ts} +2 -2
  12. package/dist/{Input-qD-RcDl4.d.cts → Input-Com9bFxL.d.cts} +2 -2
  13. package/dist/RadioBoxes/index.cjs +2 -2
  14. package/dist/RadioBoxes/index.js +2 -2
  15. package/dist/RadioGroup/index.cjs +2 -2
  16. package/dist/RadioGroup/index.js +2 -2
  17. package/dist/RadioTabs/index.cjs +4 -4
  18. package/dist/RadioTabs/index.js +3 -3
  19. package/dist/Select/index.cjs +2 -2
  20. package/dist/Select/index.js +2 -2
  21. package/dist/SubmitButton/index.cjs +2 -2
  22. package/dist/SubmitButton/index.js +2 -2
  23. package/dist/Switch/index.cjs +4 -4
  24. package/dist/Switch/index.d.cts +4 -2
  25. package/dist/Switch/index.d.ts +4 -2
  26. package/dist/Switch/index.js +3 -3
  27. package/dist/{Switch-CLs964dL.d.cts → Switch-BaMtW2HN.d.cts} +12 -3
  28. package/dist/{Switch-CLs964dL.d.ts → Switch-BaMtW2HN.d.ts} +12 -3
  29. package/dist/TextArea/index.cjs +4 -4
  30. package/dist/TextArea/index.js +3 -3
  31. package/dist/{chunk-NR5MV234.js → chunk-3PTHYFAU.js} +10 -2
  32. package/dist/chunk-3PTHYFAU.js.map +1 -0
  33. package/dist/{chunk-SHB3Z5GN.cjs → chunk-AZT3TDWZ.cjs} +3 -3
  34. package/dist/{chunk-SHB3Z5GN.cjs.map → chunk-AZT3TDWZ.cjs.map} +1 -1
  35. package/dist/{chunk-QTROOQ53.cjs → chunk-DOBUPJPN.cjs} +10 -2
  36. package/dist/chunk-DOBUPJPN.cjs.map +1 -0
  37. package/dist/{chunk-IZFO7YMQ.js → chunk-GHO2VFUQ.js} +2 -2
  38. package/dist/{chunk-IZFO7YMQ.js.map → chunk-GHO2VFUQ.js.map} +1 -1
  39. package/dist/{chunk-IAMV2JNU.cjs → chunk-I4OVSJFQ.cjs} +2 -2
  40. package/dist/chunk-I4OVSJFQ.cjs.map +1 -0
  41. package/dist/{chunk-XDHY7DXJ.js → chunk-NNKOK5EU.js} +2 -2
  42. package/dist/{chunk-I2PJDXWB.cjs → chunk-OWWUTKGY.cjs} +18 -41
  43. package/dist/chunk-OWWUTKGY.cjs.map +1 -0
  44. package/dist/chunk-P6HJOG7D.cjs +41 -0
  45. package/dist/chunk-P6HJOG7D.cjs.map +1 -0
  46. package/dist/chunk-Q2BOMFJ5.js +41 -0
  47. package/dist/chunk-Q2BOMFJ5.js.map +1 -0
  48. package/dist/{chunk-EPY6UDD3.js → chunk-QDFIRRB5.js} +4 -4
  49. package/dist/chunk-QDFIRRB5.js.map +1 -0
  50. package/dist/{chunk-2EYP66KF.cjs → chunk-SG6PWCRL.cjs} +5 -5
  51. package/dist/chunk-SG6PWCRL.cjs.map +1 -0
  52. package/dist/{chunk-KMDTMBYI.js → chunk-U5WBLGZV.js} +18 -41
  53. package/dist/chunk-U5WBLGZV.js.map +1 -0
  54. package/dist/hooks/index.cjs +3 -3
  55. package/dist/hooks/index.js +2 -2
  56. package/dist/hooks/useInputValueDebounce/index.cjs +3 -3
  57. package/dist/hooks/useInputValueDebounce/index.d.cts +6 -6
  58. package/dist/hooks/useInputValueDebounce/index.d.ts +6 -6
  59. package/dist/hooks/useInputValueDebounce/index.js +2 -2
  60. package/dist/hooks/useInputValueTransform/index.cjs +2 -2
  61. package/dist/hooks/useInputValueTransform/index.d.cts +28 -60
  62. package/dist/hooks/useInputValueTransform/index.d.ts +28 -60
  63. package/dist/hooks/useInputValueTransform/index.js +1 -1
  64. package/dist/index.cjs +7 -7
  65. package/dist/index.d.cts +3 -2
  66. package/dist/index.d.ts +3 -2
  67. package/dist/index.js +6 -6
  68. package/package.json +4 -4
  69. package/dist/chunk-2EYP66KF.cjs.map +0 -1
  70. package/dist/chunk-EPY6UDD3.js.map +0 -1
  71. package/dist/chunk-G5UX55XC.js +0 -37
  72. package/dist/chunk-G5UX55XC.js.map +0 -1
  73. package/dist/chunk-I2PJDXWB.cjs.map +0 -1
  74. package/dist/chunk-IAMV2JNU.cjs.map +0 -1
  75. package/dist/chunk-KMDTMBYI.js.map +0 -1
  76. package/dist/chunk-NR5MV234.js.map +0 -1
  77. package/dist/chunk-QTROOQ53.cjs.map +0 -1
  78. package/dist/chunk-TSB65253.cjs +0 -37
  79. package/dist/chunk-TSB65253.cjs.map +0 -1
  80. /package/dist/{chunk-XDHY7DXJ.js.map → chunk-NNKOK5EU.js.map} +0 -0
@@ -1,37 +0,0 @@
1
- // src/hooks/useInputValueTransform/useInputValueTransform.ts
2
- import { useEffect, useRef, useState } from "react";
3
- var useInputValueTransform = ({
4
- value,
5
- type,
6
- transformValue
7
- }) => {
8
- const prevExternalValue = useRef(value);
9
- const [displayValue, setDisplayValue] = useState(() => {
10
- return (transformValue == null ? void 0 : transformValue.displayValue) ? transformValue.displayValue(value != null ? value : "") : value != null ? value : "";
11
- });
12
- useEffect(() => {
13
- if (value !== prevExternalValue.current) {
14
- prevExternalValue.current = value;
15
- const newDisplayValue = (transformValue == null ? void 0 : transformValue.displayValue) ? transformValue.displayValue(value != null ? value : "") : value != null ? value : "";
16
- setDisplayValue(newDisplayValue);
17
- }
18
- }, [value, transformValue]);
19
- const getFormValue = () => {
20
- if (type === "number") {
21
- return displayValue === "" ? "" : Number(displayValue);
22
- }
23
- return (transformValue == null ? void 0 : transformValue.formValue) ? transformValue.formValue(displayValue) : displayValue;
24
- };
25
- return {
26
- displayValue,
27
- handleInputChange: (e) => {
28
- setDisplayValue(e.target.value);
29
- },
30
- getFormValue
31
- };
32
- };
33
-
34
- export {
35
- useInputValueTransform
36
- };
37
- //# sourceMappingURL=chunk-G5UX55XC.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/useInputValueTransform/useInputValueTransform.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nexport interface InputValueTransform {\n /** Transforms the form value to display value (e.g., 1000 → \"$1,000\") */\n displayValue: (value: string | number) => string | number;\n /** Transforms the display value to form value (e.g., \"$1,000\" → 1000) */\n formValue: (value: string) => string | number;\n}\n\nexport interface UseInputValueTransformOptions {\n /** The current form field value */\n value: string | number;\n /** Input type for special number handling */\n type?: 'text' | 'number' | 'password';\n /** Value transformation functions */\n transformValue?: InputValueTransform;\n}\n\nexport interface UseInputValueTransformReturn {\n /** The current display value for the input */\n displayValue: string | number;\n /** Input change handler (pass directly to onChange) */\n handleInputChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n /** Gets the form value from current display value */\n getFormValue: () => string | number;\n}\n\n/**\n * Custom hook for handling input value transformations between display and form values.\n *\n * This hook manages the separation between what the user sees (display value) and what gets\n * stored in the form (form value). It's particularly useful for:\n * - Currency formatting ($1,000 display vs 1000 stored)\n * - Number inputs with special handling\n * - Date formatting (MM/DD/YYYY display vs ISO date stored)\n * - Phone number formatting ((555) 123-4567 display vs 5551234567 stored)\n *\n * **Key Features:**\n * - Immediate display value updates for responsive UI\n * - Automatic external value synchronization (form resets, setValue calls)\n * - Special number input handling (empty string preservation)\n * - Bidirectional value transformations\n *\n * @param options Configuration for value transformation\n * @returns Display value management and form value conversion\n *\n * @example\n * ```tsx\n * // Currency formatting\n * const currencyTransform = {\n * displayValue: (val) => val ? `$${Number(val).toLocaleString()}` : '',\n * formValue: (val) => parseFloat(val.replace(/[$,]/g, '')) || 0\n * };\n *\n * const { displayValue, handleInputChange, getFormValue } = useInputValueTransform({\n * value: 1000,\n * transformValue: currencyTransform\n * });\n * // displayValue = \"$1,000\"\n * // getFormValue() = 1000\n * ```\n *\n * @example\n * ```tsx\n * // Phone number formatting\n * const phoneTransform = {\n * displayValue: (val) => {\n * const cleaned = val.toString().replace(/\\D/g, '');\n * const match = cleaned.match(/^(\\d{3})(\\d{3})(\\d{4})$/);\n * return match ? `(${match[1]}) ${match[2]}-${match[3]}` : val;\n * },\n * formValue: (val) => val.replace(/\\D/g, '')\n * };\n *\n * const { displayValue, handleInputChange, getFormValue } = useInputValueTransform({\n * value: '5551234567',\n * transformValue: phoneTransform\n * });\n * // displayValue = \"(555) 123-4567\"\n * // getFormValue() = \"5551234567\"\n * ```\n *\n * @example\n * ```tsx\n * // Number input (no transforms needed)\n * const { displayValue, handleInputChange, getFormValue } = useInputValueTransform({\n * value: 42,\n * type: 'number'\n * });\n * // Handles empty string → empty string (not NaN)\n * // Handles \"123\" → 123 (string to number conversion)\n * ```\n *\n * @example\n * ```tsx\n * // Usage in a form component\n * const MyInput = ({ field, transformValue }) => {\n * const { displayValue, handleInputChange, getFormValue } = useInputValueTransform({\n * value: field.value,\n * transformValue\n * });\n *\n * // Debounce the form updates (optional)\n * useInputValueDebounce({\n * value: getFormValue(),\n * onChange: field.onChange,\n * debounceDelay: 300\n * });\n *\n * return (\n * <input\n * value={displayValue}\n * onChange={handleInputChange}\n * />\n * );\n * };\n * ```\n */\nexport const useInputValueTransform = ({\n value,\n type,\n transformValue,\n}: UseInputValueTransformOptions): UseInputValueTransformReturn => {\n // Track previous external value to detect real external changes\n const prevExternalValue = useRef(value);\n\n // Local state for immediate display updates\n const [displayValue, setDisplayValue] = useState(() => {\n return transformValue?.displayValue\n ? transformValue.displayValue(value ?? '')\n : (value ?? '');\n });\n\n /**\n * Synchronizes display value when form value changes externally.\n *\n * This handles cases like:\n * - Form resets: reset() or setValue('field', '')\n * - External updates: setValue('field', 'new value')\n * - Default value initialization from form state\n * - Programmatic field updates from other components\n *\n * Uses a ref to track the previous value and only updates when the external\n * value actually changes, preventing infinite re-renders.\n */\n useEffect(() => {\n // Only process if the external value actually changed\n if (value !== prevExternalValue.current) {\n prevExternalValue.current = value;\n\n const newDisplayValue = transformValue?.displayValue\n ? transformValue.displayValue(value ?? '')\n : (value ?? '');\n\n setDisplayValue(newDisplayValue);\n }\n }, [value, transformValue]);\n\n /**\n * Converts the current display value to the appropriate form value.\n *\n * **Conversion Logic:**\n * 1. **Number inputs**:\n * - Empty string → empty string (preserves empty state, prevents NaN)\n * - Non-empty string → Number(value) (converts to numeric form)\n * - Example: \"\" → \"\", \"42\" → 42, \"3.14\" → 3.14\n *\n * 2. **Transform inputs**:\n * - Applies custom formValue transform function\n * - Used for converting display format back to storage format\n * - Example: \"$1,000\" → 1000, \"(555) 123-4567\" → \"5551234567\"\n *\n * 3. **Regular inputs**:\n * - Passes through the display value unchanged\n * - Example: \"hello\" → \"hello\", \"test@example.com\" → \"test@example.com\"\n *\n * @returns The form value ready for storage/submission\n */\n const getFormValue = (): string | number => {\n if (type === 'number') {\n return displayValue === '' ? '' : Number(displayValue);\n }\n\n return transformValue?.formValue\n ? transformValue.formValue(displayValue as string)\n : displayValue;\n };\n\n return {\n displayValue,\n handleInputChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n setDisplayValue(e.target.value);\n },\n getFormValue,\n };\n};\n"],"mappings":";AAAA,SAAS,WAAW,QAAQ,gBAAgB;AAsHrC,IAAM,yBAAyB,CAAC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF,MAAmE;AAEjE,QAAM,oBAAoB,OAAO,KAAK;AAGtC,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,MAAM;AACrD,YAAO,iDAAgB,gBACnB,eAAe,aAAa,wBAAS,EAAE,IACtC,wBAAS;AAAA,EAChB,CAAC;AAcD,YAAU,MAAM;AAEd,QAAI,UAAU,kBAAkB,SAAS;AACvC,wBAAkB,UAAU;AAE5B,YAAM,mBAAkB,iDAAgB,gBACpC,eAAe,aAAa,wBAAS,EAAE,IACtC,wBAAS;AAEd,sBAAgB,eAAe;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,OAAO,cAAc,CAAC;AAsB1B,QAAM,eAAe,MAAuB;AAC1C,QAAI,SAAS,UAAU;AACrB,aAAO,iBAAiB,KAAK,KAAK,OAAO,YAAY;AAAA,IACvD;AAEA,YAAO,iDAAgB,aACnB,eAAe,UAAU,YAAsB,IAC/C;AAAA,EACN;AAEA,SAAO;AAAA,IACL;AAAA,IACA,mBAAmB,CAAC,MAA2C;AAC7D,sBAAgB,EAAE,OAAO,KAAK;AAAA,IAChC;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-I2PJDXWB.cjs","../src/hooks/useInputValueDebounce/useInputValueDebounce.ts"],"names":["_a"],"mappings":"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","file":"/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-I2PJDXWB.cjs","sourcesContent":[null,"import type { InputValueTransform } from '../useInputValueTransform/useInputValueTransform';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useInputValueTransform } from '../useInputValueTransform/useInputValueTransform';\n\nexport interface UseInputValueDebounceOptions {\n /** Debounce delay in milliseconds (default: 300) */\n debounceDelay?: number;\n /** The onBlur function to call after flushing debounced value */\n onBlur: () => void;\n /** The onChange function to call with debounced value */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onChange: (...event: any[]) => void;\n /** Value transformation functions */\n transformValue?: InputValueTransform;\n /** Input type to handle number conversion (optional) */\n type?: 'text' | 'number' | 'password';\n /** The value to debounce */\n value: string | number;\n}\n\nexport interface UseInputValueDebounceReturn {\n /** Enhanced onChange function with debouncing */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onChange: (...event: any[]) => void;\n /** Enhanced onBlur function that flushes current value immediately */\n onBlur: () => void;\n /** The field value that is displayed - updates immediately */\n value: string | number;\n}\n\n/**\n * Custom hook for debouncing input value changes with immediate blur support.\n *\n * Provides immediate visual feedback by updating the display value instantly,\n * while debouncing the actual form state changes. When the input loses focus,\n * any pending debounced changes are immediately flushed.\n *\n * **Key Features:**\n * - **Debouncing**: Delays form updates until user stops typing\n * - **Transform support**: Optional value transformation between display and form values\n * - **Number conversion**: Automatic conversion for number inputs\n * - **Immediate display updates**: UI stays responsive during debouncing\n * - **Blur flushing**: Immediately applies pending changes on blur\n *\n * @param options Configuration for debounced value handling\n * @param options.debounceDelay Delay in milliseconds (default: 300)\n * @param options.onBlur Function to call after flushing debounced value\n * @param options.onChange Function to call with debounced value\n * @param options.transformValue Optional transform functions for display ↔ form value conversion\n * @param options.type Input type for number conversion ('text' | 'number' | 'password')\n * @param options.value The value to debounce\n * @returns Object containing enhanced onChange, onBlur, and immediate display value\n *\n * @example\n * Basic usage with debouncing:\n * ```tsx\n * const { onChange, onBlur, value } = useInputValueDebounce({\n * debounceDelay: 300,\n * onBlur: field.onBlur,\n * onChange: field.onChange,\n * value: field.value,\n * });\n * ```\n *\n * @example\n * Number input with automatic conversion:\n * ```tsx\n * const { onChange, onBlur, value } = useInputValueDebounce({\n * debounceDelay: 300,\n * onBlur: field.onBlur,\n * onChange: field.onChange,\n * type: 'number',\n * value: field.value, // Display: 123 (number), Form: 123 (number)\n * });\n * ```\n *\n * @example\n * Currency formatting with transforms:\n * ```tsx\n * const currencyTransform = {\n * displayValue: (val) => val ? `$${Number(val).toFixed(2)}` : '',\n * formValue: (val) => Number(val.replace(/[$,]/g, '')) || 0\n * };\n *\n * const { onChange, onBlur, value } = useInputValueDebounce({\n * debounceDelay: 300,\n * onBlur: field.onBlur,\n * onChange: field.onChange,\n * transformValue: currencyTransform,\n * value: field.value, // Display: \"$100.00\", Form: 100\n * });\n * ```\n */\nexport const useInputValueDebounce = ({\n debounceDelay = 300,\n onBlur,\n onChange,\n transformValue,\n type,\n value,\n}: UseInputValueDebounceOptions): UseInputValueDebounceReturn => {\n // Use transform hook if transformValue is provided\n const transform = useInputValueTransform({\n transformValue,\n type,\n value,\n });\n\n // Helper function to convert any value to the appropriate form value\n const getFormValue = useCallback(\n (rawValue: string | number) => {\n const stringValue = String(rawValue);\n\n if (transformValue) {\n return transformValue.formValue(stringValue);\n }\n\n if (type === 'number' && stringValue !== '') {\n const numValue = Number(stringValue);\n return Number.isNaN(numValue) ? rawValue : numValue;\n }\n\n return rawValue;\n },\n [transformValue, type],\n );\n\n // Use transform display value if available, otherwise use original value\n const displayValue = transformValue ? transform.displayValue : value;\n const [currentDisplayValue, setCurrentDisplayValue] = useState(displayValue);\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n // Sync display value when external value changes\n useEffect(() => {\n setCurrentDisplayValue(displayValue);\n }, [displayValue]);\n\n // Enhanced onChange handler\n const handleChange = useCallback(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (...event: any[]) => {\n const newValue = event[0]?.target?.value ?? event[0];\n\n // Convert display value to number if type is number and no transform\n let displayVal = newValue;\n if (!transformValue && type === 'number' && newValue !== '') {\n const numValue = Number(newValue);\n displayVal = Number.isNaN(numValue) ? newValue : numValue;\n }\n\n // Update display immediately\n setCurrentDisplayValue(displayVal);\n\n // Update transform if needed\n if (transformValue && event[0]?.target) {\n transform.handleInputChange(event[0]);\n }\n\n // Get form value using helper\n const formValue = getFormValue(newValue);\n\n // Clear existing timeout\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n const executeOnChange = () => {\n // Preserve event structure if original was an event\n if (event[0]?.target) {\n const convertedEvent = {\n ...event[0],\n target: {\n ...event[0].target,\n value: formValue,\n },\n };\n onChange(convertedEvent, ...event.slice(1));\n } else {\n onChange(formValue);\n }\n };\n\n // Execute immediately or after delay\n if (debounceDelay <= 0) {\n executeOnChange();\n } else {\n timeoutRef.current = setTimeout(executeOnChange, debounceDelay);\n }\n },\n [onChange, debounceDelay, transformValue, transform, type, getFormValue],\n );\n\n // Enhanced blur handler\n const handleBlur = useCallback(() => {\n // Flush pending changes\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n\n // Get form value using helper\n const formValue = getFormValue(currentDisplayValue);\n onChange(formValue);\n }\n onBlur();\n }, [currentDisplayValue, onChange, onBlur, getFormValue]);\n\n return {\n onChange: handleChange,\n onBlur: handleBlur,\n value: currentDisplayValue,\n };\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-IAMV2JNU.cjs","../src/RadioTabs/RadioTabs.tsx","../src/RadioTabs/index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-IAMV2JNU.cjs","sourcesContent":[null,"import type { TVClassName, TVProps } from '@fuf-stack/pixel-utils';\nimport type { TabsProps } from '@fuf-stack/pixels';\nimport type { TabProps } from '@fuf-stack/pixels/Tabs';\nimport type { ReactElement, ReactNode } from 'react';\n\nimport { RadioGroup as HeroRadioGroup } from '@heroui/radio';\n\nimport { slugify, tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\nimport Tabs from '@fuf-stack/pixels/Tabs';\n\nimport { useController, useFormContext } from '../hooks';\nimport { FieldCopyTestIdButton } from '../partials/FieldCopyTestIdButton';\nimport { FieldValidationError } from '../partials/FieldValidationError';\n\nexport const radioTabsVariants = tv({\n slots: {\n base: 'group', // Needs group for group-data condition\n label:\n 'text-sm text-foreground subpixel-antialiased group-data-[invalid=true]:text-danger',\n wrapper: '',\n tabList: '',\n tab: '',\n tabContent: '',\n cursor: '',\n panel: '',\n },\n});\n\ntype VariantProps = TVProps<typeof radioTabsVariants>;\ntype ClassName = TVClassName<typeof radioTabsVariants>;\n\nexport interface RadioTabsOption {\n /** Optional content inside of the tab */\n content?: ReactNode;\n /** disables the option */\n disabled?: boolean;\n /** option label */\n label?: React.ReactNode;\n /** option icon */\n icon?: ReactNode;\n /** HTML data-testid attribute of the option */\n testId?: string;\n /** option value */\n value: string;\n}\n\nexport interface RadioTabsProps extends VariantProps {\n /** CSS class name */\n className?: ClassName;\n /** Determines if the Buttons are disabled or not. */\n disabled?: boolean;\n /** determines orientation of the Buttons. */\n inline?: boolean;\n /** Label displayed next to the RadioButton. */\n label?: ReactNode;\n /** Name the RadioButtons are registered at in HTML forms (react-hook-form). */\n name: string;\n /** Radio button configuration. */\n options: RadioTabsOption[];\n /** Id to grab element in internal tests. */\n testId?: string;\n /** How the RadioTabs should look like. */\n variant?: TabsProps['variant'];\n}\n\n/**\n * RadioTabs component based on [HeroUI RadioGroup](https://www.heroui.com//docs/components/radio-group)\n * and [HeroUI Tabs](https://www.heroui.com//docs/components/tabs)\n */\nconst RadioTabs = ({\n className = undefined,\n disabled = false,\n inline = false,\n label = undefined,\n name,\n options,\n testId: _testId = undefined,\n variant = undefined,\n}: RadioTabsProps): ReactElement => {\n const { control, debugMode, getFieldState } = useFormContext();\n const { error, invalid, required, testId } = getFieldState(name, _testId);\n\n const { field } = useController({ control, disabled, name });\n const { disabled: isDisabled, onBlur, onChange, ref, value } = field;\n\n const showTestIdCopyButton = debugMode === 'debug-testids';\n const showLabel = label || showTestIdCopyButton;\n\n const variants = radioTabsVariants();\n const classNames = variantsToClassNames(variants, className, 'base');\n\n const tabOptions = options.map<TabProps>((option) => ({\n content: option?.content,\n disabled: option?.disabled,\n key: option.value,\n label: option?.label || option?.value,\n testId: slugify(`option_${option?.testId || option?.value}`, {\n replaceDots: true,\n }),\n }));\n\n const disabledAllKeys: string[] | undefined = tabOptions?.map(\n (option) => option.key as string,\n );\n\n return (\n <HeroRadioGroup\n classNames={classNames}\n // see HeroUI styles for group-data condition (data-invalid),\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/components/select/src/use-select.ts\n data-invalid={invalid}\n data-required={required}\n data-testid={testId}\n errorMessage={\n error && <FieldValidationError error={error} testId={testId} />\n }\n isDisabled={isDisabled}\n isInvalid={invalid}\n isRequired={required}\n label={\n showLabel && (\n // eslint-disable-next-line jsx-a11y/label-has-associated-control\n <label>\n {label}\n {showTestIdCopyButton && <FieldCopyTestIdButton testId={testId} />}\n </label>\n )\n }\n name={name}\n orientation={inline ? 'horizontal' : 'vertical'}\n onBlur={onBlur}\n ref={ref}\n >\n <Tabs\n disabledKeys={disabled ? disabledAllKeys : undefined}\n fullWidth={false}\n onSelectionChange={onChange}\n selectedKey={value}\n tabs={tabOptions as TabProps[]}\n testId={testId}\n variant={variant}\n />\n </HeroRadioGroup>\n );\n};\n\nexport default RadioTabs;\n","import RadioTabs from './RadioTabs';\n\nexport type { RadioTabsProps } from './RadioTabs';\n\nexport { RadioTabs };\n\nexport default RadioTabs;\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/useInputValueDebounce/useInputValueDebounce.ts"],"sourcesContent":["import type { InputValueTransform } from '../useInputValueTransform/useInputValueTransform';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useInputValueTransform } from '../useInputValueTransform/useInputValueTransform';\n\nexport interface UseInputValueDebounceOptions {\n /** Debounce delay in milliseconds (default: 300) */\n debounceDelay?: number;\n /** The onBlur function to call after flushing debounced value */\n onBlur: () => void;\n /** The onChange function to call with debounced value */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onChange: (...event: any[]) => void;\n /** Value transformation functions */\n transformValue?: InputValueTransform;\n /** Input type to handle number conversion (optional) */\n type?: 'text' | 'number' | 'password';\n /** The value to debounce */\n value: string | number;\n}\n\nexport interface UseInputValueDebounceReturn {\n /** Enhanced onChange function with debouncing */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onChange: (...event: any[]) => void;\n /** Enhanced onBlur function that flushes current value immediately */\n onBlur: () => void;\n /** The field value that is displayed - updates immediately */\n value: string | number;\n}\n\n/**\n * Custom hook for debouncing input value changes with immediate blur support.\n *\n * Provides immediate visual feedback by updating the display value instantly,\n * while debouncing the actual form state changes. When the input loses focus,\n * any pending debounced changes are immediately flushed.\n *\n * **Key Features:**\n * - **Debouncing**: Delays form updates until user stops typing\n * - **Transform support**: Optional value transformation between display and form values\n * - **Number conversion**: Automatic conversion for number inputs\n * - **Immediate display updates**: UI stays responsive during debouncing\n * - **Blur flushing**: Immediately applies pending changes on blur\n *\n * @param options Configuration for debounced value handling\n * @param options.debounceDelay Delay in milliseconds (default: 300)\n * @param options.onBlur Function to call after flushing debounced value\n * @param options.onChange Function to call with debounced value\n * @param options.transformValue Optional transform functions for display ↔ form value conversion\n * @param options.type Input type for number conversion ('text' | 'number' | 'password')\n * @param options.value The value to debounce\n * @returns Object containing enhanced onChange, onBlur, and immediate display value\n *\n * @example\n * Basic usage with debouncing:\n * ```tsx\n * const { onChange, onBlur, value } = useInputValueDebounce({\n * debounceDelay: 300,\n * onBlur: field.onBlur,\n * onChange: field.onChange,\n * value: field.value,\n * });\n * ```\n *\n * @example\n * Number input with automatic conversion:\n * ```tsx\n * const { onChange, onBlur, value } = useInputValueDebounce({\n * debounceDelay: 300,\n * onBlur: field.onBlur,\n * onChange: field.onChange,\n * type: 'number',\n * value: field.value, // Display: 123 (number), Form: 123 (number)\n * });\n * ```\n *\n * @example\n * Currency formatting with transforms:\n * ```tsx\n * const currencyTransform = {\n * displayValue: (val) => val ? `$${Number(val).toFixed(2)}` : '',\n * formValue: (val) => Number(val.replace(/[$,]/g, '')) || 0\n * };\n *\n * const { onChange, onBlur, value } = useInputValueDebounce({\n * debounceDelay: 300,\n * onBlur: field.onBlur,\n * onChange: field.onChange,\n * transformValue: currencyTransform,\n * value: field.value, // Display: \"$100.00\", Form: 100\n * });\n * ```\n */\nexport const useInputValueDebounce = ({\n debounceDelay = 300,\n onBlur,\n onChange,\n transformValue,\n type,\n value,\n}: UseInputValueDebounceOptions): UseInputValueDebounceReturn => {\n // Use transform hook if transformValue is provided\n const transform = useInputValueTransform({\n transformValue,\n type,\n value,\n });\n\n // Helper function to convert any value to the appropriate form value\n const getFormValue = useCallback(\n (rawValue: string | number) => {\n const stringValue = String(rawValue);\n\n if (transformValue) {\n return transformValue.formValue(stringValue);\n }\n\n if (type === 'number' && stringValue !== '') {\n const numValue = Number(stringValue);\n return Number.isNaN(numValue) ? rawValue : numValue;\n }\n\n return rawValue;\n },\n [transformValue, type],\n );\n\n // Use transform display value if available, otherwise use original value\n const displayValue = transformValue ? transform.displayValue : value;\n const [currentDisplayValue, setCurrentDisplayValue] = useState(displayValue);\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n // Sync display value when external value changes\n useEffect(() => {\n setCurrentDisplayValue(displayValue);\n }, [displayValue]);\n\n // Enhanced onChange handler\n const handleChange = useCallback(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (...event: any[]) => {\n const newValue = event[0]?.target?.value ?? event[0];\n\n // Convert display value to number if type is number and no transform\n let displayVal = newValue;\n if (!transformValue && type === 'number' && newValue !== '') {\n const numValue = Number(newValue);\n displayVal = Number.isNaN(numValue) ? newValue : numValue;\n }\n\n // Update display immediately\n setCurrentDisplayValue(displayVal);\n\n // Update transform if needed\n if (transformValue && event[0]?.target) {\n transform.handleInputChange(event[0]);\n }\n\n // Get form value using helper\n const formValue = getFormValue(newValue);\n\n // Clear existing timeout\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n const executeOnChange = () => {\n // Preserve event structure if original was an event\n if (event[0]?.target) {\n const convertedEvent = {\n ...event[0],\n target: {\n ...event[0].target,\n value: formValue,\n },\n };\n onChange(convertedEvent, ...event.slice(1));\n } else {\n onChange(formValue);\n }\n };\n\n // Execute immediately or after delay\n if (debounceDelay <= 0) {\n executeOnChange();\n } else {\n timeoutRef.current = setTimeout(executeOnChange, debounceDelay);\n }\n },\n [onChange, debounceDelay, transformValue, transform, type, getFormValue],\n );\n\n // Enhanced blur handler\n const handleBlur = useCallback(() => {\n // Flush pending changes\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n\n // Get form value using helper\n const formValue = getFormValue(currentDisplayValue);\n onChange(formValue);\n }\n onBlur();\n }, [currentDisplayValue, onChange, onBlur, getFormValue]);\n\n return {\n onChange: handleChange,\n onBlur: handleBlur,\n value: currentDisplayValue,\n };\n};\n"],"mappings":";;;;;;;;;AAEA,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AA6FlD,IAAM,wBAAwB,CAAC;AAAA,EACpC,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAiE;AAE/D,QAAM,YAAY,uBAAuB;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,QAAM,eAAe;AAAA,IACnB,CAAC,aAA8B;AAC7B,YAAM,cAAc,OAAO,QAAQ;AAEnC,UAAI,gBAAgB;AAClB,eAAO,eAAe,UAAU,WAAW;AAAA,MAC7C;AAEA,UAAI,SAAS,YAAY,gBAAgB,IAAI;AAC3C,cAAM,WAAW,OAAO,WAAW;AACnC,eAAO,OAAO,MAAM,QAAQ,IAAI,WAAW;AAAA,MAC7C;AAEA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,gBAAgB,IAAI;AAAA,EACvB;AAGA,QAAM,eAAe,iBAAiB,UAAU,eAAe;AAC/D,QAAM,CAAC,qBAAqB,sBAAsB,IAAI,SAAS,YAAY;AAC3E,QAAM,aAAa,OAA8B,IAAI;AAGrD,YAAU,MAAM;AACd,2BAAuB,YAAY;AAAA,EACrC,GAAG,CAAC,YAAY,CAAC;AAGjB,QAAM,eAAe;AAAA;AAAA,IAEnB,IAAI,UAAiB;AA9IzB;AA+IM,YAAM,YAAW,uBAAM,CAAC,MAAP,mBAAU,WAAV,mBAAkB,UAAlB,YAA2B,MAAM,CAAC;AAGnD,UAAI,aAAa;AACjB,UAAI,CAAC,kBAAkB,SAAS,YAAY,aAAa,IAAI;AAC3D,cAAM,WAAW,OAAO,QAAQ;AAChC,qBAAa,OAAO,MAAM,QAAQ,IAAI,WAAW;AAAA,MACnD;AAGA,6BAAuB,UAAU;AAGjC,UAAI,oBAAkB,WAAM,CAAC,MAAP,mBAAU,SAAQ;AACtC,kBAAU,kBAAkB,MAAM,CAAC,CAAC;AAAA,MACtC;AAGA,YAAM,YAAY,aAAa,QAAQ;AAGvC,UAAI,WAAW,SAAS;AACtB,qBAAa,WAAW,OAAO;AAAA,MACjC;AAEA,YAAM,kBAAkB,MAAM;AAxKpC,YAAAA;AA0KQ,aAAIA,MAAA,MAAM,CAAC,MAAP,gBAAAA,IAAU,QAAQ;AACpB,gBAAM,iBAAiB,iCAClB,MAAM,CAAC,IADW;AAAA,YAErB,QAAQ,iCACH,MAAM,CAAC,EAAE,SADN;AAAA,cAEN,OAAO;AAAA,YACT;AAAA,UACF;AACA,mBAAS,gBAAgB,GAAG,MAAM,MAAM,CAAC,CAAC;AAAA,QAC5C,OAAO;AACL,mBAAS,SAAS;AAAA,QACpB;AAAA,MACF;AAGA,UAAI,iBAAiB,GAAG;AACtB,wBAAgB;AAAA,MAClB,OAAO;AACL,mBAAW,UAAU,WAAW,iBAAiB,aAAa;AAAA,MAChE;AAAA,IACF;AAAA,IACA,CAAC,UAAU,eAAe,gBAAgB,WAAW,MAAM,YAAY;AAAA,EACzE;AAGA,QAAM,aAAa,YAAY,MAAM;AAEnC,QAAI,WAAW,SAAS;AACtB,mBAAa,WAAW,OAAO;AAC/B,iBAAW,UAAU;AAGrB,YAAM,YAAY,aAAa,mBAAmB;AAClD,eAAS,SAAS;AAAA,IACpB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,qBAAqB,UAAU,QAAQ,YAAY,CAAC;AAExD,SAAO;AAAA,IACL,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AACF;","names":["_a"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/Switch/Switch.tsx","../src/Switch/index.ts"],"sourcesContent":["import type { TVClassName, TVProps } from '@fuf-stack/pixel-utils';\n\nimport { Switch as HeroSwitch } from '@heroui/switch';\n\nimport { tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\n\nimport { useController, useFormContext, useInput } from '../hooks';\nimport { FieldCopyTestIdButton } from '../partials/FieldCopyTestIdButton';\nimport { FieldValidationError } from '../partials/FieldValidationError';\n\nexport const switchVariants = tv({\n slots: {\n base: '',\n endContent: '',\n errorMessage: 'ml-1 mt-1',\n // see HeroUI styles for group-data condition,\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/core/theme/src/components/select.ts\n label:\n 'text-sm text-foreground subpixel-antialiased group-data-[invalid=true]:!text-danger group-data-[required=true]:after:ml-0.5 group-data-[required=true]:after:text-danger group-data-[required=true]:after:content-[\"*\"]',\n outerWrapper: 'place-content-center',\n startContent: '',\n thumb: '',\n thumbIcon: '',\n wrapper: '',\n },\n});\n\ntype VariantProps = TVProps<typeof switchVariants>;\ntype ClassName = TVClassName<typeof switchVariants>;\n\nexport interface SwitchProps extends VariantProps {\n /** CSS class name */\n className?: ClassName;\n /** whether the select should be disabled */\n disabled?: boolean;\n /** component displayed next to the switch. */\n label?: React.ReactNode;\n /** name the field is registered under */\n name: string;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n}\n\n/**\n * Switch component based on [HeroUI Switch](https://www.heroui.com//docs/components/switch)\n */\nconst Switch = ({\n className = undefined,\n disabled = false,\n label: _label = undefined,\n name,\n testId: _testId = undefined,\n}: SwitchProps) => {\n const { control, debugMode, getFieldState } = useFormContext();\n const { error, required, testId, invalid } = getFieldState(name, _testId);\n\n const { field } = useController({ name, control, disabled });\n const { disabled: isDisabled, value, ref, onBlur, onChange } = field;\n\n const { label, getInputProps, getErrorMessageProps } = useInput({\n errorMessage: JSON.stringify(error),\n isInvalid: invalid,\n isRequired: required,\n label: _label,\n labelPlacement: 'outside',\n placeholder: ' ',\n });\n\n const variants = switchVariants();\n const classNames = variantsToClassNames(variants, className, 'outerWrapper');\n\n const showTestIdCopyButton = debugMode === 'debug-testids';\n\n return (\n <div className={classNames.outerWrapper}>\n <HeroSwitch\n aria-describedby={getInputProps()['aria-describedby']}\n classNames={classNames}\n // see HeroUI styles for group-data condition (data-invalid),\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/components/select/src/use-select.ts\n data-invalid={invalid}\n data-required={required}\n data-testid={testId}\n isDisabled={isDisabled}\n isSelected={!!value}\n name={name}\n onBlur={onBlur}\n onValueChange={onChange}\n ref={ref}\n required={required}\n value={value}\n >\n {label}\n {showTestIdCopyButton && <FieldCopyTestIdButton testId={testId} />}\n </HeroSwitch>\n {error && (\n <div className={classNames.errorMessage}>\n <div\n /* eslint-disable-next-line react/jsx-props-no-spreading */\n {...getErrorMessageProps()}\n >\n <FieldValidationError error={error} testId={testId} />\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default Switch;\n","import Switch from './Switch';\n\nexport type { SwitchProps } from './Switch';\n\nexport { Switch };\n\nexport default Switch;\n"],"mappings":";;;;;;;;;;;;;;;;;AAEA,SAAS,UAAU,kBAAkB;AAErC,SAAS,IAAI,4BAA4B;AAuEnC,SAkB2B,KAlB3B;AAjEC,IAAM,iBAAiB,GAAG;AAAA,EAC/B,OAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,cAAc;AAAA;AAAA;AAAA,IAGd,OACE;AAAA,IACF,cAAc;AAAA,IACd,cAAc;AAAA,IACd,OAAO;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AACF,CAAC;AAqBD,IAAM,SAAS,CAAC;AAAA,EACd,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,OAAO,SAAS;AAAA,EAChB;AAAA,EACA,QAAQ,UAAU;AACpB,MAAmB;AACjB,QAAM,EAAE,SAAS,WAAW,cAAc,IAAI,eAAe;AAC7D,QAAM,EAAE,OAAO,UAAU,QAAQ,QAAQ,IAAI,cAAc,MAAM,OAAO;AAExE,QAAM,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,SAAS,SAAS,CAAC;AAC3D,QAAM,EAAE,UAAU,YAAY,OAAO,KAAK,QAAQ,SAAS,IAAI;AAE/D,QAAM,EAAE,OAAO,eAAe,qBAAqB,IAAI,SAAS;AAAA,IAC9D,cAAc,KAAK,UAAU,KAAK;AAAA,IAClC,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,gBAAgB;AAAA,IAChB,aAAa;AAAA,EACf,CAAC;AAED,QAAM,WAAW,eAAe;AAChC,QAAM,aAAa,qBAAqB,UAAU,WAAW,cAAc;AAE3E,QAAM,uBAAuB,cAAc;AAE3C,SACE,qBAAC,SAAI,WAAW,WAAW,cACzB;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,oBAAkB,cAAc,EAAE,kBAAkB;AAAA,QACpD;AAAA,QAGA,gBAAc;AAAA,QACd,iBAAe;AAAA,QACf,eAAa;AAAA,QACb;AAAA,QACA,YAAY,CAAC,CAAC;AAAA,QACd;AAAA,QACA;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,QAEC;AAAA;AAAA,UACA,wBAAwB,oBAAC,iCAAsB,QAAgB;AAAA;AAAA;AAAA,IAClE;AAAA,IACC,SACC,oBAAC,SAAI,WAAW,WAAW,cACzB;AAAA,MAAC;AAAA,uCAEK,qBAAqB,IAF1B;AAAA,QAIC,8BAAC,gCAAqB,OAAc,QAAgB;AAAA;AAAA,IACtD,GACF;AAAA,KAEJ;AAEJ;AAEA,IAAO,iBAAQ;;;ACvGf,IAAOA,kBAAQ;","names":["Switch_default"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-QTROOQ53.cjs","../src/Switch/Switch.tsx","../src/Switch/index.ts"],"names":["Switch_default"],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACA;ACdA,wCAAqC;AAErC,oDAAyC;AAuEnC,+CAAA;AAjEC,IAAM,eAAA,EAAiB,4BAAA;AAAG,EAC/B,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,EAAA;AAAA,IACN,UAAA,EAAY,EAAA;AAAA,IACZ,YAAA,EAAc,WAAA;AAAA;AAAA;AAAA,IAGd,KAAA,EACE,yNAAA;AAAA,IACF,YAAA,EAAc,sBAAA;AAAA,IACd,YAAA,EAAc,EAAA;AAAA,IACd,KAAA,EAAO,EAAA;AAAA,IACP,SAAA,EAAW,EAAA;AAAA,IACX,OAAA,EAAS;AAAA,EACX;AACF,CAAC,CAAA;AAqBD,IAAM,OAAA,EAAS,CAAC;AAAA,EACd,UAAA,EAAY,KAAA,CAAA;AAAA,EACZ,SAAA,EAAW,KAAA;AAAA,EACX,KAAA,EAAO,OAAA,EAAS,KAAA,CAAA;AAAA,EAChB,IAAA;AAAA,EACA,MAAA,EAAQ,QAAA,EAAU,KAAA;AACpB,CAAA,EAAA,GAAmB;AACjB,EAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAW,cAAc,EAAA,EAAI,8CAAA,CAAe;AAC7D,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAU,MAAA,EAAQ,QAAQ,EAAA,EAAI,aAAA,CAAc,IAAA,EAAM,OAAO,CAAA;AAExE,EAAA,MAAM,EAAE,MAAM,EAAA,EAAI,6CAAA,EAAgB,IAAA,EAAM,OAAA,EAAS,SAAS,CAAC,CAAA;AAC3D,EAAA,MAAM,EAAE,QAAA,EAAU,UAAA,EAAY,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,SAAS,EAAA,EAAI,KAAA;AAE/D,EAAA,MAAM,EAAE,KAAA,EAAO,aAAA,EAAe,qBAAqB,EAAA,EAAI,wCAAA;AAAS,IAC9D,YAAA,EAAc,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAAA,IAClC,SAAA,EAAW,OAAA;AAAA,IACX,UAAA,EAAY,QAAA;AAAA,IACZ,KAAA,EAAO,MAAA;AAAA,IACP,cAAA,EAAgB,SAAA;AAAA,IAChB,WAAA,EAAa;AAAA,EACf,CAAC,CAAA;AAED,EAAA,MAAM,SAAA,EAAW,cAAA,CAAe,CAAA;AAChC,EAAA,MAAM,WAAA,EAAa,8CAAA,QAAqB,EAAU,SAAA,EAAW,cAAc,CAAA;AAE3E,EAAA,MAAM,qBAAA,EAAuB,UAAA,IAAc,eAAA;AAE3C,EAAA,uBACE,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAW,UAAA,CAAW,YAAA,EACzB,QAAA,EAAA;AAAA,oBAAA,8BAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,kBAAA,EAAkB,aAAA,CAAc,CAAA,CAAE,kBAAkB,CAAA;AAAA,QACpD,UAAA;AAAA,QAGA,cAAA,EAAc,OAAA;AAAA,QACd,eAAA,EAAe,QAAA;AAAA,QACf,aAAA,EAAa,MAAA;AAAA,QACb,UAAA;AAAA,QACA,UAAA,EAAY,CAAC,CAAC,KAAA;AAAA,QACd,IAAA;AAAA,QACA,MAAA;AAAA,QACA,aAAA,EAAe,QAAA;AAAA,QACf,GAAA;AAAA,QACA,QAAA;AAAA,QACA,KAAA;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,KAAA;AAAA,UACA,qBAAA,mBAAwB,6BAAA,+CAAC,EAAA,EAAsB,OAAA,CAAgB;AAAA,QAAA;AAAA,MAAA;AAAA,IAClE,CAAA;AAAA,IACC,MAAA,mBACC,6BAAA,KAAC,EAAA,EAAI,SAAA,EAAW,UAAA,CAAW,YAAA,EACzB,QAAA,kBAAA,6BAAA;AAAA,MAAC,KAAA;AAAA,MAAA,6CAAA,8CAAA,CAAA,CAAA,EAEK,oBAAA,CAAqB,CAAA,CAAA,EAF1B;AAAA,QAIC,QAAA,kBAAA,6BAAA,8CAAC,EAAA,EAAqB,KAAA,EAAc,OAAA,CAAgB;AAAA,MAAA,CAAA;AAAA,IACtD,EAAA,CACF;AAAA,EAAA,EAAA,CAEJ,CAAA;AAEJ,CAAA;AAEA,IAAO,eAAA,EAAQ,MAAA;ADpBf;AACA;AEpFA,IAAOA,gBAAAA,EAAQ,cAAA;AFsFf;AACA;AACE;AACA;AACF,mFAAC","file":"/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-QTROOQ53.cjs","sourcesContent":[null,"import type { TVClassName, TVProps } from '@fuf-stack/pixel-utils';\n\nimport { Switch as HeroSwitch } from '@heroui/switch';\n\nimport { tv, variantsToClassNames } from '@fuf-stack/pixel-utils';\n\nimport { useController, useFormContext, useInput } from '../hooks';\nimport { FieldCopyTestIdButton } from '../partials/FieldCopyTestIdButton';\nimport { FieldValidationError } from '../partials/FieldValidationError';\n\nexport const switchVariants = tv({\n slots: {\n base: '',\n endContent: '',\n errorMessage: 'ml-1 mt-1',\n // see HeroUI styles for group-data condition,\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/core/theme/src/components/select.ts\n label:\n 'text-sm text-foreground subpixel-antialiased group-data-[invalid=true]:!text-danger group-data-[required=true]:after:ml-0.5 group-data-[required=true]:after:text-danger group-data-[required=true]:after:content-[\"*\"]',\n outerWrapper: 'place-content-center',\n startContent: '',\n thumb: '',\n thumbIcon: '',\n wrapper: '',\n },\n});\n\ntype VariantProps = TVProps<typeof switchVariants>;\ntype ClassName = TVClassName<typeof switchVariants>;\n\nexport interface SwitchProps extends VariantProps {\n /** CSS class name */\n className?: ClassName;\n /** whether the select should be disabled */\n disabled?: boolean;\n /** component displayed next to the switch. */\n label?: React.ReactNode;\n /** name the field is registered under */\n name: string;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n}\n\n/**\n * Switch component based on [HeroUI Switch](https://www.heroui.com//docs/components/switch)\n */\nconst Switch = ({\n className = undefined,\n disabled = false,\n label: _label = undefined,\n name,\n testId: _testId = undefined,\n}: SwitchProps) => {\n const { control, debugMode, getFieldState } = useFormContext();\n const { error, required, testId, invalid } = getFieldState(name, _testId);\n\n const { field } = useController({ name, control, disabled });\n const { disabled: isDisabled, value, ref, onBlur, onChange } = field;\n\n const { label, getInputProps, getErrorMessageProps } = useInput({\n errorMessage: JSON.stringify(error),\n isInvalid: invalid,\n isRequired: required,\n label: _label,\n labelPlacement: 'outside',\n placeholder: ' ',\n });\n\n const variants = switchVariants();\n const classNames = variantsToClassNames(variants, className, 'outerWrapper');\n\n const showTestIdCopyButton = debugMode === 'debug-testids';\n\n return (\n <div className={classNames.outerWrapper}>\n <HeroSwitch\n aria-describedby={getInputProps()['aria-describedby']}\n classNames={classNames}\n // see HeroUI styles for group-data condition (data-invalid),\n // e.g.: https://github.com/heroui-inc/heroui/blob/main/packages/components/select/src/use-select.ts\n data-invalid={invalid}\n data-required={required}\n data-testid={testId}\n isDisabled={isDisabled}\n isSelected={!!value}\n name={name}\n onBlur={onBlur}\n onValueChange={onChange}\n ref={ref}\n required={required}\n value={value}\n >\n {label}\n {showTestIdCopyButton && <FieldCopyTestIdButton testId={testId} />}\n </HeroSwitch>\n {error && (\n <div className={classNames.errorMessage}>\n <div\n /* eslint-disable-next-line react/jsx-props-no-spreading */\n {...getErrorMessageProps()}\n >\n <FieldValidationError error={error} testId={testId} />\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default Switch;\n","import Switch from './Switch';\n\nexport type { SwitchProps } from './Switch';\n\nexport { Switch };\n\nexport default Switch;\n"]}
@@ -1,37 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/hooks/useInputValueTransform/useInputValueTransform.ts
2
- var _react = require('react');
3
- var useInputValueTransform = ({
4
- value,
5
- type,
6
- transformValue
7
- }) => {
8
- const prevExternalValue = _react.useRef.call(void 0, value);
9
- const [displayValue, setDisplayValue] = _react.useState.call(void 0, () => {
10
- return (transformValue == null ? void 0 : transformValue.displayValue) ? transformValue.displayValue(value != null ? value : "") : value != null ? value : "";
11
- });
12
- _react.useEffect.call(void 0, () => {
13
- if (value !== prevExternalValue.current) {
14
- prevExternalValue.current = value;
15
- const newDisplayValue = (transformValue == null ? void 0 : transformValue.displayValue) ? transformValue.displayValue(value != null ? value : "") : value != null ? value : "";
16
- setDisplayValue(newDisplayValue);
17
- }
18
- }, [value, transformValue]);
19
- const getFormValue = () => {
20
- if (type === "number") {
21
- return displayValue === "" ? "" : Number(displayValue);
22
- }
23
- return (transformValue == null ? void 0 : transformValue.formValue) ? transformValue.formValue(displayValue) : displayValue;
24
- };
25
- return {
26
- displayValue,
27
- handleInputChange: (e) => {
28
- setDisplayValue(e.target.value);
29
- },
30
- getFormValue
31
- };
32
- };
33
-
34
-
35
-
36
- exports.useInputValueTransform = useInputValueTransform;
37
- //# sourceMappingURL=chunk-TSB65253.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-TSB65253.cjs","../src/hooks/useInputValueTransform/useInputValueTransform.ts"],"names":[],"mappings":"AAAA;ACAA,8BAA4C;AAsHrC,IAAM,uBAAA,EAAyB,CAAC;AAAA,EACrC,KAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAAA,GAAmE;AAEjE,EAAA,MAAM,kBAAA,EAAoB,2BAAA,KAAY,CAAA;AAGtC,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,EAAA,EAAI,6BAAA,CAAS,EAAA,GAAM;AACrD,IAAA,OAAA,CAAO,eAAA,GAAA,KAAA,EAAA,KAAA,EAAA,EAAA,cAAA,CAAgB,YAAA,EAAA,EACnB,cAAA,CAAe,YAAA,CAAa,MAAA,GAAA,KAAA,EAAA,MAAA,EAAS,EAAE,EAAA,EACtC,MAAA,GAAA,KAAA,EAAA,MAAA,EAAS,EAAA;AAAA,EAChB,CAAC,CAAA;AAcD,EAAA,8BAAA,CAAU,EAAA,GAAM;AAEd,IAAA,GAAA,CAAI,MAAA,IAAU,iBAAA,CAAkB,OAAA,EAAS;AACvC,MAAA,iBAAA,CAAkB,QAAA,EAAU,KAAA;AAE5B,MAAA,MAAM,gBAAA,EAAA,CAAkB,eAAA,GAAA,KAAA,EAAA,KAAA,EAAA,EAAA,cAAA,CAAgB,YAAA,EAAA,EACpC,cAAA,CAAe,YAAA,CAAa,MAAA,GAAA,KAAA,EAAA,MAAA,EAAS,EAAE,EAAA,EACtC,MAAA,GAAA,KAAA,EAAA,MAAA,EAAS,EAAA;AAEd,MAAA,eAAA,CAAgB,eAAe,CAAA;AAAA,IACjC;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,cAAc,CAAC,CAAA;AAsB1B,EAAA,MAAM,aAAA,EAAe,CAAA,EAAA,GAAuB;AAC1C,IAAA,GAAA,CAAI,KAAA,IAAS,QAAA,EAAU;AACrB,MAAA,OAAO,aAAA,IAAiB,GAAA,EAAK,GAAA,EAAK,MAAA,CAAO,YAAY,CAAA;AAAA,IACvD;AAEA,IAAA,OAAA,CAAO,eAAA,GAAA,KAAA,EAAA,KAAA,EAAA,EAAA,cAAA,CAAgB,SAAA,EAAA,EACnB,cAAA,CAAe,SAAA,CAAU,YAAsB,EAAA,EAC/C,YAAA;AAAA,EACN,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,YAAA;AAAA,IACA,iBAAA,EAAmB,CAAC,CAAA,EAAA,GAA2C;AAC7D,MAAA,eAAA,CAAgB,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AAAA,IAChC,CAAA;AAAA,IACA;AAAA,EACF,CAAA;AACF,CAAA;ADnKA;AACA;AACE;AACF,wDAAC","file":"/home/runner/work/pixels/pixels/packages/uniform/dist/chunk-TSB65253.cjs","sourcesContent":[null,"import { useEffect, useRef, useState } from 'react';\n\nexport interface InputValueTransform {\n /** Transforms the form value to display value (e.g., 1000 → \"$1,000\") */\n displayValue: (value: string | number) => string | number;\n /** Transforms the display value to form value (e.g., \"$1,000\" → 1000) */\n formValue: (value: string) => string | number;\n}\n\nexport interface UseInputValueTransformOptions {\n /** The current form field value */\n value: string | number;\n /** Input type for special number handling */\n type?: 'text' | 'number' | 'password';\n /** Value transformation functions */\n transformValue?: InputValueTransform;\n}\n\nexport interface UseInputValueTransformReturn {\n /** The current display value for the input */\n displayValue: string | number;\n /** Input change handler (pass directly to onChange) */\n handleInputChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n /** Gets the form value from current display value */\n getFormValue: () => string | number;\n}\n\n/**\n * Custom hook for handling input value transformations between display and form values.\n *\n * This hook manages the separation between what the user sees (display value) and what gets\n * stored in the form (form value). It's particularly useful for:\n * - Currency formatting ($1,000 display vs 1000 stored)\n * - Number inputs with special handling\n * - Date formatting (MM/DD/YYYY display vs ISO date stored)\n * - Phone number formatting ((555) 123-4567 display vs 5551234567 stored)\n *\n * **Key Features:**\n * - Immediate display value updates for responsive UI\n * - Automatic external value synchronization (form resets, setValue calls)\n * - Special number input handling (empty string preservation)\n * - Bidirectional value transformations\n *\n * @param options Configuration for value transformation\n * @returns Display value management and form value conversion\n *\n * @example\n * ```tsx\n * // Currency formatting\n * const currencyTransform = {\n * displayValue: (val) => val ? `$${Number(val).toLocaleString()}` : '',\n * formValue: (val) => parseFloat(val.replace(/[$,]/g, '')) || 0\n * };\n *\n * const { displayValue, handleInputChange, getFormValue } = useInputValueTransform({\n * value: 1000,\n * transformValue: currencyTransform\n * });\n * // displayValue = \"$1,000\"\n * // getFormValue() = 1000\n * ```\n *\n * @example\n * ```tsx\n * // Phone number formatting\n * const phoneTransform = {\n * displayValue: (val) => {\n * const cleaned = val.toString().replace(/\\D/g, '');\n * const match = cleaned.match(/^(\\d{3})(\\d{3})(\\d{4})$/);\n * return match ? `(${match[1]}) ${match[2]}-${match[3]}` : val;\n * },\n * formValue: (val) => val.replace(/\\D/g, '')\n * };\n *\n * const { displayValue, handleInputChange, getFormValue } = useInputValueTransform({\n * value: '5551234567',\n * transformValue: phoneTransform\n * });\n * // displayValue = \"(555) 123-4567\"\n * // getFormValue() = \"5551234567\"\n * ```\n *\n * @example\n * ```tsx\n * // Number input (no transforms needed)\n * const { displayValue, handleInputChange, getFormValue } = useInputValueTransform({\n * value: 42,\n * type: 'number'\n * });\n * // Handles empty string → empty string (not NaN)\n * // Handles \"123\" → 123 (string to number conversion)\n * ```\n *\n * @example\n * ```tsx\n * // Usage in a form component\n * const MyInput = ({ field, transformValue }) => {\n * const { displayValue, handleInputChange, getFormValue } = useInputValueTransform({\n * value: field.value,\n * transformValue\n * });\n *\n * // Debounce the form updates (optional)\n * useInputValueDebounce({\n * value: getFormValue(),\n * onChange: field.onChange,\n * debounceDelay: 300\n * });\n *\n * return (\n * <input\n * value={displayValue}\n * onChange={handleInputChange}\n * />\n * );\n * };\n * ```\n */\nexport const useInputValueTransform = ({\n value,\n type,\n transformValue,\n}: UseInputValueTransformOptions): UseInputValueTransformReturn => {\n // Track previous external value to detect real external changes\n const prevExternalValue = useRef(value);\n\n // Local state for immediate display updates\n const [displayValue, setDisplayValue] = useState(() => {\n return transformValue?.displayValue\n ? transformValue.displayValue(value ?? '')\n : (value ?? '');\n });\n\n /**\n * Synchronizes display value when form value changes externally.\n *\n * This handles cases like:\n * - Form resets: reset() or setValue('field', '')\n * - External updates: setValue('field', 'new value')\n * - Default value initialization from form state\n * - Programmatic field updates from other components\n *\n * Uses a ref to track the previous value and only updates when the external\n * value actually changes, preventing infinite re-renders.\n */\n useEffect(() => {\n // Only process if the external value actually changed\n if (value !== prevExternalValue.current) {\n prevExternalValue.current = value;\n\n const newDisplayValue = transformValue?.displayValue\n ? transformValue.displayValue(value ?? '')\n : (value ?? '');\n\n setDisplayValue(newDisplayValue);\n }\n }, [value, transformValue]);\n\n /**\n * Converts the current display value to the appropriate form value.\n *\n * **Conversion Logic:**\n * 1. **Number inputs**:\n * - Empty string → empty string (preserves empty state, prevents NaN)\n * - Non-empty string → Number(value) (converts to numeric form)\n * - Example: \"\" → \"\", \"42\" → 42, \"3.14\" → 3.14\n *\n * 2. **Transform inputs**:\n * - Applies custom formValue transform function\n * - Used for converting display format back to storage format\n * - Example: \"$1,000\" → 1000, \"(555) 123-4567\" → \"5551234567\"\n *\n * 3. **Regular inputs**:\n * - Passes through the display value unchanged\n * - Example: \"hello\" → \"hello\", \"test@example.com\" → \"test@example.com\"\n *\n * @returns The form value ready for storage/submission\n */\n const getFormValue = (): string | number => {\n if (type === 'number') {\n return displayValue === '' ? '' : Number(displayValue);\n }\n\n return transformValue?.formValue\n ? transformValue.formValue(displayValue as string)\n : displayValue;\n };\n\n return {\n displayValue,\n handleInputChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n setDisplayValue(e.target.value);\n },\n getFormValue,\n };\n};\n"]}