@toolbox-web/grid-vue 0.3.1 → 0.4.1

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
@@ -217,6 +217,72 @@ import '@toolbox-web/grid-vue/features/editing';
217
217
  | `commit` | `(value: any) => void` | Save the new value |
218
218
  | `cancel` | `() => void` | Cancel editing |
219
219
 
220
+ ## Events
221
+
222
+ Handle grid events using Vue's template syntax or the `useGridEvent` composable.
223
+
224
+ ### Template Event Binding
225
+
226
+ ```vue
227
+ <script setup lang="ts">
228
+ import { TbwGrid } from '@toolbox-web/grid-vue';
229
+ import type { CellClickDetail, SortChangeDetail } from '@toolbox-web/grid';
230
+
231
+ function onCellClick(e: CustomEvent<CellClickDetail>) {
232
+ console.log(`Clicked ${e.detail.field} at row ${e.detail.rowIndex}`);
233
+ }
234
+
235
+ function onSortChange(e: CustomEvent<SortChangeDetail>) {
236
+ console.log(`Sorted by ${e.detail.field} ${e.detail.direction}`);
237
+ }
238
+ </script>
239
+
240
+ <template>
241
+ <TbwGrid :rows="rows" @cell-click="onCellClick" @sort-change="onSortChange">
242
+ <TbwGridColumn field="name" header="Name" sortable />
243
+ </TbwGrid>
244
+ </template>
245
+ ```
246
+
247
+ ### Available Events
248
+
249
+ | Event | Detail Type | Description |
250
+ | ---------------------- | -------------------- | --------------------------------- |
251
+ | `@cell-click` | `CellClickDetail` | Cell was clicked |
252
+ | `@row-click` | `RowClickDetail` | Row was clicked |
253
+ | `@cell-commit` | `CellCommitDetail` | Cell value committed (cancelable) |
254
+ | `@row-commit` | `RowCommitDetail` | Row edit completed (cancelable) |
255
+ | `@cell-change` | `CellChangeDetail` | Row updated via API |
256
+ | `@sort-change` | `SortChangeDetail` | Sort state changed |
257
+ | `@column-resize` | `ColumnResizeDetail` | Column was resized |
258
+ | `@cell-activate` | `CellActivateDetail` | Cell activated (cancelable) |
259
+ | `@column-state-change` | `GridColumnState` | Column visibility/order changed |
260
+
261
+ ## Using Plugins (Advanced)
262
+
263
+ For full control, pass plugin instances directly via `:grid-config`. Use `markRaw()` to prevent Vue from making plugin instances reactive:
264
+
265
+ ```vue
266
+ <script setup lang="ts">
267
+ import { markRaw } from 'vue';
268
+ import { TbwGrid, TbwGridColumn } from '@toolbox-web/grid-vue';
269
+ import { SelectionPlugin } from '@toolbox-web/grid/plugins/selection';
270
+ import { FilteringPlugin } from '@toolbox-web/grid/plugins/filtering';
271
+
272
+ const gridConfig = {
273
+ plugins: markRaw([new SelectionPlugin({ mode: 'range' }), new FilteringPlugin({ debounceMs: 200 })]),
274
+ };
275
+ </script>
276
+
277
+ <template>
278
+ <TbwGrid :rows="rows" :grid-config="gridConfig">
279
+ <TbwGridColumn field="name" header="Name" />
280
+ </TbwGrid>
281
+ </template>
282
+ ```
283
+
284
+ > **Important:** Always wrap plugin arrays with `markRaw()`. Vue's reactivity proxy breaks plugin internal state.
285
+
220
286
  ## Composables
221
287
 
222
288
  ### useGrid
