@stackone/malachite 2.58.0 → 2.60.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 -2
- package/dist/assets/icons/list_checks.svg.js +6 -0
- package/dist/assets/icons/list_checks.svg.js.map +1 -0
- package/dist/components/ConfirmationDialog.js +98 -98
- package/dist/components/ConfirmationDialog.js.map +1 -1
- package/dist/components/CustomIcons/ListChecksIcon.js +21 -0
- package/dist/components/CustomIcons/ListChecksIcon.js.map +1 -0
- package/dist/components/CustomIcons/index.js +159 -156
- package/dist/components/CustomIcons/index.js.map +1 -1
- package/dist/components/KeyValueList.js +60 -33
- package/dist/components/KeyValueList.js.map +1 -1
- package/dist/components/Search.js +65 -35
- package/dist/components/Search.js.map +1 -1
- package/dist/index.d.ts +78 -51
- package/dist/index.js +122 -120
- package/dist/index.js.map +1 -1
- package/dist/tailwind.css.js +1 -1
- package/package.json +1 -1
package/COMPONENTS.md
CHANGED
|
@@ -70,7 +70,7 @@ The catalog of components exported from `@stackone/malachite`. **Reach for one o
|
|
|
70
70
|
- **`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/tags/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.
|
|
71
71
|
- **`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.
|
|
72
72
|
- **`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.
|
|
73
|
-
- **`KeyValueList`** — Bordered card of label/value rows (`KeyValueList.Row`) for entity details: fixed-width secondary labels, free-form values, row dividers. `truncate` keeps a long value (an ID) to one line with an ellipsis at the cell width and a tooltip only when it is actually cut off — the value itself when it is text, else the row’s `tooltip` (`null` turns it off). For inline content only: a Tag or AppLogo is clipped without an ellipsis, so use its own truncate, as with `CodeText truncate`. _Key props:_ `label`, `truncate`, `tooltip`.
|
|
73
|
+
- **`KeyValueList`** — Bordered card of label/value rows (`KeyValueList.Row`) for entity details: fixed-width secondary labels, free-form values, row dividers. `truncate` keeps a long value (an ID) to one line with an ellipsis at the cell width and a tooltip only when it is actually cut off — the value itself when it is text, else the row’s `tooltip` (`null` turns it off). For inline content only: a Tag or AppLogo is clipped without an ellipsis, so use its own truncate, as with `CodeText truncate`. `size="small"` tightens the rows for a list inside a dialog or panel. _Key props:_ `size` (`small` | `medium`), `label`, `truncate`, `tooltip`.
|
|
74
74
|
|
|
75
75
|
## Forms & inputs
|
|
76
76
|
|
|
@@ -82,7 +82,7 @@ The catalog of components exported from `@stackone/malachite`. **Reach for one o
|
|
|
82
82
|
- **`FieldBlock`** — Something a form has to show but does not ask for — a computed list, a generated value — wearing a field’s anatomy: label, optional `badge` beside it and `action` at the end of the row, content, then helper text, all on a field’s own metrics and inset. A real control brings its anatomy with it; this is for everything that has no control to bring one. _Key props:_ `label`, `badge`, `action`, `helperText`, `children`, `className`, `style`.
|
|
83
83
|
- **`Input`** — Single-line text input. Passing `formControl` is enough to show validation: the resolver's message renders on its own line beneath the field in the destructive colour, politely announced, with `aria-invalid` and `aria-describedby` wired and the in-field error icon standing down once the message carries the meaning, and the control reports its edits back so a rejection clears as the customer fixes the field rather than standing until the next submit. Given a `formControl` the form owns the value: the field paints an explicit `value` first, then the value the form holds, then `defaultValue`, then empty — the ladder react-hook-form's own `useController` computes — so `reset()` and `setValue()` repaint the field and the text on screen cannot drift from the value being validated, which had put a rejection under a field the customer could see was filled. Passing `defaultValue` to a bound field warns in development, naming the component and the field: where the form has an entry for it, it is ignored, and where it has none it paints text the form will never submit. Set it through `useForm({ defaultValues })` instead. A consumer's own `helperText` keeps its line above it and stays dimmed, since it explains the field rather than reporting the fault — replacing one with the other left a field ringed in red with nothing saying what was wrong. An explicit `error` still wins, for a rejection the resolver knows nothing about, and `error={false}` suppresses the resolver outright, message included. `requiredIndicator` switches the label between the library default of naming the optional fields, an `asterisk` on the required ones for designs drawn that way, and `none` for a field whose value is supplied rather than asked for — a locked control is still required, but a marker only sends the reader looking for something to fill in. Visual only: `aria-required` is set from `required` whichever is chosen. _Key props:_ `label`, `type`, `InputSize`, `InputVariant` (`default` | `ghost`), `required`, `requiredIndicator`, `error`, `helperText`, `loading`, `formControl`, `value`, `defaultValue`, `showCopyButton`, `showPasswordToggle`, `aria-label`, `aria-labelledby`, `id`.
|
|
84
84
|
- **`TextArea`** — Multi-line text input. Shows resolver validation from `formControl` on exactly the same terms as `Input`: the message gets its own line beneath any `helperText`, which keeps its own, and the value climbs the same ladder — an explicit `value`, then the value the form holds, then `defaultValue`, then empty — a disabled field included, which used to show `defaultValue` whatever the form or the consumer had said. `requiredIndicator` switches the label between the library default of naming the optional fields, an `asterisk` on the required ones for designs drawn that way, and `none` for a field whose value is supplied rather than asked for — a locked control is still required, but a marker only sends the reader looking for something to fill in. Visual only: `aria-required` is set from `required` whichever is chosen. _Key props:_ `label`, `rows`, `maxLength`, `resize`, `required`, `requiredIndicator`, `error`, `helperText`, `loading`, `formControl`, `value`, `defaultValue`, `aria-label`, `aria-labelledby`, `id`.
|
|
85
|
-
- **`Search`** — Search input with a leading icon; `
|
|
85
|
+
- **`Search`** — Search input with a leading icon; `default` and `muted` variants. `width` fixes the field's width, the same prop `Dropdown` and `MultiSelect` take, so a toolbar can put its controls on one width rather than letting each size itself; without it the field fills its container, and a container narrower than the value still wins. `clearable` adds a clear button while there is text, and lets Escape clear; either way focus stays in the field, and an Escape that clears does not also close a surrounding panel. Name it with `aria-label` when the placeholder is too short to stand alone. Forwards a ref to the input. _Key props:_ `value`, `onChange`, `placeholder`, `variant`, `size`, `width`, `disabled`, `clearable`, `onClear`, `onKeyDown`, `aria-label`, `aria-labelledby`.
|
|
86
86
|
- **`Checkbox`** — Checkbox supporting checked/indeterminate/disabled. Pass `presentational` to render a visual-only, non-focusable indicator for use inside a clickable row/card. _Key props:_ `checked`, `indeterminate`, `disabled`, `onChange`, `presentational`.
|
|
87
87
|
- **`Radio`** — Single radio control with hover state; parent manages the group. Pass `presentational` to render a visual-only, non-focusable indicator for use inside a clickable row/card. _Key props:_ `checked`, `onChange`, `disabled`, `size`, `presentational`.
|
|
88
88
|
- **`SegmentedControl`** — A rounded track of mutually-exclusive options — the segmented “one of these” control. Owns the track background, the selected-thumb chrome and the `radiogroup` semantics, so consumers never hand-roll a track around `PillButton` (whose `default` variant tokens are tuned for standalone filter pills, not a sunken track). Single tab stop with arrow-key move-and-select; selection is conveyed via `aria-checked` and a foreground change, not background colour alone. An option `icon` sits before the label in a fixed 16px slot, and an option `badge` follows the label at whatever width it needs, for a mark such as a compact `Tag` naming a saving; it renders inside the segment button, so it must not be interactive. Restyle via the `segmentedControl` theme tokens. _Key props:_ `options` (`value`, `label`, `icon`, `badge`, `disabled`), `value`, `onChange`, `SegmentedControlSize` (`small` | `medium` | `large`), `fullWidth`, `disabled`, `aria-label`, `aria-labelledby`, `className`.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as a from "react";
|
|
2
|
+
const e = (l) => /* @__PURE__ */ a.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 256 256", fill: "currentColor", ...l }, /* @__PURE__ */ a.createElement("path", { d: "M224,128a8,8,0,0,1-8,8H128a8,8,0,0,1,0-16h88A8,8,0,0,1,224,128ZM128,72h88a8,8,0,0,0,0-16H128a8,8,0,0,0,0,16Zm88,112H128a8,8,0,0,0,0,16h88a8,8,0,0,0,0-16ZM82.34,42.34,56,68.69,45.66,58.34A8,8,0,0,0,34.34,69.66l16,16a8,8,0,0,0,11.32,0l32-32A8,8,0,0,0,82.34,42.34Zm0,64L56,132.69,45.66,122.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32,0l32-32a8,8,0,0,0-11.32-11.32Zm0,64L56,196.69,45.66,186.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32,0l32-32a8,8,0,0,0-11.32-11.32Z", fill: "currentColor" }));
|
|
3
|
+
export {
|
|
4
|
+
e as default
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=list_checks.svg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_checks.svg.js","sources":["../../../src/assets/icons/list_checks.svg?react"],"sourcesContent":["import * as React from \"react\";\nconst SvgListChecks = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", viewBox: \"0 0 256 256\", fill: \"currentColor\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M224,128a8,8,0,0,1-8,8H128a8,8,0,0,1,0-16h88A8,8,0,0,1,224,128ZM128,72h88a8,8,0,0,0,0-16H128a8,8,0,0,0,0,16Zm88,112H128a8,8,0,0,0,0,16h88a8,8,0,0,0,0-16ZM82.34,42.34,56,68.69,45.66,58.34A8,8,0,0,0,34.34,69.66l16,16a8,8,0,0,0,11.32,0l32-32A8,8,0,0,0,82.34,42.34Zm0,64L56,132.69,45.66,122.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32,0l32-32a8,8,0,0,0-11.32-11.32Zm0,64L56,196.69,45.66,186.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32,0l32-32a8,8,0,0,0-11.32-11.32Z\", fill: \"currentColor\" }));\nexport default SvgListChecks;\n"],"names":["SvgListChecks","props","React"],"mappings":";AACK,MAACA,IAAgB,CAACC,MAA0B,gBAAAC,EAAM,cAAc,OAAO,EAAE,OAAO,8BAA8B,SAAS,eAAe,MAAM,gBAAgB,GAAGD,EAAK,GAAoB,gBAAAC,EAAM,cAAc,QAAQ,EAAE,GAAG,udAAud,MAAM,gBAAgB,CAAC;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useState as
|
|
3
|
-
import { Button as
|
|
1
|
+
import { jsxs as p, jsx as o } from "react/jsx-runtime";
|
|
2
|
+
import { useState as _, useId as d, Children as U } from "react";
|
|
3
|
+
import { Button as N } from "./Button.js";
|
|
4
4
|
import X from "./CalloutStrip.js";
|
|
5
5
|
import P from "./CustomIcons/CheckCircleFilled.js";
|
|
6
6
|
import ee from "./CustomIcons/CheckmarkIcon.js";
|
|
@@ -11,192 +11,192 @@ import le from "./CustomIcons/WarningCircleFilled.js";
|
|
|
11
11
|
import { FieldMessage as re } from "./FieldMessage.js";
|
|
12
12
|
import { IconBadge as se } from "./IconBadge.js";
|
|
13
13
|
import { Modal as ae } from "./Modal.js";
|
|
14
|
-
import { Typography as
|
|
14
|
+
import { Typography as D } from "./Typography/index.js";
|
|
15
15
|
import { useClipboardCopy as ne } from "./useClipboardCopy.js";
|
|
16
16
|
import { CONFIRMATION_DIALOG_VARIANTS as ce } from "./confirmationDialogVariants.js";
|
|
17
17
|
import de from "./Input/Input.js";
|
|
18
|
-
const
|
|
18
|
+
const h = 12, v = (e) => e.replace(/\s+/g, " "), pe = (e, i) => {
|
|
19
19
|
const t = e.trim();
|
|
20
|
-
if (!(!
|
|
21
|
-
return
|
|
22
|
-
}, me = "Could not copy. Enter the phrase manually.", fe = (e,
|
|
20
|
+
if (!(!i || t === "" || t === i) && v(t).toLowerCase() === v(i).toLowerCase())
|
|
21
|
+
return v(t) === v(i) ? "The spacing has to match exactly." : "This is case-sensitive.";
|
|
22
|
+
}, me = "Could not copy. Enter the phrase manually.", fe = (e, i) => {
|
|
23
23
|
const t = typeof e == "object" && e !== null ? e : void 0;
|
|
24
|
-
return t ? { parts: t, text: [t.prefix,
|
|
25
|
-
}, ue = (e,
|
|
26
|
-
const { outcome:
|
|
24
|
+
return t ? { parts: t, text: [t.prefix, i, t.suffix].filter(Boolean).join(" ") } : { text: typeof e == "string" ? e : `Type ${i} to confirm` };
|
|
25
|
+
}, ue = (e, i) => e === "copied" ? `${i} copied to clipboard` : "", ye = (e, i, t, c) => {
|
|
26
|
+
const { outcome: m, canCopy: f, copy: a } = ne(`${i}|${e}`), s = async () => {
|
|
27
27
|
e && await a(e) && queueMicrotask(() => c == null ? void 0 : c(e));
|
|
28
28
|
};
|
|
29
|
-
return { outcome:
|
|
30
|
-
},
|
|
29
|
+
return { outcome: m, canCopy: f && !t, copy: () => void s() };
|
|
30
|
+
}, F = ({ children: e }) => /* @__PURE__ */ o(D.Text, { size: "small", color: "primary", children: e }), xe = ({
|
|
31
31
|
phrase: e,
|
|
32
|
-
parts:
|
|
32
|
+
parts: i,
|
|
33
33
|
plainLabel: t,
|
|
34
34
|
placeholder: c,
|
|
35
|
-
value:
|
|
36
|
-
onChange:
|
|
35
|
+
value: m,
|
|
36
|
+
onChange: f,
|
|
37
37
|
disabled: a,
|
|
38
|
-
copyLabel:
|
|
38
|
+
copyLabel: s,
|
|
39
39
|
copyOutcome: n,
|
|
40
40
|
canCopy: l,
|
|
41
|
-
onCopy:
|
|
42
|
-
nearMissMessage:
|
|
41
|
+
onCopy: I,
|
|
42
|
+
nearMissMessage: y
|
|
43
43
|
}) => {
|
|
44
|
-
const
|
|
45
|
-
return /* @__PURE__ */
|
|
46
|
-
|
|
47
|
-
/* @__PURE__ */
|
|
48
|
-
/* @__PURE__ */
|
|
44
|
+
const u = d(), x = d(), C = d(), b = d(), r = [y, n === "failed" ? me : void 0].filter(Boolean).join(" ") || void 0, g = i ? [u, i.suffix ? x : void 0].filter(Boolean).join(" ") : void 0;
|
|
45
|
+
return /* @__PURE__ */ p("div", { className: "flex flex-col gap-[6px]", children: [
|
|
46
|
+
i ? /* @__PURE__ */ p("div", { className: "flex flex-wrap items-center gap-[6px] px-2 text-[13px]", children: [
|
|
47
|
+
/* @__PURE__ */ p("span", { id: u, children: [
|
|
48
|
+
/* @__PURE__ */ o(F, { children: i.prefix }),
|
|
49
49
|
" ",
|
|
50
|
-
/* @__PURE__ */
|
|
50
|
+
/* @__PURE__ */ o(D.CodeText, { variant: "inline", children: e })
|
|
51
51
|
] }),
|
|
52
|
-
/* @__PURE__ */
|
|
53
|
-
|
|
52
|
+
/* @__PURE__ */ o(
|
|
53
|
+
N,
|
|
54
54
|
{
|
|
55
55
|
variant: "ghost",
|
|
56
56
|
size: "small",
|
|
57
57
|
iconOnly: !0,
|
|
58
|
-
"aria-label": `${
|
|
59
|
-
icon: n === "copied" ? /* @__PURE__ */
|
|
60
|
-
onClick:
|
|
58
|
+
"aria-label": `${s} ${e}`,
|
|
59
|
+
icon: n === "copied" ? /* @__PURE__ */ o(ee, { size: 13 }) : /* @__PURE__ */ o(oe, { size: 13 }),
|
|
60
|
+
onClick: I,
|
|
61
61
|
disabled: !l
|
|
62
62
|
}
|
|
63
63
|
),
|
|
64
|
-
|
|
65
|
-
] }) :
|
|
66
|
-
/* @__PURE__ */
|
|
64
|
+
i.suffix ? /* @__PURE__ */ o("span", { id: x, children: /* @__PURE__ */ o(F, { children: i.suffix }) }) : null
|
|
65
|
+
] }) : /* @__PURE__ */ o("label", { id: u, htmlFor: b, className: "px-2 text-[13px]", children: /* @__PURE__ */ o(F, { children: t }) }),
|
|
66
|
+
/* @__PURE__ */ o(
|
|
67
67
|
de,
|
|
68
68
|
{
|
|
69
|
+
id: b,
|
|
69
70
|
name: "confirmation-phrase",
|
|
70
|
-
size: "
|
|
71
|
-
value:
|
|
72
|
-
onChange:
|
|
73
|
-
|
|
74
|
-
"aria-labelledby": s,
|
|
71
|
+
size: "medium",
|
|
72
|
+
value: m,
|
|
73
|
+
onChange: f,
|
|
74
|
+
"aria-labelledby": g,
|
|
75
75
|
placeholder: c,
|
|
76
76
|
requiredIndicator: "none",
|
|
77
|
-
error: !!
|
|
78
|
-
"aria-describedby":
|
|
77
|
+
error: !!y,
|
|
78
|
+
"aria-describedby": r ? C : void 0,
|
|
79
79
|
disabled: a
|
|
80
80
|
}
|
|
81
81
|
),
|
|
82
|
-
/* @__PURE__ */
|
|
83
|
-
|
|
82
|
+
/* @__PURE__ */ o(re, { id: C, message: r }),
|
|
83
|
+
i ? /* @__PURE__ */ o("span", { role: "status", className: "sr-only", children: ue(n, e) }) : null
|
|
84
84
|
] });
|
|
85
85
|
}, Ce = {
|
|
86
|
-
default: /* @__PURE__ */
|
|
87
|
-
warning: /* @__PURE__ */
|
|
88
|
-
destructive: /* @__PURE__ */
|
|
89
|
-
success: /* @__PURE__ */
|
|
86
|
+
default: /* @__PURE__ */ o(te, { size: h }),
|
|
87
|
+
warning: /* @__PURE__ */ o(le, { size: h }),
|
|
88
|
+
destructive: /* @__PURE__ */ o(ie, { size: h }),
|
|
89
|
+
success: /* @__PURE__ */ o(P, { size: h })
|
|
90
90
|
}, Oe = ({
|
|
91
91
|
open: e,
|
|
92
|
-
onClose:
|
|
92
|
+
onClose: i,
|
|
93
93
|
onConfirm: t,
|
|
94
94
|
title: c,
|
|
95
|
-
titleAdornment:
|
|
96
|
-
badgeIcon:
|
|
95
|
+
titleAdornment: m,
|
|
96
|
+
badgeIcon: f,
|
|
97
97
|
description: a,
|
|
98
|
-
variant:
|
|
98
|
+
variant: s = "default",
|
|
99
99
|
callout: n,
|
|
100
100
|
confirmPhrase: l,
|
|
101
|
-
confirmPhraseLabel:
|
|
102
|
-
confirmPhraseCopyLabel:
|
|
103
|
-
onPhraseCopied:
|
|
101
|
+
confirmPhraseLabel: I,
|
|
102
|
+
confirmPhraseCopyLabel: y = "Copy",
|
|
103
|
+
onPhraseCopied: u,
|
|
104
104
|
confirmPhrasePlaceholder: x,
|
|
105
105
|
confirmLabel: C = "Confirm",
|
|
106
106
|
cancelLabel: b = "Cancel",
|
|
107
|
-
loading:
|
|
108
|
-
tip:
|
|
107
|
+
loading: r = !1,
|
|
108
|
+
tip: g,
|
|
109
109
|
size: M = "medium",
|
|
110
110
|
"aria-label": $,
|
|
111
111
|
"aria-labelledby": G,
|
|
112
|
-
children:
|
|
112
|
+
children: T
|
|
113
113
|
}) => {
|
|
114
|
-
const [
|
|
115
|
-
(
|
|
116
|
-
const { parts: V, text:
|
|
117
|
-
|
|
114
|
+
const [A, z] = _(""), L = d(), w = d(), B = ce[s], [S, R] = _({ open: e, confirmPhrase: l });
|
|
115
|
+
(S.open !== e || S.confirmPhrase !== l) && (R({ open: e, confirmPhrase: l }), e && z(""));
|
|
116
|
+
const { parts: V, text: j } = fe(
|
|
117
|
+
I,
|
|
118
118
|
l
|
|
119
119
|
), {
|
|
120
120
|
outcome: q,
|
|
121
|
-
canCopy:
|
|
122
|
-
copy:
|
|
123
|
-
} = ye(l, e,
|
|
124
|
-
(
|
|
125
|
-
),
|
|
126
|
-
/* @__PURE__ */
|
|
127
|
-
/* @__PURE__ */
|
|
128
|
-
|
|
121
|
+
canCopy: Y,
|
|
122
|
+
copy: H
|
|
123
|
+
} = ye(l, e, r, u), k = !l || A.trim() === l, W = pe(A, l), Z = r || !k, J = U.toArray(T).some(
|
|
124
|
+
(O) => typeof O != "string" || O.trim() !== ""
|
|
125
|
+
), E = !!a || J || !!l, K = [n ? w : null, a ? L : null].filter(Boolean).join(" ") || void 0, Q = /* @__PURE__ */ p("div", { className: "flex w-full flex-wrap items-center justify-end gap-[8px]", children: [
|
|
126
|
+
/* @__PURE__ */ o(N, { variant: "outline", size: "small", onClick: i, disabled: r, children: b }),
|
|
127
|
+
/* @__PURE__ */ o(
|
|
128
|
+
N,
|
|
129
129
|
{
|
|
130
|
-
variant:
|
|
130
|
+
variant: B.confirmVariant,
|
|
131
131
|
size: "small",
|
|
132
132
|
onClick: t,
|
|
133
133
|
disabled: Z,
|
|
134
|
-
loading:
|
|
135
|
-
tooltip: !
|
|
134
|
+
loading: r,
|
|
135
|
+
tooltip: !r && !k ? j : void 0,
|
|
136
136
|
children: C
|
|
137
137
|
}
|
|
138
138
|
)
|
|
139
139
|
] });
|
|
140
|
-
return /* @__PURE__ */
|
|
140
|
+
return /* @__PURE__ */ p(
|
|
141
141
|
ae,
|
|
142
142
|
{
|
|
143
143
|
open: e,
|
|
144
|
-
onClose:
|
|
144
|
+
onClose: i,
|
|
145
145
|
title: c,
|
|
146
146
|
size: M,
|
|
147
147
|
footer: Q,
|
|
148
|
-
busy:
|
|
149
|
-
role:
|
|
148
|
+
busy: r,
|
|
149
|
+
role: s === "destructive" ? "alertdialog" : "dialog",
|
|
150
150
|
"aria-label": $,
|
|
151
151
|
"aria-labelledby": G,
|
|
152
152
|
"aria-describedby": K,
|
|
153
|
-
closeOnOverlayClick:
|
|
153
|
+
closeOnOverlayClick: s !== "destructive" && !l,
|
|
154
154
|
headerDivider: !0,
|
|
155
|
-
titleAdornment:
|
|
155
|
+
titleAdornment: m,
|
|
156
156
|
bodyPadding: !1,
|
|
157
|
-
tray: { tone:
|
|
158
|
-
icon: /* @__PURE__ */
|
|
157
|
+
tray: { tone: B.tray, caption: g },
|
|
158
|
+
icon: /* @__PURE__ */ o(
|
|
159
159
|
se,
|
|
160
160
|
{
|
|
161
|
-
variant:
|
|
162
|
-
icon:
|
|
161
|
+
variant: s,
|
|
162
|
+
icon: f ?? Ce[s]
|
|
163
163
|
}
|
|
164
164
|
),
|
|
165
165
|
children: [
|
|
166
|
-
n ? /* @__PURE__ */
|
|
166
|
+
n ? /* @__PURE__ */ o(
|
|
167
167
|
X,
|
|
168
168
|
{
|
|
169
|
-
id:
|
|
170
|
-
type: n.type ??
|
|
169
|
+
id: w,
|
|
170
|
+
type: n.type ?? B.calloutType,
|
|
171
171
|
message: n.message,
|
|
172
|
-
divider:
|
|
172
|
+
divider: E
|
|
173
173
|
}
|
|
174
174
|
) : null,
|
|
175
|
-
|
|
176
|
-
a ? /* @__PURE__ */
|
|
175
|
+
E ? /* @__PURE__ */ p("div", { className: "flex flex-col gap-[12px] p-[28px]", children: [
|
|
176
|
+
a ? /* @__PURE__ */ o(
|
|
177
177
|
"div",
|
|
178
178
|
{
|
|
179
|
-
id:
|
|
179
|
+
id: L,
|
|
180
180
|
className: "text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]",
|
|
181
181
|
children: a
|
|
182
182
|
}
|
|
183
183
|
) : null,
|
|
184
|
-
|
|
185
|
-
l ? /* @__PURE__ */
|
|
184
|
+
T,
|
|
185
|
+
l ? /* @__PURE__ */ o(
|
|
186
186
|
xe,
|
|
187
187
|
{
|
|
188
188
|
phrase: l,
|
|
189
189
|
parts: V,
|
|
190
|
-
plainLabel:
|
|
190
|
+
plainLabel: j,
|
|
191
191
|
placeholder: x,
|
|
192
|
-
value:
|
|
193
|
-
onChange:
|
|
194
|
-
disabled:
|
|
195
|
-
copyLabel:
|
|
192
|
+
value: A,
|
|
193
|
+
onChange: z,
|
|
194
|
+
disabled: r,
|
|
195
|
+
copyLabel: y,
|
|
196
196
|
copyOutcome: q,
|
|
197
|
-
canCopy:
|
|
198
|
-
onCopy:
|
|
199
|
-
nearMissMessage:
|
|
197
|
+
canCopy: Y,
|
|
198
|
+
onCopy: H,
|
|
199
|
+
nearMissMessage: W
|
|
200
200
|
}
|
|
201
201
|
) : null
|
|
202
202
|
] }) : null
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmationDialog.js","sources":["../../src/components/ConfirmationDialog.tsx"],"sourcesContent":["import type React from 'react';\nimport { Children, useId, useState } from 'react';\nimport type { AlertType } from './Alert';\nimport Button from './Button';\nimport CalloutStrip from './CalloutStrip';\nimport CheckCircleFilled from './CustomIcons/CheckCircleFilled';\nimport CheckmarkIcon from './CustomIcons/CheckmarkIcon';\nimport CopyIcon from './CustomIcons/CopyIcon';\nimport ErrorCircleFilled from './CustomIcons/ErrorCircleFilled';\nimport InfoCircleFilled from './CustomIcons/InfoCircleFilled';\nimport WarningCircleFilled from './CustomIcons/WarningCircleFilled';\nimport FieldMessage from './FieldMessage';\nimport IconBadge from './IconBadge';\nimport { Input } from './Input';\nimport Modal, { type ModalSize } from './Modal';\nimport Typography from './Typography';\nimport { type CopyOutcome, useClipboardCopy } from './useClipboardCopy';\nimport {\n CONFIRMATION_DIALOG_VARIANTS,\n type ConfirmationDialogVariant,\n} from './confirmationDialogVariants';\n\n/** Kept beside the component: an icon is a node, not a value the variant table can hold. */\nconst BADGE_GLYPH_SIZE = 12;\n\nconst collapseSpaces = (value: string) => value.replace(/\\s+/g, ' ');\n\nconst nearMissAgainst = (typedPhrase: string, confirmPhrase?: string): string | undefined => {\n const typed = typedPhrase.trim();\n if (!confirmPhrase || typed === '' || typed === confirmPhrase) {\n return undefined;\n }\n if (collapseSpaces(typed).toLowerCase() !== collapseSpaces(confirmPhrase).toLowerCase()) {\n return undefined;\n }\n return collapseSpaces(typed) === collapseSpaces(confirmPhrase)\n ? 'The spacing has to match exactly.'\n : 'This is case-sensitive.';\n};\n\ntype PhraseLabel = string | { prefix: string; suffix?: string };\n\nconst COPY_FAILED_MESSAGE = 'Could not copy. Enter the phrase manually.';\n\nconst resolvePhraseLabel = (\n label: PhraseLabel | undefined,\n phrase?: string,\n): { parts?: { prefix: string; suffix?: string }; text: string } => {\n const parts = typeof label === 'object' && label !== null ? label : undefined;\n if (parts) {\n return { parts, text: [parts.prefix, phrase, parts.suffix].filter(Boolean).join(' ') };\n }\n return { text: typeof label === 'string' ? label : `Type ${phrase} to confirm` };\n};\n\nconst copyStatusFor = (outcome: CopyOutcome, phrase: string): string =>\n outcome === 'copied' ? `${phrase} copied to clipboard` : '';\n\nconst usePhraseCopy = (\n phrase: string | undefined,\n open: boolean,\n disabled: boolean,\n onCopied?: (phrase: string) => void,\n): { outcome: CopyOutcome; canCopy: boolean; copy: () => void } => {\n const { outcome, canCopy, copy } = useClipboardCopy(`${open}|${phrase}`);\n\n const run = async () => {\n if (phrase && (await copy(phrase))) {\n queueMicrotask(() => onCopied?.(phrase));\n }\n };\n\n return { outcome, canCopy: canCopy && !disabled, copy: () => void run() };\n};\n\nconst LabelText: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <Typography.Text size=\"xsmall\" color=\"primary\" fontWeight=\"semi-bold\">\n {children}\n </Typography.Text>\n);\n\ninterface PhraseFieldProps {\n phrase: string;\n parts?: { prefix: string; suffix?: string };\n plainLabel: string;\n placeholder?: string;\n value: string;\n onChange: (value: string) => void;\n disabled: boolean;\n copyLabel: string;\n copyOutcome: CopyOutcome;\n canCopy: boolean;\n onCopy: () => void;\n nearMissMessage?: string;\n}\n\nconst PhraseField: React.FC<PhraseFieldProps> = ({\n phrase,\n parts,\n plainLabel,\n placeholder,\n value,\n onChange,\n disabled,\n copyLabel,\n copyOutcome,\n canCopy,\n onCopy,\n nearMissMessage,\n}) => {\n const beforeId = useId();\n const afterId = useId();\n const messageId = useId();\n const message =\n [nearMissMessage, copyOutcome === 'failed' ? COPY_FAILED_MESSAGE : undefined]\n .filter(Boolean)\n .join(' ') || undefined;\n const labelledBy = parts\n ? [beforeId, parts.suffix ? afterId : undefined].filter(Boolean).join(' ')\n : undefined;\n\n return (\n <div className=\"flex flex-col gap-[6px]\">\n {parts ? (\n <div className=\"flex flex-wrap items-center gap-[6px] px-2\">\n <span id={beforeId}>\n <LabelText>{parts.prefix}</LabelText>{' '}\n <Typography.CodeText variant=\"inline\" size=\"small\">\n {phrase}\n </Typography.CodeText>\n </span>\n <Button\n variant=\"ghost\"\n size=\"small\"\n iconOnly\n aria-label={`${copyLabel} ${phrase}`}\n icon={\n copyOutcome === 'copied' ? (\n <CheckmarkIcon size={13} />\n ) : (\n <CopyIcon size={13} />\n )\n }\n onClick={onCopy}\n disabled={!canCopy}\n />\n {parts.suffix ? (\n <span id={afterId}>\n <LabelText>{parts.suffix}</LabelText>\n </span>\n ) : null}\n </div>\n ) : null}\n <Input\n name=\"confirmation-phrase\"\n size=\"large\"\n value={value}\n onChange={onChange}\n label={parts ? undefined : plainLabel}\n aria-labelledby={labelledBy}\n placeholder={placeholder}\n requiredIndicator=\"none\"\n error={!!nearMissMessage}\n aria-describedby={message ? messageId : undefined}\n disabled={disabled}\n />\n <FieldMessage id={messageId} message={message} />\n {parts ? (\n <span role=\"status\" className=\"sr-only\">\n {copyStatusFor(copyOutcome, phrase)}\n </span>\n ) : null}\n </div>\n );\n};\n\nconst VARIANT_ICON: Record<ConfirmationDialogVariant, React.ReactNode> = {\n default: <InfoCircleFilled size={BADGE_GLYPH_SIZE} />,\n warning: <WarningCircleFilled size={BADGE_GLYPH_SIZE} />,\n destructive: <ErrorCircleFilled size={BADGE_GLYPH_SIZE} />,\n success: <CheckCircleFilled size={BADGE_GLYPH_SIZE} />,\n};\n\nexport interface ConfirmationDialogProps {\n open: boolean;\n /** Dismiss handler — cancel, close button, ESC or scrim. `loading` suppresses every\n * route except ESC, which always reaches this so a keyboard user is never stranded. */\n onClose: () => void;\n /** Runs when the confirm action is taken. Closing is left to the consumer. */\n onConfirm: () => void;\n title: React.ReactNode;\n titleAdornment?: React.ReactNode;\n badgeIcon?: React.ReactNode;\n /** The sentence saying what is about to happen. */\n description?: React.ReactNode;\n variant?: ConfirmationDialogVariant;\n /** Coloured callout below the body. Defaults to the variant's own type. */\n callout?: { type?: AlertType; message: string };\n /**\n * Requires this exact phrase to be typed before the confirm action enables — for a\n * consequence severe enough that a single click should not be able to cause it.\n */\n confirmPhrase?: string;\n /** Label above the type-to-confirm field. `{ prefix, suffix }` makes the phrase copyable. */\n confirmPhraseLabel?: PhraseLabel;\n /** Names the copy control, e.g. `Copy profile name`. Default: `Copy`. */\n confirmPhraseCopyLabel?: string;\n /** Runs after the phrase reaches the clipboard, with what was copied. */\n onPhraseCopied?: (phrase: string) => void;\n confirmPhrasePlaceholder?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n /**\n * Disables the actions, spins the confirm button and suppresses the pointer dismissal\n * routes — but never ESC, which always reaches `onClose`.\n */\n loading?: boolean;\n tip?: { label?: string; message: string };\n size?: ModalSize;\n /** Accessible dialog name; required when `title` isn't a plain string. */\n 'aria-label'?: string;\n /** ID of a visible element naming the dialog (alternative to `aria-label`). */\n 'aria-labelledby'?: string;\n /** Extra body content between the description and the callout, e.g. an entity chip. */\n children?: React.ReactNode;\n}\n\nconst ConfirmationDialog: React.FC<ConfirmationDialogProps> = ({\n open,\n onClose,\n onConfirm,\n title,\n titleAdornment,\n badgeIcon,\n description,\n variant = 'default',\n callout,\n confirmPhrase,\n confirmPhraseLabel,\n confirmPhraseCopyLabel = 'Copy',\n onPhraseCopied,\n confirmPhrasePlaceholder,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n loading = false,\n tip,\n size = 'medium',\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n children,\n}) => {\n const [typedPhrase, setTypedPhrase] = useState('');\n const descriptionId = useId();\n const calloutId = useId();\n const base = CONFIRMATION_DIALOG_VARIANTS[variant];\n\n // On open, not close: the dialog outlives `open` by its exit transition, so resetting on\n // close empties the field in front of the user. Adjusted during render rather than from an\n // effect, or a reopen paints the previous answer once with confirm already enabled.\n const [answeredFor, setAnsweredFor] = useState({ open, confirmPhrase });\n if (answeredFor.open !== open || answeredFor.confirmPhrase !== confirmPhrase) {\n setAnsweredFor({ open, confirmPhrase });\n if (open) {\n setTypedPhrase('');\n }\n }\n\n const { parts: phraseParts, text: phraseLabel } = resolvePhraseLabel(\n confirmPhraseLabel,\n confirmPhrase,\n );\n const {\n outcome: copyOutcome,\n canCopy: canCopyPhrase,\n copy: handleCopyPhrase,\n } = usePhraseCopy(confirmPhrase, open, loading, onPhraseCopied);\n // Trimmed because copying an entity name commonly picks up a trailing space; the gate is\n // still exact, and deliberately case-sensitive.\n const phraseSatisfied = !confirmPhrase || typedPhrase.trim() === confirmPhrase;\n const nearMissMessage = nearMissAgainst(typedPhrase, confirmPhrase);\n const confirmDisabled = loading || !phraseSatisfied;\n const hasChildren = Children.toArray(children).some(\n (child) => typeof child !== 'string' || child.trim() !== '',\n );\n const hasBody = Boolean(description) || hasChildren || Boolean(confirmPhrase);\n // The callout is often the whole consequence, so it is announced along with the description.\n const describedBy =\n [callout ? calloutId : null, description ? descriptionId : null]\n .filter(Boolean)\n .join(' ') || undefined;\n\n const footer = (\n <div className=\"flex w-full flex-wrap items-center justify-end gap-[8px]\">\n <Button variant=\"outline\" size=\"small\" onClick={onClose} disabled={loading}>\n {cancelLabel}\n </Button>\n <Button\n variant={base.confirmVariant}\n size=\"small\"\n onClick={onConfirm}\n disabled={confirmDisabled}\n loading={loading}\n // A disabled control emits no hover, so the tooltip explains the gate from the\n // wrapper Button renders for exactly this case.\n tooltip={!loading && !phraseSatisfied ? phraseLabel : undefined}\n >\n {confirmLabel}\n </Button>\n </div>\n );\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n title={title}\n size={size}\n footer={footer}\n busy={loading}\n // A consequential choice is an alertdialog: it asks assistive tech to announce the\n // body, which is where the consequence is written.\n role={variant === 'destructive' ? 'alertdialog' : 'dialog'}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={describedBy}\n // A choice this deliberate should not be undone by a stray click, and a scrim\n // click must not discard a phrase the customer has already typed.\n closeOnOverlayClick={variant !== 'destructive' && !confirmPhrase}\n headerDivider\n titleAdornment={titleAdornment}\n bodyPadding={false}\n tray={{ tone: base.tray, caption: tip }}\n icon={\n <IconBadge\n variant={variant}\n icon={badgeIcon ?? VARIANT_ICON[variant]}\n />\n }\n >\n {callout ? (\n <CalloutStrip\n id={calloutId}\n type={callout.type ?? base.calloutType}\n message={callout.message}\n divider={hasBody}\n />\n ) : null}\n {hasBody ? (\n <div className=\"flex flex-col gap-[12px] p-[28px]\">\n {description ? (\n <div\n id={descriptionId}\n className=\"text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]\"\n >\n {description}\n </div>\n ) : null}\n {children}\n {confirmPhrase ? (\n <PhraseField\n phrase={confirmPhrase}\n parts={phraseParts}\n plainLabel={phraseLabel}\n placeholder={confirmPhrasePlaceholder}\n value={typedPhrase}\n onChange={setTypedPhrase}\n disabled={loading}\n copyLabel={confirmPhraseCopyLabel}\n copyOutcome={copyOutcome}\n canCopy={canCopyPhrase}\n onCopy={handleCopyPhrase}\n nearMissMessage={nearMissMessage}\n />\n ) : null}\n </div>\n ) : null}\n </Modal>\n );\n};\n\nexport default ConfirmationDialog;\nexport { ConfirmationDialog };\nexport type { ConfirmationDialogVariant };\n"],"names":["BADGE_GLYPH_SIZE","collapseSpaces","value","nearMissAgainst","typedPhrase","confirmPhrase","typed","COPY_FAILED_MESSAGE","resolvePhraseLabel","label","phrase","parts","copyStatusFor","outcome","usePhraseCopy","open","disabled","onCopied","canCopy","copy","useClipboardCopy","run","LabelText","children","jsx","Typography","PhraseField","plainLabel","placeholder","onChange","copyLabel","copyOutcome","onCopy","nearMissMessage","beforeId","useId","afterId","messageId","message","labelledBy","jsxs","Button","CheckmarkIcon","CopyIcon","Input","FieldMessage","VARIANT_ICON","InfoCircleFilled","WarningCircleFilled","ErrorCircleFilled","CheckCircleFilled","ConfirmationDialog","onClose","onConfirm","title","titleAdornment","badgeIcon","description","variant","callout","confirmPhraseLabel","confirmPhraseCopyLabel","onPhraseCopied","confirmPhrasePlaceholder","confirmLabel","cancelLabel","loading","tip","size","ariaLabel","ariaLabelledBy","setTypedPhrase","useState","descriptionId","calloutId","base","CONFIRMATION_DIALOG_VARIANTS","answeredFor","setAnsweredFor","phraseParts","phraseLabel","canCopyPhrase","handleCopyPhrase","phraseSatisfied","confirmDisabled","hasChildren","Children","child","hasBody","describedBy","footer","Modal","IconBadge","CalloutStrip"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ConfirmationDialog.js","sources":["../../src/components/ConfirmationDialog.tsx"],"sourcesContent":["import type React from 'react';\nimport { Children, useId, useState } from 'react';\nimport type { AlertType } from './Alert';\nimport Button from './Button';\nimport CalloutStrip from './CalloutStrip';\nimport CheckCircleFilled from './CustomIcons/CheckCircleFilled';\nimport CheckmarkIcon from './CustomIcons/CheckmarkIcon';\nimport CopyIcon from './CustomIcons/CopyIcon';\nimport ErrorCircleFilled from './CustomIcons/ErrorCircleFilled';\nimport InfoCircleFilled from './CustomIcons/InfoCircleFilled';\nimport WarningCircleFilled from './CustomIcons/WarningCircleFilled';\nimport FieldMessage from './FieldMessage';\nimport IconBadge from './IconBadge';\nimport { Input } from './Input';\nimport Modal, { type ModalSize } from './Modal';\nimport Typography from './Typography';\nimport { type CopyOutcome, useClipboardCopy } from './useClipboardCopy';\nimport {\n CONFIRMATION_DIALOG_VARIANTS,\n type ConfirmationDialogVariant,\n} from './confirmationDialogVariants';\n\n/** Kept beside the component: an icon is a node, not a value the variant table can hold. */\nconst BADGE_GLYPH_SIZE = 12;\n\nconst collapseSpaces = (value: string) => value.replace(/\\s+/g, ' ');\n\nconst nearMissAgainst = (typedPhrase: string, confirmPhrase?: string): string | undefined => {\n const typed = typedPhrase.trim();\n if (!confirmPhrase || typed === '' || typed === confirmPhrase) {\n return undefined;\n }\n if (collapseSpaces(typed).toLowerCase() !== collapseSpaces(confirmPhrase).toLowerCase()) {\n return undefined;\n }\n return collapseSpaces(typed) === collapseSpaces(confirmPhrase)\n ? 'The spacing has to match exactly.'\n : 'This is case-sensitive.';\n};\n\ntype PhraseLabel = string | { prefix: string; suffix?: string };\n\nconst COPY_FAILED_MESSAGE = 'Could not copy. Enter the phrase manually.';\n\nconst resolvePhraseLabel = (\n label: PhraseLabel | undefined,\n phrase?: string,\n): { parts?: { prefix: string; suffix?: string }; text: string } => {\n const parts = typeof label === 'object' && label !== null ? label : undefined;\n if (parts) {\n return { parts, text: [parts.prefix, phrase, parts.suffix].filter(Boolean).join(' ') };\n }\n return { text: typeof label === 'string' ? label : `Type ${phrase} to confirm` };\n};\n\nconst copyStatusFor = (outcome: CopyOutcome, phrase: string): string =>\n outcome === 'copied' ? `${phrase} copied to clipboard` : '';\n\nconst usePhraseCopy = (\n phrase: string | undefined,\n open: boolean,\n disabled: boolean,\n onCopied?: (phrase: string) => void,\n): { outcome: CopyOutcome; canCopy: boolean; copy: () => void } => {\n const { outcome, canCopy, copy } = useClipboardCopy(`${open}|${phrase}`);\n\n const run = async () => {\n if (phrase && (await copy(phrase))) {\n queueMicrotask(() => onCopied?.(phrase));\n }\n };\n\n return { outcome, canCopy: canCopy && !disabled, copy: () => void run() };\n};\n\nconst LabelText: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <Typography.Text size=\"small\" color=\"primary\">\n {children}\n </Typography.Text>\n);\n\ninterface PhraseFieldProps {\n phrase: string;\n parts?: { prefix: string; suffix?: string };\n plainLabel: string;\n placeholder?: string;\n value: string;\n onChange: (value: string) => void;\n disabled: boolean;\n copyLabel: string;\n copyOutcome: CopyOutcome;\n canCopy: boolean;\n onCopy: () => void;\n nearMissMessage?: string;\n}\n\nconst PhraseField: React.FC<PhraseFieldProps> = ({\n phrase,\n parts,\n plainLabel,\n placeholder,\n value,\n onChange,\n disabled,\n copyLabel,\n copyOutcome,\n canCopy,\n onCopy,\n nearMissMessage,\n}) => {\n const beforeId = useId();\n const afterId = useId();\n const messageId = useId();\n const inputId = useId();\n const message =\n [nearMissMessage, copyOutcome === 'failed' ? COPY_FAILED_MESSAGE : undefined]\n .filter(Boolean)\n .join(' ') || undefined;\n const labelledBy = parts\n ? [beforeId, parts.suffix ? afterId : undefined].filter(Boolean).join(' ')\n : undefined;\n\n return (\n <div className=\"flex flex-col gap-[6px]\">\n {parts ? (\n <div className=\"flex flex-wrap items-center gap-[6px] px-2 text-[13px]\">\n <span id={beforeId}>\n <LabelText>{parts.prefix}</LabelText>{' '}\n <Typography.CodeText variant=\"inline\">\n {phrase}\n </Typography.CodeText>\n </span>\n <Button\n variant=\"ghost\"\n size=\"small\"\n iconOnly\n aria-label={`${copyLabel} ${phrase}`}\n icon={\n copyOutcome === 'copied' ? (\n <CheckmarkIcon size={13} />\n ) : (\n <CopyIcon size={13} />\n )\n }\n onClick={onCopy}\n disabled={!canCopy}\n />\n {parts.suffix ? (\n <span id={afterId}>\n <LabelText>{parts.suffix}</LabelText>\n </span>\n ) : null}\n </div>\n ) : (\n <label id={beforeId} htmlFor={inputId} className=\"px-2 text-[13px]\">\n <LabelText>{plainLabel}</LabelText>\n </label>\n )}\n <Input\n id={inputId}\n name=\"confirmation-phrase\"\n size=\"medium\"\n value={value}\n onChange={onChange}\n aria-labelledby={labelledBy}\n placeholder={placeholder}\n requiredIndicator=\"none\"\n error={!!nearMissMessage}\n aria-describedby={message ? messageId : undefined}\n disabled={disabled}\n />\n <FieldMessage id={messageId} message={message} />\n {parts ? (\n <span role=\"status\" className=\"sr-only\">\n {copyStatusFor(copyOutcome, phrase)}\n </span>\n ) : null}\n </div>\n );\n};\n\nconst VARIANT_ICON: Record<ConfirmationDialogVariant, React.ReactNode> = {\n default: <InfoCircleFilled size={BADGE_GLYPH_SIZE} />,\n warning: <WarningCircleFilled size={BADGE_GLYPH_SIZE} />,\n destructive: <ErrorCircleFilled size={BADGE_GLYPH_SIZE} />,\n success: <CheckCircleFilled size={BADGE_GLYPH_SIZE} />,\n};\n\nexport interface ConfirmationDialogProps {\n open: boolean;\n /** Dismiss handler — cancel, close button, ESC or scrim. `loading` suppresses every\n * route except ESC, which always reaches this so a keyboard user is never stranded. */\n onClose: () => void;\n /** Runs when the confirm action is taken. Closing is left to the consumer. */\n onConfirm: () => void;\n title: React.ReactNode;\n titleAdornment?: React.ReactNode;\n badgeIcon?: React.ReactNode;\n /** The sentence saying what is about to happen. */\n description?: React.ReactNode;\n variant?: ConfirmationDialogVariant;\n /** Coloured callout below the body. Defaults to the variant's own type. */\n callout?: { type?: AlertType; message: string };\n /**\n * Requires this exact phrase to be typed before the confirm action enables — for a\n * consequence severe enough that a single click should not be able to cause it.\n */\n confirmPhrase?: string;\n /** Label above the type-to-confirm field. `{ prefix, suffix }` makes the phrase copyable. */\n confirmPhraseLabel?: PhraseLabel;\n /** Names the copy control, e.g. `Copy profile name`. Default: `Copy`. */\n confirmPhraseCopyLabel?: string;\n /** Runs after the phrase reaches the clipboard, with what was copied. */\n onPhraseCopied?: (phrase: string) => void;\n confirmPhrasePlaceholder?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n /**\n * Disables the actions, spins the confirm button and suppresses the pointer dismissal\n * routes — but never ESC, which always reaches `onClose`.\n */\n loading?: boolean;\n tip?: { label?: string; message: string };\n size?: ModalSize;\n /** Accessible dialog name; required when `title` isn't a plain string. */\n 'aria-label'?: string;\n /** ID of a visible element naming the dialog (alternative to `aria-label`). */\n 'aria-labelledby'?: string;\n /** Extra body content between the description and the callout, e.g. an entity chip. */\n children?: React.ReactNode;\n}\n\nconst ConfirmationDialog: React.FC<ConfirmationDialogProps> = ({\n open,\n onClose,\n onConfirm,\n title,\n titleAdornment,\n badgeIcon,\n description,\n variant = 'default',\n callout,\n confirmPhrase,\n confirmPhraseLabel,\n confirmPhraseCopyLabel = 'Copy',\n onPhraseCopied,\n confirmPhrasePlaceholder,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n loading = false,\n tip,\n size = 'medium',\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n children,\n}) => {\n const [typedPhrase, setTypedPhrase] = useState('');\n const descriptionId = useId();\n const calloutId = useId();\n const base = CONFIRMATION_DIALOG_VARIANTS[variant];\n\n // On open, not close: the dialog outlives `open` by its exit transition, so resetting on\n // close empties the field in front of the user. Adjusted during render rather than from an\n // effect, or a reopen paints the previous answer once with confirm already enabled.\n const [answeredFor, setAnsweredFor] = useState({ open, confirmPhrase });\n if (answeredFor.open !== open || answeredFor.confirmPhrase !== confirmPhrase) {\n setAnsweredFor({ open, confirmPhrase });\n if (open) {\n setTypedPhrase('');\n }\n }\n\n const { parts: phraseParts, text: phraseLabel } = resolvePhraseLabel(\n confirmPhraseLabel,\n confirmPhrase,\n );\n const {\n outcome: copyOutcome,\n canCopy: canCopyPhrase,\n copy: handleCopyPhrase,\n } = usePhraseCopy(confirmPhrase, open, loading, onPhraseCopied);\n // Trimmed because copying an entity name commonly picks up a trailing space; the gate is\n // still exact, and deliberately case-sensitive.\n const phraseSatisfied = !confirmPhrase || typedPhrase.trim() === confirmPhrase;\n const nearMissMessage = nearMissAgainst(typedPhrase, confirmPhrase);\n const confirmDisabled = loading || !phraseSatisfied;\n const hasChildren = Children.toArray(children).some(\n (child) => typeof child !== 'string' || child.trim() !== '',\n );\n const hasBody = Boolean(description) || hasChildren || Boolean(confirmPhrase);\n // The callout is often the whole consequence, so it is announced along with the description.\n const describedBy =\n [callout ? calloutId : null, description ? descriptionId : null]\n .filter(Boolean)\n .join(' ') || undefined;\n\n const footer = (\n <div className=\"flex w-full flex-wrap items-center justify-end gap-[8px]\">\n <Button variant=\"outline\" size=\"small\" onClick={onClose} disabled={loading}>\n {cancelLabel}\n </Button>\n <Button\n variant={base.confirmVariant}\n size=\"small\"\n onClick={onConfirm}\n disabled={confirmDisabled}\n loading={loading}\n // A disabled control emits no hover, so the tooltip explains the gate from the\n // wrapper Button renders for exactly this case.\n tooltip={!loading && !phraseSatisfied ? phraseLabel : undefined}\n >\n {confirmLabel}\n </Button>\n </div>\n );\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n title={title}\n size={size}\n footer={footer}\n busy={loading}\n // A consequential choice is an alertdialog: it asks assistive tech to announce the\n // body, which is where the consequence is written.\n role={variant === 'destructive' ? 'alertdialog' : 'dialog'}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={describedBy}\n // A choice this deliberate should not be undone by a stray click, and a scrim\n // click must not discard a phrase the customer has already typed.\n closeOnOverlayClick={variant !== 'destructive' && !confirmPhrase}\n headerDivider\n titleAdornment={titleAdornment}\n bodyPadding={false}\n tray={{ tone: base.tray, caption: tip }}\n icon={\n <IconBadge\n variant={variant}\n icon={badgeIcon ?? VARIANT_ICON[variant]}\n />\n }\n >\n {callout ? (\n <CalloutStrip\n id={calloutId}\n type={callout.type ?? base.calloutType}\n message={callout.message}\n divider={hasBody}\n />\n ) : null}\n {hasBody ? (\n <div className=\"flex flex-col gap-[12px] p-[28px]\">\n {description ? (\n <div\n id={descriptionId}\n className=\"text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]\"\n >\n {description}\n </div>\n ) : null}\n {children}\n {confirmPhrase ? (\n <PhraseField\n phrase={confirmPhrase}\n parts={phraseParts}\n plainLabel={phraseLabel}\n placeholder={confirmPhrasePlaceholder}\n value={typedPhrase}\n onChange={setTypedPhrase}\n disabled={loading}\n copyLabel={confirmPhraseCopyLabel}\n copyOutcome={copyOutcome}\n canCopy={canCopyPhrase}\n onCopy={handleCopyPhrase}\n nearMissMessage={nearMissMessage}\n />\n ) : null}\n </div>\n ) : null}\n </Modal>\n );\n};\n\nexport default ConfirmationDialog;\nexport { ConfirmationDialog };\nexport type { ConfirmationDialogVariant };\n"],"names":["BADGE_GLYPH_SIZE","collapseSpaces","value","nearMissAgainst","typedPhrase","confirmPhrase","typed","COPY_FAILED_MESSAGE","resolvePhraseLabel","label","phrase","parts","copyStatusFor","outcome","usePhraseCopy","open","disabled","onCopied","canCopy","copy","useClipboardCopy","run","LabelText","children","jsx","Typography","PhraseField","plainLabel","placeholder","onChange","copyLabel","copyOutcome","onCopy","nearMissMessage","beforeId","useId","afterId","messageId","inputId","message","labelledBy","jsxs","Button","CheckmarkIcon","CopyIcon","Input","FieldMessage","VARIANT_ICON","InfoCircleFilled","WarningCircleFilled","ErrorCircleFilled","CheckCircleFilled","ConfirmationDialog","onClose","onConfirm","title","titleAdornment","badgeIcon","description","variant","callout","confirmPhraseLabel","confirmPhraseCopyLabel","onPhraseCopied","confirmPhrasePlaceholder","confirmLabel","cancelLabel","loading","tip","size","ariaLabel","ariaLabelledBy","setTypedPhrase","useState","descriptionId","calloutId","base","CONFIRMATION_DIALOG_VARIANTS","answeredFor","setAnsweredFor","phraseParts","phraseLabel","canCopyPhrase","handleCopyPhrase","phraseSatisfied","confirmDisabled","hasChildren","Children","child","hasBody","describedBy","footer","Modal","IconBadge","CalloutStrip"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as l } from "react/jsx-runtime";
|
|
2
|
+
import c from "../../assets/icons/list_checks.svg.js";
|
|
3
|
+
const i = ({
|
|
4
|
+
size: t = 16,
|
|
5
|
+
className: o = "",
|
|
6
|
+
style: r = {},
|
|
7
|
+
onClick: n
|
|
8
|
+
}) => {
|
|
9
|
+
const e = {
|
|
10
|
+
width: typeof t == "number" ? `${t}px` : t,
|
|
11
|
+
height: typeof t == "number" ? `${t}px` : t,
|
|
12
|
+
display: "inline-block",
|
|
13
|
+
fill: "currentColor",
|
|
14
|
+
...r
|
|
15
|
+
};
|
|
16
|
+
return /* @__PURE__ */ l(c, { className: o, style: e, onClick: n });
|
|
17
|
+
};
|
|
18
|
+
export {
|
|
19
|
+
i as default
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=ListChecksIcon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListChecksIcon.js","sources":["../../../src/components/CustomIcons/ListChecksIcon.tsx"],"sourcesContent":["import type { CSSProperties } from 'react';\nimport ListChecksIconSvg from '../../assets/icons/list_checks.svg?react';\n\nexport interface IconProps {\n size?: number | string;\n className?: string;\n style?: CSSProperties;\n onClick?: () => void;\n}\n\nconst ListChecksIcon: React.FC<IconProps> = ({\n size = 16,\n className = '',\n style = {},\n onClick,\n}) => {\n const iconStyle: CSSProperties = {\n width: typeof size === 'number' ? `${size}px` : size,\n height: typeof size === 'number' ? `${size}px` : size,\n display: 'inline-block',\n fill: 'currentColor',\n ...style,\n };\n\n return <ListChecksIconSvg className={className} style={iconStyle} onClick={onClick} />;\n};\n\nexport default ListChecksIcon;\n"],"names":["ListChecksIcon","size","className","style","onClick","iconStyle","jsx","ListChecksIconSvg"],"mappings":";;AAUA,MAAMA,IAAsC,CAAC;AAAA,EACzC,MAAAC,IAAO;AAAA,EACP,WAAAC,IAAY;AAAA,EACZ,OAAAC,IAAQ,CAAA;AAAA,EACR,SAAAC;AACJ,MAAM;AACF,QAAMC,IAA2B;AAAA,IAC7B,OAAO,OAAOJ,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IAChD,QAAQ,OAAOA,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IACjD,SAAS;AAAA,IACT,MAAM;AAAA,IACN,GAAGE;AAAA,EAAA;AAGP,SAAO,gBAAAG,EAACC,GAAA,EAAkB,WAAAL,GAAsB,OAAOG,GAAW,SAAAD,GAAkB;AACxF;"}
|