@ketvietlab/design-system 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +111 -11
  2. package/dist/catalogue/catalogue.css +41 -34
  3. package/dist/catalogue/index.d.ts.map +1 -1
  4. package/dist/catalogue/index.js +413 -55
  5. package/dist/catalogue/index.js.map +1 -1
  6. package/dist/catalogue/page-surfaces.d.ts.map +1 -1
  7. package/dist/catalogue/page-surfaces.js +8 -6
  8. package/dist/catalogue/page-surfaces.js.map +1 -1
  9. package/dist/contract/index.d.ts.map +1 -1
  10. package/dist/contract/index.js +4 -0
  11. package/dist/contract/index.js.map +1 -1
  12. package/dist/foundations/tokens.css +2 -1
  13. package/dist/index.d.ts +3 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +1 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/layouts/flat.css +74 -0
  18. package/dist/layouts/grouped.css +126 -0
  19. package/dist/layouts/index.d.ts +3 -1
  20. package/dist/layouts/index.d.ts.map +1 -1
  21. package/dist/layouts/index.js +5 -2
  22. package/dist/layouts/index.js.map +1 -1
  23. package/dist/layouts/layouts.css +44 -7
  24. package/dist/layouts/shell.css +16 -2
  25. package/dist/layouts/shell.d.ts.map +1 -1
  26. package/dist/layouts/shell.js +1 -1
  27. package/dist/layouts/shell.js.map +1 -1
  28. package/dist/patterns/data-table.d.ts +50 -2
  29. package/dist/patterns/data-table.d.ts.map +1 -1
  30. package/dist/patterns/data-table.js +57 -3
  31. package/dist/patterns/data-table.js.map +1 -1
  32. package/dist/patterns/list-chrome.d.ts +80 -0
  33. package/dist/patterns/list-chrome.d.ts.map +1 -0
  34. package/dist/patterns/list-chrome.js +45 -0
  35. package/dist/patterns/list-chrome.js.map +1 -0
  36. package/dist/patterns/modal-sheet.d.ts +6 -1
  37. package/dist/patterns/modal-sheet.d.ts.map +1 -1
  38. package/dist/patterns/modal-sheet.js +5 -1
  39. package/dist/patterns/modal-sheet.js.map +1 -1
  40. package/dist/patterns/patterns.css +937 -131
  41. package/dist/patterns/record-page.d.ts +2 -2
  42. package/dist/patterns/record-page.d.ts.map +1 -1
  43. package/dist/patterns/record-page.js +1 -1
  44. package/dist/patterns/record-page.js.map +1 -1
  45. package/dist/primitives/actions.d.ts.map +1 -1
  46. package/dist/primitives/actions.js +1 -1
  47. package/dist/primitives/actions.js.map +1 -1
  48. package/dist/primitives/field.d.ts +16 -3
  49. package/dist/primitives/field.d.ts.map +1 -1
  50. package/dist/primitives/field.js +18 -5
  51. package/dist/primitives/field.js.map +1 -1
  52. package/dist/primitives/navigation.css +1 -1
  53. package/dist/primitives/primitives.css +82 -6
  54. package/dist/primitives/progress.js +1 -1
  55. package/dist/primitives/progress.js.map +1 -1
  56. package/dist/styles.css +2 -0
  57. package/package.json +2 -2
package/README.md CHANGED
@@ -7,24 +7,104 @@ KetSuite routes, translators, models, functions, sessions, or deployments.
7
7
 
8
8
  ```ts
9
9
  // File: src/ui/orders.tsx
10
- import { AppShell, Button, DataTable, FormPage, ListPage, Page, Section, Surface } from '@ketvietlab/design-system'
10
+ import {
11
+ AppShell,
12
+ Button,
13
+ DataTable,
14
+ ListChrome,
15
+ ListPage,
16
+ ModalSheet,
17
+ Page,
18
+ RecordPage,
19
+ Section,
20
+ Surface,
21
+ } from '@ketvietlab/design-system'
11
22
  ```
12
23
 
13
24
  Load `@ketvietlab/design-system/styles.css` and put `data-kv-design-system` on the
14
25
  application root. Components own their markup and `data-ui` hooks; applications
15
26
  provide business data and translated labels.
16
27
 