@@ -480,6 +546,19 @@ const props = defineProps<{
480
546
  | `VueCellEditor` | Deprecated - use `CellEditor` |
481
547
  | `VueTypeDefault` | Deprecated - use `TypeDefault` |
482
548
 
549
+ ## Requirements
550
+
551
+ - **Vue 3.4+** (uses `defineModel` and improved generics)
552
+ - **@toolbox-web/grid** (peer dependency)
553
+
554
+ ## Demo
555
+
556
+ See the [Vue demo app](../../demos/employee-management/vue/) for a full-featured example using `@toolbox-web/grid-vue`.
557
+
558
+ ```bash
559
+ bun nx serve demo-vue
560
+ ```
561
+
483
562
  ## Building
484
563
 
485
564
  ```bash
@@ -1 +1 @@
1
- {"version":3,"file":"filtering.d.ts","sourceRoot":"","sources":["../../../../libs/grid-vue/src/features/filtering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAYxF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAE9E;;OAEG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;IAEtD;;OAEG;IACH,UAAU,EAAE,MAAM,WAAW,EAAE,CAAC;IAEhC;;OAEG;IACH,cAAc,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;IAEjD;;OAEG;IACH,eAAe,EAAE,MAAM,IAAI,CAAC;IAE5B;;OAEG;IACH,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAE1C;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAE5C;;OAEG;IACH,mBAAmB,EAAE,MAAM,MAAM,CAAC;IAElC;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,IAAI,gBAAgB,CAuEnD"}
1
+ {"version":3,"file":"filtering.d.ts","sourceRoot":"","sources":["../../../../libs/grid-vue/src/features/filtering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAGL,KAAK,WAAW,EAEjB,MAAM,qCAAqC,CAAC;AAqC7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAE9E;;OAEG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;IAEtD;;OAEG;IACH,UAAU,EAAE,MAAM,WAAW,EAAE,CAAC;IAEhC;;OAEG;IACH,cAAc,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;IAEjD;;OAEG;IACH,eAAe,EAAE,MAAM,IAAI,CAAC;IAE5B;;OAEG;IACH,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAE1C;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAE5C;;OAEG;IACH,mBAAmB,EAAE,MAAM,MAAM,CAAC;IAElC;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,IAAI,gBAAgB,CAuEnD"}
@@ -1,14 +1,32 @@
1
- import { FilteringPlugin as n } from "@toolbox-web/grid/plugins/filtering";
2
- import { inject as g, ref as o } from "vue";
3
- import { r as u } from "../chunks/feature-registry-BgEOysSJ.js";
4
- import { G as d } from "../chunks/use-grid-DwjXrO19.js";
5
- u("filtering", (t) => t === !0 ? new n() : new n(t ?? void 0));
6
- function c() {
7
- const t = g(d, o(null)), i = () => t.value?.getPlugin(n);
1
+ import { FilteringPlugin as l } from "@toolbox-web/grid/plugins/filtering";
2
+ import { createApp as u, inject as d, ref as s } from "vue";
3
+ import { r as f } from "../chunks/feature-registry-BgEOysSJ.js";
4
+ import { G as a } from "../chunks/use-grid-DwjXrO19.js";
5
+ f("filtering", (r) => {
6
+ if (r === !0)
7
+ return new l();
8
+ if (!r)
9
+ return new l();
10
+ const t = r, e = { ...t };
11
+ if (typeof t.filterPanelRenderer == "function" && t.filterPanelRenderer.length <= 1) {
12
+ const i = t.filterPanelRenderer;
13
+ e.filterPanelRenderer = (n, g) => {
14
+ const o = document.createElement("div");
15
+ o.style.display = "contents", u({
16
+ render() {
17
+ return i(g);
18
+ }
19
+ }).mount(o), n.appendChild(o);
20
+ };
21
+ }
22
+ return new l(e);
23
+ });
24
+ function m() {
25
+ const r = d(a, s(null)), t = () => r.value?.getPlugin(l);
8
26
  return {
9
- setFilter: (e, r) => {
10
- const l = i();
11
- if (!l) {
27
+ setFilter: (e, i) => {
28
+ const n = t();
29
+ if (!n) {
12
30
  console.warn(
13
31
  `[tbw-grid:filtering] FilteringPlugin not found.
14
32
 
@@ -17,13 +35,13 @@ function c() {
17
35
  );
18
36
  return;
19
37
  }
20
- l.setFilter(e, r);
38
+ n.setFilter(e, i);
21
39
  },
