@nxgt/material 2.18.1 → 2.20.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 (115) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/README.md +1 -0
  3. package/dist/{_Uint8Array-C7apDrb7.js → _Uint8Array-DGVY6NfN.js} +1 -1
  4. package/dist/{_overRest-CCAbV-eT.js → _overRest-DCKNcrF0.js} +1 -1
  5. package/dist/{async-slice-Cuekts5f.js → async-slice-DAVXvBm1.js} +3 -3
  6. package/dist/{blockDiagram-BEXU5L5S-iNiTd2F6.js → blockDiagram-BEXU5L5S-BrCVxVRd.js} +2 -2
  7. package/dist/{chunk-3FUC2YCW-C3_88DyD.js → chunk-3FUC2YCW-DWaNSANO.js} +2 -2
  8. package/dist/{chunk-7M6MHVWA-DSA5AJyK.js → chunk-7M6MHVWA-x-N4hnls.js} +1 -1
  9. package/dist/{chunk-GNY47TPC-AFxr6Xhs.js → chunk-GNY47TPC-Dzk3o85s.js} +4 -4
  10. package/dist/{chunk-NETBCI7D-DUZYHta0.js → chunk-NETBCI7D-WvAAUJne.js} +1 -1
  11. package/dist/{chunk-Z7XXMR3K-DDFBvLN4.js → chunk-Z7XXMR3K-DY6U0Uq4.js} +1 -1
  12. package/dist/{classDiagram-v2-NBCMYWYE-Cx1q9jwX.js → classDiagram-v2-NBCMYWYE-QeFmLU9L.js} +2 -2
  13. package/dist/components/base-content.css +64 -4
  14. package/dist/components/base.css +3 -1
  15. package/dist/{components-CEXxj5QP.js → components-DH5dpaU8.js} +24401 -23964
  16. package/dist/components.js +6 -6
  17. package/dist/{dagre-6A5THRUB-B3FAoh2m.js → dagre-6A5THRUB-D-NdHe_L.js} +11 -11
  18. package/dist/{diagram-22UHCM2B-B1mxqDwI.js → diagram-22UHCM2B-DZ4jejn3.js} +2 -2
  19. package/dist/{diagram-3UASUU5V-DKbBxWI5.js → diagram-3UASUU5V-DRoFk6qc.js} +1 -1
  20. package/dist/dnd.js +1 -1
  21. package/dist/{elk-276RUBZZ-CeiRDj87.js → elk-276RUBZZ-BG0kHR2f.js} +3 -3
  22. package/dist/{erDiagram-OPXOYQCR-nyCpuYg6.js → erDiagram-OPXOYQCR-B6XRmJuU.js} +2 -2
  23. package/dist/{field-blur-DNHXOY0J.js → field-blur-B1VUvTws.js} +972 -946
  24. package/dist/{flowDiagram-KWPJA3E3-CAt7iv16.js → flowDiagram-KWPJA3E3-BghxpN0G.js} +3 -3
  25. package/dist/{ganttDiagram-FUAMR5RP-g4YEKVC-.js → ganttDiagram-FUAMR5RP-C3aoaoXQ.js} +1 -1
  26. package/dist/{graphlib-DxjKaXeR.js → graphlib-Dc5Siwxn.js} +6 -6
  27. package/dist/hooks.js +2 -2
  28. package/dist/{i18n-provider-Dv9ZSmgO.js → i18n-provider-Cq_VScPv.js} +1 -1
  29. package/dist/i18n.js +6 -6
  30. package/dist/{isArrayLikeObject-H8k6W51O.js → isArrayLikeObject-DeHDPOEB.js} +3 -3
  31. package/dist/{isEmpty-B0Bavg-e.js → isEmpty-Sic-RRp7.js} +3 -3
  32. package/dist/{journeyDiagram-ZHPQQLJL-v7NsJ_vl.js → journeyDiagram-ZHPQQLJL-DcUX0asi.js} +1 -1
  33. package/dist/lib/components/ui/collections/data-table/data-table-density.d.ts +15 -0
  34. package/dist/lib/components/ui/collections/data-table/data-table.d.ts +1 -1
  35. package/dist/lib/components/ui/collections/data-table/types.d.ts +7 -0
  36. package/dist/lib/components/ui/fields/index.d.ts +1 -0
  37. package/dist/lib/components/ui/fields/repeatable-group/index.d.ts +2 -0
  38. package/dist/lib/components/ui/fields/repeatable-group/partials/repeatable-group-footer.d.ts +14 -0
  39. package/dist/lib/components/ui/fields/repeatable-group/partials/repeatable-group-row.d.ts +19 -0
  40. package/dist/lib/components/ui/fields/repeatable-group/partials/repeatable-group-rows.d.ts +21 -0
  41. package/dist/lib/components/ui/fields/repeatable-group/partials/repeatable-group-status.d.ts +11 -0
  42. package/dist/lib/components/ui/fields/repeatable-group/repeatable-group-classes.d.ts +33 -0
  43. package/dist/lib/components/ui/fields/repeatable-group/repeatable-group-form-field.d.ts +28 -0
  44. package/dist/lib/components/ui/fields/repeatable-group/repeatable-group-names.d.ts +16 -0
  45. package/dist/lib/components/ui/fields/repeatable-group/repeatable-group.d.ts +12 -0
  46. package/dist/lib/components/ui/fields/repeatable-group/types.d.ts +45 -0
  47. package/dist/lib/components/ui/fields/repeatable-group/use-repeatable-group.d.ts +32 -0
  48. package/dist/lib/components/ui/fields/search-field/search-field.d.ts +7 -1
  49. package/dist/lib/components/ui/overlays/command/command-item.d.ts +10 -0
  50. package/dist/lib/components/ui/overlays/command/command.d.ts +5 -2
  51. package/dist/lib/components/ui/overlays/dialog/dialog-outside.d.ts +4 -2
  52. package/dist/lib/components/ui/overlays/dialog/dialog-parts.d.ts +7 -0
  53. package/dist/lib/components/ui/overlays/dialog/dialog.d.ts +2 -5
  54. package/dist/lib/components/ui/overlays/dialog/in-dialog.d.ts +13 -0
  55. package/dist/lib/components/ui/overlays/menubar/menubar-items.d.ts +18 -0
  56. package/dist/lib/components/ui/overlays/menubar/menubar-sub.d.ts +8 -0
  57. package/dist/lib/components/ui/overlays/menubar/menubar.d.ts +3 -21
  58. package/dist/lib/components/ui/overlays/sheet/sheet-parts.d.ts +7 -0
  59. package/dist/lib/components/ui/overlays/sheet/sheet.d.ts +2 -5
  60. package/dist/lib/components/ui/primitives/typography/typography.d.ts +2 -1
  61. package/dist/lib/components/ui/selection/autocomplete/partials/autocomplete-chips.d.ts +2 -0
  62. package/dist/lib/components/ui/selection/autocomplete/partials/autocomplete-popup.d.ts +2 -1
  63. package/dist/lib/components/ui/selection/checkbox-group/checkbox-group.d.ts +2 -0
  64. package/dist/lib/components/ui/selection/combobox/combobox-content.d.ts +14 -0
  65. package/dist/lib/components/ui/selection/combobox/combobox.d.ts +1 -4
  66. package/dist/lib/components/ui/selection/option-count/option-count.d.ts +18 -0
  67. package/dist/lib/components/ui/selection/radio-group/radio-group.d.ts +2 -0
  68. package/dist/lib/components/ui/selection/select-chip-field/next-selection.d.ts +10 -0
  69. package/dist/lib/components/ui/selection/select-chip-field/select-chip-field.d.ts +8 -1
  70. package/dist/lib/components/ui/selection/select-chip-field/select-chip-header.d.ts +15 -0
  71. package/dist/lib/components/ui/selection/select-chip-field/select-chip-option.d.ts +13 -0
  72. package/dist/lib/i18n/resources/en/en.d.ts +15 -0
  73. package/dist/lib/i18n/resources/en/material.json.d.ts +15 -0
  74. package/dist/lib/i18n/resources/fr/fr.d.ts +15 -0
  75. package/dist/lib/i18n/resources/fr/material.json.d.ts +15 -0
  76. package/dist/lib/i18n/resources/resources.d.ts +30 -0
  77. package/dist/lib/i18n/translator.d.ts +1 -1
  78. package/dist/lib.js +2 -2
  79. package/dist/main.js +16 -16
  80. package/dist/map.js +8 -8
  81. package/dist/material.css +1 -1
  82. package/dist/{merge-Js8537dg.js → merge-VyOzRzYB.js} +4 -4
  83. package/dist/{mermaid.core-BHmjz3IJ.js → mermaid.core-DLu6PrQ9.js} +21 -21
  84. package/dist/{mindmap-definition-NLK3R4M7-xOeGZSSo.js → mindmap-definition-NLK3R4M7-B7Y8Yx12.js} +2 -2
  85. package/dist/{pieDiagram-5QR66LMP-5nOKLXqH.js → pieDiagram-5QR66LMP-Bv9VMy5P.js} +1 -1
  86. package/dist/print.js +2 -2
  87. package/dist/{quadrantDiagram-O4NWA36T-B0RNQlBB.js → quadrantDiagram-O4NWA36T-Dr2CLVD8.js} +1 -1
  88. package/dist/{requirementDiagram-PLB6GJNP-Cw85zSzP.js → requirementDiagram-PLB6GJNP-XuNWo4K8.js} +2 -2
  89. package/dist/{sankeyDiagram-IPEJSGJF-APZoNvA9.js → sankeyDiagram-IPEJSGJF-DzXzUNs5.js} +1 -1
  90. package/dist/{sortable-provider-CUT5Wfdl.js → sortable-provider-XneXCqY1.js} +1 -1
  91. package/dist/{stateDiagram-v2-GCMORJYK-CfSjJkc3.js → stateDiagram-v2-GCMORJYK-BN2OBfZa.js} +2 -2
  92. package/dist/{stored-language-BKoohv2_.js → stored-language-DqlfjXt8.js} +26 -0
  93. package/dist/{swimlanes-2SLR337P-Bv2VKn_d.js → swimlanes-2SLR337P-Ma7iLhhV.js} +3 -3
  94. package/dist/{swimlanesDiagram-TC7HE7FX-Jk8do14f.js → swimlanesDiagram-TC7HE7FX-DWBnIppx.js} +3 -3
  95. package/dist/{timeline-definition-EJHVYXUP-Bc40K9sk.js → timeline-definition-EJHVYXUP-BBwvY1Xf.js} +1 -1
  96. package/dist/{translate-material-CCJg3yfc.js → translate-material-B6HO6ykL.js} +2 -2
  97. package/dist/{translator-DEde7BKz.js → translator-B_lmafJN.js} +1 -1
  98. package/dist/{use-heading-spy-XkSExwoT.js → use-heading-spy-D1Ifooi5.js} +2 -2
  99. package/dist/{use-material-translation-Cndoq_iK.js → use-material-translation-Bp4ECeT4.js} +2 -2
  100. package/dist/{usecaseDiagram-POWQR4AR-CKd5UWWw.js → usecaseDiagram-POWQR4AR-B1HduAbh.js} +2 -2
  101. package/dist/{xychartDiagram-PMCCYNJV-CQJbSV7N.js → xychartDiagram-PMCCYNJV-ByjPOY-5.js} +1 -1
  102. package/docs/components/README.md +1 -1
  103. package/docs/components/data-table-filter-and-lists.md +3 -1
  104. package/docs/components/form-fields.md +146 -0
  105. package/docs/components/overlays-and-menus.md +2 -0
  106. package/docs/components/primitives.md +3 -1
  107. package/docs/components/selection-and-choice.md +20 -4
  108. package/docs/guides/forms.md +84 -0
  109. package/docs/guides/i18n.md +2 -1
  110. package/docs/previews/form-fields-repeatablegroup.webp +0 -0
  111. package/docs/roadmap.md +7 -0
  112. package/docs/troubleshooting.md +69 -0
  113. package/lib/components/base-content.css +64 -4
  114. package/lib/components/base.css +3 -1
  115. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
