@featherk/composables 0.6.18 → 0.7.0
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 +6 -2
- package/dist/__tests__/fixtures.d.ts +9 -0
- package/dist/__tests__/withSetupHarness.d.ts +9 -0
- package/dist/date/useMaskedDateInput.test.d.ts +1 -0
- package/dist/featherk-composables.es.js +787 -779
- package/dist/featherk-composables.umd.js +1 -1
- package/dist/grid/index.d.ts +2 -1
- package/dist/{useGridA11y.d.ts → grid/useGridA11y.d.ts} +1 -1
- package/dist/grid/useGridA11y.test.d.ts +1 -0
- package/dist/grid/useGridActiveFilter.d.ts +22 -0
- package/dist/grid/useGridActiveFilter.test.d.ts +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/range/useMaskedDateRangeInput.test.d.ts +1 -0
- package/dist/time/useMaskedTimeInput.test.d.ts +1 -0
- package/dist/trap/usePopupTrap.test.d.ts +1 -0
- package/docs/grid/useGridA11y.md +31 -10
- package/docs/grid/useGridActiveFilter.md +108 -0
- package/docs/range/useMaskedDateRangeInput.md +2 -2
- package/package.json +5 -2
- package/dist/useGridFilter.d.ts +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(te,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("@vueuse/integrations/useFocusTrap")):typeof define=="function"&&define.amd?define(["exports","vue","@vueuse/integrations/useFocusTrap"],t):(te=typeof globalThis<"u"?globalThis:te||self,t(te.FeatherKComposables={},te.Vue,te.useFocusTrap))})(this,(function(te,t,Ee){"use strict";const Me=(e,n)=>{const c=t.ref(null);let U=!1,$=null,I=null;const N=[],A=".k-table-row[data-grid-row-index] [tabindex]",S=l=>l.key==="Enter"||l.code==="Enter"||l.code==="NumpadEnter",b=()=>e?.value?.columns,w=l=>{const y=l.key||l.code;([" ","Spacebar","Space"].includes(y)||S(l))&&(l.preventDefault(),l.stopPropagation(),c.value=l.target,l.target.click())},P=l=>{if(!c.value)return;if(l.code==="Escape"){l.stopPropagation(),c.value&&c.value.focus();return}const y=Array.from(document.querySelectorAll(".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item")),s=document.querySelector(".k-animation-container .k-popup .k-column-menu .k-filter-menu-container");if(s){if(l.code==="Tab"){const d=[".k-dropdownlist[tabindex='0']","input.k-input-inner:not([tabindex='-1']):not([disabled])","button:not([tabindex='-1']):not([disabled])",".k-checkbox"],g=n?.focusableMenuSelectors??d,h=Array.from(s.querySelectorAll(g.join(",")));if(h.length===0)return;const k=h.findIndex(Y=>Y===document.activeElement);let D;k===-1?D=0:l.shiftKey?D=(k-1+h.length)%h.length:D=(k+1)%h.length,l.preventDefault(),l.stopPropagation(),h[D]?.focus()}}else if(l.code==="ArrowUp"||l.code==="ArrowDown"){l.preventDefault(),l.stopPropagation();const d=y.findIndex(h=>h===document.activeElement);let g=d;l.code==="ArrowUp"?g=d>0?d-1:y.length-1:l.code==="ArrowDown"&&(g=d<y.length-1?d+1:0),y[g]?.focus();return}if(l.code==="Tab"){l.preventDefault(),l.stopPropagation();const d=c.value?.parentElement;(l.shiftKey?d?.previousElementSibling:d?.nextElementSibling)?.querySelector("button, [role='button'], .k-link")?.focus()}},x=()=>{$=new MutationObserver(l=>{l.forEach(y=>{y.addedNodes.forEach(s=>{if(s.nodeType===Node.ELEMENT_NODE){const d=s;if(d.classList.contains("k-animation-container")){const h=c.value;h&&(h.dataset.featherKSortable==="true"||t.nextTick(()=>{d.querySelectorAll(".k-columnmenu-item-wrapper").forEach(Y=>{Y.textContent?.toLowerCase().includes("sort")&&Y.remove()})})),d.addEventListener("keydown",P),t.nextTick(()=>{const k=()=>{const D=Array.from(d.querySelectorAll(".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item"));if(D.length===1)D[0].focus(),D[0].click(),k.attempts=0;else if(D.length>1){k.attempts=0;return}else k.attempts===void 0&&(k.attempts=0),k.attempts++<3&&setTimeout(k,200)};k()})}d.querySelectorAll(".k-animation-container").forEach(h=>{h.addEventListener("keydown",P)})}}),y.removedNodes.forEach(s=>{if(s.nodeType===Node.ELEMENT_NODE){const d=s;d.classList.contains("k-animation-container")&&d.removeEventListener("keydown",P),d.querySelectorAll(".k-animation-container").forEach(h=>{h.removeEventListener("keydown",P)})}})})}),$.observe(document.body,{childList:!0,subtree:!0})},M=l=>{const y=l.tagName.toLowerCase();return!!(["input","textarea","select","button"].includes(y)||l.closest('.k-picker-wrap, .k-input-inner, .k-textbox, [role="combobox"]'))},F=l=>{if(!l.type||!l)return;const y=l.target;if(y&&!M(y)){if(l.code==="Escape"){const s=document.activeElement?.closest(".k-table-row[data-grid-row-index]");if(s){l.preventDefault(),l.stopPropagation();try{Array.from(e?.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]")).forEach(g=>g.setAttribute("tabindex","-1"))}catch{}s.setAttribute("tabindex","0"),s.focus();return}}if(["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","Enter","NumpadEnter","Space"].includes(l.code)){if(y.classList.contains("k-grid-header-menu")&&y.classList.contains("k-grid-column-menu")){c.value=y;return}const s=y.closest(".k-table-row[data-grid-row-index]");if(s){if(["ArrowDown","ArrowUp"].includes(l.code)){l.preventDefault(),l.stopPropagation();const d=(h,k)=>{let D=k==="next"?h.nextElementSibling:h.previousElementSibling;for(;D;){const Y=D;try{if(Y.classList.contains("k-table-row"))return Y}catch{}D=k==="next"?D.nextElementSibling:D.previousElementSibling}return null},g=l.code==="ArrowDown"?d(s,"next"):d(s,"previous");g&&(s.setAttribute("tabindex","-1"),g.setAttribute("tabindex","0"),g.focus());return}if(["ArrowLeft","ArrowRight"].includes(l.code)){l.preventDefault(),l.stopPropagation();const d=s.querySelectorAll(A);if(d.length===0)return;let g=Array.from(d).findIndex(h=>h===document.activeElement);if(g===-1&&document.activeElement===s){d[0].focus();return}l.code==="ArrowRight"?g=g===d.length-1?0:g+1:l.code==="ArrowLeft"&&(g=g===d.length-1?g-1:d.length-1),d[g].focus();return}}}}},O=()=>{t.nextTick(()=>{const l=e.value.$el.closest(".k-grid");l&&l.classList.add("fk-grid")})},p=()=>{if(!I)try{const l=()=>{try{const d=Array.from(e.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]"));if(!d||d.length===0||d.filter(k=>k.getAttribute("tabindex")==="0").length===1)return;const h=d.find(k=>k===document.activeElement||k.contains(document.activeElement));if(d.forEach(k=>k.setAttribute("tabindex","-1")),h){h.setAttribute("tabindex","0");return}d[0].setAttribute("tabindex","0")}catch(d){console.error("ensureSingleTabindex error:",d)}},y=Array.from(e.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]"));y.length>0&&y.forEach((d,g)=>{d.setAttribute("tabindex",g===0?"0":"-1")});const s=e.value.$el.querySelector(".k-table-tbody");s&&(I=new MutationObserver(()=>{l()}),I.observe(s,{childList:!0,subtree:!0}))}catch(l){console.error("Error setting up row navigation:",l)}},v=()=>{t.nextTick(()=>{const y=document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");y&&y.forEach(s=>{s.setAttribute("role","button"),s.addEventListener("keydown",w)}),x(),G()})},R=()=>{const y=document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");y&&y.forEach(s=>{s.removeEventListener("keydown",w)}),$&&($.disconnect(),$=null),I&&(I.disconnect(),I=null),N.forEach(s=>s()),N.length=0},G=()=>{document.querySelectorAll(".k-grid-header .k-table-thead th").forEach((s,d)=>{if(s.dataset.featherKHeaderBound==="true")return;const g=s.querySelector(".k-grid-header-menu.k-grid-column-menu");if(!g)return;const h=b();if(h&&h[d]){const r=h[d].field??"";s.setAttribute("data-feather-k-field",r),s.setAttribute("data-feather-k-filterable",h[d].filterable===!1?"false":"true"),s.setAttribute("data-feather-k-sortable",h[d].sortable===!1?"false":"true")}const k=s.dataset.featherKFilterable!=="false",D=s.dataset.featherKSortable!=="false";g.setAttribute("tabindex","-1"),k||D?s.style.cursor="pointer":s.style.cursor="default",k?(s.setAttribute("tabindex","0"),s.setAttribute("role","button"),s.setAttribute("aria-haspopup","menu")):(s.setAttribute("tabindex","0"),s.setAttribute("role","columnheader"),s.removeAttribute("aria-haspopup"));const Y=r=>{r.target?.closest(".k-column-resizer")||(c.value=s,g.click())},re=r=>{if(k)c.value=s,r.preventDefault(),r.stopPropagation(),Y(r);else if(D){c.value=s;const f=s.querySelector(".k-link");f&&f.click()}};s.addEventListener("click",re),N.push(()=>{s.removeEventListener("click",re)});const oe=r=>{if((S(r)||r.code==="Space")&&(k||D)){if(r.preventDefault(),r.stopPropagation(),c.value=s,c.value.focus(),k)Y(r);else if(D){const f=s.querySelector(".k-link");f&&f.click()}}};s.addEventListener("keydown",oe,!0),N.push(()=>{s.removeEventListener("keydown",oe,!0)}),s.dataset.featherKHeaderBound="true"});const y=document.querySelector(".k-grid-header .k-table-thead");if(y&&y.dataset.featherKHeaderBound!=="true"){const s=d=>{const g=d.target.closest("th");g&&(S(d)||d.code==="Space")&&g.dataset.featherKFilterable==="false"&&g.dataset.featherKSortable==="false"&&(d.preventDefault(),d.stopImmediatePropagation())};y.addEventListener("keydown",s,!0),N.push(()=>{y.removeEventListener("keydown",s,!0)}),y.dataset.featherKHeaderBound="true"}},_=function(l,y){const s=l?.event?.event.target,d=b();if(!s||!d)return;const g=s.classList.contains("k-grid-header-menu"),h=s.classList.contains("k-columnmenu-item"),k=d.find(D=>D.field===l?.event?.field)?.sortable&&!0;if(!g){if(h&&!k){l?.event?.sort?.filter(Y=>Y.field!==l?.event?.field);return}typeof y=="function"&&t.nextTick(()=>{c.value&&c.value.focus(),y(l),t.nextTick(()=>{G()})})}},Z=()=>{if(!U)try{O(),p(),v(),U=!0}catch(l){console.error("initA11y failed:",l),R()}};return t.onBeforeUnmount(()=>{R()}),{activeFilterButton:c,handleGridKeyDown:F,handleSortChange:_,initA11y:Z}};function Te(e){const n=t.ref(""),c=t.ref(void 0),U=t.ref(!!e.debug),$=t.ref(e.dateFormat??"mm/dd/yyyy"),I=t.computed(()=>!!e.required),N=t.ref(!1),A=["ArrowUp","ArrowDown"],S=["ArrowLeft","ArrowRight"],b=t.computed(()=>(n.value??"").replace(/\D/g,"")),w=r=>r<=2?"mm":r<=5?"dd":b.value.length<=10?"yyyy":"mm",P=t.computed(()=>{const r=n.value&&n.value.substring(0,2).replace(/\D/g,"0")||"0";return parseInt(r).toString().padStart(2,"0")}),x=t.computed(()=>{const r=n.value&&n.value.substring(3,5).replace(/\D/g,"0")||"0";return parseInt(r).toString().padStart(2,"0")}),M=t.computed(()=>{const r=n.value&&n.value.substring(6,10).replace(/\D/g,"0")||"0";return parseInt(r).toString().padStart(4,"0")}),F=r=>{if(b.value.length===0){e.onChange({value:null,event:r});return}if(b.value.length<8){e.onChange({value:null,event:r});return}if((n.value??"").length===10&&b.value.length===8){const[f,T,j]=n.value.split("/"),K=parseInt(f),V=parseInt(T),X=parseInt(j);if(G(X,K,V)){const ae=new Date(X,K-1,V);O(ae)?e.onChange({value:ae,event:r}):e.onChange({value:null,event:r})}else e.onChange({value:null,event:r})}},O=r=>{const f=e.min??void 0,T=e.max??void 0;return!(f&&r<f||T&&r>T)},p=t.computed(()=>{if((n.value??"").length===10&&b.value.length===8){const[r,f,T]=(n.value??"").split("/"),j=parseInt(r),K=parseInt(f),V=parseInt(T);if(G(V,j,K))return new Date(V,j-1,K)}return null}),v=t.computed(()=>(n.value??"").length===10&&b.value.length===8),R=(r,f)=>new Date(r,f,0).getDate(),G=(r,f,T)=>f>=1&&f<=12&&r>=1900&&T>=1&&T<=R(r,f),_=r=>{n.value=r.value;const f=r.event?.target;c.value=f?.selectionStart??0,F(r)},Z=r=>{c.value=r.target.selectionStart??0},l=(r,f,T)=>{const j=f?.selectionStart??c.value??0;c.value=j;let K=parseInt(P.value),V=parseInt(x.value),X=parseInt(M.value);if(!(b.value.length>=8)||!G(X,K,V)){const W=e.defaultValue??new Date;K=W.getMonth()+1,V=W.getDate(),X=W.getFullYear(),n.value=`${String(K).padStart(2,"0")}/${String(V).padStart(2,"0")}/${String(X)}`;const q=new Date(X,K-1,V);e.onChange({value:O(q)?q:null,event:T}),h({useRAF:!0});return}const a=w(j);if(a==="mm")K=r==="ArrowUp"?K<12?K+1:1:K>1?K-1:12;else if(a==="dd"){const W=new Date(X,K,0).getDate();V=r==="ArrowUp"?V<W?V+1:1:V>1?V-1:W}else a==="yyyy"&&(X=r==="ArrowUp"?X+1:Math.max(1,X-1));n.value=`${String(K).padStart(2,"0")}/${String(V).padStart(2,"0")}/${String(X)}`;const[i,C,L]=n.value.split("/"),B=new Date(parseInt(L),parseInt(i)-1,parseInt(C));B.toString()!=="Invalid Date"&&parseInt(L)>=1e3?e.onChange({value:O(B)?B:null,event:T}):e.onChange({value:null,event:T}),h({useRAF:!0})},y=r=>{if(r.code==="Space"||r.key===" "){r.preventDefault(),r.stopPropagation(),e.onShowCalendar(r);return}if(r.key==="ArrowDown"&&r.altKey){r.preventDefault(),r.stopPropagation(),e.onShowCalendar(r);return}if(A.includes(r.key)){if(r.altKey)return;r.preventDefault(),r.stopPropagation();const f=r.target;l(r.key,f,r);return}},s=r=>{r.preventDefault();const f=r.deltaY<0?"ArrowUp":"ArrowDown";l(f,r.target,r)},d=r=>{const f=r.target;if(S.includes(r.key)){c.value=f?.selectionStart??0;return}if(A.includes(r.key)){if(r.altKey)return;c.value=f?.selectionStart??0}},g=r=>{N.value=!0,I.value&&!e.defaultValue&&e.externalValue&&e.externalValue.value===void 0&&b.value.length===0&&(e.externalValue.value="");const f=r.target;f&&(c.value=f.selectionStart??0)},h=r=>{const f=()=>{const T=document.getElementById(e.id);if(!T)return;const j=r?.pos??c.value??T.value.length;try{T.focus(),T.setSelectionRange(j,j)}catch{}};t.nextTick(()=>{if(r?.delay&&r.delay>0){setTimeout(f,r.delay);return}if(r?.useRAF){requestAnimationFrame(f);return}f()})};e.externalValue&&t.watch(e.externalValue,r=>{if(r){const f=new Date(r);if(f.toString()!=="Invalid Date"){const T=(f.getMonth()+1).toString().padStart(2,"0"),j=f.getDate().toString().padStart(2,"0"),K=f.getFullYear().toString();n.value=`${T}/${j}/${K}`,h({delay:50});return}}},{immediate:!0});const k=t.computed(()=>[["Date",`${P.value} / ${x.value} / ${M.value}`],["Digits only",b.value],["min",e.min?.toLocaleDateString("en-US",{year:"numeric",month:"2-digit",day:"2-digit"})??null],["max",e.max?.toLocaleDateString("en-US",{year:"numeric",month:"2-digit",day:"2-digit"})??null]]),D=t.computed(()=>{if(!I.value){if(!v.value)return!0;const f=p.value;return f?O(f):!1}if(!N.value)return!0;const r=p.value;return!v.value||!r?!1:O(r)}),Y=t.computed(()=>{if(!I.value){if(!v.value)return;const f=p.value;return f?O(f)?"valid":"out-of-bounds":"invalid-date"}if(!N.value)return;if(b.value.length===0||!v.value)return"incomplete";const r=p.value;return r?O(r)?"valid":"out-of-bounds":"invalid-date"}),re=t.computed(()=>{const r=Y.value;if(!r||r==="valid")return"";if(r==="incomplete")return"Required";if(r==="invalid-date")return`Must be in ${$.value} format.`;const f=e.min?e.min.toLocaleDateString("en-US",{year:"numeric",month:"2-digit",day:"2-digit"}):null,T=e.max?e.max.toLocaleDateString("en-US",{year:"numeric",month:"2-digit",day:"2-digit"}):null;if(r==="out-of-bounds"){if(f&&T)return`Must be between ${f} and ${T}.`;if(f)return`Must be on or after ${f}.`;if(T)return`Must be on or before ${T}.`}return""}),oe=()=>{t.nextTick(()=>{const r=document.getElementById(e.id);if(!r){console.warn(`ID (#${e.id}) not found for styling.`);return}const f=r.closest(".k-datepicker");if(!f){console.warn(`.k-datepicker parent not found for #${e.id} styling.`);return}const T=f.parentElement;if(T){if(T.classList.contains("fk-datepicker"))return;T.classList.add("fk-datepicker")}else console.warn(`Parent of .k-datepicker not found for #${e.id} styling.`)})};return t.onMounted(()=>{oe()}),{raw:n,cursorPos:c,debugEnabled:U,debugLines:k,placeholder:$,isValid:D,reason:t.readonly(Y),validationMessage:re,digitsOnly:b,month:t.readonly(P),day:t.readonly(x),year:t.readonly(M),datePart:w,handleChange:_,handleKeyDown:y,handleWheel:s,handleKeyUp:d,handleClick:Z,handleBlur:g,initStyling:oe}}function Ce(e){const n=t.ref(""),c=t.ref(void 0),U=t.ref(!!e.debug),$=t.ref(!1),I=1440*60*1e3,N=365*I,A=new Date,S=new Date(A.getTime()-N),b=new Date(A.getTime()+N);e.min=e.min??S,e.max=e.max??b;const w=t.computed(()=>(n.value??"").replace(/\D/g,"")),P=(o,u)=>new Date(o,u,0).getDate(),x=(o,u,m)=>u>=1&&u<=12&&o>=1e3&&m>=1&&m<=P(o,u),M=o=>Date.UTC(o.getFullYear(),o.getMonth(),o.getDate()),F=o=>{if(!o)return null;const u=e.min??new Date(Date.now()-90*I),m=e.max??new Date,E=M(o);return E<M(u)||E>M(m)?null:o},O=(o,u)=>e.allowReverse??!1?!0:o<=u,p=t.computed(()=>(n.value?.length??0)>=23&&w.value.length>=16),v=o=>{if((o??"").length<23||w.value.length<16)return{start:null,end:null};const u=o.substring(0,10),m=o.substring(13,23),[E,J,Q]=u.split("/").map(se=>parseInt(se||"0",10)),[ie,ce,de]=m.split("/").map(se=>parseInt(se||"0",10)),fe=new Date(Q,E-1,J),ye=new Date(de,ie-1,ce),Se=x(Q,E,J)&&fe.toString()!=="Invalid Date",be=x(de,ie,ce)&&ye.toString()!=="Invalid Date";return{start:Se?fe:null,end:be?ye:null}},R=e.externalValid??t.ref(!0),G=t.computed(()=>v(n.value)),_=t.computed(()=>{const o=F(G.value.start),u=F(G.value.end);return{start:o,end:u}}),Z=t.computed(()=>{if(!p.value)return;const o=_.value.start,u=_.value.end;if(!o||!u)return;const m=Math.abs(M(u)-M(o));return Math.round(m/864e5+1)}),l=t.computed(()=>{if(!p.value)return!1;const{start:o,end:u}=G.value;if(!o||!u||!_.value.start||!_.value.end)return!1;const m=_.value.start,E=_.value.end;return!(!O(m,E)||typeof e.maxSpanDays=="number"&&Z.value!==void 0&&Z.value>e.maxSpanDays)}),y=t.computed(()=>{const{start:o,end:u}=G.value;if(!p.value)return"incomplete";if(!o||!u)return"invalid-date";if(!_.value.start||!_.value.end)return"out-of-bounds";const m=_.value.start,E=_.value.end;return O(m,E)?typeof e.maxSpanDays=="number"&&Z.value!==void 0&&Z.value>e.maxSpanDays?"span-exceeds-limit":"valid":"reversed-range"}),s=t.ref(void 0),d=t.computed(()=>{if(R.value!==!1)return"";const{min:o,max:u}=e,m=s.value;if(!m)return"";switch(m){case"incomplete":return"Required";case"invalid-date":return"One or both dates invalid.";case"reversed-range":return"End Date must be on or after Start Date.";case"out-of-bounds":return o&&u?`Dates must be between ${D(o)} and ${D(u)}.`:"Dates must be within the allowed range.";case"span-exceeds-limit":return typeof e.maxSpanDays=="number"?`Date range exceeds ${e.maxSpanDays} days.`:"Date range exceeds maximum allowed span.";default:return""}}),g=["ArrowUp","ArrowDown"],h=["ArrowLeft","ArrowRight"],k=(o,u)=>String(o).padStart(u,"0"),D=o=>`${k(o.getMonth()+1,2)}/${k(o.getDate(),2)}/${k(o.getFullYear(),4)}`,Y=o=>o<=2?{side:"start",part:"mm"}:o<=5?{side:"start",part:(o<=3,"dd")}:o<=11?{side:"start",part:"yyyy"}:o<=15?{side:"end",part:"mm"}:o<=18?{side:"end",part:"dd"}:{side:"end",part:"yyyy"},re=(o,u,m)=>{const E=u?.selectionStart??c.value??0;c.value=E;const{start:J,end:Q}=v(n.value);if(!J&&!Q){const H=new Date,le=D(H);n.value=`${le} - ${le}`,e.onChange({value:{start:H,end:H},event:m}),t.nextTick(()=>{requestAnimationFrame(()=>{const ee=document.getElementById(e.id),ne=c.value??0;ee&&(ee.focus(),ee.setSelectionRange(ne,ne))})});return}const ie=new Date,ce=Y(E);let de=J?new Date(J):new Date(ie),fe=Q?new Date(Q):new Date(ie);const ye=(H,le)=>{if(le==="mm"){const ee=H.getMonth()+1,ne=o==="ArrowUp"?ee<12?ee+1:1:ee>1?ee-1:12;H.setMonth(ne-1);const ge=P(H.getFullYear(),ne);H.getDate()>ge&&H.setDate(ge)}else if(le==="dd"){const ee=P(H.getFullYear(),H.getMonth()+1),ne=H.getDate(),ge=o==="ArrowUp"?ne<ee?ne+1:1:ne>1?ne-1:ee;H.setDate(ge)}else if(le==="yyyy"){const ee=H.getFullYear();H.setFullYear(o==="ArrowUp"?ee+1:Math.max(1,ee-1));const ne=P(H.getFullYear(),H.getMonth()+1);H.getDate()>ne&&H.setDate(ne)}};ce.side==="start"?ye(de,ce.part):ye(fe,ce.part);const Se=D(de),be=D(fe);n.value=`${Se} - ${be}`;const se=F(de),we=F(fe);se&&we&&O(se,we)?e.onChange({value:{start:se,end:we},event:m}):e.onChange({value:null,event:m}),t.nextTick(()=>{requestAnimationFrame(()=>{const H=document.getElementById(e.id),le=c.value??0;H&&(H.focus(),H.setSelectionRange(le,le))})})},oe=o=>{const{start:u,end:m}=v(n.value);if(!u||!m){e.onChange({value:null,event:o});return}const E=F(u),J=F(m);if(!E||!J){e.onChange({value:null,event:o});return}if(!O(E,J)){e.onChange({value:null,event:o});return}e.onChange({value:{start:E,end:J},event:o})},r=o=>{const u=o.value??"",m=o.event;if(!u&&m&&m.type==="click"){ae(m);return}n.value=u;const E=m?.target;c.value=E?.selectionStart??0,oe(o)},f=o=>{c.value=o.target.selectionStart??0},T=o=>{if(o.code==="Space"||o.key===" "){o.preventDefault(),o.stopPropagation(),e.onShowCalendar(o);return}if(o.key==="ArrowDown"&&o.altKey){o.preventDefault(),o.stopPropagation(),e.onShowCalendar(o);return}if(g.includes(o.key)){o.preventDefault(),o.stopPropagation();const u=o.target;re(o.key,u,o);return}},j=o=>{o.preventDefault();const u=o.deltaY<0?"ArrowUp":"ArrowDown";re(u,o.target,o)},K=o=>{if(h.includes(o.key)||g.includes(o.key)){const u=o.target;c.value=u?.selectionStart??0}},V=()=>{s.value=y.value,(e.manageValid??!0)&&(R.value=l.value)},X=o=>{V()},ae=o=>{console.log("Clear event:",o),n.value="",c.value=0,e.onChange({value:null,event:o}),V(),t.nextTick(()=>{const u=document.getElementById(e.id);u&&(u.focus(),u.setSelectionRange(0,0))})};e.externalValue&&t.watch(e.externalValue,o=>{const u=o?.start??null,m=o?.end??null;if(u&&m){if(n.value=`${D(u)} - ${D(m)}`,e.isOpen?.value&&$.value&&e.onRequestClose){const E=typeof e.closeDelay=="number"?e.closeDelay:e.closeDelay?.value??0;setTimeout(()=>{e.onRequestClose?.(),$.value=!1,V()},E)}return}},{immediate:!0});const a=t.computed(()=>n.value&&n.value.substring(0,2).replace(/\D/g,"0")||"0"),i=t.computed(()=>n.value&&n.value.substring(3,5).replace(/\D/g,"0")||"0"),C=t.computed(()=>n.value&&n.value.substring(6,10).replace(/\D/g,"0")||"0"),L=t.computed(()=>n.value&&n.value.substring(13,15).replace(/\D/g,"0")||"0"),B=t.computed(()=>n.value&&n.value.substring(16,18).replace(/\D/g,"0")||"0"),W=t.computed(()=>n.value&&n.value.substring(19,23).replace(/\D/g,"0")||"0"),q=t.computed(()=>{const{start:o,end:u}=v(n.value);return[{label:"Raw",value:n.value},{label:"Min Date",value:`${e.min?e.min.toDateString():"-"}`},{label:"Max Date",value:`${e.max?e.max.toDateString():"-"}`},{label:"Start",value:`${String(a.value).padStart(2,"0")} / ${String(i.value).padStart(2,"0")} / ${String(C.value).padStart(4,"0")}`},{label:"End",value:`${String(L.value).padStart(2,"0")} / ${String(B.value).padStart(2,"0")} / ${String(W.value).padStart(4,"0")}`},{label:"Digits only",value:w.value},{label:"Mask complete",value:`${p.value}`},{label:"Parsed",value:`${o?o.toDateString():"-"} | ${u?u.toDateString():"-"}`},{label:"Valid (managed)",value:`${R.value??"-"}`},{label:"Span (days)",value:`${Z.value??"-"}`},{label:"Reason",value:`${y.value??"-"}`},{label:"Cursor in",value:`${c.value??"-"} (${(()=>{const m=c.value??0,E=Y(m);return`${E.side}.${E.part}`})()})`}]}),z=()=>{t.nextTick(()=>{const o=document.getElementById(e.id);if(!o){console.warn(`#${e.id} not found for styling.`);return}const u=o.closest("div");if(!u){console.warn(`Parent div of #${e.id} not found for styling.`);return}u.classList.contains("fk-daterangepicker")||u.classList.add("fk-daterangepicker")})};t.onMounted(()=>{z()});const me=()=>{t.nextTick(()=>{try{const o=Array.from(document.querySelectorAll(".k-animation-container"));if(!o.length)return;const m=[...o].reverse().find(Q=>Q.querySelector(".k-calendar"))?.querySelector(".k-calendar");if(!m)return;const E=m.querySelectorAll(".k-calendar-table");let J=!1;E.forEach(Q=>{Q.tabIndex===0&&(J?Q.tabIndex=-1:J=!0)})}catch(o){console.warn(o)}})};return e.isOpen&&t.watch(e.isOpen,o=>{o&&setTimeout(()=>me(),0)},{immediate:!1}),{raw:n,cursorPos:c,debugEnabled:U,debugLines:q,digitsOnly:w,valid:R,validComputed:t.readonly(l),reason:t.readonly(y),validationMessage:t.readonly(d),spanDays:t.readonly(Z),month1:t.readonly(a),day1:t.readonly(i),year1:t.readonly(C),month2:t.readonly(L),day2:t.readonly(B),year2:t.readonly(W),handleChange:r,handleKeyDown:T,handleWheel:j,handleKeyUp:K,handleClick:f,handleBlur:X,handleClear:ae,onCalendarChange:()=>{$.value=!0},initStyling:z}}function $e(e){const n=t.ref(""),c=t.ref(void 0),U=t.ref(!!e.debug),$=t.ref(e.timeFormat??"hh:mm AM"),I=t.computed(()=>!!e.required),N=t.ref(!1),A=["ArrowUp","ArrowDown"],S=["ArrowLeft","ArrowRight"],b=t.computed(()=>(n.value??"").replace(/\D/g,"")),w={H:/[0-9]/,h:/[0-9]/,M:/[0-9]/,m:/[0-9]/,A:/[AaPp]/,a:/[Mm]/},P=a=>a<=2?"hh":a<=5?"mm":"ampm",x=t.computed(()=>{const a=n.value&&n.value.substring(0,2).replace(/\D/g,"0")||"0",i=parseInt(a);return Math.min(Math.max(i,0),23)}),M=t.computed(()=>{const a=n.value&&n.value.substring(3,5).replace(/\D/g,"0")||"0",i=parseInt(a);return Math.min(Math.max(i,0),59)}),F=t.computed(()=>(n.value?.substring(6,8)||"AM").toUpperCase().startsWith("P")?"PM":"AM"),O=t.computed(()=>{const a=parseInt(n.value?.substring(0,2).replace(/\D/g,"0")||"0"),i=F.value;return a===12?i==="AM"?0:12:i==="PM"?a+12:a}),p=t.computed(()=>v.value?`${String(O.value).padStart(2,"0")}:${String(M.value).padStart(2,"0")}:00`:null),v=t.computed(()=>/^(\d{2}):(\d{2})\s([AP]M)$/i.test(n.value??"")),R=(a,i,C)=>{let L=a%12;return L===0&&(L=12),`${String(L).padStart(2,"0")}:${String(i).padStart(2,"0")} ${C}`},G=a=>{const i=a.match(/^(\d{2}):(\d{2})\s([AP]M)$/i);if(!i)return null;const C=parseInt(i[1]),L=parseInt(i[2]),B=i[3].toUpperCase();if(C<1||C>12||L<0||L>59)return null;let W=C%12;B==="PM"&&(W+=12);const q=new Date;return q.setSeconds(0,0),q.setHours(W),q.setMinutes(L),q},_=a=>{if(b.value.length===0){e.onChange({value:null,event:a});return}if(!v.value){e.onChange({value:null,event:a});return}const i=G(n.value);i&&l(i)?e.onChange({value:i,event:a}):e.onChange({value:null,event:a})},Z=a=>a.getHours()*60+a.getMinutes(),l=a=>{const i=e.min??void 0,C=e.max??void 0,L=Z(a);if(i){const B=Z(i);if(L<B)return!1}if(C){const B=Z(C);if(L>B)return!1}return!0},y=a=>{const i=a.getHours(),C=i>=12?"PM":"AM";n.value=R(i,a.getMinutes(),C)},s=(a,i)=>{e.onChange({value:a,event:i})},d=()=>{t.nextTick(()=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{const a=document.getElementById(e.id);if(a){a.focus();const i=(a.value??"").length;a.setSelectionRange(i,i)}})})})},g=a=>{const i=a?.event?.target;return i?i.closest(".k-time-now")?"now":i.closest(".k-time-accept")?"set":null:null},h=(a,i)=>{a&&l(a)?s(a,i):s(null,i)},k=(...a)=>{const i=a[0];if(!i)return;const C=g(i);if(C==="now"){const B=new Date;y(B),h(B,i),d();return}if(i?.value instanceof Date){const B=new Date(i.value);y(B),h(B,i),C==="set"&&d();return}if(i?.value===null){n.value="",s(null,i);return}n.value=i.value;const L=i.event?.target;c.value=L?.selectionStart??0;try{const B=c.value??0;if(P(B)==="ampm"&&(n.value??"").length>=8){const W=n.value.charAt(6);/[Aa]/.test(W)?(n.value=`${n.value.slice(0,6)}AM${n.value.slice(8)}`,t.nextTick(()=>{requestAnimationFrame(()=>{const q=document.getElementById(e.id);q&&(q.focus(),q.setSelectionRange(8,8))})})):/[Pp]/.test(W)&&(n.value=`${n.value.slice(0,6)}PM${n.value.slice(8)}`,t.nextTick(()=>{requestAnimationFrame(()=>{const q=document.getElementById(e.id);q&&(q.focus(),q.setSelectionRange(8,8))})}))}}catch{}_(i)},D=a=>{c.value=a.target.selectionStart??0},Y=(a,i,C)=>{const L=i?.selectionStart??c.value??0;c.value=L;const B=P(L),W=(n.value??"").match(/^(\d{2}):(\d{2})\s([AP]M)$/i);if(!W){if((n.value??"").length===0||b.value.length===0){const u=new Date,m=u.getHours(),E=m>=12?"PM":"AM";n.value=R(m,u.getMinutes(),E);const J=G(n.value);h(J,C),t.nextTick(()=>{requestAnimationFrame(()=>{const Q=document.getElementById(e.id),ie=c.value??0;Q&&(Q.focus(),Q.setSelectionRange(ie,ie))})})}return}let q=parseInt(W[1]),z=parseInt(W[2]),me=W[3].toUpperCase();if(B==="hh")a==="ArrowUp"?q=q<12?q+1:1:q=q>1?q-1:12;else if(B==="mm"){const u=e.minuteStepRef?.value??e.minuteStep??1;if(u===1)a==="ArrowUp"?z=z<59?z+1:0:z=z>0?z-1:59;else if(a==="ArrowUp"){const m=z%u;let E=m===0?z+u:z+(u-m);E>=60&&(E=0),z=E}else{const m=z%u;let E=m===0?z-u:z-m;E<0&&(E=60-u),z=E}}else B==="ampm"&&(me=me==="AM"?"PM":"AM");n.value=`${String(q).padStart(2,"0")}:${String(z).padStart(2,"0")} ${me}`;const o=G(n.value);h(o,C),t.nextTick(()=>{requestAnimationFrame(()=>{const u=document.getElementById(e.id),m=c.value??0;u&&(u.focus(),u.setSelectionRange(m,m))})})},re=a=>{if(a.code==="Space"||a.key===" "){a.preventDefault(),a.stopPropagation(),e.onShowPicker(a);return}if(a.key==="ArrowDown"&&a.altKey){a.preventDefault(),a.stopPropagation(),e.onShowPicker(a);return}if(A.includes(a.key)){if(a.altKey)return;a.preventDefault(),a.stopPropagation();const i=a.target;Y(a.key,i,a);return}},oe=a=>{a.preventDefault();const i=a.deltaY<0?"ArrowUp":"ArrowDown";Y(i,a.target,a)},r=a=>{const i=a.target;if(S.includes(a.key)){c.value=i?.selectionStart??0;return}if(A.includes(a.key)){if(a.altKey)return;c.value=i?.selectionStart??0}},f=a=>{N.value=!0,I.value&&e.externalValue&&e.externalValue.value===void 0&&b.value.length===0&&(e.externalValue.value="");const i=a.target;i&&(c.value=i.selectionStart??0)};e.externalValue&&t.watch(e.externalValue,a=>{if(a){const i=new Date(a);if(i.toString()!=="Invalid Date"){const C=i.getHours(),L=C>=12?"PM":"AM";n.value=R(C,i.getMinutes(),L);return}}},{immediate:!0});const T=t.computed(()=>[["Time",n.value||"--:-- --"],["Hour (12h)",x.value],["Hour (24h)",O.value],["Minute",M.value],["Period",F.value],["Time (24h)",p.value??"--:--:--"],["Digits only",b.value],["Parsed Date",j.value?.toLocaleDateString("en-US",{hour:"2-digit",minute:"2-digit"})??null],["min",e.min?.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit"})??null],["max",e.max?.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit"})??null],["valid",K.value],["reason",V.value],["validationMessage",X.value]]),j=t.computed(()=>G(n.value)??null),K=t.computed(()=>{if(!I.value){if(!v.value)return!0;const i=j.value;return i?l(i):!1}if(!N.value)return!0;const a=j.value;return!v.value||!a?!1:l(a)}),V=t.computed(()=>{if(!I.value){if(!v.value)return;const i=j.value;return i?l(i)?"valid":"out-of-bounds":"invalid-time"}if(!N.value)return;if(b.value.length===0||!v.value)return"incomplete";const a=j.value;return a?l(a)?"valid":"out-of-bounds":"invalid-time"}),X=t.computed(()=>{const a=V.value;if(!a||a==="valid")return"";if(a==="incomplete")return"Required";if(a==="invalid-time")return`Must be in ${$.value} format.`;const i={hour:"2-digit",minute:"2-digit"},C=e.min?e.min.toLocaleTimeString("en-US",i):null,L=e.max?e.max.toLocaleTimeString("en-US",i):null;if(a==="out-of-bounds"){if(C&&L)return`Must be between ${C} and ${L}.`;if(C)return`Must be ${C} or later.`;if(L)return`Must be ${L} or earlier.`}return""}),ae=()=>{t.nextTick(()=>{const a=document.getElementById(e.id);if(!a){console.warn(`#${e.id} not found for styling.`);return}const i=a.closest(".k-timepicker");if(!i){console.warn(`.k-timepicker parent of #${e.id} not found for styling.`);return}const C=i.parentElement;if(!C){console.warn(`Parent of .k-timepicker not found for #${e.id} styling.`);return}C.classList.contains("fk-timepicker")||C.classList.add("fk-timepicker")})};return t.onMounted(()=>{ae()}),{raw:n,rules:w,debugEnabled:U,debugLines:T,placeholder:$,isValid:K,reason:t.readonly(V),validationMessage:X,isComplete:v,inRangeTime:l,cursorPos:c,hour:t.readonly(x),hour24:t.readonly(O),minute:t.readonly(M),period:t.readonly(F),time24:t.readonly(p),parsedRawTime:t.readonly(j),handleChange:k,handleKeyDown:re,handleKeyUp:r,handleClick:D,handleWheel:oe,handleBlur:f,initStyling:ae}}function Pe(e){return t.getCurrentScope()?(t.onScopeDispose(e),!0):!1}const ke=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Ie=Object.prototype.toString,Fe=e=>Ie.call(e)==="[object Object]",ue=()=>{},Le=Re();function Re(){var e,n;return ke&&((e=window?.navigator)==null?void 0:e.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((n=window?.navigator)==null?void 0:n.maxTouchPoints)>2&&/iPad|Macintosh/.test(window?.navigator.userAgent))}function he(e){return Array.isArray(e)?e:[e]}function qe(e,n,c){return t.watch(e,n,{...c,immediate:!0})}const De=ke?window:void 0;function pe(e){var n;const c=t.toValue(e);return(n=c?.$el)!=null?n:c}function ve(...e){const n=[],c=()=>{n.forEach(A=>A()),n.length=0},U=(A,S,b,w)=>(A.addEventListener(S,b,w),()=>A.removeEventListener(S,b,w)),$=t.computed(()=>{const A=he(t.toValue(e[0])).filter(S=>S!=null);return A.every(S=>typeof S!="string")?A:void 0}),I=qe(()=>{var A,S;return[(S=(A=$.value)==null?void 0:A.map(b=>pe(b)))!=null?S:[De].filter(b=>b!=null),he(t.toValue($.value?e[1]:e[0])),he(t.unref($.value?e[2]:e[1])),t.toValue($.value?e[3]:e[2])]},([A,S,b,w])=>{if(c(),!A?.length||!S?.length||!b?.length)return;const P=Fe(w)?{...w}:w;n.push(...A.flatMap(x=>S.flatMap(M=>b.map(F=>U(x,M,F,P)))))},{flush:"post"}),N=()=>{I(),c()};return Pe(c),N}let Ae=!1;function Ue(e,n,c={}){const{window:U=De,ignore:$=[],capture:I=!0,detectIframe:N=!1,controls:A=!1}=c;if(!U)return A?{stop:ue,cancel:ue,trigger:ue}:ue;if(Le&&!Ae){Ae=!0;const p={passive:!0};Array.from(U.document.body.children).forEach(v=>v.addEventListener("click",ue,p)),U.document.documentElement.addEventListener("click",ue,p)}let S=!0;const b=p=>t.toValue($).some(v=>{if(typeof v=="string")return Array.from(U.document.querySelectorAll(v)).some(R=>R===p.target||p.composedPath().includes(R));{const R=pe(v);return R&&(p.target===R||p.composedPath().includes(R))}});function w(p){const v=t.toValue(p);return v&&v.$.subTree.shapeFlag===16}function P(p,v){const R=t.toValue(p),G=R.$.subTree&&R.$.subTree.children;return G==null||!Array.isArray(G)?!1:G.some(_=>_.el===v.target||v.composedPath().includes(_.el))}const x=p=>{const v=pe(e);if(p.target!=null&&!(!(v instanceof Element)&&w(e)&&P(e,p))&&!(!v||v===p.target||p.composedPath().includes(v))){if("detail"in p&&p.detail===0&&(S=!b(p)),!S){S=!0;return}n(p)}};let M=!1;const F=[ve(U,"click",p=>{M||(M=!0,setTimeout(()=>{M=!1},0),x(p))},{passive:!0,capture:I}),ve(U,"pointerdown",p=>{const v=pe(e);S=!b(p)&&!!(v&&!p.composedPath().includes(v))},{passive:!0}),N&&ve(U,"blur",p=>{setTimeout(()=>{var v;const R=pe(e);((v=U.document.activeElement)==null?void 0:v.tagName)==="IFRAME"&&!R?.contains(U.document.activeElement)&&n(p)},0)},{passive:!0})].filter(Boolean),O=()=>F.forEach(p=>p());return A?{stop:O,cancel:()=>{S=!1},trigger:p=>{S=!0,x(p),S=!1}}:O}function Oe(e){const n=t.shallowRef(null),c=[".k-animation-container .k-popup",".k-popup",".k-timepicker-popup",".k-menu-popup"],U=Array.isArray(e.popupSelector)?e.popupSelector:[e.popupSelector??c].flat(),$=w=>w?typeof e.initialFocus=="string"?w.querySelector(e.initialFocus)??w:typeof e.initialFocus=="function"?e.initialFocus(w)??w:w.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')??w:null,{activate:I,deactivate:N}=Ee.useFocusTrap(n,{escapeDeactivates:!1,clickOutsideDeactivates:!1,fallbackFocus:()=>n.value,initialFocus:()=>$(n.value),...e.focusTrapOptions??{}});let A=null,S=t.ref(null);const b=()=>{if(e.resolvePopupEl)return e.resolvePopupEl();const w=(x,M)=>{const F=Array.from(x.querySelectorAll(M));if(!F.length)return null;const O=F.filter(p=>p.offsetParent!==null||p.getClientRects().length>0);return O[O.length-1]??F[F.length-1]??null},P=e.triggerEl?.value?.closest?.(".k-animation-container")??document.body;for(const x of U){const M=w(P,x);if(M)return M}for(const x of U){const M=w(document,x);if(M)return M}return null};return Ue(n,w=>{S.value="outside",e.isOpen.value&&e.onRequestClose?.("outside",w)}),t.watch(()=>e.isOpen.value,w=>{w?(S.value=null,t.nextTick(()=>{const P=b();P&&(n.value=P,setTimeout(()=>I(),0),A||(A=x=>{x.key==="Escape"&&(S.value="escape",e.isOpen.value&&e.onRequestClose?.("escape",x))},document.addEventListener("keydown",A,!0)))})):(N(),A&&(document.removeEventListener("keydown",A,!0),A=null),n.value=null,S.value==="outside"&&t.nextTick(()=>{const P=()=>{const x=e.triggerEl?.value,M=x?.querySelector("input"),F=document.activeElement;F&&(F===M||x&&x.contains(F))&&(M??x)?.blur?.()};requestAnimationFrame(()=>setTimeout(P,0))}),e.returnFocusToTrigger!==!1&&S.value==="escape"&&e.triggerEl?.value&&(console.log("Returning focus to trigger element:",e.triggerEl.value),t.nextTick(()=>{const P=()=>{const x=e.triggerEl?.value;if(!x)return;(x.querySelector("input")??x)?.focus?.()};requestAnimationFrame(()=>setTimeout(P,0))})))}),{popupRef:n,activate:I,deactivate:N,lastCloseReason:t.readonly(S),setPopupEl:w=>n.value=w}}const Ke=e=>!!e&&typeof e=="object"&&"filters"in e&&Array.isArray(e.filters),Ve=e=>!!e&&typeof e=="object"&&"field"in e,xe=(e,n)=>!e||typeof e!="object"?!1:Ke(e)?e.filters.some(c=>xe(c,n)):Ve(e)?e.field===n:!1,Be=e=>{const n=t.ref({}),c=$=>!e.value||!e.value.filters?!1:e.value.filters.some(I=>xe(I,$));return{activeClasses:n,hasFieldFilter:c,updateActiveClass:$=>{const I=c($);console.log("updateActiveClass for",$,"hasFilter:",I),n.value[$]=I?"active":"",console.log("activeClasses after update",n.value)}}};te.useGridA11y=Me,te.useGridFilter=Be,te.useMaskedDateInput=Te,te.useMaskedDateRangeInput=Ce,te.useMaskedTimeInput=$e,te.usePopupTrap=Oe,Object.defineProperty(te,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(ne,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("@vueuse/integrations/useFocusTrap")):typeof define=="function"&&define.amd?define(["exports","vue","@vueuse/integrations/useFocusTrap"],t):(ne=typeof globalThis<"u"?globalThis:ne||self,t(ne.FeatherKComposables={},ne.Vue,ne.useFocusTrap))})(this,(function(ne,t,Ee){"use strict";const Me=(e,n)=>{const c=t.ref(null);let N=!1,q=null,U=null;const H=[],E=".k-table-row[data-grid-row-index] [tabindex]",D=()=>{const l=e?.value?.$el;return l?l.closest(".k-grid"):null},w=l=>{const y=D();if(!y)return!1;const s=l.closest(".k-grid-aria-root");if(s)return y.contains(s);const d=l.closest(".k-grid-header, .k-grid-content, .k-grid-content-locked");return d?y.contains(d):!1},k=l=>l.key==="Enter"||l.code==="Enter"||l.code==="NumpadEnter",$=()=>e?.value?.columns,A=l=>{const y=l.key||l.code;([" ","Spacebar","Space"].includes(y)||k(l))&&(l.preventDefault(),l.stopPropagation(),c.value=l.target,l.target.click())},x=l=>{if(!c.value)return;if(l.code==="Escape"){l.stopPropagation(),c.value&&c.value.focus();return}const y=Array.from(document.querySelectorAll(".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item")),s=document.querySelector(".k-animation-container .k-popup .k-column-menu .k-filter-menu-container");if(s){if(l.code==="Tab"){const d=[".k-dropdownlist[tabindex='0']","input.k-input-inner:not([tabindex='-1']):not([disabled])","button:not([tabindex='-1']):not([disabled])",".k-checkbox"],v=n?.focusableMenuSelectors??d,p=Array.from(s.querySelectorAll(v.join(",")));if(p.length===0)return;const S=p.findIndex(G=>G===document.activeElement);let P;S===-1?P=0:l.shiftKey?P=(S-1+p.length)%p.length:P=(S+1)%p.length,l.preventDefault(),l.stopPropagation(),p[P]?.focus()}}else if(l.code==="ArrowUp"||l.code==="ArrowDown"){l.preventDefault(),l.stopPropagation();const d=y.findIndex(p=>p===document.activeElement);let v=d;l.code==="ArrowUp"?v=d>0?d-1:y.length-1:l.code==="ArrowDown"&&(v=d<y.length-1?d+1:0),y[v]?.focus();return}if(l.code==="Tab"){l.preventDefault(),l.stopPropagation();const d=c.value?.parentElement;(l.shiftKey?d?.previousElementSibling:d?.nextElementSibling)?.querySelector("button, [role='button'], .k-link")?.focus()}},C=()=>{q=new MutationObserver(l=>{l.forEach(y=>{y.addedNodes.forEach(s=>{if(s.nodeType===Node.ELEMENT_NODE){const d=s;if(d.classList.contains("k-animation-container")){const p=c.value;p&&(p.dataset.featherKSortable==="true"||t.nextTick(()=>{d.querySelectorAll(".k-columnmenu-item-wrapper").forEach(G=>{G.textContent?.toLowerCase().includes("sort")&&G.remove()})})),d.addEventListener("keydown",x),t.nextTick(()=>{const S=()=>{const P=Array.from(d.querySelectorAll(".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item"));if(P.length===1)P[0].focus(),P[0].click(),S.attempts=0;else if(P.length>1){S.attempts=0;return}else S.attempts===void 0&&(S.attempts=0),S.attempts++<3&&setTimeout(S,200)};S()})}d.querySelectorAll(".k-animation-container").forEach(p=>{p.addEventListener("keydown",x)})}}),y.removedNodes.forEach(s=>{if(s.nodeType===Node.ELEMENT_NODE){const d=s;d.classList.contains("k-animation-container")&&d.removeEventListener("keydown",x),d.querySelectorAll(".k-animation-container").forEach(p=>{p.removeEventListener("keydown",x)})}})})}),q.observe(document.body,{childList:!0,subtree:!0})},O=l=>{const y=l.tagName.toLowerCase();return!!(["input","textarea","select","button"].includes(y)||l.closest('.k-picker-wrap, .k-input-inner, .k-textbox, [role="combobox"]'))},m=l=>{if(!l.type||!l)return;const y=l.target;if(!y)return;const s=y.closest(".k-table-row[data-grid-row-index]");if(!w(y))return;const d=["ArrowLeft","ArrowRight"].includes(l.code);if(!(O(y)&&!(s&&d))){if(l.code==="Escape"){const v=document.activeElement?.closest(".k-table-row[data-grid-row-index]");if(v){l.preventDefault(),l.stopPropagation();try{Array.from(e?.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]")).forEach(S=>S.setAttribute("tabindex","-1"))}catch{}v.setAttribute("tabindex","0"),v.focus();return}}if(["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","Enter","NumpadEnter","Space"].includes(l.code)){if(y.classList.contains("k-grid-header-menu")&&y.classList.contains("k-grid-column-menu")){c.value=y;return}if(s){if(["ArrowDown","ArrowUp"].includes(l.code)){l.preventDefault(),l.stopPropagation();const v=(S,P)=>{let G=P==="next"?S.nextElementSibling:S.previousElementSibling;for(;G;){const a=G;try{if(a.classList.contains("k-table-row"))return a}catch{}G=P==="next"?G.nextElementSibling:G.previousElementSibling}return null},p=l.code==="ArrowDown"?v(s,"next"):v(s,"previous");p&&(s.setAttribute("tabindex","-1"),p.setAttribute("tabindex","0"),p.focus());return}if(["ArrowLeft","ArrowRight"].includes(l.code)){l.preventDefault(),l.stopPropagation();const v=s.querySelectorAll(E);if(v.length===0)return;let p=Array.from(v).findIndex(S=>S===document.activeElement);if(p===-1&&document.activeElement===s){v[0].focus();return}l.code==="ArrowRight"?p=p===v.length-1?0:p+1:l.code==="ArrowLeft"&&(p=p===0?v.length-1:p-1),v[p].focus();return}}}}},b=()=>{t.nextTick(()=>{const l=e.value.$el.closest(".k-grid");l&&l.classList.add("fk-grid")})},F=()=>{if(!U)try{const l=()=>{try{const d=Array.from(e.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]"));if(!d||d.length===0||d.filter(S=>S.getAttribute("tabindex")==="0").length===1)return;const p=d.find(S=>S===document.activeElement||S.contains(document.activeElement));if(d.forEach(S=>S.setAttribute("tabindex","-1")),p){p.setAttribute("tabindex","0");return}d[0].setAttribute("tabindex","0")}catch(d){console.error("ensureSingleTabindex error:",d)}},y=Array.from(e.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]"));y.length>0&&y.forEach((d,v)=>{d.setAttribute("tabindex",v===0?"0":"-1")});const s=e.value.$el.querySelector(".k-table-tbody");s&&(U=new MutationObserver(()=>{l()}),U.observe(s,{childList:!0,subtree:!0}))}catch(l){console.error("Error setting up row navigation:",l)}},_=()=>{t.nextTick(()=>{const y=document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");y&&y.forEach(s=>{s.setAttribute("role","button"),s.addEventListener("keydown",A)}),C(),J()})},j=()=>{const y=document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");y&&y.forEach(s=>{s.removeEventListener("keydown",A)}),q&&(q.disconnect(),q=null),U&&(U.disconnect(),U=null),H.forEach(s=>s()),H.length=0},J=()=>{document.querySelectorAll(".k-grid-header .k-table-thead th").forEach((s,d)=>{if(s.dataset.featherKHeaderBound==="true")return;const v=s.querySelector(".k-grid-header-menu.k-grid-column-menu");if(!v)return;const p=$();if(p&&p[d]){const g=p[d].field??"";s.setAttribute("data-feather-k-field",g),s.setAttribute("data-feather-k-filterable",p[d].filterable===!1?"false":"true"),s.setAttribute("data-feather-k-sortable",p[d].sortable===!1?"false":"true")}const S=s.dataset.featherKFilterable!=="false",P=s.dataset.featherKSortable!=="false";v.setAttribute("tabindex","-1"),S||P?s.style.cursor="pointer":s.style.cursor="default",S?(s.setAttribute("tabindex","0"),s.setAttribute("role","button"),s.setAttribute("aria-haspopup","menu")):(s.setAttribute("tabindex","0"),s.setAttribute("role","columnheader"),s.removeAttribute("aria-haspopup"));const G=g=>{g.target?.closest(".k-column-resizer")||(c.value=s,v.click())},a=g=>{if(S)c.value=s,g.preventDefault(),g.stopPropagation(),G(g);else if(P){c.value=s;const L=s.querySelector(".k-link");L&&L.click()}};s.addEventListener("click",a),H.push(()=>{s.removeEventListener("click",a)});const f=g=>{if((k(g)||g.code==="Space")&&(S||P)){if(g.preventDefault(),g.stopPropagation(),c.value=s,c.value.focus(),S)G(g);else if(P){const L=s.querySelector(".k-link");L&&L.click()}}};s.addEventListener("keydown",f,!0),H.push(()=>{s.removeEventListener("keydown",f,!0)}),s.dataset.featherKHeaderBound="true"});const y=document.querySelector(".k-grid-header .k-table-thead");if(y&&y.dataset.featherKHeaderBound!=="true"){const s=d=>{const v=d.target.closest("th");v&&(k(d)||d.code==="Space")&&v.dataset.featherKFilterable==="false"&&v.dataset.featherKSortable==="false"&&(d.preventDefault(),d.stopImmediatePropagation())};y.addEventListener("keydown",s,!0),H.push(()=>{y.removeEventListener("keydown",s,!0)}),y.dataset.featherKHeaderBound="true"}},Q=function(l,y){const s=l?.event?.event.target,d=$();if(!s||!d)return;const v=s.classList.contains("k-grid-header-menu"),p=s.classList.contains("k-columnmenu-item"),S=d.find(P=>P.field===l?.event?.field)?.sortable&&!0;if(!v){if(p&&!S){l?.event?.sort?.filter(G=>G.field!==l?.event?.field);return}typeof y=="function"&&t.nextTick(()=>{c.value&&c.value.focus(),y(l),t.nextTick(()=>{J()})})}},oe=()=>{if(!N)try{b(),F(),_(),N=!0}catch(l){console.error("initA11y failed:",l),j()}};return t.onBeforeUnmount(()=>{j()}),{activeFilterButton:c,handleGridKeyDown:m,handleSortChange:Q,initA11y:oe}},Te=e=>!!e&&typeof e=="object"&&"filters"in e&&Array.isArray(e.filters),$e=e=>!!e&&typeof e=="object"&&"field"in e,we=(e,n)=>!e||typeof e!="object"?!1:Te(e)?e.filters.some(c=>we(c,n)):$e(e)?e.field===n:!1,Ce=e=>n=>e.value?.filters&&e.value.filters.some(c=>we(c,n))?"active":"";function Pe(e){const n=t.ref(""),c=t.ref(void 0),N=t.ref(!!e.debug),q=t.ref(e.dateFormat??"mm/dd/yyyy"),U=t.computed(()=>!!e.required),H=t.ref(!1),E=["ArrowUp","ArrowDown"],D=["ArrowLeft","ArrowRight"],w=t.computed(()=>(n.value??"").replace(/\D/g,"")),k=a=>a<=2?"mm":a<=5?"dd":w.value.length<=10?"yyyy":"mm",$=t.computed(()=>{const a=n.value&&n.value.substring(0,2).replace(/\D/g,"0")||"0";return parseInt(a).toString().padStart(2,"0")}),A=t.computed(()=>{const a=n.value&&n.value.substring(3,5).replace(/\D/g,"0")||"0";return parseInt(a).toString().padStart(2,"0")}),x=t.computed(()=>{const a=n.value&&n.value.substring(6,10).replace(/\D/g,"0")||"0";return parseInt(a).toString().padStart(4,"0")}),C=a=>{if(w.value.length===0){e.onChange({value:null,event:a});return}if(w.value.length<8){e.onChange({value:null,event:a});return}if((n.value??"").length===10&&w.value.length===8){const[f,g,L]=n.value.split("/"),K=parseInt(f),V=parseInt(g),X=parseInt(L);if(_(X,K,V)){const ae=new Date(X,K-1,V);O(ae)?e.onChange({value:ae,event:a}):e.onChange({value:null,event:a})}else e.onChange({value:null,event:a})}},O=a=>{const f=e.min??void 0,g=e.max??void 0;return!(f&&a<f||g&&a>g)},m=t.computed(()=>{if((n.value??"").length===10&&w.value.length===8){const[a,f,g]=(n.value??"").split("/"),L=parseInt(a),K=parseInt(f),V=parseInt(g);if(_(V,L,K))return new Date(V,L-1,K)}return null}),b=t.computed(()=>(n.value??"").length===10&&w.value.length===8),F=(a,f)=>new Date(a,f,0).getDate(),_=(a,f,g)=>f>=1&&f<=12&&a>=1900&&g>=1&&g<=F(a,f),j=a=>{n.value=a.value;const f=a.event?.target;c.value=f?.selectionStart??0,C(a)},J=a=>{c.value=a.target.selectionStart??0},Q=(a,f,g)=>{const L=f?.selectionStart??c.value??0;c.value=L;let K=parseInt($.value),V=parseInt(A.value),X=parseInt(x.value);if(!(w.value.length>=8)||!_(X,K,V)){const W=e.defaultValue??new Date;K=W.getMonth()+1,V=W.getDate(),X=W.getFullYear(),n.value=`${String(K).padStart(2,"0")}/${String(V).padStart(2,"0")}/${String(X)}`;const R=new Date(X,K-1,V);e.onChange({value:O(R)?R:null,event:g}),d({useRAF:!0});return}const o=k(L);if(o==="mm")K=a==="ArrowUp"?K<12?K+1:1:K>1?K-1:12;else if(o==="dd"){const W=new Date(X,K,0).getDate();V=a==="ArrowUp"?V<W?V+1:1:V>1?V-1:W}else o==="yyyy"&&(X=a==="ArrowUp"?X+1:Math.max(1,X-1));n.value=`${String(K).padStart(2,"0")}/${String(V).padStart(2,"0")}/${String(X)}`;const[i,T,I]=n.value.split("/"),B=new Date(parseInt(I),parseInt(i)-1,parseInt(T));B.toString()!=="Invalid Date"&&parseInt(I)>=1e3?e.onChange({value:O(B)?B:null,event:g}):e.onChange({value:null,event:g}),d({useRAF:!0})},oe=a=>{if(a.code==="Space"||a.key===" "){a.preventDefault(),a.stopPropagation(),e.onShowCalendar(a);return}if(a.key==="ArrowDown"&&a.altKey){a.preventDefault(),a.stopPropagation(),e.onShowCalendar(a);return}if(E.includes(a.key)){if(a.altKey)return;a.preventDefault(),a.stopPropagation();const f=a.target;Q(a.key,f,a);return}},l=a=>{a.preventDefault();const f=a.deltaY<0?"ArrowUp":"ArrowDown";Q(f,a.target,a)},y=a=>{const f=a.target;if(D.includes(a.key)){c.value=f?.selectionStart??0;return}if(E.includes(a.key)){if(a.altKey)return;c.value=f?.selectionStart??0}},s=a=>{H.value=!0,U.value&&!e.defaultValue&&e.externalValue&&e.externalValue.value===void 0&&w.value.length===0&&(e.externalValue.value="");const f=a.target;f&&(c.value=f.selectionStart??0)},d=a=>{const f=()=>{const g=document.getElementById(e.id);if(!g)return;const L=a?.pos??c.value??g.value.length;try{g.focus(),g.setSelectionRange(L,L)}catch{}};t.nextTick(()=>{if(a?.delay&&a.delay>0){setTimeout(f,a.delay);return}if(a?.useRAF){requestAnimationFrame(f);return}f()})};e.externalValue&&t.watch(e.externalValue,a=>{if(a){const f=new Date(a);if(f.toString()!=="Invalid Date"){const g=(f.getMonth()+1).toString().padStart(2,"0"),L=f.getDate().toString().padStart(2,"0"),K=f.getFullYear().toString();n.value=`${g}/${L}/${K}`,d({delay:50});return}}},{immediate:!0});const v=t.computed(()=>[["Date",`${$.value} / ${A.value} / ${x.value}`],["Digits only",w.value],["min",e.min?.toLocaleDateString("en-US",{year:"numeric",month:"2-digit",day:"2-digit"})??null],["max",e.max?.toLocaleDateString("en-US",{year:"numeric",month:"2-digit",day:"2-digit"})??null]]),p=t.computed(()=>{if(!U.value){if(!b.value)return!0;const f=m.value;return f?O(f):!1}if(!H.value)return!0;const a=m.value;return!b.value||!a?!1:O(a)}),S=t.computed(()=>{if(!U.value){if(!b.value)return;const f=m.value;return f?O(f)?"valid":"out-of-bounds":"invalid-date"}if(!H.value)return;if(w.value.length===0||!b.value)return"incomplete";const a=m.value;return a?O(a)?"valid":"out-of-bounds":"invalid-date"}),P=t.computed(()=>{const a=S.value;if(!a||a==="valid")return"";if(a==="incomplete")return"Required";if(a==="invalid-date")return`Must be in ${q.value} format.`;const f=e.min?e.min.toLocaleDateString("en-US",{year:"numeric",month:"2-digit",day:"2-digit"}):null,g=e.max?e.max.toLocaleDateString("en-US",{year:"numeric",month:"2-digit",day:"2-digit"}):null;if(a==="out-of-bounds"){if(f&&g)return`Must be between ${f} and ${g}.`;if(f)return`Must be on or after ${f}.`;if(g)return`Must be on or before ${g}.`}return""}),G=()=>{t.nextTick(()=>{const a=document.getElementById(e.id);if(!a){console.warn(`ID (#${e.id}) not found for styling.`);return}const f=a.closest(".k-datepicker");if(!f){console.warn(`.k-datepicker parent not found for #${e.id} styling.`);return}const g=f.parentElement;if(g){if(g.classList.contains("fk-datepicker"))return;g.classList.add("fk-datepicker")}else console.warn(`Parent of .k-datepicker not found for #${e.id} styling.`)})};return t.onMounted(()=>{G()}),{raw:n,cursorPos:c,debugEnabled:N,debugLines:v,placeholder:q,isValid:p,reason:t.readonly(S),validationMessage:P,digitsOnly:w,month:t.readonly($),day:t.readonly(A),year:t.readonly(x),datePart:k,handleChange:j,handleKeyDown:oe,handleWheel:l,handleKeyUp:y,handleClick:J,handleBlur:s,initStyling:G}}function Ie(e){const n=t.ref(""),c=t.ref(void 0),N=t.ref(!!e.debug),q=t.ref(!1),U=1440*60*1e3,H=365*U,E=new Date,D=new Date(E.getTime()-H),w=new Date(E.getTime()+H);e.min=e.min??D,e.max=e.max??w;const k=t.computed(()=>(n.value??"").replace(/\D/g,"")),$=(r,u)=>new Date(r,u,0).getDate(),A=(r,u,h)=>u>=1&&u<=12&&r>=1e3&&h>=1&&h<=$(r,u),x=r=>Date.UTC(r.getFullYear(),r.getMonth(),r.getDate()),C=r=>{if(!r)return null;const u=e.min??new Date(Date.now()-90*U),h=e.max??new Date,M=x(r);return M<x(u)||M>x(h)?null:r},O=(r,u)=>e.allowReverse??!1?!0:r<=u,m=t.computed(()=>(n.value?.length??0)>=23&&k.value.length>=16),b=r=>{if((r??"").length<23||k.value.length<16)return{start:null,end:null};const u=r.substring(0,10),h=r.substring(13,23),[M,Z,ee]=u.split("/").map(se=>parseInt(se||"0",10)),[ie,ce,de]=h.split("/").map(se=>parseInt(se||"0",10)),fe=new Date(ee,M-1,Z),ye=new Date(de,ie-1,ce),Se=A(ee,M,Z)&&fe.toString()!=="Invalid Date",be=A(de,ie,ce)&&ye.toString()!=="Invalid Date";return{start:Se?fe:null,end:be?ye:null}},F=e.externalValid??t.ref(!0),_=t.computed(()=>b(n.value)),j=t.computed(()=>{const r=C(_.value.start),u=C(_.value.end);return{start:r,end:u}}),J=t.computed(()=>{if(!m.value)return;const r=j.value.start,u=j.value.end;if(!r||!u)return;const h=Math.abs(x(u)-x(r));return Math.round(h/864e5+1)}),Q=t.computed(()=>{if(!m.value)return!1;const{start:r,end:u}=_.value;if(!r||!u||!j.value.start||!j.value.end)return!1;const h=j.value.start,M=j.value.end;return!(!O(h,M)||typeof e.maxSpanDays=="number"&&J.value!==void 0&&J.value>e.maxSpanDays)}),oe=t.computed(()=>{const{start:r,end:u}=_.value;if(!m.value)return"incomplete";if(!r||!u)return"invalid-date";if(!j.value.start||!j.value.end)return"out-of-bounds";const h=j.value.start,M=j.value.end;return O(h,M)?typeof e.maxSpanDays=="number"&&J.value!==void 0&&J.value>e.maxSpanDays?"span-exceeds-limit":"valid":"reversed-range"}),l=t.ref(void 0),y=t.computed(()=>{if(F.value!==!1)return"";const{min:r,max:u}=e,h=l.value;if(!h)return"";switch(h){case"incomplete":return"Required";case"invalid-date":return"One or both dates invalid.";case"reversed-range":return"End Date must be on or after Start Date.";case"out-of-bounds":return r&&u?`Dates must be between ${p(r)} and ${p(u)}.`:"Dates must be within the allowed range.";case"span-exceeds-limit":return typeof e.maxSpanDays=="number"?`Date range exceeds ${e.maxSpanDays} days.`:"Date range exceeds maximum allowed span.";default:return""}}),s=["ArrowUp","ArrowDown"],d=["ArrowLeft","ArrowRight"],v=(r,u)=>String(r).padStart(u,"0"),p=r=>`${v(r.getMonth()+1,2)}/${v(r.getDate(),2)}/${v(r.getFullYear(),4)}`,S=r=>r<=2?{side:"start",part:"mm"}:r<=5?{side:"start",part:(r<=3,"dd")}:r<=11?{side:"start",part:"yyyy"}:r<=15?{side:"end",part:"mm"}:r<=18?{side:"end",part:"dd"}:{side:"end",part:"yyyy"},P=(r,u,h)=>{const M=u?.selectionStart??c.value??0;c.value=M;const{start:Z,end:ee}=b(n.value);if(!Z&&!ee){const Y=new Date,le=p(Y);n.value=`${le} - ${le}`,e.onChange({value:{start:Y,end:Y},event:h}),t.nextTick(()=>{requestAnimationFrame(()=>{const te=document.getElementById(e.id),re=c.value??0;te&&(te.focus(),te.setSelectionRange(re,re))})});return}const ie=new Date,ce=S(M);let de=Z?new Date(Z):new Date(ie),fe=ee?new Date(ee):new Date(ie);const ye=(Y,le)=>{if(le==="mm"){const te=Y.getMonth()+1,re=r==="ArrowUp"?te<12?te+1:1:te>1?te-1:12;Y.setMonth(re-1);const ge=$(Y.getFullYear(),re);Y.getDate()>ge&&Y.setDate(ge)}else if(le==="dd"){const te=$(Y.getFullYear(),Y.getMonth()+1),re=Y.getDate(),ge=r==="ArrowUp"?re<te?re+1:1:re>1?re-1:te;Y.setDate(ge)}else if(le==="yyyy"){const te=Y.getFullYear();Y.setFullYear(r==="ArrowUp"?te+1:Math.max(1,te-1));const re=$(Y.getFullYear(),Y.getMonth()+1);Y.getDate()>re&&Y.setDate(re)}};ce.side==="start"?ye(de,ce.part):ye(fe,ce.part);const Se=p(de),be=p(fe);n.value=`${Se} - ${be}`;const se=C(de),ke=C(fe);se&&ke&&O(se,ke)?e.onChange({value:{start:se,end:ke},event:h}):e.onChange({value:null,event:h}),t.nextTick(()=>{requestAnimationFrame(()=>{const Y=document.getElementById(e.id),le=c.value??0;Y&&(Y.focus(),Y.setSelectionRange(le,le))})})},G=r=>{const{start:u,end:h}=b(n.value);if(!u||!h){e.onChange({value:null,event:r});return}const M=C(u),Z=C(h);if(!M||!Z){e.onChange({value:null,event:r});return}if(!O(M,Z)){e.onChange({value:null,event:r});return}e.onChange({value:{start:M,end:Z},event:r})},a=r=>{const u=r.value??"",h=r.event;if(!u&&h&&h.type==="click"){ae(h);return}n.value=u;const M=h?.target;c.value=M?.selectionStart??0,G(r)},f=r=>{c.value=r.target.selectionStart??0},g=r=>{if(r.code==="Space"||r.key===" "){r.preventDefault(),r.stopPropagation(),e.onShowCalendar(r);return}if(r.key==="ArrowDown"&&r.altKey){r.preventDefault(),r.stopPropagation(),e.onShowCalendar(r);return}if(s.includes(r.key)){r.preventDefault(),r.stopPropagation();const u=r.target;P(r.key,u,r);return}},L=r=>{r.preventDefault();const u=r.deltaY<0?"ArrowUp":"ArrowDown";P(u,r.target,r)},K=r=>{if(d.includes(r.key)||s.includes(r.key)){const u=r.target;c.value=u?.selectionStart??0}},V=()=>{l.value=oe.value,(e.manageValid??!0)&&(F.value=Q.value)},X=r=>{V()},ae=r=>{console.log("Clear event:",r),n.value="",c.value=0,e.onChange({value:null,event:r}),V(),t.nextTick(()=>{const u=document.getElementById(e.id);u&&(u.focus(),u.setSelectionRange(0,0))})};e.externalValue&&t.watch(e.externalValue,r=>{const u=r?.start??null,h=r?.end??null;if(u&&h){if(n.value=`${p(u)} - ${p(h)}`,e.isOpen?.value&&q.value&&e.onRequestClose){const M=typeof e.closeDelay=="number"?e.closeDelay:e.closeDelay?.value??0;setTimeout(()=>{e.onRequestClose?.(),q.value=!1,V()},M)}return}},{immediate:!0});const o=t.computed(()=>n.value&&n.value.substring(0,2).replace(/\D/g,"0")||"0"),i=t.computed(()=>n.value&&n.value.substring(3,5).replace(/\D/g,"0")||"0"),T=t.computed(()=>n.value&&n.value.substring(6,10).replace(/\D/g,"0")||"0"),I=t.computed(()=>n.value&&n.value.substring(13,15).replace(/\D/g,"0")||"0"),B=t.computed(()=>n.value&&n.value.substring(16,18).replace(/\D/g,"0")||"0"),W=t.computed(()=>n.value&&n.value.substring(19,23).replace(/\D/g,"0")||"0"),R=t.computed(()=>{const{start:r,end:u}=b(n.value);return[{label:"Raw",value:n.value},{label:"Min Date",value:`${e.min?e.min.toDateString():"-"}`},{label:"Max Date",value:`${e.max?e.max.toDateString():"-"}`},{label:"Start",value:`${String(o.value).padStart(2,"0")} / ${String(i.value).padStart(2,"0")} / ${String(T.value).padStart(4,"0")}`},{label:"End",value:`${String(I.value).padStart(2,"0")} / ${String(B.value).padStart(2,"0")} / ${String(W.value).padStart(4,"0")}`},{label:"Digits only",value:k.value},{label:"Mask complete",value:`${m.value}`},{label:"Parsed",value:`${r?r.toDateString():"-"} | ${u?u.toDateString():"-"}`},{label:"Valid (managed)",value:`${F.value??"-"}`},{label:"Span (days)",value:`${J.value??"-"}`},{label:"Reason",value:`${oe.value??"-"}`},{label:"Cursor in",value:`${c.value??"-"} (${(()=>{const h=c.value??0,M=S(h);return`${M.side}.${M.part}`})()})`}]}),z=()=>{t.nextTick(()=>{const r=document.getElementById(e.id);if(!r){console.warn(`#${e.id} not found for styling.`);return}const u=r.closest("div");if(!u){console.warn(`Parent div of #${e.id} not found for styling.`);return}u.classList.contains("fk-daterangepicker")||u.classList.add("fk-daterangepicker")})};t.onMounted(()=>{z()});const me=()=>{t.nextTick(()=>{try{const r=Array.from(document.querySelectorAll(".k-animation-container"));if(!r.length)return;const h=[...r].reverse().find(ee=>ee.querySelector(".k-calendar"))?.querySelector(".k-calendar");if(!h)return;const M=h.querySelectorAll(".k-calendar-table");let Z=!1;M.forEach(ee=>{ee.tabIndex===0&&(Z?ee.tabIndex=-1:Z=!0)})}catch(r){console.warn(r)}})};return e.isOpen&&t.watch(e.isOpen,r=>{r&&setTimeout(()=>me(),0)},{immediate:!1}),{raw:n,cursorPos:c,debugEnabled:N,debugLines:R,digitsOnly:k,valid:F,validComputed:t.readonly(Q),reason:t.readonly(oe),validationMessage:t.readonly(y),spanDays:t.readonly(J),month1:t.readonly(o),day1:t.readonly(i),year1:t.readonly(T),month2:t.readonly(I),day2:t.readonly(B),year2:t.readonly(W),handleChange:a,handleKeyDown:g,handleWheel:L,handleKeyUp:K,handleClick:f,handleBlur:X,handleClear:ae,onCalendarChange:()=>{q.value=!0},initStyling:z}}function Le(e){const n=t.ref(""),c=t.ref(void 0),N=t.ref(!!e.debug),q=t.ref(e.timeFormat??"hh:mm AM"),U=t.computed(()=>!!e.required),H=t.ref(!1),E=["ArrowUp","ArrowDown"],D=["ArrowLeft","ArrowRight"],w=t.computed(()=>(n.value??"").replace(/\D/g,"")),k={H:/[0-9]/,h:/[0-9]/,M:/[0-9]/,m:/[0-9]/,A:/[AaPp]/,a:/[Mm]/},$=o=>o<=2?"hh":o<=5?"mm":"ampm",A=t.computed(()=>{const o=n.value&&n.value.substring(0,2).replace(/\D/g,"0")||"0",i=parseInt(o);return Math.min(Math.max(i,0),23)}),x=t.computed(()=>{const o=n.value&&n.value.substring(3,5).replace(/\D/g,"0")||"0",i=parseInt(o);return Math.min(Math.max(i,0),59)}),C=t.computed(()=>(n.value?.substring(6,8)||"AM").toUpperCase().startsWith("P")?"PM":"AM"),O=t.computed(()=>{const o=parseInt(n.value?.substring(0,2).replace(/\D/g,"0")||"0"),i=C.value;return o===12?i==="AM"?0:12:i==="PM"?o+12:o}),m=t.computed(()=>b.value?`${String(O.value).padStart(2,"0")}:${String(x.value).padStart(2,"0")}:00`:null),b=t.computed(()=>/^(\d{2}):(\d{2})\s([AP]M)$/i.test(n.value??"")),F=(o,i,T)=>{let I=o%12;return I===0&&(I=12),`${String(I).padStart(2,"0")}:${String(i).padStart(2,"0")} ${T}`},_=o=>{const i=o.match(/^(\d{2}):(\d{2})\s([AP]M)$/i);if(!i)return null;const T=parseInt(i[1]),I=parseInt(i[2]),B=i[3].toUpperCase();if(T<1||T>12||I<0||I>59)return null;let W=T%12;B==="PM"&&(W+=12);const R=new Date;return R.setSeconds(0,0),R.setHours(W),R.setMinutes(I),R},j=o=>{if(w.value.length===0){e.onChange({value:null,event:o});return}if(!b.value){e.onChange({value:null,event:o});return}const i=_(n.value);i&&Q(i)?e.onChange({value:i,event:o}):e.onChange({value:null,event:o})},J=o=>o.getHours()*60+o.getMinutes(),Q=o=>{const i=e.min??void 0,T=e.max??void 0,I=J(o);if(i){const B=J(i);if(I<B)return!1}if(T){const B=J(T);if(I>B)return!1}return!0},oe=o=>{const i=o.getHours(),T=i>=12?"PM":"AM";n.value=F(i,o.getMinutes(),T)},l=(o,i)=>{e.onChange({value:o,event:i})},y=()=>{t.nextTick(()=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{const o=document.getElementById(e.id);if(o){o.focus();const i=(o.value??"").length;o.setSelectionRange(i,i)}})})})},s=o=>{const i=o?.event?.target;return i?i.closest(".k-time-now")?"now":i.closest(".k-time-accept")?"set":null:null},d=(o,i)=>{o&&Q(o)?l(o,i):l(null,i)},v=(...o)=>{const i=o[0];if(!i)return;const T=s(i);if(T==="now"){const B=new Date;oe(B),d(B,i),y();return}if(i?.value instanceof Date){const B=new Date(i.value);oe(B),d(B,i),T==="set"&&y();return}if(i?.value===null){n.value="",l(null,i);return}n.value=i.value;const I=i.event?.target;c.value=I?.selectionStart??0;try{const B=c.value??0;if($(B)==="ampm"&&(n.value??"").length>=8){const W=n.value.charAt(6);/[Aa]/.test(W)?(n.value=`${n.value.slice(0,6)}AM${n.value.slice(8)}`,t.nextTick(()=>{requestAnimationFrame(()=>{const R=document.getElementById(e.id);R&&(R.focus(),R.setSelectionRange(8,8))})})):/[Pp]/.test(W)&&(n.value=`${n.value.slice(0,6)}PM${n.value.slice(8)}`,t.nextTick(()=>{requestAnimationFrame(()=>{const R=document.getElementById(e.id);R&&(R.focus(),R.setSelectionRange(8,8))})}))}}catch{}j(i)},p=o=>{c.value=o.target.selectionStart??0},S=(o,i,T)=>{const I=i?.selectionStart??c.value??0;c.value=I;const B=$(I),W=(n.value??"").match(/^(\d{2}):(\d{2})\s([AP]M)$/i);if(!W){if((n.value??"").length===0||w.value.length===0){const u=new Date,h=u.getHours(),M=h>=12?"PM":"AM";n.value=F(h,u.getMinutes(),M);const Z=_(n.value);d(Z,T),t.nextTick(()=>{requestAnimationFrame(()=>{const ee=document.getElementById(e.id),ie=c.value??0;ee&&(ee.focus(),ee.setSelectionRange(ie,ie))})})}return}let R=parseInt(W[1]),z=parseInt(W[2]),me=W[3].toUpperCase();if(B==="hh")o==="ArrowUp"?R=R<12?R+1:1:R=R>1?R-1:12;else if(B==="mm"){const u=e.minuteStepRef?.value??e.minuteStep??1;if(u===1)o==="ArrowUp"?z=z<59?z+1:0:z=z>0?z-1:59;else if(o==="ArrowUp"){const h=z%u;let M=h===0?z+u:z+(u-h);M>=60&&(M=0),z=M}else{const h=z%u;let M=h===0?z-u:z-h;M<0&&(M=60-u),z=M}}else B==="ampm"&&(me=me==="AM"?"PM":"AM");n.value=`${String(R).padStart(2,"0")}:${String(z).padStart(2,"0")} ${me}`;const r=_(n.value);d(r,T),t.nextTick(()=>{requestAnimationFrame(()=>{const u=document.getElementById(e.id),h=c.value??0;u&&(u.focus(),u.setSelectionRange(h,h))})})},P=o=>{if(o.code==="Space"||o.key===" "){o.preventDefault(),o.stopPropagation(),e.onShowPicker(o);return}if(o.key==="ArrowDown"&&o.altKey){o.preventDefault(),o.stopPropagation(),e.onShowPicker(o);return}if(E.includes(o.key)){if(o.altKey)return;o.preventDefault(),o.stopPropagation();const i=o.target;S(o.key,i,o);return}},G=o=>{o.preventDefault();const i=o.deltaY<0?"ArrowUp":"ArrowDown";S(i,o.target,o)},a=o=>{const i=o.target;if(D.includes(o.key)){c.value=i?.selectionStart??0;return}if(E.includes(o.key)){if(o.altKey)return;c.value=i?.selectionStart??0}},f=o=>{H.value=!0,U.value&&e.externalValue&&e.externalValue.value===void 0&&w.value.length===0&&(e.externalValue.value="");const i=o.target;i&&(c.value=i.selectionStart??0)};e.externalValue&&t.watch(e.externalValue,o=>{if(o){const i=new Date(o);if(i.toString()!=="Invalid Date"){const T=i.getHours(),I=T>=12?"PM":"AM";n.value=F(T,i.getMinutes(),I);return}}},{immediate:!0});const g=t.computed(()=>[["Time",n.value||"--:-- --"],["Hour (12h)",A.value],["Hour (24h)",O.value],["Minute",x.value],["Period",C.value],["Time (24h)",m.value??"--:--:--"],["Digits only",w.value],["Parsed Date",L.value?.toLocaleDateString("en-US",{hour:"2-digit",minute:"2-digit"})??null],["min",e.min?.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit"})??null],["max",e.max?.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit"})??null],["valid",K.value],["reason",V.value],["validationMessage",X.value]]),L=t.computed(()=>_(n.value)??null),K=t.computed(()=>{if(!U.value){if(!b.value)return!0;const i=L.value;return i?Q(i):!1}if(!H.value)return!0;const o=L.value;return!b.value||!o?!1:Q(o)}),V=t.computed(()=>{if(!U.value){if(!b.value)return;const i=L.value;return i?Q(i)?"valid":"out-of-bounds":"invalid-time"}if(!H.value)return;if(w.value.length===0||!b.value)return"incomplete";const o=L.value;return o?Q(o)?"valid":"out-of-bounds":"invalid-time"}),X=t.computed(()=>{const o=V.value;if(!o||o==="valid")return"";if(o==="incomplete")return"Required";if(o==="invalid-time")return`Must be in ${q.value} format.`;const i={hour:"2-digit",minute:"2-digit"},T=e.min?e.min.toLocaleTimeString("en-US",i):null,I=e.max?e.max.toLocaleTimeString("en-US",i):null;if(o==="out-of-bounds"){if(T&&I)return`Must be between ${T} and ${I}.`;if(T)return`Must be ${T} or later.`;if(I)return`Must be ${I} or earlier.`}return""}),ae=()=>{t.nextTick(()=>{const o=document.getElementById(e.id);if(!o){console.warn(`#${e.id} not found for styling.`);return}const i=o.closest(".k-timepicker");if(!i){console.warn(`.k-timepicker parent of #${e.id} not found for styling.`);return}const T=i.parentElement;if(!T){console.warn(`Parent of .k-timepicker not found for #${e.id} styling.`);return}T.classList.contains("fk-timepicker")||T.classList.add("fk-timepicker")})};return t.onMounted(()=>{ae()}),{raw:n,rules:k,debugEnabled:N,debugLines:g,placeholder:q,isValid:K,reason:t.readonly(V),validationMessage:X,isComplete:b,inRangeTime:Q,cursorPos:c,hour:t.readonly(A),hour24:t.readonly(O),minute:t.readonly(x),period:t.readonly(C),time24:t.readonly(m),parsedRawTime:t.readonly(L),handleChange:v,handleKeyDown:P,handleKeyUp:a,handleClick:p,handleWheel:G,handleBlur:f,initStyling:ae}}function Fe(e){return t.getCurrentScope()?(t.onScopeDispose(e),!0):!1}const De=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Re=Object.prototype.toString,qe=e=>Re.call(e)==="[object Object]",ue=()=>{},Ue=Oe();function Oe(){var e,n;return De&&((e=window?.navigator)==null?void 0:e.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((n=window?.navigator)==null?void 0:n.maxTouchPoints)>2&&/iPad|Macintosh/.test(window?.navigator.userAgent))}function he(e){return Array.isArray(e)?e:[e]}function Ke(e,n,c){return t.watch(e,n,{...c,immediate:!0})}const Ae=De?window:void 0;function pe(e){var n;const c=t.toValue(e);return(n=c?.$el)!=null?n:c}function ve(...e){const n=[],c=()=>{n.forEach(E=>E()),n.length=0},N=(E,D,w,k)=>(E.addEventListener(D,w,k),()=>E.removeEventListener(D,w,k)),q=t.computed(()=>{const E=he(t.toValue(e[0])).filter(D=>D!=null);return E.every(D=>typeof D!="string")?E:void 0}),U=Ke(()=>{var E,D;return[(D=(E=q.value)==null?void 0:E.map(w=>pe(w)))!=null?D:[Ae].filter(w=>w!=null),he(t.toValue(q.value?e[1]:e[0])),he(t.unref(q.value?e[2]:e[1])),t.toValue(q.value?e[3]:e[2])]},([E,D,w,k])=>{if(c(),!E?.length||!D?.length||!w?.length)return;const $=qe(k)?{...k}:k;n.push(...E.flatMap(A=>D.flatMap(x=>w.map(C=>N(A,x,C,$)))))},{flush:"post"}),H=()=>{U(),c()};return Fe(c),H}let xe=!1;function Ve(e,n,c={}){const{window:N=Ae,ignore:q=[],capture:U=!0,detectIframe:H=!1,controls:E=!1}=c;if(!N)return E?{stop:ue,cancel:ue,trigger:ue}:ue;if(Ue&&!xe){xe=!0;const m={passive:!0};Array.from(N.document.body.children).forEach(b=>b.addEventListener("click",ue,m)),N.document.documentElement.addEventListener("click",ue,m)}let D=!0;const w=m=>t.toValue(q).some(b=>{if(typeof b=="string")return Array.from(N.document.querySelectorAll(b)).some(F=>F===m.target||m.composedPath().includes(F));{const F=pe(b);return F&&(m.target===F||m.composedPath().includes(F))}});function k(m){const b=t.toValue(m);return b&&b.$.subTree.shapeFlag===16}function $(m,b){const F=t.toValue(m),_=F.$.subTree&&F.$.subTree.children;return _==null||!Array.isArray(_)?!1:_.some(j=>j.el===b.target||b.composedPath().includes(j.el))}const A=m=>{const b=pe(e);if(m.target!=null&&!(!(b instanceof Element)&&k(e)&&$(e,m))&&!(!b||b===m.target||m.composedPath().includes(b))){if("detail"in m&&m.detail===0&&(D=!w(m)),!D){D=!0;return}n(m)}};let x=!1;const C=[ve(N,"click",m=>{x||(x=!0,setTimeout(()=>{x=!1},0),A(m))},{passive:!0,capture:U}),ve(N,"pointerdown",m=>{const b=pe(e);D=!w(m)&&!!(b&&!m.composedPath().includes(b))},{passive:!0}),H&&ve(N,"blur",m=>{setTimeout(()=>{var b;const F=pe(e);((b=N.document.activeElement)==null?void 0:b.tagName)==="IFRAME"&&!F?.contains(N.document.activeElement)&&n(m)},0)},{passive:!0})].filter(Boolean),O=()=>C.forEach(m=>m());return E?{stop:O,cancel:()=>{D=!1},trigger:m=>{D=!0,A(m),D=!1}}:O}function Be(e){const n=t.shallowRef(null),c=[".k-animation-container .k-popup",".k-popup",".k-timepicker-popup",".k-menu-popup"],N=Array.isArray(e.popupSelector)?e.popupSelector:[e.popupSelector??c].flat(),q=k=>k?typeof e.initialFocus=="string"?k.querySelector(e.initialFocus)??k:typeof e.initialFocus=="function"?e.initialFocus(k)??k:k.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')??k:null,{activate:U,deactivate:H}=Ee.useFocusTrap(n,{escapeDeactivates:!1,clickOutsideDeactivates:!1,fallbackFocus:()=>n.value,initialFocus:()=>q(n.value),...e.focusTrapOptions??{}});let E=null,D=t.ref(null);const w=()=>{if(e.resolvePopupEl)return e.resolvePopupEl();const k=(A,x)=>{const C=Array.from(A.querySelectorAll(x));if(!C.length)return null;const O=C.filter(m=>m.offsetParent!==null||m.getClientRects().length>0);return O[O.length-1]??C[C.length-1]??null},$=e.triggerEl?.value?.closest?.(".k-animation-container")??document.body;for(const A of N){const x=k($,A);if(x)return x}for(const A of N){const x=k(document,A);if(x)return x}return null};return Ve(n,k=>{D.value="outside",e.isOpen.value&&e.onRequestClose?.("outside",k)}),t.watch(()=>e.isOpen.value,k=>{k?(D.value=null,t.nextTick(()=>{const $=w();$&&(n.value=$,setTimeout(()=>U(),0),E||(E=A=>{A.key==="Escape"&&(D.value="escape",e.isOpen.value&&e.onRequestClose?.("escape",A))},document.addEventListener("keydown",E,!0)))})):(H(),E&&(document.removeEventListener("keydown",E,!0),E=null),n.value=null,D.value==="outside"&&t.nextTick(()=>{const $=()=>{const A=e.triggerEl?.value,x=A?.querySelector("input"),C=document.activeElement;C&&(C===x||A&&A.contains(C))&&(x??A)?.blur?.()};requestAnimationFrame(()=>setTimeout($,0))}),e.returnFocusToTrigger!==!1&&D.value==="escape"&&e.triggerEl?.value&&(console.log("Returning focus to trigger element:",e.triggerEl.value),t.nextTick(()=>{const $=()=>{const A=e.triggerEl?.value;if(!A)return;(A.querySelector("input")??A)?.focus?.()};requestAnimationFrame(()=>setTimeout($,0))})))}),{popupRef:n,activate:U,deactivate:H,lastCloseReason:t.readonly(D),setPopupEl:k=>n.value=k}}ne.useGridA11y=Me,ne.useGridActiveFilter=Ce,ne.useMaskedDateInput=Pe,ne.useMaskedDateRangeInput=Ie,ne.useMaskedTimeInput=Le,ne.usePopupTrap=Be,Object.defineProperty(ne,Symbol.toStringTag,{value:"Module"})}));
|
package/dist/grid/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { useGridA11y } from "
|
|
1
|
+
export { useGridA11y } from "./useGridA11y";
|
|
2
|
+
export { useGridActiveFilter } from "./useGridActiveFilter";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* focus management, and custom behaviors for column header menus (filter/sort).
|
|
6
6
|
*/
|
|
7
7
|
import { type Ref } from "vue";
|
|
8
|
-
import type { GridSortChangeEvent } from "
|
|
8
|
+
import type { GridSortChangeEvent } from "../types/kendo";
|
|
9
9
|
export declare const useGridA11y: (gridRef: Ref<any>, options?: {
|
|
10
10
|
focusableMenuSelectors?: string[];
|
|
11
11
|
}) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Ref } from "vue";
|
|
2
|
+
import type { CompositeFilterDescriptor } from "@progress/kendo-data-query";
|
|
3
|
+
/**
|
|
4
|
+
* Returns a reactive function that resolves to `"active"` when the given
|
|
5
|
+
* field has a filter applied in the current filter tree, or `""` when it
|
|
6
|
+
* does not.
|
|
7
|
+
*
|
|
8
|
+
* Bind the returned function directly to column `headerClassName` inside a
|
|
9
|
+
* `computed` — Vue tracks the `filterRef` dependency automatically; no
|
|
10
|
+
* manual update call is needed.
|
|
11
|
+
*
|
|
12
|
+
* @param filterRef - Reactive grid filter descriptor (the same ref bound to the Grid).
|
|
13
|
+
* @returns `(field: string) => "active" | ""`
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const activeClass = useGridActiveFilter(filterRef);
|
|
17
|
+
*
|
|
18
|
+
* const columns = computed(() => [
|
|
19
|
+
* { field: "ProductName", headerClassName: activeClass("ProductName") },
|
|
20
|
+
* ]);
|
|
21
|
+
*/
|
|
22
|
+
export declare const useGridActiveFilter: (filterRef: Ref<CompositeFilterDescriptor | undefined>) => ((field: string) => string);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/docs/grid/useGridA11y.md
CHANGED
|
@@ -207,11 +207,12 @@ Returns helpers to initialize accessibility, manage focus, and handle keyboard a
|
|
|
207
207
|
- **`activeFilterButton: Ref<HTMLElement | null>`**: Last-activated header filter/menu trigger; used to restore focus after menu closes.
|
|
208
208
|
- **`initA11y(): void`**: Initializes attributes, observers, and focus targets once Grid + non-empty data are present.
|
|
209
209
|
- **`handleGridKeyDown(e: KeyboardEvent): void`**: Row-level keyboard navigation.
|
|
210
|
+
- Scoped to this grid instance and only runs when the event originates from the grid accessibility/content region (prefers `.k-grid-aria-root`, with header/content fallback selectors for markup variance).
|
|
210
211
|
- ArrowUp/ArrowDown: move between rows (`.k-table-row[data-grid-row-index]`).
|
|
211
212
|
- ArrowLeft/ArrowRight: cycle focus within tabbable elements inside the focused row.
|
|
212
213
|
- Escape: collapse focus back to the row.
|
|
213
214
|
- Safeguards menu triggers to defer to column menu logic.
|
|
214
|
-
- **Important**:
|
|
215
|
+
- **Important**: Uses a secondary form-control guard so inputs/buttons/Kendo editors keep native keyboard behavior. Exception: when focus is inside a data row, ArrowLeft/ArrowRight are still handled for intra-row focus movement.
|
|
215
216
|
- **`handleSortChange(event: any, cb?: (event: any) => void): void`**: Composable-aware sort handling; optionally call a custom callback before applying sort.
|
|
216
217
|
|
|
217
218
|
### Options
|
|
@@ -240,13 +241,27 @@ Internal behaviors include:
|
|
|
240
241
|
- Provide descriptive `aria-label`s via `rowRender`.
|
|
241
242
|
- Ensure header menu triggers are reachable and announce intent (Filter/Sort).
|
|
242
243
|
|
|
243
|
-
##
|
|
244
|
+
## Keyboard Event Scope and Form Controls
|
|
244
245
|
|
|
245
|
-
|
|
246
|
+
`handleGridKeyDown` now applies keyboard navigation at a narrower scope. It first verifies the event belongs to the current grid instance's accessibility/content region, then applies form-control checks.
|
|
247
|
+
|
|
248
|
+
Guard sequence:
|
|
249
|
+
|
|
250
|
+
1. Resolve event target.
|
|
251
|
+
2. Resolve current grid root from `gridRef`.
|
|
252
|
+
3. Prefer nearest `.k-grid-aria-root`; continue only when it is contained by this grid instance.
|
|
253
|
+
4. Fallback for markup variance: `.k-grid-header`, `.k-grid-content`, `.k-grid-content-locked`.
|
|
254
|
+
5. Apply form-control guard (with intra-row ArrowLeft/ArrowRight exception).
|
|
255
|
+
|
|
256
|
+
This combination prevents toolbar/external interference while preserving intended row/header navigation.
|
|
257
|
+
|
|
258
|
+
### Using Form Controls in GridToolbar
|
|
259
|
+
|
|
260
|
+
Form controls in `GridToolbar` are naturally excluded from grid row navigation because they are outside row navigation intent and are filtered by the scope + form-control guards.
|
|
246
261
|
|
|
247
262
|
### What's Supported
|
|
248
263
|
|
|
249
|
-
The composable
|
|
264
|
+
The composable detects and skips grid navigation handling for:
|
|
250
265
|
|
|
251
266
|
- Native form elements: `<input>`, `<textarea>`, `<select>`, `<button>`
|
|
252
267
|
- Kendo form components:
|
|
@@ -255,9 +270,9 @@ The composable automatically detects and skips keyboard event handling for:
|
|
|
255
270
|
- `.k-textbox` (generic Kendo textbox wrapper)
|
|
256
271
|
- `[role="combobox"]` (dropdowns, autocompletes, etc.)
|
|
257
272
|
|
|
258
|
-
### Example:
|
|
273
|
+
### Example: GridToolbar Controls (No Keyboard Interference)
|
|
259
274
|
|
|
260
|
-
This pattern
|
|
275
|
+
This pattern works without extra keydown propagation workarounds:
|
|
261
276
|
|
|
262
277
|
```html
|
|
263
278
|
<Grid
|
|
@@ -287,10 +302,11 @@ This pattern now works correctly without additional event handling:
|
|
|
287
302
|
|
|
288
303
|
When a keyboard event is dispatched on the Grid:
|
|
289
304
|
|
|
290
|
-
1. `handleGridKeyDown`
|
|
291
|
-
2.
|
|
292
|
-
3.
|
|
293
|
-
4.
|
|
305
|
+
1. `handleGridKeyDown` first verifies the target is inside this grid instance's a11y/content scope.
|
|
306
|
+
2. It then checks `isFormControl()`.
|
|
307
|
+
3. If the target is a form control, the handler exits early and lets the control process keys normally.
|
|
308
|
+
4. Exception: ArrowLeft/ArrowRight inside a data row are handled for intra-row focus movement.
|
|
309
|
+
5. Otherwise, normal grid row/header navigation logic applies.
|
|
294
310
|
|
|
295
311
|
This design ensures:
|
|
296
312
|
|
|
@@ -298,6 +314,7 @@ This design ensures:
|
|
|
298
314
|
- **Spinner increments** (ArrowUp/Down) work for date/time fields
|
|
299
315
|
- **Calendar popups** open with Space and Alt+Down
|
|
300
316
|
- **Grid row navigation** still works when focus is on actual grid rows
|
|
317
|
+
- **Intra-row focus traversal** still works for ArrowLeft/ArrowRight between focusable elements in the same data row
|
|
301
318
|
|
|
302
319
|
### Migration from Older Versions
|
|
303
320
|
|
|
@@ -315,6 +332,8 @@ If you have existing code that manually stops propagation on form control events
|
|
|
315
332
|
/>
|
|
316
333
|
```
|
|
317
334
|
|
|
335
|
+
For row action buttons/controls, ArrowLeft and ArrowRight continue to move focus across focusable elements in the current row.
|
|
336
|
+
|
|
318
337
|
### The isFormControl() Helper
|
|
319
338
|
|
|
320
339
|
The `handleGridKeyDown` handler uses an internal `isFormControl()` helper function to detect whether an event target should be handled by the grid or left alone. This helper:
|
|
@@ -323,6 +342,7 @@ The `handleGridKeyDown` handler uses an internal `isFormControl()` helper functi
|
|
|
323
342
|
- Detects Kendo form components by CSS class (`.k-picker-wrap`, `.k-input-inner`, `.k-textbox`, `[role="combobox"]`)
|
|
324
343
|
- Returns `true` if the element should manage its own keyboard events
|
|
325
344
|
- Allows the grid to skip its navigation logic and let the form control handle the event naturally
|
|
345
|
+
- Is intentionally secondary to scope-guarding (the handler first narrows by grid a11y/content region)
|
|
326
346
|
|
|
327
347
|
### Opting Out
|
|
328
348
|
|
|
@@ -337,6 +357,7 @@ In rare cases where form controls don't match the standard patterns detected by
|
|
|
337
357
|
## Limitations & Assumptions
|
|
338
358
|
|
|
339
359
|
- Assumes Kendo’s Grid DOM structure and popup containers (`.k-animation-container`).
|
|
360
|
+
- Assumes `.k-grid-aria-root` is present in supported Kendo markup; fallback scope selectors are used when markup differs.
|
|
340
361
|
- Built for row-level navigation; cell-level `navigatable` conflicts with this model.
|
|
341
362
|
- Form control detection relies on standard HTML element names and known Kendo component CSS classes. Custom form components that don't match these patterns may need `.stop` modifier on their event handlers.
|
|
342
363
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# useGridActiveFilter
|
|
2
|
+
|
|
3
|
+
[← Back to Composables README](https://github.com/NantHealth/featherk/blob/integration/packages/composables/README.md)
|
|
4
|
+
|
|
5
|
+
Composable that tracks active Grid filter state by field and provides a resolver function you can bind to Grid column definitions.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- Vue 3 Composition API
|
|
10
|
+
- `@progress/kendo-data-query`
|
|
11
|
+
- `@progress/kendo-vue-grid`
|
|
12
|
+
- `@featherk/composables`
|
|
13
|
+
|
|
14
|
+
Install:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @featherk/composables
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Compatibility
|
|
21
|
+
|
|
22
|
+
- Built and tested with Kendo UI for Vue Grid v6.4.1.
|
|
23
|
+
|
|
24
|
+
## Import
|
|
25
|
+
|
|
26
|
+
`useGridActiveFilter` is exported from the package root:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { useGridActiveFilter } from "@featherk/composables";
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { computed, ref } from "vue";
|
|
36
|
+
import type { CompositeFilterDescriptor } from "@progress/kendo-data-query";
|
|
37
|
+
import type { GridFilterChangeEvent, GridColumnProps } from "@progress/kendo-vue-grid";
|
|
38
|
+
import { useGridActiveFilter } from "@featherk/composables";
|
|
39
|
+
|
|
40
|
+
const filter = ref<CompositeFilterDescriptor | undefined>(undefined);
|
|
41
|
+
|
|
42
|
+
const activeClass = useGridActiveFilter(filter);
|
|
43
|
+
|
|
44
|
+
const columns = computed<GridColumnProps[]>(() => [
|
|
45
|
+
{
|
|
46
|
+
field: "ProductName",
|
|
47
|
+
title: "Product Name",
|
|
48
|
+
filterable: true,
|
|
49
|
+
headerClassName: activeClass("ProductName"),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
field: "Category",
|
|
53
|
+
title: "Category",
|
|
54
|
+
filterable: true,
|
|
55
|
+
headerClassName: activeClass("Category"),
|
|
56
|
+
},
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
const filterChange = (event: GridFilterChangeEvent) => {
|
|
60
|
+
filter.value = event.filter;
|
|
61
|
+
};
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Template bindings (essentials shown):
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<Grid
|
|
68
|
+
:columns="columns"
|
|
69
|
+
:filter="filter"
|
|
70
|
+
@filterchange="filterChange" />
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## API
|
|
74
|
+
|
|
75
|
+
### `useGridActiveFilter(filterRef: Ref<CompositeFilterDescriptor | undefined>)`
|
|
76
|
+
|
|
77
|
+
Returns a resolver function for generating field-based class flags.
|
|
78
|
+
|
|
79
|
+
- **Returns** `(field: string) => "active" | ""`
|
|
80
|
+
- Call the returned function inside a `computed` with the column's field name.
|
|
81
|
+
- Returns `"active"` when a filter exists for that field, or `""` when it does not.
|
|
82
|
+
- Vue tracks the `filterRef` dependency automatically — no manual update call is needed.
|
|
83
|
+
|
|
84
|
+
## Behavior Notes
|
|
85
|
+
|
|
86
|
+
- Handles nested filter groups recursively.
|
|
87
|
+
- Ignores malformed/unknown filter nodes safely.
|
|
88
|
+
- If `filterRef` is `undefined` or has no filters, all fields resolve to `""`.
|
|
89
|
+
|
|
90
|
+
## Typical Usage Pattern
|
|
91
|
+
|
|
92
|
+
1. Keep a single `filter` ref that is passed to the Grid and to `useGridActiveFilter`.
|
|
93
|
+
2. Call `useGridActiveFilter(filter)` once to get the `activeClass` resolver.
|
|
94
|
+
3. Inside a `computed` column definition, bind `activeClass("fieldName")` to each filterable column's `headerClassName`.
|
|
95
|
+
4. In `@filterchange`, set `filter.value = event.filter` — Vue reactivity handles the rest.
|
|
96
|
+
|
|
97
|
+
## Styling
|
|
98
|
+
|
|
99
|
+
The composable only provides class state and does not ship CSS.
|
|
100
|
+
|
|
101
|
+
Example:
|
|
102
|
+
|
|
103
|
+
```css
|
|
104
|
+
.k-grid .k-header.active {
|
|
105
|
+
font-weight: 600;
|
|
106
|
+
text-decoration: underline;
|
|
107
|
+
}
|
|
108
|
+
```
|
|
@@ -78,7 +78,7 @@ usePopupTrap({
|
|
|
78
78
|
@change="range.handleChange"
|
|
79
79
|
@keydown="range.handleKeyDown"
|
|
80
80
|
@keyup="range.handleKeyUp"
|
|
81
|
-
@wheel
|
|
81
|
+
@wheel="range.handleWheel"
|
|
82
82
|
@click="range.handleClick"
|
|
83
83
|
@blur="range.handleBlur"
|
|
84
84
|
>
|
|
@@ -189,7 +189,7 @@ Key event bindings:
|
|
|
189
189
|
- `@change="range.handleChange"`
|
|
190
190
|
- `@keydown="range.handleKeyDown"`
|
|
191
191
|
- `@keyup="range.handleKeyUp"`
|
|
192
|
-
- `@wheel
|
|
192
|
+
- `@wheel="range.handleWheel"`
|
|
193
193
|
- `@click="range.handleClick"`
|
|
194
194
|
- `@blur="range.handleBlur"`
|
|
195
195
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@featherk/composables",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"main": "dist/featherk-composables.umd.js",
|
|
5
5
|
"module": "dist/featherk-composables.es.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -43,7 +43,9 @@
|
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "vite build && npm run build:types",
|
|
45
45
|
"build:types": "vue-tsc --emitDeclarationOnly --declaration --declarationDir dist",
|
|
46
|
-
"test": "vitest",
|
|
46
|
+
"test": "vitest --config vitest.config.ts",
|
|
47
|
+
"test:run": "vitest run --config vitest.config.ts",
|
|
48
|
+
"test:coverage": "vitest run --config vitest.config.ts --coverage",
|
|
47
49
|
"clean": "rm -rf dist",
|
|
48
50
|
"prepublishOnly": "npm run build"
|
|
49
51
|
},
|
|
@@ -67,6 +69,7 @@
|
|
|
67
69
|
"devDependencies": {
|
|
68
70
|
"@types/node": "^24.5.2",
|
|
69
71
|
"@vitejs/plugin-vue": "^6.0.1",
|
|
72
|
+
"@vue/test-utils": "^2.4.6",
|
|
70
73
|
"@vueuse/core": "^13.5.0",
|
|
71
74
|
"@vueuse/integrations": "^13.5.0",
|
|
72
75
|
"focus-trap": "^7.6.0",
|
package/dist/useGridFilter.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type Ref } from "vue";
|
|
2
|
-
import type { CompositeFilterDescriptor } from "@progress/kendo-data-query";
|
|
3
|
-
export declare const useGridFilter: (filterRef: Ref<CompositeFilterDescriptor | undefined>) => {
|
|
4
|
-
activeClasses: Ref<Record<string, string>, Record<string, string>>;
|
|
5
|
-
hasFieldFilter: (field: string) => boolean;
|
|
6
|
-
updateActiveClass: (field: string) => void;
|
|
7
|
-
};
|