@formancy/react 0.11.0 → 0.12.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.
package/dist/index.d.mts CHANGED
@@ -27,8 +27,8 @@ export declare function useFormText(): FormText$1;
27
27
  //#endregion
28
28
  //#region src/use-field.d.ts
29
29
  interface FieldBinding extends FieldSnapshot {
30
- setValue(value: unknown): void;
31
- touch(): void;
30
+ setValue(this: void, value: unknown): void;
31
+ touch(this: void): void;
32
32
  /** Spread onto the input/select/textarea element. */
33
33
  controlProps: ControlProps;
34
34
  /** Spread onto the label element. */
@@ -395,7 +395,7 @@ interface UploadOptions {
395
395
  /** Aborted when the person cancels this file. Hand it to `fetch` and the transfer stops. */
396
396
  signal: AbortSignal;
397
397
  /** Bytes sent so far, of how many. `fetch` cannot report an upload's progress; XHR can. */
398
- onProgress(sent: number, total: number): void;
398
+ onProgress(this: void, sent: number, total: number): void;
399
399
  }
400
400
  /**
401
401
  * Uploads one file and reports what was stored.
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;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"}
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,YAAY;EACrB,MAAM;;EAEN,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;;;;;;;;;;;;;;;;UCWhB;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;;;;;;;;;;;;;;;;;;;;;;;;;wBCxBP,aAAa,OAAO,oCAAiB,IAAA;;;UClCpC;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,YAAY,cAAc;;;;;;;;;;;;KAa3B,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
@@ -337,7 +337,7 @@ function CodeNode({ schema, node, locale }) {
337
337
  const label = resolveText(schema, node.label, locale);
338
338
  const labelId = useId();
339
339
  const value = useField(node.path).value;
340
- const text = typeof value === "string" ? value : value === null || value === void 0 ? "" : String(value);
340
+ const text = typeof value === "string" ? value : typeof value === "number" || typeof value === "boolean" ? String(value) : "";
341
341
  return /* @__PURE__ */ jsxs("div", {
342
342
  "data-formancy-part": "code",
343
343
  "data-state": text === "" ? "empty" : "ready",
@@ -378,11 +378,6 @@ function CodeDrawing({ value }) {
378
378
  children: modules
379
379
  });
380
380
  }
381
- function placedPaths(nodes, into = []) {
382
- for (const node of nodes) if (node.kind === "field") into.push(node.path);
383
- else placedPaths(layoutChildren(node), into);
384
- return into;
385
- }
386
381
  //#endregion
387
382
  //#region src/focus-row.ts
388
383
  function focusRow(repeater, target, add) {
@@ -427,12 +422,12 @@ function useReview(goTo) {
427
422
  const goToField = useGoToField();
428
423
  return {
429
424
  reviewing,
430
- check() {
425
+ check: () => {
431
426
  if (submit().ok) return setReviewing(true);
432
427
  const firstInvalid = engine.firstInvalid();
433
428
  if (firstInvalid !== null) goTo?.(engine.pageOf(parsePath(firstInvalid)));
434
429
  },
435
- change(answer) {
430
+ change: (answer) => {
436
431
  setReviewing(false);
437
432
  goToField(answer.field);
438
433
  }
@@ -498,48 +493,103 @@ function Review({ onChange, children }) {
498
493
  });
499
494
  }
500
495
  //#endregion
501
- //#region src/rich-text.tsx
502
- function RichText({ source }) {
503
- const blocks = parseRichText(source);
504
- if (blocks.length === 0) return null;
505
- return /* @__PURE__ */ jsx("div", {
506
- "data-formancy-part": "richtext",
507
- children: blocks.map((block, index) => /* @__PURE__ */ jsx(Block, { block }, index))
496
+ //#region src/fields/internals.tsx
497
+ function ErrorText({ field }) {
498
+ const text = useFormText();
499
+ return /* @__PURE__ */ jsx("p", {
500
+ "data-formancy-part": "error",
501
+ ...field.errorProps,
502
+ children: field.errors.map((code, index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 ? " " : null, /* @__PURE__ */ jsx("span", {
503
+ "data-formancy-code": code,
504
+ children: errorSentence(text, field.def, code, field.messages)
505
+ })] }, code))
508
506
  });
509
507
  }
510
- function Block({ block }) {
511
- if (block.kind === "paragraph") return /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(Inlines, { nodes: block.children }) });
512
- const items = block.items.map((item, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Inlines, { nodes: item }) }, index));
513
- return block.ordered ? /* @__PURE__ */ jsx("ol", { children: items }) : /* @__PURE__ */ jsx("ul", { children: items });
508
+ function FieldShell({ path, field, label, children }) {
509
+ return /* @__PURE__ */ jsxs("div", {
510
+ "data-formancy-part": "field",
511
+ "data-formancy-field-path": path,
512
+ "data-state": field.touched && field.errors.length > 0 ? "invalid" : "valid",
513
+ children: [
514
+ /* @__PURE__ */ jsx("label", {
515
+ "data-formancy-part": "label",
516
+ ...field.labelProps,
517
+ children: label
518
+ }),
519
+ /* @__PURE__ */ jsx(Description, { field }),
520
+ children,
521
+ field.touched && field.errors.length > 0 ? /* @__PURE__ */ jsx(ErrorText, { field }) : null
522
+ ]
523
+ });
514
524
  }
515
- function Inlines({ nodes }) {
516
- return /* @__PURE__ */ jsx(Fragment$1, { children: nodes.map((node, index) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Inline, { node }) }, index)) });
525
+ function statusState({ sourced, said, open, matches }) {
526
+ if (sourced.remote === null) return open && matches === 0 ? "empty" : void 0;
527
+ if (sourced.remote.busy) return "busy";
528
+ if (sourced.remote.failed) return "failed";
529
+ if (said !== "") return "hint";
530
+ return open && matches === 0 ? "empty" : void 0;
517
531
  }
