@data-slot/dialog 0.1.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 +176 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +54 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# @data-slot/dialog
|
|
2
|
+
|
|
3
|
+
Headless modal dialog component for vanilla JavaScript. Accessible, unstyled, tiny.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @data-slot/dialog
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<div data-slot="dialog">
|
|
15
|
+
<button data-slot="dialog-trigger">Open Dialog</button>
|
|
16
|
+
<div data-slot="dialog-content" hidden>
|
|
17
|
+
<h2 data-slot="dialog-title">Dialog Title</h2>
|
|
18
|
+
<p data-slot="dialog-description">Dialog description text.</p>
|
|
19
|
+
<button data-slot="dialog-close">Close</button>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<script type="module">
|
|
24
|
+
import { create } from "@data-slot/dialog";
|
|
25
|
+
|
|
26
|
+
const controllers = create();
|
|
27
|
+
</script>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## API
|
|
31
|
+
|
|
32
|
+
### `create(scope?)`
|
|
33
|
+
|
|
34
|
+
Auto-discover and bind all dialog instances in a scope (defaults to `document`).
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { create } from "@data-slot/dialog";
|
|
38
|
+
|
|
39
|
+
const controllers = create(); // Returns DialogController[]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### `createDialog(root, options?)`
|
|
43
|
+
|
|
44
|
+
Create a controller for a specific element.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { createDialog } from "@data-slot/dialog";
|
|
48
|
+
|
|
49
|
+
const dialog = createDialog(element, {
|
|
50
|
+
defaultOpen: false,
|
|
51
|
+
closeOnClickOutside: true,
|
|
52
|
+
closeOnEscape: true,
|
|
53
|
+
lockScroll: true,
|
|
54
|
+
onOpenChange: (open) => console.log(open),
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Options
|
|
59
|
+
|
|
60
|
+
| Option | Type | Default | Description |
|
|
61
|
+
|--------|------|---------|-------------|
|
|
62
|
+
| `defaultOpen` | `boolean` | `false` | Initial open state |
|
|
63
|
+
| `closeOnClickOutside` | `boolean` | `true` | Close when clicking outside content |
|
|
64
|
+
| `closeOnEscape` | `boolean` | `true` | Close when pressing Escape |
|
|
65
|
+
| `lockScroll` | `boolean` | `true` | Lock body scroll when open |
|
|
66
|
+
| `onOpenChange` | `(open: boolean) => void` | `undefined` | Callback when open state changes |
|
|
67
|
+
|
|
68
|
+
### Controller
|
|
69
|
+
|
|
70
|
+
| Method/Property | Description |
|
|
71
|
+
|-----------------|-------------|
|
|
72
|
+
| `open()` | Open the dialog |
|
|
73
|
+
| `close()` | Close the dialog |
|
|
74
|
+
| `toggle()` | Toggle the dialog |
|
|
75
|
+
| `isOpen` | Current open state (readonly `boolean`) |
|
|
76
|
+
| `destroy()` | Cleanup all event listeners |
|
|
77
|
+
|
|
78
|
+
## Markup Structure
|
|
79
|
+
|
|
80
|
+
```html
|
|
81
|
+
<div data-slot="dialog">
|
|
82
|
+
<button data-slot="dialog-trigger">Open</button>
|
|
83
|
+
<div data-slot="dialog-content" role="dialog">
|
|
84
|
+
<h2 data-slot="dialog-title">Title</h2>
|
|
85
|
+
<p data-slot="dialog-description">Description</p>
|
|
86
|
+
<button data-slot="dialog-close">Close</button>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Required Slots
|
|
92
|
+
|
|
93
|
+
- `dialog-content` - The dialog panel (required)
|
|
94
|
+
|
|
95
|
+
### Optional Slots
|
|
96
|
+
|
|
97
|
+
- `dialog-trigger` - Button to open the dialog
|
|
98
|
+
- `dialog-title` - Title for `aria-labelledby`
|
|
99
|
+
- `dialog-description` - Description for `aria-describedby`
|
|
100
|
+
- `dialog-close` - Button to close the dialog
|
|
101
|
+
|
|
102
|
+
## Styling
|
|
103
|
+
|
|
104
|
+
Use `data-state` attributes for CSS styling:
|
|
105
|
+
|
|
106
|
+
```css
|
|
107
|
+
/* Backdrop/overlay */
|
|
108
|
+
[data-slot="dialog-content"] {
|
|
109
|
+
position: fixed;
|
|
110
|
+
inset: 0;
|
|
111
|
+
display: grid;
|
|
112
|
+
place-items: center;
|
|
113
|
+
background: rgba(0, 0, 0, 0.5);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Closed state */
|
|
117
|
+
[data-slot="dialog"][data-state="closed"] [data-slot="dialog-content"] {
|
|
118
|
+
display: none;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* Animation */
|
|
122
|
+
[data-slot="dialog-content"] {
|
|
123
|
+
opacity: 0;
|
|
124
|
+
transition: opacity 0.2s;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
[data-slot="dialog"][data-state="open"] [data-slot="dialog-content"] {
|
|
128
|
+
opacity: 1;
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
With Tailwind:
|
|
133
|
+
|
|
134
|
+
```html
|
|
135
|
+
<div data-slot="dialog-content" class="fixed inset-0 grid place-items-center bg-black/50 data-[state=closed]:hidden">
|
|
136
|
+
<div class="bg-white rounded-lg p-6 max-w-md">
|
|
137
|
+
<!-- Dialog content -->
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Accessibility
|
|
143
|
+
|
|
144
|
+
The component automatically handles:
|
|
145
|
+
|
|
146
|
+
- `role="dialog"` on content
|
|
147
|
+
- `aria-modal="true"` on content
|
|
148
|
+
- `aria-labelledby` linked to title
|
|
149
|
+
- `aria-describedby` linked to description
|
|
150
|
+
- `aria-haspopup="dialog"` on trigger
|
|
151
|
+
- `aria-expanded` state on trigger
|
|
152
|
+
- Focus trap within dialog
|
|
153
|
+
- Focus restoration on close
|
|
154
|
+
|
|
155
|
+
## Keyboard Navigation
|
|
156
|
+
|
|
157
|
+
| Key | Action |
|
|
158
|
+
|-----|--------|
|
|
159
|
+
| `Escape` | Close dialog |
|
|
160
|
+
| `Tab` | Cycle focus within dialog |
|
|
161
|
+
| `Shift+Tab` | Cycle focus backwards |
|
|
162
|
+
|
|
163
|
+
## Events
|
|
164
|
+
|
|
165
|
+
Listen for changes via custom events:
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
element.addEventListener("dialog:change", (e) => {
|
|
169
|
+
console.log("Dialog open:", e.detail.open);
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
MIT
|
|
176
|
+
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=s(require(`@data-slot/core`)),l=`a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])`,u=[];let d=0,f=``,p=``;function m(e,t={}){let{defaultOpen:n=!1,onOpenChange:r,closeOnClickOutside:i=!0,closeOnEscape:a=!0,lockScroll:o=!0,alertDialog:s=!1}=t,m=(0,c.getPart)(e,`dialog-trigger`),h=(0,c.getPart)(e,`dialog-overlay`),g=(0,c.getPart)(e,`dialog-content`),_=(0,c.getPart)(e,`dialog-close`),v=(0,c.getPart)(e,`dialog-title`),y=(0,c.getPart)(e,`dialog-description`);if(!g)throw Error(`Dialog requires dialog-content slot`);if(!h)throw Error(`Dialog requires dialog-overlay slot`);let b=!1,x=null,S=[];(0,c.ensureId)(g,`dialog-content`),g.setAttribute(`role`,s?`alertdialog`:`dialog`),(0,c.setAria)(g,`modal`,!0),(0,c.linkLabelledBy)(g,v,y),h.setAttribute(`role`,`presentation`),h.setAttribute(`aria-hidden`,`true`),h.tabIndex=-1,m&&(m.setAttribute(`aria-haspopup`,`dialog`),m.setAttribute(`aria-controls`,g.id),(0,c.setAria)(m,`expanded`,!1));let C=!1,w=()=>{g.hasAttribute(`tabindex`)||(g.tabIndex=-1,C=!0)},T=()=>{C&&(g.removeAttribute(`tabindex`),C=!1)},E=()=>{let e=g.querySelector(`[autofocus]`);if(e)return e.focus();let t=g.querySelector(l);if(t)return t.focus();w(),g.focus()},D=(t,n=!1)=>{if(!(b===t&&!n)){if(t){if(x=document.activeElement,u.push(O),o){if(d===0){let e=window.innerWidth-document.documentElement.clientWidth;f=document.body.style.overflow,p=document.body.style.paddingRight,document.body.style.paddingRight=`${e}px`,document.body.style.overflow=`hidden`}d++}}else{let e=u.indexOf(O);e!==-1&&u.splice(e,1),o&&(d--,d===0&&(document.body.style.overflow=f,document.body.style.paddingRight=p)),T();let t=x;x=null,requestAnimationFrame(()=>{t&&document.contains(t)&&typeof t.focus==`function`&&t.focus()})}b=t,g.hidden=!b,h.hidden=!b,m&&(0,c.setAria)(m,`expanded`,b),e.setAttribute(`data-state`,b?`open`:`closed`),(0,c.emit)(e,`dialog:change`,{open:b}),r?.(b),t&&requestAnimationFrame(E)}};n?(g.hidden=!1,h.hidden=!1,e.setAttribute(`data-state`,`open`),D(!0,!0)):(g.hidden=!0,h.hidden=!0,e.setAttribute(`data-state`,`closed`)),m&&S.push((0,c.on)(m,`click`,()=>D(!b))),_&&S.push((0,c.on)(_,`click`,()=>D(!1))),i&&S.push((0,c.on)(h,`pointerdown`,e=>{e.target===h&&b&&D(!1)})),S.push((0,c.on)(document,`keydown`,e=>{if(b){if(e.key===`Escape`&&a){let t=u[u.length-1];t===O&&(e.preventDefault(),D(!1));return}if(e.key===`Tab`){let t=g.querySelectorAll(l);if(t.length===0){e.preventDefault(),w(),g.focus();return}let n=t[0],r=t[t.length-1],i=document.activeElement;if(!g.contains(i)){e.preventDefault(),n.focus();return}if(n===r){e.preventDefault();return}e.shiftKey?i===n&&(e.preventDefault(),r.focus()):i===r&&(e.preventDefault(),n.focus())}}}));let O={open:()=>D(!0),close:()=>D(!1),toggle:()=>D(!b),get isOpen(){return b},destroy:()=>{b&&D(!1,!0),T(),S.forEach(e=>e()),S.length=0}};return O}const h=new WeakSet;function g(e=document){let t=[];for(let n of(0,c.getRoots)(e,`dialog`)){if(h.has(n))continue;h.add(n),t.push(m(n))}return t}exports.create=g,exports.createDialog=m;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
interface DialogOptions {
|
|
3
|
+
/** Initial open state */
|
|
4
|
+
defaultOpen?: boolean;
|
|
5
|
+
/** Callback when open state changes */
|
|
6
|
+
onOpenChange?: (open: boolean) => void;
|
|
7
|
+
/** Close when clicking overlay */
|
|
8
|
+
closeOnClickOutside?: boolean;
|
|
9
|
+
/** Close when pressing Escape */
|
|
10
|
+
closeOnEscape?: boolean;
|
|
11
|
+
/** Lock body scroll when open */
|
|
12
|
+
lockScroll?: boolean;
|
|
13
|
+
/** Use alertdialog role for blocking confirmations */
|
|
14
|
+
alertDialog?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface DialogController {
|
|
17
|
+
/** Open the dialog */
|
|
18
|
+
open(): void;
|
|
19
|
+
/** Close the dialog */
|
|
20
|
+
close(): void;
|
|
21
|
+
/** Toggle the dialog */
|
|
22
|
+
toggle(): void;
|
|
23
|
+
/** Current open state */
|
|
24
|
+
readonly isOpen: boolean;
|
|
25
|
+
/** Cleanup all event listeners */
|
|
26
|
+
destroy(): void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a dialog controller for a root element
|
|
30
|
+
*
|
|
31
|
+
* Expected markup:
|
|
32
|
+
* ```html
|
|
33
|
+
* <div data-slot="dialog">
|
|
34
|
+
* <button data-slot="dialog-trigger">Open</button>
|
|
35
|
+
* <div data-slot="dialog-overlay"></div>
|
|
36
|
+
* <div data-slot="dialog-content">
|
|
37
|
+
* <h2 data-slot="dialog-title">Title</h2>
|
|
38
|
+
* <p data-slot="dialog-description">Description</p>
|
|
39
|
+
* <button data-slot="dialog-close">Close</button>
|
|
40
|
+
* </div>
|
|
41
|
+
* </div>
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* Note: Overlay is required. For modal behavior with inert backgrounds,
|
|
45
|
+
* mount dialogs as direct children of document.body (portal pattern).
|
|
46
|
+
*/
|
|
47
|
+
declare function createDialog(root: Element, options?: DialogOptions): DialogController;
|
|
48
|
+
/**
|
|
49
|
+
* Find and bind all dialog components in a scope
|
|
50
|
+
* Returns array of controllers for programmatic access
|
|
51
|
+
*/
|
|
52
|
+
declare function create(scope?: ParentNode): DialogController[];
|
|
53
|
+
//#endregion
|
|
54
|
+
export { DialogController, DialogOptions, create, createDialog };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
interface DialogOptions {
|
|
3
|
+
/** Initial open state */
|
|
4
|
+
defaultOpen?: boolean;
|
|
5
|
+
/** Callback when open state changes */
|
|
6
|
+
onOpenChange?: (open: boolean) => void;
|
|
7
|
+
/** Close when clicking overlay */
|
|
8
|
+
closeOnClickOutside?: boolean;
|
|
9
|
+
/** Close when pressing Escape */
|
|
10
|
+
closeOnEscape?: boolean;
|
|
11
|
+
/** Lock body scroll when open */
|
|
12
|
+
lockScroll?: boolean;
|
|
13
|
+
/** Use alertdialog role for blocking confirmations */
|
|
14
|
+
alertDialog?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface DialogController {
|
|
17
|
+
/** Open the dialog */
|
|
18
|
+
open(): void;
|
|
19
|
+
/** Close the dialog */
|
|
20
|
+
close(): void;
|
|
21
|
+
/** Toggle the dialog */
|
|
22
|
+
toggle(): void;
|
|
23
|
+
/** Current open state */
|
|
24
|
+
readonly isOpen: boolean;
|
|
25
|
+
/** Cleanup all event listeners */
|
|
26
|
+
destroy(): void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a dialog controller for a root element
|
|
30
|
+
*
|
|
31
|
+
* Expected markup:
|
|
32
|
+
* ```html
|
|
33
|
+
* <div data-slot="dialog">
|
|
34
|
+
* <button data-slot="dialog-trigger">Open</button>
|
|
35
|
+
* <div data-slot="dialog-overlay"></div>
|
|
36
|
+
* <div data-slot="dialog-content">
|
|
37
|
+
* <h2 data-slot="dialog-title">Title</h2>
|
|
38
|
+
* <p data-slot="dialog-description">Description</p>
|
|
39
|
+
* <button data-slot="dialog-close">Close</button>
|
|
40
|
+
* </div>
|
|
41
|
+
* </div>
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* Note: Overlay is required. For modal behavior with inert backgrounds,
|
|
45
|
+
* mount dialogs as direct children of document.body (portal pattern).
|
|
46
|
+
*/
|
|
47
|
+
declare function createDialog(root: Element, options?: DialogOptions): DialogController;
|
|
48
|
+
/**
|
|
49
|
+
* Find and bind all dialog components in a scope
|
|
50
|
+
* Returns array of controllers for programmatic access
|
|
51
|
+
*/
|
|
52
|
+
declare function create(scope?: ParentNode): DialogController[];
|
|
53
|
+
//#endregion
|
|
54
|
+
export { DialogController, DialogOptions, create, createDialog };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{emit as e,ensureId as t,getPart as n,getRoots as r,linkLabelledBy as i,on as a,setAria as o}from"@data-slot/core";const s=`a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])`,c=[];let l=0,u=``,d=``;function f(r,f={}){let{defaultOpen:p=!1,onOpenChange:m,closeOnClickOutside:h=!0,closeOnEscape:g=!0,lockScroll:_=!0,alertDialog:v=!1}=f,y=n(r,`dialog-trigger`),b=n(r,`dialog-overlay`),x=n(r,`dialog-content`),S=n(r,`dialog-close`),C=n(r,`dialog-title`),w=n(r,`dialog-description`);if(!x)throw Error(`Dialog requires dialog-content slot`);if(!b)throw Error(`Dialog requires dialog-overlay slot`);let T=!1,E=null,D=[];t(x,`dialog-content`),x.setAttribute(`role`,v?`alertdialog`:`dialog`),o(x,`modal`,!0),i(x,C,w),b.setAttribute(`role`,`presentation`),b.setAttribute(`aria-hidden`,`true`),b.tabIndex=-1,y&&(y.setAttribute(`aria-haspopup`,`dialog`),y.setAttribute(`aria-controls`,x.id),o(y,`expanded`,!1));let O=!1,k=()=>{x.hasAttribute(`tabindex`)||(x.tabIndex=-1,O=!0)},A=()=>{O&&(x.removeAttribute(`tabindex`),O=!1)},j=()=>{let e=x.querySelector(`[autofocus]`);if(e)return e.focus();let t=x.querySelector(s);if(t)return t.focus();k(),x.focus()},M=(t,n=!1)=>{if(!(T===t&&!n)){if(t){if(E=document.activeElement,c.push(N),_){if(l===0){let e=window.innerWidth-document.documentElement.clientWidth;u=document.body.style.overflow,d=document.body.style.paddingRight,document.body.style.paddingRight=`${e}px`,document.body.style.overflow=`hidden`}l++}}else{let e=c.indexOf(N);e!==-1&&c.splice(e,1),_&&(l--,l===0&&(document.body.style.overflow=u,document.body.style.paddingRight=d)),A();let t=E;E=null,requestAnimationFrame(()=>{t&&document.contains(t)&&typeof t.focus==`function`&&t.focus()})}T=t,x.hidden=!T,b.hidden=!T,y&&o(y,`expanded`,T),r.setAttribute(`data-state`,T?`open`:`closed`),e(r,`dialog:change`,{open:T}),m?.(T),t&&requestAnimationFrame(j)}};p?(x.hidden=!1,b.hidden=!1,r.setAttribute(`data-state`,`open`),M(!0,!0)):(x.hidden=!0,b.hidden=!0,r.setAttribute(`data-state`,`closed`)),y&&D.push(a(y,`click`,()=>M(!T))),S&&D.push(a(S,`click`,()=>M(!1))),h&&D.push(a(b,`pointerdown`,e=>{e.target===b&&T&&M(!1)})),D.push(a(document,`keydown`,e=>{if(T){if(e.key===`Escape`&&g){let t=c[c.length-1];t===N&&(e.preventDefault(),M(!1));return}if(e.key===`Tab`){let t=x.querySelectorAll(s);if(t.length===0){e.preventDefault(),k(),x.focus();return}let n=t[0],r=t[t.length-1],i=document.activeElement;if(!x.contains(i)){e.preventDefault(),n.focus();return}if(n===r){e.preventDefault();return}e.shiftKey?i===n&&(e.preventDefault(),r.focus()):i===r&&(e.preventDefault(),n.focus())}}}));let N={open:()=>M(!0),close:()=>M(!1),toggle:()=>M(!T),get isOpen(){return T},destroy:()=>{T&&M(!1,!0),A(),D.forEach(e=>e()),D.length=0}};return N}const p=new WeakSet;function m(e=document){let t=[];for(let n of r(e,`dialog`)){if(p.has(n))continue;p.add(n),t.push(f(n))}return t}export{m as create,f as createDialog};
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@data-slot/dialog",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsdown"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@data-slot/core": "workspace:*"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"headless",
|
|
32
|
+
"ui",
|
|
33
|
+
"dialog",
|
|
34
|
+
"modal",
|
|
35
|
+
"vanilla",
|
|
36
|
+
"data-slot"
|
|
37
|
+
],
|
|
38
|
+
"license": "MIT"
|
|
39
|
+
}
|