@toolbox-web/grid 3.10.1 → 3.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/all.js +2 -1
- package/all.js.map +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/lib/features/registry.js +1 -1
- package/lib/plugins/editing/editing-plugin.d.ts +11 -5
- package/lib/plugins/editing/index.js +2 -1
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/editing/internal/editor-injection.d.ts +9 -2
- package/lib/plugins/hierarchy/hierarchy.d.ts +5 -1
- package/lib/plugins/hierarchy/index.js +1 -1
- package/lib/plugins/hierarchy/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +1 -1
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +1 -1
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/editing.umd.js +1 -1
- package/umd/plugins/editing.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +1 -1
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/hierarchy.umd.js +1 -1
- package/umd/plugins/hierarchy.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@toolbox-web/grid")):"function"==typeof define&&define.amd?define(["exports","@toolbox-web/grid"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).TbwGridPlugin_hierarchy={},t.TbwGrid)}(this,function(t,e){function r(t,e,r=new WeakMap,o){const n=o?function(t,e){let r;for(let o=0;o<t.length;o++){const n=e(t[o]);n!==t[o]&&(r??=t.slice(),r[o]=n)}return r??t}(t,o):t,i=[];for(const h of["structure","transform"])for(const t of e)t.hierarchyStage===h&&t.beginHierarchy(n)&&i.push(t);if(0===i.length)return[...n];const s=[],l=(t,e,r)=>{o&&e&&(t=function(t,e){let r;for(let o=0;o<t.length;o++){const n=e(t[o].row);n!==t[o].row&&(r??=t.slice(),r[o]={...t[o],row:n})}return r??t}(t,o));const n={parent:e?e.row:null,parentKey:e?.key??null,depth:r};for(const o of i)t=o.processSiblings(t,n);return t},u=(t,e)=>{const o=t.length;for(let n=0;n<o;n++){const i=t[n];s.push(i.row),"object"==typeof i.row&&null!==i.row&&r.set(i.row,{level:e+1,setSize:o,posInSet:n+1});const a=i.children;i.expanded&&a&&u(i.shaped?a:l(a,i,e+1),e+1)}},a=new Array(n.length);for(let h=0;h<n.length;h++)a[h]={row:n[h]};u(l(a,null,0),0);const c=t=>"object"==typeof t&&null!==t?r.get(t):void 0;let f=!1;for(const h of i)h.endHierarchy(s,c)&&(f=!0);if(!f)for(const h of s)"object"==typeof h&&null!==h&&r.delete(h);return s}function o(t,e,r){const o=String(r);t.getAttribute(e)!==o&&t.setAttribute(e,o)}function n(t){return"function"==typeof t.processSiblings}function i(t){return t.constructor.manifest?.hookPriority?.processRows??0}Object.defineProperty(t,Symbol.toStringTag,{value:"Module"});var s=class extends e.BaseGridPlugin{static manifest={modifiesRowStructure:!0};name="hierarchy";#t=new WeakMap;detach(){this.gridElement?.querySelector(".rows-body")?.setAttribute("role","grid"),this.#t=new WeakMap}process(t,e){const o=this.#e();return o.includes(e)?o[o.length-1]!==e?t:(this.#t=new WeakMap,r(t,o,this.#t,this.#r())):(this.#t=new WeakMap,r(t,[e],this.#t,this.#r()))}#r(){const t=this.grid?.query?.("getRowSubstitutes",null)??[];let e;for(const o of t)if(o?.size){e??=new Map;for(const[t,r]of o)e.set(t,r)}if(!e)return;const r=this.grid;return t=>{if("object"!=typeof t||null===t)return t;let o;try{o=r.getRowId(t)}catch{return t}return e.has(o)?e.get(o):t}}getRowMeta(t){return"object"==typeof t&&null!==t?this.#t.get(t):void 0}afterRender(){this.#o()}onScrollRender(){this.#o()}#e(){return(this.grid?._pluginManager?.getPlugins?.()??[]).filter(n).sort((t,e)=>i(t)-i(e))}#o(){if(0===this.#e().length)return;const t=this.gridElement?.querySelector(".rows");if(!t)return;let e=!1;for(const i of t.querySelectorAll(".data-grid-row")){const t=this.getRowMeta(i.__rowDataRef);t?(e=!0,o(i,"aria-level",t.level),o(i,"aria-setsize",t.setSize),o(i,"aria-posinset",t.posInSet)):(i.removeAttribute("aria-level"),i.removeAttribute("aria-setsize"),i.removeAttribute("aria-posinset"))}const r=e?"treegrid":"grid",n=this.gridElement?.querySelector(".rows-body");n&&n.getAttribute("role")!==r&&n.setAttribute("role",r)}};t.HierarchyPlugin=s,t.buildHierarchy=r});
|
|
2
2
|
//# sourceMappingURL=hierarchy.umd.js.map
|
|
@@ -1 +1 @@
|
|
|
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":"C,6SAkCA,SAAgBc,EACdC,EACAC,EACAC,EAA0C,IAAIC,SAE9C,MAAMC,EAAiC,GACvC,IAAK,MAAMC,IAAS,CAAC,YAAa,aAChC,IAAK,MAAMC,KAAKL,EACVK,EAAEC,iBAAmBF,GAASC,EAAEE,eAAeR,IAAOI,EAAOK,KAAKH,GAG1E,GAAsB,IAAlBF,EAAOM,OAAc,MAAO,IAAIV,GAEpC,MAAMW,EAAiB,GACjBC,EAAA,CAAWC,EAAwBC,EAA8BC,KACrE,MAAMC,EAAU,CAAEF,OAAQA,EAASA,EAAOG,IAAM,KAAMC,UAAWJ,GAAQK,KAAO,KAAMJ,SACtF,IAAK,MAAMT,KAAKF,EAAQS,EAAQP,EAAEc,gBAAgBP,EAAOG,GACzD,OAAOH,GAEHQ,EAAA,CAAQR,EAAwBE,KACpC,MAAMO,EAAUT,EAAMH,OACtB,IAAK,IAAIa,EAAI,EAAGA,EAAID,EAASC,IAAK,CAChC,MAAMC,EAAOX,EAAMU,GACnBZ,EAAIF,KAAKe,EAAKP,KACU,iBAAbO,EAAKP,KAAiC,OAAbO,EAAKP,KACvCf,EAAKuB,IAAID,EAAKP,IAAK,CAAES,MAAOX,EAAQ,EAAGO,UAASK,SAAUJ,EAAI,IAEhE,MAAMK,EAAWJ,EAAKI,SAClBJ,EAAKK,UAAYD,GACnBP,EAAKG,EAAKM,OAASF,EAAWhB,EAAQgB,EAAUJ,EAAMT,EAAQ,GAAIA,EAAQ,EAE9E,GAGIgB,EAAyB,IAAIC,MAAMhC,EAAKU,QAC9C,IAAK,IAAIa,EAAI,EAAGA,EAAIvB,EAAKU,OAAQa,IAAKQ,EAAMR,GAAK,CAAEN,IAAKjB,EAAKuB,IAC7DF,EAAKT,EAAQmB,EAAO,KAAM,GAAI,GAE9B,MAAME,EAAchB,GAAiC,iBAARA,GAA4B,OAARA,EAAef,EAAKgC,IAAIjB,QAAO,EAChG,IAAIa,GAAS,EACb,IAAK,MAAMxB,KAAKF,EAAYE,EAAE6B,aAAaxB,EAAKsB,KAAaH,GAAS,GACtE,IAAKA,EACE,IAAA,MAAMb,KAAON,EAAwB,iBAARM,GAA4B,OAARA,GAAcf,EAAKkC,OAAOnB,GAElF,OAAON,CACT,CClEA,SAAS0B,EAAiBC,EAAaC,EAAcC,GACnD,MAAMC,EAAOC,OAAOF,GAChBF,EAAGK,aAAaJ,KAAUE,GAAMH,EAAGM,aAAaL,EAAME,EAC5D,CAEA,SAASI,EAAcC,GACrB,MAA4E,mBAA7DA,EAAyC1B,eAC1D,CAEA,SAAS2B,EAAoBD,GAC3B,OAAQA,EAAOE,YAAsCC,UAAUC,cAAcC,aAAe,CAC9F,C,6DAoCA,IAAaK,EAAb,cAAqCvE,EAAAA,eAEnCyE,gBAAoD,CAClDC,sBAAsB,GAIxBpB,KAAgB,YAEhBrC,GAAQ,IAAIC,QAGZ,MAAAyD,GAEE/D,KAAKgE,aAAaC,cAAc,eAAelB,aAAa,OAAQ,QACpE/C,MAAKK,EAAQ,IAAIC,OACnB,CAkBA,OAAAS,CAAQZ,EAA0B+D,GAChC,MAAM9D,EAAeJ,MAAKI,IAC1B,OAAKA,EAAa+D,SAASD,GAIvB9D,EAAaA,EAAaS,OAAS,KAAOqD,EAAe/D,GAC7DH,MAAKK,EAAQ,IAAIC,QACVJ,EAAeC,EAAMC,EAAcJ,MAAKK,KAL7CL,MAAKK,EAAQ,IAAIC,QACVJ,EAAeC,EAAM,CAAC+D,GAASlE,MAAKK,GAK/C,CAcA,UAAA+D,CAAWhD,GACT,MAAsB,iBAARA,GAA4B,OAARA,EAAepB,MAAKK,EAAMgC,IAAIjB,QAAO,CACzE,CAGA,WAAAiD,GACErE,MAAKsE,GACP,CAGA,cAAAC,GACEvE,MAAKsE,GACP,CAGA,EAAAlE,GAEE,OADiBJ,KAAKwE,MAAMC,gBAAgBC,gBAAkB,IAC/CC,OAAO3B,GAAe4B,KAAA,CAAMC,EAAGC,IAAM5B,EAAoB2B,GAAK3B,EAAoB4B,GACnG,CAEA,EAAAR,GACE,GAAoC,IAAhCtE,MAAKI,IAAgBS,OAAc,OACvC,MAAMkE,EAAO/E,KAAKgE,aAAaC,cAAc,SAC7C,IAAKc,EAAM,OAEX,IAAIC,GAAe,EACnB,IAAK,MAAMC,KAASF,EAAKG,iBAAiB,kBAAmB,CAC3D,MAAM7E,EAAOL,KAAKoE,WAAYa,EAA6BE,cACtD9E,GAOL2E,GAAe,EACfxC,EAAiByC,EAAO,aAAc5E,EAAKwB,OAC3CW,EAAiByC,EAAO,eAAgB5E,EAAKoB,SAC7Ce,EAAiByC,EAAO,gBAAiB5E,EAAKyB,YAR5CmD,EAAMG,gBAAgB,cACtBH,EAAMG,gBAAgB,gBACtBH,EAAMG,gBAAgB,iBAO1B,CAGA,MAAMC,EAAOL,EAAe,WAAa,OACnCM,EAAWtF,KAAKgE,aAAaC,cAAc,cAC7CqB,GAAYA,EAASxC,aAAa,UAAYuC,GAAMC,EAASvC,aAAa,OAAQsC,EACxF,G"}
|
|
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","substitute","roots","out","i","length","row","slice","substituteValues","active","stage","c","hierarchyStage","beginHierarchy","push","process","nodes","parent","depth","substituteRows","context","parentKey","key","processSiblings","emit","setSize","node","set","level","posInSet","children","expanded","shaped","rootNodes","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","rowSubstitute","responses","grid","query","pinned","map","size","Map","id","getRowId","has","getRowMeta","afterRender","applyAria","onScrollRender","_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/** Copy-on-write: contributors may hold on to node objects, so a substituted node is a new object. */\nfunction substituteRows(nodes: HierarchyNode[], substitute: (row: unknown) => unknown): HierarchyNode[] {\n let out: HierarchyNode[] | undefined;\n for (let i = 0; i < nodes.length; i++) {\n const row = substitute(nodes[i].row);\n if (row === nodes[i].row) continue;\n out ??= nodes.slice();\n out[i] = { ...nodes[i], row };\n }\n return out ?? nodes;\n}\n\n/** Copy-on-write substitution of a plain row list (the roots, before any node exists). */\nfunction substituteValues(rows: readonly unknown[], substitute: (row: unknown) => unknown): readonly unknown[] {\n let out: unknown[] | undefined;\n for (let i = 0; i < rows.length; i++) {\n const row = substitute(rows[i]);\n if (row === rows[i]) continue;\n out ??= rows.slice();\n out[i] = row;\n }\n return out ?? rows;\n}\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 * @param substitute - Optional. Maps a row to the object to use in its place, at\n * every nesting level, before any contributor sees it. Return the row itself to\n * keep it. `HierarchyPlugin` uses this to keep a row being edited when the data\n * is replaced with new objects. Added in 3.10.2.\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 substitute?: (row: unknown) => unknown,\n): unknown[] {\n // Roots are substituted BEFORE activation: `beginHierarchy` decides from them whether\n // there is any structure (a pinned parent may be the only row with children).\n const roots = substitute ? substituteValues(rows, substitute) : rows;\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(roots)) active.push(c);\n }\n }\n if (active.length === 0) return [...roots];\n\n const out: unknown[] = [];\n const process = (nodes: HierarchyNode[], parent: HierarchyNode | null, depth: number): HierarchyNode[] => {\n if (substitute && parent) nodes = substituteRows(nodes, substitute);\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 rootNodes: HierarchyNode[] = new Array(roots.length);\n for (let i = 0; i < roots.length; i++) rootNodes[i] = { row: roots[i] };\n emit(process(rootNodes, 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, this.#rowSubstitute());\n }\n if (contributors[contributors.length - 1] !== caller) return rows as unknown[];\n this.#meta = new WeakMap();\n return buildHierarchy(rows, contributors, this.#meta, this.#rowSubstitute());\n }\n\n /**\n * Rows other plugins pin by ID for this rebuild (`getRowSubstitutes` query) — e.g.\n * EditingPlugin's in-progress row, so an edit survives `rows` being replaced with\n * new objects even when the row is nested (#570). `undefined` when nothing is pinned.\n */\n #rowSubstitute(): ((row: unknown) => unknown) | undefined {\n const responses = this.grid?.query?.<ReadonlyMap<string, unknown> | undefined>('getRowSubstitutes', null) ?? [];\n let pinned: Map<string, unknown> | undefined;\n for (const map of responses) {\n if (!map?.size) continue;\n pinned ??= new Map();\n for (const [id, row] of map) pinned.set(id, row);\n }\n if (!pinned) return undefined;\n const grid = this.grid;\n return (row) => {\n if (typeof row !== 'object' || row === null) return row;\n let id: string | undefined;\n try {\n id = grid.getRowId(row);\n } catch {\n return row;\n }\n return pinned.has(id) ? pinned.get(id) : row;\n };\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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"}
|
package/umd/plugins/tree.umd.js
CHANGED
|
@@ -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_tree={},e.TbwGrid)}(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});var r="expanded",n="tree-toggle",i="__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("")),s=(new RegExp(`__(proto|defineGetter|defineSetter)|${i.slice(3).join("|")}|this\\b`),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("|"))),o=/^on\w+$/i,a=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),d=/^\s*(javascript|vbscript|data|blob):/i;function l(e){const t=document.createElement("template");return e&&"string"==typeof e&&(t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const n of r){const e=n.tagName.toLowerCase();if(s.has(e)){t.push(n);continue}if(("svg"===e||"http://www.w3.org/2000/svg"===n.namespaceURI)&&Array.from(n.attributes).some(e=>o.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(n);continue}const r=[];for(const t of n.attributes){const e=t.name.toLowerCase();o.test(e)?r.push(t.name):"is"!==e?(a.has(e)&&d.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name):r.push(t.name)}r.forEach(e=>n.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content)),t.content}function h(e,t,r=new WeakMap){const n=[];for(const h of["structure","transform"])for(const r of t)r.hierarchyStage===h&&r.beginHierarchy(e)&&n.push(r);if(0===n.length)return[...e];const i=[],s=(e,t,r)=>{const i={parent:t?t.row:null,parentKey:t?.key??null,depth:r};for(const s of n)e=s.processSiblings(e,i);return e},o=(e,t)=>{const n=e.length;for(let a=0;a<n;a++){const d=e[a];i.push(d.row),"object"==typeof d.row&&null!==d.row&&r.set(d.row,{level:t+1,setSize:n,posInSet:a+1});const l=d.children;d.expanded&&l&&o(d.shaped?l:s(l,d,t+1),t+1)}},a=new Array(e.length);for(let h=0;h<e.length;h++)a[h]={row:e[h]};o(s(a,null,0),0);const d=e=>"object"==typeof e&&null!==e?r.get(e):void 0;let l=!1;for(const h of n)h.endHierarchy(i,d)&&(l=!0);if(!l)for(const h of i)"object"==typeof h&&null!==h&&r.delete(h);return i}function c(e,t,r){const n=String(r);e.getAttribute(t)!==n&&e.setAttribute(t,n)}function u(e){return"function"==typeof e.processSiblings}function p(e){return e.constructor.manifest?.hookPriority?.processRows??0}var g=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 r=this.#t();return r.includes(t)?r[r.length-1]!==t?e:(this.#e=new WeakMap,h(e,r,this.#e)):(this.#e=new WeakMap,h(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(u).sort((e,t)=>p(e)-p(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,c(i,"aria-level",e.level),c(i,"aria-setsize",e.setSize),c(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)}};function f(e,t,r){return void 0!==e.id?String(e.id):r?`${r}-${t}`:String(t)}function w(e,t){const r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r}function y(e,t,r=null,n=0){const i=t.childrenField??"children",s=new Set;for(let o=0;o<e.length;o++){const a=e[o],d=f(a,o,r),l=a[i];if(Array.isArray(l)&&l.length>0){s.add(d);const e=y(l,t,d,n+1);for(const t of e)s.add(t)}}return s}function m(e,t,r,n=null,i=0){const s=r.childrenField??"children";for(let o=0;o<e.length;o++){const a=e[o],d=f(a,o,n);if(d===t)return[d];const l=a[s];if(Array.isArray(l)&&l.length>0){const e=m(l,t,r,d,i+1);if(e)return[d,...e]}}return null}function b(e,t,r,n){const i=m(e,t,r);if(!i)return n;const s=new Set(n);for(let o=0;o<i.length-1;o++)s.add(i[o]);return s}function x(e,t="children",r){if(!Array.isArray(e)||0===e.length)return!1;for(const n of e){if(!n||!0===n.__loading)continue;const e=n[t];if(Array.isArray(e)&&e.length>0)return!0;if(null!=e&&!Array.isArray(e)&&e)return!0;if(r?.(n))return!0}return!1}var v=class extends t.BaseGridPlugin{static manifest={modifiesRowStructure:!0,hookPriority:{processRows:10,onCellClick:-10},incompatibleWith:[{name:"pivot",reason:"PivotPlugin replaces the entire row and column structure with aggregated pivot data. Tree hierarchy cannot coexist with pivot aggregation."}],events:[{type:"tree-expand",description:"Emitted when tree expansion state changes (toggle, expand all, collapse all). Broadcast to both DOM consumers and plugin bus."},{type:"tree-load-start",description:"Emitted when lazy child loading starts for a node whose children are not yet loaded."},{type:"tree-load-end",description:"Emitted when lazy child loading completes and children have been merged into the parent row."},{type:"tree-load-error",description:"Emitted when lazy child loading fails. The node leaves its loading state and can be retried."}],queries:[{type:"canMoveRow",description:"Returns false for rows with children (parent nodes cannot be reordered)"},{type:"datasource:viewport-mapping",description:"Translates flat viewport row indices to top-level node indices for ServerSide pagination."}]};static dependencies=[{name:"hierarchy",required:!0,reason:"Builds the hierarchical row model",provide:()=>new g},{name:"multiSort",required:!1,reason:"Queries sort model for coordinated tree sorting"},{name:"serverSide",required:!1,reason:"Consumes datasource events for lazy-loaded tree data"}];name="tree";hierarchyStage="structure";styles='@layer tbw-plugins{tbw-grid .cell[data-field=__tbw_expander]{justify-content:flex-start;align-items:center;padding:0;display:flex;border-inline-end:none!important}tbw-grid .header-row .cell[data-field=__tbw_expander]{display:none}tbw-grid .header-row .cell[data-field=__tbw_expander]+.cell{grid-column:1/3}tbw-grid .tree-cell-wrapper{vertical-align:middle;align-items:center;padding-inline-start:calc(var(--tbw-tree-depth,0) * var(--tbw-tree-indent-width,var(--tbw-tree-toggle-size,1.25em)));display:inline-flex;overflow:visible}tbw-grid .tree-expander{box-sizing:border-box;justify-content:flex-start;align-items:center;width:100%;height:100%;display:flex}tbw-grid .tree-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;width:var(--tbw-tree-toggle-size,1.25em);height:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}tbw-grid .tree-toggle:hover{color:var(--tbw-tree-accent,var(--tbw-color-accent))}tbw-grid .tree-toggle{position:relative}tbw-grid .tree-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%}tbw-grid .tree-spacer{width:var(--tbw-tree-toggle-size,1.25em);height:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0;display:inline-block}@media (pointer:coarse){tbw-grid .tree-toggle,tbw-grid .tree-spacer{min-width:var(--tbw-touch-target-min,24px);min-height:var(--tbw-touch-target-min,24px)}}tbw-grid .tree-loading{--tbw-spinner-size:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0}tbw-grid .data-grid-row.tbw-tree-slide-in{animation:tbw-tree-slide-in var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}tbw-grid .data-grid-row.tbw-tree-fade-in{animation:tbw-tree-fade-in var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}@keyframes tbw-tree-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}@keyframes tbw-tree-fade-in{0%{opacity:0}to{opacity:1}}}';get defaultConfig(){return{childrenField:"children",autoDetect:!0,defaultExpanded:!1,indentWidth:20,showExpandIcons:!0,animation:"slide"}}expandedKeys=new Set;initialExpansionDone=!1;flattenedRows=[];rowKeyMap=new Map;previousVisibleKeys=new Set;keysToAnimate=new Set;#n=[];#i=0;sortState=null;#s=null;#o=new Map;#a=new WeakSet;#d=new WeakSet;#l=new WeakSet;#h=[];#c=new WeakMap;#u=new WeakMap;originalTreeColumnRenderer;originalTreeColumnRendererProperty="viewRenderer";wrappedTreeColumnField;#p=!1;#g=!1;detach(){this.expandedKeys.clear(),this.initialExpansionDone=!1,this.flattenedRows=[],this.#n=[],this.#i=0,this.rowKeyMap.clear(),this.previousVisibleKeys.clear(),this.keysToAnimate.clear(),this.sortState=null,this.#s=null,this.#a=new WeakSet,this.#d=new WeakSet,this.#l=new WeakSet,this.#h=[];for(const e of this.#o.values())e.controller.abort();this.#o.clear(),this.originalTreeColumnRenderer=void 0,this.originalTreeColumnRendererProperty="viewRenderer",this.wrappedTreeColumnField=void 0,this.#p=!1}handleQuery(e){if("canMoveRow"===e.type){const t=e.context,r=this.config.childrenField??"children",n=t?.[r];if(Array.isArray(n)&&n.length>0)return!1}if("datasource:viewport-mapping"===e.type){const{viewportStart:t,viewportEnd:r}=e.context;if(0===this.flattenedRows.length)return;return function(e,t,r,n){const i=e.length-1,s=t=>Math.max(0,e[Math.max(0,Math.min(t,i))]??0);return{startNode:s(r),endNode:s(n)+1,totalLoadedNodes:t}}(this.#n,this.#i,t,r)}}attach(e){super.attach(e),this.on("datasource:data",e=>{const t=e;t.claimed||(t.claimed=!0)}),this.on("datasource:children",e=>{const t=e;if("tree"!==t.context?.source)return;t.claimed=!0;const r=t.context.parentNode;if(r){const e=this.#f(r),n=this.#w(e,r);if(!n&&(this.#d.has(r)||this.#l.has(r)))return;this.#y(r,t.rows??[]),this.broadcast("tree-load-end",{key:e,row:r,depth:n?.depth??this.rowKeyMap.get(e)?.depth??0,childCount:t.rows?.length??0}),this.requestRender()}}),this.on("datasource:error",e=>{const t=e;if("tree"!==t.context?.source)return;const r=t.context.parentNode;if(!r)return;const n=this.#f(r),i=this.#w(n,r);i&&(this.broadcast("tree-load-error",{key:n,row:r,depth:i.depth,error:t.error}),this.requestRender())})}get animationStyle(){return!!this.isAnimationEnabled&&(this.config.animation??"slide")}detect(e){if(!this.config.autoDetect)return!1;const t=e,r=this.config.childrenField??function(e){if(!Array.isArray(e)||0===e.length)return null;const t=["children","items","nodes","subRows","nested"];for(const r of e)if(r&&"object"==typeof r)for(const e of t){const t=r[e];if(Array.isArray(t)&&t.length>0)return e}return null}(t)??"children";return x(t,r)}processRows(e){const t=this.grid?.getPluginByName?.("hierarchy");return t?t.process(e,this):h(e,[this])}beginHierarchy(e){const t=e;if(0===t.length||!x(t,this.config.childrenField??"children",this.config.hasChildren))return this.flattenedRows=[],this.#n=[],this.#i=0,this.rowKeyMap.clear(),this.previousVisibleKeys.clear(),this.#m(t),this.#b(),!1;const r="server"===this.grid?.query?.("datasource:sort-mode",null)?.[0];return this.#s=r?null:this.resolveEffectiveSortState(),this.config.defaultExpanded&&!this.initialExpansionDone&&(this.expandedKeys=y(t,this.config),this.initialExpansionDone=!0),this.#u=new WeakMap,!0}processSiblings(e,t){const{parentKey:r,depth:n}=t,i=this.config.childrenField??"children",s=this.config.hasChildren;for(let d=0;d<e.length;d++)this.#x(e[d].row,d,r);const o=this.#s,a=o?this.#v(e,o.field,o.direction):e;for(let d=0;d<a.length;d++){const e=a[d],t=e.row,o=this.#x(t,d,r),l=t[i],h=Array.isArray(l)&&l.length>0,c=h||!0!==t.__loading&&(s?s(t):null!=l&&!Array.isArray(l)&&!!l),u=this.expandedKeys.has(o);this.#u.set(t,{key:o,data:t,depth:n,hasChildren:c,isExpanded:u,parentKey:r,posInSet:d+1,setSize:a.length}),e.key=o,h&&u&&(e.expanded=!0,e.children=l.map(e=>({row:e})))}return a}endHierarchy(e,t){const r=this.#u;this.#u=new WeakMap,this.flattenedRows=[],this.rowKeyMap.clear(),this.keysToAnimate.clear();const n=new Set,i=new Array(e.length);let s=-1;for(let o=0;o<e.length;o++){const a=e[o],d=r.get(a);if(null===d?.parentKey&&s++,i[o]=s,!d)continue;const l=t(a)?.level;void 0!==l&&(d.depth=l-1),this.flattenedRows.push(d),this.rowKeyMap.set(d.key,d),this.#u.set(a,d),n.add(d.key),!this.previousVisibleKeys.has(d.key)&&d.depth>0&&this.keysToAnimate.add(d.key),this.#S(d)&&this.#R(d)}return this.previousVisibleKeys=n,this.#n=i,this.#i=s+1,this.#b(),!0}#b(){this.#g||(this.#g=!0,queueMicrotask(()=>{this.#g=!1,this.grid&&this.#p!==this.flattenedRows.length>0&&this.requestColumnsRender()}))}#x(e,t,r){if(void 0!==e.id){const t=String(e.id);return this.#c.set(e,t),t}const n=this.#c.get(e);if(void 0!==n)return n;const i=r?`${r}-${t}`:String(t);return this.#c.set(e,i),i}#v(e,t,r){const n=new Map;for(const i of e)n.set(i.row,i);return this.#k(e.map(e=>e.row),t,r).map(e=>n.get(e)??{row:e})}#k(e,r,n){const i=this.grid,s=i?._columns??[],o={field:r,direction:n},a=[...e],d=(i?.effectiveConfig?.sortHandler??t.builtInSort)(a,o,s);return d&&"function"==typeof d.then?(d.catch(()=>{}),(0,t.builtInSort)(a,o,s)):d}#f(e){return this.#c.get(e)??String(e.id??"?")}#y(e,t){e[this.config.childrenField??"children"]=t,this.#a.add(e)}#C(e){if(this.#a.has(e))return!1;const t=e[this.config.childrenField??"children"];if(Array.isArray(t)&&t.length>0)return!1;const r=this.config.hasChildren;return r?r(e):null!=t&&!Array.isArray(t)&&!!t}#S(e){if(!0===e.data.__loading)return!1;const t=this.#o.get(e.key);return t?t.row!==e.data:e.isExpanded&&e.hasChildren&&!this.#d.has(e.data)&&this.#C(e.data)}#m(e){if(0===this.#o.size)return;const t=new Map;for(let r=0;r<e.length;r++){const n=e[r];if(!0===n.__loading)continue;const i=void 0!==n.id?String(n.id):this.#c.get(n)??String(r);this.#o.has(i)&&t.set(i,n)}for(const[r,n]of t)this.#o.get(r)?.row!==n&&this.#R({key:r,data:n,depth:0,hasChildren:!1,isExpanded:!1,parentKey:null,posInSet:0,setSize:0},!0)}#R(e,t=!1){this.#h.push({meta:e,flat:t})>1||queueMicrotask(()=>{const e=this.#h;if(this.#h=[],!this.grid)return;let t=!1;for(const{meta:r,flat:n}of e){if(!n&&this.rowKeyMap.get(r.key)?.data!==r.data)continue;const e=this.#o.get(r.key);e&&e.row!==r.data&&this.#A(r.key),n||!this.expandedKeys.has(r.key)||this.#d.has(r.data)||(this.#d.add(r.data),t=this.requestLazyChildren(r)||t)}t&&this.requestRender()})}requestLazyChildren(e){const{key:t,depth:r,data:n}=e,i=this.#o.get(t);if(i?.row===n)return!1;if(!this.#C(n))return!1;const s=this.queryBoolean("datasource:is-active"),{loadChildren:o}=this.config;if(!s&&!o)return!1;i&&this.#A(t);const a=new AbortController;return this.#o.set(t,{row:n,depth:r,controller:a}),this.#d.add(n),this.#l.delete(n),this.broadcast("tree-load-start",{key:t,row:n,depth:r}),s?(this.grid.query("datasource:fetch-children",{context:{source:"tree",parentNode:n,nodePath:[t]},signal:a.signal}),!0):(this.#K(t,n,r,a),!0)}#q(e){return this.#o.get(e.key)?.row===e.data}#w(e,t){const r=this.#o.get(e);if(r?.row===t)return this.#o.delete(e),r}#A(e){const t=this.#o.get(e);t&&(this.#o.delete(e),this.#d.delete(t.row),this.#l.add(t.row),t.controller.abort(),this.broadcast("tree-load-end",{key:e,row:t.row,depth:t.depth,childCount:0,cancelled:!0}))}#K(e,t,r,n){const i=this.config.loadChildren,s=()=>!n.signal.aborted&&(this.#o.delete(e),!0),o=n=>{if(!s())return;const i=n??[];this.#y(t,i),this.broadcast("tree-load-end",{key:e,row:t,depth:r,childCount:i.length}),this.requestRender()},a=n=>{s()&&(this.broadcast("tree-load-error",{key:e,row:t,depth:r,error:n}),this.requestRender())};let d;try{d=i({row:t,key:e,depth:r,signal:n.signal})}catch(l){return void a(l)}if(d&&"function"==typeof d.subscribe){let e=!1,t=null;const r=()=>{e=!0,t?.unsubscribe(),t=null},i=d.subscribe({next:e=>{o(e),r()},error:e=>{a(e),r()}});return e?void i.unsubscribe():(t=i,void n.signal.addEventListener("abort",r,{once:!0}))}Promise.resolve(d).then(o,a)}resolveEffectiveSortState(){const e=this.grid?.query?.("sort:get-model",null);if(Array.isArray(e)&&e.length>0){const t=e[0];if(Array.isArray(t)&&t.length>0)return{field:t[0].field,direction:"desc"===t[0].direction?-1:1}}return this.sortState}processColumns(e){if(0===this.flattenedRows.length){const t=[...e];if(this.#p){const e=t.findIndex(e=>e.field===this.wrappedTreeColumnField);e>=0&&(t[e]={...t[e],renderer:"renderer"===this.originalTreeColumnRendererProperty?this.originalTreeColumnRenderer:void 0})}return this.#p=!1,this.originalTreeColumnRenderer=void 0,this.originalTreeColumnRendererProperty="viewRenderer",this.wrappedTreeColumnField=void 0,t}const t=[...e];if(0===t.length)return t;const{treeColumn:i}=this.config;let s=0;if(i){const e=t.findIndex(e=>e.field===i);e>=0&&(s=e)}const o=t[s],a=o.field;this.wrappedTreeColumnField!==a&&(this.originalTreeColumnRenderer=o.renderer||o.viewRenderer,this.originalTreeColumnRendererProperty=o.renderer?"renderer":"viewRenderer",this.wrappedTreeColumnField=a);const d=this.originalTreeColumnRenderer,h=()=>this.config,c=this.setIcon.bind(this);return t[s]={...o,renderer:e=>{const{row:t,value:i}=e,{showExpandIcons:s=!0,indentWidth:o}=h(),a=this.#u.get(t),u=a?.depth??0,p=document.createElement("span");if(p.className="tree-cell-wrapper",p.style.setProperty("--tbw-tree-depth",String(u)),void 0!==o&&p.style.setProperty("--tbw-tree-indent-width",`${o}px`),s)if(a&&this.#q(a)){const e=function(e){const t=document.createElement("div");return t.className=`tbw-spinner tbw-spinner--${e}`,t.setAttribute("role","progressbar"),t.setAttribute("aria-label","Loading"),t}("small");e.classList.add("tree-loading"),p.appendChild(e)}else if(a&&a.hasChildren){const e=document.createElement("span");e.className=`${n}${a.isExpanded?` ${r}`:""}`,c(e,a.isExpanded?"collapse":"expand"),e.setAttribute("data-tree-key",a.key),p.appendChild(e)}else{const e=document.createElement("span");e.className="tree-spacer",p.appendChild(e)}const g=document.createElement("span");if(g.className="tree-content",d){const t=d(e);t instanceof Node?g.appendChild(t):"string"==typeof t&&(f=g,(w=t)&&"string"==typeof w?-1!==w.indexOf("<")||-1!==w.indexOf("&")?f.replaceChildren(l(w)):f.textContent=w:f.replaceChildren())}else g.textContent=null!=i?String(i):"";var f,w;return p.appendChild(g),p}},this.#p=!0,t}onCellClick(e){const t=(e.originalEvent?.target)?.closest?.(`.${n}`);if(!t)return!1;if("dblclick"===e.originalEvent.type)return!0;const r=t.getAttribute("data-tree-key");if(!r)return!1;const i=this.rowKeyMap.get(r);return!!i&&(this.expandedKeys=w(this.expandedKeys,r),this.expandedKeys.has(r)&&this.requestLazyChildren(i),this.broadcast("tree-expand",{key:r,row:i.data,expanded:this.expandedKeys.has(r),depth:i.depth,expandedKeys:[...this.expandedKeys]}),this.requestRender(),!0)}onKeyDown(e){if(" "!==e.key)return;if(function(e){const t=e.composedPath?.()??[],r=t.length?t[0]:e.target;if(!(r instanceof HTMLElement))return!1;const n=r.tagName;return"INPUT"===n||"SELECT"===n||"TEXTAREA"===n||r.isContentEditable}(e))return;const t=this.grid._focusRow,r=this.#u.get(this.rows[t]);return r?.hasChildren?(e.preventDefault(),this.expandedKeys=w(this.expandedKeys,r.key),this.expandedKeys.has(r.key)&&this.requestLazyChildren(r),this.broadcast("tree-expand",{key:r.key,row:r.data,expanded:this.expandedKeys.has(r.key),depth:r.depth,expandedKeys:[...this.expandedKeys]}),this.requestRenderWithFocus(),!0):void 0}onHeaderClick(e){if(0===this.flattenedRows.length||!e.column.sortable)return!1;const t=this.grid?.query?.("sort:get-model",null);if(Array.isArray(t)&&t.length>0)return!1;const{field:r}=e.column;this.sortState&&this.sortState.field===r?1===this.sortState.direction?this.sortState={field:r,direction:-1}:this.sortState=null:this.sortState={field:r,direction:1};const n=this.grid;return void 0!==n._sortState&&(n._sortState=this.sortState?{...this.sortState}:null),this.broadcast("sort-change",{field:r,direction:this.sortState?.direction??0}),this.requestRender(),!0}afterRender(){const e=this.gridElement?.querySelector(".rows");if(!e)return;const t=this.animationStyle,r=!1!==t&&this.keysToAnimate.size>0,n="fade"===t?"tbw-tree-fade-in":"tbw-tree-slide-in";for(const i of e.querySelectorAll(".data-grid-row")){const e=this.#u.get(i.__rowDataRef);e&&(e.hasChildren?i.setAttribute("aria-expanded",String(e.isExpanded)):i.hasAttribute("aria-expanded")&&i.removeAttribute("aria-expanded"),i.classList.toggle("tbw-row-expanded",e.hasChildren&&e.isExpanded),this.#q(e)?i.setAttribute("aria-busy","true"):i.hasAttribute("aria-busy")&&!i.classList.contains("tbw-row-loading")&&i.removeAttribute("aria-busy"),r&&e.key&&this.keysToAnimate.has(e.key)&&(i.classList.add(n),i.addEventListener("animationend",()=>i.classList.remove(n),{once:!0})))}this.keysToAnimate.clear()}expand(e){this.expandedKeys.add(e);const t=this.rowKeyMap.get(e);t&&this.requestLazyChildren(t),this.requestRender()}collapse(e){this.expandedKeys.delete(e),this.requestRender()}toggle(e){this.expandedKeys=w(this.expandedKeys,e);const t=this.rowKeyMap.get(e);t?(this.expandedKeys.has(e)&&this.requestLazyChildren(t),this.broadcast("tree-expand",{key:e,row:t.data,expanded:this.expandedKeys.has(e),depth:t.depth,expandedKeys:[...this.expandedKeys]})):this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}expandAll(){this.expandedKeys=y(this.rows,this.config),this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}collapseAll(){this.expandedKeys=new Set,this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}isExpanded(e){return this.expandedKeys.has(e)}getExpandedKeys(){return[...this.expandedKeys]}getFlattenedRows(){return[...this.flattenedRows]}getRowMeta(e){return this.#u.get(e)}getRowByKey(e){return this.rowKeyMap.get(e)?.data}expandToKey(e){this.expandedKeys=b(this.rows,e,this.config,this.expandedKeys),this.requestRender()}};e.TreePlugin=v});
|
|
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_tree={},e.TbwGrid)}(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"});var r="expanded",n="tree-toggle",i="__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("")),s=(new RegExp(`__(proto|defineGetter|defineSetter)|${i.slice(3).join("|")}|this\\b`),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("|"))),o=/^on\w+$/i,a=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),d=/^\s*(javascript|vbscript|data|blob):/i;function l(e){const t=document.createElement("template");return e&&"string"==typeof e&&(t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const n of r){const e=n.tagName.toLowerCase();if(s.has(e)){t.push(n);continue}if(("svg"===e||"http://www.w3.org/2000/svg"===n.namespaceURI)&&Array.from(n.attributes).some(e=>o.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(n);continue}const r=[];for(const t of n.attributes){const e=t.name.toLowerCase();o.test(e)?r.push(t.name):"is"!==e?(a.has(e)&&d.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name):r.push(t.name)}r.forEach(e=>n.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content)),t.content}function h(e,t,r=new WeakMap,n){const i=n?function(e,t){let r;for(let n=0;n<e.length;n++){const i=t(e[n]);i!==e[n]&&(r??=e.slice(),r[n]=i)}return r??e}(e,n):e,s=[];for(const u of["structure","transform"])for(const e of t)e.hierarchyStage===u&&e.beginHierarchy(i)&&s.push(e);if(0===s.length)return[...i];const o=[],a=(e,t,r)=>{n&&t&&(e=function(e,t){let r;for(let n=0;n<e.length;n++){const i=t(e[n].row);i!==e[n].row&&(r??=e.slice(),r[n]={...e[n],row:i})}return r??e}(e,n));const i={parent:t?t.row:null,parentKey:t?.key??null,depth:r};for(const n of s)e=n.processSiblings(e,i);return e},d=(e,t)=>{const n=e.length;for(let i=0;i<n;i++){const s=e[i];o.push(s.row),"object"==typeof s.row&&null!==s.row&&r.set(s.row,{level:t+1,setSize:n,posInSet:i+1});const l=s.children;s.expanded&&l&&d(s.shaped?l:a(l,s,t+1),t+1)}},l=new Array(i.length);for(let u=0;u<i.length;u++)l[u]={row:i[u]};d(a(l,null,0),0);const h=e=>"object"==typeof e&&null!==e?r.get(e):void 0;let c=!1;for(const u of s)u.endHierarchy(o,h)&&(c=!0);if(!c)for(const u of o)"object"==typeof u&&null!==u&&r.delete(u);return o}function c(e,t,r){const n=String(r);e.getAttribute(t)!==n&&e.setAttribute(t,n)}function u(e){return"function"==typeof e.processSiblings}function p(e){return e.constructor.manifest?.hookPriority?.processRows??0}var g=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 r=this.#t();return r.includes(t)?r[r.length-1]!==t?e:(this.#e=new WeakMap,h(e,r,this.#e,this.#r())):(this.#e=new WeakMap,h(e,[t],this.#e,this.#r()))}#r(){const e=this.grid?.query?.("getRowSubstitutes",null)??[];let t;for(const n of e)if(n?.size){t??=new Map;for(const[e,r]of n)t.set(e,r)}if(!t)return;const r=this.grid;return e=>{if("object"!=typeof e||null===e)return e;let n;try{n=r.getRowId(e)}catch{return e}return t.has(n)?t.get(n):e}}getRowMeta(e){return"object"==typeof e&&null!==e?this.#e.get(e):void 0}afterRender(){this.#n()}onScrollRender(){this.#n()}#t(){return(this.grid?._pluginManager?.getPlugins?.()??[]).filter(u).sort((e,t)=>p(e)-p(t))}#n(){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,c(i,"aria-level",e.level),c(i,"aria-setsize",e.setSize),c(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)}};function f(e,t,r){return void 0!==e.id?String(e.id):r?`${r}-${t}`:String(t)}function w(e,t){const r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r}function y(e,t,r=null,n=0){const i=t.childrenField??"children",s=new Set;for(let o=0;o<e.length;o++){const a=e[o],d=f(a,o,r),l=a[i];if(Array.isArray(l)&&l.length>0){s.add(d);const e=y(l,t,d,n+1);for(const t of e)s.add(t)}}return s}function m(e,t,r,n=null,i=0){const s=r.childrenField??"children";for(let o=0;o<e.length;o++){const a=e[o],d=f(a,o,n);if(d===t)return[d];const l=a[s];if(Array.isArray(l)&&l.length>0){const e=m(l,t,r,d,i+1);if(e)return[d,...e]}}return null}function b(e,t,r,n){const i=m(e,t,r);if(!i)return n;const s=new Set(n);for(let o=0;o<i.length-1;o++)s.add(i[o]);return s}function x(e,t="children",r){if(!Array.isArray(e)||0===e.length)return!1;for(const n of e){if(!n||!0===n.__loading)continue;const e=n[t];if(Array.isArray(e)&&e.length>0)return!0;if(null!=e&&!Array.isArray(e)&&e)return!0;if(r?.(n))return!0}return!1}var v=class extends t.BaseGridPlugin{static manifest={modifiesRowStructure:!0,hookPriority:{processRows:10,onCellClick:-10},incompatibleWith:[{name:"pivot",reason:"PivotPlugin replaces the entire row and column structure with aggregated pivot data. Tree hierarchy cannot coexist with pivot aggregation."}],events:[{type:"tree-expand",description:"Emitted when tree expansion state changes (toggle, expand all, collapse all). Broadcast to both DOM consumers and plugin bus."},{type:"tree-load-start",description:"Emitted when lazy child loading starts for a node whose children are not yet loaded."},{type:"tree-load-end",description:"Emitted when lazy child loading completes and children have been merged into the parent row."},{type:"tree-load-error",description:"Emitted when lazy child loading fails. The node leaves its loading state and can be retried."}],queries:[{type:"canMoveRow",description:"Returns false for rows with children (parent nodes cannot be reordered)"},{type:"datasource:viewport-mapping",description:"Translates flat viewport row indices to top-level node indices for ServerSide pagination."}]};static dependencies=[{name:"hierarchy",required:!0,reason:"Builds the hierarchical row model",provide:()=>new g},{name:"multiSort",required:!1,reason:"Queries sort model for coordinated tree sorting"},{name:"serverSide",required:!1,reason:"Consumes datasource events for lazy-loaded tree data"}];name="tree";hierarchyStage="structure";styles='@layer tbw-plugins{tbw-grid .cell[data-field=__tbw_expander]{justify-content:flex-start;align-items:center;padding:0;display:flex;border-inline-end:none!important}tbw-grid .header-row .cell[data-field=__tbw_expander]{display:none}tbw-grid .header-row .cell[data-field=__tbw_expander]+.cell{grid-column:1/3}tbw-grid .tree-cell-wrapper{vertical-align:middle;align-items:center;padding-inline-start:calc(var(--tbw-tree-depth,0) * var(--tbw-tree-indent-width,var(--tbw-tree-toggle-size,1.25em)));display:inline-flex;overflow:visible}tbw-grid .tree-expander{box-sizing:border-box;justify-content:flex-start;align-items:center;width:100%;height:100%;display:flex}tbw-grid .tree-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;width:var(--tbw-tree-toggle-size,1.25em);height:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}tbw-grid .tree-toggle:hover{color:var(--tbw-tree-accent,var(--tbw-color-accent))}tbw-grid .tree-toggle{position:relative}tbw-grid .tree-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%}tbw-grid .tree-spacer{width:var(--tbw-tree-toggle-size,1.25em);height:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0;display:inline-block}@media (pointer:coarse){tbw-grid .tree-toggle,tbw-grid .tree-spacer{min-width:var(--tbw-touch-target-min,24px);min-height:var(--tbw-touch-target-min,24px)}}tbw-grid .tree-loading{--tbw-spinner-size:var(--tbw-tree-toggle-size,1.25em);flex-shrink:0}tbw-grid .data-grid-row.tbw-tree-slide-in{animation:tbw-tree-slide-in var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}tbw-grid .data-grid-row.tbw-tree-fade-in{animation:tbw-tree-fade-in var(--tbw-animation-duration,.2s) var(--tbw-animation-easing,ease-out) forwards}@keyframes tbw-tree-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}@keyframes tbw-tree-fade-in{0%{opacity:0}to{opacity:1}}}';get defaultConfig(){return{childrenField:"children",autoDetect:!0,defaultExpanded:!1,indentWidth:20,showExpandIcons:!0,animation:"slide"}}expandedKeys=new Set;initialExpansionDone=!1;flattenedRows=[];rowKeyMap=new Map;previousVisibleKeys=new Set;keysToAnimate=new Set;#i=[];#s=0;sortState=null;#o=null;#a=new Map;#d=new WeakSet;#l=new WeakSet;#h=new WeakSet;#c=[];#u=new WeakMap;#p=new WeakMap;originalTreeColumnRenderer;originalTreeColumnRendererProperty="viewRenderer";wrappedTreeColumnField;#g=!1;#f=!1;detach(){this.expandedKeys.clear(),this.initialExpansionDone=!1,this.flattenedRows=[],this.#i=[],this.#s=0,this.rowKeyMap.clear(),this.previousVisibleKeys.clear(),this.keysToAnimate.clear(),this.sortState=null,this.#o=null,this.#d=new WeakSet,this.#l=new WeakSet,this.#h=new WeakSet,this.#c=[];for(const e of this.#a.values())e.controller.abort();this.#a.clear(),this.originalTreeColumnRenderer=void 0,this.originalTreeColumnRendererProperty="viewRenderer",this.wrappedTreeColumnField=void 0,this.#g=!1}handleQuery(e){if("canMoveRow"===e.type){const t=e.context,r=this.config.childrenField??"children",n=t?.[r];if(Array.isArray(n)&&n.length>0)return!1}if("datasource:viewport-mapping"===e.type){const{viewportStart:t,viewportEnd:r}=e.context;if(0===this.flattenedRows.length)return;return function(e,t,r,n){const i=e.length-1,s=t=>Math.max(0,e[Math.max(0,Math.min(t,i))]??0);return{startNode:s(r),endNode:s(n)+1,totalLoadedNodes:t}}(this.#i,this.#s,t,r)}}attach(e){super.attach(e),this.on("datasource:data",e=>{const t=e;t.claimed||(t.claimed=!0)}),this.on("datasource:children",e=>{const t=e;if("tree"!==t.context?.source)return;t.claimed=!0;const r=t.context.parentNode;if(r){const e=this.#w(r),n=this.#y(e,r);if(!n&&(this.#l.has(r)||this.#h.has(r)))return;this.#m(r,t.rows??[]),this.broadcast("tree-load-end",{key:e,row:r,depth:n?.depth??this.rowKeyMap.get(e)?.depth??0,childCount:t.rows?.length??0}),this.requestRender()}}),this.on("datasource:error",e=>{const t=e;if("tree"!==t.context?.source)return;const r=t.context.parentNode;if(!r)return;const n=this.#w(r),i=this.#y(n,r);i&&(this.broadcast("tree-load-error",{key:n,row:r,depth:i.depth,error:t.error}),this.requestRender())})}get animationStyle(){return!!this.isAnimationEnabled&&(this.config.animation??"slide")}detect(e){if(!this.config.autoDetect)return!1;const t=e,r=this.config.childrenField??function(e){if(!Array.isArray(e)||0===e.length)return null;const t=["children","items","nodes","subRows","nested"];for(const r of e)if(r&&"object"==typeof r)for(const e of t){const t=r[e];if(Array.isArray(t)&&t.length>0)return e}return null}(t)??"children";return x(t,r)}processRows(e){const t=this.grid?.getPluginByName?.("hierarchy");return t?t.process(e,this):h(e,[this])}beginHierarchy(e){const t=e;if(0===t.length||!x(t,this.config.childrenField??"children",this.config.hasChildren))return this.flattenedRows=[],this.#i=[],this.#s=0,this.rowKeyMap.clear(),this.previousVisibleKeys.clear(),this.#b(t),this.#x(),!1;const r="server"===this.grid?.query?.("datasource:sort-mode",null)?.[0];return this.#o=r?null:this.resolveEffectiveSortState(),this.config.defaultExpanded&&!this.initialExpansionDone&&(this.expandedKeys=y(t,this.config),this.initialExpansionDone=!0),this.#p=new WeakMap,!0}processSiblings(e,t){const{parentKey:r,depth:n}=t,i=this.config.childrenField??"children",s=this.config.hasChildren;for(let d=0;d<e.length;d++)this.#v(e[d].row,d,r);const o=this.#o,a=o?this.#S(e,o.field,o.direction):e;for(let d=0;d<a.length;d++){const e=a[d],t=e.row,o=this.#v(t,d,r),l=t[i],h=Array.isArray(l)&&l.length>0,c=h||!0!==t.__loading&&(s?s(t):null!=l&&!Array.isArray(l)&&!!l),u=this.expandedKeys.has(o);this.#p.set(t,{key:o,data:t,depth:n,hasChildren:c,isExpanded:u,parentKey:r,posInSet:d+1,setSize:a.length}),e.key=o,h&&u&&(e.expanded=!0,e.children=l.map(e=>({row:e})))}return a}endHierarchy(e,t){const r=this.#p;this.#p=new WeakMap,this.flattenedRows=[],this.rowKeyMap.clear(),this.keysToAnimate.clear();const n=new Set,i=new Array(e.length);let s=-1;for(let o=0;o<e.length;o++){const a=e[o],d=r.get(a);if(null===d?.parentKey&&s++,i[o]=s,!d)continue;const l=t(a)?.level;void 0!==l&&(d.depth=l-1),this.flattenedRows.push(d),this.rowKeyMap.set(d.key,d),this.#p.set(a,d),n.add(d.key),!this.previousVisibleKeys.has(d.key)&&d.depth>0&&this.keysToAnimate.add(d.key),this.#R(d)&&this.#k(d)}return this.previousVisibleKeys=n,this.#i=i,this.#s=s+1,this.#x(),!0}#x(){this.#f||(this.#f=!0,queueMicrotask(()=>{this.#f=!1,this.grid&&this.#g!==this.flattenedRows.length>0&&this.requestColumnsRender()}))}#v(e,t,r){if(void 0!==e.id){const t=String(e.id);return this.#u.set(e,t),t}const n=this.#u.get(e);if(void 0!==n)return n;const i=r?`${r}-${t}`:String(t);return this.#u.set(e,i),i}#S(e,t,r){const n=new Map;for(const i of e)n.set(i.row,i);return this.#C(e.map(e=>e.row),t,r).map(e=>n.get(e)??{row:e})}#C(e,r,n){const i=this.grid,s=i?._columns??[],o={field:r,direction:n},a=[...e],d=(i?.effectiveConfig?.sortHandler??t.builtInSort)(a,o,s);return d&&"function"==typeof d.then?(d.catch(()=>{}),(0,t.builtInSort)(a,o,s)):d}#w(e){return this.#u.get(e)??String(e.id??"?")}#m(e,t){e[this.config.childrenField??"children"]=t,this.#d.add(e)}#A(e){if(this.#d.has(e))return!1;const t=e[this.config.childrenField??"children"];if(Array.isArray(t)&&t.length>0)return!1;const r=this.config.hasChildren;return r?r(e):null!=t&&!Array.isArray(t)&&!!t}#R(e){if(!0===e.data.__loading)return!1;const t=this.#a.get(e.key);return t?t.row!==e.data:e.isExpanded&&e.hasChildren&&!this.#l.has(e.data)&&this.#A(e.data)}#b(e){if(0===this.#a.size)return;const t=new Map;for(let r=0;r<e.length;r++){const n=e[r];if(!0===n.__loading)continue;const i=void 0!==n.id?String(n.id):this.#u.get(n)??String(r);this.#a.has(i)&&t.set(i,n)}for(const[r,n]of t)this.#a.get(r)?.row!==n&&this.#k({key:r,data:n,depth:0,hasChildren:!1,isExpanded:!1,parentKey:null,posInSet:0,setSize:0},!0)}#k(e,t=!1){this.#c.push({meta:e,flat:t})>1||queueMicrotask(()=>{const e=this.#c;if(this.#c=[],!this.grid)return;let t=!1;for(const{meta:r,flat:n}of e){if(!n&&this.rowKeyMap.get(r.key)?.data!==r.data)continue;const e=this.#a.get(r.key);e&&e.row!==r.data&&this.#K(r.key),n||!this.expandedKeys.has(r.key)||this.#l.has(r.data)||(this.#l.add(r.data),t=this.requestLazyChildren(r)||t)}t&&this.requestRender()})}requestLazyChildren(e){const{key:t,depth:r,data:n}=e,i=this.#a.get(t);if(i?.row===n)return!1;if(!this.#A(n))return!1;const s=this.queryBoolean("datasource:is-active"),{loadChildren:o}=this.config;if(!s&&!o)return!1;i&&this.#K(t);const a=new AbortController;return this.#a.set(t,{row:n,depth:r,controller:a}),this.#l.add(n),this.#h.delete(n),this.broadcast("tree-load-start",{key:t,row:n,depth:r}),s?(this.grid.query("datasource:fetch-children",{context:{source:"tree",parentNode:n,nodePath:[t]},signal:a.signal}),!0):(this.#q(t,n,r,a),!0)}#E(e){return this.#a.get(e.key)?.row===e.data}#y(e,t){const r=this.#a.get(e);if(r?.row===t)return this.#a.delete(e),r}#K(e){const t=this.#a.get(e);t&&(this.#a.delete(e),this.#l.delete(t.row),this.#h.add(t.row),t.controller.abort(),this.broadcast("tree-load-end",{key:e,row:t.row,depth:t.depth,childCount:0,cancelled:!0}))}#q(e,t,r,n){const i=this.config.loadChildren,s=()=>!n.signal.aborted&&(this.#a.delete(e),!0),o=n=>{if(!s())return;const i=n??[];this.#m(t,i),this.broadcast("tree-load-end",{key:e,row:t,depth:r,childCount:i.length}),this.requestRender()},a=n=>{s()&&(this.broadcast("tree-load-error",{key:e,row:t,depth:r,error:n}),this.requestRender())};let d;try{d=i({row:t,key:e,depth:r,signal:n.signal})}catch(l){return void a(l)}if(d&&"function"==typeof d.subscribe){let e=!1,t=null;const r=()=>{e=!0,t?.unsubscribe(),t=null},i=d.subscribe({next:e=>{o(e),r()},error:e=>{a(e),r()}});return e?void i.unsubscribe():(t=i,void n.signal.addEventListener("abort",r,{once:!0}))}Promise.resolve(d).then(o,a)}resolveEffectiveSortState(){const e=this.grid?.query?.("sort:get-model",null);if(Array.isArray(e)&&e.length>0){const t=e[0];if(Array.isArray(t)&&t.length>0)return{field:t[0].field,direction:"desc"===t[0].direction?-1:1}}return this.sortState}processColumns(e){if(0===this.flattenedRows.length){const t=[...e];if(this.#g){const e=t.findIndex(e=>e.field===this.wrappedTreeColumnField);e>=0&&(t[e]={...t[e],renderer:"renderer"===this.originalTreeColumnRendererProperty?this.originalTreeColumnRenderer:void 0})}return this.#g=!1,this.originalTreeColumnRenderer=void 0,this.originalTreeColumnRendererProperty="viewRenderer",this.wrappedTreeColumnField=void 0,t}const t=[...e];if(0===t.length)return t;const{treeColumn:i}=this.config;let s=0;if(i){const e=t.findIndex(e=>e.field===i);e>=0&&(s=e)}const o=t[s],a=o.field;this.wrappedTreeColumnField!==a&&(this.originalTreeColumnRenderer=o.renderer||o.viewRenderer,this.originalTreeColumnRendererProperty=o.renderer?"renderer":"viewRenderer",this.wrappedTreeColumnField=a);const d=this.originalTreeColumnRenderer,h=()=>this.config,c=this.setIcon.bind(this);return t[s]={...o,renderer:e=>{const{row:t,value:i}=e,{showExpandIcons:s=!0,indentWidth:o}=h(),a=this.#p.get(t),u=a?.depth??0,p=document.createElement("span");if(p.className="tree-cell-wrapper",p.style.setProperty("--tbw-tree-depth",String(u)),void 0!==o&&p.style.setProperty("--tbw-tree-indent-width",`${o}px`),s)if(a&&this.#E(a)){const e=function(e){const t=document.createElement("div");return t.className=`tbw-spinner tbw-spinner--${e}`,t.setAttribute("role","progressbar"),t.setAttribute("aria-label","Loading"),t}("small");e.classList.add("tree-loading"),p.appendChild(e)}else if(a&&a.hasChildren){const e=document.createElement("span");e.className=`${n}${a.isExpanded?` ${r}`:""}`,c(e,a.isExpanded?"collapse":"expand"),e.setAttribute("data-tree-key",a.key),p.appendChild(e)}else{const e=document.createElement("span");e.className="tree-spacer",p.appendChild(e)}const g=document.createElement("span");if(g.className="tree-content",d){const t=d(e);t instanceof Node?g.appendChild(t):"string"==typeof t&&(f=g,(w=t)&&"string"==typeof w?-1!==w.indexOf("<")||-1!==w.indexOf("&")?f.replaceChildren(l(w)):f.textContent=w:f.replaceChildren())}else g.textContent=null!=i?String(i):"";var f,w;return p.appendChild(g),p}},this.#g=!0,t}onCellClick(e){const t=(e.originalEvent?.target)?.closest?.(`.${n}`);if(!t)return!1;if("dblclick"===e.originalEvent.type)return!0;const r=t.getAttribute("data-tree-key");if(!r)return!1;const i=this.rowKeyMap.get(r);return!!i&&(this.expandedKeys=w(this.expandedKeys,r),this.expandedKeys.has(r)&&this.requestLazyChildren(i),this.broadcast("tree-expand",{key:r,row:i.data,expanded:this.expandedKeys.has(r),depth:i.depth,expandedKeys:[...this.expandedKeys]}),this.requestRender(),!0)}onKeyDown(e){if(" "!==e.key)return;if(function(e){const t=e.composedPath?.()??[],r=t.length?t[0]:e.target;if(!(r instanceof HTMLElement))return!1;const n=r.tagName;return"INPUT"===n||"SELECT"===n||"TEXTAREA"===n||r.isContentEditable}(e))return;const t=this.grid._focusRow,r=this.#p.get(this.rows[t]);return r?.hasChildren?(e.preventDefault(),this.expandedKeys=w(this.expandedKeys,r.key),this.expandedKeys.has(r.key)&&this.requestLazyChildren(r),this.broadcast("tree-expand",{key:r.key,row:r.data,expanded:this.expandedKeys.has(r.key),depth:r.depth,expandedKeys:[...this.expandedKeys]}),this.requestRenderWithFocus(),!0):void 0}onHeaderClick(e){if(0===this.flattenedRows.length||!e.column.sortable)return!1;const t=this.grid?.query?.("sort:get-model",null);if(Array.isArray(t)&&t.length>0)return!1;const{field:r}=e.column;this.sortState&&this.sortState.field===r?1===this.sortState.direction?this.sortState={field:r,direction:-1}:this.sortState=null:this.sortState={field:r,direction:1};const n=this.grid;return void 0!==n._sortState&&(n._sortState=this.sortState?{...this.sortState}:null),this.broadcast("sort-change",{field:r,direction:this.sortState?.direction??0}),this.requestRender(),!0}afterRender(){const e=this.gridElement?.querySelector(".rows");if(!e)return;const t=this.animationStyle,r=!1!==t&&this.keysToAnimate.size>0,n="fade"===t?"tbw-tree-fade-in":"tbw-tree-slide-in";for(const i of e.querySelectorAll(".data-grid-row")){const e=this.#p.get(i.__rowDataRef);e&&(e.hasChildren?i.setAttribute("aria-expanded",String(e.isExpanded)):i.hasAttribute("aria-expanded")&&i.removeAttribute("aria-expanded"),i.classList.toggle("tbw-row-expanded",e.hasChildren&&e.isExpanded),this.#E(e)?i.setAttribute("aria-busy","true"):i.hasAttribute("aria-busy")&&!i.classList.contains("tbw-row-loading")&&i.removeAttribute("aria-busy"),r&&e.key&&this.keysToAnimate.has(e.key)&&(i.classList.add(n),i.addEventListener("animationend",()=>i.classList.remove(n),{once:!0})))}this.keysToAnimate.clear()}expand(e){this.expandedKeys.add(e);const t=this.rowKeyMap.get(e);t&&this.requestLazyChildren(t),this.requestRender()}collapse(e){this.expandedKeys.delete(e),this.requestRender()}toggle(e){this.expandedKeys=w(this.expandedKeys,e);const t=this.rowKeyMap.get(e);t?(this.expandedKeys.has(e)&&this.requestLazyChildren(t),this.broadcast("tree-expand",{key:e,row:t.data,expanded:this.expandedKeys.has(e),depth:t.depth,expandedKeys:[...this.expandedKeys]})):this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}expandAll(){this.expandedKeys=y(this.rows,this.config),this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}collapseAll(){this.expandedKeys=new Set,this.emitPluginEvent("tree-expand",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}isExpanded(e){return this.expandedKeys.has(e)}getExpandedKeys(){return[...this.expandedKeys]}getFlattenedRows(){return[...this.flattenedRows]}getRowMeta(e){return this.#p.get(e)}getRowByKey(e){return this.rowKeyMap.get(e)?.data}expandToKey(e){this.expandedKeys=b(this.rows,e,this.config,this.expandedKeys),this.requestRender()}};e.TreePlugin=v});
|
|
2
2
|
//# sourceMappingURL=tree.umd.js.map
|