@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,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx as e } from "../lib/cx.js";
|
|
3
|
+
import { Glyph as t } from "../lib/glyphs.js";
|
|
4
|
+
import { IconTile as n } from "../icon/icon-tile.js";
|
|
5
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
6
|
+
import { useRef as a, useState as o } from "react";
|
|
7
|
+
//#region src/master-detail/master-detail.tsx
|
|
8
|
+
function s({ items: s, selectedId: c, onSelect: l, children: u, listLabel: d, listAction: f, labels: p = {}, className: m }) {
|
|
9
|
+
let [h, g] = o(!1), _ = a(null), v = a(null), y = () => typeof window < "u" && !window.matchMedia("(min-width: 768px)").matches, b = (e) => setTimeout(() => e()?.focus(), 0);
|
|
10
|
+
return /* @__PURE__ */ i("div", {
|
|
11
|
+
className: e("grid gap-4 font-sans md:grid-cols-[minmax(14rem,18rem)_minmax(0,1fr)]", m),
|
|
12
|
+
children: [/* @__PURE__ */ i("section", {
|
|
13
|
+
"aria-label": d,
|
|
14
|
+
className: e("content-start gap-3 md:grid", h ? "hidden" : "grid"),
|
|
15
|
+
children: [f, /* @__PURE__ */ r("ul", {
|
|
16
|
+
ref: v,
|
|
17
|
+
className: "m-0 grid list-none gap-1 rounded-lg border border-border bg-surface p-1.5",
|
|
18
|
+
children: s.map((t) => {
|
|
19
|
+
let a = t.id === c;
|
|
20
|
+
return /* @__PURE__ */ r("li", { children: /* @__PURE__ */ i("button", {
|
|
21
|
+
type: "button",
|
|
22
|
+
"aria-current": a ? "true" : void 0,
|
|
23
|
+
onClick: () => {
|
|
24
|
+
l(t.id), g(!0), y() && b(() => _.current);
|
|
25
|
+
},
|
|
26
|
+
className: e("flex w-full cursor-pointer items-center gap-2.5 rounded-sm border-0 px-2.5 py-2 text-left text-sm font-medium", "focus-visible:outline-3 focus-visible:-outline-offset-3 focus-visible:outline-focus", a ? "bg-primary text-on-primary" : "bg-transparent text-fg hover:bg-surface-muted"),
|
|
27
|
+
children: [
|
|
28
|
+
t.icon ? /* @__PURE__ */ r(n, {
|
|
29
|
+
icon: t.icon,
|
|
30
|
+
size: "xs",
|
|
31
|
+
...a ? { tone: "inverse" } : { color: t.color ?? "var(--kf-primary)" }
|
|
32
|
+
}) : t.color && /* @__PURE__ */ r("span", {
|
|
33
|
+
"aria-hidden": "true",
|
|
34
|
+
className: "size-2.5 shrink-0 rounded-full",
|
|
35
|
+
style: { background: t.color }
|
|
36
|
+
}),
|
|
37
|
+
/* @__PURE__ */ r("span", {
|
|
38
|
+
className: "min-w-0 flex-1 truncate",
|
|
39
|
+
children: t.label
|
|
40
|
+
}),
|
|
41
|
+
t.count !== void 0 && /* @__PURE__ */ r("span", {
|
|
42
|
+
className: e("text-xs tabular-nums", a ? "opacity-80" : "text-fg-muted"),
|
|
43
|
+
children: t.count
|
|
44
|
+
})
|
|
45
|
+
]
|
|
46
|
+
}) }, t.id);
|
|
47
|
+
})
|
|
48
|
+
})]
|
|
49
|
+
}), /* @__PURE__ */ i("section", {
|
|
50
|
+
ref: _,
|
|
51
|
+
tabIndex: -1,
|
|
52
|
+
"aria-label": p.detail,
|
|
53
|
+
className: e("min-w-0 content-start gap-3 focus:outline-none md:grid", h ? "grid" : "hidden"),
|
|
54
|
+
children: [/* @__PURE__ */ i("button", {
|
|
55
|
+
type: "button",
|
|
56
|
+
onClick: () => {
|
|
57
|
+
g(!1), b(() => v.current?.querySelector("[aria-current=\"true\"]") ?? v.current?.querySelector("button"));
|
|
58
|
+
},
|
|
59
|
+
className: "inline-flex w-fit cursor-pointer items-center gap-1 rounded-xs border-0 bg-transparent p-0 text-sm font-medium text-fg-muted hover:text-fg focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus md:hidden",
|
|
60
|
+
children: [/* @__PURE__ */ r(t, {
|
|
61
|
+
name: "chevron-left",
|
|
62
|
+
size: 16
|
|
63
|
+
}), p.back ?? d]
|
|
64
|
+
}), u]
|
|
65
|
+
})]
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { s as MasterDetail };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=master-detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"master-detail.js","names":["MasterDetail","detailOnMobile","setDetailOnMobile","useState","detailRef","useRef","listRef","narrow","focusLater","el","cx","className","listLabel","listAction","items","on","i","selectedId","onSelect","IconTile","labels","Glyph","children"],"sources":["../../src/master-detail/master-detail.tsx"],"sourcesContent":["'use client';\nimport { useRef, useState, type ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { IconTile } from '../icon/icon-tile';\nimport { Glyph } from '../lib/glyphs';\nimport type { IconName } from '../icon/icon';\n\n/* ---------------- MasterDetail ---------------- */\n\nexport interface MasterItem {\n id: string;\n label: string;\n icon?: IconName;\n color?: string;\n count?: number;\n}\n\nexport interface MasterDetailProps {\n items: MasterItem[];\n selectedId?: string;\n onSelect: (id: string) => void;\n /** The selected item's panel. */\n children: ReactNode;\n listLabel: string;\n /** A control above the list (\"New client\"). */\n listAction?: ReactNode;\n /** `detail` names the detail panel for screen readers (e.g. \"Client details\"). */\n labels?: { back?: string; detail?: string };\n className?: string;\n}\n\n/**\n * A selectable list on the left and the selected item's detail on the right (clients and projects, departments).\n * Below 768px it shows the list, then the detail with a back button.\n */\nexport function MasterDetail({\n items,\n selectedId,\n onSelect,\n children,\n listLabel,\n listAction,\n labels = {},\n className,\n}: MasterDetailProps) {\n const [detailOnMobile, setDetailOnMobile] = useState(false);\n const detailRef = useRef<HTMLElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n // Below 768px one panel hides the other: move focus to the panel that appears, or it falls to <body>.\n const narrow = () => typeof window !== 'undefined' && !window.matchMedia('(min-width: 768px)').matches;\n const focusLater = (el: () => HTMLElement | null | undefined) => setTimeout(() => el()?.focus(), 0);\n return (\n <div className={cx('grid gap-4 font-sans md:grid-cols-[minmax(14rem,18rem)_minmax(0,1fr)]', className)}>\n <section aria-label={listLabel} className={cx('content-start gap-3 md:grid', detailOnMobile ? 'hidden' : 'grid')}>\n {listAction}\n <ul ref={listRef} className=\"m-0 grid list-none gap-1 rounded-lg border border-border bg-surface p-1.5\">\n {items.map((i) => {\n const on = i.id === selectedId;\n return (\n <li key={i.id}>\n <button\n type=\"button\"\n aria-current={on ? 'true' : undefined}\n onClick={() => {\n onSelect(i.id);\n setDetailOnMobile(true);\n if (narrow()) focusLater(() => detailRef.current);\n }}\n className={cx(\n 'flex w-full cursor-pointer items-center gap-2.5 rounded-sm border-0 px-2.5 py-2 text-left text-sm font-medium',\n 'focus-visible:outline-3 focus-visible:-outline-offset-3 focus-visible:outline-focus',\n on ? 'bg-primary text-on-primary' : 'bg-transparent text-fg hover:bg-surface-muted',\n )}\n >\n {i.icon ? (\n <IconTile\n icon={i.icon}\n size=\"xs\"\n {...(on ? { tone: 'inverse' } : { color: i.color ?? 'var(--kf-primary)' })}\n />\n ) : (\n i.color && (\n <span\n aria-hidden=\"true\"\n className=\"size-2.5 shrink-0 rounded-full\"\n style={{ background: i.color }}\n />\n )\n )}\n <span className=\"min-w-0 flex-1 truncate\">{i.label}</span>\n {i.count !== undefined && (\n <span className={cx('text-xs tabular-nums', on ? 'opacity-80' : 'text-fg-muted')}>{i.count}</span>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n </section>\n <section\n ref={detailRef}\n tabIndex={-1}\n aria-label={labels.detail}\n className={cx('min-w-0 content-start gap-3 focus:outline-none md:grid', detailOnMobile ? 'grid' : 'hidden')}\n >\n <button\n type=\"button\"\n onClick={() => {\n setDetailOnMobile(false);\n focusLater(\n () =>\n listRef.current?.querySelector<HTMLElement>('[aria-current=\"true\"]') ??\n listRef.current?.querySelector('button'),\n );\n }}\n className=\"inline-flex w-fit cursor-pointer items-center gap-1 rounded-xs border-0 bg-transparent p-0 text-sm font-medium text-fg-muted hover:text-fg focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus md:hidden\"\n >\n <Glyph name=\"chevron-left\" size={16} />\n {labels.back ?? listLabel}\n </button>\n {children}\n </section>\n </div>\n );\n}\n"],"mappings":";;;;;;;AAmCA,SAAgBA,EAAa,EAC3B,UACA,eACA,aACA,aACA,cACA,eACA,YAAS,CAAC,GACV,gBACoB;CACpB,IAAM,CAACC,GAAgBC,KAAqBC,EAAS,EAAK,GACpDC,IAAYC,EAAoB,IAAI,GACpCC,IAAUD,EAAyB,IAAI,GAEvCE,UAAe,OAAO,SAAW,OAAe,CAAC,OAAO,WAAW,oBAAoB,CAAC,CAAC,SACzFC,KAAc,MAA6C,iBAAiBC,EAAG,CAAC,EAAE,MAAM,GAAG,CAAC;CAClG,OACE,kBAAC,OAAD;EAAK,WAAWC,EAAG,yEAAyEC,CAAS;EAArG,UAAA,CACE,kBAAC,WAAD;GAAS,cAAYC;GAAW,WAAWF,EAAG,+BAA+BT,IAAiB,WAAW,MAAM;GAA/G,UAAA,CACGY,GACD,kBAAC,MAAD;IAAI,KAAKP;IAAS,WAAU;IACzB,UAAAQ,EAAM,KAAK,MAAM;KAChB,IAAMC,IAAKC,EAAE,OAAOC;KACpB,OACE,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;MACE,MAAK;MACL,gBAAcF,IAAK,SAAS,KAAA;MAC5B,eAAe;OAGb,AAFAG,EAASF,EAAE,EAAE,GACbd,EAAkB,EAAI,GAClBK,EAAO,KAAGC,QAAiBJ,EAAU,OAAO;MAClD;MACA,WAAWM,EACT,iHACA,uFACAK,IAAK,+BAA+B,+CACtC;MAZF,UAAA;OAcGC,EAAE,OACD,kBAACG,GAAD;QACE,MAAMH,EAAE;QACR,MAAK;QACL,GAAKD,IAAK,EAAE,MAAM,UAAU,IAAI,EAAE,OAAOC,EAAE,SAAS,oBAAoB;OACzE,CAAA,IAEDA,EAAE,SACA,kBAAC,QAAD;QACE,eAAY;QACZ,WAAU;QACV,OAAO,EAAE,YAAYA,EAAE,MAAM;OAC9B,CAAA;OAGL,kBAAC,QAAD;QAAM,WAAU;QAA2B,UAAAA,EAAE;OAAY,CAAA;OACxDA,EAAE,UAAU,KAAA,KACX,kBAAC,QAAD;QAAM,WAAWN,EAAG,wBAAwBK,IAAK,eAAe,eAAe;QAAI,UAAAC,EAAE;OAAY,CAAA;MAE7F;KACN,CAAA,EAAA,GAnCKA,EAAE,EAmCP;IAER,CAAC;GACC,CAAA,CACG;EACT,CAAA,GAAA,kBAAC,WAAD;GACE,KAAKZ;GACL,UAAU;GACV,cAAYgB,EAAO;GACnB,WAAWV,EAAG,0DAA0DT,IAAiB,SAAS,QAAQ;GAJ5G,UAAA,CAME,kBAAC,UAAD;IACE,MAAK;IACL,eAAe;KAEb,AADAC,EAAkB,EAAK,GACvBM,QAEIF,EAAQ,SAAS,cAA2B,yBAAuB,KACnEA,EAAQ,SAAS,cAAc,QAAQ,CAC3C;IACF;IACA,WAAU;IAVZ,UAAA,CAYE,kBAACe,GAAD;KAAO,MAAK;KAAe,MAAM;IAAK,CAAA,GACrCD,EAAO,QAAQR,CACV;GACP,CAAA,GAAAU,CACM;EACN,CAAA,CAAA;;AAET"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ElementType, ReactNode } from 'react';
|
|
2
|
+
import type { IconName } from '../icon/icon';
|
|
3
|
+
export interface AccountMenuItem {
|
|
4
|
+
label: string;
|
|
5
|
+
icon?: IconName;
|
|
6
|
+
/** A link (rendered with `linkAs`, e.g. Next.js `Link`). */
|
|
7
|
+
href?: string;
|
|
8
|
+
/** An action instead of a link. */
|
|
9
|
+
onSelect?: () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface AccountMenuProps {
|
|
12
|
+
name: string;
|
|
13
|
+
email?: string;
|
|
14
|
+
/** Role or plan shown in the header ("Admin"). */
|
|
15
|
+
role?: string;
|
|
16
|
+
avatarSrc?: string;
|
|
17
|
+
/** Profile, settings, billing… */
|
|
18
|
+
items?: AccountMenuItem[];
|
|
19
|
+
/** Language choice as a submenu. */
|
|
20
|
+
locale?: {
|
|
21
|
+
value: string;
|
|
22
|
+
options: {
|
|
23
|
+
value: string;
|
|
24
|
+
label: string;
|
|
25
|
+
}[];
|
|
26
|
+
onChange: (value: string) => void;
|
|
27
|
+
};
|
|
28
|
+
onSignOut?: () => void;
|
|
29
|
+
/** Extra content at the end of the menu (e.g. a "Switch organization" item). */
|
|
30
|
+
children?: ReactNode;
|
|
31
|
+
/** Link component for items with `href`. */
|
|
32
|
+
linkAs?: ElementType;
|
|
33
|
+
labels?: {
|
|
34
|
+
account?: string;
|
|
35
|
+
language?: string;
|
|
36
|
+
signOut?: string;
|
|
37
|
+
};
|
|
38
|
+
className?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The top bar's account trigger (avatar + chevron) and its menu: identity header, items, language and sign out.
|
|
42
|
+
* Every product's top bar uses it.
|
|
43
|
+
*/
|
|
44
|
+
export declare function AccountMenu({ name, email, role, avatarSrc, items, locale, onSignOut, children, linkAs, labels, className, }: AccountMenuProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx as e } from "../lib/cx.js";
|
|
3
|
+
import { Glyph as t } from "../lib/glyphs.js";
|
|
4
|
+
import { Avatar as n } from "../data-display/avatar.js";
|
|
5
|
+
import { DropdownMenu as r, DropdownMenuContent as i, DropdownMenuHeader as a, DropdownMenuItem as o, DropdownMenuRadioGroup as s, DropdownMenuRadioItem as c, DropdownMenuSeparator as l, DropdownMenuSub as u, DropdownMenuSubContent as d, DropdownMenuSubTrigger as f, DropdownMenuTrigger as p } from "./dropdown-menu.js";
|
|
6
|
+
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
7
|
+
//#region src/menu/account-menu.tsx
|
|
8
|
+
function _({ name: _, email: v, role: y, avatarSrc: b, items: x = [], locale: S, onSignOut: C, children: w, linkAs: T, labels: E = {}, className: D }) {
|
|
9
|
+
return /* @__PURE__ */ g(r, { children: [/* @__PURE__ */ h(p, {
|
|
10
|
+
asChild: !0,
|
|
11
|
+
children: /* @__PURE__ */ g("button", {
|
|
12
|
+
type: "button",
|
|
13
|
+
className: e("inline-flex cursor-pointer items-center gap-1 rounded-full border-0 bg-transparent p-0.5 pr-1.5 text-fg-muted hover:bg-surface-muted hover:text-fg", "focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus", D),
|
|
14
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ h(n, {
|
|
16
|
+
name: _,
|
|
17
|
+
src: b,
|
|
18
|
+
size: "sm"
|
|
19
|
+
}),
|
|
20
|
+
/* @__PURE__ */ h("span", {
|
|
21
|
+
className: "sr-only",
|
|
22
|
+
children: E.account ?? "account menu"
|
|
23
|
+
}),
|
|
24
|
+
/* @__PURE__ */ h(t, {
|
|
25
|
+
name: "chevron-down",
|
|
26
|
+
size: 14
|
|
27
|
+
})
|
|
28
|
+
]
|
|
29
|
+
})
|
|
30
|
+
}), /* @__PURE__ */ g(i, {
|
|
31
|
+
align: "end",
|
|
32
|
+
className: "w-72",
|
|
33
|
+
children: [
|
|
34
|
+
/* @__PURE__ */ h(a, {
|
|
35
|
+
name: _,
|
|
36
|
+
email: v,
|
|
37
|
+
role: y,
|
|
38
|
+
avatarSrc: b
|
|
39
|
+
}),
|
|
40
|
+
x.map((e) => /* @__PURE__ */ h(o, {
|
|
41
|
+
icon: e.icon,
|
|
42
|
+
...e.href ? {
|
|
43
|
+
href: e.href,
|
|
44
|
+
linkAs: T
|
|
45
|
+
} : { onSelect: e.onSelect },
|
|
46
|
+
children: e.label
|
|
47
|
+
}, e.label)),
|
|
48
|
+
S && /* @__PURE__ */ g(u, { children: [/* @__PURE__ */ h(f, {
|
|
49
|
+
icon: "c-website",
|
|
50
|
+
children: /* @__PURE__ */ g("span", {
|
|
51
|
+
className: "flex items-center justify-between gap-3",
|
|
52
|
+
children: [E.language ?? "Language", /* @__PURE__ */ h("span", {
|
|
53
|
+
className: "text-xs text-fg-muted",
|
|
54
|
+
children: S.options.find((e) => e.value === S.value)?.label
|
|
55
|
+
})]
|
|
56
|
+
})
|
|
57
|
+
}), /* @__PURE__ */ h(d, { children: /* @__PURE__ */ h(s, {
|
|
58
|
+
value: S.value,
|
|
59
|
+
onValueChange: S.onChange,
|
|
60
|
+
children: S.options.map((e) => /* @__PURE__ */ h(c, {
|
|
61
|
+
value: e.value,
|
|
62
|
+
children: e.label
|
|
63
|
+
}, e.value))
|
|
64
|
+
}) })] }),
|
|
65
|
+
w,
|
|
66
|
+
C && /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(l, {}), /* @__PURE__ */ h(o, {
|
|
67
|
+
icon: "logout",
|
|
68
|
+
tone: "danger",
|
|
69
|
+
onSelect: C,
|
|
70
|
+
children: E.signOut ?? "Sign out"
|
|
71
|
+
})] })
|
|
72
|
+
]
|
|
73
|
+
})] });
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
export { _ as AccountMenu };
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=account-menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-menu.js","names":["_Fragment","AccountMenu","DropdownMenu","DropdownMenuTrigger","cx","className","Avatar","avatarSrc","labels","Glyph","DropdownMenuContent","DropdownMenuHeader","items","DropdownMenuItem","i","locale","DropdownMenuSub","DropdownMenuSubTrigger","o","DropdownMenuSubContent","DropdownMenuRadioGroup","DropdownMenuRadioItem","children","onSignOut","Fragment","DropdownMenuSeparator"],"sources":["../../src/menu/account-menu.tsx"],"sourcesContent":["'use client';\n\nimport type { ElementType, ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { Glyph } from '../lib/glyphs';\nimport type { IconName } from '../icon/icon';\nimport { Avatar } from '../data-display/avatar';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuHeader,\n DropdownMenuItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from './dropdown-menu';\n\nexport interface AccountMenuItem {\n label: string;\n icon?: IconName;\n /** A link (rendered with `linkAs`, e.g. Next.js `Link`). */\n href?: string;\n /** An action instead of a link. */\n onSelect?: () => void;\n}\n\nexport interface AccountMenuProps {\n name: string;\n email?: string;\n /** Role or plan shown in the header (\"Admin\"). */\n role?: string;\n avatarSrc?: string;\n /** Profile, settings, billing… */\n items?: AccountMenuItem[];\n /** Language choice as a submenu. */\n locale?: { value: string; options: { value: string; label: string }[]; onChange: (value: string) => void };\n onSignOut?: () => void;\n /** Extra content at the end of the menu (e.g. a \"Switch organization\" item). */\n children?: ReactNode;\n /** Link component for items with `href`. */\n linkAs?: ElementType;\n labels?: { account?: string; language?: string; signOut?: string };\n className?: string;\n}\n\n/**\n * The top bar's account trigger (avatar + chevron) and its menu: identity header, items, language and sign out.\n * Every product's top bar uses it.\n */\nexport function AccountMenu({\n name,\n email,\n role,\n avatarSrc,\n items = [],\n locale,\n onSignOut,\n children,\n linkAs,\n labels = {},\n className,\n}: AccountMenuProps) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className={cx(\n 'inline-flex cursor-pointer items-center gap-1 rounded-full border-0 bg-transparent p-0.5 pr-1.5 text-fg-muted hover:bg-surface-muted hover:text-fg',\n 'focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus',\n className,\n )}\n >\n {/* The avatar names the button (\"Ana Torres\"); the hidden text says what it opens. */}\n <Avatar name={name} src={avatarSrc} size=\"sm\" />\n <span className=\"sr-only\">{labels.account ?? 'account menu'}</span>\n <Glyph name=\"chevron-down\" size={14} />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-72\">\n <DropdownMenuHeader name={name} email={email} role={role} avatarSrc={avatarSrc} />\n {items.map((i) => (\n <DropdownMenuItem key={i.label} icon={i.icon} {...(i.href ? { href: i.href, linkAs } : { onSelect: i.onSelect })}>\n {i.label}\n </DropdownMenuItem>\n ))}\n {locale && (\n <DropdownMenuSub>\n <DropdownMenuSubTrigger icon=\"c-website\">\n <span className=\"flex items-center justify-between gap-3\">\n {labels.language ?? 'Language'}\n <span className=\"text-xs text-fg-muted\">\n {locale.options.find((o) => o.value === locale.value)?.label}\n </span>\n </span>\n </DropdownMenuSubTrigger>\n <DropdownMenuSubContent>\n <DropdownMenuRadioGroup value={locale.value} onValueChange={locale.onChange}>\n {locale.options.map((o) => (\n <DropdownMenuRadioItem key={o.value} value={o.value}>\n {o.label}\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n )}\n {children}\n {onSignOut && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem icon=\"logout\" tone=\"danger\" onSelect={onSignOut}>\n {labels.signOut ?? 'Sign out'}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":";;;;;;;AAqDA,SAAgBC,EAAY,EAC1B,SACA,UACA,SACA,cACA,WAAQ,CAAC,GACT,WACA,cACA,aACA,WACA,YAAS,CAAC,GACV,gBACmB;CACnB,OACE,kBAACC,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD;EAAqB,SAAA;EACnB,UAAA,kBAAC,UAAD;GACE,MAAK;GACL,WAAWC,EACT,sJACA,sFACAC,CACF;GANF,UAAA;IASE,kBAACC,GAAD;KAAc;KAAM,KAAKC;KAAW,MAAK;IAAM,CAAA;IAC/C,kBAAC,QAAD;KAAM,WAAU;KAAW,UAAAC,EAAO,WAAW;IAAqB,CAAA;IAClE,kBAACC,GAAD;KAAO,MAAK;KAAe,MAAM;IAAK,CAAA;GAChC;;CACW,CAAA,GACrB,kBAACC,GAAD;EAAqB,OAAM;EAAM,WAAU;EAA3C,UAAA;GACE,kBAACC,GAAD;IAA0B;IAAa;IAAa;IAAiB;GAAY,CAAA;GAChFC,EAAM,KAAK,MACV,kBAACC,GAAD;IAAgC,MAAMC,EAAE;IAAM,GAAKA,EAAE,OAAO;KAAE,MAAMA,EAAE;KAAM;IAAO,IAAI,EAAE,UAAUA,EAAE,SAAS;IAC3G,UAAAA,EAAE;GACa,GAFKA,EAAE,KAEP,CACnB;GACAC,KACC,kBAACC,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD;IAAwB,MAAK;IAC3B,UAAA,kBAAC,QAAD;KAAM,WAAU;KAAhB,UAAA,CACGT,EAAO,YAAY,YACpB,kBAAC,QAAD;MAAM,WAAU;MACb,UAAAO,EAAO,QAAQ,MAAM,MAAMG,EAAE,UAAUH,EAAO,KAAK,CAAC,EAAE;KACnD,CAAA,CACF;;GACgB,CAAA,GACxB,kBAACI,GAAD,EAAA,UACE,kBAACC,GAAD;IAAwB,OAAOL,EAAO;IAAO,eAAeA,EAAO;IAChE,UAAAA,EAAO,QAAQ,KAAK,MACnB,kBAACM,GAAD;KAAqC,OAAOH,EAAE;KAC3C,UAAAA,EAAE;IACkB,GAFKA,EAAE,KAEP,CACxB;GACqB,CAAA,EACF,CAAA,CACT,EAAA,CAAA;GAElBI;GACAC,KACC,kBAAAvB,GAAA,EAAA,UAAA,CACE,kBAACyB,GAAD,CAAwB,CAAA,GACxB,kBAACZ,GAAD;IAAkB,MAAK;IAAS,MAAK;IAAS,UAAUU;IACrD,UAAAf,EAAO,WAAW;GACH,CAAA,CAClB,EAAA,CAAA;EAEe;CACT,CAAA,CAAA,EAAA,CAAA;AAElB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as Primitive from '@radix-ui/react-context-menu';
|
|
2
|
+
import type { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
3
|
+
import { type IconName } from '../icon/icon';
|
|
4
|
+
/**
|
|
5
|
+
* Right-click (or long-press on touch) menu for an area: rows, cards, canvas nodes.
|
|
6
|
+
* Always offer the same actions elsewhere (a "More" DropdownMenu): context menus are hidden.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ContextMenu: import("react").FC<Primitive.ContextMenuProps>;
|
|
9
|
+
/** The area that opens the menu on right-click / long-press. */
|
|
10
|
+
export declare const ContextMenuTrigger: import("react").ForwardRefExoticComponent<Primitive.ContextMenuTriggerProps & import("react").RefAttributes<HTMLSpanElement>>;
|
|
11
|
+
export declare function ContextMenuContent({ className, collisionPadding, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Content>): import("react").JSX.Element;
|
|
12
|
+
interface ItemExtras {
|
|
13
|
+
icon?: IconName;
|
|
14
|
+
/** Keyboard shortcut hint, e.g. `⌘D`. */
|
|
15
|
+
shortcut?: string;
|
|
16
|
+
tone?: 'default' | 'danger';
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
export declare function ContextMenuItem({ icon, shortcut, tone, className, children, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Item> & ItemExtras): import("react").JSX.Element;
|
|
20
|
+
export declare function ContextMenuCheckboxItem({ className, children, ...rest }: ComponentPropsWithoutRef<typeof Primitive.CheckboxItem>): import("react").JSX.Element;
|
|
21
|
+
export declare const ContextMenuRadioGroup: import("react").ForwardRefExoticComponent<Primitive.ContextMenuRadioGroupProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
22
|
+
export declare function ContextMenuRadioItem({ className, children, ...rest }: ComponentPropsWithoutRef<typeof Primitive.RadioItem>): import("react").JSX.Element;
|
|
23
|
+
export declare function ContextMenuLabel({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Label>): import("react").JSX.Element;
|
|
24
|
+
export declare function ContextMenuSeparator({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Separator>): import("react").JSX.Element;
|
|
25
|
+
export declare const ContextMenuGroup: import("react").ForwardRefExoticComponent<Primitive.ContextMenuGroupProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
26
|
+
export declare const ContextMenuSub: import("react").FC<Primitive.ContextMenuSubProps>;
|
|
27
|
+
export declare function ContextMenuSubTrigger({ icon, className, children, ...rest }: ComponentPropsWithoutRef<typeof Primitive.SubTrigger> & {
|
|
28
|
+
icon?: IconName;
|
|
29
|
+
}): import("react").JSX.Element;
|
|
30
|
+
export declare function ContextMenuSubContent({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.SubContent>): import("react").JSX.Element;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx as e } from "../lib/cx.js";
|
|
3
|
+
import { Icon as t } from "../icon/icon.js";
|
|
4
|
+
import { Glyph as n } from "../lib/glyphs.js";
|
|
5
|
+
import { menuContent as r, menuIndicatorSlot as i, menuItem as a, menuLabel as o, menuSeparator as s } from "./menu-styles.js";
|
|
6
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
7
|
+
import * as u from "@radix-ui/react-context-menu";
|
|
8
|
+
//#region src/menu/context-menu.tsx
|
|
9
|
+
var d = u.Root, f = u.Trigger;
|
|
10
|
+
function p({ className: t, collisionPadding: n = 16, ...i }) {
|
|
11
|
+
return /* @__PURE__ */ c(u.Portal, { children: /* @__PURE__ */ c(u.Content, {
|
|
12
|
+
collisionPadding: n,
|
|
13
|
+
className: e(r, "[--kf-menu-max-h:var(--radix-context-menu-content-available-height)]", t),
|
|
14
|
+
...i
|
|
15
|
+
}) });
|
|
16
|
+
}
|
|
17
|
+
function m({ icon: n, shortcut: r, tone: i = "default", className: o, children: s, ...d }) {
|
|
18
|
+
return /* @__PURE__ */ l(u.Item, {
|
|
19
|
+
className: e(a, i === "danger" && "text-danger-fg data-[highlighted]:bg-danger-surface", o),
|
|
20
|
+
...d,
|
|
21
|
+
children: [
|
|
22
|
+
n && /* @__PURE__ */ c(t, {
|
|
23
|
+
name: n,
|
|
24
|
+
size: 20,
|
|
25
|
+
className: "shrink-0"
|
|
26
|
+
}),
|
|
27
|
+
/* @__PURE__ */ c("span", {
|
|
28
|
+
className: "min-w-0 flex-1 truncate",
|
|
29
|
+
children: s
|
|
30
|
+
}),
|
|
31
|
+
r && /* @__PURE__ */ c("span", {
|
|
32
|
+
className: "ml-auto pl-4 font-mono text-xs text-fg-muted",
|
|
33
|
+
children: r
|
|
34
|
+
})
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function h({ className: t, children: r, ...o }) {
|
|
39
|
+
return /* @__PURE__ */ l(u.CheckboxItem, {
|
|
40
|
+
className: e(a, i, t),
|
|
41
|
+
...o,
|
|
42
|
+
children: [/* @__PURE__ */ c(u.ItemIndicator, {
|
|
43
|
+
className: "absolute left-2.5 inline-flex text-link",
|
|
44
|
+
children: /* @__PURE__ */ c(n, {
|
|
45
|
+
name: "check",
|
|
46
|
+
size: 16
|
|
47
|
+
})
|
|
48
|
+
}), r]
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
var g = u.RadioGroup;
|
|
52
|
+
function _({ className: t, children: r, ...o }) {
|
|
53
|
+
return /* @__PURE__ */ l(u.RadioItem, {
|
|
54
|
+
className: e(a, i, t),
|
|
55
|
+
...o,
|
|
56
|
+
children: [/* @__PURE__ */ c(u.ItemIndicator, {
|
|
57
|
+
className: "absolute left-3 inline-flex text-link",
|
|
58
|
+
children: /* @__PURE__ */ c(n, {
|
|
59
|
+
name: "dot",
|
|
60
|
+
size: 14
|
|
61
|
+
})
|
|
62
|
+
}), r]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function v({ className: t, ...n }) {
|
|
66
|
+
return /* @__PURE__ */ c(u.Label, {
|
|
67
|
+
className: e(o, t),
|
|
68
|
+
...n
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function y({ className: t, ...n }) {
|
|
72
|
+
return /* @__PURE__ */ c(u.Separator, {
|
|
73
|
+
className: e(s, t),
|
|
74
|
+
...n
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
var b = u.Group, x = u.Sub;
|
|
78
|
+
function S({ icon: r, className: i, children: o, ...s }) {
|
|
79
|
+
return /* @__PURE__ */ l(u.SubTrigger, {
|
|
80
|
+
className: e(a, i),
|
|
81
|
+
...s,
|
|
82
|
+
children: [
|
|
83
|
+
r && /* @__PURE__ */ c(t, {
|
|
84
|
+
name: r,
|
|
85
|
+
size: 20,
|
|
86
|
+
className: "shrink-0"
|
|
87
|
+
}),
|
|
88
|
+
/* @__PURE__ */ c("span", {
|
|
89
|
+
className: "flex-1",
|
|
90
|
+
children: o
|
|
91
|
+
}),
|
|
92
|
+
/* @__PURE__ */ c(n, {
|
|
93
|
+
name: "chevron-right",
|
|
94
|
+
size: 16,
|
|
95
|
+
className: "text-fg-muted"
|
|
96
|
+
})
|
|
97
|
+
]
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function C({ className: t, ...n }) {
|
|
101
|
+
return /* @__PURE__ */ c(u.Portal, { children: /* @__PURE__ */ c(u.SubContent, {
|
|
102
|
+
sideOffset: 4,
|
|
103
|
+
collisionPadding: 16,
|
|
104
|
+
className: e(r, t),
|
|
105
|
+
...n
|
|
106
|
+
}) });
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
export { d as ContextMenu, h as ContextMenuCheckboxItem, p as ContextMenuContent, b as ContextMenuGroup, m as ContextMenuItem, v as ContextMenuLabel, g as ContextMenuRadioGroup, _ as ContextMenuRadioItem, y as ContextMenuSeparator, x as ContextMenuSub, C as ContextMenuSubContent, S as ContextMenuSubTrigger, f as ContextMenuTrigger };
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=context-menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-menu.js","names":["Primitive","ContextMenu","ContextMenuTrigger","ContextMenuContent","rest","cx","menuContent","className","ContextMenuItem","menuItem","tone","icon","Icon","shortcut","ContextMenuCheckboxItem","menuIndicatorSlot","Glyph","children","ContextMenuRadioGroup","ContextMenuRadioItem","ContextMenuLabel","menuLabel","ContextMenuSeparator","menuSeparator","ContextMenuGroup","ContextMenuSub","ContextMenuSubTrigger","ContextMenuSubContent"],"sources":["../../src/menu/context-menu.tsx"],"sourcesContent":["// Shares its item components' structure with the other menu files (dropdown-menu, context-menu, menubar): keep them in sync.\n'use client';\n\nimport * as Primitive from '@radix-ui/react-context-menu';\nimport type { ComponentPropsWithoutRef, ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { Icon, type IconName } from '../icon/icon';\nimport { Glyph } from '../lib/glyphs';\nimport {\n menuContent,\n menuIndicatorSlot,\n menuItem,\n menuItemDanger,\n menuLabel,\n menuSeparator,\n menuShortcut,\n} from './menu-styles';\n\n/**\n * Right-click (or long-press on touch) menu for an area: rows, cards, canvas nodes.\n * Always offer the same actions elsewhere (a \"More\" DropdownMenu): context menus are hidden.\n */\nexport const ContextMenu = Primitive.Root;\n/** The area that opens the menu on right-click / long-press. */\nexport const ContextMenuTrigger = Primitive.Trigger;\n\nexport function ContextMenuContent({\n className,\n collisionPadding = 16,\n ...rest\n}: ComponentPropsWithoutRef<typeof Primitive.Content>) {\n return (\n <Primitive.Portal>\n <Primitive.Content\n collisionPadding={collisionPadding}\n className={cx(menuContent, '[--kf-menu-max-h:var(--radix-context-menu-content-available-height)]', className)}\n {...rest}\n />\n </Primitive.Portal>\n );\n}\n\ninterface ItemExtras {\n icon?: IconName;\n /** Keyboard shortcut hint, e.g. `⌘D`. */\n shortcut?: string;\n tone?: 'default' | 'danger';\n children: ReactNode;\n}\n\nexport function ContextMenuItem({\n icon,\n shortcut,\n tone = 'default',\n className,\n children,\n ...rest\n}: ComponentPropsWithoutRef<typeof Primitive.Item> & ItemExtras) {\n return (\n <Primitive.Item className={cx(menuItem, tone === 'danger' && menuItemDanger, className)} {...rest}>\n {icon && <Icon name={icon} size={20} className=\"shrink-0\" />}\n <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n {shortcut && <span className={menuShortcut}>{shortcut}</span>}\n </Primitive.Item>\n );\n}\n\nexport function ContextMenuCheckboxItem({\n className,\n children,\n ...rest\n}: ComponentPropsWithoutRef<typeof Primitive.CheckboxItem>) {\n return (\n <Primitive.CheckboxItem className={cx(menuItem, menuIndicatorSlot, className)} {...rest}>\n <Primitive.ItemIndicator className=\"absolute left-2.5 inline-flex text-link\">\n <Glyph name=\"check\" size={16} />\n </Primitive.ItemIndicator>\n {children}\n </Primitive.CheckboxItem>\n );\n}\n\nexport const ContextMenuRadioGroup = Primitive.RadioGroup;\n\nexport function ContextMenuRadioItem({\n className,\n children,\n ...rest\n}: ComponentPropsWithoutRef<typeof Primitive.RadioItem>) {\n return (\n <Primitive.RadioItem className={cx(menuItem, menuIndicatorSlot, className)} {...rest}>\n <Primitive.ItemIndicator className=\"absolute left-3 inline-flex text-link\">\n <Glyph name=\"dot\" size={14} />\n </Primitive.ItemIndicator>\n {children}\n </Primitive.RadioItem>\n );\n}\n\nexport function ContextMenuLabel({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Label>) {\n return <Primitive.Label className={cx(menuLabel, className)} {...rest} />;\n}\n\nexport function ContextMenuSeparator({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Separator>) {\n return <Primitive.Separator className={cx(menuSeparator, className)} {...rest} />;\n}\n\nexport const ContextMenuGroup = Primitive.Group;\nexport const ContextMenuSub = Primitive.Sub;\n\nexport function ContextMenuSubTrigger({\n icon,\n className,\n children,\n ...rest\n}: ComponentPropsWithoutRef<typeof Primitive.SubTrigger> & { icon?: IconName }) {\n return (\n <Primitive.SubTrigger className={cx(menuItem, className)} {...rest}>\n {icon && <Icon name={icon} size={20} className=\"shrink-0\" />}\n <span className=\"flex-1\">{children}</span>\n <Glyph name=\"chevron-right\" size={16} className=\"text-fg-muted\" />\n </Primitive.SubTrigger>\n );\n}\n\nexport function ContextMenuSubContent({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.SubContent>) {\n return (\n <Primitive.Portal>\n <Primitive.SubContent sideOffset={4} collisionPadding={16} className={cx(menuContent, className)} {...rest} />\n </Primitive.Portal>\n );\n}\n"],"mappings":";;;;;;;;AAsBA,IAAaC,IAAcD,EAAU,MAExBE,IAAqBF,EAAU;AAE5C,SAAgBG,EAAmB,EACjC,cACA,sBAAmB,IACnB,GAAGC,KACkD;CACrD,OACE,kBAACJ,EAAU,QAAX,EAAA,UACE,kBAACA,EAAU,SAAX;EACoB;EAClB,WAAWK,EAAGC,GAAa,wEAAwEC,CAAS;EAC5G,GAAIH;CACL,CAAA,EACe,CAAA;AAEtB;AAUA,SAAgBI,EAAgB,EAC9B,SACA,aACA,UAAO,WACP,cACA,aACA,GAAGJ,KAC4D;CAC/D,OACE,kBAACJ,EAAU,MAAX;EAAgB,WAAWK,EAAGI,GAAUC,MAAS,YAAA,uDAA4BH,CAAS;EAAG,GAAIH;EAA7F,UAAA;GACGO,KAAQ,kBAACC,GAAD;IAAM,MAAMD;IAAM,MAAM;IAAI,WAAU;GAAY,CAAA;GAC3D,kBAAC,QAAD;IAAM,WAAU;IAA2B;GAAe,CAAA;GACzDE,KAAY,kBAAC,QAAD;IAAM,WAAA;IAA0B,UAAAA;GAAe,CAAA;EAC9C;;AAEpB;AAEA,SAAgBC,EAAwB,EACtC,cACA,aACA,GAAGV,KACuD;CAC1D,OACE,kBAACJ,EAAU,cAAX;EAAwB,WAAWK,EAAGI,GAAUM,GAAmBR,CAAS;EAAG,GAAIH;EAAnF,UAAA,CACE,kBAACJ,EAAU,eAAX;GAAyB,WAAU;GACjC,UAAA,kBAACgB,GAAD;IAAO,MAAK;IAAQ,MAAM;GAAK,CAAA;EACR,CAAA,GACxBC,CACqB;;AAE5B;AAEA,IAAaC,IAAwBlB,EAAU;AAE/C,SAAgBmB,EAAqB,EACnC,cACA,aACA,GAAGf,KACoD;CACvD,OACE,kBAACJ,EAAU,WAAX;EAAqB,WAAWK,EAAGI,GAAUM,GAAmBR,CAAS;EAAG,GAAIH;EAAhF,UAAA,CACE,kBAACJ,EAAU,eAAX;GAAyB,WAAU;GACjC,UAAA,kBAACgB,GAAD;IAAO,MAAK;IAAM,MAAM;GAAK,CAAA;EACN,CAAA,GACxBC,CACkB;;AAEzB;AAEA,SAAgBG,EAAiB,EAAE,cAAW,GAAGhB,KAA0D;CACzG,OAAO,kBAACJ,EAAU,OAAX;EAAiB,WAAWK,EAAGgB,GAAWd,CAAS;EAAG,GAAIH;CAAO,CAAA;AAC1E;AAEA,SAAgBkB,EAAqB,EAAE,cAAW,GAAGlB,KAA8D;CACjH,OAAO,kBAACJ,EAAU,WAAX;EAAqB,WAAWK,EAAGkB,GAAehB,CAAS;EAAG,GAAIH;CAAO,CAAA;AAClF;AAEA,IAAaoB,IAAmBxB,EAAU,OAC7ByB,IAAiBzB,EAAU;AAExC,SAAgB0B,EAAsB,EACpC,SACA,cACA,aACA,GAAGtB,KAC2E;CAC9E,OACE,kBAACJ,EAAU,YAAX;EAAsB,WAAWK,EAAGI,GAAUF,CAAS;EAAG,GAAIH;EAA9D,UAAA;GACGO,KAAQ,kBAACC,GAAD;IAAM,MAAMD;IAAM,MAAM;IAAI,WAAU;GAAY,CAAA;GAC3D,kBAAC,QAAD;IAAM,WAAU;IAAU;GAAe,CAAA;GACzC,kBAACK,GAAD;IAAO,MAAK;IAAgB,MAAM;IAAI,WAAU;GAAiB,CAAA;EAC7C;;AAE1B;AAEA,SAAgBW,EAAsB,EAAE,cAAW,GAAGvB,KAA+D;CACnH,OACE,kBAACJ,EAAU,QAAX,EAAA,UACE,kBAACA,EAAU,YAAX;EAAsB,YAAY;EAAG,kBAAkB;EAAI,WAAWK,EAAGC,GAAaC,CAAS;EAAG,GAAIH;CAAO,CAAA,EAC7F,CAAA;AAEtB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as Primitive from '@radix-ui/react-dropdown-menu';
|
|
2
|
+
import type { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';
|
|
3
|
+
import { type IconName } from '../icon/icon';
|
|
4
|
+
/**
|
|
5
|
+
* Menu of actions or options opened from a button ("More", user menu, row actions).
|
|
6
|
+
* Keyboard: arrows, type-ahead, Escape. On touch screens items grow to 44px.
|
|
7
|
+
*/
|
|
8
|
+
export declare const DropdownMenu: import("react").FC<Primitive.DropdownMenuProps>;
|
|
9
|
+
/** Use `asChild` with a Button or icon button (with `aria-label`). */
|
|
10
|
+
export declare const DropdownMenuTrigger: import("react").ForwardRefExoticComponent<Primitive.DropdownMenuTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
11
|
+
export declare function DropdownMenuContent({ className, sideOffset, align, collisionPadding, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Content>): import("react").JSX.Element;
|
|
12
|
+
interface ItemExtras {
|
|
13
|
+
icon?: IconName;
|
|
14
|
+
/** Renders the item as a link (keyboard and screen readers treat it as a menu item that navigates). */
|
|
15
|
+
href?: string;
|
|
16
|
+
/** Link component for `href` (e.g. Next.js `Link`). */
|
|
17
|
+
linkAs?: ElementType;
|
|
18
|
+
/** Keyboard shortcut hint, e.g. `⌘D`. */
|
|
19
|
+
shortcut?: string;
|
|
20
|
+
tone?: 'default' | 'danger';
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
}
|
|
23
|
+
export declare function DropdownMenuItem({ icon, shortcut, tone, href, linkAs: Link, className, children, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Item> & ItemExtras): import("react").JSX.Element;
|
|
24
|
+
export declare function DropdownMenuCheckboxItem({ className, children, ...rest }: ComponentPropsWithoutRef<typeof Primitive.CheckboxItem>): import("react").JSX.Element;
|
|
25
|
+
export declare const DropdownMenuRadioGroup: import("react").ForwardRefExoticComponent<Primitive.DropdownMenuRadioGroupProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
26
|
+
export declare function DropdownMenuRadioItem({ className, children, ...rest }: ComponentPropsWithoutRef<typeof Primitive.RadioItem>): import("react").JSX.Element;
|
|
27
|
+
export declare function DropdownMenuLabel({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Label>): import("react").JSX.Element;
|
|
28
|
+
export interface DropdownMenuHeaderProps {
|
|
29
|
+
name: string;
|
|
30
|
+
email?: string;
|
|
31
|
+
/** Role or plan shown as a small tag ("Admin"). */
|
|
32
|
+
role?: string;
|
|
33
|
+
/** Photo URL; initials otherwise. */
|
|
34
|
+
avatarSrc?: string;
|
|
35
|
+
className?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Identity band at the top of an account menu: avatar, name, email and role on the brand color.
|
|
39
|
+
* Not focusable; put it first inside `DropdownMenuContent`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function DropdownMenuHeader({ name, email, role, avatarSrc, className }: DropdownMenuHeaderProps): import("react").JSX.Element;
|
|
42
|
+
export declare function DropdownMenuSeparator({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Separator>): import("react").JSX.Element;
|
|
43
|
+
export declare const DropdownMenuGroup: import("react").ForwardRefExoticComponent<Primitive.DropdownMenuGroupProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
44
|
+
export declare const DropdownMenuSub: import("react").FC<Primitive.DropdownMenuSubProps>;
|
|
45
|
+
export declare function DropdownMenuSubTrigger({ icon, className, children, ...rest }: ComponentPropsWithoutRef<typeof Primitive.SubTrigger> & {
|
|
46
|
+
icon?: IconName;
|
|
47
|
+
}): import("react").JSX.Element;
|
|
48
|
+
export declare function DropdownMenuSubContent({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.SubContent>): import("react").JSX.Element;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx as e } from "../lib/cx.js";
|
|
3
|
+
import { Icon as t } from "../icon/icon.js";
|
|
4
|
+
import { Glyph as n } from "../lib/glyphs.js";
|
|
5
|
+
import { Avatar as r } from "../data-display/avatar.js";
|
|
6
|
+
import { menuContent as i, menuIndicatorSlot as a, menuItem as o, menuLabel as s, menuSeparator as c } from "./menu-styles.js";
|
|
7
|
+
import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
8
|
+
import * as f from "@radix-ui/react-dropdown-menu";
|
|
9
|
+
//#region src/menu/dropdown-menu.tsx
|
|
10
|
+
var p = f.Root, m = f.Trigger;
|
|
11
|
+
function h({ className: t, sideOffset: n = 6, align: r = "start", collisionPadding: a = 16, ...o }) {
|
|
12
|
+
return /* @__PURE__ */ u(f.Portal, { children: /* @__PURE__ */ u(f.Content, {
|
|
13
|
+
sideOffset: n,
|
|
14
|
+
align: r,
|
|
15
|
+
collisionPadding: a,
|
|
16
|
+
className: e(i, "[--kf-menu-max-h:var(--radix-dropdown-menu-content-available-height)]", t),
|
|
17
|
+
...o
|
|
18
|
+
}) });
|
|
19
|
+
}
|
|
20
|
+
function g({ icon: n, shortcut: r, tone: i = "default", href: a, linkAs: s = "a", className: c, children: p, ...m }) {
|
|
21
|
+
let h = /* @__PURE__ */ d(l, { children: [
|
|
22
|
+
n && /* @__PURE__ */ u(t, {
|
|
23
|
+
name: n,
|
|
24
|
+
size: 20,
|
|
25
|
+
className: "shrink-0"
|
|
26
|
+
}),
|
|
27
|
+
/* @__PURE__ */ u("span", {
|
|
28
|
+
className: "min-w-0 flex-1 truncate",
|
|
29
|
+
children: p
|
|
30
|
+
}),
|
|
31
|
+
r && /* @__PURE__ */ u("span", {
|
|
32
|
+
className: "ml-auto pl-4 font-mono text-xs text-fg-muted",
|
|
33
|
+
children: r
|
|
34
|
+
})
|
|
35
|
+
] }), g = e(o, i === "danger" && "text-danger-fg data-[highlighted]:bg-danger-surface", "no-underline", c);
|
|
36
|
+
return a ? /* @__PURE__ */ u(f.Item, {
|
|
37
|
+
asChild: !0,
|
|
38
|
+
className: g,
|
|
39
|
+
...m,
|
|
40
|
+
children: /* @__PURE__ */ u(s, {
|
|
41
|
+
href: a,
|
|
42
|
+
children: h
|
|
43
|
+
})
|
|
44
|
+
}) : /* @__PURE__ */ u(f.Item, {
|
|
45
|
+
className: g,
|
|
46
|
+
...m,
|
|
47
|
+
children: h
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function _({ className: t, children: r, ...i }) {
|
|
51
|
+
return /* @__PURE__ */ d(f.CheckboxItem, {
|
|
52
|
+
className: e(o, a, t),
|
|
53
|
+
...i,
|
|
54
|
+
children: [/* @__PURE__ */ u(f.ItemIndicator, {
|
|
55
|
+
className: "absolute left-2.5 inline-flex text-link",
|
|
56
|
+
children: /* @__PURE__ */ u(n, {
|
|
57
|
+
name: "check",
|
|
58
|
+
size: 16
|
|
59
|
+
})
|
|
60
|
+
}), r]
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
var v = f.RadioGroup;
|
|
64
|
+
function y({ className: t, children: r, ...i }) {
|
|
65
|
+
return /* @__PURE__ */ d(f.RadioItem, {
|
|
66
|
+
className: e(o, a, t),
|
|
67
|
+
...i,
|
|
68
|
+
children: [/* @__PURE__ */ u(f.ItemIndicator, {
|
|
69
|
+
className: "absolute left-3 inline-flex text-link",
|
|
70
|
+
children: /* @__PURE__ */ u(n, {
|
|
71
|
+
name: "dot",
|
|
72
|
+
size: 14
|
|
73
|
+
})
|
|
74
|
+
}), r]
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function b({ className: t, ...n }) {
|
|
78
|
+
return /* @__PURE__ */ u(f.Label, {
|
|
79
|
+
className: e(s, t),
|
|
80
|
+
...n
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function x({ name: t, email: n, role: i, avatarSrc: a, className: o }) {
|
|
84
|
+
return /* @__PURE__ */ d(f.Label, {
|
|
85
|
+
"data-theme": "dark",
|
|
86
|
+
className: e("-m-1 mb-1 flex items-center gap-3 rounded-t-md bg-primary-strong px-3.5 py-3.5 text-fg", o),
|
|
87
|
+
children: [/* @__PURE__ */ u(r, {
|
|
88
|
+
name: t,
|
|
89
|
+
src: a,
|
|
90
|
+
size: "md",
|
|
91
|
+
className: "ring-2 ring-white/30",
|
|
92
|
+
decorative: !0
|
|
93
|
+
}), /* @__PURE__ */ d("span", {
|
|
94
|
+
className: "grid min-w-0 gap-0.5",
|
|
95
|
+
children: [
|
|
96
|
+
/* @__PURE__ */ u("span", {
|
|
97
|
+
className: "truncate text-sm font-semibold",
|
|
98
|
+
children: t
|
|
99
|
+
}),
|
|
100
|
+
n && /* @__PURE__ */ u("span", {
|
|
101
|
+
className: "truncate text-xs text-fg-muted",
|
|
102
|
+
children: n
|
|
103
|
+
}),
|
|
104
|
+
i && /* @__PURE__ */ u("span", {
|
|
105
|
+
className: "mt-1 w-fit rounded-full bg-white/15 px-2 py-0.5 text-[11px] font-semibold tracking-wide uppercase",
|
|
106
|
+
children: i
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
})]
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function S({ className: t, ...n }) {
|
|
113
|
+
return /* @__PURE__ */ u(f.Separator, {
|
|
114
|
+
className: e(c, t),
|
|
115
|
+
...n
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
var C = f.Group, w = f.Sub;
|
|
119
|
+
function T({ icon: r, className: i, children: a, ...s }) {
|
|
120
|
+
return /* @__PURE__ */ d(f.SubTrigger, {
|
|
121
|
+
className: e(o, i),
|
|
122
|
+
...s,
|
|
123
|
+
children: [
|
|
124
|
+
r && /* @__PURE__ */ u(t, {
|
|
125
|
+
name: r,
|
|
126
|
+
size: 20,
|
|
127
|
+
className: "shrink-0"
|
|
128
|
+
}),
|
|
129
|
+
/* @__PURE__ */ u("span", {
|
|
130
|
+
className: "flex-1",
|
|
131
|
+
children: a
|
|
132
|
+
}),
|
|
133
|
+
/* @__PURE__ */ u(n, {
|
|
134
|
+
name: "chevron-right",
|
|
135
|
+
size: 16,
|
|
136
|
+
className: "text-fg-muted"
|
|
137
|
+
})
|
|
138
|
+
]
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function E({ className: t, ...n }) {
|
|
142
|
+
return /* @__PURE__ */ u(f.Portal, { children: /* @__PURE__ */ u(f.SubContent, {
|
|
143
|
+
sideOffset: 4,
|
|
144
|
+
collisionPadding: 16,
|
|
145
|
+
className: e(i, t),
|
|
146
|
+
...n
|
|
147
|
+
}) });
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
150
|
+
export { p as DropdownMenu, _ as DropdownMenuCheckboxItem, h as DropdownMenuContent, C as DropdownMenuGroup, x as DropdownMenuHeader, g as DropdownMenuItem, b as DropdownMenuLabel, v as DropdownMenuRadioGroup, y as DropdownMenuRadioItem, S as DropdownMenuSeparator, w as DropdownMenuSub, E as DropdownMenuSubContent, T as DropdownMenuSubTrigger, m as DropdownMenuTrigger };
|
|
151
|
+
|
|
152
|
+
//# sourceMappingURL=dropdown-menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dropdown-menu.js","names":["_Fragment","Primitive","DropdownMenu","DropdownMenuTrigger","DropdownMenuContent","rest","cx","menuContent","className","DropdownMenuItem","Link","content","Fragment","icon","Icon","shortcut","classes","menuItem","tone","href","DropdownMenuCheckboxItem","menuIndicatorSlot","Glyph","children","DropdownMenuRadioGroup","DropdownMenuRadioItem","DropdownMenuLabel","menuLabel","DropdownMenuHeader","Avatar","avatarSrc","name","email","role","DropdownMenuSeparator","menuSeparator","DropdownMenuGroup","DropdownMenuSub","DropdownMenuSubTrigger","DropdownMenuSubContent"],"sources":["../../src/menu/dropdown-menu.tsx"],"sourcesContent":["// Shares its item components' structure with the other menu files (dropdown-menu, context-menu, menubar): keep them in sync.\n'use client';\n\nimport * as Primitive from '@radix-ui/react-dropdown-menu';\nimport type { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { Icon, type IconName } from '../icon/icon';\nimport { Glyph } from '../lib/glyphs';\nimport { Avatar } from '../data-display/avatar';\nimport {\n menuContent,\n menuIndicatorSlot,\n menuItem,\n menuItemDanger,\n menuLabel,\n menuSeparator,\n menuShortcut,\n} from './menu-styles';\n\n/**\n * Menu of actions or options opened from a button (\"More\", user menu, row actions).\n * Keyboard: arrows, type-ahead, Escape. On touch screens items grow to 44px.\n */\nexport const DropdownMenu = Primitive.Root;\n/** Use `asChild` with a Button or icon button (with `aria-label`). */\nexport const DropdownMenuTrigger = Primitive.Trigger;\n\nexport function DropdownMenuContent({\n className,\n sideOffset = 6,\n align = 'start',\n collisionPadding = 16,\n ...rest\n}: ComponentPropsWithoutRef<typeof Primitive.Content>) {\n return (\n <Primitive.Portal>\n <Primitive.Content\n sideOffset={sideOffset}\n align={align}\n collisionPadding={collisionPadding}\n className={cx(menuContent, '[--kf-menu-max-h:var(--radix-dropdown-menu-content-available-height)]', className)}\n {...rest}\n />\n </Primitive.Portal>\n );\n}\n\ninterface ItemExtras {\n icon?: IconName;\n /** Renders the item as a link (keyboard and screen readers treat it as a menu item that navigates). */\n href?: string;\n /** Link component for `href` (e.g. Next.js `Link`). */\n linkAs?: ElementType;\n /** Keyboard shortcut hint, e.g. `⌘D`. */\n shortcut?: string;\n tone?: 'default' | 'danger';\n children: ReactNode;\n}\n\nexport function DropdownMenuItem({\n icon,\n shortcut,\n tone = 'default',\n href,\n linkAs: Link = 'a',\n className,\n children,\n ...rest\n}: ComponentPropsWithoutRef<typeof Primitive.Item> & ItemExtras) {\n const content = (\n <>\n {icon && <Icon name={icon} size={20} className=\"shrink-0\" />}\n <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n {shortcut && <span className={menuShortcut}>{shortcut}</span>}\n </>\n );\n const classes = cx(menuItem, tone === 'danger' && menuItemDanger, 'no-underline', className);\n if (href) {\n return (\n <Primitive.Item asChild className={classes} {...rest}>\n <Link href={href}>{content}</Link>\n </Primitive.Item>\n );\n }\n return (\n <Primitive.Item className={classes} {...rest}>\n {content}\n </Primitive.Item>\n );\n}\n\nexport function DropdownMenuCheckboxItem({\n className,\n children,\n ...rest\n}: ComponentPropsWithoutRef<typeof Primitive.CheckboxItem>) {\n return (\n <Primitive.CheckboxItem className={cx(menuItem, menuIndicatorSlot, className)} {...rest}>\n <Primitive.ItemIndicator className=\"absolute left-2.5 inline-flex text-link\">\n <Glyph name=\"check\" size={16} />\n </Primitive.ItemIndicator>\n {children}\n </Primitive.CheckboxItem>\n );\n}\n\nexport const DropdownMenuRadioGroup = Primitive.RadioGroup;\n\nexport function DropdownMenuRadioItem({\n className,\n children,\n ...rest\n}: ComponentPropsWithoutRef<typeof Primitive.RadioItem>) {\n return (\n <Primitive.RadioItem className={cx(menuItem, menuIndicatorSlot, className)} {...rest}>\n <Primitive.ItemIndicator className=\"absolute left-3 inline-flex text-link\">\n <Glyph name=\"dot\" size={14} />\n </Primitive.ItemIndicator>\n {children}\n </Primitive.RadioItem>\n );\n}\n\nexport function DropdownMenuLabel({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Label>) {\n return <Primitive.Label className={cx(menuLabel, className)} {...rest} />;\n}\n\nexport interface DropdownMenuHeaderProps {\n name: string;\n email?: string;\n /** Role or plan shown as a small tag (\"Admin\"). */\n role?: string;\n /** Photo URL; initials otherwise. */\n avatarSrc?: string;\n className?: string;\n}\n\n/**\n * Identity band at the top of an account menu: avatar, name, email and role on the brand color.\n * Not focusable; put it first inside `DropdownMenuContent`.\n */\nexport function DropdownMenuHeader({ name, email, role, avatarSrc, className }: DropdownMenuHeaderProps) {\n return (\n <Primitive.Label\n data-theme=\"dark\"\n className={cx('-m-1 mb-1 flex items-center gap-3 rounded-t-md bg-primary-strong px-3.5 py-3.5 text-fg', className)}\n >\n <Avatar name={name} src={avatarSrc} size=\"md\" className=\"ring-2 ring-white/30\" decorative />\n <span className=\"grid min-w-0 gap-0.5\">\n <span className=\"truncate text-sm font-semibold\">{name}</span>\n {email && <span className=\"truncate text-xs text-fg-muted\">{email}</span>}\n {role && (\n <span className=\"mt-1 w-fit rounded-full bg-white/15 px-2 py-0.5 text-[11px] font-semibold tracking-wide uppercase\">\n {role}\n </span>\n )}\n </span>\n </Primitive.Label>\n );\n}\n\nexport function DropdownMenuSeparator({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.Separator>) {\n return <Primitive.Separator className={cx(menuSeparator, className)} {...rest} />;\n}\n\nexport const DropdownMenuGroup = Primitive.Group;\nexport const DropdownMenuSub = Primitive.Sub;\n\nexport function DropdownMenuSubTrigger({\n icon,\n className,\n children,\n ...rest\n}: ComponentPropsWithoutRef<typeof Primitive.SubTrigger> & { icon?: IconName }) {\n return (\n <Primitive.SubTrigger className={cx(menuItem, className)} {...rest}>\n {icon && <Icon name={icon} size={20} className=\"shrink-0\" />}\n <span className=\"flex-1\">{children}</span>\n <Glyph name=\"chevron-right\" size={16} className=\"text-fg-muted\" />\n </Primitive.SubTrigger>\n );\n}\n\nexport function DropdownMenuSubContent({ className, ...rest }: ComponentPropsWithoutRef<typeof Primitive.SubContent>) {\n return (\n <Primitive.Portal>\n <Primitive.SubContent sideOffset={4} collisionPadding={16} className={cx(menuContent, className)} {...rest} />\n </Primitive.Portal>\n );\n}\n"],"mappings":";;;;;;;;;AAuBA,IAAaE,IAAeD,EAAU,MAEzBE,IAAsBF,EAAU;AAE7C,SAAgBG,EAAoB,EAClC,cACA,gBAAa,GACb,WAAQ,SACR,sBAAmB,IACnB,GAAGC,KACkD;CACrD,OACE,kBAACJ,EAAU,QAAX,EAAA,UACE,kBAACA,EAAU,SAAX;EACc;EACL;EACW;EAClB,WAAWK,EAAGC,GAAa,yEAAyEC,CAAS;EAC7G,GAAIH;CACL,CAAA,EACe,CAAA;AAEtB;AAcA,SAAgBI,EAAiB,EAC/B,SACA,aACA,UAAO,WACP,SACA,QAAQC,IAAO,KACf,cACA,aACA,GAAGL,KAC4D;CAC/D,IAAMM,IACJ,kBAAAX,GAAA,EAAA,UAAA;EACGa,KAAQ,kBAACC,GAAD;GAAM,MAAMD;GAAM,MAAM;GAAI,WAAU;EAAY,CAAA;EAC3D,kBAAC,QAAD;GAAM,WAAU;GAA2B;EAAe,CAAA;EACzDE,KAAY,kBAAC,QAAD;GAAM,WAAA;GAA0B,UAAAA;EAAe,CAAA;CAC5D,EAAA,CAAA,GAEEC,IAAUV,EAAGW,GAAUC,MAAS,YAAA,uDAA4B,gBAAgBV,CAAS;CAQ3F,OAPIW,IAEA,kBAAClB,EAAU,MAAX;EAAgB,SAAA;EAAQ,WAAWe;EAAS,GAAIX;EAC9C,UAAA,kBAACK,GAAD;GAAY;GAAO,UAAAC;EAAc,CAAA;CACnB,CAAA,IAIlB,kBAACV,EAAU,MAAX;EAAgB,WAAWe;EAAS,GAAIX;EACrC,UAAAM;CACa,CAAA;AAEpB;AAEA,SAAgBS,EAAyB,EACvC,cACA,aACA,GAAGf,KACuD;CAC1D,OACE,kBAACJ,EAAU,cAAX;EAAwB,WAAWK,EAAGW,GAAUI,GAAmBb,CAAS;EAAG,GAAIH;EAAnF,UAAA,CACE,kBAACJ,EAAU,eAAX;GAAyB,WAAU;GACjC,UAAA,kBAACqB,GAAD;IAAO,MAAK;IAAQ,MAAM;GAAK,CAAA;EACR,CAAA,GACxBC,CACqB;;AAE5B;AAEA,IAAaC,IAAyBvB,EAAU;AAEhD,SAAgBwB,EAAsB,EACpC,cACA,aACA,GAAGpB,KACoD;CACvD,OACE,kBAACJ,EAAU,WAAX;EAAqB,WAAWK,EAAGW,GAAUI,GAAmBb,CAAS;EAAG,GAAIH;EAAhF,UAAA,CACE,kBAACJ,EAAU,eAAX;GAAyB,WAAU;GACjC,UAAA,kBAACqB,GAAD;IAAO,MAAK;IAAM,MAAM;GAAK,CAAA;EACN,CAAA,GACxBC,CACkB;;AAEzB;AAEA,SAAgBG,EAAkB,EAAE,cAAW,GAAGrB,KAA0D;CAC1G,OAAO,kBAACJ,EAAU,OAAX;EAAiB,WAAWK,EAAGqB,GAAWnB,CAAS;EAAG,GAAIH;CAAO,CAAA;AAC1E;AAgBA,SAAgBuB,EAAmB,EAAE,SAAM,UAAO,SAAM,cAAW,gBAAsC;CACvG,OACE,kBAAC3B,EAAU,OAAX;EACE,cAAW;EACX,WAAWK,EAAG,0FAA0FE,CAAS;EAFnH,UAAA,CAIE,kBAACqB,GAAD;GAAc;GAAM,KAAKC;GAAW,MAAK;GAAK,WAAU;GAAuB,YAAA;EAAY,CAAA,GAC3F,kBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA;IACE,kBAAC,QAAD;KAAM,WAAU;KAAkC,UAAAC;IAAW,CAAA;IAC5DC,KAAS,kBAAC,QAAD;KAAM,WAAU;KAAkC,UAAAA;IAAY,CAAA;IACvEC,KACC,kBAAC,QAAD;KAAM,WAAU;KACb,UAAAA;IACG,CAAA;GAEJ;EACS,CAAA,CAAA;;AAErB;AAEA,SAAgBC,EAAsB,EAAE,cAAW,GAAG7B,KAA8D;CAClH,OAAO,kBAACJ,EAAU,WAAX;EAAqB,WAAWK,EAAG6B,GAAe3B,CAAS;EAAG,GAAIH;CAAO,CAAA;AAClF;AAEA,IAAa+B,IAAoBnC,EAAU,OAC9BoC,IAAkBpC,EAAU;AAEzC,SAAgBqC,EAAuB,EACrC,SACA,cACA,aACA,GAAGjC,KAC2E;CAC9E,OACE,kBAACJ,EAAU,YAAX;EAAsB,WAAWK,EAAGW,GAAUT,CAAS;EAAG,GAAIH;EAA9D,UAAA;GACGQ,KAAQ,kBAACC,GAAD;IAAM,MAAMD;IAAM,MAAM;IAAI,WAAU;GAAY,CAAA;GAC3D,kBAAC,QAAD;IAAM,WAAU;IAAU;GAAe,CAAA;GACzC,kBAACS,GAAD;IAAO,MAAK;IAAgB,MAAM;IAAI,WAAU;GAAiB,CAAA;EAC7C;;AAE1B;AAEA,SAAgBiB,EAAuB,EAAE,cAAW,GAAGlC,KAA+D;CACpH,OACE,kBAACJ,EAAU,QAAX,EAAA,UACE,kBAACA,EAAU,YAAX;EAAsB,YAAY;EAAG,kBAAkB;EAAI,WAAWK,EAAGC,GAAaC,CAAS;EAAG,GAAIH;CAAO,CAAA,EAC7F,CAAA;AAEtB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Shared classes for DropdownMenu, ContextMenu and Menubar. Items grow to 44px on touch screens. */
|
|
2
|
+
export declare const menuContent = "kf-menu z-50 min-w-[12rem] max-w-[calc(100vw-2rem)] overflow-y-auto rounded-md border border-border bg-surface p-1 font-sans text-fg shadow-overlay focus:outline-none max-h-[var(--kf-menu-max-h)]";
|
|
3
|
+
export declare const menuItem: string;
|
|
4
|
+
export declare const menuItemDanger = "text-danger-fg data-[highlighted]:bg-danger-surface";
|
|
5
|
+
export declare const menuIndicatorSlot = "pl-8";
|
|
6
|
+
export declare const menuLabel = "px-2.5 pt-2 pb-1 text-xs font-semibold tracking-wide text-fg-muted uppercase";
|
|
7
|
+
export declare const menuSeparator = "my-1 h-px bg-border";
|
|
8
|
+
export declare const menuShortcut = "ml-auto pl-4 font-mono text-xs text-fg-muted";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/menu/menu-styles.ts
|
|
2
|
+
var e = "kf-menu z-50 min-w-[12rem] max-w-[calc(100vw-2rem)] overflow-y-auto rounded-md border border-border bg-surface p-1 font-sans text-fg shadow-overlay focus:outline-none max-h-[var(--kf-menu-max-h)]", t = "relative flex min-h-9 cursor-pointer select-none items-center gap-2.5 rounded-sm px-2.5 py-1.5 text-sm outline-none pointer-coarse:min-h-11 data-[highlighted]:bg-surface-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-45 data-[state=open]:bg-surface-muted", n = "text-danger-fg data-[highlighted]:bg-danger-surface", r = "pl-8", i = "px-2.5 pt-2 pb-1 text-xs font-semibold tracking-wide text-fg-muted uppercase", a = "my-1 h-px bg-border", o = "ml-auto pl-4 font-mono text-xs text-fg-muted";
|
|
3
|
+
//#endregion
|
|
4
|
+
export { e as menuContent, r as menuIndicatorSlot, t as menuItem, n as menuItemDanger, i as menuLabel, a as menuSeparator, o as menuShortcut };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=menu-styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu-styles.js","names":["menuContent","menuItem","menuItemDanger","menuIndicatorSlot","menuLabel","menuSeparator","menuShortcut"],"sources":["../../src/menu/menu-styles.ts"],"sourcesContent":["/** Shared classes for DropdownMenu, ContextMenu and Menubar. Items grow to 44px on touch screens. */\nexport const menuContent =\n 'kf-menu z-50 min-w-[12rem] max-w-[calc(100vw-2rem)] overflow-y-auto rounded-md border border-border bg-surface p-1 font-sans text-fg shadow-overlay focus:outline-none max-h-[var(--kf-menu-max-h)]';\n\nexport const menuItem =\n 'relative flex min-h-9 cursor-pointer select-none items-center gap-2.5 rounded-sm px-2.5 py-1.5 text-sm outline-none pointer-coarse:min-h-11 ' +\n 'data-[highlighted]:bg-surface-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-45 data-[state=open]:bg-surface-muted';\n\nexport const menuItemDanger = 'text-danger-fg data-[highlighted]:bg-danger-surface';\nexport const menuIndicatorSlot = 'pl-8';\nexport const menuLabel = 'px-2.5 pt-2 pb-1 text-xs font-semibold tracking-wide text-fg-muted uppercase';\nexport const menuSeparator = 'my-1 h-px bg-border';\nexport const menuShortcut = 'ml-auto pl-4 font-mono text-xs text-fg-muted';\n"],"mappings":";AACA,IAAaA,IACX,uMAEWC,IACX,qRAGWC,IAAiB,uDACjBC,IAAoB,QACpBC,IAAY,gFACZC,IAAgB,uBAChBC,IAAe"}
|