@12-apps/ui 6.2.0 → 6.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/{chunk-35VGGLOC.js → chunk-CEKPLUQV.js} +2 -2
  2. package/dist/{chunk-35VGGLOC.js.map → chunk-CEKPLUQV.js.map} +1 -1
  3. package/dist/{chunk-7XLEWBKL.js → chunk-N554AFDB.js} +7 -10
  4. package/dist/chunk-N554AFDB.js.map +1 -0
  5. package/dist/{chunk-JDO7W4D4.js → chunk-R5ZQZSEQ.js} +2 -20
  6. package/dist/{chunk-JDO7W4D4.js.map → chunk-R5ZQZSEQ.js.map} +1 -1
  7. package/dist/{chunk-R4TYXKDD.js → chunk-TPQRIPCN.js} +52 -48
  8. package/dist/chunk-TPQRIPCN.js.map +1 -0
  9. package/dist/{chunk-62XQWGXU.js → chunk-WFPXRSIZ.js} +20 -18
  10. package/dist/chunk-WFPXRSIZ.js.map +1 -0
  11. package/dist/copy.js +1 -0
  12. package/dist/copy.js.map +1 -0
  13. package/dist/data-display/CardKit.js +15 -4
  14. package/dist/data-display/CardKit.js.map +1 -1
  15. package/dist/data-display/DataViews.js +664 -616
  16. package/dist/data-display/DataViews.js.map +1 -1
  17. package/dist/data-display/SectionOnboarding.js +3 -3
  18. package/dist/data-display/SectionOnboarding.js.map +1 -1
  19. package/dist/feedback/ConfirmAction.js +3 -5
  20. package/dist/form/CategorySelect.js +1 -1
  21. package/dist/form/CepField.js +1 -1
  22. package/dist/form/total-form.js +8 -4
  23. package/dist/form/total-form.js.map +1 -1
  24. package/dist/layout/ContentToolbar.js +1 -1
  25. package/dist/layout/TableFilter.js +1 -1
  26. package/dist/pt-BR.js +222 -0
  27. package/dist/pt-BR.js.map +1 -0
  28. package/dist/types/components/data-display/CardKit/use-remove-confirm.d.ts +4 -1
  29. package/dist/types/components/data-display/CardKit/use-remove-confirm.d.ts.map +1 -1
  30. package/dist/types/components/data-display/CardKit/use-row-confirm.d.ts +5 -2
  31. package/dist/types/components/data-display/CardKit/use-row-confirm.d.ts.map +1 -1
  32. package/dist/types/components/data-display/DataViews/DataViewsBoard.d.ts.map +1 -1
  33. package/dist/types/components/data-display/DataViews/DeleteViewDialog.d.ts.map +1 -1
  34. package/dist/types/components/data-display/DataViews/ManageViewsDialog.d.ts +4 -1
  35. package/dist/types/components/data-display/DataViews/ManageViewsDialog.d.ts.map +1 -1
  36. package/dist/types/components/data-display/DataViews/SaveViewModal.d.ts +0 -5
  37. package/dist/types/components/data-display/DataViews/SaveViewModal.d.ts.map +1 -1
  38. package/dist/types/components/data-display/DataViews/base-card.d.ts.map +1 -1
  39. package/dist/types/components/data-display/DataViews/base-list-card-gutters.d.ts.map +1 -1
  40. package/dist/types/components/data-display/DataViews/data-views-bar-controls.d.ts.map +1 -1
  41. package/dist/types/components/data-display/DataViews/data-views-category-pill.d.ts.map +1 -1
  42. package/dist/types/components/data-display/DataViews/data-views-columns-tab.d.ts.map +1 -1
  43. package/dist/types/components/data-display/DataViews/data-views-copy-context.d.ts +17 -0
  44. package/dist/types/components/data-display/DataViews/data-views-copy-context.d.ts.map +1 -0
  45. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +205 -0
  46. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -0
  47. package/dist/types/components/data-display/DataViews/data-views-display-panel.d.ts.map +1 -1
  48. package/dist/types/components/data-display/DataViews/data-views-display-tabs.d.ts.map +1 -1
  49. package/dist/types/components/data-display/DataViews/data-views-export.d.ts.map +1 -1
  50. package/dist/types/components/data-display/DataViews/data-views-filter-panel.d.ts.map +1 -1
  51. package/dist/types/components/data-display/DataViews/data-views-grid-helpers.d.ts.map +1 -1
  52. package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
  53. package/dist/types/components/data-display/DataViews/data-views-more-filters.d.ts.map +1 -1
  54. package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts.map +1 -1
  55. package/dist/types/components/data-display/DataViews/data-views-range-presets.d.ts +3 -2
  56. package/dist/types/components/data-display/DataViews/data-views-range-presets.d.ts.map +1 -1
  57. package/dist/types/components/data-display/DataViews/data-views-scopes.d.ts.map +1 -1
  58. package/dist/types/components/data-display/DataViews/data-views-search.d.ts.map +1 -1
  59. package/dist/types/components/data-display/DataViews/data-views-select-all-strip.d.ts.map +1 -1
  60. package/dist/types/components/data-display/DataViews/data-views-table-parts.d.ts.map +1 -1
  61. package/dist/types/components/data-display/DataViews/data-views-view-nav.d.ts +1 -1
  62. package/dist/types/components/data-display/DataViews/data-views-view-nav.d.ts.map +1 -1
  63. package/dist/types/components/data-display/DataViews/index.d.ts +2 -0
  64. package/dist/types/components/data-display/DataViews/index.d.ts.map +1 -1
  65. package/dist/types/components/data-display/DataViews/save-view-preview.d.ts +10 -0
  66. package/dist/types/components/data-display/DataViews/save-view-preview.d.ts.map +1 -0
  67. package/dist/types/components/data-display/DataViews/use-saved-views-controller.d.ts.map +1 -1
  68. package/dist/types/components/data-display/SectionOnboarding/SectionOnboarding.types.d.ts +6 -5
  69. package/dist/types/components/data-display/SectionOnboarding/SectionOnboarding.types.d.ts.map +1 -1
  70. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.hooks.d.ts +1 -3
  71. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.hooks.d.ts.map +1 -1
  72. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.parts.d.ts +4 -1
  73. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.parts.d.ts.map +1 -1
  74. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.types.d.ts +9 -1
  75. package/dist/types/components/feedback/ConfirmAction/ConfirmAction.types.d.ts.map +1 -1
  76. package/dist/types/components/feedback/ConfirmAction/ConfirmButton.d.ts +2 -1
  77. package/dist/types/components/feedback/ConfirmAction/ConfirmButton.d.ts.map +1 -1
  78. package/dist/types/components/feedback/ConfirmAction/index.d.ts +2 -2
  79. package/dist/types/components/feedback/ConfirmAction/index.d.ts.map +1 -1
  80. package/dist/types/components/feedback/ConfirmAction/with-confirmation.d.ts +5 -1
  81. package/dist/types/components/feedback/ConfirmAction/with-confirmation.d.ts.map +1 -1
  82. package/dist/types/components/form/CategorySelect/CategoryPanel.d.ts +4 -1
  83. package/dist/types/components/form/CategorySelect/CategoryPanel.d.ts.map +1 -1
  84. package/dist/types/components/form/CategorySelect/CategoryPanelFoot.d.ts +5 -2
  85. package/dist/types/components/form/CategorySelect/CategoryPanelFoot.d.ts.map +1 -1
  86. package/dist/types/components/form/CategorySelect/CategoryPanelHead.d.ts +5 -2
  87. package/dist/types/components/form/CategorySelect/CategoryPanelHead.d.ts.map +1 -1
  88. package/dist/types/components/form/CategorySelect/CategoryPanelList.d.ts +3 -0
  89. package/dist/types/components/form/CategorySelect/CategoryPanelList.d.ts.map +1 -1
  90. package/dist/types/components/form/CategorySelect/CategorySelect.types.d.ts +5 -0
  91. package/dist/types/components/form/CategorySelect/CategorySelect.types.d.ts.map +1 -1
  92. package/dist/types/components/form/CategorySelect/CategoryTrigger.d.ts +4 -1
  93. package/dist/types/components/form/CategorySelect/CategoryTrigger.d.ts.map +1 -1
  94. package/dist/types/components/form/CepField/CepField.d.ts +1 -1
  95. package/dist/types/components/form/CepField/CepField.d.ts.map +1 -1
  96. package/dist/types/components/form/CepField/CepField.types.d.ts +3 -0
  97. package/dist/types/components/form/CepField/CepField.types.d.ts.map +1 -1
  98. package/dist/types/components/form/total-form/Fields/CategoryField.d.ts +4 -1
  99. package/dist/types/components/form/total-form/Fields/CategoryField.d.ts.map +1 -1
  100. package/dist/types/components/form/total-form/Fields/CepField.d.ts +4 -1
  101. package/dist/types/components/form/total-form/Fields/CepField.d.ts.map +1 -1
  102. package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts +6 -1
  103. package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts.map +1 -1
  104. package/dist/types/components/layout/ContentToolbar/SavedViewsMenu.d.ts.map +1 -1
  105. package/dist/types/copy.d.ts +99 -0
  106. package/dist/types/copy.d.ts.map +1 -0
  107. package/dist/types/pt-BR.d.ts +28 -0
  108. package/dist/types/pt-BR.d.ts.map +1 -0
  109. package/package.json +10 -2
  110. package/src/components/data-display/CardKit/use-remove-confirm.tsx +5 -0
  111. package/src/components/data-display/CardKit/use-row-confirm.tsx +7 -2
  112. package/src/components/data-display/DataViews/DataViewsBoard.tsx +7 -4
  113. package/src/components/data-display/DataViews/DeleteViewDialog.tsx +6 -4
  114. package/src/components/data-display/DataViews/ManageViewsDialog.tsx +26 -10
  115. package/src/components/data-display/DataViews/SaveViewModal.tsx +56 -90
  116. package/src/components/data-display/DataViews/base-card.tsx +3 -1
  117. package/src/components/data-display/DataViews/base-list-card-gutters.tsx +3 -1
  118. package/src/components/data-display/DataViews/data-views-bar-controls.tsx +8 -5
  119. package/src/components/data-display/DataViews/data-views-category-pill.tsx +6 -3
  120. package/src/components/data-display/DataViews/data-views-columns-tab.tsx +5 -3
  121. package/src/components/data-display/DataViews/data-views-copy-context.tsx +43 -0
  122. package/src/components/data-display/DataViews/data-views-copy.ts +214 -0
  123. package/src/components/data-display/DataViews/data-views-display-panel.tsx +15 -9
  124. package/src/components/data-display/DataViews/data-views-display-tabs.tsx +19 -29
  125. package/src/components/data-display/DataViews/data-views-export.tsx +9 -10
  126. package/src/components/data-display/DataViews/data-views-filter-panel.tsx +9 -5
  127. package/src/components/data-display/DataViews/data-views-grid-helpers.tsx +5 -2
  128. package/src/components/data-display/DataViews/data-views-more-fields.tsx +5 -3
  129. package/src/components/data-display/DataViews/data-views-more-filters.tsx +6 -3
  130. package/src/components/data-display/DataViews/data-views-range-pill.tsx +9 -5
  131. package/src/components/data-display/DataViews/data-views-range-presets.ts +7 -8
  132. package/src/components/data-display/DataViews/data-views-scopes.tsx +3 -1
  133. package/src/components/data-display/DataViews/data-views-search.tsx +7 -4
  134. package/src/components/data-display/DataViews/data-views-select-all-strip.tsx +5 -3
  135. package/src/components/data-display/DataViews/data-views-table-parts.tsx +7 -2
  136. package/src/components/data-display/DataViews/data-views-view-nav.tsx +22 -16
  137. package/src/components/data-display/DataViews/index.ts +20 -0
  138. package/src/components/data-display/DataViews/save-view-preview.tsx +78 -0
  139. package/src/components/data-display/DataViews/use-saved-views-controller.ts +3 -1
  140. package/src/components/data-display/SectionOnboarding/SectionOnboarding.tsx +3 -3
  141. package/src/components/data-display/SectionOnboarding/SectionOnboarding.types.ts +8 -7
  142. package/src/components/feedback/ConfirmAction/ConfirmAction.hooks.ts +2 -2
  143. package/src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx +20 -6
  144. package/src/components/feedback/ConfirmAction/ConfirmAction.types.ts +9 -1
  145. package/src/components/feedback/ConfirmAction/ConfirmButton.tsx +12 -4
  146. package/src/components/feedback/ConfirmAction/index.ts +2 -2
  147. package/src/components/feedback/ConfirmAction/with-confirmation.tsx +4 -3
  148. package/src/components/form/CategorySelect/CategoryPanel.tsx +18 -6
  149. package/src/components/form/CategorySelect/CategoryPanelFoot.tsx +10 -5
  150. package/src/components/form/CategorySelect/CategoryPanelHead.tsx +8 -3
  151. package/src/components/form/CategorySelect/CategoryPanelList.tsx +17 -10
  152. package/src/components/form/CategorySelect/CategorySelect.tsx +3 -3
  153. package/src/components/form/CategorySelect/CategorySelect.types.ts +5 -0
  154. package/src/components/form/CategorySelect/CategoryTrigger.tsx +5 -1
  155. package/src/components/form/CepField/CepField.tsx +6 -9
  156. package/src/components/form/CepField/CepField.types.ts +3 -0
  157. package/src/components/form/total-form/Fields/CategoryField.tsx +5 -0
  158. package/src/components/form/total-form/Fields/CepField.tsx +5 -0
  159. package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +6 -1
  160. package/src/components/layout/ContentToolbar/SavedViewsMenu.tsx +1 -21
  161. package/src/components/layout/TableFilter/TableFilter.tsx +1 -1
  162. package/src/copy.ts +103 -0
  163. package/src/pt-BR.ts +247 -0
  164. package/dist/chunk-62XQWGXU.js.map +0 -1
  165. package/dist/chunk-7XLEWBKL.js.map +0 -1
  166. package/dist/chunk-R4TYXKDD.js.map +0 -1
