@featherk/composables 0.0.5 → 0.0.6

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,70 +1,124 @@
1
- # @featherk/composables — Summary
2
1
 
3
- IMPORTANT: This package is experimental and NOT READY FOR PRODUCTION.
2
+ # useGridA11y Integration Quick Reference
4
3
 
5
- > BIG DISCLAIMER — 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.
4
+ ## BIG DISCLAIMER
5
+
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.
7
+
8
+ ## Compatibility
9
+
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.*
6
13
 
7
14
  ## Short description
8
15
 
9
- `@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.
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
+
18
+ ### Notes
19
+
20
+ - The composable expects a Grid ref (a Vue ref to the Grid component).
21
+ - For row-level navigation, disable the Grid's cell-level dynamic tabindex behavior (omit or set `navigatable="false"` on the Grid).
22
+ - The composable returns helpers for keyboard handling, focus management, and sort/filter interactions.
10
23
 
11
- ## Key points
24
+ ## Prerequisites
12
25
 
13
- - Vue 3 + Composition API
14
- - TypeScript (partial coverage; some types may be missing or incomplete)
15
- - Designed to be used inside a monorepo (Turborepo) with a demo app at `demos/` and package sources in `packages/composables/src/`
26
+ - Vue 3 (script setup)
27
+ - `@progress/kendo-vue-grid` installed
28
+ - `@featherk/composables` installed
16
29
 
17
- ## What this README contains
30
+ Install (if needed)
18
31
 
19
- - Purpose and high-level features
20
- - Current stability/status and the critical disclaimer
21
- - Quick local build / demo steps to try the code (for contributors)
22
- - Where to look in the repo for implementation and exports
32
+ ```bash
33
+ npm install @featherk/composables
34
+ ```
23
35
 
24
- ## Status / Stability
36
+ ## 1) Minimal import + setup
25
37
 
26
- This package is an early-stage library and intentionally marked as experimental:
38
+ Place inside a `<script setup lang="ts">` block. Provide a Grid ref and call the composable.
27
39
 
28
- - API: Unstable. Expect breaking changes.
29
- - Types: Partial. Some public functions and returned shapes may lack strict TypeScript types.
30
- - Tests: Minimal or missing. Run tests before trusting behavior.
31
- - Documentation: Sample usage is mainly in the demo app; inline documentation is minimal.
32
- - Compatibility: Not officially supported by or affiliated with Telerik.
40
+ ```ts
41
+ import { ref } from 'vue';
42
+ import { useGridA11y } from '@featherk/composables';
33
43
 
34
- If you need production-ready composables, consider using broadly-adopted libraries or implementing small, well-scoped utilities locally.
44
+ const gridRef = ref(null);
35
45
 
36
- ## Quick start (for contributors)
46
+ const { activeFilterButton, handleGridKeyDown, handleSortChange } = useGridA11y(gridRef);
47
+ ```
37
48
 
38
- From the repository root you can build and run the demo to exercise the composables locally. Replace `npm` with your package manager if needed.
49
+ ## 2) Wire keyboard handler on the Grid
39
50
 
40
- ```bash
41
- # build the composables package only
42
- npm run build:composables
51
+ Template snippet showing essential bindings (keep other Grid props as required by your app):
43
52
 
44
- # run the demo app (dev server)
45
- npm run dev:demo
53
+ ```html
54
+ <Grid
55
+ ref="gridRef"
56
+ :dataItems="dataResult.data"
57
+ :dataItemKey="'id'"
58
+ :rowRender="renderRow"
59
+ @keydown="handleGridKeyDown" <!-- keyboard navigation -->
60
+ @sortchange="handleSortChange" <!-- composable-aware sort handling -->
61
+ navigatable="false" <!-- optional: prefer row-level nav -->
62
+ />
46
63
  ```
47
64
 
48
- ## Where to look
65
+ ## 3) Provide an accessible row renderer (`aria-label`)
49
66
 
50
- - Source code: `packages/composables/src/`
51
- - Public exports: `packages/composables/src/index.ts`
52
- - Types: `packages/composables/src/types/`
53
- - Demo usage: `demos/src/components/composables/` and `demos/src/App.vue`
67
+ > Not part of `@featherk/composable`, but good practice
54
68
 
55
- ## Contributing notes
69
+ Kendo Grid `rowRender` allows you to add an `aria-label` so screen readers announce row contents.
56
70
 
57
- - Add composables inside `packages/composables/src/` and export them from `index.ts`.
58
- - Keep changes small and documented. Add tests for new behavior where reasonable.
59
- - Build the composables package before running the demo to ensure the demo picks up local changes.
71
+ ```ts
72
+ const renderRow = (h: any, trElement: any, defaultSlots: any, props: any) => {
73
+ const ariaLabel = `Name: ${props.dataItem.name}, Price: ${props.dataItem.price}`;
74
+ // merge existing props and add aria-label
75
+ const merged = { ...trElement.props, 'aria-label': ariaLabel };
76
+ return h('tr', merged, defaultSlots);
77
+ };
78
+ ```
60
79
 
