@formancy/react 0.10.0 → 0.11.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/context.tsx","../src/use-field.ts","../src/use-repeater.ts","../src/use-wizard.ts","../src/use-submit.ts","../src/go-to-field.ts","../src/fields/internals.tsx","../src/form.tsx","../src/error-summary.tsx","../src/rich-text.tsx","../src/options-source.ts","../src/scanning.ts","../src/uploads.ts","../src/rich-text-editor.ts","../src/resume-notice.tsx"],"mappings":";;;;;wBAsBgB,mBACd,QACA,OACA;EAEA,QAAQ;;;;;;;EAOR,QAAQ;EACR,WAAW;oBACZ,IAAA;wBAsBe,iBAAiB;;;;;;;;;wBAkBjB,eAAe;;;UCvEd,qBAAqB;EACpC,SAAS;EACT;;EAEA,cAAc;;EAEd;IAAc;IAAY;;;EAE1B;IAAc;;;;;;;;;;;;;wBAaA,SAAS,eAAe,OAAO;;;UCrB9B;EACf;;EAEA;;EAEA;;EAEA;EACA;EACA,UAAU;;EAEV,QAAQ,cAAc;;;;;;;wBAQR,YAAY,eAAe,OAAO;;;UCrBjC;EACf;EACA;;;EAGA;EACA;;EAEA,QAAQ;EACR;;EAEA,KAAK;;;;;;;wBAQS,aAAa;;;;;;;;;;;wBCTb;EAAqB;EAAa,QAAQ;;;;;;;;;;;wBCD1C,iBAAiB;;;;;;;;;;;;;;;;UCYhB;EACf;EACA;;KAGU,iBAAiB,cAAc;UAE1B;EACf,SAAS,QAAQ,OAAO,WAAW;EACnC,SAAS,eAAe;;UAGT;EACf;EACA,QAAQ;;EAER;;UAGe;;;;;;;EAOf,SAAS;EACT,WAAW;;;;;;;EAOX;EACA;;;;;EAKA;EACA,YAAY,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;wBCNP,aAAa,OAAO,oCAAiB,IAAA;;;UCrDpC;EACf,SAAS;;;;;;;;;;;wBAYK,eAAe,UAAU,oCAAiB,IAAA;;;;;;;;;;;;;;;;;;;;wBCG1C,WAAW;EAAY;IAAmB;;;;;;;;;;UCZzC;;;;;EAKf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;;EASA;;;;;;;;EAQA;;EAEA,QAAQ;;;;;;;;;;;UAYO;;;;;;;;;;;;;EAaf,QAAQ,SAAS,iBAAiB,QAAQ;;EAE1C;;;;;;EAMA;;EAEA;;;;;;;;;;;;;KAcU,iBAAiB,SAAS,eAAe;qBAIxC,wCAAsB,SAAA,SAAA,eAAA;;;;;;;;;wBAUnB,qBAAqB;;;;;;;;;;;;UC9FpB;;EAEf;;EAEA;;;;;;;;;;;;;;;;;;;KAoBU,WAAW,SAAS,gBAAgB;qBAInC,iCAAe,SAAA;;;;;;;;wBASZ,cAAc;;;;;;;;;;;UC/Bb;;;;;EAKf;;EAEA,QAAQ;;EAER,WAAW,cAAc;;;;;;;;;;;;KAaf,YAAY,MAAM,MAAM,SAAS,kBAAkB,QAAQ;qBAI1D,kCAAgB,SAAA;;;;;;;;;wBAUb,eAAe;;;;;;;;;;;;;;;;;;;;;UChCd;;EAEf;;EAEA,WAAW;;;;;;;;;;;;;EAaX,MAAM,SAAS,aAAa;;EAE5B,WAAW,SAAS;EACpB;;UAGe;;WAEN,SAAS;;WAET;;WAEA,WAAW;WACX;;;;;;;;;;WAUA,YAAY,SAAS;;KAGpB,yBAAyB,OAAO,wBAAwB;qBAIvD,wCAAsB,SAAA;;;;;;;;;wBAUnB,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UC9C3B;WACN;WACA,SAAS;aAAyB;aAAuB;;;UAGnD;;WAEN,YAAY;;WAEZ,SAAS,SAAS;;wBAGb,eAAe,WAAW,UAAU,oBAAoB"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/context.tsx","../src/use-field.ts","../src/use-repeater.ts","../src/use-wizard.ts","../src/use-submit.ts","../src/go-to-field.ts","../src/fields/internals.tsx","../src/form.tsx","../src/error-summary.tsx","../src/rich-text.tsx","../src/options-source.ts","../src/scanning.ts","../src/uploads.ts","../src/rich-text-editor.ts","../src/resume-notice.tsx"],"mappings":";;;;;wBAsBgB,mBACd,QACA,OACA;EAEA,QAAQ;;;;;;;EAOR,QAAQ;EACR,WAAW;oBACZ,IAAA;wBAsBe,iBAAiB;;;;;;;;;wBAkBjB,eAAe;;;UCvEd,qBAAqB;EACpC,SAAS;EACT;;EAEA,cAAc;;EAEd;IAAc;IAAY;;;EAE1B;IAAc;;;;;;;;;;;;;wBAaA,SAAS,eAAe,OAAO;;;UCrB9B;EACf;;EAEA;;EAEA;;EAEA;EACA;EACA,UAAU;;EAEV,QAAQ,cAAc;;;;;;;wBAQR,YAAY,eAAe,OAAO;;;UCrBjC;EACf;EACA;;;EAGA;EACA;;EAEA,QAAQ;EACR;;EAEA,KAAK;;;;;;;wBAQS,aAAa;;;;;;;;;;;wBCTb;EAAqB;EAAa,QAAQ;;;;;;;;;;;wBCD1C,iBAAiB;;;;;;;;;;;;;;;;UCYhB;EACf;EACA;;KAGU,iBAAiB,cAAc;UAE1B;EACf,SAAS,QAAQ,OAAO,WAAW;EACnC,SAAS,eAAe;;UAGT;EACf;EACA,QAAQ;;EAER;;UAGe;;;;;;;EAOf,SAAS;EACT,WAAW;;;;;;;EAOX;EACA;;;;;EAKA;EACA,YAAY,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;wBCdP,aAAa,OAAO,oCAAiB,IAAA;;;UC7CpC;EACf,SAAS;;;;;;;;;;;wBAYK,eAAe,UAAU,oCAAiB,IAAA;;;;;;;;;;;;;;;;;;;;wBCG1C,WAAW;EAAY;IAAmB;;;;;;;;;;UCZzC;;;;;EAKf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;;EASA;;;;;;;;EAQA;;EAEA,QAAQ;;;;;;;;;;;UAYO;;;;;;;;;;;;;EAaf,QAAQ,SAAS,iBAAiB,QAAQ;;EAE1C;;;;;;EAMA;;EAEA;;;;;;;;;;;;;KAcU,iBAAiB,SAAS,eAAe;qBAIxC,wCAAsB,SAAA,SAAA,eAAA;;;;;;;;;wBAUnB,qBAAqB;;;;;;;;;;;;UC9FpB;;EAEf;;EAEA;;;;;;;;;;;;;;;;;;;KAoBU,WAAW,SAAS,gBAAgB;qBAInC,iCAAe,SAAA;;;;;;;;wBASZ,cAAc;;;;;;;;;;;UC/Bb;;;;;EAKf;;EAEA,QAAQ;;EAER,WAAW,cAAc;;;;;;;;;;;;KAaf,YAAY,MAAM,MAAM,SAAS,kBAAkB,QAAQ;qBAI1D,kCAAgB,SAAA;;;;;;;;;wBAUb,eAAe;;;;;;;;;;;;;;;;;;;;;UChCd;;EAEf;;EAEA,WAAW;;;;;;;;;;;;;EAaX,MAAM,SAAS,aAAa;;EAE5B,WAAW,SAAS;EACpB;;UAGe;;WAEN,SAAS;;WAET;;WAEA,WAAW;WACX;;;;;;;;;;WAUA,YAAY,SAAS;;KAGpB,yBAAyB,OAAO,wBAAwB;qBAIvD,wCAAsB,SAAA;;;;;;;;;wBAUnB,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UC9C3B;WACN;WACA,SAAS;aAAyB;aAAuB;;;UAGnD;;WAEN,YAAY;;WAEZ,SAAS,SAAS;;wBAGb,eAAe,WAAW,UAAU,oBAAoB"}
package/dist/index.mjs CHANGED
@@ -122,7 +122,7 @@ function focusControl(control) {
122
122
  if (control === null) return;
123
123
  control.dispatchEvent(new Event("formancy-reveal", { bubbles: true }));
124
124
  control.focus();
125
- if (document.activeElement !== control) control.querySelector("input, select, textarea, button")?.focus();
125
+ if (document.activeElement !== control) control.querySelector("input, select, textarea, button, [data-formancy-part$=\"-unavailable\"]")?.focus();
126
126
  }
