@elabs-ai/components-ui 4.0.0 → 4.1.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/README.md +10 -8
- package/dist/chunk-JKPPTL63.js +48 -0
- package/dist/chunk-JKPPTL63.js.map +1 -0
- package/dist/form.d.ts +28 -0
- package/dist/form.js +123 -0
- package/dist/form.js.map +1 -0
- package/dist/index.d.ts +2485 -167
- package/dist/index.js +10716 -2706
- package/dist/index.js.map +1 -1
- package/package.json +21 -7
- package/src/_peer-deps.test.ts +59 -0
- package/src/blocks-comparison-table.stories.tsx +2 -2
- package/src/components/accordion/accordion.tsx +1 -1
- package/src/components/advanced-group/advanced-group.tsx +1 -1
- package/src/components/alert/alert.tsx +4 -1
- package/src/components/app-shell/app-shell.stories.tsx +44 -2
- package/src/components/app-shell/app-shell.tsx +35 -2
- package/src/components/app-sidebar/app-sidebar.stories.tsx +9 -1
- package/src/components/attribution-panel/attribution-panel.tsx +1 -1
- package/src/components/attribution-panel/attributions.generated.ts +81 -77
- package/src/components/badge/badge.stories.tsx +8 -0
- package/src/components/badge/badge.tsx +1 -1
- package/src/components/bento-grid/bento-grid.test.tsx +1 -1
- package/src/components/bento-grid/bento-grid.tsx +1 -1
- package/src/components/breadcrumb/breadcrumb.stories.tsx +38 -0
- package/src/components/breadcrumb/breadcrumb.test.tsx +24 -1
- package/src/components/breadcrumb/breadcrumb.tsx +7 -2
- package/src/components/button/button.stories.tsx +116 -8
- package/src/components/button/button.tsx +1 -1
- package/src/components/card/card.stories.tsx +11 -6
- package/src/components/card/card.tsx +1 -1
- package/src/components/change-review/change-review.stories.tsx +145 -1
- package/src/components/change-review/change-review.test.tsx +143 -0
- package/src/components/change-review/change-review.tsx +185 -4
- package/src/components/checkbox/checkbox.tsx +1 -1
- package/src/components/color-picker/color-picker.tsx +6 -5
- package/src/components/command/command.stories.tsx +16 -6
- package/src/components/command/command.test.tsx +73 -0
- package/src/components/command/command.tsx +30 -7
- package/src/components/command/index.ts +1 -0
- package/src/components/command-trigger/command-trigger.stories.tsx +39 -0
- package/src/components/command-trigger/command-trigger.test.tsx +18 -0
- package/src/components/command-trigger/command-trigger.tsx +70 -0
- package/src/components/command-trigger/index.ts +1 -0
- package/src/components/context-rail/context-rail.stories.tsx +285 -0
- package/src/components/context-rail/context-rail.test.tsx +263 -0
- package/src/components/context-rail/context-rail.tsx +678 -0
- package/src/components/context-rail/index.ts +1 -0
- package/src/components/copyable-value/copyable-value.tsx +1 -1
- package/src/components/dialog/dialog.tsx +2 -2
- package/src/components/dropdown-menu/dropdown-menu.stories.tsx +1 -1
- package/src/components/empty-state/empty-state.test.tsx +26 -0
- package/src/components/empty-state/empty-state.tsx +6 -1
- package/src/components/expand-dialog/expand-dialog.tsx +1 -2
- package/src/components/field/field-context.ts +59 -0
- package/src/components/field/field.stories.tsx +142 -0
- package/src/components/field/field.test.tsx +415 -0
- package/src/components/field/field.tsx +340 -0
- package/src/components/field/index.ts +9 -0
- package/src/components/field-row/field-row.stories.tsx +85 -1
- package/src/components/field-row/field-row.test.tsx +145 -0
- package/src/components/field-row/field-row.tsx +48 -6
- package/src/components/file-upload/file-upload.stories.tsx +16 -0
- package/src/components/file-upload/file-upload.test.tsx +7 -2
- package/src/components/file-upload/file-upload.tsx +15 -4
- package/src/components/form/form.tsx +5 -2
- package/src/components/icon-button/icon-button.test.tsx +1 -1
- package/src/components/icon-button/icon-button.tsx +2 -2
- package/src/components/input/input.stories.tsx +121 -0
- package/src/components/input/input.test.tsx +13 -0
- package/src/components/input/input.tsx +2 -2
- package/src/components/input-group/input-group.stories.tsx +74 -0
- package/src/components/input-group/input-group.tsx +13 -4
- package/src/components/input-otp/input-otp.tsx +5 -1
- package/src/components/keyboard-shortcuts/index.ts +6 -0
- package/src/components/keyboard-shortcuts/keyboard-shortcuts.stories.tsx +177 -0
- package/src/components/keyboard-shortcuts/keyboard-shortcuts.test.tsx +73 -0
- package/src/components/keyboard-shortcuts/keyboard-shortcuts.tsx +203 -0
- package/src/components/link-preview/link-preview.tsx +1 -1
- package/src/components/locale-provider/index.ts +6 -1
- package/src/components/locale-provider/locale-provider.stories.tsx +89 -1
- package/src/components/locale-provider/locale-provider.test.tsx +257 -1
- package/src/components/locale-provider/locale-provider.tsx +63 -8
- package/src/components/locale-provider/messages.ts +501 -2
- package/src/components/match-highlight/match-highlight.stories.tsx +1 -1
- package/src/components/mention-input/mention-input-mirror.stories.tsx +9 -1
- package/src/components/mention-input/mention-input.tsx +8 -38
- package/src/components/mention-input/mention-value.ts +8 -2
- package/src/components/metric-card/metric-card.stories.tsx +5 -3
- package/src/components/metric-card/metric-card.tsx +21 -2
- package/src/components/model-picker/model-picker.stories.tsx +63 -3
- package/src/components/model-picker/model-picker.test.tsx +63 -0
- package/src/components/model-picker/model-picker.tsx +62 -36
- package/src/components/nav-main/nav-main.tsx +1 -1
- package/src/components/nav-notifications/nav-notifications.stories.tsx +110 -0
- package/src/components/nav-notifications/nav-notifications.tsx +57 -5
- package/src/components/navigation-menu/navigation-menu.stories.tsx +22 -0
- package/src/components/navigation-menu/navigation-menu.test.tsx +174 -0
- package/src/components/navigation-menu/navigation-menu.tsx +189 -12
- package/src/components/page-shell/page-shell.stories.tsx +163 -0
- package/src/components/page-shell/page-shell.test.tsx +229 -0
- package/src/components/page-shell/page-shell.tsx +108 -25
- package/src/components/pagination/pagination.test.tsx +90 -0
- package/src/components/pagination/pagination.tsx +9 -5
- package/src/components/radio-group/radio-group.tsx +1 -1
- package/src/components/rating/rating.tsx +1 -1
- package/src/components/resizable/resizable.stories.tsx +114 -2
- package/src/components/resizable/resizable.tsx +1 -1
- package/src/components/revision-timeline/revision-timeline.stories.tsx +8 -1
- package/src/components/revision-timeline/revision-timeline.test.tsx +26 -0
- package/src/components/revision-timeline/revision-timeline.tsx +46 -3
- package/src/components/schema-form/from-json-schema.test.ts +390 -0
- package/src/components/schema-form/from-json-schema.ts +375 -0
- package/src/components/schema-form/index.ts +81 -0
- package/src/components/schema-form/schema-form-spec.ts +698 -0
- package/src/components/schema-form/schema-form.stories.tsx +566 -0
- package/src/components/schema-form/schema-form.test.tsx +900 -0
- package/src/components/schema-form/schema-form.tsx +1545 -0
- package/src/components/section-header/section-header.stories.tsx +37 -0
- package/src/components/section-header/section-header.tsx +12 -1
- package/src/components/select/select.tsx +6 -2
- package/src/components/sheet/sheet.tsx +1 -1
- package/src/components/side-dock/index.ts +1 -0
- package/src/components/side-dock/side-dock.stories.tsx +137 -0
- package/src/components/side-dock/side-dock.test.tsx +273 -0
- package/src/components/side-dock/side-dock.tsx +502 -0
- package/src/components/sidebar/index.ts +1 -0
- package/src/components/sidebar/sidebar-frame.test.tsx +162 -0
- package/src/components/sidebar/sidebar.stories.tsx +421 -1
- package/src/components/sidebar/sidebar.test.tsx +36 -1
- package/src/components/sidebar/sidebar.tsx +245 -33
- package/src/components/skip-link/index.ts +1 -0
- package/src/components/skip-link/skip-link.stories.tsx +106 -0
- package/src/components/skip-link/skip-link.test.tsx +20 -0
- package/src/components/skip-link/skip-link.tsx +34 -0
- package/src/components/slider/slider.tsx +1 -1
- package/src/components/split-panel/index.ts +6 -1
- package/src/components/split-panel/split-panel.stories.tsx +18 -2
- package/src/components/split-panel/split-panel.test.tsx +20 -0
- package/src/components/split-panel/split-panel.tsx +28 -8
- package/src/components/state-panel/state-panel.stories.tsx +52 -0
- package/src/components/state-panel/state-panel.test.tsx +125 -0
- package/src/components/state-panel/state-panel.tsx +96 -17
- package/src/components/status-badge/status-badge.stories.tsx +8 -0
- package/src/components/switch/switch.tsx +1 -1
- package/src/components/table/table.stories.tsx +62 -0
- package/src/components/table/table.test.tsx +142 -1
- package/src/components/table/table.tsx +60 -1
- package/src/components/tabs/tabs.tsx +8 -2
- package/src/components/tag-input/tag-input.tsx +3 -2
- package/src/components/team-switcher/team-switcher.tsx +34 -5
- package/src/components/textarea/textarea.tsx +1 -1
- package/src/components/theme-switcher/theme-switcher.tsx +6 -2
- package/src/components/theme-switcher/use-theme-transition.ts +2 -2
- package/src/components/timeline/timeline.stories.tsx +27 -0
- package/src/components/timeline/timeline.tsx +11 -1
- package/src/components/toggle/toggle.tsx +1 -1
- package/src/components/toolbar/toolbar.stories.tsx +10 -2
- package/src/components/tree/tree.stories.tsx +2 -2
- package/src/components/tree/tree.tsx +14 -9
- package/src/components/typography/prose.tsx +1 -1
- package/src/components/typography/typography.stories.tsx +228 -0
- package/src/components/view-toolbar/view-toolbar.stories.tsx +41 -1
- package/src/components/view-toolbar/view-toolbar.test.tsx +33 -0
- package/src/components/view-toolbar/view-toolbar.tsx +37 -4
- package/src/components/virtual-select/virtual-select.test.tsx +1 -1
- package/src/components/wizard/wizard.tsx +1 -1
- package/src/components/workspace-picker/index.ts +3 -0
- package/src/components/workspace-picker/workspace-picker-state.ts +50 -0
- package/src/components/workspace-picker/workspace-picker.stories.tsx +126 -0
- package/src/components/workspace-picker/workspace-picker.test.tsx +207 -0
- package/src/components/workspace-picker/workspace-picker.tsx +172 -0
- package/src/illustrations/empty-list-illustration.tsx +26 -0
- package/src/illustrations/error-illustration.tsx +60 -0
- package/src/illustrations/first-run-illustration.tsx +27 -0
- package/src/illustrations/illustration-base.tsx +108 -0
- package/src/illustrations/illustrations.stories.tsx +94 -0
- package/src/illustrations/illustrations.test.tsx +98 -0
- package/src/illustrations/index.ts +16 -0
- package/src/illustrations/no-access-illustration.tsx +45 -0
- package/src/illustrations/no-results-illustration.tsx +46 -0
- package/src/illustrations/offline-illustration.tsx +37 -0
- package/src/illustrations/success-illustration.tsx +40 -0
- package/src/index.ts +75 -2
- package/src/lib/agent-event-model.test.ts +12 -0
- package/src/lib/agent-event-model.ts +42 -0
- package/src/lib/approval-option.test.ts +17 -0
- package/src/lib/approval-option.ts +53 -0
- package/src/lib/check-result.ts +33 -0
- package/src/lib/diff-line.test.ts +36 -0
- package/src/lib/diff-line.ts +63 -0
- package/src/lib/diff-rows.test.ts +76 -0
- package/src/lib/diff-rows.ts +92 -0
- package/src/lib/format-duration.test.ts +22 -0
- package/src/lib/format-duration.ts +30 -0
- package/src/lib/has-renderable-content.test.ts +49 -0
- package/src/lib/has-renderable-content.ts +32 -0
- package/src/lib/operating-mode.test.ts +36 -0
- package/src/lib/operating-mode.ts +81 -0
- package/src/lib/optional-peer.ts +59 -0
- package/src/lib/session-launch.ts +37 -0
- package/src/lib/slash-command.test.ts +44 -0
- package/src/lib/slash-command.ts +45 -0
- package/src/lib/trigger-query.test.ts +94 -0
- package/src/lib/trigger-query.ts +88 -0
- package/src/lib/use-mobile.ts +12 -6
- package/src/motion.stories.tsx +6 -0
- package/src/templates-object-detail-hub.stories.tsx +2 -2
- package/src/templates-screen-states.stories.tsx +5 -5
- package/src/templates-settings.stories.tsx +1 -1
- package/src/blocks/sidebar-02/app-sidebar.tsx +0 -160
- package/src/blocks/sidebar-02/logo.tsx +0 -18
- package/src/blocks/sidebar-02/nav-main.tsx +0 -13
- package/src/blocks/sidebar-02/nav-notifications.tsx +0 -7
- package/src/blocks/sidebar-02/sidebar-02.stories.tsx +0 -23
- package/src/blocks/sidebar-02/team-switcher.tsx +0 -7
- package/src/blocks/sidebar-04/app-sidebar.tsx +0 -236
- package/src/blocks/sidebar-04/mail-context.tsx +0 -29
- package/src/blocks/sidebar-04/nav-user.tsx +0 -6
- package/src/blocks/sidebar-04/sidebar-04.stories.tsx +0 -150
- package/src/blocks/sidebar-05/app-sidebar.tsx +0 -375
- package/src/blocks/sidebar-05/sidebar-05.stories.tsx +0 -18
- package/src/blocks/sidebar-05/team-switcher.tsx +0 -6
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* ICU cardinal-plural category, per `Intl.PluralRules` ("zero" | "one" | "two"
|
|
5
|
+
* | "few" | "many" | "other"). Locales vary in which categories they use —
|
|
6
|
+
* English has only "one"/"other"; Polish and Russian also use "few"/"many" —
|
|
7
|
+
* so a `PluralMessage` may omit any category it doesn't need. `"other"` is the
|
|
8
|
+
* universal fallback every locale defines.
|
|
9
|
+
*/
|
|
10
|
+
export type PluralCategory = Intl.LDMLPluralRule;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A per-count message: one string per plural category, selected at render
|
|
14
|
+
* time via `Intl.PluralRules(locale).select(count)`. Each string still
|
|
15
|
+
* supports the same `{name}`-style interpolation as a plain message.
|
|
16
|
+
* Note: when passed to `t()`, `count` in `vars` must be a number, not a
|
|
17
|
+
* numeric string, to select the correct plural category.
|
|
18
|
+
*/
|
|
19
|
+
export type PluralMessage = Partial<Record<PluralCategory, string>>;
|
|
20
|
+
|
|
21
|
+
/** A single message value: a plain string, or a plural-form map. */
|
|
22
|
+
export type MessageValue = string | PluralMessage;
|
|
23
|
+
|
|
3
24
|
/**
|
|
4
25
|
* Shipped English (en-US) default microcopy bundle.
|
|
5
26
|
*
|
|
@@ -7,7 +28,7 @@
|
|
|
7
28
|
* translate cleanly into any target locale. Keep this list small and real —
|
|
8
29
|
* only add a key here when a component actually needs it.
|
|
9
30
|
*/
|
|
10
|
-
export const DEFAULT_MESSAGES: Record<string,
|
|
31
|
+
export const DEFAULT_MESSAGES: Record<string, MessageValue> = {
|
|
11
32
|
// ── Generic (shared across packages — reuse these before minting a new key) ──
|
|
12
33
|
close: "Close",
|
|
13
34
|
copy: "Copy",
|
|
@@ -20,6 +41,11 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
20
41
|
loading: "Loading…",
|
|
21
42
|
more: "More",
|
|
22
43
|
selectAll: "Select all",
|
|
44
|
+
// Cardinal-plural example (#19) — a shared "N item(s) selected" microcopy
|
|
45
|
+
// any multi-select surface can reuse via `t("itemsSelected", { count })`.
|
|
46
|
+
// Demonstrates the plural-form shape: pick the primitive over inventing a
|
|
47
|
+
// near-duplicate flat string per component.
|
|
48
|
+
itemsSelected: { one: "{count} item selected", other: "{count} items selected" },
|
|
23
49
|
|
|
24
50
|
// ── @elabs-ai/components-ui ───────────────────────────────────────────────────────────────
|
|
25
51
|
"ui.metricCard.loading": "Loading metric…",
|
|
@@ -43,6 +69,24 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
43
69
|
"ui.modelPicker.loadFailed": "Couldn't load the list",
|
|
44
70
|
"ui.modelPicker.nothingYet": "Nothing to show yet",
|
|
45
71
|
"ui.modelPicker.retry": "Retry",
|
|
72
|
+
// KeyboardShortcuts (#113). `emptyFiltered` keeps the user's own query in the
|
|
73
|
+
// sentence so the empty state says WHY it is empty, not merely that it is.
|
|
74
|
+
"ui.keyboardShortcuts.searchPlaceholder": "Search shortcuts…",
|
|
75
|
+
"ui.keyboardShortcuts.emptyTitle": "No shortcuts found",
|
|
76
|
+
"ui.keyboardShortcuts.emptyFiltered": "No shortcuts match “{query}”.",
|
|
77
|
+
"ui.keyboardShortcuts.empty": "No shortcuts to show.",
|
|
78
|
+
// WorkspacePicker (#111). It composes ModelPicker, so it carries its OWN
|
|
79
|
+
// label/search strings rather than inheriting the generic "Choose a target".
|
|
80
|
+
// `current` is appended into the row's meta so the in-force workspace reaches
|
|
81
|
+
// the option's accessible name as a WORD, not only a check glyph (1.4.1).
|
|
82
|
+
"ui.workspacePicker.label": "Choose a workspace",
|
|
83
|
+
"ui.workspacePicker.placeholder": "No workspace selected",
|
|
84
|
+
"ui.workspacePicker.recent": "Recent workspaces",
|
|
85
|
+
"ui.workspacePicker.searchPlaceholder": "Search workspaces…",
|
|
86
|
+
"ui.workspacePicker.current": "Current",
|
|
87
|
+
"ui.workspacePicker.pathLabel": "Workspace path",
|
|
88
|
+
"ui.workspacePicker.pathPlaceholder": "/path/to/project…",
|
|
89
|
+
"ui.workspacePicker.openPath": "Open",
|
|
46
90
|
// ViewToolbar (#331). `removeFilter` deliberately WRAPS the visible chip text
|
|
47
91
|
// so the accessible name contains it (WCAG 2.5.3 Label in Name).
|
|
48
92
|
"ui.viewToolbar.about": "About this view",
|
|
@@ -81,6 +125,54 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
81
125
|
"ui.confirmDialog.cancel": "Cancel",
|
|
82
126
|
"ui.advancedGroup.title": "Advanced",
|
|
83
127
|
"ui.advancedGroup.changed": "{count} changed",
|
|
128
|
+
// SchemaForm — the spec-driven config-form renderer (issue #22).
|
|
129
|
+
"ui.schemaForm.selectPlaceholder": "Select…",
|
|
130
|
+
"ui.schemaForm.label": "Form",
|
|
131
|
+
"ui.schemaForm.submit": "Submit",
|
|
132
|
+
"ui.schemaForm.submitting": "Submitting…",
|
|
133
|
+
"ui.schemaForm.submitted": "Submitted",
|
|
134
|
+
// SchemaFormTestAction — a form/group-level "Test connection" affordance
|
|
135
|
+
// (issue #22 maintainer ruling, 2026-09-01), independent of field validity
|
|
136
|
+
// and never gating submit.
|
|
137
|
+
"ui.schemaForm.testAction.label": "Test connection",
|
|
138
|
+
"ui.schemaForm.testAction.pending": "Testing…",
|
|
139
|
+
"ui.schemaForm.testAction.success": "Connected",
|
|
140
|
+
"ui.schemaForm.testAction.failure": "Test failed",
|
|
141
|
+
// Pagination's ellipsis (sr-only — the visible glyph is decorative).
|
|
142
|
+
"ui.pagination.morePages": "More pages",
|
|
143
|
+
// Pagination's prev/next links — the ACCESSIBLE NAME (`aria-label`), distinct
|
|
144
|
+
// from the visible `previous`/`next` text below it: an `aria-label` overrides
|
|
145
|
+
// visible text content as the accessible name, so leaving these hardcoded in
|
|
146
|
+
// English meant a non-English `LocaleProvider` translated the visible label
|
|
147
|
+
// but a screen-reader user still heard English (#12/#53 review, P2).
|
|
148
|
+
"ui.pagination.previous": "Go to previous page",
|
|
149
|
+
"ui.pagination.next": "Go to next page",
|
|
150
|
+
// Sidebar's mobile Sheet title (sr-only header — the sheet itself has no
|
|
151
|
+
// visible chrome, so this is only ever read by assistive tech).
|
|
152
|
+
"ui.sidebar.title": "Sidebar",
|
|
153
|
+
// ContextRail's switcher count phrase (composed into the accessible name,
|
|
154
|
+
// e.g. "Sources 3 items") and its default empty-state copy.
|
|
155
|
+
"ui.contextRail.sectionCount": { one: "{count} item", other: "{count} items" },
|
|
156
|
+
"ui.contextRail.empty": "No sections",
|
|
157
|
+
// SideDock's resize handle — its sr-only label and its live width readout.
|
|
158
|
+
"ui.sideDock.resize": "Resize",
|
|
159
|
+
"ui.sideDock.widthValue": { one: "{size} pixel", other: "{size} pixels" },
|
|
160
|
+
// Tree's error row — shared by the virtualized and non-virtualized branches.
|
|
161
|
+
"ui.tree.failedToLoad": "Failed to load",
|
|
162
|
+
// ThemeSwitcher's "follow the OS" option, in both dropdown and toggle modes.
|
|
163
|
+
"ui.themeSwitcher.system": "System",
|
|
164
|
+
"ui.navNotifications.label": "Notifications",
|
|
165
|
+
"ui.teamSwitcher.label": "Teams",
|
|
166
|
+
"ui.teamSwitcher.addTeam": "Add team",
|
|
167
|
+
// Table's own scroll wrapper (#366). Rendered ONLY when the wrapper actually
|
|
168
|
+
// overflows, so it is never announced for a table that fits — see
|
|
169
|
+
// `packages/ui/src/components/table/table.tsx`. Deliberately a `ui.*`
|
|
170
|
+
// sibling of `data.table.scrollRegion` rather than a shared cross-package
|
|
171
|
+
// key: `Table` is a `@elabs-ai/components-ui` component and each package
|
|
172
|
+
// keeps its own namespace even where the English string coincides (compare
|
|
173
|
+
// `viewer.content` vs this), so a translator can phrase either
|
|
174
|
+
// independently and neither package depends on a string owned by another.
|
|
175
|
+
"ui.table.scrollRegion": "Table contents, scrollable",
|
|
84
176
|
|
|
85
177
|
// ── @elabs-ai/components-data ─────────────────────────────────────────────────────────────
|
|
86
178
|
// The scroll region's accessible name is rendered ONLY when the table actually
|
|
@@ -89,6 +181,57 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
89
181
|
// Fallback name for a row's activation control when the row's first cell holds
|
|
90
182
|
// no primitive value to name it after (see `rowActionLabel`).
|
|
91
183
|
"data.table.rowAction": "Activate row",
|
|
184
|
+
// createSelectionColumn (#11) — the header select-all checkbox and each row's
|
|
185
|
+
// own checkbox. Kept table-scoped (not the generic `selectAll` key) so a
|
|
186
|
+
// translator can phrase "rows" distinctly from other bulk-select surfaces.
|
|
187
|
+
"data.table.selectAllRows": "Select all rows",
|
|
188
|
+
// `selectRowNamed` names each row's checkbox from its own first data column
|
|
189
|
+
// (#11 I4) so screen-reader users hear "Select Alpha", not `selectRow`'s
|
|
190
|
+
// identical generic label repeated on every row; `selectRow` stays the
|
|
191
|
+
// fallback when no data column value is derivable.
|
|
192
|
+
"data.table.selectRowNamed": "Select {name}",
|
|
193
|
+
"data.table.selectRow": "Select row",
|
|
194
|
+
// Column resizing (#12) — the accessible name for the WAI-ARIA
|
|
195
|
+
// separator-as-slider resize handle at the end of a resizable header cell.
|
|
196
|
+
"data.table.resizeColumn": "Resize column, {name}",
|
|
197
|
+
// #51 — the handle's accessible VALUE, paired with aria-valuenow (which
|
|
198
|
+
// stays a plain number for AT/TanStack). A bare number reads as a
|
|
199
|
+
// dimensionless ordinal; the unit makes it a size. A `PluralMessage` (PR
|
|
200
|
+
// #81 review, "Format the announced resize value for the active locale") —
|
|
201
|
+
// the call site passes both `count` (the raw number, so a locale whose
|
|
202
|
+
// plural rules select something other than "other" for a given size is
|
|
203
|
+
// reachable) and `size` (pre-formatted via `formatNumber`, so a locale
|
|
204
|
+
// override renders locale-appropriate digits/grouping instead of a raw
|
|
205
|
+
// Latin-digit JS number).
|
|
206
|
+
"data.table.resizeColumnValue": { one: "{size} pixel", other: "{size} pixels" },
|
|
207
|
+
// Row drag-reorder (#13). `reorderHandle`/`reorderColumnHeader` name the
|
|
208
|
+
// grip control and its column; the four `reorder*` announcement keys back
|
|
209
|
+
// the aria-live region dnd-kit's `accessibility.announcements` renders on
|
|
210
|
+
// pickup/move/drop/cancel (WCAG 4.1.3) — `position`/`total` are 1-based so
|
|
211
|
+
// the announcement reads like "3 of 8", not a 0-based index.
|
|
212
|
+
"data.table.reorderColumnHeader": "Reorder",
|
|
213
|
+
"data.table.reorderHandle": "Reorder {name}",
|
|
214
|
+
"data.table.reorderPickedUp": "Picked up {name}.",
|
|
215
|
+
"data.table.reorderMoved": "{name} moved to position {position} of {total}.",
|
|
216
|
+
"data.table.reorderDropped": "{name} dropped at position {position} of {total}.",
|
|
217
|
+
"data.table.reorderCancelled":
|
|
218
|
+
"Reordering cancelled. {name} returned to position {position} of {total}.",
|
|
219
|
+
// #98: `@dnd-kit` renders two more AT-visible strings for this same
|
|
220
|
+
// feature that this repo's source never writes — the hidden keyboard
|
|
221
|
+
// usage instructions (wired to the grip via `aria-describedby`) and the
|
|
222
|
+
// activator's `aria-roledescription`. Both ship a hardcoded English
|
|
223
|
+
// default deep inside the library; localizing them means overriding them
|
|
224
|
+
// explicitly with these two keys. The English DEFAULT below is dnd-kit's
|
|
225
|
+
// own default text verbatim (`defaultScreenReaderInstructions.draggable`
|
|
226
|
+
// in `@dnd-kit/core`, and `useSortable`'s `roleDescription: 'sortable'` in
|
|
227
|
+
// `@dnd-kit/sortable`) — not a rewrite — so an English consumer with no
|
|
228
|
+
// `LocaleProvider` override sees byte-identical output to before this
|
|
229
|
+
// fix; only a `messages` override changes it.
|
|
230
|
+
"data.table.reorderInstructions":
|
|
231
|
+
"\n To pick up a draggable item, press the space bar.\n While dragging, use the arrow keys to move the item.\n Press space again to drop the item in its new position, or press escape to cancel.\n ",
|
|
232
|
+
"data.table.reorderRoleDescription": "sortable",
|
|
233
|
+
"data.facetFilter.clearFilters": "Clear filters",
|
|
234
|
+
"data.columnPicker.toggleColumns": "Toggle columns",
|
|
92
235
|
|
|
93
236
|
// ── @elabs-ai/components-charts ───────────────────────────────────────────────────────────
|
|
94
237
|
// Shared caption for any bare chart surface's layout-shaped skeleton
|
|
@@ -105,6 +248,12 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
105
248
|
// Announced when `copyValueOnActivate` puts a datapoint's exact value on the
|
|
106
249
|
// clipboard — the recovery path for a compact axis label.
|
|
107
250
|
"charts.datapoint.copied": "Exact value copied",
|
|
251
|
+
// ChartFrame's SVG/PNG export actions (RM-025). Each string is used twice —
|
|
252
|
+
// as the icon button's `aria-label` (its ONLY accessible name) and as the
|
|
253
|
+
// tooltip a sighted user reads — so one key serves both and they cannot
|
|
254
|
+
// drift apart in translation.
|
|
255
|
+
"charts.chartFrame.exportSvg": "Export as SVG",
|
|
256
|
+
"charts.chartFrame.exportPng": "Export as PNG",
|
|
108
257
|
|
|
109
258
|
// ── @elabs-ai/components-ai ───────────────────────────────────────────────────────────────
|
|
110
259
|
// Namespaced `ai.<area>.<key>` so package microcopy can't collide with the
|
|
@@ -120,25 +269,66 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
120
269
|
"ai.promptInput.uploadFiles": "Upload files",
|
|
121
270
|
"ai.promptInput.submit": "Submit",
|
|
122
271
|
"ai.promptInput.stop": "Stop",
|
|
272
|
+
"ai.agent.instructions": "Instructions",
|
|
273
|
+
"ai.agent.tools": "Tools",
|
|
123
274
|
"ai.codeBlock.generating": "Generating…",
|
|
124
275
|
"ai.composer.placeholder": "Ask me anything…",
|
|
125
|
-
"ai.
|
|
276
|
+
"ai.tokenUsage.usage": "Model context usage",
|
|
277
|
+
"ai.tokenUsage.totalCost": "Total cost",
|
|
278
|
+
"ai.tokenUsage.input": "Input",
|
|
279
|
+
"ai.tokenUsage.output": "Output",
|
|
280
|
+
"ai.tokenUsage.reasoning": "Reasoning",
|
|
281
|
+
"ai.tokenUsage.cache": "Cache",
|
|
126
282
|
"ai.contextPanel.back": "Back to context",
|
|
127
283
|
"ai.contextPanel.toggle": "Toggle context panel",
|
|
284
|
+
// The mobile Sheet's sr-only title (#18) — distinct from `contextPanel.toggle`,
|
|
285
|
+
// which labels the button that opens/closes it.
|
|
286
|
+
"ai.contextPanel.title": "Context panel",
|
|
128
287
|
"ai.environmentVariables.toggleVisibility": "Toggle value visibility",
|
|
129
288
|
"ai.gallery.label": "Image gallery",
|
|
130
289
|
"ai.gallery.expandImage": "Expand image",
|
|
131
290
|
"ai.gallery.downloadImage": "Download image",
|
|
291
|
+
"ai.gallery.noImages": "No images",
|
|
292
|
+
"ai.gallery.noDetails": "No details",
|
|
293
|
+
// Shared by Tool's technical view and SchemaDisplay's request panel.
|
|
294
|
+
"ai.schemaDisplay.parameters": "Parameters",
|
|
295
|
+
"ai.schemaDisplay.response": "Response",
|
|
296
|
+
// ReasoningTrigger's default not-yet-timed message (before `duration` is known).
|
|
297
|
+
"ai.reasoning.thoughtDefault": "Thought for a few seconds",
|
|
298
|
+
"ai.stackTrace.empty": "No stack frames",
|
|
299
|
+
"ai.webPreview.noConsoleOutput": "No console output",
|
|
300
|
+
// PlanTrigger's icon-only collapse/expand control (sr-only).
|
|
301
|
+
"ai.plan.togglePlan": "Toggle plan",
|
|
132
302
|
"ai.message.actions": "Message actions",
|
|
133
303
|
"ai.message.editMessage": "Edit message",
|
|
134
304
|
"ai.message.feedback": "Message feedback",
|
|
135
305
|
"ai.message.previousBranch": "Previous branch",
|
|
136
306
|
"ai.message.nextBranch": "Next branch",
|
|
307
|
+
"ai.messageCompare.error": "Error",
|
|
308
|
+
"ai.messageCompare.tabs": "Compare responses",
|
|
137
309
|
"ai.persona.idle": "Assistant idle",
|
|
138
310
|
"ai.persona.listening": "Assistant listening",
|
|
139
311
|
"ai.persona.thinking": "Assistant thinking…",
|
|
140
312
|
"ai.persona.speaking": "Assistant speaking",
|
|
141
313
|
"ai.persona.asleep": "Assistant asleep",
|
|
314
|
+
// Optional-peer lazy engines (issue #33) — one shared pair every lazy
|
|
315
|
+
// boundary's missing-dependency panel resolves through, plus one
|
|
316
|
+
// `feature`-name key per boundary that renders it (mermaid, the terminal).
|
|
317
|
+
"ai.error.engineMissing": "{feature} unavailable",
|
|
318
|
+
"ai.error.engineMissingBody": "{feature} needs {packages} to be installed.",
|
|
319
|
+
"ai.error.retry": "Try again",
|
|
320
|
+
"ai.mermaid.feature": "Mermaid diagrams",
|
|
321
|
+
"ai.mermaid.renderError": "Diagram couldn't be drawn",
|
|
322
|
+
"ai.terminal.feature": "Interactive terminal",
|
|
323
|
+
"ai.terminal.renderError": "Terminal couldn't start",
|
|
324
|
+
"ai.audioPlayer.feature": "Audio player",
|
|
325
|
+
"ai.audioPlayer.renderError": "Audio player couldn't load",
|
|
326
|
+
// AudioVisualizer. Announced through a throttled `role="status"` region —
|
|
327
|
+
// the canvas itself is decorative (see .claude/rules/loading-states.md and
|
|
328
|
+
// issue #21's accessibility guidance).
|
|
329
|
+
"ai.audioVisualizer.idle": "Microphone not connected",
|
|
330
|
+
"ai.audioVisualizer.silent": "No input detected",
|
|
331
|
+
"ai.audioVisualizer.active": "Microphone active",
|
|
142
332
|
"ai.selectionToolbar.label": "Selection actions",
|
|
143
333
|
"ai.webPreview.urlPlaceholder": "Enter URL...",
|
|
144
334
|
"ai.micSelector.searchPlaceholder": "Search microphones...",
|
|
@@ -148,6 +338,60 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
148
338
|
"ai.voiceSelector.playPreview": "Play preview",
|
|
149
339
|
"ai.voiceSelector.pausePreview": "Pause preview",
|
|
150
340
|
|
|
341
|
+
// TurnStatus / SessionStatusBar (#105). `label` itself is caller-supplied
|
|
342
|
+
// ("Working…", "Editing files…") and rendered verbatim, so it needs no key
|
|
343
|
+
// here — only the component-owned completed-turn sentence and controls do.
|
|
344
|
+
"ai.turnStatus.completedIn": "Turn completed in {elapsed}",
|
|
345
|
+
"ai.turnStatus.completed": "Turn completed",
|
|
346
|
+
"ai.turnStatus.scrollToBottom": "Scroll to bottom",
|
|
347
|
+
"ai.sessionStatusBar.connections": "{connected} of {total} connections",
|
|
348
|
+
"ai.sessionStatusBar.connecting": "Connecting…",
|
|
349
|
+
// SessionHeader (#110). The section headings and the quick-action group name
|
|
350
|
+
// are component-owned chrome; the capability/what's-new item text itself is
|
|
351
|
+
// caller-supplied and rendered verbatim.
|
|
352
|
+
"ai.sessionHeader.capabilities": "Capabilities",
|
|
353
|
+
"ai.sessionHeader.whatsNew": "What’s new",
|
|
354
|
+
"ai.sessionHeader.quickActions": "Quick actions",
|
|
355
|
+
// PermissionModeSelect (#104). The in-force marker is a WORD inside the mode
|
|
356
|
+
// label, so the current mode survives greyscale and reaches the accessible name.
|
|
357
|
+
"ai.permissionModeSelect.current": "Current",
|
|
358
|
+
// AgentEvent (#109). The pass/fail WORD is the non-colour channel — the tone
|
|
359
|
+
// is redundant with it, so a check outcome survives greyscale (WCAG 1.4.1).
|
|
360
|
+
"ai.agentEvent.checkPassed": "Passed",
|
|
361
|
+
"ai.agentEvent.checkFailed": "Failed",
|
|
362
|
+
"ai.agentEvent.checksSummary": "{passed}/{ran} checks passed",
|
|
363
|
+
"ai.agentEvent.phaseBefore": "Before",
|
|
364
|
+
"ai.agentEvent.phaseAfter": "After",
|
|
365
|
+
"ai.agentEvent.phaseLifecycle": "Lifecycle",
|
|
366
|
+
// DiffView (#102). `addedLine` / `removedLine` are the sr-only polarity
|
|
367
|
+
// prefixes — the +/− glyph is aria-hidden, so these WORDS are the channel a
|
|
368
|
+
// greyscale or screen-reader user recovers the polarity from (WCAG 1.4.1).
|
|
369
|
+
// They intentionally end in a space so they read as a prefix to the code line.
|
|
370
|
+
"ai.diffView.addedLine": "Added: ",
|
|
371
|
+
"ai.diffView.removedLine": "Removed: ",
|
|
372
|
+
"ai.diffView.statsSummary": "{additions} additions, {deletions} deletions",
|
|
373
|
+
"ai.diffView.showMore": { one: "Show {count} more line", other: "Show {count} more lines" },
|
|
374
|
+
"ai.diffView.pagerLegend": "Arrow keys scroll, Page Up/Down page, Home/End jump",
|
|
375
|
+
"ai.diffView.regionLabel": "Code diff",
|
|
376
|
+
"ai.diffView.loading": "Loading diff…",
|
|
377
|
+
// ApprovalCard (#103). The SCOPE sentence is what makes an N-option
|
|
378
|
+
// permission prompt safe to answer: "Yes" and "Yes, and don't ask again" look
|
|
379
|
+
// alike and mean very different things. Each option links its scope sentence
|
|
380
|
+
// through aria-describedby, so the blast radius of a choice reaches assistive
|
|
381
|
+
// tech as words — never as a colour or a data-* attribute.
|
|
382
|
+
"ai.approvalCard.scopeOnceDescription": "Applies to this action only.",
|
|
383
|
+
"ai.approvalCard.scopeSessionDescription":
|
|
384
|
+
"Applies to actions like this for the rest of this session.",
|
|
385
|
+
"ai.approvalCard.scopeAlwaysDescription": "Applies to actions like this from now on.",
|
|
386
|
+
"ai.approvalCard.scopeDenyDescription": "Rejects this action.",
|
|
387
|
+
"ai.approvalCard.reasonLabel": "Reason",
|
|
388
|
+
"ai.approvalCard.reasonPlaceholder": "Add a reason (optional)…",
|
|
389
|
+
// PromptInputSlash (#106). `listLabel` goes to cmdk's own `label` prop, not
|
|
390
|
+
// `aria-label` — cmdk overwrites a consumer `aria-label` on CommandList and
|
|
391
|
+
// reads its accessible name off `label` instead.
|
|
392
|
+
"ai.promptInputSlash.listLabel": "Commands",
|
|
393
|
+
"ai.promptInputSlash.empty": "No matching commands.",
|
|
394
|
+
|
|
151
395
|
// ── Streamdown chrome (third-party rendering surface) ──────────────────────
|
|
152
396
|
// `streamdown` renders its OWN controls inside every streamed-markdown block
|
|
153
397
|
// (code header, table menus, Mermaid toolbar, external-link interstitial) and
|
|
@@ -297,4 +541,259 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
297
541
|
"viewer.highlight.previous": "Previous passage",
|
|
298
542
|
"viewer.highlight.next": "Next passage",
|
|
299
543
|
"viewer.highlight.count": "Passage {index} of {total}",
|
|
544
|
+
|
|
545
|
+
// ── @elabs-ai/components-terminal ─────────────────────────────────────────
|
|
546
|
+
// Terminal (the read-only ANSI log): the ONE live-region announcement for
|
|
547
|
+
// its `isStreaming` rung. The blinking cursor block is the only other
|
|
548
|
+
// streaming signal and it is purely visual, so without this a screen-reader
|
|
549
|
+
// user attached to a running build or deploy log gets no indication that
|
|
550
|
+
// anything is still arriving.
|
|
551
|
+
"terminal.output.streaming": "Streaming output…",
|
|
552
|
+
// TerminalTranscriptRow (#117 T2): the gutter's meaning as words, so the
|
|
553
|
+
// "who spoke / what it printed / did it fail" grammar survives greyscale
|
|
554
|
+
// and reaches assistive tech, not only the glyph + colour.
|
|
555
|
+
"terminal.transcriptRow.user": "Prompt",
|
|
556
|
+
"terminal.transcriptRow.agent": "Agent",
|
|
557
|
+
"terminal.transcriptRow.output": "Output",
|
|
558
|
+
"terminal.transcriptRow.error": "Error",
|
|
559
|
+
"terminal.transcriptRow.exitCode": "Exit {code}",
|
|
560
|
+
// TerminalTodoList (#117 T5): the three-state checklist's announced word
|
|
561
|
+
// per row — the second, non-colour channel beside the ✔ / ◼ / ◻ glyph and
|
|
562
|
+
// the strikethrough/bold treatment. Wording verified 2026-09-01 against
|
|
563
|
+
// Claude Code v2.1.207's own upstream state words, parentheses included.
|
|
564
|
+
"terminal.todoList.done": "(completed)",
|
|
565
|
+
"terminal.todoList.active": "(in progress)",
|
|
566
|
+
"terminal.todoList.pending": "(pending)",
|
|
567
|
+
// TerminalEventLine (#117 T6): the lifecycle/hook event line. `outcome*` is
|
|
568
|
+
// the sr-only word beside the (always aria-hidden) StatusIcon glyph —
|
|
569
|
+
// never omitted for the default "ok" case, so "succeeded" is exactly as
|
|
570
|
+
// recoverable as "failed". `hooksTotal`/`hooksResult` are the terminal's
|
|
571
|
+
// own literal `[hooks: …]` bracket vocabulary, verified live 2026-09-01
|
|
572
|
+
// against Grok CLI v0.2.93; `hooksFailed` is the sr-only, count-aware
|
|
573
|
+
// "N hooks failed" that makes a partial hook failure (e.g. `3/1`) read as
|
|
574
|
+
// bad without relying on colour.
|
|
575
|
+
"terminal.eventLine.outcomeOk": "Succeeded",
|
|
576
|
+
"terminal.eventLine.outcomeBlocked": "Blocked",
|
|
577
|
+
"terminal.eventLine.outcomeFailed": "Failed",
|
|
578
|
+
"terminal.eventLine.phaseBefore": "Before",
|
|
579
|
+
"terminal.eventLine.phaseAfter": "After",
|
|
580
|
+
"terminal.eventLine.phaseLifecycle": "Lifecycle",
|
|
581
|
+
"terminal.eventLine.hooksTotal": "[hooks: {total}]",
|
|
582
|
+
"terminal.eventLine.hooksResult": "[hooks: {ran}/{passed}]",
|
|
583
|
+
"terminal.eventLine.hooksFailed": {
|
|
584
|
+
one: "{count} hook failed",
|
|
585
|
+
other: "{count} hooks failed",
|
|
586
|
+
},
|
|
587
|
+
// TerminalWorking (#117 T3): the in-turn footer's default label and its two
|
|
588
|
+
// icon-only controls' accessible names. No generic "stop"/"scroll to
|
|
589
|
+
// bottom" key exists yet (only the ai-namespaced `ai.promptInput.stop` /
|
|
590
|
+
// `ai.turnStatus.scrollToBottom`), so these are minted under the package's
|
|
591
|
+
// own namespace rather than borrowed cross-package.
|
|
592
|
+
"terminal.working.label": "Waiting for response…",
|
|
593
|
+
"terminal.working.stop": "Stop",
|
|
594
|
+
"terminal.working.scrollToBottom": "Scroll to bottom",
|
|
595
|
+
// TerminalStatusBar (#117 T4): the ambient chrome row's accessible name and
|
|
596
|
+
// the sr-only words beside its aria-hidden numerals/glyphs. Mirrors
|
|
597
|
+
// `ai.sessionStatusBar.connections`' wording under this package's own
|
|
598
|
+
// namespace (cannot import the `ai` key — sibling packages never import
|
|
599
|
+
// each other, `.claude/rules/terminal-components.md` § Reuse means
|
|
600
|
+
// promotion). `disconnected` and `stepsComplete` ("steps complete") are
|
|
601
|
+
// verified live 2026-09-01 against Grok CLI v0.2.93.
|
|
602
|
+
"terminal.statusBar.label": "Session status",
|
|
603
|
+
"terminal.statusBar.connecting": "Connecting…",
|
|
604
|
+
"terminal.statusBar.connections": "{connected} of {total} connections",
|
|
605
|
+
"terminal.statusBar.disconnected": "Disconnected",
|
|
606
|
+
"terminal.statusBar.context": "{used} of {limit} context used",
|
|
607
|
+
"terminal.statusBar.stepsComplete": "{current} of {total} steps complete",
|
|
608
|
+
// TerminalBanner (#117 T7): the launch card above an empty transcript.
|
|
609
|
+
// Mirrors `ai.sessionHeader.*`'s wording under this package's own
|
|
610
|
+
// namespace — sibling packages never import each other's locale keys
|
|
611
|
+
// (`.claude/rules/terminal-components.md` § Reuse means promotion).
|
|
612
|
+
"terminal.banner.capabilities": "Capabilities",
|
|
613
|
+
"terminal.banner.whatsNew": "What’s new",
|
|
614
|
+
"terminal.banner.quickActions": "Quick actions",
|
|
615
|
+
// TerminalToolCall (#117 T8): the tool-call row's status word (announced
|
|
616
|
+
// beside the glyph via TerminalRow's gutterLabel — never colour alone),
|
|
617
|
+
// the result row's swapped heading (mirrors ToolOutput's own "Result"/
|
|
618
|
+
// "Error" heading swap, `@elabs-ai/components-ai`), and the expand
|
|
619
|
+
// trigger's accessible name. Unlike upstream's inert `"(ctrl+o to
|
|
620
|
+
// expand)"` hint text, this IS a real focusable control's label — no CLI
|
|
621
|
+
// chord required.
|
|
622
|
+
"terminal.toolCall.succeeded": "Succeeded",
|
|
623
|
+
"terminal.toolCall.failed": "Failed",
|
|
624
|
+
"terminal.toolCall.running": "Running",
|
|
625
|
+
"terminal.toolCall.result": "Result",
|
|
626
|
+
"terminal.toolCall.error": "Error",
|
|
627
|
+
"terminal.toolCall.expandHint": "Show details",
|
|
628
|
+
// TerminalDiffHunk (#117 T9): the header's fixed "Update ({file})" phrase,
|
|
629
|
+
// and the collapsed-context-run disclosure's count-aware label. Mirrors
|
|
630
|
+
// `ai.diffView.showMore`'s wording under this package's own namespace —
|
|
631
|
+
// sibling packages never import each other's locale keys
|
|
632
|
+
// (`.claude/rules/terminal-components.md` § Reuse means promotion). The
|
|
633
|
+
// per-line `add`/`del` polarity words are NOT duplicated here: they ride
|
|
634
|
+
// the shared `diffLineAccessibleLabel()` keys (`ai.diffView.addedLine` /
|
|
635
|
+
// `ai.diffView.removedLine`) above, the actual promoted channel.
|
|
636
|
+
"terminal.diffHunk.header": "Update ({file})",
|
|
637
|
+
"terminal.diffHunk.showMore": {
|
|
638
|
+
one: "Show {count} more line",
|
|
639
|
+
other: "Show {count} more lines",
|
|
640
|
+
},
|
|
641
|
+
// TerminalPermission (#117 T10): the per-call scoped approval prompt's
|
|
642
|
+
// default title/question and its three scoped option labels, verified
|
|
643
|
+
// live 2026-09-01 against Claude Code v2.1.207. The third option is the
|
|
644
|
+
// vendor-free `deny` scope: upstream names its own product in this label,
|
|
645
|
+
// ours reads "the agent" instead (#117 acceptance criterion). The reason
|
|
646
|
+
// field reuses `ai.approvalCard.reasonLabel`/`reasonPlaceholder` and the
|
|
647
|
+
// option descriptions reuse `APPROVAL_SCOPE_DESCRIPTION_KEYS` — both
|
|
648
|
+
// already generic, so nothing new is minted for either.
|
|
649
|
+
"terminal.permission.title": "Bash command",
|
|
650
|
+
"terminal.permission.question": "Do you want to proceed?",
|
|
651
|
+
"terminal.permission.optionOnce": "Yes",
|
|
652
|
+
"terminal.permission.optionSession": "Yes, and don’t ask again this session",
|
|
653
|
+
"terminal.permission.optionDeny": "No, and tell the agent what to do differently",
|
|
654
|
+
// TerminalComposer (#117 T11): the prompt composer's placeholder, its
|
|
655
|
+
// merged submit/stop affordance's accessible name (mirrors
|
|
656
|
+
// `ai.promptInput.submit`/`stop` under this package's own namespace —
|
|
657
|
+
// sibling packages never import each other's locale keys,
|
|
658
|
+
// `.claude/rules/terminal-components.md` § Reuse means promotion), the
|
|
659
|
+
// effort scale's default accessible name, and the shortcut-hint row's
|
|
660
|
+
// three default words.
|
|
661
|
+
"terminal.composer.placeholder": "Type your next instruction…",
|
|
662
|
+
"terminal.composer.submit": "Send",
|
|
663
|
+
"terminal.composer.stop": "Stop",
|
|
664
|
+
"terminal.composer.effort": "Effort",
|
|
665
|
+
"terminal.composer.shortcutSend": "send",
|
|
666
|
+
"terminal.composer.shortcutNewline": "newline",
|
|
667
|
+
"terminal.composer.shortcutCancel": "cancel",
|
|
668
|
+
// TerminalSlashMenu (#117 T12): the `/`-command palette's listbox
|
|
669
|
+
// accessible name (mirrors `ai.promptInputSlash.listLabel`'s wording under
|
|
670
|
+
// this package's own namespace — sibling packages never import each
|
|
671
|
+
// other's locale keys, `.claude/rules/terminal-components.md` § Reuse
|
|
672
|
+
// means promotion). The empty state reuses the generic `noResults` key
|
|
673
|
+
// rather than minting a second one.
|
|
674
|
+
"terminal.slashMenu.listLabel": "Commands",
|
|
675
|
+
// ── @elabs-ai/components-process ──────────────────────────────────────────────────────────
|
|
676
|
+
// ProcessMap (RM-051). Namespaced `process.<area>.<key>` like every other
|
|
677
|
+
// package; a sibling package's keys are never reused across the boundary.
|
|
678
|
+
// The table twin's column headers are here because that table IS the
|
|
679
|
+
// accessible reading of the canvas — an untranslated header would leave a
|
|
680
|
+
// screen-reader user with numbers and no measure name.
|
|
681
|
+
"process.map.loading": "Discovering the process…",
|
|
682
|
+
"process.map.empty": "No activities to map",
|
|
683
|
+
"process.map.emptyBody":
|
|
684
|
+
"This log has no events, or the abstraction hid every activity. Widen the abstraction or load a different log.",
|
|
685
|
+
"process.map.label": "Process map",
|
|
686
|
+
"process.map.filter": "Filter…",
|
|
687
|
+
"process.map.activityCaption": "Activities — {metric} per activity",
|
|
688
|
+
"process.map.transitionCaption": "Transitions — {metric} per directly-follows pair",
|
|
689
|
+
"process.map.columnActivity": "Activity",
|
|
690
|
+
"process.map.columnRole": "Role",
|
|
691
|
+
"process.map.columnRework": "Rework",
|
|
692
|
+
"process.map.columnFrom": "From",
|
|
693
|
+
"process.map.columnTo": "To",
|
|
694
|
+
"process.map.columnShape": "Shape",
|
|
695
|
+
// State column (#373) — the table twin's own channel for the selection/filter state the
|
|
696
|
+
// canvas already says through real text in its accessible names; the twin used to carry
|
|
697
|
+
// it only as a `data-*` attribute, which reaches no user.
|
|
698
|
+
"process.map.columnState": "State",
|
|
699
|
+
// The State column's own CELL values (#413 review, PRRT_kwDOT6D7ts6gJX2C). #373 localized
|
|
700
|
+
// the column HEADER but left every cell printing the literal English word — since that cell
|
|
701
|
+
// is also the row's screen-reader channel for its selection/filter state
|
|
702
|
+
// (`selectionStateLabel` below is the un-localized canonical word `process-map.tsx` maps
|
|
703
|
+
// through these keys at the render site), a non-English `LocaleProvider` left both the
|
|
704
|
+
// visible AND the accessible content untranslated. `"associated"` (the ordinary case) has
|
|
705
|
+
// no key: it prints nothing, by design.
|
|
706
|
+
"process.map.stateSelected": "Selected",
|
|
707
|
+
"process.map.stateExcluded": "Excluded",
|
|
708
|
+
// Filter-intent menu item ACCESSIBLE names (#346). A transition's menu offers the same
|
|
709
|
+
// four intents once per endpoint (eight items total); the visible text
|
|
710
|
+
// (`PROCESS_FILTER_INTENT_LABELS` in map-model.ts) stays unsuffixed and compact, so these
|
|
711
|
+
// compose the activity into the item's real accessible name instead — the channel a
|
|
712
|
+
// screen-reader user actually hears, and the one the visible-only text left ambiguous.
|
|
713
|
+
"process.map.filterIntentWith": "Keep cases containing {activity}",
|
|
714
|
+
"process.map.filterIntentWithout": "Keep cases without {activity}",
|
|
715
|
+
"process.map.filterIntentStartsWith": "Keep cases starting with {activity}",
|
|
716
|
+
"process.map.filterIntentEndsWith": "Keep cases ending with {activity}",
|
|
717
|
+
// The map's own live-region summary (#375) — one polite `role="status"` announces what
|
|
718
|
+
// the active selection/filter just changed, mirroring `AbstractionControls`' hidden-count
|
|
719
|
+
// summary below: two independently-pluralized fragments, composed at the call site
|
|
720
|
+
// (`process-map.tsx`) rather than merged into one message, for the same reason.
|
|
721
|
+
"process.map.excludedActivities": {
|
|
722
|
+
one: "{count} of {total} activity excluded",
|
|
723
|
+
other: "{count} of {total} activities excluded",
|
|
724
|
+
},
|
|
725
|
+
"process.map.excludedTransitions": {
|
|
726
|
+
one: "{count} of {total} transition excluded",
|
|
727
|
+
other: "{count} of {total} transitions excluded",
|
|
728
|
+
},
|
|
729
|
+
// The live region's AFFECTED-SET fragments (#413 review, PRRT_kwDOT6D7ts6gJX2I). Counts
|
|
730
|
+
// alone are not enough: two selections/filters that exclude DIFFERENT elements but land on
|
|
731
|
+
// the SAME counts produce byte-for-byte identical text, so the polite region — which
|
|
732
|
+
// announces content CHANGES, not model changes — stays silent even though the map
|
|
733
|
+
// re-inked. Naming which elements are excluded makes the string track the actual set, not
|
|
734
|
+
// only its size. Composed at the call site alongside the two counts above, and omitted
|
|
735
|
+
// entirely when nothing of that kind is excluded (so the common case stays as short as
|
|
736
|
+
// before this fix).
|
|
737
|
+
"process.map.excludedActivityNames": "excluding {names}",
|
|
738
|
+
"process.map.excludedTransitionNames": "excluding {names}",
|
|
739
|
+
// AbstractionControls (RM-052, issue #227). The two sliders' own labels,
|
|
740
|
+
// the invert switch, the "Auto" heuristic button, and the hidden-count
|
|
741
|
+
// status line. `hiddenActivities`/`hiddenPaths` are separate `PluralMessage`s
|
|
742
|
+
// (not one combined key) because `t()` selects its plural category from a
|
|
743
|
+
// SINGLE `count` var — see `resolveMessage` in `locale-provider.tsx` — so
|
|
744
|
+
// the two independently-pluralizable counts are composed as two `t()` calls
|
|
745
|
+
// joined at the call site (`abstraction-controls.tsx`), not one key with two
|
|
746
|
+
// numbers.
|
|
747
|
+
"process.abstractionControls.label": "Abstraction",
|
|
748
|
+
"process.abstractionControls.activities": "Activities",
|
|
749
|
+
"process.abstractionControls.paths": "Paths",
|
|
750
|
+
"process.abstractionControls.invert": "Invert",
|
|
751
|
+
"process.abstractionControls.auto": "Auto",
|
|
752
|
+
"process.abstractionControls.hiddenActivities": {
|
|
753
|
+
one: "{count} activity hidden",
|
|
754
|
+
other: "{count} activities hidden",
|
|
755
|
+
},
|
|
756
|
+
"process.abstractionControls.hiddenPaths": {
|
|
757
|
+
one: "{count} path hidden",
|
|
758
|
+
other: "{count} paths hidden",
|
|
759
|
+
},
|
|
760
|
+
// MetricLayerSwitch (RM-052, issue #227). The Frequency/Performance/Rework
|
|
761
|
+
// toggle group, the node/edge metric selects' field labels, and the lock
|
|
762
|
+
// toggle's two accessible-name states. The per-VALUE metric labels
|
|
763
|
+
// ("Occurrences", "Share of transitions", …) are deliberately NOT
|
|
764
|
+
// duplicated here — they are read straight from `nodeMetricLabel`/
|
|
765
|
+
// `edgeMetricLabel` (`process-map/map-model.ts`), which already resolve
|
|
766
|
+
// each `ProcessMetric` to its correct, audience-specific text; see
|
|
767
|
+
// `metric-layer-switch.tsx`'s module docblock.
|
|
768
|
+
"process.metricLayerSwitch.label": "Metric",
|
|
769
|
+
"process.metricLayerSwitch.layer": "Metric layer",
|
|
770
|
+
"process.metricLayerSwitch.frequency": "Frequency",
|
|
771
|
+
"process.metricLayerSwitch.performance": "Performance",
|
|
772
|
+
"process.metricLayerSwitch.rework": "Rework",
|
|
773
|
+
"process.metricLayerSwitch.node": "Activity",
|
|
774
|
+
"process.metricLayerSwitch.edge": "Transition",
|
|
775
|
+
"process.metricLayerSwitch.lockOn": "Unlock activity and transition metrics",
|
|
776
|
+
"process.metricLayerSwitch.lockOff": "Lock activity and transition metrics together",
|
|
777
|
+
// ProcessKpiStrip (RM-052, issue #227). Six tiles' labels, plus the
|
|
778
|
+
// conformance tile's genuine "not available" state (no conformance model
|
|
779
|
+
// has run yet) — a real state, not a fabricated 0%.
|
|
780
|
+
"process.kpiStrip.cases": "Cases",
|
|
781
|
+
"process.kpiStrip.events": "Events",
|
|
782
|
+
"process.kpiStrip.variants": "Variants",
|
|
783
|
+
"process.kpiStrip.medianThroughput": "Median throughput",
|
|
784
|
+
"process.kpiStrip.reworkRate": "Rework rate",
|
|
785
|
+
"process.kpiStrip.conformance": "Conformance",
|
|
786
|
+
"process.kpiStrip.conformanceUnavailable": "Not available",
|
|
787
|
+
"process.kpiStrip.conformanceUnavailableHint": "Run conformance checking to see this metric.",
|
|
788
|
+
// Sparkline text alternative (#359). `Sparkline`'s own default alt text is more
|
|
789
|
+
// informative than the tile's own label — passing the label straight through
|
|
790
|
+
// overrode it and left a screen-reader user hearing the tile's name twice with no
|
|
791
|
+
// sense of the trend. `direction` is itself a resolved `t()` value (trendRising/
|
|
792
|
+
// Falling/Steady), composed into this template the same way `hiddenSummary`
|
|
793
|
+
// (abstraction-controls.tsx) composes two already-localized fragments.
|
|
794
|
+
"process.kpiStrip.trendAlt":
|
|
795
|
+
"{subject}, {periods}-period trend, {direction} from {first} to {last}",
|
|
796
|
+
"process.kpiStrip.trendRising": "rising",
|
|
797
|
+
"process.kpiStrip.trendFalling": "falling",
|
|
798
|
+
"process.kpiStrip.trendSteady": "steady",
|
|
300
799
|
};
|
|
@@ -25,6 +25,14 @@ import type { MentionOption, MentionValue } from "./mention-value";
|
|
|
25
25
|
* lock that only holds when it runs alone is not a lock at all in CI — so it
|
|
26
26
|
* gets its own story file, which the runner loads as its own test file.
|
|
27
27
|
*
|
|
28
|
+
* It shares the `Forms/MentionInput` TITLE with the main story file so it reads
|
|
29
|
+
* as one sidebar entry rather than a sub-group of its own (RM-005). That is a
|
|
30
|
+
* sidebar concern only: `@storybook/addon-vitest` turns each story FILE into its
|
|
31
|
+
* own test file, so the isolation above survives the shared title. Do NOT
|
|
32
|
+
* "finish the job" by moving these stories into `mention-input.stories.tsx` —
|
|
33
|
+
* that is the exact co-residency the audit measured as green-with-the-bug (ADR
|
|
34
|
+
* 0023 §6).
|
|
35
|
+
*
|
|
28
36
|
* ### What it pins
|
|
29
37
|
*
|
|
30
38
|
* Every box-affecting property of the field is nailed to absolute pixels, so
|
|
@@ -39,7 +47,7 @@ import type { MentionOption, MentionValue } from "./mention-value";
|
|
|
39
47
|
* the test rather than argued for in a comment.
|
|
40
48
|
*/
|
|
41
49
|
const meta = {
|
|
42
|
-
title: "Forms/MentionInput
|
|
50
|
+
title: "Forms/MentionInput",
|
|
43
51
|
component: MentionInput,
|
|
44
52
|
parameters: {
|
|
45
53
|
docs: {
|