@toolbox-web/grid 3.8.2 → 3.9.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.
Files changed (100) hide show
  1. package/all.d.ts +1 -0
  2. package/all.js +1 -1
  3. package/all.js.map +1 -1
  4. package/index.js +1 -1
  5. package/index.js.map +1 -1
  6. package/lib/core/defaults.d.ts +1 -1
  7. package/lib/core/internal/aria.d.ts +1 -1
  8. package/lib/core/internal/config-manager.d.ts +0 -4
  9. package/lib/core/plugin/base-plugin.d.ts +14 -0
  10. package/lib/core/plugin/plugin-manager.d.ts +5 -1
  11. package/lib/core/plugin/types.d.ts +2 -0
  12. package/lib/core/types.d.ts +6 -0
  13. package/lib/features/registry.js +1 -1
  14. package/lib/plugins/clipboard/clipboard-plugin.d.ts +2 -3
  15. package/lib/plugins/clipboard/index.js +1 -1
  16. package/lib/plugins/clipboard/index.js.map +1 -1
  17. package/lib/plugins/column-virtualization/index.js +1 -1
  18. package/lib/plugins/column-virtualization/index.js.map +1 -1
  19. package/lib/plugins/context-menu/index.js +1 -1
  20. package/lib/plugins/context-menu/index.js.map +1 -1
  21. package/lib/plugins/editing/index.js +1 -1
  22. package/lib/plugins/editing/index.js.map +1 -1
  23. package/lib/plugins/export/index.js +1 -1
  24. package/lib/plugins/export/index.js.map +1 -1
  25. package/lib/plugins/filtering/index.js +1 -1
  26. package/lib/plugins/filtering/index.js.map +1 -1
  27. package/lib/plugins/grouping-columns/index.js +1 -1
  28. package/lib/plugins/grouping-columns/index.js.map +1 -1
  29. package/lib/plugins/grouping-rows/grouping-rows-plugin.d.ts +20 -24
  30. package/lib/plugins/grouping-rows/grouping-rows.d.ts +9 -4
  31. package/lib/plugins/grouping-rows/index.d.ts +1 -1
  32. package/lib/plugins/grouping-rows/index.js +1 -1
  33. package/lib/plugins/grouping-rows/index.js.map +1 -1
  34. package/lib/plugins/grouping-rows/types.d.ts +32 -4
  35. package/lib/plugins/hierarchy/hierarchy-plugin.d.ts +79 -0
  36. package/lib/plugins/hierarchy/hierarchy.d.ts +28 -0
  37. package/lib/plugins/hierarchy/index.d.ts +9 -0
  38. package/lib/plugins/hierarchy/index.js +2 -0
  39. package/lib/plugins/hierarchy/index.js.map +1 -0
  40. package/lib/plugins/hierarchy/types.d.ts +92 -0
  41. package/lib/plugins/master-detail/index.js +1 -1
  42. package/lib/plugins/master-detail/index.js.map +1 -1
  43. package/lib/plugins/multi-sort/index.js +1 -1
  44. package/lib/plugins/multi-sort/index.js.map +1 -1
  45. package/lib/plugins/pinned-columns/index.js +1 -1
  46. package/lib/plugins/pinned-columns/index.js.map +1 -1
  47. package/lib/plugins/pinned-rows/index.js +1 -1
  48. package/lib/plugins/pinned-rows/index.js.map +1 -1
  49. package/lib/plugins/pivot/index.js +1 -1
  50. package/lib/plugins/pivot/index.js.map +1 -1
  51. package/lib/plugins/print/index.js +1 -1
  52. package/lib/plugins/print/index.js.map +1 -1
  53. package/lib/plugins/reorder-columns/index.js +1 -1
  54. package/lib/plugins/reorder-columns/index.js.map +1 -1
  55. package/lib/plugins/responsive/index.js +1 -1
  56. package/lib/plugins/responsive/index.js.map +1 -1
  57. package/lib/plugins/row-drag-drop/index.js +1 -1
  58. package/lib/plugins/row-drag-drop/index.js.map +1 -1
  59. package/lib/plugins/row-drag-drop/row-drag-drop-plugin.d.ts +1 -0
  60. package/lib/plugins/row-drag-drop/types.d.ts +3 -2
  61. package/lib/plugins/selection/index.js +1 -1
  62. package/lib/plugins/selection/index.js.map +1 -1
  63. package/lib/plugins/selection/selection-plugin.d.ts +2 -2
  64. package/lib/plugins/server-side/index.js +1 -1
  65. package/lib/plugins/server-side/index.js.map +1 -1
  66. package/lib/plugins/shell/index.js +1 -1
  67. package/lib/plugins/shell/index.js.map +1 -1
  68. package/lib/plugins/sticky-rows/index.js +1 -1
  69. package/lib/plugins/sticky-rows/index.js.map +1 -1
  70. package/lib/plugins/tooltip/index.js +1 -1
  71. package/lib/plugins/tooltip/index.js.map +1 -1
  72. package/lib/plugins/tree/index.js +1 -1
  73. package/lib/plugins/tree/index.js.map +1 -1
  74. package/lib/plugins/tree/tree-datasource.d.ts +7 -10
  75. package/lib/plugins/tree/tree-plugin.d.ts +23 -3
  76. package/lib/plugins/undo-redo/index.js +1 -1
  77. package/lib/plugins/undo-redo/index.js.map +1 -1
  78. package/lib/plugins/visibility/index.js +1 -1
  79. package/lib/plugins/visibility/index.js.map +1 -1
  80. package/package.json +1 -1
  81. package/umd/grid.all.umd.js +1 -1
  82. package/umd/grid.all.umd.js.map +1 -1
  83. package/umd/grid.umd.js +1 -1
  84. package/umd/grid.umd.js.map +1 -1
  85. package/umd/plugins/clipboard.umd.js +1 -1
  86. package/umd/plugins/clipboard.umd.js.map +1 -1
  87. package/umd/plugins/editing.umd.js +1 -1
  88. package/umd/plugins/editing.umd.js.map +1 -1
  89. package/umd/plugins/grouping-rows.umd.js +1 -1
  90. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  91. package/umd/plugins/hierarchy.umd.js +2 -0
  92. package/umd/plugins/hierarchy.umd.js.map +1 -0
  93. package/umd/plugins/row-drag-drop.umd.js +1 -1
  94. package/umd/plugins/row-drag-drop.umd.js.map +1 -1
  95. package/umd/plugins/selection.umd.js +1 -1
  96. package/umd/plugins/selection.umd.js.map +1 -1
  97. package/umd/plugins/tooltip.umd.js +1 -1
  98. package/umd/plugins/tooltip.umd.js.map +1 -1
  99. package/umd/plugins/tree.umd.js +1 -1
  100. package/umd/plugins/tree.umd.js.map +1 -1
