@featherk/composables 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,19 +1,23 @@
1
+ <!-- # Summary -->
1
2
 
2
- # useGridA11y — Integration Quick Reference
3
+ # `@featherk/composables`
3
4
 
4
- ## BIG DISCLAIMER
5
+ > This package provides Vue 3 composables intended to augment and improve Kendo UI for Vue (Telerik) component behavior.
6
+ >
7
+ > *This package is not affiliated with or approved by Telerik.*
5
8
 
6
- > This package is experimental and NOT READY FOR PRODUCTION. Do not use this package in production environments. The API, types, and build output are unstable. Tests and documentation are incomplete. You may encounter breaking changes, missing features, or rough edges. Use only for local experimentation or as a reference.
9
+ ## useGridA11y Integration Quick Reference
7
10
 
8
- ## Compatibility
11
+ ### BIG DISCLAIMER
9
12
 
10
- > The current version of `useGridA11y` composable was developed targeting Kendo UI for Vue version 6.4.1.
11
- >
12
- > *This library is not affiliated with or approved by Telerik.*
13
+ > This package is experimental and **NOT READY FOR PRODUCTION**. Do not use this package in production environments. The API, types, and build output are unstable. Tests and documentation are incomplete. You may encounter breaking changes, missing features, or rough edges. Use only for local experimentation or as a reference.
13
14
 
14
- ## Short description
15
+ ### Compatibility
15
16
 
