@stackone/malachite 2.56.0 → 2.57.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +5 -4
- package/dist/components/Alert.js +67 -50
- package/dist/components/Alert.js.map +1 -1
- package/dist/components/Breadcrumbs.js.map +1 -1
- package/dist/components/CalloutStrip.js +20 -0
- package/dist/components/CalloutStrip.js.map +1 -0
- package/dist/components/ConfirmationDialog.js +146 -144
- package/dist/components/ConfirmationDialog.js.map +1 -1
- package/dist/components/IconBadge.js +16 -0
- package/dist/components/IconBadge.js.map +1 -0
- package/dist/components/PageLayout/index.js.map +1 -1
- package/dist/components/PageLayout/regularLayout.js.map +1 -1
- package/dist/components/SidePanel.js +99 -82
- package/dist/components/SidePanel.js.map +1 -1
- package/dist/components/Typography/MarkdownBlock.js +89 -87
- package/dist/components/Typography/MarkdownBlock.js.map +1 -1
- package/dist/components/activeElement.js +10 -2
- package/dist/components/activeElement.js.map +1 -1
- package/dist/components/confirmationDialogVariants.js +2 -6
- package/dist/components/confirmationDialogVariants.js.map +1 -1
- package/dist/components/iconBadgeVariants.js +11 -0
- package/dist/components/iconBadgeVariants.js.map +1 -0
- package/dist/components/overlayBehaviour.js +176 -146
- package/dist/components/overlayBehaviour.js.map +1 -1
- package/dist/components/overlayLayers.js +22 -28
- package/dist/components/overlayLayers.js.map +1 -1
- package/dist/index.d.ts +31 -5
- package/dist/index.js +447 -445
- package/dist/index.js.map +1 -1
- package/dist/tailwind.css.js +1 -1
- package/package.json +1 -1
|
@@ -1,153 +1,170 @@
|
|
|
1
1
|
import { jsx as e, jsxs as a } from "react/jsx-runtime";
|
|
2
|
-
import { useState as
|
|
3
|
-
import { createPortal as
|
|
4
|
-
import { ShadowRootWrapper as
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"aria-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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 = ({
|
|
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,
|
|
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
|
|
28
31
|
}) => {
|
|
29
|
-
const [
|
|
30
|
-
ref:
|
|
31
|
-
isTopmost:
|
|
32
|
-
zIndex:
|
|
33
|
-
elevated:
|
|
34
|
-
} =
|
|
35
|
-
open:
|
|
36
|
-
onClose:
|
|
37
|
-
elevated:
|
|
38
|
-
hostRef:
|
|
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({
|
|
38
|
+
open: t,
|
|
39
|
+
onClose: o,
|
|
40
|
+
elevated: P === "above-app-overlays",
|
|
41
|
+
hostRef: S
|
|
39
42
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
})) : (
|
|
43
|
-
r.current = null,
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
}), [
|
|
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)), () => {
|
|
48
|
+
i.current !== null && (cancelAnimationFrame(i.current), i.current = null), r.current && (clearTimeout(r.current), r.current = null);
|
|
49
|
+
}), [t]), !C)
|
|
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(
|
|
47
53
|
// Host carries the stacking context — ShadowRootWrapper's `isolation` would
|
|
48
54
|
// otherwise flatten our z-index and let sticky page elements paint over us.
|
|
49
55
|
/* @__PURE__ */ e(
|
|
50
|
-
|
|
56
|
+
Y,
|
|
51
57
|
{
|
|
52
|
-
hostRef:
|
|
53
|
-
hostStyle: { position: "relative", zIndex:
|
|
54
|
-
hostProps:
|
|
58
|
+
hostRef: S,
|
|
59
|
+
hostStyle: { position: "relative", zIndex: W },
|
|
60
|
+
hostProps: j ? { ...z("sidepanel"), [J]: "" } : z("sidepanel"),
|
|
55
61
|
children: /* @__PURE__ */ a("div", { className: "fixed inset-0 z-[1000]", children: [
|
|
56
62
|
/* @__PURE__ */ e(
|
|
57
63
|
"div",
|
|
58
64
|
{
|
|
59
65
|
"aria-hidden": "true",
|
|
60
|
-
onClick:
|
|
61
|
-
className: `absolute inset-0 bg-[var(--malachite-overlay-scrim)] transition-opacity duration-200 ease-in-out ${
|
|
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"}`
|
|
62
68
|
}
|
|
63
69
|
),
|
|
64
70
|
/* @__PURE__ */ a(
|
|
65
71
|
"div",
|
|
66
72
|
{
|
|
67
|
-
ref:
|
|
73
|
+
ref: L,
|
|
68
74
|
role: "dialog",
|
|
69
|
-
"aria-modal":
|
|
75
|
+
"aria-modal": M ? "true" : void 0,
|
|
70
76
|
tabIndex: -1,
|
|
71
|
-
"aria-label":
|
|
72
|
-
"aria-labelledby":
|
|
77
|
+
"aria-label": v ? void 0 : $ ?? (typeof n == "string" ? n : void 0),
|
|
78
|
+
"aria-labelledby": v,
|
|
73
79
|
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)]",
|
|
74
80
|
style: {
|
|
75
|
-
width: `min(calc(100% - 16px), ${
|
|
81
|
+
width: `min(calc(100% - 16px), ${K(_)})`,
|
|
76
82
|
// Inline: Tailwind translate utilities silently break inside
|
|
77
83
|
// shadow roots (see CLAUDE.md Shadow DOM caveats).
|
|
78
|
-
transform:
|
|
79
|
-
transition: `transform ${
|
|
84
|
+
transform: g ? "translateX(0)" : "translateX(calc(100% + 16px))",
|
|
85
|
+
transition: `transform ${E}ms ease-in-out`
|
|
80
86
|
},
|
|
81
87
|
children: [
|
|
82
88
|
/* @__PURE__ */ a(
|
|
83
89
|
"div",
|
|
84
90
|
{
|
|
85
|
-
className: `flex flex-col gap-[20px] px-[20px] py-[18px] ${
|
|
91
|
+
className: `flex flex-col gap-[20px] px-[20px] py-[18px] ${O ? "border-0 border-b border-solid border-[var(--malachite-card-border)]" : ""}`,
|
|
86
92
|
children: [
|
|
87
93
|
/* @__PURE__ */ a("div", { className: "flex items-center gap-[12px]", children: [
|
|
88
|
-
|
|
94
|
+
b ? /* @__PURE__ */ e(
|
|
89
95
|
"button",
|
|
90
96
|
{
|
|
91
97
|
type: "button",
|
|
92
98
|
"aria-label": "Back",
|
|
93
|
-
onClick:
|
|
94
|
-
className:
|
|
95
|
-
children: /* @__PURE__ */ e(
|
|
99
|
+
onClick: b,
|
|
100
|
+
className: k,
|
|
101
|
+
children: /* @__PURE__ */ e(U, { size: 16 })
|
|
96
102
|
}
|
|
97
103
|
) : null,
|
|
98
|
-
|
|
104
|
+
f ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center", children: f }) : null,
|
|
99
105
|
/* @__PURE__ */ a("div", { className: "flex min-w-0 flex-1 items-baseline gap-[12px]", children: [
|
|
100
106
|
/* @__PURE__ */ a("div", { className: "flex min-w-0 flex-1 items-baseline gap-[8px]", children: [
|
|
101
107
|
/* @__PURE__ */ a("div", { className: "flex min-w-0 items-baseline gap-[8px]", children: [
|
|
102
108
|
/* @__PURE__ */ e("span", { className: "flex min-w-0 max-w-full shrink-0", children: /* @__PURE__ */ e(
|
|
103
|
-
|
|
109
|
+
A,
|
|
104
110
|
{
|
|
105
|
-
tooltip:
|
|
111
|
+
tooltip: n,
|
|
106
112
|
tooltipWhenTruncated: !0,
|
|
107
113
|
tooltipPlacement: "bottom",
|
|
108
114
|
className: "min-w-0 text-[length:var(--malachite-font-size-15,15px)] font-semibold",
|
|
109
|
-
children:
|
|
115
|
+
children: n
|
|
110
116
|
}
|
|
111
117
|
) }),
|
|
112
|
-
|
|
113
|
-
|
|
118
|
+
c ? /* @__PURE__ */ e(
|
|
119
|
+
A,
|
|
114
120
|
{
|
|
115
|
-
tooltip:
|
|
121
|
+
tooltip: c,
|
|
116
122
|
tooltipWhenTruncated: !0,
|
|
117
123
|
tooltipPlacement: "bottom",
|
|
118
124
|
color: "secondary",
|
|
119
125
|
className: "min-w-0 text-[13px]",
|
|
120
|
-
children:
|
|
126
|
+
children: c
|
|
121
127
|
}
|
|
122
128
|
) : null
|
|
123
129
|
] }),
|
|
124
|
-
|
|
130
|
+
p ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center", children: p }) : null
|
|
125
131
|
] }),
|
|
126
|
-
|
|
132
|
+
x ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-baseline", children: x }) : null
|
|
127
133
|
] }),
|
|
128
134
|
/* @__PURE__ */ e(
|
|
129
135
|
"button",
|
|
130
136
|
{
|
|
131
137
|
type: "button",
|
|
132
138
|
"aria-label": "Close",
|
|
133
|
-
onClick:
|
|
134
|
-
className:
|
|
135
|
-
children: /* @__PURE__ */ e(
|
|
139
|
+
onClick: o,
|
|
140
|
+
className: k,
|
|
141
|
+
children: /* @__PURE__ */ e(G, { size: 10 })
|
|
136
142
|
}
|
|
137
143
|
)
|
|
138
144
|
] }),
|
|
139
|
-
|
|
145
|
+
u ? /* @__PURE__ */ e("div", { className: "text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]", children: u }) : null
|
|
140
146
|
]
|
|
141
147
|
}
|
|
142
148
|
),
|
|
143
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ a(
|
|
144
150
|
"div",
|
|
145
151
|
{
|
|
146
|
-
className: `min-h-0 flex-1 overflow-y-auto ${
|
|
147
|
-
children:
|
|
152
|
+
className: `min-h-0 flex-1 overflow-y-auto ${y && !I ? "px-[28px]" : ""}`,
|
|
153
|
+
children: [
|
|
154
|
+
l == null ? void 0 : l.map((s, D) => /* @__PURE__ */ e(
|
|
155
|
+
q,
|
|
156
|
+
{
|
|
157
|
+
type: s.type,
|
|
158
|
+
message: s.message,
|
|
159
|
+
renderLink: V
|
|
160
|
+
},
|
|
161
|
+
D
|
|
162
|
+
)),
|
|
163
|
+
B
|
|
164
|
+
]
|
|
148
165
|
}
|
|
149
166
|
),
|
|
150
|
-
|
|
167
|
+
h ? /* @__PURE__ */ e("div", { className: "border-0 border-t border-solid border-[var(--malachite-card-border)] px-[24px] py-[16px]", children: h }) : null
|
|
151
168
|
]
|
|
152
169
|
}
|
|
153
170
|
)
|
|
@@ -155,10 +172,10 @@ const S = 200, X = (l) => typeof l == "number" ? `${l}px` : l, Z = ({
|
|
|
155
172
|
}
|
|
156
173
|
),
|
|
157
174
|
document.body
|
|
158
|
-
)
|
|
175
|
+
);
|
|
159
176
|
};
|
|
160
177
|
export {
|
|
161
|
-
|
|
162
|
-
|
|
178
|
+
oe as SidePanel,
|
|
179
|
+
oe as default
|
|
163
180
|
};
|
|
164
181
|
//# 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 ArrowLeftIcon from './CustomIcons/ArrowLeftIcon';\nimport DismissIcon from './CustomIcons/DismissIcon';\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 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 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 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 <div\n className={`min-h-0 flex-1 overflow-y-auto ${bodyPadding ? 'px-[28px]' : ''}`}\n >\n {bodyPadding ? <div className=\"py-[28px]\">{children}</div> : children}\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","children","isVisible","setIsVisible","useState","isMounted","setIsMounted","frameRef","useRef","unmountTimerRef","hostRef","handlePanelRef","isTopmost","zIndex","elevated","useOverlayBehaviour","useEffect","createPortal","jsx","ShadowRootWrapper","overlayIdentity","OVERLAY_ELEVATED_ATTR","jsxs","OVERLAY_ICON_BUTTON_CLASSES","ArrowLeftIcon","EllipsisText","DismissIcon"],"mappings":"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"}
|
|
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":"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"}
|