@toolbox-web/grid 3.9.2 → 3.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/all.js +1 -1
  2. package/all.js.map +1 -1
  3. package/index.js +1 -1
  4. package/index.js.map +1 -1
  5. package/lib/core/types.d.ts +6 -3
  6. package/lib/features/clipboard.js.map +1 -1
  7. package/lib/features/column-virtualization.js.map +1 -1
  8. package/lib/features/context-menu.js.map +1 -1
  9. package/lib/features/editing.js.map +1 -1
  10. package/lib/features/export.js.map +1 -1
  11. package/lib/features/filtering.js.map +1 -1
  12. package/lib/features/grouping-columns.js.map +1 -1
  13. package/lib/features/grouping-rows.js.map +1 -1
  14. package/lib/features/master-detail.js.map +1 -1
  15. package/lib/features/multi-sort.js.map +1 -1
  16. package/lib/features/pinned-columns.js.map +1 -1
  17. package/lib/features/pinned-rows.js.map +1 -1
  18. package/lib/features/pivot.js.map +1 -1
  19. package/lib/features/print.js.map +1 -1
  20. package/lib/features/registry.js +1 -1
  21. package/lib/features/registry.js.map +1 -1
  22. package/lib/features/reorder-columns.js.map +1 -1
  23. package/lib/features/responsive.js.map +1 -1
  24. package/lib/features/row-drag-drop.js.map +1 -1
  25. package/lib/features/selection.js.map +1 -1
  26. package/lib/features/server-side.js.map +1 -1
  27. package/lib/features/shell.js.map +1 -1
  28. package/lib/features/sticky-rows.js.map +1 -1
  29. package/lib/features/tooltip.js.map +1 -1
  30. package/lib/features/tree.js.map +1 -1
  31. package/lib/features/undo-redo.js.map +1 -1
  32. package/lib/features/visibility.js.map +1 -1
  33. package/lib/plugins/clipboard/index.js.map +1 -1
  34. package/lib/plugins/column-virtualization/index.js.map +1 -1
  35. package/lib/plugins/context-menu/index.js.map +1 -1
  36. package/lib/plugins/editing/editors.d.ts +15 -0
  37. package/lib/plugins/editing/index.js +1 -1
  38. package/lib/plugins/editing/index.js.map +1 -1
  39. package/lib/plugins/editing/internal/helpers.d.ts +23 -0
  40. package/lib/plugins/editing/types.d.ts +16 -1
  41. package/lib/plugins/export/index.js +1 -1
  42. package/lib/plugins/export/index.js.map +1 -1
  43. package/lib/plugins/filtering/filter-model.d.ts +20 -1
  44. package/lib/plugins/filtering/filter-panel-default.d.ts +15 -1
  45. package/lib/plugins/filtering/index.d.ts +1 -1
  46. package/lib/plugins/filtering/index.js +1 -1
  47. package/lib/plugins/filtering/index.js.map +1 -1
  48. package/lib/plugins/filtering/types.d.ts +58 -3
  49. package/lib/plugins/grouping-columns/index.js.map +1 -1
  50. package/lib/plugins/grouping-rows/index.js +1 -1
  51. package/lib/plugins/grouping-rows/index.js.map +1 -1
  52. package/lib/plugins/hierarchy/index.js.map +1 -1
  53. package/lib/plugins/master-detail/index.js +1 -1
  54. package/lib/plugins/master-detail/index.js.map +1 -1
  55. package/lib/plugins/master-detail/master-detail-plugin.d.ts +6 -1
  56. package/lib/plugins/multi-sort/index.js.map +1 -1
  57. package/lib/plugins/pinned-columns/index.js.map +1 -1
  58. package/lib/plugins/pinned-rows/index.js.map +1 -1
  59. package/lib/plugins/pivot/index.js +1 -1
  60. package/lib/plugins/pivot/index.js.map +1 -1
  61. package/lib/plugins/pivot/pivot-plugin.d.ts +2 -0
  62. package/lib/plugins/pivot/types.d.ts +2 -0
  63. package/lib/plugins/print/index.js.map +1 -1
  64. package/lib/plugins/reorder-columns/index.js.map +1 -1
  65. package/lib/plugins/responsive/index.js.map +1 -1
  66. package/lib/plugins/row-drag-drop/index.js.map +1 -1
  67. package/lib/plugins/selection/index.js +1 -1
  68. package/lib/plugins/selection/index.js.map +1 -1
  69. package/lib/plugins/server-side/index.js.map +1 -1
  70. package/lib/plugins/shared/form-field-target.d.ts +10 -0
  71. package/lib/plugins/shared/format-value.d.ts +12 -0
  72. package/lib/plugins/shared/structural-toggle.d.ts +14 -0
  73. package/lib/plugins/shell/index.js.map +1 -1
  74. package/lib/plugins/sticky-rows/index.js.map +1 -1
  75. package/lib/plugins/tooltip/index.js.map +1 -1
  76. package/lib/plugins/tree/index.js +1 -1
  77. package/lib/plugins/tree/index.js.map +1 -1
  78. package/lib/plugins/undo-redo/index.d.ts +1 -1
  79. package/lib/plugins/undo-redo/index.js +1 -1
  80. package/lib/plugins/undo-redo/index.js.map +1 -1
  81. package/lib/plugins/undo-redo/types.d.ts +20 -2
  82. package/lib/plugins/undo-redo/undo-redo-plugin.d.ts +8 -0
  83. package/lib/plugins/visibility/index.js.map +1 -1
  84. package/package.json +1 -1
  85. package/umd/grid.all.umd.js +1 -1
  86. package/umd/grid.all.umd.js.map +1 -1
  87. package/umd/grid.umd.js +1 -1
  88. package/umd/grid.umd.js.map +1 -1
  89. package/umd/plugins/clipboard.umd.js.map +1 -1
  90. package/umd/plugins/column-virtualization.umd.js.map +1 -1
  91. package/umd/plugins/context-menu.umd.js.map +1 -1
  92. package/umd/plugins/editing.umd.js +1 -1
  93. package/umd/plugins/editing.umd.js.map +1 -1
  94. package/umd/plugins/export.umd.js +1 -1
  95. package/umd/plugins/export.umd.js.map +1 -1
  96. package/umd/plugins/filtering.umd.js +1 -1
  97. package/umd/plugins/filtering.umd.js.map +1 -1
  98. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  99. package/umd/plugins/grouping-rows.umd.js +1 -1
  100. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  101. package/umd/plugins/hierarchy.umd.js.map +1 -1
  102. package/umd/plugins/master-detail.umd.js +1 -1
  103. package/umd/plugins/master-detail.umd.js.map +1 -1
  104. package/umd/plugins/multi-sort.umd.js.map +1 -1
  105. package/umd/plugins/pinned-columns.umd.js.map +1 -1
  106. package/umd/plugins/pinned-rows.umd.js.map +1 -1
  107. package/umd/plugins/pivot.umd.js +1 -1
  108. package/umd/plugins/pivot.umd.js.map +1 -1
  109. package/umd/plugins/print.umd.js.map +1 -1
  110. package/umd/plugins/reorder-columns.umd.js.map +1 -1
  111. package/umd/plugins/responsive.umd.js.map +1 -1
  112. package/umd/plugins/row-drag-drop.umd.js.map +1 -1
  113. package/umd/plugins/selection.umd.js +1 -1
  114. package/umd/plugins/selection.umd.js.map +1 -1
  115. package/umd/plugins/server-side.umd.js.map +1 -1
  116. package/umd/plugins/shell.umd.js.map +1 -1
  117. package/umd/plugins/sticky-rows.umd.js.map +1 -1
  118. package/umd/plugins/tooltip.umd.js.map +1 -1
  119. package/umd/plugins/tree.umd.js +1 -1
  120. package/umd/plugins/tree.umd.js.map +1 -1
  121. package/umd/plugins/undo-redo.umd.js +1 -1
  122. package/umd/plugins/undo-redo.umd.js.map +1 -1
  123. package/umd/plugins/visibility.umd.js.map +1 -1
