@12-apps/ui 6.2.0 → 6.3.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.
Files changed (166) hide show
  1. package/dist/{chunk-35VGGLOC.js → chunk-CEKPLUQV.js} +2 -2
  2. package/dist/{chunk-35VGGLOC.js.map → chunk-CEKPLUQV.js.map} +1 -1
  3. package/dist/{chunk-7XLEWBKL.js → chunk-N554AFDB.js} +7 -10
  4. package/dist/chunk-N554AFDB.js.map +1 -0
  5. package/dist/{chunk-JDO7W4D4.js → chunk-R5ZQZSEQ.js} +2 -20
  6. package/dist/{chunk-JDO7W4D4.js.map → chunk-R5ZQZSEQ.js.map} +1 -1
  7. package/dist/{chunk-R4TYXKDD.js → chunk-TPQRIPCN.js} +52 -48
  8. package/dist/chunk-TPQRIPCN.js.map +1 -0
  9. package/dist/{chunk-62XQWGXU.js → chunk-WFPXRSIZ.js} +20 -18
  10. package/dist/chunk-WFPXRSIZ.js.map +1 -0
  11. package/dist/copy.js +1 -0
  12. package/dist/copy.js.map +1 -0
  13. package/dist/data-display/CardKit.js +15 -4
  14. package/dist/data-display/CardKit.js.map +1 -1
  15. package/dist/data-display/DataViews.js +664 -616
  16. package/dist/data-display/DataViews.js.map +1 -1
  17. package/dist/data-display/SectionOnboarding.js +3 -3
  18. package/dist/data-display/SectionOnboarding.js.map +1 -1
  19. package/dist/feedback/ConfirmAction.js +3 -5
  20. package/dist/form/CategorySelect.js +1 -1
  21. package/dist/form/CepField.js +1 -1
  22. package/dist/form/total-form.js +8 -4
  23. package/dist/form/total-form.js.map +1 -1
  24. package/dist/layout/ContentToolbar.js +1 -1
  25. package/dist/layout/TableFilter.js +1 -1
  26. package/dist/pt-BR.js +222 -0
  27. package/dist/pt-BR.js.map +1 -0
  28. package/dist/types/components/data-display/CardKit/use-remove-confirm.d.ts +4 -1
  29. package/dist/types/components/data-display/CardKit/use-remove-confirm.d.ts.map +1 -1
  30. package/dist/types/components/data-display/CardKit/use-row-confirm.d.ts +5 -2
  31. package/dist/types/components/data-display/CardKit/use-row-confirm.d.ts.map +1 -1
  32. package/dist/types/components/data-display/DataViews/DataViewsBoard.d.ts.map +1 -1
  33. package/dist/types/components/data-display/DataViews/DeleteViewDialog.d.ts.map +1 -1
  34. package/dist/types/components/data-display/DataViews/ManageViewsDialog.d.ts +4 -1
  35. package/dist/types/components/data-display/DataViews/ManageViewsDialog.d.ts.map +1 -1
  36. package/dist/types/components/data-display/DataViews/SaveViewModal.d.ts +0 -5
  37. package/dist/types/components/data-display/DataViews/SaveViewModal.d.ts.map +1 -1
  38. package/dist/types/components/data-display/DataViews/base-card.d.ts.map +1 -1
  39. package/dist/types/components/data-display/DataViews/base-list-card-gutters.d.ts.map +1 -1
  40. package/dist/types/components/data-display/DataViews/data-views-bar-controls.d.ts.map +1 -1
  41. package/dist/types/components/data-display/DataViews/data-views-category-pill.d.ts.map +1 -1
  42. package/dist/types/components/data-display/DataViews/data-views-columns-tab.d.ts.map +1 -1
  43. package/dist/types/components/data-display/DataViews/data-views-copy-context.d.ts +17 -0
  44. package/dist/types/components/data-display/DataViews/data-views-copy-context.d.ts.map +1 -0
  45. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +205 -0
  46. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -0
  47. package/dist/types/components/data-display/DataViews/data-views-display-panel.d.ts.map +1 -1
  48. package/dist/types/components/data-display/DataViews/data-views-display-tabs.d.ts.map +1 -1
  49. package/dist/types/components/data-display/DataViews/data-views-export.d.ts.map +1 -1
  50. package/dist/types/components/data-display/DataViews/data-views-filter-panel.d.ts.map +1 -1
  51. package/dist/types/components/data-display/DataViews/data-views-grid-helpers.d.ts.map +1 -1
  52. package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
  53. package/dist/types/components/data-display/DataViews/data-views-more-filters.d.ts.map +1 -1
  54. package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts.map +1 -1
  55. package/dist/types/components/data-display/DataViews/data-views-range-presets.d.ts +3 -2
  56. package/dist/types/components/data-display/DataViews/data-views-range-presets.d.ts.map +1 -1
  57. package/dist/types/components/data-display/DataViews/data-views-scopes.d.ts.map +1 -1
  58. package/dist/types/components/data-display/DataViews/data-views-search.d.ts.map +1 -1
  59. package/dist/types/components/data-display/DataViews/data-views-select-all-strip.d.ts.map +1 -1
  60. package/dist/types/components/data-display/DataViews/data-views-table-parts.d.ts.map +1 -1
  61. package/dist/types/components/data-display/DataViews/data-views-view-nav.d.ts +1 -1
  62. package/dist/types/components/data-display/DataViews/data-views-view-nav.d.ts.map +1 -1
  63. package/dist/types/components/data-display/DataViews/index.d.ts +2 -0
  64. package/dist/types/components/data-display/DataViews/index.d.ts.map +1 -1
  65. package/dist/types/components/data-display/DataViews/save-view-preview.d.ts +10 -0
  66. package/dist/types/components/data-display/DataViews/save-view-preview.d.ts.map +1 -0
  67. package/dist/types/components/data-display/DataViews/use-saved-views-controller.d.ts.map +1 -1
  68. package/dist/types/components/data-display/SectionOnboarding/SectionOnboarding.types.d.ts +6 -5
  69. package/dist/types/components/data-display/SectionOnboarding/SectionOnboarding.types.d.ts.map +1 -1
  70. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.hooks.d.ts +1 -3
  71. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.hooks.d.ts.map +1 -1
  72. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.parts.d.ts +4 -1
  73. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.parts.d.ts.map +1 -1
  74. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.types.d.ts +9 -1
  75. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.types.d.ts.map +1 -1
  76. package/dist/types/components/feedback/ConfirmAction/ConfirmButton.d.ts +2 -1
  77. package/dist/types/components/feedback/ConfirmAction/ConfirmButton.d.ts.map +1 -1
  78. package/dist/types/components/feedback/ConfirmAction/index.d.ts +2 -2
  79. package/dist/types/components/feedback/ConfirmAction/index.d.ts.map +1 -1
  80. package/dist/types/components/feedback/ConfirmAction/with-confirmation.d.ts +5 -1
  81. package/dist/types/components/feedback/ConfirmAction/with-confirmation.d.ts.map +1 -1
  82. package/dist/types/components/form/CategorySelect/CategoryPanel.d.ts +4 -1
  83. package/dist/types/components/form/CategorySelect/CategoryPanel.d.ts.map +1 -1
  84. package/dist/types/components/form/CategorySelect/CategoryPanelFoot.d.ts +5 -2
  85. package/dist/types/components/form/CategorySelect/CategoryPanelFoot.d.ts.map +1 -1
  86. package/dist/types/components/form/CategorySelect/CategoryPanelHead.d.ts +5 -2
  87. package/dist/types/components/form/CategorySelect/CategoryPanelHead.d.ts.map +1 -1
  88. package/dist/types/components/form/CategorySelect/CategoryPanelList.d.ts +3 -0
  89. package/dist/types/components/form/CategorySelect/CategoryPanelList.d.ts.map +1 -1
  90. package/dist/types/components/form/CategorySelect/CategorySelect.types.d.ts +5 -0
  91. package/dist/types/components/form/CategorySelect/CategorySelect.types.d.ts.map +1 -1
  92. package/dist/types/components/form/CategorySelect/CategoryTrigger.d.ts +4 -1
  93. package/dist/types/components/form/CategorySelect/CategoryTrigger.d.ts.map +1 -1
  94. package/dist/types/components/form/CepField/CepField.d.ts +1 -1
  95. package/dist/types/components/form/CepField/CepField.d.ts.map +1 -1
  96. package/dist/types/components/form/CepField/CepField.types.d.ts +3 -0
  97. package/dist/types/components/form/CepField/CepField.types.d.ts.map +1 -1
  98. package/dist/types/components/form/total-form/Fields/CategoryField.d.ts +4 -1
  99. package/dist/types/components/form/total-form/Fields/CategoryField.d.ts.map +1 -1
  100. package/dist/types/components/form/total-form/Fields/CepField.d.ts +4 -1
  101. package/dist/types/components/form/total-form/Fields/CepField.d.ts.map +1 -1
  102. package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts +6 -1
  103. package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts.map +1 -1
  104. package/dist/types/components/layout/ContentToolbar/SavedViewsMenu.d.ts.map +1 -1
  105. package/dist/types/copy.d.ts +99 -0
  106. package/dist/types/copy.d.ts.map +1 -0
  107. package/dist/types/pt-BR.d.ts +28 -0
  108. package/dist/types/pt-BR.d.ts.map +1 -0
  109. package/package.json +10 -2
  110. package/src/components/data-display/CardKit/use-remove-confirm.tsx +5 -0
  111. package/src/components/data-display/CardKit/use-row-confirm.tsx +7 -2
  112. package/src/components/data-display/DataViews/DataViewsBoard.tsx +7 -4
  113. package/src/components/data-display/DataViews/DeleteViewDialog.tsx +6 -4
  114. package/src/components/data-display/DataViews/ManageViewsDialog.tsx +26 -10
  115. package/src/components/data-display/DataViews/SaveViewModal.tsx +56 -90
  116. package/src/components/data-display/DataViews/base-card.tsx +3 -1
  117. package/src/components/data-display/DataViews/base-list-card-gutters.tsx +3 -1
  118. package/src/components/data-display/DataViews/data-views-bar-controls.tsx +8 -5
  119. package/src/components/data-display/DataViews/data-views-category-pill.tsx +6 -3
  120. package/src/components/data-display/DataViews/data-views-columns-tab.tsx +5 -3
  121. package/src/components/data-display/DataViews/data-views-copy-context.tsx +43 -0
  122. package/src/components/data-display/DataViews/data-views-copy.ts +214 -0
  123. package/src/components/data-display/DataViews/data-views-display-panel.tsx +15 -9
  124. package/src/components/data-display/DataViews/data-views-display-tabs.tsx +19 -29
  125. package/src/components/data-display/DataViews/data-views-export.tsx +9 -10
  126. package/src/components/data-display/DataViews/data-views-filter-panel.tsx +9 -5
  127. package/src/components/data-display/DataViews/data-views-grid-helpers.tsx +5 -2
  128. package/src/components/data-display/DataViews/data-views-more-fields.tsx +5 -3
  129. package/src/components/data-display/DataViews/data-views-more-filters.tsx +6 -3
  130. package/src/components/data-display/DataViews/data-views-range-pill.tsx +9 -5
  131. package/src/components/data-display/DataViews/data-views-range-presets.ts +7 -8
  132. package/src/components/data-display/DataViews/data-views-scopes.tsx +3 -1
  133. package/src/components/data-display/DataViews/data-views-search.tsx +7 -4
  134. package/src/components/data-display/DataViews/data-views-select-all-strip.tsx +5 -3
  135. package/src/components/data-display/DataViews/data-views-table-parts.tsx +7 -2
  136. package/src/components/data-display/DataViews/data-views-view-nav.tsx +22 -16
  137. package/src/components/data-display/DataViews/index.ts +20 -0
  138. package/src/components/data-display/DataViews/save-view-preview.tsx +78 -0
  139. package/src/components/data-display/DataViews/use-saved-views-controller.ts +3 -1
  140. package/src/components/data-display/SectionOnboarding/SectionOnboarding.tsx +3 -3
  141. package/src/components/data-display/SectionOnboarding/SectionOnboarding.types.ts +8 -7
  142. package/src/components/feedback/ConfirmAction/ConfirmAction.hooks.ts +2 -2
  143. package/src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx +20 -6
  144. package/src/components/feedback/ConfirmAction/ConfirmAction.types.ts +9 -1
  145. package/src/components/feedback/ConfirmAction/ConfirmButton.tsx +12 -4
  146. package/src/components/feedback/ConfirmAction/index.ts +2 -2
  147. package/src/components/feedback/ConfirmAction/with-confirmation.tsx +4 -3
  148. package/src/components/form/CategorySelect/CategoryPanel.tsx +18 -6
  149. package/src/components/form/CategorySelect/CategoryPanelFoot.tsx +10 -5
  150. package/src/components/form/CategorySelect/CategoryPanelHead.tsx +8 -3
  151. package/src/components/form/CategorySelect/CategoryPanelList.tsx +17 -10
  152. package/src/components/form/CategorySelect/CategorySelect.tsx +3 -3
  153. package/src/components/form/CategorySelect/CategorySelect.types.ts +5 -0
  154. package/src/components/form/CategorySelect/CategoryTrigger.tsx +5 -1
  155. package/src/components/form/CepField/CepField.tsx +6 -9
  156. package/src/components/form/CepField/CepField.types.ts +3 -0
  157. package/src/components/form/total-form/Fields/CategoryField.tsx +5 -0
  158. package/src/components/form/total-form/Fields/CepField.tsx +5 -0
  159. package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +6 -1
  160. package/src/components/layout/ContentToolbar/SavedViewsMenu.tsx +1 -21
  161. package/src/components/layout/TableFilter/TableFilter.tsx +1 -1
  162. package/src/copy.ts +103 -0
  163. package/src/pt-BR.ts +247 -0
  164. package/dist/chunk-62XQWGXU.js.map +0 -1
  165. package/dist/chunk-7XLEWBKL.js.map +0 -1
  166. package/dist/chunk-R4TYXKDD.js.map +0 -1
