@stackone/malachite 2.70.0 → 2.72.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.
- package/COMPONENTS.md +12 -11
- package/dist/components/Accordion.js +59 -53
- package/dist/components/Accordion.js.map +1 -1
- package/dist/components/Alert.js +100 -75
- package/dist/components/Alert.js.map +1 -1
- package/dist/components/Button.js +89 -82
- package/dist/components/Button.js.map +1 -1
- package/dist/components/Modal.js +75 -74
- package/dist/components/Modal.js.map +1 -1
- package/dist/components/PopoverParts.js +35 -35
- package/dist/components/PopoverParts.js.map +1 -1
- package/dist/components/Search.js +30 -29
- package/dist/components/Search.js.map +1 -1
- package/dist/components/SidePanel.js +124 -106
- package/dist/components/SidePanel.js.map +1 -1
- package/dist/components/StatusPill.js +61 -0
- package/dist/components/StatusPill.js.map +1 -0
- package/dist/components/Surface.js +138 -133
- package/dist/components/Surface.js.map +1 -1
- package/dist/components/Toolbar.js +40 -33
- package/dist/components/Toolbar.js.map +1 -1
- package/dist/components/Typography/EllipsisText.js +27 -25
- package/dist/components/Typography/EllipsisText.js.map +1 -1
- package/dist/components/Typography/MarkdownBlock.js +36 -28
- package/dist/components/Typography/MarkdownBlock.js.map +1 -1
- package/dist/components/Typography/Text.js +24 -22
- package/dist/components/Typography/Text.js.map +1 -1
- package/dist/components/WizardLayout.js +81 -67
- package/dist/components/WizardLayout.js.map +1 -1
- package/dist/index.d.ts +65 -2
- package/dist/index.js +356 -354
- package/dist/index.js.map +1 -1
- package/dist/tailwind.css.js +1 -1
- package/package.json +1 -1
|
@@ -1,104 +1,118 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useRef as
|
|
3
|
-
import { Button as
|
|
4
|
-
import
|
|
5
|
-
import { GLASS_SURFACE_STYLE as
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { jsxs as s, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as j, useState as L, useLayoutEffect as z } from "react";
|
|
3
|
+
import { Button as A } from "./Button.js";
|
|
4
|
+
import R from "./CustomIcons/ArrowLeftIcon.js";
|
|
5
|
+
import { GLASS_SURFACE_STYLE as B } from "./glassSurface.js";
|
|
6
|
+
const E = {
|
|
7
|
+
default: "px-6 pt-4 min-h-[var(--malachite-control-height-small,28px)]",
|
|
8
|
+
large: "h-[60px] px-[28px] max-sm:h-[52px] max-sm:px-[16px]"
|
|
9
|
+
}, F = ({
|
|
10
|
+
showBack: p = !1,
|
|
11
|
+
onBack: f,
|
|
9
12
|
backDisabled: h = !1,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
reserveBack: d = !0,
|
|
14
|
+
topBarSize: u = "default",
|
|
15
|
+
leading: v,
|
|
16
|
+
stepper: g,
|
|
17
|
+
trailing: w,
|
|
18
|
+
banner: r,
|
|
19
|
+
header: t,
|
|
20
|
+
footer: l,
|
|
21
|
+
footerGlass: N = !1,
|
|
22
|
+
footerAlign: y = "full",
|
|
23
|
+
center: b = !1,
|
|
24
|
+
contentWidth: a = 480,
|
|
25
|
+
minWidth: c,
|
|
26
|
+
children: k,
|
|
27
|
+
className: S = ""
|
|
21
28
|
}) => {
|
|
22
|
-
const n =
|
|
23
|
-
return
|
|
24
|
-
const
|
|
25
|
-
if (!
|
|
26
|
-
|
|
29
|
+
const n = j(null), [$, o] = L(0);
|
|
30
|
+
return z(() => {
|
|
31
|
+
const i = n.current;
|
|
32
|
+
if (!i) {
|
|
33
|
+
o(0);
|
|
27
34
|
return;
|
|
28
35
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
return
|
|
33
|
-
}, [
|
|
36
|
+
const m = () => o(i.offsetHeight);
|
|
37
|
+
m();
|
|
38
|
+
const x = new ResizeObserver(m);
|
|
39
|
+
return x.observe(i), () => x.disconnect();
|
|
40
|
+
}, [l]), /* @__PURE__ */ s(
|
|
34
41
|
"div",
|
|
35
42
|
{
|
|
36
|
-
className: `w-full h-screen flex flex-col overflow-hidden bg-[var(--malachite-card-sunken-background)] ${
|
|
37
|
-
style:
|
|
43
|
+
className: `w-full h-screen flex flex-col overflow-hidden bg-[var(--malachite-card-sunken-background)] ${S}`,
|
|
44
|
+
style: c ? { minWidth: `${c}px` } : void 0,
|
|
38
45
|
children: [
|
|
39
|
-
/* @__PURE__ */
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
46
|
+
/* @__PURE__ */ s(
|
|
47
|
+
"div",
|
|
48
|
+
{
|
|
49
|
+
className: `w-full shrink-0 flex items-center justify-between ${E[u]}`,
|
|
50
|
+
children: [
|
|
51
|
+
/* @__PURE__ */ s("div", { className: "flex items-center gap-[16px] min-w-0", children: [
|
|
52
|
+
p ? /* @__PURE__ */ e(
|
|
53
|
+
A,
|
|
54
|
+
{
|
|
55
|
+
variant: "outline",
|
|
56
|
+
size: "small",
|
|
57
|
+
iconOnly: !0,
|
|
58
|
+
icon: /* @__PURE__ */ e(R, { size: 14 }),
|
|
59
|
+
disabled: h,
|
|
60
|
+
onClick: f,
|
|
61
|
+
"aria-label": "Back",
|
|
62
|
+
className: "w-[var(--malachite-control-height-small,28px)] h-[var(--malachite-control-height-small,28px)] shrink-0"
|
|
63
|
+
}
|
|
64
|
+
) : d ? /* @__PURE__ */ e("span", { className: "w-[var(--malachite-control-height-small,28px)] h-[var(--malachite-control-height-small,28px)] shrink-0" }) : null,
|
|
65
|
+
v
|
|
66
|
+
] }),
|
|
67
|
+
/* @__PURE__ */ s("div", { className: "flex items-center gap-[16px]", children: [
|
|
68
|
+
w ?? null,
|
|
69
|
+
g ?? null
|
|
70
|
+
] })
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
),
|
|
74
|
+
r ? /* @__PURE__ */ e("div", { className: "w-full shrink-0 px-[12px] pt-[12px]", children: r }) : null,
|
|
75
|
+
t ? /* @__PURE__ */ e("div", { className: "w-full shrink-0 flex flex-col items-center px-6 pt-8", children: /* @__PURE__ */ e(
|
|
62
76
|
"div",
|
|
63
77
|
{
|
|
64
78
|
className: "w-full flex flex-col items-center gap-[24px]",
|
|
65
|
-
style: { maxWidth: `${
|
|
66
|
-
children:
|
|
79
|
+
style: { maxWidth: `${a}px` },
|
|
80
|
+
children: t
|
|
67
81
|
}
|
|
68
82
|
) }) : null,
|
|
69
|
-
/* @__PURE__ */
|
|
83
|
+
/* @__PURE__ */ s("div", { className: "relative flex-1 min-h-0", children: [
|
|
70
84
|
/* @__PURE__ */ e(
|
|
71
85
|
"div",
|
|
72
86
|
{
|
|
73
|
-
className: `absolute inset-0 overflow-y-auto flex flex-col items-center px-6 ${
|
|
87
|
+
className: `absolute inset-0 overflow-y-auto flex flex-col items-center px-6 ${b ? "justify-center" : "justify-start"}`,
|
|
74
88
|
style: {
|
|
75
89
|
// Reserve the overlaid footer's height plus a gap, so the last item
|
|
76
90
|
// clears the footer with breathing room (not flush against it, which
|
|
77
91
|
// reads as hidden content continuing underneath).
|
|
78
|
-
paddingBottom:
|
|
92
|
+
paddingBottom: l ? `${$ + 24}px` : "48px"
|
|
79
93
|
},
|
|
80
94
|
children: /* @__PURE__ */ e(
|
|
81
95
|
"div",
|
|
82
96
|
{
|
|
83
97
|
className: "w-full flex flex-col items-center gap-[40px]",
|
|
84
98
|
style: {
|
|
85
|
-
maxWidth: `${
|
|
99
|
+
maxWidth: `${a}px`,
|
|
86
100
|
// Top padding lives on the scrolling content — NOT the scrollport —
|
|
87
101
|
// so a `position: sticky` child pins flush to the top with no gap.
|
|
88
|
-
paddingTop:
|
|
102
|
+
paddingTop: t ? "32px" : "48px"
|
|
89
103
|
},
|
|
90
|
-
children:
|
|
104
|
+
children: k
|
|
91
105
|
}
|
|
92
106
|
)
|
|
93
107
|
}
|
|
94
108
|
),
|
|
95
|
-
|
|
109
|
+
l ? /* @__PURE__ */ e(
|
|
96
110
|
"div",
|
|
97
111
|
{
|
|
98
112
|
ref: n,
|
|
99
113
|
className: "absolute inset-x-0 bottom-0 z-20",
|
|
100
|
-
style:
|
|
101
|
-
children:
|
|
114
|
+
style: N ? B : void 0,
|
|
115
|
+
children: y === "content" ? /* @__PURE__ */ e("div", { className: "flex justify-center px-6 pt-4 pb-3", children: /* @__PURE__ */ e("div", { className: "w-full", style: { maxWidth: `${a}px` }, children: l }) }) : l
|
|
102
116
|
}
|
|
103
117
|
) : null
|
|
104
118
|
] })
|
|
@@ -107,7 +121,7 @@ const H = ({
|
|
|
107
121
|
);
|
|
108
122
|
};
|
|
109
123
|
export {
|
|
110
|
-
|
|
111
|
-
|
|
124
|
+
F as WizardLayout,
|
|
125
|
+
F as default
|
|
112
126
|
};
|
|
113
127
|
//# sourceMappingURL=WizardLayout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WizardLayout.js","sources":["../../src/components/WizardLayout.tsx"],"sourcesContent":["import React, { useLayoutEffect, useRef, useState } from 'react';\nimport Button from './Button';\nimport ArrowLeftIcon from './CustomIcons/ArrowLeftIcon';\nimport { GLASS_SURFACE_STYLE } from './glassSurface';\n\nexport interface WizardLayoutProps {\n /** Renders the outline back button in the top-left slot. */\n showBack?: boolean;\n onBack?: () => void;\n backDisabled?: boolean;\n /** Top-left slot beside the back button — e.g. a user avatar menu. */\n leading?: React.ReactNode;\n /** Right top-bar slot (sits just before `stepper`) — e.g. a theme toggle. */\n stepper?: React.ReactNode;\n /** Far-right top-bar slot — e.g. a theme toggle. */\n trailing?: React.ReactNode;\n /**\n * Pinned below the top bar and always visible while the content scrolls —\n * e.g. connection logos + a step title. Rendered in the same centred column\n * as the content (`contentWidth`).\n */\n header?: React.ReactNode;\n /** Pinned to the bottom of the screen — typically a <FooterNav /> or a primary CTA. */\n footer?: React.ReactNode;\n /**\n * Give the pinned footer a frosted-glass treatment (translucent background +\n * backdrop blur) so scrolling content shows through it. The footer already sits\n * above sticky body content, so it reads as glass over the scrolling list.\n */\n footerGlass?: boolean;\n /** Vertically centre the content (used for terminal/success screens). */\n center?: boolean;\n /** Max width of the centered content column. */\n contentWidth?: number;\n /** Minimum width of the whole layout, below which it scrolls horizontally. */\n minWidth?: number;\n children?: React.ReactNode;\n className?: string;\n}\n\nconst WizardLayout: React.FC<WizardLayoutProps> = ({\n showBack = false,\n onBack,\n backDisabled = false,\n leading,\n stepper,\n trailing,\n header,\n footer,\n footerGlass = false,\n center = false,\n contentWidth = 480,\n minWidth,\n children,\n className = '',\n}) => {\n // The footer overlays the bottom of the scroll area (so content can glass under\n // it). Measure it so the scroll content reserves matching bottom space and the\n // last item is never hidden behind it.\n const footerRef = useRef<HTMLDivElement>(null);\n const [footerHeight, setFooterHeight] = useState(0);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: re-run when the footer node mounts/unmounts so the observer attaches to the current element.\n useLayoutEffect(() => {\n const el = footerRef.current;\n if (!el) {\n setFooterHeight(0);\n return;\n }\n const update = () => setFooterHeight(el.offsetHeight);\n update();\n const observer = new ResizeObserver(update);\n observer.observe(el);\n return () => observer.disconnect();\n }, [footer]);\n\n return (\n <div\n className={`w-full h-screen flex flex-col overflow-hidden bg-[var(--malachite-card-sunken-background)] ${className}`}\n style={minWidth ? { minWidth: `${minWidth}px` } : undefined}\n >\n <div className=\"w-full shrink-0 flex items-center justify-between px-6 pt-4 min-h-[var(--malachite-control-height-small,28px)]\">\n <div className=\"flex items-center gap-[16px] min-w-0\">\n {showBack ? (\n <Button\n variant=\"outline\"\n size=\"small\"\n iconOnly\n icon={<ArrowLeftIcon size={14} />}\n disabled={backDisabled}\n onClick={onBack}\n aria-label=\"Back\"\n className=\"w-[var(--malachite-control-height-small,28px)] h-[var(--malachite-control-height-small,28px)] shrink-0\"\n />\n ) : (\n <span className=\"w-[var(--malachite-control-height-small,28px)] h-[var(--malachite-control-height-small,28px)] shrink-0\" />\n )}\n {leading}\n </div>\n <div className=\"flex items-center gap-[16px]\">\n {trailing ?? null}\n {stepper ?? null}\n </div>\n </div>\n\n {header ? (\n <div className=\"w-full shrink-0 flex flex-col items-center px-6 pt-8\">\n <div\n className=\"w-full flex flex-col items-center gap-[24px]\"\n style={{ maxWidth: `${contentWidth}px` }}\n >\n {header}\n </div>\n </div>\n ) : null}\n\n <div className=\"relative flex-1 min-h-0\">\n <div\n className={`absolute inset-0 overflow-y-auto flex flex-col items-center px-6 ${\n center ? 'justify-center' : 'justify-start'\n }`}\n style={{\n // Reserve the overlaid footer's height plus a gap, so the last item\n // clears the footer with breathing room (not flush against it, which\n // reads as hidden content continuing underneath).\n paddingBottom: footer ? `${footerHeight + 24}px` : '48px',\n }}\n >\n <div\n className=\"w-full flex flex-col items-center gap-[40px]\"\n style={{\n maxWidth: `${contentWidth}px`,\n // Top padding lives on the scrolling content — NOT the scrollport —\n // so a `position: sticky` child pins flush to the top with no gap.\n paddingTop: header ? '32px' : '48px',\n }}\n >\n {children}\n </div>\n </div>\n\n {footer ? (\n <div\n ref={footerRef}\n // z-20 keeps the pinned footer above sticky body content (e.g. a\n // sticky Accordion header at z-10) so it can't paint over the footer.\n className=\"absolute inset-x-0 bottom-0 z-20\"\n style={footerGlass ? GLASS_SURFACE_STYLE : undefined}\n >\n {footer}\n </div>\n ) : null}\n </div>\n </div>\n );\n};\n\nexport default WizardLayout;\nexport { WizardLayout };\n"],"names":["WizardLayout","showBack","onBack","backDisabled","leading","stepper","trailing","header","footer","footerGlass","center","contentWidth","minWidth","children","className","footerRef","useRef","footerHeight","setFooterHeight","useState","useLayoutEffect","el","update","observer","jsxs","jsx","Button","ArrowLeftIcon","GLASS_SURFACE_STYLE"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WizardLayout.js","sources":["../../src/components/WizardLayout.tsx"],"sourcesContent":["import React, { useLayoutEffect, useRef, useState } from 'react';\nimport Button from './Button';\nimport ArrowLeftIcon from './CustomIcons/ArrowLeftIcon';\nimport { GLASS_SURFACE_STYLE } from './glassSurface';\n\nexport interface WizardLayoutProps {\n /** Renders the outline back button in the top-left slot. */\n showBack?: boolean;\n onBack?: () => void;\n backDisabled?: boolean;\n /** `false` drops the hidden back button's square, so `leading` sits at the same inset as `trailing`. */\n reserveBack?: boolean;\n /** `large`: a 60px bar with 28px insets (52px and 16px below 640px), items centred. */\n topBarSize?: 'default' | 'large';\n /** Top-left slot beside the back button — e.g. a user avatar menu. */\n leading?: React.ReactNode;\n /** Right top-bar slot (sits just before `stepper`) — e.g. a theme toggle. */\n stepper?: React.ReactNode;\n /** Far-right top-bar slot — e.g. a theme toggle. */\n trailing?: React.ReactNode;\n /** A page-wide notice under the top bar, above `header`. */\n banner?: React.ReactNode;\n /**\n * Pinned below the top bar and always visible while the content scrolls —\n * e.g. connection logos + a step title. Rendered in the same centred column\n * as the content (`contentWidth`).\n */\n header?: React.ReactNode;\n /** Pinned to the bottom of the screen — typically a <FooterNav /> or a primary CTA. */\n footer?: React.ReactNode;\n /**\n * Give the pinned footer a frosted-glass treatment (translucent background +\n * backdrop blur) so scrolling content shows through it. The footer already sits\n * above sticky body content, so it reads as glass over the scrolling list.\n */\n footerGlass?: boolean;\n /** `content` holds the footer to the content column, so a full-width action lines up with the list. */\n footerAlign?: 'full' | 'content';\n /** Vertically centre the content (used for terminal/success screens). */\n center?: boolean;\n /** Max width of the centered content column. */\n contentWidth?: number;\n /** Minimum width of the whole layout, below which it scrolls horizontally. */\n minWidth?: number;\n children?: React.ReactNode;\n className?: string;\n}\n\nconst TOP_BAR_CLASSES: Record<NonNullable<WizardLayoutProps['topBarSize']>, string> = {\n default: 'px-6 pt-4 min-h-[var(--malachite-control-height-small,28px)]',\n large: 'h-[60px] px-[28px] max-sm:h-[52px] max-sm:px-[16px]',\n};\n\nconst WizardLayout: React.FC<WizardLayoutProps> = ({\n showBack = false,\n onBack,\n backDisabled = false,\n reserveBack = true,\n topBarSize = 'default',\n leading,\n stepper,\n trailing,\n banner,\n header,\n footer,\n footerGlass = false,\n footerAlign = 'full',\n center = false,\n contentWidth = 480,\n minWidth,\n children,\n className = '',\n}) => {\n // The footer overlays the bottom of the scroll area (so content can glass under\n // it). Measure it so the scroll content reserves matching bottom space and the\n // last item is never hidden behind it.\n const footerRef = useRef<HTMLDivElement>(null);\n const [footerHeight, setFooterHeight] = useState(0);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: re-run when the footer node mounts/unmounts so the observer attaches to the current element.\n useLayoutEffect(() => {\n const el = footerRef.current;\n if (!el) {\n setFooterHeight(0);\n return;\n }\n const update = () => setFooterHeight(el.offsetHeight);\n update();\n const observer = new ResizeObserver(update);\n observer.observe(el);\n return () => observer.disconnect();\n }, [footer]);\n\n return (\n <div\n className={`w-full h-screen flex flex-col overflow-hidden bg-[var(--malachite-card-sunken-background)] ${className}`}\n style={minWidth ? { minWidth: `${minWidth}px` } : undefined}\n >\n <div\n className={`w-full shrink-0 flex items-center justify-between ${TOP_BAR_CLASSES[topBarSize]}`}\n >\n <div className=\"flex items-center gap-[16px] min-w-0\">\n {showBack ? (\n <Button\n variant=\"outline\"\n size=\"small\"\n iconOnly\n icon={<ArrowLeftIcon size={14} />}\n disabled={backDisabled}\n onClick={onBack}\n aria-label=\"Back\"\n className=\"w-[var(--malachite-control-height-small,28px)] h-[var(--malachite-control-height-small,28px)] shrink-0\"\n />\n ) : reserveBack ? (\n <span className=\"w-[var(--malachite-control-height-small,28px)] h-[var(--malachite-control-height-small,28px)] shrink-0\" />\n ) : null}\n {leading}\n </div>\n <div className=\"flex items-center gap-[16px]\">\n {trailing ?? null}\n {stepper ?? null}\n </div>\n </div>\n\n {banner ? <div className=\"w-full shrink-0 px-[12px] pt-[12px]\">{banner}</div> : null}\n\n {header ? (\n <div className=\"w-full shrink-0 flex flex-col items-center px-6 pt-8\">\n <div\n className=\"w-full flex flex-col items-center gap-[24px]\"\n style={{ maxWidth: `${contentWidth}px` }}\n >\n {header}\n </div>\n </div>\n ) : null}\n\n <div className=\"relative flex-1 min-h-0\">\n <div\n className={`absolute inset-0 overflow-y-auto flex flex-col items-center px-6 ${\n center ? 'justify-center' : 'justify-start'\n }`}\n style={{\n // Reserve the overlaid footer's height plus a gap, so the last item\n // clears the footer with breathing room (not flush against it, which\n // reads as hidden content continuing underneath).\n paddingBottom: footer ? `${footerHeight + 24}px` : '48px',\n }}\n >\n <div\n className=\"w-full flex flex-col items-center gap-[40px]\"\n style={{\n maxWidth: `${contentWidth}px`,\n // Top padding lives on the scrolling content — NOT the scrollport —\n // so a `position: sticky` child pins flush to the top with no gap.\n paddingTop: header ? '32px' : '48px',\n }}\n >\n {children}\n </div>\n </div>\n\n {footer ? (\n <div\n ref={footerRef}\n // z-20 keeps the pinned footer above sticky body content (e.g. a\n // sticky Accordion header at z-10) so it can't paint over the footer.\n className=\"absolute inset-x-0 bottom-0 z-20\"\n style={footerGlass ? GLASS_SURFACE_STYLE : undefined}\n >\n {footerAlign === 'content' ? (\n <div className=\"flex justify-center px-6 pt-4 pb-3\">\n <div className=\"w-full\" style={{ maxWidth: `${contentWidth}px` }}>\n {footer}\n </div>\n </div>\n ) : (\n footer\n )}\n </div>\n ) : null}\n </div>\n </div>\n );\n};\n\nexport default WizardLayout;\nexport { WizardLayout };\n"],"names":["TOP_BAR_CLASSES","WizardLayout","showBack","onBack","backDisabled","reserveBack","topBarSize","leading","stepper","trailing","banner","header","footer","footerGlass","footerAlign","center","contentWidth","minWidth","children","className","footerRef","useRef","footerHeight","setFooterHeight","useState","useLayoutEffect","el","update","observer","jsxs","jsx","Button","ArrowLeftIcon","GLASS_SURFACE_STYLE"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,11 @@ declare interface AccordionBaseProps {
|
|
|
51
51
|
* be interactive (e.g. a Checkbox) without nesting a button inside a button.
|
|
52
52
|
*/
|
|
53
53
|
trailing?: default_2.ReactNode;
|
|
54
|
+
/** Before the title, outside the toggle button. */
|
|
55
|
+
leading?: default_2.ReactNode;
|
|
56
|
+
arrowPosition?: 'start' | 'end';
|
|
57
|
+
/** `false` keeps an open row on the card ground. */
|
|
58
|
+
highlightExpanded?: boolean;
|
|
54
59
|
defaultExpanded?: boolean;
|
|
55
60
|
isExpanded?: boolean;
|
|
56
61
|
onToggle?: (expanded: boolean) => void;
|
|
@@ -180,6 +185,8 @@ export declare const AdvancedLogsIcon: React.FC<IconProps_4>;
|
|
|
180
185
|
|
|
181
186
|
export declare const Alert: default_2.FC<AlertProps>;
|
|
182
187
|
|
|
188
|
+
export declare type AlertLayout = 'inline' | 'banner';
|
|
189
|
+
|
|
183
190
|
declare interface AlertProps {
|
|
184
191
|
type?: AlertType;
|
|
185
192
|
message: string;
|
|
@@ -199,6 +206,10 @@ declare interface AlertProps {
|
|
|
199
206
|
live?: boolean;
|
|
200
207
|
/** Routes root-relative links in `message` through the app's router; see `MarkdownBlock`. */
|
|
201
208
|
renderLink?: RenderLink;
|
|
209
|
+
/** `banner`: a 48px page-wide band. Applies only without `children`. */
|
|
210
|
+
layout?: AlertLayout;
|
|
211
|
+
/** A bold sentence the message runs on from. Plain text, not markdown. */
|
|
212
|
+
lead?: string;
|
|
202
213
|
}
|
|
203
214
|
|
|
204
215
|
export declare type AlertType = 'info' | 'success' | 'error' | 'warning' | 'assistant';
|
|
@@ -402,10 +413,14 @@ declare interface ButtonProps extends default_2.ButtonHTMLAttributes<HTMLButtonE
|
|
|
402
413
|
contentAlign?: 'center' | 'start';
|
|
403
414
|
/** Fills the container's width. */
|
|
404
415
|
flexGrow?: boolean;
|
|
416
|
+
/** `wide` holds a 120px floor for a primary action. */
|
|
417
|
+
width?: 'auto' | 'wide';
|
|
405
418
|
fill?: boolean;
|
|
406
419
|
tooltip?: string;
|
|
407
420
|
tooltipPlacement?: 'top' | 'bottom' | 'left' | 'right';
|
|
408
421
|
iconOnly?: boolean;
|
|
422
|
+
/** Pulls a borderless button out by its own padding, so its label lines up with the text around it. */
|
|
423
|
+
flush?: boolean;
|
|
409
424
|
children?: default_2.ReactNode;
|
|
410
425
|
onClick?: default_2.MouseEventHandler<HTMLButtonElement & HTMLAnchorElement>;
|
|
411
426
|
/** Renders the button as a real anchor, so a link action is never an <a> nested in a <button>. */
|
|
@@ -430,7 +445,9 @@ export declare type ButtonVariant = 'filled' | 'outline'
|
|
|
430
445
|
* acts on what it produced. Provenance, not a severity: it says who is being asked, not
|
|
431
446
|
* that anything is wrong.
|
|
432
447
|
*/
|
|
433
|
-
| 'assistant' | 'destructive' | 'success' | 'warning' | 'error' | 'ghost'
|
|
448
|
+
| 'assistant' | 'destructive' | 'success' | 'warning' | 'error' | 'ghost'
|
|
449
|
+
/** Text only, in the accent colour, for a secondary action beside a primary one. */
|
|
450
|
+
| 'quiet' | 'no-style';
|
|
434
451
|
|
|
435
452
|
export declare const Card: default_2.FC<CardProps>;
|
|
436
453
|
|
|
@@ -1650,6 +1667,7 @@ declare interface EllipsisTextProps {
|
|
|
1650
1667
|
maxWidth?: string;
|
|
1651
1668
|
color?: TextColor;
|
|
1652
1669
|
size?: FontSize;
|
|
1670
|
+
fontWeight?: FontWeight;
|
|
1653
1671
|
/**
|
|
1654
1672
|
* Show `tooltip` only when the text is actually cut off. Opt-in, because `tooltip` is any
|
|
1655
1673
|
* node: a caller repeating the label wants this, and one supplying something the label does
|
|
@@ -3565,6 +3583,8 @@ export declare interface ModalProps {
|
|
|
3565
3583
|
closeOnOverlayClick?: boolean;
|
|
3566
3584
|
/** Whether the body gets default padding. Default: true. */
|
|
3567
3585
|
bodyPadding?: boolean;
|
|
3586
|
+
/** `tall`: 600px, or the viewport less 160px, for content that sizes to its box. */
|
|
3587
|
+
bodyHeight?: 'auto' | 'tall';
|
|
3568
3588
|
/** Full-width Alert bands at the top of the body, above `children`, in order. Unaffected by
|
|
3569
3589
|
* `bodyPadding`, and announced ahead of the dialog's description. The message is markdown. */
|
|
3570
3590
|
callouts?: {
|
|
@@ -4027,6 +4047,8 @@ declare type PopoverFocusSource = {
|
|
|
4027
4047
|
export declare interface PopoverHeaderProps {
|
|
4028
4048
|
title: string;
|
|
4029
4049
|
action?: default_2.ReactNode;
|
|
4050
|
+
/** `false` drops the rule and sits the header 4px over the list. */
|
|
4051
|
+
divider?: boolean;
|
|
4030
4052
|
}
|
|
4031
4053
|
|
|
4032
4054
|
export declare type PopoverInitialFocus = default_2.RefObject<HTMLElement | null> | (() => HTMLElement | null | undefined);
|
|
@@ -4310,6 +4332,7 @@ export declare interface SearchProps {
|
|
|
4310
4332
|
/** 'large' (42px) for form inputs; 'medium' (32px) for toolbars; 'small' (28px) in a table. */
|
|
4311
4333
|
size?: SearchSize;
|
|
4312
4334
|
variant?: SearchVariant;
|
|
4335
|
+
textSize?: SearchTextSize;
|
|
4313
4336
|
disabled?: boolean;
|
|
4314
4337
|
autoFocus?: boolean;
|
|
4315
4338
|
className?: string;
|
|
@@ -4331,6 +4354,9 @@ export declare interface SearchProps {
|
|
|
4331
4354
|
|
|
4332
4355
|
export declare type SearchSize = 'small' | 'medium' | 'large';
|
|
4333
4356
|
|
|
4357
|
+
/** `body` is the 14px body step at any size. */
|
|
4358
|
+
export declare type SearchTextSize = 'control' | 'body';
|
|
4359
|
+
|
|
4334
4360
|
export declare const SearchTrigger: default_2.ForwardRefExoticComponent<SearchTriggerProps & default_2.RefAttributes<HTMLButtonElement>>;
|
|
4335
4361
|
|
|
4336
4362
|
export declare interface SearchTriggerProps extends Omit<default_2.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'className' | 'style' | 'color' | 'type'> {
|
|
@@ -4663,12 +4689,15 @@ export declare interface SidePanelProps {
|
|
|
4663
4689
|
/** Dismiss handler — close button, ESC, or overlay click. */
|
|
4664
4690
|
onClose: () => void;
|
|
4665
4691
|
title: default_2.ReactNode;
|
|
4666
|
-
/** Secondary text, inline after the title. */
|
|
4667
4692
|
subtitle?: default_2.ReactNode;
|
|
4693
|
+
/** `below` stacks the subtitle under the title, so neither truncates the other. */
|
|
4694
|
+
subtitlePlacement?: 'inline' | 'below';
|
|
4668
4695
|
/** Content at the end of the title row, after the subtitle (e.g. a status tag). */
|
|
4669
4696
|
titleExtra?: default_2.ReactNode;
|
|
4670
4697
|
/** Block paragraph below the title row, spanning the header width. Announced as the panel's description. */
|
|
4671
4698
|
description?: default_2.ReactNode;
|
|
4699
|
+
/** Pinned between the header and the scrolling body. */
|
|
4700
|
+
toolbar?: default_2.ReactNode;
|
|
4672
4701
|
/** Divider under the header. Default: false. */
|
|
4673
4702
|
headerDivider?: boolean;
|
|
4674
4703
|
/** Leading header slot, typically a logo or icon. */
|
|
@@ -4853,6 +4882,26 @@ export declare interface StatusBadgeProps {
|
|
|
4853
4882
|
|
|
4854
4883
|
export declare type StatusBadgeType = 'success' | 'error' | 'warning' | 'info';
|
|
4855
4884
|
|
|
4885
|
+
export declare const StatusPill: default_2.FC<StatusPillProps>;
|
|
4886
|
+
|
|
4887
|
+
export declare interface StatusPillProps {
|
|
4888
|
+
label: string;
|
|
4889
|
+
/** Set in the mono face after a `·`. */
|
|
4890
|
+
detail?: string;
|
|
4891
|
+
tone?: StatusPillTone;
|
|
4892
|
+
icon?: default_2.ReactNode;
|
|
4893
|
+
busy?: boolean;
|
|
4894
|
+
/** Makes it a `status` live region. Off by default, as on `Alert`. */
|
|
4895
|
+
live?: boolean;
|
|
4896
|
+
/** Names the live region; only applies with `live`. */
|
|
4897
|
+
'aria-label'?: string;
|
|
4898
|
+
/** Only applies with `live`. */
|
|
4899
|
+
'aria-labelledby'?: string;
|
|
4900
|
+
className?: string;
|
|
4901
|
+
}
|
|
4902
|
+
|
|
4903
|
+
export declare type StatusPillTone = 'success' | 'neutral' | 'warning' | 'error';
|
|
4904
|
+
|
|
4856
4905
|
export declare const StepCurrentIcon: React.FC<IconProps_104>;
|
|
4857
4906
|
|
|
4858
4907
|
export declare const Stepper: default_2.FC<StepperProps>;
|
|
@@ -4985,6 +5034,8 @@ declare interface SurfaceRowChromeProps {
|
|
|
4985
5034
|
* an outcome, where the result belongs to the whole line rather than to one cell in it.
|
|
4986
5035
|
*/
|
|
4987
5036
|
tone?: 'default' | 'muted' | 'success' | 'error';
|
|
5037
|
+
/** `compact` is an 8px by 16px inset the row owns. */
|
|
5038
|
+
inset?: 'none' | 'compact';
|
|
4988
5039
|
className?: string;
|
|
4989
5040
|
style?: default_2.CSSProperties;
|
|
4990
5041
|
}
|
|
@@ -5323,6 +5374,7 @@ export declare interface TextProps {
|
|
|
5323
5374
|
children: default_2.ReactNode;
|
|
5324
5375
|
tooltip?: string;
|
|
5325
5376
|
textAlign?: 'left' | 'center' | 'right' | 'justify';
|
|
5377
|
+
wrap?: boolean;
|
|
5326
5378
|
/** The element it renders, for a heading or paragraph that keeps Text's look. */
|
|
5327
5379
|
as?: TextElement;
|
|
5328
5380
|
className?: string;
|
|
@@ -5454,6 +5506,9 @@ export declare interface ToolbarProps {
|
|
|
5454
5506
|
* the content it pins over — the consumer then owns the gutter. */
|
|
5455
5507
|
padding?: 'none' | 'compact' | 'default';
|
|
5456
5508
|
layout?: 'plain' | 'filters';
|
|
5509
|
+
/** `page` paints the sunken page ground, for a bar that sits above a card. */
|
|
5510
|
+
surface?: 'card' | 'page';
|
|
5511
|
+
sticky?: boolean;
|
|
5457
5512
|
className?: string;
|
|
5458
5513
|
style?: default_2.CSSProperties;
|
|
5459
5514
|
}
|
|
@@ -5583,12 +5638,18 @@ export declare interface WizardLayoutProps {
|
|
|
5583
5638
|
showBack?: boolean;
|
|
5584
5639
|
onBack?: () => void;
|
|
5585
5640
|
backDisabled?: boolean;
|
|
5641
|
+
/** `false` drops the hidden back button's square, so `leading` sits at the same inset as `trailing`. */
|
|
5642
|
+
reserveBack?: boolean;
|
|
5643
|
+
/** `large`: a 60px bar with 28px insets (52px and 16px below 640px), items centred. */
|
|
5644
|
+
topBarSize?: 'default' | 'large';
|
|
5586
5645
|
/** Top-left slot beside the back button — e.g. a user avatar menu. */
|
|
5587
5646
|
leading?: default_2.ReactNode;
|
|
5588
5647
|
/** Right top-bar slot (sits just before `stepper`) — e.g. a theme toggle. */
|
|
5589
5648
|
stepper?: default_2.ReactNode;
|
|
5590
5649
|
/** Far-right top-bar slot — e.g. a theme toggle. */
|
|
5591
5650
|
trailing?: default_2.ReactNode;
|
|
5651
|
+
/** A page-wide notice under the top bar, above `header`. */
|
|
5652
|
+
banner?: default_2.ReactNode;
|
|
5592
5653
|
/**
|
|
5593
5654
|
* Pinned below the top bar and always visible while the content scrolls —
|
|
5594
5655
|
* e.g. connection logos + a step title. Rendered in the same centred column
|
|
@@ -5603,6 +5664,8 @@ export declare interface WizardLayoutProps {
|
|
|
5603
5664
|
* above sticky body content, so it reads as glass over the scrolling list.
|
|
5604
5665
|
*/
|
|
5605
5666
|
footerGlass?: boolean;
|
|
5667
|
+
/** `content` holds the footer to the content column, so a full-width action lines up with the list. */
|
|
5668
|
+
footerAlign?: 'full' | 'content';
|
|
5606
5669
|
/** Vertically centre the content (used for terminal/success screens). */
|
|
5607
5670
|
center?: boolean;
|
|
5608
5671
|
/** Max width of the centered content column. */
|