dalila 1.5.13 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +47 -0
  2. package/dist/componentes/ui/accordion/index.d.ts +2 -0
  3. package/dist/componentes/ui/accordion/index.js +114 -0
  4. package/dist/componentes/ui/calendar/index.d.ts +2 -0
  5. package/dist/componentes/ui/calendar/index.js +132 -0
  6. package/dist/componentes/ui/combobox/index.d.ts +2 -0
  7. package/dist/componentes/ui/combobox/index.js +161 -0
  8. package/dist/componentes/ui/dialog/index.d.ts +10 -0
  9. package/dist/componentes/ui/dialog/index.js +54 -0
  10. package/dist/componentes/ui/drawer/index.d.ts +2 -0
  11. package/dist/componentes/ui/drawer/index.js +41 -0
  12. package/dist/componentes/ui/dropdown/index.d.ts +2 -0
  13. package/dist/componentes/ui/dropdown/index.js +48 -0
  14. package/dist/componentes/ui/dropzone/index.d.ts +2 -0
  15. package/dist/componentes/ui/dropzone/index.js +92 -0
  16. package/dist/componentes/ui/env.d.ts +1 -0
  17. package/dist/componentes/ui/env.js +2 -0
  18. package/dist/componentes/ui/index.d.ts +13 -0
  19. package/dist/componentes/ui/index.js +12 -0
  20. package/dist/componentes/ui/popover/index.d.ts +2 -0
  21. package/dist/componentes/ui/popover/index.js +156 -0
  22. package/dist/componentes/ui/runtime.d.ts +20 -0
  23. package/dist/componentes/ui/runtime.js +421 -0
  24. package/dist/componentes/ui/tabs/index.d.ts +3 -0
  25. package/dist/componentes/ui/tabs/index.js +101 -0
  26. package/dist/componentes/ui/toast/index.d.ts +3 -0
  27. package/dist/componentes/ui/toast/index.js +115 -0
  28. package/dist/componentes/ui/ui-types.d.ts +175 -0
  29. package/dist/componentes/ui/ui-types.js +1 -0
  30. package/dist/componentes/ui/validate.d.ts +7 -0
  31. package/dist/componentes/ui/validate.js +71 -0
  32. package/dist/components/ui/accordion/index.d.ts +2 -0
  33. package/dist/components/ui/accordion/index.js +114 -0
  34. package/dist/components/ui/calendar/index.d.ts +2 -0
  35. package/dist/components/ui/calendar/index.js +132 -0
  36. package/dist/components/ui/combobox/index.d.ts +2 -0
  37. package/dist/components/ui/combobox/index.js +161 -0
  38. package/dist/components/ui/dialog/index.d.ts +10 -0
  39. package/dist/components/ui/dialog/index.js +54 -0
  40. package/dist/components/ui/drawer/index.d.ts +2 -0
  41. package/dist/components/ui/drawer/index.js +41 -0
  42. package/dist/components/ui/dropdown/index.d.ts +2 -0
  43. package/dist/components/ui/dropdown/index.js +48 -0
  44. package/dist/components/ui/dropzone/index.d.ts +2 -0
  45. package/dist/components/ui/dropzone/index.js +92 -0
  46. package/dist/components/ui/env.d.ts +1 -0
  47. package/dist/components/ui/env.js +2 -0
  48. package/dist/components/ui/index.d.ts +13 -0
  49. package/dist/components/ui/index.js +12 -0
  50. package/dist/components/ui/popover/index.d.ts +2 -0
  51. package/dist/components/ui/popover/index.js +156 -0
  52. package/dist/components/ui/runtime.d.ts +20 -0
  53. package/dist/components/ui/runtime.js +421 -0
  54. package/dist/components/ui/tabs/index.d.ts +3 -0
  55. package/dist/components/ui/tabs/index.js +101 -0
  56. package/dist/components/ui/toast/index.d.ts +3 -0
  57. package/dist/components/ui/toast/index.js +115 -0
  58. package/dist/components/ui/ui-types.d.ts +175 -0
  59. package/dist/components/ui/ui-types.js +1 -0
  60. package/dist/components/ui/validate.d.ts +7 -0
  61. package/dist/components/ui/validate.js +71 -0
  62. package/dist/form/form-types.d.ts +181 -0
  63. package/dist/form/form-types.js +4 -0
  64. package/dist/form/form.d.ts +71 -0
  65. package/dist/form/form.js +1073 -0
  66. package/dist/form/index.d.ts +2 -0
  67. package/dist/form/index.js +2 -0
  68. package/dist/index.d.ts +1 -0
  69. package/dist/index.js +1 -0
  70. package/dist/runtime/bind.js +567 -9
  71. package/dist/ui/accordion.d.ts +2 -0
  72. package/dist/ui/accordion.js +114 -0
  73. package/dist/ui/calendar.d.ts +2 -0
  74. package/dist/ui/calendar.js +132 -0
  75. package/dist/ui/combobox.d.ts +2 -0
  76. package/dist/ui/combobox.js +161 -0
  77. package/dist/ui/dialog.d.ts +10 -0
  78. package/dist/ui/dialog.js +54 -0
  79. package/dist/ui/drawer.d.ts +2 -0
  80. package/dist/ui/drawer.js +41 -0
  81. package/dist/ui/dropdown.d.ts +2 -0
  82. package/dist/ui/dropdown.js +48 -0
  83. package/dist/ui/dropzone.d.ts +2 -0
  84. package/dist/ui/dropzone.js +92 -0
  85. package/dist/ui/env.d.ts +1 -0
  86. package/dist/ui/env.js +2 -0
  87. package/dist/ui/index.d.ts +13 -0
  88. package/dist/ui/index.js +12 -0
  89. package/dist/ui/popover.d.ts +2 -0
  90. package/dist/ui/popover.js +156 -0
  91. package/dist/ui/runtime.d.ts +20 -0
  92. package/dist/ui/runtime.js +421 -0
  93. package/dist/ui/tabs.d.ts +3 -0
  94. package/dist/ui/tabs.js +101 -0
  95. package/dist/ui/toast.d.ts +3 -0
  96. package/dist/ui/toast.js +115 -0
  97. package/dist/ui/ui-types.d.ts +175 -0
  98. package/dist/ui/ui-types.js +1 -0
  99. package/dist/ui/validate.d.ts +7 -0
  100. package/dist/ui/validate.js +71 -0
  101. package/package.json +60 -2
  102. package/src/components/ui/accordion/accordion.css +90 -0
  103. package/src/components/ui/alert/alert.css +78 -0
  104. package/src/components/ui/avatar/avatar.css +45 -0
  105. package/src/components/ui/badge/badge.css +71 -0
  106. package/src/components/ui/breadcrumb/breadcrumb.css +41 -0
  107. package/src/components/ui/button/button.css +135 -0
  108. package/src/components/ui/calendar/calendar.css +96 -0
  109. package/src/components/ui/card/card.css +93 -0
  110. package/src/components/ui/checkbox/checkbox.css +57 -0
  111. package/src/components/ui/chip/chip.css +62 -0
  112. package/src/components/ui/collapsible/collapsible.css +61 -0
  113. package/src/components/ui/combobox/combobox.css +85 -0
  114. package/src/components/ui/dalila/dalila.css +42 -0
  115. package/src/components/ui/dalila-core/dalila-core.css +14 -0
  116. package/src/components/ui/dialog/dialog.css +125 -0
  117. package/src/components/ui/drawer/drawer.css +122 -0
  118. package/src/components/ui/dropdown/dropdown.css +87 -0
  119. package/src/components/ui/dropzone/dropzone.css +47 -0
  120. package/src/components/ui/empty-state/empty-state.css +33 -0
  121. package/src/components/ui/form/form.css +44 -0
  122. package/src/components/ui/input/input.css +106 -0
  123. package/src/components/ui/layout/layout.css +62 -0
  124. package/src/components/ui/pagination/pagination.css +55 -0
  125. package/src/components/ui/popover/popover.css +55 -0
  126. package/src/components/ui/radio/radio.css +56 -0
  127. package/src/components/ui/separator/separator.css +38 -0
  128. package/src/components/ui/skeleton/skeleton.css +57 -0
  129. package/src/components/ui/slider/slider.css +60 -0
  130. package/src/components/ui/spinner/spinner.css +38 -0
  131. package/src/components/ui/table/table.css +54 -0
  132. package/src/components/ui/tabs/tabs.css +74 -0
  133. package/src/components/ui/toast/toast.css +100 -0
  134. package/src/components/ui/toggle/toggle.css +90 -0
  135. package/src/components/ui/tokens/tokens.css +161 -0
  136. package/src/components/ui/tooltip/tooltip.css +53 -0
  137. package/src/components/ui/typography/typography.css +81 -0
