@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
@@ -76,10 +76,11 @@ function TypeToConfirmField({
76
76
  value,
77
77
  onChange,
78
78
  disabled,
79
- dataTestId
79
+ dataTestId,
80
+ copy
80
81
  }) {
81
82
  return /* @__PURE__ */ jsxs(Stack, { spacing: 1, sx: { mt: 2 }, children: [
82
- /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: label ?? `Digite "${expected}" para confirmar.` }),
83
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: label ?? copy.typeToConfirm(expected) }),
83
84
  /* @__PURE__ */ jsx(
84
85
  TextField,
85
86
  {
@@ -88,7 +89,7 @@ function TypeToConfirmField({
88
89
  disabled,
89
90
  onChange: (event) => onChange(event.target.value),
90
91
  inputProps: {
91
- "aria-label": label ?? `Digite ${expected} para confirmar`,
92
+ "aria-label": label ?? copy.typeToConfirm(expected),
92
93
  "data-testid": `${dataTestId}-type-to-confirm`
93
94
  }
94
95
  }
@@ -122,7 +123,7 @@ function ConfirmActionDialog({
122
123
  title,
123
124
  description: confirmBody(description, copy, entityName),
124
125
  confirmText,
125
- cancelText,
126
+ cancelText: cancelText ?? copy.cancel,
126
127
  loading: state.pending,
127
128
  confirmDisabled: gateUnmet,
128
129
  initialFocus: resolveInitialFocus(tone, initialFocus),
@@ -140,7 +141,8 @@ function ConfirmActionDialog({
140
141
  value: typed,
141
142
  onChange: setTyped,
142
143
  disabled: state.pending,
143
- dataTestId
144
+ dataTestId,
145
+ copy
144
146
  }
145
147
  )
146
148
  ]
@@ -212,4 +214,4 @@ export {
212
214
  withConfirmation,
213
215
  createConfirmButton
214
216
  };
215
- //# sourceMappingURL=chunk-MXPXKORR.js.map
217
+ //# sourceMappingURL=chunk-5TCPZ6GR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/feedback/ConfirmAction/ConfirmAction.hooks.ts","../src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx","../src/components/feedback/ConfirmAction/ConfirmAction.tsx","../src/components/feedback/ConfirmAction/with-confirmation.tsx","../src/components/feedback/ConfirmAction/ConfirmButton.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport type { ConfirmHandler, UseConfirmActionResult } from './ConfirmAction.types';\n\n/** Used when the guarded action rejects and the caller supplied no wording. */\n\n\n/**\n * What the popup says after a failed attempt.\n *\n * A rejection carrying a message wins: the server's sentence (\"esta categoria\n * ainda tem produtos vinculados\") is the one the operator can act on, and it is\n * strictly better than the generic fallback. Handlers that have nothing useful\n * to say reject with nothing and get `errorText`.\n */\nfunction failureMessage(cause: unknown, errorText: string): string {\n if (cause instanceof Error && cause.message) return cause.message;\n return errorText;\n}\n\n/**\n * The confirmation state machine, headless.\n *\n * It is the whole safety contract in one place, so every consumer gets the same\n * behaviour: the action runs ONLY from `confirm`, never from opening the popup;\n * a second confirm while the first is in flight is dropped (a double-click\n * cannot send two deletes); a rejection keeps the popup open carrying the\n * failure instead of closing over a write that never happened.\n */\nexport function useConfirmAction(\n onConfirm: ConfirmHandler,\n errorText: string,\n): UseConfirmActionResult {\n const [open, setOpen] = useState(false);\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // `pending` is mirrored in a ref because the two guards that matter — drop a\n // second confirm, ignore a cancel mid-flight — are read inside callbacks that\n // must not be rebuilt on every state change. Reading the state variable there\n // would leave a stale closure holding `false` for the whole in-flight window,\n // which is exactly the double-submit this component exists to prevent.\n const busy = useRef(false);\n\n // The action can settle after the trigger has unmounted (a row deleted from\n // under its own menu), so the settle path must not touch state by then.\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n\n const request = useCallback((): void => {\n setError(null);\n setOpen(true);\n }, []);\n\n const cancel = useCallback((): void => {\n // Inert mid-flight: the write has already left, and closing here would hide\n // its outcome.\n if (busy.current) return;\n setOpen(false);\n setError(null);\n }, []);\n\n const settle = useCallback((failure: string | null): void => {\n busy.current = false;\n if (!mounted.current) return;\n setPending(false);\n setError(failure);\n if (!failure) setOpen(false);\n }, []);\n\n const confirm = useCallback((): void => {\n if (busy.current) return;\n busy.current = true;\n setPending(true);\n setError(null);\n // The handler is invoked synchronously, exactly as a plain `onClick` would\n // be — only the OUTCOME is awaited. The try/catch is what puts a handler\n // that throws synchronously on the same failure path as one that returns a\n // rejected promise.\n try {\n const result = onConfirm();\n void Promise.resolve(result)\n .then(() => settle(null))\n .catch((cause: unknown) => settle(failureMessage(cause, errorText)));\n } catch (cause) {\n settle(failureMessage(cause, errorText));\n }\n }, [errorText, onConfirm, settle]);\n\n return { open, pending, error, request, cancel, confirm };\n}\n","import type { ConfirmActionCopy } from \"../../../copy\";\nimport { Alert, Stack, TextField, Typography } from '@mui/material';\nimport React, { type ReactNode } from 'react';\n\nimport { AlertDialog } from '../../data-display/AlertDialog';\n\nimport type {\n ConfirmInitialFocus,\n ConfirmOptions,\n ConfirmTone,\n UseConfirmActionResult,\n} from './ConfirmAction.types';\n\nconst DEFAULT_TEST_ID = 'confirm-action';\n\n/**\n * The popup's body: the row being acted on, then what happens to it.\n *\n * The NAME is rendered in its own right rather than woven into the sentence, so\n * it is there whatever the caller wrote — \"the popup names the specific entity\"\n * is the one thing that must not depend on each call site remembering to\n * mention it. A body with neither a name nor a description would leave the\n * operator with only the title to decide on, so a neutral fallback covers that.\n */\nfunction confirmBody(\n description: ReactNode,\n copy: ConfirmActionCopy,\n entityName?: string,\n): ReactNode {\n if (!entityName) return description ?? copy.irreversible;\n return (\n <>\n <Typography component=\"span\" sx={{ fontWeight: 600, display: \"block\" }}>\n {entityName}\n </Typography>\n {description}\n </>\n );\n}\n\n/** Destructive dialogs open on Cancel; anything else opens on the confirm. */\nfunction resolveInitialFocus(\n tone: ConfirmTone,\n initialFocus?: ConfirmInitialFocus,\n): ConfirmInitialFocus {\n if (initialFocus) return initialFocus;\n return tone === 'destructive' ? 'cancel' : 'confirm';\n}\n\n/**\n * The type-to-confirm field. Rendered only when `typeToConfirm` is set, which\n * should be rare: it is the guard for actions with NO recovery path, where a\n * click is too cheap a gesture. Comparison is exact — trimmed of surrounding\n * whitespace only, so a trailing space from a paste does not read as a mismatch.\n */\nfunction TypeToConfirmField({\n expected,\n label,\n value,\n onChange,\n disabled,\n dataTestId,\n copy,\n}: {\n expected: string;\n label?: string;\n /** The words this prompt renders. REQUIRED — no default copy. */\n copy: ConfirmActionCopy;\n value: string;\n onChange: (next: string) => void;\n disabled: boolean;\n dataTestId: string;\n}): React.ReactElement {\n return (\n <Stack spacing={1} sx={{ mt: 2 }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {label ?? copy.typeToConfirm(expected)}\n </Typography>\n <TextField\n size=\"small\"\n value={value}\n disabled={disabled}\n onChange={(event) => onChange(event.target.value)}\n // On the INPUT rather than the wrapper: a test id on MUI's TextField\n // lands on the outer div, which is not the node a test can type into.\n inputProps={{\n 'aria-label': label ?? copy.typeToConfirm(expected),\n 'data-testid': `${dataTestId}-type-to-confirm`,\n }}\n />\n </Stack>\n );\n}\n\nexport interface ConfirmActionDialogProps extends ConfirmOptions {\n /** The fallback body when no entity is named. REQUIRED — no default copy. */\n copy: ConfirmActionCopy;\n state: UseConfirmActionResult;\n}\n\n/**\n * The popup itself: an `AlertDialog` in its destructive skin, plus the two\n * things a bare AlertDialog has no opinion about — the failure the last attempt\n * produced (shown IN the dialog, which stays open, rather than closing over a\n * write that never landed) and the optional type-to-confirm gate.\n */\nexport function ConfirmActionDialog({\n state,\n title,\n description,\n entityName,\n confirmText,\n cancelText,\n typeToConfirm,\n typeToConfirmLabel,\n tone = 'destructive',\n initialFocus,\n dataTestId = DEFAULT_TEST_ID,\n copy,\n}: ConfirmActionDialogProps): React.ReactElement {\n const [typed, setTyped] = React.useState('');\n\n // Every fresh open starts from an empty field: carrying the previous answer\n // over would hand the next delete a pre-satisfied gate.\n React.useEffect(() => {\n if (state.open) setTyped('');\n }, [state.open]);\n\n const gateUnmet = typeToConfirm !== undefined && typed.trim() !== typeToConfirm;\n\n return (\n <AlertDialog\n open={state.open}\n variant={tone === 'destructive' ? 'destructive' : 'default'}\n title={title}\n description={confirmBody(description, copy, entityName)}\n confirmText={confirmText}\n // `copy.cancel` is the fallback, NOT `AlertDialog`'s own. The 6.3.0 copy\n // sweep deleted this component's `cancelText = 'Cancelar'` default and\n // put the word in `ConfirmActionCopy` — where nothing then read it, so\n // every confirmation that names no `cancelText` of its own fell through\n // to `AlertDialog`'s English `'Cancel'`, in a pt-BR dialog. That is the\n // precise failure the sweep exists to prevent, one layer down: a port\n // that is required, supplied, and ignored.\n cancelText={cancelText ?? copy.cancel}\n loading={state.pending}\n confirmDisabled={gateUnmet}\n initialFocus={resolveInitialFocus(tone, initialFocus)}\n onConfirm={state.confirm}\n onCancel={state.cancel}\n onClose={state.cancel}\n data-testid={dataTestId}\n >\n {state.error && (\n <Alert severity=\"error\" sx={{ mt: 1 }} data-testid={`${dataTestId}-error`}>\n {state.error}\n </Alert>\n )}\n {typeToConfirm !== undefined && (\n <TypeToConfirmField\n expected={typeToConfirm}\n label={typeToConfirmLabel}\n value={typed}\n onChange={setTyped}\n disabled={state.pending}\n dataTestId={dataTestId}\n copy={copy}\n />\n )}\n </AlertDialog>\n );\n}\n","import React from 'react';\n\nimport { useConfirmAction } from './ConfirmAction.hooks';\nimport { ConfirmActionDialog } from './ConfirmAction.parts';\nimport type { ConfirmActionProps } from './ConfirmAction.types';\n\n/**\n * Wraps any trigger in a confirmation popup.\n *\n * The trigger is a render prop rather than a fixed element, so the same guard\n * covers a button, a dropdown item, an icon or a table row action without this\n * component knowing what any of them look like. The guarded handler runs ONLY\n * after the operator confirms:\n *\n * ```tsx\n * <ConfirmAction\n * title=\"Excluir a categoria?\"\n * entityName={row.name}\n * description=\"Ela vai para a lixeira e pode ser restaurada de lá.\"\n * confirmText=\"Excluir\"\n * onConfirm={() => deleteCategoryAction({ tenantSlug, id: row.id })}\n * >\n * {(request) => <Button color=\"danger\" onClick={request}>Excluir</Button>}\n * </ConfirmAction>\n * ```\n *\n * For the common case — an existing button whose `onClick` is already the\n * destructive write — reach for {@link withConfirmation} instead, which needs\n * no restructuring of the call site.\n */\nexport function ConfirmAction({\n onConfirm,\n children,\n ...options\n}: ConfirmActionProps): React.ReactElement {\n const state = useConfirmAction(onConfirm, options.errorText);\n\n return (\n <>\n {children(state.request, { pending: state.pending })}\n <ConfirmActionDialog state={state} {...options} />\n </>\n );\n}\n\nConfirmAction.displayName = 'ConfirmAction';\n","import type { ConfirmActionCopy } from '../../../copy';\nimport React from 'react';\nimport type { ComponentType } from 'react';\n\nimport { useConfirmAction } from './ConfirmAction.hooks';\nimport { ConfirmActionDialog } from './ConfirmAction.parts';\nimport type {\n ConfirmHandler,\n ConfirmOptions,\n ConfirmableComponent,\n ConfirmableProps,\n WithConfirmationProps,\n} from './ConfirmAction.types';\n\n/**\n * Merge the HOC's baked-in defaults with the per-instance `confirm` prop.\n * Returns null when the instance opts out (`confirm={false}`) or when neither\n * side supplies the two fields a confirmation cannot be written without — the\n * question and the verb. A null result means \"render the plain component\",\n * which keeps the wrapped export usable in harmless contexts.\n */\nfunction resolveOptions(\n defaults: Partial<ConfirmOptions> | undefined,\n instance: Partial<ConfirmOptions> | false | undefined,\n): ConfirmOptions | null {\n if (instance === false) return null;\n const merged = { ...defaults, ...instance };\n if (!merged.title || !merged.confirmText) return null;\n return { ...merged, title: merged.title, confirmText: merged.confirmText };\n}\n\n/**\n * Adapt the wrapped component's `onClick` into a {@link ConfirmHandler}.\n *\n * The click argument is dropped (see `ConfirmHandler`) and the return value is\n * narrowed: a promise is handed back so the popup can hold its pending state\n * until the write settles, anything else becomes `undefined`. A component with\n * no `onClick` has nothing to guard, so confirming is a no-op.\n */\nfunction useGuardedHandler(onClick: ConfirmableProps['onClick']): ConfirmHandler {\n return React.useCallback((): void | Promise<unknown> => {\n const result = onClick?.();\n return result instanceof Promise ? result : undefined;\n }, [onClick]);\n}\n\n/**\n * Give any click-driven component a confirmation popup, without restructuring\n * the call site.\n *\n * The wrapped component's own `onClick` becomes the GUARDED action: clicking\n * now opens the popup, and the handler runs only if the operator confirms. It\n * inherits the whole contract from `useConfirmAction` — cancel sends nothing, a\n * returned promise holds the popup in its pending state so a double-click\n * cannot fire two writes, and a rejection keeps the popup open carrying the\n * error.\n *\n * ```tsx\n * const ConfirmButton = withConfirmation(Button);\n *\n * <ConfirmButton\n * color=\"danger\"\n * onClick={() => deleteCategoryAction({ tenantSlug, id: row.id })}\n * confirm={{\n * title: \"Excluir a categoria?\",\n * entityName: row.name,\n * description: \"Ela vai para a lixeira e pode ser restaurada de lá.\",\n * confirmText: \"Excluir\",\n * }}\n * >\n * Excluir\n * </ConfirmButton>\n * ```\n *\n * Bake the wording in once when the same guard repeats — `withConfirmation(Button,\n * { confirmText: \"Excluir\" })` — and let each instance override what differs.\n * `confirm={false}` falls through to the plain component.\n *\n * Refs are not forwarded: the HOC renders a fragment (trigger + popup), so there\n * is no single node to hand back. Wrap a component that needs a ref at its own\n * call site with {@link ConfirmAction} instead.\n */\nexport function withConfirmation<P extends ConfirmableProps>(\n Wrapped: ComponentType<P>,\n defaults: Partial<ConfirmOptions> & { errorText: string; copy: ConfirmActionCopy },\n): ConfirmableComponent<P> {\n function WithConfirmation(props: P & WithConfirmationProps): React.ReactElement {\n const { confirm, onClick } = props;\n const options = resolveOptions(defaults, confirm);\n const state = useConfirmAction(useGuardedHandler(onClick), defaults.errorText);\n\n // `confirm` is ours and must not reach the DOM — an unknown attribute on a\n // <button> is a React warning at every render. The cast is the standard HOC\n // one: TypeScript cannot prove `Omit<P & X, 'confirm'>` is still a `P`.\n const { confirm: _confirm, ...rest } = props;\n const forwarded = rest as unknown as P;\n\n if (!options) return <Wrapped {...forwarded} />;\n\n return (\n <>\n <Wrapped {...forwarded} onClick={state.request} />\n <ConfirmActionDialog state={state} {...options} copy={defaults.copy} />\n </>\n );\n }\n\n WithConfirmation.displayName = `withConfirmation(${\n Wrapped.displayName ?? Wrapped.name ?? 'Component'\n })`;\n\n return WithConfirmation;\n}\n","import type { ConfirmActionCopy } from '../../../copy';\nimport { Button } from '../../form/Button';\nimport type { ButtonProps } from '../../form/Button/Button.types';\n\nimport { withConfirmation } from './with-confirmation';\nimport type { ConfirmableComponent } from './ConfirmAction.types';\n\n/**\n * The library `Button`, already wrapped — the shape most call sites want.\n *\n * Adding the guard to an existing button is then an import swap plus the\n * `confirm` prop; the button's own props (colour, size, icon) are untouched.\n * The baked-in defaults are only the wording and tone every destructive\n * confirmation shares, and each instance can still override them.\n */\nexport function createConfirmButton(\n copy: ConfirmActionCopy,\n errorText: string,\n): ConfirmableComponent<ButtonProps> {\n return withConfirmation<ButtonProps>(Button, {\n cancelText: copy.cancel,\n tone: 'destructive',\n errorText,\n copy,\n });\n}\n"],"mappings":"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","names":["Fragment","jsx","jsxs","React","Fragment","jsx","jsxs","React"]}
@@ -20,7 +20,8 @@ function SelectionCluster({
20
20
  actions,
21
21
  selectAllTestId,
22
22
  clearAllTestId,
23
- edgeAlign = false
23
+ edgeAlign = false,
24
+ selectAllLabel
24
25
  }) {
25
26
  const actionsSlot = actions !== void 0 && /* @__PURE__ */ jsx(Box, { sx: { ml: 0.5, display: "flex", flexShrink: 0, alignItems: "center" }, children: actions });
26
27
  return /* @__PURE__ */ jsxs(
@@ -56,7 +57,7 @@ function SelectionCluster({
56
57
  checked: hasSelection,
57
58
  onChange: (event) => event.target.checked ? selectAll() : clearSelection(),
58
59
  "data-testid": `${selectAllTestId}-checkbox`,
59
- inputProps: { "aria-label": "Selecionar todos" },
60
+ inputProps: { "aria-label": selectAllLabel },
60
61
  sx: { p: 0.5, display: { xs: "inline-flex", md: "none" } }
61
62
  }
62
63
  ),
@@ -155,7 +156,8 @@ function ContentToolbar({
155
156
  selectAllTestId,
156
157
  clearAllTestId,
157
158
  edgeAlign = false,
158
- exclusiveSelection = false
159
+ exclusiveSelection = false,
160
+ selectAllLabel
159
161
  }) {
160
162
  const showSelection = !exclusiveSelection || hasSelection;
161
163
  const showControls = !exclusiveSelection || !hasSelection;
@@ -188,6 +190,7 @@ function ContentToolbar({
188
190
  actions,
189
191
  selectAllTestId,
190
192
  clearAllTestId,
193
+ selectAllLabel,
191
194
  edgeAlign
192
195
  }
193
196
  ),
@@ -565,7 +568,8 @@ function PillTrigger({
565
568
  onOpen,
566
569
  testId,
567
570
  selectedCount,
568
- onClear
571
+ onClear,
572
+ clearLabel
569
573
  }) {
570
574
  const active = selectedCount > 0;
571
575
  return /* @__PURE__ */ jsxs4(
@@ -584,7 +588,7 @@ function PillTrigger({
584
588
  component: "span",
585
589
  role: "button",
586
590
  tabIndex: 0,
587
- "aria-label": `Limpar ${label}`,
591
+ "aria-label": clearLabel,
588
592
  "data-testid": testId ? `${testId}-clear` : void 0,
589
593
  onClick: (event) => {
590
594
  event.stopPropagation();
@@ -657,6 +661,7 @@ function MultiSelectDropdown({
657
661
  onToggle,
658
662
  onClear,
659
663
  allLabel = "All",
664
+ clearLabel,
660
665
  extraOptions,
661
666
  searchable,
662
667
  searchPlaceholder = "Search\u2026",
@@ -689,6 +694,7 @@ function MultiSelectDropdown({
689
694
  return /* @__PURE__ */ jsx5(
690
695
  PillTrigger,
691
696
  {
697
+ clearLabel,
692
698
  label,
693
699
  selectedCount: selected.size,
694
700
  onClear,
@@ -1242,4 +1248,4 @@ export {
1242
1248
  ColumnsMenu,
1243
1249
  SavedViewsMenu
1244
1250
  };
1245
- //# sourceMappingURL=chunk-R5ZQZSEQ.js.map
1251
+ //# sourceMappingURL=chunk-NUCLEOHF.js.map
@@ -0,0 +1 @@
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'\n | 'selectedCount'\n | 'selectAll'\n | 'clearSelection'\n | 'actions'\n | 'selectAllTestId'\n | 'clearAllTestId'\n | 'edgeAlign'\n | 'selectAllLabel'\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 selectAllLabel,\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': selectAllLabel }}\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 selectAllLabel,\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 selectAllLabel={selectAllLabel}\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 clearLabel,\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 clearLabel={clearLabel}\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. */\n/** The pill's own props, above the component so the signature stays short. */\nexport type PillTriggerProps = TriggerProps & {\n selectedCount: number;\n onClear?: () => void;\n /**\n * The clear affordance's accessible name — the pill's own label is already\n * on screen, so this is the only thing a screen reader gets for the little\n * cross. REQUIRED: this package ships no default copy.\n */\n clearLabel: string;\n};\n\nexport function PillTrigger({\n label,\n open,\n onOpen,\n testId,\n selectedCount,\n onClear,\n clearLabel,\n}: PillTriggerProps): 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={clearLabel}\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"]}
@@ -908,7 +908,8 @@ var linkButtonSx = {
908
908
  };
909
909
  function CategoryQuickActions({
910
910
  state,
911
- dataTestId
911
+ dataTestId,
912
+ copy
912
913
  }) {
913
914
  const allLeafIds = useMemo(() => collectLeafIds(state.allGroups), [state.allGroups]);
914
915
  const everythingPicked = allLeafIds.length > 0 && state.draft.size >= allLeafIds.length;
@@ -923,7 +924,7 @@ function CategoryQuickActions({
923
924
  "data-testid": `${dataTestId}-select-all`,
924
925
  sx: linkButtonSx,
925
926
  onClick: () => state.setDraft(everythingPicked ? /* @__PURE__ */ new Set() : new Set(allLeafIds)),
926
- children: everythingPicked ? "Desmarcar tudo" : "Marcar tudo"
927
+ children: everythingPicked ? copy.deselectAll : copy.selectAll
927
928
  }
928
929
  ),
929
930
  /* @__PURE__ */ jsx6(Box5, { component: "span", sx: { color: "divider" }, children: "\xB7" }),
@@ -935,7 +936,7 @@ function CategoryQuickActions({
935
936
  "data-testid": `${dataTestId}-expand-all`,
936
937
  sx: linkButtonSx,
937
938
  onClick: () => state.setAllExpanded(!allExpanded),
938
- children: allExpanded ? "Recolher tudo" : "Expandir tudo"
939
+ children: allExpanded ? copy.collapseAll : copy.expandAll
939
940
  }
940
941
  )
941
942
  ] });
@@ -981,7 +982,7 @@ function CategoryPanel({
981
982
  query: state.query,
982
983
  placeholder: single ? copy.search.placeholderSingle : copy.search.placeholderMulti,
983
984
  sheet,
984
- quickActions: single ? void 0 : /* @__PURE__ */ jsx7(CategoryQuickActions, { state, dataTestId }),
985
+ quickActions: single ? void 0 : /* @__PURE__ */ jsx7(CategoryQuickActions, { state, dataTestId, copy }),
985
986
  onQueryChange: state.setQuery,
986
987
  searchInputRef,
987
988
  dataTestId
@@ -1486,7 +1487,7 @@ function resolveConfig(props) {
1486
1487
  const single = props.mode === "single";
1487
1488
  return {
1488
1489
  single,
1489
- placeholder: props.placeholder ?? (single ? "Mover para\u2026" : "Categoria"),
1490
+ placeholder: props.placeholder ?? (single ? props.copy.placeholderSingle : props.copy.placeholderMulti),
1490
1491
  disabled: props.disabled ?? false,
1491
1492
  loading: props.loading ?? false,
1492
1493
  fullWidth: props.fullWidth ?? false,
@@ -1599,4 +1600,4 @@ export {
1599
1600
  filterCategoryGroups,
1600
1601
  CategorySelect
1601
1602
  };
1602
- //# sourceMappingURL=chunk-TPQRIPCN.js.map
1603
+ //# sourceMappingURL=chunk-ZF5ERIC4.js.map