28
+ Compose content with unframed `Section`, `Stack` and `Grid`. `DataTable`, `Metric`
29
+ and `ContentCard` already own their surfaces; do not wrap them in `Surface` or
30
+ another card. Reserve `Surface` for unframed content that needs a working panel,
31
+ such as a form group or a standalone process tool.
32
+
33
+ Section headings have no bottom border or divider padding in any page pattern.
34
+ Separate sections with layout gaps; add a divider only when the content explicitly
35
+ requires one, never through a page-specific section override.
36
+
37
+ For titled working blocks, use `Surface title="..." body={form}` or
38
+ `DataTable title="..."`. The title sits inside the panel at 18px (`--kv-text-xl`),
39
+ with optional `actions` beside it. A titled table owns one panel, with a borderless,
40
+ transparent scrolling viewport inside; never wrap it in another `Surface`.
41
+ The title is retained in its empty state, with optional `emptyActions` for recovery.
42
+ Omitting `title` preserves the existing unheaded form surface or standalone table.
43
+
44
+ The app structure is demonstrated as four practical layouts inside `AppShell`:
45
+ collection (`ListPage`), record (`RecordPage`), flow workspace (`WorkspacePage`
46
+ with `layout="flow"`), and canvas workspace (`WorkspacePage` with
47
+ `layout="canvas"`). Compatibility adapters remain available for migrated
48
+ screens, but new catalogue examples should show one of those practical surfaces
49
+ inside the shell.
50
+
17
51
  The catalogue is isolated behind `@ketvietlab/design-system/catalogue`, so the
18
52
  production entry point does not load its specimen data or catalogue chrome.
19
53
 
20
54
  Run the component catalogue from the repository root:
21
55
 
22
56
  ```bash
57
+ # Run from: ketjs/
23
58
  npm run design:system
24
59
  ```
25
60
 
26
61
  Then open `http://127.0.0.1:4100`.
27
62
 
63
+ ### Operational demo
64
+
65
+ Run the same app on a separate port to inspect a connected sales workflow:
66
+
67
+ ```bash
68
+ # Run from: ketjs/
69
+ PORT=4000 npm run design:system
70
+ ```
71
+
72
+ Open `http://127.0.0.1:4000/demo`. The Vietnamese demo includes a flow overview,
73
+ searchable and paginated order collection, inline record forms, activity and
74
+ document tabs, a delivery board, creation sheet and state confirmation dialog.
75
+ It consumes public design-system components directly. App-owned behavior includes
76
+ selection, native form submission, validation, modal focus management and CSV export.
77
+ Synthetic orders live in the server process only and reset when it restarts;
78
+ the demo has no connection to production records, email or delivery services.
79
+
80
+ The demo uses `data-presentation="grouped"` on its design-system root: a light grey
81
+ canvas, grey page chrome and white working groups, with a grey KetSuite sidebar in
82
+ light mode.
83
+ The default light palette uses a neutral `#F6F6F7` canvas and a `#F7F5F5`
84
+ sidebar, with a `#E9E7E8` sidebar border and a pale indigo
85
+ `#EEF0FB` selected item. Header and context use the page grey; cards stay white, with
86
+ `#E2E4E8` content dividers. The dark sidebar remains optional.
87
+ Forms and titled tables own one boundary with an 18px heading inside;
88
+ table viewports have no second frame. Titled tables use 12px inset on every side,
89
+ matching the sales demo card, without extra viewport margins or an inner frame.
90
+ The record context column is a continuous
91
+ white region with unframed subsections and metric. Disclosures inside a working
92
+ group are unframed. Kanban cards retain individual boundaries because each is a
93
+ separate navigable record. Do not wrap a whole page or arbitrary sections in cards.
94
+ Grouped layouts use 8px between cards and 12px padding around each entire card,
95
+ including its heading and body. Page gutters and heading-to-body spacing are 12px.
96
+ Field and table-row density is unchanged.
97
+ Collection paging lives in `ListChrome.pager` above the table, alongside search and bulk controls.
98
+ The demo shows the visible record range and previous/next links, with no page-number strip or
99
+ separate `ListPage.footer` pagination panel. Paging, search and status filters preserve the
100
+ current query and sort order.
101
+ ListChrome is one command bar: a bounded search field on the leading side, with
102
+ filters and the result range clustered at the trailing edge. On compact widths
103
+ search and paging stay on the first row; filters wrap on the row below.
104
+ Bulk actions occupy space only when a selection exists.
105
+ The earlier `data-presentation="flat"` experiment remains opt-in; the catalogue
106
+ and other consumers retain the default presentation.
107
+
28
108
  The contract is intentionally strict:
29
109
 
30
110
  - Inter is the only UI typeface;
@@ -36,13 +116,33 @@ The contract is intentionally strict:
36
116
 
37
117
  The public entry exports actions, status and feedback objects, fields, navigation,
38
118
  tabs, progress, layout primitives, the three-region app shell, page/record layouts,
