@fogpipe/forma-react 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +111 -26
  2. package/dist/FormRenderer-D_ZVK44t.d.ts +558 -0
  3. package/dist/chunk-5K4QITFH.js +1276 -0
  4. package/dist/chunk-5K4QITFH.js.map +1 -0
  5. package/dist/defaults/index.d.ts +56 -0
  6. package/dist/defaults/index.js +895 -0
  7. package/dist/defaults/index.js.map +1 -0
  8. package/dist/defaults/styles/forma-defaults.css +696 -0
  9. package/dist/index.d.ts +13 -549
  10. package/dist/index.js +34 -1273
  11. package/dist/index.js.map +1 -1
  12. package/package.json +17 -3
  13. package/src/FieldRenderer.tsx +12 -4
  14. package/src/FormRenderer.tsx +26 -9
  15. package/src/__tests__/FieldRenderer.test.tsx +5 -1
  16. package/src/__tests__/FormRenderer.test.tsx +146 -0
  17. package/src/__tests__/canProceed.test.ts +243 -0
  18. package/src/__tests__/defaults/components.test.tsx +818 -0
  19. package/src/__tests__/defaults/integration.test.tsx +494 -0
  20. package/src/__tests__/defaults/layout.test.tsx +298 -0
  21. package/src/__tests__/events.test.ts +15 -5
  22. package/src/__tests__/useForma.test.ts +108 -5
  23. package/src/defaults/DefaultFormRenderer.tsx +43 -0
  24. package/src/defaults/componentMap.ts +45 -0
  25. package/src/defaults/components/ArrayField.tsx +183 -0
  26. package/src/defaults/components/BooleanInput.tsx +32 -0
  27. package/src/defaults/components/ComputedDisplay.tsx +26 -0
  28. package/src/defaults/components/DateInput.tsx +59 -0
  29. package/src/defaults/components/DisplayField.tsx +15 -0
  30. package/src/defaults/components/FallbackField.tsx +35 -0
  31. package/src/defaults/components/MatrixField.tsx +98 -0
  32. package/src/defaults/components/MultiSelectInput.tsx +51 -0
  33. package/src/defaults/components/NumberInput.tsx +73 -0
  34. package/src/defaults/components/ObjectField.tsx +22 -0
  35. package/src/defaults/components/SelectInput.tsx +44 -0
  36. package/src/defaults/components/TextInput.tsx +48 -0
  37. package/src/defaults/components/TextareaInput.tsx +46 -0
  38. package/src/defaults/index.ts +33 -0
  39. package/src/defaults/layout/FieldWrapper.tsx +83 -0
  40. package/src/defaults/layout/FormLayout.tsx +34 -0
  41. package/src/defaults/layout/PageWrapper.tsx +18 -0
  42. package/src/defaults/layout/WizardLayout.tsx +130 -0
  43. package/src/defaults/styles/forma-defaults.css +696 -0
  44. package/src/events.ts +4 -1
  45. package/src/types.ts +16 -4
  46. package/src/useForma.ts +48 -34
package/README.md CHANGED
@@ -199,13 +199,13 @@ The event system lets you observe form lifecycle events for side effects like an
199
199
 
200
200
  ### Available Events
201
201
 
202
- | Event | Description |
203
- | -------------- | ------------------------------------------------------- |
204
- | `fieldChanged` | Fires after a field value changes |
205
- | `preSubmit` | Fires before validation; `data` is mutable |
206
- | `postSubmit` | Fires after submission (success, error, or invalid) |
207
- | `pageChanged` | Fires when wizard page changes |
208
- | `formReset` | Fires after `resetForm()` completes |
202
+ | Event | Description |
203
+ | -------------- | --------------------------------------------------- |
204
+ | `fieldChanged` | Fires after a field value changes |
205
+ | `preSubmit` | Fires before validation; `data` is mutable |
206
+ | `postSubmit` | Fires after submission (success, error, or invalid) |
207
+ | `pageChanged` | Fires when wizard page changes |
208
+ | `formReset` | Fires after `resetForm()` completes |
209
209
 
210
210
  ### Declarative Registration
211
211
 