127
127
  //#endregion
128
128
  //#region src/use-submit.ts
@@ -384,6 +384,16 @@ function placedPaths(nodes, into = []) {
384
384
  return into;
385
385
  }
386
386
  //#endregion
387
+ //#region src/focus-row.ts
388
+ function focusRow(repeater, target, add) {
389
+ if (target === "add") return focusControl(add);
390
+ const row = repeater.querySelectorAll("[data-formancy-part=\"row\"], [data-formancy-part=\"datagrid-row\"]")[target.row];
391
+ if (row === void 0) return;
392
+ const part = target.parts.map((name) => row.querySelector(`[data-formancy-part="${name}"]`)).find((found) => found !== null);
393
+ const first = row.querySelector("input:not([type=\"hidden\"]):not(:disabled), select:not(:disabled), textarea:not(:disabled), button:not(:disabled), [contenteditable=\"true\"], [tabindex=\"0\"]");
394
+ focusControl(part ?? first);
395
+ }
396
+ //#endregion
387
397
  //#region src/review.tsx
388
398
  function SubmitButton({ submitLabel, onSubmit, onFailedNavigate }) {
389
399
  const engine = useFormEngine();
@@ -781,6 +791,24 @@ function OptionPicture({ option }) {
781
791
  }), " "] });