22
- getFilter: (e) => i()?.getFilter(e),
23
- getFilters: () => i()?.getFilters() ?? [],
40
+ getFilter: (e) => t()?.getFilter(e),
41
+ getFilters: () => t()?.getFilters() ?? [],
24
42
  setFilterModel: (e) => {
25
- const r = i();
26
- if (!r) {
43
+ const i = t();
44
+ if (!i) {
27
45
  console.warn(
28
46
  `[tbw-grid:filtering] FilteringPlugin not found.
29
47
 
@@ -32,10 +50,10 @@ function c() {
32
50
  );
33
51
  return;
34
52
  }
35
- r.setFilterModel(e);
53
+ i.setFilterModel(e);
36
54
  },
37
55
  clearAllFilters: () => {
38
- const e = i();
56
+ const e = t();
39
57
  if (!e) {
40
58
  console.warn(
41
59
  `[tbw-grid:filtering] FilteringPlugin not found.
@@ -48,8 +66,8 @@ function c() {
48
66
  e.clearAllFilters();
49
67
  },
50
68
  clearFieldFilter: (e) => {
51
- const r = i();
52
- if (!r) {
69
+ const i = t();
70
+ if (!i) {
53
71
  console.warn(
54
72
  `[tbw-grid:filtering] FilteringPlugin not found.
55
73
 
@@ -58,14 +76,14 @@ function c() {
58
76
  );
59
77
  return;
60
78
  }
61
- r.clearFieldFilter(e);
79
+ i.clearFieldFilter(e);
62
80
  },
63
- isFieldFiltered: (e) => i()?.isFieldFiltered(e) ?? !1,
64
- getFilteredRowCount: () => i()?.getFilteredRowCount() ?? 0,
65
- getUniqueValues: (e) => i()?.getUniqueValues(e) ?? []
81
+ isFieldFiltered: (e) => t()?.isFieldFiltered(e) ?? !1,
82
+ getFilteredRowCount: () => t()?.getFilteredRowCount() ?? 0,
83
+ getUniqueValues: (e) => t()?.getUniqueValues(e) ?? []
66
84
  };
67
85
  }
68
86
  export {
69
- c as useGridFiltering
87
+ m as useGridFiltering
70
88
  };
71
89
  //# sourceMappingURL=filtering.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filtering.js","sources":["../../../../libs/grid-vue/src/features/filtering.ts"],"sourcesContent":["/**\n * Filtering feature for @toolbox-web/grid-vue\n *\n * Import this module to enable the `filtering` prop on TbwGrid.\n * Also exports `useGridFiltering()` composable for programmatic filter control.\n *\n * @example\n * ```vue\n * <script setup>\n * import '@toolbox-web/grid-vue/features/filtering';\n * </script>\n *\n * <template>\n * <TbwGrid filtering />\n * </template>\n * ```\n *\n * @example Using the composable\n * ```vue\n * <script setup>\n * import { useGridFiltering } from '@toolbox-web/grid-vue/features/filtering';\n *\n * const { setFilter, clearAllFilters, getFilteredRowCount } = useGridFiltering();\n *\n * function filterByStatus(status: string) {\n * setFilter('status', { operator: 'equals', value: status });\n * }\n * </script>\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { FilteringPlugin, type FilterModel } from '@toolbox-web/grid/plugins/filtering';\nimport { inject, ref } from 'vue';\nimport { registerFeature } from '../lib/feature-registry';\nimport { GRID_ELEMENT_KEY } from '../lib/use-grid';\n\nregisterFeature('filtering', (config) => {\n if (config === true) {\n return new FilteringPlugin();\n }\n return new FilteringPlugin(config ?? undefined);\n});\n\n/**\n * Filtering methods returned from useGridFiltering.\n */\nexport interface FilteringMethods {\n /**\n * Set a filter on a specific field.\n * @param field - The field name to filter\n * @param filter - Filter configuration, or null to remove\n */\n setFilter: (field: string, filter: Omit<FilterModel, 'field'> | null) => void;\n\n /**\n * Get the current filter for a field.\n */\n getFilter: (field: string) => FilterModel | undefined;\n\n /**\n * Get all active filters.\n */\n getFilters: () => FilterModel[];\n\n /**\n * Set all filters at once (replaces existing).\n */\n setFilterModel: (filters: FilterModel[]) => void;\n\n /**\n * Clear all active filters.\n */\n clearAllFilters: () => void;\n\n /**\n * Clear filter for a specific field.\n */\n clearFieldFilter: (field: string) => void;\n\n /**\n * Check if a field has an active filter.\n */\n isFieldFiltered: (field: string) => boolean;\n\n /**\n * Get the count of rows after filtering.\n */\n getFilteredRowCount: () => number;\n\n /**\n * Get unique values for a field (for building filter dropdowns).\n */\n getUniqueValues: (field: string) => unknown[];\n}\n\n/**\n * Composable for programmatic filter control.\n *\n * Must be used within a component that contains a TbwGrid with filtering enabled.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useGridFiltering } from '@toolbox-web/grid-vue/features/filtering';\n *\n * const { setFilter, clearAllFilters, getFilteredRowCount, isFieldFiltered } = useGridFiltering();\n *\n * function applyQuickFilter(field: string, value: string) {\n * setFilter(field, { operator: 'contains', value });\n * }\n * </script>\n *\n * <template>\n * <input @input=\"applyQuickFilter('name', $event.target.value)\" placeholder=\"Filter by name...\" />\n * <span>{{ getFilteredRowCount() }} results</span>\n * <button @click=\"clearAllFilters\">Clear Filters</button>\n * </template>\n * ```\n */\nexport function useGridFiltering(): FilteringMethods {\n const gridElement = inject(GRID_ELEMENT_KEY, ref(null));\n\n const getPlugin = (): FilteringPlugin | undefined => {\n const grid = gridElement.value as DataGridElement | null;\n return grid?.getPlugin(FilteringPlugin);\n };\n\n return {\n setFilter: (field: string, filter: Omit<FilterModel, 'field'> | null) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <TbwGrid filtering />`,\n );\n return;\n }\n plugin.setFilter(field, filter);\n },\n\n getFilter: (field: string) => getPlugin()?.getFilter(field),\n\n getFilters: () => getPlugin()?.getFilters() ?? [],\n\n setFilterModel: (filters: FilterModel[]) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <TbwGrid filtering />`,\n );\n return;\n }\n plugin.setFilterModel(filters);\n },\n\n clearAllFilters: () => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <TbwGrid filtering />`,\n );\n return;\n }\n plugin.clearAllFilters();\n },\n\n clearFieldFilter: (field: string) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <TbwGrid filtering />`,\n );\n return;\n }\n plugin.clearFieldFilter(field);\n },\n\n isFieldFiltered: (field: string) => getPlugin()?.isFieldFiltered(field) ?? false,\n\n getFilteredRowCount: () => getPlugin()?.getFilteredRowCount() ?? 0,\n\n getUniqueValues: (field: string) => getPlugin()?.getUniqueValues(field) ?? [],\n };\n}\n"],"names":["registerFeature","config","FilteringPlugin","useGridFiltering","gridElement","inject","GRID_ELEMENT_KEY","ref","getPlugin","field","filter","plugin","filters"],"mappings":";;;;AAuCAA,EAAgB,aAAa,CAACC,MACxBA,MAAW,KACN,IAAIC,EAAA,IAEN,IAAIA,EAAgBD,KAAU,MAAS,CAC/C;AA8EM,SAASE,IAAqC;AACnD,QAAMC,IAAcC,EAAOC,GAAkBC,EAAI,IAAI,CAAC,GAEhDC,IAAY,MACHJ,EAAY,OACZ,UAAUF,CAAe;AAGxC,SAAO;AAAA,IACL,WAAW,CAACO,GAAeC,MAA8C;AACvE,YAAMC,IAASH,EAAA;AACf,UAAI,CAACG,GAAQ;AACX,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA,QAAA;AAIF;AAAA,MACF;AACA,MAAAA,EAAO,UAAUF,GAAOC,CAAM;AAAA,IAChC;AAAA,IAEA,WAAW,CAACD,MAAkBD,EAAA,GAAa,UAAUC,CAAK;AAAA,IAE1D,YAAY,MAAMD,KAAa,WAAA,KAAgB,CAAA;AAAA,IAE/C,gBAAgB,CAACI,MAA2B;AAC1C,YAAMD,IAASH,EAAA;AACf,UAAI,CAACG,GAAQ;AACX,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA,QAAA;AAIF;AAAA,MACF;AACA,MAAAA,EAAO,eAAeC,CAAO;AAAA,IAC/B;AAAA,IAEA,iBAAiB,MAAM;AACrB,YAAMD,IAASH,EAAA;AACf,UAAI,CAACG,GAAQ;AACX,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA,QAAA;AAIF;AAAA,MACF;AACA,MAAAA,EAAO,gBAAA;AAAA,IACT;AAAA,IAEA,kBAAkB,CAACF,MAAkB;AACnC,YAAME,IAASH,EAAA;AACf,UAAI,CAACG,GAAQ;AACX,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA,QAAA;AAIF;AAAA,MACF;AACA,MAAAA,EAAO,iBAAiBF,CAAK;AAAA,IAC/B;AAAA,IAEA,iBAAiB,CAACA,MAAkBD,KAAa,gBAAgBC,CAAK,KAAK;AAAA,IAE3E,qBAAqB,MAAMD,KAAa,yBAAyB;AAAA,IAEjE,iBAAiB,CAACC,MAAkBD,EAAA,GAAa,gBAAgBC,CAAK,KAAK,CAAA;AAAA,EAAC;AAEhF;"}
1
+ {"version":3,"file":"filtering.js","sources":["../../../../libs/grid-vue/src/features/filtering.ts"],"sourcesContent":["/**\n * Filtering feature for @toolbox-web/grid-vue\n *\n * Import this module to enable the `filtering` prop on TbwGrid.\n * Also exports `useGridFiltering()` composable for programmatic filter control.\n *\n * @example\n * ```vue\n * <script setup>\n * import '@toolbox-web/grid-vue/features/filtering';\n * </script>\n *\n * <template>\n * <TbwGrid filtering />\n * </template>\n * ```\n *\n * @example Using the composable\n * ```vue\n * <script setup>\n * import { useGridFiltering } from '@toolbox-web/grid-vue/features/filtering';\n *\n * const { setFilter, clearAllFilters, getFilteredRowCount } = useGridFiltering();\n *\n * function filterByStatus(status: string) {\n * setFilter('status', { operator: 'equals', value: status });\n * }\n * </script>\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport {\n FilteringPlugin,\n type FilterConfig,\n type FilterModel,\n type FilterPanelParams,\n} from '@toolbox-web/grid/plugins/filtering';\nimport { createApp, inject, ref, type VNode } from 'vue';\nimport { registerFeature } from '../lib/feature-registry';\nimport { GRID_ELEMENT_KEY } from '../lib/use-grid';\n\nregisterFeature('filtering', (rawConfig) => {\n if (rawConfig === true) {\n return new FilteringPlugin();\n }\n if (!rawConfig) {\n return new FilteringPlugin();\n }\n\n const config = rawConfig as FilterConfig & { filterPanelRenderer?: unknown };\n const options = { ...config } as FilterConfig;\n\n // Bridge Vue filterPanelRenderer (1 arg: params → VNode) to vanilla (2 args: container, params)\n if (typeof config.filterPanelRenderer === 'function' && config.filterPanelRenderer.length <= 1) {\n const vueFn = config.filterPanelRenderer as unknown as (params: FilterPanelParams) => VNode;\n options.filterPanelRenderer = (container: HTMLElement, params: FilterPanelParams) => {\n const wrapper = document.createElement('div');\n wrapper.style.display = 'contents';\n\n const app = createApp({\n render() {\n return vueFn(params);\n },\n });\n\n app.mount(wrapper);\n container.appendChild(wrapper);\n };\n }\n\n return new FilteringPlugin(options);\n});\n\n/**\n * Filtering methods returned from useGridFiltering.\n */\nexport interface FilteringMethods {\n /**\n * Set a filter on a specific field.\n * @param field - The field name to filter\n * @param filter - Filter configuration, or null to remove\n */\n setFilter: (field: string, filter: Omit<FilterModel, 'field'> | null) => void;\n\n /**\n * Get the current filter for a field.\n */\n getFilter: (field: string) => FilterModel | undefined;\n\n /**\n * Get all active filters.\n */\n getFilters: () => FilterModel[];\n\n /**\n * Set all filters at once (replaces existing).\n */\n setFilterModel: (filters: FilterModel[]) => void;\n\n /**\n * Clear all active filters.\n */\n clearAllFilters: () => void;\n\n /**\n * Clear filter for a specific field.\n */\n clearFieldFilter: (field: string) => void;\n\n /**\n * Check if a field has an active filter.\n */\n isFieldFiltered: (field: string) => boolean;\n\n /**\n * Get the count of rows after filtering.\n */\n getFilteredRowCount: () => number;\n\n /**\n * Get unique values for a field (for building filter dropdowns).\n */\n getUniqueValues: (field: string) => unknown[];\n}\n\n/**\n * Composable for programmatic filter control.\n *\n * Must be used within a component that contains a TbwGrid with filtering enabled.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useGridFiltering } from '@toolbox-web/grid-vue/features/filtering';\n *\n * const { setFilter, clearAllFilters, getFilteredRowCount, isFieldFiltered } = useGridFiltering();\n *\n * function applyQuickFilter(field: string, value: string) {\n * setFilter(field, { operator: 'contains', value });\n * }\n * </script>\n *\n * <template>\n * <input @input=\"applyQuickFilter('name', $event.target.value)\" placeholder=\"Filter by name...\" />\n * <span>{{ getFilteredRowCount() }} results</span>\n * <button @click=\"clearAllFilters\">Clear Filters</button>\n * </template>\n * ```\n */\nexport function useGridFiltering(): FilteringMethods {\n const gridElement = inject(GRID_ELEMENT_KEY, ref(null));\n\n const getPlugin = (): FilteringPlugin | undefined => {\n const grid = gridElement.value as DataGridElement | null;\n return grid?.getPlugin(FilteringPlugin);\n };\n\n return {\n setFilter: (field: string, filter: Omit<FilterModel, 'field'> | null) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <TbwGrid filtering />`,\n );\n return;\n }\n plugin.setFilter(field, filter);\n },\n\n getFilter: (field: string) => getPlugin()?.getFilter(field),\n\n getFilters: () => getPlugin()?.getFilters() ?? [],\n\n setFilterModel: (filters: FilterModel[]) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <TbwGrid filtering />`,\n );\n return;\n }\n plugin.setFilterModel(filters);\n },\n\n clearAllFilters: () => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <TbwGrid filtering />`,\n );\n return;\n }\n plugin.clearAllFilters();\n },\n\n clearFieldFilter: (field: string) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <TbwGrid filtering />`,\n );\n return;\n }\n plugin.clearFieldFilter(field);\n },\n\n isFieldFiltered: (field: string) => getPlugin()?.isFieldFiltered(field) ?? false,\n\n getFilteredRowCount: () => getPlugin()?.getFilteredRowCount() ?? 0,\n\n getUniqueValues: (field: string) => getPlugin()?.getUniqueValues(field) ?? [],\n };\n}\n"],"names":["registerFeature","rawConfig","FilteringPlugin","config","options","vueFn","container","params","wrapper","createApp","useGridFiltering","gridElement","inject","GRID_ELEMENT_KEY","ref","getPlugin","field","filter","plugin","filters"],"mappings":";;;;AA4CAA,EAAgB,aAAa,CAACC,MAAc;AAC1C,MAAIA,MAAc;AAChB,WAAO,IAAIC,EAAA;AAEb,MAAI,CAACD;AACH,WAAO,IAAIC,EAAA;AAGb,QAAMC,IAASF,GACTG,IAAU,EAAE,GAAGD,EAAA;AAGrB,MAAI,OAAOA,EAAO,uBAAwB,cAAcA,EAAO,oBAAoB,UAAU,GAAG;AAC9F,UAAME,IAAQF,EAAO;AACrB,IAAAC,EAAQ,sBAAsB,CAACE,GAAwBC,MAA8B;AACnF,YAAMC,IAAU,SAAS,cAAc,KAAK;AAC5C,MAAAA,EAAQ,MAAM,UAAU,YAEZC,EAAU;AAAA,QACpB,SAAS;AACP,iBAAOJ,EAAME,CAAM;AAAA,QACrB;AAAA,MAAA,CACD,EAEG,MAAMC,CAAO,GACjBF,EAAU,YAAYE,CAAO;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO,IAAIN,EAAgBE,CAAO;AACpC,CAAC;AA8EM,SAASM,IAAqC;AACnD,QAAMC,IAAcC,EAAOC,GAAkBC,EAAI,IAAI,CAAC,GAEhDC,IAAY,MACHJ,EAAY,OACZ,UAAUT,CAAe;AAGxC,SAAO;AAAA,IACL,WAAW,CAACc,GAAeC,MAA8C;AACvE,YAAMC,IAASH,EAAA;AACf,UAAI,CAACG,GAAQ;AACX,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA,QAAA;AAIF;AAAA,MACF;AACA,MAAAA,EAAO,UAAUF,GAAOC,CAAM;AAAA,IAChC;AAAA,IAEA,WAAW,CAACD,MAAkBD,EAAA,GAAa,UAAUC,CAAK;AAAA,IAE1D,YAAY,MAAMD,KAAa,WAAA,KAAgB,CAAA;AAAA,IAE/C,gBAAgB,CAACI,MAA2B;AAC1C,YAAMD,IAASH,EAAA;AACf,UAAI,CAACG,GAAQ;AACX,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA,QAAA;AAIF;AAAA,MACF;AACA,MAAAA,EAAO,eAAeC,CAAO;AAAA,IAC/B;AAAA,IAEA,iBAAiB,MAAM;AACrB,YAAMD,IAASH,EAAA;AACf,UAAI,CAACG,GAAQ;AACX,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA,QAAA;AAIF;AAAA,MACF;AACA,MAAAA,EAAO,gBAAA;AAAA,IACT;AAAA,IAEA,kBAAkB,CAACF,MAAkB;AACnC,YAAME,IAASH,EAAA;AACf,UAAI,CAACG,GAAQ;AACX,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA,QAAA;AAIF;AAAA,MACF;AACA,MAAAA,EAAO,iBAAiBF,CAAK;AAAA,IAC/B;AAAA,IAEA,iBAAiB,CAACA,MAAkBD,KAAa,gBAAgBC,CAAK,KAAK;AAAA,IAE3E,qBAAqB,MAAMD,KAAa,yBAAyB;AAAA,IAEjE,iBAAiB,CAACC,MAAkBD,EAAA,GAAa,gBAAgBC,CAAK,KAAK,CAAA;AAAA,EAAC;AAEhF;"}
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * <template>
13
13
  * <TbwGrid pinnedColumns :columns="[
14
- * { field: 'id', sticky: 'left' },
14
+ * { field: 'id', pinned: 'left' },
15
15
  * { field: 'name' },
16
16
  * ]" />
17
17
  * </template>
@@ -1 +1 @@
1
- {"version":3,"file":"pinned-columns.js","sources":["../../../../libs/grid-vue/src/features/pinned-columns.ts"],"sourcesContent":["/**\n * Pinned columns feature for @toolbox-web/grid-vue\n *\n * Import this module to enable the `pinnedColumns` prop on TbwGrid.\n *\n * @example\n * ```vue\n * <script setup>\n * import '@toolbox-web/grid-vue/features/pinned-columns';\n * </script>\n *\n * <template>\n * <TbwGrid pinnedColumns :columns=\"[\n * { field: 'id', sticky: 'left' },\n * { field: 'name' },\n * ]\" />\n * </template>\n * ```\n *\n * @packageDocumentation\n */\n\nimport { PinnedColumnsPlugin } from '@toolbox-web/grid/plugins/pinned-columns';\nimport { registerFeature } from '../lib/feature-registry';\n\nregisterFeature('pinnedColumns', () => {\n return new PinnedColumnsPlugin();\n});\n"],"names":["registerFeature","PinnedColumnsPlugin"],"mappings":";;AAyBAA,EAAgB,iBAAiB,MACxB,IAAIC,EAAA,CACZ;"}
1
+ {"version":3,"file":"pinned-columns.js","sources":["../../../../libs/grid-vue/src/features/pinned-columns.ts"],"sourcesContent":["/**\n * Pinned columns feature for @toolbox-web/grid-vue\n *\n * Import this module to enable the `pinnedColumns` prop on TbwGrid.\n *\n * @example\n * ```vue\n * <script setup>\n * import '@toolbox-web/grid-vue/features/pinned-columns';\n * </script>\n *\n * <template>\n * <TbwGrid pinnedColumns :columns=\"[\n * { field: 'id', pinned: 'left' },\n * { field: 'name' },\n * ]\" />\n * </template>\n * ```\n *\n * @packageDocumentation\n */\n\nimport { PinnedColumnsPlugin } from '@toolbox-web/grid/plugins/pinned-columns';\nimport { registerFeature } from '../lib/feature-registry';\n\nregisterFeature('pinnedColumns', () => {\n return new PinnedColumnsPlugin();\n});\n"],"names":["registerFeature","PinnedColumnsPlugin"],"mappings":";;AAyBAA,EAAgB,iBAAiB,MACxB,IAAIC,EAAA,CACZ;"}