@data-slot/dialog 0.1.2 → 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/dist/index.cjs +1 -1
- package/dist/index.d.cts +17 -7
- package/dist/index.d.ts +17 -7
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=(e,t)=>e.querySelector(`[data-slot="${t}"]`),t=(e,t)=>[...e.querySelectorAll(`[data-slot="${t}"]`)];let n=0;const r=(e,t)=>e.id||=`${t}-${++n}`,i=(e,t,n)=>{n===null?e.removeAttribute(`aria-${t}`):e.setAttribute(`aria-${t}`,String(n))},a=(e,t,n)=>{t&&e.setAttribute(`aria-labelledby`,r(t,`title`)),n&&e.setAttribute(`aria-describedby`,r(n,`desc`))},o=(e,t,n,r)=>(e.addEventListener(t,n,r),()=>e.removeEventListener(t,n,r)),s=(e,t,n)=>e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:n})),c=`a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])`,l=[];let u=0,d=``,f
|
|
1
|
+
const e=(e,t)=>e.querySelector(`[data-slot="${t}"]`),t=(e,t)=>[...e.querySelectorAll(`[data-slot="${t}"]`)];let n=0;const r=(e,t)=>e.id||=`${t}-${++n}`,i=(e,t,n)=>{n===null?e.removeAttribute(`aria-${t}`):e.setAttribute(`aria-${t}`,String(n))},a=(e,t,n)=>{t&&e.setAttribute(`aria-labelledby`,r(t,`title`)),n&&e.setAttribute(`aria-describedby`,r(n,`desc`))},o=(e,t,n,r)=>(e.addEventListener(t,n,r),()=>e.removeEventListener(t,n,r)),s=(e,t,n)=>e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:n})),c=`a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])`,l=[];let u=0,d=``,f=``,p=null;function m(){let e=1e3;l.forEach((t,n)=>{let r=e+n*10;t._overlay&&(t._overlay.style.zIndex=String(r)),t._content&&(t._content.style.zIndex=String(r+1))})}function h(){if(p)return;let e=e=>{if(l.length===0)return;let t=l[l.length-1];if(!(!t||!t.isOpen)){if(e.key===`Escape`&&t._closeOnEscape){e.preventDefault(),t.close();return}e.key===`Tab`&&t._handleKeydown&&t._handleKeydown(e)}},t=o(document,`keydown`,e);p=()=>{t(),p=null}}function g(){l.length===0&&p&&p()}function _(t,n={}){let{defaultOpen:p=!1,onOpenChange:_,closeOnClickOutside:v=!0,closeOnEscape:y=!0,lockScroll:b=!0,alertDialog:x=!1}=n,S=e(t,`dialog-trigger`),C=e(t,`dialog-portal`),w=e(t,`dialog-overlay`),T=e(t,`dialog-content`),E=e(t,`dialog-title`),D=e(t,`dialog-description`);if(!T)throw Error(`Dialog requires dialog-content slot`);if(!w)throw Error(`Dialog requires dialog-overlay slot`);let O=!1,k=null,A=[],j=null,M=null,N=!1,P=!1;r(T,`dialog-content`),T.setAttribute(`role`,x?`alertdialog`:`dialog`),i(T,`modal`,!0),a(T,E,D),w.setAttribute(`role`,`presentation`),w.setAttribute(`aria-hidden`,`true`),w.tabIndex=-1,S&&(S.setAttribute(`aria-haspopup`,`dialog`),S.setAttribute(`aria-controls`,T.id),i(S,`expanded`,!1));let F=!1,I=()=>{T.hasAttribute(`tabindex`)||(T.tabIndex=-1,F=!0)},L=()=>{F&&(T.removeAttribute(`tabindex`),F=!1)},R=()=>{let e=T.querySelector(`[autofocus]`);if(e)return e.focus();let t=T.querySelector(c);if(t)return t.focus();I(),T.focus()},z=()=>{C&&!N&&(j=C.parentNode,M=C.nextSibling,document.body.appendChild(C),N=!0)},B=e=>{t.setAttribute(`data-state`,e),C&&C.setAttribute(`data-state`,e),w.setAttribute(`data-state`,e),T.setAttribute(`data-state`,e)},V=()=>{w.style.zIndex=``,T.style.zIndex=``},H=(e,n=!1)=>{if(!(O===e&&!n)){if(e){if(z(),k=document.activeElement,l.push(W),h(),m(),b&&!P){if(u===0){let e=window.innerWidth-document.documentElement.clientWidth;d=document.body.style.overflow,f=document.body.style.paddingRight,document.body.style.paddingRight=`${e}px`,document.body.style.overflow=`hidden`}u++,P=!0}}else{let e=l.indexOf(W);e!==-1&&l.splice(e,1),g(),V(),m(),P&&(u=Math.max(0,u-1),P=!1,u===0&&(document.body.style.overflow=d,document.body.style.paddingRight=f)),L();let t=k;k=null,requestAnimationFrame(()=>{t&&document.contains(t)&&typeof t.focus==`function`?t.focus():S&&document.contains(S)&&S.focus()})}O=e,T.hidden=!O,w.hidden=!O,S&&i(S,`expanded`,O),B(O?`open`:`closed`),s(t,`dialog:change`,{open:O}),_?.(O),e&&requestAnimationFrame(R)}},U=e=>{if(e.key!==`Tab`)return;let t=T.querySelectorAll(c);if(t.length===0){e.preventDefault(),I(),T.focus();return}let n=t[0],r=t[t.length-1],i=document.activeElement;if(!T.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())};p?(z(),T.hidden=!1,w.hidden=!1,B(`open`),H(!0,!0)):(T.hidden=!0,w.hidden=!0,B(`closed`)),S&&A.push(o(S,`click`,()=>H(!O))),A.push(o(T,`click`,e=>{let t=e.target;if(!t)return;let n=t.closest?.(`[data-slot="dialog-close"]`);n&&T.contains(n)&&H(!1)})),v&&A.push(o(w,`pointerdown`,e=>{e.target===w&&O&&H(!1)}));let W={open:()=>H(!0),close:()=>H(!1),toggle:()=>H(!O),get isOpen(){return O},destroy:()=>{if(O)H(!1,!0);else{let e=l.indexOf(W);e!==-1&&(l.splice(e,1),m(),g())}L(),A.forEach(e=>e()),A.length=0,C&&N&&(j&&document.contains(j)?j.insertBefore(C,M):C.remove(),N=!1)},_handleKeydown:U,_closeOnEscape:y,_content:T,_overlay:w};return W}const v=new WeakSet;function y(e=document){let n=[];for(let r of t(e,`dialog`)){if(v.has(r))continue;v.add(r),n.push(_(r))}return n}exports.create=y,exports.createDialog=_;
|
package/dist/index.d.cts
CHANGED
|
@@ -24,6 +24,14 @@ interface DialogController {
|
|
|
24
24
|
readonly isOpen: boolean;
|
|
25
25
|
/** Cleanup all event listeners */
|
|
26
26
|
destroy(): void;
|
|
27
|
+
/** Internal: handle keydown for focus trap (used by global handler) */
|
|
28
|
+
_handleKeydown?(e: KeyboardEvent): void;
|
|
29
|
+
/** Internal: options for global handler */
|
|
30
|
+
_closeOnEscape?: boolean;
|
|
31
|
+
/** Internal: content element for focus trap */
|
|
32
|
+
_content?: HTMLElement;
|
|
33
|
+
/** Internal: overlay element for z-index */
|
|
34
|
+
_overlay?: HTMLElement;
|
|
27
35
|
}
|
|
28
36
|
/**
|
|
29
37
|
* Create a dialog controller for a root element
|
|
@@ -32,17 +40,19 @@ interface DialogController {
|
|
|
32
40
|
* ```html
|
|
33
41
|
* <div data-slot="dialog">
|
|
34
42
|
* <button data-slot="dialog-trigger">Open</button>
|
|
35
|
-
* <div data-slot="dialog-
|
|
36
|
-
*
|
|
37
|
-
* <
|
|
38
|
-
*
|
|
39
|
-
*
|
|
43
|
+
* <div data-slot="dialog-portal">
|
|
44
|
+
* <div data-slot="dialog-overlay"></div>
|
|
45
|
+
* <div data-slot="dialog-content">
|
|
46
|
+
* <h2 data-slot="dialog-title">Title</h2>
|
|
47
|
+
* <p data-slot="dialog-description">Description</p>
|
|
48
|
+
* <button data-slot="dialog-close">Close</button>
|
|
49
|
+
* </div>
|
|
40
50
|
* </div>
|
|
41
51
|
* </div>
|
|
42
52
|
* ```
|
|
43
53
|
*
|
|
44
|
-
* Note: Overlay is required.
|
|
45
|
-
*
|
|
54
|
+
* Note: Overlay is required. The optional dialog-portal slot will be
|
|
55
|
+
* automatically moved to document.body to escape stacking context issues.
|
|
46
56
|
*/
|
|
47
57
|
declare function createDialog(root: Element, options?: DialogOptions): DialogController;
|
|
48
58
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -24,6 +24,14 @@ interface DialogController {
|
|
|
24
24
|
readonly isOpen: boolean;
|
|
25
25
|
/** Cleanup all event listeners */
|
|
26
26
|
destroy(): void;
|
|
27
|
+
/** Internal: handle keydown for focus trap (used by global handler) */
|
|
28
|
+
_handleKeydown?(e: KeyboardEvent): void;
|
|
29
|
+
/** Internal: options for global handler */
|
|
30
|
+
_closeOnEscape?: boolean;
|
|
31
|
+
/** Internal: content element for focus trap */
|
|
32
|
+
_content?: HTMLElement;
|
|
33
|
+
/** Internal: overlay element for z-index */
|
|
34
|
+
_overlay?: HTMLElement;
|
|
27
35
|
}
|
|
28
36
|
/**
|
|
29
37
|
* Create a dialog controller for a root element
|
|
@@ -32,17 +40,19 @@ interface DialogController {
|
|
|
32
40
|
* ```html
|
|
33
41
|
* <div data-slot="dialog">
|
|
34
42
|
* <button data-slot="dialog-trigger">Open</button>
|
|
35
|
-
* <div data-slot="dialog-
|
|
36
|
-
*
|
|
37
|
-
* <
|
|
38
|
-
*
|
|
39
|
-
*
|
|
43
|
+
* <div data-slot="dialog-portal">
|
|
44
|
+
* <div data-slot="dialog-overlay"></div>
|
|
45
|
+
* <div data-slot="dialog-content">
|
|
46
|
+
* <h2 data-slot="dialog-title">Title</h2>
|
|
47
|
+
* <p data-slot="dialog-description">Description</p>
|
|
48
|
+
* <button data-slot="dialog-close">Close</button>
|
|
49
|
+
* </div>
|
|
40
50
|
* </div>
|
|
41
51
|
* </div>
|
|
42
52
|
* ```
|
|
43
53
|
*
|
|
44
|
-
* Note: Overlay is required.
|
|
45
|
-
*
|
|
54
|
+
* Note: Overlay is required. The optional dialog-portal slot will be
|
|
55
|
+
* automatically moved to document.body to escape stacking context issues.
|
|
46
56
|
*/
|
|
47
57
|
declare function createDialog(root: Element, options?: DialogOptions): DialogController;
|
|
48
58
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=(e,t)=>e.querySelector(`[data-slot="${t}"]`),t=(e,t)=>[...e.querySelectorAll(`[data-slot="${t}"]`)];let n=0;const r=(e,t)=>e.id||=`${t}-${++n}`,i=(e,t,n)=>{n===null?e.removeAttribute(`aria-${t}`):e.setAttribute(`aria-${t}`,String(n))},a=(e,t,n)=>{t&&e.setAttribute(`aria-labelledby`,r(t,`title`)),n&&e.setAttribute(`aria-describedby`,r(n,`desc`))},o=(e,t,n,r)=>(e.addEventListener(t,n,r),()=>e.removeEventListener(t,n,r)),s=(e,t,n)=>e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:n})),c=`a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])`,l=[];let u=0,d=``,f
|
|
1
|
+
const e=(e,t)=>e.querySelector(`[data-slot="${t}"]`),t=(e,t)=>[...e.querySelectorAll(`[data-slot="${t}"]`)];let n=0;const r=(e,t)=>e.id||=`${t}-${++n}`,i=(e,t,n)=>{n===null?e.removeAttribute(`aria-${t}`):e.setAttribute(`aria-${t}`,String(n))},a=(e,t,n)=>{t&&e.setAttribute(`aria-labelledby`,r(t,`title`)),n&&e.setAttribute(`aria-describedby`,r(n,`desc`))},o=(e,t,n,r)=>(e.addEventListener(t,n,r),()=>e.removeEventListener(t,n,r)),s=(e,t,n)=>e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:n})),c=`a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])`,l=[];let u=0,d=``,f=``,p=null;function m(){let e=1e3;l.forEach((t,n)=>{let r=e+n*10;t._overlay&&(t._overlay.style.zIndex=String(r)),t._content&&(t._content.style.zIndex=String(r+1))})}function h(){if(p)return;let e=e=>{if(l.length===0)return;let t=l[l.length-1];if(!(!t||!t.isOpen)){if(e.key===`Escape`&&t._closeOnEscape){e.preventDefault(),t.close();return}e.key===`Tab`&&t._handleKeydown&&t._handleKeydown(e)}},t=o(document,`keydown`,e);p=()=>{t(),p=null}}function g(){l.length===0&&p&&p()}function _(t,n={}){let{defaultOpen:p=!1,onOpenChange:_,closeOnClickOutside:v=!0,closeOnEscape:y=!0,lockScroll:b=!0,alertDialog:x=!1}=n,S=e(t,`dialog-trigger`),C=e(t,`dialog-portal`),w=e(t,`dialog-overlay`),T=e(t,`dialog-content`),E=e(t,`dialog-title`),D=e(t,`dialog-description`);if(!T)throw Error(`Dialog requires dialog-content slot`);if(!w)throw Error(`Dialog requires dialog-overlay slot`);let O=!1,k=null,A=[],j=null,M=null,N=!1,P=!1;r(T,`dialog-content`),T.setAttribute(`role`,x?`alertdialog`:`dialog`),i(T,`modal`,!0),a(T,E,D),w.setAttribute(`role`,`presentation`),w.setAttribute(`aria-hidden`,`true`),w.tabIndex=-1,S&&(S.setAttribute(`aria-haspopup`,`dialog`),S.setAttribute(`aria-controls`,T.id),i(S,`expanded`,!1));let F=!1,I=()=>{T.hasAttribute(`tabindex`)||(T.tabIndex=-1,F=!0)},L=()=>{F&&(T.removeAttribute(`tabindex`),F=!1)},R=()=>{let e=T.querySelector(`[autofocus]`);if(e)return e.focus();let t=T.querySelector(c);if(t)return t.focus();I(),T.focus()},z=()=>{C&&!N&&(j=C.parentNode,M=C.nextSibling,document.body.appendChild(C),N=!0)},B=e=>{t.setAttribute(`data-state`,e),C&&C.setAttribute(`data-state`,e),w.setAttribute(`data-state`,e),T.setAttribute(`data-state`,e)},V=()=>{w.style.zIndex=``,T.style.zIndex=``},H=(e,n=!1)=>{if(!(O===e&&!n)){if(e){if(z(),k=document.activeElement,l.push(W),h(),m(),b&&!P){if(u===0){let e=window.innerWidth-document.documentElement.clientWidth;d=document.body.style.overflow,f=document.body.style.paddingRight,document.body.style.paddingRight=`${e}px`,document.body.style.overflow=`hidden`}u++,P=!0}}else{let e=l.indexOf(W);e!==-1&&l.splice(e,1),g(),V(),m(),P&&(u=Math.max(0,u-1),P=!1,u===0&&(document.body.style.overflow=d,document.body.style.paddingRight=f)),L();let t=k;k=null,requestAnimationFrame(()=>{t&&document.contains(t)&&typeof t.focus==`function`?t.focus():S&&document.contains(S)&&S.focus()})}O=e,T.hidden=!O,w.hidden=!O,S&&i(S,`expanded`,O),B(O?`open`:`closed`),s(t,`dialog:change`,{open:O}),_?.(O),e&&requestAnimationFrame(R)}},U=e=>{if(e.key!==`Tab`)return;let t=T.querySelectorAll(c);if(t.length===0){e.preventDefault(),I(),T.focus();return}let n=t[0],r=t[t.length-1],i=document.activeElement;if(!T.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())};p?(z(),T.hidden=!1,w.hidden=!1,B(`open`),H(!0,!0)):(T.hidden=!0,w.hidden=!0,B(`closed`)),S&&A.push(o(S,`click`,()=>H(!O))),A.push(o(T,`click`,e=>{let t=e.target;if(!t)return;let n=t.closest?.(`[data-slot="dialog-close"]`);n&&T.contains(n)&&H(!1)})),v&&A.push(o(w,`pointerdown`,e=>{e.target===w&&O&&H(!1)}));let W={open:()=>H(!0),close:()=>H(!1),toggle:()=>H(!O),get isOpen(){return O},destroy:()=>{if(O)H(!1,!0);else{let e=l.indexOf(W);e!==-1&&(l.splice(e,1),m(),g())}L(),A.forEach(e=>e()),A.length=0,C&&N&&(j&&document.contains(j)?j.insertBefore(C,M):C.remove(),N=!1)},_handleKeydown:U,_closeOnEscape:y,_content:T,_overlay:w};return W}const v=new WeakSet;function y(e=document){let n=[];for(let r of t(e,`dialog`)){if(v.has(r))continue;v.add(r),n.push(_(r))}return n}export{y as create,_ as createDialog};
|