@stackone/malachite 2.27.1 → 2.28.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 +2 -0
- package/dist/components/CommandPalette.js +148 -0
- package/dist/components/CommandPalette.js.map +1 -0
- package/dist/components/Keycap.js +38 -0
- package/dist/components/Keycap.js.map +1 -0
- package/dist/components/SelectionBar.js +38 -38
- package/dist/components/SelectionBar.js.map +1 -1
- package/dist/components/SidePanelNavFooter.js +21 -37
- package/dist/components/SidePanelNavFooter.js.map +1 -1
- package/dist/components/Surface.js +130 -133
- package/dist/components/Surface.js.map +1 -1
- package/dist/components/asChild.js +13 -0
- package/dist/components/asChild.js.map +1 -0
- package/dist/components/overlayBehaviour.js +82 -73
- package/dist/components/overlayBehaviour.js.map +1 -1
- package/dist/components/portalOverlay.js +12 -11
- package/dist/components/portalOverlay.js.map +1 -1
- package/dist/index.d.ts +130 -18
- package/dist/index.js +333 -329
- package/dist/index.js.map +1 -1
- package/dist/tailwind.css.js +1 -1
- package/package.json +1 -1
package/COMPONENTS.md
CHANGED
|
@@ -60,6 +60,8 @@ The catalog of components exported from `@stackone/malachite`. **Reach for one o
|
|
|
60
60
|
- **`FooterNav`** — Footer navigation bar of links. _Key props:_ `FooterNavLink[]`.
|
|
61
61
|
- **`FooterLinks`** — Inline list of footer links (e.g. terms, privacy, support).
|
|
62
62
|
- **`StepTabs`** — Header for a short, ordered flow — a two-step drawer or wizard panel. Each step is a button carrying `aria-current="step"`, not a tab: the body beneath is the step’s form, so it keeps the normal tab order instead of adopting a `tablist`’s arrow-key contract. States are current / complete (a check, still reachable so the user can go back) / upcoming. For a read-only progress readout use `Stepper`. _Key props:_ `items` (`key`, `label`, `hint`, `disabled`), `activeKey`, `completedKeys`, `onChange`, `aria-label`, `aria-labelledby`, `className`.
|
|
63
|
+
- **`CommandPalette`** — Chrome for a command palette, over a headless library that keeps its own elements. `FieldRow`/`Field` take the query input, `List` the scrolling viewport (with a bottom fade for `hasMoreBelow`), `Group` + `Heading` a titled section, and `Row` one result — composing leading/label/crumb/meta/status/hint so names start and statuses end on the same x down the list. `Message` covers empty and loading, `Legend` documents the scope sigils, `Footer` the key hints. Everything the library owns is taken through `asChild`, so its role, id, state and handlers are untouched.
|
|
64
|
+
- **`Keycap`** — One key on a keyboard, drawn as a cap — `esc`, `⌘`, a caret, or a sigil a user types to scope a search. Renders a `<kbd>`, or a button as soon as either `onClick` or `disabled` is passed — `disabled={false}` included, since naming the prop at all is the statement that the cap is a control. `SidePanelNavFooter` is built on it.
|
|
63
65
|
- **`CollapsibleSection`** — Collapsible sunken-card section (title - subtitle header, disclosure arrow right) for stacked detail sections in side panels and detail pages. A preset over `Accordion`’s `sunken` variant.
|
|
64
66
|
- **`KeyValueList`** — Bordered card of label/value rows (`KeyValueList.Row`) for entity details: fixed-width secondary labels, free-form values, row dividers.
|
|
65
67
|
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { jsx as r, jsxs as n, Fragment as g } from "react/jsx-runtime";
|
|
2
|
+
import y, { useState as w, useEffect as N, useRef as k, useCallback as $ } from "react";
|
|
3
|
+
import { createPortal as R } from "react-dom";
|
|
4
|
+
import { ShadowRootWrapper as _ } from "../ShadowRootWrapper.js";
|
|
5
|
+
import { Keycap as z } from "./Keycap.js";
|
|
6
|
+
import { paintOnChild as i } from "./asChild.js";
|
|
7
|
+
import { useOverlayBehaviour as F } from "./overlayBehaviour.js";
|
|
8
|
+
import { OVERLAY_ELEVATED_ATTR as L, overlayIdentity as h } from "./portalOverlay.js";
|
|
9
|
+
const C = "w-full max-w-[640px] overflow-hidden rounded-[var(--malachite-radius-xxl,14px)] border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-background)] outline-none [box-shadow:0_16px_48px_0_rgba(0,0,0,0.18)]", E = ({
|
|
10
|
+
children: a,
|
|
11
|
+
onDismiss: e,
|
|
12
|
+
"aria-label": t,
|
|
13
|
+
className: l = "",
|
|
14
|
+
style: s
|
|
15
|
+
}) => {
|
|
16
|
+
const [c, p] = w(!1);
|
|
17
|
+
N(() => p(!0), []);
|
|
18
|
+
const d = k(null), m = $(() => e == null ? void 0 : e(), [e]), { ref: b, isTopmost: u, zIndex: v, elevated: f } = F({
|
|
19
|
+
open: !0,
|
|
20
|
+
onClose: m,
|
|
21
|
+
hostRef: d,
|
|
22
|
+
initialFocus: "content"
|
|
23
|
+
});
|
|
24
|
+
return c ? R(
|
|
25
|
+
/* @__PURE__ */ r(
|
|
26
|
+
_,
|
|
27
|
+
{
|
|
28
|
+
hostRef: d,
|
|
29
|
+
hostStyle: { position: "relative", zIndex: v },
|
|
30
|
+
hostProps: f ? { ...h("commandpalette"), [L]: "" } : h("commandpalette"),
|
|
31
|
+
children: /* @__PURE__ */ r(
|
|
32
|
+
"div",
|
|
33
|
+
{
|
|
34
|
+
className: "fixed inset-0 z-[1000] flex items-start justify-center pt-[10vh] bg-[var(--malachite-overlay-scrim,rgba(0,0,0,0.5))]",
|
|
35
|
+
onClick: e ? (x) => x.target === x.currentTarget && e() : void 0,
|
|
36
|
+
role: "presentation",
|
|
37
|
+
children: /* @__PURE__ */ r(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
ref: b,
|
|
41
|
+
role: "dialog",
|
|
42
|
+
"aria-modal": u ? "true" : void 0,
|
|
43
|
+
"aria-label": t,
|
|
44
|
+
tabIndex: -1,
|
|
45
|
+
className: `${C} ${l}`.trim(),
|
|
46
|
+
style: s,
|
|
47
|
+
children: a
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
),
|
|
54
|
+
document.body
|
|
55
|
+
) : null;
|
|
56
|
+
}, I = "w-full border-none bg-transparent px-0 py-[18px] text-[length:var(--malachite-font-size-xlarge,18px)] text-[var(--malachite-text-primary)] outline-none placeholder:text-[var(--malachite-text-placeholder)]", S = ({ children: a, className: e = "", style: t }) => i(a, `${I} ${e}`.trim(), t), T = ({ children: a, scope: e, className: t = "" }) => /* @__PURE__ */ n(
|
|
57
|
+
"div",
|
|
58
|
+
{
|
|
59
|
+
className: `flex items-center gap-2 border-0 border-b border-solid border-[var(--malachite-card-border)] px-[18px] ${t}`.trim(),
|
|
60
|
+
children: [
|
|
61
|
+
e,
|
|
62
|
+
a
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
), j = ({ children: a }) => /* @__PURE__ */ r("span", { className: "flex-none whitespace-nowrap rounded-lg border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-sunken-background)] px-2 py-[3px] text-[length:var(--malachite-font-size-small,13px)] text-[var(--malachite-text-primary)]", children: a }), P = "max-h-[420px] overflow-auto py-1 bg-[var(--malachite-card-background)]", A = ({ children: a, hasMoreBelow: e = !1, className: t = "", style: l }) => /* @__PURE__ */ n("div", { className: "relative", children: [
|
|
66
|
+
i(a, `${P} ${t}`.trim(), l),
|
|
67
|
+
e ? /* @__PURE__ */ r(
|
|
68
|
+
"div",
|
|
69
|
+
{
|
|
70
|
+
"aria-hidden": !0,
|
|
71
|
+
className: "pointer-events-none absolute inset-x-0 bottom-0 h-[28px] bg-[linear-gradient(to_bottom,transparent,var(--malachite-card-background))]"
|
|
72
|
+
}
|
|
73
|
+
) : null
|
|
74
|
+
] }), G = ({ children: a, divider: e = !1, className: t = "", style: l }) => i(
|
|
75
|
+
a,
|
|
76
|
+
`block pt-1 pb-2 ${e ? "border-0 border-b border-solid border-[var(--malachite-card-border)]" : ""} ${t}`.trim(),
|
|
77
|
+
l
|
|
78
|
+
), M = ({
|
|
79
|
+
children: a,
|
|
80
|
+
trailing: e
|
|
81
|
+
}) => /* @__PURE__ */ n("div", { className: "mb-1 flex items-center gap-2 px-4 text-[length:var(--malachite-font-size-xsmall,11px)] font-semibold uppercase tracking-[0.06em] text-[var(--malachite-text-secondary)]", children: [
|
|
82
|
+
a,
|
|
83
|
+
e
|
|
84
|
+
] }), O = "group mx-2 flex cursor-pointer items-center gap-2 rounded-[var(--malachite-radius-xl,12px)] px-3 py-[10px] text-[length:var(--malachite-font-size-15,15px)] text-[var(--malachite-text-primary)] transition-colors hover:bg-[var(--malachite-card-sunken-background)] data-[selected=true]:bg-[var(--malachite-card-sunken-background)]", V = ({
|
|
85
|
+
children: a,
|
|
86
|
+
selected: e = !1,
|
|
87
|
+
leading: t,
|
|
88
|
+
label: l,
|
|
89
|
+
crumb: s,
|
|
90
|
+
meta: c,
|
|
91
|
+
status: p,
|
|
92
|
+
hint: d,
|
|
93
|
+
className: m = ""
|
|
94
|
+
}) => i(
|
|
95
|
+
a,
|
|
96
|
+
`${O} ${e ? "bg-[var(--malachite-card-sunken-background)]" : ""} ${m}`.trim(),
|
|
97
|
+
void 0,
|
|
98
|
+
/* @__PURE__ */ n(g, { children: [
|
|
99
|
+
t,
|
|
100
|
+
/* @__PURE__ */ n("span", { className: "flex min-w-0 flex-1 items-baseline gap-2", children: [
|
|
101
|
+
l ? /* @__PURE__ */ r("span", { className: "min-w-0 flex-[0_1_auto] overflow-hidden text-ellipsis whitespace-nowrap", children: l }) : null,
|
|
102
|
+
s ? /* @__PURE__ */ r("span", { className: "flex-none whitespace-nowrap", children: s }) : null,
|
|
103
|
+
c ? /* @__PURE__ */ r("span", { className: "flex-none", children: c }) : null
|
|
104
|
+
] }),
|
|
105
|
+
/* @__PURE__ */ r("span", { className: "flex min-w-[84px] flex-none justify-end", children: p }),
|
|
106
|
+
/* @__PURE__ */ r(
|
|
107
|
+
"span",
|
|
108
|
+
{
|
|
109
|
+
className: `flex-none ${e ? "" : "invisible"} group-data-[selected=true]:visible`,
|
|
110
|
+
children: d
|
|
111
|
+
}
|
|
112
|
+
)
|
|
113
|
+
] })
|
|
114
|
+
), H = ({ children: a, className: e = "", style: t }) => {
|
|
115
|
+
const l = `block px-4 py-2 text-[length:var(--malachite-font-size-medium,14px)] text-[var(--malachite-text-secondary)] ${e}`.trim();
|
|
116
|
+
return y.isValidElement(a) ? i(a, l, t) : /* @__PURE__ */ r("div", { className: l, style: t, children: a });
|
|
117
|
+
}, W = ({ items: a }) => /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-[14px] px-4 pt-[10px] pb-1 text-[length:var(--malachite-font-size-small,13px)] text-[var(--malachite-text-secondary)]", children: a.map((e) => /* @__PURE__ */ n("span", { className: "inline-flex items-center gap-[6px]", children: [
|
|
118
|
+
/* @__PURE__ */ r(z, { size: "small", children: e.key }),
|
|
119
|
+
e.label
|
|
120
|
+
] }, e.key)) }), B = ({ children: a, columns: e = 2, className: t = "" }) => /* @__PURE__ */ r(
|
|
121
|
+
"div",
|
|
122
|
+
{
|
|
123
|
+
className: `grid gap-1 px-2 ${e === 2 ? "grid-cols-2" : "grid-cols-1"} ${t}`.trim(),
|
|
124
|
+
children: a
|
|
125
|
+
}
|
|
126
|
+
), K = ({
|
|
127
|
+
children: a,
|
|
128
|
+
trailing: e
|
|
129
|
+
}) => /* @__PURE__ */ n("div", { className: "flex items-center justify-between gap-3 border-0 border-t border-solid border-[var(--malachite-card-border)] px-4 py-3 text-[length:var(--malachite-font-size-small,13px)] text-[var(--malachite-text-secondary)]", children: [
|
|
130
|
+
/* @__PURE__ */ r("span", { className: "flex items-center gap-[10px]", children: a }),
|
|
131
|
+
e ? /* @__PURE__ */ r("span", { className: "flex items-center gap-[10px]", children: e }) : null
|
|
132
|
+
] }), o = E;
|
|
133
|
+
o.FieldRow = T;
|
|
134
|
+
o.Field = S;
|
|
135
|
+
o.ScopeChip = j;
|
|
136
|
+
o.List = A;
|
|
137
|
+
o.Group = G;
|
|
138
|
+
o.Heading = M;
|
|
139
|
+
o.Row = V;
|
|
140
|
+
o.Grid = B;
|
|
141
|
+
o.Message = H;
|
|
142
|
+
o.Legend = W;
|
|
143
|
+
o.Footer = K;
|
|
144
|
+
export {
|
|
145
|
+
o as CommandPalette,
|
|
146
|
+
o as default
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=CommandPalette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandPalette.js","sources":["../../src/components/CommandPalette.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ShadowRootWrapper } from '../ShadowRootWrapper';\nimport Keycap from './Keycap';\nimport { paintOnChild } from './asChild';\nimport { useOverlayBehaviour } from './overlayBehaviour';\nimport { OVERLAY_ELEVATED_ATTR, overlayIdentity } from './portalOverlay';\n\nconst PANEL =\n 'w-full max-w-[640px] overflow-hidden rounded-[var(--malachite-radius-xxl,14px)] border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-background)] outline-none [box-shadow:0_16px_48px_0_rgba(0,0,0,0.18)]';\n\nexport interface CommandPaletteProps {\n children?: React.ReactNode;\n /** Scrim click, and Escape unless a consumer handler already called `preventDefault`. */\n onDismiss?: () => void;\n 'aria-label'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Open while mounted. */\nconst CommandPaletteRoot: React.FC<CommandPaletteProps> = ({\n children,\n onDismiss,\n 'aria-label': ariaLabel,\n className = '',\n style,\n}) => {\n const [isMounted, setIsMounted] = useState(false);\n useEffect(() => setIsMounted(true), []);\n\n const hostRef = useRef<HTMLDivElement | null>(null);\n const dismiss = useCallback(() => onDismiss?.(), [onDismiss]);\n const { ref, isTopmost, zIndex, elevated } = useOverlayBehaviour({\n open: true,\n onClose: dismiss,\n hostRef,\n initialFocus: 'content',\n });\n\n if (!isMounted) {\n return null;\n }\n\n return createPortal(\n <ShadowRootWrapper\n hostRef={hostRef}\n hostStyle={{ position: 'relative', zIndex }}\n hostProps={\n elevated\n ? { ...overlayIdentity('commandpalette'), [OVERLAY_ELEVATED_ATTR]: '' }\n : overlayIdentity('commandpalette')\n }\n >\n <div\n className=\"fixed inset-0 z-[1000] flex items-start justify-center pt-[10vh] bg-[var(--malachite-overlay-scrim,rgba(0,0,0,0.5))]\"\n onClick={\n onDismiss\n ? (event) => event.target === event.currentTarget && onDismiss()\n : undefined\n }\n role=\"presentation\"\n >\n <div\n ref={ref}\n role=\"dialog\"\n aria-modal={isTopmost ? 'true' : undefined}\n aria-label={ariaLabel}\n tabIndex={-1}\n className={`${PANEL} ${className}`.trim()}\n style={style}\n >\n {children}\n </div>\n </div>\n </ShadowRootWrapper>,\n document.body,\n );\n};\n\ninterface AsChildProps {\n children: React.ReactElement;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst FIELD =\n 'w-full border-none bg-transparent px-0 py-[18px] text-[length:var(--malachite-font-size-xlarge,18px)] text-[var(--malachite-text-primary)] outline-none placeholder:text-[var(--malachite-text-placeholder)]';\n\nconst Field: React.FC<AsChildProps> = ({ children, className = '', style }) =>\n paintOnChild(children, `${FIELD} ${className}`.trim(), style);\n\nexport interface FieldRowProps {\n children?: React.ReactNode;\n scope?: React.ReactNode;\n className?: string;\n}\n\nconst FieldRow: React.FC<FieldRowProps> = ({ children, scope, className = '' }) => (\n <div\n className={`flex items-center gap-2 border-0 border-b border-solid border-[var(--malachite-card-border)] px-[18px] ${className}`.trim()}\n >\n {scope}\n {children}\n </div>\n);\n\nconst ScopeChip: React.FC<{ children?: React.ReactNode }> = ({ children }) => (\n <span className=\"flex-none whitespace-nowrap rounded-lg border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-sunken-background)] px-2 py-[3px] text-[length:var(--malachite-font-size-small,13px)] text-[var(--malachite-text-primary)]\">\n {children}\n </span>\n);\n\nexport interface ListProps extends AsChildProps {\n hasMoreBelow?: boolean;\n}\n\nconst LIST = 'max-h-[420px] overflow-auto py-1 bg-[var(--malachite-card-background)]';\n\nconst List: React.FC<ListProps> = ({ children, hasMoreBelow = false, className = '', style }) => (\n <div className=\"relative\">\n {paintOnChild(children, `${LIST} ${className}`.trim(), style)}\n {hasMoreBelow ? (\n <div\n aria-hidden\n className=\"pointer-events-none absolute inset-x-0 bottom-0 h-[28px] bg-[linear-gradient(to_bottom,transparent,var(--malachite-card-background))]\"\n />\n ) : null}\n </div>\n);\n\nexport interface GroupProps extends AsChildProps {\n divider?: boolean;\n}\n\nconst Group: React.FC<GroupProps> = ({ children, divider = false, className = '', style }) =>\n paintOnChild(\n children,\n `block pt-1 pb-2 ${\n divider ? 'border-0 border-b border-solid border-[var(--malachite-card-border)]' : ''\n } ${className}`.trim(),\n style,\n );\n\nconst Heading: React.FC<{ children?: React.ReactNode; trailing?: React.ReactNode }> = ({\n children,\n trailing,\n}) => (\n <div className=\"mb-1 flex items-center gap-2 px-4 text-[length:var(--malachite-font-size-xsmall,11px)] font-semibold uppercase tracking-[0.06em] text-[var(--malachite-text-secondary)]\">\n {children}\n {trailing}\n </div>\n);\n\nexport interface RowProps {\n /** Its children are replaced, so give the item an explicit `value`/`keywords`. */\n children: React.ReactElement;\n selected?: boolean;\n leading?: React.ReactNode;\n label?: React.ReactNode;\n crumb?: React.ReactNode;\n meta?: React.ReactNode;\n status?: React.ReactNode;\n hint?: React.ReactNode;\n className?: string;\n}\n\n// `data-selected` too: a headless library marks its active item without re-rendering the row.\nconst ROW =\n 'group mx-2 flex cursor-pointer items-center gap-2 rounded-[var(--malachite-radius-xl,12px)] px-3 py-[10px] text-[length:var(--malachite-font-size-15,15px)] text-[var(--malachite-text-primary)] transition-colors hover:bg-[var(--malachite-card-sunken-background)] data-[selected=true]:bg-[var(--malachite-card-sunken-background)]';\n\nconst Row: React.FC<RowProps> = ({\n children,\n selected = false,\n leading,\n label,\n crumb,\n meta,\n status,\n hint,\n className = '',\n}) =>\n paintOnChild(\n children,\n `${ROW} ${selected ? 'bg-[var(--malachite-card-sunken-background)]' : ''} ${className}`.trim(),\n undefined,\n <>\n {leading}\n <span className=\"flex min-w-0 flex-1 items-baseline gap-2\">\n {label ? (\n <span className=\"min-w-0 flex-[0_1_auto] overflow-hidden text-ellipsis whitespace-nowrap\">\n {label}\n </span>\n ) : null}\n {crumb ? <span className=\"flex-none whitespace-nowrap\">{crumb}</span> : null}\n {meta ? <span className=\"flex-none\">{meta}</span> : null}\n </span>\n <span className=\"flex min-w-[84px] flex-none justify-end\">{status}</span>\n <span\n className={`flex-none ${selected ? '' : 'invisible'} group-data-[selected=true]:visible`}\n >\n {hint}\n </span>\n </>,\n );\n\nexport interface MessageProps {\n children: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst Message: React.FC<MessageProps> = ({ children, className = '', style }) => {\n const classes =\n `block px-4 py-2 text-[length:var(--malachite-font-size-medium,14px)] text-[var(--malachite-text-secondary)] ${className}`.trim();\n return React.isValidElement(children) ? (\n paintOnChild(children, classes, style)\n ) : (\n <div className={classes} style={style}>\n {children}\n </div>\n );\n};\n\nexport interface LegendProps {\n items: { key: string; label: string }[];\n}\n\nconst Legend: React.FC<LegendProps> = ({ items }) => (\n <div className=\"flex flex-wrap gap-[14px] px-4 pt-[10px] pb-1 text-[length:var(--malachite-font-size-small,13px)] text-[var(--malachite-text-secondary)]\">\n {items.map((item) => (\n <span key={item.key} className=\"inline-flex items-center gap-[6px]\">\n <Keycap size=\"small\">{item.key}</Keycap>\n {item.label}\n </span>\n ))}\n </div>\n);\n\nexport interface GridProps {\n children?: React.ReactNode;\n columns?: 1 | 2;\n className?: string;\n}\n\nconst Grid: React.FC<GridProps> = ({ children, columns = 2, className = '' }) => (\n <div\n className={`grid gap-1 px-2 ${columns === 2 ? 'grid-cols-2' : 'grid-cols-1'} ${className}`.trim()}\n >\n {children}\n </div>\n);\n\nconst Footer: React.FC<{ children?: React.ReactNode; trailing?: React.ReactNode }> = ({\n children,\n trailing,\n}) => (\n <div className=\"flex items-center justify-between gap-3 border-0 border-t border-solid border-[var(--malachite-card-border)] px-4 py-3 text-[length:var(--malachite-font-size-small,13px)] text-[var(--malachite-text-secondary)]\">\n <span className=\"flex items-center gap-[10px]\">{children}</span>\n {trailing ? <span className=\"flex items-center gap-[10px]\">{trailing}</span> : null}\n </div>\n);\n\ninterface CommandPaletteComponent extends React.FC<CommandPaletteProps> {\n FieldRow: React.FC<FieldRowProps>;\n Field: React.FC<AsChildProps>;\n ScopeChip: React.FC<{ children?: React.ReactNode }>;\n List: React.FC<ListProps>;\n Group: React.FC<GroupProps>;\n Heading: React.FC<{ children?: React.ReactNode; trailing?: React.ReactNode }>;\n Row: React.FC<RowProps>;\n Grid: React.FC<GridProps>;\n Message: React.FC<MessageProps>;\n Legend: React.FC<LegendProps>;\n Footer: React.FC<{ children?: React.ReactNode; trailing?: React.ReactNode }>;\n}\n\nconst CommandPalette = CommandPaletteRoot as CommandPaletteComponent;\nCommandPalette.FieldRow = FieldRow;\nCommandPalette.Field = Field;\nCommandPalette.ScopeChip = ScopeChip;\nCommandPalette.List = List;\nCommandPalette.Group = Group;\nCommandPalette.Heading = Heading;\nCommandPalette.Row = Row;\nCommandPalette.Grid = Grid;\nCommandPalette.Message = Message;\nCommandPalette.Legend = Legend;\nCommandPalette.Footer = Footer;\n\nexport default CommandPalette;\nexport { CommandPalette };\n"],"names":["PANEL","CommandPaletteRoot","children","onDismiss","ariaLabel","className","style","isMounted","setIsMounted","useState","useEffect","hostRef","useRef","dismiss","useCallback","ref","isTopmost","zIndex","elevated","useOverlayBehaviour","createPortal","jsx","ShadowRootWrapper","overlayIdentity","OVERLAY_ELEVATED_ATTR","event","FIELD","Field","paintOnChild","FieldRow","scope","jsxs","ScopeChip","LIST","List","hasMoreBelow","Group","divider","Heading","trailing","ROW","Row","selected","leading","label","crumb","meta","status","hint","Fragment","Message","classes","React","Legend","items","item","Keycap","Grid","columns","Footer","CommandPalette"],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import { FOCUS_RING as m } from "./focusRing.js";
|
|
3
|
+
const c = {
|
|
4
|
+
small: "h-[18px] min-w-[18px]",
|
|
5
|
+
medium: "h-[20px] min-w-[20px]"
|
|
6
|
+
}, b = "inline-flex items-center justify-center rounded-lg border border-solid border-[var(--malachite-card-border,rgb(232,232,232))] bg-[var(--malachite-card-background,rgb(255,255,255))] [box-shadow:var(--malachite-shadow-default,0px_1px_0px_0px_rgba(0,0,0,0.15))]", n = "px-[6px] text-[10px] font-medium uppercase tracking-[0.5px] text-[var(--malachite-text-placeholder,rgb(187,187,187))]", x = "px-[4px]", h = ({
|
|
7
|
+
children: a,
|
|
8
|
+
size: e = "medium",
|
|
9
|
+
onClick: t,
|
|
10
|
+
disabled: r,
|
|
11
|
+
"aria-label": o,
|
|
12
|
+
"aria-labelledby": l,
|
|
13
|
+
className: p = ""
|
|
14
|
+
}) => t !== void 0 || r !== void 0 ? /* @__PURE__ */ i(
|
|
15
|
+
"button",
|
|
16
|
+
{
|
|
17
|
+
type: "button",
|
|
18
|
+
"aria-label": o,
|
|
19
|
+
"aria-labelledby": l,
|
|
20
|
+
onClick: t,
|
|
21
|
+
disabled: r,
|
|
22
|
+
className: `${c[e]} ${b} ${x} transition-opacity ${m} ${r ? "cursor-not-allowed opacity-40" : "cursor-pointer hover:border-[var(--malachite-text-placeholder,rgb(187,187,187))]"} ${p}`.trim(),
|
|
23
|
+
children: a
|
|
24
|
+
}
|
|
25
|
+
) : /* @__PURE__ */ i(
|
|
26
|
+
"kbd",
|
|
27
|
+
{
|
|
28
|
+
className: `${c[e]} ${b} ${n} ${p}`.trim(),
|
|
29
|
+
"aria-label": o,
|
|
30
|
+
"aria-labelledby": l,
|
|
31
|
+
children: a
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
export {
|
|
35
|
+
h as Keycap,
|
|
36
|
+
h as default
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=Keycap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Keycap.js","sources":["../../src/components/Keycap.tsx"],"sourcesContent":["import React from 'react';\nimport { FOCUS_RING } from './focusRing';\n\nexport type KeycapSize = 'small' | 'medium';\n\nexport interface KeycapProps {\n children: React.ReactNode;\n size?: KeycapSize;\n onClick?: () => void;\n /** Renders a `<button>` even when `false`. */\n disabled?: boolean;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n className?: string;\n}\n\nconst SIZE_CLASSES: Record<KeycapSize, string> = {\n small: 'h-[18px] min-w-[18px]',\n medium: 'h-[20px] min-w-[20px]',\n};\n\nconst CAP =\n 'inline-flex items-center justify-center rounded-lg border border-solid border-[var(--malachite-card-border,rgb(232,232,232))] bg-[var(--malachite-card-background,rgb(255,255,255))] [box-shadow:var(--malachite-shadow-default,0px_1px_0px_0px_rgba(0,0,0,0.15))]';\n\nconst LABEL_CAP =\n 'px-[6px] text-[10px] font-medium uppercase tracking-[0.5px] text-[var(--malachite-text-placeholder,rgb(187,187,187))]';\nconst GLYPH_CAP = 'px-[4px]';\n\nexport const Keycap: React.FC<KeycapProps> = ({\n children,\n size = 'medium',\n onClick,\n disabled,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className = '',\n}) => {\n const pressable = onClick !== undefined || disabled !== undefined;\n\n if (!pressable) {\n return (\n <kbd\n className={`${SIZE_CLASSES[size]} ${CAP} ${LABEL_CAP} ${className}`.trim()}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </kbd>\n );\n }\n\n return (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n onClick={onClick}\n disabled={disabled}\n className={`${SIZE_CLASSES[size]} ${CAP} ${GLYPH_CAP} transition-opacity ${FOCUS_RING} ${\n disabled\n ? 'cursor-not-allowed opacity-40'\n : 'cursor-pointer hover:border-[var(--malachite-text-placeholder,rgb(187,187,187))]'\n } ${className}`.trim()}\n >\n {children}\n </button>\n );\n};\n\nexport default Keycap;\n"],"names":["SIZE_CLASSES","CAP","LABEL_CAP","GLYPH_CAP","Keycap","children","size","onClick","disabled","ariaLabel","ariaLabelledBy","className","jsx","FOCUS_RING"],"mappings":";;AAgBA,MAAMA,IAA2C;AAAA,EAC7C,OAAO;AAAA,EACP,QAAQ;AACZ,GAEMC,IACF,sQAEEC,IACF,yHACEC,IAAY,YAELC,IAAgC,CAAC;AAAA,EAC1C,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,cAAcC;AAAA,EACd,mBAAmBC;AAAA,EACnB,WAAAC,IAAY;AAChB,MACsBJ,MAAY,UAAaC,MAAa,SAepD,gBAAAI;AAAA,EAAC;AAAA,EAAA;AAAA,IACG,MAAK;AAAA,IACL,cAAYH;AAAA,IACZ,mBAAiBC;AAAA,IACjB,SAAAH;AAAA,IACA,UAAAC;AAAA,IACA,WAAW,GAAGR,EAAaM,CAAI,CAAC,IAAIL,CAAG,IAAIE,CAAS,uBAAuBU,CAAU,IACjFL,IACM,kCACA,kFACV,IAAIG,CAAS,GAAG,KAAA;AAAA,IAEf,UAAAN;AAAA,EAAA;AAAA,IAvBD,gBAAAO;AAAA,EAAC;AAAA,EAAA;AAAA,IACG,WAAW,GAAGZ,EAAaM,CAAI,CAAC,IAAIL,CAAG,IAAIC,CAAS,IAAIS,CAAS,GAAG,KAAA;AAAA,IACpE,cAAYF;AAAA,IACZ,mBAAiBC;AAAA,IAEhB,UAAAL;AAAA,EAAA;AAAA;"}
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useRef as m, useState as
|
|
3
|
-
import { PILL_TRANSITION_MS as
|
|
4
|
-
import { useAdoptedStyleSheet as
|
|
5
|
-
const T = (r) => String(r.value) === "" ? r.label : `${r.value} ${r.label}`,
|
|
1
|
+
import { jsxs as n, jsx as l } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as m, useState as I, useEffect as A, Fragment as S } from "react";
|
|
3
|
+
import { PILL_TRANSITION_MS as C, PILL_SHADOW as g, PILL_SURFACE as k, PILL_MUTED_TEXT as _, PILL_DIVIDER as O, PILL_BUTTON_BASE as R, PILL_BUTTON_CLASS as D, PILL_NOTICE_SHADOW as H, PILL_NOTICE_SLEEVE as M, PILL_NOTICE_TEXT as j, PILL_TRACK_CLASS as B, PILL_SHEET_ID as F, PILL_SHEET_CSS as U } from "./selectionBarChrome.js";
|
|
4
|
+
import { useAdoptedStyleSheet as V } from "./useAdoptedStyleSheet.js";
|
|
5
|
+
const T = (r) => String(r.value) === "" ? r.label : `${r.value} ${r.label}`, b = (r) => r.map(T).join(", "), w = (r, i) => r === void 0 || r === "" ? b(i) : `${r} ${b(i)}`.trim(), K = ({
|
|
6
6
|
open: r,
|
|
7
|
-
counts:
|
|
8
|
-
actions:
|
|
9
|
-
placement:
|
|
7
|
+
counts: i,
|
|
8
|
+
actions: v,
|
|
9
|
+
placement: N = "sticky",
|
|
10
10
|
notice: d,
|
|
11
|
-
"aria-label":
|
|
11
|
+
"aria-label": E = "Pending changes",
|
|
12
12
|
"aria-labelledby": L,
|
|
13
|
-
className:
|
|
13
|
+
className: P = ""
|
|
14
14
|
}) => {
|
|
15
|
-
const o = m(null), [
|
|
16
|
-
|
|
15
|
+
const o = m(null), [f, h] = I(r), [s, p] = I(r), a = m(null), t = m(null);
|
|
16
|
+
V(o, U, F), A(() => {
|
|
17
17
|
var e;
|
|
18
18
|
if (r)
|
|
19
|
-
|
|
20
|
-
a.current = null,
|
|
19
|
+
h(!0), t.current && (clearTimeout(t.current), t.current = null), a.current = requestAnimationFrame(() => {
|
|
20
|
+
a.current = null, p(!0);
|
|
21
21
|
});
|
|
22
22
|
else {
|
|
23
23
|
const c = document.activeElement;
|
|
24
|
-
c instanceof HTMLElement && ((e = o.current) != null && e.contains(c)) && c.blur(),
|
|
25
|
-
|
|
26
|
-
},
|
|
24
|
+
c instanceof HTMLElement && ((e = o.current) != null && e.contains(c)) && c.blur(), p(!1), t.current = setTimeout(() => {
|
|
25
|
+
t.current = null, h(!1);
|
|
26
|
+
}, C);
|
|
27
27
|
}
|
|
28
28
|
return () => {
|
|
29
|
-
a.current !== null && (cancelAnimationFrame(a.current), a.current = null),
|
|
29
|
+
a.current !== null && (cancelAnimationFrame(a.current), a.current = null), t.current && (clearTimeout(t.current), t.current = null);
|
|
30
30
|
};
|
|
31
31
|
}, [r]);
|
|
32
|
-
const
|
|
33
|
-
|
|
32
|
+
const y = N === "sticky", u = d !== void 0 && d !== "", x = `sticky bottom-0 z-30${f ? " pt-4 pb-6" : ""}`, $ = /* @__PURE__ */ n("div", { className: k, style: { boxShadow: g }, children: [
|
|
33
|
+
i.length > 0 && /* @__PURE__ */ l(
|
|
34
34
|
"p",
|
|
35
35
|
{
|
|
36
36
|
"aria-hidden": "true",
|
|
37
37
|
className: "m-0 flex items-center gap-2 text-[13px] leading-[1.6] tracking-[0.13px]",
|
|
38
|
-
children:
|
|
39
|
-
c > 0 && /* @__PURE__ */ l("span", { className:
|
|
38
|
+
children: i.map((e, c) => /* @__PURE__ */ n(S, { children: [
|
|
39
|
+
c > 0 && /* @__PURE__ */ l("span", { className: _, children: "•" }),
|
|
40
40
|
/* @__PURE__ */ l("span", { children: T(e) })
|
|
41
41
|
] }, e.label))
|
|
42
42
|
}
|
|
43
43
|
),
|
|
44
|
-
|
|
45
|
-
e.dividerBefore && /* @__PURE__ */ l("span", { "aria-hidden": "true", className: `${
|
|
46
|
-
/* @__PURE__ */
|
|
44
|
+
v.map((e) => /* @__PURE__ */ n(S, { children: [
|
|
45
|
+
e.dividerBefore && /* @__PURE__ */ l("span", { "aria-hidden": "true", className: `${O} ${_}`, children: "|" }),
|
|
46
|
+
/* @__PURE__ */ n(
|
|
47
47
|
"button",
|
|
48
48
|
{
|
|
49
49
|
type: "button",
|
|
50
50
|
disabled: e.disabled,
|
|
51
51
|
tabIndex: s ? void 0 : -1,
|
|
52
52
|
onClick: e.onClick,
|
|
53
|
-
className: `${
|
|
53
|
+
className: `${R} ${D}--${e.emphasis ?? "secondary"}`,
|
|
54
54
|
children: [
|
|
55
55
|
e.icon && e.iconPosition !== "end" && /* @__PURE__ */ l("span", { "aria-hidden": "true", className: "flex items-center", children: e.icon }),
|
|
56
56
|
e.label,
|
|
@@ -62,30 +62,30 @@ const T = (r) => String(r.value) === "" ? r.label : `${r.value} ${r.label}`, _ =
|
|
|
62
62
|
] });
|
|
63
63
|
return (
|
|
64
64
|
// The live region has to exist BEFORE its text changes or the first announcement is dropped.
|
|
65
|
-
/* @__PURE__ */
|
|
65
|
+
/* @__PURE__ */ n(
|
|
66
66
|
"div",
|
|
67
67
|
{
|
|
68
68
|
ref: o,
|
|
69
|
-
className: `${
|
|
69
|
+
className: `${B} pointer-events-none flex w-full justify-center ${y ? x : "relative"} ${P}`.trim(),
|
|
70
70
|
style: { opacity: s ? 1 : 0 },
|
|
71
71
|
children: [
|
|
72
|
-
/* @__PURE__ */ l("p", { className: "sr-only", role: "status", children: s ?
|
|
73
|
-
|
|
72
|
+
/* @__PURE__ */ l("p", { className: "sr-only", role: "status", children: s ? w(d, i) : "" }),
|
|
73
|
+
f && /* @__PURE__ */ l(
|
|
74
74
|
"div",
|
|
75
75
|
{
|
|
76
76
|
role: "group",
|
|
77
|
-
"aria-label": L ? void 0 :
|
|
77
|
+
"aria-label": L ? void 0 : E,
|
|
78
78
|
"aria-labelledby": L,
|
|
79
79
|
"aria-hidden": s ? void 0 : !0,
|
|
80
80
|
className: s ? "pointer-events-auto" : void 0,
|
|
81
|
-
children: /* @__PURE__ */
|
|
81
|
+
children: /* @__PURE__ */ n(
|
|
82
82
|
"div",
|
|
83
83
|
{
|
|
84
|
-
className: u ?
|
|
85
|
-
style: u ? { boxShadow:
|
|
84
|
+
className: u ? M : void 0,
|
|
85
|
+
style: u ? { boxShadow: H } : void 0,
|
|
86
86
|
children: [
|
|
87
|
-
u && /* @__PURE__ */ l("p", { "aria-hidden": "true", className:
|
|
88
|
-
|
|
87
|
+
u && /* @__PURE__ */ l("p", { "aria-hidden": "true", className: j, children: d }),
|
|
88
|
+
$
|
|
89
89
|
]
|
|
90
90
|
}
|
|
91
91
|
)
|
|
@@ -97,7 +97,7 @@ const T = (r) => String(r.value) === "" ? r.label : `${r.value} ${r.label}`, _ =
|
|
|
97
97
|
);
|
|
98
98
|
};
|
|
99
99
|
export {
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
K as SelectionBar,
|
|
101
|
+
K as default
|
|
102
102
|
};
|
|
103
103
|
//# sourceMappingURL=SelectionBar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionBar.js","sources":["../../src/components/SelectionBar.tsx"],"sourcesContent":["import React, { Fragment, useEffect, useRef, useState } from 'react';\nimport {\n PILL_BUTTON_BASE,\n PILL_BUTTON_CLASS,\n PILL_DIVIDER,\n PILL_MUTED_TEXT,\n PILL_NOTICE_SHADOW,\n PILL_NOTICE_SLEEVE,\n PILL_NOTICE_TEXT,\n PILL_SHADOW,\n PILL_SHEET_CSS,\n PILL_SHEET_ID,\n PILL_SURFACE,\n PILL_TRACK_CLASS,\n PILL_TRANSITION_MS,\n type SelectionBarCount,\n type SelectionBarEmphasis,\n} from './selectionBarChrome';\nimport { useAdoptedStyleSheet } from './useAdoptedStyleSheet';\n\nexport type { SelectionBarCount, SelectionBarEmphasis };\n\nexport interface SelectionBarAction {\n label: string;\n onClick: () => void;\n /** 'primary' commits the pending change; 'secondary' (the default) is a filled chip;\n * 'quiet' is unfilled and takes a wash on hover. */\n emphasis?: SelectionBarEmphasis;\n icon?: React.ReactNode;\n iconPosition?: 'start' | 'end';\n disabled?: boolean;\n /** Renders a separator glyph before this action. */\n dividerBefore?: boolean;\n}\n\nexport interface SelectionBarProps {\n /** Drives the mount: the bar animates in on true and animates out on false. */\n open: boolean;\n counts: SelectionBarCount[];\n actions: SelectionBarAction[];\n /** 'sticky' keeps the bar in view while its container scrolls; render it as the last child\n * of that content, with no `overflow: hidden` on any ancestor. */\n placement?: 'sticky' | 'inline';\n /**\n * Wraps the bar in a warning sleeve carrying this message, for state the bar is\n * reporting rather than an action it offers — e.g. that the selection is unsaved.\n * It leads the announcement. An empty string renders no sleeve.\n */\n notice?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n className?: string;\n}\n\n/** A count reads as one phrase; an empty `value` carries a bare message instead. */\nconst countText = (count: SelectionBarCount): string =>\n String(count.value) === '' ? count.label : `${count.value} ${count.label}`;\n\nconst summarise = (counts: SelectionBarCount[]): string => counts.map(countText).join(', ');\n\n/** A notice is the reason the bar is up, so it leads the announcement. */\nconst announcement = (notice: string | undefined, counts: SelectionBarCount[]): string =>\n notice === undefined || notice === ''\n ? summarise(counts)\n : `${notice} ${summarise(counts)}`.trim();\n\n/**\n * A bar reporting a pending, not-yet-written selection and the actions that resolve it. Every\n * action destroys the button just pressed, so an `onClick` that ends the pending state must\n * also move focus.\n */\nexport const SelectionBar: React.FC<SelectionBarProps> = ({\n open,\n counts,\n actions,\n placement = 'sticky',\n notice,\n 'aria-label': ariaLabel = 'Pending changes',\n 'aria-labelledby': ariaLabelledBy,\n className = '',\n}) => {\n const trackRef = useRef<HTMLDivElement>(null);\n const [isMounted, setIsMounted] = useState(open);\n const [isVisible, setIsVisible] = useState(open);\n const frameRef = useRef<number | null>(null);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useAdoptedStyleSheet(trackRef, PILL_SHEET_CSS, PILL_SHEET_ID);\n\n useEffect(() => {\n if (open) {\n setIsMounted(true);\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n frameRef.current = requestAnimationFrame(() => {\n frameRef.current = null;\n setIsVisible(true);\n });\n } else {\n // The browser refuses `aria-hidden` on a subtree still holding focus, so a caller\n // that forgets to move it would trap the keyboard here.\n const active = document.activeElement;\n if (active instanceof HTMLElement && trackRef.current?.contains(active)) {\n active.blur();\n }\n setIsVisible(false);\n timerRef.current = setTimeout(() => {\n timerRef.current = null;\n setIsMounted(false);\n }, PILL_TRANSITION_MS);\n }\n return () => {\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current);\n frameRef.current = null;\n }\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n }, [open]);\n\n const isSticky = placement === 'sticky';\n const hasNotice = notice !== undefined && notice !== '';\n\n const pill = (\n <div className={PILL_SURFACE} style={{ boxShadow: PILL_SHADOW }}>\n {counts.length > 0 && (\n <p\n aria-hidden=\"true\"\n className=\"m-0 flex items-center gap-2 text-[13px] leading-[1.6] tracking-[0.13px]\"\n >\n {counts.map((count, index) => (\n <Fragment key={count.label}>\n {index > 0 && <span className={PILL_MUTED_TEXT}>•</span>}\n <span>{countText(count)}</span>\n </Fragment>\n ))}\n </p>\n )}\n {actions.map((action) => (\n <Fragment key={action.label}>\n {action.dividerBefore && (\n <span aria-hidden=\"true\" className={`${PILL_DIVIDER} ${PILL_MUTED_TEXT}`}>\n |\n </span>\n )}\n <button\n type=\"button\"\n disabled={action.disabled}\n tabIndex={isVisible ? undefined : -1}\n onClick={action.onClick}\n className={`${PILL_BUTTON_BASE} ${PILL_BUTTON_CLASS}--${action.emphasis ?? 'secondary'}`}\n >\n {action.icon && action.iconPosition !== 'end' && (\n <span aria-hidden=\"true\" className=\"flex items-center\">\n {action.icon}\n </span>\n )}\n {action.label}\n {action.icon && action.iconPosition === 'end' && (\n <span aria-hidden=\"true\" className=\"flex items-center\">\n {action.icon}\n </span>\n )}\n </button>\n </Fragment>\n ))}\n </div>\n );\n\n return (\n // The live region has to exist BEFORE its text changes or the first announcement is dropped.\n <div\n ref={trackRef}\n className={`${PILL_TRACK_CLASS} pointer-events-none flex w-full justify-center ${isSticky ? 'sticky bottom-6 z-30' : 'relative'} ${className}`.trim()}\n style={{ opacity: isVisible ? 1 : 0 }}\n >\n <p className=\"sr-only\" role=\"status\">\n {isVisible ? announcement(notice, counts) : ''}\n </p>\n {isMounted && (\n <div\n role=\"group\"\n aria-label={ariaLabelledBy ? undefined : ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-hidden={isVisible ? undefined : true}\n className={isVisible ? 'pointer-events-auto' : undefined}\n >\n {/* Keep the wrapper stable: changing the pill's parent remounts it and drops focus\n from the action that raised the notice. */}\n <div\n className={hasNotice ? PILL_NOTICE_SLEEVE : undefined}\n style={hasNotice ? { boxShadow: PILL_NOTICE_SHADOW } : undefined}\n >\n {hasNotice && (\n <p aria-hidden=\"true\" className={PILL_NOTICE_TEXT}>\n {notice}\n </p>\n )}\n {pill}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default SelectionBar;\n"],"names":["countText","count","summarise","counts","announcement","notice","SelectionBar","open","actions","placement","ariaLabel","ariaLabelledBy","className","trackRef","useRef","isMounted","setIsMounted","useState","isVisible","setIsVisible","frameRef","timerRef","useAdoptedStyleSheet","PILL_SHEET_CSS","PILL_SHEET_ID","useEffect","active","_a","PILL_TRANSITION_MS","isSticky","hasNotice","pill","PILL_SURFACE","PILL_SHADOW","jsx","index","Fragment","PILL_MUTED_TEXT","action","PILL_DIVIDER","jsxs","PILL_BUTTON_BASE","PILL_BUTTON_CLASS","PILL_TRACK_CLASS","PILL_NOTICE_SLEEVE","PILL_NOTICE_SHADOW","PILL_NOTICE_TEXT"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SelectionBar.js","sources":["../../src/components/SelectionBar.tsx"],"sourcesContent":["import React, { Fragment, useEffect, useRef, useState } from 'react';\nimport {\n PILL_BUTTON_BASE,\n PILL_BUTTON_CLASS,\n PILL_DIVIDER,\n PILL_MUTED_TEXT,\n PILL_NOTICE_SHADOW,\n PILL_NOTICE_SLEEVE,\n PILL_NOTICE_TEXT,\n PILL_SHADOW,\n PILL_SHEET_CSS,\n PILL_SHEET_ID,\n PILL_SURFACE,\n PILL_TRACK_CLASS,\n PILL_TRANSITION_MS,\n type SelectionBarCount,\n type SelectionBarEmphasis,\n} from './selectionBarChrome';\nimport { useAdoptedStyleSheet } from './useAdoptedStyleSheet';\n\nexport type { SelectionBarCount, SelectionBarEmphasis };\n\nexport interface SelectionBarAction {\n label: string;\n onClick: () => void;\n /** 'primary' commits the pending change; 'secondary' (the default) is a filled chip;\n * 'quiet' is unfilled and takes a wash on hover. */\n emphasis?: SelectionBarEmphasis;\n icon?: React.ReactNode;\n iconPosition?: 'start' | 'end';\n disabled?: boolean;\n /** Renders a separator glyph before this action. */\n dividerBefore?: boolean;\n}\n\nexport interface SelectionBarProps {\n /** Drives the mount: the bar animates in on true and animates out on false. */\n open: boolean;\n counts: SelectionBarCount[];\n actions: SelectionBarAction[];\n /** 'sticky' keeps the bar in view while its container scrolls; render it as the last child\n * of that content, with no `overflow: hidden` on any ancestor. */\n placement?: 'sticky' | 'inline';\n /**\n * Wraps the bar in a warning sleeve carrying this message, for state the bar is\n * reporting rather than an action it offers — e.g. that the selection is unsaved.\n * It leads the announcement. An empty string renders no sleeve.\n */\n notice?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n className?: string;\n}\n\n/** A count reads as one phrase; an empty `value` carries a bare message instead. */\nconst countText = (count: SelectionBarCount): string =>\n String(count.value) === '' ? count.label : `${count.value} ${count.label}`;\n\nconst summarise = (counts: SelectionBarCount[]): string => counts.map(countText).join(', ');\n\n/** A notice is the reason the bar is up, so it leads the announcement. */\nconst announcement = (notice: string | undefined, counts: SelectionBarCount[]): string =>\n notice === undefined || notice === ''\n ? summarise(counts)\n : `${notice} ${summarise(counts)}`.trim();\n\n/**\n * A bar reporting a pending, not-yet-written selection and the actions that resolve it. Every\n * action destroys the button just pressed, so an `onClick` that ends the pending state must\n * also move focus.\n */\nexport const SelectionBar: React.FC<SelectionBarProps> = ({\n open,\n counts,\n actions,\n placement = 'sticky',\n notice,\n 'aria-label': ariaLabel = 'Pending changes',\n 'aria-labelledby': ariaLabelledBy,\n className = '',\n}) => {\n const trackRef = useRef<HTMLDivElement>(null);\n const [isMounted, setIsMounted] = useState(open);\n const [isVisible, setIsVisible] = useState(open);\n const frameRef = useRef<number | null>(null);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useAdoptedStyleSheet(trackRef, PILL_SHEET_CSS, PILL_SHEET_ID);\n\n useEffect(() => {\n if (open) {\n setIsMounted(true);\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n frameRef.current = requestAnimationFrame(() => {\n frameRef.current = null;\n setIsVisible(true);\n });\n } else {\n // The browser refuses `aria-hidden` on a subtree still holding focus, so a caller\n // that forgets to move it would trap the keyboard here.\n const active = document.activeElement;\n if (active instanceof HTMLElement && trackRef.current?.contains(active)) {\n active.blur();\n }\n setIsVisible(false);\n timerRef.current = setTimeout(() => {\n timerRef.current = null;\n setIsMounted(false);\n }, PILL_TRANSITION_MS);\n }\n return () => {\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current);\n frameRef.current = null;\n }\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n }, [open]);\n\n const isSticky = placement === 'sticky';\n const hasNotice = notice !== undefined && notice !== '';\n const stickyClass = `sticky bottom-0 z-30${isMounted ? ' pt-4 pb-6' : ''}`;\n\n const pill = (\n <div className={PILL_SURFACE} style={{ boxShadow: PILL_SHADOW }}>\n {counts.length > 0 && (\n <p\n aria-hidden=\"true\"\n className=\"m-0 flex items-center gap-2 text-[13px] leading-[1.6] tracking-[0.13px]\"\n >\n {counts.map((count, index) => (\n <Fragment key={count.label}>\n {index > 0 && <span className={PILL_MUTED_TEXT}>•</span>}\n <span>{countText(count)}</span>\n </Fragment>\n ))}\n </p>\n )}\n {actions.map((action) => (\n <Fragment key={action.label}>\n {action.dividerBefore && (\n <span aria-hidden=\"true\" className={`${PILL_DIVIDER} ${PILL_MUTED_TEXT}`}>\n |\n </span>\n )}\n <button\n type=\"button\"\n disabled={action.disabled}\n tabIndex={isVisible ? undefined : -1}\n onClick={action.onClick}\n className={`${PILL_BUTTON_BASE} ${PILL_BUTTON_CLASS}--${action.emphasis ?? 'secondary'}`}\n >\n {action.icon && action.iconPosition !== 'end' && (\n <span aria-hidden=\"true\" className=\"flex items-center\">\n {action.icon}\n </span>\n )}\n {action.label}\n {action.icon && action.iconPosition === 'end' && (\n <span aria-hidden=\"true\" className=\"flex items-center\">\n {action.icon}\n </span>\n )}\n </button>\n </Fragment>\n ))}\n </div>\n );\n\n return (\n // The live region has to exist BEFORE its text changes or the first announcement is dropped.\n <div\n ref={trackRef}\n className={`${PILL_TRACK_CLASS} pointer-events-none flex w-full justify-center ${isSticky ? stickyClass : 'relative'} ${className}`.trim()}\n style={{ opacity: isVisible ? 1 : 0 }}\n >\n <p className=\"sr-only\" role=\"status\">\n {isVisible ? announcement(notice, counts) : ''}\n </p>\n {isMounted && (\n <div\n role=\"group\"\n aria-label={ariaLabelledBy ? undefined : ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-hidden={isVisible ? undefined : true}\n className={isVisible ? 'pointer-events-auto' : undefined}\n >\n {/* Keep the wrapper stable: changing the pill's parent remounts it and drops focus\n from the action that raised the notice. */}\n <div\n className={hasNotice ? PILL_NOTICE_SLEEVE : undefined}\n style={hasNotice ? { boxShadow: PILL_NOTICE_SHADOW } : undefined}\n >\n {hasNotice && (\n <p aria-hidden=\"true\" className={PILL_NOTICE_TEXT}>\n {notice}\n </p>\n )}\n {pill}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default SelectionBar;\n"],"names":["countText","count","summarise","counts","announcement","notice","SelectionBar","open","actions","placement","ariaLabel","ariaLabelledBy","className","trackRef","useRef","isMounted","setIsMounted","useState","isVisible","setIsVisible","frameRef","timerRef","useAdoptedStyleSheet","PILL_SHEET_CSS","PILL_SHEET_ID","useEffect","active","_a","PILL_TRANSITION_MS","isSticky","hasNotice","stickyClass","pill","PILL_SURFACE","PILL_SHADOW","jsx","index","Fragment","PILL_MUTED_TEXT","action","PILL_DIVIDER","jsxs","PILL_BUTTON_BASE","PILL_BUTTON_CLASS","PILL_TRACK_CLASS","PILL_NOTICE_SLEEVE","PILL_NOTICE_SHADOW","PILL_NOTICE_TEXT"],"mappings":"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"}
|
|
@@ -1,46 +1,30 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
onNavigateDown: a,
|
|
18
|
-
canNavigateUp: l = !1,
|
|
19
|
-
canNavigateDown: i = !1,
|
|
20
|
-
actions: c,
|
|
21
|
-
className: d = ""
|
|
22
|
-
}) => /* @__PURE__ */ r("div", { className: `flex w-full items-center justify-between ${d}`, children: [
|
|
23
|
-
/* @__PURE__ */ r("div", { className: "flex items-center gap-[8px]", children: [
|
|
24
|
-
/* @__PURE__ */ r("div", { className: "flex items-center gap-[4px]", children: [
|
|
25
|
-
/* @__PURE__ */ e(o, { ariaLabel: "Previous", onClick: t, disabled: !l, children: /* @__PURE__ */ e(m, { size: 11 }) }),
|
|
26
|
-
/* @__PURE__ */ e(o, { ariaLabel: "Next", onClick: a, disabled: !i, children: /* @__PURE__ */ e(p, { size: 11 }) })
|
|
1
|
+
import { jsxs as a, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import d from "./CustomIcons/CaretDownIcon.js";
|
|
3
|
+
import o from "./CustomIcons/CaretUpIcon.js";
|
|
4
|
+
import { Keycap as l } from "./Keycap.js";
|
|
5
|
+
const s = "text-[13px] font-medium tracking-[0.14px] text-[var(--malachite-text-secondary)]", N = ({
|
|
6
|
+
onNavigateUp: r,
|
|
7
|
+
onNavigateDown: t,
|
|
8
|
+
canNavigateUp: c = !1,
|
|
9
|
+
canNavigateDown: n = !1,
|
|
10
|
+
actions: i,
|
|
11
|
+
className: m = ""
|
|
12
|
+
}) => /* @__PURE__ */ a("div", { className: `flex w-full items-center justify-between ${m}`, children: [
|
|
13
|
+
/* @__PURE__ */ a("div", { className: "flex items-center gap-[8px]", children: [
|
|
14
|
+
/* @__PURE__ */ a("div", { className: "flex items-center gap-[4px]", children: [
|
|
15
|
+
/* @__PURE__ */ e(l, { "aria-label": "Previous", onClick: r, disabled: !c, children: /* @__PURE__ */ e(o, { size: 11 }) }),
|
|
16
|
+
/* @__PURE__ */ e(l, { "aria-label": "Next", onClick: t, disabled: !n, children: /* @__PURE__ */ e(d, { size: 11 }) })
|
|
27
17
|
] }),
|
|
28
18
|
/* @__PURE__ */ e("span", { className: s, children: "Navigate" }),
|
|
29
|
-
/* @__PURE__ */
|
|
30
|
-
/* @__PURE__ */ e(
|
|
31
|
-
"span",
|
|
32
|
-
{
|
|
33
|
-
className: `${n} px-[6px] text-[10px] font-medium uppercase tracking-[0.5px] text-[var(--malachite-text-placeholder)]`,
|
|
34
|
-
children: "esc"
|
|
35
|
-
}
|
|
36
|
-
),
|
|
19
|
+
/* @__PURE__ */ a("div", { className: "ml-[20px] flex items-center gap-[8px]", children: [
|
|
20
|
+
/* @__PURE__ */ e(l, { children: "esc" }),
|
|
37
21
|
/* @__PURE__ */ e("span", { className: s, children: "Close" })
|
|
38
22
|
] })
|
|
39
23
|
] }),
|
|
40
|
-
|
|
24
|
+
i ? /* @__PURE__ */ e("div", { className: "flex items-center", children: i }) : null
|
|
41
25
|
] });
|
|
42
26
|
export {
|
|
43
|
-
|
|
44
|
-
|
|
27
|
+
N as SidePanelNavFooter,
|
|
28
|
+
N as default
|
|
45
29
|
};
|
|
46
30
|
//# sourceMappingURL=SidePanelNavFooter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SidePanelNavFooter.js","sources":["../../src/components/SidePanelNavFooter.tsx"],"sourcesContent":["import React from 'react';\nimport CaretDownIcon from './CustomIcons/CaretDownIcon';\nimport CaretUpIcon from './CustomIcons/CaretUpIcon';\nimport
|
|
1
|
+
{"version":3,"file":"SidePanelNavFooter.js","sources":["../../src/components/SidePanelNavFooter.tsx"],"sourcesContent":["import React from 'react';\nimport CaretDownIcon from './CustomIcons/CaretDownIcon';\nimport CaretUpIcon from './CustomIcons/CaretUpIcon';\nimport Keycap from './Keycap';\n\nexport interface SidePanelNavFooterProps {\n onNavigateUp?: () => void;\n onNavigateDown?: () => void;\n canNavigateUp?: boolean;\n canNavigateDown?: boolean;\n actions?: React.ReactNode;\n className?: string;\n}\n\nconst LABEL = 'text-[13px] font-medium tracking-[0.14px] text-[var(--malachite-text-secondary)]';\n\nconst SidePanelNavFooter: React.FC<SidePanelNavFooterProps> = ({\n onNavigateUp,\n onNavigateDown,\n canNavigateUp = false,\n canNavigateDown = false,\n actions,\n className = '',\n}) => (\n <div className={`flex w-full items-center justify-between ${className}`}>\n <div className=\"flex items-center gap-[8px]\">\n <div className=\"flex items-center gap-[4px]\">\n <Keycap aria-label=\"Previous\" onClick={onNavigateUp} disabled={!canNavigateUp}>\n <CaretUpIcon size={11} />\n </Keycap>\n <Keycap aria-label=\"Next\" onClick={onNavigateDown} disabled={!canNavigateDown}>\n <CaretDownIcon size={11} />\n </Keycap>\n </div>\n <span className={LABEL}>Navigate</span>\n <div className=\"ml-[20px] flex items-center gap-[8px]\">\n <Keycap>esc</Keycap>\n <span className={LABEL}>Close</span>\n </div>\n </div>\n {actions ? <div className=\"flex items-center\">{actions}</div> : null}\n </div>\n);\n\nexport default SidePanelNavFooter;\nexport { SidePanelNavFooter };\n"],"names":["LABEL","SidePanelNavFooter","onNavigateUp","onNavigateDown","canNavigateUp","canNavigateDown","actions","className","jsxs","jsx","Keycap","CaretUpIcon","CaretDownIcon"],"mappings":";;;;AAcA,MAAMA,IAAQ,oFAERC,IAAwD,CAAC;AAAA,EAC3D,cAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,eAAAC,IAAgB;AAAA,EAChB,iBAAAC,IAAkB;AAAA,EAClB,SAAAC;AAAA,EACA,WAAAC,IAAY;AAChB,MACI,gBAAAC,EAAC,OAAA,EAAI,WAAW,4CAA4CD,CAAS,IACjE,UAAA;AAAA,EAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,+BACX,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,+BACX,UAAA;AAAA,MAAA,gBAAAC,EAACC,GAAA,EAAO,cAAW,YAAW,SAASR,GAAc,UAAU,CAACE,GAC5D,UAAA,gBAAAK,EAACE,GAAA,EAAY,MAAM,GAAA,CAAI,GAC3B;AAAA,MACA,gBAAAF,EAACC,GAAA,EAAO,cAAW,QAAO,SAASP,GAAgB,UAAU,CAACE,GAC1D,UAAA,gBAAAI,EAACG,GAAA,EAAc,MAAM,IAAI,EAAA,CAC7B;AAAA,IAAA,GACJ;AAAA,IACA,gBAAAH,EAAC,QAAA,EAAK,WAAWT,GAAO,UAAA,YAAQ;AAAA,IAChC,gBAAAQ,EAAC,OAAA,EAAI,WAAU,yCACX,UAAA;AAAA,MAAA,gBAAAC,EAACC,KAAO,UAAA,MAAA,CAAG;AAAA,MACX,gBAAAD,EAAC,QAAA,EAAK,WAAWT,GAAO,UAAA,QAAA,CAAK;AAAA,IAAA,EAAA,CACjC;AAAA,EAAA,GACJ;AAAA,EACCM,IAAU,gBAAAG,EAAC,OAAA,EAAI,WAAU,qBAAqB,aAAQ,IAAS;AAAA,EAAA,CACpE;"}
|