@stackone/malachite 2.60.0 → 2.62.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.
@@ -1,166 +1,178 @@
1
1
  import { jsx as e, jsxs as a } from "react/jsx-runtime";
2
- import { useState as R, useRef as d, useEffect as F } from "react";
3
- import { createPortal as X } from "react-dom";
4
- import { ShadowRootWrapper as Y } from "../ShadowRootWrapper.js";
5
- import q from "./CalloutStrip.js";
6
- import U from "./CustomIcons/ArrowLeftIcon.js";
7
- import G from "./CustomIcons/DismissIcon.js";
8
- import A from "./Typography/EllipsisText.js";
9
- import { useOverlayBehaviour as H, OVERLAY_ICON_BUTTON_CLASSES as k } from "./overlayBehaviour.js";
10
- import { OVERLAY_ELEVATED_ATTR as J, overlayIdentity as z } from "./portalOverlay.js";
11
- const E = 200, K = (t) => typeof t == "number" ? `${t}px` : t, oe = ({
2
+ import { useId as k, useState as _, useRef as u, useEffect as q } from "react";
3
+ import { createPortal as U } from "react-dom";
4
+ import { ShadowRootWrapper as G } from "../ShadowRootWrapper.js";
5
+ import H from "./CalloutStrip.js";
6
+ import J from "./CustomIcons/ArrowLeftIcon.js";
7
+ import K from "./CustomIcons/DismissIcon.js";
8
+ import z from "./Typography/EllipsisText.js";
9
+ import { useOverlayBehaviour as Q, OVERLAY_ICON_BUTTON_CLASSES as E } from "./overlayBehaviour.js";
10
+ import { OVERLAY_ELEVATED_ATTR as Z, overlayIdentity as O } from "./portalOverlay.js";
11
+ const P = 200, ee = (t) => typeof t == "number" ? `${t}px` : t, me = ({
12
12
  open: t,
13
- onClose: o,
14
- title: n,
15
- subtitle: c,
16
- titleExtra: p,
17
- description: u,
18
- headerDivider: O = !1,
19
- icon: f,
20
- headerExtra: x,
13
+ onClose: c,
14
+ title: o,
15
+ subtitle: d,
16
+ titleExtra: f,
17
+ description: m,
18
+ headerDivider: V = !1,
19
+ icon: x,
20
+ headerExtra: b,
21
21
  footer: h,
22
- onBack: b,
23
- maxWidth: _ = 1080,
24
- "aria-label": $,
25
- "aria-labelledby": v,
26
- bodyPadding: y = !0,
27
- stacking: P = "default",
28
- callouts: m,
29
- renderLink: V,
30
- children: N
22
+ onBack: v,
23
+ maxWidth: C = 1080,
24
+ "aria-label": L,
25
+ "aria-labelledby": y,
26
+ bodyPadding: N = !0,
27
+ stacking: j = "default",
28
+ callouts: p,
29
+ renderLink: B,
30
+ children: g
31
31
  }) => {
32
- const [g, T] = R(!1), [C, w] = R(!1), i = d(null), r = d(null), S = d(null), {
33
- ref: L,
34
- isTopmost: M,
35
- zIndex: W,
36
- elevated: j
37
- } = H({
32
+ const T = k(), I = k(), [w, S] = _(!1), [M, R] = _(!1), i = u(null), r = u(null), $ = u(null), {
33
+ ref: W,
34
+ isTopmost: D,
35
+ zIndex: F,
36
+ elevated: X
37
+ } = Q({
38
38
  open: t,
39
- onClose: o,
40
- elevated: P === "above-app-overlays",
41
- hostRef: S
39
+ onClose: c,
40
+ elevated: j === "above-app-overlays",
41
+ hostRef: $
42
42
  });
43
- if (F(() => (t ? (w(!0), r.current && (clearTimeout(r.current), r.current = null), i.current = requestAnimationFrame(() => {
44
- i.current = null, T(!0);
45
- })) : (T(!1), r.current = setTimeout(() => {
46
- r.current = null, w(!1);
47
- }, E)), () => {
43
+ if (q(() => (t ? (R(!0), r.current && (clearTimeout(r.current), r.current = null), i.current = requestAnimationFrame(() => {
44
+ i.current = null, S(!0);
45
+ })) : (S(!1), r.current = setTimeout(() => {
46
+ r.current = null, R(!1);
47
+ }, P)), () => {
48
48
  i.current !== null && (cancelAnimationFrame(i.current), i.current = null), r.current && (clearTimeout(r.current), r.current = null);
49
- }), [t]), !C)
49
+ }), [t]), !M)
50
50
  return null;
51
- const l = m == null ? void 0 : m.filter((s) => s.message.trim()), I = !!(l != null && l.length), B = y ? /* @__PURE__ */ e("div", { className: I ? "p-[28px]" : "py-[28px]", children: N }) : N;
52
- return X(
51
+ const l = p == null ? void 0 : p.filter((n) => n.message.trim()), A = !!(l != null && l.length), Y = N ? /* @__PURE__ */ e("div", { className: A ? "p-[28px]" : "py-[28px]", children: g }) : g;
52
+ return U(
53
53
  // Host carries the stacking context — ShadowRootWrapper's `isolation` would
54
54
  // otherwise flatten our z-index and let sticky page elements paint over us.
55
55
  /* @__PURE__ */ e(
56
- Y,
56
+ G,
57
57
  {
58
- hostRef: S,
59
- hostStyle: { position: "relative", zIndex: W },
60
- hostProps: j ? { ...z("sidepanel"), [J]: "" } : z("sidepanel"),
58
+ hostRef: $,
59
+ hostStyle: { position: "relative", zIndex: F },
60
+ hostProps: X ? { ...O("sidepanel"), [Z]: "" } : O("sidepanel"),
61
61
  children: /* @__PURE__ */ a("div", { className: "fixed inset-0 z-[1000]", children: [
62
62
  /* @__PURE__ */ e(
63
63
  "div",
64
64
  {
65
65
  "aria-hidden": "true",
66
- onClick: o,
67
- className: `absolute inset-0 bg-[var(--malachite-overlay-scrim)] transition-opacity duration-200 ease-in-out ${g ? "opacity-100" : "opacity-0"}`
66
+ onClick: c,
67
+ className: `absolute inset-0 bg-[var(--malachite-overlay-scrim)] transition-opacity duration-200 ease-in-out ${w ? "opacity-100" : "opacity-0"}`
68
68
  }
69
69
  ),
70
70
  /* @__PURE__ */ a(
71
71
  "div",
72
72
  {
73
- ref: L,
73
+ ref: W,
74
74
  role: "dialog",
75
- "aria-modal": M ? "true" : void 0,
75
+ "aria-modal": D ? "true" : void 0,
76
+ "aria-describedby": [
77
+ ...(l ?? []).map((n, s) => `${T}-${s}`),
78
+ m ? I : null
79
+ ].filter(Boolean).join(" ") || void 0,
76
80
  tabIndex: -1,
77
- "aria-label": v ? void 0 : $ ?? (typeof n == "string" ? n : void 0),
78
- "aria-labelledby": v,
81
+ "aria-label": y ? void 0 : L ?? (typeof o == "string" ? o : void 0),
82
+ "aria-labelledby": y,
79
83
  className: "absolute top-[8px] right-[8px] bottom-[8px] flex flex-col overflow-hidden rounded-[20px] border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-background)] text-[var(--malachite-card-foreground)] outline-none [box-shadow:var(--malachite-shadow-lg)]",
80
84
  style: {
81
- width: `min(calc(100% - 16px), ${K(_)})`,
85
+ width: `min(calc(100% - 16px), ${ee(C)})`,
82
86
  // Inline: Tailwind translate utilities silently break inside
83
87
  // shadow roots (see CLAUDE.md Shadow DOM caveats).
84
- transform: g ? "translateX(0)" : "translateX(calc(100% + 16px))",
85
- transition: `transform ${E}ms ease-in-out`
88
+ transform: w ? "translateX(0)" : "translateX(calc(100% + 16px))",
89
+ transition: `transform ${P}ms ease-in-out`
86
90
  },
87
91
  children: [
88
92
  /* @__PURE__ */ a(
89
93
  "div",
90
94
  {
91
- className: `flex flex-col gap-[20px] px-[20px] py-[18px] ${O ? "border-0 border-b border-solid border-[var(--malachite-card-border)]" : ""}`,
95
+ className: `flex flex-col gap-[20px] px-[20px] py-[18px] ${V ? "border-0 border-b border-solid border-[var(--malachite-card-border)]" : ""}`,
92
96
  children: [
93
97
  /* @__PURE__ */ a("div", { className: "flex items-center gap-[12px]", children: [
94
- b ? /* @__PURE__ */ e(
98
+ v ? /* @__PURE__ */ e(
95
99
  "button",
96
100
  {
97
101
  type: "button",
98
102
  "aria-label": "Back",
99
- onClick: b,
100
- className: k,
101
- children: /* @__PURE__ */ e(U, { size: 16 })
103
+ onClick: v,
104
+ className: E,
105
+ children: /* @__PURE__ */ e(J, { size: 16 })
102
106
  }
103
107
  ) : null,
104
- f ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center", children: f }) : null,
108
+ x ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center", children: x }) : null,
105
109
  /* @__PURE__ */ a("div", { className: "flex min-w-0 flex-1 items-baseline gap-[12px]", children: [
106
110
  /* @__PURE__ */ a("div", { className: "flex min-w-0 flex-1 items-baseline gap-[8px]", children: [
107
111
  /* @__PURE__ */ a("div", { className: "flex min-w-0 items-baseline gap-[8px]", children: [
108
112
  /* @__PURE__ */ e("span", { className: "flex min-w-0 max-w-full shrink-0", children: /* @__PURE__ */ e(
109
- A,
113
+ z,
110
114
  {
111
- tooltip: n,
115
+ tooltip: o,
112
116
  tooltipWhenTruncated: !0,
113
117
  tooltipPlacement: "bottom",
114
118
  className: "min-w-0 text-[length:var(--malachite-font-size-15,15px)] font-semibold",
115
- children: n
119
+ children: o
116
120
  }
117
121
  ) }),
118
- c ? /* @__PURE__ */ e(
119
- A,
122
+ d ? /* @__PURE__ */ e(
123
+ z,
120
124
  {
121
- tooltip: c,
125
+ tooltip: d,
122
126
  tooltipWhenTruncated: !0,
123
127
  tooltipPlacement: "bottom",
124
128
  color: "secondary",
125
129
  className: "min-w-0 text-[13px]",
126
- children: c
130
+ children: d
127
131
  }
128
132
  ) : null
129
133
  ] }),
130
- p ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center", children: p }) : null
134
+ f ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center", children: f }) : null
131
135
  ] }),
132
- x ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-baseline", children: x }) : null
136
+ b ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-baseline", children: b }) : null
133
137
  ] }),
134
138
  /* @__PURE__ */ e(
135
139
  "button",
136
140
  {
137
141
  type: "button",
138
142
  "aria-label": "Close",
139
- onClick: o,
140
- className: k,
141
- children: /* @__PURE__ */ e(G, { size: 10 })
143
+ onClick: c,
144
+ className: E,
145
+ children: /* @__PURE__ */ e(K, { size: 10 })
142
146
  }
143
147
  )
144
148
  ] }),
145
- u ? /* @__PURE__ */ e("div", { className: "text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]", children: u }) : null
149
+ m ? /* @__PURE__ */ e(
150
+ "div",
151
+ {
152
+ id: I,
153
+ className: "text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]",
154
+ children: m
155
+ }
156
+ ) : null
146
157
  ]
147
158
  }
148
159
  ),
149
160
  /* @__PURE__ */ a(
150
161
  "div",
151
162
  {
152
- className: `min-h-0 flex-1 overflow-y-auto ${y && !I ? "px-[28px]" : ""}`,
163
+ className: `min-h-0 flex-1 overflow-y-auto ${N && !A ? "px-[28px]" : ""}`,
153
164
  children: [
154
- l == null ? void 0 : l.map((s, D) => /* @__PURE__ */ e(
155
- q,
165
+ l == null ? void 0 : l.map((n, s) => /* @__PURE__ */ e(
166
+ H,
156
167
  {
157
- type: s.type,
158
- message: s.message,
159
- renderLink: V
168
+ id: `${T}-${s}`,
169
+ type: n.type,
170
+ message: n.message,
171
+ renderLink: B
160
172
  },
161
- D
173
+ s
162
174
  )),
163
- B
175
+ Y
164
176
  ]
165
177
  }
166
178
  ),
@@ -175,7 +187,7 @@ const E = 200, K = (t) => typeof t == "number" ? `${t}px` : t, oe = ({
175
187
  );
176
188
  };
177
189
  export {
178
- oe as SidePanel,
179
- oe as default
190
+ me as SidePanel,
191
+ me as default
180
192
  };
181
193
  //# sourceMappingURL=SidePanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SidePanel.js","sources":["../../src/components/SidePanel.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ShadowRootWrapper } from '../ShadowRootWrapper';\nimport type { AlertType } from './Alert';\nimport CalloutStrip from './CalloutStrip';\nimport ArrowLeftIcon from './CustomIcons/ArrowLeftIcon';\nimport DismissIcon from './CustomIcons/DismissIcon';\nimport type { RenderLink } from './PageLayout/types';\nimport EllipsisText from './Typography/EllipsisText';\nimport { OVERLAY_ICON_BUTTON_CLASSES, useOverlayBehaviour } from './overlayBehaviour';\nimport { OVERLAY_ELEVATED_ATTR, overlayIdentity } from './portalOverlay';\n\nexport interface SidePanelProps {\n open: boolean;\n /** Dismiss handler — close button, ESC, or overlay click. */\n onClose: () => void;\n title: React.ReactNode;\n /** Secondary text, inline after the title. */\n subtitle?: React.ReactNode;\n /** Content at the end of the title row, after the subtitle (e.g. a status tag). */\n titleExtra?: React.ReactNode;\n /** Block paragraph below the title row, spanning the header width. */\n description?: React.ReactNode;\n /** Divider under the header. Default: false. */\n headerDivider?: boolean;\n /** Leading header slot, typically a logo or icon. */\n icon?: React.ReactNode;\n /** Content pinned right in the header, before the close button. */\n headerExtra?: React.ReactNode;\n footer?: React.ReactNode;\n /** Renders a back button before the header icon. */\n onBack?: () => void;\n /** Maximum panel width. Default: 1080. */\n maxWidth?: number | string;\n /** Accessible dialog name; required when `title` isn't a plain string. */\n 'aria-label'?: string;\n /** ID of a visible element naming the dialog (alternative to `aria-label`). */\n 'aria-labelledby'?: string;\n /** Whether the body gets default padding. Default: true. */\n bodyPadding?: boolean;\n /** `above-app-overlays` lifts the overlay stack clear of chrome pinned near max-int. */\n stacking?: 'default' | 'above-app-overlays';\n /** Full-width Alert bands at the top of the body, above `children`, in order. Unaffected by\n * `bodyPadding`. The message is markdown. */\n callouts?: { type?: AlertType; message: string }[];\n /** Routes root-relative links in `callouts` through the app's router; see `MarkdownBlock`. */\n renderLink?: RenderLink;\n children: React.ReactNode;\n}\n\nconst TRANSITION_MS = 200;\n\nconst toCssSize = (value: number | string): string =>\n typeof value === 'number' ? `${value}px` : value;\n\n/**\n * A right-hand slide-in overlay panel (drawer) for inspecting or editing an entity\n * without leaving the page. Portals to `document.body`, locks background scroll and\n * traps keyboard focus while open (restoring both on close), dismisses on ESC\n * (topmost open overlay only), overlay click or the close button, and exposes header\n * (back/icon/title/subtitle/extra), scrollable body and optional footer slots.\n */\nconst SidePanel: React.FC<SidePanelProps> = ({\n open,\n onClose,\n title,\n subtitle,\n titleExtra,\n description,\n headerDivider = false,\n icon,\n headerExtra,\n footer,\n onBack,\n maxWidth = 1080,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n bodyPadding = true,\n stacking = 'default',\n callouts,\n renderLink,\n children,\n}) => {\n const [isVisible, setIsVisible] = useState(false);\n const [isMounted, setIsMounted] = useState(false);\n const frameRef = useRef<number | null>(null);\n const unmountTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const hostRef = useRef<HTMLDivElement | null>(null);\n const {\n ref: handlePanelRef,\n isTopmost,\n zIndex,\n elevated,\n } = useOverlayBehaviour({\n open,\n onClose,\n elevated: stacking === 'above-app-overlays',\n hostRef,\n });\n\n useEffect(() => {\n if (open) {\n setIsMounted(true);\n if (unmountTimerRef.current) {\n clearTimeout(unmountTimerRef.current);\n unmountTimerRef.current = null;\n }\n frameRef.current = requestAnimationFrame(() => {\n frameRef.current = null;\n setIsVisible(true);\n });\n } else {\n setIsVisible(false);\n unmountTimerRef.current = setTimeout(() => {\n unmountTimerRef.current = null;\n setIsMounted(false);\n }, TRANSITION_MS);\n }\n return () => {\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current);\n frameRef.current = null;\n }\n if (unmountTimerRef.current) {\n clearTimeout(unmountTimerRef.current);\n unmountTimerRef.current = null;\n }\n };\n }, [open]);\n\n if (!isMounted) {\n return null;\n }\n\n const shownCallouts = callouts?.filter((callout) => callout.message.trim());\n const hasCallouts = !!shownCallouts?.length;\n const paddedBody = bodyPadding ? (\n <div className={hasCallouts ? 'p-[28px]' : 'py-[28px]'}>{children}</div>\n ) : (\n children\n );\n\n return createPortal(\n // Host carries the stacking context — ShadowRootWrapper's `isolation` would\n // otherwise flatten our z-index and let sticky page elements paint over us.\n <ShadowRootWrapper\n hostRef={hostRef}\n hostStyle={{ position: 'relative', zIndex }}\n hostProps={\n elevated\n ? { ...overlayIdentity('sidepanel'), [OVERLAY_ELEVATED_ATTR]: '' }\n : overlayIdentity('sidepanel')\n }\n >\n <div className=\"fixed inset-0 z-[1000]\">\n <div\n aria-hidden=\"true\"\n onClick={onClose}\n className={`absolute inset-0 bg-[var(--malachite-overlay-scrim)] transition-opacity duration-200 ease-in-out ${\n isVisible ? 'opacity-100' : 'opacity-0'\n }`}\n />\n <div\n ref={handlePanelRef}\n role=\"dialog\"\n // Only the topmost overlay may claim it, or a screen reader can still\n // browse the one underneath.\n aria-modal={isTopmost ? 'true' : undefined}\n tabIndex={-1}\n // Prefer aria-labelledby; only fall back to aria-label when it's absent.\n aria-label={\n ariaLabelledBy\n ? undefined\n : (ariaLabel ?? (typeof title === 'string' ? title : undefined))\n }\n aria-labelledby={ariaLabelledBy}\n className=\"absolute top-[8px] right-[8px] bottom-[8px] flex flex-col overflow-hidden rounded-[20px] border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-background)] text-[var(--malachite-card-foreground)] outline-none [box-shadow:var(--malachite-shadow-lg)]\"\n style={{\n width: `min(calc(100% - 16px), ${toCssSize(maxWidth)})`,\n // Inline: Tailwind translate utilities silently break inside\n // shadow roots (see CLAUDE.md Shadow DOM caveats).\n transform: isVisible ? 'translateX(0)' : 'translateX(calc(100% + 16px))',\n transition: `transform ${TRANSITION_MS}ms ease-in-out`,\n }}\n >\n <div\n className={`flex flex-col gap-[20px] px-[20px] py-[18px] ${\n headerDivider\n ? 'border-0 border-b border-solid border-[var(--malachite-card-border)]'\n : ''\n }`}\n >\n <div className=\"flex items-center gap-[12px]\">\n {onBack ? (\n <button\n type=\"button\"\n aria-label=\"Back\"\n onClick={onBack}\n className={OVERLAY_ICON_BUTTON_CLASSES}\n >\n <ArrowLeftIcon size={16} />\n </button>\n ) : null}\n {icon ? (\n <span className=\"flex shrink-0 items-center\">{icon}</span>\n ) : null}\n <div className=\"flex min-w-0 flex-1 items-baseline gap-[12px]\">\n <div className=\"flex min-w-0 flex-1 items-baseline gap-[8px]\">\n <div className=\"flex min-w-0 items-baseline gap-[8px]\">\n <span className=\"flex min-w-0 max-w-full shrink-0\">\n <EllipsisText\n tooltip={title}\n tooltipWhenTruncated\n tooltipPlacement=\"bottom\"\n className=\"min-w-0 text-[length:var(--malachite-font-size-15,15px)] font-semibold\"\n >\n {title}\n </EllipsisText>\n </span>\n {subtitle ? (\n <EllipsisText\n tooltip={subtitle}\n tooltipWhenTruncated\n tooltipPlacement=\"bottom\"\n color=\"secondary\"\n className=\"min-w-0 text-[13px]\"\n >\n {subtitle}\n </EllipsisText>\n ) : null}\n </div>\n {titleExtra ? (\n <span className=\"flex shrink-0 items-center\">\n {titleExtra}\n </span>\n ) : null}\n </div>\n {headerExtra ? (\n <span className=\"flex shrink-0 items-baseline\">\n {headerExtra}\n </span>\n ) : null}\n </div>\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={onClose}\n className={OVERLAY_ICON_BUTTON_CLASSES}\n >\n <DismissIcon size={10} />\n </button>\n </div>\n {description ? (\n <div className=\"text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]\">\n {description}\n </div>\n ) : null}\n </div>\n {/* Callouts move the horizontal padding inward so their strips run full-bleed. */}\n <div\n className={`min-h-0 flex-1 overflow-y-auto ${bodyPadding && !hasCallouts ? 'px-[28px]' : ''}`}\n >\n {shownCallouts?.map((callout, index) => (\n <CalloutStrip\n key={index}\n type={callout.type}\n message={callout.message}\n renderLink={renderLink}\n />\n ))}\n {paddedBody}\n </div>\n {footer ? (\n <div className=\"border-0 border-t border-solid border-[var(--malachite-card-border)] px-[24px] py-[16px]\">\n {footer}\n </div>\n ) : null}\n </div>\n </div>\n </ShadowRootWrapper>,\n document.body,\n );\n};\n\nexport default SidePanel;\nexport { SidePanel };\n"],"names":["TRANSITION_MS","toCssSize","value","SidePanel","open","onClose","title","subtitle","titleExtra","description","headerDivider","icon","headerExtra","footer","onBack","maxWidth","ariaLabel","ariaLabelledBy","bodyPadding","stacking","callouts","renderLink","children","isVisible","setIsVisible","useState","isMounted","setIsMounted","frameRef","useRef","unmountTimerRef","hostRef","handlePanelRef","isTopmost","zIndex","elevated","useOverlayBehaviour","useEffect","shownCallouts","callout","hasCallouts","paddedBody","jsx","createPortal","ShadowRootWrapper","overlayIdentity","OVERLAY_ELEVATED_ATTR","jsxs","OVERLAY_ICON_BUTTON_CLASSES","ArrowLeftIcon","EllipsisText","DismissIcon","index","CalloutStrip"],"mappings":";;;;;;;;;;AAkDA,MAAMA,IAAgB,KAEhBC,IAAY,CAACC,MACf,OAAOA,KAAU,WAAW,GAAGA,CAAK,OAAOA,GASzCC,KAAsC,CAAC;AAAA,EACzC,MAAAC;AAAA,EACA,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,aAAAC;AAAA,EACA,eAAAC,IAAgB;AAAA,EAChB,MAAAC;AAAA,EACA,aAAAC;AAAA,EACA,QAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,cAAcC;AAAA,EACd,mBAAmBC;AAAA,EACnB,aAAAC,IAAc;AAAA,EACd,UAAAC,IAAW;AAAA,EACX,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AACJ,MAAM;AACF,QAAM,CAACC,GAAWC,CAAY,IAAIC,EAAS,EAAK,GAC1C,CAACC,GAAWC,CAAY,IAAIF,EAAS,EAAK,GAC1CG,IAAWC,EAAsB,IAAI,GACrCC,IAAkBD,EAA6C,IAAI,GACnEE,IAAUF,EAA8B,IAAI,GAC5C;AAAA,IACF,KAAKG;AAAA,IACL,WAAAC;AAAA,IACA,QAAAC;AAAA,IACA,UAAAC;AAAA,EAAA,IACAC,EAAoB;AAAA,IACpB,MAAAhC;AAAA,IACA,SAAAC;AAAA,IACA,UAAUc,MAAa;AAAA,IACvB,SAAAY;AAAA,EAAA,CACH;AAgCD,MA9BAM,EAAU,OACFjC,KACAuB,EAAa,EAAI,GACbG,EAAgB,YAChB,aAAaA,EAAgB,OAAO,GACpCA,EAAgB,UAAU,OAE9BF,EAAS,UAAU,sBAAsB,MAAM;AAC3C,IAAAA,EAAS,UAAU,MACnBJ,EAAa,EAAI;AAAA,EACrB,CAAC,MAEDA,EAAa,EAAK,GAClBM,EAAgB,UAAU,WAAW,MAAM;AACvC,IAAAA,EAAgB,UAAU,MAC1BH,EAAa,EAAK;AAAA,EACtB,GAAG3B,CAAa,IAEb,MAAM;AACT,IAAI4B,EAAS,YAAY,SACrB,qBAAqBA,EAAS,OAAO,GACrCA,EAAS,UAAU,OAEnBE,EAAgB,YAChB,aAAaA,EAAgB,OAAO,GACpCA,EAAgB,UAAU;AAAA,EAElC,IACD,CAAC1B,CAAI,CAAC,GAEL,CAACsB;AACD,WAAO;AAGX,QAAMY,IAAgBlB,KAAA,gBAAAA,EAAU,OAAO,CAACmB,MAAYA,EAAQ,QAAQ,SAC9DC,IAAc,CAAC,EAACF,KAAA,QAAAA,EAAe,SAC/BG,IAAavB,IACf,gBAAAwB,EAAC,OAAA,EAAI,WAAWF,IAAc,aAAa,aAAc,UAAAlB,EAAA,CAAS,IAElEA;AAGJ,SAAOqB;AAAA;AAAA;AAAA,IAGH,gBAAAD;AAAA,MAACE;AAAA,MAAA;AAAA,QACG,SAAAb;AAAA,QACA,WAAW,EAAE,UAAU,YAAY,QAAAG,EAAA;AAAA,QACnC,WACIC,IACM,EAAE,GAAGU,EAAgB,WAAW,GAAG,CAACC,CAAqB,GAAG,GAAA,IAC5DD,EAAgB,WAAW;AAAA,QAGrC,UAAA,gBAAAE,EAAC,OAAA,EAAI,WAAU,0BACX,UAAA;AAAA,UAAA,gBAAAL;AAAA,YAAC;AAAA,YAAA;AAAA,cACG,eAAY;AAAA,cACZ,SAASrC;AAAA,cACT,WAAW,oGACPkB,IAAY,gBAAgB,WAChC;AAAA,YAAA;AAAA,UAAA;AAAA,UAEJ,gBAAAwB;AAAA,YAAC;AAAA,YAAA;AAAA,cACG,KAAKf;AAAA,cACL,MAAK;AAAA,cAGL,cAAYC,IAAY,SAAS;AAAA,cACjC,UAAU;AAAA,cAEV,cACIhB,IACM,SACCD,MAAc,OAAOV,KAAU,WAAWA,IAAQ;AAAA,cAE7D,mBAAiBW;AAAA,cACjB,WAAU;AAAA,cACV,OAAO;AAAA,gBACH,OAAO,0BAA0BhB,EAAUc,CAAQ,CAAC;AAAA;AAAA;AAAA,gBAGpD,WAAWQ,IAAY,kBAAkB;AAAA,gBACzC,YAAY,aAAavB,CAAa;AAAA,cAAA;AAAA,cAG1C,UAAA;AAAA,gBAAA,gBAAA+C;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACG,WAAW,gDACPrC,IACM,yEACA,EACV;AAAA,oBAEA,UAAA;AAAA,sBAAA,gBAAAqC,EAAC,OAAA,EAAI,WAAU,gCACV,UAAA;AAAA,wBAAAjC,IACG,gBAAA4B;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACG,MAAK;AAAA,4BACL,cAAW;AAAA,4BACX,SAAS5B;AAAA,4BACT,WAAWkC;AAAA,4BAEX,UAAA,gBAAAN,EAACO,GAAA,EAAc,MAAM,GAAA,CAAI;AAAA,0BAAA;AAAA,wBAAA,IAE7B;AAAA,wBACHtC,IACG,gBAAA+B,EAAC,QAAA,EAAK,WAAU,8BAA8B,aAAK,IACnD;AAAA,wBACJ,gBAAAK,EAAC,OAAA,EAAI,WAAU,iDACX,UAAA;AAAA,0BAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,gDACX,UAAA;AAAA,4BAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,yCACX,UAAA;AAAA,8BAAA,gBAAAL,EAAC,QAAA,EAAK,WAAU,oCACZ,UAAA,gBAAAA;AAAA,gCAACQ;AAAA,gCAAA;AAAA,kCACG,SAAS5C;AAAA,kCACT,sBAAoB;AAAA,kCACpB,kBAAiB;AAAA,kCACjB,WAAU;AAAA,kCAET,UAAAA;AAAA,gCAAA;AAAA,8BAAA,GAET;AAAA,8BACCC,IACG,gBAAAmC;AAAA,gCAACQ;AAAA,gCAAA;AAAA,kCACG,SAAS3C;AAAA,kCACT,sBAAoB;AAAA,kCACpB,kBAAiB;AAAA,kCACjB,OAAM;AAAA,kCACN,WAAU;AAAA,kCAET,UAAAA;AAAA,gCAAA;AAAA,8BAAA,IAEL;AAAA,4BAAA,GACR;AAAA,4BACCC,IACG,gBAAAkC,EAAC,QAAA,EAAK,WAAU,8BACX,aACL,IACA;AAAA,0BAAA,GACR;AAAA,0BACC9B,IACG,gBAAA8B,EAAC,QAAA,EAAK,WAAU,gCACX,aACL,IACA;AAAA,wBAAA,GACR;AAAA,wBACA,gBAAAA;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACG,MAAK;AAAA,4BACL,cAAW;AAAA,4BACX,SAASrC;AAAA,4BACT,WAAW2C;AAAA,4BAEX,UAAA,gBAAAN,EAACS,GAAA,EAAY,MAAM,GAAA,CAAI;AAAA,0BAAA;AAAA,wBAAA;AAAA,sBAC3B,GACJ;AAAA,sBACC1C,IACG,gBAAAiC,EAAC,OAAA,EAAI,WAAU,oEACV,aACL,IACA;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAGR,gBAAAK;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACG,WAAW,kCAAkC7B,KAAe,CAACsB,IAAc,cAAc,EAAE;AAAA,oBAE1F,UAAA;AAAA,sBAAAF,KAAA,gBAAAA,EAAe,IAAI,CAACC,GAASa,MAC1B,gBAAAV;AAAA,wBAACW;AAAA,wBAAA;AAAA,0BAEG,MAAMd,EAAQ;AAAA,0BACd,SAASA,EAAQ;AAAA,0BACjB,YAAAlB;AAAA,wBAAA;AAAA,wBAHK+B;AAAA,sBAAA;AAAA,sBAMZX;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEJ5B,IACG,gBAAA6B,EAAC,OAAA,EAAI,WAAU,4FACV,aACL,IACA;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QACR,EAAA,CACJ;AAAA,MAAA;AAAA,IAAA;AAAA,IAEJ,SAAS;AAAA,EAAA;AAEjB;"}
1
+ {"version":3,"file":"SidePanel.js","sources":["../../src/components/SidePanel.tsx"],"sourcesContent":["import React, { useEffect, useId, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ShadowRootWrapper } from '../ShadowRootWrapper';\nimport type { AlertType } from './Alert';\nimport CalloutStrip from './CalloutStrip';\nimport ArrowLeftIcon from './CustomIcons/ArrowLeftIcon';\nimport DismissIcon from './CustomIcons/DismissIcon';\nimport type { RenderLink } from './PageLayout/types';\nimport EllipsisText from './Typography/EllipsisText';\nimport { OVERLAY_ICON_BUTTON_CLASSES, useOverlayBehaviour } from './overlayBehaviour';\nimport { OVERLAY_ELEVATED_ATTR, overlayIdentity } from './portalOverlay';\n\nexport interface SidePanelProps {\n open: boolean;\n /** Dismiss handler — close button, ESC, or overlay click. */\n onClose: () => void;\n title: React.ReactNode;\n /** Secondary text, inline after the title. */\n subtitle?: React.ReactNode;\n /** Content at the end of the title row, after the subtitle (e.g. a status tag). */\n titleExtra?: React.ReactNode;\n /** Block paragraph below the title row, spanning the header width. Announced as the panel's description. */\n description?: React.ReactNode;\n /** Divider under the header. Default: false. */\n headerDivider?: boolean;\n /** Leading header slot, typically a logo or icon. */\n icon?: React.ReactNode;\n /** Content pinned right in the header, before the close button. */\n headerExtra?: React.ReactNode;\n footer?: React.ReactNode;\n /** Renders a back button before the header icon. */\n onBack?: () => void;\n /** Maximum panel width. Default: 1080. */\n maxWidth?: number | string;\n /** Accessible dialog name; required when `title` isn't a plain string. */\n 'aria-label'?: string;\n /** ID of a visible element naming the dialog (alternative to `aria-label`). */\n 'aria-labelledby'?: string;\n /** Whether the body gets default padding. Default: true. */\n bodyPadding?: boolean;\n /** `above-app-overlays` lifts the overlay stack clear of chrome pinned near max-int. */\n stacking?: 'default' | 'above-app-overlays';\n /** Full-width Alert bands at the top of the body, above `children`, in order. Unaffected by\n * `bodyPadding`, and announced ahead of `description`. The message is markdown. */\n callouts?: { type?: AlertType; message: string }[];\n /** Routes root-relative links in `callouts` through the app's router; see `MarkdownBlock`. */\n renderLink?: RenderLink;\n children: React.ReactNode;\n}\n\nconst TRANSITION_MS = 200;\n\nconst toCssSize = (value: number | string): string =>\n typeof value === 'number' ? `${value}px` : value;\n\n/**\n * A right-hand slide-in overlay panel (drawer) for inspecting or editing an entity\n * without leaving the page. Portals to `document.body`, locks background scroll and\n * traps keyboard focus while open (restoring both on close), dismisses on ESC\n * (topmost open overlay only), overlay click or the close button, and exposes header\n * (back/icon/title/subtitle/extra), scrollable body and optional footer slots.\n */\nconst SidePanel: React.FC<SidePanelProps> = ({\n open,\n onClose,\n title,\n subtitle,\n titleExtra,\n description,\n headerDivider = false,\n icon,\n headerExtra,\n footer,\n onBack,\n maxWidth = 1080,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n bodyPadding = true,\n stacking = 'default',\n callouts,\n renderLink,\n children,\n}) => {\n const calloutId = useId();\n const descriptionId = useId();\n const [isVisible, setIsVisible] = useState(false);\n const [isMounted, setIsMounted] = useState(false);\n const frameRef = useRef<number | null>(null);\n const unmountTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const hostRef = useRef<HTMLDivElement | null>(null);\n const {\n ref: handlePanelRef,\n isTopmost,\n zIndex,\n elevated,\n } = useOverlayBehaviour({\n open,\n onClose,\n elevated: stacking === 'above-app-overlays',\n hostRef,\n });\n\n useEffect(() => {\n if (open) {\n setIsMounted(true);\n if (unmountTimerRef.current) {\n clearTimeout(unmountTimerRef.current);\n unmountTimerRef.current = null;\n }\n frameRef.current = requestAnimationFrame(() => {\n frameRef.current = null;\n setIsVisible(true);\n });\n } else {\n setIsVisible(false);\n unmountTimerRef.current = setTimeout(() => {\n unmountTimerRef.current = null;\n setIsMounted(false);\n }, TRANSITION_MS);\n }\n return () => {\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current);\n frameRef.current = null;\n }\n if (unmountTimerRef.current) {\n clearTimeout(unmountTimerRef.current);\n unmountTimerRef.current = null;\n }\n };\n }, [open]);\n\n if (!isMounted) {\n return null;\n }\n\n const shownCallouts = callouts?.filter((callout) => callout.message.trim());\n const hasCallouts = !!shownCallouts?.length;\n const paddedBody = bodyPadding ? (\n <div className={hasCallouts ? 'p-[28px]' : 'py-[28px]'}>{children}</div>\n ) : (\n children\n );\n\n return createPortal(\n // Host carries the stacking context — ShadowRootWrapper's `isolation` would\n // otherwise flatten our z-index and let sticky page elements paint over us.\n <ShadowRootWrapper\n hostRef={hostRef}\n hostStyle={{ position: 'relative', zIndex }}\n hostProps={\n elevated\n ? { ...overlayIdentity('sidepanel'), [OVERLAY_ELEVATED_ATTR]: '' }\n : overlayIdentity('sidepanel')\n }\n >\n <div className=\"fixed inset-0 z-[1000]\">\n <div\n aria-hidden=\"true\"\n onClick={onClose}\n className={`absolute inset-0 bg-[var(--malachite-overlay-scrim)] transition-opacity duration-200 ease-in-out ${\n isVisible ? 'opacity-100' : 'opacity-0'\n }`}\n />\n <div\n ref={handlePanelRef}\n role=\"dialog\"\n // Only the topmost overlay may claim it, or a screen reader can still\n // browse the one underneath.\n aria-modal={isTopmost ? 'true' : undefined}\n aria-describedby={\n [\n ...(shownCallouts ?? []).map((_, index) => `${calloutId}-${index}`),\n description ? descriptionId : null,\n ]\n .filter(Boolean)\n .join(' ') || undefined\n }\n tabIndex={-1}\n // Prefer aria-labelledby; only fall back to aria-label when it's absent.\n aria-label={\n ariaLabelledBy\n ? undefined\n : (ariaLabel ?? (typeof title === 'string' ? title : undefined))\n }\n aria-labelledby={ariaLabelledBy}\n className=\"absolute top-[8px] right-[8px] bottom-[8px] flex flex-col overflow-hidden rounded-[20px] border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-background)] text-[var(--malachite-card-foreground)] outline-none [box-shadow:var(--malachite-shadow-lg)]\"\n style={{\n width: `min(calc(100% - 16px), ${toCssSize(maxWidth)})`,\n // Inline: Tailwind translate utilities silently break inside\n // shadow roots (see CLAUDE.md Shadow DOM caveats).\n transform: isVisible ? 'translateX(0)' : 'translateX(calc(100% + 16px))',\n transition: `transform ${TRANSITION_MS}ms ease-in-out`,\n }}\n >\n <div\n className={`flex flex-col gap-[20px] px-[20px] py-[18px] ${\n headerDivider\n ? 'border-0 border-b border-solid border-[var(--malachite-card-border)]'\n : ''\n }`}\n >\n <div className=\"flex items-center gap-[12px]\">\n {onBack ? (\n <button\n type=\"button\"\n aria-label=\"Back\"\n onClick={onBack}\n className={OVERLAY_ICON_BUTTON_CLASSES}\n >\n <ArrowLeftIcon size={16} />\n </button>\n ) : null}\n {icon ? (\n <span className=\"flex shrink-0 items-center\">{icon}</span>\n ) : null}\n <div className=\"flex min-w-0 flex-1 items-baseline gap-[12px]\">\n <div className=\"flex min-w-0 flex-1 items-baseline gap-[8px]\">\n <div className=\"flex min-w-0 items-baseline gap-[8px]\">\n <span className=\"flex min-w-0 max-w-full shrink-0\">\n <EllipsisText\n tooltip={title}\n tooltipWhenTruncated\n tooltipPlacement=\"bottom\"\n className=\"min-w-0 text-[length:var(--malachite-font-size-15,15px)] font-semibold\"\n >\n {title}\n </EllipsisText>\n </span>\n {subtitle ? (\n <EllipsisText\n tooltip={subtitle}\n tooltipWhenTruncated\n tooltipPlacement=\"bottom\"\n color=\"secondary\"\n className=\"min-w-0 text-[13px]\"\n >\n {subtitle}\n </EllipsisText>\n ) : null}\n </div>\n {titleExtra ? (\n <span className=\"flex shrink-0 items-center\">\n {titleExtra}\n </span>\n ) : null}\n </div>\n {headerExtra ? (\n <span className=\"flex shrink-0 items-baseline\">\n {headerExtra}\n </span>\n ) : null}\n </div>\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={onClose}\n className={OVERLAY_ICON_BUTTON_CLASSES}\n >\n <DismissIcon size={10} />\n </button>\n </div>\n {description ? (\n <div\n id={descriptionId}\n className=\"text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]\"\n >\n {description}\n </div>\n ) : null}\n </div>\n {/* Callouts move the horizontal padding inward so their strips run full-bleed. */}\n <div\n className={`min-h-0 flex-1 overflow-y-auto ${bodyPadding && !hasCallouts ? 'px-[28px]' : ''}`}\n >\n {shownCallouts?.map((callout, index) => (\n <CalloutStrip\n key={index}\n id={`${calloutId}-${index}`}\n type={callout.type}\n message={callout.message}\n renderLink={renderLink}\n />\n ))}\n {paddedBody}\n </div>\n {footer ? (\n <div className=\"border-0 border-t border-solid border-[var(--malachite-card-border)] px-[24px] py-[16px]\">\n {footer}\n </div>\n ) : null}\n </div>\n </div>\n </ShadowRootWrapper>,\n document.body,\n );\n};\n\nexport default SidePanel;\nexport { SidePanel };\n"],"names":["TRANSITION_MS","toCssSize","value","SidePanel","open","onClose","title","subtitle","titleExtra","description","headerDivider","icon","headerExtra","footer","onBack","maxWidth","ariaLabel","ariaLabelledBy","bodyPadding","stacking","callouts","renderLink","children","calloutId","useId","descriptionId","isVisible","setIsVisible","useState","isMounted","setIsMounted","frameRef","useRef","unmountTimerRef","hostRef","handlePanelRef","isTopmost","zIndex","elevated","useOverlayBehaviour","useEffect","shownCallouts","callout","hasCallouts","paddedBody","jsx","createPortal","ShadowRootWrapper","overlayIdentity","OVERLAY_ELEVATED_ATTR","jsxs","_","index","OVERLAY_ICON_BUTTON_CLASSES","ArrowLeftIcon","EllipsisText","DismissIcon","CalloutStrip"],"mappings":"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"}