@remit/ui 0.0.108 → 0.0.109

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/ui",
3
- "version": "0.0.108",
3
+ "version": "0.0.109",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src"
@@ -1,5 +1,6 @@
1
1
  import { useCallback, useEffect, useRef } from "react";
2
2
  import { cn } from "../lib/cn.js";
3
+ import { DialogBackdrop } from "./dialog-backdrop.js";
3
4
 
4
5
  export interface ConfirmDialogProps {
5
6
  isOpen: boolean;
@@ -80,13 +81,10 @@ export const ConfirmDialog = ({
80
81
  // confirmation is the decision blocking whatever is under it, and a drawer
81
82
  // portalled to the body at the same level would cover it.
82
83
  <div className="fixed inset-0 z-[60] flex items-center justify-center">
83
- {/* Backdrop. It carries the click-to-dismiss and the aria-hidden: the
84
- dialog itself must stay in the accessibility tree, and an
85
- aria-hidden ancestor would take it out. */}
86
- <div
87
- className="absolute inset-0 bg-canvas/80 backdrop-blur-sm"
88
- aria-hidden="true"
89
- onClick={onCancel}
84
+ <DialogBackdrop
85
+ label="Dismiss confirmation"
86
+ onDismiss={onCancel}
87
+ className="backdrop-blur-sm"
90
88
  />
91
89
 
92
90
  {/* Dialog */}
@@ -99,8 +97,6 @@ export const ConfirmDialog = ({
99
97
  "bg-surface border border-line rounded-sm shadow-lg",
100
98
  "p-6",
101
99
  )}
102
- onClick={(e) => e.stopPropagation()}
103
- onKeyDown={(e) => e.stopPropagation()}
104
100
  >
105
101
  <h2 className="text-lg font-semibold">{title}</h2>
106
102
  {description && (
@@ -0,0 +1,30 @@
1
+ import { cn } from "../lib/cn.js";
2
+
3
+ export interface DialogBackdropProps {
4
+ /** Names the dismissal to assistive technology, e.g. `"Close"`. */
5
+ label: string;
6
+ onDismiss: () => void;
7
+ className?: string;
8
+ }
9
+
10
+ /**
11
+ * The scrim behind a modal and the click-to-dismiss on it, in the shape
12
+ * `BottomSheet` already uses: a real button rather than a click handler on a
13
+ * div, out of the tab order because Escape and the dialog's own Close are the
14
+ * keyboard's way out. It sits as a sibling of the dialog card, never its
15
+ * ancestor, so a click on the card is not a click on the scrim and nothing has
16
+ * to stop propagation to survive.
17
+ */
18
+ export const DialogBackdrop = ({
19
+ label,
20
+ onDismiss,
21
+ className,
22
+ }: DialogBackdropProps) => (
23
+ <button
24
+ type="button"
25
+ aria-label={label}
26
+ tabIndex={-1}
27
+ onClick={onDismiss}
28
+ className={cn("absolute inset-0 bg-canvas/80", className)}
29
+ />
30
+ );
@@ -1,5 +1,6 @@
1
1
  import { type ReactNode, useCallback, useEffect, useRef } from "react";
2
2
  import { cn } from "../lib/cn.js";
3
+ import { DialogBackdrop } from "./dialog-backdrop.js";
3
4
 
4
5
  export interface DialogProps {
5
6
  open: boolean;
@@ -64,7 +65,6 @@ export function Dialog({
64
65
  const isRight = anchor === "right";
65
66
 
66
67
  return (
67
- // biome-ignore lint/a11y/noStaticElementInteractions: outer overlay closes dialog on click; role=presentation lets inner role=dialog own the AT semantics
68
68
  <div
69
69
  className={cn(
70
70
  "fixed inset-0 z-50 flex",
@@ -74,10 +74,8 @@ export function Dialog({
74
74
  ? "items-stretch justify-end"
75
75
  : "items-center justify-center px-4",
76
76
  )}
77
- role="presentation"
78
- onClick={onClose}
79
77
  >
80
- <div className="absolute inset-0 bg-canvas/80" />
78
+ <DialogBackdrop label="Dismiss dialog" onDismiss={onClose} />
81
79
  <div
82
80
  ref={dialogRef}
83
81
  role="dialog"
@@ -94,8 +92,6 @@ export function Dialog({
94
92
  : "w-full max-w-lg rounded-md border",
95
93
  className,
96
94
  )}
97
- onClick={(e) => e.stopPropagation()}
98
- onKeyDown={(e) => e.stopPropagation()}
99
95
  >
100
96
  <h2 id="dialog-title" className="sr-only">
101
97
  {title}
package/src/index.ts CHANGED
@@ -167,6 +167,10 @@ export {
167
167
  type DangerZoneSectionProps,
168
168
  } from "./components/danger-zone-section.js";
169
169
  export { Dialog, type DialogProps } from "./components/dialog.js";
170
+ export {
171
+ DialogBackdrop,
172
+ type DialogBackdropProps,
173
+ } from "./components/dialog-backdrop.js";
170
174
  export type { EmailFrameVariant } from "./components/email-frame-css.js";
171
175
  export {
172
176
  FieldLabel,