@data-slot/tooltip 0.2.140 → 0.2.142

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
@@ -59,7 +59,7 @@ const tooltip = createTooltip(element, {
59
59
  |--------|------|---------|-------------|
60
60
  | `delay` | `number` | `300` | Delay before showing tooltip (ms) |
61
61
  | `skipDelayDuration` | `number` | `300` | Duration to skip delay after closing (ms). Set to `0` to disable warm-up. |
62
- | `side` | `"top" \| "right" \| "bottom" \| "left"` | `"top"` | Preferred side relative to trigger |
62
+ | `side` | `"top" \| "right" \| "bottom" \| "left" \| "inline-start" \| "inline-end"` | `"top"` | Preferred side relative to trigger |
63
63
  | `align` | `"start" \| "center" \| "end"` | `"center"` | Preferred alignment |
64
64
  | `sideOffset` | `number` | `4` | Distance from trigger in pixels |
65
65
  | `alignOffset` | `number` | `0` | Offset from alignment edge in pixels |
@@ -85,7 +85,7 @@ Placement attributes (`data-side`, `data-align`, `data-side-offset`, `data-align
85
85
  |-----------|------|---------|-------------|
86
86
  | `data-delay` | number | `300` | Delay before showing tooltip (ms) |
87
87
  | `data-skip-delay-duration` | number | `300` | Duration to skip delay after closing (ms) |
88
- | `data-side` | string | `"top"` | Side relative to trigger |
88
+ | `data-side` | string | `"top"` | Side relative to trigger (`top`, `right`, `bottom`, `left`, `inline-start`, `inline-end`) |
89
89
  | `data-align` | string | `"center"` | Alignment along the side |
90
90
  | `data-side-offset` | number | `4` | Distance from trigger (px) |
91
91
  | `data-align-offset` | number | `0` | Alignment edge offset (px) |
@@ -130,7 +130,10 @@ Placement attributes (`data-side`, `data-align`, `data-side-offset`, `data-align
130
130
  ```html
131
131
  <div data-slot="tooltip">
132
132
  <button data-slot="tooltip-trigger">Trigger</button>
133
- <div data-slot="tooltip-content">Content</div>
133
+ <div data-slot="tooltip-content">
134
+ Content
135
+ <div data-slot="tooltip-arrow"></div>
136
+ </div>
134
137
  </div>
135
138
  ```
136
139
 
@@ -143,6 +146,7 @@ Placement attributes (`data-side`, `data-align`, `data-side-offset`, `data-align
143
146
 
144
147
  - `tooltip-positioner` - Optional authored positioning wrapper
145
148
  - `tooltip-portal` - Optional authored portal wrapper that can contain `tooltip-positioner`
149
+ - `tooltip-arrow` - Optional arrow element positioned against the trigger
146
150
 
147
151
  ### Composed Portal Markup (Optional)
148
152
 
@@ -151,7 +155,10 @@ Placement attributes (`data-side`, `data-align`, `data-side-offset`, `data-align
151
155
  <button data-slot="tooltip-trigger">Trigger</button>
152
156
  <div data-slot="tooltip-portal">
153
157
  <div data-slot="tooltip-positioner">
154
- <div data-slot="tooltip-content">Content</div>
158
+ <div data-slot="tooltip-content">
159
+ Content
160
+ <div data-slot="tooltip-arrow"></div>
161
+ </div>
155
162
  </div>
156
163
  </div>
157
164
  </div>
@@ -163,16 +170,28 @@ The component sets these attributes automatically:
163
170
 
164
171
  | Element | Attribute | Values |
165
172
  |---------|-----------|--------|
166
- | Root | `data-state` | `"open"` \| `"closed"` |
173
+ | Root | `data-state` | `"open"` \| `"closed"` (legacy compatibility) |
167
174
  | Root | `data-open` / `data-closed` | Present when matching state |
168
- | Root | `data-instant` | Present for warm-up opens and warm-handoff instant closes |
169
- | Content | `data-state` | `"open"` \| `"closed"` |
175
+ | Root | `data-instant` | `"delay"` \| `"focus"` \| `"dismiss"` |
176
+ | Content | `data-state` | `"open"` \| `"closed"` (legacy compatibility) |
170
177
  | Content | `data-open` / `data-closed` | Present when matching state |
171
- | Content | `data-instant` | Present for warm-up opens and warm-handoff instant closes |
172
- | Content | `data-side` | `"top"` \| `"right"` \| `"bottom"` \| `"left"` |
178
+ | Content | `data-starting-style` | Present while opening |
179
+ | Content | `data-ending-style` | Present while closing |
180
+ | Content | `data-instant` | `"delay"` \| `"focus"` \| `"dismiss"` |
181
+ | Content | `data-side` | `"top"` \| `"right"` \| `"bottom"` \| `"left"` \| `"inline-start"` \| `"inline-end"` |
173
182
  | Content | `data-align` | `"start"` \| `"center"` \| `"end"` |
174
183
  | Content | `role` | `"tooltip"` |
175
184
  | Content | `aria-hidden` | `"true"` when closed, `"false"` when open |
185
+ | Positioner | `data-open` / `data-closed` | Present when matching state |
186
+ | Positioner | `data-instant` | `"delay"` \| `"focus"` \| `"dismiss"` |
187
+ | Positioner | `data-side` | `"top"` \| `"right"` \| `"bottom"` \| `"left"` \| `"inline-start"` \| `"inline-end"` |
188
+ | Positioner | `data-align` | `"start"` \| `"center"` \| `"end"` |
189
+ | Arrow | `data-open` / `data-closed` | Present when matching state |
190
+ | Arrow | `data-instant` | `"delay"` \| `"focus"` \| `"dismiss"` |
191
+ | Arrow | `data-side` | `"top"` \| `"right"` \| `"bottom"` \| `"left"` \| `"inline-start"` \| `"inline-end"` |
192
+ | Arrow | `data-align` | `"start"` \| `"center"` \| `"end"` |
193
+ | Arrow | `data-uncentered` | Present when the arrow cannot stay perfectly centered |
194
+ | Arrow | `aria-hidden` | `"true"` |
176
195
  | Trigger | `aria-describedby` | Content ID when open, removed when closed |
177
196
 
178
197
  ## Styling
@@ -180,23 +199,42 @@ The component sets these attributes automatically:
180
199
  Position is computed in JavaScript and applied to the positioner as `position: absolute` + `transform: translate3d(...)`.
181
200
  By default, content is portaled to `document.body` while open.
182
201
  The positioned element (`tooltip-positioner`, or `tooltip-content` when `portal` is disabled) gets `--transform-origin`, which `tooltip-content` can use for transform animations via CSS inheritance.
183
- Use `data-open` / `data-closed`, `data-side`, and `data-align` for styling and animations.
202
+ Use `data-open` / `data-closed`, `data-starting-style` / `data-ending-style`, `data-side`, `data-align`, and `data-instant` for styling and animations.
184
203
  Placement uses layout dimensions, so `scale`/`zoom` animations on `tooltip-content` remain stable without adding an extra wrapper.
204
+ Tooltip arrow geometry is runtime-owned: the controller writes inline `top` / `left` coordinates and `position: absolute` on `tooltip-arrow`. CSS should only handle edge attachment, rotation, and optional cosmetic nudges. Avoid overriding the arrow cross-axis with helpers like `top-1/2`, `left-1/2`, or `-translate-y-1/2`.
185
205
 
186
206
  ### Recommended CSS
187
207
 
188
- The visibility transition trick keeps the tooltip visible during fade-out, then becomes non-focusable after the transition completes—no JS timers needed.
208
+ The example below matches the Base/shadcn composition style: real `tooltip-arrow`, logical side support, and valued `data-instant`.
189
209
 
190
210
  ```css
191
211
  [data-slot="tooltip-content"] {
212
+ position: absolute;
213
+ display: inline-flex;
214
+ align-items: center;
215
+ gap: 0.375rem;
216
+ padding: 0.375rem 0.75rem;
217
+ border-radius: 1rem;
218
+ font-size: 0.75rem;
192
219
  white-space: nowrap;
220
+ background: #111827;
221
+ color: white;
193
222
  opacity: 0;
194
223
  visibility: hidden;
195
224
  pointer-events: none;
196
- transform-origin: var(--transform-origin, center);
225
+ transform-origin: var(--transform-origin, center center);
226
+ --tooltip-slide-x: 0px;
227
+ --tooltip-slide-y: 0px;
197
228
  transition: opacity 0.15s ease, visibility 0s linear 0.15s;
198
229
  }
199
230
 
231
+ [data-slot="tooltip-content"][data-side="top"] { --tooltip-slide-y: 8px; }
232
+ [data-slot="tooltip-content"][data-side="bottom"] { --tooltip-slide-y: -8px; }
233
+ [data-slot="tooltip-content"][data-side="left"] { --tooltip-slide-x: 8px; }
234
+ [data-slot="tooltip-content"][data-side="right"] { --tooltip-slide-x: -8px; }
235
+ [data-slot="tooltip-content"][data-side="inline-start"] { --tooltip-slide-x: 8px; }
236
+ [data-slot="tooltip-content"][data-side="inline-end"] { --tooltip-slide-x: -8px; }
237
+
200
238
  [data-slot="tooltip-content"][data-open] {
201
239
  opacity: 1;
202
240
  visibility: visible;
@@ -212,27 +250,68 @@ The visibility transition trick keeps the tooltip visible during fade-out, then
212
250
  transition: none;
213
251
  animation: none;
214
252
  }
253
+
254
+ [data-slot="tooltip-arrow"] {
255
+ width: 0.625rem;
256
+ height: 0.625rem;
257
+ background: inherit;
258
+ border-radius: 2px;
259
+ transform: rotate(45deg);
260
+ }
261
+
262
+ [data-slot="tooltip-arrow"][data-side="top"] { bottom: -0.25rem; }
263
+ [data-slot="tooltip-arrow"][data-side="bottom"] { top: -0.25rem; }
264
+ [data-slot="tooltip-arrow"][data-side="left"] {
265
+ right: -0.25rem;
266
+ transform: translateX(-1.5px) rotate(45deg);
267
+ }
268
+ [data-slot="tooltip-arrow"][data-side="right"] {
269
+ left: -0.25rem;
270
+ transform: translateX(1.5px) rotate(45deg);
271
+ }
272
+ [data-slot="tooltip-arrow"][data-side="inline-start"] {
273
+ right: -0.25rem;
274
+ transform: translateX(-1.5px) rotate(45deg);
275
+ }
276
+ [data-slot="tooltip-arrow"][data-side="inline-end"] {
277
+ left: -0.25rem;
278
+ transform: translateX(1.5px) rotate(45deg);
279
+ }
215
280
  ```
216
281
 
217
282
  ### Tailwind Example
218
283
 
219
- Use root/content data attributes for open-state styling:
284
+ Use content and arrow data attributes for open-state styling:
220
285
 
221
286
  ```html
222
287
  <div data-slot="tooltip">
223
288
  <button data-slot="tooltip-trigger">
224
289
  Hover me
225
290
  </button>
226
- <div
227
- data-slot="tooltip-content"
291
+ <div
292
+ data-slot="tooltip-content"
228
293
  data-side="top"
229
294
  class="px-2 py-1
230
295
  bg-gray-900 text-white text-sm rounded
231
296
  opacity-0 pointer-events-none transition-opacity duration-150
232
- data-[open]:opacity-100
233
- data-[open]:pointer-events-auto"
297
+ data-[open]:opacity-100 data-[open]:pointer-events-auto
298
+ data-[instant]:transition-none"
234
299
  >
235
300
  Tooltip text
301
+ <div
302
+ data-slot="tooltip-arrow"
303
+ class="absolute size-2.5 rotate-45 bg-gray-900
304
+ data-[side=top]:-bottom-1
305
+ data-[side=bottom]:-top-1
306
+ data-[side=left]:-right-1
307
+ data-[side=left]:-translate-x-[1.5px]
308
+ data-[side=right]:-left-1
309
+ data-[side=right]:translate-x-[1.5px]
310
+ data-[side=inline-start]:-right-1
311
+ data-[side=inline-start]:-translate-x-[1.5px]
312
+ data-[side=inline-end]:-left-1
313
+ data-[side=inline-end]:translate-x-[1.5px]"
314
+ ></div>
236
315
  </div>
237
316
  </div>
238
317
  ```
@@ -243,8 +322,9 @@ When a user closes one tooltip and quickly hovers another, the second tooltip sh
243
322
 
244
323
  - Controlled by `skipDelayDuration` option
245
324
  - Set to `0` to disable this behavior
246
- - Warm-up adds `data-instant` on instant open/close cycles so CSS can disable transitions
247
- - During warm handoff to another tooltip trigger, the stale tooltip closes with `data-instant` so exit animation can be skipped
325
+ - Warm-up opens and warm handoff closes use `data-instant="delay"`
326
+ - Focus-triggered opens use `data-instant="focus"`
327
+ - Dismiss-style closes (for example `Escape`) use `data-instant="dismiss"`
248
328
  - Warm window is set only when a tooltip actually closes (not when a pending open is cancelled)
249
329
 
250
330
  ## Accessibility
@@ -325,7 +405,11 @@ element.dispatchEvent(
325
405
 
326
406
  #### Deprecated Shapes
327
407
 
328
- The following shape is deprecated and will be removed in v1.0:
408
+ The following attributes and shapes are deprecated and will be removed in v1.0:
409
+
410
+ - Legacy `data-state="open|closed"` styling on `tooltip` root and `tooltip-content`
411
+
412
+ Use `data-open` / `data-closed`, `data-starting-style`, `data-ending-style`, and `data-instant` instead.
329
413
 
330
414
  ```javascript
331
415
  // Deprecated: { value: boolean }
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@data-slot/core`);const t=`@data-slot/tooltip`;let n=0;const r=new Set,i=new Set,a=(e,t)=>{if(!e)return!1;for(let n of r)if(n!==t&&n.contains(e))return!0;return!1},o=(e,t)=>{for(let n of i)n(e,t)},s=[`top`,`right`,`bottom`,`left`],c=[`start`,`center`,`end`];function l(l,u={}){let d=(0,e.reuseRootBinding)(l,t,`[@data-slot/tooltip] createTooltip() called more than once for the same root. Returning the existing controller. Destroy it before rebinding with new options.`);if(d)return d;let f=(0,e.getPart)(l,`tooltip-trigger`),p=(0,e.getPart)(l,`tooltip-content`),m=(0,e.getPart)(l,`tooltip-positioner`),h=m&&p&&m.contains(p)?m:null,g=(0,e.getPart)(l,`tooltip-portal`),_=g&&h&&g.contains(h)?g:null;if(!f||!p)throw Error(`Tooltip requires trigger and content slots`);let v=u.delay??(0,e.getDataNumber)(l,`delay`)??300,y=u.skipDelayDuration??(0,e.getDataNumber)(l,`skipDelayDuration`)??300,b=u.onOpenChange,x=u.portal??(0,e.getDataBool)(p,`portal`)??(0,e.getDataBool)(l,`portal`)??!0,S=(t,n)=>(0,e.getDataEnum)(p,t,n)??(h?(0,e.getDataEnum)(h,t,n):void 0)??(0,e.getDataEnum)(l,t,n),C=t=>(0,e.getDataNumber)(p,t)??(h?(0,e.getDataNumber)(h,t):void 0)??(0,e.getDataNumber)(l,t),w=t=>(0,e.getDataBool)(p,t)??(h?(0,e.getDataBool)(h,t):void 0)??(0,e.getDataBool)(l,t),T=u.side??S(`side`,s)??`top`,E=u.align??S(`align`,c)??`center`,D=u.sideOffset??C(`sideOffset`)??4,O=u.alignOffset??C(`alignOffset`)??0,k=u.avoidCollisions??w(`avoidCollisions`)??!0,A=u.collisionPadding??C(`collisionPadding`)??8,j=!1,M=!1,N=!1,P=!1,F=null,I=[],L=(0,e.createPortalLifecycle)({content:p,root:l,enabled:x,wrapperSlot:h?void 0:`tooltip-positioner`,container:h??void 0,mountTarget:h?_??h:void 0}),R=(0,e.ensureId)(p,`tooltip-content`);p.setAttribute(`role`,`tooltip`),p.setAttribute(`data-side`,T),p.setAttribute(`data-align`,E);let z=e=>{let t=L.container;if(l.setAttribute(`data-state`,e),p.setAttribute(`data-state`,e),t!==p&&t.setAttribute(`data-state`,e),e===`open`){l.setAttribute(`data-open`,``),p.setAttribute(`data-open`,``),t!==p&&t.setAttribute(`data-open`,``),M?(l.setAttribute(`data-instant`,``),p.setAttribute(`data-instant`,``),t!==p&&t.setAttribute(`data-instant`,``)):(l.removeAttribute(`data-instant`),p.removeAttribute(`data-instant`),t!==p&&t.removeAttribute(`data-instant`)),l.removeAttribute(`data-closed`),p.removeAttribute(`data-closed`),t!==p&&t.removeAttribute(`data-closed`);return}l.setAttribute(`data-closed`,``),p.setAttribute(`data-closed`,``),t!==p&&t.setAttribute(`data-closed`,``),M?(l.setAttribute(`data-instant`,``),p.setAttribute(`data-instant`,``),t!==p&&t.setAttribute(`data-instant`,``)):(l.removeAttribute(`data-instant`),p.removeAttribute(`data-instant`),t!==p&&t.removeAttribute(`data-instant`)),l.removeAttribute(`data-open`),p.removeAttribute(`data-open`),t!==p&&t.removeAttribute(`data-open`)},B=()=>{let t=L.container,n=l.ownerDocument.defaultView??window,r=f.getBoundingClientRect(),i=(0,e.computeFloatingPosition)({anchorRect:r,contentRect:(0,e.measurePopupContentRect)(p),side:T,align:E,sideOffset:D,alignOffset:O,avoidCollisions:k,collisionPadding:A}),a=(0,e.computeFloatingTransformOrigin)({side:i.side,align:i.align,anchorRect:r,popupX:i.x,popupY:i.y});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.setProperty(`--transform-origin`,a),t.style.willChange=`transform`,t.style.margin=`0`,p.setAttribute(`data-side`,i.side),p.setAttribute(`data-align`,i.align),t!==p&&(t.setAttribute(`data-side`,i.side),t.setAttribute(`data-align`,i.align))},V=(0,e.createPresenceLifecycle)({element:p,onExitComplete:()=>{P||(L.restore(),p.hidden=!0)}}),H=(0,e.createPositionSync)({observedElements:[f,p],isActive:()=>j,ancestorScroll:!1,onUpdate:B}),U=()=>f.hasAttribute(`disabled`)||f.getAttribute(`aria-disabled`)===`true`,W=(t,r,i=!1)=>{j!==t&&(!t&&j&&y>0&&(n=Date.now()+y),M=i,j=t,j?(f.setAttribute(`aria-describedby`,R),p.setAttribute(`aria-hidden`,`false`),L.mount(),p.hidden=!1,z(`open`),V.enter(),B(),H.start(),H.update()):(z(`closed`),f.removeAttribute(`aria-describedby`),p.setAttribute(`aria-hidden`,`true`),V.exit(),H.stop()),(0,e.emit)(l,`tooltip:change`,{open:j,trigger:f,content:p,reason:r}),b?.(j))},G=e=>{if(F&&=(clearTimeout(F),null),Date.now()<n){W(!0,e,!0);return}F=setTimeout(()=>{W(!0,e),F=null},v)},K=(e,t=!1)=>{F&&=(clearTimeout(F),null),W(!1,e,t)},q=(e,t)=>{e===f||!j||(N=!1,K(t,!0))};r.add(f),i.add(q),I.push(()=>{i.delete(q),r.delete(f)}),p.hidden=!0,p.setAttribute(`aria-hidden`,`true`),z(`closed`),I.push((0,e.on)(f,`pointerenter`,e=>{e.pointerType!==`touch`&&(U()||(o(f,`pointer`),G(`pointer`)))}),(0,e.on)(f,`pointerleave`,e=>{if(e.pointerType===`touch`||N)return;let t=e.relatedTarget;if(!(t&&p.contains(t))){if(a(t,f)){K(`pointer`,!0);return}K(`pointer`)}}),(0,e.on)(f,`click`,()=>{if(!U()){if(F){clearTimeout(F),F=null;return}j&&K(`pointer`,!0)}}),(0,e.on)(f,`focus`,()=>{N=!0,!U()&&(o(f,`focus`),G(`focus`))}),(0,e.on)(f,`blur`,e=>{N=!1;let t=e.relatedTarget;if(a(t,f)){K(`blur`,!0);return}K(`blur`)})),I.push((0,e.on)(p,`pointerleave`,e=>{if(e.pointerType===`touch`||N)return;let t=e.relatedTarget;if(!(t&&f.contains(t))){if(a(t,f)){K(`pointer`,!0);return}K(`pointer`)}})),I.push((0,e.on)(l,`tooltip:set`,e=>{let t=e.detail,n;if(t?.open===void 0?t?.value!==void 0&&(n=t.value):n=t.open,typeof n==`boolean`)if(n){if(U())return;F&&=(clearTimeout(F),null),W(!0,`api`)}else K(`api`)})),I.push((0,e.createDismissLayer)({root:l,isOpen:()=>j,onDismiss:()=>K(`escape`),closeOnClickOutside:!1,closeOnEscape:!0,preventEscapeDefault:!1}));let J={show:()=>{U()||(F&&=(clearTimeout(F),null),W(!0,`api`))},hide:()=>K(`api`),get isOpen(){return j},destroy:()=>{P=!0,F&&clearTimeout(F),H.stop(),V.cleanup(),L.cleanup(),I.forEach(e=>e()),I.length=0,(0,e.clearRootBinding)(l,t,J)}};return(0,e.setRootBinding)(l,t,J),J}function u(n=document){let r=[];for(let i of(0,e.getRoots)(n,`tooltip`))(0,e.hasRootBinding)(i,t)||r.push(l(i));return r}exports.create=u,exports.createTooltip=l;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@data-slot/core`);const t=`@data-slot/tooltip`;let n=0;const r=new Set,i=new Set,a=(e,t)=>{if(!e)return!1;for(let n of r)if(n!==t&&n.contains(e))return!0;return!1},o=(e,t)=>{for(let n of i)n(e,t)},s=[`top`,`right`,`bottom`,`left`,`inline-start`,`inline-end`],c=[`start`,`center`,`end`],l=(e,t)=>e===`inline-start`?t===`rtl`?`right`:`left`:e===`inline-end`?t===`rtl`?`left`:`right`:e,u=(...e)=>[...new Set(e.filter(e=>e!=null))];function d(d,f={}){let p=(0,e.reuseRootBinding)(d,t,`[@data-slot/tooltip] createTooltip() called more than once for the same root. Returning the existing controller. Destroy it before rebinding with new options.`);if(p)return p;let m=(0,e.getPart)(d,`tooltip-trigger`),h=(0,e.getPart)(d,`tooltip-content`),g=h?.querySelector(`[data-slot="tooltip-arrow"]`)??null,_=(0,e.getPart)(d,`tooltip-positioner`),v=_&&h&&_.contains(h)?_:null,y=(0,e.getPart)(d,`tooltip-portal`),b=y&&v&&y.contains(v)?y:null;if(!m||!h)throw Error(`Tooltip requires trigger and content slots`);g&&(g.setAttribute(`aria-hidden`,`true`),g.style.position=`absolute`);let x=f.delay??(0,e.getDataNumber)(d,`delay`)??300,S=f.skipDelayDuration??(0,e.getDataNumber)(d,`skipDelayDuration`)??300,C=f.onOpenChange,w=f.portal??(0,e.getDataBool)(h,`portal`)??(0,e.getDataBool)(d,`portal`)??!0,T=(t,n)=>(0,e.getDataEnum)(h,t,n)??(v?(0,e.getDataEnum)(v,t,n):void 0)??(0,e.getDataEnum)(d,t,n),E=t=>(0,e.getDataNumber)(h,t)??(v?(0,e.getDataNumber)(v,t):void 0)??(0,e.getDataNumber)(d,t),D=t=>(0,e.getDataBool)(h,t)??(v?(0,e.getDataBool)(v,t):void 0)??(0,e.getDataBool)(d,t),O=f.side??T(`side`,s)??`top`,k=f.align??T(`align`,c)??`center`,ee=f.sideOffset??E(`sideOffset`)??4,A=f.alignOffset??E(`alignOffset`)??0,j=f.avoidCollisions??D(`avoidCollisions`)??!0,M=f.collisionPadding??E(`collisionPadding`)??8,N=!1,P=null,F=!1,I=!1,L=null,R=[],z=(0,e.createPortalLifecycle)({content:h,root:d,enabled:w,wrapperSlot:v?void 0:`tooltip-positioner`,container:v??void 0,mountTarget:v?b??v:void 0}),B=(0,e.ensureId)(h,`tooltip-content`);h.setAttribute(`role`,`tooltip`);let te=()=>{let e=d instanceof HTMLElement?d:null;return(e?.getAttribute(`dir`)??m.getAttribute(`dir`))===`rtl`||(getComputedStyle(m).direction||(e?getComputedStyle(e).direction:``)||d.ownerDocument.documentElement.getAttribute(`dir`)||``)===`rtl`?`rtl`:`ltr`},V=(e,t)=>{let n=z.container;for(let r of u(h,n,g))r.setAttribute(`data-side`,e),r.setAttribute(`data-align`,t)},H=e=>{let t=z.container;for(let n of u(d,h,t,g))e?n.setAttribute(`data-instant`,e):n.removeAttribute(`data-instant`)},U=(e,t,n,r)=>{if(!g)return;g.style.position=`absolute`;let i=g.getBoundingClientRect(),a=g.offsetWidth>0?g.offsetWidth:i.width,o=g.offsetHeight>0?g.offsetHeight:i.height;if(a<=0||o<=0){g.style.removeProperty(`left`),g.style.removeProperty(`top`),g.removeAttribute(`data-uncentered`);return}let s=l(e,t);if(s===`top`||s===`bottom`){let e=n.left+n.width/2-r.left-a/2,t=Math.max(5,r.width-a-5),i=Math.min(Math.max(e,5),t);g.style.left=`${i}px`,g.style.removeProperty(`top`),Math.abs(i-e)>.5?g.setAttribute(`data-uncentered`,``):g.removeAttribute(`data-uncentered`);return}let c=n.top+n.height/2-r.top-o/2,u=Math.max(5,r.height-o-5),d=Math.min(Math.max(c,5),u);g.style.top=`${d}px`,g.style.removeProperty(`left`),Math.abs(d-c)>.5?g.setAttribute(`data-uncentered`,``):g.removeAttribute(`data-uncentered`)},W=e=>{let t=z.container;if(d.setAttribute(`data-state`,e),h.setAttribute(`data-state`,e),H(P),e===`open`){for(let e of u(d,h,t,g))e.setAttribute(`data-open`,``),e.removeAttribute(`data-closed`);return}for(let e of u(d,h,t,g))e.setAttribute(`data-closed`,``),e.removeAttribute(`data-open`)},G=()=>{let t=z.container,n=d.ownerDocument.defaultView??window,r=te(),i=m.getBoundingClientRect(),a=(0,e.computeFloatingPosition)({anchorRect:i,contentRect:(0,e.measurePopupContentRect)(h),side:O,align:k,sideOffset:ee,alignOffset:A,avoidCollisions:j,collisionPadding:M,direction:r}),o=(0,e.computeFloatingTransformOrigin)({side:a.side,align:a.align,anchorRect:i,popupX:a.x,popupY:a.y,direction:r});t.style.position=`absolute`,t.style.top=`0px`,t.style.left=`0px`,t.style.transform=`translate3d(${a.x+n.scrollX}px, ${a.y+n.scrollY}px, 0)`,t.style.setProperty(`--transform-origin`,o),t.style.willChange=`transform`,t.style.margin=`0`,V(a.side,a.align),U(a.side,r,i,h.getBoundingClientRect())},K=(0,e.createPresenceLifecycle)({element:h,onExitComplete:()=>{I||(z.restore(),h.hidden=!0)}}),q=(0,e.createPositionSync)({observedElements:[m,h],isActive:()=>N,ancestorScroll:!1,onUpdate:G}),J=()=>m.hasAttribute(`disabled`)||m.getAttribute(`aria-disabled`)===`true`,Y=(t,r,i=null)=>{N!==t&&(!t&&N&&S>0&&(n=Date.now()+S),P=i,N=t,N?(m.setAttribute(`aria-describedby`,B),h.setAttribute(`aria-hidden`,`false`),z.mount(),h.hidden=!1,W(`open`),K.enter(),G(),q.start(),q.update()):(W(`closed`),m.removeAttribute(`aria-describedby`),h.setAttribute(`aria-hidden`,`true`),K.exit(),q.stop()),(0,e.emit)(d,`tooltip:change`,{open:N,trigger:m,content:h,reason:r}),C?.(N))},X=e=>{if(L&&=(clearTimeout(L),null),Date.now()<n){Y(!0,e,`delay`);return}L=setTimeout(()=>{Y(!0,e,e===`focus`?`focus`:null),L=null},x)},Z=(e,t=null)=>{L&&=(clearTimeout(L),null),Y(!1,e,t)},Q=(e,t)=>{e===m||!N||(F=!1,Z(t,`delay`))};r.add(m),i.add(Q),R.push(()=>{i.delete(Q),r.delete(m)}),h.hidden=!0,h.setAttribute(`aria-hidden`,`true`),V(O,k),W(`closed`),R.push((0,e.on)(m,`pointerenter`,e=>{e.pointerType!==`touch`&&(J()||(o(m,`pointer`),X(`pointer`)))}),(0,e.on)(m,`pointerleave`,e=>{if(e.pointerType===`touch`||F)return;let t=e.relatedTarget;if(!(t&&h.contains(t))){if(a(t,m)){Z(`pointer`,`delay`);return}Z(`pointer`)}}),(0,e.on)(m,`click`,()=>{if(!J()){if(L){clearTimeout(L),L=null;return}N&&Z(`pointer`,`dismiss`)}}),(0,e.on)(m,`focus`,()=>{F=!0,!J()&&(o(m,`focus`),X(`focus`))}),(0,e.on)(m,`blur`,e=>{F=!1;let t=e.relatedTarget;if(a(t,m)){Z(`blur`,`delay`);return}Z(`blur`)})),R.push((0,e.on)(h,`pointerleave`,e=>{if(e.pointerType===`touch`||F)return;let t=e.relatedTarget;if(!(t&&m.contains(t))){if(a(t,m)){Z(`pointer`,`delay`);return}Z(`pointer`)}})),R.push((0,e.on)(d,`tooltip:set`,e=>{let t=e.detail,n;if(t?.open===void 0?t?.value!==void 0&&(n=t.value):n=t.open,typeof n==`boolean`)if(n){if(J())return;L&&=(clearTimeout(L),null),Y(!0,`api`)}else Z(`api`)})),R.push((0,e.createDismissLayer)({root:d,isOpen:()=>N,onDismiss:()=>Z(`escape`,`dismiss`),closeOnClickOutside:!1,closeOnEscape:!0,preventEscapeDefault:!1}));let $={show:()=>{J()||(L&&=(clearTimeout(L),null),Y(!0,`api`))},hide:()=>Z(`api`),get isOpen(){return N},destroy:()=>{I=!0,L&&clearTimeout(L),q.stop(),K.cleanup(),z.cleanup(),R.forEach(e=>e()),R.length=0,(0,e.clearRootBinding)(d,t,$)}};return(0,e.setRootBinding)(d,t,$),$}function f(n=document){let r=[];for(let i of(0,e.getRoots)(n,`tooltip`))(0,e.hasRootBinding)(i,t)||r.push(d(i));return r}exports.create=f,exports.createTooltip=d;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/index.d.ts
2
- type TooltipSide = "top" | "right" | "bottom" | "left";
2
+ type TooltipSide = "top" | "right" | "bottom" | "left" | "inline-start" | "inline-end";
3
3
  type TooltipAlign = "start" | "center" | "end";
4
4
  type TooltipReason = "pointer" | "focus" | "blur" | "escape" | "api";
5
5
  interface TooltipOptions {
@@ -48,7 +48,7 @@ interface TooltipController {
48
48
  * ```
49
49
  *
50
50
  * Placement data attributes are resolved as: content -> authored positioner -> root.
51
- * - `data-side`: 'top' | 'right' | 'bottom' | 'left' (bind-time preferred side)
51
+ * - `data-side`: 'top' | 'right' | 'bottom' | 'left' | 'inline-start' | 'inline-end' (bind-time preferred side)
52
52
  * - `data-align`: 'start' | 'center' | 'end' (bind-time preferred align)
53
53
  * - `data-side-offset`: number (px)
54
54
  * - `data-align-offset`: number (px)
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/index.d.ts
2
- type TooltipSide = "top" | "right" | "bottom" | "left";
2
+ type TooltipSide = "top" | "right" | "bottom" | "left" | "inline-start" | "inline-end";
3
3
  type TooltipAlign = "start" | "center" | "end";
4
4
  type TooltipReason = "pointer" | "focus" | "blur" | "escape" | "api";
5
5
  interface TooltipOptions {
@@ -48,7 +48,7 @@ interface TooltipController {
48
48
  * ```
49
49
  *
50
50
  * Placement data attributes are resolved as: content -> authored positioner -> root.
51
- * - `data-side`: 'top' | 'right' | 'bottom' | 'left' (bind-time preferred side)
51
+ * - `data-side`: 'top' | 'right' | 'bottom' | 'left' | 'inline-start' | 'inline-end' (bind-time preferred side)
52
52
  * - `data-align`: 'start' | 'center' | 'end' (bind-time preferred align)
53
53
  * - `data-side-offset`: number (px)
54
54
  * - `data-align-offset`: number (px)
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{clearRootBinding as e,computeFloatingPosition as t,computeFloatingTransformOrigin as n,createDismissLayer as r,createPortalLifecycle as i,createPositionSync as a,createPresenceLifecycle as o,emit as s,ensureId as ee,getDataBool as c,getDataEnum as l,getDataNumber as u,getPart as d,getRoots as f,hasRootBinding as p,measurePopupContentRect as m,on as h,reuseRootBinding as te,setRootBinding as g}from"@data-slot/core";const _=`@data-slot/tooltip`;let v=0;const y=new Set,b=new Set,x=(e,t)=>{if(!e)return!1;for(let n of y)if(n!==t&&n.contains(e))return!0;return!1},S=(e,t)=>{for(let n of b)n(e,t)},ne=[`top`,`right`,`bottom`,`left`],C=[`start`,`center`,`end`];function w(f,p={}){let w=te(f,_,`[@data-slot/tooltip] createTooltip() called more than once for the same root. Returning the existing controller. Destroy it before rebinding with new options.`);if(w)return w;let T=d(f,`tooltip-trigger`),E=d(f,`tooltip-content`),D=d(f,`tooltip-positioner`),O=D&&E&&D.contains(E)?D:null,k=d(f,`tooltip-portal`),re=k&&O&&k.contains(O)?k:null;if(!T||!E)throw Error(`Tooltip requires trigger and content slots`);let ie=p.delay??u(f,`delay`)??300,A=p.skipDelayDuration??u(f,`skipDelayDuration`)??300,ae=p.onOpenChange,j=p.portal??c(E,`portal`)??c(f,`portal`)??!0,M=(e,t)=>l(E,e,t)??(O?l(O,e,t):void 0)??l(f,e,t),N=e=>u(E,e)??(O?u(O,e):void 0)??u(f,e),oe=e=>c(E,e)??(O?c(O,e):void 0)??c(f,e),P=p.side??M(`side`,ne)??`top`,F=p.align??M(`align`,C)??`center`,se=p.sideOffset??N(`sideOffset`)??4,ce=p.alignOffset??N(`alignOffset`)??0,I=p.avoidCollisions??oe(`avoidCollisions`)??!0,le=p.collisionPadding??N(`collisionPadding`)??8,L=!1,R=!1,z=!1,B=!1,V=null,H=[],U=i({content:E,root:f,enabled:j,wrapperSlot:O?void 0:`tooltip-positioner`,container:O??void 0,mountTarget:O?re??O:void 0}),ue=ee(E,`tooltip-content`);E.setAttribute(`role`,`tooltip`),E.setAttribute(`data-side`,P),E.setAttribute(`data-align`,F);let W=e=>{let t=U.container;if(f.setAttribute(`data-state`,e),E.setAttribute(`data-state`,e),t!==E&&t.setAttribute(`data-state`,e),e===`open`){f.setAttribute(`data-open`,``),E.setAttribute(`data-open`,``),t!==E&&t.setAttribute(`data-open`,``),R?(f.setAttribute(`data-instant`,``),E.setAttribute(`data-instant`,``),t!==E&&t.setAttribute(`data-instant`,``)):(f.removeAttribute(`data-instant`),E.removeAttribute(`data-instant`),t!==E&&t.removeAttribute(`data-instant`)),f.removeAttribute(`data-closed`),E.removeAttribute(`data-closed`),t!==E&&t.removeAttribute(`data-closed`);return}f.setAttribute(`data-closed`,``),E.setAttribute(`data-closed`,``),t!==E&&t.setAttribute(`data-closed`,``),R?(f.setAttribute(`data-instant`,``),E.setAttribute(`data-instant`,``),t!==E&&t.setAttribute(`data-instant`,``)):(f.removeAttribute(`data-instant`),E.removeAttribute(`data-instant`),t!==E&&t.removeAttribute(`data-instant`)),f.removeAttribute(`data-open`),E.removeAttribute(`data-open`),t!==E&&t.removeAttribute(`data-open`)},G=()=>{let e=U.container,r=f.ownerDocument.defaultView??window,i=T.getBoundingClientRect(),a=t({anchorRect:i,contentRect:m(E),side:P,align:F,sideOffset:se,alignOffset:ce,avoidCollisions:I,collisionPadding:le}),o=n({side:a.side,align:a.align,anchorRect:i,popupX:a.x,popupY:a.y});e.style.position=`absolute`,e.style.top=`0px`,e.style.left=`0px`,e.style.transform=`translate3d(${a.x+r.scrollX}px, ${a.y+r.scrollY}px, 0)`,e.style.setProperty(`--transform-origin`,o),e.style.willChange=`transform`,e.style.margin=`0`,E.setAttribute(`data-side`,a.side),E.setAttribute(`data-align`,a.align),e!==E&&(e.setAttribute(`data-side`,a.side),e.setAttribute(`data-align`,a.align))},K=o({element:E,onExitComplete:()=>{B||(U.restore(),E.hidden=!0)}}),q=a({observedElements:[T,E],isActive:()=>L,ancestorScroll:!1,onUpdate:G}),J=()=>T.hasAttribute(`disabled`)||T.getAttribute(`aria-disabled`)===`true`,Y=(e,t,n=!1)=>{L!==e&&(!e&&L&&A>0&&(v=Date.now()+A),R=n,L=e,L?(T.setAttribute(`aria-describedby`,ue),E.setAttribute(`aria-hidden`,`false`),U.mount(),E.hidden=!1,W(`open`),K.enter(),G(),q.start(),q.update()):(W(`closed`),T.removeAttribute(`aria-describedby`),E.setAttribute(`aria-hidden`,`true`),K.exit(),q.stop()),s(f,`tooltip:change`,{open:L,trigger:T,content:E,reason:t}),ae?.(L))},X=e=>{if(V&&=(clearTimeout(V),null),Date.now()<v){Y(!0,e,!0);return}V=setTimeout(()=>{Y(!0,e),V=null},ie)},Z=(e,t=!1)=>{V&&=(clearTimeout(V),null),Y(!1,e,t)},Q=(e,t)=>{e===T||!L||(z=!1,Z(t,!0))};y.add(T),b.add(Q),H.push(()=>{b.delete(Q),y.delete(T)}),E.hidden=!0,E.setAttribute(`aria-hidden`,`true`),W(`closed`),H.push(h(T,`pointerenter`,e=>{e.pointerType!==`touch`&&(J()||(S(T,`pointer`),X(`pointer`)))}),h(T,`pointerleave`,e=>{if(e.pointerType===`touch`||z)return;let t=e.relatedTarget;if(!(t&&E.contains(t))){if(x(t,T)){Z(`pointer`,!0);return}Z(`pointer`)}}),h(T,`click`,()=>{if(!J()){if(V){clearTimeout(V),V=null;return}L&&Z(`pointer`,!0)}}),h(T,`focus`,()=>{z=!0,!J()&&(S(T,`focus`),X(`focus`))}),h(T,`blur`,e=>{z=!1;let t=e.relatedTarget;if(x(t,T)){Z(`blur`,!0);return}Z(`blur`)})),H.push(h(E,`pointerleave`,e=>{if(e.pointerType===`touch`||z)return;let t=e.relatedTarget;if(!(t&&T.contains(t))){if(x(t,T)){Z(`pointer`,!0);return}Z(`pointer`)}})),H.push(h(f,`tooltip:set`,e=>{let t=e.detail,n;if(t?.open===void 0?t?.value!==void 0&&(n=t.value):n=t.open,typeof n==`boolean`)if(n){if(J())return;V&&=(clearTimeout(V),null),Y(!0,`api`)}else Z(`api`)})),H.push(r({root:f,isOpen:()=>L,onDismiss:()=>Z(`escape`),closeOnClickOutside:!1,closeOnEscape:!0,preventEscapeDefault:!1}));let $={show:()=>{J()||(V&&=(clearTimeout(V),null),Y(!0,`api`))},hide:()=>Z(`api`),get isOpen(){return L},destroy:()=>{B=!0,V&&clearTimeout(V),q.stop(),K.cleanup(),U.cleanup(),H.forEach(e=>e()),H.length=0,e(f,_,$)}};return g(f,_,$),$}function T(e=document){let t=[];for(let n of f(e,`tooltip`))p(n,_)||t.push(w(n));return t}export{T as create,w as createTooltip};
1
+ import{clearRootBinding as e,computeFloatingPosition as t,computeFloatingTransformOrigin as n,createDismissLayer as r,createPortalLifecycle as i,createPositionSync as a,createPresenceLifecycle as o,emit as s,ensureId as c,getDataBool as l,getDataEnum as u,getDataNumber as d,getPart as f,getRoots as p,hasRootBinding as m,measurePopupContentRect as ee,on as h,reuseRootBinding as te,setRootBinding as ne}from"@data-slot/core";const g=`@data-slot/tooltip`;let _=0;const v=new Set,y=new Set,b=(e,t)=>{if(!e)return!1;for(let n of v)if(n!==t&&n.contains(e))return!0;return!1},x=(e,t)=>{for(let n of y)n(e,t)},re=[`top`,`right`,`bottom`,`left`,`inline-start`,`inline-end`],ie=[`start`,`center`,`end`],ae=(e,t)=>e===`inline-start`?t===`rtl`?`right`:`left`:e===`inline-end`?t===`rtl`?`left`:`right`:e,S=(...e)=>[...new Set(e.filter(e=>e!=null))];function C(p,m={}){let C=te(p,g,`[@data-slot/tooltip] createTooltip() called more than once for the same root. Returning the existing controller. Destroy it before rebinding with new options.`);if(C)return C;let w=f(p,`tooltip-trigger`),T=f(p,`tooltip-content`),E=T?.querySelector(`[data-slot="tooltip-arrow"]`)??null,D=f(p,`tooltip-positioner`),O=D&&T&&D.contains(T)?D:null,k=f(p,`tooltip-portal`),oe=k&&O&&k.contains(O)?k:null;if(!w||!T)throw Error(`Tooltip requires trigger and content slots`);E&&(E.setAttribute(`aria-hidden`,`true`),E.style.position=`absolute`);let se=m.delay??d(p,`delay`)??300,A=m.skipDelayDuration??d(p,`skipDelayDuration`)??300,ce=m.onOpenChange,le=m.portal??l(T,`portal`)??l(p,`portal`)??!0,j=(e,t)=>u(T,e,t)??(O?u(O,e,t):void 0)??u(p,e,t),M=e=>d(T,e)??(O?d(O,e):void 0)??d(p,e),N=e=>l(T,e)??(O?l(O,e):void 0)??l(p,e),P=m.side??j(`side`,re)??`top`,F=m.align??j(`align`,ie)??`center`,ue=m.sideOffset??M(`sideOffset`)??4,de=m.alignOffset??M(`alignOffset`)??0,fe=m.avoidCollisions??N(`avoidCollisions`)??!0,pe=m.collisionPadding??M(`collisionPadding`)??8,I=!1,L=null,R=!1,z=!1,B=null,V=[],H=i({content:T,root:p,enabled:le,wrapperSlot:O?void 0:`tooltip-positioner`,container:O??void 0,mountTarget:O?oe??O:void 0}),me=c(T,`tooltip-content`);T.setAttribute(`role`,`tooltip`);let he=()=>{let e=p instanceof HTMLElement?p:null;return(e?.getAttribute(`dir`)??w.getAttribute(`dir`))===`rtl`||(getComputedStyle(w).direction||(e?getComputedStyle(e).direction:``)||p.ownerDocument.documentElement.getAttribute(`dir`)||``)===`rtl`?`rtl`:`ltr`},U=(e,t)=>{let n=H.container;for(let r of S(T,n,E))r.setAttribute(`data-side`,e),r.setAttribute(`data-align`,t)},ge=e=>{let t=H.container;for(let n of S(p,T,t,E))e?n.setAttribute(`data-instant`,e):n.removeAttribute(`data-instant`)},_e=(e,t,n,r)=>{if(!E)return;E.style.position=`absolute`;let i=E.getBoundingClientRect(),a=E.offsetWidth>0?E.offsetWidth:i.width,o=E.offsetHeight>0?E.offsetHeight:i.height;if(a<=0||o<=0){E.style.removeProperty(`left`),E.style.removeProperty(`top`),E.removeAttribute(`data-uncentered`);return}let s=ae(e,t);if(s===`top`||s===`bottom`){let e=n.left+n.width/2-r.left-a/2,t=Math.max(5,r.width-a-5),i=Math.min(Math.max(e,5),t);E.style.left=`${i}px`,E.style.removeProperty(`top`),Math.abs(i-e)>.5?E.setAttribute(`data-uncentered`,``):E.removeAttribute(`data-uncentered`);return}let c=n.top+n.height/2-r.top-o/2,l=Math.max(5,r.height-o-5),u=Math.min(Math.max(c,5),l);E.style.top=`${u}px`,E.style.removeProperty(`left`),Math.abs(u-c)>.5?E.setAttribute(`data-uncentered`,``):E.removeAttribute(`data-uncentered`)},W=e=>{let t=H.container;if(p.setAttribute(`data-state`,e),T.setAttribute(`data-state`,e),ge(L),e===`open`){for(let e of S(p,T,t,E))e.setAttribute(`data-open`,``),e.removeAttribute(`data-closed`);return}for(let e of S(p,T,t,E))e.setAttribute(`data-closed`,``),e.removeAttribute(`data-open`)},G=()=>{let e=H.container,r=p.ownerDocument.defaultView??window,i=he(),a=w.getBoundingClientRect(),o=t({anchorRect:a,contentRect:ee(T),side:P,align:F,sideOffset:ue,alignOffset:de,avoidCollisions:fe,collisionPadding:pe,direction:i}),s=n({side:o.side,align:o.align,anchorRect:a,popupX:o.x,popupY:o.y,direction:i});e.style.position=`absolute`,e.style.top=`0px`,e.style.left=`0px`,e.style.transform=`translate3d(${o.x+r.scrollX}px, ${o.y+r.scrollY}px, 0)`,e.style.setProperty(`--transform-origin`,s),e.style.willChange=`transform`,e.style.margin=`0`,U(o.side,o.align),_e(o.side,i,a,T.getBoundingClientRect())},K=o({element:T,onExitComplete:()=>{z||(H.restore(),T.hidden=!0)}}),q=a({observedElements:[w,T],isActive:()=>I,ancestorScroll:!1,onUpdate:G}),J=()=>w.hasAttribute(`disabled`)||w.getAttribute(`aria-disabled`)===`true`,Y=(e,t,n=null)=>{I!==e&&(!e&&I&&A>0&&(_=Date.now()+A),L=n,I=e,I?(w.setAttribute(`aria-describedby`,me),T.setAttribute(`aria-hidden`,`false`),H.mount(),T.hidden=!1,W(`open`),K.enter(),G(),q.start(),q.update()):(W(`closed`),w.removeAttribute(`aria-describedby`),T.setAttribute(`aria-hidden`,`true`),K.exit(),q.stop()),s(p,`tooltip:change`,{open:I,trigger:w,content:T,reason:t}),ce?.(I))},X=e=>{if(B&&=(clearTimeout(B),null),Date.now()<_){Y(!0,e,`delay`);return}B=setTimeout(()=>{Y(!0,e,e===`focus`?`focus`:null),B=null},se)},Z=(e,t=null)=>{B&&=(clearTimeout(B),null),Y(!1,e,t)},Q=(e,t)=>{e===w||!I||(R=!1,Z(t,`delay`))};v.add(w),y.add(Q),V.push(()=>{y.delete(Q),v.delete(w)}),T.hidden=!0,T.setAttribute(`aria-hidden`,`true`),U(P,F),W(`closed`),V.push(h(w,`pointerenter`,e=>{e.pointerType!==`touch`&&(J()||(x(w,`pointer`),X(`pointer`)))}),h(w,`pointerleave`,e=>{if(e.pointerType===`touch`||R)return;let t=e.relatedTarget;if(!(t&&T.contains(t))){if(b(t,w)){Z(`pointer`,`delay`);return}Z(`pointer`)}}),h(w,`click`,()=>{if(!J()){if(B){clearTimeout(B),B=null;return}I&&Z(`pointer`,`dismiss`)}}),h(w,`focus`,()=>{R=!0,!J()&&(x(w,`focus`),X(`focus`))}),h(w,`blur`,e=>{R=!1;let t=e.relatedTarget;if(b(t,w)){Z(`blur`,`delay`);return}Z(`blur`)})),V.push(h(T,`pointerleave`,e=>{if(e.pointerType===`touch`||R)return;let t=e.relatedTarget;if(!(t&&w.contains(t))){if(b(t,w)){Z(`pointer`,`delay`);return}Z(`pointer`)}})),V.push(h(p,`tooltip:set`,e=>{let t=e.detail,n;if(t?.open===void 0?t?.value!==void 0&&(n=t.value):n=t.open,typeof n==`boolean`)if(n){if(J())return;B&&=(clearTimeout(B),null),Y(!0,`api`)}else Z(`api`)})),V.push(r({root:p,isOpen:()=>I,onDismiss:()=>Z(`escape`,`dismiss`),closeOnClickOutside:!1,closeOnEscape:!0,preventEscapeDefault:!1}));let $={show:()=>{J()||(B&&=(clearTimeout(B),null),Y(!0,`api`))},hide:()=>Z(`api`),get isOpen(){return I},destroy:()=>{z=!0,B&&clearTimeout(B),q.stop(),K.cleanup(),H.cleanup(),V.forEach(e=>e()),V.length=0,e(p,g,$)}};return ne(p,g,$),$}function w(e=document){let t=[];for(let n of p(e,`tooltip`))m(n,g)||t.push(C(n));return t}export{w as create,C as createTooltip};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-slot/tooltip",
3
- "version": "0.2.140",
3
+ "version": "0.2.142",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.cjs",
@@ -34,6 +34,6 @@
34
34
  ],
35
35
  "license": "MIT",
36
36
  "dependencies": {
37
- "@data-slot/core": "0.2.140"
37
+ "@data-slot/core": "0.2.142"
38
38
  }
39
39
  }