@stackone/malachite 2.67.0 → 2.68.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 +1 -1
- package/dist/components/Popover.js +59 -56
- package/dist/components/Popover.js.map +1 -1
- package/dist/components/PopoverParts.js +88 -41
- package/dist/components/PopoverParts.js.map +1 -1
- package/dist/index.d.ts +29 -0
- package/dist/tailwind.css.js +1 -1
- package/package.json +1 -1
|
@@ -1,68 +1,112 @@
|
|
|
1
|
-
import { jsx as n, jsxs as u } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { jsx as n, jsxs as u, Fragment as f } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as v, useContext as x, useRef as h, useLayoutEffect as b } from "react";
|
|
3
|
+
import { Button as g } from "./Button.js";
|
|
4
|
+
import T from "./Tooltip.js";
|
|
5
|
+
import { BORDER as c, NO_SCROLLBAR as N } from "./chromeStyles.js";
|
|
6
|
+
import { FOCUS_RING_INSET as y } from "./focusRing.js";
|
|
7
|
+
import { isPlainClick as S } from "./linkClick.js";
|
|
7
8
|
import { PopoverShownContext as w } from "./popoverTree.js";
|
|
8
|
-
import { safeHref as
|
|
9
|
-
const
|
|
9
|
+
import { safeHref as R } from "./safeHref.js";
|
|
10
|
+
const F = ({ title: e, action: t }) => /* @__PURE__ */ u(
|
|
10
11
|
"div",
|
|
11
12
|
{
|
|
12
|
-
className: `flex items-center justify-between border-0 border-b border-solid ${
|
|
13
|
+
className: `flex items-center justify-between border-0 border-b border-solid ${c} px-5 py-4 text-[12px] leading-[15px] font-normal text-[var(--malachite-text-dimmed,rgb(161,161,161))]`,
|
|
13
14
|
children: [
|
|
14
15
|
/* @__PURE__ */ n("span", { children: e }),
|
|
15
16
|
t
|
|
16
17
|
]
|
|
17
18
|
}
|
|
18
|
-
),
|
|
19
|
-
const t = e.querySelector(
|
|
19
|
+
), E = '[aria-current]:not([aria-current="false"]):not([aria-current=""]), [aria-selected="true"], [role="radio"][aria-checked="true"]', P = ["aria-current", "aria-selected", "aria-checked"], m = (e) => {
|
|
20
|
+
const t = e.querySelector(E);
|
|
20
21
|
if (!t)
|
|
21
22
|
return !1;
|
|
22
|
-
const
|
|
23
|
-
return a < e.scrollTop ? e.scrollTop = a :
|
|
24
|
-
},
|
|
25
|
-
const
|
|
23
|
+
const r = e.getBoundingClientRect().top + e.clientTop, { top: l, bottom: o } = t.getBoundingClientRect(), a = l - r + e.scrollTop, i = o - r + e.scrollTop;
|
|
24
|
+
return a < e.scrollTop ? e.scrollTop = a : i > e.scrollTop + e.clientHeight && (e.scrollTop = i - e.clientHeight), !0;
|
|
25
|
+
}, U = ({ children: e, scrollToSelected: t = !1 }) => {
|
|
26
|
+
const r = x(w), l = h(null);
|
|
26
27
|
return b(() => {
|
|
27
|
-
const
|
|
28
|
-
if (!t || !
|
|
28
|
+
const o = l.current;
|
|
29
|
+
if (!t || !r || !o || m(o))
|
|
29
30
|
return;
|
|
30
31
|
const a = new MutationObserver(() => {
|
|
31
|
-
|
|
32
|
+
m(o) && a.disconnect();
|
|
32
33
|
});
|
|
33
|
-
return a.observe(
|
|
34
|
+
return a.observe(o, {
|
|
34
35
|
childList: !0,
|
|
35
36
|
subtree: !0,
|
|
36
37
|
attributes: !0,
|
|
37
|
-
attributeFilter:
|
|
38
|
+
attributeFilter: P
|
|
38
39
|
}), () => a.disconnect();
|
|
39
|
-
}, [t,
|
|
40
|
+
}, [t, r]), /* @__PURE__ */ n(
|
|
40
41
|
"div",
|
|
41
42
|
{
|
|
42
|
-
ref:
|
|
43
|
-
className: `flex max-h-80 flex-col gap-[2px] overflow-y-auto p-2 ${
|
|
43
|
+
ref: l,
|
|
44
|
+
className: `flex max-h-80 flex-col gap-[2px] overflow-y-auto p-2 ${N}`,
|
|
44
45
|
children: e
|
|
45
46
|
}
|
|
46
47
|
);
|
|
47
|
-
},
|
|
48
|
-
({ children: e }, t) => /* @__PURE__ */ n("div", { ref: t, className: `border-0 border-t border-solid ${
|
|
48
|
+
}, C = v(
|
|
49
|
+
({ children: e }, t) => /* @__PURE__ */ n("div", { ref: t, className: `border-0 border-t border-solid ${c} p-2`, children: e })
|
|
49
50
|
);
|
|
50
|
-
|
|
51
|
-
const
|
|
51
|
+
C.displayName = "Popover.Section";
|
|
52
|
+
const M = ({ children: e }) => /* @__PURE__ */ n("div", { className: "px-3 py-2 text-[length:var(--malachite-font-size-small,13px)] text-[var(--malachite-text-dimmed,rgb(161,161,161))] select-none", children: e }), q = ({ children: e }) => /* @__PURE__ */ n("div", { className: "px-2 pt-2", children: e }), G = ({ children: e }) => /* @__PURE__ */ n(
|
|
53
|
+
"div",
|
|
54
|
+
{
|
|
55
|
+
className: `border-0 border-t border-solid ${c} px-5 py-3 text-[length:var(--malachite-font-size-xsmall,11px)] leading-4 text-[var(--malachite-text-secondary,rgb(123,123,123))]`,
|
|
56
|
+
children: e
|
|
57
|
+
}
|
|
58
|
+
), O = {
|
|
59
|
+
default: "text-[var(--malachite-text-secondary,rgb(123,123,123))]",
|
|
60
|
+
error: "text-[var(--malachite-text-error,rgb(237,53,54))]"
|
|
61
|
+
}, _ = (e) => e != null && e !== !1 && e !== "", $ = v(
|
|
62
|
+
({ message: e, tone: t = "default", action: r, focusable: l = !1 }, o) => {
|
|
63
|
+
const a = _(e);
|
|
64
|
+
return /* @__PURE__ */ u(f, { children: [
|
|
65
|
+
/* @__PURE__ */ n(
|
|
66
|
+
"div",
|
|
67
|
+
{
|
|
68
|
+
ref: o,
|
|
69
|
+
role: "status",
|
|
70
|
+
tabIndex: l ? -1 : void 0,
|
|
71
|
+
className: a ? "outline-none" : "sr-only",
|
|
72
|
+
children: a && /* @__PURE__ */ n(
|
|
73
|
+
"div",
|
|
74
|
+
{
|
|
75
|
+
className: `px-3 py-2 text-[length:var(--malachite-font-size-small,13px)] ${O[t]}`,
|
|
76
|
+
children: e
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
a && r && /* @__PURE__ */ n("div", { className: "px-3 pb-2", children: /* @__PURE__ */ n(
|
|
82
|
+
g,
|
|
83
|
+
{
|
|
84
|
+
variant: "outline",
|
|
85
|
+
size: "small",
|
|
86
|
+
loading: r.pending,
|
|
87
|
+
onClick: r.onClick,
|
|
88
|
+
children: r.label
|
|
89
|
+
}
|
|
90
|
+
) })
|
|
91
|
+
] });
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
$.displayName = "Popover.Status";
|
|
95
|
+
const V = ({
|
|
52
96
|
icon: e,
|
|
53
97
|
"aria-label": t,
|
|
54
|
-
onClick:
|
|
55
|
-
href:
|
|
56
|
-
disabled:
|
|
98
|
+
onClick: r,
|
|
99
|
+
href: l,
|
|
100
|
+
disabled: o = !1,
|
|
57
101
|
tooltip: a
|
|
58
102
|
}) => {
|
|
59
|
-
const
|
|
103
|
+
const i = o ? void 0 : R(l), s = `m-0 inline-flex size-5 items-center justify-center rounded-[var(--malachite-radius-sm,4px)] border-0 bg-transparent p-0 transition-colors duration-150 [&_svg]:size-3! ${o ? "cursor-not-allowed text-[var(--malachite-text-placeholder,rgb(187,187,187))] opacity-50" : "cursor-pointer text-[var(--malachite-text-placeholder,rgb(187,187,187))] hover:bg-[var(--malachite-pillbutton-background,rgb(241,241,241))] hover:text-[var(--malachite-text-secondary,rgb(123,123,123))]"} ${y}`, d = i !== void 0 ? /* @__PURE__ */ n(
|
|
60
104
|
"a",
|
|
61
105
|
{
|
|
62
|
-
href:
|
|
106
|
+
href: i,
|
|
63
107
|
"aria-label": t,
|
|
64
108
|
onClick: (p) => {
|
|
65
|
-
|
|
109
|
+
S(p) && r && (p.preventDefault(), r());
|
|
66
110
|
},
|
|
67
111
|
className: `no-underline ${s}`,
|
|
68
112
|
children: e
|
|
@@ -72,19 +116,22 @@ const H = ({ children: e }) => /* @__PURE__ */ n("div", { className: "px-3 py-2
|
|
|
72
116
|
{
|
|
73
117
|
type: "button",
|
|
74
118
|
"aria-label": t,
|
|
75
|
-
"aria-disabled":
|
|
76
|
-
onClick:
|
|
119
|
+
"aria-disabled": o || void 0,
|
|
120
|
+
onClick: o ? void 0 : r,
|
|
77
121
|
className: s,
|
|
78
122
|
children: e
|
|
79
123
|
}
|
|
80
124
|
);
|
|
81
|
-
return a ? /* @__PURE__ */ n(
|
|
125
|
+
return a ? /* @__PURE__ */ n(T, { text: a, children: d }) : d;
|
|
82
126
|
};
|
|
83
127
|
export {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
128
|
+
V as PopoverAction,
|
|
129
|
+
M as PopoverEmpty,
|
|
130
|
+
F as PopoverHeader,
|
|
131
|
+
U as PopoverList,
|
|
132
|
+
G as PopoverNote,
|
|
133
|
+
q as PopoverSearch,
|
|
134
|
+
C as PopoverSection,
|
|
135
|
+
$ as PopoverStatus
|
|
89
136
|
};
|
|
90
137
|
//# sourceMappingURL=PopoverParts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PopoverParts.js","sources":["../../src/components/PopoverParts.tsx"],"sourcesContent":["import React, { forwardRef, useContext, useLayoutEffect, useRef } from 'react';\nimport Tooltip from './Tooltip';\nimport { BORDER, NO_SCROLLBAR } from './chromeStyles';\nimport { FOCUS_RING_INSET } from './focusRing';\nimport { isPlainClick } from './linkClick';\nimport { PopoverShownContext } from './popoverTree';\nimport { safeHref } from './safeHref';\n\nexport interface PopoverHeaderProps {\n title: string;\n action?: React.ReactNode;\n}\n\nexport const PopoverHeader: React.FC<PopoverHeaderProps> = ({ title, action }) => (\n <div\n className={`flex items-center justify-between border-0 border-b border-solid ${BORDER} px-5 py-4 text-[12px] leading-[15px] font-normal text-[var(--malachite-text-dimmed,rgb(161,161,161))]`}\n >\n <span>{title}</span>\n {action}\n </div>\n);\n\nconst SELECTED_ROW =\n '[aria-current]:not([aria-current=\"false\"]):not([aria-current=\"\"]), [aria-selected=\"true\"], [role=\"radio\"][aria-checked=\"true\"]';\nconst SELECTION_ATTRIBUTES = ['aria-current', 'aria-selected', 'aria-checked'];\n\n// Not `scrollIntoView`: that also scrolls every scrollable ancestor, the page included.\nconst scrollSelectedRowIntoView = (list: HTMLElement): boolean => {\n const row = list.querySelector<HTMLElement>(SELECTED_ROW);\n if (!row) {\n return false;\n }\n const listTop = list.getBoundingClientRect().top + list.clientTop;\n const { top, bottom } = row.getBoundingClientRect();\n const rowTop = top - listTop + list.scrollTop;\n const rowBottom = bottom - listTop + list.scrollTop;\n if (rowTop < list.scrollTop) {\n list.scrollTop = rowTop;\n } else if (rowBottom > list.scrollTop + list.clientHeight) {\n list.scrollTop = rowBottom - list.clientHeight;\n }\n return true;\n};\n\nexport interface PopoverListProps {\n children: React.ReactNode;\n /**\n * Scrolls the list to its selected row (`aria-current`, `aria-selected` or a checked radio)\n * each time the popover is shown, once that row mounts. Only the list scrolls.\n */\n scrollToSelected?: boolean;\n}\n\nexport const PopoverList: React.FC<PopoverListProps> = ({ children, scrollToSelected = false }) => {\n const shown = useContext(PopoverShownContext);\n const listRef = useRef<HTMLDivElement>(null);\n\n // Before paint, so a shown panel never draws a frame at the top and then jumps.\n useLayoutEffect(() => {\n const list = listRef.current;\n if (!scrollToSelected || !shown || !list || scrollSelectedRowIntoView(list)) {\n return;\n }\n const observer = new MutationObserver(() => {\n if (scrollSelectedRowIntoView(list)) {\n observer.disconnect();\n }\n });\n observer.observe(list, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: SELECTION_ATTRIBUTES,\n });\n return () => observer.disconnect();\n }, [scrollToSelected, shown]);\n\n return (\n <div\n ref={listRef}\n className={`flex max-h-80 flex-col gap-[2px] overflow-y-auto p-2 ${NO_SCROLLBAR}`}\n >\n {children}\n </div>\n );\n};\n\nexport const PopoverSection = forwardRef<HTMLDivElement, { children: React.ReactNode }>(\n ({ children }, ref) => (\n <div ref={ref} className={`border-0 border-t border-solid ${BORDER} p-2`}>\n {children}\n </div>\n ),\n);\nPopoverSection.displayName = 'Popover.Section';\n\nexport const PopoverEmpty: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <div className=\"px-3 py-2 text-[length:var(--malachite-font-size-small,13px)] text-[var(--malachite-text-dimmed,rgb(161,161,161))] select-none\">\n {children}\n </div>\n);\n\nexport interface PopoverActionProps {\n icon: React.ReactNode;\n 'aria-label': string;\n onClick?: () => void;\n /** Renders a link; a plain click runs `onClick` instead of following it, when one is given. */\n href?: string;\n disabled?: boolean;\n tooltip?: string;\n}\n\nexport const PopoverAction: React.FC<PopoverActionProps> = ({\n icon,\n 'aria-label': ariaLabel,\n onClick,\n href: rawHref,\n disabled = false,\n tooltip,\n}) => {\n const href = disabled ? undefined : safeHref(rawHref);\n const className = `m-0 inline-flex size-5 items-center justify-center rounded-[var(--malachite-radius-sm,4px)] border-0 bg-transparent p-0 transition-colors duration-150 [&_svg]:size-3! ${disabled ? 'cursor-not-allowed text-[var(--malachite-text-placeholder,rgb(187,187,187))] opacity-50' : `cursor-pointer text-[var(--malachite-text-placeholder,rgb(187,187,187))] hover:bg-[var(--malachite-pillbutton-background,rgb(241,241,241))] hover:text-[var(--malachite-text-secondary,rgb(123,123,123))]`} ${FOCUS_RING_INSET}`;\n const button =\n href !== undefined ? (\n <a\n href={href}\n aria-label={ariaLabel}\n onClick={(event) => {\n if (isPlainClick(event) && onClick) {\n event.preventDefault();\n onClick();\n }\n }}\n className={`no-underline ${className}`}\n >\n {icon}\n </a>\n ) : (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n aria-disabled={disabled || undefined}\n onClick={disabled ? undefined : onClick}\n className={className}\n >\n {icon}\n </button>\n );\n return tooltip ? <Tooltip text={tooltip}>{button}</Tooltip> : button;\n};\n"],"names":["PopoverHeader","title","action","jsxs","BORDER","jsx","SELECTED_ROW","SELECTION_ATTRIBUTES","scrollSelectedRowIntoView","list","row","listTop","top","bottom","rowTop","rowBottom","PopoverList","children","scrollToSelected","shown","useContext","PopoverShownContext","listRef","useRef","useLayoutEffect","observer","NO_SCROLLBAR","PopoverSection","forwardRef","ref","PopoverEmpty","PopoverAction","icon","ariaLabel","onClick","rawHref","disabled","tooltip","href","safeHref","className","FOCUS_RING_INSET","button","event","isPlainClick","Tooltip"],"mappings":";;;;;;;;AAaO,MAAMA,IAA8C,CAAC,EAAE,OAAAC,GAAO,QAAAC,QACjE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACG,WAAW,oEAAoEC,CAAM;AAAA,IAErF,UAAA;AAAA,MAAA,gBAAAC,EAAC,UAAM,UAAAJ,EAAA,CAAM;AAAA,MACZC;AAAA,IAAA;AAAA,EAAA;AACL,GAGEI,IACF,kIACEC,IAAuB,CAAC,gBAAgB,iBAAiB,cAAc,GAGvEC,IAA4B,CAACC,MAA+B;AAC9D,QAAMC,IAAMD,EAAK,cAA2BH,CAAY;AACxD,MAAI,CAACI;AACD,WAAO;AAEX,QAAMC,IAAUF,EAAK,sBAAA,EAAwB,MAAMA,EAAK,WAClD,EAAE,KAAAG,GAAK,QAAAC,MAAWH,EAAI,sBAAA,GACtBI,IAASF,IAAMD,IAAUF,EAAK,WAC9BM,IAAYF,IAASF,IAAUF,EAAK;AAC1C,SAAIK,IAASL,EAAK,YACdA,EAAK,YAAYK,IACVC,IAAYN,EAAK,YAAYA,EAAK,iBACzCA,EAAK,YAAYM,IAAYN,EAAK,eAE/B;AACX,GAWaO,IAA0C,CAAC,EAAE,UAAAC,GAAU,kBAAAC,IAAmB,SAAY;AAC/F,QAAMC,IAAQC,EAAWC,CAAmB,GACtCC,IAAUC,EAAuB,IAAI;AAG3C,SAAAC,EAAgB,MAAM;AAClB,UAAMf,IAAOa,EAAQ;AACrB,QAAI,CAACJ,KAAoB,CAACC,KAAS,CAACV,KAAQD,EAA0BC,CAAI;AACtE;AAEJ,UAAMgB,IAAW,IAAI,iBAAiB,MAAM;AACxC,MAAIjB,EAA0BC,CAAI,KAC9BgB,EAAS,WAAA;AAAA,IAEjB,CAAC;AACD,WAAAA,EAAS,QAAQhB,GAAM;AAAA,MACnB,WAAW;AAAA,MACX,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,iBAAiBF;AAAA,IAAA,CACpB,GACM,MAAMkB,EAAS,WAAA;AAAA,EAC1B,GAAG,CAACP,GAAkBC,CAAK,CAAC,GAGxB,gBAAAd;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,KAAKiB;AAAA,MACL,WAAW,wDAAwDI,CAAY;AAAA,MAE9E,UAAAT;AAAA,IAAA;AAAA,EAAA;AAGb,GAEaU,IAAiBC;AAAA,EAC1B,CAAC,EAAE,UAAAX,EAAA,GAAYY,MACX,gBAAAxB,EAAC,OAAA,EAAI,KAAAwB,GAAU,WAAW,kCAAkCzB,CAAM,QAC7D,UAAAa,EAAA,CACL;AAER;AACAU,EAAe,cAAc;AAEtB,MAAMG,IAAwD,CAAC,EAAE,UAAAb,QACpE,gBAAAZ,EAAC,OAAA,EAAI,WAAU,kIACV,UAAAY,EAAA,CACL,GAaSc,IAA8C,CAAC;AAAA,EACxD,MAAAC;AAAA,EACA,cAAcC;AAAA,EACd,SAAAC;AAAA,EACA,MAAMC;AAAA,EACN,UAAAC,IAAW;AAAA,EACX,SAAAC;AACJ,MAAM;AACF,QAAMC,IAAOF,IAAW,SAAYG,EAASJ,CAAO,GAC9CK,IAAY,0KAA0KJ,IAAW,4FAA4F,2MAA2M,IAAIK,CAAgB,IAC5fC,IACFJ,MAAS,SACL,gBAAAjC;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,MAAAiC;AAAA,MACA,cAAYL;AAAA,MACZ,SAAS,CAACU,MAAU;AAChB,QAAIC,EAAaD,CAAK,KAAKT,MACvBS,EAAM,eAAA,GACNT,EAAA;AAAA,MAER;AAAA,MACA,WAAW,gBAAgBM,CAAS;AAAA,MAEnC,UAAAR;AAAA,IAAA;AAAA,EAAA,IAGL,gBAAA3B;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,MAAK;AAAA,MACL,cAAY4B;AAAA,MACZ,iBAAeG,KAAY;AAAA,MAC3B,SAASA,IAAW,SAAYF;AAAA,MAChC,WAAAM;AAAA,MAEC,UAAAR;AAAA,IAAA;AAAA,EAAA;AAGb,SAAOK,IAAU,gBAAAhC,EAACwC,GAAA,EAAQ,MAAMR,GAAU,aAAO,IAAaK;AAClE;"}
|
|
1
|
+
{"version":3,"file":"PopoverParts.js","sources":["../../src/components/PopoverParts.tsx"],"sourcesContent":["import React, { forwardRef, useContext, useLayoutEffect, useRef } from 'react';\nimport Button from './Button';\nimport Tooltip from './Tooltip';\nimport { BORDER, NO_SCROLLBAR } from './chromeStyles';\nimport { FOCUS_RING_INSET } from './focusRing';\nimport { isPlainClick } from './linkClick';\nimport { PopoverShownContext } from './popoverTree';\nimport { safeHref } from './safeHref';\n\nexport interface PopoverHeaderProps {\n title: string;\n action?: React.ReactNode;\n}\n\nexport const PopoverHeader: React.FC<PopoverHeaderProps> = ({ title, action }) => (\n <div\n className={`flex items-center justify-between border-0 border-b border-solid ${BORDER} px-5 py-4 text-[12px] leading-[15px] font-normal text-[var(--malachite-text-dimmed,rgb(161,161,161))]`}\n >\n <span>{title}</span>\n {action}\n </div>\n);\n\nconst SELECTED_ROW =\n '[aria-current]:not([aria-current=\"false\"]):not([aria-current=\"\"]), [aria-selected=\"true\"], [role=\"radio\"][aria-checked=\"true\"]';\nconst SELECTION_ATTRIBUTES = ['aria-current', 'aria-selected', 'aria-checked'];\n\n// Not `scrollIntoView`: that also scrolls every scrollable ancestor, the page included.\nconst scrollSelectedRowIntoView = (list: HTMLElement): boolean => {\n const row = list.querySelector<HTMLElement>(SELECTED_ROW);\n if (!row) {\n return false;\n }\n const listTop = list.getBoundingClientRect().top + list.clientTop;\n const { top, bottom } = row.getBoundingClientRect();\n const rowTop = top - listTop + list.scrollTop;\n const rowBottom = bottom - listTop + list.scrollTop;\n if (rowTop < list.scrollTop) {\n list.scrollTop = rowTop;\n } else if (rowBottom > list.scrollTop + list.clientHeight) {\n list.scrollTop = rowBottom - list.clientHeight;\n }\n return true;\n};\n\nexport interface PopoverListProps {\n children: React.ReactNode;\n /**\n * Scrolls the list to its selected row (`aria-current`, `aria-selected` or a checked radio)\n * each time the popover is shown, once that row mounts. Only the list scrolls.\n */\n scrollToSelected?: boolean;\n}\n\nexport const PopoverList: React.FC<PopoverListProps> = ({ children, scrollToSelected = false }) => {\n const shown = useContext(PopoverShownContext);\n const listRef = useRef<HTMLDivElement>(null);\n\n // Before paint, so a shown panel never draws a frame at the top and then jumps.\n useLayoutEffect(() => {\n const list = listRef.current;\n if (!scrollToSelected || !shown || !list || scrollSelectedRowIntoView(list)) {\n return;\n }\n const observer = new MutationObserver(() => {\n if (scrollSelectedRowIntoView(list)) {\n observer.disconnect();\n }\n });\n observer.observe(list, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: SELECTION_ATTRIBUTES,\n });\n return () => observer.disconnect();\n }, [scrollToSelected, shown]);\n\n return (\n <div\n ref={listRef}\n className={`flex max-h-80 flex-col gap-[2px] overflow-y-auto p-2 ${NO_SCROLLBAR}`}\n >\n {children}\n </div>\n );\n};\n\nexport const PopoverSection = forwardRef<HTMLDivElement, { children: React.ReactNode }>(\n ({ children }, ref) => (\n <div ref={ref} className={`border-0 border-t border-solid ${BORDER} p-2`}>\n {children}\n </div>\n ),\n);\nPopoverSection.displayName = 'Popover.Section';\n\nexport const PopoverEmpty: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <div className=\"px-3 py-2 text-[length:var(--malachite-font-size-small,13px)] text-[var(--malachite-text-dimmed,rgb(161,161,161))] select-none\">\n {children}\n </div>\n);\n\nexport const PopoverSearch: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <div className=\"px-2 pt-2\">{children}</div>\n);\n\nexport const PopoverNote: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <div\n className={`border-0 border-t border-solid ${BORDER} px-5 py-3 text-[length:var(--malachite-font-size-xsmall,11px)] leading-4 text-[var(--malachite-text-secondary,rgb(123,123,123))]`}\n >\n {children}\n </div>\n);\n\nexport type PopoverStatusTone = 'default' | 'error';\n\nexport interface PopoverStatusAction {\n label: string;\n onClick: () => void;\n /** Shows the button's spinner and ignores clicks, e.g. while a retry is in flight. */\n pending?: boolean;\n}\n\nexport interface PopoverStatusProps {\n /**\n * What the panel is waiting on, or why it is empty. Clear it rather than unmount the part:\n * only a region already in the tree announces a new message.\n */\n message?: React.ReactNode;\n tone?: PopoverStatusTone;\n /** A button under the message that resolves it, such as Retry. Shown only with a message. */\n action?: PopoverStatusAction;\n /** Lets the region take focus from script (`tabIndex={-1}`), e.g. from `initialFocus`. */\n focusable?: boolean;\n}\n\nconst STATUS_TONE_TEXT: Record<PopoverStatusTone, string> = {\n default: 'text-[var(--malachite-text-secondary,rgb(123,123,123))]',\n error: 'text-[var(--malachite-text-error,rgb(237,53,54))]',\n};\n\nconst hasMessage = (message: React.ReactNode): boolean =>\n message !== undefined && message !== null && message !== false && message !== '';\n\nexport const PopoverStatus = forwardRef<HTMLDivElement, PopoverStatusProps>(\n ({ message, tone = 'default', action, focusable = false }, ref) => {\n const shown = hasMessage(message);\n return (\n <>\n {/* Stays `status` while empty and for errors: a role or aria-hidden changed with the\n text is not reliably announced. No ring: a focus target, not a control. */}\n <div\n ref={ref}\n role=\"status\"\n tabIndex={focusable ? -1 : undefined}\n className={shown ? 'outline-none' : 'sr-only'}\n >\n {shown && (\n <div\n className={`px-3 py-2 text-[length:var(--malachite-font-size-small,13px)] ${STATUS_TONE_TEXT[tone]}`}\n >\n {message}\n </div>\n )}\n </div>\n {shown && action && (\n <div className=\"px-3 pb-2\">\n <Button\n variant=\"outline\"\n size=\"small\"\n loading={action.pending}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n </div>\n )}\n </>\n );\n },\n);\nPopoverStatus.displayName = 'Popover.Status';\n\nexport interface PopoverActionProps {\n icon: React.ReactNode;\n 'aria-label': string;\n onClick?: () => void;\n /** Renders a link; a plain click runs `onClick` instead of following it, when one is given. */\n href?: string;\n disabled?: boolean;\n tooltip?: string;\n}\n\nexport const PopoverAction: React.FC<PopoverActionProps> = ({\n icon,\n 'aria-label': ariaLabel,\n onClick,\n href: rawHref,\n disabled = false,\n tooltip,\n}) => {\n const href = disabled ? undefined : safeHref(rawHref);\n const className = `m-0 inline-flex size-5 items-center justify-center rounded-[var(--malachite-radius-sm,4px)] border-0 bg-transparent p-0 transition-colors duration-150 [&_svg]:size-3! ${disabled ? 'cursor-not-allowed text-[var(--malachite-text-placeholder,rgb(187,187,187))] opacity-50' : `cursor-pointer text-[var(--malachite-text-placeholder,rgb(187,187,187))] hover:bg-[var(--malachite-pillbutton-background,rgb(241,241,241))] hover:text-[var(--malachite-text-secondary,rgb(123,123,123))]`} ${FOCUS_RING_INSET}`;\n const button =\n href !== undefined ? (\n <a\n href={href}\n aria-label={ariaLabel}\n onClick={(event) => {\n if (isPlainClick(event) && onClick) {\n event.preventDefault();\n onClick();\n }\n }}\n className={`no-underline ${className}`}\n >\n {icon}\n </a>\n ) : (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n aria-disabled={disabled || undefined}\n onClick={disabled ? undefined : onClick}\n className={className}\n >\n {icon}\n </button>\n );\n return tooltip ? <Tooltip text={tooltip}>{button}</Tooltip> : button;\n};\n"],"names":["PopoverHeader","title","action","jsxs","BORDER","jsx","SELECTED_ROW","SELECTION_ATTRIBUTES","scrollSelectedRowIntoView","list","row","listTop","top","bottom","rowTop","rowBottom","PopoverList","children","scrollToSelected","shown","useContext","PopoverShownContext","listRef","useRef","useLayoutEffect","observer","NO_SCROLLBAR","PopoverSection","forwardRef","ref","PopoverEmpty","PopoverSearch","PopoverNote","STATUS_TONE_TEXT","hasMessage","message","PopoverStatus","tone","focusable","Fragment","Button","PopoverAction","icon","ariaLabel","onClick","rawHref","disabled","tooltip","href","safeHref","className","FOCUS_RING_INSET","button","event","isPlainClick","Tooltip"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3950,6 +3950,13 @@ export declare const Popover: default_2.FC<PopoverProps> & {
|
|
|
3950
3950
|
Empty: default_2.FC<{
|
|
3951
3951
|
children: default_2.ReactNode;
|
|
3952
3952
|
}>;
|
|
3953
|
+
Search: default_2.FC<{
|
|
3954
|
+
children: default_2.ReactNode;
|
|
3955
|
+
}>;
|
|
3956
|
+
Status: default_2.ForwardRefExoticComponent< PopoverStatusProps & default_2.RefAttributes<HTMLDivElement>>;
|
|
3957
|
+
Note: default_2.FC<{
|
|
3958
|
+
children: default_2.ReactNode;
|
|
3959
|
+
}>;
|
|
3953
3960
|
};
|
|
3954
3961
|
|
|
3955
3962
|
export declare interface PopoverActionProps {
|
|
@@ -4022,6 +4029,28 @@ export declare type PopoverPlacement = FloatingPlacement;
|
|
|
4022
4029
|
|
|
4023
4030
|
export declare type PopoverProps = PopoverBaseProps & PopoverName & PopoverFocusSource;
|
|
4024
4031
|
|
|
4032
|
+
export declare interface PopoverStatusAction {
|
|
4033
|
+
label: string;
|
|
4034
|
+
onClick: () => void;
|
|
4035
|
+
/** Shows the button's spinner and ignores clicks, e.g. while a retry is in flight. */
|
|
4036
|
+
pending?: boolean;
|
|
4037
|
+
}
|
|
4038
|
+
|
|
4039
|
+
export declare interface PopoverStatusProps {
|
|
4040
|
+
/**
|
|
4041
|
+
* What the panel is waiting on, or why it is empty. Clear it rather than unmount the part:
|
|
4042
|
+
* only a region already in the tree announces a new message.
|
|
4043
|
+
*/
|
|
4044
|
+
message?: default_2.ReactNode;
|
|
4045
|
+
tone?: PopoverStatusTone;
|
|
4046
|
+
/** A button under the message that resolves it, such as Retry. Shown only with a message. */
|
|
4047
|
+
action?: PopoverStatusAction;
|
|
4048
|
+
/** Lets the region take focus from script (`tabIndex={-1}`), e.g. from `initialFocus`. */
|
|
4049
|
+
focusable?: boolean;
|
|
4050
|
+
}
|
|
4051
|
+
|
|
4052
|
+
export declare type PopoverStatusTone = 'default' | 'error';
|
|
4053
|
+
|
|
4025
4054
|
export declare const PreviewIcon: React.FC<IconProps_86>;
|
|
4026
4055
|
|
|
4027
4056
|
/** A translucent rounded card that groups {@link PreviewTreeRow}s into a tree preview. */
|