2025-09-05 14:59:21 +08:00

2 lines
10 KiB
JavaScript

import{computed as O,defineComponent as j,Fragment as W,h as T,inject as q,onMounted as ee,onUnmounted as te,provide as z,ref as R,shallowRef as ie,watchEffect as J}from"vue";import{useNestedPortals as se}from'../../components/portal/portal.js';import{useEventListener as pe}from'../../hooks/use-event-listener.js';import{useId as H}from'../../hooks/use-id.js';import{useOutsideClick as fe}from'../../hooks/use-outside-click.js';import{useResolveButtonType as ve}from'../../hooks/use-resolve-button-type.js';import{useMainTreeNode as ce,useRootContainers as de}from'../../hooks/use-root-containers.js';import{Direction as M,useTabDirection as oe}from'../../hooks/use-tab-direction.js';import{Features as Q,Hidden as X}from'../../internal/hidden.js';import{State as N,useOpenClosed as ne,useOpenClosedProvider as Pe}from'../../internal/open-closed.js';import{Keys as k}from'../../keyboard.js';import{dom as n}from'../../utils/dom.js';import{Focus as D,FocusableMode as me,focusIn as B,FocusResult as Y,getFocusableElements as Z,isFocusableElement as be}from'../../utils/focus-management.js';import{match as K}from'../../utils/match.js';import'../../utils/micro-task.js';import{getOwnerDocument as V}from'../../utils/owner.js';import{Features as _,render as A}from'../../utils/render.js';var Se=(s=>(s[s.Open=0]="Open",s[s.Closed=1]="Closed",s))(Se||{});let re=Symbol("PopoverContext");function U(d){let P=q(re,null);if(P===null){let s=new Error(`<${d} /> is missing a parent <${ye.name} /> component.`);throw Error.captureStackTrace&&Error.captureStackTrace(s,U),s}return P}let le=Symbol("PopoverGroupContext");function ae(){return q(le,null)}let ue=Symbol("PopoverPanelContext");function ge(){return q(ue,null)}let ye=j({name:"Popover",inheritAttrs:!1,props:{as:{type:[Object,String],default:"div"}},setup(d,{slots:P,attrs:s,expose:h}){var u;let f=R(null);h({el:f,$el:f});let t=R(1),o=R(null),y=R(null),v=R(null),m=R(null),b=O(()=>V(f)),E=O(()=>{var L,$;if(!n(o)||!n(m))return!1;for(let x of document.querySelectorAll("body > *"))if(Number(x==null?void 0:x.contains(n(o)))^Number(x==null?void 0:x.contains(n(m))))return!0;let e=Z(),r=e.indexOf(n(o)),l=(r+e.length-1)%e.length,g=(r+1)%e.length,G=e[l],C=e[g];return!((L=n(m))!=null&&L.contains(G))&&!(($=n(m))!=null&&$.contains(C))}),a={popoverState:t,buttonId:R(null),panelId:R(null),panel:m,button:o,isPortalled:E,beforePanelSentinel:y,afterPanelSentinel:v,togglePopover(){t.value=K(t.value,{[0]:1,[1]:0})},closePopover(){t.value!==1&&(t.value=1)},close(e){a.closePopover();let r=(()=>e?e instanceof HTMLElement?e:e.value instanceof HTMLElement?n(e):n(a.button):n(a.button))();r==null||r.focus()}};z(re,a),Pe(O(()=>K(t.value,{[0]:N.Open,[1]:N.Closed})));let S={buttonId:a.buttonId,panelId:a.panelId,close(){a.closePopover()}},c=ae(),I=c==null?void 0:c.registerPopover,[F,w]=se(),i=de({mainTreeNodeRef:c==null?void 0:c.mainTreeNodeRef,portals:F,defaultContainers:[o,m]});function p(){var e,r,l,g;return(g=c==null?void 0:c.isFocusWithinPopoverGroup())!=null?g:((e=b.value)==null?void 0:e.activeElement)&&(((r=n(o))==null?void 0:r.contains(b.value.activeElement))||((l=n(m))==null?void 0:l.contains(b.value.activeElement)))}return J(()=>I==null?void 0:I(S)),pe((u=b.value)==null?void 0:u.defaultView,"focus",e=>{var r,l;e.target!==window&&e.target instanceof HTMLElement&&t.value===0&&(p()||o&&m&&(i.contains(e.target)||(r=n(a.beforePanelSentinel))!=null&&r.contains(e.target)||(l=n(a.afterPanelSentinel))!=null&&l.contains(e.target)||a.closePopover()))},!0),fe(i.resolveContainers,(e,r)=>{var l;a.closePopover(),be(r,me.Loose)||(e.preventDefault(),(l=n(o))==null||l.focus())},O(()=>t.value===0)),()=>{let e={open:t.value===0,close:a.close};return T(W,[T(w,{},()=>A({theirProps:{...d,...s},ourProps:{ref:f},slot:e,slots:P,attrs:s,name:"Popover"})),T(i.MainTreeNode)])}}}),Ge=j({name:"PopoverButton",props:{as:{type:[Object,String],default:"button"},disabled:{type:[Boolean],default:!1},id:{type:String,default:null}},inheritAttrs:!1,setup(d,{attrs:P,slots:s,expose:h}){var u;let f=(u=d.id)!=null?u:`headlessui-popover-button-${H()}`,t=U("PopoverButton"),o=O(()=>V(t.button));h({el:t.button,$el:t.button}),ee(()=>{t.buttonId.value=f}),te(()=>{t.buttonId.value=null});let y=ae(),v=y==null?void 0:y.closeOthers,m=ge(),b=O(()=>m===null?!1:m.value===t.panelId.value),E=R(null),a=`headlessui-focus-sentinel-${H()}`;b.value||J(()=>{t.button.value=n(E)});let S=ve(O(()=>({as:d.as,type:P.type})),E);function c(e){var r,l,g,G,C;if(b.value){if(t.popoverState.value===1)return;switch(e.key){case k.Space:case k.Enter:e.preventDefault(),(l=(r=e.target).click)==null||l.call(r),t.closePopover(),(g=n(t.button))==null||g.focus();break}}else switch(e.key){case k.Space:case k.Enter:e.preventDefault(),e.stopPropagation(),t.popoverState.value===1&&(v==null||v(t.buttonId.value)),t.togglePopover();break;case k.Escape:if(t.popoverState.value!==0)return v==null?void 0:v(t.buttonId.value);if(!n(t.button)||(G=o.value)!=null&&G.activeElement&&!((C=n(t.button))!=null&&C.contains(o.value.activeElement)))return;e.preventDefault(),e.stopPropagation(),t.closePopover();break}}function I(e){b.value||e.key===k.Space&&e.preventDefault()}function F(e){var r,l;d.disabled||(b.value?(t.closePopover(),(r=n(t.button))==null||r.focus()):(e.preventDefault(),e.stopPropagation(),t.popoverState.value===1&&(v==null||v(t.buttonId.value)),t.togglePopover(),(l=n(t.button))==null||l.focus()))}function w(e){e.preventDefault(),e.stopPropagation()}let i=oe();function p(){let e=n(t.panel);if(!e)return;function r(){K(i.value,{[M.Forwards]:()=>B(e,D.First),[M.Backwards]:()=>B(e,D.Last)})===Y.Error&&B(Z().filter(g=>g.dataset.headlessuiFocusGuard!=="true"),K(i.value,{[M.Forwards]:D.Next,[M.Backwards]:D.Previous}),{relativeTo:n(t.button)})}r()}return()=>{let e=t.popoverState.value===0,r={open:e},{...l}=d,g=b.value?{ref:E,type:S.value,onKeydown:c,onClick:F}:{ref:E,id:f,type:S.value,"aria-expanded":t.popoverState.value===0,"aria-controls":n(t.panel)?t.panelId.value:void 0,disabled:d.disabled?!0:void 0,onKeydown:c,onKeyup:I,onClick:F,onMousedown:w};return T(W,[A({ourProps:g,theirProps:{...P,...l},slot:r,attrs:P,slots:s,name:"PopoverButton"}),e&&!b.value&&t.isPortalled.value&&T(X,{id:a,features:Q.Focusable,"data-headlessui-focus-guard":!0,as:"button",type:"button",onFocus:p})])}}}),$e=j({name:"PopoverOverlay",props:{as:{type:[Object,String],default:"div"},static:{type:Boolean,default:!1},unmount:{type:Boolean,default:!0}},setup(d,{attrs:P,slots:s}){let h=U("PopoverOverlay"),f=`headlessui-popover-overlay-${H()}`,t=ne(),o=O(()=>t!==null?(t.value&N.Open)===N.Open:h.popoverState.value===0);function y(){h.closePopover()}return()=>{let v={open:h.popoverState.value===0};return A({ourProps:{id:f,"aria-hidden":!0,onClick:y},theirProps:d,slot:v,attrs:P,slots:s,features:_.RenderStrategy|_.Static,visible:o.value,name:"PopoverOverlay"})}}}),je=j({name:"PopoverPanel",props:{as:{type:[Object,String],default:"div"},static:{type:Boolean,default:!1},unmount:{type:Boolean,default:!0},focus:{type:Boolean,default:!1},id:{type:String,default:null}},inheritAttrs:!1,setup(d,{attrs:P,slots:s,expose:h}){var w;let f=(w=d.id)!=null?w:`headlessui-popover-panel-${H()}`,{focus:t}=d,o=U("PopoverPanel"),y=O(()=>V(o.panel)),v=`headlessui-focus-sentinel-before-${H()}`,m=`headlessui-focus-sentinel-after-${H()}`;h({el:o.panel,$el:o.panel}),ee(()=>{o.panelId.value=f}),te(()=>{o.panelId.value=null}),z(ue,o.panelId),J(()=>{var p,u;if(!t||o.popoverState.value!==0||!o.panel)return;let i=(p=y.value)==null?void 0:p.activeElement;(u=n(o.panel))!=null&&u.contains(i)||B(n(o.panel),D.First)});let b=ne(),E=O(()=>b!==null?(b.value&N.Open)===N.Open:o.popoverState.value===0);function a(i){var p,u;switch(i.key){case k.Escape:if(o.popoverState.value!==0||!n(o.panel)||y.value&&!((p=n(o.panel))!=null&&p.contains(y.value.activeElement)))return;i.preventDefault(),i.stopPropagation(),o.closePopover(),(u=n(o.button))==null||u.focus();break}}function S(i){var u,e,r,l,g;let p=i.relatedTarget;p&&n(o.panel)&&((u=n(o.panel))!=null&&u.contains(p)||(o.closePopover(),((r=(e=n(o.beforePanelSentinel))==null?void 0:e.contains)!=null&&r.call(e,p)||(g=(l=n(o.afterPanelSentinel))==null?void 0:l.contains)!=null&&g.call(l,p))&&p.focus({preventScroll:!0})))}let c=oe();function I(){let i=n(o.panel);if(!i)return;function p(){K(c.value,{[M.Forwards]:()=>{var e;B(i,D.First)===Y.Error&&((e=n(o.afterPanelSentinel))==null||e.focus())},[M.Backwards]:()=>{var u;(u=n(o.button))==null||u.focus({preventScroll:!0})}})}p()}function F(){let i=n(o.panel);if(!i)return;function p(){K(c.value,{[M.Forwards]:()=>{let u=n(o.button),e=n(o.panel);if(!u)return;let r=Z(),l=r.indexOf(u),g=r.slice(0,l+1),C=[...r.slice(l+1),...g];for(let L of C.slice())if(L.dataset.headlessuiFocusGuard==="true"||e!=null&&e.contains(L)){let $=C.indexOf(L);$!==-1&&C.splice($,1)}B(C,D.First,{sorted:!1})},[M.Backwards]:()=>{var e;B(i,D.Previous)===Y.Error&&((e=n(o.button))==null||e.focus())}})}p()}return()=>{let i={open:o.popoverState.value===0,close:o.close},{focus:p,...u}=d,e={ref:o.panel,id:f,onKeydown:a,onFocusout:t&&o.popoverState.value===0?S:void 0,tabIndex:-1};return A({ourProps:e,theirProps:{...P,...u},attrs:P,slot:i,slots:{...s,default:(...r)=>{var l;return[T(W,[E.value&&o.isPortalled.value&&T(X,{id:v,ref:o.beforePanelSentinel,features:Q.Focusable,"data-headlessui-focus-guard":!0,as:"button",type:"button",onFocus:I}),(l=s.default)==null?void 0:l.call(s,...r),E.value&&o.isPortalled.value&&T(X,{id:m,ref:o.afterPanelSentinel,features:Q.Focusable,"data-headlessui-focus-guard":!0,as:"button",type:"button",onFocus:F})])]}},features:_.RenderStrategy|_.Static,visible:E.value,name:"PopoverPanel"})}}}),Ae=j({name:"PopoverGroup",inheritAttrs:!1,props:{as:{type:[Object,String],default:"div"}},setup(d,{attrs:P,slots:s,expose:h}){let f=R(null),t=ie([]),o=O(()=>V(f)),y=ce();h({el:f,$el:f});function v(a){let S=t.value.indexOf(a);S!==-1&&t.value.splice(S,1)}function m(a){return t.value.push(a),()=>{v(a)}}function b(){var c;let a=o.value;if(!a)return!1;let S=a.activeElement;return(c=n(f))!=null&&c.contains(S)?!0:t.value.some(I=>{var F,w;return((F=a.getElementById(I.buttonId.value))==null?void 0:F.contains(S))||((w=a.getElementById(I.panelId.value))==null?void 0:w.contains(S))})}function E(a){for(let S of t.value)S.buttonId.value!==a&&S.close()}return z(le,{registerPopover:m,unregisterPopover:v,isFocusWithinPopoverGroup:b,closeOthers:E,mainTreeNodeRef:y.mainTreeNodeRef}),()=>T(W,[A({ourProps:{ref:f},theirProps:{...d,...P},slot:{},attrs:P,slots:s,name:"PopoverGroup"}),T(y.MainTreeNode)])}});export{ye as Popover,Ge as PopoverButton,Ae as PopoverGroup,$e as PopoverOverlay,je as PopoverPanel};