@ketvietlab/design-system 0.1.22 → 0.1.25
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 +30 -1
- package/dist/catalogue/index.js +1 -1
- package/dist/catalogue/inventory-policy.json +7 -0
- package/dist/catalogue/inventory.generated.js +1 -1
- package/dist/catalogue/inventory.generated.js.map +1 -1
- package/dist/catalogue/inventory.generated.json +425 -141
- package/dist/catalogue/registry.d.ts.map +1 -1
- package/dist/catalogue/registry.js +3 -0
- package/dist/catalogue/registry.js.map +1 -1
- package/dist/catalogue/specimens.d.ts.map +1 -1
- package/dist/catalogue/specimens.js +16 -3
- package/dist/catalogue/specimens.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interactions/menu/index.d.ts +28 -1
- package/dist/interactions/menu/index.d.ts.map +1 -1
- package/dist/interactions/menu/index.js +16 -13
- package/dist/interactions/menu/index.js.map +1 -1
- package/dist/interactions/menu/styles.css +53 -1
- package/dist/patterns/data-table/styles.css +12 -0
- package/dist/patterns/list-chrome/index.d.ts +6 -1
- package/dist/patterns/list-chrome/index.d.ts.map +1 -1
- package/dist/patterns/list-chrome/index.js +5 -1
- package/dist/patterns/list-chrome/index.js.map +1 -1
- package/dist/patterns/list-chrome/styles.css +9 -0
- package/dist/patterns/modal-sheet/index.d.ts +23 -1
- package/dist/patterns/modal-sheet/index.d.ts.map +1 -1
- package/dist/patterns/modal-sheet/index.js +2 -1
- package/dist/patterns/modal-sheet/index.js.map +1 -1
- package/dist/patterns/modal-sheet/styles.css +25 -0
- package/dist/primitives/feedback/styles.css +37 -18
- package/dist/primitives/field/index.d.ts +5 -0
- package/dist/primitives/field/index.d.ts.map +1 -1
- package/dist/primitives/field/index.js +2 -2
- package/dist/primitives/field/index.js.map +1 -1
- package/dist/primitives/field/styles.css +8 -0
- package/dist/primitives/navigation/index.d.ts +36 -3
- package/dist/primitives/navigation/index.d.ts.map +1 -1
- package/dist/primitives/navigation/index.js +18 -1
- package/dist/primitives/navigation/index.js.map +1 -1
- package/dist/primitives/navigation/styles.css +27 -0
- package/dist/runtime/index.d.ts +1 -8
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +19 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -41,6 +41,15 @@ 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
|
+
### Popups close on an outside click and on Escape
|
|
45
|
+
|
|
46
|
+
Every popup built on `<details>` behaves like the action menu: a click outside it
|
|
47
|
+
closes it, and Escape closes the open one and returns focus to its summary. This
|
|
48
|
+
covers `Menu` (`data-ui="menu"`), the period choice of `TimeframeFilter`
|
|
49
|
+
(`data-ui="timeframe-menu"`) and list view settings (`data-ui="view-settings"`).
|
|
50
|
+
The runtime lists the non-menu popups in `DISMISSIBLE_POPUPS`; a new popup component
|
|
51
|
+
adds its hook there instead of wiring its own document listener.
|
|
52
|
+
|
|
44
53
|
### Collections open records in a modal
|
|
45
54
|
|
|
46
55
|
A row of a `DataTable` (or `ResourceList`, `DataGrid`) and a `KanbanCard` always open
|
|
@@ -60,12 +69,32 @@ returns them exactly where they were.
|
|
|
60
69
|
modal host, so the server and first client render stay identical.
|
|
61
70
|
- Size follows content: a short record uses the default size, and only long content
|
|
62
71
|
such as a multi-tab record uses the large size with an internal scroll region.
|
|
72
|
+
- A record with more than one tab passes `height: 'fixed'` to `ModalSheet`: the dialog
|
|
73
|
+
holds the viewport cap (`data-height="fixed"`) so switching between tabs of different
|
|
74
|
+
heights never resizes it. `TabbedView` keeps the tab bar visible and only `TabPanel`
|
|
75
|
+
scrolls. The panel deliberately owns no left or right padding; the containing modal
|
|
76
|
+
supplies the horizontal inset. A
|
|
77
|
+
single-view record and its nested dialogs keep `height: 'content'` (the default).
|
|
63
78
|
- A child action of the record (reassign, postpone, confirm) opens inside the same
|
|
64
79
|
island as a nested step, not as another page.
|
|
65
80
|
- `RecordPage` remains for records reached directly rather than from a collection,
|
|
66
81
|
such as a shared link or a record without a parent list. It is never the target of
|
|
67
82
|
a collection row or card.
|
|
68
83
|
|
|
84
|
+
### Option groups
|
|
85
|
+
|
|
86
|
+
`checkbox-group` and `radio` fields (`CheckboxGroup`, `RadioGroup`, or `RecordForm`
|
|
87
|
+
fields with those types) keep one label on the left and the options on the right,
|
|
88
|
+
each option's text after its control. `optionsOrientation` sets how the options flow:
|
|
89
|
+
|
|
90
|
+
- `horizontal` (default): options wrap on one line. Use for a few short choices.
|
|
91
|
+
- `vertical`: one option per line, rendered as `data-orientation="vertical"` on
|
|
92
|
+
`field-options`. Use when the choices should scan as a list, such as companies,
|
|
93
|
+
branches or job roles.
|
|
94
|
+
|
|
95
|
+
Do not restyle `field-options` in an application to stack options; pass
|
|
96
|
+
`optionsOrientation: 'vertical'` instead.
|
|
97
|
+
|
|
69
98
|
The app structure is demonstrated with `AppNavigation` and four practical layouts inside `AppShell`:
|
|
70
99
|
collection (`ListPage`), record (`RecordPage`), flow workspace (`WorkspacePage`
|
|
71
100
|
with `layout="flow"`), and canvas workspace (`WorkspacePage` with
|
|
@@ -207,7 +236,7 @@ The contract is intentionally strict:
|
|
|
207
236
|
- component CSS consumes semantic/component roles, not numbered palette swatches.
|
|
208
237
|
|
|
209
238
|
The public entry exports actions, status and feedback objects, fields, navigation,
|
|
210
|
-
|
|
239
|
+
`Tab`, `Tabs`, `TabPanel` and `TabbedView`, progress, layout primitives, the responsive application navigation, the
|
|
211
240
|
three-region app shell, page/record layouts,
|
|
212
241
|
`ListChrome` with `BulkActions` and `PagerBar`, the canonical list and record page
|
|
213
242
|
compositions, data tables, forms, and modal sheets. Use `ListPage` for operational
|
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.25" }), _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 })] })))] }))) })] }));
|
|
@@ -589,6 +589,13 @@
|
|
|
589
589
|
"target": "Public core",
|
|
590
590
|
"wave": 2,
|
|
591
591
|
"gapTask": "DS-015"
|
|
592
|
+
},
|
|
593
|
+
"./client/record-modal-form.tsx": {
|
|
594
|
+
"owner": "Overlays",
|
|
595
|
+
"decision": "promote",
|
|
596
|
+
"target": "Public core",
|
|
597
|
+
"wave": 2,
|
|
598
|
+
"gapTask": "DS-015"
|
|
592
599
|
}
|
|
593
600
|
},
|
|
594
601
|
"plannedComponents": []
|