39
- the canonical list-page and form-page compositions, data tables, forms, and modal sheets. Use
40
- `ListPage` for operational collections: applications provide translated identity,
41
- URL-driven controls and result content while the pattern keeps header, controls,
42
- status, body and footer in one stable order. The primary action stays beside the
43
- title, while result status and controls share one command bar. Use `FormPage` for
44
- create and edit screens: the primary decision stays beside record identity, the
45
- business form keeps one reading column, and durable facts may occupy the optional
46
- context rail. Form fields keep labels on the left and controls on the right at
47
- every viewport; responsive layouts tighten those columns instead of changing the
48
- reading direction. Every supported state appears in the catalogue.
119
+ `ListChrome` with `BulkActions` and `PagerBar`, the canonical list and record page
120
+ compositions, data tables, forms, and modal sheets. Use `ListPage` for operational
121
+ collections: applications provide translated identity, URL-driven controls and
122
+ result content while the pattern keeps header, controls, status, body and footer in
123
+ one stable order. `DataTable` covers the common collection contract: responsive
124
+ stacking, row selection, sorting, grouping, visible columns and row links. Do not
125
+ place record action buttons inside table rows; link the row to the record instead.
126
+ Use `RecordPage` for durable subjects, and the compatibility `FormPage` only for
127
+ existing create/edit screens that have not migrated. Form fields support native
128
+ controls, custom controls, checkbox/radio groups and nested field groups. Route-owned
129
+ `ModalSheet` instances carry close/backdrop metadata and become fullscreen at the
130
+ mobile breakpoint. The catalogue includes common component states; the page preview
131
+ also covers loading, empty, error, validation and read-only states in English and Vietnamese.
132
+
133
+ `rowHref` provides one keyboard link per row, including the full row pointer target.
134
+ Linked cells are display-only. Associate `selection.form` and `bulk.form` with the
135
+ same native form to submit selected IDs and the bulk command. Selection syncing
136
+ and select-all remain application runtime responsibilities.
137
+
138
+ Forms keep labels on the left and controls on the right, including on mobile.
139
+ Help and errors align below the control. Narrow panels reduce the number of field
140
+ pairs per row without stacking labels above inputs. Native inputs support `readOnly`,
141
+ `min` and `max`; choices can be disabled individually, and invalid nested groups
142
+ open automatically. Give repeated search/sort controls unique IDs. Loading links
143
+ are disabled, and empty query rows do not occupy space.
144
+
145
+ Route-modal focus trapping, background inertness, Escape, focus restoration and
146
+ unsaved-change confirmation belong to the route runtime. ARIA metadata alone
147
+ does not implement those interactions. See the backend development guide for the
148
+ full composition and integration contract.
@@ -15,11 +15,7 @@
15
15
  display: grid;
16
16
  min-height: 100dvh;
17
17
  grid-template-columns: 15rem minmax(0, 1fr);
18
- background:
19
- linear-gradient(var(--kv-color-line) 1px, transparent 1px),
20
- linear-gradient(90deg, var(--kv-color-line) 1px, transparent 1px), var(--kv-color-canvas);
21
- background-size: 4rem 4rem;
22
- background-position: -1px -1px;
18
+ background: var(--kv-color-canvas);
23
19
  }
24
20
 
25
21
  :where([data-kv-design-system]) [data-ui="catalogue-rail"] {
@@ -63,7 +59,7 @@
63
59
  font-family: var(--kv-font-mono);
64
60
  font-size: var(--kv-text-xs);
65
61
  font-weight: 700;
66
- letter-spacing: 0.08em;
62
+ letter-spacing: 0;
67
63
  text-transform: uppercase;
68
64
  }
69
65
 
@@ -108,20 +104,9 @@
108
104
  grid-template-columns: minmax(0, 1fr) minmax(17rem, 0.45fr);
109
105
  gap: var(--kv-space-8);
110
106
  align-items: end;
111
- min-height: 19rem;
112
- margin-bottom: 5rem;
113
- padding: clamp(var(--kv-space-6), 5vw, var(--kv-space-12));
114
- border: 1px solid var(--kv-color-line-strong);
115
- border-radius: var(--kv-radius-lg);
116
- background:
117
- radial-gradient(
118
- circle at 88% 12%,
119
- color-mix(in srgb, var(--kv-color-accent) 20%, transparent),
120
- transparent 32%
121
- ),
122
- linear-gradient(142deg, var(--kv-color-surface), var(--kv-color-canvas-raised));
123
- box-shadow: var(--kv-shadow-float);
124
- overflow: hidden;
107
+ margin-bottom: var(--kv-space-8);
108
+ padding-bottom: var(--kv-space-6);
109
+ border-bottom: 1px solid var(--kv-color-line-strong);
125
110
  }
126
111
 
127
112
  :where([data-kv-design-system]) [data-ui="catalogue-hero"] [data-ui="catalogue-kicker"] {
@@ -130,13 +115,13 @@
130
115
  }
131
116
 
132
117
  :where([data-kv-design-system]) [data-ui="catalogue-title"] {
133
- max-width: 13ch;
118
+ overflow-wrap: anywhere;
134
119
  margin-bottom: var(--kv-space-4);
135
120
  font-family: var(--kv-font-display);
136
- font-size: var(--kv-text-3xl);
121
+ font-size: 1.5rem;
137
122
  font-weight: var(--kv-weight-semibold);
138
- letter-spacing: -0.035em;
139
- line-height: 0.98;
123
+ letter-spacing: 0;
124
+ line-height: var(--kv-leading-tight);
140
125
  }