@@ -1 +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":"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"}
1
+ {"version":3,"file":"hierarchy.umd.js","names":["BaseGridPlugin","global","factory","exports","module","require","define","amd","globalThis","self","TbwGridPlugin_hierarchy","TbwGrid","this","_toolbox_web_grid","buildHierarchy","rows","contributors","meta","WeakMap","active","stage","c","hierarchyStage","beginHierarchy","push","length","out","process","nodes","parent","depth","context","row","parentKey","key","processSiblings","emit","setSize","i","node","set","level","posInSet","children","expanded","shaped","roots","Array","positionOf","get","endHierarchy","delete","setAttrIfChanged","el","name","value","next","String","getAttribute","setAttribute","isContributor","plugin","processRowsPriority","constructor","manifest","hookPriority","processRows","Object","defineProperty","Symbol","toStringTag","HierarchyPlugin","BaseGridPlugin","static","modifiesRowStructure","detach","gridElement","querySelector","caller","includes","getRowMeta","afterRender","applyAria","onScrollRender","grid","_pluginManager","getPlugins","filter","sort","a","b","body","hierarchical","rowEl","querySelectorAll","__rowDataRef","removeAttribute","role","rowsBody"],"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":"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"}
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@toolbox-web/grid")):"function"==typeof define&&define.amd?define(["exports","@toolbox-web/grid"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TbwGridPlugin_masterDetail={},e.TbwGrid)}(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});var i=/{{\s*([^}]+)\s*}}/g,n="__DG_EMPTY__",s=/^[\w$. '?+\-*/%:()!<>=,&|]+$/,a="__otorp__|__retteGenifed__|__retteSenifed__|rotcurtsnoc|wodniw|sihTlabolg|labolg|ssecorp|noitcnuF|tropmi|lave|tcelfeR|yxorP|rorrE|stnemugra|tnemucod|noitacol|eikooc|egarotSlacol|egarotSnoisses|BDdexedni|hctef|tseuqeRpttHLMX|tekcoSbeW|rekroW|rekroWderahS|rekroWecivreS|renepo|tnerap|pot|semarf|fles".split("|").map(e=>e.split("").reverse().join("")),r=new RegExp(`__(proto|defineGetter|defineSetter)|${a.slice(3).join("|")}|this\\b`);var o=new Set("script|iframe|object|embed|form|input|button|textarea|select|link|meta|base|style|template|slot|portal|frame|frameset|applet|noscript|noembed|plaintext|xmp|listing|math".split("|")),l=/^on\w+$/i,d=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),c=/^\s*(javascript|vbscript|data|blob):/i;function h(e,t){t&&"string"==typeof t?-1!==t.indexOf("<")||-1!==t.indexOf("&")?e.replaceChildren(function(e){const t=document.createElement("template");return e&&"string"==typeof e&&(t.innerHTML=e,u(t.content)),t.content}(t)):e.textContent=t:e.replaceChildren()}function u(e){const t=[],i=e.querySelectorAll("*");for(const n of i){const e=n.tagName.toLowerCase();if(o.has(e)){t.push(n);continue}if(("svg"===e||"http://www.w3.org/2000/svg"===n.namespaceURI)&&Array.from(n.attributes).some(e=>l.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(n);continue}const i=[];for(const t of n.attributes){const e=t.name.toLowerCase();l.test(e)?i.push(t.name):"is"!==e?(d.has(e)&&c.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&i.push(t.name):i.push(t.name)}i.forEach(e=>n.removeAttribute(e))}t.forEach(e=>e.remove())}function p(e,t){const i=function(e){const t=[];let i=0;for(;i<e.length;){const n=e[i];if(" "!==n){if(n>="0"&&n<="9"||"."===n&&i+1<e.length&&e[i+1]>="0"&&e[i+1]<="9"){const n=i;for(;i<e.length&&(e[i]>="0"&&e[i]<="9"||"."===e[i]);)i++;t.push({type:"num",v:Number(e.slice(n,i))});continue}if("'"===n){let n="";for(i++;i<e.length&&"'"!==e[i];)n+=e[i++];if(i>=e.length)return null;i++,t.push({type:"str",v:n});continue}if(n>="a"&&n<="z"||n>="A"&&n<="Z"||"_"===n||"$"===n){const n=i;for(;i<e.length&&/[\w$.]/.test(e[i]);)i++;t.push({type:"id",v:e.slice(n,i)});continue}if(i+2<e.length){const n=e.slice(i,i+3);if("==="===n||"!=="===n){t.push({type:"op",v:n}),i+=3;continue}}if(i+1<e.length){const n=e.slice(i,i+2);if("=="===n||"!="===n||"<="===n||">="===n||"&&"===n||"||"===n){t.push({type:"op",v:n}),i+=2;continue}}if(!"+-*/%<>!?:(),".includes(n))return null;t.push({type:"op",v:n}),i++}else i++}return t}(e);if(!i)return;const n=i;let s=0;function a(){return n[s]}function r(){return n[s++]}function o(e,t){const i=a();return!!i&&(i.type===e&&(void 0===t||i.v===t))}function l(){const e=function(){let e=d();for(;o("op","||");)r(),e=e||d();return e}();if(o("op","?")){r();const t=l();if(!o("op",":"))return;r();const i=l();return e?t:i}return e}function d(){let e=c();for(;o("op","&&");)r(),e=e&&c();return e}function c(){let e=h();for(;;){const t=a();if(!t||"op"!==t.type)break;if("==="===t.v)r(),e=e===h();else if("!=="===t.v)r(),e=e!==h();else if("=="===t.v)r(),e=e==h();else{if("!="!==t.v)break;r(),e=e!=h()}}return e}function h(){let e=u();for(;;){const t=a();if(!t||"op"!==t.type)break;if("<"===t.v)r(),e=e<u();else if(">"===t.v)r(),e=e>u();else if("<="===t.v)r(),e=e<=u();else{if(">="!==t.v)break;r(),e=e>=u()}}return e}function u(){let e=p();for(;;){const t=a();if(!t||"op"!==t.type)break;if("+"===t.v)r(),e+=p();else{if("-"!==t.v)break;r(),e-=p()}}return e}function p(){let e=f();for(;;){const t=a();if(!t||"op"!==t.type)break;if("*"===t.v)r(),e*=f();else if("/"===t.v)r(),e/=f();else{if("%"!==t.v)break;r(),e%=f()}}return e}function f(){return o("op","!")?(r(),!f()):g()}function g(){const e=a();if(e){if("num"===e.type)return r(),e.v;if("str"===e.type)return r(),e.v;if("id"===e.type)return r(),function(e){if("value"===e)return t.value;if(e.startsWith("row.")){const i=e.slice(4);return t.row?t.row[i]:void 0}if(e.startsWith("typeDefault.")){const i=e.slice(12);return t.typeDefault?t.typeDefault[i]:void 0}return"row"===e?t.row:"typeDefault"===e?t.typeDefault:void 0}(e.v);if("op"===e.type&&"("===e.v){r();const e=l();return o("op",")")&&r(),e}return"op"===e.type&&"-"===e.v?(r(),-g()):void 0}}const w=l();return s<n.length?void 0:w}function f(e,t){if(!e||-1===e.indexOf("{{"))return e;const a=[],o=(l=e.replace(i,(e,i)=>{const o=function(e,t){if(!(e=(e||"").trim()))return n;if(g.test(e))return n;if("value"===e)return null==t.value?n:String(t.value);if(e.startsWith("row.")&&!/[()?]/.test(e)&&!e.includes(":")){const i=e.slice(4),s=t.row?t.row[i]:void 0;return null==s?n:String(s)}if(e.startsWith("typeDefault.")&&!/[()?]/.test(e)&&!e.includes(":")){const i=e.slice(12),s=t.typeDefault?t.typeDefault[i]:void 0;return null==s?n:String(s)}if(e.length>80)return n;if(!s.test(e)||r.test(e))return n;const i=e.match(/\./g);if(i&&i.length>1)return n;try{const i=p(e,t),s=null==i?"":String(i);return g.test(s)?n:s||n}catch{return n}}(i,t);return a.push({expr:i.trim(),result:o}),o===n?o:(l=o)&&"string"==typeof l?l.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;"):"";var l}),l?l.replace(new RegExp(n,"g"),"").replace(/Reflect\.[^<>{}\s]+|\bProxy\b|ownKeys\([^)]*\)/g,""):l);var l;const d=a.length&&a.every(e=>""===e.result||e.result===n);return g.test(e)||d?"":o}var g=/Reflect|Proxy|ownKeys/;var w="__tbw_expander";function m(e){return e.field===w}var x=class e extends t.BaseGridPlugin{name="masterDetail";styles='@layer tbw-plugins{tbw-grid .cell[data-field=__tbw_expander]{justify-content:center;align-items:center;padding:0;display:flex;border-right:none!important}tbw-grid .header-row .cell[data-field=__tbw_expander]{display:none}tbw-grid .master-detail-expander{justify-content:center;align-items:center;width:100%;height:100%;display:flex}tbw-grid .master-detail-toggle{cursor:pointer;opacity:.7;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;display:inline-flex}tbw-grid .master-detail-toggle:hover{opacity:1}tbw-grid .master-detail-toggle{position:relative}tbw-grid .master-detail-toggle: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%}@media (pointer:coarse){tbw-grid .master-detail-toggle{min-width:var(--tbw-touch-target-min,24px);min-height:var(--tbw-touch-target-min,24px)}}tbw-grid .master-detail-row{background:var(--tbw-master-detail-bg,var(--tbw-color-row-alt));border-bottom:1px solid var(--tbw-master-detail-border,var(--tbw-color-border));grid-column:1/-1;display:grid;overflow:hidden}tbw-grid .master-detail-cell{padding:var(--tbw-detail-padding,var(--tbw-spacing-xl,1rem));overflow:auto}tbw-grid .master-detail-row.tbw-expanding{animation:tbw-detail-expand var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}tbw-grid .master-detail-row.tbw-collapsing{animation:tbw-detail-collapse var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}@keyframes tbw-detail-expand{0%{opacity:0;max-height:0;padding-top:0;padding-bottom:0}to{opacity:1;max-height:var(--tbw-detail-max-height,31.25rem);padding-top:var(--tbw-detail-padding,var(--tbw-spacing-xl,1rem));padding-bottom:var(--tbw-detail-padding,var(--tbw-spacing-xl,1rem))}}@keyframes tbw-detail-collapse{0%{opacity:1;max-height:var(--tbw-detail-max-height,31.25rem)}to{opacity:0;max-height:0}}}';static dependencies=[{name:"serverSide",required:!1,reason:"Fetches detail data via datasource:fetch-children on expand"}];get#e(){return this.grid}get defaultConfig(){return{detailHeight:"auto",expandOnRowClick:!1,animation:"slide"}}attach(e){super.attach(e),this.parseLightDomDetail(),this.on("datasource:children",e=>{const t=e;if("master-detail"!==t.context?.source)return;t.claimed=!0;const i=t.context.row;this.detailLoads.delete(i),i&&this.#t(i)&&(this.detailDataMap.set(i,t.rows),this.#i(i),this.requestRender())}),this.on("datasource:error",e=>{const t=e;if("master-detail"!==t.context?.source)return;const i=t.context.row;i&&this.detailLoads.delete(i)&&(this.#i(i),this.emit("detail-load-error",{rowIndex:this.rows.indexOf(i),row:i,error:t.error}),this.requestRender())}),this.on("datasource:data",e=>{this.#n=e})}#s(){const e=this.#n;if(this.#n=void 0,!e||e.claimed||0===this.detailLoads.size)return;const t=new Set(this.rows);for(const i of this.detailLoads.keys())t.has(i)||this.#a(i)}#r(e){if(null==e)return!1;const t=e;return!t.__isGroupRow&&!0!==t.__loading}#t(e){return!!this.#r(e)&&(!!function(e,t){return e.has(t)}(this.expandedRows,e)||this.#o&&!this.#l.has(e))}#d(){return this.#o||this.expandedRows.size>0}#c(e,t){t?(this.#l.delete(e),this.expandedRows=function(e,t){return e.add(t),e}(this.expandedRows,e)):(this.expandedRows=function(e,t){return e.delete(t),e}(this.expandedRows,e),this.#o&&this.#l.add(e))}#i(e){const t=this.detailElements.get(e);t&&(this.#h(e,t),this.measuredDetailHeights.delete(e))}#h(e,t){const i=this.#e.__frameworkAdapter;if(i?.unmount){const e=t.querySelector(".master-detail-cell")?.firstElementChild;e&&i.unmount(e)}t.parentNode&&t.remove(),this.detailElements.delete(e)}#u(e,t,i){if(this.detailDataMap.has(e)||this.detailLoads.has(e))return;if(!this.#r(e))return;if(this.#p.has(e))return;if(!(i??this.queryBoolean("datasource:is-active")))return;this.#p.add(e);const n=new AbortController;this.detailLoads.set(e,n),this.grid.query("datasource:fetch-children",{context:{source:"master-detail",row:e,rowIndex:t},signal:n.signal})}#a(e){this.detailLoads.get(e)?.abort(),this.detailLoads.delete(e),null!==e&&"object"==typeof e&&this.#p.delete(e)}parseLightDomDetail(){const e=this.gridElement;if(!e)return;const t=e.querySelector("tbw-grid-detail");if(!t)return;const i=this.#e.__frameworkAdapter;if(i?.parseDetailElement){const e=i.parseDetailElement(t);if(e)return void(this.config={...this.config,detailRenderer:e})}const n=t.getAttribute("animation"),s=t.getAttribute("show-expand-column"),a=t.getAttribute("expand-on-row-click"),r=t.getAttribute("height"),o={};null!==n&&(o.animation="false"!==n&&n),null!==s&&(o.showExpandColumn="false"!==s),null!==a&&(o.expandOnRowClick="true"===a),null!==r&&(o.detailHeight="auto"===r?"auto":parseInt(r,10));const l=t.innerHTML.trim();l&&!this.config.detailRenderer&&(o.detailRenderer=(e,t)=>function(e){if(!e||"string"!=typeof e)return"";if(-1===e.indexOf("<"))return e;const t=document.createElement("template");return t.innerHTML=e,u(t.content),t.innerHTML}(f(l,{value:e,row:e}))),Object.keys(o).length>0&&(this.config={...this.config,...o})}get animationStyle(){return!!this.isAnimationEnabled&&(this.config.animation??"slide")}animateExpand(e,t,i){if(!this.isAnimationEnabled||!1===this.animationStyle)return!1;e.classList.add("tbw-expanding");let n=!1;const s=()=>{n||(n=!0,e.classList.remove("tbw-expanding"),void 0!==t&&void 0!==i&&this.#f(e,t,i))};return e.addEventListener("animationend",s,{once:!0}),setTimeout(s,this.animationDuration+50),!0}animateCollapse(e,t){if(!this.isAnimationEnabled||!1===this.animationStyle)return void t();e.classList.add("tbw-collapsing");const i=()=>{e.classList.remove("tbw-collapsing"),t()};e.addEventListener("animationend",i,{once:!0}),setTimeout(i,this.animationDuration+50)}#f(e,t,i){if(!e.isConnected)return;const n=e.offsetHeight;if(n>0){const e=this.measuredDetailHeights.get(t);this.measuredDetailHeights.set(t,n),e!==n&&this.grid.invalidateRowHeight(i)}}expandedRows=new Set;detailElements=new Map;measuredDetailHeights=new WeakMap;rowsToAnimate=new Set;detailLoads=new Map;detailDataMap=new WeakMap;#o=!1;#l=new WeakSet;#p=new WeakSet;#n;static DEFAULT_DETAIL_HEIGHT=150;getDetailHeight(t){const i=this.detailElements.get(t);if(i&&!i.classList.contains("tbw-expanding")&&!i.classList.contains("tbw-collapsing")){const e=i.offsetHeight;if(e>0)return this.measuredDetailHeights.set(t,e),e}const n=this.measuredDetailHeights.get(t);return n&&n>0?n:"number"==typeof this.config?.detailHeight?this.config.detailHeight:e.DEFAULT_DETAIL_HEIGHT}toggleAndEmit(e,t){if(!this.#r(e))return;const i=!this.#t(e);this.#c(e,i),i?this.rowsToAnimate.add(e):this.#a(e),this.emit("detail-expand",{rowIndex:t,row:e,expanded:i}),i&&this.#t(e)&&this.#u(e,t),this.requestRender()}detach(){this.expandedRows.clear(),this.detailElements.clear(),this.measuredDetailHeights=new WeakMap,this.rowsToAnimate.clear();for(const e of this.detailLoads.values())e.abort();this.detailLoads.clear(),this.detailDataMap=new WeakMap,this.#o=!1,this.#l=new WeakSet,this.#p=new WeakSet,this.#n=void 0}processColumns(e){if(!(!0===this.config.showExpandColumn||!1!==this.config.showExpandColumn&&this.config.detailRenderer))return[...e];const t=[...e];if(function(e){return e.find(m)}(t))return t;const i=(n=this.name,{field:w,header:"",width:32,resizable:!1,sortable:!1,filterable:!1,lockPosition:!0,utility:!0,meta:{expanderColumn:!0,expanderPlugin:n}});var n;return i.viewRenderer=e=>{const{row:t}=e,i=this.#t(t),n=document.createElement("span");n.className="master-detail-expander expander-cell";const s=document.createElement("span");return s.className="master-detail-toggle"+(i?" expanded":""),this.setIcon(s,i?"collapse":"expand"),s.setAttribute("role","button"),s.setAttribute("tabindex","0"),s.setAttribute("aria-expanded",String(i)),s.setAttribute("aria-label",i?"Collapse details":"Expand details"),n.appendChild(s),n},[i,...t]}onRowClick(e){if(this.config.expandOnRowClick&&this.config.detailRenderer)return this.toggleAndEmit(e.row,e.rowIndex),!1}onCellClick(e){if((e.originalEvent?.target)?.classList.contains("master-detail-toggle"))return this.toggleAndEmit(e.row,e.rowIndex),!0;this.#d()&&queueMicrotask(()=>this.#g())}onKeyDown(e){if(" "!==e.key)return;const t=this.grid._focusCol,i=this.grid._focusRow,n=this.visibleColumns[t];if(!n||!m(n))return;const s=this.rows[i];return s?(e.preventDefault(),this.toggleAndEmit(s,i),this.requestRenderWithFocus(),!0):void 0}afterRender(){this.#s(),this.#w(),this.#g()}#w(){const e=this.gridElement?.querySelector('.header-row .cell[data-field="__tbw_expander"]');if(!e)return;const t=parseInt(e.getAttribute("data-col")||"0",10),i=e.nextElementSibling;i&&(i.style.gridColumn=`${t+1} / ${t+3}`)}onScrollRender(){this.config.detailRenderer&&this.#d()&&this.#g()}#g(){const e=this.config.detailRenderer;if(!e)return;const t=this.gridElement?.querySelector(".rows");if(!t)return;const i=this.#m(t);this.#x(i);const n=this.columns.length,s=this.#d()&&this.queryBoolean("datasource:is-active");for(const[a,r]of i){const t=this.rows[a];t&&this.#b(t,a,r,n,e,s)}}#b(e,t,i,n,s,a){const r=this.#t(e);if(i.classList.toggle("tbw-row-expanded",r),!r)return;if(this.#u(e,t,a),!this.#t(e))return void i.classList.remove("tbw-row-expanded");const o=this.detailElements.get(e);o?o.previousElementSibling!==i&&i.after(o):this.#v(e,t,i,n,s)}#m(e){const t=this.grid,i=t._rowPool,n=t._virtualization?.start??0,s=t._virtualization?.end??0,a=new Map;if(i){const t=Math.min(i.length,s-n);for(let s=0;s<t;s++){const t=i[s];t.parentNode===e&&a.set(n+s,t)}return a}for(const r of e.querySelectorAll(".data-grid-row")){const e=r.querySelector(".cell[data-row]"),t=e?parseInt(e.getAttribute("data-row")??"-1",10):-1;t>=0&&a.set(t,r)}return a}#x(e){for(const[t,i]of this.detailElements){const n=this.rows.indexOf(t),s=n>=0&&e.has(n);this.#t(t)&&s||this.#h(t,i)}}#v(e,t,i,n,s){const a=function(e,t,i,n){const s=document.createElement("div");s.className="master-detail-row",s.setAttribute("data-detail-for",String(t)),s.setAttribute("role","row");const a=document.createElement("div");a.className="master-detail-cell",a.setAttribute("role","cell"),a.style.gridColumn=`1 / ${n+1}`;const r=i(e,t);return"string"==typeof r?h(a,r):r instanceof HTMLElement&&a.appendChild(r),s.appendChild(a),s}(e,t,s,n);"number"==typeof this.config.detailHeight&&(a.style.height=`${this.config.detailHeight}px`),i.after(a),this.detailElements.set(e,a);const r=this.rowsToAnimate.has(e);r&&this.rowsToAnimate.delete(e),r&&this.animateExpand(a,e,t)||requestAnimationFrame(()=>{this.#f(a,e,t)})}getRowHeight(e,t){if(this.#t(e))return(this.grid.defaultRowHeight??28)+this.getDetailHeight(e)}#R(e){const t=this.rows,i=[];for(let n=0,s=Math.min(e,t.length);n<s;n++)this.#t(t[n])&&i.push({index:n,row:t[n]});return i}#D(e,t,i){const n=this.rows;let s=e;for(let a=Math.min(e,i.length)-1;a>=0;a--){const e=i[a];if(e.offset+e.height<=t)break;this.#t(n[a])&&(s=a)}return s}adjustVirtualStart(e,t,i){if(!this.#d())return e;const n=this.grid?._virtualization?.positionCache;if(n&&n.length>0)return this.#D(e,t,n);let s=e,a=0;for(const{index:r,row:o}of this.#R(e)){const e=r*i+a,n=this.getDetailHeight(o);a+=n,e+i+n>t&&r<s&&(s=r)}return s}expand(e){const t=this.rows[e];if(this.#r(t)){const i=this.#t(t);this.rowsToAnimate.add(t),this.#c(t,!0),i||this.#u(t,e),this.requestRender()}}collapse(e){const t=this.rows[e];t&&(this.#c(t,!1),this.#a(t),this.requestRender())}toggle(e){const t=this.rows[e];if(this.#r(t)){const i=!this.#t(t);this.#c(t,i),i?(this.rowsToAnimate.add(t),this.#u(t,e)):this.#a(t),this.requestRender()}}isExpanded(e){const t=this.rows[e];return!!t&&this.#t(t)}expandAll(){const e=this.queryBoolean("datasource:is-active"),t=this.rows,i=[];for(let n=0;n<t.length;n++){const e=t[n];this.#r(e)&&!this.#t(e)&&i.push({row:e,index:n})}this.#o=!0,this.#l=new WeakSet;for(const{row:n,index:s}of i)this.#t(n)&&(this.rowsToAnimate.add(n),this.#u(n,s,e));this.requestRender()}collapseAll(){this.#o=!1,this.#l=new WeakSet;for(const e of[...this.detailLoads.keys()])this.#a(e);this.#p=new WeakSet,this.expandedRows.clear(),this.requestRender()}getExpandedRows(){return this.#R(this.rows.length).map(e=>e.index)}getDetailElement(e){const t=this.rows[e];return t?this.detailElements.get(t):void 0}getDetailData(e){const t=this.rows[e];return t?this.detailDataMap.get(t):void 0}isDetailLoading(e){const t=this.rows[e];return!!t&&this.detailLoads.has(t)}refreshDetailRenderer(){const e=this.config.detailRenderer;if(this.config={...this.config,detailRenderer:void 0},this.parseLightDomDetail(),!this.config.detailRenderer&&e&&(this.config={...this.config,detailRenderer:e}),this.config.detailRenderer){const e=this.#e;"function"==typeof e.refreshColumns?e.refreshColumns():this.requestRender()}}};e.MasterDetailPlugin=x});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@toolbox-web/grid")):"function"==typeof define&&define.amd?define(["exports","@toolbox-web/grid"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TbwGridPlugin_masterDetail={},e.TbwGrid)}(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});var i=/{{\s*([^}]+)\s*}}/g,n="__DG_EMPTY__",s=/^[\w$. '?+\-*/%:()!<>=,&|]+$/,a="__otorp__|__retteGenifed__|__retteSenifed__|rotcurtsnoc|wodniw|sihTlabolg|labolg|ssecorp|noitcnuF|tropmi|lave|tcelfeR|yxorP|rorrE|stnemugra|tnemucod|noitacol|eikooc|egarotSlacol|egarotSnoisses|BDdexedni|hctef|tseuqeRpttHLMX|tekcoSbeW|rekroW|rekroWderahS|rekroWecivreS|renepo|tnerap|pot|semarf|fles".split("|").map(e=>e.split("").reverse().join("")),r=new RegExp(`__(proto|defineGetter|defineSetter)|${a.slice(3).join("|")}|this\\b`);var o=new Set("script|iframe|object|embed|form|input|button|textarea|select|link|meta|base|style|template|slot|portal|frame|frameset|applet|noscript|noembed|plaintext|xmp|listing|math".split("|")),l=/^on\w+$/i,d=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),c=/^\s*(javascript|vbscript|data|blob):/i;function h(e,t){t&&"string"==typeof t?-1!==t.indexOf("<")||-1!==t.indexOf("&")?e.replaceChildren(function(e){const t=document.createElement("template");return e&&"string"==typeof e&&(t.innerHTML=e,u(t.content)),t.content}(t)):e.textContent=t:e.replaceChildren()}function u(e){const t=[],i=e.querySelectorAll("*");for(const n of i){const e=n.tagName.toLowerCase();if(o.has(e)){t.push(n);continue}if(("svg"===e||"http://www.w3.org/2000/svg"===n.namespaceURI)&&Array.from(n.attributes).some(e=>l.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(n);continue}const i=[];for(const t of n.attributes){const e=t.name.toLowerCase();l.test(e)?i.push(t.name):"is"!==e?(d.has(e)&&c.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&i.push(t.name):i.push(t.name)}i.forEach(e=>n.removeAttribute(e))}t.forEach(e=>e.remove())}function p(e,t){const i=function(e){const t=[];let i=0;for(;i<e.length;){const n=e[i];if(" "!==n){if(n>="0"&&n<="9"||"."===n&&i+1<e.length&&e[i+1]>="0"&&e[i+1]<="9"){const n=i;for(;i<e.length&&(e[i]>="0"&&e[i]<="9"||"."===e[i]);)i++;t.push({type:"num",v:Number(e.slice(n,i))});continue}if("'"===n){let n="";for(i++;i<e.length&&"'"!==e[i];)n+=e[i++];if(i>=e.length)return null;i++,t.push({type:"str",v:n});continue}if(n>="a"&&n<="z"||n>="A"&&n<="Z"||"_"===n||"$"===n){const n=i;for(;i<e.length&&/[\w$.]/.test(e[i]);)i++;t.push({type:"id",v:e.slice(n,i)});continue}if(i+2<e.length){const n=e.slice(i,i+3);if("==="===n||"!=="===n){t.push({type:"op",v:n}),i+=3;continue}}if(i+1<e.length){const n=e.slice(i,i+2);if("=="===n||"!="===n||"<="===n||">="===n||"&&"===n||"||"===n){t.push({type:"op",v:n}),i+=2;continue}}if(!"+-*/%<>!?:(),".includes(n))return null;t.push({type:"op",v:n}),i++}else i++}return t}(e);if(!i)return;const n=i;let s=0;function a(){return n[s]}function r(){return n[s++]}function o(e,t){const i=a();return!!i&&(i.type===e&&(void 0===t||i.v===t))}function l(){const e=function(){let e=d();for(;o("op","||");)r(),e=e||d();return e}();if(o("op","?")){r();const t=l();if(!o("op",":"))return;r();const i=l();return e?t:i}return e}function d(){let e=c();for(;o("op","&&");)r(),e=e&&c();return e}function c(){let e=h();for(;;){const t=a();if(!t||"op"!==t.type)break;if("==="===t.v)r(),e=e===h();else if("!=="===t.v)r(),e=e!==h();else if("=="===t.v)r(),e=e==h();else{if("!="!==t.v)break;r(),e=e!=h()}}return e}function h(){let e=u();for(;;){const t=a();if(!t||"op"!==t.type)break;if("<"===t.v)r(),e=e<u();else if(">"===t.v)r(),e=e>u();else if("<="===t.v)r(),e=e<=u();else{if(">="!==t.v)break;r(),e=e>=u()}}return e}function u(){let e=p();for(;;){const t=a();if(!t||"op"!==t.type)break;if("+"===t.v)r(),e+=p();else{if("-"!==t.v)break;r(),e-=p()}}return e}function p(){let e=f();for(;;){const t=a();if(!t||"op"!==t.type)break;if("*"===t.v)r(),e*=f();else if("/"===t.v)r(),e/=f();else{if("%"!==t.v)break;r(),e%=f()}}return e}function f(){return o("op","!")?(r(),!f()):g()}function g(){const e=a();if(e){if("num"===e.type)return r(),e.v;if("str"===e.type)return r(),e.v;if("id"===e.type)return r(),function(e){if("value"===e)return t.value;if(e.startsWith("row.")){const i=e.slice(4);return t.row?t.row[i]:void 0}if(e.startsWith("typeDefault.")){const i=e.slice(12);return t.typeDefault?t.typeDefault[i]:void 0}return"row"===e?t.row:"typeDefault"===e?t.typeDefault:void 0}(e.v);if("op"===e.type&&"("===e.v){r();const e=l();return o("op",")")&&r(),e}return"op"===e.type&&"-"===e.v?(r(),-g()):void 0}}const w=l();return s<n.length?void 0:w}function f(e,t){if(!e||-1===e.indexOf("{{"))return e;const a=[],o=(l=e.replace(i,(e,i)=>{const o=function(e,t){if(!(e=(e||"").trim()))return n;if(g.test(e))return n;if("value"===e)return null==t.value?n:String(t.value);if(e.startsWith("row.")&&!/[()?]/.test(e)&&!e.includes(":")){const i=e.slice(4),s=t.row?t.row[i]:void 0;return null==s?n:String(s)}if(e.startsWith("typeDefault.")&&!/[()?]/.test(e)&&!e.includes(":")){const i=e.slice(12),s=t.typeDefault?t.typeDefault[i]:void 0;return null==s?n:String(s)}if(e.length>80)return n;if(!s.test(e)||r.test(e))return n;const i=e.match(/\./g);if(i&&i.length>1)return n;try{const i=p(e,t),s=null==i?"":String(i);return g.test(s)?n:s||n}catch{return n}}(i,t);return a.push({expr:i.trim(),result:o}),o===n?o:(l=o)&&"string"==typeof l?l.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;"):"";var l}),l?l.replace(new RegExp(n,"g"),"").replace(/Reflect\.[^<>{}\s]+|\bProxy\b|ownKeys\([^)]*\)/g,""):l);var l;const d=a.length&&a.every(e=>""===e.result||e.result===n);return g.test(e)||d?"":o}var g=/Reflect|Proxy|ownKeys/;var w="__tbw_expander";function m(e){return e.field===w}var x="master-detail-toggle";var b=`.${"tree-toggle"},.${x},.${"group-toggle"}`;var v=class e extends t.BaseGridPlugin{name="masterDetail";styles='@layer tbw-plugins{tbw-grid .cell[data-field=__tbw_expander]{justify-content:center;align-items:center;padding:0;display:flex;border-right:none!important}tbw-grid .header-row .cell[data-field=__tbw_expander]{display:none}tbw-grid .master-detail-expander{justify-content:center;align-items:center;width:100%;height:100%;display:flex}tbw-grid .master-detail-toggle{cursor:pointer;opacity:.7;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;display:inline-flex}tbw-grid .master-detail-toggle:hover{opacity:1}tbw-grid .master-detail-toggle{position:relative}tbw-grid .master-detail-toggle: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%}@media (pointer:coarse){tbw-grid .master-detail-toggle{min-width:var(--tbw-touch-target-min,24px);min-height:var(--tbw-touch-target-min,24px)}}tbw-grid .master-detail-row{background:var(--tbw-master-detail-bg,var(--tbw-color-row-alt));border-bottom:1px solid var(--tbw-master-detail-border,var(--tbw-color-border));grid-column:1/-1;display:grid;overflow:hidden}tbw-grid .master-detail-cell{padding:var(--tbw-detail-padding,var(--tbw-spacing-xl,1rem));overflow:auto}tbw-grid .master-detail-row.tbw-expanding{animation:tbw-detail-expand var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}tbw-grid .master-detail-row.tbw-collapsing{animation:tbw-detail-collapse var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}@keyframes tbw-detail-expand{0%{opacity:0;max-height:0;padding-top:0;padding-bottom:0}to{opacity:1;max-height:var(--tbw-detail-max-height,31.25rem);padding-top:var(--tbw-detail-padding,var(--tbw-spacing-xl,1rem));padding-bottom:var(--tbw-detail-padding,var(--tbw-spacing-xl,1rem))}}@keyframes tbw-detail-collapse{0%{opacity:1;max-height:var(--tbw-detail-max-height,31.25rem)}to{opacity:0;max-height:0}}}';static manifest={hookPriority:{onCellClick:-10}};static dependencies=[{name:"serverSide",required:!1,reason:"Fetches detail data via datasource:fetch-children on expand"}];get#e(){return this.grid}get defaultConfig(){return{detailHeight:"auto",expandOnRowClick:!1,animation:"slide"}}attach(e){super.attach(e),this.parseLightDomDetail(),this.on("datasource:children",e=>{const t=e;if("master-detail"!==t.context?.source)return;t.claimed=!0;const i=t.context.row;this.detailLoads.delete(i),i&&this.#t(i)&&(this.detailDataMap.set(i,t.rows),this.#i(i),this.requestRender())}),this.on("datasource:error",e=>{const t=e;if("master-detail"!==t.context?.source)return;const i=t.context.row;i&&this.detailLoads.delete(i)&&(this.#i(i),this.emit("detail-load-error",{rowIndex:this.rows.indexOf(i),row:i,error:t.error}),this.requestRender())}),this.on("datasource:data",e=>{this.#n=e})}#s(){const e=this.#n;if(this.#n=void 0,!e||e.claimed||0===this.detailLoads.size)return;const t=new Set(this.rows);for(const i of this.detailLoads.keys())t.has(i)||this.#a(i)}#r(e){if(null==e)return!1;const t=e;return!t.__isGroupRow&&!0!==t.__loading}#t(e){return!!this.#r(e)&&(!!function(e,t){return e.has(t)}(this.expandedRows,e)||this.#o&&!this.#l.has(e))}#d(){return this.#o||this.expandedRows.size>0}#c(e,t){t?(this.#l.delete(e),this.expandedRows=function(e,t){return e.add(t),e}(this.expandedRows,e)):(this.expandedRows=function(e,t){return e.delete(t),e}(this.expandedRows,e),this.#o&&this.#l.add(e))}#i(e){const t=this.detailElements.get(e);t&&(this.#h(e,t),this.measuredDetailHeights.delete(e))}#h(e,t){const i=this.#e.__frameworkAdapter;if(i?.unmount){const e=t.querySelector(".master-detail-cell")?.firstElementChild;e&&i.unmount(e)}t.parentNode&&t.remove(),this.detailElements.delete(e)}#u(e,t,i){if(this.detailDataMap.has(e)||this.detailLoads.has(e))return;if(!this.#r(e))return;if(this.#p.has(e))return;if(!(i??this.queryBoolean("datasource:is-active")))return;this.#p.add(e);const n=new AbortController;this.detailLoads.set(e,n),this.grid.query("datasource:fetch-children",{context:{source:"master-detail",row:e,rowIndex:t},signal:n.signal})}#a(e){this.detailLoads.get(e)?.abort(),this.detailLoads.delete(e),null!==e&&"object"==typeof e&&this.#p.delete(e)}parseLightDomDetail(){const e=this.gridElement;if(!e)return;const t=e.querySelector("tbw-grid-detail");if(!t)return;const i=this.#e.__frameworkAdapter;if(i?.parseDetailElement){const e=i.parseDetailElement(t);if(e)return void(this.config={...this.config,detailRenderer:e})}const n=t.getAttribute("animation"),s=t.getAttribute("show-expand-column"),a=t.getAttribute("expand-on-row-click"),r=t.getAttribute("height"),o={};null!==n&&(o.animation="false"!==n&&n),null!==s&&(o.showExpandColumn="false"!==s),null!==a&&(o.expandOnRowClick="true"===a),null!==r&&(o.detailHeight="auto"===r?"auto":parseInt(r,10));const l=t.innerHTML.trim();l&&!this.config.detailRenderer&&(o.detailRenderer=(e,t)=>function(e){if(!e||"string"!=typeof e)return"";if(-1===e.indexOf("<"))return e;const t=document.createElement("template");return t.innerHTML=e,u(t.content),t.innerHTML}(f(l,{value:e,row:e}))),Object.keys(o).length>0&&(this.config={...this.config,...o})}get animationStyle(){return!!this.isAnimationEnabled&&(this.config.animation??"slide")}animateExpand(e,t,i){if(!this.isAnimationEnabled||!1===this.animationStyle)return!1;e.classList.add("tbw-expanding");let n=!1;const s=()=>{n||(n=!0,e.classList.remove("tbw-expanding"),void 0!==t&&void 0!==i&&this.#f(e,t,i))};return e.addEventListener("animationend",s,{once:!0}),setTimeout(s,this.animationDuration+50),!0}animateCollapse(e,t){if(!this.isAnimationEnabled||!1===this.animationStyle)return void t();e.classList.add("tbw-collapsing");const i=()=>{e.classList.remove("tbw-collapsing"),t()};e.addEventListener("animationend",i,{once:!0}),setTimeout(i,this.animationDuration+50)}#f(e,t,i){if(!e.isConnected)return;const n=e.offsetHeight;if(n>0){const e=this.measuredDetailHeights.get(t);this.measuredDetailHeights.set(t,n),e!==n&&this.grid.invalidateRowHeight(i)}}expandedRows=new Set;detailElements=new Map;measuredDetailHeights=new WeakMap;rowsToAnimate=new Set;detailLoads=new Map;detailDataMap=new WeakMap;#o=!1;#l=new WeakSet;#p=new WeakSet;#n;static DEFAULT_DETAIL_HEIGHT=150;getDetailHeight(t){const i=this.detailElements.get(t);if(i&&!i.classList.contains("tbw-expanding")&&!i.classList.contains("tbw-collapsing")){const e=i.offsetHeight;if(e>0)return this.measuredDetailHeights.set(t,e),e}const n=this.measuredDetailHeights.get(t);return n&&n>0?n:"number"==typeof this.config?.detailHeight?this.config.detailHeight:e.DEFAULT_DETAIL_HEIGHT}toggleAndEmit(e,t){if(!this.#r(e))return;const i=!this.#t(e);this.#c(e,i),i?this.rowsToAnimate.add(e):this.#a(e),this.emit("detail-expand",{rowIndex:t,row:e,expanded:i}),i&&this.#t(e)&&this.#u(e,t),this.requestRender()}detach(){this.expandedRows.clear(),this.detailElements.clear(),this.measuredDetailHeights=new WeakMap,this.rowsToAnimate.clear();for(const e of this.detailLoads.values())e.abort();this.detailLoads.clear(),this.detailDataMap=new WeakMap,this.#o=!1,this.#l=new WeakSet,this.#p=new WeakSet,this.#n=void 0}processColumns(e){if(!(!0===this.config.showExpandColumn||!1!==this.config.showExpandColumn&&this.config.detailRenderer))return[...e];const t=[...e];if(function(e){return e.find(m)}(t))return t;const i=(n=this.name,{field:w,header:"",width:32,resizable:!1,sortable:!1,filterable:!1,lockPosition:!0,utility:!0,meta:{expanderColumn:!0,expanderPlugin:n}});var n;return i.viewRenderer=e=>{const{row:t}=e,i=this.#t(t),n=document.createElement("span");n.className="master-detail-expander expander-cell";const s=document.createElement("span");return s.className=`${x}${i?" expanded":""}`,this.setIcon(s,i?"collapse":"expand"),s.setAttribute("role","button"),s.setAttribute("tabindex","0"),s.setAttribute("aria-expanded",String(i)),s.setAttribute("aria-label",i?"Collapse details":"Expand details"),n.appendChild(s),n},[i,...t]}onRowClick(e){if(this.config.expandOnRowClick&&this.config.detailRenderer&&"dblclick"!==e.originalEvent.type&&!function(e){return!!e.target?.closest?.(b)}(e.originalEvent))return this.toggleAndEmit(e.row,e.rowIndex),!1}onCellClick(e){if(function(e){return!!(e?.target)?.closest?.(`.${x}`)}(e.originalEvent))return"dblclick"===e.originalEvent.type||this.toggleAndEmit(e.row,e.rowIndex),!0;this.#d()&&queueMicrotask(()=>this.#g())}onKeyDown(e){if(" "!==e.key)return;if(function(e){const t=e.composedPath?.()??[],i=t.length?t[0]:e.target;if(!(i instanceof HTMLElement))return!1;const n=i.tagName;return"INPUT"===n||"SELECT"===n||"TEXTAREA"===n||i.isContentEditable}(e))return;const t=this.grid._focusCol,i=this.grid._focusRow,n=this.visibleColumns[t];if(!n||!m(n))return;const s=this.rows[i];return s?(e.preventDefault(),this.toggleAndEmit(s,i),this.requestRenderWithFocus(),!0):void 0}afterRender(){this.#s(),this.#w(),this.#g()}#w(){const e=this.gridElement?.querySelector('.header-row .cell[data-field="__tbw_expander"]');if(!e)return;const t=parseInt(e.getAttribute("data-col")||"0",10),i=e.nextElementSibling;i&&(i.style.gridColumn=`${t+1} / ${t+3}`)}onScrollRender(){this.config.detailRenderer&&this.#d()&&this.#g()}#g(){const e=this.config.detailRenderer;if(!e)return;const t=this.gridElement?.querySelector(".rows");if(!t)return;const i=this.#m(t);this.#x(i);const n=this.columns.length,s=this.#d()&&this.queryBoolean("datasource:is-active");for(const[a,r]of i){const t=this.rows[a];t&&this.#b(t,a,r,n,e,s)}}#b(e,t,i,n,s,a){const r=this.#t(e);if(i.classList.toggle("tbw-row-expanded",r),!r)return;if(this.#u(e,t,a),!this.#t(e))return void i.classList.remove("tbw-row-expanded");const o=this.detailElements.get(e);o?o.previousElementSibling!==i&&i.after(o):this.#v(e,t,i,n,s)}#m(e){const t=this.grid,i=t._rowPool,n=t._virtualization?.start??0,s=t._virtualization?.end??0,a=new Map;if(i){const t=Math.min(i.length,s-n);for(let s=0;s<t;s++){const t=i[s];t.parentNode===e&&a.set(n+s,t)}return a}for(const r of e.querySelectorAll(".data-grid-row")){const e=r.querySelector(".cell[data-row]"),t=e?parseInt(e.getAttribute("data-row")??"-1",10):-1;t>=0&&a.set(t,r)}return a}#x(e){for(const[t,i]of this.detailElements){const n=this.rows.indexOf(t),s=n>=0&&e.has(n);this.#t(t)&&s||this.#h(t,i)}}#v(e,t,i,n,s){const a=function(e,t,i,n){const s=document.createElement("div");s.className="master-detail-row",s.setAttribute("data-detail-for",String(t)),s.setAttribute("role","row");const a=document.createElement("div");a.className="master-detail-cell",a.setAttribute("role","cell"),a.style.gridColumn=`1 / ${n+1}`;const r=i(e,t);return"string"==typeof r?h(a,r):r instanceof HTMLElement&&a.appendChild(r),s.appendChild(a),s}(e,t,s,n);"number"==typeof this.config.detailHeight&&(a.style.height=`${this.config.detailHeight}px`),i.after(a),this.detailElements.set(e,a);const r=this.rowsToAnimate.has(e);r&&this.rowsToAnimate.delete(e),r&&this.animateExpand(a,e,t)||requestAnimationFrame(()=>{this.#f(a,e,t)})}getRowHeight(e,t){if(this.#t(e))return(this.grid.defaultRowHeight??28)+this.getDetailHeight(e)}#R(e){const t=this.rows,i=[];for(let n=0,s=Math.min(e,t.length);n<s;n++)this.#t(t[n])&&i.push({index:n,row:t[n]});return i}#D(e,t,i){const n=this.rows;let s=e;for(let a=Math.min(e,i.length)-1;a>=0;a--){const e=i[a];if(e.offset+e.height<=t)break;this.#t(n[a])&&(s=a)}return s}adjustVirtualStart(e,t,i){if(!this.#d())return e;const n=this.grid?._virtualization?.positionCache;if(n&&n.length>0)return this.#D(e,t,n);let s=e,a=0;for(const{index:r,row:o}of this.#R(e)){const e=r*i+a,n=this.getDetailHeight(o);a+=n,e+i+n>t&&r<s&&(s=r)}return s}expand(e){const t=this.rows[e];if(this.#r(t)){const i=this.#t(t);this.rowsToAnimate.add(t),this.#c(t,!0),i||this.#u(t,e),this.requestRender()}}collapse(e){const t=this.rows[e];t&&(this.#c(t,!1),this.#a(t),this.requestRender())}toggle(e){const t=this.rows[e];if(this.#r(t)){const i=!this.#t(t);this.#c(t,i),i?(this.rowsToAnimate.add(t),this.#u(t,e)):this.#a(t),this.requestRender()}}isExpanded(e){const t=this.rows[e];return!!t&&this.#t(t)}expandAll(){const e=this.queryBoolean("datasource:is-active"),t=this.rows,i=[];for(let n=0;n<t.length;n++){const e=t[n];this.#r(e)&&!this.#t(e)&&i.push({row:e,index:n})}this.#o=!0,this.#l=new WeakSet;for(const{row:n,index:s}of i)this.#t(n)&&(this.rowsToAnimate.add(n),this.#u(n,s,e));this.requestRender()}collapseAll(){this.#o=!1,this.#l=new WeakSet;for(const e of[...this.detailLoads.keys()])this.#a(e);this.#p=new WeakSet,this.expandedRows.clear(),this.requestRender()}getExpandedRows(){return this.#R(this.rows.length).map(e=>e.index)}getDetailElement(e){const t=this.rows[e];return t?this.detailElements.get(t):void 0}getDetailData(e){const t=this.rows[e];return t?this.detailDataMap.get(t):void 0}isDetailLoading(e){const t=this.rows[e];return!!t&&this.detailLoads.has(t)}refreshDetailRenderer(){const e=this.config.detailRenderer;if(this.config={...this.config,detailRenderer:void 0},this.parseLightDomDetail(),!this.config.detailRenderer&&e&&(this.config={...this.config,detailRenderer:e}),this.config.detailRenderer){const e=this.#e;"function"==typeof e.refreshColumns?e.refreshColumns():this.requestRender()}}};e.MasterDetailPlugin=v});
2
2
  //# sourceMappingURL=master-detail.umd.js.map