518
- function Inline({ node }) {
519
- switch (node.kind) {
520
- case "text": return /* @__PURE__ */ jsx(Fragment$1, { children: node.text });
521
- case "strong": return /* @__PURE__ */ jsx("strong", { children: /* @__PURE__ */ jsx(Inlines, { nodes: node.children }) });
522
- case "emphasis": return /* @__PURE__ */ jsx("em", { children: /* @__PURE__ */ jsx(Inlines, { nodes: node.children }) });
523
- case "link": return /* @__PURE__ */ jsx("a", {
524
- href: node.href,
525
- rel: "noreferrer noopener nofollow ugc",
526
- children: /* @__PURE__ */ jsx(Inlines, { nodes: node.children })
527
- });
528
- }
532
+ function RequiredHint({ field }) {
533
+ const text = useFormText();
534
+ if (!field.required) return null;
535
+ return /* @__PURE__ */ jsx("span", {
536
+ "data-formancy-part": "required-hint",
537
+ id: field.props.hint.id,
538
+ children: text("form.required")
539
+ });
529
540
  }
530
- //#endregion
531
- //#region src/rich-text-editor.ts
532
- const RichTextEditorContext = createContext(void 0);
533
- const RichTextEditorProvider = RichTextEditorContext.Provider;
534
- function useRichTextEditorFactory() {
535
- return useContext(RichTextEditorContext);
541
+ function Description({ field }) {
542
+ if (field.description === void 0) return null;
543
+ return /* @__PURE__ */ jsx("p", {
544
+ "data-formancy-part": "description",
545
+ id: field.props.description.id,
546
+ children: field.description
547
+ });
548
+ }
549
+ function usePlaceholder(field) {
550
+ return useFormEngine().text(field.def.placeholder);
551
+ }
552
+ function optionDomId(field, value) {
553
+ return `${field.ids.control}:option:${value}`;
554
+ }
555
+ function useResolvedOptions(field) {
556
+ const engine = useFormEngine();
557
+ return inOptionOrder((field.def.options ?? []).map((option) => ({
558
+ value: option.value,
559
+ label: engine.text(option.label) ?? option.value,
560
+ ...option.image !== void 0 && isImageSource(option.image.src) ? { image: {
561
+ src: option.image.src,
562
+ alt: engine.text(option.image.alt) ?? ""
563
+ } } : {}
564
+ })), field.optionOrder);
565
+ }
566
+ function OptionPicture({ option }) {
567
+ if (option.image === void 0) return null;
568
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("img", {
569
+ "data-formancy-part": "option-image",
570
+ src: option.image.src,
571
+ alt: option.image.alt,
572
+ loading: "lazy",
573
+ decoding: "async"
574
+ }), " "] });
536
575
  }
