@godxjp/ui 23.4.8 → 23.4.9
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/dist/components/feedback/dialog.d.ts +2 -1
- package/dist/components/feedback/dialog.js +9 -6
- package/dist/contracts/measurement.json +1 -1
- package/dist/styles/control.css +4 -0
- package/dist/styles/dialog-layout.css +22 -1
- package/dist/styles/layout.css +5 -5
- package/dist/tokens/components/feedback.css +3 -0
- package/docs/feedback/danger-confirm.tsx +6 -3
- package/package.json +2 -2
|
@@ -142,7 +142,8 @@ declare const AlertDialogAction: typeof DialogAction;
|
|
|
142
142
|
declare const AlertDialogCancel: typeof DialogCancel;
|
|
143
143
|
/**
|
|
144
144
|
* Preset: confirm / destructive / typed-challenge / step-up without compound markup. Both flows
|
|
145
|
-
* force the destructive
|
|
145
|
+
* force the destructive shape: the confirm button plus antd's leading status glyph. The header
|
|
146
|
+
* surface stays untinted — see the note on `showDangerIcon` below.
|
|
146
147
|
*/
|
|
147
148
|
declare function AlertDialog({ open, onOpenChange, title, description, confirmLabel, cancelLabel, variant, confirmPhrase, challenge, onConfirm, stepUp, keepOpenOnConfirm, pending, }: AlertDialogProp): React.JSX.Element;
|
|
148
149
|
export declare const Dialog: typeof DialogRoot & {
|
|
@@ -4,7 +4,7 @@ import { useOverlayPortalContainer } from "../../lib/overlay-portal.js";
|
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { chain, mergeRefs } from "@react-aria/utils";
|
|
6
6
|
import { Dialog as RacDialog, Modal, ModalOverlay } from "react-aria-components";
|
|
7
|
-
import { X } from "lucide-react";
|
|
7
|
+
import { AlertCircle, X } from "lucide-react";
|
|
8
8
|
import { cn } from "../../lib/utils.js";
|
|
9
9
|
import { Slot } from "../../lib/slot.js";
|
|
10
10
|
import { overlayHeaderToneClass } from "./overlay-header-tone.js";
|
|
@@ -392,7 +392,7 @@ function AlertDialog({
|
|
|
392
392
|
const needsPhrase = phrase != null && phrase.length > 0;
|
|
393
393
|
const phraseMatches = !needsPhrase || typed === phrase;
|
|
394
394
|
const effectiveVariant = needsPhrase ? "destructive" : variant;
|
|
395
|
-
const
|
|
395
|
+
const showDangerIcon = effectiveVariant === "destructive";
|
|
396
396
|
const resolvedConfirm = confirmLabel ?? (needsPhrase ? t("common.delete") : t("common.continue"));
|
|
397
397
|
const resolvedCancel = cancelLabel ?? t("common.cancel");
|
|
398
398
|
const busy = pending || verifying;
|
|
@@ -429,10 +429,13 @@ function AlertDialog({
|
|
|
429
429
|
})();
|
|
430
430
|
};
|
|
431
431
|
return /* @__PURE__ */ jsx(AlertDialogRoot, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
|
|
432
|
-
/* @__PURE__ */
|
|
433
|
-
/* @__PURE__ */ jsx(
|
|
434
|
-
|
|
435
|
-
|
|
432
|
+
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsxs("div", { className: "ui-dialog-confirm-body", children: [
|
|
433
|
+
showDangerIcon && /* @__PURE__ */ jsx(AlertCircle, { className: "ui-dialog-confirm-icon", "aria-hidden": true }),
|
|
434
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-dialog-confirm-text", children: [
|
|
435
|
+
/* @__PURE__ */ jsx(AlertDialogTitle, { children: title }),
|
|
436
|
+
description ? /* @__PURE__ */ jsx(AlertDialogDescription, { children: description }) : null
|
|
437
|
+
] })
|
|
438
|
+
] }) }),
|
|
436
439
|
needsPhrase && /* @__PURE__ */ jsx(FormField, { id: inputId, label: t("common.typeToConfirm", { phrase }), children: /* @__PURE__ */ jsx(
|
|
437
440
|
Input,
|
|
438
441
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "AUTO-GENERATED by scripts/gen-measurement-contract.mjs — do not edit. Read this instead of guessing: docs/MEASUREMENT-CONTRACT.md.",
|
|
3
|
-
"version": "23.4.
|
|
3
|
+
"version": "23.4.9",
|
|
4
4
|
"targetSize": {
|
|
5
5
|
"standard": "WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA — 24×24 CSS px",
|
|
6
6
|
"min": 24,
|
package/dist/styles/control.css
CHANGED
|
@@ -470,6 +470,10 @@
|
|
|
470
470
|
fill: currentColor;
|
|
471
471
|
}
|
|
472
472
|
|
|
473
|
+
.ui-radio[data-state="unchecked"] .ui-radio-icon {
|
|
474
|
+
visibility: hidden;
|
|
475
|
+
}
|
|
476
|
+
|
|
473
477
|
.ui-switch:has(input[aria-invalid="true"]) {
|
|
474
478
|
--tw-ring-shadow: 0 0 0 var(--focus-ring-width) hsl(var(--destructive));
|
|
475
479
|
box-shadow: 0 0 0 var(--focus-ring-width) hsl(var(--destructive));
|
|
@@ -123,7 +123,8 @@
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
[data-slot="dialog-content"]:has([data-slot="dialog-body"]) [data-slot="dialog-header"]
|
|
126
|
+
[data-slot="dialog-content"]:has([data-slot="dialog-body"]) [data-slot="dialog-header"],
|
|
127
|
+
[data-slot="dialog-header"]:not([data-tone="default"]) {
|
|
127
128
|
margin-inline: calc(-1 * var(--dialog-space-x));
|
|
128
129
|
margin-block-start: calc(-1 * var(--dialog-space-y));
|
|
129
130
|
padding: var(--dialog-space-y) var(--dialog-space-x);
|
|
@@ -222,6 +223,26 @@
|
|
|
222
223
|
[data-slot="dialog-header"]:not([data-tone="default"]) [data-slot="dialog-description"] {
|
|
223
224
|
color: hsl(var(--foreground));
|
|
224
225
|
}
|
|
226
|
+
|
|
227
|
+
.ui-dialog-confirm-body {
|
|
228
|
+
display: flex;
|
|
229
|
+
align-items: flex-start;
|
|
230
|
+
gap: var(--dialog-confirm-space-gap);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.ui-dialog-confirm-icon {
|
|
234
|
+
flex: none;
|
|
235
|
+
inline-size: var(--dialog-confirm-icon-size);
|
|
236
|
+
block-size: var(--dialog-confirm-icon-size);
|
|
237
|
+
color: hsl(var(--text-error));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.ui-dialog-confirm-text {
|
|
241
|
+
display: flex;
|
|
242
|
+
min-inline-size: 0;
|
|
243
|
+
flex-direction: column;
|
|
244
|
+
gap: var(--dialog-title-block-space-gap);
|
|
245
|
+
}
|
|
225
246
|
}
|
|
226
247
|
|
|
227
248
|
@media (prefers-reduced-motion: reduce) {
|
package/dist/styles/layout.css
CHANGED
|
@@ -716,6 +716,11 @@
|
|
|
716
716
|
width: 100%;
|
|
717
717
|
}
|
|
718
718
|
|
|
719
|
+
.ui-page-header-extra > .ui-flex[data-direction="row"] {
|
|
720
|
+
flex-wrap: wrap;
|
|
721
|
+
max-inline-size: 100%;
|
|
722
|
+
}
|
|
723
|
+
|
|
719
724
|
.ui-page-header-title-row {
|
|
720
725
|
display: flex;
|
|
721
726
|
flex-wrap: wrap;
|
|
@@ -762,11 +767,6 @@
|
|
|
762
767
|
.ui-page-header .ui-page-subtitle {
|
|
763
768
|
font-size: var(--page-subtitle-font-size-compact);
|
|
764
769
|
}
|
|
765
|
-
|
|
766
|
-
.ui-page-header-extra > .ui-flex[data-direction="row"] {
|
|
767
|
-
flex-wrap: wrap;
|
|
768
|
-
max-width: 100%;
|
|
769
|
-
}
|
|
770
770
|
}
|
|
771
771
|
|
|
772
772
|
@media (max-width: 639.98px) {
|
|
@@ -36,6 +36,9 @@
|
|
|
36
36
|
--dialog-title-block-space-gap: var(--space-1);
|
|
37
37
|
--dialog-extra-space-gap: var(--space-2);
|
|
38
38
|
|
|
39
|
+
--dialog-confirm-icon-size: var(--icon-size-xl);
|
|
40
|
+
--dialog-confirm-space-gap: var(--space-3);
|
|
41
|
+
|
|
39
42
|
--dialog-header-close-space-inline-end: var(--space-8);
|
|
40
43
|
|
|
41
44
|
--dialog-close-rest-alpha: 0.7;
|
|
@@ -7,7 +7,8 @@ import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
|
7
7
|
/**
|
|
8
8
|
* DangerConfirm recipe (godxui#193) — high-stakes deletion built on the AlertDialog preset.
|
|
9
9
|
* No new component: `challenge` gates the confirm button behind an exact typed slug, and `stepUp`
|
|
10
|
-
* runs an async passkey / 2FA re-auth before onConfirm fires. Both force the destructive
|
|
10
|
+
* runs an async passkey / 2FA re-auth before onConfirm fires. Both force the destructive shape
|
|
11
|
+
* (button + leading status glyph, untinted surface — antd `Modal.confirm` parity).
|
|
11
12
|
* Mirrors DXS SCR-203 (org delete by slug) and SCR-209 (refund with step-up).
|
|
12
13
|
*/
|
|
13
14
|
export default function Demo() {
|
|
@@ -25,8 +26,10 @@ export default function Demo() {
|
|
|
25
26
|
<CardTitle level={2}>Organization delete · typed slug challenge</CardTitle>
|
|
26
27
|
<CardDescription>
|
|
27
28
|
The confirm button stays disabled until the operator types the exact organization slug
|
|
28
|
-
(<code>acme-inc</code>). A typed challenge always forces the destructive
|
|
29
|
-
|
|
29
|
+
(<code>acme-inc</code>). A typed challenge always forces the destructive shape: the
|
|
30
|
+
destructive confirm button and antd’s leading status glyph. The header surface
|
|
31
|
+
stays untinted — the glyph is the signal, exactly as <code>Modal.confirm</code> does
|
|
32
|
+
it.
|
|
30
33
|
</CardDescription>
|
|
31
34
|
</CardHeader>
|
|
32
35
|
<CardContent>
|