782
792
  }
783
793
  //#endregion
794
+ //#region src/fields/computed-answer.tsx
795
+ function ComputedAnswerField({ path, label }) {
796
+ const field = useField(path);
797
+ const engine = useFormEngine();
798
+ const text = useFormText();
799
+ return /* @__PURE__ */ jsx(FieldShell, {
800
+ path,
801
+ field,
802
+ label,
803
+ children: /* @__PURE__ */ jsx("input", {
804
+ type: "text",
805
+ readOnly: true,
806
+ ...field.controlProps,
807
+ value: answerInWords(engine.schema(), field.def, field.value, text, engine.locale())
808
+ })
809
+ });
810
+ }
811
+ //#endregion
784
812
  //#region src/fields/typeahead-field.tsx
785
813
  function TypeaheadSelectField({ path, label, field }) {
786
814
  const text = useFormText();
@@ -969,6 +997,8 @@ function SelectField({ path, label }) {
969
997
  label,
970
998
  children: /* @__PURE__ */ jsx("p", {
971
999
  "data-formancy-part": "options-unavailable",
1000
+ id: field.controlProps.id,
1001
+ tabIndex: -1,
972
1002
  children: text("options.unavailable", { source: field.def.optionsSource ?? "" })
973
1003
  })
974
1004
  });
@@ -1042,24 +1072,6 @@ function RadioGroupField({ path, label }) {
1042
1072
  });
1043
1073
  }
1044
1074
  //#endregion
1045
- //#region src/fields/computed-answer.tsx
1046
- function ComputedAnswerField({ path, label }) {
1047
- const field = useField(path);
1048
- const engine = useFormEngine();
1049
- const text = useFormText();
1050
- return /* @__PURE__ */ jsx(FieldShell, {
1051
- path,
1052
- field,
1053
- label,
1054
- children: /* @__PURE__ */ jsx("input", {
1055
- type: "text",
1056
- readOnly: true,
1057
- ...field.controlProps,
1058
- value: answerInWords(engine.schema(), field.def, field.value, text, engine.locale())
1059
- })
1060
- });
1061
- }
1062
- //#endregion
1063
1075
  //#region src/fields/file-field.tsx