537
576
  //#endregion
538
- //#region src/scanning.ts
539
- const ScannerContext = createContext(void 0);
540
- const ScannerProvider = ScannerContext.Provider;
541
- function useScanner() {
542
- return useContext(ScannerContext);
577
+ //#region src/fields/computed-answer.tsx
578
+ function ComputedAnswerField({ path, label }) {
579
+ const field = useField(path);
580
+ const engine = useFormEngine();
581
+ const text = useFormText();
582
+ return /* @__PURE__ */ jsx(FieldShell, {
583
+ path,
584
+ field,
585
+ label,
586
+ children: /* @__PURE__ */ jsx("input", {
587
+ type: "text",
588
+ readOnly: true,
589
+ ...field.controlProps,
590
+ value: answerInWords(engine.schema(), field.def, field.value, text, engine.locale())
591
+ })
592
+ });
543
593
  }
544
594
  //#endregion
545
595
  //#region src/options-source.ts
@@ -703,112 +753,6 @@ function storedValues(value) {
703
753
  return value.filter((item) => typeof item === "string" && item !== "");
704
754
  }
705
755
  //#endregion
706
- //#region src/uploads.ts
707
- const UploaderContext = createContext(void 0);
708
- const UploaderProvider = UploaderContext.Provider;
709
- function useUploader() {
710
- return useContext(UploaderContext);
711
- }
712
- //#endregion
713
- //#region src/fields/internals.tsx
714
- function ErrorText({ field }) {
715
- const text = useFormText();
716
- return /* @__PURE__ */ jsx("p", {
717
- "data-formancy-part": "error",
718
- ...field.errorProps,
719
- children: field.errors.map((code, index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 ? " " : null, /* @__PURE__ */ jsx("span", {
720
- "data-formancy-code": code,
721
- children: errorSentence(text, field.def, code, field.messages)
722
- })] }, code))
723
- });
724
- }
725
- function FieldShell({ path, field, label, children }) {
726
- return /* @__PURE__ */ jsxs("div", {
727
- "data-formancy-part": "field",
728
- "data-formancy-field-path": path,
729
- "data-state": field.touched && field.errors.length > 0 ? "invalid" : "valid",
730
- children: [
731
- /* @__PURE__ */ jsx("label", {
732
- "data-formancy-part": "label",
733
- ...field.labelProps,
734
- children: label
735
- }),
736
- /* @__PURE__ */ jsx(Description, { field }),
737
- children,
738
- field.touched && field.errors.length > 0 ? /* @__PURE__ */ jsx(ErrorText, { field }) : null
739
- ]
740
- });
741
- }
742
- function statusState({ sourced, said, open, matches }) {
743
- if (sourced.remote === null) return open && matches === 0 ? "empty" : void 0;
744
- if (sourced.remote.busy) return "busy";
745
- if (sourced.remote.failed) return "failed";
746
- if (said !== "") return "hint";
747
- return open && matches === 0 ? "empty" : void 0;
748
- }
749
- function RequiredHint({ field }) {
750
- const text = useFormText();
751
- if (!field.required) return null;
752
- return /* @__PURE__ */ jsx("span", {
753
- "data-formancy-part": "required-hint",
754
- id: field.props.hint.id,
755
- children: text("form.required")
756
- });
757
- }
758
- function Description({ field }) {
759
- if (field.description === void 0) return null;
760
- return /* @__PURE__ */ jsx("p", {
761
- "data-formancy-part": "description",
762
- id: field.props.description.id,
763
- children: field.description
764
- });
765
- }
766
- function usePlaceholder(field) {
767
- return useFormEngine().text(field.def.placeholder);
768
- }
769
- function optionDomId(field, value) {
770
- return `${field.ids.control}:option:${value}`;
771
- }
772
- function useResolvedOptions(field) {
773
- const engine = useFormEngine();
774
- return inOptionOrder((field.def.options ?? []).map((option) => ({
775
- value: option.value,
776
- label: engine.text(option.label) ?? option.value,
777
- ...option.image !== void 0 && isImageSource(option.image.src) ? { image: {
778
- src: option.image.src,
779
- alt: engine.text(option.image.alt) ?? ""
780
- } } : {}
781
- })), field.optionOrder);
782
- }
783
- function OptionPicture({ option }) {
784
- if (option.image === void 0) return null;
785
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("img", {
786
- "data-formancy-part": "option-image",
787
- src: option.image.src,
788
- alt: option.image.alt,
789
- loading: "lazy",
790
- decoding: "async"
791
- }), " "] });
792
- }
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
812
756
  //#region src/fields/typeahead-field.tsx
