@data-slot/popover 0.2.54 → 0.2.56
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 +18 -2
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -107,6 +107,21 @@ const popover = createPopover(element, {
|
|
|
107
107
|
### Optional Slots
|
|
108
108
|
|
|
109
109
|
- `popover-close` - Button to close the popover
|
|
110
|
+
- `popover-positioner` - Optional authored positioning wrapper (when provided, reused instead of generated wrapper)
|
|
111
|
+
- `popover-portal` - Optional authored portal wrapper that can contain `popover-positioner`
|
|
112
|
+
|
|
113
|
+
### Composed Portal Markup (Optional)
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<div data-slot="popover">
|
|
117
|
+
<button data-slot="popover-trigger">Trigger</button>
|
|
118
|
+
<div data-slot="popover-portal">
|
|
119
|
+
<div data-slot="popover-positioner">
|
|
120
|
+
<div data-slot="popover-content">Content</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
```
|
|
110
125
|
|
|
111
126
|
### Data Attributes
|
|
112
127
|
|
|
@@ -145,9 +160,10 @@ Placement can be set on root or content (content takes precedence):
|
|
|
145
160
|
## Styling
|
|
146
161
|
|
|
147
162
|
Popover position is computed in JavaScript and applied as `position: absolute` + inline `transform: translate3d(...)`.
|
|
148
|
-
By default, content is portaled to `document.body` while open (document coordinates).
|
|
163
|
+
By default, content is portaled to `document.body` while open (document coordinates). If you provide authored `popover-positioner` / `popover-portal` slots, those are reused. Otherwise a transient `popover-positioner` wrapper is generated.
|
|
164
|
+
If `portal` is disabled, positioning is applied directly to `popover-content`.
|
|
149
165
|
Use `data-open`/`data-closed` and `data-side` for styling/animation.
|
|
150
|
-
|
|
166
|
+
This keeps `popover-content` free for transform animations.
|
|
151
167
|
|
|
152
168
|
```css
|
|
153
169
|
[data-slot="popover-content"] {
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@data-slot/core`);const t=[`top`,`right`,`bottom`,`left`],n=[`start`,`center`,`end`];function r(r,i={}){let a=(0,e.getPart)(r,`popover-trigger`),o=(0,e.getPart)(r,`popover-content`),s=(0,e.getPart)(r,`popover-close`);if(!a||!o)throw Error(`Popover requires trigger and content slots`);let
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@data-slot/core`);const t=[`top`,`right`,`bottom`,`left`],n=[`start`,`center`,`end`];function r(r,i={}){let a=(0,e.getPart)(r,`popover-trigger`),o=(0,e.getPart)(r,`popover-content`),s=(0,e.getPart)(r,`popover-close`),c=(0,e.getPart)(r,`popover-positioner`),l=c&&o&&c.contains(o)?c:null,u=(0,e.getPart)(r,`popover-portal`),d=u&&l&&u.contains(l)?u:null;if(!a||!o)throw Error(`Popover requires trigger and content slots`);let f=i.defaultOpen??(0,e.getDataBool)(r,`defaultOpen`)??!1,p=i.onOpenChange,m=i.closeOnClickOutside??(0,e.getDataBool)(r,`closeOnClickOutside`)??!0,h=i.closeOnEscape??(0,e.getDataBool)(r,`closeOnEscape`)??!0,g=i.portal??(0,e.getDataBool)(o,`portal`)??(0,e.getDataBool)(r,`portal`)??!0,_=i.position??(0,e.getDataEnum)(o,`position`,t)??(0,e.getDataEnum)(r,`position`,t),v=i.side??(0,e.getDataEnum)(o,`side`,t)??(0,e.getDataEnum)(r,`side`,t)??_??`bottom`,y=i.align??(0,e.getDataEnum)(o,`align`,n)??(0,e.getDataEnum)(r,`align`,n)??`center`,b=i.sideOffset??(0,e.getDataNumber)(o,`sideOffset`)??(0,e.getDataNumber)(r,`sideOffset`)??4,x=i.alignOffset??(0,e.getDataNumber)(o,`alignOffset`)??(0,e.getDataNumber)(r,`alignOffset`)??0,S=i.avoidCollisions??(0,e.getDataBool)(o,`avoidCollisions`)??(0,e.getDataBool)(r,`avoidCollisions`)??!0,C=i.collisionPadding??(0,e.getDataNumber)(o,`collisionPadding`)??(0,e.getDataNumber)(r,`collisionPadding`)??8,w=f,T=[],E=(0,e.createPortalLifecycle)({content:o,root:r,enabled:g,wrapperSlot:l?void 0:`popover-positioner`,container:l??void 0,mountTarget:l?d??l:void 0}),D=!1,O=null,k=!1,A=()=>{k&&=(o.removeAttribute(`tabindex`),!1)},j=()=>{let e=o.querySelector(`[autofocus]`);if(e)return e.focus();let t=o.querySelector(`a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])`);if(t)return t.focus();o.getAttribute(`tabindex`)||(o.setAttribute(`tabindex`,`-1`),k=!0),o.focus()},M=(0,e.ensureId)(o,`popover-content`);a.setAttribute(`aria-haspopup`,`dialog`),a.setAttribute(`aria-controls`,M),o.setAttribute(`data-side`,v),o.setAttribute(`data-align`,y),o.setAttribute(`data-position`,v);let N=()=>{let t=E.container,n=r.ownerDocument.defaultView??window,i=(0,e.computeFloatingPosition)({anchorRect:a.getBoundingClientRect(),contentRect:o.getBoundingClientRect(),side:v,align:y,sideOffset:b,alignOffset:x,avoidCollisions:S,collisionPadding:C});t.style.position=`absolute`,t.style.top=`0px`,t.style.left=`0px`,t.style.transform=`translate3d(${i.x+n.scrollX}px, ${i.y+n.scrollY}px, 0)`,t.style.willChange=`transform`,t.style.margin=`0`,o.setAttribute(`data-side`,i.side),o.setAttribute(`data-align`,i.align),t!==o&&(t.setAttribute(`data-side`,i.side),t.setAttribute(`data-align`,i.align)),o.setAttribute(`data-position`,i.side)},P=e=>{let t=E.container;r.setAttribute(`data-state`,e),o.setAttribute(`data-state`,e),t!==o&&t.setAttribute(`data-state`,e),e===`open`?(r.setAttribute(`data-open`,``),o.setAttribute(`data-open`,``),t!==o&&t.setAttribute(`data-open`,``),r.removeAttribute(`data-closed`),o.removeAttribute(`data-closed`),t!==o&&t.removeAttribute(`data-closed`)):(r.setAttribute(`data-closed`,``),o.setAttribute(`data-closed`,``),t!==o&&t.setAttribute(`data-closed`,``),r.removeAttribute(`data-open`),o.removeAttribute(`data-open`),t!==o&&t.removeAttribute(`data-open`))},F=()=>{requestAnimationFrame(()=>{O&&O.isConnected?(0,e.focusElement)(O):(0,e.focusElement)(a),O=null})},I=(0,e.createPresenceLifecycle)({element:o,onExitComplete:()=>{D||(E.restore(),o.hidden=!0,A(),F())}}),L=(0,e.createPositionSync)({observedElements:[a,o],isActive:()=>w,ancestorScroll:!1,onUpdate:N}),R=t=>{w!==t&&(t&&(O=document.activeElement),w=t,(0,e.setAria)(a,`expanded`,w),t?(E.mount(),o.hidden=!1,P(`open`),I.enter(),N(),L.start(),L.update(),requestAnimationFrame(j)):(P(`closed`),I.exit(),L.stop()),(0,e.emit)(r,`popover:change`,{open:w}),p?.(w))};return(0,e.setAria)(a,`expanded`,w),P(w?`open`:`closed`),o.hidden=!w,f&&(E.mount(),I.enter(),o.hidden=!1,N(),L.start(),L.update(),requestAnimationFrame(j)),T.push((0,e.on)(a,`click`,()=>R(!w))),s&&T.push((0,e.on)(s,`click`,()=>R(!1))),T.push((0,e.createDismissLayer)({root:r,isOpen:()=>w,onDismiss:()=>R(!1),closeOnClickOutside:m,closeOnEscape:h})),T.push((0,e.on)(r,`popover:set`,e=>{let t=e.detail,n;t?.open===void 0?t?.value!==void 0&&(n=t.value):n=t.open,typeof n==`boolean`&&R(n)})),{open:()=>R(!0),close:()=>R(!1),toggle:()=>R(!w),get isOpen(){return w},destroy:()=>{D=!0,L.stop(),I.cleanup(),E.cleanup(),T.forEach(e=>e()),T.length=0,A()}}}const i=new WeakSet;function a(t=document){let n=[];for(let a of(0,e.getRoots)(t,`popover`))i.has(a)||(i.add(a),n.push(r(a)));return n}exports.create=a,exports.createPopover=r;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{computeFloatingPosition as e,createDismissLayer as t,createPortalLifecycle as n,createPositionSync as r,createPresenceLifecycle as i,emit as a,ensureId as o,focusElement as s,getDataBool as c,getDataEnum as l,getDataNumber as u,getPart as d,getRoots as f,on as p,setAria as m}from"@data-slot/core";const h=[`top`,`right`,`bottom`,`left`],g=[`start`,`center`,`end`];function _(f,_={}){let v=d(f,`popover-trigger`),y=d(f,`popover-content`),b=d(f,`popover-close`);if(!v||!y)throw Error(`Popover requires trigger and content slots`);let
|
|
1
|
+
import{computeFloatingPosition as e,createDismissLayer as t,createPortalLifecycle as n,createPositionSync as r,createPresenceLifecycle as i,emit as a,ensureId as o,focusElement as s,getDataBool as c,getDataEnum as l,getDataNumber as u,getPart as d,getRoots as f,on as p,setAria as m}from"@data-slot/core";const h=[`top`,`right`,`bottom`,`left`],g=[`start`,`center`,`end`];function _(f,_={}){let v=d(f,`popover-trigger`),y=d(f,`popover-content`),b=d(f,`popover-close`),x=d(f,`popover-positioner`),S=x&&y&&x.contains(y)?x:null,C=d(f,`popover-portal`),w=C&&S&&C.contains(S)?C:null;if(!v||!y)throw Error(`Popover requires trigger and content slots`);let T=_.defaultOpen??c(f,`defaultOpen`)??!1,E=_.onOpenChange,D=_.closeOnClickOutside??c(f,`closeOnClickOutside`)??!0,O=_.closeOnEscape??c(f,`closeOnEscape`)??!0,k=_.portal??c(y,`portal`)??c(f,`portal`)??!0,A=_.position??l(y,`position`,h)??l(f,`position`,h),j=_.side??l(y,`side`,h)??l(f,`side`,h)??A??`bottom`,M=_.align??l(y,`align`,g)??l(f,`align`,g)??`center`,N=_.sideOffset??u(y,`sideOffset`)??u(f,`sideOffset`)??4,P=_.alignOffset??u(y,`alignOffset`)??u(f,`alignOffset`)??0,F=_.avoidCollisions??c(y,`avoidCollisions`)??c(f,`avoidCollisions`)??!0,I=_.collisionPadding??u(y,`collisionPadding`)??u(f,`collisionPadding`)??8,L=T,R=[],z=n({content:y,root:f,enabled:k,wrapperSlot:S?void 0:`popover-positioner`,container:S??void 0,mountTarget:S?w??S:void 0}),B=!1,V=null,H=!1,U=()=>{H&&=(y.removeAttribute(`tabindex`),!1)},W=()=>{let e=y.querySelector(`[autofocus]`);if(e)return e.focus();let t=y.querySelector(`a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])`);if(t)return t.focus();y.getAttribute(`tabindex`)||(y.setAttribute(`tabindex`,`-1`),H=!0),y.focus()},G=o(y,`popover-content`);v.setAttribute(`aria-haspopup`,`dialog`),v.setAttribute(`aria-controls`,G),y.setAttribute(`data-side`,j),y.setAttribute(`data-align`,M),y.setAttribute(`data-position`,j);let K=()=>{let t=z.container,n=f.ownerDocument.defaultView??window,r=e({anchorRect:v.getBoundingClientRect(),contentRect:y.getBoundingClientRect(),side:j,align:M,sideOffset:N,alignOffset:P,avoidCollisions:F,collisionPadding:I});t.style.position=`absolute`,t.style.top=`0px`,t.style.left=`0px`,t.style.transform=`translate3d(${r.x+n.scrollX}px, ${r.y+n.scrollY}px, 0)`,t.style.willChange=`transform`,t.style.margin=`0`,y.setAttribute(`data-side`,r.side),y.setAttribute(`data-align`,r.align),t!==y&&(t.setAttribute(`data-side`,r.side),t.setAttribute(`data-align`,r.align)),y.setAttribute(`data-position`,r.side)},q=e=>{let t=z.container;f.setAttribute(`data-state`,e),y.setAttribute(`data-state`,e),t!==y&&t.setAttribute(`data-state`,e),e===`open`?(f.setAttribute(`data-open`,``),y.setAttribute(`data-open`,``),t!==y&&t.setAttribute(`data-open`,``),f.removeAttribute(`data-closed`),y.removeAttribute(`data-closed`),t!==y&&t.removeAttribute(`data-closed`)):(f.setAttribute(`data-closed`,``),y.setAttribute(`data-closed`,``),t!==y&&t.setAttribute(`data-closed`,``),f.removeAttribute(`data-open`),y.removeAttribute(`data-open`),t!==y&&t.removeAttribute(`data-open`))},J=()=>{requestAnimationFrame(()=>{V&&V.isConnected?s(V):s(v),V=null})},Y=i({element:y,onExitComplete:()=>{B||(z.restore(),y.hidden=!0,U(),J())}}),X=r({observedElements:[v,y],isActive:()=>L,ancestorScroll:!1,onUpdate:K}),Z=e=>{L!==e&&(e&&(V=document.activeElement),L=e,m(v,`expanded`,L),e?(z.mount(),y.hidden=!1,q(`open`),Y.enter(),K(),X.start(),X.update(),requestAnimationFrame(W)):(q(`closed`),Y.exit(),X.stop()),a(f,`popover:change`,{open:L}),E?.(L))};return m(v,`expanded`,L),q(L?`open`:`closed`),y.hidden=!L,T&&(z.mount(),Y.enter(),y.hidden=!1,K(),X.start(),X.update(),requestAnimationFrame(W)),R.push(p(v,`click`,()=>Z(!L))),b&&R.push(p(b,`click`,()=>Z(!1))),R.push(t({root:f,isOpen:()=>L,onDismiss:()=>Z(!1),closeOnClickOutside:D,closeOnEscape:O})),R.push(p(f,`popover:set`,e=>{let t=e.detail,n;t?.open===void 0?t?.value!==void 0&&(n=t.value):n=t.open,typeof n==`boolean`&&Z(n)})),{open:()=>Z(!0),close:()=>Z(!1),toggle:()=>Z(!L),get isOpen(){return L},destroy:()=>{B=!0,X.stop(),Y.cleanup(),z.cleanup(),R.forEach(e=>e()),R.length=0,U()}}}const v=new WeakSet;function y(e=document){let t=[];for(let n of f(e,`popover`))v.has(n)||(v.add(n),t.push(_(n)));return t}export{y as create,_ as createPopover};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@data-slot/popover",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.56",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -38,6 +38,6 @@
|
|
|
38
38
|
],
|
|
39
39
|
"license": "MIT",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@data-slot/core": "0.2.
|
|
41
|
+
"@data-slot/core": "0.2.56"
|
|
42
42
|
}
|
|
43
43
|
}
|