@ketvietlab/design-system 0.1.9 → 0.1.13
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 +92 -6
- package/dist/atlas/README.md +35 -0
- package/dist/atlas/adapter.schema.json +78 -0
- package/dist/atlas/profile.json +43 -0
- package/dist/atlas-cli.d.ts +3 -0
- package/dist/atlas-cli.d.ts.map +1 -0
- package/dist/atlas-cli.js +213 -0
- package/dist/atlas-cli.js.map +1 -0
- package/dist/catalogue/catalogue.css +198 -5
- package/dist/catalogue/groups.d.ts +11 -0
- package/dist/catalogue/groups.d.ts.map +1 -0
- package/dist/catalogue/groups.js +47 -0
- package/dist/catalogue/groups.js.map +1 -0
- package/dist/catalogue/index.d.ts +16 -17
- package/dist/catalogue/index.d.ts.map +1 -1
- package/dist/catalogue/index.js +39 -751
- package/dist/catalogue/index.js.map +1 -1
- package/dist/catalogue/inventory-policy.json +560 -0
- package/dist/catalogue/inventory.css +574 -0
- package/dist/catalogue/inventory.d.ts +16 -0
- package/dist/catalogue/inventory.d.ts.map +1 -0
- package/dist/catalogue/inventory.generated.d.ts +42 -0
- package/dist/catalogue/inventory.generated.d.ts.map +1 -0
- package/dist/catalogue/inventory.generated.js +3 -0
- package/dist/catalogue/inventory.generated.js.map +1 -0
- package/dist/catalogue/inventory.generated.json +9993 -0
- package/dist/catalogue/inventory.js +48 -0
- package/dist/catalogue/inventory.js.map +1 -0
- package/dist/catalogue/registry.d.ts +12 -0
- package/dist/catalogue/registry.d.ts.map +1 -0
- package/dist/catalogue/registry.js +134 -0
- package/dist/catalogue/registry.js.map +1 -0
- package/dist/catalogue/specimens.d.ts +15 -0
- package/dist/catalogue/specimens.d.ts.map +1 -0
- package/dist/catalogue/specimens.js +1186 -0
- package/dist/catalogue/specimens.js.map +1 -0
- package/dist/catalogue/styles.css +1 -0
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +64 -18
- package/dist/contract/index.js.map +1 -1
- package/dist/data-display/data-grid/index.d.ts +22 -0
- package/dist/data-display/data-grid/index.d.ts.map +1 -0
- package/dist/data-display/data-grid/index.js +15 -0
- package/dist/data-display/data-grid/index.js.map +1 -0
- package/dist/data-display/data-grid/styles.css +49 -0
- package/dist/data-display/resource-list/index.d.ts +22 -0
- package/dist/data-display/resource-list/index.d.ts.map +1 -0
- package/dist/data-display/resource-list/index.js +21 -0
- package/dist/data-display/resource-list/index.js.map +1 -0
- package/dist/data-display/resource-list/styles.css +39 -0
- package/dist/data-display/tree/index.d.ts +33 -0
- package/dist/data-display/tree/index.d.ts.map +1 -0
- package/dist/data-display/tree/index.js +21 -0
- package/dist/data-display/tree/index.js.map +1 -0
- package/dist/data-display/tree/styles.css +45 -0
- package/dist/data-operations/inline-edit/index.d.ts +19 -0
- package/dist/data-operations/inline-edit/index.d.ts.map +1 -0
- package/dist/data-operations/inline-edit/index.js +5 -0
- package/dist/data-operations/inline-edit/index.js.map +1 -0
- package/dist/data-operations/inline-edit/styles.css +34 -0
- package/dist/data-operations/list-controls/index.d.ts +67 -0
- package/dist/data-operations/list-controls/index.d.ts.map +1 -0
- package/dist/data-operations/list-controls/index.js +35 -0
- package/dist/data-operations/list-controls/index.js.map +1 -0
- package/dist/data-operations/list-controls/styles.css +82 -0
- package/dist/forms/combobox/index.d.ts +39 -0
- package/dist/forms/combobox/index.d.ts.map +1 -0
- package/dist/forms/combobox/index.js +23 -0
- package/dist/forms/combobox/index.js.map +1 -0
- package/dist/forms/combobox/styles.css +76 -0
- package/dist/forms/date-time/index.d.ts +25 -0
- package/dist/forms/date-time/index.d.ts.map +1 -0
- package/dist/forms/date-time/index.js +15 -0
- package/dist/forms/date-time/index.js.map +1 -0
- package/dist/forms/date-time/styles.css +25 -0
- package/dist/forms/relation-picker/index.d.ts +12 -0
- package/dist/forms/relation-picker/index.d.ts.map +1 -0
- package/dist/forms/relation-picker/index.js +13 -0
- package/dist/forms/relation-picker/index.js.map +1 -0
- package/dist/forms/relation-picker/styles.css +5 -0
- package/dist/forms/scalar-fields/index.d.ts +24 -0
- package/dist/forms/scalar-fields/index.d.ts.map +1 -0
- package/dist/forms/scalar-fields/index.js +23 -0
- package/dist/forms/scalar-fields/index.js.map +1 -0
- package/dist/forms/scalar-fields/styles.css +52 -0
- package/dist/forms/shared.d.ts +19 -0
- package/dist/forms/shared.d.ts.map +1 -0
- package/dist/forms/shared.js +9 -0
- package/dist/forms/shared.js.map +1 -0
- package/dist/forms/upload/index.d.ts +20 -0
- package/dist/forms/upload/index.d.ts.map +1 -0
- package/dist/forms/upload/index.js +11 -0
- package/dist/forms/upload/index.js.map +1 -0
- package/dist/forms/upload/styles.css +21 -0
- package/dist/foundations/reset.css +4 -0
- package/dist/foundations/tokens.css +31 -4
- package/dist/index.d.ts +78 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +43 -19
- package/dist/index.js.map +1 -1
- package/dist/interactions/dialog/index.d.ts +25 -0
- package/dist/interactions/dialog/index.d.ts.map +1 -0
- package/dist/interactions/dialog/index.js +10 -0
- package/dist/interactions/dialog/index.js.map +1 -0
- package/dist/interactions/dialog/styles.css +11 -0
- package/dist/interactions/menu/index.d.ts +27 -0
- package/dist/interactions/menu/index.d.ts.map +1 -0
- package/dist/interactions/menu/index.js +13 -0
- package/dist/interactions/menu/index.js.map +1 -0
- package/dist/interactions/menu/styles.css +85 -0
- package/dist/interactions/popover/index.d.ts +15 -0
- package/dist/interactions/popover/index.d.ts.map +1 -0
- package/dist/interactions/popover/index.js +4 -0
- package/dist/interactions/popover/index.js.map +1 -0
- package/dist/interactions/popover/styles.css +47 -0
- package/dist/interactions/skeleton/index.d.ts +7 -0
- package/dist/interactions/skeleton/index.d.ts.map +1 -0
- package/dist/interactions/skeleton/index.js +5 -0
- package/dist/interactions/skeleton/index.js.map +1 -0
- package/dist/interactions/skeleton/styles.css +32 -0
- package/dist/interactions/spinner/index.d.ts +7 -0
- package/dist/interactions/spinner/index.d.ts.map +1 -0
- package/dist/interactions/spinner/index.js +4 -0
- package/dist/interactions/spinner/index.js.map +1 -0
- package/dist/interactions/spinner/styles.css +38 -0
- package/dist/interactions/toast/index.d.ts +16 -0
- package/dist/interactions/toast/index.d.ts.map +1 -0
- package/dist/interactions/toast/index.js +13 -0
- package/dist/interactions/toast/index.js.map +1 -0
- package/dist/interactions/toast/styles.css +64 -0
- package/dist/interactions/tooltip/index.d.ts +9 -0
- package/dist/interactions/tooltip/index.d.ts.map +1 -0
- package/dist/interactions/tooltip/index.js +4 -0
- package/dist/interactions/tooltip/index.js.map +1 -0
- package/dist/interactions/tooltip/styles.css +65 -0
- package/dist/layouts/app-navigation/index.d.ts +63 -0
- package/dist/layouts/app-navigation/index.d.ts.map +1 -0
- package/dist/layouts/app-navigation/index.js +50 -0
- package/dist/layouts/app-navigation/index.js.map +1 -0
- package/dist/layouts/app-navigation/styles.css +331 -0
- package/dist/layouts/app-navigation.d.ts +2 -0
- package/dist/layouts/app-navigation.d.ts.map +1 -0
- package/dist/layouts/app-navigation.js +2 -0
- package/dist/layouts/app-navigation.js.map +1 -0
- package/dist/layouts/flat/styles.css +74 -0
- package/dist/layouts/flat.css +1 -74
- package/dist/layouts/grouped/styles.css +131 -0
- package/dist/layouts/grouped.css +1 -126
- package/dist/layouts/index.d.ts +1 -69
- package/dist/layouts/index.d.ts.map +1 -1
- package/dist/layouts/index.js +1 -68
- package/dist/layouts/index.js.map +1 -1
- package/dist/layouts/layout/index.d.ts +70 -0
- package/dist/layouts/layout/index.d.ts.map +1 -0
- package/dist/layouts/layout/index.js +71 -0
- package/dist/layouts/layout/index.js.map +1 -0
- package/dist/layouts/layout/styles.css +369 -0
- package/dist/layouts/layouts.css +1 -369
- package/dist/layouts/shell/index.d.ts +27 -0
- package/dist/layouts/shell/index.d.ts.map +1 -0
- package/dist/layouts/shell/index.js +24 -0
- package/dist/layouts/shell/index.js.map +1 -0
- package/dist/layouts/shell/styles.css +168 -0
- package/dist/layouts/shell.css +1 -168
- package/dist/layouts/shell.d.ts +1 -26
- package/dist/layouts/shell.d.ts.map +1 -1
- package/dist/layouts/shell.js +1 -23
- package/dist/layouts/shell.js.map +1 -1
- package/dist/patterns/board-page/index.d.ts +16 -0
- package/dist/patterns/board-page/index.d.ts.map +1 -0
- package/dist/patterns/board-page/index.js +30 -0
- package/dist/patterns/board-page/index.js.map +1 -0
- package/dist/patterns/board-page/styles.css +164 -0
- package/dist/patterns/board-page.d.ts +1 -13
- package/dist/patterns/board-page.d.ts.map +1 -1
- package/dist/patterns/board-page.js +1 -27
- package/dist/patterns/board-page.js.map +1 -1
- package/dist/patterns/dashboard-page/index.d.ts +15 -0
- package/dist/patterns/dashboard-page/index.d.ts.map +1 -0
- package/dist/patterns/dashboard-page/index.js +27 -0
- package/dist/patterns/dashboard-page/index.js.map +1 -0
- package/dist/patterns/dashboard-page/styles.css +169 -0
- package/dist/patterns/dashboard-page.d.ts +1 -12
- package/dist/patterns/dashboard-page.d.ts.map +1 -1
- package/dist/patterns/dashboard-page.js +1 -24
- package/dist/patterns/dashboard-page.js.map +1 -1
- package/dist/patterns/data-table/index.d.ts +74 -0
- package/dist/patterns/data-table/index.d.ts.map +1 -0
- package/dist/patterns/data-table/index.js +60 -0
- package/dist/patterns/data-table/index.js.map +1 -0
- package/dist/patterns/data-table/styles.css +269 -0
- package/dist/patterns/data-table.d.ts +1 -73
- package/dist/patterns/data-table.d.ts.map +1 -1
- package/dist/patterns/data-table.js +1 -59
- package/dist/patterns/data-table.js.map +1 -1
- package/dist/patterns/form-page/index.d.ts +8 -0
- package/dist/patterns/form-page/index.d.ts.map +1 -0
- package/dist/patterns/form-page/index.js +22 -0
- package/dist/patterns/form-page/index.js.map +1 -0
- package/dist/patterns/form-page/styles.css +237 -0
- package/dist/patterns/form-page.d.ts +1 -7
- package/dist/patterns/form-page.d.ts.map +1 -1
- package/dist/patterns/form-page.js +1 -21
- package/dist/patterns/form-page.js.map +1 -1
- package/dist/patterns/list-chrome/index.d.ts +80 -0
- package/dist/patterns/list-chrome/index.d.ts.map +1 -0
- package/dist/patterns/list-chrome/index.js +45 -0
- package/dist/patterns/list-chrome/index.js.map +1 -0
- package/dist/patterns/list-chrome/styles.css +245 -0
- package/dist/patterns/list-chrome.d.ts +1 -79
- package/dist/patterns/list-chrome.d.ts.map +1 -1
- package/dist/patterns/list-chrome.js +1 -44
- package/dist/patterns/list-chrome.js.map +1 -1
- package/dist/patterns/list-page/index.d.ts +31 -0
- package/dist/patterns/list-page/index.d.ts.map +1 -0
- package/dist/patterns/list-page/index.js +41 -0
- package/dist/patterns/list-page/index.js.map +1 -0
- package/dist/patterns/list-page/responsive.css +140 -0
- package/dist/patterns/list-page/styles.css +228 -0
- package/dist/patterns/list-page.d.ts +1 -30
- package/dist/patterns/list-page.d.ts.map +1 -1
- package/dist/patterns/list-page.js +1 -40
- package/dist/patterns/list-page.js.map +1 -1
- package/dist/patterns/modal-sheet/index.d.ts +16 -0
- package/dist/patterns/modal-sheet/index.d.ts.map +1 -0
- package/dist/patterns/modal-sheet/index.js +15 -0
- package/dist/patterns/modal-sheet/index.js.map +1 -0
- package/dist/patterns/modal-sheet/styles.css +219 -0
- package/dist/patterns/modal-sheet.d.ts +1 -15
- package/dist/patterns/modal-sheet.d.ts.map +1 -1
- package/dist/patterns/modal-sheet.js +1 -14
- package/dist/patterns/modal-sheet.js.map +1 -1
- package/dist/patterns/page-shell/index.d.ts +24 -0
- package/dist/patterns/page-shell/index.d.ts.map +1 -0
- package/dist/patterns/page-shell/index.js +11 -0
- package/dist/patterns/page-shell/index.js.map +1 -0
- package/dist/patterns/page-shell.d.ts +1 -23
- package/dist/patterns/page-shell.d.ts.map +1 -1
- package/dist/patterns/page-shell.js +1 -10
- package/dist/patterns/page-shell.js.map +1 -1
- package/dist/patterns/patterns.css +12 -2247
- package/dist/patterns/pipeline/index.d.ts +29 -0
- package/dist/patterns/pipeline/index.d.ts.map +1 -0
- package/dist/patterns/pipeline/index.js +26 -0
- package/dist/patterns/pipeline/index.js.map +1 -0
- package/dist/patterns/pipeline/styles.css +168 -0
- package/dist/patterns/pipeline.d.ts +1 -28
- package/dist/patterns/pipeline.d.ts.map +1 -1
- package/dist/patterns/pipeline.js +1 -25
- package/dist/patterns/pipeline.js.map +1 -1
- package/dist/patterns/record-form/index.d.ts +18 -0
- package/dist/patterns/record-form/index.d.ts.map +1 -0
- package/dist/patterns/record-form/index.js +14 -0
- package/dist/patterns/record-form/index.js.map +1 -0
- package/dist/patterns/record-form/styles.css +175 -0
- package/dist/patterns/record-form.d.ts +1 -17
- package/dist/patterns/record-form.d.ts.map +1 -1
- package/dist/patterns/record-form.js +1 -13
- package/dist/patterns/record-form.js.map +1 -1
- package/dist/patterns/record-page/index.d.ts +31 -0
- package/dist/patterns/record-page/index.d.ts.map +1 -0
- package/dist/patterns/record-page/index.js +29 -0
- package/dist/patterns/record-page/index.js.map +1 -0
- package/dist/patterns/record-page/styles.css +228 -0
- package/dist/patterns/record-page.d.ts +1 -30
- package/dist/patterns/record-page.d.ts.map +1 -1
- package/dist/patterns/record-page.js +1 -28
- package/dist/patterns/record-page.js.map +1 -1
- package/dist/patterns/workspace-page/index.d.ts +23 -0
- package/dist/patterns/workspace-page/index.d.ts.map +1 -0
- package/dist/patterns/workspace-page/index.js +26 -0
- package/dist/patterns/workspace-page/index.js.map +1 -0
- package/dist/patterns/workspace-page/styles.css +9 -0
- package/dist/patterns/workspace-page.d.ts +1 -22
- package/dist/patterns/workspace-page.d.ts.map +1 -1
- package/dist/patterns/workspace-page.js +1 -25
- package/dist/patterns/workspace-page.js.map +1 -1
- package/dist/primitives/actions/index.d.ts +36 -0
- package/dist/primitives/actions/index.d.ts.map +1 -0
- package/dist/primitives/actions/index.js +10 -0
- package/dist/primitives/actions/index.js.map +1 -0
- package/dist/primitives/actions/styles.css +149 -0
- package/dist/primitives/actions.d.ts +1 -35
- package/dist/primitives/actions.d.ts.map +1 -1
- package/dist/primitives/actions.js +1 -9
- package/dist/primitives/actions.js.map +1 -1
- package/dist/primitives/feedback/index.d.ts +19 -0
- package/dist/primitives/feedback/index.d.ts.map +1 -0
- package/dist/primitives/feedback/index.js +21 -0
- package/dist/primitives/feedback/index.js.map +1 -0
- package/dist/primitives/feedback/styles.css +117 -0
- package/dist/primitives/feedback.d.ts +1 -18
- package/dist/primitives/feedback.d.ts.map +1 -1
- package/dist/primitives/feedback.js +1 -22
- package/dist/primitives/feedback.js.map +1 -1
- package/dist/primitives/field/index.d.ts +35 -0
- package/dist/primitives/field/index.d.ts.map +1 -0
- package/dist/primitives/field/index.js +34 -0
- package/dist/primitives/field/index.js.map +1 -0
- package/dist/primitives/field/native-control.d.ts +4 -0
- package/dist/primitives/field/native-control.d.ts.map +1 -0
- package/dist/primitives/field/native-control.js +12 -0
- package/dist/primitives/field/native-control.js.map +1 -0
- package/dist/primitives/field/styles.css +160 -0
- package/dist/primitives/field.d.ts +1 -34
- package/dist/primitives/field.d.ts.map +1 -1
- package/dist/primitives/field.js +1 -41
- package/dist/primitives/field.js.map +1 -1
- package/dist/primitives/navigation/index.d.ts +36 -0
- package/dist/primitives/navigation/index.d.ts.map +1 -0
- package/dist/primitives/navigation/index.js +19 -0
- package/dist/primitives/navigation/index.js.map +1 -0
- package/dist/primitives/{navigation.css → navigation/styles.css} +51 -0
- package/dist/primitives/navigation.d.ts +1 -25
- package/dist/primitives/navigation.d.ts.map +1 -1
- package/dist/primitives/navigation.js +1 -15
- package/dist/primitives/navigation.js.map +1 -1
- package/dist/primitives/primitives.css +4 -570
- package/dist/primitives/progress/index.d.ts +10 -0
- package/dist/primitives/progress/index.d.ts.map +1 -0
- package/dist/primitives/progress/index.js +13 -0
- package/dist/primitives/progress/index.js.map +1 -0
- package/dist/primitives/progress.d.ts +1 -9
- package/dist/primitives/progress.d.ts.map +1 -1
- package/dist/primitives/progress.js +1 -12
- package/dist/primitives/progress.js.map +1 -1
- package/dist/primitives/status/index.d.ts +27 -0
- package/dist/primitives/status/index.d.ts.map +1 -0
- package/dist/primitives/status/index.js +16 -0
- package/dist/primitives/status/index.js.map +1 -0
- package/dist/primitives/status/styles.css +114 -0
- package/dist/primitives/status.d.ts +1 -26
- package/dist/primitives/status.d.ts.map +1 -1
- package/dist/primitives/status.js +1 -15
- package/dist/primitives/status.js.map +1 -1
- package/dist/record/activity/index.d.ts +26 -0
- package/dist/record/activity/index.d.ts.map +1 -0
- package/dist/record/activity/index.js +33 -0
- package/dist/record/activity/index.js.map +1 -0
- package/dist/record/activity/styles.css +38 -0
- package/dist/record/composition/index.d.ts +33 -0
- package/dist/record/composition/index.d.ts.map +1 -0
- package/dist/record/composition/index.js +10 -0
- package/dist/record/composition/index.js.map +1 -0
- package/dist/record/composition/styles.css +30 -0
- package/dist/record/display/index.d.ts +37 -0
- package/dist/record/display/index.d.ts.map +1 -0
- package/dist/record/display/index.js +23 -0
- package/dist/record/display/index.js.map +1 -0
- package/dist/record/display/styles.css +63 -0
- package/dist/record/formatted-values/index.d.ts +19 -0
- package/dist/record/formatted-values/index.d.ts.map +1 -0
- package/dist/record/formatted-values/index.js +21 -0
- package/dist/record/formatted-values/index.js.map +1 -0
- package/dist/record/formatted-values/styles.css +8 -0
- package/dist/record/media/index.d.ts +31 -0
- package/dist/record/media/index.d.ts.map +1 -0
- package/dist/record/media/index.js +19 -0
- package/dist/record/media/index.js.map +1 -0
- package/dist/record/media/styles.css +38 -0
- package/dist/runtime/auto.d.ts +2 -0
- package/dist/runtime/auto.d.ts.map +1 -0
- package/dist/runtime/auto.js +5 -0
- package/dist/runtime/auto.js.map +1 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +369 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/styles.css +47 -8
- package/package.json +9 -2
- /package/dist/primitives/{progress.css → progress/styles.css} +0 -0
|
@@ -0,0 +1,1186 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@ketvietlab/ketjs-view/jsx-runtime";
|
|
2
|
+
import { ActionGroup, Button, IconButton, LinkButton } from '../primitives/actions.js';
|
|
3
|
+
import { Avatar, Badge, Code, CountBadge, Tag } from '../primitives/status.js';
|
|
4
|
+
import { EmptyState, LoadingState, Notice } from '../primitives/feedback.js';
|
|
5
|
+
import { Field } from '../primitives/field.js';
|
|
6
|
+
import { Breadcrumbs, NavList, Tabs } from '../primitives/navigation.js';
|
|
7
|
+
import { Progress } from '../primitives/progress.js';
|
|
8
|
+
import { ContentCard, Disclosure, Grid, Inline, Metric, Section, Stack, Surface } from '../layouts/index.js';
|
|
9
|
+
import { AppShell, Page } from '../layouts/shell.js';
|
|
10
|
+
import { AppNavigation } from '../layouts/app-navigation.js';
|
|
11
|
+
import { DataTable } from '../patterns/data-table.js';
|
|
12
|
+
import { ListChrome } from '../patterns/list-chrome.js';
|
|
13
|
+
import { BoardPage } from '../patterns/board-page.js';
|
|
14
|
+
import { DashboardPage } from '../patterns/dashboard-page.js';
|
|
15
|
+
import { ListPage } from '../patterns/list-page.js';
|
|
16
|
+
import { FormPage } from '../patterns/form-page.js';
|
|
17
|
+
import { RecordPage } from '../patterns/record-page.js';
|
|
18
|
+
import { WorkspacePage } from '../patterns/workspace-page.js';
|
|
19
|
+
import { ModalSheet } from '../patterns/modal-sheet.js';
|
|
20
|
+
import { Pipeline } from '../patterns/pipeline.js';
|
|
21
|
+
import { RecordForm } from '../patterns/record-form.js';
|
|
22
|
+
import { ActionMenu, Menu } from '../interactions/menu/index.js';
|
|
23
|
+
import { Popover } from '../interactions/popover/index.js';
|
|
24
|
+
import { Tooltip } from '../interactions/tooltip/index.js';
|
|
25
|
+
import { ConfirmDialog, Dialog } from '../interactions/dialog/index.js';
|
|
26
|
+
import { ToastRegion } from '../interactions/toast/index.js';
|
|
27
|
+
import { Spinner } from '../interactions/spinner/index.js';
|
|
28
|
+
import { Skeleton } from '../interactions/skeleton/index.js';
|
|
29
|
+
import { Checkbox, CheckboxGroup, MoneyField, NumberField, RadioGroup, SearchField, Select, Switch, TextArea, TextField, } from '../forms/scalar-fields/index.js';
|
|
30
|
+
import { Combobox, MultiCombobox, TagPicker } from '../forms/combobox/index.js';
|
|
31
|
+
import { DatePicker, DateRangePicker, DateTimePicker, TimePicker } from '../forms/date-time/index.js';
|
|
32
|
+
import { DropZone, FileUpload } from '../forms/upload/index.js';
|
|
33
|
+
import { RelationPicker } from '../forms/relation-picker/index.js';
|
|
34
|
+
import { AppliedFilters, FilterBar, SavedViews, SearchBar, SortMenu, ViewSettings, } from '../data-operations/list-controls/index.js';
|
|
35
|
+
import { InlineEdit } from '../data-operations/inline-edit/index.js';
|
|
36
|
+
import { ResourceList } from '../data-display/resource-list/index.js';
|
|
37
|
+
import { DataGrid } from '../data-display/data-grid/index.js';
|
|
38
|
+
import { Tree, TreeGrid } from '../data-display/tree/index.js';
|
|
39
|
+
import { AvatarGroup, DescriptionList, Person, Status } from '../record/display/index.js';
|
|
40
|
+
import { FormattedDate, FormattedMoney, FormattedNumber } from '../record/formatted-values/index.js';
|
|
41
|
+
import { RecordActions, RecordRail, RecordSummary } from '../record/composition/index.js';
|
|
42
|
+
import { ActivityTimeline, AuditLog } from '../record/activity/index.js';
|
|
43
|
+
import { Attachments, MediaGallery } from '../record/media/index.js';
|
|
44
|
+
const orders = [
|
|
45
|
+
{ id: 'SO-1042', customer: 'Công ty Ánh Dương', total: '18.450.000 ₫', state: 'Ready' },
|
|
46
|
+
{ id: 'SO-1041', customer: 'Khách sạn Mùa Hạ', total: '6.800.000 ₫', state: 'Review' },
|
|
47
|
+
{ id: 'SO-1039', customer: 'Nguyễn Minh Châu', total: '2.150.000 ₫', state: 'Blocked' },
|
|
48
|
+
];
|
|
49
|
+
const toneOf = (state) => state === 'Ready' ? 'positive' : state === 'Review' ? 'warning' : 'danger';
|
|
50
|
+
const demoNavItems = (active) => [
|
|
51
|
+
{ label: 'Collection', href: '#app-shell', leading: '≡', active: active === 'collection', count: 148 },
|
|
52
|
+
{ label: 'Record', href: '#record-page', leading: '◇', active: active === 'record' },
|
|
53
|
+
{ label: 'Flow', href: '#workspace-flow', leading: '▦', active: active === 'flow', count: 7 },
|
|
54
|
+
{ label: 'Canvas', href: '#workspace-canvas', leading: '□', active: active === 'canvas' },
|
|
55
|
+
];
|
|
56
|
+
const DemoSidebar = (props) => (_jsx(AppNavigation, { id: `demo-navigation-${props.active}`, label: "K\u00E9tSuite workspace", identity: "K\u00E9tSuite", context: "Operations workspace", menuLabel: "Workspace menu", groups: [
|
|
57
|
+
{
|
|
58
|
+
id: `demo-primary-${props.active}`,
|
|
59
|
+
label: 'Workspace',
|
|
60
|
+
items: demoNavItems(props.active).map((item) => ({
|
|
61
|
+
...item,
|
|
62
|
+
id: `${props.active}-${item.href.slice(1)}`,
|
|
63
|
+
})),
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: `demo-manage-${props.active}`,
|
|
67
|
+
label: 'Manage',
|
|
68
|
+
items: [
|
|
69
|
+
{ id: `${props.active}-settings`, label: 'Settings', href: '#app-navigation', leading: '⚙' },
|
|
70
|
+
{
|
|
71
|
+
id: `${props.active}-reports`,
|
|
72
|
+
label: 'Reports',
|
|
73
|
+
leading: '▤',
|
|
74
|
+
children: [
|
|
75
|
+
{ id: `${props.active}-sales-report`, label: 'Sales', href: '#data-table' },
|
|
76
|
+
{ id: `${props.active}-stock-report`, label: 'Inventory', href: '#metric' },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
], footer: "Signed in \u00B7 Duy Kieu" }));
|
|
82
|
+
const DemoRail = (props) => (_jsxs("div", { "data-ui": "shell-demo-rail", children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "Context" }), _jsx("strong", { children: props.title }), _jsx("p", { children: props.detail }), props.progress !== undefined && _jsx(Progress, { label: props.title, value: props.progress }), props.items !== undefined && _jsx(Stack, { gap: "compact", items: props.items })] }));
|
|
83
|
+
const DemoShell = (props) => (_jsx(AppShell, { mode: "embedded", sidebar: _jsx(DemoSidebar, { active: props.active }), main: props.main, rightRail: props.railTitle !== undefined ? (_jsx(DemoRail, { title: props.railTitle, detail: props.railDetail ?? '', progress: props.railProgress, items: props.railItems })) : undefined }));
|
|
84
|
+
const OrdersTable = (props = {}) => (_jsx(DataTable, { title: props.title, rows: props.grouped ? [] : orders, id: (row) => row.id, rowHref: (row) => `#${row.id}`, responsive: "stack", selection: { selectedIds: ['SO-1042'] }, groups: props.grouped
|
|
85
|
+
? [
|
|
86
|
+
{
|
|
87
|
+
id: 'ready',
|
|
88
|
+
label: 'Ready to invoice',
|
|
89
|
+
count: 2,
|
|
90
|
+
rows: orders.slice(0, 2),
|
|
91
|
+
pager: { label: '2 shown in Ready', nextHref: '#data-table' },
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: 'blocked',
|
|
95
|
+
label: 'Needs decision',
|
|
96
|
+
count: 1,
|
|
97
|
+
rows: orders.slice(2),
|
|
98
|
+
},
|
|
99
|
+
]
|
|
100
|
+
: undefined, columns: [
|
|
101
|
+
{
|
|
102
|
+
key: 'id',
|
|
103
|
+
label: 'Order',
|
|
104
|
+
cell: (row) => row.id,
|
|
105
|
+
priority: 'primary',
|
|
106
|
+
kind: 'identifier',
|
|
107
|
+
sort: { href: '#data-table', direction: 'descending' },
|
|
108
|
+
},
|
|
109
|
+
{ key: 'customer', label: 'Customer', cell: (row) => row.customer },
|
|
110
|
+
{ key: 'total', label: 'Total', cell: (row) => row.total, align: 'end', kind: 'currency' },
|
|
111
|
+
{
|
|
112
|
+
key: 'state',
|
|
113
|
+
label: 'State',
|
|
114
|
+
cell: (row) => _jsx(Badge, { label: row.state, tone: toneOf(row.state) }),
|
|
115
|
+
kind: 'status',
|
|
116
|
+
},
|
|
117
|
+
] }));
|
|
118
|
+
const ListDemoChrome = (props) => (_jsx(ListChrome, { search: {
|
|
119
|
+
id: `${props.id}-query`,
|
|
120
|
+
action: `#${props.id}`,
|
|
121
|
+
value: props.id === 'list-page' ? 'Mùa Hạ' : '',
|
|
122
|
+
placeholder: 'Search records',
|
|
123
|
+
hidden: { view: 'table' },
|
|
124
|
+
}, facets: [
|
|
125
|
+
{ id: 'all', label: 'All', href: `#${props.id}`, active: true, count: 148 },
|
|
126
|
+
{ id: 'ready', label: 'Ready', href: `#${props.id}`, count: 91 },
|
|
127
|
+
{ id: 'review', label: 'Review', href: `#${props.id}`, count: 7 },
|
|
128
|
+
], views: [
|
|
129
|
+
{ id: 'table', label: 'Table', href: `#${props.id}`, active: true },
|
|
130
|
+
{ id: 'kanban', label: 'Kanban', href: `#${props.id}` },
|
|
131
|
+
], sort: {
|
|
132
|
+
id: `${props.id}-sort`,
|
|
133
|
+
action: `#${props.id}`,
|
|
134
|
+
choices: [
|
|
135
|
+
{ value: 'date-desc', label: 'Newest first', selected: true },
|
|
136
|
+
{ value: 'total-desc', label: 'Largest total' },
|
|
137
|
+
],
|
|
138
|
+
}, bulk: {
|
|
139
|
+
selectedCount: props.selected ?? 1,
|
|
140
|
+
summary: `${props.selected ?? 1} selected`,
|
|
141
|
+
clearHref: `#${props.id}`,
|
|
142
|
+
actions: [{ id: 'approve', label: 'Approve', name: 'intent', value: 'approve', variant: 'primary' }],
|
|
143
|
+
}, pager: {
|
|
144
|
+
summary: 'Showing 1-3 of 148',
|
|
145
|
+
previousHref: null,
|
|
146
|
+
nextHref: `#${props.id}`,
|
|
147
|
+
pages: [
|
|
148
|
+
{ label: '1', href: `#${props.id}`, active: true },
|
|
149
|
+
{ label: '2', href: `#${props.id}` },
|
|
150
|
+
],
|
|
151
|
+
} }));
|
|
152
|
+
export const componentGroups = [
|
|
153
|
+
{
|
|
154
|
+
id: 'actions',
|
|
155
|
+
name: 'Actions',
|
|
156
|
+
description: 'Business hierarchy expressed independently from colour.',
|
|
157
|
+
examples: [
|
|
158
|
+
{
|
|
159
|
+
id: 'button',
|
|
160
|
+
name: 'Button',
|
|
161
|
+
description: 'Primary, secondary, tertiary, destructive, loading and disabled states.',
|
|
162
|
+
render: () => (_jsx(ActionGroup, { label: "Button variants", actions: [
|
|
163
|
+
_jsx(Button, { label: "Create order", variant: "primary", leading: "+" }),
|
|
164
|
+
_jsx(Button, { label: "Save draft", variant: "secondary" }),
|
|
165
|
+
_jsx(Button, { label: "More details", variant: "tertiary" }),
|
|
166
|
+
_jsx(Button, { label: "Terminate", variant: "destructive" }),
|
|
167
|
+
_jsx(Button, { label: "Saving", loading: true }),
|
|
168
|
+
_jsx(Button, { label: "Unavailable", disabled: true }),
|
|
169
|
+
_jsx(LinkButton, { label: "Opening record", href: "#record-page", loading: true }),
|
|
170
|
+
_jsx(IconButton, { label: "Toggle theme", icon: "\u263E" }),
|
|
171
|
+
] })),
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: 'action-sizes',
|
|
175
|
+
name: 'Action sizes',
|
|
176
|
+
description: 'Density changes target size without changing hierarchy.',
|
|
177
|
+
render: () => (_jsx(ActionGroup, { label: "Action sizes", actions: [
|
|
178
|
+
_jsx(Button, { label: "Compact", size: "compact" }),
|
|
179
|
+
_jsx(Button, { label: "Default" }),
|
|
180
|
+
_jsx(Button, { label: "Prominent decision", size: "prominent", variant: "primary" }),
|
|
181
|
+
_jsx(IconButton, { label: "Compact theme toggle", icon: "\u263E", size: "compact" }),
|
|
182
|
+
_jsx(IconButton, { label: "Prominent theme toggle", icon: "\u263E", size: "prominent" }),
|
|
183
|
+
_jsx(LinkButton, { label: "Open record", href: "#data-table", variant: "tertiary", leading: "\u2197" }),
|
|
184
|
+
] })),
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
id: 'status',
|
|
190
|
+
name: 'Status & identity',
|
|
191
|
+
description: 'Compact objects for operational scanning.',
|
|
192
|
+
examples: [
|
|
193
|
+
{
|
|
194
|
+
id: 'badges',
|
|
195
|
+
name: 'Badge and tag',
|
|
196
|
+
description: 'Tones carry meaning; tags represent categories and active filters.',
|
|
197
|
+
render: () => (_jsx(Inline, { items: [
|
|
198
|
+
_jsx(Badge, { label: "Neutral" }),
|
|
199
|
+
_jsx(Badge, { label: "Synchronized", tone: "info" }),
|
|
200
|
+
_jsx(Badge, { label: "Ready", tone: "positive" }),
|
|
201
|
+
_jsx(Badge, { label: "Needs review", tone: "warning" }),
|
|
202
|
+
_jsx(Badge, { label: "Failed", tone: "danger" }),
|
|
203
|
+
_jsx(Tag, { label: "H\u00E0 N\u1ED9i", removeHref: "#status", removeLabel: "Remove H\u00E0 N\u1ED9i filter" }),
|
|
204
|
+
_jsx(CountBadge, { count: 12, label: "12 pending items" }),
|
|
205
|
+
] })),
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: 'identity',
|
|
209
|
+
name: 'Avatar and code',
|
|
210
|
+
description: 'Stable fallbacks for people and exact machine-readable values.',
|
|
211
|
+
render: () => (_jsx(Inline, { items: [
|
|
212
|
+
_jsx(Avatar, { name: "Nguy\u1EC5n Minh Ch\u00E2u", size: "small" }),
|
|
213
|
+
_jsx(Avatar, { name: "Nguy\u1EC5n Minh Ch\u00E2u" }),
|
|
214
|
+
_jsx(Avatar, { name: "Nguy\u1EC5n Minh Ch\u00E2u", size: "large" }),
|
|
215
|
+
_jsx(Code, { value: "tenant-vn-hn-0042", context: "tenant" }),
|
|
216
|
+
] })),
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
id: 'feedback',
|
|
222
|
+
name: 'Feedback',
|
|
223
|
+
description: 'Complete operational states, including the paths nobody screenshots first.',
|
|
224
|
+
examples: [
|
|
225
|
+
{
|
|
226
|
+
id: 'notice',
|
|
227
|
+
name: 'Notice',
|
|
228
|
+
description: 'Status, warning and recovery information with an optional action.',
|
|
229
|
+
render: () => (_jsx(Stack, { gap: "compact", items: [
|
|
230
|
+
_jsx(Notice, { title: "Sync complete", message: "42 records are ready for review.", tone: "positive" }),
|
|
231
|
+
_jsx(Notice, { title: "Release drift", message: "Two tenants are one release behind.", tone: "warning" }),
|
|
232
|
+
_jsx(Notice, { title: "Connection failed", message: "The provider rejected the stored credential. Rotate it before retrying.", tone: "danger", actions: _jsx(Button, { label: "Rotate", size: "compact" }) }),
|
|
233
|
+
] })),
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
id: 'empty-loading',
|
|
237
|
+
name: 'Empty and loading',
|
|
238
|
+
description: 'Explicit state preserves layout and gives the reader a next step.',
|
|
239
|
+
render: () => (_jsx(Grid, { columns: 2, items: [
|
|
240
|
+
_jsx(Surface, { padding: "none", body: _jsx(EmptyState, { title: "No saved views", message: "Save the current filters to reuse them later.", actions: _jsx(Button, { label: "Save current view", size: "compact" }) }) }),
|
|
241
|
+
_jsx(Surface, { padding: "none", body: _jsx(LoadingState, { label: "Loading order history", lines: 3 }) }),
|
|
242
|
+
] })),
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
id: 'fields',
|
|
248
|
+
name: 'Fields',
|
|
249
|
+
description: 'Native controls with one label, help and error contract.',
|
|
250
|
+
examples: [
|
|
251
|
+
{
|
|
252
|
+
id: 'field',
|
|
253
|
+
name: 'Field',
|
|
254
|
+
description: 'Text, select, checkbox and error states without application-owned markup.',
|
|
255
|
+
render: () => (_jsx(Surface, { body: _jsx(Grid, { columns: 2, items: [
|
|
256
|
+
_jsx(Field, { id: "company-name", name: "company", label: "Company name", value: "K\u00E9t Vi\u1EC7t", required: true }),
|
|
257
|
+
_jsx(Field, { id: "deployment", name: "deployment", label: "Deployment", type: "select", value: "commerce", options: [
|
|
258
|
+
{ value: 'commerce', label: 'Commerce' },
|
|
259
|
+
{ value: 'cosmetic', label: 'Cosmetic' },
|
|
260
|
+
{ value: 'hospitality', label: 'Hospitality' },
|
|
261
|
+
], help: "A tenant belongs to exactly one deployment." }),
|
|
262
|
+
_jsx(Field, { id: "database-key", name: "databaseKey", label: "Database key", value: "Invalid Key", error: "Use lowercase letters, numbers and hyphens only." }),
|
|
263
|
+
_jsx(Field, { id: "active", name: "active", label: "Active for new orders", type: "checkbox", value: true, help: "New orders can be assigned to this company." }),
|
|
264
|
+
] }) })),
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
id: 'field-states',
|
|
270
|
+
name: 'Field states',
|
|
271
|
+
description: 'Native input types, validation, read-only values and nested groups.',
|
|
272
|
+
examples: [
|
|
273
|
+
{
|
|
274
|
+
id: 'advanced-fields',
|
|
275
|
+
name: 'Operational fields',
|
|
276
|
+
description: 'Numeric constraints, dates, options and nested validation use the same field contract.',
|
|
277
|
+
render: () => (_jsx(Surface, { title: "Settings", body: _jsx(RecordForm, { action: "#advanced-fields", submitLabel: "Save settings", fields: [
|
|
278
|
+
{
|
|
279
|
+
id: 'settings-reference',
|
|
280
|
+
name: 'reference',
|
|
281
|
+
label: 'Reference',
|
|
282
|
+
value: 'CUS-0042',
|
|
283
|
+
readOnly: true,
|
|
284
|
+
help: 'Assigned when the account was created.',
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
id: 'settings-locked',
|
|
288
|
+
name: 'locked',
|
|
289
|
+
label: 'External reference',
|
|
290
|
+
value: 'Pending verification',
|
|
291
|
+
disabled: true,
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
id: 'settings-limit',
|
|
295
|
+
name: 'limit',
|
|
296
|
+
label: 'Credit limit',
|
|
297
|
+
type: 'decimal',
|
|
298
|
+
value: 80000000,
|
|
299
|
+
min: 0,
|
|
300
|
+
step: '1000',
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
id: 'settings-date',
|
|
304
|
+
name: 'date',
|
|
305
|
+
label: 'Effective date',
|
|
306
|
+
type: 'date',
|
|
307
|
+
value: '2026-09-08',
|
|
308
|
+
},
|
|
309
|
+
{ id: 'settings-time', name: 'time', label: 'Delivery time', type: 'time', value: '09:00' },
|
|
310
|
+
{
|
|
311
|
+
id: 'settings-color',
|
|
312
|
+
name: 'color',
|
|
313
|
+
label: 'Calendar colour',
|
|
314
|
+
type: 'color',
|
|
315
|
+
value: '#5167c4',
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
id: 'settings-billing',
|
|
319
|
+
name: 'billing',
|
|
320
|
+
label: 'Billing frequency',
|
|
321
|
+
type: 'radio',
|
|
322
|
+
value: 'monthly',
|
|
323
|
+
required: true,
|
|
324
|
+
options: [
|
|
325
|
+
{ value: 'monthly', label: 'Monthly' },
|
|
326
|
+
{ value: 'quarterly', label: 'Quarterly' },
|
|
327
|
+
],
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
id: 'settings-channels',
|
|
331
|
+
name: 'channels',
|
|
332
|
+
label: 'Notifications',
|
|
333
|
+
type: 'checkbox-group',
|
|
334
|
+
options: [
|
|
335
|
+
{ value: 'email', label: 'Email', checked: true },
|
|
336
|
+
{ value: 'sms', label: 'SMS' },
|
|
337
|
+
],
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
id: 'settings-address',
|
|
341
|
+
name: 'address',
|
|
342
|
+
label: 'Delivery address',
|
|
343
|
+
error: 'Check the delivery address.',
|
|
344
|
+
fields: [
|
|
345
|
+
{
|
|
346
|
+
id: 'settings-street',
|
|
347
|
+
name: 'street',
|
|
348
|
+
label: 'Street',
|
|
349
|
+
value: '',
|
|
350
|
+
required: true,
|
|
351
|
+
error: 'Enter a street address.',
|
|
352
|
+
span: 'full',
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
id: 'settings-city',
|
|
356
|
+
name: 'city',
|
|
357
|
+
label: 'City',
|
|
358
|
+
value: 'Hồ Chí Minh',
|
|
359
|
+
autocomplete: 'address-level2',
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
},
|
|
363
|
+
] }) })),
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
id: 'layouts',
|
|
369
|
+
name: 'Layouts',
|
|
370
|
+
description: 'Quiet hierarchy for dense application screens.',
|
|
371
|
+
examples: [
|
|
372
|
+
{
|
|
373
|
+
id: 'surface-section',
|
|
374
|
+
name: 'Surface and section',
|
|
375
|
+
description: 'Layout components establish rhythm without domain assumptions.',
|
|
376
|
+
render: () => (_jsx(Section, { eyebrow: "Operations", title: "Daily overview", description: "The section owns hierarchy; its body remains application data.", actions: _jsx(LinkButton, { label: "View report", href: "#patterns", size: "compact" }), body: _jsx(Grid, { columns: 4, items: [
|
|
377
|
+
_jsx(Metric, { label: "Orders", value: "148", detail: "+12 today", tone: "positive", icon: _jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "1.75", "aria-hidden": "true", focusable: "false", children: [_jsx("path", { d: "M3 6h18v12H3z" }), _jsx("circle", { cx: "12", cy: "12", r: "2.5" })] }) }),
|
|
378
|
+
_jsx(Metric, { label: "Review queue", value: "7", detail: "Oldest 42 min", tone: "warning", href: "#surface-section" }),
|
|
379
|
+
_jsx(Metric, { label: "Blocked", value: "2", detail: "Credential required", tone: "danger" }),
|
|
380
|
+
_jsx(Metric, { label: "Archived", value: "1 204", detail: "No state to report" }),
|
|
381
|
+
] }) })),
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
id: 'content-card',
|
|
385
|
+
name: 'Content card',
|
|
386
|
+
description: 'A composable record summary with valid nested actions.',
|
|
387
|
+
render: () => (_jsx(Grid, { columns: 3, items: [
|
|
388
|
+
_jsx(ContentCard, { title: "Commerce", summary: "General retail operations", body: "24 ready tenants", meta: _jsx(Badge, { label: "Stable", tone: "positive" }), href: "#content-card" }),
|
|
389
|
+
_jsx(ContentCard, { title: "Cosmetic", summary: "Care and marketplace workflows", body: "9 ready tenants", meta: _jsx(Badge, { label: "Review", tone: "warning" }), selected: true }),
|
|
390
|
+
_jsx(ContentCard, { title: "Hospitality", summary: "Property and OTA operations", body: "6 ready tenants", actions: _jsx(Button, { label: "Open cohort", size: "compact" }) }),
|
|
391
|
+
] })),
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
id: 'disclosure',
|
|
395
|
+
name: 'Disclosure',
|
|
396
|
+
description: 'Secondary detail stays available without dominating the primary workflow.',
|
|
397
|
+
render: () => (_jsx(Disclosure, { summary: "Permission provenance", body: _jsx(Stack, { gap: "compact", items: [
|
|
398
|
+
_jsx(Code, { value: "sales.order.approve", context: "managed-template" }),
|
|
399
|
+
_jsx(Code, { value: "sales.order.read", context: "managed-template" }),
|
|
400
|
+
] }) })),
|
|
401
|
+
},
|
|
402
|
+
],
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
id: 'application-structure',
|
|
406
|
+
name: 'Application structure',
|
|
407
|
+
description: 'Responsive application navigation and four practical layouts inside the same shell.',
|
|
408
|
+
examples: [
|
|
409
|
+
{
|
|
410
|
+
id: 'app-navigation',
|
|
411
|
+
name: 'Responsive application navigation',
|
|
412
|
+
description: 'One navigation model becomes a persistent desktop sidebar and an accessible mobile drawer.',
|
|
413
|
+
render: () => (_jsx(DemoShell, { active: "collection", main: _jsx(Page, { title: "Operations overview", description: "Resize below 768 px to review the mobile trigger and drawer.", body: _jsx(Grid, { columns: 2, items: [
|
|
414
|
+
_jsx(Metric, { label: "Open orders", value: "148", detail: "12 need attention" }),
|
|
415
|
+
_jsx(Metric, { label: "Ready to invoice", value: "91", detail: "Updated just now" }),
|
|
416
|
+
] }) }) })),
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
id: 'app-shell',
|
|
420
|
+
name: 'Collection shell',
|
|
421
|
+
description: 'A full list workspace with sidebar navigation, URL-owned list chrome, selectable rows and a context rail.',
|
|
422
|
+
render: () => (_jsx(DemoShell, { active: "collection", main: _jsx(ListPage, { variant: "operational", context: "Sales / Sales orders", title: "Sales orders", description: "Review demand, fulfillment and payment state from one operational list.", actions: _jsx(Button, { label: "Create order", variant: "primary" }), controls: _jsx(ListDemoChrome, { id: "app-shell" }), body: _jsx(OrdersTable, { title: "Order list" }) }), railTitle: "List health", railDetail: "Seven orders need a human decision before invoicing.", railProgress: 72, railItems: [
|
|
423
|
+
_jsx(Badge, { label: "91 ready", tone: "positive" }),
|
|
424
|
+
_jsx(Badge, { label: "7 review", tone: "warning" }),
|
|
425
|
+
] })),
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
id: 'record-page',
|
|
429
|
+
name: 'Record shell',
|
|
430
|
+
description: 'A durable subject with record identity, tabs, form content and a right-hand facts rail.',
|
|
431
|
+
render: () => (_jsx(DemoShell, { active: "record", main: _jsx(RecordPage, { variant: "operational", context: "Customers / M\u00F9a H\u1EA1 Riverside", title: "M\u00F9a H\u1EA1 Riverside", description: "Customer \u00B7 CUS-0042", status: _jsx(Badge, { label: "Active", tone: "positive" }), actions: _jsx(ActionGroup, { actions: [
|
|
432
|
+
_jsx(Button, { label: "Save", variant: "primary", size: "compact" }),
|
|
433
|
+
_jsx(Button, { label: "Archive", variant: "tertiary", size: "compact" }),
|
|
434
|
+
] }), navigation: _jsx(Tabs, { label: "Customer record", items: [
|
|
435
|
+
{ id: 'details', label: 'Details', href: '#record-page', active: true },
|
|
436
|
+
{ id: 'orders', label: 'Orders', href: '#record-page', count: 6 },
|
|
437
|
+
{ id: 'activity', label: 'Activity', href: '#record-page', count: 8 },
|
|
438
|
+
] }), body: _jsx(Stack, { items: [
|
|
439
|
+
_jsx(Surface, { title: "Main information", body: _jsx(RecordForm, { action: "#record-page", fields: [
|
|
440
|
+
{
|
|
441
|
+
id: 'layout-partner-name',
|
|
442
|
+
span: 'full',
|
|
443
|
+
name: 'name',
|
|
444
|
+
label: 'Name',
|
|
445
|
+
value: 'Mùa Hạ Riverside',
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
id: 'layout-partner-email',
|
|
449
|
+
span: 'full',
|
|
450
|
+
name: 'email',
|
|
451
|
+
label: 'Email',
|
|
452
|
+
type: 'email',
|
|
453
|
+
value: 'hello@muaha.example',
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
id: 'layout-partner-tags',
|
|
457
|
+
name: 'tags',
|
|
458
|
+
label: 'Tags',
|
|
459
|
+
type: 'checkbox-group',
|
|
460
|
+
span: 'full',
|
|
461
|
+
options: [
|
|
462
|
+
{ value: 'vip', label: 'VIP', checked: true },
|
|
463
|
+
{ value: 'hospitality', label: 'Hospitality', checked: true },
|
|
464
|
+
],
|
|
465
|
+
},
|
|
466
|
+
], submitLabel: "Save" }) }),
|
|
467
|
+
_jsx(OrdersTable, { title: "Recent orders" }),
|
|
468
|
+
] }), aside: _jsx(Stack, { items: [
|
|
469
|
+
_jsx(Metric, { label: "Credit limit", value: "80m \u20AB", detail: "42m \u20AB available" }),
|
|
470
|
+
_jsx(Progress, { label: "Onboarding complete", value: 84, tone: "positive" }),
|
|
471
|
+
] }), asideLabel: "Customer context" }) })),
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
id: 'workspace-flow',
|
|
475
|
+
name: 'Flow workspace',
|
|
476
|
+
description: 'A vertical operations overview where metrics, process state and exception lists sit on one grey canvas.',
|
|
477
|
+
render: () => (_jsx(DemoShell, { active: "flow", main: _jsx(WorkspacePage, { variant: "operational", layout: "flow", context: "Sales / Overview", title: "Revenue operations", description: "Follow confirmed demand, open work and handoffs across the team.", actions: _jsx(Button, { label: "Create quotation", variant: "primary" }), controls: _jsx(ActionGroup, { label: "Flow controls", actions: [
|
|
478
|
+
_jsx(LinkButton, { label: "Today", href: "#workspace-flow", size: "compact" }),
|
|
479
|
+
_jsx(LinkButton, { label: "This week", href: "#workspace-flow", size: "compact", variant: "tertiary" }),
|
|
480
|
+
] }), body: _jsx(Stack, { gap: "loose", items: [
|
|
481
|
+
_jsx(Grid, { columns: 4, items: [
|
|
482
|
+
_jsx(Metric, { label: "Quotations", value: 24, detail: "5 new today" }),
|
|
483
|
+
_jsx(Metric, { label: "Sent", value: 9, detail: "Awaiting reply", tone: "info" }),
|
|
484
|
+
_jsx(Metric, { label: "Confirmed", value: 18, detail: "82,000,000 \u20AB", tone: "positive" }),
|
|
485
|
+
_jsx(Metric, { label: "Blocked", value: 2, detail: "Needs attention", tone: "danger" }),
|
|
486
|
+
] }),
|
|
487
|
+
_jsx(Surface, { title: "Sales flow", body: _jsx(Pipeline, { label: "Sales flow", steps: [
|
|
488
|
+
{ id: 'draft', label: 'Quotation', value: 24 },
|
|
489
|
+
{ id: 'sent', label: 'Sent', value: 9, tone: 'info' },
|
|
490
|
+
{ id: 'confirmed', label: 'Confirmed', value: 18, tone: 'positive' },
|
|
491
|
+
{ id: 'invoice', label: 'To invoice', value: 6, tone: 'warning' },
|
|
492
|
+
] }) }),
|
|
493
|
+
_jsx(OrdersTable, { grouped: true, title: "Exceptions" }),
|
|
494
|
+
] }) }), railTitle: "Daily target", railDetail: "56 of 82 confirmed orders have been invoiced today.", railProgress: 68 })),
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
id: 'workspace-canvas',
|
|
498
|
+
name: 'Canvas workspace',
|
|
499
|
+
description: 'A horizontal board-style surface where the main content can scroll without changing the shell.',
|
|
500
|
+
render: () => (_jsx(DemoShell, { active: "canvas", main: _jsx(WorkspacePage, { variant: "operational", layout: "canvas", context: "CRM / Pipeline", title: "Opportunities board", description: "Move active opportunities through a spatial workflow.", actions: _jsx(Button, { label: "Create opportunity", variant: "primary" }), controls: _jsx(Inline, { items: [
|
|
501
|
+
_jsx(LinkButton, { label: "My pipeline", href: "#workspace-canvas", size: "compact" }),
|
|
502
|
+
_jsx(LinkButton, { label: "All teams", href: "#workspace-canvas", size: "compact", variant: "tertiary" }),
|
|
503
|
+
_jsx(Tag, { label: "High value", removeHref: "#workspace-canvas", removeLabel: "Remove filter" }),
|
|
504
|
+
] }), body: _jsx(Grid, { columns: 3, items: [
|
|
505
|
+
_jsx(Section, { title: "Qualified", body: _jsx(Stack, { gap: "compact", items: [
|
|
506
|
+
_jsx(ContentCard, { title: "M\u00F9a H\u1EA1 Riverside", meta: "42,000,000 \u20AB", body: "Needs proposal" }),
|
|
507
|
+
_jsx(ContentCard, { title: "\u00C1nh D\u01B0\u01A1ng Group", meta: "18,000,000 \u20AB", body: "Demo booked" }),
|
|
508
|
+
] }) }),
|
|
509
|
+
_jsx(Section, { title: "Proposal", body: _jsx(Stack, { gap: "compact", items: [
|
|
510
|
+
_jsx(ContentCard, { title: "Lotus Hotels", meta: "64,000,000 \u20AB", body: "Awaiting CFO" }),
|
|
511
|
+
_jsx(ContentCard, { title: "B\u00ECnh Minh Retail", meta: "30,000,000 \u20AB", body: "Legal review" }),
|
|
512
|
+
] }) }),
|
|
513
|
+
_jsx(Section, { title: "Negotiation", body: _jsx(Stack, { gap: "compact", items: [
|
|
514
|
+
_jsx(ContentCard, { title: "S\u00F4ng Xanh", meta: "52,000,000 \u20AB", body: "Discount requested" }),
|
|
515
|
+
_jsx(ContentCard, { title: "Urban Stay", meta: "40,000,000 \u20AB", body: "Close this week" }),
|
|
516
|
+
] }) }),
|
|
517
|
+
] }) }), railTitle: "Pipeline risk", railDetail: "Three opportunities need owner follow-up before Friday.", railItems: [
|
|
518
|
+
_jsx(Badge, { label: "2 overdue", tone: "danger" }),
|
|
519
|
+
_jsx(Badge, { label: "6 due this week", tone: "warning" }),
|
|
520
|
+
] })),
|
|
521
|
+
},
|
|
522
|
+
],
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
id: 'navigation',
|
|
526
|
+
name: 'Navigation & progress',
|
|
527
|
+
description: 'Low-luminance selection and compact progress keep attention on the working content.',
|
|
528
|
+
examples: [
|
|
529
|
+
{
|
|
530
|
+
id: 'navigation-items',
|
|
531
|
+
name: 'Navigation and tabs',
|
|
532
|
+
description: 'The active indigo remains restrained in both vertical and horizontal navigation.',
|
|
533
|
+
render: () => (_jsx(Stack, { items: [
|
|
534
|
+
_jsx(Breadcrumbs, { label: "Current location", items: [
|
|
535
|
+
{ label: 'Workspace', href: '#navigation-items' },
|
|
536
|
+
{ label: 'Sales', href: '#navigation-items' },
|
|
537
|
+
{ label: 'Orders' },
|
|
538
|
+
] }),
|
|
539
|
+
_jsx(NavList, { label: "Product", items: [
|
|
540
|
+
{ label: 'Details', href: '#navigation-items', leading: '◇', active: true },
|
|
541
|
+
{ label: 'Variants', href: '#navigation-items', leading: '□', count: 12 },
|
|
542
|
+
{ label: 'Inventory', href: '#navigation-items', leading: '≡' },
|
|
543
|
+
] }),
|
|
544
|
+
_jsx(Tabs, { label: "Record views", items: [
|
|
545
|
+
{ id: 'summary', label: 'Summary', href: '#navigation-items', active: true },
|
|
546
|
+
{ id: 'activity', label: 'Activity', href: '#navigation-items', count: 8 },
|
|
547
|
+
{ id: 'files', label: 'Files', href: '#navigation-items', count: 3 },
|
|
548
|
+
], extension: _jsx("a", { "data-ui": "tab", href: "#navigation-items", children: "Extension" }) }),
|
|
549
|
+
] })),
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
id: 'progress',
|
|
553
|
+
name: 'Progress',
|
|
554
|
+
description: 'A four-pixel track communicates state without becoming another panel.',
|
|
555
|
+
render: () => (_jsx(Stack, { gap: "compact", items: [
|
|
556
|
+
_jsx(Progress, { label: "Project completion", value: 68 }),
|
|
557
|
+
_jsx(Progress, { label: "Approved", value: 92, tone: "positive" }),
|
|
558
|
+
_jsx(Progress, { label: "At risk", value: 54, tone: "warning" }),
|
|
559
|
+
_jsx(Progress, { label: "Overdue", value: 31, tone: "danger" }),
|
|
560
|
+
] })),
|
|
561
|
+
},
|
|
562
|
+
],
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
id: 'patterns',
|
|
566
|
+
name: 'Patterns',
|
|
567
|
+
description: 'Generic workflows assembled from the same primitives.',
|
|
568
|
+
examples: [
|
|
569
|
+
{
|
|
570
|
+
id: 'list-chrome',
|
|
571
|
+
name: 'List chrome',
|
|
572
|
+
description: 'Search, filters, view switch, bulk state and paging for URL-driven collection screens.',
|
|
573
|
+
render: () => (_jsx(ListChrome, { search: {
|
|
574
|
+
id: 'customer-query',
|
|
575
|
+
action: '#list-chrome',
|
|
576
|
+
placeholder: 'Search customers',
|
|
577
|
+
}, facets: [
|
|
578
|
+
{ id: 'active', label: 'Active', href: '#list-chrome', active: true, count: 42 },
|
|
579
|
+
{ id: 'draft', label: 'Draft', href: '#list-chrome', count: 6 },
|
|
580
|
+
], views: [
|
|
581
|
+
{ id: 'table', label: 'Table', href: '#list-chrome', active: true },
|
|
582
|
+
{ id: 'cards', label: 'Cards', href: '#list-chrome' },
|
|
583
|
+
], sort: {
|
|
584
|
+
id: 'customer-sort',
|
|
585
|
+
action: '#list-chrome',
|
|
586
|
+
choices: [
|
|
587
|
+
{ value: 'updated-desc', label: 'Recently updated', selected: true },
|
|
588
|
+
{ value: 'name-asc', label: 'Name A-Z' },
|
|
589
|
+
],
|
|
590
|
+
}, status: "48 customers", actions: _jsx(Button, { label: "Create", variant: "primary", size: "compact" }), bulk: {
|
|
591
|
+
selectedCount: 2,
|
|
592
|
+
summary: '2 customers selected',
|
|
593
|
+
clearHref: '#list-chrome',
|
|
594
|
+
actions: [{ id: 'archive', label: 'Archive', name: 'intent', value: 'archive' }],
|
|
595
|
+
}, pager: {
|
|
596
|
+
summary: 'Showing 1-25 of 48',
|
|
597
|
+
nextHref: '#list-chrome',
|
|
598
|
+
pages: [
|
|
599
|
+
{ label: '1', href: '#list-chrome', active: true },
|
|
600
|
+
{ label: '2', href: '#list-chrome' },
|
|
601
|
+
],
|
|
602
|
+
} })),
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
id: 'list-page',
|
|
606
|
+
name: 'List page',
|
|
607
|
+
description: 'The canonical collection hierarchy: identity, actions, URL-driven controls, result context and records.',
|
|
608
|
+
render: () => (_jsx(ListPage, { variant: "operational", context: "Sales / Sales orders", eyebrow: "Sales", title: "Sales orders", description: "Review demand, fulfillment and payment state from one operational list.", actions: _jsx(Button, { label: "Create order", variant: "primary" }), controls: _jsx(ListChrome, { search: {
|
|
609
|
+
id: 'orders-query',
|
|
610
|
+
action: '#list-page',
|
|
611
|
+
value: 'Mùa Hạ',
|
|
612
|
+
placeholder: 'Search orders',
|
|
613
|
+
hidden: { view: 'all' },
|
|
614
|
+
}, facets: [
|
|
615
|
+
{ id: 'all', label: 'All', href: '#list-page', active: true, count: 148 },
|
|
616
|
+
{ id: 'ready', label: 'Ready', href: '#list-page', count: 91 },
|
|
617
|
+
{ id: 'review', label: 'Review', href: '#list-page', count: 7 },
|
|
618
|
+
], views: [
|
|
619
|
+
{ id: 'table', label: 'Table', href: '#list-page', active: true },
|
|
620
|
+
{ id: 'kanban', label: 'Kanban', href: '#list-page' },
|
|
621
|
+
], sort: {
|
|
622
|
+
id: 'orders-sort',
|
|
623
|
+
action: '#list-page',
|
|
624
|
+
choices: [
|
|
625
|
+
{ value: 'date-desc', label: 'Newest first', selected: true },
|
|
626
|
+
{ value: 'total-desc', label: 'Largest total' },
|
|
627
|
+
{ value: 'customer-asc', label: 'Customer A-Z' },
|
|
628
|
+
],
|
|
629
|
+
}, bulk: {
|
|
630
|
+
selectedCount: 1,
|
|
631
|
+
summary: '1 order selected',
|
|
632
|
+
clearHref: '#list-page',
|
|
633
|
+
actions: [
|
|
634
|
+
{ id: 'approve', label: 'Approve', name: 'intent', value: 'approve', variant: 'primary' },
|
|
635
|
+
{ id: 'export', label: 'Export', name: 'intent', value: 'export' },
|
|
636
|
+
],
|
|
637
|
+
}, pager: {
|
|
638
|
+
summary: 'Showing 1-3 of 148',
|
|
639
|
+
previousHref: null,
|
|
640
|
+
nextHref: '#list-page',
|
|
641
|
+
pages: [
|
|
642
|
+
{ label: '1', href: '#list-page', active: true },
|
|
643
|
+
{ label: '2', href: '#list-page' },
|
|
644
|
+
{ label: '3', href: '#list-page' },
|
|
645
|
+
],
|
|
646
|
+
} }), body: _jsx(DataTable, { title: "Order list", rows: orders, id: (row) => row.id, rowHref: (row) => `#${row.id}`, responsive: "stack", selection: { selectedIds: ['SO-1042'] }, columns: [
|
|
647
|
+
{
|
|
648
|
+
key: 'id',
|
|
649
|
+
label: 'Order',
|
|
650
|
+
cell: (row) => row.id,
|
|
651
|
+
priority: 'primary',
|
|
652
|
+
kind: 'identifier',
|
|
653
|
+
sort: { href: '#list-page', direction: 'descending' },
|
|
654
|
+
},
|
|
655
|
+
{ key: 'customer', label: 'Customer', cell: (row) => row.customer },
|
|
656
|
+
{ key: 'total', label: 'Total', cell: (row) => row.total, align: 'end', kind: 'currency' },
|
|
657
|
+
{
|
|
658
|
+
key: 'state',
|
|
659
|
+
label: 'State',
|
|
660
|
+
cell: (row) => _jsx(Badge, { label: row.state, tone: toneOf(row.state) }),
|
|
661
|
+
kind: 'status',
|
|
662
|
+
},
|
|
663
|
+
] }) })),
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
id: 'dashboard-page',
|
|
667
|
+
name: 'Dashboard page',
|
|
668
|
+
description: 'The canonical overview hierarchy: durable context, compact identity, primary action and an uninterrupted analytical canvas.',
|
|
669
|
+
render: () => (_jsx(DashboardPage, { variant: "operational", context: "Sales / Overview", eyebrow: "Commercial workspace", title: "Sales overview", description: "Follow demand, confirmed revenue and the work waiting for the team.", actions: _jsx(Button, { label: "Create quotation", variant: "primary" }), body: _jsx(Stack, { gap: "loose", items: [
|
|
670
|
+
_jsx(Grid, { columns: 4, items: [
|
|
671
|
+
_jsx(Metric, { label: "Quotations", value: 24, detail: "5 new today" }),
|
|
672
|
+
_jsx(Metric, { label: "Sent", value: 9, detail: "Awaiting a reply", tone: "info" }),
|
|
673
|
+
_jsx(Metric, { label: "Confirmed", value: 18, detail: "82,000,000 \u20AB", tone: "positive" }),
|
|
674
|
+
_jsx(Metric, { label: "To invoice", value: 6, detail: "Needs attention", tone: "warning" }),
|
|
675
|
+
] }),
|
|
676
|
+
_jsx(Surface, { title: "Sales flow", body: _jsx(Pipeline, { label: "Sales flow", steps: [
|
|
677
|
+
{ id: 'draft', label: 'Quotation', value: 24 },
|
|
678
|
+
{ id: 'sent', label: 'Sent', value: 9, tone: 'info' },
|
|
679
|
+
{ id: 'confirmed', label: 'Confirmed', value: 18, tone: 'positive' },
|
|
680
|
+
{ id: 'invoice', label: 'To invoice', value: 6, tone: 'warning' },
|
|
681
|
+
] }) }),
|
|
682
|
+
] }) })),
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
id: 'board-page',
|
|
686
|
+
name: 'Board page',
|
|
687
|
+
description: 'The canonical horizontal workspace: durable context, compact identity, global controls and an uninterrupted board canvas.',
|
|
688
|
+
render: () => (_jsx(BoardPage, { variant: "operational", context: "CRM / Pipeline", eyebrow: "Pipeline", title: "Sales opportunities", description: "Move active opportunities through the sales process.", actions: _jsx(Button, { label: "Create opportunity", variant: "primary" }), controls: _jsx(ActionGroup, { label: "Board controls", actions: [
|
|
689
|
+
_jsx(LinkButton, { label: "My opportunities", href: "#board-page", size: "compact" }),
|
|
690
|
+
_jsx(LinkButton, { label: "All teams", href: "#board-page", size: "compact", variant: "tertiary" }),
|
|
691
|
+
] }), body: _jsx(Grid, { columns: 3, items: [
|
|
692
|
+
_jsx(ContentCard, { title: "Qualified", meta: "8 opportunities", body: "125,000,000 \u20AB" }),
|
|
693
|
+
_jsx(ContentCard, { title: "Proposal", meta: "5 opportunities", body: "94,000,000 \u20AB" }),
|
|
694
|
+
_jsx(ContentCard, { title: "Negotiation", meta: "3 opportunities", body: "62,000,000 \u20AB" }),
|
|
695
|
+
] }) })),
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
id: 'pipeline',
|
|
699
|
+
name: 'Pipeline',
|
|
700
|
+
description: 'Stages of a process and the work sitting in each. A later stage may hold more than the one before it.',
|
|
701
|
+
render: () => (_jsx(Pipeline, { label: "Order pipeline", steps: [
|
|
702
|
+
{ id: 'draft', label: 'Draft', value: 24, href: '#pipeline' },
|
|
703
|
+
{ id: 'sent', label: 'Sent', value: 9, href: '#pipeline', tone: 'info' },
|
|
704
|
+
{ id: 'confirmed', label: 'Confirmed', value: 18, href: '#pipeline', tone: 'positive' },
|
|
705
|
+
{ id: 'to-invoice', label: 'To invoice', value: 6, href: '#pipeline', tone: 'warning' },
|
|
706
|
+
] })),
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
id: 'data-table',
|
|
710
|
+
name: 'Data table',
|
|
711
|
+
description: 'Columns are data; rows remain semantic and horizontally contained.',
|
|
712
|
+
render: () => (_jsx(DataTable, { title: "Recent sales orders", actions: _jsx(LinkButton, { label: "View all orders", href: "#app-shell", variant: "tertiary" }), rows: [], id: (row) => row.id, rowHref: (row) => `#${row.id}`, responsive: "stack", gutter: "compact", selection: { selectedIds: ['SO-1042'] }, groups: [
|
|
713
|
+
{
|
|
714
|
+
id: 'ready',
|
|
715
|
+
label: 'Ready to invoice',
|
|
716
|
+
count: 2,
|
|
717
|
+
href: '#data-table',
|
|
718
|
+
rows: orders.slice(0, 2),
|
|
719
|
+
pager: { label: '2 shown in Ready', nextHref: '#data-table' },
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
id: 'blocked',
|
|
723
|
+
label: 'Needs decision',
|
|
724
|
+
count: 1,
|
|
725
|
+
rows: orders.slice(2),
|
|
726
|
+
},
|
|
727
|
+
], columns: [
|
|
728
|
+
{
|
|
729
|
+
key: 'id',
|
|
730
|
+
label: 'Order',
|
|
731
|
+
cell: (row) => row.id,
|
|
732
|
+
priority: 'primary',
|
|
733
|
+
kind: 'identifier',
|
|
734
|
+
sort: { href: '#data-table', direction: 'descending' },
|
|
735
|
+
},
|
|
736
|
+
{ key: 'customer', label: 'Customer', cell: (row) => row.customer },
|
|
737
|
+
{ key: 'total', label: 'Total', cell: (row) => row.total, align: 'end', kind: 'currency' },
|
|
738
|
+
{
|
|
739
|
+
key: 'state',
|
|
740
|
+
label: 'State',
|
|
741
|
+
cell: (row) => _jsx(Badge, { label: row.state, tone: toneOf(row.state) }),
|
|
742
|
+
kind: 'status',
|
|
743
|
+
},
|
|
744
|
+
] })),
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
id: 'form-page',
|
|
748
|
+
name: 'Form page',
|
|
749
|
+
description: 'The canonical form hierarchy: record identity and decision first, a stable form column, then durable context.',
|
|
750
|
+
render: () => (_jsx(FormPage, { variant: "operational", context: "Customers / M\u00F9a H\u1EA1 Riverside", title: "M\u00F9a H\u1EA1 Riverside", description: "Customer \u00B7 CUS-0042", status: _jsx(Badge, { label: "Active", tone: "positive" }), actions: _jsx(Button, { label: "Save partner", variant: "primary" }), body: _jsx(Surface, { title: "Main information", body: _jsx(RecordForm, { action: "#form-page", fields: [
|
|
751
|
+
{ id: 'partner-name', name: 'name', label: 'Name', value: 'Mùa Hạ Riverside' },
|
|
752
|
+
{ id: 'partner-ref', name: 'ref', label: 'Reference', value: 'CUS-0042' },
|
|
753
|
+
{
|
|
754
|
+
id: 'partner-email',
|
|
755
|
+
name: 'email',
|
|
756
|
+
label: 'Email',
|
|
757
|
+
type: 'email',
|
|
758
|
+
value: 'hello@muaha.example',
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
id: 'partner-phone',
|
|
762
|
+
name: 'phone',
|
|
763
|
+
label: 'Phone',
|
|
764
|
+
type: 'tel',
|
|
765
|
+
value: '+84 28 3822 0042',
|
|
766
|
+
},
|
|
767
|
+
], submitLabel: "Save partner" }) }), aside: _jsx(Section, { title: "Record context", body: _jsx(Stack, { gap: "compact", items: ['Customer since 2023', '6 delivery addresses'] }) }), asideLabel: "Partner context" })),
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
id: 'record-form',
|
|
771
|
+
name: 'Record form',
|
|
772
|
+
description: 'Application supplies translated labels and values, not form markup.',
|
|
773
|
+
render: () => (_jsx(Surface, { title: "Main information", body: _jsx(RecordForm, { action: "#record-form", fields: [
|
|
774
|
+
{ id: 'record-name', name: 'name', label: 'Display name', value: 'Mùa Hạ Riverside' },
|
|
775
|
+
{
|
|
776
|
+
id: 'record-status',
|
|
777
|
+
name: 'status',
|
|
778
|
+
label: 'Lifecycle',
|
|
779
|
+
type: 'select',
|
|
780
|
+
value: 'ready',
|
|
781
|
+
options: [
|
|
782
|
+
{ value: 'draft', label: 'Draft' },
|
|
783
|
+
{ value: 'ready', label: 'Ready' },
|
|
784
|
+
],
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
id: 'record-note',
|
|
788
|
+
name: 'note',
|
|
789
|
+
label: 'Internal note',
|
|
790
|
+
type: 'textarea',
|
|
791
|
+
value: 'Migration approved by the operations team.',
|
|
792
|
+
span: 'full',
|
|
793
|
+
},
|
|
794
|
+
], submitLabel: "Save record", cancelHref: "#patterns", cancelLabel: "Cancel" }) })),
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
id: 'modal-sheet',
|
|
798
|
+
name: 'Modal sheet',
|
|
799
|
+
description: 'Shown embedded here; the production mode occupies the viewport.',
|
|
800
|
+
render: () => (_jsx(ModalSheet, { id: "release-drift-modal", mode: "embedded", title: "Resolve release drift", closeHref: "#modal-sheet", closeLabel: "Close modal", body: _jsx(Stack, { items: [
|
|
801
|
+
_jsx(Notice, { title: "Two tenants are behind", message: "Migration runs separately for each database and preserves failed tenants for retry.", tone: "warning" }),
|
|
802
|
+
_jsx(ActionGroup, { actions: [
|
|
803
|
+
_jsx(Button, { label: "Start migration", variant: "primary" }),
|
|
804
|
+
_jsx(LinkButton, { label: "Review plan", href: "#data-table", variant: "tertiary" }),
|
|
805
|
+
] }),
|
|
806
|
+
] }) })),
|
|
807
|
+
},
|
|
808
|
+
],
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
id: 'interactions',
|
|
812
|
+
name: 'Interaction essentials',
|
|
813
|
+
description: 'Controlled SSR state with native fallbacks and one optional runtime adapter.',
|
|
814
|
+
examples: [
|
|
815
|
+
{
|
|
816
|
+
id: 'menu',
|
|
817
|
+
name: 'Menu and action menu',
|
|
818
|
+
description: 'Native disclosure supports links, submit actions, descriptions and disabled state.',
|
|
819
|
+
render: () => (_jsx(Inline, { items: [
|
|
820
|
+
_jsx(Menu, { id: "record-menu", label: "Record actions", open: true, items: [
|
|
821
|
+
{ id: 'open', label: 'Open record', href: '#record-page' },
|
|
822
|
+
{ id: 'duplicate', label: 'Duplicate', value: 'duplicate' },
|
|
823
|
+
{ id: 'archive', label: 'Archive', value: 'archive', destructive: true },
|
|
824
|
+
] }),
|
|
825
|
+
_jsx(ActionMenu, { id: "more-actions", label: "More actions", items: [{ id: 'export', label: 'Export report', href: '#data-table' }] }),
|
|
826
|
+
] })),
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
id: 'popover',
|
|
830
|
+
name: 'Popover and tooltip',
|
|
831
|
+
description: 'Popover state remains URL-owned; tooltips contain descriptive text only.',
|
|
832
|
+
render: () => (_jsx(Inline, { items: [
|
|
833
|
+
_jsx(Popover, { id: "owner-popover", label: "Record owner", trigger: _jsx(Badge, { label: "Show owner" }), body: _jsx("p", { children: "Nguy\u1EC5n Ng\u1ECDc Linh \u00B7 Sales operations" }), open: true, openHref: "#popover", closeHref: "#popover", closeLabel: "Close owner details" }),
|
|
834
|
+
_jsx(Tooltip, { id: "sync-tip", text: "Last synchronized two minutes ago", trigger: _jsx(Badge, { label: "Synced", tone: "positive" }) }),
|
|
835
|
+
] })),
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
id: 'dialog',
|
|
839
|
+
name: 'Dialog and confirmation',
|
|
840
|
+
description: 'Named modal semantics with native close and submit paths.',
|
|
841
|
+
render: () => (_jsx(Grid, { columns: 2, items: [
|
|
842
|
+
_jsx(Dialog, { id: "details-dialog", mode: "embedded", title: "Review assignment", description: "The current owner keeps access.", closeHref: "#dialog", closeLabel: "Close dialog", body: _jsx("p", { children: "Assign this record to the operations queue." }) }),
|
|
843
|
+
_jsx(ConfirmDialog, { id: "archive-dialog", mode: "embedded", title: "Archive record?", message: "The record leaves active worklists but remains available in history.", closeHref: "#dialog", closeLabel: "Cancel", confirmLabel: "Archive" }),
|
|
844
|
+
] })),
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
id: 'feedback-runtime',
|
|
848
|
+
name: 'Transient feedback and loading',
|
|
849
|
+
description: 'Live-region toasts, compact progress and content skeletons share state rules.',
|
|
850
|
+
render: () => (_jsx(Stack, { items: [
|
|
851
|
+
_jsx(Inline, { items: [_jsx(Spinner, { label: "Saving record" }), _jsx("span", { children: "Saving record" })] }),
|
|
852
|
+
_jsx(Skeleton, { label: "Loading customer summary", lines: 3 }),
|
|
853
|
+
_jsx(ToastRegion, { label: "Notifications", toasts: [
|
|
854
|
+
{
|
|
855
|
+
id: 'saved',
|
|
856
|
+
title: 'Record saved',
|
|
857
|
+
message: 'All changes are synchronized.',
|
|
858
|
+
tone: 'positive',
|
|
859
|
+
},
|
|
860
|
+
] }),
|
|
861
|
+
] })),
|
|
862
|
+
},
|
|
863
|
+
],
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
id: 'form-controls',
|
|
867
|
+
name: 'Form controls and pickers',
|
|
868
|
+
description: 'Typed, server-rendered controls preserve user input and native submission semantics.',
|
|
869
|
+
examples: [
|
|
870
|
+
{
|
|
871
|
+
id: 'scalar-fields',
|
|
872
|
+
name: 'Scalar fields',
|
|
873
|
+
description: 'Text, long text, search, exact numeric and money values share one field contract.',
|
|
874
|
+
render: () => (_jsx(Grid, { columns: 2, items: [
|
|
875
|
+
_jsx(TextField, { id: "customer", name: "customer", label: "Customer", value: "An Vi\u1EC7t", required: true }),
|
|
876
|
+
_jsx(SearchField, { id: "reference", name: "reference", label: "Reference", value: "SO-1042" }),
|
|
877
|
+
_jsx(NumberField, { id: "quantity", name: "quantity", label: "Quantity", value: "12", min: "0" }),
|
|
878
|
+
_jsx(MoneyField, { id: "total", name: "total", label: "Total", value: "18450000.00" }),
|
|
879
|
+
_jsx(TextArea, { id: "note", name: "note", label: "Internal note", value: "Deliver before 17:00.", span: "full" }),
|
|
880
|
+
] })),
|
|
881
|
+
},
|
|
882
|
+
{
|
|
883
|
+
id: 'selection-controls',
|
|
884
|
+
name: 'Selection controls',
|
|
885
|
+
description: 'Native checkbox, group, radio, switch and select states remain submit-capable.',
|
|
886
|
+
render: () => (_jsx(Stack, { items: [
|
|
887
|
+
_jsx(Checkbox, { id: "priority", name: "priority", label: "Priority order", value: true }),
|
|
888
|
+
_jsx(CheckboxGroup, { id: "channels", name: "channels", label: "Channels", options: [
|
|
889
|
+
{ value: 'email', label: 'Email', checked: true },
|
|
890
|
+
{ value: 'sms', label: 'SMS' },
|
|
891
|
+
] }),
|
|
892
|
+
_jsx(RadioGroup, { id: "delivery", name: "delivery", label: "Delivery", value: "standard", options: [
|
|
893
|
+
{ value: 'standard', label: 'Standard' },
|
|
894
|
+
{ value: 'express', label: 'Express' },
|
|
895
|
+
] }),
|
|
896
|
+
_jsx(Switch, { id: "notify", name: "notify", label: "Notify owner", checked: true }),
|
|
897
|
+
_jsx(Select, { id: "warehouse", name: "warehouse", label: "Warehouse", value: "hn", options: [
|
|
898
|
+
{ value: 'hn', label: 'Hà Nội' },
|
|
899
|
+
{ value: 'hcm', label: 'Hồ Chí Minh' },
|
|
900
|
+
] }),
|
|
901
|
+
] })),
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
id: 'comboboxes',
|
|
905
|
+
name: 'Combobox and tags',
|
|
906
|
+
description: 'Query, open state and selected values remain controlled by URL or application state.',
|
|
907
|
+
render: () => {
|
|
908
|
+
const options = [
|
|
909
|
+
{ value: 'linh', label: 'Ngọc Linh', description: 'Sales operations' },
|
|
910
|
+
{ value: 'minh', label: 'Minh Anh', description: 'Fulfilment' },
|
|
911
|
+
];
|
|
912
|
+
return (_jsx(Stack, { items: [
|
|
913
|
+
_jsx(Combobox, { id: "owner", name: "owner", label: "Owner", query: "Ng\u1ECDc", value: "linh", options: options, open: true, openHref: "#comboboxes", closeHref: "#comboboxes" }),
|
|
914
|
+
_jsx(MultiCombobox, { id: "watchers", name: "watchers", label: "Watchers", query: "", options: options, values: ['linh'], open: false, openHref: "#comboboxes", closeHref: "#comboboxes", removeHref: () => '#comboboxes' }),
|
|
915
|
+
_jsx(TagPicker, { id: "tags", name: "tags", label: "Tags", query: "", options: [{ value: 'urgent', label: 'Urgent' }], values: ['urgent'], open: false, openHref: "#comboboxes", closeHref: "#comboboxes", removeHref: () => '#comboboxes' }),
|
|
916
|
+
] }));
|
|
917
|
+
},
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
id: 'date-time',
|
|
921
|
+
name: 'Civil date and local time',
|
|
922
|
+
description: 'Civil dates and local times submit their source text without implicit UTC conversion.',
|
|
923
|
+
render: () => (_jsx(Stack, { items: [
|
|
924
|
+
_jsx(DatePicker, { id: "date", name: "date", label: "Delivery date", value: "2026-09-08" }),
|
|
925
|
+
_jsx(DateRangePicker, { id: "range", label: "Reporting period", start: { id: 'from', name: 'from', value: '2026-09-01' }, end: { id: 'to', name: 'to', value: '2026-09-30' }, startLabel: "From", endLabel: "To" }),
|
|
926
|
+
_jsx(DateTimePicker, { id: "appointment", name: "appointment", label: "Appointment", value: "2026-09-08T14:30" }),
|
|
927
|
+
_jsx(TimePicker, { id: "cutoff", name: "cutoff", label: "Cut-off", value: "17:00" }),
|
|
928
|
+
] })),
|
|
929
|
+
},
|
|
930
|
+
{
|
|
931
|
+
id: 'uploads',
|
|
932
|
+
name: 'File upload and drop zone',
|
|
933
|
+
description: 'Native file input owns submission; the application owns transport and storage.',
|
|
934
|
+
render: () => (_jsx(Stack, { items: [
|
|
935
|
+
_jsx(FileUpload, { id: "invoice", name: "invoice", label: "Invoice", accept: "application/pdf" }),
|
|
936
|
+
_jsx(DropZone, { id: "photos", name: "photos", label: "Delivery photos", accept: "image/*", multiple: true, status: "Up to 10 files \u00B7 8 MB each" }),
|
|
937
|
+
] })),
|
|
938
|
+
},
|
|
939
|
+
{
|
|
940
|
+
id: 'relation-picker',
|
|
941
|
+
name: 'Relation picker',
|
|
942
|
+
description: 'The renderer only receives permission-filtered records from the application adapter.',
|
|
943
|
+
render: () => (_jsx(RelationPicker, { id: "partner", name: "partner", label: "Partner", query: "An", value: "an-viet", results: [
|
|
944
|
+
{ id: 'an-viet', name: 'An Việt', city: 'Hà Nội' },
|
|
945
|
+
{ id: 'anh-duong', name: 'Ánh Dương', city: 'Đà Nẵng' },
|
|
946
|
+
], getValue: (partner) => partner.id, getLabel: (partner) => partner.name, getDescription: (partner) => partner.city, open: true, openHref: "#relation-picker", closeHref: "#relation-picker" })),
|
|
947
|
+
},
|
|
948
|
+
],
|
|
949
|
+
},
|
|
950
|
+
{
|
|
951
|
+
id: 'data-operations',
|
|
952
|
+
name: 'Data operations',
|
|
953
|
+
description: 'URL-owned collection controls and bounded data renderers for operational work.',
|
|
954
|
+
examples: [
|
|
955
|
+
{
|
|
956
|
+
id: 'collection-controls',
|
|
957
|
+
name: 'Search, filter and sort',
|
|
958
|
+
description: 'Every control has a canonical URL and preserves unrelated query state.',
|
|
959
|
+
render: () => (_jsx(Stack, { items: [
|
|
960
|
+
_jsx(SearchBar, { action: "/orders", value: "An Vi\u1EC7t", hidden: { state: 'open' } }),
|
|
961
|
+
_jsx(FilterBar, { filters: [
|
|
962
|
+
_jsx(LinkButton, { href: "/orders?state=open", label: "Open", size: "compact" }),
|
|
963
|
+
_jsx(LinkButton, { href: "/orders?owner=me", label: "My records", size: "compact" }),
|
|
964
|
+
_jsx(SortMenu, { id: "sort-orders", choices: [
|
|
965
|
+
{
|
|
966
|
+
id: 'updated',
|
|
967
|
+
label: 'Recently updated',
|
|
968
|
+
href: '/orders?sort=updated',
|
|
969
|
+
active: true,
|
|
970
|
+
},
|
|
971
|
+
{ id: 'value', label: 'Highest value', href: '/orders?sort=value' },
|
|
972
|
+
] }),
|
|
973
|
+
] }),
|
|
974
|
+
_jsx(AppliedFilters, { filters: [
|
|
975
|
+
{ id: 'state', label: 'State', value: 'Open', removeHref: '/orders?q=An+Việt' },
|
|
976
|
+
{ id: 'owner', label: 'Owner', value: 'Me', removeHref: '/orders?state=open' },
|
|
977
|
+
], clearHref: "/orders" }),
|
|
978
|
+
] })),
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
id: 'saved-views',
|
|
982
|
+
name: 'Saved views and settings',
|
|
983
|
+
description: 'The renderer carries version tokens while the application owns persistence and permission.',
|
|
984
|
+
render: () => (_jsx(Stack, { items: [
|
|
985
|
+
_jsx(SavedViews, { views: [
|
|
986
|
+
{
|
|
987
|
+
id: 'all',
|
|
988
|
+
label: 'All orders',
|
|
989
|
+
href: '/orders',
|
|
990
|
+
active: true,
|
|
991
|
+
description: '148 records',
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
id: 'review',
|
|
995
|
+
label: 'Needs review',
|
|
996
|
+
href: '/orders?view=review',
|
|
997
|
+
description: '7 records',
|
|
998
|
+
},
|
|
999
|
+
] }),
|
|
1000
|
+
_jsx(ViewSettings, { id: "order-view", action: "/orders/views", version: "7", settings: [
|
|
1001
|
+
{ id: 'customer', label: 'Customer', visible: true, disabled: true },
|
|
1002
|
+
{ id: 'total', label: 'Total', visible: true },
|
|
1003
|
+
{ id: 'owner', label: 'Owner', visible: false },
|
|
1004
|
+
] }),
|
|
1005
|
+
] })),
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
id: 'resource-list',
|
|
1009
|
+
name: 'Resource list',
|
|
1010
|
+
description: 'One keyboard link per row with optional selection and paging composition.',
|
|
1011
|
+
render: () => (_jsx(ResourceList, { label: "Orders", rows: orders, id: (row) => row.id, href: (row) => `/orders/${row.id}`, primary: (row) => `${row.id} · ${row.customer}`, secondary: (row) => row.total, meta: (row) => _jsx(Badge, { label: row.state, tone: toneOf(row.state) }), selectedIds: ['SO-1042'], pager: { summary: '1–3 of 148', nextHref: '/orders?page=2' } })),
|
|
1012
|
+
},
|
|
1013
|
+
{
|
|
1014
|
+
id: 'data-grid',
|
|
1015
|
+
name: 'Bounded data grid',
|
|
1016
|
+
description: 'Column order, visibility and pinning are explicit; row rendering is capped before virtualization.',
|
|
1017
|
+
render: () => (_jsx(DataGrid, { label: "Order analysis", rows: orders, id: (row) => row.id, maxRows: 500, columns: [
|
|
1018
|
+
{ key: 'id', label: 'Order', cell: (row) => row.id, pinned: 'start', width: '8rem' },
|
|
1019
|
+
{ key: 'customer', label: 'Customer', cell: (row) => row.customer, width: '18rem' },
|
|
1020
|
+
{ key: 'total', label: 'Total', cell: (row) => row.total, width: '10rem' },
|
|
1021
|
+
{ key: 'state', label: 'State', cell: (row) => row.state, width: '9rem' },
|
|
1022
|
+
] })),
|
|
1023
|
+
},
|
|
1024
|
+
{
|
|
1025
|
+
id: 'tree',
|
|
1026
|
+
name: 'Tree and tree grid',
|
|
1027
|
+
description: 'Hierarchy uses native links; tabular hierarchy is reserved for independent multi-column data.',
|
|
1028
|
+
render: () => (_jsx(Grid, { columns: 2, items: [
|
|
1029
|
+
_jsx(Tree, { label: "Workspace pages", nodes: [
|
|
1030
|
+
{
|
|
1031
|
+
id: 'sales',
|
|
1032
|
+
label: 'Sales',
|
|
1033
|
+
expanded: true,
|
|
1034
|
+
children: [
|
|
1035
|
+
{ id: 'orders', label: 'Orders', href: '/orders', active: true },
|
|
1036
|
+
{ id: 'reports', label: 'Reports', href: '/reports' },
|
|
1037
|
+
],
|
|
1038
|
+
},
|
|
1039
|
+
] }),
|
|
1040
|
+
_jsx(TreeGrid, { label: "Account hierarchy", rows: [
|
|
1041
|
+
{
|
|
1042
|
+
row: { id: '100', name: 'Assets', balance: '120.000.000 ₫' },
|
|
1043
|
+
level: 1,
|
|
1044
|
+
hasChildren: true,
|
|
1045
|
+
},
|
|
1046
|
+
{ row: { id: '110', name: 'Cash', balance: '42.000.000 ₫' }, level: 2 },
|
|
1047
|
+
], id: (row) => row.id, primary: (row) => `${row.id} · ${row.name}`, columns: [{ key: 'balance', label: 'Balance', cell: (row) => row.balance }] }),
|
|
1048
|
+
] })),
|
|
1049
|
+
},
|
|
1050
|
+
{
|
|
1051
|
+
id: 'inline-edit',
|
|
1052
|
+
name: 'Inline edit',
|
|
1053
|
+
description: 'Controlled edit state keeps a native form fallback, stale version and rejected input.',
|
|
1054
|
+
render: () => (_jsx(InlineEdit, { id: "customer-name", label: "Customer", value: "An Vi\u1EC7t", editing: true, editHref: "?edit=customer", cancelHref: "?edit=", action: "/orders/SO-1042/customer", name: "customer", inputValue: "An Vi\u1EC7t Trading", version: "7" })),
|
|
1055
|
+
},
|
|
1056
|
+
],
|
|
1057
|
+
},
|
|
1058
|
+
{
|
|
1059
|
+
id: 'record-workspace',
|
|
1060
|
+
name: 'Record and workspace composition',
|
|
1061
|
+
description: 'Neutral record facts, activity and media compose inside the three canonical page patterns.',
|
|
1062
|
+
examples: [
|
|
1063
|
+
{
|
|
1064
|
+
id: 'record-display',
|
|
1065
|
+
name: 'Record facts and formatted values',
|
|
1066
|
+
description: 'Identity, status and locale-aware values remain small, reusable display primitives.',
|
|
1067
|
+
render: () => (_jsx(Stack, { items: [
|
|
1068
|
+
_jsx(Inline, { items: [
|
|
1069
|
+
_jsx(Person, { name: "Ng\u1ECDc Linh", detail: "Sales operations" }),
|
|
1070
|
+
_jsx(AvatarGroup, { label: "Order collaborators", people: [
|
|
1071
|
+
{ id: 'linh', name: 'Ngọc Linh' },
|
|
1072
|
+
{ id: 'minh', name: 'Minh Anh' },
|
|
1073
|
+
{ id: 'ha', name: 'Thu Hà' },
|
|
1074
|
+
{ id: 'nam', name: 'Hoàng Nam' },
|
|
1075
|
+
{ id: 'vy', name: 'Thảo Vy' },
|
|
1076
|
+
], max: 4 }),
|
|
1077
|
+
_jsx(Status, { label: "Ready", tone: "positive" }),
|
|
1078
|
+
] }),
|
|
1079
|
+
_jsx(DescriptionList, { columns: 3, items: [
|
|
1080
|
+
{ id: 'date', label: 'Delivery date', value: _jsx(FormattedDate, { value: "2026-09-08" }) },
|
|
1081
|
+
{ id: 'quantity', label: 'Quantity', value: _jsx(FormattedNumber, { value: 1200 }) },
|
|
1082
|
+
{
|
|
1083
|
+
id: 'total',
|
|
1084
|
+
label: 'Total',
|
|
1085
|
+
value: _jsx(FormattedMoney, { value: 18450000, currency: "VND" }),
|
|
1086
|
+
},
|
|
1087
|
+
] }),
|
|
1088
|
+
] })),
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
id: 'record-composition',
|
|
1092
|
+
name: 'Record summary, actions and rail',
|
|
1093
|
+
description: 'One identity header and one neutral aside prevent nested-card drift.',
|
|
1094
|
+
render: () => (_jsx(Grid, { columns: 2, items: [
|
|
1095
|
+
_jsx(Stack, { items: [
|
|
1096
|
+
_jsx(RecordSummary, { title: "SO-1042", subtitle: "An Vi\u1EC7t Trading", person: { name: 'Ngọc Linh', detail: 'Owner' }, status: { label: 'Ready', tone: 'positive' }, facts: [
|
|
1097
|
+
{ id: 'date', label: 'Delivery', value: '08/09/2026' },
|
|
1098
|
+
{ id: 'total', label: 'Total', value: '18.450.000 ₫' },
|
|
1099
|
+
] }),
|
|
1100
|
+
_jsx(RecordActions, { actions: [
|
|
1101
|
+
_jsx(Button, { label: "Confirm", variant: "primary" }),
|
|
1102
|
+
_jsx(ActionMenu, { id: "record-more", label: "More", items: [] }),
|
|
1103
|
+
] }),
|
|
1104
|
+
] }),
|
|
1105
|
+
_jsx(RecordRail, { sections: [
|
|
1106
|
+
{
|
|
1107
|
+
id: 'owner',
|
|
1108
|
+
title: 'Owner',
|
|
1109
|
+
body: _jsx(Person, { name: "Ng\u1ECDc Linh", detail: "Sales operations" }),
|
|
1110
|
+
},
|
|
1111
|
+
{ id: 'health', title: 'Health', body: _jsx(Status, { label: "On track", tone: "positive" }) },
|
|
1112
|
+
] }),
|
|
1113
|
+
] })),
|
|
1114
|
+
},
|
|
1115
|
+
{
|
|
1116
|
+
id: 'activity-audit',
|
|
1117
|
+
name: 'Activity timeline and audit log',
|
|
1118
|
+
description: 'Applications own permission, redaction and queries; renderers expose all result states.',
|
|
1119
|
+
render: () => {
|
|
1120
|
+
const activity = [
|
|
1121
|
+
{
|
|
1122
|
+
id: 'a1',
|
|
1123
|
+
actor: 'Ngọc Linh',
|
|
1124
|
+
action: 'moved the order to Ready',
|
|
1125
|
+
datetime: '2026-09-08T14:30:00+07:00',
|
|
1126
|
+
timeLabel: '14:30 today',
|
|
1127
|
+
},
|
|
1128
|
+
{
|
|
1129
|
+
id: 'a2',
|
|
1130
|
+
actor: 'System',
|
|
1131
|
+
action: 'synchronized a protected value',
|
|
1132
|
+
datetime: '2026-09-08T14:25:00+07:00',
|
|
1133
|
+
timeLabel: '14:25 today',
|
|
1134
|
+
redacted: true,
|
|
1135
|
+
},
|
|
1136
|
+
];
|
|
1137
|
+
return (_jsx(Grid, { columns: 2, items: [
|
|
1138
|
+
_jsx(ActivityTimeline, { label: "Activity", items: activity }),
|
|
1139
|
+
_jsx(AuditLog, { label: "Audit log", items: activity }),
|
|
1140
|
+
] }));
|
|
1141
|
+
},
|
|
1142
|
+
},
|
|
1143
|
+
{
|
|
1144
|
+
id: 'attachments-media',
|
|
1145
|
+
name: 'Attachments and media',
|
|
1146
|
+
description: 'Storage URLs and mutations stay in the application; public components render authorized results.',
|
|
1147
|
+
render: () => (_jsx(Grid, { columns: 2, items: [
|
|
1148
|
+
_jsx(Attachments, { label: "Order attachments", items: [
|
|
1149
|
+
{ id: 'invoice', name: 'invoice-SO-1042.pdf', href: '/files/invoice', meta: '238 KB' },
|
|
1150
|
+
{ id: 'contract', name: 'Restricted contract', redacted: true },
|
|
1151
|
+
] }),
|
|
1152
|
+
_jsx(MediaGallery, { label: "Delivery media", items: [
|
|
1153
|
+
{ id: 'restricted', alt: '', redacted: true, caption: 'Permission required' },
|
|
1154
|
+
{
|
|
1155
|
+
id: 'proof',
|
|
1156
|
+
alt: 'Delivery proof placeholder',
|
|
1157
|
+
src: 'data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%22400%22 height=%22300%22%3E%3Crect width=%22400%22 height=%22300%22 fill=%22%23eef0fb%22/%3E%3Cpath d=%22M80 220l70-80 50 50 50-70 80 100%22 fill=%22none%22 stroke=%22%23566fd1%22 stroke-width=%2212%22/%3E%3C/svg%3E',
|
|
1158
|
+
caption: 'Delivery proof',
|
|
1159
|
+
},
|
|
1160
|
+
] }),
|
|
1161
|
+
] })),
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
id: 'canonical-recipes',
|
|
1165
|
+
name: 'Canonical page recipes',
|
|
1166
|
+
description: 'Worklist, analytical list, settings and master-detail vary slots—not page-pattern count.',
|
|
1167
|
+
render: () => (_jsx(Grid, { columns: 3, items: [
|
|
1168
|
+
_jsx(ContentCard, { title: "ListPage", body: "Worklist \u00B7 analytical list \u00B7 settings" }),
|
|
1169
|
+
_jsx(ContentCard, { title: "RecordPage", body: "Summary \u00B7 facts \u00B7 timeline \u00B7 attachments" }),
|
|
1170
|
+
_jsx(ContentCard, { title: "WorkspacePage", body: "Master-detail \u00B7 board \u00B7 schedule \u00B7 timeline canvas" }),
|
|
1171
|
+
] })),
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
id: 'canvas-recipes',
|
|
1175
|
+
name: 'Optional canvas recipes',
|
|
1176
|
+
description: 'Board, schedule and timeline keep spatial columns and local horizontal overflow.',
|
|
1177
|
+
render: () => (_jsx("div", { "data-pattern": "workspace", "data-workspace-mode": "canvas", children: _jsx(Grid, { columns: 3, items: [
|
|
1178
|
+
_jsx(ContentCard, { title: "Backlog", body: "SO-1047 \u00B7 SO-1048" }),
|
|
1179
|
+
_jsx(ContentCard, { title: "In progress", body: "SO-1042 \u00B7 SO-1043" }),
|
|
1180
|
+
_jsx(ContentCard, { title: "Done", body: "SO-1039 \u00B7 SO-1040" }),
|
|
1181
|
+
] }) })),
|
|
1182
|
+
},
|
|
1183
|
+
],
|
|
1184
|
+
},
|
|
1185
|
+
];
|
|
1186
|
+
//# sourceMappingURL=specimens.js.map
|