@glob-ui/dialog 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +16 -2
- package/dist/index.d.mts +53 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.js +333 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +307 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +67 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kevin Martínez E
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @glob-ui/dialog
|
|
2
2
|
|
|
3
|
-
|
|
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
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @glob-ui/dialog
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Documentation
|
|
12
|
+
|
|
13
|
+
Full docs, examples and the accessibility table: [Dialog](https://github.com/kevin-martineze/GlobUI/tree/main/apps/docs/content/docs/components/dialog.mdx).
|
|
14
|
+
|
|
15
|
+
## License
|
|
16
|
+
|
|
17
|
+
MIT. See [LICENSE](./LICENSE).
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { VariantProps } from 'class-variance-authority';
|
|
5
|
+
|
|
6
|
+
interface DialogProps {
|
|
7
|
+
open?: boolean;
|
|
8
|
+
defaultOpen?: boolean;
|
|
9
|
+
onOpenChange?: (open: boolean) => void;
|
|
10
|
+
/** Close when the backdrop is clicked. */
|
|
11
|
+
closeOnOutsideClick?: boolean;
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
}
|
|
14
|
+
declare function Dialog({ open, defaultOpen, onOpenChange, closeOnOutsideClick, children }: DialogProps): react_jsx_runtime.JSX.Element;
|
|
15
|
+
declare namespace Dialog {
|
|
16
|
+
var displayName: string;
|
|
17
|
+
}
|
|
18
|
+
interface DialogTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
19
|
+
asChild?: boolean;
|
|
20
|
+
}
|
|
21
|
+
declare const DialogTrigger: react.ForwardRefExoticComponent<DialogTriggerProps & react.RefAttributes<HTMLButtonElement>>;
|
|
22
|
+
declare const dialogVariants: (props?: ({
|
|
23
|
+
size?: "sm" | "md" | "lg" | null | undefined;
|
|
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>>;
|
|
35
|
+
interface DialogContentProps extends React.DialogHTMLAttributes<HTMLDialogElement>, VariantProps<typeof dialogVariants> {
|
|
36
|
+
/** Shows an X button in the top-right corner. */
|
|
37
|
+
showCloseButton?: boolean;
|
|
38
|
+
}
|
|
39
|
+
declare const DialogContent: react.ForwardRefExoticComponent<DialogContentProps & react.RefAttributes<HTMLDialogElement>>;
|
|
40
|
+
type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement>;
|
|
41
|
+
declare const DialogHeader: react.ForwardRefExoticComponent<DialogHeaderProps & react.RefAttributes<HTMLDivElement>>;
|
|
42
|
+
type DialogTitleProps = React.HTMLAttributes<HTMLHeadingElement>;
|
|
43
|
+
declare const DialogTitle: react.ForwardRefExoticComponent<DialogTitleProps & react.RefAttributes<HTMLHeadingElement>>;
|
|
44
|
+
type DialogDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>;
|
|
45
|
+
declare const DialogDescription: react.ForwardRefExoticComponent<DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>>;
|
|
46
|
+
type DialogFooterProps = React.HTMLAttributes<HTMLDivElement>;
|
|
47
|
+
declare const DialogFooter: react.ForwardRefExoticComponent<DialogFooterProps & react.RefAttributes<HTMLDivElement>>;
|
|
48
|
+
interface DialogCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
49
|
+
asChild?: boolean;
|
|
50
|
+
}
|
|
51
|
+
declare const DialogClose: react.ForwardRefExoticComponent<DialogCloseProps & react.RefAttributes<HTMLButtonElement>>;
|
|
52
|
+
|
|
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
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { VariantProps } from 'class-variance-authority';
|
|
5
|
+
|
|
6
|
+
interface DialogProps {
|
|
7
|
+
open?: boolean;
|
|
8
|
+
defaultOpen?: boolean;
|
|
9
|
+
onOpenChange?: (open: boolean) => void;
|
|
10
|
+
/** Close when the backdrop is clicked. */
|
|
11
|
+
closeOnOutsideClick?: boolean;
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
}
|
|
14
|
+
declare function Dialog({ open, defaultOpen, onOpenChange, closeOnOutsideClick, children }: DialogProps): react_jsx_runtime.JSX.Element;
|
|
15
|
+
declare namespace Dialog {
|
|
16
|
+
var displayName: string;
|
|
17
|
+
}
|
|
18
|
+
interface DialogTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
19
|
+
asChild?: boolean;
|
|
20
|
+
}
|
|
21
|
+
declare const DialogTrigger: react.ForwardRefExoticComponent<DialogTriggerProps & react.RefAttributes<HTMLButtonElement>>;
|
|
22
|
+
declare const dialogVariants: (props?: ({
|
|
23
|
+
size?: "sm" | "md" | "lg" | null | undefined;
|
|
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>>;
|
|
35
|
+
interface DialogContentProps extends React.DialogHTMLAttributes<HTMLDialogElement>, VariantProps<typeof dialogVariants> {
|
|
36
|
+
/** Shows an X button in the top-right corner. */
|
|
37
|
+
showCloseButton?: boolean;
|
|
38
|
+
}
|
|
39
|
+
declare const DialogContent: react.ForwardRefExoticComponent<DialogContentProps & react.RefAttributes<HTMLDialogElement>>;
|
|
40
|
+
type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement>;
|
|
41
|
+
declare const DialogHeader: react.ForwardRefExoticComponent<DialogHeaderProps & react.RefAttributes<HTMLDivElement>>;
|
|
42
|
+
type DialogTitleProps = React.HTMLAttributes<HTMLHeadingElement>;
|
|
43
|
+
declare const DialogTitle: react.ForwardRefExoticComponent<DialogTitleProps & react.RefAttributes<HTMLHeadingElement>>;
|
|
44
|
+
type DialogDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>;
|
|
45
|
+
declare const DialogDescription: react.ForwardRefExoticComponent<DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>>;
|
|
46
|
+
type DialogFooterProps = React.HTMLAttributes<HTMLDivElement>;
|
|
47
|
+
declare const DialogFooter: react.ForwardRefExoticComponent<DialogFooterProps & react.RefAttributes<HTMLDivElement>>;
|
|
48
|
+
interface DialogCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
49
|
+
asChild?: boolean;
|
|
50
|
+
}
|
|
51
|
+
declare const DialogClose: react.ForwardRefExoticComponent<DialogCloseProps & react.RefAttributes<HTMLButtonElement>>;
|
|
52
|
+
|
|
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
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProps = Object.defineProperties;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
+
var __spreadValues = (a, b) => {
|
|
13
|
+
for (var prop in b || (b = {}))
|
|
14
|
+
if (__hasOwnProp.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
if (__getOwnPropSymbols)
|
|
17
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
+
if (__propIsEnum.call(b, prop))
|
|
19
|
+
__defNormalProp(a, prop, b[prop]);
|
|
20
|
+
}
|
|
21
|
+
return a;
|
|
22
|
+
};
|
|
23
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
+
var __objRest = (source, exclude) => {
|
|
25
|
+
var target = {};
|
|
26
|
+
for (var prop in source)
|
|
27
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
if (source != null && __getOwnPropSymbols)
|
|
30
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
31
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
32
|
+
target[prop] = source[prop];
|
|
33
|
+
}
|
|
34
|
+
return target;
|
|
35
|
+
};
|
|
36
|
+
var __export = (target, all) => {
|
|
37
|
+
for (var name in all)
|
|
38
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
39
|
+
};
|
|
40
|
+
var __copyProps = (to, from, except, desc) => {
|
|
41
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
42
|
+
for (let key of __getOwnPropNames(from))
|
|
43
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
44
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
45
|
+
}
|
|
46
|
+
return to;
|
|
47
|
+
};
|
|
48
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
49
|
+
|
|
50
|
+
// src/index.ts
|
|
51
|
+
var index_exports = {};
|
|
52
|
+
__export(index_exports, {
|
|
53
|
+
Dialog: () => Dialog,
|
|
54
|
+
DialogClose: () => DialogClose,
|
|
55
|
+
DialogCloseIcon: () => DialogCloseIcon,
|
|
56
|
+
DialogContent: () => DialogContent,
|
|
57
|
+
DialogContentBase: () => DialogContentBase,
|
|
58
|
+
DialogDescription: () => DialogDescription,
|
|
59
|
+
DialogFooter: () => DialogFooter,
|
|
60
|
+
DialogHeader: () => DialogHeader,
|
|
61
|
+
DialogTitle: () => DialogTitle,
|
|
62
|
+
DialogTrigger: () => DialogTrigger,
|
|
63
|
+
dialogVariants: () => dialogVariants
|
|
64
|
+
});
|
|
65
|
+
module.exports = __toCommonJS(index_exports);
|
|
66
|
+
|
|
67
|
+
// src/dialog.tsx
|
|
68
|
+
var import_react = require("react");
|
|
69
|
+
var import_class_variance_authority = require("class-variance-authority");
|
|
70
|
+
var import_utils = require("@glob-ui/utils");
|
|
71
|
+
var import_hooks = require("@glob-ui/hooks");
|
|
72
|
+
var import_slot = require("@glob-ui/slot");
|
|
73
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
74
|
+
var lockCount = 0;
|
|
75
|
+
var savedStyles = null;
|
|
76
|
+
function lockScroll() {
|
|
77
|
+
const html = document.documentElement;
|
|
78
|
+
if (lockCount === 0) {
|
|
79
|
+
const scrollbarWidth = window.innerWidth - html.clientWidth;
|
|
80
|
+
savedStyles = { overflow: html.style.overflow, paddingRight: html.style.paddingRight };
|
|
81
|
+
if (scrollbarWidth > 0) {
|
|
82
|
+
const current = parseFloat(getComputedStyle(html).paddingRight) || 0;
|
|
83
|
+
html.style.paddingRight = `${current + scrollbarWidth}px`;
|
|
84
|
+
}
|
|
85
|
+
html.style.overflow = "hidden";
|
|
86
|
+
}
|
|
87
|
+
lockCount++;
|
|
88
|
+
return () => {
|
|
89
|
+
lockCount--;
|
|
90
|
+
if (lockCount === 0 && savedStyles) {
|
|
91
|
+
html.style.overflow = savedStyles.overflow;
|
|
92
|
+
html.style.paddingRight = savedStyles.paddingRight;
|
|
93
|
+
savedStyles = null;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
var DialogContext = (0, import_react.createContext)(null);
|
|
98
|
+
function useDialogContext(part) {
|
|
99
|
+
const ctx = (0, import_react.useContext)(DialogContext);
|
|
100
|
+
if (!ctx) throw new Error(`${part} must be used inside Dialog, Sheet or AlertDialog`);
|
|
101
|
+
return ctx;
|
|
102
|
+
}
|
|
103
|
+
function Dialog({ open, defaultOpen = false, onOpenChange, closeOnOutsideClick = true, children }) {
|
|
104
|
+
const [isOpen, setOpen] = (0, import_hooks.useControllableState)(open, defaultOpen, onOpenChange);
|
|
105
|
+
const baseId = (0, import_react.useId)();
|
|
106
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
107
|
+
DialogContext.Provider,
|
|
108
|
+
{
|
|
109
|
+
value: {
|
|
110
|
+
open: isOpen,
|
|
111
|
+
setOpen,
|
|
112
|
+
contentId: `${baseId}-content`,
|
|
113
|
+
titleId: `${baseId}-title`,
|
|
114
|
+
descriptionId: `${baseId}-description`,
|
|
115
|
+
closeOnOutsideClick
|
|
116
|
+
},
|
|
117
|
+
children
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
Dialog.displayName = "Dialog";
|
|
122
|
+
var DialogTrigger = (0, import_react.forwardRef)(
|
|
123
|
+
(_a, ref) => {
|
|
124
|
+
var _b = _a, { asChild = false, onClick } = _b, props = __objRest(_b, ["asChild", "onClick"]);
|
|
125
|
+
const ctx = useDialogContext("DialogTrigger");
|
|
126
|
+
const Comp = asChild ? import_slot.Slot : "button";
|
|
127
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
128
|
+
Comp,
|
|
129
|
+
__spreadValues({
|
|
130
|
+
ref,
|
|
131
|
+
type: asChild ? void 0 : "button",
|
|
132
|
+
"aria-haspopup": "dialog",
|
|
133
|
+
"aria-expanded": ctx.open,
|
|
134
|
+
"aria-controls": ctx.open ? ctx.contentId : void 0,
|
|
135
|
+
onClick: (e) => {
|
|
136
|
+
onClick == null ? void 0 : onClick(e);
|
|
137
|
+
if (!e.defaultPrevented) ctx.setOpen(true);
|
|
138
|
+
}
|
|
139
|
+
}, props)
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
DialogTrigger.displayName = "DialogTrigger";
|
|
144
|
+
var dialogVariants = (0, import_class_variance_authority.cva)(
|
|
145
|
+
[
|
|
146
|
+
"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",
|
|
147
|
+
// Enter/exit. @starting-style animates the entry; allow-discrete keeps display/overlay alive
|
|
148
|
+
// during the exit. Browsers without them open and close without animation.
|
|
149
|
+
"scale-95 opacity-0 transition-[opacity,scale,overlay,display] transition-discrete duration-200 ease-out",
|
|
150
|
+
"open:scale-100 open:opacity-100 starting:open:scale-95 starting:open:opacity-0",
|
|
151
|
+
"backdrop:bg-glob-overlay backdrop:opacity-0 backdrop:transition-[opacity,overlay,display] backdrop:transition-discrete backdrop:duration-200",
|
|
152
|
+
"open:backdrop:opacity-100 starting:open:backdrop:opacity-0",
|
|
153
|
+
"motion-reduce:transition-none motion-reduce:backdrop:transition-none"
|
|
154
|
+
],
|
|
155
|
+
{
|
|
156
|
+
variants: {
|
|
157
|
+
size: {
|
|
158
|
+
sm: "max-w-sm",
|
|
159
|
+
md: "max-w-lg",
|
|
160
|
+
lg: "max-w-2xl"
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
defaultVariants: {
|
|
164
|
+
size: "md"
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
|
+
var DialogContentBase = (0, import_react.forwardRef)(
|
|
169
|
+
(_a, ref) => {
|
|
170
|
+
var _b = _a, { className, children, onCancel, onClose, onPointerDown, onClick } = _b, props = __objRest(_b, ["className", "children", "onCancel", "onClose", "onPointerDown", "onClick"]);
|
|
171
|
+
const ctx = useDialogContext("DialogContent");
|
|
172
|
+
const { open, setOpen, titleId, descriptionId, closeOnOutsideClick } = ctx;
|
|
173
|
+
const innerRef = (0, import_react.useRef)(null);
|
|
174
|
+
const previouslyFocused = (0, import_react.useRef)(null);
|
|
175
|
+
const pointerDownOnBackdrop = (0, import_react.useRef)(false);
|
|
176
|
+
const mergedRef = (0, import_react.useMemo)(() => (0, import_slot.composeRefs)(ref, innerRef), [ref]);
|
|
177
|
+
const hasOwnLabel = props["aria-labelledby"] !== void 0 || props["aria-label"] !== void 0;
|
|
178
|
+
const hasOwnDescription = props["aria-describedby"] !== void 0;
|
|
179
|
+
(0, import_react.useEffect)(() => {
|
|
180
|
+
const dialog = innerRef.current;
|
|
181
|
+
if (!dialog) return;
|
|
182
|
+
if (!open) {
|
|
183
|
+
if (dialog.open) dialog.close();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (!dialog.open) {
|
|
187
|
+
previouslyFocused.current = document.activeElement;
|
|
188
|
+
if (!hasOwnLabel) {
|
|
189
|
+
if (document.getElementById(titleId)) dialog.setAttribute("aria-labelledby", titleId);
|
|
190
|
+
else dialog.removeAttribute("aria-labelledby");
|
|
191
|
+
}
|
|
192
|
+
if (!hasOwnDescription) {
|
|
193
|
+
if (document.getElementById(descriptionId)) dialog.setAttribute("aria-describedby", descriptionId);
|
|
194
|
+
else dialog.removeAttribute("aria-describedby");
|
|
195
|
+
}
|
|
196
|
+
dialog.showModal();
|
|
197
|
+
}
|
|
198
|
+
return lockScroll();
|
|
199
|
+
}, [open, titleId, descriptionId, hasOwnLabel, hasOwnDescription]);
|
|
200
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
201
|
+
"dialog",
|
|
202
|
+
__spreadProps(__spreadValues({
|
|
203
|
+
ref: mergedRef,
|
|
204
|
+
id: ctx.contentId,
|
|
205
|
+
className: (0, import_utils.cn)(className),
|
|
206
|
+
onCancel: (e) => {
|
|
207
|
+
onCancel == null ? void 0 : onCancel(e);
|
|
208
|
+
e.preventDefault();
|
|
209
|
+
setOpen(false);
|
|
210
|
+
},
|
|
211
|
+
onClose: (e) => {
|
|
212
|
+
var _a2, _b2;
|
|
213
|
+
onClose == null ? void 0 : onClose(e);
|
|
214
|
+
if (open) setOpen(false);
|
|
215
|
+
const active = document.activeElement;
|
|
216
|
+
if (!active || active === document.body || ((_a2 = innerRef.current) == null ? void 0 : _a2.contains(active))) {
|
|
217
|
+
(_b2 = previouslyFocused.current) == null ? void 0 : _b2.focus();
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
onPointerDown: (e) => {
|
|
221
|
+
onPointerDown == null ? void 0 : onPointerDown(e);
|
|
222
|
+
pointerDownOnBackdrop.current = e.target === e.currentTarget;
|
|
223
|
+
},
|
|
224
|
+
onClick: (e) => {
|
|
225
|
+
onClick == null ? void 0 : onClick(e);
|
|
226
|
+
if (e.defaultPrevented) return;
|
|
227
|
+
if (closeOnOutsideClick && pointerDownOnBackdrop.current && e.target === e.currentTarget) {
|
|
228
|
+
setOpen(false);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}, props), {
|
|
232
|
+
children
|
|
233
|
+
})
|
|
234
|
+
);
|
|
235
|
+
}
|
|
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
|
+
);
|
|
270
|
+
DialogContent.displayName = "DialogContent";
|
|
271
|
+
var DialogHeader = (0, import_react.forwardRef)((_a, ref) => {
|
|
272
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
273
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", __spreadValues({ ref, className: (0, import_utils.cn)("flex flex-col gap-1.5 pr-8", className) }, props));
|
|
274
|
+
});
|
|
275
|
+
DialogHeader.displayName = "DialogHeader";
|
|
276
|
+
var DialogTitle = (0, import_react.forwardRef)((_a, ref) => {
|
|
277
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
278
|
+
const ctx = useDialogContext("DialogTitle");
|
|
279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
280
|
+
"h2",
|
|
281
|
+
__spreadValues({
|
|
282
|
+
ref,
|
|
283
|
+
id: ctx.titleId,
|
|
284
|
+
className: (0, import_utils.cn)("text-lg font-semibold leading-none tracking-tight", className)
|
|
285
|
+
}, props)
|
|
286
|
+
);
|
|
287
|
+
});
|
|
288
|
+
DialogTitle.displayName = "DialogTitle";
|
|
289
|
+
var DialogDescription = (0, import_react.forwardRef)(
|
|
290
|
+
(_a, ref) => {
|
|
291
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
292
|
+
const ctx = useDialogContext("DialogDescription");
|
|
293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", __spreadValues({ ref, id: ctx.descriptionId, className: (0, import_utils.cn)("text-sm text-glob-text-secondary", className) }, props));
|
|
294
|
+
}
|
|
295
|
+
);
|
|
296
|
+
DialogDescription.displayName = "DialogDescription";
|
|
297
|
+
var DialogFooter = (0, import_react.forwardRef)((_a, ref) => {
|
|
298
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
299
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", __spreadValues({ ref, className: (0, import_utils.cn)("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className) }, props));
|
|
300
|
+
});
|
|
301
|
+
DialogFooter.displayName = "DialogFooter";
|
|
302
|
+
var DialogClose = (0, import_react.forwardRef)((_a, ref) => {
|
|
303
|
+
var _b = _a, { asChild = false, onClick } = _b, props = __objRest(_b, ["asChild", "onClick"]);
|
|
304
|
+
const ctx = useDialogContext("DialogClose");
|
|
305
|
+
const Comp = asChild ? import_slot.Slot : "button";
|
|
306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
307
|
+
Comp,
|
|
308
|
+
__spreadValues({
|
|
309
|
+
ref,
|
|
310
|
+
type: asChild ? void 0 : "button",
|
|
311
|
+
onClick: (e) => {
|
|
312
|
+
onClick == null ? void 0 : onClick(e);
|
|
313
|
+
if (!e.defaultPrevented) ctx.setOpen(false);
|
|
314
|
+
}
|
|
315
|
+
}, props)
|
|
316
|
+
);
|
|
317
|
+
});
|
|
318
|
+
DialogClose.displayName = "DialogClose";
|
|
319
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
320
|
+
0 && (module.exports = {
|
|
321
|
+
Dialog,
|
|
322
|
+
DialogClose,
|
|
323
|
+
DialogCloseIcon,
|
|
324
|
+
DialogContent,
|
|
325
|
+
DialogContentBase,
|
|
326
|
+
DialogDescription,
|
|
327
|
+
DialogFooter,
|
|
328
|
+
DialogHeader,
|
|
329
|
+
DialogTitle,
|
|
330
|
+
DialogTrigger,
|
|
331
|
+
dialogVariants
|
|
332
|
+
});
|
|
333
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;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,mDAAmD;AACpF,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;AAErB,IAAM,qBAAiB;AAAA,EAC5B;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,wBAAoB;AAAA,EACxB,CAAC,IAA8E,QAAQ;AAAtF,iBAAE,aAAW,UAAU,UAAU,SAAS,eAAe,QApJ5D,IAoJG,IAAqE,kBAArE,IAAqE,CAAnE,aAAW,YAAU,YAAU,WAAS,iBAAe;AACxD,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,SAAS;AAAA,QAEvB,UAAU,CAAC,MAAM;AACf,+CAAW;AACX,YAAE,eAAe;AACjB,kBAAQ,KAAK;AAAA,QACf;AAAA,QAEA,SAAS,CAAC,MAAM;AAjMxB,cAAAA,KAAAC;AAkMU,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,QAiCE;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AACA,kBAAkB,cAAc;AAKhC,IAAM,sBAAkB,yBAAoD,CAAC,IAAkC,QAAQ;AAA1C,eAAE,aAAW,QAjO1F,IAiO6E,IAAyB,kBAAzB,IAAyB,CAAvB,aAAW;AACxF,QAAM,MAAM,iBAAiB,iBAAiB;AAC9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,cAAW;AAAA,MACX,SAAS,CAAC,MAAM;AACd,2CAAU;AACV,YAAI,CAAC,EAAE,iBAAkB,KAAI,QAAQ,KAAK;AAAA,MAC5C;AAAA,MACA,eAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,OACI,QAZL;AAAA,MAcC,sDAAC,SAAI,eAAY,QAAO,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,WAAU,WACtG,sDAAC,UAAK,GAAE,wBAAuB,GACjC;AAAA;AAAA,EACF;AAEJ,CAAC;AACD,gBAAgB,cAAc;AAS9B,IAAM,oBAAgB;AAAA,EACpB,CAAC,IAAiE,QAAK;AAAtE,iBAAE,aAAW,MAAM,kBAAkB,MAAM,SAlQ9C,IAkQG,IAAwD,kBAAxD,IAAwD,CAAtD,aAAW,QAAM,mBAAwB;AAC1C,uDAAC,kDAAkB,KAAU,eAAW,iBAAG,eAAe,EAAE,MAAM,UAAU,CAAC,CAAC,KAAO,QAApF,EACC,uDAAC,SAAI,WAAU,8EACZ;AAAA;AAAA,MACA,mBAAmB,4CAAC,mBAAgB;AAAA,OACvC,IACF;AAAA;AAEJ;AACA,cAAc,cAAc;AAI5B,IAAM,mBAAe,yBAA8C,CAAC,IAAyB,QAAK;AAA9B,eAAE,YA/QtE,IA+QoE,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,YAtRxE,IAsRsE,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,YAtSL,IAsSG,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,YAjTtE,IAiToE,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,QA1TxF,IA0TqE,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"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __spreadValues = (a, b) => {
|
|
10
|
+
for (var prop in b || (b = {}))
|
|
11
|
+
if (__hasOwnProp.call(b, prop))
|
|
12
|
+
__defNormalProp(a, prop, b[prop]);
|
|
13
|
+
if (__getOwnPropSymbols)
|
|
14
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
15
|
+
if (__propIsEnum.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
}
|
|
18
|
+
return a;
|
|
19
|
+
};
|
|
20
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
21
|
+
var __objRest = (source, exclude) => {
|
|
22
|
+
var target = {};
|
|
23
|
+
for (var prop in source)
|
|
24
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
25
|
+
target[prop] = source[prop];
|
|
26
|
+
if (source != null && __getOwnPropSymbols)
|
|
27
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
28
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
29
|
+
target[prop] = source[prop];
|
|
30
|
+
}
|
|
31
|
+
return target;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// src/dialog.tsx
|
|
35
|
+
import {
|
|
36
|
+
createContext,
|
|
37
|
+
forwardRef,
|
|
38
|
+
useContext,
|
|
39
|
+
useEffect,
|
|
40
|
+
useId,
|
|
41
|
+
useMemo,
|
|
42
|
+
useRef
|
|
43
|
+
} from "react";
|
|
44
|
+
import { cva } from "class-variance-authority";
|
|
45
|
+
import { cn } from "@glob-ui/utils";
|
|
46
|
+
import { useControllableState } from "@glob-ui/hooks";
|
|
47
|
+
import { Slot, composeRefs } from "@glob-ui/slot";
|
|
48
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
49
|
+
var lockCount = 0;
|
|
50
|
+
var savedStyles = null;
|
|
51
|
+
function lockScroll() {
|
|
52
|
+
const html = document.documentElement;
|
|
53
|
+
if (lockCount === 0) {
|
|
54
|
+
const scrollbarWidth = window.innerWidth - html.clientWidth;
|
|
55
|
+
savedStyles = { overflow: html.style.overflow, paddingRight: html.style.paddingRight };
|
|
56
|
+
if (scrollbarWidth > 0) {
|
|
57
|
+
const current = parseFloat(getComputedStyle(html).paddingRight) || 0;
|
|
58
|
+
html.style.paddingRight = `${current + scrollbarWidth}px`;
|
|
59
|
+
}
|
|
60
|
+
html.style.overflow = "hidden";
|
|
61
|
+
}
|
|
62
|
+
lockCount++;
|
|
63
|
+
return () => {
|
|
64
|
+
lockCount--;
|
|
65
|
+
if (lockCount === 0 && savedStyles) {
|
|
66
|
+
html.style.overflow = savedStyles.overflow;
|
|
67
|
+
html.style.paddingRight = savedStyles.paddingRight;
|
|
68
|
+
savedStyles = null;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
var DialogContext = createContext(null);
|
|
73
|
+
function useDialogContext(part) {
|
|
74
|
+
const ctx = useContext(DialogContext);
|
|
75
|
+
if (!ctx) throw new Error(`${part} must be used inside Dialog, Sheet or AlertDialog`);
|
|
76
|
+
return ctx;
|
|
77
|
+
}
|
|
78
|
+
function Dialog({ open, defaultOpen = false, onOpenChange, closeOnOutsideClick = true, children }) {
|
|
79
|
+
const [isOpen, setOpen] = useControllableState(open, defaultOpen, onOpenChange);
|
|
80
|
+
const baseId = useId();
|
|
81
|
+
return /* @__PURE__ */ jsx(
|
|
82
|
+
DialogContext.Provider,
|
|
83
|
+
{
|
|
84
|
+
value: {
|
|
85
|
+
open: isOpen,
|
|
86
|
+
setOpen,
|
|
87
|
+
contentId: `${baseId}-content`,
|
|
88
|
+
titleId: `${baseId}-title`,
|
|
89
|
+
descriptionId: `${baseId}-description`,
|
|
90
|
+
closeOnOutsideClick
|
|
91
|
+
},
|
|
92
|
+
children
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
Dialog.displayName = "Dialog";
|
|
97
|
+
var DialogTrigger = forwardRef(
|
|
98
|
+
(_a, ref) => {
|
|
99
|
+
var _b = _a, { asChild = false, onClick } = _b, props = __objRest(_b, ["asChild", "onClick"]);
|
|
100
|
+
const ctx = useDialogContext("DialogTrigger");
|
|
101
|
+
const Comp = asChild ? Slot : "button";
|
|
102
|
+
return /* @__PURE__ */ jsx(
|
|
103
|
+
Comp,
|
|
104
|
+
__spreadValues({
|
|
105
|
+
ref,
|
|
106
|
+
type: asChild ? void 0 : "button",
|
|
107
|
+
"aria-haspopup": "dialog",
|
|
108
|
+
"aria-expanded": ctx.open,
|
|
109
|
+
"aria-controls": ctx.open ? ctx.contentId : void 0,
|
|
110
|
+
onClick: (e) => {
|
|
111
|
+
onClick == null ? void 0 : onClick(e);
|
|
112
|
+
if (!e.defaultPrevented) ctx.setOpen(true);
|
|
113
|
+
}
|
|
114
|
+
}, props)
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
DialogTrigger.displayName = "DialogTrigger";
|
|
119
|
+
var dialogVariants = cva(
|
|
120
|
+
[
|
|
121
|
+
"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",
|
|
122
|
+
// Enter/exit. @starting-style animates the entry; allow-discrete keeps display/overlay alive
|
|
123
|
+
// during the exit. Browsers without them open and close without animation.
|
|
124
|
+
"scale-95 opacity-0 transition-[opacity,scale,overlay,display] transition-discrete duration-200 ease-out",
|
|
125
|
+
"open:scale-100 open:opacity-100 starting:open:scale-95 starting:open:opacity-0",
|
|
126
|
+
"backdrop:bg-glob-overlay backdrop:opacity-0 backdrop:transition-[opacity,overlay,display] backdrop:transition-discrete backdrop:duration-200",
|
|
127
|
+
"open:backdrop:opacity-100 starting:open:backdrop:opacity-0",
|
|
128
|
+
"motion-reduce:transition-none motion-reduce:backdrop:transition-none"
|
|
129
|
+
],
|
|
130
|
+
{
|
|
131
|
+
variants: {
|
|
132
|
+
size: {
|
|
133
|
+
sm: "max-w-sm",
|
|
134
|
+
md: "max-w-lg",
|
|
135
|
+
lg: "max-w-2xl"
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
defaultVariants: {
|
|
139
|
+
size: "md"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
var DialogContentBase = forwardRef(
|
|
144
|
+
(_a, ref) => {
|
|
145
|
+
var _b = _a, { className, children, onCancel, onClose, onPointerDown, onClick } = _b, props = __objRest(_b, ["className", "children", "onCancel", "onClose", "onPointerDown", "onClick"]);
|
|
146
|
+
const ctx = useDialogContext("DialogContent");
|
|
147
|
+
const { open, setOpen, titleId, descriptionId, closeOnOutsideClick } = ctx;
|
|
148
|
+
const innerRef = useRef(null);
|
|
149
|
+
const previouslyFocused = useRef(null);
|
|
150
|
+
const pointerDownOnBackdrop = useRef(false);
|
|
151
|
+
const mergedRef = useMemo(() => composeRefs(ref, innerRef), [ref]);
|
|
152
|
+
const hasOwnLabel = props["aria-labelledby"] !== void 0 || props["aria-label"] !== void 0;
|
|
153
|
+
const hasOwnDescription = props["aria-describedby"] !== void 0;
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
const dialog = innerRef.current;
|
|
156
|
+
if (!dialog) return;
|
|
157
|
+
if (!open) {
|
|
158
|
+
if (dialog.open) dialog.close();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (!dialog.open) {
|
|
162
|
+
previouslyFocused.current = document.activeElement;
|
|
163
|
+
if (!hasOwnLabel) {
|
|
164
|
+
if (document.getElementById(titleId)) dialog.setAttribute("aria-labelledby", titleId);
|
|
165
|
+
else dialog.removeAttribute("aria-labelledby");
|
|
166
|
+
}
|
|
167
|
+
if (!hasOwnDescription) {
|
|
168
|
+
if (document.getElementById(descriptionId)) dialog.setAttribute("aria-describedby", descriptionId);
|
|
169
|
+
else dialog.removeAttribute("aria-describedby");
|
|
170
|
+
}
|
|
171
|
+
dialog.showModal();
|
|
172
|
+
}
|
|
173
|
+
return lockScroll();
|
|
174
|
+
}, [open, titleId, descriptionId, hasOwnLabel, hasOwnDescription]);
|
|
175
|
+
return /* @__PURE__ */ jsx(
|
|
176
|
+
"dialog",
|
|
177
|
+
__spreadProps(__spreadValues({
|
|
178
|
+
ref: mergedRef,
|
|
179
|
+
id: ctx.contentId,
|
|
180
|
+
className: cn(className),
|
|
181
|
+
onCancel: (e) => {
|
|
182
|
+
onCancel == null ? void 0 : onCancel(e);
|
|
183
|
+
e.preventDefault();
|
|
184
|
+
setOpen(false);
|
|
185
|
+
},
|
|
186
|
+
onClose: (e) => {
|
|
187
|
+
var _a2, _b2;
|
|
188
|
+
onClose == null ? void 0 : onClose(e);
|
|
189
|
+
if (open) setOpen(false);
|
|
190
|
+
const active = document.activeElement;
|
|
191
|
+
if (!active || active === document.body || ((_a2 = innerRef.current) == null ? void 0 : _a2.contains(active))) {
|
|
192
|
+
(_b2 = previouslyFocused.current) == null ? void 0 : _b2.focus();
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
onPointerDown: (e) => {
|
|
196
|
+
onPointerDown == null ? void 0 : onPointerDown(e);
|
|
197
|
+
pointerDownOnBackdrop.current = e.target === e.currentTarget;
|
|
198
|
+
},
|
|
199
|
+
onClick: (e) => {
|
|
200
|
+
onClick == null ? void 0 : onClick(e);
|
|
201
|
+
if (e.defaultPrevented) return;
|
|
202
|
+
if (closeOnOutsideClick && pointerDownOnBackdrop.current && e.target === e.currentTarget) {
|
|
203
|
+
setOpen(false);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}, props), {
|
|
207
|
+
children
|
|
208
|
+
})
|
|
209
|
+
);
|
|
210
|
+
}
|
|
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
|
+
);
|
|
245
|
+
DialogContent.displayName = "DialogContent";
|
|
246
|
+
var DialogHeader = forwardRef((_a, ref) => {
|
|
247
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
248
|
+
return /* @__PURE__ */ jsx("div", __spreadValues({ ref, className: cn("flex flex-col gap-1.5 pr-8", className) }, props));
|
|
249
|
+
});
|
|
250
|
+
DialogHeader.displayName = "DialogHeader";
|
|
251
|
+
var DialogTitle = forwardRef((_a, ref) => {
|
|
252
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
253
|
+
const ctx = useDialogContext("DialogTitle");
|
|
254
|
+
return /* @__PURE__ */ jsx(
|
|
255
|
+
"h2",
|
|
256
|
+
__spreadValues({
|
|
257
|
+
ref,
|
|
258
|
+
id: ctx.titleId,
|
|
259
|
+
className: cn("text-lg font-semibold leading-none tracking-tight", className)
|
|
260
|
+
}, props)
|
|
261
|
+
);
|
|
262
|
+
});
|
|
263
|
+
DialogTitle.displayName = "DialogTitle";
|
|
264
|
+
var DialogDescription = forwardRef(
|
|
265
|
+
(_a, ref) => {
|
|
266
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
267
|
+
const ctx = useDialogContext("DialogDescription");
|
|
268
|
+
return /* @__PURE__ */ jsx("p", __spreadValues({ ref, id: ctx.descriptionId, className: cn("text-sm text-glob-text-secondary", className) }, props));
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
DialogDescription.displayName = "DialogDescription";
|
|
272
|
+
var DialogFooter = forwardRef((_a, ref) => {
|
|
273
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
274
|
+
return /* @__PURE__ */ jsx("div", __spreadValues({ ref, className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className) }, props));
|
|
275
|
+
});
|
|
276
|
+
DialogFooter.displayName = "DialogFooter";
|
|
277
|
+
var DialogClose = forwardRef((_a, ref) => {
|
|
278
|
+
var _b = _a, { asChild = false, onClick } = _b, props = __objRest(_b, ["asChild", "onClick"]);
|
|
279
|
+
const ctx = useDialogContext("DialogClose");
|
|
280
|
+
const Comp = asChild ? Slot : "button";
|
|
281
|
+
return /* @__PURE__ */ jsx(
|
|
282
|
+
Comp,
|
|
283
|
+
__spreadValues({
|
|
284
|
+
ref,
|
|
285
|
+
type: asChild ? void 0 : "button",
|
|
286
|
+
onClick: (e) => {
|
|
287
|
+
onClick == null ? void 0 : onClick(e);
|
|
288
|
+
if (!e.defaultPrevented) ctx.setOpen(false);
|
|
289
|
+
}
|
|
290
|
+
}, props)
|
|
291
|
+
);
|
|
292
|
+
});
|
|
293
|
+
DialogClose.displayName = "DialogClose";
|
|
294
|
+
export {
|
|
295
|
+
Dialog,
|
|
296
|
+
DialogClose,
|
|
297
|
+
DialogCloseIcon,
|
|
298
|
+
DialogContent,
|
|
299
|
+
DialogContentBase,
|
|
300
|
+
DialogDescription,
|
|
301
|
+
DialogFooter,
|
|
302
|
+
DialogHeader,
|
|
303
|
+
DialogTitle,
|
|
304
|
+
DialogTrigger,
|
|
305
|
+
dialogVariants
|
|
306
|
+
};
|
|
307
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +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, 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,70 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glob-ui/dialog",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"module": "./dist/index.mjs",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": {
|
|
10
|
+
"types": "./dist/index.d.mts",
|
|
11
|
+
"default": "./dist/index.mjs"
|
|
12
|
+
},
|
|
13
|
+
"require": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist/",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": "^19"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@glob-ui/hooks": "0.2.0",
|
|
30
|
+
"@glob-ui/slot": "0.2.0",
|
|
31
|
+
"@glob-ui/utils": "0.2.0",
|
|
32
|
+
"class-variance-authority": "^0.7.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"tsup": "^8.5.1"
|
|
36
|
+
},
|
|
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
|
+
"keywords": [
|
|
39
|
+
"react",
|
|
40
|
+
"glob-ui",
|
|
41
|
+
"components",
|
|
42
|
+
"accessible",
|
|
43
|
+
"tailwind",
|
|
44
|
+
"dialog"
|
|
45
|
+
],
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"author": "Kevin Martínez E",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/kevin-martineze/GlobUI.git",
|
|
51
|
+
"directory": "packages/dialog"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/kevin-martineze/GlobUI#readme",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/kevin-martineze/GlobUI/issues"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public",
|
|
59
|
+
"provenance": true
|
|
60
|
+
},
|
|
61
|
+
"sideEffects": false,
|
|
62
|
+
"type": "commonjs",
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=18.18"
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"build": "tsup",
|
|
68
|
+
"dev": "tsup --watch --no-clean"
|
|
69
|
+
}
|
|
6
70
|
}
|