@keyfunc/keybricks-ds 2.5.0 → 2.6.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.
Files changed (72) hide show
  1. package/DEPLOY.md +4 -4
  2. package/INTEGRATION.md +20 -1
  3. package/_adherence.oxlintrc.json +10 -4
  4. package/_ds_bundle.js +20559 -0
  5. package/_src/icon-index.js +1 -0
  6. package/_src/unicons-index.js +1 -0
  7. package/_src/usage-code.js +737 -0
  8. package/changelog.js +12 -0
  9. package/components/buttons/BUTTON_MIGRATION.md +111 -0
  10. package/components/buttons/Button.vue +59 -12
  11. package/components/buttons/Button.vue.d.ts +44 -0
  12. package/components/charts/BarList.jsx +1 -1
  13. package/components/charts/BarList.vue +8 -3
  14. package/components/charts/Ribbon3D.d.ts +2 -0
  15. package/components/charts/Scatter3D.d.ts +4 -0
  16. package/components/charts/SunburstChart.jsx +6 -1
  17. package/components/charts/SunburstChart.vue +7 -1
  18. package/components/charts/Surface3D.d.ts +2 -0
  19. package/components/charts/WorldMap.jsx +6 -1
  20. package/components/charts/WorldMap.vue +7 -1
  21. package/components/data/Table.jsx +1 -1
  22. package/components/data/Table.vue +1 -1
  23. package/components/display/ProgressBar.jsx +1 -1
  24. package/components/display/ProgressBar.vue +1 -1
  25. package/components/feedback/Accordion.jsx +1 -1
  26. package/components/feedback/Accordion.vue +1 -1
  27. package/components/feedback/ContextMenu.jsx +3 -3
  28. package/components/feedback/ContextMenu.vue +4 -4
  29. package/components/feedback/Drawer.jsx +3 -3
  30. package/components/feedback/Drawer.vue +3 -3
  31. package/components/feedback/MESSAGE_SERVICES.md +71 -0
  32. package/components/feedback/Toast.vue +5 -5
  33. package/components/feedback/_internal/MessageBoxView.vue +237 -0
  34. package/components/feedback/_internal/MessageView.vue +73 -0
  35. package/components/feedback/_internal/service-utils.js +46 -0
  36. package/components/feedback/message-box.d.ts +69 -0
  37. package/components/feedback/message-box.js +92 -0
  38. package/components/feedback/message.d.ts +37 -0
  39. package/components/feedback/message.js +68 -0
  40. package/components/forms/Checkbox.d.ts +2 -0
  41. package/components/forms/Checkbox.jsx +9 -4
  42. package/components/forms/Checkbox.vue +6 -2
  43. package/components/forms/DatePicker.jsx +3 -1
  44. package/components/forms/DatePicker.vue +2 -1
  45. package/components/forms/Dropzone.jsx +1 -1
  46. package/components/forms/Dropzone.vue +1 -1
  47. package/components/forms/MultiSelect.jsx +5 -3
  48. package/components/forms/MultiSelect.vue +4 -3
  49. package/components/forms/Slider.jsx +1 -1
  50. package/components/forms/Slider.vue +1 -1
  51. package/components/forms/Switch.jsx +4 -4
  52. package/components/forms/Switch.vue +4 -4
  53. package/components/navigation/Sidebar.jsx +2 -2
  54. package/components/navigation/Sidebar.vue +2 -2
  55. package/components/navigation/TopBar.jsx +1 -1
  56. package/components/navigation/TopBar.vue +1 -1
  57. package/components/navigation/Tree.jsx +2 -2
  58. package/components/navigation/Tree.vue +8 -5
  59. package/components/pipeline/DataPreview.jsx +1 -1
  60. package/components/pipeline/DataPreview.vue +1 -1
  61. package/components/pipeline/NodeCard.jsx +1 -1
  62. package/components/pipeline/NodeCard.vue +1 -1
  63. package/components/pipeline/PaletteItem.vue +1 -1
  64. package/components/pipeline/PalettePanel.jsx +3 -3
  65. package/components/pipeline/PalettePanel.vue +2 -2
  66. package/components/tabs/SegmentedControl.jsx +2 -2
  67. package/components/tabs/SegmentedControl.vue +2 -2
  68. package/index.html +1 -1
  69. package/package.json +12 -2
  70. package/tokens/dark.css +1 -1
  71. package/tokens/interaction.css +4 -0
  72. package/tokens/layout.css +3 -0
