@toolbox-web/grid 0.2.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -13
- package/all.d.ts +25 -5659
- package/all.d.ts.map +1 -0
- package/all.js +524 -450
- package/all.js.map +1 -1
- package/index.d.ts +8 -2678
- package/index.d.ts.map +1 -0
- package/index.js +3929 -25
- package/index.js.map +1 -1
- package/lib/core/constants.d.ts +114 -0
- package/lib/core/constants.d.ts.map +1 -0
- package/lib/core/grid.d.ts +337 -0
- package/lib/core/grid.d.ts.map +1 -0
- package/lib/core/internal/aggregators.d.ts +67 -0
- package/lib/core/internal/aggregators.d.ts.map +1 -0
- package/lib/core/internal/column-state.d.ts +124 -0
- package/lib/core/internal/column-state.d.ts.map +1 -0
- package/lib/core/internal/columns.d.ts +107 -0
- package/lib/core/internal/columns.d.ts.map +1 -0
- package/lib/core/internal/dom-builder.d.ts +115 -0
- package/lib/core/internal/dom-builder.d.ts.map +1 -0
- package/lib/core/internal/editing.d.ts +76 -0
- package/lib/core/internal/editing.d.ts.map +1 -0
- package/lib/core/internal/editors.d.ts +8 -0
- package/lib/core/internal/editors.d.ts.map +1 -0
- package/lib/core/internal/event-delegation.d.ts +11 -0
- package/lib/core/internal/event-delegation.d.ts.map +1 -0
- package/lib/core/internal/grid-internals.d.ts +83 -0
- package/lib/core/internal/grid-internals.d.ts.map +1 -0
- package/lib/core/internal/header.d.ts +7 -0
- package/lib/core/internal/header.d.ts.map +1 -0
- package/lib/core/internal/idle-scheduler.d.ts +65 -0
- package/lib/core/internal/idle-scheduler.d.ts.map +1 -0
- package/lib/core/internal/inference.d.ts +12 -0
- package/lib/core/internal/inference.d.ts.map +1 -0
- package/lib/core/internal/keyboard.d.ts +18 -0
- package/lib/core/internal/keyboard.d.ts.map +1 -0
- package/lib/core/internal/resize.d.ts +3 -0
- package/lib/core/internal/resize.d.ts.map +1 -0
- package/lib/core/internal/rows.d.ts +35 -0
- package/lib/core/internal/rows.d.ts.map +1 -0
- package/lib/core/internal/sanitize.d.ts +13 -0
- package/lib/core/internal/sanitize.d.ts.map +1 -0
- package/lib/core/internal/shell.d.ts +228 -0
- package/lib/core/internal/shell.d.ts.map +1 -0
- package/lib/core/internal/sorting.d.ts +24 -0
- package/lib/core/internal/sorting.d.ts.map +1 -0
- package/lib/core/internal/touch-scroll.d.ts +54 -0
- package/lib/core/internal/touch-scroll.d.ts.map +1 -0
- package/lib/core/internal/utils.d.ts +38 -0
- package/lib/core/internal/utils.d.ts.map +1 -0
- package/lib/core/internal/virtualization.d.ts +66 -0
- package/lib/core/internal/virtualization.d.ts.map +1 -0
- package/lib/core/plugin/base-plugin.d.ts +616 -0
- package/lib/core/plugin/base-plugin.d.ts.map +1 -0
- package/lib/core/plugin/index.d.ts +11 -0
- package/lib/core/plugin/index.d.ts.map +1 -0
- package/lib/core/plugin/plugin-manager.d.ts +183 -0
- package/lib/core/plugin/plugin-manager.d.ts.map +1 -0
- package/lib/core/plugin/types.d.ts +196 -0
- package/lib/core/plugin/types.d.ts.map +1 -0
- package/lib/core/types.d.ts +841 -0
- package/lib/core/types.d.ts.map +1 -0
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts +46 -0
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts.map +1 -0
- package/lib/plugins/clipboard/copy.d.ts +47 -0
- package/lib/plugins/clipboard/copy.d.ts.map +1 -0
- package/lib/plugins/clipboard/index.d.ts +7 -0
- package/lib/plugins/clipboard/index.d.ts.map +1 -0
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/clipboard/paste.d.ts +25 -0
- package/lib/plugins/clipboard/paste.d.ts.map +1 -0
- package/lib/plugins/clipboard/types.d.ts +40 -0
- package/lib/plugins/clipboard/types.d.ts.map +1 -0
- package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts +54 -0
- package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts.map +1 -0
- package/lib/plugins/column-virtualization/column-virtualization.d.ts +53 -0
- package/lib/plugins/column-virtualization/column-virtualization.d.ts.map +1 -0
- package/lib/plugins/column-virtualization/index.d.ts +7 -0
- package/lib/plugins/column-virtualization/index.d.ts.map +1 -0
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/column-virtualization/types.d.ts +41 -0
- package/lib/plugins/column-virtualization/types.d.ts.map +1 -0
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +52 -0
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -0
- package/lib/plugins/context-menu/index.d.ts +7 -0
- package/lib/plugins/context-menu/index.d.ts.map +1 -0
- package/lib/plugins/context-menu/index.js +24 -24
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/context-menu/menu.d.ts +38 -0
- package/lib/plugins/context-menu/menu.d.ts.map +1 -0
- package/lib/plugins/context-menu/types.d.ts +77 -0
- package/lib/plugins/context-menu/types.d.ts.map +1 -0
- package/lib/plugins/export/ExportPlugin.d.ts +53 -0
- package/lib/plugins/export/ExportPlugin.d.ts.map +1 -0
- package/lib/plugins/export/csv.d.ts +31 -0
- package/lib/plugins/export/csv.d.ts.map +1 -0
- package/lib/plugins/export/excel.d.ts +12 -0
- package/lib/plugins/export/excel.d.ts.map +1 -0
- package/lib/plugins/export/index.d.ts +7 -0
- package/lib/plugins/export/index.d.ts.map +1 -0
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/export/types.d.ts +57 -0
- package/lib/plugins/export/types.d.ts.map +1 -0
- package/lib/plugins/filtering/FilteringPlugin.d.ts +128 -0
- package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -0
- package/lib/plugins/filtering/filter-model.d.ts +38 -0
- package/lib/plugins/filtering/filter-model.d.ts.map +1 -0
- package/lib/plugins/filtering/index.d.ts +7 -0
- package/lib/plugins/filtering/index.d.ts.map +1 -0
- package/lib/plugins/filtering/index.js +5 -5
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/filtering/types.d.ts +157 -0
- package/lib/plugins/filtering/types.d.ts.map +1 -0
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +51 -0
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -0
- package/lib/plugins/grouping-columns/grouping-columns.d.ts +41 -0
- package/lib/plugins/grouping-columns/grouping-columns.d.ts.map +1 -0
- package/lib/plugins/grouping-columns/index.d.ts +7 -0
- package/lib/plugins/grouping-columns/index.d.ts.map +1 -0
- package/lib/plugins/grouping-columns/index.js +58 -42
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-columns/types.d.ts +91 -0
- package/lib/plugins/grouping-columns/types.d.ts.map +1 -0
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +120 -0
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts.map +1 -0
- package/lib/plugins/grouping-rows/grouping-rows.d.ts +51 -0
- package/lib/plugins/grouping-rows/grouping-rows.d.ts.map +1 -0
- package/lib/plugins/grouping-rows/index.d.ts +7 -0
- package/lib/plugins/grouping-rows/index.d.ts.map +1 -0
- package/lib/plugins/grouping-rows/index.js +51 -51
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/grouping-rows/types.d.ts +95 -0
- package/lib/plugins/grouping-rows/types.d.ts.map +1 -0
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +147 -0
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -0
- package/lib/plugins/master-detail/index.d.ts +7 -0
- package/lib/plugins/master-detail/index.d.ts.map +1 -0
- package/lib/plugins/master-detail/index.js +235 -78
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/master-detail/master-detail.d.ts +30 -0
- package/lib/plugins/master-detail/master-detail.d.ts.map +1 -0
- package/lib/plugins/master-detail/types.d.ts +40 -0
- package/lib/plugins/master-detail/types.d.ts.map +1 -0
- package/lib/plugins/multi-sort/MultiSortPlugin.d.ts +58 -0
- package/lib/plugins/multi-sort/MultiSortPlugin.d.ts.map +1 -0
- package/lib/plugins/multi-sort/index.d.ts +7 -0
- package/lib/plugins/multi-sort/index.d.ts.map +1 -0
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/multi-sort/multi-sort.d.ts +51 -0
- package/lib/plugins/multi-sort/multi-sort.d.ts.map +1 -0
- package/lib/plugins/multi-sort/types.d.ts +25 -0
- package/lib/plugins/multi-sort/types.d.ts.map +1 -0
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +58 -0
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts.map +1 -0
- package/lib/plugins/pinned-columns/index.d.ts +7 -0
- package/lib/plugins/pinned-columns/index.d.ts.map +1 -0
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-columns/pinned-columns.d.ts +62 -0
- package/lib/plugins/pinned-columns/pinned-columns.d.ts.map +1 -0
- package/lib/plugins/pinned-columns/types.d.ts +20 -0
- package/lib/plugins/pinned-columns/types.d.ts.map +1 -0
- package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts +64 -0
- package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts.map +1 -0
- package/lib/plugins/pinned-rows/index.d.ts +7 -0
- package/lib/plugins/pinned-rows/index.d.ts.map +1 -0
- package/lib/plugins/pinned-rows/index.js +1 -1
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pinned-rows/pinned-rows.d.ts +43 -0
- package/lib/plugins/pinned-rows/pinned-rows.d.ts.map +1 -0
- package/lib/plugins/pinned-rows/types.d.ts +95 -0
- package/lib/plugins/pinned-rows/types.d.ts.map +1 -0
- package/lib/plugins/pivot/PivotPlugin.d.ts +94 -0
- package/lib/plugins/pivot/PivotPlugin.d.ts.map +1 -0
- package/lib/plugins/pivot/index.d.ts +7 -0
- package/lib/plugins/pivot/index.d.ts.map +1 -0
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/pivot/pivot-engine.d.ts +50 -0
- package/lib/plugins/pivot/pivot-engine.d.ts.map +1 -0
- package/lib/plugins/pivot/pivot-model.d.ts +6 -0
- package/lib/plugins/pivot/pivot-model.d.ts.map +1 -0
- package/lib/plugins/pivot/pivot-panel.d.ts +25 -0
- package/lib/plugins/pivot/pivot-panel.d.ts.map +1 -0
- package/lib/plugins/pivot/pivot-rows.d.ts +33 -0
- package/lib/plugins/pivot/pivot-rows.d.ts.map +1 -0
- package/lib/plugins/pivot/types.d.ts +62 -0
- package/lib/plugins/pivot/types.d.ts.map +1 -0
- package/lib/plugins/reorder/ReorderPlugin.d.ts +81 -0
- package/lib/plugins/reorder/ReorderPlugin.d.ts.map +1 -0
- package/lib/plugins/reorder/column-drag.d.ts +41 -0
- package/lib/plugins/reorder/column-drag.d.ts.map +1 -0
- package/lib/plugins/reorder/index.d.ts +7 -0
- package/lib/plugins/reorder/index.d.ts.map +1 -0
- package/lib/plugins/reorder/index.js +51 -48
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/reorder/types.d.ts +54 -0
- package/lib/plugins/reorder/types.d.ts.map +1 -0
- package/lib/plugins/selection/SelectionPlugin.d.ts +77 -0
- package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -0
- package/lib/plugins/selection/index.d.ts +8 -0
- package/lib/plugins/selection/index.d.ts.map +1 -0
- package/lib/plugins/selection/index.js +86 -75
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/selection/range-selection.d.ts +109 -0
- package/lib/plugins/selection/range-selection.d.ts.map +1 -0
- package/lib/plugins/selection/row-selection.d.ts +48 -0
- package/lib/plugins/selection/row-selection.d.ts.map +1 -0
- package/lib/plugins/selection/types.d.ts +80 -0
- package/lib/plugins/selection/types.d.ts.map +1 -0
- package/lib/plugins/server-side/ServerSidePlugin.d.ts +56 -0
- package/lib/plugins/server-side/ServerSidePlugin.d.ts.map +1 -0
- package/lib/plugins/server-side/cache.d.ts +14 -0
- package/lib/plugins/server-side/cache.d.ts.map +1 -0
- package/lib/plugins/server-side/datasource.d.ts +12 -0
- package/lib/plugins/server-side/datasource.d.ts.map +1 -0
- package/lib/plugins/server-side/index.d.ts +7 -0
- package/lib/plugins/server-side/index.d.ts.map +1 -0
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/server-side/types.d.ts +43 -0
- package/lib/plugins/server-side/types.d.ts.map +1 -0
- package/lib/plugins/tree/TreePlugin.d.ts +49 -0
- package/lib/plugins/tree/TreePlugin.d.ts.map +1 -0
- package/lib/plugins/tree/index.d.ts +8 -0
- package/lib/plugins/tree/index.d.ts.map +1 -0
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/tree/tree-data.d.ts +42 -0
- package/lib/plugins/tree/tree-data.d.ts.map +1 -0
- package/lib/plugins/tree/tree-detect.d.ts +24 -0
- package/lib/plugins/tree/tree-detect.d.ts.map +1 -0
- package/lib/plugins/tree/types.d.ts +61 -0
- package/lib/plugins/tree/types.d.ts.map +1 -0
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts +68 -0
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts.map +1 -0
- package/lib/plugins/undo-redo/history.d.ts +64 -0
- package/lib/plugins/undo-redo/history.d.ts.map +1 -0
- package/lib/plugins/undo-redo/index.d.ts +7 -0
- package/lib/plugins/undo-redo/index.d.ts.map +1 -0
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/undo-redo/types.d.ts +41 -0
- package/lib/plugins/undo-redo/types.d.ts.map +1 -0
- package/lib/plugins/visibility/VisibilityPlugin.d.ts +135 -0
- package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -0
- package/lib/plugins/visibility/index.d.ts +8 -0
- package/lib/plugins/visibility/index.d.ts.map +1 -0
- package/lib/plugins/visibility/index.js.map +1 -1
- package/lib/plugins/visibility/types.d.ts +33 -0
- package/lib/plugins/visibility/types.d.ts.map +1 -0
- package/lib/plugins/visibility/visibility.d.ts +30 -0
- package/lib/plugins/visibility/visibility.d.ts.map +1 -0
- package/package.json +6 -2
- package/public.d.ts +52 -0
- package/public.d.ts.map +1 -0
- package/umd/grid.all.umd.js +32 -74
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +22 -64
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/context-menu.umd.js +1 -1
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +1 -1
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-columns.umd.js +1 -1
- package/umd/plugins/grouping-columns.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/master-detail.umd.js +1 -1
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/pinned-rows.umd.js +1 -1
- package/umd/plugins/pinned-rows.umd.js.map +1 -1
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/selection.umd.js +1 -1
- package/umd/plugins/selection.umd.js.map +1 -1
- package/index-YjW60MHD.js +0 -3235
- package/index-YjW60MHD.js.map +0 -1
package/index.js
CHANGED
|
@@ -1,28 +1,3932 @@
|
|
|
1
|
-
import { B as s, k as g, D as e, i as t, b as i, F as o, o as n, G as l, p as u, b as A, q as G, P as d, j as E, c as I, d as D, m, n as S, g as C, a as F, l as N, f as P, r as _, h as U, u as b } from "./index-YjW60MHD.js";
|
|
1
|
+
const de = ':root{color-scheme:light dark}:host{--tbw-color-bg: transparent;--tbw-color-panel-bg: light-dark(#eeeeee, #222222);--tbw-color-fg: light-dark(#222222, #eeeeee);--tbw-color-fg-muted: light-dark(#555555, #aaaaaa);--tbw-color-accent: light-dark(#3b82f6, #3b82f6);--tbw-color-accent-fg: light-dark(#ffffff, #000000);--tbw-color-success: light-dark(hsl(122, 39%, 40%), hsl(122, 39%, 49%));--tbw-color-selection: light-dark(#fff7d6, #333333);--tbw-color-row-alt: var(--tbw-color-bg);--tbw-color-row-hover: light-dark(#f0f6ff, #1c1c1c);--tbw-color-header-bg: color-mix(in hsl, var(--tbw-color-panel-bg) 85%, var(--tbw-color-fg));--tbw-color-header-fg: color-mix(in hsl, var(--tbw-color-fg) 75%, var(--tbw-color-panel-bg));--tbw-color-border: light-dark(#d0d0d4, #454545);--tbw-color-border-strong: light-dark(#777777, #adacac);--tbw-color-border-cell: var(--tbw-color-border);--tbw-color-border-header: var(--tbw-color-border);--tbw-color-shadow: light-dark(rgba(0, 0, 0, .1), rgba(0, 0, 0, .3));--tbw-font-family: inherit;--tbw-font-size: inherit;--tbw-font-size-header: var(--tbw-font-size);--tbw-font-weight-header: bold;--tbw-cell-padding-header: 2px 8px;--tbw-cell-padding: 2px 8px;--tbw-cell-padding-input: 2px 6px;--tbw-row-height: 28px;--tbw-header-height: 30px;--tbw-cell-white-space: nowrap;--tbw-border-radius: 4px;--tbw-border-input: 1px solid var(--tbw-color-border-strong);--tbw-border-header: 1px solid var(--tbw-color-border-header);--tbw-row-divider: 1px solid var(--tbw-color-border-cell);--tbw-row-hover-outline: 0;--tbw-color-active-row-bg: var(--tbw-color-selection);--tbw-active-row-outline: 0;--tbw-focus-outline: 2px solid var(--tbw-color-accent);--tbw-focus-outline-offset: -2px;--tbw-focus-background: rgba(from var(--tbw-color-accent) r g b / 12%);--tbw-range-border-color: var(--tbw-color-accent);--tbw-range-selection-bg: rgba(from var(--tbw-range-border-color) r g b / 12%);--tbw-resize-handle-width: 6px;--tbw-resize-handle-color: transparent;--tbw-resize-handle-color-hover: var(--tbw-color-accent);--tbw-resize-handle-border-radius: 0;--tbw-scrollbar-thumb: var(--tbw-color-border-strong);--tbw-scrollbar-track: var(--tbw-color-bg);--tbw-transition-duration: .12s;--tbw-transition-ease: ease;--tbw-animation-duration: .2s;--tbw-animation-easing: ease-out;--tbw-animation-enabled: 1;--tbw-editing-bg: var(--tbw-color-selection);--tbw-editing-border: var(--tbw-border-input, 1px solid var(--tbw-color-border-strong));--tbw-padding-editing-input: var(--tbw-cell-padding-input, 2px 6px);--tbw-font-size-editor: inherit;--tbw-sort-indicator-color: var(--tbw-color-fg-muted);--tbw-sort-indicator-active-color: var(--tbw-color-accent);--tbw-header-text-transform: none;--tbw-header-letter-spacing: normal;--tbw-color-header-separator: var(--tbw-color-border-cell);--tbw-checkbox-size: 16px;--tbw-density-scale: 1}:host{position:relative;display:block;width:100%;height:100%;min-height:0;contain:content;font-family:var(--tbw-font-family);font-size:var(--tbw-font-size);background:var(--tbw-color-bg);color:var(--tbw-color-fg);border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);overflow:clip;outline:none}:host,:host *{box-sizing:border-box}:host .header{display:block;flex-shrink:0;z-index:var(--tbw-z-layer-header, 30);background:var(--tbw-color-header-bg);overflow:visible}:host .header-group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-color-header-bg);z-index:var(--tbw-z-layer-header, 30)}:host .header-group-cell{display:flex;align-items:center;justify-content:flex-start;padding:var(--tbw-cell-padding-header, 2px 8px);color:var(--tbw-color-header-group-fg, var(--tbw-color-header-fg));font-weight:var(--tbw-font-weight-header-group, var(--tbw-font-weight-header));justify-content:var(--tbw-align-header-group, var(--tbw-align-header, flex-start))}:host .header-row{display:grid;grid-template-columns:var(--tbw-column-template);color:var(--tbw-color-header-fg);font-size:var(--tbw-font-size-header);min-height:var(--tbw-header-height);border-bottom:var(--tbw-border-header);z-index:var(--tbw-z-layer-header, 30)}:host .header-row>.cell{display:flex;align-items:center;gap:4px;padding:var(--tbw-cell-padding-header, 2px 8px);background-color:var(--tbw-color-header-bg);font-weight:var(--tbw-font-weight-header);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}:host .header-row>.cell>span:first-child{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .header-row>.cell>span[part~=sort-indicator]{flex-shrink:0;opacity:.6}:host .header-row>.cell:last-child{border-right:0}:host .header-group-cell:not(:last-child),:host .header-row>.cell.grouped.group-end:not(:last-child){border-right:2px solid var(--tbw-color-border)}:host .tbw-grid-root{display:flex;flex-direction:column;height:100%}:host .rows-body-wrapper{flex:1;min-height:0;display:flex;flex-direction:row;width:100%;min-width:fit-content}:host .rows-body{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow:visible}:host .rows-container{display:flex;flex-direction:row;flex:1;min-height:0;overflow:visible}:host .rows-viewport{flex:1;min-width:0;position:relative;display:block;overflow:clip}:host .faux-vscroll{position:sticky;inset-inline-end:0;flex-shrink:0;width:auto;overflow-y:auto;overflow-x:hidden;z-index:var(--tbw-z-layer-header, 30)}:host .faux-vscroll-spacer{width:1px}:host .rows-viewport .rows{position:absolute;top:0;left:0;min-width:100%;will-change:transform;z-index:var(--tbw-z-layer-rows, 1)}:host .data-grid-row{display:grid;grid-template-columns:var(--tbw-column-template);contain:layout style}:host .data-grid-row:has(.editing){background:var(--tbw-editing-bg)}:host .selecting .data-grid-row>.cell{user-select:none}:host .data-grid-row>.cell.selected:focus-visible,:host .data-grid-row>.cell:focus-visible:not(.cell-focus){outline:none}:host .data-grid-row>.cell{display:block;padding:var(--tbw-cell-padding, 2px 8px);border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height);line-height:calc(var(--tbw-row-height) - 5px);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0;white-space:var(--tbw-cell-white-space, nowrap);text-overflow:ellipsis}:host .data-grid-row>.cell>*{overflow:hidden;text-overflow:ellipsis;white-space:inherit;min-width:0}:host .data-grid-row>.cell:last-child{border-right:0}:host .data-grid-row>.cell[data-type=boolean]{text-align:center}:host .data-grid-row>.cell[data-type=boolean] input[type=checkbox]{margin:0;width:var(--tbw-checkbox-size);height:var(--tbw-checkbox-size);vertical-align:middle}:host .data-grid-row>.cell.editing{overflow:hidden;padding:0;display:flex;min-height:calc(var(--tbw-row-height) + 2px)}:host .data-grid-row>.cell.editing input:not([type=checkbox]),:host .data-grid-row>.cell.editing select,:host .data-grid-row>.cell.editing textarea{width:100%;height:100%;flex:1 1 auto;min-width:0;border:var(--tbw-editing-border);padding:var(--tbw-padding-editing-input);font-size:var(--tbw-font-size-editor)}:host .data-grid-row:nth-child(2n){background:var(--tbw-color-row-alt)}:host .data-grid-row:hover{background:var(--tbw-color-row-hover)}:host .sortable{cursor:pointer;user-select:none}:host .resize-handle{position:absolute;top:0;right:calc(var(--tbw-resize-handle-width) / -2);width:var(--tbw-resize-handle-width);height:100%;cursor:e-resize;user-select:none;touch-action:none;z-index:20;background:var(--tbw-resize-handle-color);transition:background .12s ease;border-radius:var(--tbw-resize-handle-border-radius)}:host .resize-handle:hover{background:var(--tbw-resize-handle-color-hover)}:host .cell-focus,:host .row-focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}:host .sticky-left,:host .sticky-right{position:sticky;z-index:25}:host .header-row>.cell.sticky-left,:host .header-row>.cell.sticky-right{background:var(--tbw-color-header-bg);z-index:35}:host .data-grid-row>.cell.sticky-left,:host .data-grid-row>.cell.sticky-right{background:var(--tbw-color-panel-bg)}:host .sticky-left{box-shadow:1px 0 0 var(--tbw-color-border)}:host .sticky-right{box-shadow:-1px 0 0 var(--tbw-color-border)}.grid-container{position:relative;width:100%;height:100%}.grid-placeholder{padding:2rem;text-align:center;color:var(--tbw-color-fg);opacity:.6}:host{--tbw-shell-header-height: 44px;--tbw-shell-header-bg: var(--tbw-color-panel-bg);--tbw-shell-header-border: var(--tbw-color-border);--tbw-shell-title-font-size: 14px;--tbw-shell-title-font-weight: 600;--tbw-tool-panel-width: 280px;--tbw-tool-panel-bg: var(--tbw-color-panel-bg);--tbw-tool-panel-border: var(--tbw-color-border);--tbw-tool-panel-header-height: 40px;--tbw-tool-panel-transition: var(--tbw-animation-duration) var(--tbw-animation-easing);--tbw-toolbar-button-size: 32px;--tbw-toolbar-button-gap: 4px}:host .tbw-grid-root.has-shell{display:flex;flex-direction:column;height:100%}:host .tbw-shell-header{display:flex;align-items:center;gap:8px;min-height:var(--tbw-shell-header-height);padding:0 8px;background:var(--tbw-shell-header-bg);border-bottom:1px solid var(--tbw-shell-header-border);flex-shrink:0}:host .tbw-shell-title{font-size:var(--tbw-shell-title-font-size);font-weight:var(--tbw-shell-title-font-weight);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .tbw-shell-content{flex:1;display:flex;align-items:center;gap:12px;min-width:0;overflow:hidden}:host .tbw-shell-toolbar{display:flex;align-items:center;gap:var(--tbw-toolbar-button-gap);flex-shrink:0}:host .tbw-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;width:var(--tbw-toolbar-button-size);height:var(--tbw-toolbar-button-size);padding:0;border:1px solid transparent;border-radius:var(--tbw-border-radius);background:transparent;color:var(--tbw-color-fg);cursor:pointer;font-size:16px;transition:background var(--tbw-transition-duration) var(--tbw-transition-ease),border-color var(--tbw-transition-duration) var(--tbw-transition-ease)}:host .tbw-toolbar-btn:hover{background:var(--tbw-color-row-hover)}:host .tbw-toolbar-btn:focus-visible{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}:host .tbw-toolbar-btn.active{background:var(--tbw-focus-background);border-color:var(--tbw-color-accent)}:host .tbw-toolbar-btn:disabled{opacity:.5;cursor:not-allowed}:host .tbw-toolbar-separator{width:1px;height:20px;background:var(--tbw-color-border);margin:0 4px}:host .tbw-shell-body{position:relative;display:flex;flex:1;min-height:0;overflow:visible}:host .tbw-grid-content{flex:1;min-width:0;min-height:0;display:flex;flex-direction:row;overflow:hidden}:host .tbw-scroll-area{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow-x:auto;overflow-y:hidden;overflow-anchor:none}:host .tbw-tool-panel{position:absolute;top:0;bottom:0;right:0;width:0;overflow:hidden;background:var(--tbw-tool-panel-bg);border-left:1px solid var(--tbw-tool-panel-border);transition:width var(--tbw-tool-panel-transition);display:flex;flex-direction:column;z-index:30;box-shadow:-2px 0 8px var(--tbw-color-shadow)}:host .tbw-tool-panel[data-position=left]{right:auto;left:0;border-left:none;border-right:1px solid var(--tbw-tool-panel-border);box-shadow:2px 0 8px var(--tbw-color-shadow)}:host .tbw-tool-panel.open{width:var(--tbw-tool-panel-width)}:host .tbw-tool-panel-resize{position:absolute;top:0;bottom:0;width:6px;cursor:col-resize;background:transparent;z-index:10;transition:background var(--tbw-transition-duration) var(--tbw-transition-ease)}:host .tbw-tool-panel-resize[data-handle-position=left]{left:0}:host .tbw-tool-panel-resize[data-handle-position=right]{right:0}:host .tbw-tool-panel-resize:hover,:host .tbw-tool-panel-resize.resizing{background:var(--tbw-color-accent)}:host .tbw-tool-panel-header{display:flex;align-items:center;justify-content:space-between;min-height:var(--tbw-tool-panel-header-height);padding:0 12px;border-bottom:1px solid var(--tbw-tool-panel-border);flex-shrink:0}:host .tbw-tool-panel-title{font-weight:600;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .tbw-tool-panel-close{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;border-radius:var(--tbw-border-radius);background:transparent;color:var(--tbw-color-fg-muted);cursor:pointer;font-size:14px}:host .tbw-tool-panel-close:hover{background:var(--tbw-color-row-hover);color:var(--tbw-color-fg)}:host .tbw-tool-panel-content{flex:1;overflow:auto}:host .tbw-accordion{display:flex;flex-direction:column;gap:0}:host .tbw-accordion-section{border-bottom:1px solid var(--tbw-tool-panel-border)}:host .tbw-accordion-section:last-child{border-bottom:none}:host .tbw-accordion-header{display:flex;align-items:center;gap:8px;width:100%;padding:10px 12px;border:none;background:transparent;color:var(--tbw-color-fg);font-size:13px;font-weight:600;text-align:left;cursor:pointer;user-select:none}:host .tbw-accordion-header:hover{background:var(--tbw-color-row-hover)}:host .tbw-accordion-section.single .tbw-accordion-header{cursor:default}:host .tbw-accordion-section.single .tbw-accordion-header:hover{background:transparent}:host .tbw-accordion-chevron{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:10px;color:var(--tbw-color-fg-muted);transition:transform .15s ease;flex-shrink:0}:host .tbw-accordion-section.expanded .tbw-accordion-chevron{transform:rotate(90deg)}:host .tbw-accordion-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:14px;flex-shrink:0}:host .tbw-accordion-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .tbw-accordion-content{display:none}:host .tbw-accordion-section.expanded .tbw-accordion-content{display:block}@media(prefers-reduced-motion:reduce){:host([data-animation-mode="reduced-motion"]){--tbw-animation-enabled: 0;--tbw-animation-duration: 0ms}}:host([data-animation-mode="off"]){--tbw-animation-enabled: 0;--tbw-animation-duration: 0ms}:host .tbw-expanding{animation:tbw-expand var(--tbw-animation-duration) var(--tbw-animation-easing) forwards;overflow:hidden}:host .tbw-collapsing{animation:tbw-collapse var(--tbw-animation-duration) var(--tbw-animation-easing) forwards;overflow:hidden}@keyframes tbw-expand{0%{opacity:0;max-height:0;transform:translateY(-8px)}to{opacity:1;max-height:500px;transform:translateY(0)}}@keyframes tbw-collapse{0%{opacity:1;max-height:500px;transform:translateY(0)}to{opacity:0;max-height:0;transform:translateY(-8px)}}:host .tbw-fade-in{animation:tbw-fade-in var(--tbw-animation-duration) var(--tbw-animation-easing) forwards}:host .tbw-fade-out{animation:tbw-fade-out var(--tbw-animation-duration) var(--tbw-animation-easing) forwards}@keyframes tbw-fade-in{0%{opacity:0}to{opacity:1}}@keyframes tbw-fade-out{0%{opacity:1}to{opacity:0}}:host .tbw-flip-animating{will-change:transform;z-index:1}:host .tbw-toggle-icon{display:inline-flex;align-items:center;justify-content:center;transition:transform var(--tbw-animation-duration) var(--tbw-animation-easing)}:host .tbw-toggle-icon.tbw-expanded{transform:rotate(90deg)}';
|
|
2
|
+
function Ve(t) {
|
|
3
|
+
const e = /* @__PURE__ */ new Map();
|
|
4
|
+
return t._sortState && e.set(t._sortState.field, {
|
|
5
|
+
direction: t._sortState.direction === 1 ? "asc" : "desc",
|
|
6
|
+
priority: 0
|
|
7
|
+
}), e;
|
|
8
|
+
}
|
|
9
|
+
function Te(t, e) {
|
|
10
|
+
const o = t._columns, n = Ve(t);
|
|
11
|
+
return {
|
|
12
|
+
columns: o.map((i, l) => {
|
|
13
|
+
const r = {
|
|
14
|
+
field: i.field,
|
|
15
|
+
order: l,
|
|
16
|
+
visible: !0
|
|
17
|
+
// If it's in _columns, it's visible (hidden columns are filtered out)
|
|
18
|
+
}, s = i;
|
|
19
|
+
s.__renderedWidth !== void 0 ? r.width = s.__renderedWidth : i.width !== void 0 && (r.width = typeof i.width == "string" ? parseFloat(i.width) : i.width);
|
|
20
|
+
const a = n.get(i.field);
|
|
21
|
+
a && (r.sort = a);
|
|
22
|
+
for (const c of e)
|
|
23
|
+
if (c.getColumnState) {
|
|
24
|
+
const h = c.getColumnState(i.field);
|
|
25
|
+
h && Object.assign(r, h);
|
|
26
|
+
}
|
|
27
|
+
return r;
|
|
28
|
+
})
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function Fe(t, e, o, n) {
|
|
32
|
+
if (!e.columns || e.columns.length === 0) return;
|
|
33
|
+
const i = new Map(e.columns.map((s) => [s.field, s])), l = o.map((s) => {
|
|
34
|
+
const a = i.get(s.field);
|
|
35
|
+
if (!a) return s;
|
|
36
|
+
const c = { ...s };
|
|
37
|
+
return a.width !== void 0 && (c.width = a.width, c.__renderedWidth = a.width), a.visible !== void 0 && (c.hidden = !a.visible), c;
|
|
38
|
+
});
|
|
39
|
+
l.sort((s, a) => {
|
|
40
|
+
const c = i.get(s.field)?.order ?? 1 / 0, h = i.get(a.field)?.order ?? 1 / 0;
|
|
41
|
+
return c - h;
|
|
42
|
+
}), t._columns = l;
|
|
43
|
+
const r = e.columns.filter((s) => s.sort !== void 0).sort((s, a) => (s.sort?.priority ?? 0) - (a.sort?.priority ?? 0));
|
|
44
|
+
if (r.length > 0) {
|
|
45
|
+
const s = r[0];
|
|
46
|
+
s.sort && (t._sortState = {
|
|
47
|
+
field: s.field,
|
|
48
|
+
direction: s.sort.direction === "asc" ? 1 : -1
|
|
49
|
+
});
|
|
50
|
+
} else
|
|
51
|
+
t._sortState = null;
|
|
52
|
+
for (const s of n)
|
|
53
|
+
if (s.applyColumnState)
|
|
54
|
+
for (const a of e.columns)
|
|
55
|
+
s.applyColumnState(a.field, a);
|
|
56
|
+
}
|
|
57
|
+
function Ge(t, e, o) {
|
|
58
|
+
let n = null;
|
|
59
|
+
return () => {
|
|
60
|
+
n !== null && clearTimeout(n), n = setTimeout(() => {
|
|
61
|
+
n = null;
|
|
62
|
+
const i = Te(t, e());
|
|
63
|
+
o(i);
|
|
64
|
+
}, 100);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function xe(t, e, o, n) {
|
|
68
|
+
const i = t.effectiveConfig?.columns ?? [], l = i.find((s) => s.field === e);
|
|
69
|
+
return !l || !o && l.lockVisible || !o && i.filter((a) => !a.hidden && a.field !== e).length === 0 || !!l.hidden === !o ? !1 : (l.hidden = !o, n.emit("column-visibility", {
|
|
70
|
+
field: e,
|
|
71
|
+
visible: o,
|
|
72
|
+
visibleColumns: i.filter((s) => !s.hidden).map((s) => s.field)
|
|
73
|
+
}), n.clearRowPool(), n.setup(), n.requestStateChange(), !0);
|
|
74
|
+
}
|
|
75
|
+
function Ue(t, e, o) {
|
|
76
|
+
const i = (t.effectiveConfig?.columns ?? []).find((l) => l.field === e);
|
|
77
|
+
return i ? xe(t, e, !!i.hidden, o) : !1;
|
|
78
|
+
}
|
|
79
|
+
function Xe(t, e) {
|
|
80
|
+
const n = (t.effectiveConfig?.columns ?? []).find((i) => i.field === e);
|
|
81
|
+
return n ? !n.hidden : !1;
|
|
82
|
+
}
|
|
83
|
+
function Ye(t, e) {
|
|
84
|
+
const o = t.effectiveConfig?.columns ?? [];
|
|
85
|
+
o.some((n) => n.hidden) && (o.forEach((n) => n.hidden = !1), e.emit("column-visibility", {
|
|
86
|
+
visibleColumns: o.map((n) => n.field)
|
|
87
|
+
}), e.clearRowPool(), e.setup(), e.requestStateChange());
|
|
88
|
+
}
|
|
89
|
+
function je(t) {
|
|
90
|
+
return (t.effectiveConfig?.columns ?? []).map((o) => ({
|
|
91
|
+
field: o.field,
|
|
92
|
+
header: o.header || o.field,
|
|
93
|
+
visible: !o.hidden,
|
|
94
|
+
lockVisible: o.lockVisible
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
function Ke(t) {
|
|
98
|
+
return t._columns.map((e) => e.field);
|
|
99
|
+
}
|
|
100
|
+
function Ze(t, e, o) {
|
|
101
|
+
if (!e.length) return;
|
|
102
|
+
const n = new Map(t._columns.map((l) => [l.field, l])), i = [];
|
|
103
|
+
for (const l of e) {
|
|
104
|
+
const r = n.get(l);
|
|
105
|
+
r && (i.push(r), n.delete(l));
|
|
106
|
+
}
|
|
107
|
+
for (const l of n.values())
|
|
108
|
+
i.push(l);
|
|
109
|
+
t._columns = i, o.renderHeader(), o.updateTemplate(), o.refreshVirtualWindow();
|
|
110
|
+
}
|
|
111
|
+
const X = {
|
|
112
|
+
STRETCH: "stretch",
|
|
113
|
+
FIXED: "fixed"
|
|
114
|
+
}, Je = {
|
|
115
|
+
mode: "reduced-motion",
|
|
116
|
+
duration: 200,
|
|
117
|
+
easing: "ease-out"
|
|
118
|
+
}, O = {
|
|
119
|
+
expand: "▶",
|
|
120
|
+
collapse: "▼",
|
|
121
|
+
sortAsc: "▲",
|
|
122
|
+
sortDesc: "▼",
|
|
123
|
+
sortNone: "⇅",
|
|
124
|
+
submenuArrow: "▶",
|
|
125
|
+
dragHandle: "⋮⋮",
|
|
126
|
+
toolPanel: "☰"
|
|
127
|
+
};
|
|
128
|
+
function Qe(t) {
|
|
129
|
+
return t == null ? "string" : typeof t == "number" ? "number" : typeof t == "boolean" ? "boolean" : t instanceof Date || typeof t == "string" && /\d{4}-\d{2}-\d{2}/.test(t) && !isNaN(Date.parse(t)) ? "date" : "string";
|
|
130
|
+
}
|
|
131
|
+
function Le(t, e) {
|
|
132
|
+
if (e && e.length) {
|
|
133
|
+
const l = {};
|
|
134
|
+
return e.forEach((r) => {
|
|
135
|
+
r.type && (l[r.field] = r.type);
|
|
136
|
+
}), { columns: e, typeMap: l };
|
|
137
|
+
}
|
|
138
|
+
const o = t[0] || {}, n = Object.keys(o).map((l) => {
|
|
139
|
+
const r = o[l], s = Qe(r);
|
|
140
|
+
return { field: l, header: l.charAt(0).toUpperCase() + l.slice(1), type: s };
|
|
141
|
+
}), i = {};
|
|
142
|
+
return n.forEach((l) => {
|
|
143
|
+
i[l.field] = l.type || "string";
|
|
144
|
+
}), { columns: n, typeMap: i };
|
|
145
|
+
}
|
|
146
|
+
const et = /{{\s*([^}]+)\s*}}/g, A = "__DG_EMPTY__", tt = /^[\w$. '?+\-*/%:()!<>=,&|]+$/, ot = /__(proto|defineGetter|defineSetter)|constructor|window|globalThis|global|process|Function|import|eval|Reflect|Proxy|Error|arguments|document|location|cookie|localStorage|sessionStorage|indexedDB|fetch|XMLHttpRequest|WebSocket|Worker|SharedWorker|ServiceWorker|opener|parent|top|frames|self|this\b/, nt = /* @__PURE__ */ new Set([
|
|
147
|
+
"script",
|
|
148
|
+
"iframe",
|
|
149
|
+
"object",
|
|
150
|
+
"embed",
|
|
151
|
+
"form",
|
|
152
|
+
"input",
|
|
153
|
+
"button",
|
|
154
|
+
"textarea",
|
|
155
|
+
"select",
|
|
156
|
+
"link",
|
|
157
|
+
"meta",
|
|
158
|
+
"base",
|
|
159
|
+
"style",
|
|
160
|
+
"template",
|
|
161
|
+
"slot",
|
|
162
|
+
"portal",
|
|
163
|
+
"frame",
|
|
164
|
+
"frameset",
|
|
165
|
+
"applet",
|
|
166
|
+
"noscript",
|
|
167
|
+
"noembed",
|
|
168
|
+
"plaintext",
|
|
169
|
+
"xmp",
|
|
170
|
+
"listing"
|
|
171
|
+
]), ue = /^on\w+$/i, it = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "data", "srcdoc", "xlink:href", "poster", "srcset"]), lt = /^\s*(javascript|vbscript|data|blob):/i;
|
|
172
|
+
function K(t) {
|
|
173
|
+
if (!t || typeof t != "string") return "";
|
|
174
|
+
if (t.indexOf("<") === -1) return t;
|
|
175
|
+
const e = document.createElement("template");
|
|
176
|
+
return e.innerHTML = t, rt(e.content), e.innerHTML;
|
|
177
|
+
}
|
|
178
|
+
function rt(t) {
|
|
179
|
+
const e = [], o = t.querySelectorAll("*");
|
|
180
|
+
for (const n of o) {
|
|
181
|
+
const i = n.tagName.toLowerCase();
|
|
182
|
+
if (nt.has(i)) {
|
|
183
|
+
e.push(n);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if ((i === "svg" || n.namespaceURI === "http://www.w3.org/2000/svg") && Array.from(n.attributes).some(
|
|
187
|
+
(s) => ue.test(s.name) || s.name === "href" || s.name === "xlink:href"
|
|
188
|
+
)) {
|
|
189
|
+
e.push(n);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
const l = [];
|
|
193
|
+
for (const r of n.attributes) {
|
|
194
|
+
const s = r.name.toLowerCase();
|
|
195
|
+
if (ue.test(s)) {
|
|
196
|
+
l.push(r.name);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (it.has(s) && lt.test(r.value)) {
|
|
200
|
+
l.push(r.name);
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (s === "style" && /expression\s*\(|javascript:|behavior\s*:/i.test(r.value)) {
|
|
204
|
+
l.push(r.name);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
l.forEach((r) => n.removeAttribute(r));
|
|
209
|
+
}
|
|
210
|
+
e.forEach((n) => n.remove());
|
|
211
|
+
}
|
|
212
|
+
function Pe(t, e) {
|
|
213
|
+
if (!t || t.indexOf("{{") === -1) return t;
|
|
214
|
+
const o = [], n = t.replace(et, (s, a) => {
|
|
215
|
+
const c = st(a, e);
|
|
216
|
+
return o.push({ expr: a.trim(), result: c }), c;
|
|
217
|
+
}), i = at(n), l = o.length && o.every((s) => s.result === "" || s.result === A);
|
|
218
|
+
return /Reflect\.|\bProxy\b|ownKeys\(/.test(t) || l ? "" : i;
|
|
219
|
+
}
|
|
220
|
+
function st(t, e) {
|
|
221
|
+
if (t = (t || "").trim(), !t || /\b(Reflect|Proxy|ownKeys)\b/.test(t)) return A;
|
|
222
|
+
if (t === "value") return e.value == null ? A : String(e.value);
|
|
223
|
+
if (t.startsWith("row.") && !/[()?]/.test(t) && !t.includes(":")) {
|
|
224
|
+
const n = t.slice(4), i = e.row ? e.row[n] : void 0;
|
|
225
|
+
return i == null ? A : String(i);
|
|
226
|
+
}
|
|
227
|
+
if (t.length > 80 || !tt.test(t) || ot.test(t)) return A;
|
|
228
|
+
const o = t.match(/\./g);
|
|
229
|
+
if (o && o.length > 1) return A;
|
|
230
|
+
try {
|
|
231
|
+
const i = new Function("value", "row", `return (${t});`)(e.value, e.row), l = i == null ? "" : String(i);
|
|
232
|
+
return /Reflect|Proxy|ownKeys/.test(l) ? A : l || A;
|
|
233
|
+
} catch {
|
|
234
|
+
return A;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function at(t) {
|
|
238
|
+
return t && t.replace(new RegExp(A, "g"), "").replace(/Reflect\.[^<>{}\s]+/g, "").replace(/\bProxy\b/g, "").replace(/ownKeys\([^)]*\)/g, "");
|
|
239
|
+
}
|
|
240
|
+
function ct(t) {
|
|
241
|
+
if (/Reflect|Proxy|ownKeys/.test(t.textContent || "")) {
|
|
242
|
+
if (Array.from(t.childNodes).forEach((e) => {
|
|
243
|
+
e.nodeType === Node.TEXT_NODE && /Reflect|Proxy|ownKeys/.test(e.textContent || "") && (e.textContent = "");
|
|
244
|
+
}), /Reflect|Proxy|ownKeys/.test(t.textContent || "")) {
|
|
245
|
+
if (/Reflect|Proxy|ownKeys/.test(t.textContent || ""))
|
|
246
|
+
for (; t.firstChild; ) t.removeChild(t.firstChild);
|
|
247
|
+
t.textContent = (t.textContent || "").replace(/Reflect|Proxy|ownKeys/g, "");
|
|
248
|
+
}
|
|
249
|
+
(t.textContent || "").trim().length === 0 && (t.textContent = "");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function he(t) {
|
|
253
|
+
const e = /Reflect\.|\bProxy\b|ownKeys\(/.test(t), o = (n) => e ? "" : Pe(t, n);
|
|
254
|
+
return o.__blocked = e, o;
|
|
255
|
+
}
|
|
256
|
+
function dt(t) {
|
|
257
|
+
return Array.from(t.querySelectorAll("tbw-grid-column")).map((o) => {
|
|
258
|
+
const n = o.getAttribute("field") || "";
|
|
259
|
+
if (!n) return null;
|
|
260
|
+
const i = o.getAttribute("type") || void 0, r = i && (/* @__PURE__ */ new Set(["number", "string", "date", "boolean", "select", "typeahead"])).has(i) ? i : void 0, s = o.getAttribute("header") || void 0, a = o.hasAttribute("sortable"), c = o.hasAttribute("editable"), h = { field: n, type: r, header: s, sortable: a, editable: c }, d = o.getAttribute("width");
|
|
261
|
+
if (d) {
|
|
262
|
+
const m = parseFloat(d);
|
|
263
|
+
!isNaN(m) && /^\d+(\.\d+)?$/.test(d.trim()) ? h.width = m : h.width = d;
|
|
264
|
+
}
|
|
265
|
+
const u = o.getAttribute("minWidth") || o.getAttribute("min-width");
|
|
266
|
+
if (u) {
|
|
267
|
+
const m = parseFloat(u);
|
|
268
|
+
isNaN(m) || (h.minWidth = m);
|
|
269
|
+
}
|
|
270
|
+
o.hasAttribute("resizable") && (h.resizable = !0), o.hasAttribute("sizable") && (h.resizable = !0);
|
|
271
|
+
const p = o.getAttribute("editor"), f = o.getAttribute("renderer");
|
|
272
|
+
p && (h.__editorName = p), f && (h.__rendererName = f);
|
|
273
|
+
const b = o.getAttribute("options");
|
|
274
|
+
b && (h.options = b.split(",").map((m) => {
|
|
275
|
+
const [v, C] = m.includes(":") ? m.split(":") : [m.trim(), m.trim()];
|
|
276
|
+
return { value: v.trim(), label: C?.trim() || v.trim() };
|
|
277
|
+
}));
|
|
278
|
+
const g = o.querySelector("tbw-grid-column-view"), w = o.querySelector("tbw-grid-column-editor"), _ = o.querySelector("tbw-grid-column-header");
|
|
279
|
+
if (g && (h.__viewTemplate = g), w && (h.__editorTemplate = w), _ && (h.__headerTemplate = _), g) {
|
|
280
|
+
const v = (globalThis.DataGridElement?.getAdapters?.() ?? []).find((C) => C.canHandle(g));
|
|
281
|
+
v && (h.viewRenderer = v.createRenderer(g));
|
|
282
|
+
}
|
|
283
|
+
if (w) {
|
|
284
|
+
const v = (globalThis.DataGridElement?.getAdapters?.() ?? []).find((C) => C.canHandle(w));
|
|
285
|
+
v && (h.editor = v.createEditor(w));
|
|
286
|
+
}
|
|
287
|
+
return h;
|
|
288
|
+
}).filter((o) => !!o);
|
|
289
|
+
}
|
|
290
|
+
function ut(t, e) {
|
|
291
|
+
if ((!t || !t.length) && (!e || !e.length)) return [];
|
|
292
|
+
if (!t || !t.length) return e || [];
|
|
293
|
+
if (!e || !e.length) return t;
|
|
294
|
+
const o = {};
|
|
295
|
+
e.forEach((i) => o[i.field] = i);
|
|
296
|
+
const n = t.map((i) => {
|
|
297
|
+
const l = o[i.field];
|
|
298
|
+
if (!l) return i;
|
|
299
|
+
const r = { ...i };
|
|
300
|
+
return l.header && !r.header && (r.header = l.header), l.type && !r.type && (r.type = l.type), r.sortable = i.sortable || l.sortable, (i.resizable === !0 || l.resizable === !0) && (r.resizable = !0), r.editable = i.editable || l.editable, l.width != null && r.width == null && (r.width = l.width), l.minWidth != null && r.minWidth == null && (r.minWidth = l.minWidth), l.__viewTemplate && (r.__viewTemplate = l.__viewTemplate), l.__editorTemplate && (r.__editorTemplate = l.__editorTemplate), l.__headerTemplate && (r.__headerTemplate = l.__headerTemplate), l.viewRenderer && !r.viewRenderer && (r.viewRenderer = l.viewRenderer), l.editor && !r.editor && (r.editor = l.editor), delete o[i.field], r;
|
|
301
|
+
});
|
|
302
|
+
return Object.keys(o).forEach((i) => n.push(o[i])), n;
|
|
303
|
+
}
|
|
304
|
+
function fe(t, e) {
|
|
305
|
+
try {
|
|
306
|
+
t.part?.add?.(e);
|
|
307
|
+
} catch {
|
|
308
|
+
}
|
|
309
|
+
const o = t.getAttribute("part");
|
|
310
|
+
o ? o.split(/\s+/).includes(e) || t.setAttribute("part", o + " " + e) : t.setAttribute("part", e);
|
|
311
|
+
}
|
|
312
|
+
function pe(t) {
|
|
313
|
+
t.__lightDomColumnsCache || (t.__originalColumnNodes = Array.from(
|
|
314
|
+
t.querySelectorAll("tbw-grid-column")
|
|
315
|
+
), t.__lightDomColumnsCache = t.__originalColumnNodes.length ? dt(t) : []);
|
|
316
|
+
const e = t.__lightDomColumnsCache, o = ut(t._columns, e);
|
|
317
|
+
o.forEach((i) => {
|
|
318
|
+
i.__viewTemplate && !i.__compiledView && (i.__compiledView = he(i.__viewTemplate.innerHTML)), i.__editorTemplate && !i.__compiledEditor && (i.__compiledEditor = he(i.__editorTemplate.innerHTML));
|
|
319
|
+
});
|
|
320
|
+
const { columns: n } = Le(t._rows, o);
|
|
321
|
+
t._columns = n;
|
|
322
|
+
}
|
|
323
|
+
function be(t) {
|
|
324
|
+
const e = t.effectiveConfig?.fitMode || t.fitMode || X.STRETCH;
|
|
325
|
+
if (e !== X.STRETCH && e !== X.FIXED || t.__didInitialAutoSize || !t.isConnected) return;
|
|
326
|
+
const o = t._headerRowEl?.children || [];
|
|
327
|
+
if (!o.length) return;
|
|
328
|
+
let n = !1;
|
|
329
|
+
t._visibleColumns.forEach((i, l) => {
|
|
330
|
+
if (i.width) return;
|
|
331
|
+
const r = o[l];
|
|
332
|
+
let s = r ? r.scrollWidth : 0;
|
|
333
|
+
for (const a of t._rowPool) {
|
|
334
|
+
const c = a.children[l];
|
|
335
|
+
if (c) {
|
|
336
|
+
const h = c.scrollWidth;
|
|
337
|
+
h > s && (s = h);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
s > 0 && (i.width = s + 2, i.__autoSized = !0, n = !0);
|
|
341
|
+
}), n && z(t), t.__didInitialAutoSize = !0;
|
|
342
|
+
}
|
|
343
|
+
function z(t) {
|
|
344
|
+
(t.effectiveConfig?.fitMode || t.fitMode || X.STRETCH) === X.STRETCH ? t._gridTemplate = t._visibleColumns.map((o) => {
|
|
345
|
+
if (o.width) return `${o.width}px`;
|
|
346
|
+
const n = o.minWidth;
|
|
347
|
+
return n != null ? `minmax(${n}px, 1fr)` : "1fr";
|
|
348
|
+
}).join(" ").trim() : t._gridTemplate = t._visibleColumns.map((o) => o.width ? `${o.width}px` : "max-content").join(" "), t.style.setProperty("--tbw-column-template", t._gridTemplate);
|
|
349
|
+
}
|
|
350
|
+
function ht(t) {
|
|
351
|
+
switch (t.type) {
|
|
352
|
+
case "number":
|
|
353
|
+
return (e) => {
|
|
354
|
+
const o = document.createElement("input");
|
|
355
|
+
return o.type = "number", o.value = e.value != null ? String(e.value) : "", o.addEventListener("blur", () => e.commit(o.value === "" ? null : Number(o.value))), o.addEventListener("keydown", (n) => {
|
|
356
|
+
n.key === "Enter" && e.commit(o.value === "" ? null : Number(o.value)), n.key === "Escape" && e.cancel();
|
|
357
|
+
}), o;
|
|
358
|
+
};
|
|
359
|
+
case "boolean":
|
|
360
|
+
return (e) => {
|
|
361
|
+
const o = document.createElement("input");
|
|
362
|
+
return o.type = "checkbox", o.checked = !!e.value, o.addEventListener("change", () => e.commit(o.checked)), o;
|
|
363
|
+
};
|
|
364
|
+
case "date":
|
|
365
|
+
return (e) => {
|
|
366
|
+
const o = document.createElement("input");
|
|
367
|
+
return o.type = "date", e.value instanceof Date && (o.valueAsDate = e.value), o.addEventListener("change", () => e.commit(o.valueAsDate)), o.addEventListener("keydown", (n) => {
|
|
368
|
+
n.key === "Escape" && e.cancel();
|
|
369
|
+
}), o;
|
|
370
|
+
};
|
|
371
|
+
case "select":
|
|
372
|
+
case "typeahead":
|
|
373
|
+
return (e) => {
|
|
374
|
+
const o = document.createElement("select");
|
|
375
|
+
e.column.multi && (o.multiple = !0), (typeof e.column.options == "function" ? e.column.options() : e.column.options || []).forEach((l) => {
|
|
376
|
+
const r = document.createElement("option");
|
|
377
|
+
r.value = String(l.value), r.textContent = l.label, (e.column.multi && Array.isArray(e.value) && e.value.includes(l.value) || !e.column.multi && e.value === l.value) && (r.selected = !0), o.appendChild(r);
|
|
378
|
+
});
|
|
379
|
+
const i = () => {
|
|
380
|
+
if (e.column.multi) {
|
|
381
|
+
const l = [];
|
|
382
|
+
Array.from(o.selectedOptions).forEach((r) => {
|
|
383
|
+
l.push(r.value);
|
|
384
|
+
}), e.commit(l);
|
|
385
|
+
} else
|
|
386
|
+
e.commit(o.value);
|
|
387
|
+
};
|
|
388
|
+
return o.addEventListener("change", i), o.addEventListener("blur", i), o.addEventListener("keydown", (l) => {
|
|
389
|
+
l.key === "Escape" && e.cancel();
|
|
390
|
+
}), o;
|
|
391
|
+
};
|
|
392
|
+
default:
|
|
393
|
+
return (e) => {
|
|
394
|
+
const o = document.createElement("input");
|
|
395
|
+
return o.type = "text", o.value = e.value != null ? String(e.value) : "", o.addEventListener("blur", () => e.commit(o.value)), o.addEventListener("keydown", (n) => {
|
|
396
|
+
n.key === "Enter" && e.commit(o.value), n.key === "Escape" && e.cancel();
|
|
397
|
+
}), o;
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
function ae(t) {
|
|
402
|
+
return `<span role="checkbox" aria-checked="${t}" aria-label="${t}">${t ? "🗹" : "☐"}</span>`;
|
|
403
|
+
}
|
|
404
|
+
function He(t) {
|
|
405
|
+
if (t == null || t === "") return "";
|
|
406
|
+
if (t instanceof Date)
|
|
407
|
+
return isNaN(t.getTime()) ? "" : t.toLocaleDateString();
|
|
408
|
+
if (typeof t == "number" || typeof t == "string") {
|
|
409
|
+
const e = new Date(t);
|
|
410
|
+
return isNaN(e.getTime()) ? "" : e.toLocaleDateString();
|
|
411
|
+
}
|
|
412
|
+
return "";
|
|
413
|
+
}
|
|
414
|
+
function Me(t) {
|
|
415
|
+
if (!t) return -1;
|
|
416
|
+
const e = t.getAttribute("data-row");
|
|
417
|
+
return e ? parseInt(e, 10) : -1;
|
|
418
|
+
}
|
|
419
|
+
function U(t) {
|
|
420
|
+
if (!t) return -1;
|
|
421
|
+
const e = t.getAttribute("data-col");
|
|
422
|
+
return e ? parseInt(e, 10) : -1;
|
|
423
|
+
}
|
|
424
|
+
function le(t) {
|
|
425
|
+
t && t.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
|
|
426
|
+
}
|
|
427
|
+
function ft(t, e) {
|
|
428
|
+
if (t._dispatchKeyDown?.(e))
|
|
429
|
+
return;
|
|
430
|
+
const o = t._rows.length - 1, n = t._visibleColumns.length - 1, i = t._activeEditRows !== void 0 && t._activeEditRows !== -1, r = t._visibleColumns[t._focusCol]?.type, s = e.composedPath ? e.composedPath() : [], a = s && s.length ? s[0] : e.target, c = (h) => {
|
|
431
|
+
if (!h) return !1;
|
|
432
|
+
const d = h.tagName;
|
|
433
|
+
return !!(d === "INPUT" || d === "SELECT" || d === "TEXTAREA" || h.isContentEditable);
|
|
434
|
+
};
|
|
435
|
+
if (!(c(a) && (e.key === "Home" || e.key === "End")) && !(c(a) && (e.key === "ArrowUp" || e.key === "ArrowDown") && a.tagName === "INPUT" && a.type === "number") && !(c(a) && (e.key === "ArrowLeft" || e.key === "ArrowRight")) && !(c(a) && (e.key === "Enter" || e.key === "Escape")) && !(i && (r === "select" || r === "typeahead") && (e.key === "ArrowDown" || e.key === "ArrowUp"))) {
|
|
436
|
+
switch (e.key) {
|
|
437
|
+
case "Tab": {
|
|
438
|
+
e.preventDefault(), !e.shiftKey ? t._focusCol < n ? t._focusCol += 1 : (typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow < o && (t._focusRow += 1, t._focusCol = 0)) : t._focusCol > 0 ? t._focusCol -= 1 : t._focusRow > 0 && (typeof t.commitActiveRowEdit == "function" && t._activeEditRows === t._focusRow && t.commitActiveRowEdit(), t._focusRow -= 1, t._focusCol = n), k(t);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
case "ArrowDown":
|
|
442
|
+
i && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = Math.min(o, t._focusRow + 1), e.preventDefault();
|
|
443
|
+
break;
|
|
444
|
+
case "ArrowUp":
|
|
445
|
+
i && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = Math.max(0, t._focusRow - 1), e.preventDefault();
|
|
446
|
+
break;
|
|
447
|
+
case "ArrowRight":
|
|
448
|
+
t._focusCol = Math.min(n, t._focusCol + 1), e.preventDefault();
|
|
449
|
+
break;
|
|
450
|
+
case "ArrowLeft":
|
|
451
|
+
t._focusCol = Math.max(0, t._focusCol - 1), e.preventDefault();
|
|
452
|
+
break;
|
|
453
|
+
case "Home":
|
|
454
|
+
(e.ctrlKey || e.metaKey) && (i && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = 0), t._focusCol = 0, e.preventDefault(), k(t, { forceScrollLeft: !0 });
|
|
455
|
+
return;
|
|
456
|
+
case "End":
|
|
457
|
+
(e.ctrlKey || e.metaKey) && (i && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = o), t._focusCol = n, e.preventDefault(), k(t, { forceScrollRight: !0 });
|
|
458
|
+
return;
|
|
459
|
+
case "PageDown":
|
|
460
|
+
t._focusRow = Math.min(o, t._focusRow + 20), e.preventDefault();
|
|
461
|
+
break;
|
|
462
|
+
case "PageUp":
|
|
463
|
+
t._focusRow = Math.max(0, t._focusRow - 20), e.preventDefault();
|
|
464
|
+
break;
|
|
465
|
+
case "Enter":
|
|
466
|
+
if (typeof t.beginBulkEdit == "function") {
|
|
467
|
+
t.beginBulkEdit(t._focusRow);
|
|
468
|
+
return;
|
|
469
|
+
} else
|
|
470
|
+
t.dispatchEvent(
|
|
471
|
+
new CustomEvent("activate-cell", { detail: { row: t._focusRow, col: t._focusCol } })
|
|
472
|
+
);
|
|
473
|
+
return k(t);
|
|
474
|
+
default:
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
k(t);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
function k(t, e) {
|
|
481
|
+
if (t._virtualization?.enabled) {
|
|
482
|
+
const { rowHeight: r, container: s, viewportEl: a } = t._virtualization, c = s, h = a?.clientHeight ?? c?.clientHeight ?? 0;
|
|
483
|
+
if (c && h > 0) {
|
|
484
|
+
const d = t._focusRow * r;
|
|
485
|
+
d < c.scrollTop ? c.scrollTop = d : d + r > c.scrollTop + h && (c.scrollTop = d - h + r);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
const o = t._activeEditRows !== void 0 && t._activeEditRows !== -1;
|
|
489
|
+
o || t.refreshVirtualWindow(!1), le(t._bodyEl), Array.from(t._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((r) => {
|
|
490
|
+
r.setAttribute("aria-selected", "false");
|
|
491
|
+
});
|
|
492
|
+
const n = t._focusRow, i = t._virtualization.start ?? 0, l = t._virtualization.end ?? t._rows.length;
|
|
493
|
+
if (n >= i && n < l) {
|
|
494
|
+
const r = t._bodyEl.querySelectorAll(".data-grid-row")[n - i], s = r?.children[t._focusCol];
|
|
495
|
+
if (s) {
|
|
496
|
+
s.classList.add("cell-focus"), s.setAttribute("aria-selected", "true");
|
|
497
|
+
const a = t.shadowRoot?.querySelector(".tbw-scroll-area");
|
|
498
|
+
if (a && s && !o)
|
|
499
|
+
if (e?.forceScrollLeft)
|
|
500
|
+
a.scrollLeft = 0;
|
|
501
|
+
else if (e?.forceScrollRight)
|
|
502
|
+
a.scrollLeft = a.scrollWidth - a.clientWidth;
|
|
503
|
+
else {
|
|
504
|
+
const c = t._getHorizontalScrollOffsets?.(r ?? void 0, s) ?? { left: 0, right: 0 };
|
|
505
|
+
if (!c.skipScroll) {
|
|
506
|
+
const h = s.getBoundingClientRect(), d = a.getBoundingClientRect(), u = h.left - d.left + a.scrollLeft, p = u + h.width, f = a.scrollLeft + c.left, b = a.scrollLeft + a.clientWidth - c.right;
|
|
507
|
+
u < f ? a.scrollLeft = u - c.left : p > b && (a.scrollLeft = p - a.clientWidth + c.right);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (t._activeEditRows !== void 0 && t._activeEditRows !== -1 && s.classList.contains("editing")) {
|
|
511
|
+
const c = s.querySelector(B);
|
|
512
|
+
if (c && document.activeElement !== c)
|
|
513
|
+
try {
|
|
514
|
+
c.focus({ preventScroll: !0 });
|
|
515
|
+
} catch {
|
|
516
|
+
}
|
|
517
|
+
} else if (!s.contains(document.activeElement)) {
|
|
518
|
+
s.hasAttribute("tabindex") || s.setAttribute("tabindex", "-1");
|
|
519
|
+
try {
|
|
520
|
+
s.focus({ preventScroll: !0 });
|
|
521
|
+
} catch {
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
const Oe = document.createElement("template");
|
|
528
|
+
Oe.innerHTML = '<div class="cell" role="gridcell" part="cell"></div>';
|
|
529
|
+
const ke = document.createElement("template");
|
|
530
|
+
ke.innerHTML = '<div class="data-grid-row" role="row" part="row"></div>';
|
|
531
|
+
function pt() {
|
|
532
|
+
return Oe.content.firstElementChild.cloneNode(!0);
|
|
533
|
+
}
|
|
534
|
+
function bt() {
|
|
535
|
+
return ke.content.firstElementChild.cloneNode(!0);
|
|
536
|
+
}
|
|
537
|
+
const wt = "__cellDisplayCache", gt = "__cellCacheEpoch";
|
|
538
|
+
function Z(t) {
|
|
539
|
+
t[wt] = void 0, t[gt] = void 0, t.__hasSpecialColumns = void 0;
|
|
540
|
+
}
|
|
541
|
+
function mt(t, e, o, n, i) {
|
|
542
|
+
const l = Math.max(0, o - e), r = t._bodyEl, s = t._visibleColumns, a = s.length;
|
|
543
|
+
let c = t.__cachedHeaderRowCount;
|
|
544
|
+
for (c === void 0 && (c = t.shadowRoot?.querySelector(".header-group-row") ? 2 : 1, t.__cachedHeaderRowCount = c); t._rowPool.length < l; ) {
|
|
545
|
+
const d = bt();
|
|
546
|
+
d.addEventListener("click", (u) => we(t, u, d, !1)), d.addEventListener("dblclick", (u) => we(t, u, d, !0)), t._rowPool.push(d);
|
|
547
|
+
}
|
|
548
|
+
if (t._rowPool.length > l) {
|
|
549
|
+
for (let d = l; d < t._rowPool.length; d++) {
|
|
550
|
+
const u = t._rowPool[d];
|
|
551
|
+
u.parentNode === r && u.remove();
|
|
552
|
+
}
|
|
553
|
+
t._rowPool.length = l;
|
|
554
|
+
}
|
|
555
|
+
const h = i && t.__hasRenderRowPlugins !== !1;
|
|
556
|
+
for (let d = 0; d < l; d++) {
|
|
557
|
+
const u = e + d, p = t._rows[u], f = t._rowPool[d];
|
|
558
|
+
if (f.setAttribute("aria-rowindex", String(u + c + 1)), h && i(p, f, u)) {
|
|
559
|
+
f.__epoch = n, f.__rowDataRef = p, f.parentNode !== r && r.appendChild(f);
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
562
|
+
const b = f.__epoch, g = f.__rowDataRef, w = f.children.length, m = b === n && w === a, v = g !== p;
|
|
563
|
+
let C = !1;
|
|
564
|
+
if (m && v) {
|
|
565
|
+
for (let R = 0; R < a; R++)
|
|
566
|
+
if (s[R].externalView && !f.querySelector(`.cell[data-col="${R}"] [data-external-view]`)) {
|
|
567
|
+
C = !0;
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
if (!m || C) {
|
|
572
|
+
const R = J(f), x = t._activeEditRows === u;
|
|
573
|
+
if (R && !x)
|
|
574
|
+
f.__isCustomRow && (f.className = "data-grid-row", f.setAttribute("role", "row"), f.__isCustomRow = !1), Q(f), I(t, f, p, u), f.__epoch = n, f.__rowDataRef = p;
|
|
575
|
+
else if (R && x)
|
|
576
|
+
oe(t, f, p, u), f.__rowDataRef = p;
|
|
577
|
+
else if (f.__isCustomRow && (f.className = "data-grid-row", f.setAttribute("role", "row"), f.__isCustomRow = !1), I(t, f, p, u), f.__epoch = n, f.__rowDataRef = p, x) {
|
|
578
|
+
const H = f.children;
|
|
579
|
+
for (let S = 0; S < H.length; S++) {
|
|
580
|
+
const T = t._visibleColumns[S];
|
|
581
|
+
T && T.editable && L(t, p, u, T, H[S], !0);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
} else if (v) {
|
|
585
|
+
const R = J(f), x = t._activeEditRows === u;
|
|
586
|
+
if (R && !x)
|
|
587
|
+
Q(f), I(t, f, p, u), f.__epoch = n, f.__rowDataRef = p;
|
|
588
|
+
else if (oe(t, f, p, u), f.__rowDataRef = p, x && !R) {
|
|
589
|
+
const H = f.children;
|
|
590
|
+
for (let S = 0; S < H.length; S++) {
|
|
591
|
+
const T = t._visibleColumns[S];
|
|
592
|
+
T && T.editable && L(t, p, u, T, H[S], !0);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
} else {
|
|
596
|
+
const R = J(f), x = t._activeEditRows === u;
|
|
597
|
+
if (R && !x)
|
|
598
|
+
Q(f), I(t, f, p, u), f.__epoch = n, f.__rowDataRef = p;
|
|
599
|
+
else if (oe(t, f, p, u), x && !R) {
|
|
600
|
+
const H = f.children;
|
|
601
|
+
for (let S = 0; S < H.length; S++) {
|
|
602
|
+
const T = t._visibleColumns[S];
|
|
603
|
+
T && T.editable && L(t, p, u, T, H[S], !0);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
const $ = t._changedRowIndices.has(u), $e = f.classList.contains("changed");
|
|
608
|
+
$ !== $e && f.classList.toggle("changed", $), f.parentNode !== r && r.appendChild(f);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
function oe(t, e, o, n) {
|
|
612
|
+
const i = e.children, l = t._visibleColumns, r = l.length, s = i.length, a = r < s ? r : s, c = t._focusRow, h = t._focusCol;
|
|
613
|
+
let d = t.__hasSpecialColumns;
|
|
614
|
+
if (d === void 0) {
|
|
615
|
+
d = !1;
|
|
616
|
+
for (let p = 0; p < r; p++) {
|
|
617
|
+
const f = l[p];
|
|
618
|
+
if (f.__viewTemplate || f.__compiledView || f.viewRenderer || f.externalView || f.format || f.type === "date" || f.type === "boolean") {
|
|
619
|
+
d = !0;
|
|
620
|
+
break;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
t.__hasSpecialColumns = d;
|
|
624
|
+
}
|
|
625
|
+
const u = String(n);
|
|
626
|
+
if (!d) {
|
|
627
|
+
for (let p = 0; p < a; p++) {
|
|
628
|
+
const f = i[p], b = o[l[p].field];
|
|
629
|
+
f.textContent = b == null ? "" : String(b), f.getAttribute("data-row") !== u && f.setAttribute("data-row", u);
|
|
630
|
+
const g = c === n && h === p, w = f.classList.contains("cell-focus");
|
|
631
|
+
g !== w && (f.classList.toggle("cell-focus", g), f.setAttribute("aria-selected", String(g)));
|
|
632
|
+
}
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
for (let p = 0; p < a; p++)
|
|
636
|
+
if (l[p].externalView && !i[p].querySelector("[data-external-view]")) {
|
|
637
|
+
I(t, e, o, n);
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
for (let p = 0; p < a; p++) {
|
|
641
|
+
const f = l[p], b = i[p];
|
|
642
|
+
b.getAttribute("data-row") !== u && b.setAttribute("data-row", u);
|
|
643
|
+
const g = c === n && h === p, w = b.classList.contains("cell-focus");
|
|
644
|
+
if (g !== w && (b.classList.toggle("cell-focus", g), b.setAttribute("aria-selected", String(g))), b.classList.contains("editing")) continue;
|
|
645
|
+
if (f.viewRenderer) {
|
|
646
|
+
const v = o[f.field], C = f.viewRenderer({ row: o, value: v, field: f.field, column: f });
|
|
647
|
+
typeof C == "string" ? b.innerHTML = K(C) : C ? (b.innerHTML = "", b.appendChild(C)) : b.textContent = v == null ? "" : String(v);
|
|
648
|
+
continue;
|
|
649
|
+
}
|
|
650
|
+
if (f.__viewTemplate || f.__compiledView || f.externalView)
|
|
651
|
+
continue;
|
|
652
|
+
const _ = o[f.field];
|
|
653
|
+
let m;
|
|
654
|
+
if (f.format)
|
|
655
|
+
try {
|
|
656
|
+
const v = f.format(_, o);
|
|
657
|
+
m = v == null ? "" : String(v);
|
|
658
|
+
} catch {
|
|
659
|
+
m = _ == null ? "" : String(_);
|
|
660
|
+
}
|
|
661
|
+
else f.type === "date" ? (m = He(_), b.textContent = m) : f.type === "boolean" ? b.innerHTML = ae(!!_) : (m = _ == null ? "" : String(_), b.textContent = m);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
function I(t, e, o, n) {
|
|
665
|
+
e.innerHTML = "";
|
|
666
|
+
const i = t._visibleColumns, l = i.length, r = t._focusRow, s = t._focusCol;
|
|
667
|
+
t.effectiveConfig?.editOn || t.editOn;
|
|
668
|
+
const a = t, c = document.createDocumentFragment();
|
|
669
|
+
for (let h = 0; h < l; h++) {
|
|
670
|
+
const d = i[h], u = pt();
|
|
671
|
+
u.setAttribute("aria-colindex", String(h + 1)), u.setAttribute("data-col", String(h)), u.setAttribute("data-row", String(n)), u.setAttribute("data-field", d.field), d.type, d.type && u.setAttribute("data-type", d.type);
|
|
672
|
+
let p = o[d.field];
|
|
673
|
+
const f = d.format;
|
|
674
|
+
if (f)
|
|
675
|
+
try {
|
|
676
|
+
p = f(p, o);
|
|
677
|
+
} catch {
|
|
678
|
+
}
|
|
679
|
+
const b = d.__compiledView, g = d.__viewTemplate, w = d.viewRenderer, _ = d.externalView;
|
|
680
|
+
let m = !1;
|
|
681
|
+
if (w) {
|
|
682
|
+
const v = w({ row: o, value: p, field: d.field, column: d });
|
|
683
|
+
typeof v == "string" ? (u.innerHTML = K(v), m = !0) : v ? u.appendChild(v) : u.textContent = p == null ? "" : String(p);
|
|
684
|
+
} else if (_) {
|
|
685
|
+
const v = _, C = document.createElement("div");
|
|
686
|
+
C.setAttribute("data-external-view", ""), C.setAttribute("data-field", d.field), u.appendChild(C);
|
|
687
|
+
const $ = { row: o, value: p, field: d.field, column: d };
|
|
688
|
+
if (v.mount)
|
|
689
|
+
try {
|
|
690
|
+
v.mount({ placeholder: C, context: $, spec: v });
|
|
691
|
+
} catch {
|
|
692
|
+
}
|
|
693
|
+
else
|
|
694
|
+
queueMicrotask(() => {
|
|
695
|
+
try {
|
|
696
|
+
a.dispatchEvent(
|
|
697
|
+
new CustomEvent("mount-external-view", {
|
|
698
|
+
bubbles: !0,
|
|
699
|
+
composed: !0,
|
|
700
|
+
detail: { placeholder: C, spec: v, context: $ }
|
|
701
|
+
})
|
|
702
|
+
);
|
|
703
|
+
} catch {
|
|
704
|
+
}
|
|
705
|
+
});
|
|
706
|
+
C.setAttribute("data-mounted", "");
|
|
707
|
+
} else if (b) {
|
|
708
|
+
const v = b({ row: o, value: p, field: d.field, column: d }), C = b.__blocked;
|
|
709
|
+
u.innerHTML = C ? "" : K(v), m = !0, C && (u.textContent = "", u.setAttribute("data-blocked-template", ""));
|
|
710
|
+
} else if (g) {
|
|
711
|
+
const v = g.innerHTML;
|
|
712
|
+
/Reflect\.|\bProxy\b|ownKeys\(/.test(v) ? (u.textContent = "", u.setAttribute("data-blocked-template", "")) : (u.innerHTML = K(Pe(v, { row: o, value: p })), m = !0);
|
|
713
|
+
} else
|
|
714
|
+
d.type === "date" ? u.textContent = He(p) : d.type === "boolean" ? u.innerHTML = ae(!!p) : u.textContent = p == null ? "" : String(p);
|
|
715
|
+
if (m) {
|
|
716
|
+
ct(u);
|
|
717
|
+
const v = u.textContent || "";
|
|
718
|
+
/Proxy|Reflect\.ownKeys/.test(v) && (u.textContent = v.replace(/Proxy|Reflect\.ownKeys/g, "").trim(), /Proxy|Reflect\.ownKeys/.test(u.textContent || "") && (u.textContent = ""));
|
|
719
|
+
}
|
|
720
|
+
u.hasAttribute("data-blocked-template") && (u.textContent || "").trim().length && (u.textContent = ""), d.editable ? u.tabIndex = 0 : d.type === "boolean" && (u.hasAttribute("tabindex") || (u.tabIndex = 0)), r === n && s === h ? (u.classList.add("cell-focus"), u.setAttribute("aria-selected", "true")) : u.setAttribute("aria-selected", "false"), c.appendChild(u);
|
|
721
|
+
}
|
|
722
|
+
e.appendChild(c);
|
|
723
|
+
}
|
|
724
|
+
function we(t, e, o, n) {
|
|
725
|
+
if (e.target?.closest(".resize-handle")) return;
|
|
726
|
+
const i = o.querySelector(".cell[data-row]"), l = Me(i);
|
|
727
|
+
if (l < 0) return;
|
|
728
|
+
const r = t._rows[l];
|
|
729
|
+
if (!r || t._dispatchRowClick?.(e, l, r, o))
|
|
730
|
+
return;
|
|
731
|
+
const s = e.target?.closest(".cell[data-col]");
|
|
732
|
+
if (s) {
|
|
733
|
+
const d = Number(s.getAttribute("data-col"));
|
|
734
|
+
if (!isNaN(d)) {
|
|
735
|
+
if (t._dispatchCellClick?.(e, l, d, s))
|
|
736
|
+
return;
|
|
737
|
+
const u = t._focusRow !== l || t._focusCol !== d;
|
|
738
|
+
if (t._focusRow = l, t._focusCol = d, s.classList.contains("editing")) {
|
|
739
|
+
u && (le(t.shadowRoot ?? t._bodyEl), s.classList.add("cell-focus"));
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
k(t);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
if (t._activeEditRows === l) {
|
|
746
|
+
s && (le(t.shadowRoot ?? t._bodyEl), s.classList.add("cell-focus"), queueMicrotask(() => {
|
|
747
|
+
const d = Number(s.getAttribute("data-col")), u = t._visibleColumns[d];
|
|
748
|
+
if (u && u.editable && s.classList.contains("editing")) {
|
|
749
|
+
const p = s.querySelector(B);
|
|
750
|
+
try {
|
|
751
|
+
p?.focus({ preventScroll: !0 });
|
|
752
|
+
} catch {
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}));
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
if (J(o)) {
|
|
759
|
+
if (!n) return;
|
|
760
|
+
const d = o.children;
|
|
761
|
+
for (let u = 0; u < d.length; u++)
|
|
762
|
+
d[u].classList.remove("editing");
|
|
763
|
+
Q(o);
|
|
764
|
+
}
|
|
765
|
+
const c = t.effectiveConfig?.editOn ?? t.editOn ?? "dblClick";
|
|
766
|
+
if (c === !1) return;
|
|
767
|
+
const h = c === "dblclick" ? "dblClick" : c;
|
|
768
|
+
if (h === "click" || h === "dblClick" && n) {
|
|
769
|
+
if (typeof t.beginBulkEdit == "function") {
|
|
770
|
+
t.beginBulkEdit(l);
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
W(t, l, r);
|
|
774
|
+
} else return;
|
|
775
|
+
Array.from(o.children).forEach((d, u) => {
|
|
776
|
+
const p = t._visibleColumns[u];
|
|
777
|
+
p && p.editable && L(t, r, l, p, d, !0);
|
|
778
|
+
}), s && queueMicrotask(() => {
|
|
779
|
+
const d = o.querySelector(`.cell[data-col="${t._focusCol}"]`);
|
|
780
|
+
if (d?.classList.contains("editing")) {
|
|
781
|
+
const u = d.querySelector(B);
|
|
782
|
+
try {
|
|
783
|
+
u?.focus({ preventScroll: !0 });
|
|
784
|
+
} catch {
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
const B = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])';
|
|
790
|
+
function re(t) {
|
|
791
|
+
return !(t === "__proto__" || t === "constructor" || t === "prototype");
|
|
792
|
+
}
|
|
793
|
+
function J(t) {
|
|
794
|
+
return (t.__editingCellCount ?? 0) > 0;
|
|
795
|
+
}
|
|
796
|
+
function vt(t) {
|
|
797
|
+
const e = (t.__editingCellCount ?? 0) + 1;
|
|
798
|
+
t.__editingCellCount = e, t.setAttribute("data-has-editing", "");
|
|
799
|
+
}
|
|
800
|
+
function Q(t) {
|
|
801
|
+
t.__editingCellCount = 0, t.removeAttribute("data-has-editing");
|
|
802
|
+
}
|
|
803
|
+
function W(t, e, o) {
|
|
804
|
+
t._activeEditRows !== e && (t._rowEditSnapshots.set(e, { ...o }), t._activeEditRows = e);
|
|
805
|
+
}
|
|
806
|
+
function D(t, e, o) {
|
|
807
|
+
if (t._activeEditRows !== e) return;
|
|
808
|
+
const n = t._rowEditSnapshots.get(e), i = t._rows[e], l = t.findRenderedRowElement?.(e);
|
|
809
|
+
if (!o && l && i && l.querySelectorAll(".cell.editing").forEach((s) => {
|
|
810
|
+
const a = Number(s.getAttribute("data-col"));
|
|
811
|
+
if (isNaN(a)) return;
|
|
812
|
+
const c = t._visibleColumns[a];
|
|
813
|
+
if (!c) return;
|
|
814
|
+
const h = s.querySelector("input,textarea,select");
|
|
815
|
+
if (h) {
|
|
816
|
+
let d;
|
|
817
|
+
h instanceof HTMLInputElement && h.type === "checkbox" ? d = h.checked : (d = h.value, c.type === "number" && d !== "" && (d = Number(d))), i[c.field] !== d && ce(t, e, c, d, i);
|
|
818
|
+
}
|
|
819
|
+
}), o && n && i)
|
|
820
|
+
Object.keys(n).forEach((r) => i[r] = n[r]), t._changedRowIndices.delete(e), Z(t);
|
|
821
|
+
else if (!o) {
|
|
822
|
+
const r = t._changedRowIndices.has(e);
|
|
823
|
+
t.dispatchEvent(
|
|
824
|
+
new CustomEvent("row-commit", {
|
|
825
|
+
detail: {
|
|
826
|
+
rowIndex: e,
|
|
827
|
+
row: i,
|
|
828
|
+
changed: r,
|
|
829
|
+
changedRows: t.changedRows,
|
|
830
|
+
changedRowIndices: t.changedRowIndices
|
|
831
|
+
}
|
|
832
|
+
})
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
t._rowEditSnapshots.delete(e), t._activeEditRows = -1, l && (I(t, l, t._rows[e], e), t._changedRowIndices.has(e) ? l.classList.add("changed") : l.classList.remove("changed")), queueMicrotask(() => {
|
|
836
|
+
try {
|
|
837
|
+
const r = t._focusRow, s = t._focusCol, a = t.findRenderedRowElement?.(r);
|
|
838
|
+
if (a) {
|
|
839
|
+
Array.from(t._bodyEl.querySelectorAll(".cell-focus")).forEach(
|
|
840
|
+
(h) => h.classList.remove("cell-focus")
|
|
841
|
+
);
|
|
842
|
+
const c = a.querySelector(`.cell[data-row="${r}"][data-col="${s}"]`);
|
|
843
|
+
c && (c.classList.add("cell-focus"), c.setAttribute("aria-selected", "true"), c.hasAttribute("tabindex") || c.setAttribute("tabindex", "-1"), c.focus({ preventScroll: !0 }));
|
|
844
|
+
}
|
|
845
|
+
} catch {
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
function ce(t, e, o, n, i) {
|
|
850
|
+
const l = o.field;
|
|
851
|
+
if (!re(l) || i[l] === n) return;
|
|
852
|
+
i[l] = n;
|
|
853
|
+
const s = !t._changedRowIndices.has(e);
|
|
854
|
+
t._changedRowIndices.add(e);
|
|
855
|
+
const a = t.findRenderedRowElement?.(e);
|
|
856
|
+
a && a.classList.add("changed"), t.dispatchEvent(
|
|
857
|
+
new CustomEvent("cell-commit", {
|
|
858
|
+
detail: {
|
|
859
|
+
row: i,
|
|
860
|
+
field: l,
|
|
861
|
+
value: n,
|
|
862
|
+
rowIndex: e,
|
|
863
|
+
changedRows: t.changedRows,
|
|
864
|
+
changedRowIndices: t.changedRowIndices,
|
|
865
|
+
firstTimeForRow: s
|
|
866
|
+
}
|
|
867
|
+
})
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
function L(t, e, o, n, i, l = !1) {
|
|
871
|
+
if (!n.editable || (t._activeEditRows !== o && W(t, o, e), i.classList.contains("editing"))) return;
|
|
872
|
+
const r = re(n.field) ? e[n.field] : void 0;
|
|
873
|
+
i.classList.add("editing");
|
|
874
|
+
const s = i.parentElement;
|
|
875
|
+
s && vt(s);
|
|
876
|
+
let a = !1;
|
|
877
|
+
const c = (b) => {
|
|
878
|
+
a || t._activeEditRows === -1 || ce(t, o, n, b, e);
|
|
879
|
+
}, h = () => {
|
|
880
|
+
a = !0, e[n.field] = re(n.field) ? r : void 0;
|
|
881
|
+
const b = i.querySelector("input,textarea,select");
|
|
882
|
+
b && (typeof HTMLInputElement < "u" && b instanceof HTMLInputElement && b.type === "checkbox" ? b.checked = !!r : "value" in b && (b.value = r ?? ""));
|
|
883
|
+
}, d = document.createElement("div");
|
|
884
|
+
d.style.display = "contents", i.innerHTML = "", i.appendChild(d), d.addEventListener("keydown", (b) => {
|
|
885
|
+
b.key === "Enter" && (b.stopPropagation(), b.preventDefault(), a = !0, D(t, o, !1)), b.key === "Escape" && (b.stopPropagation(), b.preventDefault(), h(), D(t, o, !0));
|
|
886
|
+
});
|
|
887
|
+
const u = n.__editorTemplate, p = n.editor || (u ? "template" : ht(n)), f = r;
|
|
888
|
+
if (p === "template" && u) {
|
|
889
|
+
const b = u.cloneNode(!0), g = n.__compiledEditor;
|
|
890
|
+
g ? b.innerHTML = g({ row: e, value: r, field: n.field, column: n }) : b.querySelectorAll("*").forEach((_) => {
|
|
891
|
+
_.childNodes.length === 1 && _.firstChild?.nodeType === Node.TEXT_NODE && (_.textContent = _.textContent?.replace(/{{\s*value\s*}}/g, r == null ? "" : String(r)).replace(/{{\s*row\.([a-zA-Z0-9_]+)\s*}}/g, (m, v) => {
|
|
892
|
+
const C = e[v];
|
|
893
|
+
return C == null ? "" : String(C);
|
|
894
|
+
}) || "");
|
|
895
|
+
});
|
|
896
|
+
const w = b.querySelector("input,textarea,select");
|
|
897
|
+
if (w) {
|
|
898
|
+
const _ = typeof HTMLInputElement < "u";
|
|
899
|
+
_ && w instanceof HTMLInputElement && w.type === "checkbox" ? w.checked = !!r : "value" in w && (w.value = r ?? ""), w.addEventListener("blur", () => {
|
|
900
|
+
const m = _ && w instanceof HTMLInputElement && w.type === "checkbox" ? w.checked : w.value;
|
|
901
|
+
c(m);
|
|
902
|
+
}), w.addEventListener("keydown", (m) => {
|
|
903
|
+
if (m.key === "Enter") {
|
|
904
|
+
m.stopPropagation(), m.preventDefault(), a = !0;
|
|
905
|
+
const v = _ && w instanceof HTMLInputElement && w.type === "checkbox" ? w.checked : w.value;
|
|
906
|
+
c(v), D(t, o, !1);
|
|
907
|
+
}
|
|
908
|
+
m.key === "Escape" && (m.stopPropagation(), m.preventDefault(), h(), D(t, o, !0));
|
|
909
|
+
}), _ && w instanceof HTMLInputElement && w.type === "checkbox" && w.addEventListener("change", () => {
|
|
910
|
+
const m = w.checked;
|
|
911
|
+
c(m);
|
|
912
|
+
}), l || setTimeout(() => w.focus({ preventScroll: !0 }), 0);
|
|
913
|
+
}
|
|
914
|
+
d.appendChild(b);
|
|
915
|
+
} else if (typeof p == "string") {
|
|
916
|
+
const b = document.createElement(p);
|
|
917
|
+
b.value = f, b.addEventListener("change", () => c(b.value)), d.appendChild(b), l || queueMicrotask(() => {
|
|
918
|
+
d.querySelector(B)?.focus({ preventScroll: !0 });
|
|
919
|
+
});
|
|
920
|
+
} else if (typeof p == "function") {
|
|
921
|
+
const b = p({ row: e, value: f, field: n.field, column: n, commit: c, cancel: h });
|
|
922
|
+
typeof b == "string" ? d.innerHTML = b : d.appendChild(b), l || queueMicrotask(() => {
|
|
923
|
+
d.querySelector(B)?.focus({ preventScroll: !0 });
|
|
924
|
+
});
|
|
925
|
+
} else if (p && typeof p == "object") {
|
|
926
|
+
const b = document.createElement("div");
|
|
927
|
+
b.setAttribute("data-external-editor", ""), b.setAttribute("data-field", n.field), d.appendChild(b);
|
|
928
|
+
const g = { row: e, value: f, field: n.field, column: n, commit: c, cancel: h };
|
|
929
|
+
if (p.mount)
|
|
930
|
+
try {
|
|
931
|
+
p.mount({ placeholder: b, context: g, spec: p });
|
|
932
|
+
} catch {
|
|
933
|
+
}
|
|
934
|
+
else
|
|
935
|
+
t.dispatchEvent(
|
|
936
|
+
new CustomEvent("mount-external-editor", { detail: { placeholder: b, spec: p, context: g } })
|
|
937
|
+
);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
function _t(t, e, o) {
|
|
941
|
+
t.dispatchEvent(new CustomEvent(e, { detail: o, bubbles: !0 }));
|
|
942
|
+
}
|
|
943
|
+
function De(t) {
|
|
944
|
+
return Array.from(t._changedRowIndices).map((e) => t._rows[e]);
|
|
945
|
+
}
|
|
946
|
+
function ze(t) {
|
|
947
|
+
return Array.from(t._changedRowIndices);
|
|
948
|
+
}
|
|
949
|
+
function Ct(t, e) {
|
|
950
|
+
t._changedRowIndices.clear(), e || _t(t, "changed-rows-reset", {
|
|
951
|
+
rows: De(t),
|
|
952
|
+
indices: ze(t)
|
|
953
|
+
}), t._rowPool.forEach((o) => o.classList.remove("changed"));
|
|
954
|
+
}
|
|
955
|
+
function Et(t, e, o) {
|
|
956
|
+
if (t.effectiveConfig?.editOn === !1 || !t._columns.some((r) => r.editable)) return;
|
|
957
|
+
const i = t._rows[e];
|
|
958
|
+
W(t, e, i);
|
|
959
|
+
const l = o.findRenderedRowElement(e);
|
|
960
|
+
l && (Array.from(l.children).forEach((r, s) => {
|
|
961
|
+
const a = t._visibleColumns[s];
|
|
962
|
+
if (a?.editable) {
|
|
963
|
+
const c = r;
|
|
964
|
+
c.classList.contains("editing") || L(t, i, e, a, c, !0);
|
|
965
|
+
}
|
|
966
|
+
}), setTimeout(() => {
|
|
967
|
+
let r = l.querySelector(`.cell[data-col="${t._focusCol}"]`);
|
|
968
|
+
if (r?.classList.contains("editing") || (r = l.querySelector(".cell.editing")), r?.classList.contains("editing")) {
|
|
969
|
+
const s = r.querySelector(B);
|
|
970
|
+
try {
|
|
971
|
+
s?.focus({ preventScroll: !0 });
|
|
972
|
+
} catch {
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}, 0));
|
|
976
|
+
}
|
|
977
|
+
function yt(t) {
|
|
978
|
+
t._activeEditRows !== -1 && D(t, t._activeEditRows, !1);
|
|
979
|
+
}
|
|
980
|
+
function St(t) {
|
|
981
|
+
t._activeEditRows !== -1 && D(t, t._activeEditRows, !0);
|
|
982
|
+
}
|
|
983
|
+
function te(t, e) {
|
|
984
|
+
const o = Me(e), n = U(e);
|
|
985
|
+
if (o < 0 || n < 0) return null;
|
|
986
|
+
const i = t._rows[o], l = t._visibleColumns[n];
|
|
987
|
+
return !i || !l ? null : { rowIndex: o, colIndex: n, rowData: i, col: l };
|
|
988
|
+
}
|
|
989
|
+
function Rt(t, e) {
|
|
990
|
+
if (e.classList.contains("editing")) return;
|
|
991
|
+
const o = te(t, e);
|
|
992
|
+
o && (t._focusRow = o.rowIndex, t._focusCol = o.colIndex, k(t));
|
|
993
|
+
}
|
|
994
|
+
function At(t, e, o) {
|
|
995
|
+
if (e.classList.contains("editing")) return;
|
|
996
|
+
const n = te(t, e);
|
|
997
|
+
n && (o.stopPropagation(), t._focusRow = n.rowIndex, t._focusCol = n.colIndex, L(t, n.rowData, n.rowIndex, n.col, e));
|
|
998
|
+
}
|
|
999
|
+
function Tt(t, e, o) {
|
|
1000
|
+
o.stopPropagation();
|
|
1001
|
+
const n = te(t, e);
|
|
1002
|
+
if (!n) return;
|
|
1003
|
+
if (typeof t.beginBulkEdit == "function") {
|
|
1004
|
+
t._focusRow = n.rowIndex, t._focusCol = n.colIndex, t.beginBulkEdit(n.rowIndex);
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
W(t, n.rowIndex, n.rowData);
|
|
1008
|
+
const i = t.findRenderedRowElement?.(n.rowIndex);
|
|
1009
|
+
if (i) {
|
|
1010
|
+
const l = i.children;
|
|
1011
|
+
for (let r = 0; r < l.length; r++) {
|
|
1012
|
+
const s = t._visibleColumns[r];
|
|
1013
|
+
s && s.editable && L(t, n.rowData, n.rowIndex, s, l[r], !0);
|
|
1014
|
+
}
|
|
1015
|
+
queueMicrotask(() => {
|
|
1016
|
+
const r = i.querySelector(`.cell[data-col="${t._focusCol}"]`);
|
|
1017
|
+
if (r?.classList.contains("editing")) {
|
|
1018
|
+
const s = r.querySelector(B);
|
|
1019
|
+
try {
|
|
1020
|
+
s?.focus({ preventScroll: !0 });
|
|
1021
|
+
} catch {
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
function xt(t, e, o) {
|
|
1028
|
+
const n = te(t, e);
|
|
1029
|
+
if (!n) return;
|
|
1030
|
+
const { rowIndex: i, colIndex: l, rowData: r, col: s } = n, a = e.classList.contains("editing");
|
|
1031
|
+
if ((s.type === "select" || s.type === "typeahead") && !a && o.key === "Enter") {
|
|
1032
|
+
o.preventDefault(), t._activeEditRows !== i && W(t, i, r), L(t, r, i, s, e), setTimeout(() => {
|
|
1033
|
+
const c = e.querySelector("select");
|
|
1034
|
+
try {
|
|
1035
|
+
c?.showPicker?.();
|
|
1036
|
+
} catch {
|
|
1037
|
+
}
|
|
1038
|
+
c?.focus({ preventScroll: !0 });
|
|
1039
|
+
}, 0);
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
if (s.type === "boolean" && o.key === " " && !a) {
|
|
1043
|
+
o.preventDefault(), t._activeEditRows !== i && W(t, i, r);
|
|
1044
|
+
const c = !r[s.field];
|
|
1045
|
+
ce(t, i, s, c, r), e.innerHTML = ae(!!c);
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
if (o.key === "Enter" && !a) {
|
|
1049
|
+
o.preventDefault(), o.stopPropagation(), t._focusRow = i, t._focusCol = l, typeof t.beginBulkEdit == "function" ? t.beginBulkEdit(i) : L(t, r, i, s, e);
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
if (o.key === "F2" && !a) {
|
|
1053
|
+
o.preventDefault(), L(t, r, i, s, e);
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
function Lt(t, e, o) {
|
|
1058
|
+
const n = () => t.effectiveConfig?.editOn || t.editOn;
|
|
1059
|
+
e.addEventListener(
|
|
1060
|
+
"mousedown",
|
|
1061
|
+
(i) => {
|
|
1062
|
+
const l = i.target.closest(".cell[data-col]");
|
|
1063
|
+
if (!l) return;
|
|
1064
|
+
const r = U(l);
|
|
1065
|
+
if (r < 0) return;
|
|
1066
|
+
const s = t._visibleColumns[r];
|
|
1067
|
+
s && s.editable && Rt(t, l);
|
|
1068
|
+
},
|
|
1069
|
+
{ signal: o }
|
|
1070
|
+
), e.addEventListener(
|
|
1071
|
+
"click",
|
|
1072
|
+
(i) => {
|
|
1073
|
+
if (n() !== "click") return;
|
|
1074
|
+
const r = i.target.closest(".cell[data-col]");
|
|
1075
|
+
if (!r) return;
|
|
1076
|
+
const s = U(r);
|
|
1077
|
+
if (s < 0) return;
|
|
1078
|
+
const a = t._visibleColumns[s];
|
|
1079
|
+
a && a.editable && At(t, r, i);
|
|
1080
|
+
},
|
|
1081
|
+
{ signal: o }
|
|
1082
|
+
), e.addEventListener(
|
|
1083
|
+
"dblclick",
|
|
1084
|
+
(i) => {
|
|
1085
|
+
const l = n();
|
|
1086
|
+
if ((l === "dblclick" ? "dblClick" : l) === "click" || l === !1) return;
|
|
1087
|
+
const s = i.target.closest(".cell[data-col]");
|
|
1088
|
+
if (!s) return;
|
|
1089
|
+
const a = U(s);
|
|
1090
|
+
if (a < 0) return;
|
|
1091
|
+
const c = t._visibleColumns[a];
|
|
1092
|
+
c && c.editable && Tt(t, s, i);
|
|
1093
|
+
},
|
|
1094
|
+
{ signal: o }
|
|
1095
|
+
), e.addEventListener(
|
|
1096
|
+
"keydown",
|
|
1097
|
+
(i) => {
|
|
1098
|
+
const l = i.target.closest(".cell[data-col]");
|
|
1099
|
+
if (!l) return;
|
|
1100
|
+
const r = U(l);
|
|
1101
|
+
if (r < 0) return;
|
|
1102
|
+
const s = t._visibleColumns[r];
|
|
1103
|
+
s && s.editable && xt(t, l, i);
|
|
1104
|
+
},
|
|
1105
|
+
{ signal: o }
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
function Pt(t, e) {
|
|
1109
|
+
return t == null && e == null ? 0 : t == null ? -1 : e == null || t > e ? 1 : t < e ? -1 : 0;
|
|
1110
|
+
}
|
|
1111
|
+
function Ht(t, e, o) {
|
|
1112
|
+
const i = o.find((s) => s.field === e.field)?.sortComparator ?? Pt, { field: l, direction: r } = e;
|
|
1113
|
+
return [...t].sort((s, a) => i(s[l], a[l], s, a) * r);
|
|
1114
|
+
}
|
|
1115
|
+
function ge(t, e, o, n) {
|
|
1116
|
+
t._rows = e, t.__rowRenderEpoch++, t._rowPool.forEach((i) => i.__epoch = -1), q(t), t.refreshVirtualWindow(!0), t.dispatchEvent(
|
|
1117
|
+
new CustomEvent("sort-change", { detail: { field: o.field, direction: n } })
|
|
1118
|
+
), t.requestStateChange?.();
|
|
1119
|
+
}
|
|
1120
|
+
function me(t, e) {
|
|
1121
|
+
!t._sortState || t._sortState.field !== e.field ? (t._sortState || (t.__originalOrder = t._rows.slice()), ve(t, e, 1)) : t._sortState.direction === 1 ? ve(t, e, -1) : (t._sortState = null, t.__rowRenderEpoch++, t._rowPool.forEach((n) => n.__epoch = -1), t._rows = t.__originalOrder.slice(), q(t), t._headerRowEl?.querySelectorAll('[role="columnheader"].sortable')?.forEach((n) => {
|
|
1122
|
+
n.getAttribute("aria-sort") ? (n.getAttribute("aria-sort") === "ascending" || n.getAttribute("aria-sort") === "descending") && (t._sortState || n.setAttribute("aria-sort", "none")) : n.setAttribute("aria-sort", "none");
|
|
1123
|
+
}), t.refreshVirtualWindow(!0), t.dispatchEvent(
|
|
1124
|
+
new CustomEvent("sort-change", { detail: { field: e.field, direction: 0 } })
|
|
1125
|
+
), t.requestStateChange?.());
|
|
1126
|
+
}
|
|
1127
|
+
function ve(t, e, o) {
|
|
1128
|
+
t._sortState = { field: e.field, direction: o };
|
|
1129
|
+
const n = { field: e.field, direction: o }, i = t._columns, r = (t.effectiveConfig?.sortHandler ?? Ht)(t._rows, n, i);
|
|
1130
|
+
r && typeof r.then == "function" ? r.then((s) => {
|
|
1131
|
+
ge(t, s, e, o);
|
|
1132
|
+
}) : ge(t, r, e, o);
|
|
1133
|
+
}
|
|
1134
|
+
function Mt(t, e) {
|
|
1135
|
+
typeof e == "string" ? t.textContent = e : e instanceof HTMLElement && (t.innerHTML = "", t.appendChild(e.cloneNode(!0)));
|
|
1136
|
+
}
|
|
1137
|
+
function q(t) {
|
|
1138
|
+
t._headerRowEl = t.findHeaderRow();
|
|
1139
|
+
const e = t._headerRowEl;
|
|
1140
|
+
e.innerHTML = "", t._visibleColumns.forEach((o, n) => {
|
|
1141
|
+
const i = document.createElement("div");
|
|
1142
|
+
i.className = "cell", fe(i, "header-cell"), i.setAttribute("role", "columnheader"), i.setAttribute("aria-colindex", String(n + 1)), i.setAttribute("data-field", o.field), i.setAttribute("data-col", String(n));
|
|
1143
|
+
const l = o.__headerTemplate;
|
|
1144
|
+
if (l) Array.from(l.childNodes).forEach((r) => i.appendChild(r.cloneNode(!0)));
|
|
1145
|
+
else {
|
|
1146
|
+
const r = o.header || o.field, s = document.createElement("span");
|
|
1147
|
+
s.textContent = r, i.appendChild(s);
|
|
1148
|
+
}
|
|
1149
|
+
if (o.sortable) {
|
|
1150
|
+
i.classList.add("sortable"), i.tabIndex = 0;
|
|
1151
|
+
const r = document.createElement("span");
|
|
1152
|
+
fe(r, "sort-indicator");
|
|
1153
|
+
const s = t._sortState?.field === o.field ? t._sortState.direction : 0, a = { ...O, ...t.icons }, c = s === 1 ? a.sortAsc : s === -1 ? a.sortDesc : a.sortNone;
|
|
1154
|
+
Mt(r, c), i.appendChild(r), i.setAttribute("aria-sort", s === 0 ? "none" : s === 1 ? "ascending" : "descending"), i.addEventListener("click", (h) => {
|
|
1155
|
+
t._resizeController?.isResizing || t._dispatchHeaderClick?.(h, n, i) || me(t, o);
|
|
1156
|
+
}), i.addEventListener("keydown", (h) => {
|
|
1157
|
+
if (h.key === "Enter" || h.key === " ") {
|
|
1158
|
+
if (h.preventDefault(), t._dispatchHeaderClick?.(h, n, i)) return;
|
|
1159
|
+
me(t, o);
|
|
1160
|
+
}
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
if (o.resizable) {
|
|
1164
|
+
i.style.position = "relative";
|
|
1165
|
+
const r = document.createElement("div");
|
|
1166
|
+
r.className = "resize-handle", r.setAttribute("aria-hidden", "true"), r.addEventListener("mousedown", (s) => {
|
|
1167
|
+
s.stopPropagation(), s.preventDefault(), t._resizeController.start(s, n, i);
|
|
1168
|
+
}), r.addEventListener("dblclick", (s) => {
|
|
1169
|
+
s.stopPropagation(), s.preventDefault(), t._resizeController.resetColumn(n);
|
|
1170
|
+
}), i.appendChild(r);
|
|
1171
|
+
}
|
|
1172
|
+
e.appendChild(i);
|
|
1173
|
+
}), e.querySelectorAll(".cell.sortable").forEach((o) => {
|
|
1174
|
+
o.getAttribute("aria-sort") || o.setAttribute("aria-sort", "none");
|
|
1175
|
+
}), e.children.length > 0 ? (e.setAttribute("role", "row"), e.setAttribute("aria-rowindex", "1")) : (e.removeAttribute("role"), e.removeAttribute("aria-rowindex"));
|
|
1176
|
+
}
|
|
1177
|
+
const Ne = typeof requestIdleCallback == "function";
|
|
1178
|
+
function Ot(t, e) {
|
|
1179
|
+
return Ne ? requestIdleCallback(t, e) : window.setTimeout(() => {
|
|
1180
|
+
const o = Date.now();
|
|
1181
|
+
t({
|
|
1182
|
+
didTimeout: !1,
|
|
1183
|
+
timeRemaining: () => Math.max(0, 50 - (Date.now() - o))
|
|
1184
|
+
});
|
|
1185
|
+
}, 1);
|
|
1186
|
+
}
|
|
1187
|
+
function _e(t) {
|
|
1188
|
+
Ne ? cancelIdleCallback(t) : clearTimeout(t);
|
|
1189
|
+
}
|
|
1190
|
+
function kt(t) {
|
|
1191
|
+
let e = null, o = null, n = null, i = null;
|
|
1192
|
+
const l = (a) => {
|
|
1193
|
+
if (!e) return;
|
|
1194
|
+
const c = a.clientX - e.startX, h = Math.max(40, e.startWidth + c), d = t._visibleColumns[e.colIndex];
|
|
1195
|
+
d.width = h, d.__userResized = !0, d.__renderedWidth = h, o == null && (o = requestAnimationFrame(() => {
|
|
1196
|
+
o = null, t.updateTemplate?.();
|
|
1197
|
+
})), t.dispatchEvent(
|
|
1198
|
+
new CustomEvent("column-resize", { detail: { field: d.field, width: h } })
|
|
1199
|
+
);
|
|
1200
|
+
};
|
|
1201
|
+
let r = !1;
|
|
1202
|
+
const s = () => {
|
|
1203
|
+
const a = e !== null;
|
|
1204
|
+
a && (r = !0, requestAnimationFrame(() => {
|
|
1205
|
+
r = !1;
|
|
1206
|
+
})), window.removeEventListener("mousemove", l), window.removeEventListener("mouseup", s), n !== null && (document.documentElement.style.cursor = n, n = null), i !== null && (document.body.style.userSelect = i, i = null), e = null, a && t.requestStateChange && t.requestStateChange();
|
|
1207
|
+
};
|
|
1208
|
+
return {
|
|
1209
|
+
get isResizing() {
|
|
1210
|
+
return e !== null || r;
|
|
1211
|
+
},
|
|
1212
|
+
start(a, c, h) {
|
|
1213
|
+
a.preventDefault();
|
|
1214
|
+
const d = h.getBoundingClientRect();
|
|
1215
|
+
e = { startX: a.clientX, colIndex: c, startWidth: d.width }, window.addEventListener("mousemove", l), window.addEventListener("mouseup", s), n === null && (n = document.documentElement.style.cursor), document.documentElement.style.cursor = "e-resize", i === null && (i = document.body.style.userSelect), document.body.style.userSelect = "none";
|
|
1216
|
+
},
|
|
1217
|
+
resetColumn(a) {
|
|
1218
|
+
const c = t._visibleColumns[a];
|
|
1219
|
+
c && (c.__userResized = !1, c.__renderedWidth = void 0, c.width = c.__originalWidth, t.updateTemplate?.(), t.requestStateChange?.(), t.dispatchEvent(
|
|
1220
|
+
new CustomEvent("column-resize-reset", { detail: { field: c.field, width: c.width } })
|
|
1221
|
+
));
|
|
1222
|
+
},
|
|
1223
|
+
dispose() {
|
|
1224
|
+
s();
|
|
1225
|
+
}
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
function Y(t, e, o) {
|
|
1229
|
+
const n = document.createElement(t);
|
|
1230
|
+
if (e)
|
|
1231
|
+
for (const i in e) {
|
|
1232
|
+
const l = e[i];
|
|
1233
|
+
l != null && n.setAttribute(i, l);
|
|
1234
|
+
}
|
|
1235
|
+
return n;
|
|
1236
|
+
}
|
|
1237
|
+
function y(t, e) {
|
|
1238
|
+
const o = document.createElement("div");
|
|
1239
|
+
if (t && (o.className = t), e)
|
|
1240
|
+
for (const n in e) {
|
|
1241
|
+
const i = e[n];
|
|
1242
|
+
i != null && o.setAttribute(n, i);
|
|
1243
|
+
}
|
|
1244
|
+
return o;
|
|
1245
|
+
}
|
|
1246
|
+
function ee(t, e, o) {
|
|
1247
|
+
const n = document.createElement("button");
|
|
1248
|
+
if (t && (n.className = t), e)
|
|
1249
|
+
for (const i in e) {
|
|
1250
|
+
const l = e[i];
|
|
1251
|
+
l != null && n.setAttribute(i, l);
|
|
1252
|
+
}
|
|
1253
|
+
return n;
|
|
1254
|
+
}
|
|
1255
|
+
function Ce(t) {
|
|
1256
|
+
const e = document.createElement("slot");
|
|
1257
|
+
return t && (e.name = t), e;
|
|
1258
|
+
}
|
|
1259
|
+
const Be = document.createElement("template");
|
|
1260
|
+
Be.innerHTML = `
|
|
1261
|
+
<div class="tbw-scroll-area">
|
|
1262
|
+
<div class="rows-body-wrapper">
|
|
1263
|
+
<div class="rows-body" role="grid">
|
|
1264
|
+
<div class="header">
|
|
1265
|
+
<div class="header-row" part="header-row"></div>
|
|
1266
|
+
</div>
|
|
1267
|
+
<div class="rows-container">
|
|
1268
|
+
<div class="rows-viewport">
|
|
1269
|
+
<div class="rows"></div>
|
|
1270
|
+
</div>
|
|
1271
|
+
</div>
|
|
1272
|
+
</div>
|
|
1273
|
+
</div>
|
|
1274
|
+
</div>
|
|
1275
|
+
<div class="faux-vscroll">
|
|
1276
|
+
<div class="faux-vscroll-spacer"></div>
|
|
1277
|
+
</div>
|
|
1278
|
+
`;
|
|
1279
|
+
function Ie() {
|
|
1280
|
+
return Be.content.cloneNode(!0);
|
|
1281
|
+
}
|
|
1282
|
+
function Ee(t) {
|
|
1283
|
+
const e = document.createDocumentFragment(), o = y(t.hasShell ? "tbw-grid-root has-shell" : "tbw-grid-root");
|
|
1284
|
+
if (t.hasShell && t.shellHeader && t.shellBody)
|
|
1285
|
+
o.appendChild(t.shellHeader), o.appendChild(t.shellBody);
|
|
1286
|
+
else {
|
|
1287
|
+
const n = y("tbw-grid-content");
|
|
1288
|
+
n.appendChild(Ie()), o.appendChild(n);
|
|
1289
|
+
}
|
|
1290
|
+
return e.appendChild(o), e;
|
|
1291
|
+
}
|
|
1292
|
+
function Dt(t) {
|
|
1293
|
+
const e = y("tbw-shell-header", { part: "shell-header", role: "presentation" });
|
|
1294
|
+
if (t.title) {
|
|
1295
|
+
const l = y("tbw-shell-title");
|
|
1296
|
+
l.textContent = t.title, e.appendChild(l);
|
|
1297
|
+
}
|
|
1298
|
+
const o = y("tbw-shell-content", { part: "shell-content", role: "presentation" });
|
|
1299
|
+
o.appendChild(Ce("header-content")), e.appendChild(o);
|
|
1300
|
+
const n = y("tbw-shell-toolbar", { part: "shell-toolbar", role: "presentation" });
|
|
1301
|
+
for (const l of t.configButtons)
|
|
1302
|
+
if (l.icon && l.action) {
|
|
1303
|
+
const r = ee("tbw-toolbar-btn", {
|
|
1304
|
+
"data-btn": l.id,
|
|
1305
|
+
title: l.label,
|
|
1306
|
+
"aria-label": l.label
|
|
1307
|
+
});
|
|
1308
|
+
l.disabled && (r.disabled = !0), r.innerHTML = l.icon, n.appendChild(r);
|
|
1309
|
+
}
|
|
1310
|
+
for (const l of t.apiButtons)
|
|
1311
|
+
if (l.icon && l.action) {
|
|
1312
|
+
const r = ee("tbw-toolbar-btn", {
|
|
1313
|
+
"data-btn": l.id,
|
|
1314
|
+
title: l.label,
|
|
1315
|
+
"aria-label": l.label
|
|
1316
|
+
});
|
|
1317
|
+
l.disabled && (r.disabled = !0), r.innerHTML = l.icon, n.appendChild(r);
|
|
1318
|
+
}
|
|
1319
|
+
for (const l of t.configButtons)
|
|
1320
|
+
(l.hasElement || l.hasRender) && n.appendChild(y("tbw-toolbar-btn-slot", { "data-btn-slot": l.id }));
|
|
1321
|
+
for (const l of t.apiButtons)
|
|
1322
|
+
(l.hasElement || l.hasRender) && n.appendChild(y("tbw-toolbar-btn-slot", { "data-btn-slot": l.id }));
|
|
1323
|
+
if (t.hasLightDomButtons && n.appendChild(Ce("toolbar")), (t.configButtons.length > 0 || t.apiButtons.length > 0 || t.hasLightDomButtons) && t.hasPanels && n.appendChild(y("tbw-toolbar-separator")), t.hasPanels) {
|
|
1324
|
+
const l = ee(t.isPanelOpen ? "tbw-toolbar-btn active" : "tbw-toolbar-btn", {
|
|
1325
|
+
"data-panel-toggle": "",
|
|
1326
|
+
title: "Settings",
|
|
1327
|
+
"aria-label": "Toggle settings panel",
|
|
1328
|
+
"aria-pressed": String(t.isPanelOpen),
|
|
1329
|
+
"aria-controls": "tbw-tool-panel"
|
|
1330
|
+
});
|
|
1331
|
+
l.innerHTML = t.toolPanelIcon, n.appendChild(l);
|
|
1332
|
+
}
|
|
1333
|
+
return e.appendChild(n), e;
|
|
1334
|
+
}
|
|
1335
|
+
function zt(t) {
|
|
1336
|
+
const e = y("tbw-shell-body"), o = t.panels.length > 0, n = t.panels.length === 1, i = y("tbw-grid-content");
|
|
1337
|
+
i.appendChild(Ie());
|
|
1338
|
+
let l = null;
|
|
1339
|
+
if (o) {
|
|
1340
|
+
l = Y("aside", {
|
|
1341
|
+
class: t.isPanelOpen ? "tbw-tool-panel open" : "tbw-tool-panel",
|
|
1342
|
+
part: "tool-panel",
|
|
1343
|
+
"data-position": t.position,
|
|
1344
|
+
role: "presentation",
|
|
1345
|
+
id: "tbw-tool-panel"
|
|
1346
|
+
});
|
|
1347
|
+
const r = t.position === "left" ? "right" : "left";
|
|
1348
|
+
l.appendChild(
|
|
1349
|
+
y("tbw-tool-panel-resize", {
|
|
1350
|
+
"data-resize-handle": "",
|
|
1351
|
+
"data-handle-position": r,
|
|
1352
|
+
"aria-hidden": "true"
|
|
1353
|
+
})
|
|
1354
|
+
);
|
|
1355
|
+
const s = y("tbw-tool-panel-content", { role: "presentation" }), a = y("tbw-accordion");
|
|
1356
|
+
for (const c of t.panels) {
|
|
1357
|
+
const h = `tbw-accordion-section${c.isExpanded ? " expanded" : ""}${n ? " single" : ""}`, d = y(h, { "data-section": c.id }), u = ee("tbw-accordion-header", {
|
|
1358
|
+
"aria-expanded": String(c.isExpanded),
|
|
1359
|
+
"aria-controls": `tbw-section-${c.id}`
|
|
1360
|
+
});
|
|
1361
|
+
if (n && u.setAttribute("aria-disabled", "true"), c.icon) {
|
|
1362
|
+
const f = Y("span", { class: "tbw-accordion-icon" });
|
|
1363
|
+
f.innerHTML = c.icon, u.appendChild(f);
|
|
1364
|
+
}
|
|
1365
|
+
const p = Y("span", { class: "tbw-accordion-title" });
|
|
1366
|
+
if (p.textContent = c.title, u.appendChild(p), !n) {
|
|
1367
|
+
const f = Y("span", { class: "tbw-accordion-chevron" });
|
|
1368
|
+
f.innerHTML = c.isExpanded ? t.collapseIcon : t.expandIcon, u.appendChild(f);
|
|
1369
|
+
}
|
|
1370
|
+
d.appendChild(u), d.appendChild(
|
|
1371
|
+
y("tbw-accordion-content", {
|
|
1372
|
+
id: `tbw-section-${c.id}`,
|
|
1373
|
+
role: "presentation"
|
|
1374
|
+
})
|
|
1375
|
+
), a.appendChild(d);
|
|
1376
|
+
}
|
|
1377
|
+
s.appendChild(a), l.appendChild(s);
|
|
1378
|
+
}
|
|
1379
|
+
return t.position === "left" && l ? (e.appendChild(l), e.appendChild(i)) : (e.appendChild(i), l && e.appendChild(l)), e;
|
|
1380
|
+
}
|
|
1381
|
+
function M(t) {
|
|
1382
|
+
return t ? typeof t == "string" ? t : t.outerHTML : "";
|
|
1383
|
+
}
|
|
1384
|
+
function Nt() {
|
|
1385
|
+
return {
|
|
1386
|
+
toolPanels: /* @__PURE__ */ new Map(),
|
|
1387
|
+
headerContents: /* @__PURE__ */ new Map(),
|
|
1388
|
+
toolbarButtons: /* @__PURE__ */ new Map(),
|
|
1389
|
+
lightDomButtons: [],
|
|
1390
|
+
lightDomHeaderContent: [],
|
|
1391
|
+
lightDomTitle: null,
|
|
1392
|
+
lightDomToolPanelIds: /* @__PURE__ */ new Set(),
|
|
1393
|
+
isPanelOpen: !1,
|
|
1394
|
+
expandedSections: /* @__PURE__ */ new Set(),
|
|
1395
|
+
headerContentCleanups: /* @__PURE__ */ new Map(),
|
|
1396
|
+
panelCleanups: /* @__PURE__ */ new Map(),
|
|
1397
|
+
toolbarButtonCleanups: /* @__PURE__ */ new Map(),
|
|
1398
|
+
// Deprecated - kept for backward compatibility
|
|
1399
|
+
activePanel: null,
|
|
1400
|
+
activePanelCleanup: null
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
function se(t, e) {
|
|
1404
|
+
return !!(t?.header?.title || e.lightDomTitle || t?.header?.toolbarButtons?.length || e.toolPanels.size > 0 || e.headerContents.size > 0 || e.toolbarButtons.size > 0 || e.lightDomButtons.length > 0 || e.lightDomHeaderContent.length > 0);
|
|
1405
|
+
}
|
|
1406
|
+
function ye(t, e, o = "☰") {
|
|
1407
|
+
const n = t?.header?.title ?? "", i = !!n, l = M(o), r = t?.header?.toolbarButtons ?? [], s = r.length > 0, a = e.toolbarButtons.size > 0, c = e.lightDomButtons.length > 0, h = e.toolPanels.size > 0, u = (s || a || c) && h, p = [...r].sort((g, w) => (g.order ?? 100) - (w.order ?? 100)), f = [...e.toolbarButtons.values()].sort((g, w) => (g.order ?? 100) - (w.order ?? 100));
|
|
1408
|
+
let b = "";
|
|
1409
|
+
for (const g of p)
|
|
1410
|
+
g.icon && g.action && (b += `<button class="tbw-toolbar-btn" data-btn="${g.id}" title="${g.label}" aria-label="${g.label}"${g.disabled ? " disabled" : ""}>${g.icon}</button>`);
|
|
1411
|
+
for (const g of f)
|
|
1412
|
+
g.icon && g.action && (b += `<button class="tbw-toolbar-btn" data-btn="${g.id}" title="${g.label}" aria-label="${g.label}"${g.disabled ? " disabled" : ""}>${g.icon}</button>`);
|
|
1413
|
+
for (const g of p)
|
|
1414
|
+
(g.element || g.render) && (b += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${g.id}"></div>`);
|
|
1415
|
+
for (const g of f)
|
|
1416
|
+
(g.element || g.render) && (b += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${g.id}"></div>`);
|
|
1417
|
+
if (c && (b += '<slot name="toolbar"></slot>'), u && (b += '<div class="tbw-toolbar-separator"></div>'), h) {
|
|
1418
|
+
const g = e.isPanelOpen;
|
|
1419
|
+
b += `<button class="tbw-toolbar-btn${g ? " active" : ""}" data-panel-toggle title="Settings" aria-label="Toggle settings panel" aria-pressed="${g}" aria-controls="tbw-tool-panel">${l}</button>`;
|
|
1420
|
+
}
|
|
1421
|
+
return `
|
|
1422
|
+
<div class="tbw-shell-header" part="shell-header" role="presentation">
|
|
1423
|
+
${i ? `<div class="tbw-shell-title">${n}</div>` : ""}
|
|
1424
|
+
<div class="tbw-shell-content" part="shell-content" role="presentation">
|
|
1425
|
+
<slot name="header-content"></slot>
|
|
1426
|
+
</div>
|
|
1427
|
+
<div class="tbw-shell-toolbar" part="shell-toolbar" role="presentation">
|
|
1428
|
+
${b}
|
|
1429
|
+
</div>
|
|
1430
|
+
</div>
|
|
1431
|
+
`;
|
|
1432
|
+
}
|
|
1433
|
+
function V(t, e) {
|
|
1434
|
+
const o = t.querySelector("tbw-grid-header");
|
|
1435
|
+
if (!o) return;
|
|
1436
|
+
if (!e.lightDomTitle) {
|
|
1437
|
+
const r = o.getAttribute("title");
|
|
1438
|
+
r && (e.lightDomTitle = r);
|
|
1439
|
+
}
|
|
1440
|
+
const n = o.querySelectorAll("tbw-grid-header-content");
|
|
1441
|
+
n.length > 0 && e.lightDomHeaderContent.length === 0 && (e.lightDomHeaderContent = Array.from(n), e.lightDomHeaderContent.forEach((r) => {
|
|
1442
|
+
r.setAttribute("slot", "header-content");
|
|
1443
|
+
}));
|
|
1444
|
+
const i = o.querySelectorAll("tbw-grid-tool-button"), l = o.querySelectorAll('button.tbw-toolbar-btn[slot="toolbar"]');
|
|
1445
|
+
i.length > 0 && e.lightDomButtons.length === 0 ? (e.lightDomButtons = Array.from(i).map((r) => {
|
|
1446
|
+
const s = document.createElement("button");
|
|
1447
|
+
s.className = "tbw-toolbar-btn";
|
|
1448
|
+
const a = r.getAttribute("id") ?? "", c = r.getAttribute("label") ?? "", h = r.getAttribute("icon") ?? "", d = r.getAttribute("order") ?? "100";
|
|
1449
|
+
return s.setAttribute("data-btn", a), s.setAttribute("title", c), s.setAttribute("aria-label", c), s.setAttribute("data-order", d), s.textContent = h, s.setAttribute("slot", "toolbar"), r.replaceWith(s), s;
|
|
1450
|
+
}), e.lightDomButtons.sort((r, s) => {
|
|
1451
|
+
const a = parseInt(r.getAttribute("data-order") ?? "100", 10), c = parseInt(s.getAttribute("data-order") ?? "100", 10);
|
|
1452
|
+
return a - c;
|
|
1453
|
+
})) : l.length > 0 && e.lightDomButtons.length === 0 && (e.lightDomButtons = Array.from(l), e.lightDomButtons.sort((r, s) => {
|
|
1454
|
+
const a = parseInt(r.getAttribute("data-order") ?? "100", 10), c = parseInt(s.getAttribute("data-order") ?? "100", 10);
|
|
1455
|
+
return a - c;
|
|
1456
|
+
})), e.lightDomButtons.forEach((r) => {
|
|
1457
|
+
r.parentElement === o && t.appendChild(r);
|
|
1458
|
+
}), o.style.display = "none";
|
|
1459
|
+
}
|
|
1460
|
+
function F(t, e, o) {
|
|
1461
|
+
t.querySelectorAll(":scope > tbw-grid-tool-panel").forEach((i) => {
|
|
1462
|
+
const l = i, r = l.getAttribute("id"), s = l.getAttribute("title");
|
|
1463
|
+
if (!r || !s) {
|
|
1464
|
+
console.warn(
|
|
1465
|
+
`[parseLightDomToolPanels] Tool panel missing required id or title attribute: id="${r ?? ""}", title="${s ?? ""}"`
|
|
1466
|
+
);
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1469
|
+
const a = l.getAttribute("icon") ?? void 0, c = l.getAttribute("tooltip") ?? void 0, h = parseInt(l.getAttribute("order") ?? "100", 10);
|
|
1470
|
+
let d;
|
|
1471
|
+
const u = o?.(l);
|
|
1472
|
+
if (u)
|
|
1473
|
+
d = u;
|
|
1474
|
+
else {
|
|
1475
|
+
const b = l.innerHTML.trim();
|
|
1476
|
+
d = (g) => {
|
|
1477
|
+
const w = document.createElement("div");
|
|
1478
|
+
return w.innerHTML = b, g.appendChild(w), () => w.remove();
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
const p = e.toolPanels.get(r);
|
|
1482
|
+
if (p) {
|
|
1483
|
+
if (u) {
|
|
1484
|
+
p.render = d, p.order = h, p.icon = a, p.tooltip = c;
|
|
1485
|
+
const b = e.panelCleanups.get(r);
|
|
1486
|
+
b && (b(), e.panelCleanups.delete(r));
|
|
1487
|
+
}
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
const f = {
|
|
1491
|
+
id: r,
|
|
1492
|
+
title: s,
|
|
1493
|
+
icon: a,
|
|
1494
|
+
tooltip: c,
|
|
1495
|
+
order: h,
|
|
1496
|
+
render: d
|
|
1497
|
+
};
|
|
1498
|
+
e.toolPanels.set(r, f), e.lightDomToolPanelIds.add(r), l.style.display = "none";
|
|
1499
|
+
});
|
|
1500
|
+
}
|
|
1501
|
+
function Bt(t, e, o, n) {
|
|
1502
|
+
const i = t.querySelector(".tbw-shell-toolbar");
|
|
1503
|
+
i && i.addEventListener("click", (r) => {
|
|
1504
|
+
const s = r.target;
|
|
1505
|
+
if (s.closest("[data-panel-toggle]")) {
|
|
1506
|
+
n.onPanelToggle();
|
|
1507
|
+
return;
|
|
1508
|
+
}
|
|
1509
|
+
const c = s.closest("[data-btn]");
|
|
1510
|
+
if (c) {
|
|
1511
|
+
const h = c.getAttribute("data-btn");
|
|
1512
|
+
h && n.onToolbarButtonClick(h);
|
|
1513
|
+
}
|
|
1514
|
+
});
|
|
1515
|
+
const l = t.querySelector(".tbw-accordion");
|
|
1516
|
+
l && l.addEventListener("click", (r) => {
|
|
1517
|
+
const a = r.target.closest(".tbw-accordion-header");
|
|
1518
|
+
if (a) {
|
|
1519
|
+
const h = a.closest("[data-section]")?.getAttribute("data-section");
|
|
1520
|
+
h && n.onSectionToggle(h);
|
|
1521
|
+
}
|
|
1522
|
+
});
|
|
1523
|
+
}
|
|
1524
|
+
function It(t, e, o) {
|
|
1525
|
+
const n = t.querySelector(".tbw-tool-panel"), i = t.querySelector("[data-resize-handle]"), l = t.querySelector(".tbw-shell-body");
|
|
1526
|
+
if (!n || !i || !l)
|
|
1527
|
+
return () => {
|
|
1528
|
+
};
|
|
1529
|
+
const r = e?.toolPanel?.position ?? "right", s = 200;
|
|
1530
|
+
let a = 0, c = 0, h = 0, d = !1;
|
|
1531
|
+
const u = (b) => {
|
|
1532
|
+
if (!d) return;
|
|
1533
|
+
b.preventDefault();
|
|
1534
|
+
const g = r === "left" ? b.clientX - a : a - b.clientX, w = Math.min(h, Math.max(s, c + g));
|
|
1535
|
+
n.style.width = `${w}px`;
|
|
1536
|
+
}, p = () => {
|
|
1537
|
+
if (!d) return;
|
|
1538
|
+
d = !1, i.classList.remove("resizing"), n.style.transition = "", document.body.style.cursor = "", document.body.style.userSelect = "";
|
|
1539
|
+
const b = n.getBoundingClientRect().width;
|
|
1540
|
+
o(b), document.removeEventListener("mousemove", u), document.removeEventListener("mouseup", p);
|
|
1541
|
+
}, f = (b) => {
|
|
1542
|
+
b.preventDefault(), d = !0, a = b.clientX, c = n.getBoundingClientRect().width, h = l.getBoundingClientRect().width - 20, i.classList.add("resizing"), n.style.transition = "none", document.body.style.cursor = "col-resize", document.body.style.userSelect = "none", document.addEventListener("mousemove", u), document.addEventListener("mouseup", p);
|
|
1543
|
+
};
|
|
1544
|
+
return i.addEventListener("mousedown", f), () => {
|
|
1545
|
+
i.removeEventListener("mousedown", f), document.removeEventListener("mousemove", u), document.removeEventListener("mouseup", p);
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1548
|
+
function qt(t, e, o) {
|
|
1549
|
+
const n = [...e?.header?.toolbarButtons ?? [], ...o.toolbarButtons.values()];
|
|
1550
|
+
for (const i of n) {
|
|
1551
|
+
const l = t.querySelector(`[data-btn-slot="${i.id}"]`);
|
|
1552
|
+
if (!l) continue;
|
|
1553
|
+
const r = o.toolbarButtonCleanups.get(i.id);
|
|
1554
|
+
if (r && (r(), o.toolbarButtonCleanups.delete(i.id)), i.element)
|
|
1555
|
+
l.appendChild(i.element);
|
|
1556
|
+
else if (i.render) {
|
|
1557
|
+
const s = i.render(l);
|
|
1558
|
+
s && o.toolbarButtonCleanups.set(i.id, s);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
function qe(t, e) {
|
|
1563
|
+
const o = t.querySelector(".tbw-shell-content");
|
|
1564
|
+
if (!o) return;
|
|
1565
|
+
const n = [...e.headerContents.values()].sort((l, r) => (l.order ?? 100) - (r.order ?? 100)), i = o.querySelector('slot[name="header-content"]');
|
|
1566
|
+
for (const l of n) {
|
|
1567
|
+
const r = e.headerContentCleanups.get(l.id);
|
|
1568
|
+
r && (r(), e.headerContentCleanups.delete(l.id));
|
|
1569
|
+
let s = o.querySelector(`[data-header-content="${l.id}"]`);
|
|
1570
|
+
s || (s = document.createElement("div"), s.setAttribute("data-header-content", l.id), i ? o.insertBefore(s, i) : o.appendChild(s));
|
|
1571
|
+
const a = l.render(s);
|
|
1572
|
+
a && e.headerContentCleanups.set(l.id, a);
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
function Wt(t, e, o) {
|
|
1576
|
+
if (!e.isPanelOpen) return;
|
|
1577
|
+
const n = M(o?.expand ?? O.expand), i = M(o?.collapse ?? O.collapse);
|
|
1578
|
+
for (const [l, r] of e.toolPanels) {
|
|
1579
|
+
const s = e.expandedSections.has(l), a = t.querySelector(`[data-section="${l}"]`), c = a?.querySelector(".tbw-accordion-content");
|
|
1580
|
+
if (!a || !c) continue;
|
|
1581
|
+
a.classList.toggle("expanded", s);
|
|
1582
|
+
const h = a.querySelector(".tbw-accordion-header");
|
|
1583
|
+
h && h.setAttribute("aria-expanded", String(s));
|
|
1584
|
+
const d = a.querySelector(".tbw-accordion-chevron");
|
|
1585
|
+
if (d && (d.innerHTML = s ? i : n), s) {
|
|
1586
|
+
if (c.children.length === 0) {
|
|
1587
|
+
const u = r.render(c);
|
|
1588
|
+
u && e.panelCleanups.set(l, u);
|
|
1589
|
+
}
|
|
1590
|
+
} else {
|
|
1591
|
+
const u = e.panelCleanups.get(l);
|
|
1592
|
+
u && (u(), e.panelCleanups.delete(l)), c.innerHTML = "";
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
function Se(t, e) {
|
|
1597
|
+
const o = t.querySelector("[data-panel-toggle]");
|
|
1598
|
+
o && (o.classList.toggle("active", e.isPanelOpen), o.setAttribute("aria-pressed", String(e.isPanelOpen)));
|
|
1599
|
+
}
|
|
1600
|
+
function Re(t, e) {
|
|
1601
|
+
const o = t.querySelector(".tbw-tool-panel");
|
|
1602
|
+
o && (o.classList.toggle("open", e.isPanelOpen), e.isPanelOpen || (o.style.width = ""));
|
|
1603
|
+
}
|
|
1604
|
+
function $t(t, e) {
|
|
1605
|
+
const o = [];
|
|
1606
|
+
for (const n of t?.header?.toolbarButtons ?? [])
|
|
1607
|
+
o.push({
|
|
1608
|
+
id: n.id,
|
|
1609
|
+
label: n.label,
|
|
1610
|
+
disabled: n.disabled ?? !1,
|
|
1611
|
+
source: "config"
|
|
1612
|
+
});
|
|
1613
|
+
for (const n of e.toolbarButtons.values())
|
|
1614
|
+
o.push({
|
|
1615
|
+
id: n.id,
|
|
1616
|
+
label: n.label,
|
|
1617
|
+
disabled: n.disabled ?? !1,
|
|
1618
|
+
source: "config"
|
|
1619
|
+
});
|
|
1620
|
+
for (let n = 0; n < e.lightDomButtons.length; n++) {
|
|
1621
|
+
const l = e.lightDomButtons[n].querySelector("button");
|
|
1622
|
+
o.push({
|
|
1623
|
+
id: `light-dom-${n}`,
|
|
1624
|
+
label: l?.getAttribute("title") ?? l?.getAttribute("aria-label") ?? "",
|
|
1625
|
+
disabled: l?.disabled ?? !1,
|
|
1626
|
+
source: "light-dom"
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
for (const n of e.toolPanels.values())
|
|
1630
|
+
o.push({
|
|
1631
|
+
id: `panel-toggle-${n.id}`,
|
|
1632
|
+
label: n.tooltip ?? n.title,
|
|
1633
|
+
disabled: !1,
|
|
1634
|
+
source: "panel-toggle",
|
|
1635
|
+
panelId: n.id
|
|
1636
|
+
});
|
|
1637
|
+
return o;
|
|
1638
|
+
}
|
|
1639
|
+
function Vt(t) {
|
|
1640
|
+
for (const e of t.headerContentCleanups.values())
|
|
1641
|
+
e();
|
|
1642
|
+
t.headerContentCleanups.clear(), t.activePanelCleanup && (t.activePanelCleanup(), t.activePanelCleanup = null);
|
|
1643
|
+
for (const e of t.toolbarButtonCleanups.values())
|
|
1644
|
+
e();
|
|
1645
|
+
t.toolbarButtonCleanups.clear(), t.activePanel && t.toolPanels.get(t.activePanel)?.onClose?.(), t.toolPanels.clear(), t.headerContents.clear(), t.toolbarButtons.clear(), t.lightDomButtons = [], t.lightDomHeaderContent = [], t.activePanel = null;
|
|
1646
|
+
}
|
|
1647
|
+
function Ft(t, e) {
|
|
1648
|
+
let o = !1;
|
|
1649
|
+
const n = {
|
|
1650
|
+
get isInitialized() {
|
|
1651
|
+
return o;
|
|
1652
|
+
},
|
|
1653
|
+
setInitialized(i) {
|
|
1654
|
+
o = i;
|
|
1655
|
+
},
|
|
1656
|
+
get isPanelOpen() {
|
|
1657
|
+
return t.isPanelOpen;
|
|
1658
|
+
},
|
|
1659
|
+
get activePanel() {
|
|
1660
|
+
return t.isPanelOpen && t.expandedSections.size > 0 ? [...t.expandedSections][0] : null;
|
|
1661
|
+
},
|
|
1662
|
+
get expandedSections() {
|
|
1663
|
+
return [...t.expandedSections];
|
|
1664
|
+
},
|
|
1665
|
+
openToolPanel() {
|
|
1666
|
+
if (t.isPanelOpen) return;
|
|
1667
|
+
if (t.toolPanels.size === 0) {
|
|
1668
|
+
console.warn("[tbw-grid] No tool panels registered");
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1671
|
+
if (t.isPanelOpen = !0, t.expandedSections.size === 0 && t.toolPanels.size > 0) {
|
|
1672
|
+
const r = [...t.toolPanels.values()].sort((s, a) => (s.order ?? 100) - (a.order ?? 100))[0];
|
|
1673
|
+
r && t.expandedSections.add(r.id);
|
|
1674
|
+
}
|
|
1675
|
+
const i = e.getShadow();
|
|
1676
|
+
Se(i, t), Re(i, t), Wt(i, t, e.getAccordionIcons()), e.emit("tool-panel-open", { sections: n.expandedSections });
|
|
1677
|
+
},
|
|
1678
|
+
closeToolPanel() {
|
|
1679
|
+
if (!t.isPanelOpen) return;
|
|
1680
|
+
for (const l of t.panelCleanups.values())
|
|
1681
|
+
l();
|
|
1682
|
+
t.panelCleanups.clear(), t.activePanelCleanup && (t.activePanelCleanup(), t.activePanelCleanup = null);
|
|
1683
|
+
for (const l of t.toolPanels.values())
|
|
1684
|
+
l.onClose?.();
|
|
1685
|
+
t.isPanelOpen = !1;
|
|
1686
|
+
const i = e.getShadow();
|
|
1687
|
+
Se(i, t), Re(i, t), e.emit("tool-panel-close", {});
|
|
1688
|
+
},
|
|
1689
|
+
toggleToolPanel() {
|
|
1690
|
+
t.isPanelOpen ? n.closeToolPanel() : n.openToolPanel();
|
|
1691
|
+
},
|
|
1692
|
+
toggleToolPanelSection(i) {
|
|
1693
|
+
const l = t.toolPanels.get(i);
|
|
1694
|
+
if (!l) {
|
|
1695
|
+
console.warn(`[tbw-grid] Tool panel section "${i}" not found`);
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
if (t.toolPanels.size === 1)
|
|
1699
|
+
return;
|
|
1700
|
+
const r = e.getShadow(), s = t.expandedSections.has(i);
|
|
1701
|
+
if (s) {
|
|
1702
|
+
const a = t.panelCleanups.get(i);
|
|
1703
|
+
a && (a(), t.panelCleanups.delete(i)), l.onClose?.(), t.expandedSections.delete(i), ne(r, i, !1);
|
|
1704
|
+
} else {
|
|
1705
|
+
for (const [a, c] of t.toolPanels)
|
|
1706
|
+
if (a !== i && t.expandedSections.has(a)) {
|
|
1707
|
+
const h = t.panelCleanups.get(a);
|
|
1708
|
+
h && (h(), t.panelCleanups.delete(a)), c.onClose?.(), t.expandedSections.delete(a), ne(r, a, !1);
|
|
1709
|
+
const d = r.querySelector(`[data-section="${a}"] .tbw-accordion-content`);
|
|
1710
|
+
d && (d.innerHTML = "");
|
|
1711
|
+
}
|
|
1712
|
+
t.expandedSections.add(i), ne(r, i, !0), Gt(r, t, i);
|
|
1713
|
+
}
|
|
1714
|
+
e.emit("tool-panel-section-toggle", { id: i, expanded: !s });
|
|
1715
|
+
},
|
|
1716
|
+
getToolPanels() {
|
|
1717
|
+
return [...t.toolPanels.values()];
|
|
1718
|
+
},
|
|
1719
|
+
registerToolPanel(i) {
|
|
1720
|
+
if (t.toolPanels.has(i.id)) {
|
|
1721
|
+
console.warn(`[tbw-grid] Tool panel "${i.id}" already registered`);
|
|
1722
|
+
return;
|
|
1723
|
+
}
|
|
1724
|
+
t.toolPanels.set(i.id, i), o && e.refreshShellHeader();
|
|
1725
|
+
},
|
|
1726
|
+
unregisterToolPanel(i) {
|
|
1727
|
+
if (t.expandedSections.has(i)) {
|
|
1728
|
+
const l = t.panelCleanups.get(i);
|
|
1729
|
+
l && (l(), t.panelCleanups.delete(i)), t.expandedSections.delete(i);
|
|
1730
|
+
}
|
|
1731
|
+
t.toolPanels.delete(i), o && e.refreshShellHeader();
|
|
1732
|
+
},
|
|
1733
|
+
getHeaderContents() {
|
|
1734
|
+
return [...t.headerContents.values()];
|
|
1735
|
+
},
|
|
1736
|
+
registerHeaderContent(i) {
|
|
1737
|
+
if (t.headerContents.has(i.id)) {
|
|
1738
|
+
console.warn(`[tbw-grid] Header content "${i.id}" already registered`);
|
|
1739
|
+
return;
|
|
1740
|
+
}
|
|
1741
|
+
t.headerContents.set(i.id, i), o && qe(e.getShadow(), t);
|
|
1742
|
+
},
|
|
1743
|
+
unregisterHeaderContent(i) {
|
|
1744
|
+
const l = t.headerContentCleanups.get(i);
|
|
1745
|
+
l && (l(), t.headerContentCleanups.delete(i)), t.headerContents.get(i)?.onDestroy?.(), t.headerContents.delete(i), e.getShadow().querySelector(`[data-header-content="${i}"]`)?.remove();
|
|
1746
|
+
},
|
|
1747
|
+
getToolbarButtons() {
|
|
1748
|
+
return $t(e.getShellConfig(), t);
|
|
1749
|
+
},
|
|
1750
|
+
registerToolbarButton(i) {
|
|
1751
|
+
if (t.toolbarButtons.has(i.id)) {
|
|
1752
|
+
console.warn(`[tbw-grid] Toolbar button "${i.id}" already registered`);
|
|
1753
|
+
return;
|
|
1754
|
+
}
|
|
1755
|
+
t.toolbarButtons.set(i.id, i), o && e.refreshShellHeader();
|
|
1756
|
+
},
|
|
1757
|
+
unregisterToolbarButton(i) {
|
|
1758
|
+
const l = t.toolbarButtonCleanups.get(i);
|
|
1759
|
+
l && (l(), t.toolbarButtonCleanups.delete(i)), t.toolbarButtons.delete(i), o && e.refreshShellHeader();
|
|
1760
|
+
},
|
|
1761
|
+
setToolbarButtonDisabled(i, l) {
|
|
1762
|
+
const r = t.toolbarButtons.get(i);
|
|
1763
|
+
r && (r.disabled = l);
|
|
1764
|
+
const s = e.getShadow().querySelector(`[data-btn="${i}"]`);
|
|
1765
|
+
s && (s.disabled = l);
|
|
1766
|
+
}
|
|
1767
|
+
};
|
|
1768
|
+
return n;
|
|
1769
|
+
}
|
|
1770
|
+
function ne(t, e, o) {
|
|
1771
|
+
const n = t.querySelector(`[data-section="${e}"]`);
|
|
1772
|
+
n && n.classList.toggle("expanded", o);
|
|
1773
|
+
}
|
|
1774
|
+
function Gt(t, e, o) {
|
|
1775
|
+
const n = e.toolPanels.get(o);
|
|
1776
|
+
if (!n?.render) return;
|
|
1777
|
+
const i = t.querySelector(`[data-section="${o}"] .tbw-accordion-content`);
|
|
1778
|
+
if (!i) return;
|
|
1779
|
+
const l = n.render(i);
|
|
1780
|
+
l && e.panelCleanups.set(o, l);
|
|
1781
|
+
}
|
|
1782
|
+
function Ut(t, e, o, n) {
|
|
1783
|
+
const i = se(e, o);
|
|
1784
|
+
if (t.replaceChildren(), i) {
|
|
1785
|
+
const l = M(n?.toolPanel ?? O.toolPanel), r = M(n?.expand ?? O.expand), s = M(n?.collapse ?? O.collapse), c = [...e?.header?.toolbarButtons ?? []].sort((w, _) => (w.order ?? 100) - (_.order ?? 100)), h = [...o.toolbarButtons.values()].sort((w, _) => (w.order ?? 100) - (_.order ?? 100)), d = {
|
|
1786
|
+
title: e?.header?.title ?? o.lightDomTitle ?? void 0,
|
|
1787
|
+
hasLightDomButtons: o.lightDomButtons.length > 0,
|
|
1788
|
+
hasPanels: o.toolPanels.size > 0,
|
|
1789
|
+
isPanelOpen: o.isPanelOpen,
|
|
1790
|
+
toolPanelIcon: l,
|
|
1791
|
+
configButtons: c.map((w) => ({
|
|
1792
|
+
id: w.id,
|
|
1793
|
+
label: w.label,
|
|
1794
|
+
icon: M(w.icon),
|
|
1795
|
+
disabled: w.disabled,
|
|
1796
|
+
hasElement: !!w.element,
|
|
1797
|
+
hasRender: !!w.render,
|
|
1798
|
+
action: w.action
|
|
1799
|
+
})),
|
|
1800
|
+
apiButtons: h.map((w) => ({
|
|
1801
|
+
id: w.id,
|
|
1802
|
+
label: w.label,
|
|
1803
|
+
icon: M(w.icon),
|
|
1804
|
+
disabled: w.disabled,
|
|
1805
|
+
hasElement: !!w.element,
|
|
1806
|
+
hasRender: !!w.render,
|
|
1807
|
+
action: w.action
|
|
1808
|
+
}))
|
|
1809
|
+
}, u = [...o.toolPanels.values()].sort((w, _) => (w.order ?? 100) - (_.order ?? 100)), p = {
|
|
1810
|
+
position: e?.toolPanel?.position ?? "right",
|
|
1811
|
+
isPanelOpen: o.isPanelOpen,
|
|
1812
|
+
expandIcon: r,
|
|
1813
|
+
collapseIcon: s,
|
|
1814
|
+
panels: u.map((w) => ({
|
|
1815
|
+
id: w.id,
|
|
1816
|
+
title: w.title,
|
|
1817
|
+
icon: M(w.icon),
|
|
1818
|
+
isExpanded: o.expandedSections.has(w.id)
|
|
1819
|
+
}))
|
|
1820
|
+
}, f = Dt(d), b = zt(p), g = Ee({
|
|
1821
|
+
hasShell: !0,
|
|
1822
|
+
shellHeader: f,
|
|
1823
|
+
shellBody: b
|
|
1824
|
+
});
|
|
1825
|
+
t.appendChild(g);
|
|
1826
|
+
} else {
|
|
1827
|
+
const l = Ee({ hasShell: !1 });
|
|
1828
|
+
t.appendChild(l);
|
|
1829
|
+
}
|
|
1830
|
+
return i;
|
|
1831
|
+
}
|
|
1832
|
+
function Xt() {
|
|
1833
|
+
return {
|
|
1834
|
+
startY: null,
|
|
1835
|
+
startX: null,
|
|
1836
|
+
scrollTop: null,
|
|
1837
|
+
scrollLeft: null,
|
|
1838
|
+
lastY: null,
|
|
1839
|
+
lastX: null,
|
|
1840
|
+
lastTime: null,
|
|
1841
|
+
velocityY: 0,
|
|
1842
|
+
velocityX: 0,
|
|
1843
|
+
momentumRaf: 0
|
|
1844
|
+
};
|
|
1845
|
+
}
|
|
1846
|
+
function Yt(t) {
|
|
1847
|
+
t.startY = null, t.startX = null, t.scrollTop = null, t.scrollLeft = null, t.lastY = null, t.lastX = null, t.lastTime = null;
|
|
1848
|
+
}
|
|
1849
|
+
function We(t) {
|
|
1850
|
+
t.momentumRaf && (cancelAnimationFrame(t.momentumRaf), t.momentumRaf = 0);
|
|
1851
|
+
}
|
|
1852
|
+
function jt(t, e, o) {
|
|
1853
|
+
if (t.touches.length !== 1) return;
|
|
1854
|
+
We(e);
|
|
1855
|
+
const n = t.touches[0];
|
|
1856
|
+
e.startY = n.clientY, e.startX = n.clientX, e.lastY = n.clientY, e.lastX = n.clientX, e.lastTime = performance.now(), e.scrollTop = o.fauxScrollbar.scrollTop, e.scrollLeft = o.scrollArea?.scrollLeft ?? 0, e.velocityY = 0, e.velocityX = 0;
|
|
1857
|
+
}
|
|
1858
|
+
function Kt(t, e, o) {
|
|
1859
|
+
if (t.touches.length !== 1 || e.startY === null || e.startX === null || e.scrollTop === null || e.scrollLeft === null)
|
|
1860
|
+
return !1;
|
|
1861
|
+
const n = t.touches[0], i = n.clientY, l = n.clientX, r = performance.now(), s = e.startY - i, a = e.startX - l;
|
|
1862
|
+
if (e.lastTime !== null && e.lastY !== null && e.lastX !== null) {
|
|
1863
|
+
const b = r - e.lastTime;
|
|
1864
|
+
b > 0 && (e.velocityY = (e.lastY - i) / b, e.velocityX = (e.lastX - l) / b);
|
|
1865
|
+
}
|
|
1866
|
+
e.lastY = i, e.lastX = l, e.lastTime = r;
|
|
1867
|
+
const { scrollTop: c, scrollHeight: h, clientHeight: d } = o.fauxScrollbar, u = h - d, p = s > 0 && c < u || s < 0 && c > 0;
|
|
1868
|
+
let f = !1;
|
|
1869
|
+
if (o.scrollArea) {
|
|
1870
|
+
const { scrollLeft: b, scrollWidth: g, clientWidth: w } = o.scrollArea, _ = g - w;
|
|
1871
|
+
f = a > 0 && b < _ || a < 0 && b > 0;
|
|
1872
|
+
}
|
|
1873
|
+
return p && (o.fauxScrollbar.scrollTop = e.scrollTop + s), f && o.scrollArea && (o.scrollArea.scrollLeft = e.scrollLeft + a), p || f;
|
|
1874
|
+
}
|
|
1875
|
+
function Zt(t, e) {
|
|
1876
|
+
(Math.abs(t.velocityY) > 0.1 || Math.abs(t.velocityX) > 0.1) && Jt(t, e), Yt(t);
|
|
1877
|
+
}
|
|
1878
|
+
function Jt(t, e) {
|
|
1879
|
+
const i = () => {
|
|
1880
|
+
t.velocityY *= 0.95, t.velocityX *= 0.95;
|
|
1881
|
+
const l = t.velocityY * 16, r = t.velocityX * 16;
|
|
1882
|
+
Math.abs(t.velocityY) > 0.01 && (e.fauxScrollbar.scrollTop += l), Math.abs(t.velocityX) > 0.01 && e.scrollArea && (e.scrollArea.scrollLeft += r), Math.abs(t.velocityY) > 0.01 || Math.abs(t.velocityX) > 0.01 ? t.momentumRaf = requestAnimationFrame(i) : t.momentumRaf = 0;
|
|
1883
|
+
};
|
|
1884
|
+
t.momentumRaf = requestAnimationFrame(i);
|
|
1885
|
+
}
|
|
1886
|
+
function Qt(t, e, o, n) {
|
|
1887
|
+
t.addEventListener("touchstart", (i) => jt(i, e, o), {
|
|
1888
|
+
passive: !0,
|
|
1889
|
+
signal: n
|
|
1890
|
+
}), t.addEventListener(
|
|
1891
|
+
"touchmove",
|
|
1892
|
+
(i) => {
|
|
1893
|
+
Kt(i, e, o) && i.preventDefault();
|
|
1894
|
+
},
|
|
1895
|
+
{ passive: !1, signal: n }
|
|
1896
|
+
), t.addEventListener("touchend", () => Zt(e, o), { passive: !0, signal: n });
|
|
1897
|
+
}
|
|
1898
|
+
class eo {
|
|
1899
|
+
constructor(e) {
|
|
1900
|
+
this.grid = e;
|
|
1901
|
+
}
|
|
1902
|
+
/** Plugin instances in order of attachment */
|
|
1903
|
+
plugins = [];
|
|
1904
|
+
/** Map from plugin class to instance for fast lookup */
|
|
1905
|
+
pluginMap = /* @__PURE__ */ new Map();
|
|
1906
|
+
/** Cell renderers registered by plugins */
|
|
1907
|
+
cellRenderers = /* @__PURE__ */ new Map();
|
|
1908
|
+
/** Header renderers registered by plugins */
|
|
1909
|
+
headerRenderers = /* @__PURE__ */ new Map();
|
|
1910
|
+
/** Cell editors registered by plugins */
|
|
1911
|
+
cellEditors = /* @__PURE__ */ new Map();
|
|
1912
|
+
/**
|
|
1913
|
+
* Attach all plugins from the config.
|
|
1914
|
+
*/
|
|
1915
|
+
attachAll(e) {
|
|
1916
|
+
for (const o of e)
|
|
1917
|
+
this.attach(o);
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* Attach a plugin to this grid.
|
|
1921
|
+
*/
|
|
1922
|
+
attach(e) {
|
|
1923
|
+
if (this.pluginMap.set(e.constructor, e), this.plugins.push(e), e.cellRenderers)
|
|
1924
|
+
for (const [o, n] of Object.entries(e.cellRenderers))
|
|
1925
|
+
this.cellRenderers.set(o, n);
|
|
1926
|
+
if (e.headerRenderers)
|
|
1927
|
+
for (const [o, n] of Object.entries(e.headerRenderers))
|
|
1928
|
+
this.headerRenderers.set(o, n);
|
|
1929
|
+
if (e.cellEditors)
|
|
1930
|
+
for (const [o, n] of Object.entries(e.cellEditors))
|
|
1931
|
+
this.cellEditors.set(o, n);
|
|
1932
|
+
e.attach(this.grid);
|
|
1933
|
+
}
|
|
1934
|
+
/**
|
|
1935
|
+
* Detach all plugins and clean up.
|
|
1936
|
+
*/
|
|
1937
|
+
detachAll() {
|
|
1938
|
+
for (let e = this.plugins.length - 1; e >= 0; e--)
|
|
1939
|
+
this.plugins[e].detach();
|
|
1940
|
+
this.plugins = [], this.pluginMap.clear(), this.cellRenderers.clear(), this.headerRenderers.clear(), this.cellEditors.clear();
|
|
1941
|
+
}
|
|
1942
|
+
/**
|
|
1943
|
+
* Get a plugin instance by its class.
|
|
1944
|
+
*/
|
|
1945
|
+
getPlugin(e) {
|
|
1946
|
+
return this.pluginMap.get(e);
|
|
1947
|
+
}
|
|
1948
|
+
/**
|
|
1949
|
+
* Get a plugin instance by its name.
|
|
1950
|
+
*/
|
|
1951
|
+
getPluginByName(e) {
|
|
1952
|
+
return this.plugins.find((o) => o.name === e);
|
|
1953
|
+
}
|
|
1954
|
+
/**
|
|
1955
|
+
* Check if a plugin is attached.
|
|
1956
|
+
*/
|
|
1957
|
+
hasPlugin(e) {
|
|
1958
|
+
return this.pluginMap.has(e);
|
|
1959
|
+
}
|
|
1960
|
+
/**
|
|
1961
|
+
* Get all attached plugins.
|
|
1962
|
+
*/
|
|
1963
|
+
getAll() {
|
|
1964
|
+
return this.plugins;
|
|
1965
|
+
}
|
|
1966
|
+
/**
|
|
1967
|
+
* Get a cell renderer by type name.
|
|
1968
|
+
*/
|
|
1969
|
+
getCellRenderer(e) {
|
|
1970
|
+
return this.cellRenderers.get(e);
|
|
1971
|
+
}
|
|
1972
|
+
/**
|
|
1973
|
+
* Get a header renderer by type name.
|
|
1974
|
+
*/
|
|
1975
|
+
getHeaderRenderer(e) {
|
|
1976
|
+
return this.headerRenderers.get(e);
|
|
1977
|
+
}
|
|
1978
|
+
/**
|
|
1979
|
+
* Get a cell editor by type name.
|
|
1980
|
+
*/
|
|
1981
|
+
getCellEditor(e) {
|
|
1982
|
+
return this.cellEditors.get(e);
|
|
1983
|
+
}
|
|
1984
|
+
/**
|
|
1985
|
+
* Get all CSS styles from all plugins.
|
|
1986
|
+
*/
|
|
1987
|
+
getAllStyles() {
|
|
1988
|
+
return this.plugins.filter((e) => e.styles).map((e) => e.styles).join(`
|
|
1989
|
+
`);
|
|
1990
|
+
}
|
|
1991
|
+
// #region Hook execution methods
|
|
1992
|
+
/**
|
|
1993
|
+
* Execute processRows hook on all plugins.
|
|
1994
|
+
*/
|
|
1995
|
+
processRows(e) {
|
|
1996
|
+
let o = [...e];
|
|
1997
|
+
for (const n of this.plugins)
|
|
1998
|
+
n.processRows && (o = n.processRows(o));
|
|
1999
|
+
return o;
|
|
2000
|
+
}
|
|
2001
|
+
/**
|
|
2002
|
+
* Execute processColumns hook on all plugins.
|
|
2003
|
+
*/
|
|
2004
|
+
processColumns(e) {
|
|
2005
|
+
let o = [...e];
|
|
2006
|
+
for (const n of this.plugins)
|
|
2007
|
+
n.processColumns && (o = n.processColumns(o));
|
|
2008
|
+
return o;
|
|
2009
|
+
}
|
|
2010
|
+
/**
|
|
2011
|
+
* Execute beforeRender hook on all plugins.
|
|
2012
|
+
*/
|
|
2013
|
+
beforeRender() {
|
|
2014
|
+
for (const e of this.plugins)
|
|
2015
|
+
e.beforeRender?.();
|
|
2016
|
+
}
|
|
2017
|
+
/**
|
|
2018
|
+
* Execute afterRender hook on all plugins.
|
|
2019
|
+
*/
|
|
2020
|
+
afterRender() {
|
|
2021
|
+
for (const e of this.plugins)
|
|
2022
|
+
e.afterRender?.();
|
|
2023
|
+
}
|
|
2024
|
+
/**
|
|
2025
|
+
* Execute onScrollRender hook on all plugins.
|
|
2026
|
+
* Called after scroll-triggered row rendering for lightweight visual state updates.
|
|
2027
|
+
*/
|
|
2028
|
+
onScrollRender() {
|
|
2029
|
+
for (const e of this.plugins)
|
|
2030
|
+
e.onScrollRender?.();
|
|
2031
|
+
}
|
|
2032
|
+
/**
|
|
2033
|
+
* Get total extra height contributed by plugins (e.g., expanded detail rows).
|
|
2034
|
+
* Used to adjust scrollbar height calculations.
|
|
2035
|
+
*/
|
|
2036
|
+
getExtraHeight() {
|
|
2037
|
+
let e = 0;
|
|
2038
|
+
for (const o of this.plugins)
|
|
2039
|
+
typeof o.getExtraHeight == "function" && (e += o.getExtraHeight());
|
|
2040
|
+
return e;
|
|
2041
|
+
}
|
|
2042
|
+
/**
|
|
2043
|
+
* Get extra height from plugins that appears before a given row index.
|
|
2044
|
+
* Used by virtualization to correctly position the scroll window.
|
|
2045
|
+
*/
|
|
2046
|
+
getExtraHeightBefore(e) {
|
|
2047
|
+
let o = 0;
|
|
2048
|
+
for (const n of this.plugins)
|
|
2049
|
+
typeof n.getExtraHeightBefore == "function" && (o += n.getExtraHeightBefore(e));
|
|
2050
|
+
return o;
|
|
2051
|
+
}
|
|
2052
|
+
/**
|
|
2053
|
+
* Adjust the virtualization start index based on plugin needs.
|
|
2054
|
+
* Returns the minimum start index from all plugins.
|
|
2055
|
+
*/
|
|
2056
|
+
adjustVirtualStart(e, o, n) {
|
|
2057
|
+
let i = e;
|
|
2058
|
+
for (const l of this.plugins)
|
|
2059
|
+
if (typeof l.adjustVirtualStart == "function") {
|
|
2060
|
+
const r = l.adjustVirtualStart(e, o, n);
|
|
2061
|
+
r < i && (i = r);
|
|
2062
|
+
}
|
|
2063
|
+
return i;
|
|
2064
|
+
}
|
|
2065
|
+
/**
|
|
2066
|
+
* Execute renderRow hook on all plugins.
|
|
2067
|
+
* Returns true if any plugin handled the row.
|
|
2068
|
+
*/
|
|
2069
|
+
renderRow(e, o, n) {
|
|
2070
|
+
for (const i of this.plugins)
|
|
2071
|
+
if (i.renderRow?.(e, o, n))
|
|
2072
|
+
return !0;
|
|
2073
|
+
return !1;
|
|
2074
|
+
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Query all plugins with a generic query and collect responses.
|
|
2077
|
+
* This enables inter-plugin communication without the core knowing plugin-specific concepts.
|
|
2078
|
+
*
|
|
2079
|
+
* Common query types are defined in PLUGIN_QUERIES, but plugins can define their own.
|
|
2080
|
+
*
|
|
2081
|
+
* @param query - The query object containing type and context
|
|
2082
|
+
* @returns Array of non-undefined responses from plugins
|
|
2083
|
+
*/
|
|
2084
|
+
queryPlugins(e) {
|
|
2085
|
+
const o = [];
|
|
2086
|
+
for (const n of this.plugins) {
|
|
2087
|
+
const i = n.onPluginQuery?.(e);
|
|
2088
|
+
i !== void 0 && o.push(i);
|
|
2089
|
+
}
|
|
2090
|
+
return o;
|
|
2091
|
+
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Execute onKeyDown hook on all plugins.
|
|
2094
|
+
* Returns true if any plugin handled the event.
|
|
2095
|
+
*/
|
|
2096
|
+
onKeyDown(e) {
|
|
2097
|
+
for (const o of this.plugins)
|
|
2098
|
+
if (o.onKeyDown?.(e))
|
|
2099
|
+
return !0;
|
|
2100
|
+
return !1;
|
|
2101
|
+
}
|
|
2102
|
+
/**
|
|
2103
|
+
* Execute onCellClick hook on all plugins.
|
|
2104
|
+
* Returns true if any plugin handled the event.
|
|
2105
|
+
*/
|
|
2106
|
+
onCellClick(e) {
|
|
2107
|
+
for (const o of this.plugins)
|
|
2108
|
+
if (o.onCellClick?.(e))
|
|
2109
|
+
return !0;
|
|
2110
|
+
return !1;
|
|
2111
|
+
}
|
|
2112
|
+
/**
|
|
2113
|
+
* Execute onRowClick hook on all plugins.
|
|
2114
|
+
* Returns true if any plugin handled the event.
|
|
2115
|
+
*/
|
|
2116
|
+
onRowClick(e) {
|
|
2117
|
+
for (const o of this.plugins)
|
|
2118
|
+
if (o.onRowClick?.(e))
|
|
2119
|
+
return !0;
|
|
2120
|
+
return !1;
|
|
2121
|
+
}
|
|
2122
|
+
/**
|
|
2123
|
+
* Execute onHeaderClick hook on all plugins.
|
|
2124
|
+
* Returns true if any plugin handled the event.
|
|
2125
|
+
*/
|
|
2126
|
+
onHeaderClick(e) {
|
|
2127
|
+
for (const o of this.plugins)
|
|
2128
|
+
if (o.onHeaderClick?.(e))
|
|
2129
|
+
return !0;
|
|
2130
|
+
return !1;
|
|
2131
|
+
}
|
|
2132
|
+
/**
|
|
2133
|
+
* Execute onScroll hook on all plugins.
|
|
2134
|
+
*/
|
|
2135
|
+
onScroll(e) {
|
|
2136
|
+
for (const o of this.plugins)
|
|
2137
|
+
o.onScroll?.(e);
|
|
2138
|
+
}
|
|
2139
|
+
/**
|
|
2140
|
+
* Execute onCellMouseDown hook on all plugins.
|
|
2141
|
+
* Returns true if any plugin handled the event.
|
|
2142
|
+
*/
|
|
2143
|
+
onCellMouseDown(e) {
|
|
2144
|
+
for (const o of this.plugins)
|
|
2145
|
+
if (o.onCellMouseDown?.(e))
|
|
2146
|
+
return !0;
|
|
2147
|
+
return !1;
|
|
2148
|
+
}
|
|
2149
|
+
/**
|
|
2150
|
+
* Execute onCellMouseMove hook on all plugins.
|
|
2151
|
+
* Returns true if any plugin handled the event.
|
|
2152
|
+
*/
|
|
2153
|
+
onCellMouseMove(e) {
|
|
2154
|
+
for (const o of this.plugins)
|
|
2155
|
+
if (o.onCellMouseMove?.(e))
|
|
2156
|
+
return !0;
|
|
2157
|
+
return !1;
|
|
2158
|
+
}
|
|
2159
|
+
/**
|
|
2160
|
+
* Execute onCellMouseUp hook on all plugins.
|
|
2161
|
+
* Returns true if any plugin handled the event.
|
|
2162
|
+
*/
|
|
2163
|
+
onCellMouseUp(e) {
|
|
2164
|
+
for (const o of this.plugins)
|
|
2165
|
+
if (o.onCellMouseUp?.(e))
|
|
2166
|
+
return !0;
|
|
2167
|
+
return !1;
|
|
2168
|
+
}
|
|
2169
|
+
// #endregion
|
|
2170
|
+
// #region Scroll Boundary Hooks
|
|
2171
|
+
/**
|
|
2172
|
+
* Collect horizontal scroll boundary offsets from all plugins.
|
|
2173
|
+
* Combines offsets from all plugins that report them.
|
|
2174
|
+
*
|
|
2175
|
+
* @param rowEl - The row element (optional, for calculating widths from rendered cells)
|
|
2176
|
+
* @param focusedCell - The currently focused cell element (optional, to determine if scrolling should be skipped)
|
|
2177
|
+
* @returns Combined left and right pixel offsets, plus skipScroll if any plugin requests it
|
|
2178
|
+
*/
|
|
2179
|
+
getHorizontalScrollOffsets(e, o) {
|
|
2180
|
+
let n = 0, i = 0, l = !1;
|
|
2181
|
+
for (const r of this.plugins) {
|
|
2182
|
+
const s = r.getHorizontalScrollOffsets?.(e, o);
|
|
2183
|
+
s && (n += s.left, i += s.right, s.skipScroll && (l = !0));
|
|
2184
|
+
}
|
|
2185
|
+
return { left: n, right: i, skipScroll: l };
|
|
2186
|
+
}
|
|
2187
|
+
// #endregion
|
|
2188
|
+
// #region Shell Integration Hooks
|
|
2189
|
+
/**
|
|
2190
|
+
* Collect tool panels from all plugins.
|
|
2191
|
+
* Returns panels sorted by order (ascending).
|
|
2192
|
+
*/
|
|
2193
|
+
getToolPanels() {
|
|
2194
|
+
const e = [];
|
|
2195
|
+
for (const o of this.plugins) {
|
|
2196
|
+
const n = o.getToolPanel?.();
|
|
2197
|
+
n && e.push({ plugin: o, panel: n });
|
|
2198
|
+
}
|
|
2199
|
+
return e.sort((o, n) => (o.panel.order ?? 0) - (n.panel.order ?? 0));
|
|
2200
|
+
}
|
|
2201
|
+
/**
|
|
2202
|
+
* Collect header contents from all plugins.
|
|
2203
|
+
* Returns contents sorted by order (ascending).
|
|
2204
|
+
*/
|
|
2205
|
+
getHeaderContents() {
|
|
2206
|
+
const e = [];
|
|
2207
|
+
for (const o of this.plugins) {
|
|
2208
|
+
const n = o.getHeaderContent?.();
|
|
2209
|
+
n && e.push({ plugin: o, content: n });
|
|
2210
|
+
}
|
|
2211
|
+
return e.sort((o, n) => (o.content.order ?? 0) - (n.content.order ?? 0));
|
|
2212
|
+
}
|
|
2213
|
+
// #endregion
|
|
2214
|
+
}
|
|
2215
|
+
class N extends HTMLElement {
|
|
2216
|
+
// TODO: Rename to 'data-grid' when migration is complete
|
|
2217
|
+
static tagName = "tbw-grid";
|
|
2218
|
+
static version = "0.3.0";
|
|
2219
|
+
// ---------------- Framework Adapters ----------------
|
|
2220
|
+
/**
|
|
2221
|
+
* Registry of framework adapters that handle converting light DOM elements
|
|
2222
|
+
* to functional renderers/editors. Framework libraries (Angular, React, Vue)
|
|
2223
|
+
* register adapters to enable zero-boilerplate component integration.
|
|
2224
|
+
*/
|
|
2225
|
+
static adapters = [];
|
|
2226
|
+
/**
|
|
2227
|
+
* Register a framework adapter for handling framework-specific components.
|
|
2228
|
+
* Adapters are checked in registration order when processing light DOM templates.
|
|
2229
|
+
*
|
|
2230
|
+
* @example
|
|
2231
|
+
* ```typescript
|
|
2232
|
+
* // In @toolbox-web/grid-angular
|
|
2233
|
+
* import { AngularGridAdapter } from '@toolbox-web/grid-angular';
|
|
2234
|
+
*
|
|
2235
|
+
* // One-time setup in app
|
|
2236
|
+
* GridElement.registerAdapter(new AngularGridAdapter(injector, appRef));
|
|
2237
|
+
* ```
|
|
2238
|
+
*/
|
|
2239
|
+
static registerAdapter(e) {
|
|
2240
|
+
this.adapters.push(e);
|
|
2241
|
+
}
|
|
2242
|
+
/**
|
|
2243
|
+
* Get all registered framework adapters.
|
|
2244
|
+
* Used internally by light DOM parsing to find adapters that can handle templates.
|
|
2245
|
+
*/
|
|
2246
|
+
static getAdapters() {
|
|
2247
|
+
return this.adapters;
|
|
2248
|
+
}
|
|
2249
|
+
/**
|
|
2250
|
+
* Clear all registered adapters (primarily for testing).
|
|
2251
|
+
*/
|
|
2252
|
+
static clearAdapters() {
|
|
2253
|
+
this.adapters = [];
|
|
2254
|
+
}
|
|
2255
|
+
// ---------------- Observed Attributes ----------------
|
|
2256
|
+
static get observedAttributes() {
|
|
2257
|
+
return ["rows", "columns", "grid-config", "fit-mode", "edit-on"];
|
|
2258
|
+
}
|
|
2259
|
+
#n;
|
|
2260
|
+
#M = !1;
|
|
2261
|
+
// ---------------- Ready Promise ----------------
|
|
2262
|
+
#U;
|
|
2263
|
+
#X;
|
|
2264
|
+
// #region Input Properties
|
|
2265
|
+
// These backing fields store raw user input. They are merged into
|
|
2266
|
+
// #effectiveConfig by #mergeEffectiveConfig(). Never read directly
|
|
2267
|
+
// for rendering logic - always use effectiveConfig or derived state.
|
|
2268
|
+
#r = [];
|
|
2269
|
+
#c;
|
|
2270
|
+
#g;
|
|
2271
|
+
#y;
|
|
2272
|
+
#S;
|
|
2273
|
+
// #endregion
|
|
2274
|
+
// #region Private properties
|
|
2275
|
+
// All input sources converge here. This is the canonical config
|
|
2276
|
+
// that all rendering and logic should read from.
|
|
2277
|
+
#t = {};
|
|
2278
|
+
#O = !1;
|
|
2279
|
+
// ---------------- Batched Updates ----------------
|
|
2280
|
+
// When multiple properties are set in rapid succession (within same microtask),
|
|
2281
|
+
// we batch them into a single update to avoid redundant re-renders.
|
|
2282
|
+
#m = !1;
|
|
2283
|
+
#k = {
|
|
2284
|
+
rows: !1,
|
|
2285
|
+
columns: !1,
|
|
2286
|
+
gridConfig: !1,
|
|
2287
|
+
fitMode: !1,
|
|
2288
|
+
editMode: !1
|
|
2289
|
+
};
|
|
2290
|
+
#p = 0;
|
|
2291
|
+
#R = null;
|
|
2292
|
+
#A = !1;
|
|
2293
|
+
// Cached flag for plugin scroll handlers
|
|
2294
|
+
#D;
|
|
2295
|
+
// Cached hook to avoid closures
|
|
2296
|
+
#T = !1;
|
|
2297
|
+
#Y = Xt();
|
|
2298
|
+
#s;
|
|
2299
|
+
#b;
|
|
2300
|
+
#w;
|
|
2301
|
+
// Watches first row for size changes (CSS loading, custom renderers)
|
|
2302
|
+
#u;
|
|
2303
|
+
#h;
|
|
2304
|
+
// Handle for cancelling deferred idle work
|
|
2305
|
+
// Pooled scroll event object (reused to avoid GC pressure during scroll)
|
|
2306
|
+
#te = {
|
|
2307
|
+
scrollTop: 0,
|
|
2308
|
+
scrollLeft: 0,
|
|
2309
|
+
scrollHeight: 0,
|
|
2310
|
+
scrollWidth: 0,
|
|
2311
|
+
clientHeight: 0,
|
|
2312
|
+
clientWidth: 0
|
|
2313
|
+
};
|
|
2314
|
+
// ---------------- Plugin System ----------------
|
|
2315
|
+
#e;
|
|
2316
|
+
// ---------------- Event Listeners ----------------
|
|
2317
|
+
#x = !1;
|
|
2318
|
+
// Guard against adding duplicate component-level listeners
|
|
2319
|
+
#v;
|
|
2320
|
+
// Separate controller for DOM scroll listeners (recreated on DOM changes)
|
|
2321
|
+
// ---------------- Column State ----------------
|
|
2322
|
+
#z;
|
|
2323
|
+
#f;
|
|
2324
|
+
// ---------------- Shell State ----------------
|
|
2325
|
+
#o = Nt();
|
|
2326
|
+
#i;
|
|
2327
|
+
#L;
|
|
2328
|
+
// #endregion
|
|
2329
|
+
// #region Derived State
|
|
2330
|
+
// _rows: result of applying plugin processRows hooks
|
|
2331
|
+
_rows = [];
|
|
2332
|
+
// _baseColumns: columns before plugin transformation (analogous to #rows for row processing)
|
|
2333
|
+
// This is the source of truth for processColumns - plugins transform these
|
|
2334
|
+
#N = [];
|
|
2335
|
+
// _columns is a getter/setter that operates on effectiveConfig.columns
|
|
2336
|
+
// This ensures effectiveConfig.columns is the single source of truth for columns
|
|
2337
|
+
// _columns always contains ALL columns (including hidden)
|
|
2338
|
+
get _columns() {
|
|
2339
|
+
return this.#t.columns ?? [];
|
|
2340
|
+
}
|
|
2341
|
+
set _columns(e) {
|
|
2342
|
+
this.#t.columns = e;
|
|
2343
|
+
}
|
|
2344
|
+
// visibleColumns returns only visible columns for rendering
|
|
2345
|
+
// This is what header/row rendering should use
|
|
2346
|
+
get _visibleColumns() {
|
|
2347
|
+
return this._columns.filter((e) => !e.hidden);
|
|
2348
|
+
}
|
|
2349
|
+
// #endregion
|
|
2350
|
+
// #region Runtime State (Plugin-accessible)
|
|
2351
|
+
// DOM references
|
|
2352
|
+
_headerRowEl;
|
|
2353
|
+
_bodyEl;
|
|
2354
|
+
_rowPool = [];
|
|
2355
|
+
_resizeController;
|
|
2356
|
+
// Virtualization & scroll state
|
|
2357
|
+
_virtualization = {
|
|
2358
|
+
enabled: !0,
|
|
2359
|
+
rowHeight: 28,
|
|
2360
|
+
bypassThreshold: 24,
|
|
2361
|
+
start: 0,
|
|
2362
|
+
end: 0,
|
|
2363
|
+
container: null,
|
|
2364
|
+
viewportEl: null,
|
|
2365
|
+
totalHeightEl: null
|
|
2366
|
+
};
|
|
2367
|
+
// Focus & navigation
|
|
2368
|
+
_focusRow = 0;
|
|
2369
|
+
_focusCol = 0;
|
|
2370
|
+
// Sort state
|
|
2371
|
+
_sortState = null;
|
|
2372
|
+
// Edit state
|
|
2373
|
+
_activeEditRows = -1;
|
|
2374
|
+
_rowEditSnapshots = /* @__PURE__ */ new Map();
|
|
2375
|
+
_changedRowIndices = /* @__PURE__ */ new Set();
|
|
2376
|
+
// Layout
|
|
2377
|
+
_gridTemplate = "";
|
|
2378
|
+
// #endregion
|
|
2379
|
+
// #region Implementation Details (Internal only)
|
|
2380
|
+
__rowRenderEpoch = 0;
|
|
2381
|
+
__didInitialAutoSize = !1;
|
|
2382
|
+
__lightDomColumnsCache;
|
|
2383
|
+
__originalColumnNodes;
|
|
2384
|
+
__originalOrder = [];
|
|
2385
|
+
// Cached DOM refs for hot path (refreshVirtualWindow) - avoid querySelector per scroll
|
|
2386
|
+
__rowsBodyEl = null;
|
|
2387
|
+
__scrollAreaEl = null;
|
|
2388
|
+
__footerEl = null;
|
|
2389
|
+
// #endregion
|
|
2390
|
+
// #region Public API Props (getters/setters)
|
|
2391
|
+
// Getters return the EFFECTIVE value (after merging), not the raw input.
|
|
2392
|
+
// This is what consumers and plugins need - the current resolved state.
|
|
2393
|
+
// Setters update input properties which trigger re-merge into effectiveConfig.
|
|
2394
|
+
get rows() {
|
|
2395
|
+
return this._rows;
|
|
2396
|
+
}
|
|
2397
|
+
set rows(e) {
|
|
2398
|
+
const o = this.#r;
|
|
2399
|
+
this.#r = e, o !== e && this.#C("rows");
|
|
2400
|
+
}
|
|
2401
|
+
/**
|
|
2402
|
+
* Get the original unfiltered/unprocessed rows.
|
|
2403
|
+
* Use this when you need access to all source data regardless of active filters.
|
|
2404
|
+
*/
|
|
2405
|
+
get sourceRows() {
|
|
2406
|
+
return this.#r;
|
|
2407
|
+
}
|
|
2408
|
+
get columns() {
|
|
2409
|
+
return [...this._columns];
|
|
2410
|
+
}
|
|
2411
|
+
set columns(e) {
|
|
2412
|
+
const o = this.#c;
|
|
2413
|
+
this.#c = e, o !== e && this.#C("columns");
|
|
2414
|
+
}
|
|
2415
|
+
get gridConfig() {
|
|
2416
|
+
return this.#t;
|
|
2417
|
+
}
|
|
2418
|
+
set gridConfig(e) {
|
|
2419
|
+
const o = this.#g;
|
|
2420
|
+
this.#g = e, o !== e && (this.__lightDomColumnsCache = void 0, this.#C("gridConfig"));
|
|
2421
|
+
}
|
|
2422
|
+
get fitMode() {
|
|
2423
|
+
return this.#t.fitMode ?? "stretch";
|
|
2424
|
+
}
|
|
2425
|
+
set fitMode(e) {
|
|
2426
|
+
const o = this.#y;
|
|
2427
|
+
this.#y = e, o !== e && this.#C("fitMode");
|
|
2428
|
+
}
|
|
2429
|
+
get editOn() {
|
|
2430
|
+
return this.#t.editOn;
|
|
2431
|
+
}
|
|
2432
|
+
set editOn(e) {
|
|
2433
|
+
const o = this.#S;
|
|
2434
|
+
this.#S = e, o !== e && this.#C("editMode");
|
|
2435
|
+
}
|
|
2436
|
+
/**
|
|
2437
|
+
* Effective config accessor for internal modules and plugins.
|
|
2438
|
+
* Returns the merged config (single source of truth) before plugin processing.
|
|
2439
|
+
* Use this when you need the raw merged config (e.g., for column definitions including hidden).
|
|
2440
|
+
* @internal Plugin API
|
|
2441
|
+
*/
|
|
2442
|
+
get effectiveConfig() {
|
|
2443
|
+
return this.#t;
|
|
2444
|
+
}
|
|
2445
|
+
/**
|
|
2446
|
+
* Get the disconnect signal for event listener cleanup.
|
|
2447
|
+
* This signal is aborted when the grid disconnects from the DOM.
|
|
2448
|
+
* Plugins and internal code can use this for automatic listener cleanup.
|
|
2449
|
+
* @internal Plugin API
|
|
2450
|
+
* @example
|
|
2451
|
+
* element.addEventListener('click', handler, { signal: this.grid.disconnectSignal });
|
|
2452
|
+
*/
|
|
2453
|
+
get disconnectSignal() {
|
|
2454
|
+
return this.#s || (this.#s = new AbortController()), this.#s.signal;
|
|
2455
|
+
}
|
|
2456
|
+
// #endregion
|
|
2457
|
+
constructor() {
|
|
2458
|
+
super(), this.#n = this.attachShadow({ mode: "open" }), this.#oe(), this.#U = new Promise((e) => this.#X = e), this.#i = Ft(this.#o, {
|
|
2459
|
+
getShadow: () => this.#n,
|
|
2460
|
+
getShellConfig: () => this.#t?.shell,
|
|
2461
|
+
getAccordionIcons: () => ({
|
|
2462
|
+
expand: this.#t?.icons?.expand ?? O.expand,
|
|
2463
|
+
collapse: this.#t?.icons?.collapse ?? O.collapse
|
|
2464
|
+
}),
|
|
2465
|
+
emit: (e, o) => this.#d(e, o),
|
|
2466
|
+
refreshShellHeader: () => this.refreshShellHeader()
|
|
2467
|
+
});
|
|
2468
|
+
}
|
|
2469
|
+
async #oe() {
|
|
2470
|
+
const e = new CSSStyleSheet();
|
|
2471
|
+
if (de.length > 0) {
|
|
2472
|
+
e.replaceSync(de), this.#n.adoptedStyleSheets = [e];
|
|
2473
|
+
return;
|
|
2474
|
+
}
|
|
2475
|
+
await new Promise((o) => setTimeout(o, 50));
|
|
2476
|
+
try {
|
|
2477
|
+
let o = "";
|
|
2478
|
+
for (const n of Array.from(document.styleSheets))
|
|
2479
|
+
try {
|
|
2480
|
+
const l = Array.from(n.cssRules || []).map((r) => r.cssText).join(`
|
|
2481
|
+
`);
|
|
2482
|
+
if (l.includes(".tbw-grid-root") && l.includes(":host")) {
|
|
2483
|
+
o = l;
|
|
2484
|
+
break;
|
|
2485
|
+
}
|
|
2486
|
+
} catch {
|
|
2487
|
+
continue;
|
|
2488
|
+
}
|
|
2489
|
+
o ? (e.replaceSync(o), this.#n.adoptedStyleSheets = [e]) : (typeof process > "u" || process.env?.NODE_ENV !== "test") && console.warn(
|
|
2490
|
+
"[tbw-grid] Could not find grid.css in document.styleSheets. Grid styling will not work.",
|
|
2491
|
+
"Available stylesheets:",
|
|
2492
|
+
Array.from(document.styleSheets).map((n) => n.href || "(inline)")
|
|
2493
|
+
);
|
|
2494
|
+
} catch (o) {
|
|
2495
|
+
console.warn("[tbw-grid] Failed to extract grid.css from document stylesheets:", o);
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
// ---------------- Plugin System ----------------
|
|
2499
|
+
/**
|
|
2500
|
+
* Get a plugin instance by its class.
|
|
2501
|
+
* Used by plugins for inter-plugin communication.
|
|
2502
|
+
* @internal Plugin API
|
|
2503
|
+
*/
|
|
2504
|
+
getPlugin(e) {
|
|
2505
|
+
return this.#e?.getPlugin(e);
|
|
2506
|
+
}
|
|
2507
|
+
/**
|
|
2508
|
+
* Get a plugin instance by its name.
|
|
2509
|
+
* Used for loose coupling between plugins (avoids static imports).
|
|
2510
|
+
* @internal Plugin API
|
|
2511
|
+
*/
|
|
2512
|
+
getPluginByName(e) {
|
|
2513
|
+
return this.#e?.getPluginByName(e);
|
|
2514
|
+
}
|
|
2515
|
+
/**
|
|
2516
|
+
* Request a full re-render of the grid.
|
|
2517
|
+
* Called by plugins when they need the grid to update.
|
|
2518
|
+
* Note: This does NOT reset plugin state - just re-processes rows/columns and renders.
|
|
2519
|
+
* @internal Plugin API
|
|
2520
|
+
*/
|
|
2521
|
+
requestRender() {
|
|
2522
|
+
this.#H(), this.#P(), q(this), z(this), this.refreshVirtualWindow(!0);
|
|
2523
|
+
}
|
|
2524
|
+
/**
|
|
2525
|
+
* Update the grid's column template CSS.
|
|
2526
|
+
* Called by resize controller during column resize operations.
|
|
2527
|
+
* @internal
|
|
2528
|
+
*/
|
|
2529
|
+
updateTemplate() {
|
|
2530
|
+
z(this);
|
|
2531
|
+
}
|
|
2532
|
+
/**
|
|
2533
|
+
* Request a lightweight style update without rebuilding DOM.
|
|
2534
|
+
* Called by plugins when they only need to update CSS classes/styles.
|
|
2535
|
+
* This runs all plugin afterRender hooks without rebuilding row/column DOM.
|
|
2536
|
+
* @internal Plugin API
|
|
2537
|
+
*/
|
|
2538
|
+
requestAfterRender() {
|
|
2539
|
+
this.#e?.afterRender();
|
|
2540
|
+
}
|
|
2541
|
+
/**
|
|
2542
|
+
* Initialize plugin system with instances from config.
|
|
2543
|
+
* Plugins are class instances passed in gridConfig.plugins[].
|
|
2544
|
+
*/
|
|
2545
|
+
#j() {
|
|
2546
|
+
this.#e = new eo(this);
|
|
2547
|
+
const e = this.#t?.plugins, o = Array.isArray(e) ? e : [];
|
|
2548
|
+
this.#e.attachAll(o);
|
|
2549
|
+
}
|
|
2550
|
+
/**
|
|
2551
|
+
* Inject all plugin styles into the shadow DOM.
|
|
2552
|
+
* Must be called after #render() since innerHTML wipes existing content.
|
|
2553
|
+
*/
|
|
2554
|
+
#K() {
|
|
2555
|
+
const e = this.#e?.getAllStyles() ?? "";
|
|
2556
|
+
if (e) {
|
|
2557
|
+
const o = document.createElement("style");
|
|
2558
|
+
o.setAttribute("data-plugin", "all"), o.textContent = e, this.#n.appendChild(o);
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
/**
|
|
2562
|
+
* Update plugins when grid config changes.
|
|
2563
|
+
* With class-based plugins, we need to detach old and attach new.
|
|
2564
|
+
*/
|
|
2565
|
+
#Z() {
|
|
2566
|
+
this.#e && this.#e.detachAll(), this.#j(), this.#K(), this.#J(), this.#A = this.#e?.getAll().some((e) => e.onScroll) ?? !1;
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* Clean up plugin states when grid disconnects.
|
|
2570
|
+
*/
|
|
2571
|
+
#ne() {
|
|
2572
|
+
this.#e?.detachAll();
|
|
2573
|
+
}
|
|
2574
|
+
/**
|
|
2575
|
+
* Collect tool panels and header content from all plugins.
|
|
2576
|
+
* Called after plugins are attached but before render.
|
|
2577
|
+
*/
|
|
2578
|
+
#J() {
|
|
2579
|
+
if (!this.#e) return;
|
|
2580
|
+
const e = this.#e.getToolPanels();
|
|
2581
|
+
for (const { panel: n } of e)
|
|
2582
|
+
this.#o.toolPanels.has(n.id) || this.#o.toolPanels.set(n.id, n);
|
|
2583
|
+
const o = this.#e.getHeaderContents();
|
|
2584
|
+
for (const { content: n } of o)
|
|
2585
|
+
this.#o.headerContents.has(n.id) || this.#o.headerContents.set(n.id, n);
|
|
2586
|
+
}
|
|
2587
|
+
/**
|
|
2588
|
+
* Gets a renderer factory for tool panels from registered framework adapters.
|
|
2589
|
+
* Returns a factory function that tries each adapter in order until one handles the element.
|
|
2590
|
+
*/
|
|
2591
|
+
#_() {
|
|
2592
|
+
const e = N.getAdapters();
|
|
2593
|
+
if (e.length === 0 && !this.__frameworkAdapter) return;
|
|
2594
|
+
const o = this.__frameworkAdapter;
|
|
2595
|
+
return (n) => {
|
|
2596
|
+
if (o?.createToolPanelRenderer) {
|
|
2597
|
+
const i = o.createToolPanelRenderer(n);
|
|
2598
|
+
if (i) return i;
|
|
2599
|
+
}
|
|
2600
|
+
for (const i of e)
|
|
2601
|
+
if (i.createToolPanelRenderer) {
|
|
2602
|
+
const l = i.createToolPanelRenderer(n);
|
|
2603
|
+
if (l) return l;
|
|
2604
|
+
}
|
|
2605
|
+
};
|
|
2606
|
+
}
|
|
2607
|
+
// ---------------- Lifecycle ----------------
|
|
2608
|
+
connectedCallback() {
|
|
2609
|
+
this.hasAttribute("tabindex") || (this.tabIndex = 0), this.hasAttribute("version") || this.setAttribute("version", N.version), this._rows = Array.isArray(this.#r) ? [...this.#r] : [], this.#s && (this.#s.abort(), this.#x = !1), this.#s = new AbortController(), this.#h && (_e(this.#h), this.#h = void 0), V(this, this.#o), F(this, this.#o, this.#_()), this.#l(), this.#j(), this.#J(), this.#M || (this.#F(), this.#K(), this.#M = !0), this.#B(), this.#h = Ot(
|
|
2610
|
+
() => {
|
|
2611
|
+
this.#ve();
|
|
2612
|
+
},
|
|
2613
|
+
{ timeout: 100 }
|
|
2614
|
+
);
|
|
2615
|
+
}
|
|
2616
|
+
disconnectedCallback() {
|
|
2617
|
+
this.#h && (_e(this.#h), this.#h = void 0), this.#ne(), Vt(this.#o), this.#i.setInitialized(!1), this.#L?.(), this.#L = void 0, We(this.#Y), this.#s && (this.#s.abort(), this.#s = void 0), this.#v?.abort(), this.#v = void 0, this.#x = !1, this._resizeController && this._resizeController.dispose(), this.#b && (this.#b.disconnect(), this.#b = void 0), this.#w && (this.#w.disconnect(), this.#w = void 0, this.#I = !1), this.#u && (this.#u.disconnect(), this.#u = void 0), Z(this), this._rowEditSnapshots.clear(), this._changedRowIndices.clear(), this.#E.clear();
|
|
2618
|
+
for (const e of this._rowPool)
|
|
2619
|
+
e.remove();
|
|
2620
|
+
this._rowPool.length = 0, this.__rowsBodyEl = null, this.__scrollAreaEl = null, this.__footerEl = null, this.#O = !1;
|
|
2621
|
+
}
|
|
2622
|
+
/**
|
|
2623
|
+
* Handle HTML attribute changes.
|
|
2624
|
+
* Only processes attribute values when SET (non-null).
|
|
2625
|
+
* Removing an attribute does NOT clear JS-set properties.
|
|
2626
|
+
*/
|
|
2627
|
+
attributeChangedCallback(e, o, n) {
|
|
2628
|
+
if (o === n || !n || n === "null" || n === "undefined") return;
|
|
2629
|
+
const l = {
|
|
2630
|
+
rows: "rows",
|
|
2631
|
+
columns: "columns",
|
|
2632
|
+
"grid-config": "gridConfig",
|
|
2633
|
+
"fit-mode": "fitMode",
|
|
2634
|
+
"edit-on": "editOn"
|
|
2635
|
+
}[e];
|
|
2636
|
+
if (l)
|
|
2637
|
+
if (e === "rows" || e === "columns" || e === "grid-config")
|
|
2638
|
+
try {
|
|
2639
|
+
this[l] = JSON.parse(n);
|
|
2640
|
+
} catch {
|
|
2641
|
+
console.warn(`[tbw-grid] Invalid JSON for '${e}' attribute:`, n);
|
|
2642
|
+
}
|
|
2643
|
+
else
|
|
2644
|
+
this[l] = n;
|
|
2645
|
+
}
|
|
2646
|
+
#B() {
|
|
2647
|
+
const o = this.#n.querySelector(".tbw-grid-content") ?? this.#n.querySelector(".tbw-grid-root");
|
|
2648
|
+
if (this._headerRowEl = o?.querySelector(".header-row"), this._virtualization.totalHeightEl = o?.querySelector(".faux-vscroll-spacer"), this._virtualization.viewportEl = o?.querySelector(".rows-viewport"), this._bodyEl = o?.querySelector(".rows"), this.__rowsBodyEl = o?.querySelector(".rows-body"), this.__scrollAreaEl = o?.querySelector(".tbw-scroll-area"), this.__footerEl = o?.querySelector(".tbw-footer"), this.#i.isInitialized) {
|
|
2649
|
+
qe(this.#n, this.#o), qt(this.#n, this.#t?.shell, this.#o);
|
|
2650
|
+
const l = this.#t?.shell?.toolPanel?.defaultOpen;
|
|
2651
|
+
l && this.#o.toolPanels.has(l) && (this.openToolPanel(), this.#o.expandedSections.add(l));
|
|
2652
|
+
}
|
|
2653
|
+
if (this.setAttribute("data-upgraded", ""), this.#O = !0, this._resizeController = kt(this), this.#a(), this.#ie(o), this.#x)
|
|
2654
|
+
return;
|
|
2655
|
+
this.#x = !0;
|
|
2656
|
+
const n = this.disconnectSignal;
|
|
2657
|
+
this.addEventListener("keydown", (l) => ft(this, l), { signal: n }), document.addEventListener(
|
|
2658
|
+
"keydown",
|
|
2659
|
+
(l) => {
|
|
2660
|
+
l.key === "Escape" && this._activeEditRows !== -1 && D(this, this._activeEditRows, !0);
|
|
2661
|
+
},
|
|
2662
|
+
{ capture: !0, signal: n }
|
|
2663
|
+
), document.addEventListener(
|
|
2664
|
+
"mousedown",
|
|
2665
|
+
(l) => {
|
|
2666
|
+
if (this._activeEditRows === -1) return;
|
|
2667
|
+
const r = this.findRenderedRowElement(this._activeEditRows);
|
|
2668
|
+
!r || (l.composedPath && l.composedPath() || []).includes(r) || D(this, this._activeEditRows, !1);
|
|
2669
|
+
},
|
|
2670
|
+
{ signal: n }
|
|
2671
|
+
), this.#n.addEventListener("mousedown", (l) => this.#be(l), { signal: n }), document.addEventListener("mousemove", (l) => this.#we(l), { signal: n }), document.addEventListener("mouseup", (l) => this.#ge(l), { signal: n });
|
|
2672
|
+
const i = this.#t.rowHeight;
|
|
2673
|
+
i && i > 0 ? this._virtualization.rowHeight = i : requestAnimationFrame(() => this.#Q()), queueMicrotask(() => this.#re()), requestAnimationFrame(() => requestAnimationFrame(() => this.#X?.()));
|
|
2674
|
+
}
|
|
2675
|
+
/**
|
|
2676
|
+
* Measure actual row height from DOM.
|
|
2677
|
+
* Finds the tallest cell to account for custom renderers that may push height.
|
|
2678
|
+
*/
|
|
2679
|
+
#Q() {
|
|
2680
|
+
const e = this._bodyEl?.querySelector(".data-grid-row");
|
|
2681
|
+
if (!e) return;
|
|
2682
|
+
const o = e.querySelectorAll(".cell");
|
|
2683
|
+
let n = 0;
|
|
2684
|
+
o.forEach((r) => {
|
|
2685
|
+
const s = r.offsetHeight;
|
|
2686
|
+
s > n && (n = s);
|
|
2687
|
+
});
|
|
2688
|
+
const i = e.getBoundingClientRect(), l = Math.max(i.height, n);
|
|
2689
|
+
l > 0 && l !== this._virtualization.rowHeight && (this._virtualization.rowHeight = l, this.refreshVirtualWindow(!0));
|
|
2690
|
+
}
|
|
2691
|
+
/**
|
|
2692
|
+
* Set up scroll-related event listeners on DOM elements.
|
|
2693
|
+
* These need to be re-attached when the DOM is recreated (e.g., shell toggle).
|
|
2694
|
+
* Uses a separate AbortController that is recreated each time.
|
|
2695
|
+
*/
|
|
2696
|
+
#ie(e) {
|
|
2697
|
+
this.#v?.abort(), this.#v = new AbortController();
|
|
2698
|
+
const o = this.#v.signal, n = e?.querySelector(".faux-vscroll"), i = e?.querySelector(".rows");
|
|
2699
|
+
if (this._virtualization.container = n ?? this, this.#A = this.#e?.getAll().some((l) => l.onScroll) ?? !1, n && i) {
|
|
2700
|
+
n.addEventListener(
|
|
2701
|
+
"scroll",
|
|
2702
|
+
() => {
|
|
2703
|
+
if (!this._virtualization.enabled && !this.#A) return;
|
|
2704
|
+
const s = n.scrollTop, a = this._virtualization.rowHeight;
|
|
2705
|
+
if (this._rows.length <= this._virtualization.bypassThreshold)
|
|
2706
|
+
i.style.transform = `translateY(${-s}px)`;
|
|
2707
|
+
else {
|
|
2708
|
+
const c = Math.floor(s / a), h = c - c % 2, d = -(s - h * a);
|
|
2709
|
+
i.style.transform = `translateY(${d}px)`;
|
|
2710
|
+
}
|
|
2711
|
+
this.#R = s, this.#p || (this.#p = requestAnimationFrame(() => {
|
|
2712
|
+
this.#p = 0, this.#R !== null && (this.#pe(this.#R), this.#R = null);
|
|
2713
|
+
}));
|
|
2714
|
+
},
|
|
2715
|
+
{ passive: !0, signal: o }
|
|
2716
|
+
);
|
|
2717
|
+
const l = this.#n.querySelector(".tbw-grid-content"), r = this.#n.querySelector(".tbw-scroll-area");
|
|
2718
|
+
l && (l.addEventListener(
|
|
2719
|
+
"wheel",
|
|
2720
|
+
(s) => {
|
|
2721
|
+
const a = s.shiftKey || Math.abs(s.deltaX) > Math.abs(s.deltaY);
|
|
2722
|
+
if (a && r) {
|
|
2723
|
+
const c = s.shiftKey ? s.deltaY : s.deltaX, { scrollLeft: h, scrollWidth: d, clientWidth: u } = r;
|
|
2724
|
+
(c > 0 && h < d - u || c < 0 && h > 0) && (s.preventDefault(), r.scrollLeft += c);
|
|
2725
|
+
} else if (!a) {
|
|
2726
|
+
const { scrollTop: c, scrollHeight: h, clientHeight: d } = n;
|
|
2727
|
+
(s.deltaY > 0 && c < h - d || s.deltaY < 0 && c > 0) && (s.preventDefault(), n.scrollTop += s.deltaY);
|
|
2728
|
+
}
|
|
2729
|
+
},
|
|
2730
|
+
{ passive: !1, signal: o }
|
|
2731
|
+
), Qt(l, this.#Y, { fauxScrollbar: n, scrollArea: r }, o));
|
|
2732
|
+
}
|
|
2733
|
+
this._bodyEl && Lt(this, this._bodyEl, o), this.#b?.disconnect(), this._virtualization.viewportEl && (this.#b = new ResizeObserver(() => {
|
|
2734
|
+
this.#p || (this.#p = requestAnimationFrame(() => {
|
|
2735
|
+
this.#p = 0, this.refreshVirtualWindow(!0), k(this);
|
|
2736
|
+
}));
|
|
2737
|
+
}), this.#b.observe(this._virtualization.viewportEl)), this._virtualization.enabled && requestAnimationFrame(() => {
|
|
2738
|
+
this.refreshVirtualWindow(!0), this.#le();
|
|
2739
|
+
});
|
|
2740
|
+
}
|
|
2741
|
+
/**
|
|
2742
|
+
* Set up ResizeObserver on first row's cells to detect height changes.
|
|
2743
|
+
* Called after rows are rendered to observe the actual content cells.
|
|
2744
|
+
* Handles dynamic CSS loading, lazy images, font loading, etc.
|
|
2745
|
+
*/
|
|
2746
|
+
#I = !1;
|
|
2747
|
+
// Only set up once per lifecycle
|
|
2748
|
+
#le() {
|
|
2749
|
+
if (this.#I) return;
|
|
2750
|
+
const e = this._bodyEl?.querySelector(".data-grid-row");
|
|
2751
|
+
if (!e) return;
|
|
2752
|
+
this.#I = !0, this.#w?.disconnect();
|
|
2753
|
+
const o = e.querySelectorAll(".cell");
|
|
2754
|
+
o.length > 0 && (this.#w = new ResizeObserver(() => {
|
|
2755
|
+
this.#Q();
|
|
2756
|
+
}), o.forEach((n) => this.#w.observe(n)));
|
|
2757
|
+
}
|
|
2758
|
+
// ---------------- Event Emitters ----------------
|
|
2759
|
+
#d(e, o) {
|
|
2760
|
+
this.dispatchEvent(new CustomEvent(e, { detail: o, bubbles: !0, composed: !0 }));
|
|
2761
|
+
}
|
|
2762
|
+
_emitCellCommit(e) {
|
|
2763
|
+
this.#d("cell-commit", e);
|
|
2764
|
+
}
|
|
2765
|
+
_emitRowCommit(e) {
|
|
2766
|
+
this.#d("row-commit", e);
|
|
2767
|
+
}
|
|
2768
|
+
_emitSortChange(e) {
|
|
2769
|
+
this.#d("sort-change", e);
|
|
2770
|
+
}
|
|
2771
|
+
_emitColumnResize(e) {
|
|
2772
|
+
this.#d("column-resize", e);
|
|
2773
|
+
}
|
|
2774
|
+
_emitActivateCell(e) {
|
|
2775
|
+
this.#d("activate-cell", e);
|
|
2776
|
+
}
|
|
2777
|
+
/** Update ARIA selection attributes on rendered rows/cells */
|
|
2778
|
+
#re() {
|
|
2779
|
+
this._bodyEl?.querySelectorAll(".data-grid-row")?.forEach((o, n) => {
|
|
2780
|
+
const i = n === this._focusRow;
|
|
2781
|
+
o.setAttribute("aria-selected", String(i)), o.querySelectorAll(".cell").forEach((l, r) => {
|
|
2782
|
+
l.setAttribute("aria-selected", String(i && r === this._focusCol));
|
|
2783
|
+
});
|
|
2784
|
+
});
|
|
2785
|
+
}
|
|
2786
|
+
// ---------------- Batched Update System ----------------
|
|
2787
|
+
// Allows multiple property changes within the same microtask to be coalesced
|
|
2788
|
+
// into a single update cycle, dramatically reducing redundant renders.
|
|
2789
|
+
/**
|
|
2790
|
+
* Queue an update for a specific property type.
|
|
2791
|
+
* All updates queued within the same microtask are batched together.
|
|
2792
|
+
*/
|
|
2793
|
+
#C(e) {
|
|
2794
|
+
this.#k[e] = !0, !this.#m && (this.#m = !0, queueMicrotask(() => this.#se()));
|
|
2795
|
+
}
|
|
2796
|
+
/**
|
|
2797
|
+
* Process all pending updates in optimal order.
|
|
2798
|
+
* Priority: gridConfig first (may affect all), then columns, rows, fitMode, editMode
|
|
2799
|
+
*/
|
|
2800
|
+
#se() {
|
|
2801
|
+
if (!this.#m || !this.#O) {
|
|
2802
|
+
this.#m = !1;
|
|
2803
|
+
return;
|
|
2804
|
+
}
|
|
2805
|
+
const e = this.#k;
|
|
2806
|
+
if (this.#m = !1, this.#k = {
|
|
2807
|
+
rows: !1,
|
|
2808
|
+
columns: !1,
|
|
2809
|
+
gridConfig: !1,
|
|
2810
|
+
fitMode: !1,
|
|
2811
|
+
editMode: !1
|
|
2812
|
+
}, e.gridConfig) {
|
|
2813
|
+
this.#he();
|
|
2814
|
+
return;
|
|
2815
|
+
}
|
|
2816
|
+
e.columns && this.#ce(), e.rows && this.#ae(), e.fitMode && this.#de(), e.editMode && this.#ue();
|
|
2817
|
+
}
|
|
2818
|
+
// Individual update applicators - these do the actual work
|
|
2819
|
+
#ae() {
|
|
2820
|
+
this._rows = Array.isArray(this.#r) ? [...this.#r] : [], this.#H(), this._columns.length > 0 || Array.isArray(this.#t?.columns) && this.#t.columns.length > 0 || Array.isArray(this.#c) && this.#c.length > 0 ? (this.#P(), this.refreshVirtualWindow(!0)) : this.#a();
|
|
2821
|
+
}
|
|
2822
|
+
#ce() {
|
|
2823
|
+
Z(this), this.#l(), this.#a();
|
|
2824
|
+
}
|
|
2825
|
+
#de() {
|
|
2826
|
+
this.#l(), this.#t.fitMode === "fixed" ? (this.__didInitialAutoSize = !1, be(this)) : (this._columns.forEach((o) => {
|
|
2827
|
+
!o.__userResized && o.__autoSized && delete o.width;
|
|
2828
|
+
}), z(this));
|
|
2829
|
+
}
|
|
2830
|
+
#ue() {
|
|
2831
|
+
this.#l(), this._rowPool.length = 0, this._bodyEl && (this._bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.refreshVirtualWindow(!0);
|
|
2832
|
+
}
|
|
2833
|
+
#he() {
|
|
2834
|
+
const e = !!this.#n.querySelector(".has-shell");
|
|
2835
|
+
se(this.#t, this.#o), pe(this), this.#l(), this.#Z();
|
|
2836
|
+
const o = se(this.#t, this.#o);
|
|
2837
|
+
if (e !== o || !e && o) {
|
|
2838
|
+
this.#F(), this.#B();
|
|
2839
|
+
return;
|
|
2840
|
+
}
|
|
2841
|
+
this.#H(), this.#P(), q(this), z(this), this.refreshVirtualWindow(!0);
|
|
2842
|
+
}
|
|
2843
|
+
// NOTE: Legacy watch handlers have been replaced by the batched update system.
|
|
2844
|
+
// The #queueUpdate() method schedules updates which are processed by #flushPendingUpdates()
|
|
2845
|
+
// and individual #apply*Update() methods. This coalesces rapid property changes
|
|
2846
|
+
// (e.g., setting rows, columns, gridConfig in quick succession) into a single update cycle.
|
|
2847
|
+
#P() {
|
|
2848
|
+
if (this.#e) {
|
|
2849
|
+
const e = this.#N.length > 0 ? this.#N : this._columns, o = e.filter((l) => !l.hidden), n = e.filter((l) => l.hidden), i = this.#e.processColumns([...o]);
|
|
2850
|
+
if (i !== o) {
|
|
2851
|
+
const l = new Map(i.map((s, a) => [s.field, { col: s, order: a }]));
|
|
2852
|
+
if (!o.some((s) => l.has(s.field)) && i.length > 0)
|
|
2853
|
+
this._columns = [...i, ...n];
|
|
2854
|
+
else {
|
|
2855
|
+
const s = e.map((a) => {
|
|
2856
|
+
if (a.hidden) return a;
|
|
2857
|
+
const c = l.get(a.field);
|
|
2858
|
+
return c ? c.col : a;
|
|
2859
|
+
});
|
|
2860
|
+
this._columns = s;
|
|
2861
|
+
}
|
|
2862
|
+
} else
|
|
2863
|
+
this._columns = [...e];
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
/** Recompute row model via plugin hooks. */
|
|
2867
|
+
#H() {
|
|
2868
|
+
Z(this);
|
|
2869
|
+
const e = Array.isArray(this.#r) ? [...this.#r] : [], o = this.#e?.processRows(e) ?? e;
|
|
2870
|
+
this._rows = o;
|
|
2871
|
+
}
|
|
2872
|
+
/**
|
|
2873
|
+
* Build the canonical effective configuration by merging all input sources.
|
|
2874
|
+
*
|
|
2875
|
+
* This is the **single source of truth** for the grid's configuration.
|
|
2876
|
+
* All inputs (gridConfig, light DOM, individual props) converge here.
|
|
2877
|
+
*
|
|
2878
|
+
* **Precedence (lowest → highest):**
|
|
2879
|
+
* 1. `gridConfig` property - base config object
|
|
2880
|
+
* 2. Light DOM `<tbw-grid-column>` elements - declarative columns
|
|
2881
|
+
* 3. `columns` property - programmatic columns override
|
|
2882
|
+
* 4. Inferred columns - auto-detected from row data
|
|
2883
|
+
* 5. Individual props (`fitMode`, `editOn`) - convenience overrides
|
|
2884
|
+
*
|
|
2885
|
+
* After this method runs:
|
|
2886
|
+
* - `#effectiveConfig` contains the merged result
|
|
2887
|
+
* - `_columns` is NOT set here (done by #getColumnConfiguration + #processColumns)
|
|
2888
|
+
* - Plugins receive config via their attach() method
|
|
2889
|
+
*/
|
|
2890
|
+
#l() {
|
|
2891
|
+
const e = this.#g ? { ...this.#g } : {};
|
|
2892
|
+
let o = Array.isArray(e.columns) ? [...e.columns] : [];
|
|
2893
|
+
const n = (this.__lightDomColumnsCache || []).map((i) => ({
|
|
2894
|
+
...i
|
|
2895
|
+
}));
|
|
2896
|
+
if (n.length) {
|
|
2897
|
+
const i = {};
|
|
2898
|
+
o.forEach((l) => i[l.field] = l), n.forEach((l) => {
|
|
2899
|
+
const r = i[l.field];
|
|
2900
|
+
r ? (l.header && !r.header && (r.header = l.header), l.type && !r.type && (r.type = l.type), r.sortable = r.sortable || l.sortable, l.resizable && (r.resizable = !0), l.editable && (r.editable = !0)) : (o.push(l), i[l.field] = l);
|
|
2901
|
+
});
|
|
2902
|
+
}
|
|
2903
|
+
if (this.#c && this.#c.length && (o = [...this.#c]), (!o || o.length === 0) && this._rows.length && (o = Le(this._rows).columns), o.length) {
|
|
2904
|
+
o.forEach((r) => {
|
|
2905
|
+
r.sortable === void 0 && (r.sortable = !0), r.resizable === void 0 && (r.resizable = !0);
|
|
2906
|
+
const s = r;
|
|
2907
|
+
s.__originalWidth === void 0 && typeof r.width == "number" && (s.__originalWidth = r.width);
|
|
2908
|
+
});
|
|
2909
|
+
const i = this.#t.columns;
|
|
2910
|
+
i?.some((r) => r.__compiledView || r.__compiledEditor) ? e.columns = i : e.columns = o;
|
|
2911
|
+
} else {
|
|
2912
|
+
const i = this.#t.columns;
|
|
2913
|
+
i?.some((l) => l.__compiledView || l.__compiledEditor) && (e.columns = i);
|
|
2914
|
+
}
|
|
2915
|
+
this.#y && (e.fitMode = this.#y), e.fitMode || (e.fitMode = "stretch"), this.#S && (e.editOn = this.#S), this.#o.lightDomTitle && (e.shell || (e.shell = {}), e.shell.header || (e.shell.header = {}), e.shell.header.title || (e.shell.header.title = this.#o.lightDomTitle)), e.rowHeight && e.rowHeight > 0 && (this._virtualization.rowHeight = e.rowHeight), e.columnState && !this.#f && (this.#f = e.columnState), this.#t = e, e.fitMode === "fixed" && this._columns.forEach((i) => {
|
|
2916
|
+
i.width == null && (i.width = 80);
|
|
2917
|
+
}), this.#fe();
|
|
2918
|
+
}
|
|
2919
|
+
/**
|
|
2920
|
+
* Apply animation configuration to CSS custom properties on the host element.
|
|
2921
|
+
* This makes the grid's animation settings available to plugins via CSS variables.
|
|
2922
|
+
*/
|
|
2923
|
+
#fe() {
|
|
2924
|
+
const e = {
|
|
2925
|
+
...Je,
|
|
2926
|
+
...this.#t.animation
|
|
2927
|
+
}, o = e.mode ?? "reduced-motion";
|
|
2928
|
+
let n = 1;
|
|
2929
|
+
o === !1 || o === "off" ? n = 0 : (o === !0 || o === "on") && (n = 1), this.style.setProperty("--tbw-animation-duration", `${e.duration}ms`), this.style.setProperty("--tbw-animation-easing", e.easing ?? "ease-out"), this.style.setProperty("--tbw-animation-enabled", String(n)), this.dataset.animationMode = typeof o == "boolean" ? o ? "on" : "off" : o;
|
|
2930
|
+
}
|
|
2931
|
+
// ---------------- Delegate Wrappers ----------------
|
|
2932
|
+
#q(e, o, n = this.__rowRenderEpoch) {
|
|
2933
|
+
this.#D || (this.#D = (i, l, r) => this.#e?.renderRow(i, l, r) ?? !1), mt(this, e, o, n, this.#D);
|
|
2934
|
+
}
|
|
2935
|
+
// ---------------- Core Helpers ----------------
|
|
2936
|
+
#a() {
|
|
2937
|
+
if (!this.isConnected || !this._headerRowEl || !this._bodyEl)
|
|
2938
|
+
return;
|
|
2939
|
+
const e = this.#g?.columns || this.#c || [];
|
|
2940
|
+
if (e.length) {
|
|
2941
|
+
const n = new Map(this._columns.filter((l) => l.hidden).map((l) => [l.field, !0])), i = e.map((l) => ({
|
|
2942
|
+
...l,
|
|
2943
|
+
hidden: n.get(l.field) ?? l.hidden
|
|
2944
|
+
}));
|
|
2945
|
+
this._columns = i;
|
|
2946
|
+
}
|
|
2947
|
+
if (pe(this), this.#l(), this.#Z(), this.#N = [...this._columns], this.#H(), this.#P(), this.#f) {
|
|
2948
|
+
const n = this.#f;
|
|
2949
|
+
this.#f = void 0, this.#ee(n);
|
|
2950
|
+
}
|
|
2951
|
+
q(this), z(this), this.refreshVirtualWindow(!0), this.#t.fitMode === "fixed" && !this.__didInitialAutoSize && requestAnimationFrame(() => be(this)), this._bodyEl && (this._bodyEl.style.display = "", this._bodyEl.style.gridTemplateColumns = ""), queueMicrotask(() => this.#e?.afterRender());
|
|
2952
|
+
}
|
|
2953
|
+
/** Internal method to apply column state without triggering setup loop */
|
|
2954
|
+
#ee(e) {
|
|
2955
|
+
const o = this.#t.columns ?? [], n = this.#e?.getAll() ?? [];
|
|
2956
|
+
Fe(this, e, o, n);
|
|
2957
|
+
for (const i of e.columns) {
|
|
2958
|
+
const l = o.find((r) => r.field === i.field);
|
|
2959
|
+
l && (l.hidden = !i.visible);
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
#pe(e) {
|
|
2963
|
+
if (this.refreshVirtualWindow(!1), this.#e?.onScrollRender(), this.#A) {
|
|
2964
|
+
const o = this._virtualization.container, n = this.#te;
|
|
2965
|
+
n.scrollTop = e, n.scrollLeft = o?.scrollLeft ?? 0, n.scrollHeight = o?.scrollHeight ?? 0, n.scrollWidth = o?.scrollWidth ?? 0, n.clientHeight = o?.clientHeight ?? 0, n.clientWidth = o?.clientWidth ?? 0, this.#e?.onScroll(n);
|
|
2966
|
+
}
|
|
2967
|
+
}
|
|
2968
|
+
/**
|
|
2969
|
+
* Find the header row element in the shadow DOM.
|
|
2970
|
+
* Used by plugins that need to access header cells for styling or measurement.
|
|
2971
|
+
* @internal Plugin API
|
|
2972
|
+
*/
|
|
2973
|
+
findHeaderRow() {
|
|
2974
|
+
return this.#n.querySelector(".header-row");
|
|
2975
|
+
}
|
|
2976
|
+
/**
|
|
2977
|
+
* Find a rendered row element by its data row index.
|
|
2978
|
+
* Returns null if the row is not currently rendered (virtualized out of view).
|
|
2979
|
+
* Used by plugins that need to access specific row elements for styling or measurement.
|
|
2980
|
+
* @internal Plugin API
|
|
2981
|
+
* @param rowIndex - The data row index (not the DOM position)
|
|
2982
|
+
*/
|
|
2983
|
+
findRenderedRowElement(e) {
|
|
2984
|
+
return Array.from(this._bodyEl.querySelectorAll(".data-grid-row")).find((o) => {
|
|
2985
|
+
const n = o.querySelector(".cell[data-row]");
|
|
2986
|
+
return n && Number(n.getAttribute("data-row")) === e;
|
|
2987
|
+
}) || null;
|
|
2988
|
+
}
|
|
2989
|
+
/**
|
|
2990
|
+
* Dispatch a cell click event to the plugin system.
|
|
2991
|
+
* Returns true if any plugin handled the event.
|
|
2992
|
+
*/
|
|
2993
|
+
_dispatchCellClick(e, o, n, i) {
|
|
2994
|
+
const l = this._rows[o], r = this._columns[n];
|
|
2995
|
+
if (!l || !r) return !1;
|
|
2996
|
+
const s = {
|
|
2997
|
+
row: l,
|
|
2998
|
+
rowIndex: o,
|
|
2999
|
+
colIndex: n,
|
|
3000
|
+
field: r.field,
|
|
3001
|
+
value: l[r.field],
|
|
3002
|
+
cellEl: i,
|
|
3003
|
+
originalEvent: e
|
|
3004
|
+
};
|
|
3005
|
+
return this.#e?.onCellClick(s) ?? !1;
|
|
3006
|
+
}
|
|
3007
|
+
/**
|
|
3008
|
+
* Dispatch a row click event to the plugin system.
|
|
3009
|
+
* Returns true if any plugin handled the event.
|
|
3010
|
+
*/
|
|
3011
|
+
_dispatchRowClick(e, o, n, i) {
|
|
3012
|
+
if (!n) return !1;
|
|
3013
|
+
const l = {
|
|
3014
|
+
rowIndex: o,
|
|
3015
|
+
row: n,
|
|
3016
|
+
rowEl: i,
|
|
3017
|
+
originalEvent: e
|
|
3018
|
+
};
|
|
3019
|
+
return this.#e?.onRowClick(l) ?? !1;
|
|
3020
|
+
}
|
|
3021
|
+
/**
|
|
3022
|
+
* Dispatch a header click event to the plugin system.
|
|
3023
|
+
* Returns true if any plugin handled the event.
|
|
3024
|
+
*/
|
|
3025
|
+
_dispatchHeaderClick(e, o, n) {
|
|
3026
|
+
const i = this._columns[o];
|
|
3027
|
+
if (!i) return !1;
|
|
3028
|
+
const l = {
|
|
3029
|
+
colIndex: o,
|
|
3030
|
+
field: i.field,
|
|
3031
|
+
column: i,
|
|
3032
|
+
headerEl: n,
|
|
3033
|
+
originalEvent: e
|
|
3034
|
+
};
|
|
3035
|
+
return this.#e?.onHeaderClick(l) ?? !1;
|
|
3036
|
+
}
|
|
3037
|
+
/**
|
|
3038
|
+
* Dispatch a keyboard event to the plugin system.
|
|
3039
|
+
* Returns true if any plugin handled the event.
|
|
3040
|
+
*/
|
|
3041
|
+
_dispatchKeyDown(e) {
|
|
3042
|
+
return this.#e?.onKeyDown(e) ?? !1;
|
|
3043
|
+
}
|
|
3044
|
+
/**
|
|
3045
|
+
* Get horizontal scroll boundary offsets from plugins.
|
|
3046
|
+
* Used by keyboard navigation to ensure focused cells are fully visible
|
|
3047
|
+
* when plugins like pinned columns obscure part of the scroll area.
|
|
3048
|
+
*/
|
|
3049
|
+
_getHorizontalScrollOffsets(e, o) {
|
|
3050
|
+
return this.#e?.getHorizontalScrollOffsets(e, o) ?? { left: 0, right: 0 };
|
|
3051
|
+
}
|
|
3052
|
+
/**
|
|
3053
|
+
* Query all plugins with a generic query and collect responses.
|
|
3054
|
+
* This enables inter-plugin communication without the core knowing plugin-specific concepts.
|
|
3055
|
+
* @internal Plugin API
|
|
3056
|
+
*
|
|
3057
|
+
* @example
|
|
3058
|
+
* // Check if any plugin vetoes moving a column
|
|
3059
|
+
* const responses = grid.queryPlugins<boolean>({ type: PLUGIN_QUERIES.CAN_MOVE_COLUMN, context: column });
|
|
3060
|
+
* const canMove = !responses.includes(false);
|
|
3061
|
+
*/
|
|
3062
|
+
queryPlugins(e) {
|
|
3063
|
+
return this.#e?.queryPlugins(e) ?? [];
|
|
3064
|
+
}
|
|
3065
|
+
/**
|
|
3066
|
+
* Build a CellMouseEvent from a native MouseEvent.
|
|
3067
|
+
* Extracts cell/row information from the event target.
|
|
3068
|
+
*/
|
|
3069
|
+
#W(e, o) {
|
|
3070
|
+
let n = null;
|
|
3071
|
+
const i = e.composedPath?.();
|
|
3072
|
+
if (i && i.length > 0 ? n = i[0] : n = e.target, n && !this.#n.contains(n)) {
|
|
3073
|
+
const f = this.#n.elementFromPoint(e.clientX, e.clientY);
|
|
3074
|
+
f && (n = f);
|
|
3075
|
+
}
|
|
3076
|
+
const l = n?.closest?.("[data-col]"), r = n?.closest?.(".data-grid-row"), s = n?.closest?.(".header-row");
|
|
3077
|
+
let a, c, h, d, u, p;
|
|
3078
|
+
return l && (a = parseInt(l.getAttribute("data-row") ?? "-1", 10), c = parseInt(l.getAttribute("data-col") ?? "-1", 10), a >= 0 && c >= 0 && (h = this._rows[a], p = this._columns[c], d = p?.field, u = h && d ? h[d] : void 0)), {
|
|
3079
|
+
type: o,
|
|
3080
|
+
row: h,
|
|
3081
|
+
rowIndex: a !== void 0 && a >= 0 ? a : void 0,
|
|
3082
|
+
colIndex: c !== void 0 && c >= 0 ? c : void 0,
|
|
3083
|
+
field: d,
|
|
3084
|
+
value: u,
|
|
3085
|
+
column: p,
|
|
3086
|
+
originalEvent: e,
|
|
3087
|
+
cellElement: l ?? void 0,
|
|
3088
|
+
rowElement: r ?? void 0,
|
|
3089
|
+
isHeader: !!s,
|
|
3090
|
+
cell: a !== void 0 && c !== void 0 && a >= 0 && c >= 0 ? { row: a, col: c } : void 0
|
|
3091
|
+
};
|
|
3092
|
+
}
|
|
3093
|
+
/**
|
|
3094
|
+
/**
|
|
3095
|
+
* Handle mousedown events and dispatch to plugin system.
|
|
3096
|
+
*/
|
|
3097
|
+
#be(e) {
|
|
3098
|
+
const o = this.#W(e, "mousedown");
|
|
3099
|
+
(this.#e?.onCellMouseDown(o) ?? !1) && (this.#T = !0);
|
|
3100
|
+
}
|
|
3101
|
+
/**
|
|
3102
|
+
* Handle mousemove events (only when dragging).
|
|
3103
|
+
*/
|
|
3104
|
+
#we(e) {
|
|
3105
|
+
if (!this.#T) return;
|
|
3106
|
+
const o = this.#W(e, "mousemove");
|
|
3107
|
+
this.#e?.onCellMouseMove(o);
|
|
3108
|
+
}
|
|
3109
|
+
/**
|
|
3110
|
+
* Handle mouseup events.
|
|
3111
|
+
*/
|
|
3112
|
+
#ge(e) {
|
|
3113
|
+
if (!this.#T) return;
|
|
3114
|
+
const o = this.#W(e, "mouseup");
|
|
3115
|
+
this.#e?.onCellMouseUp(o), this.#T = !1;
|
|
3116
|
+
}
|
|
3117
|
+
// API consumed by internal utils (rows.ts) - delegates to editing.ts
|
|
3118
|
+
get changedRows() {
|
|
3119
|
+
return De(this);
|
|
3120
|
+
}
|
|
3121
|
+
get changedRowIndices() {
|
|
3122
|
+
return ze(this);
|
|
3123
|
+
}
|
|
3124
|
+
async resetChangedRows(e) {
|
|
3125
|
+
Ct(this, e);
|
|
3126
|
+
}
|
|
3127
|
+
async beginBulkEdit(e) {
|
|
3128
|
+
Et(this, e, {
|
|
3129
|
+
findRenderedRowElement: (o) => this.findRenderedRowElement?.(o) ?? null
|
|
3130
|
+
});
|
|
3131
|
+
}
|
|
3132
|
+
async commitActiveRowEdit() {
|
|
3133
|
+
yt(this);
|
|
3134
|
+
}
|
|
3135
|
+
async cancelActiveRowEdit() {
|
|
3136
|
+
St(this);
|
|
3137
|
+
}
|
|
3138
|
+
async ready() {
|
|
3139
|
+
return this.#U;
|
|
3140
|
+
}
|
|
3141
|
+
async forceLayout() {
|
|
3142
|
+
this.#a(), await new Promise((e) => requestAnimationFrame(() => requestAnimationFrame(e)));
|
|
3143
|
+
}
|
|
3144
|
+
/** Public method: returns a frozen snapshot of the merged effective configuration */
|
|
3145
|
+
async getConfig() {
|
|
3146
|
+
return Object.freeze({ ...this.#t || {} });
|
|
3147
|
+
}
|
|
3148
|
+
// ---------------- Column Visibility API ----------------
|
|
3149
|
+
// Delegates to column-state.ts pure functions
|
|
3150
|
+
/** Visibility callbacks for column-state.ts functions */
|
|
3151
|
+
#$ = {
|
|
3152
|
+
emit: (e, o) => this.#d(e, o),
|
|
3153
|
+
clearRowPool: () => {
|
|
3154
|
+
this._rowPool.length = 0, this._bodyEl && (this._bodyEl.innerHTML = ""), this.__rowRenderEpoch++;
|
|
3155
|
+
},
|
|
3156
|
+
setup: () => this.#a(),
|
|
3157
|
+
requestStateChange: () => this.requestStateChange()
|
|
3158
|
+
};
|
|
3159
|
+
setColumnVisible(e, o) {
|
|
3160
|
+
return xe(this, e, o, this.#$);
|
|
3161
|
+
}
|
|
3162
|
+
toggleColumnVisibility(e) {
|
|
3163
|
+
return Ue(this, e, this.#$);
|
|
3164
|
+
}
|
|
3165
|
+
isColumnVisible(e) {
|
|
3166
|
+
return Xe(this, e);
|
|
3167
|
+
}
|
|
3168
|
+
showAllColumns() {
|
|
3169
|
+
Ye(this, this.#$);
|
|
3170
|
+
}
|
|
3171
|
+
getAllColumns() {
|
|
3172
|
+
return je(this);
|
|
3173
|
+
}
|
|
3174
|
+
setColumnOrder(e) {
|
|
3175
|
+
Ze(this, e, {
|
|
3176
|
+
renderHeader: () => q(this),
|
|
3177
|
+
updateTemplate: () => z(this),
|
|
3178
|
+
refreshVirtualWindow: () => this.refreshVirtualWindow(!0)
|
|
3179
|
+
});
|
|
3180
|
+
}
|
|
3181
|
+
getColumnOrder() {
|
|
3182
|
+
return Ke(this);
|
|
3183
|
+
}
|
|
3184
|
+
// ---------------- Column State API ----------------
|
|
3185
|
+
/**
|
|
3186
|
+
* Get the current column state, including order, width, visibility, sort, and plugin state.
|
|
3187
|
+
* Returns a serializable object suitable for localStorage or database storage.
|
|
3188
|
+
*/
|
|
3189
|
+
getColumnState() {
|
|
3190
|
+
const e = this.#e?.getAll() ?? [];
|
|
3191
|
+
return Te(this, e);
|
|
3192
|
+
}
|
|
3193
|
+
/**
|
|
3194
|
+
* Set the column state, restoring order, width, visibility, sort, and plugin state.
|
|
3195
|
+
* Use this to restore previously saved column state.
|
|
3196
|
+
*/
|
|
3197
|
+
set columnState(e) {
|
|
3198
|
+
e && (this.#f = e, this.#M && this.#me(e));
|
|
3199
|
+
}
|
|
3200
|
+
/**
|
|
3201
|
+
* Get the current column state.
|
|
3202
|
+
*/
|
|
3203
|
+
get columnState() {
|
|
3204
|
+
return this.getColumnState();
|
|
3205
|
+
}
|
|
3206
|
+
/**
|
|
3207
|
+
* Apply column state internally.
|
|
3208
|
+
*/
|
|
3209
|
+
#me(e) {
|
|
3210
|
+
(this.#t.columns ?? []).forEach((n) => {
|
|
3211
|
+
n.hidden = !1;
|
|
3212
|
+
}), this.#ee(e), this.#a();
|
|
3213
|
+
}
|
|
3214
|
+
/**
|
|
3215
|
+
* Request a state change event to be emitted.
|
|
3216
|
+
* Called internally after resize, reorder, visibility, or sort changes.
|
|
3217
|
+
* Plugins should call this after changing their state.
|
|
3218
|
+
* The event is debounced to avoid excessive events during drag operations.
|
|
3219
|
+
* @internal Plugin API
|
|
3220
|
+
*/
|
|
3221
|
+
requestStateChange() {
|
|
3222
|
+
this.#z || (this.#z = Ge(
|
|
3223
|
+
this,
|
|
3224
|
+
() => this.#e?.getAll() ?? [],
|
|
3225
|
+
(e) => this.#d("column-state-change", e)
|
|
3226
|
+
)), this.#z();
|
|
3227
|
+
}
|
|
3228
|
+
/**
|
|
3229
|
+
* Reset column state to initial configuration.
|
|
3230
|
+
* Clears all user modifications (order, width, visibility, sort).
|
|
3231
|
+
*/
|
|
3232
|
+
resetColumnState() {
|
|
3233
|
+
this.#f = void 0, (this.#t.columns ?? []).forEach((n) => {
|
|
3234
|
+
n.hidden = !1;
|
|
3235
|
+
}), this._sortState = null, this.__originalOrder = [], this.#l(), this.#a();
|
|
3236
|
+
const o = this.#e?.getAll() ?? [];
|
|
3237
|
+
for (const n of o)
|
|
3238
|
+
if (n.applyColumnState)
|
|
3239
|
+
for (const i of this._columns)
|
|
3240
|
+
n.applyColumnState(i.field, {
|
|
3241
|
+
field: i.field,
|
|
3242
|
+
order: 0,
|
|
3243
|
+
visible: !0
|
|
3244
|
+
});
|
|
3245
|
+
this.requestStateChange();
|
|
3246
|
+
}
|
|
3247
|
+
// ---------------- Shell / Tool Panel API ----------------
|
|
3248
|
+
// These methods delegate to ShellController for implementation.
|
|
3249
|
+
// The controller encapsulates all tool panel logic while grid.ts
|
|
3250
|
+
// exposes the public API surface.
|
|
3251
|
+
/** Check if the tool panel is currently open. */
|
|
3252
|
+
get isToolPanelOpen() {
|
|
3253
|
+
return this.#i.isPanelOpen;
|
|
3254
|
+
}
|
|
3255
|
+
/**
|
|
3256
|
+
* Get the currently active tool panel ID, or null if none is open.
|
|
3257
|
+
* @deprecated Use isToolPanelOpen and expandedToolPanelSections instead.
|
|
3258
|
+
*/
|
|
3259
|
+
get activeToolPanel() {
|
|
3260
|
+
return this.#i.activePanel;
|
|
3261
|
+
}
|
|
3262
|
+
/** Get the IDs of expanded accordion sections. */
|
|
3263
|
+
get expandedToolPanelSections() {
|
|
3264
|
+
return this.#i.expandedSections;
|
|
3265
|
+
}
|
|
3266
|
+
/** Open the tool panel (accordion view with all registered panels). */
|
|
3267
|
+
openToolPanel() {
|
|
3268
|
+
this.#i.openToolPanel();
|
|
3269
|
+
}
|
|
3270
|
+
/** Close the tool panel. */
|
|
3271
|
+
closeToolPanel() {
|
|
3272
|
+
this.#i.closeToolPanel();
|
|
3273
|
+
}
|
|
3274
|
+
/** Toggle the tool panel open/closed. */
|
|
3275
|
+
toggleToolPanel() {
|
|
3276
|
+
this.#i.toggleToolPanel();
|
|
3277
|
+
}
|
|
3278
|
+
/** Toggle an accordion section expanded/collapsed. */
|
|
3279
|
+
toggleToolPanelSection(e) {
|
|
3280
|
+
this.#i.toggleToolPanelSection(e);
|
|
3281
|
+
}
|
|
3282
|
+
/** Get registered tool panel definitions. */
|
|
3283
|
+
getToolPanels() {
|
|
3284
|
+
return this.#i.getToolPanels();
|
|
3285
|
+
}
|
|
3286
|
+
/** Register a custom tool panel (without creating a plugin). */
|
|
3287
|
+
registerToolPanel(e) {
|
|
3288
|
+
this.#i.registerToolPanel(e);
|
|
3289
|
+
}
|
|
3290
|
+
/** Unregister a custom tool panel. */
|
|
3291
|
+
unregisterToolPanel(e) {
|
|
3292
|
+
this.#i.unregisterToolPanel(e);
|
|
3293
|
+
}
|
|
3294
|
+
/** Get registered header content definitions. */
|
|
3295
|
+
getHeaderContents() {
|
|
3296
|
+
return this.#i.getHeaderContents();
|
|
3297
|
+
}
|
|
3298
|
+
/** Register custom header content (without creating a plugin). */
|
|
3299
|
+
registerHeaderContent(e) {
|
|
3300
|
+
this.#i.registerHeaderContent(e);
|
|
3301
|
+
}
|
|
3302
|
+
/** Unregister custom header content. */
|
|
3303
|
+
unregisterHeaderContent(e) {
|
|
3304
|
+
this.#i.unregisterHeaderContent(e);
|
|
3305
|
+
}
|
|
3306
|
+
/** Get all registered toolbar buttons. */
|
|
3307
|
+
getToolbarButtons() {
|
|
3308
|
+
return this.#i.getToolbarButtons();
|
|
3309
|
+
}
|
|
3310
|
+
/** Register a custom toolbar button programmatically. */
|
|
3311
|
+
registerToolbarButton(e) {
|
|
3312
|
+
this.#i.registerToolbarButton(e);
|
|
3313
|
+
}
|
|
3314
|
+
/** Unregister a custom toolbar button. */
|
|
3315
|
+
unregisterToolbarButton(e) {
|
|
3316
|
+
this.#i.unregisterToolbarButton(e);
|
|
3317
|
+
}
|
|
3318
|
+
/** Enable/disable a toolbar button by ID. */
|
|
3319
|
+
setToolbarButtonDisabled(e, o) {
|
|
3320
|
+
this.#i.setToolbarButtonDisabled(e, o);
|
|
3321
|
+
}
|
|
3322
|
+
/**
|
|
3323
|
+
* Re-parse light DOM shell elements and refresh shell header.
|
|
3324
|
+
* Call this after dynamically modifying <tbw-grid-header> children.
|
|
3325
|
+
*/
|
|
3326
|
+
refreshShellHeader() {
|
|
3327
|
+
V(this, this.#o), F(this, this.#o, this.#_()), this.#F(), this.#B();
|
|
3328
|
+
}
|
|
3329
|
+
// #region Custom Styles API
|
|
3330
|
+
/** Map of registered custom style elements by ID */
|
|
3331
|
+
#E = /* @__PURE__ */ new Map();
|
|
3332
|
+
/**
|
|
3333
|
+
* Register custom CSS styles to be injected into the grid's shadow DOM.
|
|
3334
|
+
* Use this to style custom cell renderers, editors, or detail panels.
|
|
3335
|
+
*
|
|
3336
|
+
* @param id - Unique identifier for the style block (for removal/updates)
|
|
3337
|
+
* @param css - CSS string to inject
|
|
3338
|
+
*
|
|
3339
|
+
* @example
|
|
3340
|
+
* ```typescript
|
|
3341
|
+
* // Register custom styles for a detail panel
|
|
3342
|
+
* grid.registerStyles('my-detail-styles', `
|
|
3343
|
+
* .my-detail-panel { padding: 16px; }
|
|
3344
|
+
* .my-detail-table { width: 100%; }
|
|
3345
|
+
* `);
|
|
3346
|
+
*
|
|
3347
|
+
* // Update styles later
|
|
3348
|
+
* grid.registerStyles('my-detail-styles', updatedCss);
|
|
3349
|
+
*
|
|
3350
|
+
* // Remove styles
|
|
3351
|
+
* grid.unregisterStyles('my-detail-styles');
|
|
3352
|
+
* ```
|
|
3353
|
+
*/
|
|
3354
|
+
registerStyles(e, o) {
|
|
3355
|
+
this.unregisterStyles(e);
|
|
3356
|
+
const n = document.createElement("style");
|
|
3357
|
+
n.id = `tbw-custom-${e}`, n.textContent = o, this.#n.appendChild(n), this.#E.set(e, n);
|
|
3358
|
+
}
|
|
3359
|
+
/**
|
|
3360
|
+
* Remove previously registered custom styles.
|
|
3361
|
+
* @param id - The ID used when registering the styles
|
|
3362
|
+
*/
|
|
3363
|
+
unregisterStyles(e) {
|
|
3364
|
+
const o = this.#E.get(e);
|
|
3365
|
+
o && (o.remove(), this.#E.delete(e));
|
|
3366
|
+
}
|
|
3367
|
+
/**
|
|
3368
|
+
* Get list of registered custom style IDs.
|
|
3369
|
+
*/
|
|
3370
|
+
getRegisteredStyles() {
|
|
3371
|
+
return Array.from(this.#E.keys());
|
|
3372
|
+
}
|
|
3373
|
+
// #endregion
|
|
3374
|
+
/**
|
|
3375
|
+
* Set up MutationObserver to watch for light DOM changes.
|
|
3376
|
+
* This handles frameworks like Angular that project content asynchronously.
|
|
3377
|
+
* When shell-related elements are added/changed, the shell header is updated.
|
|
3378
|
+
*/
|
|
3379
|
+
#ve() {
|
|
3380
|
+
this.#u && this.#u.disconnect();
|
|
3381
|
+
let e = null, o = !1, n = !1;
|
|
3382
|
+
const i = () => {
|
|
3383
|
+
if (e = null, o) {
|
|
3384
|
+
const l = this.#o.lightDomTitle;
|
|
3385
|
+
if (V(this, this.#o), F(this, this.#o, this.#_()), this.#o.lightDomTitle && !l) {
|
|
3386
|
+
this.#l();
|
|
3387
|
+
const s = this.#n.querySelector(".tbw-shell-header");
|
|
3388
|
+
if (s) {
|
|
3389
|
+
const a = ye(
|
|
3390
|
+
this.#t.shell,
|
|
3391
|
+
this.#o,
|
|
3392
|
+
this.#t.icons?.toolPanel
|
|
3393
|
+
), c = document.createElement("div");
|
|
3394
|
+
c.innerHTML = a;
|
|
3395
|
+
const h = c.firstElementChild;
|
|
3396
|
+
h && (s.replaceWith(h), this.#G());
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
o = !1;
|
|
3400
|
+
}
|
|
3401
|
+
n && (this.__lightDomColumnsCache = void 0, this.#a(), n = !1);
|
|
3402
|
+
};
|
|
3403
|
+
this.#u = new MutationObserver((l) => {
|
|
3404
|
+
for (const r of l) {
|
|
3405
|
+
for (const s of r.addedNodes) {
|
|
3406
|
+
if (s.nodeType !== Node.ELEMENT_NODE) continue;
|
|
3407
|
+
const c = s.tagName.toLowerCase();
|
|
3408
|
+
c === "tbw-grid-header" ? o = !0 : (c === "tbw-grid-column" || c === "tbw-grid-detail") && (n = !0);
|
|
3409
|
+
}
|
|
3410
|
+
if (r.type === "attributes" && r.target.nodeType === Node.ELEMENT_NODE) {
|
|
3411
|
+
const a = r.target.tagName.toLowerCase();
|
|
3412
|
+
a === "tbw-grid-header" ? o = !0 : a === "tbw-grid-column" && (n = !0);
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
(o || n) && !e && (e = setTimeout(i, 0));
|
|
3416
|
+
}), this.#u.observe(this, {
|
|
3417
|
+
childList: !0,
|
|
3418
|
+
subtree: !0,
|
|
3419
|
+
attributes: !0,
|
|
3420
|
+
attributeFilter: ["title", "field", "header", "width", "hidden"]
|
|
3421
|
+
});
|
|
3422
|
+
}
|
|
3423
|
+
/**
|
|
3424
|
+
* Re-parse light DOM column elements and refresh the grid.
|
|
3425
|
+
* Call this after framework adapters have registered their templates.
|
|
3426
|
+
* @internal Used by framework integration libraries (Angular, React, Vue)
|
|
3427
|
+
*/
|
|
3428
|
+
refreshColumns() {
|
|
3429
|
+
this.__lightDomColumnsCache = void 0;
|
|
3430
|
+
const e = this.#o.lightDomTitle;
|
|
3431
|
+
if (V(this, this.#o), F(this, this.#o, this.#_()), this.#o.lightDomTitle && !e) {
|
|
3432
|
+
this.#l();
|
|
3433
|
+
const n = this.#n.querySelector(".tbw-shell-header");
|
|
3434
|
+
if (n) {
|
|
3435
|
+
const i = ye(
|
|
3436
|
+
this.#t.shell,
|
|
3437
|
+
this.#o,
|
|
3438
|
+
this.#t.icons?.toolPanel
|
|
3439
|
+
), l = document.createElement("div");
|
|
3440
|
+
l.innerHTML = i;
|
|
3441
|
+
const r = l.firstElementChild;
|
|
3442
|
+
r && (n.replaceWith(r), this.#G());
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3445
|
+
this.#a();
|
|
3446
|
+
}
|
|
3447
|
+
// ---------------- Virtual Window ----------------
|
|
3448
|
+
/**
|
|
3449
|
+
* Calculate total height for the faux scrollbar spacer element.
|
|
3450
|
+
* Used by both bypass and virtualized rendering paths to ensure consistent scroll behavior.
|
|
3451
|
+
*/
|
|
3452
|
+
#V(e) {
|
|
3453
|
+
const o = this._virtualization.rowHeight, n = this._virtualization.container ?? this, i = this._virtualization.viewportEl ?? n, l = n.clientHeight, r = i.clientHeight, a = this.shadowRoot?.querySelector(".tbw-scroll-area"), c = a ? a.clientHeight : l, d = c - r, u = this.#e?.getExtraHeight() ?? 0, p = Math.max(0, l - c);
|
|
3454
|
+
return e * o + d + u + p;
|
|
3455
|
+
}
|
|
3456
|
+
/**
|
|
3457
|
+
* Core virtualization routine. Chooses between bypass (small datasets), grouped window rendering,
|
|
3458
|
+
* or standard row window rendering.
|
|
3459
|
+
* @internal Plugin API
|
|
3460
|
+
*/
|
|
3461
|
+
refreshVirtualWindow(e = !1) {
|
|
3462
|
+
if (!this._bodyEl) return;
|
|
3463
|
+
const o = this._rows.length;
|
|
3464
|
+
if (!this._virtualization.enabled) {
|
|
3465
|
+
this.#q(0, o), this.#e?.afterRender();
|
|
3466
|
+
return;
|
|
3467
|
+
}
|
|
3468
|
+
if (this._rows.length <= this._virtualization.bypassThreshold) {
|
|
3469
|
+
this._virtualization.start = 0, this._virtualization.end = o, e && (this._bodyEl.style.transform = "translateY(0px)"), this.#q(0, o, e ? ++this.__rowRenderEpoch : this.__rowRenderEpoch), this._virtualization.totalHeightEl && (this._virtualization.totalHeightEl.style.height = `${this.#V(o)}px`), this.__rowsBodyEl?.setAttribute("aria-rowcount", String(o)), this.__rowsBodyEl?.setAttribute("aria-colcount", String(this._visibleColumns.length)), this.#e?.afterRender();
|
|
3470
|
+
return;
|
|
3471
|
+
}
|
|
3472
|
+
const n = this._virtualization.container ?? this, i = this._virtualization.viewportEl ?? n, l = i.clientHeight, r = this._virtualization.rowHeight, s = n.scrollTop;
|
|
3473
|
+
let a = Math.floor(s / r), c = 0;
|
|
3474
|
+
const h = 10;
|
|
3475
|
+
for (; c < h; ) {
|
|
3476
|
+
const _ = this.#e?.getExtraHeightBefore?.(a) ?? 0, m = Math.floor((s - _) / r);
|
|
3477
|
+
if (m >= a || m < 0) break;
|
|
3478
|
+
a = m, c++;
|
|
3479
|
+
}
|
|
3480
|
+
a = a - a % 2, a < 0 && (a = 0);
|
|
3481
|
+
const d = this.#e?.adjustVirtualStart(a, s, r);
|
|
3482
|
+
d !== void 0 && d < a && (a = d, a = a - a % 2, a < 0 && (a = 0));
|
|
3483
|
+
const u = Math.ceil(l / r) + 3;
|
|
3484
|
+
let p = a + u;
|
|
3485
|
+
if (p > o && (p = o), this._virtualization.start = a, this._virtualization.end = p, n.clientHeight === 0 && l > 0) {
|
|
3486
|
+
requestAnimationFrame(() => this.refreshVirtualWindow(e));
|
|
3487
|
+
return;
|
|
3488
|
+
}
|
|
3489
|
+
const b = this.#V(o);
|
|
3490
|
+
this._virtualization.totalHeightEl && (this._virtualization.totalHeightEl.style.height = `${b}px`);
|
|
3491
|
+
const g = this.#e?.getExtraHeightBefore?.(a) ?? 0, w = -(s - a * r - g);
|
|
3492
|
+
this._bodyEl.style.transform = `translateY(${w}px)`, this.#q(a, p, e ? ++this.__rowRenderEpoch : this.__rowRenderEpoch), this.__rowsBodyEl?.setAttribute("aria-rowcount", String(o)), this.__rowsBodyEl?.setAttribute("aria-colcount", String(this._visibleColumns.length)), e && (this.#e?.afterRender(), queueMicrotask(() => {
|
|
3493
|
+
const _ = n.clientHeight, m = i.clientHeight;
|
|
3494
|
+
if (_ === 0 && m > 0) return;
|
|
3495
|
+
const v = this.#V(o);
|
|
3496
|
+
this._virtualization.totalHeightEl && (this._virtualization.totalHeightEl.style.height = `${v}px`);
|
|
3497
|
+
}));
|
|
3498
|
+
}
|
|
3499
|
+
// ---------------- Render ----------------
|
|
3500
|
+
#F() {
|
|
3501
|
+
V(this, this.#o), F(this, this.#o, this.#_()), this.#l();
|
|
3502
|
+
const e = this.#t?.shell;
|
|
3503
|
+
Ut(this.#n, e, this.#o, this.#t?.icons) && (this.#G(), this.#i.setInitialized(!0));
|
|
3504
|
+
}
|
|
3505
|
+
/**
|
|
3506
|
+
* Set up shell event listeners after render.
|
|
3507
|
+
*/
|
|
3508
|
+
#G() {
|
|
3509
|
+
Bt(this.#n, this.#t?.shell, this.#o, {
|
|
3510
|
+
onPanelToggle: () => this.toggleToolPanel(),
|
|
3511
|
+
onSectionToggle: (e) => this.toggleToolPanelSection(e),
|
|
3512
|
+
onToolbarButtonClick: (e) => this.#_e(e)
|
|
3513
|
+
}), this.#L?.(), this.#L = It(this.#n, this.#t?.shell, (e) => {
|
|
3514
|
+
this.style.setProperty("--tbw-tool-panel-width", `${e}px`);
|
|
3515
|
+
});
|
|
3516
|
+
}
|
|
3517
|
+
/**
|
|
3518
|
+
* Handle toolbar button click (for config buttons with action).
|
|
3519
|
+
*/
|
|
3520
|
+
#_e(e) {
|
|
3521
|
+
const n = (this.#t?.shell?.header?.toolbarButtons ?? []).find((l) => l.id === e);
|
|
3522
|
+
if (n?.action) {
|
|
3523
|
+
n.action();
|
|
3524
|
+
return;
|
|
3525
|
+
}
|
|
3526
|
+
const i = this.#o.toolbarButtons.get(e);
|
|
3527
|
+
i?.action && i.action();
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
3530
|
+
customElements.get(N.tagName) || customElements.define(N.tagName, N);
|
|
3531
|
+
globalThis.DataGridElement = N;
|
|
3532
|
+
const oo = {
|
|
3533
|
+
/** Ask if a column can be moved. Context: ColumnConfig. Response: boolean | undefined */
|
|
3534
|
+
CAN_MOVE_COLUMN: "canMoveColumn",
|
|
3535
|
+
/** Get context menu items. Context: ContextMenuParams. Response: ContextMenuItem[] */
|
|
3536
|
+
GET_CONTEXT_MENU_ITEMS: "getContextMenuItems"
|
|
3537
|
+
};
|
|
3538
|
+
class no {
|
|
3539
|
+
/** Plugin version - override in subclass if needed */
|
|
3540
|
+
version = "1.0.0";
|
|
3541
|
+
/** CSS styles to inject into the grid's shadow DOM */
|
|
3542
|
+
styles;
|
|
3543
|
+
/** Custom cell renderers keyed by type name */
|
|
3544
|
+
cellRenderers;
|
|
3545
|
+
/** Custom header renderers keyed by type name */
|
|
3546
|
+
headerRenderers;
|
|
3547
|
+
/** Custom cell editors keyed by type name */
|
|
3548
|
+
cellEditors;
|
|
3549
|
+
/** The grid instance this plugin is attached to */
|
|
3550
|
+
grid;
|
|
3551
|
+
/** Plugin configuration - merged with defaults in attach() */
|
|
3552
|
+
config;
|
|
3553
|
+
/** User-provided configuration from constructor */
|
|
3554
|
+
userConfig;
|
|
3555
|
+
/**
|
|
3556
|
+
* Default configuration - subclasses should override this getter.
|
|
3557
|
+
* Note: This must be a getter (not property initializer) for proper inheritance
|
|
3558
|
+
* since property initializers run after parent constructor.
|
|
3559
|
+
*/
|
|
3560
|
+
get defaultConfig() {
|
|
3561
|
+
return {};
|
|
3562
|
+
}
|
|
3563
|
+
constructor(e = {}) {
|
|
3564
|
+
this.userConfig = e;
|
|
3565
|
+
}
|
|
3566
|
+
/**
|
|
3567
|
+
* Called when the plugin is attached to a grid.
|
|
3568
|
+
* Override to set up event listeners, initialize state, etc.
|
|
3569
|
+
*/
|
|
3570
|
+
attach(e) {
|
|
3571
|
+
this.grid = e, this.config = { ...this.defaultConfig, ...this.userConfig };
|
|
3572
|
+
}
|
|
3573
|
+
/**
|
|
3574
|
+
* Called when the plugin is detached from a grid.
|
|
3575
|
+
* Override to clean up event listeners, timers, etc.
|
|
3576
|
+
*/
|
|
3577
|
+
detach() {
|
|
3578
|
+
}
|
|
3579
|
+
/**
|
|
3580
|
+
* Get another plugin instance from the same grid.
|
|
3581
|
+
* Use for inter-plugin communication.
|
|
3582
|
+
*/
|
|
3583
|
+
getPlugin(e) {
|
|
3584
|
+
return this.grid?.getPlugin(e);
|
|
3585
|
+
}
|
|
3586
|
+
/**
|
|
3587
|
+
* Emit a custom event from the grid.
|
|
3588
|
+
*/
|
|
3589
|
+
emit(e, o) {
|
|
3590
|
+
this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: o, bubbles: !0 }));
|
|
3591
|
+
}
|
|
3592
|
+
/**
|
|
3593
|
+
* Request a re-render of the grid.
|
|
3594
|
+
*/
|
|
3595
|
+
requestRender() {
|
|
3596
|
+
this.grid?.requestRender?.();
|
|
3597
|
+
}
|
|
3598
|
+
/**
|
|
3599
|
+
* Request a lightweight style update without rebuilding DOM.
|
|
3600
|
+
* Use this instead of requestRender() when only CSS classes need updating.
|
|
3601
|
+
*/
|
|
3602
|
+
requestAfterRender() {
|
|
3603
|
+
this.grid?.requestAfterRender?.();
|
|
3604
|
+
}
|
|
3605
|
+
/**
|
|
3606
|
+
* Get the current rows from the grid.
|
|
3607
|
+
*/
|
|
3608
|
+
get rows() {
|
|
3609
|
+
return this.grid?.rows ?? [];
|
|
3610
|
+
}
|
|
3611
|
+
/**
|
|
3612
|
+
* Get the original unfiltered/unprocessed rows from the grid.
|
|
3613
|
+
* Use this when you need all source data regardless of active filters.
|
|
3614
|
+
*/
|
|
3615
|
+
get sourceRows() {
|
|
3616
|
+
return this.grid?.sourceRows ?? [];
|
|
3617
|
+
}
|
|
3618
|
+
/**
|
|
3619
|
+
* Get the current columns from the grid.
|
|
3620
|
+
*/
|
|
3621
|
+
get columns() {
|
|
3622
|
+
return this.grid?.columns ?? [];
|
|
3623
|
+
}
|
|
3624
|
+
/**
|
|
3625
|
+
* Get only visible columns from the grid (excludes hidden).
|
|
3626
|
+
* Use this for rendering that needs to match the grid template.
|
|
3627
|
+
*/
|
|
3628
|
+
get visibleColumns() {
|
|
3629
|
+
return this.grid?._visibleColumns ?? [];
|
|
3630
|
+
}
|
|
3631
|
+
/**
|
|
3632
|
+
* Get the shadow root of the grid.
|
|
3633
|
+
*/
|
|
3634
|
+
get shadowRoot() {
|
|
3635
|
+
return this.grid?.shadowRoot ?? null;
|
|
3636
|
+
}
|
|
3637
|
+
/**
|
|
3638
|
+
* Get the disconnect signal for event listener cleanup.
|
|
3639
|
+
* This signal is aborted when the grid disconnects from the DOM.
|
|
3640
|
+
* Use this when adding event listeners that should be cleaned up automatically.
|
|
3641
|
+
*
|
|
3642
|
+
* Best for:
|
|
3643
|
+
* - Document/window-level listeners added in attach()
|
|
3644
|
+
* - Listeners on the grid element itself
|
|
3645
|
+
* - Any listener that should persist across renders
|
|
3646
|
+
*
|
|
3647
|
+
* Not needed for:
|
|
3648
|
+
* - Listeners on elements created in afterRender() (removed with element)
|
|
3649
|
+
*
|
|
3650
|
+
* @example
|
|
3651
|
+
* element.addEventListener('click', handler, { signal: this.disconnectSignal });
|
|
3652
|
+
* document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
|
|
3653
|
+
*/
|
|
3654
|
+
get disconnectSignal() {
|
|
3655
|
+
return this.grid?.disconnectSignal;
|
|
3656
|
+
}
|
|
3657
|
+
/**
|
|
3658
|
+
* Get the grid-level icons configuration.
|
|
3659
|
+
* Returns merged icons (user config + defaults).
|
|
3660
|
+
*/
|
|
3661
|
+
get gridIcons() {
|
|
3662
|
+
const e = this.grid?.gridConfig?.icons ?? {};
|
|
3663
|
+
return { ...O, ...e };
|
|
3664
|
+
}
|
|
3665
|
+
/**
|
|
3666
|
+
* Resolve an icon value to string or HTMLElement.
|
|
3667
|
+
* Checks plugin config first, then grid-level icons, then defaults.
|
|
3668
|
+
*
|
|
3669
|
+
* @param iconKey - The icon key in GridIcons (e.g., 'expand', 'collapse')
|
|
3670
|
+
* @param pluginOverride - Optional plugin-level override
|
|
3671
|
+
* @returns The resolved icon value
|
|
3672
|
+
*/
|
|
3673
|
+
resolveIcon(e, o) {
|
|
3674
|
+
return o !== void 0 ? o : this.gridIcons[e];
|
|
3675
|
+
}
|
|
3676
|
+
/**
|
|
3677
|
+
* Set an icon value on an element.
|
|
3678
|
+
* Handles both string (text/HTML) and HTMLElement values.
|
|
3679
|
+
*
|
|
3680
|
+
* @param element - The element to set the icon on
|
|
3681
|
+
* @param icon - The icon value (string or HTMLElement)
|
|
3682
|
+
*/
|
|
3683
|
+
setIcon(e, o) {
|
|
3684
|
+
typeof o == "string" ? e.innerHTML = o : o instanceof HTMLElement && (e.innerHTML = "", e.appendChild(o.cloneNode(!0)));
|
|
3685
|
+
}
|
|
3686
|
+
/**
|
|
3687
|
+
* Log a warning message.
|
|
3688
|
+
*/
|
|
3689
|
+
warn(e) {
|
|
3690
|
+
console.warn(`[tbw-grid:${this.name}] ${e}`);
|
|
3691
|
+
}
|
|
3692
|
+
// #endregion
|
|
3693
|
+
}
|
|
3694
|
+
const E = {
|
|
3695
|
+
// ─── Core Structure ───────────────────────────────────────────────
|
|
3696
|
+
ROOT: "tbw-grid-root",
|
|
3697
|
+
HEADER: "header",
|
|
3698
|
+
HEADER_ROW: "header-row",
|
|
3699
|
+
HEADER_CELL: "header-cell",
|
|
3700
|
+
// Body structure
|
|
3701
|
+
ROWS_VIEWPORT: "rows-viewport",
|
|
3702
|
+
ROWS_SPACER: "rows-spacer",
|
|
3703
|
+
ROWS_CONTAINER: "rows",
|
|
3704
|
+
// Row elements
|
|
3705
|
+
DATA_ROW: "data-row",
|
|
3706
|
+
GROUP_ROW: "group-row",
|
|
3707
|
+
// Cell elements
|
|
3708
|
+
DATA_CELL: "data-cell",
|
|
3709
|
+
// ─── Core States ──────────────────────────────────────────────────
|
|
3710
|
+
SELECTED: "selected",
|
|
3711
|
+
FOCUSED: "focused",
|
|
3712
|
+
EDITING: "editing",
|
|
3713
|
+
EXPANDED: "expanded",
|
|
3714
|
+
COLLAPSED: "collapsed",
|
|
3715
|
+
DRAGGING: "dragging",
|
|
3716
|
+
RESIZING: "resizing",
|
|
3717
|
+
// Sorting (core feature)
|
|
3718
|
+
SORTABLE: "sortable",
|
|
3719
|
+
SORTED_ASC: "sorted-asc",
|
|
3720
|
+
SORTED_DESC: "sorted-desc",
|
|
3721
|
+
// Visibility
|
|
3722
|
+
HIDDEN: "hidden",
|
|
3723
|
+
// ─── Shared Classes (used by plugins, styled by core CSS) ────────
|
|
3724
|
+
// These are defined here because core CSS provides the base styling.
|
|
3725
|
+
// Plugins apply these classes; core CSS defines how they look.
|
|
3726
|
+
// Sticky positioning (PinnedColumnsPlugin applies, core CSS styles)
|
|
3727
|
+
STICKY_LEFT: "sticky-left",
|
|
3728
|
+
STICKY_RIGHT: "sticky-right",
|
|
3729
|
+
// Pinned rows (PinnedRowsPlugin applies, core CSS styles)
|
|
3730
|
+
PINNED_TOP: "pinned-top",
|
|
3731
|
+
PINNED_BOTTOM: "pinned-bottom",
|
|
3732
|
+
// Tree structure (TreePlugin applies, core CSS styles)
|
|
3733
|
+
TREE_TOGGLE: "tree-toggle",
|
|
3734
|
+
TREE_INDENT: "tree-indent",
|
|
3735
|
+
// Grouping (GroupingRowsPlugin applies, core CSS styles)
|
|
3736
|
+
GROUP_TOGGLE: "group-toggle",
|
|
3737
|
+
GROUP_LABEL: "group-label",
|
|
3738
|
+
GROUP_COUNT: "group-count",
|
|
3739
|
+
// Selection (SelectionPlugin applies, core CSS styles)
|
|
3740
|
+
RANGE_SELECTION: "range-selection",
|
|
3741
|
+
SELECTION_OVERLAY: "selection-overlay"
|
|
3742
|
+
}, j = {
|
|
3743
|
+
// ─── Core Attributes ──────────────────────────────────────────────
|
|
3744
|
+
ROW_INDEX: "data-row-index",
|
|
3745
|
+
COL_INDEX: "data-col-index",
|
|
3746
|
+
FIELD: "data-field",
|
|
3747
|
+
// ─── Shared Attributes (used by plugins) ──────────────────────────
|
|
3748
|
+
GROUP_KEY: "data-group-key",
|
|
3749
|
+
// GroupingRowsPlugin
|
|
3750
|
+
TREE_LEVEL: "data-tree-level",
|
|
3751
|
+
// TreePlugin
|
|
3752
|
+
STICKY: "data-sticky"
|
|
3753
|
+
// PinnedColumnsPlugin
|
|
3754
|
+
}, io = {
|
|
3755
|
+
ROOT: `.${E.ROOT}`,
|
|
3756
|
+
HEADER: `.${E.HEADER}`,
|
|
3757
|
+
HEADER_ROW: `.${E.HEADER_ROW}`,
|
|
3758
|
+
HEADER_CELL: `.${E.HEADER_CELL}`,
|
|
3759
|
+
ROWS_VIEWPORT: `.${E.ROWS_VIEWPORT}`,
|
|
3760
|
+
ROWS_CONTAINER: `.${E.ROWS_CONTAINER}`,
|
|
3761
|
+
DATA_ROW: `.${E.DATA_ROW}`,
|
|
3762
|
+
DATA_CELL: `.${E.DATA_CELL}`,
|
|
3763
|
+
GROUP_ROW: `.${E.GROUP_ROW}`,
|
|
3764
|
+
// By data attribute
|
|
3765
|
+
ROW_BY_INDEX: (t) => `.${E.DATA_ROW}[${j.ROW_INDEX}="${t}"]`,
|
|
3766
|
+
CELL_BY_FIELD: (t) => `.${E.DATA_CELL}[${j.FIELD}="${t}"]`,
|
|
3767
|
+
CELL_AT: (t, e) => `.${E.DATA_ROW}[${j.ROW_INDEX}="${t}"] .${E.DATA_CELL}[${j.COL_INDEX}="${e}"]`,
|
|
3768
|
+
// State selectors
|
|
3769
|
+
SELECTED_ROWS: `.${E.DATA_ROW}.${E.SELECTED}`,
|
|
3770
|
+
EDITING_CELL: `.${E.DATA_CELL}.${E.EDITING}`
|
|
3771
|
+
}, lo = {
|
|
3772
|
+
// Colors
|
|
3773
|
+
COLOR_BG: "--tbw-color-bg",
|
|
3774
|
+
COLOR_FG: "--tbw-color-fg",
|
|
3775
|
+
COLOR_FG_MUTED: "--tbw-color-fg-muted",
|
|
3776
|
+
COLOR_BORDER: "--tbw-color-border",
|
|
3777
|
+
COLOR_ACCENT: "--tbw-color-accent",
|
|
3778
|
+
COLOR_HEADER_BG: "--tbw-color-header-bg",
|
|
3779
|
+
COLOR_HEADER_FG: "--tbw-color-header-fg",
|
|
3780
|
+
COLOR_SELECTION: "--tbw-color-selection",
|
|
3781
|
+
COLOR_ROW_HOVER: "--tbw-color-row-hover",
|
|
3782
|
+
COLOR_ROW_ALT: "--tbw-color-row-alt",
|
|
3783
|
+
// Sizing
|
|
3784
|
+
ROW_HEIGHT: "--tbw-row-height",
|
|
3785
|
+
HEADER_HEIGHT: "--tbw-header-height",
|
|
3786
|
+
CELL_PADDING: "--tbw-cell-padding",
|
|
3787
|
+
// Typography
|
|
3788
|
+
FONT_FAMILY: "--tbw-font-family",
|
|
3789
|
+
FONT_SIZE: "--tbw-font-size",
|
|
3790
|
+
// Borders
|
|
3791
|
+
BORDER_RADIUS: "--tbw-border-radius",
|
|
3792
|
+
FOCUS_OUTLINE: "--tbw-focus-outline"
|
|
3793
|
+
}, ro = {
|
|
3794
|
+
CELL_COMMIT: "cell-commit",
|
|
3795
|
+
ROW_COMMIT: "row-commit",
|
|
3796
|
+
CHANGED_ROWS_RESET: "changed-rows-reset",
|
|
3797
|
+
MOUNT_EXTERNAL_VIEW: "mount-external-view",
|
|
3798
|
+
MOUNT_EXTERNAL_EDITOR: "mount-external-editor",
|
|
3799
|
+
SORT_CHANGE: "sort-change",
|
|
3800
|
+
COLUMN_RESIZE: "column-resize",
|
|
3801
|
+
ACTIVATE_CELL: "activate-cell",
|
|
3802
|
+
GROUP_TOGGLE: "group-toggle",
|
|
3803
|
+
COLUMN_STATE_CHANGE: "column-state-change"
|
|
3804
|
+
}, so = {
|
|
3805
|
+
// Selection plugin
|
|
3806
|
+
SELECTION_CHANGE: "selection-change",
|
|
3807
|
+
// Tree plugin
|
|
3808
|
+
TREE_EXPAND: "tree-expand",
|
|
3809
|
+
// Filtering plugin
|
|
3810
|
+
FILTER_CHANGE: "filter-change",
|
|
3811
|
+
// Sorting plugin
|
|
3812
|
+
SORT_MODEL_CHANGE: "sort-model-change",
|
|
3813
|
+
// Export plugin
|
|
3814
|
+
EXPORT_START: "export-start",
|
|
3815
|
+
EXPORT_COMPLETE: "export-complete",
|
|
3816
|
+
// Clipboard plugin
|
|
3817
|
+
CLIPBOARD_COPY: "clipboard-copy",
|
|
3818
|
+
CLIPBOARD_PASTE: "clipboard-paste",
|
|
3819
|
+
// Context menu plugin
|
|
3820
|
+
CONTEXT_MENU_OPEN: "context-menu-open",
|
|
3821
|
+
CONTEXT_MENU_CLOSE: "context-menu-close",
|
|
3822
|
+
// Undo/Redo plugin
|
|
3823
|
+
HISTORY_CHANGE: "history-change",
|
|
3824
|
+
// Server-side plugin
|
|
3825
|
+
SERVER_LOADING: "server-loading",
|
|
3826
|
+
SERVER_ERROR: "server-error",
|
|
3827
|
+
// Visibility plugin
|
|
3828
|
+
COLUMN_VISIBILITY_CHANGE: "column-visibility-change",
|
|
3829
|
+
// Reorder plugin
|
|
3830
|
+
COLUMN_REORDER: "column-reorder",
|
|
3831
|
+
// Master-detail plugin
|
|
3832
|
+
DETAIL_EXPAND: "detail-expand",
|
|
3833
|
+
// Grouping rows plugin
|
|
3834
|
+
GROUP_EXPAND: "group-expand"
|
|
3835
|
+
}, ie = {
|
|
3836
|
+
sum: (t, e) => t.reduce((o, n) => o + (Number(n[e]) || 0), 0),
|
|
3837
|
+
avg: (t, e) => {
|
|
3838
|
+
const o = t.reduce((n, i) => n + (Number(i[e]) || 0), 0);
|
|
3839
|
+
return t.length ? o / t.length : 0;
|
|
3840
|
+
},
|
|
3841
|
+
count: (t) => t.length,
|
|
3842
|
+
min: (t, e) => Math.min(...t.map((o) => Number(o[e]) || 1 / 0)),
|
|
3843
|
+
max: (t, e) => Math.max(...t.map((o) => Number(o[e]) || -1 / 0)),
|
|
3844
|
+
first: (t, e) => t[0]?.[e],
|
|
3845
|
+
last: (t, e) => t[t.length - 1]?.[e]
|
|
3846
|
+
}, G = /* @__PURE__ */ new Map(), P = {
|
|
3847
|
+
/**
|
|
3848
|
+
* Register a custom aggregator function.
|
|
3849
|
+
*/
|
|
3850
|
+
register(t, e) {
|
|
3851
|
+
G.set(t, e);
|
|
3852
|
+
},
|
|
3853
|
+
/**
|
|
3854
|
+
* Unregister a custom aggregator function.
|
|
3855
|
+
*/
|
|
3856
|
+
unregister(t) {
|
|
3857
|
+
G.delete(t);
|
|
3858
|
+
},
|
|
3859
|
+
/**
|
|
3860
|
+
* Get an aggregator function by reference.
|
|
3861
|
+
*/
|
|
3862
|
+
get(t) {
|
|
3863
|
+
if (t !== void 0)
|
|
3864
|
+
return typeof t == "function" ? t : G.get(t) ?? ie[t];
|
|
3865
|
+
},
|
|
3866
|
+
/**
|
|
3867
|
+
* Run an aggregator on a set of rows.
|
|
3868
|
+
*/
|
|
3869
|
+
run(t, e, o, n) {
|
|
3870
|
+
const i = this.get(t);
|
|
3871
|
+
return i ? i(e, o, n) : void 0;
|
|
3872
|
+
},
|
|
3873
|
+
/**
|
|
3874
|
+
* Check if an aggregator exists.
|
|
3875
|
+
*/
|
|
3876
|
+
has(t) {
|
|
3877
|
+
return G.has(t) || t in ie;
|
|
3878
|
+
},
|
|
3879
|
+
/**
|
|
3880
|
+
* List all available aggregator names.
|
|
3881
|
+
*/
|
|
3882
|
+
list() {
|
|
3883
|
+
return [...Object.keys(ie), ...G.keys()];
|
|
3884
|
+
}
|
|
3885
|
+
}, Ae = {
|
|
3886
|
+
sum: (t) => t.reduce((e, o) => e + o, 0),
|
|
3887
|
+
avg: (t) => t.length ? t.reduce((e, o) => e + o, 0) / t.length : 0,
|
|
3888
|
+
count: (t) => t.length,
|
|
3889
|
+
min: (t) => t.length ? Math.min(...t) : 0,
|
|
3890
|
+
max: (t) => t.length ? Math.max(...t) : 0,
|
|
3891
|
+
first: (t) => t[0] ?? 0,
|
|
3892
|
+
last: (t) => t[t.length - 1] ?? 0
|
|
3893
|
+
};
|
|
3894
|
+
function to(t) {
|
|
3895
|
+
return Ae[t] ?? Ae.sum;
|
|
3896
|
+
}
|
|
3897
|
+
function ao(t, e) {
|
|
3898
|
+
return to(t)(e);
|
|
3899
|
+
}
|
|
3900
|
+
const co = P.register.bind(P), uo = P.unregister.bind(P), ho = P.get.bind(P), fo = P.run.bind(P), po = P.list.bind(P);
|
|
2
3901
|
export {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
3902
|
+
no as BaseGridPlugin,
|
|
3903
|
+
Je as DEFAULT_ANIMATION_CONFIG,
|
|
3904
|
+
O as DEFAULT_GRID_ICONS,
|
|
3905
|
+
ro as DGEvents,
|
|
3906
|
+
N as DataGridElement,
|
|
3907
|
+
X as FitModeEnum,
|
|
3908
|
+
lo as GridCSSVars,
|
|
3909
|
+
E as GridClasses,
|
|
3910
|
+
j as GridDataAttrs,
|
|
3911
|
+
N as GridElement,
|
|
3912
|
+
io as GridSelectors,
|
|
3913
|
+
oo as PLUGIN_QUERIES,
|
|
3914
|
+
so as PluginEvents,
|
|
3915
|
+
eo as PluginManager,
|
|
3916
|
+
k as a,
|
|
3917
|
+
P as aggregatorRegistry,
|
|
3918
|
+
Ht as builtInSort,
|
|
3919
|
+
le as c,
|
|
3920
|
+
Pt as defaultComparator,
|
|
3921
|
+
Pe as e,
|
|
3922
|
+
Me as g,
|
|
3923
|
+
ho as getAggregator,
|
|
3924
|
+
to as getValueAggregator,
|
|
3925
|
+
po as listAggregators,
|
|
3926
|
+
co as registerAggregator,
|
|
3927
|
+
fo as runAggregator,
|
|
3928
|
+
ao as runValueAggregator,
|
|
3929
|
+
K as s,
|
|
3930
|
+
uo as unregisterAggregator
|
|
27
3931
|
};
|
|
28
3932
|
//# sourceMappingURL=index.js.map
|