16
- `@featherk/composables` provides small Vue 3 composables intended to augment and improve accessibility and behavior for Kendo UI components (Telerik). The library is developed alongside a demo app that shows usage patterns and integration points.
17
+ > The current version of `useGridA11y` composable was developed targeting Kendo UI for Vue version 6.4.1.
18
+ >*Use of Kendo UI for Vue Grid requires a paid [license](https://www.telerik.com/purchase/kendo-ui) from Telerik.*
19
+ >
20
+ >See [Kendo UI for Vue Grid Documentation](https://www.telerik.com/kendo-vue-ui/components/grid)
17
21
 
18
22
  ### Notes
19
23
 
@@ -21,13 +25,13 @@
21
25
  - For row-level navigation, disable the Grid's cell-level dynamic tabindex behavior (omit or set `navigatable="false"` on the Grid).
22
26
  - The composable returns helpers for keyboard handling, focus management, and sort/filter interactions.
23
27
 
24
- ### Styling and the .fk-grid class
28
+ ### Styling and the `.fk-grid` class
25
29
 
26
30
  - The composable will add the CSS class `.fk-grid` to the Grid's root element (see `setupGridStyling()` in the source). The composable itself does NOT include any CSS (no inline styles or stylesheet).
27
31
  - The `.fk-grid` class is a hook used by the FeatherK stylesheet to apply visual styles. To see visual indicators (for example, the active/filtered status), you must include the appropriate FeatherK stylesheet for Kendo in your application.
28
32
  - Ensure you are using the matching FeatherK styling release for correct visuals — e.g. `featherk-q3-2024-v#.css` (replace `#` with the patch version you are using).
29
33
 
30
- ## Prerequisites
34
+ ### Prerequisites
31
35
 
32
36
  - Vue 3 (script setup)
33
37
  - `@progress/kendo-vue-grid` installed
@@ -39,7 +43,7 @@ Install (if needed)
39
43
  npm install @featherk/composables
40
44
  ```
41
45
 
42
- ## 1) Minimal import + setup
46
+ ### 1) Minimal import + setup
43
47
 
44
48
  Place inside a `<script setup lang="ts">` block. Provide a Grid ref and call the composable.
45
49
 
@@ -49,26 +53,27 @@ import { useGridA11y } from '@featherk/composables';
49
53
 
50
54
  const gridRef = ref(null);
51
55
 
52
- const { activeFilterButton, handleGridKeyDown, handleSortChange } = useGridA11y(gridRef);
56
+ const { activeFilterButton, handleGridKeyDown, handleSortChange } =
57
+ useGridA11y(gridRef);
53
58
  ```
54
59
 
55
- ## 2) Wire keyboard handler on the Grid
60
+ ### 2) Wire keyboard handler on the Grid
56
61
 
57
- Template snippet showing essential bindings (keep other Grid props as required by your app):
62
+ Template snippet showing essential bindings (keep other `Grid` props as required by your app):
58
63
 
59
64
  ```html
60
65
  <Grid
61
66
  ref="gridRef"
62
67
  :dataItems="dataResult.data"
63
68
  :dataItemKey="'id'"
64
- :rowRender="renderRow"
65
- @keydown="handleGridKeyDown" <!-- keyboard navigation -->
66
- @sortchange="handleSortChange" <!-- composable-aware sort handling -->
67
- navigatable="false" <!-- optional: prefer row-level nav -->
69
+ :rowRender="renderRow" // optional: aria-label for screen reader
70
+ @keydown="handleGridKeyDown" // keyboard navigation
71
+ @sortchange="handleSortChange" // composable-aware sort handling
72
+ navigatable="false" // turn off cell to cell navigation
68
73
  />
69
74
  ```
70
75
 
71
- ## 3) Provide an accessible row renderer (`aria-label`)
76
+ ### 3) Provide an accessible row renderer (`aria-label`)
72
77
 
73
78
  > Not part of `@featherk/composable`, but good practice
74
79
 
@@ -83,7 +88,7 @@ const renderRow = (h: any, trElement: any, defaultSlots: any, props: any) => {
83
88
  };
84
89
  ```
85
90
 
86
- ## 4) Focus the active filter button after filter changes
91
+ ### 4) Focus the active filter button after filter changes
87
92
 
88
93
  The composable returns `activeFilterButton` (a ref) which you can focus after DOM updates.
89
94
 
@@ -101,7 +106,7 @@ function onFilterChange(event: any) {
101
106
  }
102
107
  ```
103
108
 
104
- ## 5) Custom sort handling with composable helper
109
+ ### 5) Custom sort handling with composable helper
105
110
 
106
111
  If you need to show a loader or call an API, pass a custom callback into the composable's sort helper so the composable does its internal work and your app performs side effects.
107
112
 
@@ -120,11 +125,11 @@ function onSortChange(event: any) {
120
125
  }
121
126
  ```
122
127
 
123
- ## 6) Summary checklist
128
+ ### 6) Summary checklist
124
129
 
125
130
  - Import and call `useGridA11y(gridRef)`
126
- - Bind returned keyboard handler to Grid `@keydown`
127
- - Bind returned sort handler to Grid `@sortchange` (and optionally pass a custom callback)
131
+ - Bind returned keyboard handler to `Grid` `@keydown`
132
+ - Bind returned sort handler to `Grid` `@sortchange` (and optionally pass a custom callback)
128
133
  - Use returned `activeFilterButton` to manage focus after filter updates
129
134
  - Provide a `rowRender` that adds a descriptive `aria-label` for each row
130
- - Set `navigatable="false"` on the Grid to prefer row-level navigation
135
+ - Set `navigatable="false"` on the `Grid` to prefer row-level navigation
@@ -263,7 +263,7 @@ const G = (f) => {
263
263
  );
264
264
  }
265
265
  const i = e.dataset.featherKFilterable !== "false", l = e.dataset.featherKSortable !== "false";
266
- n.setAttribute("tabindex", "-1"), i ? (e.setAttribute("tabindex", "0"), e.setAttribute("role", "button"), e.setAttribute("aria-haspopup", "menu"), e.style.cursor = "pointer") : (e.setAttribute("tabindex", "0"), e.setAttribute("role", "columnheader"), e.removeAttribute("aria-haspopup"), e.style.cursor = "default");
266
+ n.setAttribute("tabindex", "-1"), i || l ? e.style.cursor = "pointer" : e.style.cursor = "default", i ? (e.setAttribute("tabindex", "0"), e.setAttribute("role", "button"), e.setAttribute("aria-haspopup", "menu")) : (e.setAttribute("tabindex", "0"), e.setAttribute("role", "columnheader"), e.removeAttribute("aria-haspopup"));
267
267
  const d = (c) => {
268
268
  c.target?.closest(".k-column-resizer") || (s.value = e, n.click());
269
269
  }, v = (c) => {
@@ -1 +1 @@
1
- (function(m,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],c):(m=typeof globalThis<"u"?globalThis:m||self,c(m.FeatherKComposables={},m.Vue))})(this,(function(m,c){"use strict";const S=b=>{const s=c.ref(null);let p=null,d=null;const k=[],h=".k-table-row[data-grid-row-index] [tabindex]",g=()=>b?.value?.columns,v=t=>{const o=t.key||t.code;[" ","Spacebar","Space","Enter"].includes(o)&&(t.preventDefault(),t.stopPropagation(),s.value=t.target,t.target.click())},y=t=>{if(!s.value)return;if(t.code==="Escape"){t.preventDefault(),t.stopPropagation(),s.value&&s.value.focus();return}const o=Array.from(document.querySelectorAll(".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item")),e=document.querySelector(".k-filter-menu-container");if(e){if(t.code==="Tab"){const n=[".k-filter-menu-container .k-dropdownlist[tabindex='0']",".k-filter-menu-container input.k-input-inner:not([tabindex='-1']):not([disabled])",".k-filter-menu-container button:not([tabindex='-1']):not([disabled])"],r=Array.from(e.querySelectorAll(n.join(",")));if(r.length===0)return;const a=r.findIndex(l=>l===document.activeElement);let i;a===-1?i=0:t.shiftKey?i=(a-1+r.length)%r.length:i=(a+1)%r.length,t.preventDefault(),t.stopPropagation(),r[i]?.focus();return}}else if(t.code==="ArrowUp"||t.code==="ArrowDown"){t.preventDefault(),t.stopPropagation();const n=o.findIndex(a=>a===document.activeElement);let r=n;t.code==="ArrowUp"?r=n>0?n-1:o.length-1:t.code==="ArrowDown"&&(r=n<o.length-1?n+1:0),o[r]?.focus();return}t.code==="Tab"&&(t.preventDefault(),t.stopPropagation(),t.shiftKey?(s.value?.previousElementSibling).focus():(s.value?.nextElementSibling).focus())},L=()=>{p=new MutationObserver(t=>{t.forEach(o=>{o.addedNodes.forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const n=e;if(n.classList.contains("k-animation-container")){const a=s.value;a&&(a.dataset.featherKSortable==="true"||c.nextTick(()=>{n.querySelectorAll(".k-columnmenu-item-wrapper").forEach(f=>{f.textContent?.toLowerCase().includes("sort")&&f.remove()})})),n.addEventListener("keydown",y),c.nextTick(()=>{const i=()=>{const l=Array.from(n.querySelectorAll(".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item"));if(l.length===1)l[0].focus(),l[0].click(),i.attempts=0;else if(l.length>1){i.attempts=0;return}else i.attempts===void 0&&(i.attempts=0),i.attempts++<3&&setTimeout(i,200)};i()})}n.querySelectorAll(".k-animation-container").forEach(a=>{a.addEventListener("keydown",y)})}}),o.removedNodes.forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const n=e;n.classList.contains("k-animation-container")&&n.removeEventListener("keydown",y),n.querySelectorAll(".k-animation-container").forEach(a=>{a.removeEventListener("keydown",y)})}})})}),p.observe(document.body,{childList:!0,subtree:!0})},T=t=>{if(!t.type||!t)return;console.log("handleGridKeyDown",t,t.code);const o=t.target;if(o){if(t.code==="Escape"){const e=document.activeElement?.closest(".k-table-row[data-grid-row-index]");if(e){t.preventDefault(),t.stopPropagation();try{Array.from(b?.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]")).forEach(r=>r.setAttribute("tabindex","-1"))}catch{}e.setAttribute("tabindex","0"),e.focus();return}}if(["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","Enter","Space"].includes(t.code)){if(t.preventDefault(),o.classList.contains("k-grid-header-menu")&&o.classList.contains("k-grid-column-menu")){s.value=o;return}const e=o.closest(".k-table-row[data-grid-row-index]");if(e){if(["ArrowDown","ArrowUp"].includes(t.code)){const n=(a,i)=>{let l=i==="next"?a.nextElementSibling:a.previousElementSibling;for(;l;){const f=l;try{if(f.hasAttribute&&f.classList.contains("k-table-row"))return f}catch{}l=i==="next"?l.nextElementSibling:l.previousElementSibling}return null},r=t.code==="ArrowDown"?n(e,"next"):n(e,"previous");r&&(e.setAttribute("tabindex","-1"),r.setAttribute("tabindex","0"),r.focus());return}if(["ArrowLeft","ArrowRight"].includes(t.code)){t.preventDefault();const n=e.querySelectorAll(h);if(n.length===0)return;let r=Array.from(n).findIndex(a=>a===document.activeElement);if(r===-1&&document.activeElement===e){n[0].focus();return}t.code==="ArrowRight"?r=r===n.length-1?0:r+1:t.code==="ArrowLeft"&&(r=r===n.length-1?r-1:n.length-1),n[r].focus();return}}}}},D=()=>{c.nextTick(()=>{const t=b.value.$el.closest(".k-grid");t&&t.classList.add("fk-grid")})},q=()=>{try{const t=()=>{try{const n=Array.from(b.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]"));if(!n||n.length===0||n.filter(i=>i.getAttribute("tabindex")==="0").length===1)return;const a=n.find(i=>i===document.activeElement||i.contains(document.activeElement));if(n.forEach(i=>i.setAttribute("tabindex","-1")),a){a.setAttribute("tabindex","0");return}n[0].setAttribute("tabindex","0")}catch(n){console.error("ensureSingleTabindex error:",n)}},o=Array.from(b.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]"));o.length>0&&o.forEach((n,r)=>{n.setAttribute("tabindex",r===0?"0":"-1")});const e=b.value.$el.querySelector(".k-table-tbody");e&&(d=new MutationObserver(()=>{t()}),d.observe(e,{childList:!0,subtree:!0}))}catch(t){console.error("Error setting up row navigation:",t)}},C=()=>{c.nextTick(()=>{const o=document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");o&&o.forEach(e=>{e.setAttribute("role","button"),e.addEventListener("keydown",v)}),L(),K()})},I=()=>{const o=document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");o&&o.forEach(e=>{e.removeEventListener("keydown",v)}),p&&(p.disconnect(),p=null),d&&(d.disconnect(),d=null),k.forEach(e=>e()),k.length=0},K=()=>{document.querySelectorAll(".k-grid-header .k-table-thead th").forEach((e,n)=>{const r=e.querySelector(".k-grid-header-menu.k-grid-column-menu");if(!r)return;const a=g();if(a&&a[n]){const u=a[n].field??"";e.setAttribute("data-feather-k-field",u),e.setAttribute("data-feather-k-filterable",a[n].filterable===!1?"false":"true"),e.setAttribute("data-feather-k-sortable",a[n].sortable===!1?"false":"true")}const i=e.dataset.featherKFilterable!=="false",l=e.dataset.featherKSortable!=="false";r.setAttribute("tabindex","-1"),i?(e.setAttribute("tabindex","0"),e.setAttribute("role","button"),e.setAttribute("aria-haspopup","menu"),e.style.cursor="pointer"):(e.setAttribute("tabindex","0"),e.setAttribute("role","columnheader"),e.removeAttribute("aria-haspopup"),e.style.cursor="default");const f=u=>{u.target?.closest(".k-column-resizer")||(s.value=e,r.click())},A=u=>{if(i)s.value=e,u.preventDefault(),u.stopPropagation(),f(u);else if(l){s.value=e;const w=new KeyboardEvent("keydown",{key:"Enter",code:"Enter",keyCode:13,which:13,bubbles:!0,cancelable:!0});e.dispatchEvent(w)}};e.addEventListener("click",A),k.push(()=>{e.removeEventListener("click",A)});const E=u=>{if((u.code==="Enter"||u.code==="Space")&&(i||l)){if(s.value=e,s.value.focus(),i)u.preventDefault(),u.stopPropagation(),f(u);else if(l){const w=e.querySelector(".k-link");w&&w.click()}}};e.addEventListener("keydown",E,!0),k.push(()=>{e.removeEventListener("keydown",E,!0)})});const o=document.querySelector(".k-grid-header .k-table-thead");if(o){const e=n=>{const r=n.target.closest("th");r&&(n.code==="Enter"||n.code==="Space")&&r.dataset.featherKFilterable==="false"&&r.dataset.featherKSortable==="false"&&(n.preventDefault(),n.stopImmediatePropagation())};o.addEventListener("keydown",e,!0),k.push(()=>{o.removeEventListener("keydown",e,!0)})}},M=function(t,o){const e=t?.event.event.target,n=g();if(!e||!n)return;const r=e.classList.contains("k-link"),a=e.classList.contains("k-columnmenu-item"),i=n.find(l=>l.field===t.event.field)?.sortable&&!0;if(!r){if(a&&!i){(t.event.sort&&void 0)?.filter(f=>f.field!==t.event.field);return}typeof o=="function"&&c.nextTick(()=>{s.value&&s.value.focus(),o(t)})}};return c.onMounted(()=>{D(),q(),C()}),c.onBeforeUnmount(()=>{I()}),{activeFilterButton:s,handleGridKeyDown:T,handleSortChange:M}};function x(b={}){const{activeByDefault:s=!1,autoActivateDelay:p=0}=b,d=c.ref(s);function k(){d.value=!0}function h(){d.value=!1}function g(){d.value=!d.value}return c.onMounted(()=>{p>0&&!s&&setTimeout(()=>{k()},p)}),c.onUnmounted(()=>{}),{isGridActive:d,activateGrid:k,deactivateGrid:h,toggleGrid:g}}m.useGridA11y=S,m.useGridComposableEx=x,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(m,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],c):(m=typeof globalThis<"u"?globalThis:m||self,c(m.FeatherKComposables={},m.Vue))})(this,(function(m,c){"use strict";const S=b=>{const s=c.ref(null);let p=null,d=null;const k=[],h=".k-table-row[data-grid-row-index] [tabindex]",g=()=>b?.value?.columns,v=t=>{const o=t.key||t.code;[" ","Spacebar","Space","Enter"].includes(o)&&(t.preventDefault(),t.stopPropagation(),s.value=t.target,t.target.click())},y=t=>{if(!s.value)return;if(t.code==="Escape"){t.preventDefault(),t.stopPropagation(),s.value&&s.value.focus();return}const o=Array.from(document.querySelectorAll(".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item")),e=document.querySelector(".k-filter-menu-container");if(e){if(t.code==="Tab"){const n=[".k-filter-menu-container .k-dropdownlist[tabindex='0']",".k-filter-menu-container input.k-input-inner:not([tabindex='-1']):not([disabled])",".k-filter-menu-container button:not([tabindex='-1']):not([disabled])"],r=Array.from(e.querySelectorAll(n.join(",")));if(r.length===0)return;const a=r.findIndex(l=>l===document.activeElement);let i;a===-1?i=0:t.shiftKey?i=(a-1+r.length)%r.length:i=(a+1)%r.length,t.preventDefault(),t.stopPropagation(),r[i]?.focus();return}}else if(t.code==="ArrowUp"||t.code==="ArrowDown"){t.preventDefault(),t.stopPropagation();const n=o.findIndex(a=>a===document.activeElement);let r=n;t.code==="ArrowUp"?r=n>0?n-1:o.length-1:t.code==="ArrowDown"&&(r=n<o.length-1?n+1:0),o[r]?.focus();return}t.code==="Tab"&&(t.preventDefault(),t.stopPropagation(),t.shiftKey?(s.value?.previousElementSibling).focus():(s.value?.nextElementSibling).focus())},L=()=>{p=new MutationObserver(t=>{t.forEach(o=>{o.addedNodes.forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const n=e;if(n.classList.contains("k-animation-container")){const a=s.value;a&&(a.dataset.featherKSortable==="true"||c.nextTick(()=>{n.querySelectorAll(".k-columnmenu-item-wrapper").forEach(f=>{f.textContent?.toLowerCase().includes("sort")&&f.remove()})})),n.addEventListener("keydown",y),c.nextTick(()=>{const i=()=>{const l=Array.from(n.querySelectorAll(".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item"));if(l.length===1)l[0].focus(),l[0].click(),i.attempts=0;else if(l.length>1){i.attempts=0;return}else i.attempts===void 0&&(i.attempts=0),i.attempts++<3&&setTimeout(i,200)};i()})}n.querySelectorAll(".k-animation-container").forEach(a=>{a.addEventListener("keydown",y)})}}),o.removedNodes.forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const n=e;n.classList.contains("k-animation-container")&&n.removeEventListener("keydown",y),n.querySelectorAll(".k-animation-container").forEach(a=>{a.removeEventListener("keydown",y)})}})})}),p.observe(document.body,{childList:!0,subtree:!0})},T=t=>{if(!t.type||!t)return;console.log("handleGridKeyDown",t,t.code);const o=t.target;if(o){if(t.code==="Escape"){const e=document.activeElement?.closest(".k-table-row[data-grid-row-index]");if(e){t.preventDefault(),t.stopPropagation();try{Array.from(b?.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]")).forEach(r=>r.setAttribute("tabindex","-1"))}catch{}e.setAttribute("tabindex","0"),e.focus();return}}if(["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","Enter","Space"].includes(t.code)){if(t.preventDefault(),o.classList.contains("k-grid-header-menu")&&o.classList.contains("k-grid-column-menu")){s.value=o;return}const e=o.closest(".k-table-row[data-grid-row-index]");if(e){if(["ArrowDown","ArrowUp"].includes(t.code)){const n=(a,i)=>{let l=i==="next"?a.nextElementSibling:a.previousElementSibling;for(;l;){const f=l;try{if(f.hasAttribute&&f.classList.contains("k-table-row"))return f}catch{}l=i==="next"?l.nextElementSibling:l.previousElementSibling}return null},r=t.code==="ArrowDown"?n(e,"next"):n(e,"previous");r&&(e.setAttribute("tabindex","-1"),r.setAttribute("tabindex","0"),r.focus());return}if(["ArrowLeft","ArrowRight"].includes(t.code)){t.preventDefault();const n=e.querySelectorAll(h);if(n.length===0)return;let r=Array.from(n).findIndex(a=>a===document.activeElement);if(r===-1&&document.activeElement===e){n[0].focus();return}t.code==="ArrowRight"?r=r===n.length-1?0:r+1:t.code==="ArrowLeft"&&(r=r===n.length-1?r-1:n.length-1),n[r].focus();return}}}}},D=()=>{c.nextTick(()=>{const t=b.value.$el.closest(".k-grid");t&&t.classList.add("fk-grid")})},q=()=>{try{const t=()=>{try{const n=Array.from(b.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]"));if(!n||n.length===0||n.filter(i=>i.getAttribute("tabindex")==="0").length===1)return;const a=n.find(i=>i===document.activeElement||i.contains(document.activeElement));if(n.forEach(i=>i.setAttribute("tabindex","-1")),a){a.setAttribute("tabindex","0");return}n[0].setAttribute("tabindex","0")}catch(n){console.error("ensureSingleTabindex error:",n)}},o=Array.from(b.value.$el.querySelectorAll(".k-table-row[data-grid-row-index]"));o.length>0&&o.forEach((n,r)=>{n.setAttribute("tabindex",r===0?"0":"-1")});const e=b.value.$el.querySelector(".k-table-tbody");e&&(d=new MutationObserver(()=>{t()}),d.observe(e,{childList:!0,subtree:!0}))}catch(t){console.error("Error setting up row navigation:",t)}},C=()=>{c.nextTick(()=>{const o=document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");o&&o.forEach(e=>{e.setAttribute("role","button"),e.addEventListener("keydown",v)}),L(),K()})},I=()=>{const o=document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");o&&o.forEach(e=>{e.removeEventListener("keydown",v)}),p&&(p.disconnect(),p=null),d&&(d.disconnect(),d=null),k.forEach(e=>e()),k.length=0},K=()=>{document.querySelectorAll(".k-grid-header .k-table-thead th").forEach((e,n)=>{const r=e.querySelector(".k-grid-header-menu.k-grid-column-menu");if(!r)return;const a=g();if(a&&a[n]){const u=a[n].field??"";e.setAttribute("data-feather-k-field",u),e.setAttribute("data-feather-k-filterable",a[n].filterable===!1?"false":"true"),e.setAttribute("data-feather-k-sortable",a[n].sortable===!1?"false":"true")}const i=e.dataset.featherKFilterable!=="false",l=e.dataset.featherKSortable!=="false";r.setAttribute("tabindex","-1"),i||l?e.style.cursor="pointer":e.style.cursor="default",i?(e.setAttribute("tabindex","0"),e.setAttribute("role","button"),e.setAttribute("aria-haspopup","menu")):(e.setAttribute("tabindex","0"),e.setAttribute("role","columnheader"),e.removeAttribute("aria-haspopup"));const f=u=>{u.target?.closest(".k-column-resizer")||(s.value=e,r.click())},A=u=>{if(i)s.value=e,u.preventDefault(),u.stopPropagation(),f(u);else if(l){s.value=e;const w=new KeyboardEvent("keydown",{key:"Enter",code:"Enter",keyCode:13,which:13,bubbles:!0,cancelable:!0});e.dispatchEvent(w)}};e.addEventListener("click",A),k.push(()=>{e.removeEventListener("click",A)});const E=u=>{if((u.code==="Enter"||u.code==="Space")&&(i||l)){if(s.value=e,s.value.focus(),i)u.preventDefault(),u.stopPropagation(),f(u);else if(l){const w=e.querySelector(".k-link");w&&w.click()}}};e.addEventListener("keydown",E,!0),k.push(()=>{e.removeEventListener("keydown",E,!0)})});const o=document.querySelector(".k-grid-header .k-table-thead");if(o){const e=n=>{const r=n.target.closest("th");r&&(n.code==="Enter"||n.code==="Space")&&r.dataset.featherKFilterable==="false"&&r.dataset.featherKSortable==="false"&&(n.preventDefault(),n.stopImmediatePropagation())};o.addEventListener("keydown",e,!0),k.push(()=>{o.removeEventListener("keydown",e,!0)})}},M=function(t,o){const e=t?.event.event.target,n=g();if(!e||!n)return;const r=e.classList.contains("k-link"),a=e.classList.contains("k-columnmenu-item"),i=n.find(l=>l.field===t.event.field)?.sortable&&!0;if(!r){if(a&&!i){(t.event.sort&&void 0)?.filter(f=>f.field!==t.event.field);return}typeof o=="function"&&c.nextTick(()=>{s.value&&s.value.focus(),o(t)})}};return c.onMounted(()=>{D(),q(),C()}),c.onBeforeUnmount(()=>{I()}),{activeFilterButton:s,handleGridKeyDown:T,handleSortChange:M}};function x(b={}){const{activeByDefault:s=!1,autoActivateDelay:p=0}=b,d=c.ref(s);function k(){d.value=!0}function h(){d.value=!1}function g(){d.value=!d.value}return c.onMounted(()=>{p>0&&!s&&setTimeout(()=>{k()},p)}),c.onUnmounted(()=>{}),{isGridActive:d,activateGrid:k,deactivateGrid:h,toggleGrid:g}}m.useGridA11y=S,m.useGridComposableEx=x,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@featherk/composables",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "main": "dist/featherk-composables.umd.js",
5
5
  "module": "dist/featherk-composables.es.js",
6
6
  "types": "dist/index.d.ts",
@@ -28,5 +28,13 @@
28
28
  "publishConfig": {
29
29
  "access": "public"
30
30
  },
31
+ "keywords": [
32
+ "vue",
33
+ "composables",
34
+ "kendo",
35
+ "telerik",
36
+ "a11y",
37
+ "accessibility"
38
+ ],
31
39
  "license": "MIT"
32
40
  }