- import { S as e, _ as t, g as n, p as r, v as i, w as a, x as o } from "./translator-DEde7BKz.js";
2
- import { n as s, r as c } from "./_overRest-CCAbV-eT.js";
3
- import { a as l, c as u, d, i as f, l as p, n as m, p as h, r as g, t as _, u as v } from "./_Uint8Array-C7apDrb7.js";
4
- import { n as y, r as b, t as x } from "./isArrayLikeObject-H8k6W51O.js";
1
+ import { S as e, _ as t, g as n, p as r, v as i, w as a, x as o } from "./translator-B_lmafJN.js";
2
+ import { n as s, r as c } from "./_overRest-DCKNcrF0.js";
3
+ import { a as l, c as u, d, i as f, l as p, n as m, p as h, r as g, t as _, u as v } from "./_Uint8Array-DGVY6NfN.js";
4
+ import { n as y, r as b, t as x } from "./isArrayLikeObject-DeHDPOEB.js";
5
5
  //#region ../../node_modules/lodash-es/_baseCreate.js
6
6
  var S = Object.create, C = function() {
7
7
  function e() {}
@@ -8,9 +8,9 @@ import { a as he } from "./chunk-MBY4JIJT-BFIqOe-8.js";
8
8
  import "./chunk-7PRAP22T-0C6_H8Li.js";
9
9
  import "./chunk-7INBJB4K-k-I67NSP.js";
10
10
  import "./chunk-5DYCD2WN-Cd1zazNp.js";
11
- import "./chunk-Z7XXMR3K-DDFBvLN4.js";
11
+ import "./chunk-Z7XXMR3K-DY6U0Uq4.js";
12
12
  import "./chunk-UA2S7LBM-ChuksCDg.js";
13
- import { n as ge } from "./chunk-GNY47TPC-AFxr6Xhs.js";
13
+ import { n as ge } from "./chunk-GNY47TPC-Dzk3o85s.js";
14
14
  import { n as _e, t as ve } from "./chunk-LNGE3PJU-DJjGTS7O.js";
15
15
  //#region ../../node_modules/es-toolkit/dist/compat/_internal/isPrototype.mjs
16
16
  function ye(e) {
@@ -302,7 +302,7 @@ var qe = "c4", Je = {
302
302
  id: Ye,
303
303
  detector: /* @__PURE__ */ p((e) => /^\s*(graph|flowchart)/.test(e), "detector"),
304
304
  loader: /* @__PURE__ */ p(async () => {
305
- let { diagram: e } = await import("./flowDiagram-KWPJA3E3-CAt7iv16.js");
305
+ let { diagram: e } = await import("./flowDiagram-KWPJA3E3-BghxpN0G.js");
306
306
  return {
307
307
  id: Ye,
308
308
  diagram: e
@@ -312,7 +312,7 @@ var qe = "c4", Je = {
312
312
  id: Ze,
313
313
  detector: /* @__PURE__ */ p((e) => /^\s*agentflow-beta\b/.test(e), "detector"),
314
314
  loader: /* @__PURE__ */ p(async () => {
315
- let { diagram: e } = await import("./diagram-22UHCM2B-B1mxqDwI.js");
315
+ let { diagram: e } = await import("./diagram-22UHCM2B-DZ4jejn3.js");
316
316
  return {
317
317
  id: Ze,
318
318
  diagram: e
@@ -322,7 +322,7 @@ var qe = "c4", Je = {
322
322
  id: $e,
323
323
  detector: /* @__PURE__ */ p((e) => /^\s*swimlane-beta\b/.test(e), "detector"),
324
324
  loader: /* @__PURE__ */ p(async () => {
325
- let { diagram: e } = await import("./swimlanesDiagram-TC7HE7FX-Jk8do14f.js");
325
+ let { diagram: e } = await import("./swimlanesDiagram-TC7HE7FX-DWBnIppx.js");
326
326
  return {
327
327
  id: $e,
328
328
  diagram: e
@@ -332,7 +332,7 @@ var qe = "c4", Je = {
332
332
  id: tt,
333
333
  detector: /* @__PURE__ */ p((e) => /^\s*erDiagram/.test(e), "detector"),
334
334
  loader: /* @__PURE__ */ p(async () => {
335
- let { diagram: e } = await import("./erDiagram-OPXOYQCR-nyCpuYg6.js");
335
+ let { diagram: e } = await import("./erDiagram-OPXOYQCR-B6XRmJuU.js");
336
336
  return {
337
337
  id: tt,
338
338
  diagram: e
@@ -352,7 +352,7 @@ var qe = "c4", Je = {
352
352
  id: at,
353
353
  detector: /* @__PURE__ */ p((e) => /^\s*gantt/.test(e), "detector"),
354
354
  loader: /* @__PURE__ */ p(async () => {
355
- let { diagram: e } = await import("./ganttDiagram-FUAMR5RP-g4YEKVC-.js");
355
+ let { diagram: e } = await import("./ganttDiagram-FUAMR5RP-C3aoaoXQ.js");
356
356
  return {
357
357
  id: at,
358
358
  diagram: e
@@ -372,7 +372,7 @@ var qe = "c4", Je = {
372
372
  id: lt,
373
373
  detector: /* @__PURE__ */ p((e) => /^\s*pie/.test(e), "detector"),
374
374
  loader: /* @__PURE__ */ p(async () => {
375
- let { diagram: e } = await import("./pieDiagram-5QR66LMP-5nOKLXqH.js");
375
+ let { diagram: e } = await import("./pieDiagram-5QR66LMP-Bv9VMy5P.js");
376
376
  return {
377
377
  id: lt,
378
378
  diagram: e
@@ -382,7 +382,7 @@ var qe = "c4", Je = {
382
382
  id: dt,
383
383
  detector: /* @__PURE__ */ p((e) => /^\s*quadrantChart/.test(e), "detector"),
384
384
  loader: /* @__PURE__ */ p(async () => {
385
- let { diagram: e } = await import("./quadrantDiagram-O4NWA36T-B0RNQlBB.js");
385
+ let { diagram: e } = await import("./quadrantDiagram-O4NWA36T-Dr2CLVD8.js");
386
386
  return {
387
387
  id: dt,
388
388
  diagram: e
@@ -392,7 +392,7 @@ var qe = "c4", Je = {
392
392
  id: pt,
393
393
  detector: /* @__PURE__ */ p((e) => /^\s*xychart(-beta)?/.test(e), "detector"),
394
394
  loader: /* @__PURE__ */ p(async () => {
395
- let { diagram: e } = await import("./xychartDiagram-PMCCYNJV-CQJbSV7N.js");
395
+ let { diagram: e } = await import("./xychartDiagram-PMCCYNJV-ByjPOY-5.js");
396
396
  return {
397
397
  id: pt,
398
398
  diagram: e
@@ -402,7 +402,7 @@ var qe = "c4", Je = {
402
402
  id: ht,
403
403
  detector: /* @__PURE__ */ p((e) => /^\s*requirement(Diagram)?/.test(e), "detector"),
404
404
  loader: /* @__PURE__ */ p(async () => {
405
- let { diagram: e } = await import("./requirementDiagram-PLB6GJNP-Cw85zSzP.js");
405
+ let { diagram: e } = await import("./requirementDiagram-PLB6GJNP-XuNWo4K8.js");
406
406
  return {
407
407
  id: ht,
408
408
  diagram: e
@@ -422,7 +422,7 @@ var qe = "c4", Je = {
422
422
  id: yt,
423
423
  detector: /* @__PURE__ */ p((e) => /^\s*classDiagram/.test(e), "detector"),
424
424
  loader: /* @__PURE__ */ p(async () => {
425
- let { diagram: e } = await import("./classDiagram-v2-NBCMYWYE-Cx1q9jwX.js");
425
+ let { diagram: e } = await import("./classDiagram-v2-NBCMYWYE-QeFmLU9L.js");
426
426
  return {
427
427
  id: yt,
428
428
  diagram: e
@@ -432,7 +432,7 @@ var qe = "c4", Je = {
432
432
  id: xt,
433
433
  detector: /* @__PURE__ */ p((e) => /^\s*stateDiagram/.test(e), "detector"),
434
434
  loader: /* @__PURE__ */ p(async () => {
435
- let { diagram: e } = await import("./stateDiagram-v2-GCMORJYK-CfSjJkc3.js");
435
+ let { diagram: e } = await import("./stateDiagram-v2-GCMORJYK-BN2OBfZa.js");
436
436
  return {
437
437
  id: xt,
438
438
  diagram: e
@@ -442,7 +442,7 @@ var qe = "c4", Je = {
442
442
  id: Ct,
443
443
  detector: /* @__PURE__ */ p((e) => /^\s*journey/.test(e), "detector"),
444
444
  loader: /* @__PURE__ */ p(async () => {
445
- let { diagram: e } = await import("./journeyDiagram-ZHPQQLJL-v7NsJ_vl.js");
445
+ let { diagram: e } = await import("./journeyDiagram-ZHPQQLJL-DcUX0asi.js");
446
446
  return {
447
447
  id: Ct,
448
448
  diagram: e
@@ -460,7 +460,7 @@ var qe = "c4", Je = {
460
460
  id: Ot,
461
461
  detector: /* @__PURE__ */ p((e, t = {}) => /^\s*flowchart-elk/.test(e) ? (t.layout = "elk", !0) : !1, "detector"),
462
462
  loader: /* @__PURE__ */ p(async () => {
463
- let { diagram: e } = await import("./flowDiagram-KWPJA3E3-CAt7iv16.js");
463
+ let { diagram: e } = await import("./flowDiagram-KWPJA3E3-BghxpN0G.js");
464
464
  return {
465
465
  id: Ot,
466
466
  diagram: e
@@ -470,7 +470,7 @@ var qe = "c4", Je = {
470
470
  id: At,
471
471
  detector: /* @__PURE__ */ p((e) => /^\s*timeline/.test(e), "detector"),
472
472
  loader: /* @__PURE__ */ p(async () => {
473
- let { diagram: e } = await import("./timeline-definition-EJHVYXUP-Bc40K9sk.js");
473
+ let { diagram: e } = await import("./timeline-definition-EJHVYXUP-BBwvY1Xf.js");
474
474
  return {
475
475
  id: At,
476
476
  diagram: e
@@ -480,7 +480,7 @@ var qe = "c4", Je = {
480
480
  id: Mt,
481
481
  detector: /* @__PURE__ */ p((e) => /^\s*mindmap/.test(e), "detector"),
482
482
  loader: /* @__PURE__ */ p(async () => {
483
- let { diagram: e } = await import("./mindmap-definition-NLK3R4M7-xOeGZSSo.js");
483
+ let { diagram: e } = await import("./mindmap-definition-NLK3R4M7-B7Y8Yx12.js");
484
484
  return {
485
485
  id: Mt,
486
486
  diagram: e
@@ -500,7 +500,7 @@ var qe = "c4", Je = {
500
500
  id: It,
501
501
  detector: /* @__PURE__ */ p((e) => /^\s*sankey(-beta)?/.test(e), "detector"),
502
502
  loader: /* @__PURE__ */ p(async () => {
503
- let { diagram: e } = await import("./sankeyDiagram-IPEJSGJF-APZoNvA9.js");
503
+ let { diagram: e } = await import("./sankeyDiagram-IPEJSGJF-DzXzUNs5.js");
504
504
  return {
505
505
  id: It,
506
506
  diagram: e
@@ -530,7 +530,7 @@ var qe = "c4", Je = {
530
530
  id: Ht,
531
531
  detector: /* @__PURE__ */ p((e) => /^\s*block(-beta)?/.test(e), "detector"),
532
532
  loader: /* @__PURE__ */ p(async () => {
533
- let { diagram: e } = await import("./blockDiagram-BEXU5L5S-iNiTd2F6.js");
533
+ let { diagram: e } = await import("./blockDiagram-BEXU5L5S-BrCVxVRd.js");
534
534
  return {
535
535
  id: Ht,
536
536
  diagram: e
@@ -590,7 +590,7 @@ var qe = "c4", Je = {
590
590
  id: en,
591
591
  detector: /* @__PURE__ */ p((e) => /^\s*treemap/.test(e), "detector"),
592
592
  loader: /* @__PURE__ */ p(async () => {
593
- let { diagram: e } = await import("./diagram-3UASUU5V-DKbBxWI5.js");
593
+ let { diagram: e } = await import("./diagram-3UASUU5V-DRoFk6qc.js");
594
594
  return {
595
595
  id: en,
596
596
  diagram: e
@@ -600,7 +600,7 @@ var qe = "c4", Je = {
600
600
  id: nn,
601
601
  detector: /* @__PURE__ */ p((e) => /^\s*usecase-beta(?:\s|$)/.test(e), "detector"),
602
602
  loader: /* @__PURE__ */ p(async () => {
603
- let { diagram: e } = await import("./usecaseDiagram-POWQR4AR-CKd5UWWw.js");
603
+ let { diagram: e } = await import("./usecaseDiagram-POWQR4AR-B1HduAbh.js");
604
604
  return {
605
605
  id: nn,
606
606
  diagram: e
@@ -7,11 +7,11 @@ import "./chunk-MBY4JIJT-BFIqOe-8.js";
7
7
  import "./chunk-7PRAP22T-0C6_H8Li.js";
8
8
  import "./chunk-7INBJB4K-k-I67NSP.js";
9
9
  import "./chunk-5DYCD2WN-Cd1zazNp.js";
10
- import "./chunk-Z7XXMR3K-DDFBvLN4.js";
10
+ import "./chunk-Z7XXMR3K-DY6U0Uq4.js";
11
11
  import { t as u } from "./chunk-XXDRQBXY-dKXxu_aj.js";
12
12
  import { t as d } from "./chunk-WEXAMYUT-CbFOhEve.js";
13
13
  import "./chunk-UA2S7LBM-ChuksCDg.js";
14
- import { r as f, t as p } from "./chunk-GNY47TPC-AFxr6Xhs.js";
14
+ import { r as f, t as p } from "./chunk-GNY47TPC-Dzk3o85s.js";
15
15
  //#region ../../node_modules/uuid/dist/stringify.js
16
16
  var m = [];
17
17
  for (let e = 0; e < 256; ++e) m.push((e + 256).toString(16).slice(1));
@@ -1,4 +1,4 @@
1
- import { ct as e, ot as t } from "./components-CEXxj5QP.js";
1
+ import { ct as e, ot as t } from "./components-DH5dpaU8.js";
2
2
  import { n } from "./src-CsLQInsN.js";
3
3
  import { i as r, p as i } from "./chunk-ZIGJFQKS-9VXArDKF.js";
4
4
  import { t as a } from "./ordinal-DwxdXP1t.js";
package/dist/print.js CHANGED
@@ -1,5 +1,5 @@
1
- import { r as e } from "./i18n-provider-Dv9ZSmgO.js";
2
- import { t } from "./translate-material-CCJg3yfc.js";
1
+ import { r as e } from "./i18n-provider-Cq_VScPv.js";
2
+ import { t } from "./translate-material-B6HO6ykL.js";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
4
  import { Children as i, createContext as a, isValidElement as o, useCallback as s, useContext as c, useEffect as l, useMemo as u, useState as d } from "react";
5
5
  import { OBJECT_URL_TTL_MS as f, downloadPdfFile as p } from "@nxgt/material-core/pdf-download";
@@ -1,4 +1,4 @@
1
- import { rt as e } from "./components-CEXxj5QP.js";
1
+ import { rt as e } from "./components-DH5dpaU8.js";
2
2
  import { n as t, t as n } from "./src-CsLQInsN.js";
3
3
  import { n as r } from "./chunk-Y2CYZVJY-BAad7w_K.js";
4
4
  import { D as i, H as a, U as o, a as s, c, f as l, q as u, v as d, w as f, x as p, y as m, z as h } from "./chunk-O7XYJQB3-BChweQ_V.js";
@@ -8,11 +8,11 @@ import "./chunk-7PRAP22T-0C6_H8Li.js";
8
8
  import { a as p, i as m, o as h, r as g } from "./chunk-J5ZVWO5B-DmRRmhon.js";
9
9
  import "./chunk-7INBJB4K-k-I67NSP.js";
10
10
  import "./chunk-5DYCD2WN-Cd1zazNp.js";
11
- import "./chunk-Z7XXMR3K-DDFBvLN4.js";
11
+ import "./chunk-Z7XXMR3K-DY6U0Uq4.js";
12
12
  import { t as _ } from "./chunk-XXDRQBXY-dKXxu_aj.js";
13
13
  import { t as v } from "./chunk-WEXAMYUT-CbFOhEve.js";
14
14
  import "./chunk-UA2S7LBM-ChuksCDg.js";
15
- import { r as y, t as b } from "./chunk-GNY47TPC-AFxr6Xhs.js";
15
+ import { r as y, t as b } from "./chunk-GNY47TPC-Dzk3o85s.js";
16
16
  //#region ../../node_modules/mermaid/dist/chunks/mermaid.core/requirementDiagram-PLB6GJNP.mjs
17
17
  var x = (function() {
18
18
  var e = /* @__PURE__ */ n(function(e, t, n, r) {
@@ -1,4 +1,4 @@
1
- import { V as e } from "./components-CEXxj5QP.js";
1
+ import { V as e } from "./components-DH5dpaU8.js";
2
2
  import { t } from "./src-CsLQInsN.js";
3
3
  import { t as n } from "./ordinal-DwxdXP1t.js";
4
4
  import { n as r } from "./chunk-Y2CYZVJY-BAad7w_K.js";
@@ -1,6 +1,6 @@
1
1
  import { t as e } from "./utils-DC8bw9A_.js";
2
2
  import { pt as t, t as n } from "./icon-button-B1nN3J6B.js";
3
- import { t as r } from "./use-material-translation-Cndoq_iK.js";
3
+ import { t as r } from "./use-material-translation-Bp4ECeT4.js";
4
4
  import { GripVertical as i } from "lucide-react";
5
5
  import { jsx as a } from "react/jsx-runtime";
6
6
  import o, { cloneElement as s, createContext as c, forwardRef as l, memo as u, useCallback as d, useContext as f, useEffect as p, useLayoutEffect as m, useMemo as h, useReducer as g, useRef as _, useState as v } from "react";
@@ -8,12 +8,12 @@ import "./chunk-7PRAP22T-0C6_H8Li.js";
8
8
  import { a as h, i as g, o as _, r as v } from "./chunk-J5ZVWO5B-DmRRmhon.js";
9
9
  import "./chunk-7INBJB4K-k-I67NSP.js";
10
10
  import "./chunk-5DYCD2WN-Cd1zazNp.js";
11
- import "./chunk-Z7XXMR3K-DDFBvLN4.js";
11
+ import "./chunk-Z7XXMR3K-DY6U0Uq4.js";
12
12
  import { t as y } from "./chunk-GWA4HPMP-B8jXI0Tl.js";
13
13
  import { t as b } from "./chunk-XXDRQBXY-dKXxu_aj.js";
14
14
  import { t as x } from "./chunk-WEXAMYUT-CbFOhEve.js";
15
15
  import "./chunk-UA2S7LBM-ChuksCDg.js";
16
- import { r as S, t as C } from "./chunk-GNY47TPC-AFxr6Xhs.js";
16
+ import { r as S, t as C } from "./chunk-GNY47TPC-Dzk3o85s.js";
17
17
  //#region ../../node_modules/mermaid/dist/chunks/mermaid.core/stateDiagram-v2-GCMORJYK.mjs
18
18
  var w = (function() {
19
19
  var e = /* @__PURE__ */ i(function(e, t, n, r) {
@@ -340,6 +340,7 @@ var e = {
340
340
  "select-all": "Select all",
341
341
  "select-row": "Select row",
342
342
  "toggle-row": "Toggle row details",
343
+ expand: "Expand",
343
344
  "scroll-region": "Scrollable table"
344
345
  },
345
346
  pagination: {
@@ -752,6 +753,7 @@ var e = {
752
753
  placeholder: "Search…",
753
754
  empty: "No results"
754
755
  },
756
+ "option-count": { label: "{count, plural, one {result} other {results}}" },
755
757
  autocomplete: {
756
758
  empty: "No option found.",
757
759
  add: "Add \"{query}\"",
@@ -1231,6 +1233,17 @@ var e = {
1231
1233
  saved: "I have saved these codes",
1232
1234
  "saved-required": "Tick the box once your codes are safe",
1233
1235
  done: "Done"
1236
+ },
1237
+ "repeatable-group": {
1238
+ row: "row",
1239
+ add: "Add {label}",
1240
+ remove: "Remove {label} {index}",
1241
+ "move-up": "Move {label} {index} up",
1242
+ "move-down": "Move {label} {index} down",
1243
+ added: "Added {label} {index}",
1244
+ removed: "Removed {label} {index}",
1245
+ moved: "Moved {label} {from} to position {to}",
1246
+ "max-reached": "Maximum reached ({max})"
1234
1247
  }
1235
1248
  } },
1236
1249
  fr: { material: {
@@ -1572,6 +1585,7 @@ var e = {
1572
1585
  "select-all": "Tout sélectionner",
1573
1586
  "select-row": "Sélectionner la ligne",
1574
1587
  "toggle-row": "Afficher ou masquer les détails de la ligne",
1588
+ expand: "Déplier",
1575
1589
  "scroll-region": "Tableau défilant"
1576
1590
  },
1577
1591
  pagination: {
@@ -1984,6 +1998,7 @@ var e = {
1984
1998
  placeholder: "Rechercher…",
1985
1999
  empty: "Aucun résultat"
1986
2000
  },
2001
+ "option-count": { label: "{count, plural, one {résultat} other {résultats}}" },
1987
2002
  autocomplete: {
1988
2003
  empty: "Aucune option.",
1989
2004
  add: "Ajouter « {query} »",
@@ -2463,6 +2478,17 @@ var e = {
2463
2478
  saved: "J'ai enregistré ces codes",
2464
2479
  "saved-required": "Cochez la case une fois vos codes en lieu sûr",
2465
2480
  done: "Terminé"
2481
+ },
2482
+ "repeatable-group": {
2483
+ row: "ligne",
2484
+ add: "Ajouter une {label}",
2485
+ remove: "Retirer la {label} {index}",
2486
+ "move-up": "Monter la {label} {index}",
2487
+ "move-down": "Descendre la {label} {index}",
2488
+ added: "Ajout : {label} {index}",
2489
+ removed: "Suppression : {label} {index}",
2490
+ moved: "Déplacement : {label} {from} en position {to}",
2491
+ "max-reached": "Maximum atteint ({max})"
2466
2492
  }
2467
2493
  } }
2468
2494
  }, t = "language", n = "en", r = Object.keys(e);
@@ -7,10 +7,10 @@ import "./chunk-MBY4JIJT-BFIqOe-8.js";
7
7
  import "./chunk-7PRAP22T-0C6_H8Li.js";
8
8
  import "./chunk-7INBJB4K-k-I67NSP.js";
9
9
  import "./chunk-5DYCD2WN-Cd1zazNp.js";
10
- import "./chunk-Z7XXMR3K-DDFBvLN4.js";
10
+ import "./chunk-Z7XXMR3K-DY6U0Uq4.js";
11
11
  import "./chunk-UA2S7LBM-ChuksCDg.js";
12
- import { r as n } from "./chunk-3FUC2YCW-C3_88DyD.js";
13
- import { t as r } from "./chunk-NETBCI7D-DUZYHta0.js";
12
+ import { r as n } from "./chunk-3FUC2YCW-DWaNSANO.js";
13
+ import { t as r } from "./chunk-NETBCI7D-WvAAUJne.js";
14
14
  //#region ../../node_modules/mermaid/dist/chunks/mermaid.core/swimlanes-2SLR337P.mjs
15
15
  function i(e, { measure: t }) {
16
16
  let n = e.config?.swimlane?.lineHops;
@@ -7,14 +7,14 @@ import "./chunk-MBY4JIJT-BFIqOe-8.js";
7
7
  import "./chunk-7PRAP22T-0C6_H8Li.js";
8
8
  import "./chunk-7INBJB4K-k-I67NSP.js";
9
9
  import "./chunk-5DYCD2WN-Cd1zazNp.js";
10
- import "./chunk-Z7XXMR3K-DDFBvLN4.js";
10
+ import "./chunk-Z7XXMR3K-DY6U0Uq4.js";
11
11
  import "./chunk-GWA4HPMP-B8jXI0Tl.js";
12
12
  import "./chunk-XXDRQBXY-dKXxu_aj.js";
13
13
  import "./chunk-WEXAMYUT-CbFOhEve.js";
14
14
  import "./chunk-UA2S7LBM-ChuksCDg.js";
15
- import "./chunk-GNY47TPC-AFxr6Xhs.js";
15
+ import "./chunk-GNY47TPC-Dzk3o85s.js";
16
16
  import "./chunk-LNGE3PJU-DJjGTS7O.js";
17
- import { r as t, t as n } from "./chunk-7M6MHVWA-DSA5AJyK.js";
17
+ import { r as t, t as n } from "./chunk-7M6MHVWA-x-N4hnls.js";
18
18
  //#region ../../node_modules/mermaid/dist/chunks/mermaid.core/swimlanesDiagram-TC7HE7FX.mjs
19
19
  var r = n({ styles: /* @__PURE__ */ e((e) => `${t(e)}
20
20
  .swimlane.cluster:not([data-color-id]) rect {
@@ -1,4 +1,4 @@
1
- import { ct as e } from "./components-CEXxj5QP.js";
1
+ import { ct as e } from "./components-DH5dpaU8.js";
2
2
  import { n as t, t as n } from "./src-CsLQInsN.js";
3
3
  import { p as r } from "./chunk-ZIGJFQKS-9VXArDKF.js";
4
4
  import { n as i, t as a } from "./chunk-Y2CYZVJY-BAad7w_K.js";
@@ -1,5 +1,5 @@
1
- import "./stored-language-BKoohv2_.js";
2
- import { E as e, r as t } from "./translator-DEde7BKz.js";
1
+ import "./stored-language-DqlfjXt8.js";
2
+ import { E as e, r as t } from "./translator-B_lmafJN.js";
3
3
  //#region lib/i18n/translate-material.ts
4
4
  function n(n, r, i, a) {
5
5
  if (n) for (let e of /* @__PURE__ */ new Set([n, n.split("-")[0]])) {
@@ -1,4 +1,4 @@
1
- import { a as e, i as t, o as n, t as r } from "./stored-language-BKoohv2_.js";
1
+ import { a as e, i as t, o as n, t as r } from "./stored-language-DqlfjXt8.js";
2
2
  //#region ../../node_modules/@formatjs/fast-memoize/index.js
3
3
  function i(e, t) {
4
4
  let n = t && t.cache ? t.cache : ne, r = t && t.serializer ? t.serializer : ee;
@@ -1,5 +1,5 @@
1
- import { n as e } from "./stored-language-BKoohv2_.js";
2
- import { r as t } from "./i18n-provider-Dv9ZSmgO.js";
1
+ import { n as e } from "./stored-language-DqlfjXt8.js";
2
+ import { r as t } from "./i18n-provider-Cq_VScPv.js";
3
3
  import { _ as n, g as r, h as i, n as a, v as o, y as s } from "./number.utils-BiBN2hWJ.js";
4
4
  import { createContext as c, useCallback as l, useContext as u, useEffect as d, useMemo as f, useRef as p, useSyncExternalStore as m } from "react";
5
5
  //#region lib/hooks/resolve-theme.ts
@@ -1,5 +1,5 @@
1
- import { r as e } from "./i18n-provider-Dv9ZSmgO.js";
2
- import { t } from "./translate-material-CCJg3yfc.js";
1
+ import { r as e } from "./i18n-provider-Cq_VScPv.js";
2
+ import { t } from "./translate-material-B6HO6ykL.js";
3
3
  import { useCallback as n } from "react";
4
4
  //#region lib/i18n/use-material-translation.ts
5
5
  function r() {
@@ -8,11 +8,11 @@ import "./chunk-7PRAP22T-0C6_H8Li.js";
8
8
  import { a as g, i as _, o as v, r as y } from "./chunk-J5ZVWO5B-DmRRmhon.js";
9
9
  import "./chunk-7INBJB4K-k-I67NSP.js";
10
10
  import "./chunk-5DYCD2WN-Cd1zazNp.js";
11
- import "./chunk-Z7XXMR3K-DDFBvLN4.js";
11
+ import "./chunk-Z7XXMR3K-DY6U0Uq4.js";
12
12
  import { t as ee } from "./chunk-XXDRQBXY-dKXxu_aj.js";
13
13
  import { t as te } from "./chunk-WEXAMYUT-CbFOhEve.js";
14
14
  import "./chunk-UA2S7LBM-ChuksCDg.js";
15
- import { r as ne, t as re } from "./chunk-GNY47TPC-AFxr6Xhs.js";
15
+ import { r as ne, t as re } from "./chunk-GNY47TPC-Dzk3o85s.js";
16
16
  //#region ../../node_modules/chevrotain/node_modules/lodash-es/_freeGlobal.js
17
17
  var ie = typeof global == "object" && global && global.Object === Object && global, ae = typeof self == "object" && self && self.Object === Object && self, b = ie || ae || Function("return this")(), oe = b.Symbol, se = Object.prototype, ce = se.hasOwnProperty, le = se.toString, ue = oe ? oe.toStringTag : void 0;
18
18
  function de(e) {
@@ -1,4 +1,4 @@
1
- import { at as e, rt as t, st as n } from "./components-CEXxj5QP.js";
1
+ import { at as e, rt as t, st as n } from "./components-DH5dpaU8.js";
2
2
  import { n as r } from "./src-CsLQInsN.js";
3
3
  import { i } from "./chunk-ZIGJFQKS-9VXArDKF.js";
4
4
  import { n as a } from "./chunk-Y2CYZVJY-BAad7w_K.js";
@@ -26,7 +26,7 @@ Anything you press that is not a field: buttons, link buttons, copy, load more,
26
26
 
27
27
  ## [Form fields](form-fields.md)
28
28
 
29
- Labelled inputs with a value, each with its form-library wrapper, and the composite values (attributes, contacts, address, opening hours), and the titled sections a long form is laid out in. 25 entries.
29
+ Labelled inputs with a value, each with its form-library wrapper, and the composite values (attributes, contacts, address, opening hours), the titled sections a long form is laid out in, and the rows a user adds and removes. 26 entries.
30
30
 
31
31
  [<img src="../previews/form-fields-textfield.webp" height="72" alt="TextField">](form-fields.md#textfield)
32
32
  [<img src="../previews/form-fields-phonefield.webp" height="72" alt="PhoneField">](form-fields.md#phonefield)
@@ -57,7 +57,8 @@ action); `DataTablePagination`, `DataTableServerFooter` and
57
57
  `useColumnHelpers<T>()` returns a
58
58
  `columnHelper` bound to the table's features and `predefinedColumns()` —
59
59
  `select` (checkboxes) and `expand` (a toggle for `renderExpandedRow`, named
60
- "Toggle row details" (`material.table.labels.toggle-row`) with `aria-expanded`);
60
+ "Toggle row details" (`material.table.labels.toggle-row`) with `aria-expanded`, under a
61
+ visually hidden header "Expand", `material.table.labels.expand`);
61
62
  `useDeleteRowsHandler(onDelete)` returns a `handleDelete(rows)` click
62
63
  handler and the `confirmDialog` to render.
63
64
  `dataTableFeatures` / `DataTableFeatures` are the TanStack v9 features the
@@ -77,6 +78,7 @@ table enables, for typing your own column defs.
77
78
  | `scrollLabel` | `string` | "Scrollable table" | the name of the scroll region the table becomes while it overflows |
78
79
  | `loading` | `boolean` | `false` | skeleton rows, or the current rows dimmed; `aria-busy`; controls disabled |
79
80
  | `loadingRows` | `number` | the page size | how many skeleton rows |
81
+ | `density` | `'comfortable' \| 'compact'` | `'comfortable'` | `compact` tightens the cell padding, the row and header heights and the gap between rows, the selection column included; it is the table's `data-density` attribute, styled with classes (no inline style). The toolbar band and the empty state keep their size; the print variant is unchanged |
80
82
  | `empty` | `ReactNode \| ({ filtered }) => ReactNode` | icon and "No data available" | content of the empty row, spanning every visible column |
81
83
  | `manual` | `boolean` | `false` | `data` is one server page: no client filtering, sorting or paging; the footer is the server footer ([server-side data](#server-side-data)) |
82
84
  | `sorting` / `onSortingChange` | `SortingState` / `(sorting) => void` | held inside | controlled sorting; the callback gets the new state, not an updater, and is not called for an update that resolves to the current value |
@@ -11,6 +11,7 @@ for the value type each one writes. Everything is imported from
11
11
  | --- | --- | --- |
12
12
  | <img src="../previews/form-fields-field.webp" width="96" alt=""> | [Field](#field) | Renders the field matching a config `type` |
13
13
  | <img src="../previews/form-fields-formsection.webp" width="96" alt=""> | [FormSection](#formsection) | Titled section of a form, one column on a phone |
14
+ | <img src="../previews/form-fields-repeatablegroup.webp" width="96" alt=""> | [RepeatableGroup](#repeatablegroup) | Rows a user adds, removes and reorders |
14
15
  | <img src="../previews/form-fields-textfield.webp" width="96" alt=""> | [TextField](#textfield) | Labelled input with adornments and helper text |
15
16
  | <img src="../previews/form-fields-textareafield.webp" width="96" alt=""> | [TextareaField](#textareafield) | Labelled textarea with row sizing and a counter |
16
17
  | <img src="../previews/form-fields-emailfield.webp" width="96" alt=""> | [EmailField](#emailfield) | Validates on blur, `mailto:` button |
@@ -163,6 +164,131 @@ semibold, uppercase and muted, set apart from the fields' labels, and reads
163
164
 
164
165
  ---
165
166
 
167
+ ## RepeatableGroup
168
+
169
+ ![RepeatableGroup](../previews/form-fields-repeatablegroup.webp)
170
+
171
+ Rows of fields a user adds, removes and, optionally, reorders — a school
172
+ year's periods, a list of contacts. `RepeatableGroupFormField` wires it to
173
+ react-hook-form's `useFieldArray`; each row's fields are your own form
174
+ wrappers, rendered by `renderRow`.
175
+
176
+ ```tsx
177
+ import { useForm } from 'react-hook-form';
178
+ import {
179
+ Button,
180
+ DateFormField,
181
+ RepeatableGroupFormField,
182
+ TextFormField,
183
+ } from '@nxgt/material/components';
184
+
185
+ type Period = { name: string; start?: Date; end?: Date };
186
+ type Values = { periods: Period[] };
187
+
188
+ export function SchoolYearForm({ onSave }: { onSave: (values: Values) => void }) {
189
+ const { control, handleSubmit } = useForm<Values>({
190
+ defaultValues: { periods: [{ name: 'Term 1' }] },
191
+ });
192
+ return (
193
+ <form className="form-grid-layout" onSubmit={handleSubmit(onSave)}>
194
+ <div data-slot="form-fields">
195
+ <RepeatableGroupFormField
196
+ control={control}
197
+ name="periods"
198
+ label="Periods"
199
+ rowLabel="period"
200
+ addLabel="Add period"
201
+ max={6}
202
+ reorderable
203
+ emptyTitle="No periods yet"
204
+ newRow={() => ({ name: '' })}
205
+ renderRow={({ index }) => (
206
+ <>
207
+ <TextFormField control={control} name={`periods.${index}.name`} label="Name" />
208
+ <DateFormField control={control} name={`periods.${index}.start`} label="Start date" />
209
+ <DateFormField control={control} name={`periods.${index}.end`} label="End date" />
210
+ </>
211
+ )}
212
+ />
213
+ </div>
214
+ <div data-slot="form-actions">
215
+ <Button type="submit">Save</Button>
216
+ </div>
217
+ </form>
218
+ );
219
+ }
220
+ ```
221
+
222
+ | Prop | Type | Default | Effect |
223
+ | --- | --- | --- | --- |
224
+ | `control`, `name` | `Control<T>`, `ArrayPath<T>` | — | the form and its array (`RepeatableGroupFormField`) |
225
+ | `newRow` | `() => FieldArray<T, N>` | — | the value Add appends |
226
+ | `renderRow` | `(row) => ReactNode` | — | one row's fields; `row` is `{ field, index, position, path }` (`index` 0-based, `position` 1-based, `path` `${name}.${index}`) |
227
+ | `label` | `ReactNode` | — | names the group (the list inside it is not named again) |
228
+ | `rowLabel` | `string` | `'row'` (translated) | names each row's buttons ("Remove period 2") and the announcements |
229
+ | `addLabel` | `string` | `'Add {rowLabel}'` | the Add button's text |
230
+ | `reorderable` | `boolean` | `false` | move up / move down buttons on each row |
231
+ | `max` | `number` | — | at this many rows, Add is disabled and says why |
232
+ | `min` | `number` | — | at this many rows, Remove is disabled |
233
+ | `emptyTitle`, `emptyDescription` | `ReactNode` | — | an `EmptyState` when there is no row |
234
+ | `disabled` | `boolean` | the form's | disables every button |
235
+
236
+ Without a form library, `RepeatableGroup` takes the rows and the three
237
+ actions; the move buttons show only with `onMove`:
238
+
239
+ ```tsx
240
+ import { useState } from 'react';
241
+ import { RepeatableGroup, TextField } from '@nxgt/material/components';
242
+
243
+ type Guest = { id: string; name: string };
244
+
245
+ export function Guests() {
246
+ const [guests, setGuests] = useState<Guest[]>([]);
247
+ const rename = (index: number, name: string) =>
248
+ setGuests((list) => list.map((g, i) => (i === index ? { ...g, name } : g)));
249
+ return (
250
+ <RepeatableGroup
251
+ label="Guests"
252
+ rowLabel="guest"
253
+ items={guests}
254
+ onAdd={() => setGuests((list) => [...list, { id: crypto.randomUUID(), name: '' }])}
255
+ onRemove={(index) => setGuests((list) => list.filter((_, i) => i !== index))}
256
+ renderRow={({ item, index }) => (
257
+ <TextField label="Name" value={item.name} onChange={(e) => rename(index, e.target.value)} />
258
+ )}
259
+ />
260
+ );
261
+ }
262
+ ```
263
+
264
+ `getKey` defaults to the item's `id`. That is the key react-hook-form's
265
+ `useFieldArray` puts on each of its `fields` (a generated id, not your data's),
266
+ so `RepeatableGroupFormField` needs none; a plain list without an `id` falls
267
+ back to the index, and should pass `getKey`. `error` shows an error under the
268
+ rows.
269
+
270
+ `rowLabel` is a lower-case noun. The French templates carry the feminine
271
+ article ("Ajouter une ligne", "Retirer la ligne 2"), so a French app passes a
272
+ feminine noun (`rowLabel="période"`), or overrides `addLabel` and the
273
+ `material.repeatable-group.*` keys in its own bundle (`mergeResources`) for a
274
+ masculine one.
275
+
276
+ - **Semantics:** a `role="group"` named by `label`, its rows a list
277
+ (`getAllByRole('listitem')`), each row's icon buttons named after it
278
+ ("Remove period 2", "Move period 2 up").
279
+ - **Focus and announcements:** see
280
+ [Rows a user adds and removes](../guides/forms.md#rows-a-user-adds-and-removes);
281
+ at `max`, Add stays focusable (`aria-disabled`) and is described by
282
+ "Maximum reached (6)".
283
+ - **Errors:** the array's own error (`errors.<name>.message` or `.root.message`)
284
+ describes the group; each row's fields show their own.
285
+ - **Layout:** one column on a phone, columns of at least 11rem from a container
286
+ width of `@xl`; no inline style.
287
+
288
+ **Storybook:** `Form fields/RepeatableGroup` · **Vue:** `RepeatableGroup`, `RepeatableGroupFormField`
289
+
290
+ ---
291
+
166
292
  ## TextField
167
293
 
168
294
  ![TextField](../previews/form-fields-textfield.webp)
@@ -429,8 +555,28 @@ import { SearchField } from '@nxgt/material/components';
429
555
  | `onValueChange` | `(value: string) => void` | — | the text, debounced when `debounceMs` is set; the latest `onValueChange` is called when the delay ends, so an inline arrow is safe |
430
556
  | `debounceMs` | `number` | `0` | delay before `onValueChange`; `0` calls it on every key |
431
557
  | `loading` | `boolean` | `false` | spinner in place of the clear button |
558
+ | `shortcut` | `string` | — | a hint for the key that focuses the field, e.g. `"/"`: a `Kbd` at the end while the field is empty, not loading and not disabled (`aria-hidden`) and `aria-keyshortcuts` on the input. It binds no key; your page listens and focuses the field |
432
559
  | `onChange` | native handler | — | still fires on every key, undebounced |
433
560
 
561
+ The `shortcut` hint binds no key. `SearchField` passes `id` and the other
562
+ input props to the `<input>`, so the page focuses it by `id`:
563
+
564
+ ```tsx
565
+ useEffect(() => {
566
+ const onKey = (event: KeyboardEvent) => {
567
+ const target = event.target as HTMLElement;
568
+ if (event.key === '/' && !target.closest('input, textarea, [contenteditable]')) {
569
+ event.preventDefault();
570
+ document.getElementById('orders-search')?.focus();
571
+ }
572
+ };
573
+ document.addEventListener('keydown', onKey);
574
+ return () => document.removeEventListener('keydown', onKey);
575
+ }, []);
576
+
577
+ <SearchField id="orders-search" shortcut="/" />
578
+ ```
579
+
434
580
  **Emits:** `string` through `onValueChange`; `SearchFormField` stores `string`.
435
581
  **Form wrapper:** `SearchFormField` — `control` and `name`, see
436
582
  [forms](../guides/forms.md#the-pair) and [what each field emits](../guides/forms.md#what-each-field-emits).