@data-slot/popover 0.2.41 → 0.2.42
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
CHANGED
|
@@ -53,6 +53,7 @@ const popover = createPopover(element, {
|
|
|
53
53
|
alignOffset: 0,
|
|
54
54
|
avoidCollisions: true,
|
|
55
55
|
collisionPadding: 8,
|
|
56
|
+
portal: true,
|
|
56
57
|
closeOnClickOutside: true,
|
|
57
58
|
closeOnEscape: true,
|
|
58
59
|
onOpenChange: (open) => console.log(open),
|
|
@@ -70,6 +71,7 @@ const popover = createPopover(element, {
|
|
|
70
71
|
| `alignOffset` | `number` | `0` | Offset from alignment edge in pixels |
|
|
71
72
|
| `avoidCollisions` | `boolean` | `true` | Flip/shift to stay in viewport |
|
|
72
73
|
| `collisionPadding` | `number` | `8` | Viewport edge padding in pixels |
|
|
74
|
+
| `portal` | `boolean` | `true` | Portal content to `document.body` while open |
|
|
73
75
|
| `position` | `"top" \| "bottom" \| "left" \| "right"` | - | Deprecated alias for `side` |
|
|
74
76
|
| `closeOnClickOutside` | `boolean` | `true` | Close when clicking outside |
|
|
75
77
|
| `closeOnEscape` | `boolean` | `true` | Close when pressing Escape |
|
|
@@ -119,6 +121,7 @@ Options can also be set via data attributes on the root element. JS options take
|
|
|
119
121
|
| `data-align-offset` | number | `0` | Offset from alignment edge (px) |
|
|
120
122
|
| `data-avoid-collisions` | boolean | `true` | Flip/shift to stay in viewport |
|
|
121
123
|
| `data-collision-padding` | number | `8` | Viewport edge padding (px) |
|
|
124
|
+
| `data-portal` | boolean | `true` | Portal content to `document.body` while open |
|
|
122
125
|
| `data-close-on-click-outside` | boolean | `true` | Close when clicking outside |
|
|
123
126
|
| `data-close-on-escape` | boolean | `true` | Close when pressing Escape |
|
|
124
127
|
|
|
@@ -141,7 +144,8 @@ Placement can be set on root or content (content takes precedence):
|
|
|
141
144
|
|
|
142
145
|
## Styling
|
|
143
146
|
|
|
144
|
-
Popover position is computed in JavaScript and applied as `position:
|
|
147
|
+
Popover position is computed in JavaScript and applied as `position: absolute` + inline `top/left`.
|
|
148
|
+
By default, content is portaled to `document.body` while open, so absolute positioning is based on document coordinates.
|
|
145
149
|
Use `data-state`, `data-side`, and `data-align` for styling/animation:
|
|
146
150
|
|
|
147
151
|
```css
|
|
@@ -151,7 +155,7 @@ Use `data-state`, `data-side`, and `data-align` for styling/animation:
|
|
|
151
155
|
}
|
|
152
156
|
|
|
153
157
|
[data-slot="popover-content"] {
|
|
154
|
-
position:
|
|
158
|
+
position: absolute;
|
|
155
159
|
transition: opacity 0.2s ease-out, transform 0.2s ease-out;
|
|
156
160
|
}
|
|
157
161
|
|
|
@@ -178,7 +182,7 @@ With Tailwind:
|
|
|
178
182
|
data-slot="popover-content"
|
|
179
183
|
data-side="bottom"
|
|
180
184
|
data-align="start"
|
|
181
|
-
class="
|
|
185
|
+
class="absolute bg-white shadow-lg rounded-lg p-4 transition data-[state=closed]:opacity-0"
|
|
182
186
|
>
|
|
183
187
|
Content
|
|
184
188
|
</div>
|
|
@@ -28,6 +28,8 @@ interface PopoverOptions {
|
|
|
28
28
|
collisionPadding?: number;
|
|
29
29
|
/** Callback when open state changes */
|
|
30
30
|
onOpenChange?: (open: boolean) => void;
|
|
31
|
+
/** Portal content to body while open. @default true */
|
|
32
|
+
portal?: boolean;
|
|
31
33
|
/** Close when clicking outside */
|
|
32
34
|
closeOnClickOutside?: boolean;
|
|
33
35
|
/** Close when pressing Escape */
|
|
@@ -28,6 +28,8 @@ interface PopoverOptions {
|
|
|
28
28
|
collisionPadding?: number;
|
|
29
29
|
/** Callback when open state changes */
|
|
30
30
|
onOpenChange?: (open: boolean) => void;
|
|
31
|
+
/** Portal content to body while open. @default true */
|
|
32
|
+
portal?: boolean;
|
|
31
33
|
/** Close when clicking outside */
|
|
32
34
|
closeOnClickOutside?: boolean;
|
|
33
35
|
/** Close when pressing Escape */
|
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 c=i.defaultOpen??(0,e.getDataBool)(r,`defaultOpen`)??!1,l=i.onOpenChange,u=i.closeOnClickOutside??(0,e.getDataBool)(r,`closeOnClickOutside`)??!0,d=i.closeOnEscape??(0,e.getDataBool)(r,`closeOnEscape`)??!0,f=i.position??(0,e.getDataEnum)(o,`position`,t)??(0,e.getDataEnum)(r,`position`,t),
|
|
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 c=i.defaultOpen??(0,e.getDataBool)(r,`defaultOpen`)??!1,l=i.onOpenChange,u=i.closeOnClickOutside??(0,e.getDataBool)(r,`closeOnClickOutside`)??!0,d=i.closeOnEscape??(0,e.getDataBool)(r,`closeOnEscape`)??!0,f=i.portal??(0,e.getDataBool)(o,`portal`)??(0,e.getDataBool)(r,`portal`)??!0,p=i.position??(0,e.getDataEnum)(o,`position`,t)??(0,e.getDataEnum)(r,`position`,t),m=i.side??(0,e.getDataEnum)(o,`side`,t)??(0,e.getDataEnum)(r,`side`,t)??p??`bottom`,h=i.align??(0,e.getDataEnum)(o,`align`,n)??(0,e.getDataEnum)(r,`align`,n)??`center`,g=i.sideOffset??(0,e.getDataNumber)(o,`sideOffset`)??(0,e.getDataNumber)(r,`sideOffset`)??4,_=i.alignOffset??(0,e.getDataNumber)(o,`alignOffset`)??(0,e.getDataNumber)(r,`alignOffset`)??0,v=i.avoidCollisions??(0,e.getDataBool)(o,`avoidCollisions`)??(0,e.getDataBool)(r,`avoidCollisions`)??!0,y=i.collisionPadding??(0,e.getDataNumber)(o,`collisionPadding`)??(0,e.getDataNumber)(r,`collisionPadding`)??8,b=c,x=[],S=(0,e.createPortalLifecycle)({content:o,root:r,enabled:f}),C=null,w=!1,T=()=>{w&&=(o.removeAttribute(`tabindex`),!1)},E=()=>{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`),w=!0),o.focus()},D=(0,e.ensureId)(o,`popover-content`);a.setAttribute(`aria-haspopup`,`dialog`),a.setAttribute(`aria-controls`,D),o.setAttribute(`data-side`,m),o.setAttribute(`data-align`,h),o.setAttribute(`data-position`,m);let O=()=>{let t=r.ownerDocument.defaultView??window,n=(0,e.computeFloatingPosition)({anchorRect:a.getBoundingClientRect(),contentRect:o.getBoundingClientRect(),side:m,align:h,sideOffset:g,alignOffset:_,avoidCollisions:v,collisionPadding:y});o.style.position=`absolute`,o.style.top=`${n.y+t.scrollY}px`,o.style.left=`${n.x+t.scrollX}px`,o.style.margin=`0`,o.setAttribute(`data-side`,n.side),o.setAttribute(`data-align`,n.align),o.setAttribute(`data-position`,n.side)},k=(0,e.createPositionSync)({observedElements:[a,o],isActive:()=>b,ancestorScroll:!1,onUpdate:O}),A=t=>{b!==t&&(t&&(C=document.activeElement),b=t,(0,e.setAria)(a,`expanded`,b),(0,e.emit)(r,`popover:change`,{open:b}),l?.(b),t?(S.mount(),o.hidden=!1,r.setAttribute(`data-state`,`open`),o.setAttribute(`data-state`,`open`),O(),k.start(),k.update(),requestAnimationFrame(E)):(k.stop(),S.restore(),o.hidden=!0,r.setAttribute(`data-state`,`closed`),o.setAttribute(`data-state`,`closed`),T(),requestAnimationFrame(()=>{C&&C.isConnected?C.focus():a.focus(),C=null})))};return(0,e.setAria)(a,`expanded`,b),o.hidden=!b,r.setAttribute(`data-state`,b?`open`:`closed`),o.setAttribute(`data-state`,b?`open`:`closed`),c&&(S.mount(),O(),k.start(),k.update(),requestAnimationFrame(E)),x.push((0,e.on)(a,`click`,()=>A(!b))),s&&x.push((0,e.on)(s,`click`,()=>A(!1))),x.push((0,e.createDismissLayer)({root:r,isOpen:()=>b,onDismiss:()=>A(!1),closeOnClickOutside:u,closeOnEscape:d})),x.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`&&A(n)})),{open:()=>A(!0),close:()=>A(!1),toggle:()=>A(!b),get isOpen(){return b},destroy:()=>{k.stop(),S.cleanup(),x.forEach(e=>e()),x.length=0,T()}}}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,
|
|
1
|
+
import{computeFloatingPosition as e,createDismissLayer as t,createPortalLifecycle as n,createPositionSync as r,emit as i,ensureId as a,getDataBool as o,getDataEnum as s,getDataNumber as c,getPart as l,getRoots as u,on as d,setAria as f}from"@data-slot/core";const p=[`top`,`right`,`bottom`,`left`],m=[`start`,`center`,`end`];function h(u,h={}){let g=l(u,`popover-trigger`),_=l(u,`popover-content`),v=l(u,`popover-close`);if(!g||!_)throw Error(`Popover requires trigger and content slots`);let y=h.defaultOpen??o(u,`defaultOpen`)??!1,b=h.onOpenChange,x=h.closeOnClickOutside??o(u,`closeOnClickOutside`)??!0,S=h.closeOnEscape??o(u,`closeOnEscape`)??!0,C=h.portal??o(_,`portal`)??o(u,`portal`)??!0,w=h.position??s(_,`position`,p)??s(u,`position`,p),T=h.side??s(_,`side`,p)??s(u,`side`,p)??w??`bottom`,E=h.align??s(_,`align`,m)??s(u,`align`,m)??`center`,D=h.sideOffset??c(_,`sideOffset`)??c(u,`sideOffset`)??4,O=h.alignOffset??c(_,`alignOffset`)??c(u,`alignOffset`)??0,k=h.avoidCollisions??o(_,`avoidCollisions`)??o(u,`avoidCollisions`)??!0,A=h.collisionPadding??c(_,`collisionPadding`)??c(u,`collisionPadding`)??8,j=y,M=[],N=n({content:_,root:u,enabled:C}),P=null,F=!1,I=()=>{F&&=(_.removeAttribute(`tabindex`),!1)},L=()=>{let e=_.querySelector(`[autofocus]`);if(e)return e.focus();let t=_.querySelector(`a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])`);if(t)return t.focus();_.getAttribute(`tabindex`)||(_.setAttribute(`tabindex`,`-1`),F=!0),_.focus()},R=a(_,`popover-content`);g.setAttribute(`aria-haspopup`,`dialog`),g.setAttribute(`aria-controls`,R),_.setAttribute(`data-side`,T),_.setAttribute(`data-align`,E),_.setAttribute(`data-position`,T);let z=()=>{let t=u.ownerDocument.defaultView??window,n=e({anchorRect:g.getBoundingClientRect(),contentRect:_.getBoundingClientRect(),side:T,align:E,sideOffset:D,alignOffset:O,avoidCollisions:k,collisionPadding:A});_.style.position=`absolute`,_.style.top=`${n.y+t.scrollY}px`,_.style.left=`${n.x+t.scrollX}px`,_.style.margin=`0`,_.setAttribute(`data-side`,n.side),_.setAttribute(`data-align`,n.align),_.setAttribute(`data-position`,n.side)},B=r({observedElements:[g,_],isActive:()=>j,ancestorScroll:!1,onUpdate:z}),V=e=>{j!==e&&(e&&(P=document.activeElement),j=e,f(g,`expanded`,j),i(u,`popover:change`,{open:j}),b?.(j),e?(N.mount(),_.hidden=!1,u.setAttribute(`data-state`,`open`),_.setAttribute(`data-state`,`open`),z(),B.start(),B.update(),requestAnimationFrame(L)):(B.stop(),N.restore(),_.hidden=!0,u.setAttribute(`data-state`,`closed`),_.setAttribute(`data-state`,`closed`),I(),requestAnimationFrame(()=>{P&&P.isConnected?P.focus():g.focus(),P=null})))};return f(g,`expanded`,j),_.hidden=!j,u.setAttribute(`data-state`,j?`open`:`closed`),_.setAttribute(`data-state`,j?`open`:`closed`),y&&(N.mount(),z(),B.start(),B.update(),requestAnimationFrame(L)),M.push(d(g,`click`,()=>V(!j))),v&&M.push(d(v,`click`,()=>V(!1))),M.push(t({root:u,isOpen:()=>j,onDismiss:()=>V(!1),closeOnClickOutside:x,closeOnEscape:S})),M.push(d(u,`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`&&V(n)})),{open:()=>V(!0),close:()=>V(!1),toggle:()=>V(!j),get isOpen(){return j},destroy:()=>{B.stop(),N.cleanup(),M.forEach(e=>e()),M.length=0,I()}}}const g=new WeakSet;function _(e=document){let t=[];for(let n of u(e,`popover`))g.has(n)||(g.add(n),t.push(h(n)));return t}export{_ as create,h 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.42",
|
|
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.42"
|
|
42
42
|
}
|
|
43
43
|
}
|