@12-apps/ui 6.1.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components-catalog.md +8 -0
- package/dist/{chunk-35VGGLOC.js → chunk-CEKPLUQV.js} +2 -2
- package/dist/{chunk-35VGGLOC.js.map → chunk-CEKPLUQV.js.map} +1 -1
- package/dist/{chunk-62XQWGXU.js → chunk-MXPXKORR.js} +19 -17
- package/dist/chunk-MXPXKORR.js.map +1 -0
- package/dist/{chunk-7XLEWBKL.js → chunk-N554AFDB.js} +7 -10
- package/dist/chunk-N554AFDB.js.map +1 -0
- package/dist/{chunk-JDO7W4D4.js → chunk-R5ZQZSEQ.js} +2 -20
- package/dist/{chunk-JDO7W4D4.js.map → chunk-R5ZQZSEQ.js.map} +1 -1
- package/dist/{chunk-R4TYXKDD.js → chunk-TPQRIPCN.js} +52 -48
- package/dist/chunk-TPQRIPCN.js.map +1 -0
- package/dist/copy.js +1 -0
- package/dist/copy.js.map +1 -0
- package/dist/data-display/CardKit.js +277 -0
- package/dist/data-display/CardKit.js.map +1 -0
- package/dist/data-display/DataViews.js +664 -616
- package/dist/data-display/DataViews.js.map +1 -1
- package/dist/data-display/SectionOnboarding.js +3 -3
- package/dist/data-display/SectionOnboarding.js.map +1 -1
- package/dist/feedback/ConfirmAction.js +3 -5
- package/dist/form/CategorySelect.js +1 -1
- package/dist/form/CepField.js +1 -1
- package/dist/form/total-form.js +8 -4
- package/dist/form/total-form.js.map +1 -1
- package/dist/layout/ContentToolbar.js +1 -1
- package/dist/layout/TableFilter.js +1 -1
- package/dist/pt-BR.js +222 -0
- package/dist/pt-BR.js.map +1 -0
- package/dist/types/components/data-display/CardKit/CardKebab.d.ts +23 -0
- package/dist/types/components/data-display/CardKit/CardKebab.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/CardKit.types.d.ts +55 -0
- package/dist/types/components/data-display/CardKit/CardKit.types.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/card-actions-context.d.ts +51 -0
- package/dist/types/components/data-display/CardKit/card-actions-context.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/index.d.ts +15 -0
- package/dist/types/components/data-display/CardKit/index.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/list-card-parts.d.ts +60 -0
- package/dist/types/components/data-display/CardKit/list-card-parts.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/row-actions-to-menu.d.ts +17 -0
- package/dist/types/components/data-display/CardKit/row-actions-to-menu.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/use-remove-confirm.d.ts +65 -0
- package/dist/types/components/data-display/CardKit/use-remove-confirm.d.ts.map +1 -0
- package/dist/types/components/data-display/CardKit/use-row-confirm.d.ts +60 -0
- package/dist/types/components/data-display/CardKit/use-row-confirm.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/DataViewsBoard.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/DeleteViewDialog.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/ManageViewsDialog.d.ts +4 -1
- package/dist/types/components/data-display/DataViews/ManageViewsDialog.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/SaveViewModal.d.ts +0 -5
- package/dist/types/components/data-display/DataViews/SaveViewModal.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/base-card.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/base-list-card-gutters.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-bar-controls.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-category-pill.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-columns-tab.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-copy-context.d.ts +17 -0
- package/dist/types/components/data-display/DataViews/data-views-copy-context.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +205 -0
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/data-views-display-panel.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-display-tabs.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-export.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-filter-panel.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-grid-helpers.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-more-filters.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-range-presets.d.ts +3 -2
- package/dist/types/components/data-display/DataViews/data-views-range-presets.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-scopes.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-search.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-select-all-strip.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-table-parts.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-view-nav.d.ts +1 -1
- package/dist/types/components/data-display/DataViews/data-views-view-nav.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/index.d.ts +2 -0
- package/dist/types/components/data-display/DataViews/index.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/save-view-preview.d.ts +10 -0
- package/dist/types/components/data-display/DataViews/save-view-preview.d.ts.map +1 -0
- package/dist/types/components/data-display/DataViews/use-saved-views-controller.d.ts.map +1 -1
- package/dist/types/components/data-display/SectionOnboarding/SectionOnboarding.types.d.ts +6 -5
- package/dist/types/components/data-display/SectionOnboarding/SectionOnboarding.types.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.hooks.d.ts +1 -3
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.hooks.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.parts.d.ts +4 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.parts.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.types.d.ts +9 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmAction.types.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmButton.d.ts +2 -1
- package/dist/types/components/feedback/ConfirmAction/ConfirmButton.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/index.d.ts +2 -2
- package/dist/types/components/feedback/ConfirmAction/index.d.ts.map +1 -1
- package/dist/types/components/feedback/ConfirmAction/with-confirmation.d.ts +5 -1
- package/dist/types/components/feedback/ConfirmAction/with-confirmation.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryPanel.d.ts +4 -1
- package/dist/types/components/form/CategorySelect/CategoryPanel.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryPanelFoot.d.ts +5 -2
- package/dist/types/components/form/CategorySelect/CategoryPanelFoot.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryPanelHead.d.ts +5 -2
- package/dist/types/components/form/CategorySelect/CategoryPanelHead.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryPanelList.d.ts +3 -0
- package/dist/types/components/form/CategorySelect/CategoryPanelList.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategorySelect.types.d.ts +5 -0
- package/dist/types/components/form/CategorySelect/CategorySelect.types.d.ts.map +1 -1
- package/dist/types/components/form/CategorySelect/CategoryTrigger.d.ts +4 -1
- package/dist/types/components/form/CategorySelect/CategoryTrigger.d.ts.map +1 -1
- package/dist/types/components/form/CepField/CepField.d.ts +1 -1
- package/dist/types/components/form/CepField/CepField.d.ts.map +1 -1
- package/dist/types/components/form/CepField/CepField.types.d.ts +3 -0
- package/dist/types/components/form/CepField/CepField.types.d.ts.map +1 -1
- package/dist/types/components/form/total-form/Fields/CategoryField.d.ts +4 -1
- package/dist/types/components/form/total-form/Fields/CategoryField.d.ts.map +1 -1
- package/dist/types/components/form/total-form/Fields/CepField.d.ts +4 -1
- package/dist/types/components/form/total-form/Fields/CepField.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts +6 -1
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/SavedViewsMenu.d.ts.map +1 -1
- package/dist/types/copy.d.ts +99 -0
- package/dist/types/copy.d.ts.map +1 -0
- package/dist/types/pt-BR.d.ts +28 -0
- package/dist/types/pt-BR.d.ts.map +1 -0
- package/dist/types/utils/export-rows.d.ts +31 -0
- package/dist/types/utils/export-rows.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/utils.js +50 -0
- package/dist/utils.js.map +1 -1
- package/package.json +14 -2
- package/src/components/data-display/CardKit/CardKebab.tsx +43 -0
- package/src/components/data-display/CardKit/CardKit.md +87 -0
- package/src/components/data-display/CardKit/CardKit.types.ts +60 -0
- package/src/components/data-display/CardKit/card-actions-context.tsx +98 -0
- package/src/components/data-display/CardKit/index.ts +19 -0
- package/src/components/data-display/CardKit/list-card-parts.tsx +163 -0
- package/src/components/data-display/CardKit/row-actions-to-menu.ts +29 -0
- package/src/components/data-display/CardKit/use-remove-confirm.tsx +111 -0
- package/src/components/data-display/CardKit/use-row-confirm.tsx +96 -0
- package/src/components/data-display/DataViews/DataViewsBoard.tsx +7 -4
- package/src/components/data-display/DataViews/DeleteViewDialog.tsx +6 -4
- package/src/components/data-display/DataViews/ManageViewsDialog.tsx +26 -10
- package/src/components/data-display/DataViews/SaveViewModal.tsx +56 -90
- package/src/components/data-display/DataViews/base-card.tsx +3 -1
- package/src/components/data-display/DataViews/base-list-card-gutters.tsx +3 -1
- package/src/components/data-display/DataViews/data-views-bar-controls.tsx +8 -5
- package/src/components/data-display/DataViews/data-views-category-pill.tsx +6 -3
- package/src/components/data-display/DataViews/data-views-columns-tab.tsx +5 -3
- package/src/components/data-display/DataViews/data-views-copy-context.tsx +43 -0
- package/src/components/data-display/DataViews/data-views-copy.ts +214 -0
- package/src/components/data-display/DataViews/data-views-display-panel.tsx +15 -9
- package/src/components/data-display/DataViews/data-views-display-tabs.tsx +19 -29
- package/src/components/data-display/DataViews/data-views-export.tsx +9 -10
- package/src/components/data-display/DataViews/data-views-filter-panel.tsx +9 -5
- package/src/components/data-display/DataViews/data-views-grid-helpers.tsx +5 -2
- package/src/components/data-display/DataViews/data-views-more-fields.tsx +5 -3
- package/src/components/data-display/DataViews/data-views-more-filters.tsx +6 -3
- package/src/components/data-display/DataViews/data-views-range-pill.tsx +9 -5
- package/src/components/data-display/DataViews/data-views-range-presets.ts +7 -8
- package/src/components/data-display/DataViews/data-views-scopes.tsx +3 -1
- package/src/components/data-display/DataViews/data-views-search.tsx +7 -4
- package/src/components/data-display/DataViews/data-views-select-all-strip.tsx +5 -3
- package/src/components/data-display/DataViews/data-views-table-parts.tsx +7 -2
- package/src/components/data-display/DataViews/data-views-view-nav.tsx +22 -16
- package/src/components/data-display/DataViews/index.ts +20 -0
- package/src/components/data-display/DataViews/save-view-preview.tsx +78 -0
- package/src/components/data-display/DataViews/use-saved-views-controller.ts +3 -1
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.tsx +3 -3
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.types.ts +8 -7
- package/src/components/feedback/ConfirmAction/ConfirmAction.hooks.ts +2 -2
- package/src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx +12 -5
- package/src/components/feedback/ConfirmAction/ConfirmAction.types.ts +9 -1
- package/src/components/feedback/ConfirmAction/ConfirmButton.tsx +12 -4
- package/src/components/feedback/ConfirmAction/index.ts +2 -2
- package/src/components/feedback/ConfirmAction/with-confirmation.tsx +4 -3
- package/src/components/form/CategorySelect/CategoryPanel.tsx +18 -6
- package/src/components/form/CategorySelect/CategoryPanelFoot.tsx +10 -5
- package/src/components/form/CategorySelect/CategoryPanelHead.tsx +8 -3
- package/src/components/form/CategorySelect/CategoryPanelList.tsx +17 -10
- package/src/components/form/CategorySelect/CategorySelect.tsx +3 -3
- package/src/components/form/CategorySelect/CategorySelect.types.ts +5 -0
- package/src/components/form/CategorySelect/CategoryTrigger.tsx +5 -1
- package/src/components/form/CepField/CepField.tsx +6 -9
- package/src/components/form/CepField/CepField.types.ts +3 -0
- package/src/components/form/total-form/Fields/CategoryField.tsx +5 -0
- package/src/components/form/total-form/Fields/CepField.tsx +5 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +6 -1
- package/src/components/layout/ContentToolbar/SavedViewsMenu.tsx +1 -21
- package/src/components/layout/TableFilter/TableFilter.tsx +1 -1
- package/src/copy.ts +103 -0
- package/src/pt-BR.ts +247 -0
- package/src/utils/export-rows.ts +95 -0
- package/src/utils/index.ts +1 -0
- package/dist/chunk-62XQWGXU.js.map +0 -1
- package/dist/chunk-7XLEWBKL.js.map +0 -1
- package/dist/chunk-R4TYXKDD.js.map +0 -1
|
@@ -100,8 +100,8 @@ const ConfiguredView: React.FC<SectionOnboardingProps> = ({
|
|
|
100
100
|
title,
|
|
101
101
|
configuredTitle,
|
|
102
102
|
configuredSummary,
|
|
103
|
-
editLabel
|
|
104
|
-
collapseLabel
|
|
103
|
+
editLabel,
|
|
104
|
+
collapseLabel,
|
|
105
105
|
defaultExpanded = false,
|
|
106
106
|
children,
|
|
107
107
|
className,
|
|
@@ -167,7 +167,7 @@ const HeroView: React.FC<SectionOnboardingProps & { onStart: () => void }> = ({
|
|
|
167
167
|
activeStepId,
|
|
168
168
|
completedStepIds,
|
|
169
169
|
primaryAction,
|
|
170
|
-
startLabel
|
|
170
|
+
startLabel,
|
|
171
171
|
secondaryAction,
|
|
172
172
|
helpLink,
|
|
173
173
|
children,
|
|
@@ -64,7 +64,14 @@ export interface SectionOnboardingProps {
|
|
|
64
64
|
* and `children` exist. Clicking it advances the hero to the in-progress view
|
|
65
65
|
* (steps + form) without the parent managing state. @default 'Começar'
|
|
66
66
|
*/
|
|
67
|
-
|
|
67
|
+
/** The button that begins the section. REQUIRED since FUT-760. */
|
|
68
|
+
startLabel: string;
|
|
69
|
+
|
|
70
|
+
/** Label of the reveal toggle in the configured state. */
|
|
71
|
+
editLabel: string;
|
|
72
|
+
|
|
73
|
+
/** Label of that toggle while the form is revealed. */
|
|
74
|
+
collapseLabel: string;
|
|
68
75
|
|
|
69
76
|
/** Optional secondary CTA of the hero — e.g. "Ver como funciona". */
|
|
70
77
|
secondaryAction?: SectionOnboardingAction;
|
|
@@ -81,12 +88,6 @@ export interface SectionOnboardingProps {
|
|
|
81
88
|
*/
|
|
82
89
|
configuredSummary?: ReactNode;
|
|
83
90
|
|
|
84
|
-
/** Label of the reveal toggle in the configured state. @default 'Editar' */
|
|
85
|
-
editLabel?: string;
|
|
86
|
-
|
|
87
|
-
/** Label of the reveal toggle while expanded. @default 'Ocultar' */
|
|
88
|
-
collapseLabel?: string;
|
|
89
|
-
|
|
90
91
|
/** Start the configured state with the form already revealed. @default false */
|
|
91
92
|
defaultExpanded?: boolean;
|
|
92
93
|
|
|
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
3
3
|
import type { ConfirmHandler, UseConfirmActionResult } from './ConfirmAction.types';
|
|
4
4
|
|
|
5
5
|
/** Used when the guarded action rejects and the caller supplied no wording. */
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* What the popup says after a failed attempt.
|
|
@@ -29,7 +29,7 @@ function failureMessage(cause: unknown, errorText: string): string {
|
|
|
29
29
|
*/
|
|
30
30
|
export function useConfirmAction(
|
|
31
31
|
onConfirm: ConfirmHandler,
|
|
32
|
-
errorText: string
|
|
32
|
+
errorText: string,
|
|
33
33
|
): UseConfirmActionResult {
|
|
34
34
|
const [open, setOpen] = useState(false);
|
|
35
35
|
const [pending, setPending] = useState(false);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ConfirmActionCopy } from "../../../copy";
|
|
1
2
|
import { Alert, Stack, TextField, Typography } from '@mui/material';
|
|
2
3
|
import React, { type ReactNode } from 'react';
|
|
3
4
|
|
|
@@ -10,7 +11,6 @@ import type {
|
|
|
10
11
|
UseConfirmActionResult,
|
|
11
12
|
} from './ConfirmAction.types';
|
|
12
13
|
|
|
13
|
-
const DEFAULT_CANCEL_TEXT = 'Cancelar';
|
|
14
14
|
const DEFAULT_TEST_ID = 'confirm-action';
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -22,8 +22,12 @@ const DEFAULT_TEST_ID = 'confirm-action';
|
|
|
22
22
|
* mention it. A body with neither a name nor a description would leave the
|
|
23
23
|
* operator with only the title to decide on, so a neutral fallback covers that.
|
|
24
24
|
*/
|
|
25
|
-
function confirmBody(
|
|
26
|
-
|
|
25
|
+
function confirmBody(
|
|
26
|
+
description: ReactNode,
|
|
27
|
+
copy: ConfirmActionCopy,
|
|
28
|
+
entityName?: string,
|
|
29
|
+
): ReactNode {
|
|
30
|
+
if (!entityName) return description ?? copy.irreversible;
|
|
27
31
|
return (
|
|
28
32
|
<>
|
|
29
33
|
<Typography component="span" sx={{ fontWeight: 600, display: "block" }}>
|
|
@@ -86,6 +90,8 @@ function TypeToConfirmField({
|
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
export interface ConfirmActionDialogProps extends ConfirmOptions {
|
|
93
|
+
/** The fallback body when no entity is named. REQUIRED — no default copy. */
|
|
94
|
+
copy: ConfirmActionCopy;
|
|
89
95
|
state: UseConfirmActionResult;
|
|
90
96
|
}
|
|
91
97
|
|
|
@@ -101,12 +107,13 @@ export function ConfirmActionDialog({
|
|
|
101
107
|
description,
|
|
102
108
|
entityName,
|
|
103
109
|
confirmText,
|
|
104
|
-
cancelText
|
|
110
|
+
cancelText,
|
|
105
111
|
typeToConfirm,
|
|
106
112
|
typeToConfirmLabel,
|
|
107
113
|
tone = 'destructive',
|
|
108
114
|
initialFocus,
|
|
109
115
|
dataTestId = DEFAULT_TEST_ID,
|
|
116
|
+
copy,
|
|
110
117
|
}: ConfirmActionDialogProps): React.ReactElement {
|
|
111
118
|
const [typed, setTyped] = React.useState('');
|
|
112
119
|
|
|
@@ -123,7 +130,7 @@ export function ConfirmActionDialog({
|
|
|
123
130
|
open={state.open}
|
|
124
131
|
variant={tone === 'destructive' ? 'destructive' : 'default'}
|
|
125
132
|
title={title}
|
|
126
|
-
description={confirmBody(description, entityName)}
|
|
133
|
+
description={confirmBody(description, copy, entityName)}
|
|
127
134
|
confirmText={confirmText}
|
|
128
135
|
cancelText={cancelText}
|
|
129
136
|
loading={state.pending}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ConfirmActionCopy } from "../../../copy";
|
|
1
2
|
import type { ComponentType, ReactNode } from 'react';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -43,7 +44,6 @@ export interface ConfirmOptions {
|
|
|
43
44
|
/** Defaults to `cancel` for the destructive tone, `confirm` otherwise. */
|
|
44
45
|
initialFocus?: ConfirmInitialFocus;
|
|
45
46
|
/** Shown inside the dialog when the action rejects; the dialog stays open. */
|
|
46
|
-
errorText?: string;
|
|
47
47
|
/** Root test id; the dialog's parts derive theirs from it. */
|
|
48
48
|
dataTestId?: string;
|
|
49
49
|
}
|
|
@@ -82,6 +82,14 @@ export interface UseConfirmActionResult {
|
|
|
82
82
|
* the trigger — a button, a menu item, an icon.
|
|
83
83
|
*/
|
|
84
84
|
export interface ConfirmActionProps extends ConfirmOptions {
|
|
85
|
+
/**
|
|
86
|
+
* What the operator is told when the action fails and the cause carries no
|
|
87
|
+
* message. REQUIRED since FUT-760 — it used to default to this package's own
|
|
88
|
+
* pt-BR, so a host that passed nothing shipped one product's Portuguese.
|
|
89
|
+
*/
|
|
90
|
+
errorText: string;
|
|
91
|
+
/** The fallback body when no entity is named. REQUIRED — see `errorText`. */
|
|
92
|
+
copy: ConfirmActionCopy;
|
|
85
93
|
onConfirm: ConfirmHandler;
|
|
86
94
|
children: (request: () => void, state: { pending: boolean }) => ReactNode;
|
|
87
95
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ConfirmActionCopy } from '../../../copy';
|
|
1
2
|
import { Button } from '../../form/Button';
|
|
2
3
|
import type { ButtonProps } from '../../form/Button/Button.types';
|
|
3
4
|
|
|
@@ -12,7 +13,14 @@ import type { ConfirmableComponent } from './ConfirmAction.types';
|
|
|
12
13
|
* The baked-in defaults are only the wording and tone every destructive
|
|
13
14
|
* confirmation shares, and each instance can still override them.
|
|
14
15
|
*/
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
)
|
|
16
|
+
export function createConfirmButton(
|
|
17
|
+
copy: ConfirmActionCopy,
|
|
18
|
+
errorText: string,
|
|
19
|
+
): ConfirmableComponent<ButtonProps> {
|
|
20
|
+
return withConfirmation<ButtonProps>(Button, {
|
|
21
|
+
cancelText: copy.cancel,
|
|
22
|
+
tone: 'destructive',
|
|
23
|
+
errorText,
|
|
24
|
+
copy,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ConfirmAction } from './ConfirmAction';
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
2
|
+
export { createConfirmButton } from './ConfirmButton';
|
|
3
|
+
export { useConfirmAction } from './ConfirmAction.hooks';
|
|
4
4
|
export { ConfirmActionDialog } from './ConfirmAction.parts';
|
|
5
5
|
export { withConfirmation } from './with-confirmation';
|
|
6
6
|
export type {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ConfirmActionCopy } from '../../../copy';
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import type { ComponentType } from 'react';
|
|
3
4
|
|
|
@@ -81,12 +82,12 @@ function useGuardedHandler(onClick: ConfirmableProps['onClick']): ConfirmHandler
|
|
|
81
82
|
*/
|
|
82
83
|
export function withConfirmation<P extends ConfirmableProps>(
|
|
83
84
|
Wrapped: ComponentType<P>,
|
|
84
|
-
defaults
|
|
85
|
+
defaults: Partial<ConfirmOptions> & { errorText: string; copy: ConfirmActionCopy },
|
|
85
86
|
): ConfirmableComponent<P> {
|
|
86
87
|
function WithConfirmation(props: P & WithConfirmationProps): React.ReactElement {
|
|
87
88
|
const { confirm, onClick } = props;
|
|
88
89
|
const options = resolveOptions(defaults, confirm);
|
|
89
|
-
const state = useConfirmAction(useGuardedHandler(onClick),
|
|
90
|
+
const state = useConfirmAction(useGuardedHandler(onClick), defaults.errorText);
|
|
90
91
|
|
|
91
92
|
// `confirm` is ours and must not reach the DOM — an unknown attribute on a
|
|
92
93
|
// <button> is a React warning at every render. The cast is the standard HOC
|
|
@@ -99,7 +100,7 @@ export function withConfirmation<P extends ConfirmableProps>(
|
|
|
99
100
|
return (
|
|
100
101
|
<>
|
|
101
102
|
<Wrapped {...forwarded} onClick={state.request} />
|
|
102
|
-
<ConfirmActionDialog state={state} {...options} />
|
|
103
|
+
<ConfirmActionDialog state={state} {...options} copy={defaults.copy} />
|
|
103
104
|
</>
|
|
104
105
|
);
|
|
105
106
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import type { CategorySelectCopy } from "../../../copy";
|
|
3
4
|
import { Box } from '@mui/material';
|
|
4
5
|
|
|
5
6
|
import { removeChip } from './category-tree';
|
|
@@ -12,6 +13,8 @@ import type { CategoryGroup, CategorySelectionChip } from './CategorySelect.type
|
|
|
12
13
|
import type { CategorySelectState } from './useCategorySelect';
|
|
13
14
|
|
|
14
15
|
export interface CategoryPanelProps {
|
|
16
|
+
/** The words this panel renders. REQUIRED — no default copy. */
|
|
17
|
+
copy: CategorySelectCopy;
|
|
15
18
|
state: CategorySelectState;
|
|
16
19
|
chips: CategorySelectionChip[];
|
|
17
20
|
rowIds: string[];
|
|
@@ -55,6 +58,7 @@ export function CategoryPanel({
|
|
|
55
58
|
searchInputRef,
|
|
56
59
|
listRef,
|
|
57
60
|
dataTestId,
|
|
61
|
+
copy,
|
|
58
62
|
}: CategoryPanelProps): React.JSX.Element {
|
|
59
63
|
return (
|
|
60
64
|
<Box
|
|
@@ -65,8 +69,9 @@ export function CategoryPanel({
|
|
|
65
69
|
sx={(theme) => ({ ...panelSx(theme), ...(sheet ? sheetSx(theme) : {}) })}
|
|
66
70
|
>
|
|
67
71
|
<CategoryPanelHead
|
|
72
|
+
copy={copy}
|
|
68
73
|
query={state.query}
|
|
69
|
-
placeholder={single ?
|
|
74
|
+
placeholder={single ? copy.search.placeholderSingle : copy.search.placeholderMulti}
|
|
70
75
|
sheet={sheet}
|
|
71
76
|
quickActions={
|
|
72
77
|
single ? undefined : <CategoryQuickActions state={state} dataTestId={dataTestId} />
|
|
@@ -76,9 +81,9 @@ export function CategoryPanel({
|
|
|
76
81
|
dataTestId={dataTestId}
|
|
77
82
|
/>
|
|
78
83
|
{!single && !loading && (
|
|
79
|
-
<PinnedTray state={state} chips={chips} dataTestId={dataTestId} />
|
|
84
|
+
<PinnedTray state={state} chips={chips} dataTestId={dataTestId} copy={copy} />
|
|
80
85
|
)}
|
|
81
|
-
<CategoryPanelList
|
|
86
|
+
<CategoryPanelList copy={copy}
|
|
82
87
|
groups={state.visibleGroups}
|
|
83
88
|
query={state.query}
|
|
84
89
|
draft={state.draft}
|
|
@@ -103,6 +108,7 @@ export function CategoryPanel({
|
|
|
103
108
|
changed={changed}
|
|
104
109
|
single={single}
|
|
105
110
|
sheet={sheet}
|
|
111
|
+
copy={copy}
|
|
106
112
|
onApply={onApply}
|
|
107
113
|
onCancel={onCancel}
|
|
108
114
|
dataTestId={dataTestId}
|
|
@@ -116,9 +122,11 @@ function PinnedTray({
|
|
|
116
122
|
state,
|
|
117
123
|
chips,
|
|
118
124
|
dataTestId,
|
|
119
|
-
|
|
125
|
+
copy,
|
|
126
|
+
}: Pick<CategoryPanelProps, 'state' | 'chips' | 'dataTestId' | 'copy'>): React.JSX.Element {
|
|
120
127
|
return (
|
|
121
128
|
<CategoryPinnedTray
|
|
129
|
+
copy={copy}
|
|
122
130
|
chips={chips}
|
|
123
131
|
onRemove={(chipId) => state.setDraft(removeChip(state.allGroups, chipId, state.draft))}
|
|
124
132
|
dataTestId={dataTestId}
|
|
@@ -135,18 +143,22 @@ function PanelFooter({
|
|
|
135
143
|
onApply,
|
|
136
144
|
onCancel,
|
|
137
145
|
dataTestId,
|
|
146
|
+
copy,
|
|
138
147
|
}: Pick<
|
|
139
148
|
CategoryPanelProps,
|
|
140
|
-
'state' | 'changed' | 'single' | 'sheet' | 'onApply' | 'onCancel' | 'dataTestId'
|
|
149
|
+
'state' | 'changed' | 'single' | 'sheet' | 'onApply' | 'onCancel' | 'dataTestId' | 'copy'
|
|
141
150
|
>): React.JSX.Element {
|
|
142
151
|
if (single) {
|
|
143
|
-
return
|
|
152
|
+
return (
|
|
153
|
+
<CategorySingleFoot sheet={sheet} onCancel={onCancel} dataTestId={dataTestId} copy={copy} />
|
|
154
|
+
);
|
|
144
155
|
}
|
|
145
156
|
return (
|
|
146
157
|
<CategoryMultiFoot
|
|
147
158
|
count={state.draft.size}
|
|
148
159
|
changed={changed}
|
|
149
160
|
sheet={sheet}
|
|
161
|
+
copy={copy}
|
|
150
162
|
onClear={() => state.setDraft(new Set())}
|
|
151
163
|
onApply={onApply}
|
|
152
164
|
dataTestId={dataTestId}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Box, Button } from '@mui/material';
|
|
4
4
|
|
|
5
|
+
import type { CategorySelectCopy } from '../../../copy';
|
|
5
6
|
import { footerSx, METRICS } from './CategorySelect.styles';
|
|
6
7
|
|
|
7
8
|
const buttonSx = (sheet: boolean) =>
|
|
@@ -23,6 +24,7 @@ interface MultiFootProps {
|
|
|
23
24
|
onClear: () => void;
|
|
24
25
|
onApply: () => void;
|
|
25
26
|
dataTestId: string;
|
|
27
|
+
copy: CategorySelectCopy;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
/**
|
|
@@ -37,11 +39,12 @@ export function CategoryMultiFoot({
|
|
|
37
39
|
onClear,
|
|
38
40
|
onApply,
|
|
39
41
|
dataTestId,
|
|
42
|
+
copy,
|
|
40
43
|
}: MultiFootProps): React.JSX.Element {
|
|
41
44
|
return (
|
|
42
45
|
<Box sx={footerSx} data-testid={`${dataTestId}-footer`}>
|
|
43
46
|
<Box component="span" sx={{ fontSize: 12, color: 'text.secondary' }}>
|
|
44
|
-
|
|
47
|
+
{copy.footer.selectedCount(count)}
|
|
45
48
|
</Box>
|
|
46
49
|
<Box sx={{ display: 'flex', gap: '6px' }}>
|
|
47
50
|
<Button
|
|
@@ -51,7 +54,7 @@ export function CategoryMultiFoot({
|
|
|
51
54
|
onClick={onClear}
|
|
52
55
|
data-testid={`${dataTestId}-clear`}
|
|
53
56
|
>
|
|
54
|
-
|
|
57
|
+
{copy.footer.clear}
|
|
55
58
|
</Button>
|
|
56
59
|
<Button
|
|
57
60
|
variant="contained"
|
|
@@ -59,7 +62,7 @@ export function CategoryMultiFoot({
|
|
|
59
62
|
onClick={onApply}
|
|
60
63
|
data-testid={`${dataTestId}-apply`}
|
|
61
64
|
>
|
|
62
|
-
{changed ?
|
|
65
|
+
{changed ? copy.footer.apply : copy.footer.close}
|
|
63
66
|
</Button>
|
|
64
67
|
</Box>
|
|
65
68
|
</Box>
|
|
@@ -71,15 +74,17 @@ export function CategorySingleFoot({
|
|
|
71
74
|
sheet,
|
|
72
75
|
onCancel,
|
|
73
76
|
dataTestId,
|
|
77
|
+
copy,
|
|
74
78
|
}: {
|
|
75
79
|
sheet: boolean;
|
|
76
80
|
onCancel: () => void;
|
|
77
81
|
dataTestId: string;
|
|
82
|
+
copy: CategorySelectCopy;
|
|
78
83
|
}): React.JSX.Element {
|
|
79
84
|
return (
|
|
80
85
|
<Box sx={footerSx} data-testid={`${dataTestId}-footer`}>
|
|
81
86
|
<Box component="span" sx={{ fontSize: 12, color: 'text.secondary' }}>
|
|
82
|
-
|
|
87
|
+
{copy.footer.singleHint}
|
|
83
88
|
</Box>
|
|
84
89
|
<Button
|
|
85
90
|
variant="outlined"
|
|
@@ -87,7 +92,7 @@ export function CategorySingleFoot({
|
|
|
87
92
|
onClick={onCancel}
|
|
88
93
|
data-testid={`${dataTestId}-cancel`}
|
|
89
94
|
>
|
|
90
|
-
|
|
95
|
+
{copy.footer.cancel}
|
|
91
96
|
</Button>
|
|
92
97
|
</Box>
|
|
93
98
|
);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import type { CategorySelectCopy } from '../../../copy';
|
|
3
4
|
import { Box, InputBase } from '@mui/material';
|
|
4
5
|
|
|
5
6
|
import { SearchGlyph } from './CategoryIcons';
|
|
@@ -21,6 +22,7 @@ interface PanelHeadProps {
|
|
|
21
22
|
onQueryChange: (next: string) => void;
|
|
22
23
|
searchInputRef: React.RefObject<HTMLInputElement | null>;
|
|
23
24
|
dataTestId: string;
|
|
25
|
+
copy: CategorySelectCopy;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
const searchFieldSx = {
|
|
@@ -72,6 +74,7 @@ export function CategoryPanelHead({
|
|
|
72
74
|
onQueryChange,
|
|
73
75
|
searchInputRef,
|
|
74
76
|
dataTestId,
|
|
77
|
+
copy,
|
|
75
78
|
}: PanelHeadProps): React.JSX.Element {
|
|
76
79
|
return (
|
|
77
80
|
<Box sx={(theme) => panelHeadSx(theme, sheet)}>
|
|
@@ -99,7 +102,7 @@ export function CategoryPanelHead({
|
|
|
99
102
|
<Box
|
|
100
103
|
component="button"
|
|
101
104
|
type="button"
|
|
102
|
-
aria-label=
|
|
105
|
+
aria-label={copy.search.clear}
|
|
103
106
|
data-testid={`${dataTestId}-search-clear`}
|
|
104
107
|
sx={clearButtonSx}
|
|
105
108
|
onClick={() => onQueryChange('')}
|
|
@@ -129,6 +132,7 @@ interface PinnedTrayProps {
|
|
|
129
132
|
chips: CategorySelectionChip[];
|
|
130
133
|
onRemove: (chipId: string) => void;
|
|
131
134
|
dataTestId: string;
|
|
135
|
+
copy: CategorySelectCopy;
|
|
132
136
|
}
|
|
133
137
|
|
|
134
138
|
/**
|
|
@@ -142,18 +146,19 @@ export function CategoryPinnedTray({
|
|
|
142
146
|
chips,
|
|
143
147
|
onRemove,
|
|
144
148
|
dataTestId,
|
|
149
|
+
copy,
|
|
145
150
|
}: PinnedTrayProps): React.JSX.Element | null {
|
|
146
151
|
if (chips.length === 0) return null;
|
|
147
152
|
return (
|
|
148
153
|
<Box sx={pinnedSx} data-testid={`${dataTestId}-pinned`}>
|
|
149
|
-
<Box sx={pinnedLabelSx}>
|
|
154
|
+
<Box sx={pinnedLabelSx}>{copy.search.pinnedLabel(chips.length)}</Box>
|
|
150
155
|
<Box sx={chipWrapSx}>
|
|
151
156
|
{chips.map((chip) => (
|
|
152
157
|
<Box component="span" key={chip.id} sx={chipSx}>
|
|
153
158
|
{chip.label}
|
|
154
159
|
<button
|
|
155
160
|
type="button"
|
|
156
|
-
aria-label={
|
|
161
|
+
aria-label={copy.search.removeChip(chip.label)}
|
|
157
162
|
data-testid={`${dataTestId}-unpin-${chip.id}`}
|
|
158
163
|
onClick={() => onRemove(chip.id)}
|
|
159
164
|
>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import type { CategorySelectCopy } from "../../../copy";
|
|
3
4
|
import { Box, Button, Skeleton } from '@mui/material';
|
|
4
5
|
|
|
5
6
|
import { categoryCheckState } from './category-tree';
|
|
@@ -18,6 +19,8 @@ const SENTENCE_CASE = { textTransform: 'none' } as const;
|
|
|
18
19
|
const SKELETON_ROWS = 6;
|
|
19
20
|
|
|
20
21
|
interface PanelListProps {
|
|
22
|
+
/** The words this panel renders. REQUIRED — no default copy. */
|
|
23
|
+
copy: CategorySelectCopy;
|
|
21
24
|
groups: CategoryGroup[];
|
|
22
25
|
query: string;
|
|
23
26
|
draft: ReadonlySet<string>;
|
|
@@ -52,17 +55,19 @@ function LoadingRows(): React.JSX.Element {
|
|
|
52
55
|
function EmptyCatalogue({
|
|
53
56
|
onCreateCategory,
|
|
54
57
|
dataTestId,
|
|
58
|
+
copy,
|
|
55
59
|
}: {
|
|
56
60
|
onCreateCategory?: (name?: string) => void;
|
|
57
61
|
dataTestId: string;
|
|
62
|
+
copy: CategorySelectCopy;
|
|
58
63
|
}): React.JSX.Element {
|
|
59
64
|
return (
|
|
60
65
|
<Box sx={emptySx} data-testid={`${dataTestId}-empty-catalogue`}>
|
|
61
|
-
<strong>
|
|
62
|
-
<p>
|
|
66
|
+
<strong>{copy.emptyTitle}</strong>
|
|
67
|
+
<p>{copy.purpose}</p>
|
|
63
68
|
{onCreateCategory && (
|
|
64
69
|
<Button variant="contained" size="small" sx={SENTENCE_CASE} onClick={() => onCreateCategory()}>
|
|
65
|
-
|
|
70
|
+
{copy.createCategory}
|
|
66
71
|
</Button>
|
|
67
72
|
)}
|
|
68
73
|
</Box>
|
|
@@ -75,19 +80,21 @@ function NoResults({
|
|
|
75
80
|
onClearQuery,
|
|
76
81
|
onCreateCategory,
|
|
77
82
|
dataTestId,
|
|
83
|
+
copy,
|
|
78
84
|
}: {
|
|
79
85
|
query: string;
|
|
80
86
|
onClearQuery: () => void;
|
|
81
87
|
onCreateCategory?: (name?: string) => void;
|
|
82
88
|
dataTestId: string;
|
|
89
|
+
copy: CategorySelectCopy;
|
|
83
90
|
}): React.JSX.Element {
|
|
84
91
|
return (
|
|
85
92
|
<Box sx={emptySx} data-testid={`${dataTestId}-no-results`}>
|
|
86
|
-
<strong>
|
|
87
|
-
<p>
|
|
93
|
+
<strong>{copy.noResults.title(query)}</strong>
|
|
94
|
+
<p>{copy.noResults.hint}</p>
|
|
88
95
|
<Box sx={{ display: 'flex', gap: '6px', justifyContent: 'center' }}>
|
|
89
96
|
<Button variant="outlined" size="small" sx={SENTENCE_CASE} onClick={onClearQuery}>
|
|
90
|
-
|
|
97
|
+
{copy.noResults.clearSearch}
|
|
91
98
|
</Button>
|
|
92
99
|
{onCreateCategory && (
|
|
93
100
|
<Button
|
|
@@ -97,7 +104,7 @@ function NoResults({
|
|
|
97
104
|
data-testid={`${dataTestId}-create`}
|
|
98
105
|
onClick={() => onCreateCategory(query.trim())}
|
|
99
106
|
>
|
|
100
|
-
|
|
107
|
+
{copy.noResults.create(query.trim())}
|
|
101
108
|
</Button>
|
|
102
109
|
)}
|
|
103
110
|
</Box>
|
|
@@ -161,13 +168,13 @@ function CategoryGroupRows({
|
|
|
161
168
|
|
|
162
169
|
/** The scrolling body of the panel, including its three non-list states. */
|
|
163
170
|
export function CategoryPanelList(props: PanelListProps): React.JSX.Element {
|
|
164
|
-
const { groups, loading, query, listRef, sheet, dataTestId } = props;
|
|
171
|
+
const { groups, loading, query, listRef, sheet, dataTestId, copy } = props;
|
|
165
172
|
|
|
166
173
|
const body = (): React.JSX.Element => {
|
|
167
174
|
if (loading) return <LoadingRows />;
|
|
168
175
|
if (groups.length === 0 && query.trim().length > 0) {
|
|
169
176
|
return (
|
|
170
|
-
<NoResults
|
|
177
|
+
<NoResults copy={copy}
|
|
171
178
|
query={query}
|
|
172
179
|
onClearQuery={props.onClearQuery}
|
|
173
180
|
onCreateCategory={props.onCreateCategory}
|
|
@@ -177,7 +184,7 @@ export function CategoryPanelList(props: PanelListProps): React.JSX.Element {
|
|
|
177
184
|
}
|
|
178
185
|
if (groups.length === 0) {
|
|
179
186
|
return (
|
|
180
|
-
<EmptyCatalogue
|
|
187
|
+
<EmptyCatalogue copy={copy}
|
|
181
188
|
onCreateCategory={props.onCreateCategory}
|
|
182
189
|
dataTestId={dataTestId}
|
|
183
190
|
/>
|
|
@@ -102,7 +102,7 @@ function usePanelFocus(
|
|
|
102
102
|
* is the only way a 290px-tall list stays usable one-handed.
|
|
103
103
|
*/
|
|
104
104
|
export function CategorySelect(props: CategorySelectProps): React.JSX.Element {
|
|
105
|
-
const { options, label, error, onCreateCategory } = props;
|
|
105
|
+
const { options, label, error, onCreateCategory, copy } = props;
|
|
106
106
|
const {
|
|
107
107
|
single,
|
|
108
108
|
placeholder,
|
|
@@ -135,7 +135,7 @@ export function CategorySelect(props: CategorySelectProps): React.JSX.Element {
|
|
|
135
135
|
return (
|
|
136
136
|
<FormControl fullWidth={fullWidth} error={Boolean(error)}>
|
|
137
137
|
{label && <FormLabel error={Boolean(error)}>{label}</FormLabel>}
|
|
138
|
-
<CategoryTrigger
|
|
138
|
+
<CategoryTrigger copy={copy}
|
|
139
139
|
placeholder={placeholder}
|
|
140
140
|
selectionLabel={
|
|
141
141
|
props.mode === 'single' ? singleLabel(state.allGroups, props.value) : undefined
|
|
@@ -155,7 +155,7 @@ export function CategorySelect(props: CategorySelectProps): React.JSX.Element {
|
|
|
155
155
|
anchorEl={state.triggerRef.current}
|
|
156
156
|
onClose={actions.cancel}
|
|
157
157
|
>
|
|
158
|
-
<CategoryPanel
|
|
158
|
+
<CategoryPanel copy={copy}
|
|
159
159
|
state={state}
|
|
160
160
|
chips={chips}
|
|
161
161
|
rowIds={rowIds}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CategorySelectCopy } from "../../../copy";
|
|
1
2
|
import type { SizeValue } from '../../../tokens/scales';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -84,6 +85,8 @@ export interface CategorySelectBaseProps {
|
|
|
84
85
|
* not reload on every tick.
|
|
85
86
|
*/
|
|
86
87
|
export interface CategoryMultiSelectProps extends CategorySelectBaseProps {
|
|
88
|
+
/** The words this control renders. REQUIRED — no default copy. */
|
|
89
|
+
copy: CategorySelectCopy;
|
|
87
90
|
mode?: 'multi';
|
|
88
91
|
/** The APPLIED selection — subcategory ids. */
|
|
89
92
|
value: string[];
|
|
@@ -93,6 +96,8 @@ export interface CategoryMultiSelectProps extends CategorySelectBaseProps {
|
|
|
93
96
|
|
|
94
97
|
/** Single-select mode: the "move to…" picker. Choosing a row commits at once. */
|
|
95
98
|
export interface CategorySingleSelectProps extends CategorySelectBaseProps {
|
|
99
|
+
/** The words this control renders. REQUIRED — no default copy. */
|
|
100
|
+
copy: CategorySelectCopy;
|
|
96
101
|
mode: 'single';
|
|
97
102
|
/** The chosen category or subcategory id, or `null`. */
|
|
98
103
|
value: string | null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import type { CategorySelectCopy } from "../../../copy";
|
|
3
4
|
import { Box } from '@mui/material';
|
|
4
5
|
|
|
5
6
|
import { CaretGlyph } from './CategoryIcons';
|
|
@@ -11,6 +12,8 @@ import {
|
|
|
11
12
|
} from './CategorySelect.styles';
|
|
12
13
|
|
|
13
14
|
interface CategoryTriggerProps {
|
|
15
|
+
/** The words this renders. REQUIRED — this package ships no default copy. */
|
|
16
|
+
copy: CategorySelectCopy;
|
|
14
17
|
/** Text shown when nothing is selected. */
|
|
15
18
|
placeholder: string;
|
|
16
19
|
/** Resolved label when there IS a selection (single mode shows "Pai › Filha"). */
|
|
@@ -46,6 +49,7 @@ export function CategoryTrigger({
|
|
|
46
49
|
onClear,
|
|
47
50
|
triggerRef,
|
|
48
51
|
dataTestId,
|
|
52
|
+
copy,
|
|
49
53
|
}: CategoryTriggerProps): React.JSX.Element {
|
|
50
54
|
const hasSelection = Boolean(selectionLabel) || (count ?? 0) > 0;
|
|
51
55
|
return (
|
|
@@ -86,7 +90,7 @@ export function CategoryTrigger({
|
|
|
86
90
|
component="span"
|
|
87
91
|
role="button"
|
|
88
92
|
tabIndex={0}
|
|
89
|
-
aria-label=
|
|
93
|
+
aria-label={copy.clearSelection}
|
|
90
94
|
data-testid={`${dataTestId}-clear-trigger`}
|
|
91
95
|
sx={triggerClearSx}
|
|
92
96
|
onClick={(event: React.MouseEvent) => {
|