@toolbox-web/grid-vue 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ import { CellRange, SelectionResult } from '@toolbox-web/grid/plugins/selection'
5
5
  * Uses the injected grid element from TbwGrid's provide/inject.
6
6
  * Methods work immediately when grid is available.
7
7
  */
8
- export interface SelectionMethods {
8
+ export interface SelectionMethods<TRow = unknown> {
9
9
  /**
10
10
  * Select all rows (row mode) or all cells (range mode).
11
11
  */
@@ -27,6 +27,16 @@ export interface SelectionMethods {
27
27
  * Set selection ranges programmatically.
28
28
  */
29
29
  setRanges: (ranges: CellRange[]) => void;
30
+ /**
31
+ * Get actual row objects for the current selection.
32
+ * Works in all selection modes (row, cell, range) — resolves indices
33
+ * against the grid's processed (sorted/filtered) rows.
34
+ *
35
+ * This is the recommended way to get selected rows. Unlike manual
36
+ * index mapping, it correctly resolves rows even when the grid is
37
+ * sorted or filtered.
38
+ */
39
+ getSelectedRows: () => TRow[];
30
40
  }
31
41
  /**
32
42
  * Composable for programmatic selection control.
@@ -49,5 +59,5 @@ export interface SelectionMethods {
49
59
  * </script>
50
60
  * ```
51
61
  */
52
- export declare function useGridSelection<TRow = unknown>(): SelectionMethods;
62
+ export declare function useGridSelection<TRow = unknown>(): SelectionMethods<TRow>;
53
63
  //# sourceMappingURL=selection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../../libs/grid-vue/src/features/selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAc5G;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;IAEtB;;OAEG;IACH,cAAc,EAAE,MAAM,IAAI,CAAC;IAE3B;;;OAGG;IACH,YAAY,EAAE,MAAM,eAAe,GAAG,IAAI,CAAC;IAE3C;;OAEG;IACH,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAEtD;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAG,OAAO,KAAK,gBAAgB,CAsDnE"}
1
+ {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../../libs/grid-vue/src/features/selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAc5G;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB,CAAC,IAAI,GAAG,OAAO;IAC9C;;OAEG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;IAEtB;;OAEG;IACH,cAAc,EAAE,MAAM,IAAI,CAAC;IAE3B;;;OAGG;IACH,YAAY,EAAE,MAAM,eAAe,GAAG,IAAI,CAAC;IAE3C;;OAEG;IACH,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAEtD;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;IAEzC;;;;;;;;OAQG;IACH,eAAe,EAAE,MAAM,IAAI,EAAE,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAG,OAAO,KAAK,gBAAgB,CAAC,IAAI,CAAC,CA0DzE"}
@@ -3,7 +3,7 @@ import { inject as u, ref as g } from "vue";
3
3
  import { r as d } from "../chunks/feature-registry-BgEOysSJ.js";
4
4
  import { G as a } from "../chunks/use-grid-DwjXrO19.js";
5
5
  d("selection", (t) => t === "cell" || t === "row" || t === "range" ? new s({ mode: t }) : new s(t ?? void 0));
6
- function p() {
6
+ function R() {
7
7
  const t = u(a, g(null)), n = () => t.value?.getPlugin(s);
8
8
  return {
9
9
  selectAll: () => {
@@ -34,10 +34,11 @@ function p() {
34
34
  isCellSelected: (e, o) => n()?.isCellSelected(e, o) ?? !1,
35
35
  setRanges: (e) => {
36
36
  n()?.setRanges(e);
37
- }
37
+ },
38
+ getSelectedRows: () => n()?.getSelectedRows() ?? []
38
39
  };
39
40
  }
40
41
  export {
41
- p as useGridSelection
42
+ R as useGridSelection
42
43
  };
43
44
  //# sourceMappingURL=selection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"selection.js","sources":["../../../../libs/grid-vue/src/features/selection.ts"],"sourcesContent":["/**\n * Selection feature for @toolbox-web/grid-vue\n *\n * Import this module to enable the `selection` prop on TbwGrid.\n * Also exports `useGridSelection()` composable for programmatic selection control.\n *\n * @example\n * ```vue\n * <script setup>\n * import '@toolbox-web/grid-vue/features/selection';\n * </script>\n *\n * <template>\n * <TbwGrid selection=\"range\" />\n * </template>\n * ```\n *\n * @example Using the composable\n * ```vue\n * <script setup>\n * import { useGridSelection } from '@toolbox-web/grid-vue/features/selection';\n *\n * const { selectAll, clearSelection, getSelection } = useGridSelection();\n *\n * function handleSelectAll() {\n * selectAll();\n * }\n * </script>\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { SelectionPlugin, type CellRange, type SelectionResult } from '@toolbox-web/grid/plugins/selection';\nimport { inject, ref } from 'vue';\nimport { registerFeature } from '../lib/feature-registry';\nimport { GRID_ELEMENT_KEY } from '../lib/use-grid';\n\nregisterFeature('selection', (config) => {\n // Handle shorthand: 'cell', 'row', 'range'\n if (config === 'cell' || config === 'row' || config === 'range') {\n return new SelectionPlugin({ mode: config });\n }\n // Full config object\n return new SelectionPlugin(config ?? undefined);\n});\n\n/**\n * Selection methods returned from useGridSelection.\n *\n * Uses the injected grid element from TbwGrid's provide/inject.\n * Methods work immediately when grid is available.\n */\nexport interface SelectionMethods {\n /**\n * Select all rows (row mode) or all cells (range mode).\n */\n selectAll: () => void;\n\n /**\n * Clear all selection.\n */\n clearSelection: () => void;\n\n /**\n * Get the current selection state.\n * Use this to derive selected rows, indices, etc.\n */\n getSelection: () => SelectionResult | null;\n\n /**\n * Check if a specific cell is selected.\n */\n isCellSelected: (row: number, col: number) => boolean;\n\n /**\n * Set selection ranges programmatically.\n */\n setRanges: (ranges: CellRange[]) => void;\n}\n\n/**\n * Composable for programmatic selection control.\n *\n * Must be used within a component that contains a TbwGrid with the selection feature enabled.\n * Uses Vue's provide/inject, so it works reliably regardless of when the grid renders.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useGridSelection } from '@toolbox-web/grid-vue/features/selection';\n *\n * const { selectAll, clearSelection, getSelection } = useGridSelection();\n *\n * function exportSelected() {\n * const selection = getSelection();\n * if (!selection) return;\n * // Derive rows from selection.ranges and grid.rows\n * }\n * </script>\n * ```\n */\nexport function useGridSelection<TRow = unknown>(): SelectionMethods {\n const gridElement = inject(GRID_ELEMENT_KEY, ref(null));\n\n const getPlugin = (): SelectionPlugin | undefined => {\n const grid = gridElement.value as DataGridElement<TRow> | null;\n return grid?.getPlugin(SelectionPlugin);\n };\n\n return {\n selectAll: () => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:selection] SelectionPlugin not found.\\n\\n` +\n ` → Enable selection on the grid:\\n` +\n ` <TbwGrid selection=\"range\" />`,\n );\n return;\n }\n const grid = gridElement.value as DataGridElement<TRow> | null;\n // Cast to any to access protected config\n const mode = (plugin as any).config?.mode;\n\n if (mode === 'row') {\n const rowCount = grid?.rows?.length ?? 0;\n const allIndices = new Set<number>();\n for (let i = 0; i < rowCount; i++) allIndices.add(i);\n (plugin as any).selected = allIndices;\n (plugin as any).requestAfterRender?.();\n } else if (mode === 'range') {\n const rowCount = grid?.rows?.length ?? 0;\n const colCount = (grid as any)?._columns?.length ?? 0;\n if (rowCount > 0 && colCount > 0) {\n plugin.setRanges([{ from: { row: 0, col: 0 }, to: { row: rowCount - 1, col: colCount - 1 } }]);\n }\n }\n },\n\n clearSelection: () => {\n getPlugin()?.clearSelection();\n },\n\n getSelection: () => {\n return getPlugin()?.getSelection() ?? null;\n },\n\n isCellSelected: (row: number, col: number) => {\n return getPlugin()?.isCellSelected(row, col) ?? false;\n },\n\n setRanges: (ranges: CellRange[]) => {\n getPlugin()?.setRanges(ranges);\n },\n };\n}\n"],"names":["registerFeature","config","SelectionPlugin","useGridSelection","gridElement","inject","GRID_ELEMENT_KEY","ref","getPlugin","plugin","grid","mode","rowCount","allIndices","colCount","row","col","ranges"],"mappings":";;;;AAuCAA,EAAgB,aAAa,CAACC,MAExBA,MAAW,UAAUA,MAAW,SAASA,MAAW,UAC/C,IAAIC,EAAgB,EAAE,MAAMD,GAAQ,IAGtC,IAAIC,EAAgBD,KAAU,MAAS,CAC/C;AAyDM,SAASE,IAAqD;AACnE,QAAMC,IAAcC,EAAOC,GAAkBC,EAAI,IAAI,CAAC,GAEhDC,IAAY,MACHJ,EAAY,OACZ,UAAUF,CAAe;AAGxC,SAAO;AAAA,IACL,WAAW,MAAM;AACf,YAAMO,IAASD,EAAA;AACf,UAAI,CAACC,GAAQ;AACX,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA,QAAA;AAIF;AAAA,MACF;AACA,YAAMC,IAAON,EAAY,OAEnBO,IAAQF,EAAe,QAAQ;AAErC,UAAIE,MAAS,OAAO;AAClB,cAAMC,IAAWF,GAAM,MAAM,UAAU,GACjCG,wBAAiB,IAAA;AACvB,iBAAS,IAAI,GAAG,IAAID,GAAU,IAAK,CAAAC,EAAW,IAAI,CAAC;AAClD,QAAAJ,EAAe,WAAWI,GAC1BJ,EAAe,qBAAA;AAAA,MAClB,WAAWE,MAAS,SAAS;AAC3B,cAAMC,IAAWF,GAAM,MAAM,UAAU,GACjCI,IAAYJ,GAAc,UAAU,UAAU;AACpD,QAAIE,IAAW,KAAKE,IAAW,KAC7BL,EAAO,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,KAAK,EAAA,GAAK,IAAI,EAAE,KAAKG,IAAW,GAAG,KAAKE,IAAW,EAAA,EAAE,CAAG,CAAC;AAAA,MAEjG;AAAA,IACF;AAAA,IAEA,gBAAgB,MAAM;AACpB,MAAAN,EAAA,GAAa,eAAA;AAAA,IACf;AAAA,IAEA,cAAc,MACLA,EAAA,GAAa,aAAA,KAAkB;AAAA,IAGxC,gBAAgB,CAACO,GAAaC,MACrBR,EAAA,GAAa,eAAeO,GAAKC,CAAG,KAAK;AAAA,IAGlD,WAAW,CAACC,MAAwB;AAClC,MAAAT,EAAA,GAAa,UAAUS,CAAM;AAAA,IAC/B;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"selection.js","sources":["../../../../libs/grid-vue/src/features/selection.ts"],"sourcesContent":["/**\n * Selection feature for @toolbox-web/grid-vue\n *\n * Import this module to enable the `selection` prop on TbwGrid.\n * Also exports `useGridSelection()` composable for programmatic selection control.\n *\n * @example\n * ```vue\n * <script setup>\n * import '@toolbox-web/grid-vue/features/selection';\n * </script>\n *\n * <template>\n * <TbwGrid selection=\"range\" />\n * </template>\n * ```\n *\n * @example Using the composable\n * ```vue\n * <script setup>\n * import { useGridSelection } from '@toolbox-web/grid-vue/features/selection';\n *\n * const { selectAll, clearSelection, getSelection } = useGridSelection();\n *\n * function handleSelectAll() {\n * selectAll();\n * }\n * </script>\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { SelectionPlugin, type CellRange, type SelectionResult } from '@toolbox-web/grid/plugins/selection';\nimport { inject, ref } from 'vue';\nimport { registerFeature } from '../lib/feature-registry';\nimport { GRID_ELEMENT_KEY } from '../lib/use-grid';\n\nregisterFeature('selection', (config) => {\n // Handle shorthand: 'cell', 'row', 'range'\n if (config === 'cell' || config === 'row' || config === 'range') {\n return new SelectionPlugin({ mode: config });\n }\n // Full config object\n return new SelectionPlugin(config ?? undefined);\n});\n\n/**\n * Selection methods returned from useGridSelection.\n *\n * Uses the injected grid element from TbwGrid's provide/inject.\n * Methods work immediately when grid is available.\n */\nexport interface SelectionMethods<TRow = unknown> {\n /**\n * Select all rows (row mode) or all cells (range mode).\n */\n selectAll: () => void;\n\n /**\n * Clear all selection.\n */\n clearSelection: () => void;\n\n /**\n * Get the current selection state.\n * Use this to derive selected rows, indices, etc.\n */\n getSelection: () => SelectionResult | null;\n\n /**\n * Check if a specific cell is selected.\n */\n isCellSelected: (row: number, col: number) => boolean;\n\n /**\n * Set selection ranges programmatically.\n */\n setRanges: (ranges: CellRange[]) => void;\n\n /**\n * Get actual row objects for the current selection.\n * Works in all selection modes (row, cell, range) — resolves indices\n * against the grid's processed (sorted/filtered) rows.\n *\n * This is the recommended way to get selected rows. Unlike manual\n * index mapping, it correctly resolves rows even when the grid is\n * sorted or filtered.\n */\n getSelectedRows: () => TRow[];\n}\n\n/**\n * Composable for programmatic selection control.\n *\n * Must be used within a component that contains a TbwGrid with the selection feature enabled.\n * Uses Vue's provide/inject, so it works reliably regardless of when the grid renders.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useGridSelection } from '@toolbox-web/grid-vue/features/selection';\n *\n * const { selectAll, clearSelection, getSelection } = useGridSelection();\n *\n * function exportSelected() {\n * const selection = getSelection();\n * if (!selection) return;\n * // Derive rows from selection.ranges and grid.rows\n * }\n * </script>\n * ```\n */\nexport function useGridSelection<TRow = unknown>(): SelectionMethods<TRow> {\n const gridElement = inject(GRID_ELEMENT_KEY, ref(null));\n\n const getPlugin = (): SelectionPlugin | undefined => {\n const grid = gridElement.value as DataGridElement<TRow> | null;\n return grid?.getPlugin(SelectionPlugin);\n };\n\n return {\n selectAll: () => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:selection] SelectionPlugin not found.\\n\\n` +\n ` → Enable selection on the grid:\\n` +\n ` <TbwGrid selection=\"range\" />`,\n );\n return;\n }\n const grid = gridElement.value as DataGridElement<TRow> | null;\n // Cast to any to access protected config\n const mode = (plugin as any).config?.mode;\n\n if (mode === 'row') {\n const rowCount = grid?.rows?.length ?? 0;\n const allIndices = new Set<number>();\n for (let i = 0; i < rowCount; i++) allIndices.add(i);\n (plugin as any).selected = allIndices;\n (plugin as any).requestAfterRender?.();\n } else if (mode === 'range') {\n const rowCount = grid?.rows?.length ?? 0;\n const colCount = (grid as any)?._columns?.length ?? 0;\n if (rowCount > 0 && colCount > 0) {\n plugin.setRanges([{ from: { row: 0, col: 0 }, to: { row: rowCount - 1, col: colCount - 1 } }]);\n }\n }\n },\n\n clearSelection: () => {\n getPlugin()?.clearSelection();\n },\n\n getSelection: () => {\n return getPlugin()?.getSelection() ?? null;\n },\n\n isCellSelected: (row: number, col: number) => {\n return getPlugin()?.isCellSelected(row, col) ?? false;\n },\n\n setRanges: (ranges: CellRange[]) => {\n getPlugin()?.setRanges(ranges);\n },\n\n getSelectedRows: (): TRow[] => {\n return getPlugin()?.getSelectedRows<TRow>() ?? [];\n },\n };\n}\n"],"names":["registerFeature","config","SelectionPlugin","useGridSelection","gridElement","inject","GRID_ELEMENT_KEY","ref","getPlugin","plugin","grid","mode","rowCount","allIndices","colCount","row","col","ranges"],"mappings":";;;;AAuCAA,EAAgB,aAAa,CAACC,MAExBA,MAAW,UAAUA,MAAW,SAASA,MAAW,UAC/C,IAAIC,EAAgB,EAAE,MAAMD,GAAQ,IAGtC,IAAIC,EAAgBD,KAAU,MAAS,CAC/C;AAoEM,SAASE,IAA2D;AACzE,QAAMC,IAAcC,EAAOC,GAAkBC,EAAI,IAAI,CAAC,GAEhDC,IAAY,MACHJ,EAAY,OACZ,UAAUF,CAAe;AAGxC,SAAO;AAAA,IACL,WAAW,MAAM;AACf,YAAMO,IAASD,EAAA;AACf,UAAI,CAACC,GAAQ;AACX,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA,QAAA;AAIF;AAAA,MACF;AACA,YAAMC,IAAON,EAAY,OAEnBO,IAAQF,EAAe,QAAQ;AAErC,UAAIE,MAAS,OAAO;AAClB,cAAMC,IAAWF,GAAM,MAAM,UAAU,GACjCG,wBAAiB,IAAA;AACvB,iBAAS,IAAI,GAAG,IAAID,GAAU,IAAK,CAAAC,EAAW,IAAI,CAAC;AAClD,QAAAJ,EAAe,WAAWI,GAC1BJ,EAAe,qBAAA;AAAA,MAClB,WAAWE,MAAS,SAAS;AAC3B,cAAMC,IAAWF,GAAM,MAAM,UAAU,GACjCI,IAAYJ,GAAc,UAAU,UAAU;AACpD,QAAIE,IAAW,KAAKE,IAAW,KAC7BL,EAAO,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,KAAK,EAAA,GAAK,IAAI,EAAE,KAAKG,IAAW,GAAG,KAAKE,IAAW,EAAA,EAAE,CAAG,CAAC;AAAA,MAEjG;AAAA,IACF;AAAA,IAEA,gBAAgB,MAAM;AACpB,MAAAN,EAAA,GAAa,eAAA;AAAA,IACf;AAAA,IAEA,cAAc,MACLA,EAAA,GAAa,aAAA,KAAkB;AAAA,IAGxC,gBAAgB,CAACO,GAAaC,MACrBR,EAAA,GAAa,eAAeO,GAAKC,CAAG,KAAK;AAAA,IAGlD,WAAW,CAACC,MAAwB;AAClC,MAAAT,EAAA,GAAa,UAAUS,CAAM;AAAA,IAC/B;AAAA,IAEA,iBAAiB,MACRT,EAAA,GAAa,gBAAA,KAA2B,CAAA;AAAA,EACjD;AAEJ;"}
package/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { defineComponent as y, provide as L, inject as F, createApp as f, createVNode as k, ref as R, computed as ne, onMounted as T, onBeforeUnmount as q, watch as j, createElementBlock as O, openBlock as P, renderSlot as U, useSlots as S, h as C } from "vue";
1
+ import { defineComponent as y, provide as L, inject as F, createApp as f, createVNode as k, ref as R, computed as ne, onMounted as T, onBeforeUnmount as q, watch as j, createElementBlock as O, openBlock as P, renderSlot as U, useSlots as B, h as C } from "vue";
2
2
  import { DataGridElement as re } from "@toolbox-web/grid";
3
3
  import { c as oe } from "./chunks/feature-registry-BgEOysSJ.js";
4
- import { a as Ve, g as ke, b as Le, i as Fe, r as Me } from "./chunks/feature-registry-BgEOysSJ.js";
4
+ import { a as Se, g as ke, b as Le, i as Fe, r as Me } from "./chunks/feature-registry-BgEOysSJ.js";
5
5
  import { G as H } from "./chunks/use-grid-DwjXrO19.js";
6
6
  import { u as Ae } from "./chunks/use-grid-DwjXrO19.js";
7
7
  const K = /* @__PURE__ */ Symbol("grid-icons");
@@ -45,32 +45,32 @@ const de = y({
45
45
  }
46
46
  }), Q = /* @__PURE__ */ new WeakMap(), X = /* @__PURE__ */ new WeakMap(), v = /* @__PURE__ */ new WeakMap(), w = /* @__PURE__ */ new Map();
47
47
  function le(i, e) {
48
- const n = i.getAttribute("field"), t = v.get(i) ?? {};
49
- if (t.renderer = e, v.set(i, t), n) {
50
- const r = w.get(n) ?? {};
51
- r.renderer = e, w.set(n, r);
48
+ const t = i.getAttribute("field"), n = v.get(i) ?? {};
49
+ if (n.renderer = e, v.set(i, n), t) {
50
+ const r = w.get(t) ?? {};
51
+ r.renderer = e, w.set(t, r);
52
52
  }
53
53
  }
54
54
  function ae(i, e) {
55
- const n = i.getAttribute("field"), t = v.get(i) ?? {};
56
- if (t.editor = e, v.set(i, t), n) {
57
- const r = w.get(n) ?? {};
58
- r.editor = e, w.set(n, r);
55
+ const t = i.getAttribute("field"), n = v.get(i) ?? {};
56
+ if (n.editor = e, v.set(i, n), t) {
57
+ const r = w.get(t) ?? {};
58
+ r.editor = e, w.set(t, r);
59
59
  }
60
60
  }
61
61
  function ce(i) {
62
62
  let e = v.get(i)?.renderer;
63
63
  if (!e) {
64
- const n = i.getAttribute("field");
65
- n && (e = w.get(n)?.renderer);
64
+ const t = i.getAttribute("field");
65
+ t && (e = w.get(t)?.renderer);
66
66
  }
67
67
  return e;
68
68
  }
69
69
  function ue(i) {
70
70
  let e = v.get(i)?.editor;
71
71
  if (!e) {
72
- const n = i.getAttribute("field");
73
- n && (e = w.get(n)?.editor);
72
+ const t = i.getAttribute("field");
73
+ t && (e = w.get(t)?.editor);
74
74
  }
75
75
  return e;
76
76
  }
@@ -84,17 +84,19 @@ function G(i) {
84
84
  if (typeof i == "function") {
85
85
  const e = Function.prototype.toString.call(i);
86
86
  if (e.startsWith("class ") || e.startsWith("class{")) return !0;
87
- const n = i;
88
- if ("__name" in n || typeof n.setup == "function") return !0;
87
+ const t = i;
88
+ if ("__name" in t || typeof t.setup == "function") return !0;
89
89
  }
90
90
  return !1;
91
91
  }
92
- function B(i) {
92
+ function V(i) {
93
93
  return typeof i == "function" && !G(i);
94
94
  }
95
95
  const E = /* @__PURE__ */ Symbol.for("tbw:vue-processed");
96
96
  class fe {
97
97
  mountedViews = [];
98
+ /** Editor-specific views tracked separately for per-cell cleanup via releaseCell. */
99
+ editorViews = [];
98
100
  typeDefaults = null;
99
101
  // #region Config Processing
100
102
  /**
@@ -122,8 +124,8 @@ class fe {
122
124
  * @returns Processed config with DOM-returning functions
123
125
  */
124
126
  processGridConfig(e) {
125
- const n = { ...e };
126
- return e.columns && (n.columns = e.columns.map((t) => this.processColumn(t))), e.typeDefaults && (n.typeDefaults = this.processTypeDefaults(e.typeDefaults)), n;
127
+ const t = { ...e };
128
+ return e.columns && (t.columns = e.columns.map((n) => this.processColumn(n))), e.typeDefaults && (t.typeDefaults = this.processTypeDefaults(e.typeDefaults)), t;
127
129
  }
128
130
  /**
129
131
  * Processes typeDefaults, converting Vue component/VNode references
@@ -133,20 +135,20 @@ class fe {
133
135
  * @returns Processed TypeDefault record
134
136
  */
135
137
  processTypeDefaults(e) {
136
- const n = {};
137
- for (const [t, r] of Object.entries(e)) {
138
+ const t = {};
139
+ for (const [n, r] of Object.entries(e)) {
138
140
  const s = {
139
141
  editorParams: r.editorParams
140
142
  };
141
- r.renderer && (G(r.renderer) ? s.renderer = this.createConfigComponentRenderer(r.renderer) : B(r.renderer) && (s.renderer = this.createTypeRenderer(
143
+ r.renderer && (G(r.renderer) ? s.renderer = this.createConfigComponentRenderer(r.renderer) : V(r.renderer) && (s.renderer = this.createTypeRenderer(
142
144
  r.renderer
143
145
  ))), r.editor && (G(r.editor) ? s.editor = this.createConfigComponentEditor(
144
146
  r.editor
145
- ) : B(r.editor) && (s.editor = this.createTypeEditor(
147
+ ) : V(r.editor) && (s.editor = this.createTypeEditor(
146
148
  r.editor
147
- ))), r.filterPanelRenderer && (s.filterPanelRenderer = this.createFilterPanelRenderer(r.filterPanelRenderer)), n[t] = s;
149
+ ))), r.filterPanelRenderer && (s.filterPanelRenderer = this.createFilterPanelRenderer(r.filterPanelRenderer)), t[n] = s;
148
150
  }
149
- return n;
151
+ return t;
150
152
  }
151
153
  /**
152
154
  * Processes a single column configuration, converting Vue component references
@@ -156,26 +158,26 @@ class fe {
156
158
  * @returns Processed ColumnConfig with DOM-returning functions
157
159
  */
158
160
  processColumn(e) {
159
- const n = { ...e };
161
+ const t = { ...e };
160
162
  if (e.renderer && !e.renderer[E]) {
161
163
  if (G(e.renderer)) {
162
- const t = this.createConfigComponentRenderer(e.renderer);
163
- t[E] = !0, n.renderer = t;
164
- } else if (B(e.renderer)) {
165
- const t = this.createConfigVNodeRenderer(e.renderer);
166
- t[E] = !0, n.renderer = t;
164
+ const n = this.createConfigComponentRenderer(e.renderer);
165
+ n[E] = !0, t.renderer = n;
166
+ } else if (V(e.renderer)) {
167
+ const n = this.createConfigVNodeRenderer(e.renderer);
168
+ n[E] = !0, t.renderer = n;
167
169
  }
168
170
  }
169
171
  if (e.editor && !e.editor[E]) {
170
172
  if (G(e.editor)) {
171
- const t = this.createConfigComponentEditor(e.editor);
172
- t[E] = !0, n.editor = t;
173
- } else if (B(e.editor)) {
174
- const t = this.createConfigVNodeEditor(e.editor);
175
- t[E] = !0, n.editor = t;
173
+ const n = this.createConfigComponentEditor(e.editor);
174
+ n[E] = !0, t.editor = n;
175
+ } else if (V(e.editor)) {
176
+ const n = this.createConfigVNodeEditor(e.editor);
177
+ n[E] = !0, t.editor = n;
176
178
  }
177
179
  }
178
- return n;
180
+ return t;
179
181
  }
180
182
  /**
181
183
  * Creates a DOM-returning renderer from a Vue component class.
@@ -183,22 +185,22 @@ class fe {
183
185
  * @internal
184
186
  */
185
187
  createConfigComponentRenderer(e) {
186
- const n = /* @__PURE__ */ new WeakMap();
187
- return (t) => {
188
- const r = t.cellEl;
188
+ const t = /* @__PURE__ */ new WeakMap();
189
+ return (n) => {
190
+ const r = n.cellEl;
189
191
  if (r) {
190
- const a = n.get(r);
192
+ const a = t.get(r);
191
193
  if (a)
192
- return a.update(t), a.container;
194
+ return a.update(n), a.container;
193
195
  const c = document.createElement("div");
194
196
  c.className = "vue-cell-renderer", c.style.display = "contents";
195
- let u = t;
197
+ let u = n;
196
198
  const g = e, h = f({
197
199
  render() {
198
200
  return k(g, { ...u });
199
201
  }
200
202
  });
201
- return h.mount(c), n.set(r, {
203
+ return h.mount(c), t.set(r, {
202
204
  app: h,
203
205
  container: c,
204
206
  update: (_) => {
@@ -210,7 +212,7 @@ class fe {
210
212
  s.className = "vue-cell-renderer", s.style.display = "contents";
211
213
  const d = e, l = f({
212
214
  render() {
213
- return k(d, { ...t });
215
+ return k(d, { ...n });
214
216
  }
215
217
  });
216
218
  return l.mount(s), this.mountedViews.push({ app: l, container: s }), s;
@@ -222,22 +224,22 @@ class fe {
222
224
  * @internal
223
225
  */
224
226
  createConfigVNodeRenderer(e) {
225
- const n = /* @__PURE__ */ new WeakMap();
226
- return (t) => {
227
- const r = t.cellEl;
227
+ const t = /* @__PURE__ */ new WeakMap();
228
+ return (n) => {
229
+ const r = n.cellEl;
228
230
  if (r) {
229
- const l = n.get(r);
231
+ const l = t.get(r);
230
232
  if (l)
231
- return l.update(t), l.container;
233
+ return l.update(n), l.container;
232
234
  const a = document.createElement("div");
233
235
  a.className = "vue-cell-renderer", a.style.display = "contents";
234
- let c = t;
236
+ let c = n;
235
237
  const u = f({
236
238
  render() {
237
239
  return e(c);
238
240
  }
239
241
  });
240
- return u.mount(a), n.set(r, {
242
+ return u.mount(a), t.set(r, {
241
243
  app: u,
242
244
  container: a,
243
245
  update: (g) => {
@@ -249,7 +251,7 @@ class fe {
249
251
  s.className = "vue-cell-renderer", s.style.display = "contents";
250
252
  const d = f({
251
253
  render() {
252
- return e(t);
254
+ return e(n);
253
255
  }
254
256
  });
255
257
  return d.mount(s), this.mountedViews.push({ app: d, container: s }), s;
@@ -261,15 +263,15 @@ class fe {
261
263
  * @internal
262
264
  */
263
265
  createConfigComponentEditor(e) {
264
- return (n) => {
265
- const t = document.createElement("div");
266
- t.className = "vue-cell-editor", t.style.display = "contents";
266
+ return (t) => {
267
+ const n = document.createElement("div");
268
+ n.className = "vue-cell-editor", n.style.display = "contents";
267
269
  const r = e, s = f({
268
270
  render() {
269
- return k(r, { ...n });
271
+ return k(r, { ...t });
270
272
  }
271
273
  });
272
- return s.mount(t), this.mountedViews.push({ app: s, container: t }), t;
274
+ return s.mount(n), this.editorViews.push({ app: s, container: n }), n;
273
275
  };
274
276
  }
275
277
  /**
@@ -278,15 +280,15 @@ class fe {
278
280
  * @internal
279
281
  */
280
282
  createConfigVNodeEditor(e) {
281
- return (n) => {
282
- const t = document.createElement("div");
283
- t.className = "vue-cell-editor", t.style.display = "contents";
283
+ return (t) => {
284
+ const n = document.createElement("div");
285
+ n.className = "vue-cell-editor", n.style.display = "contents";
284
286
  const r = f({
285
287
  render() {
286
- return e(n);
288
+ return e(t);
287
289
  }
288
290
  });
289
- return r.mount(t), this.mountedViews.push({ app: r, container: t }), t;
291
+ return r.mount(n), this.editorViews.push({ app: r, container: n }), n;
290
292
  };
291
293
  }
292
294
  // #endregion
@@ -304,28 +306,28 @@ class fe {
304
306
  * Checks if a renderer or editor is registered for this element.
305
307
  */
306
308
  canHandle(e) {
307
- const n = e.getAttribute("field");
308
- let t = v.get(e);
309
- if (!t && n) {
310
- const d = w.get(n);
311
- d && (d.renderer || d.editor) && (t = d, v.set(e, t));
309
+ const t = e.getAttribute("field");
310
+ let n = v.get(e);
311
+ if (!n && t) {
312
+ const d = w.get(t);
313
+ d && (d.renderer || d.editor) && (n = d, v.set(e, n));
312
314
  }
313
- const r = t?.renderer !== void 0, s = t?.editor !== void 0;
314
- return t !== void 0 && (r || s);
315
+ const r = n?.renderer !== void 0, s = n?.editor !== void 0;
316
+ return n !== void 0 && (r || s);
315
317
  }
316
318
  /**
317
319
  * Creates a view renderer function that renders a Vue component
318
320
  * and returns its container DOM element.
319
321
  */
320
322
  createRenderer(e) {
321
- const n = ce(e);
322
- if (!n)
323
+ const t = ce(e);
324
+ if (!t)
323
325
  return;
324
- const t = /* @__PURE__ */ new WeakMap();
326
+ const n = /* @__PURE__ */ new WeakMap();
325
327
  return (r) => {
326
328
  const s = r.cellEl;
327
329
  if (s) {
328
- const a = t.get(s);
330
+ const a = n.get(s);
329
331
  if (a)
330
332
  return a.update(r), a.container;
331
333
  const c = document.createElement("div");
@@ -333,10 +335,10 @@ class fe {
333
335
  let u = r;
334
336
  const g = f({
335
337
  render() {
336
- return n(u);
338
+ return t(u);
337
339
  }
338
340
  });
339
- return g.mount(c), t.set(s, {
341
+ return g.mount(c), n.set(s, {
340
342
  app: g,
341
343
  container: c,
342
344
  update: (h) => {
@@ -348,7 +350,7 @@ class fe {
348
350
  d.className = "vue-cell-renderer", d.style.display = "contents";
349
351
  const l = f({
350
352
  render() {
351
- return n(r);
353
+ return t(r);
352
354
  }
353
355
  });
354
356
  return l.mount(d), this.mountedViews.push({ app: l, container: d }), d;
@@ -359,17 +361,17 @@ class fe {
359
361
  * Returns a function that creates the editor DOM element.
360
362
  */
361
363
  createEditor(e) {
362
- const n = ue(e);
363
- if (n)
364
- return (t) => {
364
+ const t = ue(e);
365
+ if (t)
366
+ return (n) => {
365
367
  const r = document.createElement("div");
366
368
  r.className = "vue-cell-editor", r.style.display = "contents";
367
369
  const s = f({
368
370
  render() {
369
- return n(t);
371
+ return t(n);
370
372
  }
371
373
  });
372
- return s.mount(r), this.mountedViews.push({ app: s, container: r }), r;
374
+ return s.mount(r), this.editorViews.push({ app: s, container: r }), r;
373
375
  };
374
376
  }
375
377
  /**
@@ -377,11 +379,11 @@ class fe {
377
379
  * Parses the <tbw-grid-detail> element and returns a Vue-based renderer.
378
380
  */
379
381
  parseDetailElement(e) {
380
- const n = e.closest("tbw-grid");
381
- if (!n) return;
382
- const t = n.querySelector("tbw-grid-detail");
382
+ const t = e.closest("tbw-grid");
383
383
  if (!t) return;
384
- const r = Q.get(t);
384
+ const n = t.querySelector("tbw-grid-detail");
385
+ if (!n) return;
386
+ const r = Q.get(n);
385
387
  if (r)
386
388
  return (s, d) => {
387
389
  const l = document.createElement("div");
@@ -403,11 +405,11 @@ class fe {
403
405
  * Parses the <tbw-grid-responsive-card> element and returns a Vue-based renderer.
404
406
  */
405
407
  parseResponsiveCardElement(e) {
406
- const n = e.closest("tbw-grid");
407
- if (!n) return;
408
- const t = n.querySelector("tbw-grid-responsive-card");
408
+ const t = e.closest("tbw-grid");
409
409
  if (!t) return;
410
- const r = X.get(t);
410
+ const n = t.querySelector("tbw-grid-responsive-card");
411
+ if (!n) return;
412
+ const r = X.get(n);
411
413
  if (r)
412
414
  return (s, d) => {
413
415
  const l = document.createElement("div");
@@ -456,28 +458,28 @@ class fe {
456
458
  getTypeDefault(e) {
457
459
  if (!this.typeDefaults)
458
460
  return;
459
- const n = this.typeDefaults[e];
460
- if (!n)
461
+ const t = this.typeDefaults[e];
462
+ if (!t)
461
463
  return;
462
- const t = {
463
- editorParams: n.editorParams
464
+ const n = {
465
+ editorParams: t.editorParams
464
466
  };
465
- return n.renderer && (t.renderer = this.createTypeRenderer(n.renderer)), n.editor && (t.editor = this.createTypeEditor(n.editor)), n.filterPanelRenderer && (t.filterPanelRenderer = this.createFilterPanelRenderer(n.filterPanelRenderer)), t;
467
+ return t.renderer && (n.renderer = this.createTypeRenderer(t.renderer)), t.editor && (n.editor = this.createTypeEditor(t.editor)), t.filterPanelRenderer && (n.filterPanelRenderer = this.createFilterPanelRenderer(t.filterPanelRenderer)), n;
466
468
  }
467
469
  /**
468
470
  * Creates a renderer function from a Vue render function for type defaults.
469
471
  * @internal
470
472
  */
471
473
  createTypeRenderer(e) {
472
- return (n) => {
473
- const t = document.createElement("span");
474
- t.style.display = "contents";
474
+ return (t) => {
475
+ const n = document.createElement("span");
476
+ n.style.display = "contents";
475
477
  const r = f({
476
478
  render() {
477
- return e(n);
479
+ return e(t);
478
480
  }
479
481
  });
480
- return r.mount(t), this.mountedViews.push({ app: r, container: t }), t;
482
+ return r.mount(n), this.mountedViews.push({ app: r, container: n }), n;
481
483
  };
482
484
  }
483
485
  /**
@@ -485,15 +487,15 @@ class fe {
485
487
  * @internal
486
488
  */
487
489
  createTypeEditor(e) {
488
- return (n) => {
489
- const t = document.createElement("span");
490
- t.style.display = "contents";
490
+ return (t) => {
491
+ const n = document.createElement("span");
492
+ n.style.display = "contents";
491
493
  const r = f({
492
494
  render() {
493
- return e(n);
495
+ return e(t);
494
496
  }
495
497
  });
496
- return r.mount(t), this.mountedViews.push({ app: r, container: t }), t;
498
+ return r.mount(n), this.editorViews.push({ app: r, container: n }), n;
497
499
  };
498
500
  }
499
501
  /**
@@ -504,15 +506,15 @@ class fe {
504
506
  * @internal
505
507
  */
506
508
  createFilterPanelRenderer(e) {
507
- return (n, t) => {
509
+ return (t, n) => {
508
510
  const r = document.createElement("div");
509
511
  r.style.display = "contents";
510
512
  const s = f({
511
513
  render() {
512
- return e(t);
514
+ return e(n);
513
515
  }
514
516
  });
515
- s.mount(r), this.mountedViews.push({ app: s, container: r }), n.appendChild(r);
517
+ s.mount(r), this.mountedViews.push({ app: s, container: r }), t.appendChild(r);
516
518
  };
517
519
  }
518
520
  // #endregion
@@ -520,12 +522,34 @@ class fe {
520
522
  * Cleanup all mounted Vue apps.
521
523
  */
522
524
  cleanup() {
523
- for (const { app: e, container: n } of this.mountedViews)
525
+ for (const { app: e, container: t } of this.mountedViews)
524
526
  try {
525
- e.unmount(), n.remove();
527
+ e.unmount(), t.remove();
526
528
  } catch {
527
529
  }
528
530
  this.mountedViews = [];
531
+ for (const { app: e, container: t } of this.editorViews)
532
+ try {
533
+ e.unmount(), t.remove();
534
+ } catch {
535
+ }
536
+ this.editorViews = [];
537
+ }
538
+ /**
539
+ * Called when a cell's content is about to be wiped.
540
+ * Destroys editor Vue apps whose container is inside the cell.
541
+ */
542
+ releaseCell(e) {
543
+ for (let t = this.editorViews.length - 1; t >= 0; t--) {
544
+ const { app: n, container: r } = this.editorViews[t];
545
+ if (e.contains(r)) {
546
+ try {
547
+ n.unmount(), r.remove();
548
+ } catch {
549
+ }
550
+ this.editorViews.splice(t, 1);
551
+ }
552
+ }
529
553
  }
530
554
  }
531
555
  const pe = fe, Re = /* @__PURE__ */ y({
@@ -671,13 +695,13 @@ const pe = fe, Re = /* @__PURE__ */ y({
671
695
  }
672
696
  },
673
697
  emits: ["cell-commit", "row-commit", "cell-click", "cell-dblclick", "selection-change", "row-toggle", "sort-change", "ready"],
674
- setup(i, { expose: e, emit: n }) {
675
- let t = !1, r = null;
698
+ setup(i, { expose: e, emit: t }) {
699
+ let n = !1, r = null;
676
700
  function s() {
677
- return t || (r = new pe(), re.registerAdapter(r), t = !0), r;
701
+ return n || (r = new pe(), re.registerAdapter(r), n = !0), r;
678
702
  }
679
703
  s();
680
- const d = i, l = n, a = R(null);
704
+ const d = i, l = t, a = R(null);
681
705
  L(H, a);
682
706
  const c = J(), u = ie(), g = [
683
707
  "selection",
@@ -756,8 +780,8 @@ const pe = fe, Re = /* @__PURE__ */ y({
756
780
  get() {
757
781
  return te.call(this);
758
782
  },
759
- set(V) {
760
- V && p ? D.call(this, p.processGridConfig(V)) : D.call(this, V);
783
+ set(S) {
784
+ S && p ? D.call(this, p.processGridConfig(S)) : D.call(this, S);
761
785
  },
762
786
  configurable: !0
763
787
  });
@@ -828,12 +852,12 @@ const pe = fe, Re = /* @__PURE__ */ y({
828
852
  hidden: { type: Boolean }
829
853
  },
830
854
  setup(i) {
831
- const e = S(), n = R(null);
855
+ const e = B(), t = R(null);
832
856
  return T(() => {
833
- const t = n.value;
834
- if (!t) return;
857
+ const n = t.value;
858
+ if (!n) return;
835
859
  const r = !!e.cell, s = !!e.editor;
836
- r && le(t, (d) => {
860
+ r && le(n, (d) => {
837
861
  const l = e.cell;
838
862
  if (!l) return C("span");
839
863
  const a = l({
@@ -842,7 +866,7 @@ const pe = fe, Re = /* @__PURE__ */ y({
842
866
  column: d.column
843
867
  });
844
868
  return C("div", { style: "display: contents" }, a);
845
- }), s && ae(t, (d) => {
869
+ }), s && ae(n, (d) => {
846
870
  const l = e.editor;
847
871
  if (!l) return C("span");
848
872
  const a = l({
@@ -858,9 +882,9 @@ const pe = fe, Re = /* @__PURE__ */ y({
858
882
  });
859
883
  return C("div", { style: "display: contents" }, a);
860
884
  });
861
- }), (t, r) => (P(), O("tbw-grid-column", {
885
+ }), (n, r) => (P(), O("tbw-grid-column", {
862
886
  ref_key: "columnRef",
863
- ref: n,
887
+ ref: t,
864
888
  field: i.field,
865
889
  header: i.header,
866
890
  width: i.width,
@@ -881,11 +905,11 @@ const pe = fe, Re = /* @__PURE__ */ y({
881
905
  animation: { type: [String, Boolean], default: "slide" }
882
906
  },
883
907
  setup(i) {
884
- const e = R(null), n = S();
908
+ const e = R(null), t = B();
885
909
  return T(() => {
886
- const t = e.value;
887
- !t || !n.default || Q.set(t, (r) => n.default?.(r));
888
- }), (t, r) => (P(), O("tbw-grid-detail", {
910
+ const n = e.value;
911
+ !n || !t.default || Q.set(n, (r) => t.default?.(r));
912
+ }), (n, r) => (P(), O("tbw-grid-detail", {
889
913
  ref_key: "detailRef",
890
914
  ref: e,
891
915
  "show-expand-column": i.showExpandColumn,
@@ -895,11 +919,11 @@ const pe = fe, Re = /* @__PURE__ */ y({
895
919
  }), Pe = /* @__PURE__ */ y({
896
920
  __name: "TbwGridResponsiveCard",
897
921
  setup(i) {
898
- const e = R(null), n = S();
922
+ const e = R(null), t = B();
899
923
  return T(() => {
900
- const t = e.value;
901
- !t || !n.default || X.set(t, (r) => n.default?.(r));
902
- }), (t, r) => (P(), O("tbw-grid-responsive-card", {
924
+ const n = e.value;
925
+ !n || !t.default || X.set(n, (r) => t.default?.(r));
926
+ }), (n, r) => (P(), O("tbw-grid-responsive-card", {
903
927
  ref_key: "cardRef",
904
928
  ref: e
905
929
  }, null, 512));
@@ -907,7 +931,7 @@ const pe = fe, Re = /* @__PURE__ */ y({
907
931
  }), _e = /* @__PURE__ */ y({
908
932
  __name: "TbwGridToolButtons",
909
933
  setup(i) {
910
- return (e, n) => (P(), O("tbw-grid-tool-buttons", null, [
934
+ return (e, t) => (P(), O("tbw-grid-tool-buttons", null, [
911
935
  U(e.$slots, "default")
912
936
  ]));
913
937
  }
@@ -921,11 +945,11 @@ const pe = fe, Re = /* @__PURE__ */ y({
921
945
  width: { default: "250px" }
922
946
  },
923
947
  setup(i) {
924
- const e = R(null), n = S();
948
+ const e = R(null), t = B();
925
949
  return T(() => {
926
- const t = e.value;
927
- !t || !n.default || ye.set(t, (r) => n.default?.(r));
928
- }), (t, r) => (P(), O("tbw-grid-tool-panel", {
950
+ const n = e.value;
951
+ !n || !t.default || ye.set(n, (r) => t.default?.(r));
952
+ }), (n, r) => (P(), O("tbw-grid-tool-panel", {
929
953
  ref_key: "panelRef",
930
954
  ref: e,
931
955
  id: i.id,
@@ -936,11 +960,11 @@ const pe = fe, Re = /* @__PURE__ */ y({
936
960
  }, null, 8, ve));
937
961
  }
938
962
  });
939
- function Ge(i, e, n) {
940
- const t = n ?? F(H, R(null));
963
+ function Ge(i, e, t) {
964
+ const n = t ?? F(H, R(null));
941
965
  let r = null;
942
966
  T(() => {
943
- const s = t.value;
967
+ const s = n.value;
944
968
  if (!s) return;
945
969
  const d = e;
946
970
  s.addEventListener(i, d), r = () => s.removeEventListener(i, d);
@@ -968,8 +992,8 @@ const je = y({
968
992
  },
969
993
  setup(i, { slots: e }) {
970
994
  return () => {
971
- let n = e.default?.();
972
- return i.typeDefaults && (n = C(de, { defaults: i.typeDefaults }, () => n)), i.icons && (n = C(se, { icons: i.icons }, () => n)), n;
995
+ let t = e.default?.();
996
+ return i.typeDefaults && (t = C(de, { defaults: i.typeDefaults }, () => t)), i.icons && (t = C(se, { icons: i.icons }, () => t)), t;
973
997
  };
974
998
  }
975
999
  });
@@ -988,7 +1012,7 @@ export {
988
1012
  _e as TbwGridToolButtons,
989
1013
  De as TbwGridToolPanel,
990
1014
  pe as VueGridAdapter,
991
- Ve as clearFeatureRegistry,
1015
+ Se as clearFeatureRegistry,
992
1016
  oe as createPluginFromFeature,
993
1017
  ke as getFeatureFactory,
994
1018
  Le as getRegisteredFeatures,
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../libs/grid-vue/src/lib/grid-icon-registry.ts","../../../libs/grid-vue/src/lib/grid-type-registry.ts","../../../libs/grid-vue/src/lib/detail-panel-registry.ts","../../../libs/grid-vue/src/lib/responsive-card-registry.ts","../../../libs/grid-vue/src/lib/vue-grid-adapter.ts","../../../libs/grid-vue/src/lib/TbwGrid.vue","../../../libs/grid-vue/src/lib/TbwGridColumn.vue","../../../libs/grid-vue/src/lib/TbwGridDetailPanel.vue","../../../libs/grid-vue/src/lib/TbwGridResponsiveCard.vue","../../../libs/grid-vue/src/lib/TbwGridToolButtons.vue","../../../libs/grid-vue/src/lib/tool-panel-registry.ts","../../../libs/grid-vue/src/lib/TbwGridToolPanel.vue","../../../libs/grid-vue/src/lib/use-grid-event.ts","../../../libs/grid-vue/src/lib/grid-provider.ts"],"sourcesContent":["/**\n * Icon registry for Vue applications.\n *\n * Provides application-wide icon overrides that all grids inherit\n * automatically via Vue's provide/inject.\n */\nimport type { GridIcons } from '@toolbox-web/grid';\nimport { defineComponent, inject, provide, type InjectionKey, type PropType } from 'vue';\n\n/**\n * Injection key for grid icons.\n */\nexport const GRID_ICONS: InjectionKey<Partial<GridIcons>> = Symbol('grid-icons');\n\n/**\n * Composable to get the current icon overrides from the nearest provider.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useGridIcons } from '@toolbox-web/grid-vue';\n *\n * const icons = useGridIcons();\n * </script>\n * ```\n */\nexport function useGridIcons(): Partial<GridIcons> | undefined {\n return inject(GRID_ICONS, undefined);\n}\n\n/**\n * Provides application-wide icon overrides for all descendant grids.\n *\n * Wrap your application (or part of it) with this provider to customize\n * icons used by all TbwGrid components.\n *\n * @example\n * ```vue\n * <script setup>\n * import { GridIconProvider } from '@toolbox-web/grid-vue';\n *\n * const icons = {\n * sortAsc: '↑',\n * sortDesc: '↓',\n * expand: '+',\n * collapse: '−',\n * };\n * </script>\n *\n * <template>\n * <GridIconProvider :icons=\"icons\">\n * <App />\n * </GridIconProvider>\n * </template>\n * ```\n */\nexport const GridIconProvider = defineComponent({\n name: 'GridIconProvider',\n props: {\n /**\n * Icon overrides to provide to all descendant grids.\n */\n icons: {\n type: Object as PropType<Partial<GridIcons>>,\n required: true,\n },\n },\n setup(props, { slots }) {\n // Provide icons to descendants\n provide(GRID_ICONS, props.icons);\n\n // Render children\n return () => slots.default?.();\n },\n});\n\nexport type GridIconProviderProps = InstanceType<typeof GridIconProvider>['$props'];\n","/**\n * Type-level default registry for Vue applications.\n *\n * Provides application-wide type defaults for renderers and editors\n * that all grids inherit automatically via Vue's provide/inject.\n */\nimport type { CellRenderContext, ColumnEditorContext } from '@toolbox-web/grid';\nimport type { FilterPanelParams } from '@toolbox-web/grid/plugins/filtering';\nimport { defineComponent, inject, provide, type InjectionKey, type PropType, type VNode } from 'vue';\n\n// #region TypeDefault Interface\n/**\n * Type default configuration for Vue applications.\n *\n * Defines default renderer, editor, and editorParams for a data type\n * using Vue render functions.\n *\n * @example\n * ```ts\n * import type { TypeDefault } from '@toolbox-web/grid-vue';\n * import CountryFlag from './CountryFlag.vue';\n * import CountrySelect from './CountrySelect.vue';\n *\n * const countryDefault: TypeDefault<Employee, string> = {\n * renderer: (ctx) => h(CountryFlag, { code: ctx.value }),\n * editor: (ctx) => h(CountrySelect, {\n * modelValue: ctx.value,\n * 'onUpdate:modelValue': ctx.commit,\n * }),\n * };\n * ```\n */\nexport interface TypeDefault<TRow = unknown, TValue = unknown> {\n /** Vue render function for rendering cells of this type */\n renderer?: (ctx: CellRenderContext<TRow, TValue>) => VNode;\n /** Vue render function for editing cells of this type */\n editor?: (ctx: ColumnEditorContext<TRow, TValue>) => VNode;\n /** Default editorParams for this type */\n editorParams?: Record<string, unknown>;\n /**\n * Vue render function for custom filter panels for this type.\n *\n * Unlike the core imperative API `(container, params) => void`, this accepts\n * a Vue render function that receives only the params and returns a VNode.\n * The bridge handles mounting and appending to the container automatically.\n *\n * @example\n * ```ts\n * import { h } from 'vue';\n * import CustomFilter from './CustomFilter.vue';\n *\n * const typeDefault: TypeDefault = {\n * filterPanelRenderer: (params) => h(CustomFilter, {\n * field: params.field,\n * uniqueValues: params.uniqueValues,\n * onApply: (values: Set<unknown>) => params.applySetFilter(values),\n * }),\n * };\n * ```\n */\n filterPanelRenderer?: (params: FilterPanelParams) => VNode;\n}\n\n/**\n * @deprecated Use `TypeDefault` instead.\n * @see {@link TypeDefault}\n */\nexport type VueTypeDefault<TRow = unknown, TValue = unknown> = TypeDefault<TRow, TValue>;\n// #endregion\n\n/**\n * Type defaults registry - a map of type names to their defaults.\n */\nexport type TypeDefaultsMap = Record<string, TypeDefault>;\n\n/**\n * Injection key for type defaults.\n */\nexport const GRID_TYPE_DEFAULTS: InjectionKey<TypeDefaultsMap> = Symbol('grid-type-defaults');\n\n/**\n * Composable to get the current type defaults from the nearest provider.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useGridTypeDefaults } from '@toolbox-web/grid-vue';\n *\n * const typeDefaults = useGridTypeDefaults();\n * </script>\n * ```\n */\nexport function useGridTypeDefaults(): TypeDefaultsMap | undefined {\n return inject(GRID_TYPE_DEFAULTS, undefined);\n}\n\n/**\n * Composable to get a specific type's default configuration.\n *\n * @param typeName - The type name to look up\n *\n * @example\n * ```vue\n * <script setup>\n * import { useTypeDefault } from '@toolbox-web/grid-vue';\n *\n * const countryDefault = useTypeDefault('country');\n * </script>\n * ```\n */\nexport function useTypeDefault<TRow = unknown, TValue = unknown>(\n typeName: string,\n): TypeDefault<TRow, TValue> | undefined {\n const defaults = useGridTypeDefaults();\n return defaults?.[typeName] as TypeDefault<TRow, TValue> | undefined;\n}\n\n/**\n * Provides application-wide type defaults for all descendant grids.\n *\n * Wrap your application (or part of it) with this provider to make\n * type-level renderers and editors available to all TbwGrid components.\n *\n * @example\n * ```vue\n * <script setup>\n * import { GridTypeProvider, type TypeDefaultsMap } from '@toolbox-web/grid-vue';\n * import { h } from 'vue';\n * import CountryBadge from './CountryBadge.vue';\n *\n * const typeDefaults: TypeDefaultsMap = {\n * country: {\n * renderer: (ctx) => h(CountryBadge, { code: ctx.value }),\n * },\n * };\n * </script>\n *\n * <template>\n * <GridTypeProvider :defaults=\"typeDefaults\">\n * <App />\n * </GridTypeProvider>\n * </template>\n * ```\n */\nexport const GridTypeProvider = defineComponent({\n name: 'GridTypeProvider',\n props: {\n /**\n * Type defaults to provide to all descendant grids.\n */\n defaults: {\n type: Object as PropType<TypeDefaultsMap>,\n required: true,\n },\n },\n setup(props, { slots }) {\n // Provide type defaults to descendants\n provide(GRID_TYPE_DEFAULTS, props.defaults);\n\n // Render children\n return () => slots.default?.();\n },\n});\n\nexport type GridTypeProviderProps = InstanceType<typeof GridTypeProvider>['$props'];\n","/**\n * Registry for detail panel renderers.\n * @internal\n */\nimport type { VNode } from 'vue';\n\n/**\n * Context object passed to the detail panel slot.\n */\nexport interface DetailPanelContext<T = unknown> {\n /** The row data for this detail panel */\n row: T;\n /** The row index */\n rowIndex: number;\n}\n\n/**\n * Registry for detail renderers (per grid element)\n */\nexport const detailRegistry = new WeakMap<HTMLElement, (ctx: DetailPanelContext<unknown>) => VNode[] | undefined>();\n\n/**\n * Get the detail renderer for a grid element.\n * @internal\n */\nexport function getDetailRenderer(\n gridElement: HTMLElement,\n): ((ctx: DetailPanelContext<unknown>) => VNode[] | undefined) | undefined {\n const detailElement = gridElement.querySelector('tbw-grid-detail') as HTMLElement | null;\n if (detailElement) {\n return detailRegistry.get(detailElement);\n }\n return undefined;\n}\n","/**\n * Registry for responsive card renderers.\n * @internal\n */\nimport type { VNode } from 'vue';\n\n/**\n * Context object passed to the responsive card slot.\n */\nexport interface ResponsiveCardContext<T = unknown> {\n /** The row data */\n row: T;\n /** The row index */\n rowIndex: number;\n}\n\n/**\n * Registry for responsive card renderers (per element)\n */\nexport const cardRegistry = new WeakMap<HTMLElement, (ctx: ResponsiveCardContext<unknown>) => VNode[] | undefined>();\n\n/**\n * Get the responsive card renderer for a grid element.\n * @internal\n */\nexport function getResponsiveCardRenderer(\n gridElement: HTMLElement,\n): ((ctx: ResponsiveCardContext<unknown>) => VNode[] | undefined) | undefined {\n const cardElement = gridElement.querySelector('tbw-grid-responsive-card') as HTMLElement | null;\n if (cardElement) {\n return cardRegistry.get(cardElement);\n }\n return undefined;\n}\n","import type {\n ColumnConfig as BaseColumnConfig,\n GridConfig as BaseGridConfig,\n TypeDefault as BaseTypeDefault,\n CellRenderContext,\n ColumnEditorContext,\n ColumnEditorSpec,\n ColumnViewRenderer,\n FrameworkAdapter,\n} from '@toolbox-web/grid';\nimport type { FilterPanelParams } from '@toolbox-web/grid/plugins/filtering';\nimport { createApp, createVNode, type App, type Component, type VNode } from 'vue';\nimport { detailRegistry, type DetailPanelContext } from './detail-panel-registry';\nimport type { TypeDefault, TypeDefaultsMap } from './grid-type-registry';\nimport { cardRegistry, type ResponsiveCardContext } from './responsive-card-registry';\nimport type { ColumnConfig, GridConfig } from './vue-column-config';\nexport type { GridConfig };\n\n/**\n * Registry mapping column elements to their Vue render functions.\n * Each column element stores its renderer/editor functions here.\n */\ninterface ColumnRegistry {\n renderer?: (ctx: CellRenderContext<unknown, unknown>) => VNode;\n editor?: (ctx: ColumnEditorContext<unknown, unknown>) => VNode;\n}\n\nconst columnRegistries = new WeakMap<HTMLElement, ColumnRegistry>();\n\n// Secondary registry by field name to handle Vue component re-creation\nconst fieldRegistries = new Map<string, ColumnRegistry>();\n\n/**\n * Register a Vue cell renderer for a column element.\n * Called by TbwGridColumn when it has a #cell slot.\n */\nexport function registerColumnRenderer(\n element: HTMLElement,\n renderer: (ctx: CellRenderContext<unknown, unknown>) => VNode,\n): void {\n const field = element.getAttribute('field');\n\n const registry = columnRegistries.get(element) ?? {};\n registry.renderer = renderer;\n columnRegistries.set(element, registry);\n\n // Also register by field name for fallback lookup\n if (field) {\n const fieldRegistry = fieldRegistries.get(field) ?? {};\n fieldRegistry.renderer = renderer;\n fieldRegistries.set(field, fieldRegistry);\n }\n}\n\n/**\n * Register a Vue cell editor for a column element.\n * Called by TbwGridColumn when it has an #editor slot.\n */\nexport function registerColumnEditor(\n element: HTMLElement,\n editor: (ctx: ColumnEditorContext<unknown, unknown>) => VNode,\n): void {\n const field = element.getAttribute('field');\n const registry = columnRegistries.get(element) ?? {};\n registry.editor = editor;\n columnRegistries.set(element, registry);\n\n // Also register by field name for fallback lookup\n if (field) {\n const fieldRegistry = fieldRegistries.get(field) ?? {};\n fieldRegistry.editor = editor;\n fieldRegistries.set(field, fieldRegistry);\n }\n}\n\n/**\n * Get the renderer registered for a column element.\n * Falls back to field-based lookup if WeakMap lookup fails.\n */\nexport function getColumnRenderer(\n element: HTMLElement,\n): ((ctx: CellRenderContext<unknown, unknown>) => VNode) | undefined {\n let renderer = columnRegistries.get(element)?.renderer;\n\n // Fallback to field-based lookup for Vue component re-creation scenarios\n if (!renderer) {\n const field = element.getAttribute('field');\n if (field) {\n renderer = fieldRegistries.get(field)?.renderer;\n }\n }\n\n return renderer;\n}\n\n/**\n * Get the editor registered for a column element.\n * Falls back to field-based lookup if WeakMap lookup fails.\n */\nexport function getColumnEditor(\n element: HTMLElement,\n): ((ctx: ColumnEditorContext<unknown, unknown>) => VNode) | undefined {\n let editor = columnRegistries.get(element)?.editor;\n\n // Fallback to field-based lookup for Vue component re-creation scenarios\n if (!editor) {\n const field = element.getAttribute('field');\n if (field) {\n editor = fieldRegistries.get(field)?.editor;\n }\n }\n\n return editor;\n}\n\n/**\n * Get all registered field names.\n * @internal - for testing only\n */\nexport function getRegisteredFields(): string[] {\n return Array.from(fieldRegistries.keys());\n}\n\n/**\n * Clear the field registries.\n * @internal - for testing only\n */\nexport function clearFieldRegistries(): void {\n fieldRegistries.clear();\n}\n\n// #region Vue Component Detection\n\n/**\n * Checks if a value is a Vue component (SFC or defineComponent result).\n *\n * Vue components are identified by:\n * - Having `__name` (SFC compiled marker)\n * - Having `setup` function (Composition API component)\n * - Having `render` function (Options API component)\n * - Being an ES6 class (class-based component)\n *\n * Regular functions `(ctx) => HTMLElement` that are already processed\n * will not match these checks, making this idempotent.\n */\nexport function isVueComponent(value: unknown): value is Component {\n if (value == null) return false;\n\n // Already a DOM-returning function (processed) — skip\n if (typeof value === 'function' && value.prototype === undefined) {\n // Plain arrow/function — could be a VNode-returning render fn OR\n // an already-processed DOM-returning fn. We can't distinguish at runtime,\n // so we check if it looks like a Vue component (has component markers).\n // Plain functions without component markers are treated as VNode-returning.\n return false;\n }\n\n if (typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n // SFC compiled marker\n if ('__name' in obj) return true;\n // Composition API\n if (typeof obj['setup'] === 'function') return true;\n // Options API\n if (typeof obj['render'] === 'function') return true;\n }\n\n if (typeof value === 'function') {\n // ES6 class-based component\n const fnString = Function.prototype.toString.call(value);\n if (fnString.startsWith('class ') || fnString.startsWith('class{')) return true;\n\n // defineComponent returns a function with component markers\n const fn = value as unknown as Record<string, unknown>;\n if ('__name' in fn || typeof fn['setup'] === 'function') return true;\n }\n\n return false;\n}\n\n/**\n * Checks if a value is a VNode-returning render function.\n * These are plain functions (not component objects) that return VNodes.\n * They need wrapping to produce HTMLElements for the grid core.\n */\nfunction isVNodeRenderFunction(value: unknown): value is (...args: unknown[]) => VNode {\n return typeof value === 'function' && !isVueComponent(value);\n}\n\n/**\n * Symbol used to mark renderer/editor functions that have already been\n * processed by the adapter (i.e., wrapped from VNode/Component → DOM).\n * Prevents double-wrapping when `processGridConfig` is called multiple times.\n */\nconst PROCESSED_MARKER = Symbol.for('tbw:vue-processed');\n\n// #endregion\n\n/**\n * Tracks mounted Vue apps for cleanup.\n */\ninterface MountedView {\n app: App;\n container: HTMLElement;\n}\n\n/**\n * Cache for cell containers and their Vue apps.\n */\ninterface CellAppCache {\n app: App;\n container: HTMLElement;\n update: (ctx: CellRenderContext<unknown, unknown>) => void;\n}\n\n/**\n * Framework adapter that enables Vue 3 component integration\n * with the grid's light DOM configuration API.\n *\n * ## Usage\n *\n * The adapter is automatically registered when using the TbwGrid component.\n * For advanced use cases, you can manually register:\n *\n * ```ts\n * import { GridElement } from '@toolbox-web/grid';\n * import { GridAdapter } from '@toolbox-web/grid-vue';\n *\n * // One-time registration\n * GridElement.registerAdapter(new GridAdapter());\n * ```\n *\n * ## Declarative usage with TbwGrid:\n *\n * ```vue\n * <TbwGrid :rows=\"data\" :grid-config=\"config\">\n * <TbwGridColumn field=\"status\">\n * <template #cell=\"{ value, row }\">\n * <StatusBadge :value=\"value\" />\n * </template>\n * </TbwGridColumn>\n * </TbwGrid>\n * ```\n */\nexport class GridAdapter implements FrameworkAdapter {\n private mountedViews: MountedView[] = [];\n private typeDefaults: TypeDefaultsMap | null = null;\n\n // #region Config Processing\n\n /**\n * Processes a Vue grid configuration, converting Vue component references\n * and VNode-returning render functions to DOM-returning functions.\n *\n * This is idempotent — already-processed configs pass through safely.\n *\n * @example\n * ```ts\n * import { GridAdapter, type GridConfig } from '@toolbox-web/grid-vue';\n * import StatusBadge from './StatusBadge.vue';\n *\n * const config: GridConfig<Employee> = {\n * columns: [\n * { field: 'status', renderer: StatusBadge },\n * ],\n * };\n *\n * const adapter = new GridAdapter();\n * const processedConfig = adapter.processGridConfig(config);\n * ```\n *\n * @param config - Vue grid config with possible component/VNode references\n * @returns Processed config with DOM-returning functions\n */\n processGridConfig<TRow = unknown>(config: GridConfig<TRow>): BaseGridConfig<TRow> {\n const result = { ...config } as BaseGridConfig<TRow>;\n\n // Process columns\n if (config.columns) {\n result.columns = config.columns.map((col) => this.processColumn(col));\n }\n\n // Process typeDefaults\n if (config.typeDefaults) {\n result.typeDefaults = this.processTypeDefaults(config.typeDefaults as Record<string, TypeDefault>) as Record<\n string,\n BaseTypeDefault<TRow>\n >;\n }\n\n return result;\n }\n\n /**\n * Processes typeDefaults, converting Vue component/VNode references\n * to DOM-returning functions.\n *\n * @param typeDefaults - Vue type defaults with possible component references\n * @returns Processed TypeDefault record\n */\n processTypeDefaults<TRow = unknown>(\n typeDefaults: Record<string, TypeDefault<TRow>>,\n ): Record<string, BaseTypeDefault<TRow>> {\n const processed: Record<string, BaseTypeDefault<TRow>> = {};\n\n for (const [type, config] of Object.entries(typeDefaults)) {\n const processedConfig: BaseTypeDefault<TRow> = {\n editorParams: config.editorParams,\n };\n\n if (config.renderer) {\n if (isVueComponent(config.renderer)) {\n processedConfig.renderer = this.createConfigComponentRenderer(config.renderer as Component);\n } else if (isVNodeRenderFunction(config.renderer)) {\n processedConfig.renderer = this.createTypeRenderer(\n config.renderer as (ctx: CellRenderContext<TRow>) => VNode,\n );\n }\n }\n\n if (config.editor) {\n if (isVueComponent(config.editor)) {\n processedConfig.editor = this.createConfigComponentEditor(\n config.editor as Component,\n ) as BaseTypeDefault['editor'];\n } else if (isVNodeRenderFunction(config.editor)) {\n processedConfig.editor = this.createTypeEditor(\n config.editor as (ctx: ColumnEditorContext<TRow>) => VNode,\n ) as BaseTypeDefault['editor'];\n }\n }\n\n if (config.filterPanelRenderer) {\n processedConfig.filterPanelRenderer = this.createFilterPanelRenderer(config.filterPanelRenderer);\n }\n\n processed[type] = processedConfig;\n }\n\n return processed;\n }\n\n /**\n * Processes a single column configuration, converting Vue component references\n * and VNode-returning render functions to DOM-returning functions.\n *\n * @param column - Vue column config\n * @returns Processed ColumnConfig with DOM-returning functions\n */\n processColumn<TRow = unknown>(column: ColumnConfig<TRow>): BaseColumnConfig<TRow> {\n const processed = { ...column } as BaseColumnConfig<TRow>;\n\n if (column.renderer && !(column.renderer as unknown as Record<symbol, unknown>)[PROCESSED_MARKER]) {\n if (isVueComponent(column.renderer)) {\n const wrapped = this.createConfigComponentRenderer(column.renderer as Component);\n (wrapped as unknown as Record<symbol, unknown>)[PROCESSED_MARKER] = true;\n processed.renderer = wrapped as BaseColumnConfig<TRow>['renderer'];\n } else if (isVNodeRenderFunction(column.renderer)) {\n const wrapped = this.createConfigVNodeRenderer(column.renderer as (ctx: CellRenderContext<TRow>) => VNode);\n (wrapped as unknown as Record<symbol, unknown>)[PROCESSED_MARKER] = true;\n processed.renderer = wrapped as BaseColumnConfig<TRow>['renderer'];\n }\n }\n\n if (column.editor && !(column.editor as unknown as Record<symbol, unknown>)[PROCESSED_MARKER]) {\n if (isVueComponent(column.editor)) {\n const wrapped = this.createConfigComponentEditor(column.editor as Component);\n (wrapped as unknown as Record<symbol, unknown>)[PROCESSED_MARKER] = true;\n processed.editor = wrapped as BaseColumnConfig<TRow>['editor'];\n } else if (isVNodeRenderFunction(column.editor)) {\n const wrapped = this.createConfigVNodeEditor(column.editor as (ctx: ColumnEditorContext<TRow>) => VNode);\n (wrapped as unknown as Record<symbol, unknown>)[PROCESSED_MARKER] = true;\n processed.editor = wrapped as BaseColumnConfig<TRow>['editor'];\n }\n }\n\n return processed;\n }\n\n /**\n * Creates a DOM-returning renderer from a Vue component class.\n * Used for config-based renderers (not slot-based).\n * @internal\n */\n private createConfigComponentRenderer<TRow = unknown, TValue = unknown>(\n component: Component,\n ): ColumnViewRenderer<TRow, TValue> {\n const cellCache = new WeakMap<HTMLElement, CellAppCache>();\n\n return (ctx: CellRenderContext<TRow, TValue>) => {\n const cellEl = (ctx as any).cellEl as HTMLElement | undefined;\n\n if (cellEl) {\n const cached = cellCache.get(cellEl);\n if (cached) {\n cached.update(ctx as CellRenderContext<unknown, unknown>);\n return cached.container;\n }\n\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n let currentCtx = ctx as CellRenderContext<unknown, unknown>;\n const comp = component;\n\n const app = createApp({\n render() {\n return createVNode(comp, { ...currentCtx });\n },\n });\n\n app.mount(container);\n\n cellCache.set(cellEl, {\n app,\n container,\n update: (newCtx) => {\n currentCtx = newCtx;\n app._instance?.update();\n },\n });\n\n return container;\n }\n\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n const comp = component;\n const app = createApp({\n render() {\n return createVNode(comp, { ...ctx });\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates a DOM-returning renderer from a VNode-returning render function.\n * Used for config-based renderers (not slot-based).\n * @internal\n */\n private createConfigVNodeRenderer<TRow = unknown, TValue = unknown>(\n renderFn: (ctx: CellRenderContext<TRow, TValue>) => VNode,\n ): ColumnViewRenderer<TRow, TValue> {\n const cellCache = new WeakMap<HTMLElement, CellAppCache>();\n\n return (ctx: CellRenderContext<TRow, TValue>) => {\n const cellEl = (ctx as any).cellEl as HTMLElement | undefined;\n\n if (cellEl) {\n const cached = cellCache.get(cellEl);\n if (cached) {\n cached.update(ctx as CellRenderContext<unknown, unknown>);\n return cached.container;\n }\n\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n let currentCtx = ctx as CellRenderContext<unknown, unknown>;\n\n const app = createApp({\n render() {\n return renderFn(currentCtx as CellRenderContext<TRow, TValue>);\n },\n });\n\n app.mount(container);\n\n cellCache.set(cellEl, {\n app,\n container,\n update: (newCtx) => {\n currentCtx = newCtx;\n app._instance?.update();\n },\n });\n\n return container;\n }\n\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(ctx);\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates a DOM-returning editor from a Vue component class.\n * Used for config-based editors (not slot-based).\n * @internal\n */\n private createConfigComponentEditor<TRow = unknown, TValue = unknown>(\n component: Component,\n ): ColumnEditorSpec<TRow, TValue> {\n return (ctx: ColumnEditorContext<TRow, TValue>): HTMLElement => {\n const container = document.createElement('div');\n container.className = 'vue-cell-editor';\n container.style.display = 'contents';\n\n const comp = component;\n const app = createApp({\n render() {\n return createVNode(comp, { ...ctx });\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates a DOM-returning editor from a VNode-returning render function.\n * Used for config-based editors (not slot-based).\n * @internal\n */\n private createConfigVNodeEditor<TRow = unknown, TValue = unknown>(\n renderFn: (ctx: ColumnEditorContext<TRow, TValue>) => VNode,\n ): ColumnEditorSpec<TRow, TValue> {\n return (ctx: ColumnEditorContext<TRow, TValue>): HTMLElement => {\n const container = document.createElement('div');\n container.className = 'vue-cell-editor';\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(ctx);\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n // #endregion\n\n /**\n * Sets the type defaults map for this adapter.\n * Called by TbwGrid when it receives type defaults from context.\n *\n * @internal\n */\n setTypeDefaults(defaults: TypeDefaultsMap | null): void {\n this.typeDefaults = defaults;\n }\n\n /**\n * Determines if this adapter can handle the given element.\n * Checks if a renderer or editor is registered for this element.\n */\n canHandle(element: HTMLElement): boolean {\n const field = element.getAttribute('field');\n let registry = columnRegistries.get(element);\n\n // If not found in WeakMap, try field-based lookup\n if (!registry && field) {\n const fieldRegistry = fieldRegistries.get(field);\n if (fieldRegistry && (fieldRegistry.renderer || fieldRegistry.editor)) {\n registry = fieldRegistry;\n columnRegistries.set(element, registry);\n }\n }\n\n const hasRenderer = registry?.renderer !== undefined;\n const hasEditor = registry?.editor !== undefined;\n return registry !== undefined && (hasRenderer || hasEditor);\n }\n\n /**\n * Creates a view renderer function that renders a Vue component\n * and returns its container DOM element.\n */\n createRenderer<TRow = unknown, TValue = unknown>(element: HTMLElement): ColumnViewRenderer<TRow, TValue> {\n const renderFn = getColumnRenderer(element);\n\n if (!renderFn) {\n return undefined as unknown as ColumnViewRenderer<TRow, TValue>;\n }\n\n // Cell cache for this field - maps cell element to its Vue app\n const cellCache = new WeakMap<HTMLElement, CellAppCache>();\n\n return (ctx: CellRenderContext<TRow, TValue>) => {\n const cellEl = (ctx as any).cellEl as HTMLElement | undefined;\n\n if (cellEl) {\n // Check if we have a cached app for this cell\n const cached = cellCache.get(cellEl);\n if (cached) {\n // Update the existing app with new context\n cached.update(ctx as CellRenderContext<unknown, unknown>);\n return cached.container;\n }\n\n // Create new container and Vue app for this cell\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n // Create reactive context that can be updated\n let currentCtx = ctx as CellRenderContext<unknown, unknown>;\n\n const app = createApp({\n render() {\n return renderFn(currentCtx);\n },\n });\n\n app.mount(container);\n\n // Store in cache with update function\n cellCache.set(cellEl, {\n app,\n container,\n update: (newCtx) => {\n currentCtx = newCtx;\n // Force re-render\n app._instance?.update();\n },\n });\n\n return container;\n }\n\n // Fallback: create container without caching\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(ctx as CellRenderContext<unknown, unknown>);\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates an editor spec that renders a Vue component for cell editing.\n * Returns a function that creates the editor DOM element.\n */\n createEditor<TRow = unknown, TValue = unknown>(element: HTMLElement): ColumnEditorSpec<TRow, TValue> {\n const editorFn = getColumnEditor(element);\n\n if (!editorFn) {\n return undefined as unknown as ColumnEditorSpec<TRow, TValue>;\n }\n\n // Return a function that creates the editor element\n return (ctx: ColumnEditorContext<TRow, TValue>): HTMLElement => {\n const container = document.createElement('div');\n container.className = 'vue-cell-editor';\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return editorFn(ctx as ColumnEditorContext<unknown, unknown>);\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Framework adapter hook called by MasterDetailPlugin during attach().\n * Parses the <tbw-grid-detail> element and returns a Vue-based renderer.\n */\n parseDetailElement<TRow = unknown>(\n detailElement: Element,\n ): ((row: TRow, rowIndex: number) => HTMLElement) | undefined {\n const gridElement = detailElement.closest('tbw-grid') as HTMLElement | null;\n if (!gridElement) return undefined;\n\n // Get renderer from registry (registered by TbwGridDetailPanel)\n const detailEl = gridElement.querySelector('tbw-grid-detail') as HTMLElement | null;\n if (!detailEl) return undefined;\n\n const renderFn = detailRegistry.get(detailEl);\n if (!renderFn) return undefined;\n\n return (row: TRow, rowIndex: number): HTMLElement => {\n const container = document.createElement('div');\n container.className = 'vue-detail-panel';\n\n const ctx: DetailPanelContext<TRow> = { row, rowIndex };\n const vnodes = renderFn(ctx as DetailPanelContext<unknown>);\n\n if (vnodes && vnodes.length > 0) {\n // Render VNodes into container\n const app = createApp({\n render() {\n return vnodes;\n },\n });\n app.mount(container);\n this.mountedViews.push({ app, container });\n }\n\n return container;\n };\n }\n\n /**\n * Framework adapter hook called by ResponsivePlugin during attach().\n * Parses the <tbw-grid-responsive-card> element and returns a Vue-based renderer.\n */\n parseResponsiveCardElement<TRow = unknown>(\n cardElement: Element,\n ): ((row: TRow, rowIndex: number) => HTMLElement) | undefined {\n const gridElement = cardElement.closest('tbw-grid') as HTMLElement | null;\n if (!gridElement) return undefined;\n\n // Get renderer from registry (registered by TbwGridResponsiveCard)\n const cardEl = gridElement.querySelector('tbw-grid-responsive-card') as HTMLElement | null;\n if (!cardEl) return undefined;\n\n const renderFn = cardRegistry.get(cardEl);\n if (!renderFn) return undefined;\n\n return (row: TRow, rowIndex: number): HTMLElement => {\n const container = document.createElement('div');\n container.className = 'vue-responsive-card';\n\n const ctx: ResponsiveCardContext<TRow> = { row, rowIndex };\n const vnodes = renderFn(ctx as ResponsiveCardContext<unknown>);\n\n if (vnodes && vnodes.length > 0) {\n // Render VNodes into container\n const app = createApp({\n render() {\n return vnodes;\n },\n });\n app.mount(container);\n this.mountedViews.push({ app, container });\n }\n\n return container;\n };\n }\n\n // #region Type Defaults Support\n\n /**\n * Gets type-level defaults from the type defaults map.\n *\n * This enables application-wide type defaults configured via GridTypeProvider.\n * The returned TypeDefault contains renderer/editor functions that render\n * Vue components into the grid's cells.\n *\n * @example\n * ```vue\n * <script setup>\n * import { GridTypeProvider } from '@toolbox-web/grid-vue';\n * import { h } from 'vue';\n * import CountryBadge from './CountryBadge.vue';\n *\n * const typeDefaults = {\n * country: {\n * renderer: (ctx) => h(CountryBadge, { code: ctx.value }),\n * },\n * };\n * </script>\n *\n * <template>\n * <GridTypeProvider :defaults=\"typeDefaults\">\n * <App />\n * </GridTypeProvider>\n * </template>\n * ```\n */\n getTypeDefault<TRow = unknown>(type: string): BaseTypeDefault<TRow> | undefined {\n if (!this.typeDefaults) {\n return undefined;\n }\n\n const vueDefault = this.typeDefaults[type] as TypeDefault<TRow> | undefined;\n if (!vueDefault) {\n return undefined;\n }\n\n const typeDefault: BaseTypeDefault<TRow> = {\n editorParams: vueDefault.editorParams,\n };\n\n // Create renderer function that renders Vue component\n if (vueDefault.renderer) {\n typeDefault.renderer = this.createTypeRenderer<TRow>(vueDefault.renderer);\n }\n\n // Create editor function that renders Vue component\n if (vueDefault.editor) {\n typeDefault.editor = this.createTypeEditor<TRow>(vueDefault.editor) as BaseTypeDefault['editor'];\n }\n\n // Create filterPanelRenderer function that renders Vue component\n if (vueDefault.filterPanelRenderer) {\n typeDefault.filterPanelRenderer = this.createFilterPanelRenderer(vueDefault.filterPanelRenderer);\n }\n\n return typeDefault;\n }\n\n /**\n * Creates a renderer function from a Vue render function for type defaults.\n * @internal\n */\n private createTypeRenderer<TRow = unknown, TValue = unknown>(\n renderFn: (ctx: CellRenderContext<TRow, TValue>) => VNode,\n ): ColumnViewRenderer<TRow, TValue> {\n return (ctx: CellRenderContext<TRow, TValue>) => {\n const container = document.createElement('span');\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(ctx);\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates an editor function from a Vue render function for type defaults.\n * @internal\n */\n private createTypeEditor<TRow = unknown, TValue = unknown>(\n renderFn: (ctx: ColumnEditorContext<TRow, TValue>) => VNode,\n ): ColumnEditorSpec<TRow, TValue> {\n return (ctx: ColumnEditorContext<TRow, TValue>) => {\n const container = document.createElement('span');\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(ctx);\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates a filter panel renderer function from a Vue render function.\n *\n * Wraps a Vue `(params: FilterPanelParams) => VNode` function into the\n * imperative `(container, params) => void` signature expected by the core grid.\n * @internal\n */\n private createFilterPanelRenderer(\n renderFn: (params: FilterPanelParams) => VNode,\n ): (container: HTMLElement, params: FilterPanelParams) => void {\n return (container: HTMLElement, params: FilterPanelParams) => {\n const wrapper = document.createElement('div');\n wrapper.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(params);\n },\n });\n\n app.mount(wrapper);\n this.mountedViews.push({ app, container: wrapper });\n container.appendChild(wrapper);\n };\n }\n\n // #endregion\n\n /**\n * Cleanup all mounted Vue apps.\n */\n cleanup(): void {\n for (const { app, container } of this.mountedViews) {\n try {\n app.unmount();\n container.remove();\n } catch {\n // Ignore cleanup errors\n }\n }\n this.mountedViews = [];\n }\n}\n\n/**\n * @deprecated Use `GridAdapter` instead. This alias will be removed in a future version.\n * @see {@link GridAdapter}\n */\nexport const VueGridAdapter = GridAdapter;\n","<script setup lang=\"ts\" generic=\"TRow = unknown\">\nimport type { BaseGridPlugin, ColumnConfig, DataGridElement, FitMode, GridConfig } from '@toolbox-web/grid';\nimport { DataGridElement as GridElement } from '@toolbox-web/grid';\nimport type {\n ClipboardConfig,\n ColumnVirtualizationConfig,\n ContextMenuConfig,\n ExportConfig,\n FilterConfig,\n GroupingColumnsConfig,\n GroupingRowsConfig,\n MasterDetailConfig,\n MultiSortConfig,\n PinnedRowsConfig,\n PivotConfig,\n PrintConfig,\n ReorderConfig,\n ResponsivePluginConfig,\n RowReorderConfig,\n SelectionConfig,\n ServerSideConfig,\n TreeConfig,\n UndoRedoConfig,\n VisibilityConfig,\n} from '@toolbox-web/grid/all';\nimport { computed, onBeforeUnmount, onMounted, provide, ref, watch, type PropType } from 'vue';\nimport { createPluginFromFeature, type FeatureName } from './feature-registry';\nimport { useGridIcons } from './grid-icon-registry';\nimport { useGridTypeDefaults } from './grid-type-registry';\nimport { GRID_ELEMENT_KEY } from './use-grid';\nimport { GridAdapter, VueGridAdapter, type GridConfig as VueGridConfig } from './vue-grid-adapter';\n\n// Track if adapter is registered\nlet adapterRegistered = false;\nlet globalAdapter: GridAdapter | null = null;\n\n/**\n * Ensure the Vue adapter is registered globally.\n */\nfunction ensureAdapterRegistered(): GridAdapter {\n if (!adapterRegistered) {\n globalAdapter = new VueGridAdapter();\n GridElement.registerAdapter(globalAdapter);\n adapterRegistered = true;\n }\n return globalAdapter as GridAdapter;\n}\n\n// Register adapter at module load\nensureAdapterRegistered();\n\n/**\n * Props for TbwGrid component\n */\nconst props = defineProps({\n /** Row data to display */\n rows: {\n type: Array as PropType<TRow[]>,\n default: () => [],\n },\n /** Column definitions (shorthand for gridConfig.columns) */\n columns: {\n type: Array as PropType<ColumnConfig<TRow>[]>,\n default: undefined,\n },\n /** Full grid configuration */\n gridConfig: {\n type: Object as PropType<GridConfig<TRow>>,\n default: undefined,\n },\n /** Fit mode shorthand */\n fitMode: {\n type: String as PropType<FitMode>,\n default: undefined,\n },\n\n // ═══════════════════════════════════════════════════════════════════\n // FEATURE PROPS - Declarative plugin configuration\n // ═══════════════════════════════════════════════════════════════════\n\n /** Enable cell/row/range selection */\n selection: {\n type: [String, Object] as PropType<'cell' | 'row' | 'range' | SelectionConfig<TRow>>,\n default: undefined,\n },\n /** Enable inline cell editing */\n editing: {\n type: [Boolean, String] as PropType<boolean | 'click' | 'dblclick' | 'manual'>,\n default: undefined,\n },\n /** Enable clipboard copy/paste */\n clipboard: {\n type: [Boolean, Object] as PropType<boolean | ClipboardConfig>,\n default: undefined,\n },\n /** Enable right-click context menu */\n contextMenu: {\n type: [Boolean, Object] as PropType<boolean | ContextMenuConfig>,\n default: undefined,\n },\n /** Enable multi-column sorting */\n multiSort: {\n type: [Boolean, String, Object] as PropType<boolean | 'single' | 'multi' | MultiSortConfig>,\n default: undefined,\n },\n /** @deprecated Use multiSort instead */\n sorting: {\n type: [Boolean, String, Object] as PropType<boolean | 'single' | 'multi' | MultiSortConfig>,\n default: undefined,\n },\n /** Enable column filtering */\n filtering: {\n type: [Boolean, Object] as PropType<boolean | FilterConfig<TRow>>,\n default: undefined,\n },\n /** Enable column drag-to-reorder */\n reorder: {\n type: [Boolean, Object] as PropType<boolean | ReorderConfig>,\n default: undefined,\n },\n /** Enable column visibility toggle panel */\n visibility: {\n type: [Boolean, Object] as PropType<boolean | VisibilityConfig>,\n default: undefined,\n },\n /** Enable pinned/sticky columns */\n pinnedColumns: {\n type: Boolean as PropType<boolean>,\n default: undefined,\n },\n /** Enable multi-level column headers */\n groupingColumns: {\n type: [Boolean, Object] as PropType<boolean | GroupingColumnsConfig>,\n default: undefined,\n },\n /** Enable horizontal column virtualization */\n columnVirtualization: {\n type: [Boolean, Object] as PropType<boolean | ColumnVirtualizationConfig>,\n default: undefined,\n },\n /** Enable row drag-to-reorder */\n rowReorder: {\n type: [Boolean, Object] as PropType<boolean | RowReorderConfig>,\n default: undefined,\n },\n /** Enable row grouping by field values */\n groupingRows: {\n type: Object as PropType<GroupingRowsConfig>,\n default: undefined,\n },\n /** Enable pinned rows */\n pinnedRows: {\n type: [Boolean, Object] as PropType<boolean | PinnedRowsConfig>,\n default: undefined,\n },\n /** Enable hierarchical tree view */\n tree: {\n type: [Boolean, Object] as PropType<boolean | TreeConfig>,\n default: undefined,\n },\n /** Enable master-detail expandable rows */\n masterDetail: {\n type: Object as PropType<MasterDetailConfig>,\n default: undefined,\n },\n /** Enable responsive card layout */\n responsive: {\n type: [Boolean, Object] as PropType<boolean | ResponsivePluginConfig>,\n default: undefined,\n },\n /** Enable undo/redo for cell edits */\n undoRedo: {\n type: [Boolean, Object] as PropType<boolean | UndoRedoConfig>,\n default: undefined,\n },\n /** Enable CSV/JSON export */\n export: {\n type: [Boolean, Object] as PropType<boolean | ExportConfig>,\n default: undefined,\n },\n /** Enable print functionality */\n print: {\n type: [Boolean, Object] as PropType<boolean | PrintConfig>,\n default: undefined,\n },\n /** Enable pivot table functionality */\n pivot: {\n type: Object as PropType<PivotConfig>,\n default: undefined,\n },\n /** Enable server-side data operations */\n serverSide: {\n type: Object as PropType<ServerSideConfig>,\n default: undefined,\n },\n});\n\n/**\n * Emits for TbwGrid\n */\nconst emit = defineEmits<{\n /** Emitted when a cell value is committed */\n (e: 'cell-commit', event: CustomEvent): void;\n /** Emitted when a row's values are committed */\n (e: 'row-commit', event: CustomEvent): void;\n /** Emitted when a cell is clicked */\n (e: 'cell-click', event: CustomEvent): void;\n /** Emitted when a cell is double-clicked */\n (e: 'cell-dblclick', event: CustomEvent): void;\n /** Emitted when selection changes */\n (e: 'selection-change', event: CustomEvent): void;\n /** Emitted when a row is expanded/collapsed */\n (e: 'row-toggle', event: CustomEvent): void;\n /** Emitted when sorting changes */\n (e: 'sort-change', event: CustomEvent): void;\n /** Emitted when the grid is ready */\n (e: 'ready', event: CustomEvent): void;\n}>();\n\n// Template ref for the grid element\nconst gridRef = ref<DataGridElement<TRow> | null>(null);\n\n// Provide grid element to descendants (for useGrid composable)\nprovide(GRID_ELEMENT_KEY, gridRef);\n\n// Get type defaults and icons from providers\nconst typeDefaults = useGridTypeDefaults();\nconst iconOverrides = useGridIcons();\n\n// Feature prop names for creating plugins\nconst FEATURE_PROPS: FeatureName[] = [\n 'selection',\n 'editing',\n 'clipboard',\n 'contextMenu',\n 'multiSort',\n 'sorting',\n 'filtering',\n 'reorder',\n 'visibility',\n 'pinnedColumns',\n 'groupingColumns',\n 'columnVirtualization',\n 'rowReorder',\n 'groupingRows',\n 'pinnedRows',\n 'tree',\n 'masterDetail',\n 'responsive',\n 'undoRedo',\n 'export',\n 'print',\n 'pivot',\n 'serverSide',\n];\n\n/**\n * Create plugins from feature props.\n */\nfunction createFeaturePlugins(): BaseGridPlugin[] {\n const plugins: BaseGridPlugin[] = [];\n\n for (const feature of FEATURE_PROPS) {\n const propValue = props[feature as keyof typeof props];\n if (propValue !== undefined) {\n const plugin = createPluginFromFeature(feature, propValue);\n if (plugin) {\n plugins.push(plugin as BaseGridPlugin);\n }\n }\n }\n\n return plugins;\n}\n\n// Merged config with feature plugins\nconst mergedConfig = computed<GridConfig<TRow> | undefined>(() => {\n const baseConfig = props.gridConfig ?? {};\n const featurePlugins = createFeaturePlugins();\n const configPlugins = (baseConfig.plugins as BaseGridPlugin[]) ?? [];\n\n // Merge: feature plugins first, then config plugins\n const mergedPlugins = [...featurePlugins, ...configPlugins];\n\n // Apply type defaults if provided\n const typeDefaults$ = typeDefaults;\n\n // Apply icon overrides if provided\n const icons = iconOverrides ? { ...baseConfig.icons, ...iconOverrides } : baseConfig.icons;\n\n return {\n ...baseConfig,\n ...(props.columns ? { columns: props.columns } : {}),\n ...(mergedPlugins.length > 0 ? { plugins: mergedPlugins } : {}),\n ...(icons ? { icons } : {}),\n } as GridConfig<TRow>;\n});\n\n// Event handlers\nfunction handleCellCommit(event: Event) {\n emit('cell-commit', event as CustomEvent);\n}\n\nfunction handleRowCommit(event: Event) {\n emit('row-commit', event as CustomEvent);\n}\n\nfunction handleCellClick(event: Event) {\n emit('cell-click', event as CustomEvent);\n}\n\nfunction handleCellDblclick(event: Event) {\n emit('cell-dblclick', event as CustomEvent);\n}\n\nfunction handleSelectionChange(event: Event) {\n emit('selection-change', event as CustomEvent);\n}\n\nfunction handleRowToggle(event: Event) {\n emit('row-toggle', event as CustomEvent);\n}\n\nfunction handleSortChange(event: Event) {\n emit('sort-change', event as CustomEvent);\n}\n\nfunction handleReady(event: Event) {\n emit('ready', event as CustomEvent);\n}\n\n/**\n * Intercepts the element's `gridConfig` property so ALL writes\n * go through the adapter's processGridConfig first.\n *\n * This converts Vue component classes and VNode-returning functions\n * to DOM-returning functions before the grid core sees them.\n * Handles cases where `:grid-config` is bound directly to the\n * custom element (bypassing TbwGrid.vue).\n */\nfunction interceptElementGridConfig(grid: HTMLElement, adapter: GridAdapter): void {\n const proto = Object.getPrototypeOf(grid);\n const desc = Object.getOwnPropertyDescriptor(proto, 'gridConfig');\n if (!desc?.set || !desc?.get) return;\n\n const originalSet = desc.set;\n const originalGet = desc.get;\n\n // Instance-level override (does not affect the prototype or other grid elements)\n Object.defineProperty(grid, 'gridConfig', {\n get() {\n return originalGet.call(this);\n },\n set(value: VueGridConfig | undefined) {\n if (value && adapter) {\n // processGridConfig is idempotent: already-processed functions pass\n // through isVueComponent unchanged, so double-processing is safe.\n originalSet.call(this, adapter.processGridConfig(value));\n } else {\n originalSet.call(this, value);\n }\n },\n configurable: true,\n });\n}\n\n/**\n * Removes the instance-level gridConfig interceptor,\n * restoring the prototype's original getter/setter.\n */\nfunction removeGridConfigInterceptor(grid: HTMLElement): void {\n // Deleting the instance property restores the prototype accessor\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete (grid as any).gridConfig;\n}\n\n// Setup and cleanup\nonMounted(() => {\n const grid = gridRef.value as unknown as HTMLElement & DataGridElement<TRow>;\n if (!grid) return;\n\n // Attach the framework adapter to the grid element\n // This enables MasterDetailPlugin and ResponsivePlugin to use Vue-based renderers\n const adapter = ensureAdapterRegistered();\n (grid as any).__frameworkAdapter = adapter;\n\n // Pass type defaults to the adapter\n adapter.setTypeDefaults(typeDefaults ?? null);\n\n // Intercept the element's gridConfig setter so ALL writes\n // (including direct custom element bindings) go through processGridConfig.\n interceptElementGridConfig(grid, adapter);\n\n // Add event listeners\n grid.addEventListener('cell-commit', handleCellCommit);\n grid.addEventListener('row-commit', handleRowCommit);\n grid.addEventListener('cell-click', handleCellClick);\n grid.addEventListener('cell-dblclick', handleCellDblclick);\n grid.addEventListener('selection-change', handleSelectionChange);\n grid.addEventListener('row-toggle', handleRowToggle);\n grid.addEventListener('sort-change', handleSortChange);\n grid.addEventListener('ready', handleReady);\n\n // Set initial data\n if (props.rows.length > 0) {\n grid.rows = props.rows;\n }\n if (mergedConfig.value) {\n // Process through adapter before passing to grid\n grid.gridConfig = mergedConfig.value;\n }\n if (props.fitMode) {\n grid.fitMode = props.fitMode;\n }\n});\n\nonBeforeUnmount(() => {\n const grid = gridRef.value as unknown as HTMLElement & DataGridElement<TRow>;\n if (!grid) return;\n\n // Remove the gridConfig setter interceptor\n removeGridConfigInterceptor(grid);\n\n // Remove event listeners\n grid.removeEventListener('cell-commit', handleCellCommit);\n grid.removeEventListener('row-commit', handleRowCommit);\n grid.removeEventListener('cell-click', handleCellClick);\n grid.removeEventListener('cell-dblclick', handleCellDblclick);\n grid.removeEventListener('selection-change', handleSelectionChange);\n grid.removeEventListener('row-toggle', handleRowToggle);\n grid.removeEventListener('sort-change', handleSortChange);\n grid.removeEventListener('ready', handleReady);\n});\n\n// Watch for prop changes\nwatch(\n () => props.rows,\n (newRows) => {\n if (gridRef.value) {\n gridRef.value.rows = newRows;\n }\n },\n { deep: true },\n);\n\nwatch(\n mergedConfig,\n (newConfig) => {\n if (gridRef.value && newConfig) {\n gridRef.value.gridConfig = newConfig;\n }\n },\n { deep: true },\n);\n\nwatch(\n () => props.fitMode,\n (newFitMode) => {\n if (gridRef.value && newFitMode) {\n gridRef.value.fitMode = newFitMode;\n }\n },\n);\n\n// Watch for type defaults changes\nwatch(\n () => typeDefaults,\n (newTypeDefaults) => {\n const adapter = ensureAdapterRegistered();\n adapter.setTypeDefaults(newTypeDefaults ?? null);\n },\n { deep: true },\n);\n\n// Expose the grid element for programmatic access\ndefineExpose({\n /** The underlying grid element */\n gridElement: gridRef,\n /** Force a layout recalculation */\n forceLayout: () => gridRef.value?.forceLayout(),\n /** Get current grid configuration */\n getConfig: () => gridRef.value?.getConfig(),\n /** Wait for grid to be ready */\n ready: () => gridRef.value?.ready(),\n});\n</script>\n\n<template>\n <tbw-grid ref=\"gridRef\">\n <slot></slot>\n </tbw-grid>\n</template>\n","<script setup lang=\"ts\">\nimport type { CellRenderContext, ColumnEditorContext } from '@toolbox-web/grid';\nimport { h, onMounted, ref, type VNode } from 'vue';\nimport type { CellSlotProps, EditorSlotProps } from './slot-types';\nimport { registerColumnEditor, registerColumnRenderer } from './vue-grid-adapter';\n\n/**\n * Props for TbwGridColumn\n */\nconst props = defineProps<{\n /** Field path in the row object */\n field: string;\n /** Column header text */\n header?: string;\n /** Column width */\n width?: string | number;\n /** Minimum column width */\n minWidth?: string | number;\n /** Maximum column width */\n maxWidth?: string | number;\n /** Whether the column is sortable */\n sortable?: boolean;\n /** Whether the column is resizable */\n resizable?: boolean;\n /** Whether the column is editable */\n editable?: boolean;\n /** Data type for the column */\n type?: string;\n /** Column alignment */\n align?: 'left' | 'center' | 'right';\n /** Whether the column is hidden */\n hidden?: boolean;\n}>();\n\n// Define slots with proper typing and get the slots object\nconst slots = defineSlots<{\n /** Custom cell renderer slot */\n cell?: (props: CellSlotProps) => VNode[];\n /** Custom cell editor slot */\n editor?: (props: EditorSlotProps) => VNode[];\n}>();\n\n// Template ref for the column element\nconst columnRef = ref<HTMLElement | null>(null);\n\nonMounted(() => {\n const element = columnRef.value;\n if (!element) return;\n\n // Check if cell slot exists by trying to access it\n const hasCellSlot = !!slots.cell;\n const hasEditorSlot = !!slots.editor;\n\n // Register renderer if #cell slot is provided\n if (hasCellSlot) {\n registerColumnRenderer(element, (ctx: CellRenderContext<unknown, unknown>) => {\n const slotFn = slots.cell;\n if (!slotFn) return h('span');\n const slotContent = slotFn({\n value: ctx.value,\n row: ctx.row,\n column: ctx.column,\n });\n // Return the VNode array wrapped in a div\n return h('div', { style: 'display: contents' }, slotContent);\n });\n }\n\n // Register editor if #editor slot is provided\n if (hasEditorSlot) {\n registerColumnEditor(element, (ctx: ColumnEditorContext<unknown, unknown>) => {\n const slotFn = slots.editor;\n if (!slotFn) return h('span');\n const slotContent = slotFn({\n value: ctx.value,\n row: ctx.row,\n column: ctx.column,\n field: ctx.field,\n rowId: ctx.rowId ?? '',\n commit: ctx.commit,\n cancel: ctx.cancel,\n updateRow: ctx.updateRow,\n onValueChange: ctx.onValueChange,\n });\n return h('div', { style: 'display: contents' }, slotContent);\n });\n }\n});\n</script>\n\n<template>\n <tbw-grid-column\n ref=\"columnRef\"\n :field=\"field\"\n :header=\"header\"\n :width=\"width\"\n :min-width=\"minWidth\"\n :max-width=\"maxWidth\"\n :sortable=\"sortable\"\n :resizable=\"resizable\"\n :editable=\"editable\"\n :type=\"type\"\n :align=\"align\"\n :hidden=\"hidden\"\n >\n <!-- Hidden slot to capture slot definitions -->\n </tbw-grid-column>\n</template>\n","<script setup lang=\"ts\" generic=\"TRow = unknown\">\nimport { onMounted, ref, useSlots, type VNode } from 'vue';\nimport { detailRegistry, type DetailPanelContext } from './detail-panel-registry';\n\n/**\n * Props for TbwGridDetailPanel\n */\nconst props = withDefaults(\n defineProps<{\n /**\n * Whether to show the expand/collapse column.\n * @default true\n */\n showExpandColumn?: boolean;\n\n /**\n * Animation style for expand/collapse.\n * - 'slide': Smooth height animation (default)\n * - 'fade': Opacity transition\n * - false: No animation\n * @default 'slide'\n */\n animation?: 'slide' | 'fade' | false;\n }>(),\n {\n showExpandColumn: true,\n animation: 'slide',\n },\n);\n\n// Define slots with proper typing\ndefineSlots<{\n /** Detail panel content slot */\n default?: (props: DetailPanelContext<TRow>) => VNode[];\n}>();\n\n// Template ref for the detail element\nconst detailRef = ref<HTMLElement | null>(null);\nconst slots = useSlots();\n\nonMounted(() => {\n const element = detailRef.value;\n if (!element || !slots.default) return;\n\n // Register the slot renderer\n detailRegistry.set(element, (ctx: DetailPanelContext<unknown>) => {\n return slots.default?.(ctx as DetailPanelContext<TRow>);\n });\n});\n</script>\n\n<template>\n <tbw-grid-detail ref=\"detailRef\" :show-expand-column=\"showExpandColumn\" :animation=\"animation\" />\n</template>\n","<script setup lang=\"ts\" generic=\"TRow = unknown\">\nimport { onMounted, ref, useSlots, type VNode } from 'vue';\nimport { cardRegistry, type ResponsiveCardContext } from './responsive-card-registry';\n\n/**\n * Props for TbwGridResponsiveCard\n */\nconst props = defineProps<{\n // Currently no additional props needed\n}>();\n\n// Define slots with proper typing\ndefineSlots<{\n /** Card content slot */\n default?: (props: ResponsiveCardContext<TRow>) => VNode[];\n}>();\n\n// Template ref for the card element\nconst cardRef = ref<HTMLElement | null>(null);\nconst slots = useSlots();\n\nonMounted(() => {\n const element = cardRef.value;\n if (!element || !slots.default) return;\n\n // Register the slot renderer\n cardRegistry.set(element, (ctx: ResponsiveCardContext<unknown>) => {\n return slots.default?.(ctx as ResponsiveCardContext<TRow>);\n });\n});\n</script>\n\n<template>\n <tbw-grid-responsive-card ref=\"cardRef\" />\n</template>\n","<script setup lang=\"ts\">\nimport { type VNode } from 'vue';\n\n/**\n * Props for TbwGridToolButtons\n */\ndefineProps<{\n // Currently no additional props needed\n}>();\n\n// Define slots with proper typing\ndefineSlots<{\n /** Tool button content slot */\n default?: () => VNode[];\n}>();\n</script>\n\n<template>\n <tbw-grid-tool-buttons>\n <slot />\n </tbw-grid-tool-buttons>\n</template>\n","/**\n * Registry for tool panel renderers.\n * @internal\n */\nimport type { VNode } from 'vue';\n\n/**\n * Context object passed to the tool panel slot.\n */\nexport interface ToolPanelContext {\n /** The grid element */\n gridElement: HTMLElement;\n}\n\n/**\n * Registry for tool panel renderers (per element)\n */\nexport const toolPanelRegistry = new WeakMap<HTMLElement, (ctx: ToolPanelContext) => VNode[] | undefined>();\n\n/**\n * Get the tool panel renderer for an element.\n * @internal\n */\nexport function getToolPanelRenderer(\n panelElement: HTMLElement,\n): ((ctx: ToolPanelContext) => VNode[] | undefined) | undefined {\n return toolPanelRegistry.get(panelElement);\n}\n","<script setup lang=\"ts\">\nimport { onMounted, ref, useSlots, type VNode } from 'vue';\nimport { toolPanelRegistry, type ToolPanelContext } from './tool-panel-registry';\n\n/**\n * Props for TbwGridToolPanel\n */\nconst props = withDefaults(\n defineProps<{\n /**\n * Unique identifier for this tool panel.\n */\n id: string;\n\n /**\n * Display label for the panel tab/button.\n */\n label: string;\n\n /**\n * Icon for the panel tab (string or SVG).\n */\n icon?: string;\n\n /**\n * Position of the panel.\n * @default 'right'\n */\n position?: 'left' | 'right';\n\n /**\n * Width of the panel when open.\n * @default '250px'\n */\n width?: string;\n }>(),\n {\n position: 'right',\n width: '250px',\n },\n);\n\n// Define slots with proper typing\ndefineSlots<{\n /** Tool panel content slot */\n default?: (props: ToolPanelContext) => VNode[];\n}>();\n\n// Template ref for the tool panel element\nconst panelRef = ref<HTMLElement | null>(null);\nconst slots = useSlots();\n\nonMounted(() => {\n const element = panelRef.value;\n if (!element || !slots.default) return;\n\n // Register the slot renderer\n toolPanelRegistry.set(element, (ctx: ToolPanelContext) => {\n return slots.default?.(ctx);\n });\n});\n</script>\n\n<template>\n <tbw-grid-tool-panel ref=\"panelRef\" :id=\"id\" :label=\"label\" :icon=\"icon\" :position=\"position\" :width=\"width\" />\n</template>\n","import type { DataGridElement } from '@toolbox-web/grid';\nimport { inject, onBeforeUnmount, onMounted, ref, type Ref } from 'vue';\nimport { GRID_ELEMENT_KEY } from './use-grid';\n\n/**\n * Grid event types and their payload types.\n */\nexport interface GridEventMap {\n 'cell-click': { value: unknown; row: unknown; column: unknown; rowIndex: number; colIndex: number };\n 'cell-dblclick': { value: unknown; row: unknown; column: unknown; rowIndex: number; colIndex: number };\n 'cell-commit': { value: unknown; oldValue: unknown; row: unknown; column: unknown };\n 'row-commit': { row: unknown; changes: Record<string, unknown> };\n 'selection-change': { selectedRows: unknown[]; selectedCells: unknown[] };\n 'sort-change': { field: string; direction: 'asc' | 'desc' | null };\n 'row-toggle': { row: unknown; expanded: boolean };\n ready: undefined;\n}\n\n/**\n * Composable for subscribing to grid events with automatic cleanup.\n *\n * @param eventName - The name of the grid event to listen for\n * @param handler - The event handler function\n * @param gridElement - Optional grid element ref (uses injected if not provided)\n *\n * @example\n * ```vue\n * <script setup>\n * import { useGridEvent } from '@toolbox-web/grid-vue';\n *\n * useGridEvent('cell-commit', (event) => {\n * console.log('Cell committed:', event.detail);\n * });\n *\n * useGridEvent('selection-change', (event) => {\n * console.log('Selection changed:', event.detail);\n * });\n * </script>\n * ```\n */\nexport function useGridEvent<K extends keyof GridEventMap>(\n eventName: K,\n handler: (event: CustomEvent<GridEventMap[K]>) => void,\n gridElement?: Ref<DataGridElement | null>,\n): void {\n const grid = gridElement ?? inject(GRID_ELEMENT_KEY, ref(null));\n let cleanup: (() => void) | null = null;\n\n onMounted(() => {\n const element = grid.value as unknown as HTMLElement | null;\n if (!element) return;\n\n const eventHandler = handler as EventListener;\n element.addEventListener(eventName, eventHandler);\n cleanup = () => element.removeEventListener(eventName, eventHandler);\n });\n\n onBeforeUnmount(() => {\n cleanup?.();\n });\n}\n","/**\n * Combined provider for type defaults and icons.\n *\n * Convenience component that combines GridTypeProvider and GridIconProvider.\n */\nimport type { GridIcons } from '@toolbox-web/grid';\nimport { defineComponent, h, type PropType, type VNode } from 'vue';\nimport { GridIconProvider } from './grid-icon-registry';\nimport { GridTypeProvider, type TypeDefaultsMap } from './grid-type-registry';\n\n/**\n * Combined provider for type defaults and icons.\n *\n * @example\n * ```vue\n * <script setup>\n * import { GridProvider, type TypeDefaultsMap } from '@toolbox-web/grid-vue';\n * import { h } from 'vue';\n *\n * const typeDefaults: TypeDefaultsMap = {\n * country: { renderer: (ctx) => h('span', ctx.value) },\n * };\n *\n * const icons = { sortAsc: '↑', sortDesc: '↓' };\n * </script>\n *\n * <template>\n * <GridProvider :typeDefaults=\"typeDefaults\" :icons=\"icons\">\n * <App />\n * </GridProvider>\n * </template>\n * ```\n */\nexport const GridProvider = defineComponent({\n name: 'GridProvider',\n props: {\n /**\n * Type defaults to provide to all descendant grids.\n */\n typeDefaults: {\n type: Object as PropType<TypeDefaultsMap>,\n default: undefined,\n },\n /**\n * Icon overrides to provide to all descendant grids.\n */\n icons: {\n type: Object as PropType<Partial<GridIcons>>,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n return () => {\n let content: VNode[] | VNode | undefined = slots.default?.();\n\n // Wrap with type provider if typeDefaults is provided\n if (props.typeDefaults) {\n content = h(GridTypeProvider, { defaults: props.typeDefaults }, () => content);\n }\n\n // Wrap with icon provider if icons is provided\n if (props.icons) {\n content = h(GridIconProvider, { icons: props.icons }, () => content);\n }\n\n return content;\n };\n },\n});\n\nexport type GridProviderProps = InstanceType<typeof GridProvider>['$props'];\n"],"names":["GRID_ICONS","useGridIcons","inject","GridIconProvider","defineComponent","props","slots","provide","GRID_TYPE_DEFAULTS","useGridTypeDefaults","useTypeDefault","typeName","GridTypeProvider","detailRegistry","cardRegistry","columnRegistries","fieldRegistries","registerColumnRenderer","element","renderer","field","registry","fieldRegistry","registerColumnEditor","editor","getColumnRenderer","getColumnEditor","isVueComponent","value","obj","fnString","fn","isVNodeRenderFunction","PROCESSED_MARKER","GridAdapter","config","result","col","typeDefaults","processed","type","processedConfig","column","wrapped","component","cellCache","ctx","cellEl","cached","container","currentCtx","comp","app","createApp","createVNode","newCtx","renderFn","defaults","hasRenderer","hasEditor","editorFn","detailElement","gridElement","detailEl","row","rowIndex","vnodes","cardElement","cardEl","vueDefault","typeDefault","params","wrapper","VueGridAdapter","adapterRegistered","globalAdapter","ensureAdapterRegistered","GridElement","__props","emit","__emit","gridRef","ref","GRID_ELEMENT_KEY","iconOverrides","FEATURE_PROPS","createFeaturePlugins","plugins","feature","propValue","plugin","createPluginFromFeature","mergedConfig","computed","baseConfig","featurePlugins","configPlugins","mergedPlugins","icons","handleCellCommit","event","handleRowCommit","handleCellClick","handleCellDblclick","handleSelectionChange","handleRowToggle","handleSortChange","handleReady","interceptElementGridConfig","grid","adapter","proto","desc","originalSet","originalGet","removeGridConfigInterceptor","onMounted","onBeforeUnmount","watch","newRows","newConfig","newFitMode","newTypeDefaults","__expose","_createElementBlock","_renderSlot","_ctx","_useSlots","columnRef","hasCellSlot","hasEditorSlot","slotFn","h","slotContent","detailRef","useSlots","cardRef","toolPanelRegistry","panelRef","useGridEvent","eventName","handler","cleanup","eventHandler","GridProvider","content"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../libs/grid-vue/src/lib/grid-icon-registry.ts","../../../libs/grid-vue/src/lib/grid-type-registry.ts","../../../libs/grid-vue/src/lib/detail-panel-registry.ts","../../../libs/grid-vue/src/lib/responsive-card-registry.ts","../../../libs/grid-vue/src/lib/vue-grid-adapter.ts","../../../libs/grid-vue/src/lib/TbwGrid.vue","../../../libs/grid-vue/src/lib/TbwGridColumn.vue","../../../libs/grid-vue/src/lib/TbwGridDetailPanel.vue","../../../libs/grid-vue/src/lib/TbwGridResponsiveCard.vue","../../../libs/grid-vue/src/lib/TbwGridToolButtons.vue","../../../libs/grid-vue/src/lib/tool-panel-registry.ts","../../../libs/grid-vue/src/lib/TbwGridToolPanel.vue","../../../libs/grid-vue/src/lib/use-grid-event.ts","../../../libs/grid-vue/src/lib/grid-provider.ts"],"sourcesContent":["/**\n * Icon registry for Vue applications.\n *\n * Provides application-wide icon overrides that all grids inherit\n * automatically via Vue's provide/inject.\n */\nimport type { GridIcons } from '@toolbox-web/grid';\nimport { defineComponent, inject, provide, type InjectionKey, type PropType } from 'vue';\n\n/**\n * Injection key for grid icons.\n */\nexport const GRID_ICONS: InjectionKey<Partial<GridIcons>> = Symbol('grid-icons');\n\n/**\n * Composable to get the current icon overrides from the nearest provider.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useGridIcons } from '@toolbox-web/grid-vue';\n *\n * const icons = useGridIcons();\n * </script>\n * ```\n */\nexport function useGridIcons(): Partial<GridIcons> | undefined {\n return inject(GRID_ICONS, undefined);\n}\n\n/**\n * Provides application-wide icon overrides for all descendant grids.\n *\n * Wrap your application (or part of it) with this provider to customize\n * icons used by all TbwGrid components.\n *\n * @example\n * ```vue\n * <script setup>\n * import { GridIconProvider } from '@toolbox-web/grid-vue';\n *\n * const icons = {\n * sortAsc: '↑',\n * sortDesc: '↓',\n * expand: '+',\n * collapse: '−',\n * };\n * </script>\n *\n * <template>\n * <GridIconProvider :icons=\"icons\">\n * <App />\n * </GridIconProvider>\n * </template>\n * ```\n */\nexport const GridIconProvider = defineComponent({\n name: 'GridIconProvider',\n props: {\n /**\n * Icon overrides to provide to all descendant grids.\n */\n icons: {\n type: Object as PropType<Partial<GridIcons>>,\n required: true,\n },\n },\n setup(props, { slots }) {\n // Provide icons to descendants\n provide(GRID_ICONS, props.icons);\n\n // Render children\n return () => slots.default?.();\n },\n});\n\nexport type GridIconProviderProps = InstanceType<typeof GridIconProvider>['$props'];\n","/**\n * Type-level default registry for Vue applications.\n *\n * Provides application-wide type defaults for renderers and editors\n * that all grids inherit automatically via Vue's provide/inject.\n */\nimport type { CellRenderContext, ColumnEditorContext } from '@toolbox-web/grid';\nimport type { FilterPanelParams } from '@toolbox-web/grid/plugins/filtering';\nimport { defineComponent, inject, provide, type InjectionKey, type PropType, type VNode } from 'vue';\n\n// #region TypeDefault Interface\n/**\n * Type default configuration for Vue applications.\n *\n * Defines default renderer, editor, and editorParams for a data type\n * using Vue render functions.\n *\n * @example\n * ```ts\n * import type { TypeDefault } from '@toolbox-web/grid-vue';\n * import CountryFlag from './CountryFlag.vue';\n * import CountrySelect from './CountrySelect.vue';\n *\n * const countryDefault: TypeDefault<Employee, string> = {\n * renderer: (ctx) => h(CountryFlag, { code: ctx.value }),\n * editor: (ctx) => h(CountrySelect, {\n * modelValue: ctx.value,\n * 'onUpdate:modelValue': ctx.commit,\n * }),\n * };\n * ```\n */\nexport interface TypeDefault<TRow = unknown, TValue = unknown> {\n /** Vue render function for rendering cells of this type */\n renderer?: (ctx: CellRenderContext<TRow, TValue>) => VNode;\n /** Vue render function for editing cells of this type */\n editor?: (ctx: ColumnEditorContext<TRow, TValue>) => VNode;\n /** Default editorParams for this type */\n editorParams?: Record<string, unknown>;\n /**\n * Vue render function for custom filter panels for this type.\n *\n * Unlike the core imperative API `(container, params) => void`, this accepts\n * a Vue render function that receives only the params and returns a VNode.\n * The bridge handles mounting and appending to the container automatically.\n *\n * @example\n * ```ts\n * import { h } from 'vue';\n * import CustomFilter from './CustomFilter.vue';\n *\n * const typeDefault: TypeDefault = {\n * filterPanelRenderer: (params) => h(CustomFilter, {\n * field: params.field,\n * uniqueValues: params.uniqueValues,\n * onApply: (values: Set<unknown>) => params.applySetFilter(values),\n * }),\n * };\n * ```\n */\n filterPanelRenderer?: (params: FilterPanelParams) => VNode;\n}\n\n/**\n * @deprecated Use `TypeDefault` instead.\n * @see {@link TypeDefault}\n */\nexport type VueTypeDefault<TRow = unknown, TValue = unknown> = TypeDefault<TRow, TValue>;\n// #endregion\n\n/**\n * Type defaults registry - a map of type names to their defaults.\n */\nexport type TypeDefaultsMap = Record<string, TypeDefault>;\n\n/**\n * Injection key for type defaults.\n */\nexport const GRID_TYPE_DEFAULTS: InjectionKey<TypeDefaultsMap> = Symbol('grid-type-defaults');\n\n/**\n * Composable to get the current type defaults from the nearest provider.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useGridTypeDefaults } from '@toolbox-web/grid-vue';\n *\n * const typeDefaults = useGridTypeDefaults();\n * </script>\n * ```\n */\nexport function useGridTypeDefaults(): TypeDefaultsMap | undefined {\n return inject(GRID_TYPE_DEFAULTS, undefined);\n}\n\n/**\n * Composable to get a specific type's default configuration.\n *\n * @param typeName - The type name to look up\n *\n * @example\n * ```vue\n * <script setup>\n * import { useTypeDefault } from '@toolbox-web/grid-vue';\n *\n * const countryDefault = useTypeDefault('country');\n * </script>\n * ```\n */\nexport function useTypeDefault<TRow = unknown, TValue = unknown>(\n typeName: string,\n): TypeDefault<TRow, TValue> | undefined {\n const defaults = useGridTypeDefaults();\n return defaults?.[typeName] as TypeDefault<TRow, TValue> | undefined;\n}\n\n/**\n * Provides application-wide type defaults for all descendant grids.\n *\n * Wrap your application (or part of it) with this provider to make\n * type-level renderers and editors available to all TbwGrid components.\n *\n * @example\n * ```vue\n * <script setup>\n * import { GridTypeProvider, type TypeDefaultsMap } from '@toolbox-web/grid-vue';\n * import { h } from 'vue';\n * import CountryBadge from './CountryBadge.vue';\n *\n * const typeDefaults: TypeDefaultsMap = {\n * country: {\n * renderer: (ctx) => h(CountryBadge, { code: ctx.value }),\n * },\n * };\n * </script>\n *\n * <template>\n * <GridTypeProvider :defaults=\"typeDefaults\">\n * <App />\n * </GridTypeProvider>\n * </template>\n * ```\n */\nexport const GridTypeProvider = defineComponent({\n name: 'GridTypeProvider',\n props: {\n /**\n * Type defaults to provide to all descendant grids.\n */\n defaults: {\n type: Object as PropType<TypeDefaultsMap>,\n required: true,\n },\n },\n setup(props, { slots }) {\n // Provide type defaults to descendants\n provide(GRID_TYPE_DEFAULTS, props.defaults);\n\n // Render children\n return () => slots.default?.();\n },\n});\n\nexport type GridTypeProviderProps = InstanceType<typeof GridTypeProvider>['$props'];\n","/**\n * Registry for detail panel renderers.\n * @internal\n */\nimport type { VNode } from 'vue';\n\n/**\n * Context object passed to the detail panel slot.\n */\nexport interface DetailPanelContext<T = unknown> {\n /** The row data for this detail panel */\n row: T;\n /** The row index */\n rowIndex: number;\n}\n\n/**\n * Registry for detail renderers (per grid element)\n */\nexport const detailRegistry = new WeakMap<HTMLElement, (ctx: DetailPanelContext<unknown>) => VNode[] | undefined>();\n\n/**\n * Get the detail renderer for a grid element.\n * @internal\n */\nexport function getDetailRenderer(\n gridElement: HTMLElement,\n): ((ctx: DetailPanelContext<unknown>) => VNode[] | undefined) | undefined {\n const detailElement = gridElement.querySelector('tbw-grid-detail') as HTMLElement | null;\n if (detailElement) {\n return detailRegistry.get(detailElement);\n }\n return undefined;\n}\n","/**\n * Registry for responsive card renderers.\n * @internal\n */\nimport type { VNode } from 'vue';\n\n/**\n * Context object passed to the responsive card slot.\n */\nexport interface ResponsiveCardContext<T = unknown> {\n /** The row data */\n row: T;\n /** The row index */\n rowIndex: number;\n}\n\n/**\n * Registry for responsive card renderers (per element)\n */\nexport const cardRegistry = new WeakMap<HTMLElement, (ctx: ResponsiveCardContext<unknown>) => VNode[] | undefined>();\n\n/**\n * Get the responsive card renderer for a grid element.\n * @internal\n */\nexport function getResponsiveCardRenderer(\n gridElement: HTMLElement,\n): ((ctx: ResponsiveCardContext<unknown>) => VNode[] | undefined) | undefined {\n const cardElement = gridElement.querySelector('tbw-grid-responsive-card') as HTMLElement | null;\n if (cardElement) {\n return cardRegistry.get(cardElement);\n }\n return undefined;\n}\n","import type {\n ColumnConfig as BaseColumnConfig,\n GridConfig as BaseGridConfig,\n TypeDefault as BaseTypeDefault,\n CellRenderContext,\n ColumnEditorContext,\n ColumnEditorSpec,\n ColumnViewRenderer,\n FrameworkAdapter,\n} from '@toolbox-web/grid';\nimport type { FilterPanelParams } from '@toolbox-web/grid/plugins/filtering';\nimport { createApp, createVNode, type App, type Component, type VNode } from 'vue';\nimport { detailRegistry, type DetailPanelContext } from './detail-panel-registry';\nimport type { TypeDefault, TypeDefaultsMap } from './grid-type-registry';\nimport { cardRegistry, type ResponsiveCardContext } from './responsive-card-registry';\nimport type { ColumnConfig, GridConfig } from './vue-column-config';\nexport type { GridConfig };\n\n/**\n * Registry mapping column elements to their Vue render functions.\n * Each column element stores its renderer/editor functions here.\n */\ninterface ColumnRegistry {\n renderer?: (ctx: CellRenderContext<unknown, unknown>) => VNode;\n editor?: (ctx: ColumnEditorContext<unknown, unknown>) => VNode;\n}\n\nconst columnRegistries = new WeakMap<HTMLElement, ColumnRegistry>();\n\n// Secondary registry by field name to handle Vue component re-creation\nconst fieldRegistries = new Map<string, ColumnRegistry>();\n\n/**\n * Register a Vue cell renderer for a column element.\n * Called by TbwGridColumn when it has a #cell slot.\n */\nexport function registerColumnRenderer(\n element: HTMLElement,\n renderer: (ctx: CellRenderContext<unknown, unknown>) => VNode,\n): void {\n const field = element.getAttribute('field');\n\n const registry = columnRegistries.get(element) ?? {};\n registry.renderer = renderer;\n columnRegistries.set(element, registry);\n\n // Also register by field name for fallback lookup\n if (field) {\n const fieldRegistry = fieldRegistries.get(field) ?? {};\n fieldRegistry.renderer = renderer;\n fieldRegistries.set(field, fieldRegistry);\n }\n}\n\n/**\n * Register a Vue cell editor for a column element.\n * Called by TbwGridColumn when it has an #editor slot.\n */\nexport function registerColumnEditor(\n element: HTMLElement,\n editor: (ctx: ColumnEditorContext<unknown, unknown>) => VNode,\n): void {\n const field = element.getAttribute('field');\n const registry = columnRegistries.get(element) ?? {};\n registry.editor = editor;\n columnRegistries.set(element, registry);\n\n // Also register by field name for fallback lookup\n if (field) {\n const fieldRegistry = fieldRegistries.get(field) ?? {};\n fieldRegistry.editor = editor;\n fieldRegistries.set(field, fieldRegistry);\n }\n}\n\n/**\n * Get the renderer registered for a column element.\n * Falls back to field-based lookup if WeakMap lookup fails.\n */\nexport function getColumnRenderer(\n element: HTMLElement,\n): ((ctx: CellRenderContext<unknown, unknown>) => VNode) | undefined {\n let renderer = columnRegistries.get(element)?.renderer;\n\n // Fallback to field-based lookup for Vue component re-creation scenarios\n if (!renderer) {\n const field = element.getAttribute('field');\n if (field) {\n renderer = fieldRegistries.get(field)?.renderer;\n }\n }\n\n return renderer;\n}\n\n/**\n * Get the editor registered for a column element.\n * Falls back to field-based lookup if WeakMap lookup fails.\n */\nexport function getColumnEditor(\n element: HTMLElement,\n): ((ctx: ColumnEditorContext<unknown, unknown>) => VNode) | undefined {\n let editor = columnRegistries.get(element)?.editor;\n\n // Fallback to field-based lookup for Vue component re-creation scenarios\n if (!editor) {\n const field = element.getAttribute('field');\n if (field) {\n editor = fieldRegistries.get(field)?.editor;\n }\n }\n\n return editor;\n}\n\n/**\n * Get all registered field names.\n * @internal - for testing only\n */\nexport function getRegisteredFields(): string[] {\n return Array.from(fieldRegistries.keys());\n}\n\n/**\n * Clear the field registries.\n * @internal - for testing only\n */\nexport function clearFieldRegistries(): void {\n fieldRegistries.clear();\n}\n\n// #region Vue Component Detection\n\n/**\n * Checks if a value is a Vue component (SFC or defineComponent result).\n *\n * Vue components are identified by:\n * - Having `__name` (SFC compiled marker)\n * - Having `setup` function (Composition API component)\n * - Having `render` function (Options API component)\n * - Being an ES6 class (class-based component)\n *\n * Regular functions `(ctx) => HTMLElement` that are already processed\n * will not match these checks, making this idempotent.\n */\nexport function isVueComponent(value: unknown): value is Component {\n if (value == null) return false;\n\n // Already a DOM-returning function (processed) — skip\n if (typeof value === 'function' && value.prototype === undefined) {\n // Plain arrow/function — could be a VNode-returning render fn OR\n // an already-processed DOM-returning fn. We can't distinguish at runtime,\n // so we check if it looks like a Vue component (has component markers).\n // Plain functions without component markers are treated as VNode-returning.\n return false;\n }\n\n if (typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n // SFC compiled marker\n if ('__name' in obj) return true;\n // Composition API\n if (typeof obj['setup'] === 'function') return true;\n // Options API\n if (typeof obj['render'] === 'function') return true;\n }\n\n if (typeof value === 'function') {\n // ES6 class-based component\n const fnString = Function.prototype.toString.call(value);\n if (fnString.startsWith('class ') || fnString.startsWith('class{')) return true;\n\n // defineComponent returns a function with component markers\n const fn = value as unknown as Record<string, unknown>;\n if ('__name' in fn || typeof fn['setup'] === 'function') return true;\n }\n\n return false;\n}\n\n/**\n * Checks if a value is a VNode-returning render function.\n * These are plain functions (not component objects) that return VNodes.\n * They need wrapping to produce HTMLElements for the grid core.\n */\nfunction isVNodeRenderFunction(value: unknown): value is (...args: unknown[]) => VNode {\n return typeof value === 'function' && !isVueComponent(value);\n}\n\n/**\n * Symbol used to mark renderer/editor functions that have already been\n * processed by the adapter (i.e., wrapped from VNode/Component → DOM).\n * Prevents double-wrapping when `processGridConfig` is called multiple times.\n */\nconst PROCESSED_MARKER = Symbol.for('tbw:vue-processed');\n\n// #endregion\n\n/**\n * Tracks mounted Vue apps for cleanup.\n */\ninterface MountedView {\n app: App;\n container: HTMLElement;\n}\n\n/**\n * Cache for cell containers and their Vue apps.\n */\ninterface CellAppCache {\n app: App;\n container: HTMLElement;\n update: (ctx: CellRenderContext<unknown, unknown>) => void;\n}\n\n/**\n * Framework adapter that enables Vue 3 component integration\n * with the grid's light DOM configuration API.\n *\n * ## Usage\n *\n * The adapter is automatically registered when using the TbwGrid component.\n * For advanced use cases, you can manually register:\n *\n * ```ts\n * import { GridElement } from '@toolbox-web/grid';\n * import { GridAdapter } from '@toolbox-web/grid-vue';\n *\n * // One-time registration\n * GridElement.registerAdapter(new GridAdapter());\n * ```\n *\n * ## Declarative usage with TbwGrid:\n *\n * ```vue\n * <TbwGrid :rows=\"data\" :grid-config=\"config\">\n * <TbwGridColumn field=\"status\">\n * <template #cell=\"{ value, row }\">\n * <StatusBadge :value=\"value\" />\n * </template>\n * </TbwGridColumn>\n * </TbwGrid>\n * ```\n */\nexport class GridAdapter implements FrameworkAdapter {\n private mountedViews: MountedView[] = [];\n /** Editor-specific views tracked separately for per-cell cleanup via releaseCell. */\n private editorViews: MountedView[] = [];\n private typeDefaults: TypeDefaultsMap | null = null;\n\n // #region Config Processing\n\n /**\n * Processes a Vue grid configuration, converting Vue component references\n * and VNode-returning render functions to DOM-returning functions.\n *\n * This is idempotent — already-processed configs pass through safely.\n *\n * @example\n * ```ts\n * import { GridAdapter, type GridConfig } from '@toolbox-web/grid-vue';\n * import StatusBadge from './StatusBadge.vue';\n *\n * const config: GridConfig<Employee> = {\n * columns: [\n * { field: 'status', renderer: StatusBadge },\n * ],\n * };\n *\n * const adapter = new GridAdapter();\n * const processedConfig = adapter.processGridConfig(config);\n * ```\n *\n * @param config - Vue grid config with possible component/VNode references\n * @returns Processed config with DOM-returning functions\n */\n processGridConfig<TRow = unknown>(config: GridConfig<TRow>): BaseGridConfig<TRow> {\n const result = { ...config } as BaseGridConfig<TRow>;\n\n // Process columns\n if (config.columns) {\n result.columns = config.columns.map((col) => this.processColumn(col));\n }\n\n // Process typeDefaults\n if (config.typeDefaults) {\n result.typeDefaults = this.processTypeDefaults(config.typeDefaults as Record<string, TypeDefault>) as Record<\n string,\n BaseTypeDefault<TRow>\n >;\n }\n\n return result;\n }\n\n /**\n * Processes typeDefaults, converting Vue component/VNode references\n * to DOM-returning functions.\n *\n * @param typeDefaults - Vue type defaults with possible component references\n * @returns Processed TypeDefault record\n */\n processTypeDefaults<TRow = unknown>(\n typeDefaults: Record<string, TypeDefault<TRow>>,\n ): Record<string, BaseTypeDefault<TRow>> {\n const processed: Record<string, BaseTypeDefault<TRow>> = {};\n\n for (const [type, config] of Object.entries(typeDefaults)) {\n const processedConfig: BaseTypeDefault<TRow> = {\n editorParams: config.editorParams,\n };\n\n if (config.renderer) {\n if (isVueComponent(config.renderer)) {\n processedConfig.renderer = this.createConfigComponentRenderer(config.renderer as Component);\n } else if (isVNodeRenderFunction(config.renderer)) {\n processedConfig.renderer = this.createTypeRenderer(\n config.renderer as (ctx: CellRenderContext<TRow>) => VNode,\n );\n }\n }\n\n if (config.editor) {\n if (isVueComponent(config.editor)) {\n processedConfig.editor = this.createConfigComponentEditor(\n config.editor as Component,\n ) as BaseTypeDefault['editor'];\n } else if (isVNodeRenderFunction(config.editor)) {\n processedConfig.editor = this.createTypeEditor(\n config.editor as (ctx: ColumnEditorContext<TRow>) => VNode,\n ) as BaseTypeDefault['editor'];\n }\n }\n\n if (config.filterPanelRenderer) {\n processedConfig.filterPanelRenderer = this.createFilterPanelRenderer(config.filterPanelRenderer);\n }\n\n processed[type] = processedConfig;\n }\n\n return processed;\n }\n\n /**\n * Processes a single column configuration, converting Vue component references\n * and VNode-returning render functions to DOM-returning functions.\n *\n * @param column - Vue column config\n * @returns Processed ColumnConfig with DOM-returning functions\n */\n processColumn<TRow = unknown>(column: ColumnConfig<TRow>): BaseColumnConfig<TRow> {\n const processed = { ...column } as BaseColumnConfig<TRow>;\n\n if (column.renderer && !(column.renderer as unknown as Record<symbol, unknown>)[PROCESSED_MARKER]) {\n if (isVueComponent(column.renderer)) {\n const wrapped = this.createConfigComponentRenderer(column.renderer as Component);\n (wrapped as unknown as Record<symbol, unknown>)[PROCESSED_MARKER] = true;\n processed.renderer = wrapped as BaseColumnConfig<TRow>['renderer'];\n } else if (isVNodeRenderFunction(column.renderer)) {\n const wrapped = this.createConfigVNodeRenderer(column.renderer as (ctx: CellRenderContext<TRow>) => VNode);\n (wrapped as unknown as Record<symbol, unknown>)[PROCESSED_MARKER] = true;\n processed.renderer = wrapped as BaseColumnConfig<TRow>['renderer'];\n }\n }\n\n if (column.editor && !(column.editor as unknown as Record<symbol, unknown>)[PROCESSED_MARKER]) {\n if (isVueComponent(column.editor)) {\n const wrapped = this.createConfigComponentEditor(column.editor as Component);\n (wrapped as unknown as Record<symbol, unknown>)[PROCESSED_MARKER] = true;\n processed.editor = wrapped as BaseColumnConfig<TRow>['editor'];\n } else if (isVNodeRenderFunction(column.editor)) {\n const wrapped = this.createConfigVNodeEditor(column.editor as (ctx: ColumnEditorContext<TRow>) => VNode);\n (wrapped as unknown as Record<symbol, unknown>)[PROCESSED_MARKER] = true;\n processed.editor = wrapped as BaseColumnConfig<TRow>['editor'];\n }\n }\n\n return processed;\n }\n\n /**\n * Creates a DOM-returning renderer from a Vue component class.\n * Used for config-based renderers (not slot-based).\n * @internal\n */\n private createConfigComponentRenderer<TRow = unknown, TValue = unknown>(\n component: Component,\n ): ColumnViewRenderer<TRow, TValue> {\n const cellCache = new WeakMap<HTMLElement, CellAppCache>();\n\n return (ctx: CellRenderContext<TRow, TValue>) => {\n const cellEl = (ctx as any).cellEl as HTMLElement | undefined;\n\n if (cellEl) {\n const cached = cellCache.get(cellEl);\n if (cached) {\n cached.update(ctx as CellRenderContext<unknown, unknown>);\n return cached.container;\n }\n\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n let currentCtx = ctx as CellRenderContext<unknown, unknown>;\n const comp = component;\n\n const app = createApp({\n render() {\n return createVNode(comp, { ...currentCtx });\n },\n });\n\n app.mount(container);\n\n cellCache.set(cellEl, {\n app,\n container,\n update: (newCtx) => {\n currentCtx = newCtx;\n app._instance?.update();\n },\n });\n\n return container;\n }\n\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n const comp = component;\n const app = createApp({\n render() {\n return createVNode(comp, { ...ctx });\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates a DOM-returning renderer from a VNode-returning render function.\n * Used for config-based renderers (not slot-based).\n * @internal\n */\n private createConfigVNodeRenderer<TRow = unknown, TValue = unknown>(\n renderFn: (ctx: CellRenderContext<TRow, TValue>) => VNode,\n ): ColumnViewRenderer<TRow, TValue> {\n const cellCache = new WeakMap<HTMLElement, CellAppCache>();\n\n return (ctx: CellRenderContext<TRow, TValue>) => {\n const cellEl = (ctx as any).cellEl as HTMLElement | undefined;\n\n if (cellEl) {\n const cached = cellCache.get(cellEl);\n if (cached) {\n cached.update(ctx as CellRenderContext<unknown, unknown>);\n return cached.container;\n }\n\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n let currentCtx = ctx as CellRenderContext<unknown, unknown>;\n\n const app = createApp({\n render() {\n return renderFn(currentCtx as CellRenderContext<TRow, TValue>);\n },\n });\n\n app.mount(container);\n\n cellCache.set(cellEl, {\n app,\n container,\n update: (newCtx) => {\n currentCtx = newCtx;\n app._instance?.update();\n },\n });\n\n return container;\n }\n\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(ctx);\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates a DOM-returning editor from a Vue component class.\n * Used for config-based editors (not slot-based).\n * @internal\n */\n private createConfigComponentEditor<TRow = unknown, TValue = unknown>(\n component: Component,\n ): ColumnEditorSpec<TRow, TValue> {\n return (ctx: ColumnEditorContext<TRow, TValue>): HTMLElement => {\n const container = document.createElement('div');\n container.className = 'vue-cell-editor';\n container.style.display = 'contents';\n\n const comp = component;\n const app = createApp({\n render() {\n return createVNode(comp, { ...ctx });\n },\n });\n\n app.mount(container);\n // Track in editor-specific array for per-cell cleanup via releaseCell\n this.editorViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates a DOM-returning editor from a VNode-returning render function.\n * Used for config-based editors (not slot-based).\n * @internal\n */\n private createConfigVNodeEditor<TRow = unknown, TValue = unknown>(\n renderFn: (ctx: ColumnEditorContext<TRow, TValue>) => VNode,\n ): ColumnEditorSpec<TRow, TValue> {\n return (ctx: ColumnEditorContext<TRow, TValue>): HTMLElement => {\n const container = document.createElement('div');\n container.className = 'vue-cell-editor';\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(ctx);\n },\n });\n\n app.mount(container);\n // Track in editor-specific array for per-cell cleanup via releaseCell\n this.editorViews.push({ app, container });\n\n return container;\n };\n }\n\n // #endregion\n\n /**\n * Sets the type defaults map for this adapter.\n * Called by TbwGrid when it receives type defaults from context.\n *\n * @internal\n */\n setTypeDefaults(defaults: TypeDefaultsMap | null): void {\n this.typeDefaults = defaults;\n }\n\n /**\n * Determines if this adapter can handle the given element.\n * Checks if a renderer or editor is registered for this element.\n */\n canHandle(element: HTMLElement): boolean {\n const field = element.getAttribute('field');\n let registry = columnRegistries.get(element);\n\n // If not found in WeakMap, try field-based lookup\n if (!registry && field) {\n const fieldRegistry = fieldRegistries.get(field);\n if (fieldRegistry && (fieldRegistry.renderer || fieldRegistry.editor)) {\n registry = fieldRegistry;\n columnRegistries.set(element, registry);\n }\n }\n\n const hasRenderer = registry?.renderer !== undefined;\n const hasEditor = registry?.editor !== undefined;\n return registry !== undefined && (hasRenderer || hasEditor);\n }\n\n /**\n * Creates a view renderer function that renders a Vue component\n * and returns its container DOM element.\n */\n createRenderer<TRow = unknown, TValue = unknown>(element: HTMLElement): ColumnViewRenderer<TRow, TValue> {\n const renderFn = getColumnRenderer(element);\n\n if (!renderFn) {\n return undefined as unknown as ColumnViewRenderer<TRow, TValue>;\n }\n\n // Cell cache for this field - maps cell element to its Vue app\n const cellCache = new WeakMap<HTMLElement, CellAppCache>();\n\n return (ctx: CellRenderContext<TRow, TValue>) => {\n const cellEl = (ctx as any).cellEl as HTMLElement | undefined;\n\n if (cellEl) {\n // Check if we have a cached app for this cell\n const cached = cellCache.get(cellEl);\n if (cached) {\n // Update the existing app with new context\n cached.update(ctx as CellRenderContext<unknown, unknown>);\n return cached.container;\n }\n\n // Create new container and Vue app for this cell\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n // Create reactive context that can be updated\n let currentCtx = ctx as CellRenderContext<unknown, unknown>;\n\n const app = createApp({\n render() {\n return renderFn(currentCtx);\n },\n });\n\n app.mount(container);\n\n // Store in cache with update function\n cellCache.set(cellEl, {\n app,\n container,\n update: (newCtx) => {\n currentCtx = newCtx;\n // Force re-render\n app._instance?.update();\n },\n });\n\n return container;\n }\n\n // Fallback: create container without caching\n const container = document.createElement('div');\n container.className = 'vue-cell-renderer';\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(ctx as CellRenderContext<unknown, unknown>);\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates an editor spec that renders a Vue component for cell editing.\n * Returns a function that creates the editor DOM element.\n */\n createEditor<TRow = unknown, TValue = unknown>(element: HTMLElement): ColumnEditorSpec<TRow, TValue> {\n const editorFn = getColumnEditor(element);\n\n if (!editorFn) {\n return undefined as unknown as ColumnEditorSpec<TRow, TValue>;\n }\n\n // Return a function that creates the editor element\n return (ctx: ColumnEditorContext<TRow, TValue>): HTMLElement => {\n const container = document.createElement('div');\n container.className = 'vue-cell-editor';\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return editorFn(ctx as ColumnEditorContext<unknown, unknown>);\n },\n });\n\n app.mount(container);\n // Track in editor-specific array for per-cell cleanup via releaseCell\n this.editorViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Framework adapter hook called by MasterDetailPlugin during attach().\n * Parses the <tbw-grid-detail> element and returns a Vue-based renderer.\n */\n parseDetailElement<TRow = unknown>(\n detailElement: Element,\n ): ((row: TRow, rowIndex: number) => HTMLElement) | undefined {\n const gridElement = detailElement.closest('tbw-grid') as HTMLElement | null;\n if (!gridElement) return undefined;\n\n // Get renderer from registry (registered by TbwGridDetailPanel)\n const detailEl = gridElement.querySelector('tbw-grid-detail') as HTMLElement | null;\n if (!detailEl) return undefined;\n\n const renderFn = detailRegistry.get(detailEl);\n if (!renderFn) return undefined;\n\n return (row: TRow, rowIndex: number): HTMLElement => {\n const container = document.createElement('div');\n container.className = 'vue-detail-panel';\n\n const ctx: DetailPanelContext<TRow> = { row, rowIndex };\n const vnodes = renderFn(ctx as DetailPanelContext<unknown>);\n\n if (vnodes && vnodes.length > 0) {\n // Render VNodes into container\n const app = createApp({\n render() {\n return vnodes;\n },\n });\n app.mount(container);\n this.mountedViews.push({ app, container });\n }\n\n return container;\n };\n }\n\n /**\n * Framework adapter hook called by ResponsivePlugin during attach().\n * Parses the <tbw-grid-responsive-card> element and returns a Vue-based renderer.\n */\n parseResponsiveCardElement<TRow = unknown>(\n cardElement: Element,\n ): ((row: TRow, rowIndex: number) => HTMLElement) | undefined {\n const gridElement = cardElement.closest('tbw-grid') as HTMLElement | null;\n if (!gridElement) return undefined;\n\n // Get renderer from registry (registered by TbwGridResponsiveCard)\n const cardEl = gridElement.querySelector('tbw-grid-responsive-card') as HTMLElement | null;\n if (!cardEl) return undefined;\n\n const renderFn = cardRegistry.get(cardEl);\n if (!renderFn) return undefined;\n\n return (row: TRow, rowIndex: number): HTMLElement => {\n const container = document.createElement('div');\n container.className = 'vue-responsive-card';\n\n const ctx: ResponsiveCardContext<TRow> = { row, rowIndex };\n const vnodes = renderFn(ctx as ResponsiveCardContext<unknown>);\n\n if (vnodes && vnodes.length > 0) {\n // Render VNodes into container\n const app = createApp({\n render() {\n return vnodes;\n },\n });\n app.mount(container);\n this.mountedViews.push({ app, container });\n }\n\n return container;\n };\n }\n\n // #region Type Defaults Support\n\n /**\n * Gets type-level defaults from the type defaults map.\n *\n * This enables application-wide type defaults configured via GridTypeProvider.\n * The returned TypeDefault contains renderer/editor functions that render\n * Vue components into the grid's cells.\n *\n * @example\n * ```vue\n * <script setup>\n * import { GridTypeProvider } from '@toolbox-web/grid-vue';\n * import { h } from 'vue';\n * import CountryBadge from './CountryBadge.vue';\n *\n * const typeDefaults = {\n * country: {\n * renderer: (ctx) => h(CountryBadge, { code: ctx.value }),\n * },\n * };\n * </script>\n *\n * <template>\n * <GridTypeProvider :defaults=\"typeDefaults\">\n * <App />\n * </GridTypeProvider>\n * </template>\n * ```\n */\n getTypeDefault<TRow = unknown>(type: string): BaseTypeDefault<TRow> | undefined {\n if (!this.typeDefaults) {\n return undefined;\n }\n\n const vueDefault = this.typeDefaults[type] as TypeDefault<TRow> | undefined;\n if (!vueDefault) {\n return undefined;\n }\n\n const typeDefault: BaseTypeDefault<TRow> = {\n editorParams: vueDefault.editorParams,\n };\n\n // Create renderer function that renders Vue component\n if (vueDefault.renderer) {\n typeDefault.renderer = this.createTypeRenderer<TRow>(vueDefault.renderer);\n }\n\n // Create editor function that renders Vue component\n if (vueDefault.editor) {\n typeDefault.editor = this.createTypeEditor<TRow>(vueDefault.editor) as BaseTypeDefault['editor'];\n }\n\n // Create filterPanelRenderer function that renders Vue component\n if (vueDefault.filterPanelRenderer) {\n typeDefault.filterPanelRenderer = this.createFilterPanelRenderer(vueDefault.filterPanelRenderer);\n }\n\n return typeDefault;\n }\n\n /**\n * Creates a renderer function from a Vue render function for type defaults.\n * @internal\n */\n private createTypeRenderer<TRow = unknown, TValue = unknown>(\n renderFn: (ctx: CellRenderContext<TRow, TValue>) => VNode,\n ): ColumnViewRenderer<TRow, TValue> {\n return (ctx: CellRenderContext<TRow, TValue>) => {\n const container = document.createElement('span');\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(ctx);\n },\n });\n\n app.mount(container);\n this.mountedViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates an editor function from a Vue render function for type defaults.\n * @internal\n */\n private createTypeEditor<TRow = unknown, TValue = unknown>(\n renderFn: (ctx: ColumnEditorContext<TRow, TValue>) => VNode,\n ): ColumnEditorSpec<TRow, TValue> {\n return (ctx: ColumnEditorContext<TRow, TValue>) => {\n const container = document.createElement('span');\n container.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(ctx);\n },\n });\n\n app.mount(container);\n // Track in editor-specific array for per-cell cleanup via releaseCell\n this.editorViews.push({ app, container });\n\n return container;\n };\n }\n\n /**\n * Creates a filter panel renderer function from a Vue render function.\n *\n * Wraps a Vue `(params: FilterPanelParams) => VNode` function into the\n * imperative `(container, params) => void` signature expected by the core grid.\n * @internal\n */\n private createFilterPanelRenderer(\n renderFn: (params: FilterPanelParams) => VNode,\n ): (container: HTMLElement, params: FilterPanelParams) => void {\n return (container: HTMLElement, params: FilterPanelParams) => {\n const wrapper = document.createElement('div');\n wrapper.style.display = 'contents';\n\n const app = createApp({\n render() {\n return renderFn(params);\n },\n });\n\n app.mount(wrapper);\n this.mountedViews.push({ app, container: wrapper });\n container.appendChild(wrapper);\n };\n }\n\n // #endregion\n\n /**\n * Cleanup all mounted Vue apps.\n */\n cleanup(): void {\n for (const { app, container } of this.mountedViews) {\n try {\n app.unmount();\n container.remove();\n } catch {\n // Ignore cleanup errors\n }\n }\n this.mountedViews = [];\n for (const { app, container } of this.editorViews) {\n try {\n app.unmount();\n container.remove();\n } catch {\n // Ignore cleanup errors\n }\n }\n this.editorViews = [];\n }\n\n /**\n * Called when a cell's content is about to be wiped.\n * Destroys editor Vue apps whose container is inside the cell.\n */\n releaseCell(cellEl: HTMLElement): void {\n for (let i = this.editorViews.length - 1; i >= 0; i--) {\n const { app, container } = this.editorViews[i];\n if (cellEl.contains(container)) {\n try {\n app.unmount();\n container.remove();\n } catch {\n // Ignore cleanup errors\n }\n this.editorViews.splice(i, 1);\n }\n }\n }\n}\n\n/**\n * @deprecated Use `GridAdapter` instead. This alias will be removed in a future version.\n * @see {@link GridAdapter}\n */\nexport const VueGridAdapter = GridAdapter;\n","<script setup lang=\"ts\" generic=\"TRow = unknown\">\nimport type { BaseGridPlugin, ColumnConfig, DataGridElement, FitMode, GridConfig } from '@toolbox-web/grid';\nimport { DataGridElement as GridElement } from '@toolbox-web/grid';\nimport type {\n ClipboardConfig,\n ColumnVirtualizationConfig,\n ContextMenuConfig,\n ExportConfig,\n FilterConfig,\n GroupingColumnsConfig,\n GroupingRowsConfig,\n MasterDetailConfig,\n MultiSortConfig,\n PinnedRowsConfig,\n PivotConfig,\n PrintConfig,\n ReorderConfig,\n ResponsivePluginConfig,\n RowReorderConfig,\n SelectionConfig,\n ServerSideConfig,\n TreeConfig,\n UndoRedoConfig,\n VisibilityConfig,\n} from '@toolbox-web/grid/all';\nimport { computed, onBeforeUnmount, onMounted, provide, ref, watch, type PropType } from 'vue';\nimport { createPluginFromFeature, type FeatureName } from './feature-registry';\nimport { useGridIcons } from './grid-icon-registry';\nimport { useGridTypeDefaults } from './grid-type-registry';\nimport { GRID_ELEMENT_KEY } from './use-grid';\nimport { GridAdapter, VueGridAdapter, type GridConfig as VueGridConfig } from './vue-grid-adapter';\n\n// Track if adapter is registered\nlet adapterRegistered = false;\nlet globalAdapter: GridAdapter | null = null;\n\n/**\n * Ensure the Vue adapter is registered globally.\n */\nfunction ensureAdapterRegistered(): GridAdapter {\n if (!adapterRegistered) {\n globalAdapter = new VueGridAdapter();\n GridElement.registerAdapter(globalAdapter);\n adapterRegistered = true;\n }\n return globalAdapter as GridAdapter;\n}\n\n// Register adapter at module load\nensureAdapterRegistered();\n\n/**\n * Props for TbwGrid component\n */\nconst props = defineProps({\n /** Row data to display */\n rows: {\n type: Array as PropType<TRow[]>,\n default: () => [],\n },\n /** Column definitions (shorthand for gridConfig.columns) */\n columns: {\n type: Array as PropType<ColumnConfig<TRow>[]>,\n default: undefined,\n },\n /** Full grid configuration */\n gridConfig: {\n type: Object as PropType<GridConfig<TRow>>,\n default: undefined,\n },\n /** Fit mode shorthand */\n fitMode: {\n type: String as PropType<FitMode>,\n default: undefined,\n },\n\n // ═══════════════════════════════════════════════════════════════════\n // FEATURE PROPS - Declarative plugin configuration\n // ═══════════════════════════════════════════════════════════════════\n\n /** Enable cell/row/range selection */\n selection: {\n type: [String, Object] as PropType<'cell' | 'row' | 'range' | SelectionConfig<TRow>>,\n default: undefined,\n },\n /** Enable inline cell editing */\n editing: {\n type: [Boolean, String] as PropType<boolean | 'click' | 'dblclick' | 'manual'>,\n default: undefined,\n },\n /** Enable clipboard copy/paste */\n clipboard: {\n type: [Boolean, Object] as PropType<boolean | ClipboardConfig>,\n default: undefined,\n },\n /** Enable right-click context menu */\n contextMenu: {\n type: [Boolean, Object] as PropType<boolean | ContextMenuConfig>,\n default: undefined,\n },\n /** Enable multi-column sorting */\n multiSort: {\n type: [Boolean, String, Object] as PropType<boolean | 'single' | 'multi' | MultiSortConfig>,\n default: undefined,\n },\n /** @deprecated Use multiSort instead */\n sorting: {\n type: [Boolean, String, Object] as PropType<boolean | 'single' | 'multi' | MultiSortConfig>,\n default: undefined,\n },\n /** Enable column filtering */\n filtering: {\n type: [Boolean, Object] as PropType<boolean | FilterConfig<TRow>>,\n default: undefined,\n },\n /** Enable column drag-to-reorder */\n reorder: {\n type: [Boolean, Object] as PropType<boolean | ReorderConfig>,\n default: undefined,\n },\n /** Enable column visibility toggle panel */\n visibility: {\n type: [Boolean, Object] as PropType<boolean | VisibilityConfig>,\n default: undefined,\n },\n /** Enable pinned/sticky columns */\n pinnedColumns: {\n type: Boolean as PropType<boolean>,\n default: undefined,\n },\n /** Enable multi-level column headers */\n groupingColumns: {\n type: [Boolean, Object] as PropType<boolean | GroupingColumnsConfig>,\n default: undefined,\n },\n /** Enable horizontal column virtualization */\n columnVirtualization: {\n type: [Boolean, Object] as PropType<boolean | ColumnVirtualizationConfig>,\n default: undefined,\n },\n /** Enable row drag-to-reorder */\n rowReorder: {\n type: [Boolean, Object] as PropType<boolean | RowReorderConfig>,\n default: undefined,\n },\n /** Enable row grouping by field values */\n groupingRows: {\n type: Object as PropType<GroupingRowsConfig>,\n default: undefined,\n },\n /** Enable pinned rows */\n pinnedRows: {\n type: [Boolean, Object] as PropType<boolean | PinnedRowsConfig>,\n default: undefined,\n },\n /** Enable hierarchical tree view */\n tree: {\n type: [Boolean, Object] as PropType<boolean | TreeConfig>,\n default: undefined,\n },\n /** Enable master-detail expandable rows */\n masterDetail: {\n type: Object as PropType<MasterDetailConfig>,\n default: undefined,\n },\n /** Enable responsive card layout */\n responsive: {\n type: [Boolean, Object] as PropType<boolean | ResponsivePluginConfig>,\n default: undefined,\n },\n /** Enable undo/redo for cell edits */\n undoRedo: {\n type: [Boolean, Object] as PropType<boolean | UndoRedoConfig>,\n default: undefined,\n },\n /** Enable CSV/JSON export */\n export: {\n type: [Boolean, Object] as PropType<boolean | ExportConfig>,\n default: undefined,\n },\n /** Enable print functionality */\n print: {\n type: [Boolean, Object] as PropType<boolean | PrintConfig>,\n default: undefined,\n },\n /** Enable pivot table functionality */\n pivot: {\n type: Object as PropType<PivotConfig>,\n default: undefined,\n },\n /** Enable server-side data operations */\n serverSide: {\n type: Object as PropType<ServerSideConfig>,\n default: undefined,\n },\n});\n\n/**\n * Emits for TbwGrid\n */\nconst emit = defineEmits<{\n /** Emitted when a cell value is committed */\n (e: 'cell-commit', event: CustomEvent): void;\n /** Emitted when a row's values are committed */\n (e: 'row-commit', event: CustomEvent): void;\n /** Emitted when a cell is clicked */\n (e: 'cell-click', event: CustomEvent): void;\n /** Emitted when a cell is double-clicked */\n (e: 'cell-dblclick', event: CustomEvent): void;\n /** Emitted when selection changes */\n (e: 'selection-change', event: CustomEvent): void;\n /** Emitted when a row is expanded/collapsed */\n (e: 'row-toggle', event: CustomEvent): void;\n /** Emitted when sorting changes */\n (e: 'sort-change', event: CustomEvent): void;\n /** Emitted when the grid is ready */\n (e: 'ready', event: CustomEvent): void;\n}>();\n\n// Template ref for the grid element\nconst gridRef = ref<DataGridElement<TRow> | null>(null);\n\n// Provide grid element to descendants (for useGrid composable)\nprovide(GRID_ELEMENT_KEY, gridRef);\n\n// Get type defaults and icons from providers\nconst typeDefaults = useGridTypeDefaults();\nconst iconOverrides = useGridIcons();\n\n// Feature prop names for creating plugins\nconst FEATURE_PROPS: FeatureName[] = [\n 'selection',\n 'editing',\n 'clipboard',\n 'contextMenu',\n 'multiSort',\n 'sorting',\n 'filtering',\n 'reorder',\n 'visibility',\n 'pinnedColumns',\n 'groupingColumns',\n 'columnVirtualization',\n 'rowReorder',\n 'groupingRows',\n 'pinnedRows',\n 'tree',\n 'masterDetail',\n 'responsive',\n 'undoRedo',\n 'export',\n 'print',\n 'pivot',\n 'serverSide',\n];\n\n/**\n * Create plugins from feature props.\n */\nfunction createFeaturePlugins(): BaseGridPlugin[] {\n const plugins: BaseGridPlugin[] = [];\n\n for (const feature of FEATURE_PROPS) {\n const propValue = props[feature as keyof typeof props];\n if (propValue !== undefined) {\n const plugin = createPluginFromFeature(feature, propValue);\n if (plugin) {\n plugins.push(plugin as BaseGridPlugin);\n }\n }\n }\n\n return plugins;\n}\n\n// Merged config with feature plugins\nconst mergedConfig = computed<GridConfig<TRow> | undefined>(() => {\n const baseConfig = props.gridConfig ?? {};\n const featurePlugins = createFeaturePlugins();\n const configPlugins = (baseConfig.plugins as BaseGridPlugin[]) ?? [];\n\n // Merge: feature plugins first, then config plugins\n const mergedPlugins = [...featurePlugins, ...configPlugins];\n\n // Apply type defaults if provided\n const typeDefaults$ = typeDefaults;\n\n // Apply icon overrides if provided\n const icons = iconOverrides ? { ...baseConfig.icons, ...iconOverrides } : baseConfig.icons;\n\n return {\n ...baseConfig,\n ...(props.columns ? { columns: props.columns } : {}),\n ...(mergedPlugins.length > 0 ? { plugins: mergedPlugins } : {}),\n ...(icons ? { icons } : {}),\n } as GridConfig<TRow>;\n});\n\n// Event handlers\nfunction handleCellCommit(event: Event) {\n emit('cell-commit', event as CustomEvent);\n}\n\nfunction handleRowCommit(event: Event) {\n emit('row-commit', event as CustomEvent);\n}\n\nfunction handleCellClick(event: Event) {\n emit('cell-click', event as CustomEvent);\n}\n\nfunction handleCellDblclick(event: Event) {\n emit('cell-dblclick', event as CustomEvent);\n}\n\nfunction handleSelectionChange(event: Event) {\n emit('selection-change', event as CustomEvent);\n}\n\nfunction handleRowToggle(event: Event) {\n emit('row-toggle', event as CustomEvent);\n}\n\nfunction handleSortChange(event: Event) {\n emit('sort-change', event as CustomEvent);\n}\n\nfunction handleReady(event: Event) {\n emit('ready', event as CustomEvent);\n}\n\n/**\n * Intercepts the element's `gridConfig` property so ALL writes\n * go through the adapter's processGridConfig first.\n *\n * This converts Vue component classes and VNode-returning functions\n * to DOM-returning functions before the grid core sees them.\n * Handles cases where `:grid-config` is bound directly to the\n * custom element (bypassing TbwGrid.vue).\n */\nfunction interceptElementGridConfig(grid: HTMLElement, adapter: GridAdapter): void {\n const proto = Object.getPrototypeOf(grid);\n const desc = Object.getOwnPropertyDescriptor(proto, 'gridConfig');\n if (!desc?.set || !desc?.get) return;\n\n const originalSet = desc.set;\n const originalGet = desc.get;\n\n // Instance-level override (does not affect the prototype or other grid elements)\n Object.defineProperty(grid, 'gridConfig', {\n get() {\n return originalGet.call(this);\n },\n set(value: VueGridConfig | undefined) {\n if (value && adapter) {\n // processGridConfig is idempotent: already-processed functions pass\n // through isVueComponent unchanged, so double-processing is safe.\n originalSet.call(this, adapter.processGridConfig(value));\n } else {\n originalSet.call(this, value);\n }\n },\n configurable: true,\n });\n}\n\n/**\n * Removes the instance-level gridConfig interceptor,\n * restoring the prototype's original getter/setter.\n */\nfunction removeGridConfigInterceptor(grid: HTMLElement): void {\n // Deleting the instance property restores the prototype accessor\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete (grid as any).gridConfig;\n}\n\n// Setup and cleanup\nonMounted(() => {\n const grid = gridRef.value as unknown as HTMLElement & DataGridElement<TRow>;\n if (!grid) return;\n\n // Attach the framework adapter to the grid element\n // This enables MasterDetailPlugin and ResponsivePlugin to use Vue-based renderers\n const adapter = ensureAdapterRegistered();\n (grid as any).__frameworkAdapter = adapter;\n\n // Pass type defaults to the adapter\n adapter.setTypeDefaults(typeDefaults ?? null);\n\n // Intercept the element's gridConfig setter so ALL writes\n // (including direct custom element bindings) go through processGridConfig.\n interceptElementGridConfig(grid, adapter);\n\n // Add event listeners\n grid.addEventListener('cell-commit', handleCellCommit);\n grid.addEventListener('row-commit', handleRowCommit);\n grid.addEventListener('cell-click', handleCellClick);\n grid.addEventListener('cell-dblclick', handleCellDblclick);\n grid.addEventListener('selection-change', handleSelectionChange);\n grid.addEventListener('row-toggle', handleRowToggle);\n grid.addEventListener('sort-change', handleSortChange);\n grid.addEventListener('ready', handleReady);\n\n // Set initial data\n if (props.rows.length > 0) {\n grid.rows = props.rows;\n }\n if (mergedConfig.value) {\n // Process through adapter before passing to grid\n grid.gridConfig = mergedConfig.value;\n }\n if (props.fitMode) {\n grid.fitMode = props.fitMode;\n }\n});\n\nonBeforeUnmount(() => {\n const grid = gridRef.value as unknown as HTMLElement & DataGridElement<TRow>;\n if (!grid) return;\n\n // Remove the gridConfig setter interceptor\n removeGridConfigInterceptor(grid);\n\n // Remove event listeners\n grid.removeEventListener('cell-commit', handleCellCommit);\n grid.removeEventListener('row-commit', handleRowCommit);\n grid.removeEventListener('cell-click', handleCellClick);\n grid.removeEventListener('cell-dblclick', handleCellDblclick);\n grid.removeEventListener('selection-change', handleSelectionChange);\n grid.removeEventListener('row-toggle', handleRowToggle);\n grid.removeEventListener('sort-change', handleSortChange);\n grid.removeEventListener('ready', handleReady);\n});\n\n// Watch for prop changes\nwatch(\n () => props.rows,\n (newRows) => {\n if (gridRef.value) {\n gridRef.value.rows = newRows;\n }\n },\n { deep: true },\n);\n\nwatch(\n mergedConfig,\n (newConfig) => {\n if (gridRef.value && newConfig) {\n gridRef.value.gridConfig = newConfig;\n }\n },\n { deep: true },\n);\n\nwatch(\n () => props.fitMode,\n (newFitMode) => {\n if (gridRef.value && newFitMode) {\n gridRef.value.fitMode = newFitMode;\n }\n },\n);\n\n// Watch for type defaults changes\nwatch(\n () => typeDefaults,\n (newTypeDefaults) => {\n const adapter = ensureAdapterRegistered();\n adapter.setTypeDefaults(newTypeDefaults ?? null);\n },\n { deep: true },\n);\n\n// Expose the grid element for programmatic access\ndefineExpose({\n /** The underlying grid element */\n gridElement: gridRef,\n /** Force a layout recalculation */\n forceLayout: () => gridRef.value?.forceLayout(),\n /** Get current grid configuration */\n getConfig: () => gridRef.value?.getConfig(),\n /** Wait for grid to be ready */\n ready: () => gridRef.value?.ready(),\n});\n</script>\n\n<template>\n <tbw-grid ref=\"gridRef\">\n <slot></slot>\n </tbw-grid>\n</template>\n","<script setup lang=\"ts\">\nimport type { CellRenderContext, ColumnEditorContext } from '@toolbox-web/grid';\nimport { h, onMounted, ref, type VNode } from 'vue';\nimport type { CellSlotProps, EditorSlotProps } from './slot-types';\nimport { registerColumnEditor, registerColumnRenderer } from './vue-grid-adapter';\n\n/**\n * Props for TbwGridColumn\n */\nconst props = defineProps<{\n /** Field path in the row object */\n field: string;\n /** Column header text */\n header?: string;\n /** Column width */\n width?: string | number;\n /** Minimum column width */\n minWidth?: string | number;\n /** Maximum column width */\n maxWidth?: string | number;\n /** Whether the column is sortable */\n sortable?: boolean;\n /** Whether the column is resizable */\n resizable?: boolean;\n /** Whether the column is editable */\n editable?: boolean;\n /** Data type for the column */\n type?: string;\n /** Column alignment */\n align?: 'left' | 'center' | 'right';\n /** Whether the column is hidden */\n hidden?: boolean;\n}>();\n\n// Define slots with proper typing and get the slots object\nconst slots = defineSlots<{\n /** Custom cell renderer slot */\n cell?: (props: CellSlotProps) => VNode[];\n /** Custom cell editor slot */\n editor?: (props: EditorSlotProps) => VNode[];\n}>();\n\n// Template ref for the column element\nconst columnRef = ref<HTMLElement | null>(null);\n\nonMounted(() => {\n const element = columnRef.value;\n if (!element) return;\n\n // Check if cell slot exists by trying to access it\n const hasCellSlot = !!slots.cell;\n const hasEditorSlot = !!slots.editor;\n\n // Register renderer if #cell slot is provided\n if (hasCellSlot) {\n registerColumnRenderer(element, (ctx: CellRenderContext<unknown, unknown>) => {\n const slotFn = slots.cell;\n if (!slotFn) return h('span');\n const slotContent = slotFn({\n value: ctx.value,\n row: ctx.row,\n column: ctx.column,\n });\n // Return the VNode array wrapped in a div\n return h('div', { style: 'display: contents' }, slotContent);\n });\n }\n\n // Register editor if #editor slot is provided\n if (hasEditorSlot) {\n registerColumnEditor(element, (ctx: ColumnEditorContext<unknown, unknown>) => {\n const slotFn = slots.editor;\n if (!slotFn) return h('span');\n const slotContent = slotFn({\n value: ctx.value,\n row: ctx.row,\n column: ctx.column,\n field: ctx.field,\n rowId: ctx.rowId ?? '',\n commit: ctx.commit,\n cancel: ctx.cancel,\n updateRow: ctx.updateRow,\n onValueChange: ctx.onValueChange,\n });\n return h('div', { style: 'display: contents' }, slotContent);\n });\n }\n});\n</script>\n\n<template>\n <tbw-grid-column\n ref=\"columnRef\"\n :field=\"field\"\n :header=\"header\"\n :width=\"width\"\n :min-width=\"minWidth\"\n :max-width=\"maxWidth\"\n :sortable=\"sortable\"\n :resizable=\"resizable\"\n :editable=\"editable\"\n :type=\"type\"\n :align=\"align\"\n :hidden=\"hidden\"\n >\n <!-- Hidden slot to capture slot definitions -->\n </tbw-grid-column>\n</template>\n","<script setup lang=\"ts\" generic=\"TRow = unknown\">\nimport { onMounted, ref, useSlots, type VNode } from 'vue';\nimport { detailRegistry, type DetailPanelContext } from './detail-panel-registry';\n\n/**\n * Props for TbwGridDetailPanel\n */\nconst props = withDefaults(\n defineProps<{\n /**\n * Whether to show the expand/collapse column.\n * @default true\n */\n showExpandColumn?: boolean;\n\n /**\n * Animation style for expand/collapse.\n * - 'slide': Smooth height animation (default)\n * - 'fade': Opacity transition\n * - false: No animation\n * @default 'slide'\n */\n animation?: 'slide' | 'fade' | false;\n }>(),\n {\n showExpandColumn: true,\n animation: 'slide',\n },\n);\n\n// Define slots with proper typing\ndefineSlots<{\n /** Detail panel content slot */\n default?: (props: DetailPanelContext<TRow>) => VNode[];\n}>();\n\n// Template ref for the detail element\nconst detailRef = ref<HTMLElement | null>(null);\nconst slots = useSlots();\n\nonMounted(() => {\n const element = detailRef.value;\n if (!element || !slots.default) return;\n\n // Register the slot renderer\n detailRegistry.set(element, (ctx: DetailPanelContext<unknown>) => {\n return slots.default?.(ctx as DetailPanelContext<TRow>);\n });\n});\n</script>\n\n<template>\n <tbw-grid-detail ref=\"detailRef\" :show-expand-column=\"showExpandColumn\" :animation=\"animation\" />\n</template>\n","<script setup lang=\"ts\" generic=\"TRow = unknown\">\nimport { onMounted, ref, useSlots, type VNode } from 'vue';\nimport { cardRegistry, type ResponsiveCardContext } from './responsive-card-registry';\n\n/**\n * Props for TbwGridResponsiveCard\n */\nconst props = defineProps<{\n // Currently no additional props needed\n}>();\n\n// Define slots with proper typing\ndefineSlots<{\n /** Card content slot */\n default?: (props: ResponsiveCardContext<TRow>) => VNode[];\n}>();\n\n// Template ref for the card element\nconst cardRef = ref<HTMLElement | null>(null);\nconst slots = useSlots();\n\nonMounted(() => {\n const element = cardRef.value;\n if (!element || !slots.default) return;\n\n // Register the slot renderer\n cardRegistry.set(element, (ctx: ResponsiveCardContext<unknown>) => {\n return slots.default?.(ctx as ResponsiveCardContext<TRow>);\n });\n});\n</script>\n\n<template>\n <tbw-grid-responsive-card ref=\"cardRef\" />\n</template>\n","<script setup lang=\"ts\">\nimport { type VNode } from 'vue';\n\n/**\n * Props for TbwGridToolButtons\n */\ndefineProps<{\n // Currently no additional props needed\n}>();\n\n// Define slots with proper typing\ndefineSlots<{\n /** Tool button content slot */\n default?: () => VNode[];\n}>();\n</script>\n\n<template>\n <tbw-grid-tool-buttons>\n <slot />\n </tbw-grid-tool-buttons>\n</template>\n","/**\n * Registry for tool panel renderers.\n * @internal\n */\nimport type { VNode } from 'vue';\n\n/**\n * Context object passed to the tool panel slot.\n */\nexport interface ToolPanelContext {\n /** The grid element */\n gridElement: HTMLElement;\n}\n\n/**\n * Registry for tool panel renderers (per element)\n */\nexport const toolPanelRegistry = new WeakMap<HTMLElement, (ctx: ToolPanelContext) => VNode[] | undefined>();\n\n/**\n * Get the tool panel renderer for an element.\n * @internal\n */\nexport function getToolPanelRenderer(\n panelElement: HTMLElement,\n): ((ctx: ToolPanelContext) => VNode[] | undefined) | undefined {\n return toolPanelRegistry.get(panelElement);\n}\n","<script setup lang=\"ts\">\nimport { onMounted, ref, useSlots, type VNode } from 'vue';\nimport { toolPanelRegistry, type ToolPanelContext } from './tool-panel-registry';\n\n/**\n * Props for TbwGridToolPanel\n */\nconst props = withDefaults(\n defineProps<{\n /**\n * Unique identifier for this tool panel.\n */\n id: string;\n\n /**\n * Display label for the panel tab/button.\n */\n label: string;\n\n /**\n * Icon for the panel tab (string or SVG).\n */\n icon?: string;\n\n /**\n * Position of the panel.\n * @default 'right'\n */\n position?: 'left' | 'right';\n\n /**\n * Width of the panel when open.\n * @default '250px'\n */\n width?: string;\n }>(),\n {\n position: 'right',\n width: '250px',\n },\n);\n\n// Define slots with proper typing\ndefineSlots<{\n /** Tool panel content slot */\n default?: (props: ToolPanelContext) => VNode[];\n}>();\n\n// Template ref for the tool panel element\nconst panelRef = ref<HTMLElement | null>(null);\nconst slots = useSlots();\n\nonMounted(() => {\n const element = panelRef.value;\n if (!element || !slots.default) return;\n\n // Register the slot renderer\n toolPanelRegistry.set(element, (ctx: ToolPanelContext) => {\n return slots.default?.(ctx);\n });\n});\n</script>\n\n<template>\n <tbw-grid-tool-panel ref=\"panelRef\" :id=\"id\" :label=\"label\" :icon=\"icon\" :position=\"position\" :width=\"width\" />\n</template>\n","import type { DataGridElement } from '@toolbox-web/grid';\nimport { inject, onBeforeUnmount, onMounted, ref, type Ref } from 'vue';\nimport { GRID_ELEMENT_KEY } from './use-grid';\n\n/**\n * Grid event types and their payload types.\n */\nexport interface GridEventMap {\n 'cell-click': { value: unknown; row: unknown; column: unknown; rowIndex: number; colIndex: number };\n 'cell-dblclick': { value: unknown; row: unknown; column: unknown; rowIndex: number; colIndex: number };\n 'cell-commit': { value: unknown; oldValue: unknown; row: unknown; column: unknown };\n 'row-commit': { row: unknown; changes: Record<string, unknown> };\n 'selection-change': { selectedRows: unknown[]; selectedCells: unknown[] };\n 'sort-change': { field: string; direction: 'asc' | 'desc' | null };\n 'row-toggle': { row: unknown; expanded: boolean };\n ready: undefined;\n}\n\n/**\n * Composable for subscribing to grid events with automatic cleanup.\n *\n * @param eventName - The name of the grid event to listen for\n * @param handler - The event handler function\n * @param gridElement - Optional grid element ref (uses injected if not provided)\n *\n * @example\n * ```vue\n * <script setup>\n * import { useGridEvent } from '@toolbox-web/grid-vue';\n *\n * useGridEvent('cell-commit', (event) => {\n * console.log('Cell committed:', event.detail);\n * });\n *\n * useGridEvent('selection-change', (event) => {\n * console.log('Selection changed:', event.detail);\n * });\n * </script>\n * ```\n */\nexport function useGridEvent<K extends keyof GridEventMap>(\n eventName: K,\n handler: (event: CustomEvent<GridEventMap[K]>) => void,\n gridElement?: Ref<DataGridElement | null>,\n): void {\n const grid = gridElement ?? inject(GRID_ELEMENT_KEY, ref(null));\n let cleanup: (() => void) | null = null;\n\n onMounted(() => {\n const element = grid.value as unknown as HTMLElement | null;\n if (!element) return;\n\n const eventHandler = handler as EventListener;\n element.addEventListener(eventName, eventHandler);\n cleanup = () => element.removeEventListener(eventName, eventHandler);\n });\n\n onBeforeUnmount(() => {\n cleanup?.();\n });\n}\n","/**\n * Combined provider for type defaults and icons.\n *\n * Convenience component that combines GridTypeProvider and GridIconProvider.\n */\nimport type { GridIcons } from '@toolbox-web/grid';\nimport { defineComponent, h, type PropType, type VNode } from 'vue';\nimport { GridIconProvider } from './grid-icon-registry';\nimport { GridTypeProvider, type TypeDefaultsMap } from './grid-type-registry';\n\n/**\n * Combined provider for type defaults and icons.\n *\n * @example\n * ```vue\n * <script setup>\n * import { GridProvider, type TypeDefaultsMap } from '@toolbox-web/grid-vue';\n * import { h } from 'vue';\n *\n * const typeDefaults: TypeDefaultsMap = {\n * country: { renderer: (ctx) => h('span', ctx.value) },\n * };\n *\n * const icons = { sortAsc: '↑', sortDesc: '↓' };\n * </script>\n *\n * <template>\n * <GridProvider :typeDefaults=\"typeDefaults\" :icons=\"icons\">\n * <App />\n * </GridProvider>\n * </template>\n * ```\n */\nexport const GridProvider = defineComponent({\n name: 'GridProvider',\n props: {\n /**\n * Type defaults to provide to all descendant grids.\n */\n typeDefaults: {\n type: Object as PropType<TypeDefaultsMap>,\n default: undefined,\n },\n /**\n * Icon overrides to provide to all descendant grids.\n */\n icons: {\n type: Object as PropType<Partial<GridIcons>>,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n return () => {\n let content: VNode[] | VNode | undefined = slots.default?.();\n\n // Wrap with type provider if typeDefaults is provided\n if (props.typeDefaults) {\n content = h(GridTypeProvider, { defaults: props.typeDefaults }, () => content);\n }\n\n // Wrap with icon provider if icons is provided\n if (props.icons) {\n content = h(GridIconProvider, { icons: props.icons }, () => content);\n }\n\n return content;\n };\n },\n});\n\nexport type GridProviderProps = InstanceType<typeof GridProvider>['$props'];\n"],"names":["GRID_ICONS","useGridIcons","inject","GridIconProvider","defineComponent","props","slots","provide","GRID_TYPE_DEFAULTS","useGridTypeDefaults","useTypeDefault","typeName","GridTypeProvider","detailRegistry","cardRegistry","columnRegistries","fieldRegistries","registerColumnRenderer","element","renderer","field","registry","fieldRegistry","registerColumnEditor","editor","getColumnRenderer","getColumnEditor","isVueComponent","value","obj","fnString","fn","isVNodeRenderFunction","PROCESSED_MARKER","GridAdapter","config","result","col","typeDefaults","processed","type","processedConfig","column","wrapped","component","cellCache","ctx","cellEl","cached","container","currentCtx","comp","app","createApp","createVNode","newCtx","renderFn","defaults","hasRenderer","hasEditor","editorFn","detailElement","gridElement","detailEl","row","rowIndex","vnodes","cardElement","cardEl","vueDefault","typeDefault","params","wrapper","i","VueGridAdapter","adapterRegistered","globalAdapter","ensureAdapterRegistered","GridElement","__props","emit","__emit","gridRef","ref","GRID_ELEMENT_KEY","iconOverrides","FEATURE_PROPS","createFeaturePlugins","plugins","feature","propValue","plugin","createPluginFromFeature","mergedConfig","computed","baseConfig","featurePlugins","configPlugins","mergedPlugins","icons","handleCellCommit","event","handleRowCommit","handleCellClick","handleCellDblclick","handleSelectionChange","handleRowToggle","handleSortChange","handleReady","interceptElementGridConfig","grid","adapter","proto","desc","originalSet","originalGet","removeGridConfigInterceptor","onMounted","onBeforeUnmount","watch","newRows","newConfig","newFitMode","newTypeDefaults","__expose","_createElementBlock","_renderSlot","_ctx","_useSlots","columnRef","hasCellSlot","hasEditorSlot","slotFn","h","slotContent","detailRef","useSlots","cardRef","toolPanelRegistry","panelRef","useGridEvent","eventName","handler","cleanup","eventHandler","GridProvider","content"],"mappings":"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"}
@@ -77,6 +77,8 @@ export declare function isVueComponent(value: unknown): value is Component;
77
77
  */
78
78
  export declare class GridAdapter implements FrameworkAdapter {
79
79
  private mountedViews;
80
+ /** Editor-specific views tracked separately for per-cell cleanup via releaseCell. */
81
+ private editorViews;
80
82
  private typeDefaults;
81
83
  /**
82
84
  * Processes a Vue grid configuration, converting Vue component references
@@ -226,6 +228,11 @@ export declare class GridAdapter implements FrameworkAdapter {
226
228
  * Cleanup all mounted Vue apps.
227
229
  */
228
230
  cleanup(): void;
231
+ /**
232
+ * Called when a cell's content is about to be wiped.
233
+ * Destroys editor Vue apps whose container is inside the cell.
234
+ */
235
+ releaseCell(cellEl: HTMLElement): void;
229
236
  }
230
237
  /**
231
238
  * @deprecated Use `GridAdapter` instead. This alias will be removed in a future version.
@@ -1 +1 @@
1
- {"version":3,"file":"vue-grid-adapter.d.ts","sourceRoot":"","sources":["../../../../libs/grid-vue/src/lib/vue-grid-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vue-grid-adapter.d.ts","sourceRoot":"","sources":["../../../../libs/grid-vue/src/lib/vue-grid-adapter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolbox-web/grid-vue",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Vue 3 adapter for @toolbox-web/grid data grid component",
5
5
  "type": "module",
6
6
  "main": "./index.js",