@keyfunc/keybricks-ds 1.0.4 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEPLOY.md +4 -4
- package/DESIGN.md +154 -53
- package/INTEGRATION.md +174 -35
- package/SKILL.md +6 -4
- package/_adherence.oxlintrc.json +164 -68
- package/_scripts/build-index.mjs +9 -0
- package/_scripts/build-tokens.mjs +5 -2
- package/assets/icons/icon-index.js +1 -1
- package/assets/icons/icon-index.json +1 -1
- package/components/_cards/accordion.card.html +2 -2
- package/components/_cards/action-chip.card.html +8 -3
- package/components/_cards/activity.card.html +2 -2
- package/components/_cards/alert.card.html +2 -2
- package/components/_cards/app-chrome.card.html +4 -4
- package/components/_cards/banner.card.html +1 -1
- package/components/_cards/breadcrumb.card.html +2 -2
- package/components/_cards/button-1-base.card.html +2 -2
- package/components/_cards/button-2-states.card.html +14 -14
- package/components/_cards/button-3-sizes-icons.card.html +1 -1
- package/components/_cards/button-4-group.card.html +5 -5
- package/components/_cards/canvas-zoom-controls.card.html +1 -1
- package/components/_cards/cards-indicators.card.html +2 -2
- package/components/_cards/charts-1-sparkline.card.html +2 -2
- package/components/_cards/charts-10-gauge.card.html +4 -4
- 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 +1 -1
- package/components/_cards/charts-15-distribution.card.html +1 -1
- 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 +2 -2
- package/components/_cards/charts-20-sunburst.card.html +2 -2
- package/components/_cards/charts-21-worldmap.card.html +2 -2
- 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 +2 -2
- package/components/_cards/charts-4-barlist.card.html +2 -2
- package/components/_cards/charts-5-donut.card.html +3 -3
- 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 +2 -2
- package/components/_cards/charts-99-fullpage.card.html +5 -5
- package/components/_cards/checkbox.card.html +4 -4
- package/components/_cards/codeblock.card.html +1 -1
- package/components/_cards/combobox.card.html +3 -2
- package/components/_cards/context-menu.card.html +3 -2
- package/components/_cards/date-picker.card.html +5 -2
- package/components/_cards/diffvalue.card.html +2 -2
- package/components/_cards/divider.card.html +3 -3
- package/components/_cards/drawer.card.html +2 -2
- package/components/_cards/dropdown-menu.card.html +6 -6
- package/components/_cards/dropzone.card.html +1 -1
- package/components/_cards/empty-state.card.html +5 -5
- package/components/_cards/filter-bar.card.html +5 -5
- package/components/_cards/icon-button.card.html +2 -2
- package/components/_cards/icons-1-core.card.html +2 -2
- package/components/_cards/icons-2-feather.card.html +3 -3
- package/components/_cards/icons-3-unicons.card.html +3 -3
- package/components/_cards/input.card.html +5 -2
- package/components/_cards/kbd.card.html +2 -2
- package/components/_cards/keyvalue.card.html +2 -2
- package/components/_cards/listrow.card.html +2 -2
- package/components/_cards/loading.card.html +2 -2
- package/components/_cards/log-viewer.card.html +2 -2
- package/components/_cards/modal.card.html +9 -9
- package/components/_cards/multi-select.card.html +3 -2
- package/components/_cards/number-stepper.card.html +3 -2
- package/components/_cards/pagination.card.html +3 -2
- package/components/_cards/people.card.html +3 -3
- package/components/_cards/pipeline-node.card.html +2 -2
- package/components/_cards/pipeline-palette.card.html +4 -4
- package/components/_cards/radio.card.html +2 -2
- package/components/_cards/search.card.html +5 -2
- package/components/_cards/segmented-control.card.html +2 -2
- package/components/_cards/select.card.html +4 -4
- package/components/_cards/slider.card.html +1 -1
- package/components/_cards/smart-table.card.html +1 -1
- package/components/_cards/spreadsheet.card.html +2 -2
- package/components/_cards/stepper.card.html +2 -2
- package/components/_cards/table.card.html +103 -0
- package/components/_cards/tabs.card.html +3 -2
- package/components/_cards/tag.card.html +5 -2
- package/components/_cards/textarea.card.html +2 -2
- package/components/_cards/timeline.card.html +1 -1
- package/components/_cards/toast.card.html +4 -4
- package/components/_cards/toggles.card.html +3 -3
- package/components/_cards/tooltip.card.html +5 -5
- package/components/_cards/tree.card.html +2 -2
- 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-navigation.js +1 -1
- package/components/_shared/src-pipeline.js +1 -1
- package/components/_shared/src-tabs.js +1 -1
- package/components/_vue/index.mjs +9 -5
- package/components/buttons/ActionChip.d.ts +3 -1
- package/components/buttons/ActionChip.jsx +4 -4
- package/components/buttons/ActionChip.vue +4 -4
- package/components/buttons/Button.d.ts +5 -2
- package/components/buttons/Button.jsx +15 -18
- package/components/buttons/Button.vue +17 -18
- package/components/buttons/ButtonGroup.vue +1 -1
- package/components/buttons/IconButton.d.ts +2 -1
- package/components/buttons/IconButton.jsx +9 -7
- package/components/buttons/IconButton.vue +10 -8
- package/components/buttons/buttons.prompt.md +6 -5
- package/components/charts/Bar3D.jsx +2 -2
- package/components/charts/Bar3D.vue +2 -2
- package/components/charts/BarChart.jsx +4 -4
- package/components/charts/BarChart.vue +4 -4
- package/components/charts/BarList.jsx +1 -1
- package/components/charts/BarList.vue +1 -1
- package/components/charts/BoxPlot.jsx +1 -1
- package/components/charts/BoxPlot.vue +2 -2
- package/components/charts/BulletChart.jsx +1 -1
- package/components/charts/BulletChart.vue +1 -1
- package/components/charts/CandlestickChart.jsx +2 -2
- package/components/charts/CandlestickChart.vue +3 -3
- package/components/charts/ChartKit.jsx +5 -5
- package/components/charts/ChartLegend.vue +16 -0
- package/components/charts/ChartTooltip.vue +16 -0
- package/components/charts/ChordChart.jsx +2 -2
- package/components/charts/ChordChart.vue +2 -2
- package/components/charts/GanttChart.jsx +2 -2
- package/components/charts/GanttChart.vue +2 -2
- package/components/charts/GaugeChart.jsx +2 -2
- package/components/charts/GaugeChart.vue +2 -2
- package/components/charts/HeatmapChart.jsx +2 -2
- package/components/charts/HeatmapChart.vue +2 -2
- package/components/charts/Histogram.jsx +2 -2
- package/components/charts/Histogram.vue +3 -3
- package/components/charts/LineChart.jsx +1 -1
- package/components/charts/LineChart.vue +3 -3
- package/components/charts/ParetoChart.jsx +3 -3
- package/components/charts/ParetoChart.vue +4 -4
- package/components/charts/PlotGrid.vue +18 -0
- package/components/charts/RadarChart.jsx +1 -1
- package/components/charts/RadarChart.vue +1 -1
- package/components/charts/Ribbon3D.jsx +2 -2
- package/components/charts/Ribbon3D.vue +2 -2
- package/components/charts/SankeyChart.jsx +2 -2
- package/components/charts/SankeyChart.vue +2 -2
- package/components/charts/Scatter3D.jsx +1 -1
- package/components/charts/Scatter3D.vue +1 -1
- package/components/charts/ScatterChart.jsx +3 -3
- package/components/charts/ScatterChart.vue +4 -4
- package/components/charts/Sparkline.jsx +1 -1
- package/components/charts/Sparkline.vue +1 -1
- package/components/charts/SunburstChart.jsx +1 -1
- package/components/charts/SunburstChart.vue +1 -1
- package/components/charts/Surface3D.jsx +2 -2
- package/components/charts/Surface3D.vue +2 -2
- package/components/charts/TreemapChart.jsx +2 -2
- package/components/charts/TreemapChart.vue +2 -2
- package/components/charts/WaterfallChart.jsx +2 -2
- package/components/charts/WaterfallChart.vue +3 -3
- package/components/charts/WorldMap.jsx +2 -2
- package/components/charts/WorldMap.vue +2 -2
- package/components/charts/XLabels.vue +11 -0
- package/components/data/CodeBlock.jsx +1 -1
- package/components/data/CodeBlock.vue +1 -1
- package/components/data/DiffValue.jsx +1 -1
- package/components/data/DiffValue.vue +1 -1
- package/components/data/FilterBar.d.ts +2 -0
- package/components/data/FilterBar.jsx +10 -9
- package/components/data/FilterBar.vue +9 -8
- package/components/data/KeyValue.jsx +3 -3
- package/components/data/KeyValue.vue +3 -3
- package/components/data/ListRow.jsx +2 -2
- package/components/data/ListRow.vue +2 -2
- package/components/data/Pagination.d.ts +5 -1
- package/components/data/Pagination.jsx +16 -12
- package/components/data/Pagination.vue +14 -9
- package/components/data/SmartTable.d.ts +4 -1
- package/components/data/SmartTable.jsx +16 -14
- package/components/data/SmartTable.vue +25 -22
- package/components/data/Spreadsheet.d.ts +2 -0
- package/components/data/Spreadsheet.jsx +12 -11
- package/components/data/Spreadsheet.vue +14 -13
- package/components/data/Table.d.ts +47 -0
- package/components/data/Table.jsx +85 -0
- package/components/data/Table.vue +63 -0
- package/components/data/data.prompt.md +3 -3
- package/components/display/Avatar.vue +3 -2
- package/components/display/AvatarGroup.vue +3 -2
- package/components/display/Badge.vue +1 -1
- package/components/display/Divider.vue +3 -3
- package/components/display/Donut.vue +3 -2
- package/components/display/IconTile.vue +2 -1
- package/components/display/Kbd.vue +1 -1
- package/components/display/ProgressBar.jsx +1 -1
- package/components/display/ProgressBar.vue +1 -1
- package/components/display/StatCard.vue +1 -1
- package/components/display/Tag.d.ts +3 -1
- package/components/display/Tag.jsx +4 -4
- package/components/display/Tag.vue +4 -4
- package/components/feedback/Accordion.jsx +2 -2
- package/components/feedback/Accordion.vue +2 -2
- package/components/feedback/ActivityItem.d.ts +3 -1
- package/components/feedback/ActivityItem.jsx +5 -5
- package/components/feedback/ActivityItem.vue +5 -4
- package/components/feedback/Alert.jsx +4 -4
- package/components/feedback/Alert.vue +3 -3
- package/components/feedback/Banner.jsx +5 -5
- package/components/feedback/Banner.vue +5 -5
- package/components/feedback/ContextMenu.d.ts +3 -1
- package/components/feedback/ContextMenu.jsx +5 -5
- package/components/feedback/ContextMenu.vue +5 -5
- package/components/feedback/DotActivity.vue +3 -3
- package/components/feedback/Drawer.d.ts +2 -0
- package/components/feedback/Drawer.jsx +6 -6
- package/components/feedback/Drawer.vue +22 -15
- package/components/feedback/EmptyState.vue +2 -2
- package/components/feedback/LogViewer.vue +1 -1
- package/components/feedback/Modal.d.ts +2 -0
- package/components/feedback/Modal.jsx +12 -11
- package/components/feedback/Modal.vue +10 -8
- package/components/feedback/Skeleton.vue +2 -1
- package/components/feedback/Spinner.vue +2 -1
- package/components/feedback/Stepper.vue +1 -1
- package/components/feedback/Timeline.jsx +1 -1
- package/components/feedback/Timeline.vue +1 -1
- package/components/feedback/Toast.vue +4 -4
- package/components/feedback/ToastStack.vue +11 -0
- package/components/feedback/Tooltip.vue +19 -0
- package/components/feedback/feedback.prompt.md +4 -4
- package/components/forms/Checkbox.d.ts +3 -2
- package/components/forms/Checkbox.jsx +7 -7
- package/components/forms/Checkbox.vue +8 -8
- package/components/forms/Combobox.d.ts +2 -0
- package/components/forms/Combobox.jsx +12 -10
- package/components/forms/Combobox.vue +11 -10
- package/components/forms/DatePicker.d.ts +4 -0
- package/components/forms/DatePicker.jsx +16 -12
- package/components/forms/DatePicker.vue +15 -11
- package/components/forms/Dropzone.jsx +2 -2
- package/components/forms/Dropzone.vue +5 -5
- package/components/forms/Field.d.ts +5 -1
- package/components/forms/Field.jsx +4 -4
- package/components/forms/Field.vue +4 -4
- package/components/forms/Input.d.ts +5 -1
- package/components/forms/Input.jsx +7 -7
- package/components/forms/Input.vue +3 -3
- package/components/forms/MultiSelect.d.ts +2 -0
- package/components/forms/MultiSelect.jsx +13 -11
- package/components/forms/MultiSelect.vue +12 -11
- package/components/forms/NumberStepper.d.ts +3 -1
- package/components/forms/NumberStepper.jsx +7 -7
- package/components/forms/NumberStepper.vue +8 -7
- package/components/forms/Radio.d.ts +5 -3
- package/components/forms/Radio.jsx +13 -15
- package/components/forms/Radio.vue +9 -10
- package/components/forms/RadioGroup.vue +5 -5
- package/components/forms/SearchInput.d.ts +3 -1
- package/components/forms/SearchInput.jsx +6 -6
- package/components/forms/SearchInput.vue +7 -6
- package/components/forms/Select.d.ts +3 -2
- package/components/forms/Select.jsx +6 -7
- package/components/forms/Select.vue +6 -6
- package/components/forms/Slider.jsx +3 -3
- package/components/forms/Slider.vue +3 -3
- package/components/forms/Switch.d.ts +2 -2
- package/components/forms/Switch.jsx +20 -22
- package/components/forms/Switch.vue +15 -14
- package/components/forms/Textarea.vue +4 -4
- package/components/forms/forms.prompt.md +1 -1
- package/components/forms/input-base.js +2 -1
- package/components/index.d.ts +1 -2
- package/components/index.js +3 -4
- package/components/navigation/Breadcrumb.jsx +3 -3
- package/components/navigation/Breadcrumb.vue +4 -4
- package/components/navigation/DocTree.jsx +3 -3
- package/components/navigation/DocTree.vue +3 -3
- package/components/navigation/PageHeading.vue +1 -1
- package/components/navigation/PageToolbar.vue +7 -6
- package/components/navigation/Sidebar.jsx +1 -1
- package/components/navigation/Sidebar.vue +3 -3
- package/components/navigation/ThemeToggle.vue +2 -1
- package/components/navigation/TopBar.d.ts +3 -1
- package/components/navigation/TopBar.jsx +6 -6
- package/components/navigation/Tree.jsx +5 -5
- package/components/navigation/Tree.vue +5 -5
- package/components/pipeline/ConfigPanel.d.ts +2 -0
- package/components/pipeline/ConfigPanel.jsx +9 -9
- package/components/pipeline/ConfigPanel.vue +9 -9
- package/components/pipeline/DataPreview.d.ts +3 -1
- package/components/pipeline/DataPreview.jsx +7 -7
- package/components/pipeline/DataPreview.vue +7 -7
- package/components/pipeline/NodeCard.jsx +3 -3
- package/components/pipeline/NodeCard.vue +3 -3
- package/components/pipeline/PaletteItem.vue +2 -2
- package/components/pipeline/PaletteListItem.vue +1 -1
- package/components/pipeline/PalettePanel.jsx +2 -2
- package/components/pipeline/PalettePanel.vue +1 -1
- package/components/pipeline/Port.vue +15 -0
- package/components/pipeline/PortLabel.vue +15 -0
- package/components/pipeline/ZoomControls.vue +1 -1
- package/components/pipeline/port-skin.js +13 -0
- package/components/px.js +4 -0
- package/components/tabs/PanelTabs.vue +5 -4
- package/components/tabs/PillTabs.vue +5 -4
- package/components/tabs/SegmentedControl.d.ts +2 -2
- package/components/tabs/SegmentedControl.jsx +7 -7
- package/components/tabs/SegmentedControl.vue +7 -7
- package/components/tabs/Tabs.d.ts +5 -3
- package/components/tabs/Tabs.jsx +15 -15
- package/components/tabs/Tabs.vue +5 -5
- package/components/tabs/ViewToggle.d.ts +3 -1
- package/components/tabs/ViewToggle.jsx +5 -5
- package/components/tabs/ViewToggle.vue +5 -5
- package/components/tabs/tabs.prompt.md +1 -1
- package/keybricks.css +4 -0
- package/package.json +6 -3
- package/readme.md +90 -122
- package/readme.zh-CN.md +120 -0
- package/tokens/charts.css +20 -17
- package/tokens/colors.css +2 -2
- package/tokens/dark.css +2 -2
- package/tokens/hover.css +32 -0
- package/tokens/interaction.css +3 -1
- package/tokens/layout.css +29 -7
- package/tokens/tokens.d.ts +36 -0
- package/tokens/tokens.js +143 -89
- package/tokens/tokens.json +240 -106
- package/tokens/typography.css +27 -14
- package/components/_cards/brand-visual.card.html +0 -43
- package/components/_cards/datatable.card.html +0 -48
- package/components/_shared/src-brand.js +0 -1
- package/components/brand/BrandVisual.d.ts +0 -17
- package/components/brand/BrandVisual.jsx +0 -29
- package/components/brand/BrandVisual.vue +0 -34
- package/components/brand/_dir.card.html +0 -13
- package/components/brand/brandMotifs.js +0 -210
- package/components/buttons/_dir.card.html +0 -13
- package/components/charts/ChartKit.vue +0 -47
- package/components/charts/_dir.card.html +0 -7
- package/components/data/DataTable.d.ts +0 -28
- package/components/data/DataTable.jsx +0 -32
- package/components/data/DataTable.vue +0 -25
- package/components/data/_dir.card.html +0 -13
- package/components/display/_dir.card.html +0 -13
- package/components/feedback/_dir.card.html +0 -13
- package/components/forms/_dir.card.html +0 -13
- package/components/icons/_dir.card.html +0 -13
- package/components/navigation/_dir.card.html +0 -13
- package/components/pipeline/_dir.card.html +0 -13
- package/components/tabs/_dir.card.html +0 -13
package/components/tabs/Tabs.jsx
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
/** Underline tabs on a hairline baseline (Import/Export). Active = blue text + 2px blue underline. */
|
|
4
|
-
export function Tabs({ tabs = [], active, onChange, style }) {
|
|
3
|
+
/** Underline tabs on a hairline baseline (Import/Export). Active = blue text + 2px blue underline. The bar is the region's bar height (sm 32 · md 40 · lg 44) with the tier's control text; omit `size` to inherit. */
|
|
4
|
+
export function Tabs({ tabs = [], active, onChange, size, style }) {
|
|
5
5
|
return (
|
|
6
|
-
<div style={{ display: "flex", gap: 4, borderBottom: "1px solid var(--border-control)", ...style }}>
|
|
6
|
+
<div role="tablist" data-size={size} style={{ display: "flex", gap: 4, borderBottom: "1px solid var(--border-control)", ...style }}>
|
|
7
7
|
{tabs.map((t) => {
|
|
8
8
|
const is = t === active;
|
|
9
9
|
return (
|
|
10
|
-
<button key={t} type="button" onClick={() => onChange && onChange(t)}
|
|
11
|
-
style={{ background: "transparent", border: "none", cursor: "pointer", padding: "
|
|
10
|
+
<button key={t} type="button" role="tab" aria-selected={is} data-ink={is ? undefined : ""} onClick={() => onChange && onChange(t)}
|
|
11
|
+
style={{ background: "transparent", border: "none", cursor: "pointer", height: "var(--bar-h)", boxSizing: "border-box", padding: "0 var(--control-px)", marginBottom: -1, borderBottom: is ? "2px solid var(--action-primary)" : "2px solid transparent", fontFamily: "var(--font-sans)", fontWeight: "var(--weight-medium)", fontSize: "var(--control-text)", lineHeight: "var(--control-leading)", letterSpacing: "var(--control-tracking)", color: is ? "var(--action-primary)" : "var(--ink, var(--text-body))", whiteSpace: "nowrap" }}>
|
|
12
12
|
{t}
|
|
13
13
|
</button>
|
|
14
14
|
);
|
|
@@ -17,15 +17,15 @@ export function Tabs({ tabs = [], active, onChange, style }) {
|
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
export function PanelTabs({ tabs = [], active, onChange, style }) {
|
|
20
|
+
/** Panel tabs (Node Info · Calc Rules · Output Fields · SQL Preview): a lighter underline tab bar at the region's bar height with regular-weight control text. Put the panel in an sm region for the compact 32px/12px look. */
|
|
21
|
+
export function PanelTabs({ tabs = [], active, onChange, size, style }) {
|
|
22
22
|
return (
|
|
23
|
-
<div style={{ display: "flex", borderBottom: "1px solid var(--border-subtle)", ...style }}>
|
|
23
|
+
<div role="tablist" data-size={size} style={{ display: "flex", borderBottom: "1px solid var(--border-subtle)", ...style }}>
|
|
24
24
|
{tabs.map((t) => {
|
|
25
25
|
const is = t === active;
|
|
26
26
|
return (
|
|
27
|
-
<button key={t} type="button" onClick={() => onChange && onChange(t)}
|
|
28
|
-
style={{ background: "transparent", border: "none", cursor: "pointer", padding: "
|
|
27
|
+
<button key={t} type="button" role="tab" aria-selected={is} data-ink={is ? undefined : ""} onClick={() => onChange && onChange(t)}
|
|
28
|
+
style={{ background: "transparent", border: "none", cursor: "pointer", height: "var(--bar-h)", boxSizing: "border-box", padding: "0 var(--control-px)", marginBottom: -1, borderBottom: is ? "2px solid var(--action-primary)" : "2px solid transparent", fontFamily: "var(--font-sans)", fontSize: "var(--control-text)", lineHeight: "var(--control-leading)", letterSpacing: "var(--control-tracking)", color: is ? "var(--action-primary)" : "var(--ink, var(--text-secondary))", whiteSpace: "nowrap" }}>
|
|
29
29
|
{t}
|
|
30
30
|
</button>
|
|
31
31
|
);
|
|
@@ -34,15 +34,15 @@ export function PanelTabs({ tabs = [], active, onChange, style }) {
|
|
|
34
34
|
);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/** Text pill filter tabs (For Review · To be Submitted · For Approval). Active =
|
|
38
|
-
export function PillTabs({ tabs = [], active, onChange, style }) {
|
|
37
|
+
/** Text pill filter tabs (For Review · To be Submitted · For Approval). Active = tinted pill. Pills are control-height (sm 24 · md 32 · lg 36); omit `size` to inherit. */
|
|
38
|
+
export function PillTabs({ tabs = [], active, onChange, size, style }) {
|
|
39
39
|
return (
|
|
40
|
-
<div style={{ display: "flex", gap:
|
|
40
|
+
<div role="tablist" data-size={size} style={{ display: "flex", gap: "var(--control-gap)", ...style }}>
|
|
41
41
|
{tabs.map((t) => {
|
|
42
42
|
const is = t === active;
|
|
43
43
|
return (
|
|
44
|
-
<button key={t} type="button" onClick={() => onChange && onChange(t)}
|
|
45
|
-
style={{ background: is ? "var(--bg-active)" : "transparent", border: "none", cursor: "pointer", height:
|
|
44
|
+
<button key={t} type="button" role="tab" aria-selected={is} data-ink={is ? undefined : ""} data-wash={is ? undefined : ""} onClick={() => onChange && onChange(t)}
|
|
45
|
+
style={{ background: is ? "var(--bg-active)" : "var(--wash, transparent)", border: "none", cursor: "pointer", height: "var(--control-h)", padding: "0 var(--control-px)", borderRadius: "var(--radius-md)", fontFamily: "var(--font-sans)", fontWeight: "var(--weight-medium)", fontSize: "var(--control-text)", lineHeight: "var(--control-leading)", letterSpacing: "var(--control-tracking)", color: is ? "var(--text-heading)" : "var(--ink, var(--text-secondary))", whiteSpace: "nowrap" }}>
|
|
46
46
|
{t}
|
|
47
47
|
</button>
|
|
48
48
|
);
|
package/components/tabs/Tabs.vue
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
// Underline tabs on a hairline baseline (Import/Export). Active = blue text + 2px blue underline.
|
|
3
|
-
defineProps({ tabs: { type: Array, default: () => [] }, active: String, style: Object })
|
|
2
|
+
// Underline tabs on a hairline baseline (Import/Export). Active = blue text + 2px blue underline. The bar is the region's bar height (sm 32 · md 40 · lg 44) with the tier's control text; omit `size` to inherit.
|
|
3
|
+
defineProps({ tabs: { type: Array, default: () => [] }, active: String, size: String, style: Object })
|
|
4
4
|
const emit = defineEmits(['change'])
|
|
5
5
|
</script>
|
|
6
6
|
<template>
|
|
7
|
-
<div :style="{ display: 'flex', gap:
|
|
8
|
-
<button v-for="t in tabs" :key="t" type="button" @click="emit('change', t)"
|
|
9
|
-
:style="{ background: 'transparent', border: 'none', cursor: 'pointer', padding: '
|
|
7
|
+
<div role="tablist" :data-size="size" :style="{ display: 'flex', gap: '4px', borderBottom: '1px solid var(--border-control)', ...style }">
|
|
8
|
+
<button v-for="t in tabs" :key="t" type="button" role="tab" :aria-selected="t === active" :data-ink="t === active ? undefined : ''" @click="emit('change', t)"
|
|
9
|
+
:style="{ background: 'transparent', border: 'none', cursor: 'pointer', height: 'var(--bar-h)', boxSizing: 'border-box', padding: '0 var(--control-px)', marginBottom: '-1px', borderBottom: t === active ? '2px solid var(--action-primary)' : '2px solid transparent', fontFamily: 'var(--font-sans)', fontWeight: 'var(--weight-medium)', fontSize: 'var(--control-text)', lineHeight: 'var(--control-leading)', letterSpacing: 'var(--control-tracking)', color: t === active ? 'var(--action-primary)' : 'var(--ink, var(--text-body))', whiteSpace: 'nowrap' }">{{ t }}</button>
|
|
10
10
|
</div>
|
|
11
11
|
</template>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
/** list/grid
|
|
2
|
+
/** list/grid icon toggle — two IconButtons at the region's tier (sm 24 · md 32 · lg 36), active gets the tinted wash. */
|
|
3
3
|
export interface ViewToggleProps {
|
|
4
4
|
value?: "list" | "grid";
|
|
5
|
+
/** Size tier. Omit to inherit the enclosing region's tier (the default). */
|
|
6
|
+
size?: "sm" | "md" | "lg";
|
|
5
7
|
onChange?: (v: "list" | "grid") => void;
|
|
6
8
|
style?: React.CSSProperties;
|
|
7
9
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { IconButton } from "../buttons/IconButton.jsx";
|
|
3
3
|
|
|
4
|
-
/** Two-state list/grid icon toggle (palette header). */
|
|
5
|
-
export function ViewToggle({ value = "grid", onChange, style }) {
|
|
4
|
+
/** Two-state list/grid icon toggle (palette header). Two IconButtons at the region's tier; omit `size` to inherit. */
|
|
5
|
+
export function ViewToggle({ value = "grid", onChange, size, style }) {
|
|
6
6
|
return (
|
|
7
|
-
<div style={{ display: "inline-flex", gap: 2, ...style }}>
|
|
8
|
-
<IconButton icon="list"
|
|
9
|
-
<IconButton icon="layout-grid"
|
|
7
|
+
<div data-size={size} style={{ display: "inline-flex", gap: 2, ...style }}>
|
|
8
|
+
<IconButton icon="list" active={value === "list"} onClick={() => onChange && onChange("list")} label="List view" />
|
|
9
|
+
<IconButton icon="layout-grid" active={value === "grid"} onClick={() => onChange && onChange("grid")} label="Grid view" />
|
|
10
10
|
</div>
|
|
11
11
|
);
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import IconButton from '../buttons/IconButton.vue'
|
|
3
|
-
// Two-state list/grid icon toggle (palette header).
|
|
4
|
-
defineProps({ modelValue: { type: String, default: 'grid' }, style: Object })
|
|
3
|
+
// Two-state list/grid icon toggle (palette header). Two IconButtons at the region's tier; omit `size` to inherit.
|
|
4
|
+
defineProps({ modelValue: { type: String, default: 'grid' }, size: String, style: Object })
|
|
5
5
|
const emit = defineEmits(['update:modelValue'])
|
|
6
6
|
</script>
|
|
7
7
|
<template>
|
|
8
|
-
<div :style="{ display: 'inline-flex', gap:
|
|
9
|
-
<IconButton icon="list"
|
|
10
|
-
<IconButton icon="layout-grid"
|
|
8
|
+
<div :data-size="size" :style="{ display: 'inline-flex', gap: '2px', ...style }">
|
|
9
|
+
<IconButton icon="list" :active="modelValue === 'list'" label="List view" @click="emit('update:modelValue', 'list')" />
|
|
10
|
+
<IconButton icon="layout-grid" :active="modelValue === 'grid'" label="Grid view" @click="emit('update:modelValue', 'grid')" />
|
|
11
11
|
</div>
|
|
12
12
|
</template>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Tab systems: `Tabs` (
|
|
1
|
+
Tab systems: `Tabs` (underline — page level), `PanelTabs` (lighter underline — config panel, put the panel in an sm region), `PillTabs` (pill filters), `ViewToggle` (list/grid icons). All read the region's size tier: bars are 32 / 40 / 44px, pills 24 / 32 / 36px.
|
|
2
2
|
|
|
3
3
|
```jsx
|
|
4
4
|
<Tabs tabs={["Import","Export"]} active={tab} onChange={setTab}/>
|
package/keybricks.css
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keyfunc/keybricks-ds",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Keybricks design system —
|
|
3
|
+
"version": "2.1.1",
|
|
4
|
+
"description": "Keybricks design system — 352 design tokens, three size tiers and 117 UI components in React and Vue 3, source-only.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": [
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"default": "./components/index.js"
|
|
14
14
|
},
|
|
15
15
|
"./vue": "./components/_vue/index.mjs",
|
|
16
|
-
"./styles.css": "./
|
|
16
|
+
"./styles.css": "./keybricks.css",
|
|
17
|
+
"./keybricks.css": "./keybricks.css",
|
|
17
18
|
"./tokens": {
|
|
18
19
|
"types": "./tokens/tokens.d.ts",
|
|
19
20
|
"default": "./tokens/tokens.js"
|
|
@@ -31,7 +32,9 @@
|
|
|
31
32
|
"assets",
|
|
32
33
|
"_scripts",
|
|
33
34
|
"styles.css",
|
|
35
|
+
"keybricks.css",
|
|
34
36
|
"readme.md",
|
|
37
|
+
"readme.zh-CN.md",
|
|
35
38
|
"DESIGN.md",
|
|
36
39
|
"INTEGRATION.md",
|
|
37
40
|
"DEPLOY.md",
|
package/readme.md
CHANGED
|
@@ -1,150 +1,118 @@
|
|
|
1
1
|
# Keybricks Design System
|
|
2
2
|
|
|
3
|
+
English · [中文](readme.zh-CN.md)
|
|
4
|
+
|
|
3
5
|
Keybricks is an enterprise performance-management (EPM) platform for finance teams: documents & reporting, business intelligence, data integration, reconciliation, consolidation, and a management suite (modeling, workflow, security, system migration, business logic, tasks, validation rules, control center). Its signature surface is a node-based **data-pipeline editor** ("adapters" like *Oracle Adapter*) where users wire Data Source → Join → Transformation → Merge → Output nodes on a dotted canvas.
|
|
4
|
-
(Keybricks 是面向财务团队的企业绩效管理(EPM)平台:文档与报表、商业智能、数据集成、对账、合并报表,以及管理套件(建模、工作流、权限、系统迁移、业务逻辑、任务管理、校验规则、控制中心)。其标志性界面是基于节点的**数据管道编辑器**(如「Oracle Adapter」),用户在点状网格画布上依次连接数据源 → 关联 → 转换 → 合并 → 输出节点。)
|
|
5
6
|
|
|
6
|
-
## Products represented
|
|
7
|
+
## Products represented
|
|
7
8
|
One product: the Keybricks web app (desktop, 1512×~860 design size). Key surfaces: Home dashboard · Documents · Pipeline editor · System Migration wizard.
|
|
8
|
-
(单一产品:Keybricks 网页应用(桌面端,设计尺寸约 1512×860)。核心界面:首页仪表盘、文档中心、管道编辑器、系统迁移向导。)
|
|
9
9
|
|
|
10
|
-
##
|
|
11
|
-
- **Voice
|
|
12
|
-
|
|
13
|
-
- **
|
|
14
|
-
|
|
15
|
-
- **
|
|
16
|
-
|
|
17
|
-
- **Terminology / 术语**: domain-precise EPM/ETL vocabulary — Detail Sheet, Dimension, Model, Association Match, Multi-Condition Judge, Group Calculation, Concat Merge, Reconciliation, Consolidation. Config codes render in mono ALL_CAPS_SNAKE ("FIN_CURRENCY_DEFAULT").
|
|
18
|
-
(精确的 EPM/ETL 领域术语;配置代码用等宽字体全大写下划线格式,如「FIN_CURRENCY_DEFAULT」。)
|
|
19
|
-
- **Numbers & meta / 数字与元信息**: counts as "1 document", "2 items", relative time "2 hours ago", log lines "[14:30] Task started: Import".
|
|
20
|
-
(计数如「1 document」「2 items」;相对时间如「2 hours ago」;日志行如「[14:30] Task started: Import」。)
|
|
21
|
-
- **Status language / 状态文案**: "• Editing" dot-prefixed state chip; steps named as nouns ("Upload & Parse", "Comparison", "Confirmation", "Execution", "Results").
|
|
22
|
-
(状态用圆点前缀,如「• Editing」;步骤用名词命名,如「Upload & Parse」「Comparison」「Confirmation」「Execution」「Results」。)
|
|
10
|
+
## Content fundamentals
|
|
11
|
+
- **Voice**: terse, technical, verb-first. Buttons are imperative: "Run Test", "Submit", "Save Settings", "Continue to Confirmation", "Mark as New", "Skip Selected".
|
|
12
|
+
- **Casing**: Title Case for nav, headings, buttons, table headers ("Import History", "Custom Parameters"); sentence case for helper copy ("Import and manage configuration migrations across systems", "Click to upload or drag and drop", "JSON files only").
|
|
13
|
+
- **Person**: no "I/we/you" — labels are objective and system-centric. Personal touch is limited to the dashboard greeting "Good evening, Felix" + full date "Monday, April 21, 2026".
|
|
14
|
+
- **Terminology**: domain-precise EPM/ETL vocabulary — Detail Sheet, Dimension, Model, Association Match, Multi-Condition Judge, Group Calculation, Concat Merge, Reconciliation, Consolidation. Config codes render in mono ALL_CAPS_SNAKE ("FIN_CURRENCY_DEFAULT").
|
|
15
|
+
- **Numbers & meta**: counts as "1 document", "2 items", relative time "2 hours ago", log lines "[14:30] Task started: Import".
|
|
16
|
+
- **Status language**: "• Editing" dot-prefixed state chip; steps named as nouns ("Upload & Parse", "Comparison", "Confirmation", "Execution", "Results").
|
|
23
17
|
- **Emoji**: never. Icons carry all decoration.
|
|
24
|
-
|
|
25
|
-
- **Localization note / 本地化说明**: content is bilingual-tolerant — a document named 财务分析 sits beside English names; UI chrome stays English.
|
|
26
|
-
(内容本身容忍中英混排——如「财务分析」这样的文档名可与英文文档名并列;界面框架文案本身保持英文。)
|
|
18
|
+
- **Localization**: content is bilingual-tolerant — a document named 财务分析 sits beside English names; UI chrome stays English.
|
|
27
19
|
|
|
28
|
-
##
|
|
29
|
-
- **Color
|
|
20
|
+
## Visual foundations
|
|
21
|
+
- **Color**: near-monochrome neutral UI (neutral ramp #FAFAFA→#0A0A0A) with ONE action blue (#155DFC). Color is reserved for meaning: node-category hues (source green #009966, join blue #155DFC, transform orange #FF6900, merge purple #9810FA, output teal #009689, each with a 100-tint tile bg), feedback (success #00BC7D, danger #FB2C36, warning #FFB900), charts (`--series-1…8`, see `tokens/charts.css`). Backgrounds: app #FAFAFA, surfaces white. No gradients except chart-area fills (blue → transparent).
|
|
30
22
|
The system is organized in **three tiers**, and only the middle one is public API:
|
|
31
23
|
1. **Palette** — `--<hue>-<step>` on a fixed 50→950 lightness scale (neutral + blue extracted from the source file; red/orange/amber/emerald/teal/cyan/purple/pink generated in OKLCH on one shared lightness/chroma curve so every family reads as part of the same system rather than a public library's defaults — steps other tokens point to byte-for-byte, like `--danger`/`--warning`/`--success`/`--cat-*`, are pinned to those exact source-verified values; cyan and pink have no source anchor, so their hue angles were chosen to complete an evenly spaced wheel alongside the anchored hues and the brand blue), plus the transparency ramps `--neutral-alpha-*` (2→80%, black in light / white in dark) and `--brand-alpha-*` (8→32%). Identical in both themes; referenced only by tier 2.
|
|
32
24
|
2. **Semantic role** — `--bg-*`, `--text-*`, `--border-*`, `--action-*`, `--overlay-*`, and the feedback families `--success/warning/danger/info` with `-bg`/`-text` pairs. Named by job, flips for dark mode. **Components and consuming designs reference these and nothing else.**
|
|
33
25
|
3. **Component** — `--cat-*`, `--tooltip-bg`, `--dropzone-border-hover`: one part of one component, added only when no tier-2 role fits.
|
|
26
|
+
|
|
34
27
|
Rules that don't bend: step 400 and lighter never carry body text on white (they are surfaces, borders, disabled glyphs); `--on-accent` (#FFFFFF) is the only foreground allowed on a saturated fill, in **both** themes; label hues are mechanical (light = 100-step bg + 700-step text, dark = 950-step bg + 300-step text) so a new category needs no judgement; hue means *category*, the four feedback roles mean *severity*. Contrast targets: 4.5:1 body text, 3:1 for 18px+/bold and for UI boundaries. Three Colors cards carry the values: Palette (every ramp), Schemes (sets that work together), Transparency (the alpha scale).
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- **
|
|
39
|
-
|
|
40
|
-
- **
|
|
41
|
-
|
|
42
|
-
- **
|
|
43
|
-
|
|
44
|
-
- **
|
|
45
|
-
|
|
46
|
-
- **
|
|
47
|
-
(几乎全平面化设计。仅画布节点有轻阴影;选中态为蓝色边框+浅蓝光环;徽标带 2px 白色描边。其余元素依赖边框区分层次。)
|
|
48
|
-
- **Backgrounds/imagery / 背景与图像**: no photography, no illustration. The pipeline canvas is #fafafa with a subtle dot/curve grid; chart areas use soft blue gradient fills. Only bitmap: the cube logo.
|
|
49
|
-
(不使用摄影图或插画。管道画布为浅灰底配点状网格;图表区域用柔和蓝色渐变填充。唯一位图资源是立方体 Logo。)
|
|
50
|
-
- **States / 交互状态**: every interactive element carries five states beyond rest. **Hover** moves the fill one step (`--bg-hover` wash on ghost items, `--action-primary-hover` on solid buttons, `--soft-hover` on tinted ones). **Press** moves it a second step: Button and IconButton use explicit tokens (`--action-primary-active`, `--action-dark-active`, `--bg-press`, `--soft-active`, `--danger-active`, `--danger-soft-active`) and opt out of the global layer with `data-press="own"`; every other control — nav rows, tree items, menu items, chips, tabs, list rows, option rows, palette tiles — gets press from the one global rule in `tokens/interaction.css` (`filter: var(--press-filter)` on `:active`, which multiplies whatever wash hover is already showing, and brightens rather than darkens in dark mode). No scale transforms, no shadow shifts; text-only buttons drop to 70% opacity instead. **Keyboard focus** is also global: a 2px `--focus-border` outline at 2px offset on `:focus-visible` only, so a mouse click never draws it. **Selected/active** is persistent, not transient: active nav = `--bg-active` pill + heading-weight text; selected node = blue border + ring. **Disabled** is 55% opacity (50% on icon buttons) with the default cursor.
|
|
51
|
-
(每个可交互元素在静默态之外都有五种状态:悬停加深一档;按下再加深一档——Button 与 IconButton 使用专门的 `--*-active` / `--bg-press` token 并以 `data-press="own"` 退出全局层,其余所有控件(导航行、树节点、菜单项、标签页、列表行、选项行、面板磁贴等)由 `tokens/interaction.css` 中的单条全局规则提供按压态(`:active` 时叠加 `filter: var(--press-filter)`,在悬停底色之上再加深一档,深色模式下方向为提亮);不做缩放或阴影变化,纯文字按钮改为降至 70% 透明度。键盘聚焦同样是全局的:仅在 `:focus-visible` 时绘制 2px `--focus-border` 描边(偏移 2px),鼠标点击不显示。选中态是持续态而非瞬时态;禁用态约 55% 透明度(图标按钮 50%)并使用默认光标。)
|
|
52
|
-
- **Motion / 动效**: kept minimal by design (see Motion section below) — 120–160ms ease-out on hover/selection, nothing bouncy or far-traveling.
|
|
53
|
-
(动效克制(详见下方“动效”一节)——悬停/选中约 120–160ms 缓出,无弹跳、无大位移。)
|
|
54
|
-
- **Layout chrome / 布局框架**: left sidebar 240px (collapsible to a 64px icon rail), 56px top bar (search left, bell + black "AI Assistant" pill right), optional 240px secondary panel (Documents tree, pipeline palette), 400px right config panel, 250px bottom data-preview drawer.
|
|
55
|
-
(左侧边栏 240px(可收起为 64px 图标栏);顶栏 56px(左搜索,右铃铛+黑色「AI Assistant」胶囊);可选二级面板 240px;右侧配置面板 400px;底部数据预览抽屉 250px。)
|
|
56
|
-
- **Cards / 卡片**: white, radius 10, hairline border, 21px padding, 13px/500 title — never elevated.
|
|
57
|
-
(白底、10px 圆角、细边框、21px 内边距、13px/中等字重标题——不使用投影堆叠层级。)
|
|
58
|
-
- **Density / 密度**: high; tables 29–51px rows; mono 11px for data cells.
|
|
59
|
-
(高密度界面;表格行高 29–51px;数据单元格用 11px 等宽字体。)
|
|
28
|
+
- **Type**: Inter only (300 stat numerals, 400 body, 500 UI-medium, 600 titles and table headers) on the 14px scale — 12 captions · 14 body and controls · 16 section titles · 20 page titles; 24px only for the greeting + stat numbers (weight 300); 11px for chart ticks and nothing else. Negative tracking from 14px up (-.15 to -.54px), 0 at 12px. Menlo for data/code/logs at the row's own size with tabular figures. Chinese, Japanese and Korean (`lang="zh|ja|ko"`): same sizes, weight 500 → 600, tracking 0, never caps.
|
|
29
|
+
- **Spacing**: 4-px family in practice (2/4/6/8/10/12/16/24/32); page padding 24×32; card padding 21 (dense 17); section gap 24. Inside a bar the gaps come from the size tier: 8 inside a group, 12/16/24 between groups, 12/16 from a card edge to the first control.
|
|
30
|
+
- **Size tiers**: one tier per region — `data-size="sm" | "md" | "lg"` gives 24 / 32 / 36px controls, 12 / 14 / 14px control text and 32 / 40 / 44px rows; every control inside inherits, nothing interactive is below 24px, and heights or text sizes are never mixed in one row. md is the app default; dialogs are lg; dense grids are sm.
|
|
31
|
+
- **Radii**: 4 small controls · 8 buttons/inputs/nav/chips · 10 cards/search/dropzone · 14 palette tiles · 16 canvas nodes · full circles for ports/steps/pills.
|
|
32
|
+
- **Borders**: hairline everywhere — cards rgba(229,229,229,.6); controls #e5e5e5; row separators #f5f5f5; checkbox #d1d5db 1.5px; ports #d4d4d4 2px; dropzone dashed #d4d4d4 2px.
|
|
33
|
+
- **Shadows**: nearly flat. Canvas nodes only: `0 1px 3px rgba(0,0,0,.1), 0 1px 2px -1px rgba(0,0,0,.1)`; selection = blue-400 border + 2px blue-100 ring; badges get a 2px white ring. Everything else relies on borders.
|
|
34
|
+
- **Backgrounds & imagery**: no photography, no illustration. The pipeline canvas is #fafafa with a subtle dot/curve grid; chart areas use soft blue gradient fills. Only bitmap: the cube logo.
|
|
35
|
+
- **States**: every interactive element carries five states beyond rest. **Hover** moves the fill one step (`--bg-hover` wash on ghost items, `--action-primary-hover` on solid buttons, `--soft-hover` on tinted ones); controls whose colours are inline get it from the hover hooks in `tokens/hover.css`. **Press** moves it a second step: Button and IconButton use explicit tokens (`--action-primary-active`, `--action-dark-active`, `--bg-press`, `--soft-active`, `--danger-active`, `--danger-soft-active`) and opt out of the global layer with `data-press="own"`; every other control — nav rows, tree items, menu items, chips, tabs, list rows, option rows, palette tiles — gets press from the one global rule in `tokens/interaction.css` (`filter: var(--press-filter)` on `:active`, which multiplies whatever wash hover is already showing, and brightens rather than darkens in dark mode). No scale transforms, no shadow shifts; text-only buttons drop to 70% opacity instead. **Keyboard focus** is also global: a 2px `--focus-border` outline at 2px offset on `:focus-visible` only, so a mouse click never draws it. **Selected/active** is persistent, not transient: active nav = `--bg-active` pill + heading-weight text; selected node = blue border + ring. **Disabled** is 55% opacity (50% on icon buttons) with the default cursor.
|
|
36
|
+
- **Motion**: kept minimal by design (see Motion below) — 120–160ms ease-out on hover/selection, nothing bouncy or far-traveling.
|
|
37
|
+
- **Layout chrome**: left sidebar 240px (collapsible to a 64px icon rail), 56px top bar (search left, bell + black "AI Assistant" pill right), optional 240px secondary panel (Documents tree, pipeline palette), 400px right config panel, 250px bottom data-preview drawer.
|
|
38
|
+
- **Cards**: white, radius 10, hairline border, 21px padding, 14px/500 title — never elevated.
|
|
39
|
+
- **Density**: high; table rows 32 (sm) · 40 (md) · 44 (lg); header cells the same size as body cells in weight 600, sentence case; mono cells at the row's size.
|
|
60
40
|
|
|
61
|
-
##
|
|
41
|
+
## Iconography
|
|
62
42
|
- The product's icons are the **Lucide** stroke set (16/14px at 1.33px effective stroke, `currentColor`). We ship `components/icons/Icon.jsx`, embedding the exact Lucide path data for every glyph the product uses. Usage: `<Icon name="search" size={16}/>`.
|
|
63
|
-
(产品图标采用 **Lucide** 线性图标集(16/14px,约 1.33px 描边,随文字颜色变化)。已封装为 `components/icons/Icon.jsx`,内含产品实际用到的全部图形路径。用法:`<Icon name="search" size={16}/>`。)
|
|
64
43
|
- Icon color follows text color (#525252 default chrome, #a1a1a1 muted, category hue inside tinted tiles).
|
|
65
|
-
(图标颜色跟随文字色:默认 #525252,弱化态 #a1a1a1,分类色块内为对应分类色。)
|
|
66
44
|
- Tinted icon tiles are a signature motif: 40×40 r14 (palette), 48×48 r16 (nodes), 32×32 r8 hairline-bordered (list rows) — 100-tint bg + 600-hue glyph.
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
|
|
70
|
-
- **Extended icon libraries / 扩展图标库**: all 287 Feather icons (same 24-grid stroke-2 dialect) are merged into `Icon` via `components/icons/feather-paths.js` — core names win on overlap. Unicons line style (1,206 glyphs) renders through `components/icons/Unicon.jsx` from the official Unicons CDN webfont — a substitution: the SVG set is not vendored locally, so `Unicon` needs network access. Keyword indexes for search: `assets/icons/icon-index.json` (core + Feather) and `assets/icons/unicons-index.json`; browse both in the two Icon Gallery cards (every icon carries keywords).
|
|
71
|
-
(扩展图标库:287 个 Feather 图标(与核心集同为 24 网格描边风格)已全部并入 `Icon` 组件,重名时以核心集为准;Unicons 线性风格 1,206 个图标通过 `Unicon` 组件从 Unicons 官方 CDN 字体渲染(替代方案:SVG 未本地化,需联网)。两份关键词索引位于 `assets/icons/`,可在两张 Icon Gallery 卡片中按关键词搜索,每个图标均附关键词。)
|
|
45
|
+
- Emoji or unicode-as-icon: never.
|
|
46
|
+
- **Extended icon libraries**: all 287 Feather icons (same 24-grid stroke-2 dialect) are merged into `Icon` via `components/icons/feather-paths.js` — core names win on overlap. Unicons line style (1,206 glyphs) renders through `components/icons/Unicon.jsx` from the official Unicons CDN webfont — a substitution: the SVG set is not vendored locally, so `Unicon` needs network access. Keyword indexes for search: `assets/icons/icon-index.json` (core + Feather) and `assets/icons/unicons-index.json`; browse both in the two Icon Gallery cards (every icon carries keywords).
|
|
47
|
+
- **Icon sources**: Feather — github.com/feathericons/feather (`icons/*.svg`, keywords from `src/tags.json`), MIT licence; Unicons — github.com/Iconscout/unicons (`json/line.json`), Apache-2.0 licence. Last synced 2026-08-15.
|
|
72
48
|
- Badges: 13–20px circles (error red, warning amber, pending gray, debug red) with 2px white ring, overlapping the parent's corner.
|
|
73
|
-
(徽标为 13–20px 圆形,叠加在父元素角上,带 2px 白色描边。)
|
|
74
49
|
|
|
75
|
-
## Tokens & fonts
|
|
76
|
-
- `tokens/colors.css
|
|
50
|
+
## Tokens & fonts
|
|
51
|
+
- `tokens/colors.css` (base colors + semantic aliases), `tokens/colors-extended.css` (nine 50–950 accent ramps + semantic label pairs), `tokens/alpha.css` (transparency ramps and overlays), `tokens/typography.css` (14px scale, CJK rules), `tokens/layout.css` (radii, shadows, chrome sizes, size tiers, z-index), `tokens/motion.css`, `tokens/charts.css` (series palette and plot furniture), `tokens/interaction.css` (global press and keyboard-focus layer), `tokens/hover.css` (hover hooks), `tokens/fonts.css`, `tokens/dark.css`.
|
|
52
|
+
- `styles.css` imports every token file except `hover.css`; `keybricks.css` imports `styles.css` + `hover.css` and is what the npm path `@keyfunc/keybricks-ds/styles.css` resolves to.
|
|
77
53
|
|
|
78
|
-
## Dark mode
|
|
54
|
+
## Dark mode
|
|
79
55
|
- Apply with `<html data-theme="dark">`; every component reads semantic aliases only, so nothing else changes. Toggle it live in the UI kit from the top bar or the sidebar's **Dark Mode** item (persisted to `localStorage("kb-theme")`). `applyStoredTheme()` restores it at app start.
|
|
80
|
-
|
|
81
|
-
- **
|
|
82
|
-
|
|
83
|
-
-
|
|
84
|
-
|
|
85
|
-
- **Foreground on filled surfaces / 填充色上的前景色**: text and icons sitting on a saturated fill use `--on-accent`, which stays white in both themes; the neutral "AI Assistant" pill uses `--action-dark-fg`, which inverts with the theme. Never use `--text-inverse` for this — it is the inverse of body text and flips to near-black on dark backgrounds.
|
|
86
|
-
(位于饱和色填充之上的文字与图标使用 `--on-accent`,在两套主题下恒为白色;中性色的「AI Assistant」胶囊使用 `--action-dark-fg`,随主题反转。此场景不得使用 `--text-inverse`,它是正文颜色的反色,在深色背景上会变为近黑色。)
|
|
87
|
-
- **Status / 规范成熟度**: the dark palette is an original derivation of the light one, validated for contrast rather than copied from a dark-theme design. Confirm it against your intended dark spec before production use.
|
|
88
|
-
(深色调色板基于浅色体系推导而来,已做对比度验证,但并非直接来自现成的深色设计稿。正式用于生产前,建议与团队预期的深色规范核对。)
|
|
89
|
-
- Authoring rule / 开发规范: never reference `--neutral-*` / `--blue-*` directly in a component. Use the semantic layer (`--bg-surface`, `--bg-raised`, `--text-body`, `--border-card`, `--track`, `--soft-bg`, `--info-bg`, `--on-accent`, `--port-border`, `--dropzone-border`, `--ring-surface`, `--tooltip-bg`, …) so both themes work for free.
|
|
90
|
-
(组件中禁止直接引用 `--neutral-*`/`--blue-*` 等基础色变量,一律使用语义层变量,这样浅色/深色两套主题自动生效,无需额外适配。)
|
|
56
|
+
- **Primary blue in dark**: on the #0a0a0a canvas the light-theme blue reads murky, and a brighter #2b7fff cannot carry white 14px type (3.8:1, below AA). Dark mode therefore uses **`#1f6feb`** — 4.3:1 against the canvas, 4.6:1 for its white label, both passing AA, in the same hue family (~214°) one step lower in luminance. The light theme keeps `#155dfc`.
|
|
57
|
+
- **Other shifts**: four surface steps (#0a0a0a app / #161616 surface / #1d1d1d raised / #1f1f1f inset); borders `rgba(255,255,255,.09)`; the dark "AI Assistant" pill inverts to light-on-dark (`--action-dark-fg`); category and status tints become low-alpha washes of the same hues; tooltips invert; shadows deepen rather than glow.
|
|
58
|
+
- **Foreground on filled surfaces**: text and icons sitting on a saturated fill use `--on-accent`, which stays white in both themes; the neutral "AI Assistant" pill uses `--action-dark-fg`, which inverts with the theme. Never use `--text-inverse` for this — it is the inverse of body text and flips to near-black on dark backgrounds.
|
|
59
|
+
- **Status**: the dark palette is an original derivation of the light one, validated for contrast rather than copied from a dark-theme design. Confirm it against your intended dark spec before production use.
|
|
60
|
+
- **Authoring rule**: never reference `--neutral-*` / `--blue-*` directly in a component. Use the semantic layer (`--bg-surface`, `--bg-raised`, `--text-body`, `--border-card`, `--track`, `--soft-bg`, `--info-bg`, `--on-accent`, `--port-border`, `--dropzone-border`, `--ring-surface`, `--tooltip-bg`, …) so both themes work for free.
|
|
91
61
|
|
|
92
|
-
## Motion
|
|
93
|
-
- `tokens/motion.css` defines a restrained scale: 80/120/160/240/360ms with `--ease-out cubic-bezier(.2,.8,.3,1)`. Recipes: `--t-hover
|
|
94
|
-
- **Font caveat
|
|
95
|
-
(Inter 通过 Google Fonts 加载;Menlo 无网页字体可用,非 Mac 平台会回退到 ui-monospace/SF Mono/Consolas,如需精确还原请提供正版字体文件。)
|
|
62
|
+
## Motion
|
|
63
|
+
- `tokens/motion.css` defines a restrained scale: 80/120/160/240/360ms with `--ease-out cubic-bezier(.2,.8,.3,1)`. Recipes: `--t-hover` (hover and press), `kb-rise` (menus, dialogs), `kb-toast-in`, `kb-pulse` (skeletons), `kb-spin` (loading — constant-speed rotation, the industry norm for indeterminate spinners). `prefers-reduced-motion` is honoured globally. Nothing bounces; nothing travels more than 8px.
|
|
64
|
+
- **Font caveat**: Inter is loaded from Google Fonts. Menlo has no webfont — the mono stack falls back to ui-monospace/SF Mono/Consolas on non-mac platforms; supply licensed font files if exact rendering matters.
|
|
96
65
|
|
|
97
|
-
## Index
|
|
66
|
+
## Index
|
|
98
67
|
|
|
99
|
-
**For developers integrating this system
|
|
100
|
-
- `DESIGN.md` — the rules file for AI coding agents: absolute token values, interaction states, an explicit
|
|
101
|
-
- `INTEGRATION.md` — the integration guide: three steps to first paint, the full
|
|
102
|
-
- `DEPLOY.md` — running the system on GitLab: what ships in the package and what stays on Pages, the entry points, the release flow, and the bundler config each consumer needs
|
|
103
|
-
- `index.html` · `gallery.html` — the documentation site: the browsable system and the filterable thumbnail grid, both deployed to GitLab Pages by CI
|
|
104
|
-
- `package.json` · `.gitlab-ci.yml` · `_scripts/` — makes the system an installable package: a version tag publishes to the GitLab Package Registry, the default branch redeploys the docs site, and `npm run check` fails the pipeline if the generated tokens or barrels drift from source
|
|
68
|
+
**For developers integrating this system**
|
|
69
|
+
- `DESIGN.md` — the rules file for AI coding agents: absolute token values, interaction states, an explicit "do not" list, and voice. Point Claude Code / Cursor / Copilot at this before they generate UI.
|
|
70
|
+
- `INTEGRATION.md` — the integration guide: three steps to first paint, the full 117-component index with import paths, token reference, dark mode, interaction states, versioning.
|
|
71
|
+
- `DEPLOY.md` — running the system on GitLab: what ships in the package and what stays on Pages, the entry points, the release flow, and the bundler config each consumer needs.
|
|
72
|
+
- `index.html` · `gallery.html` — the documentation site: the browsable system and the filterable thumbnail grid, both deployed to GitLab Pages by CI.
|
|
73
|
+
- `package.json` · `.gitlab-ci.yml` · `_scripts/` — makes the system an installable package: a version tag publishes to the GitLab Package Registry, the default branch redeploys the docs site, and `npm run check` fails the pipeline if the generated tokens or barrels drift from source.
|
|
105
74
|
|
|
106
|
-
|
|
107
|
-
- `
|
|
108
|
-
- `
|
|
109
|
-
- `
|
|
110
|
-
- `
|
|
75
|
+
**Other files**
|
|
76
|
+
- `styles.css` — global CSS entry (imports all token files); `keybricks.css` — the package's stylesheet entry (tokens + hover hooks).
|
|
77
|
+
- `assets/` — keybricks-logo.png and the icon keyword indexes.
|
|
78
|
+
- `guidelines/` — foundation showcase cards (Design System tab).
|
|
79
|
+
- `ui_kits/keybricks-app/` — interactive product recreation: Home, Documents, Pipeline editor, System Migration.
|
|
80
|
+
- `SKILL.md` — agent skill entry file.
|
|
111
81
|
|
|
112
|
-
## Components
|
|
113
|
-
- `components/icons/` — Icon
|
|
114
|
-
- `components/buttons/` — Button
|
|
115
|
-
- `components/forms/` — Field
|
|
116
|
-
- `components/tabs/` — Tabs
|
|
117
|
-
- `components/display/` — Card
|
|
118
|
-
- `components/feedback/` — Stepper
|
|
119
|
-
- `components/data/` —
|
|
120
|
-
- `components/navigation/` — Sidebar
|
|
121
|
-
- `components/pipeline/` — NodeCard
|
|
122
|
-
- `components/
|
|
123
|
-
- `components/charts/` — 图表模块(27 种):Sparkline、LineChart、BarChart、BarList、DonutChart、ScatterChart、HeatmapChart、WaterfallChart、BulletChart、GaugeChart、FunnelChart、TreemapChart、RadarChart、Histogram、BoxPlot、ParetoChart、CandlestickChart、SankeyChart、ChordChart、SunburstChart、WorldMap、GanttChart,以及 3D 系列 Surface3D、Scatter3D、Bar3D、Pie3D、Ribbon3D(SVG 画家算法渲染,拖拽旋转;+ ChartKit 共享图例/提示,`tokens/charts.css` 序列色与绘图配件)。三个尺寸层级:统计卡内微型、卡片内交互中型、整页分析大型;每种图表在任何尺寸都保留悬停读数。WorldMap 使用真实 Natural Earth 地理数据,需页面加载固定版本的 d3 与 topojson。
|
|
82
|
+
## Components
|
|
83
|
+
- `components/icons/` — Icon (+ ICON_PATHS glyph data + feather-paths.js, the full Feather fallback), Unicon (Unicons CDN webfont).
|
|
84
|
+
- `components/buttons/` — Button, IconButton, ActionChip.
|
|
85
|
+
- `components/forms/` — Field, Input, Textarea, Select, SearchInput, Checkbox, NumberStepper, Dropzone, Switch, Radio, RadioGroup, Combobox, MultiSelect, DatePicker, Slider.
|
|
86
|
+
- `components/tabs/` — Tabs, PanelTabs, PillTabs, ViewToggle, SegmentedControl.
|
|
87
|
+
- `components/display/` — Card, StatCard, Badge, StatusBadge, IconTile, ProgressBar, Donut, AreaChart, MiniBars, Avatar, AvatarGroup, Tag, Divider, Kbd.
|
|
88
|
+
- `components/feedback/` — Stepper, ContextMenu, ActivityItem, DotActivity, LogViewer, Tooltip, Modal, Toast, ToastStack, Alert, EmptyState, Skeleton, Spinner, Menu, Accordion, Banner, Drawer, Timeline.
|
|
89
|
+
- `components/data/` — Table, ListRow, Pagination, KeyValue, KeyValueList, DiffValue, CodeBlock, Spreadsheet, SmartTable, FilterBar.
|
|
90
|
+
- `components/navigation/` — Sidebar (+ KEYBRICKS_NAV), TopBar, PageToolbar, PageHeading, DocTree, Breadcrumb, Tree, ThemeToggle (+ applyStoredTheme).
|
|
91
|
+
- `components/pipeline/` — NodeCard, Port, PortLabel, PaletteItem, PaletteListItem, PalettePanel (+ PIPELINE_CATALOG), PipelineCanvas, DataPreview, ConfigPanel, ZoomControls.
|
|
92
|
+
- `components/charts/` — 27 chart types: Sparkline, LineChart, BarChart, BarList, DonutChart, ScatterChart, HeatmapChart, WaterfallChart, BulletChart, GaugeChart, FunnelChart, TreemapChart, RadarChart, Histogram, BoxPlot, ParetoChart, CandlestickChart, SankeyChart, ChordChart, SunburstChart, WorldMap, GanttChart, and the 3D set Surface3D, Scatter3D, Bar3D, Pie3D, Ribbon3D (SVG painter's-algorithm rendering, drag to rotate; + ChartKit shared legend/tooltip, `tokens/charts.css` series colors and plot furniture). Three scales: micro inside stat tiles, interactive mid-size inside cards, full-page analysis; every chart keeps its hover read-out at every scale. WorldMap uses real Natural Earth geography and needs the page to load pinned d3 and topojson.
|
|
124
93
|
|
|
125
|
-
## Intentional additions
|
|
94
|
+
## Intentional additions
|
|
126
95
|
These extend the original inventory — each is a standard need this product clearly has, built only from the extracted foundations (no new colors, radii, or type sizes):
|
|
127
|
-
|
|
128
|
-
- `
|
|
129
|
-
- `
|
|
130
|
-
- `
|
|
131
|
-
- `
|
|
132
|
-
- `
|
|
133
|
-
- `
|
|
134
|
-
- `
|
|
135
|
-
- `
|
|
136
|
-
- `
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
- `
|
|
140
|
-
- `
|
|
141
|
-
- `
|
|
142
|
-
- `
|
|
143
|
-
- `
|
|
144
|
-
|
|
145
|
-
- `
|
|
146
|
-
- `
|
|
147
|
-
- `
|
|
148
|
-
- `
|
|
149
|
-
- `
|
|
150
|
-
- Token 补充:`tokens/motion.css`、层级(z-index)体系。
|
|
96
|
+
- `Icon` — icon wrapper component.
|
|
97
|
+
- `Switch`, `Radio`/`RadioGroup` — settings toggles and single choice.
|
|
98
|
+
- `SegmentedControl` — view/range switching (a generalisation of the existing `ViewToggle`).
|
|
99
|
+
- `Tooltip`, `Modal`, `Toast`/`ToastStack` — confirmation and notification.
|
|
100
|
+
- `Alert`, `EmptyState`, `Skeleton`, `Spinner` — empty, loading and error states.
|
|
101
|
+
- `Breadcrumb` — breadcrumb navigation (hierarchy reaches three levels, e.g. Management → System Migration → Import).
|
|
102
|
+
- `Pagination` — table paging.
|
|
103
|
+
- `Avatar`/`AvatarGroup` — avatars; tinted initials when no photo exists, pass `src` for a real image.
|
|
104
|
+
- `ThemeToggle` + `applyStoredTheme` — drive dark mode.
|
|
105
|
+
- `KeyValue`/`KeyValueList`, `DiffValue` — the "label / value" and "before → after" patterns that recur in config summaries and the migration confirmation step.
|
|
106
|
+
- **Enterprise pack** (drawn from the common inventory of IBM Carbon, SAP Fiori, Salesforce Lightning and Workday Canvas; existing tokens only):
|
|
107
|
+
- `Spreadsheet` — Excel-style sheet: formula bar (name box + fx), frozen letter/number headers, click and Shift-click range selection, double-click editing, live `=SUM()/AVERAGE()` formulas, sheet tabs, Sum/Avg/Count status bar.
|
|
108
|
+
- `SmartTable` — Notion/Airtable/Coda-style database grid: field headers with type icons (text/number/select/multiSelect/date/person/checkbox/url/progress), theme-aware colored option pills (`--hue-*`), row hover + expand button, double-click inline editing, "+ New" row and field columns, COUNT/SUM/AVG footer aggregates, view toolbar (Hide fields/Filter/Group/Sort/search).
|
|
109
|
+
- `FilterBar` — Fiori-style list-report filter bar (variant name + expand/collapse + Adapt Filters (n) + Go).
|
|
110
|
+
- `Combobox` — type-to-filter single-select dropdown; `MultiSelect` — multi-select dropdown (tags + "+n" overflow + clear all).
|
|
111
|
+
- `DatePicker` — calendar popover date picker; `Slider` — slider (drag bubble + min/max labels).
|
|
112
|
+
- `Drawer` — right-hand slide-out detail panel; `Banner` — page-level notification (distinct from in-card Alert and floating Toast); `Timeline` — vertical activity timeline; `Tree` — general nested tree (cascading checks, async loading, search highlight, drag into folder, keyboard navigation).
|
|
113
|
+
- `Tag`, `Divider`, `Kbd` — filter tags, separators and shortcut hints that were hand-built over and over in the UI.
|
|
114
|
+
- `Menu` (dropdown anchored under its trigger, distinct from `ContextMenu`, which opens at the click point), `Accordion` (general collapsible section, distinct from `ListRow`, which is specific to workflow documents).
|
|
115
|
+
- `CodeBlock` — mono code block with a Copy button, for SQL Preview and exported-JSON previews.
|
|
116
|
+
- `ZoomControls` — zoom controls for the pipeline canvas; the source implied pan/zoom but gave no control for it.
|
|
117
|
+
- `StatCard`/`Donut`/`ProgressBar`/`AreaChart`/`MiniBars` — built-in chart widgets, so small dashboards need no chart library.
|
|
118
|
+
- Token additions: `tokens/motion.css` and the z-index scale.
|