1064
1076
  function FileField({ path, label }) {
1065
1077
  const field = useField(path);
@@ -1083,6 +1095,8 @@ function FileField({ path, label }) {
1083
1095
  children: [
1084
1096
  upload === void 0 ? /* @__PURE__ */ jsx("p", {
1085
1097
  "data-formancy-part": "file-unavailable",
1098
+ id: field.controlProps.id,
1099
+ tabIndex: -1,
1086
1100
  children: text("file.unavailable")
1087
1101
  }) : /* @__PURE__ */ jsx("div", {
1088
1102
  "data-formancy-part": "file-dropzone",
@@ -1539,6 +1553,8 @@ function TagPickerField({ path, label }) {
1539
1553
  label,
1540
1554
  children: /* @__PURE__ */ jsx("p", {
1541
1555
  "data-formancy-part": "options-unavailable",
1556
+ id: field.controlProps.id,
1557
+ tabIndex: -1,
1542
1558
  children: text("options.unavailable", { source: field.def.optionsSource ?? "" })
1543
1559
  })
1544
1560
  });
@@ -1675,6 +1691,7 @@ function SelectBoxesField({ path, label }) {
1675
1691
  /* @__PURE__ */ jsx(Description, { field }),
1676
1692
  remote?.unavailable === true ? /* @__PURE__ */ jsx("p", {
1677
1693
  "data-formancy-part": "options-unavailable",
1694
+ tabIndex: -1,
1678
1695
  children: text("options.unavailable", { source: field.def.optionsSource ?? "" })
1679
1696
  }) : null,
1680
1697
  options.map((option) => {
@@ -2318,6 +2335,30 @@ function TextareaField({ path, label }) {
2318
2335
  });
2319
2336
  }
2320
2337
  //#endregion
2338
+ //#region src/fields.ts
2339
+ const DEFAULT_COMPONENTS = {
2340
+ text: TextField,
2341
+ textarea: TextareaField,
2342
+ number: NumberSwitch,
2343
+ checkbox: CheckboxField,
2344
+ date: DateField,
2345
+ time: TimeField,
2346
+ datetime: DateTimeField,
2347
+ select: SelectField,
2348
+ radio: RadioGroupField,
2349
+ selectboxes: SelectBoxesSwitch,
2350
+ ranking: RankingField,
2351
+ matrix: MatrixField,
2352
+ file: FileField,
2353
+ richtext: RichTextField,
2354
+ signature: SignatureField,
2355
+ hidden: null,
2356
+ static: StaticField,
2357
+ group: null,
2358
+ page: null,
2359
+ repeater: null
2360
+ };
2361
+ //#endregion
2321
2362
  //#region src/form.tsx
2322
2363
  function FormancyForm(props) {
2323
2364
  return useFormEngine().wizard() === void 0 ? /* @__PURE__ */ jsx(FlatForm, { ...props }) : /* @__PURE__ */ jsx(PagedForm, { ...props });
@@ -2488,6 +2529,14 @@ function RepeaterSection({ wire, labels, registry }) {
2488
2529
  const label = engine.text(def?.label) ?? labels?.[wire] ?? wire;
2489
2530
  const addLabel = def?.addLabel ?? text("repeater.add", { label });
2490
2531
  const removeLabel = def?.removeLabel ?? text("repeater.remove", { label });
2532
+ const fieldset = useRef(null);
2533
+ const addButton = useRef(null);
2534
+ const [focusing, setFocusing] = useState(void 0);
2535
+ useEffect(() => {
2536
+ if (focusing === void 0 || fieldset.current === null) return;
2537
+ focusRow(fieldset.current, focusing, addButton.current);
2538
+ setFocusing(void 0);
2539
+ }, [focusing]);
2491
2540
  const fallbackFor = (instanceWire) => {
2492
2541
  const template = instanceWire.replace(/\[\d+\]/, "[]");
2493
2542
  return labels?.[template] ?? labels?.[instanceWire];
@@ -2506,7 +2555,13 @@ function RepeaterSection({ wire, labels, registry }) {
2506
2555
  type: "button",
2507
2556
  "data-formancy-part": "row-remove",
2508
2557
  disabled: field.disabled,
2509
- onClick: () => repeater.removeRow(index),
2558
+ onClick: () => {
2559
+ repeater.removeRow(index);
2560
+ setFocusing(repeater.rowCount === 1 ? "add" : {
2561
+ row: Math.min(index, repeater.rowCount - 2),
2562
+ parts: []
2563
+ });
2564
+ },
2510
2565
  children: /* @__PURE__ */ jsx("span", {
2511
2566
  "data-formancy-part": "row-action-text",
2512
2567
  children: text("repeater.removeRow", {
@@ -2516,11 +2571,17 @@ function RepeaterSection({ wire, labels, registry }) {
2516
2571
  })
2517
2572
  })
2518
2573
  }) : null,
2519
- index > 0 ? /* @__PURE__ */ jsx("button", {
2574
+ index > 0 && !field.readOnly ? /* @__PURE__ */ jsx("button", {
2520
2575
  type: "button",
2521
2576
  "data-formancy-part": "row-up",
2522
2577
  disabled: field.disabled,
2523
- onClick: () => repeater.moveRow(index, index - 1),
2578
+ onClick: () => {
2579
+ repeater.moveRow(index, index - 1);
2580
+ setFocusing({
2581
+ row: index - 1,
2582
+ parts: ["row-up", "row-down"]
2583
+ });
2584
+ },
2524
2585
  children: /* @__PURE__ */ jsx("span", {
2525
2586
  "data-formancy-part": "row-action-text",
2526
2587
  children: text("repeater.moveUp", {
@@ -2530,11 +2591,17 @@ function RepeaterSection({ wire, labels, registry }) {
2530
2591
  })
2531
2592
  })
2532
2593
  }) : null,
2533
- index < repeater.rowCount - 1 ? /* @__PURE__ */ jsx("button", {
2594
+ index < repeater.rowCount - 1 && !field.readOnly ? /* @__PURE__ */ jsx("button", {
2534
2595
  type: "button",
2535
2596
  "data-formancy-part": "row-down",
2536
2597
  disabled: field.disabled,
2537
- onClick: () => repeater.moveRow(index, index + 1),
2598
+ onClick: () => {
2599
+ repeater.moveRow(index, index + 1);
2600
+ setFocusing({
2601
+ row: index + 1,
2602
+ parts: ["row-down", "row-up"]
2603
+ });
2604
+ },
2538
2605
  children: /* @__PURE__ */ jsx("span", {
2539
2606
  "data-formancy-part": "row-action-text",
2540
2607
  children: text("repeater.moveDown", {
@@ -2567,6 +2634,7 @@ function RepeaterSection({ wire, labels, registry }) {
2567
2634
  if (!field.visible) return null;
2568
2635
  const showError = field.touched && field.errors.length > 0;
2569
2636
  return /* @__PURE__ */ jsxs("fieldset", {
2637
+ ref: fieldset,
2570
2638
  "data-formancy-part": "repeater",
2571
2639
  "data-formancy-field-path": wire,
2572
2640
  "data-state": showError ? "invalid" : "valid",
@@ -2593,37 +2661,27 @@ function RepeaterSection({ wire, labels, registry }) {
2593
2661
  }) : null, rows]
2594
2662
  }) : rows,
2595
2663
  showError ? /* @__PURE__ */ jsx(ErrorText, { field }) : null,
2664
+ def?.maxItems === void 0 || field.readOnly ? null : /* @__PURE__ */ jsx("p", {
2665
+ role: "status",
2666
+ "data-formancy-part": "repeater-status",
2667
+ children: repeater.canAdd ? "" : text("repeater.full", { max: def.maxItems })
2668
+ }),
2596
2669
  repeater.canAdd ? /* @__PURE__ */ jsx("button", {
2597
2670
  type: "button",
2671
+ ref: addButton,
2598
2672
  disabled: field.disabled,
2599
- onClick: () => repeater.addRow(),
2673
+ onClick: () => {
2674
+ repeater.addRow();
2675
+ setFocusing({
2676
+ row: repeater.rowCount,
2677
+ parts: []
2678
+ });
2679
+ },
2600
2680
  children: addLabel
2601
2681
  }) : null
2602
2682
  ]
2603
2683
  });
2604
2684
  }
2605
- const DEFAULT_COMPONENTS = {
2606
- text: TextField,
2607
- textarea: TextareaField,
2608
- number: NumberSwitch,
2609
- checkbox: CheckboxField,
2610
- date: DateField,
2611
- time: TimeField,
2612
- datetime: DateTimeField,
2613
- select: SelectField,
2614
- radio: RadioGroupField,
2615
- selectboxes: SelectBoxesSwitch,
2616
- ranking: RankingField,
2617
- matrix: MatrixField,
2618
- file: FileField,
2619
- richtext: RichTextField,
2620
- signature: SignatureField,
2621
- hidden: null,
2622
- static: StaticField,
2623
- group: null,
2624
- page: null,
2625
- repeater: null
2626
- };
2627
2685
  //#endregion
2628
2686
  //#region src/error-summary.tsx
2629
2687
  function ErrorSummary({ labels }) {