813
757
  function TypeaheadSelectField({ path, label, field }) {
814
758
  const text = useFormText();
@@ -837,6 +781,10 @@ function TypeaheadSelectField({ path, label, field }) {
837
781
  const activeIndex = matches.findIndex((option) => option.value === activeValue);
838
782
  const activeId = expanded && activeIndex !== -1 ? optionDomId(field, matches[activeIndex].value) : void 0;
839
783
  const listboxId = `${field.ids.control}:listbox`;
784
+ const listbox = useRef(null);
785
+ useEffect(() => {
786
+ if (expanded && activeIndex !== -1) listbox.current?.children[activeIndex]?.scrollIntoView?.({ block: "nearest" });
787
+ }, [expanded, activeIndex]);
840
788
  const choose = (value) => {
841
789
  field.setValue(value);
842
790
  setQuery(null);
@@ -920,6 +868,7 @@ function TypeaheadSelectField({ path, label, field }) {
920
868
  onKeyDown,
921
869
  onBlur
922
870
  }), /* @__PURE__ */ jsx("ul", {
871
+ ref: listbox,
923
872
  id: listboxId,
924
873
  role: "listbox",
925
874
  "aria-label": text("options.suggestions", { label }),
@@ -1072,6 +1021,13 @@ function RadioGroupField({ path, label }) {
1072
1021
  });
1073
1022
  }
1074
1023
  //#endregion
1024
+ //#region src/uploads.ts
1025
+ const UploaderContext = createContext(void 0);
1026
+ const UploaderProvider = UploaderContext.Provider;
1027
+ function useUploader() {
1028
+ return useContext(UploaderContext);
1029
+ }
1030
+ //#endregion
1075
1031
  //#region src/fields/file-field.tsx
1076
1032
  function FileField({ path, label }) {
1077
1033
  const field = useField(path);
@@ -1315,6 +1271,43 @@ function FileThumbnail({ source }) {
1315
1271
  });
1316
1272
  }
1317
1273
  //#endregion
1274
+ //#region src/rich-text.tsx
1275
+ function RichText({ source }) {
1276
+ const blocks = parseRichText(source);
1277
+ if (blocks.length === 0) return null;
1278
+ return /* @__PURE__ */ jsx("div", {
1279
+ "data-formancy-part": "richtext",
1280
+ children: blocks.map((block, index) => /* @__PURE__ */ jsx(Block, { block }, index))
1281
+ });
1282
+ }
1283
+ function Block({ block }) {
1284
+ if (block.kind === "paragraph") return /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(Inlines, { nodes: block.children }) });
1285
+ const items = block.items.map((item, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Inlines, { nodes: item }) }, index));
1286
+ return block.ordered ? /* @__PURE__ */ jsx("ol", { children: items }) : /* @__PURE__ */ jsx("ul", { children: items });
1287
+ }
1288
+ function Inlines({ nodes }) {
1289
+ return /* @__PURE__ */ jsx(Fragment$1, { children: nodes.map((node, index) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Inline, { node }) }, index)) });
1290
+ }
1291
+ function Inline({ node }) {
1292
+ switch (node.kind) {
1293
+ case "text": return /* @__PURE__ */ jsx(Fragment$1, { children: node.text });
1294
+ case "strong": return /* @__PURE__ */ jsx("strong", { children: /* @__PURE__ */ jsx(Inlines, { nodes: node.children }) });
1295
+ case "emphasis": return /* @__PURE__ */ jsx("em", { children: /* @__PURE__ */ jsx(Inlines, { nodes: node.children }) });
1296
+ case "link": return /* @__PURE__ */ jsx("a", {
1297
+ href: node.href,
1298
+ rel: "noreferrer noopener nofollow ugc",
1299
+ children: /* @__PURE__ */ jsx(Inlines, { nodes: node.children })
1300
+ });
1301
+ }
1302
+ }
1303
+ //#endregion
1304
+ //#region src/rich-text-editor.ts
1305
+ const RichTextEditorContext = createContext(void 0);
1306
+ const RichTextEditorProvider = RichTextEditorContext.Provider;
1307
+ function useRichTextEditorFactory() {
1308
+ return useContext(RichTextEditorContext);
1309
+ }
1310
+ //#endregion
1318
1311
  //#region src/fields/rich-text-field.tsx
