@boost33/ui 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/CHANGELOG.md +214 -123
  2. package/dist/backdrop-icons.d.ts +53 -0
  3. package/dist/backdrop-icons.js +62 -0
  4. package/dist/backdrop-icons.js.map +1 -0
  5. package/dist/backdrop.css +1 -0
  6. package/dist/backdrop.d.ts +46 -0
  7. package/dist/backdrop.js +127 -0
  8. package/dist/backdrop.js.map +1 -0
  9. package/dist/components/AccountMenu/AccountMenu.d.ts +42 -32
  10. package/dist/components/AccountMenu/AccountMenu.js +66 -48
  11. package/dist/components/AccountMenu/AccountMenu.js.map +1 -1
  12. package/dist/components/AccountMenu/AccountMenu.module.css.js +44 -38
  13. package/dist/components/AccountMenu/AccountMenu.module.css.js.map +1 -1
  14. package/dist/components/AccountMenu/StandardAccountMenu.d.ts +87 -0
  15. package/dist/components/AccountMenu/StandardAccountMenu.js +86 -0
  16. package/dist/components/AccountMenu/StandardAccountMenu.js.map +1 -0
  17. package/dist/components/AccountMenu/icons.d.ts +2 -2
  18. package/dist/components/AccountMenu/icons.js +21 -8
  19. package/dist/components/AccountMenu/icons.js.map +1 -1
  20. package/dist/components/AccountMenu/initials.d.ts +11 -0
  21. package/dist/components/AccountMenu/initials.js +8 -0
  22. package/dist/components/AccountMenu/initials.js.map +1 -0
  23. package/dist/components/AccountMenu/labels.d.ts +64 -3
  24. package/dist/components/AccountMenu/labels.js +33 -5
  25. package/dist/components/AccountMenu/labels.js.map +1 -1
  26. package/dist/components/AccountMenu/use-menu.d.ts +34 -0
  27. package/dist/components/AccountMenu/use-menu.js +102 -0
  28. package/dist/components/AccountMenu/use-menu.js.map +1 -0
  29. package/dist/components/Backdrop/BackdropAppMenu.d.ts +55 -0
  30. package/dist/components/Backdrop/BackdropAppMenu.js +79 -0
  31. package/dist/components/Backdrop/BackdropAppMenu.js.map +1 -0
  32. package/dist/components/Backdrop/BackdropAppMenu.module.css.js +48 -0
  33. package/dist/components/Backdrop/BackdropAppMenu.module.css.js.map +1 -0
  34. package/dist/components/Backdrop/BackdropBasics.d.ts +129 -0
  35. package/dist/components/Backdrop/BackdropBasics.js +130 -0
  36. package/dist/components/Backdrop/BackdropBasics.js.map +1 -0
  37. package/dist/components/Backdrop/BackdropBasics.module.css.js +71 -0
  38. package/dist/components/Backdrop/BackdropBasics.module.css.js.map +1 -0
  39. package/dist/components/Backdrop/BackdropButton.d.ts +63 -0
  40. package/dist/components/Backdrop/BackdropButton.js +59 -0
  41. package/dist/components/Backdrop/BackdropButton.js.map +1 -0
  42. package/dist/components/Backdrop/BackdropButton.module.css.js +41 -0
  43. package/dist/components/Backdrop/BackdropButton.module.css.js.map +1 -0
  44. package/dist/components/Backdrop/BackdropCharts.d.ts +158 -0
  45. package/dist/components/Backdrop/BackdropCharts.js +222 -0
  46. package/dist/components/Backdrop/BackdropCharts.js.map +1 -0
  47. package/dist/components/Backdrop/BackdropCharts.module.css.js +109 -0
  48. package/dist/components/Backdrop/BackdropCharts.module.css.js.map +1 -0
  49. package/dist/components/Backdrop/BackdropChrome.d.ts +26 -0
  50. package/dist/components/Backdrop/BackdropChrome.js +35 -0
  51. package/dist/components/Backdrop/BackdropChrome.js.map +1 -0
  52. package/dist/components/Backdrop/BackdropConversation.d.ts +67 -0
  53. package/dist/components/Backdrop/BackdropConversation.js +76 -0
  54. package/dist/components/Backdrop/BackdropConversation.js.map +1 -0
  55. package/dist/components/Backdrop/BackdropConversation.module.css.js +44 -0
  56. package/dist/components/Backdrop/BackdropConversation.module.css.js.map +1 -0
  57. package/dist/components/Backdrop/BackdropData.d.ts +195 -0
  58. package/dist/components/Backdrop/BackdropData.js +204 -0
  59. package/dist/components/Backdrop/BackdropData.js.map +1 -0
  60. package/dist/components/Backdrop/BackdropData.module.css.js +135 -0
  61. package/dist/components/Backdrop/BackdropData.module.css.js.map +1 -0
  62. package/dist/components/Backdrop/BackdropDisplay.d.ts +122 -0
  63. package/dist/components/Backdrop/BackdropDisplay.js +80 -0
  64. package/dist/components/Backdrop/BackdropDisplay.js.map +1 -0
  65. package/dist/components/Backdrop/BackdropDisplay.module.css.js +80 -0
  66. package/dist/components/Backdrop/BackdropDisplay.module.css.js.map +1 -0
  67. package/dist/components/Backdrop/BackdropFields.d.ts +122 -0
  68. package/dist/components/Backdrop/BackdropFields.js +196 -0
  69. package/dist/components/Backdrop/BackdropFields.js.map +1 -0
  70. package/dist/components/Backdrop/BackdropFields.module.css.js +104 -0
  71. package/dist/components/Backdrop/BackdropFields.module.css.js.map +1 -0
  72. package/dist/components/Backdrop/BackdropFlows.d.ts +128 -0
  73. package/dist/components/Backdrop/BackdropFlows.js +156 -0
  74. package/dist/components/Backdrop/BackdropFlows.js.map +1 -0
  75. package/dist/components/Backdrop/BackdropFlows.module.css.js +80 -0
  76. package/dist/components/Backdrop/BackdropFlows.module.css.js.map +1 -0
  77. package/dist/components/Backdrop/BackdropFrame.d.ts +36 -0
  78. package/dist/components/Backdrop/BackdropFrame.js +15 -0
  79. package/dist/components/Backdrop/BackdropFrame.js.map +1 -0
  80. package/dist/components/Backdrop/BackdropFrame.module.css.js +14 -0
  81. package/dist/components/Backdrop/BackdropFrame.module.css.js.map +1 -0
  82. package/dist/components/Backdrop/BackdropGlobalPanels.d.ts +272 -0
  83. package/dist/components/Backdrop/BackdropGlobalPanels.js +264 -0
  84. package/dist/components/Backdrop/BackdropGlobalPanels.js.map +1 -0
  85. package/dist/components/Backdrop/BackdropGlobalPanels.module.css.js +201 -0
  86. package/dist/components/Backdrop/BackdropGlobalPanels.module.css.js.map +1 -0
  87. package/dist/components/Backdrop/BackdropHub.d.ts +80 -0
  88. package/dist/components/Backdrop/BackdropHub.js +92 -0
  89. package/dist/components/Backdrop/BackdropHub.js.map +1 -0
  90. package/dist/components/Backdrop/BackdropHub.module.css.js +40 -0
  91. package/dist/components/Backdrop/BackdropHub.module.css.js.map +1 -0
  92. package/dist/components/Backdrop/BackdropLists.d.ts +165 -0
  93. package/dist/components/Backdrop/BackdropLists.js +162 -0
  94. package/dist/components/Backdrop/BackdropLists.js.map +1 -0
  95. package/dist/components/Backdrop/BackdropLists.module.css.js +114 -0
  96. package/dist/components/Backdrop/BackdropLists.module.css.js.map +1 -0
  97. package/dist/components/Backdrop/BackdropOverlays.d.ts +175 -0
  98. package/dist/components/Backdrop/BackdropOverlays.js +252 -0
  99. package/dist/components/Backdrop/BackdropOverlays.js.map +1 -0
  100. package/dist/components/Backdrop/BackdropOverlays.module.css.js +104 -0
  101. package/dist/components/Backdrop/BackdropOverlays.module.css.js.map +1 -0
  102. package/dist/components/Backdrop/BackdropPage.d.ts +73 -0
  103. package/dist/components/Backdrop/BackdropPage.js +65 -0
  104. package/dist/components/Backdrop/BackdropPage.js.map +1 -0
  105. package/dist/components/Backdrop/BackdropPage.module.css.js +46 -0
  106. package/dist/components/Backdrop/BackdropPage.module.css.js.map +1 -0
  107. package/dist/components/Backdrop/BackdropPatterns.d.ts +224 -0
  108. package/dist/components/Backdrop/BackdropPatterns.js +202 -0
  109. package/dist/components/Backdrop/BackdropPatterns.js.map +1 -0
  110. package/dist/components/Backdrop/BackdropPatterns.module.css.js +114 -0
  111. package/dist/components/Backdrop/BackdropPatterns.module.css.js.map +1 -0
  112. package/dist/components/Backdrop/BackdropRail.d.ts +63 -0
  113. package/dist/components/Backdrop/BackdropRail.js +98 -0
  114. package/dist/components/Backdrop/BackdropRail.js.map +1 -0
  115. package/dist/components/Backdrop/BackdropRail.module.css.js +42 -0
  116. package/dist/components/Backdrop/BackdropRail.module.css.js.map +1 -0
  117. package/dist/components/Backdrop/BackdropSheets.d.ts +68 -0
  118. package/dist/components/Backdrop/BackdropSheets.js +75 -0
  119. package/dist/components/Backdrop/BackdropSheets.js.map +1 -0
  120. package/dist/components/Backdrop/BackdropSheets.module.css.js +42 -0
  121. package/dist/components/Backdrop/BackdropSheets.module.css.js.map +1 -0
  122. package/dist/components/Backdrop/BackdropTabs.d.ts +20 -0
  123. package/dist/components/Backdrop/BackdropTabs.js +31 -0
  124. package/dist/components/Backdrop/BackdropTabs.js.map +1 -0
  125. package/dist/components/Backdrop/BackdropTabs.module.css.js +16 -0
  126. package/dist/components/Backdrop/BackdropTabs.module.css.js.map +1 -0
  127. package/dist/components/Backdrop/BackdropTooltip.d.ts +21 -0
  128. package/dist/components/Backdrop/BackdropTooltip.js +15 -0
  129. package/dist/components/Backdrop/BackdropTooltip.js.map +1 -0
  130. package/dist/components/Backdrop/BackdropTooltip.module.css.js +18 -0
  131. package/dist/components/Backdrop/BackdropTooltip.module.css.js.map +1 -0
  132. package/dist/components/Backdrop/BackdropTopStrip.d.ts +65 -0
  133. package/dist/components/Backdrop/BackdropTopStrip.js +46 -0
  134. package/dist/components/Backdrop/BackdropTopStrip.js.map +1 -0
  135. package/dist/components/Backdrop/BackdropTopStrip.module.css.js +40 -0
  136. package/dist/components/Backdrop/BackdropTopStrip.module.css.js.map +1 -0
  137. package/dist/components/Backdrop/cx.d.ts +2 -0
  138. package/dist/components/Backdrop/cx.js +7 -0
  139. package/dist/components/Backdrop/cx.js.map +1 -0
  140. package/dist/components/Backdrop/icons.d.ts +70 -0
  141. package/dist/components/Backdrop/icons.js +103 -0
  142. package/dist/components/Backdrop/icons.js.map +1 -0
  143. package/dist/components/TopBar/TopBar.d.ts +8 -1
  144. package/dist/components/TopBar/TopBar.js +19 -16
  145. package/dist/components/TopBar/TopBar.js.map +1 -1
  146. package/dist/index.d.ts +4 -2
  147. package/dist/index.js +40 -36
  148. package/dist/index.js.map +1 -1
  149. package/dist/style.css +1 -1
  150. package/package.json +23 -4
