@customafk/lunas-ui 0.2.59 → 0.2.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cms-layout-BMwn0Yv3.cjs +2 -0
- package/dist/cms-layout-BMwn0Yv3.cjs.map +1 -0
- package/dist/cms-layout-sd6GB6tR.mjs +2 -0
- package/dist/cms-layout-sd6GB6tR.mjs.map +1 -0
- package/dist/dialogs/detail-dialog/index.cjs +1 -1
- package/dist/dialogs/detail-dialog/index.cjs.map +1 -1
- package/dist/dialogs/detail-dialog/index.mjs +1 -1
- package/dist/dialogs/detail-dialog/index.mjs.map +1 -1
- package/dist/features/logo/index.cjs +2 -0
- package/dist/features/logo/index.cjs.map +1 -0
- package/dist/features/logo/index.d.cts +22 -0
- package/dist/features/logo/index.d.mts +22 -0
- package/dist/features/logo/index.mjs +2 -0
- package/dist/features/logo/index.mjs.map +1 -0
- package/dist/features/tables/index.cjs +1 -1
- package/dist/features/tables/index.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/layouts/cms-layout/index.cjs +1 -1
- package/dist/layouts/cms-layout/index.mjs +1 -1
- package/dist/layouts/payment-layout/index.cjs +1 -1
- package/dist/layouts/payment-layout/index.mjs +1 -1
- package/dist/pages/FeatureDeveloping.cjs +1 -1
- package/dist/pages/FeatureDeveloping.cjs.map +1 -1
- package/dist/pages/FeatureDeveloping.mjs +1 -1
- package/dist/pages/FeatureDeveloping.mjs.map +1 -1
- package/dist/pages/FeatureFixing.cjs +1 -1
- package/dist/pages/FeatureFixing.cjs.map +1 -1
- package/dist/pages/FeatureFixing.mjs +1 -1
- package/dist/pages/FeatureFixing.mjs.map +1 -1
- package/dist/pages/LoginPage.cjs +1 -1
- package/dist/pages/LoginPage.cjs.map +1 -1
- package/dist/pages/LoginPage.mjs +1 -1
- package/dist/pages/LoginPage.mjs.map +1 -1
- package/dist/pages/NotAuthorized.cjs +1 -1
- package/dist/pages/NotAuthorized.cjs.map +1 -1
- package/dist/pages/NotAuthorized.mjs +1 -1
- package/dist/pages/NotAuthorized.mjs.map +1 -1
- package/dist/pages/NotFound.cjs +1 -1
- package/dist/pages/NotFound.cjs.map +1 -1
- package/dist/pages/NotFound.mjs +1 -1
- package/dist/pages/NotFound.mjs.map +1 -1
- package/dist/pages/RegisterPage.cjs +1 -1
- package/dist/pages/RegisterPage.cjs.map +1 -1
- package/dist/pages/RegisterPage.mjs +1 -1
- package/dist/pages/RegisterPage.mjs.map +1 -1
- package/dist/pages/VerifyEmailPage.cjs +1 -1
- package/dist/pages/VerifyEmailPage.cjs.map +1 -1
- package/dist/pages/VerifyEmailPage.mjs +1 -1
- package/dist/pages/VerifyEmailPage.mjs.map +1 -1
- package/dist/payment-layout-BLrXT-oc.cjs +2 -0
- package/dist/payment-layout-BLrXT-oc.cjs.map +1 -0
- package/dist/payment-layout-Dsz6wYT1.mjs +2 -0
- package/dist/{payment-layout-CG_l7Es-.mjs.map → payment-layout-Dsz6wYT1.mjs.map} +1 -1
- package/dist/{resizable-CVpc0g5U.d.cts → resizable-CFCYn9e_.d.cts} +2 -2
- package/dist/{resizable-CVpc0g5U.d.mts → resizable-CFCYn9e_.d.mts} +2 -2
- package/dist/{tables-UaA4qIaD.mjs → tables-B9cF58YD.mjs} +2 -2
- package/dist/{tables-UaA4qIaD.mjs.map → tables-B9cF58YD.mjs.map} +1 -1
- package/dist/{tables-CNJ10l7L.cjs → tables-NiAoBy75.cjs} +2 -2
- package/dist/{tables-CNJ10l7L.cjs.map → tables-NiAoBy75.cjs.map} +1 -1
- package/dist/tanstack-form-BMVn8ai_.cjs.map +1 -1
- package/dist/tanstack-form-DTCgWGCA.mjs.map +1 -1
- package/dist/ui/resizable.d.cts +1 -1
- package/dist/ui/resizable.d.mts +1 -1
- package/package.json +5 -1
- package/dist/cms-layout-Bsw2mKXo.cjs +0 -2
- package/dist/cms-layout-Bsw2mKXo.cjs.map +0 -1
- package/dist/cms-layout-IwpD0LvR.mjs +0 -2
- package/dist/cms-layout-IwpD0LvR.mjs.map +0 -1
- package/dist/payment-layout-CG_l7Es-.mjs +0 -2
- package/dist/payment-layout-Dlvc1P7b.cjs +0 -2
- package/dist/payment-layout-Dlvc1P7b.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tanstack-form-DTCgWGCA.mjs","names":["Label","LabelPrimitive","Label","Tooltip","Separator","Switch","Checkbox","Label","Label","Popover","Label","Popover","Label","RadioGroup","Label","Label","Label","Label","Select","Label","Label","Checkbox","Dialog","RadixDialog","Popover","Popover","RadioGroup","Dialog","RadixDialog","Select","Switch","SwitchPrimitive","Switch","Separator","SeparatorPrimitive","Separator","Dialog","Separator","DialogPrimitive","Separator"],"sources":["../packages/components/features/tanstack-form/components/atoms/simple-array-field.tsx","../packages/components/features/tanstack-form/components/ui/label.tsx","../packages/components/features/tanstack-form/components/ui/field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-boolean-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-combobox-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-date-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-radio-group-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-email-field.tsx","../packages/components/ui/inputs/number-input.tsx","../packages/components/features/tanstack-form/components/atoms/simple-number-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-password-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-select-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-textarea-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-text-field.tsx","../packages/components/features/tanstack-form/components/fields/checkbox-field.tsx","../packages/components/features/tanstack-form/components/fields/combobox-field.tsx","../packages/components/features/tanstack-form/components/fields/date-field.tsx","../packages/components/features/tanstack-form/components/fields/email-field.tsx","../packages/components/features/tanstack-form/components/fields/number-field.tsx","../packages/components/features/tanstack-form/components/fields/password-field.tsx","../packages/components/features/tanstack-form/components/fields/radio-group-field.tsx","../packages/components/features/tanstack-form/components/fields/select-field.tsx","../packages/components/features/tanstack-form/components/ui/switch.tsx","../packages/components/features/tanstack-form/components/fields/switch-field.tsx","../packages/components/features/tanstack-form/components/fields/text-field.tsx","../packages/components/features/tanstack-form/components/fields/textarea-field.tsx","../packages/components/features/tanstack-form/components/fields/text-editor-field.tsx","../packages/components/features/tanstack-form/components/forms/action-submit.tsx","../packages/components/features/tanstack-form/components/forms/actions-form.tsx","../packages/components/features/tanstack-form/components/ui/separator.tsx","../packages/components/features/tanstack-form/components/forms/card-form.tsx","../packages/components/features/tanstack-form/components/forms/container-form.tsx","../packages/components/features/tanstack-form/components/ui/cancel-button.tsx","../packages/components/features/tanstack-form/components/ui/submit-button.tsx","../packages/components/features/tanstack-form/components/forms/dialog-form.tsx","../packages/components/features/tanstack-form/components/forms/group-field.tsx","../packages/components/features/tanstack-form/components/forms/popover-form.tsx","../packages/components/features/tanstack-form/components/forms/section-form.tsx","../packages/components/features/tanstack-form/components/forms/title-field.tsx","../packages/components/features/tanstack-form/tanstack-form.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback } from 'react';\n\nimport { PlusIcon, Trash2Icon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\n\n// ─── ArrayCol ──────────────────────────────────────────────────────────────\n\ntype ArrayColProps = {\n /**\n * Fixed column width as a pixel number (e.g. `96`) or any CSS string\n * (e.g. `'8rem'`, `'20%'`). Omit to let the column expand and fill the\n * remaining row space (`flex: 1`).\n */\n width?: number | string;\n className?: string;\n children: React.ReactNode;\n};\n\n/**\n * Layout helper for columns inside a `SimpleArrayField` row. Controls width\n * without repeating `<div className=\"w-24\">` or `<div className=\"flex-1\">`.\n *\n * @example\n * <SimpleArrayField defaultRow={...}>\n * {i => (\n * <>\n * <ArrayCol> // flex-1 — takes remaining space\n * <AppField name={`items[${i}].name`}>...</AppField>\n * </ArrayCol>\n * <ArrayCol width={96}> // 96 px fixed\n * <AppField name={`items[${i}].qty`}>...</AppField>\n * </ArrayCol>\n * <ArrayCol width=\"8rem\"> // CSS string\n * <AppField name={`items[${i}].tax`}>...</AppField>\n * </ArrayCol>\n * </>\n * )}\n * </SimpleArrayField>\n */\nexport function ArrayCol({ width, className, children }: ArrayColProps) {\n const style: React.CSSProperties = width ? { width: typeof width === 'number' ? `${width}px` : width, flexShrink: 0 } : { flex: 1, minWidth: 0 };\n\n return (\n <div data-slot=\"array-col\" style={style} className={className}>\n {children}\n </div>\n );\n}\n\n// ─── ArrayHeaderRow ────────────────────────────────────────────────────────\n\ntype ArrayHeaderRowProps = {\n className?: string;\n children: React.ReactNode;\n};\n\n/**\n * Styled header row for a `SimpleArrayField` table. Place it directly above\n * `<SimpleArrayField>` and use `<ArrayCol>` children with text labels to align\n * headers with their columns. A spacer matching the delete-button width is\n * appended automatically.\n *\n * @example\n * <ArrayHeaderRow>\n * <ArrayCol>Name</ArrayCol>\n * <ArrayCol width={96}>Price</ArrayCol>\n * <ArrayCol width={80}>Qty</ArrayCol>\n * </ArrayHeaderRow>\n * <SimpleArrayField defaultRow={...}>\n * {i => (...)}\n * </SimpleArrayField>\n */\nexport function ArrayHeaderRow({ className, children }: ArrayHeaderRowProps) {\n return (\n <div data-slot=\"array-header-row\" className={cn('mb-1 flex items-center gap-2 px-1 text-xs font-medium text-text-positive-weak', className)}>\n {children}\n {/* spacer matching the delete icon button width */}\n <div className=\"min-w-8 w-8 shrink-0\" />\n </div>\n );\n}\n\n// ─── SimpleArrayField ──────────────────────────────────────────────────────\n\ntype Props<T> = {\n /**\n * Shape of a brand-new empty row appended when the user clicks \"Add row\".\n */\n defaultRow: T;\n /**\n * Render function called once per row. Receives the zero-based row `index`\n * so you can build field paths like `` `items[${index}].name` ``.\n */\n children: (index: number) => React.ReactNode;\n /** Label on the add button. Defaults to `'Add row'`. */\n addLabel?: string;\n className?: string;\n};\n\n/**\n * Array field wrapper that manages rows (add / remove) while letting you\n * freely compose any fields inside each row.\n *\n * @example\n * const { AppForm, AppField } = useTanStackForm({ defaultValues: { items: [] } });\n *\n * <AppForm>\n * <AppField name=\"items\">\n * {({ SimpleArrayField }) => (\n * <SimpleArrayField defaultRow={{ name: null, qty: null }}>\n * {(i) => (\n * <div className=\"flex gap-2\">\n * <AppField name={`items[${i}].name`}>\n * {({ SimpleTextField }) => <SimpleTextField label=\"Name\" />}\n * </AppField>\n * <AppField name={`items[${i}].qty`}>\n * {({ SimpleNumberField }) => <SimpleNumberField label=\"Qty\" />}\n * </AppField>\n * </div>\n * )}\n * </SimpleArrayField>\n * )}\n * </AppField>\n * </AppForm>\n */\nexport function SimpleArrayField<T>({ defaultRow, children, addLabel = 'Thêm hàng', className }: Props<T>) {\n const field = useTanStackFieldContext<T[]>();\n const rows = field.state.value ?? [];\n\n const addRow = useCallback(() => {\n field.pushValue({ ...defaultRow } as T);\n }, [field, defaultRow]);\n\n const removeRow = useCallback(\n (index: number) => {\n field.removeValue(index);\n },\n [field]\n );\n\n return (\n <div data-slot=\"simple-array-field\" className={cn('flex flex-col gap-2', className)}>\n {rows.map((_, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: index is the stable identity for form rows\n <div key={i} className=\"flex items-start gap-2\">\n {children(i)}\n <Button type=\"button\" size=\"icon\" variant=\"ghost\" color=\"danger\" className=\"min-w-8\" onClick={() => removeRow(i)}>\n <Trash2Icon size={14} />\n </Button>\n </div>\n ))}\n\n <div>\n <Button type=\"button\" variant=\"outline\" color=\"muted\" size=\"xs\" onClick={addRow}>\n <PlusIcon size={13} />\n {addLabel}\n </Button>\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Label as LabelPrimitive } from 'radix-ui';\n\n/**\n * Form field label that automatically renders a \"Required\" badge when the field is marked aria-required.\n *\n * @example\n * import { Label } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <Label htmlFor=\"email\">Email address</Label>\n */\nfunction Label({ className, children, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n 'text-text-positive',\n 'flex w-full items-center justify-between',\n 'select-none font-medium text-sm/6 leading-none',\n 'group-data-[disabled=true]:pointer-events-none',\n 'group-data-[disabled=true]:opacity-50',\n 'peer-disabled:cursor-not-allowed',\n 'peer-disabled:opacity-50',\n 'aria-required:*:data-[slot=required-indicator]:inline-block',\n className\n )}\n {...props}\n >\n <span className=\"flex items-center gap-1\">{children}</span>\n <span\n data-slot=\"required-indicator\"\n className=\"hidden shrink-0 rounded-lg bg-danger-strong px-1.5 py-1 font-semibold text-[11px] leading-none text-white\"\n >\n Bắt buộc\n </span>\n </LabelPrimitive.Root>\n );\n}\n\nexport { Label };\n","'use client';\n\nimport { memo, useMemo } from 'react';\n\nimport { HelpCircleIcon, InfoIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Separator } from '@/components/ui/separator';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Label } from './label';\n\nconst fieldVariants = cva('group/field flex w-full gap-2 data-[invalid=true]:text-danger *:data-[slot=field-content]:gap-0', {\n variants: {\n orientation: {\n vertical: ['flex-col *:w-full [&>.sr-only]:w-auto'],\n horizontal: [\n 'flex-row items-center gap-4',\n '*:data-[slot=field-content]:basis-1/2',\n '*:data-[slot=field-content-main]:flex-1',\n '*:data-[slot=field-label]:flex-auto',\n 'has-[>[data-slot=field-content]]:items-start',\n 'has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\n ],\n responsive: [\n 'flex-col *:w-full [&>.sr-only]:w-auto',\n '@md/field-group:flex-row',\n '@md/field-group:items-center',\n '@md/field-group:gap-4',\n '@md/field-group:*:w-auto',\n '@md/field-group:*:data-[slot=field-content]:basis-1/2',\n '@md/field-group:*:data-[slot=field-content-main]:basis-1/2',\n '@md/field-group:*:data-[slot=field-label]:flex-auto',\n '@md/field-group:has-[>[data-slot=field-content]]:items-start',\n '@md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\n ],\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n\n/**\n * Outermost `<fieldset>` wrapper that stacks multiple `Field` rows with consistent vertical spacing.\n *\n * @example\n * import { FieldSet } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldSet>\n * <Field><FieldLabel>Name</FieldLabel><FieldContent><input /></FieldContent></Field>\n * </FieldSet>\n */\nconst FieldSet = memo(({ className, ...props }: React.ComponentProps<'fieldset'>) => {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn('flex flex-col gap-6 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3', className)}\n {...props}\n />\n );\n});\nFieldSet.displayName = 'FieldSet';\n\n/**\n * Props for {@link FieldLegend}.\n */\ntype FieldLegendProps = React.ComponentProps<'legend'> & {\n /**\n * Visual weight of the legend text.\n * - `'legend'` — larger base-size text (section heading).\n * - `'label'` — smaller label-size text (matches field label weight).\n * @default 'legend'\n */\n variant?: 'legend' | 'label';\n};\n\n/**\n * `<legend>` element for a `<fieldset>`, styled as either a section heading or a compact label.\n *\n * @example\n * import { FieldSet, FieldLegend } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldSet>\n * <FieldLegend variant=\"legend\">Personal details</FieldLegend>\n * </FieldSet>\n */\nconst FieldLegend = memo(({ className, variant = 'legend', ...props }: FieldLegendProps) => {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn('mb-3 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base', className)}\n {...props}\n />\n );\n});\nFieldLegend.displayName = 'FieldLegend';\n\n/**\n * Container `<div>` that groups a set of `Field` rows with container-query support for responsive layouts.\n *\n * @example\n * import { FieldGroup } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldGroup>\n * <Field>…</Field>\n * <Field>…</Field>\n * </FieldGroup>\n */\nconst FieldGroup = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group @container/field-group',\n 'flex flex-col gap-7 pt-4',\n 'data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4',\n className\n )}\n {...props}\n />\n );\n});\nFieldGroup.displayName = 'FieldGroup';\n\n/**\n * Single form field row that arranges label, input, and meta elements with configurable orientation.\n *\n * @example\n * import { Field } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <Field orientation=\"horizontal\">\n * <FieldLabel htmlFor=\"username\">Username</FieldLabel>\n * <FieldContent><input id=\"username\" /></FieldContent>\n * </Field>\n */\nconst Field = memo(({ className, orientation = 'vertical', ...props }: React.ComponentProps<'div'> & VariantProps<typeof fieldVariants>) => {\n return <div data-slot=\"field\" data-orientation={orientation} className={cn(fieldVariants({ orientation }), className)} {...props} />;\n});\nField.displayName = 'Field';\n\n/**\n * Flex column wrapper that houses the primary input control together with description and error slots.\n *\n * @example\n * import { FieldContent } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldContent>\n * <input type=\"text\" />\n * <FieldDescription>Enter your full name.</FieldDescription>\n * </FieldContent>\n */\nconst FieldContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"field-content\" className={cn('group/field-content flex flex-col gap-1.5 leading-snug', className)} {...props} />;\n});\nFieldContent.displayName = 'FieldContent';\n\n/**\n * Positioned wrapper for the main input element that enables absolutely-placed adornments (icons, spinners).\n *\n * @example\n * import { FieldContentMain } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldContentMain>\n * <input type=\"text\" className=\"pr-8\" />\n * <SearchIcon className=\"absolute right-2 top-2\" />\n * </FieldContentMain>\n */\nconst FieldContentMain = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"field-content-main\" className={cn('relative', className)} {...props} />;\n});\nFieldContentMain.displayName = 'FieldContentMain';\n\n/**\n * Styled `<label>` element for a `Field`, extending the base `Label` with field-group-aware spacing and border states.\n *\n * @example\n * import { FieldLabel } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldLabel htmlFor=\"email\" aria-required>Email</FieldLabel>\n */\nconst FieldLabel = memo(({ className, ...props }: React.ComponentProps<typeof Label>) => {\n return (\n <Label\n data-slot=\"field-label\"\n className={cn(\n 'group/field-label peer/field-label min-h-6 gap-1 font-medium leading-snug',\n 'has-[>[data-slot=field]]:w-full',\n 'has-[>[data-slot=field]]:flex-col',\n 'has-[>[data-slot=field]]:rounded-md',\n 'has-[>[data-slot=field]]:border',\n 'has-[>[data-slot=field]]:border-border',\n 'has-data-[state=checked]:border-primary',\n '*:data-[slot=field]:p-4 group-data-[disabled=true]/field:opacity-50',\n className\n )}\n {...props}\n />\n );\n});\nFieldLabel.displayName = 'FieldLabel';\n\n/**\n * Inline title element (non-`<label>`) for fields whose label cannot be a native `<label>`, such as custom checkbox groups.\n *\n * @example\n * import { FieldTitle } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldTitle>Notification preferences</FieldTitle>\n */\nconst FieldTitle = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return (\n <div\n data-slot=\"field-label\"\n className={cn('flex w-fit items-center gap-2 font-medium text-sm leading-snug group-data-[disabled=true]/field:opacity-50', className)}\n {...props}\n />\n );\n});\nFieldTitle.displayName = 'FieldTitle';\n\n/**\n * Supplementary hint text rendered below the input to guide the user, with support for inline anchor links.\n *\n * @example\n * import { FieldDescription } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldDescription>Must be at least 8 characters.</FieldDescription>\n */\nconst FieldDescription = memo(({ className, ...props }: React.ComponentProps<'p'>) => {\n return (\n <p\n data-slot=\"field-description\"\n className={cn(\n // biome-ignore lint/security/noSecrets: true\n 'nth-last-2:-mt-1 font-normal text-text-positive-weak text-xs leading-normal last:mt-0 [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4 [[data-variant=legend]+&]:-mt-1.5',\n className\n )}\n {...props}\n />\n );\n});\nFieldDescription.displayName = 'FieldDescription';\n\n/**\n * Props for {@link FieldNote}.\n */\ntype FieldNoteProps = React.ComponentProps<'div'> & {\n /**\n * When `false` the note is not rendered at all; useful for conditional display without wrapper conditionals.\n * @default true\n */\n isShow?: boolean;\n};\n\n/**\n * Highlighted informational callout box with an info icon, shown below a field to surface contextual guidance.\n *\n * @example\n * import { FieldNote } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldNote isShow={isDraftMode}>Changes are saved automatically in draft mode.</FieldNote>\n */\nconst FieldNote = memo(({ isShow = true, className, children, ...props }: FieldNoteProps) => {\n if (isShow === false) return null;\n return (\n <div\n data-slot=\"field-note\"\n className={cn(\n 'flex items-start gap-1.5 rounded border border-primary-muted/60 bg-primary-bg-subtle/80 px-2.5 py-2 text-text-positive-weak text-xs',\n className\n )}\n {...props}\n >\n <InfoIcon size={12} className=\"mt-0.5 shrink-0 text-primary/70\" />\n <span>{children}</span>\n </div>\n );\n});\nFieldNote.displayName = 'FieldNote';\n\n/**\n * Props for {@link FieldTooltip}.\n */\ntype FieldTooltipProps = {\n /** Text content displayed inside the tooltip when the help icon is hovered or focused. */\n tooltip: string;\n};\n\n/**\n * Small help-circle icon button that reveals a tooltip with additional field context on hover or focus.\n *\n * @example\n * import { FieldTooltip } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldLabel>\n * Password <FieldTooltip tooltip=\"Use at least one uppercase letter and one number.\" />\n * </FieldLabel>\n */\nconst FieldTooltip = memo(({ tooltip }: FieldTooltipProps) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n tabIndex={-1}\n className=\"inline-flex cursor-default items-center text-text-positive-weak/70 hover:text-text-positive focus:outline-none\"\n >\n <HelpCircleIcon size={13} aria-hidden=\"true\" />\n <span className=\"sr-only\">Thêm thông tin</span>\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-xs text-balance\">\n {tooltip}\n </TooltipContent>\n </Tooltip>\n );\n});\nFieldTooltip.displayName = 'FieldTooltip';\n\n/**\n * Visual divider row that optionally displays a centered text label, used to separate logical sections within a `FieldGroup`.\n *\n * @example\n * import { FieldSeparator } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldSeparator>or</FieldSeparator>\n */\nconst FieldSeparator = memo(({ children, className, ...props }: React.PropsWithChildren<React.ComponentProps<'div'>>) => {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span className=\"relative mx-auto block w-fit bg-background px-2 text-text-positive-weak\" data-slot=\"field-separator-content\">\n {children}\n </span>\n )}\n </div>\n );\n});\nFieldSeparator.displayName = 'FieldSeparator';\n\n/**\n * Props for {@link FieldError}.\n */\ntype FieldErrorProps = React.ComponentProps<'div'> & {\n errors?: Array<{ code?: string; message?: string } | undefined>;\n requiredMessage?: string;\n};\n\nconst FieldError = memo(({ className, children, errors, requiredMessage = 'Trường này là bắt buộc', ...props }: FieldErrorProps) => {\n const content = useMemo(() => {\n const resolve = (error: { code?: string; message?: string }) => (error.code === 'invalid_type' ? requiredMessage : error.message);\n\n if (children) {\n return children;\n }\n\n if (!errors) {\n return null;\n }\n\n if (errors?.length === 1 && errors[0]?.message) {\n return (\n <div className=\"flex flex-row items-center justify-start gap-x-0.5\">\n <p>{resolve(errors[0])}</p>\n </div>\n );\n }\n\n return (\n <ul className=\"flex list-none flex-col\">\n {errors.map(error => {\n if (typeof error === 'string') return <li key={error}>{error}</li>;\n if (!error?.message) return null;\n return <li key={error.code ?? error.message}>{resolve(error)}</li>;\n })}\n </ul>\n );\n }, [children, errors, requiredMessage]);\n\n if (!content) {\n return null;\n }\n\n return (\n <div role=\"alert\" data-slot=\"field-error\" className={cn('w-full font-medium text-danger-strong text-xs', className)} {...props}>\n {content}\n </div>\n );\n});\nFieldError.displayName = 'FieldError';\n\nexport {\n Field,\n FieldLabel,\n FieldDescription,\n FieldNote,\n FieldError,\n FieldGroup,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldContent,\n FieldContentMain,\n FieldTitle,\n FieldTooltip,\n};\n","'use client';\n\nimport { useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { Checkbox } from '@/components/ui/checkbox';\nimport { Label } from '@/components/ui/label';\nimport { Switch } from '@/components/ui/switch';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n required?: boolean;\n disabled?: boolean;\n variant?: 'checkbox' | 'switch';\n};\n\nexport const SimpleBooleanField: React.FC<Props> = ({ label, required, disabled, variant = 'checkbox' }) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<boolean | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n const checked = state.value ?? false;\n const isDisabled = disabled || isSubmitting;\n\n const onCheckedChange = useCallback(\n (value: boolean) => {\n if (isSubmitting) return;\n handleChange(value);\n },\n [isSubmitting, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-center gap-2 h-9\">\n {variant === 'switch' ? (\n <Switch id={id} name={name} checked={checked} disabled={isDisabled} aria-invalid={_invalid} onBlur={handleBlur} onCheckedChange={onCheckedChange} />\n ) : (\n <Checkbox id={id} name={name} checked={checked} disabled={isDisabled} aria-invalid={_invalid} onBlur={handleBlur} onCheckedChange={onCheckedChange} />\n )}\n {label && (\n <Label htmlFor={id} className=\"cursor-pointer\">\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n </div>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer';\nimport { Label } from '@/components/ui/label';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n disabled?: boolean;\n options: Array<{ value: string; label: string }>;\n};\n\nexport const SimpleComboboxField: React.FC<Props> = ({ label, placeholder, required, disabled, options }) => {\n const id = useId();\n const { form, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n const isMobile = useIsMobile();\n const [drawerOpen, setDrawerOpen] = useState(false);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n const isDisabled = disabled || isSubmitting;\n\n const selectedLabel = options.find(({ value }) => value === state.value)?.label;\n\n const commandList = (\n <Command>\n <CommandInput placeholder={placeholder ?? 'Tìm kiếm…'} />\n <CommandList>\n <CommandEmpty>Không tìm thấy kết quả.</CommandEmpty>\n <CommandGroup>\n {options.map(option => (\n <CommandItem\n key={option.value}\n value={option.label}\n onSelect={() => {\n handleChange(option.value === state.value ? null : option.value);\n setDrawerOpen(false);\n }}\n >\n {option.label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n if (isMobile) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Button\n id={id}\n type=\"button\"\n variant=\"outline\"\n color=\"muted\"\n disabled={isDisabled}\n aria-invalid={_invalid}\n className={cn(\n 'w-full justify-start font-normal outline-1 outline-border -outline-offset-1',\n !state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle'\n )}\n onBlur={handleBlur}\n onClick={() => setDrawerOpen(true)}\n >\n {selectedLabel ?? <span className=\"text-text-positive-muted\">{placeholder}</span>}\n </Button>\n\n <Drawer open={drawerOpen} onOpenChange={setDrawerOpen} direction=\"bottom\">\n <DrawerContent>\n <DrawerHeader>\n <DrawerTitle>{label ?? placeholder ?? 'Tìm kiếm…'}</DrawerTitle>\n </DrawerHeader>\n <div className=\"overflow-y-auto pb-safe-bottom\">{commandList}</div>\n </DrawerContent>\n </Drawer>\n\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Popover>\n <PopoverTrigger asChild>\n <Button\n id={id}\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid}\n className={cn(\n 'flex w-full items-center justify-start rounded outline-border font-normal',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n !state.value && 'text-text-positive-muted'\n )}\n >\n {selectedLabel ?? <span className=\"text-text-positive-muted\">{placeholder}</span>}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" side=\"bottom\" className=\"w-[--radix-popover-trigger-width] p-0 rounded\" onBlur={handleBlur}>\n {commandList}\n </PopoverContent>\n </Popover>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\nimport { CalendarDaysIcon } from 'lucide-react';\n\nimport { format } from '@customafk/react-toolkit/date-fns';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Calendar } from '@/components/ui/calendar';\nimport { Label } from '@/components/ui/label';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n disabled?: boolean;\n minDate?: Date;\n maxDate?: Date;\n};\n\nexport const SimpleDateField: React.FC<Props> = ({ label, placeholder, required, disabled, minDate, maxDate }) => {\n const id = useId();\n const { form, state, handleBlur, handleChange } = useTanStackFieldContext<Date | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n const isDisabled = disabled || isSubmitting;\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Popover>\n <PopoverTrigger asChild>\n <Button\n id={id}\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid}\n className={cn(\n 'flex w-full items-center justify-between rounded outline-border font-normal',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n state.value === null && 'text-text-positive-muted'\n )}\n >\n <span>{state.value ? format(state.value, 'PPP') : (placeholder ?? 'Select date')}</span>\n <CalendarDaysIcon strokeWidth={1} />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" side=\"bottom\" className=\"w-fit p-0 rounded\" onBlur={handleBlur}>\n <Calendar\n mode=\"single\"\n selected={state.value ?? undefined}\n hidden={{\n before: minDate ?? new Date(1900, 0, 1),\n after: maxDate ?? new Date(2100, 11, 31),\n }}\n onSelect={date => {\n if (!date) return;\n handleChange(date);\n }}\n />\n </PopoverContent>\n </Popover>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { Label } from '@/components/ui/label';\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n required?: boolean;\n disabled?: boolean;\n options: Array<{ value: string; label: string }>;\n orientation?: 'horizontal' | 'vertical';\n};\n\nexport const SimpleRadioGroupField: React.FC<Props> = ({ label, required, disabled, options, orientation = 'vertical' }) => {\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n const isDisabled = disabled || isSubmitting;\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <RadioGroup\n name={name}\n value={state.value ?? ''}\n disabled={isDisabled}\n aria-invalid={_invalid}\n className={orientation === 'horizontal' ? 'flex flex-row flex-wrap gap-x-4 gap-y-2' : 'flex flex-col gap-2'}\n onValueChange={handleChange}\n onBlur={handleBlur}\n >\n {options.map(option => (\n <div key={option.value} className=\"flex items-center gap-2\">\n <RadioGroupItem id={`${name}-${option.value}`} value={option.value} />\n <Label htmlFor={`${name}-${option.value}`} className=\"cursor-pointer font-normal\">\n {option.label}\n </Label>\n </div>\n ))}\n </RadioGroup>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { AtSignIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n maxLength?: number;\n disabled?: boolean;\n};\n\nexport const SimpleEmailField: React.FC<Props> = ({ label, placeholder, required, maxLength, disabled }) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n if (maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isSubmitting, maxLength, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <div className=\"relative\">\n <Input\n id={id}\n name={name}\n type=\"email\"\n value={state.value ?? ''}\n aria-invalid={_invalid}\n autoComplete=\"email\"\n placeholder={placeholder}\n disabled={disabled || isSubmitting}\n className={cn('pl-9')}\n onBlur={handleBlur}\n onChange={onChange}\n />\n <div className=\"pointer-events-none absolute inset-y-0 left-0 flex size-9 items-center justify-center text-muted\">\n <AtSignIcon size={14} />\n </div>\n </div>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\n\nconst createValidationRegex = (allowNegative: boolean): RegExp => {\n return allowNegative ? /^-?\\d*\\.?\\d*$/ : /^\\d*\\.?\\d*$/;\n};\n\nconst formatNumberWithCommas = (num: number | string): string => {\n return Number(num).toLocaleString();\n};\n\nconst customRoundedValue = (value: number, precision: number, roundingRule: 'up' | 'down' | 'nearest' | 'none') => {\n if (roundingRule === 'none') return value;\n\n const factor = 10 ** precision;\n const scaledValue = value * factor;\n\n switch (roundingRule) {\n case 'up':\n return Math.ceil(scaledValue) / factor;\n case 'down':\n return Math.floor(scaledValue) / factor;\n case 'nearest': {\n if (scaledValue % 1 < 0.1) return Math.floor(scaledValue) / factor;\n if (scaledValue % 1 >= 0.59) return Math.ceil(scaledValue) / factor;\n return (Math.floor(scaledValue) + 0.5) / factor;\n }\n default: {\n return value;\n }\n }\n};\n\ntype TProps = React.HTMLAttributes<HTMLInputElement> & {\n /**\n * Description: Value for the text field\n *\n * Default: ''\n *\n * Usage: Value for the text field\n */\n value?: number | null | undefined;\n /**\n * Description: Disabled state of the text field\n *\n * Default: `false`\n *\n * Usage: Disabled state of the text field\n *\n * Note: If true, the text field will be disabled\n */\n disabled?: boolean;\n /**\n * Description: Readonly state of the text field\n *\n * Default: `false`\n *\n * Usage: Readonly state of the text field\n */\n readOnly?: boolean;\n /**\n * Description: Allow negative value for the text field\n *\n * Default: `false`\n *\n * Usage: Allow negative value for the text field\n */\n allowNegative?: boolean;\n /**\n * Description: Decimal point for the text field\n *\n * Default: `undefined`\n *\n * Usage: Ex: [12,3] => console.log(2323.23) // True\n *\n * Note: IF use this prop, `numberAfterDecimalPoint` will be ignored\n */\n decimal?: [number, number];\n /**\n * Description: Rounding rule for the text field\n *\n * Default: `nearest`\n *\n * Usage: Rounding rule for the text field\n * - 'up': Round up\n * - 'down': Round down\n * - 'nearest': Round to nearest\n * - 'none': No rounding\n *\n * E.g.\n * - Value: 2.135, precision: 2\n * - 'up' => 2.14\n * - 'down' => 2.13\n * - 'nearest' => 2.13\n * - 'none' => 2.135\n */\n roundingRule?: 'up' | 'down' | 'nearest' | 'none';\n /**\n * Description: Number of digits after the decimal point\n *\n * Default: `2`\n *\n * Usage: Number of digits after the decimal point\n */\n numberAfterDecimalPoint?: number;\n /**\n * Description: Placeholder for the text field\n *\n * Default: ''\n *\n * Usage: Placeholder for the text field\n */\n placeholder?: string;\n /**\n * Description: Unit text for the text field\n *\n * Default: ''\n *\n * E.g. 'kg', 'm', 'USD'...\n */\n unitText?: string;\n /**\n * Description: Invalid state of the text field\n *\n * Default: `false`\n *\n * Usage: Invalid state of the text field\n */\n invalid?: boolean;\n /**\n * Description: Precision for the text field\n *\n * Default: `undefined`\n * E.g.\n * - 2.13 => 2.1 when precision is 1\n * - 2.134 => 2.13 when precision is 2\n */\n precision?: number;\n /**\n * Description: Callback function for the value change\n * Usage: Callback function for the value change\n */\n wrapperClassName?: string;\n /**\n * Description: Callback function for the value change\n * Usage: Callback function for the value change\n */\n onValueChange?: (value: number | null) => void;\n /**\n * Description: Callback function for the blur event\n * Usage: Callback function for the blur event\n */\n onBlur?: () => void;\n};\n/**\n * ## Unit Text Field Component\n *\n * **Description**: This component is to display common text field with unit\n *\n * **Usage**: Text field with unit example: 1000 (kg), 100 (m), 1000 (USD)...\n */\nexport const NumberInput: React.FC<TProps> = ({\n disabled = false,\n readOnly = false,\n allowNegative = false,\n numberAfterDecimalPoint = 2,\n roundingRule = 'none',\n value = null,\n unitText,\n decimal,\n placeholder,\n precision,\n wrapperClassName,\n className,\n onChange,\n onValueChange,\n onFocus,\n onBlur,\n ...props\n}) => {\n const _unitRef = useRef<HTMLSpanElement>(null);\n const _inputRef = useRef<HTMLInputElement>(null);\n\n const [_value, _setValue] = useState<string | null>(value?.toString() ?? null);\n\n // Memoized values for validation and formatting\n const maxDecimalPlaces = useMemo(() => decimal?.[1] ?? numberAfterDecimalPoint, [decimal, numberAfterDecimalPoint]);\n const maxIntegerLength = useMemo(() => decimal && decimal[0] - decimal[1], [decimal]);\n const validationRegex = useMemo(() => createValidationRegex(allowNegative), [allowNegative]);\n\n // Validate decimal point is less than or equal to the limit\n const validateDecimalPoint = useCallback(\n (value: string) => {\n if (!maxDecimalPlaces || value === '-') return true;\n\n const [integerPart, decimalPart = ''] = value.split('.') as [string, string];\n const integerPartLength = integerPart.startsWith('-') ? integerPart.length - 1 : integerPart.length;\n const decimalPartLength = decimalPart.length;\n\n return decimalPartLength <= maxDecimalPlaces && integerPartLength <= (maxIntegerLength ?? Infinity);\n },\n [maxDecimalPlaces, maxIntegerLength]\n );\n const formattedValue = useCallback(\n (val: string) => {\n if (val === '0') return '0';\n if (!Number(val)) return null;\n\n const numValue = parseFloat(val);\n const effectivePrecision = Math.min(maxDecimalPlaces - 1, precision || 0);\n const roundedValue = customRoundedValue(numValue, effectivePrecision, roundingRule).toString();\n const [integerPart, decimalPart = ''] = roundedValue.split('.');\n const formattedInteger = formatNumberWithCommas(integerPart);\n return decimalPart ? `${formattedInteger}.${decimalPart}` : formattedInteger;\n },\n [maxDecimalPlaces, precision, roundingRule]\n );\n\n const handleZeroCase = useCallback(\n (value: string) => {\n // Check for zero\n const isZero = value === '0';\n // Check for negative zero patterns. E.g., '-0', '-0.0', '-0.000', '-0.'\n const isNegativeZero = value === '-' || /^-0+(\\.0+)?$/.test(value) || /^-0*\\.$/.test(value);\n if (isZero) {\n onValueChange?.(0);\n _setValue(value);\n return;\n }\n if (isNegativeZero) {\n _setValue(() => {\n onValueChange?.(0);\n return value;\n });\n return;\n }\n },\n [onValueChange]\n );\n const handleChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n e => {\n // Don't prevent default behavior of input change\n onChange?.(e);\n\n // Custom event handler for value change\n const { value: inputValue } = e.target;\n\n // Handle empty input\n if (inputValue === '' || inputValue === undefined) {\n onValueChange?.(null);\n _setValue(null);\n return;\n }\n\n // Handle zero and negative zero\n handleZeroCase(inputValue);\n\n // Validate input format\n if (!validationRegex.test(inputValue) || !validateDecimalPoint(inputValue)) return;\n\n const numericValue = parseFloat(inputValue) || 0;\n onValueChange?.(numericValue);\n _setValue(inputValue);\n },\n [validateDecimalPoint, onChange, onValueChange, handleZeroCase, validationRegex]\n );\n\n const handleFocus = useCallback<React.FocusEventHandler<HTMLInputElement>>(\n e => {\n if (readOnly) return;\n onFocus?.(e);\n _setValue(prev => (typeof prev === 'string' ? prev.replace(/,/g, '') : null)); // Remove commas for easier editing\n },\n [readOnly, onFocus]\n );\n\n const handleBlur = useCallback<React.FocusEventHandler<HTMLInputElement>>(\n e => {\n if (readOnly) return;\n onBlur?.(e);\n _setValue(prev => {\n if (prev === null) return null;\n const isZero = prev === '0' || prev === '-' || /^-0+(\\.0+)?$/.test(prev) || /^-0*\\.$/.test(prev);\n if (isZero) return '0';\n return typeof prev === 'string' ? formattedValue(prev) : null;\n });\n },\n [readOnly, formattedValue, onBlur]\n );\n\n // Set initial value\n useEffect(() => {\n const isFocused = document.activeElement === _inputRef.current;\n\n if (value === undefined || value === null || !validationRegex.test(value.toString()) || !validateDecimalPoint(value.toString())) {\n _setValue(null);\n return;\n }\n\n _setValue(prev => (isFocused ? prev : formattedValue(value.toString())));\n }, [formattedValue, value, validateDecimalPoint, validationRegex]);\n\n // Set padding right for the input field\n useEffect(() => {\n if (!_unitRef.current || !_inputRef.current || !unitText) return;\n const unitWidth = _unitRef.current.offsetWidth;\n _inputRef.current.style.setProperty('padding-right', `${(unitWidth + 10) / 16}rem`);\n }, [unitText]);\n\n return (\n <div className={cn('relative', wrapperClassName)}>\n <Input\n {...props}\n ref={_inputRef}\n value={_value || (readOnly ? '0' : '')}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n className={cn('text-end font-number text-sm slashed-zero lining-nums tabular-nums', readOnly && 'bg-muted text-muted-foreground', className)}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n />\n {unitText && (\n <span ref={_unitRef} className=\"-translate-y-1/2 pointer-events-none absolute top-1/2 right-2 text-muted-foreground text-sm\">\n {unitText}\n </span>\n )}\n </div>\n );\n};\n","'use client';\n\nimport { useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { Label } from '@/components/ui/label';\nimport { NumberInput } from '@/components/ui/inputs/number-input';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n unit?: string;\n allowNegative?: boolean;\n disabled?: boolean;\n};\n\nexport const SimpleNumberField: React.FC<Props> = ({ label, placeholder, required, unit, allowNegative, disabled }) => {\n const id = useId();\n const { form, state, handleBlur, handleChange } = useTanStackFieldContext<number | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n\n const onValueChange = useCallback(\n (value: number | null) => {\n if (isSubmitting) return;\n handleChange(value);\n },\n [isSubmitting, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <NumberInput\n id={id}\n value={state.value}\n placeholder={placeholder}\n unitText={unit}\n allowNegative={allowNegative}\n disabled={disabled || isSubmitting}\n onBlur={handleBlur}\n onValueChange={onValueChange}\n />\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useCallback, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { EyeIcon, EyeOffIcon } from 'lucide-react';\n\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n disabled?: boolean;\n};\n\nexport const SimplePasswordField: React.FC<Props> = ({ label, placeholder, required, disabled }) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const [isVisible, setIsVisible] = useState(false);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n\n const toggleVisibility = useCallback(() => setIsVisible(prev => !prev), []);\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n handleChange(value || null);\n },\n [isSubmitting, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <div className=\"relative\">\n <Input\n id={id}\n name={name}\n type={isVisible ? 'text' : 'password'}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n autoComplete=\"current-password\"\n placeholder={placeholder}\n disabled={disabled || isSubmitting}\n className=\"pr-9\"\n onBlur={handleBlur}\n onChange={onChange}\n />\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={isVisible ? 'Ẩn mật khẩu' : 'Hiện mật khẩu'}\n aria-pressed={isVisible}\n aria-controls={id}\n className=\"absolute inset-y-0 right-0 flex size-9 items-center justify-center text-muted outline-none transition-colors hover:text-text-positive focus-visible:text-text-positive disabled:pointer-events-none disabled:opacity-50\"\n disabled={disabled || isSubmitting}\n onClick={toggleVisibility}\n >\n {isVisible ? <EyeOffIcon size={16} aria-hidden=\"true\" /> : <EyeIcon size={16} aria-hidden=\"true\" />}\n </button>\n </div>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useId, useState } from 'react';\n\nimport { PackagePlusIcon } from 'lucide-react';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Drawer, DrawerClose, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer';\nimport { Label } from '@/components/ui/label';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n options: Array<{ value: string; label: string }>;\n};\n\nexport const SimpleSelectField: React.FC<Props> = ({ label, placeholder, required, options }) => {\n const id = useId();\n const { state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [drawerOpen, setDrawerOpen] = useState(false);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n const selectedLabel = options.find(o => o.value === state.value)?.label;\n\n if (isMobile) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Button\n id={id}\n type=\"button\"\n variant=\"outline\"\n color=\"muted\"\n className={cn(\n 'w-full justify-start font-normal outline-1 outline-border -outline-offset-1',\n !state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle'\n )}\n aria-invalid={_invalid}\n onBlur={handleBlur}\n onClick={() => setDrawerOpen(true)}\n >\n {selectedLabel ?? <span className=\"text-text-positive-muted\">{placeholder}</span>}\n </Button>\n\n <Drawer open={drawerOpen} onOpenChange={setDrawerOpen} direction=\"bottom\">\n <DrawerContent>\n <DrawerHeader>\n <DrawerTitle>{label ?? placeholder ?? 'Select an option'}</DrawerTitle>\n </DrawerHeader>\n <div className=\"flex flex-col overflow-y-auto pb-safe-bottom\">\n {options.length > 0 ? (\n options.map(option => (\n <DrawerClose key={option.value} asChild>\n <button\n type=\"button\"\n className={cn(\n 'flex w-full items-center px-4 py-3 text-left text-sm transition-colors',\n 'hover:bg-muted-muted active:bg-muted-muted',\n state.value === option.value && 'bg-primary-bg-subtle font-medium text-primary'\n )}\n onClick={() => {\n handleChange(option.value);\n setDrawerOpen(false);\n }}\n >\n {option.label}\n </button>\n </DrawerClose>\n ))\n ) : (\n <div className=\"flex items-center justify-center gap-x-2 px-4 py-8 text-center text-sm text-text-positive-weak\">\n <PackagePlusIcon strokeWidth={1} />\n No options available\n </div>\n )}\n </div>\n </DrawerContent>\n </Drawer>\n\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Select value={state.value ?? ''} onValueChange={handleChange}>\n <SelectTrigger id={id} aria-invalid={_invalid ? 'true' : undefined} onBlur={handleBlur}>\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent>\n {options.length > 0 ? (\n options.map(option => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))\n ) : (\n <div className=\"flex items-center justify-center gap-x-2 rounded border border-border bg-muted-muted px-4 py-6.5 text-center text-sm text-text-positive-weak\">\n <PackagePlusIcon strokeWidth={1} />\n No options available\n </div>\n )}\n </SelectContent>\n </Select>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { Textarea } from '@/components/ui/textarea';\nimport { Label } from '@/components/ui/label';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n maxLength?: number;\n rows?: number;\n disabled?: boolean;\n};\n\nexport const SimpleTextareaField: React.FC<Props> = ({ label, placeholder, required, maxLength, rows, disabled }) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLTextAreaElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n if (maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isSubmitting, maxLength, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Textarea\n id={id}\n name={name}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n placeholder={placeholder}\n rows={rows}\n disabled={disabled || isSubmitting}\n onBlur={handleBlur}\n onChange={onChange}\n />\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\nimport type { SimpleTextFieldProps as Props } from '../../types';\n\nexport const SimpleTextField: React.FC<Props> = ({ label, placeholder, required, maxLength, disabled }) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n if (maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isSubmitting, maxLength, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Input\n id={id}\n name={name}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n placeholder={placeholder}\n autoComplete=\"off\"\n disabled={disabled || isSubmitting}\n onBlur={handleBlur}\n onChange={onChange}\n />\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { Field, FieldContent, FieldContentMain, FieldDescription, FieldGroup, FieldLabel, FieldNote, FieldSeparator, FieldTooltip } from '../ui/field';\nimport { Checkbox } from '@/components/ui/checkbox';\n\nimport type { CheckboxFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected checkbox group field that manages an array of selected string values,\n * supporting multi-selection and submission-state disabling.\n *\n * @example\n * import { CheckboxField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"roles\">\n * {() => (\n * <CheckboxField\n * label=\"Roles\"\n * options={[\n * { value: 'admin', label: 'Admin' },\n * { value: 'editor', label: 'Editor' },\n * ]}\n * helperText=\"Select one or more roles\"\n * />\n * )}\n * </form.Field>\n */\nexport const CheckboxField: React.FC<Props> = ({ label, description, options, tooltip, helperText, orientation }) => {\n const field = useTanStackFieldContext<string[] | null>();\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation}>\n <FieldContent>\n <FieldLabel>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContent>\n <FieldContentMain>\n <FieldGroup className=\"flex flex-col gap-y-2\">\n {options.map(option => {\n return (\n <Field key={option.value} orientation=\"horizontal\">\n <Checkbox\n id={`${field.name}-${option.value}`}\n name={field.name}\n checked={field.state.value?.includes(option.value) ?? false}\n disabled={isSubmitting}\n onCheckedChange={checked => {\n if (checked && field.state.value !== null) {\n field.pushValue(option.value);\n } else if (checked && field.state.value === null) {\n field.setValue([option.value]);\n } else if (!checked && field.state.value !== null) {\n const index = field.state.value.indexOf(option.value);\n if (index > -1) field.removeValue(index);\n } else {\n field.setValue(null);\n }\n }}\n />\n <FieldLabel htmlFor={`${field.name}-${option.value}`} className=\"text-text-positive\">\n {option.label}\n </FieldLabel>\n </Field>\n );\n })}\n </FieldGroup>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { XIcon } from 'lucide-react';\n\nimport { Dialog as RadixDialog } from 'radix-ui';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Dialog, DialogClose, DialogOverlay, DialogPortal } from '@/components/ui/dialog';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { ComboboxFieldProps } from '../../types';\n\nexport const ComboboxField = memo<ComboboxFieldProps>(\n ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n options,\n required = false,\n disabled = false,\n clearable = false,\n showErrorMessage = true,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _showClear = clearable && !!field.state.value && !isDisabled;\n\n const selectedLabel = options.find(({ value }) => value === field.state.value)?.label;\n\n const onClear = () => {\n field.handleChange(null);\n field.handleBlur();\n };\n\n const triggerButton = (onClick?: () => void) => (\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex w-full items-center justify-start rounded outline-border',\n 'hover:bg-transparent',\n 'focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak',\n 'data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n _showClear && 'pr-8',\n !field.state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n onClick={onClick}\n >\n {selectedLabel ? (\n <p className=\"flex min-w-0 flex-1 items-center gap-2 truncate text-start\">{selectedLabel}</p>\n ) : (\n <p className=\"flex-1 text-start text-text-positive-muted\">{placeholder}</p>\n )}\n </Button>\n );\n\n const renderCommandList = (onSelect: (value: string) => void) => (\n <Command className=\"border-none\">\n <CommandInput placeholder={placeholder ?? 'Tìm kiếm…'} />\n <CommandList>\n <CommandEmpty className=\"flex min-h-30 items-center justify-center text-sm text-text-positive-weak\">Không tìm thấy kết quả nào phù hợp.</CommandEmpty>\n <CommandGroup className=\"max-h-60 overflow-y-auto\">\n {options.map(({ value, label: optLabel }) => (\n <CommandItem key={value} value={optLabel} onSelect={() => onSelect(value)}>\n {optLabel}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={field.name}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex justify-end\">\n <div className=\"flex w-full flex-col\">\n <div className=\"relative\">\n {isMobile ? (\n <>\n {triggerButton(() => setDialogOpen(true))}\n <Dialog\n open={dialogOpen}\n onOpenChange={open => {\n setDialogOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <DialogPortal>\n <DialogOverlay />\n <RadixDialog.Content\n onOpenAutoFocus={e => e.preventDefault()}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-50',\n 'flex flex-col bg-background rounded-t-2xl outline-none',\n 'max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0',\n 'duration-300'\n )}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border shrink-0\">\n <span className=\"font-semibold text-sm text-text-positive\">{label}</span>\n <DialogClose asChild>\n <button\n type=\"button\"\n aria-label=\"Đóng\"\n className=\"flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive\"\n >\n <XIcon size={16} />\n </button>\n </DialogClose>\n </div>\n\n <div className=\"flex flex-col overflow-y-auto\">\n {_showClear && (\n <DialogClose asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle\"\n onClick={onClear}\n >\n <XIcon size={14} />\n Xóa lựa chọn\n </button>\n </DialogClose>\n )}\n {renderCommandList(value => {\n field.handleChange(value);\n setDialogOpen(false);\n field.handleBlur();\n })}\n </div>\n\n <div className=\"shrink-0 h-safe-bottom\" />\n </RadixDialog.Content>\n </DialogPortal>\n </Dialog>\n </>\n ) : (\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>{triggerButton()}</PopoverTrigger>\n <PopoverContent align=\"end\" side=\"bottom\" className=\"flex w-fit rounded p-0\">\n {renderCommandList(value => {\n field.handleChange(value);\n setPopoverOpen(false);\n field.handleBlur();\n })}\n </PopoverContent>\n </Popover>\n )}\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa lựa chọn\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n </div>\n\n {_touched && showErrorMessage && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nComboboxField.displayName = 'ComboboxField';\n","'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { CalendarDaysIcon } from 'lucide-react';\n\nimport { endOfToday, endOfTomorrow, endOfYesterday, format, lastDayOfMonth, startOfMonth, subDays } from '@customafk/react-toolkit/date-fns';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Calendar } from '@/components/ui/calendar';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { DateFieldProps as Props } from '../../types';\n\nexport const DateField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n helperText,\n showErrorMessage = true,\n required = false,\n disabled = false,\n minDate,\n maxDate,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<Date | null>();\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _isInvalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n\n const handleSelect = (date: Date) => {\n field.handleChange(date);\n setPopoverOpen(false);\n };\n\n return (\n <FieldGroup className=\"px-4\">\n <Field orientation={orientation} data-invalid={_isInvalid}>\n <FieldContent>\n <FieldLabel htmlFor={field.name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex flex-col space-y-1\">\n <div className=\"flex w-full flex-col\">\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_isInvalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex items-center justify-between rounded font-normal outline-border',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n field.state.value === null && 'text-text-positive-muted',\n _isInvalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n >\n <p>{field.state.value === null ? (placeholder ?? 'Select date') : format(field.state.value, 'PPPP')}</p>\n <CalendarDaysIcon strokeWidth={1} />\n </Button>\n </PopoverTrigger>\n\n <PopoverContent align=\"start\" side=\"bottom\" className=\"flex w-fit min-w-0 overflow-y-auto rounded p-0\">\n <div className=\"flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm\">\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfToday())}>\n Hôm nay\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfTomorrow())}>\n Ngày mai\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfYesterday())}>\n Hôm qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 3))}>\n 3 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 7))}>\n 7 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 30))}>\n 30 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(startOfMonth(endOfToday()))}>\n Tháng này\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(lastDayOfMonth(endOfToday()))}>\n Tháng trước\n </Button>\n </div>\n <div className=\"flex flex-1 flex-col\">\n <div className=\"min-w-73 border-b border-b-border p-2\">\n <Calendar\n mode=\"single\"\n selected={field.state.value ?? undefined}\n hidden={{\n before: minDate ?? new Date(1900, 0, 1),\n after: maxDate ?? new Date(2100, 11, 31),\n }}\n onSelect={date => {\n if (!date) return;\n handleSelect(date);\n }}\n />\n </div>\n </div>\n </PopoverContent>\n </Popover>\n\n {_touched && showErrorMessage && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nDateField.displayName = 'DateField';\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { AtSignIcon, XIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\nimport { useTanStackFieldContext } from '../../tanstack-form';\n\nimport type { EmailFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected email input field with an at-sign prefix icon,\n * optional clear button, and inline validation error display.\n *\n * @example\n * import { EmailField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"email\">\n * {() => (\n * <EmailField\n * label=\"Email address\"\n * placeholder=\"you@example.com\"\n * required\n * />\n * )}\n * </form.Field>\n */\nexport const EmailField: React.FC<Props> = ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n showErrorMessage = true,\n required = false,\n maxLength,\n}) => {\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isDirty && state.meta.isTouched && !state.meta.isValid;\n const _isEmpty = required && state.value === null;\n const _showClear = !isSubmitting && !!state.value;\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n if (maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isSubmitting, maxLength, handleChange]\n );\n\n const onClear = useCallback(() => {\n if (isSubmitting) return;\n handleChange(null);\n }, [isSubmitting, handleChange]);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field data-invalid={_invalid} orientation={orientation}>\n <FieldContent>\n <FieldLabel htmlFor={name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldContentMain>\n <Input\n id={name}\n name={name}\n value={state.value === null ? '' : state.value}\n aria-invalid={_invalid}\n autoComplete=\"email\"\n placeholder={placeholder}\n className={cn('pl-9', _showClear && 'pr-9', isSubmitting && 'pointer-events-none bg-muted-muted opacity-60')}\n onBlur={handleBlur}\n onChange={onChange}\n />\n <div className=\"absolute top-0 left-0 flex size-9 items-center justify-center text-muted\">\n <AtSignIcon size={14} />\n </div>\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa\"\n className=\"absolute inset-e-0 inset-y-0 top-3 flex h-fit w-8 cursor-pointer items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:text-text-positive-strong\"\n onClick={onClear}\n >\n <XIcon size={14} aria-hidden=\"true\" />\n </button>\n )}\n\n <div className=\"mt-1 flex w-full items-start justify-start\">\n {showErrorMessage && state.meta.isDirty && <FieldError errors={state.meta.errors} />}\n </div>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { memo, useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { BanIcon, Loader2Icon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { NumberInput } from '@/components/ui/inputs/number-input';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { NumberFieldProps } from '../../types';\n\n/**\n * A TanStack Form-connected numeric input field supporting rounding rules,\n * decimal precision, unit labels, and submission-state feedback.\n *\n * @example\n * import { NumberField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"quantity\">\n * {() => (\n * <NumberField\n * label=\"Quantity\"\n * placeholder=\"0\"\n * unit=\"pcs\"\n * decimalPlaces={2}\n * required\n * />\n * )}\n * </form.Field>\n */\nexport const NumberField = memo<NumberFieldProps>(\n ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n showErrorMessage = true,\n rounding,\n decimalPlaces,\n precision,\n unit,\n required = false,\n disabled = false,\n allowNegative,\n }) => {\n const id = useId();\n const errorId = useId();\n\n const field = useTanStackFieldContext<number | null>();\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _hasErrors = !!field.state.meta.errors.length;\n\n const onValueChange = useCallback(\n (value: number | null) => {\n if (isDisabled) return;\n field.handleChange(value);\n },\n [isDisabled, field.handleChange]\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel htmlFor={id} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain>\n <div className=\"relative w-full\">\n <NumberInput\n id={id}\n value={field.state.value}\n aria-invalid={_invalid}\n aria-describedby={errorId}\n placeholder={placeholder}\n disabled={isDisabled}\n roundingRule={rounding}\n numberAfterDecimalPoint={decimalPlaces}\n precision={precision}\n unitText={unit}\n allowNegative={allowNegative}\n className={cn(isDisabled && 'pointer-events-none opacity-60')}\n onBlur={field.handleBlur}\n onValueChange={onValueChange}\n />\n {isSubmitting && (\n <div className=\"pointer-events-none absolute inset-s-2 inset-y-0 top-2.5 [&>svg]:size-3.5\">\n <Loader2Icon className=\"animate-spin text-primary-strong\" />\n </div>\n )}\n {!isSubmitting && _touched && showErrorMessage && _hasErrors && (\n <div className=\"pointer-events-none absolute inset-s-2 inset-y-0 top-2.75 text-danger-strong [&>svg]:size-3.5\">\n <BanIcon />\n </div>\n )}\n <div className=\"mt-1 flex w-full items-start justify-between gap-x-2\">\n {_touched && showErrorMessage ? <FieldError id={errorId} className=\"flex-1\" errors={field.state.meta.errors} /> : <div />}\n </div>\n </div>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nNumberField.displayName = 'NumberField';\n","'use client';\n\nimport { useCallback, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { EyeIcon, EyeOffIcon } from 'lucide-react';\n\nimport { Input } from '@/components/ui/input';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { PasswordFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected password input field with a show/hide toggle button\n * and inline validation error display.\n *\n * @example\n * import { PasswordField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"password\">\n * {() => (\n * <PasswordField\n * label=\"Password\"\n * placeholder=\"Enter your password\"\n * helperText=\"Must be at least 8 characters\"\n * />\n * )}\n * </form.Field>\n */\nexport const PasswordField: React.FC<Props> = ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n helperText,\n showErrorMessage = true,\n}) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const [isVisible, setIsVisible] = useState<boolean>(false);\n\n const _invalid = state.meta.isDirty && state.meta.isTouched && !state.meta.isValid;\n\n const toggleVisibility = useCallback(() => setIsVisible(prev => !prev), []);\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n handleChange(value || null);\n },\n [isSubmitting, handleChange]\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field data-invalid={_invalid} orientation={orientation}>\n <FieldContent>\n <FieldLabel htmlFor={id}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldContentMain>\n <Input\n id={id}\n name={name}\n type={isVisible ? 'text' : 'password'}\n placeholder={placeholder}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n autoComplete=\"new-password\"\n onBlur={handleBlur}\n onChange={onChange}\n />\n\n <button\n className=\"absolute inset-e-0 inset-y-0 flex size-9 items-center justify-center rounded-e-md text-muted outline-none transition-[color,box-shadow] focus:z-10 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n type=\"button\"\n onClick={toggleVisibility}\n aria-label={isVisible ? 'Ẩn mật khẩu' : 'Hiện mật khẩu'}\n aria-pressed={isVisible}\n aria-controls={id}\n >\n {isVisible ? <EyeOffIcon size={16} aria-hidden=\"true\" /> : <EyeIcon size={16} aria-hidden=\"true\" />}\n </button>\n\n <div className=\"mt-1 flex w-full items-start justify-start\">\n {showErrorMessage && state.meta.isDirty && <FieldError errors={state.meta.errors} />}\n </div>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTitle,\n FieldTooltip,\n} from '../ui/field';\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';\n\nimport type { RadioGroupFieldProps as Props } from '../../types';\n\nexport const RadioGroupField: React.FC<Props> = ({ label, description, orientation, options, tooltip, helperText }) => {\n const field = useTanStackFieldContext<string | null>();\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n\n return (\n <FieldGroup className=\"px-4\">\n <Field orientation={orientation} className=\"flex-col gap-2\">\n <FieldContent>\n <FieldLabel>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContent>\n\n <FieldContentMain>\n <RadioGroup value={field.state.value ?? ''} className=\"w-full\" onValueChange={field.handleChange}>\n {options.map(option => (\n <FieldLabel\n key={option.value}\n className={cn(\n 'h-fit',\n field.state.value === option.value && 'border-primary-weak! bg-primary-bg-subtle',\n isSubmitting && 'pointer-events-none bg-muted-muted opacity-60',\n field.state.value === option.value && isSubmitting && 'border-border-strong!'\n )}\n >\n <Field orientation=\"horizontal\" className=\"items-start gap-3 rounded p-2!\">\n <RadioGroupItem value={option.value} className=\"mt-0.5 shrink-0\" />\n <FieldContent className=\"gap-0.5!\">\n <FieldTitle>{option.label}</FieldTitle>\n <FieldDescription className=\"text-xs\">{option.description}</FieldDescription>\n </FieldContent>\n </Field>\n </FieldLabel>\n ))}\n </RadioGroup>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { ChevronDownIcon, PackagePlusIcon, XIcon } from 'lucide-react';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Dialog as RadixDialog } from 'radix-ui';\n\nimport { Dialog, DialogClose, DialogOverlay, DialogPortal } from '@/components/ui/dialog';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { SelectFieldProps as Props } from '../../types';\n\nexport const SelectField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n options,\n helperText,\n clearable = false,\n required = false,\n disabled = false,\n showErrorMessage = true,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [dialogOpen, setDialogOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _showClear = clearable && !!field.state.value && !isDisabled;\n\n const selectedLabel = options.find(o => o.value === field.state.value)?.label;\n\n const onClear = () => {\n field.handleChange(null);\n field.handleBlur();\n };\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel htmlFor={field.name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex flex-col\">\n {isMobile ? (\n <>\n <button\n id={field.name}\n type=\"button\"\n disabled={isDisabled}\n aria-invalid={_invalid ? 'true' : undefined}\n aria-describedby={errorId}\n onBlur={field.handleBlur}\n onClick={() => setDialogOpen(true)}\n className={cn(\n 'flex w-full items-center justify-between',\n 'outline-1 outline-border -outline-offset-1',\n 'gap-2 rounded bg-transparent px-3 py-2',\n 'shadow-input transition-all cursor-pointer whitespace-nowrap text-sm',\n 'focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n _invalid && 'outline-danger bg-danger-bg-subtle ring-danger-weak',\n !field.state.value && 'text-text-positive-muted'\n )}\n >\n <span className=\"line-clamp-1\">{selectedLabel ?? placeholder}</span>\n <ChevronDownIcon size={16} className=\"shrink-0 opacity-50\" />\n </button>\n\n <Dialog\n open={dialogOpen}\n onOpenChange={open => {\n setDialogOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <DialogPortal>\n <DialogOverlay />\n <RadixDialog.Content\n onOpenAutoFocus={e => e.preventDefault()}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-50',\n 'flex flex-col bg-background rounded-t-2xl outline-none',\n 'max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0',\n 'duration-300'\n )}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border shrink-0\">\n <span className=\"font-semibold text-sm text-text-positive\">{label ?? placeholder ?? 'Chọn một tùy chọn'}</span>\n <DialogClose asChild>\n <button\n type=\"button\"\n aria-label=\"Đóng\"\n className=\"flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive\"\n >\n <XIcon size={16} />\n </button>\n </DialogClose>\n </div>\n\n <div className=\"flex flex-col overflow-y-auto\">\n {_showClear && (\n <DialogClose asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle\"\n onClick={onClear}\n >\n <XIcon size={14} />\n Xóa lựa chọn\n </button>\n </DialogClose>\n )}\n {options.length > 0 ? (\n options.map(option => (\n <DialogClose key={option.value} asChild>\n <button\n type=\"button\"\n className={cn(\n 'flex w-full items-center px-4 py-3 text-left text-sm transition-colors',\n 'hover:bg-muted-muted active:bg-muted-muted',\n field.state.value === option.value && 'bg-primary-bg-subtle font-medium text-primary'\n )}\n onClick={() => {\n field.handleChange(option.value);\n field.handleBlur();\n }}\n >\n {option.label}\n </button>\n </DialogClose>\n ))\n ) : (\n <div className=\"flex items-center justify-center gap-x-2 px-4 py-8 text-center text-sm text-text-positive-weak\">\n <PackagePlusIcon strokeWidth={1} />\n Không có tùy chọn\n </div>\n )}\n </div>\n\n <div className=\"shrink-0 h-safe-bottom\" />\n </RadixDialog.Content>\n </DialogPortal>\n </Dialog>\n </>\n ) : (\n <div className=\"relative\">\n <Select value={field.state.value ?? ''} disabled={isDisabled} onValueChange={field.handleChange}>\n <SelectTrigger aria-invalid={_invalid ? 'true' : undefined} aria-describedby={errorId} onBlur={field.handleBlur}>\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent>\n {options.length > 0 ? (\n options.map(option => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))\n ) : (\n <div className=\"flex items-center justify-center gap-x-2 rounded border border-border bg-muted-muted px-4 py-6.5 text-center text-sm text-text-positive-weak\">\n <PackagePlusIcon strokeWidth={1} />\n No options available\n </div>\n )}\n </SelectContent>\n </Select>\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa lựa chọn\"\n className=\"absolute right-7 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n </div>\n )}\n\n {_touched && showErrorMessage && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nSelectField.displayName = 'SelectField';\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Switch as SwitchPrimitive } from 'radix-ui';\n\n/**\n * Accessible toggle switch built on Radix UI, styled with primary-color checked state and smooth thumb transition.\n *\n * @example\n * import { Switch } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <Switch defaultChecked onCheckedChange={(checked) => console.log(checked)} />\n */\nfunction Switch({ className, ...props }: React.ComponentProps<typeof SwitchPrimitive.Root>) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n className={cn(\n 'peer',\n 'w-8 shrink-0 cursor-pointer items-center rounded-full shadow-xs transition-all',\n 'inline-flex h-5',\n 'focus-visible:border-primary-strong',\n 'focus-visible:ring-primary-weak',\n 'focus-visible:ring-4',\n 'disabled:cursor-not-allowed',\n 'disabled:opacity-50',\n\n '-outline-offset-1 inset-shadow-2xs outline-1',\n\n 'data-[state=checked]:bg-primary',\n 'data-[state=checked]:outline-primary-strong',\n\n 'data-[state=unchecked]:bg-muted-weak',\n 'data-[state=unchecked]:outline-border',\n\n 'data-[state=unchecked]:[&_span]:size-4',\n 'data-[state=unchecked]:[&_span]:translate-x-0.5',\n 'data-[state=unchecked]:[&_span]:rtl:-translate-x-0.5',\n className\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className={cn(\n 'block size-4 bg-card shadow-xs',\n 'pointer-events-none rounded-full ring-0 transition-transform',\n 'data-[state=checked]:translate-x-[calc(100%-3px)]',\n 'data-[state=unchecked]:translate-x-0'\n )}\n />\n </SwitchPrimitive.Root>\n );\n}\n\nexport { Switch };\n","'use client';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { Field, FieldContent, FieldDescription, FieldGroup, FieldNote, FieldSeparator, FieldTitle } from '../ui/field';\nimport { Switch } from '../ui/switch';\n\nimport type { SwitchFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected boolean toggle field rendered as a labelled switch,\n * positioned absolutely in the top-right corner of the field card.\n *\n * @example\n * import { SwitchField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"notifications\">\n * {() => (\n * <SwitchField\n * label=\"Enable notifications\"\n * description=\"Receive email alerts for important events\"\n * helperText=\"You can change this at any time\"\n * />\n * )}\n * </form.Field>\n */\nexport const SwitchField: React.FC<Props> = ({ label, description, helperText }) => {\n const field = useTanStackFieldContext<boolean | null>();\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation=\"vertical\" className=\"relative justify-between gap-y-1\">\n <FieldContent>\n <FieldTitle className=\"cursor-pointer\">\n <label htmlFor={field.name}>{label}</label>\n </FieldTitle>\n <FieldDescription>{description}</FieldDescription>\n <Switch\n id={field.name}\n checked={field.state.value ?? false}\n className=\"absolute top-1 right-1\"\n onBlur={field.handleBlur}\n onCheckedChange={field.handleChange}\n />\n </FieldContent>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { memo, useCallback, useId, useRef } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { BanIcon, Loader2Icon, XIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '@/components/features/tanstack-form/components/ui/field';\nimport { useTanStackFieldContext } from '../../tanstack-form';\n\nimport type { TextFieldProps as Props } from '../../types';\n\n/** Fraction of maxLength at which the counter turns warning color (80%). */\nconst COUNTER_WARNING_THRESHOLD = 0.8;\n\n/** Pixel size for inline adornment icons (error ban, loading spinner). */\nconst ADORNMENT_ICON_SIZE = 14;\n\n// Static handler — no closure deps, shared across all TextField instances\nconst onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = e => {\n if (e.key === 'Enter') e.preventDefault();\n};\n\n/**\n * A TanStack Form-connected single-line text input with label, validation, and optional features.\n *\n * Must be rendered inside an `AppField` context from `useTanStackForm`.\n * The field value type is `string | null` — `null` represents an empty/unset state.\n *\n * ---\n *\n * **Basic usage**\n * @example\n * const { AppField } = useTanStackForm({ defaultValues: { name: null } });\n *\n * <AppField name=\"name\">\n * {field => <field.TextField label=\"Full name\" placeholder=\"Nguyễn Văn A\" />}\n * </AppField>\n *\n * ---\n *\n * **With validation**\n * @example\n * <AppField\n * name=\"username\"\n * validators={{ onChange: ({ value }) => !value ? 'Bắt buộc' : undefined }}\n * >\n * {field => <field.TextField label=\"Username\" required />}\n * </AppField>\n *\n * ---\n *\n * **With character counter and max length**\n * @example\n * <AppField name=\"bio\">\n * {field => (\n * <field.TextField\n * label=\"Bio\"\n * counter\n * maxLength={160}\n * placeholder=\"Giới thiệu bản thân…\"\n * />\n * )}\n * </AppField>\n *\n * ---\n *\n * **With clear button and helper note**\n * @example\n * <AppField name=\"search\">\n * {field => (\n * <field.TextField\n * label=\"Tìm kiếm\"\n * showClearButton\n * helperText=\"Nhập ít nhất 3 ký tự để tìm kiếm.\"\n * />\n * )}\n * </AppField>\n *\n * ---\n *\n * **Horizontal layout**\n * @example\n * <AppField name=\"code\">\n * {field => (\n * <field.TextField\n * label=\"Mã sản phẩm\"\n * orientation=\"horizontal\"\n * tooltip=\"Mã duy nhất định danh sản phẩm trong hệ thống.\"\n * />\n * )}\n * </AppField>\n */\nexport const TextField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n\n tooltip,\n helperText,\n counter = false,\n orientation = 'responsive',\n showClearButton = false,\n showErrorMessage = true,\n\n required = false,\n disabled = false,\n maxLength,\n }) => {\n const id = useId();\n const errorId = useId();\n const inputRef = useRef<HTMLInputElement>(null);\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = state.meta.isDirty || state.meta.isTouched;\n const _invalid = _touched && !state.meta.isValid;\n const _isEmpty = required && state.value === null;\n const _hasErrors = state.meta.errors.length > 0;\n const _showClearButton = showClearButton && !isDisabled && !!state.value;\n\n // Counter values are only computed when the feature is active\n const _count = counter ? (state.value?.length ?? 0) : 0;\n const _isNearLimit = counter && !!maxLength && _count >= maxLength * COUNTER_WARNING_THRESHOLD;\n const _isAtLimit = counter && !!maxLength && _count >= maxLength;\n const _countText = counter ? (maxLength ? `${_count} / ${maxLength} ký tự` : `${_count} ký tự`) : null;\n\n // Skip the bottom row entirely when neither error nor counter will render\n const _showBottomRow = counter || (_touched && showErrorMessage);\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (counter && maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [counter, maxLength, handleChange]\n );\n\n const onClear = useCallback(() => {\n handleChange(null);\n inputRef.current?.focus();\n }, [handleChange]);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={id}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n {description && <FieldDescription>{description}</FieldDescription>}\n </FieldContent>\n <FieldContentMain>\n <Input\n ref={inputRef}\n id={id}\n name={name}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n aria-describedby={errorId}\n autoComplete=\"off\"\n placeholder={placeholder}\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n disabled={isDisabled}\n className={cn('pr-6', isDisabled && 'pointer-events-none bg-muted-muted opacity-60')}\n onBlur={handleBlur}\n onChange={onChange}\n onKeyDown={onKeyDown}\n />\n {_showClearButton && (\n <button\n type=\"button\"\n aria-label=\"Xóa\"\n className=\"absolute inset-e-1 top-2.5 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n {isSubmitting && (\n <div className=\"absolute inset-e-2 inset-y-0 top-2.5 text-muted-weak\">\n <Loader2Icon size={ADORNMENT_ICON_SIZE} className=\"animate-spin text-primary-strong\" />\n </div>\n )}\n {!_showClearButton && _touched && showErrorMessage && _hasErrors && (\n <div className=\"absolute inset-e-2 inset-y-0 top-2.5 text-danger-strong\">\n <BanIcon aria-hidden=\"true\" size={ADORNMENT_ICON_SIZE} />\n </div>\n )}\n {_showBottomRow && (\n <div className=\"my-1 flex w-full items-start justify-between gap-x-2\">\n {_touched && showErrorMessage ? <FieldError id={errorId} className=\"flex-1\" errors={state.meta.errors} /> : <div />}\n {counter && (\n <p\n className={cn(\n 'h-4 flex-0 text-nowrap text-end text-xs tabular-nums transition-colors',\n _isAtLimit ? 'font-medium text-danger-strong' : _isNearLimit ? 'text-warning-strong' : 'text-text-positive-weak'\n )}\n >\n {_countText}\n </p>\n )}\n </div>\n )}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nTextField.displayName = 'TextField';\n","'use client';\n\nimport { memo, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { BanIcon, CheckIcon, CopyIcon, Loader2Icon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Textarea } from '@/components/ui/textarea';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { TextareaFieldProps as Props } from '../../types';\n\nexport const TextareaField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n\n tooltip,\n helperText,\n counter = false,\n orientation = 'responsive',\n showErrorMessage = true,\n\n required = false,\n disabled = false,\n maxLength,\n }) => {\n const id = useId();\n const errorId = useId();\n const [copied, setCopied] = useState(false);\n const copyTimeoutRef = useRef<number | null>(null);\n\n const { form, state, name, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _count = state.value?.length ?? 0;\n\n const _countText = useMemo(() => {\n if (!counter) return '';\n return maxLength ? `${_count} / ${maxLength} ký tự` : `${_count} ký tự`;\n }, [_count, counter, maxLength]);\n\n const _isNearLimit = !!maxLength && _count >= maxLength * 0.8;\n const _isAtLimit = !!maxLength && _count >= maxLength;\n\n const _touched = state.meta.isDirty || state.meta.isTouched;\n const _invalid = _touched && !state.meta.isValid;\n const _isEmpty = required && state.value === null;\n const _hasErrors = !!state.meta.errors.length;\n const _showCopy = !!state.value && !isDisabled;\n\n const _counterClass = useMemo(\n () =>\n cn(\n 'h-4 flex-0 text-nowrap text-end text-xs tabular-nums transition-colors',\n _isAtLimit ? 'font-medium text-danger-strong' : _isNearLimit ? 'text-warning-strong' : 'text-text-positive-weak'\n ),\n [_isAtLimit, _isNearLimit]\n );\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLTextAreaElement>>(\n ({ target: { value } }) => {\n if (isDisabled) return;\n if (counter && maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isDisabled, counter, maxLength, handleChange]\n );\n\n const onCopy = useCallback(async () => {\n if (!state.value) return;\n await navigator.clipboard.writeText(state.value);\n if (copyTimeoutRef.current !== null) window.clearTimeout(copyTimeoutRef.current);\n setCopied(true);\n copyTimeoutRef.current = window.setTimeout(() => setCopied(false), 1500);\n }, [state.value]);\n\n useEffect(() => {\n return () => {\n if (copyTimeoutRef.current !== null) window.clearTimeout(copyTimeoutRef.current);\n };\n }, []);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={id}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldContentMain>\n <Textarea\n id={id}\n name={name}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n aria-describedby={errorId}\n autoCapitalize=\"none\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n placeholder={placeholder}\n disabled={isDisabled}\n className={cn(isDisabled && 'pointer-events-none bg-muted-muted opacity-60')}\n onChange={onChange}\n onBlur={handleBlur}\n />\n {_showCopy && (\n <button\n type=\"button\"\n aria-label=\"Sao chép\"\n className=\"absolute inset-e-1 top-2 flex size-4 cursor-pointer items-center justify-center rounded-md outline-none transition-[color,transform] focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onCopy}\n >\n {copied ? (\n <CheckIcon aria-hidden=\"true\" className=\"text-success-strong\" />\n ) : (\n <CopyIcon\n aria-hidden=\"true\"\n className=\"text-text-positive-weak transition-colors hover:text-text-positive focus-visible:text-primary-strong\"\n />\n )}\n </button>\n )}\n {isSubmitting && (\n <div className=\"absolute inset-e-2 inset-y-0 top-2.5 text-muted-weak\">\n <Loader2Icon size={14} className=\"animate-spin text-primary-strong\" />\n </div>\n )}\n {!_showCopy && _touched && showErrorMessage && _hasErrors && (\n <div className=\"absolute inset-e-2 inset-y-0 top-2.5 text-danger-strong\">\n <BanIcon size={14} />\n </div>\n )}\n <div className=\"my-1 flex w-full items-start justify-between gap-x-2\">\n {_touched && showErrorMessage ? <FieldError id={errorId} className=\"flex-1\" errors={state.meta.errors} /> : <div />}\n {!!counter && <p className={_counterClass}>{_countText}</p>}\n </div>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nTextareaField.displayName = 'TextareaField';\n","'use client';\n\nimport { memo, useCallback } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { TextEditor } from '@/components/features/text-editor';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldNote, FieldSeparator, FieldTooltip } from '../ui/field';\n\nimport type { TextEditorFieldProps as Props } from '../../types';\n\nexport const TextEditorField: React.FC<Props> = memo(({ label, description, placeholder, tooltip, helperText, showErrorMessage = true, required = false }) => {\n const { form, state, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isDirty && state.meta.isTouched && !state.meta.isValid;\n const _isEmpty = required && state.value === null;\n\n const onChange = useCallback(\n (html: string) => {\n if (isSubmitting) return;\n handleChange(html || null);\n },\n [isSubmitting, handleChange]\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation=\"vertical\" data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <TextEditor value={state.value ?? ''} placeholder={placeholder} readOnly={isSubmitting} onChange={onChange} />\n {state.meta.isDirty && showErrorMessage && !!state.meta.errors.length && <FieldError errors={state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n});\nTextEditorField.displayName = 'TextEditorField';\n","import { useCallback } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../../tanstack-form';\n\n/**\n * Renders a submit button wired to the current TanStack Form context, automatically handling loading and disabled states.\n *\n * @example\n * import { TanStackActionSubmit } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionSubmit label=\"Save Changes\" className=\"mt-4\" />\n */\nexport const TanStackActionSubmit: React.FC<{\n /** Button label text. Defaults to `'Submit'` when omitted. */\n label?: string;\n /** Additional CSS class names applied to the button element. */\n className?: string;\n}> = ({ label, className }) => {\n const form = useTanStackFormContext();\n\n const onSubmit = useCallback(async () => {\n await form.handleSubmit({ submitAction: 'submit' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }, [form]);\n return (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button type=\"button\" size=\"md\" disabled={disabled} isLoading={isSubmitting} className={cn('min-h-8 min-w-32', className)} onClick={onSubmit}>\n {label ?? 'Xác nhận'}\n </Button>\n );\n }}\n />\n );\n};\n","import { ArrowDownToLine, PlusIcon } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../../tanstack-form';\n\n/**\n * Renders a form action bar with a Cancel button and a context-aware submit button (Add New or Update) driven by TanStack Form state.\n *\n * @example\n * import { TanStackActionsForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionsForm type=\"create\" />\n *\n * // For an update workflow:\n * <TanStackActionsForm type=\"update\" />\n */\nexport const TanStackActionsForm: React.FC<\n React.PropsWithChildren<{\n /**\n * Determines which submit button variant is rendered.\n * - `'create'` — shows an \"Add New\" button that resets the form on success.\n * - `'update'` — shows an \"Update\" button that resets the form on success.\n * Defaults to `'create'`.\n */\n type?: 'create' | 'update';\n }>\n> = ({ type = 'create' }) => {\n const form = useTanStackFormContext();\n return (\n <div className=\"flex h-8 items-center justify-between\">\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || state.isSubmitting,\n })}\n children={({ disabled }) => {\n return (\n <Button color=\"muted\" variant=\"outline\" type=\"button\" size=\"md\" disabled={disabled} className=\"h-full min-w-32\" onClick={() => form.reset()}>\n Hủy bỏ\n </Button>\n );\n }}\n />\n {type === 'create' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'create' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <PlusIcon />\n Thêm mới\n </Button>\n );\n }}\n />\n )}\n {type === 'update' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'update' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <ArrowDownToLine />\n Cập nhật\n </Button>\n );\n }}\n />\n )}\n </div>\n );\n};\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Separator as SeparatorPrimitive } from 'radix-ui';\n\n/**\n * Thin decorative divider line that supports horizontal and vertical orientations via Radix UI Separator.\n *\n * @example\n * import { Separator } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <Separator orientation=\"horizontal\" />\n */\nfunction Separator({ className, orientation = 'horizontal', decorative = true, ...props }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n 'shrink-0 bg-border-weak',\n 'data-[orientation=horizontal]:h-px',\n 'data-[orientation=horizontal]:w-full',\n 'data-[orientation=vertical]:h-full',\n 'data-[orientation=vertical]:w-px',\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Separator };\n","'use client';\n\nimport { Trash2Icon } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\n\nimport { Separator } from '../ui/separator';\n\n/**\n * Renders a card-style form section with a header, optional description, a delete button, and a content area for fields.\n *\n * @example\n * import { TanStackCardForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackCardForm\n * title=\"Shipping Address\"\n * description=\"Where should we deliver your order?\"\n * onDelete={() => removeAddress(id)}\n * >\n * <TextField name=\"street\" />\n * </TanStackCardForm>\n */\nexport const TanStackCardForm: React.FC<\n React.PropsWithChildren<{\n /** Bold heading text shown at the top of the card. */\n title: string;\n /** Optional secondary text rendered beneath the title. */\n description?: string;\n /** When provided, renders a danger \"Remove\" button in the card's top-right corner. */\n onDelete?: () => void | Promise<void>;\n }>\n> = ({ title, description, onDelete, children }) => {\n return (\n <section data-slot=\"card-form\" className=\"relative flex flex-col rounded-md bg-card pb-4 shadow-card ring-1 ring-border\">\n <div data-slot=\"card-form-header\" className=\"flex flex-col space-y-0.5 px-4 py-3\">\n <p className=\"font-semibold text-base tracking-tight\">{title}</p>\n {!!description && <p className=\"text-text-positive-weak text-sm\">{description}</p>}\n </div>\n <Separator />\n <div data-slot=\"card-form-main\" className=\"flex flex-col py-4\">\n {children}\n </div>\n {!!onDelete && (\n <Button\n color=\"danger\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute top-2.5 right-3\"\n onClick={e => {\n onDelete?.();\n e.preventDefault();\n e.stopPropagation();\n }}\n >\n <Trash2Icon />\n Remove\n </Button>\n )}\n </section>\n );\n};\n","/**\n * Wraps a set of TanStack form sections in a vertically-stacked flex container.\n *\n * @example\n * import { TanStackContainerForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackContainerForm>\n * <TanStackSectionForm title=\"Personal Info\">\n * {/* fields *\\/}\n * </TanStackSectionForm>\n * </TanStackContainerForm>\n */\nexport const TanStackContainerForm: React.FC<React.PropsWithChildren> = ({ children }) => {\n return (\n <div data-slot=\"section-form\" className=\"flex flex-col space-y-4\">\n {children}\n </div>\n );\n};\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\n/**\n * Secondary outline button used to dismiss or cancel a form without submitting, defaulting to the label \"Cancel\".\n *\n * @example\n * import { CancelButton } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <CancelButton onClick={() => router.back()} />\n */\nexport const CancelButton: React.FC<React.ComponentProps<'button'>> = ({ disabled, className, onClick, children }) => {\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n color=\"muted\"\n disabled={disabled}\n className={cn('min-w-40', className)}\n onClick={onClick as React.MouseEventHandler<HTMLButtonElement>}\n >\n {children ?? 'Huỷ'}\n </Button>\n );\n};\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\n/**\n * Props for the {@link SubmitButton} component.\n */\ntype SubmitButtonProps = React.ComponentProps<'button'> & {\n /**\n * When `true` the button enters a loading state and is automatically disabled to prevent duplicate submissions.\n */\n isSubmitting?: boolean;\n /**\n * Label text rendered inside the button.\n * @default 'Submit'\n */\n submitText?: string;\n};\n\n/**\n * Primary form submission button that shows a loading indicator while the form is being submitted.\n *\n * @example\n * import { SubmitButton } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <SubmitButton isSubmitting={form.state.isSubmitting} submitText=\"Save changes\" />\n */\nexport const SubmitButton: React.FC<SubmitButtonProps> = ({ isSubmitting, submitText = 'Xác nhận', disabled, className, onClick }) => {\n return (\n <Button\n type=\"button\"\n isLoading={isSubmitting}\n disabled={disabled || isSubmitting}\n className={cn('min-w-40', className)}\n onClick={onClick as React.MouseEventHandler<HTMLButtonElement>}\n >\n {submitText}\n </Button>\n );\n};\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Dialog, DialogContent, DialogOverlay, DialogPortal, DialogTitle } from '@/components/ui/dialog';\nimport { Separator } from '@/components/ui/separator';\n\nimport { useTanStackFormContext } from '../../tanstack-form';\nimport { CancelButton } from '../ui/cancel-button';\nimport { SubmitButton } from '../ui/submit-button';\n\n/**\n * Renders a modal dialog that wraps a TanStack Form with a title, scrollable content area, and built-in submit/cancel actions.\n *\n * @example\n * import { TanStackDialogForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackDialogForm\n * title=\"Create User\"\n * submitText=\"Create\"\n * className=\"max-w-lg\"\n * open={isOpen}\n * onOpenChange={setIsOpen}\n * >\n * <NameField />\n * <EmailField />\n * </TanStackDialogForm>\n */\nexport const TanStackDialogForm: React.FC<\n React.PropsWithChildren<{\n /** Heading text displayed in the dialog title bar. */\n title: string;\n /** Custom label for the submit button. Defaults to the `SubmitButton` component's built-in label when omitted. */\n submitText?: string;\n /** Optional fixed width for the dialog content area, as a pixel number (e.g. `600`) or any CSS string (e.g. `'50%'`, `'40rem'`). Omit to let the dialog size itself based on content. */\n width?: number | string;\n /** Optional fixed max-width for the dialog content area, as a pixel number (e.g. `600`) or any CSS string (e.g. `'50%'`, `'40rem'`). Omit to let the dialog size itself based on content and viewport. */\n maxWidth?: number | string;\n /** Optional additional class name(s) to apply to the dialog content container. */\n className?: string;\n /** Controlled open state of the dialog. */\n open?: boolean;\n /** Callback fired when the dialog open state changes; the form is reset on close. */\n onOpenChange?: (open: boolean) => void;\n }>\n> = ({ title, submitText, width, maxWidth, className, open, onOpenChange, children }) => {\n const form = useTanStackFormContext();\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n if (!open) form.reset();\n onOpenChange?.(open);\n },\n [form.reset, onOpenChange]\n );\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogContent\n style={\n {\n '--width': width,\n '--max-width': maxWidth,\n } as React.CSSProperties\n }\n className={cn(\n 'flex size-full max-h-dvh max-w-dvw flex-col gap-0 overflow-y-auto rounded-none p-0 shadow-dialog sm:h-auto sm:max-h-[85dvh] sm:max-w-5xl sm:rounded-md',\n width && `sm:w-(--width)`,\n maxWidth && `sm:max-w-(--max-width)`,\n className\n )}\n onOpenAutoFocus={event => {\n // Prevents focus from shifting to the content when the dialog opens, which can cause layout shift if the content includes autofocusable elements.\n event.preventDefault();\n }}\n >\n <div data-slot=\"dialog-header\" className=\"flex items-center justify-center gap-2 px-6 py-5 text-center sm:text-left\">\n <DialogTitle data-slot=\"dialog-title\" className=\"font-semibold text-lg tracking-tight\">\n {title}\n </DialogTitle>\n </div>\n <Separator />\n <div data-slot=\"dialog-content\" className=\"relative flex flex-col overflow-y-auto p-0 pt-4 max-sm:flex-1 sm:p-4\">\n {children}\n </div>\n <Separator />\n <div data-slot=\"dialog-footer\" className=\"flex flex-col-reverse items-center justify-end gap-2 px-6 py-4 sm:flex-row max-sm:[&>button]:w-full\">\n <form.Subscribe\n selector={state => ({ disabled: state.isSubmitting })}\n children={({ disabled }) => (\n <CancelButton\n disabled={disabled}\n onClick={() => {\n form.reset();\n handleOpenChange(false);\n }}\n />\n )}\n />\n <form.Subscribe\n selector={state => ({\n isSubmitting: state.isSubmitting,\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit,\n })}\n children={({ isSubmitting, disabled }) => (\n <SubmitButton isSubmitting={isSubmitting} disabled={disabled} submitText={submitText} onClick={() => form.handleSubmit()} />\n )}\n />\n </div>\n </DialogContent>\n </DialogPortal>\n </Dialog>\n );\n};\n","import {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n} from '@/components/features/tanstack-form/components/ui/field';\n\n/**\n * Renders a labeled field group with an optional description, helper text, and a bottom separator.\n *\n * @example\n * import { TanStackFieldGroup } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackFieldGroup\n * label=\"Contact Details\"\n * description=\"Enter your contact information.\"\n * helperText=\"All fields are required.\"\n * orientation=\"horizontal\"\n * >\n * <EmailField />\n * </TanStackFieldGroup>\n */\nexport const TanStackFieldGroup: React.FC<\n React.PropsWithChildren<{\n /** Primary label displayed above the field content. */\n label: string;\n /** Secondary descriptive text shown beneath the label. */\n description?: string;\n /** Supplementary helper note rendered below the field content. */\n helperText?: string;\n /** Layout orientation of the label-to-content axis. Defaults to `'responsive'`. */\n orientation?: 'horizontal' | 'vertical' | 'responsive';\n }>\n> = ({\n label,\n description,\n helperText,\n\n orientation = 'responsive',\n children,\n}) => {\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation}>\n <FieldContent>\n <FieldLabel>{label}</FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldContentMain>\n {children}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { CloseButton } from '@/components/ui/buttons/close';\n\nimport { Dialog as DialogPrimitive } from 'radix-ui';\nimport { useTanStackFormContext } from '../../tanstack-form';\nimport { CancelButton } from '../ui/cancel-button';\nimport { SubmitButton } from '../ui/submit-button';\n\n/**\n * Renders a slide-in side-panel dialog that wraps a TanStack form with built-in submit and cancel actions.\n *\n * @example\n * import { TanStackPopoverForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackPopoverForm\n * title=\"Edit Profile\"\n * open={isOpen}\n * onOpenChange={setIsOpen}\n * >\n * <EmailField />\n * </TanStackPopoverForm>\n */\nexport const TanStackPopoverForm: React.FC<\n React.PropsWithChildren<{\n /** Heading text displayed in the panel header. */\n title: string;\n /** Controlled open state of the popover dialog. */\n open?: boolean;\n /** Additional CSS class names applied to the scrollable content area. */\n contentClassName?: string;\n /** Callback fired when the open state changes. */\n onOpenChange?: (open: boolean) => void;\n }>\n> = ({ title, open, contentClassName, onOpenChange, children }) => {\n const form = useTanStackFormContext();\n\n return (\n <DialogPrimitive.Root data-slot=\"dialog\" open={open} onOpenChange={onOpenChange}>\n <DialogPrimitive.Portal data-slot=\"dialog-portal\">\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n 'fixed inset-0 z-40 bg-black/40 backdrop-blur-sm',\n 'data-[state=open]:animate-in data-[state=open]:fade-in',\n 'data-[state=closed]:animate-out data-[state=closed]:fade-out'\n )}\n />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n 'fixed top-4 right-4 z-50 h-[calc(100dvh-2rem)] min-w-sm max-w-xl rounded-md bg-background shadow-lg ring-1 ring-border',\n 'duration-300',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-right data-[state=open]:fade-in',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-right data-[state=closed]:fade-out'\n )}\n >\n <section className=\"relative flex size-full flex-col\">\n <header className=\"flex h-14 shrink-0 items-center border-b border-border px-5\">\n <h2 className=\"font-semibold text-base tracking-tight text-text-positive\">{title}</h2>\n </header>\n\n <div className={cn('flex flex-1 flex-col overflow-y-auto py-4', contentClassName)}>{children}</div>\n\n <div className=\"flex shrink-0 flex-col gap-2 border-t border-border px-4 py-3\">\n <form.Subscribe\n selector={state => ({\n isSubmitting: state.isSubmitting,\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit,\n })}\n children={({ isSubmitting, disabled }) => (\n <SubmitButton isSubmitting={isSubmitting} disabled={disabled} className=\"w-full\" onClick={() => form.handleSubmit()} />\n )}\n />\n <form.Subscribe\n selector={state => ({ disabled: state.isPristine || state.isSubmitting })}\n children={({ disabled }) => (\n <CancelButton\n disabled={disabled}\n className=\"w-full\"\n onClick={() => {\n form.reset();\n onOpenChange?.(false);\n }}\n />\n )}\n />\n </div>\n\n <DialogPrimitive.Close asChild>\n <CloseButton className=\"absolute top-2.5 right-3\" />\n </DialogPrimitive.Close>\n </section>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n};\n","'use client';\n\nimport { Separator } from '../ui/separator';\n\n/**\n * Internal header sub-component for `TanStackSectionForm` that renders a styled section title.\n */\nconst SectionHeader: React.FC<React.PropsWithChildren> = ({ children }) => {\n return (\n <header data-slot=\"section-header\" className=\"flex items-center px-4 py-3 font-semibold text-base text-text-positive tracking-tight\">\n {children}\n </header>\n );\n};\n\n/**\n * Internal body sub-component for `TanStackSectionForm` that wraps field content with vertical padding.\n */\nconst SectionMain: React.FC<React.PropsWithChildren> = ({ children }) => {\n return (\n <main data-slot=\"section-main\" className=\"relative flex flex-col py-4\">\n {children}\n </main>\n );\n};\n\n/**\n * Renders a card-like form section with a titled header, separator, and a content area for form fields.\n *\n * @example\n * import { TanStackSectionForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackSectionForm title=\"Account Settings\">\n * <EmailField />\n * <PasswordField />\n * </TanStackSectionForm>\n */\nexport const TanStackSectionForm: React.FC<\n React.PropsWithChildren<{\n /** Heading text displayed in the section header bar. */\n title: string;\n }>\n> = ({ title, children }) => {\n return (\n <section data-slot=\"section-form\" className=\"flex flex-col rounded-md bg-background shadow-card ring-1 ring-border\">\n <SectionHeader>{title}</SectionHeader>\n <Separator />\n <SectionMain>{children}</SectionMain>\n </section>\n );\n};\n","import { Field, FieldContent, FieldDescription, FieldGroup, FieldLegend, FieldNote, FieldSeparator } from '../ui/field';\n\n/**\n * Renders a standalone section title with an optional description and helper note, followed by a separator.\n *\n * @example\n * import { TanStackTitleField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackTitleField\n * title=\"Billing Address\"\n * description=\"Provide the address associated with your payment method.\"\n * helperText=\"Must match your bank records.\"\n * />\n */\nexport const TanStackTitleField: React.FC<{\n /** The heading text rendered as a legend element. */\n title: string;\n /** Optional supplementary text displayed beneath the title. */\n description?: string;\n /** Optional helper note shown below the description area. */\n helperText?: string;\n}> = ({ title, description, helperText }) => {\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field className=\"gap-0\">\n <FieldContent>\n <FieldLegend className=\"mb-1\">{title}</FieldLegend>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","import { createFormHook, createFormHookContexts } from '@tanstack/react-form';\n\nimport { ArrayCol, ArrayHeaderRow, SimpleArrayField } from './components/atoms/simple-array-field';\nimport { SimpleBooleanField } from './components/atoms/simple-boolean-field';\nimport { SimpleComboboxField } from './components/atoms/simple-combobox-field';\nimport { SimpleDateField } from './components/atoms/simple-date-field';\nimport { SimpleRadioGroupField } from './components/atoms/simple-radio-group-field';\nimport { SimpleEmailField } from './components/atoms/simple-email-field';\nimport { SimpleNumberField } from './components/atoms/simple-number-field';\nimport { SimplePasswordField } from './components/atoms/simple-password-field';\nimport { SimpleSelectField } from './components/atoms/simple-select-field';\nimport { SimpleTextareaField } from './components/atoms/simple-textarea-field';\nimport { SimpleTextField } from './components/atoms/simple-text-field';\nimport { CheckboxField } from './components/fields/checkbox-field';\nimport { ComboboxField } from './components/fields/combobox-field';\nimport { DateField } from './components/fields/date-field';\nimport { EmailField } from './components/fields/email-field';\nimport { NumberField } from './components/fields/number-field';\nimport { PasswordField } from './components/fields/password-field';\nimport { RadioGroupField } from './components/fields/radio-group-field';\nimport { SelectField } from './components/fields/select-field';\nimport { SwitchField } from './components/fields/switch-field';\nimport { TextField } from './components/fields/text-field';\nimport { TextareaField } from './components/fields/textarea-field';\nimport { TextEditorField } from './components/fields/text-editor-field';\nimport { TanStackActionSubmit } from './components/forms/action-submit';\nimport { TanStackActionsForm } from './components/forms/actions-form';\nimport { TanStackCardForm } from './components/forms/card-form';\nimport { TanStackContainerForm } from './components/forms/container-form';\nimport { TanStackDialogForm } from './components/forms/dialog-form';\nimport { TanStackFieldGroup } from './components/forms/group-field';\nimport { TanStackPopoverForm } from './components/forms/popover-form';\nimport { TanStackSectionForm } from './components/forms/section-form';\nimport { TanStackTitleField } from './components/forms/title-field';\nimport { Field, FieldContent, FieldContentMain, FieldError, FieldGroup, FieldLabel, FieldSeparator } from './components/ui/field';\n\nconst { fieldContext, formContext, useFieldContext: useTanStackFieldContext, useFormContext: useTanStackFormContext } = createFormHookContexts();\n\n/**\n * Factory result from {@link createFormHook} pre-wired with all Lunas UI field and form components.\n *\n * ### `useTanStackForm`\n * Pre-configured TanStack Form hook that returns a type-safe form instance bound to all Lunas UI\n * field and form components.\n *\n * @example\n * import { useTanStackForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * const form = useTanStackForm({\n * defaultValues: { name: '', email: '' },\n * onSubmit: async ({ value }) => console.log(value),\n * });\n *\n * return (\n * <form.Provider>\n * <form.AppForm>\n * <form.AppField name=\"name\" children={(field) => <field.TextField label=\"Name\" />} />\n * <form.Subscribe selector={(s) => s.canSubmit}>\n * {(canSubmit) => <form.TanStackActionSubmit disabled={!canSubmit} />}\n * </form.Subscribe>\n * </form.AppForm>\n * </form.Provider>\n * );\n *\n * ### `withTanStackForm`\n * Higher-order component that wraps a sub-form component with access to the parent\n * `useTanStackForm` form context, enabling isolated field groups that still participate in the\n * top-level form state.\n *\n * @example\n * import { withTanStackForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * const AddressFields = withTanStackForm(\n * { street: '', city: '' } as const,\n * ({ form }) => (\n * <>\n * <form.AppField name=\"street\" children={(f) => <f.TextField label=\"Street\" />} />\n * <form.AppField name=\"city\" children={(f) => <f.TextField label=\"City\" />} />\n * </>\n * ),\n * );\n *\n * ### `withTanStackFieldGroup`\n * Higher-order component that creates a reusable field-group component sharing the enclosing\n * `useTanStackForm` context without requiring additional form providers.\n *\n * @example\n * import { withTanStackFieldGroup } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * const ContactGroup = withTanStackFieldGroup(({ form }) => (\n * <form.AppField name=\"phone\" children={(f) => <f.TextField label=\"Phone\" />} />\n * ));\n */\nconst {\n useAppForm: useTanStackForm,\n withForm: withTanStackForm,\n withFieldGroup: withTanStackFieldGroup,\n} = createFormHook({\n fieldContext,\n formContext,\n\n fieldComponents: {\n TextField,\n TextareaField,\n TextEditorField,\n NumberField,\n EmailField,\n PasswordField,\n\n SelectField,\n ComboboxField,\n DateField,\n SwitchField,\n RadioGroupField,\n CheckboxField,\n\n SimpleTextField,\n SimpleEmailField,\n SimplePasswordField,\n SimpleTextareaField,\n SimpleNumberField,\n SimpleSelectField,\n SimpleArrayField,\n SimpleBooleanField,\n SimpleComboboxField,\n SimpleDateField,\n SimpleRadioGroupField,\n\n FieldGroup,\n Field,\n FieldContent,\n FieldLabel,\n FieldContentMain,\n FieldSeparator,\n FieldError,\n },\n formComponents: {\n TanStackDialogForm,\n TanStackPopoverForm,\n TanStackContainerForm,\n TanStackSectionForm,\n TanStackCardForm,\n TanStackFieldGroup,\n TanStackTitleField,\n\n TanStackActionsForm,\n TanStackActionSubmit,\n\n ArrayCol,\n ArrayHeaderRow,\n },\n});\n\nexport {\n // Hooks & HOCs\n useTanStackForm,\n withTanStackForm,\n withTanStackFieldGroup,\n useTanStackFieldContext,\n useTanStackFormContext,\n // Form containers\n TanStackDialogForm,\n TanStackPopoverForm,\n TanStackContainerForm,\n TanStackSectionForm,\n TanStackCardForm,\n TanStackFieldGroup,\n TanStackTitleField,\n // Form actions\n TanStackActionsForm,\n TanStackActionSubmit,\n type SubmitButton,\n type CancelButton,\n // Array helpers\n ArrayCol,\n ArrayHeaderRow,\n // Rich field components\n TextField,\n TextareaField,\n TextEditorField,\n NumberField,\n EmailField,\n PasswordField,\n SelectField,\n ComboboxField,\n DateField,\n SwitchField,\n RadioGroupField,\n CheckboxField,\n // Simple (minimal) field components\n SimpleTextField,\n SimpleEmailField,\n SimplePasswordField,\n SimpleTextareaField,\n SimpleNumberField,\n SimpleSelectField,\n SimpleArrayField,\n SimpleBooleanField,\n SimpleComboboxField,\n SimpleDateField,\n SimpleRadioGroupField,\n // Field UI primitives\n type FieldSet,\n type FieldLegend,\n FieldGroup,\n Field,\n FieldContent,\n FieldContentMain,\n FieldLabel,\n type FieldTitle,\n type FieldDescription,\n type FieldNote,\n type FieldTooltip,\n FieldSeparator,\n FieldError,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tanstack-form-DTCgWGCA.mjs","names":["Label","LabelPrimitive","Label","Tooltip","Separator","Switch","Checkbox","Label","Label","Popover","Label","Popover","Label","RadioGroup","Label","Label","Label","Label","Select","Label","Label","Checkbox","Dialog","RadixDialog","Popover","Popover","RadioGroup","Dialog","RadixDialog","Select","Switch","SwitchPrimitive","Switch","Separator","SeparatorPrimitive","Separator","Dialog","Separator","DialogPrimitive","Separator"],"sources":["../packages/components/features/tanstack-form/components/atoms/simple-array-field.tsx","../packages/components/features/tanstack-form/components/ui/label.tsx","../packages/components/features/tanstack-form/components/ui/field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-boolean-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-combobox-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-date-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-radio-group-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-email-field.tsx","../packages/components/ui/inputs/number-input.tsx","../packages/components/features/tanstack-form/components/atoms/simple-number-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-password-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-select-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-textarea-field.tsx","../packages/components/features/tanstack-form/components/atoms/simple-text-field.tsx","../packages/components/features/tanstack-form/components/fields/checkbox-field.tsx","../packages/components/features/tanstack-form/components/fields/combobox-field.tsx","../packages/components/features/tanstack-form/components/fields/date-field.tsx","../packages/components/features/tanstack-form/components/fields/email-field.tsx","../packages/components/features/tanstack-form/components/fields/number-field.tsx","../packages/components/features/tanstack-form/components/fields/password-field.tsx","../packages/components/features/tanstack-form/components/fields/radio-group-field.tsx","../packages/components/features/tanstack-form/components/fields/select-field.tsx","../packages/components/features/tanstack-form/components/ui/switch.tsx","../packages/components/features/tanstack-form/components/fields/switch-field.tsx","../packages/components/features/tanstack-form/components/fields/text-field.tsx","../packages/components/features/tanstack-form/components/fields/textarea-field.tsx","../packages/components/features/tanstack-form/components/fields/text-editor-field.tsx","../packages/components/features/tanstack-form/components/forms/action-submit.tsx","../packages/components/features/tanstack-form/components/forms/actions-form.tsx","../packages/components/features/tanstack-form/components/ui/separator.tsx","../packages/components/features/tanstack-form/components/forms/card-form.tsx","../packages/components/features/tanstack-form/components/forms/container-form.tsx","../packages/components/features/tanstack-form/components/ui/cancel-button.tsx","../packages/components/features/tanstack-form/components/ui/submit-button.tsx","../packages/components/features/tanstack-form/components/forms/dialog-form.tsx","../packages/components/features/tanstack-form/components/forms/group-field.tsx","../packages/components/features/tanstack-form/components/forms/popover-form.tsx","../packages/components/features/tanstack-form/components/forms/section-form.tsx","../packages/components/features/tanstack-form/components/forms/title-field.tsx","../packages/components/features/tanstack-form/tanstack-form.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback } from 'react';\n\nimport { PlusIcon, Trash2Icon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\n\n// ─── ArrayCol ──────────────────────────────────────────────────────────────\n\ntype ArrayColProps = {\n /**\n * Fixed column width as a pixel number (e.g. `96`) or any CSS string\n * (e.g. `'8rem'`, `'20%'`). Omit to let the column expand and fill the\n * remaining row space (`flex: 1`).\n */\n width?: number | string;\n className?: string;\n children: React.ReactNode;\n};\n\n/**\n * Layout helper for columns inside a `SimpleArrayField` row. Controls width\n * without repeating `<div className=\"w-24\">` or `<div className=\"flex-1\">`.\n *\n * @example\n * <SimpleArrayField defaultRow={...}>\n * {i => (\n * <>\n * <ArrayCol> // flex-1 — takes remaining space\n * <AppField name={`items[${i}].name`}>...</AppField>\n * </ArrayCol>\n * <ArrayCol width={96}> // 96 px fixed\n * <AppField name={`items[${i}].qty`}>...</AppField>\n * </ArrayCol>\n * <ArrayCol width=\"8rem\"> // CSS string\n * <AppField name={`items[${i}].tax`}>...</AppField>\n * </ArrayCol>\n * </>\n * )}\n * </SimpleArrayField>\n */\nexport function ArrayCol({ width, className, children }: ArrayColProps) {\n const style: React.CSSProperties = width ? { width: typeof width === 'number' ? `${width}px` : width, flexShrink: 0 } : { flex: 1, minWidth: 0 };\n\n return (\n <div data-slot=\"array-col\" style={style} className={className}>\n {children}\n </div>\n );\n}\n\n// ─── ArrayHeaderRow ────────────────────────────────────────────────────────\n\ntype ArrayHeaderRowProps = {\n className?: string;\n children: React.ReactNode;\n};\n\n/**\n * Styled header row for a `SimpleArrayField` table. Place it directly above\n * `<SimpleArrayField>` and use `<ArrayCol>` children with text labels to align\n * headers with their columns. A spacer matching the delete-button width is\n * appended automatically.\n *\n * @example\n * <ArrayHeaderRow>\n * <ArrayCol>Name</ArrayCol>\n * <ArrayCol width={96}>Price</ArrayCol>\n * <ArrayCol width={80}>Qty</ArrayCol>\n * </ArrayHeaderRow>\n * <SimpleArrayField defaultRow={...}>\n * {i => (...)}\n * </SimpleArrayField>\n */\nexport function ArrayHeaderRow({ className, children }: ArrayHeaderRowProps) {\n return (\n <div data-slot=\"array-header-row\" className={cn('mb-1 flex items-center gap-2 px-1 text-xs font-medium text-text-positive-weak', className)}>\n {children}\n {/* spacer matching the delete icon button width */}\n <div className=\"min-w-8 w-8 shrink-0\" />\n </div>\n );\n}\n\n// ─── SimpleArrayField ──────────────────────────────────────────────────────\n\ntype Props<T> = {\n /**\n * Shape of a brand-new empty row appended when the user clicks \"Add row\".\n */\n defaultRow: T;\n /**\n * Render function called once per row. Receives the zero-based row `index`\n * so you can build field paths like `` `items[${index}].name` ``.\n */\n children: (index: number) => React.ReactNode;\n /** Label on the add button. Defaults to `'Add row'`. */\n addLabel?: string;\n className?: string;\n};\n\n/**\n * Array field wrapper that manages rows (add / remove) while letting you\n * freely compose any fields inside each row.\n *\n * @example\n * const { AppForm, AppField } = useTanStackForm({ defaultValues: { items: [] } });\n *\n * <AppForm>\n * <AppField name=\"items\">\n * {({ SimpleArrayField }) => (\n * <SimpleArrayField defaultRow={{ name: null, qty: null }}>\n * {(i) => (\n * <div className=\"flex gap-2\">\n * <AppField name={`items[${i}].name`}>\n * {({ SimpleTextField }) => <SimpleTextField label=\"Name\" />}\n * </AppField>\n * <AppField name={`items[${i}].qty`}>\n * {({ SimpleNumberField }) => <SimpleNumberField label=\"Qty\" />}\n * </AppField>\n * </div>\n * )}\n * </SimpleArrayField>\n * )}\n * </AppField>\n * </AppForm>\n */\nexport function SimpleArrayField<T>({ defaultRow, children, addLabel = 'Thêm hàng', className }: Props<T>) {\n const field = useTanStackFieldContext<T[]>();\n const rows = field.state.value ?? [];\n\n const addRow = useCallback(() => {\n field.pushValue({ ...defaultRow } as T);\n }, [field, defaultRow]);\n\n const removeRow = useCallback(\n (index: number) => {\n field.removeValue(index);\n },\n [field]\n );\n\n return (\n <div data-slot=\"simple-array-field\" className={cn('flex flex-col gap-2', className)}>\n {rows.map((_, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: index is the stable identity for form rows\n <div key={i} className=\"flex items-start gap-2\">\n {children(i)}\n <Button type=\"button\" size=\"icon\" variant=\"ghost\" color=\"danger\" className=\"min-w-8\" onClick={() => removeRow(i)}>\n <Trash2Icon size={14} />\n </Button>\n </div>\n ))}\n\n <div>\n <Button type=\"button\" variant=\"outline\" color=\"muted\" size=\"xs\" onClick={addRow}>\n <PlusIcon size={13} />\n {addLabel}\n </Button>\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Label as LabelPrimitive } from 'radix-ui';\n\n/**\n * Form field label that automatically renders a \"Required\" badge when the field is marked aria-required.\n *\n * @example\n * import { Label } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <Label htmlFor=\"email\">Email address</Label>\n */\nfunction Label({ className, children, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n 'text-text-positive',\n 'flex w-full items-center justify-between',\n 'select-none font-medium text-sm/6 leading-none',\n 'group-data-[disabled=true]:pointer-events-none',\n 'group-data-[disabled=true]:opacity-50',\n 'peer-disabled:cursor-not-allowed',\n 'peer-disabled:opacity-50',\n 'aria-required:*:data-[slot=required-indicator]:inline-block',\n className\n )}\n {...props}\n >\n <span className=\"flex items-center gap-1\">{children}</span>\n <span\n data-slot=\"required-indicator\"\n className=\"hidden shrink-0 rounded-lg bg-danger-strong px-1.5 py-1 font-semibold text-[11px] leading-none text-white\"\n >\n Bắt buộc\n </span>\n </LabelPrimitive.Root>\n );\n}\n\nexport { Label };\n","'use client';\n\nimport { memo, useMemo } from 'react';\n\nimport { HelpCircleIcon, InfoIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Separator } from '@/components/ui/separator';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Label } from './label';\n\nconst fieldVariants = cva('group/field flex w-full gap-2 data-[invalid=true]:text-danger *:data-[slot=field-content]:gap-0', {\n variants: {\n orientation: {\n vertical: ['flex-col *:w-full [&>.sr-only]:w-auto'],\n horizontal: [\n 'flex-row items-center gap-4',\n '*:data-[slot=field-content]:basis-1/2',\n '*:data-[slot=field-content-main]:flex-1',\n '*:data-[slot=field-label]:flex-auto',\n 'has-[>[data-slot=field-content]]:items-start',\n 'has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\n ],\n responsive: [\n 'flex-col *:w-full [&>.sr-only]:w-auto',\n '@md/field-group:flex-row',\n '@md/field-group:items-center',\n '@md/field-group:gap-4',\n '@md/field-group:*:w-auto',\n '@md/field-group:*:data-[slot=field-content]:basis-1/2',\n '@md/field-group:*:data-[slot=field-content-main]:basis-1/2',\n '@md/field-group:*:data-[slot=field-label]:flex-auto',\n '@md/field-group:has-[>[data-slot=field-content]]:items-start',\n '@md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\n ],\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n\n/**\n * Outermost `<fieldset>` wrapper that stacks multiple `Field` rows with consistent vertical spacing.\n *\n * @example\n * import { FieldSet } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldSet>\n * <Field><FieldLabel>Name</FieldLabel><FieldContent><input /></FieldContent></Field>\n * </FieldSet>\n */\nconst FieldSet = memo(({ className, ...props }: React.ComponentProps<'fieldset'>) => {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn('flex flex-col gap-6 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3', className)}\n {...props}\n />\n );\n});\nFieldSet.displayName = 'FieldSet';\n\n/**\n * Props for {@link FieldLegend}.\n */\ntype FieldLegendProps = React.ComponentProps<'legend'> & {\n /**\n * Visual weight of the legend text.\n * - `'legend'` — larger base-size text (section heading).\n * - `'label'` — smaller label-size text (matches field label weight).\n * @default 'legend'\n */\n variant?: 'legend' | 'label';\n};\n\n/**\n * `<legend>` element for a `<fieldset>`, styled as either a section heading or a compact label.\n *\n * @example\n * import { FieldSet, FieldLegend } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldSet>\n * <FieldLegend variant=\"legend\">Personal details</FieldLegend>\n * </FieldSet>\n */\nconst FieldLegend = memo(({ className, variant = 'legend', ...props }: FieldLegendProps) => {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn('mb-3 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base', className)}\n {...props}\n />\n );\n});\nFieldLegend.displayName = 'FieldLegend';\n\n/**\n * Container `<div>` that groups a set of `Field` rows with container-query support for responsive layouts.\n *\n * @example\n * import { FieldGroup } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldGroup>\n * <Field>…</Field>\n * <Field>…</Field>\n * </FieldGroup>\n */\nconst FieldGroup = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group @container/field-group',\n 'flex flex-col gap-7 pt-4',\n 'data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4',\n className\n )}\n {...props}\n />\n );\n});\nFieldGroup.displayName = 'FieldGroup';\n\n/**\n * Single form field row that arranges label, input, and meta elements with configurable orientation.\n *\n * @example\n * import { Field } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <Field orientation=\"horizontal\">\n * <FieldLabel htmlFor=\"username\">Username</FieldLabel>\n * <FieldContent><input id=\"username\" /></FieldContent>\n * </Field>\n */\nconst Field = memo(({ className, orientation = 'vertical', ...props }: React.ComponentProps<'div'> & VariantProps<typeof fieldVariants>) => {\n return <div data-slot=\"field\" data-orientation={orientation} className={cn(fieldVariants({ orientation }), className)} {...props} />;\n});\nField.displayName = 'Field';\n\n/**\n * Flex column wrapper that houses the primary input control together with description and error slots.\n *\n * @example\n * import { FieldContent } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldContent>\n * <input type=\"text\" />\n * <FieldDescription>Enter your full name.</FieldDescription>\n * </FieldContent>\n */\nconst FieldContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"field-content\" className={cn('group/field-content flex flex-col gap-1.5 leading-snug', className)} {...props} />;\n});\nFieldContent.displayName = 'FieldContent';\n\n/**\n * Positioned wrapper for the main input element that enables absolutely-placed adornments (icons, spinners).\n *\n * @example\n * import { FieldContentMain } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldContentMain>\n * <input type=\"text\" className=\"pr-8\" />\n * <SearchIcon className=\"absolute right-2 top-2\" />\n * </FieldContentMain>\n */\nconst FieldContentMain = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"field-content-main\" className={cn('relative', className)} {...props} />;\n});\nFieldContentMain.displayName = 'FieldContentMain';\n\n/**\n * Styled `<label>` element for a `Field`, extending the base `Label` with field-group-aware spacing and border states.\n *\n * @example\n * import { FieldLabel } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldLabel htmlFor=\"email\" aria-required>Email</FieldLabel>\n */\nconst FieldLabel = memo(({ className, ...props }: React.ComponentProps<typeof Label>) => {\n return (\n <Label\n data-slot=\"field-label\"\n className={cn(\n 'group/field-label peer/field-label min-h-6 gap-1 font-medium leading-snug',\n 'has-[>[data-slot=field]]:w-full',\n 'has-[>[data-slot=field]]:flex-col',\n 'has-[>[data-slot=field]]:rounded-md',\n 'has-[>[data-slot=field]]:border',\n 'has-[>[data-slot=field]]:border-border',\n 'has-data-[state=checked]:border-primary',\n '*:data-[slot=field]:p-4 group-data-[disabled=true]/field:opacity-50',\n className\n )}\n {...props}\n />\n );\n});\nFieldLabel.displayName = 'FieldLabel';\n\n/**\n * Inline title element (non-`<label>`) for fields whose label cannot be a native `<label>`, such as custom checkbox groups.\n *\n * @example\n * import { FieldTitle } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldTitle>Notification preferences</FieldTitle>\n */\nconst FieldTitle = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return (\n <div\n data-slot=\"field-label\"\n className={cn('flex w-fit items-center gap-2 font-medium text-sm leading-snug group-data-[disabled=true]/field:opacity-50', className)}\n {...props}\n />\n );\n});\nFieldTitle.displayName = 'FieldTitle';\n\n/**\n * Supplementary hint text rendered below the input to guide the user, with support for inline anchor links.\n *\n * @example\n * import { FieldDescription } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldDescription>Must be at least 8 characters.</FieldDescription>\n */\nconst FieldDescription = memo(({ className, ...props }: React.ComponentProps<'p'>) => {\n return (\n <p\n data-slot=\"field-description\"\n className={cn(\n // biome-ignore lint/security/noSecrets: true\n 'nth-last-2:-mt-1 font-normal text-text-positive-weak text-xs leading-normal last:mt-0 [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4 [[data-variant=legend]+&]:-mt-1.5',\n className\n )}\n {...props}\n />\n );\n});\nFieldDescription.displayName = 'FieldDescription';\n\n/**\n * Props for {@link FieldNote}.\n */\ntype FieldNoteProps = React.ComponentProps<'div'> & {\n /**\n * When `false` the note is not rendered at all; useful for conditional display without wrapper conditionals.\n * @default true\n */\n isShow?: boolean;\n};\n\n/**\n * Highlighted informational callout box with an info icon, shown below a field to surface contextual guidance.\n *\n * @example\n * import { FieldNote } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldNote isShow={isDraftMode}>Changes are saved automatically in draft mode.</FieldNote>\n */\nconst FieldNote = memo(({ isShow = true, className, children, ...props }: FieldNoteProps) => {\n if (isShow === false) return null;\n return (\n <div\n data-slot=\"field-note\"\n className={cn(\n 'flex items-start gap-1.5 rounded border border-primary-muted/60 bg-primary-bg-subtle/80 px-2.5 py-2 text-text-positive-weak text-xs',\n className\n )}\n {...props}\n >\n <InfoIcon size={12} className=\"mt-0.5 shrink-0 text-primary/70\" />\n <span>{children}</span>\n </div>\n );\n});\nFieldNote.displayName = 'FieldNote';\n\n/**\n * Props for {@link FieldTooltip}.\n */\ntype FieldTooltipProps = {\n /** Text content displayed inside the tooltip when the help icon is hovered or focused. */\n tooltip: string;\n};\n\n/**\n * Small help-circle icon button that reveals a tooltip with additional field context on hover or focus.\n *\n * @example\n * import { FieldTooltip } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldLabel>\n * Password <FieldTooltip tooltip=\"Use at least one uppercase letter and one number.\" />\n * </FieldLabel>\n */\nconst FieldTooltip = memo(({ tooltip }: FieldTooltipProps) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n tabIndex={-1}\n className=\"inline-flex cursor-default items-center text-text-positive-weak/70 hover:text-text-positive focus:outline-none\"\n >\n <HelpCircleIcon size={13} aria-hidden=\"true\" />\n <span className=\"sr-only\">Thêm thông tin</span>\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-xs text-balance\">\n {tooltip}\n </TooltipContent>\n </Tooltip>\n );\n});\nFieldTooltip.displayName = 'FieldTooltip';\n\n/**\n * Visual divider row that optionally displays a centered text label, used to separate logical sections within a `FieldGroup`.\n *\n * @example\n * import { FieldSeparator } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <FieldSeparator>or</FieldSeparator>\n */\nconst FieldSeparator = memo(({ children, className, ...props }: React.PropsWithChildren<React.ComponentProps<'div'>>) => {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span className=\"relative mx-auto block w-fit bg-background px-2 text-text-positive-weak\" data-slot=\"field-separator-content\">\n {children}\n </span>\n )}\n </div>\n );\n});\nFieldSeparator.displayName = 'FieldSeparator';\n\n/**\n * Props for {@link FieldError}.\n */\ntype FieldErrorProps = React.ComponentProps<'div'> & {\n errors?: Array<{ code?: string; message?: string } | undefined>;\n requiredMessage?: string;\n};\n\nconst FieldError = memo(({ className, children, errors, requiredMessage = 'Trường này là bắt buộc', ...props }: FieldErrorProps) => {\n const content = useMemo(() => {\n const resolve = (error: { code?: string; message?: string }) => (error.code === 'invalid_type' ? requiredMessage : error.message);\n\n if (children) {\n return children;\n }\n\n if (!errors) {\n return null;\n }\n\n if (errors?.length === 1 && errors[0]?.message) {\n return (\n <div className=\"flex flex-row items-center justify-start gap-x-0.5\">\n <p>{resolve(errors[0])}</p>\n </div>\n );\n }\n\n return (\n <ul className=\"flex list-none flex-col\">\n {errors.map(error => {\n if (typeof error === 'string') return <li key={error}>{error}</li>;\n if (!error?.message) return null;\n return <li key={error.code ?? error.message}>{resolve(error)}</li>;\n })}\n </ul>\n );\n }, [children, errors, requiredMessage]);\n\n if (!content) {\n return null;\n }\n\n return (\n <div role=\"alert\" data-slot=\"field-error\" className={cn('w-full font-medium text-danger-strong text-xs', className)} {...props}>\n {content}\n </div>\n );\n});\nFieldError.displayName = 'FieldError';\n\nexport {\n Field,\n FieldLabel,\n FieldDescription,\n FieldNote,\n FieldError,\n FieldGroup,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldContent,\n FieldContentMain,\n FieldTitle,\n FieldTooltip,\n};\n","'use client';\n\nimport { useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { Checkbox } from '@/components/ui/checkbox';\nimport { Label } from '@/components/ui/label';\nimport { Switch } from '@/components/ui/switch';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n required?: boolean;\n disabled?: boolean;\n variant?: 'checkbox' | 'switch';\n};\n\nexport const SimpleBooleanField: React.FC<Props> = ({ label, required, disabled, variant = 'checkbox' }) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<boolean | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n const checked = state.value ?? false;\n const isDisabled = disabled || isSubmitting;\n\n const onCheckedChange = useCallback(\n (value: boolean) => {\n if (isSubmitting) return;\n handleChange(value);\n },\n [isSubmitting, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-center gap-2 h-9\">\n {variant === 'switch' ? (\n <Switch id={id} name={name} checked={checked} disabled={isDisabled} aria-invalid={_invalid} onBlur={handleBlur} onCheckedChange={onCheckedChange} />\n ) : (\n <Checkbox id={id} name={name} checked={checked} disabled={isDisabled} aria-invalid={_invalid} onBlur={handleBlur} onCheckedChange={onCheckedChange} />\n )}\n {label && (\n <Label htmlFor={id} className=\"cursor-pointer\">\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n </div>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer';\nimport { Label } from '@/components/ui/label';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n disabled?: boolean;\n options: Array<{ value: string; label: string }>;\n};\n\nexport const SimpleComboboxField: React.FC<Props> = ({ label, placeholder, required, disabled, options }) => {\n const id = useId();\n const { form, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n const isMobile = useIsMobile();\n const [drawerOpen, setDrawerOpen] = useState(false);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n const isDisabled = disabled || isSubmitting;\n\n const selectedLabel = options.find(({ value }) => value === state.value)?.label;\n\n const commandList = (\n <Command>\n <CommandInput placeholder={placeholder ?? 'Tìm kiếm…'} />\n <CommandList>\n <CommandEmpty>Không tìm thấy kết quả.</CommandEmpty>\n <CommandGroup>\n {options.map(option => (\n <CommandItem\n key={option.value}\n value={option.label}\n onSelect={() => {\n handleChange(option.value === state.value ? null : option.value);\n setDrawerOpen(false);\n }}\n >\n {option.label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n if (isMobile) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Button\n id={id}\n type=\"button\"\n variant=\"outline\"\n color=\"muted\"\n disabled={isDisabled}\n aria-invalid={_invalid}\n className={cn(\n 'w-full justify-start font-normal outline-1 outline-border -outline-offset-1',\n !state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle'\n )}\n onBlur={handleBlur}\n onClick={() => setDrawerOpen(true)}\n >\n {selectedLabel ?? <span className=\"text-text-positive-muted\">{placeholder}</span>}\n </Button>\n\n <Drawer open={drawerOpen} onOpenChange={setDrawerOpen} direction=\"bottom\">\n <DrawerContent>\n <DrawerHeader>\n <DrawerTitle>{label ?? placeholder ?? 'Tìm kiếm…'}</DrawerTitle>\n </DrawerHeader>\n <div className=\"overflow-y-auto pb-safe-bottom\">{commandList}</div>\n </DrawerContent>\n </Drawer>\n\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Popover>\n <PopoverTrigger asChild>\n <Button\n id={id}\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid}\n className={cn(\n 'flex w-full items-center justify-start rounded outline-border font-normal',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n !state.value && 'text-text-positive-muted'\n )}\n >\n {selectedLabel ?? <span className=\"text-text-positive-muted\">{placeholder}</span>}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" side=\"bottom\" className=\"w-[--radix-popover-trigger-width] p-0 rounded\" onBlur={handleBlur}>\n {commandList}\n </PopoverContent>\n </Popover>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\nimport { CalendarDaysIcon } from 'lucide-react';\n\nimport { format } from '@customafk/react-toolkit/date-fns';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Calendar } from '@/components/ui/calendar';\nimport { Label } from '@/components/ui/label';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n disabled?: boolean;\n minDate?: Date;\n maxDate?: Date;\n};\n\nexport const SimpleDateField: React.FC<Props> = ({ label, placeholder, required, disabled, minDate, maxDate }) => {\n const id = useId();\n const { form, state, handleBlur, handleChange } = useTanStackFieldContext<Date | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n const isDisabled = disabled || isSubmitting;\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Popover>\n <PopoverTrigger asChild>\n <Button\n id={id}\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid}\n className={cn(\n 'flex w-full items-center justify-between rounded outline-border font-normal',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n state.value === null && 'text-text-positive-muted'\n )}\n >\n <span>{state.value ? format(state.value, 'PPP') : (placeholder ?? 'Select date')}</span>\n <CalendarDaysIcon strokeWidth={1} />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" side=\"bottom\" className=\"w-fit p-0 rounded\" onBlur={handleBlur}>\n <Calendar\n mode=\"single\"\n selected={state.value ?? undefined}\n hidden={{\n before: minDate ?? new Date(1900, 0, 1),\n after: maxDate ?? new Date(2100, 11, 31),\n }}\n onSelect={date => {\n if (!date) return;\n handleChange(date);\n }}\n />\n </PopoverContent>\n </Popover>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { Label } from '@/components/ui/label';\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n required?: boolean;\n disabled?: boolean;\n options: Array<{ value: string; label: string }>;\n orientation?: 'horizontal' | 'vertical';\n};\n\nexport const SimpleRadioGroupField: React.FC<Props> = ({ label, required, disabled, options, orientation = 'vertical' }) => {\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n const isDisabled = disabled || isSubmitting;\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <RadioGroup\n name={name}\n value={state.value ?? ''}\n disabled={isDisabled}\n aria-invalid={_invalid}\n className={orientation === 'horizontal' ? 'flex flex-row flex-wrap gap-x-4 gap-y-2' : 'flex flex-col gap-2'}\n onValueChange={handleChange}\n onBlur={handleBlur}\n >\n {options.map(option => (\n <div key={option.value} className=\"flex items-center gap-2\">\n <RadioGroupItem id={`${name}-${option.value}`} value={option.value} />\n <Label htmlFor={`${name}-${option.value}`} className=\"cursor-pointer font-normal\">\n {option.label}\n </Label>\n </div>\n ))}\n </RadioGroup>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { AtSignIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n maxLength?: number;\n disabled?: boolean;\n};\n\nexport const SimpleEmailField: React.FC<Props> = ({ label, placeholder, required, maxLength, disabled }) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n if (maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isSubmitting, maxLength, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <div className=\"relative\">\n <Input\n id={id}\n name={name}\n type=\"email\"\n value={state.value ?? ''}\n aria-invalid={_invalid}\n autoComplete=\"email\"\n placeholder={placeholder}\n disabled={disabled || isSubmitting}\n className={cn('pl-9')}\n onBlur={handleBlur}\n onChange={onChange}\n />\n <div className=\"pointer-events-none absolute inset-y-0 left-0 flex size-9 items-center justify-center text-muted\">\n <AtSignIcon size={14} />\n </div>\n </div>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\n\nconst createValidationRegex = (allowNegative: boolean): RegExp => {\n return allowNegative ? /^-?\\d*\\.?\\d*$/ : /^\\d*\\.?\\d*$/;\n};\n\nconst formatNumberWithCommas = (num: number | string): string => {\n return Number(num).toLocaleString();\n};\n\nconst customRoundedValue = (value: number, precision: number, roundingRule: 'up' | 'down' | 'nearest' | 'none') => {\n if (roundingRule === 'none') return value;\n\n const factor = 10 ** precision;\n const scaledValue = value * factor;\n\n switch (roundingRule) {\n case 'up':\n return Math.ceil(scaledValue) / factor;\n case 'down':\n return Math.floor(scaledValue) / factor;\n case 'nearest': {\n if (scaledValue % 1 < 0.1) return Math.floor(scaledValue) / factor;\n if (scaledValue % 1 >= 0.59) return Math.ceil(scaledValue) / factor;\n return (Math.floor(scaledValue) + 0.5) / factor;\n }\n default: {\n return value;\n }\n }\n};\n\ntype TProps = React.HTMLAttributes<HTMLInputElement> & {\n /**\n * Description: Value for the text field\n *\n * Default: ''\n *\n * Usage: Value for the text field\n */\n value?: number | null | undefined;\n /**\n * Description: Disabled state of the text field\n *\n * Default: `false`\n *\n * Usage: Disabled state of the text field\n *\n * Note: If true, the text field will be disabled\n */\n disabled?: boolean;\n /**\n * Description: Readonly state of the text field\n *\n * Default: `false`\n *\n * Usage: Readonly state of the text field\n */\n readOnly?: boolean;\n /**\n * Description: Allow negative value for the text field\n *\n * Default: `false`\n *\n * Usage: Allow negative value for the text field\n */\n allowNegative?: boolean;\n /**\n * Description: Decimal point for the text field\n *\n * Default: `undefined`\n *\n * Usage: Ex: [12,3] => console.log(2323.23) // True\n *\n * Note: IF use this prop, `numberAfterDecimalPoint` will be ignored\n */\n decimal?: [number, number];\n /**\n * Description: Rounding rule for the text field\n *\n * Default: `nearest`\n *\n * Usage: Rounding rule for the text field\n * - 'up': Round up\n * - 'down': Round down\n * - 'nearest': Round to nearest\n * - 'none': No rounding\n *\n * E.g.\n * - Value: 2.135, precision: 2\n * - 'up' => 2.14\n * - 'down' => 2.13\n * - 'nearest' => 2.13\n * - 'none' => 2.135\n */\n roundingRule?: 'up' | 'down' | 'nearest' | 'none';\n /**\n * Description: Number of digits after the decimal point\n *\n * Default: `2`\n *\n * Usage: Number of digits after the decimal point\n */\n numberAfterDecimalPoint?: number;\n /**\n * Description: Placeholder for the text field\n *\n * Default: ''\n *\n * Usage: Placeholder for the text field\n */\n placeholder?: string;\n /**\n * Description: Unit text for the text field\n *\n * Default: ''\n *\n * E.g. 'kg', 'm', 'USD'...\n */\n unitText?: string;\n /**\n * Description: Invalid state of the text field\n *\n * Default: `false`\n *\n * Usage: Invalid state of the text field\n */\n invalid?: boolean;\n /**\n * Description: Precision for the text field\n *\n * Default: `undefined`\n * E.g.\n * - 2.13 => 2.1 when precision is 1\n * - 2.134 => 2.13 when precision is 2\n */\n precision?: number;\n /**\n * Description: Callback function for the value change\n * Usage: Callback function for the value change\n */\n wrapperClassName?: string;\n /**\n * Description: Callback function for the value change\n * Usage: Callback function for the value change\n */\n onValueChange?: (value: number | null) => void;\n /**\n * Description: Callback function for the blur event\n * Usage: Callback function for the blur event\n */\n onBlur?: () => void;\n};\n/**\n * ## Unit Text Field Component\n *\n * **Description**: This component is to display common text field with unit\n *\n * **Usage**: Text field with unit example: 1000 (kg), 100 (m), 1000 (USD)...\n */\nexport const NumberInput: React.FC<TProps> = ({\n disabled = false,\n readOnly = false,\n allowNegative = false,\n numberAfterDecimalPoint = 2,\n roundingRule = 'none',\n value = null,\n unitText,\n decimal,\n placeholder,\n precision,\n wrapperClassName,\n className,\n onChange,\n onValueChange,\n onFocus,\n onBlur,\n ...props\n}) => {\n const _unitRef = useRef<HTMLSpanElement>(null);\n const _inputRef = useRef<HTMLInputElement>(null);\n\n const [_value, _setValue] = useState<string | null>(value?.toString() ?? null);\n\n // Memoized values for validation and formatting\n const maxDecimalPlaces = useMemo(() => decimal?.[1] ?? numberAfterDecimalPoint, [decimal, numberAfterDecimalPoint]);\n const maxIntegerLength = useMemo(() => decimal && decimal[0] - decimal[1], [decimal]);\n const validationRegex = useMemo(() => createValidationRegex(allowNegative), [allowNegative]);\n\n // Validate decimal point is less than or equal to the limit\n const validateDecimalPoint = useCallback(\n (value: string) => {\n if (!maxDecimalPlaces || value === '-') return true;\n\n const [integerPart, decimalPart = ''] = value.split('.') as [string, string];\n const integerPartLength = integerPart.startsWith('-') ? integerPart.length - 1 : integerPart.length;\n const decimalPartLength = decimalPart.length;\n\n return decimalPartLength <= maxDecimalPlaces && integerPartLength <= (maxIntegerLength ?? Infinity);\n },\n [maxDecimalPlaces, maxIntegerLength]\n );\n const formattedValue = useCallback(\n (val: string) => {\n if (val === '0') return '0';\n if (!Number(val)) return null;\n\n const numValue = parseFloat(val);\n const effectivePrecision = Math.min(maxDecimalPlaces - 1, precision || 0);\n const roundedValue = customRoundedValue(numValue, effectivePrecision, roundingRule).toString();\n const [integerPart, decimalPart = ''] = roundedValue.split('.');\n const formattedInteger = formatNumberWithCommas(integerPart);\n return decimalPart ? `${formattedInteger}.${decimalPart}` : formattedInteger;\n },\n [maxDecimalPlaces, precision, roundingRule]\n );\n\n const handleZeroCase = useCallback(\n (value: string) => {\n // Check for zero\n const isZero = value === '0';\n // Check for negative zero patterns. E.g., '-0', '-0.0', '-0.000', '-0.'\n const isNegativeZero = value === '-' || /^-0+(\\.0+)?$/.test(value) || /^-0*\\.$/.test(value);\n if (isZero) {\n onValueChange?.(0);\n _setValue(value);\n return;\n }\n if (isNegativeZero) {\n _setValue(() => {\n onValueChange?.(0);\n return value;\n });\n return;\n }\n },\n [onValueChange]\n );\n const handleChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n e => {\n // Don't prevent default behavior of input change\n onChange?.(e);\n\n // Custom event handler for value change\n const { value: inputValue } = e.target;\n\n // Handle empty input\n if (inputValue === '' || inputValue === undefined) {\n onValueChange?.(null);\n _setValue(null);\n return;\n }\n\n // Handle zero and negative zero\n handleZeroCase(inputValue);\n\n // Validate input format\n if (!validationRegex.test(inputValue) || !validateDecimalPoint(inputValue)) return;\n\n const numericValue = parseFloat(inputValue) || 0;\n onValueChange?.(numericValue);\n _setValue(inputValue);\n },\n [validateDecimalPoint, onChange, onValueChange, handleZeroCase, validationRegex]\n );\n\n const handleFocus = useCallback<React.FocusEventHandler<HTMLInputElement>>(\n e => {\n if (readOnly) return;\n onFocus?.(e);\n _setValue(prev => (typeof prev === 'string' ? prev.replace(/,/g, '') : null)); // Remove commas for easier editing\n },\n [readOnly, onFocus]\n );\n\n const handleBlur = useCallback<React.FocusEventHandler<HTMLInputElement>>(\n e => {\n if (readOnly) return;\n onBlur?.(e);\n _setValue(prev => {\n if (prev === null) return null;\n const isZero = prev === '0' || prev === '-' || /^-0+(\\.0+)?$/.test(prev) || /^-0*\\.$/.test(prev);\n if (isZero) return '0';\n return typeof prev === 'string' ? formattedValue(prev) : null;\n });\n },\n [readOnly, formattedValue, onBlur]\n );\n\n // Set initial value\n useEffect(() => {\n const isFocused = document.activeElement === _inputRef.current;\n\n if (value === undefined || value === null || !validationRegex.test(value.toString()) || !validateDecimalPoint(value.toString())) {\n _setValue(null);\n return;\n }\n\n _setValue(prev => (isFocused ? prev : formattedValue(value.toString())));\n }, [formattedValue, value, validateDecimalPoint, validationRegex]);\n\n // Set padding right for the input field\n useEffect(() => {\n if (!_unitRef.current || !_inputRef.current || !unitText) return;\n const unitWidth = _unitRef.current.offsetWidth;\n _inputRef.current.style.setProperty('padding-right', `${(unitWidth + 10) / 16}rem`);\n }, [unitText]);\n\n return (\n <div className={cn('relative', wrapperClassName)}>\n <Input\n {...props}\n ref={_inputRef}\n value={_value || (readOnly ? '0' : '')}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n className={cn('text-end font-number text-sm slashed-zero lining-nums tabular-nums', readOnly && 'bg-muted text-muted-foreground', className)}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n />\n {unitText && (\n <span ref={_unitRef} className=\"-translate-y-1/2 pointer-events-none absolute top-1/2 right-2 text-muted-foreground text-sm\">\n {unitText}\n </span>\n )}\n </div>\n );\n};\n","'use client';\n\nimport { useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { Label } from '@/components/ui/label';\nimport { NumberInput } from '@/components/ui/inputs/number-input';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n unit?: string;\n allowNegative?: boolean;\n disabled?: boolean;\n};\n\nexport const SimpleNumberField: React.FC<Props> = ({ label, placeholder, required, unit, allowNegative, disabled }) => {\n const id = useId();\n const { form, state, handleBlur, handleChange } = useTanStackFieldContext<number | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n\n const onValueChange = useCallback(\n (value: number | null) => {\n if (isSubmitting) return;\n handleChange(value);\n },\n [isSubmitting, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <NumberInput\n id={id}\n value={state.value}\n placeholder={placeholder}\n unitText={unit}\n allowNegative={allowNegative}\n disabled={disabled || isSubmitting}\n onBlur={handleBlur}\n onValueChange={onValueChange}\n />\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useCallback, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { EyeIcon, EyeOffIcon } from 'lucide-react';\n\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n disabled?: boolean;\n};\n\nexport const SimplePasswordField: React.FC<Props> = ({ label, placeholder, required, disabled }) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const [isVisible, setIsVisible] = useState(false);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n\n const toggleVisibility = useCallback(() => setIsVisible(prev => !prev), []);\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n handleChange(value || null);\n },\n [isSubmitting, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <div className=\"relative\">\n <Input\n id={id}\n name={name}\n type={isVisible ? 'text' : 'password'}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n autoComplete=\"current-password\"\n placeholder={placeholder}\n disabled={disabled || isSubmitting}\n className=\"pr-9\"\n onBlur={handleBlur}\n onChange={onChange}\n />\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={isVisible ? 'Ẩn mật khẩu' : 'Hiện mật khẩu'}\n aria-pressed={isVisible}\n aria-controls={id}\n className=\"absolute inset-y-0 right-0 flex size-9 items-center justify-center text-muted outline-none transition-colors hover:text-text-positive focus-visible:text-text-positive disabled:pointer-events-none disabled:opacity-50\"\n disabled={disabled || isSubmitting}\n onClick={toggleVisibility}\n >\n {isVisible ? <EyeOffIcon size={16} aria-hidden=\"true\" /> : <EyeIcon size={16} aria-hidden=\"true\" />}\n </button>\n </div>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useId, useState } from 'react';\n\nimport { PackagePlusIcon } from 'lucide-react';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Drawer, DrawerClose, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer';\nimport { Label } from '@/components/ui/label';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n options: Array<{ value: string; label: string }>;\n};\n\nexport const SimpleSelectField: React.FC<Props> = ({ label, placeholder, required, options }) => {\n const id = useId();\n const { state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [drawerOpen, setDrawerOpen] = useState(false);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n const selectedLabel = options.find(o => o.value === state.value)?.label;\n\n if (isMobile) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Button\n id={id}\n type=\"button\"\n variant=\"outline\"\n color=\"muted\"\n className={cn(\n 'w-full justify-start font-normal outline-1 outline-border -outline-offset-1',\n !state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle'\n )}\n aria-invalid={_invalid}\n onBlur={handleBlur}\n onClick={() => setDrawerOpen(true)}\n >\n {selectedLabel ?? <span className=\"text-text-positive-muted\">{placeholder}</span>}\n </Button>\n\n <Drawer open={drawerOpen} onOpenChange={setDrawerOpen} direction=\"bottom\">\n <DrawerContent>\n <DrawerHeader>\n <DrawerTitle>{label ?? placeholder ?? 'Select an option'}</DrawerTitle>\n </DrawerHeader>\n <div className=\"flex flex-col overflow-y-auto pb-safe-bottom\">\n {options.length > 0 ? (\n options.map(option => (\n <DrawerClose key={option.value} asChild>\n <button\n type=\"button\"\n className={cn(\n 'flex w-full items-center px-4 py-3 text-left text-sm transition-colors',\n 'hover:bg-muted-muted active:bg-muted-muted',\n state.value === option.value && 'bg-primary-bg-subtle font-medium text-primary'\n )}\n onClick={() => {\n handleChange(option.value);\n setDrawerOpen(false);\n }}\n >\n {option.label}\n </button>\n </DrawerClose>\n ))\n ) : (\n <div className=\"flex items-center justify-center gap-x-2 px-4 py-8 text-center text-sm text-text-positive-weak\">\n <PackagePlusIcon strokeWidth={1} />\n No options available\n </div>\n )}\n </div>\n </DrawerContent>\n </Drawer>\n\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Select value={state.value ?? ''} onValueChange={handleChange}>\n <SelectTrigger id={id} aria-invalid={_invalid ? 'true' : undefined} onBlur={handleBlur}>\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent>\n {options.length > 0 ? (\n options.map(option => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))\n ) : (\n <div className=\"flex items-center justify-center gap-x-2 rounded border border-border bg-muted-muted px-4 py-6.5 text-center text-sm text-text-positive-weak\">\n <PackagePlusIcon strokeWidth={1} />\n No options available\n </div>\n )}\n </SelectContent>\n </Select>\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { Textarea } from '@/components/ui/textarea';\nimport { Label } from '@/components/ui/label';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\ntype Props = {\n label?: string;\n placeholder?: string;\n required?: boolean;\n maxLength?: number;\n rows?: number;\n disabled?: boolean;\n};\n\nexport const SimpleTextareaField: React.FC<Props> = ({ label, placeholder, required, maxLength, rows, disabled }) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLTextAreaElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n if (maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isSubmitting, maxLength, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Textarea\n id={id}\n name={name}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n placeholder={placeholder}\n rows={rows}\n disabled={disabled || isSubmitting}\n onBlur={handleBlur}\n onChange={onChange}\n />\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { FieldError } from '../ui/field';\n\nimport type { SimpleTextFieldProps as Props } from '../../types';\n\nexport const SimpleTextField: React.FC<Props> = ({ label, placeholder, required, maxLength, disabled }) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isTouched && !state.meta.isValid;\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n if (maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isSubmitting, maxLength, handleChange]\n );\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <Label htmlFor={id}>\n {label}\n {required && <span className=\"text-danger-strong\">*</span>}\n </Label>\n )}\n <Input\n id={id}\n name={name}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n placeholder={placeholder}\n autoComplete=\"off\"\n disabled={disabled || isSubmitting}\n onBlur={handleBlur}\n onChange={onChange}\n />\n {_invalid && <FieldError errors={state.meta.errors} />}\n </div>\n );\n};\n","'use client';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { Field, FieldContent, FieldContentMain, FieldDescription, FieldGroup, FieldLabel, FieldNote, FieldSeparator, FieldTooltip } from '../ui/field';\nimport { Checkbox } from '@/components/ui/checkbox';\n\nimport type { CheckboxFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected checkbox group field that manages an array of selected string values,\n * supporting multi-selection and submission-state disabling.\n *\n * @example\n * import { CheckboxField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"roles\">\n * {() => (\n * <CheckboxField\n * label=\"Roles\"\n * options={[\n * { value: 'admin', label: 'Admin' },\n * { value: 'editor', label: 'Editor' },\n * ]}\n * helperText=\"Select one or more roles\"\n * />\n * )}\n * </form.Field>\n */\nexport const CheckboxField: React.FC<Props> = ({ label, description, options, tooltip, helperText, orientation }) => {\n const field = useTanStackFieldContext<string[] | null>();\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation}>\n <FieldContent>\n <FieldLabel>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContent>\n <FieldContentMain>\n <FieldGroup className=\"flex flex-col gap-y-2\">\n {options.map(option => {\n return (\n <Field key={option.value} orientation=\"horizontal\">\n <Checkbox\n id={`${field.name}-${option.value}`}\n name={field.name}\n checked={field.state.value?.includes(option.value) ?? false}\n disabled={isSubmitting}\n onCheckedChange={checked => {\n if (checked && field.state.value !== null) {\n field.pushValue(option.value);\n } else if (checked && field.state.value === null) {\n field.setValue([option.value]);\n } else if (!checked && field.state.value !== null) {\n const index = field.state.value.indexOf(option.value);\n if (index > -1) field.removeValue(index);\n } else {\n field.setValue(null);\n }\n }}\n />\n <FieldLabel htmlFor={`${field.name}-${option.value}`} className=\"text-text-positive\">\n {option.label}\n </FieldLabel>\n </Field>\n );\n })}\n </FieldGroup>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { XIcon } from 'lucide-react';\n\nimport { Dialog as RadixDialog } from 'radix-ui';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Dialog, DialogClose, DialogOverlay, DialogPortal } from '@/components/ui/dialog';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { ComboboxFieldProps } from '../../types';\n\nexport const ComboboxField = memo<ComboboxFieldProps>(\n ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n options,\n required = false,\n disabled = false,\n clearable = false,\n showErrorMessage = true,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _showClear = clearable && !!field.state.value && !isDisabled;\n\n const selectedLabel = options.find(({ value }) => value === field.state.value)?.label;\n\n const onClear = () => {\n field.handleChange(null);\n field.handleBlur();\n };\n\n const triggerButton = (onClick?: () => void) => (\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex w-full items-center justify-start rounded outline-border',\n 'hover:bg-transparent',\n 'focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak',\n 'data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n _showClear && 'pr-8',\n !field.state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n onClick={onClick}\n >\n {selectedLabel ? (\n <p className=\"flex min-w-0 flex-1 items-center gap-2 truncate text-start\">{selectedLabel}</p>\n ) : (\n <p className=\"flex-1 text-start text-text-positive-muted\">{placeholder}</p>\n )}\n </Button>\n );\n\n const renderCommandList = (onSelect: (value: string) => void) => (\n <Command className=\"border-none\">\n <CommandInput placeholder={placeholder ?? 'Tìm kiếm…'} />\n <CommandList>\n <CommandEmpty className=\"flex min-h-30 items-center justify-center text-sm text-text-positive-weak\">Không tìm thấy kết quả nào phù hợp.</CommandEmpty>\n <CommandGroup className=\"max-h-60 overflow-y-auto\">\n {options.map(({ value, label: optLabel }) => (\n <CommandItem key={value} value={optLabel} onSelect={() => onSelect(value)}>\n {optLabel}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={field.name}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex justify-end\">\n <div className=\"flex w-full flex-col\">\n <div className=\"relative\">\n {isMobile ? (\n <>\n {triggerButton(() => setDialogOpen(true))}\n <Dialog\n open={dialogOpen}\n onOpenChange={open => {\n setDialogOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <DialogPortal>\n <DialogOverlay />\n <RadixDialog.Content\n onOpenAutoFocus={e => e.preventDefault()}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-50',\n 'flex flex-col bg-background rounded-t-2xl outline-none',\n 'max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0',\n 'duration-300'\n )}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border shrink-0\">\n <span className=\"font-semibold text-sm text-text-positive\">{label}</span>\n <DialogClose asChild>\n <button\n type=\"button\"\n aria-label=\"Đóng\"\n className=\"flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive\"\n >\n <XIcon size={16} />\n </button>\n </DialogClose>\n </div>\n\n <div className=\"flex flex-col overflow-y-auto\">\n {_showClear && (\n <DialogClose asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle\"\n onClick={onClear}\n >\n <XIcon size={14} />\n Xóa lựa chọn\n </button>\n </DialogClose>\n )}\n {renderCommandList(value => {\n field.handleChange(value);\n setDialogOpen(false);\n field.handleBlur();\n })}\n </div>\n\n <div className=\"shrink-0 h-safe-bottom\" />\n </RadixDialog.Content>\n </DialogPortal>\n </Dialog>\n </>\n ) : (\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>{triggerButton()}</PopoverTrigger>\n <PopoverContent align=\"end\" side=\"bottom\" className=\"flex w-fit rounded p-0\">\n {renderCommandList(value => {\n field.handleChange(value);\n setPopoverOpen(false);\n field.handleBlur();\n })}\n </PopoverContent>\n </Popover>\n )}\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa lựa chọn\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n </div>\n\n {_touched && showErrorMessage && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nComboboxField.displayName = 'ComboboxField';\n","'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { CalendarDaysIcon } from 'lucide-react';\n\nimport { endOfToday, endOfTomorrow, endOfYesterday, format, lastDayOfMonth, startOfMonth, subDays } from '@customafk/react-toolkit/date-fns';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Calendar } from '@/components/ui/calendar';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { DateFieldProps as Props } from '../../types';\n\nexport const DateField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n helperText,\n showErrorMessage = true,\n required = false,\n disabled = false,\n minDate,\n maxDate,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<Date | null>();\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _isInvalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n\n const handleSelect = (date: Date) => {\n field.handleChange(date);\n setPopoverOpen(false);\n };\n\n return (\n <FieldGroup className=\"px-4\">\n <Field orientation={orientation} data-invalid={_isInvalid}>\n <FieldContent>\n <FieldLabel htmlFor={field.name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex flex-col space-y-1\">\n <div className=\"flex w-full flex-col\">\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_isInvalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex items-center justify-between rounded font-normal outline-border',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n field.state.value === null && 'text-text-positive-muted',\n _isInvalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n >\n <p>{field.state.value === null ? (placeholder ?? 'Select date') : format(field.state.value, 'PPPP')}</p>\n <CalendarDaysIcon strokeWidth={1} />\n </Button>\n </PopoverTrigger>\n\n <PopoverContent align=\"start\" side=\"bottom\" className=\"flex w-fit min-w-0 overflow-y-auto rounded p-0\">\n <div className=\"flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm\">\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfToday())}>\n Hôm nay\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfTomorrow())}>\n Ngày mai\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfYesterday())}>\n Hôm qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 3))}>\n 3 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 7))}>\n 7 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 30))}>\n 30 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(startOfMonth(endOfToday()))}>\n Tháng này\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(lastDayOfMonth(endOfToday()))}>\n Tháng trước\n </Button>\n </div>\n <div className=\"flex flex-1 flex-col\">\n <div className=\"min-w-73 border-b border-b-border p-2\">\n <Calendar\n mode=\"single\"\n selected={field.state.value ?? undefined}\n hidden={{\n before: minDate ?? new Date(1900, 0, 1),\n after: maxDate ?? new Date(2100, 11, 31),\n }}\n onSelect={date => {\n if (!date) return;\n handleSelect(date);\n }}\n />\n </div>\n </div>\n </PopoverContent>\n </Popover>\n\n {_touched && showErrorMessage && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nDateField.displayName = 'DateField';\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { AtSignIcon, XIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\nimport { useTanStackFieldContext } from '../../tanstack-form';\n\nimport type { EmailFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected email input field with an at-sign prefix icon,\n * optional clear button, and inline validation error display.\n *\n * @example\n * import { EmailField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"email\">\n * {() => (\n * <EmailField\n * label=\"Email address\"\n * placeholder=\"you@example.com\"\n * required\n * />\n * )}\n * </form.Field>\n */\nexport const EmailField: React.FC<Props> = ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n showErrorMessage = true,\n required = false,\n maxLength,\n}) => {\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isDirty && state.meta.isTouched && !state.meta.isValid;\n const _isEmpty = required && state.value === null;\n const _showClear = !isSubmitting && !!state.value;\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n if (maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isSubmitting, maxLength, handleChange]\n );\n\n const onClear = useCallback(() => {\n if (isSubmitting) return;\n handleChange(null);\n }, [isSubmitting, handleChange]);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field data-invalid={_invalid} orientation={orientation}>\n <FieldContent>\n <FieldLabel htmlFor={name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldContentMain>\n <Input\n id={name}\n name={name}\n value={state.value === null ? '' : state.value}\n aria-invalid={_invalid}\n autoComplete=\"email\"\n placeholder={placeholder}\n className={cn('pl-9', _showClear && 'pr-9', isSubmitting && 'pointer-events-none bg-muted-muted opacity-60')}\n onBlur={handleBlur}\n onChange={onChange}\n />\n <div className=\"absolute top-0 left-0 flex size-9 items-center justify-center text-muted\">\n <AtSignIcon size={14} />\n </div>\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa\"\n className=\"absolute inset-e-0 inset-y-0 top-3 flex h-fit w-8 cursor-pointer items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:text-text-positive-strong\"\n onClick={onClear}\n >\n <XIcon size={14} aria-hidden=\"true\" />\n </button>\n )}\n\n <div className=\"mt-1 flex w-full items-start justify-start\">\n {showErrorMessage && state.meta.isDirty && <FieldError errors={state.meta.errors} />}\n </div>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { memo, useCallback, useId } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { BanIcon, Loader2Icon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { NumberInput } from '@/components/ui/inputs/number-input';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { NumberFieldProps } from '../../types';\n\n/**\n * A TanStack Form-connected numeric input field supporting rounding rules,\n * decimal precision, unit labels, and submission-state feedback.\n *\n * @example\n * import { NumberField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"quantity\">\n * {() => (\n * <NumberField\n * label=\"Quantity\"\n * placeholder=\"0\"\n * unit=\"pcs\"\n * decimalPlaces={2}\n * required\n * />\n * )}\n * </form.Field>\n */\nexport const NumberField = memo<NumberFieldProps>(\n ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n showErrorMessage = true,\n rounding,\n decimalPlaces,\n precision,\n unit,\n required = false,\n disabled = false,\n allowNegative,\n }) => {\n const id = useId();\n const errorId = useId();\n\n const field = useTanStackFieldContext<number | null>();\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _hasErrors = !!field.state.meta.errors.length;\n\n const onValueChange = useCallback(\n (value: number | null) => {\n if (isDisabled) return;\n field.handleChange(value);\n },\n [isDisabled, field.handleChange]\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel htmlFor={id} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain>\n <div className=\"relative w-full\">\n <NumberInput\n id={id}\n value={field.state.value}\n aria-invalid={_invalid}\n aria-describedby={errorId}\n placeholder={placeholder}\n disabled={isDisabled}\n roundingRule={rounding}\n numberAfterDecimalPoint={decimalPlaces}\n precision={precision}\n unitText={unit}\n allowNegative={allowNegative}\n className={cn(isDisabled && 'pointer-events-none opacity-60')}\n onBlur={field.handleBlur}\n onValueChange={onValueChange}\n />\n {isSubmitting && (\n <div className=\"pointer-events-none absolute inset-s-2 inset-y-0 top-2.5 [&>svg]:size-3.5\">\n <Loader2Icon className=\"animate-spin text-primary-strong\" />\n </div>\n )}\n {!isSubmitting && _touched && showErrorMessage && _hasErrors && (\n <div className=\"pointer-events-none absolute inset-s-2 inset-y-0 top-2.75 text-danger-strong [&>svg]:size-3.5\">\n <BanIcon />\n </div>\n )}\n <div className=\"mt-1 flex w-full items-start justify-between gap-x-2\">\n {_touched && showErrorMessage ? <FieldError id={errorId} className=\"flex-1\" errors={field.state.meta.errors} /> : <div />}\n </div>\n </div>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nNumberField.displayName = 'NumberField';\n","'use client';\n\nimport { useCallback, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { EyeIcon, EyeOffIcon } from 'lucide-react';\n\nimport { Input } from '@/components/ui/input';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { PasswordFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected password input field with a show/hide toggle button\n * and inline validation error display.\n *\n * @example\n * import { PasswordField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"password\">\n * {() => (\n * <PasswordField\n * label=\"Password\"\n * placeholder=\"Enter your password\"\n * helperText=\"Must be at least 8 characters\"\n * />\n * )}\n * </form.Field>\n */\nexport const PasswordField: React.FC<Props> = ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n helperText,\n showErrorMessage = true,\n}) => {\n const id = useId();\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const [isVisible, setIsVisible] = useState<boolean>(false);\n\n const _invalid = state.meta.isDirty && state.meta.isTouched && !state.meta.isValid;\n\n const toggleVisibility = useCallback(() => setIsVisible(prev => !prev), []);\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n handleChange(value || null);\n },\n [isSubmitting, handleChange]\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field data-invalid={_invalid} orientation={orientation}>\n <FieldContent>\n <FieldLabel htmlFor={id}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldContentMain>\n <Input\n id={id}\n name={name}\n type={isVisible ? 'text' : 'password'}\n placeholder={placeholder}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n autoComplete=\"new-password\"\n onBlur={handleBlur}\n onChange={onChange}\n />\n\n <button\n className=\"absolute inset-e-0 inset-y-0 flex size-9 items-center justify-center rounded-e-md text-muted outline-none transition-[color,box-shadow] focus:z-10 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n type=\"button\"\n onClick={toggleVisibility}\n aria-label={isVisible ? 'Ẩn mật khẩu' : 'Hiện mật khẩu'}\n aria-pressed={isVisible}\n aria-controls={id}\n >\n {isVisible ? <EyeOffIcon size={16} aria-hidden=\"true\" /> : <EyeIcon size={16} aria-hidden=\"true\" />}\n </button>\n\n <div className=\"mt-1 flex w-full items-start justify-start\">\n {showErrorMessage && state.meta.isDirty && <FieldError errors={state.meta.errors} />}\n </div>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTitle,\n FieldTooltip,\n} from '../ui/field';\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';\n\nimport type { RadioGroupFieldProps as Props } from '../../types';\n\nexport const RadioGroupField: React.FC<Props> = ({ label, description, orientation, options, tooltip, helperText }) => {\n const field = useTanStackFieldContext<string | null>();\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n\n return (\n <FieldGroup className=\"px-4\">\n <Field orientation={orientation} className=\"flex-col gap-2\">\n <FieldContent>\n <FieldLabel>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContent>\n\n <FieldContentMain>\n <RadioGroup value={field.state.value ?? ''} className=\"w-full\" onValueChange={field.handleChange}>\n {options.map(option => (\n <FieldLabel\n key={option.value}\n className={cn(\n 'h-fit',\n field.state.value === option.value && 'border-primary-weak! bg-primary-bg-subtle',\n isSubmitting && 'pointer-events-none bg-muted-muted opacity-60',\n field.state.value === option.value && isSubmitting && 'border-border-strong!'\n )}\n >\n <Field orientation=\"horizontal\" className=\"items-start gap-3 rounded p-2!\">\n <RadioGroupItem value={option.value} className=\"mt-0.5 shrink-0\" />\n <FieldContent className=\"gap-0.5!\">\n <FieldTitle>{option.label}</FieldTitle>\n <FieldDescription className=\"text-xs\">{option.description}</FieldDescription>\n </FieldContent>\n </Field>\n </FieldLabel>\n ))}\n </RadioGroup>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { ChevronDownIcon, PackagePlusIcon, XIcon } from 'lucide-react';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Dialog as RadixDialog } from 'radix-ui';\n\nimport { Dialog, DialogClose, DialogOverlay, DialogPortal } from '@/components/ui/dialog';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { SelectFieldProps as Props } from '../../types';\n\nexport const SelectField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n options,\n helperText,\n clearable = false,\n required = false,\n disabled = false,\n showErrorMessage = true,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [dialogOpen, setDialogOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _showClear = clearable && !!field.state.value && !isDisabled;\n\n const selectedLabel = options.find(o => o.value === field.state.value)?.label;\n\n const onClear = () => {\n field.handleChange(null);\n field.handleBlur();\n };\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel htmlFor={field.name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex flex-col\">\n {isMobile ? (\n <>\n <button\n id={field.name}\n type=\"button\"\n disabled={isDisabled}\n aria-invalid={_invalid ? 'true' : undefined}\n aria-describedby={errorId}\n onBlur={field.handleBlur}\n onClick={() => setDialogOpen(true)}\n className={cn(\n 'flex w-full items-center justify-between',\n 'outline-1 outline-border -outline-offset-1',\n 'gap-2 rounded bg-transparent px-3 py-2',\n 'shadow-input transition-all cursor-pointer whitespace-nowrap text-sm',\n 'focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n _invalid && 'outline-danger bg-danger-bg-subtle ring-danger-weak',\n !field.state.value && 'text-text-positive-muted'\n )}\n >\n <span className=\"line-clamp-1\">{selectedLabel ?? placeholder}</span>\n <ChevronDownIcon size={16} className=\"shrink-0 opacity-50\" />\n </button>\n\n <Dialog\n open={dialogOpen}\n onOpenChange={open => {\n setDialogOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <DialogPortal>\n <DialogOverlay />\n <RadixDialog.Content\n onOpenAutoFocus={e => e.preventDefault()}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-50',\n 'flex flex-col bg-background rounded-t-2xl outline-none',\n 'max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0',\n 'duration-300'\n )}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border shrink-0\">\n <span className=\"font-semibold text-sm text-text-positive\">{label ?? placeholder ?? 'Chọn một tùy chọn'}</span>\n <DialogClose asChild>\n <button\n type=\"button\"\n aria-label=\"Đóng\"\n className=\"flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive\"\n >\n <XIcon size={16} />\n </button>\n </DialogClose>\n </div>\n\n <div className=\"flex flex-col overflow-y-auto\">\n {_showClear && (\n <DialogClose asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle\"\n onClick={onClear}\n >\n <XIcon size={14} />\n Xóa lựa chọn\n </button>\n </DialogClose>\n )}\n {options.length > 0 ? (\n options.map(option => (\n <DialogClose key={option.value} asChild>\n <button\n type=\"button\"\n className={cn(\n 'flex w-full items-center px-4 py-3 text-left text-sm transition-colors',\n 'hover:bg-muted-muted active:bg-muted-muted',\n field.state.value === option.value && 'bg-primary-bg-subtle font-medium text-primary'\n )}\n onClick={() => {\n field.handleChange(option.value);\n field.handleBlur();\n }}\n >\n {option.label}\n </button>\n </DialogClose>\n ))\n ) : (\n <div className=\"flex items-center justify-center gap-x-2 px-4 py-8 text-center text-sm text-text-positive-weak\">\n <PackagePlusIcon strokeWidth={1} />\n Không có tùy chọn\n </div>\n )}\n </div>\n\n <div className=\"shrink-0 h-safe-bottom\" />\n </RadixDialog.Content>\n </DialogPortal>\n </Dialog>\n </>\n ) : (\n <div className=\"relative\">\n <Select value={field.state.value ?? ''} disabled={isDisabled} onValueChange={field.handleChange}>\n <SelectTrigger aria-invalid={_invalid ? 'true' : undefined} aria-describedby={errorId} onBlur={field.handleBlur}>\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent>\n {options.length > 0 ? (\n options.map(option => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))\n ) : (\n <div className=\"flex items-center justify-center gap-x-2 rounded border border-border bg-muted-muted px-4 py-6.5 text-center text-sm text-text-positive-weak\">\n <PackagePlusIcon strokeWidth={1} />\n No options available\n </div>\n )}\n </SelectContent>\n </Select>\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa lựa chọn\"\n className=\"absolute right-7 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n </div>\n )}\n\n {_touched && showErrorMessage && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nSelectField.displayName = 'SelectField';\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Switch as SwitchPrimitive } from 'radix-ui';\n\n/**\n * Accessible toggle switch built on Radix UI, styled with primary-color checked state and smooth thumb transition.\n *\n * @example\n * import { Switch } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <Switch defaultChecked onCheckedChange={(checked) => console.log(checked)} />\n */\nfunction Switch({ className, ...props }: React.ComponentProps<typeof SwitchPrimitive.Root>) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n className={cn(\n 'peer',\n 'w-8 shrink-0 cursor-pointer items-center rounded-full shadow-xs transition-all',\n 'inline-flex h-5',\n 'focus-visible:border-primary-strong',\n 'focus-visible:ring-primary-weak',\n 'focus-visible:ring-4',\n 'disabled:cursor-not-allowed',\n 'disabled:opacity-50',\n\n '-outline-offset-1 inset-shadow-2xs outline-1',\n\n 'data-[state=checked]:bg-primary',\n 'data-[state=checked]:outline-primary-strong',\n\n 'data-[state=unchecked]:bg-muted-weak',\n 'data-[state=unchecked]:outline-border',\n\n 'data-[state=unchecked]:[&_span]:size-4',\n 'data-[state=unchecked]:[&_span]:translate-x-0.5',\n 'data-[state=unchecked]:[&_span]:rtl:-translate-x-0.5',\n className\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className={cn(\n 'block size-4 bg-card shadow-xs',\n 'pointer-events-none rounded-full ring-0 transition-transform',\n 'data-[state=checked]:translate-x-[calc(100%-3px)]',\n 'data-[state=unchecked]:translate-x-0'\n )}\n />\n </SwitchPrimitive.Root>\n );\n}\n\nexport { Switch };\n","'use client';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { Field, FieldContent, FieldDescription, FieldGroup, FieldNote, FieldSeparator, FieldTitle } from '../ui/field';\nimport { Switch } from '../ui/switch';\n\nimport type { SwitchFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected boolean toggle field rendered as a labelled switch,\n * positioned absolutely in the top-right corner of the field card.\n *\n * @example\n * import { SwitchField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"notifications\">\n * {() => (\n * <SwitchField\n * label=\"Enable notifications\"\n * description=\"Receive email alerts for important events\"\n * helperText=\"You can change this at any time\"\n * />\n * )}\n * </form.Field>\n */\nexport const SwitchField: React.FC<Props> = ({ label, description, helperText }) => {\n const field = useTanStackFieldContext<boolean | null>();\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation=\"vertical\" className=\"relative justify-between gap-y-1\">\n <FieldContent>\n <FieldTitle className=\"cursor-pointer\">\n <label htmlFor={field.name}>{label}</label>\n </FieldTitle>\n <FieldDescription>{description}</FieldDescription>\n <Switch\n id={field.name}\n checked={field.state.value ?? false}\n className=\"absolute top-1 right-1\"\n onBlur={field.handleBlur}\n onCheckedChange={field.handleChange}\n />\n </FieldContent>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { memo, useCallback, useId, useRef } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { BanIcon, Loader2Icon, XIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '@/components/features/tanstack-form/components/ui/field';\nimport { useTanStackFieldContext } from '../../tanstack-form';\n\nimport type { TextFieldProps as Props } from '../../types';\n\n/** Fraction of maxLength at which the counter turns warning color (80%). */\nconst COUNTER_WARNING_THRESHOLD = 0.8;\n\n/** Pixel size for inline adornment icons (error ban, loading spinner). */\nconst ADORNMENT_ICON_SIZE = 14;\n\n// Static handler — no closure deps, shared across all TextField instances\nconst onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = e => {\n if (e.key === 'Enter') e.preventDefault();\n};\n\n/**\n * A TanStack Form-connected single-line text input with label, validation, and optional features.\n *\n * Must be rendered inside an `AppField` context from `useTanStackForm`.\n * The field value type is `string | null` — `null` represents an empty/unset state.\n *\n * ---\n *\n * **Basic usage**\n * @example\n * const { AppField } = useTanStackForm({ defaultValues: { name: null } });\n *\n * <AppField name=\"name\">\n * {field => <field.TextField label=\"Full name\" placeholder=\"Nguyễn Văn A\" />}\n * </AppField>\n *\n * ---\n *\n * **With validation**\n * @example\n * <AppField\n * name=\"username\"\n * validators={{ onChange: ({ value }) => !value ? 'Bắt buộc' : undefined }}\n * >\n * {field => <field.TextField label=\"Username\" required />}\n * </AppField>\n *\n * ---\n *\n * **With character counter and max length**\n * @example\n * <AppField name=\"bio\">\n * {field => (\n * <field.TextField\n * label=\"Bio\"\n * counter\n * maxLength={160}\n * placeholder=\"Giới thiệu bản thân…\"\n * />\n * )}\n * </AppField>\n *\n * ---\n *\n * **With clear button and helper note**\n * @example\n * <AppField name=\"search\">\n * {field => (\n * <field.TextField\n * label=\"Tìm kiếm\"\n * showClearButton\n * helperText=\"Nhập ít nhất 3 ký tự để tìm kiếm.\"\n * />\n * )}\n * </AppField>\n *\n * ---\n *\n * **Horizontal layout**\n * @example\n * <AppField name=\"code\">\n * {field => (\n * <field.TextField\n * label=\"Mã sản phẩm\"\n * orientation=\"horizontal\"\n * tooltip=\"Mã duy nhất định danh sản phẩm trong hệ thống.\"\n * />\n * )}\n * </AppField>\n */\nexport const TextField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n\n tooltip,\n helperText,\n counter = false,\n orientation = 'responsive',\n showClearButton = false,\n showErrorMessage = true,\n\n required = false,\n disabled = false,\n maxLength,\n }) => {\n const id = useId();\n const errorId = useId();\n const inputRef = useRef<HTMLInputElement>(null);\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = state.meta.isDirty || state.meta.isTouched;\n const _invalid = _touched && !state.meta.isValid;\n const _isEmpty = required && state.value === null;\n const _hasErrors = state.meta.errors.length > 0;\n const _showClearButton = showClearButton && !isDisabled && !!state.value;\n\n // Counter values are only computed when the feature is active\n const _count = counter ? (state.value?.length ?? 0) : 0;\n const _isNearLimit = counter && !!maxLength && _count >= maxLength * COUNTER_WARNING_THRESHOLD;\n const _isAtLimit = counter && !!maxLength && _count >= maxLength;\n const _countText = counter ? (maxLength ? `${_count} / ${maxLength} ký tự` : `${_count} ký tự`) : null;\n\n // Skip the bottom row entirely when neither error nor counter will render\n const _showBottomRow = counter || (_touched && showErrorMessage);\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (counter && maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [counter, maxLength, handleChange]\n );\n\n const onClear = useCallback(() => {\n handleChange(null);\n inputRef.current?.focus();\n }, [handleChange]);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={id}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n {description && <FieldDescription>{description}</FieldDescription>}\n </FieldContent>\n <FieldContentMain>\n <Input\n ref={inputRef}\n id={id}\n name={name}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n aria-describedby={errorId}\n autoComplete=\"off\"\n placeholder={placeholder}\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n disabled={isDisabled}\n className={cn('pr-6', isDisabled && 'pointer-events-none bg-muted-muted opacity-60')}\n onBlur={handleBlur}\n onChange={onChange}\n onKeyDown={onKeyDown}\n />\n {_showClearButton && (\n <button\n type=\"button\"\n aria-label=\"Xóa\"\n className=\"absolute inset-e-1 top-2.5 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n {isSubmitting && (\n <div className=\"absolute inset-e-2 inset-y-0 top-2.5 text-muted-weak\">\n <Loader2Icon size={ADORNMENT_ICON_SIZE} className=\"animate-spin text-primary-strong\" />\n </div>\n )}\n {!_showClearButton && _touched && showErrorMessage && _hasErrors && (\n <div className=\"absolute inset-e-2 inset-y-0 top-2.5 text-danger-strong\">\n <BanIcon aria-hidden=\"true\" size={ADORNMENT_ICON_SIZE} />\n </div>\n )}\n {_showBottomRow && (\n <div className=\"my-1 flex w-full items-start justify-between gap-x-2\">\n {_touched && showErrorMessage ? <FieldError id={errorId} className=\"flex-1\" errors={state.meta.errors} /> : <div />}\n {counter && (\n <p\n className={cn(\n 'h-4 flex-0 text-nowrap text-end text-xs tabular-nums transition-colors',\n _isAtLimit ? 'font-medium text-danger-strong' : _isNearLimit ? 'text-warning-strong' : 'text-text-positive-weak'\n )}\n >\n {_countText}\n </p>\n )}\n </div>\n )}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nTextField.displayName = 'TextField';\n","'use client';\n\nimport { memo, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { BanIcon, CheckIcon, CopyIcon, Loader2Icon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Textarea } from '@/components/ui/textarea';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { TextareaFieldProps as Props } from '../../types';\n\nexport const TextareaField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n\n tooltip,\n helperText,\n counter = false,\n orientation = 'responsive',\n showErrorMessage = true,\n\n required = false,\n disabled = false,\n maxLength,\n }) => {\n const id = useId();\n const errorId = useId();\n const [copied, setCopied] = useState(false);\n const copyTimeoutRef = useRef<number | null>(null);\n\n const { form, state, name, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _count = state.value?.length ?? 0;\n\n const _countText = useMemo(() => {\n if (!counter) return '';\n return maxLength ? `${_count} / ${maxLength} ký tự` : `${_count} ký tự`;\n }, [_count, counter, maxLength]);\n\n const _isNearLimit = !!maxLength && _count >= maxLength * 0.8;\n const _isAtLimit = !!maxLength && _count >= maxLength;\n\n const _touched = state.meta.isDirty || state.meta.isTouched;\n const _invalid = _touched && !state.meta.isValid;\n const _isEmpty = required && state.value === null;\n const _hasErrors = !!state.meta.errors.length;\n const _showCopy = !!state.value && !isDisabled;\n\n const _counterClass = useMemo(\n () =>\n cn(\n 'h-4 flex-0 text-nowrap text-end text-xs tabular-nums transition-colors',\n _isAtLimit ? 'font-medium text-danger-strong' : _isNearLimit ? 'text-warning-strong' : 'text-text-positive-weak'\n ),\n [_isAtLimit, _isNearLimit]\n );\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLTextAreaElement>>(\n ({ target: { value } }) => {\n if (isDisabled) return;\n if (counter && maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isDisabled, counter, maxLength, handleChange]\n );\n\n const onCopy = useCallback(async () => {\n if (!state.value) return;\n await navigator.clipboard.writeText(state.value);\n if (copyTimeoutRef.current !== null) window.clearTimeout(copyTimeoutRef.current);\n setCopied(true);\n copyTimeoutRef.current = window.setTimeout(() => setCopied(false), 1500);\n }, [state.value]);\n\n useEffect(() => {\n return () => {\n if (copyTimeoutRef.current !== null) window.clearTimeout(copyTimeoutRef.current);\n };\n }, []);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={id}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldContentMain>\n <Textarea\n id={id}\n name={name}\n value={state.value ?? ''}\n aria-invalid={_invalid}\n aria-describedby={errorId}\n autoCapitalize=\"none\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n placeholder={placeholder}\n disabled={isDisabled}\n className={cn(isDisabled && 'pointer-events-none bg-muted-muted opacity-60')}\n onChange={onChange}\n onBlur={handleBlur}\n />\n {_showCopy && (\n <button\n type=\"button\"\n aria-label=\"Sao chép\"\n className=\"absolute inset-e-1 top-2 flex size-4 cursor-pointer items-center justify-center rounded-md outline-none transition-[color,transform] focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onCopy}\n >\n {copied ? (\n <CheckIcon aria-hidden=\"true\" className=\"text-success-strong\" />\n ) : (\n <CopyIcon\n aria-hidden=\"true\"\n className=\"text-text-positive-weak transition-colors hover:text-text-positive focus-visible:text-primary-strong\"\n />\n )}\n </button>\n )}\n {isSubmitting && (\n <div className=\"absolute inset-e-2 inset-y-0 top-2.5 text-muted-weak\">\n <Loader2Icon size={14} className=\"animate-spin text-primary-strong\" />\n </div>\n )}\n {!_showCopy && _touched && showErrorMessage && _hasErrors && (\n <div className=\"absolute inset-e-2 inset-y-0 top-2.5 text-danger-strong\">\n <BanIcon size={14} />\n </div>\n )}\n <div className=\"my-1 flex w-full items-start justify-between gap-x-2\">\n {_touched && showErrorMessage ? <FieldError id={errorId} className=\"flex-1\" errors={state.meta.errors} /> : <div />}\n {!!counter && <p className={_counterClass}>{_countText}</p>}\n </div>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nTextareaField.displayName = 'TextareaField';\n","'use client';\n\nimport { memo, useCallback } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { TextEditor } from '@/components/features/text-editor';\n\nimport { useTanStackFieldContext } from '../../tanstack-form';\nimport { Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldNote, FieldSeparator, FieldTooltip } from '../ui/field';\n\nimport type { TextEditorFieldProps as Props } from '../../types';\n\nexport const TextEditorField: React.FC<Props> = memo(({ label, description, placeholder, tooltip, helperText, showErrorMessage = true, required = false }) => {\n const { form, state, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isDirty && state.meta.isTouched && !state.meta.isValid;\n const _isEmpty = required && state.value === null;\n\n const onChange = useCallback(\n (html: string) => {\n if (isSubmitting) return;\n handleChange(html || null);\n },\n [isSubmitting, handleChange]\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation=\"vertical\" data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <TextEditor value={state.value ?? ''} placeholder={placeholder} readOnly={isSubmitting} onChange={onChange} />\n {state.meta.isDirty && showErrorMessage && !!state.meta.errors.length && <FieldError errors={state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n});\nTextEditorField.displayName = 'TextEditorField';\n","import { useCallback } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../../tanstack-form';\n\n/**\n * Renders a submit button wired to the current TanStack Form context, automatically handling loading and disabled states.\n *\n * @example\n * import { TanStackActionSubmit } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionSubmit label=\"Save Changes\" className=\"mt-4\" />\n */\nexport const TanStackActionSubmit: React.FC<{\n /** Button label text. Defaults to `'Submit'` when omitted. */\n label?: string;\n /** Additional CSS class names applied to the button element. */\n className?: string;\n}> = ({ label, className }) => {\n const form = useTanStackFormContext();\n\n const onSubmit = useCallback(async () => {\n await form.handleSubmit({ submitAction: 'submit' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }, [form]);\n return (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button type=\"button\" size=\"md\" disabled={disabled} isLoading={isSubmitting} className={cn('min-h-8 min-w-32', className)} onClick={onSubmit}>\n {label ?? 'Xác nhận'}\n </Button>\n );\n }}\n />\n );\n};\n","import { ArrowDownToLine, PlusIcon } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../../tanstack-form';\n\n/**\n * Renders a form action bar with a Cancel button and a context-aware submit button (Add New or Update) driven by TanStack Form state.\n *\n * @example\n * import { TanStackActionsForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionsForm type=\"create\" />\n *\n * // For an update workflow:\n * <TanStackActionsForm type=\"update\" />\n */\nexport const TanStackActionsForm: React.FC<\n React.PropsWithChildren<{\n /**\n * Determines which submit button variant is rendered.\n * - `'create'` — shows an \"Add New\" button that resets the form on success.\n * - `'update'` — shows an \"Update\" button that resets the form on success.\n * Defaults to `'create'`.\n */\n type?: 'create' | 'update';\n }>\n> = ({ type = 'create' }) => {\n const form = useTanStackFormContext();\n return (\n <div className=\"flex h-8 items-center justify-between\">\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || state.isSubmitting,\n })}\n children={({ disabled }) => {\n return (\n <Button color=\"muted\" variant=\"outline\" type=\"button\" size=\"md\" disabled={disabled} className=\"h-full min-w-32\" onClick={() => form.reset()}>\n Hủy bỏ\n </Button>\n );\n }}\n />\n {type === 'create' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'create' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <PlusIcon />\n Thêm mới\n </Button>\n );\n }}\n />\n )}\n {type === 'update' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'update' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <ArrowDownToLine />\n Cập nhật\n </Button>\n );\n }}\n />\n )}\n </div>\n );\n};\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Separator as SeparatorPrimitive } from 'radix-ui';\n\n/**\n * Thin decorative divider line that supports horizontal and vertical orientations via Radix UI Separator.\n *\n * @example\n * import { Separator } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <Separator orientation=\"horizontal\" />\n */\nfunction Separator({ className, orientation = 'horizontal', decorative = true, ...props }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n 'shrink-0 bg-border-weak',\n 'data-[orientation=horizontal]:h-px',\n 'data-[orientation=horizontal]:w-full',\n 'data-[orientation=vertical]:h-full',\n 'data-[orientation=vertical]:w-px',\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Separator };\n","'use client';\n\nimport { Trash2Icon } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\n\nimport { Separator } from '../ui/separator';\n\n/**\n * Renders a card-style form section with a header, optional description, a delete button, and a content area for fields.\n *\n * @example\n * import { TanStackCardForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackCardForm\n * title=\"Shipping Address\"\n * description=\"Where should we deliver your order?\"\n * onDelete={() => removeAddress(id)}\n * >\n * <TextField name=\"street\" />\n * </TanStackCardForm>\n */\nexport const TanStackCardForm: React.FC<\n React.PropsWithChildren<{\n /** Bold heading text shown at the top of the card. */\n title: string;\n /** Optional secondary text rendered beneath the title. */\n description?: string;\n /** When provided, renders a danger \"Remove\" button in the card's top-right corner. */\n onDelete?: () => void | Promise<void>;\n }>\n> = ({ title, description, onDelete, children }) => {\n return (\n <section data-slot=\"card-form\" className=\"relative flex flex-col rounded-md bg-card pb-4 shadow-card ring-1 ring-border\">\n <div data-slot=\"card-form-header\" className=\"flex flex-col space-y-0.5 px-4 py-3\">\n <p className=\"font-semibold text-base tracking-tight\">{title}</p>\n {!!description && <p className=\"text-text-positive-weak text-sm\">{description}</p>}\n </div>\n <Separator />\n <div data-slot=\"card-form-main\" className=\"flex flex-col py-4\">\n {children}\n </div>\n {!!onDelete && (\n <Button\n color=\"danger\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute top-2.5 right-3\"\n onClick={e => {\n onDelete?.();\n e.preventDefault();\n e.stopPropagation();\n }}\n >\n <Trash2Icon />\n Remove\n </Button>\n )}\n </section>\n );\n};\n","/**\n * Wraps a set of TanStack form sections in a vertically-stacked flex container.\n *\n * @example\n * import { TanStackContainerForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackContainerForm>\n * <TanStackSectionForm title=\"Personal Info\">\n * {/* fields *\\/}\n * </TanStackSectionForm>\n * </TanStackContainerForm>\n */\nexport const TanStackContainerForm: React.FC<React.PropsWithChildren> = ({ children }) => {\n return (\n <div data-slot=\"section-form\" className=\"flex flex-col space-y-4\">\n {children}\n </div>\n );\n};\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\n/**\n * Secondary outline button used to dismiss or cancel a form without submitting, defaulting to the label \"Cancel\".\n *\n * @example\n * import { CancelButton } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <CancelButton onClick={() => router.back()} />\n */\nexport const CancelButton: React.FC<React.ComponentProps<'button'>> = ({ disabled, className, onClick, children }) => {\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n color=\"muted\"\n disabled={disabled}\n className={cn('min-w-40', className)}\n onClick={onClick as React.MouseEventHandler<HTMLButtonElement>}\n >\n {children ?? 'Huỷ'}\n </Button>\n );\n};\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\n/**\n * Props for the {@link SubmitButton} component.\n */\ntype SubmitButtonProps = React.ComponentProps<'button'> & {\n /**\n * When `true` the button enters a loading state and is automatically disabled to prevent duplicate submissions.\n */\n isSubmitting?: boolean;\n /**\n * Label text rendered inside the button.\n * @default 'Submit'\n */\n submitText?: string;\n};\n\n/**\n * Primary form submission button that shows a loading indicator while the form is being submitted.\n *\n * @example\n * import { SubmitButton } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <SubmitButton isSubmitting={form.state.isSubmitting} submitText=\"Save changes\" />\n */\nexport const SubmitButton: React.FC<SubmitButtonProps> = ({ isSubmitting, submitText = 'Xác nhận', disabled, className, onClick }) => {\n return (\n <Button\n type=\"button\"\n isLoading={isSubmitting}\n disabled={disabled || isSubmitting}\n className={cn('min-w-40', className)}\n onClick={onClick as React.MouseEventHandler<HTMLButtonElement>}\n >\n {submitText}\n </Button>\n );\n};\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Dialog, DialogContent, DialogOverlay, DialogPortal, DialogTitle } from '@/components/ui/dialog';\nimport { Separator } from '@/components/ui/separator';\n\nimport { useTanStackFormContext } from '../../tanstack-form';\nimport { CancelButton } from '../ui/cancel-button';\nimport { SubmitButton } from '../ui/submit-button';\n\n/**\n * Renders a modal dialog that wraps a TanStack Form with a title, scrollable content area, and built-in submit/cancel actions.\n *\n * @example\n * import { TanStackDialogForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackDialogForm\n * title=\"Create User\"\n * submitText=\"Create\"\n * className=\"max-w-lg\"\n * open={isOpen}\n * onOpenChange={setIsOpen}\n * >\n * <NameField />\n * <EmailField />\n * </TanStackDialogForm>\n */\nexport const TanStackDialogForm: React.FC<\n React.PropsWithChildren<{\n /** Heading text displayed in the dialog title bar. */\n title: string;\n /** Custom label for the submit button. Defaults to the `SubmitButton` component's built-in label when omitted. */\n submitText?: string;\n /** Optional fixed width for the dialog content area, as a pixel number (e.g. `600`) or any CSS string (e.g. `'50%'`, `'40rem'`). Omit to let the dialog size itself based on content. */\n width?: number | string;\n /** Optional fixed max-width for the dialog content area, as a pixel number (e.g. `600`) or any CSS string (e.g. `'50%'`, `'40rem'`). Omit to let the dialog size itself based on content and viewport. */\n maxWidth?: number | string;\n /** Optional additional class name(s) to apply to the dialog content container. */\n className?: string;\n /** Controlled open state of the dialog. */\n open?: boolean;\n /** Callback fired when the dialog open state changes; the form is reset on close. */\n onOpenChange?: (open: boolean) => void;\n }>\n> = ({ title, submitText, width, maxWidth, className, open, onOpenChange, children }) => {\n const form = useTanStackFormContext();\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n if (!open) form.reset();\n onOpenChange?.(open);\n },\n [form.reset, onOpenChange]\n );\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogContent\n style={\n {\n '--width': width,\n '--max-width': maxWidth,\n } as React.CSSProperties\n }\n className={cn(\n 'flex size-full max-h-dvh max-w-dvw flex-col gap-0 overflow-y-auto rounded-none p-0 shadow-dialog sm:h-auto sm:max-h-[85dvh] sm:max-w-5xl sm:rounded-md',\n width && `sm:w-(--width)`,\n maxWidth && `sm:max-w-(--max-width)`,\n className\n )}\n onOpenAutoFocus={event => {\n // Prevents focus from shifting to the content when the dialog opens, which can cause layout shift if the content includes autofocusable elements.\n event.preventDefault();\n }}\n >\n <div data-slot=\"dialog-header\" className=\"flex items-center justify-center gap-2 px-6 py-5 text-center sm:text-left\">\n <DialogTitle data-slot=\"dialog-title\" className=\"font-semibold text-lg tracking-tight\">\n {title}\n </DialogTitle>\n </div>\n <Separator />\n <div data-slot=\"dialog-content\" className=\"relative flex flex-col overflow-y-auto p-0 pt-4 max-sm:flex-1 sm:p-4\">\n {children}\n </div>\n <Separator />\n <div data-slot=\"dialog-footer\" className=\"flex flex-col-reverse items-center justify-end gap-2 px-6 py-4 sm:flex-row max-sm:[&>button]:w-full\">\n <form.Subscribe\n selector={state => ({ disabled: state.isSubmitting })}\n children={({ disabled }) => (\n <CancelButton\n disabled={disabled}\n onClick={() => {\n form.reset();\n handleOpenChange(false);\n }}\n />\n )}\n />\n <form.Subscribe\n selector={state => ({\n isSubmitting: state.isSubmitting,\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit,\n })}\n children={({ isSubmitting, disabled }) => (\n <SubmitButton isSubmitting={isSubmitting} disabled={disabled} submitText={submitText} onClick={() => form.handleSubmit()} />\n )}\n />\n </div>\n </DialogContent>\n </DialogPortal>\n </Dialog>\n );\n};\n","import {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n} from '@/components/features/tanstack-form/components/ui/field';\n\n/**\n * Renders a labeled field group with an optional description, helper text, and a bottom separator.\n *\n * @example\n * import { TanStackFieldGroup } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackFieldGroup\n * label=\"Contact Details\"\n * description=\"Enter your contact information.\"\n * helperText=\"All fields are required.\"\n * orientation=\"horizontal\"\n * >\n * <EmailField />\n * </TanStackFieldGroup>\n */\nexport const TanStackFieldGroup: React.FC<\n React.PropsWithChildren<{\n /** Primary label displayed above the field content. */\n label: string;\n /** Secondary descriptive text shown beneath the label. */\n description?: string;\n /** Supplementary helper note rendered below the field content. */\n helperText?: string;\n /** Layout orientation of the label-to-content axis. Defaults to `'responsive'`. */\n orientation?: 'horizontal' | 'vertical' | 'responsive';\n }>\n> = ({\n label,\n description,\n helperText,\n\n orientation = 'responsive',\n children,\n}) => {\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation}>\n <FieldContent>\n <FieldLabel>{label}</FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldContentMain>\n {children}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { CloseButton } from '@/components/ui/buttons/close';\n\nimport { Dialog as DialogPrimitive } from 'radix-ui';\nimport { useTanStackFormContext } from '../../tanstack-form';\nimport { CancelButton } from '../ui/cancel-button';\nimport { SubmitButton } from '../ui/submit-button';\n\n/**\n * Renders a slide-in side-panel dialog that wraps a TanStack form with built-in submit and cancel actions.\n *\n * @example\n * import { TanStackPopoverForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackPopoverForm\n * title=\"Edit Profile\"\n * open={isOpen}\n * onOpenChange={setIsOpen}\n * >\n * <EmailField />\n * </TanStackPopoverForm>\n */\nexport const TanStackPopoverForm: React.FC<\n React.PropsWithChildren<{\n /** Heading text displayed in the panel header. */\n title: string;\n /** Controlled open state of the popover dialog. */\n open?: boolean;\n /** Additional CSS class names applied to the scrollable content area. */\n contentClassName?: string;\n /** Callback fired when the open state changes. */\n onOpenChange?: (open: boolean) => void;\n }>\n> = ({ title, open, contentClassName, onOpenChange, children }) => {\n const form = useTanStackFormContext();\n\n return (\n <DialogPrimitive.Root data-slot=\"dialog\" open={open} onOpenChange={onOpenChange}>\n <DialogPrimitive.Portal data-slot=\"dialog-portal\">\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n 'fixed inset-0 z-40 bg-black/40 backdrop-blur-sm',\n 'data-[state=open]:animate-in data-[state=open]:fade-in',\n 'data-[state=closed]:animate-out data-[state=closed]:fade-out'\n )}\n />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n 'fixed top-4 right-4 z-50 h-[calc(100dvh-2rem)] min-w-sm max-w-xl rounded-md bg-background shadow-lg ring-1 ring-border',\n 'duration-300',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-right data-[state=open]:fade-in',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-right data-[state=closed]:fade-out'\n )}\n >\n <section className=\"relative flex size-full flex-col\">\n <header className=\"flex h-14 shrink-0 items-center border-b border-border px-5\">\n <h2 className=\"font-semibold text-base tracking-tight text-text-positive\">{title}</h2>\n </header>\n\n <div className={cn('flex flex-1 flex-col overflow-y-auto py-4', contentClassName)}>{children}</div>\n\n <div className=\"flex shrink-0 flex-col gap-2 border-t border-border px-4 py-3\">\n <form.Subscribe\n selector={state => ({\n isSubmitting: state.isSubmitting,\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit,\n })}\n children={({ isSubmitting, disabled }) => (\n <SubmitButton isSubmitting={isSubmitting} disabled={disabled} className=\"w-full\" onClick={() => form.handleSubmit()} />\n )}\n />\n <form.Subscribe\n selector={state => ({ disabled: state.isPristine || state.isSubmitting })}\n children={({ disabled }) => (\n <CancelButton\n disabled={disabled}\n className=\"w-full\"\n onClick={() => {\n form.reset();\n onOpenChange?.(false);\n }}\n />\n )}\n />\n </div>\n\n <DialogPrimitive.Close asChild>\n <CloseButton className=\"absolute top-2.5 right-3\" />\n </DialogPrimitive.Close>\n </section>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n};\n","'use client';\n\nimport { Separator } from '../ui/separator';\n\n/**\n * Internal header sub-component for `TanStackSectionForm` that renders a styled section title.\n */\nconst SectionHeader: React.FC<React.PropsWithChildren> = ({ children }) => {\n return (\n <header data-slot=\"section-header\" className=\"flex items-center px-4 py-3 font-semibold text-base text-text-positive tracking-tight\">\n {children}\n </header>\n );\n};\n\n/**\n * Internal body sub-component for `TanStackSectionForm` that wraps field content with vertical padding.\n */\nconst SectionMain: React.FC<React.PropsWithChildren> = ({ children }) => {\n return (\n <main data-slot=\"section-main\" className=\"relative flex flex-col py-4\">\n {children}\n </main>\n );\n};\n\n/**\n * Renders a card-like form section with a titled header, separator, and a content area for form fields.\n *\n * @example\n * import { TanStackSectionForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackSectionForm title=\"Account Settings\">\n * <EmailField />\n * <PasswordField />\n * </TanStackSectionForm>\n */\nexport const TanStackSectionForm: React.FC<\n React.PropsWithChildren<{\n /** Heading text displayed in the section header bar. */\n title: string;\n }>\n> = ({ title, children }) => {\n return (\n <section data-slot=\"section-form\" className=\"flex flex-col rounded-md bg-background shadow-card ring-1 ring-border\">\n <SectionHeader>{title}</SectionHeader>\n <Separator />\n <SectionMain>{children}</SectionMain>\n </section>\n );\n};\n","import { Field, FieldContent, FieldDescription, FieldGroup, FieldLegend, FieldNote, FieldSeparator } from '../ui/field';\n\n/**\n * Renders a standalone section title with an optional description and helper note, followed by a separator.\n *\n * @example\n * import { TanStackTitleField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackTitleField\n * title=\"Billing Address\"\n * description=\"Provide the address associated with your payment method.\"\n * helperText=\"Must match your bank records.\"\n * />\n */\nexport const TanStackTitleField: React.FC<{\n /** The heading text rendered as a legend element. */\n title: string;\n /** Optional supplementary text displayed beneath the title. */\n description?: string;\n /** Optional helper note shown below the description area. */\n helperText?: string;\n}> = ({ title, description, helperText }) => {\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field className=\"gap-0\">\n <FieldContent>\n <FieldLegend className=\"mb-1\">{title}</FieldLegend>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n","import { createFormHook, createFormHookContexts } from '@tanstack/react-form';\n\nimport { ArrayCol, ArrayHeaderRow, SimpleArrayField } from './components/atoms/simple-array-field';\nimport { SimpleBooleanField } from './components/atoms/simple-boolean-field';\nimport { SimpleComboboxField } from './components/atoms/simple-combobox-field';\nimport { SimpleDateField } from './components/atoms/simple-date-field';\nimport { SimpleRadioGroupField } from './components/atoms/simple-radio-group-field';\nimport { SimpleEmailField } from './components/atoms/simple-email-field';\nimport { SimpleNumberField } from './components/atoms/simple-number-field';\nimport { SimplePasswordField } from './components/atoms/simple-password-field';\nimport { SimpleSelectField } from './components/atoms/simple-select-field';\nimport { SimpleTextareaField } from './components/atoms/simple-textarea-field';\nimport { SimpleTextField } from './components/atoms/simple-text-field';\nimport { CheckboxField } from './components/fields/checkbox-field';\nimport { ComboboxField } from './components/fields/combobox-field';\nimport { DateField } from './components/fields/date-field';\nimport { EmailField } from './components/fields/email-field';\nimport { NumberField } from './components/fields/number-field';\nimport { PasswordField } from './components/fields/password-field';\nimport { RadioGroupField } from './components/fields/radio-group-field';\nimport { SelectField } from './components/fields/select-field';\nimport { SwitchField } from './components/fields/switch-field';\nimport { TextField } from './components/fields/text-field';\nimport { TextareaField } from './components/fields/textarea-field';\nimport { TextEditorField } from './components/fields/text-editor-field';\nimport { TanStackActionSubmit } from './components/forms/action-submit';\nimport { TanStackActionsForm } from './components/forms/actions-form';\nimport { TanStackCardForm } from './components/forms/card-form';\nimport { TanStackContainerForm } from './components/forms/container-form';\nimport { TanStackDialogForm } from './components/forms/dialog-form';\nimport { TanStackFieldGroup } from './components/forms/group-field';\nimport { TanStackPopoverForm } from './components/forms/popover-form';\nimport { TanStackSectionForm } from './components/forms/section-form';\nimport { TanStackTitleField } from './components/forms/title-field';\nimport { Field, FieldContent, FieldContentMain, FieldError, FieldGroup, FieldLabel, FieldSeparator } from './components/ui/field';\n\nconst { fieldContext, formContext, useFieldContext: useTanStackFieldContext, useFormContext: useTanStackFormContext } = createFormHookContexts();\n\n/**\n * Factory result from {@link createFormHook} pre-wired with all Lunas UI field and form components.\n *\n * ### `useTanStackForm`\n * Pre-configured TanStack Form hook that returns a type-safe form instance bound to all Lunas UI\n * field and form components.\n *\n * @example\n * import { useTanStackForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * const form = useTanStackForm({\n * defaultValues: { name: '', email: '' },\n * onSubmit: async ({ value }) => console.log(value),\n * });\n *\n * return (\n * <form.Provider>\n * <form.AppForm>\n * <form.AppField name=\"name\" children={(field) => <field.TextField label=\"Name\" />} />\n * <form.Subscribe selector={(s) => s.canSubmit}>\n * {(canSubmit) => <form.TanStackActionSubmit disabled={!canSubmit} />}\n * </form.Subscribe>\n * </form.AppForm>\n * </form.Provider>\n * );\n *\n * ### `withTanStackForm`\n * Higher-order component that wraps a sub-form component with access to the parent\n * `useTanStackForm` form context, enabling isolated field groups that still participate in the\n * top-level form state.\n *\n * @example\n * import { withTanStackForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * const AddressFields = withTanStackForm(\n * { street: '', city: '' } as const,\n * ({ form }) => (\n * <>\n * <form.AppField name=\"street\" children={(f) => <f.TextField label=\"Street\" />} />\n * <form.AppField name=\"city\" children={(f) => <f.TextField label=\"City\" />} />\n * </>\n * ),\n * );\n *\n * ### `withTanStackFieldGroup`\n * Higher-order component that creates a reusable field-group component sharing the enclosing\n * `useTanStackForm` context without requiring additional form providers.\n *\n * @example\n * import { withTanStackFieldGroup } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * const ContactGroup = withTanStackFieldGroup(({ form }) => (\n * <form.AppField name=\"phone\" children={(f) => <f.TextField label=\"Phone\" />} />\n * ));\n */\nconst {\n useAppForm: useTanStackForm,\n withForm: withTanStackForm,\n withFieldGroup: withTanStackFieldGroup,\n} = createFormHook({\n fieldContext,\n formContext,\n\n fieldComponents: {\n TextField,\n TextareaField,\n TextEditorField,\n NumberField,\n EmailField,\n PasswordField,\n\n SelectField,\n ComboboxField,\n DateField,\n SwitchField,\n RadioGroupField,\n CheckboxField,\n\n SimpleTextField,\n SimpleEmailField,\n SimplePasswordField,\n SimpleTextareaField,\n SimpleNumberField,\n SimpleSelectField,\n SimpleArrayField,\n SimpleBooleanField,\n SimpleComboboxField,\n SimpleDateField,\n SimpleRadioGroupField,\n\n FieldGroup,\n Field,\n FieldContent,\n FieldLabel,\n FieldContentMain,\n FieldSeparator,\n FieldError,\n },\n formComponents: {\n TanStackDialogForm,\n TanStackPopoverForm,\n TanStackContainerForm,\n TanStackSectionForm,\n TanStackCardForm,\n TanStackFieldGroup,\n TanStackTitleField,\n\n TanStackActionsForm,\n TanStackActionSubmit,\n\n ArrayCol,\n ArrayHeaderRow,\n },\n});\n\nexport {\n // Hooks & HOCs\n useTanStackForm,\n withTanStackForm,\n withTanStackFieldGroup,\n useTanStackFieldContext,\n useTanStackFormContext,\n // Form containers\n TanStackDialogForm,\n TanStackPopoverForm,\n TanStackContainerForm,\n TanStackSectionForm,\n TanStackCardForm,\n TanStackFieldGroup,\n TanStackTitleField,\n // Form actions\n TanStackActionsForm,\n TanStackActionSubmit,\n // Array helpers\n ArrayCol,\n ArrayHeaderRow,\n // Rich field components\n TextField,\n TextareaField,\n TextEditorField,\n NumberField,\n EmailField,\n PasswordField,\n SelectField,\n ComboboxField,\n DateField,\n SwitchField,\n RadioGroupField,\n CheckboxField,\n // Simple (minimal) field components\n SimpleTextField,\n SimpleEmailField,\n SimplePasswordField,\n SimpleTextareaField,\n SimpleNumberField,\n SimpleSelectField,\n SimpleArrayField,\n SimpleBooleanField,\n SimpleComboboxField,\n SimpleDateField,\n SimpleRadioGroupField,\n // Field UI primitives\n FieldGroup,\n Field,\n FieldContent,\n FieldContentMain,\n FieldLabel,\n FieldSeparator,\n FieldError,\n};\n"],"mappings":"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"}
|