61
- ## Next steps (recommended)
80
+ ## 4) Focus the active filter button after filter changes
62
81
 
63
- - Add unit tests and a CI job (currently missing or minimal).
64
- - Improve TypeScript coverage for public API shapes.
65
- - Add examples and API docs for each composable.
66
- - Consider adding a clear versioning strategy (semver) and a roadmap stating when the package will be considered stable.
82
+ The composable returns `activeFilterButton` (a ref) which you can focus after DOM updates.
83
+
84
+ ```ts
85
+ import { nextTick } from 'vue';
86
+
87
+ function onFilterChange(event: any) {
88
+ // update your filter state and data here
89
+
90
+ nextTick(() => {
91
+ if (activeFilterButton.value) {
92
+ activeFilterButton.value.focus();
93
+ }
94
+ });
95
+ }
96
+ ```
97
+
98
+ ## 5) Custom sort handling with composable helper
99
+
100
+ 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.
101
+
102
+ ```ts
103
+ const optionalCustomSort = (event: any) => {
104
+ loader.value = true;
105
+ // example async
106
+ setTimeout(() => {
107
+ loader.value = false;
108
+ // apply sort state and reload data
109
+ }, 200);
110
+ };
111
+
112
+ function onSortChange(event: any) {
113
+ handleSortChange(event, optionalCustomSort);
114
+ }
115
+ ```
67
116
 
68
- ## License
117
+ ## 6) Summary checklist
69
118
 
70
- See top-level `LICENSE` for repository licensing information.
119
+ - Import and call `useGridA11y(gridRef)`
120
+ - Bind returned keyboard handler to Grid `@keydown`
121
+ - Bind returned sort handler to Grid `@sortchange` (and optionally pass a custom callback)
122
+ - Use returned `activeFilterButton` to manage focus after filter updates
123
+ - Provide a `rowRender` that adds a descriptive `aria-label` for each row
124
+ - Set `navigatable="false"` on the Grid to prefer row-level navigation
@@ -1,75 +1,75 @@
1
1
  import { ref as E, onMounted as S, onBeforeUnmount as M, nextTick as p, onUnmounted as N } from "vue";
