@keyfunc/keybricks-ds 2.1.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEPLOY.md +20 -5
- package/DESIGN.md +148 -20
- package/INTEGRATION.md +97 -24
- package/SKILL.md +11 -11
- package/_adherence.oxlintrc.json +56 -24
- package/_scripts/build-index.mjs +15 -4
- package/assets/icons/icon-index.js +1 -1
- package/assets/icons/icon-index.json +1 -1
- package/assets/logos/datasource/dat.png +0 -0
- package/assets/logos/datasource/excel.png +0 -0
- package/assets/logos/datasource/ftp.png +0 -0
- package/assets/logos/datasource/hierarchy.png +0 -0
- package/assets/logos/datasource/hive.png +0 -0
- package/assets/logos/datasource/json.png +0 -0
- package/assets/logos/datasource/mariadb.png +0 -0
- package/assets/logos/datasource/mongodb.png +0 -0
- package/assets/logos/datasource/mysql.png +0 -0
- package/assets/logos/datasource/odbc.png +0 -0
- package/assets/logos/datasource/oracle.png +0 -0
- package/assets/logos/datasource/postgresql.png +0 -0
- package/assets/logos/datasource/rest-api.png +0 -0
- package/assets/logos/datasource/sap-alt.png +0 -0
- package/assets/logos/datasource/sap.png +0 -0
- package/assets/logos/datasource/soap.png +0 -0
- package/assets/logos/datasource/sql-server.png +0 -0
- package/components/_cards/accordion.card.html +1 -1
- package/components/_cards/action-chip.card.html +11 -14
- package/components/_cards/activity.card.html +2 -2
- package/components/_cards/alert.card.html +2 -2
- package/components/_cards/app-chrome.card.html +34 -22
- package/components/_cards/banner.card.html +1 -1
- package/components/_cards/breadcrumb.card.html +4 -4
- package/components/_cards/button-1-base.card.html +23 -26
- package/components/_cards/button-2-states.card.html +14 -12
- package/components/_cards/button-3-sizes-icons.card.html +20 -19
- package/components/_cards/button-4-group.card.html +14 -31
- package/components/_cards/canvas-zoom-controls.card.html +1 -1
- package/components/_cards/cards-indicators.card.html +1 -1
- package/components/_cards/charts-1-sparkline.card.html +4 -4
- package/components/_cards/charts-10-gauge.card.html +2 -2
- package/components/_cards/charts-11-funnel.card.html +2 -2
- package/components/_cards/charts-12-treemap.card.html +2 -2
- package/components/_cards/charts-14-radar.card.html +3 -3
- package/components/_cards/charts-15-distribution.card.html +2 -2
- package/components/_cards/charts-16-pareto.card.html +2 -2
- package/components/_cards/charts-17-candlestick.card.html +2 -2
- package/components/_cards/charts-18-sankey.card.html +2 -2
- package/components/_cards/charts-19-chord.card.html +2 -2
- package/components/_cards/charts-2-line.card.html +3 -3
- package/components/_cards/charts-20-sunburst.card.html +2 -2
- package/components/_cards/charts-21-worldmap.card.html +3 -3
- package/components/_cards/charts-22-gantt.card.html +2 -2
- package/components/_cards/charts-23-bar3d.card.html +2 -2
- package/components/_cards/charts-24-pie3d.card.html +2 -2
- package/components/_cards/charts-25-surface3d.card.html +2 -2
- package/components/_cards/charts-26-scatter3d.card.html +2 -2
- package/components/_cards/charts-27-ribbon3d.card.html +2 -2
- package/components/_cards/charts-3-bar.card.html +6 -6
- package/components/_cards/charts-4-barlist.card.html +2 -2
- package/components/_cards/charts-5-donut.card.html +2 -2
- package/components/_cards/charts-6-scatter.card.html +2 -2
- package/components/_cards/charts-7-heatmap.card.html +2 -2
- package/components/_cards/charts-8-waterfall.card.html +2 -2
- package/components/_cards/charts-9-bullet.card.html +3 -3
- package/components/_cards/charts-99-fullpage.card.html +1 -1
- package/components/_cards/checkbox.card.html +6 -3
- package/components/_cards/codeblock.card.html +2 -2
- package/components/_cards/combobox.card.html +6 -4
- package/components/_cards/context-menu.card.html +12 -5
- package/components/_cards/date-picker.card.html +8 -5
- package/components/_cards/diffvalue.card.html +2 -2
- package/components/_cards/divider.card.html +2 -2
- package/components/_cards/drawer.card.html +3 -3
- package/components/_cards/dropdown-menu.card.html +2 -2
- package/components/_cards/dropzone.card.html +5 -3
- package/components/_cards/empty-state.card.html +2 -2
- package/components/_cards/filter-bar.card.html +1 -1
- package/components/_cards/icon-button.card.html +14 -14
- package/components/_cards/icons-0-usage.card.html +88 -0
- package/components/_cards/icons-1-core.card.html +4 -4
- package/components/_cards/icons-2-feather.card.html +4 -4
- package/components/_cards/icons-3-unicons.card.html +3 -3
- package/components/_cards/icons-4-datasource.card.html +5 -0
- package/components/_cards/input.card.html +5 -5
- package/components/_cards/kbd.card.html +1 -1
- package/components/_cards/keyvalue.card.html +1 -1
- package/components/_cards/listrow.card.html +1 -1
- package/components/_cards/loading.card.html +2 -2
- package/components/_cards/log-viewer.card.html +2 -2
- package/components/_cards/modal.card.html +1 -1
- package/components/_cards/multi-select.card.html +6 -4
- package/components/_cards/number-stepper.card.html +9 -6
- package/components/_cards/pagination.card.html +6 -4
- package/components/_cards/people.card.html +2 -2
- package/components/_cards/pipeline-node.card.html +8 -8
- package/components/_cards/pipeline-palette.card.html +2 -2
- package/components/_cards/radio.card.html +12 -7
- package/components/_cards/search.card.html +6 -6
- package/components/_cards/segmented-control.card.html +19 -12
- package/components/_cards/select.card.html +7 -3
- package/components/_cards/slider.card.html +2 -2
- package/components/_cards/smart-table.card.html +3 -3
- package/components/_cards/spreadsheet.card.html +2 -2
- package/components/_cards/stepper.card.html +2 -2
- package/components/_cards/table.card.html +79 -17
- package/components/_cards/tabs.card.html +10 -5
- package/components/_cards/tag.card.html +6 -6
- package/components/_cards/textarea.card.html +1 -1
- package/components/_cards/timeline.card.html +3 -3
- package/components/_cards/toast.card.html +7 -5
- package/components/_cards/toggles.card.html +14 -9
- package/components/_cards/tooltip.card.html +3 -3
- package/components/_cards/tree.card.html +2 -2
- package/components/_shared/card-kit.css +25 -0
- package/components/_shared/card-kit.js +50 -0
- package/components/_shared/src-buttons.js +1 -1
- package/components/_shared/src-charts.js +1 -1
- package/components/_shared/src-data.js +1 -1
- package/components/_shared/src-display.js +1 -1
- package/components/_shared/src-feedback.js +1 -1
- package/components/_shared/src-forms.js +1 -1
- package/components/_shared/src-icons.js +1 -1
- package/components/_shared/src-navigation.js +1 -1
- package/components/_shared/src-tabs.js +1 -1
- package/components/_shared/view-source.js +12 -12
- package/components/_vue/index.mjs +10 -0
- package/components/buttons/ActionChip.d.ts +1 -1
- package/components/buttons/Button.d.ts +1 -1
- package/components/buttons/Button.jsx +1 -1
- package/components/buttons/Button.vue +1 -1
- package/components/buttons/IconButton.d.ts +1 -1
- package/components/buttons/IconButton.jsx +5 -3
- package/components/buttons/IconButton.vue +3 -2
- package/components/charts/Bar3D.jsx +1 -1
- package/components/charts/Bar3D.vue +2 -2
- package/components/charts/BarChart.jsx +3 -3
- package/components/charts/BarChart.vue +6 -6
- package/components/charts/BarList.jsx +3 -3
- package/components/charts/BarList.vue +3 -3
- package/components/charts/BoxPlot.vue +2 -2
- package/components/charts/BulletChart.jsx +5 -5
- package/components/charts/BulletChart.vue +5 -5
- package/components/charts/CandlestickChart.vue +3 -3
- package/components/charts/ChartKit.jsx +4 -3
- package/components/charts/ChartTooltip.vue +1 -1
- package/components/charts/ChordChart.jsx +1 -1
- package/components/charts/ChordChart.vue +2 -2
- package/components/charts/DonutChart.jsx +1 -1
- package/components/charts/DonutChart.vue +2 -2
- package/components/charts/FunnelChart.jsx +3 -3
- package/components/charts/FunnelChart.vue +4 -4
- package/components/charts/GanttChart.vue +1 -1
- package/components/charts/GaugeChart.jsx +2 -2
- package/components/charts/GaugeChart.vue +2 -2
- package/components/charts/HeatmapChart.jsx +1 -1
- package/components/charts/HeatmapChart.vue +1 -1
- package/components/charts/Histogram.jsx +2 -2
- package/components/charts/Histogram.vue +4 -4
- package/components/charts/LineChart.vue +2 -2
- package/components/charts/ParetoChart.jsx +1 -1
- package/components/charts/ParetoChart.vue +3 -3
- package/components/charts/Pie3D.jsx +1 -1
- package/components/charts/Pie3D.vue +2 -2
- package/components/charts/PlotGrid.vue +1 -1
- package/components/charts/RadarChart.vue +1 -1
- package/components/charts/Ribbon3D.jsx +1 -1
- package/components/charts/Ribbon3D.vue +2 -2
- package/components/charts/SankeyChart.jsx +1 -1
- package/components/charts/SankeyChart.vue +2 -2
- package/components/charts/Scatter3D.vue +1 -1
- package/components/charts/ScatterChart.jsx +1 -1
- package/components/charts/ScatterChart.vue +3 -3
- package/components/charts/Sparkline.jsx +1 -1
- package/components/charts/Sparkline.vue +1 -1
- package/components/charts/SunburstChart.vue +1 -1
- package/components/charts/Surface3D.jsx +1 -1
- package/components/charts/Surface3D.vue +2 -2
- package/components/charts/TreemapChart.jsx +1 -1
- package/components/charts/TreemapChart.vue +2 -2
- package/components/charts/WaterfallChart.jsx +1 -1
- package/components/charts/WaterfallChart.vue +5 -4
- package/components/charts/WorldMap.jsx +4 -4
- package/components/charts/WorldMap.vue +5 -5
- package/components/data/DiffValue.d.ts +1 -0
- package/components/data/DiffValue.jsx +1 -1
- package/components/data/DiffValue.vue +1 -1
- package/components/data/KeyValue.d.ts +1 -1
- package/components/data/KeyValue.jsx +2 -2
- package/components/data/KeyValue.vue +2 -2
- package/components/data/Pagination.jsx +2 -2
- package/components/data/Pagination.vue +1 -1
- package/components/data/SmartTable.jsx +5 -5
- package/components/data/SmartTable.vue +6 -6
- package/components/data/Spreadsheet.jsx +5 -5
- package/components/data/Spreadsheet.vue +6 -6
- package/components/data/Table.d.ts +58 -4
- package/components/data/Table.jsx +153 -15
- package/components/data/Table.vue +105 -15
- package/components/data/data.prompt.md +1 -1
- package/components/display/Avatar.jsx +2 -2
- package/components/display/Avatar.vue +1 -1
- package/components/display/AvatarGroup.vue +1 -1
- package/components/display/Badge.d.ts +4 -1
- package/components/display/Badge.jsx +10 -5
- package/components/display/IconTile.vue +9 -4
- package/components/display/Kbd.d.ts +1 -1
- package/components/display/Kbd.jsx +1 -1
- package/components/display/Kbd.vue +1 -1
- package/components/feedback/ActivityItem.jsx +1 -1
- package/components/feedback/ContextMenu.d.ts +3 -2
- package/components/feedback/ContextMenu.jsx +8 -4
- package/components/feedback/ContextMenu.vue +9 -6
- package/components/feedback/Menu.d.ts +1 -1
- package/components/feedback/Modal.jsx +1 -1
- package/components/feedback/Modal.vue +1 -1
- package/components/feedback/Timeline.vue +2 -2
- package/components/feedback/feedback.prompt.md +1 -1
- package/components/forms/Combobox.d.ts +1 -1
- package/components/forms/DatePicker.d.ts +1 -1
- package/components/forms/Input.d.ts +1 -1
- package/components/forms/Input.jsx +2 -2
- package/components/forms/Input.vue +1 -1
- package/components/forms/MultiSelect.d.ts +1 -1
- package/components/forms/NumberStepper.d.ts +1 -1
- package/components/forms/SearchInput.d.ts +1 -1
- package/components/forms/Select.d.ts +1 -1
- package/components/forms/Select.jsx +1 -1
- package/components/forms/Select.vue +1 -1
- package/components/forms/Slider.jsx +1 -1
- package/components/forms/Slider.vue +1 -1
- package/components/forms/Switch.jsx +3 -3
- package/components/forms/Switch.vue +11 -8
- package/components/forms/Textarea.vue +1 -1
- package/components/forms/input-base.js +1 -1
- package/components/icons/Icon.jsx +17 -1
- package/components/icons/Icon.prompt.md +2 -0
- package/components/icons/Icon.vue +1 -1
- package/components/icons/icon-paths.js +15 -0
- package/components/index.d.ts +1 -0
- package/components/index.js +5 -4
- package/components/navigation/Breadcrumb.jsx +3 -7
- package/components/navigation/Breadcrumb.vue +2 -8
- package/components/navigation/SidePanel.d.ts +22 -0
- package/components/navigation/SidePanel.jsx +23 -0
- package/components/navigation/SidePanel.vue +21 -0
- package/components/navigation/Sidebar.d.ts +23 -7
- package/components/navigation/Sidebar.jsx +38 -56
- package/components/navigation/Sidebar.vue +40 -44
- package/components/navigation/TopBar.d.ts +28 -3
- package/components/navigation/TopBar.jsx +54 -7
- package/components/navigation/TopBar.vue +26 -8
- package/components/navigation/Tree.jsx +1 -1
- package/components/navigation/Tree.vue +9 -4
- package/components/navigation/UserMenu.vue +27 -0
- package/components/navigation/chrome-tones.js +22 -0
- package/components/navigation/nav-model.js +26 -0
- package/components/navigation/navigation.prompt.md +2 -0
- package/components/navigation/theme-store.js +9 -0
- package/components/tabs/CountBadge.vue +12 -0
- package/components/tabs/PanelTabs.vue +7 -3
- package/components/tabs/PillTabs.vue +8 -4
- package/components/tabs/SegmentedControl.d.ts +5 -3
- package/components/tabs/SegmentedControl.jsx +6 -4
- package/components/tabs/SegmentedControl.vue +4 -3
- package/components/tabs/Tabs.d.ts +14 -4
- package/components/tabs/Tabs.jsx +35 -20
- package/components/tabs/Tabs.vue +7 -3
- package/components/tabs/ViewToggle.d.ts +1 -1
- package/components/tabs/tabs.prompt.md +2 -2
- package/package.json +2 -2
- package/readme.md +10 -9
- package/readme.zh-CN.md +8 -7
- package/tokens/alpha.css +3 -1
- package/tokens/colors.css +1 -1
- package/tokens/dark.css +1 -1
- package/tokens/layout.css +8 -5
- package/tokens/tokens.d.ts +24 -0
- package/tokens/tokens.js +42 -6
- package/tokens/tokens.json +97 -11
- package/tokens/typography.css +26 -9
package/DEPLOY.md
CHANGED
|
@@ -55,11 +55,11 @@ deploys the documentation site. Watch it under *Build → Pipelines*.
|
|
|
55
55
|
**5. Cut the first release.**
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
git tag v2.
|
|
58
|
+
git tag v2.4.0 && git push --tags
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
That tag runs `generated:check` → `version:check` → `npm publish`. Confirm under *Deploy →
|
|
62
|
-
Package Registry*: `@keyfunc/keybricks-ds` 2.
|
|
62
|
+
Package Registry*: `@keyfunc/keybricks-ds` 2.4.0.
|
|
63
63
|
|
|
64
64
|
**6. Hand developers two things:** the Pages URL, and the `.npmrc` snippet in §4 below.
|
|
65
65
|
|
|
@@ -96,7 +96,7 @@ Published (`files` in `package.json`): `components/`, `tokens/`, `assets/`, `_sc
|
|
|
96
96
|
> that mode — Vue apps on a git dependency should deep-import
|
|
97
97
|
> `@keyfunc/keybricks-ds/components/<group>/<Name>.vue`, which is the recommended path anyway.
|
|
98
98
|
|
|
99
|
-
Not published: `guidelines/`, `
|
|
99
|
+
Not published: `guidelines/`, `index.html`, `gallery.html`,
|
|
100
100
|
`_ds_bundle.js`. Those are the documentation site — they go to Pages, not into every
|
|
101
101
|
`node_modules`.
|
|
102
102
|
|
|
@@ -112,7 +112,7 @@ import tokens from '@keyfunc/keybricks-ds/tokens.json' // cross-
|
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
Deep imports are the better default in Vue and in any app that cares about tree-shaking —
|
|
115
|
-
a barrel of
|
|
115
|
+
a barrel of 129 exports asks the bundler to prove each one is unused.
|
|
116
116
|
|
|
117
117
|
## 3. Publishing (maintainers)
|
|
118
118
|
|
|
@@ -130,6 +130,12 @@ git push && git push --tags
|
|
|
130
130
|
`.gitlab-ci.yml` then runs: `generated:check` → `version:check` (tag must equal
|
|
131
131
|
`package.json` version) → `npm publish` → `pages`.
|
|
132
132
|
|
|
133
|
+
**Changelog.** Every release gets an entry at the top of `changelog.js` (version, ISO date, and
|
|
134
|
+
items tagged `new` / `improved` / `fixed` / `breaking` / `removed`, each in English, Chinese and
|
|
135
|
+
Japanese). The documentation site renders it as the *Changelog* section under Overview. While a
|
|
136
|
+
version is still being built its entry carries `status: "unreleased"`; on release, drop the status
|
|
137
|
+
and set the date. Migration details stay in `INTEGRATION.md`; the changelog is the short summary.
|
|
138
|
+
|
|
133
139
|
**Versioning policy.** A token's *value* changing is a minor; a token being *renamed or
|
|
134
140
|
removed* is a major, because consumer code references `var(--name)` directly. Adding a
|
|
135
141
|
component or a prop is a minor. Changing a component's default appearance is a major —
|
|
@@ -156,7 +162,7 @@ GitLab injects `CI_JOB_TOKEN` — use that instead and no secret is stored anywh
|
|
|
156
162
|
**Install — straight from git** (no registry, no publish; works today)
|
|
157
163
|
|
|
158
164
|
```json
|
|
159
|
-
"@keyfunc/keybricks-ds": "git+ssh://git@gitlab.epm2demo.cn/Felix/keybricks-ds.git#v2.
|
|
165
|
+
"@keyfunc/keybricks-ds": "git+ssh://git@gitlab.epm2demo.cn/Felix/keybricks-ds.git#v2.4.0"
|
|
160
166
|
```
|
|
161
167
|
|
|
162
168
|
Because the package has no build step, a git dependency needs no `prepare` script — npm
|
|
@@ -202,3 +208,12 @@ consuming app to fail CI on the two rules that break theming:
|
|
|
202
208
|
|
|
203
209
|
Both are the same rule stated twice: components read the semantic layer, and only the
|
|
204
210
|
semantic layer. That is what makes dark mode cost nothing.
|
|
211
|
+
|
|
212
|
+
## Runtime checks
|
|
213
|
+
|
|
214
|
+
`_tests/` holds browser pages that exercise the real components: `react-runtime.html` (the compiled
|
|
215
|
+
bundle), `table-selection.html` (Table loaded from source: checkbox spacing at every width, code chips, two-line rows, sorting), `vue-runtime.html` (the `.vue` files, loaded with vue3-sfc-loader), `cards-interaction*.html`
|
|
216
|
+
(clicks through the documentation demos) and `icon-rules.html` (the Keybricks glyphs against the drawing rules). Serve the repo root (`npx serve .`), open a page and read the
|
|
217
|
+
console — every line starts with PASS or FAIL. Run them after changing a component in either framework.
|
|
218
|
+
`measure-cards.html` is a tool, not a test: it measures each documentation page at its card width so the
|
|
219
|
+
`viewport` sizes in the cards, `site-nav.js` and `gallery.html` can be kept in step.
|
package/DESIGN.md
CHANGED
|
@@ -84,7 +84,7 @@ Never put `--success` (the solid) behind text — use the `-bg` / `-text` pair.
|
|
|
84
84
|
Series walk `--series-1…10` in order; signed values are ALWAYS `--chart-pos` / `--chart-neg`
|
|
85
85
|
(diverging bars, waterfall bridges, deltas, auto sparklines); totals and combo overlay lines are
|
|
86
86
|
`--chart-total`; guides are dashed `--chart-guide`. Lines are straight or monotone-cubic — never
|
|
87
|
-
a spline that overshoots a real value. Numbers are `--font-
|
|
87
|
+
a spline that overshoots a real value. Numbers are `--font-sans` with tabular figures, compact-formatted. Every chart
|
|
88
88
|
answers a hover at every size: a tile-tier chart drops its axes and legend, never its tooltip.
|
|
89
89
|
Geography is data, not a drawing — country outlines come from Natural Earth via d3-geo.
|
|
90
90
|
3D charts are presentation, not analysis: plain SVG painter’s-algorithm rendering, one upper-left
|
|
@@ -99,7 +99,7 @@ feedback colors mean **severity**. Do not mix the two vocabularies.
|
|
|
99
99
|
|
|
100
100
|
## Typography
|
|
101
101
|
|
|
102
|
-
`--font-sans` is Inter. `--font-mono` is Menlo. There is no third family. Under
|
|
102
|
+
`--font-sans` is Inter. `--font-mono` is Menlo, and it is for code only: code blocks, logs, inline code in the docs, and config codes (`FIN_CURRENCY_DEFAULT`), which render as a code chip — Menlo at `--text-code` (12px; 11px in sm; Latin, so not bumped in CJK) on `--bg-inset` with a hairline border (`code: true` on a Table column). Everything else in the interface — IDs, amounts, chart numbers, keyboard keys — is `--font-sans`; numbers that must line up add `font-variant-numeric: tabular-nums`. There is no third family. Under
|
|
103
103
|
`lang="zh" | "ja" | "ko"` the sans stack continues into the system CJK face (PingFang SC /
|
|
104
104
|
Hiragino / Apple SD Gothic Neo on macOS, Microsoft YaHei / Yu Gothic UI / Malgun Gothic on
|
|
105
105
|
Windows, Noto Sans CJK elsewhere); Latin glyphs stay Inter.
|
|
@@ -138,19 +138,144 @@ and menu row is the tier's control text; a `Badge` or `Tag` is its own small obj
|
|
|
138
138
|
exception. In content, a secondary annotation (a timestamp beside a name, a count beside a label)
|
|
139
139
|
may be `--text-xs`. Never put a 14px label and a 12px control on the same baseline.
|
|
140
140
|
|
|
141
|
+
### Count badges on tabs and segments
|
|
142
|
+
|
|
143
|
+
A `Tabs`, `PanelTabs` or `PillTabs` tab, or a `SegmentedControl` option, may carry `count` (`{ label: "Submission", count: 3 }`).
|
|
144
|
+
It renders 6px right of the label as a small full-radius badge: `--count-h` tall (sm 16 · md 18 · lg 20),
|
|
145
|
+
6px sides, **12px tabular figures in the UI font** (digits are Latin, so the size is not bumped in CJK).
|
|
146
|
+
The fill is the alpha wash `--neutral-alpha-8` — it darkens whatever it sits on by the same step, so the
|
|
147
|
+
badge reads on a white tab, on the #f5f5f5 active pill and in dark mode alike (a solid `--bg-hover` vanished on
|
|
148
|
+
the active pill). Selected is told from unselected by the text alone: `--text-heading` vs `--text-body` —
|
|
149
|
+
never `--text-secondary`, which fails 4.5:1 on a grey fill at 12px. Under the blue active underline tab the
|
|
150
|
+
badge stays neutral, so the blue is only the tab's own label and line. A count of 0 or none draws nothing; `showZero` (on the control, or per option) draws a muted
|
|
151
|
+
0 so a filter set keeps its shape. The selected value is still matched by label — a count is decoration,
|
|
152
|
+
never identity. Counts never appear in `iconOnly` segments.
|
|
153
|
+
|
|
154
|
+
### App chrome
|
|
155
|
+
|
|
156
|
+
The shell is `Sidebar` + optional `SidePanel` + `TopBar`, all 56px at the top edge. The rail is 240px (64px
|
|
157
|
+
collapsed), with a 56px brand head without a rule, a 2px-gap list of 36px items and a pinned footer
|
|
158
|
+
(Management, Knowledge Base) above a version line. Items that open a panel (`trailing: true`) carry a
|
|
159
|
+
14px chevron; while a panel is open the rail collapses to its 64px icon form and the panel docks beside
|
|
160
|
+
it at 240px, in the **same tone**. Tones: `recessed` (default — grey rail, the active item is a white tile
|
|
161
|
+
with a hairline ring), `flush` (white rail), `contrast` (rail scoped to the dark theme) and `custom`
|
|
162
|
+
(dark scope on one of ten `SIDEBAR_COLORS`). Pick one tone per product and pass it to both
|
|
163
|
+
`Sidebar` and `SidePanel`. The top bar holds the bare search on the left and, on the right, the dark
|
|
164
|
+
AI Assistant button, notifications, help and the user trigger, which opens `UserMenu` (identity,
|
|
165
|
+
appearance switch, rows).
|
|
166
|
+
|
|
167
|
+
### Menus: action vs single choice
|
|
168
|
+
|
|
169
|
+
`ContextMenu` and `Menu` serve two kinds of list, and the row spacing says which one it is.
|
|
170
|
+
|
|
171
|
+
- **Action menu** (Edit · Duplicate · Delete): no item is selected. Rows are flush (`gap: 0`); only the
|
|
172
|
+
hovered row is filled.
|
|
173
|
+
- **Single-choice menu** (section switcher, language picker): pass `selected: true` on the current item. It
|
|
174
|
+
gets a `--bg-hover` fill and `--weight-medium` `--text-heading` — **no checkmark**, the fill is the
|
|
175
|
+
mark. Rows are announced as `menuitemradio` with `aria-checked`. As soon as any item is selected the
|
|
176
|
+
rows are spaced **2px apart** (`gap: 2px`), the same rhythm as `Sidebar`, `Tree` and `DocTree`, so a
|
|
177
|
+
hovered row's fill never runs into the selected row's fill.
|
|
178
|
+
|
|
179
|
+
Dividers keep their 4px top and bottom margin in both kinds, independent of the row gap. Don't mix the
|
|
180
|
+
two: a menu that both switches state and runs actions puts the actions after a divider, and the choice
|
|
181
|
+
rows still carry `selected`.
|
|
182
|
+
|
|
141
183
|
### Table headers
|
|
142
184
|
|
|
143
185
|
A header cell is the **same size as its data cells**, weight 600, `--text-secondary`, sentence
|
|
144
186
|
case, no letter-spacing. The header is set apart by `--bg-table-header`, never by caps or a
|
|
145
|
-
heavier rule.
|
|
146
|
-
figures — codes and amounts are never a point smaller than the words beside them.
|
|
187
|
+
heavier rule. Amount and ID columns (`mono: true`) keep the row's size, font and colour and add
|
|
188
|
+
only tabular figures; config-code columns (`code: true`) use the code chip — codes and amounts are never a point smaller than the words beside them.
|
|
189
|
+
|
|
190
|
+
### Sortable headers
|
|
191
|
+
|
|
192
|
+
Mark a column `sortable: true` and its header gets a sort button: a muted sm `IconButton` at the
|
|
193
|
+
**right end of the header cell** — the same edge as a two-line row's `⋯`, so the two line up. The label
|
|
194
|
+
keeps its alignment (left, or right for number columns, where it sits 4px before the button).
|
|
195
|
+
|
|
196
|
+
- **Unsorted** — the button appears only while the header is hovered (or holds keyboard focus), icon
|
|
197
|
+
`arrow-up`. It keeps its space while hidden, so the label never shifts.
|
|
198
|
+
- **Click** cycles ascending (`arrow-up`) → descending (`arrow-down`) → unsorted. The tooltip names the
|
|
199
|
+
next step: *Sort ascending* · *Sort descending* · *Clear sorting*.
|
|
200
|
+
- **Sorted** — the button stays without hover and the label turns `--text-heading`; the header carries
|
|
201
|
+
`aria-sort`.
|
|
202
|
+
- **One column at a time.** Clicking another column's button starts it at ascending and clears the first.
|
|
203
|
+
- A long label truncates; the button never shrinks. With `resizable` the button sits inside the cell
|
|
204
|
+
padding, left of the divider, so the two never overlap.
|
|
205
|
+
- Action columns (row ⋯, checkboxes) are never `sortable`, so they show no button.
|
|
206
|
+
|
|
207
|
+
API: `sort` / `onSortChange` control it (`{ key, direction: "asc" | "desc" }` or `null`; Vue
|
|
208
|
+
`v-model:sort`, `@sort-change`); `defaultSort` seeds it uncontrolled. The table reorders rows itself —
|
|
209
|
+
numbers (commas allowed) numerically, text by locale with numeric collation, empty values last — unless
|
|
210
|
+
the column passes `compare(a, b, rowA, rowB)` or the table sets `manualSort` (rows arrive sorted from
|
|
211
|
+
the server). Selection indices and `onRowMore` always refer to the original `rows` order.
|
|
212
|
+
|
|
213
|
+
### Two-line name rows
|
|
214
|
+
|
|
215
|
+
The name column of a document list (folders, models, sheets) is a **two-line title cell**:
|
|
216
|
+
`columns: [{ key: "name", label: "Name", width: 300, twoLine: true }, …]`. Left to right:
|
|
217
|
+
|
|
218
|
+
1. an `IconTile kind="row"` tinted by the row's `hue` (`source` · `join` · `transform` · `merge` ·
|
|
219
|
+
`output`; `neutral` is the grey tile for folders and containers);
|
|
220
|
+
2. two lines of text — the **title** in the tier's control text, `--text-heading`, regular weight, and the
|
|
221
|
+
**description** in `--text-xs`, `--text-secondary`. Each is one line and truncates with an ellipsis. Give the column a `width`; in a tight table it
|
|
222
|
+
shrinks to `minWidth` (default 180px) before the other columns give way;
|
|
223
|
+
3. an sm `⋯` `IconButton` on the right (`onRowMore(row, index, event)`; Vue `@row-more`; `more: false` hides it).
|
|
224
|
+
|
|
225
|
+
An optional 14px **mark** sits right after the title: `mark: "favorite"` is a filled star in `--warning`;
|
|
226
|
+
`{ icon, color, label }` draws any 14px outline icon. Fields default to the row keys `icon`, `hue`,
|
|
227
|
+
`description`, `mark`; pass `twoLine: { icon, hue, description, mark }` with field names or
|
|
228
|
+
`(row, index) => value` accessors to read them from elsewhere.
|
|
229
|
+
|
|
230
|
+
The header stays the tier's bar height; only body rows grow. Every other cell stays vertically centred
|
|
231
|
+
and unchanged. All measures are `--title-cell-*` tier tokens:
|
|
232
|
+
|
|
233
|
+
| | sm | md | lg |
|
|
234
|
+
| --- | --- | --- | --- |
|
|
235
|
+
| Icon tile (`--title-cell-tile`, `-tile-r`) | 28 · r8 | **32 · r8** | 40 · r10 |
|
|
236
|
+
| Icon in the tile (`--title-cell-icon`) | 14 | 16 | 20 |
|
|
237
|
+
| Tile → text (`--title-cell-tile-gap`) | 8 | 12 | 12 |
|
|
238
|
+
| Title | 12 / 16 (13 / 18 CJK) | 14 / 20 | 14 / 20 |
|
|
239
|
+
| Description | 12 / 16 (13 / 18 CJK) | 12 / 16 (13 / 18 CJK) | 12 / 16 (13 / 18 CJK) |
|
|
240
|
+
| Title → description (`--title-cell-gap`) | 2 | 2 | 4 |
|
|
241
|
+
| Row padding top and bottom (`--title-cell-py`) | 8 | 10 | 14 |
|
|
242
|
+
| **Row height** (Latin / CJK) | **50 / 54** | **58 / 60** | **68 / 70** |
|
|
243
|
+
| Header | 36 | 40 | 48 |
|
|
244
|
+
| `⋯` button | sm 28 | sm 28 | sm 28 |
|
|
245
|
+
|
|
246
|
+
**Opening a row.** Pass `onRowOpen(row, index, event)` (Vue `@row-open`) and the icon tile and the title open
|
|
247
|
+
the row: both get the hand cursor, and the title is a keyboard target (Enter / Space). The ⋯ button and the
|
|
248
|
+
expand arrow never open the row. Without the callback nothing in the cell looks clickable.
|
|
249
|
+
|
|
250
|
+
**Tree rows.** Set `tree` on the table and nest rows through `children` — or set `hasChildren: true` on a
|
|
251
|
+
row whose children you load when it opens. The two-line column then indents **24px per level** and reserves a
|
|
252
|
+
**20px arrow slot + 4px** before the tile, so a child's arrow sits exactly under its parent's tile and leaf
|
|
253
|
+
rows line up with folders. The arrow is a muted `chevron-right` (tier icon size) that turns down when
|
|
254
|
+
open, with the `--overlay-hover` wash on hover; rows carry `aria-level` and `aria-expanded`. Expansion
|
|
255
|
+
is `expandedKeys` / `onExpandChange(row, expanded, keys)` (Vue `v-model:expandedKeys`, `@expand-change`),
|
|
256
|
+
or `defaultExpandedKeys` uncontrolled; `rowKey` names the key field (default `id`). Sorting reorders
|
|
257
|
+
siblings only — children stay under their parent. Every index the table reports (selection, `onRowMore`,
|
|
258
|
+
`onRowOpen`) is the row's depth-first position over all rows, expanded or not, so it never moves when the
|
|
259
|
+
user sorts or expands; for a flat table that is simply its position in `rows`.
|
|
260
|
+
|
|
261
|
+
**Labels.** The table draws six words itself — the sort tooltips, ⋯, and the arrow's expand / collapse.
|
|
262
|
+
`labels: { sortAsc, sortDesc, sortClear, more, expand, collapse }` translates them; missing keys fall
|
|
263
|
+
back to English. Pass them in the product's language — a Chinese table with English tooltips is a bug.
|
|
264
|
+
|
|
265
|
+
In sm the title and description are the same size, so the description is told apart by colour alone —
|
|
266
|
+
use sm two-line rows only where the list is dense and short labels are expected.
|
|
147
267
|
|
|
148
268
|
### Chinese, Japanese and Korean
|
|
149
269
|
|
|
150
270
|
Han, kana and Hangul have no capitals and no italics, so emphasis is weight. Under
|
|
151
|
-
`:lang(zh|ja|ko)` the tokens change for you: `--weight-medium`
|
|
152
|
-
|
|
153
|
-
|
|
271
|
+
`:lang(zh|ja|ko)` the tokens change for you: `--weight-medium` and `--weight-semibold` both become
|
|
272
|
+
**500** — square glyphs carry more strokes, so PingFang 600 next to Inter 500 reads a full step bolder —
|
|
273
|
+
and every `--tracking-*` is **0**. (Microsoft YaHei, Meiryo, Yu Gothic UI and Malgun Gothic ship no 500
|
|
274
|
+
face, so on Windows these render Regular; size, colour and the header fill keep the hierarchy.) Below 14px CJK is one step larger than
|
|
275
|
+
Latin — `--text-xs` 13px (leading 18) and `--text-2xs` 12px — so no square glyph renders under
|
|
276
|
+
12px; chart numerals read `--text-2xs-mono` and stay 11px. Text sized from geometry (switch inside text, avatar initials) is floored at `--text-glyph-min`: 11px, 12px in CJK. Inside an sm region `--weight-medium`
|
|
277
|
+
is 400 for CJK, because bold strokes merge at 13px. Simplified and Traditional Chinese, Japanese
|
|
278
|
+
and Korean get the same rule. CJK text is never smaller than the Latin
|
|
154
279
|
text beside it, never letter-spaced and never transformed; a CJK table header or section label
|
|
155
280
|
is emphasised by weight alone. Set `lang` on `<html>`, or on the region when one panel switches
|
|
156
281
|
language — every component re-reads `--font-sans`, so a per-region switch works.
|
|
@@ -175,18 +300,19 @@ so two controls that share a row can never disagree. `md` is the default on `:ro
|
|
|
175
300
|
|
|
176
301
|
| Token | sm | md | lg | Used by |
|
|
177
302
|
| --- | --- | --- | --- | --- |
|
|
178
|
-
| `--control-h` |
|
|
179
|
-
| `--control-text` | 12 | **14** | 14 | text in controls and their labels, table cells |
|
|
303
|
+
| `--control-h` | 28 | **32** | 40 | buttons, inputs, selects, search, steppers, segmented controls, chips, pagination items, menu rows |
|
|
304
|
+
| `--control-text` | 12 (13 CJK) | **14** | 14 | text in controls and their labels, table cells |
|
|
180
305
|
| `--control-icon` | 14 | 16 | 16 | icon inside a control |
|
|
181
306
|
| `--control-px` | 8 | 12 | 16 | horizontal padding of a text control or button |
|
|
182
307
|
| `--control-gap` | 8 | 8 | 8 | inside one group: label → its control, button → button |
|
|
183
308
|
| `--group-gap` | 12 | 16 | 24 | between groups in one bar: field → next field |
|
|
184
|
-
| `--bar-h` |
|
|
185
|
-
| `--bar-card-h` |
|
|
309
|
+
| `--bar-h` | 36 | 40 | 48 | toolbar, filter bar, tab bar, table row, list row |
|
|
310
|
+
| `--bar-card-h` | 44 | 48 | 56 | a bar inside a bordered card (table toolbar, pagination) |
|
|
186
311
|
| `--edge-pad` | 12 | 16 | 16 | card edge → first control or cell |
|
|
187
312
|
| `--cell-px` | 8 | 12 | 16 | horizontal padding of a table cell |
|
|
188
313
|
| `--check-size` | 14 | 16 | 16 | checkbox and radio box |
|
|
189
314
|
| `--tag-h` | 20 | 24 | 28 | `Tag` |
|
|
315
|
+
| `--count-h` | 16 | 18 | 20 | count badge beside a segment / pill label |
|
|
190
316
|
| `--switch-w` × `--switch-h` | 28 × 16 | 36 × 20 | 44 × 24 | `Switch` track |
|
|
191
317
|
|
|
192
318
|
Where each tier belongs:
|
|
@@ -198,18 +324,18 @@ Where each tier belongs:
|
|
|
198
324
|
|
|
199
325
|
Rules:
|
|
200
326
|
|
|
201
|
-
- **One tier per row.** Never a
|
|
327
|
+
- **One tier per row.** Never a 28px icon button beside a 32px input.
|
|
202
328
|
- **Nothing interactive is smaller than 24px.** The former `xs` sizes and `dense` props map to `sm`.
|
|
203
329
|
- A per-control `size` prop only stamps `data-size` on that control. Use it for a control that
|
|
204
330
|
stands alone in its band — never to "fix" one control inside a bar.
|
|
205
331
|
- Text inside a control is `--control-text`, not `--text-xs` because it looks tidier.
|
|
206
|
-
- `--h-button` and `--h-input` are aliases of `--control-h`; `--h-button-sm` is
|
|
332
|
+
- `--h-button` and `--h-input` are aliases of `--control-h`; `--h-button-sm` is 28px. Prefer the
|
|
207
333
|
tier tokens in new code.
|
|
208
334
|
|
|
209
335
|
### Button emphasis — pick the variant, never the size
|
|
210
336
|
|
|
211
337
|
The tier says how dense a region is; the **variant** says how important an action is. Never
|
|
212
|
-
shrink a button to make it feel lighter: a
|
|
338
|
+
shrink a button to make it feel lighter: a 28px button beside 32px controls and 14px text reads
|
|
213
339
|
as a mistake on a calm page, and the tier rule above forbids it anyway. Reach for a quieter
|
|
214
340
|
variant instead.
|
|
215
341
|
|
|
@@ -267,7 +393,9 @@ Nothing bounces. Nothing slides more than a few pixels. Keyframes available:
|
|
|
267
393
|
|
|
268
394
|
- **Hover** — every pointer target answers it, one step at a time:
|
|
269
395
|
filled and boxed buttons, menu rows, list rows, nav and tree items, segments → one surface step
|
|
270
|
-
(`--bg-hover`, `--action-primary-hover`, `--soft-hover`);
|
|
396
|
+
(`--bg-hover`, `--action-primary-hover`, `--soft-hover`); a borderless `IconButton` → the alpha
|
|
397
|
+
overlay `--overlay-hover` (press `--overlay-press`), because it sits on white rows, grey table headers
|
|
398
|
+
and grey bars alike and a solid `--bg-hover` disappears on `--bg-table-header`; field boxes (inputs, selects, date,
|
|
271
399
|
combobox, multi-select, search, stepper) → border `--border-control` to `--border-strong`;
|
|
272
400
|
text-only controls (inactive tabs, legend items, clear ×, copy) → ink to `--text-heading`;
|
|
273
401
|
table body rows → `--bg-inset`; checkbox and radio rings → `--text-muted`; switch tracks →
|
|
@@ -320,22 +448,22 @@ The list that prevents the most rework. These are absolute.
|
|
|
320
448
|
- **Do not mix size tiers in one row.** The region declares `data-size`; the controls inherit. A
|
|
321
449
|
`size` prop on one control inside a bar is a bug, not a fix.
|
|
322
450
|
- **Do not shrink, letter-space or uppercase Chinese, Japanese or Korean text.** Under `lang`
|
|
323
|
-
the emphasis weight is
|
|
451
|
+
the emphasis and heading weight is 500 (medium 400 at sm), tracking is 0, and sizes under 14px step up by one — that is the whole CJK rule.
|
|
324
452
|
- **Do not put dark text on a saturated fill.** `--on-accent` (white) is the only option,
|
|
325
453
|
in both themes — this is why the dark-mode primary button keeps white text.
|
|
326
454
|
- **Do not scale or shift elements on press.** Press is a color step only.
|
|
327
455
|
- **Do not show a drop indicator where the drop is impossible.** No half-row boxes on a
|
|
328
456
|
container, no insert rules on a node that can't take children.
|
|
329
457
|
- **Do not build a new primitive when one exists.** Check the component index in
|
|
330
|
-
`INTEGRATION.md` first — there are
|
|
331
|
-
- **Do not use emoji as icons.** Use `<Icon name="..." />` (
|
|
458
|
+
`INTEGRATION.md` first — there are 120.
|
|
459
|
+
- **Do not use emoji as icons.** Use `<Icon name="..." />` (330 glyphs) or `<Unicon>` (1,206).
|
|
332
460
|
- **Do not invent new component variants.** If `Button` lacks the variant you want, that is a
|
|
333
461
|
design-system request, not a local override.
|
|
334
462
|
- **Do not stack two primary buttons.** One primary action per view; everything else is
|
|
335
463
|
`outline`, `ghost`, or `text`.
|
|
336
464
|
- **Do not use full-uppercase text.** Table headers and section labels are sentence case, weight
|
|
337
|
-
600, tracking 0 — the same size as the text they label. (
|
|
338
|
-
|
|
465
|
+
600, tracking 0 — the same size as the text they label. (This site's own card labels follow the
|
|
466
|
+
same rule: 12px, sentence case.)
|
|
339
467
|
- **Do not animate anything longer than 360ms** or with a bounce/elastic easing.
|
|
340
468
|
|
|
341
469
|
---
|
package/INTEGRATION.md
CHANGED
|
@@ -31,7 +31,7 @@ Not using a registry yet? A git dependency works with no publishing at all — t
|
|
|
31
31
|
has no build step, so npm can use the checkout as-is:
|
|
32
32
|
|
|
33
33
|
```json
|
|
34
|
-
"@keyfunc/keybricks-ds": "git+ssh://git@gitlab.epm2demo.cn/Felix/keybricks-ds.git#v2.
|
|
34
|
+
"@keyfunc/keybricks-ds": "git+ssh://git@gitlab.epm2demo.cn/Felix/keybricks-ds.git#v2.4.0"
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
**Source-only package.** `.jsx` and `.vue` files are published as authored, so your
|
|
@@ -98,7 +98,7 @@ import Textarea from '@keyfunc/keybricks-ds/components/forms/Textarea.vue'
|
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
That is the whole integration. The `data-size="lg"` on the form is the size tier — every control
|
|
101
|
-
inside it is
|
|
101
|
+
inside it is 40px tall; leave it off and they are the app default, 32px (see *Size tiers* below).
|
|
102
102
|
Everything below is reference material.
|
|
103
103
|
|
|
104
104
|
---
|
|
@@ -136,9 +136,9 @@ properties — `--control-h`, `--control-text`, `--control-icon`, `--control-px`
|
|
|
136
136
|
A **region** sets them with one attribute:
|
|
137
137
|
|
|
138
138
|
```html
|
|
139
|
-
<div data-size="sm">…</div> <!--
|
|
139
|
+
<div data-size="sm">…</div> <!-- 28px controls · 12px text (13px CJK) · 36px rows — dense grids, pipeline nodes -->
|
|
140
140
|
<div data-size="md">…</div> <!-- 32px controls · 14px text · 40px rows — the app default (:root) -->
|
|
141
|
-
<div data-size="lg">…</div> <!--
|
|
141
|
+
<div data-size="lg">…</div> <!-- 40px controls · 14px text · 48px rows — dialogs, short forms -->
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
Put `data-size` on the toolbar, filter bar, form, table or panel and leave the controls' `size`
|
|
@@ -162,7 +162,7 @@ Text, weight and tracking follow the tier through `--control-text` / `--control-
|
|
|
162
162
|
weight becomes 600 and all tracking is 0 — nothing to configure. `DESIGN.md` has the full token
|
|
163
163
|
table and the rules behind it.
|
|
164
164
|
|
|
165
|
-
## Component index (
|
|
165
|
+
## Component index (120 components)
|
|
166
166
|
Import path is `@keyfunc/keybricks-ds/components/<group>/<Name>.jsx` (React) or `.vue` (Vue 3).
|
|
167
167
|
Every component has a sibling `.d.ts` with its full props contract, and each group has a
|
|
168
168
|
`.prompt.md` with usage notes.
|
|
@@ -180,8 +180,11 @@ components (`Input.jsx` exports `Input` and `Textarea`; `Badge.jsx` exports `Bad
|
|
|
180
180
|
cannot export values, so on the Vue side every such secondary is its own file with a default
|
|
181
181
|
export — `Textarea.vue`, `IconTile.vue`, `StatusBadge.vue`, `Tooltip.vue`, `ToastStack.vue`, `Port.vue`, `PortLabel.vue`, `ChartLegend.vue`, `ChartTooltip.vue`, `PlotGrid.vue`, `XLabels.vue`, `ButtonGroup.vue`, `StatCard.vue`, `Toast.vue`,
|
|
182
182
|
`Spinner.vue`, `PageHeading.vue`, and so on — always named exactly as the React export.
|
|
183
|
-
Shared non-component values live in plain modules: `
|
|
184
|
-
`
|
|
183
|
+
Shared non-component values live in plain modules: `navigation/nav-model.js` (`KEYBRICKS_NAV`),
|
|
184
|
+
`navigation/theme-store.js` (`applyStoredTheme`), `pipeline/pipeline-catalog.js` (`PIPELINE_CATALOG`),
|
|
185
|
+
`icons/icon-paths.js`, `icons/feather-paths.js` — all five are also exported from
|
|
186
|
+
`@keyfunc/keybricks-ds/vue` — plus the internal helpers `forms/input-base.js` (`inputBase`),
|
|
187
|
+
`pipeline/port-skin.js` (`portSkin`) and `px.js` (`px`).
|
|
185
188
|
|
|
186
189
|
```js
|
|
187
190
|
// React
|
|
@@ -235,7 +238,9 @@ import Textarea from '@keyfunc/keybricks-ds/components/forms/Textarea.vue'
|
|
|
235
238
|
| Component | What it's for |
|
|
236
239
|
| --- | --- |
|
|
237
240
|
| `Sidebar` | The app's primary nav: collapsible sections, active state, footer items. `KEYBRICKS_NAV` is the product's real nav tree. |
|
|
241
|
+
| `SidePanel` | 240px panel docked beside the sidebar (Documents, Management), in the rail's tone. |
|
|
238
242
|
| `TopBar` | Global header — search, notifications, theme toggle, avatar. |
|
|
243
|
+
| `UserMenu` | Account menu from the top bar's user trigger: identity, appearance switch, rows. |
|
|
239
244
|
| `PageHeading` | Page title with optional subtitle and right-aligned actions. |
|
|
240
245
|
| `PageToolbar` | Secondary bar under the heading: filters, view toggles, bulk actions. |
|
|
241
246
|
| `Breadcrumb` | Path trail; collapses to an ellipsis dropdown past `maxItems`. |
|
|
@@ -246,9 +251,10 @@ import Textarea from '@keyfunc/keybricks-ds/components/forms/Textarea.vue'
|
|
|
246
251
|
### `tabs/` — switching views
|
|
247
252
|
| Component | What it's for |
|
|
248
253
|
| --- | --- |
|
|
249
|
-
| `Tabs` | Page-level underline tabs. |
|
|
250
|
-
| `PanelTabs` | Compact tabs inside a detail panel or drawer. |
|
|
251
|
-
| `PillTabs` | Filter/status tabs as pills. |
|
|
254
|
+
| `Tabs` | Page-level underline tabs; `{ label, count }` adds a count badge. |
|
|
255
|
+
| `PanelTabs` | Compact tabs inside a detail panel or drawer; `{ label, count }` adds a count badge. |
|
|
256
|
+
| `PillTabs` | Filter/status tabs as pills; `{ label, count }` adds a count badge. |
|
|
257
|
+
| `CountBadge` | The count badge beside a segment / pill label (`--count-h`, 12px tabular figures); used by `SegmentedControl` and `PillTabs`, exported for custom filter bars. |
|
|
252
258
|
| `SegmentedControl` | Switches views of the same data, applies instantly — not a saved form value (`RadioGroup`) and not page navigation (`Tabs`). Reads the size tier, `icon` per option, `iconOnly`, per-option or whole-control `disabled`, `fullWidth`. ← → keyboard. |
|
|
253
259
|
| `ViewToggle` | List/grid icon toggle. |
|
|
254
260
|
|
|
@@ -287,7 +293,7 @@ import Textarea from '@keyfunc/keybricks-ds/components/forms/Textarea.vue'
|
|
|
287
293
|
### `icons/` — iconography
|
|
288
294
|
| Component | What it's for |
|
|
289
295
|
| --- | --- |
|
|
290
|
-
| `Icon` |
|
|
296
|
+
| `Icon` | 330 stroke glyphs: the 83-glyph core set plus all of Feather (on a shared name the core glyph wins). `<Icon name="download" size={16} />` |
|
|
291
297
|
| `Unicon` | 1,206 additional Unicons line glyphs, loaded from CDN. Use when `Icon` has no match. |
|
|
292
298
|
|
|
293
299
|
### `pipeline/` — the data-pipeline editor
|
|
@@ -487,7 +493,7 @@ a migration note in the release. Token renames are major because your own code r
|
|
|
487
493
|
Pin a minor range and update deliberately:
|
|
488
494
|
|
|
489
495
|
```json
|
|
490
|
-
"@keyfunc/keybricks-ds": "~2.
|
|
496
|
+
"@keyfunc/keybricks-ds": "~2.4.0"
|
|
491
497
|
```
|
|
492
498
|
|
|
493
499
|
### Migrating from 1.x to 2.0
|
|
@@ -513,6 +519,85 @@ Pin a minor range and update deliberately:
|
|
|
513
519
|
- **Tokens outside CSS.** `tokens.json` / `tokens.js` / `tokens.d.ts` gained the tier tokens
|
|
514
520
|
(`--control-*`, `--bar-h`, `--group-gap`, …) — 352 light tokens in all (2.0.2 adds `--danger-soft-hover`).
|
|
515
521
|
|
|
522
|
+
### 2.4.0
|
|
523
|
+
|
|
524
|
+
- **App Chrome matches the product.** `Sidebar`: 56px brand head without a rule, `--text-md` brand, a 2px-gap list, `trailing: true` items with a chevron (they open a side panel), Collapse / Expand item (chevron-left / panel-left), pinned footer and an optional `version` line. New `tone` prop — `"recessed"` (grey rail, active item a white tile with a hairline ring; **the new default**), `"flush"` (the old white look), `"contrast"` (dark-scoped rail), `"custom"` + `color` (`SIDEBAR_COLORS` or any hex). `KEYBRICKS_NAV` is the product's nav (Home … Task Execution); new `KEYBRICKS_NAV_FOOTER` (Management, Knowledge Base) is the default footer (was Help / Settings / Dark Mode) and `KEYBRICKS_MGMT` holds the Management panel groups. To keep the old look pass `tone="flush"` and your own `footerItems`.
|
|
525
|
+
- **Data-source logos:** 17 logo images (databases, SAP, protocols, file types) in `assets/logos/datasource/<id>.png`, 500×500 PNG, listed on the new *Data Source Logos* icons page. They are plain images, not `Icon` glyphs — use them with `<img>`.
|
|
526
|
+
- **New `SidePanel`**: the 240px panel docked beside the sidebar (Documents, Management), same tone as the rail, opens from 0 width with a fade; 56px header with title, actions and close.
|
|
527
|
+
- **`TopBar`**: dark **AI Assistant** (`ai` icon) first, then notifications and help `IconButton`s, then a user trigger (`user={{ name, email }}`) that opens a menu. The bell is no longer `lg`. **New `UserMenu`**: avatar, name, email, an Appearance row (icon-only light / dark / system) and menu rows.
|
|
528
|
+
|
|
529
|
+
- **`ContextMenu` / `Menu` single-choice state.** Items accept `selected: true` (section switcher, language picker): `--bg-hover` fill, `--weight-medium` `--text-heading`, no checkmark; rows become `menuitemradio` with `aria-checked`. When any item is selected the rows are spaced 2px apart (as in `Sidebar`, `Tree`, `DocTree`); action menus with nothing selected keep flush rows. Dividers keep 4px above and below.
|
|
530
|
+
|
|
531
|
+
- **Docs:** new *Icon Usage* page at the top of Icons (monochrome vs coloured glyphs: IconTile hues, Tree/DocTree document hues, status, marks). The documentation site itself now follows the system rules — neutral selected segments, sentence-case labels, sm-tier toolbar controls, 32px Sidebar-spec nav rows.
|
|
532
|
+
### 2.3.2
|
|
533
|
+
|
|
534
|
+
- **Counts on `Tabs`, `PanelTabs`, `PillTabs` and `SegmentedControl`.** Tabs / options accept `{ label, count?, showZero? }`; a count renders as a `CountBadge` 6px right of the label — `--count-h` tall (new tier token: sm 16 · md 18 · lg 20), 6px sides, full radius, 12px tabular figures; fill `--neutral-alpha-8` on any surface, text `--text-body`, `--text-heading` when selected. 0 or no count hides it; `showZero` (control or option) draws a muted 0. Selection is still matched by label. `CountBadge` is exported (React `Tabs.jsx`, Vue `CountBadge.vue`).
|
|
535
|
+
- Additive only.
|
|
536
|
+
|
|
537
|
+
### 2.3.1
|
|
538
|
+
|
|
539
|
+
- **`Table` row open, tree rows and labels.** `onRowOpen(row, index, event)` (Vue `@row-open`) makes the icon tile and title of a two-line cell open the row (hand cursor; Enter / Space on the title). `tree` with nested `children` (or `hasChildren` for lazy rows) indents the two-line column 24px per level with an expand arrow — `expandedKeys` / `defaultExpandedKeys` / `onExpandChange(row, expanded, keys)` (Vue `v-model:expandedKeys`, `@expand-change`), `rowKey` (default `id`); sorting reorders siblings only. `labels: { sortAsc, sortDesc, sortClear, more, expand, collapse }` translates every word the table draws (English by default). Indices reported by selection and callbacks are depth-first over all rows — unchanged for flat tables.
|
|
540
|
+
- Additive only: flat tables, existing props and indices behave exactly as in 2.3.0.
|
|
541
|
+
|
|
542
|
+
### 2.3.0
|
|
543
|
+
|
|
544
|
+
- **sm and lg size tiers.** sm controls are **28px** (was 24) with 36px rows and bars (was 32);
|
|
545
|
+
lg controls are **40px** (was 36) with 48px rows (was 44); md is unchanged. 24px sat at the
|
|
546
|
+
floor of the industry range and left the segmented control's segments 18px tall; 36 was only
|
|
547
|
+
4px above md, where Ant Design, Fluent 2, Primer and shadcn all step to 40. sm text stays 12px
|
|
548
|
+
for Latin. Layouts built on the tier tokens follow automatically; anything you sized by hand to
|
|
549
|
+
sit beside an sm or lg control should be re-checked.
|
|
550
|
+
- **CJK small sizes are one step larger.** Under `lang="zh" | "ja" | "ko"` (Simplified and
|
|
551
|
+
Traditional Chinese alike) `--text-xs` / `--text-sm` are 13px with 18px leading and
|
|
552
|
+
`--text-2xs` is 12px, so no CJK text renders below 12px. 14px and up are unchanged. In sm
|
|
553
|
+
regions the CJK medium weight is 400. Outside sm, CJK `--weight-medium` and `--weight-semibold` are both 500 (they were 600): at the same number, CJK glyphs read heavier than Latin, so 600 looked a step bolder than English and erased the difference between labels and headers. On Windows (no 500 face in YaHei / Meiryo / Malgun) both render Regular. Chart numerals use the new `--text-2xs-mono`
|
|
554
|
+
(11px in every language).
|
|
555
|
+
- `Table` selection: the checkbox now sits in the first column's leading space instead of a column of its own. Both sides of the checkbox now equal the edge padding (16px; 12px in sm), so the box sits evenly between the card edge and the first column's text and stays aligned with card titles and toolbars. Before, the gap was 40px and grew with the table width when columns declared widths (up to ~120px). If you styled the old selection cell (`td:first-child` holding only the checkbox), move that styling to the first data cell.
|
|
556
|
+
- **`Table` two-line name rows**: a `twoLine` column renders an `IconTile` (kind "row", tinted by `hue`; `neutral` = grey), a title over a description (each one line, truncated), an optional 14px mark (`"favorite"` = filled star in `--warning`) and a trailing sm `⋯` (`onRowMore(row, index, event)`, Vue `@row-more`). md rows are 58px (sm 50 · lg 68; CJK 54 · 60 · 70); the header keeps the bar height. New tier tokens `--title-cell-py`, `--title-cell-gap`, `--title-cell-tile`, `--title-cell-icon`, `--title-cell-tile-r`, `--title-cell-tile-gap`. `IconTile kind="row"` is now tinted when you pass `hue` (unchanged without it), adds `hue="neutral"` and an `iconStyle` prop.
|
|
557
|
+
- **`Table` sortable headers**: `sortable: true` on a column adds a muted sm sort button at the header cell's right end (in line with a two-line row's `⋯`) — on hover while unsorted (`arrow-up`), kept while sorted (`arrow-up` / `arrow-down`, label `--text-heading`, `aria-sort`). Click cycles ascending → descending → none; one column at a time; tooltips *Sort ascending* / *Sort descending* / *Clear sorting*. New props `sort`, `defaultSort`, `onSortChange` (Vue `v-model:sort`, `@sort-change`), `manualSort`; column `compare`. Selection indices keep referring to the original `rows` order.
|
|
558
|
+
- `IconButton` hover and press are now alpha overlays (`--overlay-hover`, `--overlay-press`) instead of the solid `--bg-hover` / `--bg-press`. On white they are the same colour as before; on a grey surface (table header, toolbar) the hover is now visible instead of matching the background. `--overlay-press` is 12% (was 8%, unused) and the dark theme gets its own overlay values (8% / 16%).
|
|
559
|
+
- **Fix — `Table` `code` columns:** only text and number values get the code chip; an element in the cell (a `Skeleton` while loading, a link) renders as is. Before, a loading row in a code column drew a chip around the skeleton and grew to about 50px.
|
|
560
|
+
- **Two AI glyphs join the core icon set**: `ai` (rounded frame, open at the top-right, with a large and a small four-point star) and `ai-sparkles` (a large and a small four-point star). Both are traced from the reference glyphs and redrawn to the core-set rules: stroke 2 with no fill, integer endpoints, at least 2px clear between separate elements. The core set is 83 glyphs; `Icon` resolves 330 names. Search terms: ai, assistant, copilot, agent, intelligent, generative, sparkles, magic.
|
|
561
|
+
- `Pagination`: page items and prev/next lose their border (GitHub Primer / Atlassian style). The current page takes the neutral selected fill (`--bg-active`, weight 600) instead of the action blue — it is a state, not an action; the others are plain until hovered. Size is unchanged — items stay control-height (32px at md).
|
|
562
|
+
- The monospace font is now for code only (`CodeBlock`, `LogViewer`, code in the docs). `Table`/`SmartTable` `mono` columns, `KeyValue` and `DiffValue` `mono`, `Spreadsheet` numbers and formula bar, `Kbd`, the `Input`/`Textarea` counter, the `Slider` value and every chart number now use `--font-sans` with tabular figures; `mono` columns also take the normal text colour. The `mono` props and the `--text-2xs-mono` token keep their names. Config codes get a new column option, `code: true`: a code chip — Menlo at the new `--text-code` / `--leading-code` (12/18px, 11/16px in sm, not bumped in CJK) on `--bg-inset` with a hairline border. Switch config-code columns from `mono` to `code`.
|
|
563
|
+
- `Table` column separators (the resize handles in the header) are one step darker: new token `--border-split` — `#D4D4D4` light, `#404040` dark (was `--border-control`, #E5E5E5 / #333333). Hover and drag still turn them blue.
|
|
564
|
+
- New tokens: `--text-2xs-mono` and `--text-glyph-min` (11px, 12px in CJK) — the floor for text that is sized from geometry: `Switch` inside/knob text and `Avatar` initials no longer drop to 9–10px. `--h-button-sm` is 28px.
|
|
565
|
+
- Removed the `ui_kits/keybricks-app` product recreation and the `templates/web-app` starter: the
|
|
566
|
+
production designs now live in their own projects. No component or token is affected.
|
|
567
|
+
- **Fix — React entry:** `applyStoredTheme` was documented but missing from
|
|
568
|
+
`@keyfunc/keybricks-ds` (the barrel generator skipped lower-case names). It is exported now.
|
|
569
|
+
- **Fix — Vue entry:** `KEYBRICKS_NAV` and `applyStoredTheme` existed for Vue only as comments.
|
|
570
|
+
They now live in `navigation/nav-model.js` and `navigation/theme-store.js`, which React re-exports
|
|
571
|
+
and `@keyfunc/keybricks-ds/vue` exports directly, along with `PIPELINE_CATALOG`, `VUE_ICON_PATHS`
|
|
572
|
+
and `FEATHER_PATHS` — one source for both frameworks.
|
|
573
|
+
- **Fixes — Vue matched to React** (found by a token-by-token and prop-by-prop audit of every
|
|
574
|
+
React/Vue pair): `Tree` keyboard focus ring uses `--focus-border` (was `--focus-ring`) and now
|
|
575
|
+
accepts `treeData`, `expandedKeys`, `selectedKeys`, `checkedKeys`; `Switch` accepts
|
|
576
|
+
`inlinePrompt`; `Timeline` title and meta carry their line-height and tracking (CJK meta now
|
|
577
|
+
gets its 18px leading); `Spreadsheet` column headers carry `--tracking-xs`; `SmartTable` URL
|
|
578
|
+
cells use `--link`; `FunnelChart` bands animate width; `WaterfallChart` shows the hover band.
|
|
579
|
+
`BulletChart` range bands use `--neutral-alpha-12` in both frameworks (theme-aware; was a
|
|
580
|
+
hard-coded black in Vue and an undefined token in React).
|
|
581
|
+
- Sidebar nav model (`KEYBRICKS_NAV`): Reconciliation uses the `reconciliation` icon and
|
|
582
|
+
Consolidation the `consolidation` icon; the Management › Reconciliation entry no longer reuses
|
|
583
|
+
`network`.
|
|
584
|
+
- Component cards share one specimen layout (label column, 12px sentence-case labels) and every
|
|
585
|
+
size-tier demo shows a Latin row and a CJK row.
|
|
586
|
+
|
|
587
|
+
### 2.2.0
|
|
588
|
+
|
|
589
|
+
- **Eleven Keybricks glyphs join the core icon set** — `<Icon name="journal" />` in React and
|
|
590
|
+
Vue alike. Modules: `reconciliation`, `consolidation`, `journal`, `event`, `view-tree`.
|
|
591
|
+
Actions: `drilldown`, `add-below`, `copy-data`, `task-execution`, `time-future`,
|
|
592
|
+
`time-restatement`. Each was checked against the core-set drawing rules, now written down in
|
|
593
|
+
the Iconography section of `readme.md`; six were redrawn to meet them (paths inside 2–22,
|
|
594
|
+
integer coordinates, 2px between separate elements, rx 1 on small rects, true circular
|
|
595
|
+
corners). The core set is now 81 glyphs; with Feather, `Icon` resolves 328 names.
|
|
596
|
+
- Two submitted glyphs were already in the library and were not duplicated: *hierarchy* is
|
|
597
|
+
`layers` and *change* is Feather's `repeat`. Both words now find them in the icon search.
|
|
598
|
+
- The docs gave the icon total as 362. That counted the 40 names Feather shares with the core
|
|
599
|
+
set twice; the number of distinct names is now 328.
|
|
600
|
+
|
|
516
601
|
### 2.1.1
|
|
517
602
|
|
|
518
603
|
- **Chart series palette replaced** (`--series-1…8`, light and dark). One lightness band, a chroma
|
|
@@ -570,18 +655,6 @@ Pin a minor range and update deliberately:
|
|
|
570
655
|
|
|
571
656
|
Release mechanics, the CI pipeline and the Pages site are documented in `DEPLOY.md`.
|
|
572
657
|
|
|
573
|
-
## Templates
|
|
574
|
-
|
|
575
|
-
A template is a ready-made screen you copy into a new project as a starting point, rather than a
|
|
576
|
-
component you import. Each lives in `templates/<slug>/`.
|
|
577
|
-
|
|
578
|
-
| Template | What you get |
|
|
579
|
-
| --- | --- |
|
|
580
|
-
| `templates/web-app/` | The full app shell: sidebar with the real nav model, top bar, page heading, stat tiles and a data table. |
|
|
581
|
-
|
|
582
|
-
Copy the folder, then edit one line — the `base` in `ds-base.js` — to point at wherever the design
|
|
583
|
-
system sits relative to the copied page.
|
|
584
|
-
|
|
585
658
|
## Getting help
|
|
586
659
|
|
|
587
660
|
- **Documentation site** — the GitLab Pages build: `index.html` for the browsable system
|
package/SKILL.md
CHANGED
|
@@ -4,30 +4,30 @@ description: Use this skill to generate well-branded interfaces and assets for K
|
|
|
4
4
|
user-invocable: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Read the
|
|
7
|
+
Read the readme.md file within this skill, and explore the other available files. This skill's documentation is bilingual (English / 中文)。
|
|
8
8
|
|
|
9
9
|
Key facts / 关键信息: Keybricks is a near-monochrome, hairline-bordered, 14px-Inter enterprise UI with one action blue (#155dfc, dark mode #1f6feb), five node-category hues, and a signature node-pipeline editor.
|
|
10
10
|
(Keybricks 是一个近乎单色、细边框、以 14px Inter 为主的企业级界面,仅有一个强调蓝(浅色 #155dfc / 深色 #1f6feb)、五种节点分类色,以及标志性的数据管道编辑器。)
|
|
11
|
-
Tokens live in `tokens/*.css` (linked via `styles.css`, includes `tokens/dark.css` for dark mode and `tokens/motion.css` for motion); React components in `components/<group>/` (each with a `.d.ts` contract
|
|
12
|
-
(设计令牌位于 `tokens/*.css`(经 `styles.css` 汇总,含深色模式 `tokens/dark.css` 与动效 `tokens/motion.css`);React 组件位于 `components
|
|
11
|
+
Tokens live in `tokens/*.css` (linked via `styles.css`, includes `tokens/dark.css` for dark mode and `tokens/motion.css` for motion); React and Vue 3 components in `components/<group>/` (each React file with a `.d.ts` contract; each group with a `.prompt.md` usage note).
|
|
12
|
+
(设计令牌位于 `tokens/*.css`(经 `styles.css` 汇总,含深色模式 `tokens/dark.css` 与动效 `tokens/motion.css`);React 与 Vue 3 组件位于 `components/<分组>/`(React 文件附 `.d.ts` 类型定义,每个分组附 `.prompt.md` 用法说明)。)
|
|
13
13
|
|
|
14
14
|
If creating visual artifacts (slides, mocks, throwaway prototypes, etc), copy assets out and create static HTML files for the user to view. If working on production code, you can copy assets and read the rules here to become an expert in designing with this brand.
|
|
15
15
|
|
|
16
16
|
If the user invokes this skill without any other guidance, ask them what they want to build or design, ask some questions, and act as an expert designer who outputs HTML artifacts _or_ production code, depending on the need.
|
|
17
17
|
|
|
18
18
|
Rules of thumb / 要点速览:
|
|
19
|
-
- Inter 14px/400 is the default; 500 for nav/headings/labels; 600 for node & panel titles and table headers; 300 only for big numerals. Menlo for
|
|
20
|
-
(Inter 14px/常规 为默认;500 用于导航/标题/标签;600 用于节点与面板标题及表头;300
|
|
21
|
-
- One size tier per region: `data-size="sm" | "md" | "lg"` =
|
|
22
|
-
(每个区域只用一档尺寸:`data-size="sm" | "md" | "lg"` 对应
|
|
19
|
+
- Inter 14px/400 is the default; 500 for nav/headings/labels; 600 for node & panel titles and table headers; 300 only for big numerals. Menlo only for code — CodeBlock, LogViewer and config-code chips; amounts and IDs stay in Inter with tabular figures. In Chinese/Japanese/Korean, 500 and 600 both become 500, tracking is 0, and text below 14px is one step larger (12→13, 11→12).
|
|
20
|
+
(Inter 14px/常规 为默认;500 用于导航/标题/标签;600 用于节点与面板标题及表头;300 仅用于大号数字。Menlo 只用于代码——代码块、日志和配置代码标签;金额与编号仍用 Inter 等宽数字。中/日/韩文中 500 与 600 都改为 500(同字重下方块字更显粗),字距为 0,14px 以下的字号比英文大一档(12→13、11→12)。)
|
|
21
|
+
- One size tier per region: `data-size="sm" | "md" | "lg"` = 28 / 32 / 40px controls (rows and bars 36 / 40 / 48). Set it on the bar, form, table or dialog; controls inherit. Never mix heights or text sizes in one row; nothing interactive under 24px.
|
|
22
|
+
(每个区域只用一档尺寸:`data-size="sm" | "md" | "lg"` 对应 28 / 32 / 40px 控件(行与工具栏 36 / 40 / 48)。设在工具栏、表单、表格或对话框上,控件自动继承。同一行不混用高度或字号;可交互元素不小于 24px。)
|
|
23
23
|
- Backgrounds: app #fafafa, surfaces white, hairline borders rgba(229,229,229,.6); shadows only on canvas nodes.
|
|
24
24
|
(背景:应用层 #fafafa,卡片层白色,细边框;仅画布节点有阴影。)
|
|
25
25
|
- One blue CTA per view; ghost text buttons beside it. Color only for meaning (category hues, status).
|
|
26
26
|
(每个界面只有一个蓝色主按钮,旁边配文字按钮;颜色只用于表达含义。)
|
|
27
|
-
- Icons: Lucide stroke
|
|
28
|
-
(图标统一用 Icon
|
|
29
|
-
- Radii: 4
|
|
30
|
-
(圆角:4px
|
|
27
|
+
- Icons: the Icon component — Lucide stroke glyphs plus the Keybricks glyphs drawn to the same rules (`ai`, `ai-sparkles`, module icons) — never emoji, never ad-hoc SVG.
|
|
28
|
+
(图标统一用 Icon 组件:Lucide 线性图标,加上按同一规范绘制的 Keybricks 图标(`ai`、`ai-sparkles`、模块图标)——禁止 emoji,禁止临时手绘 SVG。)
|
|
29
|
+
- Radii: 4 checkboxes · 8 buttons/inputs/row icon tiles · 10 cards · 14/16 tiles & nodes · full circles.
|
|
30
|
+
(圆角:4px 复选框、8px 按钮/输入框/行内图标块、10px 卡片、14/16px 图标块与节点、端口/胶囊全圆角。)
|
|
31
31
|
- Copy: Title Case labels, imperative verb-first buttons ("Run Test", "Mark as New"), terse technical vocabulary.
|
|
32
32
|
(文案:标签用词首大写,按钮用祈使动词开头,术语简洁精确。)
|
|
33
33
|
- Dark mode: set `<html data-theme="dark">`. Style only via semantic tokens (`--bg-surface`, `--text-body`, `--border-card`, `--track`, `--soft-bg`, `--info-bg`, `--on-accent`, `--ring-surface`) — never raw `--neutral-*`/`--blue-*` — and both themes work automatically.
|