@@ -441,14 +441,11 @@ function CategoryMultiFoot({
441
441
  sheet,
442
442
  onClear,
443
443
  onApply,
444
- dataTestId
444
+ dataTestId,
445
+ copy
445
446
  }) {
446
447
  return /* @__PURE__ */ jsxs(Box, { sx: footerSx, "data-testid": `${dataTestId}-footer`, children: [
447
- /* @__PURE__ */ jsxs(Box, { component: "span", sx: { fontSize: 12, color: "text.secondary" }, children: [
448
- /* @__PURE__ */ jsx("strong", { children: count }),
449
- " selecionada",
450
- count === 1 ? "" : "s"
451
- ] }),
448
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontSize: 12, color: "text.secondary" }, children: copy.footer.selectedCount(count) }),
452
449
  /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", gap: "6px" }, children: [
453
450
  /* @__PURE__ */ jsx(
454
451
  Button,
@@ -458,7 +455,7 @@ function CategoryMultiFoot({
458
455
  sx: buttonSx(sheet),
459
456
  onClick: onClear,
460
457
  "data-testid": `${dataTestId}-clear`,
461
- children: "Limpar"
458
+ children: copy.footer.clear
462
459
  }
463
460
  ),
464
461
  /* @__PURE__ */ jsx(
@@ -468,7 +465,7 @@ function CategoryMultiFoot({
468
465
  sx: buttonSx(sheet),
469
466
  onClick: onApply,
470
467
  "data-testid": `${dataTestId}-apply`,
471
- children: changed ? "Aplicar" : "Fechar"
468
+ children: changed ? copy.footer.apply : copy.footer.close
472
469
  }
473
470
  )
474
471
  ] })
@@ -477,10 +474,11 @@ function CategoryMultiFoot({
477
474
  function CategorySingleFoot({
478
475
  sheet,
479
476
  onCancel,
480
- dataTestId
477
+ dataTestId,
478
+ copy
481
479
  }) {
482
480
  return /* @__PURE__ */ jsxs(Box, { sx: footerSx, "data-testid": `${dataTestId}-footer`, children: [
483
- /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontSize: 12, color: "text.secondary" }, children: "Escolha uma categoria" }),
481
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontSize: 12, color: "text.secondary" }, children: copy.footer.singleHint }),
484
482
  /* @__PURE__ */ jsx(
485
483
  Button,
486
484
  {
@@ -488,7 +486,7 @@ function CategorySingleFoot({
488
486
  sx: buttonSx(sheet),
489
487
  onClick: onCancel,
490
488
  "data-testid": `${dataTestId}-cancel`,
491
- children: "Cancelar"
489
+ children: copy.footer.cancel
492
490
  }
493
491
  )
494
492
  ] });
