@letar/forms 1.0.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +331 -0
- package/README.md +9 -9
- package/README.ru.md +389 -0
- package/analytics.js +3 -0
- package/analytics.js.map +1 -0
- package/chunk-2PSXYC3I.js +1782 -0
- package/chunk-2PSXYC3I.js.map +1 -0
- package/chunk-5D6S6EGF.js +206 -0
- package/chunk-5D6S6EGF.js.map +1 -0
- package/chunk-6E7VJAJT.js +78 -0
- package/chunk-6E7VJAJT.js.map +1 -0
- package/chunk-CGXKRCSM.js +117 -0
- package/chunk-CGXKRCSM.js.map +1 -0
- package/chunk-DQUVUMCX.js +982 -0
- package/chunk-DQUVUMCX.js.map +1 -0
- package/chunk-K3J4L26K.js +345 -0
- package/chunk-K3J4L26K.js.map +1 -0
- package/chunk-MAYUFA5K.js +822 -0
- package/chunk-MAYUFA5K.js.map +1 -0
- package/{chunk-4V6WBJ76.js → chunk-MVGXZNHP.js} +2 -2
- package/{chunk-4V6WBJ76.js.map → chunk-MVGXZNHP.js.map} +1 -1
- package/chunk-MZDTJSF7.js +299 -0
- package/chunk-MZDTJSF7.js.map +1 -0
- package/chunk-Q5EOF36Y.js +709 -0
- package/chunk-Q5EOF36Y.js.map +1 -0
- package/{chunk-7FEQFDJ7.js → chunk-R2RTCKXY.js} +2 -2
- package/{chunk-7FEQFDJ7.js.map → chunk-R2RTCKXY.js.map} +1 -1
- package/chunk-XFWLD5EO.js +1045 -0
- package/chunk-XFWLD5EO.js.map +1 -0
- package/fields/boolean.js +5 -0
- package/fields/boolean.js.map +1 -0
- package/fields/datetime.js +5 -0
- package/fields/datetime.js.map +1 -0
- package/fields/number.js +5 -0
- package/fields/number.js.map +1 -0
- package/fields/selection.js +5 -0
- package/fields/selection.js.map +1 -0
- package/fields/specialized.js +5 -0
- package/fields/specialized.js.map +1 -0
- package/fields/text.js +5 -0
- package/fields/text.js.map +1 -0
- package/hcaptcha-U4XIT3HS.js +64 -0
- package/hcaptcha-U4XIT3HS.js.map +1 -0
- package/i18n.js +1 -1
- package/index.js +3736 -4962
- package/index.js.map +1 -1
- package/offline.js +1 -1
- package/package.json +59 -4
- package/recaptcha-PKAUAY2S.js +56 -0
- package/recaptcha-PKAUAY2S.js.map +1 -0
- package/server-errors.js +3 -0
- package/server-errors.js.map +1 -0
- package/turnstile-7FXTBSLW.js +36 -0
- package/turnstile-7FXTBSLW.js.map +1 -0
- package/validators/ru.js +73 -0
- package/validators/ru.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/declarative/form-fields/selection/field-autocomplete.tsx","../src/lib/declarative/form-fields/selection/field-checkbox-card.tsx","../src/lib/declarative/form-fields/selection/field-combobox.tsx","../src/lib/declarative/form-fields/selection/field-listbox.tsx","../src/lib/declarative/form-fields/selection/field-native-select.tsx","../src/lib/declarative/form-fields/selection/field-radio-card.tsx","../src/lib/declarative/form-fields/selection/field-radio-group.tsx","../src/lib/declarative/form-fields/selection/field-segmented-group.tsx","../src/lib/declarative/form-fields/selection/field-select.tsx","../src/lib/declarative/form-fields/selection/field-tags.tsx","../src/lib/declarative/form-fields/selection/field-cascading-select.tsx"],"names":["jsxs","jsx","useFilter","useMemo","Field","Combobox","Spinner","Portal","createListCollection","Select"],"mappings":"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","file":"chunk-MAYUFA5K.js","sourcesContent":["'use client'\n\nimport { Combobox, createListCollection, Field, Portal, Spinner, useFilter } from '@chakra-ui/react'\nimport { type ReactElement, useMemo } from 'react'\nimport type { BaseFieldProps, FieldSize } from '../../types'\nimport { type AsyncQueryFn, createField, FieldError, SelectionFieldLabel, useAsyncSearch } from '../base'\n\n/**\n * Props for Form.Field.Autocomplete\n */\nexport interface AutocompleteFieldProps<TData = unknown> extends BaseFieldProps {\n /**\n * Static suggestions for autocomplete\n */\n suggestions?: string[]\n\n /**\n * Async function for loading suggestions\n * Should return { data, isLoading, error } similar to TanStack Query\n *\n * @example\n * ```tsx\n * useQuery={(search) => useFindManyCity({\n * where: { name: { contains: search, mode: 'insensitive' } },\n * take: 10,\n * })}\n * ```\n */\n useQuery?: AsyncQueryFn<TData>\n\n /**\n * Get label from data element\n * Required when using useQuery\n */\n getLabel?: (item: TData) => string\n\n /**\n * Debounce delay in milliseconds\n * @default 300\n */\n debounce?: number\n\n /**\n * Minimum characters to trigger suggestions\n * @default 1\n */\n minChars?: number\n\n /**\n * Component size\n * @default 'md'\n */\n size?: FieldSize\n\n /**\n * Visual variant\n * @default 'outline'\n */\n variant?: 'outline' | 'subtle' | 'flushed'\n\n /**\n * Message for empty result\n * @default \"No suggestions\"\n */\n emptyMessage?: string\n\n /**\n * Message on loading\n * @default \"Loading...\"\n */\n loadingMessage?: string\n}\n\n/**\n * Suggestion element\n */\ninterface AutocompleteItem {\n label: string\n value: string\n}\n\n/** State type for useFieldState */\ninterface AutocompleteFieldState {\n inputValue: string\n setInputValue: (value: string) => void\n isLoading: boolean\n suggestions: AutocompleteItem[]\n collection: ReturnType<typeof createListCollection<AutocompleteItem>>\n}\n\n/**\n * Form.Field.Autocomplete - Text input with suggestions\n *\n * Simplified version of Combobox that always allows custom values.\n * Ideal for city names, products or any free text input with suggestions.\n *\n * @example Static suggestions\n * ```tsx\n * <Form.Field.Autocomplete\n * name=\"city\"\n * label=\"City\"\n * suggestions={['Moscow', 'Saint Petersburg', 'Kazan', 'Novosibirsk']}\n * />\n * ```\n *\n * @example Async suggestions with ZenStack\n * ```tsx\n * <Form.Field.Autocomplete\n * name=\"product\"\n * label=\"Product\"\n * useQuery={(search) => useFindManyProduct({\n * where: { name: { contains: search, mode: 'insensitive' } },\n * take: 10,\n * })}\n * getLabel={(p) => p.name}\n * debounce={300}\n * minChars={2}\n * />\n * ```\n */\nexport const FieldAutocomplete = createField<AutocompleteFieldProps, string, AutocompleteFieldState>({\n displayName: 'FieldAutocomplete',\n useFieldState: (componentProps: Omit<AutocompleteFieldProps, keyof BaseFieldProps>): AutocompleteFieldState => {\n // Async search with debounce via shared hook\n const {\n inputValue,\n setInputValue,\n isLoading,\n data: queryData,\n } = useAsyncSearch({\n useQuery: componentProps.useQuery,\n debounce: componentProps.debounce ?? 300,\n minChars: componentProps.minChars ?? 1,\n })\n\n // Filter for static suggestions\n const { contains } = useFilter({ sensitivity: 'base' })\n\n // Build suggestions list\n const suggestions = useMemo((): AutocompleteItem[] => {\n if (componentProps.suggestions) {\n // Filtering static suggestions by input value\n const filtered = inputValue\n ? componentProps.suggestions.filter((s) => contains(s, inputValue))\n : componentProps.suggestions.slice(0, 10) // First 10 when input is empty\n return filtered.map((s) => ({ label: s, value: s }))\n }\n\n if (queryData && componentProps.getLabel) {\n const getLabel = componentProps.getLabel\n return (queryData as unknown[]).map((item) => {\n const itemLabel = getLabel(item)\n return { label: itemLabel, value: itemLabel }\n })\n }\n\n return []\n }, [componentProps.suggestions, queryData, componentProps.getLabel, inputValue, contains])\n\n // Create collection\n const collection = useMemo(() => {\n return createListCollection({\n items: suggestions,\n itemToString: (item) => item.label,\n itemToValue: (item) => item.value,\n })\n }, [suggestions])\n\n return {\n inputValue,\n setInputValue,\n isLoading,\n suggestions,\n collection,\n }\n },\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps, fieldState }): ReactElement => {\n const currentValue = (field.state.value as string) ?? ''\n const minChars = componentProps.minChars ?? 1\n\n return (\n <Field.Root\n invalid={hasError}\n required={resolved.required}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n >\n <Combobox.Root\n collection={fieldState.collection}\n size={componentProps.size ?? 'md'}\n variant={componentProps.variant ?? 'outline'}\n value={currentValue ? [currentValue] : []}\n inputValue={fieldState.inputValue}\n onInputValueChange={(details) => {\n fieldState.setInputValue(details.inputValue)\n // Always update field value (allowCustomValue behavior)\n field.handleChange(details.inputValue)\n }}\n onValueChange={(details) => {\n const newValue = details.value[0] ?? ''\n fieldState.setInputValue(newValue)\n field.handleChange(newValue)\n }}\n onInteractOutside={() => field.handleBlur()}\n disabled={resolved.disabled}\n allowCustomValue\n openOnClick\n data-field-name={fullPath}\n >\n {resolved.label && (\n <Combobox.Label>\n <SelectionFieldLabel label={resolved.label} tooltip={resolved.tooltip} required={resolved.required} />\n </Combobox.Label>\n )}\n\n <Combobox.Control>\n <Combobox.Input placeholder={resolved.placeholder ?? 'Start typing...'} />\n <Combobox.IndicatorGroup>\n {fieldState.isLoading && <Spinner size=\"xs\" />}\n <Combobox.Trigger />\n </Combobox.IndicatorGroup>\n </Combobox.Control>\n\n <Portal>\n <Combobox.Positioner>\n <Combobox.Content>\n {/* Loading state */}\n {fieldState.isLoading && fieldState.suggestions.length === 0 && (\n <Combobox.Empty>{componentProps.loadingMessage ?? 'Loading...'}</Combobox.Empty>\n )}\n\n {/* Empty result */}\n {!fieldState.isLoading &&\n fieldState.suggestions.length === 0 &&\n fieldState.inputValue.length >= minChars && (\n <Combobox.Empty>{componentProps.emptyMessage ?? 'No suggestions'}</Combobox.Empty>\n )}\n\n {/* Hint about minimum characters */}\n {!fieldState.isLoading &&\n fieldState.suggestions.length === 0 &&\n fieldState.inputValue.length < minChars &&\n fieldState.inputValue.length > 0 && (\n <Combobox.Empty>Enter at least {minChars} characters</Combobox.Empty>\n )}\n\n {/* Suggestions */}\n {fieldState.suggestions.map((item) => (\n <Combobox.Item item={item} key={item.value}>\n <Combobox.ItemText>{item.label}</Combobox.ItemText>\n <Combobox.ItemIndicator />\n </Combobox.Item>\n ))}\n </Combobox.Content>\n </Combobox.Positioner>\n </Portal>\n </Combobox.Root>\n\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n )\n },\n})\n","'use client'\n\nimport { CheckboxCard, CheckboxGroup, Fieldset, Flex, HStack } from '@chakra-ui/react'\nimport type { ReactElement } from 'react'\nimport type { BaseFieldProps, FieldSizeWithoutXs, FieldTooltipMeta, RichOption } from '../../types'\nimport { createField } from '../base'\nimport { FieldTooltip } from '../base/field-tooltip'\n\n/**\n * Props for CheckboxCard field\n */\nexport interface CheckboxCardFieldProps<T = string> extends Omit<BaseFieldProps, 'placeholder'> {\n /** Tooltip for field label */\n tooltip?: FieldTooltipMeta\n /** Options for cards */\n options: RichOption<T>[]\n /** Size (by default: md) */\n size?: FieldSizeWithoutXs\n /** Visual variant (by default: outline) */\n variant?: 'surface' | 'subtle' | 'outline' | 'solid'\n /** Color palette */\n colorPalette?: string\n /** Content alignment (by default: start) */\n align?: 'start' | 'end' | 'center'\n /** Orientation (by default: horizontal) */\n orientation?: 'horizontal' | 'vertical'\n /** Gap between cards (by default: 2) */\n gap?: number | string\n}\n\n/**\n * Form.Field.CheckboxCard - Multiple selection as cards\n *\n * Renders a group of checkbox cards for selecting multiple options.\n * Each card can have a label, description and icon.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field.CheckboxCard\n * name=\"features\"\n * label=\"Select features\"\n * options={[\n * { label: 'TypeScript', value: 'ts', description: 'Type safety' },\n * { label: 'ESLint', value: 'eslint', description: 'Code quality' },\n * { label: 'Prettier', value: 'prettier', description: 'Formatting' },\n * ]}\n * />\n * ```\n *\n * @example With icons\n * ```tsx\n * <Form.Field.CheckboxCard\n * name=\"permissions\"\n * options={[\n * { label: 'Admin', value: 'admin', icon: <ShieldIcon /> },\n * { label: 'User', value: 'user', icon: <UserIcon /> },\n * ]}\n * align=\"center\"\n * />\n * ```\n */\nexport const FieldCheckboxCard = createField<CheckboxCardFieldProps, string[]>({\n displayName: 'FieldCheckboxCard',\n render: ({ field, resolved, hasError, errorMessage, componentProps }): ReactElement => {\n // Value always array for checkbox cards\n const currentValue = field.state.value as string[] | undefined\n const valueArray: string[] = currentValue ?? []\n\n return (\n <Fieldset.Root invalid={hasError} disabled={resolved.disabled}>\n <CheckboxGroup\n value={valueArray}\n onValueChange={(value) => field.handleChange(value)}\n disabled={resolved.disabled}\n invalid={hasError}\n >\n {resolved.label && (\n <Fieldset.Legend mb={2}>\n {resolved.tooltip ? (\n <HStack gap={1}>\n <span>{resolved.label}</span>\n <FieldTooltip {...resolved.tooltip} />\n </HStack>\n ) : (\n resolved.label\n )}\n {resolved.required && (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n style={{ color: 'var(--chakra-colors-fg-error)', marginInlineStart: '1px' }}\n >\n *\n </span>\n )}\n </Fieldset.Legend>\n )}\n\n <Flex\n gap={componentProps.gap ?? 2}\n direction={(componentProps.orientation ?? 'horizontal') === 'vertical' ? 'column' : 'row'}\n wrap={(componentProps.orientation ?? 'horizontal') === 'horizontal' ? 'wrap' : undefined}\n >\n {componentProps.options.map((opt) => (\n <CheckboxCard.Root\n key={opt.value}\n value={opt.value}\n size={componentProps.size ?? 'md'}\n variant={componentProps.variant ?? 'outline'}\n colorPalette={componentProps.colorPalette}\n align={componentProps.align ?? 'start'}\n disabled={opt.disabled}\n >\n <CheckboxCard.HiddenInput />\n <CheckboxCard.Control>\n <CheckboxCard.Content>\n {opt.icon}\n <CheckboxCard.Label>{opt.label}</CheckboxCard.Label>\n {opt.description && <CheckboxCard.Description>{opt.description}</CheckboxCard.Description>}\n </CheckboxCard.Content>\n <CheckboxCard.Indicator />\n </CheckboxCard.Control>\n </CheckboxCard.Root>\n ))}\n </Flex>\n </CheckboxGroup>\n\n {hasError ? (\n <Fieldset.ErrorText>{errorMessage}</Fieldset.ErrorText>\n ) : (\n resolved.helperText && <Fieldset.HelperText>{resolved.helperText}</Fieldset.HelperText>\n )}\n </Fieldset.Root>\n )\n },\n})\n","'use client'\n\nimport { Combobox, Field, Portal, Spinner, useFilter } from '@chakra-ui/react'\nimport { type ReactElement, type ReactNode, useMemo } from 'react'\nimport type { BaseFieldProps, FieldSize, GroupableOption } from '../../types'\nimport {\n type AsyncQueryFn,\n createField,\n FieldError,\n getOptionLabel,\n type GroupedOptionsResult,\n type ResolvedFieldProps,\n SelectionFieldLabel,\n useAsyncSearch,\n useGroupedOptions,\n} from '../base'\n\n/**\n * Props for Form.Field.Combobox\n */\nexport interface ComboboxFieldProps<T = string, TData = unknown> extends BaseFieldProps {\n /**\n * Static options (mutually exclusive with useQuery)\n */\n options?: GroupableOption<T>[]\n\n /**\n * Async function for loading options\n * Should return { data, isLoading, error } similar to TanStack Query\n *\n * @example\n * ```tsx\n * useQuery={(search) => useFindManyUser({\n * where: { name: { contains: search, mode: 'insensitive' } },\n * take: 20,\n * })}\n * ```\n */\n useQuery?: AsyncQueryFn<TData>\n\n /**\n * Get label from data element\n * Required when using useQuery\n */\n getLabel?: (item: TData) => ReactNode\n\n /**\n * Get value from data element\n * Required when using useQuery\n */\n getValue?: (item: TData) => T\n\n /**\n * Get group key from data element\n * Optional, for grouping results\n */\n getGroup?: (item: TData) => string | undefined\n\n /**\n * Check if element is disabled\n */\n getDisabled?: (item: TData) => boolean\n\n /**\n * Debounce delay in milliseconds\n * @default 300\n */\n debounce?: number\n\n /**\n * Minimum characters to trigger search\n * @default 1\n */\n minChars?: number\n\n /**\n * Show clear button\n * Auto-determined from schema if not specified\n */\n clearable?: boolean\n\n /**\n * Allow custom values not from the list\n * @default false\n */\n allowCustomValue?: boolean\n\n /**\n * Component size\n */\n size?: FieldSize\n\n /**\n * Visual variant\n */\n variant?: 'outline' | 'subtle' | 'flushed'\n\n /**\n * Message for empty result\n * @default \"Nothing found\"\n */\n emptyMessage?: string\n\n /**\n * Message on loading\n * @default \"Loading...\"\n */\n loadingMessage?: string\n}\n\n/** State type for useFieldState */\ninterface ComboboxFieldState extends GroupedOptionsResult {\n inputValue: string\n setInputValue: (value: string) => void\n isLoading: boolean\n options: GroupableOption[]\n resolvedClearable: boolean\n}\n\n/**\n * Form.Field.Combobox - Async search select with debounce and grouping\n *\n * Supports both static options and async loading via TanStack Query hooks.\n *\n * @example Static options\n * ```tsx\n * <Form.Field.Combobox\n * name=\"framework\"\n * label=\"Framework\"\n * options={[\n * { label: 'React', value: 'react' },\n * { label: 'Vue', value: 'vue', group: 'Frontend' },\n * ]}\n * />\n * ```\n *\n * @example Async with ZenStack hooks\n * ```tsx\n * <Form.Field.Combobox\n * name=\"userId\"\n * label=\"User\"\n * useQuery={(search) => useFindManyUser({\n * where: { name: { contains: search, mode: 'insensitive' } },\n * take: 20,\n * })}\n * getLabel={(user) => user.name}\n * getValue={(user) => user.id}\n * getGroup={(user) => user.role}\n * debounce={300}\n * minChars={2}\n * />\n * ```\n */\nexport const FieldCombobox = createField<ComboboxFieldProps, string, ComboboxFieldState>({\n displayName: 'FieldCombobox',\n useFieldState: (\n componentProps: Omit<ComboboxFieldProps, keyof BaseFieldProps>,\n resolved: ResolvedFieldProps\n ): ComboboxFieldState => {\n // Async search with debounce via shared hook\n const {\n inputValue,\n setInputValue,\n isLoading,\n data: queryData,\n } = useAsyncSearch({\n useQuery: componentProps.useQuery,\n debounce: componentProps.debounce ?? 300,\n minChars: componentProps.minChars ?? 1,\n })\n\n // Filter for static options\n const { contains } = useFilter({ sensitivity: 'base' })\n\n // Build options from static or async source\n const options = useMemo((): GroupableOption[] => {\n if (componentProps.options) {\n // Filtering static options by input value\n if (!inputValue) {\n return componentProps.options\n }\n return componentProps.options.filter((opt) => {\n return contains(getOptionLabel(opt), inputValue)\n })\n }\n\n if (queryData && componentProps.getLabel && componentProps.getValue) {\n const getLabel = componentProps.getLabel\n const getValue = componentProps.getValue\n return (queryData as unknown[]).map((item) => ({\n label: getLabel(item),\n value: getValue(item),\n group: componentProps.getGroup?.(item),\n disabled: componentProps.getDisabled?.(item),\n }))\n }\n\n return []\n }, [\n componentProps.options,\n queryData,\n componentProps.getLabel,\n componentProps.getValue,\n componentProps.getGroup,\n componentProps.getDisabled,\n inputValue,\n contains,\n ])\n\n // Create collection with grouping via shared hook\n const { collection, groups } = useGroupedOptions(options)\n\n // Auto-determine clearable\n const resolvedClearable = componentProps.clearable ?? !resolved.required\n\n return {\n inputValue,\n setInputValue,\n isLoading,\n options,\n collection,\n groups,\n resolvedClearable,\n }\n },\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps, fieldState }): ReactElement => {\n const currentValue = field.state.value as string | undefined\n const minChars = componentProps.minChars ?? 1\n\n return (\n <Field.Root invalid={hasError} required={resolved.required} disabled={resolved.disabled}>\n <Combobox.Root\n collection={fieldState.collection}\n size={componentProps.size ?? 'md'}\n variant={componentProps.variant ?? 'outline'}\n value={currentValue ? [currentValue] : []}\n inputValue={fieldState.inputValue}\n onInputValueChange={(details) => fieldState.setInputValue(details.inputValue)}\n onValueChange={(details) => {\n const newValue = details.value[0] as string | undefined\n field.handleChange(newValue ?? '')\n }}\n onInteractOutside={() => field.handleBlur()}\n disabled={resolved.disabled}\n allowCustomValue={componentProps.allowCustomValue ?? false}\n openOnClick\n data-field-name={fullPath}\n >\n {resolved.label && (\n <Combobox.Label>\n <SelectionFieldLabel label={resolved.label} tooltip={resolved.tooltip} required={resolved.required} />\n </Combobox.Label>\n )}\n\n <Combobox.Control>\n <Combobox.Input placeholder={resolved.placeholder ?? 'Search...'} />\n <Combobox.IndicatorGroup>\n {fieldState.isLoading && <Spinner size=\"xs\" />}\n {fieldState.resolvedClearable && <Combobox.ClearTrigger />}\n <Combobox.Trigger />\n </Combobox.IndicatorGroup>\n </Combobox.Control>\n\n <Portal>\n <Combobox.Positioner>\n <Combobox.Content>\n {/* Loading state */}\n {fieldState.isLoading && fieldState.options.length === 0 && (\n <Combobox.Empty>{componentProps.loadingMessage ?? 'Loading...'}</Combobox.Empty>\n )}\n\n {/* Empty result */}\n {!fieldState.isLoading &&\n fieldState.options.length === 0 &&\n fieldState.inputValue.length >= minChars && (\n <Combobox.Empty>{componentProps.emptyMessage ?? 'Nothing found'}</Combobox.Empty>\n )}\n\n {/* Hint about minimum characters */}\n {!fieldState.isLoading &&\n fieldState.options.length === 0 &&\n fieldState.inputValue.length < minChars &&\n fieldState.inputValue.length > 0 && (\n <Combobox.Empty>Enter at least {minChars} characters</Combobox.Empty>\n )}\n\n {/* Grouped options */}\n {fieldState.groups\n ? Array.from(fieldState.groups.entries()).map(([groupName, groupOptions]) => (\n <Combobox.ItemGroup key={groupName}>\n {groupName && <Combobox.ItemGroupLabel>{groupName}</Combobox.ItemGroupLabel>}\n {groupOptions.map((opt) => (\n <Combobox.Item item={opt} key={opt.value}>\n <Combobox.ItemText>{getOptionLabel(opt)}</Combobox.ItemText>\n <Combobox.ItemIndicator />\n </Combobox.Item>\n ))}\n </Combobox.ItemGroup>\n ))\n : /* Flat options */\n fieldState.options.map((opt) => (\n <Combobox.Item item={opt} key={opt.value}>\n <Combobox.ItemText>{getOptionLabel(opt)}</Combobox.ItemText>\n <Combobox.ItemIndicator />\n </Combobox.Item>\n ))}\n </Combobox.Content>\n </Combobox.Positioner>\n </Portal>\n </Combobox.Root>\n\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n )\n },\n})\n","'use client'\n\nimport { Field, Listbox } from '@chakra-ui/react'\nimport type { ReactElement } from 'react'\nimport type { BaseFieldProps, FieldSizeWithoutXs, GroupableOption } from '../../types'\nimport {\n createField,\n FieldError,\n getOptionLabel,\n type GroupedOptionsResult,\n SelectionFieldLabel,\n useGroupedOptions,\n} from '../base'\n\n/**\n * Props for Listbox field\n */\nexport interface ListboxFieldProps<T = string> extends Omit<BaseFieldProps, 'placeholder'> {\n /** Options for listbox */\n options: GroupableOption<T>[]\n /**\n * Selection mode\n * - `single`: Single selection (by default)\n * - `multiple`: Multiple selection\n */\n selectionMode?: 'single' | 'multiple'\n /** Size */\n size?: FieldSizeWithoutXs\n /** Visual variant */\n variant?: 'subtle' | 'solid' | 'plain'\n /** Color palette */\n colorPalette?: string\n /** Element orientation (by default: vertical) */\n orientation?: 'horizontal' | 'vertical'\n /** Maximum height for scrolling */\n maxHeight?: string | number\n}\n\n/** State type for useFieldState */\ntype ListboxFieldState = GroupedOptionsResult\n\n/**\n * Form.Field.Listbox - Selection list with visible options\n *\n * Unlike Select/Combobox which use dropdown, Listbox shows\n * all options directly in the form. Well suited for short lists (2-8 elements)\n * where all options should be visible.\n *\n * @example Single selection\n * ```tsx\n * <Form.Field.Listbox\n * name=\"framework\"\n * label=\"Framework\"\n * options={[\n * { label: 'React', value: 'react' },\n * { label: 'Vue', value: 'vue' },\n * { label: 'Angular', value: 'angular' },\n * ]}\n * />\n * ```\n *\n * @example Multiple selection\n * ```tsx\n * <Form.Field.Listbox\n * name=\"features\"\n * label=\"Features\"\n * selectionMode=\"multiple\"\n * options={[\n * { label: 'TypeScript', value: 'ts' },\n * { label: 'Testing', value: 'test' },\n * { label: 'Linting', value: 'lint' },\n * ]}\n * />\n * ```\n *\n * @example With groups\n * ```tsx\n * <Form.Field.Listbox\n * name=\"language\"\n * options={[\n * { label: 'TypeScript', value: 'ts', group: 'Frontend' },\n * { label: 'Python', value: 'py', group: 'Backend' },\n * ]}\n * />\n * ```\n */\nexport const FieldListbox = createField<ListboxFieldProps, string | string[], ListboxFieldState>({\n displayName: 'FieldListbox',\n useFieldState: (componentProps): ListboxFieldState => {\n // Use shared hook for grouping options\n return useGroupedOptions(componentProps.options)\n },\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps, fieldState }): ReactElement => {\n // Handle single vs multiple values\n const currentValue = field.state.value as string | string[] | undefined\n const valueArray: string[] = Array.isArray(currentValue) ? currentValue : currentValue ? [currentValue] : []\n const selectionMode = componentProps.selectionMode ?? 'single'\n\n return (\n <Field.Root\n invalid={hasError}\n required={resolved.required}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n >\n <Listbox.Root\n collection={fieldState.collection}\n selectionMode={selectionMode}\n orientation={componentProps.orientation ?? 'vertical'}\n variant={componentProps.variant ?? 'subtle'}\n colorPalette={componentProps.colorPalette}\n value={valueArray}\n onValueChange={(details) => {\n if (selectionMode === 'single') {\n // Single mode: save single value or empty string\n const newValue = details.value[0] as string | undefined\n field.handleChange(newValue ?? '')\n } else {\n // Multiple mode: save array\n field.handleChange(details.value)\n }\n }}\n disabled={resolved.disabled}\n data-field-name={fullPath}\n >\n {resolved.label && (\n <Listbox.Label fontSize={componentProps.size ?? 'md'}>\n <SelectionFieldLabel label={resolved.label} tooltip={resolved.tooltip} required={resolved.required} />\n </Listbox.Label>\n )}\n\n <Listbox.Content maxH={componentProps.maxHeight}>\n {fieldState.groups\n ? /* Grouped options */\n Array.from(fieldState.groups.entries()).map(([groupName, groupOptions]) => (\n <Listbox.ItemGroup key={groupName}>\n {groupName && <Listbox.ItemGroupLabel>{groupName}</Listbox.ItemGroupLabel>}\n {groupOptions.map((opt) => (\n <Listbox.Item item={opt} key={opt.value}>\n <Listbox.ItemText>{getOptionLabel(opt)}</Listbox.ItemText>\n <Listbox.ItemIndicator />\n </Listbox.Item>\n ))}\n </Listbox.ItemGroup>\n ))\n : /* Flat options */\n componentProps.options.map((opt) => (\n <Listbox.Item item={opt} key={opt.value}>\n <Listbox.ItemText>{getOptionLabel(opt)}</Listbox.ItemText>\n <Listbox.ItemIndicator />\n </Listbox.Item>\n ))}\n </Listbox.Content>\n </Listbox.Root>\n\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n )\n },\n})\n","'use client'\n\nimport { NativeSelect } from '@chakra-ui/react'\nimport type { ReactElement } from 'react'\nimport type { BaseFieldProps, NativeSelectOption } from '../../types'\nimport { createField, FieldWrapper } from '../base'\n\n// Re-export for backward compatibility\nexport type { NativeSelectOption } from '../../types'\n\nexport interface NativeSelectFieldProps<T = string> extends BaseFieldProps {\n options: NativeSelectOption<T>[]\n}\n\n/**\n * Form.Field.NativeSelect - Native browser select dropdown\n *\n * Renders a Chakra NativeSelect with automatic form integration and error display.\n * Uses native browser select for best mobile UX (shows system picker on iOS/Android).\n *\n * @example\n * ```tsx\n * <Form.Field.NativeSelect\n * name=\"type\"\n * label=\"Type\"\n * options={[\n * { title: 'Option 1', value: 'opt1' },\n * { title: 'Option 2', value: 'opt2' },\n * ]}\n * />\n * ```\n */\nexport const FieldNativeSelect = createField<NativeSelectFieldProps, string>({\n displayName: 'FieldNativeSelect',\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }): ReactElement => (\n <FieldWrapper resolved={resolved} hasError={hasError} errorMessage={errorMessage} fullPath={fullPath}>\n <NativeSelect.Root>\n <NativeSelect.Field\n value={(field.state.value as string) ?? ''}\n onChange={(e) => field.handleChange((e.target as HTMLSelectElement).value)}\n onBlur={field.handleBlur}\n data-field-name={fullPath}\n >\n {resolved.placeholder && (\n <option value=\"\" disabled>\n {resolved.placeholder}\n </option>\n )}\n {componentProps.options.map((opt, idx) => (\n <option key={idx} value={opt.value}>\n {typeof opt.title === 'string' ? opt.title : opt.value}\n </option>\n ))}\n </NativeSelect.Field>\n <NativeSelect.Indicator />\n </NativeSelect.Root>\n </FieldWrapper>\n ),\n})\n","'use client'\n\nimport { Field, RadioCard } from '@chakra-ui/react'\nimport { type KeyboardEvent, type ReactElement, useCallback } from 'react'\nimport type { BaseFieldProps, FieldSizeWithoutXs, FieldTooltipMeta, RichOption } from '../../types'\nimport { createField, FieldError, SelectionFieldLabel } from '../base'\n\n/**\n * Props for RadioCard field\n */\nexport interface RadioCardFieldProps<T = string> extends Omit<BaseFieldProps, 'placeholder'> {\n /** Tooltip for field label */\n tooltip?: FieldTooltipMeta\n /** Options for cards */\n options: RichOption<T>[]\n /** Size (by default: md) */\n size?: FieldSizeWithoutXs\n /** Visual variant (by default: outline) */\n variant?: 'surface' | 'subtle' | 'outline' | 'solid'\n /** Color palette */\n colorPalette?: string\n /** Content alignment (by default: start) */\n align?: 'start' | 'end' | 'center'\n /** Orientation (by default: horizontal) */\n orientation?: 'horizontal' | 'vertical'\n /** Gap between cards (by default: 2) */\n gap?: number | string\n /** Enable enhanced keyboard navigation with cycling (by default: false) */\n keyboardNavigation?: boolean\n}\n\n/** State type for useFieldState */\ninterface RadioCardFieldState {\n enabledOptions: RichOption[]\n handleKeyDown: (\n e: KeyboardEvent<HTMLDivElement>,\n currentValue: string | undefined,\n handleChange: (value: string) => void\n ) => void\n}\n\n/**\n * Form.Field.RadioCard - Single selection as cards\n *\n * Renders a group of radio cards for selecting one option.\n * Each card can have a label, description and icon.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field.RadioCard\n * name=\"plan\"\n * label=\"Select plan\"\n * options={[\n * { label: 'Free', value: 'free', description: 'Basic features' },\n * { label: 'Pro', value: 'pro', description: 'All features' },\n * { label: 'Enterprise', value: 'enterprise', description: 'Customization' },\n * ]}\n * />\n * ```\n *\n * @example With icons\n * ```tsx\n * <Form.Field.RadioCard\n * name=\"role\"\n * options={[\n * { label: 'Admin', value: 'admin', icon: <ShieldIcon /> },\n * { label: 'User', value: 'user', icon: <UserIcon /> },\n * ]}\n * align=\"center\"\n * />\n * ```\n */\nexport const FieldRadioCard = createField<RadioCardFieldProps, string, RadioCardFieldState>({\n displayName: 'FieldRadioCard',\n useFieldState: (componentProps): RadioCardFieldState => {\n // Get only enabled options for keyboard navigation\n const enabledOptions = componentProps.options.filter((opt) => !opt.disabled)\n\n // Handle keyboard navigation with cycling\n const handleKeyDown = useCallback(\n (\n e: KeyboardEvent<HTMLDivElement>,\n currentValue: string | undefined,\n handleChange: (value: string) => void\n ): void => {\n if (!componentProps.keyboardNavigation || enabledOptions.length === 0) {\n return\n }\n\n const isHorizontal = (componentProps.orientation ?? 'horizontal') === 'horizontal'\n const prevKey = isHorizontal ? 'ArrowLeft' : 'ArrowUp'\n const nextKey = isHorizontal ? 'ArrowRight' : 'ArrowDown'\n\n if (e.key !== prevKey && e.key !== nextKey) {\n return\n }\n\n e.preventDefault()\n\n const currentIndex = currentValue ? enabledOptions.findIndex((opt) => opt.value === currentValue) : -1\n\n let newIndex: number\n\n if (e.key === nextKey) {\n // Forward (cycle to first if at end)\n newIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % enabledOptions.length\n } else {\n // Back (cycle to last if at beginning)\n newIndex =\n currentIndex === -1\n ? enabledOptions.length - 1\n : (currentIndex - 1 + enabledOptions.length) % enabledOptions.length\n }\n\n handleChange(enabledOptions[newIndex].value)\n },\n [componentProps.keyboardNavigation, enabledOptions, componentProps.orientation]\n )\n\n return { enabledOptions, handleKeyDown }\n },\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps, fieldState }): ReactElement => {\n const currentValue = field.state.value as string | undefined\n\n return (\n <Field.Root\n invalid={hasError}\n required={resolved.required}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n >\n <RadioCard.Root\n value={currentValue ?? ''}\n onValueChange={(details) => field.handleChange(details.value)}\n onKeyDown={\n componentProps.keyboardNavigation\n ? (e) => fieldState.handleKeyDown(e, currentValue, field.handleChange)\n : undefined\n }\n disabled={resolved.disabled}\n name={fullPath}\n size={componentProps.size ?? 'md'}\n variant={componentProps.variant ?? 'outline'}\n colorPalette={componentProps.colorPalette}\n align={componentProps.align ?? 'start'}\n orientation={componentProps.orientation ?? 'horizontal'}\n gap={componentProps.gap ?? 2}\n >\n {resolved.label && (\n <RadioCard.Label>\n <SelectionFieldLabel label={resolved.label} tooltip={resolved.tooltip} required={resolved.required} />\n </RadioCard.Label>\n )}\n\n {componentProps.options.map((opt) => (\n <RadioCard.Item key={opt.value} value={opt.value} disabled={opt.disabled}>\n <RadioCard.ItemHiddenInput />\n <RadioCard.ItemControl>\n <RadioCard.ItemContent>\n {opt.icon}\n <RadioCard.ItemText>{opt.label}</RadioCard.ItemText>\n {opt.description && <RadioCard.ItemDescription>{opt.description}</RadioCard.ItemDescription>}\n </RadioCard.ItemContent>\n <RadioCard.ItemIndicator />\n </RadioCard.ItemControl>\n </RadioCard.Item>\n ))}\n </RadioCard.Root>\n\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n )\n },\n})\n","'use client'\n\nimport { Field, RadioGroup } from '@chakra-ui/react'\nimport type { ReactElement } from 'react'\nimport type { BaseFieldProps, BaseOption, FieldSize } from '../../types'\nimport { createField, FieldError, FieldLabel, getOptionLabel } from '../base'\n\n/**\n * Props for RadioGroup field\n */\nexport interface RadioGroupFieldProps<T = string> extends Omit<BaseFieldProps, 'placeholder'> {\n /** Options for radio group */\n options: BaseOption<T>[]\n /** Orientation (by default: vertical) */\n orientation?: 'horizontal' | 'vertical'\n /** Size */\n size?: FieldSize\n /** Visual variant */\n variant?: 'outline' | 'subtle' | 'solid'\n /** Color palette */\n colorPalette?: string\n}\n\n/**\n * Form.Field.RadioGroup - Radio button group for single selection\n *\n * Renders a radio button group for mutually exclusive options.\n * Use Select for long lists, RadioGroup for short ones (2-5 options).\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field.RadioGroup\n * name=\"size\"\n * label=\"Size\"\n * options={[\n * { label: 'Small', value: 'sm' },\n * { label: 'Medium', value: 'md' },\n * { label: 'Large', value: 'lg' },\n * ]}\n * />\n * ```\n *\n * @example Horizontal layout\n * ```tsx\n * <Form.Field.RadioGroup\n * name=\"priority\"\n * orientation=\"horizontal\"\n * options={[\n * { label: 'Low', value: 'low' },\n * { label: 'Medium', value: 'medium' },\n * { label: 'High', value: 'high' },\n * ]}\n * />\n * ```\n */\nexport const FieldRadioGroup = createField<RadioGroupFieldProps, string>({\n displayName: 'FieldRadioGroup',\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }): ReactElement => (\n <Field.Root\n invalid={hasError}\n required={resolved.required}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n >\n <FieldLabel label={resolved.label} tooltip={resolved.tooltip} required={resolved.required} />\n <RadioGroup.Root\n value={(field.state.value as string) ?? undefined}\n onValueChange={(details) => field.handleChange(details.value)}\n orientation={componentProps.orientation ?? 'vertical'}\n size={componentProps.size ?? 'md'}\n variant={componentProps.variant ?? 'solid'}\n colorPalette={componentProps.colorPalette ?? 'brand'}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n data-field-name={fullPath}\n display=\"flex\"\n flexDirection={componentProps.orientation === 'horizontal' ? 'row' : 'column'}\n gap={componentProps.orientation === 'horizontal' ? 4 : 2}\n flexWrap=\"wrap\"\n >\n {componentProps.options.map((opt) => (\n <RadioGroup.Item key={opt.value} value={opt.value} disabled={opt.disabled}>\n <RadioGroup.ItemHiddenInput onBlur={field.handleBlur} />\n <RadioGroup.ItemIndicator />\n <RadioGroup.ItemText>{getOptionLabel(opt)}</RadioGroup.ItemText>\n </RadioGroup.Item>\n ))}\n </RadioGroup.Root>\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n ),\n})\n","'use client'\n\nimport { Field, SegmentGroup } from '@chakra-ui/react'\nimport type { ReactElement } from 'react'\nimport type { BaseFieldProps, BaseOption, FieldSize } from '../../types'\nimport { createField, FieldError, FieldLabel } from '../base'\n\n/**\n * Props for SegmentedGroup field\n */\nexport interface SegmentedGroupFieldProps<T = string> extends Omit<BaseFieldProps, 'placeholder'> {\n /** Options for segmented control */\n options: BaseOption<T>[]\n /** Size (by default: md) */\n size?: FieldSize\n /** Orientation (by default: horizontal) */\n orientation?: 'horizontal' | 'vertical'\n /** Color palette */\n colorPalette?: string\n}\n\n/**\n * Form.Field.SegmentedGroup - Segmented control for single selection\n *\n * Renders a segmented control for selecting one option from a set.\n * Similar to radio buttons but styled as connected segments.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field.SegmentedGroup\n * name=\"size\"\n * label=\"Size\"\n * options={[\n * { label: 'S', value: 'sm' },\n * { label: 'M', value: 'md' },\n * { label: 'L', value: 'lg' },\n * ]}\n * />\n * ```\n *\n * @example Different sizes\n * ```tsx\n * <Form.Field.SegmentedGroup\n * name=\"billing\"\n * options={[\n * { label: 'Monthly', value: 'monthly' },\n * { label: 'Yearly', value: 'yearly' },\n * ]}\n * size=\"sm\"\n * />\n * ```\n */\nexport const FieldSegmentedGroup = createField<SegmentedGroupFieldProps, string>({\n displayName: 'FieldSegmentedGroup',\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }): ReactElement => (\n <Field.Root\n invalid={hasError}\n required={resolved.required}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n >\n <FieldLabel label={resolved.label} tooltip={resolved.tooltip} required={resolved.required} />\n <SegmentGroup.Root\n value={(field.state.value as string) ?? ''}\n onValueChange={(details) => field.handleChange(details.value)}\n disabled={resolved.disabled}\n name={fullPath}\n size={componentProps.size ?? 'md'}\n orientation={componentProps.orientation ?? 'horizontal'}\n colorPalette={componentProps.colorPalette}\n >\n <SegmentGroup.Indicator />\n {componentProps.options.map((opt) => (\n <SegmentGroup.Item key={opt.value} value={opt.value} disabled={opt.disabled}>\n <SegmentGroup.ItemText>{opt.label}</SegmentGroup.ItemText>\n <SegmentGroup.ItemHiddenInput />\n </SegmentGroup.Item>\n ))}\n </SegmentGroup.Root>\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n ),\n})\n","'use client'\n\nimport { createListCollection, Field, Portal, Select } from '@chakra-ui/react'\nimport { type ReactElement, useMemo } from 'react'\nimport type { BaseFieldProps, BaseOption, FieldSize } from '../../types'\nimport { createField, FieldError, getOptionLabel, type ResolvedFieldProps, SelectionFieldLabel } from '../base'\n\n/** Normalized option (value is always string for Chakra) */\ninterface NormalizedOption {\n label: React.ReactNode\n value: string\n disabled?: boolean\n}\n\n/**\n * Props for Select field\n */\nexport interface SelectFieldProps extends BaseFieldProps {\n /** Options for selection (string or number values). If not specified, taken from schema meta */\n options?: BaseOption<string | number>[]\n /** Value type: 'string' (by default) or 'number' */\n valueType?: 'string' | 'number'\n /** Show clear button (auto-determined: true if optional, false if required) */\n clearable?: boolean\n /** Size */\n size?: FieldSize\n /** Visual variant */\n variant?: 'outline' | 'subtle'\n}\n\n/** State type for useFieldState */\ninterface SelectFieldState {\n collection: ReturnType<typeof createListCollection<NormalizedOption>>\n normalizedOptions: NormalizedOption[]\n resolvedClearable: boolean\n}\n\n/**\n * Form.Field.Select - Styled Chakra Select dropdown\n *\n * Styled select component with customizable appearance,\n * animations and advanced features (search, clear, custom rendering).\n *\n * For simple cases or better mobile UX use Form.Field.NativeSelect.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field.Select\n * name=\"framework\"\n * label=\"Framework\"\n * options={[\n * { label: 'React', value: 'react' },\n * { label: 'Vue', value: 'vue' },\n * { label: 'Angular', value: 'angular', disabled: true },\n * ]}\n * clearable\n * />\n * ```\n */\nexport const FieldSelect = createField<SelectFieldProps, string | number, SelectFieldState>({\n displayName: 'FieldSelect',\n useFieldState: (\n componentProps: Omit<SelectFieldProps, keyof BaseFieldProps>,\n resolved: ResolvedFieldProps\n ): SelectFieldState => {\n // Options: props take priority, fallback to schema meta\n const sourceOptions = componentProps.options ?? resolved.options ?? []\n\n // Normalize options — value always string for Chakra\n const normalizedOptions: NormalizedOption[] = useMemo(\n () =>\n sourceOptions.map((opt) => ({\n label: opt.label,\n value: String(opt.value),\n disabled: opt.disabled,\n })),\n [sourceOptions]\n )\n\n // Create collection from normalized options\n const collection = useMemo(\n () =>\n createListCollection({\n items: normalizedOptions,\n itemToString: getOptionLabel,\n itemToValue: (item) => item.value,\n }),\n [normalizedOptions]\n )\n\n // Auto-determine clearable: show clear button if field is optional\n const resolvedClearable = componentProps.clearable ?? !resolved.required\n\n return { collection, normalizedOptions, resolvedClearable }\n },\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps, fieldState }): ReactElement => {\n // Convert current value to string for Chakra\n const currentValue = field.state.value\n const stringValue = currentValue !== null && currentValue !== undefined ? String(currentValue) : undefined\n\n return (\n <Field.Root invalid={hasError} required={resolved.required} disabled={resolved.disabled}>\n <Select.Root\n collection={fieldState.collection}\n size={componentProps.size ?? 'md'}\n variant={componentProps.variant ?? 'outline'}\n value={stringValue ? [stringValue] : []}\n onValueChange={(details) => {\n const newStringValue = details.value[0] as string | undefined\n // Convert back to needed type\n if (componentProps.valueType === 'number') {\n field.handleChange(newStringValue ? Number(newStringValue) : 0)\n } else {\n field.handleChange(newStringValue ?? '')\n }\n }}\n onInteractOutside={() => field.handleBlur()}\n disabled={resolved.disabled}\n data-field-name={fullPath}\n >\n <Select.HiddenSelect />\n {resolved.label && (\n <Select.Label>\n <SelectionFieldLabel label={resolved.label} tooltip={resolved.tooltip} required={resolved.required} />\n </Select.Label>\n )}\n <Select.Control>\n <Select.Trigger>\n <Select.ValueText placeholder={resolved.placeholder} />\n </Select.Trigger>\n <Select.IndicatorGroup>\n {fieldState.resolvedClearable && <Select.ClearTrigger />}\n <Select.Indicator />\n </Select.IndicatorGroup>\n </Select.Control>\n <Portal>\n <Select.Positioner>\n <Select.Content>\n {fieldState.normalizedOptions.map((opt) => (\n <Select.Item item={opt} key={opt.value}>\n {getOptionLabel(opt)}\n <Select.ItemIndicator />\n </Select.Item>\n ))}\n </Select.Content>\n </Select.Positioner>\n </Portal>\n </Select.Root>\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n )\n },\n})\n","'use client'\n\nimport { Field, TagsInput } from '@chakra-ui/react'\nimport type { ReactElement } from 'react'\nimport type { BaseFieldProps, FieldTooltipMeta } from '../../types'\nimport { createField, FieldError, SelectionFieldLabel } from '../base'\n\n/**\n * Props for Form.Field.Tags\n */\nexport interface TagsFieldProps extends BaseFieldProps {\n /** Tooltip for field label */\n tooltip?: FieldTooltipMeta\n /** Maximum number of tags */\n maxTags?: number\n /** Minimum length of each tag (by default: 1) */\n minTagLength?: number\n /** Custom delimiter (regex or string). Default: Enter */\n delimiter?: RegExp | string\n /** Add tags on blur (by default: false) */\n addOnBlur?: boolean\n /** Add tags on paste (by default: true) */\n addOnPaste?: boolean\n /** Allow editing tags on click (by default: false) */\n editable?: boolean\n /** Show clear button (by default: false) */\n clearable?: boolean\n /** Size (by default: md) */\n size?: 'xs' | 'sm' | 'md' | 'lg'\n /** Visual variant (by default: outline) */\n variant?: 'outline' | 'subtle' | 'flushed'\n /** Color palette for tags */\n colorPalette?: string\n}\n\n/**\n * Form.Field.Tags - Tags input field\n *\n * Renders input for adding/removing string tags.\n * Integrates with Chakra UI TagsInput component.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field.Tags name=\"tags\" label=\"Tags\" placeholder=\"Add tag...\" />\n * ```\n *\n * @example With constraints\n * ```tsx\n * <Form.Field.Tags\n * name=\"categories\"\n * label=\"Categories\"\n * maxTags={5}\n * minTagLength={2}\n * helperText=\"Up to 5 categories\"\n * />\n * ```\n *\n * @example With custom delimiter\n * ```tsx\n * <Form.Field.Tags\n * name=\"emails\"\n * label=\"Email addresses\"\n * delimiter={/[;,\\s]/}\n * addOnPaste\n * />\n * ```\n *\n * @example Editable tags\n * ```tsx\n * <Form.Field.Tags\n * name=\"tags\"\n * label=\"Tags\"\n * editable\n * clearable\n * />\n * ```\n */\nexport const FieldTags = createField<TagsFieldProps, string[]>({\n displayName: 'FieldTags',\n\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }): ReactElement => {\n const {\n maxTags,\n minTagLength = 1,\n delimiter,\n addOnBlur = false,\n addOnPaste = true,\n editable = false,\n clearable = false,\n size = 'md',\n variant = 'outline',\n colorPalette,\n } = componentProps\n\n const value = (field.state.value as string[]) ?? []\n\n const handleValueChange = (details: { value: string[] }) => {\n field.handleChange(details.value)\n }\n\n const validateTag = (details: { inputValue: string }) => {\n return details.inputValue.length >= minTagLength\n }\n\n return (\n <Field.Root\n invalid={hasError}\n required={resolved.required}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n >\n <TagsInput.Root\n value={value}\n onValueChange={handleValueChange}\n max={maxTags}\n validate={validateTag}\n delimiter={delimiter}\n blurBehavior={addOnBlur ? 'add' : undefined}\n addOnPaste={addOnPaste}\n editable={editable}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n size={size}\n variant={variant}\n colorPalette={colorPalette}\n data-field-name={fullPath}\n >\n {resolved.label && (\n <TagsInput.Label>\n <SelectionFieldLabel label={resolved.label} tooltip={resolved.tooltip} required={resolved.required} />\n </TagsInput.Label>\n )}\n\n <TagsInput.Control>\n <TagsInput.Items />\n <TagsInput.Input placeholder={resolved.placeholder} onBlur={field.handleBlur} />\n {clearable && <TagsInput.ClearTrigger />}\n </TagsInput.Control>\n\n <TagsInput.HiddenInput />\n </TagsInput.Root>\n\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n )\n },\n})\n","'use client'\n\nimport { createListCollection, Field, Portal, Select, Spinner } from '@chakra-ui/react'\nimport { type ReactElement, useEffect, useMemo, useRef, useState } from 'react'\nimport { useFormGroup } from '../../../form-group'\nimport { useDeclarativeForm } from '../../form-context'\nimport type { BaseFieldProps, BaseOption, FieldSize } from '../../types'\nimport { FieldError, getFieldErrors, getOptionLabel, type ResolvedFieldProps, SelectionFieldLabel } from '../base'\nimport { useResolvedFieldProps } from '../base/use-resolved-field-props'\n\n/**\n * Options loading result\n */\nexport interface CascadingSelectLoadResult<T = string> {\n /** Loaded options */\n options: BaseOption<T>[]\n}\n\n/**\n * Props for CascadingSelect field\n */\nexport interface CascadingSelectFieldProps<TParent = string, TValue = string> extends BaseFieldProps {\n /**\n * Parent field name that this select depends on\n * @example \"country\" - load cities on country change\n */\n dependsOn: string\n /**\n * Function to load options when parent field changes\n * @param parentValue - Current value of the parent field\n * @returns Promise with options array or object with options\n */\n loadOptions: (\n parentValue: TParent | undefined\n ) => Promise<BaseOption<TValue>[]> | Promise<CascadingSelectLoadResult<TValue>>\n /**\n * Initial options (shown before parent value is selected)\n * @default []\n */\n initialOptions?: BaseOption<TValue>[]\n /**\n * Automatically clear value when parent changes\n * @default true\n */\n clearOnParentChange?: boolean\n /**\n * Disable field while parent is empty\n * @default true\n */\n disableWhenParentEmpty?: boolean\n /**\n * Show clear button (auto-determined: true if optional, false if required)\n */\n clearable?: boolean\n /**\n * Component size\n */\n size?: FieldSize\n /**\n * Visual variant\n */\n variant?: 'outline' | 'subtle'\n /**\n * Placeholder when parent value is empty\n */\n placeholderWhenDisabled?: string\n}\n\n/**\n * Internal component for rendering Select with loaded options\n */\ninterface CascadingSelectContentProps<TParent, TValue> {\n parentValue: TParent | undefined\n form: ReturnType<typeof useDeclarativeForm>['form']\n fullPath: string\n resolved: ResolvedFieldProps\n loadOptions: CascadingSelectFieldProps<TParent, TValue>['loadOptions']\n initialOptions: BaseOption<TValue>[]\n clearOnParentChange: boolean\n disableWhenParentEmpty: boolean\n clearable?: boolean\n size: FieldSize\n variant: 'outline' | 'subtle'\n placeholderWhenDisabled?: string\n}\n\nfunction CascadingSelectContent<TParent = string, TValue = string>({\n parentValue,\n form,\n fullPath,\n resolved,\n loadOptions,\n initialOptions,\n clearOnParentChange,\n disableWhenParentEmpty,\n clearable,\n size,\n variant,\n placeholderWhenDisabled,\n}: CascadingSelectContentProps<TParent, TValue>): ReactElement {\n // Options state and loading\n const [options, setOptions] = useState<BaseOption<TValue>[]>(initialOptions)\n const [isLoading, setIsLoading] = useState(false)\n\n // Ref for tracking previous parent value\n const prevParentValueRef = useRef<TParent | undefined>(parentValue)\n\n // Ref for stable loadOptions reference (avoid infinite loops with inline functions)\n const loadOptionsRef = useRef(loadOptions)\n loadOptionsRef.current = loadOptions\n\n // Effect for loading options when parentValue changes\n useEffect(() => {\n // Loading function\n const doLoad = async () => {\n if (parentValue === undefined || parentValue === null || parentValue === '') {\n setOptions(initialOptions)\n return\n }\n\n setIsLoading(true)\n try {\n const result = await loadOptionsRef.current(parentValue)\n // Support both formats: array or object with options\n const newOptions = Array.isArray(result) ? result : result.options\n setOptions(newOptions)\n } catch (error) {\n console.error('Error loading cascading select options:', error)\n setOptions([])\n } finally {\n setIsLoading(false)\n }\n }\n\n void doLoad()\n }, [parentValue, initialOptions])\n\n // Effect for clearing value when parent changes\n useEffect(() => {\n if (clearOnParentChange && prevParentValueRef.current !== parentValue) {\n // Clear field value if parent changed (not on first render)\n if (prevParentValueRef.current !== undefined) {\n form.setFieldValue(fullPath, '' as unknown)\n }\n prevParentValueRef.current = parentValue\n }\n }, [parentValue, clearOnParentChange, form, fullPath])\n\n // Determine if the field should be disabled\n const isParentEmpty = parentValue === undefined || parentValue === null || parentValue === ''\n const isDisabled = resolved.disabled || (disableWhenParentEmpty && isParentEmpty)\n\n // Determine placeholder\n const effectivePlaceholder = isParentEmpty && placeholderWhenDisabled ? placeholderWhenDisabled : resolved.placeholder\n\n // Auto-determine clearable\n const resolvedClearable = clearable ?? !resolved.required\n\n // Create collection from options\n const collection = useMemo(\n () =>\n createListCollection({\n items: options,\n itemToString: getOptionLabel,\n itemToValue: (item) => item.value as string,\n }),\n [options]\n )\n\n return (\n <form.Field name={fullPath}>\n {(field: {\n state: { value: unknown; meta: { errors?: unknown[] } }\n handleChange: (v: unknown) => void\n handleBlur: () => void\n }) => {\n const { hasError, errorMessage } = getFieldErrors(field)\n const currentValue = field.state.value as string | undefined\n\n return (\n <Field.Root invalid={hasError} required={resolved.required} disabled={isDisabled}>\n <Select.Root\n collection={collection}\n size={size}\n variant={variant}\n value={currentValue ? [currentValue] : []}\n onValueChange={(details) => {\n const newValue = details.value[0] as string | undefined\n field.handleChange(newValue ?? '')\n }}\n onInteractOutside={() => field.handleBlur()}\n disabled={isDisabled}\n data-field-name={fullPath}\n >\n <Select.HiddenSelect />\n {resolved.label && (\n <Select.Label>\n <SelectionFieldLabel label={resolved.label} tooltip={resolved.tooltip} required={resolved.required} />\n </Select.Label>\n )}\n <Select.Control>\n <Select.Trigger>\n <Select.ValueText placeholder={effectivePlaceholder} />\n </Select.Trigger>\n <Select.IndicatorGroup>\n {isLoading && <Spinner size=\"xs\" />}\n {resolvedClearable && !isLoading && <Select.ClearTrigger />}\n <Select.Indicator />\n </Select.IndicatorGroup>\n </Select.Control>\n <Portal>\n <Select.Positioner>\n <Select.Content>\n {options.map((opt) => (\n <Select.Item item={opt} key={opt.value as string}>\n {getOptionLabel(opt)}\n <Select.ItemIndicator />\n </Select.Item>\n ))}\n </Select.Content>\n </Select.Positioner>\n </Portal>\n </Select.Root>\n <FieldError hasError={!!hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n )\n }}\n </form.Field>\n )\n}\n\n/**\n * Form.Field.CascadingSelect - Cascading select depending on another field\n *\n * Loads options dynamically based on another field's value.\n * Useful for linked lists like Country -> City, Category -> Subcategory.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field.Select\n * name=\"country\"\n * label=\"Country\"\n * options={countries}\n * />\n * <Form.Field.CascadingSelect\n * name=\"city\"\n * label=\"City\"\n * dependsOn=\"country\"\n * loadOptions={async (countryCode) => {\n * if (!countryCode) return []\n * const cities = await fetchCities(countryCode)\n * return cities.map(c => ({ label: c.name, value: c.id }))\n * }}\n * placeholderWhenDisabled=\"Select country first\"\n * />\n * ```\n *\n * @example Nested fields\n * ```tsx\n * <Form.Field.CascadingSelect\n * name=\"address.region\"\n * label=\"Region\"\n * dependsOn=\"address.country\"\n * loadOptions={loadRegions}\n * />\n * ```\n */\nexport function FieldCascadingSelect<TParent = string, TValue = string>(\n props: CascadingSelectFieldProps<TParent, TValue>\n): ReactElement {\n const {\n name,\n dependsOn,\n loadOptions,\n initialOptions = [],\n clearOnParentChange = true,\n disableWhenParentEmpty = true,\n clearable,\n size = 'md',\n variant = 'outline',\n placeholderWhenDisabled,\n ...baseProps\n } = props\n\n const { form } = useDeclarativeForm()\n const parentGroup = useFormGroup()\n const { form: _formFromProps, fullPath, ...resolvedRest } = useResolvedFieldProps(name, baseProps)\n\n const resolved: ResolvedFieldProps = {\n label: resolvedRest.label,\n placeholder: resolvedRest.placeholder,\n helperText: resolvedRest.helperText,\n tooltip: resolvedRest.tooltip,\n required: resolvedRest.required,\n disabled: resolvedRest.disabled,\n readOnly: resolvedRest.readOnly,\n constraints: resolvedRest.constraints,\n options: resolvedRest.options,\n autocomplete: resolvedRest.autocomplete,\n }\n\n // Build full path to parent field\n const fullDependsOnPath = parentGroup ? `${parentGroup.name}.${dependsOn}` : dependsOn\n\n // Create selector for parent field value (inline, like in FormWhen)\n const parentSelector = (state: { values: Record<string, unknown> }): TParent | undefined => {\n const parts = fullDependsOnPath.split('.')\n let value: unknown = state.values\n for (const part of parts) {\n if (value && typeof value === 'object') {\n value = (value as Record<string, unknown>)[part]\n } else {\n value = undefined\n break\n }\n }\n return value as TParent | undefined\n }\n\n // Use form.Subscribe to subscribe to parent field changes\n return (\n <form.Subscribe selector={parentSelector}>\n {(parentValue: TParent | undefined) => (\n <CascadingSelectContent\n parentValue={parentValue}\n form={form}\n fullPath={fullPath}\n resolved={resolved}\n loadOptions={loadOptions}\n initialOptions={initialOptions as BaseOption<TValue>[]}\n clearOnParentChange={clearOnParentChange}\n disableWhenParentEmpty={disableWhenParentEmpty}\n clearable={clearable}\n size={size}\n variant={variant}\n placeholderWhenDisabled={placeholderWhenDisabled}\n />\n )}\n </form.Subscribe>\n )\n}\n\nFieldCascadingSelect.displayName = 'FieldCascadingSelect'\n"]}
|
|
@@ -431,5 +431,5 @@ function FormSyncStatus({
|
|
|
431
431
|
}
|
|
432
432
|
|
|
433
433
|
export { FormOfflineIndicator, FormSyncStatus, addToQueue, clearQueue, createSyncQueueStore, getOfflineStatus, getQueueFromStorage, processQueueItem, removeFromQueue, subscribeToStatusChanges, useOfflineForm, useOfflineStatus, useSyncQueue };
|
|
434
|
-
//# sourceMappingURL=chunk-
|
|
435
|
-
//# sourceMappingURL=chunk-
|
|
434
|
+
//# sourceMappingURL=chunk-MVGXZNHP.js.map
|
|
435
|
+
//# sourceMappingURL=chunk-MVGXZNHP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/offline/offline-service.ts","../src/lib/offline/use-offline-status.ts","../src/lib/offline/use-sync-queue.ts","../src/lib/offline/use-offline-form.ts","../src/lib/offline/form-offline-indicator.tsx","../src/lib/offline/form-sync-status.tsx"],"names":["listeners","notifyListeners","isOffline","useSyncExternalStore","useState","useCallback","useEffect","jsxs","HStack","jsx","Icon","Badge"],"mappings":";;;;;;AAiBA,SAAS,SAAA,GAAqB;AAC5B,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,SAAA,KAAc,WAAA;AAC/D;AAMA,IAAI,SAAA,GAAgD,IAAA;AACpD,eAAe,MAAA,GAAsD;AACnE,EAAA,IAAI,CAAC,WAAU,EAAG;AAChB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,SAAA,GAAY,MAAM,OAAO,YAAY,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,SAAA;AACT;AAMA,IAAM,8BAAA,GAAiC,sBAAA;AAUhC,SAAS,gBAAA,GAA4B;AAC1C,EAAA,IAAI,OAAO,cAAc,WAAA,EAAa;AACpC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,CAAC,SAAA,CAAU,MAAA;AACpB;AAOO,SAAS,yBAAyB,QAAA,EAAoD;AAC3F,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAEjC,IAAA,OAAO,MAAM;AAAA,IAAC,CAAA;AAAA,EAChB;AAEA,EAAA,MAAM,YAAA,GAAe,MAAM,QAAA,CAAS,KAAK,CAAA;AACzC,EAAA,MAAM,aAAA,GAAgB,MAAM,QAAA,CAAS,IAAI,CAAA;AAEzC,EAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,YAAY,CAAA;AAC9C,EAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,aAAa,CAAA;AAEhD,EAAA,OAAO,MAAM;AACX,IAAA,MAAA,CAAO,mBAAA,CAAoB,UAAU,YAAY,CAAA;AACjD,IAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,aAAa,CAAA;AAAA,EACrD,CAAA;AACF;AASA,SAAS,UAAA,GAAqB;AAC5B,EAAA,OAAO,CAAA,EAAG,IAAA,CAAK,GAAA,EAAK,IAAI,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAChE;AAKA,eAAsB,oBAAoB,UAAA,EAA+C;AACvF,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,MAAA,EAAO;AACzB,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,MAAM,MAAM,UAAA,IAAc,8BAAA;AAC1B,IAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,GAAA,CAAqB,GAAG,CAAA;AACjD,IAAA,OAAO,UAAU,EAAC;AAAA,EACpB,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,wDAAwD,KAAK,CAAA;AAC3E,IAAA,OAAO,EAAC;AAAA,EACV;AACF;AAKA,eAAe,kBAAA,CAAmB,OAAwB,UAAA,EAAoC;AAC5F,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,MAAA,EAAO;AACzB,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA;AAAA,IACF;AACA,IAAA,MAAM,MAAM,UAAA,IAAc,8BAAA;AAC1B,IAAA,MAAM,GAAA,CAAI,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAAA,EAC1B,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,qDAAqD,KAAK,CAAA;AAAA,EAC1E;AACF;AAKA,eAAsB,UAAA,CAAW,QAAoB,UAAA,EAA6C;AAChG,EAAA,MAAM,KAAA,GAAQ,MAAM,mBAAA,CAAoB,UAAU,CAAA;AAElD,EAAA,MAAM,IAAA,GAAsB;AAAA,IAC1B,IAAI,UAAA,EAAW;AAAA,IACf,MAAA;AAAA,IACA,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,IACpB,QAAA,EAAU,CAAA;AAAA,IACV,WAAA,EAAa,CAAA;AAAA,IACb,MAAA,EAAQ;AAAA,GACV;AAEA,EAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,EAAA,MAAM,kBAAA,CAAmB,OAAO,UAAU,CAAA;AAE1C,EAAA,OAAO,IAAA;AACT;AAKA,eAAsB,eAAA,CAAgB,IAAY,UAAA,EAAuC;AACvF,EAAA,MAAM,KAAA,GAAQ,MAAM,mBAAA,CAAoB,UAAU,CAAA;AAClD,EAAA,MAAM,QAAQ,KAAA,CAAM,SAAA,CAAU,CAAC,IAAA,KAAS,IAAA,CAAK,OAAO,EAAE,CAAA;AAEtD,EAAA,IAAI,UAAU,EAAA,EAAI;AAChB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,KAAA,CAAM,MAAA,CAAO,OAAO,CAAC,CAAA;AACrB,EAAA,MAAM,kBAAA,CAAmB,OAAO,UAAU,CAAA;AAE1C,EAAA,OAAO,IAAA;AACT;AAKA,eAAsB,gBAAA,CAAiB,MAAqB,OAAA,EAAyD;AACnH,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA;AAExC,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM,EAAE,GAAG,IAAA,EAAM,QAAQ,QAAA;AAAkB,OAC7C;AAAA,IACF;AAGA,IAAA,MAAM,WAAA,GAA6B;AAAA,MACjC,GAAG,IAAA;AAAA,MACH,QAAA,EAAU,KAAK,QAAA,GAAW,CAAA;AAAA,MAC1B,QAAQ,IAAA,CAAK,QAAA,GAAW,CAAA,IAAK,IAAA,CAAK,cAAc,QAAA,GAAW,SAAA;AAAA,MAC3D,OAAO,MAAA,CAAO;AAAA,KAChB;AAEA,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,IAAA,EAAM,WAAA;AAAA,MACN,OAAO,MAAA,CAAO;AAAA,KAChB;AAAA,EACF,SAAS,KAAA,EAAO;AAEd,IAAA,MAAM,YAAA,GAAe,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AAC9D,IAAA,MAAM,WAAA,GAA6B;AAAA,MACjC,GAAG,IAAA;AAAA,MACH,QAAA,EAAU,KAAK,QAAA,GAAW,CAAA;AAAA,MAC1B,QAAQ,IAAA,CAAK,QAAA,GAAW,CAAA,IAAK,IAAA,CAAK,cAAc,QAAA,GAAW,SAAA;AAAA,MAC3D,KAAA,EAAO;AAAA,KACT;AAEA,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,IAAA,EAAM,WAAA;AAAA,MACN,KAAA,EAAO;AAAA,KACT;AAAA,EACF;AACF;AAKA,eAAsB,WAAW,UAAA,EAAoC;AACnE,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,MAAA,EAAO;AACzB,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA;AAAA,IACF;AACA,IAAA,MAAM,MAAM,UAAA,IAAc,8BAAA;AAC1B,IAAA,MAAM,GAAA,CAAI,IAAI,GAAG,CAAA;AAAA,EACnB,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,yDAAyD,KAAK,CAAA;AAAA,EAC9E;AACF;AAKO,SAAS,qBAAqB,UAAA,EAAqC;AACxE,EAAA,IAAI,QAAyB,EAAC;AAC9B,EAAA,MAAMA,UAAAA,uBAAgB,GAAA,EAAgB;AACtC,EAAA,MAAM,MAAM,UAAA,IAAc,8BAAA;AAE1B,EAAA,MAAMC,mBAAkB,MAAM;AAC5B,IAAAD,UAAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,KAAa,UAAU,CAAA;AAAA,EAC5C,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,UAAU,MAAM,KAAA;AAAA,IAEhB,cAAA,EAAgB,MAAM,KAAA,CAAM,MAAA;AAAA,IAE5B,SAAA,EAAW,CAAC,QAAA,KAAyB;AACnC,MAAAA,UAAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,MAAA,OAAO,MAAM;AACX,QAAAA,UAAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,MAC3B,CAAA;AAAA,IACF,CAAA;AAAA,IAEA,YAAY,YAAY;AACtB,MAAA,KAAA,GAAQ,MAAM,oBAAoB,GAAG,CAAA;AACrC,MAAAC,gBAAAA,EAAgB;AAAA,IAClB,CAAA;AAAA,IAEA,GAAA,EAAK,OAAO,MAAA,KAAuB;AACjC,MAAA,MAAM,IAAA,GAAO,MAAM,UAAA,CAAW,MAAA,EAAQ,GAAG,CAAA;AACzC,MAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,MAAAA,gBAAAA,EAAgB;AAChB,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAA,EAAQ,OAAO,EAAA,KAAe;AAC5B,MAAA,MAAM,MAAA,GAAS,MAAM,eAAA,CAAgB,EAAA,EAAI,GAAG,CAAA;AAC5C,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,KAAA,GAAQ,MAAM,MAAA,CAAO,CAAC,IAAA,KAAS,IAAA,CAAK,OAAO,EAAE,CAAA;AAC7C,QAAAA,gBAAAA,EAAgB;AAAA,MAClB;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IAEA,UAAA,EAAY,OAAO,OAAA,KAA+B;AAChD,MAAA,MAAM,UAAgC,EAAC;AAEvC,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,IAAI,IAAA,CAAK,WAAW,SAAA,EAAW;AAC7B,UAAA,MAAM,MAAA,GAAS,MAAM,gBAAA,CAAiB,IAAA,EAAM,OAAO,CAAA;AACnD,UAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AAGnB,UAAA,IAAI,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,IAAA,EAAM;AACjC,YAAA,MAAM,eAAA,CAAgB,IAAA,CAAK,EAAA,EAAI,GAAG,CAAA;AAClC,YAAA,KAAA,GAAQ,MAAM,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,KAAK,EAAE,CAAA;AAAA,UAC9C,CAAA,MAAA,IAAW,OAAO,IAAA,EAAM;AAEtB,YAAA,MAAM,KAAA,GAAQ,MAAM,SAAA,CAAU,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,KAAK,EAAE,CAAA;AACrD,YAAA,IAAI,UAAU,EAAA,EAAI;AAChB,cAAA,KAAA,CAAM,KAAK,IAAI,MAAA,CAAO,IAAA;AAAA,YACxB;AACA,YAAA,MAAM,kBAAA,CAAmB,OAAO,GAAG,CAAA;AAAA,UACrC;AAAA,QACF;AAAA,MACF;AAEA,MAAAA,gBAAAA,EAAgB;AAChB,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,GACF;AACF;ACjSA,IAAI,SAAA,GAAY,KAAA;AAEhB,IAAM,SAAA,uBAAgB,GAAA,EAAgB;AAEtC,IAAM,kBAAkB,MAAM;AAC5B,EAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,KAAa,QAAA,EAAU,CAAA;AAC5C,CAAA;AAGA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,EAAA,SAAA,GAAY,gBAAA,EAAiB;AAE7B,EAAA,wBAAA,CAAyB,CAAC,OAAA,KAAY;AACpC,IAAA,SAAA,GAAY,OAAA;AACZ,IAAA,eAAA,EAAgB;AAAA,EAClB,CAAC,CAAA;AACH;AAsBO,SAAS,gBAAA,GAA4B;AAC1C,EAAA,OAAO,oBAAA;AAAA,IACL,CAAC,QAAA,KAAa;AACZ,MAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,MAAA,OAAO,MAAM;AACX,QAAA,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,MAC3B,CAAA;AAAA,IACF,CAAA;AAAA,IACA,MAAM,SAAA;AAAA,IACN,MAAM;AAAA;AAAA,GACR;AACF;AC/CA,IAAM,wBAAwB,oBAAA,EAAqB;AACnD,IAAM,cAA+B,EAAC;AAGtC,IAAI,WAAA,GAAc,KAAA;AAElB,IAAM,aAAa,YAAY;AAC7B,EAAA,IAAI,CAAC,WAAA,IAAe,OAAO,MAAA,KAAW,WAAA,EAAa;AACjD,IAAA,WAAA,GAAc,IAAA;AACd,IAAA,MAAM,sBAAsB,UAAA,EAAW;AAAA,EACzC;AACF,CAAA;AAwCO,SAAS,YAAA,GAAmC;AACjD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,IAAI,CAAA;AAC/C,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AACtD,EAAA,MAAMC,aAAY,gBAAA,EAAiB;AAGnC,EAAA,MAAM,KAAA,GAAQC,oBAAAA;AAAA,IACZ,CAAC,QAAA,KAAa,qBAAA,CAAsB,SAAA,CAAU,QAAQ,CAAA;AAAA,IACtD,MAAM,sBAAsB,QAAA,EAAS;AAAA,IACrC,MAAM;AAAA;AAAA,GACR;AAGA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,UAAA,EAAW,CAAE,KAAK,MAAM;AACtB,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,OAAO,MAAA,KAA+C;AAClF,IAAA,OAAO,qBAAA,CAAsB,IAAI,MAAM,CAAA;AAAA,EACzC,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,YAAA,GAAe,WAAA,CAAY,OAAO,EAAA,KAAiC;AACvE,IAAA,OAAO,qBAAA,CAAsB,OAAO,EAAE,CAAA;AAAA,EACxC,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,OAAO,OAAA,KAA8D;AACnE,MAAA,IAAID,UAAAA,EAAW;AACb,QAAA,OAAA,CAAQ,KAAK,kDAAkD,CAAA;AAC/D,QAAA,OAAO,EAAC;AAAA,MACV;AAEA,MAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,MAAA,IAAI;AACF,QAAA,OAAO,MAAM,qBAAA,CAAsB,UAAA,CAAW,OAAO,CAAA;AAAA,MACvD,CAAA,SAAE;AACA,QAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,MACvB;AAAA,IACF,CAAA;AAAA,IACA,CAACA,UAAS;AAAA,GACZ;AAEA,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,aAAa,KAAA,CAAM,MAAA;AAAA,IACnB,YAAA,EAAc,MAAM,MAAA,CAAO,CAAC,SAAS,IAAA,CAAK,MAAA,KAAW,SAAS,CAAA,CAAE,MAAA;AAAA,IAChE,SAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACF;AACF;;;AChEO,SAAS,cAAA,CAAiC;AAAA,EAC/C,UAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAAsD;AACpD,EAAA,MAAMA,aAAY,gBAAA,EAAiB;AACnC,EAAA,MAAM,EAAE,SAAA,EAAW,YAAA,EAAc,cAAc,YAAA,EAAc,WAAA,KAAgB,YAAA,EAAa;AAC1F,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAIE,SAAwB,IAAI,CAAA;AAG1E,EAAA,MAAM,aAAA,GAAgB,OAAO,KAAK,CAAA;AAKlC,EAAA,MAAM,MAAA,GAASC,WAAAA;AAAA,IACb,OAAO,KAAA,KAA2C;AAEhD,MAAA,IAAIH,UAAAA,EAAW;AACb,QAAA,IAAI;AACF,UAAA,MAAM,SAAA,GAAY,MAAM,SAAA,CAAU;AAAA,YAChC,IAAA,EAAM,UAAA;AAAA,YACN,OAAA,EAAS;AAAA,WACV,CAAA;AAED,UAAA,QAAA,IAAW;AAEX,UAAA,OAAO;AAAA,YACL,OAAA,EAAS,IAAA;AAAA,YACT,MAAA,EAAQ,IAAA;AAAA,YACR,aAAa,SAAA,CAAU;AAAA,WACzB;AAAA,QACF,SAAS,KAAA,EAAO;AACd,UAAA,MAAM,YAAA,GAAe,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,uBAAA;AAC9D,UAAA,OAAA,GAAU,YAAY,CAAA;AACtB,UAAA,OAAO;AAAA,YACL,OAAA,EAAS,KAAA;AAAA,YACT,KAAA,EAAO;AAAA,WACT;AAAA,QACF;AAAA,MACF;AAGA,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,YAAA,CAAa,KAAK,CAAA;AAEvC,QAAA,IAAI,OAAO,OAAA,EAAS;AAClB,UAAA,SAAA,IAAY;AAAA,QACd,CAAA,MAAA,IAAW,OAAO,KAAA,EAAO;AACvB,UAAA,OAAA,GAAU,OAAO,KAAK,CAAA;AAAA,QACxB;AAEA,QAAA,OAAO;AAAA,UACL,SAAS,MAAA,CAAO,OAAA;AAAA,UAChB,OAAO,MAAA,CAAO,KAAA;AAAA,UACd,MAAA,EAAQ;AAAA,SACV;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,MAAM,YAAA,GAAe,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,kBAAA;AAC9D,QAAA,OAAA,GAAU,YAAY,CAAA;AACtB,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO,YAAA;AAAA,UACP,MAAA,EAAQ;AAAA,SACV;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,CAACA,UAAAA,EAAW,UAAA,EAAY,WAAW,YAAA,EAAc,SAAA,EAAW,UAAU,OAAO;AAAA,GAC/E;AAMA,EAAA,MAAM,kBAAA,GAAqBG,WAAAA;AAAA,IACzB,OAAO,MAAA,KAAsE;AAE3E,MAAA,IAAI,MAAA,CAAO,SAAS,UAAA,EAAY;AAC9B,QAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,MACzB;AAEA,MAAA,OAAO,YAAA,CAAa,OAAO,OAAY,CAAA;AAAA,IACzC,CAAA;AAAA,IACA,CAAC,YAAY,YAAY;AAAA,GAC3B;AAGA,EAAAC,UAAU,MAAM;AAEd,IAAA,IAAI,CAACJ,UAAAA,IAAa,YAAA,GAAe,CAAA,IAAK,CAAC,cAAc,OAAA,EAAS;AAC5D,MAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AACxB,MAAA,kBAAA,CAAmB,IAAA,CAAK,KAAK,CAAA;AAE7B,MAAA,YAAA,CAAa,kBAAkB,CAAA,CAC5B,IAAA,CAAK,CAAC,OAAA,KAAY;AACjB,QAAA,MAAM,SAAS,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,EAAE,OAAO,CAAA;AAC/C,QAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,UAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,cAAA,EAAiB,MAAA,CAAO,MAAM,CAAA,uBAAA,CAAyB,CAAA;AAAA,QACtE;AAAA,MACF,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,QAAA,aAAA,CAAc,OAAA,GAAU,KAAA;AAAA,MAC1B,CAAC,CAAA;AAAA,IACL;AAAA,EACF,GAAG,CAACA,UAAAA,EAAW,YAAA,EAAc,YAAA,EAAc,kBAAkB,CAAC,CAAA;AAE9D,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,SAAA,EAAAA,UAAAA;AAAA,IACA,YAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACF;AACF;ACvIO,SAAS,oBAAA,CAAqB;AAAA,EACnC,KAAA,GAAQ,cAAA;AAAA,EACR,YAAA,GAAe,QAAA;AAAA,EACf,OAAA,GAAU,QAAA;AAAA,EACV,GAAG;AACL,CAAA,EAAyD;AACvD,EAAA,MAAMA,aAAY,gBAAA,EAAiB;AAEnC,EAAA,IAAI,CAACA,UAAAA,EAAW;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAM,YAAA,EAA4B,OAAA,EAAkB,aAAA,EAAY,mBAAA,EAAqB,GAAG,IAAA,EACvF,QAAA,kBAAA,IAAA,CAAC,MAAA,EAAA,EAAO,GAAA,EAAK,CAAA,EACX,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,QAAK,OAAA,EAAO,IAAA,EAAC,SAAS,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,aAAU,CAAA,EACb,CAAA;AAAA,oBACA,GAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM;AAAA,GAAA,EACf,CAAA,EACF,CAAA;AAEJ;ACnBO,SAAS,cAAA,CAAe;AAAA,EAC7B,aAAA,GAAgB,KAAA;AAAA,EAChB,YAAA,GAAe,YAAA;AAAA,EACf,YAAA,GAAe,CAAC,KAAA,KAAkB,CAAA,SAAA,EAAY,KAAK,CAAA,CAAA;AAAA,EACnD,WAAA,GAAc,QAAA;AAAA,EACd,YAAA,GAAe,MAAA;AAAA,EACf,GAAG;AACL,CAAA,EAAmD;AACjD,EAAA,MAAMA,aAAY,gBAAA,EAAiB;AACnC,EAAA,MAAM,EAAE,YAAA,EAAc,YAAA,EAAa,GAAI,YAAA,EAAa;AAGpD,EAAA,IAAI,CAACA,UAAAA,IAAa,YAAA,KAAiB,KAAK,CAAC,YAAA,IAAgB,CAAC,aAAA,EAAe;AACvE,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,gBAAgB,MAAM;AAE1B,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,uBACEK,IAAAA,CAACC,MAAAA,EAAA,EAAO,KAAK,CAAA,EACX,QAAA,EAAA;AAAA,wBAAAC,GAAAA,CAAC,OAAA,EAAA,EAAQ,IAAA,EAAK,IAAA,EAAK,CAAA;AAAA,wBACnBA,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,YAAA,EAAa;AAAA,OAAA,EACtB,CAAA;AAAA,IAEJ;AAGA,IAAA,IAAI,eAAe,CAAA,EAAG;AACpB,MAAA,MAAM,QAAQ,OAAO,YAAA,KAAiB,UAAA,GAAa,YAAA,CAAa,YAAY,CAAA,GAAI,YAAA;AAChF,MAAA,uBACEF,IAAAA,CAACC,MAAAA,EAAA,EAAO,KAAK,CAAA,EACX,QAAA,EAAA;AAAA,wBAAAC,GAAAA,CAACC,IAAAA,EAAA,EAAK,OAAA,EAAO,IAAA,EAAC,SAAS,CAAA,EACrB,QAAA,kBAAAD,GAAAA,CAAC,OAAA,EAAA,EAAQ,CAAA,EACX,CAAA;AAAA,wBACAA,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,KAAA,EAAM;AAAA,OAAA,EACf,CAAA;AAAA,IAEJ;AAGA,IAAA,uBACEF,IAAAA,CAACC,MAAAA,EAAA,EAAO,KAAK,CAAA,EACX,QAAA,EAAA;AAAA,sBAAAC,GAAAA,CAACC,IAAAA,EAAA,EAAK,OAAA,EAAO,IAAA,EAAC,SAAS,CAAA,EACrB,QAAA,kBAAAD,GAAAA,CAAC,OAAA,EAAA,EAAQ,CAAA,EACX,CAAA;AAAA,sBACAA,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,WAAA,EAAY;AAAA,KAAA,EACrB,CAAA;AAAA,EAEJ,CAAA;AAGA,EAAA,MAAM,qBAAA,GAAwB,YAAA,GAAe,CAAA,GAAI,QAAA,GAAW,eAAe,YAAA,GAAe,OAAA;AAE1F,EAAA,uBACEA,GAAAA;AAAA,IAACE,KAAAA;AAAA,IAAA;AAAA,MACC,YAAA,EAAc,qBAAA;AAAA,MACd,OAAA,EAAQ,QAAA;AAAA,MACR,aAAA,EAAY,aAAA;AAAA,MACZ,oBAAA,EAAoB,YAAA;AAAA,MACpB,iBAAA,EAAiB,YAAA;AAAA,MAChB,GAAG,IAAA;AAAA,MAEH,QAAA,EAAA,aAAA;AAAc;AAAA,GACjB;AAEJ","file":"chunk-4V6WBJ76.js","sourcesContent":["/**\n * Offline functionality service\n *\n * Business logic:\n * - Online/offline status detection\n * - Sync action queue in IndexedDB\n */\n\nimport type { ProcessQueueResult, SyncAction, SyncActionHandler, SyncQueueItem, SyncQueueStore } from './types'\n\n// ============================================\n// LAZY IMPORT IDB-KEYVAL\n// ============================================\n\n/**\n * Check that we are in a browser with IndexedDB support\n */\nfunction canUseIDB(): boolean {\n return typeof window !== 'undefined' && typeof indexedDB !== 'undefined'\n}\n\n/**\n * Lazy import of idb-keyval to avoid SSR issues\n * Cache the promise to prevent repeated imports\n */\nlet idbModule: typeof import('idb-keyval') | null = null\nasync function getIDB(): Promise<typeof import('idb-keyval') | null> {\n if (!canUseIDB()) {\n return null\n }\n if (!idbModule) {\n idbModule = await import('idb-keyval')\n }\n return idbModule\n}\n\n// ============================================\n// CONSTANTS\n// ============================================\n\nconst DEFAULT_SYNC_QUEUE_STORAGE_KEY = 'lena-form-sync-queue'\n\n// ============================================\n// CONNECTION STATUS\n// ============================================\n\n/**\n * Get current offline status\n * @returns true if offline, false if online\n */\nexport function getOfflineStatus(): boolean {\n if (typeof navigator === 'undefined') {\n return false\n }\n return !navigator.onLine\n}\n\n/**\n * Subscribe to connection status changes\n * @param callback - function called when status changes\n * @returns unsubscribe function\n */\nexport function subscribeToStatusChanges(callback: (isOffline: boolean) => void): () => void {\n if (typeof window === 'undefined') {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {}\n }\n\n const handleOnline = () => callback(false)\n const handleOffline = () => callback(true)\n\n window.addEventListener('online', handleOnline)\n window.addEventListener('offline', handleOffline)\n\n return () => {\n window.removeEventListener('online', handleOnline)\n window.removeEventListener('offline', handleOffline)\n }\n}\n\n// ============================================\n// SYNC QUEUE\n// ============================================\n\n/**\n * Generate unique ID\n */\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Get queue from IndexedDB\n */\nexport async function getQueueFromStorage(storageKey?: string): Promise<SyncQueueItem[]> {\n try {\n const idb = await getIDB()\n if (!idb) {\n return []\n }\n const key = storageKey ?? DEFAULT_SYNC_QUEUE_STORAGE_KEY\n const stored = await idb.get<SyncQueueItem[]>(key)\n return stored ?? []\n } catch (error) {\n console.error('[OfflineService] Error loading queue from IndexedDB:', error)\n return []\n }\n}\n\n/**\n * Save queue to IndexedDB\n */\nasync function saveQueueToStorage(queue: SyncQueueItem[], storageKey?: string): Promise<void> {\n try {\n const idb = await getIDB()\n if (!idb) {\n return\n }\n const key = storageKey ?? DEFAULT_SYNC_QUEUE_STORAGE_KEY\n await idb.set(key, queue)\n } catch (error) {\n console.error('[OfflineService] Error saving queue to IndexedDB:', error)\n }\n}\n\n/**\n * Add action to queue\n */\nexport async function addToQueue(action: SyncAction, storageKey?: string): Promise<SyncQueueItem> {\n const queue = await getQueueFromStorage(storageKey)\n\n const item: SyncQueueItem = {\n id: generateId(),\n action,\n createdAt: Date.now(),\n attempts: 0,\n maxAttempts: 3,\n status: 'PENDING',\n }\n\n queue.push(item)\n await saveQueueToStorage(queue, storageKey)\n\n return item\n}\n\n/**\n * Remove item from queue\n */\nexport async function removeFromQueue(id: string, storageKey?: string): Promise<boolean> {\n const queue = await getQueueFromStorage(storageKey)\n const index = queue.findIndex((item) => item.id === id)\n\n if (index === -1) {\n return false\n }\n\n queue.splice(index, 1)\n await saveQueueToStorage(queue, storageKey)\n\n return true\n}\n\n/**\n * Process one queue item\n */\nexport async function processQueueItem(item: SyncQueueItem, handler: SyncActionHandler): Promise<ProcessQueueResult> {\n try {\n const result = await handler(item.action)\n\n if (result.success) {\n return {\n success: true,\n item: { ...item, status: 'SYNCED' as const },\n }\n }\n\n // Unsuccessful result without exception\n const updatedItem: SyncQueueItem = {\n ...item,\n attempts: item.attempts + 1,\n status: item.attempts + 1 >= item.maxAttempts ? 'FAILED' : 'PENDING',\n error: result.error,\n }\n\n return {\n success: false,\n item: updatedItem,\n error: result.error,\n }\n } catch (error) {\n // Exception during execution\n const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n const updatedItem: SyncQueueItem = {\n ...item,\n attempts: item.attempts + 1,\n status: item.attempts + 1 >= item.maxAttempts ? 'FAILED' : 'PENDING',\n error: errorMessage,\n }\n\n return {\n success: false,\n item: updatedItem,\n error: errorMessage,\n }\n }\n}\n\n/**\n * Clear queue\n */\nexport async function clearQueue(storageKey?: string): Promise<void> {\n try {\n const idb = await getIDB()\n if (!idb) {\n return\n }\n const key = storageKey ?? DEFAULT_SYNC_QUEUE_STORAGE_KEY\n await idb.del(key)\n } catch (error) {\n console.error('[OfflineService] Error clearing queue from IndexedDB:', error)\n }\n}\n\n/**\n * Create sync queue store\n */\nexport function createSyncQueueStore(storageKey?: string): SyncQueueStore {\n let queue: SyncQueueItem[] = []\n const listeners = new Set<() => void>()\n const key = storageKey ?? DEFAULT_SYNC_QUEUE_STORAGE_KEY\n\n const notifyListeners = () => {\n listeners.forEach((listener) => listener())\n }\n\n return {\n getQueue: () => queue,\n\n getQueueLength: () => queue.length,\n\n subscribe: (listener: () => void) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n\n initialize: async () => {\n queue = await getQueueFromStorage(key)\n notifyListeners()\n },\n\n add: async (action: SyncAction) => {\n const item = await addToQueue(action, key)\n queue.push(item)\n notifyListeners()\n return item\n },\n\n remove: async (id: string) => {\n const result = await removeFromQueue(id, key)\n if (result) {\n queue = queue.filter((item) => item.id !== id)\n notifyListeners()\n }\n return result\n },\n\n processAll: async (handler: SyncActionHandler) => {\n const results: ProcessQueueResult[] = []\n\n for (const item of queue) {\n if (item.status === 'PENDING') {\n const result = await processQueueItem(item, handler)\n results.push(result)\n\n // Update queue after processing\n if (result.success && result.item) {\n await removeFromQueue(item.id, key)\n queue = queue.filter((q) => q.id !== item.id)\n } else if (result.item) {\n // Update item in queue\n const index = queue.findIndex((q) => q.id === item.id)\n if (index !== -1) {\n queue[index] = result.item\n }\n await saveQueueToStorage(queue, key)\n }\n }\n }\n\n notifyListeners()\n return results\n },\n }\n}\n","'use client'\n\nimport { useSyncExternalStore } from 'react'\n\nimport { getOfflineStatus, subscribeToStatusChanges } from './offline-service'\n\n// Global state for synchronization across tabs\nlet isOffline = false\n\nconst listeners = new Set<() => void>()\n\nconst notifyListeners = () => {\n listeners.forEach((listener) => listener())\n}\n\n// Initialize on first load\nif (typeof window !== 'undefined') {\n isOffline = getOfflineStatus()\n\n subscribeToStatusChanges((offline) => {\n isOffline = offline\n notifyListeners()\n })\n}\n\n/**\n * Hook for detecting offline status\n *\n * @returns true if the browser is offline\n *\n * @example\n * ```tsx\n * import { useOfflineStatus } from '@lena/form-components/offline'\n *\n * function MyComponent() {\n * const isOffline = useOfflineStatus()\n *\n * if (isOffline) {\n * return <OfflineBanner />\n * }\n *\n * return <OnlineContent />\n * }\n * ```\n */\nexport function useOfflineStatus(): boolean {\n return useSyncExternalStore(\n (callback) => {\n listeners.add(callback)\n return () => {\n listeners.delete(callback)\n }\n },\n () => isOffline,\n () => false, // SSR fallback — assume online\n )\n}\n","'use client'\n\nimport { useCallback, useEffect, useState, useSyncExternalStore } from 'react'\n\nimport { createSyncQueueStore } from './offline-service'\nimport type { ProcessQueueResult, SyncAction, SyncActionHandler, SyncQueueItem, UseSyncQueueResult } from './types'\nimport { useOfflineStatus } from './use-offline-status'\n\n// Global sync queue store (default)\nconst defaultSyncQueueStore = createSyncQueueStore()\nconst EMPTY_QUEUE: SyncQueueItem[] = []\n\n// Initialization flag\nlet initialized = false\n\nconst initialize = async () => {\n if (!initialized && typeof window !== 'undefined') {\n initialized = true\n await defaultSyncQueueStore.initialize()\n }\n}\n\n/**\n * Hook for working with the sync queue\n *\n * Allows adding actions to the queue in offline mode\n * and synchronizing them when connection is restored.\n *\n * @example\n * ```tsx\n * import { useSyncQueue } from '@lena/form-components/offline'\n *\n * function MyComponent() {\n * const { queue, queueLength, addAction, processQueue, isProcessing } = useSyncQueue()\n *\n * // Add action to queue (works offline too)\n * const handleBookLesson = async (slotId: string) => {\n * if (isOffline) {\n * await addAction({ type: 'BOOK_LESSON', payload: { slotId } })\n * toast({ title: 'Action added to sync queue' })\n * } else {\n * await api.bookLesson(slotId)\n * }\n * }\n *\n * // Process queue when connection is restored\n * useEffect(() => {\n * if (!isOffline && queueLength > 0) {\n * processQueue(async (action) => {\n * switch (action.type) {\n * case 'BOOK_LESSON':\n * return api.bookLesson(action.payload.slotId)\n * // ... other action types\n * }\n * })\n * }\n * }, [isOffline, queueLength, processQueue])\n * }\n * ```\n */\nexport function useSyncQueue(): UseSyncQueueResult {\n const [isLoading, setIsLoading] = useState(true)\n const [isProcessing, setIsProcessing] = useState(false)\n const isOffline = useOfflineStatus()\n\n // Subscribe to queue changes\n const queue = useSyncExternalStore(\n (callback) => defaultSyncQueueStore.subscribe(callback),\n () => defaultSyncQueueStore.getQueue(),\n () => EMPTY_QUEUE, // SSR fallback\n )\n\n // Initialize on mount\n useEffect(() => {\n initialize().then(() => {\n setIsLoading(false)\n })\n }, [])\n\n // Add action to queue\n const addAction = useCallback(async (action: SyncAction): Promise<SyncQueueItem> => {\n return defaultSyncQueueStore.add(action)\n }, [])\n\n // Remove action from queue\n const removeAction = useCallback(async (id: string): Promise<boolean> => {\n return defaultSyncQueueStore.remove(id)\n }, [])\n\n // Process entire queue\n const processQueue = useCallback(\n async (handler: SyncActionHandler): Promise<ProcessQueueResult[]> => {\n if (isOffline) {\n console.warn('[SyncQueue] Cannot process queue in offline mode')\n return []\n }\n\n setIsProcessing(true)\n try {\n return await defaultSyncQueueStore.processAll(handler)\n } finally {\n setIsProcessing(false)\n }\n },\n [isOffline],\n )\n\n return {\n queue,\n queueLength: queue.length,\n pendingCount: queue.filter((item) => item.status === 'PENDING').length,\n isLoading,\n isProcessing,\n addAction,\n removeAction,\n processQueue,\n }\n}\n","'use client'\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\nimport type { OfflineSubmitResult, SyncAction, UseOfflineFormOptions, UseOfflineFormResult } from './types'\nimport { useOfflineStatus } from './use-offline-status'\nimport { useSyncQueue } from './use-sync-queue'\n\n/**\n * Hook for offline form support with TanStack Form\n *\n * Automatically detects connection status and:\n * - Online: sends data directly\n * - Offline: saves to IndexedDB queue for synchronization\n *\n * @example\n * ```tsx\n * import { useOfflineForm } from '@lena/form-components/offline'\n *\n * function ProfileForm({ initialData }) {\n * const { submit, isOffline, pendingCount, isProcessing } = useOfflineForm({\n * actionType: 'UPDATE_PROFILE',\n * onlineSubmit: async (value) => {\n * const result = await updateProfileAction(value)\n * return { success: result.success, error: result.error?.formErrors?.[0] }\n * },\n * onSuccess: () => toaster.success({ title: 'Saved' }),\n * onQueued: () => toaster.info({ title: 'Saved locally' }),\n * onError: (error) => toaster.error({ title: 'Error', description: error }),\n * })\n *\n * const form = useAppForm({\n * defaultValues: initialData,\n * onSubmit: async ({ value }) => {\n * await submit(value)\n * },\n * })\n *\n * return (\n * <form onSubmit={(e) => { e.preventDefault(); form.handleSubmit() }}>\n * {isOffline && <Badge colorPalette=\"orange\">Offline mode</Badge>}\n * {pendingCount > 0 && (\n * <Badge colorPalette=\"blue\">\n * {isProcessing ? 'Syncing...' : `Pending: ${pendingCount}`}\n * </Badge>\n * )}\n * <form.AppField name=\"name\" children={(field) => <field.TextField label=\"Name\" />} />\n * <Button type=\"submit\">{isOffline ? 'Save locally' : 'Save'}</Button>\n * </form>\n * )\n * }\n * ```\n */\nexport function useOfflineForm<T extends object>({\n actionType,\n onlineSubmit,\n onSuccess,\n onQueued,\n onError,\n}: UseOfflineFormOptions<T>): UseOfflineFormResult<T> {\n const isOffline = useOfflineStatus()\n const { addAction, processQueue, pendingCount, isProcessing, queueLength } = useSyncQueue()\n const [lastSyncAttempt, setLastSyncAttempt] = useState<number | null>(null)\n\n // Ref to prevent repeated queue processing\n const processingRef = useRef(false)\n\n /**\n * Form submission with offline support\n */\n const submit = useCallback(\n async (value: T): Promise<OfflineSubmitResult> => {\n // Offline — add to queue\n if (isOffline) {\n try {\n const queueItem = await addAction({\n type: actionType,\n payload: value as Record<string, unknown>,\n })\n\n onQueued?.()\n\n return {\n success: true,\n queued: true,\n queueItemId: queueItem.id,\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Error saving to queue'\n onError?.(errorMessage)\n return {\n success: false,\n error: errorMessage,\n }\n }\n }\n\n // Online — send directly\n try {\n const result = await onlineSubmit(value)\n\n if (result.success) {\n onSuccess?.()\n } else if (result.error) {\n onError?.(result.error)\n }\n\n return {\n success: result.success,\n error: result.error,\n queued: false,\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Submission error'\n onError?.(errorMessage)\n return {\n success: false,\n error: errorMessage,\n queued: false,\n }\n }\n },\n [isOffline, actionType, addAction, onlineSubmit, onSuccess, onQueued, onError],\n )\n\n /**\n * Handler for queued actions\n * Called when connection is restored\n */\n const handleQueuedAction = useCallback(\n async (action: SyncAction): Promise<{ success: boolean; error?: string }> => {\n // Process only our action type\n if (action.type !== actionType) {\n return { success: true } // Skip other action types\n }\n\n return onlineSubmit(action.payload as T)\n },\n [actionType, onlineSubmit],\n )\n\n // Automatic sync when connection is restored\n useEffect(() => {\n // If online and there are items in queue — try to sync\n if (!isOffline && pendingCount > 0 && !processingRef.current) {\n processingRef.current = true\n setLastSyncAttempt(Date.now())\n\n processQueue(handleQueuedAction)\n .then((results) => {\n const failed = results.filter((r) => !r.success)\n if (failed.length > 0) {\n console.warn(`[OfflineForm] ${failed.length} actions failed to sync`)\n }\n })\n .finally(() => {\n processingRef.current = false\n })\n }\n }, [isOffline, pendingCount, processQueue, handleQueuedAction])\n\n return {\n submit,\n isOffline,\n pendingCount,\n queueLength,\n isProcessing,\n lastSyncAttempt,\n }\n}\n","'use client'\n\nimport { Badge, type BadgeProps, HStack, Icon } from '@chakra-ui/react'\nimport { LuWifiOff } from 'react-icons/lu'\n\nimport type { OfflineIndicatorProps } from './types'\nimport { useOfflineStatus } from './use-offline-status'\n\n/**\n * Offline mode indicator\n *\n * Automatically shown when the browser is offline.\n * Hidden when connection is restored.\n *\n * @example\n * ```tsx\n * import { Form } from '@lena/form-components'\n *\n * <Form initialValue={data} onSubmit={handleSubmit}>\n * <Form.OfflineIndicator />\n * <Form.Field.String name=\"title\" />\n * <Form.Button.Submit />\n * </Form>\n * ```\n *\n * @example With custom settings\n * ```tsx\n * <Form.OfflineIndicator\n * label=\"No connection\"\n * colorPalette=\"red\"\n * variant=\"solid\"\n * />\n * ```\n */\nexport function FormOfflineIndicator({\n label = 'Offline mode',\n colorPalette = 'orange',\n variant = 'subtle',\n ...rest\n}: OfflineIndicatorProps & Omit<BadgeProps, 'children'>) {\n const isOffline = useOfflineStatus()\n\n if (!isOffline) {\n return null\n }\n\n return (\n <Badge colorPalette={colorPalette} variant={variant} data-testid=\"offline-indicator\" {...rest}>\n <HStack gap={1}>\n <Icon asChild boxSize={3}>\n <LuWifiOff />\n </Icon>\n <span>{label}</span>\n </HStack>\n </Badge>\n )\n}\n","'use client'\n\nimport { Badge, type BadgeProps, HStack, Icon, Spinner } from '@chakra-ui/react'\nimport { LuCheck, LuClock } from 'react-icons/lu'\n\nimport type { SyncStatusProps } from './types'\nimport { useOfflineStatus } from './use-offline-status'\nimport { useSyncQueue } from './use-sync-queue'\n\n/**\n * Sync queue status indicator\n *\n * Shows:\n * - Number of pending actions\n * - Spinner during synchronization\n * - \"Synced\" when queue is empty\n *\n * Works globally, does not require Form context.\n *\n * @example\n * ```tsx\n * import { FormSyncStatus } from '@lena/form-components/offline'\n *\n * // In layout or header\n * <FormSyncStatus />\n * ```\n *\n * @example With custom settings\n * ```tsx\n * <FormSyncStatus\n * showWhenEmpty={false}\n * syncingLabel=\"Syncing...\"\n * pendingLabel={(count) => `Pending: ${count}`}\n * syncedLabel=\"All synced\"\n * />\n * ```\n */\nexport function FormSyncStatus({\n showWhenEmpty = false,\n syncingLabel = 'Syncing...',\n pendingLabel = (count: number) => `Pending: ${count}`,\n syncedLabel = 'Synced',\n colorPalette = 'blue',\n ...rest\n}: SyncStatusProps & Omit<BadgeProps, 'children'>) {\n const isOffline = useOfflineStatus()\n const { pendingCount, isProcessing } = useSyncQueue()\n\n // Hide if online, queue empty and showWhenEmpty = false\n if (!isOffline && pendingCount === 0 && !isProcessing && !showWhenEmpty) {\n return null\n }\n\n // Determine what to display\n const renderContent = () => {\n // Synchronization in progress\n if (isProcessing) {\n return (\n <HStack gap={1}>\n <Spinner size=\"xs\" />\n <span>{syncingLabel}</span>\n </HStack>\n )\n }\n\n // There are pending items\n if (pendingCount > 0) {\n const label = typeof pendingLabel === 'function' ? pendingLabel(pendingCount) : pendingLabel\n return (\n <HStack gap={1}>\n <Icon asChild boxSize={3}>\n <LuClock />\n </Icon>\n <span>{label}</span>\n </HStack>\n )\n }\n\n // All synced\n return (\n <HStack gap={1}>\n <Icon asChild boxSize={3}>\n <LuCheck />\n </Icon>\n <span>{syncedLabel}</span>\n </HStack>\n )\n }\n\n // Color depends on state\n const effectiveColorPalette = pendingCount > 0 ? 'orange' : isProcessing ? colorPalette : 'green'\n\n return (\n <Badge\n colorPalette={effectiveColorPalette}\n variant=\"subtle\"\n data-testid=\"sync-status\"\n data-pending-count={pendingCount}\n data-processing={isProcessing}\n {...rest}\n >\n {renderContent()}\n </Badge>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/offline/offline-service.ts","../src/lib/offline/use-offline-status.ts","../src/lib/offline/use-sync-queue.ts","../src/lib/offline/use-offline-form.ts","../src/lib/offline/form-offline-indicator.tsx","../src/lib/offline/form-sync-status.tsx"],"names":["listeners","notifyListeners","isOffline","useSyncExternalStore","useState","useCallback","useEffect","jsxs","HStack","jsx","Icon","Badge"],"mappings":"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","file":"chunk-MVGXZNHP.js","sourcesContent":["/**\n * Offline functionality service\n *\n * Business logic:\n * - Online/offline status detection\n * - Sync action queue in IndexedDB\n */\n\nimport type { ProcessQueueResult, SyncAction, SyncActionHandler, SyncQueueItem, SyncQueueStore } from './types'\n\n// ============================================\n// LAZY IMPORT IDB-KEYVAL\n// ============================================\n\n/**\n * Check that we are in a browser with IndexedDB support\n */\nfunction canUseIDB(): boolean {\n return typeof window !== 'undefined' && typeof indexedDB !== 'undefined'\n}\n\n/**\n * Lazy import of idb-keyval to avoid SSR issues\n * Cache the promise to prevent repeated imports\n */\nlet idbModule: typeof import('idb-keyval') | null = null\nasync function getIDB(): Promise<typeof import('idb-keyval') | null> {\n if (!canUseIDB()) {\n return null\n }\n if (!idbModule) {\n idbModule = await import('idb-keyval')\n }\n return idbModule\n}\n\n// ============================================\n// CONSTANTS\n// ============================================\n\nconst DEFAULT_SYNC_QUEUE_STORAGE_KEY = 'lena-form-sync-queue'\n\n// ============================================\n// CONNECTION STATUS\n// ============================================\n\n/**\n * Get current offline status\n * @returns true if offline, false if online\n */\nexport function getOfflineStatus(): boolean {\n if (typeof navigator === 'undefined') {\n return false\n }\n return !navigator.onLine\n}\n\n/**\n * Subscribe to connection status changes\n * @param callback - function called when status changes\n * @returns unsubscribe function\n */\nexport function subscribeToStatusChanges(callback: (isOffline: boolean) => void): () => void {\n if (typeof window === 'undefined') {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {}\n }\n\n const handleOnline = () => callback(false)\n const handleOffline = () => callback(true)\n\n window.addEventListener('online', handleOnline)\n window.addEventListener('offline', handleOffline)\n\n return () => {\n window.removeEventListener('online', handleOnline)\n window.removeEventListener('offline', handleOffline)\n }\n}\n\n// ============================================\n// SYNC QUEUE\n// ============================================\n\n/**\n * Generate unique ID\n */\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Get queue from IndexedDB\n */\nexport async function getQueueFromStorage(storageKey?: string): Promise<SyncQueueItem[]> {\n try {\n const idb = await getIDB()\n if (!idb) {\n return []\n }\n const key = storageKey ?? DEFAULT_SYNC_QUEUE_STORAGE_KEY\n const stored = await idb.get<SyncQueueItem[]>(key)\n return stored ?? []\n } catch (error) {\n console.error('[OfflineService] Error loading queue from IndexedDB:', error)\n return []\n }\n}\n\n/**\n * Save queue to IndexedDB\n */\nasync function saveQueueToStorage(queue: SyncQueueItem[], storageKey?: string): Promise<void> {\n try {\n const idb = await getIDB()\n if (!idb) {\n return\n }\n const key = storageKey ?? DEFAULT_SYNC_QUEUE_STORAGE_KEY\n await idb.set(key, queue)\n } catch (error) {\n console.error('[OfflineService] Error saving queue to IndexedDB:', error)\n }\n}\n\n/**\n * Add action to queue\n */\nexport async function addToQueue(action: SyncAction, storageKey?: string): Promise<SyncQueueItem> {\n const queue = await getQueueFromStorage(storageKey)\n\n const item: SyncQueueItem = {\n id: generateId(),\n action,\n createdAt: Date.now(),\n attempts: 0,\n maxAttempts: 3,\n status: 'PENDING',\n }\n\n queue.push(item)\n await saveQueueToStorage(queue, storageKey)\n\n return item\n}\n\n/**\n * Remove item from queue\n */\nexport async function removeFromQueue(id: string, storageKey?: string): Promise<boolean> {\n const queue = await getQueueFromStorage(storageKey)\n const index = queue.findIndex((item) => item.id === id)\n\n if (index === -1) {\n return false\n }\n\n queue.splice(index, 1)\n await saveQueueToStorage(queue, storageKey)\n\n return true\n}\n\n/**\n * Process one queue item\n */\nexport async function processQueueItem(item: SyncQueueItem, handler: SyncActionHandler): Promise<ProcessQueueResult> {\n try {\n const result = await handler(item.action)\n\n if (result.success) {\n return {\n success: true,\n item: { ...item, status: 'SYNCED' as const },\n }\n }\n\n // Unsuccessful result without exception\n const updatedItem: SyncQueueItem = {\n ...item,\n attempts: item.attempts + 1,\n status: item.attempts + 1 >= item.maxAttempts ? 'FAILED' : 'PENDING',\n error: result.error,\n }\n\n return {\n success: false,\n item: updatedItem,\n error: result.error,\n }\n } catch (error) {\n // Exception during execution\n const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n const updatedItem: SyncQueueItem = {\n ...item,\n attempts: item.attempts + 1,\n status: item.attempts + 1 >= item.maxAttempts ? 'FAILED' : 'PENDING',\n error: errorMessage,\n }\n\n return {\n success: false,\n item: updatedItem,\n error: errorMessage,\n }\n }\n}\n\n/**\n * Clear queue\n */\nexport async function clearQueue(storageKey?: string): Promise<void> {\n try {\n const idb = await getIDB()\n if (!idb) {\n return\n }\n const key = storageKey ?? DEFAULT_SYNC_QUEUE_STORAGE_KEY\n await idb.del(key)\n } catch (error) {\n console.error('[OfflineService] Error clearing queue from IndexedDB:', error)\n }\n}\n\n/**\n * Create sync queue store\n */\nexport function createSyncQueueStore(storageKey?: string): SyncQueueStore {\n let queue: SyncQueueItem[] = []\n const listeners = new Set<() => void>()\n const key = storageKey ?? DEFAULT_SYNC_QUEUE_STORAGE_KEY\n\n const notifyListeners = () => {\n listeners.forEach((listener) => listener())\n }\n\n return {\n getQueue: () => queue,\n\n getQueueLength: () => queue.length,\n\n subscribe: (listener: () => void) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n\n initialize: async () => {\n queue = await getQueueFromStorage(key)\n notifyListeners()\n },\n\n add: async (action: SyncAction) => {\n const item = await addToQueue(action, key)\n queue.push(item)\n notifyListeners()\n return item\n },\n\n remove: async (id: string) => {\n const result = await removeFromQueue(id, key)\n if (result) {\n queue = queue.filter((item) => item.id !== id)\n notifyListeners()\n }\n return result\n },\n\n processAll: async (handler: SyncActionHandler) => {\n const results: ProcessQueueResult[] = []\n\n for (const item of queue) {\n if (item.status === 'PENDING') {\n const result = await processQueueItem(item, handler)\n results.push(result)\n\n // Update queue after processing\n if (result.success && result.item) {\n await removeFromQueue(item.id, key)\n queue = queue.filter((q) => q.id !== item.id)\n } else if (result.item) {\n // Update item in queue\n const index = queue.findIndex((q) => q.id === item.id)\n if (index !== -1) {\n queue[index] = result.item\n }\n await saveQueueToStorage(queue, key)\n }\n }\n }\n\n notifyListeners()\n return results\n },\n }\n}\n","'use client'\n\nimport { useSyncExternalStore } from 'react'\n\nimport { getOfflineStatus, subscribeToStatusChanges } from './offline-service'\n\n// Global state for synchronization across tabs\nlet isOffline = false\n\nconst listeners = new Set<() => void>()\n\nconst notifyListeners = () => {\n listeners.forEach((listener) => listener())\n}\n\n// Initialize on first load\nif (typeof window !== 'undefined') {\n isOffline = getOfflineStatus()\n\n subscribeToStatusChanges((offline) => {\n isOffline = offline\n notifyListeners()\n })\n}\n\n/**\n * Hook for detecting offline status\n *\n * @returns true if the browser is offline\n *\n * @example\n * ```tsx\n * import { useOfflineStatus } from '@lena/form-components/offline'\n *\n * function MyComponent() {\n * const isOffline = useOfflineStatus()\n *\n * if (isOffline) {\n * return <OfflineBanner />\n * }\n *\n * return <OnlineContent />\n * }\n * ```\n */\nexport function useOfflineStatus(): boolean {\n return useSyncExternalStore(\n (callback) => {\n listeners.add(callback)\n return () => {\n listeners.delete(callback)\n }\n },\n () => isOffline,\n () => false // SSR fallback — assume online\n )\n}\n","'use client'\n\nimport { useCallback, useEffect, useState, useSyncExternalStore } from 'react'\n\nimport { createSyncQueueStore } from './offline-service'\nimport type { ProcessQueueResult, SyncAction, SyncActionHandler, SyncQueueItem, UseSyncQueueResult } from './types'\nimport { useOfflineStatus } from './use-offline-status'\n\n// Global sync queue store (default)\nconst defaultSyncQueueStore = createSyncQueueStore()\nconst EMPTY_QUEUE: SyncQueueItem[] = []\n\n// Initialization flag\nlet initialized = false\n\nconst initialize = async () => {\n if (!initialized && typeof window !== 'undefined') {\n initialized = true\n await defaultSyncQueueStore.initialize()\n }\n}\n\n/**\n * Hook for working with the sync queue\n *\n * Allows adding actions to the queue in offline mode\n * and synchronizing them when connection is restored.\n *\n * @example\n * ```tsx\n * import { useSyncQueue } from '@lena/form-components/offline'\n *\n * function MyComponent() {\n * const { queue, queueLength, addAction, processQueue, isProcessing } = useSyncQueue()\n *\n * // Add action to queue (works offline too)\n * const handleBookLesson = async (slotId: string) => {\n * if (isOffline) {\n * await addAction({ type: 'BOOK_LESSON', payload: { slotId } })\n * toast({ title: 'Action added to sync queue' })\n * } else {\n * await api.bookLesson(slotId)\n * }\n * }\n *\n * // Process queue when connection is restored\n * useEffect(() => {\n * if (!isOffline && queueLength > 0) {\n * processQueue(async (action) => {\n * switch (action.type) {\n * case 'BOOK_LESSON':\n * return api.bookLesson(action.payload.slotId)\n * // ... other action types\n * }\n * })\n * }\n * }, [isOffline, queueLength, processQueue])\n * }\n * ```\n */\nexport function useSyncQueue(): UseSyncQueueResult {\n const [isLoading, setIsLoading] = useState(true)\n const [isProcessing, setIsProcessing] = useState(false)\n const isOffline = useOfflineStatus()\n\n // Subscribe to queue changes\n const queue = useSyncExternalStore(\n (callback) => defaultSyncQueueStore.subscribe(callback),\n () => defaultSyncQueueStore.getQueue(),\n () => EMPTY_QUEUE // SSR fallback\n )\n\n // Initialize on mount\n useEffect(() => {\n initialize().then(() => {\n setIsLoading(false)\n })\n }, [])\n\n // Add action to queue\n const addAction = useCallback(async (action: SyncAction): Promise<SyncQueueItem> => {\n return defaultSyncQueueStore.add(action)\n }, [])\n\n // Remove action from queue\n const removeAction = useCallback(async (id: string): Promise<boolean> => {\n return defaultSyncQueueStore.remove(id)\n }, [])\n\n // Process entire queue\n const processQueue = useCallback(\n async (handler: SyncActionHandler): Promise<ProcessQueueResult[]> => {\n if (isOffline) {\n console.warn('[SyncQueue] Cannot process queue in offline mode')\n return []\n }\n\n setIsProcessing(true)\n try {\n return await defaultSyncQueueStore.processAll(handler)\n } finally {\n setIsProcessing(false)\n }\n },\n [isOffline]\n )\n\n return {\n queue,\n queueLength: queue.length,\n pendingCount: queue.filter((item) => item.status === 'PENDING').length,\n isLoading,\n isProcessing,\n addAction,\n removeAction,\n processQueue,\n }\n}\n","'use client'\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\nimport type { OfflineSubmitResult, SyncAction, UseOfflineFormOptions, UseOfflineFormResult } from './types'\nimport { useOfflineStatus } from './use-offline-status'\nimport { useSyncQueue } from './use-sync-queue'\n\n/**\n * Hook for offline form support with TanStack Form\n *\n * Automatically detects connection status and:\n * - Online: sends data directly\n * - Offline: saves to IndexedDB queue for synchronization\n *\n * @example\n * ```tsx\n * import { useOfflineForm } from '@lena/form-components/offline'\n *\n * function ProfileForm({ initialData }) {\n * const { submit, isOffline, pendingCount, isProcessing } = useOfflineForm({\n * actionType: 'UPDATE_PROFILE',\n * onlineSubmit: async (value) => {\n * const result = await updateProfileAction(value)\n * return { success: result.success, error: result.error?.formErrors?.[0] }\n * },\n * onSuccess: () => toaster.success({ title: 'Saved' }),\n * onQueued: () => toaster.info({ title: 'Saved locally' }),\n * onError: (error) => toaster.error({ title: 'Error', description: error }),\n * })\n *\n * const form = useAppForm({\n * defaultValues: initialData,\n * onSubmit: async ({ value }) => {\n * await submit(value)\n * },\n * })\n *\n * return (\n * <form onSubmit={(e) => { e.preventDefault(); form.handleSubmit() }}>\n * {isOffline && <Badge colorPalette=\"orange\">Offline mode</Badge>}\n * {pendingCount > 0 && (\n * <Badge colorPalette=\"blue\">\n * {isProcessing ? 'Syncing...' : `Pending: ${pendingCount}`}\n * </Badge>\n * )}\n * <form.AppField name=\"name\" children={(field) => <field.TextField label=\"Name\" />} />\n * <Button type=\"submit\">{isOffline ? 'Save locally' : 'Save'}</Button>\n * </form>\n * )\n * }\n * ```\n */\nexport function useOfflineForm<T extends object>({\n actionType,\n onlineSubmit,\n onSuccess,\n onQueued,\n onError,\n}: UseOfflineFormOptions<T>): UseOfflineFormResult<T> {\n const isOffline = useOfflineStatus()\n const { addAction, processQueue, pendingCount, isProcessing, queueLength } = useSyncQueue()\n const [lastSyncAttempt, setLastSyncAttempt] = useState<number | null>(null)\n\n // Ref to prevent repeated queue processing\n const processingRef = useRef(false)\n\n /**\n * Form submission with offline support\n */\n const submit = useCallback(\n async (value: T): Promise<OfflineSubmitResult> => {\n // Offline — add to queue\n if (isOffline) {\n try {\n const queueItem = await addAction({\n type: actionType,\n payload: value as Record<string, unknown>,\n })\n\n onQueued?.()\n\n return {\n success: true,\n queued: true,\n queueItemId: queueItem.id,\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Error saving to queue'\n onError?.(errorMessage)\n return {\n success: false,\n error: errorMessage,\n }\n }\n }\n\n // Online — send directly\n try {\n const result = await onlineSubmit(value)\n\n if (result.success) {\n onSuccess?.()\n } else if (result.error) {\n onError?.(result.error)\n }\n\n return {\n success: result.success,\n error: result.error,\n queued: false,\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Submission error'\n onError?.(errorMessage)\n return {\n success: false,\n error: errorMessage,\n queued: false,\n }\n }\n },\n [isOffline, actionType, addAction, onlineSubmit, onSuccess, onQueued, onError]\n )\n\n /**\n * Handler for queued actions\n * Called when connection is restored\n */\n const handleQueuedAction = useCallback(\n async (action: SyncAction): Promise<{ success: boolean; error?: string }> => {\n // Process only our action type\n if (action.type !== actionType) {\n return { success: true } // Skip other action types\n }\n\n return onlineSubmit(action.payload as T)\n },\n [actionType, onlineSubmit]\n )\n\n // Automatic sync when connection is restored\n useEffect(() => {\n // If online and there are items in queue — try to sync\n if (!isOffline && pendingCount > 0 && !processingRef.current) {\n processingRef.current = true\n setLastSyncAttempt(Date.now())\n\n processQueue(handleQueuedAction)\n .then((results) => {\n const failed = results.filter((r) => !r.success)\n if (failed.length > 0) {\n console.warn(`[OfflineForm] ${failed.length} actions failed to sync`)\n }\n })\n .finally(() => {\n processingRef.current = false\n })\n }\n }, [isOffline, pendingCount, processQueue, handleQueuedAction])\n\n return {\n submit,\n isOffline,\n pendingCount,\n queueLength,\n isProcessing,\n lastSyncAttempt,\n }\n}\n","'use client'\n\nimport { Badge, type BadgeProps, HStack, Icon } from '@chakra-ui/react'\nimport { LuWifiOff } from 'react-icons/lu'\n\nimport type { OfflineIndicatorProps } from './types'\nimport { useOfflineStatus } from './use-offline-status'\n\n/**\n * Offline mode indicator\n *\n * Automatically shown when the browser is offline.\n * Hidden when connection is restored.\n *\n * @example\n * ```tsx\n * import { Form } from '@lena/form-components'\n *\n * <Form initialValue={data} onSubmit={handleSubmit}>\n * <Form.OfflineIndicator />\n * <Form.Field.String name=\"title\" />\n * <Form.Button.Submit />\n * </Form>\n * ```\n *\n * @example With custom settings\n * ```tsx\n * <Form.OfflineIndicator\n * label=\"No connection\"\n * colorPalette=\"red\"\n * variant=\"solid\"\n * />\n * ```\n */\nexport function FormOfflineIndicator({\n label = 'Offline mode',\n colorPalette = 'orange',\n variant = 'subtle',\n ...rest\n}: OfflineIndicatorProps & Omit<BadgeProps, 'children'>) {\n const isOffline = useOfflineStatus()\n\n if (!isOffline) {\n return null\n }\n\n return (\n <Badge colorPalette={colorPalette} variant={variant} data-testid=\"offline-indicator\" {...rest}>\n <HStack gap={1}>\n <Icon asChild boxSize={3}>\n <LuWifiOff />\n </Icon>\n <span>{label}</span>\n </HStack>\n </Badge>\n )\n}\n","'use client'\n\nimport { Badge, type BadgeProps, HStack, Icon, Spinner } from '@chakra-ui/react'\nimport { LuCheck, LuClock } from 'react-icons/lu'\n\nimport type { SyncStatusProps } from './types'\nimport { useOfflineStatus } from './use-offline-status'\nimport { useSyncQueue } from './use-sync-queue'\n\n/**\n * Sync queue status indicator\n *\n * Shows:\n * - Number of pending actions\n * - Spinner during synchronization\n * - \"Synced\" when queue is empty\n *\n * Works globally, does not require Form context.\n *\n * @example\n * ```tsx\n * import { FormSyncStatus } from '@lena/form-components/offline'\n *\n * // In layout or header\n * <FormSyncStatus />\n * ```\n *\n * @example With custom settings\n * ```tsx\n * <FormSyncStatus\n * showWhenEmpty={false}\n * syncingLabel=\"Syncing...\"\n * pendingLabel={(count) => `Pending: ${count}`}\n * syncedLabel=\"All synced\"\n * />\n * ```\n */\nexport function FormSyncStatus({\n showWhenEmpty = false,\n syncingLabel = 'Syncing...',\n pendingLabel = (count: number) => `Pending: ${count}`,\n syncedLabel = 'Synced',\n colorPalette = 'blue',\n ...rest\n}: SyncStatusProps & Omit<BadgeProps, 'children'>) {\n const isOffline = useOfflineStatus()\n const { pendingCount, isProcessing } = useSyncQueue()\n\n // Hide if online, queue empty and showWhenEmpty = false\n if (!isOffline && pendingCount === 0 && !isProcessing && !showWhenEmpty) {\n return null\n }\n\n // Determine what to display\n const renderContent = () => {\n // Synchronization in progress\n if (isProcessing) {\n return (\n <HStack gap={1}>\n <Spinner size=\"xs\" />\n <span>{syncingLabel}</span>\n </HStack>\n )\n }\n\n // There are pending items\n if (pendingCount > 0) {\n const label = typeof pendingLabel === 'function' ? pendingLabel(pendingCount) : pendingLabel\n return (\n <HStack gap={1}>\n <Icon asChild boxSize={3}>\n <LuClock />\n </Icon>\n <span>{label}</span>\n </HStack>\n )\n }\n\n // All synced\n return (\n <HStack gap={1}>\n <Icon asChild boxSize={3}>\n <LuCheck />\n </Icon>\n <span>{syncedLabel}</span>\n </HStack>\n )\n }\n\n // Color depends on state\n const effectiveColorPalette = pendingCount > 0 ? 'orange' : isProcessing ? colorPalette : 'green'\n\n return (\n <Badge\n colorPalette={effectiveColorPalette}\n variant=\"subtle\"\n data-testid=\"sync-status\"\n data-pending-count={pendingCount}\n data-processing={isProcessing}\n {...rest}\n >\n {renderContent()}\n </Badge>\n )\n}\n"]}
|