@ketvietlab/design-system 0.1.16 → 0.1.18
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/README.md +29 -0
- package/dist/catalogue/catalogue.css +8 -0
- package/dist/catalogue/index.js +1 -1
- package/dist/catalogue/inventory-policy.json +35 -0
- package/dist/catalogue/inventory.generated.js +1 -1
- package/dist/catalogue/inventory.generated.js.map +1 -1
- package/dist/catalogue/inventory.generated.json +1073 -113
- package/dist/catalogue/registry.d.ts.map +1 -1
- package/dist/catalogue/registry.js +6 -0
- package/dist/catalogue/registry.js.map +1 -1
- package/dist/catalogue/specimens.d.ts.map +1 -1
- package/dist/catalogue/specimens.js +113 -8
- package/dist/catalogue/specimens.js.map +1 -1
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +6 -0
- package/dist/contract/index.js.map +1 -1
- package/dist/data-display/bar-chart/index.d.ts +61 -0
- package/dist/data-display/bar-chart/index.d.ts.map +1 -0
- package/dist/data-display/bar-chart/index.js +64 -0
- package/dist/data-display/bar-chart/index.js.map +1 -0
- package/dist/data-display/bar-chart/styles.css +191 -0
- package/dist/data-display/matrix/index.d.ts +36 -0
- package/dist/data-display/matrix/index.d.ts.map +1 -0
- package/dist/data-display/matrix/index.js +28 -0
- package/dist/data-display/matrix/index.js.map +1 -0
- package/dist/data-display/matrix/styles.css +148 -0
- package/dist/data-operations/timeframe-filter/index.d.ts +34 -0
- package/dist/data-operations/timeframe-filter/index.d.ts.map +1 -0
- package/dist/data-operations/timeframe-filter/index.js +30 -0
- package/dist/data-operations/timeframe-filter/index.js.map +1 -0
- package/dist/data-operations/timeframe-filter/styles.css +109 -0
- package/dist/foundations/tokens.css +10 -0
- package/dist/index.d.ts +11 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/interactions/menu/index.d.ts +17 -2
- package/dist/interactions/menu/index.d.ts.map +1 -1
- package/dist/interactions/menu/index.js +21 -5
- package/dist/interactions/menu/index.js.map +1 -1
- package/dist/interactions/menu/styles.css +36 -0
- package/dist/layouts/app-navigation/styles.css +8 -0
- package/dist/layouts/layout/index.d.ts +43 -3
- package/dist/layouts/layout/index.d.ts.map +1 -1
- package/dist/layouts/layout/index.js +28 -4
- package/dist/layouts/layout/index.js.map +1 -1
- package/dist/layouts/layout/styles.css +182 -4
- package/dist/layouts/page-identity/index.d.ts +19 -0
- package/dist/layouts/page-identity/index.d.ts.map +1 -0
- package/dist/layouts/page-identity/index.js +6 -0
- package/dist/layouts/page-identity/index.js.map +1 -0
- package/dist/layouts/shell/index.d.ts +7 -11
- package/dist/layouts/shell/index.d.ts.map +1 -1
- package/dist/layouts/shell/index.js +12 -2
- package/dist/layouts/shell/index.js.map +1 -1
- package/dist/layouts/shell/styles.css +16 -31
- package/dist/patterns/data-table/index.d.ts.map +1 -1
- package/dist/patterns/data-table/index.js +1 -1
- package/dist/patterns/data-table/index.js.map +1 -1
- package/dist/patterns/data-table/styles.css +132 -43
- package/dist/patterns/list-chrome/index.d.ts +2 -2
- package/dist/patterns/list-chrome/index.d.ts.map +1 -1
- package/dist/patterns/list-chrome/index.js +4 -3
- package/dist/patterns/list-chrome/index.js.map +1 -1
- package/dist/patterns/list-chrome/styles.css +122 -40
- package/dist/patterns/list-page/styles.css +5 -1
- package/dist/patterns/modal-sheet/index.d.ts +9 -2
- package/dist/patterns/modal-sheet/index.d.ts.map +1 -1
- package/dist/patterns/modal-sheet/index.js +5 -1
- package/dist/patterns/modal-sheet/index.js.map +1 -1
- package/dist/patterns/modal-sheet/styles.css +1 -1
- package/dist/patterns/page-shell/index.d.ts +2 -23
- package/dist/patterns/page-shell/index.d.ts.map +1 -1
- package/dist/patterns/page-shell/index.js +1 -10
- package/dist/patterns/page-shell/index.js.map +1 -1
- package/dist/patterns/page-shell/styles.css +131 -0
- package/dist/patterns/patterns.css +1 -0
- package/dist/primitives/feedback/index.d.ts.map +1 -1
- package/dist/primitives/feedback/index.js +9 -2
- package/dist/primitives/feedback/index.js.map +1 -1
- package/dist/primitives/feedback/styles.css +42 -17
- package/dist/primitives/navigation/index.d.ts +11 -5
- package/dist/primitives/navigation/index.d.ts.map +1 -1
- package/dist/primitives/navigation/index.js +17 -2
- package/dist/primitives/navigation/index.js.map +1 -1
- package/dist/primitives/navigation/styles.css +101 -13
- package/dist/primitives/status/index.d.ts.map +1 -1
- package/dist/primitives/status/index.js +2 -2
- package/dist/primitives/status/index.js.map +1 -1
- package/dist/primitives/status/styles.css +8 -8
- package/dist/record/display/index.js +1 -1
- package/dist/record/display/index.js.map +1 -1
- package/dist/record/display/styles.css +2 -2
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +99 -4
- package/dist/runtime/index.js.map +1 -1
- package/dist/styles.css +2 -50
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -41,6 +41,31 @@ transparent scrolling viewport inside; never wrap it in another `Surface`.
|
|
|
41
41
|
The title is retained in its empty state, with optional `emptyActions` for recovery.
|
|
42
42
|
Omitting `title` preserves the existing unheaded form surface or standalone table.
|
|
43
43
|
|
|
44
|
+
### Collections open records in a modal
|
|
45
|
+
|
|
46
|
+
A row of a `DataTable` (or `ResourceList`, `DataGrid`) and a `KanbanCard` always open
|
|
47
|
+
their record in a `ModalSheet` on top of the collection. They never navigate to a
|
|
48
|
+
separate record page. The reader keeps the collection's filters, scroll position,
|
|
49
|
+
selection and board column while working on one record, and closing the modal
|
|
50
|
+
returns them exactly where they were.
|
|
51
|
+
|
|
52
|
+
- `rowHref` and `KanbanCard href` point at the modal trigger for that record, not at
|
|
53
|
+
a record route. Create actions on the same collection follow the same rule.
|
|
54
|
+
- The modal is a client-side island. It owns open and close, focus trapping and
|
|
55
|
+
restoration, Escape and backdrop closing, background inertness, tabs inside the
|
|
56
|
+
record, unsaved-change prompts and completion feedback. Opening, switching tabs
|
|
57
|
+
and closing do not reload the page or rebuild the collection on the server.
|
|
58
|
+
- Modal state is not a separate page state. A deep link may ask the island to open a
|
|
59
|
+
record after hydration, but the server always renders the collection with a closed
|
|
60
|
+
modal host, so the server and first client render stay identical.
|
|
61
|
+
- Size follows content: a short record uses the default size, and only long content
|
|
62
|
+
such as a multi-tab record uses the large size with an internal scroll region.
|
|
63
|
+
- A child action of the record (reassign, postpone, confirm) opens inside the same
|
|
64
|
+
island as a nested step, not as another page.
|
|
65
|
+
- `RecordPage` remains for records reached directly rather than from a collection,
|
|
66
|
+
such as a shared link or a record without a parent list. It is never the target of
|
|
67
|
+
a collection row or card.
|
|
68
|
+
|
|
44
69
|
The app structure is demonstrated with `AppNavigation` and four practical layouts inside `AppShell`:
|
|
45
70
|
collection (`ListPage`), record (`RecordPage`), flow workspace (`WorkspacePage`
|
|
46
71
|
with `layout="flow"`), and canvas workspace (`WorkspacePage` with
|
|
@@ -57,6 +82,10 @@ Only leaf links expose the active state. Top-level branches form one accordion a
|
|
|
57
82
|
the complete sidebar, and the interaction adapter keeps the open branch from being
|
|
58
83
|
collapsed without choosing another branch. Use `expanded` when a branch should start
|
|
59
84
|
open without an active descendant.
|
|
85
|
+
Top-level navigation rows use the shared dense metrics: a 30px row, 13px label,
|
|
86
|
+
10px content gap and an 18px leading icon. Icon size belongs to `AppNavigation`, so
|
|
87
|
+
application shells and catalogue demos render the same geometry without local icon
|
|
88
|
+
overrides.
|
|
60
89
|
The optional interaction adapter adds mobile dialog semantics, Escape/backdrop/link
|
|
61
90
|
closing, focus trapping and restoration, background inertness, and scroll locking.
|
|
62
91
|
|
|
@@ -374,6 +374,14 @@
|
|
|
374
374
|
overflow: hidden;
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
+
/* Overlay specimens must demonstrate the real layer instead of clipping it
|
|
378
|
+
to the documentation card. The normal clipped border returns when closed. */
|
|
379
|
+
:where([data-kv-design-system]) [data-ui="catalogue-specimen"]:has([data-ui="menu"][open]) {
|
|
380
|
+
position: relative;
|
|
381
|
+
z-index: var(--kv-layer-menu);
|
|
382
|
+
overflow: visible;
|
|
383
|
+
}
|
|
384
|
+
|
|
377
385
|
:where([data-kv-design-system]) [data-ui="catalogue-specimen-head"] {
|
|
378
386
|
display: flex;
|
|
379
387
|
align-items: start;
|
package/dist/catalogue/index.js
CHANGED
|
@@ -44,7 +44,7 @@ export const CATALOGUE_HOOKS = [
|
|
|
44
44
|
export const CatalogueHead = () => html `<meta name="description" content="Két Việt public component documentation"><link rel="stylesheet" href="/design-system/catalogue/styles.css"><script type="module" src="/design-system/runtime/auto.js"></script>`;
|
|
45
45
|
const registrationsFor = (groupId) => componentRegistry.filter((registration) => registration.groupId === groupId);
|
|
46
46
|
const pathWithPreferences = (path, theme, density) => `${path}?theme=${theme}&density=${density}`;
|
|
47
|
-
const CatalogueRail = (props) => (_jsxs("aside", { "data-ui": "catalogue-rail", children: [_jsxs("a", { "data-ui": "catalogue-brand", href: pathWithPreferences('/', props.theme, props.density), children: [_jsx("span", { "aria-hidden": "true", children: "K" }), _jsx("strong", { children: "K\u00E9t Vi\u1EC7t" })] }), _jsx("p", { "data-ui": "catalogue-kicker", children: "Design system \u00B7 0.1.
|
|
47
|
+
const CatalogueRail = (props) => (_jsxs("aside", { "data-ui": "catalogue-rail", children: [_jsxs("a", { "data-ui": "catalogue-brand", href: pathWithPreferences('/', props.theme, props.density), children: [_jsx("span", { "aria-hidden": "true", children: "K" }), _jsx("strong", { children: "K\u00E9t Vi\u1EC7t" })] }), _jsx("p", { "data-ui": "catalogue-kicker", children: "Design system \u00B7 0.1.18" }), _jsxs("nav", { "data-ui": "catalogue-nav", "aria-label": "Design system documentation", children: [_jsx("span", { "data-ui": "catalogue-nav-section", children: "Get started" }), _jsx("a", { "data-ui": "catalogue-nav-group", href: pathWithPreferences('/', props.theme, props.density), "aria-current": props.active === 'overview' ? 'page' : null, children: _jsx("span", { children: "Overview" }) }), _jsxs("a", { "data-ui": "catalogue-nav-group", href: pathWithPreferences('/components', props.theme, props.density), "aria-current": props.active === 'components' ? 'page' : null, children: [_jsx("span", { children: "Components" }), _jsx("span", { "data-ui": "catalogue-nav-count", children: String(componentRegistry.length) })] }), _jsx("a", { "data-ui": "catalogue-nav-group", href: `/demo?theme=${props.theme}`, children: _jsx("span", { children: "Application demo" }) }), _jsx("a", { "data-ui": "catalogue-nav-group", href: `/demo2?theme=${props.theme}`, children: _jsx("span", { children: "Application submenu demo" }) }), _jsx("span", { "data-ui": "catalogue-nav-section", children: "Component groups" }), each(componentGroups, (group) => group.id, (group) => (_jsxs("a", { "data-ui": "catalogue-nav-group", href: pathWithPreferences(`/components/${group.id}`, props.theme, props.density), "aria-current": props.active === group.id ? 'page' : null, children: [_jsx("span", { children: group.name }), _jsx("span", { "data-ui": "catalogue-nav-count", children: String(registrationsFor(group.id).length) })] }))), _jsx("span", { "data-ui": "catalogue-nav-section", children: "Reference" }), _jsxs("a", { "data-ui": "catalogue-nav-group", href: "/surfaces?kind=record&theme=light", children: [_jsx("span", { children: "Page patterns" }), _jsx("span", { "data-ui": "catalogue-nav-count", children: "3" })] }), _jsx("a", { "data-ui": "catalogue-nav-group", href: "/inventory", children: _jsx("span", { children: "Inventory" }) })] })] }));
|
|
48
48
|
const CataloguePreferences = (props) => (_jsxs("div", { "data-ui": "catalogue-controls", role: "group", "aria-label": "Catalogue preferences", children: [_jsx("span", { children: "Theme" }), each(['light', 'dark', 'system'], (value) => value, (value) => (_jsx("a", { href: pathWithPreferences(props.path, value, props.density), "aria-current": props.theme === value ? 'page' : null, children: value[0].toUpperCase() + value.slice(1) }))), _jsx("span", { children: "Density" }), each(['compact', 'default', 'comfortable'], (value) => value, (value) => (_jsx("a", { href: pathWithPreferences(props.path, props.theme, value), "aria-current": props.density === value ? 'page' : null, children: value === 'comfortable' ? 'Comfort' : value[0].toUpperCase() + value.slice(1) })))] }));
|
|
49
49
|
const Overview = (props) => (_jsxs(_Fragment, { children: [_jsxs("header", { "data-ui": "catalogue-hero", children: [_jsxs("div", { children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "SSR-first \u00B7 operational \u00B7 accessible" }), _jsx("h1", { "data-ui": "catalogue-title", children: "The interface language for K\u00E9t applications." }), _jsx("p", { "data-ui": "catalogue-intro", children: "Reusable contracts for dense business software\u2014designed to remain useful before JavaScript arrives and predictable when the workflow gets complicated." }), _jsx(LinkButton, { label: `Explore ${String(componentRegistry.length)} components`, href: pathWithPreferences('/components', props.theme, props.density), variant: "primary" }), _jsx(LinkButton, { label: "Review inventory", href: "/inventory", variant: "secondary" }), _jsx(LinkButton, { label: "Open application demo", href: `/demo?theme=${props.theme === 'system' ? 'light' : props.theme}`, variant: "secondary" }), _jsx(LinkButton, { label: "Try submenu navigation", href: `/demo2?theme=${props.theme === 'system' ? 'light' : props.theme}`, variant: "secondary" })] }), _jsx(CataloguePreferences, { path: "/", theme: props.theme, density: props.density })] }), _jsxs("section", { "data-ui": "catalogue-metrics", "aria-label": "Design system summary", children: [_jsxs("article", { children: [_jsx("strong", { children: String(componentRegistry.length) }), _jsx("span", { children: "public components" })] }), _jsxs("article", { children: [_jsx("strong", { children: String(componentGroups.reduce((total, group) => total + group.examples.length, 0)) }), _jsx("span", { children: "executable specimens" })] }), _jsxs("article", { children: [_jsx("strong", { children: String(componentGroups.length) }), _jsx("span", { children: "documented groups" })] }), _jsxs("article", { children: [_jsx("strong", { children: String(designSystemInventory.summary.plannedComponents) }), _jsx("span", { children: "planned contracts" })] })] }), _jsxs("section", { "data-ui": "catalogue-group", children: [_jsxs("header", { "data-ui": "catalogue-group-head", children: [_jsxs("div", { children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "System map" }), _jsx("h2", { children: "Start with the contract" })] }), _jsx("p", { children: "Use the smallest stable layer that owns the behavior. Recipes compose components; applications own business state." })] }), _jsxs("div", { "data-ui": "catalogue-doc-grid", children: [_jsxs("article", { "data-ui": "catalogue-doc-card", children: [_jsx("span", { children: "01" }), _jsx("h3", { children: "Foundations" }), _jsx("p", { children: "Semantic tokens, density, focus, motion and responsive rules form one cascade." }), _jsx("a", { href: "/inventory#css", children: "Inspect CSS ownership \u2192" })] }), _jsxs("article", { "data-ui": "catalogue-doc-card", children: [_jsx("span", { children: "02" }), _jsx("h3", { children: "Components" }), _jsxs("p", { children: [String(componentRegistry.length), " renderer contracts with explicit owners, states and specimens."] }), _jsx("a", { href: pathWithPreferences('/components', props.theme, props.density), children: "Browse components \u2192" })] }), _jsxs("article", { "data-ui": "catalogue-doc-card", children: [_jsx("span", { children: "03" }), _jsx("h3", { children: "Page patterns" }), _jsx("p", { children: "ListPage, RecordPage and WorkspacePage are the only full-page identities." }), _jsx("a", { href: "/surfaces?kind=record&theme=light", children: "Review page surfaces \u2192" })] })] })] }), _jsxs("section", { "data-ui": "catalogue-group", children: [_jsxs("header", { "data-ui": "catalogue-group-head", children: [_jsxs("div", { children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "Component library" }), _jsx("h2", { children: "Explore the system" })] }), _jsx("p", { children: "Every number below is a component contract, not a specimen card." })] }), _jsx("div", { "data-ui": "catalogue-doc-grid", children: each(componentGroups, (group) => group.id, (group) => (_jsxs("a", { "data-ui": "catalogue-doc-card", href: pathWithPreferences(`/components/${group.id}`, props.theme, props.density), children: [_jsx("span", { children: String(registrationsFor(group.id).length).padStart(2, '0') }), _jsx("h3", { children: group.name }), _jsx("p", { children: group.description })] }))) })] })] }));
|
|
50
50
|
const ComponentIndex = (props) => (_jsxs(_Fragment, { children: [_jsxs("header", { "data-ui": "catalogue-hero", children: [_jsxs("div", { children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "Reference / components" }), _jsxs("h1", { "data-ui": "catalogue-title", children: [String(componentRegistry.length), " public components"] }), _jsx("p", { "data-ui": "catalogue-intro", children: "Search the complete public surface by ownership group. Components may share a specimen, but every contract remains visible here." })] }), _jsx(CataloguePreferences, { path: props.path, theme: props.theme, density: props.density })] }), _jsx("div", { "data-ui": "catalogue-component-index", children: each(componentGroups, (group) => group.id, (group) => (_jsxs("section", { "data-ui": "catalogue-component-list", "aria-labelledby": `${group.id}-title`, children: [_jsxs("header", { children: [_jsx("h2", { id: `${group.id}-title`, children: group.name }), _jsx("span", { children: String(registrationsFor(group.id).length) })] }), each(registrationsFor(group.id), (registration) => registration.name, (registration) => (_jsxs("a", { "data-ui": "catalogue-component-link", href: `${pathWithPreferences(`/components/${group.id}`, props.theme, props.density)}#${registration.specimenId}`, children: [_jsx("strong", { children: registration.name }), _jsx("small", { children: registration.maturity })] })))] }))) })] }));
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "ketjs.design-system-inventory-policy.v1",
|
|
3
3
|
"publicModules": {
|
|
4
|
+
"./data-operations/timeframe-filter/index.tsx": {
|
|
5
|
+
"owner": "Data operations",
|
|
6
|
+
"maturity": "stable",
|
|
7
|
+
"decision": "build",
|
|
8
|
+
"wave": 4,
|
|
9
|
+
"gapTask": "DS-031"
|
|
10
|
+
},
|
|
11
|
+
"./data-display/bar-chart/index.tsx": {
|
|
12
|
+
"owner": "Data display",
|
|
13
|
+
"maturity": "stable",
|
|
14
|
+
"decision": "build",
|
|
15
|
+
"wave": 4,
|
|
16
|
+
"gapTask": "DS-031"
|
|
17
|
+
},
|
|
4
18
|
"./data-display/data-grid/index.tsx": {
|
|
5
19
|
"owner": "Data display",
|
|
6
20
|
"maturity": "stable",
|
|
@@ -8,6 +22,13 @@
|
|
|
8
22
|
"wave": 4,
|
|
9
23
|
"gapTask": "DS-031"
|
|
10
24
|
},
|
|
25
|
+
"./data-display/matrix/index.tsx": {
|
|
26
|
+
"owner": "Data display",
|
|
27
|
+
"maturity": "stable",
|
|
28
|
+
"decision": "build",
|
|
29
|
+
"wave": 4,
|
|
30
|
+
"gapTask": "DS-031"
|
|
31
|
+
},
|
|
11
32
|
"./data-display/resource-list/index.tsx": {
|
|
12
33
|
"owner": "Data display",
|
|
13
34
|
"maturity": "stable",
|
|
@@ -554,6 +575,20 @@
|
|
|
554
575
|
"target": "Public core",
|
|
555
576
|
"wave": 1,
|
|
556
577
|
"gapTask": "DS-007"
|
|
578
|
+
},
|
|
579
|
+
"./record-modal.tsx": {
|
|
580
|
+
"owner": "Overlays",
|
|
581
|
+
"decision": "promote",
|
|
582
|
+
"target": "Public core",
|
|
583
|
+
"wave": 2,
|
|
584
|
+
"gapTask": "DS-015"
|
|
585
|
+
},
|
|
586
|
+
"./client/record-modal.tsx": {
|
|
587
|
+
"owner": "Overlays",
|
|
588
|
+
"decision": "promote",
|
|
589
|
+
"target": "Public core",
|
|
590
|
+
"wave": 2,
|
|
591
|
+
"gapTask": "DS-015"
|
|
557
592
|
}
|
|
558
593
|
},
|
|
559
594
|
"plannedComponents": []
|