2
- const G = (m) => {
3
- const l = E(null);
4
- let d = null, u = null;
5
- const f = [], v = ".k-table-row[data-grid-row-index] [tabindex]", k = () => m?.value?.columns, h = (e) => {
6
- const o = e.key || e.code;
7
- [" ", "Spacebar", "Space", "Enter"].includes(o) && (e.preventDefault(), e.stopPropagation(), l.value = e.target, e.target.click());
8
- }, g = (e) => {
9
- if (!l.value) return;
10
- if (e.code === "Escape") {
11
- e.preventDefault(), e.stopPropagation(), l.value && l.value.focus();
2
+ const G = (b) => {
3
+ const s = E(null);
4
+ let f = null, u = null;
5
+ const m = [], v = ".k-table-row[data-grid-row-index] [tabindex]", k = () => b?.value?.columns, h = (t) => {
6
+ const o = t.key || t.code;
7
+ [" ", "Spacebar", "Space", "Enter"].includes(o) && (t.preventDefault(), t.stopPropagation(), s.value = t.target, t.target.click());
8
+ }, g = (t) => {
9
+ if (!s.value) return;
10
+ if (t.code === "Escape") {
11
+ t.preventDefault(), t.stopPropagation(), s.value && s.value.focus();
12
12
  return;
13
13
  }
14
14
  const o = Array.from(
15
15
  document.querySelectorAll(
16
16
  ".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item"
17
17
  )
18
- ), t = document.querySelector(".k-filter-menu-container");
19
- if (t) {
20
- if (e.code === "Tab") {
21
- const r = [
18
+ ), e = document.querySelector(".k-filter-menu-container");
19
+ if (e) {
20
+ if (t.code === "Tab") {
21
+ const n = [
22
22
  ".k-filter-menu-container .k-dropdownlist[tabindex='0']",
23
23
  ".k-filter-menu-container input.k-input-inner:not([tabindex='-1']):not([disabled])",
24
24
  ".k-filter-menu-container button:not([tabindex='-1']):not([disabled])"
25
- ], n = Array.from(
26
- t.querySelectorAll(r.join(","))
25
+ ], r = Array.from(
26
+ e.querySelectorAll(n.join(","))
27
27
  );
28
- if (n.length === 0) return;
29
- const a = n.findIndex(
30
- (s) => s === document.activeElement
28
+ if (r.length === 0) return;
29
+ const a = r.findIndex(
30
+ (l) => l === document.activeElement
31
31
  );
32
32
  let i;
33
- a === -1 ? i = 0 : e.shiftKey ? i = (a - 1 + n.length) % n.length : i = (a + 1) % n.length, e.preventDefault(), e.stopPropagation(), n[i]?.focus();
33
+ 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();
34
34
  return;
35
35
  }
36
- } else if (e.code === "ArrowUp" || e.code === "ArrowDown") {
37
- e.preventDefault(), e.stopPropagation();
38
- const r = o.findIndex(
36
+ } else if (t.code === "ArrowUp" || t.code === "ArrowDown") {
37
+ t.preventDefault(), t.stopPropagation();
38
+ const n = o.findIndex(
39
39
  (a) => a === document.activeElement
40
40
  );
41
- let n = r;
42
- e.code === "ArrowUp" ? n = r > 0 ? r - 1 : o.length - 1 : e.code === "ArrowDown" && (n = r < o.length - 1 ? r + 1 : 0), o[n]?.focus();
41
+ let r = n;
42
+ 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();
43
43
  return;
44
44
  }
45
- e.code === "Tab" && (e.preventDefault(), e.stopPropagation(), e.shiftKey ? (l.value?.previousElementSibling).focus() : (l.value?.nextElementSibling).focus());
45
+ t.code === "Tab" && (t.preventDefault(), t.stopPropagation(), t.shiftKey ? (s.value?.previousElementSibling).focus() : (s.value?.nextElementSibling).focus());
46
46
  }, x = () => {
47
- d = new MutationObserver((e) => {
48
- e.forEach((o) => {
49
- o.addedNodes.forEach((t) => {
50
- if (t.nodeType === Node.ELEMENT_NODE) {
51
- const r = t;
52
- if (r.classList.contains("k-animation-container")) {
53
- const a = l.value;
47
+ f = new MutationObserver((t) => {
48
+ t.forEach((o) => {
49
+ o.addedNodes.forEach((e) => {
50
+ if (e.nodeType === Node.ELEMENT_NODE) {
51
+ const n = e;
52
+ if (n.classList.contains("k-animation-container")) {
53
+ const a = s.value;
54
54
  a && (a.dataset.featherKSortable === "true" || p(() => {
55
- r.querySelectorAll(
55
+ n.querySelectorAll(
56
56
  ".k-columnmenu-item-wrapper"
57
- ).forEach((b) => {
58
- b.textContent?.toLowerCase().includes("sort") && b.remove();
57
+ ).forEach((d) => {
58
+ d.textContent?.toLowerCase().includes("sort") && d.remove();
59
59
  });
60
- })), r.addEventListener(
60
+ })), n.addEventListener(
61
61
  "keydown",
62
62
  g
63
63
  ), p(() => {
64
64
  const i = () => {
65
- const s = Array.from(
66
- r.querySelectorAll(
65
+ const l = Array.from(
66
+ n.querySelectorAll(
67
67
  ".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item"
68
68
  )
69
69
  );
70
- if (s.length === 1)
71
- s[0].focus(), s[0].click(), i.attempts = 0;
72
- else if (s.length > 1) {
70
+ if (l.length === 1)
71
+ l[0].focus(), l[0].click(), i.attempts = 0;
72
+ else if (l.length > 1) {
73
73
  i.attempts = 0;
74
74
  return;
75
75
  } else
@@ -78,7 +78,7 @@ const G = (m) => {
78
78
  i();
79
79
  });
80
80
  }
81
- r.querySelectorAll(
81
+ n.querySelectorAll(
82
82
  ".k-animation-container"
83
83
  ).forEach((a) => {
84
84
  a.addEventListener(
@@ -87,13 +87,13 @@ const G = (m) => {
87
87
  );
88
88
  });
89
89
  }
90
- }), o.removedNodes.forEach((t) => {
91
- if (t.nodeType === Node.ELEMENT_NODE) {
92
- const r = t;
93
- r.classList.contains("k-animation-container") && r.removeEventListener(
90
+ }), o.removedNodes.forEach((e) => {
91
+ if (e.nodeType === Node.ELEMENT_NODE) {
92
+ const n = e;
93
+ n.classList.contains("k-animation-container") && n.removeEventListener(
94
94
  "keydown",
95
95
  g
96
- ), r.querySelectorAll(
96
+ ), n.querySelectorAll(
97
97
  ".k-animation-container"
98
98
  ).forEach((a) => {
99
99
  a.removeEventListener(
@@ -104,15 +104,15 @@ const G = (m) => {
104
104
  }
105
105
  });
106
106
  });
107
- }), d.observe(document.body, {
107
+ }), f.observe(document.body, {
108
108
  childList: !0,
109
109
  subtree: !0
110
110
  });
111
- }, L = (e) => {
112
- if (!e.type || !e)
111
+ }, L = (t) => {
112
+ if (!t.type || !t)
113
113
  return;
114
- console.log("handleGridKeyDown", e, e.code);
115
- const o = e.target;
114
+ console.log("handleGridKeyDown", t, t.code);
115
+ const o = t.target;
116
116
  if (o && [
117
117
  "ArrowDown",
118
118
  "ArrowLeft",
@@ -120,86 +120,98 @@ const G = (m) => {
120
120
  "ArrowUp",
121
121
  "Enter",
122
122
  "Space"
123
- ].includes(e.code)) {
124
- if (e.preventDefault(), o.classList.contains("k-grid-header-menu") && o.classList.contains("k-grid-column-menu")) {
125
- l.value = o;
123
+ ].includes(t.code)) {
124
+ if (t.preventDefault(), o.classList.contains("k-grid-header-menu") && o.classList.contains("k-grid-column-menu")) {
125
+ s.value = o;
126
126
  return;
127
127
  }
128
- const t = o.closest(
128
+ const e = o.closest(
129
129
  ".k-table-row[data-grid-row-index]"
130
130
  );
131
- if (t) {
132
- if (["ArrowDown", "ArrowUp"].includes(e.code)) {
133
- let r = null;
134
- e.code === "ArrowDown" ? r = t.nextElementSibling : e.code === "ArrowUp" && (r = t.previousElementSibling), r && r.hasAttribute("tabindex") && (t.setAttribute("tabindex", "-1"), r.setAttribute("tabindex", "0"), r.focus());
131
+ if (e) {
132
+ if (["ArrowDown", "ArrowUp"].includes(t.code)) {
133
+ const n = (a, i) => {
134
+ let l = i === "next" ? a.nextElementSibling : a.previousElementSibling;
135
+ for (; l; ) {
136
+ const d = l;
137
+ try {
138
+ if (d.hasAttribute && d.hasAttribute("tabindex"))
139
+ return d;
140
+ } catch {
141
+ }
142
+ l = i === "next" ? l.nextElementSibling : l.previousElementSibling;
143
+ }
144
+ return null;
145
+ }, r = t.code === "ArrowDown" ? n(e, "next") : n(e, "previous");
146
+ r && (e.setAttribute("tabindex", "-1"), r.setAttribute("tabindex", "0"), r.focus());
135
147
  return;
136
148
  }
137
- if (["ArrowLeft", "ArrowRight"].includes(e.code)) {
138
- e.preventDefault();
139
- const r = t.querySelectorAll(
149
+ if (["ArrowLeft", "ArrowRight"].includes(t.code)) {
150
+ t.preventDefault();
151
+ const n = e.querySelectorAll(
140
152
  v
141
153
  );
142
- if (r.length === 0) return;
143
- let n = Array.from(r).findIndex(
154
+ if (n.length === 0) return;
155
+ let r = Array.from(n).findIndex(
144
156
  (a) => a === document.activeElement
145
157
  );
146
- if (n === -1 && document.activeElement === t) {
147
- r[0].focus();
158
+ if (r === -1 && document.activeElement === e) {
159
+ n[0].focus();
148
160
  return;
149
161
  }
150
- e.code === "ArrowRight" ? n = n === r.length - 1 ? 0 : n + 1 : e.code === "ArrowLeft" && (n = n === r.length - 1 ? n - 1 : r.length - 1), r[n].focus();
162
+ 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();
151
163
  return;
152
164
  }
153
165
  }
154
166
  }
155
167
  }, D = () => {
156
168
  p(() => {
157
- const e = m.value.$el.closest(".k-grid");
158
- e && e.classList.add("fk-grid");
169
+ const t = b.value.$el.closest(".k-grid");
170
+ t && t.classList.add("fk-grid");
159
171
  });
160
172
  }, T = () => {
161
173
  try {
162
- const e = () => {
174
+ const t = () => {
163
175
  try {
164
- const r = Array.from(
165
- m.value.$el.querySelectorAll(
176
+ const n = Array.from(
177
+ b.value.$el.querySelectorAll(
166
178
  ".k-table-row[data-grid-row-index]"
167
179
  )
168
180
  );
169
- if (!r || r.length === 0 || r.filter(
181
+ if (!n || n.length === 0 || n.filter(
170
182
  (i) => i.getAttribute("tabindex") === "0"
171
183
  ).length === 1) return;
172
- const a = r.find(
184
+ const a = n.find(
173
185
  (i) => i === document.activeElement || i.contains(document.activeElement)
174
186
  );
175
- if (r.forEach((i) => i.setAttribute("tabindex", "-1")), a) {
187
+ if (n.forEach((i) => i.setAttribute("tabindex", "-1")), a) {
176
188
  a.setAttribute("tabindex", "0");
177
189
  return;
178
190
  }
179
- r[0].setAttribute("tabindex", "0");
180
- } catch (r) {
181
- console.error("ensureSingleTabindex error:", r);
191
+ n[0].setAttribute("tabindex", "0");
192
+ } catch (n) {
193
+ console.error("ensureSingleTabindex error:", n);
182
194
  }
183
195
  }, o = Array.from(
184
- m.value.$el.querySelectorAll(
196
+ b.value.$el.querySelectorAll(
185
197
  ".k-table-row[data-grid-row-index]"
186
198
  )
187
199
  );
188
- o.length > 0 && o.forEach((r, n) => {
189
- r.setAttribute("tabindex", n === 0 ? "0" : "-1");
200
+ o.length > 0 && o.forEach((n, r) => {
201
+ n.setAttribute("tabindex", r === 0 ? "0" : "-1");
190
202
  });
191
- const t = m.value.$el.querySelector(".k-table-tbody");
192
- t && (u = new MutationObserver(() => {
193
- e();
194
- }), u.observe(t, { childList: !0, subtree: !0 }));
195
- } catch (e) {
196
- console.error("Error setting up row navigation:", e);
203
+ const e = b.value.$el.querySelector(".k-table-tbody");
204
+ e && (u = new MutationObserver(() => {
205
+ t();
206
+ }), u.observe(e, { childList: !0, subtree: !0 }));
207
+ } catch (t) {
208
+ console.error("Error setting up row navigation:", t);
197
209
  }
198
210
  }, q = () => {
199
211
  p(() => {
200
212
  const o = document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");
201
- o && o.forEach((t) => {
202
- t.setAttribute("role", "button"), t.addEventListener(
213
+ o && o.forEach((e) => {
214
+ e.setAttribute("role", "button"), e.addEventListener(
203
215
  "keydown",
204
216
  h
205
217
  );
@@ -207,40 +219,40 @@ const G = (m) => {
207
219
  });
208
220
  }, C = () => {
209
221
  const o = document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");
210
- o && o.forEach((t) => {
211
- t.removeEventListener(
222
+ o && o.forEach((e) => {
223
+ e.removeEventListener(
212
224
  "keydown",
213
225
  h
214
226
  );
215
- }), d && (d.disconnect(), d = null), u && (u.disconnect(), u = null), f.forEach((t) => t()), f.length = 0;
227
+ }), f && (f.disconnect(), f = null), u && (u.disconnect(), u = null), m.forEach((e) => e()), m.length = 0;
216
228
  }, I = () => {
217
229
  document.querySelectorAll(
218
230
  ".k-grid-header .k-table-thead th"
219
- ).forEach((t, r) => {
220
- const n = t.querySelector(
231
+ ).forEach((e, n) => {
232
+ const r = e.querySelector(
221
233
  ".k-grid-header-menu.k-grid-column-menu"
222
234
  );
223
- if (!n) return;
235
+ if (!r) return;
224
236
  const a = k();
225
- if (a && a[r]) {
226
- const c = a[r].field ?? "";
227
- t.setAttribute("data-feather-k-field", c), t.setAttribute(
237
+ if (a && a[n]) {
238
+ const c = a[n].field ?? "";
239
+ e.setAttribute("data-feather-k-field", c), e.setAttribute(
228
240
  "data-feather-k-filterable",
229
- a[r].filterable === !1 ? "false" : "true"
230
- ), t.setAttribute(
241
+ a[n].filterable === !1 ? "false" : "true"
242
+ ), e.setAttribute(
231
243
  "data-feather-k-sortable",
232
- a[r].sortable === !1 ? "false" : "true"
244
+ a[n].sortable === !1 ? "false" : "true"
233
245
  );
234
246
  }
235
- const i = t.dataset.featherKFilterable !== "false", s = t.dataset.featherKSortable !== "false";
236
- n.setAttribute("tabindex", "-1"), i ? (t.setAttribute("tabindex", "0"), t.setAttribute("role", "button"), t.setAttribute("aria-haspopup", "menu"), t.style.cursor = "pointer") : (t.setAttribute("tabindex", "0"), t.setAttribute("role", "columnheader"), t.removeAttribute("aria-haspopup"), t.style.cursor = "default");
237
- const b = (c) => {
238
- c.target?.closest(".k-column-resizer") || (l.value = t, n.click());
247
+ const i = e.dataset.featherKFilterable !== "false", l = e.dataset.featherKSortable !== "false";
248
+ 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");
249
+ const d = (c) => {
250
+ c.target?.closest(".k-column-resizer") || (s.value = e, r.click());
239
251
  }, w = (c) => {
240
252
  if (i)
241
- l.value = t, c.preventDefault(), c.stopPropagation(), b(c);
242
- else if (s) {
243
- l.value = t;
253
+ s.value = e, c.preventDefault(), c.stopPropagation(), d(c);
254
+ else if (l) {
255
+ s.value = e;
244
256
  const y = new KeyboardEvent("keydown", {
245
257
  key: "Enter",
246
258
  code: "Enter",
@@ -249,58 +261,58 @@ const G = (m) => {
249
261
  bubbles: !0,
250
262
  cancelable: !0
251
263
  });
252
- t.dispatchEvent(y);
264
+ e.dispatchEvent(y);
253
265
  }
254
266
  };
255
- t.addEventListener("click", w), f.push(() => {
256
- t.removeEventListener("click", w);
267
+ e.addEventListener("click", w), m.push(() => {
268
+ e.removeEventListener("click", w);
257
269
  });
258
270
  const A = (c) => {
259
- if ((c.code === "Enter" || c.code === "Space") && (i || s)) {
260
- if (l.value = t, l.value.focus(), i)
261
- c.preventDefault(), c.stopPropagation(), b(c);
262
- else if (s) {
263
- const y = t.querySelector(".k-link");
271
+ if ((c.code === "Enter" || c.code === "Space") && (i || l)) {
272
+ if (s.value = e, s.value.focus(), i)
273
+ c.preventDefault(), c.stopPropagation(), d(c);
274
+ else if (l) {
275
+ const y = e.querySelector(".k-link");
264
276
  y && y.click();
265
277
  }
266
278
  }
267
279
  };
268
- t.addEventListener("keydown", A, !0), f.push(() => {
269
- t.removeEventListener("keydown", A, !0);
280
+ e.addEventListener("keydown", A, !0), m.push(() => {
281
+ e.removeEventListener("keydown", A, !0);
270
282
  });
271
283
  });
272
284
  const o = document.querySelector(".k-grid-header .k-table-thead");
273
285
  if (o) {
274
- const t = (r) => {
275
- const n = r.target.closest("th");
276
- n && (r.code === "Enter" || r.code === "Space") && n.dataset.featherKFilterable === "false" && n.dataset.featherKSortable === "false" && (r.preventDefault(), r.stopImmediatePropagation());
286
+ const e = (n) => {
287
+ const r = n.target.closest("th");
288
+ r && (n.code === "Enter" || n.code === "Space") && r.dataset.featherKFilterable === "false" && r.dataset.featherKSortable === "false" && (n.preventDefault(), n.stopImmediatePropagation());
277
289
  };
278
290
  o.addEventListener(
279
291
  "keydown",
280
- t,
292
+ e,
281
293
  !0
282
294
  // NOTE: capture phase
283
- ), f.push(() => {
295
+ ), m.push(() => {
284
296
  o.removeEventListener(
285
297
  "keydown",
286
- t,
298
+ e,
287
299
  !0
288
300
  );
289
301
  });
290
302
  }
291
- }, K = function(e, o) {
292
- const t = e?.event.event.target, r = k();
293
- if (!t || !r) return;
294
- const n = t.classList.contains("k-link"), a = t.classList.contains("k-columnmenu-item"), i = r.find((s) => s.field === e.event.field)?.sortable && !0;
295
- if (!n) {
303
+ }, K = function(t, o) {
304
+ const e = t?.event.event.target, n = k();
305
+ if (!e || !n) return;
306
+ 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;
307
+ if (!r) {
296
308
  if (a && !i) {
297
- (e.event.sort && void 0)?.filter(
298
- (b) => b.field !== e.event.field
309
+ (t.event.sort && void 0)?.filter(
310
+ (d) => d.field !== t.event.field
299
311
  );
300
312
  return;
301
313
  }
302
314
  typeof o == "function" && p(() => {
303
- l.value && l.value.focus(), o(e);
315
+ s.value && s.value.focus(), o(t);
304
316
  });
305
317
  }
306
318
  };
@@ -309,14 +321,14 @@ const G = (m) => {
309
321
  }), M(() => {
310
322
  C();
311
323
  }), {
312
- activeFilterButton: l,
324
+ activeFilterButton: s,
313
325
  handleGridKeyDown: L,
314
326
  handleSortChange: K
315
327
  };
316
328
  };
317
- function B(m = {}) {
318
- const { activeByDefault: l = !1, autoActivateDelay: d = 0 } = m, u = E(l);
319
- function f() {
329
+ function B(b = {}) {
330
+ const { activeByDefault: s = !1, autoActivateDelay: f = 0 } = b, u = E(s);
331
+ function m() {
320
332
  u.value = !0;
321
333
  }
322
334
  function v() {
@@ -326,13 +338,13 @@ function B(m = {}) {
326
338
  u.value = !u.value;
327
339
  }
328
340
  return S(() => {
329
- d > 0 && !l && setTimeout(() => {
330
- f();
331
- }, d);
341
+ f > 0 && !s && setTimeout(() => {
342
+ m();
343
+ }, f);
332
344
  }), N(() => {
333
345
  }), {
334
346
  isGridActive: u,
335
- activateGrid: f,
347
+ activateGrid: m,
336
348
  deactivateGrid: v,
337
349
  toggleGrid: k
338
350
  };
@@ -1 +1 @@
1
- (function(f,s){typeof exports=="object"&&typeof module<"u"?s(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],s):(f=typeof globalThis<"u"?globalThis:f||self,s(f.FeatherKComposables={},f.Vue))})(this,(function(f,s){"use strict";const S=p=>{const l=s.ref(null);let m=null,d=null;const b=[],h=".k-table-row[data-grid-row-index] [tabindex]",g=()=>p?.value?.columns,v=e=>{const o=e.key||e.code;[" ","Spacebar","Space","Enter"].includes(o)&&(e.preventDefault(),e.stopPropagation(),l.value=e.target,e.target.click())},y=e=>{if(!l.value)return;if(e.code==="Escape"){e.preventDefault(),e.stopPropagation(),l.value&&l.value.focus();return}const o=Array.from(document.querySelectorAll(".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item")),t=document.querySelector(".k-filter-menu-container");if(t){if(e.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(t.querySelectorAll(n.join(",")));if(r.length===0)return;const a=r.findIndex(c=>c===document.activeElement);let i;a===-1?i=0:e.shiftKey?i=(a-1+r.length)%r.length:i=(a+1)%r.length,e.preventDefault(),e.stopPropagation(),r[i]?.focus();return}}else if(e.code==="ArrowUp"||e.code==="ArrowDown"){e.preventDefault(),e.stopPropagation();const n=o.findIndex(a=>a===document.activeElement);let r=n;e.code==="ArrowUp"?r=n>0?n-1:o.length-1:e.code==="ArrowDown"&&(r=n<o.length-1?n+1:0),o[r]?.focus();return}e.code==="Tab"&&(e.preventDefault(),e.stopPropagation(),e.shiftKey?(l.value?.previousElementSibling).focus():(l.value?.nextElementSibling).focus())},L=()=>{m=new MutationObserver(e=>{e.forEach(o=>{o.addedNodes.forEach(t=>{if(t.nodeType===Node.ELEMENT_NODE){const n=t;if(n.classList.contains("k-animation-container")){const a=l.value;a&&(a.dataset.featherKSortable==="true"||s.nextTick(()=>{n.querySelectorAll(".k-columnmenu-item-wrapper").forEach(k=>{k.textContent?.toLowerCase().includes("sort")&&k.remove()})})),n.addEventListener("keydown",y),s.nextTick(()=>{const i=()=>{const c=Array.from(n.querySelectorAll(".k-animation-container .k-popup .k-column-menu .k-columnmenu-item-wrapper .k-columnmenu-item"));if(c.length===1)c[0].focus(),c[0].click(),i.attempts=0;else if(c.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(t=>{if(t.nodeType===Node.ELEMENT_NODE){const n=t;n.classList.contains("k-animation-container")&&n.removeEventListener("keydown",y),n.querySelectorAll(".k-animation-container").forEach(a=>{a.removeEventListener("keydown",y)})}})})}),m.observe(document.body,{childList:!0,subtree:!0})},T=e=>{if(!e.type||!e)return;console.log("handleGridKeyDown",e,e.code);const o=e.target;if(o&&["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","Enter","Space"].includes(e.code)){if(e.preventDefault(),o.classList.contains("k-grid-header-menu")&&o.classList.contains("k-grid-column-menu")){l.value=o;return}const t=o.closest(".k-table-row[data-grid-row-index]");if(t){if(["ArrowDown","ArrowUp"].includes(e.code)){let n=null;e.code==="ArrowDown"?n=t.nextElementSibling:e.code==="ArrowUp"&&(n=t.previousElementSibling),n&&n.hasAttribute("tabindex")&&(t.setAttribute("tabindex","-1"),n.setAttribute("tabindex","0"),n.focus());return}if(["ArrowLeft","ArrowRight"].includes(e.code)){e.preventDefault();const n=t.querySelectorAll(h);if(n.length===0)return;let r=Array.from(n).findIndex(a=>a===document.activeElement);if(r===-1&&document.activeElement===t){n[0].focus();return}e.code==="ArrowRight"?r=r===n.length-1?0:r+1:e.code==="ArrowLeft"&&(r=r===n.length-1?r-1:n.length-1),n[r].focus();return}}}},D=()=>{s.nextTick(()=>{const e=p.value.$el.closest(".k-grid");e&&e.classList.add("fk-grid")})},q=()=>{try{const e=()=>{try{const n=Array.from(p.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(p.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 t=p.value.$el.querySelector(".k-table-tbody");t&&(d=new MutationObserver(()=>{e()}),d.observe(t,{childList:!0,subtree:!0}))}catch(e){console.error("Error setting up row navigation:",e)}},C=()=>{s.nextTick(()=>{const o=document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");o&&o.forEach(t=>{t.setAttribute("role","button"),t.addEventListener("keydown",v)}),L(),K()})},I=()=>{const o=document.querySelectorAll(".k-grid-header .k-grid-header-menu.k-grid-column-menu");o&&o.forEach(t=>{t.removeEventListener("keydown",v)}),m&&(m.disconnect(),m=null),d&&(d.disconnect(),d=null),b.forEach(t=>t()),b.length=0},K=()=>{document.querySelectorAll(".k-grid-header .k-table-thead th").forEach((t,n)=>{const r=t.querySelector(".k-grid-header-menu.k-grid-column-menu");if(!r)return;const a=g();if(a&&a[n]){const u=a[n].field??"";t.setAttribute("data-feather-k-field",u),t.setAttribute("data-feather-k-filterable",a[n].filterable===!1?"false":"true"),t.setAttribute("data-feather-k-sortable",a[n].sortable===!1?"false":"true")}const i=t.dataset.featherKFilterable!=="false",c=t.dataset.featherKSortable!=="false";r.setAttribute("tabindex","-1"),i?(t.setAttribute("tabindex","0"),t.setAttribute("role","button"),t.setAttribute("aria-haspopup","menu"),t.style.cursor="pointer"):(t.setAttribute("tabindex","0"),t.setAttribute("role","columnheader"),t.removeAttribute("aria-haspopup"),t.style.cursor="default");const k=u=>{u.target?.closest(".k-column-resizer")||(l.value=t,r.click())},A=u=>{if(i)l.value=t,u.preventDefault(),u.stopPropagation(),k(u);else if(c){l.value=t;const w=new KeyboardEvent("keydown",{key:"Enter",code:"Enter",keyCode:13,which:13,bubbles:!0,cancelable:!0});t.dispatchEvent(w)}};t.addEventListener("click",A),b.push(()=>{t.removeEventListener("click",A)});const E=u=>{if((u.code==="Enter"||u.code==="Space")&&(i||c)){if(l.value=t,l.value.focus(),i)u.preventDefault(),u.stopPropagation(),k(u);else if(c){const w=t.querySelector(".k-link");w&&w.click()}}};t.addEventListener("keydown",E,!0),b.push(()=>{t.removeEventListener("keydown",E,!0)})});const o=document.querySelector(".k-grid-header .k-table-thead");if(o){const t=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",t,!0),b.push(()=>{o.removeEventListener("keydown",t,!0)})}},M=function(e,o){const t=e?.event.event.target,n=g();if(!t||!n)return;const r=t.classList.contains("k-link"),a=t.classList.contains("k-columnmenu-item"),i=n.find(c=>c.field===e.event.field)?.sortable&&!0;if(!r){if(a&&!i){(e.event.sort&&void 0)?.filter(k=>k.field!==e.event.field);return}typeof o=="function"&&s.nextTick(()=>{l.value&&l.value.focus(),o(e)})}};return s.onMounted(()=>{D(),q(),C()}),s.onBeforeUnmount(()=>{I()}),{activeFilterButton:l,handleGridKeyDown:T,handleSortChange:M}};function x(p={}){const{activeByDefault:l=!1,autoActivateDelay:m=0}=p,d=s.ref(l);function b(){d.value=!0}function h(){d.value=!1}function g(){d.value=!d.value}return s.onMounted(()=>{m>0&&!l&&setTimeout(()=>{b()},m)}),s.onUnmounted(()=>{}),{isGridActive:d,activateGrid:b,deactivateGrid:h,toggleGrid:g}}f.useGridA11y=S,f.useGridComposableEx=x,Object.defineProperty(f,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=k=>{const s=c.ref(null);let b=null,d=null;const p=[],w=".k-table-row[data-grid-row-index] [tabindex]",g=()=>k?.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=()=>{b=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)})}})})}),b.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&&["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.hasAttribute("tabindex"))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(w);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=k.value.$el.closest(".k-grid");t&&t.classList.add("fk-grid")})},q=()=>{try{const t=()=>{try{const n=Array.from(k.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(k.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=k.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)}),b&&(b.disconnect(),b=null),d&&(d.disconnect(),d=null),p.forEach(e=>e()),p.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 h=new KeyboardEvent("keydown",{key:"Enter",code:"Enter",keyCode:13,which:13,bubbles:!0,cancelable:!0});e.dispatchEvent(h)}};e.addEventListener("click",A),p.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 h=e.querySelector(".k-link");h&&h.click()}}};e.addEventListener("keydown",E,!0),p.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),p.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(k={}){const{activeByDefault:s=!1,autoActivateDelay:b=0}=k,d=c.ref(s);function p(){d.value=!0}function w(){d.value=!1}function g(){d.value=!d.value}return c.onMounted(()=>{b>0&&!s&&setTimeout(()=>{p()},b)}),c.onUnmounted(()=>{}),{isGridActive:d,activateGrid:p,deactivateGrid:w,toggleGrid:g}}m.useGridA11y=S,m.useGridComposableEx=x,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}));
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { useGridA11y } from './useGridA11y';
2
- export { useGridComposableEx } from './useGridComposableEx';
1
+ export { useGridA11y } from "./useGridA11y";
2
+ export { useGridComposableEx } from "./useGridComposableEx";
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export interface SortDescriptor {
6
6
  field?: string;
7
- dir?: 'asc' | 'desc';
7
+ dir?: "asc" | "desc";
8
8
  }
9
9
  export interface GridColumnProps {
10
10
  field?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@featherk/composables",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "main": "dist/featherk-composables.umd.js",
5
5
  "module": "dist/featherk-composables.es.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,7 +11,6 @@
11
11
  "build": "vite build && npm run build:types",
12
12
  "build:types": "vue-tsc --emitDeclarationOnly --declaration --declarationDir dist",
13
13
  "test": "vitest",
14
- "lint": "eslint src --ext .ts,.vue",
15
14
  "clean": "rm -rf dist",
16
15
  "prepublishOnly": "npm run build"
17
16
  },
@@ -21,7 +20,6 @@
21
20
  "devDependencies": {
22
21
  "@types/node": "^24.5.2",
23
22
  "@vitejs/plugin-vue": "^6.0.1",
24
- "eslint": "^8.0.0",
25
23
  "typescript": "~5.8.3",
26
24
  "vite": "^7.1.7",
27
25
  "vitest": "^3.2.4",
@@ -31,4 +29,4 @@
31
29
  "access": "public"
32
30
  },
33
31
  "license": "MIT"
34
- }
32
+ }