141
126
 
142
127
  :where([data-kv-design-system]) [data-ui="catalogue-intro"] {
@@ -164,7 +149,7 @@
164
149
  font-family: var(--kv-font-mono);
165
150
  font-size: var(--kv-text-xs);
166
151
  font-weight: 800;
167
- letter-spacing: 0.08em;
152
+ letter-spacing: 0;
168
153
  text-transform: uppercase;
169
154
  }
170
155
 
@@ -187,7 +172,7 @@
187
172
  :where([data-kv-design-system]) [data-ui="catalogue-group"] {
188
173
  display: grid;
189
174
  gap: var(--kv-space-4);
190
- margin-top: 5rem;
175
+ margin-top: var(--kv-space-10);
191
176
  scroll-margin-top: var(--kv-space-5);
192
177
  }
193
178
 
@@ -203,7 +188,7 @@
203
188
  :where([data-kv-design-system]) [data-ui="catalogue-group-head"] h2 {
204
189
  margin-bottom: 0;
205
190
  font-family: var(--kv-font-display);
206
- font-size: 1.8rem;
191
+ font-size: var(--kv-text-xl);
207
192
  font-weight: 650;
208
193
  }
209
194
 
@@ -250,13 +235,20 @@
250
235
 
251
236
  :where([data-kv-design-system]) [data-ui="catalogue-stage"] {
252
237
  min-width: 0;
253
- padding: clamp(var(--kv-space-4), 4vw, var(--kv-space-8));
254
- background: radial-gradient(
255
- circle at 1px 1px,
256
- color-mix(in srgb, var(--kv-color-line) 74%, transparent) 1px,
257
- transparent 0
258
- );
259
- background-size: 1rem 1rem;
238
+ padding: var(--kv-space-4);
239
+ background: var(--kv-page-bg);
240
+ }
241
+
242
+ :where([data-kv-design-system]) [data-ui="catalogue-stage"] > [data-ui="app-shell"][data-mode="embedded"] {
243
+ height: min(44rem, 88dvh);
244
+ min-height: 34rem;
245
+ }
246
+
247
+ :where([data-kv-design-system])
248
+ [data-ui="catalogue-stage"]
249
+ > [data-ui="app-shell"][data-mode="embedded"]
250
+ [data-ui="app-main"] {
251
+ overflow-y: auto;
260
252
  }
261
253
 
262
254
  :where([data-kv-design-system]) [data-ui="shell-demo-sidebar"],
@@ -325,6 +317,21 @@
325
317
  align-items: stretch;
326
318
  flex-direction: column;
327
319
  }
320
+
321
+ :where([data-kv-design-system])
322
+ [data-ui="catalogue-stage"]
323
+ > [data-ui="app-shell"][data-mode="embedded"] {
324
+ height: auto;
325
+ min-height: 0;
326
+ overflow: visible;
327
+ }
328
+
329
+ :where([data-kv-design-system])
330
+ [data-ui="catalogue-stage"]
331
+ > [data-ui="app-shell"][data-mode="embedded"]
332
+ [data-ui="app-main"] {
333
+ overflow-y: visible;
334
+ }
328
335
  }
329
336
 
330
337
  @media (max-width: 30rem) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/design-system/src/catalogue/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAkBtE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAErF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,QAAQ,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;CACtC,CAAA;AAkBD,eAAO,MAAM,eAAe,EAAE,SAAS,cAAc,EA+sBpD,CAAA;AAED,eAAO,MAAM,eAAe,YAC1B,2BAA2B,EAC3B,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,EACzB,gCAAgC,EAChC,iBAAiB,CACT,CAAA;AAEV,eAAO,MAAM,aAAa,QAAO,cACgH,CAAA;AAEjJ,eAAO,MAAM,aAAa,WACjB;IAAE,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,aAAa,CAAA;CAAE,KAC9F,cA2GF,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/design-system/src/catalogue/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAqBtE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAErF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,QAAQ,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;CACtC,CAAA;AAsKD,eAAO,MAAM,eAAe,EAAE,SAAS,cAAc,EAwoCpD,CAAA;AAED,eAAO,MAAM,eAAe,YAC1B,2BAA2B,EAC3B,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,EACzB,gCAAgC,EAChC,iBAAiB,CACT,CAAA;AAEV,eAAO,MAAM,aAAa,QAAO,cACgH,CAAA;AAEjJ,eAAO,MAAM,aAAa,WACjB;IAAE,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,aAAa,CAAA;CAAE,KAC9F,cA2GF,CAAA"}