@glob-ui/dialog 0.1.0 → 0.2.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/README.md +1 -1
- package/dist/index.d.mts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +46 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +42 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @glob-ui/dialog
|
|
2
2
|
|
|
3
|
-
A modal dialog on the native `<dialog>` element. Focus moves in, Escape closes it, and focus returns to the trigger.
|
|
3
|
+
A modal dialog on the native `<dialog>` element. Focus moves in, Escape closes it, and focus returns to the trigger. Build your own modal on the same behaviour with `DialogContentBase`.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
package/dist/index.d.mts
CHANGED
|
@@ -22,6 +22,16 @@ declare const DialogTrigger: react.ForwardRefExoticComponent<DialogTriggerProps
|
|
|
22
22
|
declare const dialogVariants: (props?: ({
|
|
23
23
|
size?: "sm" | "md" | "lg" | null | undefined;
|
|
24
24
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
25
|
+
type DialogContentBaseProps = React.DialogHTMLAttributes<HTMLDialogElement>;
|
|
26
|
+
/**
|
|
27
|
+
* The modal behaviour of Dialog with no styles and no layout: showModal, the shared scroll lock,
|
|
28
|
+
* Esc, backdrop click (see closeOnOutsideClick), focus return and aria-labelledby/describedby.
|
|
29
|
+
* Build your own modal on the same behaviour. Sheet and AlertDialog are built on it.
|
|
30
|
+
*/
|
|
31
|
+
declare const DialogContentBase: react.ForwardRefExoticComponent<DialogContentBaseProps & react.RefAttributes<HTMLDialogElement>>;
|
|
32
|
+
type DialogCloseIconProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
33
|
+
/** The X button in the top-right corner. Closes the surrounding Dialog, Sheet or AlertDialog. */
|
|
34
|
+
declare const DialogCloseIcon: react.ForwardRefExoticComponent<DialogCloseIconProps & react.RefAttributes<HTMLButtonElement>>;
|
|
25
35
|
interface DialogContentProps extends React.DialogHTMLAttributes<HTMLDialogElement>, VariantProps<typeof dialogVariants> {
|
|
26
36
|
/** Shows an X button in the top-right corner. */
|
|
27
37
|
showCloseButton?: boolean;
|
|
@@ -40,4 +50,4 @@ interface DialogCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
40
50
|
}
|
|
41
51
|
declare const DialogClose: react.ForwardRefExoticComponent<DialogCloseProps & react.RefAttributes<HTMLButtonElement>>;
|
|
42
52
|
|
|
43
|
-
export { Dialog, DialogClose, type DialogCloseProps, DialogContent, type DialogContentProps, DialogDescription, type DialogDescriptionProps, DialogFooter, type DialogFooterProps, DialogHeader, type DialogHeaderProps, type DialogProps, DialogTitle, type DialogTitleProps, DialogTrigger, type DialogTriggerProps };
|
|
53
|
+
export { Dialog, DialogClose, DialogCloseIcon, type DialogCloseIconProps, type DialogCloseProps, DialogContent, DialogContentBase, type DialogContentBaseProps, type DialogContentProps, DialogDescription, type DialogDescriptionProps, DialogFooter, type DialogFooterProps, DialogHeader, type DialogHeaderProps, type DialogProps, DialogTitle, type DialogTitleProps, DialogTrigger, type DialogTriggerProps, dialogVariants };
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,16 @@ declare const DialogTrigger: react.ForwardRefExoticComponent<DialogTriggerProps
|
|
|
22
22
|
declare const dialogVariants: (props?: ({
|
|
23
23
|
size?: "sm" | "md" | "lg" | null | undefined;
|
|
24
24
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
25
|
+
type DialogContentBaseProps = React.DialogHTMLAttributes<HTMLDialogElement>;
|
|
26
|
+
/**
|
|
27
|
+
* The modal behaviour of Dialog with no styles and no layout: showModal, the shared scroll lock,
|
|
28
|
+
* Esc, backdrop click (see closeOnOutsideClick), focus return and aria-labelledby/describedby.
|
|
29
|
+
* Build your own modal on the same behaviour. Sheet and AlertDialog are built on it.
|
|
30
|
+
*/
|
|
31
|
+
declare const DialogContentBase: react.ForwardRefExoticComponent<DialogContentBaseProps & react.RefAttributes<HTMLDialogElement>>;
|
|
32
|
+
type DialogCloseIconProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
33
|
+
/** The X button in the top-right corner. Closes the surrounding Dialog, Sheet or AlertDialog. */
|
|
34
|
+
declare const DialogCloseIcon: react.ForwardRefExoticComponent<DialogCloseIconProps & react.RefAttributes<HTMLButtonElement>>;
|
|
25
35
|
interface DialogContentProps extends React.DialogHTMLAttributes<HTMLDialogElement>, VariantProps<typeof dialogVariants> {
|
|
26
36
|
/** Shows an X button in the top-right corner. */
|
|
27
37
|
showCloseButton?: boolean;
|
|
@@ -40,4 +50,4 @@ interface DialogCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
40
50
|
}
|
|
41
51
|
declare const DialogClose: react.ForwardRefExoticComponent<DialogCloseProps & react.RefAttributes<HTMLButtonElement>>;
|
|
42
52
|
|
|
43
|
-
export { Dialog, DialogClose, type DialogCloseProps, DialogContent, type DialogContentProps, DialogDescription, type DialogDescriptionProps, DialogFooter, type DialogFooterProps, DialogHeader, type DialogHeaderProps, type DialogProps, DialogTitle, type DialogTitleProps, DialogTrigger, type DialogTriggerProps };
|
|
53
|
+
export { Dialog, DialogClose, DialogCloseIcon, type DialogCloseIconProps, type DialogCloseProps, DialogContent, DialogContentBase, type DialogContentBaseProps, type DialogContentProps, DialogDescription, type DialogDescriptionProps, DialogFooter, type DialogFooterProps, DialogHeader, type DialogHeaderProps, type DialogProps, DialogTitle, type DialogTitleProps, DialogTrigger, type DialogTriggerProps, dialogVariants };
|
package/dist/index.js
CHANGED
|
@@ -52,12 +52,15 @@ var index_exports = {};
|
|
|
52
52
|
__export(index_exports, {
|
|
53
53
|
Dialog: () => Dialog,
|
|
54
54
|
DialogClose: () => DialogClose,
|
|
55
|
+
DialogCloseIcon: () => DialogCloseIcon,
|
|
55
56
|
DialogContent: () => DialogContent,
|
|
57
|
+
DialogContentBase: () => DialogContentBase,
|
|
56
58
|
DialogDescription: () => DialogDescription,
|
|
57
59
|
DialogFooter: () => DialogFooter,
|
|
58
60
|
DialogHeader: () => DialogHeader,
|
|
59
61
|
DialogTitle: () => DialogTitle,
|
|
60
|
-
DialogTrigger: () => DialogTrigger
|
|
62
|
+
DialogTrigger: () => DialogTrigger,
|
|
63
|
+
dialogVariants: () => dialogVariants
|
|
61
64
|
});
|
|
62
65
|
module.exports = __toCommonJS(index_exports);
|
|
63
66
|
|
|
@@ -94,7 +97,7 @@ function lockScroll() {
|
|
|
94
97
|
var DialogContext = (0, import_react.createContext)(null);
|
|
95
98
|
function useDialogContext(part) {
|
|
96
99
|
const ctx = (0, import_react.useContext)(DialogContext);
|
|
97
|
-
if (!ctx) throw new Error(`${part} must be used inside Dialog`);
|
|
100
|
+
if (!ctx) throw new Error(`${part} must be used inside Dialog, Sheet or AlertDialog`);
|
|
98
101
|
return ctx;
|
|
99
102
|
}
|
|
100
103
|
function Dialog({ open, defaultOpen = false, onOpenChange, closeOnOutsideClick = true, children }) {
|
|
@@ -162,9 +165,9 @@ var dialogVariants = (0, import_class_variance_authority.cva)(
|
|
|
162
165
|
}
|
|
163
166
|
}
|
|
164
167
|
);
|
|
165
|
-
var
|
|
168
|
+
var DialogContentBase = (0, import_react.forwardRef)(
|
|
166
169
|
(_a, ref) => {
|
|
167
|
-
var _b = _a, { className,
|
|
170
|
+
var _b = _a, { className, children, onCancel, onClose, onPointerDown, onClick } = _b, props = __objRest(_b, ["className", "children", "onCancel", "onClose", "onPointerDown", "onClick"]);
|
|
168
171
|
const ctx = useDialogContext("DialogContent");
|
|
169
172
|
const { open, setOpen, titleId, descriptionId, closeOnOutsideClick } = ctx;
|
|
170
173
|
const innerRef = (0, import_react.useRef)(null);
|
|
@@ -199,7 +202,7 @@ var DialogContent = (0, import_react.forwardRef)(
|
|
|
199
202
|
__spreadProps(__spreadValues({
|
|
200
203
|
ref: mergedRef,
|
|
201
204
|
id: ctx.contentId,
|
|
202
|
-
className: (0, import_utils.cn)(
|
|
205
|
+
className: (0, import_utils.cn)(className),
|
|
203
206
|
onCancel: (e) => {
|
|
204
207
|
onCancel == null ? void 0 : onCancel(e);
|
|
205
208
|
e.preventDefault();
|
|
@@ -226,23 +229,44 @@ var DialogContent = (0, import_react.forwardRef)(
|
|
|
226
229
|
}
|
|
227
230
|
}
|
|
228
231
|
}, props), {
|
|
229
|
-
children
|
|
230
|
-
children,
|
|
231
|
-
showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
232
|
-
"button",
|
|
233
|
-
{
|
|
234
|
-
type: "button",
|
|
235
|
-
"aria-label": "Close",
|
|
236
|
-
onClick: () => setOpen(false),
|
|
237
|
-
className: "absolute right-4 top-4 inline-flex h-8 w-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring",
|
|
238
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "h-4 w-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 6L6 18M6 6l12 12" }) })
|
|
239
|
-
}
|
|
240
|
-
)
|
|
241
|
-
] })
|
|
232
|
+
children
|
|
242
233
|
})
|
|
243
234
|
);
|
|
244
235
|
}
|
|
245
236
|
);
|
|
237
|
+
DialogContentBase.displayName = "DialogContentBase";
|
|
238
|
+
var DialogCloseIcon = (0, import_react.forwardRef)((_a, ref) => {
|
|
239
|
+
var _b = _a, { className, onClick } = _b, props = __objRest(_b, ["className", "onClick"]);
|
|
240
|
+
const ctx = useDialogContext("DialogCloseIcon");
|
|
241
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
242
|
+
"button",
|
|
243
|
+
__spreadProps(__spreadValues({
|
|
244
|
+
ref,
|
|
245
|
+
type: "button",
|
|
246
|
+
"aria-label": "Close",
|
|
247
|
+
onClick: (e) => {
|
|
248
|
+
onClick == null ? void 0 : onClick(e);
|
|
249
|
+
if (!e.defaultPrevented) ctx.setOpen(false);
|
|
250
|
+
},
|
|
251
|
+
className: (0, import_utils.cn)(
|
|
252
|
+
"absolute right-4 top-4 inline-flex h-8 w-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring",
|
|
253
|
+
className
|
|
254
|
+
)
|
|
255
|
+
}, props), {
|
|
256
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "h-4 w-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 6L6 18M6 6l12 12" }) })
|
|
257
|
+
})
|
|
258
|
+
);
|
|
259
|
+
});
|
|
260
|
+
DialogCloseIcon.displayName = "DialogCloseIcon";
|
|
261
|
+
var DialogContent = (0, import_react.forwardRef)(
|
|
262
|
+
(_a, ref) => {
|
|
263
|
+
var _b = _a, { className, size, showCloseButton = true, children } = _b, props = __objRest(_b, ["className", "size", "showCloseButton", "children"]);
|
|
264
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogContentBase, __spreadProps(__spreadValues({ ref, className: (0, import_utils.cn)(dialogVariants({ size, className })) }, props), { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative flex max-h-[calc(100dvh-2rem)] flex-col gap-4 overflow-y-auto p-6", children: [
|
|
265
|
+
children,
|
|
266
|
+
showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogCloseIcon, {})
|
|
267
|
+
] }) }));
|
|
268
|
+
}
|
|
269
|
+
);
|
|
246
270
|
DialogContent.displayName = "DialogContent";
|
|
247
271
|
var DialogHeader = (0, import_react.forwardRef)((_a, ref) => {
|
|
248
272
|
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
@@ -296,11 +320,14 @@ DialogClose.displayName = "DialogClose";
|
|
|
296
320
|
0 && (module.exports = {
|
|
297
321
|
Dialog,
|
|
298
322
|
DialogClose,
|
|
323
|
+
DialogCloseIcon,
|
|
299
324
|
DialogContent,
|
|
325
|
+
DialogContentBase,
|
|
300
326
|
DialogDescription,
|
|
301
327
|
DialogFooter,
|
|
302
328
|
DialogHeader,
|
|
303
329
|
DialogTitle,
|
|
304
|
-
DialogTrigger
|
|
330
|
+
DialogTrigger,
|
|
331
|
+
dialogVariants
|
|
305
332
|
});
|
|
306
333
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/dialog.tsx"],"sourcesContent":["export { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose } from \"./dialog\"\nexport type { DialogProps, DialogTriggerProps, DialogContentProps, DialogHeaderProps, DialogTitleProps, DialogDescriptionProps, DialogFooterProps, DialogCloseProps } from \"./dialog\"\n","\"use client\"\n\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n} from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"@glob-ui/utils\"\nimport { useControllableState } from \"@glob-ui/hooks\"\nimport { Slot, composeRefs } from \"@glob-ui/slot\"\n\n// Scroll lock shared by every open dialog. Compensates the scrollbar width so the page does not shift.\nlet lockCount = 0\nlet savedStyles: { overflow: string; paddingRight: string } | null = null\n\nfunction lockScroll() {\n const html = document.documentElement\n if (lockCount === 0) {\n const scrollbarWidth = window.innerWidth - html.clientWidth\n savedStyles = { overflow: html.style.overflow, paddingRight: html.style.paddingRight }\n if (scrollbarWidth > 0) {\n const current = parseFloat(getComputedStyle(html).paddingRight) || 0\n html.style.paddingRight = `${current + scrollbarWidth}px`\n }\n html.style.overflow = \"hidden\"\n }\n lockCount++\n return () => {\n lockCount--\n if (lockCount === 0 && savedStyles) {\n html.style.overflow = savedStyles.overflow\n html.style.paddingRight = savedStyles.paddingRight\n savedStyles = null\n }\n }\n}\n\ninterface DialogContextValue {\n open: boolean\n setOpen: (open: boolean) => void\n contentId: string\n titleId: string\n descriptionId: string\n closeOnOutsideClick: boolean\n}\n\nconst DialogContext = createContext<DialogContextValue | null>(null)\n\nfunction useDialogContext(part: string) {\n const ctx = useContext(DialogContext)\n if (!ctx) throw new Error(`${part} must be used inside Dialog`)\n return ctx\n}\n\nexport interface DialogProps {\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n /** Close when the backdrop is clicked. */\n closeOnOutsideClick?: boolean\n children?: React.ReactNode\n}\n\nfunction Dialog({ open, defaultOpen = false, onOpenChange, closeOnOutsideClick = true, children }: DialogProps) {\n const [isOpen, setOpen] = useControllableState(open, defaultOpen, onOpenChange)\n const baseId = useId()\n\n return (\n <DialogContext.Provider\n value={{\n open: isOpen,\n setOpen,\n contentId: `${baseId}-content`,\n titleId: `${baseId}-title`,\n descriptionId: `${baseId}-description`,\n closeOnOutsideClick,\n }}\n >\n {children}\n </DialogContext.Provider>\n )\n}\nDialog.displayName = \"Dialog\"\n\nexport interface DialogTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean\n}\n\nconst DialogTrigger = forwardRef<HTMLButtonElement, DialogTriggerProps>(\n ({ asChild = false, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogTrigger\")\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n ref={ref}\n type={asChild ? undefined : \"button\"}\n aria-haspopup=\"dialog\"\n aria-expanded={ctx.open}\n aria-controls={ctx.open ? ctx.contentId : undefined}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (!e.defaultPrevented) ctx.setOpen(true)\n }}\n {...props}\n />\n )\n }\n)\nDialogTrigger.displayName = \"DialogTrigger\"\n\nconst dialogVariants = cva(\n [\n \"m-auto max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] overflow-visible rounded-glob-lg border border-glob-border bg-glob-surface p-0 text-glob-text shadow-glob-md\",\n // Enter/exit. @starting-style animates the entry; allow-discrete keeps display/overlay alive\n // during the exit. Browsers without them open and close without animation.\n \"scale-95 opacity-0 transition-[opacity,scale,overlay,display] transition-discrete duration-200 ease-out\",\n \"open:scale-100 open:opacity-100 starting:open:scale-95 starting:open:opacity-0\",\n \"backdrop:bg-glob-overlay backdrop:opacity-0 backdrop:transition-[opacity,overlay,display] backdrop:transition-discrete backdrop:duration-200\",\n \"open:backdrop:opacity-100 starting:open:backdrop:opacity-0\",\n \"motion-reduce:transition-none motion-reduce:backdrop:transition-none\",\n ],\n {\n variants: {\n size: {\n sm: \"max-w-sm\",\n md: \"max-w-lg\",\n lg: \"max-w-2xl\",\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n }\n)\n\nexport interface DialogContentProps\n extends React.DialogHTMLAttributes<HTMLDialogElement>,\n VariantProps<typeof dialogVariants> {\n /** Shows an X button in the top-right corner. */\n showCloseButton?: boolean\n}\n\nconst DialogContent = forwardRef<HTMLDialogElement, DialogContentProps>(\n (\n { className, size, showCloseButton = true, children, onCancel, onClose, onPointerDown, onClick, ...props },\n ref\n ) => {\n const ctx = useDialogContext(\"DialogContent\")\n const { open, setOpen, titleId, descriptionId, closeOnOutsideClick } = ctx\n const innerRef = useRef<HTMLDialogElement>(null)\n const previouslyFocused = useRef<HTMLElement | null>(null)\n const pointerDownOnBackdrop = useRef(false)\n const mergedRef = useMemo(() => composeRefs(ref, innerRef), [ref])\n const hasOwnLabel = props[\"aria-labelledby\"] !== undefined || props[\"aria-label\"] !== undefined\n const hasOwnDescription = props[\"aria-describedby\"] !== undefined\n\n useEffect(() => {\n const dialog = innerRef.current\n if (!dialog) return\n if (!open) {\n if (dialog.open) dialog.close()\n return\n }\n if (!dialog.open) {\n previouslyFocused.current = document.activeElement as HTMLElement | null\n // Point at Title/Description only if they are rendered, so the references never dangle.\n if (!hasOwnLabel) {\n if (document.getElementById(titleId)) dialog.setAttribute(\"aria-labelledby\", titleId)\n else dialog.removeAttribute(\"aria-labelledby\")\n }\n if (!hasOwnDescription) {\n if (document.getElementById(descriptionId)) dialog.setAttribute(\"aria-describedby\", descriptionId)\n else dialog.removeAttribute(\"aria-describedby\")\n }\n dialog.showModal()\n }\n return lockScroll()\n }, [open, titleId, descriptionId, hasOwnLabel, hasOwnDescription])\n\n return (\n <dialog\n ref={mergedRef}\n id={ctx.contentId}\n className={cn(dialogVariants({ size, className }))}\n // Esc: keep React state as the source of truth (controlled dialogs may refuse to close).\n onCancel={(e) => {\n onCancel?.(e)\n e.preventDefault()\n setOpen(false)\n }}\n // Closed by the browser anyway (e.g. a repeated Esc that cannot be cancelled): sync state.\n onClose={(e) => {\n onClose?.(e)\n if (open) setOpen(false)\n const active = document.activeElement\n if (!active || active === document.body || innerRef.current?.contains(active)) {\n previouslyFocused.current?.focus()\n }\n }}\n // A click lands on the <dialog> element itself only over the backdrop: content fills it.\n onPointerDown={(e) => {\n onPointerDown?.(e)\n pointerDownOnBackdrop.current = e.target === e.currentTarget\n }}\n onClick={(e) => {\n onClick?.(e)\n if (e.defaultPrevented) return\n if (closeOnOutsideClick && pointerDownOnBackdrop.current && e.target === e.currentTarget) {\n setOpen(false)\n }\n }}\n {...props}\n >\n <div className=\"relative flex max-h-[calc(100dvh-2rem)] flex-col gap-4 overflow-y-auto p-6\">\n {children}\n {showCloseButton && (\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={() => setOpen(false)}\n className=\"absolute right-4 top-4 inline-flex h-8 w-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring\"\n >\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"h-4 w-4\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n )}\n </div>\n </dialog>\n )\n }\n)\nDialogContent.displayName = \"DialogContent\"\n\nexport type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement>\n\nconst DialogHeader = forwardRef<HTMLDivElement, DialogHeaderProps>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"flex flex-col gap-1.5 pr-8\", className)} {...props} />\n))\nDialogHeader.displayName = \"DialogHeader\"\n\nexport type DialogTitleProps = React.HTMLAttributes<HTMLHeadingElement>\n\nconst DialogTitle = forwardRef<HTMLHeadingElement, DialogTitleProps>(({ className, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogTitle\")\n return (\n <h2\n ref={ref}\n id={ctx.titleId}\n className={cn(\"text-lg font-semibold leading-none tracking-tight\", className)}\n {...props}\n />\n )\n})\nDialogTitle.displayName = \"DialogTitle\"\n\nexport type DialogDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>\n\nconst DialogDescription = forwardRef<HTMLParagraphElement, DialogDescriptionProps>(\n ({ className, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogDescription\")\n return (\n <p ref={ref} id={ctx.descriptionId} className={cn(\"text-sm text-glob-text-secondary\", className)} {...props} />\n )\n }\n)\nDialogDescription.displayName = \"DialogDescription\"\n\nexport type DialogFooterProps = React.HTMLAttributes<HTMLDivElement>\n\nconst DialogFooter = forwardRef<HTMLDivElement, DialogFooterProps>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)} {...props} />\n))\nDialogFooter.displayName = \"DialogFooter\"\n\nexport interface DialogCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean\n}\n\nconst DialogClose = forwardRef<HTMLButtonElement, DialogCloseProps>(({ asChild = false, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogClose\")\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n ref={ref}\n type={asChild ? undefined : \"button\"}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (!e.defaultPrevented) ctx.setOpen(false)\n }}\n {...props}\n />\n )\n})\nDialogClose.displayName = \"DialogClose\"\n\nexport {\n Dialog,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n DialogClose,\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,mBAQO;AACP,sCAAuC;AACvC,mBAAmB;AACnB,mBAAqC;AACrC,kBAAkC;AA2D9B;AAxDJ,IAAI,YAAY;AAChB,IAAI,cAAiE;AAErE,SAAS,aAAa;AACpB,QAAM,OAAO,SAAS;AACtB,MAAI,cAAc,GAAG;AACnB,UAAM,iBAAiB,OAAO,aAAa,KAAK;AAChD,kBAAc,EAAE,UAAU,KAAK,MAAM,UAAU,cAAc,KAAK,MAAM,aAAa;AACrF,QAAI,iBAAiB,GAAG;AACtB,YAAM,UAAU,WAAW,iBAAiB,IAAI,EAAE,YAAY,KAAK;AACnE,WAAK,MAAM,eAAe,GAAG,UAAU,cAAc;AAAA,IACvD;AACA,SAAK,MAAM,WAAW;AAAA,EACxB;AACA;AACA,SAAO,MAAM;AACX;AACA,QAAI,cAAc,KAAK,aAAa;AAClC,WAAK,MAAM,WAAW,YAAY;AAClC,WAAK,MAAM,eAAe,YAAY;AACtC,oBAAc;AAAA,IAChB;AAAA,EACF;AACF;AAWA,IAAM,oBAAgB,4BAAyC,IAAI;AAEnE,SAAS,iBAAiB,MAAc;AACtC,QAAM,UAAM,yBAAW,aAAa;AACpC,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,GAAG,IAAI,6BAA6B;AAC9D,SAAO;AACT;AAWA,SAAS,OAAO,EAAE,MAAM,cAAc,OAAO,cAAc,sBAAsB,MAAM,SAAS,GAAgB;AAC9G,QAAM,CAAC,QAAQ,OAAO,QAAI,mCAAqB,MAAM,aAAa,YAAY;AAC9E,QAAM,aAAS,oBAAM;AAErB,SACE;AAAA,IAAC,cAAc;AAAA,IAAd;AAAA,MACC,OAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA,WAAW,GAAG,MAAM;AAAA,QACpB,SAAS,GAAG,MAAM;AAAA,QAClB,eAAe,GAAG,MAAM;AAAA,QACxB;AAAA,MACF;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AACA,OAAO,cAAc;AAMrB,IAAM,oBAAgB;AAAA,EACpB,CAAC,IAAwC,QAAQ;AAAhD,iBAAE,YAAU,OAAO,QA9FtB,IA8FG,IAA+B,kBAA/B,IAA+B,CAA7B,WAAiB;AAClB,UAAM,MAAM,iBAAiB,eAAe;AAC5C,UAAM,OAAO,UAAU,mBAAO;AAC9B,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAM,UAAU,SAAY;AAAA,QAC5B,iBAAc;AAAA,QACd,iBAAe,IAAI;AAAA,QACnB,iBAAe,IAAI,OAAO,IAAI,YAAY;AAAA,QAC1C,SAAS,CAAC,MAA2C;AACnD,6CAAU;AACV,cAAI,CAAC,EAAE,iBAAkB,KAAI,QAAQ,IAAI;AAAA,QAC3C;AAAA,SACI;AAAA,IACN;AAAA,EAEJ;AACF;AACA,cAAc,cAAc;AAE5B,IAAM,qBAAiB;AAAA,EACrB;AAAA,IACE;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,MAAM;AAAA,IACR;AAAA,EACF;AACF;AASA,IAAM,oBAAgB;AAAA,EACpB,CACE,IACA,QACG;AAFH,iBAAE,aAAW,MAAM,kBAAkB,MAAM,UAAU,UAAU,SAAS,eAAe,QArJ3F,IAqJI,IAAmG,kBAAnG,IAAmG,CAAjG,aAAW,QAAM,mBAAwB,YAAU,YAAU,WAAS,iBAAe;AAGvF,UAAM,MAAM,iBAAiB,eAAe;AAC5C,UAAM,EAAE,MAAM,SAAS,SAAS,eAAe,oBAAoB,IAAI;AACvE,UAAM,eAAW,qBAA0B,IAAI;AAC/C,UAAM,wBAAoB,qBAA2B,IAAI;AACzD,UAAM,4BAAwB,qBAAO,KAAK;AAC1C,UAAM,gBAAY,sBAAQ,UAAM,yBAAY,KAAK,QAAQ,GAAG,CAAC,GAAG,CAAC;AACjE,UAAM,cAAc,MAAM,iBAAiB,MAAM,UAAa,MAAM,YAAY,MAAM;AACtF,UAAM,oBAAoB,MAAM,kBAAkB,MAAM;AAExD,gCAAU,MAAM;AACd,YAAM,SAAS,SAAS;AACxB,UAAI,CAAC,OAAQ;AACb,UAAI,CAAC,MAAM;AACT,YAAI,OAAO,KAAM,QAAO,MAAM;AAC9B;AAAA,MACF;AACA,UAAI,CAAC,OAAO,MAAM;AAChB,0BAAkB,UAAU,SAAS;AAErC,YAAI,CAAC,aAAa;AAChB,cAAI,SAAS,eAAe,OAAO,EAAG,QAAO,aAAa,mBAAmB,OAAO;AAAA,cAC/E,QAAO,gBAAgB,iBAAiB;AAAA,QAC/C;AACA,YAAI,CAAC,mBAAmB;AACtB,cAAI,SAAS,eAAe,aAAa,EAAG,QAAO,aAAa,oBAAoB,aAAa;AAAA,cAC5F,QAAO,gBAAgB,kBAAkB;AAAA,QAChD;AACA,eAAO,UAAU;AAAA,MACnB;AACA,aAAO,WAAW;AAAA,IACpB,GAAG,CAAC,MAAM,SAAS,eAAe,aAAa,iBAAiB,CAAC;AAEjE,WACE;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,IAAI,IAAI;AAAA,QACR,eAAW,iBAAG,eAAe,EAAE,MAAM,UAAU,CAAC,CAAC;AAAA,QAEjD,UAAU,CAAC,MAAM;AACf,+CAAW;AACX,YAAE,eAAe;AACjB,kBAAQ,KAAK;AAAA,QACf;AAAA,QAEA,SAAS,CAAC,MAAM;AApMxB,cAAAA,KAAAC;AAqMU,6CAAU;AACV,cAAI,KAAM,SAAQ,KAAK;AACvB,gBAAM,SAAS,SAAS;AACxB,cAAI,CAAC,UAAU,WAAW,SAAS,UAAQD,MAAA,SAAS,YAAT,gBAAAA,IAAkB,SAAS,UAAS;AAC7E,aAAAC,MAAA,kBAAkB,YAAlB,gBAAAA,IAA2B;AAAA,UAC7B;AAAA,QACF;AAAA,QAEA,eAAe,CAAC,MAAM;AACpB,yDAAgB;AAChB,gCAAsB,UAAU,EAAE,WAAW,EAAE;AAAA,QACjD;AAAA,QACA,SAAS,CAAC,MAAM;AACd,6CAAU;AACV,cAAI,EAAE,iBAAkB;AACxB,cAAI,uBAAuB,sBAAsB,WAAW,EAAE,WAAW,EAAE,eAAe;AACxF,oBAAQ,KAAK;AAAA,UACf;AAAA,QACF;AAAA,SACI,QA/BL;AAAA,QAiCC,uDAAC,SAAI,WAAU,8EACZ;AAAA;AAAA,UACA,mBACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,SAAS,MAAM,QAAQ,KAAK;AAAA,cAC5B,WAAU;AAAA,cAEV,sDAAC,SAAI,eAAY,QAAO,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,WAAU,WACtG,sDAAC,UAAK,GAAE,wBAAuB,GACjC;AAAA;AAAA,UACF;AAAA,WAEJ;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AACA,cAAc,cAAc;AAI5B,IAAM,mBAAe,yBAA8C,CAAC,IAAyB,QAAK;AAA9B,eAAE,YAjPtE,IAiPoE,IAAgB,kBAAhB,IAAgB,CAAd;AACpE,qDAAC,wBAAI,KAAU,eAAW,iBAAG,8BAA8B,SAAS,KAAO,MAAO;AAAA,CACnF;AACD,aAAa,cAAc;AAI3B,IAAM,kBAAc,yBAAiD,CAAC,IAAyB,QAAQ;AAAjC,eAAE,YAxPxE,IAwPsE,IAAgB,kBAAhB,IAAgB,CAAd;AACtE,QAAM,MAAM,iBAAiB,aAAa;AAC1C,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,IAAI,IAAI;AAAA,MACR,eAAW,iBAAG,qDAAqD,SAAS;AAAA,OACxE;AAAA,EACN;AAEJ,CAAC;AACD,YAAY,cAAc;AAI1B,IAAM,wBAAoB;AAAA,EACxB,CAAC,IAAyB,QAAQ;AAAjC,iBAAE,YAxQL,IAwQG,IAAgB,kBAAhB,IAAgB,CAAd;AACD,UAAM,MAAM,iBAAiB,mBAAmB;AAChD,WACE,4CAAC,sBAAE,KAAU,IAAI,IAAI,eAAe,eAAW,iBAAG,oCAAoC,SAAS,KAAO,MAAO;AAAA,EAEjH;AACF;AACA,kBAAkB,cAAc;AAIhC,IAAM,mBAAe,yBAA8C,CAAC,IAAyB,QAAK;AAA9B,eAAE,YAnRtE,IAmRoE,IAAgB,kBAAhB,IAAgB,CAAd;AACpE,qDAAC,wBAAI,KAAU,eAAW,iBAAG,0DAA0D,SAAS,KAAO,MAAO;AAAA,CAC/G;AACD,aAAa,cAAc;AAM3B,IAAM,kBAAc,yBAAgD,CAAC,IAAwC,QAAQ;AAAhD,eAAE,YAAU,OAAO,QA5RxF,IA4RqE,IAA+B,kBAA/B,IAA+B,CAA7B,WAAiB;AACtF,QAAM,MAAM,iBAAiB,aAAa;AAC1C,QAAM,OAAO,UAAU,mBAAO;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAM,UAAU,SAAY;AAAA,MAC5B,SAAS,CAAC,MAA2C;AACnD,2CAAU;AACV,YAAI,CAAC,EAAE,iBAAkB,KAAI,QAAQ,KAAK;AAAA,MAC5C;AAAA,OACI;AAAA,EACN;AAEJ,CAAC;AACD,YAAY,cAAc;","names":["_a","_b"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/dialog.tsx"],"sourcesContent":["export { Dialog, DialogTrigger, DialogContent, DialogContentBase, DialogCloseIcon, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, dialogVariants } from \"./dialog\"\nexport type { DialogProps, DialogTriggerProps, DialogContentProps, DialogContentBaseProps, DialogCloseIconProps, DialogHeaderProps, DialogTitleProps, DialogDescriptionProps, DialogFooterProps, DialogCloseProps } from \"./dialog\"\n","\"use client\"\n\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n} from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"@glob-ui/utils\"\nimport { useControllableState } from \"@glob-ui/hooks\"\nimport { Slot, composeRefs } from \"@glob-ui/slot\"\n\n// Scroll lock shared by every open dialog. Compensates the scrollbar width so the page does not shift.\nlet lockCount = 0\nlet savedStyles: { overflow: string; paddingRight: string } | null = null\n\nfunction lockScroll() {\n const html = document.documentElement\n if (lockCount === 0) {\n const scrollbarWidth = window.innerWidth - html.clientWidth\n savedStyles = { overflow: html.style.overflow, paddingRight: html.style.paddingRight }\n if (scrollbarWidth > 0) {\n const current = parseFloat(getComputedStyle(html).paddingRight) || 0\n html.style.paddingRight = `${current + scrollbarWidth}px`\n }\n html.style.overflow = \"hidden\"\n }\n lockCount++\n return () => {\n lockCount--\n if (lockCount === 0 && savedStyles) {\n html.style.overflow = savedStyles.overflow\n html.style.paddingRight = savedStyles.paddingRight\n savedStyles = null\n }\n }\n}\n\ninterface DialogContextValue {\n open: boolean\n setOpen: (open: boolean) => void\n contentId: string\n titleId: string\n descriptionId: string\n closeOnOutsideClick: boolean\n}\n\nconst DialogContext = createContext<DialogContextValue | null>(null)\n\nfunction useDialogContext(part: string) {\n const ctx = useContext(DialogContext)\n if (!ctx) throw new Error(`${part} must be used inside Dialog, Sheet or AlertDialog`)\n return ctx\n}\n\nexport interface DialogProps {\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n /** Close when the backdrop is clicked. */\n closeOnOutsideClick?: boolean\n children?: React.ReactNode\n}\n\nfunction Dialog({ open, defaultOpen = false, onOpenChange, closeOnOutsideClick = true, children }: DialogProps) {\n const [isOpen, setOpen] = useControllableState(open, defaultOpen, onOpenChange)\n const baseId = useId()\n\n return (\n <DialogContext.Provider\n value={{\n open: isOpen,\n setOpen,\n contentId: `${baseId}-content`,\n titleId: `${baseId}-title`,\n descriptionId: `${baseId}-description`,\n closeOnOutsideClick,\n }}\n >\n {children}\n </DialogContext.Provider>\n )\n}\nDialog.displayName = \"Dialog\"\n\nexport interface DialogTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean\n}\n\nconst DialogTrigger = forwardRef<HTMLButtonElement, DialogTriggerProps>(\n ({ asChild = false, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogTrigger\")\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n ref={ref}\n type={asChild ? undefined : \"button\"}\n aria-haspopup=\"dialog\"\n aria-expanded={ctx.open}\n aria-controls={ctx.open ? ctx.contentId : undefined}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (!e.defaultPrevented) ctx.setOpen(true)\n }}\n {...props}\n />\n )\n }\n)\nDialogTrigger.displayName = \"DialogTrigger\"\n\nexport const dialogVariants = cva(\n [\n \"m-auto max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] overflow-visible rounded-glob-lg border border-glob-border bg-glob-surface p-0 text-glob-text shadow-glob-md\",\n // Enter/exit. @starting-style animates the entry; allow-discrete keeps display/overlay alive\n // during the exit. Browsers without them open and close without animation.\n \"scale-95 opacity-0 transition-[opacity,scale,overlay,display] transition-discrete duration-200 ease-out\",\n \"open:scale-100 open:opacity-100 starting:open:scale-95 starting:open:opacity-0\",\n \"backdrop:bg-glob-overlay backdrop:opacity-0 backdrop:transition-[opacity,overlay,display] backdrop:transition-discrete backdrop:duration-200\",\n \"open:backdrop:opacity-100 starting:open:backdrop:opacity-0\",\n \"motion-reduce:transition-none motion-reduce:backdrop:transition-none\",\n ],\n {\n variants: {\n size: {\n sm: \"max-w-sm\",\n md: \"max-w-lg\",\n lg: \"max-w-2xl\",\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n }\n)\n\nexport type DialogContentBaseProps = React.DialogHTMLAttributes<HTMLDialogElement>\n\n/**\n * The modal behaviour of Dialog with no styles and no layout: showModal, the shared scroll lock,\n * Esc, backdrop click (see closeOnOutsideClick), focus return and aria-labelledby/describedby.\n * Build your own modal on the same behaviour. Sheet and AlertDialog are built on it.\n */\nconst DialogContentBase = forwardRef<HTMLDialogElement, DialogContentBaseProps>(\n ({ className, children, onCancel, onClose, onPointerDown, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogContent\")\n const { open, setOpen, titleId, descriptionId, closeOnOutsideClick } = ctx\n const innerRef = useRef<HTMLDialogElement>(null)\n const previouslyFocused = useRef<HTMLElement | null>(null)\n const pointerDownOnBackdrop = useRef(false)\n const mergedRef = useMemo(() => composeRefs(ref, innerRef), [ref])\n const hasOwnLabel = props[\"aria-labelledby\"] !== undefined || props[\"aria-label\"] !== undefined\n const hasOwnDescription = props[\"aria-describedby\"] !== undefined\n\n useEffect(() => {\n const dialog = innerRef.current\n if (!dialog) return\n if (!open) {\n if (dialog.open) dialog.close()\n return\n }\n if (!dialog.open) {\n previouslyFocused.current = document.activeElement as HTMLElement | null\n // Point at Title/Description only if they are rendered, so the references never dangle.\n if (!hasOwnLabel) {\n if (document.getElementById(titleId)) dialog.setAttribute(\"aria-labelledby\", titleId)\n else dialog.removeAttribute(\"aria-labelledby\")\n }\n if (!hasOwnDescription) {\n if (document.getElementById(descriptionId)) dialog.setAttribute(\"aria-describedby\", descriptionId)\n else dialog.removeAttribute(\"aria-describedby\")\n }\n dialog.showModal()\n }\n return lockScroll()\n }, [open, titleId, descriptionId, hasOwnLabel, hasOwnDescription])\n\n return (\n <dialog\n ref={mergedRef}\n id={ctx.contentId}\n className={cn(className)}\n // Esc: keep React state as the source of truth (controlled dialogs may refuse to close).\n onCancel={(e) => {\n onCancel?.(e)\n e.preventDefault()\n setOpen(false)\n }}\n // Closed by the browser anyway (e.g. a repeated Esc that cannot be cancelled): sync state.\n onClose={(e) => {\n onClose?.(e)\n if (open) setOpen(false)\n const active = document.activeElement\n if (!active || active === document.body || innerRef.current?.contains(active)) {\n previouslyFocused.current?.focus()\n }\n }}\n // A click lands on the <dialog> element itself only over the backdrop: content fills it.\n onPointerDown={(e) => {\n onPointerDown?.(e)\n pointerDownOnBackdrop.current = e.target === e.currentTarget\n }}\n onClick={(e) => {\n onClick?.(e)\n if (e.defaultPrevented) return\n if (closeOnOutsideClick && pointerDownOnBackdrop.current && e.target === e.currentTarget) {\n setOpen(false)\n }\n }}\n {...props}\n >\n {children}\n </dialog>\n )\n }\n)\nDialogContentBase.displayName = \"DialogContentBase\"\n\nexport type DialogCloseIconProps = React.ButtonHTMLAttributes<HTMLButtonElement>\n\n/** The X button in the top-right corner. Closes the surrounding Dialog, Sheet or AlertDialog. */\nconst DialogCloseIcon = forwardRef<HTMLButtonElement, DialogCloseIconProps>(({ className, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogCloseIcon\")\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Close\"\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) ctx.setOpen(false)\n }}\n className={cn(\n \"absolute right-4 top-4 inline-flex h-8 w-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring\",\n className\n )}\n {...props}\n >\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"h-4 w-4\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n )\n})\nDialogCloseIcon.displayName = \"DialogCloseIcon\"\n\nexport interface DialogContentProps\n extends React.DialogHTMLAttributes<HTMLDialogElement>,\n VariantProps<typeof dialogVariants> {\n /** Shows an X button in the top-right corner. */\n showCloseButton?: boolean\n}\n\nconst DialogContent = forwardRef<HTMLDialogElement, DialogContentProps>(\n ({ className, size, showCloseButton = true, children, ...props }, ref) => (\n <DialogContentBase ref={ref} className={cn(dialogVariants({ size, className }))} {...props}>\n <div className=\"relative flex max-h-[calc(100dvh-2rem)] flex-col gap-4 overflow-y-auto p-6\">\n {children}\n {showCloseButton && <DialogCloseIcon />}\n </div>\n </DialogContentBase>\n )\n)\nDialogContent.displayName = \"DialogContent\"\n\nexport type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement>\n\nconst DialogHeader = forwardRef<HTMLDivElement, DialogHeaderProps>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"flex flex-col gap-1.5 pr-8\", className)} {...props} />\n))\nDialogHeader.displayName = \"DialogHeader\"\n\nexport type DialogTitleProps = React.HTMLAttributes<HTMLHeadingElement>\n\nconst DialogTitle = forwardRef<HTMLHeadingElement, DialogTitleProps>(({ className, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogTitle\")\n return (\n <h2\n ref={ref}\n id={ctx.titleId}\n className={cn(\"text-lg font-semibold leading-none tracking-tight\", className)}\n {...props}\n />\n )\n})\nDialogTitle.displayName = \"DialogTitle\"\n\nexport type DialogDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>\n\nconst DialogDescription = forwardRef<HTMLParagraphElement, DialogDescriptionProps>(\n ({ className, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogDescription\")\n return (\n <p ref={ref} id={ctx.descriptionId} className={cn(\"text-sm text-glob-text-secondary\", className)} {...props} />\n )\n }\n)\nDialogDescription.displayName = \"DialogDescription\"\n\nexport type DialogFooterProps = React.HTMLAttributes<HTMLDivElement>\n\nconst DialogFooter = forwardRef<HTMLDivElement, DialogFooterProps>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)} {...props} />\n))\nDialogFooter.displayName = \"DialogFooter\"\n\nexport interface DialogCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean\n}\n\nconst DialogClose = forwardRef<HTMLButtonElement, DialogCloseProps>(({ asChild = false, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogClose\")\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n ref={ref}\n type={asChild ? undefined : \"button\"}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (!e.defaultPrevented) ctx.setOpen(false)\n }}\n {...props}\n />\n )\n})\nDialogClose.displayName = \"DialogClose\"\n\nexport {\n Dialog,\n DialogTrigger,\n DialogContent,\n DialogContentBase,\n DialogCloseIcon,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n DialogClose,\n}\n"],"mappings":"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","names":["_a","_b"]}
|
package/dist/index.mjs
CHANGED
|
@@ -72,7 +72,7 @@ function lockScroll() {
|
|
|
72
72
|
var DialogContext = createContext(null);
|
|
73
73
|
function useDialogContext(part) {
|
|
74
74
|
const ctx = useContext(DialogContext);
|
|
75
|
-
if (!ctx) throw new Error(`${part} must be used inside Dialog`);
|
|
75
|
+
if (!ctx) throw new Error(`${part} must be used inside Dialog, Sheet or AlertDialog`);
|
|
76
76
|
return ctx;
|
|
77
77
|
}
|
|
78
78
|
function Dialog({ open, defaultOpen = false, onOpenChange, closeOnOutsideClick = true, children }) {
|
|
@@ -140,9 +140,9 @@ var dialogVariants = cva(
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
);
|
|
143
|
-
var
|
|
143
|
+
var DialogContentBase = forwardRef(
|
|
144
144
|
(_a, ref) => {
|
|
145
|
-
var _b = _a, { className,
|
|
145
|
+
var _b = _a, { className, children, onCancel, onClose, onPointerDown, onClick } = _b, props = __objRest(_b, ["className", "children", "onCancel", "onClose", "onPointerDown", "onClick"]);
|
|
146
146
|
const ctx = useDialogContext("DialogContent");
|
|
147
147
|
const { open, setOpen, titleId, descriptionId, closeOnOutsideClick } = ctx;
|
|
148
148
|
const innerRef = useRef(null);
|
|
@@ -177,7 +177,7 @@ var DialogContent = forwardRef(
|
|
|
177
177
|
__spreadProps(__spreadValues({
|
|
178
178
|
ref: mergedRef,
|
|
179
179
|
id: ctx.contentId,
|
|
180
|
-
className: cn(
|
|
180
|
+
className: cn(className),
|
|
181
181
|
onCancel: (e) => {
|
|
182
182
|
onCancel == null ? void 0 : onCancel(e);
|
|
183
183
|
e.preventDefault();
|
|
@@ -204,23 +204,44 @@ var DialogContent = forwardRef(
|
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
206
|
}, props), {
|
|
207
|
-
children
|
|
208
|
-
children,
|
|
209
|
-
showCloseButton && /* @__PURE__ */ jsx(
|
|
210
|
-
"button",
|
|
211
|
-
{
|
|
212
|
-
type: "button",
|
|
213
|
-
"aria-label": "Close",
|
|
214
|
-
onClick: () => setOpen(false),
|
|
215
|
-
className: "absolute right-4 top-4 inline-flex h-8 w-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring",
|
|
216
|
-
children: /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "h-4 w-4", children: /* @__PURE__ */ jsx("path", { d: "M18 6L6 18M6 6l12 12" }) })
|
|
217
|
-
}
|
|
218
|
-
)
|
|
219
|
-
] })
|
|
207
|
+
children
|
|
220
208
|
})
|
|
221
209
|
);
|
|
222
210
|
}
|
|
223
211
|
);
|
|
212
|
+
DialogContentBase.displayName = "DialogContentBase";
|
|
213
|
+
var DialogCloseIcon = forwardRef((_a, ref) => {
|
|
214
|
+
var _b = _a, { className, onClick } = _b, props = __objRest(_b, ["className", "onClick"]);
|
|
215
|
+
const ctx = useDialogContext("DialogCloseIcon");
|
|
216
|
+
return /* @__PURE__ */ jsx(
|
|
217
|
+
"button",
|
|
218
|
+
__spreadProps(__spreadValues({
|
|
219
|
+
ref,
|
|
220
|
+
type: "button",
|
|
221
|
+
"aria-label": "Close",
|
|
222
|
+
onClick: (e) => {
|
|
223
|
+
onClick == null ? void 0 : onClick(e);
|
|
224
|
+
if (!e.defaultPrevented) ctx.setOpen(false);
|
|
225
|
+
},
|
|
226
|
+
className: cn(
|
|
227
|
+
"absolute right-4 top-4 inline-flex h-8 w-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring",
|
|
228
|
+
className
|
|
229
|
+
)
|
|
230
|
+
}, props), {
|
|
231
|
+
children: /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "h-4 w-4", children: /* @__PURE__ */ jsx("path", { d: "M18 6L6 18M6 6l12 12" }) })
|
|
232
|
+
})
|
|
233
|
+
);
|
|
234
|
+
});
|
|
235
|
+
DialogCloseIcon.displayName = "DialogCloseIcon";
|
|
236
|
+
var DialogContent = forwardRef(
|
|
237
|
+
(_a, ref) => {
|
|
238
|
+
var _b = _a, { className, size, showCloseButton = true, children } = _b, props = __objRest(_b, ["className", "size", "showCloseButton", "children"]);
|
|
239
|
+
return /* @__PURE__ */ jsx(DialogContentBase, __spreadProps(__spreadValues({ ref, className: cn(dialogVariants({ size, className })) }, props), { children: /* @__PURE__ */ jsxs("div", { className: "relative flex max-h-[calc(100dvh-2rem)] flex-col gap-4 overflow-y-auto p-6", children: [
|
|
240
|
+
children,
|
|
241
|
+
showCloseButton && /* @__PURE__ */ jsx(DialogCloseIcon, {})
|
|
242
|
+
] }) }));
|
|
243
|
+
}
|
|
244
|
+
);
|
|
224
245
|
DialogContent.displayName = "DialogContent";
|
|
225
246
|
var DialogHeader = forwardRef((_a, ref) => {
|
|
226
247
|
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
@@ -273,11 +294,14 @@ DialogClose.displayName = "DialogClose";
|
|
|
273
294
|
export {
|
|
274
295
|
Dialog,
|
|
275
296
|
DialogClose,
|
|
297
|
+
DialogCloseIcon,
|
|
276
298
|
DialogContent,
|
|
299
|
+
DialogContentBase,
|
|
277
300
|
DialogDescription,
|
|
278
301
|
DialogFooter,
|
|
279
302
|
DialogHeader,
|
|
280
303
|
DialogTitle,
|
|
281
|
-
DialogTrigger
|
|
304
|
+
DialogTrigger,
|
|
305
|
+
dialogVariants
|
|
282
306
|
};
|
|
283
307
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dialog.tsx"],"sourcesContent":["\"use client\"\n\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n} from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"@glob-ui/utils\"\nimport { useControllableState } from \"@glob-ui/hooks\"\nimport { Slot, composeRefs } from \"@glob-ui/slot\"\n\n// Scroll lock shared by every open dialog. Compensates the scrollbar width so the page does not shift.\nlet lockCount = 0\nlet savedStyles: { overflow: string; paddingRight: string } | null = null\n\nfunction lockScroll() {\n const html = document.documentElement\n if (lockCount === 0) {\n const scrollbarWidth = window.innerWidth - html.clientWidth\n savedStyles = { overflow: html.style.overflow, paddingRight: html.style.paddingRight }\n if (scrollbarWidth > 0) {\n const current = parseFloat(getComputedStyle(html).paddingRight) || 0\n html.style.paddingRight = `${current + scrollbarWidth}px`\n }\n html.style.overflow = \"hidden\"\n }\n lockCount++\n return () => {\n lockCount--\n if (lockCount === 0 && savedStyles) {\n html.style.overflow = savedStyles.overflow\n html.style.paddingRight = savedStyles.paddingRight\n savedStyles = null\n }\n }\n}\n\ninterface DialogContextValue {\n open: boolean\n setOpen: (open: boolean) => void\n contentId: string\n titleId: string\n descriptionId: string\n closeOnOutsideClick: boolean\n}\n\nconst DialogContext = createContext<DialogContextValue | null>(null)\n\nfunction useDialogContext(part: string) {\n const ctx = useContext(DialogContext)\n if (!ctx) throw new Error(`${part} must be used inside Dialog`)\n return ctx\n}\n\nexport interface DialogProps {\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n /** Close when the backdrop is clicked. */\n closeOnOutsideClick?: boolean\n children?: React.ReactNode\n}\n\nfunction Dialog({ open, defaultOpen = false, onOpenChange, closeOnOutsideClick = true, children }: DialogProps) {\n const [isOpen, setOpen] = useControllableState(open, defaultOpen, onOpenChange)\n const baseId = useId()\n\n return (\n <DialogContext.Provider\n value={{\n open: isOpen,\n setOpen,\n contentId: `${baseId}-content`,\n titleId: `${baseId}-title`,\n descriptionId: `${baseId}-description`,\n closeOnOutsideClick,\n }}\n >\n {children}\n </DialogContext.Provider>\n )\n}\nDialog.displayName = \"Dialog\"\n\nexport interface DialogTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean\n}\n\nconst DialogTrigger = forwardRef<HTMLButtonElement, DialogTriggerProps>(\n ({ asChild = false, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogTrigger\")\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n ref={ref}\n type={asChild ? undefined : \"button\"}\n aria-haspopup=\"dialog\"\n aria-expanded={ctx.open}\n aria-controls={ctx.open ? ctx.contentId : undefined}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (!e.defaultPrevented) ctx.setOpen(true)\n }}\n {...props}\n />\n )\n }\n)\nDialogTrigger.displayName = \"DialogTrigger\"\n\nconst dialogVariants = cva(\n [\n \"m-auto max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] overflow-visible rounded-glob-lg border border-glob-border bg-glob-surface p-0 text-glob-text shadow-glob-md\",\n // Enter/exit. @starting-style animates the entry; allow-discrete keeps display/overlay alive\n // during the exit. Browsers without them open and close without animation.\n \"scale-95 opacity-0 transition-[opacity,scale,overlay,display] transition-discrete duration-200 ease-out\",\n \"open:scale-100 open:opacity-100 starting:open:scale-95 starting:open:opacity-0\",\n \"backdrop:bg-glob-overlay backdrop:opacity-0 backdrop:transition-[opacity,overlay,display] backdrop:transition-discrete backdrop:duration-200\",\n \"open:backdrop:opacity-100 starting:open:backdrop:opacity-0\",\n \"motion-reduce:transition-none motion-reduce:backdrop:transition-none\",\n ],\n {\n variants: {\n size: {\n sm: \"max-w-sm\",\n md: \"max-w-lg\",\n lg: \"max-w-2xl\",\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n }\n)\n\nexport interface DialogContentProps\n extends React.DialogHTMLAttributes<HTMLDialogElement>,\n VariantProps<typeof dialogVariants> {\n /** Shows an X button in the top-right corner. */\n showCloseButton?: boolean\n}\n\nconst DialogContent = forwardRef<HTMLDialogElement, DialogContentProps>(\n (\n { className, size, showCloseButton = true, children, onCancel, onClose, onPointerDown, onClick, ...props },\n ref\n ) => {\n const ctx = useDialogContext(\"DialogContent\")\n const { open, setOpen, titleId, descriptionId, closeOnOutsideClick } = ctx\n const innerRef = useRef<HTMLDialogElement>(null)\n const previouslyFocused = useRef<HTMLElement | null>(null)\n const pointerDownOnBackdrop = useRef(false)\n const mergedRef = useMemo(() => composeRefs(ref, innerRef), [ref])\n const hasOwnLabel = props[\"aria-labelledby\"] !== undefined || props[\"aria-label\"] !== undefined\n const hasOwnDescription = props[\"aria-describedby\"] !== undefined\n\n useEffect(() => {\n const dialog = innerRef.current\n if (!dialog) return\n if (!open) {\n if (dialog.open) dialog.close()\n return\n }\n if (!dialog.open) {\n previouslyFocused.current = document.activeElement as HTMLElement | null\n // Point at Title/Description only if they are rendered, so the references never dangle.\n if (!hasOwnLabel) {\n if (document.getElementById(titleId)) dialog.setAttribute(\"aria-labelledby\", titleId)\n else dialog.removeAttribute(\"aria-labelledby\")\n }\n if (!hasOwnDescription) {\n if (document.getElementById(descriptionId)) dialog.setAttribute(\"aria-describedby\", descriptionId)\n else dialog.removeAttribute(\"aria-describedby\")\n }\n dialog.showModal()\n }\n return lockScroll()\n }, [open, titleId, descriptionId, hasOwnLabel, hasOwnDescription])\n\n return (\n <dialog\n ref={mergedRef}\n id={ctx.contentId}\n className={cn(dialogVariants({ size, className }))}\n // Esc: keep React state as the source of truth (controlled dialogs may refuse to close).\n onCancel={(e) => {\n onCancel?.(e)\n e.preventDefault()\n setOpen(false)\n }}\n // Closed by the browser anyway (e.g. a repeated Esc that cannot be cancelled): sync state.\n onClose={(e) => {\n onClose?.(e)\n if (open) setOpen(false)\n const active = document.activeElement\n if (!active || active === document.body || innerRef.current?.contains(active)) {\n previouslyFocused.current?.focus()\n }\n }}\n // A click lands on the <dialog> element itself only over the backdrop: content fills it.\n onPointerDown={(e) => {\n onPointerDown?.(e)\n pointerDownOnBackdrop.current = e.target === e.currentTarget\n }}\n onClick={(e) => {\n onClick?.(e)\n if (e.defaultPrevented) return\n if (closeOnOutsideClick && pointerDownOnBackdrop.current && e.target === e.currentTarget) {\n setOpen(false)\n }\n }}\n {...props}\n >\n <div className=\"relative flex max-h-[calc(100dvh-2rem)] flex-col gap-4 overflow-y-auto p-6\">\n {children}\n {showCloseButton && (\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={() => setOpen(false)}\n className=\"absolute right-4 top-4 inline-flex h-8 w-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring\"\n >\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"h-4 w-4\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n )}\n </div>\n </dialog>\n )\n }\n)\nDialogContent.displayName = \"DialogContent\"\n\nexport type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement>\n\nconst DialogHeader = forwardRef<HTMLDivElement, DialogHeaderProps>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"flex flex-col gap-1.5 pr-8\", className)} {...props} />\n))\nDialogHeader.displayName = \"DialogHeader\"\n\nexport type DialogTitleProps = React.HTMLAttributes<HTMLHeadingElement>\n\nconst DialogTitle = forwardRef<HTMLHeadingElement, DialogTitleProps>(({ className, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogTitle\")\n return (\n <h2\n ref={ref}\n id={ctx.titleId}\n className={cn(\"text-lg font-semibold leading-none tracking-tight\", className)}\n {...props}\n />\n )\n})\nDialogTitle.displayName = \"DialogTitle\"\n\nexport type DialogDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>\n\nconst DialogDescription = forwardRef<HTMLParagraphElement, DialogDescriptionProps>(\n ({ className, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogDescription\")\n return (\n <p ref={ref} id={ctx.descriptionId} className={cn(\"text-sm text-glob-text-secondary\", className)} {...props} />\n )\n }\n)\nDialogDescription.displayName = \"DialogDescription\"\n\nexport type DialogFooterProps = React.HTMLAttributes<HTMLDivElement>\n\nconst DialogFooter = forwardRef<HTMLDivElement, DialogFooterProps>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)} {...props} />\n))\nDialogFooter.displayName = \"DialogFooter\"\n\nexport interface DialogCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean\n}\n\nconst DialogClose = forwardRef<HTMLButtonElement, DialogCloseProps>(({ asChild = false, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogClose\")\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n ref={ref}\n type={asChild ? undefined : \"button\"}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (!e.defaultPrevented) ctx.setOpen(false)\n }}\n {...props}\n />\n )\n})\nDialogClose.displayName = \"DialogClose\"\n\nexport {\n Dialog,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n DialogClose,\n}\n"],"mappings":"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","names":["_a","_b"]}
|
|
1
|
+
{"version":3,"sources":["../src/dialog.tsx"],"sourcesContent":["\"use client\"\n\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n} from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"@glob-ui/utils\"\nimport { useControllableState } from \"@glob-ui/hooks\"\nimport { Slot, composeRefs } from \"@glob-ui/slot\"\n\n// Scroll lock shared by every open dialog. Compensates the scrollbar width so the page does not shift.\nlet lockCount = 0\nlet savedStyles: { overflow: string; paddingRight: string } | null = null\n\nfunction lockScroll() {\n const html = document.documentElement\n if (lockCount === 0) {\n const scrollbarWidth = window.innerWidth - html.clientWidth\n savedStyles = { overflow: html.style.overflow, paddingRight: html.style.paddingRight }\n if (scrollbarWidth > 0) {\n const current = parseFloat(getComputedStyle(html).paddingRight) || 0\n html.style.paddingRight = `${current + scrollbarWidth}px`\n }\n html.style.overflow = \"hidden\"\n }\n lockCount++\n return () => {\n lockCount--\n if (lockCount === 0 && savedStyles) {\n html.style.overflow = savedStyles.overflow\n html.style.paddingRight = savedStyles.paddingRight\n savedStyles = null\n }\n }\n}\n\ninterface DialogContextValue {\n open: boolean\n setOpen: (open: boolean) => void\n contentId: string\n titleId: string\n descriptionId: string\n closeOnOutsideClick: boolean\n}\n\nconst DialogContext = createContext<DialogContextValue | null>(null)\n\nfunction useDialogContext(part: string) {\n const ctx = useContext(DialogContext)\n if (!ctx) throw new Error(`${part} must be used inside Dialog, Sheet or AlertDialog`)\n return ctx\n}\n\nexport interface DialogProps {\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n /** Close when the backdrop is clicked. */\n closeOnOutsideClick?: boolean\n children?: React.ReactNode\n}\n\nfunction Dialog({ open, defaultOpen = false, onOpenChange, closeOnOutsideClick = true, children }: DialogProps) {\n const [isOpen, setOpen] = useControllableState(open, defaultOpen, onOpenChange)\n const baseId = useId()\n\n return (\n <DialogContext.Provider\n value={{\n open: isOpen,\n setOpen,\n contentId: `${baseId}-content`,\n titleId: `${baseId}-title`,\n descriptionId: `${baseId}-description`,\n closeOnOutsideClick,\n }}\n >\n {children}\n </DialogContext.Provider>\n )\n}\nDialog.displayName = \"Dialog\"\n\nexport interface DialogTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean\n}\n\nconst DialogTrigger = forwardRef<HTMLButtonElement, DialogTriggerProps>(\n ({ asChild = false, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogTrigger\")\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n ref={ref}\n type={asChild ? undefined : \"button\"}\n aria-haspopup=\"dialog\"\n aria-expanded={ctx.open}\n aria-controls={ctx.open ? ctx.contentId : undefined}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (!e.defaultPrevented) ctx.setOpen(true)\n }}\n {...props}\n />\n )\n }\n)\nDialogTrigger.displayName = \"DialogTrigger\"\n\nexport const dialogVariants = cva(\n [\n \"m-auto max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] overflow-visible rounded-glob-lg border border-glob-border bg-glob-surface p-0 text-glob-text shadow-glob-md\",\n // Enter/exit. @starting-style animates the entry; allow-discrete keeps display/overlay alive\n // during the exit. Browsers without them open and close without animation.\n \"scale-95 opacity-0 transition-[opacity,scale,overlay,display] transition-discrete duration-200 ease-out\",\n \"open:scale-100 open:opacity-100 starting:open:scale-95 starting:open:opacity-0\",\n \"backdrop:bg-glob-overlay backdrop:opacity-0 backdrop:transition-[opacity,overlay,display] backdrop:transition-discrete backdrop:duration-200\",\n \"open:backdrop:opacity-100 starting:open:backdrop:opacity-0\",\n \"motion-reduce:transition-none motion-reduce:backdrop:transition-none\",\n ],\n {\n variants: {\n size: {\n sm: \"max-w-sm\",\n md: \"max-w-lg\",\n lg: \"max-w-2xl\",\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n }\n)\n\nexport type DialogContentBaseProps = React.DialogHTMLAttributes<HTMLDialogElement>\n\n/**\n * The modal behaviour of Dialog with no styles and no layout: showModal, the shared scroll lock,\n * Esc, backdrop click (see closeOnOutsideClick), focus return and aria-labelledby/describedby.\n * Build your own modal on the same behaviour. Sheet and AlertDialog are built on it.\n */\nconst DialogContentBase = forwardRef<HTMLDialogElement, DialogContentBaseProps>(\n ({ className, children, onCancel, onClose, onPointerDown, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogContent\")\n const { open, setOpen, titleId, descriptionId, closeOnOutsideClick } = ctx\n const innerRef = useRef<HTMLDialogElement>(null)\n const previouslyFocused = useRef<HTMLElement | null>(null)\n const pointerDownOnBackdrop = useRef(false)\n const mergedRef = useMemo(() => composeRefs(ref, innerRef), [ref])\n const hasOwnLabel = props[\"aria-labelledby\"] !== undefined || props[\"aria-label\"] !== undefined\n const hasOwnDescription = props[\"aria-describedby\"] !== undefined\n\n useEffect(() => {\n const dialog = innerRef.current\n if (!dialog) return\n if (!open) {\n if (dialog.open) dialog.close()\n return\n }\n if (!dialog.open) {\n previouslyFocused.current = document.activeElement as HTMLElement | null\n // Point at Title/Description only if they are rendered, so the references never dangle.\n if (!hasOwnLabel) {\n if (document.getElementById(titleId)) dialog.setAttribute(\"aria-labelledby\", titleId)\n else dialog.removeAttribute(\"aria-labelledby\")\n }\n if (!hasOwnDescription) {\n if (document.getElementById(descriptionId)) dialog.setAttribute(\"aria-describedby\", descriptionId)\n else dialog.removeAttribute(\"aria-describedby\")\n }\n dialog.showModal()\n }\n return lockScroll()\n }, [open, titleId, descriptionId, hasOwnLabel, hasOwnDescription])\n\n return (\n <dialog\n ref={mergedRef}\n id={ctx.contentId}\n className={cn(className)}\n // Esc: keep React state as the source of truth (controlled dialogs may refuse to close).\n onCancel={(e) => {\n onCancel?.(e)\n e.preventDefault()\n setOpen(false)\n }}\n // Closed by the browser anyway (e.g. a repeated Esc that cannot be cancelled): sync state.\n onClose={(e) => {\n onClose?.(e)\n if (open) setOpen(false)\n const active = document.activeElement\n if (!active || active === document.body || innerRef.current?.contains(active)) {\n previouslyFocused.current?.focus()\n }\n }}\n // A click lands on the <dialog> element itself only over the backdrop: content fills it.\n onPointerDown={(e) => {\n onPointerDown?.(e)\n pointerDownOnBackdrop.current = e.target === e.currentTarget\n }}\n onClick={(e) => {\n onClick?.(e)\n if (e.defaultPrevented) return\n if (closeOnOutsideClick && pointerDownOnBackdrop.current && e.target === e.currentTarget) {\n setOpen(false)\n }\n }}\n {...props}\n >\n {children}\n </dialog>\n )\n }\n)\nDialogContentBase.displayName = \"DialogContentBase\"\n\nexport type DialogCloseIconProps = React.ButtonHTMLAttributes<HTMLButtonElement>\n\n/** The X button in the top-right corner. Closes the surrounding Dialog, Sheet or AlertDialog. */\nconst DialogCloseIcon = forwardRef<HTMLButtonElement, DialogCloseIconProps>(({ className, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogCloseIcon\")\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Close\"\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) ctx.setOpen(false)\n }}\n className={cn(\n \"absolute right-4 top-4 inline-flex h-8 w-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring\",\n className\n )}\n {...props}\n >\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"h-4 w-4\">\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n )\n})\nDialogCloseIcon.displayName = \"DialogCloseIcon\"\n\nexport interface DialogContentProps\n extends React.DialogHTMLAttributes<HTMLDialogElement>,\n VariantProps<typeof dialogVariants> {\n /** Shows an X button in the top-right corner. */\n showCloseButton?: boolean\n}\n\nconst DialogContent = forwardRef<HTMLDialogElement, DialogContentProps>(\n ({ className, size, showCloseButton = true, children, ...props }, ref) => (\n <DialogContentBase ref={ref} className={cn(dialogVariants({ size, className }))} {...props}>\n <div className=\"relative flex max-h-[calc(100dvh-2rem)] flex-col gap-4 overflow-y-auto p-6\">\n {children}\n {showCloseButton && <DialogCloseIcon />}\n </div>\n </DialogContentBase>\n )\n)\nDialogContent.displayName = \"DialogContent\"\n\nexport type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement>\n\nconst DialogHeader = forwardRef<HTMLDivElement, DialogHeaderProps>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"flex flex-col gap-1.5 pr-8\", className)} {...props} />\n))\nDialogHeader.displayName = \"DialogHeader\"\n\nexport type DialogTitleProps = React.HTMLAttributes<HTMLHeadingElement>\n\nconst DialogTitle = forwardRef<HTMLHeadingElement, DialogTitleProps>(({ className, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogTitle\")\n return (\n <h2\n ref={ref}\n id={ctx.titleId}\n className={cn(\"text-lg font-semibold leading-none tracking-tight\", className)}\n {...props}\n />\n )\n})\nDialogTitle.displayName = \"DialogTitle\"\n\nexport type DialogDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>\n\nconst DialogDescription = forwardRef<HTMLParagraphElement, DialogDescriptionProps>(\n ({ className, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogDescription\")\n return (\n <p ref={ref} id={ctx.descriptionId} className={cn(\"text-sm text-glob-text-secondary\", className)} {...props} />\n )\n }\n)\nDialogDescription.displayName = \"DialogDescription\"\n\nexport type DialogFooterProps = React.HTMLAttributes<HTMLDivElement>\n\nconst DialogFooter = forwardRef<HTMLDivElement, DialogFooterProps>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)} {...props} />\n))\nDialogFooter.displayName = \"DialogFooter\"\n\nexport interface DialogCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean\n}\n\nconst DialogClose = forwardRef<HTMLButtonElement, DialogCloseProps>(({ asChild = false, onClick, ...props }, ref) => {\n const ctx = useDialogContext(\"DialogClose\")\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n ref={ref}\n type={asChild ? undefined : \"button\"}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (!e.defaultPrevented) ctx.setOpen(false)\n }}\n {...props}\n />\n )\n})\nDialogClose.displayName = \"DialogClose\"\n\nexport {\n Dialog,\n DialogTrigger,\n DialogContent,\n DialogContentBase,\n DialogCloseIcon,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n DialogClose,\n}\n"],"mappings":"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","names":["_a","_b"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glob-ui/dialog",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
"react": "^19"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@glob-ui/hooks": "0.
|
|
30
|
-
"@glob-ui/slot": "0.
|
|
31
|
-
"@glob-ui/utils": "0.
|
|
29
|
+
"@glob-ui/hooks": "0.2.0",
|
|
30
|
+
"@glob-ui/slot": "0.2.0",
|
|
31
|
+
"@glob-ui/utils": "0.2.0",
|
|
32
32
|
"class-variance-authority": "^0.7.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"tsup": "^8.5.1"
|
|
36
36
|
},
|
|
37
|
-
"description": "A modal dialog on the native `<dialog>` element. Focus moves in, Escape closes it, and focus returns to the trigger.",
|
|
37
|
+
"description": "A modal dialog on the native `<dialog>` element. Focus moves in, Escape closes it, and focus returns to the trigger. Build your own modal on the same behaviour with `DialogContentBase`.",
|
|
38
38
|
"keywords": [
|
|
39
39
|
"react",
|
|
40
40
|
"glob-ui",
|