@coherent.js/forms 1.0.0-rc.6 → 1.0.1

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,4 +1,5 @@
1
1
  // src/form-builder.js
2
+ import { render as renderToHTML } from "@coherent.js/core";
2
3
  var FormBuilder = class {
3
4
  constructor(options = {}) {
4
5
  this.options = {
@@ -286,17 +287,8 @@ var FormBuilder = class {
286
287
  /**
287
288
  * Convert form to HTML string
288
289
  */
289
- toHTML() {
290
- const fields = this.getFields();
291
- let html = `<form name="${this.options.name}">`;
292
- fields.forEach((field) => {
293
- html += `<div class="form-field">`;
294
- html += `<label for="${field.name}">${field.label}</label>`;
295
- html += `<input type="${field.type}" name="${field.name}" id="${field.name}">`;
296
- html += `</div>`;
297
- });
298
- html += `</form>`;
299
- return html;
290
+ toHTML(options = {}) {
291
+ return renderToHTML(this.buildForm(options));
300
292
  }
301
293
  /**
302
294
  * Mark field as touched
@@ -335,6 +327,29 @@ var FormBuilder = class {
335
327
  if (validatorNames) {
336
328
  inputProps["data-validators"] = validatorNames;
337
329
  }
330
+ if (field.type === "textarea" || field.type === "select") {
331
+ const { type: _type, value: _value, ...rest } = inputProps;
332
+ const props = { ...rest };
333
+ if (field.type === "textarea") {
334
+ return { textarea: { ...props, text: String(value) } };
335
+ }
336
+ const { placeholder: _placeholder, ...selectProps } = props;
337
+ return {
338
+ select: {
339
+ ...selectProps,
340
+ children: (field.options ?? []).map((option) => {
341
+ const { value: optionValue, label = optionValue } = typeof option === "object" && option !== null ? option : { value: option };
342
+ return {
343
+ option: {
344
+ value: optionValue,
345
+ selected: String(optionValue) === String(value) || void 0,
346
+ text: String(label)
347
+ }
348
+ };
349
+ })
350
+ }
351
+ };
352
+ }
338
353
  return {
339
354
  input: inputProps
340
355
  };
@@ -398,22 +413,53 @@ var FormBuilder = class {
398
413
  for (const [name] of this.fields) {
399
414
  fields.push(this.buildField(name));
400
415
  }
401
- if (options.submitButton !== false) {
416
+ const settings = { ...this.options, ...options };
417
+ if (settings.submitButton !== false) {
402
418
  fields.push({
403
419
  button: {
404
420
  type: "submit",
405
- text: options.submitText || "Submit",
421
+ text: settings.submitText || "Submit",
406
422
  className: "submit-button"
407
423
  }
408
424
  });
409
425
  }
410
- return {
411
- form: {
412
- onsubmit: "handleSubmit(event)",
413
- novalidate: true,
414
- children: fields
415
- }
416
- };
426
+ const form = {};
427
+ if (settings.action) form.action = settings.action;
428
+ if (settings.method) form.method = settings.method;
429
+ if (settings.name) form.name = settings.name;
430
+ if (settings.id) form.id = settings.id;
431
+ if (settings.className) form.className = settings.className;
432
+ if (settings.enctype) form.enctype = settings.enctype;
433
+ form.onsubmit = "handleSubmit(event)";
434
+ form.novalidate = true;
435
+ form.children = fields;
436
+ return { form };
437
+ }
438
+ /**
439
+ * Set the form action URL
440
+ */
441
+ setAction(action) {
442
+ this.options.action = action;
443
+ return this;
444
+ }
445
+ /**
446
+ * Set the form submission method
447
+ */
448
+ setMethod(method) {
449
+ this.options.method = method;
450
+ return this;
451
+ }
452
+ /**
453
+ * Build the form component (alias for buildForm)
454
+ */
455
+ build(options = {}) {
456
+ return this.buildForm(options);
457
+ }
458
+ /**
459
+ * Render the form to a component (alias for buildForm)
460
+ */
461
+ render(options = {}) {
462
+ return this.buildForm(options);
417
463
  }
418
464
  /**
419
465
  * Check if form is currently submitting
@@ -466,12 +512,19 @@ function createFormBuilder(options = {}) {
466
512
  }
467
513
  return form;
468
514
  }
469
- function buildForm(fields, options = {}) {
515
+ function buildForm(config = {}) {
516
+ const { fields = [], ...options } = Array.isArray(config) ? { fields: config } : config;
470
517
  const builder = new FormBuilder(options);
471
- for (const [name, config] of Object.entries(fields)) {
472
- builder.field(name, config);
518
+ if (Array.isArray(fields)) {
519
+ for (const field of fields) {
520
+ if (field && field.name) builder.field(field.name, field);
521
+ }
522
+ } else {
523
+ for (const [name, field] of Object.entries(fields)) {
524
+ builder.field(name, field);
525
+ }
473
526
  }
474
- return builder;
527
+ return builder.buildForm(options);
475
528
  }
476
529
  var form_builder_default = {
477
530
  FormBuilder,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/form-builder.js"],
4
- "sourcesContent": ["/**\n * Coherent.js Form Builder\n * \n * Utilities for building forms with Coherent.js\n * \n * @module forms/form-builder\n */\n\n/**\n * Form Builder\n * Helps create form components with validation\n */\nexport class FormBuilder {\n constructor(options = {}) {\n this.options = {\n validateOnChange: true,\n validateOnBlur: true,\n name: options.name || 'form',\n ...options\n };\n \n this.fields = new Map();\n this.groups = new Map();\n this.values = {};\n this.errors = {};\n this.touched = {};\n this.initialValues = {};\n this.submitHandler = null;\n this.errorHandler = null;\n this._isSubmitting = false;\n }\n\n /**\n * Add a field to the form (alias for field)\n */\n addField(name, config = {}) {\n return this.field(name, config);\n }\n\n /**\n * Add a field to the form\n */\n field(name, config = {}) {\n const fieldConfig = {\n name,\n type: config.type || 'text',\n label: config.label || name,\n placeholder: config.placeholder || '',\n defaultValue: config.defaultValue || '',\n validators: config.validators || [],\n required: config.required || false,\n visible: config.visible !== false,\n showWhen: config.showWhen,\n ...config\n };\n \n this.fields.set(name, fieldConfig);\n\n // Set default value\n if (config.defaultValue !== undefined) {\n this.values[name] = config.defaultValue;\n this.initialValues[name] = config.defaultValue;\n }\n\n return this;\n }\n\n /**\n * Remove a field from the form\n */\n removeField(name) {\n this.fields.delete(name);\n delete this.values[name];\n delete this.errors[name];\n delete this.touched[name];\n return this;\n }\n\n /**\n * Update field configuration\n */\n updateField(name, config) {\n const field = this.fields.get(name);\n if (field) {\n this.fields.set(name, { ...field, ...config });\n }\n return this;\n }\n\n /**\n * Get all fields as array\n */\n getFields() {\n return Array.from(this.fields.values());\n }\n\n /**\n * Add a field group\n */\n addGroup(name, config = {}) {\n this.groups.set(name, {\n name,\n label: config.label || name,\n fields: config.fields || [],\n ...config\n });\n\n // Add fields in the group\n if (config.fields) {\n config.fields.forEach(fieldConfig => {\n this.addField(fieldConfig.name, fieldConfig);\n });\n }\n\n return this;\n }\n\n /**\n * Get field configuration\n */\n getField(name) {\n return this.fields.get(name);\n }\n\n /**\n * Set field value\n */\n setValue(name, value) {\n this.values[name] = value;\n this.touched[name] = true;\n\n const field = this.fields.get(name);\n if (field && (field.validateOnChange || this.options.validateOnChange)) {\n this.validateField(name);\n }\n }\n\n /**\n * Set multiple values\n */\n setValues(values) {\n Object.assign(this.values, values);\n return this;\n }\n\n /**\n * Get field value\n */\n getValue(name) {\n return this.values[name];\n }\n\n /**\n * Get all values\n */\n getValues() {\n return { ...this.values };\n }\n\n /**\n * Get field error\n */\n getFieldError(name) {\n return this.errors[name];\n }\n\n /**\n * Check if form has errors\n */\n hasErrors() {\n return Object.keys(this.errors).length > 0;\n }\n\n /**\n * Clear all errors\n */\n clearErrors() {\n this.errors = {};\n return this;\n }\n\n /**\n * Check if form is dirty (values changed from initial)\n */\n isDirty() {\n return Object.keys(this.values).some(key => {\n return this.values[key] !== this.initialValues[key];\n });\n }\n\n /**\n * Check if form is valid\n */\n isValid() {\n const result = this.validate();\n return Object.keys(result).length === 0;\n }\n\n /**\n * Validate a field\n */\n validateField(name) {\n const field = this.fields.get(name);\n if (!field) return null;\n\n // Skip validation for hidden fields (support both showWhen and showIf)\n const showCondition = field.showWhen || field.showIf;\n if (showCondition && !showCondition(this.values)) {\n delete this.errors[name];\n return null;\n }\n\n const value = this.values[name];\n \n // Check required\n if (field.required && (value === undefined || value === null || value === '')) {\n const error = 'This field is required';\n this.errors[name] = error;\n return error;\n }\n\n // Skip further validation if empty and not required\n if (!value && !field.required) {\n delete this.errors[name];\n return null;\n }\n\n // Type-based validation\n if (value) {\n if (field.type === 'email') {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(value)) {\n const error = 'Please enter a valid email address';\n this.errors[name] = error;\n return error;\n }\n } else if (field.type === 'url') {\n try {\n new URL(value);\n } catch {\n const error = 'Please enter a valid URL';\n this.errors[name] = error;\n return error;\n }\n } else if (field.type === 'number') {\n if (isNaN(Number(value))) {\n const error = 'Please enter a valid number';\n this.errors[name] = error;\n return error;\n }\n }\n }\n\n // Check custom validate function\n if (field.validate) {\n const error = field.validate(value, this.values);\n if (error) {\n this.errors[name] = error;\n return error;\n }\n }\n\n // Run validators\n for (const validator of field.validators || []) {\n const error = validator(value, this.values);\n if (error) {\n this.errors[name] = error;\n return error;\n }\n }\n\n delete this.errors[name];\n return null;\n }\n\n /**\n * Validate all fields\n */\n validate() {\n const errors = {};\n\n for (const [name, field] of this.fields) {\n // Skip hidden fields (support both showWhen and showIf)\n const showCondition = field.showWhen || field.showIf;\n if (showCondition && !showCondition(this.values)) {\n continue;\n }\n\n const error = this.validateField(name);\n if (error) {\n errors[name] = error;\n }\n }\n\n this.errors = errors;\n return errors;\n }\n\n /**\n * Set submit handler\n */\n onSubmit(handler) {\n this.submitHandler = handler;\n return this;\n }\n\n /**\n * Set error handler\n */\n onError(handler) {\n this.errorHandler = handler;\n return this;\n }\n\n /**\n * Submit the form\n */\n async submit() {\n const errors = this.validate();\n \n if (Object.keys(errors).length > 0) {\n return { success: false, errors };\n }\n\n if (!this.submitHandler) {\n return { success: true, data: this.values };\n }\n\n this._isSubmitting = true;\n\n try {\n const result = await this.submitHandler(this.values);\n this._isSubmitting = false;\n return { success: true, data: result };\n } catch (error) {\n this._isSubmitting = false;\n if (this.errorHandler) {\n this.errorHandler(error);\n }\n return { success: false, error };\n }\n }\n\n /**\n * Serialize form data\n */\n serialize() {\n return { ...this.values };\n }\n\n /**\n * Convert form to HTML string\n */\n toHTML() {\n const fields = this.getFields();\n let html = `<form name=\"${this.options.name}\">`;\n \n fields.forEach(field => {\n html += `<div class=\"form-field\">`;\n html += `<label for=\"${field.name}\">${field.label}</label>`;\n html += `<input type=\"${field.type}\" name=\"${field.name}\" id=\"${field.name}\">`;\n html += `</div>`;\n });\n \n html += `</form>`;\n return html;\n }\n\n /**\n * Mark field as touched\n */\n touch(name) {\n this.touched[name] = true;\n }\n\n /**\n * Build input component with validation metadata for hydration\n */\n buildInput(name) {\n const field = this.fields.get(name);\n if (!field) return null;\n\n const value = this.values[name] || '';\n const error = this.errors[name];\n const isTouched = this.touched[name];\n\n // Build validator names string for data-validators attribute\n const validatorNames = field.validators\n .map(v => {\n if (typeof v === 'function') return v.name || 'custom';\n if (typeof v === 'string') return v;\n return null;\n })\n .filter(Boolean)\n .join(',');\n\n const inputProps = {\n type: field.type,\n name: field.name,\n id: field.name,\n value: value,\n placeholder: field.placeholder,\n 'aria-invalid': error ? 'true' : 'false',\n 'aria-describedby': error ? `${name}-error` : undefined,\n className: error && isTouched ? 'error' : ''\n };\n\n // Add validation metadata for client-side hydration\n if (field.required) {\n inputProps.required = true;\n inputProps['data-required'] = 'true';\n }\n\n if (validatorNames) {\n inputProps['data-validators'] = validatorNames;\n }\n\n // Note: Event handlers are attached during hydration, not inline\n // This enables progressive enhancement and CSP compliance\n\n return {\n input: inputProps\n };\n }\n\n /**\n * Build label component\n */\n buildLabel(name) {\n const field = this.fields.get(name);\n if (!field) return null;\n\n return {\n label: {\n for: field.name,\n text: field.label\n }\n };\n }\n\n /**\n * Build error component\n */\n buildError(name) {\n const error = this.errors[name];\n const isTouched = this.touched[name];\n\n if (!error || !isTouched) return null;\n\n return {\n div: {\n id: `${name}-error`,\n className: 'error-message',\n role: 'alert',\n text: error\n }\n };\n }\n\n /**\n * Build complete field component\n */\n buildField(name) {\n const field = this.fields.get(name);\n if (!field) return null;\n\n const children = [\n this.buildLabel(name),\n this.buildInput(name)\n ];\n\n const error = this.buildError(name);\n if (error) {\n children.push(error);\n }\n\n return {\n div: {\n className: 'form-field',\n 'data-field': name,\n children\n }\n };\n }\n\n /**\n * Build entire form\n */\n buildForm(options = {}) {\n const fields = [];\n\n for (const [name] of this.fields) {\n fields.push(this.buildField(name));\n }\n\n if (options.submitButton !== false) {\n fields.push({\n button: {\n type: 'submit',\n text: options.submitText || 'Submit',\n className: 'submit-button'\n }\n });\n }\n\n return {\n form: {\n onsubmit: 'handleSubmit(event)',\n novalidate: true,\n children: fields\n }\n };\n }\n\n /**\n * Check if form is currently submitting\n */\n isSubmitting() {\n return this._isSubmitting;\n }\n\n /**\n * Get a field group\n */\n getGroup(name) {\n return this.groups.get(name);\n }\n\n /**\n * Check if a field is visible\n */\n isFieldVisible(name) {\n const field = this.fields.get(name);\n if (!field) return false;\n \n // Support both showWhen and showIf\n const showCondition = field.showWhen || field.showIf;\n if (showCondition) {\n return showCondition(this.values);\n }\n \n return field.visible !== false;\n }\n\n /**\n * Reset form\n */\n reset() {\n // Reset to initial values or empty strings\n this.values = {};\n for (const [name, field] of this.fields) {\n if (field.defaultValue !== undefined) {\n this.values[name] = field.defaultValue;\n } else {\n this.values[name] = '';\n }\n }\n this.errors = {};\n this.touched = {};\n this._isSubmitting = false;\n return this;\n }\n}\n\n/**\n * Create a form builder\n */\nexport function createFormBuilder(options = {}) {\n const form = new FormBuilder(options);\n\n // Add fields if provided\n if (options.fields) {\n options.fields.forEach(fieldConfig => {\n form.addField(fieldConfig.name, fieldConfig);\n });\n }\n\n return form;\n}\n\n/**\n * Quick form builder helper\n */\nexport function buildForm(fields, options = {}) {\n const builder = new FormBuilder(options);\n\n for (const [name, config] of Object.entries(fields)) {\n builder.field(name, config);\n }\n\n return builder;\n}\n\nexport default {\n FormBuilder,\n createFormBuilder,\n buildForm\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Coherent.js Form Builder\n * \n * Utilities for building forms with Coherent.js\n * \n * @module forms/form-builder\n */\n\nimport { render as renderToHTML } from '@coherent.js/core';\n\n/**\n * Form Builder\n * Helps create form components with validation\n */\nexport class FormBuilder {\n constructor(options = {}) {\n this.options = {\n validateOnChange: true,\n validateOnBlur: true,\n name: options.name || 'form',\n ...options\n };\n \n this.fields = new Map();\n this.groups = new Map();\n this.values = {};\n this.errors = {};\n this.touched = {};\n this.initialValues = {};\n this.submitHandler = null;\n this.errorHandler = null;\n this._isSubmitting = false;\n }\n\n /**\n * Add a field to the form (alias for field)\n */\n addField(name, config = {}) {\n return this.field(name, config);\n }\n\n /**\n * Add a field to the form\n */\n field(name, config = {}) {\n const fieldConfig = {\n name,\n type: config.type || 'text',\n label: config.label || name,\n placeholder: config.placeholder || '',\n defaultValue: config.defaultValue || '',\n validators: config.validators || [],\n required: config.required || false,\n visible: config.visible !== false,\n showWhen: config.showWhen,\n ...config\n };\n \n this.fields.set(name, fieldConfig);\n\n // Set default value\n if (config.defaultValue !== undefined) {\n this.values[name] = config.defaultValue;\n this.initialValues[name] = config.defaultValue;\n }\n\n return this;\n }\n\n /**\n * Remove a field from the form\n */\n removeField(name) {\n this.fields.delete(name);\n delete this.values[name];\n delete this.errors[name];\n delete this.touched[name];\n return this;\n }\n\n /**\n * Update field configuration\n */\n updateField(name, config) {\n const field = this.fields.get(name);\n if (field) {\n this.fields.set(name, { ...field, ...config });\n }\n return this;\n }\n\n /**\n * Get all fields as array\n */\n getFields() {\n return Array.from(this.fields.values());\n }\n\n /**\n * Add a field group\n */\n addGroup(name, config = {}) {\n this.groups.set(name, {\n name,\n label: config.label || name,\n fields: config.fields || [],\n ...config\n });\n\n // Add fields in the group\n if (config.fields) {\n config.fields.forEach(fieldConfig => {\n this.addField(fieldConfig.name, fieldConfig);\n });\n }\n\n return this;\n }\n\n /**\n * Get field configuration\n */\n getField(name) {\n return this.fields.get(name);\n }\n\n /**\n * Set field value\n */\n setValue(name, value) {\n this.values[name] = value;\n this.touched[name] = true;\n\n const field = this.fields.get(name);\n if (field && (field.validateOnChange || this.options.validateOnChange)) {\n this.validateField(name);\n }\n }\n\n /**\n * Set multiple values\n */\n setValues(values) {\n Object.assign(this.values, values);\n return this;\n }\n\n /**\n * Get field value\n */\n getValue(name) {\n return this.values[name];\n }\n\n /**\n * Get all values\n */\n getValues() {\n return { ...this.values };\n }\n\n /**\n * Get field error\n */\n getFieldError(name) {\n return this.errors[name];\n }\n\n /**\n * Check if form has errors\n */\n hasErrors() {\n return Object.keys(this.errors).length > 0;\n }\n\n /**\n * Clear all errors\n */\n clearErrors() {\n this.errors = {};\n return this;\n }\n\n /**\n * Check if form is dirty (values changed from initial)\n */\n isDirty() {\n return Object.keys(this.values).some(key => {\n return this.values[key] !== this.initialValues[key];\n });\n }\n\n /**\n * Check if form is valid\n */\n isValid() {\n const result = this.validate();\n return Object.keys(result).length === 0;\n }\n\n /**\n * Validate a field\n */\n validateField(name) {\n const field = this.fields.get(name);\n if (!field) return null;\n\n // Skip validation for hidden fields (support both showWhen and showIf)\n const showCondition = field.showWhen || field.showIf;\n if (showCondition && !showCondition(this.values)) {\n delete this.errors[name];\n return null;\n }\n\n const value = this.values[name];\n \n // Check required\n if (field.required && (value === undefined || value === null || value === '')) {\n const error = 'This field is required';\n this.errors[name] = error;\n return error;\n }\n\n // Skip further validation if empty and not required\n if (!value && !field.required) {\n delete this.errors[name];\n return null;\n }\n\n // Type-based validation\n if (value) {\n if (field.type === 'email') {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(value)) {\n const error = 'Please enter a valid email address';\n this.errors[name] = error;\n return error;\n }\n } else if (field.type === 'url') {\n try {\n new URL(value);\n } catch {\n const error = 'Please enter a valid URL';\n this.errors[name] = error;\n return error;\n }\n } else if (field.type === 'number') {\n if (isNaN(Number(value))) {\n const error = 'Please enter a valid number';\n this.errors[name] = error;\n return error;\n }\n }\n }\n\n // Check custom validate function\n if (field.validate) {\n const error = field.validate(value, this.values);\n if (error) {\n this.errors[name] = error;\n return error;\n }\n }\n\n // Run validators\n for (const validator of field.validators || []) {\n const error = validator(value, this.values);\n if (error) {\n this.errors[name] = error;\n return error;\n }\n }\n\n delete this.errors[name];\n return null;\n }\n\n /**\n * Validate all fields\n */\n validate() {\n const errors = {};\n\n for (const [name, field] of this.fields) {\n // Skip hidden fields (support both showWhen and showIf)\n const showCondition = field.showWhen || field.showIf;\n if (showCondition && !showCondition(this.values)) {\n continue;\n }\n\n const error = this.validateField(name);\n if (error) {\n errors[name] = error;\n }\n }\n\n this.errors = errors;\n return errors;\n }\n\n /**\n * Set submit handler\n */\n onSubmit(handler) {\n this.submitHandler = handler;\n return this;\n }\n\n /**\n * Set error handler\n */\n onError(handler) {\n this.errorHandler = handler;\n return this;\n }\n\n /**\n * Submit the form\n */\n async submit() {\n const errors = this.validate();\n \n if (Object.keys(errors).length > 0) {\n return { success: false, errors };\n }\n\n if (!this.submitHandler) {\n return { success: true, data: this.values };\n }\n\n this._isSubmitting = true;\n\n try {\n const result = await this.submitHandler(this.values);\n this._isSubmitting = false;\n return { success: true, data: result };\n } catch (error) {\n this._isSubmitting = false;\n if (this.errorHandler) {\n this.errorHandler(error);\n }\n return { success: false, error };\n }\n }\n\n /**\n * Serialize form data\n */\n serialize() {\n return { ...this.values };\n }\n\n /**\n * Convert form to HTML string\n */\n toHTML(options = {}) {\n // Delegates to buildForm() so there is one source of truth. The previous\n // hand-rolled string builder dropped action, method and every field\n // attribute beyond type/name/id, and interpolated values unescaped.\n return renderToHTML(this.buildForm(options));\n }\n\n /**\n * Mark field as touched\n */\n touch(name) {\n this.touched[name] = true;\n }\n\n /**\n * Build input component with validation metadata for hydration\n */\n buildInput(name) {\n const field = this.fields.get(name);\n if (!field) return null;\n\n const value = this.values[name] || '';\n const error = this.errors[name];\n const isTouched = this.touched[name];\n\n // Build validator names string for data-validators attribute\n const validatorNames = field.validators\n .map(v => {\n if (typeof v === 'function') return v.name || 'custom';\n if (typeof v === 'string') return v;\n return null;\n })\n .filter(Boolean)\n .join(',');\n\n const inputProps = {\n type: field.type,\n name: field.name,\n id: field.name,\n value: value,\n placeholder: field.placeholder,\n 'aria-invalid': error ? 'true' : 'false',\n 'aria-describedby': error ? `${name}-error` : undefined,\n className: error && isTouched ? 'error' : ''\n };\n\n // Add validation metadata for client-side hydration\n if (field.required) {\n inputProps.required = true;\n inputProps['data-required'] = 'true';\n }\n\n if (validatorNames) {\n inputProps['data-validators'] = validatorNames;\n }\n\n // Note: Event handlers are attached during hydration, not inline\n // This enables progressive enhancement and CSP compliance\n\n // textarea and select are elements, not input types. `type=\"textarea\"` is\n // not valid HTML \u2014 browsers render it as a single-line text box.\n if (field.type === 'textarea' || field.type === 'select') {\n const { type: _type, value: _value, ...rest } = inputProps;\n const props = { ...rest };\n\n if (field.type === 'textarea') {\n return { textarea: { ...props, text: String(value) } };\n }\n\n const { placeholder: _placeholder, ...selectProps } = props;\n\n return {\n select: {\n ...selectProps,\n children: (field.options ?? []).map(option => {\n const { value: optionValue, label = optionValue } =\n typeof option === 'object' && option !== null ? option : { value: option };\n\n return {\n option: {\n value: optionValue,\n selected: String(optionValue) === String(value) || undefined,\n text: String(label)\n }\n };\n })\n }\n };\n }\n\n return {\n input: inputProps\n };\n }\n\n /**\n * Build label component\n */\n buildLabel(name) {\n const field = this.fields.get(name);\n if (!field) return null;\n\n return {\n label: {\n for: field.name,\n text: field.label\n }\n };\n }\n\n /**\n * Build error component\n */\n buildError(name) {\n const error = this.errors[name];\n const isTouched = this.touched[name];\n\n if (!error || !isTouched) return null;\n\n return {\n div: {\n id: `${name}-error`,\n className: 'error-message',\n role: 'alert',\n text: error\n }\n };\n }\n\n /**\n * Build complete field component\n */\n buildField(name) {\n const field = this.fields.get(name);\n if (!field) return null;\n\n const children = [\n this.buildLabel(name),\n this.buildInput(name)\n ];\n\n const error = this.buildError(name);\n if (error) {\n children.push(error);\n }\n\n return {\n div: {\n className: 'form-field',\n 'data-field': name,\n children\n }\n };\n }\n\n /**\n * Build entire form\n */\n buildForm(options = {}) {\n const fields = [];\n\n for (const [name] of this.fields) {\n fields.push(this.buildField(name));\n }\n\n const settings = { ...this.options, ...options };\n\n if (settings.submitButton !== false) {\n fields.push({\n button: {\n type: 'submit',\n text: settings.submitText || 'Submit',\n className: 'submit-button'\n }\n });\n }\n\n const form = {};\n\n // Emitted before the handler so the markup reads action-first, and so a\n // form still submits to the right place without JavaScript.\n if (settings.action) form.action = settings.action;\n if (settings.method) form.method = settings.method;\n if (settings.name) form.name = settings.name;\n if (settings.id) form.id = settings.id;\n if (settings.className) form.className = settings.className;\n if (settings.enctype) form.enctype = settings.enctype;\n\n form.onsubmit = 'handleSubmit(event)';\n form.novalidate = true;\n form.children = fields;\n\n return { form };\n }\n\n /**\n * Set the form action URL\n */\n setAction(action) {\n this.options.action = action;\n return this;\n }\n\n /**\n * Set the form submission method\n */\n setMethod(method) {\n this.options.method = method;\n return this;\n }\n\n /**\n * Build the form component (alias for buildForm)\n */\n build(options = {}) {\n return this.buildForm(options);\n }\n\n /**\n * Render the form to a component (alias for buildForm)\n */\n render(options = {}) {\n return this.buildForm(options);\n }\n\n /**\n * Check if form is currently submitting\n */\n isSubmitting() {\n return this._isSubmitting;\n }\n\n /**\n * Get a field group\n */\n getGroup(name) {\n return this.groups.get(name);\n }\n\n /**\n * Check if a field is visible\n */\n isFieldVisible(name) {\n const field = this.fields.get(name);\n if (!field) return false;\n \n // Support both showWhen and showIf\n const showCondition = field.showWhen || field.showIf;\n if (showCondition) {\n return showCondition(this.values);\n }\n \n return field.visible !== false;\n }\n\n /**\n * Reset form\n */\n reset() {\n // Reset to initial values or empty strings\n this.values = {};\n for (const [name, field] of this.fields) {\n if (field.defaultValue !== undefined) {\n this.values[name] = field.defaultValue;\n } else {\n this.values[name] = '';\n }\n }\n this.errors = {};\n this.touched = {};\n this._isSubmitting = false;\n return this;\n }\n}\n\n/**\n * Create a form builder\n */\nexport function createFormBuilder(options = {}) {\n const form = new FormBuilder(options);\n\n // Add fields if provided\n if (options.fields) {\n options.fields.forEach(fieldConfig => {\n form.addField(fieldConfig.name, fieldConfig);\n });\n }\n\n return form;\n}\n\n/**\n * Build a form component from a configuration object.\n *\n * Returns a renderable component, as the type declarations have always said.\n * It previously returned the FormBuilder itself, so `render(buildForm(...))`\n * threw \"Invalid component structure\". Use createFormBuilder() when you want\n * the builder.\n *\n * @param {Object} config - Form configuration; `fields` may be an array of\n * field objects or an object keyed by field name. Remaining keys (action,\n * method, name, className, enctype, submitText) configure the form element.\n * @returns {Object} A Coherent.js component\n */\nexport function buildForm(config = {}) {\n const { fields = [], ...options } = Array.isArray(config) ? { fields: config } : config;\n const builder = new FormBuilder(options);\n\n if (Array.isArray(fields)) {\n for (const field of fields) {\n if (field && field.name) builder.field(field.name, field);\n }\n } else {\n for (const [name, field] of Object.entries(fields)) {\n builder.field(name, field);\n }\n }\n\n return builder.buildForm(options);\n}\n\nexport default {\n FormBuilder,\n createFormBuilder,\n buildForm\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/validators.js", "../src/form-hydration.js"],
4
- "sourcesContent": ["/**\n * Coherent.js Forms - Validators\n * \n * Form validation utilities\n * \n * @module forms/validators\n */\n\n/**\n * Built-in validators with signature: (value, options, translator, allValues) => errorMessage | null\n */\nexport const validators = {\n required: (value, options = {}) => {\n if (value === null || value === undefined || value === '') {\n return options.message || validators.required.message || 'This field is required';\n }\n return null;\n },\n\n email: (value) => {\n if (!value) return null;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(value)) {\n return 'Please enter a valid email address';\n }\n return null;\n },\n\n minLength: (value, options = {}) => {\n if (!value) return null;\n const min = options.min || 0;\n if (value.length < min) {\n return options.message || `Must be at least ${min} characters`;\n }\n return null;\n },\n\n maxLength: (value, options = {}) => {\n if (!value) return null;\n const max = options.max || Infinity;\n if (value.length > max) {\n return options.message || `Must be no more than ${max} characters`;\n }\n return null;\n },\n\n min: (value, options = {}) => {\n if (value === null || value === undefined || value === '') return null;\n const num = Number(value);\n const minValue = options.min || 0;\n if (isNaN(num) || num < minValue) {\n return options.message || `Must be at least ${minValue}`;\n }\n return null;\n },\n\n max: (value, options = {}) => {\n if (value === null || value === undefined || value === '') return null;\n const num = Number(value);\n const maxValue = options.max || Infinity;\n if (isNaN(num) || num > maxValue) {\n return options.message || `Must be no more than ${maxValue}`;\n }\n return null;\n },\n\n pattern: (value, options = {}) => {\n if (!value) return null;\n const regex = options.pattern || options.regex;\n if (regex && !regex.test(value)) {\n return options.message || 'Invalid format';\n }\n return null;\n },\n\n url: (value) => {\n if (!value) return null;\n try {\n new URL(value);\n return null;\n } catch {\n return 'Please enter a valid URL';\n }\n },\n\n number: (value) => {\n if (value === null || value === undefined || value === '') return null;\n if (isNaN(Number(value))) {\n return 'Must be a valid number';\n }\n return null;\n },\n\n integer: (value) => {\n if (value === null || value === undefined || value === '') return null;\n const num = Number(value);\n if (isNaN(num) || !Number.isInteger(num)) {\n return 'Must be a whole number';\n }\n return null;\n },\n\n phone: (value) => {\n if (!value) return null;\n const phoneRegex = /^[\\d\\s\\-\\+\\(\\)]+$/;\n if (!phoneRegex.test(value) || value.replace(/\\D/g, '').length < 10) {\n return 'Please enter a valid phone number';\n }\n return null;\n },\n\n date: (value) => {\n if (!value) return null;\n const date = new Date(value);\n if (isNaN(date.getTime())) {\n return 'Please enter a valid date';\n }\n return null;\n },\n\n match: (value, options = {}, translator, allValues = {}) => {\n if (!value) return null;\n const fieldName = options.field || options.fieldName;\n if (value !== allValues[fieldName]) {\n return options.message || `Must match ${fieldName}`;\n }\n return null;\n },\n\n custom: (value, options = {}, translator, allValues) => {\n const validatorFn = options.validator || options.fn;\n if (!validatorFn) return null;\n const isValid = validatorFn(value, allValues);\n return isValid ? null : (options.message || 'Validation failed');\n },\n\n fileType: (value, options = {}) => {\n if (!value) return null;\n \n const allowedTypes = options.accept || options.types || [];\n \n // Handle File object\n if (value.type !== undefined) {\n const fileType = value.type;\n const fileExt = value.name ? value.name.split('.').pop().toLowerCase() : '';\n \n // Check MIME type or extension\n const isValid = allowedTypes.some(type => {\n if (type.startsWith('.')) {\n return fileExt === type.slice(1).toLowerCase();\n }\n if (type.includes('/')) {\n if (type.endsWith('/*')) {\n return fileType.startsWith(type.replace('/*', '/'));\n }\n return fileType === type;\n }\n return fileExt === type.toLowerCase();\n });\n \n if (!isValid) {\n return options.message || `File type must be one of: ${allowedTypes.join(', ')}`;\n }\n return null;\n }\n \n return null;\n },\n\n fileSize: (value, options = {}) => {\n if (!value) return null;\n \n const maxSize = options.maxSize || Infinity;\n \n // Handle File object\n if (value.size !== undefined) {\n if (value.size > maxSize) {\n const maxSizeMB = (maxSize / (1024 * 1024)).toFixed(2);\n return options.message || `File size must be less than ${maxSizeMB}MB`;\n }\n return null;\n }\n \n return null;\n },\n\n fileExtension: (value, options = {}) => {\n if (!value) return null;\n \n const allowedExtensions = options.extensions || [];\n const fileName = value.name || value;\n const ext = `.${ fileName.split('.').pop().toLowerCase()}`;\n \n const isValid = allowedExtensions.some(allowed => {\n return ext === allowed.toLowerCase();\n });\n \n if (!isValid) {\n return options.message || `File extension must be one of: ${allowedExtensions.join(', ')}`;\n }\n return null;\n },\n\n alpha: (value) => {\n if (!value) return null;\n const alphaRegex = /^[a-zA-Z]+$/;\n if (!alphaRegex.test(value)) {\n return 'Must contain only letters';\n }\n return null;\n },\n\n alphanumeric: (value) => {\n if (!value) return null;\n const alphanumericRegex = /^[a-zA-Z0-9]+$/;\n if (!alphanumericRegex.test(value)) {\n return 'Must contain only letters and numbers';\n }\n return null;\n },\n\n uppercase: (value) => {\n if (!value) return null;\n if (value !== value.toUpperCase()) {\n return 'Must be uppercase';\n }\n return null;\n },\n\n // Get a registered validator\n get: (name) => {\n return validators[name];\n },\n\n // Compose multiple validators\n compose: (validatorList) => {\n return (value, options, translator, allValues) => {\n for (const validator of validatorList) {\n const error = typeof validator === 'function'\n ? validator(value, options, translator, allValues)\n : null;\n if (error) {\n return error;\n }\n }\n return null;\n };\n },\n\n // Debounce async validator\n debounce: (validator, delay = 300) => {\n let timeoutId;\n return (value) => {\n return new Promise((resolve) => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(async () => {\n const result = await validator(value);\n resolve(result);\n }, delay);\n });\n };\n },\n\n // Cancellable async validator\n cancellable: (validator) => {\n let abortController;\n const wrapped = async (value) => {\n if (abortController) {\n abortController.abort();\n }\n // AbortController is a global browser/Node.js API\n abortController = typeof AbortController !== 'undefined' ? new AbortController() : null;\n try {\n return await validator(value, abortController ? abortController.signal : null);\n } catch (error) {\n if (error.name === 'AbortError') {\n return null;\n }\n throw error;\n }\n };\n wrapped.cancel = () => {\n if (abortController) {\n abortController.abort();\n }\n };\n return wrapped;\n },\n\n // Conditional validator\n when: (condition, validator) => {\n return (value, options = {}, translator, allValues = {}) => {\n // Pass options as context if it looks like context (has non-validator properties)\n const context = options.min !== undefined || options.max !== undefined ? allValues : options;\n const shouldValidate = typeof condition === 'function' \n ? condition(value, context) \n : condition;\n \n if (!shouldValidate) {\n return null;\n }\n \n return typeof validator === 'function'\n ? validator(value, options, translator, allValues)\n : null;\n };\n },\n\n // Validator chain builder\n chain: (options = {}) => {\n const validatorList = [];\n const stopOnFirstError = options.stopOnFirstError !== false;\n \n const chain = {\n required: (opts) => {\n validatorList.push((v, o, t, a) => validators.required(v, opts || o, t, a));\n return chain;\n },\n email: (opts) => {\n validatorList.push((v, o, t, a) => validators.email(v, opts || o, t, a));\n return chain;\n },\n minLength: (opts) => {\n validatorList.push((v, o, t, a) => validators.minLength(v, opts || o, t, a));\n return chain;\n },\n maxLength: (opts) => {\n validatorList.push((v, o, t, a) => validators.maxLength(v, opts || o, t, a));\n return chain;\n },\n custom: (fn, message) => {\n validatorList.push((v, o, t, a) => {\n // Custom validator returns null if valid, message if invalid\n const result = fn(v, a);\n return result === null || result === true || result === undefined ? null : (message || result);\n });\n return chain;\n },\n validate: (value, opts, translator, allValues) => {\n if (stopOnFirstError) {\n // Stop on first error - return single error or null\n for (const validator of validatorList) {\n const error = validator(value, opts, translator, allValues);\n if (error) {\n return error;\n }\n }\n return null;\n } else {\n // Collect all errors - return array or null\n const errors = [];\n for (const validator of validatorList) {\n const error = validator(value, opts, translator, allValues);\n if (error) {\n errors.push(error);\n }\n }\n return errors.length > 0 ? errors : null;\n }\n }\n };\n \n return chain;\n }\n};\n\n/**\n * Validate a single field\n */\nexport function validateField(value, validatorList, formData = {}) {\n for (const validator of validatorList) {\n const error = validator(value, formData);\n if (error) {\n return error;\n }\n }\n return null;\n}\n\n/**\n * Validate entire form\n */\nexport function validateForm(formData, fieldValidators) {\n const errors = {};\n \n for (const [fieldName, validatorList] of Object.entries(fieldValidators)) {\n const value = formData[fieldName];\n const error = validateField(value, validatorList, formData);\n if (error) {\n errors[fieldName] = error;\n }\n }\n \n return Object.keys(errors).length > 0 ? errors : null;\n}\n\n/**\n * Create a validator\n */\nexport function createValidator(validatorFn, message) {\n return (value, options, translator, allValues) => {\n const result = validatorFn(value, options, translator, allValues);\n // If validator returns a string, use it as the error message\n if (typeof result === 'string') {\n return result;\n }\n // If validator returns falsy (null, false, undefined), no error\n if (!result) {\n return null;\n }\n // If validator returns truthy (true, object, etc), use provided message\n return message || 'Validation failed';\n };\n}\n\n/**\n * Register a custom validator\n */\nexport function registerValidator(name, validatorFn) {\n validators[name] = validatorFn;\n}\n\n/**\n * Compose multiple validators\n */\nexport function composeValidators(...validatorFns) {\n return (value, options, translator, allValues) => {\n for (const validator of validatorFns) {\n const error = validator(value, options, translator, allValues);\n if (error) {\n return error;\n }\n }\n return null;\n };\n}\n\nexport default {\n validators,\n validateField,\n validateForm,\n createValidator,\n registerValidator,\n composeValidators\n};\n", "/**\n * Form Hydration for Coherent.js\n *\n * Progressive enhancement for server-rendered forms\n * Reads validation metadata from HTML and attaches client-side behavior\n *\n * @module forms/form-hydration\n */\n\nimport { validators } from './validators.js';\n\n/**\n * Hydrate a server-rendered form with client-side validation and behavior\n *\n * @param {string|HTMLFormElement} formSelector - Form selector or element\n * @param {Object} options - Hydration options\n * @returns {Object} Form controller\n */\nexport function hydrateForm(formSelector, options = {}) {\n // Browser-only check\n if (typeof document === 'undefined') {\n console.warn('hydrateForm can only run in browser environment');\n return null;\n }\n\n const form = typeof formSelector === 'string'\n ? document.querySelector(formSelector)\n : formSelector;\n\n if (!form) {\n console.warn(`Form not found: ${formSelector}`);\n return null;\n }\n\n const opts = {\n validateOnBlur: true,\n validateOnChange: false,\n validateOnSubmit: true,\n showErrorsOnTouch: true,\n debounce: 300,\n ...options\n };\n\n // Form state\n const state = {\n values: {},\n errors: {},\n touched: {},\n isSubmitting: false,\n fields: new Map()\n };\n\n // Debounce timers\n const debounceTimers = new Map();\n\n /**\n * Parse validators from data-validators attribute\n */\n function parseValidators(validatorString) {\n if (!validatorString) return [];\n\n return validatorString.split(',').map(v => {\n const trimmed = v.trim();\n\n // Handle validators with parameters: minLength:8\n const [name, ...params] = trimmed.split(':');\n\n if (validators[name]) {\n return params.length > 0\n ? validators[name](...params.map(p => isNaN(p) ? p : Number(p)))\n : validators[name];\n }\n\n return null;\n }).filter(Boolean);\n }\n\n /**\n * Discover and register fields from form HTML\n */\n function discoverFields() {\n const inputs = form.querySelectorAll('[name]');\n\n inputs.forEach(input => {\n const name = input.getAttribute('name');\n const field = {\n name,\n element: input,\n type: input.getAttribute('type') || 'text',\n required: input.hasAttribute('required') || input.dataset.required === 'true',\n validators: parseValidators(input.dataset.validators),\n errorElement: null\n };\n\n // Find or create error display element\n const errorId = `${name}-error`;\n field.errorElement = document.getElementById(errorId) || createErrorElement(name, input);\n\n state.fields.set(name, field);\n state.values[name] = getFieldValue(input);\n state.touched[name] = false;\n state.errors[name] = null;\n });\n }\n\n /**\n * Create error display element\n */\n function createErrorElement(name, inputElement) {\n const errorDiv = document.createElement('div');\n errorDiv.id = `${name}-error`;\n errorDiv.className = 'error-message';\n errorDiv.setAttribute('role', 'alert');\n errorDiv.style.display = 'none';\n\n // Insert after input or its parent field wrapper\n const fieldWrapper = inputElement.closest('.form-field') || inputElement.parentElement;\n fieldWrapper.appendChild(errorDiv);\n\n return errorDiv;\n }\n\n /**\n * Get field value based on input type\n */\n function getFieldValue(input) {\n if (input.type === 'checkbox') {\n return input.checked;\n } else if (input.type === 'radio') {\n const checked = form.querySelector(`[name=\"${input.name}\"]:checked`);\n return checked ? checked.value : null;\n } else {\n return input.value;\n }\n }\n\n /**\n * Set field value\n */\n function setFieldValue(name, value) {\n const field = state.fields.get(name);\n if (!field) return;\n\n const { element } = field;\n\n if (element.type === 'checkbox') {\n element.checked = Boolean(value);\n } else if (element.type === 'radio') {\n const radio = form.querySelector(`[name=\"${name}\"][value=\"${value}\"]`);\n if (radio) radio.checked = true;\n } else {\n element.value = value;\n }\n\n state.values[name] = value;\n }\n\n /**\n * Validate a single field\n */\n function validateField(name) {\n const field = state.fields.get(name);\n if (!field) return true;\n\n const value = state.values[name];\n let error = null;\n\n // Required validation\n if (field.required && (value === null || value === undefined || value === '')) {\n error = 'This field is required';\n }\n\n // Run custom validators\n if (!error && field.validators.length > 0) {\n for (const validator of field.validators) {\n const result = validator.validate\n ? validator.validate(value, state.values)\n : validator(value, state.values);\n\n if (result !== true && result !== undefined && result !== null) {\n error = validator.message || result || 'Validation failed';\n break;\n }\n }\n }\n\n state.errors[name] = error;\n displayError(name, error);\n\n return !error;\n }\n\n /**\n * Display error message\n */\n function displayError(name, error) {\n const field = state.fields.get(name);\n if (!field) return;\n\n const { element, errorElement } = field;\n\n if (error && state.touched[name] && opts.showErrorsOnTouch) {\n // Show error\n errorElement.textContent = error;\n errorElement.style.display = 'block';\n element.setAttribute('aria-invalid', 'true');\n element.classList.add('error');\n } else {\n // Hide error\n errorElement.textContent = '';\n errorElement.style.display = 'none';\n element.setAttribute('aria-invalid', 'false');\n element.classList.remove('error');\n }\n }\n\n /**\n * Validate entire form\n */\n function validateForm() {\n let isValid = true;\n\n for (const name of state.fields.keys()) {\n const fieldValid = validateField(name);\n if (!fieldValid) isValid = false;\n }\n\n return isValid;\n }\n\n /**\n * Handle input change\n */\n function handleChange(event) {\n const input = event.target;\n const name = input.getAttribute('name');\n\n if (!state.fields.has(name)) return;\n\n state.values[name] = getFieldValue(input);\n\n if (opts.validateOnChange) {\n // Debounce validation\n if (debounceTimers.has(name)) {\n clearTimeout(debounceTimers.get(name));\n }\n\n const timer = setTimeout(() => {\n validateField(name);\n debounceTimers.delete(name);\n }, opts.debounce);\n\n debounceTimers.set(name, timer);\n }\n }\n\n /**\n * Handle input blur\n */\n function handleBlur(event) {\n const input = event.target;\n const name = input.getAttribute('name');\n\n if (!state.fields.has(name)) return;\n\n state.touched[name] = true;\n\n if (opts.validateOnBlur) {\n validateField(name);\n }\n }\n\n /**\n * Handle form submission\n */\n function handleSubmit(event) {\n event.preventDefault();\n\n // Mark all fields as touched\n for (const name of state.fields.keys()) {\n state.touched[name] = true;\n }\n\n const isValid = validateForm();\n\n if (!isValid) {\n // Focus first error field\n const firstErrorField = Array.from(state.fields.values())\n .find(field => state.errors[field.name]);\n\n if (firstErrorField) {\n firstErrorField.element.focus();\n }\n\n // Call onError callback\n if (options.onError) {\n options.onError(state.errors);\n }\n\n return;\n }\n\n // Form is valid, prepare submission\n state.isSubmitting = true;\n\n const submitData = { ...state.values };\n\n // Call onSubmit callback\n if (options.onSubmit) {\n const result = options.onSubmit(submitData, event);\n\n // If onSubmit returns false, don't submit\n if (result === false) {\n state.isSubmitting = false;\n return;\n }\n\n // If onSubmit returns a promise, wait for it\n if (result && typeof result.then === 'function') {\n result\n .then(() => {\n state.isSubmitting = false;\n if (options.onSuccess) {\n options.onSuccess(submitData);\n }\n })\n .catch(error => {\n state.isSubmitting = false;\n if (options.onError) {\n options.onError(error);\n }\n });\n return;\n }\n }\n\n // Default: submit the form normally\n if (!options.onSubmit) {\n form.submit();\n }\n\n state.isSubmitting = false;\n }\n\n /**\n * Attach event listeners\n */\n function attachEventListeners() {\n // Input change events\n state.fields.forEach(field => {\n field.element.addEventListener('input', handleChange);\n field.element.addEventListener('blur', handleBlur);\n });\n\n // Form submit\n form.addEventListener('submit', handleSubmit);\n }\n\n /**\n * Detach event listeners (cleanup)\n */\n function detachEventListeners() {\n state.fields.forEach(field => {\n field.element.removeEventListener('input', handleChange);\n field.element.removeEventListener('blur', handleBlur);\n });\n\n form.removeEventListener('submit', handleSubmit);\n\n // Clear debounce timers\n debounceTimers.forEach(timer => clearTimeout(timer));\n debounceTimers.clear();\n }\n\n /**\n * Reset form to initial state\n */\n function reset() {\n state.fields.forEach(field => {\n setFieldValue(field.name, '');\n state.touched[field.name] = false;\n state.errors[field.name] = null;\n displayError(field.name, null);\n });\n\n state.isSubmitting = false;\n form.reset();\n }\n\n // Initialize\n discoverFields();\n attachEventListeners();\n\n // Public API\n return {\n validateField,\n validateForm,\n setFieldValue,\n getFieldValue: (name) => state.values[name],\n getError: (name) => state.errors[name],\n getErrors: () => ({ ...state.errors }),\n getValues: () => ({ ...state.values }),\n setTouched: (name, touched = true) => {\n state.touched[name] = touched;\n },\n reset,\n destroy: detachEventListeners,\n isValid: () => Object.values(state.errors).every(e => !e),\n isSubmitting: () => state.isSubmitting,\n getState: () => ({\n values: { ...state.values },\n errors: { ...state.errors },\n touched: { ...state.touched },\n isSubmitting: state.isSubmitting\n })\n };\n}\n\nexport default hydrateForm;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Coherent.js Forms - Validators\n *\n * Form validation utilities\n *\n * @module forms/validators\n */\n\nimport { validators as packageValidators } from './validation.js';\n\n/**\n * Built-in validators with signature: (value, options, translator, allValues) => errorMessage | null\n */\nexport const validators = {\n required: (value, options = {}) => {\n if (value === null || value === undefined || value === '') {\n return options.message || validators.required.message || 'This field is required';\n }\n return null;\n },\n\n email: (value) => {\n if (!value) return null;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(value)) {\n return 'Please enter a valid email address';\n }\n return null;\n },\n\n minLength: (value, options = {}) => {\n if (!value) return null;\n const min = options.min || 0;\n if (value.length < min) {\n return options.message || `Must be at least ${min} characters`;\n }\n return null;\n },\n\n maxLength: (value, options = {}) => {\n if (!value) return null;\n const max = options.max || Infinity;\n if (value.length > max) {\n return options.message || `Must be no more than ${max} characters`;\n }\n return null;\n },\n\n min: (value, options = {}) => {\n if (value === null || value === undefined || value === '') return null;\n const num = Number(value);\n const minValue = options.min || 0;\n if (isNaN(num) || num < minValue) {\n return options.message || `Must be at least ${minValue}`;\n }\n return null;\n },\n\n max: (value, options = {}) => {\n if (value === null || value === undefined || value === '') return null;\n const num = Number(value);\n const maxValue = options.max || Infinity;\n if (isNaN(num) || num > maxValue) {\n return options.message || `Must be no more than ${maxValue}`;\n }\n return null;\n },\n\n pattern: (value, options = {}) => {\n if (!value) return null;\n const regex = options.pattern || options.regex;\n if (regex && !regex.test(value)) {\n return options.message || 'Invalid format';\n }\n return null;\n },\n\n url: (value) => {\n if (!value) return null;\n try {\n new URL(value);\n return null;\n } catch {\n return 'Please enter a valid URL';\n }\n },\n\n number: (value) => {\n if (value === null || value === undefined || value === '') return null;\n if (isNaN(Number(value))) {\n return 'Must be a valid number';\n }\n return null;\n },\n\n integer: (value) => {\n if (value === null || value === undefined || value === '') return null;\n const num = Number(value);\n if (isNaN(num) || !Number.isInteger(num)) {\n return 'Must be a whole number';\n }\n return null;\n },\n\n phone: (value) => {\n if (!value) return null;\n const phoneRegex = /^[\\d\\s\\-\\+\\(\\)]+$/;\n if (!phoneRegex.test(value) || value.replace(/\\D/g, '').length < 10) {\n return 'Please enter a valid phone number';\n }\n return null;\n },\n\n date: (value) => {\n if (!value) return null;\n const date = new Date(value);\n if (isNaN(date.getTime())) {\n return 'Please enter a valid date';\n }\n return null;\n },\n\n match: (value, options = {}, translator, allValues = {}) => {\n if (!value) return null;\n const fieldName = options.field || options.fieldName;\n if (value !== allValues[fieldName]) {\n return options.message || `Must match ${fieldName}`;\n }\n return null;\n },\n\n custom: (value, options = {}, translator, allValues) => {\n const validatorFn = options.validator || options.fn;\n if (!validatorFn) return null;\n const isValid = validatorFn(value, allValues);\n return isValid ? null : (options.message || 'Validation failed');\n },\n\n fileType: (value, options = {}) => {\n if (!value) return null;\n \n const allowedTypes = options.accept || options.types || [];\n \n // Handle File object\n if (value.type !== undefined) {\n const fileType = value.type;\n const fileExt = value.name ? value.name.split('.').pop().toLowerCase() : '';\n \n // Check MIME type or extension\n const isValid = allowedTypes.some(type => {\n if (type.startsWith('.')) {\n return fileExt === type.slice(1).toLowerCase();\n }\n if (type.includes('/')) {\n if (type.endsWith('/*')) {\n return fileType.startsWith(type.replace('/*', '/'));\n }\n return fileType === type;\n }\n return fileExt === type.toLowerCase();\n });\n \n if (!isValid) {\n return options.message || `File type must be one of: ${allowedTypes.join(', ')}`;\n }\n return null;\n }\n \n return null;\n },\n\n fileSize: (value, options = {}) => {\n if (!value) return null;\n \n const maxSize = options.maxSize || Infinity;\n \n // Handle File object\n if (value.size !== undefined) {\n if (value.size > maxSize) {\n const maxSizeMB = (maxSize / (1024 * 1024)).toFixed(2);\n return options.message || `File size must be less than ${maxSizeMB}MB`;\n }\n return null;\n }\n \n return null;\n },\n\n fileExtension: (value, options = {}) => {\n if (!value) return null;\n \n const allowedExtensions = options.extensions || [];\n const fileName = value.name || value;\n const ext = `.${ fileName.split('.').pop().toLowerCase()}`;\n \n const isValid = allowedExtensions.some(allowed => {\n return ext === allowed.toLowerCase();\n });\n \n if (!isValid) {\n return options.message || `File extension must be one of: ${allowedExtensions.join(', ')}`;\n }\n return null;\n },\n\n alpha: (value) => {\n if (!value) return null;\n const alphaRegex = /^[a-zA-Z]+$/;\n if (!alphaRegex.test(value)) {\n return 'Must contain only letters';\n }\n return null;\n },\n\n alphanumeric: (value) => {\n if (!value) return null;\n const alphanumericRegex = /^[a-zA-Z0-9]+$/;\n if (!alphanumericRegex.test(value)) {\n return 'Must contain only letters and numbers';\n }\n return null;\n },\n\n uppercase: (value) => {\n if (!value) return null;\n if (value !== value.toUpperCase()) {\n return 'Must be uppercase';\n }\n return null;\n },\n\n // Get a registered validator\n get: (name) => {\n return validators[name];\n },\n\n // Compose multiple validators\n compose: (validatorList) => {\n return (value, options, translator, allValues) => {\n for (const validator of validatorList) {\n const error = typeof validator === 'function'\n ? validator(value, options, translator, allValues)\n : null;\n if (error) {\n return error;\n }\n }\n return null;\n };\n },\n\n // Debounce async validator\n debounce: (validator, delay = 300) => {\n let timeoutId;\n return (value) => {\n return new Promise((resolve) => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(async () => {\n const result = await validator(value);\n resolve(result);\n }, delay);\n });\n };\n },\n\n // Cancellable async validator\n cancellable: (validator) => {\n let abortController;\n const wrapped = async (value) => {\n if (abortController) {\n abortController.abort();\n }\n // AbortController is a global browser/Node.js API\n abortController = typeof AbortController !== 'undefined' ? new AbortController() : null;\n try {\n return await validator(value, abortController ? abortController.signal : null);\n } catch (error) {\n if (error.name === 'AbortError') {\n return null;\n }\n throw error;\n }\n };\n wrapped.cancel = () => {\n if (abortController) {\n abortController.abort();\n }\n };\n return wrapped;\n },\n\n // Conditional validator\n when: (condition, validator) => {\n return (value, options = {}, translator, allValues = {}) => {\n // Pass options as context if it looks like context (has non-validator properties)\n const context = options.min !== undefined || options.max !== undefined ? allValues : options;\n const shouldValidate = typeof condition === 'function' \n ? condition(value, context) \n : condition;\n \n if (!shouldValidate) {\n return null;\n }\n \n return typeof validator === 'function'\n ? validator(value, options, translator, allValues)\n : null;\n };\n },\n\n // Validator chain builder\n chain: (options = {}) => {\n const validatorList = [];\n const stopOnFirstError = options.stopOnFirstError !== false;\n \n const chain = {\n required: (opts) => {\n validatorList.push((v, o, t, a) => validators.required(v, opts || o, t, a));\n return chain;\n },\n email: (opts) => {\n validatorList.push((v, o, t, a) => validators.email(v, opts || o, t, a));\n return chain;\n },\n minLength: (opts) => {\n validatorList.push((v, o, t, a) => validators.minLength(v, opts || o, t, a));\n return chain;\n },\n maxLength: (opts) => {\n validatorList.push((v, o, t, a) => validators.maxLength(v, opts || o, t, a));\n return chain;\n },\n custom: (fn, message) => {\n validatorList.push((v, o, t, a) => {\n // Custom validator returns null if valid, message if invalid\n const result = fn(v, a);\n return result === null || result === true || result === undefined ? null : (message || result);\n });\n return chain;\n },\n validate: (value, opts, translator, allValues) => {\n if (stopOnFirstError) {\n // Stop on first error - return single error or null\n for (const validator of validatorList) {\n const error = validator(value, opts, translator, allValues);\n if (error) {\n return error;\n }\n }\n return null;\n } else {\n // Collect all errors - return array or null\n const errors = [];\n for (const validator of validatorList) {\n const error = validator(value, opts, translator, allValues);\n if (error) {\n errors.push(error);\n }\n }\n return errors.length > 0 ? errors : null;\n }\n }\n };\n \n return chain;\n }\n};\n\n/**\n * Validate a single field\n */\nexport function validateField(value, validatorList, formData = {}) {\n for (const validator of validatorList) {\n const error = validator(value, formData);\n if (error) {\n return error;\n }\n }\n return null;\n}\n\n/**\n * Validate entire form\n */\nexport function validateForm(formData, fieldValidators) {\n const errors = {};\n \n for (const [fieldName, validatorList] of Object.entries(fieldValidators)) {\n const value = formData[fieldName];\n const error = validateField(value, validatorList, formData);\n if (error) {\n errors[fieldName] = error;\n }\n }\n \n return Object.keys(errors).length > 0 ? errors : null;\n}\n\n/**\n * Create a validator\n */\nexport function createValidator(validatorFn, message) {\n return (value, options, translator, allValues) => {\n const result = validatorFn(value, options, translator, allValues);\n // If validator returns a string, use it as the error message\n if (typeof result === 'string') {\n return result;\n }\n // If validator returns falsy (null, false, undefined), no error\n if (!result) {\n return null;\n }\n // If validator returns truthy (true, object, etc), use provided message\n return message || 'Validation failed';\n };\n}\n\n/**\n * Register a custom validator\n *\n * index.js re-exports validation.js's `validators`, which shadows this\n * module's object in the star export \u2014 so registering only here left\n * `validators[name]` undefined for every consumer. Register in both: the\n * package registry so callers can reach it, and the local one so `get()` and\n * `compose()` keep resolving it by name.\n */\nexport function registerValidator(name, validatorFn) {\n validators[name] = validatorFn;\n packageValidators[name] = validatorFn;\n}\n\n/**\n * Compose multiple validators\n */\nexport function composeValidators(...validatorFns) {\n return (value, options, translator, allValues) => {\n for (const validator of validatorFns) {\n const error = validator(value, options, translator, allValues);\n if (error) {\n return error;\n }\n }\n return null;\n };\n}\n\nexport default {\n validators,\n validateField,\n validateForm,\n createValidator,\n registerValidator,\n composeValidators\n};\n", "/**\n * Form Hydration for Coherent.js\n *\n * Progressive enhancement for server-rendered forms\n * Reads validation metadata from HTML and attaches client-side behavior\n *\n * @module forms/form-hydration\n */\n\nimport { validators } from './validators.js';\n\n/**\n * Hydrate a server-rendered form with client-side validation and behavior\n *\n * @param {string|HTMLFormElement} formSelector - Form selector or element\n * @param {Object} options - Hydration options\n * @returns {Object} Form controller\n */\nexport function hydrateForm(formSelector, options = {}) {\n // Browser-only check\n if (typeof document === 'undefined') {\n console.warn('hydrateForm can only run in browser environment');\n return null;\n }\n\n const form = typeof formSelector === 'string'\n ? document.querySelector(formSelector)\n : formSelector;\n\n if (!form) {\n console.warn(`Form not found: ${formSelector}`);\n return null;\n }\n\n const opts = {\n validateOnBlur: true,\n validateOnChange: false,\n validateOnSubmit: true,\n showErrorsOnTouch: true,\n debounce: 300,\n ...options\n };\n\n // Form state\n const state = {\n values: {},\n errors: {},\n touched: {},\n isSubmitting: false,\n fields: new Map()\n };\n\n // Debounce timers\n const debounceTimers = new Map();\n\n /**\n * Parse validators from data-validators attribute\n */\n function parseValidators(validatorString) {\n if (!validatorString) return [];\n\n return validatorString.split(',').map(v => {\n const trimmed = v.trim();\n\n // Handle validators with parameters: minLength:8\n const [name, ...params] = trimmed.split(':');\n\n if (validators[name]) {\n return params.length > 0\n ? validators[name](...params.map(p => isNaN(p) ? p : Number(p)))\n : validators[name];\n }\n\n return null;\n }).filter(Boolean);\n }\n\n /**\n * Discover and register fields from form HTML\n */\n function discoverFields() {\n const inputs = form.querySelectorAll('[name]');\n\n inputs.forEach(input => {\n const name = input.getAttribute('name');\n const field = {\n name,\n element: input,\n type: input.getAttribute('type') || 'text',\n required: input.hasAttribute('required') || input.dataset.required === 'true',\n validators: parseValidators(input.dataset.validators),\n errorElement: null\n };\n\n // Find or create error display element\n const errorId = `${name}-error`;\n field.errorElement = document.getElementById(errorId) || createErrorElement(name, input);\n\n state.fields.set(name, field);\n state.values[name] = getFieldValue(input);\n state.touched[name] = false;\n state.errors[name] = null;\n });\n }\n\n /**\n * Create error display element\n */\n function createErrorElement(name, inputElement) {\n const errorDiv = document.createElement('div');\n errorDiv.id = `${name}-error`;\n errorDiv.className = 'error-message';\n errorDiv.setAttribute('role', 'alert');\n errorDiv.style.display = 'none';\n\n // Insert after input or its parent field wrapper\n const fieldWrapper = inputElement.closest('.form-field') || inputElement.parentElement;\n fieldWrapper.appendChild(errorDiv);\n\n return errorDiv;\n }\n\n /**\n * Get field value based on input type\n */\n function getFieldValue(input) {\n if (input.type === 'checkbox') {\n return input.checked;\n } else if (input.type === 'radio') {\n const checked = form.querySelector(`[name=\"${input.name}\"]:checked`);\n return checked ? checked.value : null;\n } else {\n return input.value;\n }\n }\n\n /**\n * Set field value\n */\n function setFieldValue(name, value) {\n const field = state.fields.get(name);\n if (!field) return;\n\n const { element } = field;\n\n if (element.type === 'checkbox') {\n element.checked = Boolean(value);\n } else if (element.type === 'radio') {\n const radio = form.querySelector(`[name=\"${name}\"][value=\"${value}\"]`);\n if (radio) radio.checked = true;\n } else {\n element.value = value;\n }\n\n state.values[name] = value;\n }\n\n /**\n * Validate a single field\n */\n function validateField(name) {\n const field = state.fields.get(name);\n if (!field) return true;\n\n const value = state.values[name];\n let error = null;\n\n // Required validation\n if (field.required && (value === null || value === undefined || value === '')) {\n error = 'This field is required';\n }\n\n // Run custom validators\n if (!error && field.validators.length > 0) {\n for (const validator of field.validators) {\n const result = validator.validate\n ? validator.validate(value, state.values)\n : validator(value, state.values);\n\n if (result !== true && result !== undefined && result !== null) {\n error = validator.message || result || 'Validation failed';\n break;\n }\n }\n }\n\n state.errors[name] = error;\n displayError(name, error);\n\n return !error;\n }\n\n /**\n * Display error message\n */\n function displayError(name, error) {\n const field = state.fields.get(name);\n if (!field) return;\n\n const { element, errorElement } = field;\n\n if (error && state.touched[name] && opts.showErrorsOnTouch) {\n // Show error\n errorElement.textContent = error;\n errorElement.style.display = 'block';\n element.setAttribute('aria-invalid', 'true');\n element.classList.add('error');\n } else {\n // Hide error\n errorElement.textContent = '';\n errorElement.style.display = 'none';\n element.setAttribute('aria-invalid', 'false');\n element.classList.remove('error');\n }\n }\n\n /**\n * Validate entire form\n */\n function validateForm() {\n let isValid = true;\n\n for (const name of state.fields.keys()) {\n const fieldValid = validateField(name);\n if (!fieldValid) isValid = false;\n }\n\n return isValid;\n }\n\n /**\n * Handle input change\n */\n function handleChange(event) {\n const input = event.target;\n const name = input.getAttribute('name');\n\n if (!state.fields.has(name)) return;\n\n state.values[name] = getFieldValue(input);\n\n if (opts.validateOnChange) {\n // Debounce validation\n if (debounceTimers.has(name)) {\n clearTimeout(debounceTimers.get(name));\n }\n\n const timer = setTimeout(() => {\n validateField(name);\n debounceTimers.delete(name);\n }, opts.debounce);\n\n debounceTimers.set(name, timer);\n }\n }\n\n /**\n * Handle input blur\n */\n function handleBlur(event) {\n const input = event.target;\n const name = input.getAttribute('name');\n\n if (!state.fields.has(name)) return;\n\n state.touched[name] = true;\n\n if (opts.validateOnBlur) {\n validateField(name);\n }\n }\n\n /**\n * Handle form submission\n */\n function handleSubmit(event) {\n event.preventDefault();\n\n // Mark all fields as touched\n for (const name of state.fields.keys()) {\n state.touched[name] = true;\n }\n\n const isValid = validateForm();\n\n if (!isValid) {\n // Focus first error field\n const firstErrorField = Array.from(state.fields.values())\n .find(field => state.errors[field.name]);\n\n if (firstErrorField) {\n firstErrorField.element.focus();\n }\n\n // Call onError callback\n if (options.onError) {\n options.onError(state.errors);\n }\n\n return;\n }\n\n // Form is valid, prepare submission\n state.isSubmitting = true;\n\n const submitData = { ...state.values };\n\n // Call onSubmit callback\n if (options.onSubmit) {\n const result = options.onSubmit(submitData, event);\n\n // If onSubmit returns false, don't submit\n if (result === false) {\n state.isSubmitting = false;\n return;\n }\n\n // If onSubmit returns a promise, wait for it\n if (result && typeof result.then === 'function') {\n result\n .then(() => {\n state.isSubmitting = false;\n if (options.onSuccess) {\n options.onSuccess(submitData);\n }\n })\n .catch(error => {\n state.isSubmitting = false;\n if (options.onError) {\n options.onError(error);\n }\n });\n return;\n }\n }\n\n // Default: submit the form normally\n if (!options.onSubmit) {\n form.submit();\n }\n\n state.isSubmitting = false;\n }\n\n /**\n * Attach event listeners\n */\n function attachEventListeners() {\n // Input change events\n state.fields.forEach(field => {\n field.element.addEventListener('input', handleChange);\n field.element.addEventListener('blur', handleBlur);\n });\n\n // Form submit\n form.addEventListener('submit', handleSubmit);\n }\n\n /**\n * Detach event listeners (cleanup)\n */\n function detachEventListeners() {\n state.fields.forEach(field => {\n field.element.removeEventListener('input', handleChange);\n field.element.removeEventListener('blur', handleBlur);\n });\n\n form.removeEventListener('submit', handleSubmit);\n\n // Clear debounce timers\n debounceTimers.forEach(timer => clearTimeout(timer));\n debounceTimers.clear();\n }\n\n /**\n * Reset form to initial state\n */\n function reset() {\n state.fields.forEach(field => {\n setFieldValue(field.name, '');\n state.touched[field.name] = false;\n state.errors[field.name] = null;\n displayError(field.name, null);\n });\n\n state.isSubmitting = false;\n form.reset();\n }\n\n // Initialize\n discoverFields();\n attachEventListeners();\n\n // Public API\n return {\n validateField,\n validateForm,\n setFieldValue,\n getFieldValue: (name) => state.values[name],\n getError: (name) => state.errors[name],\n getErrors: () => ({ ...state.errors }),\n getValues: () => ({ ...state.values }),\n setTouched: (name, touched = true) => {\n state.touched[name] = touched;\n },\n reset,\n destroy: detachEventListeners,\n isValid: () => Object.values(state.errors).every(e => !e),\n isSubmitting: () => state.isSubmitting,\n getState: () => ({\n values: { ...state.values },\n errors: { ...state.errors },\n touched: { ...state.touched },\n isSubmitting: state.isSubmitting\n })\n };\n}\n\nexport default hydrateForm;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }