@data-slot/navigation-menu 0.2.57 → 0.2.59

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
@@ -72,6 +72,10 @@ const menu = createNavigationMenu(element, {
72
72
  | `delayOpen` | `number` | `200` | Delay before opening on hover (ms) |
73
73
  | `delayClose` | `number` | `150` | Delay before closing on mouse leave (ms) |
74
74
  | `openOnFocus` | `boolean` | `true` | Whether focusing a trigger opens its content |
75
+ | `side` | `"top" \| "right" \| "bottom" \| "left"` | `"bottom"` | Viewport side relative to trigger |
76
+ | `align` | `"start" \| "center" \| "end"` | `"start"` | Viewport alignment on cross-axis |
77
+ | `sideOffset` | `number` | `0` | Distance from trigger to viewport (px) |
78
+ | `alignOffset` | `number` | `0` | Cross-axis alignment offset (px) |
75
79
  | `onValueChange` | `(value: string \| null) => void` | `undefined` | Callback when active item changes |
76
80
 
77
81
  ### Data Attributes
@@ -83,19 +87,26 @@ Options can also be set via data attributes on the root element. JS options take
83
87
  | `data-delay-open` | number | `200` | Delay before opening on hover (ms) |
84
88
  | `data-delay-close` | number | `150` | Delay before closing on mouse leave (ms) |
85
89
  | `data-open-on-focus` | boolean | `true` | Whether focusing a trigger opens its content |
90
+ | `data-side` | string | `"bottom"` | Side: `"top"`, `"right"`, `"bottom"`, `"left"` |
86
91
  | `data-align` | string | `"start"` | Viewport alignment: `"start"`, `"center"`, or `"end"` |
92
+ | `data-side-offset` | number | `0` | Distance from trigger to viewport (px) |
93
+ | `data-align-offset` | number | `0` | Cross-axis alignment offset (px) |
87
94
 
88
95
  Boolean attributes: present or `"true"` = true, `"false"` = false, absent = default.
89
96
 
90
- The `data-align` attribute controls how the viewport is positioned relative to the active trigger:
97
+ Placement attributes (`data-side`, `data-align`, `data-side-offset`, `data-align-offset`) control
98
+ how the viewport is positioned relative to the active trigger:
91
99
  - `start` - Align viewport left edge with trigger left edge (default)
92
100
  - `center` - Center viewport under trigger
93
101
  - `end` - Align viewport right edge with trigger right edge
94
102
 
95
103
  Can be set on:
96
- 1. `navigation-menu-content` (highest priority)
104
+ 1. `navigation-menu-content` (highest priority, per-panel)
97
105
  2. `navigation-menu-item`
98
- 3. `navigation-menu` root (lowest priority, applies to all items)
106
+ 3. `navigation-menu` root (lowest priority, global default)
107
+
108
+ `navigation-menu-viewport-positioner` / `navigation-menu-positioner` are styling containers.
109
+ Their `data-side` / `data-align` are mirrored output values and are not used as placement inputs.
99
110
 
100
111
  ```html
101
112
  <!-- Faster hover response, no auto-open on focus -->
@@ -145,17 +156,18 @@ Can be set on:
145
156
 
146
157
  - `navigation-menu-indicator` - Animated highlight that follows the hovered trigger
147
158
  - `navigation-menu-viewport` - Container for content with size transitions
148
- - `navigation-menu-positioner` - Positioning wrapper for active content (generated if not authored)
149
159
  - `navigation-menu-viewport-positioner` - Positioning wrapper for viewport (generated if not authored)
150
160
  - `navigation-menu-portal` - Optional authored portal wrapper that can contain positioners
151
161
 
152
162
  ## Styling
153
163
 
154
- Active `navigation-menu-content` and `navigation-menu-viewport` are portaled to `document.body`
155
- while open. If authored `navigation-menu-portal` / positioner slots are present, they are reused.
156
- Otherwise, `navigation-menu-positioner` and `navigation-menu-viewport-positioner` wrappers are
157
- generated and positioned at the navigation root so submenu layers are not clipped by local
158
- stacking contexts.
164
+ `navigation-menu-viewport` is portaled to `document.body` while open. If authored
165
+ `navigation-menu-portal` / `navigation-menu-viewport-positioner` slots are present, they are
166
+ reused. Otherwise, a `navigation-menu-viewport-positioner` wrapper is generated and positioned
167
+ at the navigation root so submenu layers are not clipped by local stacking contexts.
168
+
169
+ The active `navigation-menu-content` panel is mounted inside `navigation-menu-viewport` while open
170
+ and restored to its original markup location when inactive/closed.
159
171
 
160
172
  ### Basic Styling
161
173
 
@@ -171,10 +183,11 @@ stacking contexts.
171
183
 
172
184
  /* Viewport sizing and positioning */
173
185
  [data-slot="navigation-menu-viewport"] {
186
+ top: var(--viewport-top, 100%);
174
187
  left: var(--viewport-left, 0);
175
188
  width: var(--viewport-width);
176
189
  height: var(--viewport-height);
177
- transition: left 0.3s, width 0.3s, height 0.3s;
190
+ transition: top 0.3s, left 0.3s, width 0.3s, height 0.3s;
178
191
  }
179
192
 
180
193
  /* Skip animation on initial open */
@@ -193,7 +206,9 @@ stacking contexts.
193
206
 
194
207
  ### Motion Animations
195
208
 
196
- Content panels receive `data-motion` attributes for enter/exit animations:
209
+ Content panels receive `data-motion` attributes for directional enter/exit animations.
210
+ Both content and viewport also receive `data-starting-style` / `data-ending-style` markers from
211
+ presence lifecycle hooks, so you can style smooth fade/scale transitions before unmount.
197
212
 
198
213
  ```css
199
214
  /* Entering from right */
@@ -206,6 +221,12 @@ Content panels receive `data-motion` attributes for enter/exit animations:
206
221
  animation: slideToLeft 0.2s;
207
222
  }
208
223
 
224
+ /* Presence lifecycle helpers */
225
+ [data-slot="navigation-menu-content"][data-ending-style],
226
+ [data-slot="navigation-menu-viewport"][data-ending-style] {
227
+ opacity: 0;
228
+ }
229
+
209
230
  @keyframes slideFromRight {
210
231
  from { transform: translateX(100%); opacity: 0; }
211
232
  to { transform: translateX(0); opacity: 1; }
@@ -221,6 +242,7 @@ Content panels receive `data-motion` attributes for enter/exit animations:
221
242
 
222
243
  | Variable | Element | Description |
223
244
  |----------|---------|-------------|
245
+ | `--viewport-top` | viewport | Top offset based on side/sideOffset |
224
246
  | `--viewport-left` | viewport | Left offset based on alignment |
225
247
  | `--viewport-width` | viewport | Width of active content |
226
248
  | `--viewport-height` | viewport | Height of active content |
@@ -1,6 +1,8 @@
1
1
  //#region src/index.d.ts
2
2
  /** Alignment of the viewport relative to the trigger */
3
3
  type Align = "start" | "center" | "end";
4
+ declare const SIDES: readonly ["top", "right", "bottom", "left"];
5
+ type Side = (typeof SIDES)[number];
4
6
  interface NavigationMenuOptions {
5
7
  /** Delay before opening on hover (ms) */
6
8
  delayOpen?: number;
@@ -8,6 +10,14 @@ interface NavigationMenuOptions {
8
10
  delayClose?: number;
9
11
  /** Whether focusing a trigger opens its content (default: true) */
10
12
  openOnFocus?: boolean;
13
+ /** Preferred side of viewport relative to trigger */
14
+ side?: Side;
15
+ /** Alignment of viewport relative to trigger */
16
+ align?: Align;
17
+ /** Distance from trigger to viewport (px) */
18
+ sideOffset?: number;
19
+ /** Offset along alignment axis (px) */
20
+ alignOffset?: number;
11
21
  /** Callback when active item changes */
12
22
  onValueChange?: (value: string | null) => void;
13
23
  }
@@ -1,6 +1,8 @@
1
1
  //#region src/index.d.ts
2
2
  /** Alignment of the viewport relative to the trigger */
3
3
  type Align = "start" | "center" | "end";
4
+ declare const SIDES: readonly ["top", "right", "bottom", "left"];
5
+ type Side = (typeof SIDES)[number];
4
6
  interface NavigationMenuOptions {
5
7
  /** Delay before opening on hover (ms) */
6
8
  delayOpen?: number;
@@ -8,6 +10,14 @@ interface NavigationMenuOptions {
8
10
  delayClose?: number;
9
11
  /** Whether focusing a trigger opens its content (default: true) */
10
12
  openOnFocus?: boolean;
13
+ /** Preferred side of viewport relative to trigger */
14
+ side?: Side;
15
+ /** Alignment of viewport relative to trigger */
16
+ align?: Align;
17
+ /** Distance from trigger to viewport (px) */
18
+ sideOffset?: number;
19
+ /** Offset along alignment axis (px) */
20
+ alignOffset?: number;
11
21
  /** Callback when active item changes */
12
22
  onValueChange?: (value: string | null) => void;
13
23
  }
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@data-slot/core`);const t=[`start`,`center`,`end`];function n(n,r={}){let i=r.delayOpen??(0,e.getDataNumber)(n,`delayOpen`)??200,a=r.delayClose??(0,e.getDataNumber)(n,`delayClose`)??150,o=r.openOnFocus??(0,e.getDataBool)(n,`openOnFocus`)??!0,s=r.onValueChange,c=e=>e.replace(/[^a-z0-9\-_:.]/gi,`-`),l=(e,t)=>{`inert`in e&&(e.inert=t)},u=(0,e.getPart)(n,`navigation-menu-list`),d=(0,e.getParts)(n,`navigation-menu-item`),f=(0,e.getPart)(n,`navigation-menu-viewport`),p=(0,e.getPart)(n,`navigation-menu-indicator`),m=(e,t)=>{let r=e.parentElement;for(;r&&r!==n;){if(r.getAttribute(`data-slot`)===t)return r;r=r.parentElement}return null};if(!u||d.length===0)throw Error(`NavigationMenu requires navigation-menu-list and at least one navigation-menu-item`);let h=null,g=null,_=-1,v=null,y=null,b=null,x=!1,S=!1,C=!1,w=!1,T=[],E=new Map,D=new Map,O=new Set,k=f?m(f,`navigation-menu-viewport-positioner`):null,A=k?m(k,`navigation-menu-portal`):null,j=f?(0,e.createPortalLifecycle)({content:f,root:n,enabled:!0,wrapperSlot:k?void 0:`navigation-menu-viewport-positioner`,container:k??void 0,mountTarget:k?A??k:void 0}):null,M=f?(0,e.createPresenceLifecycle)({element:f,onExitComplete:()=>{w||(j?.restore(),f.hidden=!0,f.style.pointerEvents=`none`)}}):null,N=e=>{let t=E.get(e);if(!t)return;let r=t.container,i=n.ownerDocument.defaultView??window,a=n.getBoundingClientRect();r.style.position=`absolute`,r.style.top=`0px`,r.style.left=`0px`,r.style.transform=`translate3d(${a.left+i.scrollX}px, ${a.top+i.scrollY}px, 0)`,r.style.width=`${a.width}px`,r.style.height=`${a.height}px`,r.style.margin=`0`,r.style.willChange=`transform`,r.style.pointerEvents=`none`},P=()=>{if(!f||!j)return;let e=j.container,t=n.ownerDocument.defaultView??window,r=n.getBoundingClientRect();e.style.position=`absolute`,e.style.top=`0px`,e.style.left=`0px`,e.style.transform=`translate3d(${r.left+t.scrollX}px, ${r.top+t.scrollY}px, 0)`,e.style.width=`${r.width}px`,e.style.height=`${r.height}px`,e.style.margin=`0`,e.style.willChange=`transform`,e.style.pointerEvents=`none`},F=null,I=e=>{F?.disconnect(),F=null,!(!f||!e)&&(F=new ResizeObserver(()=>G(e.content,e.trigger,e.align)),F.observe(e.content))};T.push(()=>F?.disconnect()),T.push(()=>{D.forEach(e=>e.cleanup()),D.clear(),M?.cleanup(),E.forEach(e=>e.cleanup()),E.clear(),j?.cleanup()});let L=new Map,R=0;d.forEach(r=>{let i=r.dataset.value;if(!i)return;let a=(0,e.getPart)(r,`navigation-menu-trigger`),o=(0,e.getPart)(r,`navigation-menu-content`);if(a&&o){let s=(0,e.getDataEnum)(o,`align`,t)??(0,e.getDataEnum)(r,`align`,t)??(0,e.getDataEnum)(n,`align`,t)??`start`;L.set(i,{item:r,trigger:a,content:o,index:R++,align:s});let l=m(o,`navigation-menu-positioner`);l&&O.has(l)&&(l=null),l&&O.add(l);let u=l?m(l,`navigation-menu-portal`):null;E.set(o,(0,e.createPortalLifecycle)({content:o,root:n,enabled:!0,wrapperSlot:l?void 0:`navigation-menu-positioner`,container:l??void 0,mountTarget:l?u??l:void 0})),D.set(o,(0,e.createPresenceLifecycle)({element:o,onExitComplete:()=>{w||(E.get(o)?.restore(),o.hidden=!0,o.style.pointerEvents=`none`)}}));let d=c(i),f=(0,e.ensureId)(a,`nav-menu-trigger-${d}`),p=(0,e.ensureId)(o,`nav-menu-content-${d}`);a.setAttribute(`aria-haspopup`,`true`),a.setAttribute(`aria-controls`,p),o.setAttribute(`aria-labelledby`,f)}});let z=Array.from(L.values()).map(e=>e.trigger),B=new Map;for(let[e,t]of L)B.set(t.trigger,e);let V=e=>Array.from(e.querySelectorAll(`a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])`)).filter(e=>!e.hidden&&!e.closest(`[hidden]`)),H=()=>{v&&=(clearTimeout(v),null),y&&=(clearTimeout(y),null)},U=null,W=()=>(U||(U=document.createElement(`div`),U.setAttribute(`data-slot`,`navigation-menu-bridge`),U.style.cssText=`position: absolute; left: 0; right: 0; top: 0; pointer-events: auto; z-index: -1;`,f&&f.insertBefore(U,f.firstChild),T.push((0,e.on)(U,`pointerenter`,()=>{H()}))),U),G=(e,t,r)=>{f&&requestAnimationFrame(()=>{let i=e.firstElementChild,a=i?.getBoundingClientRect(),o=i?getComputedStyle(i):null,s=o&&parseFloat(o.marginTop)||0,c=o&&parseFloat(o.marginBottom)||0,l=a??e.getBoundingClientRect(),u=l.height+s+c,d=getComputedStyle(f),p=parseFloat(d.marginTop)||0,m=e.getBoundingClientRect();f.style.setProperty(`--viewport-width`,`${m.width}px`),f.style.setProperty(`--viewport-height`,`${u}px`);let h=n.getBoundingClientRect(),g=t.getBoundingClientRect(),_;_=r===`center`?g.left-h.left+g.width/2-l.width/2:r===`end`?g.right-h.left-l.width:g.left-h.left,f.style.setProperty(`--viewport-left`,`${_}px`),f.style.left=`${_}px`,e.style.left=`${_}px`,N(e),P();let v=s+p;if(v>0){let e=W();e.style.height=`${v}px`,e.style.transform=`translateY(-${v}px)`}else U&&(U.style.height=`0`)})},K=e=>_===-1||e>_?`right`:`left`,q=e=>{if(!p)return;if(b=e,!e){p.setAttribute(`data-state`,`hidden`);return}let t=u.getBoundingClientRect(),n=e.getBoundingClientRect();p.style.setProperty(`--indicator-left`,`${n.left-t.left}px`),p.style.setProperty(`--indicator-width`,`${n.width}px`),p.style.setProperty(`--indicator-top`,`${n.top-t.top}px`);let r=(f&&parseFloat(getComputedStyle(f).marginTop)||0)<1?1:0;p.style.setProperty(`--indicator-height`,`${n.height-r}px`),p.setAttribute(`data-state`,`visible`)},J=(t,r=!1)=>{if(t===h){H();return}if(t!==null&&t===g){H();return}H(),g=t===null?null:t;let o=()=>{let r=h,i=t?L.get(t):null,a=r!==null&&t!==null&&r!==t,o=a&&i?K(i.index):null,c=document.activeElement;if(t===null&&c&&(0,e.containsWithPortals)(n,c)){let e=r?L.get(r)?.trigger:null;e&&e.focus()}if(L.forEach(({trigger:n,content:i,item:a},s)=>{let c=s===t,u=s===r;if((0,e.setAria)(n,`expanded`,c),n.setAttribute(`data-state`,c?`open`:`closed`),c||u&&t===null?n.tabIndex=0:n.tabIndex=-1,a.setAttribute(`data-state`,c?`open`:`closed`),!c){let e=E.get(i),t=D.get(i);if(i.setAttribute(`data-state`,`inactive`),i.setAttribute(`aria-hidden`,`true`),l(i,!0),i.style.pointerEvents=`none`,u&&o){let e=o===`right`?`to-left`:`to-right`;i.setAttribute(`data-motion`,e)}else u&&i.removeAttribute(`data-motion`);u?t?.exit():t?.isExiting||(i.removeAttribute(`data-motion`),e?.restore(),i.hidden=!0)}}),i){if(j?.mount(),f&&(f.hidden=!1),r===null&&M?.enter(),E.get(i.content)?.mount(),D.get(i.content)?.enter(),o){let e=o===`right`?`from-right`:`from-left`;i.content.setAttribute(`data-motion`,e)}else i.content.removeAttribute(`data-motion`);i.content.setAttribute(`data-state`,`active`),i.content.removeAttribute(`aria-hidden`),l(i.content,!1),i.content.hidden=!1,i.content.style.pointerEvents=`auto`,_=i.index,G(i.content,i.trigger,i.align),I(i),q(i.trigger)}else M?.exit(),I(null);let u=t!==null;n.setAttribute(`data-state`,u?`open`:`closed`),o?n.setAttribute(`data-motion`,o===`right`?`from-right`:`from-left`):n.removeAttribute(`data-motion`),f&&(f.setAttribute(`data-state`,u?`open`:`closed`),f.style.pointerEvents=u?`auto`:`none`,u&&!a?f.setAttribute(`data-instant`,``):a&&f.removeAttribute(`data-instant`),o&&f.style.setProperty(`--motion-direction`,o===`right`?`1`:`-1`)),h=t,g=null,t===null&&q(null),(0,e.emit)(n,`navigation-menu:change`,{value:t}),s?.(t)};r?o():t!==null&&h===null?v=setTimeout(o,i):t!==null&&h!==null?o():y=setTimeout(o,a)};n.setAttribute(`data-state`,`closed`),f&&(f.setAttribute(`data-state`,`closed`),f.hidden=!0,f.style.pointerEvents=`none`),p&&p.setAttribute(`data-state`,`hidden`),L.forEach(({trigger:t,content:n,item:r})=>{t.tagName===`BUTTON`&&!t.hasAttribute(`type`)&&(t.type=`button`),(0,e.setAria)(t,`expanded`,!1),t.setAttribute(`data-state`,`closed`),t.tabIndex=t===z[0]?0:-1,r.setAttribute(`data-state`,`closed`),n.setAttribute(`data-state`,`inactive`),n.setAttribute(`aria-hidden`,`true`),n.tabIndex=-1,l(n,!0),n.hidden=!0,n.style.pointerEvents=`none`}),L.forEach(({item:t,trigger:n},r)=>{T.push((0,e.on)(n,`pointerenter`,()=>{x||q(n)})),T.push((0,e.on)(t,`pointerenter`,()=>{x||J(r)})),T.push((0,e.on)(t,`pointerleave`,()=>{g===r&&h===null&&(H(),g=null)})),T.push((0,e.on)(n,`focus`,()=>{S||(o&&J(r,!0),q(n))})),T.push((0,e.on)(n,`pointerdown`,()=>{S=!0})),T.push((0,e.on)(n,`click`,()=>{H(),h===r&&x?(x=!1,J(null,!0),q(null)):h===r&&!x?(x=!0,q(n)):(x=!0,J(r,!0),q(n)),S=!1}))}),T.push((0,e.on)(n,`pointerenter`,()=>{C=!0}),(0,e.on)(n,`pointerleave`,t=>{let r=t.relatedTarget;(0,e.containsWithPortals)(n,r)||(C=!1,x||(J(null),q(null)))}),(0,e.on)(n,`pointerdown`,H)),f&&T.push((0,e.on)(f,`pointerenter`,()=>{H()}),(0,e.on)(f,`transitionend`,e=>{if(e.target!==f)return;let t=h?L.get(h):null;t&&G(t.content,t.trigger,t.align)})),L.forEach(({content:t})=>{T.push((0,e.on)(t,`pointerenter`,()=>{H()}),(0,e.on)(t,`pointerleave`,t=>{if(x)return;let r=t.relatedTarget;(0,e.containsWithPortals)(n,r)||(J(null),q(null))}))}),T.push((0,e.on)(u,`keydown`,e=>{let t=e.target,n=z.indexOf(t);if(n===-1)return;let r=B.get(t)??null,i=n;switch(e.key){case`ArrowLeft`:i=n-1,i<0&&(i=z.length-1);break;case`ArrowRight`:i=n+1,i>=z.length&&(i=0);break;case`ArrowDown`:e.preventDefault(),r&&(x=!0,J(r,!0),requestAnimationFrame(()=>{let e=L.get(r);if(!e)return;let t=V(e.content)[0];t?t.focus():e.content.focus()}));return;case`Home`:i=0;break;case`End`:i=z.length-1;break;case`Escape`:x=!1,J(null,!0),q(null);return;default:return}e.preventDefault();let a=z[i];a&&(z.forEach(e=>e.tabIndex=e===a?0:-1),a.focus(),q(a))})),L.forEach(({content:t,trigger:n})=>{T.push((0,e.on)(t,`keydown`,e=>{let r=e.target,i=V(t),a=i.indexOf(r);if(a!==-1)switch(e.key){case`ArrowDown`:case`ArrowRight`:{e.preventDefault();let t=a+1;t<i.length&&i[t]?.focus();break}case`ArrowUp`:case`ArrowLeft`:e.preventDefault(),a===0?n.focus():i[a-1]?.focus();break;case`Escape`:e.preventDefault(),x=!1,J(null,!0),q(null),n.focus();break}}))});let Y=()=>(0,e.containsWithPortals)(n,document.activeElement)||C||x,X=()=>{x=!1,J(null,!0),q(null)};return T.push((0,e.on)(document,`pointerup`,()=>{S=!1},{capture:!0}),(0,e.on)(document,`pointercancel`,()=>{S=!1},{capture:!0})),T.push((0,e.on)(document,`focusin`,t=>{h!==null&&((0,e.containsWithPortals)(n,t.target)||X())})),T.push((0,e.createDismissLayer)({root:n,isOpen:()=>h!==null&&Y(),onDismiss:X,closeOnClickOutside:!0,closeOnEscape:!0,preventEscapeDefault:!1,isInside:t=>!!t&&(0,e.containsWithPortals)(n,t)})),T.push((0,e.on)(window,`resize`,()=>{if(h&&requestAnimationFrame(()=>P()),h){let e=L.get(h);e&&requestAnimationFrame(()=>N(e.content))}b&&requestAnimationFrame(()=>q(b))}),(0,e.on)(u,`scroll`,()=>{b&&requestAnimationFrame(()=>q(b))})),T.push((0,e.on)(n,`navigation-menu:set`,e=>{let t=e.detail;if(t?.value!==void 0){if(t.value===null)X();else if(L.has(t.value)){x=!0,J(t.value,!0);let e=L.get(t.value);e&&q(e.trigger)}}})),{get value(){return h},open:e=>J(e,!0),close:()=>J(null,!0),destroy:()=>{w=!0,H(),T.forEach(e=>e()),T.length=0}}}const r=new WeakSet;function i(t=document){let i=[];for(let a of(0,e.getRoots)(t,`navigation-menu`))r.has(a)||(r.add(a),i.push(n(a)));return i}exports.create=i,exports.createNavigationMenu=n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@data-slot/core`);const t=[`start`,`center`,`end`],n=[`top`,`right`,`bottom`,`left`];function r(r,i={}){let a=i.delayOpen??(0,e.getDataNumber)(r,`delayOpen`)??200,o=i.delayClose??(0,e.getDataNumber)(r,`delayClose`)??150,s=i.openOnFocus??(0,e.getDataBool)(r,`openOnFocus`)??!0,c=i.side??(0,e.getDataEnum)(r,`side`,n)??`bottom`,l=i.align??(0,e.getDataEnum)(r,`align`,t)??`start`,u=i.sideOffset??(0,e.getDataNumber)(r,`sideOffset`)??0,d=i.alignOffset??(0,e.getDataNumber)(r,`alignOffset`)??0,f=i.onValueChange,p=e=>e.replace(/[^a-z0-9\-_:.]/gi,`-`),m=(e,t)=>{`inert`in e&&(e.inert=t)},h=(0,e.getPart)(r,`navigation-menu-list`),g=(0,e.getParts)(r,`navigation-menu-item`),_=(0,e.getPart)(r,`navigation-menu-viewport`),v=(0,e.getPart)(r,`navigation-menu-indicator`),y=(e,t)=>{let n=e.parentElement;for(;n&&n!==r;){if(n.getAttribute(`data-slot`)===t)return n;n=n.parentElement}return null};if(!h||g.length===0)throw Error(`NavigationMenu requires navigation-menu-list and at least one navigation-menu-item`);let b=null,x=null,S=-1,C=null,w=null,T=null,E=!1,D=!1,O=!1,k=!1,A=[],j=new Map,M=new Map,N=_?y(_,`navigation-menu-viewport-positioner`):null,P=_?y(_,`navigation-menu-positioner`):null,F=N??P,I=F?y(F,`navigation-menu-portal`):null,L=_?(0,e.createPortalLifecycle)({content:_,root:r,enabled:!0,wrapperSlot:F?void 0:`navigation-menu-viewport-positioner`,container:F??void 0,mountTarget:F?I??F:void 0}):null,R=_?(0,e.createPresenceLifecycle)({element:_,onExitComplete:()=>{k||(L?.restore(),_.hidden=!0,_.style.pointerEvents=`none`)}}):null,ee=e=>{if(!_)return;let t=M.get(e)??{originalParent:null,originalNextSibling:null,mountedInViewport:!1};t.mountedInViewport||(t.originalParent=e.parentNode,t.originalNextSibling=e.nextSibling,t.mountedInViewport=!0,M.set(e,t)),e.parentNode!==_&&_.appendChild(e)},z=e=>{let t=M.get(e);if(!t||!t.mountedInViewport)return;let n=t.originalParent,r=t.originalNextSibling;n&&n.isConnected?r&&r.parentNode===n?n.insertBefore(e,r):n.appendChild(e):e.remove(),t.mountedInViewport=!1,t.originalParent=null,t.originalNextSibling=null},B=()=>{if(!_||!L)return;let e=L.container,t=r.ownerDocument.defaultView??window,n=r.getBoundingClientRect();e.style.position=`absolute`,e.style.top=`0px`,e.style.left=`0px`,e.style.transform=`translate3d(${n.left+t.scrollX}px, ${n.top+t.scrollY}px, 0)`,e.style.width=`${n.width}px`,e.style.height=`${n.height}px`,e.style.margin=`0`,e.style.willChange=`transform`,e.style.pointerEvents=`none`},V=null,H=e=>{V?.disconnect(),V=null,!(!_||!e)&&(V=new ResizeObserver(()=>{let t=W(e.item,e.content);X(e.content,e.trigger,t)}),V.observe(e.content))};A.push(()=>V?.disconnect()),A.push(()=>{j.forEach(e=>e.cleanup()),j.clear(),M.forEach((e,t)=>{z(t),t.hidden=!0,t.style.pointerEvents=`none`}),M.clear(),R?.cleanup(),L?.cleanup()});let U=new Map,W=(r,a)=>({side:i.side??(0,e.getDataEnum)(a,`side`,n)??(0,e.getDataEnum)(r,`side`,n)??c,align:i.align??(0,e.getDataEnum)(a,`align`,t)??(0,e.getDataEnum)(r,`align`,t)??l,sideOffset:i.sideOffset??(0,e.getDataNumber)(a,`sideOffset`)??(0,e.getDataNumber)(r,`sideOffset`)??u,alignOffset:i.alignOffset??(0,e.getDataNumber)(a,`alignOffset`)??(0,e.getDataNumber)(r,`alignOffset`)??d}),te=0;g.forEach(t=>{let n=t.dataset.value;if(!n)return;let r=(0,e.getPart)(t,`navigation-menu-trigger`),i=(0,e.getPart)(t,`navigation-menu-content`);if(r&&i){U.set(n,{item:t,trigger:r,content:i,index:te++}),j.set(i,(0,e.createPresenceLifecycle)({element:i,onExitComplete:()=>{k||(z(i),i.hidden=!0,i.style.pointerEvents=`none`)}}));let a=p(n),o=(0,e.ensureId)(r,`nav-menu-trigger-${a}`),s=(0,e.ensureId)(i,`nav-menu-content-${a}`);r.setAttribute(`aria-haspopup`,`true`),r.setAttribute(`aria-controls`,s),i.setAttribute(`aria-labelledby`,o)}});let G=Array.from(U.values()).map(e=>e.trigger),K=new Map;for(let[e,t]of U)K.set(t.trigger,e);let q=e=>Array.from(e.querySelectorAll(`a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])`)).filter(e=>!e.hidden&&!e.closest(`[hidden]`)),J=()=>{C&&=(clearTimeout(C),null),w&&=(clearTimeout(w),null)},Y=null,ne=()=>{if(!_)return null;let e=L?.container;return e instanceof HTMLElement?e:_.parentElement instanceof HTMLElement?_.parentElement:_},re=()=>{let t=ne();return Y||(Y=document.createElement(`div`),Y.setAttribute(`data-slot`,`navigation-menu-bridge`),Y.style.cssText=`position: absolute; pointer-events: auto; z-index: 0;`,A.push((0,e.on)(Y,`pointerenter`,()=>{J()}))),t&&Y.parentElement!==t&&t.insertBefore(Y,t.firstChild),Y},X=(t,i,a)=>{_&&requestAnimationFrame(()=>{let o=t.firstElementChild,s=o?.getBoundingClientRect(),c=o?getComputedStyle(o):null,l=c&&parseFloat(c.marginTop)||0,u=c&&parseFloat(c.marginBottom)||0,d=s??t.getBoundingClientRect(),f=d.height+l+u,p=getComputedStyle(_),m=parseFloat(p.marginTop)||0,h=t.getBoundingClientRect();_.style.setProperty(`--viewport-width`,`${h.width}px`),_.style.setProperty(`--viewport-height`,`${f}px`);let g=r.getBoundingClientRect(),v=(0,e.computeFloatingPosition)({anchorRect:i.getBoundingClientRect(),contentRect:d,side:a.side,align:a.align,sideOffset:a.sideOffset,alignOffset:a.alignOffset,avoidCollisions:!1,collisionPadding:0,allowedSides:n}),y=v.x-g.left,b=v.y-g.top;_.style.setProperty(`--viewport-top`,`${b}px`),_.style.setProperty(`--viewport-left`,`${y}px`),_.style.top=`${b}px`,_.style.left=`${y}px`,t.style.top=`0px`,t.style.left=`0px`,_.setAttribute(`data-side`,v.side),_.setAttribute(`data-align`,v.align),t.setAttribute(`data-side`,v.side),t.setAttribute(`data-align`,v.align);let x=L?.container;x&&x!==_&&(x.setAttribute(`data-side`,v.side),x.setAttribute(`data-align`,v.align)),B();let S=_.getBoundingClientRect(),C=Math.max(0,S.top-g.bottom),w=Math.max(0,g.top-S.bottom),T=Math.max(0,S.left-g.right),E=Math.max(0,g.left-S.right),D=Math.max(0,l+m),O=Math.max(C,w,D),k=Math.max(T,E);if(Math.max(O,k)>0){let e=re();if(e.style.transform=`none`,e.style.bottom=`auto`,e.style.right=`auto`,O>=k){let t=Math.max(C,w,D);e.style.width=`${h.width}px`,e.style.height=`${t}px`,e.style.left=`${y}px`,w>C&&w>=D?e.style.top=`${b+f}px`:e.style.top=`${b-t}px`}else{let t=Math.max(T,E);e.style.height=`${f}px`,e.style.width=`${t}px`,e.style.top=`${b}px`,E>T?e.style.left=`${y+h.width}px`:e.style.left=`${y-t}px`}}else Y&&(Y.style.height=`0`,Y.style.width=`0`,Y.style.top=`0px`,Y.style.left=`0px`,Y.style.right=`0px`,Y.style.bottom=`auto`,Y.style.transform=`none`)})},ie=e=>S===-1||e>S?`right`:`left`,Z=e=>{if(!v)return;if(T=e,!e){v.setAttribute(`data-state`,`hidden`);return}let t=h.getBoundingClientRect(),n=e.getBoundingClientRect();v.style.setProperty(`--indicator-left`,`${n.left-t.left}px`),v.style.setProperty(`--indicator-width`,`${n.width}px`),v.style.setProperty(`--indicator-top`,`${n.top-t.top}px`);let r=(_&&parseFloat(getComputedStyle(_).marginTop)||0)<1?1:0;v.style.setProperty(`--indicator-height`,`${n.height-r}px`),v.setAttribute(`data-state`,`visible`)},Q=(t,n=!1)=>{if(t===b){J();return}if(t!==null&&t===x){J();return}J(),x=t===null?null:t;let i=()=>{let n=b,i=t?U.get(t):null,a=n!==null&&t!==null&&n!==t,o=a&&i?ie(i.index):null,s=document.activeElement;if(t===null&&s&&(0,e.containsWithPortals)(r,s)){let e=n?U.get(n)?.trigger:null;e&&e.focus()}if(U.forEach(({trigger:r,content:i,item:a},s)=>{let c=s===t,l=s===n;if((0,e.setAria)(r,`expanded`,c),r.setAttribute(`data-state`,c?`open`:`closed`),c||l&&t===null?r.tabIndex=0:r.tabIndex=-1,a.setAttribute(`data-state`,c?`open`:`closed`),!c){let e=j.get(i);if(i.setAttribute(`data-state`,`inactive`),i.setAttribute(`aria-hidden`,`true`),m(i,!0),i.style.pointerEvents=`none`,l&&o){let e=o===`right`?`to-left`:`to-right`;i.setAttribute(`data-motion`,e)}else l&&i.removeAttribute(`data-motion`);l?e?.exit():e?.isExiting||(i.removeAttribute(`data-motion`),z(i),i.hidden=!0)}}),i){if(L?.mount(),_&&(_.hidden=!1),n===null&&R?.enter(),ee(i.content),j.get(i.content)?.enter(),o){let e=o===`right`?`from-right`:`from-left`;i.content.setAttribute(`data-motion`,e)}else i.content.removeAttribute(`data-motion`);i.content.setAttribute(`data-state`,`active`),i.content.removeAttribute(`aria-hidden`),m(i.content,!1),i.content.hidden=!1,i.content.style.pointerEvents=`auto`,S=i.index;let e=W(i.item,i.content);X(i.content,i.trigger,e),H(i),Z(i.trigger)}else R?.exit(),H(null);let c=t!==null;r.setAttribute(`data-state`,c?`open`:`closed`),o?r.setAttribute(`data-motion`,o===`right`?`from-right`:`from-left`):r.removeAttribute(`data-motion`),_&&(_.setAttribute(`data-state`,c?`open`:`closed`),_.style.pointerEvents=c?`auto`:`none`,c&&!a?_.setAttribute(`data-instant`,``):a&&_.removeAttribute(`data-instant`),o&&_.style.setProperty(`--motion-direction`,o===`right`?`1`:`-1`)),b=t,x=null,t===null&&Z(null),(0,e.emit)(r,`navigation-menu:change`,{value:t}),f?.(t)};n?i():t!==null&&b===null?C=setTimeout(i,a):t!==null&&b!==null?i():w=setTimeout(i,o)};r.setAttribute(`data-state`,`closed`),_&&(_.setAttribute(`data-state`,`closed`),_.hidden=!0,_.style.pointerEvents=`none`),v&&v.setAttribute(`data-state`,`hidden`),U.forEach(({trigger:t,content:n,item:r})=>{t.tagName===`BUTTON`&&!t.hasAttribute(`type`)&&(t.type=`button`),(0,e.setAria)(t,`expanded`,!1),t.setAttribute(`data-state`,`closed`),t.tabIndex=t===G[0]?0:-1,r.setAttribute(`data-state`,`closed`),n.setAttribute(`data-state`,`inactive`),n.setAttribute(`aria-hidden`,`true`),n.tabIndex=-1,m(n,!0),n.hidden=!0,n.style.pointerEvents=`none`}),U.forEach(({item:t,trigger:n},r)=>{A.push((0,e.on)(n,`pointerenter`,()=>{E||Z(n)})),A.push((0,e.on)(t,`pointerenter`,()=>{E||Q(r)})),A.push((0,e.on)(t,`pointerleave`,()=>{x===r&&b===null&&(J(),x=null)})),A.push((0,e.on)(n,`focus`,()=>{D||(s&&Q(r,!0),Z(n))})),A.push((0,e.on)(n,`pointerdown`,()=>{D=!0})),A.push((0,e.on)(n,`click`,()=>{J(),b===r&&E?(E=!1,Q(null,!0),Z(null)):b===r&&!E?(E=!0,Z(n)):(E=!0,Q(r,!0),Z(n)),D=!1}))}),A.push((0,e.on)(r,`pointerenter`,()=>{O=!0}),(0,e.on)(r,`pointerleave`,t=>{let n=t.relatedTarget;(0,e.containsWithPortals)(r,n)||(O=!1,E||(Q(null),Z(null)))}),(0,e.on)(r,`pointerdown`,J)),_&&A.push((0,e.on)(_,`pointerenter`,()=>{J()}),(0,e.on)(_,`transitionend`,e=>{if(e.target!==_)return;let t=b?U.get(b):null;if(t){let e=W(t.item,t.content);X(t.content,t.trigger,e)}})),U.forEach(({content:t})=>{A.push((0,e.on)(t,`pointerenter`,()=>{J()}),(0,e.on)(t,`pointerleave`,t=>{if(E)return;let n=t.relatedTarget;(0,e.containsWithPortals)(r,n)||(Q(null),Z(null))}))}),A.push((0,e.on)(h,`keydown`,e=>{let t=e.target,n=G.indexOf(t);if(n===-1)return;let r=K.get(t)??null,i=n;switch(e.key){case`ArrowLeft`:i=n-1,i<0&&(i=G.length-1);break;case`ArrowRight`:i=n+1,i>=G.length&&(i=0);break;case`ArrowDown`:e.preventDefault(),r&&(E=!0,Q(r,!0),requestAnimationFrame(()=>{let e=U.get(r);if(!e)return;let t=q(e.content)[0];t?t.focus():e.content.focus()}));return;case`Home`:i=0;break;case`End`:i=G.length-1;break;case`Escape`:E=!1,Q(null,!0),Z(null);return;default:return}e.preventDefault();let a=G[i];a&&(G.forEach(e=>e.tabIndex=e===a?0:-1),a.focus(),Z(a))})),U.forEach(({content:t,trigger:n})=>{A.push((0,e.on)(t,`keydown`,e=>{let r=e.target,i=q(t),a=i.indexOf(r);if(a!==-1)switch(e.key){case`ArrowDown`:case`ArrowRight`:{e.preventDefault();let t=a+1;t<i.length&&i[t]?.focus();break}case`ArrowUp`:case`ArrowLeft`:e.preventDefault(),a===0?n.focus():i[a-1]?.focus();break;case`Escape`:e.preventDefault(),E=!1,Q(null,!0),Z(null),n.focus();break}}))});let ae=()=>(0,e.containsWithPortals)(r,document.activeElement)||O||E,$=()=>{E=!1,Q(null,!0),Z(null)};return A.push((0,e.on)(document,`pointerup`,()=>{D=!1},{capture:!0}),(0,e.on)(document,`pointercancel`,()=>{D=!1},{capture:!0})),A.push((0,e.on)(document,`focusin`,t=>{b!==null&&((0,e.containsWithPortals)(r,t.target)||$())})),A.push((0,e.createDismissLayer)({root:r,isOpen:()=>b!==null&&ae(),onDismiss:$,closeOnClickOutside:!0,closeOnEscape:!0,preventEscapeDefault:!1,isInside:t=>!!t&&(0,e.containsWithPortals)(r,t)})),A.push((0,e.on)(window,`resize`,()=>{b&&requestAnimationFrame(()=>B()),T&&requestAnimationFrame(()=>Z(T))}),(0,e.on)(h,`scroll`,()=>{T&&requestAnimationFrame(()=>Z(T))})),A.push((0,e.on)(r,`navigation-menu:set`,e=>{let t=e.detail;if(t?.value!==void 0){if(t.value===null)$();else if(U.has(t.value)){E=!0,Q(t.value,!0);let e=U.get(t.value);e&&Z(e.trigger)}}})),{get value(){return b},open:e=>Q(e,!0),close:()=>Q(null,!0),destroy:()=>{k=!0,J(),A.forEach(e=>e()),A.length=0}}}const i=new WeakSet;function a(t=document){let n=[];for(let a of(0,e.getRoots)(t,`navigation-menu`))i.has(a)||(i.add(a),n.push(r(a)));return n}exports.create=a,exports.createNavigationMenu=r;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{containsWithPortals as e,createDismissLayer as t,createPortalLifecycle as n,createPresenceLifecycle as r,emit as i,ensureId as a,getDataBool as o,getDataEnum as s,getDataNumber as c,getPart as l,getParts as u,getRoots as d,on as f,setAria as p}from"@data-slot/core";const m=[`start`,`center`,`end`];function h(d,h={}){let g=h.delayOpen??c(d,`delayOpen`)??200,_=h.delayClose??c(d,`delayClose`)??150,ee=h.openOnFocus??o(d,`openOnFocus`)??!0,te=h.onValueChange,ne=e=>e.replace(/[^a-z0-9\-_:.]/gi,`-`),v=(e,t)=>{`inert`in e&&(e.inert=t)},y=l(d,`navigation-menu-list`),b=u(d,`navigation-menu-item`),x=l(d,`navigation-menu-viewport`),S=l(d,`navigation-menu-indicator`),C=(e,t)=>{let n=e.parentElement;for(;n&&n!==d;){if(n.getAttribute(`data-slot`)===t)return n;n=n.parentElement}return null};if(!y||b.length===0)throw Error(`NavigationMenu requires navigation-menu-list and at least one navigation-menu-item`);let w=null,T=null,E=-1,D=null,O=null,k=null,A=!1,j=!1,M=!1,N=!1,P=[],F=new Map,I=new Map,L=new Set,R=x?C(x,`navigation-menu-viewport-positioner`):null,re=R?C(R,`navigation-menu-portal`):null,z=x?n({content:x,root:d,enabled:!0,wrapperSlot:R?void 0:`navigation-menu-viewport-positioner`,container:R??void 0,mountTarget:R?re??R:void 0}):null,B=x?r({element:x,onExitComplete:()=>{N||(z?.restore(),x.hidden=!0,x.style.pointerEvents=`none`)}}):null,V=e=>{let t=F.get(e);if(!t)return;let n=t.container,r=d.ownerDocument.defaultView??window,i=d.getBoundingClientRect();n.style.position=`absolute`,n.style.top=`0px`,n.style.left=`0px`,n.style.transform=`translate3d(${i.left+r.scrollX}px, ${i.top+r.scrollY}px, 0)`,n.style.width=`${i.width}px`,n.style.height=`${i.height}px`,n.style.margin=`0`,n.style.willChange=`transform`,n.style.pointerEvents=`none`},H=()=>{if(!x||!z)return;let e=z.container,t=d.ownerDocument.defaultView??window,n=d.getBoundingClientRect();e.style.position=`absolute`,e.style.top=`0px`,e.style.left=`0px`,e.style.transform=`translate3d(${n.left+t.scrollX}px, ${n.top+t.scrollY}px, 0)`,e.style.width=`${n.width}px`,e.style.height=`${n.height}px`,e.style.margin=`0`,e.style.willChange=`transform`,e.style.pointerEvents=`none`},U=null,W=e=>{U?.disconnect(),U=null,!(!x||!e)&&(U=new ResizeObserver(()=>X(e.content,e.trigger,e.align)),U.observe(e.content))};P.push(()=>U?.disconnect()),P.push(()=>{I.forEach(e=>e.cleanup()),I.clear(),B?.cleanup(),F.forEach(e=>e.cleanup()),F.clear(),z?.cleanup()});let G=new Map,ie=0;b.forEach(e=>{let t=e.dataset.value;if(!t)return;let i=l(e,`navigation-menu-trigger`),o=l(e,`navigation-menu-content`);if(i&&o){let c=s(o,`align`,m)??s(e,`align`,m)??s(d,`align`,m)??`start`;G.set(t,{item:e,trigger:i,content:o,index:ie++,align:c});let l=C(o,`navigation-menu-positioner`);l&&L.has(l)&&(l=null),l&&L.add(l);let u=l?C(l,`navigation-menu-portal`):null;F.set(o,n({content:o,root:d,enabled:!0,wrapperSlot:l?void 0:`navigation-menu-positioner`,container:l??void 0,mountTarget:l?u??l:void 0})),I.set(o,r({element:o,onExitComplete:()=>{N||(F.get(o)?.restore(),o.hidden=!0,o.style.pointerEvents=`none`)}}));let f=ne(t),p=a(i,`nav-menu-trigger-${f}`),h=a(o,`nav-menu-content-${f}`);i.setAttribute(`aria-haspopup`,`true`),i.setAttribute(`aria-controls`,h),o.setAttribute(`aria-labelledby`,p)}});let K=Array.from(G.values()).map(e=>e.trigger),q=new Map;for(let[e,t]of G)q.set(t.trigger,e);let ae=e=>Array.from(e.querySelectorAll(`a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])`)).filter(e=>!e.hidden&&!e.closest(`[hidden]`)),J=()=>{D&&=(clearTimeout(D),null),O&&=(clearTimeout(O),null)},Y=null,oe=()=>(Y||(Y=document.createElement(`div`),Y.setAttribute(`data-slot`,`navigation-menu-bridge`),Y.style.cssText=`position: absolute; left: 0; right: 0; top: 0; pointer-events: auto; z-index: -1;`,x&&x.insertBefore(Y,x.firstChild),P.push(f(Y,`pointerenter`,()=>{J()}))),Y),X=(e,t,n)=>{x&&requestAnimationFrame(()=>{let r=e.firstElementChild,i=r?.getBoundingClientRect(),a=r?getComputedStyle(r):null,o=a&&parseFloat(a.marginTop)||0,s=a&&parseFloat(a.marginBottom)||0,c=i??e.getBoundingClientRect(),l=c.height+o+s,u=getComputedStyle(x),f=parseFloat(u.marginTop)||0,p=e.getBoundingClientRect();x.style.setProperty(`--viewport-width`,`${p.width}px`),x.style.setProperty(`--viewport-height`,`${l}px`);let m=d.getBoundingClientRect(),h=t.getBoundingClientRect(),g;g=n===`center`?h.left-m.left+h.width/2-c.width/2:n===`end`?h.right-m.left-c.width:h.left-m.left,x.style.setProperty(`--viewport-left`,`${g}px`),x.style.left=`${g}px`,e.style.left=`${g}px`,V(e),H();let _=o+f;if(_>0){let e=oe();e.style.height=`${_}px`,e.style.transform=`translateY(-${_}px)`}else Y&&(Y.style.height=`0`)})},se=e=>E===-1||e>E?`right`:`left`,Z=e=>{if(!S)return;if(k=e,!e){S.setAttribute(`data-state`,`hidden`);return}let t=y.getBoundingClientRect(),n=e.getBoundingClientRect();S.style.setProperty(`--indicator-left`,`${n.left-t.left}px`),S.style.setProperty(`--indicator-width`,`${n.width}px`),S.style.setProperty(`--indicator-top`,`${n.top-t.top}px`);let r=(x&&parseFloat(getComputedStyle(x).marginTop)||0)<1?1:0;S.style.setProperty(`--indicator-height`,`${n.height-r}px`),S.setAttribute(`data-state`,`visible`)},Q=(t,n=!1)=>{if(t===w){J();return}if(t!==null&&t===T){J();return}J(),T=t===null?null:t;let r=()=>{let n=w,r=t?G.get(t):null,a=n!==null&&t!==null&&n!==t,o=a&&r?se(r.index):null,s=document.activeElement;if(t===null&&s&&e(d,s)){let e=n?G.get(n)?.trigger:null;e&&e.focus()}if(G.forEach(({trigger:e,content:r,item:i},a)=>{let s=a===t,c=a===n;if(p(e,`expanded`,s),e.setAttribute(`data-state`,s?`open`:`closed`),s||c&&t===null?e.tabIndex=0:e.tabIndex=-1,i.setAttribute(`data-state`,s?`open`:`closed`),!s){let e=F.get(r),t=I.get(r);if(r.setAttribute(`data-state`,`inactive`),r.setAttribute(`aria-hidden`,`true`),v(r,!0),r.style.pointerEvents=`none`,c&&o){let e=o===`right`?`to-left`:`to-right`;r.setAttribute(`data-motion`,e)}else c&&r.removeAttribute(`data-motion`);c?t?.exit():t?.isExiting||(r.removeAttribute(`data-motion`),e?.restore(),r.hidden=!0)}}),r){if(z?.mount(),x&&(x.hidden=!1),n===null&&B?.enter(),F.get(r.content)?.mount(),I.get(r.content)?.enter(),o){let e=o===`right`?`from-right`:`from-left`;r.content.setAttribute(`data-motion`,e)}else r.content.removeAttribute(`data-motion`);r.content.setAttribute(`data-state`,`active`),r.content.removeAttribute(`aria-hidden`),v(r.content,!1),r.content.hidden=!1,r.content.style.pointerEvents=`auto`,E=r.index,X(r.content,r.trigger,r.align),W(r),Z(r.trigger)}else B?.exit(),W(null);let c=t!==null;d.setAttribute(`data-state`,c?`open`:`closed`),o?d.setAttribute(`data-motion`,o===`right`?`from-right`:`from-left`):d.removeAttribute(`data-motion`),x&&(x.setAttribute(`data-state`,c?`open`:`closed`),x.style.pointerEvents=c?`auto`:`none`,c&&!a?x.setAttribute(`data-instant`,``):a&&x.removeAttribute(`data-instant`),o&&x.style.setProperty(`--motion-direction`,o===`right`?`1`:`-1`)),w=t,T=null,t===null&&Z(null),i(d,`navigation-menu:change`,{value:t}),te?.(t)};n?r():t!==null&&w===null?D=setTimeout(r,g):t!==null&&w!==null?r():O=setTimeout(r,_)};d.setAttribute(`data-state`,`closed`),x&&(x.setAttribute(`data-state`,`closed`),x.hidden=!0,x.style.pointerEvents=`none`),S&&S.setAttribute(`data-state`,`hidden`),G.forEach(({trigger:e,content:t,item:n})=>{e.tagName===`BUTTON`&&!e.hasAttribute(`type`)&&(e.type=`button`),p(e,`expanded`,!1),e.setAttribute(`data-state`,`closed`),e.tabIndex=e===K[0]?0:-1,n.setAttribute(`data-state`,`closed`),t.setAttribute(`data-state`,`inactive`),t.setAttribute(`aria-hidden`,`true`),t.tabIndex=-1,v(t,!0),t.hidden=!0,t.style.pointerEvents=`none`}),G.forEach(({item:e,trigger:t},n)=>{P.push(f(t,`pointerenter`,()=>{A||Z(t)})),P.push(f(e,`pointerenter`,()=>{A||Q(n)})),P.push(f(e,`pointerleave`,()=>{T===n&&w===null&&(J(),T=null)})),P.push(f(t,`focus`,()=>{j||(ee&&Q(n,!0),Z(t))})),P.push(f(t,`pointerdown`,()=>{j=!0})),P.push(f(t,`click`,()=>{J(),w===n&&A?(A=!1,Q(null,!0),Z(null)):w===n&&!A?(A=!0,Z(t)):(A=!0,Q(n,!0),Z(t)),j=!1}))}),P.push(f(d,`pointerenter`,()=>{M=!0}),f(d,`pointerleave`,t=>{let n=t.relatedTarget;e(d,n)||(M=!1,A||(Q(null),Z(null)))}),f(d,`pointerdown`,J)),x&&P.push(f(x,`pointerenter`,()=>{J()}),f(x,`transitionend`,e=>{if(e.target!==x)return;let t=w?G.get(w):null;t&&X(t.content,t.trigger,t.align)})),G.forEach(({content:t})=>{P.push(f(t,`pointerenter`,()=>{J()}),f(t,`pointerleave`,t=>{if(A)return;let n=t.relatedTarget;e(d,n)||(Q(null),Z(null))}))}),P.push(f(y,`keydown`,e=>{let t=e.target,n=K.indexOf(t);if(n===-1)return;let r=q.get(t)??null,i=n;switch(e.key){case`ArrowLeft`:i=n-1,i<0&&(i=K.length-1);break;case`ArrowRight`:i=n+1,i>=K.length&&(i=0);break;case`ArrowDown`:e.preventDefault(),r&&(A=!0,Q(r,!0),requestAnimationFrame(()=>{let e=G.get(r);if(!e)return;let t=ae(e.content)[0];t?t.focus():e.content.focus()}));return;case`Home`:i=0;break;case`End`:i=K.length-1;break;case`Escape`:A=!1,Q(null,!0),Z(null);return;default:return}e.preventDefault();let a=K[i];a&&(K.forEach(e=>e.tabIndex=e===a?0:-1),a.focus(),Z(a))})),G.forEach(({content:e,trigger:t})=>{P.push(f(e,`keydown`,n=>{let r=n.target,i=ae(e),a=i.indexOf(r);if(a!==-1)switch(n.key){case`ArrowDown`:case`ArrowRight`:{n.preventDefault();let e=a+1;e<i.length&&i[e]?.focus();break}case`ArrowUp`:case`ArrowLeft`:n.preventDefault(),a===0?t.focus():i[a-1]?.focus();break;case`Escape`:n.preventDefault(),A=!1,Q(null,!0),Z(null),t.focus();break}}))});let ce=()=>e(d,document.activeElement)||M||A,$=()=>{A=!1,Q(null,!0),Z(null)};return P.push(f(document,`pointerup`,()=>{j=!1},{capture:!0}),f(document,`pointercancel`,()=>{j=!1},{capture:!0})),P.push(f(document,`focusin`,t=>{w!==null&&(e(d,t.target)||$())})),P.push(t({root:d,isOpen:()=>w!==null&&ce(),onDismiss:$,closeOnClickOutside:!0,closeOnEscape:!0,preventEscapeDefault:!1,isInside:t=>!!t&&e(d,t)})),P.push(f(window,`resize`,()=>{if(w&&requestAnimationFrame(()=>H()),w){let e=G.get(w);e&&requestAnimationFrame(()=>V(e.content))}k&&requestAnimationFrame(()=>Z(k))}),f(y,`scroll`,()=>{k&&requestAnimationFrame(()=>Z(k))})),P.push(f(d,`navigation-menu:set`,e=>{let t=e.detail;if(t?.value!==void 0){if(t.value===null)$();else if(G.has(t.value)){A=!0,Q(t.value,!0);let e=G.get(t.value);e&&Z(e.trigger)}}})),{get value(){return w},open:e=>Q(e,!0),close:()=>Q(null,!0),destroy:()=>{N=!0,J(),P.forEach(e=>e()),P.length=0}}}const g=new WeakSet;function _(e=document){let t=[];for(let n of d(e,`navigation-menu`))g.has(n)||(g.add(n),t.push(h(n)));return t}export{_ as create,h as createNavigationMenu};
1
+ import{computeFloatingPosition as e,containsWithPortals as t,createDismissLayer as n,createPortalLifecycle as r,createPresenceLifecycle as i,emit as a,ensureId as o,getDataBool as s,getDataEnum as c,getDataNumber as l,getPart as u,getParts as ee,getRoots as d,on as f,setAria as p}from"@data-slot/core";const m=[`start`,`center`,`end`],h=[`top`,`right`,`bottom`,`left`];function g(d,g={}){let _=g.delayOpen??l(d,`delayOpen`)??200,v=g.delayClose??l(d,`delayClose`)??150,y=g.openOnFocus??s(d,`openOnFocus`)??!0,b=g.side??c(d,`side`,h)??`bottom`,x=g.align??c(d,`align`,m)??`start`,S=g.sideOffset??l(d,`sideOffset`)??0,C=g.alignOffset??l(d,`alignOffset`)??0,w=g.onValueChange,T=e=>e.replace(/[^a-z0-9\-_:.]/gi,`-`),E=(e,t)=>{`inert`in e&&(e.inert=t)},D=u(d,`navigation-menu-list`),te=ee(d,`navigation-menu-item`),O=u(d,`navigation-menu-viewport`),k=u(d,`navigation-menu-indicator`),ne=(e,t)=>{let n=e.parentElement;for(;n&&n!==d;){if(n.getAttribute(`data-slot`)===t)return n;n=n.parentElement}return null};if(!D||te.length===0)throw Error(`NavigationMenu requires navigation-menu-list and at least one navigation-menu-item`);let A=null,j=null,M=-1,re=null,ie=null,N=null,P=!1,F=!1,I=!1,L=!1,R=[],z=new Map,B=new Map,ae=O?ne(O,`navigation-menu-viewport-positioner`):null,oe=O?ne(O,`navigation-menu-positioner`):null,V=ae??oe,se=V?ne(V,`navigation-menu-portal`):null,H=O?r({content:O,root:d,enabled:!0,wrapperSlot:V?void 0:`navigation-menu-viewport-positioner`,container:V??void 0,mountTarget:V?se??V:void 0}):null,U=O?i({element:O,onExitComplete:()=>{L||(H?.restore(),O.hidden=!0,O.style.pointerEvents=`none`)}}):null,ce=e=>{if(!O)return;let t=B.get(e)??{originalParent:null,originalNextSibling:null,mountedInViewport:!1};t.mountedInViewport||(t.originalParent=e.parentNode,t.originalNextSibling=e.nextSibling,t.mountedInViewport=!0,B.set(e,t)),e.parentNode!==O&&O.appendChild(e)},W=e=>{let t=B.get(e);if(!t||!t.mountedInViewport)return;let n=t.originalParent,r=t.originalNextSibling;n&&n.isConnected?r&&r.parentNode===n?n.insertBefore(e,r):n.appendChild(e):e.remove(),t.mountedInViewport=!1,t.originalParent=null,t.originalNextSibling=null},le=()=>{if(!O||!H)return;let e=H.container,t=d.ownerDocument.defaultView??window,n=d.getBoundingClientRect();e.style.position=`absolute`,e.style.top=`0px`,e.style.left=`0px`,e.style.transform=`translate3d(${n.left+t.scrollX}px, ${n.top+t.scrollY}px, 0)`,e.style.width=`${n.width}px`,e.style.height=`${n.height}px`,e.style.margin=`0`,e.style.willChange=`transform`,e.style.pointerEvents=`none`},G=null,ue=e=>{G?.disconnect(),G=null,!(!O||!e)&&(G=new ResizeObserver(()=>{let t=q(e.item,e.content);Z(e.content,e.trigger,t)}),G.observe(e.content))};R.push(()=>G?.disconnect()),R.push(()=>{z.forEach(e=>e.cleanup()),z.clear(),B.forEach((e,t)=>{W(t),t.hidden=!0,t.style.pointerEvents=`none`}),B.clear(),U?.cleanup(),H?.cleanup()});let K=new Map,q=(e,t)=>({side:g.side??c(t,`side`,h)??c(e,`side`,h)??b,align:g.align??c(t,`align`,m)??c(e,`align`,m)??x,sideOffset:g.sideOffset??l(t,`sideOffset`)??l(e,`sideOffset`)??S,alignOffset:g.alignOffset??l(t,`alignOffset`)??l(e,`alignOffset`)??C}),de=0;te.forEach(e=>{let t=e.dataset.value;if(!t)return;let n=u(e,`navigation-menu-trigger`),r=u(e,`navigation-menu-content`);if(n&&r){K.set(t,{item:e,trigger:n,content:r,index:de++}),z.set(r,i({element:r,onExitComplete:()=>{L||(W(r),r.hidden=!0,r.style.pointerEvents=`none`)}}));let a=T(t),s=o(n,`nav-menu-trigger-${a}`),c=o(r,`nav-menu-content-${a}`);n.setAttribute(`aria-haspopup`,`true`),n.setAttribute(`aria-controls`,c),r.setAttribute(`aria-labelledby`,s)}});let J=Array.from(K.values()).map(e=>e.trigger),fe=new Map;for(let[e,t]of K)fe.set(t.trigger,e);let pe=e=>Array.from(e.querySelectorAll(`a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])`)).filter(e=>!e.hidden&&!e.closest(`[hidden]`)),Y=()=>{re&&=(clearTimeout(re),null),ie&&=(clearTimeout(ie),null)},X=null,me=()=>{if(!O)return null;let e=H?.container;return e instanceof HTMLElement?e:O.parentElement instanceof HTMLElement?O.parentElement:O},he=()=>{let e=me();return X||(X=document.createElement(`div`),X.setAttribute(`data-slot`,`navigation-menu-bridge`),X.style.cssText=`position: absolute; pointer-events: auto; z-index: 0;`,R.push(f(X,`pointerenter`,()=>{Y()}))),e&&X.parentElement!==e&&e.insertBefore(X,e.firstChild),X},Z=(t,n,r)=>{O&&requestAnimationFrame(()=>{let i=t.firstElementChild,a=i?.getBoundingClientRect(),o=i?getComputedStyle(i):null,s=o&&parseFloat(o.marginTop)||0,c=o&&parseFloat(o.marginBottom)||0,l=a??t.getBoundingClientRect(),u=l.height+s+c,ee=getComputedStyle(O),f=parseFloat(ee.marginTop)||0,p=t.getBoundingClientRect();O.style.setProperty(`--viewport-width`,`${p.width}px`),O.style.setProperty(`--viewport-height`,`${u}px`);let m=d.getBoundingClientRect(),g=e({anchorRect:n.getBoundingClientRect(),contentRect:l,side:r.side,align:r.align,sideOffset:r.sideOffset,alignOffset:r.alignOffset,avoidCollisions:!1,collisionPadding:0,allowedSides:h}),_=g.x-m.left,v=g.y-m.top;O.style.setProperty(`--viewport-top`,`${v}px`),O.style.setProperty(`--viewport-left`,`${_}px`),O.style.top=`${v}px`,O.style.left=`${_}px`,t.style.top=`0px`,t.style.left=`0px`,O.setAttribute(`data-side`,g.side),O.setAttribute(`data-align`,g.align),t.setAttribute(`data-side`,g.side),t.setAttribute(`data-align`,g.align);let y=H?.container;y&&y!==O&&(y.setAttribute(`data-side`,g.side),y.setAttribute(`data-align`,g.align)),le();let b=O.getBoundingClientRect(),x=Math.max(0,b.top-m.bottom),S=Math.max(0,m.top-b.bottom),C=Math.max(0,b.left-m.right),w=Math.max(0,m.left-b.right),T=Math.max(0,s+f),E=Math.max(x,S,T),D=Math.max(C,w);if(Math.max(E,D)>0){let e=he();if(e.style.transform=`none`,e.style.bottom=`auto`,e.style.right=`auto`,E>=D){let t=Math.max(x,S,T);e.style.width=`${p.width}px`,e.style.height=`${t}px`,e.style.left=`${_}px`,S>x&&S>=T?e.style.top=`${v+u}px`:e.style.top=`${v-t}px`}else{let t=Math.max(C,w);e.style.height=`${u}px`,e.style.width=`${t}px`,e.style.top=`${v}px`,w>C?e.style.left=`${_+p.width}px`:e.style.left=`${_-t}px`}}else X&&(X.style.height=`0`,X.style.width=`0`,X.style.top=`0px`,X.style.left=`0px`,X.style.right=`0px`,X.style.bottom=`auto`,X.style.transform=`none`)})},ge=e=>M===-1||e>M?`right`:`left`,Q=e=>{if(!k)return;if(N=e,!e){k.setAttribute(`data-state`,`hidden`);return}let t=D.getBoundingClientRect(),n=e.getBoundingClientRect();k.style.setProperty(`--indicator-left`,`${n.left-t.left}px`),k.style.setProperty(`--indicator-width`,`${n.width}px`),k.style.setProperty(`--indicator-top`,`${n.top-t.top}px`);let r=(O&&parseFloat(getComputedStyle(O).marginTop)||0)<1?1:0;k.style.setProperty(`--indicator-height`,`${n.height-r}px`),k.setAttribute(`data-state`,`visible`)},$=(e,n=!1)=>{if(e===A){Y();return}if(e!==null&&e===j){Y();return}Y(),j=e===null?null:e;let r=()=>{let n=A,r=e?K.get(e):null,i=n!==null&&e!==null&&n!==e,o=i&&r?ge(r.index):null,s=document.activeElement;if(e===null&&s&&t(d,s)){let e=n?K.get(n)?.trigger:null;e&&e.focus()}if(K.forEach(({trigger:t,content:r,item:i},a)=>{let s=a===e,c=a===n;if(p(t,`expanded`,s),t.setAttribute(`data-state`,s?`open`:`closed`),s||c&&e===null?t.tabIndex=0:t.tabIndex=-1,i.setAttribute(`data-state`,s?`open`:`closed`),!s){let e=z.get(r);if(r.setAttribute(`data-state`,`inactive`),r.setAttribute(`aria-hidden`,`true`),E(r,!0),r.style.pointerEvents=`none`,c&&o){let e=o===`right`?`to-left`:`to-right`;r.setAttribute(`data-motion`,e)}else c&&r.removeAttribute(`data-motion`);c?e?.exit():e?.isExiting||(r.removeAttribute(`data-motion`),W(r),r.hidden=!0)}}),r){if(H?.mount(),O&&(O.hidden=!1),n===null&&U?.enter(),ce(r.content),z.get(r.content)?.enter(),o){let e=o===`right`?`from-right`:`from-left`;r.content.setAttribute(`data-motion`,e)}else r.content.removeAttribute(`data-motion`);r.content.setAttribute(`data-state`,`active`),r.content.removeAttribute(`aria-hidden`),E(r.content,!1),r.content.hidden=!1,r.content.style.pointerEvents=`auto`,M=r.index;let e=q(r.item,r.content);Z(r.content,r.trigger,e),ue(r),Q(r.trigger)}else U?.exit(),ue(null);let c=e!==null;d.setAttribute(`data-state`,c?`open`:`closed`),o?d.setAttribute(`data-motion`,o===`right`?`from-right`:`from-left`):d.removeAttribute(`data-motion`),O&&(O.setAttribute(`data-state`,c?`open`:`closed`),O.style.pointerEvents=c?`auto`:`none`,c&&!i?O.setAttribute(`data-instant`,``):i&&O.removeAttribute(`data-instant`),o&&O.style.setProperty(`--motion-direction`,o===`right`?`1`:`-1`)),A=e,j=null,e===null&&Q(null),a(d,`navigation-menu:change`,{value:e}),w?.(e)};n?r():e!==null&&A===null?re=setTimeout(r,_):e!==null&&A!==null?r():ie=setTimeout(r,v)};d.setAttribute(`data-state`,`closed`),O&&(O.setAttribute(`data-state`,`closed`),O.hidden=!0,O.style.pointerEvents=`none`),k&&k.setAttribute(`data-state`,`hidden`),K.forEach(({trigger:e,content:t,item:n})=>{e.tagName===`BUTTON`&&!e.hasAttribute(`type`)&&(e.type=`button`),p(e,`expanded`,!1),e.setAttribute(`data-state`,`closed`),e.tabIndex=e===J[0]?0:-1,n.setAttribute(`data-state`,`closed`),t.setAttribute(`data-state`,`inactive`),t.setAttribute(`aria-hidden`,`true`),t.tabIndex=-1,E(t,!0),t.hidden=!0,t.style.pointerEvents=`none`}),K.forEach(({item:e,trigger:t},n)=>{R.push(f(t,`pointerenter`,()=>{P||Q(t)})),R.push(f(e,`pointerenter`,()=>{P||$(n)})),R.push(f(e,`pointerleave`,()=>{j===n&&A===null&&(Y(),j=null)})),R.push(f(t,`focus`,()=>{F||(y&&$(n,!0),Q(t))})),R.push(f(t,`pointerdown`,()=>{F=!0})),R.push(f(t,`click`,()=>{Y(),A===n&&P?(P=!1,$(null,!0),Q(null)):A===n&&!P?(P=!0,Q(t)):(P=!0,$(n,!0),Q(t)),F=!1}))}),R.push(f(d,`pointerenter`,()=>{I=!0}),f(d,`pointerleave`,e=>{let n=e.relatedTarget;t(d,n)||(I=!1,P||($(null),Q(null)))}),f(d,`pointerdown`,Y)),O&&R.push(f(O,`pointerenter`,()=>{Y()}),f(O,`transitionend`,e=>{if(e.target!==O)return;let t=A?K.get(A):null;if(t){let e=q(t.item,t.content);Z(t.content,t.trigger,e)}})),K.forEach(({content:e})=>{R.push(f(e,`pointerenter`,()=>{Y()}),f(e,`pointerleave`,e=>{if(P)return;let n=e.relatedTarget;t(d,n)||($(null),Q(null))}))}),R.push(f(D,`keydown`,e=>{let t=e.target,n=J.indexOf(t);if(n===-1)return;let r=fe.get(t)??null,i=n;switch(e.key){case`ArrowLeft`:i=n-1,i<0&&(i=J.length-1);break;case`ArrowRight`:i=n+1,i>=J.length&&(i=0);break;case`ArrowDown`:e.preventDefault(),r&&(P=!0,$(r,!0),requestAnimationFrame(()=>{let e=K.get(r);if(!e)return;let t=pe(e.content)[0];t?t.focus():e.content.focus()}));return;case`Home`:i=0;break;case`End`:i=J.length-1;break;case`Escape`:P=!1,$(null,!0),Q(null);return;default:return}e.preventDefault();let a=J[i];a&&(J.forEach(e=>e.tabIndex=e===a?0:-1),a.focus(),Q(a))})),K.forEach(({content:e,trigger:t})=>{R.push(f(e,`keydown`,n=>{let r=n.target,i=pe(e),a=i.indexOf(r);if(a!==-1)switch(n.key){case`ArrowDown`:case`ArrowRight`:{n.preventDefault();let e=a+1;e<i.length&&i[e]?.focus();break}case`ArrowUp`:case`ArrowLeft`:n.preventDefault(),a===0?t.focus():i[a-1]?.focus();break;case`Escape`:n.preventDefault(),P=!1,$(null,!0),Q(null),t.focus();break}}))});let _e=()=>t(d,document.activeElement)||I||P,ve=()=>{P=!1,$(null,!0),Q(null)};return R.push(f(document,`pointerup`,()=>{F=!1},{capture:!0}),f(document,`pointercancel`,()=>{F=!1},{capture:!0})),R.push(f(document,`focusin`,e=>{A!==null&&(t(d,e.target)||ve())})),R.push(n({root:d,isOpen:()=>A!==null&&_e(),onDismiss:ve,closeOnClickOutside:!0,closeOnEscape:!0,preventEscapeDefault:!1,isInside:e=>!!e&&t(d,e)})),R.push(f(window,`resize`,()=>{A&&requestAnimationFrame(()=>le()),N&&requestAnimationFrame(()=>Q(N))}),f(D,`scroll`,()=>{N&&requestAnimationFrame(()=>Q(N))})),R.push(f(d,`navigation-menu:set`,e=>{let t=e.detail;if(t?.value!==void 0){if(t.value===null)ve();else if(K.has(t.value)){P=!0,$(t.value,!0);let e=K.get(t.value);e&&Q(e.trigger)}}})),{get value(){return A},open:e=>$(e,!0),close:()=>$(null,!0),destroy:()=>{L=!0,Y(),R.forEach(e=>e()),R.length=0}}}const _=new WeakSet;function v(e=document){let t=[];for(let n of d(e,`navigation-menu`))_.has(n)||(_.add(n),t.push(g(n)));return t}export{v as create,g as createNavigationMenu};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-slot/navigation-menu",
3
- "version": "0.2.57",
3
+ "version": "0.2.59",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.cjs",
@@ -39,6 +39,6 @@
39
39
  ],
40
40
  "license": "MIT",
41
41
  "dependencies": {
42
- "@data-slot/core": "0.2.57"
42
+ "@data-slot/core": "0.2.59"
43
43
  }
44
44
  }