@@ -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="Limpar seleção"
93
+ aria-label={copy.clearSelection}
90
94
  data-testid={`${dataTestId}-clear-trigger`}
91
95
  sx={triggerClearSx}
92
96
  onClick={(event: React.MouseEvent) => {
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
 
3
+ import type { CepFieldCopy } from "../../../copy";
3
4
  import React, { useCallback, useEffect, useRef, useState } from 'react';
4
5
 
5
6
  import { cepDigits, formatCep, isValidCep } from '@12-apps/forms-core';
@@ -8,13 +9,6 @@ import { FormControl, FormLabel, FormMessage } from '../Form';
8
9
  import { Input } from '../Input';
9
10
  import type { CepAddress, CepFieldProps, CepLookupStatus } from './CepField.types';
10
11
 
11
- /** What the user is told for each non-idle outcome. */
12
- const STATUS_TEXT: Record<Exclude<CepLookupStatus, 'idle'>, string> = {
13
- loading: 'Buscando endereço…',
14
- found: 'Endereço preenchido pelo CEP.',
15
- notfound: 'CEP não encontrado — preencha o endereço manualmente.',
16
- };
17
-
18
12
  /** Everything {@link useCepLookup} needs, so the hook signature stays flat. */
19
13
  interface LookupOptions {
20
14
  digits: string;
@@ -103,17 +97,19 @@ function CepStatus({
103
97
  status,
104
98
  testId,
105
99
  suppressed,
100
+ copy,
106
101
  }: {
107
102
  status: CepLookupStatus;
108
103
  testId: string;
109
104
  suppressed: boolean;
105
+ copy: CepFieldCopy;
110
106
  }): React.ReactElement {
111
107
  const visible = !suppressed && status !== 'idle';
112
108
  return (
113
109
  <span id={`${testId}-status`} role="status" aria-live="polite">
114
110
  {visible && (
115
111
  <FormMessage error={status === 'notfound'} dataTestId={`${testId}-${status}`}>
116
- {STATUS_TEXT[status as Exclude<CepLookupStatus, 'idle'>]}
112
+ {copy[status as Exclude<CepLookupStatus, 'idle'>]}
117
113
  </FormMessage>
118
114
  )}
119
115
  </span>
@@ -157,6 +153,7 @@ export function CepField({
157
153
  debounceMs = 500,
158
154
  name = 'postalCode',
159
155
  dataTestId,
156
+ copy,
160
157
  }: CepFieldProps): React.ReactElement {
161
158
  const testId = dataTestId ?? `cep-field-${name}`;
162
159
 
@@ -203,7 +200,7 @@ export function CepField({
203
200
  {error}
204
201
  </FormMessage>
205
202
  )}
206
- <CepStatus status={status} testId={testId} suppressed={Boolean(error)} />
203
+ <CepStatus status={status} testId={testId} suppressed={Boolean(error)} copy={copy} />
207
204
  </FormControl>
208
205
  );
209
206
  }
@@ -1,3 +1,4 @@
1
+ import type { CepFieldCopy } from "../../../copy";
1
2
  /**
2
3
  * Types for {@link CepField} — the reusable CEP auto-completer.
3
4
  */
@@ -29,6 +30,8 @@ export interface CepAddress {
29
30
  export type CepLookupStatus = 'idle' | 'loading' | 'found' | 'notfound';
30
31
 
31
32
  export interface CepFieldProps {
33
+ /** The lookup status wording. REQUIRED — no default copy. */
34
+ copy: CepFieldCopy;
32
35
  /** Current field value. Masked (`01310-100`) or bare — the field re-masks. */
33
36
  value: string;
34
37
  /**
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
 
3
+ import type { CategorySelectCopy } from "../../../../copy";
3
4
  import React from 'react';
4
5
 
5
6
  import { CategorySelect } from '../../CategorySelect';
@@ -8,6 +9,8 @@ import { useFormContext } from '../FormContext';
8
9
 
9
10
  /** Props for the `total-form` {@link CategoryField}. */
10
11
  export interface CategoryFieldProps {
12
+ /** The picker\'s words. REQUIRED — this package ships no default copy. */
13
+ copy: CategorySelectCopy;
11
14
  /** Field name; also the key into the form's values/errors. */
12
15
  name: string;
13
16
  /** The categories to choose from, flat, each carrying its `parentId`. */
@@ -36,12 +39,14 @@ export function CategoryField({
36
39
  label,
37
40
  placeholder,
38
41
  allowParentSelection = true,
42
+ copy,
39
43
  }: CategoryFieldProps): React.ReactElement {
40
44
  const { values, errors, setFieldValue } = useFormContext();
41
45
  const error = errors[name];
42
46
 
43
47
  return (
44
48
  <CategorySelect
49
+ copy={copy}
45
50
  mode="single"
46
51
  fullWidth
47
52
  label={label}
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
 
3
+ import type { CepFieldCopy } from "../../../../copy";
3
4
  import React, { useCallback, useMemo, useRef } from 'react';
4
5
 
5
6
  import { CepField as BaseCepField, type CepAddress } from '../../CepField';
@@ -16,6 +17,8 @@ export type CepFills = Partial<Record<CepPart, string>>;
16
17
 
17
18
  /** Props for the `total-form` {@link CepField}. */
18
19
  export interface CepFieldProps {
20
+ /** The lookup status wording. REQUIRED — no default copy. */
21
+ copy: CepFieldCopy;
19
22
  /** Field name; also the key into the form's values/errors. */
20
23
  name: string;
21
24
  /** Optional visible label. Defaults to `CEP`. */
@@ -103,6 +106,7 @@ export function CepField({
103
106
  lookup,
104
107
  fills,
105
108
  debounceMs,
109
+ copy,
106
110
  }: CepFieldProps): React.ReactElement {
107
111
  const { values, errors, setFieldValue } = useFormContext();
108
112
  const { write, clearOwned } = useOwnedAutofill();
@@ -128,6 +132,7 @@ export function CepField({
128
132
 
129
133
  return (
130
134
  <BaseCepField
135
+ copy={copy}
131
136
  name={name}
132
137
  label={label}
133
138
  value={values[name] ?? ''}
@@ -258,6 +258,11 @@ export interface SavedViewsMenuProps<V extends SavedViewLike = SavedViewLike> {
258
258
  onToggleShare: (view: V) => void;
259
259
  onManageAll: () => void;
260
260
  /** Override any of the default (pt-BR) strings. */
261
- labels?: Partial<SavedViewsLabels>;
261
+ /**
262
+ * Every word this menu renders. REQUIRED since FUT-760: it used to be
263
+ * `Partial<…>` over a pt-BR default, so a host that passed nothing shipped
264
+ * one product's Portuguese. `PT_BR_SAVED_VIEWS_LABELS` is that exact set.
265
+ */
266
+ labels: SavedViewsLabels;
262
267
  testIdPrefix?: string;
263
268
  }
@@ -13,26 +13,6 @@ import type {
13
13
  SavedViewsMenuProps,
14
14
  } from './ContentToolbar.types';
15
15
 
16
- /** Default (pt-BR) strings; override any via the `labels` prop. */
17
- const DEFAULT_LABELS: SavedViewsLabels = {
18
- trigger: 'Visões',
19
- mainView: 'Visão principal',
20
- pinned: 'Fixadas',
21
- recent: 'Recentes',
22
- empty: 'Nenhuma visão salva ainda.',
23
- saveCurrent: '+ Salvar visão atual',
24
- manageAll: 'Gerenciar visões',
25
- apply: 'Aplicar',
26
- setDefault: 'Definir como padrão',
27
- pin: 'Fixar na barra lateral',
28
- unpin: 'Desafixar',
29
- share: 'Compartilhar com a equipe',
30
- unshare: 'Tornar privada',
31
- edit: 'Editar',
32
- remove: 'Excluir',
33
- defaultTag: 'Padrão',
34
- };
35
-
36
16
  /** How many non-pinned views show under "Recentes". */
37
17
  const RECENT_LIMIT = 5;
38
18
 
@@ -280,7 +260,7 @@ export function SavedViewsMenu<V extends SavedViewLike = SavedViewLike>({
280
260
  action();
281
261
  close();
282
262
  };
283
- const labels = { ...DEFAULT_LABELS, ...labelOverrides };
263
+ const labels = labelOverrides;
284
264
  const pinned = views.filter((view) => view.pinned);
285
265
  const recent = views.filter((view) => !view.pinned).slice(0, RECENT_LIMIT);
286
266
 
@@ -328,7 +328,7 @@ const TableFilterRangeField = ({
328
328
  step,
329
329
  minPlaceholder = 'min',
330
330
  maxPlaceholder = 'max',
331
- invalidLabel = 'O máximo deve ser maior ou igual ao mínimo.',
331
+ invalidLabel,
332
332
  testId,
333
333
  }: TableFilterRangeFieldProps): React.JSX.Element => {
334
334
  const invalid = isRangeInverted(value);
package/src/copy.ts ADDED
@@ -0,0 +1,103 @@
1
+ /**
2
+ * The words the standalone components render, as REQUIRED host config
3
+ * (FUT-760).
4
+ *
5
+ * `@12-apps/ui` is the package EVERY host renders, so copy compiled in here
6
+ * reached every adopter of every other package too — the same leak as anywhere
7
+ * else, at the widest possible blast radius. Several of these components made
8
+ * it worse by taking the words as OPTIONAL props with pt-BR defaults, which
9
+ * reads as configurable right up until nobody configures it.
10
+ *
11
+ * The DataViews family has its own object (`DataViewsCopy`) threaded through a
12
+ * context, because nineteen files are one mounted surface. These six are
13
+ * mounted independently, so each takes what it renders.
14
+ */
15
+
16
+ export interface SectionOnboardingCopy {
17
+ /** The button that begins the guided section. */
18
+ start: string;
19
+ /** The reveal toggle in the configured state, and its collapsed twin. */
20
+ edit: string;
21
+ collapse: string;
22
+ }
23
+
24
+ export interface ConfirmActionCopy {
25
+ /** The dismiss button every confirmation shares. */
26
+ cancel: string;
27
+ /** Shown when the action fails and the caller supplied no reason. */
28
+ defaultError: string;
29
+ /**
30
+ * The fallback body when the caller names no entity.
31
+ *
32
+ * A caller that DOES name one gets the host's own sentence — this package
33
+ * never guesses a noun for someone else's rows.
34
+ */
35
+ irreversible: string;
36
+ }
37
+
38
+ export interface CategorySelectCopy {
39
+ /**
40
+ * What categories are FOR, in the host's own terms.
41
+ *
42
+ * This used to read "Categorias organizam o cardápio e os filtros da loja" —
43
+ * a restaurant's menu, hard-coded into a generic picker. A host selling
44
+ * insurance policies got told about its cardápio.
45
+ */
46
+ purpose: string;
47
+ clearSelection: string;
48
+ /** The empty state, when the host has no categories at all. */
49
+ emptyTitle: string;
50
+ createCategory: string;
51
+ /**
52
+ * The search found nothing.
53
+ *
54
+ * Two of the four interpolate the term typed, so they are functions rather
55
+ * than strings with a placeholder to substitute: where the term sits in the
56
+ * sentence is the translator's call, not ours.
57
+ */
58
+ noResults: {
59
+ title: (query: string) => string;
60
+ hint: string;
61
+ clearSearch: string;
62
+ create: (query: string) => string;
63
+ };
64
+ /**
65
+ * The panel's two footers.
66
+ *
67
+ * `selectedCount` is a function because Portuguese agrees the participle with
68
+ * the count and English does not — the shape has to let a translator decide
69
+ * the whole sentence, not fill a slot in ours.
70
+ */
71
+ /** The search box above the list, and the chips beneath it. */
72
+ search: {
73
+ /** Two placeholders: a single-select picker offers no subcategories. */
74
+ placeholderSingle: string;
75
+ placeholderMulti: string;
76
+ clear: string;
77
+ removeChip(label: string): string;
78
+ /** The tray above the list, counting what is already picked. */
79
+ pinnedLabel(count: number): string;
80
+ };
81
+ footer: {
82
+ selectedCount(count: number): string;
83
+ clear: string;
84
+ /** The primary button, which reads `close` while the draft is unchanged. */
85
+ apply: string;
86
+ close: string;
87
+ /** The single-select footer: what to do, and the way out. */
88
+ singleHint: string;
89
+ cancel: string;
90
+ };
91
+ }
92
+
93
+ export interface CepFieldCopy {
94
+ loading: string;
95
+ found: string;
96
+ /** Keyed to match `CepLookupStatus` exactly, so the lookup can index it. */
97
+ notfound: string;
98
+ }
99
+
100
+ export interface TableFilterCopy {
101
+ /** A numeric range whose maximum is below its minimum. */
102
+ invalidRange: string;
103
+ }
package/src/pt-BR.ts ADDED
@@ -0,0 +1,247 @@
1
+ import type { DataViewsCopy } from "./components/data-display/DataViews/data-views-copy";
2
+ import type { SavedViewsLabels } from "./components/layout/ContentToolbar/ContentToolbar.types";
3
+ import type {
4
+ CategorySelectCopy,
5
+ CepFieldCopy,
6
+ ConfirmActionCopy,
7
+ SectionOnboardingCopy,
8
+ TableFilterCopy,
9
+ } from "./copy";
10
+
11
+ /**
12
+ * The pt-BR packs — NAMED constants a host passes by hand, never defaults.
13
+ *
14
+ * The filename is what exempts this file from the copy-portability gate:
15
+ * Portuguese may ship, it may not be silent. Every sentence is VERBATIM what
16
+ * the components used to render, so a host adopting these sees no change on
17
+ * screen — what changes is that the words are chosen in a diff.
18
+ */
19
+ export const PT_BR_SECTION_ONBOARDING_COPY: SectionOnboardingCopy = {
20
+ edit: "Editar",
21
+ collapse: "Ocultar",
22
+ start: "Começar",
23
+ };
24
+
25
+ export const PT_BR_CONFIRM_ACTION_COPY: ConfirmActionCopy = {
26
+ cancel: "Cancelar",
27
+ defaultError: "Não foi possível concluir a ação. Tente novamente.",
28
+ irreversible: "Esta ação não pode ser desfeita.",
29
+ };
30
+
31
+ export const PT_BR_CATEGORY_SELECT_COPY: CategorySelectCopy = {
32
+ purpose: "Categorias organizam o cardápio e os filtros da loja.",
33
+ clearSelection: "Limpar seleção",
34
+ emptyTitle: "Nenhuma categoria ainda",
35
+ createCategory: "Criar categoria",
36
+ noResults: {
37
+ title: (query) => `Nada encontrado para “${query}”`,
38
+ hint: "Tente outro termo ou verifique a grafia.",
39
+ clearSearch: "Limpar busca",
40
+ create: (query) => `Criar “${query}”`,
41
+ },
42
+ search: {
43
+ placeholderSingle: "Buscar categoria…",
44
+ placeholderMulti: "Buscar categoria ou subcategoria",
45
+ clear: "Limpar busca",
46
+ removeChip: (label) => `Remover ${label}`,
47
+ pinnedLabel: (count) => `Selecionadas · ${count}`,
48
+ },
49
+ footer: {
50
+ selectedCount: (count) => `${count} selecionada${count === 1 ? "" : "s"}`,
51
+ clear: "Limpar",
52
+ apply: "Aplicar",
53
+ close: "Fechar",
54
+ singleHint: "Escolha uma categoria",
55
+ cancel: "Cancelar",
56
+ },
57
+ };
58
+
59
+ export const PT_BR_CEP_FIELD_COPY: CepFieldCopy = {
60
+ loading: "Buscando endereço…",
61
+ found: "Endereço preenchido pelo CEP.",
62
+ notfound: "CEP não encontrado — preencha o endereço manualmente.",
63
+ };
64
+
65
+ /**
66
+ * The saved-views dropdown's labels.
67
+ *
68
+ * Typed as the package's OWN `SavedViewsLabels` rather than a parallel shape:
69
+ * that interface already named every string, including the seven with no
70
+ * diacritics the copy gate could not see (`Aplicar`, `Fixar na barra lateral`,
71
+ * `Editar`…). The prop was `Partial<SavedViewsLabels>` with a pt-BR default —
72
+ * configurable in the type, inherited in practice.
73
+ */
74
+ export const PT_BR_SAVED_VIEWS_LABELS: SavedViewsLabels = {
75
+ trigger: "Visões",
76
+ mainView: "Visão principal",
77
+ pinned: "Fixadas",
78
+ recent: "Recentes",
79
+ empty: "Nenhuma visão salva ainda.",
80
+ saveCurrent: "+ Salvar visão atual",
81
+ manageAll: "Gerenciar visões",
82
+ apply: "Aplicar",
83
+ setDefault: "Definir como padrão",
84
+ pin: "Fixar na barra lateral",
85
+ unpin: "Desafixar",
86
+ share: "Compartilhar com a equipe",
87
+ unshare: "Tornar privada",
88
+ edit: "Editar",
89
+ remove: "Excluir",
90
+ defaultTag: "Padrão",
91
+ };
92
+
93
+ export const PT_BR_TABLE_FILTER_COPY: TableFilterCopy = {
94
+ invalidRange: "O máximo deve ser maior ou igual ao mínimo.",
95
+ };
96
+
97
+ export const PT_BR_DATA_VIEWS_COPY: DataViewsCopy = {
98
+ savedViewsMenu: PT_BR_SAVED_VIEWS_LABELS,
99
+ confirmAction: PT_BR_CONFIRM_ACTION_COPY,
100
+ categorySelect: PT_BR_CATEGORY_SELECT_COPY,
101
+ board: {
102
+ countOnPage: (label, count) => `${label}: ${count} nesta página`,
103
+ onThisPage: (count) => `${count} nesta página`,
104
+ pageSum: (sum) => `Soma desta página: ${sum}`,
105
+ pageScopeNote:
106
+ "As contagens e somas abaixo referem-se apenas aos itens desta página.",
107
+ },
108
+ deleteView: {
109
+ title: "Excluir visão",
110
+ sharedWarning: "Esta visão está compartilhada — a equipe perderá o acesso a ela.",
111
+ rowsUnaffected: (entityLabel) =>
112
+ `${entityLabel} não são afetados; apenas o recorte salvo é removido.`,
113
+ confirm: "Excluir visão",
114
+ },
115
+ manageViews: {
116
+ title: "Gerenciar visões",
117
+ empty: "Nenhuma visão salva.",
118
+ defaultTag: "Padrão",
119
+ otherUserTag: "De outro usuário",
120
+ deleteTitle: "Excluir a visão salva?",
121
+ deleteBody: "Os filtros e colunas guardados nela são perdidos. Não é possível restaurar.",
122
+ deleteConfirm: "Excluir",
123
+ },
124
+ saveView: {
125
+ sharedDescription: "Qualquer pessoa da loja poderá abrir e usar esta visão.",
126
+ setDefaultTitle: "Definir como padrão",
127
+ setDefaultDescription: "Esta tela abre nesta visão em vez da Visão principal.",
128
+ previewHeading: "O que esta visão guarda",
129
+ previewUnchanged: "Nada foi alterado — esta visão ficará igual à Visão principal.",
130
+ sortRowLabel: "Ordenação",
131
+ saveFailed: "Não foi possível salvar a visão.",
132
+ titleEditing: "Editar visão",
133
+ titleCreating: "Salvar visão",
134
+ descriptionLabel: "Descrição — opcional",
135
+ descriptionPlaceholder: "Para que serve esta visão",
136
+ submitEditing: "Salvar alterações",
137
+ submitCreating: "Salvar visão",
138
+ nameLabel: "Nome",
139
+ cancel: "Cancelar",
140
+ pinnedTitle: "Fixar na barra lateral",
141
+ pinnedDescription: "Aparece como atalho no menu, abaixo desta tela.",
142
+ sharedTitle: "Compartilhar com a equipe",
143
+ namePlaceholder: "Ex.: Recusados no PIX desta semana",
144
+ previewFilters: "Filtros",
145
+ previewHiddenColumns: "Colunas ocultas",
146
+ },
147
+ columns: {
148
+ visibleCount: (visible, total) => `${visible} de ${total} visíveis`,
149
+ reset: "Padrão",
150
+ showAll: "Mostrar todas",
151
+ },
152
+ display: {
153
+ sortTab: "Ordenar",
154
+ columnsTab: "Colunas",
155
+ panelTab: "Exibição",
156
+ direction: "Direção",
157
+ layoutHints: {
158
+ table: "Colunas comparáveis, boa para varrer números.",
159
+ list: "Uma linha por item, com os dados principais.",
160
+ cards: "Blocos maiores, bom para poucos itens.",
161
+ board: "Colunas por etapa, para acompanhar o que está onde.",
162
+ },
163
+ densityHeadings: {
164
+ table: "Altura das linhas",
165
+ list: "Altura das linhas",
166
+ cards: "Cards por linha",
167
+ board: "Largura das colunas",
168
+ },
169
+ densityLabels: {
170
+ table: { compact: "Baixa", cozy: "Média", comfortable: "Alta" },
171
+ list: { compact: "Baixa", cozy: "Média", comfortable: "Alta" },
172
+ cards: { compact: "Muitos", cozy: "Médio", comfortable: "Poucos" },
173
+ board: { compact: "Estreita", cozy: "Média", comfortable: "Larga" },
174
+ },
175
+ boardUnavailable: "Esta tela não declara etapas, então não oferece quadro.",
176
+ densityUnavailableNarrow:
177
+ "Um card por linha nesta largura — a densidade volta em telas maiores.",
178
+ trigger: "Exibir",
179
+ },
180
+ export: {
181
+ formats: {
182
+ json: { label: "JSON (.json)", hint: "Para integrações" },
183
+ },
184
+ visibleColumns: (columnCount) => `${columnCount} colunas visíveis, na ordem atual`,
185
+ trigger: "Exportar",
186
+ },
187
+ grid: {
188
+ rowActions: "Ações",
189
+ bulkActions: (selectedCount) => `Ações (${selectedCount}) ▾`,
190
+ },
191
+ filters: {
192
+ moreFilters: (count) => `Mais filtros: ${count} sem espaço na barra`,
193
+ moreFiltersApplied: (count, appliedCount) =>
194
+ `Mais filtros: ${count} sem espaço na barra, ${appliedCount} aplicado(s)`,
195
+ overflowNote: "sem espaço na barra",
196
+ rangeEnd: "Até",
197
+ rangeInvalid: "O início precisa ser menor que o fim.",
198
+ rangePresets: {
199
+ hoje: "Hoje",
200
+ ontem: "Ontem",
201
+ semana: "Esta semana",
202
+ mes: "Este mês",
203
+ ano: "Este ano",
204
+ },
205
+ scopesLabel: "Situação",
206
+ panelTitle: "Filtros",
207
+ clear: "Limpar",
208
+ clearAll: "Limpar filtros",
209
+ clearRange: (label) => `Limpar ${label}`,
210
+ allOption: "Todas",
211
+ optionSearchPlaceholder: "Buscar…",
212
+ optionsEmpty: "Nenhum resultado",
213
+ },
214
+ selection: {
215
+ selectAllOnPage: "Selecionar todos nesta página",
216
+ clearSelection: "Limpar seleção",
217
+ selectAll: "Selecionar tudo",
218
+ onThisPage: (count) => `${count} nesta página`,
219
+ selectRow: "Selecionar",
220
+ },
221
+ nav: {
222
+ mainView: "Visão principal",
223
+ defaultTag: "Padrão",
224
+ viewOptions: (viewName) => `Opções de ${viewName}`,
225
+ emptyHint: "Nenhuma visão salva. Ajuste filtros, colunas ou ordenação e salve abaixo.",
226
+ setDefault: "Definir como padrão",
227
+ deleteView: "Excluir visão",
228
+ unsavedChanges: "Alterações não salvas",
229
+ label: "Visão",
230
+ update: "Atualizar visão",
231
+ save: "Salvar visão",
232
+ updateFailed: "Não foi possível atualizar a visão",
233
+ saveFailed: "Não foi possível salvar a alteração da visão.",
234
+ editView: "Renomear e editar",
235
+ pinToSidebar: "Fixar na barra lateral",
236
+ shareWithTeam: "Compartilhar com a equipe",
237
+ },
238
+ search: {
239
+ placeholder: "Buscar…",
240
+ allColumnsLabel: "Buscar em todas as colunas",
241
+ keywordPlaceholder: "Pressione Enter para filtrar",
242
+ open: "Buscar",
243
+ close: "Fechar busca",
244
+ clear: "Limpar busca",
245
+ },
246
+ };
247
+