@kodffe/ui 0.0.0-stage → 0.10.1
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/dist/_virtual/_rolldown/runtime.js +11 -0
- package/dist/accordion/accordion.d.ts +44 -0
- package/dist/accordion/accordion.js +84 -0
- package/dist/accordion/accordion.js.map +1 -0
- package/dist/alert/alert.d.ts +17 -0
- package/dist/alert/alert.js +59 -0
- package/dist/alert/alert.js.map +1 -0
- package/dist/app-shell/app-footer.d.ts +29 -0
- package/dist/app-shell/app-footer.js +39 -0
- package/dist/app-shell/app-footer.js.map +1 -0
- package/dist/app-shell/app-shell-context.d.ts +10 -0
- package/dist/app-shell/app-shell-context.js +12 -0
- package/dist/app-shell/app-shell-context.js.map +1 -0
- package/dist/app-shell/app-shell.d.ts +42 -0
- package/dist/app-shell/app-shell.js +191 -0
- package/dist/app-shell/app-shell.js.map +1 -0
- package/dist/app-shell/floating-actions.d.ts +19 -0
- package/dist/app-shell/floating-actions.js +59 -0
- package/dist/app-shell/floating-actions.js.map +1 -0
- package/dist/app-shell/workspace-switcher.d.ts +25 -0
- package/dist/app-shell/workspace-switcher.js +82 -0
- package/dist/app-shell/workspace-switcher.js.map +1 -0
- package/dist/badge/badge.d.ts +19 -0
- package/dist/badge/badge.js +59 -0
- package/dist/badge/badge.js.map +1 -0
- package/dist/banner/banner.d.ts +22 -0
- package/dist/banner/banner.js +80 -0
- package/dist/banner/banner.js.map +1 -0
- package/dist/breadcrumbs/breadcrumbs.d.ts +18 -0
- package/dist/breadcrumbs/breadcrumbs.js +45 -0
- package/dist/breadcrumbs/breadcrumbs.js.map +1 -0
- package/dist/button/button.d.ts +38 -0
- package/dist/button/button.js +83 -0
- package/dist/button/button.js.map +1 -0
- package/dist/card/card.d.ts +159 -0
- package/dist/card/card.js +390 -0
- package/dist/card/card.js.map +1 -0
- package/dist/card/insight-card.d.ts +19 -0
- package/dist/card/insight-card.js +51 -0
- package/dist/card/insight-card.js.map +1 -0
- package/dist/card/integration-card.d.ts +19 -0
- package/dist/card/integration-card.js +70 -0
- package/dist/card/integration-card.js.map +1 -0
- package/dist/charts/charts.d.ts +75 -0
- package/dist/charts/charts.js +453 -0
- package/dist/charts/charts.js.map +1 -0
- package/dist/choice/choice.d.ts +39 -0
- package/dist/choice/choice.js +143 -0
- package/dist/choice/choice.js.map +1 -0
- package/dist/combobox/combobox.d.ts +46 -0
- package/dist/combobox/combobox.js +196 -0
- package/dist/combobox/combobox.js.map +1 -0
- package/dist/command-palette/command-palette.d.ts +35 -0
- package/dist/command-palette/command-palette.js +164 -0
- package/dist/command-palette/command-palette.js.map +1 -0
- package/dist/confirm-dialog/confirm-dialog.d.ts +37 -0
- package/dist/confirm-dialog/confirm-dialog.js +106 -0
- package/dist/confirm-dialog/confirm-dialog.js.map +1 -0
- package/dist/content/assistant.d.ts +86 -0
- package/dist/content/assistant.js +213 -0
- package/dist/content/assistant.js.map +1 -0
- package/dist/content/content.d.ts +45 -0
- package/dist/content/content.js +136 -0
- package/dist/content/content.js.map +1 -0
- package/dist/data-display/avatar-sizes.d.ts +8 -0
- package/dist/data-display/avatar-sizes.js +12 -0
- package/dist/data-display/avatar-sizes.js.map +1 -0
- package/dist/data-display/avatar.d.ts +21 -0
- package/dist/data-display/avatar.js +53 -0
- package/dist/data-display/avatar.js.map +1 -0
- package/dist/data-display/chip.d.ts +20 -0
- package/dist/data-display/chip.js +64 -0
- package/dist/data-display/chip.js.map +1 -0
- package/dist/data-display/code-block.d.ts +14 -0
- package/dist/data-display/code-block.js +50 -0
- package/dist/data-display/code-block.js.map +1 -0
- package/dist/data-display/data-display.d.ts +73 -0
- package/dist/data-display/data-display.js +227 -0
- package/dist/data-display/data-display.js.map +1 -0
- package/dist/data-display/insights.d.ts +120 -0
- package/dist/data-display/insights.js +220 -0
- package/dist/data-display/insights.js.map +1 -0
- package/dist/data-table/cells.d.ts +86 -0
- package/dist/data-table/cells.js +163 -0
- package/dist/data-table/cells.js.map +1 -0
- package/dist/data-table/data-table.d.ts +112 -0
- package/dist/data-table/data-table.js +558 -0
- package/dist/data-table/data-table.js.map +1 -0
- package/dist/date-picker/date-picker.d.ts +61 -0
- package/dist/date-picker/date-picker.js +309 -0
- package/dist/date-picker/date-picker.js.map +1 -0
- package/dist/drawer/drawer.d.ts +32 -0
- package/dist/drawer/drawer.js +72 -0
- package/dist/drawer/drawer.js.map +1 -0
- package/dist/empty-state/empty-state.d.ts +25 -0
- package/dist/empty-state/empty-state.js +78 -0
- package/dist/empty-state/empty-state.js.map +1 -0
- package/dist/error-state/error-state.d.ts +19 -0
- package/dist/error-state/error-state.js +56 -0
- package/dist/error-state/error-state.js.map +1 -0
- package/dist/event-calendar/calendar-logic.test.d.ts +1 -0
- package/dist/event-calendar/dates.d.ts +35 -0
- package/dist/event-calendar/dates.js +55 -0
- package/dist/event-calendar/dates.js.map +1 -0
- package/dist/event-calendar/event-calendar.d.ts +125 -0
- package/dist/event-calendar/event-calendar.js +795 -0
- package/dist/event-calendar/event-calendar.js.map +1 -0
- package/dist/event-calendar/event-details.d.ts +50 -0
- package/dist/event-calendar/event-details.js +124 -0
- package/dist/event-calendar/event-details.js.map +1 -0
- package/dist/event-calendar/layout.d.ts +48 -0
- package/dist/event-calendar/layout.js +55 -0
- package/dist/event-calendar/layout.js.map +1 -0
- package/dist/file-upload/file-upload.d.ts +70 -0
- package/dist/file-upload/file-upload.js +307 -0
- package/dist/file-upload/file-upload.js.map +1 -0
- package/dist/filters/filters.d.ts +48 -0
- package/dist/filters/filters.js +103 -0
- package/dist/filters/filters.js.map +1 -0
- package/dist/form-field/form-field.d.ts +39 -0
- package/dist/form-field/form-field.js +88 -0
- package/dist/form-field/form-field.js.map +1 -0
- package/dist/hover-card/hover-card.d.ts +15 -0
- package/dist/hover-card/hover-card.js +27 -0
- package/dist/hover-card/hover-card.js.map +1 -0
- package/dist/hover-card/person-hover-card.d.ts +26 -0
- package/dist/hover-card/person-hover-card.js +85 -0
- package/dist/hover-card/person-hover-card.js.map +1 -0
- package/dist/icon/icon-tile.d.ts +20 -0
- package/dist/icon/icon-tile.js +55 -0
- package/dist/icon/icon-tile.js.map +1 -0
- package/dist/icon/icon.d.ts +14 -0
- package/dist/icon/icon.js +28 -0
- package/dist/icon/icon.js.map +1 -0
- package/dist/icon/icons.generated.d.ts +358 -0
- package/dist/icon/icons.generated.js +362 -0
- package/dist/icon/icons.generated.js.map +1 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +88 -0
- package/dist/input/extra-inputs.d.ts +122 -0
- package/dist/input/extra-inputs.js +351 -0
- package/dist/input/extra-inputs.js.map +1 -0
- package/dist/input/field-styles.d.ts +5 -0
- package/dist/input/field-styles.js +14 -0
- package/dist/input/field-styles.js.map +1 -0
- package/dist/input/input.d.ts +50 -0
- package/dist/input/input.js +107 -0
- package/dist/input/input.js.map +1 -0
- package/dist/layout/layout.d.ts +41 -0
- package/dist/layout/layout.js +90 -0
- package/dist/layout/layout.js.map +1 -0
- package/dist/lib/control-styles.d.ts +9 -0
- package/dist/lib/control-styles.js +16 -0
- package/dist/lib/control-styles.js.map +1 -0
- package/dist/lib/cx.d.ts +2 -0
- package/dist/lib/cx.js +8 -0
- package/dist/lib/cx.js.map +1 -0
- package/dist/lib/glyphs.d.ts +13 -0
- package/dist/lib/glyphs.js +67 -0
- package/dist/lib/glyphs.js.map +1 -0
- package/dist/lib/segmented-styles.d.ts +8 -0
- package/dist/lib/segmented-styles.js +12 -0
- package/dist/lib/segmented-styles.js.map +1 -0
- package/dist/lib/select-on-arrow.d.ts +7 -0
- package/dist/lib/select-on-arrow.js +21 -0
- package/dist/lib/select-on-arrow.js.map +1 -0
- package/dist/lib/skip-link.d.ts +5 -0
- package/dist/lib/skip-link.js +13 -0
- package/dist/lib/skip-link.js.map +1 -0
- package/dist/lib/use-media-query.d.ts +4 -0
- package/dist/lib/use-media-query.js +15 -0
- package/dist/lib/use-media-query.js.map +1 -0
- package/dist/lists/lists.d.ts +76 -0
- package/dist/lists/lists.js +133 -0
- package/dist/lists/lists.js.map +1 -0
- package/dist/locale-switch/locale-switch.d.ts +29 -0
- package/dist/locale-switch/locale-switch.js +62 -0
- package/dist/locale-switch/locale-switch.js.map +1 -0
- package/dist/logo/logo.d.ts +31 -0
- package/dist/logo/logo.js +157 -0
- package/dist/logo/logo.js.map +1 -0
- package/dist/logo/product-logo.d.ts +19 -0
- package/dist/logo/product-logo.js +46 -0
- package/dist/logo/product-logo.js.map +1 -0
- package/dist/marketing/marketing.d.ts +176 -0
- package/dist/marketing/marketing.js +451 -0
- package/dist/marketing/marketing.js.map +1 -0
- package/dist/marketing/newsletter-form.d.ts +21 -0
- package/dist/marketing/newsletter-form.js +100 -0
- package/dist/marketing/newsletter-form.js.map +1 -0
- package/dist/mascot/mascot.d.ts +28 -0
- package/dist/mascot/mascot.js +28 -0
- package/dist/mascot/mascot.js.map +1 -0
- package/dist/mascot/mascots.generated.d.ts +284 -0
- package/dist/mascot/mascots.generated.js +287 -0
- package/dist/mascot/mascots.generated.js.map +1 -0
- package/dist/master-detail/master-detail.d.ts +30 -0
- package/dist/master-detail/master-detail.js +71 -0
- package/dist/master-detail/master-detail.js.map +1 -0
- package/dist/menu/account-menu.d.ts +44 -0
- package/dist/menu/account-menu.js +78 -0
- package/dist/menu/account-menu.js.map +1 -0
- package/dist/menu/context-menu.d.ts +31 -0
- package/dist/menu/context-menu.js +111 -0
- package/dist/menu/context-menu.js.map +1 -0
- package/dist/menu/dropdown-menu.d.ts +49 -0
- package/dist/menu/dropdown-menu.js +152 -0
- package/dist/menu/dropdown-menu.js.map +1 -0
- package/dist/menu/menu-styles.d.ts +8 -0
- package/dist/menu/menu-styles.js +6 -0
- package/dist/menu/menu-styles.js.map +1 -0
- package/dist/menu/menubar.d.ts +31 -0
- package/dist/menu/menubar.js +125 -0
- package/dist/menu/menubar.js.map +1 -0
- package/dist/modal/modal.d.ts +34 -0
- package/dist/modal/modal.js +58 -0
- package/dist/modal/modal.js.map +1 -0
- package/dist/notification-center/notification-center.d.ts +51 -0
- package/dist/notification-center/notification-center.js +244 -0
- package/dist/notification-center/notification-center.js.map +1 -0
- package/dist/otp-input/otp-input.d.ts +23 -0
- package/dist/otp-input/otp-input.js +61 -0
- package/dist/otp-input/otp-input.js.map +1 -0
- package/dist/overlay/overlay.d.ts +53 -0
- package/dist/overlay/overlay.js +103 -0
- package/dist/overlay/overlay.js.map +1 -0
- package/dist/page-header/page-header.d.ts +55 -0
- package/dist/page-header/page-header.js +114 -0
- package/dist/page-header/page-header.js.map +1 -0
- package/dist/page-header/record-headers.d.ts +51 -0
- package/dist/page-header/record-headers.js +134 -0
- package/dist/page-header/record-headers.js.map +1 -0
- package/dist/page-header/section-header.d.ts +21 -0
- package/dist/page-header/section-header.js +44 -0
- package/dist/page-header/section-header.js.map +1 -0
- package/dist/page-navigation/page-navigation.d.ts +59 -0
- package/dist/page-navigation/page-navigation.js +136 -0
- package/dist/page-navigation/page-navigation.js.map +1 -0
- package/dist/pagination/pagination.d.ts +28 -0
- package/dist/pagination/pagination.js +102 -0
- package/dist/pagination/pagination.js.map +1 -0
- package/dist/phone-input/phone-input.d.ts +34 -0
- package/dist/phone-input/phone-input.js +171 -0
- package/dist/phone-input/phone-input.js.map +1 -0
- package/dist/popover/popover.d.ts +23 -0
- package/dist/popover/popover.js +40 -0
- package/dist/popover/popover.js.map +1 -0
- package/dist/progress/progress.d.ts +21 -0
- package/dist/progress/progress.js +49 -0
- package/dist/progress/progress.js.map +1 -0
- package/dist/segmented-control/segmented-control.d.ts +32 -0
- package/dist/segmented-control/segmented-control.js +29 -0
- package/dist/segmented-control/segmented-control.js.map +1 -0
- package/dist/select/select.d.ts +48 -0
- package/dist/select/select.js +136 -0
- package/dist/select/select.js.map +1 -0
- package/dist/settings/permission-matrix.d.ts +29 -0
- package/dist/settings/permission-matrix.js +101 -0
- package/dist/settings/permission-matrix.js.map +1 -0
- package/dist/settings/settings-row.d.ts +32 -0
- package/dist/settings/settings-row.js +63 -0
- package/dist/settings/settings-row.js.map +1 -0
- package/dist/side-nav/side-nav.d.ts +36 -0
- package/dist/side-nav/side-nav.js +123 -0
- package/dist/side-nav/side-nav.js.map +1 -0
- package/dist/site-header/site-header.d.ts +32 -0
- package/dist/site-header/site-header.js +99 -0
- package/dist/site-header/site-header.js.map +1 -0
- package/dist/skeleton/skeleton.d.ts +16 -0
- package/dist/skeleton/skeleton.js +19 -0
- package/dist/skeleton/skeleton.js.map +1 -0
- package/dist/slider/slider.d.ts +15 -0
- package/dist/slider/slider.js +48 -0
- package/dist/slider/slider.js.map +1 -0
- package/dist/spinner/spinner.d.ts +15 -0
- package/dist/spinner/spinner.js +42 -0
- package/dist/spinner/spinner.js.map +1 -0
- package/dist/stepper/step-dots.d.ts +16 -0
- package/dist/stepper/step-dots.js +26 -0
- package/dist/stepper/step-dots.js.map +1 -0
- package/dist/stepper/stepper.d.ts +26 -0
- package/dist/stepper/stepper.js +113 -0
- package/dist/stepper/stepper.js.map +1 -0
- package/dist/tabs/tabs.d.ts +31 -0
- package/dist/tabs/tabs.js +66 -0
- package/dist/tabs/tabs.js.map +1 -0
- package/dist/templates/app-templates.d.ts +126 -0
- package/dist/templates/app-templates.js +153 -0
- package/dist/templates/app-templates.js.map +1 -0
- package/dist/templates/site-templates.d.ts +49 -0
- package/dist/templates/site-templates.js +110 -0
- package/dist/templates/site-templates.js.map +1 -0
- package/dist/toast/toast-store.d.ts +54 -0
- package/dist/toast/toast-store.js +49 -0
- package/dist/toast/toast-store.js.map +1 -0
- package/dist/toast/toaster.d.ts +15 -0
- package/dist/toast/toaster.js +124 -0
- package/dist/toast/toaster.js.map +1 -0
- package/dist/tooltip/tooltip.d.ts +29 -0
- package/dist/tooltip/tooltip.js +54 -0
- package/dist/tooltip/tooltip.js.map +1 -0
- package/package.json +88 -3
- package/styles.css +521 -0
- package/README.md +0 -3
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx as e } from "../lib/cx.js";
|
|
3
|
+
import { AppShell as t } from "../app-shell/app-shell.js";
|
|
4
|
+
import { Fragment as n, jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
//#region src/templates/app-templates.tsx
|
|
6
|
+
function a({ logo: e, role: a, notifications: o, account: s, workspace: c, nav: l, footer: u, floating: d, children: f, className: p }) {
|
|
7
|
+
return /* @__PURE__ */ i(n, { children: [/* @__PURE__ */ r(t, {
|
|
8
|
+
layout: "topbar",
|
|
9
|
+
brand: e,
|
|
10
|
+
className: p,
|
|
11
|
+
header: /* @__PURE__ */ i(n, { children: [
|
|
12
|
+
a && /* @__PURE__ */ r("span", {
|
|
13
|
+
className: "hidden sm:inline-flex",
|
|
14
|
+
children: a
|
|
15
|
+
}),
|
|
16
|
+
o,
|
|
17
|
+
s
|
|
18
|
+
] }),
|
|
19
|
+
nav: l || c ? /* @__PURE__ */ i("div", {
|
|
20
|
+
className: "grid gap-4",
|
|
21
|
+
children: [c, l]
|
|
22
|
+
}) : void 0,
|
|
23
|
+
footer: u,
|
|
24
|
+
children: f
|
|
25
|
+
}), d] });
|
|
26
|
+
}
|
|
27
|
+
var o = "grid min-w-0 content-start gap-6";
|
|
28
|
+
function s({ header: t, metrics: n, main: a, aside: s, children: c, className: l }) {
|
|
29
|
+
return /* @__PURE__ */ i("div", {
|
|
30
|
+
className: e(o, l),
|
|
31
|
+
children: [
|
|
32
|
+
t,
|
|
33
|
+
n && /* @__PURE__ */ r("div", {
|
|
34
|
+
className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4",
|
|
35
|
+
children: n
|
|
36
|
+
}),
|
|
37
|
+
(a || s) && /* @__PURE__ */ i("div", {
|
|
38
|
+
className: "grid gap-6 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]",
|
|
39
|
+
children: [a && /* @__PURE__ */ r("div", {
|
|
40
|
+
className: o,
|
|
41
|
+
children: a
|
|
42
|
+
}), s && /* @__PURE__ */ r("div", {
|
|
43
|
+
className: o,
|
|
44
|
+
children: s
|
|
45
|
+
})]
|
|
46
|
+
}),
|
|
47
|
+
c
|
|
48
|
+
]
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function c({ header: t, toolbar: n, children: r, className: a }) {
|
|
52
|
+
return /* @__PURE__ */ i("div", {
|
|
53
|
+
className: e(o, a),
|
|
54
|
+
children: [
|
|
55
|
+
t,
|
|
56
|
+
n,
|
|
57
|
+
r
|
|
58
|
+
]
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function l({ header: t, filters: n, metrics: a, children: s, className: c }) {
|
|
62
|
+
return /* @__PURE__ */ i("div", {
|
|
63
|
+
className: e(o, c),
|
|
64
|
+
children: [
|
|
65
|
+
t,
|
|
66
|
+
n,
|
|
67
|
+
a && /* @__PURE__ */ r("div", {
|
|
68
|
+
className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4",
|
|
69
|
+
children: a
|
|
70
|
+
}),
|
|
71
|
+
/* @__PURE__ */ r("div", {
|
|
72
|
+
className: "grid gap-6 lg:grid-cols-2",
|
|
73
|
+
children: s
|
|
74
|
+
})
|
|
75
|
+
]
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function u({ header: t, calendar: n, summaryHeader: a, summary: s, className: c }) {
|
|
79
|
+
return /* @__PURE__ */ i("div", {
|
|
80
|
+
className: e(o, c),
|
|
81
|
+
children: [
|
|
82
|
+
t,
|
|
83
|
+
n,
|
|
84
|
+
(a || s) && /* @__PURE__ */ i("section", {
|
|
85
|
+
className: "grid gap-4",
|
|
86
|
+
children: [a, s && /* @__PURE__ */ r("div", {
|
|
87
|
+
className: "grid gap-6 lg:grid-cols-2",
|
|
88
|
+
children: s
|
|
89
|
+
})]
|
|
90
|
+
})
|
|
91
|
+
]
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function d({ header: t, nav: n, tabs: a, children: s, className: c }) {
|
|
95
|
+
return /* @__PURE__ */ i("div", {
|
|
96
|
+
className: e(o, c),
|
|
97
|
+
children: [t, /* @__PURE__ */ i("div", {
|
|
98
|
+
className: "grid gap-6 md:grid-cols-[var(--spacing-subnav)_minmax(0,1fr)]",
|
|
99
|
+
children: [/* @__PURE__ */ r("div", {
|
|
100
|
+
className: "md:sticky md:top-[calc(var(--spacing-appbar)+1.5rem)] md:self-start",
|
|
101
|
+
children: n
|
|
102
|
+
}), /* @__PURE__ */ i("div", {
|
|
103
|
+
className: e(o, "max-w-form"),
|
|
104
|
+
children: [a, s]
|
|
105
|
+
})]
|
|
106
|
+
})]
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function f({ header: t, children: n, className: r }) {
|
|
110
|
+
return /* @__PURE__ */ i("div", {
|
|
111
|
+
className: e(o, r),
|
|
112
|
+
children: [t, n]
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function p({ back: t, profile: n, tabs: a, children: s, aside: c, className: l }) {
|
|
116
|
+
return /* @__PURE__ */ i("div", {
|
|
117
|
+
className: e(o, l),
|
|
118
|
+
children: [
|
|
119
|
+
t,
|
|
120
|
+
n,
|
|
121
|
+
a,
|
|
122
|
+
/* @__PURE__ */ i("div", {
|
|
123
|
+
className: e("grid gap-6", !!c && "lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]"),
|
|
124
|
+
children: [/* @__PURE__ */ r("div", {
|
|
125
|
+
className: o,
|
|
126
|
+
children: s
|
|
127
|
+
}), c && /* @__PURE__ */ r("div", {
|
|
128
|
+
className: o,
|
|
129
|
+
children: c
|
|
130
|
+
})]
|
|
131
|
+
})
|
|
132
|
+
]
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function m({ header: t, children: n, aside: a, className: s }) {
|
|
136
|
+
return /* @__PURE__ */ i("div", {
|
|
137
|
+
className: e(o, "mx-auto w-full max-w-5xl", s),
|
|
138
|
+
children: [t, /* @__PURE__ */ i("div", {
|
|
139
|
+
className: e("grid gap-6", !!a && "lg:grid-cols-[minmax(0,3fr)_minmax(0,2fr)]"),
|
|
140
|
+
children: [/* @__PURE__ */ r("div", {
|
|
141
|
+
className: o,
|
|
142
|
+
children: n
|
|
143
|
+
}), a && /* @__PURE__ */ r("div", {
|
|
144
|
+
className: o,
|
|
145
|
+
children: a
|
|
146
|
+
})]
|
|
147
|
+
})]
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
//#endregion
|
|
151
|
+
export { m as AccountPage, a as AppLayout, u as CalendarPage, s as DashboardPage, c as ListPage, f as MasterDetailPage, p as ProfilePage, l as ReportPage, d as SettingsPage };
|
|
152
|
+
|
|
153
|
+
//# sourceMappingURL=app-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-templates.js","names":["_Fragment","AppLayout","Fragment","AppShell","logo","role","notifications","account","nav","workspace","floating","stack","DashboardPage","cx","className","header","metrics","main","aside","children","ListPage","toolbar","ReportPage","filters","CalendarPage","calendar","summaryHeader","summary","SettingsPage","tabs","MasterDetailPage","ProfilePage","back","profile","AccountPage"],"sources":["../../src/templates/app-templates.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { AppShell } from '../app-shell/app-shell';\n\n/*\n * Dashboard templates (ADR-0013). They only arrange slots: every product passes its own components\n * (PageHeader, MetricCard, DataTable…), so pages share one shape without sharing data or logic.\n */\n\n/* ---------------- AppLayout ---------------- */\n\nexport interface AppLayoutProps {\n /** `ProductLogo` in a link to the dashboard home. */\n logo: ReactNode;\n /** The user's role (\"Administrator\"), shown as a badge in the top bar from 640px. */\n role?: ReactNode;\n /** Notifications button (`NotificationCenter`). */\n notifications?: ReactNode;\n /** `AccountMenu`. */\n account: ReactNode;\n /** `WorkspaceSwitcher` above the navigation. */\n workspace?: ReactNode;\n /** `SideNav`. Omit for pages without a sidebar (account settings). */\n nav?: ReactNode;\n /** `AppFooter`. */\n footer?: ReactNode;\n /** `FloatingActions` (the assistant button). */\n floating?: ReactNode;\n children: ReactNode;\n className?: string;\n}\n\n/**\n * The one dashboard layout for every product: top bar (logo, role, notifications, account), sidebar (workspace +\n * navigation), content and a slim footer, plus the floating assistant. Built on `AppShell layout=\"topbar\"`.\n */\nexport function AppLayout({\n logo,\n role,\n notifications,\n account,\n workspace,\n nav,\n footer,\n floating,\n children,\n className,\n}: AppLayoutProps) {\n return (\n <>\n <AppShell\n layout=\"topbar\"\n brand={logo}\n className={className}\n header={\n <>\n {role && <span className=\"hidden sm:inline-flex\">{role}</span>}\n {notifications}\n {account}\n </>\n }\n nav={\n nav || workspace ? (\n <div className=\"grid gap-4\">\n {workspace}\n {nav}\n </div>\n ) : undefined\n }\n footer={footer}\n >\n {children}\n </AppShell>\n {floating}\n </>\n );\n}\n\n/* ---------------- Page templates ---------------- */\n\nconst stack = 'grid min-w-0 content-start gap-6';\n\nexport interface DashboardPageProps {\n /**\n * `PageHeader`. With page tabs, render the header (with its `TabsList`) above and this page inside the active\n * `TabsContent`, without `header`, so each tab controls a real panel.\n */\n header?: ReactNode;\n /** A row of `MetricCard`s. */\n metrics?: ReactNode;\n /** The wide column (2/3): charts and lists. */\n main?: ReactNode;\n /** The narrow column (1/3): tasks, activity. */\n aside?: ReactNode;\n /** Full-width content below the columns. */\n children?: ReactNode;\n className?: string;\n}\n\n/** Overview: header, a row of metrics, then a 2/3 + 1/3 grid of cards and full-width content. */\nexport function DashboardPage({ header, metrics, main, aside, children, className }: DashboardPageProps) {\n return (\n <div className={cx(stack, className)}>\n {header}\n {metrics && <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">{metrics}</div>}\n {(main || aside) && (\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]\">\n {main && <div className={stack}>{main}</div>}\n {aside && <div className={stack}>{aside}</div>}\n </div>\n )}\n {children}\n </div>\n );\n}\n\nexport interface ListPageProps {\n header?: ReactNode;\n /** Underline `Tabs` or a `SectionHeader` above the table. */\n toolbar?: ReactNode;\n /** The `DataTable`. */\n children: ReactNode;\n className?: string;\n}\n\n/** A list of records: header, optional section header or tabs, the table. */\nexport function ListPage({ header, toolbar, children, className }: ListPageProps) {\n return (\n <div className={cx(stack, className)}>\n {header}\n {toolbar}\n {children}\n </div>\n );\n}\n\nexport interface ReportPageProps {\n header?: ReactNode;\n /** `FilterBar`. */\n filters?: ReactNode;\n metrics?: ReactNode;\n /** Charts, two per row from 1024px. */\n children: ReactNode;\n className?: string;\n}\n\n/** Reports: header, filters, a row of metrics and charts in a two-column grid. */\nexport function ReportPage({ header, filters, metrics, children, className }: ReportPageProps) {\n return (\n <div className={cx(stack, className)}>\n {header}\n {filters}\n {metrics && <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">{metrics}</div>}\n <div className=\"grid gap-6 lg:grid-cols-2\">{children}</div>\n </div>\n );\n}\n\nexport interface CalendarPageProps {\n /** `PageHeader` (with tabs when the calendar is one view of a module). */\n header?: ReactNode;\n /** `EventCalendar`, with its side panel in `aside`. */\n calendar: ReactNode;\n /** Summary under the calendar: a heading row with period presets (`SectionHeader` + `SegmentedControl`). */\n summaryHeader?: ReactNode;\n /** Summary cards (`StatGrid`, `RankedList`, charts), two per row from 1024px. */\n summary?: ReactNode;\n className?: string;\n}\n\n/** Calendar (ADR-0016): header, the calendar with its side panel, and a full-width summary below. */\nexport function CalendarPage({ header, calendar, summaryHeader, summary, className }: CalendarPageProps) {\n return (\n <div className={cx(stack, className)}>\n {header}\n {calendar}\n {(summaryHeader || summary) && (\n <section className=\"grid gap-4\">\n {summaryHeader}\n {summary && <div className=\"grid gap-6 lg:grid-cols-2\">{summary}</div>}\n </section>\n )}\n </div>\n );\n}\n\nexport interface SettingsPageProps {\n header?: ReactNode;\n /** Secondary navigation (`SideNav appearance=\"solid\"`), `--kf-subnav-width` wide. */\n nav: ReactNode;\n /** Sub-tabs above the form column (Kudibot's third navigation level). */\n tabs?: ReactNode;\n /** Cards with `SettingsRow` / `FormField`, in a column limited to the form width. */\n children: ReactNode;\n className?: string;\n}\n\n/** Settings: header, a secondary navigation and a form column of cards. Below 768px the navigation comes first. */\nexport function SettingsPage({ header, nav, tabs, children, className }: SettingsPageProps) {\n return (\n <div className={cx(stack, className)}>\n {header}\n <div className=\"grid gap-6 md:grid-cols-[var(--spacing-subnav)_minmax(0,1fr)]\">\n <div className=\"md:sticky md:top-[calc(var(--spacing-appbar)+1.5rem)] md:self-start\">{nav}</div>\n <div className={cx(stack, 'max-w-form')}>\n {tabs}\n {children}\n </div>\n </div>\n </div>\n );\n}\n\nexport interface MasterDetailPageProps {\n header?: ReactNode;\n /** `MasterDetail`. */\n children: ReactNode;\n className?: string;\n}\n\n/** Configuration of grouped records (clients and projects): header and a `MasterDetail`. */\nexport function MasterDetailPage({ header, children, className }: MasterDetailPageProps) {\n return (\n <div className={cx(stack, className)}>\n {header}\n {children}\n </div>\n );\n}\n\nexport interface ProfilePageProps {\n /** A back link (\"‹ People\"). */\n back?: ReactNode;\n /** `ProfileHeader` (or `EntityHeader` for companies). */\n profile: ReactNode;\n /** Underline `Tabs` for the profile's sections. */\n tabs?: ReactNode;\n children: ReactNode;\n /** A side column (about me, contact, teams) from 1024px. */\n aside?: ReactNode;\n className?: string;\n}\n\n/** A person's or a company's page: back link, profile header, tabs, then cards with an optional side column. */\nexport function ProfilePage({ back, profile, tabs, children, aside, className }: ProfilePageProps) {\n return (\n <div className={cx(stack, className)}>\n {back}\n {profile}\n {tabs}\n <div className={cx('grid gap-6', !!aside && 'lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]')}>\n <div className={stack}>{children}</div>\n {aside && <div className={stack}>{aside}</div>}\n </div>\n </div>\n );\n}\n\nexport interface AccountPageProps {\n /** `PageHeader` with the user's avatar as `media`. */\n header: ReactNode;\n /** Forms (profile, password, notifications). */\n children: ReactNode;\n /** A side list (organizations, devices). */\n aside?: ReactNode;\n className?: string;\n}\n\n/**\n * The user's account across organizations: a narrow container with forms and a side list. Use it inside\n * `AppLayout` without `nav` (top bar only).\n */\nexport function AccountPage({ header, children, aside, className }: AccountPageProps) {\n return (\n <div className={cx(stack, 'mx-auto w-full max-w-5xl', className)}>\n {header}\n <div className={cx('grid gap-6', !!aside && 'lg:grid-cols-[minmax(0,3fr)_minmax(0,2fr)]')}>\n <div className={stack}>{children}</div>\n {aside && <div className={stack}>{aside}</div>}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAsCA,SAAgBC,EAAU,EACxB,SACA,SACA,kBACA,YACA,cACA,QACA,WACA,aACA,aACA,gBACiB;CACjB,OACE,kBAAAD,GAAA,EAAA,UAAA,CACE,kBAACG,GAAD;EACE,QAAO;EACP,OAAOC;EACI;EACX,QACE,kBAAAJ,GAAA,EAAA,UAAA;GACGK,KAAQ,kBAAC,QAAD;IAAM,WAAU;IAAyB,UAAAA;GAAW,CAAA;GAC5DC;GACAC;EACD,EAAA,CAAA;EAEJ,KACEC,KAAOC,IACL,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACGA,GACAD,CACE;EACH,CAAA,IAAA,KAAA;EAEE;EAEP;CACO,CAAA,GACTE,CACD,EAAA,CAAA;AAEN;AAIA,IAAMC,IAAQ;AAoBd,SAAgBC,EAAc,EAAE,WAAQ,YAAS,SAAM,UAAO,aAAU,gBAAiC;CACvG,OACE,kBAAC,OAAD;EAAK,WAAWC,EAAGF,GAAOG,CAAS;EAAnC,UAAA;GACGC;GACAC,KAAW,kBAAC,OAAD;IAAK,WAAU;IAA4C,UAAAA;GAAa,CAAA;IAClFC,KAAQC,MACR,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACGD,KAAQ,kBAAC,OAAD;KAAK,WAAWN;KAAQ,UAAAM;IAAU,CAAA,GAC1CC,KAAS,kBAAC,OAAD;KAAK,WAAWP;KAAQ,UAAAO;IAAW,CAAA,CAC1C;;GAENC;EACE;;AAET;AAYA,SAAgBC,EAAS,EAAE,WAAQ,YAAS,aAAU,gBAA4B;CAChF,OACE,kBAAC,OAAD;EAAK,WAAWP,EAAGF,GAAOG,CAAS;EAAnC,UAAA;GACGC;GACAM;GACAF;EACE;;AAET;AAaA,SAAgBG,EAAW,EAAE,WAAQ,YAAS,YAAS,aAAU,gBAA8B;CAC7F,OACE,kBAAC,OAAD;EAAK,WAAWT,EAAGF,GAAOG,CAAS;EAAnC,UAAA;GACGC;GACAQ;GACAP,KAAW,kBAAC,OAAD;IAAK,WAAU;IAA4C,UAAAA;GAAa,CAAA;GACpF,kBAAC,OAAD;IAAK,WAAU;IAA6B;GAAc,CAAA;EACvD;;AAET;AAeA,SAAgBQ,EAAa,EAAE,WAAQ,aAAU,kBAAe,YAAS,gBAAgC;CACvG,OACE,kBAAC,OAAD;EAAK,WAAWX,EAAGF,GAAOG,CAAS;EAAnC,UAAA;GACGC;GACAU;IACCC,KAAiBC,MACjB,kBAAC,WAAD;IAAS,WAAU;IAAnB,UAAA,CACGD,GACAC,KAAW,kBAAC,OAAD;KAAK,WAAU;KAA6B,UAAAA;IAAa,CAAA,CAC9D;;EAER;;AAET;AAcA,SAAgBC,EAAa,EAAE,WAAQ,QAAK,SAAM,aAAU,gBAAgC;CAC1F,OACE,kBAAC,OAAD;EAAK,WAAWf,EAAGF,GAAOG,CAAS;EAAnC,UAAA,CACGC,GACD,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAAC,OAAD;IAAK,WAAU;IAAuE,UAAAP;GAAS,CAAA,GAC/F,kBAAC,OAAD;IAAK,WAAWK,EAAGF,GAAO,YAAY;IAAtC,UAAA,CACGkB,GACAV,CACE;GACF,CAAA,CAAA;EACF,CAAA,CAAA;;AAET;AAUA,SAAgBW,EAAiB,EAAE,WAAQ,aAAU,gBAAoC;CACvF,OACE,kBAAC,OAAD;EAAK,WAAWjB,EAAGF,GAAOG,CAAS;EAAnC,UAAA,CACGC,GACAI,CACE;;AAET;AAgBA,SAAgBY,EAAY,EAAE,SAAM,YAAS,SAAM,aAAU,UAAO,gBAA+B;CACjG,OACE,kBAAC,OAAD;EAAK,WAAWlB,EAAGF,GAAOG,CAAS;EAAnC,UAAA;GACGkB;GACAC;GACAJ;GACD,kBAAC,OAAD;IAAK,WAAWhB,EAAG,cAAc,CAAC,CAACK,KAAS,4CAA4C;IAAxF,UAAA,CACE,kBAAC,OAAD;KAAK,WAAWP;KAAQ;IAAc,CAAA,GACrCO,KAAS,kBAAC,OAAD;KAAK,WAAWP;KAAQ,UAAAO;IAAW,CAAA,CAC1C;;EACF;;AAET;AAgBA,SAAgBgB,EAAY,EAAE,WAAQ,aAAU,UAAO,gBAA+B;CACpF,OACE,kBAAC,OAAD;EAAK,WAAWrB,EAAGF,GAAO,4BAA4BG,CAAS;EAA/D,UAAA,CACGC,GACD,kBAAC,OAAD;GAAK,WAAWF,EAAG,cAAc,CAAC,CAACK,KAAS,4CAA4C;GAAxF,UAAA,CACE,kBAAC,OAAD;IAAK,WAAWP;IAAQ;GAAc,CAAA,GACrCO,KAAS,kBAAC,OAAD;IAAK,WAAWP;IAAQ,UAAAO;GAAW,CAAA,CAC1C;EACF,CAAA,CAAA;;AAET"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
interface FrameProps {
|
|
3
|
+
/** `SiteHeader`. */
|
|
4
|
+
header: ReactNode;
|
|
5
|
+
/** `SiteFooter`. */
|
|
6
|
+
footer?: ReactNode;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
labels?: {
|
|
9
|
+
skip?: string;
|
|
10
|
+
};
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Home, pricing and landing pages: `SiteHeader`, stacked `Section`s, `SiteFooter`, and a skip link. */
|
|
14
|
+
export declare function MarketingLayout({ header, footer, children, labels, className }: FrameProps): import("react").JSX.Element;
|
|
15
|
+
export interface ArticleLayoutProps extends FrameProps {
|
|
16
|
+
/** `PageHero size="compact"` with the title and `meta`. */
|
|
17
|
+
hero: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
/** Terms, privacy and support articles: a compact hero and one narrow `Prose` column. */
|
|
20
|
+
export declare function ArticleLayout({ header, footer, hero, children, labels, className }: ArticleLayoutProps): import("react").JSX.Element;
|
|
21
|
+
export interface DocsLayoutProps extends FrameProps {
|
|
22
|
+
/** The docs `SideNav` (about 240px), sticky from 1024px; a "Contents" disclosure on smaller screens. */
|
|
23
|
+
nav: ReactNode;
|
|
24
|
+
/** `TableOfContents` for long articles, shown from 1280px. */
|
|
25
|
+
toc?: ReactNode;
|
|
26
|
+
/** `PrevNextNav` at the end of the article. */
|
|
27
|
+
pagination?: ReactNode;
|
|
28
|
+
labels?: {
|
|
29
|
+
skip?: string;
|
|
30
|
+
contents?: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Docs: a sticky navigation, the article column (`Prose`), an optional table of contents and Previous / Next. */
|
|
34
|
+
export declare function DocsLayout({ header, footer, nav, toc, pagination, children, labels, className, }: DocsLayoutProps): import("react").JSX.Element;
|
|
35
|
+
export interface AuthLayoutProps {
|
|
36
|
+
/** `SiteHeader variant="minimal"` (logo and, e.g., a "Sign in" link). */
|
|
37
|
+
header: ReactNode;
|
|
38
|
+
/** The form card's content: title, fields, main action. */
|
|
39
|
+
children: ReactNode;
|
|
40
|
+
/** Links under the card ("Don't have an account? Sign up", legal). */
|
|
41
|
+
below?: ReactNode;
|
|
42
|
+
labels?: {
|
|
43
|
+
skip?: string;
|
|
44
|
+
};
|
|
45
|
+
className?: string;
|
|
46
|
+
}
|
|
47
|
+
/** Log in, sign up and password reset: a gradient strip, a minimal header and one centred card, no footer. */
|
|
48
|
+
export declare function AuthLayout({ header, children, below, labels, className }: AuthLayoutProps): import("react").JSX.Element;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { cx as e } from "../lib/cx.js";
|
|
2
|
+
import { Glyph as t } from "../lib/glyphs.js";
|
|
3
|
+
import { SkipLink as n } from "../lib/skip-link.js";
|
|
4
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
//#region src/templates/site-templates.tsx
|
|
6
|
+
function a({ header: t, footer: a, children: o, labels: s = {}, className: c }) {
|
|
7
|
+
return /* @__PURE__ */ i("div", {
|
|
8
|
+
className: e("flex min-h-dvh flex-col bg-bg font-sans text-fg", c),
|
|
9
|
+
children: [
|
|
10
|
+
/* @__PURE__ */ r(n, { label: s.skip ?? "Skip to content" }),
|
|
11
|
+
t,
|
|
12
|
+
/* @__PURE__ */ r("main", {
|
|
13
|
+
id: "kf-main",
|
|
14
|
+
tabIndex: -1,
|
|
15
|
+
className: "flex-1 focus:outline-none",
|
|
16
|
+
children: o
|
|
17
|
+
}),
|
|
18
|
+
a
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function o({ header: e, footer: t, hero: n, children: o, labels: s, className: c }) {
|
|
23
|
+
return /* @__PURE__ */ i(a, {
|
|
24
|
+
header: e,
|
|
25
|
+
footer: t,
|
|
26
|
+
labels: s,
|
|
27
|
+
className: c,
|
|
28
|
+
children: [n, /* @__PURE__ */ r("div", {
|
|
29
|
+
className: "mx-auto w-full max-w-article px-gutter pb-section-md",
|
|
30
|
+
children: o
|
|
31
|
+
})]
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function s({ header: n, footer: o, nav: s, toc: c, pagination: l, children: u, labels: d = {}, className: f }) {
|
|
35
|
+
return /* @__PURE__ */ r(a, {
|
|
36
|
+
header: n,
|
|
37
|
+
footer: o,
|
|
38
|
+
labels: d,
|
|
39
|
+
className: f,
|
|
40
|
+
children: /* @__PURE__ */ i("div", {
|
|
41
|
+
className: e("mx-auto grid w-full max-w-app gap-8 px-gutter py-8 lg:grid-cols-[var(--spacing-sidebar)_minmax(0,1fr)] lg:py-12", !!c && "xl:grid-cols-[var(--spacing-sidebar)_minmax(0,1fr)_14rem]"),
|
|
42
|
+
children: [
|
|
43
|
+
/* @__PURE__ */ i("details", {
|
|
44
|
+
className: "group rounded-lg border border-border bg-surface lg:hidden",
|
|
45
|
+
children: [/* @__PURE__ */ i("summary", {
|
|
46
|
+
className: "flex cursor-pointer list-none items-center justify-between px-4 py-3 font-semibold focus-visible:outline-3 focus-visible:outline-focus",
|
|
47
|
+
children: [d.contents ?? "Contents", /* @__PURE__ */ r(t, {
|
|
48
|
+
name: "chevron-down",
|
|
49
|
+
size: 16,
|
|
50
|
+
className: "transition-transform group-open:rotate-180 motion-reduce:transition-none"
|
|
51
|
+
})]
|
|
52
|
+
}), /* @__PURE__ */ r("div", {
|
|
53
|
+
className: "border-t border-border p-3",
|
|
54
|
+
children: s
|
|
55
|
+
})]
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ r("aside", {
|
|
58
|
+
className: "hidden lg:block",
|
|
59
|
+
children: /* @__PURE__ */ r("div", {
|
|
60
|
+
className: "sticky top-24 max-h-[calc(100dvh-7rem)] overflow-y-auto",
|
|
61
|
+
children: s
|
|
62
|
+
})
|
|
63
|
+
}),
|
|
64
|
+
/* @__PURE__ */ i("div", {
|
|
65
|
+
className: "grid min-w-0 content-start gap-10",
|
|
66
|
+
children: [/* @__PURE__ */ r("article", {
|
|
67
|
+
className: "min-w-0",
|
|
68
|
+
children: u
|
|
69
|
+
}), l]
|
|
70
|
+
}),
|
|
71
|
+
c && /* @__PURE__ */ r("div", {
|
|
72
|
+
className: "hidden xl:block",
|
|
73
|
+
children: c
|
|
74
|
+
})
|
|
75
|
+
]
|
|
76
|
+
})
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function c({ header: t, children: a, below: o, labels: s = {}, className: c }) {
|
|
80
|
+
return /* @__PURE__ */ i("div", {
|
|
81
|
+
className: e("flex min-h-dvh flex-col bg-bg font-sans text-fg", c),
|
|
82
|
+
children: [
|
|
83
|
+
/* @__PURE__ */ r(n, { label: s.skip ?? "Skip to content" }),
|
|
84
|
+
/* @__PURE__ */ r("div", {
|
|
85
|
+
"aria-hidden": "true",
|
|
86
|
+
className: "h-1.5 bg-gradient-brand-vivid"
|
|
87
|
+
}),
|
|
88
|
+
t,
|
|
89
|
+
/* @__PURE__ */ r("main", {
|
|
90
|
+
id: "kf-main",
|
|
91
|
+
tabIndex: -1,
|
|
92
|
+
className: "grid flex-1 place-items-center px-gutter py-10 focus:outline-none",
|
|
93
|
+
children: /* @__PURE__ */ i("div", {
|
|
94
|
+
className: "grid w-full max-w-[30rem] gap-6",
|
|
95
|
+
children: [/* @__PURE__ */ r("div", {
|
|
96
|
+
className: "rounded-xl border border-border bg-surface p-6 shadow-raised sm:p-8",
|
|
97
|
+
children: a
|
|
98
|
+
}), o && /* @__PURE__ */ r("div", {
|
|
99
|
+
className: "text-center text-sm text-fg-muted",
|
|
100
|
+
children: o
|
|
101
|
+
})]
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
]
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
export { o as ArticleLayout, c as AuthLayout, s as DocsLayout, a as MarketingLayout };
|
|
109
|
+
|
|
110
|
+
//# sourceMappingURL=site-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-templates.js","names":["MarketingLayout","cx","className","SkipLink","labels","header","footer","ArticleLayout","hero","DocsLayout","toc","Glyph","nav","pagination","AuthLayout","below"],"sources":["../../src/templates/site-templates.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { Glyph } from '../lib/glyphs';\nimport { SkipLink } from '../lib/skip-link';\n\n/* Public-page templates (ADR-0013): they arrange slots, every site brings its own header, footer and content. */\n\ninterface FrameProps {\n /** `SiteHeader`. */\n header: ReactNode;\n /** `SiteFooter`. */\n footer?: ReactNode;\n children: ReactNode;\n labels?: { skip?: string };\n className?: string;\n}\n\n/* ---------------- MarketingLayout ---------------- */\n\n/** Home, pricing and landing pages: `SiteHeader`, stacked `Section`s, `SiteFooter`, and a skip link. */\nexport function MarketingLayout({ header, footer, children, labels = {}, className }: FrameProps) {\n return (\n <div className={cx('flex min-h-dvh flex-col bg-bg font-sans text-fg', className)}>\n <SkipLink label={labels.skip ?? 'Skip to content'} />\n {header}\n <main id=\"kf-main\" tabIndex={-1} className=\"flex-1 focus:outline-none\">\n {children}\n </main>\n {footer}\n </div>\n );\n}\n\n/* ---------------- ArticleLayout ---------------- */\n\nexport interface ArticleLayoutProps extends FrameProps {\n /** `PageHero size=\"compact\"` with the title and `meta`. */\n hero: ReactNode;\n}\n\n/** Terms, privacy and support articles: a compact hero and one narrow `Prose` column. */\nexport function ArticleLayout({ header, footer, hero, children, labels, className }: ArticleLayoutProps) {\n return (\n <MarketingLayout header={header} footer={footer} labels={labels} className={className}>\n {hero}\n <div className=\"mx-auto w-full max-w-article px-gutter pb-section-md\">{children}</div>\n </MarketingLayout>\n );\n}\n\n/* ---------------- DocsLayout ---------------- */\n\nexport interface DocsLayoutProps extends FrameProps {\n /** The docs `SideNav` (about 240px), sticky from 1024px; a \"Contents\" disclosure on smaller screens. */\n nav: ReactNode;\n /** `TableOfContents` for long articles, shown from 1280px. */\n toc?: ReactNode;\n /** `PrevNextNav` at the end of the article. */\n pagination?: ReactNode;\n labels?: { skip?: string; contents?: string };\n}\n\n/** Docs: a sticky navigation, the article column (`Prose`), an optional table of contents and Previous / Next. */\nexport function DocsLayout({\n header,\n footer,\n nav,\n toc,\n pagination,\n children,\n labels = {},\n className,\n}: DocsLayoutProps) {\n return (\n <MarketingLayout header={header} footer={footer} labels={labels} className={className}>\n <div\n className={cx(\n 'mx-auto grid w-full max-w-app gap-8 px-gutter py-8 lg:grid-cols-[var(--spacing-sidebar)_minmax(0,1fr)] lg:py-12',\n !!toc && 'xl:grid-cols-[var(--spacing-sidebar)_minmax(0,1fr)_14rem]',\n )}\n >\n {/* Native disclosure on phones and tablets: works without JavaScript; always open from 1024px. */}\n <details className=\"group rounded-lg border border-border bg-surface lg:hidden\">\n <summary className=\"flex cursor-pointer list-none items-center justify-between px-4 py-3 font-semibold focus-visible:outline-3 focus-visible:outline-focus\">\n {labels.contents ?? 'Contents'}\n <Glyph\n name=\"chevron-down\"\n size={16}\n className=\"transition-transform group-open:rotate-180 motion-reduce:transition-none\"\n />\n </summary>\n <div className=\"border-t border-border p-3\">{nav}</div>\n </details>\n <aside className=\"hidden lg:block\">\n <div className=\"sticky top-24 max-h-[calc(100dvh-7rem)] overflow-y-auto\">{nav}</div>\n </aside>\n <div className=\"grid min-w-0 content-start gap-10\">\n <article className=\"min-w-0\">{children}</article>\n {pagination}\n </div>\n {toc && <div className=\"hidden xl:block\">{toc}</div>}\n </div>\n </MarketingLayout>\n );\n}\n\n/* ---------------- AuthLayout ---------------- */\n\nexport interface AuthLayoutProps {\n /** `SiteHeader variant=\"minimal\"` (logo and, e.g., a \"Sign in\" link). */\n header: ReactNode;\n /** The form card's content: title, fields, main action. */\n children: ReactNode;\n /** Links under the card (\"Don't have an account? Sign up\", legal). */\n below?: ReactNode;\n labels?: { skip?: string };\n className?: string;\n}\n\n/** Log in, sign up and password reset: a gradient strip, a minimal header and one centred card, no footer. */\nexport function AuthLayout({ header, children, below, labels = {}, className }: AuthLayoutProps) {\n return (\n <div className={cx('flex min-h-dvh flex-col bg-bg font-sans text-fg', className)}>\n <SkipLink label={labels.skip ?? 'Skip to content'} />\n <div aria-hidden=\"true\" className=\"h-1.5 bg-gradient-brand-vivid\" />\n {header}\n <main id=\"kf-main\" tabIndex={-1} className=\"grid flex-1 place-items-center px-gutter py-10 focus:outline-none\">\n <div className=\"grid w-full max-w-[30rem] gap-6\">\n <div className=\"rounded-xl border border-border bg-surface p-6 shadow-raised sm:p-8\">{children}</div>\n {below && <div className=\"text-center text-sm text-fg-muted\">{below}</div>}\n </div>\n </main>\n </div>\n );\n}\n"],"mappings":";;;;;AAoBA,SAAgBA,EAAgB,EAAE,WAAQ,WAAQ,aAAU,YAAS,CAAC,GAAG,gBAAyB;CAChG,OACE,kBAAC,OAAD;EAAK,WAAWC,EAAG,mDAAmDC,CAAS;EAA/E,UAAA;GACE,kBAACC,GAAD,EAAU,OAAOC,EAAO,QAAQ,kBAAoB,CAAA;GACnDC;GACD,kBAAC,QAAD;IAAM,IAAG;IAAU,UAAU;IAAI,WAAU;IACxC;GACG,CAAA;GACLC;EACE;;AAET;AAUA,SAAgBC,EAAc,EAAE,WAAQ,WAAQ,SAAM,aAAU,WAAQ,gBAAiC;CACvG,OACE,kBAACP,GAAD;EAAyB;EAAgB;EAAgB;EAAmB;EAA5E,UAAA,CACGQ,GACD,kBAAC,OAAD;GAAK,WAAU;GAAwD;EAAc,CAAA,CACtE;;AAErB;AAeA,SAAgBC,EAAW,EACzB,WACA,WACA,QACA,QACA,eACA,aACA,YAAS,CAAC,GACV,gBACkB;CAClB,OACE,kBAACT,GAAD;EAAyB;EAAgB;EAAgB;EAAmB;EAC1E,UAAA,kBAAC,OAAD;GACE,WAAWC,EACT,mHACA,CAAC,CAACS,KAAO,2DACX;GAJF,UAAA;IAOE,kBAAC,WAAD;KAAS,WAAU;KAAnB,UAAA,CACE,kBAAC,WAAD;MAAS,WAAU;MAAnB,UAAA,CACGN,EAAO,YAAY,YACpB,kBAACO,GAAD;OACE,MAAK;OACL,MAAM;OACN,WAAU;MACX,CAAA,CACM;KACT,CAAA,GAAA,kBAAC,OAAD;MAAK,WAAU;MAA8B,UAAAC;KAAS,CAAA,CAC/C;;IACT,kBAAC,SAAD;KAAO,WAAU;KACf,UAAA,kBAAC,OAAD;MAAK,WAAU;MAA2D,UAAAA;KAAS,CAAA;IAC9E,CAAA;IACP,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,WAAD;MAAS,WAAU;MAAW;KAAkB,CAAA,GAC/CC,CACE;;IACJH,KAAO,kBAAC,OAAD;KAAK,WAAU;KAAmB,UAAAA;IAAS,CAAA;GAChD;;CACU,CAAA;AAErB;AAgBA,SAAgBI,EAAW,EAAE,WAAQ,aAAU,UAAO,YAAS,CAAC,GAAG,gBAA8B;CAC/F,OACE,kBAAC,OAAD;EAAK,WAAWb,EAAG,mDAAmDC,CAAS;EAA/E,UAAA;GACE,kBAACC,GAAD,EAAU,OAAOC,EAAO,QAAQ,kBAAoB,CAAA;GACpD,kBAAC,OAAD;IAAK,eAAY;IAAO,WAAU;GAAiC,CAAA;GAClEC;GACD,kBAAC,QAAD;IAAM,IAAG;IAAU,UAAU;IAAI,WAAU;IACzC,UAAA,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,OAAD;MAAK,WAAU;MAAuE;KAAc,CAAA,GACnGU,KAAS,kBAAC,OAAD;MAAK,WAAU;MAAqC,UAAAA;KAAW,CAAA,CACtE;;GACD,CAAA;EACH;;AAET"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export type ToastVariant = 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'loading';
|
|
3
|
+
export interface ToastAction {
|
|
4
|
+
label: string;
|
|
5
|
+
onClick: () => void;
|
|
6
|
+
/** Describes how to do the same without the toast, for screen readers (e.g. "Undo from the History page"). Defaults to `label`. */
|
|
7
|
+
altText?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ToastOptions {
|
|
10
|
+
/** Pass an id to update an existing toast instead of adding a new one. */
|
|
11
|
+
id?: string;
|
|
12
|
+
description?: ReactNode;
|
|
13
|
+
action?: ToastAction;
|
|
14
|
+
/** Milliseconds before auto-dismiss. `Infinity` keeps it open. Defaults: 5000, danger 8000, loading Infinity. */
|
|
15
|
+
duration?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ToastData extends Omit<ToastOptions, 'id'> {
|
|
18
|
+
id: string;
|
|
19
|
+
variant: ToastVariant;
|
|
20
|
+
title: ReactNode;
|
|
21
|
+
open: boolean;
|
|
22
|
+
}
|
|
23
|
+
type Listener = () => void;
|
|
24
|
+
export declare function subscribe(listener: Listener): () => boolean;
|
|
25
|
+
export declare function getToasts(): ToastData[];
|
|
26
|
+
export declare function getServerToasts(): ToastData[];
|
|
27
|
+
/** Closes one toast (or all when `id` is omitted); it is removed after its exit animation. */
|
|
28
|
+
declare function dismiss(id?: string): void;
|
|
29
|
+
type Message<T> = ReactNode | ((value: T) => ReactNode);
|
|
30
|
+
/**
|
|
31
|
+
* Shows a toast. Render one `<Toaster />` near the root of the app.
|
|
32
|
+
*
|
|
33
|
+
* ```ts
|
|
34
|
+
* toast.success('Workflow saved');
|
|
35
|
+
* toast.danger('Sync failed', { action: { label: 'Retry', onClick: retry } });
|
|
36
|
+
* toast.promise(save(), { loading: 'Saving…', success: 'Saved', error: (e) => `Failed: ${e.message}` });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare const toast: ((title: ReactNode, options?: ToastOptions) => string) & {
|
|
40
|
+
success: (title: ReactNode, options?: ToastOptions) => string;
|
|
41
|
+
warning: (title: ReactNode, options?: ToastOptions) => string;
|
|
42
|
+
danger: (title: ReactNode, options?: ToastOptions) => string;
|
|
43
|
+
info: (title: ReactNode, options?: ToastOptions) => string;
|
|
44
|
+
loading: (title: ReactNode, options?: ToastOptions) => string;
|
|
45
|
+
dismiss: typeof dismiss;
|
|
46
|
+
/** One toast that goes loading → success or danger. Returns the original promise. */
|
|
47
|
+
promise<T>(promise: Promise<T>, messages: {
|
|
48
|
+
loading: ReactNode;
|
|
49
|
+
success: Message<T>;
|
|
50
|
+
error: Message<unknown>;
|
|
51
|
+
description?: ReactNode;
|
|
52
|
+
}): Promise<T>;
|
|
53
|
+
};
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region src/toast/toast-store.ts
|
|
2
|
+
var e = [], t = /* @__PURE__ */ new Set(), n = 0, r = 300;
|
|
3
|
+
function i() {
|
|
4
|
+
for (let e of t) e();
|
|
5
|
+
}
|
|
6
|
+
function a(e) {
|
|
7
|
+
return t.add(e), () => t.delete(e);
|
|
8
|
+
}
|
|
9
|
+
function o() {
|
|
10
|
+
return e;
|
|
11
|
+
}
|
|
12
|
+
var s = [];
|
|
13
|
+
function c() {
|
|
14
|
+
return s;
|
|
15
|
+
}
|
|
16
|
+
function l(t, r, a = {}) {
|
|
17
|
+
let { id: o, ...s } = a, c = o ?? `kf-toast-${++n}`, l = e.find((e) => e.id === c), u = {
|
|
18
|
+
id: c,
|
|
19
|
+
variant: t,
|
|
20
|
+
title: r,
|
|
21
|
+
open: !0,
|
|
22
|
+
...s
|
|
23
|
+
};
|
|
24
|
+
return e = l ? e.map((e) => e.id === c ? u : e) : [...e, u], i(), c;
|
|
25
|
+
}
|
|
26
|
+
function u(t) {
|
|
27
|
+
e = e.map((e) => t === void 0 || e.id === t ? {
|
|
28
|
+
...e,
|
|
29
|
+
open: !1
|
|
30
|
+
} : e), i(), setTimeout(() => {
|
|
31
|
+
e = e.filter((e) => e.open), i();
|
|
32
|
+
}, r);
|
|
33
|
+
}
|
|
34
|
+
var d = (e, t) => typeof e == "function" ? e(t) : e, f = Object.assign((e, t) => l("neutral", e, t), {
|
|
35
|
+
success: (e, t) => l("success", e, t),
|
|
36
|
+
warning: (e, t) => l("warning", e, t),
|
|
37
|
+
danger: (e, t) => l("danger", e, t),
|
|
38
|
+
info: (e, t) => l("info", e, t),
|
|
39
|
+
loading: (e, t) => l("loading", e, t),
|
|
40
|
+
dismiss: u,
|
|
41
|
+
promise(e, t) {
|
|
42
|
+
let n = l("loading", t.loading, { description: t.description });
|
|
43
|
+
return e.then((e) => l("success", d(t.success, e), { id: n }), (e) => l("danger", d(t.error, e), { id: n })), e;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
//#endregion
|
|
47
|
+
export { c as getServerToasts, o as getToasts, a as subscribe, f as toast };
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=toast-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-store.js","names":["toasts","listeners","counter","EXIT_MS","emit","l","subscribe","listener","getToasts","EMPTY","getServerToasts","upsert","given","rest","options","id","existing","t","next","dismiss","resolve","m","value","toast","title","messages","promise","error"],"sources":["../../src/toast/toast-store.ts"],"sourcesContent":["import type { ReactNode } from 'react';\n\nexport type ToastVariant = 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'loading';\n\nexport interface ToastAction {\n label: string;\n onClick: () => void;\n /** Describes how to do the same without the toast, for screen readers (e.g. \"Undo from the History page\"). Defaults to `label`. */\n altText?: string;\n}\n\nexport interface ToastOptions {\n /** Pass an id to update an existing toast instead of adding a new one. */\n id?: string;\n description?: ReactNode;\n action?: ToastAction;\n /** Milliseconds before auto-dismiss. `Infinity` keeps it open. Defaults: 5000, danger 8000, loading Infinity. */\n duration?: number;\n}\n\nexport interface ToastData extends Omit<ToastOptions, 'id'> {\n id: string;\n variant: ToastVariant;\n title: ReactNode;\n open: boolean;\n}\n\ntype Listener = () => void;\n\nlet toasts: ToastData[] = [];\nconst listeners = new Set<Listener>();\nlet counter = 0;\n\nconst EXIT_MS = 300;\n\nfunction emit() {\n for (const l of listeners) l();\n}\n\nexport function subscribe(listener: Listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nexport function getToasts() {\n return toasts;\n}\n\nconst EMPTY: ToastData[] = [];\nexport function getServerToasts() {\n return EMPTY;\n}\n\nfunction upsert(variant: ToastVariant, title: ReactNode, options: ToastOptions = {}): string {\n const { id: given, ...rest } = options;\n const id = given ?? `kf-toast-${++counter}`;\n const existing = toasts.find((t) => t.id === id);\n // Updating replaces content and timing; drop fields the new call does not set.\n const next: ToastData = { id, variant, title, open: true, ...rest };\n toasts = existing ? toasts.map((t) => (t.id === id ? next : t)) : [...toasts, next];\n emit();\n return id;\n}\n\n/** Closes one toast (or all when `id` is omitted); it is removed after its exit animation. */\nfunction dismiss(id?: string) {\n toasts = toasts.map((t) => (id === undefined || t.id === id ? { ...t, open: false } : t));\n emit();\n setTimeout(() => {\n toasts = toasts.filter((t) => t.open);\n emit();\n }, EXIT_MS);\n}\n\ntype Message<T> = ReactNode | ((value: T) => ReactNode);\nconst resolve = <T,>(m: Message<T>, value: T): ReactNode => (typeof m === 'function' ? (m as (v: T) => ReactNode)(value) : m);\n\n/**\n * Shows a toast. Render one `<Toaster />` near the root of the app.\n *\n * ```ts\n * toast.success('Workflow saved');\n * toast.danger('Sync failed', { action: { label: 'Retry', onClick: retry } });\n * toast.promise(save(), { loading: 'Saving…', success: 'Saved', error: (e) => `Failed: ${e.message}` });\n * ```\n */\nexport const toast = Object.assign((title: ReactNode, options?: ToastOptions) => upsert('neutral', title, options), {\n success: (title: ReactNode, options?: ToastOptions) => upsert('success', title, options),\n warning: (title: ReactNode, options?: ToastOptions) => upsert('warning', title, options),\n danger: (title: ReactNode, options?: ToastOptions) => upsert('danger', title, options),\n info: (title: ReactNode, options?: ToastOptions) => upsert('info', title, options),\n loading: (title: ReactNode, options?: ToastOptions) => upsert('loading', title, options),\n dismiss,\n /** One toast that goes loading → success or danger. Returns the original promise. */\n promise<T>(\n promise: Promise<T>,\n messages: { loading: ReactNode; success: Message<T>; error: Message<unknown>; description?: ReactNode },\n ): Promise<T> {\n const id = upsert('loading', messages.loading, { description: messages.description });\n promise.then(\n (value) => upsert('success', resolve(messages.success, value), { id }),\n (error: unknown) => upsert('danger', resolve(messages.error, error), { id }),\n );\n return promise;\n },\n});\n"],"mappings":";AA6BA,IAAIA,IAAsB,CAAC,GACrBC,oBAAY,IAAI,IAAc,GAChCC,IAAU,GAERC,IAAU;AAEhB,SAASC,IAAO;CACd,KAAK,IAAMC,KAAKJ,GAAW,EAAE;AAC/B;AAEA,SAAgBK,EAAU,GAAoB;CAE5C,OADAL,EAAU,IAAIM,CAAQ,SACTN,EAAU,OAAOM,CAAQ;AACxC;AAEA,SAAgBC,IAAY;CAC1B,OAAOR;AACT;AAEA,IAAMS,IAAqB,CAAC;AAC5B,SAAgBC,IAAkB;CAChC,OAAOD;AACT;AAEA,SAASE,EAAO,GAAuB,GAAkB,IAAwB,CAAC,GAAW;CAC3F,IAAM,EAAE,IAAIC,GAAO,GAAGC,MAASC,GACzBC,IAAKH,KAAS,YAAY,EAAEV,KAC5Bc,IAAWhB,EAAO,MAAM,MAAMiB,EAAE,OAAOF,CAAE,GAEzCG,IAAkB;EAAE;EAAI;EAAS;EAAO,MAAM;EAAM,GAAGL;CAAK;CAGlE,OAFA,IAASG,IAAWhB,EAAO,KAAK,MAAOiB,EAAE,OAAOF,IAAKG,IAAOD,CAAE,IAAI,CAAC,GAAGjB,GAAQkB,CAAI,GAClFd,EAAK,GACEW;AACT;AAGA,SAASI,EAAQ,GAAa;CAG5B,AAFA,IAASnB,EAAO,KAAK,MAAOe,MAAO,KAAA,KAAaE,EAAE,OAAOF,IAAK;EAAE,GAAGE;EAAG,MAAM;CAAM,IAAIA,CAAE,GACxFb,EAAK,GACL,iBAAiB;EAEf,AADA,IAASJ,EAAO,QAAQ,MAAMiB,EAAE,IAAI,GACpCb,EAAK;CACP,GAAGD,CAAO;AACZ;AAGA,IAAMiB,KAAe,GAAe,MAAyB,OAAOC,KAAM,aAAcA,EAA0BC,CAAK,IAAID,GAW9GE,IAAQ,OAAO,QAAQ,GAAkB,MAA2BZ,EAAO,WAAWa,GAAOV,CAAO,GAAG;CAClH,UAAU,GAAkB,MAA2BH,EAAO,WAAWa,GAAOV,CAAO;CACvF,UAAU,GAAkB,MAA2BH,EAAO,WAAWa,GAAOV,CAAO;CACvF,SAAS,GAAkB,MAA2BH,EAAO,UAAUa,GAAOV,CAAO;CACrF,OAAO,GAAkB,MAA2BH,EAAO,QAAQa,GAAOV,CAAO;CACjF,UAAU,GAAkB,MAA2BH,EAAO,WAAWa,GAAOV,CAAO;CACvF;CAEA,QACE,GACA,GACY;EACZ,IAAMC,IAAKJ,EAAO,WAAWc,EAAS,SAAS,EAAE,aAAaA,EAAS,YAAY,CAAC;EAKpF,OAJAC,EAAQ,MACL,MAAUf,EAAO,WAAWS,EAAQK,EAAS,SAASH,CAAK,GAAG,EAAE,MAAG,CAAC,IACpE,MAAmBX,EAAO,UAAUS,EAAQK,EAAS,OAAOE,CAAK,GAAG,EAAE,MAAG,CAAC,CAC7E,GACOD;CACT;AACF,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface ToasterProps {
|
|
2
|
+
/** Maximum toasts on screen; the rest wait in the queue. */
|
|
3
|
+
max?: number;
|
|
4
|
+
/** Accessible name of the notifications region (translate it). `{hotkey}` is replaced by the shortcut. */
|
|
5
|
+
label?: string;
|
|
6
|
+
/** Keyboard shortcut that moves focus to the toasts. */
|
|
7
|
+
hotkey?: string[];
|
|
8
|
+
closeLabel?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Renders the toasts created with `toast()`. Mount once near the app root.
|
|
13
|
+
* Desktop: top-right, swipe right to dismiss. Mobile: bottom, full width, swipe down.
|
|
14
|
+
*/
|
|
15
|
+
export declare function Toaster({ max, label, hotkey, closeLabel, className }: ToasterProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx as e } from "../lib/cx.js";
|
|
3
|
+
import { Icon as t } from "../icon/icon.js";
|
|
4
|
+
import { Spinner as n } from "../spinner/spinner.js";
|
|
5
|
+
import { Button as r } from "../button/button.js";
|
|
6
|
+
import { DESKTOP_QUERY as i, useMediaQuery as a } from "../lib/use-media-query.js";
|
|
7
|
+
import { getServerToasts as o, getToasts as s, subscribe as c, toast as l } from "./toast-store.js";
|
|
8
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
9
|
+
import { useSyncExternalStore as f } from "react";
|
|
10
|
+
import * as p from "@radix-ui/react-toast";
|
|
11
|
+
//#region src/toast/toaster.tsx
|
|
12
|
+
var m = {
|
|
13
|
+
success: {
|
|
14
|
+
name: "accept",
|
|
15
|
+
className: "text-success-icon"
|
|
16
|
+
},
|
|
17
|
+
warning: {
|
|
18
|
+
name: "warning",
|
|
19
|
+
className: "text-warning-icon"
|
|
20
|
+
},
|
|
21
|
+
danger: {
|
|
22
|
+
name: "error",
|
|
23
|
+
className: "text-danger-icon"
|
|
24
|
+
},
|
|
25
|
+
info: {
|
|
26
|
+
name: "info",
|
|
27
|
+
className: "text-info-icon"
|
|
28
|
+
}
|
|
29
|
+
}, h = {
|
|
30
|
+
neutral: "before:bg-border",
|
|
31
|
+
loading: "before:bg-primary",
|
|
32
|
+
success: "before:bg-success-icon",
|
|
33
|
+
warning: "before:bg-warning-icon",
|
|
34
|
+
danger: "before:bg-danger-icon",
|
|
35
|
+
info: "before:bg-info-icon"
|
|
36
|
+
}, g = {
|
|
37
|
+
neutral: 5e3,
|
|
38
|
+
success: 5e3,
|
|
39
|
+
info: 5e3,
|
|
40
|
+
warning: 6e3,
|
|
41
|
+
danger: 8e3,
|
|
42
|
+
loading: Infinity
|
|
43
|
+
};
|
|
44
|
+
function _({ max: t = 3, label: n = "Notifications ({hotkey})", hotkey: r = ["F8"], closeLabel: l = "Dismiss", className: m }) {
|
|
45
|
+
let h = f(c, s, o), g = a(i), _ = h.slice(0, t);
|
|
46
|
+
return /* @__PURE__ */ d(p.Provider, {
|
|
47
|
+
swipeDirection: g ? "right" : "down",
|
|
48
|
+
label: n.replace(" ({hotkey})", ""),
|
|
49
|
+
children: [_.map((e) => /* @__PURE__ */ u(v, {
|
|
50
|
+
data: e,
|
|
51
|
+
closeLabel: l
|
|
52
|
+
}, e.id)), /* @__PURE__ */ u(p.Viewport, {
|
|
53
|
+
hotkey: r,
|
|
54
|
+
label: n,
|
|
55
|
+
className: e("fixed inset-x-0 bottom-0 z-[60] m-0 flex list-none flex-col gap-2 p-4 outline-none", "pb-[max(1rem,env(safe-area-inset-bottom))]", "sm:top-0 sm:right-0 sm:bottom-auto sm:left-auto sm:w-[26rem] sm:flex-col-reverse sm:pt-[max(1rem,env(safe-area-inset-top))]", m)
|
|
56
|
+
})]
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function v({ data: i, closeLabel: a }) {
|
|
60
|
+
let { id: o, variant: s, title: c, description: f, action: _, open: v } = i, y = m[s];
|
|
61
|
+
return /* @__PURE__ */ d(p.Root, {
|
|
62
|
+
open: v,
|
|
63
|
+
onOpenChange: (e) => !e && l.dismiss(o),
|
|
64
|
+
duration: i.duration ?? g[s],
|
|
65
|
+
type: s === "danger" ? "foreground" : "background",
|
|
66
|
+
className: e("kf-toast relative flex items-start gap-3 overflow-hidden rounded-md border border-border bg-surface py-3.5 pr-3 pl-5 font-sans text-fg shadow-overlay", "before:absolute before:inset-y-0 before:left-0 before:w-1 before:content-['']", h[s]),
|
|
67
|
+
children: [
|
|
68
|
+
s === "loading" ? /* @__PURE__ */ u(n, {
|
|
69
|
+
size: 22,
|
|
70
|
+
className: "mt-px shrink-0 text-primary"
|
|
71
|
+
}) : y && /* @__PURE__ */ u(t, {
|
|
72
|
+
name: y.name,
|
|
73
|
+
size: 24,
|
|
74
|
+
className: e("mt-px", y.className)
|
|
75
|
+
}),
|
|
76
|
+
/* @__PURE__ */ d("div", {
|
|
77
|
+
className: "min-w-0 flex-1 py-0.5",
|
|
78
|
+
children: [
|
|
79
|
+
/* @__PURE__ */ u(p.Title, {
|
|
80
|
+
className: "text-[15px] leading-snug font-semibold",
|
|
81
|
+
children: c
|
|
82
|
+
}),
|
|
83
|
+
f && /* @__PURE__ */ u(p.Description, {
|
|
84
|
+
className: "mt-0.5 text-sm text-fg-muted",
|
|
85
|
+
children: f
|
|
86
|
+
}),
|
|
87
|
+
_ && /* @__PURE__ */ u(p.Action, {
|
|
88
|
+
asChild: !0,
|
|
89
|
+
altText: _.altText ?? _.label,
|
|
90
|
+
children: /* @__PURE__ */ u(r, {
|
|
91
|
+
size: "sm",
|
|
92
|
+
variant: "secondary",
|
|
93
|
+
className: "mt-2.5",
|
|
94
|
+
onClick: _.onClick,
|
|
95
|
+
children: _.label
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
]
|
|
99
|
+
}),
|
|
100
|
+
/* @__PURE__ */ u(p.Close, {
|
|
101
|
+
"aria-label": a,
|
|
102
|
+
className: e("grid size-8 shrink-0 cursor-pointer place-items-center rounded-full border-0 bg-transparent text-fg-muted", "hover:bg-surface-muted hover:text-fg focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus"),
|
|
103
|
+
children: /* @__PURE__ */ u("svg", {
|
|
104
|
+
viewBox: "0 0 24 24",
|
|
105
|
+
width: "16",
|
|
106
|
+
height: "16",
|
|
107
|
+
"aria-hidden": "true",
|
|
108
|
+
focusable: "false",
|
|
109
|
+
children: /* @__PURE__ */ u("path", {
|
|
110
|
+
d: "M6 6l12 12M18 6L6 18",
|
|
111
|
+
stroke: "currentColor",
|
|
112
|
+
strokeWidth: "2.25",
|
|
113
|
+
strokeLinecap: "round",
|
|
114
|
+
fill: "none"
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
]
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
export { _ as Toaster };
|
|
123
|
+
|
|
124
|
+
//# sourceMappingURL=toaster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toaster.js","names":["RadixToast","ICONS","ACCENT","DEFAULT_DURATION","Toaster","toasts","useSyncExternalStore","subscribe","getToasts","getServerToasts","desktop","useMediaQuery","DESKTOP_QUERY","visible","max","label","ToastItem","t","cx","className","data","icon","variant","next","toast","id","Spinner","Icon","title","description","action","Button","closeLabel"],"sources":["../../src/toast/toaster.tsx"],"sourcesContent":["'use client';\n\nimport * as RadixToast from '@radix-ui/react-toast';\nimport { useSyncExternalStore } from 'react';\nimport { cx } from '../lib/cx';\nimport { DESKTOP_QUERY, useMediaQuery } from '../lib/use-media-query';\nimport { Spinner } from '../spinner/spinner';\nimport { Icon, type IconName } from '../icon/icon';\nimport { Button } from '../button/button';\nimport { getServerToasts, getToasts, subscribe, toast, type ToastData, type ToastVariant } from './toast-store';\n\nconst ICONS: Partial<Record<ToastVariant, { name: IconName; className: string }>> = {\n success: { name: 'accept', className: 'text-success-icon' },\n warning: { name: 'warning', className: 'text-warning-icon' },\n danger: { name: 'error', className: 'text-danger-icon' },\n info: { name: 'info', className: 'text-info-icon' },\n};\n\nconst ACCENT: Record<ToastVariant, string> = {\n neutral: 'before:bg-border',\n loading: 'before:bg-primary',\n success: 'before:bg-success-icon',\n warning: 'before:bg-warning-icon',\n danger: 'before:bg-danger-icon',\n info: 'before:bg-info-icon',\n};\n\nconst DEFAULT_DURATION: Record<ToastVariant, number> = {\n neutral: 5000,\n success: 5000,\n info: 5000,\n warning: 6000,\n danger: 8000,\n loading: Infinity,\n};\n\nexport interface ToasterProps {\n /** Maximum toasts on screen; the rest wait in the queue. */\n max?: number;\n /** Accessible name of the notifications region (translate it). `{hotkey}` is replaced by the shortcut. */\n label?: string;\n /** Keyboard shortcut that moves focus to the toasts. */\n hotkey?: string[];\n closeLabel?: string;\n className?: string;\n}\n\n/**\n * Renders the toasts created with `toast()`. Mount once near the app root.\n * Desktop: top-right, swipe right to dismiss. Mobile: bottom, full width, swipe down.\n */\nexport function Toaster({ max = 3, label = 'Notifications ({hotkey})', hotkey = ['F8'], closeLabel = 'Dismiss', className }: ToasterProps) {\n const toasts = useSyncExternalStore(subscribe, getToasts, getServerToasts);\n const desktop = useMediaQuery(DESKTOP_QUERY);\n const visible = toasts.slice(0, max);\n\n return (\n <RadixToast.Provider swipeDirection={desktop ? 'right' : 'down'} label={label.replace(' ({hotkey})', '')}>\n {visible.map((t) => (\n <ToastItem key={t.id} data={t} closeLabel={closeLabel} />\n ))}\n <RadixToast.Viewport\n hotkey={hotkey}\n label={label}\n className={cx(\n 'fixed inset-x-0 bottom-0 z-[60] m-0 flex list-none flex-col gap-2 p-4 outline-none',\n 'pb-[max(1rem,env(safe-area-inset-bottom))]',\n 'sm:top-0 sm:right-0 sm:bottom-auto sm:left-auto sm:w-[26rem] sm:flex-col-reverse sm:pt-[max(1rem,env(safe-area-inset-top))]',\n className,\n )}\n />\n </RadixToast.Provider>\n );\n}\n\nfunction ToastItem({ data, closeLabel }: { data: ToastData; closeLabel: string }) {\n const { id, variant, title, description, action, open } = data;\n const icon = ICONS[variant];\n return (\n <RadixToast.Root\n open={open}\n onOpenChange={(next) => !next && toast.dismiss(id)}\n duration={data.duration ?? DEFAULT_DURATION[variant]}\n type={variant === 'danger' ? 'foreground' : 'background'}\n className={cx(\n 'kf-toast relative flex items-start gap-3 overflow-hidden rounded-md border border-border bg-surface py-3.5 pr-3 pl-5 font-sans text-fg shadow-overlay',\n \"before:absolute before:inset-y-0 before:left-0 before:w-1 before:content-['']\",\n ACCENT[variant],\n )}\n >\n {variant === 'loading' ? (\n <Spinner size={22} className=\"mt-px shrink-0 text-primary\" />\n ) : (\n icon && <Icon name={icon.name} size={24} className={cx('mt-px', icon.className)} />\n )}\n <div className=\"min-w-0 flex-1 py-0.5\">\n <RadixToast.Title className=\"text-[15px] leading-snug font-semibold\">{title}</RadixToast.Title>\n {description && <RadixToast.Description className=\"mt-0.5 text-sm text-fg-muted\">{description}</RadixToast.Description>}\n {action && (\n <RadixToast.Action asChild altText={action.altText ?? action.label}>\n <Button size=\"sm\" variant=\"secondary\" className=\"mt-2.5\" onClick={action.onClick}>\n {action.label}\n </Button>\n </RadixToast.Action>\n )}\n </div>\n <RadixToast.Close\n aria-label={closeLabel}\n className={cx(\n 'grid size-8 shrink-0 cursor-pointer place-items-center rounded-full border-0 bg-transparent text-fg-muted',\n 'hover:bg-surface-muted hover:text-fg focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus',\n )}\n >\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M6 6l12 12M18 6L6 18\" stroke=\"currentColor\" strokeWidth=\"2.25\" strokeLinecap=\"round\" fill=\"none\" />\n </svg>\n </RadixToast.Close>\n </RadixToast.Root>\n );\n}\n"],"mappings":";;;;;;;;;;;AAWA,IAAMC,IAA8E;CAClF,SAAS;EAAE,MAAM;EAAU,WAAW;CAAoB;CAC1D,SAAS;EAAE,MAAM;EAAW,WAAW;CAAoB;CAC3D,QAAQ;EAAE,MAAM;EAAS,WAAW;CAAmB;CACvD,MAAM;EAAE,MAAM;EAAQ,WAAW;CAAiB;AACpD,GAEMC,IAAuC;CAC3C,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,QAAQ;CACR,MAAM;AACR,GAEMC,IAAiD;CACrD,SAAS;CACT,SAAS;CACT,MAAM;CACN,SAAS;CACT,QAAQ;CACR,SAAS;AACX;AAiBA,SAAgBC,EAAQ,EAAE,SAAM,GAAG,WAAQ,4BAA4B,YAAS,CAAC,IAAI,GAAG,gBAAa,WAAW,gBAA2B;CACzI,IAAMC,IAASC,EAAqBC,GAAWC,GAAWC,CAAe,GACnEC,IAAUC,EAAcC,CAAa,GACrCC,IAAUR,EAAO,MAAM,GAAGS,CAAG;CAEnC,OACE,kBAACd,EAAW,UAAZ;EAAqB,gBAAgBU,IAAU,UAAU;EAAQ,OAAOK,EAAM,QAAQ,eAAe,EAAE;EAAvG,UAAA,CACGF,EAAQ,KAAK,MACZ,kBAACG,GAAD;GAAsB,MAAMC;GAAe;EAAa,GAAxCA,EAAE,EAAsC,CACzD,GACD,kBAACjB,EAAW,UAAZ;GACU;GACD;GACP,WAAWkB,EACT,sFACA,8CACA,+HACAC,CACF;EACD,CAAA,CACkB;;AAEzB;AAEA,SAASH,EAAU,EAAE,SAAM,iBAAuD;CAChF,IAAM,EAAE,OAAI,YAAS,UAAO,gBAAa,WAAQ,YAASI,GACpDC,IAAOpB,EAAMqB;CACnB,OACE,kBAACtB,EAAW,MAAZ;EACQ;EACN,eAAe,MAAS,CAACuB,KAAQC,EAAM,QAAQC,CAAE;EACjD,UAAUL,EAAK,YAAYjB,EAAiBmB;EAC5C,MAAMA,MAAY,WAAW,eAAe;EAC5C,WAAWJ,EACT,yJACA,iFACAhB,EAAOoB,EACT;EATF,UAAA;GAWGA,MAAY,YACX,kBAACI,GAAD;IAAS,MAAM;IAAI,WAAU;GAA+B,CAAA,IAE5DL,KAAQ,kBAACM,GAAD;IAAM,MAAMN,EAAK;IAAM,MAAM;IAAI,WAAWH,EAAG,SAASG,EAAK,SAAS;GAAI,CAAA;GAEpF,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,kBAACrB,EAAW,OAAZ;MAAkB,WAAU;MAA0C,UAAA4B;KAAwB,CAAA;KAC7FC,KAAe,kBAAC7B,EAAW,aAAZ;MAAwB,WAAU;MAAgC,UAAA6B;KAAoC,CAAA;KACrHC,KACC,kBAAC9B,EAAW,QAAZ;MAAmB,SAAA;MAAQ,SAAS8B,EAAO,WAAWA,EAAO;MAC3D,UAAA,kBAACC,GAAD;OAAQ,MAAK;OAAK,SAAQ;OAAY,WAAU;OAAS,SAASD,EAAO;OACtE,UAAAA,EAAO;MACF,CAAA;KACS,CAAA;IAElB;;GACL,kBAAC9B,EAAW,OAAZ;IACE,cAAYgC;IACZ,WAAWd,EACT,6GACA,yHACF;IAEA,UAAA,kBAAC,OAAD;KAAK,SAAQ;KAAY,OAAM;KAAK,QAAO;KAAK,eAAY;KAAO,WAAU;KAC3E,UAAA,kBAAC,QAAD;MAAM,GAAE;MAAuB,QAAO;MAAe,aAAY;MAAO,eAAc;MAAQ,MAAK;KAAQ,CAAA;IACxG,CAAA;GACW,CAAA;EACH;;AAErB"}
|