@@ -0,0 +1,68 @@
1
+ import { ReactNode } from 'react';
2
+ export interface BackdropHubSheetProps {
3
+ children: ReactNode;
4
+ /**
5
+ * `page` (default): the hub's 64px side padding and 28px rhythm. `bare`: no
6
+ * padding, for a global page that lays out its own columns (Inbox, Settings).
7
+ */
8
+ padding?: 'page' | 'bare';
9
+ /** A side panel floating over this sheet (BackdropSidePanel). */
10
+ panel?: ReactNode;
11
+ className?: string;
12
+ }
13
+ export declare function BackdropHubSheet({ children, padding, panel, className }: BackdropHubSheetProps): import("react").JSX.Element;
14
+ export interface BackdropAppLayerProps {
15
+ /** The app menu column: a BackdropAppMenu. */
16
+ menu: ReactNode;
17
+ /** Layer 1: a BackdropContentSheet. */
18
+ children: ReactNode;
19
+ className?: string;
20
+ }
21
+ export declare function BackdropAppLayer({ menu, children, className }: BackdropAppLayerProps): import("react").JSX.Element;
22
+ export interface BackdropContentSheetProps {
23
+ children: ReactNode;
24
+ /** `page` (default): 40px padding, 24px rhythm. `bare`: none. */
25
+ padding?: 'page' | 'bare';
26
+ /** A side panel floating over this sheet (BackdropSidePanel). */
27
+ panel?: ReactNode;
28
+ className?: string;
29
+ }
30
+ export declare function BackdropContentSheet({ children, padding, panel, className }: BackdropContentSheetProps): import("react").JSX.Element;
31
+ export type BackdropSidePanelWidth = 'default' | 'wide';
32
+ export interface BackdropSidePanelProps {
33
+ /** The panel's heading: the item it peeks at ("Message · Step 2"). */
34
+ title: ReactNode;
35
+ /** One fact line under the title (with `leading`, the subtitle: the person's company). */
36
+ facts?: ReactNode;
37
+ /**
38
+ * A mark before the title: a person's avatar on a message thread. The header
39
+ * then centres its row on it. Decorative: the title names the panel.
40
+ */
41
+ leading?: ReactNode;
42
+ /** `default` 440px. `wide` 484px, for message threads only (ADR-0017, D6). */
43
+ width?: BackdropSidePanelWidth;
44
+ /** The close button's accessible name ("Close"). */
45
+ closeLabel: string;
46
+ onClose?: () => void;
47
+ /**
48
+ * Step through the list the panel was opened from without closing it
49
+ * (research addition, 9 Nov). Each takes its own accessible name; omit both
50
+ * when the panel was not opened from a list.
51
+ */
52
+ previous?: BackdropSidePanelStep;
53
+ next?: BackdropSidePanelStep;
54
+ children: ReactNode;
55
+ /** Actions pinned to the panel's foot ([Approve] · "Skip"). */
56
+ footer?: ReactNode;
57
+ /** Move focus into the panel as it mounts. On by default; a story beside other stories turns it off. */
58
+ autoFocus?: boolean;
59
+ className?: string;
60
+ }
61
+ export interface BackdropSidePanelStep {
62
+ /** "Previous message" / "Next message". */
63
+ label: string;
64
+ onClick?: () => void;
65
+ /** At the first or last item of the list. */
66
+ disabled?: boolean;
67
+ }
68
+ export declare function BackdropSidePanel({ title, facts, leading, width, closeLabel, onClose, previous, next, children, footer, autoFocus, className, }: BackdropSidePanelProps): import("react").JSX.Element;
@@ -0,0 +1,75 @@
1
+ "use client";
2
+ import { jsxs as i, jsx as a } from "react/jsx-runtime";
3
+ import { useRef as C, useEffect as P } from "react";
4
+ import e from "./BackdropSheets.module.css.js";
5
+ import { cx as o } from "./cx.js";
6
+ import { ChevronUp as S, ChevronDown as D, Close as E } from "./icons.js";
7
+ import { BackdropIconButton as f } from "./BackdropButton.js";
8
+ function x({ children: n, padding: d = "page", panel: l, className: r }) {
9
+ return /* @__PURE__ */ i("div", { className: o(e.hubSheet, r), children: [
10
+ /* @__PURE__ */ a("div", { className: o(e.scroll, d === "page" && e.hubPadding), children: n }),
11
+ l
12
+ ] });
13
+ }
14
+ function z({ menu: n, children: d, className: l }) {
15
+ return /* @__PURE__ */ i("div", { className: o(e.appLayer, l), children: [
16
+ n,
17
+ d
18
+ ] });
19
+ }
20
+ function A({ children: n, padding: d = "page", panel: l, className: r }) {
21
+ return /* @__PURE__ */ i("div", { className: o(e.contentSheet, r), children: [
22
+ /* @__PURE__ */ a("div", { className: o(e.scroll, d === "page" && e.contentPadding), children: n }),
23
+ l
24
+ ] });
25
+ }
26
+ function M({
27
+ title: n,
28
+ facts: d,
29
+ leading: l,
30
+ width: r = "default",
31
+ closeLabel: v,
32
+ onClose: p,
33
+ previous: t,
34
+ next: s,
35
+ children: k,
36
+ footer: h,
37
+ autoFocus: y = !0,
38
+ className: g
39
+ }) {
40
+ const B = typeof n == "string" ? n : void 0, m = C(null);
41
+ return P(() => {
42
+ var b;
43
+ const c = document.activeElement;
44
+ return y && ((b = m.current) == null || b.focus({ preventScroll: !0 })), () => {
45
+ var N;
46
+ const u = document.activeElement;
47
+ (!u || u === document.body || !!((N = m.current) != null && N.contains(u))) && c instanceof HTMLElement && c !== document.body && c.isConnected && c.focus();
48
+ };
49
+ }, []), /* @__PURE__ */ i("aside", { ref: m, tabIndex: -1, onKeyDown: (c) => {
50
+ c.key !== "Escape" || c.defaultPrevented || !p || (c.preventDefault(), c.stopPropagation(), p());
51
+ }, className: o(e.sidePanel, r === "wide" && e.sidePanelWide, g), "aria-label": B, children: [
52
+ /* @__PURE__ */ i("div", { className: o(e.panelHeader, !!l && e.panelHeaderLeading), children: [
53
+ l && /* @__PURE__ */ a("span", { className: e.panelLeading, "aria-hidden": "true", children: l }),
54
+ /* @__PURE__ */ i("div", { className: e.panelHeading, children: [
55
+ /* @__PURE__ */ a("h2", { className: e.panelTitle, children: n }),
56
+ d && /* @__PURE__ */ a("p", { className: e.panelFacts, children: d })
57
+ ] }),
58
+ /* @__PURE__ */ i("div", { className: e.panelControls, children: [
59
+ t && /* @__PURE__ */ a(f, { label: t.label, icon: /* @__PURE__ */ a(S, {}), onClick: t.onClick, disabled: t.disabled }),
60
+ s && /* @__PURE__ */ a(f, { label: s.label, icon: /* @__PURE__ */ a(D, { size: 18 }), onClick: s.onClick, disabled: s.disabled }),
61
+ (t || s) && /* @__PURE__ */ a("span", { className: e.panelDivider, "aria-hidden": "true" }),
62
+ /* @__PURE__ */ a(f, { label: v, icon: /* @__PURE__ */ a(E, {}), onClick: p, tooltipSide: "left" })
63
+ ] })
64
+ ] }),
65
+ /* @__PURE__ */ a("div", { className: e.panelBody, children: k }),
66
+ h && /* @__PURE__ */ a("div", { className: e.panelFooter, children: h })
67
+ ] });
68
+ }
69
+ export {
70
+ z as BackdropAppLayer,
71
+ A as BackdropContentSheet,
72
+ x as BackdropHubSheet,
73
+ M as BackdropSidePanel
74
+ };
75
+ //# sourceMappingURL=BackdropSheets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackdropSheets.js","sources":["../../../src/components/Backdrop/BackdropSheets.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useRef, type KeyboardEvent, type ReactNode } from 'react'\nimport styles from './BackdropSheets.module.css'\nimport { cx } from './cx'\nimport { ChevronDown, ChevronUp, Close } from './icons'\nimport { BackdropIconButton } from './BackdropButton'\n\n/* ── Hub sheet ─────────────────────────────────────────────────────────── */\n\nexport interface BackdropHubSheetProps {\n children: ReactNode\n /**\n * `page` (default): the hub's 64px side padding and 28px rhythm. `bare`: no\n * padding, for a global page that lays out its own columns (Inbox, Settings).\n */\n padding?: 'page' | 'bare'\n /** A side panel floating over this sheet (BackdropSidePanel). */\n panel?: ReactNode\n className?: string\n}\n\n/*\n * The hub's white sheet. It sits directly on the frame (there is no app menu on\n * the hub), wears the frame theme's edge, and runs off the bottom: no bottom\n * gutter, square bottom corners, and its content scrolls inside it.\n */\nexport function BackdropHubSheet({ children, padding = 'page', panel, className }: BackdropHubSheetProps) {\n return (\n <div className={cx(styles.hubSheet, className)}>\n <div className={cx(styles.scroll, padding === 'page' && styles.hubPadding)}>{children}</div>\n {panel}\n </div>\n )\n}\n\n/* ── App layer (layer 2 sheet holding layer 1) ─────────────────────────── */\n\nexport interface BackdropAppLayerProps {\n /** The app menu column: a BackdropAppMenu. */\n menu: ReactNode\n /** Layer 1: a BackdropContentSheet. */\n children: ReactNode\n className?: string\n}\n\n/*\n * Layer 2: the panel-grey sheet on the frame that carries the app's menu and,\n * inset 6px top and right, the white content sheet. It keeps a 12px gutter to\n * the frame on the right and at the bottom; the content sheet inside it runs\n * off the bottom (round 4, V4 geometry).\n */\nexport function BackdropAppLayer({ menu, children, className }: BackdropAppLayerProps) {\n return (\n <div className={cx(styles.appLayer, className)}>\n {menu}\n {children}\n </div>\n )\n}\n\n/* ── Content sheet (layer 1) ───────────────────────────────────────────── */\n\nexport interface BackdropContentSheetProps {\n children: ReactNode\n /** `page` (default): 40px padding, 24px rhythm. `bare`: none. */\n padding?: 'page' | 'bare'\n /** A side panel floating over this sheet (BackdropSidePanel). */\n panel?: ReactNode\n className?: string\n}\n\nexport function BackdropContentSheet({ children, padding = 'page', panel, className }: BackdropContentSheetProps) {\n return (\n <div className={cx(styles.contentSheet, className)}>\n <div className={cx(styles.scroll, padding === 'page' && styles.contentPadding)}>{children}</div>\n {panel}\n </div>\n )\n}\n\n/* ── Side panel ────────────────────────────────────────────────────────── */\n\nexport type BackdropSidePanelWidth = 'default' | 'wide'\n\nexport interface BackdropSidePanelProps {\n /** The panel's heading: the item it peeks at (\"Message · Step 2\"). */\n title: ReactNode\n /** One fact line under the title (with `leading`, the subtitle: the person's company). */\n facts?: ReactNode\n /**\n * A mark before the title: a person's avatar on a message thread. The header\n * then centres its row on it. Decorative: the title names the panel.\n */\n leading?: ReactNode\n /** `default` 440px. `wide` 484px, for message threads only (ADR-0017, D6). */\n width?: BackdropSidePanelWidth\n /** The close button's accessible name (\"Close\"). */\n closeLabel: string\n onClose?: () => void\n /**\n * Step through the list the panel was opened from without closing it\n * (research addition, 9 Nov). Each takes its own accessible name; omit both\n * when the panel was not opened from a list.\n */\n previous?: BackdropSidePanelStep\n next?: BackdropSidePanelStep\n children: ReactNode\n /** Actions pinned to the panel's foot ([Approve] · \"Skip\"). */\n footer?: ReactNode\n /** Move focus into the panel as it mounts. On by default; a story beside other stories turns it off. */\n autoFocus?: boolean\n className?: string\n}\n\nexport interface BackdropSidePanelStep {\n /** \"Previous message\" / \"Next message\". */\n label: string\n onClick?: () => void\n /** At the first or last item of the list. */\n disabled?: boolean\n}\n\n/*\n * A floating card over the content sheet: peek at one item while the list\n * stays (the depth rule). 440px, inset 6px from the sheet's top, right and\n * bottom, radius 10 all round, no scrim -- layer 1 stays visible and usable\n * beside it (round 5, decision 2). Content longer than the card scrolls inside.\n *\n * A complementary landmark named by its title, not a dialog: it does not trap\n * focus or block the page. Open while it is mounted. On mount it takes focus\n * (the landmark itself, so a screen reader announces its name, without a ring:\n * it is a landing point, not a control) unless `autoFocus` is false. Escape\n * inside it calls `onClose`, and on unmount focus returns to wherever it was\n * when the panel opened -- the list row it was opened from -- when focus would\n * otherwise be stranded in the panel or dropped to the body. Stepping with\n * previous / next keeps it mounted, so focus stays in the panel.\n */\nexport function BackdropSidePanel({\n title,\n facts,\n leading,\n width = 'default',\n closeLabel,\n onClose,\n previous,\n next,\n children,\n footer,\n autoFocus = true,\n className,\n}: BackdropSidePanelProps) {\n const name = typeof title === 'string' ? title : undefined\n const panel = useRef<HTMLElement | null>(null)\n\n useEffect(() => {\n const opener = document.activeElement\n if (autoFocus) panel.current?.focus({ preventScroll: true })\n return () => {\n const active = document.activeElement\n const stranded = !active || active === document.body || Boolean(panel.current?.contains(active))\n if (stranded && opener instanceof HTMLElement && opener !== document.body && opener.isConnected) opener.focus()\n }\n // Mount and unmount only: a new title while stepping is the same panel.\n }, [])\n\n const onKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n // A popover inside the panel stops its own Escape, so this one only sees\n // an Escape meant for the panel.\n if (event.key !== 'Escape' || event.defaultPrevented || !onClose) return\n event.preventDefault()\n event.stopPropagation()\n onClose()\n }\n\n return (\n <aside ref={panel} tabIndex={-1} onKeyDown={onKeyDown} className={cx(styles.sidePanel, width === 'wide' && styles.sidePanelWide, className)} aria-label={name}>\n <div className={cx(styles.panelHeader, Boolean(leading) && styles.panelHeaderLeading)}>\n {leading && (\n <span className={styles.panelLeading} aria-hidden=\"true\">\n {leading}\n </span>\n )}\n <div className={styles.panelHeading}>\n <h2 className={styles.panelTitle}>{title}</h2>\n {facts && <p className={styles.panelFacts}>{facts}</p>}\n </div>\n <div className={styles.panelControls}>\n {previous && (\n <BackdropIconButton label={previous.label} icon={<ChevronUp />} onClick={previous.onClick} disabled={previous.disabled} />\n )}\n {next && <BackdropIconButton label={next.label} icon={<ChevronDown size={18} />} onClick={next.onClick} disabled={next.disabled} />}\n {(previous || next) && <span className={styles.panelDivider} aria-hidden=\"true\" />}\n <BackdropIconButton label={closeLabel} icon={<Close />} onClick={onClose} tooltipSide=\"left\" />\n </div>\n </div>\n <div className={styles.panelBody}>{children}</div>\n {footer && <div className={styles.panelFooter}>{footer}</div>}\n </aside>\n )\n}\n"],"names":["BackdropHubSheet","children","padding","panel","className","cx","styles","jsx","BackdropAppLayer","menu","BackdropContentSheet","BackdropSidePanel","title","facts","leading","width","closeLabel","onClose","previous","next","footer","autoFocus","name","useRef","useEffect","opener","_a","active","event","jsxs","BackdropIconButton","ChevronUp","ChevronDown","Close"],"mappings":";;;;;;;AA2BO,SAASA,EAAiB,EAAE,UAAAC,GAAU,SAAAC,IAAU,QAAQ,OAAAC,GAAO,WAAAC,KAAoC;AACxG,2BACG,OAAA,EAAI,WAAWC,EAAGC,EAAO,UAAUF,CAAS,GAC3C,UAAA;AAAA,IAAA,gBAAAG,EAAC,OAAA,EAAI,WAAWF,EAAGC,EAAO,QAAQJ,MAAY,UAAUI,EAAO,UAAU,GAAI,UAAAL,EAAA,CAAS;AAAA,IACrFE;AAAA,EAAA,GACH;AAEJ;AAkBO,SAASK,EAAiB,EAAE,MAAAC,GAAM,UAAAR,GAAU,WAAAG,KAAoC;AACrF,2BACG,OAAA,EAAI,WAAWC,EAAGC,EAAO,UAAUF,CAAS,GAC1C,UAAA;AAAA,IAAAK;AAAA,IACAR;AAAA,EAAA,GACH;AAEJ;AAaO,SAASS,EAAqB,EAAE,UAAAT,GAAU,SAAAC,IAAU,QAAQ,OAAAC,GAAO,WAAAC,KAAwC;AAChH,2BACG,OAAA,EAAI,WAAWC,EAAGC,EAAO,cAAcF,CAAS,GAC/C,UAAA;AAAA,IAAA,gBAAAG,EAAC,OAAA,EAAI,WAAWF,EAAGC,EAAO,QAAQJ,MAAY,UAAUI,EAAO,cAAc,GAAI,UAAAL,EAAA,CAAS;AAAA,IACzFE;AAAA,EAAA,GACH;AAEJ;AA2DO,SAASQ,EAAkB;AAAA,EAChC,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,SAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,YAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC;AAAA,EACA,UAAAlB;AAAA,EACA,QAAAmB;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,WAAAjB;AACF,GAA2B;AACzB,QAAMkB,IAAO,OAAOV,KAAU,WAAWA,IAAQ,QAC3CT,IAAQoB,EAA2B,IAAI;AAE7C,SAAAC,EAAU,MAAM;;AACd,UAAMC,IAAS,SAAS;AACxB,WAAIJ,OAAWK,IAAAvB,EAAM,YAAN,QAAAuB,EAAe,MAAM,EAAE,eAAe,QAC9C,MAAM;;AACX,YAAMC,IAAS,SAAS;AAExB,OADiB,CAACA,KAAUA,MAAW,SAAS,QAAQ,IAAQD,IAAAvB,EAAM,YAAN,QAAAuB,EAAe,SAASC,QACxEF,aAAkB,eAAeA,MAAW,SAAS,QAAQA,EAAO,eAAaA,EAAO,MAAA;AAAA,IAC1G;AAAA,EAEF,GAAG,CAAA,CAAE,qBAYF,SAAA,EAAM,KAAKtB,GAAO,UAAU,IAAI,WAVjB,CAACyB,MAAsC;AAGvD,IAAIA,EAAM,QAAQ,YAAYA,EAAM,oBAAoB,CAACX,MACzDW,EAAM,eAAA,GACNA,EAAM,gBAAA,GACNX,EAAA;AAAA,EACF,GAGyD,WAAWZ,EAAGC,EAAO,WAAWS,MAAU,UAAUT,EAAO,eAAeF,CAAS,GAAG,cAAYkB,GACvJ,UAAA;AAAA,IAAA,gBAAAO,EAAC,OAAA,EAAI,WAAWxB,EAAGC,EAAO,aAAa,EAAQQ,KAAYR,EAAO,kBAAkB,GACjF,UAAA;AAAA,MAAAQ,uBACE,QAAA,EAAK,WAAWR,EAAO,cAAc,eAAY,QAC/C,UAAAQ,EAAA,CACH;AAAA,MAEF,gBAAAe,EAAC,OAAA,EAAI,WAAWvB,EAAO,cACrB,UAAA;AAAA,QAAA,gBAAAC,EAAC,MAAA,EAAG,WAAWD,EAAO,YAAa,UAAAM,GAAM;AAAA,QACxCC,KAAS,gBAAAN,EAAC,KAAA,EAAE,WAAWD,EAAO,YAAa,UAAAO,EAAA,CAAM;AAAA,MAAA,GACpD;AAAA,MACA,gBAAAgB,EAAC,OAAA,EAAI,WAAWvB,EAAO,eACpB,UAAA;AAAA,QAAAY,KACC,gBAAAX,EAACuB,GAAA,EAAmB,OAAOZ,EAAS,OAAO,MAAM,gBAAAX,EAACwB,GAAA,CAAA,CAAU,GAAI,SAASb,EAAS,SAAS,UAAUA,EAAS,UAAU;AAAA,QAEzHC,KAAQ,gBAAAZ,EAACuB,GAAA,EAAmB,OAAOX,EAAK,OAAO,MAAM,gBAAAZ,EAACyB,GAAA,EAAY,MAAM,IAAI,GAAI,SAASb,EAAK,SAAS,UAAUA,EAAK,UAAU;AAAA,SAC/HD,KAAYC,MAAS,gBAAAZ,EAAC,QAAA,EAAK,WAAWD,EAAO,cAAc,eAAY,QAAO;AAAA,QAChF,gBAAAC,EAACuB,GAAA,EAAmB,OAAOd,GAAY,MAAM,gBAAAT,EAAC0B,GAAA,CAAA,CAAM,GAAI,SAAShB,GAAS,aAAY,OAAA,CAAO;AAAA,MAAA,EAAA,CAC/F;AAAA,IAAA,GACF;AAAA,IACA,gBAAAV,EAAC,OAAA,EAAI,WAAWD,EAAO,WAAY,UAAAL,GAAS;AAAA,IAC3CmB,KAAU,gBAAAb,EAAC,OAAA,EAAI,WAAWD,EAAO,aAAc,UAAAc,EAAA,CAAO;AAAA,EAAA,GACzD;AAEJ;"}
@@ -0,0 +1,42 @@
1
+ const e = "_scroll_f4fzw_3", n = "_hubSheet_f4fzw_12", a = "_hubPadding_f4fzw_24", _ = "_appLayer_f4fzw_33", t = "_contentSheet_f4fzw_49", l = "_contentPadding_f4fzw_60", o = "_sidePanel_f4fzw_69", d = "_panelHeader_f4fzw_92", f = "_sidePanelWide_f4fzw_101", p = "_panelHeaderLeading_f4fzw_107", s = "_panelLeading_f4fzw_112", i = "_panelHeading_f4fzw_117", c = "_panelTitle_f4fzw_125", r = "_panelFacts_f4fzw_134", w = "_panelBody_f4fzw_141", z = "_panelFooter_f4fzw_151", g = "_panelControls_f4fzw_160", h = "_panelDivider_f4fzw_167", P = {
2
+ scroll: e,
3
+ hubSheet: n,
4
+ hubPadding: a,
5
+ appLayer: _,
6
+ contentSheet: t,
7
+ contentPadding: l,
8
+ sidePanel: o,
9
+ panelHeader: d,
10
+ sidePanelWide: f,
11
+ panelHeaderLeading: p,
12
+ panelLeading: s,
13
+ panelHeading: i,
14
+ panelTitle: c,
15
+ panelFacts: r,
16
+ panelBody: w,
17
+ panelFooter: z,
18
+ panelControls: g,
19
+ panelDivider: h
20
+ };
21
+ export {
22
+ _ as appLayer,
23
+ l as contentPadding,
24
+ t as contentSheet,
25
+ P as default,
26
+ a as hubPadding,
27
+ n as hubSheet,
28
+ w as panelBody,
29
+ g as panelControls,
30
+ h as panelDivider,
31
+ r as panelFacts,
32
+ z as panelFooter,
33
+ d as panelHeader,
34
+ p as panelHeaderLeading,
35
+ i as panelHeading,
36
+ s as panelLeading,
37
+ c as panelTitle,
38
+ e as scroll,
39
+ o as sidePanel,
40
+ f as sidePanelWide
41
+ };
42
+ //# sourceMappingURL=BackdropSheets.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackdropSheets.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,20 @@
1
+ import { ReactNode } from 'react';
2
+ export interface BackdropTab {
3
+ value: string;
4
+ label: ReactNode;
5
+ /** A count after the label ("People 48", "To send 5"). */
6
+ count?: ReactNode;
7
+ disabled?: boolean;
8
+ }
9
+ export interface BackdropTabsProps {
10
+ tabs: BackdropTab[];
11
+ /** The selected tab's value. Controlled: the caller owns which tab is open. */
12
+ value: string;
13
+ onValueChange?: (value: string) => void;
14
+ /** The tab list's accessible name, e.g. the page title. */
15
+ label: string;
16
+ /** Content at the right end of the row ("Connect a channel"). */
17
+ trailing?: ReactNode;
18
+ className?: string;
19
+ }
20
+ export declare function BackdropTabs({ tabs, value, onValueChange, label, trailing, className }: BackdropTabsProps): import("react").JSX.Element;
@@ -0,0 +1,31 @@
1
+ import { jsxs as a, jsx as s } from "react/jsx-runtime";
2
+ import l from "./BackdropTabs.module.css.js";
3
+ import { cx as m } from "./cx.js";
4
+ function h({ tabs: c, value: o, onValueChange: r, label: d, trailing: i, className: t }) {
5
+ return /* @__PURE__ */ a("div", { className: m(l.row, t), children: [
6
+ /* @__PURE__ */ s("div", { role: "tablist", "aria-label": d, className: l.list, children: c.map((e) => {
7
+ const n = e.value === o;
8
+ return /* @__PURE__ */ a(
9
+ "button",
10
+ {
11
+ type: "button",
12
+ role: "tab",
13
+ "aria-selected": n,
14
+ disabled: e.disabled,
15
+ className: l.tab,
16
+ onClick: r ? () => r(e.value) : void 0,
17
+ children: [
18
+ /* @__PURE__ */ s("span", { children: e.label }),
19
+ e.count !== void 0 && /* @__PURE__ */ s("span", { className: l.count, children: e.count })
20
+ ]
21
+ },
22
+ e.value
23
+ );
24
+ }) }),
25
+ i && /* @__PURE__ */ s("div", { className: l.trailing, children: i })
26
+ ] });
27
+ }
28
+ export {
29
+ h as BackdropTabs
30
+ };
31
+ //# sourceMappingURL=BackdropTabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackdropTabs.js","sources":["../../../src/components/Backdrop/BackdropTabs.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport styles from './BackdropTabs.module.css'\nimport { cx } from './cx'\n\nexport interface BackdropTab {\n value: string\n label: ReactNode\n /** A count after the label (\"People 48\", \"To send 5\"). */\n count?: ReactNode\n disabled?: boolean\n}\n\nexport interface BackdropTabsProps {\n tabs: BackdropTab[]\n /** The selected tab's value. Controlled: the caller owns which tab is open. */\n value: string\n onValueChange?: (value: string) => void\n /** The tab list's accessible name, e.g. the page title. */\n label: string\n /** Content at the right end of the row (\"Connect a channel\"). */\n trailing?: ReactNode\n className?: string\n}\n\n/*\n * Underlined tabs on a hairline, Paper's campaign-builder row: 15px, the\n * selected tab ink semibold over a 2px ink rule, the rest muted medium.\n *\n * Stage A: the selection is a prop and each tab is a button that reports a\n * click. Arrow-key roving focus (WAI-ARIA tabs) is Stage B; until then every\n * tab is in the tab order, which is operable, just not the pattern's ideal.\n */\nexport function BackdropTabs({ tabs, value, onValueChange, label, trailing, className }: BackdropTabsProps) {\n return (\n <div className={cx(styles.row, className)}>\n <div role=\"tablist\" aria-label={label} className={styles.list}>\n {tabs.map((tab) => {\n const selected = tab.value === value\n return (\n <button\n key={tab.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n disabled={tab.disabled}\n className={styles.tab}\n onClick={onValueChange ? () => onValueChange(tab.value) : undefined}\n >\n <span>{tab.label}</span>\n {tab.count !== undefined && <span className={styles.count}>{tab.count}</span>}\n </button>\n )\n })}\n </div>\n {trailing && <div className={styles.trailing}>{trailing}</div>}\n </div>\n )\n}\n"],"names":["BackdropTabs","tabs","value","onValueChange","label","trailing","className","cx","styles","jsx","tab","selected","jsxs"],"mappings":";;;AAgCO,SAASA,EAAa,EAAE,MAAAC,GAAM,OAAAC,GAAO,eAAAC,GAAe,OAAAC,GAAO,UAAAC,GAAU,WAAAC,KAAgC;AAC1G,2BACG,OAAA,EAAI,WAAWC,EAAGC,EAAO,KAAKF,CAAS,GACtC,UAAA;AAAA,IAAA,gBAAAG,EAAC,OAAA,EAAI,MAAK,WAAU,cAAYL,GAAO,WAAWI,EAAO,MACtD,UAAAP,EAAK,IAAI,CAACS,MAAQ;AACjB,YAAMC,IAAWD,EAAI,UAAUR;AAC/B,aACE,gBAAAU;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,MAAK;AAAA,UACL,MAAK;AAAA,UACL,iBAAeD;AAAA,UACf,UAAUD,EAAI;AAAA,UACd,WAAWF,EAAO;AAAA,UAClB,SAASL,IAAgB,MAAMA,EAAcO,EAAI,KAAK,IAAI;AAAA,UAE1D,UAAA;AAAA,YAAA,gBAAAD,EAAC,QAAA,EAAM,YAAI,MAAA,CAAM;AAAA,YAChBC,EAAI,UAAU,UAAa,gBAAAD,EAAC,UAAK,WAAWD,EAAO,OAAQ,UAAAE,EAAI,MAAA,CAAM;AAAA,UAAA;AAAA,QAAA;AAAA,QATjEA,EAAI;AAAA,MAAA;AAAA,IAYf,CAAC,EAAA,CACH;AAAA,IACCL,KAAY,gBAAAI,EAAC,OAAA,EAAI,WAAWD,EAAO,UAAW,UAAAH,EAAA,CAAS;AAAA,EAAA,GAC1D;AAEJ;"}
@@ -0,0 +1,16 @@
1
+ const t = "_row_1f0u9_3", _ = "_list_1f0u9_10", o = "_tab_1f0u9_15", n = "_count_1f0u9_55", s = "_trailing_1f0u9_63", c = {
2
+ row: t,
3
+ list: _,
4
+ tab: o,
5
+ count: n,
6
+ trailing: s
7
+ };
8
+ export {
9
+ n as count,
10
+ c as default,
11
+ _ as list,
12
+ t as row,
13
+ o as tab,
14
+ s as trailing
15
+ };
16
+ //# sourceMappingURL=BackdropTabs.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackdropTabs.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
@@ -0,0 +1,21 @@
1
+ import { ReactElement, ReactNode } from 'react';
2
+ export type BackdropTooltipSide = 'top' | 'right' | 'bottom' | 'left';
3
+ export interface BackdropTooltipProps {
4
+ /** The tip. Short: a name ("Inbox"), a shortcut, or one fact. */
5
+ content: ReactNode;
6
+ /** One focusable element: the tooltip shows on its hover and keyboard focus. */
7
+ children: ReactElement<Record<string, unknown>>;
8
+ side?: BackdropTooltipSide;
9
+ /**
10
+ * The tip repeats the trigger's own accessible name (an icon-only rail item
11
+ * or button). It is then hidden from assistive tech, so the name is not read
12
+ * twice; otherwise it is wired as the trigger's description.
13
+ */
14
+ labelsTrigger?: boolean;
15
+ /** Hold the tip open, for a story or a screenshot. */
16
+ open?: boolean;
17
+ /** Keep the tip hidden (its trigger's panel is open) without unmounting it. */
18
+ suppressed?: boolean;
19
+ className?: string;
20
+ }
21
+ export declare function BackdropTooltip({ content, children, side, labelsTrigger, open, suppressed, className }: BackdropTooltipProps): import("react").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { jsxs as c, jsx as f } from "react/jsx-runtime";
2
+ import { useId as l, isValidElement as v, cloneElement as u } from "react";
3
+ import i from "./BackdropTooltip.module.css.js";
4
+ import { cx as a } from "./cx.js";
5
+ function E({ content: d, children: t, side: e = "top", labelsTrigger: o = !1, open: p = !1, suppressed: r = !1, className: n }) {
6
+ const s = l(), m = !o && v(t) ? u(t, { "aria-describedby": s }) : t;
7
+ return /* @__PURE__ */ c("span", { className: a(i.anchor, n), "data-open": p || void 0, "data-suppressed": r || void 0, children: [
8
+ m,
9
+ /* @__PURE__ */ f("span", { id: o ? void 0 : s, role: o ? void 0 : "tooltip", "aria-hidden": o || void 0, className: a(i.tip, i[e]), children: d })
10
+ ] });
11
+ }
12
+ export {
13
+ E as BackdropTooltip
14
+ };
15
+ //# sourceMappingURL=BackdropTooltip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackdropTooltip.js","sources":["../../../src/components/Backdrop/BackdropTooltip.tsx"],"sourcesContent":["import { cloneElement, isValidElement, useId, type ReactElement, type ReactNode } from 'react'\nimport styles from './BackdropTooltip.module.css'\nimport { cx } from './cx'\n\nexport type BackdropTooltipSide = 'top' | 'right' | 'bottom' | 'left'\n\nexport interface BackdropTooltipProps {\n /** The tip. Short: a name (\"Inbox\"), a shortcut, or one fact. */\n content: ReactNode\n /** One focusable element: the tooltip shows on its hover and keyboard focus. */\n children: ReactElement<Record<string, unknown>>\n side?: BackdropTooltipSide\n /**\n * The tip repeats the trigger's own accessible name (an icon-only rail item\n * or button). It is then hidden from assistive tech, so the name is not read\n * twice; otherwise it is wired as the trigger's description.\n */\n labelsTrigger?: boolean\n /** Hold the tip open, for a story or a screenshot. */\n open?: boolean\n /** Keep the tip hidden (its trigger's panel is open) without unmounting it. */\n suppressed?: boolean\n className?: string\n}\n\n/*\n * CSS-only: the tip shows while the wrapper is hovered or holds keyboard focus\n * (`:focus-visible` inside it), after a short delay, and needs no state -- so\n * the component stays a server component and costs a consumer no client\n * bundle. Escape-to-dismiss (WCAG 1.4.13) is the one behaviour this cannot\n * give; it lands with Stage B.\n */\nexport function BackdropTooltip({ content, children, side = 'top', labelsTrigger = false, open = false, suppressed = false, className }: BackdropTooltipProps) {\n const id = useId()\n const trigger =\n !labelsTrigger && isValidElement(children) ? cloneElement(children, { 'aria-describedby': id }) : children\n return (\n <span className={cx(styles.anchor, className)} data-open={open || undefined} data-suppressed={suppressed || undefined}>\n {trigger}\n <span id={labelsTrigger ? undefined : id} role={labelsTrigger ? undefined : 'tooltip'} aria-hidden={labelsTrigger || undefined} className={cx(styles.tip, styles[side])}>\n {content}\n </span>\n </span>\n )\n}\n"],"names":["BackdropTooltip","content","children","side","labelsTrigger","open","suppressed","className","id","useId","trigger","isValidElement","cloneElement","jsxs","cx","styles","jsx"],"mappings":";;;;AAgCO,SAASA,EAAgB,EAAE,SAAAC,GAAS,UAAAC,GAAU,MAAAC,IAAO,OAAO,eAAAC,IAAgB,IAAO,MAAAC,IAAO,IAAO,YAAAC,IAAa,IAAO,WAAAC,KAAmC;AAC7J,QAAMC,IAAKC,EAAA,GACLC,IACJ,CAACN,KAAiBO,EAAeT,CAAQ,IAAIU,EAAaV,GAAU,EAAE,oBAAoBM,EAAA,CAAI,IAAIN;AACpG,SACE,gBAAAW,EAAC,QAAA,EAAK,WAAWC,EAAGC,EAAO,QAAQR,CAAS,GAAG,aAAWF,KAAQ,QAAW,mBAAiBC,KAAc,QACzG,UAAA;AAAA,IAAAI;AAAA,IACD,gBAAAM,EAAC,UAAK,IAAIZ,IAAgB,SAAYI,GAAI,MAAMJ,IAAgB,SAAY,WAAW,eAAaA,KAAiB,QAAW,WAAWU,EAAGC,EAAO,KAAKA,EAAOZ,CAAI,CAAC,GACnK,UAAAF,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;"}
@@ -0,0 +1,18 @@
1
+ const t = "_anchor_2v4zk_3", o = "_tip_2v4zk_10", _ = "_top_2v4zk_53", c = "_bottom_2v4zk_59", n = "_right_2v4zk_65", s = "_left_2v4zk_71", p = {
2
+ anchor: t,
3
+ tip: o,
4
+ top: _,
5
+ bottom: c,
6
+ right: n,
7
+ left: s
8
+ };
9
+ export {
10
+ t as anchor,
11
+ c as bottom,
12
+ p as default,
13
+ s as left,
14
+ n as right,
15
+ o as tip,
16
+ _ as top
17
+ };
18
+ //# sourceMappingURL=BackdropTooltip.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackdropTooltip.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,65 @@
1
+ import { ButtonHTMLAttributes, ReactNode } from 'react';
2
+ export interface BackdropTopStripCollapse {
3
+ /** "Collapse menu" / "Expand menu": the toggle's accessible name, both states. */
4
+ label: string;
5
+ /** The app menu is folded to its icon strip; the toggle shows the expand glyph. */
6
+ folded: boolean;
7
+ onToggle?: () => void;
8
+ }
9
+ export interface BackdropTopStripProps {
10
+ /**
11
+ * `app` puts the menu's collapse toggle in the slot above the rail and the
12
+ * Boost33 mark after it. `hub` has no menu to collapse: the mark moves into
13
+ * that slot and the wordmark follows it. Search sits at the same x in both.
14
+ */
15
+ variant: 'hub' | 'app';
16
+ /** The Boost33 mark, 32px (Boost33Mark). */
17
+ mark: ReactNode;
18
+ /** Hub only: the word after the mark. A brand name, passed in like any copy. */
19
+ wordmark?: ReactNode;
20
+ /** App only: the collapse/expand toggle. */
21
+ collapse?: BackdropTopStripCollapse;
22
+ /** A BackdropSearchTrigger. */
23
+ search: ReactNode;
24
+ /**
25
+ * The right-hand group, in order: mission chip · tokens chip · Ask · Help ·
26
+ * account avatar (round 4, correction 2).
27
+ */
28
+ trailing: ReactNode;
29
+ /** The strip's landmark name. */
30
+ label: string;
31
+ className?: string;
32
+ }
33
+ export declare function BackdropTopStrip({ variant, mark, wordmark, collapse, search, trailing, label, className }: BackdropTopStripProps): import("react").JSX.Element;
34
+ export interface BackdropSearchTriggerProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
35
+ /** The placeholder line: "Search apps, companies, deals". */
36
+ placeholder: string;
37
+ /** The shortcut shown at the right end: "⌘K". */
38
+ shortcut?: string;
39
+ }
40
+ /** A button that looks like a field: it opens the search dialog (⌘K). 360px, 280px below 1200px. */
41
+ export declare function BackdropSearchTrigger({ placeholder, shortcut, className, type, ...rest }: BackdropSearchTriggerProps): import("react").JSX.Element;
42
+ export interface BackdropStripChipProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
43
+ icon: ReactNode;
44
+ /** "Book 5 meetings · 2/5", "1,240 tokens". */
45
+ label: ReactNode;
46
+ /** The shorter label below 1200px ("2/5"). The full label stays the accessible name. */
47
+ compactLabel?: ReactNode;
48
+ /** Its popover is open. */
49
+ pressed?: boolean;
50
+ }
51
+ export declare function BackdropStripChip({ icon, label, compactLabel, pressed, className, type, ...rest }: BackdropStripChipProps): import("react").JSX.Element;
52
+ export interface BackdropStripButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
53
+ icon: ReactNode;
54
+ label: ReactNode;
55
+ pressed?: boolean;
56
+ }
57
+ export declare function BackdropStripButton({ icon, label, pressed, className, type, ...rest }: BackdropStripButtonProps): import("react").JSX.Element;
58
+ export interface BackdropStripAvatarProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'aria-label'> {
59
+ /** Two letters. */
60
+ initials: string;
61
+ /** The button's name: "Account menu, Camille Martin". */
62
+ label: string;
63
+ pressed?: boolean;
64
+ }
65
+ export declare function BackdropStripAvatar({ initials, label, pressed, className, type, ...rest }: BackdropStripAvatarProps): import("react").JSX.Element;
@@ -0,0 +1,46 @@
1
+ import { jsxs as c, jsx as a } from "react/jsx-runtime";
2
+ import e from "./BackdropTopStrip.module.css.js";
3
+ import { cx as d } from "./cx.js";
4
+ import { Search as p, Expand as m, Collapse as u } from "./icons.js";
5
+ import { BackdropTooltip as b } from "./BackdropTooltip.js";
6
+ function v({ variant: l, mark: i, wordmark: n, collapse: r, search: s, trailing: t, label: o, className: h }) {
7
+ return /* @__PURE__ */ c("header", { className: d(e.strip, h), "aria-label": o, children: [
8
+ /* @__PURE__ */ a("div", { className: e.slot, children: l === "hub" ? /* @__PURE__ */ a("span", { className: e.mark, children: i }) : r && /* @__PURE__ */ a(b, { content: r.label, side: "right", labelsTrigger: !0, children: /* @__PURE__ */ a("button", { type: "button", className: e.collapse, "aria-label": r.label, "aria-expanded": !r.folded, onClick: r.onToggle, children: r.folded ? /* @__PURE__ */ a(m, {}) : /* @__PURE__ */ a(u, {}) }) }) }),
9
+ l === "hub" && n && /* @__PURE__ */ a("span", { className: e.wordmark, children: n }),
10
+ /* @__PURE__ */ a("div", { className: e.lead, children: l === "app" && /* @__PURE__ */ a("span", { className: e.mark, children: i }) }),
11
+ /* @__PURE__ */ a("div", { className: e.search, children: s }),
12
+ /* @__PURE__ */ a("div", { className: e.fill }),
13
+ /* @__PURE__ */ a("div", { className: e.trailing, children: t })
14
+ ] });
15
+ }
16
+ function B({ placeholder: l, shortcut: i, className: n, type: r = "button", ...s }) {
17
+ return /* @__PURE__ */ c("button", { type: r, className: d(e.searchTrigger, n), "aria-keyshortcuts": i ? "Meta+K" : void 0, ...s, children: [
18
+ /* @__PURE__ */ a(p, {}),
19
+ /* @__PURE__ */ a("span", { className: e.searchPlaceholder, children: l }),
20
+ i && /* @__PURE__ */ a("kbd", { className: e.shortcut, "aria-hidden": "true", children: i })
21
+ ] });
22
+ }
23
+ function S({ icon: l, label: i, compactLabel: n, pressed: r = !1, className: s, type: t = "button", ...o }) {
24
+ return /* @__PURE__ */ c("button", { type: t, "aria-expanded": r, className: d(e.chip, s), ...o, children: [
25
+ l,
26
+ /* @__PURE__ */ a("span", { className: d(e.chipLabel, n !== void 0 && e.hasCompact), children: i }),
27
+ n !== void 0 && /* @__PURE__ */ a("span", { className: e.chipCompact, "aria-hidden": "true", children: n })
28
+ ] });
29
+ }
30
+ function T({ icon: l, label: i, pressed: n = !1, className: r, type: s = "button", ...t }) {
31
+ return /* @__PURE__ */ c("button", { type: s, "aria-expanded": n, className: d(e.stripButton, r), ...t, children: [
32
+ l,
33
+ /* @__PURE__ */ a("span", { children: i })
34
+ ] });
35
+ }
36
+ function C({ initials: l, label: i, pressed: n = !1, className: r, type: s = "button", ...t }) {
37
+ return /* @__PURE__ */ a("button", { type: s, "aria-label": i, "aria-expanded": n, className: d(e.avatar, r), ...t, children: /* @__PURE__ */ a("span", { "aria-hidden": "true", children: l }) });
38
+ }
39
+ export {
40
+ B as BackdropSearchTrigger,
41
+ C as BackdropStripAvatar,
42
+ T as BackdropStripButton,
43
+ S as BackdropStripChip,
44
+ v as BackdropTopStrip
45
+ };
46
+ //# sourceMappingURL=BackdropTopStrip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackdropTopStrip.js","sources":["../../../src/components/Backdrop/BackdropTopStrip.tsx"],"sourcesContent":["import type { ButtonHTMLAttributes, ReactNode } from 'react'\nimport styles from './BackdropTopStrip.module.css'\nimport { cx } from './cx'\nimport { Collapse, Expand, Search } from './icons'\nimport { BackdropTooltip } from './BackdropTooltip'\n\nexport interface BackdropTopStripCollapse {\n /** \"Collapse menu\" / \"Expand menu\": the toggle's accessible name, both states. */\n label: string\n /** The app menu is folded to its icon strip; the toggle shows the expand glyph. */\n folded: boolean\n onToggle?: () => void\n}\n\nexport interface BackdropTopStripProps {\n /**\n * `app` puts the menu's collapse toggle in the slot above the rail and the\n * Boost33 mark after it. `hub` has no menu to collapse: the mark moves into\n * that slot and the wordmark follows it. Search sits at the same x in both.\n */\n variant: 'hub' | 'app'\n /** The Boost33 mark, 32px (Boost33Mark). */\n mark: ReactNode\n /** Hub only: the word after the mark. A brand name, passed in like any copy. */\n wordmark?: ReactNode\n /** App only: the collapse/expand toggle. */\n collapse?: BackdropTopStripCollapse\n /** A BackdropSearchTrigger. */\n search: ReactNode\n /**\n * The right-hand group, in order: mission chip · tokens chip · Ask · Help ·\n * account avatar (round 4, correction 2).\n */\n trailing: ReactNode\n /** The strip's landmark name. */\n label: string\n className?: string\n}\n\n/*\n * Backdrop's top strip, 60px. The left 76px is the slot directly above the\n * rail's icon column. Search starts at x = 140 on every screen: 76 + 64 -- the\n * 64 is the mark plus its 16px either side in an app, and the wordmark's run on\n * the hub (round 4: \"Search stays at exactly the same x on the hub and in\n * apps; only the logo area differs\").\n */\nexport function BackdropTopStrip({ variant, mark, wordmark, collapse, search, trailing, label, className }: BackdropTopStripProps) {\n return (\n <header className={cx(styles.strip, className)} aria-label={label}>\n <div className={styles.slot}>\n {variant === 'hub' ? (\n <span className={styles.mark}>{mark}</span>\n ) : (\n collapse && (\n <BackdropTooltip content={collapse.label} side=\"right\" labelsTrigger>\n <button type=\"button\" className={styles.collapse} aria-label={collapse.label} aria-expanded={!collapse.folded} onClick={collapse.onToggle}>\n {collapse.folded ? <Expand /> : <Collapse />}\n </button>\n </BackdropTooltip>\n )\n )}\n </div>\n {variant === 'hub' && wordmark && <span className={styles.wordmark}>{wordmark}</span>}\n <div className={styles.lead}>{variant === 'app' && <span className={styles.mark}>{mark}</span>}</div>\n <div className={styles.search}>{search}</div>\n <div className={styles.fill} />\n <div className={styles.trailing}>{trailing}</div>\n </header>\n )\n}\n\n/* ── Search trigger ────────────────────────────────────────────────────── */\n\nexport interface BackdropSearchTriggerProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {\n /** The placeholder line: \"Search apps, companies, deals\". */\n placeholder: string\n /** The shortcut shown at the right end: \"⌘K\". */\n shortcut?: string\n}\n\n/** A button that looks like a field: it opens the search dialog (⌘K). 360px, 280px below 1200px. */\nexport function BackdropSearchTrigger({ placeholder, shortcut, className, type = 'button', ...rest }: BackdropSearchTriggerProps) {\n return (\n <button type={type} className={cx(styles.searchTrigger, className)} aria-keyshortcuts={shortcut ? 'Meta+K' : undefined} {...rest}>\n <Search />\n <span className={styles.searchPlaceholder}>{placeholder}</span>\n {shortcut && (\n <kbd className={styles.shortcut} aria-hidden=\"true\">\n {shortcut}\n </kbd>\n )}\n </button>\n )\n}\n\n/* ── Strip chip (mission, tokens) ──────────────────────────────────────── */\n\nexport interface BackdropStripChipProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {\n icon: ReactNode\n /** \"Book 5 meetings · 2/5\", \"1,240 tokens\". */\n label: ReactNode\n /** The shorter label below 1200px (\"2/5\"). The full label stays the accessible name. */\n compactLabel?: ReactNode\n /** Its popover is open. */\n pressed?: boolean\n}\n\nexport function BackdropStripChip({ icon, label, compactLabel, pressed = false, className, type = 'button', ...rest }: BackdropStripChipProps) {\n return (\n <button type={type} aria-expanded={pressed} className={cx(styles.chip, className)} {...rest}>\n {icon}\n <span className={cx(styles.chipLabel, compactLabel !== undefined && styles.hasCompact)}>{label}</span>\n {compactLabel !== undefined && (\n <span className={styles.chipCompact} aria-hidden=\"true\">\n {compactLabel}\n </span>\n )}\n </button>\n )\n}\n\n/* ── Strip button (Ask, Help) ──────────────────────────────────────────── */\n\nexport interface BackdropStripButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {\n icon: ReactNode\n label: ReactNode\n pressed?: boolean\n}\n\nexport function BackdropStripButton({ icon, label, pressed = false, className, type = 'button', ...rest }: BackdropStripButtonProps) {\n return (\n <button type={type} aria-expanded={pressed} className={cx(styles.stripButton, className)} {...rest}>\n {icon}\n <span>{label}</span>\n </button>\n )\n}\n\n/* ── Account avatar ────────────────────────────────────────────────────── */\n\nexport interface BackdropStripAvatarProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'aria-label'> {\n /** Two letters. */\n initials: string\n /** The button's name: \"Account menu, Camille Martin\". */\n label: string\n pressed?: boolean\n}\n\nexport function BackdropStripAvatar({ initials, label, pressed = false, className, type = 'button', ...rest }: BackdropStripAvatarProps) {\n return (\n <button type={type} aria-label={label} aria-expanded={pressed} className={cx(styles.avatar, className)} {...rest}>\n <span aria-hidden=\"true\">{initials}</span>\n </button>\n )\n}\n"],"names":["BackdropTopStrip","variant","mark","wordmark","collapse","search","trailing","label","className","jsxs","cx","styles","jsx","BackdropTooltip","Expand","Collapse","BackdropSearchTrigger","placeholder","shortcut","type","rest","Search","BackdropStripChip","icon","compactLabel","pressed","BackdropStripButton","BackdropStripAvatar","initials"],"mappings":";;;;;AA8CO,SAASA,EAAiB,EAAE,SAAAC,GAAS,MAAAC,GAAM,UAAAC,GAAU,UAAAC,GAAU,QAAAC,GAAQ,UAAAC,GAAU,OAAAC,GAAO,WAAAC,KAAoC;AACjI,SACE,gBAAAC,EAAC,YAAO,WAAWC,EAAGC,EAAO,OAAOH,CAAS,GAAG,cAAYD,GAC1D,UAAA;AAAA,IAAA,gBAAAK,EAAC,OAAA,EAAI,WAAWD,EAAO,MACpB,gBAAY,QACX,gBAAAC,EAAC,QAAA,EAAK,WAAWD,EAAO,MAAO,aAAK,IAEpCP,uBACGS,GAAA,EAAgB,SAAST,EAAS,OAAO,MAAK,SAAQ,eAAa,IAClE,UAAA,gBAAAQ,EAAC,YAAO,MAAK,UAAS,WAAWD,EAAO,UAAU,cAAYP,EAAS,OAAO,iBAAe,CAACA,EAAS,QAAQ,SAASA,EAAS,UAC9H,UAAAA,EAAS,SAAS,gBAAAQ,EAACE,GAAA,CAAA,CAAO,IAAK,gBAAAF,EAACG,GAAA,CAAA,CAAS,EAAA,CAC5C,EAAA,CACF,EAAA,CAGN;AAAA,IACCd,MAAY,SAASE,KAAY,gBAAAS,EAAC,UAAK,WAAWD,EAAO,UAAW,UAAAR,EAAA,CAAS;AAAA,IAC9E,gBAAAS,EAAC,OAAA,EAAI,WAAWD,EAAO,MAAO,UAAAV,MAAY,SAAS,gBAAAW,EAAC,QAAA,EAAK,WAAWD,EAAO,MAAO,aAAK,GAAQ;AAAA,IAC/F,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAO,QAAS,UAAAN,GAAO;AAAA,IACvC,gBAAAO,EAAC,OAAA,EAAI,WAAWD,EAAO,KAAA,CAAM;AAAA,IAC7B,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAO,UAAW,UAAAL,EAAA,CAAS;AAAA,EAAA,GAC7C;AAEJ;AAYO,SAASU,EAAsB,EAAE,aAAAC,GAAa,UAAAC,GAAU,WAAAV,GAAW,MAAAW,IAAO,UAAU,GAAGC,KAAoC;AAChI,SACE,gBAAAX,EAAC,UAAA,EAAO,MAAAU,GAAY,WAAWT,EAAGC,EAAO,eAAeH,CAAS,GAAG,qBAAmBU,IAAW,WAAW,QAAY,GAAGE,GAC1H,UAAA;AAAA,IAAA,gBAAAR,EAACS,GAAA,EAAO;AAAA,IACR,gBAAAT,EAAC,QAAA,EAAK,WAAWD,EAAO,mBAAoB,UAAAM,GAAY;AAAA,IACvDC,uBACE,OAAA,EAAI,WAAWP,EAAO,UAAU,eAAY,QAC1C,UAAAO,EAAA,CACH;AAAA,EAAA,GAEJ;AAEJ;AAcO,SAASI,EAAkB,EAAE,MAAAC,GAAM,OAAAhB,GAAO,cAAAiB,GAAc,SAAAC,IAAU,IAAO,WAAAjB,GAAW,MAAAW,IAAO,UAAU,GAAGC,EAAA,GAAgC;AAC7I,SACE,gBAAAX,EAAC,UAAA,EAAO,MAAAU,GAAY,iBAAeM,GAAS,WAAWf,EAAGC,EAAO,MAAMH,CAAS,GAAI,GAAGY,GACpF,UAAA;AAAA,IAAAG;AAAA,IACD,gBAAAX,EAAC,QAAA,EAAK,WAAWF,EAAGC,EAAO,WAAWa,MAAiB,UAAab,EAAO,UAAU,GAAI,UAAAJ,EAAA,CAAM;AAAA,IAC9FiB,MAAiB,UAChB,gBAAAZ,EAAC,QAAA,EAAK,WAAWD,EAAO,aAAa,eAAY,QAC9C,UAAAa,EAAA,CACH;AAAA,EAAA,GAEJ;AAEJ;AAUO,SAASE,EAAoB,EAAE,MAAAH,GAAM,OAAAhB,GAAO,SAAAkB,IAAU,IAAO,WAAAjB,GAAW,MAAAW,IAAO,UAAU,GAAGC,KAAkC;AACnI,SACE,gBAAAX,EAAC,UAAA,EAAO,MAAAU,GAAY,iBAAeM,GAAS,WAAWf,EAAGC,EAAO,aAAaH,CAAS,GAAI,GAAGY,GAC3F,UAAA;AAAA,IAAAG;AAAA,IACD,gBAAAX,EAAC,UAAM,UAAAL,EAAA,CAAM;AAAA,EAAA,GACf;AAEJ;AAYO,SAASoB,EAAoB,EAAE,UAAAC,GAAU,OAAArB,GAAO,SAAAkB,IAAU,IAAO,WAAAjB,GAAW,MAAAW,IAAO,UAAU,GAAGC,KAAkC;AACvI,SACE,gBAAAR,EAAC,YAAO,MAAAO,GAAY,cAAYZ,GAAO,iBAAekB,GAAS,WAAWf,EAAGC,EAAO,QAAQH,CAAS,GAAI,GAAGY,GAC1G,UAAA,gBAAAR,EAAC,UAAK,eAAY,QAAQ,aAAS,EAAA,CACrC;AAEJ;"}
@@ -0,0 +1,40 @@
1
+ const s = "_strip_jhosp_3", o = "_slot_jhosp_14", t = "_lead_jhosp_24", _ = "_mark_jhosp_33", c = "_wordmark_jhosp_44", a = "_search_jhosp_58", r = "_fill_jhosp_63", h = "_trailing_jhosp_67", p = "_collapse_jhosp_75", l = "_searchTrigger_jhosp_76", e = "_chip_jhosp_77", i = "_stripButton_jhosp_78", n = "_avatar_jhosp_79", j = "_searchPlaceholder_jhosp_133", m = "_shortcut_jhosp_142", d = "_chipCompact_jhosp_174", g = "_hasCompact_jhosp_233", u = {
2
+ strip: s,
3
+ slot: o,
4
+ lead: t,
5
+ mark: _,
6
+ wordmark: c,
7
+ search: a,
8
+ fill: r,
9
+ trailing: h,
10
+ collapse: p,
11
+ searchTrigger: l,
12
+ chip: e,
13
+ stripButton: i,
14
+ avatar: n,
15
+ searchPlaceholder: j,
16
+ shortcut: m,
17
+ chipCompact: d,
18
+ hasCompact: g
19
+ };
20
+ export {
21
+ n as avatar,
22
+ e as chip,
23
+ d as chipCompact,
24
+ p as collapse,
25
+ u as default,
26
+ r as fill,
27
+ g as hasCompact,
28
+ t as lead,
29
+ _ as mark,
30
+ a as search,
31
+ j as searchPlaceholder,
32
+ l as searchTrigger,
33
+ m as shortcut,
34
+ o as slot,
35
+ s as strip,
36
+ i as stripButton,
37
+ h as trailing,
38
+ c as wordmark
39
+ };
40
+ //# sourceMappingURL=BackdropTopStrip.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackdropTopStrip.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,2 @@
1
+ /** Joins the truthy class names. Local to Backdrop; the 0.8 components inline theirs. */
2
+ export declare function cx(...names: Array<string | false | null | undefined>): string;
@@ -0,0 +1,7 @@
1
+ function o(...n) {
2
+ return n.filter(Boolean).join(" ");
3
+ }
4
+ export {
5
+ o as cx
6
+ };
7
+ //# sourceMappingURL=cx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cx.js","sources":["../../../src/components/Backdrop/cx.ts"],"sourcesContent":["/** Joins the truthy class names. Local to Backdrop; the 0.8 components inline theirs. */\nexport function cx(...names: Array<string | false | null | undefined>): string {\n return names.filter(Boolean).join(' ')\n}\n"],"names":["cx","names"],"mappings":"AACO,SAASA,KAAMC,GAAyD;AAC7E,SAAOA,EAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AACvC;"}