@keyfunc/keybricks-ds 2.4.0 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEPLOY.md +4 -4
- package/DESIGN.md +7 -1
- package/INTEGRATION.md +11 -2
- package/_adherence.oxlintrc.json +7 -0
- package/components/_cards/relative-time-picker.card.html +45 -0
- package/components/_cards/smart-table.card.html +4 -1
- package/components/_shared/src-data.js +1 -1
- package/components/_shared/src-forms.js +1 -1
- package/components/_vue/index.mjs +1 -0
- package/components/data/SmartTable.d.ts +7 -2
- package/components/data/SmartTable.jsx +12 -4
- package/components/data/SmartTable.vue +12 -4
- package/components/forms/RelativeTimePicker.d.ts +39 -0
- package/components/forms/RelativeTimePicker.jsx +89 -0
- package/components/forms/RelativeTimePicker.prompt.md +72 -0
- package/components/forms/RelativeTimePicker.vue +81 -0
- package/components/forms/forms.prompt.md +3 -0
- package/components/forms/relative-time.d.ts +12 -0
- package/components/forms/relative-time.js +90 -0
- package/components/index.d.ts +1 -0
- package/components/index.js +1 -0
- package/components/navigation/Sidebar.d.ts +1 -1
- package/package.json +2 -2
- package/readme.md +3 -2
- package/readme.zh-CN.md +3 -2
- package/tokens/tokens.json +1 -1
package/DEPLOY.md
CHANGED
|
@@ -55,7 +55,7 @@ deploys the documentation site. Watch it under *Build → Pipelines*.
|
|
|
55
55
|
**5. Cut the first release.**
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
git tag v2.4.
|
|
58
|
+
git tag v2.4.2 && git push --tags
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
That tag runs `generated:check` → `version:check` → `npm publish`. Confirm under *Deploy →
|
|
@@ -112,7 +112,7 @@ import tokens from '@keyfunc/keybricks-ds/tokens.json' // cross-
|
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
Deep imports are the better default in Vue and in any app that cares about tree-shaking —
|
|
115
|
-
a barrel of
|
|
115
|
+
a barrel of 130 exports asks the bundler to prove each one is unused.
|
|
116
116
|
|
|
117
117
|
## 3. Publishing (maintainers)
|
|
118
118
|
|
|
@@ -162,7 +162,7 @@ GitLab injects `CI_JOB_TOKEN` — use that instead and no secret is stored anywh
|
|
|
162
162
|
**Install — straight from git** (no registry, no publish; works today)
|
|
163
163
|
|
|
164
164
|
```json
|
|
165
|
-
"@keyfunc/keybricks-ds": "git+ssh://git@gitlab.epm2demo.cn/Felix/keybricks-ds.git#v2.4.
|
|
165
|
+
"@keyfunc/keybricks-ds": "git+ssh://git@gitlab.epm2demo.cn/Felix/keybricks-ds.git#v2.4.2"
|
|
166
166
|
```
|
|
167
167
|
|
|
168
168
|
Because the package has no build step, a git dependency needs no `prepare` script — npm
|
|
@@ -212,7 +212,7 @@ semantic layer. That is what makes dark mode cost nothing.
|
|
|
212
212
|
## Runtime checks
|
|
213
213
|
|
|
214
214
|
`_tests/` holds browser pages that exercise the real components: `react-runtime.html` (the compiled
|
|
215
|
-
bundle), `table-selection.html` (Table loaded from source: checkbox spacing at every width, code chips, two-line rows, sorting), `vue-runtime.html` (the `.vue` files, loaded with vue3-sfc-loader), `cards-interaction*.html`
|
|
215
|
+
bundle), `table-selection.html` (Table loaded from source: checkbox spacing at every width, code chips, two-line rows, sorting), `smart-table-density.html` (SmartTable from source: default / compact rows, the Row height menu, controlled density), `relative-time-picker.html` (RelativeTimePicker from source: helpers, tiers, dialog, keyboard), `vue-runtime.html` (the `.vue` files, loaded with vue3-sfc-loader), `cards-interaction*.html`
|
|
216
216
|
(clicks through the documentation demos) and `icon-rules.html` (the Keybricks glyphs against the drawing rules). Serve the repo root (`npx serve .`), open a page and read the
|
|
217
217
|
console — every line starts with PASS or FAIL. Run them after changing a component in either framework.
|
|
218
218
|
`measure-cards.html` is a tool, not a test: it measures each documentation page at its card width so the
|
package/DESIGN.md
CHANGED
|
@@ -319,6 +319,12 @@ Where each tier belongs:
|
|
|
319
319
|
|
|
320
320
|
- **sm** — dense data grids (`SmartTable`, `Spreadsheet` and `DataPreview` set it themselves),
|
|
321
321
|
controls inside pipeline nodes, a toolbar that must fit a 32px row.
|
|
322
|
+
`SmartTable` adds a **row density** on top of the tier: `default` rows are the tier's `--bar-h`
|
|
323
|
+
(36 / 40 / 48) with `--cell-px`; `compact` rows are the tier's `--control-h` (28 / 32 / 40 — the
|
|
324
|
+
same as a Spreadsheet cell) with the Spreadsheet's 8px cell padding — `--cell-px` is already 8 at
|
|
325
|
+
sm, so there only the height changes. Header and footer rows follow; the toolbar does not. Users switch it from the toolbar's *Row height* menu (a single-choice menu); `density`
|
|
326
|
+
controls it, `defaultDensity` seeds it. Pills (20), checkboxes (16) and avatars (20) all centre in
|
|
327
|
+
a 28px row. There is no taller option: long text truncates in every density.
|
|
322
328
|
- **md** — everything else: app toolbars, filter bars, tables, long forms, settings pages.
|
|
323
329
|
- **lg** — dialogs (`Modal` sets it), short forms, wizards, onboarding, a page with one task.
|
|
324
330
|
|
|
@@ -455,7 +461,7 @@ The list that prevents the most rework. These are absolute.
|
|
|
455
461
|
- **Do not show a drop indicator where the drop is impossible.** No half-row boxes on a
|
|
456
462
|
container, no insert rules on a node that can't take children.
|
|
457
463
|
- **Do not build a new primitive when one exists.** Check the component index in
|
|
458
|
-
`INTEGRATION.md` first — there are
|
|
464
|
+
`INTEGRATION.md` first — there are 121.
|
|
459
465
|
- **Do not use emoji as icons.** Use `<Icon name="..." />` (330 glyphs) or `<Unicon>` (1,206).
|
|
460
466
|
- **Do not invent new component variants.** If `Button` lacks the variant you want, that is a
|
|
461
467
|
design-system request, not a local override.
|
package/INTEGRATION.md
CHANGED
|
@@ -31,7 +31,7 @@ Not using a registry yet? A git dependency works with no publishing at all — t
|
|
|
31
31
|
has no build step, so npm can use the checkout as-is:
|
|
32
32
|
|
|
33
33
|
```json
|
|
34
|
-
"@keyfunc/keybricks-ds": "git+ssh://git@gitlab.epm2demo.cn/Felix/keybricks-ds.git#v2.4.
|
|
34
|
+
"@keyfunc/keybricks-ds": "git+ssh://git@gitlab.epm2demo.cn/Felix/keybricks-ds.git#v2.4.2"
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
**Source-only package.** `.jsx` and `.vue` files are published as authored, so your
|
|
@@ -162,7 +162,7 @@ Text, weight and tracking follow the tier through `--control-text` / `--control-
|
|
|
162
162
|
weight becomes 600 and all tracking is 0 — nothing to configure. `DESIGN.md` has the full token
|
|
163
163
|
table and the rules behind it.
|
|
164
164
|
|
|
165
|
-
## Component index (
|
|
165
|
+
## Component index (121 components)
|
|
166
166
|
Import path is `@keyfunc/keybricks-ds/components/<group>/<Name>.jsx` (React) or `.vue` (Vue 3).
|
|
167
167
|
Every component has a sibling `.d.ts` with its full props contract, and each group has a
|
|
168
168
|
`.prompt.md` with usage notes.
|
|
@@ -220,6 +220,7 @@ import Textarea from '@keyfunc/keybricks-ds/components/forms/Textarea.vue'
|
|
|
220
220
|
| `Slider` | Range input with a filled track, drag value bubble and optional min/max labels. |
|
|
221
221
|
| `DatePicker` | Text field plus a month-grid popover. Values are `YYYY-MM-DD` strings; `locale` localises the month title, weekday initials and field text. |
|
|
222
222
|
| `Dropzone` | File drop target with hover, drag-over, uploaded and error states. |
|
|
223
|
+
| `RelativeTimePicker` | "How long ago" filter for logs, monitoring and inboxes: a field-shaped trigger opening a small dialog with an amount input, a unit select (minute … month, optional "Any time" → `null`) and a live "From" preview. Pure helpers in `forms/relative-time.js` (`resolveRelativeTime`, `normalizeRelativeTime` …). `labels` localises every string. |
|
|
223
224
|
|
|
224
225
|
### `data/` — tables and structured values
|
|
225
226
|
| Component | What it's for |
|
|
@@ -519,6 +520,14 @@ Pin a minor range and update deliberately:
|
|
|
519
520
|
- **Tokens outside CSS.** `tokens.json` / `tokens.js` / `tokens.d.ts` gained the tier tokens
|
|
520
521
|
(`--control-*`, `--bar-h`, `--group-gap`, …) — 352 light tokens in all (2.0.2 adds `--danger-soft-hover`).
|
|
521
522
|
|
|
523
|
+
### 2.4.2
|
|
524
|
+
|
|
525
|
+
- **New `RelativeTimePicker`** (forms) — the relative-time filter from the product, contributed by the app team and brought onto the system rules: inline token styling (the separate `relative-time.css` is gone), `Field` labels in the dialog, `data-field` hover, `.5` disabled opacity like every other field. Unit labels may be `{ one, other }` and follow `Intl.PluralRules` of `locale` ("1 hour ago" / "2 hours ago"; a CJK label stays one string); the amount field is a plain numeric text field (`inputmode="numeric"`, no native spinners). Props unchanged: `value` / `onChange(value, date)` (Vue `v-model` + `@change`), `allowUnlimited`, `labels`, `locale`, `referenceDate`, `formatDate`, `formatValue`, `size`. Helpers in `forms/relative-time.js`. Also brought in from the 2.4.1 merge: the app team's original files (`relative-time.js`, types, prompt) are kept; only the styling moved inline.
|
|
526
|
+
|
|
527
|
+
### 2.4.1
|
|
528
|
+
|
|
529
|
+
- **`SmartTable` row density.** `density: "default" | "compact"` (+ `defaultDensity`, `onDensityChange`; Vue `v-model:density` / `@density-change`). Default rows stay the tier's `--bar-h`; compact rows are the tier's `--control-h` (28 at sm, the Spreadsheet's cell height) with 8px cell padding, header and footer included. The toolbar gains a *Row height* single-choice menu. `rowHeight` still works and overrides density.
|
|
530
|
+
|
|
522
531
|
### 2.4.0
|
|
523
532
|
|
|
524
533
|
- **App Chrome matches the product.** `Sidebar`: 56px brand head without a rule, `--text-md` brand, a 2px-gap list, `trailing: true` items with a chevron (they open a side panel), Collapse / Expand item (chevron-left / panel-left), pinned footer and an optional `version` line. New `tone` prop — `"recessed"` (grey rail, active item a white tile with a hairline ring; **the new default**), `"flush"` (the old white look), `"contrast"` (dark-scoped rail), `"custom"` + `color` (`SIDEBAR_COLORS` or any hex). `KEYBRICKS_NAV` is the product's nav (Home … Task Execution); new `KEYBRICKS_NAV_FOOTER` (Management, Knowledge Base) is the default footer (was Help / Settings / Dark Mode) and `KEYBRICKS_MGMT` holds the Management panel groups. To keep the old look pass `tone="flush"` and your own `footerItems`.
|
package/_adherence.oxlintrc.json
CHANGED
|
@@ -405,6 +405,10 @@
|
|
|
405
405
|
"selector": "JSXOpeningElement[name.name='Radio'] > JSXAttribute[name.name='size'] > Literal[value!=/^(?:sm|md|lg)$/]",
|
|
406
406
|
"message": "<Radio> size must be one of 'sm' | 'md' | 'lg'."
|
|
407
407
|
},
|
|
408
|
+
{
|
|
409
|
+
"selector": "JSXOpeningElement[name.name='RelativeTimeValue'] > JSXAttribute > JSXIdentifier[name!=/^(?:amount|unit|key|ref|className|style|children)$/]",
|
|
410
|
+
"message": "<RelativeTimeValue> doesn't accept that prop. Declared props: amount, unit."
|
|
411
|
+
},
|
|
408
412
|
{
|
|
409
413
|
"selector": "JSXOpeningElement[name.name='Ribbon3DSeries'] > JSXAttribute > JSXIdentifier[name!=/^(?:name|values|color|key|ref|className|style|children)$/]",
|
|
410
414
|
"message": "<Ribbon3DSeries> doesn't accept that prop. Declared props: name, values, color."
|
|
@@ -785,6 +789,9 @@
|
|
|
785
789
|
"Radio": {
|
|
786
790
|
"replaces": []
|
|
787
791
|
},
|
|
792
|
+
"RelativeTimeValue": {
|
|
793
|
+
"replaces": []
|
|
794
|
+
},
|
|
788
795
|
"Ribbon3DSeries": {
|
|
789
796
|
"replaces": []
|
|
790
797
|
},
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<!-- @dsCard group="Components" viewport="700x720" name="Relative Time Picker" subtitle="Filter by how long ago · md / sm / lg · unlimited · disabled · localised labels" -->
|
|
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"><link rel="stylesheet" href="../_shared/card-kit.css">
|
|
4
|
+
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
5
|
+
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
6
|
+
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
7
|
+
<script src="../../_ds_bundle.js"></script>
|
|
8
|
+
<script src="../_shared/card-kit.js"></script>
|
|
9
|
+
<script src="../_shared/view-source.js"></script>
|
|
10
|
+
<style>body{margin:0;background:var(--bg-surface)}</style></head>
|
|
11
|
+
<body><div id="root"></div>
|
|
12
|
+
<script type="text/babel">
|
|
13
|
+
const { RelativeTimePicker, Field, Button, SearchInput } = window.KeybricksDesignSystem_71231a;
|
|
14
|
+
const ZH = { title: "相对时间", amount: "数量", unit: "单位", preview: "起始时间", unlimited: "不限时间", Minute: "分钟前", Hour: "小时前", Day: "天前", Week: "周前", Month: "个月前" };
|
|
15
|
+
function Sheet() {
|
|
16
|
+
const [a, setA] = React.useState({ amount: 1, unit: "Hour" });
|
|
17
|
+
const [b, setB] = React.useState({ amount: 7, unit: "Day" });
|
|
18
|
+
const [c, setC] = React.useState({ amount: 0, unit: "None" });
|
|
19
|
+
const [z, setZ] = React.useState({ amount: 30, unit: "Minute" });
|
|
20
|
+
const [last, setLast] = React.useState(null);
|
|
21
|
+
const on = (set) => (v, d) => { set(v); setLast(d ? d.toLocaleString() : "null (any time)"); };
|
|
22
|
+
return <div className="kb-sheet">
|
|
23
|
+
<KBSec title="Trigger — md · sm · lg" note="A field-shaped trigger at the tier height; click it to open the dialog (amount + unit, live “From” preview). Omit size to inherit the region's tier.">
|
|
24
|
+
<KBRow k="md"><div style={{ width: 220 }}><RelativeTimePicker value={a} onChange={on(setA)} /></div></KBRow>
|
|
25
|
+
<KBRow k="sm"><div data-size="sm" style={{ width: 200 }}><RelativeTimePicker value={b} onChange={on(setB)} /></div></KBRow>
|
|
26
|
+
<KBRow k="lg"><div data-size="lg" style={{ width: 240 }}><RelativeTimePicker value={a} onChange={on(setA)} /></div></KBRow>
|
|
27
|
+
</KBSec>
|
|
28
|
+
<KBSec title="States" note="Unlimited reads “Any time” and resolves to null. allowUnlimited={false} removes that option; 0 still means unlimited for legacy filters.">
|
|
29
|
+
<KBRow k="unlimited"><div style={{ width: 220 }}><RelativeTimePicker value={c} onChange={on(setC)} /></div></KBRow>
|
|
30
|
+
<KBRow k="no unlimited"><div style={{ width: 220 }}><RelativeTimePicker value={b} onChange={on(setB)} allowUnlimited={false} /></div></KBRow>
|
|
31
|
+
<KBRow k="disabled"><div style={{ width: 220 }}><RelativeTimePicker value={a} disabled /></div></KBRow>
|
|
32
|
+
</KBSec>
|
|
33
|
+
<KBSec title="In a filter bar · localised" note="labels overrides every string; the dialog copies the region's tier, language and theme. onChange(value, date) only fires on edits, never on mount.">
|
|
34
|
+
<KBRow k="zh-CN" style={{ display: "block" }}><div lang="zh-CN" style={{ display: "flex", alignItems: "flex-end", gap: "var(--group-gap)" }}>
|
|
35
|
+
<Field label="时间范围" style={{ width: 200 }}><RelativeTimePicker value={z} onChange={on(setZ)} labels={ZH} locale="zh-CN" /></Field>
|
|
36
|
+
<Field label="关键字" style={{ width: 200 }}><SearchInput placeholder="搜索日志" /></Field>
|
|
37
|
+
<Button variant="outline">查询</Button>
|
|
38
|
+
</div></KBRow>
|
|
39
|
+
<div className="note">Last change resolved to: <code>{last || "—"}</code></div>
|
|
40
|
+
</KBSec>
|
|
41
|
+
</div>;
|
|
42
|
+
}
|
|
43
|
+
ReactDOM.createRoot(document.getElementById("root")).render(<Sheet />);
|
|
44
|
+
if (window.KBViewSource) setTimeout(function () { KBViewSource.mount("#root", [{ "name": "RelativeTimePicker.jsx", "path": "../forms/RelativeTimePicker.jsx" }, { "name": "relative-time.js", "path": "../forms/relative-time.js", "vue": "../forms/relative-time.js", "vueName": "relative-time.js" }]); }, 0);
|
|
45
|
+
</script></body></html>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- @dsCard group="Components" viewport="
|
|
1
|
+
<!-- @dsCard group="Components" viewport="700x900" name="Smart Table (Database Grid)" subtitle="Default and compact row density · Notion/Airtable-style grid — typed fields · hue pills · aggregates · + New" -->
|
|
2
2
|
<!DOCTYPE html>
|
|
3
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>
|
|
@@ -30,6 +30,9 @@ const rows=[
|
|
|
30
30
|
];
|
|
31
31
|
function Sheet(){return <div>
|
|
32
32
|
<SmartTable fields={fields} rows={rows} title="Launch tracker"/>
|
|
33
|
+
<div className="hint" style={{marginBottom:20}}>Default density — rows are the tier's bar height (36px at sm). The toolbar's <b>Row height</b> menu switches between Default and Compact.</div>
|
|
34
|
+
<SmartTable fields={fields} rows={rows.slice(0,4)} title="Launch tracker — compact" defaultDensity="compact"/>
|
|
35
|
+
<div className="hint" style={{marginBottom:20}}>Compact density — rows are the tier's control height (28px at sm, the same as a Spreadsheet cell) with the Spreadsheet's 8px cell padding (the same as sm's <code>--cell-px</code>, so here only the height changes); header and footer follow. <code>density="compact"</code> controls it, <code>defaultDensity</code> just seeds it.</div>
|
|
33
36
|
<div className="hint">Typed fields with per-type header icons; select/multi-select render theme-aware hue pills; hover a row number for the expand affordance; double-click text/number/date cells to edit; “+ New” appends a row; the footer aggregates per column (COUNT / SUM / AVG). Scrolls horizontally like Airtable when fields overflow.</div>
|
|
34
37
|
</div>;}
|
|
35
38
|
ReactDOM.createRoot(document.getElementById("root")).render(<Sheet/>);
|