@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
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<!-- @dsCard group="Components" viewport="
|
|
1
|
+
<!-- @dsCard group="Components" viewport="700x1620" name="Pipeline Node Card" subtitle="220×90 node — category hues · status badges · ports with hover, drag-to-connect and drop states" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
-
<style>body{margin:0;background:var(--bg-surface);padding:18px;font-family:var(--font-sans);box-sizing:border-box}.lbl{font-size:
|
|
9
|
+
<style>body{margin:0;background:var(--bg-surface);padding:18px;font-family:var(--font-sans);box-sizing:border-box}.lbl{font-size:var(--text-xs);color:var(--text-muted);display:block;padding-bottom:14px}.row{display:flex;flex-wrap:wrap;gap:34px 46px;padding-bottom:26px}.sec{padding-bottom:6px}.note{border-top:1px solid var(--border-subtle);padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
|
|
10
10
|
<body><div id="root"></div>
|
|
11
11
|
<script type="text/babel">
|
|
12
12
|
const { NodeCard, Port, PortLabel, PipelineCanvas } = window.KeybricksDesignSystem_71231a;
|
|
@@ -49,11 +49,11 @@ function Sheet(){
|
|
|
49
49
|
<div className="sec">
|
|
50
50
|
<span className="lbl">Port states — rest, hover, dragging, drop target</span>
|
|
51
51
|
<div className="row" style={{alignItems:"center",gap:"18px 30px",paddingBottom:18}}>
|
|
52
|
-
<span style={{display:"flex",alignItems:"center",gap:10}}><Port/><code style={{fontFamily:"var(--font-mono)",fontSize:
|
|
53
|
-
<span style={{display:"flex",alignItems:"center",gap:10}}><Port interactive/><code style={{fontFamily:"var(--font-mono)",fontSize:
|
|
54
|
-
<span style={{display:"flex",alignItems:"center",gap:10}}><Port tone="active"/><code style={{fontFamily:"var(--font-mono)",fontSize:
|
|
55
|
-
<span style={{display:"flex",alignItems:"center",gap:10}}><Port tone="target"/><code style={{fontFamily:"var(--font-mono)",fontSize:
|
|
56
|
-
<span style={{display:"flex",alignItems:"center",gap:10}}><PortLabel label="A"/><PortLabel label="B" interactive/><PortLabel label="B" tone="target"/><code style={{fontFamily:"var(--font-mono)",fontSize:
|
|
52
|
+
<span style={{display:"flex",alignItems:"center",gap:10}}><Port/><code style={{fontFamily:"var(--font-mono)",fontSize:"var(--text-xs)",color:"var(--text-secondary)"}}>rest</code></span>
|
|
53
|
+
<span style={{display:"flex",alignItems:"center",gap:10}}><Port interactive/><code style={{fontFamily:"var(--font-mono)",fontSize:"var(--text-xs)",color:"var(--text-secondary)"}}>hover me</code></span>
|
|
54
|
+
<span style={{display:"flex",alignItems:"center",gap:10}}><Port tone="active"/><code style={{fontFamily:"var(--font-mono)",fontSize:"var(--text-xs)",color:"var(--text-secondary)"}}>active</code></span>
|
|
55
|
+
<span style={{display:"flex",alignItems:"center",gap:10}}><Port tone="target"/><code style={{fontFamily:"var(--font-mono)",fontSize:"var(--text-xs)",color:"var(--text-secondary)"}}>target</code></span>
|
|
56
|
+
<span style={{display:"flex",alignItems:"center",gap:10}}><PortLabel label="A"/><PortLabel label="B" interactive/><PortLabel label="B" tone="target"/><code style={{fontFamily:"var(--font-mono)",fontSize:"var(--text-xs)",color:"var(--text-secondary)"}}>A/B pills</code></span>
|
|
57
57
|
</div>
|
|
58
58
|
<span className="lbl">Drag to connect — hold an output port and drop it on an input</span>
|
|
59
59
|
<div style={{border:"1px solid var(--border-card)",borderRadius:"var(--radius-lg)",overflow:"hidden",height:250}}>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<!-- @dsCard group="Components" viewport="700x690" name="Pipeline Palette" subtitle="240px component drawer — grid/list toggle · collapsible hued categories" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
-
<style>body{margin:0;background:var(--bg-surface);padding:18px;font-family:var(--font-sans);box-sizing:border-box}.lbl{font-size:
|
|
9
|
+
<style>body{margin:0;background:var(--bg-surface);padding:18px;font-family:var(--font-sans);box-sizing:border-box}.lbl{font-size:var(--text-xs);color:var(--text-muted);display:block;padding-bottom:8px}.g{display:flex;gap:28px;align-items:flex-start}.pane{border:1px solid var(--border-card);border-radius:var(--radius-lg);overflow:hidden;height:390px;width:242px}.bits{flex:1;min-width:0}.bitrow{display:flex;align-items:center;gap:16px;padding:6px 0}.hint{font-size:var(--text-xs);line-height:16px;color:var(--text-secondary);padding-top:8px}.hint code{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-body)}.note{border-top:1px solid var(--border-subtle);margin-top:18px;padding-top:12px;font-size:var(--text-xs);line-height:17px;color:var(--text-secondary)}.note code{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-body)}.note strong{color:var(--text-heading);font-weight:var(--weight-medium)}</style></head>
|
|
10
10
|
<body><div id="root"></div>
|
|
11
11
|
<script type="text/babel">
|
|
12
12
|
const { PalettePanel, PaletteItem, PaletteListItem, PIPELINE_CATALOG } = window.KeybricksDesignSystem_71231a;
|
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
<!-- @dsCard group="Components" viewport="
|
|
1
|
+
<!-- @dsCard group="Components" viewport="700x1120" name="Radio Button" subtitle="Single choice from a small set — md/sm · description · disabled · row · card variant · arrow-key navigation" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
-
<
|
|
9
|
+
<script src="../_shared/card-kit.js"></script>
|
|
10
|
+
<style>body{margin:0;padding:20px 24px;font-family:var(--font-sans);background:var(--bg-surface)}.sec{font-size:var(--text-xs);font-weight:600;color:var(--text-muted);padding:18px 0 6px;border-top:1px solid var(--border-subtle);margin-top:14px}.sec:first-child{border-top:none;margin-top:0;padding-top:0}.case{display:grid;grid-template-columns:170px 1fr;align-items:start;gap:20px;padding:6px 0}.k{font-size:var(--text-xs);color:var(--text-secondary);font-family:var(--font-sans);padding-top:2px}.v{display:flex;align-items:flex-start;gap:24px;flex-wrap:wrap}.note{font-size:var(--text-xs);line-height:17px;color:var(--text-secondary);max-width:60ch;padding-top:6px}a{color:var(--link)}a:hover{color:var(--link-hover)}.kb-h-gap{margin:28px 0 12px}.kb-h-gap:first-child{margin-top:0}</style>
|
|
10
11
|
</head><body><div id="root"></div>
|
|
11
12
|
<script type="text/babel">
|
|
12
13
|
const { Radio, RadioGroup } = window.KeybricksDesignSystem_71231a;
|
|
14
|
+
const { KBTiers: Tiers } = window;
|
|
13
15
|
const Case = ({ k, children }) => <div className="case"><span className="k">{k}</span><div className="v">{children}</div></div>;
|
|
14
16
|
function Sheet() {
|
|
15
17
|
const [a, setA] = React.useState("Overwrite"), [b, setB] = React.useState("Ascending"), [c, setC] = React.useState("weekly"), [d, setD] = React.useState("merge"), [e, setE] = React.useState("USD"), [s1, setS1] = React.useState(true), [s2, setS2] = React.useState(true), [s3, setS3] = React.useState(false);
|
|
16
18
|
return <div>
|
|
17
|
-
<div className="
|
|
19
|
+
<div className="kb-h kb-h-gap">Single radio</div>
|
|
18
20
|
<Case k="md · sm"><Radio checked={s1} onChange={() => setS1(true)} label="Selected" /><Radio checked={!s1} onChange={() => setS1(false)} label="Unselected" /><Radio size="sm" checked={s2} onChange={() => setS2(true)} label="Small" /><Radio size="sm" checked={!s2} onChange={() => setS2(false)} label="Small" /></Case>
|
|
19
21
|
<Case k="disabled"><Radio checked disabled label="Locked on" /><Radio disabled label="Locked off" /></Case>
|
|
20
22
|
<Case k="description"><Radio checked={!s3} onChange={() => setS3(false)} label="Weekly digest" description="One summary every Monday morning" /><Radio checked={s3} onChange={() => setS3(true)} label="Daily" description="Every morning at 08:00" /></Case>
|
|
21
23
|
|
|
22
|
-
<div className="
|
|
24
|
+
<div className="kb-h kb-h-gap">RadioGroup — vertical (default)</div>
|
|
23
25
|
<Case k='options: string[]'><RadioGroup options={["New", "Overwrite", "Skip"]} value={a} onChange={setA} /></Case>
|
|
24
26
|
<Case k="with descriptions"><RadioGroup value={c} onChange={setC} options={[
|
|
25
27
|
{ label: "Weekly digest", value: "weekly", description: "One summary every Monday" },
|
|
@@ -27,12 +29,15 @@ function Sheet() {
|
|
|
27
29
|
{ label: "Never", value: "never", description: "Only in-app notifications", disabled: true }
|
|
28
30
|
]} /></Case>
|
|
29
31
|
|
|
30
|
-
<div className="
|
|
32
|
+
<div className="kb-h kb-h-gap">Size tiers — Latin and CJK labels</div>
|
|
33
|
+
<Tiers stack init={(l)=>l==="en"?"Ascending":"升序"} render={(t,l,v,set)=><RadioGroup row options={l==="en"?["Ascending","Descending"]:["升序","降序"]} value={v} onChange={set}/>}/>
|
|
34
|
+
|
|
35
|
+
<div className="kb-h kb-h-gap">RadioGroup — row · sm</div>
|
|
31
36
|
<Case k="row"><RadioGroup row options={["USD", "EUR", "CNY", "JPY"]} value={e} onChange={setE} /></Case>
|
|
32
37
|
<Case k='row · size="sm"'><RadioGroup row size="sm" options={["Ascending", "Descending"]} value={b} onChange={setB} /></Case>
|
|
33
38
|
<Case k="disabled group"><RadioGroup row disabled options={["Draft", "Published"]} value="Draft" /></Case>
|
|
34
39
|
|
|
35
|
-
<div className="
|
|
40
|
+
<div className="kb-h kb-h-gap">RadioGroup — card variant</div>
|
|
36
41
|
<Case k='variant="cards" row'><RadioGroup variant="cards" row value={d} onChange={setD} style={{ width: 460 }} options={[
|
|
37
42
|
{ label: "Merge", value: "merge", description: "Keep target values, add new keys" },
|
|
38
43
|
{ label: "Overwrite", value: "overwrite", description: "Target takes source values" },
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
<!-- @dsCard group="Components" viewport="
|
|
1
|
+
<!-- @dsCard group="Components" viewport="700x520" name="Search Input" subtitle="Bordered · bare top-bar · with value/clear · disabled" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
-
<
|
|
9
|
+
<script src="../_shared/card-kit.js"></script>
|
|
10
|
+
<style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans);box-sizing:border-box}.row{display:flex;flex-direction:column;gap:6px}.lbl{font-size:var(--text-xs);color:var(--text-muted)}.dark-strip{background:var(--neutral-900);border-radius:8px;padding:14px}</style></head>
|
|
10
11
|
<body><div id="root"></div>
|
|
11
12
|
<script type="text/babel">
|
|
12
13
|
const { SearchInput } = window.KeybricksDesignSystem_71231a;
|
|
14
|
+
const { KBTiers: Tiers } = window;
|
|
13
15
|
function Sheet(){return <div style={{display:"flex",flexDirection:"column",gap:14}}>
|
|
14
16
|
<div className="row"><span className="lbl">Empty</span><SearchInput style={{width:260}}/></div>
|
|
15
17
|
<div className="row"><span className="lbl">With value (shows clear ×)</span><SearchInput defaultValue="Budget 2026" style={{width:260}}/></div>
|
|
16
18
|
<div className="row"><span className="lbl">Disabled</span><SearchInput placeholder="Search unavailable" disabled style={{width:260}}/></div>
|
|
17
|
-
<div
|
|
18
|
-
<div style={{display:"flex",gap:16,alignItems:"center",flexWrap:"wrap"}}><div data-size="sm"><SearchInput placeholder="Search…" style={{width:180}}/></div><div data-size="md"><SearchInput placeholder="Search…" style={{width:200}}/></div><div data-size="lg"><SearchInput placeholder="Search…" style={{width:220}}/></div></div>
|
|
19
|
-
</div>
|
|
19
|
+
<div style={{gridColumn:"1 / -1",display:"flex",flexDirection:"column",gap:8}}><span className="lbl">Size tiers — data-size on the region, the control inherits it</span><Tiers render={(t,l)=><SearchInput placeholder={l==="en"?"Search…":"搜索…"} style={{width:150}}/>}/></div>
|
|
20
20
|
<div className="row"><span className="lbl">Bare — top bar flavor, on dark chrome</span>
|
|
21
21
|
<div className="dark-strip"><SearchInput bare placeholder="Search documents, workflows, data..." style={{width:320}}/></div>
|
|
22
22
|
</div>
|
|
@@ -1,39 +1,46 @@
|
|
|
1
|
-
<!-- @dsCard group="Components" viewport="
|
|
1
|
+
<!-- @dsCard group="Components" viewport="700x1260" name="Segmented Control" subtitle="Mutually exclusive views in one inset track — md/sm · counts · icons · icon-only · disabled option · full width · ViewToggle" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
-
<
|
|
9
|
+
<script src="../_shared/card-kit.js"></script>
|
|
10
|
+
<style>body{margin:0;padding:20px 24px;font-family:var(--font-sans);background:var(--bg-surface)}.sec{font-size:var(--text-xs);font-weight:600;color:var(--text-muted);padding:18px 0 6px;border-top:1px solid var(--border-subtle);margin-top:14px}.sec:first-child{border-top:none;margin-top:0;padding-top:0}.case{display:grid;grid-template-columns:170px 1fr;align-items:center;gap:20px;min-height:36px;padding:5px 0}.k{font-size:var(--text-xs);color:var(--text-secondary);font-family:var(--font-sans)}.v{display:flex;align-items:center;gap:20px;flex-wrap:wrap}.note{font-size:var(--text-xs);line-height:17px;color:var(--text-secondary);max-width:60ch;padding-top:6px}a{color:var(--link)}a:hover{color:var(--link-hover)}.kb-h-gap{margin:28px 0 12px}.kb-h-gap:first-child{margin-top:0}</style>
|
|
10
11
|
</head><body><div id="root"></div>
|
|
11
12
|
<script type="text/babel">
|
|
12
13
|
const { SegmentedControl, ViewToggle } = window.KeybricksDesignSystem_71231a;
|
|
14
|
+
const { KBTiers: Tiers } = window;
|
|
13
15
|
const Case = ({ k, children }) => <div className="case"><span className="k">{k}</span><div className="v">{children}</div></div>;
|
|
14
16
|
function Sheet() {
|
|
15
|
-
const [a, setA] = React.useState("Grid"), [b, setB] = React.useState("Last 30 days"), [c, setC] = React.useState("Table"), [d, setD] = React.useState("Actual"), [e, setE] = React.useState("Month"), [f, setF] = React.useState("Overview"), [v, setV] = React.useState("grid");
|
|
17
|
+
const [n, setN] = React.useState("Submission"), [a, setA] = React.useState("Grid"), [b, setB] = React.useState("Last 30 days"), [c, setC] = React.useState("Table"), [d, setD] = React.useState("Actual"), [e, setE] = React.useState("Month"), [f, setF] = React.useState("Overview"), [v, setV] = React.useState("grid");
|
|
16
18
|
return <div>
|
|
17
|
-
<div className="
|
|
18
|
-
<
|
|
19
|
-
<Case k="sm"><SegmentedControl size="sm" options={["Last 7 days", "Last 30 days", "Quarter"]} value={b} onChange={setB} /></Case>
|
|
19
|
+
<div className="kb-h kb-h-gap">Sizes</div>
|
|
20
|
+
<Tiers stack style={{gridTemplateColumns:"56px repeat(2,max-content)",columnGap:16}} init={(l)=>l==="en"?"Last 30 days":"近 30 天"} render={(t,l,v,set)=><SegmentedControl options={l==="en"?["Last 7 days","Last 30 days","Quarter"]:["近 7 天","近 30 天","本季度"]} value={v} onChange={set}/>}/>
|
|
20
21
|
|
|
21
|
-
<div className="
|
|
22
|
+
<div className="kb-h kb-h-gap">Counts</div>
|
|
23
|
+
<Case k="count on an option"><SegmentedControl options={[{ label: "Submission", count: 3 }, { label: "Review", count: 12 }, { label: "Approved", count: 0 }]} value={n} onChange={setN} /></Case>
|
|
24
|
+
<Case k="showZero · muted 0"><SegmentedControl showZero options={[{ label: "Submission", count: 3 }, { label: "Review", count: 12 }, { label: "Approved", count: 0 }]} value={n} onChange={setN} /></Case>
|
|
25
|
+
<Case k="sizes"><div style={{ display: "flex", flexDirection: "column", gap: 12, alignItems: "flex-start" }}>{["sm", "md", "lg"].map(s => <SegmentedControl key={s} size={s} options={[{ label: "Submission", count: 3 }, { label: "Review", count: 12 }, { label: "Approved" }]} value={n} onChange={setN} />)}</div></Case>
|
|
26
|
+
<div className="note">The badge sits 6px right of the label: <code>--count-h</code> tall (sm 16 · md 18 · lg 20), 6px sides, full radius, 12px tabular figures. The fill is the alpha wash <code>--neutral-alpha-8</code>, so it shows on the white active segment and the #fafafa track alike; the text tells them apart — <code>--text-heading</code> selected, <code>--text-body</code> unselected. A count of 0 or none hides it; <code>showZero</code> (on the control or the option) draws a muted 0. The selected value is still matched by label.</div>
|
|
27
|
+
|
|
28
|
+
<div className="kb-h kb-h-gap">With icons</div>
|
|
22
29
|
<Case k="icon + label"><SegmentedControl options={[{ label: "List", icon: "list" }, { label: "Grid", icon: "layout-grid" }]} value={a} onChange={setA} /></Case>
|
|
23
30
|
<Case k="icon only · aria label"><SegmentedControl options={[{ icon: "table", label: "Table" }, { icon: "chart-column", label: "Chart" }, { icon: "code", label: "JSON" }]} iconOnly value={c} onChange={setC} /></Case>
|
|
24
31
|
|
|
25
|
-
<div className="
|
|
32
|
+
<div className="kb-h kb-h-gap">States</div>
|
|
26
33
|
<Case k="disabled option"><SegmentedControl options={[{ label: "Month" }, { label: "Quarter" }, { label: "Year", disabled: true }]} value={e} onChange={setE} /></Case>
|
|
27
34
|
<Case k="disabled control"><SegmentedControl disabled options={["Actual", "Budget"]} value="Actual" /></Case>
|
|
28
35
|
|
|
29
|
-
<div className="
|
|
36
|
+
<div className="kb-h kb-h-gap">Layout</div>
|
|
30
37
|
<Case k="fullWidth"><SegmentedControl fullWidth options={["Overview", "Details", "History"]} value={f} onChange={setF} style={{ width: 400 }} /></Case>
|
|
31
38
|
|
|
32
|
-
<div className="
|
|
39
|
+
<div className="kb-h kb-h-gap">ViewToggle — the two-state shorthand</div>
|
|
33
40
|
<Case k="list / grid"><ViewToggle value={v} onChange={setV} /></Case>
|
|
34
41
|
<div className="note">Segmented control switches <em>views of the same data</em> and applies instantly — never for a form value that gets saved (that's <code>RadioGroup</code>) and never for navigation between pages (that's <code>Tabs</code>). 2–5 options, labels one or two words. <code>ViewToggle</code> is the fixed list/grid pair used in panel headers.</div>
|
|
35
42
|
</div>;
|
|
36
43
|
}
|
|
37
44
|
ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
|
|
38
|
-
if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"SegmentedControl.jsx","path":"../tabs/SegmentedControl.jsx"},{"name":"ViewToggle.jsx","path":"../tabs/ViewToggle.jsx"}]); }, 0);
|
|
45
|
+
if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"SegmentedControl.jsx","path":"../tabs/SegmentedControl.jsx"},{"name":"Tabs.jsx (CountBadge)","path":"../tabs/Tabs.jsx","vue":"../tabs/CountBadge.vue","vueName":"CountBadge.vue"},{"name":"ViewToggle.jsx","path":"../tabs/ViewToggle.jsx"}]); }, 0);
|
|
39
46
|
</script></body></html>
|
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
<!-- @dsCard group="Components" viewport="
|
|
1
|
+
<!-- @dsCard group="Components" viewport="700x430" name="Select" subtitle="md / sm · placeholder · disabled · error" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
+
<script src="../_shared/card-kit.js"></script>
|
|
9
10
|
<style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans);box-sizing:border-box}.g{display:grid;grid-template-columns:repeat(3,1fr);gap:16px 12px}</style></head>
|
|
10
11
|
<body><div id="root"></div>
|
|
11
12
|
<script type="text/babel">
|
|
12
13
|
const { Select, Field } = window.KeybricksDesignSystem_71231a;
|
|
14
|
+
const { KBLive: Live } = window;
|
|
15
|
+
const { KBTiers: Tiers } = window;
|
|
13
16
|
function Sheet(){return <div className="g">
|
|
14
17
|
<Field label="Default (md)"><Select options={["All Modules","Financial Settings","User Management"]}/></Field>
|
|
15
18
|
<Field label="Placeholder, unselected"><Select options={["New","Overwrite","Skip"]} placeholder="Choose an action"/></Field>
|
|
16
19
|
<Field label="Disabled"><Select options={["USD","EUR"]} value="USD" disabled/></Field>
|
|
17
|
-
<Field label="sm — dense regions"><Select size="sm" options={["New","Overwrite","Skip"]} value=
|
|
20
|
+
<Field label="sm — dense regions"><Live init="Overwrite">{(v,set)=><Select size="sm" options={["New","Overwrite","Skip"]} value={v} onChange={(e)=>set(e && e.target ? e.target.value : e)}/>}</Live></Field>
|
|
18
21
|
<Field label="Required, unselected" required error="Select a target module"><Select options={["Financial Settings","User Management"]} placeholder="Select module" error/></Field>
|
|
19
22
|
<Field label="sm, disabled"><Select size="sm" options={["New","Overwrite","Skip"]} value="Skip" disabled/></Field>
|
|
23
|
+
<div style={{gridColumn:"1 / -1",display:"flex",flexDirection:"column",gap:8}}><span className="lbl">Size tiers — data-size on the region, the control inherits it</span><Tiers stack init={(l)=>l==="en"?"Overwrite":"覆盖"} render={(t,l,v,set)=><div style={{width:200}}><Select options={l==="en"?["New","Overwrite","Skip"]:["新增","覆盖","跳过"]} value={v} onChange={(e)=>set(e && e.target ? e.target.value : e)}/></div>}/></div>
|
|
20
24
|
</div>;}
|
|
21
25
|
ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
|
|
22
26
|
if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"Select.jsx","path":"../forms/Select.jsx"},{"name":"Field.jsx","path":"../forms/Field.jsx"}]); }, 0);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<!-- @dsCard group="Components" viewport="700x300" name="Slider" subtitle="Filled track · ring knob · value bubble · min/max labels" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
-
<style>body{margin:0;background:var(--bg-surface);padding:16px 16px 24px;font-family:var(--font-sans);box-sizing:border-box}.g{display:grid;grid-template-columns:repeat(2,1fr);gap:22px 24px}.lbl{font-size:
|
|
9
|
+
<style>body{margin:0;background:var(--bg-surface);padding:16px 16px 24px;font-family:var(--font-sans);box-sizing:border-box}.g{display:grid;grid-template-columns:repeat(2,1fr);gap:22px 24px}.lbl{font-size:var(--text-xs);color:var(--text-muted);display:block;padding-bottom:12px}</style></head>
|
|
10
10
|
<body><div id="root"></div>
|
|
11
11
|
<script type="text/babel">
|
|
12
12
|
const { Slider } = window.KeybricksDesignSystem_71231a;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<!-- @dsCard group="Components" viewport="
|
|
1
|
+
<!-- @dsCard group="Components" viewport="700x500" name="Smart Table (Database Grid)" subtitle="Notion/Airtable-style grid — typed fields · hue pills · aggregates · + New" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
-
<style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans);box-sizing:border-box}.hint{font-size:
|
|
9
|
+
<style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans);box-sizing:border-box}.hint{font-size:var(--text-xs);color:var(--text-secondary);padding-top:10px;line-height:1.5}</style></head>
|
|
10
10
|
<body><div id="root"></div>
|
|
11
11
|
<script type="text/babel">
|
|
12
12
|
const { SmartTable } = window.KeybricksDesignSystem_71231a;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<!-- @dsCard group="Components" viewport="924x560" name="Spreadsheet" subtitle="Formula bar · frozen headers · range selection · =SUM() · sheet tabs · status bar" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
-
<style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans);box-sizing:border-box}.lbl{font-size:
|
|
9
|
+
<style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans);box-sizing:border-box}.lbl{font-size:var(--text-xs);color:var(--text-muted);display:block;padding-bottom:8px}.hint{font-size:var(--text-xs);color:var(--text-secondary);padding-top:10px;line-height:1.5}</style></head>
|
|
10
10
|
<body><div id="root"></div>
|
|
11
11
|
<script type="text/babel">
|
|
12
12
|
const { Spreadsheet } = window.KeybricksDesignSystem_71231a;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<!-- @dsCard group="Components" viewport="700x450" name="Stepper" subtitle="Multi-step flow header — done · current · upcoming" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
-
<style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans);box-sizing:border-box}.lbl{font-size:
|
|
9
|
+
<style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans);box-sizing:border-box}.lbl{font-size:var(--text-xs);color:var(--text-muted);display:block;padding-bottom:8px}</style></head>
|
|
10
10
|
<body><div id="root"></div>
|
|
11
11
|
<script type="text/babel">
|
|
12
12
|
const { Stepper } = window.KeybricksDesignSystem_71231a;
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
<!-- @dsCard group="Components" viewport="
|
|
1
|
+
<!-- @dsCard group="Components" viewport="700x6150" name="Table" subtitle="Anatomy · densities · column types · two-line name · sorting · selection · frames · column resize · states · composition" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css">
|
|
3
|
+
<html><head><meta charset="utf-8"><script src="../_shared/frame-theme.js"></script><link rel="stylesheet" href="../../styles.css"><link rel="stylesheet" href="../../tokens/hover.css"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
4
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
5
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
6
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
7
|
<script src="../../_ds_bundle.js"></script>
|
|
8
8
|
<script src="../_shared/view-source.js"></script>
|
|
9
|
-
<
|
|
9
|
+
<script src="../_shared/card-kit.js"></script>
|
|
10
|
+
<style>body{margin:0;background:var(--bg-surface);padding:20px 24px;font-family:var(--font-sans);box-sizing:border-box}.sec{font-size:var(--text-xs);font-weight:600;color:var(--text-muted);padding:20px 0 4px;border-top:1px solid var(--border-subtle);margin-top:18px}.sec:first-child{border-top:none;margin-top:0;padding-top:0}.case{padding:10px 0 4px}.k{font-size:var(--text-xs);color:var(--text-secondary);font-family:var(--font-sans);display:block;padding-bottom:8px}.note{font-size:var(--text-xs);line-height:17px;color:var(--text-secondary);max-width:64ch;padding:6px 0 0}.note code{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--text-heading)}.grey{background:var(--bg-app);padding:16px;border-radius:var(--radius-lg)}a{color:var(--link)}a:hover{color:var(--link-hover)}.kb-h-gap{margin:28px 0 12px}.kb-h-gap:first-child{margin-top:0}</style></head>
|
|
10
11
|
<body><div id="root"></div>
|
|
11
12
|
<script type="text/babel">
|
|
12
13
|
const { Table, Select, Badge, Pagination, EmptyState, Skeleton, IconButton } = window.KeybricksDesignSystem_71231a;
|
|
14
|
+
const { KBLive: Live } = window;
|
|
15
|
+
const { KBTiers: Tiers } = window;
|
|
13
16
|
const Case = ({ k, children }) => <div className="case"><span className="k">{k}</span>{children}</div>;
|
|
14
|
-
const CFG = [{ key: "module", label: "Module", width: 150 }, { key: "code", label: "Code",
|
|
17
|
+
const CFG = [{ key: "module", label: "Module", width: 150 }, { key: "code", label: "Code", code: true, width: 200 }, { key: "cur", label: "Current Value" }, { key: "next", label: "New Value" }];
|
|
15
18
|
const CFG_ROWS = [
|
|
16
19
|
{ module: "Financial Settings", code: "FIN_CURRENCY_DEFAULT", cur: "USD", next: "EUR" },
|
|
17
20
|
{ module: "Financial Settings", code: "FIN_DECIMAL_PLACES", cur: "2", next: "2" },
|
|
@@ -23,40 +26,99 @@ const RUN_ROWS = [
|
|
|
23
26
|
{ id: "RUN-1891", doc: "Vendor Master Sync", status: "Failed", rows: "–", fin: "08:12" },
|
|
24
27
|
{ id: "RUN-1890", doc: "FX Rates Refresh", status: "Completed", rows: "312", fin: "06:00" },
|
|
25
28
|
];
|
|
29
|
+
const SORT_COLS = [...RUNS.filter(c => c.key !== "fin").map(c => ({ ...c, sortable: true })), { key: "act", label: "", width: 44, align: "right", render: () => <IconButton icon="ellipsis" size="sm" muted label="Row actions" /> }];
|
|
30
|
+
const SORT_ROWS = [...RUN_ROWS, { id: "RUN-1889", doc: "Intercompany Matching", status: "Partial", rows: "2,048", fin: "05:30" }, { id: "RUN-1888", doc: "Bank Statement Import", status: "Completed", rows: "964", fin: "04:15" }];
|
|
26
31
|
const DENSE = [{ key: "id", label: "ID", mono: true }, { key: "entity", label: "Entity", mono: true }, { key: "customer", label: "Customer", mono: true }, { key: "batch", label: "Batch Code", mono: true }, { key: "qty", label: "Qty", mono: true, align: "right" }];
|
|
27
32
|
const DENSE_ROWS = [
|
|
28
33
|
{ id: "528563", entity: "HK", customer: "A", batch: "HYSTK-1", qty: "4100" },
|
|
29
34
|
{ id: "528564", entity: "SG", customer: "B", batch: "HYSTK-4", qty: "1610" },
|
|
30
35
|
{ id: "528565", entity: "HK", customer: "C", batch: "HYSTK-5", qty: "3200" },
|
|
31
36
|
];
|
|
37
|
+
const DOCS = [{ key: "name", label: "Name", width: 270, minWidth: 200, twoLine: true, sortable: true }, { key: "details", label: "Details", width: 110, sortable: true }, { key: "at", label: "Changed at", mono: true, sortable: true }];
|
|
38
|
+
const DOC_ROWS = [
|
|
39
|
+
{ name: "2026 Budget", description: "Budget cycle FY2026", icon: "folder", hue: "neutral", details: "1 folder · 3 docs" },
|
|
40
|
+
{ name: "Consolidation", description: "Group consolidation model", icon: "folder", hue: "neutral", details: "2 docs" },
|
|
41
|
+
{ name: "FX Rates Model", description: "Average and closing rates", icon: "box", hue: "merge", mark: "favorite", details: "Model Sheet", by: "Luo Lisi", at: "2026-09-17 06:35" },
|
|
42
|
+
{ name: "Opening Balance Sheet — FY26 Group Entities", description: "FY26 opening balances", icon: "table", hue: "join", details: "Detail Sheet", by: "Felix Wang", at: "2026-09-12 09:10" },
|
|
43
|
+
{ name: "Cash Flow Forecast", description: "13-week rolling forecast", icon: "table", hue: "source", details: "Spreadsheet", by: "Guo Kaige", at: "2026-10-16 08:30" },
|
|
44
|
+
];
|
|
45
|
+
const TREE_ROWS = [
|
|
46
|
+
{ id: "budget", name: "2026 Budget", description: "Budget cycle FY2026", icon: "folder", hue: "neutral", details: "1 folder · 2 docs", children: [
|
|
47
|
+
{ id: "q1", name: "Q1 Forecast", description: "Quarterly re-forecast", icon: "folder", hue: "neutral", details: "1 doc", children: [
|
|
48
|
+
{ id: "q1-opex", name: "Opex by Department", description: "Detail sheet", icon: "table", hue: "join", details: "Detail Sheet", at: "2026-10-02 14:20" },
|
|
49
|
+
] },
|
|
50
|
+
{ id: "headcount", name: "Headcount Plan", description: "Hiring by cost centre", icon: "table", hue: "source", details: "Spreadsheet", at: "2026-09-28 10:05" },
|
|
51
|
+
{ id: "capex", name: "Capex Model", description: "Asset additions and depreciation", icon: "box", hue: "merge", details: "Model Sheet", at: "2026-09-21 16:40" },
|
|
52
|
+
] },
|
|
53
|
+
{ id: "consol", name: "Consolidation", description: "Group consolidation model", icon: "folder", hue: "neutral", details: "2 docs", children: [
|
|
54
|
+
{ id: "elim", name: "Intercompany Eliminations", description: "Matched pairs by entity", icon: "table", hue: "join", details: "Detail Sheet", at: "2026-10-12 09:30" },
|
|
55
|
+
{ id: "fx", name: "FX Rates Model", description: "Average and closing rates", icon: "box", hue: "merge", mark: "favorite", details: "Model Sheet", at: "2026-09-17 06:35" },
|
|
56
|
+
] },
|
|
57
|
+
{ id: "cash", name: "Cash Flow Forecast", description: "13-week rolling forecast", icon: "table", hue: "source", details: "Spreadsheet", at: "2026-10-16 08:30" },
|
|
58
|
+
];
|
|
59
|
+
const ZH_LABELS = { sortAsc: "升序排列", sortDesc: "降序排列", sortClear: "取消排序", more: "更多操作", expand: "展开", collapse: "收起" };
|
|
60
|
+
const DOC_ROWS_ZH = [
|
|
61
|
+
{ name: "2026 预算", description: "FY2026 预算周期", icon: "folder", hue: "neutral", details: "3 个文档" },
|
|
62
|
+
{ name: "汇率模型", description: "月平均与期末汇率", icon: "box", hue: "merge", mark: "favorite", details: "模型表", by: "罗丽思", at: "2026-09-17 06:35" },
|
|
63
|
+
];
|
|
32
64
|
|
|
33
65
|
function Sheet() {
|
|
34
66
|
const [sel, setSel] = React.useState([0]);
|
|
35
67
|
const toggle = (w, v) => { if (w === "all") setSel(v ? [0, 1, 2] : []); else setSel(v ? [...sel, w] : sel.filter(i => i !== w)); };
|
|
36
68
|
const [widths, setWidths] = React.useState({ module: 150, code: 200 });
|
|
37
69
|
const [page, setPage] = React.useState(1);
|
|
70
|
+
const [dsel, setDsel] = React.useState([]);
|
|
71
|
+
const dtoggle = (w, v) => { if (w === "all") setDsel(v ? DOC_ROWS.map((_, i) => i) : []); else setDsel(v ? [...dsel, w] : dsel.filter(i => i !== w)); };
|
|
72
|
+
const [moreOn, setMoreOn] = React.useState(null);
|
|
73
|
+
const [srt, setSrt] = React.useState(null);
|
|
74
|
+
const [exp, setExp] = React.useState(["budget"]);
|
|
75
|
+
const [opened, setOpened] = React.useState(null);
|
|
38
76
|
return <div>
|
|
39
|
-
<div className="
|
|
77
|
+
<div className="kb-h kb-h-gap">Anatomy</div>
|
|
40
78
|
<Case k="md — 40px rows · 14px cells · header in weight 600, sentence case · hairline rules">
|
|
41
79
|
<Table bordered columns={RUNS} rows={RUN_ROWS} />
|
|
42
|
-
<div className="note">One rule weight throughout (<code>--border-subtle</code>). The header is set apart by its <code>--bg-table-header</code> tint — never by a heavier line.
|
|
80
|
+
<div className="note">One rule weight throughout (<code>--border-subtle</code>). The header is set apart by its <code>--bg-table-header</code> tint — never by a heavier line. Config-code columns (<code>code</code>) show a code chip — Menlo 12px on the inset fill; amount and ID columns (<code>mono</code>) keep the UI font with tabular figures; <code>align: "right"</code> for quantities.</div>
|
|
43
81
|
</Case>
|
|
44
82
|
|
|
45
|
-
<div className="
|
|
83
|
+
<div className="kb-h kb-h-gap">Densities</div>
|
|
46
84
|
<Case k="md · 40px rows (the default)"><Table bordered columns={CFG} rows={CFG_ROWS.slice(0, 2)} /></Case>
|
|
47
|
-
<Case k="sm ·
|
|
85
|
+
<Case k="sm · 36px rows, 12px text — dense grids and the data-preview drawer"><Table size="sm" bordered columns={DENSE} rows={DENSE_ROWS} /></Case>
|
|
86
|
+
<Case k="sm · CJK — 13px text, regular weight (lang="zh-CN" on the region)"><div lang="zh-CN"><Table size="sm" bordered columns={[{ key: "code", label: "科目代码", mono: true }, { key: "name", label: "科目名称" }, { key: "dept", label: "成本中心" }, { key: "amt", label: "期末余额", mono: true }]} rows={[{ code: "1001", name: "库存现金", dept: "總部財務", amt: "12,480.00" }, { code: "1002", name: "银行存款", dept: "上海分公司", amt: "3,215,906.12" }, { code: "2202", name: "应付账款", dept: "東京支社", amt: "486,300.00" }]} /></div></Case>
|
|
48
87
|
|
|
49
|
-
<div className="
|
|
88
|
+
<div className="kb-h kb-h-gap">Column types</div>
|
|
50
89
|
<Case k="text · mono · align right · render (Badge) · render (Select)">
|
|
51
|
-
<Table bordered columns={[{ ...CFG[1], width: 220 }, { key: "cur", label: "Current Value", align: "right", width: 130 }, { key: "status", label: "Status", width: 120, render: (_, r, i) => <Badge tone={["success", "neutral", "warning"][i]}>{["Match", "Identical", "Conflict"][i]}</Badge> }, { key: "action", label: "Action", width: 160, render: () => <Select options={["New", "Overwrite", "Skip"]} value=
|
|
90
|
+
<Table bordered columns={[{ ...CFG[1], width: 220 }, { key: "cur", label: "Current Value", align: "right", width: 130 }, { key: "status", label: "Status", width: 120, render: (_, r, i) => <Badge tone={["success", "neutral", "warning"][i]}>{["Match", "Identical", "Conflict"][i]}</Badge> }, { key: "action", label: "Action", width: 160, render: () => <Live init="New">{(v, set) => <Select options={["New", "Overwrite", "Skip"]} value={v} onChange={(e)=>set(e && e.target ? e.target.value : e)} style={{ width: 128 }} />}</Live> }]} rows={CFG_ROWS} />
|
|
91
|
+
</Case>
|
|
92
|
+
|
|
93
|
+
<div className="kb-h kb-h-gap">Two-line name</div>
|
|
94
|
+
<Case k="twoLine column — md · 58px rows · header stays 40px · resizable + sortable: the sort button and the ⋯ share the column's right edge">
|
|
95
|
+
<Table bordered resizable selectable selected={dsel} onToggle={dtoggle} columns={DOCS} rows={DOC_ROWS} onRowMore={(r) => setMoreOn(r.name)} />
|
|
96
|
+
<div className="note">Icon tile (<code>IconTile kind="row"</code>, 32px r8, tinted by <code>hue</code>; <code>neutral</code> is the grey folder tile) · 12px · title 14px <code>--text-heading</code> over description 12px <code>--text-secondary</code>, 2px apart, each one line and truncated · sm ⋯ button on the right. <code>mark: "favorite"</code> adds a filled 14px star in <code>--warning</code>. Other cells stay vertically centred and unchanged. Last ⋯ clicked: <code>{moreOn || "none"}</code></div>
|
|
97
|
+
</Case>
|
|
98
|
+
<Case k="tree — rows nest through children · 24px per level · arrow to expand · onRowOpen on the tile and title">
|
|
99
|
+
<Table bordered tree columns={DOCS} rows={TREE_ROWS} expandedKeys={exp} onExpandChange={(r, open, keys) => setExp(keys)} onRowOpen={(r) => setOpened(r.name)} />
|
|
100
|
+
<div className="note">Each level indents 24px; the 20px arrow slot plus 4px puts a child's arrow under its parent's tile. Rows without children keep the slot, so tiles line up. Click a tile or a title to open the row (hand cursor; Enter or Space on the title). Sorting reorders siblings only. Opened: <code>{opened || "none"}</code> · <code>expandedKeys</code>: <code>{JSON.stringify(exp)}</code></div>
|
|
101
|
+
</Case>
|
|
102
|
+
<Case k="sm · 50px rows — 28px tile, 8px to the text, 12px title, 8px padding"><Table size="sm" bordered columns={DOCS} rows={DOC_ROWS.slice(2, 4)} /></Case>
|
|
103
|
+
<Case k="lg · 68px rows — 40px tile r10, 20px icon, 4px between lines, 14px padding"><Table size="lg" bordered columns={DOCS} rows={DOC_ROWS.slice(2, 4)} /></Case>
|
|
104
|
+
<Case k="md · CJK — description 13/18, row 60px (lang="zh-CN") · labels: the sort and ⋯ tooltips in Chinese"><div lang="zh-CN"><Table bordered labels={ZH_LABELS} columns={[{ ...DOCS[0], label: "名称" }, { ...DOCS[1], label: "详情" }, { ...DOCS[2], label: "修改时间" }]} rows={DOC_ROWS_ZH} /></div></Case>
|
|
105
|
+
|
|
106
|
+
<div className="kb-h kb-h-gap">Sorting</div>
|
|
107
|
+
<Case k="sortable — hover a header for the sort button · ascending → descending → none · one column at a time">
|
|
108
|
+
<Table bordered columns={SORT_COLS} rows={SORT_ROWS} sort={srt} onSortChange={setSrt} />
|
|
109
|
+
<div className="note">A muted sm <code>IconButton</code> sits at the header cell's right end — in line with a two-line row's ⋯: shown on hover (<code>arrow-up</code>, “Sort ascending”), then kept while the column is sorted (<code>arrow-up</code> / <code>arrow-down</code>) and the label turns <code>--text-heading</code>. A new column always starts ascending. The action column is not <code>sortable</code>, so it has no button. <code>sort</code>: <code>{srt ? srt.key + " · " + srt.direction : "null"}</code></div>
|
|
110
|
+
</Case>
|
|
111
|
+
<Case k="with resizable — the button sits left of the divider; a long label truncates, the button stays · defaultSort: Rows descending">
|
|
112
|
+
<Table bordered resizable defaultSort={{ key: "rows", direction: "desc" }} columns={[{ key: "id", label: "Run ID", mono: true, width: 110, sortable: true }, { key: "doc", label: "Document", width: 220, sortable: true }, { key: "rows", label: "Rows", mono: true, align: "right", width: 100, sortable: true }, { key: "fin", label: "Finished at (local time)", width: 110, sortable: true }]} rows={SORT_ROWS} />
|
|
52
113
|
</Case>
|
|
114
|
+
<Case k="sm — same button at 28px in a 36px header · defaultSort: Document ascending, so its button shows without hover"><Table size="sm" bordered columns={SORT_COLS.slice(0, 4)} rows={SORT_ROWS.slice(0, 3)} defaultSort={{ key: "doc", direction: "asc" }} /></Case>
|
|
53
115
|
|
|
54
|
-
<div className="
|
|
116
|
+
<div className="kb-h kb-h-gap">Selection</div>
|
|
55
117
|
<Case k="selectable · selected · onToggle — header checkbox is indeterminate on partial">
|
|
56
118
|
<Table bordered selectable selected={sel} onToggle={toggle} columns={CFG} rows={CFG_ROWS} />
|
|
57
119
|
</Case>
|
|
58
120
|
|
|
59
|
-
<div className="
|
|
121
|
+
<div className="kb-h kb-h-gap">Frames</div>
|
|
60
122
|
<Case k="bordered — table draws its own card frame; use on grey pages">
|
|
61
123
|
<div className="grey"><Table bordered columns={RUNS.slice(0, 3)} rows={RUN_ROWS.slice(0, 2)} /></div>
|
|
62
124
|
</Case>
|
|
@@ -68,12 +130,12 @@ function Sheet() {
|
|
|
68
130
|
<div className="note">Never wrap a bare table in your own bordered div — its header rule doubles against the frame. <code>bordered</code> when the table is the card; <code>framed</code> when the card also holds a toolbar or pagination.</div>
|
|
69
131
|
</Case>
|
|
70
132
|
|
|
71
|
-
<div className="
|
|
133
|
+
<div className="kb-h kb-h-gap">Column resize</div>
|
|
72
134
|
<Case k="resizable — short divider between header cells; hover turns it blue, drag sets the width">
|
|
73
135
|
<Table bordered resizable columns={CFG} rows={CFG_ROWS.slice(0, 2)} />
|
|
74
136
|
</Case>
|
|
75
137
|
<Case k="minWidth — per column lower bound (default 48)">
|
|
76
|
-
<Table bordered resizable columns={[{ key: "module", label: "Module", width: 150, minWidth: 140 }, { key: "code", label: "Code",
|
|
138
|
+
<Table bordered resizable columns={[{ key: "module", label: "Module", width: 150, minWidth: 140 }, { key: "code", label: "Code", code: true, width: 200, minWidth: 120 }, { key: "cur", label: "Current Value" }, { key: "next", label: "New Value", align: "right" }]} rows={CFG_ROWS.slice(0, 2)} />
|
|
77
139
|
</Case>
|
|
78
140
|
<Case k="sm — same handle">
|
|
79
141
|
<Table size="sm" bordered resizable columns={DENSE} rows={DENSE_ROWS.slice(0, 2)} />
|
|
@@ -83,7 +145,7 @@ function Sheet() {
|
|
|
83
145
|
<div className="note">Uncontrolled (above) keeps widths inside the component — they reset on remount. Controlled hands them to you: module <code>{widths.module ?? "auto"}</code> · code <code>{widths.code ?? "auto"}</code> — persist these to keep a user's layout across sessions.</div>
|
|
84
146
|
</Case>
|
|
85
147
|
|
|
86
|
-
<div className="
|
|
148
|
+
<div className="kb-h kb-h-gap">States</div>
|
|
87
149
|
<Case k="empty — content renders inside the table">
|
|
88
150
|
<Table bordered columns={CFG.slice(0, 3)} rows={[]} empty={<EmptyState icon="table" title="No rows to display" hint="Run a sync to populate this table." style={{ padding: "28px 0" }} />} />
|
|
89
151
|
</Case>
|
|
@@ -91,7 +153,7 @@ function Sheet() {
|
|
|
91
153
|
<Table bordered columns={CFG.slice(0, 3)} rows={[0, 1, 2].map(() => ({ module: <Skeleton width="60%" height={10} />, code: <Skeleton width="80%" height={10} />, cur: <Skeleton width="30%" height={10} /> }))} />
|
|
92
154
|
</Case>
|
|
93
155
|
|
|
94
|
-
<div className="
|
|
156
|
+
<div className="kb-h kb-h-gap">Composition</div>
|
|
95
157
|
<Case k="row actions — trailing IconButton column, align right">
|
|
96
158
|
<Table bordered columns={[...RUNS.slice(0, 3), { key: "act", label: "", width: 44, align: "right", render: () => <IconButton icon="ellipsis" muted label="Row actions" /> }]} rows={RUN_ROWS} />
|
|
97
159
|
<div className="note">See <b>Filter Bar (List Report)</b> for the full list-report pattern: filters above, <code>framed</code> table, pagination below. See <b>Smart Table</b> and <b>Spreadsheet</b> for editable grids.</div>
|
|
@@ -99,5 +161,5 @@ function Sheet() {
|
|
|
99
161
|
</div>;
|
|
100
162
|
}
|
|
101
163
|
ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
|
|
102
|
-
if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"Table.jsx","path":"../data/Table.jsx"},{"name":"
|
|
164
|
+
if (window.KBViewSource) setTimeout(function(){ KBViewSource.mount("#root", [{"name":"Table.jsx","path":"../data/Table.jsx"},{"name":"Badge.jsx (IconTile)","path":"../display/Badge.jsx","vue":"../display/IconTile.vue","vueName":"IconTile.vue"},{"name":"Pagination.jsx","path":"../data/Pagination.jsx"},{"name":"Alert.jsx (EmptyState · Skeleton)","path":"../feedback/Alert.jsx","vue":"../feedback/EmptyState.vue","vueName":"EmptyState.vue"}]); }, 0);
|
|
103
165
|
</script></body></html>
|