@@ -567,7 +565,8 @@ function CategoryPanelHead({
567
565
  quickActions,
568
566
  onQueryChange,
569
567
  searchInputRef,
570
- dataTestId
568
+ dataTestId,
569
+ copy
571
570
  }) {
572
571
  return /* @__PURE__ */ jsxs3(Box2, { sx: (theme) => panelHeadSx(theme, sheet), children: [
573
572
  /* @__PURE__ */ jsxs3(Box2, { sx: searchFieldSx, children: [
@@ -601,7 +600,7 @@ function CategoryPanelHead({
601
600
  {
602
601
  component: "button",
603
602
  type: "button",
604
- "aria-label": "Limpar busca",
603
+ "aria-label": copy.search.clear,
605
604
  "data-testid": `${dataTestId}-search-clear`,
606
605
  sx: clearButtonSx,
607
606
  onClick: () => onQueryChange(""),
@@ -627,21 +626,19 @@ function CategoryPanelHead({
627
626
  function CategoryPinnedTray({
628
627
  chips,
629
628
  onRemove,
630
- dataTestId
629
+ dataTestId,
630
+ copy
631
631
  }) {
632
632
  if (chips.length === 0) return null;
633
633
  return /* @__PURE__ */ jsxs3(Box2, { sx: pinnedSx, "data-testid": `${dataTestId}-pinned`, children: [
634
- /* @__PURE__ */ jsxs3(Box2, { sx: pinnedLabelSx, children: [
635
- "Selecionadas \xB7 ",
636
- chips.length
637
- ] }),
634
+ /* @__PURE__ */ jsx3(Box2, { sx: pinnedLabelSx, children: copy.search.pinnedLabel(chips.length) }),
638
635
  /* @__PURE__ */ jsx3(Box2, { sx: chipWrapSx, children: chips.map((chip) => /* @__PURE__ */ jsxs3(Box2, { component: "span", sx: chipSx, children: [
639
636
  chip.label,
640
637
  /* @__PURE__ */ jsx3(
641
638
  "button",
642
639
  {
643
640
  type: "button",
644
- "aria-label": `Remover ${chip.label}`,
641
+ "aria-label": copy.search.removeChip(chip.label),
645
642
  "data-testid": `${dataTestId}-unpin-${chip.id}`,
646
643
  onClick: () => onRemove(chip.id),
647
644
  children: "\xD7"
@@ -773,30 +770,28 @@ function LoadingRows() {
773
770
  }
774
771
  function EmptyCatalogue({
775
772
  onCreateCategory,
776
- dataTestId
773
+ dataTestId,
774
+ copy
777
775
  }) {
778
776
  return /* @__PURE__ */ jsxs5(Box4, { sx: emptySx, "data-testid": `${dataTestId}-empty-catalogue`, children: [
779
- /* @__PURE__ */ jsx5("strong", { children: "Nenhuma categoria ainda" }),
780
- /* @__PURE__ */ jsx5("p", { children: "Categorias organizam o card\xE1pio e os filtros da loja." }),
781
- onCreateCategory && /* @__PURE__ */ jsx5(Button2, { variant: "contained", size: "small", sx: SENTENCE_CASE, onClick: () => onCreateCategory(), children: "Criar categoria" })
777
+ /* @__PURE__ */ jsx5("strong", { children: copy.emptyTitle }),
778
+ /* @__PURE__ */ jsx5("p", { children: copy.purpose }),
779
+ onCreateCategory && /* @__PURE__ */ jsx5(Button2, { variant: "contained", size: "small", sx: SENTENCE_CASE, onClick: () => onCreateCategory(), children: copy.createCategory })
782
780
  ] });
783
781
  }
784
782
  function NoResults({
785
783
  query,
786
784
  onClearQuery,
787
785
  onCreateCategory,
788
- dataTestId
786
+ dataTestId,
787
+ copy
789
788
  }) {
790
789
  return /* @__PURE__ */ jsxs5(Box4, { sx: emptySx, "data-testid": `${dataTestId}-no-results`, children: [
791
- /* @__PURE__ */ jsxs5("strong", { children: [
792
- "Nada encontrado para \u201C",
793
- query,
794
- "\u201D"
795
- ] }),
796
- /* @__PURE__ */ jsx5("p", { children: "Tente outro termo ou verifique a grafia." }),
790
+ /* @__PURE__ */ jsx5("strong", { children: copy.noResults.title(query) }),
791
+ /* @__PURE__ */ jsx5("p", { children: copy.noResults.hint }),
797
792
  /* @__PURE__ */ jsxs5(Box4, { sx: { display: "flex", gap: "6px", justifyContent: "center" }, children: [
798
- /* @__PURE__ */ jsx5(Button2, { variant: "outlined", size: "small", sx: SENTENCE_CASE, onClick: onClearQuery, children: "Limpar busca" }),
799
- onCreateCategory && /* @__PURE__ */ jsxs5(
793
+ /* @__PURE__ */ jsx5(Button2, { variant: "outlined", size: "small", sx: SENTENCE_CASE, onClick: onClearQuery, children: copy.noResults.clearSearch }),
794
+ onCreateCategory && /* @__PURE__ */ jsx5(
800
795
  Button2,
801
796
  {
802
797
  variant: "contained",
@@ -804,11 +799,7 @@ function NoResults({
804
799
  sx: SENTENCE_CASE,
805
800
  "data-testid": `${dataTestId}-create`,
806
801
  onClick: () => onCreateCategory(query.trim()),
807
- children: [
808
- "Criar \u201C",
809
- query.trim(),
810
- "\u201D"
811
- ]
802
+ children: copy.noResults.create(query.trim())
812
803
  }
813
804
  )
814
805
  ] })
@@ -858,13 +849,14 @@ function CategoryGroupRows({
858
849
  ] });
859
850
  }
860
851
  function CategoryPanelList(props) {
861
- const { groups, loading, query, listRef, sheet, dataTestId } = props;
852
+ const { groups, loading, query, listRef, sheet, dataTestId, copy } = props;
862
853
  const body = () => {
863
854
  if (loading) return /* @__PURE__ */ jsx5(LoadingRows, {});
864
855
  if (groups.length === 0 && query.trim().length > 0) {
865
856
  return /* @__PURE__ */ jsx5(
866
857
  NoResults,
867
858
  {
859
+ copy,
868
860
  query,
869
861
  onClearQuery: props.onClearQuery,
870
862
  onCreateCategory: props.onCreateCategory,
@@ -876,6 +868,7 @@ function CategoryPanelList(props) {
876
868
  return /* @__PURE__ */ jsx5(
877
869
  EmptyCatalogue,
878
870
  {
871
+ copy,
879
872
  onCreateCategory: props.onCreateCategory,
880
873
  dataTestId
881
874
  }
@@ -969,7 +962,8 @@ function CategoryPanel({
969
962
  onCreateCategory,
970
963
  searchInputRef,
971
964
  listRef,
972
- dataTestId
965
+ dataTestId,
966
+ copy
973
967
  }) {
974
968
  return /* @__PURE__ */ jsxs7(
975
969
  Box6,
@@ -983,8 +977,9 @@ function CategoryPanel({
983
977
  /* @__PURE__ */ jsx7(
984
978
  CategoryPanelHead,
985
979
  {
980
+ copy,
986
981
  query: state.query,
987
- placeholder: single ? "Buscar categoria\u2026" : "Buscar categoria ou subcategoria",
982
+ placeholder: single ? copy.search.placeholderSingle : copy.search.placeholderMulti,
988
983
  sheet,
989
984
  quickActions: single ? void 0 : /* @__PURE__ */ jsx7(CategoryQuickActions, { state, dataTestId }),
990
985
  onQueryChange: state.setQuery,
@@ -992,10 +987,11 @@ function CategoryPanel({
992
987
  dataTestId
993
988
  }
994
989
  ),
995
- !single && !loading && /* @__PURE__ */ jsx7(PinnedTray, { state, chips, dataTestId }),
990
+ !single && !loading && /* @__PURE__ */ jsx7(PinnedTray, { state, chips, dataTestId, copy }),
996
991
  /* @__PURE__ */ jsx7(
997
992
  CategoryPanelList,
998
993
  {
994
+ copy,
999
995
  groups: state.visibleGroups,
1000
996
  query: state.query,
1001
997
  draft: state.draft,
@@ -1023,6 +1019,7 @@ function CategoryPanel({
1023
1019
  changed,
1024
1020
  single,
1025
1021
  sheet,
1022
+ copy,
1026
1023
  onApply,
1027
1024
  onCancel,
1028
1025
  dataTestId
@@ -1035,11 +1032,13 @@ function CategoryPanel({
1035
1032
  function PinnedTray({
1036
1033
  state,
1037
1034
  chips,
1038
- dataTestId
1035
+ dataTestId,
1036
+ copy
1039
1037
  }) {
1040
1038
  return /* @__PURE__ */ jsx7(
1041
1039
  CategoryPinnedTray,
1042
1040
  {
1041
+ copy,
1043
1042
  chips,
1044
1043
  onRemove: (chipId) => state.setDraft(removeChip(state.allGroups, chipId, state.draft)),
1045
1044
  dataTestId
@@ -1053,10 +1052,11 @@ function PanelFooter({
1053
1052
  sheet,
1054
1053
  onApply,
1055
1054
  onCancel,
1056
- dataTestId
1055
+ dataTestId,
1056
+ copy
1057
1057
  }) {
1058
1058
  if (single) {
1059
- return /* @__PURE__ */ jsx7(CategorySingleFoot, { sheet, onCancel, dataTestId });
1059
+ return /* @__PURE__ */ jsx7(CategorySingleFoot, { sheet, onCancel, dataTestId, copy });
1060
1060
  }
1061
1061
  return /* @__PURE__ */ jsx7(
1062
1062
  CategoryMultiFoot,
@@ -1064,6 +1064,7 @@ function PanelFooter({
1064
1064
  count: state.draft.size,
1065
1065
  changed,
1066
1066
  sheet,
1067
+ copy,
1067
1068
  onClear: () => state.setDraft(/* @__PURE__ */ new Set()),
1068
1069
  onApply,
1069
1070
  dataTestId
@@ -1125,7 +1126,8 @@ function CategoryTrigger({
1125
1126
  onOpen,
1126
1127
  onClear,
1127
1128
  triggerRef,
1128
- dataTestId
1129
+ dataTestId,
1130
+ copy
1129
1131
  }) {
1130
1132
  const hasSelection = Boolean(selectionLabel) || (count ?? 0) > 0;
1131
1133
  return /* @__PURE__ */ jsxs8(
@@ -1166,7 +1168,7 @@ function CategoryTrigger({
1166
1168
  component: "span",
1167
1169
  role: "button",
1168
1170
  tabIndex: 0,
1169
- "aria-label": "Limpar sele\xE7\xE3o",
1171
+ "aria-label": copy.clearSelection,
1170
1172
  "data-testid": `${dataTestId}-clear-trigger`,
1171
1173
  sx: triggerClearSx,
1172
1174
  onClick: (event) => {
@@ -1506,7 +1508,7 @@ function usePanelFocus(open, activeIndex, searchInputRef, listRef) {
1506
1508
  }, [activeIndex, listRef]);
1507
1509
  }
1508
1510
  function CategorySelect(props) {
1509
- const { options, label, error, onCreateCategory } = props;
1511
+ const { options, label, error, onCreateCategory, copy } = props;
1510
1512
  const {
1511
1513
  single,
1512
1514
  placeholder,
@@ -1536,6 +1538,7 @@ function CategorySelect(props) {
1536
1538
  /* @__PURE__ */ jsx10(
1537
1539
  CategoryTrigger,
1538
1540
  {
1541
+ copy,
1539
1542
  placeholder,
1540
1543
  selectionLabel: props.mode === "single" ? singleLabel(state.allGroups, props.value) : void 0,
1541
1544
  count: single ? void 0 : applied.length,
@@ -1558,6 +1561,7 @@ function CategorySelect(props) {
1558
1561
  children: /* @__PURE__ */ jsx10(
1559
1562
  CategoryPanel,
1560
1563
  {
1564
+ copy,
1561
1565
  state,
1562
1566
  chips,
1563
1567
  rowIds,
@@ -1595,4 +1599,4 @@ export {
1595
1599
  filterCategoryGroups,
1596
1600
  CategorySelect
1597
1601
  };
1598
- //# sourceMappingURL=chunk-R4TYXKDD.js.map
1602
+ //# sourceMappingURL=chunk-TPQRIPCN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/form/CategorySelect/CategorySelect.tsx","../src/components/form/CategorySelect/category-tree.ts","../src/components/form/CategorySelect/CategoryPanel.tsx","../src/components/form/CategorySelect/CategoryPanelFoot.tsx","../src/components/form/CategorySelect/CategorySelect.styles.ts","../src/components/form/CategorySelect/CategoryPanelHead.tsx","../src/components/form/CategorySelect/CategoryIcons.tsx","../src/components/form/CategorySelect/CategoryPanelList.tsx","../src/components/form/CategorySelect/CategoryRows.tsx","../src/components/form/CategorySelect/CategoryQuickActions.tsx","../src/components/form/CategorySelect/CategoryPanelSurface.tsx","../src/components/form/CategorySelect/CategoryTrigger.tsx","../src/components/form/CategorySelect/useCategoryCommit.ts","../src/components/form/CategorySelect/useCategoryKeyHandler.ts","../src/components/form/CategorySelect/category-keyboard.ts","../src/components/form/CategorySelect/useCategorySelect.ts"],"sourcesContent":["'use client';\n\nimport { useEffect, useMemo, useRef } from 'react';\nimport { useMediaQuery, useTheme } from '@mui/material';\n\nimport { summarizeSelection } from './category-tree';\nimport { CategoryPanel } from './CategoryPanel';\nimport { CategoryPanelSurface } from './CategoryPanelSurface';\nimport { CategoryTrigger } from './CategoryTrigger';\nimport { METRICS } from './CategorySelect.styles';\nimport type { CategoryGroup, CategorySelectProps } from './CategorySelect.types';\nimport { useCategoryCommit } from './useCategoryCommit';\nimport { useCategoryKeyHandler } from './useCategoryKeyHandler';\nimport { useCategorySelect } from './useCategorySelect';\nimport { FormControl, FormLabel, FormMessage } from '../Form';\n\n/** The applied selection, always as an array — the two modes differ in shape. */\nfunction appliedIds(props: CategorySelectProps): string[] {\n if (props.mode === 'single') return props.value ? [props.value] : [];\n return props.value;\n}\n\n/** True when the draft differs from what is already applied. */\nfunction draftChanged(draft: ReadonlySet<string>, applied: readonly string[]): boolean {\n return draft.size !== applied.length || applied.some((id) => !draft.has(id));\n}\n\n/** \"Pai › Filha\" for a chosen id, so the trigger carries its context. */\nfunction singleLabel(groups: CategoryGroup[], value: string | null): string | undefined {\n if (!value) return undefined;\n const asCategory = groups.find((group) => group.category.id === value);\n if (asCategory) return asCategory.category.name;\n const owner = groups.find((group) => group.subcategories.some((sub) => sub.id === value));\n const sub = owner?.subcategories.find((candidate) => candidate.id === value);\n return sub && owner ? `${owner.category.name} › ${sub.name}` : undefined;\n}\n\n/** The optional props, resolved once so the component body stays branch-free. */\ninterface ResolvedConfig {\n single: boolean;\n placeholder: string;\n disabled: boolean;\n loading: boolean;\n fullWidth: boolean;\n showCounts: boolean;\n allowParentSelection: boolean;\n dataTestId: string;\n}\n\nfunction resolveConfig(props: CategorySelectProps): ResolvedConfig {\n const single = props.mode === 'single';\n return {\n single,\n placeholder: props.placeholder ?? (single ? 'Mover para…' : 'Categoria'),\n disabled: props.disabled ?? false,\n loading: props.loading ?? false,\n fullWidth: props.fullWidth ?? false,\n showCounts: props.showCounts ?? false,\n allowParentSelection: props.allowParentSelection ?? false,\n dataTestId: props.dataTestId ?? 'category-select',\n };\n}\n\n/** Focus the search box on open, and keep the keyboard cursor in view. */\nfunction usePanelFocus(\n open: boolean,\n activeIndex: number,\n searchInputRef: React.RefObject<HTMLInputElement | null>,\n listRef: React.RefObject<HTMLDivElement | null>,\n): void {\n // The first thing an admin does with ten categories is type; focusing here\n // saves the extra click every single time the panel opens.\n useEffect(() => {\n if (!open) return undefined;\n const frame = requestAnimationFrame(() => searchInputRef.current?.focus());\n return () => cancelAnimationFrame(frame);\n }, [open, searchInputRef]);\n\n useEffect(() => {\n if (activeIndex < 0) return;\n const rows = listRef.current?.querySelectorAll('[role=\"option\"], [role=\"button\"]');\n rows?.[activeIndex]?.scrollIntoView({ block: 'nearest' });\n }, [activeIndex, listRef]);\n}\n\n/**\n * A hierarchical category picker: categories as the frame, subcategories as the\n * thing you choose.\n *\n * Two modes off one component. `multi` is the FILTER — ticks accumulate in a\n * draft and reach `onChange` only on Apply, so the list behind the panel does not\n * reload on every click. `single` is the \"move to…\" picker, where choosing a row\n * commits immediately because there is nothing to batch.\n *\n * The tree opens fully expanded: nothing a search could match is hidden behind a\n * disclosure. Selected categories pin above the list so they survive scrolling\n * and searching, search is accent-insensitive (`agua` finds `Águas`), and the\n * whole tree is keyboard-drivable — ↑↓ to move, → to open, ← to close, Space to\n * mark, Enter to apply, Esc to cancel.\n *\n * Under {@link METRICS.sheetBreakpoint} the panel becomes a bottom sheet, which\n * is the only way a 290px-tall list stays usable one-handed.\n */\nexport function CategorySelect(props: CategorySelectProps): React.JSX.Element {\n const { options, label, error, onCreateCategory, copy } = props;\n const {\n single,\n placeholder,\n disabled,\n loading,\n fullWidth,\n showCounts,\n allowParentSelection,\n dataTestId,\n } = resolveConfig(props);\n\n const theme = useTheme();\n const sheet = useMediaQuery(theme.breakpoints.down(METRICS.sheetBreakpoint));\n const applied = appliedIds(props);\n\n const state = useCategorySelect({ options, selected: applied });\n const searchInputRef = useRef<HTMLInputElement | null>(null);\n const listRef = useRef<HTMLDivElement | null>(null);\n usePanelFocus(state.open, state.activeIndex, searchInputRef, listRef);\n\n const chips = useMemo(\n () => summarizeSelection(state.allGroups, state.draft),\n [state.allGroups, state.draft],\n );\n const rowIds = useMemo(() => state.rows.map((row) => row.id), [state.rows]);\n\n const actions = useCategoryCommit({ props, state, single, allowParentSelection });\n const onKeyDown = useCategoryKeyHandler({ state, single, allowParentSelection, actions });\n\n return (\n <FormControl fullWidth={fullWidth} error={Boolean(error)}>\n {label && <FormLabel error={Boolean(error)}>{label}</FormLabel>}\n <CategoryTrigger copy={copy}\n placeholder={placeholder}\n selectionLabel={\n props.mode === 'single' ? singleLabel(state.allGroups, props.value) : undefined\n }\n count={single ? undefined : applied.length}\n open={state.open}\n disabled={disabled}\n fullWidth={fullWidth}\n onOpen={state.openPanel}\n onClear={applied.length > 0 ? actions.clearSelection : undefined}\n triggerRef={state.triggerRef}\n dataTestId={dataTestId}\n />\n <CategoryPanelSurface\n open={state.open}\n sheet={sheet}\n anchorEl={state.triggerRef.current}\n onClose={actions.cancel}\n >\n <CategoryPanel copy={copy}\n state={state}\n chips={chips}\n rowIds={rowIds}\n changed={draftChanged(state.draft, applied)}\n single={single}\n sheet={sheet}\n loading={loading}\n showCounts={showCounts}\n allowParentSelection={allowParentSelection}\n ariaLabel={label ?? placeholder}\n onKeyDown={onKeyDown}\n onActivateCategory={actions.activateCategory}\n onActivateSubcategory={actions.activateSubcategory}\n onApply={actions.commit}\n onCancel={actions.cancel}\n onCreateCategory={onCreateCategory}\n searchInputRef={searchInputRef}\n listRef={listRef}\n dataTestId={dataTestId}\n />\n </CategoryPanelSurface>\n {error && <FormMessage error dataTestId={`${dataTestId}-message`}>{error}</FormMessage>}\n </FormControl>\n );\n}\n","import type {\n CategoryGroup,\n CategorySelectionChip,\n CategorySelectOption,\n} from './CategorySelect.types';\n\n/**\n * Fold a string to its comparison form: no diacritics, lower case.\n *\n * Portuguese category names are full of them (\"Águas\", \"Cápsulas\", \"Grãos\"), and\n * an admin typing \"agua\" or \"graos\" on a hurried phone keyboard means the same\n * thing. Comparing folded forms on both sides makes the search accent-blind in\n * both directions.\n */\nexport function foldText(text: string): string {\n return text\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase();\n}\n\n/**\n * Group a flat `parentId` list into top level + children, preserving input order.\n *\n * An option whose `parentId` names no top-level row is promoted to top level\n * rather than dropped — a category is never invisible just because its parent\n * was filtered out of the payload, or because the tree is deeper than two levels.\n */\nexport function buildCategoryGroups(options: CategorySelectOption[]): CategoryGroup[] {\n const roots = options.filter((option) => !option.parentId);\n const rootIds = new Set(roots.map((root) => root.id));\n const groups = new Map<string, CategoryGroup>(\n roots.map((root) => [root.id, { category: root, subcategories: [] }]),\n );\n const orphans: CategoryGroup[] = [];\n\n options.forEach((option) => {\n if (!option.parentId) return;\n const parent = groups.get(option.parentId);\n if (parent) {\n parent.subcategories.push(option);\n return;\n }\n if (!rootIds.has(option.id)) orphans.push({ category: option, subcategories: [] });\n });\n\n return [...groups.values(), ...orphans];\n}\n\n/** Every selectable leaf id across all groups, in display order. */\nexport function collectLeafIds(groups: CategoryGroup[]): string[] {\n return groups.flatMap((group) =>\n group.subcategories.length > 0\n ? group.subcategories.map((sub) => sub.id)\n : [group.category.id],\n );\n}\n\n/** The leaves a category stands for — its subcategories, or itself when childless. */\nexport function leavesOf(group: CategoryGroup): string[] {\n return group.subcategories.length > 0\n ? group.subcategories.map((sub) => sub.id)\n : [group.category.id];\n}\n\nexport type CategoryCheckState = 'off' | 'partial' | 'on';\n\n/** Whether none, some, or all of a category's leaves are selected. */\nexport function categoryCheckState(\n group: CategoryGroup,\n selected: ReadonlySet<string>,\n): CategoryCheckState {\n const leaves = leavesOf(group);\n const hits = leaves.filter((id) => selected.has(id)).length;\n if (hits === 0) return 'off';\n return hits === leaves.length ? 'on' : 'partial';\n}\n\n/** Select every leaf of a category, or clear them all when already complete. */\nexport function toggleCategoryLeaves(\n group: CategoryGroup,\n selected: ReadonlySet<string>,\n): Set<string> {\n const next = new Set(selected);\n const leaves = leavesOf(group);\n const turningOff = categoryCheckState(group, selected) === 'on';\n leaves.forEach((id) => (turningOff ? next.delete(id) : next.add(id)));\n return next;\n}\n\n/** Add an id when absent, remove it when present. */\nexport function toggleLeaf(id: string, selected: ReadonlySet<string>): Set<string> {\n const next = new Set(selected);\n if (!next.delete(id)) next.add(id);\n return next;\n}\n\n/**\n * Collapse a raw id set into the chips a human reads: a category that is fully\n * selected becomes ONE chip bearing the category's name, rather than one chip\n * per subcategory — \"Bebidas\" instead of six drinks.\n */\nexport function summarizeSelection(\n groups: CategoryGroup[],\n selected: ReadonlySet<string>,\n): CategorySelectionChip[] {\n return groups.flatMap((group): CategorySelectionChip[] => {\n const state = categoryCheckState(group, selected);\n if (state === 'off') return [];\n if (state === 'on') {\n return [{ id: group.category.id, label: group.category.name, whole: true }];\n }\n return group.subcategories\n .filter((sub) => selected.has(sub.id))\n .map((sub) => ({ id: sub.id, label: sub.name, whole: false }));\n });\n}\n\n/**\n * Drop the leaves a chip stands for. A `whole` chip removes the whole category;\n * any other chip removes just that leaf.\n */\nexport function removeChip(\n groups: CategoryGroup[],\n chipId: string,\n selected: ReadonlySet<string>,\n): Set<string> {\n const next = new Set(selected);\n const group = groups.find((candidate) => candidate.category.id === chipId);\n if (group) {\n leavesOf(group).forEach((id) => next.delete(id));\n return next;\n }\n next.delete(chipId);\n return next;\n}\n\n/**\n * Search across BOTH levels, keeping every hit under its parent.\n *\n * A category that matches keeps all of its subcategories, so \"Bebidas\" shows the\n * whole group. A category that does not match keeps only the subcategories that\n * do — the hit still arrives with its parent visible above it, which is the\n * context that tells \"Massas\" (mercearia) from \"Massas\" (pratos principais).\n */\nexport function filterCategoryGroups(groups: CategoryGroup[], query: string): CategoryGroup[] {\n const needle = foldText(query.trim());\n if (!needle) return groups;\n return groups.flatMap((group) => {\n if (foldText(group.category.name).includes(needle)) return [group];\n const subcategories = group.subcategories.filter((sub) =>\n foldText(sub.name).includes(needle),\n );\n return subcategories.length > 0 ? [{ category: group.category, subcategories }] : [];\n });\n}\n\n/** A run of text, flagged when it is the part that matched the query. */\ninterface HighlightSegment {\n text: string;\n match: boolean;\n}\n\n/**\n * Split a label around the query hit so the view can mark it.\n *\n * Slicing uses indices from the FOLDED text but cuts the ORIGINAL, which is safe\n * because folding is per-character here: NFD-stripping combining marks and\n * lower-casing both preserve offsets for the scripts these names use.\n */\nexport function highlightSegments(text: string, query: string): HighlightSegment[] {\n const needle = foldText(query.trim());\n if (!needle) return [{ text, match: false }];\n const at = foldText(text).indexOf(needle);\n if (at < 0) return [{ text, match: false }];\n return [\n { text: text.slice(0, at), match: false },\n { text: text.slice(at, at + needle.length), match: true },\n { text: text.slice(at + needle.length), match: false },\n ].filter((segment) => segment.text.length > 0);\n}\n\n/** A flattened row, so keyboard navigation can walk what is actually on screen. */\nexport interface CategoryRowRef {\n kind: 'category' | 'subcategory';\n id: string;\n /** Owning category id — lets ← jump from a subcategory back to its parent. */\n parentId?: string;\n}\n\n/** The visible rows, in order, honouring which categories are expanded. */\nexport function flattenRows(\n groups: CategoryGroup[],\n isExpanded: (categoryId: string) => boolean,\n): CategoryRowRef[] {\n return groups.flatMap((group) => {\n const head: CategoryRowRef = { kind: 'category', id: group.category.id };\n if (!isExpanded(group.category.id)) return [head];\n return [\n head,\n ...group.subcategories.map(\n (sub): CategoryRowRef => ({\n kind: 'subcategory',\n id: sub.id,\n parentId: group.category.id,\n }),\n ),\n ];\n });\n}\n","'use client';\n\nimport type { CategorySelectCopy } from \"../../../copy\";\nimport { Box } from '@mui/material';\n\nimport { removeChip } from './category-tree';\nimport { CategoryMultiFoot, CategorySingleFoot } from './CategoryPanelFoot';\nimport { CategoryPanelHead, CategoryPinnedTray } from './CategoryPanelHead';\nimport { CategoryPanelList } from './CategoryPanelList';\nimport { CategoryQuickActions } from './CategoryQuickActions';\nimport { panelSx, sheetSx } from './CategorySelect.styles';\nimport type { CategoryGroup, CategorySelectionChip } from './CategorySelect.types';\nimport type { CategorySelectState } from './useCategorySelect';\n\nexport interface CategoryPanelProps {\n /** The words this panel renders. REQUIRED — no default copy. */\n copy: CategorySelectCopy;\n state: CategorySelectState;\n chips: CategorySelectionChip[];\n rowIds: string[];\n /** True when the applied selection differs from the draft. */\n changed: boolean;\n single: boolean;\n sheet: boolean;\n loading: boolean;\n showCounts: boolean;\n allowParentSelection: boolean;\n ariaLabel: string;\n onKeyDown: (event: React.KeyboardEvent) => void;\n onActivateCategory: (group: CategoryGroup) => void;\n onActivateSubcategory: (id: string) => void;\n onApply: () => void;\n onCancel: () => void;\n onCreateCategory?: () => void;\n searchInputRef: React.RefObject<HTMLInputElement | null>;\n listRef: React.RefObject<HTMLDivElement | null>;\n dataTestId: string;\n}\n\n/** Search + pinned selection + tree + footer, in the panel's own chrome. */\nexport function CategoryPanel({\n state,\n chips,\n rowIds,\n changed,\n single,\n sheet,\n loading,\n showCounts,\n allowParentSelection,\n ariaLabel,\n onKeyDown,\n onActivateCategory,\n onActivateSubcategory,\n onApply,\n onCancel,\n onCreateCategory,\n searchInputRef,\n listRef,\n dataTestId,\n copy,\n}: CategoryPanelProps): React.JSX.Element {\n return (\n <Box\n onKeyDown={onKeyDown}\n role=\"dialog\"\n aria-label={ariaLabel}\n data-testid={`${dataTestId}-panel`}\n sx={(theme) => ({ ...panelSx(theme), ...(sheet ? sheetSx(theme) : {}) })}\n >\n <CategoryPanelHead\n copy={copy}\n query={state.query}\n placeholder={single ? copy.search.placeholderSingle : copy.search.placeholderMulti}\n sheet={sheet}\n quickActions={\n single ? undefined : <CategoryQuickActions state={state} dataTestId={dataTestId} />\n }\n onQueryChange={state.setQuery}\n searchInputRef={searchInputRef}\n dataTestId={dataTestId}\n />\n {!single && !loading && (\n <PinnedTray state={state} chips={chips} dataTestId={dataTestId} copy={copy} />\n )}\n <CategoryPanelList copy={copy}\n groups={state.visibleGroups}\n query={state.query}\n draft={state.draft}\n rowIds={rowIds}\n activeIndex={state.activeIndex}\n sheet={sheet}\n single={single}\n loading={loading}\n showCounts={showCounts}\n allowParentSelection={allowParentSelection}\n isExpanded={state.isExpanded}\n onToggleExpanded={state.toggleExpanded}\n onActivateCategory={onActivateCategory}\n onActivateSubcategory={onActivateSubcategory}\n onClearQuery={() => state.setQuery('')}\n onCreateCategory={onCreateCategory}\n listRef={listRef}\n dataTestId={dataTestId}\n />\n <PanelFooter\n state={state}\n changed={changed}\n single={single}\n sheet={sheet}\n copy={copy}\n onApply={onApply}\n onCancel={onCancel}\n dataTestId={dataTestId}\n />\n </Box>\n );\n}\n\n/** The selected-category chips, wired to remove from the draft. */\nfunction PinnedTray({\n state,\n chips,\n dataTestId,\n copy,\n}: Pick<CategoryPanelProps, 'state' | 'chips' | 'dataTestId' | 'copy'>): React.JSX.Element {\n return (\n <CategoryPinnedTray\n copy={copy}\n chips={chips}\n onRemove={(chipId) => state.setDraft(removeChip(state.allGroups, chipId, state.draft))}\n dataTestId={dataTestId}\n />\n );\n}\n\n/** Whichever footer the mode calls for. */\nfunction PanelFooter({\n state,\n changed,\n single,\n sheet,\n onApply,\n onCancel,\n dataTestId,\n copy,\n}: Pick<\n CategoryPanelProps,\n 'state' | 'changed' | 'single' | 'sheet' | 'onApply' | 'onCancel' | 'dataTestId' | 'copy'\n>): React.JSX.Element {\n if (single) {\n return (\n <CategorySingleFoot sheet={sheet} onCancel={onCancel} dataTestId={dataTestId} copy={copy} />\n );\n }\n return (\n <CategoryMultiFoot\n count={state.draft.size}\n changed={changed}\n sheet={sheet}\n copy={copy}\n onClear={() => state.setDraft(new Set())}\n onApply={onApply}\n dataTestId={dataTestId}\n />\n );\n}\n","'use client';\n\nimport { Box, Button } from '@mui/material';\n\nimport type { CategorySelectCopy } from '../../../copy';\nimport { footerSx, METRICS } from './CategorySelect.styles';\n\nconst buttonSx = (sheet: boolean) =>\n ({\n height: sheet ? METRICS.sheetFooterButton : METRICS.footerButton,\n padding: '0 13px',\n borderRadius: '8px',\n fontSize: 12.5,\n fontWeight: 600,\n textTransform: 'none',\n minWidth: 0,\n }) as const;\n\ninterface MultiFootProps {\n count: number;\n /** False once the draft matches what is already applied — Apply becomes Close. */\n changed: boolean;\n sheet: boolean;\n onClear: () => void;\n onApply: () => void;\n dataTestId: string;\n copy: CategorySelectCopy;\n}\n\n/**\n * Multi-select footer: the running count, Clear, and the Apply that publishes\n * the draft. The primary button reads \"Fechar\" when nothing changed, so it never\n * promises an update it would not make.\n */\nexport function CategoryMultiFoot({\n count,\n changed,\n sheet,\n onClear,\n onApply,\n dataTestId,\n copy,\n}: MultiFootProps): React.JSX.Element {\n return (\n <Box sx={footerSx} data-testid={`${dataTestId}-footer`}>\n <Box component=\"span\" sx={{ fontSize: 12, color: 'text.secondary' }}>\n {copy.footer.selectedCount(count)}\n </Box>\n <Box sx={{ display: 'flex', gap: '6px' }}>\n <Button\n variant=\"outlined\"\n disabled={count === 0}\n sx={buttonSx(sheet)}\n onClick={onClear}\n data-testid={`${dataTestId}-clear`}\n >\n {copy.footer.clear}\n </Button>\n <Button\n variant=\"contained\"\n sx={buttonSx(sheet)}\n onClick={onApply}\n data-testid={`${dataTestId}-apply`}\n >\n {changed ? copy.footer.apply : copy.footer.close}\n </Button>\n </Box>\n </Box>\n );\n}\n\n/** Single-select footer: a hint and a way out. Picking a row commits directly. */\nexport function CategorySingleFoot({\n sheet,\n onCancel,\n dataTestId,\n copy,\n}: {\n sheet: boolean;\n onCancel: () => void;\n dataTestId: string;\n copy: CategorySelectCopy;\n}): React.JSX.Element {\n return (\n <Box sx={footerSx} data-testid={`${dataTestId}-footer`}>\n <Box component=\"span\" sx={{ fontSize: 12, color: 'text.secondary' }}>\n {copy.footer.singleHint}\n </Box>\n <Button\n variant=\"outlined\"\n sx={buttonSx(sheet)}\n onClick={onCancel}\n data-testid={`${dataTestId}-cancel`}\n >\n {copy.footer.cancel}\n </Button>\n </Box>\n );\n}\n","import { alpha, type CSSObject, type Theme } from '@mui/material';\n\n/**\n * The prototype's METRICS, verbatim.\n *\n * Every number here is lifted from the approved design and is intentionally\n * absolute rather than derived from `theme.spacing`: the design is specified on\n * a half-pixel type scale (13.5px rows, 1.5px checkbox borders) that an 8px\n * spacing grid cannot express without rounding the look away.\n *\n * COLOURS are the deliberate exception — they come from the theme, because a\n * tenant can white-label the palette (a hard-coded indigo would survive the\n * rebrand and the rest of the screen would not) and because the library ships a\n * dark mode. On the default light indigo theme the tokens below resolve to the\n * prototype's own values.\n */\nexport const METRICS = {\n triggerHeight: 38,\n triggerRadius: 10,\n panelWidth: 340,\n panelRadius: 14,\n listMaxHeight: 290,\n sheetListMaxHeight: 340,\n rowHeight: 36,\n sheetRowHeight: 42,\n rowRadius: 8,\n boxSize: 18,\n chevronButton: 22,\n footerButton: 32,\n sheetFooterButton: 38,\n /** Below this width the panel becomes a bottom sheet. */\n sheetBreakpoint: 480,\n} as const;\n\n/** Accent family, derived so a white-labelled palette carries through. */\nconst accent = (theme: Theme) => ({\n main: theme.palette.primary.main,\n ink: theme.palette.primary.dark,\n soft: alpha(theme.palette.primary.main, 0.08),\n edge: alpha(theme.palette.primary.main, 0.28),\n ring: alpha(theme.palette.primary.main, 0.15),\n});\n\n/** The closed control. `selected` swaps it to the accent-tinted \"has filter\" skin. */\nexport const triggerSx = (theme: Theme, selected: boolean, open: boolean): CSSObject => {\n const brand = accent(theme);\n return {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n height: METRICS.triggerHeight,\n padding: '0 10px 0 12px',\n borderRadius: `${METRICS.triggerRadius}px`,\n border: `1px solid ${open || selected ? brand.edge : theme.palette.divider}`,\n background: selected ? brand.soft : theme.palette.background.paper,\n color: selected ? brand.ink : theme.palette.text.primary,\n font: 'inherit',\n fontSize: 13,\n cursor: 'pointer',\n maxWidth: '100%',\n transition: 'border-color .12s, box-shadow .12s',\n boxShadow: open ? `0 0 0 3px ${brand.ring}` : 'none',\n '&:hover': { borderColor: open || selected ? brand.edge : theme.palette.text.disabled },\n '&:focus-visible': {\n outline: 'none',\n borderColor: brand.main,\n boxShadow: `0 0 0 3px ${alpha(brand.main, 0.18)}`,\n },\n '&:disabled': { opacity: 0.5, cursor: 'default' },\n };\n};\n\n/** The count pill inside the trigger. */\nexport const triggerCountSx = (theme: Theme): CSSObject => ({\n fontWeight: 600,\n fontSize: 11,\n lineHeight: 1,\n background: theme.palette.primary.main,\n color: theme.palette.primary.contrastText,\n borderRadius: '999px',\n padding: '3px 6px',\n minWidth: 18,\n textAlign: 'center',\n});\n\n/** The trigger's inline clear (×) and the chevron. */\nexport const triggerClearSx: CSSObject = {\n width: 20,\n height: 20,\n flex: '0 0 auto',\n border: 0,\n background: 'transparent',\n borderRadius: '5px',\n display: 'grid',\n placeItems: 'center',\n cursor: 'pointer',\n color: 'inherit',\n opacity: 0.6,\n padding: 0,\n '&:hover': { background: alpha('#000', 0.08), opacity: 1 },\n};\n\nexport const triggerChevronSx = (open: boolean): CSSObject => ({\n width: 14,\n height: 14,\n flex: '0 0 auto',\n opacity: 0.55,\n transition: 'transform .15s',\n transform: open ? 'rotate(180deg)' : 'none',\n});\n\n/** The floating panel. */\nexport const panelSx = (theme: Theme): CSSObject => ({\n width: METRICS.panelWidth,\n maxWidth: '100%',\n background: theme.palette.background.paper,\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: `${METRICS.panelRadius}px`,\n boxShadow: '0 1px 2px rgba(16,20,35,.05), 0 18px 40px -12px rgba(16,20,35,.28)',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n});\n\n/** Bottom-sheet skin, applied under {@link METRICS.sheetBreakpoint}. */\nexport const sheetSx = (theme: Theme): CSSObject => ({\n width: '100%',\n maxWidth: 'none',\n borderRadius: '18px 18px 0 0',\n borderBottom: 0,\n position: 'relative',\n paddingTop: '4px',\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n top: 7,\n left: '50%',\n transform: 'translateX(-50%)',\n width: 36,\n height: 4,\n borderRadius: '2px',\n background: theme.palette.divider,\n },\n});\n\nexport const panelHeadSx = (theme: Theme, sheet: boolean): CSSObject => ({\n padding: sheet ? '18px 10px 8px' : '10px 10px 8px',\n borderBottom: `1px solid ${theme.palette.divider}`,\n});\n\nexport const pinnedSx = (theme: Theme): CSSObject => ({\n padding: '9px 10px',\n borderBottom: `1px solid ${theme.palette.divider}`,\n background: alpha(theme.palette.primary.main, 0.03),\n});\n\nexport const pinnedLabelSx = (theme: Theme): CSSObject => ({\n fontWeight: 600,\n fontSize: 10,\n lineHeight: 1,\n letterSpacing: '.08em',\n textTransform: 'uppercase',\n color: theme.palette.text.secondary,\n marginBottom: '7px',\n});\n\nexport const chipWrapSx: CSSObject = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '5px',\n maxHeight: 74,\n overflow: 'auto',\n};\n\n/** A selected-category chip, in the pinned tray and the applied bar alike. */\nexport const chipSx = (theme: Theme): CSSObject => {\n const brand = accent(theme);\n return {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '5px',\n fontSize: 12,\n background: brand.soft,\n color: brand.ink,\n border: `1px solid ${brand.edge}`,\n borderRadius: '7px',\n padding: '3px 4px 3px 8px',\n '& button': {\n border: 0,\n background: 'transparent',\n color: 'inherit',\n cursor: 'pointer',\n padding: 0,\n width: 16,\n height: 16,\n borderRadius: '4px',\n display: 'grid',\n placeItems: 'center',\n opacity: 0.65,\n fontSize: 13,\n lineHeight: 1,\n '&:hover': { background: alpha(theme.palette.primary.main, 0.16), opacity: 1 },\n },\n };\n};\n\nexport const listSx = (sheet: boolean): CSSObject => ({\n overflow: 'auto',\n maxHeight: sheet ? METRICS.sheetListMaxHeight : METRICS.listMaxHeight,\n padding: '6px 6px 8px',\n scrollPadding: '8px 0',\n overscrollBehavior: 'contain',\n});\n\n/** A row. `active` is the KEYBOARD cursor — deliberately distinct from hover. */\nexport const rowSx = (theme: Theme, active: boolean, sheet: boolean): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '0 8px',\n height: sheet ? METRICS.sheetRowHeight : METRICS.rowHeight,\n borderRadius: `${METRICS.rowRadius}px`,\n cursor: 'pointer',\n userSelect: 'none',\n position: 'relative',\n width: '100%',\n border: 0,\n textAlign: 'left',\n font: 'inherit',\n background: active ? alpha(theme.palette.primary.main, 0.08) : 'transparent',\n boxShadow: active ? `inset 0 0 0 1px ${alpha(theme.palette.primary.main, 0.3)}` : 'none',\n '&:hover': {\n background: active\n ? alpha(theme.palette.primary.main, 0.08)\n : theme.palette.action.hover,\n },\n '&:focus-visible': { outline: `2px solid ${theme.palette.primary.main}`, outlineOffset: 1 },\n});\n\nexport const rowNameSx = (theme: Theme, isCategory: boolean): CSSObject => ({\n flex: 1,\n minWidth: 0,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n fontSize: 13.5,\n fontWeight: isCategory ? 600 : 450,\n color: isCategory ? theme.palette.text.primary : theme.palette.text.secondary,\n});\n\nexport const rowMetaSx = (theme: Theme, selected: boolean): CSSObject => ({\n font: '500 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace',\n color: selected ? theme.palette.primary.main : theme.palette.text.secondary,\n fontWeight: selected ? 600 : 500,\n flex: '0 0 auto',\n});\n\n/** The query hit inside a row label. */\nexport const markSx: CSSObject = {\n background: '#fff2a8',\n color: 'inherit',\n borderRadius: '2px',\n padding: '0 1px',\n};\n\nexport const chevronButtonSx = (theme: Theme, open: boolean): CSSObject => ({\n width: METRICS.chevronButton,\n height: METRICS.chevronButton,\n flex: '0 0 auto',\n border: 0,\n background: 'transparent',\n borderRadius: '6px',\n display: 'grid',\n placeItems: 'center',\n cursor: 'pointer',\n color: theme.palette.text.secondary,\n padding: 0,\n '&:hover': { background: theme.palette.action.hover, color: theme.palette.text.primary },\n '& svg': { width: 12, height: 12, transition: 'transform .15s', transform: open ? 'rotate(90deg)' : 'none' },\n});\n\n/** The tri-state checkbox: unchecked, checked, or the partial bar. */\nexport const checkboxSx = (theme: Theme, state: 'off' | 'partial' | 'on'): CSSObject => ({\n width: METRICS.boxSize,\n height: METRICS.boxSize,\n flex: '0 0 auto',\n border: `1.5px solid ${state === 'off' ? theme.palette.divider : theme.palette.primary.main}`,\n borderRadius: '5px',\n background: state === 'off' ? theme.palette.background.paper : theme.palette.primary.main,\n display: 'grid',\n placeItems: 'center',\n transition: 'background .1s, border-color .1s',\n '& svg': { width: 12, height: 12, color: theme.palette.primary.contrastText },\n});\n\n/** The partial bar drawn inside a half-selected checkbox. */\nexport const checkboxBarSx = (theme: Theme): CSSObject => ({\n width: 9,\n height: 2,\n background: theme.palette.primary.contrastText,\n borderRadius: '1px',\n});\n\nexport const radioSx = (theme: Theme, on: boolean): CSSObject => ({\n width: METRICS.boxSize,\n height: METRICS.boxSize,\n flex: '0 0 auto',\n borderRadius: '50%',\n background: theme.palette.background.paper,\n border: on\n ? `5.5px solid ${theme.palette.primary.main}`\n : `1.5px solid ${theme.palette.divider}`,\n boxSizing: 'border-box',\n});\n\nexport const sectionHeadSx = (theme: Theme): CSSObject => ({\n fontWeight: 600,\n fontSize: 10,\n lineHeight: 1,\n letterSpacing: '.08em',\n textTransform: 'uppercase',\n color: theme.palette.text.secondary,\n padding: '9px 8px 6px',\n});\n\nexport const footerSx = (theme: Theme): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '8px',\n padding: '9px 10px',\n borderTop: `1px solid ${theme.palette.divider}`,\n background: theme.palette.action.hover,\n});\n\nexport const emptySx = (theme: Theme): CSSObject => ({\n padding: '26px 18px',\n textAlign: 'center',\n color: theme.palette.text.secondary,\n '& strong': {\n display: 'block',\n color: theme.palette.text.primary,\n fontSize: 13.5,\n marginBottom: '4px',\n },\n '& p': { margin: '0 0 12px', fontSize: 12.5, lineHeight: 1.5 },\n});\n\n/** Skeleton row used while the catalogue loads. */\nexport const skeletonSx: CSSObject = {\n height: METRICS.rowHeight,\n margin: '4px 6px',\n borderRadius: `${METRICS.rowRadius}px`,\n};\n","'use client';\n\nimport type { CategorySelectCopy } from '../../../copy';\nimport { Box, InputBase } from '@mui/material';\n\nimport { SearchGlyph } from './CategoryIcons';\nimport {\n chipSx,\n chipWrapSx,\n panelHeadSx,\n pinnedLabelSx,\n pinnedSx,\n} from './CategorySelect.styles';\nimport type { CategorySelectionChip } from './CategorySelect.types';\n\ninterface PanelHeadProps {\n query: string;\n placeholder: string;\n sheet: boolean;\n /** Quick actions belong to multi-select only; single-select has nothing to bulk-do. */\n quickActions?: React.ReactNode;\n onQueryChange: (next: string) => void;\n searchInputRef: React.RefObject<HTMLInputElement | null>;\n dataTestId: string;\n copy: CategorySelectCopy;\n}\n\nconst searchFieldSx = {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n '& input': {\n width: '100%',\n height: 36,\n padding: '0 30px 0 32px',\n fontSize: 13,\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: '9px',\n background: 'background.paper',\n color: 'text.primary',\n '&:focus': {\n outline: 'none',\n borderColor: 'primary.main',\n boxShadow: (theme: { palette: { primary: { main: string } } }) =>\n `0 0 0 3px ${theme.palette.primary.main}26`,\n },\n },\n} as const;\n\nconst clearButtonSx = {\n position: 'absolute',\n right: 7,\n width: 20,\n height: 20,\n border: 0,\n background: 'action.selected',\n color: 'text.secondary',\n borderRadius: '50%',\n display: 'grid',\n placeItems: 'center',\n cursor: 'pointer',\n fontSize: 12,\n padding: 0,\n lineHeight: 1,\n} as const;\n\n/** Search field, its clear affordance, and the optional quick-action row. */\nexport function CategoryPanelHead({\n query,\n placeholder,\n sheet,\n quickActions,\n onQueryChange,\n searchInputRef,\n dataTestId,\n copy,\n}: PanelHeadProps): React.JSX.Element {\n return (\n <Box sx={(theme) => panelHeadSx(theme, sheet)}>\n <Box sx={searchFieldSx}>\n <SearchGlyph\n style={{\n position: 'absolute',\n left: 10,\n width: 15,\n height: 15,\n opacity: 0.55,\n pointerEvents: 'none',\n }}\n />\n <InputBase\n inputRef={searchInputRef}\n value={query}\n placeholder={placeholder}\n autoComplete=\"off\"\n inputProps={{ 'aria-label': placeholder, 'data-testid': `${dataTestId}-search` }}\n onChange={(event) => onQueryChange(event.target.value)}\n sx={{ width: '100%' }}\n />\n {query.length > 0 && (\n <Box\n component=\"button\"\n type=\"button\"\n aria-label={copy.search.clear}\n data-testid={`${dataTestId}-search-clear`}\n sx={clearButtonSx}\n onClick={() => onQueryChange('')}\n >\n ×\n </Box>\n )}\n </Box>\n {quickActions && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n marginTop: '8px',\n fontSize: 12,\n }}\n >\n {quickActions}\n </Box>\n )}\n </Box>\n );\n}\n\ninterface PinnedTrayProps {\n chips: CategorySelectionChip[];\n onRemove: (chipId: string) => void;\n dataTestId: string;\n copy: CategorySelectCopy;\n}\n\n/**\n * The selected categories, pinned above the list.\n *\n * Pinned rather than left in place because a selection made at the bottom of a\n * ten-category tree scrolls out of sight the moment you look for the next one —\n * and a search hides it entirely. Here it survives both.\n */\nexport function CategoryPinnedTray({\n chips,\n onRemove,\n dataTestId,\n copy,\n}: PinnedTrayProps): React.JSX.Element | null {\n if (chips.length === 0) return null;\n return (\n <Box sx={pinnedSx} data-testid={`${dataTestId}-pinned`}>\n <Box sx={pinnedLabelSx}>{copy.search.pinnedLabel(chips.length)}</Box>\n <Box sx={chipWrapSx}>\n {chips.map((chip) => (\n <Box component=\"span\" key={chip.id} sx={chipSx}>\n {chip.label}\n <button\n type=\"button\"\n aria-label={copy.search.removeChip(chip.label)}\n data-testid={`${dataTestId}-unpin-${chip.id}`}\n onClick={() => onRemove(chip.id)}\n >\n ×\n </button>\n </Box>\n ))}\n </Box>\n </Box>\n );\n}\n","/**\n * The prototype's four glyphs, inlined.\n *\n * Inline SVG rather than `@mui/icons-material` because these are drawn at the\n * design's own weights (2.4 for the chevrons, 3.2 for the tick) and sizes; the\n * Material set is a 24px grid at a fixed weight and would not land on the same\n * pixels.\n */\n\nconst STROKE = {\n fill: 'none',\n stroke: 'currentColor',\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n} as const;\n\n/** The tick inside a checked box. */\nexport function CheckGlyph(): React.JSX.Element {\n return (\n <svg viewBox=\"0 0 24 24\" strokeWidth={3.2} aria-hidden=\"true\" {...STROKE}>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\n/** The disclosure chevron on a category row (points right; rotates when open). */\nexport function DisclosureGlyph(): React.JSX.Element {\n return (\n <svg viewBox=\"0 0 24 24\" strokeWidth={2.4} aria-hidden=\"true\" {...STROKE}>\n <path d=\"m9 5 7 7-7 7\" />\n </svg>\n );\n}\n\n/** The trigger's caret (points down; rotates when the panel is open). */\nexport function CaretGlyph({ style }: { style?: React.CSSProperties }): React.JSX.Element {\n return (\n <svg viewBox=\"0 0 24 24\" strokeWidth={2.4} style={style} aria-hidden=\"true\" {...STROKE}>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\n/** The magnifier in the panel's search field. */\nexport function SearchGlyph({ style }: { style?: React.CSSProperties }): React.JSX.Element {\n return (\n <svg viewBox=\"0 0 24 24\" strokeWidth={2} style={style} aria-hidden=\"true\" {...STROKE}>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </svg>\n );\n}\n","'use client';\n\nimport type { CategorySelectCopy } from \"../../../copy\";\nimport { Box, Button, Skeleton } from '@mui/material';\n\nimport { categoryCheckState } from './category-tree';\nimport {\n CategoryHeadRow,\n CategorySectionHeading,\n SubcategoryRow,\n} from './CategoryRows';\nimport { emptySx, listSx, skeletonSx } from './CategorySelect.styles';\nimport type { CategoryGroup } from './CategorySelect.types';\n\n/** The design sets these labels in sentence case, not MUI's default caps. */\nconst SENTENCE_CASE = { textTransform: 'none' } as const;\n\n/** How many skeleton rows stand in for the catalogue while it loads. */\nconst SKELETON_ROWS = 6;\n\ninterface PanelListProps {\n /** The words this panel renders. REQUIRED — no default copy. */\n copy: CategorySelectCopy;\n groups: CategoryGroup[];\n query: string;\n draft: ReadonlySet<string>;\n rowIds: string[];\n activeIndex: number;\n sheet: boolean;\n single: boolean;\n loading: boolean;\n showCounts: boolean;\n allowParentSelection: boolean;\n isExpanded: (categoryId: string) => boolean;\n onToggleExpanded: (categoryId: string) => void;\n onActivateCategory: (group: CategoryGroup) => void;\n onActivateSubcategory: (id: string) => void;\n onClearQuery: () => void;\n onCreateCategory?: (name?: string) => void;\n listRef: React.RefObject<HTMLDivElement | null>;\n dataTestId: string;\n}\n\nfunction LoadingRows(): React.JSX.Element {\n return (\n <>\n {Array.from({ length: SKELETON_ROWS }, (_unused, index) => (\n <Skeleton key={index} variant=\"rounded\" sx={skeletonSx} />\n ))}\n </>\n );\n}\n\n/** No categories exist at all — an onboarding moment, not an error. */\nfunction EmptyCatalogue({\n onCreateCategory,\n dataTestId,\n copy,\n}: {\n onCreateCategory?: (name?: string) => void;\n dataTestId: string;\n copy: CategorySelectCopy;\n}): React.JSX.Element {\n return (\n <Box sx={emptySx} data-testid={`${dataTestId}-empty-catalogue`}>\n <strong>{copy.emptyTitle}</strong>\n <p>{copy.purpose}</p>\n {onCreateCategory && (\n <Button variant=\"contained\" size=\"small\" sx={SENTENCE_CASE} onClick={() => onCreateCategory()}>\n {copy.createCategory}\n </Button>\n )}\n </Box>\n );\n}\n\n/** The search found nothing — offer creation, or the way back. */\nfunction NoResults({\n query,\n onClearQuery,\n onCreateCategory,\n dataTestId,\n copy,\n}: {\n query: string;\n onClearQuery: () => void;\n onCreateCategory?: (name?: string) => void;\n dataTestId: string;\n copy: CategorySelectCopy;\n}): React.JSX.Element {\n return (\n <Box sx={emptySx} data-testid={`${dataTestId}-no-results`}>\n <strong>{copy.noResults.title(query)}</strong>\n <p>{copy.noResults.hint}</p>\n <Box sx={{ display: 'flex', gap: '6px', justifyContent: 'center' }}>\n <Button variant=\"outlined\" size=\"small\" sx={SENTENCE_CASE} onClick={onClearQuery}>\n {copy.noResults.clearSearch}\n </Button>\n {onCreateCategory && (\n <Button\n variant=\"contained\"\n size=\"small\"\n sx={SENTENCE_CASE}\n data-testid={`${dataTestId}-create`}\n onClick={() => onCreateCategory(query.trim())}\n >\n {copy.noResults.create(query.trim())}\n </Button>\n )}\n </Box>\n </Box>\n );\n}\n\n/** One group: its heading or head row, then whichever children are visible. */\nfunction CategoryGroupRows({\n group,\n props,\n}: {\n group: CategoryGroup;\n props: PanelListProps;\n}): React.JSX.Element {\n const { draft, query, single, allowParentSelection, rowIds, activeIndex, sheet } = props;\n const categoryId = group.category.id;\n const expanded = props.isExpanded(categoryId);\n const asHeading = single && !allowParentSelection;\n const selectedCount = group.subcategories.filter((sub) => draft.has(sub.id)).length;\n\n return (\n <>\n {asHeading ? (\n <CategorySectionHeading option={group.category} query={query} />\n ) : (\n <CategoryHeadRow\n option={group.category}\n query={query}\n expanded={expanded}\n active={rowIds[activeIndex] === categoryId}\n sheet={sheet}\n checkState={\n allowParentSelection ? categoryCheckState(group, draft) : undefined\n }\n selectedCount={selectedCount}\n showCounts={props.showCounts}\n onToggleExpanded={() => props.onToggleExpanded(categoryId)}\n onActivate={() => props.onActivateCategory(group)}\n dataTestId={props.dataTestId}\n />\n )}\n {(expanded || asHeading) &&\n group.subcategories.map((sub) => (\n <SubcategoryRow\n key={sub.id}\n option={sub}\n query={query}\n selected={draft.has(sub.id)}\n active={rowIds[activeIndex] === sub.id}\n sheet={sheet}\n single={single}\n showCounts={props.showCounts}\n onActivate={() => props.onActivateSubcategory(sub.id)}\n dataTestId={props.dataTestId}\n />\n ))}\n </>\n );\n}\n\n/** The scrolling body of the panel, including its three non-list states. */\nexport function CategoryPanelList(props: PanelListProps): React.JSX.Element {\n const { groups, loading, query, listRef, sheet, dataTestId, copy } = props;\n\n const body = (): React.JSX.Element => {\n if (loading) return <LoadingRows />;\n if (groups.length === 0 && query.trim().length > 0) {\n return (\n <NoResults copy={copy}\n query={query}\n onClearQuery={props.onClearQuery}\n onCreateCategory={props.onCreateCategory}\n dataTestId={dataTestId}\n />\n );\n }\n if (groups.length === 0) {\n return (\n <EmptyCatalogue copy={copy}\n onCreateCategory={props.onCreateCategory}\n dataTestId={dataTestId}\n />\n );\n }\n return (\n <>\n {groups.map((group) => (\n <CategoryGroupRows key={group.category.id} group={group} props={props} />\n ))}\n </>\n );\n };\n\n return (\n <Box\n ref={listRef}\n role=\"listbox\"\n aria-multiselectable={props.single ? undefined : true}\n tabIndex={-1}\n data-testid={`${dataTestId}-list`}\n sx={listSx(sheet)}\n >\n {body()}\n </Box>\n );\n}\n","'use client';\n\nimport { Box } from '@mui/material';\n\nimport { CheckGlyph, DisclosureGlyph } from './CategoryIcons';\nimport { highlightSegments, type CategoryCheckState } from './category-tree';\nimport {\n checkboxBarSx,\n checkboxSx,\n chevronButtonSx,\n markSx,\n METRICS,\n radioSx,\n rowMetaSx,\n rowNameSx,\n rowSx,\n sectionHeadSx,\n} from './CategorySelect.styles';\nimport type { CategorySelectOption } from './CategorySelect.types';\n\n/** A label with the search hit marked. */\nexport function HighlightedName({\n text,\n query,\n}: {\n text: string;\n query: string;\n}): React.JSX.Element {\n const segments = highlightSegments(text, query);\n return (\n <>\n {segments.map((segment, index) =>\n segment.match ? (\n <Box component=\"mark\" key={`${segment.text}-${index}`} sx={markSx}>\n {segment.text}\n </Box>\n ) : (\n <span key={`${segment.text}-${index}`}>{segment.text}</span>\n ),\n )}\n </>\n );\n}\n\n/** Tri-state checkbox. `partial` draws the bar the prototype uses for \"some\". */\nexport function CategoryCheckbox({ state }: { state: CategoryCheckState }): React.JSX.Element {\n return (\n <Box sx={(theme) => checkboxSx(theme, state)} aria-hidden=\"true\">\n {state === 'on' && <CheckGlyph />}\n {state === 'partial' && <Box sx={checkboxBarSx} />}\n </Box>\n );\n}\n\nexport function CategoryRadio({ on }: { on: boolean }): React.JSX.Element {\n return <Box sx={(theme) => radioSx(theme, on)} aria-hidden=\"true\" />;\n}\n\ninterface CategoryHeadRowProps {\n option: CategorySelectOption;\n query: string;\n expanded: boolean;\n active: boolean;\n sheet: boolean;\n /** Absent in leaf-only mode, where the category is a heading with no checkbox. */\n checkState?: CategoryCheckState;\n selectedCount: number;\n showCounts: boolean;\n onToggleExpanded: () => void;\n onActivate: () => void;\n dataTestId: string;\n}\n\n/** The trailing number: how many children are picked, else the item count. */\nfunction rowMeta(\n selectedCount: number,\n showCounts: boolean,\n count: number | undefined,\n): { text: string; selected: boolean } | null {\n if (selectedCount > 0) return { text: String(selectedCount), selected: true };\n if (showCounts && count !== undefined) return { text: String(count), selected: false };\n return null;\n}\n\n/**\n * A top-level category row: disclosure chevron, optional checkbox, name, meta.\n *\n * The chevron is its OWN button inside the row button — clicking it only folds,\n * while clicking the row does the row's job (expand as a heading, or tick when\n * parents are selectable).\n */\nexport function CategoryHeadRow({\n option,\n query,\n expanded,\n active,\n sheet,\n checkState,\n selectedCount,\n showCounts,\n onToggleExpanded,\n onActivate,\n dataTestId,\n}: CategoryHeadRowProps): React.JSX.Element {\n const meta = rowMeta(selectedCount, showCounts, option.count);\n return (\n <Box\n component=\"div\"\n role={checkState ? 'option' : 'button'}\n aria-selected={checkState ? checkState === 'on' : undefined}\n aria-expanded={expanded}\n data-testid={`${dataTestId}-category-${option.id}`}\n sx={(theme) => rowSx(theme, active, sheet)}\n onClick={onActivate}\n >\n <Box\n component=\"button\"\n type=\"button\"\n tabIndex={-1}\n aria-label={`${expanded ? 'Recolher' : 'Expandir'} ${option.name}`}\n data-testid={`${dataTestId}-expand-${option.id}`}\n sx={(theme) => chevronButtonSx(theme, expanded)}\n onClick={(event: React.MouseEvent) => {\n event.stopPropagation();\n onToggleExpanded();\n }}\n >\n <DisclosureGlyph />\n </Box>\n {checkState ? (\n <CategoryCheckbox state={checkState} />\n ) : (\n <Box sx={{ width: METRICS.boxSize, flex: '0 0 auto' }} />\n )}\n <Box component=\"span\" sx={(theme) => rowNameSx(theme, true)}>\n <HighlightedName text={option.name} query={query} />\n </Box>\n {meta && (\n <Box component=\"span\" sx={(theme) => rowMetaSx(theme, meta.selected)}>\n {meta.text}\n </Box>\n )}\n </Box>\n );\n}\n\ninterface SubcategoryRowProps {\n option: CategorySelectOption;\n query: string;\n selected: boolean;\n active: boolean;\n sheet: boolean;\n /** Single-select mode draws a radio; multi-select draws a checkbox. */\n single: boolean;\n showCounts: boolean;\n onActivate: () => void;\n dataTestId: string;\n}\n\nexport function SubcategoryRow({\n option,\n query,\n selected,\n active,\n sheet,\n single,\n showCounts,\n onActivate,\n dataTestId,\n}: SubcategoryRowProps): React.JSX.Element {\n return (\n <Box\n component=\"div\"\n role=\"option\"\n aria-selected={selected}\n data-testid={`${dataTestId}-option-${option.id}`}\n sx={(theme) => ({ ...rowSx(theme, active, sheet), paddingLeft: '14px' })}\n onClick={onActivate}\n >\n <Box sx={{ width: METRICS.chevronButton, flex: '0 0 auto' }} />\n {single ? (\n <CategoryRadio on={selected} />\n ) : (\n <CategoryCheckbox state={selected ? 'on' : 'off'} />\n )}\n <Box component=\"span\" sx={(theme) => rowNameSx(theme, false)}>\n <HighlightedName text={option.name} query={query} />\n </Box>\n {showCounts && option.count !== undefined && (\n <Box component=\"span\" sx={(theme) => rowMetaSx(theme, false)}>\n {option.count}\n </Box>\n )}\n </Box>\n );\n}\n\n/** The category as a non-interactive heading (single-select, leaf-only). */\nexport function CategorySectionHeading({\n option,\n query,\n}: {\n option: CategorySelectOption;\n query: string;\n}): React.JSX.Element {\n return (\n <Box sx={sectionHeadSx}>\n <HighlightedName text={option.name} query={query} />\n </Box>\n );\n}\n","'use client';\n\nimport { Box } from '@mui/material';\nimport { useMemo } from 'react';\n\nimport { collectLeafIds } from './category-tree';\nimport type { CategorySelectState } from './useCategorySelect';\n\n/** The panel's text-button treatment. */\nconst linkButtonSx = {\n background: 'none',\n border: 0,\n padding: 0,\n font: 'inherit',\n fontSize: 12,\n color: 'primary.main',\n cursor: 'pointer',\n fontWeight: 550,\n '&:hover': { textDecoration: 'underline' },\n '&:disabled': { color: 'text.disabled', cursor: 'default', textDecoration: 'none' },\n} as const;\n\n/**\n * Bulk actions for multi-select: mark everything, and fold everything.\n *\n * Both labels flip to their inverse once the action is spent (\"Desmarcar tudo\",\n * \"Recolher tudo\"), so the control always says what pressing it will do rather\n * than what state the list is in.\n */\nexport function CategoryQuickActions({\n state,\n dataTestId,\n}: {\n state: CategorySelectState;\n dataTestId: string;\n}): React.JSX.Element {\n const allLeafIds = useMemo(() => collectLeafIds(state.allGroups), [state.allGroups]);\n const everythingPicked = allLeafIds.length > 0 && state.draft.size >= allLeafIds.length;\n const allExpanded =\n state.allGroups.length > 0 &&\n state.allGroups.every((group) => state.isExpanded(group.category.id));\n\n return (\n <>\n <Box\n component=\"button\"\n type=\"button\"\n disabled={allLeafIds.length === 0}\n data-testid={`${dataTestId}-select-all`}\n sx={linkButtonSx}\n onClick={() => state.setDraft(everythingPicked ? new Set() : new Set(allLeafIds))}\n >\n {everythingPicked ? 'Desmarcar tudo' : 'Marcar tudo'}\n </Box>\n <Box component=\"span\" sx={{ color: 'divider' }}>\n ·\n </Box>\n <Box\n component=\"button\"\n type=\"button\"\n data-testid={`${dataTestId}-expand-all`}\n sx={linkButtonSx}\n onClick={() => state.setAllExpanded(!allExpanded)}\n >\n {allExpanded ? 'Recolher tudo' : 'Expandir tudo'}\n </Box>\n </>\n );\n}\n","'use client';\n\nimport { Drawer, Popover } from '@mui/material';\n\nimport { stackedOverlayZIndex } from '../../../tokens/layers';\n\n/** Chrome-free surface props: the panel draws its own border and shadow. */\nconst BARE_PAPER = { background: 'transparent', boxShadow: 'none' } as const;\n\n/**\n * Both surfaces clear the sheet ladder rather than taking MUI's default.\n *\n * A `Popover` defaults to `zIndex.modal` and a temporary `Drawer` to\n * `zIndex.drawer`, one step lower still — and `StackedModal` gives its second\n * panel 1310. So this panel opened UNDER the sheet that opened it, and, being a\n * live modal with an unreachable backdrop, took the focus of every field around\n * it with no way to dismiss it (12-57). See `tokens/layers`.\n */\nconst ABOVE_SHEETS = { zIndex: stackedOverlayZIndex } as const;\n\ninterface SurfaceProps {\n open: boolean;\n /** True below the sheet breakpoint — anchor to the bottom edge instead. */\n sheet: boolean;\n anchorEl: HTMLElement | null;\n onClose: () => void;\n children: React.ReactNode;\n}\n\n/**\n * Where the panel lives: anchored under the trigger on a pointer, or a bottom\n * sheet on a phone.\n *\n * Both surfaces are modal, which is what gives the panel its dismiss-on-outside,\n * Esc handling and focus containment for free rather than hand-rolled.\n */\nexport function CategoryPanelSurface({\n open,\n sheet,\n anchorEl,\n onClose,\n children,\n}: SurfaceProps): React.JSX.Element {\n if (sheet) {\n return (\n <Drawer\n anchor=\"bottom\"\n open={open}\n onClose={onClose}\n sx={ABOVE_SHEETS}\n slotProps={{ paper: { sx: BARE_PAPER } }}\n >\n {children}\n </Drawer>\n );\n }\n return (\n <Popover\n open={open}\n anchorEl={anchorEl}\n onClose={onClose}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n marginThreshold={8}\n sx={ABOVE_SHEETS}\n slotProps={{ paper: { sx: { ...BARE_PAPER, marginTop: '6px', overflow: 'visible' } } }}\n >\n {children}\n </Popover>\n );\n}\n","'use client';\n\nimport type { CategorySelectCopy } from \"../../../copy\";\nimport { Box } from '@mui/material';\n\nimport { CaretGlyph } from './CategoryIcons';\nimport {\n triggerChevronSx,\n triggerClearSx,\n triggerCountSx,\n triggerSx,\n} from './CategorySelect.styles';\n\ninterface CategoryTriggerProps {\n /** The words this renders. REQUIRED — this package ships no default copy. */\n copy: CategorySelectCopy;\n /** Text shown when nothing is selected. */\n placeholder: string;\n /** Resolved label when there IS a selection (single mode shows \"Pai › Filha\"). */\n selectionLabel?: string;\n /** Selection size — rendered as the count pill in multi-select. */\n count?: number;\n open: boolean;\n disabled?: boolean;\n fullWidth: boolean;\n onOpen: () => void;\n /** Absent when there is nothing to clear. */\n onClear?: () => void;\n triggerRef: React.RefObject<HTMLButtonElement | null>;\n dataTestId: string;\n}\n\n/**\n * The closed control.\n *\n * The clear (×) is a real button nested in the trigger button, so \"remove the\n * filter\" is one click from the closed state — without it, clearing means open,\n * find Clear, apply. Its click is stopped from reaching the trigger, which would\n * otherwise open the panel on the way out.\n */\nexport function CategoryTrigger({\n placeholder,\n selectionLabel,\n count,\n open,\n disabled,\n fullWidth,\n onOpen,\n onClear,\n triggerRef,\n dataTestId,\n copy,\n}: CategoryTriggerProps): React.JSX.Element {\n const hasSelection = Boolean(selectionLabel) || (count ?? 0) > 0;\n return (\n <Box\n component=\"button\"\n type=\"button\"\n ref={triggerRef}\n disabled={disabled}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n data-testid={`${dataTestId}-trigger`}\n onClick={onOpen}\n sx={(theme) => ({\n ...triggerSx(theme, hasSelection, open),\n width: fullWidth ? '100%' : 'auto',\n })}\n >\n <Box\n component=\"span\"\n sx={{\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n maxWidth: 190,\n flex: fullWidth ? 1 : '0 1 auto',\n textAlign: 'left',\n }}\n >\n {selectionLabel ?? placeholder}\n </Box>\n {count !== undefined && count > 0 && (\n <Box component=\"span\" sx={triggerCountSx} data-testid={`${dataTestId}-count`}>\n {count}\n </Box>\n )}\n {hasSelection && onClear && (\n <Box\n component=\"span\"\n role=\"button\"\n tabIndex={0}\n aria-label={copy.clearSelection}\n data-testid={`${dataTestId}-clear-trigger`}\n sx={triggerClearSx}\n onClick={(event: React.MouseEvent) => {\n event.stopPropagation();\n onClear();\n }}\n onKeyDown={(event: React.KeyboardEvent) => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n event.stopPropagation();\n onClear();\n }}\n >\n ×\n </Box>\n )}\n <CaretGlyph style={triggerChevronSx(open) as React.CSSProperties} />\n </Box>\n );\n}\n","import { useCallback, useMemo } from 'react';\n\nimport type { CategoryGroup, CategorySelectProps } from './CategorySelect.types';\nimport type { CategorySelectState } from './useCategorySelect';\n\n/** The verbs a row, a footer button or a key press can invoke. */\nexport interface CategoryActions {\n /** Publish the draft to the caller and close (multi-select). */\n commit: () => void;\n /** Choose one id and close (single-select). */\n pick: (id: string) => void;\n /** Close without publishing, returning focus to the trigger. */\n cancel: () => void;\n /** Empty the APPLIED selection straight from the closed trigger. */\n clearSelection: () => void;\n activateCategory: (group: CategoryGroup) => void;\n activateSubcategory: (id: string) => void;\n}\n\ninterface UseCategoryCommitArgs {\n props: CategorySelectProps;\n state: CategorySelectState;\n single: boolean;\n allowParentSelection: boolean;\n}\n\n/**\n * The commit semantics, which are the one thing the two modes genuinely differ\n * on: multi-select batches into a draft and publishes on Apply, single-select\n * publishes the moment a row is chosen.\n */\nexport function useCategoryCommit({\n props,\n state,\n single,\n allowParentSelection,\n}: UseCategoryCommitArgs): CategoryActions {\n const { closePanel, triggerRef, toggleCategory, toggleSubcategory, toggleExpanded } = state;\n\n const closeAndRefocus = useCallback(() => {\n closePanel();\n triggerRef.current?.focus();\n }, [closePanel, triggerRef]);\n\n const commit = useCallback(() => {\n if (props.mode === 'single') return;\n props.onChange([...state.draft]);\n closeAndRefocus();\n }, [props, state.draft, closeAndRefocus]);\n\n const pick = useCallback(\n (id: string) => {\n if (props.mode !== 'single') return;\n props.onChange(id);\n closeAndRefocus();\n },\n [props, closeAndRefocus],\n );\n\n const clearSelection = useCallback(() => {\n if (props.mode === 'single') props.onChange(null);\n else props.onChange([]);\n }, [props]);\n\n // A category row means different things per mode: pick the whole category,\n // tick all its leaves, or — when it is only a heading — just fold it.\n const activateCategory = useCallback(\n (group: CategoryGroup) => {\n if (allowParentSelection && single) {\n pick(group.category.id);\n return;\n }\n if (allowParentSelection) {\n toggleCategory(group);\n return;\n }\n toggleExpanded(group.category.id);\n },\n [allowParentSelection, single, pick, toggleCategory, toggleExpanded],\n );\n\n const activateSubcategory = useCallback(\n (id: string) => {\n if (single) pick(id);\n else toggleSubcategory(id);\n },\n [single, pick, toggleSubcategory],\n );\n\n return useMemo(\n () => ({\n commit,\n pick,\n cancel: closeAndRefocus,\n clearSelection,\n activateCategory,\n activateSubcategory,\n }),\n [commit, pick, closeAndRefocus, clearSelection, activateCategory, activateSubcategory],\n );\n}\n","import { useCallback } from 'react';\n\nimport { handleCategoryKeyDown } from './category-keyboard';\nimport type { CategoryActions } from './useCategoryCommit';\nimport type { CategorySelectState } from './useCategorySelect';\n\ninterface UseCategoryKeyHandlerArgs {\n state: CategorySelectState;\n single: boolean;\n allowParentSelection: boolean;\n actions: CategoryActions;\n}\n\n/**\n * Bind the panel's keydown to the tree navigator.\n *\n * `preventDefault` fires only for keys the navigator actually consumed, so an\n * unhandled key still reaches the search box — otherwise typing would be dead.\n */\nexport function useCategoryKeyHandler({\n state,\n single,\n allowParentSelection,\n actions,\n}: UseCategoryKeyHandlerArgs): (event: React.KeyboardEvent) => void {\n const { isExpanded, toggleExpanded } = state;\n\n const expand = useCallback(\n (id: string) => {\n if (!isExpanded(id)) toggleExpanded(id);\n },\n [isExpanded, toggleExpanded],\n );\n\n const collapse = useCallback(\n (id: string) => {\n if (isExpanded(id)) toggleExpanded(id);\n },\n [isExpanded, toggleExpanded],\n );\n\n return useCallback(\n (event: React.KeyboardEvent) => {\n const inSearchField = (event.target as HTMLElement | null)?.tagName === 'INPUT';\n const editingText = inSearchField && state.query.length > 0;\n const consumed = handleCategoryKeyDown(event.key, editingText, {\n rows: state.rows,\n activeIndex: state.activeIndex,\n groups: state.visibleGroups,\n single,\n allowParentSelection,\n setActiveIndex: state.setActiveIndex,\n toggleExpanded,\n expand,\n collapse,\n toggleCategory: state.toggleCategory,\n toggleSubcategory: state.toggleSubcategory,\n commit: actions.commit,\n cancel: actions.cancel,\n pick: actions.pick,\n });\n if (consumed) event.preventDefault();\n },\n [state, single, allowParentSelection, toggleExpanded, expand, collapse, actions],\n );\n}\n","import type { CategoryRowRef } from './category-tree';\nimport type { CategoryGroup } from './CategorySelect.types';\n\n/** What a key handler is allowed to do to the panel. */\nexport interface CategoryKeyContext {\n rows: CategoryRowRef[];\n activeIndex: number;\n groups: CategoryGroup[];\n /** Single-select mode picks on Enter/Space instead of toggling a draft. */\n single: boolean;\n /** Categories are headings, not checkboxes, unless parents are selectable. */\n allowParentSelection: boolean;\n setActiveIndex: (next: number) => void;\n toggleExpanded: (categoryId: string) => void;\n expand: (categoryId: string) => void;\n collapse: (categoryId: string) => void;\n toggleCategory: (group: CategoryGroup) => void;\n toggleSubcategory: (id: string) => void;\n commit: () => void;\n cancel: () => void;\n pick: (id: string) => void;\n}\n\n/** The row under the keyboard cursor, if the cursor is on one. */\nfunction activeRow(context: CategoryKeyContext): CategoryRowRef | undefined {\n return context.activeIndex >= 0 ? context.rows[context.activeIndex] : undefined;\n}\n\nfunction groupOf(context: CategoryKeyContext, id: string): CategoryGroup | undefined {\n return context.groups.find((group) => group.category.id === id);\n}\n\nfunction moveCursor(context: CategoryKeyContext, delta: number): void {\n const { rows, activeIndex } = context;\n if (rows.length === 0) return;\n const next =\n delta > 0\n ? Math.min(rows.length - 1, activeIndex + 1)\n : Math.max(0, activeIndex - 1);\n context.setActiveIndex(next);\n}\n\n/** → opens a category. On a subcategory it is a no-op: there is nothing deeper. */\nfunction handleRight(context: CategoryKeyContext): void {\n const row = activeRow(context);\n if (row?.kind === 'category') context.expand(row.id);\n}\n\n/** ← collapses a category, or walks a subcategory back up to its parent. */\nfunction handleLeft(context: CategoryKeyContext): void {\n const row = activeRow(context);\n if (!row) return;\n if (row.kind === 'category') {\n context.collapse(row.id);\n return;\n }\n if (!row.parentId) return;\n context.collapse(row.parentId);\n const parentIndex = context.rows.findIndex(\n (candidate) => candidate.kind === 'category' && candidate.id === row.parentId,\n );\n if (parentIndex >= 0) context.setActiveIndex(parentIndex);\n}\n\n/**\n * Space marks. On a category that is only a HEADING it expands instead — the\n * row has no checkbox, so \"mark\" has nothing to mean there.\n */\nfunction handleSpace(context: CategoryKeyContext): void {\n const row = activeRow(context);\n if (!row) return;\n if (context.single) {\n context.pick(row.id);\n return;\n }\n if (row.kind === 'subcategory') {\n context.toggleSubcategory(row.id);\n return;\n }\n const group = groupOf(context, row.id);\n if (!group) return;\n if (context.allowParentSelection) context.toggleCategory(group);\n else context.toggleExpanded(row.id);\n}\n\nfunction handleEnter(context: CategoryKeyContext): void {\n const row = activeRow(context);\n if (context.single) {\n if (row) context.pick(row.id);\n return;\n }\n context.commit();\n}\n\n/** Key → behaviour. A map keeps this dispatch flat instead of a long if-chain. */\nconst HANDLERS: Record<string, (context: CategoryKeyContext) => void> = {\n ArrowDown: (context) => moveCursor(context, 1),\n ArrowUp: (context) => moveCursor(context, -1),\n ArrowRight: handleRight,\n ArrowLeft: handleLeft,\n ' ': handleSpace,\n Enter: handleEnter,\n Escape: (context) => context.cancel(),\n};\n\n/**\n * Keys the SEARCH BOX has a claim on: Space types a space, and the horizontal\n * arrows move the caret.\n *\n * They are only yielded while the field actually holds text. The panel opens\n * with focus in an EMPTY search box, so yielding unconditionally — as the\n * prototype does — would make Space and ←/→ dead on arrival for anyone driving\n * the tree from the keyboard, which is most of the point of having it. With no\n * text there is no caret to move and no word to space, so the tree takes them;\n * type one character and they revert to the field.\n */\nconst TEXT_ENTRY_KEYS = new Set([' ', 'ArrowLeft', 'ArrowRight']);\n\n/**\n * Drive the tree from the keyboard.\n *\n * Returns `true` when the key was consumed, so the caller can `preventDefault`\n * only for keys this actually handled — an unhandled key must still reach the\n * search input untouched.\n */\nexport function handleCategoryKeyDown(\n key: string,\n editingSearchText: boolean,\n context: CategoryKeyContext,\n): boolean {\n if (editingSearchText && TEXT_ENTRY_KEYS.has(key)) return false;\n const handler = HANDLERS[key];\n if (!handler) return false;\n handler(context);\n return true;\n}\n","import { useCallback, useMemo, useRef, useState } from 'react';\n\nimport {\n buildCategoryGroups,\n filterCategoryGroups,\n flattenRows,\n toggleCategoryLeaves,\n toggleLeaf,\n type CategoryRowRef,\n} from './category-tree';\nimport type { CategoryGroup, CategorySelectOption } from './CategorySelect.types';\n\n/** Which categories are unfolded, and the ways that set changes. */\ninterface ExpansionState {\n isExpanded: (categoryId: string) => boolean;\n toggleExpanded: (categoryId: string) => void;\n setAllExpanded: (expanded: boolean) => void;\n expandAll: (groups: CategoryGroup[]) => void;\n}\n\n/**\n * The expanded set.\n *\n * `searching` short-circuits the lookup instead of mutating the set: a query must\n * reveal every hit, but clearing it has to restore whatever the admin had folded,\n * which an overwrite would have destroyed.\n */\nfunction useExpandedCategories(\n allGroups: CategoryGroup[],\n searching: boolean,\n): ExpansionState {\n const [expanded, setExpanded] = useState<ReadonlySet<string>>(() => new Set());\n\n const isExpanded = useCallback(\n (categoryId: string) => searching || expanded.has(categoryId),\n [searching, expanded],\n );\n\n const toggleExpanded = useCallback((categoryId: string) => {\n setExpanded((current) => {\n const next = new Set(current);\n if (!next.delete(categoryId)) next.add(categoryId);\n return next;\n });\n }, []);\n\n const setAllExpanded = useCallback(\n (shouldExpand: boolean) => {\n setExpanded(shouldExpand ? new Set(allGroups.map((g) => g.category.id)) : new Set());\n },\n [allGroups],\n );\n\n const expandAll = useCallback((groups: CategoryGroup[]) => {\n setExpanded(new Set(groups.map((group) => group.category.id)));\n }, []);\n\n return { isExpanded, toggleExpanded, setAllExpanded, expandAll };\n}\n\n/** The pending selection and the two ways a row changes it. */\ninterface DraftState {\n draft: ReadonlySet<string>;\n setDraft: (next: ReadonlySet<string>) => void;\n toggleCategory: (group: CategoryGroup) => void;\n toggleSubcategory: (id: string) => void;\n}\n\nfunction useDraftSelection(initial: readonly string[]): DraftState {\n const [draft, setDraftState] = useState<ReadonlySet<string>>(() => new Set(initial));\n\n const toggleCategory = useCallback((group: CategoryGroup) => {\n setDraftState((current) => toggleCategoryLeaves(group, current));\n }, []);\n\n const toggleSubcategory = useCallback((id: string) => {\n setDraftState((current) => toggleLeaf(id, current));\n }, []);\n\n const setDraft = useCallback((next: ReadonlySet<string>) => setDraftState(next), []);\n\n return { draft, setDraft, toggleCategory, toggleSubcategory };\n}\n\n/** Everything the panel and trigger need to render and drive one select. */\nexport interface CategorySelectState extends ExpansionState, DraftState {\n open: boolean;\n query: string;\n /** Groups after the search filter — what is actually on screen. */\n visibleGroups: CategoryGroup[];\n /** All groups, unfiltered — the basis for chips and \"select all\". */\n allGroups: CategoryGroup[];\n rows: CategoryRowRef[];\n activeIndex: number;\n setQuery: (next: string) => void;\n setActiveIndex: (next: number) => void;\n openPanel: () => void;\n closePanel: () => void;\n triggerRef: React.RefObject<HTMLButtonElement | null>;\n}\n\ninterface UseCategorySelectArgs {\n options: CategorySelectOption[];\n /** The applied selection to seed the draft from each time the panel opens. */\n selected: readonly string[];\n}\n\n/**\n * Panel state for one CategorySelect.\n *\n * The DRAFT is the load-bearing idea. Ticks land here, not on the caller's\n * `value`, so the list behind the panel does not refetch on every click; Apply\n * publishes, dismissing discards. Opening re-seeds the draft from the applied\n * value, which is what makes \"cancel\" mean cancel.\n */\nexport function useCategorySelect({\n options,\n selected,\n}: UseCategorySelectArgs): CategorySelectState {\n const [open, setOpen] = useState(false);\n const [query, setQueryState] = useState('');\n const [activeIndex, setActiveIndex] = useState(-1);\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n\n const allGroups = useMemo(() => buildCategoryGroups(options), [options]);\n const visibleGroups = useMemo(\n () => filterCategoryGroups(allGroups, query),\n [allGroups, query],\n );\n\n const expansion = useExpandedCategories(allGroups, query.trim().length > 0);\n const selection = useDraftSelection(selected);\n const rows = useMemo(\n () => flattenRows(visibleGroups, expansion.isExpanded),\n [visibleGroups, expansion.isExpanded],\n );\n\n const openPanel = useCallback(() => {\n selection.setDraft(new Set(selected));\n expansion.expandAll(allGroups);\n setQueryState('');\n setActiveIndex(-1);\n setOpen(true);\n }, [selected, allGroups, selection, expansion]);\n\n const closePanel = useCallback(() => {\n setOpen(false);\n setQueryState('');\n setActiveIndex(-1);\n }, []);\n\n const setQuery = useCallback((next: string) => {\n setQueryState(next);\n setActiveIndex(-1);\n }, []);\n\n return {\n ...expansion,\n ...selection,\n open,\n query,\n visibleGroups,\n allGroups,\n rows,\n activeIndex,\n setQuery,\n setActiveIndex,\n openPanel,\n closePanel,\n triggerRef,\n };\n}\n"],"mappings":"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","names":["useMemo","useRef","Box","Box","jsx","jsxs","jsx","jsxs","Box","Box","Button","Box","jsx","jsxs","Box","Fragment","jsx","jsxs","Box","Button","Box","Fragment","jsx","jsxs","Box","jsx","jsxs","Box","jsx","Box","jsx","jsxs","Box","useMemo","useCallback","useCallback","useCallback","useMemo","useCallback","useMemo","jsx","jsxs","sub","useRef","useMemo"]}