@keyfunc/keybricks-ds 2.5.0 → 2.5.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 +3 -3
- package/INTEGRATION.md +12 -1
- package/_adherence.oxlintrc.json +10 -4
- package/_ds_bundle.js +20559 -0
- package/_src/icon-index.js +1 -0
- package/_src/unicons-index.js +1 -0
- package/_src/usage-code.js +737 -0
- package/changelog.js +7 -0
- package/components/charts/BarList.jsx +1 -1
- package/components/charts/BarList.vue +8 -3
- package/components/charts/Ribbon3D.d.ts +2 -0
- package/components/charts/Scatter3D.d.ts +4 -0
- package/components/charts/SunburstChart.jsx +6 -1
- package/components/charts/SunburstChart.vue +7 -1
- package/components/charts/Surface3D.d.ts +2 -0
- package/components/charts/WorldMap.jsx +6 -1
- package/components/charts/WorldMap.vue +7 -1
- package/components/data/Table.jsx +1 -1
- package/components/data/Table.vue +1 -1
- package/components/display/ProgressBar.jsx +1 -1
- package/components/display/ProgressBar.vue +1 -1
- package/components/feedback/Accordion.jsx +1 -1
- package/components/feedback/Accordion.vue +1 -1
- package/components/feedback/ContextMenu.jsx +3 -3
- package/components/feedback/ContextMenu.vue +4 -4
- package/components/feedback/Drawer.jsx +3 -3
- package/components/feedback/Drawer.vue +3 -3
- package/components/forms/Checkbox.d.ts +2 -0
- package/components/forms/Checkbox.jsx +9 -4
- package/components/forms/Checkbox.vue +6 -2
- package/components/forms/DatePicker.jsx +3 -1
- package/components/forms/DatePicker.vue +2 -1
- package/components/forms/Dropzone.jsx +1 -1
- package/components/forms/Dropzone.vue +1 -1
- package/components/forms/MultiSelect.jsx +5 -3
- package/components/forms/MultiSelect.vue +4 -3
- package/components/forms/Slider.jsx +1 -1
- package/components/forms/Slider.vue +1 -1
- package/components/forms/Switch.jsx +4 -4
- package/components/forms/Switch.vue +4 -4
- package/components/navigation/Sidebar.jsx +2 -2
- package/components/navigation/Sidebar.vue +2 -2
- package/components/navigation/TopBar.jsx +1 -1
- package/components/navigation/TopBar.vue +1 -1
- package/components/navigation/Tree.jsx +2 -2
- package/components/navigation/Tree.vue +8 -5
- package/components/pipeline/DataPreview.jsx +1 -1
- package/components/pipeline/DataPreview.vue +1 -1
- package/components/pipeline/NodeCard.jsx +1 -1
- package/components/pipeline/NodeCard.vue +1 -1
- package/components/pipeline/PaletteItem.vue +1 -1
- package/components/pipeline/PalettePanel.jsx +3 -3
- package/components/pipeline/PalettePanel.vue +2 -2
- package/components/tabs/SegmentedControl.jsx +2 -2
- package/components/tabs/SegmentedControl.vue +2 -2
- package/index.html +1 -1
- package/package.json +4 -2
- package/tokens/dark.css +1 -1
- package/tokens/interaction.css +4 -0
- package/tokens/layout.css +3 -0
|
@@ -62,18 +62,18 @@ export function Switch({ checked = false, onChange, disabled, size, tone = "prim
|
|
|
62
62
|
const glyphText = pick(knobText, checked);
|
|
63
63
|
const knobX = checked ? `calc(100% - ${H} + 2px)` : 2;
|
|
64
64
|
|
|
65
|
-
const knob = <span aria-hidden="true" style={{ position: "absolute", top: 2, left: knobX, width: KNOB, height: KNOB, borderRadius: "var(--radius-full)", background: "var(--bg-surface)", boxShadow: "
|
|
65
|
+
const knob = <span aria-hidden="true" style={{ position: "absolute", top: 2, left: knobX, width: KNOB, height: KNOB, borderRadius: "var(--radius-full)", background: "var(--bg-surface)", boxShadow: "var(--shadow-thumb)", transition: "left var(--dur) var(--ease-out)", display: "flex", alignItems: "center", justifyContent: "center", color: track, fontSize: TEXT, lineHeight: 1, fontWeight: "var(--weight-semibold)", fontFamily: "var(--font-sans)", overflow: "hidden" }}>
|
|
66
66
|
{loading
|
|
67
67
|
? <span style={{ width: GLYPH, height: GLYPH, borderRadius: "50%", border: `1.5px solid ${track}`, borderRightColor: "transparent", animation: "kb-spin 720ms linear infinite" }}></span>
|
|
68
68
|
: glyphIcon ? <Icon name={glyphIcon} size={10} strokeWidth={2.5} style={{ width: GLYPH, height: GLYPH }} />
|
|
69
69
|
: glyphText ? <span>{String(glyphText).slice(0, 1)}</span> : null}
|
|
70
70
|
</span>;
|
|
71
71
|
|
|
72
|
-
const insideStyle = (side) => ({ position: "absolute", top: 0, bottom: 0, [side]: 6, display: "flex", alignItems: "center", fontSize: TEXT, lineHeight: 1, fontWeight: "var(--weight-semibold)", fontFamily: "var(--font-sans)", letterSpacing: ".2px", color: "var(--on-accent)", transition: "opacity
|
|
72
|
+
const insideStyle = (side) => ({ position: "absolute", top: 0, bottom: 0, [side]: 6, display: "flex", alignItems: "center", fontSize: TEXT, lineHeight: 1, fontWeight: "var(--weight-semibold)", fontFamily: "var(--font-sans)", letterSpacing: ".2px", color: "var(--on-accent)", transition: "opacity var(--dur) var(--ease-out)", pointerEvents: "none", whiteSpace: "nowrap" });
|
|
73
73
|
|
|
74
74
|
const pill = <span role="switch" aria-checked={checked} aria-busy={loading || undefined} aria-disabled={disabled || undefined} tabIndex={inert ? -1 : 0} onClick={flip}
|
|
75
75
|
onKeyDown={e => { if (e.key === " " || e.key === "Enter") { e.preventDefault(); flip(); } }}
|
|
76
|
-
style={{ position: "relative", display: "inline-block", width: w, height: H, borderRadius: "var(--radius-full)", "--sw-track": track, background: "var(--sw-bg, var(--sw-track))", transition: "background
|
|
76
|
+
style={{ position: "relative", display: "inline-block", width: w, height: H, borderRadius: "var(--radius-full)", "--sw-track": track, background: "var(--sw-bg, var(--sw-track))", transition: "background var(--dur) var(--ease-out)", cursor: inert ? (loading ? "progress" : "not-allowed") : "pointer", flexShrink: 0, verticalAlign: "middle", outline: "none" }}>
|
|
77
77
|
{hasInside && <span style={{ ...insideStyle("left"), opacity: checked ? 1 : 0 }}>{insideOn}</span>}
|
|
78
78
|
{hasInside && <span style={{ ...insideStyle("right"), opacity: checked ? 0 : 1 }}>{insideOff}</span>}
|
|
79
79
|
{knob}
|
|
@@ -83,7 +83,7 @@ export function Switch({ checked = false, onChange, disabled, size, tone = "prim
|
|
|
83
83
|
if (single) return <span data-size={size} data-sw="" style={{ display: "inline-flex", alignItems: "center", verticalAlign: "middle", gap: "var(--control-gap)", opacity: disabled ? .5 : 1, ...style }}>{pill}<span onClick={flip} style={{ ...capBase, fontWeight: "var(--weight-regular)", color: "var(--text-body)" }}>{label}</span></span>;
|
|
84
84
|
if (labelOn == null && labelOff == null) return <span data-size={size} style={{ display: "inline-flex", alignItems: "center", verticalAlign: "middle", opacity: disabled ? .5 : 1, ...style }}>{pill}</span>;
|
|
85
85
|
|
|
86
|
-
const cap = (text, active) => text == null ? null : <span style={{ ...capBase, fontWeight: active ? "var(--weight-medium)" : "var(--weight-regular)", color: active ? "var(--text-heading)" : "var(--text-muted)", transition: "color
|
|
86
|
+
const cap = (text, active) => text == null ? null : <span style={{ ...capBase, fontWeight: active ? "var(--weight-medium)" : "var(--weight-regular)", color: active ? "var(--text-heading)" : "var(--text-muted)", transition: "color var(--dur) var(--ease-out)" }} onClick={flip}>{text}</span>;
|
|
87
87
|
return <span data-size={size} data-sw="" style={{ display: "inline-flex", alignItems: "center", verticalAlign: "middle", gap: "var(--control-gap)", opacity: disabled ? .5 : 1, ...style }}>
|
|
88
88
|
{cap(labelOff, !checked)}{pill}{cap(labelOn, checked)}
|
|
89
89
|
</span>;
|
|
@@ -44,17 +44,17 @@ async function flip() {
|
|
|
44
44
|
}
|
|
45
45
|
emit('update:checked', next); emit('change', next)
|
|
46
46
|
}
|
|
47
|
-
const insideStyle = (side, on) => ({ position: 'absolute', top: 0, bottom: 0, [side]: '6px', display: 'flex', alignItems: 'center', fontSize: TEXT, lineHeight: 1, fontWeight: 'var(--weight-semibold)', fontFamily: 'var(--font-sans)', letterSpacing: '.2px', color: 'var(--on-accent)', transition: 'opacity
|
|
48
|
-
const cap = (active) => ({ fontSize: 'var(--control-text)', lineHeight: 'var(--control-leading)', letterSpacing: 'var(--control-tracking)', fontFamily: 'var(--font-sans)', fontWeight: active ? 'var(--weight-medium)' : 'var(--weight-regular)', color: active ? 'var(--text-heading)' : 'var(--text-muted)', transition: 'color
|
|
47
|
+
const insideStyle = (side, on) => ({ position: 'absolute', top: 0, bottom: 0, [side]: '6px', display: 'flex', alignItems: 'center', fontSize: TEXT, lineHeight: 1, fontWeight: 'var(--weight-semibold)', fontFamily: 'var(--font-sans)', letterSpacing: '.2px', color: 'var(--on-accent)', transition: 'opacity var(--dur) var(--ease-out)', pointerEvents: 'none', whiteSpace: 'nowrap', opacity: on === props.checked ? 1 : 0 })
|
|
48
|
+
const cap = (active) => ({ fontSize: 'var(--control-text)', lineHeight: 'var(--control-leading)', letterSpacing: 'var(--control-tracking)', fontFamily: 'var(--font-sans)', fontWeight: active ? 'var(--weight-medium)' : 'var(--weight-regular)', color: active ? 'var(--text-heading)' : 'var(--text-muted)', transition: 'color var(--dur) var(--ease-out)', cursor: inert.value ? 'default' : 'pointer', userSelect: 'none' })
|
|
49
49
|
</script>
|
|
50
50
|
<template>
|
|
51
51
|
<span :data-size="size" data-sw="" :style="{ display: 'inline-flex', alignItems: 'center', verticalAlign: 'middle', gap: 'var(--control-gap)', opacity: disabled ? .5 : 1, ...style }">
|
|
52
52
|
<span v-if="labelOff != null" :style="cap(!checked)" @click="flip">{{ labelOff }}</span>
|
|
53
53
|
<span role="switch" :aria-checked="checked" :aria-busy="isLoading || undefined" :aria-disabled="disabled || undefined" :tabindex="inert ? -1 : 0" @click="flip" @keydown.space.prevent="flip" @keydown.enter.prevent="flip"
|
|
54
|
-
:style="{ position: 'relative', display: 'inline-block', width: width, height: H, borderRadius: 'var(--radius-full)', '--sw-track': track, background: 'var(--sw-bg, var(--sw-track))', transition: 'background
|
|
54
|
+
:style="{ position: 'relative', display: 'inline-block', width: width, height: H, borderRadius: 'var(--radius-full)', '--sw-track': track, background: 'var(--sw-bg, var(--sw-track))', transition: 'background var(--dur) var(--ease-out)', cursor: inert ? (isLoading ? 'progress' : 'not-allowed') : 'pointer', flexShrink: 0, verticalAlign: 'middle', outline: 'none' }">
|
|
55
55
|
<span v-if="hasInside" :style="insideStyle('left', true)">{{ inOn }}</span>
|
|
56
56
|
<span v-if="hasInside" :style="insideStyle('right', false)">{{ inOff }}</span>
|
|
57
|
-
<span aria-hidden="true" :style="{ position: 'absolute', top: '2px', left: knobX, width: KNOB, height: KNOB, borderRadius: 'var(--radius-full)', background: 'var(--bg-surface)', boxShadow: '
|
|
57
|
+
<span aria-hidden="true" :style="{ position: 'absolute', top: '2px', left: knobX, width: KNOB, height: KNOB, borderRadius: 'var(--radius-full)', background: 'var(--bg-surface)', boxShadow: 'var(--shadow-thumb)', transition: 'left var(--dur) var(--ease-out)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: track, fontSize: TEXT, lineHeight: 1, fontWeight: 'var(--weight-semibold)', fontFamily: 'var(--font-sans)', overflow: 'hidden' }">
|
|
58
58
|
<span v-if="isLoading" :style="{ width: GLYPH, height: GLYPH, borderRadius: '50%', border: '1.5px solid ' + track, borderRightColor: 'transparent', animation: 'kb-spin 720ms linear infinite' }"></span>
|
|
59
59
|
<Icon v-else-if="glyphIcon" :name="glyphIcon" :size="10" :stroke-width="2.5" :style="{ width: GLYPH, height: GLYPH }" />
|
|
60
60
|
<span v-else-if="glyphText">{{ glyphText }}</span>
|
|
@@ -36,10 +36,10 @@ export function Sidebar({ items = KEYBRICKS_NAV, footerItems = KEYBRICKS_NAV_FOO
|
|
|
36
36
|
</div>
|
|
37
37
|
) : <NavItem key={it.label} icon={it.icon} label={it.label} collapsed={collapsed} trailing={it.trailing} active={active === it.label} onClick={() => pick(it.label)} />);
|
|
38
38
|
return (
|
|
39
|
-
<aside data-theme={t.theme} style={{ ...t.vars, width: collapsed ? "var(--rail-w)" : "var(--sidebar-w)", height, background: "var(--sb-bg)", borderRight: "1px solid var(--sb-border)", color: "var(--sb-text)", display: "flex", flexDirection: "column", boxSizing: "border-box", flexShrink: 0, transition: "width
|
|
39
|
+
<aside data-theme={t.theme} style={{ ...t.vars, width: collapsed ? "var(--rail-w)" : "var(--sidebar-w)", height, background: "var(--sb-bg)", borderRight: "1px solid var(--sb-border)", color: "var(--sb-text)", display: "flex", flexDirection: "column", boxSizing: "border-box", flexShrink: 0, transition: "width var(--dur-fast) var(--ease-out)", ...style }}>
|
|
40
40
|
<div style={{ height: "var(--topbar-h)", display: "flex", alignItems: "center", gap: 10, padding: "0 16px", boxSizing: "border-box", justifyContent: collapsed ? "center" : "flex-start", flexShrink: 0 }}>
|
|
41
41
|
<img src={logo} alt="" style={{ width: 24, height: 24, objectFit: "contain", flexShrink: 0 }} />
|
|
42
|
-
{!collapsed ? <span style={{ fontFamily: "var(--font-sans)", fontSize: "var(--text-md)", lineHeight: "var(--leading-md)", letterSpacing: "var(--tracking-md)", fontWeight: "var(--weight-semibold)", color: "var(--sb-brand)", whiteSpace: "nowrap" }}>{brand}</span> : null}
|
|
42
|
+
{!collapsed ? <span style={{ fontFamily: "var(--font-sans)", fontSize: "var(--text-md)", lineHeight: "var(--leading-md)", letterSpacing: "var(--tracking-md)", fontWeight: "var(--weight-semibold)", color: "var(--sb-brand)", whiteSpace: "nowrap", minWidth: 0, overflow: "hidden", textOverflow: "ellipsis" }}>{brand}</span> : null}
|
|
43
43
|
</div>
|
|
44
44
|
<nav style={{ flex: 1, overflowY: "auto", overflowX: "hidden", padding: 8, display: "flex", flexDirection: "column", gap: 2 }}>
|
|
45
45
|
{onToggleCollapse ? <NavItem icon={collapsed ? "panel-left" : "chevron-left"} label={collapsed ? L.expand : L.collapse} collapsed={collapsed} onClick={onToggleCollapse} /> : null}
|
|
@@ -21,10 +21,10 @@ const groups = computed(() => [{ id: 'main', list: props.items }, { id: 'foot',
|
|
|
21
21
|
const versionText = computed(() => props.collapsed && props.version ? 'v' + String(props.version).split(' ').pop().replace(/^v/i, '') : props.version)
|
|
22
22
|
</script>
|
|
23
23
|
<template>
|
|
24
|
-
<aside :data-theme="t.theme" :style="{ ...t.vars, width: collapsed ? 'var(--rail-w)' : 'var(--sidebar-w)', height, background: 'var(--sb-bg)', borderRight: '1px solid var(--sb-border)', color: 'var(--sb-text)', display: 'flex', flexDirection: 'column', boxSizing: 'border-box', flexShrink: 0, transition: 'width
|
|
24
|
+
<aside :data-theme="t.theme" :style="{ ...t.vars, width: collapsed ? 'var(--rail-w)' : 'var(--sidebar-w)', height, background: 'var(--sb-bg)', borderRight: '1px solid var(--sb-border)', color: 'var(--sb-text)', display: 'flex', flexDirection: 'column', boxSizing: 'border-box', flexShrink: 0, transition: 'width var(--dur-fast) var(--ease-out)', ...style }">
|
|
25
25
|
<div :style="{ height: 'var(--topbar-h)', display: 'flex', alignItems: 'center', gap: '10px', padding: '0 16px', boxSizing: 'border-box', justifyContent: collapsed ? 'center' : 'flex-start', flexShrink: 0 }">
|
|
26
26
|
<img :src="logo" alt="" style="width:24px;height:24px;object-fit:contain;flex-shrink:0" />
|
|
27
|
-
<span v-if="!collapsed" style="font-family:var(--font-sans);font-size:var(--text-md);line-height:var(--leading-md);letter-spacing:var(--tracking-md);font-weight:var(--weight-semibold);color:var(--sb-brand);white-space:nowrap">{{ brand }}</span>
|
|
27
|
+
<span v-if="!collapsed" style="font-family:var(--font-sans);font-size:var(--text-md);line-height:var(--leading-md);letter-spacing:var(--tracking-md);font-weight:var(--weight-semibold);color:var(--sb-brand);white-space:nowrap;min-width:0;overflow:hidden;text-overflow:ellipsis">{{ brand }}</span>
|
|
28
28
|
</div>
|
|
29
29
|
<template v-for="g in groups" :key="g.id">
|
|
30
30
|
<component :is="g.id === 'main' ? 'nav' : 'div'" :style="g.id === 'main' ? { flex: 1, overflowY: 'auto', overflowX: 'hidden', padding: '8px', display: 'flex', flexDirection: 'column', gap: '2px' } : { padding: '8px', display: 'flex', flexDirection: 'column', gap: '2px', flexShrink: 0 }">
|
|
@@ -56,7 +56,7 @@ export function TopBar({ placeholder = "Search documents, workflows, data...", o
|
|
|
56
56
|
<IconButton icon="circle-help" label={helpLabel} title={helpLabel} onClick={onHelp} />
|
|
57
57
|
{user ? <div role="button" tabIndex={0} aria-haspopup="menu" aria-expanded={open} onClick={() => setOpen(!open)} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setOpen(!open); } }} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
|
|
58
58
|
style={{ height: 32, display: "flex", alignItems: "center", gap: 8, padding: "0 8px 0 10px", borderRadius: "var(--radius-md)", cursor: "pointer", userSelect: "none", background: open ? "var(--bg-active)" : hover ? "var(--bg-hover)" : "transparent", transition: "var(--t-hover)" }}>
|
|
59
|
-
<span style={{ ...TXT, fontWeight: "var(--weight-medium)", color: "var(--text-heading)", whiteSpace: "nowrap" }}>{user.name}</span>
|
|
59
|
+
<span style={{ ...TXT, fontWeight: "var(--weight-medium)", color: "var(--text-heading)", whiteSpace: "nowrap", minWidth: 0, maxWidth: 160, overflow: "hidden", textOverflow: "ellipsis" }}>{user.name}</span>
|
|
60
60
|
<span style={{ display: "inline-flex", color: "var(--text-muted)" }}><Icon name="chevron-down" size={16} /></span>
|
|
61
61
|
</div> : null}
|
|
62
62
|
</>)}
|
|
@@ -27,7 +27,7 @@ function key(e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault();
|
|
|
27
27
|
<IconButton icon="circle-help" :label="helpLabel" :title="helpLabel" @click="emit('help')" />
|
|
28
28
|
<div v-if="user" role="button" tabindex="0" aria-haspopup="menu" :aria-expanded="open" @click="open = !open" @keydown="key" @mouseenter="hover = true" @mouseleave="hover = false"
|
|
29
29
|
:style="{ height: '32px', display: 'flex', alignItems: 'center', gap: '8px', padding: '0 8px 0 10px', borderRadius: 'var(--radius-md)', cursor: 'pointer', userSelect: 'none', background: open ? 'var(--bg-active)' : hover ? 'var(--bg-hover)' : 'transparent', transition: 'var(--t-hover)' }">
|
|
30
|
-
<span style="font-family:var(--font-sans);font-size:var(--text-base);line-height:var(--leading-base);letter-spacing:var(--tracking-base);font-weight:var(--weight-medium);color:var(--text-heading);white-space:nowrap">{{ user.name }}</span>
|
|
30
|
+
<span style="font-family:var(--font-sans);font-size:var(--text-base);line-height:var(--leading-base);letter-spacing:var(--tracking-base);font-weight:var(--weight-medium);color:var(--text-heading);white-space:nowrap;min-width:0;max-width:160px;overflow:hidden;text-overflow:ellipsis">{{ user.name }}</span>
|
|
31
31
|
<span style="display:inline-flex;color:var(--text-muted)"><Icon name="chevron-down" :size="16" /></span>
|
|
32
32
|
</div>
|
|
33
33
|
</slot>
|
|
@@ -166,7 +166,7 @@ function Row({ item, state, cfg, api }) {
|
|
|
166
166
|
{chevron}
|
|
167
167
|
{cfg.checkable && node.checkable !== false ? (
|
|
168
168
|
<span onClick={(e) => e.stopPropagation()} style={{ display: "inline-flex", flexShrink: 0 }}>
|
|
169
|
-
<Checkbox checked={checked} indeterminate={half} disabled={disabled || node.disableCheckbox} onChange={() => api.check(key)} />
|
|
169
|
+
<Checkbox checked={checked} indeterminate={half} disabled={disabled || node.disableCheckbox} tabIndex={-1} onChange={() => api.check(key)} />
|
|
170
170
|
</span>
|
|
171
171
|
) : null}
|
|
172
172
|
{cfg.showIcon ? (
|
|
@@ -353,7 +353,7 @@ export function Tree({
|
|
|
353
353
|
const cfg = { checkable, checkStrictly, multiple, selectable, showIcon, showLine, draggable, searchValue, onContextMenu, rowActions };
|
|
354
354
|
|
|
355
355
|
return (
|
|
356
|
-
<div role="tree" aria-multiselectable={multiple || undefined} style={{ display: "flex", flexDirection: "column", gap: showLine ? 0 : 1, ...style }}>
|
|
356
|
+
<div role="tree" aria-multiselectable={multiple || undefined} style={{ display: "flex", flexDirection: "column", gap: showLine ? 0 : 1, minWidth: 0, ...style }}>
|
|
357
357
|
<style>{"@keyframes kb-tree-spin{to{transform:rotate(360deg)}}"}</style>
|
|
358
358
|
{rows.length === 0 ? (
|
|
359
359
|
<div style={{ padding: "10px 8px", fontFamily: "var(--font-sans)", fontSize: "var(--text-base)", color: "var(--text-muted)" }}>No matching items</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { ref, computed, watch } from 'vue'
|
|
2
|
+
import { ref, computed, watch, getCurrentInstance } from 'vue'
|
|
3
3
|
import Icon from '../icons/Icon.vue'
|
|
4
4
|
import Checkbox from '../forms/Checkbox.vue'
|
|
5
5
|
// Nested tree view: expand/collapse, single or multiple selection, cascading checkboxes with
|
|
@@ -33,7 +33,10 @@ const props = defineProps({
|
|
|
33
33
|
reorder: Boolean,
|
|
34
34
|
loadData: Function, rowActions: Function, style: Object,
|
|
35
35
|
})
|
|
36
|
-
|
|
36
|
+
// @context-menu(key, event) — like React's onContextMenu; only a listener suppresses the browser menu.
|
|
37
|
+
const emit = defineEmits(['select', 'check', 'expand', 'drop', 'contextMenu'])
|
|
38
|
+
const treeInst = getCurrentInstance()
|
|
39
|
+
function onCtx(e, key) { if (treeInst && treeInst.vnode.props && treeInst.vnode.props.onContextMenu) { e.preventDefault(); emit('contextMenu', key, e) } }
|
|
37
40
|
const Cell = (p) => p.v
|
|
38
41
|
Cell.props = ['v']
|
|
39
42
|
|
|
@@ -221,7 +224,7 @@ function parts(text) {
|
|
|
221
224
|
const dropAt = k => (drop.value && drop.value.key === k ? drop.value.pos : null)
|
|
222
225
|
</script>
|
|
223
226
|
<template>
|
|
224
|
-
<div role="tree" :style="{ display: 'flex', flexDirection: 'column', gap: showLine ? 0 : '1px', ...style }">
|
|
227
|
+
<div role="tree" :style="{ display: 'flex', flexDirection: 'column', gap: showLine ? 0 : '1px', minWidth: 0, ...style }">
|
|
225
228
|
<div v-for="row in rows" :key="row.key" role="treeitem" class="kb-tree-row"
|
|
226
229
|
:tabindex="focus === row.key || (!focus && row === rows[0]) ? 0 : -1"
|
|
227
230
|
:aria-expanded="isBranch(row.n) ? openKeys.includes(row.key) : undefined"
|
|
@@ -229,7 +232,7 @@ const dropAt = k => (drop.value && drop.value.key === k ? drop.value.pos : null)
|
|
|
229
232
|
:draggable="draggable && !row.n.disabled"
|
|
230
233
|
@dragstart="dragKey = row.key" @dragover="onDragOver($event, row.key)" @dragleave="drop = null"
|
|
231
234
|
@drop.prevent="onDrop(row.key)" @dragend="dragKey = null; drop = null"
|
|
232
|
-
@click="rowClick(row.n)" @keydown="keyDown($event, row)"
|
|
235
|
+
@click="rowClick(row.n)" @contextmenu="onCtx($event, row.key)" @keydown="keyDown($event, row)"
|
|
233
236
|
:class="{ 'is-disabled': row.n.disabled }"
|
|
234
237
|
:style="{
|
|
235
238
|
position: 'relative', minHeight: 'var(--h-tree-item)', borderRadius: 'var(--radius-md)', display: 'flex', alignItems: 'center', gap: '6px',
|
|
@@ -255,7 +258,7 @@ const dropAt = k => (drop.value && drop.value.key === k ? drop.value.pos : null)
|
|
|
255
258
|
<span v-else :style="{ width: showLine ? 0 : '14px', flexShrink: 0 }" />
|
|
256
259
|
<span v-if="checkable && row.n.checkable !== false" @click.stop style="display:inline-flex;flex-shrink:0">
|
|
257
260
|
<Checkbox :checked="view.full.has(row.key)" :indeterminate="view.half.has(row.key)"
|
|
258
|
-
:disabled="row.n.disabled || row.n.disableCheckbox" @change="check(row.key)" />
|
|
261
|
+
:disabled="row.n.disabled || row.n.disableCheckbox" :tabindex="-1" @change="check(row.key)" />
|
|
259
262
|
</span>
|
|
260
263
|
<span v-if="showIcon" :style="{ color: isBranch(row.n) ? 'var(--text-muted)' : docHues[row.n.hue || 'gray'], display: 'inline-flex', flexShrink: 0 }">
|
|
261
264
|
<Icon :name="row.n.icon || (isBranch(row.n) ? (openKeys.includes(row.key) ? 'folder-open' : 'folder') : 'file-text')" :size="15" />
|
|
@@ -7,7 +7,7 @@ import { Table } from "../data/Table.jsx";
|
|
|
7
7
|
/** Bottom data-preview drawer — 250px: 40px header (title, Debug Mode, collapse) + dense table. An sm size region: the header's controls are 24px and the table has 32px rows with 12px text. */
|
|
8
8
|
export function DataPreview({ title = "Data Preview", columns = [], rows = [], debug = false, onDebug, collapsed, onCollapse, size = "sm", style }) {
|
|
9
9
|
return (
|
|
10
|
-
<div data-size={size} style={{ background: "var(--bg-surface)", borderTop: "1px solid var(--border-card)", display: "flex", flexDirection: "column", height: collapsed ? "var(--bar-card-h)" : "var(--drawer-h)", overflow: "hidden", boxSizing: "border-box", flexShrink: 0, transition: "height
|
|
10
|
+
<div data-size={size} style={{ background: "var(--bg-surface)", borderTop: "1px solid var(--border-card)", display: "flex", flexDirection: "column", height: collapsed ? "var(--bar-card-h)" : "var(--drawer-h)", overflow: "hidden", boxSizing: "border-box", flexShrink: 0, transition: "height var(--dur-fast) var(--ease-out)", ...style }}>
|
|
11
11
|
<div style={{ height: "var(--bar-card-h)", display: "flex", alignItems: "center", gap: "var(--group-gap)", padding: "0 var(--edge-pad)", boxSizing: "border-box", flexShrink: 0 }}>
|
|
12
12
|
<span style={{ fontFamily: "var(--font-sans)", fontWeight: "var(--weight-semibold)", fontSize: "var(--text-base)", lineHeight: "var(--leading-base)", letterSpacing: "var(--tracking-base)", color: "var(--text-heading)" }}>{title}</span>
|
|
13
13
|
<span style={{ flex: 1 }} />
|
|
@@ -7,7 +7,7 @@ defineProps({ title: { type: String, default: 'Data Preview' }, columns: { type:
|
|
|
7
7
|
const emit = defineEmits(['update:debug', 'toggleCollapse'])
|
|
8
8
|
</script>
|
|
9
9
|
<template>
|
|
10
|
-
<div :data-size="size" :style="{ background: 'var(--bg-surface)', borderTop: '1px solid var(--border-card)', display: 'flex', flexDirection: 'column', height: collapsed ? 'var(--bar-card-h)' : 'var(--drawer-h)', overflow: 'hidden', boxSizing: 'border-box', flexShrink: 0, transition: 'height
|
|
10
|
+
<div :data-size="size" :style="{ background: 'var(--bg-surface)', borderTop: '1px solid var(--border-card)', display: 'flex', flexDirection: 'column', height: collapsed ? 'var(--bar-card-h)' : 'var(--drawer-h)', overflow: 'hidden', boxSizing: 'border-box', flexShrink: 0, transition: 'height var(--dur-fast) var(--ease-out)', ...style }">
|
|
11
11
|
<div style="height:var(--bar-card-h);display:flex;align-items:center;gap:var(--group-gap);padding:0 var(--edge-pad);box-sizing:border-box;flex-shrink:0">
|
|
12
12
|
<span style="font-family:var(--font-sans);font-weight:var(--weight-semibold);font-size:var(--text-base);line-height:var(--leading-base);letter-spacing:var(--tracking-base);color:var(--text-heading)">{{ title }}</span>
|
|
13
13
|
<span style="flex:1" />
|
|
@@ -51,7 +51,7 @@ export function PortLabel({ label = "A", tone = "default", interactive = false,
|
|
|
51
51
|
export function NodeCard({ title, subtitle, icon = "table", subtitleIcon, hue = "source", selected, badge, inputs = [], output = true, showMenu = true, onClick, onMenu, onOutputDown, onInputUp, onInputEnter, onInputLeave, outputTone = "default", inputTones = [], style }) {
|
|
52
52
|
const live = !!(onOutputDown || onInputUp);
|
|
53
53
|
return (
|
|
54
|
-
<div onClick={onClick} style={{ position: "relative", width: 220, height: 90, borderRadius: "var(--radius-node)", background: "var(--bg-surface)", border: `1px solid ${selected ? "var(--selected-border)" : "var(--border-control)"}`, boxShadow: selected ? "var(--shadow-selected)" : "var(--shadow-node)", boxSizing: "border-box", cursor: "pointer", ...style }}>
|
|
54
|
+
<div onClick={onClick} role={onClick ? "button" : undefined} tabIndex={onClick ? 0 : undefined} onKeyDown={onClick ? (e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onClick(e); } } : undefined} style={{ position: "relative", width: 220, height: 90, borderRadius: "var(--radius-node)", background: "var(--bg-surface)", border: `1px solid ${selected ? "var(--selected-border)" : "var(--border-control)"}`, boxShadow: selected ? "var(--shadow-selected)" : "var(--shadow-node)", boxSizing: "border-box", cursor: "pointer", ...style }}>
|
|
55
55
|
<div style={{ display: "flex", alignItems: "center", gap: 12, padding: 16, height: "100%", boxSizing: "border-box" }}>
|
|
56
56
|
<span style={{ position: "relative", flexShrink: 0 }}>
|
|
57
57
|
<IconTile icon={icon} hue={hue} kind="node" />
|
|
@@ -29,7 +29,7 @@ const pillBase = { width: '28px', height: '22px', borderRadius: 'var(--radius-fu
|
|
|
29
29
|
const tone = i => props.inputTones[i] || 'default'
|
|
30
30
|
</script>
|
|
31
31
|
<template>
|
|
32
|
-
<div @click="emit('click')" :style="{ position: 'relative', width: '220px', height: '90px', borderRadius: 'var(--radius-node)', background: 'var(--bg-surface)', border: `1px solid ${selected ? 'var(--selected-border)' : 'var(--border-control)'}`, boxShadow: selected ? 'var(--shadow-selected)' : 'var(--shadow-node)', boxSizing: 'border-box', cursor: 'pointer', ...style }">
|
|
32
|
+
<div role="button" tabindex="0" @keydown.enter.prevent="emit('click')" @keydown.space.prevent="emit('click')" @click="emit('click')" :style="{ position: 'relative', width: '220px', height: '90px', borderRadius: 'var(--radius-node)', background: 'var(--bg-surface)', border: `1px solid ${selected ? 'var(--selected-border)' : 'var(--border-control)'}`, boxShadow: selected ? 'var(--shadow-selected)' : 'var(--shadow-node)', boxSizing: 'border-box', cursor: 'pointer', ...style }">
|
|
33
33
|
<div style="display:flex;align-items:center;gap:12px;padding:16px;height:100%;box-sizing:border-box">
|
|
34
34
|
<span style="position:relative;flex-shrink:0">
|
|
35
35
|
<IconTile :icon="icon" :hue="hue" kind="node" />
|
|
@@ -8,7 +8,7 @@ const hover = ref(false)
|
|
|
8
8
|
</script>
|
|
9
9
|
<template>
|
|
10
10
|
<div role="button" tabindex="0" @click="$emit('click')" @mouseenter="hover = true" @mouseleave="hover = false"
|
|
11
|
-
:style="{ width: '67.664px', borderRadius: 'var(--radius-lg)', padding: '8px', display: 'flex', flexDirection: 'column', gap: '6px', alignItems: 'center', cursor: 'grab', boxSizing: 'border-box', background: hover ? 'var(--bg-hover)' : 'transparent', transition: 'background
|
|
11
|
+
:style="{ width: '67.664px', borderRadius: 'var(--radius-lg)', padding: '8px', display: 'flex', flexDirection: 'column', gap: '6px', alignItems: 'center', cursor: 'grab', boxSizing: 'border-box', background: hover ? 'var(--bg-hover)' : 'transparent', transition: 'background var(--dur-fast) var(--ease-out)', ...style }">
|
|
12
12
|
<IconTile :icon="icon" :hue="hue" kind="palette" />
|
|
13
13
|
<span style="font-family:var(--font-sans);font-size:var(--text-xs);line-height:var(--leading-xs);letter-spacing:var(--tracking-xs);color:var(--text-body);text-align:center">{{ label }}</span>
|
|
14
14
|
</div>
|
|
@@ -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
|
|
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
|
|
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
|
|
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 ? "
|
|
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 ? '
|
|
25
|
-
<Icon v-if="o.icon" :name="o.icon" :size="16" :style="tierIcon" /><template v-if="!iconOnly">{{ o.label }}
|
|
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.
|
|
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.
|
|
3
|
+
"version": "2.5.1",
|
|
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",
|
|
@@ -45,7 +45,9 @@
|
|
|
45
45
|
"guidelines",
|
|
46
46
|
"changelog.js",
|
|
47
47
|
"site-nav.js",
|
|
48
|
-
"covers.js"
|
|
48
|
+
"covers.js",
|
|
49
|
+
"_ds_bundle.js",
|
|
50
|
+
"_src"
|
|
49
51
|
],
|
|
50
52
|
"scripts": {
|
|
51
53
|
"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}
|
package/tokens/interaction.css
CHANGED
|
@@ -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 */
|