@12-apps/ui 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/{chunk-MXPXKORR.js → chunk-5TCPZ6GR.js} +8 -6
  2. package/dist/chunk-5TCPZ6GR.js.map +1 -0
  3. package/dist/{chunk-R5ZQZSEQ.js → chunk-NUCLEOHF.js} +12 -6
  4. package/dist/chunk-NUCLEOHF.js.map +1 -0
  5. package/dist/{chunk-TPQRIPCN.js → chunk-ZF5ERIC4.js} +7 -6
  6. package/dist/chunk-ZF5ERIC4.js.map +1 -0
  7. package/dist/data-display/CardKit.js +1 -1
  8. package/dist/data-display/DataViews.js +28 -22
  9. package/dist/data-display/DataViews.js.map +1 -1
  10. package/dist/feedback/ConfirmAction.js +1 -1
  11. package/dist/form/CategorySelect.js +1 -1
  12. package/dist/form/CreatableSelect.js +1 -1
  13. package/dist/form/CreatableSelect.js.map +1 -1
  14. package/dist/form/SearchPalette.js +3 -4
  15. package/dist/form/SearchPalette.js.map +1 -1
  16. package/dist/form/total-form.js +1 -1
  17. package/dist/layout/ContentToolbar.js +1 -1
  18. package/dist/pt-BR.js +23 -4
  19. package/dist/pt-BR.js.map +1 -1
  20. package/dist/types/components/data-display/DataViews/DataViewsBoard.d.ts.map +1 -1
  21. package/dist/types/components/data-display/DataViews/data-views-category-pill.d.ts.map +1 -1
  22. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +38 -1
  23. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -1
  24. package/dist/types/components/data-display/DataViews/data-views-empty.d.ts.map +1 -1
  25. package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
  26. package/dist/types/components/data-display/DataViews/data-views-more-filters.d.ts.map +1 -1
  27. package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts.map +1 -1
  28. package/dist/types/components/data-display/DataViews/data-views-toolbar.d.ts.map +1 -1
  29. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.parts.d.ts.map +1 -1
  30. package/dist/types/components/form/CategorySelect/CategoryQuickActions.d.ts +4 -1
  31. package/dist/types/components/form/CategorySelect/CategoryQuickActions.d.ts.map +1 -1
  32. package/dist/types/components/form/CreatableSelect/CreatableSelect.d.ts.map +1 -1
  33. package/dist/types/components/form/CreatableSelect/CreatableSelect.types.d.ts +2 -1
  34. package/dist/types/components/form/CreatableSelect/CreatableSelect.types.d.ts.map +1 -1
  35. package/dist/types/components/form/SearchPalette/SearchPalette.d.ts.map +1 -1
  36. package/dist/types/components/form/SearchPalette/SearchPalette.types.d.ts +3 -3
  37. package/dist/types/components/form/SearchPalette/SearchPalette.types.d.ts.map +1 -1
  38. package/dist/types/components/layout/ContentToolbar/ContentToolbar.d.ts +1 -1
  39. package/dist/types/components/layout/ContentToolbar/ContentToolbar.d.ts.map +1 -1
  40. package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts +12 -0
  41. package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts.map +1 -1
  42. package/dist/types/components/layout/ContentToolbar/MultiSelectDropdown.d.ts +1 -1
  43. package/dist/types/components/layout/ContentToolbar/MultiSelectDropdown.d.ts.map +1 -1
  44. package/dist/types/components/layout/ContentToolbar/MultiSelectTriggers.d.ts +10 -2
  45. package/dist/types/components/layout/ContentToolbar/MultiSelectTriggers.d.ts.map +1 -1
  46. package/dist/types/copy.d.ts +22 -0
  47. package/dist/types/copy.d.ts.map +1 -1
  48. package/dist/types/pt-BR.d.ts.map +1 -1
  49. package/package.json +1 -1
  50. package/src/components/data-display/DataViews/DataViewsBoard.tsx +2 -1
  51. package/src/components/data-display/DataViews/DeleteViewDialog.tsx +2 -2
  52. package/src/components/data-display/DataViews/ManageViewsDialog.tsx +1 -1
  53. package/src/components/data-display/DataViews/data-views-category-pill.tsx +1 -0
  54. package/src/components/data-display/DataViews/data-views-columns-tab.tsx +4 -3
  55. package/src/components/data-display/DataViews/data-views-copy.ts +38 -1
  56. package/src/components/data-display/DataViews/data-views-empty.tsx +6 -3
  57. package/src/components/data-display/DataViews/data-views-more-fields.tsx +3 -1
  58. package/src/components/data-display/DataViews/data-views-more-filters.tsx +2 -1
  59. package/src/components/data-display/DataViews/data-views-range-pill.tsx +2 -1
  60. package/src/components/data-display/DataViews/data-views-toolbar.tsx +3 -0
  61. package/src/components/data-display/DataViews/data-views-view-nav.tsx +2 -2
  62. package/src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx +14 -3
  63. package/src/components/form/CategorySelect/CategoryPanel.tsx +1 -1
  64. package/src/components/form/CategorySelect/CategoryQuickActions.tsx +7 -2
  65. package/src/components/form/CategorySelect/CategorySelect.tsx +1 -1
  66. package/src/components/form/CreatableSelect/CreatableSelect.md +2 -2
  67. package/src/components/form/CreatableSelect/CreatableSelect.tsx +1 -1
  68. package/src/components/form/CreatableSelect/CreatableSelect.types.ts +2 -1
  69. package/src/components/form/SearchPalette/SearchPalette.tsx +3 -4
  70. package/src/components/form/SearchPalette/SearchPalette.types.ts +3 -3
  71. package/src/components/layout/ContentToolbar/ContentToolbar.tsx +13 -2
  72. package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +12 -0
  73. package/src/components/layout/ContentToolbar/MultiSelectDropdown.tsx +2 -0
  74. package/src/components/layout/ContentToolbar/MultiSelectTriggers.tsx +15 -2
  75. package/src/copy.ts +22 -0
  76. package/src/pt-BR.ts +19 -0
  77. package/dist/chunk-MXPXKORR.js.map +0 -1
  78. package/dist/chunk-R5ZQZSEQ.js.map +0 -1
  79. package/dist/chunk-TPQRIPCN.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/ContentToolbar/ContentToolbar.tsx","../src/components/layout/ContentToolbar/ViewSelector.tsx","../src/components/layout/ContentToolbar/SortByDropdown.tsx","../src/components/layout/ContentToolbar/MultiSelectDropdown.tsx","../src/components/layout/ContentToolbar/MultiSelectTriggers.tsx","../src/components/layout/ContentToolbar/FilterTrigger.tsx","../src/components/layout/ContentToolbar/ColumnsMenu.tsx","../src/components/layout/ContentToolbar/SavedViewsMenu.tsx"],"sourcesContent":["'use client';\n\nimport { Box, Button, Checkbox, Divider, Typography } from '@mui/material';\nimport React from 'react';\n\nimport type { ContentToolbarProps } from './ContentToolbar.types';\n\nconst selectionButtonSx = {\n minWidth: 0,\n height: 'auto',\n borderRadius: 0.5,\n fontWeight: 600,\n py: 0.5,\n px: 1.5,\n fontSize: '0.75rem',\n textTransform: 'none',\n color: 'text.primary',\n} as const;\n\ntype SelectionClusterProps = Pick<\n ContentToolbarProps,\n 'hasSelection' | 'selectedCount' | 'selectAll' | 'clearSelection' | 'actions' | 'selectAllTestId' | 'clearAllTestId' | 'edgeAlign'\n>;\n\n/** The left cluster: Select All + (when selecting) Clear All / count / actions. */\nfunction SelectionCluster({\n hasSelection,\n selectedCount,\n selectAll,\n clearSelection,\n actions,\n selectAllTestId,\n clearAllTestId,\n edgeAlign = false,\n}: SelectionClusterProps): React.JSX.Element {\n const actionsSlot = actions !== undefined && (\n <Box sx={{ ml: 0.5, display: 'flex', flexShrink: 0, alignItems: 'center' }}>{actions}</Box>\n );\n return (\n <Box\n sx={{\n display: 'flex',\n minWidth: 0,\n // Mobile: don't grow, so the controls sit on the SAME line as the checkbox\n // (no orphaned selection row). Desktop: grow to push controls right.\n flex: { xs: '0 0 auto', md: 1 },\n alignItems: 'center',\n gap: 1.5,\n ml: edgeAlign ? -1.5 : 0,\n }}\n >\n {/* Desktop: a \"Select All\" text button (md+). Mobile: a compact checkbox\n that toggles select-all/clear — the text would eat the tight row. */}\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n onClick={selectAll}\n data-testid={selectAllTestId}\n sx={{ ...selectionButtonSx, display: { xs: 'none', md: 'inline-flex' } }}\n >\n Select All\n </Button>\n <Checkbox\n size=\"small\"\n checked={hasSelection}\n onChange={(event) => (event.target.checked ? selectAll() : clearSelection())}\n data-testid={`${selectAllTestId}-checkbox`}\n inputProps={{ 'aria-label': 'Selecionar todos' }}\n sx={{ p: 0.5, display: { xs: 'inline-flex', md: 'none' } }}\n />\n {hasSelection ? (\n <>\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n onClick={clearSelection}\n data-testid={clearAllTestId}\n sx={selectionButtonSx}\n >\n Clear All\n </Button>\n <Divider orientation=\"vertical\" flexItem sx={{ height: 16, alignSelf: 'center' }} />\n <Typography\n component=\"span\"\n data-testid=\"selected-count-indicator\"\n sx={{ fontSize: '0.875rem', color: 'text.secondary', whiteSpace: 'nowrap', flexShrink: 0 }}\n >\n {selectedCount} {selectedCount === 1 ? 'item' : 'items'} selected\n </Typography>\n {actionsSlot}\n </>\n ) : (\n actionsSlot\n )}\n </Box>\n );\n}\n\n/**\n * The BROWSING half of the toolbar: search + filters on the left, the page's\n * own controls on the right. Split out of {@link ContentToolbar} so that\n * function stays inside the complexity gate — it is layout only, and the\n * decision of whether to show it at all is made by the caller.\n */\nfunction BrowsingClusters({\n leadingControls,\n rightControls,\n hasSelection,\n edgeAlign,\n}: {\n leadingControls?: React.ReactNode;\n rightControls: React.ReactNode;\n hasSelection: boolean;\n edgeAlign: boolean;\n}): React.JSX.Element {\n return (\n <>\n {/* minWidth:0 lets this cluster be the one that gives up width as the row\n * tightens, which is what the filter overflow measures against. */}\n {leadingControls !== undefined && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n flexGrow: 1,\n minWidth: 0,\n // The collapse ladder has a FLOOR — below roughly 400px even the\n // fully-collapsed row does not fit, and its controls cannot shrink\n // (they are flexShrink:0 so an over-packed row sheds instead of\n // squeezing). Past that point this scrolls rather than letting them\n // paint outside the toolbar, which is what a narrow phone did.\n overflowX: 'auto',\n // No scrollbar gutter stealing height on the common case.\n scrollbarWidth: 'thin',\n }}\n >\n {leadingControls}\n </Box>\n )}\n {/* ml:auto keeps the controls right-aligned even when the cluster wraps to\n * its own row (where justify-content:space-between would otherwise snap a\n * lone item to the left); it's a no-op on a shared row. */}\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n // Same single-line rule as the row itself: this cluster wrapping\n // INTERNALLY buys a second line just as surely as the row wrapping\n // does. It bit at exactly 900px, the `md` breakpoint where the \"N de\n // N\" counter appears and pushes Exibir/Exportar over the edge.\n flexWrap: leadingControls === undefined ? 'wrap' : 'nowrap',\n // Tight (5px) when browsing so the controls fit one line beside the\n // checkbox; roomier (14px) in selection mode where they get their own row.\n gap: hasSelection ? '14px' : '5px',\n ml: 'auto',\n mr: edgeAlign ? -1.5 : 0,\n '& > *': { flexShrink: 0 },\n }}\n >\n {rightControls}\n </Box>\n </>\n );\n}\n\n/**\n * Shared toolbar for content pages (Favorites, Personal Space, Recents, …). The\n * left cluster owns selection chrome — **Select All**, and once items are\n * selected, **Clear All** + an \"N items selected\" count + an optional `actions`\n * slot. The right cluster is a free `rightControls` slot for page-specific\n * controls (ViewSelector, SortByDropdown, MultiSelectDropdown, FilterTrigger).\n *\n * Faithful, generic MUI port of the reference `ContentPageToolbar` — the\n * domain-specific default actions are intentionally left to the consumer via\n * the `actions` slot so this stays agnostic and reusable across projects.\n *\n * @example\n * ```tsx\n * <ContentToolbar\n * hasSelection={selected.size > 0}\n * selectedCount={selected.size}\n * selectAll={selectAll}\n * clearSelection={clear}\n * rightControls={\n * <>\n * <ViewSelector viewMode={view} onViewModeChange={setView} zoom={zoom} onZoomChange={setZoom} />\n * <SortByDropdown fields={FIELDS} activeField={field} onFieldChange={setField} />\n * <MultiSelectDropdown label=\"Content Type\" options={types} selected={typeSet} onToggle={toggle} onClear={clear} />\n * <FilterTrigger open={panelOpen} onOpenChange={setPanelOpen} hasActiveFilters={hasFilters} />\n * </>\n * }\n * />\n * ```\n */\nexport function ContentToolbar({\n hasSelection,\n selectedCount,\n selectAll,\n clearSelection,\n rightControls,\n leadingControls,\n actions,\n selectAllTestId,\n clearAllTestId,\n edgeAlign = false,\n exclusiveSelection = false,\n}: ContentToolbarProps): React.JSX.Element {\n // Under `exclusiveSelection` the two states are alternatives, not neighbours:\n // browsing shows the controls and no checkbox, selecting shows the checkbox\n // and no controls. Anything else double-books the row.\n const showSelection = !exclusiveSelection || hasSelection;\n const showControls = !exclusiveSelection || !hasSelection;\n return (\n // Two clusters on one line. They may wrap onto separate rows ONLY for a\n // toolbar without `leadingControls` — one carrying search + filters is\n // driven by a measured collapse ladder (see `useFilterOverflow`), and a\n // wrap there is the ladder having failed: it would silently buy a second\n // row instead of shedding a control into \"Mais\", which is the one outcome\n // the ladder exists to prevent.\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 2,\n flexWrap: leadingControls === undefined ? 'wrap' : 'nowrap',\n rowGap: 1,\n }}\n >\n {showSelection && (\n <SelectionCluster\n hasSelection={hasSelection}\n selectedCount={selectedCount}\n selectAll={selectAll}\n clearSelection={clearSelection}\n actions={actions}\n selectAllTestId={selectAllTestId}\n clearAllTestId={clearAllTestId}\n edgeAlign={edgeAlign}\n />\n )}\n\n {showControls && (\n <BrowsingClusters\n leadingControls={leadingControls}\n rightControls={rightControls}\n hasSelection={hasSelection}\n edgeAlign={edgeAlign}\n />\n )}\n </Box>\n );\n}\n","'use client';\n\nimport CheckIcon from '@mui/icons-material/Check';\nimport ChevronDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport GridIcon from '@mui/icons-material/GridViewOutlined';\nimport ListIcon from '@mui/icons-material/FormatListBulletedRounded';\nimport { Box, Button, ListItemIcon, ListItemText, Menu, MenuItem, Slider } from '@mui/material';\n// Type-only, so it is erased at build time and costs no barrel transform.\nimport type { SvgIconComponent } from '@mui/icons-material';\nimport React, { useState } from 'react';\n\nimport type { ViewMode, ViewSelectorProps } from './ContentToolbar.types';\n\nconst VIEW_OPTIONS: { value: ViewMode; label: string; icon: SvgIconComponent }[] = [\n { value: 'grid', label: 'Grid View', icon: GridIcon },\n { value: 'list', label: 'List View', icon: ListIcon },\n];\n\n/**\n * View selector: a grid/list dropdown plus a card-size zoom slider (grid mode\n * only). Faithful MUI port of the reference toolbar's view control.\n */\nexport function ViewSelector({\n viewMode,\n onViewModeChange,\n zoom,\n onZoomChange,\n}: ViewSelectorProps): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const open = Boolean(anchorEl);\n const activeOption = VIEW_OPTIONS.find((option) => option.value === viewMode) ?? VIEW_OPTIONS[0]!;\n const ActiveIcon = activeOption.icon;\n\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>\n {viewMode === 'grid' && (\n <Box sx={{ width: 96, display: 'flex', alignItems: 'center' }}>\n <Slider\n data-testid=\"resize-card-slider\"\n aria-label=\"Card size\"\n value={zoom[0] ?? 0}\n onChange={(_, value) => onZoomChange([value as number])}\n min={0}\n max={100}\n step={1}\n size=\"small\"\n />\n </Box>\n )}\n\n <Button\n data-testid=\"view-mode-btn\"\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n aria-label={activeOption.label}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={(event) => setAnchorEl(event.currentTarget)}\n sx={{ minWidth: 0, height: 32, px: 1, gap: 1, color: 'text.secondary' }}\n >\n <ActiveIcon sx={{ fontSize: 16 }} />\n <ChevronDownIcon sx={{ fontSize: 14 }} />\n </Button>\n <Menu\n anchorEl={anchorEl}\n open={open}\n onClose={() => setAnchorEl(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n slotProps={{ paper: { sx: { minWidth: 180 } } }}\n >\n {VIEW_OPTIONS.map((option) => {\n const OptionIcon = option.icon;\n const selected = viewMode === option.value;\n return (\n <MenuItem\n key={option.value}\n data-testid={`view-mode-${option.value}`}\n onClick={() => {\n onViewModeChange(option.value);\n setAnchorEl(null);\n }}\n sx={{ gap: 1.5 }}\n >\n <ListItemText>{option.label}</ListItemText>\n <OptionIcon sx={{ fontSize: 16, color: 'text.secondary' }} />\n <ListItemIcon sx={{ minWidth: 'auto !important' }}>\n <CheckIcon sx={{ fontSize: 16, color: selected ? 'text.primary' : 'transparent' }} />\n </ListItemIcon>\n </MenuItem>\n );\n })}\n </Menu>\n </Box>\n );\n}\n","'use client';\n\nimport CheckIcon from '@mui/icons-material/Check';\nimport ChevronDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport { Box, Button, Divider, ListSubheader, Menu, MenuItem, Typography } from '@mui/material';\nimport React, { useState } from 'react';\n\nimport type {\n SortByDropdownProps,\n SortFieldDefinition,\n SortOrderOption,\n} from './ContentToolbar.types';\n\nfunction findActiveField<TField extends string>(\n fields: SortFieldDefinition<TField>[] | undefined,\n activeField: TField,\n): SortFieldDefinition<TField> | undefined {\n return fields?.find((field) => field.value === activeField);\n}\n\nfunction findActiveOrder(\n fieldDef: SortFieldDefinition | undefined,\n activeOrder: string | undefined,\n): SortOrderOption | undefined {\n const options = fieldDef?.orderOptions;\n if (!options?.length) return undefined;\n return options.find((option) => option.value === activeOrder) ?? options[0];\n}\n\nfunction resolveArrowDirection(option: SortOrderOption | undefined, indexInList: number): 'up' | 'down' {\n if (option?.arrowDirection) return option.arrowDirection;\n // A missing (<0) or first index sorts \"down\"; any later option sorts \"up\".\n return indexInList <= 0 ? 'down' : 'up';\n}\n\nfunction buildTriggerLabel(\n fieldDef: SortFieldDefinition | undefined,\n orderOption: SortOrderOption | undefined,\n): string {\n if (!fieldDef) return '';\n if (fieldDef.showOrderInTrigger === false || !orderOption) return fieldDef.label;\n if (fieldDef.triggerLabelStyle === 'range' && fieldDef.orderOptions?.length === 2) {\n const other = fieldDef.orderOptions.find((option) => option.value !== orderOption.value);\n if (other) return `${fieldDef.label} (${orderOption.label.toLowerCase()}-${other.label.toLowerCase()})`;\n }\n return `${fieldDef.label} (${orderOption.label.toLowerCase()})`;\n}\n\n/** The trigger's full label (md+), short label (mobile), and direction arrow. */\nfunction resolveTriggerParts(\n fieldDef: SortFieldDefinition | undefined,\n orderOption: SortOrderOption | undefined,\n orderOptions: SortOrderOption[],\n): { full: string; short: string; arrowSuffix: string } {\n const useRangeLabel = fieldDef?.triggerLabelStyle === 'range' && orderOptions.length === 2;\n const orderIndex = orderOptions.findIndex((option) => option.value === orderOption?.value);\n const arrow = resolveArrowDirection(orderOption, orderIndex);\n const arrowSuffix = orderOptions.length > 0 && !useRangeLabel ? ` ${arrow === 'down' ? '↓' : '↑'}` : '';\n const full = buildTriggerLabel(fieldDef, orderOption);\n return { full, short: fieldDef?.label ?? full, arrowSuffix };\n}\n\nconst sectionLabelSx = { px: 1, py: 0.75, fontSize: '0.75rem', fontWeight: 600, color: 'text.primary', lineHeight: 1.5 } as const;\n\n/** A fixed-width check slot (empty when unchecked) so labels align. */\nfunction SortCheck({ checked }: { checked: boolean }): React.JSX.Element {\n return (\n <Box component=\"span\" sx={{ display: 'flex', width: 16, flexShrink: 0, alignItems: 'center', justifyContent: 'center' }} aria-hidden>\n {checked ? <CheckIcon sx={{ fontSize: 14 }} /> : null}\n </Box>\n );\n}\n\n/** One `id`/`label` menu row with a leading check + testid. */\nfunction SortRow({\n value,\n label,\n checked,\n onSelect,\n}: {\n value: string;\n label: string;\n checked: boolean;\n onSelect: () => void;\n}): React.JSX.Element {\n return (\n <MenuItem data-testid={`sort-${value}-option`} onClick={onSelect} sx={{ gap: 1 }}>\n <SortCheck checked={checked} />\n <Box component=\"span\" sx={{ flex: 1, minWidth: 0, textAlign: 'left' }}>\n {label}\n </Box>\n </MenuItem>\n );\n}\n\ninterface SortMenuProps<TField extends string> {\n anchorEl: HTMLElement | null;\n open: boolean;\n close: () => void;\n orderOptions: SortOrderOption[];\n activeOrderValue: string | undefined;\n onOrderSelect: (value: string) => void;\n fields: SortFieldDefinition<TField>[];\n activeField: TField;\n onFieldSelect: (field: TField) => void;\n}\n\n/** The Order + Sort sections of the dropdown menu. */\nfunction SortMenu<TField extends string>({\n anchorEl,\n open,\n close,\n orderOptions,\n activeOrderValue,\n onOrderSelect,\n fields,\n activeField,\n onFieldSelect,\n}: SortMenuProps<TField>): React.JSX.Element {\n return (\n <Menu\n anchorEl={anchorEl}\n open={open}\n onClose={close}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n slotProps={{ paper: { sx: { minWidth: 180 } } }}\n >\n {orderOptions.length > 0 && [\n <ListSubheader key=\"order-label\" sx={sectionLabelSx}>\n Order\n </ListSubheader>,\n ...orderOptions.map((option) => (\n <SortRow\n key={`order-${option.value}`}\n value={option.value}\n label={option.label}\n checked={activeOrderValue === option.value}\n onSelect={() => onOrderSelect(option.value)}\n />\n )),\n <Divider key=\"order-divider\" />,\n ]}\n <ListSubheader sx={sectionLabelSx}>Sort</ListSubheader>\n {fields.map((field) => (\n <SortRow\n key={field.value}\n value={field.value}\n label={field.label}\n checked={activeField === field.value}\n onSelect={() => onFieldSelect(field.value)}\n />\n ))}\n </Menu>\n );\n}\n\n/**\n * Generic \"Sort By\" dropdown: a \"Sort By:\" label + a trigger whose menu has an\n * **Order** section (direction within the active field) and a **Sort** section\n * (which field). The Order section is hidden when the field defines no order\n * options. Faithful MUI port of the reference control.\n */\nexport function SortByDropdown<TField extends string = string>({\n fields,\n activeField,\n activeOrder,\n onFieldChange,\n onOrderChange,\n 'data-testid': testId,\n}: SortByDropdownProps<TField>): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const open = Boolean(anchorEl);\n const close = (): void => setAnchorEl(null);\n\n const safeFields = fields ?? [];\n const activeFieldDef = findActiveField(fields, activeField);\n const orderOptions = activeFieldDef?.orderOptions ?? [];\n const activeOrderOption = findActiveOrder(activeFieldDef, activeOrder);\n const trigger = resolveTriggerParts(activeFieldDef, activeOrderOption, orderOptions);\n\n function handleFieldChange(field: TField): void {\n // Switch field in ONE callback. Previously this also fired `onOrderChange`\n // to reset the order, but a consumer whose `onOrderChange` derives the field\n // from its own (now-stale) prop would re-apply the OLD field — silently\n // reverting the field change (e.g. picking \"E-mail\" snapped back to \"Nome\").\n // The field-change consumer owns the resulting order.\n onFieldChange(field);\n close();\n }\n\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, fontSize: '0.875rem' }}>\n <Typography\n component=\"span\"\n sx={{ display: { xs: 'none', md: 'inline' }, color: 'text.secondary', fontSize: '0.875rem' }}\n >\n Sort By:\n </Typography>\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n data-testid={testId}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={(event) => setAnchorEl(event.currentTarget)}\n sx={{ minWidth: 0, height: 32, px: 1, gap: 0.5, color: 'text.primary', textTransform: 'none', fontWeight: 600 }}\n >\n {/* Full \"Nome (crescente)\" on md+; just the field name on mobile — the\n arrow already conveys the direction, so the parenthetical is dropped. */}\n <Box component=\"span\" sx={{ display: { xs: 'none', md: 'inline' } }}>\n {trigger.full}\n </Box>\n <Box component=\"span\" sx={{ display: { xs: 'inline', md: 'none' } }}>\n {trigger.short}\n </Box>\n {trigger.arrowSuffix}\n <ChevronDownIcon sx={{ fontSize: 14 }} />\n </Button>\n <SortMenu\n anchorEl={anchorEl}\n open={open}\n close={close}\n orderOptions={orderOptions}\n activeOrderValue={activeOrderOption?.value}\n onOrderSelect={(value) => {\n onOrderChange?.(value);\n close();\n }}\n fields={safeFields}\n activeField={activeField}\n onFieldSelect={handleFieldChange}\n />\n </Box>\n );\n}\n","'use client';\n\nimport SearchIcon from '@mui/icons-material/Search';\nimport {\n Box,\n Button,\n Checkbox,\n Divider,\n InputAdornment,\n ListSubheader,\n Menu,\n MenuItem,\n TextField,\n} from '@mui/material';\nimport React, { useMemo, useState } from 'react';\n\nimport type {\n MultiSelectDropdownProps,\n MultiSelectExtraOption,\n MultiSelectOption,\n} from './ContentToolbar.types';\nimport { buildTriggerLabel, InlineTrigger, PillTrigger, StackedTrigger } from './MultiSelectTriggers';\n\n/** One checkbox menu row with an optional trailing count. */\nfunction CheckboxRow({\n label,\n count,\n checked,\n onToggle,\n}: {\n label: string;\n count?: number;\n checked: boolean;\n onToggle: (next: boolean) => void;\n}): React.JSX.Element {\n return (\n <MenuItem onClick={() => onToggle(!checked)} sx={{ gap: 1 }}>\n <Checkbox checked={checked} size=\"small\" disableRipple sx={{ p: 0, pointerEvents: 'none' }} tabIndex={-1} />\n <Box component=\"span\" sx={{ flex: 1, minWidth: 0, textAlign: 'left' }}>\n {label}\n {count != null && (\n <Box component=\"span\" sx={{ color: 'text.secondary' }}>\n {' '}\n ({count})\n </Box>\n )}\n </Box>\n </MenuItem>\n );\n}\n\n/**\n * Generic multi-select dropdown with checkboxes, counts, an optional \"Options\"\n * section, and a \"Clear\" action. Faithful MUI port of the reference toolbar's\n * \"Content Type\" control. The menu stays open while toggling options.\n */\nexport function MultiSelectDropdown<TValue extends string = string>({\n label,\n options,\n selected,\n onToggle,\n onClear,\n allLabel = 'All',\n extraOptions,\n searchable,\n searchPlaceholder = 'Search…',\n noResultsLabel = 'No results',\n layout = 'inline',\n 'data-testid': testId,\n onOpenChange,\n}: MultiSelectDropdownProps<TValue>): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const [query, setQuery] = useState('');\n const open = Boolean(anchorEl);\n const stacked = layout === 'stacked';\n // Reset the query each time the menu closes so it reopens showing everything.\n const close = (): void => {\n setAnchorEl(null);\n setQuery('');\n onOpenChange?.(false);\n };\n const triggerLabel = buildTriggerLabel(selected, options, allLabel);\n // Auto-enable search for long lists (e.g. many categories) unless overridden.\n const showSearch = searchable ?? options.length > 8;\n const anyExtraChecked = extraOptions?.some((option) => option.checked) ?? false;\n const clearDisabled = selected.size === 0 && !anyExtraChecked;\n\n const openMenu = (event: React.MouseEvent<HTMLElement>): void => {\n setAnchorEl(event.currentTarget);\n onOpenChange?.(true);\n };\n const triggerProps = { triggerLabel, open, onOpen: openMenu, testId };\n\n const renderTrigger = (): React.JSX.Element => {\n if (stacked) return <StackedTrigger label={label} {...triggerProps} />;\n if (layout === 'pill')\n return (\n <PillTrigger\n label={label}\n selectedCount={selected.size}\n onClear={onClear}\n {...triggerProps}\n />\n );\n return <InlineTrigger label={label} {...triggerProps} />;\n };\n\n return (\n <>\n {renderTrigger()}\n <MultiSelectMenu\n anchorEl={anchorEl}\n open={open}\n close={close}\n options={options}\n selected={selected}\n onToggle={onToggle}\n extraOptions={extraOptions}\n clearDisabled={clearDisabled}\n onClear={onClear}\n showSearch={showSearch}\n query={query}\n onQueryChange={setQuery}\n searchPlaceholder={searchPlaceholder}\n noResultsLabel={noResultsLabel}\n matchAnchorWidth={stacked}\n testId={testId}\n />\n </>\n );\n}\n\n/** Sticky search box at the top of the menu; keydowns don't reach the Menu's typeahead. */\nfunction MenuSearchField({\n query,\n onQueryChange,\n placeholder,\n testId,\n}: {\n query: string;\n onQueryChange: (value: string) => void;\n placeholder: string;\n testId?: string;\n}): React.JSX.Element {\n return (\n <Box\n sx={{ position: 'sticky', top: 0, zIndex: 1, bgcolor: 'background.paper', px: 1, py: 0.75 }}\n onKeyDown={(event) => event.stopPropagation()}\n >\n <TextField\n autoFocus\n size=\"small\"\n fullWidth\n value={query}\n onChange={(event) => onQueryChange(event.target.value)}\n placeholder={placeholder}\n inputProps={{ 'aria-label': placeholder, 'data-testid': testId ? `${testId}-search` : undefined }}\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon sx={{ fontSize: 16 }} />\n </InputAdornment>\n ),\n }}\n />\n </Box>\n );\n}\n\ninterface MultiSelectMenuProps<TValue extends string> {\n anchorEl: HTMLElement | null;\n open: boolean;\n close: () => void;\n options: MultiSelectOption<TValue>[];\n selected: ReadonlySet<TValue>;\n onToggle: (value: TValue, checked: boolean) => void;\n extraOptions?: MultiSelectExtraOption[];\n clearDisabled: boolean;\n onClear: () => void;\n showSearch: boolean;\n query: string;\n onQueryChange: (value: string) => void;\n searchPlaceholder: string;\n noResultsLabel: string;\n /** Match the menu width to the trigger and left-align it (stacked select). */\n matchAnchorWidth?: boolean;\n testId?: string;\n}\n\n/**\n * Menu placement. Default: anchored to the trigger's right (toolbar). When\n * `matchAnchorWidth` (stacked select), match the trigger width and left-align so\n * the menu sits flush under the full-width control.\n */\nfunction resolveMenuPlacement(\n matchAnchorWidth: boolean | undefined,\n anchorEl: HTMLElement | null,\n): { anchorWidth: number | undefined; align: 'left' | 'right' } {\n if (!matchAnchorWidth) return { anchorWidth: undefined, align: 'right' };\n return { anchorWidth: anchorEl?.offsetWidth, align: 'left' };\n}\n\n/** The (optional) search box + checkbox list + optional \"Options\" section + a \"Clear\" footer. */\nfunction MultiSelectMenu<TValue extends string>({\n anchorEl,\n open,\n close,\n options,\n selected,\n onToggle,\n extraOptions,\n clearDisabled,\n onClear,\n showSearch,\n query,\n onQueryChange,\n searchPlaceholder,\n noResultsLabel,\n matchAnchorWidth,\n testId,\n}: MultiSelectMenuProps<TValue>): React.JSX.Element {\n const trimmed = query.trim().toLowerCase();\n const visibleOptions = useMemo(\n () => (trimmed ? options.filter((option) => option.label.toLowerCase().includes(trimmed)) : options),\n [options, trimmed],\n );\n const { anchorWidth, align } = resolveMenuPlacement(matchAnchorWidth, anchorEl);\n return (\n <Menu\n anchorEl={anchorEl}\n open={open}\n onClose={close}\n anchorOrigin={{ vertical: 'bottom', horizontal: align }}\n transformOrigin={{ vertical: 'top', horizontal: align }}\n // Keep focus on the search box (don't let the Menu grab the first item),\n // and stop MUI's typeahead from swallowing keystrokes meant for the input.\n autoFocus={!showSearch}\n disableAutoFocusItem\n slotProps={{\n // Cap the height so a long list (e.g. many categories) scrolls instead\n // of running off-screen; the sticky search box stays pinned on top.\n paper: { sx: { minWidth: anchorWidth ?? 180, width: anchorWidth, maxHeight: 360 } },\n list: { sx: { pt: showSearch ? 0 : undefined, pb: 0 } },\n }}\n >\n {showSearch && (\n <MenuSearchField query={query} onQueryChange={onQueryChange} placeholder={searchPlaceholder} testId={testId} />\n )}\n {visibleOptions.length === 0 && showSearch ? (\n <MenuItem disabled data-testid={testId ? `${testId}-no-results` : undefined} sx={{ fontSize: '0.8125rem' }}>\n {noResultsLabel}\n </MenuItem>\n ) : (\n visibleOptions.map((option) => (\n <CheckboxRow\n key={option.value}\n label={option.label}\n count={option.count}\n checked={selected.has(option.value)}\n onToggle={(next) => onToggle(option.value, next)}\n />\n ))\n )}\n {extraOptions && extraOptions.length > 0\n ? [\n <Divider key=\"extra-divider\" />,\n <ListSubheader key=\"extra-label\" sx={{ px: 1, py: 0.75, fontSize: '0.75rem', fontWeight: 600 }}>\n Options\n </ListSubheader>,\n ...extraOptions.map((extra) => (\n <CheckboxRow key={extra.id} label={extra.label} checked={extra.checked} onToggle={(next) => extra.onCheckedChange(next)} />\n )),\n ]\n : null}\n <MenuClearFooter clearDisabled={clearDisabled} onClear={onClear} close={close} testId={testId} />\n </Menu>\n );\n}\n\n/** The bottom \"Clear\" footer that resets the selection and closes the menu. */\nfunction MenuClearFooter({\n clearDisabled,\n onClear,\n close,\n testId,\n}: {\n clearDisabled: boolean;\n onClear: () => void;\n close: () => void;\n testId?: string;\n}): React.JSX.Element {\n return (\n <Box\n sx={{\n // Pin to the bottom of the scroll viewport so it stays visible while the\n // options list scrolls (mirrors the sticky search box on top).\n position: 'sticky',\n bottom: 0,\n zIndex: 1,\n display: 'flex',\n justifyContent: 'flex-end',\n borderTop: 1,\n borderColor: 'divider',\n bgcolor: 'background.paper',\n px: 1,\n py: 0.75,\n }}\n >\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n data-testid={testId ? `${testId}-clear` : undefined}\n disabled={clearDisabled}\n onClick={() => {\n onClear();\n close();\n }}\n sx={{ minWidth: 0, px: 1, py: 0.25, fontSize: '0.75rem', fontWeight: 400, textTransform: 'none', color: 'text.secondary' }}\n >\n Clear\n </Button>\n </Box>\n );\n}\n","'use client';\n\nimport CloseIcon from '@mui/icons-material/Close';\nimport ChevronDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport { Box, Button, Typography } from '@mui/material';\nimport React, { useId } from 'react';\n\nimport type { MultiSelectOption } from './ContentToolbar.types';\n\n/**\n * Trigger label from the current selection: `allLabel` when none/all are\n * selected, the single label when one, else \"first (+N)\". Uses Set iteration\n * order so the label reflects the first-clicked option.\n */\nexport function buildTriggerLabel<TValue extends string>(\n selected: ReadonlySet<TValue>,\n options: MultiSelectOption<TValue>[],\n allLabel: string,\n): string {\n const size = selected.size;\n if (size === 0 || size === options.length) return allLabel;\n const labelMap = new Map(options.map((option) => [option.value, option.label]));\n const firstValue = selected.values().next().value as TValue;\n const firstLabel = labelMap.get(firstValue) ?? allLabel;\n if (size === 1) return firstLabel;\n return `${firstLabel} (+${size - 1})`;\n}\n\nexport interface TriggerProps {\n label: string;\n triggerLabel: string;\n open: boolean;\n onOpen: (event: React.MouseEvent<HTMLElement>) => void;\n testId?: string;\n}\n\n/** Compact `Label:` text button for a horizontal toolbar (the default layout). */\nexport function InlineTrigger({ label, triggerLabel, open, onOpen, testId }: TriggerProps): React.JSX.Element {\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, fontSize: '0.875rem' }}>\n <Typography component=\"span\" sx={{ color: 'text.secondary', fontSize: '0.875rem' }}>\n {label}:\n </Typography>\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n data-testid={testId}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={onOpen}\n sx={{ minWidth: 0, height: 32, px: 1, gap: 0.5, color: 'text.primary', textTransform: 'none', fontWeight: 600 }}\n >\n {triggerLabel}\n <ChevronDownIcon sx={{ fontSize: 14 }} />\n </Button>\n </Box>\n );\n}\n\n/** Full-width, outlined select-style control with the label above (stacked layout). */\nexport function StackedTrigger({ label, triggerLabel, open, onOpen, testId }: TriggerProps): React.JSX.Element {\n // Name the button by label + value (aria-labelledby): a <button> isn't labelable.\n const baseId = useId();\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>\n <Typography id={`${baseId}-label`} component=\"label\" sx={{ fontSize: '0.75rem', fontWeight: 500, color: 'text.secondary' }}>\n {label}\n </Typography>\n <Button\n variant=\"outlined\"\n color=\"inherit\"\n fullWidth\n data-testid={testId}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-labelledby={`${baseId}-label ${baseId}-value`}\n onClick={onOpen}\n endIcon={<ChevronDownIcon sx={{ fontSize: 18, color: 'text.secondary' }} />}\n sx={{\n justifyContent: 'space-between',\n height: 40,\n px: 1.5,\n color: 'text.primary',\n textTransform: 'none',\n fontWeight: 400,\n fontSize: '0.875rem',\n borderColor: 'divider',\n bgcolor: 'background.paper',\n '&:hover': { borderColor: 'text.primary', bgcolor: 'background.paper' },\n }}\n >\n <Box\n component=\"span\" id={`${baseId}-value`}\n sx={{ flex: 1, minWidth: 0, textAlign: 'left', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}\n >\n {triggerLabel}\n </Box>\n </Button>\n </Box>\n );\n}\n\n/** Rounded outlined chip (`Label ▾`, `Label (N) ▾` when selected) for a filter row. */\nexport function PillTrigger({\n label,\n open,\n onOpen,\n testId,\n selectedCount,\n onClear,\n}: TriggerProps & { selectedCount: number; onClear?: () => void }): React.JSX.Element {\n const active = selectedCount > 0;\n return (\n <Button\n variant=\"outlined\"\n color=\"inherit\"\n size=\"small\"\n data-testid={testId}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={onOpen}\n // Clearing lives ON the pill: the filter and the way to remove it are one\n // control, so removing one does not mean finding it again in a second\n // list somewhere else on the page.\n startIcon={\n active && onClear ? (\n <Box\n component=\"span\"\n role=\"button\"\n tabIndex={0}\n aria-label={`Limpar ${label}`}\n data-testid={testId ? `${testId}-clear` : undefined}\n onClick={(event: React.MouseEvent) => {\n // The pill's own click opens the menu; clearing must not.\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 sx={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '50%',\n cursor: 'pointer',\n color: 'primary.main',\n '&:hover': { bgcolor: 'primary.main', color: 'primary.contrastText' },\n }}\n >\n <CloseIcon sx={{ fontSize: 14 }} />\n </Box>\n ) : undefined\n }\n endIcon={<ChevronDownIcon sx={{ fontSize: 16 }} />}\n sx={{\n borderRadius: 999,\n height: 34,\n px: 1.5,\n color: 'text.primary',\n fontWeight: 600,\n fontSize: '0.8125rem',\n textTransform: 'none',\n borderColor: active ? 'primary.main' : 'divider',\n bgcolor: active ? 'action.selected' : 'background.paper',\n '&:hover': { borderColor: active ? 'primary.main' : 'text.primary', bgcolor: active ? 'action.selected' : 'action.hover' },\n }}\n >\n {label}\n {active ? ` (${selectedCount})` : ''}\n </Button>\n );\n}\n","'use client';\n\nimport FilterIcon from '@mui/icons-material/FilterListRounded';\nimport { Box, Button } from '@mui/material';\nimport React from 'react';\n\nimport type { FilterTriggerProps } from './ContentToolbar.types';\n\n/**\n * Labeled filter toggle: a \"Filtros\" button (styled like the sibling toolbar\n * controls) with a funnel icon and, when filters are active, a count badge — so\n * it's obvious that the list is filtered and by how many facets. The panel itself\n * is supplied by the consumer.\n */\nexport function FilterTrigger({\n open,\n onOpenChange,\n hasActiveFilters = false,\n activeCount = 0,\n label = 'Filtros',\n 'data-testid': testId = 'toggle-filters-btn',\n}: FilterTriggerProps): React.JSX.Element {\n const active = activeCount > 0 || hasActiveFilters;\n return (\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n data-testid={testId}\n aria-expanded={open}\n aria-label={open ? 'Close filters' : 'Open filters'}\n onClick={() => onOpenChange(!open)}\n startIcon={<FilterIcon sx={{ fontSize: 16 }} />}\n sx={{\n minWidth: 0,\n height: 32,\n px: 1,\n gap: 0.25,\n textTransform: 'none',\n fontWeight: 600,\n color: active ? 'primary.main' : 'text.primary',\n bgcolor: open ? 'action.selected' : 'transparent',\n }}\n >\n {label}\n {activeCount > 0 && (\n <Box\n component=\"span\"\n data-testid={`${testId}-count`}\n sx={{\n ml: 0.5,\n minWidth: 18,\n height: 18,\n px: 0.5,\n borderRadius: 999,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '0.7rem',\n fontWeight: 700,\n lineHeight: 1,\n bgcolor: 'primary.main',\n color: 'primary.contrastText',\n }}\n >\n {activeCount}\n </Box>\n )}\n </Button>\n );\n}\n","'use client';\n\nimport ColumnsIcon from '@mui/icons-material/ViewColumnRounded';\nimport { Box, Checkbox, IconButton, ListSubheader, Menu, MenuItem } from '@mui/material';\nimport React, { useState } from 'react';\n\nimport type { ColumnVisibilityOption, ColumnsMenuProps } from './ContentToolbar.types';\n\n/** One column checkbox row; toggling never closes the menu. */\nfunction ColumnRow({\n option,\n onToggle,\n testId,\n}: {\n option: ColumnVisibilityOption;\n onToggle: (id: string, visible: boolean) => void;\n testId?: string;\n}): React.JSX.Element {\n return (\n <MenuItem\n data-testid={testId}\n onClick={() => onToggle(option.id, !option.visible)}\n disabled={option.locked}\n sx={{ gap: 1 }}\n >\n <Checkbox\n checked={option.visible}\n size=\"small\"\n disableRipple\n sx={{ p: 0, pointerEvents: 'none' }}\n tabIndex={-1}\n />\n <Box component=\"span\" sx={{ flex: 1, minWidth: 0, textAlign: 'left' }}>\n {option.label}\n </Box>\n </MenuItem>\n );\n}\n\n/**\n * Stateless column-visibility selector: a neutral icon button (matching\n * {@link FilterTrigger}/{@link SortByDropdown}) opening a checkbox list of the\n * hideable columns. Purely presentational — the caller owns the visibility state\n * and is notified via `onToggle`. The menu stays open while toggling so several\n * columns can be flipped at once.\n */\nexport function ColumnsMenu({\n columns,\n onToggle,\n title = 'Columns',\n ariaLabel = 'Toggle columns',\n 'data-testid': testId,\n}: ColumnsMenuProps): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const open = Boolean(anchorEl);\n const close = (): void => setAnchorEl(null);\n\n return (\n <>\n <IconButton\n size=\"small\"\n data-testid={testId}\n aria-label={ariaLabel}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={(event) => setAnchorEl(event.currentTarget)}\n sx={{\n width: 32,\n height: 32,\n borderRadius: 1,\n color: 'text.secondary',\n bgcolor: open ? 'action.selected' : 'transparent',\n }}\n >\n <ColumnsIcon sx={{ fontSize: 16 }} />\n </IconButton>\n <Menu\n anchorEl={anchorEl}\n open={open}\n onClose={close}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n slotProps={{ paper: { sx: { minWidth: 200 } } }}\n >\n <ListSubheader sx={{ px: 1.5, py: 0.75, fontSize: '0.75rem', fontWeight: 600, color: 'text.primary', lineHeight: 1.5 }}>\n {title}\n </ListSubheader>\n {columns.map((option) => (\n <ColumnRow\n key={option.id}\n option={option}\n onToggle={onToggle}\n testId={testId ? `${testId}-${option.id}` : undefined}\n />\n ))}\n </Menu>\n </>\n );\n}\n","'use client';\n\nimport CheckIcon from '@mui/icons-material/Check';\nimport ChevronDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport KebabIcon from '@mui/icons-material/MoreVert';\nimport ViewIcon from '@mui/icons-material/Visibility';\nimport { Box, Button, IconButton, Menu, MenuItem, Popover, Stack, Typography } from '@mui/material';\nimport React, { useState } from 'react';\n\nimport type {\n SavedViewLike,\n SavedViewsLabels,\n SavedViewsMenuProps,\n} from './ContentToolbar.types';\n\n/** How many non-pinned views show under \"Recentes\". */\nconst RECENT_LIMIT = 5;\n\ninterface RowHandlers<V extends SavedViewLike> {\n apply: (view: V) => void;\n onEdit: (view: V) => void;\n onDelete: (view: V) => void;\n onSetDefault: (view: V) => void;\n onTogglePin: (view: V) => void;\n onToggleShare: (view: V) => void;\n}\n\nfunction DefaultTag({ label, testId }: { label: string; testId: string }): React.JSX.Element {\n return (\n <Box\n component=\"span\"\n data-testid={testId}\n sx={{ px: 0.75, py: 0.125, borderRadius: 1, fontSize: '0.7rem', bgcolor: 'primary.main', color: 'primary.contrastText' }}\n >\n {label}\n </Box>\n );\n}\n\ninterface KebabAction {\n id: string;\n label: string;\n danger?: boolean;\n run: () => void;\n}\n\n/** Build the per-view ⋮ actions; owner-only mutations follow \"Apply\". */\nfunction buildActions<V extends SavedViewLike>(\n view: V,\n handlers: RowHandlers<V>,\n labels: SavedViewsLabels,\n): KebabAction[] {\n const actions: KebabAction[] = [{ id: 'apply', label: labels.apply, run: () => handlers.apply(view) }];\n if (!view.isOwner) return actions;\n if (!view.isDefault) {\n actions.push({ id: 'default', label: labels.setDefault, run: () => handlers.onSetDefault(view) });\n }\n actions.push({ id: 'pin', label: view.pinned ? labels.unpin : labels.pin, run: () => handlers.onTogglePin(view) });\n actions.push({ id: 'share', label: view.shared ? labels.unshare : labels.share, run: () => handlers.onToggleShare(view) });\n actions.push({ id: 'edit', label: labels.edit, run: () => handlers.onEdit(view) });\n actions.push({ id: 'delete', label: labels.remove, danger: true, run: () => handlers.onDelete(view) });\n return actions;\n}\n\nfunction ViewKebab<V extends SavedViewLike>({\n view,\n handlers,\n labels,\n testIdPrefix,\n}: {\n view: V;\n handlers: RowHandlers<V>;\n labels: SavedViewsLabels;\n testIdPrefix: string;\n}): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const close = (): void => setAnchorEl(null);\n return (\n <>\n <IconButton\n size=\"small\"\n aria-label={`${labels.apply} ${view.name}`}\n data-testid={`${testIdPrefix}-kebab-${view.id}`}\n onClick={(event) => setAnchorEl(event.currentTarget)}\n sx={{ width: 28, height: 28, color: 'text.secondary' }}\n >\n <KebabIcon sx={{ fontSize: 16 }} />\n </IconButton>\n <Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={close}>\n {buildActions(view, handlers, labels).map((action) => (\n <MenuItem\n key={action.id}\n data-testid={`${testIdPrefix}-item-${action.id}-${view.id}`}\n onClick={() => {\n action.run();\n close();\n }}\n sx={action.danger ? { color: 'error.main' } : undefined}\n >\n {action.label}\n </MenuItem>\n ))}\n </Menu>\n </>\n );\n}\n\nfunction ViewRow<V extends SavedViewLike>({\n view,\n handlers,\n labels,\n testIdPrefix,\n}: {\n view: V;\n handlers: RowHandlers<V>;\n labels: SavedViewsLabels;\n testIdPrefix: string;\n}): React.JSX.Element {\n return (\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }} data-testid={`${testIdPrefix}-row-${view.id}`}>\n <Box\n onClick={() => handlers.apply(view)}\n sx={{ flex: 1, minWidth: 0, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 0.75 }}\n data-testid={`${testIdPrefix}-apply-${view.id}`}\n >\n <Typography component=\"span\" sx={{ fontSize: '0.875rem' }}>\n {view.name}\n </Typography>\n {view.isDefault && <DefaultTag label={labels.defaultTag} testId={`${testIdPrefix}-default-${view.id}`} />}\n </Box>\n <ViewKebab view={view} handlers={handlers} labels={labels} testIdPrefix={testIdPrefix} />\n </Stack>\n );\n}\n\nfunction ViewSection<V extends SavedViewLike>({\n title,\n list,\n sectionKey,\n handlers,\n labels,\n testIdPrefix,\n}: {\n title: string;\n list: V[];\n sectionKey: string;\n handlers: RowHandlers<V>;\n labels: SavedViewsLabels;\n testIdPrefix: string;\n}): React.JSX.Element | null {\n if (list.length === 0) return null;\n return (\n <Box data-testid={`${testIdPrefix}-section-${sectionKey}`}>\n <Typography component=\"span\" sx={{ fontSize: '0.75rem', fontWeight: 600, color: 'text.secondary' }}>\n {title}\n </Typography>\n <Stack spacing={0.5} sx={{ mt: 0.5 }}>\n {list.map((view) => (\n <ViewRow key={view.id} view={view} handlers={handlers} labels={labels} testIdPrefix={testIdPrefix} />\n ))}\n </Stack>\n </Box>\n );\n}\n\n/** A borderless footer text button (Save current / Manage all). */\nfunction FooterButton({\n label,\n testId,\n onClick,\n}: {\n label: string;\n testId: string;\n onClick: () => void;\n}): React.JSX.Element {\n return (\n <Button variant=\"text\" size=\"small\" color=\"inherit\" onClick={onClick} data-testid={testId} sx={{ textTransform: 'none' }}>\n {label}\n </Button>\n );\n}\n\n/** The popover contents: the built-in Main vision default, saved-view sections, and footer. */\nfunction PopoverBody<V extends SavedViewLike>({\n views,\n pinned,\n recent,\n activeViewName,\n labels,\n handlers,\n onSelectMain,\n onSaveCurrent,\n onManageAll,\n testIdPrefix,\n}: {\n views: V[];\n pinned: V[];\n recent: V[];\n activeViewName?: string;\n labels: SavedViewsLabels;\n handlers: RowHandlers<V>;\n onSelectMain: () => void;\n onSaveCurrent: () => void;\n onManageAll: () => void;\n testIdPrefix: string;\n}): React.JSX.Element {\n return (\n <Stack spacing={1.5} sx={{ p: 1.5, width: 300 }} data-testid={`${testIdPrefix}-popover`}>\n {/* Built-in no-filter default, always available above the saved views. */}\n <MenuItem data-testid={`${testIdPrefix}-main`} selected={!activeViewName} onClick={onSelectMain} sx={{ borderRadius: 1, px: 1, gap: 1 }}>\n <Box component=\"span\" sx={{ flex: 1, minWidth: 0, fontSize: '0.875rem' }}>\n {labels.mainView}\n </Box>\n {!activeViewName && <CheckIcon sx={{ fontSize: 16, color: 'primary.main' }} />}\n </MenuItem>\n {views.length === 0 ? (\n <Typography sx={{ fontSize: '0.75rem', color: 'text.secondary' }}>{labels.empty}</Typography>\n ) : (\n <>\n <ViewSection title={labels.pinned} list={pinned} sectionKey=\"pinned\" handlers={handlers} labels={labels} testIdPrefix={testIdPrefix} />\n <ViewSection title={labels.recent} list={recent} sectionKey=\"recent\" handlers={handlers} labels={labels} testIdPrefix={testIdPrefix} />\n </>\n )}\n <Box sx={{ borderTop: 1, borderColor: 'divider', pt: 1 }}>\n <Stack spacing={0.5} sx={{ alignItems: 'flex-start' }}>\n <FooterButton label={labels.saveCurrent} testId={`${testIdPrefix}-save-current`} onClick={onSaveCurrent} />\n <FooterButton label={labels.manageAll} testId={`${testIdPrefix}-manage-all`} onClick={onManageAll} />\n </Stack>\n </Box>\n </Stack>\n );\n}\n\n/**\n * Stateless saved-views dropdown: a neutral trigger (styled like the sibling\n * toolbar controls) that shows `activeViewName` when a view is applied, else the\n * built-in \"Main vision\" label. The popover lists the Main vision default plus\n * pinned + recent views; a per-view ⋮ exposes owner-only mutations. This\n * component owns NO data — every action is a callback, so a page-level Connector\n * wires it to the backend.\n */\nexport function SavedViewsMenu<V extends SavedViewLike = SavedViewLike>({\n views,\n activeViewName,\n onApply,\n onSelectMain,\n onSaveCurrent,\n onEdit,\n onDelete,\n onSetDefault,\n onTogglePin,\n onToggleShare,\n onManageAll,\n labels: labelOverrides,\n testIdPrefix = 'views',\n}: SavedViewsMenuProps<V>): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);\n const close = (): void => setAnchorEl(null);\n const runAndClose = (action: () => void) => (): void => {\n action();\n close();\n };\n const labels = labelOverrides;\n const pinned = views.filter((view) => view.pinned);\n const recent = views.filter((view) => !view.pinned).slice(0, RECENT_LIMIT);\n\n const handlers: RowHandlers<V> = {\n apply: (view) => {\n onApply(view);\n close();\n },\n onEdit,\n onDelete,\n onSetDefault,\n onTogglePin,\n onToggleShare,\n };\n\n return (\n <>\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n onClick={(event) => setAnchorEl(event.currentTarget)}\n data-testid={`${testIdPrefix}-button`}\n aria-haspopup=\"menu\"\n aria-expanded={Boolean(anchorEl)}\n aria-label={activeViewName ?? labels.mainView}\n sx={{ minWidth: 0, height: 32, px: 1, gap: 0.5, color: 'text.primary', textTransform: 'none', fontWeight: 600 }}\n >\n {/* Mobile: an eye icon stands in for the view name to keep the toolbar one line. */}\n <ViewIcon sx={{ fontSize: 18, display: { xs: 'inline-flex', md: 'none' } }} />\n <Box component=\"span\" sx={{ display: { xs: 'none', md: 'inline' } }}>\n {activeViewName ?? labels.mainView}\n </Box>\n <ChevronDownIcon sx={{ fontSize: 14 }} />\n </Button>\n <Popover\n open={Boolean(anchorEl)}\n anchorEl={anchorEl}\n onClose={close}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n >\n <PopoverBody\n views={views}\n pinned={pinned}\n recent={recent}\n activeViewName={activeViewName}\n labels={labels}\n handlers={handlers}\n onSelectMain={runAndClose(onSelectMain)}\n onSaveCurrent={runAndClose(onSaveCurrent)}\n onManageAll={runAndClose(onManageAll)}\n testIdPrefix={testIdPrefix}\n />\n </Popover>\n </>\n );\n}\n"],"mappings":"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","names":["Box","Button","jsx","jsxs","CheckIcon","ChevronDownIcon","Box","Button","Divider","Menu","MenuItem","Typography","useState","jsx","jsxs","Box","Button","Checkbox","Divider","ListSubheader","Menu","MenuItem","useState","ChevronDownIcon","Box","Button","Typography","jsx","jsxs","buildTriggerLabel","Fragment","jsx","jsxs","MenuItem","Checkbox","Box","useState","buildTriggerLabel","Menu","Divider","ListSubheader","Button","Box","Button","jsx","jsxs","Box","Checkbox","ListSubheader","Menu","MenuItem","useState","Fragment","jsx","jsxs","CheckIcon","ChevronDownIcon","Box","Button","IconButton","Menu","MenuItem","Typography","useState","Fragment","jsx","jsxs"]}
@@ -1 +0,0 @@
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"]}