@@ -0,0 +1,2 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("../../core/plugin/base-plugin")):"function"==typeof define&&define.amd?define(["exports","../../core/plugin/base-plugin"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TbwGridPlugin_hierarchy={},e.TbwGrid)}(this,function(e,t){function r(e,t,r=new WeakMap){const o=[];for(const c of["structure","transform"])for(const r of t)r.hierarchyStage===c&&r.beginHierarchy(e)&&o.push(r);if(0===o.length)return[...e];const n=[],i=(e,t,r)=>{const n={parent:t?t.row:null,parentKey:t?.key??null,depth:r};for(const i of o)e=i.processSiblings(e,n);return e},s=(e,t)=>{const o=e.length;for(let l=0;l<o;l++){const a=e[l];n.push(a.row),"object"==typeof a.row&&null!==a.row&&r.set(a.row,{level:t+1,setSize:o,posInSet:l+1});const u=a.children;a.expanded&&u&&s(a.shaped?u:i(u,a,t+1),t+1)}},l=new Array(e.length);for(let c=0;c<e.length;c++)l[c]={row:e[c]};s(i(l,null,0),0);const a=e=>"object"==typeof e&&null!==e?r.get(e):void 0;let u=!1;for(const c of o)c.endHierarchy(n,a)&&(u=!0);if(!u)for(const c of n)"object"==typeof c&&null!==c&&r.delete(c);return n}function o(e,t,r){const o=String(r);e.getAttribute(t)!==o&&e.setAttribute(t,o)}function n(e){return"function"==typeof e.processSiblings}function i(e){return e.constructor.manifest?.hookPriority?.processRows??0}Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});var s=class extends t.BaseGridPlugin{static manifest={modifiesRowStructure:!0};name="hierarchy";#e=new WeakMap;detach(){this.gridElement?.querySelector(".rows-body")?.setAttribute("role","grid"),this.#e=new WeakMap}process(e,t){const o=this.#t();return o.includes(t)?o[o.length-1]!==t?e:(this.#e=new WeakMap,r(e,o,this.#e)):(this.#e=new WeakMap,r(e,[t],this.#e))}getRowMeta(e){return"object"==typeof e&&null!==e?this.#e.get(e):void 0}afterRender(){this.#r()}onScrollRender(){this.#r()}#t(){return(this.grid?._pluginManager?.getPlugins?.()??[]).filter(n).sort((e,t)=>i(e)-i(t))}#r(){if(0===this.#t().length)return;const e=this.gridElement?.querySelector(".rows");if(!e)return;let t=!1;for(const i of e.querySelectorAll(".data-grid-row")){const e=this.getRowMeta(i.__rowDataRef);e?(t=!0,o(i,"aria-level",e.level),o(i,"aria-setsize",e.setSize),o(i,"aria-posinset",e.posInSet)):(i.removeAttribute("aria-level"),i.removeAttribute("aria-setsize"),i.removeAttribute("aria-posinset"))}const r=t?"treegrid":"grid",n=this.gridElement?.querySelector(".rows-body");n&&n.getAttribute("role")!==r&&n.setAttribute("role",r)}};e.HierarchyPlugin=s,e.buildHierarchy=r});
2
+ //# sourceMappingURL=hierarchy.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hierarchy.umd.js","names":[],"sources":["../../../../../libs/grid/src/lib/plugins/hierarchy/hierarchy.ts","../../../../../libs/grid/src/lib/plugins/hierarchy/hierarchy-plugin.ts"],"sourcesContent":["/**\n * Hierarchy Engine\n *\n * Pure row-model builder shared by the HierarchyPlugin and its contributors.\n */\n\nimport type { HierarchyContributor, HierarchyNode, HierarchyRowMeta } from './types';\n\n/**\n * Build the flat row list for `rows` from every contributor's sibling-list\n * transforms, recording each emitted row's ARIA position in `meta`.\n *\n * Contributors whose `beginHierarchy` returns `false` sit out the rebuild.\n * With no active contributor the rows pass through unchanged. When every\n * active contributor's `endHierarchy` returns `false`, no position is kept in `meta`.\n *\n * This is what `HierarchyPlugin.process()` runs for all attached contributors.\n * Call it directly to run a contributor without a grid — e.g. as the\n * `processRows` fallback when no HierarchyPlugin is attached, or in unit tests.\n *\n * @example\n * ```ts\n * override processRows(rows: readonly unknown[]): unknown[] {\n * const hierarchy = this.grid?.getPluginByName('hierarchy');\n * return hierarchy ? hierarchy.process(rows, this) : buildHierarchy(rows, [this]);\n * }\n * ```\n *\n * @param rows - The root rows.\n * @param contributors - Contributors to run, in `processRows` hook order.\n * @param meta - Receives each emitted row's position. Pass a fresh map per rebuild.\n * @returns The flattened rows, in render order.\n * @since 3.9.0\n */\nexport function buildHierarchy(\n rows: readonly unknown[],\n contributors: readonly HierarchyContributor[],\n meta: WeakMap<object, HierarchyRowMeta> = new WeakMap(),\n): unknown[] {\n const active: HierarchyContributor[] = [];\n for (const stage of ['structure', 'transform'] as const) {\n for (const c of contributors) {\n if (c.hierarchyStage === stage && c.beginHierarchy(rows)) active.push(c);\n }\n }\n if (active.length === 0) return [...rows];\n\n const out: unknown[] = [];\n const process = (nodes: HierarchyNode[], parent: HierarchyNode | null, depth: number): HierarchyNode[] => {\n const context = { parent: parent ? parent.row : null, parentKey: parent?.key ?? null, depth };\n for (const c of active) nodes = c.processSiblings(nodes, context);\n return nodes;\n };\n const emit = (nodes: HierarchyNode[], depth: number): void => {\n const setSize = nodes.length;\n for (let i = 0; i < setSize; i++) {\n const node = nodes[i];\n out.push(node.row);\n if (typeof node.row === 'object' && node.row !== null) {\n meta.set(node.row, { level: depth + 1, setSize, posInSet: i + 1 });\n }\n const children = node.children;\n if (node.expanded && children) {\n emit(node.shaped ? children : process(children, node, depth + 1), depth + 1);\n }\n }\n };\n\n const roots: HierarchyNode[] = new Array(rows.length);\n for (let i = 0; i < rows.length; i++) roots[i] = { row: rows[i] };\n emit(process(roots, null, 0), 0);\n\n const positionOf = (row: unknown) => (typeof row === 'object' && row !== null ? meta.get(row) : undefined);\n let shaped = false;\n for (const c of active) if (c.endHierarchy(out, positionOf)) shaped = true;\n if (!shaped) {\n for (const row of out) if (typeof row === 'object' && row !== null) meta.delete(row);\n }\n return out;\n}\n","/**\n * Hierarchy Plugin\n *\n * Owns the hierarchical row model shared by structure-contributing plugins.\n */\n\nimport type { PluginManifest } from '../../core/plugin/base-plugin';\nimport { BaseGridPlugin } from '../../core/plugin/base-plugin';\nimport type { RowElementInternal } from '../../core/types';\nimport { buildHierarchy } from './hierarchy';\nimport type { HierarchyContributor, HierarchyRowMeta } from './types';\n\n/** Attribute write that skips the DOM mutation when the value is unchanged (per-frame hot path). */\nfunction setAttrIfChanged(el: Element, name: string, value: number): void {\n const next = String(value);\n if (el.getAttribute(name) !== next) el.setAttribute(name, next);\n}\n\nfunction isContributor(plugin: unknown): plugin is HierarchyContributor & BaseGridPlugin {\n return typeof (plugin as Partial<HierarchyContributor>).processSiblings === 'function';\n}\n\nfunction processRowsPriority(plugin: BaseGridPlugin): number {\n return (plugin.constructor as typeof BaseGridPlugin).manifest?.hookPriority?.processRows ?? 0;\n}\n\n/**\n * Hierarchy Plugin for tbw-grid\n *\n * Builds one hierarchical row model from every attached structure contributor\n * — {@link https://toolboxjs.com/grid/plugins/tree/ | TreePlugin} discovers\n * child rows, {@link https://toolboxjs.com/grid/plugins/grouping-rows/ | GroupingRowsPlugin}\n * groups sibling lists — and announces each row's position with the WAI-ARIA\n * treegrid pattern (`aria-level` / `aria-setsize` / `aria-posinset`).\n *\n * Contributors know nothing about each other, so they compose: a grid with\n * both Tree and GroupingRows groups the children of every tree level.\n *\n * You never need to add this plugin yourself — TreePlugin and\n * GroupingRowsPlugin declare it as a dependency and the grid attaches it\n * automatically. It has no configuration.\n *\n * @example Group the children of every tree node\n * ```ts\n * import { TreePlugin } from '@toolbox-web/grid/plugins/tree';\n * import { GroupingRowsPlugin } from '@toolbox-web/grid/plugins/grouping-rows';\n *\n * grid.gridConfig = {\n * plugins: [\n * new TreePlugin({ childrenField: 'children' }),\n * new GroupingRowsPlugin({\n * // Leave the root level ungrouped, group every child level by kind\n * groupOn: (row, { depth }) => (depth > 0 ? row.kind : null),\n * }),\n * ],\n * };\n * ```\n *\n * @since 3.9.0\n */\nexport class HierarchyPlugin extends BaseGridPlugin {\n /** @internal */\n static override readonly manifest: PluginManifest = {\n modifiesRowStructure: true,\n };\n\n /** @internal */\n readonly name = 'hierarchy';\n\n #meta = new WeakMap<object, HierarchyRowMeta>();\n\n /** @internal */\n override detach(): void {\n // Restore the default `role=\"grid\"` (template default in `core/internal/dom-builder.ts`).\n this.gridElement?.querySelector('.rows-body')?.setAttribute('role', 'grid');\n this.#meta = new WeakMap();\n }\n\n /**\n * Build the row model for a contributor's `processRows` hook.\n *\n * Every contributor forwards its hook here; only the one that runs last in\n * the `processRows` pipeline builds the model (for all contributors at\n * once) — the earlier ones pass their rows through untouched.\n *\n * @example\n * ```ts\n * override processRows(rows: readonly unknown[]): unknown[] {\n * return this.grid.getPluginByName('hierarchy')?.process(rows, this) ?? [...rows];\n * }\n * ```\n *\n * @since 3.9.0\n */\n process(rows: readonly unknown[], caller: HierarchyContributor): unknown[] {\n const contributors = this.#contributors();\n if (!contributors.includes(caller as HierarchyContributor & BaseGridPlugin)) {\n this.#meta = new WeakMap();\n return buildHierarchy(rows, [caller], this.#meta);\n }\n if (contributors[contributors.length - 1] !== caller) return rows as unknown[];\n this.#meta = new WeakMap();\n return buildHierarchy(rows, contributors, this.#meta);\n }\n\n /**\n * Hierarchy position of a row in the current row model, or `undefined` when\n * the row is not rendered (e.g. collapsed under a parent).\n *\n * @example\n * ```ts\n * const meta = grid.getPluginByName('hierarchy')?.getRowMeta(grid.rows[0]);\n * console.log(meta?.level, meta?.posInSet, meta?.setSize);\n * ```\n *\n * @since 3.9.0\n */\n getRowMeta(row: unknown): HierarchyRowMeta | undefined {\n return typeof row === 'object' && row !== null ? this.#meta.get(row) : undefined;\n }\n\n /** @internal */\n override afterRender(): void {\n this.#applyAria();\n }\n\n /** @internal */\n override onScrollRender(): void {\n this.#applyAria();\n }\n\n /** Attached contributors, in `processRows` hook order. */\n #contributors(): Array<HierarchyContributor & BaseGridPlugin> {\n const plugins = (this.grid?._pluginManager?.getPlugins?.() ?? []) as readonly BaseGridPlugin[];\n return plugins.filter(isContributor).sort((a, b) => processRowsPriority(a) - processRowsPriority(b));\n }\n\n #applyAria(): void {\n if (this.#contributors().length === 0) return;\n const body = this.gridElement?.querySelector('.rows');\n if (!body) return;\n\n let hierarchical = false;\n for (const rowEl of body.querySelectorAll('.data-grid-row')) {\n const meta = this.getRowMeta((rowEl as RowElementInternal).__rowDataRef);\n if (!meta) {\n // Pooled row elements may carry a position from a previous row model.\n rowEl.removeAttribute('aria-level');\n rowEl.removeAttribute('aria-setsize');\n rowEl.removeAttribute('aria-posinset');\n continue;\n }\n hierarchical = true;\n setAttrIfChanged(rowEl, 'aria-level', meta.level);\n setAttrIfChanged(rowEl, 'aria-setsize', meta.setSize);\n setAttrIfChanged(rowEl, 'aria-posinset', meta.posInSet);\n }\n\n // `treegrid` only while the model has hierarchy, so per-row level/setsize/posinset are valid in context.\n const role = hierarchical ? 'treegrid' : 'grid';\n const rowsBody = this.gridElement?.querySelector('.rows-body');\n if (rowsBody && rowsBody.getAttribute('role') !== role) rowsBody.setAttribute('role', role);\n }\n}\n"],"mappings":"sUAkCA,SAAgB,EACd,EACA,EACA,EAA0C,IAAI,SAE9C,MAAM,EAAiC,GACvC,IAAK,MAAM,IAAS,CAAC,YAAa,aAChC,IAAK,MAAM,KAAK,EACV,EAAE,iBAAmB,GAAS,EAAE,eAAe,IAAO,EAAO,KAAK,GAG1E,GAAsB,IAAlB,EAAO,OAAc,MAAO,IAAI,GAEpC,MAAM,EAAiB,GACjB,EAAA,CAAW,EAAwB,EAA8B,KACrE,MAAM,EAAU,CAAE,OAAQ,EAAS,EAAO,IAAM,KAAM,UAAW,GAAQ,KAAO,KAAM,SACtF,IAAK,MAAM,KAAK,EAAQ,EAAQ,EAAE,gBAAgB,EAAO,GACzD,OAAO,GAEH,EAAA,CAAQ,EAAwB,KACpC,MAAM,EAAU,EAAM,OACtB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAS,IAAK,CAChC,MAAM,EAAO,EAAM,GACnB,EAAI,KAAK,EAAK,KACU,iBAAb,EAAK,KAAiC,OAAb,EAAK,KACvC,EAAK,IAAI,EAAK,IAAK,CAAE,MAAO,EAAQ,EAAG,UAAS,SAAU,EAAI,IAEhE,MAAM,EAAW,EAAK,SAClB,EAAK,UAAY,GACnB,EAAK,EAAK,OAAS,EAAW,EAAQ,EAAU,EAAM,EAAQ,GAAI,EAAQ,EAE9E,GAGI,EAAyB,IAAI,MAAM,EAAK,QAC9C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,EAAM,GAAK,CAAE,IAAK,EAAK,IAC7D,EAAK,EAAQ,EAAO,KAAM,GAAI,GAE9B,MAAM,EAAc,GAAiC,iBAAR,GAA4B,OAAR,EAAe,EAAK,IAAI,QAAO,EAChG,IAAI,GAAS,EACb,IAAK,MAAM,KAAK,EAAY,EAAE,aAAa,EAAK,KAAa,GAAS,GACtE,IAAK,EACE,IAAA,MAAM,KAAO,EAAwB,iBAAR,GAA4B,OAAR,GAAc,EAAK,OAAO,GAElF,OAAO,CACT,CClEA,SAAS,EAAiB,EAAa,EAAc,GACnD,MAAM,EAAO,OAAO,GAChB,EAAG,aAAa,KAAU,GAAM,EAAG,aAAa,EAAM,EAC5D,CAEA,SAAS,EAAc,GACrB,MAA4E,mBAA7D,EAAyC,eAC1D,CAEA,SAAS,EAAoB,GAC3B,OAAQ,EAAO,YAAsC,UAAU,cAAc,aAAe,CAC9F,8DAoCA,IAAa,EAAb,cAAqC,EAAA,eAEnC,gBAAoD,CAClD,sBAAsB,GAIxB,KAAgB,YAEhB,GAAQ,IAAI,QAGZ,MAAA,GAEE,KAAK,aAAa,cAAc,eAAe,aAAa,OAAQ,QACpE,MAAK,EAAQ,IAAI,OACnB,CAkBA,OAAA,CAAQ,EAA0B,GAChC,MAAM,EAAe,MAAK,IAC1B,OAAK,EAAa,SAAS,GAIvB,EAAa,EAAa,OAAS,KAAO,EAAe,GAC7D,MAAK,EAAQ,IAAI,QACV,EAAe,EAAM,EAAc,MAAK,KAL7C,MAAK,EAAQ,IAAI,QACV,EAAe,EAAM,CAAC,GAAS,MAAK,GAK/C,CAcA,UAAA,CAAW,GACT,MAAsB,iBAAR,GAA4B,OAAR,EAAe,MAAK,EAAM,IAAI,QAAO,CACzE,CAGA,WAAA,GACE,MAAK,GACP,CAGA,cAAA,GACE,MAAK,GACP,CAGA,EAAA,GAEE,OADiB,KAAK,MAAM,gBAAgB,gBAAkB,IAC/C,OAAO,GAAe,KAAA,CAAM,EAAG,IAAM,EAAoB,GAAK,EAAoB,GACnG,CAEA,EAAA,GACE,GAAoC,IAAhC,MAAK,IAAgB,OAAc,OACvC,MAAM,EAAO,KAAK,aAAa,cAAc,SAC7C,IAAK,EAAM,OAEX,IAAI,GAAe,EACnB,IAAK,MAAM,KAAS,EAAK,iBAAiB,kBAAmB,CAC3D,MAAM,EAAO,KAAK,WAAY,EAA6B,cACtD,GAOL,GAAe,EACf,EAAiB,EAAO,aAAc,EAAK,OAC3C,EAAiB,EAAO,eAAgB,EAAK,SAC7C,EAAiB,EAAO,gBAAiB,EAAK,YAR5C,EAAM,gBAAgB,cACtB,EAAM,gBAAgB,gBACtB,EAAM,gBAAgB,iBAO1B,CAGA,MAAM,EAAO,EAAe,WAAa,OACnC,EAAW,KAAK,aAAa,cAAc,cAC7C,GAAY,EAAS,aAAa,UAAY,GAAM,EAAS,aAAa,OAAQ,EACxF"}
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("../../core/constants"),require("../../core/internal/drag-drop-registry"),require("../../core/internal/keyboard"),require("../../core/plugin/base-plugin")):"function"==typeof define&&define.amd?define(["exports","../../core/constants","../../core/internal/drag-drop-registry","../../core/internal/keyboard","../../core/plugin/base-plugin"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TbwGridPlugin_rowDragDrop={},e.TbwGrid,e.TbwGrid,e.TbwGrid,e.TbwGrid)}(this,function(e,t,r,o,i){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});var n=null;function s(){return n}function a(){n=null}var d="application/x-tbw-grid-rows+json";function l(e){const t=e.match(/^application\/x-tbw-grid-rows\+json;zone=(.*)$/);if(!t)return null;try{return decodeURIComponent(t[1])}catch{return t[1]}}function c(e){return JSON.stringify(e)}function g(e,t,r,o){if(!e)return{overIndex:null,insertIndex:o,isBefore:!1};const i=r(e);if(i<0)return{overIndex:null,insertIndex:o,isBefore:!1};const n=e.getBoundingClientRect(),s=t<n.top+n.height/2;return{overIndex:i,insertIndex:s?i:i+1,isBefore:s}}function u(){return"function"==typeof HTMLElement.prototype?.showPopover}function h(e,t){let r=null,o=!1,i=!1;const n=new AbortController;function s(){o&&r&&(o=!1,u()&&r.hidePopover(),r.hidden=!0)}return document.addEventListener("pointerdown",e=>{o&&r&&!e.composedPath().includes(r)&&s()},{capture:!0,signal:n.signal}),document.addEventListener("keydown",e=>{"Escape"===e.key&&s()},{capture:!0,signal:n.signal}),{get element(){return r},open(a,d,l){if(i||0===l.length)return;r||(r=function(){const r=document.createElement("div");return r.id=e,r.className=t,r.setAttribute("popover","manual"),r.setAttribute("role","group"),r.hidden=!0,r.addEventListener("focusout",e=>{const t=e.relatedTarget;t instanceof Node&&!r.contains(t)&&s()},{signal:n.signal}),r}());const c=a.closest("tbw-grid, [data-tbw-grid]")??document.body;r.parentNode!==c&&c.appendChild(r),r.setAttribute("aria-label",d),r.replaceChildren();for(const e of l){const o=document.createElement("button");o.type="button",o.className=`${t}-item`,o.textContent=e.label,o.disabled=!0===e.disabled,o.addEventListener("click",()=>{s(),e.run()}),r.appendChild(o)}r.hidden=!1,!o&&u()&&r.showPopover(),o=!0,function(e){if(!r)return;const t=e.getBoundingClientRect(),o=r.getBoundingClientRect(),i=Math.max(4,Math.min(t.left,window.innerWidth-o.width-4)),n=t.bottom+6,s=n+o.height<=window.innerHeight?n:Math.max(4,t.top-6-o.height);r.style.left=`${Math.round(i)}px`,r.style.top=`${Math.round(s)}px`}(a),r.querySelector("button:not([disabled])")?.focus()},close:s,dispose(){i=!0,s(),n.abort(),r?.remove(),r=null}}}var p="__tbw_row_drag",f=null,w=new Set;function m(){if("undefined"==typeof BroadcastChannel)return null;if(f)return f;try{(f=new BroadcastChannel("tbw-row-drag-drop")).addEventListener("message",e=>{const t=e.data;if(t&&"tbw-row-drag-drop:transfer"===t.type)for(const r of Array.from(w))try{r(t)}catch{}})}catch{f=null}return f}var b=new Set;var v=class e extends i.BaseGridPlugin{name="rowDragDrop";styles='@layer tbw-plugins{[data-field=__tbw_row_drag]{justify-content:center;align-items:center;display:flex}.dg-row-drag-handle{cursor:grab;-webkit-user-select:none;user-select:none;min-width:1em;min-height:1em;color:var(--tbw-row-reorder-handle-color,var(--tbw-color-fg-muted));transition:color var(--tbw-transition-duration,.12s) var(--tbw-transition-ease,ease);font-size:var(--tbw-font-size,1em);letter-spacing:-2px;justify-content:center;align-items:center;display:flex;position:relative}.dg-row-drag-handle:after{content:"";inline-size:var(--tbw-touch-target-min,24px);block-size:var(--tbw-touch-target-min,24px);position:absolute;inset-block-start:50%;inset-inline-start:50%;translate:-50% -50%}.dg-row-drag-handle:hover{color:var(--tbw-row-reorder-handle-hover,var(--tbw-color-fg))}.dg-row-drag-handle:active{cursor:grabbing}@media (hover:none){.dg-row-drag-handle{color:var(--tbw-row-reorder-handle-hover,var(--tbw-color-fg))}}@media (pointer:coarse){.dg-row-drag-handle{min-width:var(--tbw-touch-target-min,24px);min-height:var(--tbw-touch-target-min,24px)}}.data-grid-row.dragging{opacity:.6}.data-grid-row[draggable=true]{cursor:grab}.data-grid-row[draggable=true].dragging{cursor:grabbing}.tbw-row-drag-clone{pointer-events:none;position:fixed;top:-10000px;left:-10000px}.tbw-row-drag-count{pointer-events:none;background:var(--tbw-row-reorder-indicator,var(--tbw-color-accent));color:var(--tbw-color-accent-fg);box-shadow:0 2px 6px var(--tbw-color-shadow);z-index:9999;border-radius:999px;padding:2px 8px;font:600 12px/1.4 system-ui,sans-serif;position:fixed;top:-1000px;left:-1000px}.data-grid-row.drop-target{position:relative}.data-grid-row.drop-target.drop-before:before,.data-grid-row.drop-target.drop-after:after{content:"";height:var(--tbw-drop-indicator-width,2px);background-color:var(--tbw-drop-indicator-color,var(--tbw-row-reorder-indicator,var(--tbw-color-accent)));z-index:10;pointer-events:none;position:absolute;left:0;right:0}.data-grid-row.drop-target.drop-before:before{top:0}.data-grid-row.drop-target.drop-after:after{bottom:0}.tbw-grid--drop-target-active{outline:2px dashed var(--tbw-drop-indicator-color,var(--tbw-color-accent));outline-offset:-2px}.tbw-grid--drop-target-rejected{outline:2px dashed var(--tbw-color-danger);outline-offset:-2px}.tbw-grid--auto-scrolling{cursor:ns-resize}.data-grid-row.flip-animating{transition:transform var(--tbw-animation-duration,.2s) ease-out;will-change:transform;z-index:1}.tbw-row-move-menu{min-width:10rem;padding:var(--tbw-spacing-xs,.25rem);background:var(--tbw-color-panel-bg,light-dark(#fff,#1f1f1f));color:var(--tbw-color-fg,light-dark(#1a1a1a,#f0f0f0));border:1px solid var(--tbw-color-border,light-dark(#d0d0d0,#3a3a3a));border-radius:var(--tbw-border-radius,.25rem);box-shadow:var(--tbw-shadow-md,0 4px 12px #00000040);font:inherit;z-index:10001;flex-direction:column;margin:0;display:flex;position:fixed}.tbw-row-move-menu[hidden]{display:none}.tbw-row-move-menu-item{min-height:var(--tbw-touch-target-min,24px);padding:var(--tbw-spacing-xs,.25rem) var(--tbw-spacing-sm,.5rem);text-align:start;border-radius:min(var(--tbw-border-radius,.25rem), 6px);color:inherit;font:inherit;cursor:pointer;background:0 0;border:none}.tbw-row-move-menu-item:hover:not(:disabled){background:var(--tbw-color-row-hover,light-dark(#f0f0f0,#2a2a2a))}.tbw-row-move-menu-item:disabled{opacity:.5;cursor:default}}';static manifest={events:[{type:"row-move",description:"Intra-grid row reorder.",cancelable:!0},{type:"row-drag-start",description:"Cross-grid drag started on this grid.",cancelable:!0},{type:"row-drag-end",description:"Drag finished on this grid (regardless of outcome)."},{type:"row-drop",description:"Cross-grid drop landing on this grid.",cancelable:!0},{type:"row-transfer",description:"Cross-grid transfer completed (fires on both grids)."}]};get defaultConfig(){return{enableKeyboard:!0,dragHandlePosition:"left",dragHandleWidth:40,debounceMs:150,animation:"flip",operation:"move",autoScroll:!0,dragFrom:"handle"}}shouldRenderDragHandle(){const e=this.config.showDragHandle;return!1!==e&&(!0===e||"row"!==this.config.dragFrom)}get rowIsDraggable(){return"row"===this.config.dragFrom||"both"===this.config.dragFrom}get animationType(){return!!this.isAnimationEnabled&&(void 0!==this.config.animation?this.config.animation:"flip")}isDragging=!1;draggedRowIndex=null;draggedRows=[];draggedIndices=[];dragSessionId=null;dragAccepted=!1;dropRowIndex=null;pendingMove=null;debounceTimer=null;lastFocusCol=0;autoScroller=null;gridId="";remoteTransferListener=e=>this.onRemoteTransfer(e);moveMenu=null;get internalGrid(){return this.grid}attach(e){super.attach(e);const t=this.gridElement;var o;t&&(this.gridId=t.id||`tbw-grid-${(0,r.newDragSessionId)().slice(0,8)}`,t.id||(t.id=this.gridId),this.setupDelegatedDragListeners(),o=this.remoteTransferListener,w.add(o),m(),b.add(this))}detach(){this.clearDebounceTimer(),this.autoScroller?.stop(),this.autoScroller=null,function(e){if(w.delete(e),0===w.size&&f){try{f.close()}catch{}f=null}}(this.remoteTransferListener),b.delete(this),this.moveMenu?.dispose(),this.moveMenu=null,this.dragSessionId&&(0,r.clearDragSession)(this.dragSessionId),a(),this.resetDragState(),super.detach()}processColumns(e){if(!this.shouldRenderDragHandle())return[...e];const t={field:p,header:"",width:this.config.dragHandleWidth??40,resizable:!1,sortable:!1,filterable:!1,lockPosition:!0,utility:!0,viewRenderer:()=>{const e=document.createElement("div");return e.className="dg-row-drag-handle",e.setAttribute("aria-label","Drag to reorder, or activate for move options"),e.setAttribute("role","button"),e.setAttribute("tabindex","-1"),e.draggable=!0,e.addEventListener("click",t=>{t.stopPropagation(),this.openMoveMenu(e)}),this.setIcon(e,"dragHandle"),e}};return"right"===this.config.dragHandlePosition?[...e,t]:[t,...e]}afterRender(){this.applyRowDraggable()}onScrollRender(){this.applyRowDraggable()}applyRowDraggable(){const e=this.internalGrid._bodyEl;if(!e)return;const t=this.rowIsDraggable,r=e.querySelectorAll(".data-grid-row");for(const o of r)t?"true"!==o.getAttribute("draggable")&&o.setAttribute("draggable","true"):o.hasAttribute("draggable")&&o.removeAttribute("draggable")}onKeyDown(e){if(!this.config.enableKeyboard)return;if(!e.ctrlKey||"ArrowUp"!==e.key&&"ArrowDown"!==e.key)return;const t=this.internalGrid,r=t._focusRow,o=t._rows??this.sourceRows;if(r<0||r>=o.length)return;const i="up"==("ArrowUp"===e.key?"up":"down")?r-1:r+1;if(i<0||i>=o.length)return;const n=o[r];return this.canMoveRow(r,i)?(this.handleKeyboardMove(n,r,i,t._focusCol),e.preventDefault(),e.stopPropagation(),!0):void 0}onCellClick(){this.flushPendingMove()}moveRow(e,t){const r=[...this.sourceRows];e<0||e>=r.length||t<0||t>=r.length||e!==t&&this.canMoveRow(e,t)&&this.executeIntraGridMove(r[e],e,t,"keyboard")}canMoveRow(e,t){const r=this.internalGrid._rows??this.sourceRows;if(e<0||e>=r.length)return!1;if(t<0||t>=r.length)return!1;if(e===t)return!1;const o=r[e],i=this.grid?.query?.("canMoveRow",o);if(Array.isArray(i)&&i.includes(!1))return!1;if(this.config.canDrag&&!this.config.canDrag(o,e))return!1;if(this.config.canDrop){const r={sessionId:"intra",sourceGridId:this.gridId,dropZone:this.config.dropZone??"",rows:[o],rowIndices:[e],operation:"move"};if(!this.config.canDrop(r,t))return!1}return!0}setupDelegatedDragListeners(){const e=this.gridElement;if(!e)return;const t=this.disconnectSignal;e.addEventListener("dragstart",e=>this.onDragStart(e),{signal:t}),e.addEventListener("dragend",()=>this.onDragEnd(),{signal:t}),e.addEventListener("dragover",e=>this.onDragOver(e),{signal:t}),e.addEventListener("dragleave",e=>this.onDragLeave(e),{signal:t}),e.addEventListener("drop",e=>this.onDrop(e),{signal:t})}onDragStart(e){const o=e.target;if(!o)return;const i=o.closest(".dg-row-drag-handle");let s=null,a=!1;if(i)s=i.closest(".data-grid-row"),a=!0;else if(this.rowIsDraggable){if(this.isInteractiveDragOrigin(o))return;s=o.closest(".data-grid-row")}if(!s)return;const l=this.getRowIndex(s);if(l<0)return;const{rows:g,indices:u}=this.resolveDraggedRows(l);if(0===g.length)return;if(this.config.canDrag&&!this.config.canDrag(g[0],l))return void e.preventDefault();const h=this.config.operation??"move",p=this.config.dropZone??"",f=(0,r.newDragSessionId)(),w={rows:g,indices:u,operation:h,dropZone:p};if(this.emitCancelable("row-drag-start",w))return void e.preventDefault();this.isDragging=!0,this.draggedRowIndex=l,this.draggedRows=g,this.draggedIndices=u,this.dragSessionId=f,this.dragAccepted=!1;const m=this.config.serializeRow??(e=>e),b={sessionId:f,sourceGridId:this.gridId,dropZone:p,rows:g.map(m),rowIndices:u,operation:h};if(e.dataTransfer){e.dataTransfer.effectAllowed="copy"===h?"copyMove":"move";try{e.dataTransfer.setData(d,c(b)),p&&e.dataTransfer.setData(`${d};zone=${encodeURIComponent(p)}`,c(b)),e.dataTransfer.setData("text/plain",function(e,t){const r=t.filter(e=>!e.utility&&"string"==typeof e.field&&""!==e.field),o=[];for(const i of e){const e=r.map(e=>{const t=i[e.field];return null==t?"":String(t).replace(/[\t\r\n]+/g," ")});o.push(e.join("\t"))}return o.join("\n")}(g,this.columns))}catch{}if(g.length>1){const t=document.createElement("div");t.className="tbw-row-drag-count",t.textContent=`${g.length} rows`,document.body.appendChild(t);try{e.dataTransfer.setDragImage(t,10,10)}catch{}setTimeout(()=>t.remove(),0)}else this.attachRowCloneDragImage(e,s,a?i:null)}(0,r.registerDragSession)(f,g),function(e,t){n={sessionId:e,payload:t}}(f,b),s.classList.add(t.GridClasses.DRAGGING),this.gridElement.classList.add("tbw-grid--drag-source")}static INTERACTIVE_DRAG_SELECTORS='input,textarea,select,button,a,[contenteditable=""],[contenteditable="true"],.dg-cell-editor,.tbw-checkbox-cell';isInteractiveDragOrigin(t){return null!==t.closest(e.INTERACTIVE_DRAG_SELECTORS)}attachRowCloneDragImage(e,t,r){if(!e.dataTransfer)return;const o=t.getBoundingClientRect(),i=t.cloneNode(!0);i.classList.add("tbw-row-drag-clone"),i.classList.remove("dragging","drop-target","drop-before","drop-after","flip-animating","row-focus"),i.removeAttribute("aria-selected"),i.style.width=`${o.width}px`,i.style.height=`${o.height}px`,this.gridElement.appendChild(i);let n=e.clientX-o.left,s=e.clientY-o.top;if(r){const e=r.getBoundingClientRect();n=e.left-o.left+e.width/2,s=e.top-o.top+e.height/2}n=Math.max(0,Math.min(o.width,n)),s=Math.max(0,Math.min(o.height,s));try{e.dataTransfer.setDragImage(i,n,s)}catch{}setTimeout(()=>i.remove(),0)}onDragOver(e){const t=e.dataTransfer;if(!t)return;const r=t.types?Array.from(t.types):[];if(!function(e){for(const t of e)if("application/x-tbw-grid-rows+json"===t||t.startsWith("application/x-tbw-grid-rows+json;"))return!0;return!1}(r)&&!this.isDragging)return;const o=this.config.dropZone??"",i=s(),n=this.isDragging&&i?.payload.sourceGridId===this.gridId;if(!n){if(!o)return;if(!(function(e,t){for(const r of e)if(l(r)===t)return r;return null}(r,o)||i&&i.payload.dropZone===o))return}e.preventDefault(),t&&(t.dropEffect=i?.payload.operation??this.config.operation??"move");const a=e.target.closest(".data-grid-row"),d=this.internalGrid._rows??[],c=g(a,e.clientY,e=>this.getRowIndex(e),d.length);if(n&&null!==c.overIndex&&c.overIndex===this.draggedRowIndex)this.clearDropTargetClasses();else{if(i&&this.config.canDrop){const e=this.config.canDrop(i.payload,c.insertIndex);if(this.gridElement.classList.toggle("tbw-grid--drop-target-active",e),this.gridElement.classList.toggle("tbw-grid--drop-target-rejected",!e),!e)return void this.clearDropTargetClasses()}else this.gridElement.classList.add("tbw-grid--drop-target-active");this.dropRowIndex=c.insertIndex,this.applyDropPositionClasses(a,c.isBefore),!1!==this.config.autoScroll&&(this.ensureAutoScroller(),this.autoScroller?.onPointerMove(e.clientY))}}onDragLeave(e){const t=e.target.closest(".data-grid-row");t&&t.classList.remove("drop-target","drop-before","drop-after"),e.currentTarget&&!this.gridElement.contains(e.relatedTarget)&&(this.gridElement.classList.remove("tbw-grid--drop-target-active","tbw-grid--drop-target-rejected"),this.autoScroller?.stop())}onDrop(e){e.preventDefault(),this.autoScroller?.stop(),this.gridElement.classList.remove("tbw-grid--drop-target-active","tbw-grid--drop-target-rejected"),this.clearDropTargetClasses();const t=e.dataTransfer;if(!t)return;let o=s()?.payload??null,i=null;if(o){const e=(0,r.lookupDragSession)(o.sessionId);e&&(i=e)}else{if(o=function(e){if(!e)return null;try{const t=JSON.parse(e);if("string"!=typeof t?.sessionId||"string"!=typeof t?.sourceGridId||"string"!=typeof t?.dropZone||!Array.isArray(t?.rows)||!Array.isArray(t?.rowIndices)||"move"!==t.operation&&"copy"!==t.operation)return null;for(const e of t.rowIndices)if("number"!=typeof e||!Number.isInteger(e)||e<0)return null;return t}catch{return null}}(t.getData(d)),o){const e=(0,r.lookupDragSession)(o.sessionId);e&&(i=e)}}if(!o)return;const n=e.target.closest(".data-grid-row"),a=this.internalGrid._rows??[],l=g(n,e.clientY,e=>this.getRowIndex(e),a.length);let c=this.dropRowIndex??l.insertIndex;const u=o.sourceGridId===this.gridId,h=this.config.dropZone??"";if(u){const e=o.rowIndices[0];if(1===o.rowIndices.length&&c>e&&c--,e===c)return;const t=(i??o.rows)[0];if(!this.canMoveRow(e,c))return;return void this.executeIntraGridMove(t,e,c,"drag")}if(!h||h!==o.dropZone)return;if(this.config.canDrop&&!this.config.canDrop(o,c))return this.gridElement.classList.add("tbw-grid--drop-target-rejected"),void setTimeout(()=>this.gridElement.classList.remove("tbw-grid--drop-target-rejected"),200);const p=this.config.deserializeRow??(e=>e),f=i??o.rows.map(e=>p(e)),w={payload:o,sourceGridId:o.sourceGridId,targetIndex:c,operation:o.operation};if(this.emitCancelable("row-drop",w))return;const b=[...a];b.splice(c,0,...f),this.grid.rows=b;const v=this.findPeerOnGrid(o.sourceGridId);if("move"===o.operation&&v){const e=document.getElementById(o.sourceGridId);if(e){const t=(e._rows??e.rows??[]).slice(),r=[...o.rowIndices].sort((e,t)=>t-e);for(const e of r)e>=0&&e<t.length&&t.splice(e,1);e.rows=t}}v&&(v.dragAccepted=!0);const I={rows:f,fromGridId:o.sourceGridId,toGridId:this.gridId,fromIndices:o.rowIndices,toIndex:c,operation:o.operation};this.emit("row-transfer",I),v?v.emitTransfer(I):function(e){const t=m();if(t)try{t.postMessage(e)}catch{}}({type:"tbw-row-drag-drop:transfer",sessionId:o.sessionId,sourceGridId:o.sourceGridId,toGridId:this.gridId,dropZone:h,rowIndices:o.rowIndices,toIndex:c,operation:o.operation,serializedRows:o.rows})}onRemoteTransfer(e){if(e.sourceGridId!==this.gridId)return;const t=this.config.dropZone??"";if(!t||e.dropZone!==t)return;const r=this.config.deserializeRow??(e=>e),o=e.serializedRows.map(e=>r(e));if("move"===e.operation){const t=(this.internalGrid._rows??this.sourceRows).slice(),r=[...e.rowIndices].sort((e,t)=>t-e);for(const e of r)e>=0&&e<t.length&&t.splice(e,1);this.grid.rows=t}this.dragAccepted=!0,this.emit("row-transfer",{rows:o,fromGridId:e.sourceGridId,toGridId:e.toGridId,fromIndices:e.rowIndices,toIndex:e.toIndex,operation:e.operation})}onDragEnd(){if(this.dragSessionId&&(0,r.clearDragSession)(this.dragSessionId),a(),this.autoScroller?.stop(),this.gridElement.classList.remove("tbw-grid--drag-source"),this.isDragging){const e={rows:this.draggedRows,indices:this.draggedIndices,accepted:this.dragAccepted};this.emit("row-drag-end",e)}this.clearDragClasses(),this.resetDragState()}emitTransfer(e){this.emit("row-transfer",e)}findPeerOnGrid(e){const t=document.getElementById(e);return t?.getPluginByName?t.getPluginByName("rowDragDrop")??null:null}peersInDropZone(){const e=this.config.dropZone??"";if(!e)return[];const t=[];for(const r of b){const o=r;o!==this&&((o.config.dropZone??"")===e&&t.push(o))}return t}get gridLabel(){const e=this.gridElement;return e?.getAttribute("aria-label")||e?.id||"grid"}openMoveMenu(e){const t=e.closest(".data-grid-row");if(!t)return;const r=this.getRowIndex(t);if(r<0)return;const o=this.internalGrid._rows??this.sourceRows,i=[{label:"Move up",disabled:0===r||!this.canMoveRow(r,r-1),run:()=>this.moveRow(r,r-1)},{label:"Move down",disabled:r>=o.length-1||!this.canMoveRow(r,r+1),run:()=>this.moveRow(r,r+1)},{label:"Move to top",disabled:0===r||!this.canMoveRow(r,0),run:()=>this.moveRow(r,0)},{label:"Move to bottom",disabled:r>=o.length-1||!this.canMoveRow(r,o.length-1),run:()=>this.moveRow(r,o.length-1)}],n="copy"===(this.config.operation??"move")?"Copy to":"Send to";for(const s of this.peersInDropZone())i.push({label:`${n} ${s.gridLabel}`,run:()=>this.transferToPeer(s,r)});this.moveMenu??=h("tbw-row-move-menu","tbw-row-move-menu"),this.moveMenu.open(e,`Move row ${r+1}`,i)}transferToPeer(e,t){const o=this.config.dropZone??"";if(!o)return;const{rows:i,indices:n}=this.resolveDraggedRows(t);if(0===i.length)return;if(this.config.canDrag&&!this.config.canDrag(i[0],t))return;const s=this.config.operation??"move";if(this.emitCancelable("row-drag-start",{rows:i,indices:n,operation:s,dropZone:o}))return;const a=this.config.serializeRow??(e=>e),d={sessionId:(0,r.newDragSessionId)(),sourceGridId:this.gridId,dropZone:o,rows:i.map(a),rowIndices:n,operation:s},l=e.acceptTransfer(d,i);if(l<0)return;if("move"===s){const e=[...this.internalGrid._rows??this.sourceRows];for(const t of[...n].sort((e,t)=>t-e))t>=0&&t<e.length&&e.splice(t,1);this.grid.rows=e}const c={rows:i,fromGridId:this.gridId,toGridId:e.gridId,fromIndices:n,toIndex:l,operation:s};e.emitTransfer(c),this.emit("row-transfer",c)}acceptTransfer(e,t){const r=this.config.dropZone??"";if(!r||r!==e.dropZone)return-1;const o=this.internalGrid._rows??this.sourceRows,i=o.length;if(this.config.canDrop&&!this.config.canDrop(e,i))return-1;const n={payload:e,sourceGridId:e.sourceGridId,targetIndex:i,operation:e.operation};return this.emitCancelable("row-drop",n)?-1:(this.grid.rows=[...o,...t],i)}resolveDraggedRows(e){const t=this.internalGrid._rows??this.sourceRows,r=t[e],o=this.grid?.getPluginByName?.("selection");if(o?.getSelectedRowIndices){const r=o.getSelectedRowIndices();if(r.includes(e)&&r.length>1){const e=[...r].sort((e,t)=>e-t);return{rows:e.map(e=>t[e]),indices:e}}}return{rows:[r],indices:[e]}}ensureAutoScroller(){if(this.autoScroller)return;const e=this.gridElement.querySelector(".rows-viewport");if(!e)return;const t="object"==typeof this.config.autoScroll?this.config.autoScroll:void 0;this.autoScroller=function(e,t={},r){const o=t.edgeSize??60,i=t.speed??8,n=t.maxSpeed??24;let s=null,a=null,d=!1;const l=e=>{e!==d&&(d=e,r?.(e))},c=()=>{if(s=null,null===a)return void l(!1);const t=e.getBoundingClientRect();let r=0;if(a<t.top+o){const e=1-Math.max(0,a-t.top)/o;r=-Math.round(i+(n-i)*e)}else if(a>t.bottom-o){const e=1-Math.max(0,t.bottom-a)/o;r=Math.round(i+(n-i)*e)}if(0===r)return void l(!1);const d=e.scrollTop;e.scrollTop=d+r,e.scrollTop!==d?(l(!0),s=requestAnimationFrame(c)):l(!1)};return{onPointerMove(e){a=e,null===s&&(s=requestAnimationFrame(c))},stop(){null!==s&&(cancelAnimationFrame(s),s=null),a=null,l(!1)},get isScrolling(){return d}}}(e,t,e=>{this.gridElement.classList.toggle("tbw-grid--auto-scrolling",e)})}applyDropPositionClasses(e,t){this.clearDropTargetClasses(),e&&(e.classList.add("drop-target"),e.classList.toggle("drop-before",t),e.classList.toggle("drop-after",!t))}clearDropTargetClasses(){this.gridElement?.querySelectorAll(".data-grid-row.drop-target").forEach(e=>{e.classList.remove("drop-target","drop-before","drop-after")})}clearDragClasses(){this.gridElement?.querySelectorAll(".data-grid-row").forEach(e=>{e.classList.remove(t.GridClasses.DRAGGING,"drop-target","drop-before","drop-after")})}resetDragState(){this.isDragging=!1,this.draggedRowIndex=null,this.draggedRows=[],this.draggedIndices=[],this.dragSessionId=null,this.dragAccepted=!1,this.dropRowIndex=null,this.pendingMove=null}getRowIndex(e){const t=e.querySelector(".cell[data-row]");return t?parseInt(t.getAttribute("data-row")??"-1",10):-1}clearDebounceTimer(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null)}handleKeyboardMove(e,t,r,i){this.pendingMove?this.pendingMove.currentIndex=r:this.pendingMove={originalIndex:t,currentIndex:r,row:e},this.lastFocusCol=i;const n=this.internalGrid,s=[...n._rows??this.sourceRows],[a]=s.splice(t,1);s.splice(r,0,a),n._rows=s,n._focusRow=r,n._focusCol=i,n.refreshVirtualWindow(!0),(0,o.ensureCellVisible)(n),this.clearDebounceTimer(),this.debounceTimer=setTimeout(()=>this.flushPendingMove(),this.config.debounceMs??300)}flushPendingMove(){if(this.clearDebounceTimer(),!this.pendingMove)return;const{originalIndex:e,currentIndex:t,row:r}=this.pendingMove;if(this.pendingMove=null,e===t)return;const i=this.internalGrid,n={row:r,fromIndex:e,toIndex:t,rows:[...i._rows??this.sourceRows],source:"keyboard"};this.emitCancelable("row-move",n)&&(i._rows=[...this.sourceRows],i._focusRow=e,i._focusCol=this.lastFocusCol,i.refreshVirtualWindow(!0),(0,o.ensureCellVisible)(i))}executeIntraGridMove(e,t,r,o){const i=[...this.sourceRows],[n]=i.splice(t,1);i.splice(r,0,n);const s={row:e,fromIndex:t,toIndex:r,rows:i,source:o};if(!this.emitCancelable("row-move",s))if("flip"===this.animationType&&this.gridElement){const e=this.captureRowPositions();this.grid.rows=i,requestAnimationFrame(()=>{this.gridElement.offsetHeight,this.animateFLIP(e,t,r)})}else this.grid.rows=i}captureRowPositions(){const e=new Map;return this.gridElement?.querySelectorAll(".data-grid-row").forEach(t=>{const r=this.getRowIndex(t);r>=0&&e.set(r,t.getBoundingClientRect().top)}),e}animateFLIP(e,t,r){const o=this.gridElement;if(!o||0===e.size)return;const i=Math.min(t,r),n=Math.max(t,r),s=[];if(o.querySelectorAll(".data-grid-row").forEach(o=>{const a=o,d=this.getRowIndex(a);if(d<0||d<i||d>n)return;let l;l=d===r?t:t<r?d+1:d-1;const c=e.get(l);if(void 0===c)return;const g=c-a.getBoundingClientRect().top;Math.abs(g)>1&&s.push({el:a,deltaY:g})}),0===s.length)return;s.forEach(({el:e,deltaY:t})=>{e.style.transform=`translateY(${t}px)`}),o.offsetHeight;const a=this.animationDuration;requestAnimationFrame(()=>{s.forEach(({el:e})=>{e.classList.add("flip-animating"),e.style.transform=""}),setTimeout(()=>{s.forEach(({el:e})=>{e.style.transform="",e.classList.remove("flip-animating")})},a+50)})}};e.ROW_DRAG_HANDLE_FIELD=p,e.RowDragDropPlugin=v});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("../../core/constants"),require("../../core/internal/drag-drop-registry"),require("../../core/internal/keyboard"),require("../../core/plugin/base-plugin")):"function"==typeof define&&define.amd?define(["exports","../../core/constants","../../core/internal/drag-drop-registry","../../core/internal/keyboard","../../core/plugin/base-plugin"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TbwGridPlugin_rowDragDrop={},e.TbwGrid,e.TbwGrid,e.TbwGrid,e.TbwGrid)}(this,function(e,t,r,o,i){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});function n(){return"function"==typeof HTMLElement.prototype?.showPopover}function s(e,t){let r=null,o=!1,i=!1;const s=new AbortController;function a(){o&&r&&(o=!1,n()&&r.hidePopover(),r.hidden=!0)}return document.addEventListener("pointerdown",e=>{o&&r&&!e.composedPath().includes(r)&&a()},{capture:!0,signal:s.signal}),document.addEventListener("keydown",e=>{"Escape"===e.key&&a()},{capture:!0,signal:s.signal}),{get element(){return r},open(d,l,c){if(i||0===c.length)return;r||(r=function(){const r=document.createElement("div");return r.id=e,r.className=t,r.setAttribute("popover","manual"),r.setAttribute("role","group"),r.hidden=!0,r.addEventListener("focusout",e=>{const t=e.relatedTarget;t instanceof Node&&!r.contains(t)&&a()},{signal:s.signal}),r}());const g=d.closest("tbw-grid, [data-tbw-grid]")??document.body;r.parentNode!==g&&g.appendChild(r),r.setAttribute("aria-label",l),r.replaceChildren();for(const e of c){const o=document.createElement("button");o.type="button",o.className=`${t}-item`,o.textContent=e.label,o.disabled=!0===e.disabled,o.addEventListener("click",()=>{a(),e.run()}),r.appendChild(o)}r.hidden=!1,!o&&n()&&r.showPopover(),o=!0,function(e){if(!r)return;const t=e.getBoundingClientRect(),o=r.getBoundingClientRect(),i=Math.max(4,Math.min(t.left,window.innerWidth-o.width-4)),n=t.bottom+6,s=n+o.height<=window.innerHeight?n:Math.max(4,t.top-6-o.height);r.style.left=`${Math.round(i)}px`,r.style.top=`${Math.round(s)}px`}(d),r.querySelector("button:not([disabled])")?.focus()},close:a,dispose(){i=!0,a(),s.abort(),r?.remove(),r=null}}}var a=null;function d(){return a}function l(){a=null}var c="application/x-tbw-grid-rows+json";function g(e){const t=e.match(/^application\/x-tbw-grid-rows\+json;zone=(.*)$/);if(!t)return null;try{return decodeURIComponent(t[1])}catch{return t[1]}}function u(e){return JSON.stringify(e)}function h(e,t,r,o){if(!e)return{overIndex:null,insertIndex:o,isBefore:!1};const i=r(e);if(i<0)return{overIndex:null,insertIndex:o,isBefore:!1};const n=e.getBoundingClientRect(),s=t<n.top+n.height/2;return{overIndex:i,insertIndex:s?i:i+1,isBefore:s}}var f="__tbw_row_drag",p=null,w=new Set;function m(){if("undefined"==typeof BroadcastChannel)return null;if(p)return p;try{(p=new BroadcastChannel("tbw-row-drag-drop")).addEventListener("message",e=>{const t=e.data;if(t&&"tbw-row-drag-drop:transfer"===t.type)for(const r of Array.from(w))try{r(t)}catch{}})}catch{p=null}return p}var b=new Set;var v=class e extends i.BaseGridPlugin{name="rowDragDrop";styles='@layer tbw-plugins{[data-field=__tbw_row_drag]{justify-content:center;align-items:center;display:flex}.dg-row-drag-handle{cursor:grab;-webkit-user-select:none;user-select:none;min-width:1em;min-height:1em;color:var(--tbw-row-reorder-handle-color,var(--tbw-color-fg-muted));transition:color var(--tbw-transition-duration,.12s) var(--tbw-transition-ease,ease);font-size:var(--tbw-font-size,1em);letter-spacing:-2px;justify-content:center;align-items:center;display:flex;position:relative}.dg-row-drag-handle:after{content:"";inline-size:var(--tbw-touch-target-min,24px);block-size:var(--tbw-touch-target-min,24px);position:absolute;inset-block-start:50%;inset-inline-start:50%;translate:-50% -50%}.dg-row-drag-handle:hover{color:var(--tbw-row-reorder-handle-hover,var(--tbw-color-fg))}.dg-row-drag-handle:active{cursor:grabbing}@media (hover:none){.dg-row-drag-handle{color:var(--tbw-row-reorder-handle-hover,var(--tbw-color-fg))}}@media (pointer:coarse){.dg-row-drag-handle{min-width:var(--tbw-touch-target-min,24px);min-height:var(--tbw-touch-target-min,24px)}}.data-grid-row.dragging{opacity:.6}.data-grid-row[draggable=true]{cursor:grab}.data-grid-row[draggable=true].dragging{cursor:grabbing}.tbw-row-drag-clone{pointer-events:none;position:fixed;top:-10000px;left:-10000px}.tbw-row-drag-count{pointer-events:none;background:var(--tbw-row-reorder-indicator,var(--tbw-color-accent));color:var(--tbw-color-accent-fg);box-shadow:0 2px 6px var(--tbw-color-shadow);z-index:9999;border-radius:999px;padding:2px 8px;font:600 12px/1.4 system-ui,sans-serif;position:fixed;top:-1000px;left:-1000px}.data-grid-row.drop-target{position:relative}.data-grid-row.drop-target.drop-before:before,.data-grid-row.drop-target.drop-after:after{content:"";height:var(--tbw-drop-indicator-width,2px);background-color:var(--tbw-drop-indicator-color,var(--tbw-row-reorder-indicator,var(--tbw-color-accent)));z-index:10;pointer-events:none;position:absolute;left:0;right:0}.data-grid-row.drop-target.drop-before:before{top:0}.data-grid-row.drop-target.drop-after:after{bottom:0}.tbw-grid--drop-target-active{outline:2px dashed var(--tbw-drop-indicator-color,var(--tbw-color-accent));outline-offset:-2px}.tbw-grid--drop-target-rejected{outline:2px dashed var(--tbw-color-danger);outline-offset:-2px}.tbw-grid--auto-scrolling{cursor:ns-resize}.data-grid-row.flip-animating{transition:transform var(--tbw-animation-duration,.2s) ease-out;will-change:transform;z-index:1}.tbw-row-move-menu{min-width:10rem;padding:var(--tbw-spacing-xs,.25rem);background:var(--tbw-color-panel-bg,light-dark(#fff,#1f1f1f));color:var(--tbw-color-fg,light-dark(#1a1a1a,#f0f0f0));border:1px solid var(--tbw-color-border,light-dark(#d0d0d0,#3a3a3a));border-radius:var(--tbw-border-radius,.25rem);box-shadow:var(--tbw-shadow-md,0 4px 12px #00000040);font:inherit;z-index:10001;flex-direction:column;margin:0;display:flex;position:fixed}.tbw-row-move-menu[hidden]{display:none}.tbw-row-move-menu-item{min-height:var(--tbw-touch-target-min,24px);padding:var(--tbw-spacing-xs,.25rem) var(--tbw-spacing-sm,.5rem);text-align:start;border-radius:min(var(--tbw-border-radius,.25rem), 6px);color:inherit;font:inherit;cursor:pointer;background:0 0;border:none}.tbw-row-move-menu-item:hover:not(:disabled){background:var(--tbw-color-row-hover,light-dark(#f0f0f0,#2a2a2a))}.tbw-row-move-menu-item:disabled{opacity:.5;cursor:default}}';static manifest={events:[{type:"row-move",description:"Intra-grid row reorder.",cancelable:!0},{type:"row-drag-start",description:"Cross-grid drag started on this grid.",cancelable:!0},{type:"row-drag-end",description:"Drag finished on this grid (regardless of outcome)."},{type:"row-drop",description:"Cross-grid drop landing on this grid.",cancelable:!0},{type:"row-transfer",description:"Cross-grid transfer completed (fires on both grids)."}]};get defaultConfig(){return{enableKeyboard:!0,dragHandlePosition:"left",dragHandleWidth:40,debounceMs:150,animation:"flip",operation:"move",autoScroll:!0,dragFrom:"handle"}}shouldRenderDragHandle(){const e=this.config.showDragHandle;return!1!==e&&(!0===e||"row"!==this.config.dragFrom)}get rowIsDraggable(){return"row"===this.config.dragFrom||"both"===this.config.dragFrom}get animationType(){return!!this.isAnimationEnabled&&(void 0!==this.config.animation?this.config.animation:"flip")}isDragging=!1;draggedRowIndex=null;draggedRows=[];draggedIndices=[];dragSessionId=null;dragAccepted=!1;dropRowIndex=null;pendingMove=null;debounceTimer=null;lastFocusCol=0;autoScroller=null;gridId="";remoteTransferListener=e=>this.onRemoteTransfer(e);moveMenu=null;get internalGrid(){return this.grid}attach(e){super.attach(e);const t=this.gridElement;var o;t&&(this.gridId=t.id||`tbw-grid-${(0,r.newDragSessionId)().slice(0,8)}`,t.id||(t.id=this.gridId),this.setupDelegatedDragListeners(),o=this.remoteTransferListener,w.add(o),m(),b.add(this))}detach(){this.clearDebounceTimer(),this.autoScroller?.stop(),this.autoScroller=null,function(e){if(w.delete(e),0===w.size&&p){try{p.close()}catch{}p=null}}(this.remoteTransferListener),b.delete(this),this.moveMenu?.dispose(),this.moveMenu=null,this.dragSessionId&&(0,r.clearDragSession)(this.dragSessionId),l(),this.resetDragState(),super.detach()}processColumns(e){if(!this.shouldRenderDragHandle())return[...e];const t={field:f,header:"",width:this.config.dragHandleWidth??40,resizable:!1,sortable:!1,filterable:!1,lockPosition:!0,utility:!0,viewRenderer:()=>{const e=document.createElement("div");return e.className="dg-row-drag-handle",e.setAttribute("aria-label","Drag to reorder, or activate for move options"),e.setAttribute("role","button"),e.setAttribute("tabindex","-1"),e.draggable=!0,e.addEventListener("click",t=>{t.stopPropagation(),this.openMoveMenu(e)}),this.setIcon(e,"dragHandle"),e}};return"right"===this.config.dragHandlePosition?[...e,t]:[t,...e]}afterRender(){this.applyRowDraggable()}onScrollRender(){this.applyRowDraggable()}applyRowDraggable(){const e=this.internalGrid._bodyEl;if(!e)return;const t=this.rowIsDraggable,r=e.querySelectorAll(".data-grid-row");for(const o of r)t?"true"!==o.getAttribute("draggable")&&o.setAttribute("draggable","true"):o.hasAttribute("draggable")&&o.removeAttribute("draggable")}onKeyDown(e){if(!this.config.enableKeyboard)return;if(!e.altKey&&!e.ctrlKey||"ArrowUp"!==e.key&&"ArrowDown"!==e.key)return;if(this.#e(e))return;const t=this.internalGrid,r=t._focusRow,o=t._rows??this.sourceRows;if(r<0||r>=o.length)return;const i="up"==("ArrowUp"===e.key?"up":"down")?r-1:r+1;if(i<0||i>=o.length)return;const n=o[r];return this.canMoveRow(r,i)?(this.handleKeyboardMove(n,r,i,t._focusCol),e.preventDefault(),e.stopPropagation(),!0):void 0}#e(e){if(this.queryBoolean("isEditing"))return!0;const t=e.composedPath?.()[0]??e.target;if(!t?.closest||t===this.gridElement)return!1;if(!t.closest(".rows-body"))return!0;const r=t.tagName;return"INPUT"===r||"SELECT"===r||"TEXTAREA"===r||t.isContentEditable}onCellClick(){this.flushPendingMove()}moveRow(e,t){const r=[...this.sourceRows];e<0||e>=r.length||t<0||t>=r.length||e!==t&&this.canMoveRow(e,t)&&this.executeIntraGridMove(r[e],e,t,"keyboard")}canMoveRow(e,t){const r=this.internalGrid._rows??this.sourceRows;if(e<0||e>=r.length)return!1;if(t<0||t>=r.length)return!1;if(e===t)return!1;const o=r[e],i=this.grid?.query?.("canMoveRow",o);if(Array.isArray(i)&&i.includes(!1))return!1;if(this.config.canDrag&&!this.config.canDrag(o,e))return!1;if(this.config.canDrop){const r={sessionId:"intra",sourceGridId:this.gridId,dropZone:this.config.dropZone??"",rows:[o],rowIndices:[e],operation:"move"};if(!this.config.canDrop(r,t))return!1}return!0}setupDelegatedDragListeners(){const e=this.gridElement;if(!e)return;const t=this.disconnectSignal;e.addEventListener("dragstart",e=>this.onDragStart(e),{signal:t}),e.addEventListener("dragend",()=>this.onDragEnd(),{signal:t}),e.addEventListener("dragover",e=>this.onDragOver(e),{signal:t}),e.addEventListener("dragleave",e=>this.onDragLeave(e),{signal:t}),e.addEventListener("drop",e=>this.onDrop(e),{signal:t})}onDragStart(e){const o=e.target;if(!o)return;const i=o.closest(".dg-row-drag-handle");let n=null,s=!1;if(i)n=i.closest(".data-grid-row"),s=!0;else if(this.rowIsDraggable){if(this.isInteractiveDragOrigin(o))return;n=o.closest(".data-grid-row")}if(!n)return;const d=this.getRowIndex(n);if(d<0)return;const{rows:l,indices:g}=this.resolveDraggedRows(d);if(0===l.length)return;if(this.config.canDrag&&!this.config.canDrag(l[0],d))return void e.preventDefault();const h=this.config.operation??"move",f=this.config.dropZone??"",p=(0,r.newDragSessionId)(),w={rows:l,indices:g,operation:h,dropZone:f};if(this.emitCancelable("row-drag-start",w))return void e.preventDefault();this.isDragging=!0,this.draggedRowIndex=d,this.draggedRows=l,this.draggedIndices=g,this.dragSessionId=p,this.dragAccepted=!1;const m=this.config.serializeRow??(e=>e),b={sessionId:p,sourceGridId:this.gridId,dropZone:f,rows:l.map(m),rowIndices:g,operation:h};if(e.dataTransfer){e.dataTransfer.effectAllowed="copy"===h?"copyMove":"move";try{e.dataTransfer.setData(c,u(b)),f&&e.dataTransfer.setData(`${c};zone=${encodeURIComponent(f)}`,u(b)),e.dataTransfer.setData("text/plain",function(e,t){const r=t.filter(e=>!e.utility&&"string"==typeof e.field&&""!==e.field),o=[];for(const i of e){const e=r.map(e=>{const t=i[e.field];return null==t?"":String(t).replace(/[\t\r\n]+/g," ")});o.push(e.join("\t"))}return o.join("\n")}(l,this.columns))}catch{}if(l.length>1){const t=document.createElement("div");t.className="tbw-row-drag-count",t.textContent=`${l.length} rows`,document.body.appendChild(t);try{e.dataTransfer.setDragImage(t,10,10)}catch{}setTimeout(()=>t.remove(),0)}else this.attachRowCloneDragImage(e,n,s?i:null)}(0,r.registerDragSession)(p,l),function(e,t){a={sessionId:e,payload:t}}(p,b),n.classList.add(t.GridClasses.DRAGGING),this.gridElement.classList.add("tbw-grid--drag-source")}static INTERACTIVE_DRAG_SELECTORS='input,textarea,select,button,a,[contenteditable=""],[contenteditable="true"],.dg-cell-editor,.tbw-checkbox-cell';isInteractiveDragOrigin(t){return null!==t.closest(e.INTERACTIVE_DRAG_SELECTORS)}attachRowCloneDragImage(e,t,r){if(!e.dataTransfer)return;const o=t.getBoundingClientRect(),i=t.cloneNode(!0);i.classList.add("tbw-row-drag-clone"),i.classList.remove("dragging","drop-target","drop-before","drop-after","flip-animating","row-focus"),i.removeAttribute("aria-selected"),i.style.width=`${o.width}px`,i.style.height=`${o.height}px`,this.gridElement.appendChild(i);let n=e.clientX-o.left,s=e.clientY-o.top;if(r){const e=r.getBoundingClientRect();n=e.left-o.left+e.width/2,s=e.top-o.top+e.height/2}n=Math.max(0,Math.min(o.width,n)),s=Math.max(0,Math.min(o.height,s));try{e.dataTransfer.setDragImage(i,n,s)}catch{}setTimeout(()=>i.remove(),0)}onDragOver(e){const t=e.dataTransfer;if(!t)return;const r=t.types?Array.from(t.types):[];if(!function(e){for(const t of e)if("application/x-tbw-grid-rows+json"===t||t.startsWith("application/x-tbw-grid-rows+json;"))return!0;return!1}(r)&&!this.isDragging)return;const o=this.config.dropZone??"",i=d(),n=this.isDragging&&i?.payload.sourceGridId===this.gridId;if(!n){if(!o)return;if(!(function(e,t){for(const r of e)if(g(r)===t)return r;return null}(r,o)||i&&i.payload.dropZone===o))return}e.preventDefault(),t&&(t.dropEffect=i?.payload.operation??this.config.operation??"move");const s=e.target.closest(".data-grid-row"),a=this.internalGrid._rows??[],l=h(s,e.clientY,e=>this.getRowIndex(e),a.length);if(n&&null!==l.overIndex&&l.overIndex===this.draggedRowIndex)this.clearDropTargetClasses();else{if(i&&this.config.canDrop){const e=this.config.canDrop(i.payload,l.insertIndex);if(this.gridElement.classList.toggle("tbw-grid--drop-target-active",e),this.gridElement.classList.toggle("tbw-grid--drop-target-rejected",!e),!e)return void this.clearDropTargetClasses()}else this.gridElement.classList.add("tbw-grid--drop-target-active");this.dropRowIndex=l.insertIndex,this.applyDropPositionClasses(s,l.isBefore),!1!==this.config.autoScroll&&(this.ensureAutoScroller(),this.autoScroller?.onPointerMove(e.clientY))}}onDragLeave(e){const t=e.target.closest(".data-grid-row");t&&t.classList.remove("drop-target","drop-before","drop-after"),e.currentTarget&&!this.gridElement.contains(e.relatedTarget)&&(this.gridElement.classList.remove("tbw-grid--drop-target-active","tbw-grid--drop-target-rejected"),this.autoScroller?.stop())}onDrop(e){e.preventDefault(),this.autoScroller?.stop(),this.gridElement.classList.remove("tbw-grid--drop-target-active","tbw-grid--drop-target-rejected"),this.clearDropTargetClasses();const t=e.dataTransfer;if(!t)return;let o=d()?.payload??null,i=null;if(o){const e=(0,r.lookupDragSession)(o.sessionId);e&&(i=e)}else{if(o=function(e){if(!e)return null;try{const t=JSON.parse(e);if("string"!=typeof t?.sessionId||"string"!=typeof t?.sourceGridId||"string"!=typeof t?.dropZone||!Array.isArray(t?.rows)||!Array.isArray(t?.rowIndices)||"move"!==t.operation&&"copy"!==t.operation)return null;for(const e of t.rowIndices)if("number"!=typeof e||!Number.isInteger(e)||e<0)return null;return t}catch{return null}}(t.getData(c)),o){const e=(0,r.lookupDragSession)(o.sessionId);e&&(i=e)}}if(!o)return;const n=e.target.closest(".data-grid-row"),s=this.internalGrid._rows??[],a=h(n,e.clientY,e=>this.getRowIndex(e),s.length);let l=this.dropRowIndex??a.insertIndex;const g=o.sourceGridId===this.gridId,u=this.config.dropZone??"";if(g){const e=o.rowIndices[0];if(1===o.rowIndices.length&&l>e&&l--,e===l)return;const t=(i??o.rows)[0];if(!this.canMoveRow(e,l))return;return void this.executeIntraGridMove(t,e,l,"drag")}if(!u||u!==o.dropZone)return;if(this.config.canDrop&&!this.config.canDrop(o,l))return this.gridElement.classList.add("tbw-grid--drop-target-rejected"),void setTimeout(()=>this.gridElement.classList.remove("tbw-grid--drop-target-rejected"),200);const f=this.config.deserializeRow??(e=>e),p=i??o.rows.map(e=>f(e)),w={payload:o,sourceGridId:o.sourceGridId,targetIndex:l,operation:o.operation};if(this.emitCancelable("row-drop",w))return;const b=[...s];b.splice(l,0,...p),this.grid.rows=b;const v=this.findPeerOnGrid(o.sourceGridId);if("move"===o.operation&&v){const e=document.getElementById(o.sourceGridId);if(e){const t=(e._rows??e.rows??[]).slice(),r=[...o.rowIndices].sort((e,t)=>t-e);for(const e of r)e>=0&&e<t.length&&t.splice(e,1);e.rows=t}}v&&(v.dragAccepted=!0);const I={rows:p,fromGridId:o.sourceGridId,toGridId:this.gridId,fromIndices:o.rowIndices,toIndex:l,operation:o.operation};this.emit("row-transfer",I),v?v.emitTransfer(I):function(e){const t=m();if(t)try{t.postMessage(e)}catch{}}({type:"tbw-row-drag-drop:transfer",sessionId:o.sessionId,sourceGridId:o.sourceGridId,toGridId:this.gridId,dropZone:u,rowIndices:o.rowIndices,toIndex:l,operation:o.operation,serializedRows:o.rows})}onRemoteTransfer(e){if(e.sourceGridId!==this.gridId)return;const t=this.config.dropZone??"";if(!t||e.dropZone!==t)return;const r=this.config.deserializeRow??(e=>e),o=e.serializedRows.map(e=>r(e));if("move"===e.operation){const t=(this.internalGrid._rows??this.sourceRows).slice(),r=[...e.rowIndices].sort((e,t)=>t-e);for(const e of r)e>=0&&e<t.length&&t.splice(e,1);this.grid.rows=t}this.dragAccepted=!0,this.emit("row-transfer",{rows:o,fromGridId:e.sourceGridId,toGridId:e.toGridId,fromIndices:e.rowIndices,toIndex:e.toIndex,operation:e.operation})}onDragEnd(){if(this.dragSessionId&&(0,r.clearDragSession)(this.dragSessionId),l(),this.autoScroller?.stop(),this.gridElement.classList.remove("tbw-grid--drag-source"),this.isDragging){const e={rows:this.draggedRows,indices:this.draggedIndices,accepted:this.dragAccepted};this.emit("row-drag-end",e)}this.clearDragClasses(),this.resetDragState()}emitTransfer(e){this.emit("row-transfer",e)}findPeerOnGrid(e){const t=document.getElementById(e);return t?.getPluginByName?t.getPluginByName("rowDragDrop")??null:null}peersInDropZone(){const e=this.config.dropZone??"";if(!e)return[];const t=[];for(const r of b){const o=r;o!==this&&((o.config.dropZone??"")===e&&t.push(o))}return t}get gridLabel(){const e=this.gridElement;return e?.getAttribute("aria-label")||e?.id||"grid"}openMoveMenu(e){const t=e.closest(".data-grid-row");if(!t)return;const r=this.getRowIndex(t);if(r<0)return;const o=this.internalGrid._rows??this.sourceRows,i=[{label:"Move up",disabled:0===r||!this.canMoveRow(r,r-1),run:()=>this.moveRow(r,r-1)},{label:"Move down",disabled:r>=o.length-1||!this.canMoveRow(r,r+1),run:()=>this.moveRow(r,r+1)},{label:"Move to top",disabled:0===r||!this.canMoveRow(r,0),run:()=>this.moveRow(r,0)},{label:"Move to bottom",disabled:r>=o.length-1||!this.canMoveRow(r,o.length-1),run:()=>this.moveRow(r,o.length-1)}],n="copy"===(this.config.operation??"move")?"Copy to":"Send to";for(const s of this.peersInDropZone())i.push({label:`${n} ${s.gridLabel}`,run:()=>this.transferToPeer(s,r)});this.moveMenu??=s("tbw-row-move-menu","tbw-row-move-menu"),this.moveMenu.open(e,`Move row ${r+1}`,i)}transferToPeer(e,t){const o=this.config.dropZone??"";if(!o)return;const{rows:i,indices:n}=this.resolveDraggedRows(t);if(0===i.length)return;if(this.config.canDrag&&!this.config.canDrag(i[0],t))return;const s=this.config.operation??"move";if(this.emitCancelable("row-drag-start",{rows:i,indices:n,operation:s,dropZone:o}))return;const a=this.config.serializeRow??(e=>e),d={sessionId:(0,r.newDragSessionId)(),sourceGridId:this.gridId,dropZone:o,rows:i.map(a),rowIndices:n,operation:s},l=e.acceptTransfer(d,i);if(l<0)return;if("move"===s){const e=[...this.internalGrid._rows??this.sourceRows];for(const t of[...n].sort((e,t)=>t-e))t>=0&&t<e.length&&e.splice(t,1);this.grid.rows=e}const c={rows:i,fromGridId:this.gridId,toGridId:e.gridId,fromIndices:n,toIndex:l,operation:s};e.emitTransfer(c),this.emit("row-transfer",c)}acceptTransfer(e,t){const r=this.config.dropZone??"";if(!r||r!==e.dropZone)return-1;const o=this.internalGrid._rows??this.sourceRows,i=o.length;if(this.config.canDrop&&!this.config.canDrop(e,i))return-1;const n={payload:e,sourceGridId:e.sourceGridId,targetIndex:i,operation:e.operation};return this.emitCancelable("row-drop",n)?-1:(this.grid.rows=[...o,...t],i)}resolveDraggedRows(e){const t=this.internalGrid._rows??this.sourceRows,r=t[e],o=this.grid?.getPluginByName?.("selection");if(o?.getSelectedRowIndices){const r=o.getSelectedRowIndices();if(r.includes(e)&&r.length>1){const e=[...r].sort((e,t)=>e-t);return{rows:e.map(e=>t[e]),indices:e}}}return{rows:[r],indices:[e]}}ensureAutoScroller(){if(this.autoScroller)return;const e=this.gridElement.querySelector(".rows-viewport");if(!e)return;const t="object"==typeof this.config.autoScroll?this.config.autoScroll:void 0;this.autoScroller=function(e,t={},r){const o=t.edgeSize??60,i=t.speed??8,n=t.maxSpeed??24;let s=null,a=null,d=!1;const l=e=>{e!==d&&(d=e,r?.(e))},c=()=>{if(s=null,null===a)return void l(!1);const t=e.getBoundingClientRect();let r=0;if(a<t.top+o){const e=1-Math.max(0,a-t.top)/o;r=-Math.round(i+(n-i)*e)}else if(a>t.bottom-o){const e=1-Math.max(0,t.bottom-a)/o;r=Math.round(i+(n-i)*e)}if(0===r)return void l(!1);const d=e.scrollTop;e.scrollTop=d+r,e.scrollTop!==d?(l(!0),s=requestAnimationFrame(c)):l(!1)};return{onPointerMove(e){a=e,null===s&&(s=requestAnimationFrame(c))},stop(){null!==s&&(cancelAnimationFrame(s),s=null),a=null,l(!1)},get isScrolling(){return d}}}(e,t,e=>{this.gridElement.classList.toggle("tbw-grid--auto-scrolling",e)})}applyDropPositionClasses(e,t){this.clearDropTargetClasses(),e&&(e.classList.add("drop-target"),e.classList.toggle("drop-before",t),e.classList.toggle("drop-after",!t))}clearDropTargetClasses(){this.gridElement?.querySelectorAll(".data-grid-row.drop-target").forEach(e=>{e.classList.remove("drop-target","drop-before","drop-after")})}clearDragClasses(){this.gridElement?.querySelectorAll(".data-grid-row").forEach(e=>{e.classList.remove(t.GridClasses.DRAGGING,"drop-target","drop-before","drop-after")})}resetDragState(){this.isDragging=!1,this.draggedRowIndex=null,this.draggedRows=[],this.draggedIndices=[],this.dragSessionId=null,this.dragAccepted=!1,this.dropRowIndex=null,this.pendingMove=null}getRowIndex(e){const t=e.querySelector(".cell[data-row]");return t?parseInt(t.getAttribute("data-row")??"-1",10):-1}clearDebounceTimer(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null)}handleKeyboardMove(e,t,r,i){this.pendingMove?this.pendingMove.currentIndex=r:this.pendingMove={originalIndex:t,currentIndex:r,row:e},this.lastFocusCol=i;const n=this.internalGrid,s=[...n._rows??this.sourceRows],[a]=s.splice(t,1);s.splice(r,0,a),n._rows=s,n._focusRow=r,n._focusCol=i,n.refreshVirtualWindow(!0),(0,o.ensureCellVisible)(n),this.clearDebounceTimer(),this.debounceTimer=setTimeout(()=>this.flushPendingMove(),this.config.debounceMs??300)}flushPendingMove(){if(this.clearDebounceTimer(),!this.pendingMove)return;const{originalIndex:e,currentIndex:t,row:r}=this.pendingMove;if(this.pendingMove=null,e===t)return;const i=this.internalGrid,n={row:r,fromIndex:e,toIndex:t,rows:[...i._rows??this.sourceRows],source:"keyboard"};this.emitCancelable("row-move",n)&&(i._rows=[...this.sourceRows],i._focusRow=e,i._focusCol=this.lastFocusCol,i.refreshVirtualWindow(!0),(0,o.ensureCellVisible)(i))}executeIntraGridMove(e,t,r,o){const i=[...this.sourceRows],[n]=i.splice(t,1);i.splice(r,0,n);const s={row:e,fromIndex:t,toIndex:r,rows:i,source:o};if(!this.emitCancelable("row-move",s))if("flip"===this.animationType&&this.gridElement){const e=this.captureRowPositions();this.grid.rows=i,requestAnimationFrame(()=>{this.gridElement.offsetHeight,this.animateFLIP(e,t,r)})}else this.grid.rows=i}captureRowPositions(){const e=new Map;return this.gridElement?.querySelectorAll(".data-grid-row").forEach(t=>{const r=this.getRowIndex(t);r>=0&&e.set(r,t.getBoundingClientRect().top)}),e}animateFLIP(e,t,r){const o=this.gridElement;if(!o||0===e.size)return;const i=Math.min(t,r),n=Math.max(t,r),s=[];if(o.querySelectorAll(".data-grid-row").forEach(o=>{const a=o,d=this.getRowIndex(a);if(d<0||d<i||d>n)return;let l;l=d===r?t:t<r?d+1:d-1;const c=e.get(l);if(void 0===c)return;const g=c-a.getBoundingClientRect().top;Math.abs(g)>1&&s.push({el:a,deltaY:g})}),0===s.length)return;s.forEach(({el:e,deltaY:t})=>{e.style.transform=`translateY(${t}px)`}),o.offsetHeight;const a=this.animationDuration;requestAnimationFrame(()=>{s.forEach(({el:e})=>{e.classList.add("flip-animating"),e.style.transform=""}),setTimeout(()=>{s.forEach(({el:e})=>{e.style.transform="",e.classList.remove("flip-animating")})},a+50)})}};e.ROW_DRAG_HANDLE_FIELD=f,e.RowDragDropPlugin=v});
2
2
  //# sourceMappingURL=row-drag-drop.umd.js.map