@@ -0,0 +1,175 @@
1
+ import type { Signal } from "../../core/signal.js";
2
+ export interface DialogOptions {
3
+ closeOnBackdrop?: boolean;
4
+ closeOnEscape?: boolean;
5
+ }
6
+ export interface Dialog {
7
+ open: Signal<boolean>;
8
+ show(): void;
9
+ close(): void;
10
+ toggle(): void;
11
+ _attachTo(el: HTMLDialogElement): void;
12
+ }
13
+ export type DrawerSide = "right" | "left" | "bottom";
14
+ export interface DrawerOptions extends DialogOptions {
15
+ side?: DrawerSide;
16
+ }
17
+ export interface Drawer extends Dialog {
18
+ side: Signal<DrawerSide>;
19
+ }
20
+ export type ToastVariant = "success" | "error" | "warning" | "info";
21
+ export type ToastPosition = "top-right" | "top-left" | "bottom-right" | "bottom-left" | "top-center" | "bottom-center";
22
+ export interface ToastItem {
23
+ id: string;
24
+ variant: ToastVariant;
25
+ title: string;
26
+ text?: string;
27
+ variantClass: string;
28
+ icon: string;
29
+ }
30
+ export interface ToastOptions {
31
+ position?: ToastPosition;
32
+ duration?: number;
33
+ maxToasts?: number;
34
+ }
35
+ export interface Toast {
36
+ items: Signal<ToastItem[]>;
37
+ activeVariant: Signal<ToastVariant | "idle">;
38
+ containerClass: Signal<string>;
39
+ show(variant: ToastVariant, title: string, text?: string, duration?: number): string;
40
+ success(title: string, text?: string): string;
41
+ error(title: string, text?: string): string;
42
+ warning(title: string, text?: string): string;
43
+ info(title: string, text?: string): string;
44
+ dismiss(id: string): void;
45
+ clear(): void;
46
+ }
47
+ export interface TabsOptions {
48
+ initial?: string;
49
+ orientation?: "horizontal" | "vertical";
50
+ }
51
+ export interface Tabs {
52
+ active: Signal<string>;
53
+ select(tabId: string): void;
54
+ isActive(tabId: string): boolean;
55
+ handleClick(ev: Event): void;
56
+ _attachTo(el: HTMLElement): void;
57
+ }
58
+ export interface TabBindings {
59
+ tabClass: Signal<string>;
60
+ selected: Signal<string>;
61
+ visible: Signal<boolean>;
62
+ }
63
+ export interface DropdownOptions {
64
+ closeOnSelect?: boolean;
65
+ }
66
+ export interface Dropdown {
67
+ open: Signal<boolean>;
68
+ toggle(ev?: Event): void;
69
+ close(): void;
70
+ select(ev?: Event): void;
71
+ _attachTo(el: HTMLElement): void;
72
+ }
73
+ export interface ComboboxOption {
74
+ value: string;
75
+ label: string;
76
+ }
77
+ export interface ComboboxOptions {
78
+ options: ComboboxOption[];
79
+ placeholder?: string;
80
+ name?: string;
81
+ }
82
+ export interface Combobox {
83
+ open: Signal<boolean>;
84
+ query: Signal<string>;
85
+ value: Signal<string>;
86
+ label: Signal<string>;
87
+ filtered: Signal<ComboboxOption[]>;
88
+ highlightedIndex: Signal<number>;
89
+ show(): void;
90
+ close(): void;
91
+ toggle(): void;
92
+ handleInput(ev: Event): void;
93
+ handleSelect(ev: Event): void;
94
+ handleKeydown(ev: KeyboardEvent): void;
95
+ _attachTo(el: HTMLElement): void;
96
+ }
97
+ export interface AccordionOptions {
98
+ single?: boolean;
99
+ initial?: string[];
100
+ }
101
+ export interface Accordion {
102
+ openItems: Signal<Set<string>>;
103
+ toggle(itemId: string): void;
104
+ open(itemId: string): void;
105
+ close(itemId: string): void;
106
+ isOpen(itemId: string): Signal<boolean>;
107
+ _attachTo(el: HTMLElement): void;
108
+ }
109
+ export interface CalendarDay {
110
+ date: number;
111
+ month: "prev" | "current" | "next";
112
+ fullDate: Date;
113
+ isToday: boolean;
114
+ isSelected: boolean;
115
+ disabled: boolean;
116
+ }
117
+ export interface CalendarOptions {
118
+ initial?: Date;
119
+ min?: Date;
120
+ max?: Date;
121
+ dayLabels?: string[];
122
+ monthLabels?: string[];
123
+ }
124
+ export interface Calendar {
125
+ year: Signal<number>;
126
+ month: Signal<number>;
127
+ selected: Signal<Date | null>;
128
+ title: Signal<string>;
129
+ days: Signal<CalendarDay[]>;
130
+ dayLabels: string[];
131
+ prev(): void;
132
+ next(): void;
133
+ select(date: Date): void;
134
+ handleDayClick(ev: Event): void;
135
+ }
136
+ export interface DropzoneOptions {
137
+ accept?: string;
138
+ multiple?: boolean;
139
+ maxFiles?: number;
140
+ maxSize?: number;
141
+ }
142
+ export interface Dropzone {
143
+ dragging: Signal<boolean>;
144
+ files: Signal<File[]>;
145
+ browse(): void;
146
+ handleClick(): void;
147
+ handleDragover(ev: DragEvent): void;
148
+ handleDragleave(): void;
149
+ handleDrop(ev: DragEvent): void;
150
+ _attachTo(el: HTMLElement): void;
151
+ }
152
+ export type PopoverPlacement = "top" | "bottom" | "left" | "right" | "top-start" | "bottom-start";
153
+ export interface PopoverOptions {
154
+ placement?: PopoverPlacement;
155
+ gap?: number;
156
+ viewportPadding?: number;
157
+ }
158
+ export interface Popover {
159
+ open: Signal<boolean>;
160
+ placement: Signal<PopoverPlacement>;
161
+ show(): void;
162
+ hide(): void;
163
+ toggle(): void;
164
+ position(trigger: HTMLElement, popoverEl: HTMLElement): void;
165
+ _attachTo(trigger: HTMLElement, popoverEl: HTMLElement): void;
166
+ }
167
+ export interface TabsMount {
168
+ api: Tabs;
169
+ bindings: [string, string][];
170
+ }
171
+ export interface PopoverMount {
172
+ api: Popover;
173
+ triggerId?: string;
174
+ panelId?: string;
175
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ export declare function validateDialogOptions(opts: Record<string, unknown>): void;
2
+ export declare function validateDrawerOptions(opts: Record<string, unknown>): void;
3
+ export declare function validateToastOptions(opts: Record<string, unknown>): void;
4
+ export declare function validatePopoverOptions(opts: Record<string, unknown>): void;
5
+ export declare function validateDropzoneOptions(opts: Record<string, unknown>): void;
6
+ export declare function validateCalendarOptions(opts: Record<string, unknown>): void;
7
+ export declare function validateComboboxOptions(opts: Record<string, unknown>): void;
@@ -0,0 +1,71 @@
1
+ // ── Prop Validation ─────────────────────────────────────────────────
2
+ const VALID_TOAST_POSITIONS = new Set([
3
+ "top-right", "top-left", "bottom-right", "bottom-left", "top-center", "bottom-center",
4
+ ]);
5
+ const VALID_POPOVER_PLACEMENTS = new Set([
6
+ "top", "bottom", "left", "right", "top-start", "bottom-start",
7
+ ]);
8
+ const VALID_DRAWER_SIDES = new Set(["right", "left", "bottom"]);
9
+ function warn(component, message) {
10
+ console.warn(`[Dalila] ${component}: ${message}`);
11
+ }
12
+ function warnInvalidType(component, prop, expected, got) {
13
+ warn(component, `"${prop}" expected ${expected}, got ${typeof got} (${String(got)})`);
14
+ }
15
+ export function validateDialogOptions(opts) {
16
+ if (opts.closeOnBackdrop !== undefined && typeof opts.closeOnBackdrop !== "boolean") {
17
+ warnInvalidType("createDialog", "closeOnBackdrop", "boolean", opts.closeOnBackdrop);
18
+ }
19
+ if (opts.closeOnEscape !== undefined && typeof opts.closeOnEscape !== "boolean") {
20
+ warnInvalidType("createDialog", "closeOnEscape", "boolean", opts.closeOnEscape);
21
+ }
22
+ }
23
+ export function validateDrawerOptions(opts) {
24
+ validateDialogOptions(opts);
25
+ if (opts.side !== undefined && !VALID_DRAWER_SIDES.has(opts.side)) {
26
+ warn("createDrawer", `"side" must be one of "right"|"left"|"bottom", got "${String(opts.side)}"`);
27
+ }
28
+ }
29
+ export function validateToastOptions(opts) {
30
+ if (opts.position !== undefined && !VALID_TOAST_POSITIONS.has(opts.position)) {
31
+ warn("createToast", `"position" must be a valid ToastPosition, got "${String(opts.position)}"`);
32
+ }
33
+ if (opts.duration !== undefined && (typeof opts.duration !== "number" || opts.duration < 0)) {
34
+ warn("createToast", `"duration" must be a number >= 0, got ${String(opts.duration)}`);
35
+ }
36
+ if (opts.maxToasts !== undefined && (typeof opts.maxToasts !== "number" || opts.maxToasts <= 0)) {
37
+ warn("createToast", `"maxToasts" must be a number > 0, got ${String(opts.maxToasts)}`);
38
+ }
39
+ }
40
+ export function validatePopoverOptions(opts) {
41
+ if (opts.placement !== undefined && !VALID_POPOVER_PLACEMENTS.has(opts.placement)) {
42
+ warn("createPopover", `"placement" must be a valid PopoverPlacement, got "${String(opts.placement)}"`);
43
+ }
44
+ if (opts.gap !== undefined && (typeof opts.gap !== "number" || opts.gap < 0)) {
45
+ warn("createPopover", `"gap" must be a number >= 0, got ${String(opts.gap)}`);
46
+ }
47
+ if (opts.viewportPadding !== undefined && (typeof opts.viewportPadding !== "number" || opts.viewportPadding < 0)) {
48
+ warn("createPopover", `"viewportPadding" must be a number >= 0, got ${String(opts.viewportPadding)}`);
49
+ }
50
+ }
51
+ export function validateDropzoneOptions(opts) {
52
+ if (opts.maxFiles !== undefined && (typeof opts.maxFiles !== "number" || opts.maxFiles <= 0)) {
53
+ warn("createDropzone", `"maxFiles" must be a number > 0, got ${String(opts.maxFiles)}`);
54
+ }
55
+ if (opts.maxSize !== undefined && (typeof opts.maxSize !== "number" || opts.maxSize <= 0)) {
56
+ warn("createDropzone", `"maxSize" must be a number > 0, got ${String(opts.maxSize)}`);
57
+ }
58
+ }
59
+ export function validateCalendarOptions(opts) {
60
+ const min = opts.min;
61
+ const max = opts.max;
62
+ if (min && max && min > max) {
63
+ warn("createCalendar", `"min" must be before "max"`);
64
+ }
65
+ }
66
+ export function validateComboboxOptions(opts) {
67
+ const options = opts.options;
68
+ if (!Array.isArray(options) || options.length === 0) {
69
+ warn("createCombobox", `"options" must be a non-empty array`);
70
+ }
71
+ }
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Type utilities for path-based access
3
+ */
4
+ export type FieldErrors = Record<string, string>;
5
+ export interface FormSubmitContext {
6
+ signal: AbortSignal;
7
+ }
8
+ export interface FormOptions<T> {
9
+ /**
10
+ * Default values for the form.
11
+ * Can be a static object, a function returning values, or a promise.
12
+ */
13
+ defaultValues?: Partial<T> | (() => Partial<T>) | (() => Promise<Partial<T>>);
14
+ /**
15
+ * Custom parser for FormData → T.
16
+ * If not provided, uses the built-in parser with dot/bracket notation.
17
+ */
18
+ parse?: (formEl: HTMLFormElement, fd: FormData) => T;
19
+ /**
20
+ * Client-side validation function.
21
+ * Returns { fieldErrors?, formError? } or just fieldErrors.
22
+ */
23
+ validate?: (data: T) => FieldErrors | {
24
+ fieldErrors?: FieldErrors;
25
+ formError?: string;
26
+ } | void;
27
+ /**
28
+ * When to run validation:
29
+ * - "submit" (default): only on submit
30
+ * - "blur": on field blur after first submit
31
+ * - "change": on every change after first submit
32
+ */
33
+ validateOn?: 'submit' | 'blur' | 'change';
34
+ /**
35
+ * Transform server errors into form errors.
36
+ * Useful for mapping backend error formats to field paths.
37
+ */
38
+ transformServerErrors?: (error: unknown) => {
39
+ fieldErrors?: FieldErrors;
40
+ formError?: string;
41
+ } | void;
42
+ }
43
+ export interface Form<T> {
44
+ /**
45
+ * Creates a submit handler that:
46
+ * - prevents default
47
+ * - collects FormData
48
+ * - parses to T
49
+ * - validates (if configured)
50
+ * - calls handler with data and AbortSignal
51
+ * - cancels previous submit if re-submitted
52
+ */
53
+ handleSubmit(handler: (data: T, ctx: FormSubmitContext) => Promise<unknown> | unknown): (ev: SubmitEvent) => void;
54
+ /**
55
+ * Reset form to initial/new defaults
56
+ */
57
+ reset(nextDefaults?: Partial<T>): void;
58
+ /**
59
+ * Set error for a specific field
60
+ */
61
+ setError(path: string, message: string): void;
62
+ /**
63
+ * Set form-level error
64
+ */
65
+ setFormError(message: string): void;
66
+ /**
67
+ * Clear errors (all or by prefix)
68
+ */
69
+ clearErrors(prefix?: string): void;
70
+ /**
71
+ * Get error message for a field
72
+ */
73
+ error(path: string): string | null;
74
+ /**
75
+ * Get form-level error
76
+ */
77
+ formError(): string | null;
78
+ /**
79
+ * Check if field has been touched
80
+ */
81
+ touched(path: string): boolean;
82
+ /**
83
+ * Check if field is dirty (value differs from default)
84
+ */
85
+ dirty(path: string): boolean;
86
+ /**
87
+ * Check if form is currently submitting
88
+ */
89
+ submitting(): boolean;
90
+ /**
91
+ * Get submit count
92
+ */
93
+ submitCount(): number;
94
+ /**
95
+ * Focus first error field (or specific field)
96
+ */
97
+ focus(path?: string): void;
98
+ /**
99
+ * Internal: register a field element
100
+ * @internal
101
+ */
102
+ _registerField(path: string, element: HTMLElement): () => void;
103
+ /**
104
+ * Internal: get form element
105
+ * @internal
106
+ */
107
+ _getFormElement(): HTMLFormElement | null;
108
+ /**
109
+ * Internal: set form element
110
+ * @internal
111
+ */
112
+ _setFormElement(form: HTMLFormElement): void;
113
+ /**
114
+ * Create or get a field array
115
+ */
116
+ fieldArray<TItem = unknown>(path: string): FieldArray<TItem>;
117
+ }
118
+ export interface FieldArrayItem<T = unknown> {
119
+ key: string;
120
+ value?: T;
121
+ }
122
+ export interface FieldArray<TItem = unknown> {
123
+ /**
124
+ * Get array of items with stable keys
125
+ */
126
+ fields(): FieldArrayItem<TItem>[];
127
+ /**
128
+ * Append item(s) to the end
129
+ */
130
+ append(value: TItem | TItem[]): void;
131
+ /**
132
+ * Remove item by key
133
+ */
134
+ remove(key: string): void;
135
+ /**
136
+ * Remove item by index
137
+ */
138
+ removeAt(index: number): void;
139
+ /**
140
+ * Insert item at index
141
+ */
142
+ insert(index: number, value: TItem): void;
143
+ /**
144
+ * Move item from one index to another
145
+ */
146
+ move(fromIndex: number, toIndex: number): void;
147
+ /**
148
+ * Swap two items by index
149
+ */
150
+ swap(indexA: number, indexB: number): void;
151
+ /**
152
+ * Replace entire array
153
+ */
154
+ replace(values: TItem[]): void;
155
+ /**
156
+ * Update a specific item by key
157
+ */
158
+ update(key: string, value: TItem): void;
159
+ /**
160
+ * Update a specific item by index
161
+ */
162
+ updateAt(index: number, value: TItem): void;
163
+ /**
164
+ * Clear all items
165
+ */
166
+ clear(): void;
167
+ /**
168
+ * Get current length
169
+ */
170
+ length(): number;
171
+ /**
172
+ * Internal: translate index-based path to key-based path
173
+ * @internal
174
+ */
175
+ _translatePath(path: string): string | null;
176
+ /**
177
+ * Internal: get current index for a key
178
+ * @internal
179
+ */
180
+ _getIndex(key: string): number;
181
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Type utilities for path-based access
3
+ */
4
+ export {};
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Dalila Forms - DOM-first reactive form management
3
+ *
4
+ * Design principles:
5
+ * - Values live in the DOM (uncontrolled by default)
6
+ * - Meta-state in memory (errors, touched, dirty, submitting)
7
+ * - Declarative HTML via directives
8
+ * - Scope-safe with automatic cleanup
9
+ * - Race-safe submits with AbortController
10
+ * - Field arrays with stable keys
11
+ */
12
+ import type { Form, FormOptions } from './form-types.js';
13
+ /**
14
+ * Symbol to mark handlers that have been wrapped by handleSubmit().
15
+ * Used by bindForm to avoid double-wrapping.
16
+ */
17
+ export declare const WRAPPED_HANDLER: unique symbol;
18
+ /**
19
+ * Parse FormData into a nested object structure.
20
+ *
21
+ * Supports:
22
+ * - Simple fields: "email" → { email: "..." }
23
+ * - Nested objects: "user.name" → { user: { name: "..." } }
24
+ * - Arrays: "phones[0].number" → { phones: [{ number: "..." }] }
25
+ * - Checkboxes: single = boolean, multiple = array of values
26
+ * - Select multiple: array of selected values
27
+ * - Radio: single value
28
+ * - Files: File object
29
+ *
30
+ * ## Checkbox Parsing Contract
31
+ *
32
+ * HTML FormData omits unchecked checkboxes entirely. To resolve this ambiguity,
33
+ * parseFormData() inspects the DOM to distinguish between "field missing" vs "checkbox unchecked".
34
+ *
35
+ * ### Single Checkbox (one input with unique name)
36
+ * When there is exactly ONE checkbox with a given name:
37
+ * - Checked (with or without value) → `true`
38
+ * - Unchecked → `false`
39
+ * - Value attribute is ignored (always returns boolean)
40
+ *
41
+ * Example:
42
+ * ```html
43
+ * <input type="checkbox" name="agree" />
44
+ * ```
45
+ * Result: `{ agree: false }` (unchecked) or `{ agree: true }` (checked)
46
+ *
47
+ * ### Multiple Checkboxes (same name, multiple inputs)
48
+ * When there are MULTIPLE checkboxes with the same name:
49
+ * - Result is ALWAYS an array
50
+ * - Some checked → `["value1", "value2"]`
51
+ * - None checked → `[]`
52
+ * - One checked → `["value1"]` (still an array!)
53
+ *
54
+ * Example:
55
+ * ```html
56
+ * <input type="checkbox" name="colors" value="red" checked />
57
+ * <input type="checkbox" name="colors" value="blue" />
58
+ * <input type="checkbox" name="colors" value="green" checked />
59
+ * ```
60
+ * Result: `{ colors: ["red", "green"] }`
61
+ *
62
+ * ### Edge Cases
63
+ * - Radio buttons: Unchecked radio → field absent (standard HTML behavior)
64
+ * - Select multiple: Always returns array (like multiple checkboxes)
65
+ *
66
+ * @param form - The form element to parse (used for DOM inspection)
67
+ * @param fd - FormData instance from the form
68
+ * @returns Parsed form data with nested structure
69
+ */
70
+ export declare function parseFormData<T = unknown>(form: HTMLFormElement, fd: FormData): T;
71
+ export declare function createForm<T = unknown>(options?: FormOptions<T>): Form<T>;