1319
1312
  function RichTextToolbar({ disabled, label, onCommand }) {
1320
1313
  const buttons = useRef([]);
@@ -2227,6 +2220,13 @@ function CharacterCount({ field }) {
2227
2220
  })] });
2228
2221
  }
2229
2222
  //#endregion
2223
+ //#region src/scanning.ts
2224
+ const ScannerContext = createContext(void 0);
2225
+ const ScannerProvider = ScannerContext.Provider;
2226
+ function useScanner() {
2227
+ return useContext(ScannerContext);
2228
+ }
2229
+ //#endregion
2230
2230
  //#region src/fields/text-fields.tsx
2231
2231
  function TextField({ path, label }) {
2232
2232
  const field = useField(path);
@@ -2431,34 +2431,31 @@ function FieldList({ labels, registry, page, layout }) {
2431
2431
  const repeaterWires = engine.repeaterPaths();
2432
2432
  const schema = engine.schema();
2433
2433
  const arrangement = schema.layouts?.find((candidate) => candidate.name === layout);
2434
- if (layout !== void 0 && arrangement !== void 0) {
2435
- new Set(placedPaths(arrangement.nodes));
2436
- return /* @__PURE__ */ jsx(LayoutTree, {
2437
- schema,
2438
- nodes: arrangement.nodes,
2439
- locale: engine.locale(),
2440
- shows: page === void 0 ? void 0 : (path) => placedPage(engine, path) === page,
2441
- renderField: (path) => {
2442
- if (repeaterWires.includes(path)) return /* @__PURE__ */ jsx(RepeaterSection, {
2443
- wire: path,
2444
- labels,
2445
- registry
2446
- }, path);
2447
- const group = placedGroup(engine, path);
2448
- if (group !== void 0) return /* @__PURE__ */ jsx(GroupSection, {
2449
- path,
2450
- group,
2451
- labels,
2452
- registry
2453
- }, path);
2454
- return /* @__PURE__ */ jsx(FieldSlot, {
2455
- path,
2456
- fallbackLabel: labels?.[path],
2457
- registry
2458
- }, path);
2459
- }
2460
- });
2461
- }
2434
+ if (layout !== void 0 && arrangement !== void 0) return /* @__PURE__ */ jsx(LayoutTree, {
2435
+ schema,
2436
+ nodes: arrangement.nodes,
2437
+ locale: engine.locale(),
2438
+ shows: page === void 0 ? void 0 : (path) => placedPage(engine, path) === page,
2439
+ renderField: (path) => {
2440
+ if (repeaterWires.includes(path)) return /* @__PURE__ */ jsx(RepeaterSection, {
2441
+ wire: path,
2442
+ labels,
2443
+ registry
2444
+ }, path);
2445
+ const group = placedGroup(engine, path);
2446
+ if (group !== void 0) return /* @__PURE__ */ jsx(GroupSection, {
2447
+ path,
2448
+ group,
2449
+ labels,
2450
+ registry
2451
+ }, path);
2452
+ return /* @__PURE__ */ jsx(FieldSlot, {
2453
+ path,
2454
+ fallbackLabel: labels?.[path],
2455
+ registry
2456
+ }, path);
2457
+ }
2458
+ });
2462
2459
  const inPage = (wire) => page === void 0 || engine.pageOf(parsePath(wire)) === page;
2463
2460
  const staticWires = engine.fieldPaths().filter((wire) => !repeaterWires.some((repeater) => wire.startsWith(`${repeater}[`)));
2464
2461
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [staticWires.filter(inPage).map((wire) => /* @__PURE__ */ jsx(FieldSlot, {