@tachui/forms 0.7.0-alpha1 → 0.7.1-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"Form-ueYEcSg1.cjs","sources":["../src/components/Form.ts"],"sourcesContent":["/**\n * Form Component\n *\n * SwiftUI-inspired form container with validation, state management,\n * and comprehensive form handling capabilities.\n */\n\nimport type {\n Component,\n ComponentChildren,\n ComponentInstance,\n ComponentProps,\n DOMNode,\n} from '@tachui/core'\nimport { createEffect, createSignal, defaultChildrenRenderer, h, text } from '@tachui/core'\nimport { createFormState } from '../state'\nimport type { FormProps } from '../types'\n\n/**\n * Helper function to render form children with form context injection\n */\nfunction renderFormChildren(children: ComponentChildren, formContext: any): DOMNode[] {\n // If children is an array, handle each child\n if (Array.isArray(children)) {\n return children.flatMap((child) => renderSingleChild(child, formContext))\n }\n\n // Single child\n return renderSingleChild(children, formContext)\n}\n\n/**\n * Render a single child with form context\n */\nfunction renderSingleChild(child: ComponentChildren, formContext: any): DOMNode[] {\n // Handle null/undefined\n if (child === null || child === undefined) {\n return []\n }\n\n // Handle ComponentInstance objects - inject form context\n if (typeof child === 'object' && 'type' in child && child.type === 'component') {\n const childWithContext = {\n ...child,\n props: {\n ...child.props,\n _formContext: formContext,\n },\n }\n // Bind the render function to the new object so 'this.props' works correctly\n const boundRender = child.render.bind(childWithContext)\n const rendered = boundRender()\n return Array.isArray(rendered) ? rendered : [rendered]\n }\n\n // Use default children renderer for everything else (strings, numbers, DOMNodes, etc.)\n return defaultChildrenRenderer(child)\n}\n\n/**\n * Form component implementation\n */\nexport const Form: Component<FormProps> = (props) => {\n const {\n onSubmit,\n onChange,\n validation = {\n validateOn: 'blur',\n stopOnFirstError: false,\n debounceMs: 300,\n },\n initialValues = {},\n resetOnSubmit = false,\n preserveValues = false,\n children,\n ...restProps\n } = props\n\n // Create form state manager\n const formManager = createFormState(initialValues)\n const [submissionResult, setSubmissionResult] = createSignal<'idle' | 'success' | 'error'>('idle')\n\n // Handle form submission\n const handleSubmit = async (event?: Event) => {\n if (event) {\n event.preventDefault()\n }\n\n if (!onSubmit) {\n return\n }\n\n try {\n setSubmissionResult('idle')\n\n // Validate form before submission\n const isValid = await formManager.validateForm()\n\n if (isValid) {\n const values = formManager.watch()\n await onSubmit(values, formManager.state)\n setSubmissionResult('success')\n\n if (resetOnSubmit) {\n formManager.resetForm()\n }\n } else {\n setSubmissionResult('error')\n }\n } catch (error) {\n setSubmissionResult('error')\n console.error('Form submission error:', error)\n }\n }\n\n // Handle form changes\n createEffect(() => {\n if (onChange) {\n // const values = formManager.watch()\n const state = formManager.state\n\n // Find the last changed field (this is a simplification)\n const changedFields = Object.keys(state.fields).filter((name) => state.fields[name].dirty)\n if (changedFields.length > 0) {\n const lastChanged = changedFields[changedFields.length - 1]\n const fieldState = state.fields[lastChanged]\n onChange(lastChanged, fieldState.value, fieldState)\n }\n }\n })\n\n // Create form context for child components\n const formContext = {\n register: formManager.register,\n unregister: formManager.unregister,\n setValue: formManager.setValue,\n getValue: formManager.getValue,\n getError: formManager.getError,\n validateField: formManager.validateField,\n validation,\n onChange,\n }\n\n const componentInstance: ComponentInstance = {\n type: 'component',\n id: restProps.id || 'form',\n render: () =>\n h(\n 'form',\n {\n ...restProps,\n onsubmit: handleSubmit,\n novalidate: true, // We handle validation ourselves\n 'data-tachui-form': true,\n 'data-form-state': formManager.state.valid ? 'valid' : 'invalid',\n 'data-form-submitting': formManager.state.submitting,\n 'data-submission-result': submissionResult(),\n },\n ...renderFormChildren(children, formContext)\n ),\n props: props,\n cleanup: [\n () => {\n // Cleanup form state if not preserving values\n if (!preserveValues) {\n formManager.resetForm()\n }\n },\n ],\n }\n\n return componentInstance\n}\n\n/**\n * Enhanced FormSection component for grouping form fields\n * \n * Combines the semantic benefits of <fieldset> with the rich styling\n * and functionality from Core Section component. Provides the best\n * of both worlds: proper form semantics and comprehensive features.\n */\nexport const FormSection: Component<\n {\n // Content (enhanced from Core Section)\n title?: string\n description?: string\n header?: string | (() => string) | ComponentInstance\n footer?: string | (() => string) | ComponentInstance\n children: ComponentChildren\n\n // Styling (from Core Section)\n style?: 'automatic' | 'grouped' | 'inset' | 'plain' | 'sidebar'\n spacing?: number\n\n // Behavior (enhanced from Core Section)\n collapsible?: boolean\n collapsed?: boolean\n onToggle?: (collapsed: boolean) => void\n\n // Accessibility\n accessibilityLabel?: string\n accessibilityRole?: string\n } & ComponentProps\n> = (props) => {\n const {\n title,\n description, \n header,\n footer,\n style = 'automatic',\n spacing = 12,\n collapsible = false,\n collapsed: initialCollapsed = false,\n onToggle,\n accessibilityLabel,\n accessibilityRole = 'group',\n children,\n ...restProps\n } = props\n\n const [collapsed, setCollapsed] = createSignal(initialCollapsed)\n\n // Handle toggle with optional callback\n const handleToggle = () => {\n const newCollapsed = !collapsed()\n setCollapsed(newCollapsed)\n if (onToggle) {\n onToggle(newCollapsed)\n }\n }\n\n // Resolve dynamic content (from Core Section)\n const resolveContent = (content: string | (() => string) | ComponentInstance | undefined) => {\n if (!content) return null\n if (typeof content === 'string') return content\n if (typeof content === 'function') return content()\n return content\n }\n\n // Get section styles based on style prop (adapted from Core Section)\n const getSectionStyles = () => {\n const baseStyles = {\n marginBottom: '20px',\n border: 'none', // Remove default fieldset border\n padding: '0', // Remove default fieldset padding\n margin: '0 0 20px 0', // Override default fieldset margin\n }\n\n switch (style) {\n case 'grouped':\n return {\n ...baseStyles,\n backgroundColor: '#ffffff',\n border: '1px solid #e0e0e0',\n borderRadius: '12px',\n overflow: 'hidden' as const,\n }\n\n case 'inset':\n return {\n ...baseStyles,\n backgroundColor: '#f8f9fa',\n border: '1px solid #e9ecef',\n borderRadius: '8px',\n margin: '0 16px 20px 16px',\n }\n\n case 'sidebar':\n return {\n ...baseStyles,\n borderLeft: '3px solid #007AFF',\n paddingLeft: '16px',\n backgroundColor: '#f8f9fa',\n borderRadius: '0 8px 8px 0',\n }\n\n case 'plain':\n return baseStyles\n default:\n return {\n ...baseStyles,\n backgroundColor: '#ffffff',\n border: '1px solid #f0f0f0',\n borderRadius: '8px',\n }\n }\n }\n\n // Get header styles (adapted from Core Section)\n const getHeaderStyles = () => {\n const baseStyles = {\n fontSize: '16px',\n fontWeight: '600' as const,\n color: '#1a1a1a',\n margin: '0 0 12px 0',\n }\n\n switch (style) {\n case 'grouped':\n case 'inset':\n return {\n ...baseStyles,\n padding: '12px 16px 0 16px',\n backgroundColor: '#f8f9fa',\n borderBottom: '1px solid #e9ecef',\n }\n\n case 'sidebar':\n return {\n ...baseStyles,\n fontSize: '14px',\n textTransform: 'uppercase' as const,\n letterSpacing: '0.5px',\n color: '#666',\n marginBottom: '8px',\n }\n\n default:\n return {\n ...baseStyles,\n padding: '0 0 8px 0',\n }\n }\n }\n\n // Get content styles (adapted from Core Section)\n const getContentStyles = () => {\n const baseStyles = {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: `${spacing}px`,\n }\n\n switch (style) {\n case 'grouped':\n case 'inset':\n return {\n ...baseStyles,\n padding: '16px',\n }\n\n case 'sidebar':\n return {\n ...baseStyles,\n padding: '8px 0',\n }\n\n default:\n return {\n ...baseStyles,\n padding: '12px',\n }\n }\n }\n\n // Get footer styles (adapted from Core Section)\n const getFooterStyles = () => {\n const baseStyles = {\n fontSize: '14px',\n color: '#666',\n margin: '8px 0 0 0',\n }\n\n switch (style) {\n case 'grouped':\n case 'inset':\n return {\n ...baseStyles,\n padding: '0 16px 12px 16px',\n backgroundColor: '#f8f9fa',\n borderTop: '1px solid #e9ecef',\n }\n\n default:\n return {\n ...baseStyles,\n padding: '0 0 4px 0',\n }\n }\n }\n\n // Render header content\n const renderHeader = () => {\n // Prioritize title over header for backwards compatibility\n const headerContent = title || resolveContent(header)\n if (!headerContent) return []\n\n const headerStyles = getHeaderStyles()\n\n // Add collapse toggle if collapsible\n if (collapsible) {\n const toggleIcon = collapsed() ? '▶' : '▼'\n\n return [\n h(\n 'legend',\n {\n style: {\n ...headerStyles,\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n onclick: handleToggle,\n },\n h(\n 'span',\n {\n style: {\n fontSize: '12px',\n color: '#666',\n },\n },\n text(toggleIcon)\n ),\n ...(typeof headerContent === 'string'\n ? [text(headerContent)]\n : [headerContent.render()].flat())\n )\n ]\n }\n\n return [\n h(\n 'legend',\n { style: headerStyles },\n ...(typeof headerContent === 'string'\n ? [text(headerContent)]\n : [headerContent.render()].flat())\n )\n ]\n }\n\n // Render description if provided (backwards compatibility)\n const renderDescription = () => {\n if (!description || collapsed()) return []\n \n return [\n h(\n 'div',\n {\n style: {\n fontSize: '14px',\n color: '#666',\n marginBottom: '12px',\n padding: style === 'grouped' || style === 'inset' ? '0 16px' : '0',\n },\n },\n text(description)\n )\n ]\n }\n\n // Render content\n const renderContent = () => {\n // Don't render content if collapsed\n if (collapsible && collapsed()) {\n return []\n }\n\n return [\n h(\n 'div',\n {\n style: getContentStyles(),\n },\n ...renderFormChildren(children, (props as any)._formContext)\n )\n ]\n }\n\n // Render footer content\n const renderFooter = () => {\n const footerContent = resolveContent(footer)\n if (!footerContent || collapsed()) return []\n\n return [\n h(\n 'div',\n {\n style: getFooterStyles(),\n },\n ...(typeof footerContent === 'string'\n ? [text(footerContent)]\n : [footerContent.render()].flat())\n )\n ]\n }\n\n const componentInstance: ComponentInstance = {\n type: 'component',\n id: restProps.id || 'form-section',\n render: () =>\n h(\n 'fieldset',\n {\n ...restProps,\n style: getSectionStyles(),\n 'aria-label': accessibilityLabel,\n role: accessibilityRole,\n 'data-tachui-form-section': true,\n 'data-collapsible': collapsible,\n 'data-collapsed': collapsed(),\n 'data-style': style,\n },\n ...renderHeader(),\n ...renderDescription(),\n ...renderContent(),\n ...renderFooter()\n ),\n props: props,\n }\n\n return componentInstance\n}\n\n/**\n * Form utilities and helpers\n */\nexport const FormUtils = {\n /**\n * Create a form with automatic field registration\n */\n createAutoForm: (schema: any) => {\n // This would be implemented to automatically generate form fields\n // based on a JSON schema - simplified for now\n console.log('Auto form creation:', schema)\n return Form\n },\n\n /**\n * Form validation utilities\n */\n validation: {\n /**\n * Create a validation schema from field definitions\n */\n createSchema: (fields: Record<string, any>) => {\n return {\n fields,\n validate: async (_values: Record<string, any>) => {\n // TODO: Implement schema-based validation\n return { valid: true, errors: {} }\n },\n }\n },\n },\n\n /**\n * Form serialization utilities\n */\n serialize: {\n /**\n * Convert form values to FormData\n */\n toFormData: (values: Record<string, any>): FormData => {\n const formData = new FormData()\n\n Object.entries(values).forEach(([key, value]) => {\n if (value !== null && value !== undefined) {\n if (value instanceof File || value instanceof Blob) {\n formData.append(key, value)\n } else if (Array.isArray(value)) {\n value.forEach((item, index) => {\n formData.append(`${key}[${index}]`, String(item))\n })\n } else {\n formData.append(key, String(value))\n }\n }\n })\n\n return formData\n },\n\n /**\n * Convert form values to URL search params\n */\n toURLSearchParams: (values: Record<string, any>): URLSearchParams => {\n const params = new URLSearchParams()\n\n Object.entries(values).forEach(([key, value]) => {\n if (value !== null && value !== undefined) {\n if (Array.isArray(value)) {\n value.forEach((item) => params.append(key, String(item)))\n } else {\n params.append(key, String(value))\n }\n }\n })\n\n return params\n },\n\n /**\n * Convert form values to JSON\n */\n toJSON: (values: Record<string, any>): string => {\n return JSON.stringify(values, null, 2)\n },\n },\n}\n\n// Export form-related types for convenience\nexport type { FormProps, FormState } from '../types'\n"],"names":["renderFormChildren","children","formContext","child","renderSingleChild","childWithContext","rendered","defaultChildrenRenderer","Form","props","onSubmit","onChange","validation","initialValues","resetOnSubmit","preserveValues","restProps","formManager","createFormState","submissionResult","setSubmissionResult","createSignal","handleSubmit","event","values","error","createEffect","state","changedFields","name","lastChanged","fieldState","h","FormSection","title","description","header","footer","style","spacing","collapsible","initialCollapsed","onToggle","accessibilityLabel","accessibilityRole","collapsed","setCollapsed","handleToggle","newCollapsed","resolveContent","content","getSectionStyles","baseStyles","getHeaderStyles","getContentStyles","getFooterStyles","renderHeader","headerContent","headerStyles","toggleIcon","text","renderDescription","renderContent","renderFooter","footerContent","FormUtils","schema","fields","_values","formData","key","value","item","index","params"],"mappings":"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"}
@@ -1,376 +0,0 @@
1
- import { createSignal as R, createEffect as B, h as f, text as m, defaultChildrenRenderer as L } from "@tachui/core";
2
- import { a as j } from "./forms-core-B1bx1drO.js";
3
- function w(r, t) {
4
- return Array.isArray(r) ? r.flatMap((o) => v(o, t)) : v(r, t);
5
- }
6
- function v(r, t) {
7
- if (r == null)
8
- return [];
9
- if (typeof r == "object" && "type" in r && r.type === "component") {
10
- const o = {
11
- ...r,
12
- props: {
13
- ...r.props,
14
- _formContext: t
15
- }
16
- }, a = r.render.bind(o)();
17
- return Array.isArray(a) ? a : [a];
18
- }
19
- return L(r);
20
- }
21
- const P = (r) => {
22
- const {
23
- onSubmit: t,
24
- onChange: o,
25
- validation: n = {
26
- validateOn: "blur",
27
- stopOnFirstError: !1,
28
- debounceMs: 300
29
- },
30
- initialValues: a = {},
31
- resetOnSubmit: i = !1,
32
- preserveValues: S = !1,
33
- children: g,
34
- ...b
35
- } = r, s = j(a), [h, u] = R("idle"), C = async (l) => {
36
- if (l && l.preventDefault(), !!t)
37
- try {
38
- if (u("idle"), await s.validateForm()) {
39
- const d = s.watch();
40
- await t(d, s.state), u("success"), i && s.resetForm();
41
- } else
42
- u("error");
43
- } catch (c) {
44
- u("error"), console.error("Form submission error:", c);
45
- }
46
- };
47
- B(() => {
48
- if (o) {
49
- const l = s.state, c = Object.keys(l.fields).filter((d) => l.fields[d].dirty);
50
- if (c.length > 0) {
51
- const d = c[c.length - 1], y = l.fields[d];
52
- o(d, y.value, y);
53
- }
54
- }
55
- });
56
- const x = {
57
- register: s.register,
58
- unregister: s.unregister,
59
- setValue: s.setValue,
60
- getValue: s.getValue,
61
- getError: s.getError,
62
- validateField: s.validateField,
63
- validation: n,
64
- onChange: o
65
- };
66
- return {
67
- type: "component",
68
- id: b.id || "form",
69
- render: () => f(
70
- "form",
71
- {
72
- ...b,
73
- onsubmit: C,
74
- novalidate: !0,
75
- // We handle validation ourselves
76
- "data-tachui-form": !0,
77
- "data-form-state": s.state.valid ? "valid" : "invalid",
78
- "data-form-submitting": s.state.submitting,
79
- "data-submission-result": h()
80
- },
81
- ...w(g, x)
82
- ),
83
- props: r,
84
- cleanup: [
85
- () => {
86
- S || s.resetForm();
87
- }
88
- ]
89
- };
90
- }, _ = (r) => {
91
- const {
92
- title: t,
93
- description: o,
94
- header: n,
95
- footer: a,
96
- style: i = "automatic",
97
- spacing: S = 12,
98
- collapsible: g = !1,
99
- collapsed: b = !1,
100
- onToggle: s,
101
- accessibilityLabel: h,
102
- accessibilityRole: u = "group",
103
- children: C,
104
- ...x
105
- } = r, [p, l] = R(b), c = () => {
106
- const e = !p();
107
- l(e), s && s(e);
108
- }, d = (e) => e ? typeof e == "string" ? e : typeof e == "function" ? e() : e : null, y = () => {
109
- const e = {
110
- marginBottom: "20px",
111
- border: "none",
112
- // Remove default fieldset border
113
- padding: "0",
114
- // Remove default fieldset padding
115
- margin: "0 0 20px 0"
116
- // Override default fieldset margin
117
- };
118
- switch (i) {
119
- case "grouped":
120
- return {
121
- ...e,
122
- backgroundColor: "#ffffff",
123
- border: "1px solid #e0e0e0",
124
- borderRadius: "12px",
125
- overflow: "hidden"
126
- };
127
- case "inset":
128
- return {
129
- ...e,
130
- backgroundColor: "#f8f9fa",
131
- border: "1px solid #e9ecef",
132
- borderRadius: "8px",
133
- margin: "0 16px 20px 16px"
134
- };
135
- case "sidebar":
136
- return {
137
- ...e,
138
- borderLeft: "3px solid #007AFF",
139
- paddingLeft: "16px",
140
- backgroundColor: "#f8f9fa",
141
- borderRadius: "0 8px 8px 0"
142
- };
143
- case "plain":
144
- return e;
145
- default:
146
- return {
147
- ...e,
148
- backgroundColor: "#ffffff",
149
- border: "1px solid #f0f0f0",
150
- borderRadius: "8px"
151
- };
152
- }
153
- }, A = () => {
154
- const e = {
155
- fontSize: "16px",
156
- fontWeight: "600",
157
- color: "#1a1a1a",
158
- margin: "0 0 12px 0"
159
- };
160
- switch (i) {
161
- case "grouped":
162
- case "inset":
163
- return {
164
- ...e,
165
- padding: "12px 16px 0 16px",
166
- backgroundColor: "#f8f9fa",
167
- borderBottom: "1px solid #e9ecef"
168
- };
169
- case "sidebar":
170
- return {
171
- ...e,
172
- fontSize: "14px",
173
- textTransform: "uppercase",
174
- letterSpacing: "0.5px",
175
- color: "#666",
176
- marginBottom: "8px"
177
- };
178
- default:
179
- return {
180
- ...e,
181
- padding: "0 0 8px 0"
182
- };
183
- }
184
- }, E = () => {
185
- const e = {
186
- display: "flex",
187
- flexDirection: "column",
188
- gap: `${S}px`
189
- };
190
- switch (i) {
191
- case "grouped":
192
- case "inset":
193
- return {
194
- ...e,
195
- padding: "16px"
196
- };
197
- case "sidebar":
198
- return {
199
- ...e,
200
- padding: "8px 0"
201
- };
202
- default:
203
- return {
204
- ...e,
205
- padding: "12px"
206
- };
207
- }
208
- }, O = () => {
209
- const e = {
210
- fontSize: "14px",
211
- color: "#666",
212
- margin: "8px 0 0 0"
213
- };
214
- switch (i) {
215
- case "grouped":
216
- case "inset":
217
- return {
218
- ...e,
219
- padding: "0 16px 12px 16px",
220
- backgroundColor: "#f8f9fa",
221
- borderTop: "1px solid #e9ecef"
222
- };
223
- default:
224
- return {
225
- ...e,
226
- padding: "0 0 4px 0"
227
- };
228
- }
229
- }, V = () => {
230
- const e = t || d(n);
231
- if (!e) return [];
232
- const F = A();
233
- if (g) {
234
- const k = p() ? "▶" : "▼";
235
- return [
236
- f(
237
- "legend",
238
- {
239
- style: {
240
- ...F,
241
- cursor: "pointer",
242
- display: "flex",
243
- alignItems: "center",
244
- gap: "8px"
245
- },
246
- onclick: c
247
- },
248
- f(
249
- "span",
250
- {
251
- style: {
252
- fontSize: "12px",
253
- color: "#666"
254
- }
255
- },
256
- m(k)
257
- ),
258
- ...typeof e == "string" ? [m(e)] : [e.render()].flat()
259
- )
260
- ];
261
- }
262
- return [
263
- f(
264
- "legend",
265
- { style: F },
266
- ...typeof e == "string" ? [m(e)] : [e.render()].flat()
267
- )
268
- ];
269
- }, z = () => !o || p() ? [] : [
270
- f(
271
- "div",
272
- {
273
- style: {
274
- fontSize: "14px",
275
- color: "#666",
276
- marginBottom: "12px",
277
- padding: i === "grouped" || i === "inset" ? "0 16px" : "0"
278
- }
279
- },
280
- m(o)
281
- )
282
- ], D = () => g && p() ? [] : [
283
- f(
284
- "div",
285
- {
286
- style: E()
287
- },
288
- ...w(C, r._formContext)
289
- )
290
- ], I = () => {
291
- const e = d(a);
292
- return !e || p() ? [] : [
293
- f(
294
- "div",
295
- {
296
- style: O()
297
- },
298
- ...typeof e == "string" ? [m(e)] : [e.render()].flat()
299
- )
300
- ];
301
- };
302
- return {
303
- type: "component",
304
- id: x.id || "form-section",
305
- render: () => f(
306
- "fieldset",
307
- {
308
- ...x,
309
- style: y(),
310
- "aria-label": h,
311
- role: u,
312
- "data-tachui-form-section": !0,
313
- "data-collapsible": g,
314
- "data-collapsed": p(),
315
- "data-style": i
316
- },
317
- ...V(),
318
- ...z(),
319
- ...D(),
320
- ...I()
321
- ),
322
- props: r
323
- };
324
- }, $ = {
325
- /**
326
- * Create a form with automatic field registration
327
- */
328
- createAutoForm: (r) => (console.log("Auto form creation:", r), P),
329
- /**
330
- * Form validation utilities
331
- */
332
- validation: {
333
- /**
334
- * Create a validation schema from field definitions
335
- */
336
- createSchema: (r) => ({
337
- fields: r,
338
- validate: async (t) => ({ valid: !0, errors: {} })
339
- })
340
- },
341
- /**
342
- * Form serialization utilities
343
- */
344
- serialize: {
345
- /**
346
- * Convert form values to FormData
347
- */
348
- toFormData: (r) => {
349
- const t = new FormData();
350
- return Object.entries(r).forEach(([o, n]) => {
351
- n != null && (n instanceof File || n instanceof Blob ? t.append(o, n) : Array.isArray(n) ? n.forEach((a, i) => {
352
- t.append(`${o}[${i}]`, String(a));
353
- }) : t.append(o, String(n)));
354
- }), t;
355
- },
356
- /**
357
- * Convert form values to URL search params
358
- */
359
- toURLSearchParams: (r) => {
360
- const t = new URLSearchParams();
361
- return Object.entries(r).forEach(([o, n]) => {
362
- n != null && (Array.isArray(n) ? n.forEach((a) => t.append(o, String(a))) : t.append(o, String(n)));
363
- }), t;
364
- },
365
- /**
366
- * Convert form values to JSON
367
- */
368
- toJSON: (r) => JSON.stringify(r, null, 2)
369
- }
370
- };
371
- export {
372
- P as F,
373
- _ as a,
374
- $ as b
375
- };
376
- //# sourceMappingURL=Form-ylAr3o_e.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Form-ylAr3o_e.js","sources":["../src/components/Form.ts"],"sourcesContent":["/**\n * Form Component\n *\n * SwiftUI-inspired form container with validation, state management,\n * and comprehensive form handling capabilities.\n */\n\nimport type {\n Component,\n ComponentChildren,\n ComponentInstance,\n ComponentProps,\n DOMNode,\n} from '@tachui/core'\nimport { createEffect, createSignal, defaultChildrenRenderer, h, text } from '@tachui/core'\nimport { createFormState } from '../state'\nimport type { FormProps } from '../types'\n\n/**\n * Helper function to render form children with form context injection\n */\nfunction renderFormChildren(children: ComponentChildren, formContext: any): DOMNode[] {\n // If children is an array, handle each child\n if (Array.isArray(children)) {\n return children.flatMap((child) => renderSingleChild(child, formContext))\n }\n\n // Single child\n return renderSingleChild(children, formContext)\n}\n\n/**\n * Render a single child with form context\n */\nfunction renderSingleChild(child: ComponentChildren, formContext: any): DOMNode[] {\n // Handle null/undefined\n if (child === null || child === undefined) {\n return []\n }\n\n // Handle ComponentInstance objects - inject form context\n if (typeof child === 'object' && 'type' in child && child.type === 'component') {\n const childWithContext = {\n ...child,\n props: {\n ...child.props,\n _formContext: formContext,\n },\n }\n // Bind the render function to the new object so 'this.props' works correctly\n const boundRender = child.render.bind(childWithContext)\n const rendered = boundRender()\n return Array.isArray(rendered) ? rendered : [rendered]\n }\n\n // Use default children renderer for everything else (strings, numbers, DOMNodes, etc.)\n return defaultChildrenRenderer(child)\n}\n\n/**\n * Form component implementation\n */\nexport const Form: Component<FormProps> = (props) => {\n const {\n onSubmit,\n onChange,\n validation = {\n validateOn: 'blur',\n stopOnFirstError: false,\n debounceMs: 300,\n },\n initialValues = {},\n resetOnSubmit = false,\n preserveValues = false,\n children,\n ...restProps\n } = props\n\n // Create form state manager\n const formManager = createFormState(initialValues)\n const [submissionResult, setSubmissionResult] = createSignal<'idle' | 'success' | 'error'>('idle')\n\n // Handle form submission\n const handleSubmit = async (event?: Event) => {\n if (event) {\n event.preventDefault()\n }\n\n if (!onSubmit) {\n return\n }\n\n try {\n setSubmissionResult('idle')\n\n // Validate form before submission\n const isValid = await formManager.validateForm()\n\n if (isValid) {\n const values = formManager.watch()\n await onSubmit(values, formManager.state)\n setSubmissionResult('success')\n\n if (resetOnSubmit) {\n formManager.resetForm()\n }\n } else {\n setSubmissionResult('error')\n }\n } catch (error) {\n setSubmissionResult('error')\n console.error('Form submission error:', error)\n }\n }\n\n // Handle form changes\n createEffect(() => {\n if (onChange) {\n // const values = formManager.watch()\n const state = formManager.state\n\n // Find the last changed field (this is a simplification)\n const changedFields = Object.keys(state.fields).filter((name) => state.fields[name].dirty)\n if (changedFields.length > 0) {\n const lastChanged = changedFields[changedFields.length - 1]\n const fieldState = state.fields[lastChanged]\n onChange(lastChanged, fieldState.value, fieldState)\n }\n }\n })\n\n // Create form context for child components\n const formContext = {\n register: formManager.register,\n unregister: formManager.unregister,\n setValue: formManager.setValue,\n getValue: formManager.getValue,\n getError: formManager.getError,\n validateField: formManager.validateField,\n validation,\n onChange,\n }\n\n const componentInstance: ComponentInstance = {\n type: 'component',\n id: restProps.id || 'form',\n render: () =>\n h(\n 'form',\n {\n ...restProps,\n onsubmit: handleSubmit,\n novalidate: true, // We handle validation ourselves\n 'data-tachui-form': true,\n 'data-form-state': formManager.state.valid ? 'valid' : 'invalid',\n 'data-form-submitting': formManager.state.submitting,\n 'data-submission-result': submissionResult(),\n },\n ...renderFormChildren(children, formContext)\n ),\n props: props,\n cleanup: [\n () => {\n // Cleanup form state if not preserving values\n if (!preserveValues) {\n formManager.resetForm()\n }\n },\n ],\n }\n\n return componentInstance\n}\n\n/**\n * Enhanced FormSection component for grouping form fields\n * \n * Combines the semantic benefits of <fieldset> with the rich styling\n * and functionality from Core Section component. Provides the best\n * of both worlds: proper form semantics and comprehensive features.\n */\nexport const FormSection: Component<\n {\n // Content (enhanced from Core Section)\n title?: string\n description?: string\n header?: string | (() => string) | ComponentInstance\n footer?: string | (() => string) | ComponentInstance\n children: ComponentChildren\n\n // Styling (from Core Section)\n style?: 'automatic' | 'grouped' | 'inset' | 'plain' | 'sidebar'\n spacing?: number\n\n // Behavior (enhanced from Core Section)\n collapsible?: boolean\n collapsed?: boolean\n onToggle?: (collapsed: boolean) => void\n\n // Accessibility\n accessibilityLabel?: string\n accessibilityRole?: string\n } & ComponentProps\n> = (props) => {\n const {\n title,\n description, \n header,\n footer,\n style = 'automatic',\n spacing = 12,\n collapsible = false,\n collapsed: initialCollapsed = false,\n onToggle,\n accessibilityLabel,\n accessibilityRole = 'group',\n children,\n ...restProps\n } = props\n\n const [collapsed, setCollapsed] = createSignal(initialCollapsed)\n\n // Handle toggle with optional callback\n const handleToggle = () => {\n const newCollapsed = !collapsed()\n setCollapsed(newCollapsed)\n if (onToggle) {\n onToggle(newCollapsed)\n }\n }\n\n // Resolve dynamic content (from Core Section)\n const resolveContent = (content: string | (() => string) | ComponentInstance | undefined) => {\n if (!content) return null\n if (typeof content === 'string') return content\n if (typeof content === 'function') return content()\n return content\n }\n\n // Get section styles based on style prop (adapted from Core Section)\n const getSectionStyles = () => {\n const baseStyles = {\n marginBottom: '20px',\n border: 'none', // Remove default fieldset border\n padding: '0', // Remove default fieldset padding\n margin: '0 0 20px 0', // Override default fieldset margin\n }\n\n switch (style) {\n case 'grouped':\n return {\n ...baseStyles,\n backgroundColor: '#ffffff',\n border: '1px solid #e0e0e0',\n borderRadius: '12px',\n overflow: 'hidden' as const,\n }\n\n case 'inset':\n return {\n ...baseStyles,\n backgroundColor: '#f8f9fa',\n border: '1px solid #e9ecef',\n borderRadius: '8px',\n margin: '0 16px 20px 16px',\n }\n\n case 'sidebar':\n return {\n ...baseStyles,\n borderLeft: '3px solid #007AFF',\n paddingLeft: '16px',\n backgroundColor: '#f8f9fa',\n borderRadius: '0 8px 8px 0',\n }\n\n case 'plain':\n return baseStyles\n default:\n return {\n ...baseStyles,\n backgroundColor: '#ffffff',\n border: '1px solid #f0f0f0',\n borderRadius: '8px',\n }\n }\n }\n\n // Get header styles (adapted from Core Section)\n const getHeaderStyles = () => {\n const baseStyles = {\n fontSize: '16px',\n fontWeight: '600' as const,\n color: '#1a1a1a',\n margin: '0 0 12px 0',\n }\n\n switch (style) {\n case 'grouped':\n case 'inset':\n return {\n ...baseStyles,\n padding: '12px 16px 0 16px',\n backgroundColor: '#f8f9fa',\n borderBottom: '1px solid #e9ecef',\n }\n\n case 'sidebar':\n return {\n ...baseStyles,\n fontSize: '14px',\n textTransform: 'uppercase' as const,\n letterSpacing: '0.5px',\n color: '#666',\n marginBottom: '8px',\n }\n\n default:\n return {\n ...baseStyles,\n padding: '0 0 8px 0',\n }\n }\n }\n\n // Get content styles (adapted from Core Section)\n const getContentStyles = () => {\n const baseStyles = {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: `${spacing}px`,\n }\n\n switch (style) {\n case 'grouped':\n case 'inset':\n return {\n ...baseStyles,\n padding: '16px',\n }\n\n case 'sidebar':\n return {\n ...baseStyles,\n padding: '8px 0',\n }\n\n default:\n return {\n ...baseStyles,\n padding: '12px',\n }\n }\n }\n\n // Get footer styles (adapted from Core Section)\n const getFooterStyles = () => {\n const baseStyles = {\n fontSize: '14px',\n color: '#666',\n margin: '8px 0 0 0',\n }\n\n switch (style) {\n case 'grouped':\n case 'inset':\n return {\n ...baseStyles,\n padding: '0 16px 12px 16px',\n backgroundColor: '#f8f9fa',\n borderTop: '1px solid #e9ecef',\n }\n\n default:\n return {\n ...baseStyles,\n padding: '0 0 4px 0',\n }\n }\n }\n\n // Render header content\n const renderHeader = () => {\n // Prioritize title over header for backwards compatibility\n const headerContent = title || resolveContent(header)\n if (!headerContent) return []\n\n const headerStyles = getHeaderStyles()\n\n // Add collapse toggle if collapsible\n if (collapsible) {\n const toggleIcon = collapsed() ? '▶' : '▼'\n\n return [\n h(\n 'legend',\n {\n style: {\n ...headerStyles,\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n onclick: handleToggle,\n },\n h(\n 'span',\n {\n style: {\n fontSize: '12px',\n color: '#666',\n },\n },\n text(toggleIcon)\n ),\n ...(typeof headerContent === 'string'\n ? [text(headerContent)]\n : [headerContent.render()].flat())\n )\n ]\n }\n\n return [\n h(\n 'legend',\n { style: headerStyles },\n ...(typeof headerContent === 'string'\n ? [text(headerContent)]\n : [headerContent.render()].flat())\n )\n ]\n }\n\n // Render description if provided (backwards compatibility)\n const renderDescription = () => {\n if (!description || collapsed()) return []\n \n return [\n h(\n 'div',\n {\n style: {\n fontSize: '14px',\n color: '#666',\n marginBottom: '12px',\n padding: style === 'grouped' || style === 'inset' ? '0 16px' : '0',\n },\n },\n text(description)\n )\n ]\n }\n\n // Render content\n const renderContent = () => {\n // Don't render content if collapsed\n if (collapsible && collapsed()) {\n return []\n }\n\n return [\n h(\n 'div',\n {\n style: getContentStyles(),\n },\n ...renderFormChildren(children, (props as any)._formContext)\n )\n ]\n }\n\n // Render footer content\n const renderFooter = () => {\n const footerContent = resolveContent(footer)\n if (!footerContent || collapsed()) return []\n\n return [\n h(\n 'div',\n {\n style: getFooterStyles(),\n },\n ...(typeof footerContent === 'string'\n ? [text(footerContent)]\n : [footerContent.render()].flat())\n )\n ]\n }\n\n const componentInstance: ComponentInstance = {\n type: 'component',\n id: restProps.id || 'form-section',\n render: () =>\n h(\n 'fieldset',\n {\n ...restProps,\n style: getSectionStyles(),\n 'aria-label': accessibilityLabel,\n role: accessibilityRole,\n 'data-tachui-form-section': true,\n 'data-collapsible': collapsible,\n 'data-collapsed': collapsed(),\n 'data-style': style,\n },\n ...renderHeader(),\n ...renderDescription(),\n ...renderContent(),\n ...renderFooter()\n ),\n props: props,\n }\n\n return componentInstance\n}\n\n/**\n * Form utilities and helpers\n */\nexport const FormUtils = {\n /**\n * Create a form with automatic field registration\n */\n createAutoForm: (schema: any) => {\n // This would be implemented to automatically generate form fields\n // based on a JSON schema - simplified for now\n console.log('Auto form creation:', schema)\n return Form\n },\n\n /**\n * Form validation utilities\n */\n validation: {\n /**\n * Create a validation schema from field definitions\n */\n createSchema: (fields: Record<string, any>) => {\n return {\n fields,\n validate: async (_values: Record<string, any>) => {\n // TODO: Implement schema-based validation\n return { valid: true, errors: {} }\n },\n }\n },\n },\n\n /**\n * Form serialization utilities\n */\n serialize: {\n /**\n * Convert form values to FormData\n */\n toFormData: (values: Record<string, any>): FormData => {\n const formData = new FormData()\n\n Object.entries(values).forEach(([key, value]) => {\n if (value !== null && value !== undefined) {\n if (value instanceof File || value instanceof Blob) {\n formData.append(key, value)\n } else if (Array.isArray(value)) {\n value.forEach((item, index) => {\n formData.append(`${key}[${index}]`, String(item))\n })\n } else {\n formData.append(key, String(value))\n }\n }\n })\n\n return formData\n },\n\n /**\n * Convert form values to URL search params\n */\n toURLSearchParams: (values: Record<string, any>): URLSearchParams => {\n const params = new URLSearchParams()\n\n Object.entries(values).forEach(([key, value]) => {\n if (value !== null && value !== undefined) {\n if (Array.isArray(value)) {\n value.forEach((item) => params.append(key, String(item)))\n } else {\n params.append(key, String(value))\n }\n }\n })\n\n return params\n },\n\n /**\n * Convert form values to JSON\n */\n toJSON: (values: Record<string, any>): string => {\n return JSON.stringify(values, null, 2)\n },\n },\n}\n\n// Export form-related types for convenience\nexport type { FormProps, FormState } from '../types'\n"],"names":["renderFormChildren","children","formContext","child","renderSingleChild","childWithContext","rendered","defaultChildrenRenderer","Form","props","onSubmit","onChange","validation","initialValues","resetOnSubmit","preserveValues","restProps","formManager","createFormState","submissionResult","setSubmissionResult","createSignal","handleSubmit","event","values","error","createEffect","state","changedFields","name","lastChanged","fieldState","h","FormSection","title","description","header","footer","style","spacing","collapsible","initialCollapsed","onToggle","accessibilityLabel","accessibilityRole","collapsed","setCollapsed","handleToggle","newCollapsed","resolveContent","content","getSectionStyles","baseStyles","getHeaderStyles","getContentStyles","getFooterStyles","renderHeader","headerContent","headerStyles","toggleIcon","text","renderDescription","renderContent","renderFooter","footerContent","FormUtils","schema","fields","_values","formData","key","value","item","index","params"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("../Form-ueYEcSg1.cjs"),e=require("../forms-inputs-DQ5QI_SU.cjs"),o=require("../forms-complex-DLEnXXJ5.cjs");exports.Form=i.Form;exports.FormSection=i.FormSection;exports.FormUtils=i.FormUtils;exports.Checkbox=e.Checkbox;exports.CheckboxGroup=e.CheckboxGroup;exports.ColorField=e.ColorField;exports.CreditCardField=e.CreditCardField;exports.DateField=e.DateField;exports.EmailField=e.EmailField;exports.NumberField=e.NumberField;exports.PasswordField=e.PasswordField;exports.PhoneField=e.PhoneField;exports.PostalCodeField=e.PostalCodeField;exports.Radio=e.Radio;exports.RadioGroup=e.RadioGroup;exports.SSNField=e.SSNField;exports.SearchField=e.SearchField;exports.Switch=e.Switch;exports.TextArea=e.TextArea;exports.TextField=e.TextField;exports.TimeField=e.TimeField;exports.URLField=e.URLField;exports.Combobox=o.Combobox;exports.MultiSelect=o.MultiSelect;exports.Select=o.Select;
2
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}