@@ -9,7 +9,7 @@ export function PaletteItem({ icon, hue, label, onClick, style }) {
9
9
  const [hover, setHover] = React.useState(false);
10
10
  return (
11
11
  <div role="button" tabIndex={0} onClick={onClick} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
12
- style={{ width: 67.664, borderRadius: "var(--radius-lg)", padding: 8, display: "flex", flexDirection: "column", gap: 6, alignItems: "center", cursor: "grab", boxSizing: "border-box", background: hover ? "var(--bg-hover)" : "transparent", transition: "background .12s ease", ...style }}>
12
+ style={{ width: 67.664, borderRadius: "var(--radius-lg)", padding: 8, display: "flex", flexDirection: "column", gap: 6, alignItems: "center", cursor: "grab", boxSizing: "border-box", background: hover ? "var(--bg-hover)" : "transparent", transition: "background var(--dur-fast) var(--ease-out)", ...style }}>
13
13
  <IconTile icon={icon} hue={hue} kind="palette" />
14
14
  <span style={{ fontFamily: "var(--font-sans)", fontSize: "var(--text-xs)", lineHeight: "var(--leading-xs)", letterSpacing: "var(--tracking-xs)", color: "var(--text-body)", textAlign: "center" }}>{label}</span>
15
15
  </div>
@@ -44,8 +44,8 @@ export function PalettePanel({ catalog = PIPELINE_CATALOG, height = "100%", onPi
44
44
  <div style={{ flex: 1, overflowY: "auto", padding: 8 }}>
45
45
  {catalog.map((cat) => (
46
46
  <div key={cat.label}>
47
- <div onClick={() => toggle(cat.label)} data-wash="" style={{ height: "var(--h-subnav-item)", borderRadius: "var(--radius-md)", display: "flex", alignItems: "center", gap: 8, padding: "6px 8px", boxSizing: "border-box", cursor: "pointer", background: "var(--wash, transparent)", transition: "var(--t-hover)" }}>
48
- <span style={{ color: "var(--text-muted)", display: "inline-flex", transform: closed.includes(cat.label) ? "rotate(-90deg)" : "none", transition: "transform .15s ease" }}><Icon name="chevron-down" size={14} /></span>
47
+ <div role="button" tabIndex={0} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); toggle(cat.label); } }} onClick={() => toggle(cat.label)} data-wash="" style={{ height: "var(--h-subnav-item)", borderRadius: "var(--radius-md)", display: "flex", alignItems: "center", gap: 8, padding: "6px 8px", boxSizing: "border-box", cursor: "pointer", background: "var(--wash, transparent)", transition: "var(--t-hover)" }}>
48
+ <span style={{ color: "var(--text-muted)", display: "inline-flex", transform: closed.includes(cat.label) ? "rotate(-90deg)" : "none", transition: "transform var(--dur-fast) var(--ease-out)" }}><Icon name="chevron-down" size={14} /></span>
49
49
  <span style={{ color: `var(--cat-${cat.hue})`, display: "inline-flex" }}><Icon name={cat.icon} size={14} /></span>
50
50
  <span style={{ fontFamily: "var(--font-sans)", fontWeight: "var(--weight-medium)", fontSize: "var(--text-base)", lineHeight: "var(--leading-base)", letterSpacing: "var(--tracking-base)", color: "var(--text-strong)" }}>{cat.label}</span>
51
51
  </div>
@@ -21,8 +21,8 @@ function toggle(l) { closed.value = closed.value.includes(l) ? closed.value.filt
21
21
  </div>
22
22
  <div style="flex:1;overflow-y:auto;padding:8px">
23
23
  <div v-for="cat in catalog" :key="cat.label">
24
- <div @click="toggle(cat.label)" data-wash="" style="height:var(--h-subnav-item);border-radius:var(--radius-md);display:flex;align-items:center;gap:8px;padding:6px 8px;box-sizing:border-box;cursor:pointer;background:var(--wash, transparent);transition:var(--t-hover)">
25
- <span :style="{ color: 'var(--text-muted)', display: 'inline-flex', transform: closed.includes(cat.label) ? 'rotate(-90deg)' : 'none', transition: 'transform .15s ease' }"><Icon name="chevron-down" :size="14" /></span>
24
+ <div role="button" tabindex="0" @keydown.enter.prevent="toggle(cat.label)" @keydown.space.prevent="toggle(cat.label)" @click="toggle(cat.label)" data-wash="" style="height:var(--h-subnav-item);border-radius:var(--radius-md);display:flex;align-items:center;gap:8px;padding:6px 8px;box-sizing:border-box;cursor:pointer;background:var(--wash, transparent);transition:var(--t-hover)">
25
+ <span :style="{ color: 'var(--text-muted)', display: 'inline-flex', transform: closed.includes(cat.label) ? 'rotate(-90deg)' : 'none', transition: 'transform var(--dur-fast) var(--ease-out)' }"><Icon name="chevron-down" :size="14" /></span>
26
26
  <span :style="{ color: `var(--cat-${cat.hue})`, display: 'inline-flex' }"><Icon :name="cat.icon" :size="14" /></span>
27
27
  <span style="font-family:var(--font-sans);font-weight:var(--weight-medium);font-size:var(--text-base);line-height:var(--leading-base);letter-spacing:var(--tracking-base);color:var(--text-strong)">{{ cat.label }}</span>
28
28
  </div>
@@ -28,8 +28,8 @@ export function SegmentedControl({ options = [], value, onChange, size, iconOnly
28
28
  return (
29
29
  <button key={o.label} type="button" role="tab" aria-selected={is} aria-label={iconOnly ? o.label : undefined} title={iconOnly ? o.label : undefined} disabled={off} tabIndex={is ? 0 : -1} data-ink={is || off ? undefined : ""}
30
30
  onClick={() => !off && onChange && onChange(o.label)}
31
- style={{ height: "calc(var(--control-h) - 6px)", padding: iconOnly ? "0 calc(var(--control-px) - 4px)" : "0 calc(var(--control-px) - 2px)", flex: fullWidth ? 1 : "none", justifyContent: "center", display: "inline-flex", alignItems: "center", gap: 6, borderRadius: "var(--radius-sm)", border: "none", cursor: off ? "not-allowed" : "pointer", background: is ? "var(--bg-surface)" : "transparent", boxShadow: is ? "0 1px 2px rgba(0,0,0,.08)" : "none", 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))", opacity: o.disabled && !disabled ? .45 : 1, whiteSpace: "nowrap", transition: "var(--t-hover)" }}>
32
- {o.icon ? <Icon name={o.icon} size={16} style={tierIcon} /> : null}{iconOnly ? null : o.label}{iconOnly ? null : <CountBadge count={o.count} selected={is} showZero={o.showZero ?? showZero} />}
31
+ style={{ height: "calc(var(--control-h) - 6px)", padding: iconOnly ? "0 calc(var(--control-px) - 4px)" : "0 calc(var(--control-px) - 2px)", flex: fullWidth ? 1 : "none", justifyContent: "center", display: "inline-flex", alignItems: "center", gap: 6, borderRadius: "var(--radius-sm)", border: "none", cursor: off ? "not-allowed" : "pointer", background: is ? "var(--bg-surface)" : "transparent", boxShadow: is ? "var(--shadow-raised)" : "none", 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))", opacity: o.disabled && !disabled ? .45 : 1, whiteSpace: "nowrap", minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", transition: "var(--t-hover)" }}>
32
+ {o.icon ? <Icon name={o.icon} size={16} style={tierIcon} /> : null}{iconOnly ? null : <span style={{ minWidth: 0, overflow: "hidden", textOverflow: "ellipsis" }}>{o.label}</span>}{iconOnly ? null : <CountBadge count={o.count} selected={is} showZero={o.showZero ?? showZero} />}
33
33
  </button>
34
34
  );
35
35
  })}
@@ -21,8 +21,8 @@ function onKey(e) {
21
21
  <template>
22
22
  <div role="tablist" :data-size="size" :aria-disabled="disabled || undefined" @keydown="onKey" :style="{ display: fullWidth ? 'flex' : 'inline-flex', height: 'var(--control-h)', padding: '2px', gap: '2px', background: 'var(--bg-inset)', border: '1px solid var(--border-control)', borderRadius: 'var(--radius-md)', boxSizing: 'border-box', opacity: disabled ? .5 : 1, ...style }">
23
23
  <button v-for="o in opts" :key="o.label" type="button" role="tab" :aria-selected="modelValue === o.label" :aria-label="iconOnly ? o.label : undefined" :title="iconOnly ? o.label : undefined" :disabled="disabled || o.disabled" :tabindex="modelValue === o.label ? 0 : -1" :data-ink="modelValue === o.label || disabled || o.disabled ? undefined : ''" @click="pick(o)"
24
- :style="{ height: 'calc(var(--control-h) - 6px)', padding: iconOnly ? '0 calc(var(--control-px) - 4px)' : '0 calc(var(--control-px) - 2px)', flex: fullWidth ? 1 : 'none', justifyContent: 'center', display: 'inline-flex', alignItems: 'center', gap: '6px', borderRadius: 'var(--radius-sm)', border: 'none', cursor: (disabled || o.disabled) ? 'not-allowed' : 'pointer', background: modelValue === o.label ? 'var(--bg-surface)' : 'transparent', boxShadow: modelValue === o.label ? '0 1px 2px rgba(0,0,0,.08)' : 'none', fontFamily: 'var(--font-sans)', fontWeight: 'var(--weight-medium)', fontSize: 'var(--control-text)', lineHeight: 'var(--control-leading)', letterSpacing: 'var(--control-tracking)', color: modelValue === o.label ? 'var(--text-heading)' : 'var(--ink, var(--text-secondary))', opacity: o.disabled && !disabled ? .45 : 1, whiteSpace: 'nowrap', transition: 'var(--t-hover)' }">
25
- <Icon v-if="o.icon" :name="o.icon" :size="16" :style="tierIcon" /><template v-if="!iconOnly">{{ o.label }}<CountBadge :count="o.count" :selected="modelValue === o.label" :show-zero="o.showZero ?? showZero" /></template>
24
+ :style="{ height: 'calc(var(--control-h) - 6px)', padding: iconOnly ? '0 calc(var(--control-px) - 4px)' : '0 calc(var(--control-px) - 2px)', flex: fullWidth ? 1 : 'none', justifyContent: 'center', display: 'inline-flex', alignItems: 'center', gap: '6px', borderRadius: 'var(--radius-sm)', border: 'none', cursor: (disabled || o.disabled) ? 'not-allowed' : 'pointer', background: modelValue === o.label ? 'var(--bg-surface)' : 'transparent', boxShadow: modelValue === o.label ? 'var(--shadow-raised)' : 'none', fontFamily: 'var(--font-sans)', fontWeight: 'var(--weight-medium)', fontSize: 'var(--control-text)', lineHeight: 'var(--control-leading)', letterSpacing: 'var(--control-tracking)', color: modelValue === o.label ? 'var(--text-heading)' : 'var(--ink, var(--text-secondary))', opacity: o.disabled && !disabled ? .45 : 1, whiteSpace: 'nowrap', minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', transition: 'var(--t-hover)' }">
25
+ <Icon v-if="o.icon" :name="o.icon" :size="16" :style="tierIcon" /><template v-if="!iconOnly"><span style="min-width:0;overflow:hidden;text-overflow:ellipsis">{{ o.label }}</span><CountBadge :count="o.count" :selected="modelValue === o.label" :show-zero="o.showZero ?? showZero" /></template>
26
26
  </button>
27
27
  </div>
28
28
  </template>
package/index.html CHANGED
@@ -176,7 +176,7 @@ section{margin-bottom:52px;scroll-margin-top:78px}
176
176
  const GROUPS=[["Brand","品牌","ブランド"],["Colors","颜色","カラー"],["Type","字体排印","タイポグラフィ"],["Foundations","基础规范","基盤仕様"],["Components","组件","コンポーネント"],["Charts","图表","チャート"],["Icons","图标库","アイコン"]];
177
177
 
178
178
  const S={
179
- brandsub:["Design System · v2.5.0","设计系统 · v2.5.0","デザインシステム · v2.5.0"],
179
+ brandsub:["Design System · v2.5.1","设计系统 · v2.5.1","デザインシステム · v2.5.1"],
180
180
  doc_readme:["Readme","说明文档","ドキュメント"],
181
181
  doc_design:["DESIGN.md","下载 DESIGN.md","DESIGN.md"],
182
182
  doc_integration:["Integration","接入指南","導入ガイド"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keyfunc/keybricks-ds",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "Keybricks design system — design tokens, three size tiers and 121 UI components in React and Vue 3, source-only.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -13,6 +13,14 @@
13
13
  "default": "./components/index.js"
14
14
  },
15
15
  "./vue": "./components/_vue/index.mjs",
16
+ "./vue/message": {
17
+ "types": "./components/feedback/message.d.ts",
18
+ "default": "./components/feedback/message.js"
19
+ },
20
+ "./vue/message-box": {
21
+ "types": "./components/feedback/message-box.d.ts",
22
+ "default": "./components/feedback/message-box.js"
23
+ },
16
24
  "./styles.css": "./keybricks.css",
17
25
  "./keybricks.css": "./keybricks.css",
18
26
  "./tokens": {
@@ -45,7 +53,9 @@
45
53
  "guidelines",
46
54
  "changelog.js",
47
55
  "site-nav.js",
48
- "covers.js"
56
+ "covers.js",
57
+ "_ds_bundle.js",
58
+ "_src"
49
59
  ],
50
60
  "scripts": {
51
61
  "build:tokens": "node _scripts/build-tokens.mjs",
package/tokens/dark.css CHANGED
@@ -48,7 +48,7 @@ color-scheme:dark;
48
48
  --shadow-node:0 1px 3px 0 rgba(0,0,0,.6),0 1px 2px -1px rgba(0,0,0,.5);
49
49
  --shadow-selected:0 0 0 2px rgba(43,127,255,.32),0 1px 3px 0 rgba(0,0,0,.6);
50
50
  --shadow-menu:0 4px 16px rgba(0,0,0,.55),0 1px 3px rgba(0,0,0,.4);
51
- --shadow-modal:0 24px 64px rgba(0,0,0,.7),0 2px 8px rgba(0,0,0,.5);
51
+ --shadow-modal:0 24px 64px rgba(0,0,0,.7),0 2px 8px rgba(0,0,0,.5);--shadow-raised:0 1px 2px rgba(0,0,0,.4);--shadow-thumb:0 1px 2px rgba(0,0,0,.5);--shadow-drawer:-8px 0 24px rgba(0,0,0,.5);
52
52
  }
53
53
  [data-theme="dark"] body{background:var(--bg-app);color:var(--text-primary)}
54
54
  [data-theme="dark"] img[src$="keybricks-logo.png"]{filter:none}
@@ -47,3 +47,7 @@ summary:focus-visible,
47
47
  [role="tab"]:focus-visible,
48
48
  [role="switch"]:focus-visible,
49
49
  [role="treeitem"]:focus-visible{outline:2px solid var(--focus-border);outline-offset:2px}
50
+
51
+ /* A field box (Select, Combobox, DatePicker, MultiSelect …) is one line: its value text and tags truncate with an ellipsis
52
+ instead of spilling past the border. Icons and the chevron are svg or aria-hidden, so they are not affected. */
53
+ [data-field]>span:not([aria-hidden]),[role="combobox"]>span:not([aria-hidden]){min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
package/tokens/layout.css CHANGED
@@ -12,6 +12,9 @@
12
12
  --shadow-selected:0 0 0 2px var(--focus-ring),0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);
13
13
  --shadow-menu:0 4px 12px rgba(0,0,0,.1),0 1px 3px rgba(0,0,0,.08);
14
14
  --shadow-modal:0 24px 64px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08);
15
+ --shadow-raised:0 1px 2px rgba(0,0,0,.08); /* a selected segment lifted off its track */
16
+ --shadow-thumb:0 1px 2px rgba(0,0,0,.15); /* slider thumb, switch knob */
17
+ --shadow-drawer:-8px 0 24px rgba(0,0,0,.12); /* right-hand drawer edge */
15
18
  --ring-surface:0 0 0 2px var(--bg-surface);
16
19
  --ring-focus:0 0 0 2px var(--bg-surface),0 0 0 4px var(--focus-border);
17
20
  /* Chrome sizes */