@elabs-ai/components-ui 4.0.0 → 4.2.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-FCH4ZN6G.js +57 -0
- package/dist/chunk-FCH4ZN6G.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 +2597 -188
- package/dist/index.js +12855 -3578
- package/dist/index.js.map +1 -1
- package/dist/lib/cn.js +10 -1
- package/dist/lib/cn.js.map +1 -1
- package/package.json +21 -7
- package/src/__contract__/attribution-panel.contract.test.tsx +49 -0
- package/src/__contract__/badge.contract.test.tsx +49 -0
- package/src/__contract__/bounded-number.contract.test.tsx +49 -0
- package/src/__contract__/button.contract.test.tsx +49 -0
- package/src/__contract__/color-picker.contract.test.tsx +49 -0
- package/src/__contract__/combobox.contract.test.tsx +49 -0
- package/src/__contract__/command-trigger.contract.test.tsx +49 -0
- package/src/__contract__/copyable-value.contract.test.tsx +49 -0
- package/src/__contract__/date-picker.contract.test.tsx +49 -0
- package/src/__contract__/date-range-picker.contract.test.tsx +49 -0
- package/src/__contract__/empty-state.contract.test.tsx +49 -0
- package/src/__contract__/error-state.contract.test.tsx +49 -0
- package/src/__contract__/icon-button.contract.test.tsx +49 -0
- package/src/__contract__/input.contract.test.tsx +49 -0
- package/src/__contract__/key-value-editor.contract.test.tsx +49 -0
- package/src/__contract__/list-editor.contract.test.tsx +49 -0
- package/src/__contract__/loading-state.contract.test.tsx +49 -0
- package/src/__contract__/metric-card.contract.test.tsx +49 -0
- package/src/__contract__/model-picker.contract.test.tsx +49 -0
- package/src/__contract__/nav-notifications.contract.test.tsx +49 -0
- package/src/__contract__/number-input.contract.test.tsx +49 -0
- package/src/__contract__/rating.contract.test.tsx +49 -0
- package/src/__contract__/schema-form.contract.test.tsx +49 -0
- package/src/__contract__/section-header.contract.test.tsx +49 -0
- package/src/__contract__/segmented-field.contract.test.tsx +49 -0
- package/src/__contract__/slider-number.contract.test.tsx +49 -0
- package/src/__contract__/status-badge.contract.test.tsx +49 -0
- package/src/__contract__/tag-input.contract.test.tsx +49 -0
- package/src/__contract__/text.contract.test.tsx +49 -0
- package/src/__contract__/textarea.contract.test.tsx +49 -0
- package/src/__contract__/timeline.contract.test.tsx +49 -0
- package/src/__contract__/toggle.contract.test.tsx +49 -0
- package/src/__contract__/transfer.contract.test.tsx +49 -0
- package/src/__contract__/tree-select.contract.test.tsx +49 -0
- package/src/__contract__/tree.contract.test.tsx +49 -0
- package/src/__contract__/virtual-select.contract.test.tsx +49 -0
- package/src/__contract__/workspace-picker.contract.test.tsx +49 -0
- package/src/_peer-deps.test.ts +59 -0
- package/src/blocks-comparison-table.stories.tsx +2 -2
- package/src/components/accordion/accordion.tsx +13 -4
- package/src/components/advanced-group/advanced-group.tsx +1 -1
- package/src/components/alert/alert.tsx +15 -4
- package/src/components/alert-dialog/alert-dialog.test.tsx +32 -0
- package/src/components/alert-dialog/alert-dialog.tsx +28 -6
- package/src/components/app-shell/app-shell.stories.tsx +44 -2
- package/src/components/app-shell/app-shell.test.tsx +99 -0
- package/src/components/app-shell/app-shell.tsx +56 -4
- package/src/components/app-sidebar/app-sidebar.stories.tsx +9 -1
- package/src/components/attribution-panel/attribution-panel.tsx +3 -1
- package/src/components/attribution-panel/attributions.generated.ts +83 -79
- package/src/components/avatar/avatar.tsx +4 -1
- package/src/components/badge/badge.stories.tsx +8 -0
- package/src/components/badge/badge.test.tsx +8 -0
- package/src/components/badge/badge.tsx +15 -5
- package/src/components/bento-grid/bento-grid.test.tsx +24 -3
- package/src/components/bento-grid/bento-grid.tsx +11 -1
- package/src/components/bounded-number/bounded-number.test.tsx +1 -1
- package/src/components/bounded-number/bounded-number.tsx +78 -75
- package/src/components/breadcrumb/breadcrumb.stories.tsx +38 -0
- package/src/components/breadcrumb/breadcrumb.test.tsx +24 -1
- package/src/components/breadcrumb/breadcrumb.tsx +10 -4
- package/src/components/button/button.stories.tsx +116 -8
- package/src/components/button/button.tsx +18 -12
- package/src/components/button-group/button-group.tsx +1 -1
- package/src/components/calendar/calendar.tsx +3 -2
- package/src/components/card/card.stories.tsx +11 -6
- package/src/components/card/card.test.tsx +24 -2
- package/src/components/card/card.tsx +48 -7
- package/src/components/carousel/carousel.test.tsx +169 -0
- package/src/components/carousel/carousel.tsx +93 -32
- 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 +214 -24
- package/src/components/checkbox/checkbox.tsx +2 -1
- package/src/components/collapsible-panel/use-collapsible-panel.ts +0 -3
- package/src/components/color-picker/color-picker.tsx +22 -15
- package/src/components/combobox/combobox.stories.tsx +10 -0
- package/src/components/combobox/combobox.test.tsx +54 -0
- package/src/components/combobox/combobox.tsx +25 -11
- package/src/components/command/command.stories.tsx +16 -6
- package/src/components/command/command.test.tsx +88 -0
- package/src/components/command/command.tsx +38 -13
- 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-menu/context-menu.tsx +16 -7
- 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.stories.tsx +10 -0
- package/src/components/copyable-value/copyable-value.test.tsx +28 -1
- package/src/components/copyable-value/copyable-value.tsx +13 -2
- package/src/components/date-picker/date-picker.stories.tsx +9 -0
- package/src/components/date-picker/date-picker.test.tsx +52 -0
- package/src/components/date-picker/date-picker.tsx +13 -15
- package/src/components/date-range-picker/date-range-picker.stories.tsx +9 -0
- package/src/components/date-range-picker/date-range-picker.test.tsx +76 -1
- package/src/components/date-range-picker/date-range-picker.tsx +39 -28
- package/src/components/descriptions/descriptions.tsx +1 -1
- package/src/components/dialog/dialog.test.tsx +8 -3
- package/src/components/dialog/dialog.tsx +14 -6
- package/src/components/drawer/drawer.tsx +23 -6
- package/src/components/dropdown-menu/dropdown-menu.stories.tsx +1 -1
- package/src/components/dropdown-menu/dropdown-menu.tsx +4 -4
- 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 +342 -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 +50 -6
- package/src/components/file-upload/file-upload.stories.tsx +16 -0
- package/src/components/file-upload/file-upload.test.tsx +90 -12
- package/src/components/file-upload/file-upload.tsx +164 -31
- package/src/components/form/form.tsx +8 -3
- package/src/components/hover-card/hover-card.tsx +1 -0
- package/src/components/icon-button/icon-button.test.tsx +1 -1
- package/src/components/icon-button/icon-button.tsx +3 -3
- package/src/components/input/input.stories.tsx +121 -0
- package/src/components/input/input.test.tsx +13 -0
- package/src/components/input/input.tsx +8 -4
- package/src/components/input-group/input-group.stories.tsx +74 -0
- package/src/components/input-group/input-group.tsx +18 -9
- package/src/components/input-otp/input-otp.tsx +8 -2
- 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/label/label.tsx +1 -1
- package/src/components/link-preview/link-preview.tsx +1 -1
- package/src/components/list-editor/list-editor.test.tsx +24 -0
- package/src/components/list-editor/list-editor.tsx +126 -52
- package/src/components/locale-provider/index.ts +6 -1
- package/src/components/locale-provider/locale-keys.test.ts +134 -0
- 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 +822 -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.stories.tsx +3 -3
- package/src/components/mention-input/mention-input.test.tsx +51 -1
- package/src/components/mention-input/mention-input.tsx +66 -46
- package/src/components/mention-input/mention-value.ts +8 -2
- package/src/components/menubar/menubar.tsx +16 -6
- 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 +8 -4
- package/src/components/nav-notifications/nav-notifications.stories.tsx +110 -0
- package/src/components/nav-notifications/nav-notifications.test.tsx +11 -0
- package/src/components/nav-notifications/nav-notifications.tsx +67 -9
- package/src/components/nav-user/nav-user.tsx +5 -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 +204 -15
- package/src/components/number-input/number-input.stories.tsx +7 -3
- package/src/components/number-input/number-input.test.tsx +47 -0
- package/src/components/number-input/number-input.tsx +65 -24
- 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 +109 -0
- package/src/components/pagination/pagination.tsx +27 -19
- package/src/components/popover/popover.tsx +1 -0
- package/src/components/progress/progress.tsx +2 -0
- package/src/components/radio-group/radio-group.tsx +1 -1
- package/src/components/rating/rating.tsx +3 -1
- package/src/components/resizable/resizable.stories.tsx +114 -2
- package/src/components/resizable/resizable.test.tsx +76 -0
- package/src/components/resizable/resizable.tsx +32 -6
- 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 +53 -5
- 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-store.ts +506 -0
- package/src/components/schema-form/schema-form.stories.tsx +566 -0
- package/src/components/schema-form/schema-form.test.tsx +1021 -0
- package/src/components/schema-form/schema-form.tsx +1381 -0
- package/src/components/section-header/section-header.stories.tsx +37 -0
- package/src/components/section-header/section-header.tsx +14 -3
- package/src/components/select/select.tsx +13 -7
- package/src/components/separator/separator.tsx +1 -0
- package/src/components/sheet/sheet.test.tsx +39 -0
- package/src/components/sheet/sheet.tsx +40 -9
- 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 +299 -0
- package/src/components/side-dock/side-dock.tsx +515 -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 +71 -2
- package/src/components/sidebar/sidebar.tsx +264 -38
- package/src/components/skeleton/skeleton.tsx +1 -0
- 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/slider-number/slider-number.stories.tsx +4 -1
- package/src/components/slider-number/slider-number.test.tsx +1 -1
- package/src/components/sonner/sonner.tsx +2 -0
- package/src/components/spinner/spinner.test.tsx +18 -0
- package/src/components/spinner/spinner.tsx +14 -4
- 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 +110 -24
- package/src/components/status-badge/status-badge.stories.tsx +8 -0
- package/src/components/switch/switch.tsx +3 -1
- package/src/components/table/table.stories.tsx +64 -0
- package/src/components/table/table.test.tsx +149 -1
- package/src/components/table/table.tsx +71 -2
- package/src/components/tabs/index.ts +10 -1
- package/src/components/tabs/tabs.stories.tsx +48 -0
- package/src/components/tabs/tabs.test.tsx +67 -0
- package/src/components/tabs/tabs.tsx +176 -72
- package/src/components/tag-input/tag-input.tsx +6 -3
- package/src/components/team-switcher/team-switcher.tsx +35 -6
- package/src/components/textarea/textarea.tsx +2 -2
- package/src/components/theme-switcher/theme-switcher.stories.tsx +76 -0
- package/src/components/theme-switcher/theme-switcher.test.tsx +182 -0
- package/src/components/theme-switcher/theme-switcher.tsx +140 -12
- 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 +10 -3
- package/src/components/toggle/toggle.tsx +7 -2
- package/src/components/toggle-group/toggle-group.tsx +2 -0
- package/src/components/toolbar/toolbar.stories.tsx +10 -2
- package/src/components/tooltip/tooltip.tsx +2 -1
- package/src/components/top-nav/top-nav.tsx +1 -1
- package/src/components/transfer/transfer.tsx +35 -30
- package/src/components/tree/tree.stories.tsx +2 -2
- package/src/components/tree/tree.test.tsx +41 -0
- package/src/components/tree/tree.tsx +91 -31
- package/src/components/tree/use-tree-keyboard.ts +37 -14
- package/src/components/tree-select/tree-select.stories.tsx +9 -0
- package/src/components/tree-select/tree-select.test.tsx +5 -0
- package/src/components/tree-select/tree-select.tsx +11 -14
- package/src/components/typography/prose.test.tsx +3 -2
- package/src/components/typography/prose.tsx +3 -3
- 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.stories.tsx +9 -0
- package/src/components/virtual-select/virtual-select.test.tsx +29 -3
- package/src/components/virtual-select/virtual-select.tsx +56 -18
- package/src/components/wizard/wizard.test.tsx +9 -0
- package/src/components/wizard/wizard.tsx +13 -5
- 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 +80 -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/cn.ts +9 -0
- package/src/lib/csv.ts +48 -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 +94 -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/merge-refs.ts +2 -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-controllable-state.ts +47 -0
- package/src/lib/use-mobile.test.tsx +47 -0
- package/src/lib/use-mobile.ts +34 -12
- 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,10 +28,11 @@
|
|
|
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",
|
|
35
|
+
clear: "Clear",
|
|
14
36
|
previous: "Previous",
|
|
15
37
|
next: "Next",
|
|
16
38
|
previousSlide: "Previous slide",
|
|
@@ -20,6 +42,11 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
20
42
|
loading: "Loading…",
|
|
21
43
|
more: "More",
|
|
22
44
|
selectAll: "Select all",
|
|
45
|
+
// Cardinal-plural example (#19) — a shared "N item(s) selected" microcopy
|
|
46
|
+
// any multi-select surface can reuse via `t("itemsSelected", { count })`.
|
|
47
|
+
// Demonstrates the plural-form shape: pick the primitive over inventing a
|
|
48
|
+
// near-duplicate flat string per component.
|
|
49
|
+
itemsSelected: { one: "{count} item selected", other: "{count} items selected" },
|
|
23
50
|
|
|
24
51
|
// ── @elabs-ai/components-ui ───────────────────────────────────────────────────────────────
|
|
25
52
|
"ui.metricCard.loading": "Loading metric…",
|
|
@@ -43,6 +70,24 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
43
70
|
"ui.modelPicker.loadFailed": "Couldn't load the list",
|
|
44
71
|
"ui.modelPicker.nothingYet": "Nothing to show yet",
|
|
45
72
|
"ui.modelPicker.retry": "Retry",
|
|
73
|
+
// KeyboardShortcuts (#113). `emptyFiltered` keeps the user's own query in the
|
|
74
|
+
// sentence so the empty state says WHY it is empty, not merely that it is.
|
|
75
|
+
"ui.keyboardShortcuts.searchPlaceholder": "Search shortcuts…",
|
|
76
|
+
"ui.keyboardShortcuts.emptyTitle": "No shortcuts found",
|
|
77
|
+
"ui.keyboardShortcuts.emptyFiltered": "No shortcuts match “{query}”.",
|
|
78
|
+
"ui.keyboardShortcuts.empty": "No shortcuts to show.",
|
|
79
|
+
// WorkspacePicker (#111). It composes ModelPicker, so it carries its OWN
|
|
80
|
+
// label/search strings rather than inheriting the generic "Choose a target".
|
|
81
|
+
// `current` is appended into the row's meta so the in-force workspace reaches
|
|
82
|
+
// the option's accessible name as a WORD, not only a check glyph (1.4.1).
|
|
83
|
+
"ui.workspacePicker.label": "Choose a workspace",
|
|
84
|
+
"ui.workspacePicker.placeholder": "No workspace selected",
|
|
85
|
+
"ui.workspacePicker.recent": "Recent workspaces",
|
|
86
|
+
"ui.workspacePicker.searchPlaceholder": "Search workspaces…",
|
|
87
|
+
"ui.workspacePicker.current": "Current",
|
|
88
|
+
"ui.workspacePicker.pathLabel": "Workspace path",
|
|
89
|
+
"ui.workspacePicker.pathPlaceholder": "/path/to/project…",
|
|
90
|
+
"ui.workspacePicker.openPath": "Open",
|
|
46
91
|
// ViewToolbar (#331). `removeFilter` deliberately WRAPS the visible chip text
|
|
47
92
|
// so the accessible name contains it (WCAG 2.5.3 Label in Name).
|
|
48
93
|
"ui.viewToolbar.about": "About this view",
|
|
@@ -81,14 +126,212 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
81
126
|
"ui.confirmDialog.cancel": "Cancel",
|
|
82
127
|
"ui.advancedGroup.title": "Advanced",
|
|
83
128
|
"ui.advancedGroup.changed": "{count} changed",
|
|
129
|
+
// SchemaForm — the spec-driven config-form renderer (issue #22).
|
|
130
|
+
"ui.schemaForm.selectPlaceholder": "Select…",
|
|
131
|
+
"ui.schemaForm.label": "Form",
|
|
132
|
+
"ui.schemaForm.submit": "Submit",
|
|
133
|
+
"ui.schemaForm.submitting": "Submitting…",
|
|
134
|
+
"ui.schemaForm.submitted": "Submitted",
|
|
135
|
+
// SchemaFormTestAction — a form/group-level "Test connection" affordance
|
|
136
|
+
// (issue #22 maintainer ruling, 2026-09-01), independent of field validity
|
|
137
|
+
// and never gating submit.
|
|
138
|
+
"ui.schemaForm.testAction.label": "Test connection",
|
|
139
|
+
"ui.schemaForm.testAction.pending": "Testing…",
|
|
140
|
+
"ui.schemaForm.testAction.success": "Connected",
|
|
141
|
+
"ui.schemaForm.testAction.failure": "Test failed",
|
|
142
|
+
// Pagination's ellipsis (sr-only — the visible glyph is decorative).
|
|
143
|
+
"ui.breadcrumb.label": "breadcrumb",
|
|
144
|
+
"ui.pagination.label": "pagination",
|
|
145
|
+
"ui.pagination.morePages": "More pages",
|
|
146
|
+
// Pagination's prev/next links — the ACCESSIBLE NAME (`aria-label`), distinct
|
|
147
|
+
// from the visible `previous`/`next` text below it: an `aria-label` overrides
|
|
148
|
+
// visible text content as the accessible name, so leaving these hardcoded in
|
|
149
|
+
// English meant a non-English `LocaleProvider` translated the visible label
|
|
150
|
+
// but a screen-reader user still heard English (#12/#53 review, P2).
|
|
151
|
+
"ui.pagination.previous": "Go to previous page",
|
|
152
|
+
"ui.pagination.next": "Go to next page",
|
|
153
|
+
// Sidebar's mobile Sheet title (sr-only header — the sheet itself has no
|
|
154
|
+
// visible chrome, so this is only ever read by assistive tech).
|
|
155
|
+
"ui.sidebar.title": "Sidebar",
|
|
156
|
+
// ContextRail's switcher count phrase (composed into the accessible name,
|
|
157
|
+
// e.g. "Sources 3 items") and its default empty-state copy.
|
|
158
|
+
"ui.contextRail.sectionCount": { one: "{count} item", other: "{count} items" },
|
|
159
|
+
"ui.contextRail.empty": "No sections",
|
|
160
|
+
// SideDock's resize handle — its sr-only label and its live width readout.
|
|
161
|
+
"ui.sideDock.resize": "Resize",
|
|
162
|
+
"ui.sideDock.widthValue": { one: "{size} pixel", other: "{size} pixels" },
|
|
163
|
+
// Tree's error row — shared by the virtualized and non-virtualized branches.
|
|
164
|
+
"ui.tree.failedToLoad": "Failed to load",
|
|
165
|
+
// ThemeSwitcher's "follow the OS" option, in both dropdown and toggle modes.
|
|
166
|
+
"ui.themeSwitcher.system": "System",
|
|
167
|
+
// Group labels + scheme names in the family layout (ADR 0036).
|
|
168
|
+
"ui.themeSwitcher.theme": "Theme",
|
|
169
|
+
"ui.themeSwitcher.mode": "Mode",
|
|
170
|
+
"ui.themeSwitcher.light": "Light",
|
|
171
|
+
"ui.themeSwitcher.dark": "Dark",
|
|
172
|
+
"ui.navNotifications.label": "Notifications",
|
|
173
|
+
"ui.teamSwitcher.label": "Teams",
|
|
174
|
+
"ui.teamSwitcher.addTeam": "Add team",
|
|
175
|
+
// Table's own scroll wrapper (#366). Rendered ONLY when the wrapper actually
|
|
176
|
+
// overflows, so it is never announced for a table that fits — see
|
|
177
|
+
// `packages/ui/src/components/table/table.tsx`. Deliberately a `ui.*`
|
|
178
|
+
// sibling of `data.table.scrollRegion` rather than a shared cross-package
|
|
179
|
+
// key: `Table` is a `@elabs-ai/components-ui` component and each package
|
|
180
|
+
// keeps its own namespace even where the English string coincides (compare
|
|
181
|
+
// `viewer.content` vs this), so a translator can phrase either
|
|
182
|
+
// independently and neither package depends on a string owned by another.
|
|
183
|
+
"ui.table.scrollRegion": "Table contents, scrollable",
|
|
184
|
+
// NumberInput's step buttons (#4 i18n sweep).
|
|
185
|
+
"ui.numberInput.decrease": "Decrease",
|
|
186
|
+
"ui.numberInput.increase": "Increase",
|
|
187
|
+
// Combobox/VirtualSelect/TreeSelect each keep their own placeholder pair
|
|
188
|
+
// (English text coincides, but a translator may phrase a search box
|
|
189
|
+
// differently per surface — same rationale as `ui.table.scrollRegion`).
|
|
190
|
+
"ui.combobox.placeholder": "Select…",
|
|
191
|
+
"ui.combobox.searchPlaceholder": "Search…",
|
|
192
|
+
"ui.virtualSelect.placeholder": "Select…",
|
|
193
|
+
"ui.virtualSelect.searchPlaceholder": "Search…",
|
|
194
|
+
"ui.treeSelect.placeholder": "Select…",
|
|
195
|
+
"ui.treeSelect.moreSelected": "and {count} more selected",
|
|
196
|
+
"ui.fileUpload.selectedFiles": "Selected files",
|
|
197
|
+
"ui.fileUpload.dragDropHere": "Drag & drop files here",
|
|
198
|
+
"ui.fileUpload.browseFiles": "Browse files",
|
|
199
|
+
// Sidebar's mobile Sheet description (sr-only) and the collapse/expand
|
|
200
|
+
// trigger's shared name (SidebarTrigger's sr-only text + SidebarRail's
|
|
201
|
+
// aria-label/title).
|
|
202
|
+
"ui.sidebar.mobileDescription": "Displays the mobile sidebar.",
|
|
203
|
+
"ui.sidebar.toggle": "Toggle Sidebar",
|
|
204
|
+
"ui.revisionTimeline.label": "Revisions",
|
|
205
|
+
"ui.tree.retry": "Retry",
|
|
206
|
+
"ui.tree.retryLoadingChildren": "Retry loading children",
|
|
207
|
+
// Spinner's bare default label — kept WITHOUT an ellipsis (unlike the
|
|
208
|
+
// generic `loading` key) to stay byte-identical to its pre-i18n default.
|
|
209
|
+
"ui.spinner.label": "Loading",
|
|
210
|
+
"ui.statePanel.errorTitle": "Something went wrong",
|
|
211
|
+
"ui.statePanel.errorDescription": "An unexpected error occurred. Please try again.",
|
|
212
|
+
"ui.statePanel.errorEyebrow": "Error",
|
|
213
|
+
"ui.carousel.label": "Carousel",
|
|
214
|
+
// Transfer (#4 i18n sweep). `panelFallback`/`itemsFallback` back the two
|
|
215
|
+
// spots where the panel title isn't a plain string (a ReactNode) and the
|
|
216
|
+
// sr-only text falls back to a generic word instead.
|
|
217
|
+
"ui.transfer.selectAllIn": "Select all in {title}",
|
|
218
|
+
"ui.transfer.panelFallback": "panel",
|
|
219
|
+
"ui.transfer.searchIn": "Search {title}",
|
|
220
|
+
"ui.transfer.itemsFallback": "items",
|
|
221
|
+
"ui.transfer.searchPlaceholder": "Search…",
|
|
222
|
+
"ui.transfer.empty": "No items",
|
|
223
|
+
"ui.transfer.defaultSourceTitle": "Source",
|
|
224
|
+
"ui.transfer.defaultTargetTitle": "Target",
|
|
225
|
+
"ui.transfer.movedToTarget": {
|
|
226
|
+
one: "{count} item moved to the target list.",
|
|
227
|
+
other: "{count} items moved to the target list.",
|
|
228
|
+
},
|
|
229
|
+
"ui.transfer.movedToSource": {
|
|
230
|
+
one: "{count} item moved to the source list.",
|
|
231
|
+
other: "{count} items moved to the source list.",
|
|
232
|
+
},
|
|
233
|
+
"ui.transfer.moveControls": "Move controls",
|
|
234
|
+
"ui.transfer.moveSelectedRight": "Move selected right",
|
|
235
|
+
"ui.transfer.moveAllRight": "Move all right",
|
|
236
|
+
"ui.transfer.moveSelectedLeft": "Move selected left",
|
|
237
|
+
"ui.transfer.moveAllLeft": "Move all left",
|
|
238
|
+
// ChangeReview (#4 i18n sweep).
|
|
239
|
+
"ui.changeReview.heading": "Review changes",
|
|
240
|
+
"ui.changeReview.approvedCount": "{approved} of {total} approved",
|
|
241
|
+
"ui.changeReview.rejectAll": "Reject all",
|
|
242
|
+
"ui.changeReview.rejectAllLabel": "Reject all changes",
|
|
243
|
+
"ui.changeReview.approveAll": "Approve all",
|
|
244
|
+
"ui.changeReview.approveAllLabel": "Approve all changes",
|
|
245
|
+
"ui.changeReview.provenanceLabel": "Change provenance",
|
|
246
|
+
"ui.changeReview.emptyTitle": "No changes to review",
|
|
247
|
+
"ui.changeReview.emptyDescription":
|
|
248
|
+
"When an agent proposes edits, they'll appear here for your approval.",
|
|
249
|
+
"ui.changeReview.statusAdded": "added",
|
|
250
|
+
"ui.changeReview.statusRemoved": "removed",
|
|
251
|
+
"ui.changeReview.statusModified": "modified",
|
|
252
|
+
"ui.changeReview.phaseBefore": "Before",
|
|
253
|
+
"ui.changeReview.phaseAfter": "After",
|
|
254
|
+
"ui.changeReview.checkPassed": "Passed",
|
|
255
|
+
"ui.changeReview.checkFailed": "Failed",
|
|
256
|
+
"ui.changeReview.showDetail": "Show detail",
|
|
257
|
+
"ui.changeReview.hideDetail": "Hide detail",
|
|
258
|
+
"ui.changeReview.rejectHunk": "Reject hunk: {title}",
|
|
259
|
+
"ui.changeReview.approveHunk": "Approve hunk: {title}",
|
|
260
|
+
"ui.changeReview.changeType": "Change type: {status}",
|
|
261
|
+
"ui.changeReview.beforePrefix": "Before: ",
|
|
262
|
+
"ui.changeReview.afterPrefix": "After: ",
|
|
263
|
+
"ui.changeReview.approvedBadge": "Approved",
|
|
264
|
+
"ui.navNotifications.trigger": "Open notifications",
|
|
265
|
+
"ui.colorPicker.pickColor": "Pick color",
|
|
266
|
+
"ui.colorPicker.none": "None",
|
|
267
|
+
"ui.colorPicker.swatches": "Color swatches",
|
|
268
|
+
"ui.colorPicker.customHexLabel": "Custom hex",
|
|
269
|
+
"ui.colorPicker.notThemeAware": "(not theme-aware)",
|
|
270
|
+
"ui.colorPicker.customHex": "Custom hex color",
|
|
84
271
|
|
|
85
272
|
// ── @elabs-ai/components-data ─────────────────────────────────────────────────────────────
|
|
86
273
|
// The scroll region's accessible name is rendered ONLY when the table actually
|
|
87
274
|
// overflows its container, so it is never announced for a table that fits.
|
|
88
275
|
"data.table.scrollRegion": "Table contents, scrollable",
|
|
276
|
+
"data.table.loading": "Loading table data…",
|
|
89
277
|
// Fallback name for a row's activation control when the row's first cell holds
|
|
90
278
|
// no primitive value to name it after (see `rowActionLabel`).
|
|
91
279
|
"data.table.rowAction": "Activate row",
|
|
280
|
+
// createSelectionColumn (#11) — the header select-all checkbox and each row's
|
|
281
|
+
// own checkbox. Kept table-scoped (not the generic `selectAll` key) so a
|
|
282
|
+
// translator can phrase "rows" distinctly from other bulk-select surfaces.
|
|
283
|
+
"data.table.selectAllRows": "Select all rows",
|
|
284
|
+
// `selectRowNamed` names each row's checkbox from its own first data column
|
|
285
|
+
// (#11 I4) so screen-reader users hear "Select Alpha", not `selectRow`'s
|
|
286
|
+
// identical generic label repeated on every row; `selectRow` stays the
|
|
287
|
+
// fallback when no data column value is derivable.
|
|
288
|
+
"data.table.selectRowNamed": "Select {name}",
|
|
289
|
+
"data.table.selectRow": "Select row",
|
|
290
|
+
// Column resizing (#12) — the accessible name for the WAI-ARIA
|
|
291
|
+
// separator-as-slider resize handle at the end of a resizable header cell.
|
|
292
|
+
"data.table.resizeColumn": "Resize column, {name}",
|
|
293
|
+
// #51 — the handle's accessible VALUE, paired with aria-valuenow (which
|
|
294
|
+
// stays a plain number for AT/TanStack). A bare number reads as a
|
|
295
|
+
// dimensionless ordinal; the unit makes it a size. A `PluralMessage` (PR
|
|
296
|
+
// #81 review, "Format the announced resize value for the active locale") —
|
|
297
|
+
// the call site passes both `count` (the raw number, so a locale whose
|
|
298
|
+
// plural rules select something other than "other" for a given size is
|
|
299
|
+
// reachable) and `size` (pre-formatted via `formatNumber`, so a locale
|
|
300
|
+
// override renders locale-appropriate digits/grouping instead of a raw
|
|
301
|
+
// Latin-digit JS number).
|
|
302
|
+
"data.table.resizeColumnValue": { one: "{size} pixel", other: "{size} pixels" },
|
|
303
|
+
// Row drag-reorder (#13). `reorderHandle`/`reorderColumnHeader` name the
|
|
304
|
+
// grip control and its column; the four `reorder*` announcement keys back
|
|
305
|
+
// the aria-live region dnd-kit's `accessibility.announcements` renders on
|
|
306
|
+
// pickup/move/drop/cancel (WCAG 4.1.3) — `position`/`total` are 1-based so
|
|
307
|
+
// the announcement reads like "3 of 8", not a 0-based index.
|
|
308
|
+
"data.table.reorderColumnHeader": "Reorder",
|
|
309
|
+
"data.table.reorderHandle": "Reorder {name}",
|
|
310
|
+
"data.table.reorderPickedUp": "Picked up {name}.",
|
|
311
|
+
"data.table.reorderMoved": "{name} moved to position {position} of {total}.",
|
|
312
|
+
"data.table.reorderDropped": "{name} dropped at position {position} of {total}.",
|
|
313
|
+
"data.table.reorderCancelled":
|
|
314
|
+
"Reordering cancelled. {name} returned to position {position} of {total}.",
|
|
315
|
+
// #98: `@dnd-kit` renders two more AT-visible strings for this same
|
|
316
|
+
// feature that this repo's source never writes — the hidden keyboard
|
|
317
|
+
// usage instructions (wired to the grip via `aria-describedby`) and the
|
|
318
|
+
// activator's `aria-roledescription`. Both ship a hardcoded English
|
|
319
|
+
// default deep inside the library; localizing them means overriding them
|
|
320
|
+
// explicitly with these two keys. The English DEFAULT below is dnd-kit's
|
|
321
|
+
// own default text verbatim (`defaultScreenReaderInstructions.draggable`
|
|
322
|
+
// in `@dnd-kit/core`, and `useSortable`'s `roleDescription: 'sortable'` in
|
|
323
|
+
// `@dnd-kit/sortable`) — not a rewrite — so an English consumer with no
|
|
324
|
+
// `LocaleProvider` override sees byte-identical output to before this
|
|
325
|
+
// fix; only a `messages` override changes it.
|
|
326
|
+
"data.table.reorderInstructions":
|
|
327
|
+
"\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 ",
|
|
328
|
+
"data.table.reorderRoleDescription": "sortable",
|
|
329
|
+
"data.facetFilter.clearFilters": "Clear filters",
|
|
330
|
+
"data.columnPicker.toggleColumns": "Toggle columns",
|
|
331
|
+
"data.columnPicker.label": "Columns",
|
|
332
|
+
"data.searchInput.label": "Search",
|
|
333
|
+
"data.searchInput.placeholder": "Search…",
|
|
334
|
+
"data.searchInput.clear": "Clear search",
|
|
92
335
|
|
|
93
336
|
// ── @elabs-ai/components-charts ───────────────────────────────────────────────────────────
|
|
94
337
|
// Shared caption for any bare chart surface's layout-shaped skeleton
|
|
@@ -105,6 +348,49 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
105
348
|
// Announced when `copyValueOnActivate` puts a datapoint's exact value on the
|
|
106
349
|
// clipboard — the recovery path for a compact axis label.
|
|
107
350
|
"charts.datapoint.copied": "Exact value copied",
|
|
351
|
+
// ChartFrame's SVG/PNG export actions (RM-025). Each string is used twice —
|
|
352
|
+
// as the icon button's `aria-label` (its ONLY accessible name) and as the
|
|
353
|
+
// tooltip a sighted user reads — so one key serves both and they cannot
|
|
354
|
+
// drift apart in translation.
|
|
355
|
+
"charts.chartFrame.exportSvg": "Export as SVG",
|
|
356
|
+
"charts.chartFrame.exportPng": "Export as PNG",
|
|
357
|
+
"charts.chartFrame.flipToTable": "Flip to table view",
|
|
358
|
+
"charts.chartFrame.showChart": "Show chart",
|
|
359
|
+
"charts.chartFrame.showAsTable": "Show as table",
|
|
360
|
+
"charts.chartFrame.downloadCsv": "Download CSV",
|
|
361
|
+
"charts.chartFrame.expandChart": "Expand chart",
|
|
362
|
+
"charts.chartFrame.expand": "Expand",
|
|
363
|
+
"charts.chartFrame.summary": "Summary",
|
|
364
|
+
"charts.chartFrame.noDataToSummarize": "No data to summarize.",
|
|
365
|
+
"charts.chartFrame.defaultTitle": "Chart",
|
|
366
|
+
"charts.chartFrame.summaryDetailLabel": "Chart summary",
|
|
367
|
+
"charts.legend.label": "Chart legend",
|
|
368
|
+
"charts.gantt.timeline": "Timeline",
|
|
369
|
+
"charts.gantt.dragToResizeColumn": "Drag to resize column",
|
|
370
|
+
"charts.gantt.viewControls": "Gantt view controls",
|
|
371
|
+
"charts.gantt.viewMode": "View mode",
|
|
372
|
+
"charts.gantt.viewModeLabel": "View mode:",
|
|
373
|
+
"charts.gantt.taskList": "Task list",
|
|
374
|
+
"charts.gantt.taskListLabel": "Tasks",
|
|
375
|
+
"charts.gantt.noTasksToDisplay": "No tasks to display",
|
|
376
|
+
"charts.gantt.unitDay": "Day",
|
|
377
|
+
"charts.gantt.unitWeek": "Week",
|
|
378
|
+
"charts.gantt.unitMonth": "Month",
|
|
379
|
+
"charts.gantt.unitQuarter": "Quarter",
|
|
380
|
+
"charts.gantt.unitHour": "Hour",
|
|
381
|
+
"charts.gantt.unitMinute": "Minute",
|
|
382
|
+
"charts.gantt.unitSecond": "Second",
|
|
383
|
+
"charts.gantt.unitMillisecond": "Millisecond",
|
|
384
|
+
|
|
385
|
+
// ── @elabs-ai/components-maps ─────────────────────────────────────────────────────────────
|
|
386
|
+
"maps.popup.close": "Close popup",
|
|
387
|
+
"maps.canvas.unavailableTitle": "Map unavailable",
|
|
388
|
+
"maps.canvas.unavailableDescription": "This browser can’t render WebGL maps.",
|
|
389
|
+
|
|
390
|
+
// ── @elabs-ai/components-flow ─────────────────────────────────────────────────────────────
|
|
391
|
+
"flow.inspectorPanel.close": "Close inspector",
|
|
392
|
+
"flow.inspectorPanel.title": "Inspector",
|
|
393
|
+
"flow.inspectorPanel.emptyMessage": "Select a node to see its details.",
|
|
108
394
|
|
|
109
395
|
// ── @elabs-ai/components-ai ───────────────────────────────────────────────────────────────
|
|
110
396
|
// Namespaced `ai.<area>.<key>` so package microcopy can't collide with the
|
|
@@ -120,25 +406,71 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
120
406
|
"ai.promptInput.uploadFiles": "Upload files",
|
|
121
407
|
"ai.promptInput.submit": "Submit",
|
|
122
408
|
"ai.promptInput.stop": "Stop",
|
|
409
|
+
"ai.agent.instructions": "Instructions",
|
|
410
|
+
"ai.agent.tools": "Tools",
|
|
411
|
+
"ai.agent.outputSchema": "Output Schema",
|
|
123
412
|
"ai.codeBlock.generating": "Generating…",
|
|
124
413
|
"ai.composer.placeholder": "Ask me anything…",
|
|
125
|
-
"ai.
|
|
414
|
+
"ai.tokenUsage.usage": "Model context usage",
|
|
415
|
+
"ai.tokenUsage.totalCost": "Total cost",
|
|
416
|
+
"ai.tokenUsage.input": "Input",
|
|
417
|
+
"ai.tokenUsage.output": "Output",
|
|
418
|
+
"ai.tokenUsage.reasoning": "Reasoning",
|
|
419
|
+
"ai.tokenUsage.cache": "Cache",
|
|
126
420
|
"ai.contextPanel.back": "Back to context",
|
|
127
421
|
"ai.contextPanel.toggle": "Toggle context panel",
|
|
422
|
+
// The mobile Sheet's sr-only title (#18) — distinct from `contextPanel.toggle`,
|
|
423
|
+
// which labels the button that opens/closes it.
|
|
424
|
+
"ai.contextPanel.title": "Context panel",
|
|
425
|
+
"ai.contextPanel.description": "Displays the chat context panel.",
|
|
128
426
|
"ai.environmentVariables.toggleVisibility": "Toggle value visibility",
|
|
129
427
|
"ai.gallery.label": "Image gallery",
|
|
130
428
|
"ai.gallery.expandImage": "Expand image",
|
|
131
429
|
"ai.gallery.downloadImage": "Download image",
|
|
430
|
+
"ai.gallery.noImages": "No images",
|
|
431
|
+
"ai.gallery.noDetails": "No details",
|
|
432
|
+
// Shared by Tool's technical view and SchemaDisplay's request panel.
|
|
433
|
+
"ai.schemaDisplay.parameters": "Parameters",
|
|
434
|
+
"ai.schemaDisplay.response": "Response",
|
|
435
|
+
"ai.schemaDisplay.requestBody": "Request Body",
|
|
436
|
+
// ReasoningTrigger's default not-yet-timed message (before `duration` is known).
|
|
437
|
+
"ai.reasoning.thoughtDefault": "Thought for a few seconds",
|
|
438
|
+
"ai.reasoning.thinking": "Thinking…",
|
|
439
|
+
"ai.reasoning.thoughtForDuration": "Thought for {duration} seconds",
|
|
440
|
+
"ai.stackTrace.empty": "No stack frames",
|
|
441
|
+
"ai.webPreview.noConsoleOutput": "No console output",
|
|
442
|
+
// PlanTrigger's icon-only collapse/expand control (sr-only).
|
|
443
|
+
"ai.plan.togglePlan": "Toggle plan",
|
|
132
444
|
"ai.message.actions": "Message actions",
|
|
133
445
|
"ai.message.editMessage": "Edit message",
|
|
134
446
|
"ai.message.feedback": "Message feedback",
|
|
135
447
|
"ai.message.previousBranch": "Previous branch",
|
|
136
448
|
"ai.message.nextBranch": "Next branch",
|
|
449
|
+
"ai.messageCompare.error": "Error",
|
|
450
|
+
"ai.messageCompare.tabs": "Compare responses",
|
|
137
451
|
"ai.persona.idle": "Assistant idle",
|
|
138
452
|
"ai.persona.listening": "Assistant listening",
|
|
139
453
|
"ai.persona.thinking": "Assistant thinking…",
|
|
140
454
|
"ai.persona.speaking": "Assistant speaking",
|
|
141
455
|
"ai.persona.asleep": "Assistant asleep",
|
|
456
|
+
// Optional-peer lazy engines (issue #33) — one shared pair every lazy
|
|
457
|
+
// boundary's missing-dependency panel resolves through, plus one
|
|
458
|
+
// `feature`-name key per boundary that renders it (mermaid, the terminal).
|
|
459
|
+
"ai.error.engineMissing": "{feature} unavailable",
|
|
460
|
+
"ai.error.engineMissingBody": "{feature} needs {packages} to be installed.",
|
|
461
|
+
"ai.error.retry": "Try again",
|
|
462
|
+
"ai.mermaid.feature": "Mermaid diagrams",
|
|
463
|
+
"ai.mermaid.renderError": "Diagram couldn't be drawn",
|
|
464
|
+
"ai.terminal.feature": "Interactive terminal",
|
|
465
|
+
"ai.terminal.renderError": "Terminal couldn't start",
|
|
466
|
+
"ai.audioPlayer.feature": "Audio player",
|
|
467
|
+
"ai.audioPlayer.renderError": "Audio player couldn't load",
|
|
468
|
+
// AudioVisualizer. Announced through a throttled `role="status"` region —
|
|
469
|
+
// the canvas itself is decorative (see .claude/rules/loading-states.md and
|
|
470
|
+
// issue #21's accessibility guidance).
|
|
471
|
+
"ai.audioVisualizer.idle": "Microphone not connected",
|
|
472
|
+
"ai.audioVisualizer.silent": "No input detected",
|
|
473
|
+
"ai.audioVisualizer.active": "Microphone active",
|
|
142
474
|
"ai.selectionToolbar.label": "Selection actions",
|
|
143
475
|
"ai.webPreview.urlPlaceholder": "Enter URL...",
|
|
144
476
|
"ai.micSelector.searchPlaceholder": "Search microphones...",
|
|
@@ -148,6 +480,60 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
148
480
|
"ai.voiceSelector.playPreview": "Play preview",
|
|
149
481
|
"ai.voiceSelector.pausePreview": "Pause preview",
|
|
150
482
|
|
|
483
|
+
// TurnStatus / SessionStatusBar (#105). `label` itself is caller-supplied
|
|
484
|
+
// ("Working…", "Editing files…") and rendered verbatim, so it needs no key
|
|
485
|
+
// here — only the component-owned completed-turn sentence and controls do.
|
|
486
|
+
"ai.turnStatus.completedIn": "Turn completed in {elapsed}",
|
|
487
|
+
"ai.turnStatus.completed": "Turn completed",
|
|
488
|
+
"ai.turnStatus.scrollToBottom": "Scroll to bottom",
|
|
489
|
+
"ai.sessionStatusBar.connections": "{connected} of {total} connections",
|
|
490
|
+
"ai.sessionStatusBar.connecting": "Connecting…",
|
|
491
|
+
// SessionHeader (#110). The section headings and the quick-action group name
|
|
492
|
+
// are component-owned chrome; the capability/what's-new item text itself is
|
|
493
|
+
// caller-supplied and rendered verbatim.
|
|
494
|
+
"ai.sessionHeader.capabilities": "Capabilities",
|
|
495
|
+
"ai.sessionHeader.whatsNew": "What’s new",
|
|
496
|
+
"ai.sessionHeader.quickActions": "Quick actions",
|
|
497
|
+
// PermissionModeSelect (#104). The in-force marker is a WORD inside the mode
|
|
498
|
+
// label, so the current mode survives greyscale and reaches the accessible name.
|
|
499
|
+
"ai.permissionModeSelect.current": "Current",
|
|
500
|
+
// AgentEvent (#109). The pass/fail WORD is the non-colour channel — the tone
|
|
501
|
+
// is redundant with it, so a check outcome survives greyscale (WCAG 1.4.1).
|
|
502
|
+
"ai.agentEvent.checkPassed": "Passed",
|
|
503
|
+
"ai.agentEvent.checkFailed": "Failed",
|
|
504
|
+
"ai.agentEvent.checksSummary": "{passed}/{ran} checks passed",
|
|
505
|
+
"ai.agentEvent.phaseBefore": "Before",
|
|
506
|
+
"ai.agentEvent.phaseAfter": "After",
|
|
507
|
+
"ai.agentEvent.phaseLifecycle": "Lifecycle",
|
|
508
|
+
// DiffView (#102). `addedLine` / `removedLine` are the sr-only polarity
|
|
509
|
+
// prefixes — the +/− glyph is aria-hidden, so these WORDS are the channel a
|
|
510
|
+
// greyscale or screen-reader user recovers the polarity from (WCAG 1.4.1).
|
|
511
|
+
// They intentionally end in a space so they read as a prefix to the code line.
|
|
512
|
+
"ai.diffView.addedLine": "Added: ",
|
|
513
|
+
"ai.diffView.removedLine": "Removed: ",
|
|
514
|
+
"ai.diffView.statsSummary": "{additions} additions, {deletions} deletions",
|
|
515
|
+
"ai.diffView.showMore": { one: "Show {count} more line", other: "Show {count} more lines" },
|
|
516
|
+
"ai.diffView.pagerLegend": "Arrow keys scroll, Page Up/Down page, Home/End jump",
|
|
517
|
+
"ai.diffView.regionLabel": "Code diff",
|
|
518
|
+
"ai.diffView.loading": "Loading diff…",
|
|
519
|
+
// ApprovalCard (#103). The SCOPE sentence is what makes an N-option
|
|
520
|
+
// permission prompt safe to answer: "Yes" and "Yes, and don't ask again" look
|
|
521
|
+
// alike and mean very different things. Each option links its scope sentence
|
|
522
|
+
// through aria-describedby, so the blast radius of a choice reaches assistive
|
|
523
|
+
// tech as words — never as a colour or a data-* attribute.
|
|
524
|
+
"ai.approvalCard.scopeOnceDescription": "Applies to this action only.",
|
|
525
|
+
"ai.approvalCard.scopeSessionDescription":
|
|
526
|
+
"Applies to actions like this for the rest of this session.",
|
|
527
|
+
"ai.approvalCard.scopeAlwaysDescription": "Applies to actions like this from now on.",
|
|
528
|
+
"ai.approvalCard.scopeDenyDescription": "Rejects this action.",
|
|
529
|
+
"ai.approvalCard.reasonLabel": "Reason",
|
|
530
|
+
"ai.approvalCard.reasonPlaceholder": "Add a reason (optional)…",
|
|
531
|
+
// PromptInputSlash (#106). `listLabel` goes to cmdk's own `label` prop, not
|
|
532
|
+
// `aria-label` — cmdk overwrites a consumer `aria-label` on CommandList and
|
|
533
|
+
// reads its accessible name off `label` instead.
|
|
534
|
+
"ai.promptInputSlash.listLabel": "Commands",
|
|
535
|
+
"ai.promptInputSlash.empty": "No matching commands.",
|
|
536
|
+
|
|
151
537
|
// ── Streamdown chrome (third-party rendering surface) ──────────────────────
|
|
152
538
|
// `streamdown` renders its OWN controls inside every streamed-markdown block
|
|
153
539
|
// (code header, table menus, Mermaid toolbar, external-link interstitial) and
|
|
@@ -195,6 +581,185 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
195
581
|
"ai.streamdown.copyLink": "Copy link",
|
|
196
582
|
"ai.streamdown.copied": "Copied",
|
|
197
583
|
"ai.streamdown.openLink": "Open link",
|
|
584
|
+
// Tool (#4 i18n sweep).
|
|
585
|
+
"ai.tool.showTechnicalDetails": "Show technical details",
|
|
586
|
+
"ai.tool.error": "Error",
|
|
587
|
+
"ai.tool.result": "Result",
|
|
588
|
+
// AssetPreview.
|
|
589
|
+
"ai.assetPreview.rowCount": { one: "{count} row", other: "{count} rows" },
|
|
590
|
+
"ai.assetPreview.noPreview": "No preview available…",
|
|
591
|
+
"ai.assetPreview.preview": "Preview",
|
|
592
|
+
"ai.assetPreview.raw": "Raw",
|
|
593
|
+
// WebPreview's sandboxed iframe accessible name.
|
|
594
|
+
"ai.webPreview.previewTitle": "Preview",
|
|
595
|
+
// FileTree's expand/collapse chevron control.
|
|
596
|
+
"ai.fileTree.expandFolder": "Expand {name}",
|
|
597
|
+
"ai.fileTree.collapseFolder": "Collapse {name}",
|
|
598
|
+
"ai.fileTree.noAssetsProduced": "No assets produced yet.",
|
|
599
|
+
"ai.conversation.download": "Download conversation",
|
|
600
|
+
// OpenInChat. `provider` is a brand name (ChatGPT, Claude, …) — kept
|
|
601
|
+
// untranslated data, interpolated into the translated "Open in …" phrase.
|
|
602
|
+
"ai.openInChat.trigger": "Open in chat",
|
|
603
|
+
"ai.openInChat.openInProvider": "Open in {provider}",
|
|
604
|
+
// TestResults.
|
|
605
|
+
"ai.testResults.passedCount": { one: "{count} passed", other: "{count} passed" },
|
|
606
|
+
"ai.testResults.failedCount": { one: "{count} failed", other: "{count} failed" },
|
|
607
|
+
"ai.testResults.skippedCount": { one: "{count} skipped", other: "{count} skipped" },
|
|
608
|
+
"ai.testResults.testsPassed": "{passed}/{total} tests passed",
|
|
609
|
+
|
|
610
|
+
// ── @elabs-ai/components-editor ───────────────────────────────────────────
|
|
611
|
+
// DecisionCard (ai-objects). Status vocabulary + the card's own accessible name
|
|
612
|
+
// and the "Alternatives considered" section (shared by its heading and its list's
|
|
613
|
+
// aria-label).
|
|
614
|
+
"editor.decisionCard.statusAccepted": "Accepted",
|
|
615
|
+
"editor.decisionCard.statusRejected": "Rejected",
|
|
616
|
+
"editor.decisionCard.statusProposed": "Proposed",
|
|
617
|
+
"editor.decisionCard.statusSuperseded": "Superseded",
|
|
618
|
+
"editor.decisionCard.label": "Decision: {label}",
|
|
619
|
+
"editor.decisionCard.alternativesConsidered": "Alternatives considered",
|
|
620
|
+
// KnowledgeCard (ai-objects).
|
|
621
|
+
"editor.knowledgeCard.label": "Knowledge fact",
|
|
622
|
+
"editor.knowledgeCard.heading": "Knowledge",
|
|
623
|
+
"editor.knowledgeCard.sources": "Sources",
|
|
624
|
+
"editor.knowledgeCard.source": "Source: {name}",
|
|
625
|
+
"editor.knowledgeCard.sourceUnresolved": "Source (unresolved): {name}",
|
|
626
|
+
// CalcBlock. `equals` is the sr-only prefix read before a computed value —
|
|
627
|
+
// intentionally ends in a space so it reads as a prefix (mirrors `ai.diffView.addedLine`).
|
|
628
|
+
"editor.calcBlock.error": "Error: {message}",
|
|
629
|
+
"editor.calcBlock.equals": "equals ",
|
|
630
|
+
"editor.calcBlock.total": "Total",
|
|
631
|
+
"editor.calcBlock.emptyBlock": "Empty calc block.",
|
|
632
|
+
// CopyButton. The "Copy" state reuses the shared generic `copy` key.
|
|
633
|
+
"editor.copyButton.copied": "Copied",
|
|
634
|
+
// EditorToolbar.
|
|
635
|
+
"editor.editorToolbar.language": "Language",
|
|
636
|
+
// Citations (markdown-academic).
|
|
637
|
+
"editor.citations.citationLabel": "Citation: {name}",
|
|
638
|
+
"editor.citations.unresolvedCitation": "Unresolved citation",
|
|
639
|
+
"editor.citations.unresolvedKey": "Unresolved: @{key}",
|
|
640
|
+
"editor.citations.references": "References",
|
|
641
|
+
// Math (markdown-academic).
|
|
642
|
+
"editor.math.renderError": "Could not render math",
|
|
643
|
+
"editor.math.renderErrorLabel": "Math (could not render): {tex}",
|
|
644
|
+
// CompletionMenu (markdown-editor).
|
|
645
|
+
"editor.completions.suggestions": "Suggestions",
|
|
646
|
+
"editor.completions.noSuggestions": "No suggestions",
|
|
647
|
+
// SlashMenu (markdown-editor).
|
|
648
|
+
"editor.slashMenu.insertBlock": "Insert block",
|
|
649
|
+
"editor.slashMenu.noMatchingBlocks": "No matching blocks",
|
|
650
|
+
// TableControlsView (markdown-editor/table-view — the WYSIWYG GFM table toolbar).
|
|
651
|
+
"editor.tableView.tableControls": "Table controls",
|
|
652
|
+
"editor.tableView.row": "Row",
|
|
653
|
+
"editor.tableView.col": "Col",
|
|
654
|
+
"editor.tableView.addRowAbove": "Add row above",
|
|
655
|
+
"editor.tableView.addRowBelow": "Add row below",
|
|
656
|
+
"editor.tableView.deleteRow": "Delete row",
|
|
657
|
+
"editor.tableView.addColumnLeft": "Add column left",
|
|
658
|
+
"editor.tableView.addColumnRight": "Add column right",
|
|
659
|
+
"editor.tableView.deleteColumn": "Delete column",
|
|
660
|
+
// Directive node-views (markdown-editor/directive-views — Milkdown WYSIWYG).
|
|
661
|
+
"editor.directiveViews.cardTitle": "Card title",
|
|
662
|
+
"editor.directiveViews.calloutTitle": "Callout title",
|
|
663
|
+
"editor.directiveViews.unknownBlock": "Unknown block: {name}",
|
|
664
|
+
"editor.directiveViews.unknownInlineBlock": "Unknown inline block:",
|
|
665
|
+
"editor.directiveViews.metricLabel": "Metric label",
|
|
666
|
+
"editor.directiveViews.metricLabelPlaceholder": "Label",
|
|
667
|
+
"editor.directiveViews.metricValue": "Metric value",
|
|
668
|
+
"editor.directiveViews.metricValuePlaceholder": "0",
|
|
669
|
+
"editor.directiveViews.editIteration": "Edit iteration…",
|
|
670
|
+
"editor.directiveViews.changeLayout": "Change layout",
|
|
671
|
+
"editor.directiveViews.transpose": "Transpose",
|
|
672
|
+
"editor.directiveViews.convertToStatic": "Convert to static",
|
|
673
|
+
"editor.directiveViews.needsEmbeddedValues": "— needs embedded values",
|
|
674
|
+
"editor.directiveViews.pivot": "Pivot",
|
|
675
|
+
"editor.directiveViews.iterate": "Iterate",
|
|
676
|
+
"editor.directiveViews.perItem": "· per {as}",
|
|
677
|
+
"editor.directiveViews.templateSuffix": "— template",
|
|
678
|
+
"editor.directiveViews.iterationActions": "Iteration actions",
|
|
679
|
+
"editor.directiveViews.iterationActionsTitle": "Iteration actions…",
|
|
680
|
+
// IterationBuilderDialog (markdown-iteration) — the guided iterate/pivot authoring modal.
|
|
681
|
+
"editor.iterationBuilder.pivotNoun": "pivot",
|
|
682
|
+
"editor.iterationBuilder.iterationNoun": "iteration",
|
|
683
|
+
"editor.iterationBuilder.editTitle": "Edit {noun}",
|
|
684
|
+
"editor.iterationBuilder.insertTitle": "Insert {noun}",
|
|
685
|
+
"editor.iterationBuilder.pivotDescription":
|
|
686
|
+
"Pick the row and column values, then write the per-cell template. The matrix below fills in live.",
|
|
687
|
+
"editor.iterationBuilder.iterationDescription":
|
|
688
|
+
"Add the list values, then write the per-row template. The result below fills in live.",
|
|
689
|
+
"editor.iterationBuilder.bindName": "Bind name",
|
|
690
|
+
"editor.iterationBuilder.bindNamePlaceholder": "item",
|
|
691
|
+
"editor.iterationBuilder.bindNameHintPrefix": "Use ",
|
|
692
|
+
"editor.iterationBuilder.bindNameHintSuffix": " in the template.",
|
|
693
|
+
"editor.iterationBuilder.rowValues": "Row values",
|
|
694
|
+
"editor.iterationBuilder.values": "Values",
|
|
695
|
+
"editor.iterationBuilder.valuePlaceholder": "Type a value, press Enter…",
|
|
696
|
+
"editor.iterationBuilder.columnValues": "Column values",
|
|
697
|
+
"editor.iterationBuilder.layout": "Layout",
|
|
698
|
+
"editor.iterationBuilder.perCellTemplate": "Per-cell template",
|
|
699
|
+
"editor.iterationBuilder.perRowTemplate": "Per-row template",
|
|
700
|
+
"editor.iterationBuilder.livePreview": "Live preview",
|
|
701
|
+
"editor.iterationBuilder.cancel": "Cancel",
|
|
702
|
+
"editor.iterationBuilder.save": "Save",
|
|
703
|
+
"editor.iterationBuilder.insert": "Insert",
|
|
704
|
+
// IterationTemplateDialog (markdown-iteration) — the lighter template-only modal.
|
|
705
|
+
"editor.templateDialog.editPivotTitle": "Edit pivot template",
|
|
706
|
+
"editor.templateDialog.editIterationTitle": "Edit iteration template",
|
|
707
|
+
"editor.templateDialog.descriptionPrefix": "The per-{unit} template. Use ",
|
|
708
|
+
"editor.templateDialog.descriptionMiddle": " placeholders (e.g. ",
|
|
709
|
+
"editor.templateDialog.descriptionSuffix":
|
|
710
|
+
") — each is filled per {unit} when the block renders.",
|
|
711
|
+
"editor.templateDialog.editorLabel": "Iteration template editor",
|
|
712
|
+
"editor.templateDialog.cancel": "Cancel",
|
|
713
|
+
"editor.templateDialog.saveTemplate": "Save template",
|
|
714
|
+
// DocumentOutline (markdown-outline).
|
|
715
|
+
"editor.documentOutline.label": "Document outline",
|
|
716
|
+
"editor.documentOutline.empty": "No headings yet.",
|
|
717
|
+
// MarkdownToolbar (the source-pane formatting bar). Directive snippet labels
|
|
718
|
+
// are the Insert menu's fallback item text (`DIRECTIVE_SNIPPETS`); the snippet
|
|
719
|
+
// MARKDOWN they insert is example document content, not UI chrome, and stays
|
|
720
|
+
// English (see the `i18n-exempt` comments at each snippet).
|
|
721
|
+
"editor.markdownToolbar.label": "Markdown formatting",
|
|
722
|
+
"editor.markdownToolbar.bold": "Bold",
|
|
723
|
+
"editor.markdownToolbar.italic": "Italic",
|
|
724
|
+
"editor.markdownToolbar.inlineCode": "Inline code",
|
|
725
|
+
"editor.markdownToolbar.link": "Link",
|
|
726
|
+
"editor.markdownToolbar.headingLevel": "Heading level",
|
|
727
|
+
"editor.markdownToolbar.heading": "Heading",
|
|
728
|
+
"editor.markdownToolbar.headingLevelItem": "Heading {level}",
|
|
729
|
+
"editor.markdownToolbar.quote": "Quote",
|
|
730
|
+
"editor.markdownToolbar.bulletList": "Bullet list",
|
|
731
|
+
"editor.markdownToolbar.numberedList": "Numbered list",
|
|
732
|
+
"editor.markdownToolbar.divider": "Divider",
|
|
733
|
+
"editor.markdownToolbar.insertBlock": "Insert block",
|
|
734
|
+
"editor.markdownToolbar.insert": "Insert",
|
|
735
|
+
"editor.markdownToolbar.insertBrandBlock": "Insert brand block",
|
|
736
|
+
"editor.markdownToolbar.directiveCard": "Card",
|
|
737
|
+
"editor.markdownToolbar.directiveCallout": "Callout",
|
|
738
|
+
"editor.markdownToolbar.directiveMetric": "Metric",
|
|
739
|
+
"editor.markdownToolbar.directiveTimeline": "Timeline",
|
|
740
|
+
// MarkdownWorkspace's focus-writing toggle.
|
|
741
|
+
"editor.markdownWorkspace.focusWriting": "Focus writing",
|
|
742
|
+
"editor.markdownWorkspace.focus": "Focus",
|
|
743
|
+
"editor.markdownWorkspace.focusWritingHint": "Typewriter scrolling · inactive paragraphs dim",
|
|
744
|
+
// MermaidDiagram (the inline renderer).
|
|
745
|
+
"editor.mermaidDiagram.label": "Diagram",
|
|
746
|
+
"editor.mermaidDiagram.expand": "Expand diagram",
|
|
747
|
+
"editor.mermaidDiagram.downloadSvg": "Download diagram as SVG",
|
|
748
|
+
"editor.mermaidDiagram.copySource": "Copy diagram source",
|
|
749
|
+
"editor.mermaidDiagram.renderFailed": "Diagram failed to render",
|
|
750
|
+
"editor.mermaidDiagram.rendering": "Rendering diagram…",
|
|
751
|
+
// MermaidViewer (the expanded zoom/pan/search surface). `nodeCountHint` mirrors
|
|
752
|
+
// the ORIGINAL (pre-i18n) copy exactly, including its always-plural "nodes" —
|
|
753
|
+
// it is a static hint ("N nodes · type to filter"), not a real plural form, so
|
|
754
|
+
// it stays a plain interpolated string rather than a `PluralMessage`.
|
|
755
|
+
"editor.mermaidViewer.findPlaceholder": "Find in diagram…",
|
|
756
|
+
"editor.mermaidViewer.findLabel": "Find in diagram",
|
|
757
|
+
"editor.mermaidViewer.matchCount": { one: "{count} node", other: "{count} nodes" },
|
|
758
|
+
"editor.mermaidViewer.nodeCountHint": "{count} nodes · type to filter",
|
|
759
|
+
"editor.mermaidViewer.zoomOut": "Zoom out",
|
|
760
|
+
"editor.mermaidViewer.zoomIn": "Zoom in",
|
|
761
|
+
"editor.mermaidViewer.resetZoom": "Reset zoom to 100%",
|
|
762
|
+
"editor.mermaidViewer.fitDiagram": "Fit diagram",
|
|
198
763
|
|
|
199
764
|
// ── @elabs-ai/components-viewer (ADR 0024) ─────────────────────────
|
|
200
765
|
// FileViewer chrome. Every control here is icon-only, so these ARE the
|
|
@@ -297,4 +862,259 @@ export const DEFAULT_MESSAGES: Record<string, string> = {
|
|
|
297
862
|
"viewer.highlight.previous": "Previous passage",
|
|
298
863
|
"viewer.highlight.next": "Next passage",
|
|
299
864
|
"viewer.highlight.count": "Passage {index} of {total}",
|
|
865
|
+
|
|
866
|
+
// ── @elabs-ai/components-terminal ─────────────────────────────────────────
|
|
867
|
+
// Terminal (the read-only ANSI log): the ONE live-region announcement for
|
|
868
|
+
// its `isStreaming` rung. The blinking cursor block is the only other
|
|
869
|
+
// streaming signal and it is purely visual, so without this a screen-reader
|
|
870
|
+
// user attached to a running build or deploy log gets no indication that
|
|
871
|
+
// anything is still arriving.
|
|
872
|
+
"terminal.output.streaming": "Streaming output…",
|
|
873
|
+
// TerminalTranscriptRow (#117 T2): the gutter's meaning as words, so the
|
|
874
|
+
// "who spoke / what it printed / did it fail" grammar survives greyscale
|
|
875
|
+
// and reaches assistive tech, not only the glyph + colour.
|
|
876
|
+
"terminal.transcriptRow.user": "Prompt",
|
|
877
|
+
"terminal.transcriptRow.agent": "Agent",
|
|
878
|
+
"terminal.transcriptRow.output": "Output",
|
|
879
|
+
"terminal.transcriptRow.error": "Error",
|
|
880
|
+
"terminal.transcriptRow.exitCode": "Exit {code}",
|
|
881
|
+
// TerminalTodoList (#117 T5): the three-state checklist's announced word
|
|
882
|
+
// per row — the second, non-colour channel beside the ✔ / ◼ / ◻ glyph and
|
|
883
|
+
// the strikethrough/bold treatment. Wording verified 2026-09-01 against
|
|
884
|
+
// Claude Code v2.1.207's own upstream state words, parentheses included.
|
|
885
|
+
"terminal.todoList.done": "(completed)",
|
|
886
|
+
"terminal.todoList.active": "(in progress)",
|
|
887
|
+
"terminal.todoList.pending": "(pending)",
|
|
888
|
+
// TerminalEventLine (#117 T6): the lifecycle/hook event line. `outcome*` is
|
|
889
|
+
// the sr-only word beside the (always aria-hidden) StatusIcon glyph —
|
|
890
|
+
// never omitted for the default "ok" case, so "succeeded" is exactly as
|
|
891
|
+
// recoverable as "failed". `hooksTotal`/`hooksResult` are the terminal's
|
|
892
|
+
// own literal `[hooks: …]` bracket vocabulary, verified live 2026-09-01
|
|
893
|
+
// against Grok CLI v0.2.93; `hooksFailed` is the sr-only, count-aware
|
|
894
|
+
// "N hooks failed" that makes a partial hook failure (e.g. `3/1`) read as
|
|
895
|
+
// bad without relying on colour.
|
|
896
|
+
"terminal.eventLine.outcomeOk": "Succeeded",
|
|
897
|
+
"terminal.eventLine.outcomeBlocked": "Blocked",
|
|
898
|
+
"terminal.eventLine.outcomeFailed": "Failed",
|
|
899
|
+
"terminal.eventLine.phaseBefore": "Before",
|
|
900
|
+
"terminal.eventLine.phaseAfter": "After",
|
|
901
|
+
"terminal.eventLine.phaseLifecycle": "Lifecycle",
|
|
902
|
+
"terminal.eventLine.hooksTotal": "[hooks: {total}]",
|
|
903
|
+
"terminal.eventLine.hooksResult": "[hooks: {ran}/{passed}]",
|
|
904
|
+
"terminal.eventLine.hooksFailed": {
|
|
905
|
+
one: "{count} hook failed",
|
|
906
|
+
other: "{count} hooks failed",
|
|
907
|
+
},
|
|
908
|
+
// TerminalWorking (#117 T3): the in-turn footer's default label and its two
|
|
909
|
+
// icon-only controls' accessible names. No generic "stop"/"scroll to
|
|
910
|
+
// bottom" key exists yet (only the ai-namespaced `ai.promptInput.stop` /
|
|
911
|
+
// `ai.turnStatus.scrollToBottom`), so these are minted under the package's
|
|
912
|
+
// own namespace rather than borrowed cross-package.
|
|
913
|
+
"terminal.working.label": "Waiting for response…",
|
|
914
|
+
"terminal.working.stop": "Stop",
|
|
915
|
+
"terminal.working.scrollToBottom": "Scroll to bottom",
|
|
916
|
+
// TerminalStatusBar (#117 T4): the ambient chrome row's accessible name and
|
|
917
|
+
// the sr-only words beside its aria-hidden numerals/glyphs. Mirrors
|
|
918
|
+
// `ai.sessionStatusBar.connections`' wording under this package's own
|
|
919
|
+
// namespace (cannot import the `ai` key — sibling packages never import
|
|
920
|
+
// each other, `.claude/rules/terminal-components.md` § Reuse means
|
|
921
|
+
// promotion). `disconnected` and `stepsComplete` ("steps complete") are
|
|
922
|
+
// verified live 2026-09-01 against Grok CLI v0.2.93.
|
|
923
|
+
"terminal.statusBar.label": "Session status",
|
|
924
|
+
"terminal.statusBar.connecting": "Connecting…",
|
|
925
|
+
"terminal.statusBar.connections": "{connected} of {total} connections",
|
|
926
|
+
"terminal.statusBar.disconnected": "Disconnected",
|
|
927
|
+
"terminal.statusBar.context": "{used} of {limit} context used",
|
|
928
|
+
"terminal.statusBar.stepsComplete": "{current} of {total} steps complete",
|
|
929
|
+
// TerminalBanner (#117 T7): the launch card above an empty transcript.
|
|
930
|
+
// Mirrors `ai.sessionHeader.*`'s wording under this package's own
|
|
931
|
+
// namespace — sibling packages never import each other's locale keys
|
|
932
|
+
// (`.claude/rules/terminal-components.md` § Reuse means promotion).
|
|
933
|
+
"terminal.banner.capabilities": "Capabilities",
|
|
934
|
+
"terminal.banner.whatsNew": "What’s new",
|
|
935
|
+
"terminal.banner.quickActions": "Quick actions",
|
|
936
|
+
// TerminalToolCall (#117 T8): the tool-call row's status word (announced
|
|
937
|
+
// beside the glyph via TerminalRow's gutterLabel — never colour alone),
|
|
938
|
+
// the result row's swapped heading (mirrors ToolOutput's own "Result"/
|
|
939
|
+
// "Error" heading swap, `@elabs-ai/components-ai`), and the expand
|
|
940
|
+
// trigger's accessible name. Unlike upstream's inert `"(ctrl+o to
|
|
941
|
+
// expand)"` hint text, this IS a real focusable control's label — no CLI
|
|
942
|
+
// chord required.
|
|
943
|
+
"terminal.toolCall.succeeded": "Succeeded",
|
|
944
|
+
"terminal.toolCall.failed": "Failed",
|
|
945
|
+
"terminal.toolCall.running": "Running",
|
|
946
|
+
"terminal.toolCall.result": "Result",
|
|
947
|
+
"terminal.toolCall.error": "Error",
|
|
948
|
+
"terminal.toolCall.expandHint": "Show details",
|
|
949
|
+
// TerminalDiffHunk (#117 T9): the header's fixed "Update ({file})" phrase,
|
|
950
|
+
// and the collapsed-context-run disclosure's count-aware label. Mirrors
|
|
951
|
+
// `ai.diffView.showMore`'s wording under this package's own namespace —
|
|
952
|
+
// sibling packages never import each other's locale keys
|
|
953
|
+
// (`.claude/rules/terminal-components.md` § Reuse means promotion). The
|
|
954
|
+
// per-line `add`/`del` polarity words are NOT duplicated here: they ride
|
|
955
|
+
// the shared `diffLineAccessibleLabel()` keys (`ai.diffView.addedLine` /
|
|
956
|
+
// `ai.diffView.removedLine`) above, the actual promoted channel.
|
|
957
|
+
"terminal.diffHunk.header": "Update ({file})",
|
|
958
|
+
"terminal.diffHunk.showMore": {
|
|
959
|
+
one: "Show {count} more line",
|
|
960
|
+
other: "Show {count} more lines",
|
|
961
|
+
},
|
|
962
|
+
// TerminalPermission (#117 T10): the per-call scoped approval prompt's
|
|
963
|
+
// default title/question and its three scoped option labels, verified
|
|
964
|
+
// live 2026-09-01 against Claude Code v2.1.207. The third option is the
|
|
965
|
+
// vendor-free `deny` scope: upstream names its own product in this label,
|
|
966
|
+
// ours reads "the agent" instead (#117 acceptance criterion). The reason
|
|
967
|
+
// field reuses `ai.approvalCard.reasonLabel`/`reasonPlaceholder` and the
|
|
968
|
+
// option descriptions reuse `APPROVAL_SCOPE_DESCRIPTION_KEYS` — both
|
|
969
|
+
// already generic, so nothing new is minted for either.
|
|
970
|
+
"terminal.permission.title": "Bash command",
|
|
971
|
+
"terminal.permission.question": "Do you want to proceed?",
|
|
972
|
+
"terminal.permission.optionOnce": "Yes",
|
|
973
|
+
"terminal.permission.optionSession": "Yes, and don’t ask again this session",
|
|
974
|
+
"terminal.permission.optionDeny": "No, and tell the agent what to do differently",
|
|
975
|
+
// TerminalComposer (#117 T11): the prompt composer's placeholder, its
|
|
976
|
+
// merged submit/stop affordance's accessible name (mirrors
|
|
977
|
+
// `ai.promptInput.submit`/`stop` under this package's own namespace —
|
|
978
|
+
// sibling packages never import each other's locale keys,
|
|
979
|
+
// `.claude/rules/terminal-components.md` § Reuse means promotion), the
|
|
980
|
+
// effort scale's default accessible name, and the shortcut-hint row's
|
|
981
|
+
// three default words.
|
|
982
|
+
"terminal.composer.placeholder": "Type your next instruction…",
|
|
983
|
+
"terminal.composer.submit": "Send",
|
|
984
|
+
"terminal.composer.stop": "Stop",
|
|
985
|
+
"terminal.composer.effort": "Effort",
|
|
986
|
+
"terminal.composer.shortcutSend": "send",
|
|
987
|
+
"terminal.composer.shortcutNewline": "newline",
|
|
988
|
+
"terminal.composer.shortcutCancel": "cancel",
|
|
989
|
+
// TerminalSlashMenu (#117 T12): the `/`-command palette's listbox
|
|
990
|
+
// accessible name (mirrors `ai.promptInputSlash.listLabel`'s wording under
|
|
991
|
+
// this package's own namespace — sibling packages never import each
|
|
992
|
+
// other's locale keys, `.claude/rules/terminal-components.md` § Reuse
|
|
993
|
+
// means promotion). The empty state reuses the generic `noResults` key
|
|
994
|
+
// rather than minting a second one.
|
|
995
|
+
"terminal.slashMenu.listLabel": "Commands",
|
|
996
|
+
// ── @elabs-ai/components-process ──────────────────────────────────────────────────────────
|
|
997
|
+
// ProcessMap (RM-051). Namespaced `process.<area>.<key>` like every other
|
|
998
|
+
// package; a sibling package's keys are never reused across the boundary.
|
|
999
|
+
// The table twin's column headers are here because that table IS the
|
|
1000
|
+
// accessible reading of the canvas — an untranslated header would leave a
|
|
1001
|
+
// screen-reader user with numbers and no measure name.
|
|
1002
|
+
"process.map.loading": "Discovering the process…",
|
|
1003
|
+
"process.map.empty": "No activities to map",
|
|
1004
|
+
"process.map.emptyBody":
|
|
1005
|
+
"This log has no events, or the abstraction hid every activity. Widen the abstraction or load a different log.",
|
|
1006
|
+
"process.map.label": "Process map",
|
|
1007
|
+
"process.map.filter": "Filter…",
|
|
1008
|
+
"process.map.activityCaption": "Activities — {metric} per activity",
|
|
1009
|
+
"process.map.transitionCaption": "Transitions — {metric} per directly-follows pair",
|
|
1010
|
+
"process.map.columnActivity": "Activity",
|
|
1011
|
+
"process.map.columnRole": "Role",
|
|
1012
|
+
"process.map.columnRework": "Rework",
|
|
1013
|
+
"process.map.columnFrom": "From",
|
|
1014
|
+
"process.map.columnTo": "To",
|
|
1015
|
+
"process.map.columnShape": "Shape",
|
|
1016
|
+
// State column (#373) — the table twin's own channel for the selection/filter state the
|
|
1017
|
+
// canvas already says through real text in its accessible names; the twin used to carry
|
|
1018
|
+
// it only as a `data-*` attribute, which reaches no user.
|
|
1019
|
+
"process.map.columnState": "State",
|
|
1020
|
+
// The State column's own CELL values (#413 review, PRRT_kwDOT6D7ts6gJX2C). #373 localized
|
|
1021
|
+
// the column HEADER but left every cell printing the literal English word — since that cell
|
|
1022
|
+
// is also the row's screen-reader channel for its selection/filter state
|
|
1023
|
+
// (`selectionStateLabel` below is the un-localized canonical word `process-map.tsx` maps
|
|
1024
|
+
// through these keys at the render site), a non-English `LocaleProvider` left both the
|
|
1025
|
+
// visible AND the accessible content untranslated. `"associated"` (the ordinary case) has
|
|
1026
|
+
// no key: it prints nothing, by design.
|
|
1027
|
+
"process.map.stateSelected": "Selected",
|
|
1028
|
+
"process.map.stateExcluded": "Excluded",
|
|
1029
|
+
// Filter-intent menu item ACCESSIBLE names (#346). A transition's menu offers the same
|
|
1030
|
+
// four intents once per endpoint (eight items total); the visible text
|
|
1031
|
+
// (`PROCESS_FILTER_INTENT_LABELS` in map-model.ts) stays unsuffixed and compact, so these
|
|
1032
|
+
// compose the activity into the item's real accessible name instead — the channel a
|
|
1033
|
+
// screen-reader user actually hears, and the one the visible-only text left ambiguous.
|
|
1034
|
+
"process.map.filterIntentWith": "Keep cases containing {activity}",
|
|
1035
|
+
"process.map.filterIntentWithout": "Keep cases without {activity}",
|
|
1036
|
+
"process.map.filterIntentStartsWith": "Keep cases starting with {activity}",
|
|
1037
|
+
"process.map.filterIntentEndsWith": "Keep cases ending with {activity}",
|
|
1038
|
+
// The map's own live-region summary (#375) — one polite `role="status"` announces what
|
|
1039
|
+
// the active selection/filter just changed, mirroring `AbstractionControls`' hidden-count
|
|
1040
|
+
// summary below: two independently-pluralized fragments, composed at the call site
|
|
1041
|
+
// (`process-map.tsx`) rather than merged into one message, for the same reason.
|
|
1042
|
+
"process.map.excludedActivities": {
|
|
1043
|
+
one: "{count} of {total} activity excluded",
|
|
1044
|
+
other: "{count} of {total} activities excluded",
|
|
1045
|
+
},
|
|
1046
|
+
"process.map.excludedTransitions": {
|
|
1047
|
+
one: "{count} of {total} transition excluded",
|
|
1048
|
+
other: "{count} of {total} transitions excluded",
|
|
1049
|
+
},
|
|
1050
|
+
// The live region's AFFECTED-SET fragments (#413 review, PRRT_kwDOT6D7ts6gJX2I). Counts
|
|
1051
|
+
// alone are not enough: two selections/filters that exclude DIFFERENT elements but land on
|
|
1052
|
+
// the SAME counts produce byte-for-byte identical text, so the polite region — which
|
|
1053
|
+
// announces content CHANGES, not model changes — stays silent even though the map
|
|
1054
|
+
// re-inked. Naming which elements are excluded makes the string track the actual set, not
|
|
1055
|
+
// only its size. Composed at the call site alongside the two counts above, and omitted
|
|
1056
|
+
// entirely when nothing of that kind is excluded (so the common case stays as short as
|
|
1057
|
+
// before this fix).
|
|
1058
|
+
"process.map.excludedActivityNames": "excluding {names}",
|
|
1059
|
+
"process.map.excludedTransitionNames": "excluding {names}",
|
|
1060
|
+
// AbstractionControls (RM-052, issue #227). The two sliders' own labels,
|
|
1061
|
+
// the invert switch, the "Auto" heuristic button, and the hidden-count
|
|
1062
|
+
// status line. `hiddenActivities`/`hiddenPaths` are separate `PluralMessage`s
|
|
1063
|
+
// (not one combined key) because `t()` selects its plural category from a
|
|
1064
|
+
// SINGLE `count` var — see `resolveMessage` in `locale-provider.tsx` — so
|
|
1065
|
+
// the two independently-pluralizable counts are composed as two `t()` calls
|
|
1066
|
+
// joined at the call site (`abstraction-controls.tsx`), not one key with two
|
|
1067
|
+
// numbers.
|
|
1068
|
+
"process.abstractionControls.label": "Abstraction",
|
|
1069
|
+
"process.abstractionControls.activities": "Activities",
|
|
1070
|
+
"process.abstractionControls.paths": "Paths",
|
|
1071
|
+
"process.abstractionControls.invert": "Invert",
|
|
1072
|
+
"process.abstractionControls.auto": "Auto",
|
|
1073
|
+
"process.abstractionControls.hiddenActivities": {
|
|
1074
|
+
one: "{count} activity hidden",
|
|
1075
|
+
other: "{count} activities hidden",
|
|
1076
|
+
},
|
|
1077
|
+
"process.abstractionControls.hiddenPaths": {
|
|
1078
|
+
one: "{count} path hidden",
|
|
1079
|
+
other: "{count} paths hidden",
|
|
1080
|
+
},
|
|
1081
|
+
// MetricLayerSwitch (RM-052, issue #227). The Frequency/Performance/Rework
|
|
1082
|
+
// toggle group, the node/edge metric selects' field labels, and the lock
|
|
1083
|
+
// toggle's two accessible-name states. The per-VALUE metric labels
|
|
1084
|
+
// ("Occurrences", "Share of transitions", …) are deliberately NOT
|
|
1085
|
+
// duplicated here — they are read straight from `nodeMetricLabel`/
|
|
1086
|
+
// `edgeMetricLabel` (`process-map/map-model.ts`), which already resolve
|
|
1087
|
+
// each `ProcessMetric` to its correct, audience-specific text; see
|
|
1088
|
+
// `metric-layer-switch.tsx`'s module docblock.
|
|
1089
|
+
"process.metricLayerSwitch.label": "Metric",
|
|
1090
|
+
"process.metricLayerSwitch.layer": "Metric layer",
|
|
1091
|
+
"process.metricLayerSwitch.frequency": "Frequency",
|
|
1092
|
+
"process.metricLayerSwitch.performance": "Performance",
|
|
1093
|
+
"process.metricLayerSwitch.rework": "Rework",
|
|
1094
|
+
"process.metricLayerSwitch.node": "Activity",
|
|
1095
|
+
"process.metricLayerSwitch.edge": "Transition",
|
|
1096
|
+
"process.metricLayerSwitch.lockOn": "Unlock activity and transition metrics",
|
|
1097
|
+
"process.metricLayerSwitch.lockOff": "Lock activity and transition metrics together",
|
|
1098
|
+
// ProcessKpiStrip (RM-052, issue #227). Six tiles' labels, plus the
|
|
1099
|
+
// conformance tile's genuine "not available" state (no conformance model
|
|
1100
|
+
// has run yet) — a real state, not a fabricated 0%.
|
|
1101
|
+
"process.kpiStrip.cases": "Cases",
|
|
1102
|
+
"process.kpiStrip.events": "Events",
|
|
1103
|
+
"process.kpiStrip.variants": "Variants",
|
|
1104
|
+
"process.kpiStrip.medianThroughput": "Median throughput",
|
|
1105
|
+
"process.kpiStrip.reworkRate": "Rework rate",
|
|
1106
|
+
"process.kpiStrip.conformance": "Conformance",
|
|
1107
|
+
"process.kpiStrip.conformanceUnavailable": "Not available",
|
|
1108
|
+
"process.kpiStrip.conformanceUnavailableHint": "Run conformance checking to see this metric.",
|
|
1109
|
+
// Sparkline text alternative (#359). `Sparkline`'s own default alt text is more
|
|
1110
|
+
// informative than the tile's own label — passing the label straight through
|
|
1111
|
+
// overrode it and left a screen-reader user hearing the tile's name twice with no
|
|
1112
|
+
// sense of the trend. `direction` is itself a resolved `t()` value (trendRising/
|
|
1113
|
+
// Falling/Steady), composed into this template the same way `hiddenSummary`
|
|
1114
|
+
// (abstraction-controls.tsx) composes two already-localized fragments.
|
|
1115
|
+
"process.kpiStrip.trendAlt":
|
|
1116
|
+
"{subject}, {periods}-period trend, {direction} from {first} to {last}",
|
|
1117
|
+
"process.kpiStrip.trendRising": "rising",
|
|
1118
|
+
"process.kpiStrip.trendFalling": "falling",
|
|
1119
|
+
"process.kpiStrip.trendSteady": "steady",
|
|
300
1120
|
};
|