@@ -217,7 +217,10 @@ const forma = useForma({
217
217
  onSubmit: handleSubmit,
218
218
  on: {
219
219
  fieldChanged: (event) => {
220
- analytics.track("field_changed", { path: event.path, source: event.source });
220
+ analytics.track("field_changed", {
221
+ path: event.path,
222
+ source: event.source,
223
+ });
221
224
  },
222
225
  preSubmit: async (event) => {
223
226
  event.data.token = await getCSRFToken();
@@ -302,28 +305,28 @@ formRef.current?.setValues({ name: "John" });
302
305
 
303
306
  ### useForma Methods
304
307
 
305
- | Method | Description |
306
- | --------------------------------- | ------------------------------------ |
307
- | `setFieldValue(path, value)` | Set field value |
308
- | `setFieldTouched(path, touched?)` | Mark field as touched |
309
- | `setValues(values)` | Set multiple values |
310
- | `validateField(path)` | Validate single field |
311
- | `validateForm()` | Validate entire form |
312
- | `submitForm()` | Submit the form |
313
- | `resetForm()` | Reset to initial values |
308
+ | Method | Description |
309
+ | --------------------------------- | -------------------------------------------- |
310
+ | `setFieldValue(path, value)` | Set field value |
311
+ | `setFieldTouched(path, touched?)` | Mark field as touched |
312
+ | `setValues(values)` | Set multiple values |
313
+ | `validateField(path)` | Validate single field |
314
+ | `validateForm()` | Validate entire form |
315
+ | `submitForm()` | Submit the form |
316
+ | `resetForm()` | Reset to initial values |
314
317
  | `on(event, listener)` | Register event listener; returns unsubscribe |
315
318
 
316
319
  ### useForma Options
317
320
 
318
- | Option | Type | Default | Description |
319
- | ---------------------- | -------------------------------- | -------- | ------------------------- |
320
- | `spec` | `Forma` | required | The Forma specification |
321
- | `initialData` | `Record<string, unknown>` | `{}` | Initial form values |
322
- | `onSubmit` | `(data) => void` | - | Submit handler |
323
- | `onChange` | `(data, computed) => void` | - | Change handler |
324
- | `validateOn` | `"change" \| "blur" \| "submit"` | `"blur"` | When to validate |
325
- | `referenceData` | `Record<string, unknown>` | - | Additional reference data |
326
- | `validationDebounceMs` | `number` | `0` | Debounce validation (ms) |
321
+ | Option | Type | Default | Description |
322
+ | ---------------------- | -------------------------------- | -------- | --------------------------- |
323
+ | `spec` | `Forma` | required | The Forma specification |
324
+ | `initialData` | `Record<string, unknown>` | `{}` | Initial form values |
325
+ | `onSubmit` | `(data) => void` | - | Submit handler |
326
+ | `onChange` | `(data, computed) => void` | - | Change handler |
327
+ | `validateOn` | `"change" \| "blur" \| "submit"` | `"blur"` | When to validate |
328
+ | `referenceData` | `Record<string, unknown>` | - | Additional reference data |
329
+ | `validationDebounceMs` | `number` | `0` | Debounce validation (ms) |
327
330
  | `on` | `FormaEvents` | - | Declarative event listeners |
328
331
 
329
332
  ## Error Boundary
@@ -351,6 +354,88 @@ The error boundary supports:
351
354
  - `onError` callback for logging
352
355
  - `resetKey` prop to reset error state
353
356
 
357
+ ## Default Components
358
+
359
+ Don't want to build every field component yourself? The default component library gives you a working form in 2 lines:
360
+
361
+ ```tsx
362
+ import { DefaultFormRenderer } from "@fogpipe/forma-react/defaults";
363
+ import "@fogpipe/forma-react/defaults/styles.css";
364
+
365
+ <DefaultFormRenderer spec={formaSpec} onSubmit={handleSubmit} />;
366
+ ```
367
+
368
+ This renders a fully styled, accessible form with all 18 field types, error handling, and wizard support — zero configuration.
369
+
370
+ ### Override Individual Components
371
+
372
+ Swap any component while keeping the rest:
373
+
374
+ ```tsx
375
+ import { FormRenderer } from "@fogpipe/forma-react";
376
+ import {
377
+ defaultComponentMap,
378
+ defaultFieldWrapper,
379
+ defaultLayout,
380
+ } from "@fogpipe/forma-react/defaults";
381
+ import "@fogpipe/forma-react/defaults/styles.css";
382
+
383
+ const components = { ...defaultComponentMap, select: MyFancySelect };
384
+
385
+ <FormRenderer
386
+ spec={formaSpec}
387
+ components={components}
388
+ fieldWrapper={defaultFieldWrapper}
389
+ layout={defaultLayout}
390
+ onSubmit={handleSubmit}
391
+ />;
392
+ ```
393
+
394
+ ### Wizard Forms
395
+
396
+ Enable wizard layout for multi-page forms:
397
+
398
+ ```tsx
399
+ <DefaultFormRenderer spec={wizardSpec} onSubmit={handleSubmit} wizardLayout />
400
+ ```
401
+
402
+ ### Theming
403
+
404
+ Override CSS variables to customize the look:
405
+
406
+ ```css
407
+ :root {
408
+ --forma-color-primary: #7c3aed;
409
+ --forma-color-error: #e11d48;
410
+ --forma-radius: 12px;
411
+ --forma-font-family: "Inter", sans-serif;
412
+ }
413
+ ```
414
+
415
+ Dark mode works via `[data-theme="dark"]` attribute or `prefers-color-scheme: dark` media query.
416
+
417
+ ### Component Reference
418
+
419
+ | Field Type | Component | Renders |
420
+ |---|---|---|
421
+ | `text`, `email`, `phone`, `url`, `password` | TextInput | `<input>` with type mapping |
422
+ | `textarea` | TextareaInput | `<textarea>` |
423
+ | `number` | NumberInput | `<input type="number">` with parseFloat |
424
+ | `integer` | IntegerInput | `<input type="number">` with parseInt |
425
+ | `boolean` | BooleanInput | Custom styled checkbox |
426
+ | `date` | DateInput | `<input type="date">` |
427
+ | `datetime` | DateTimeInput | `<input type="datetime-local">` |
428
+ | `select` | SelectInput | Native `<select>` with custom arrow |
429
+ | `multiselect` | MultiSelectInput | Checkbox group |
430
+ | `array` | ArrayField | Item list with Add/Remove |
431
+ | `object` | ObjectField | `<fieldset>` container |
432
+ | `computed` | ComputedDisplay | Read-only `<output>` |
433
+ | `display` | DisplayField | Static content `<div>` |
434
+ | `matrix` | MatrixField | `<table>` with radio/checkbox cells |
435
+ | `fallback` | FallbackField | Text input + dev warning |
436
+
437
+ See the [full documentation](https://docs.formidable.fogpipe.com/forma-react/default-components) for theming details, all CSS variables, and advanced usage.
438
+
354
439
  ## License
355
440
 
356
441
  MIT