@toolbox-web/grid 2.3.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/all.d.ts +1 -0
  2. package/all.js +2 -2
  3. package/all.js.map +1 -1
  4. package/index.js +1 -1
  5. package/index.js.map +1 -1
  6. package/lib/core/grid.d.ts +2 -1
  7. package/lib/core/internal/aria.d.ts +13 -0
  8. package/lib/core/internal/diagnostics.d.ts +5 -1
  9. package/lib/core/internal/dom-builder.d.ts +0 -25
  10. package/lib/core/internal/drag-drop-registry.d.ts +66 -0
  11. package/lib/core/internal/render-scheduler.d.ts +9 -8
  12. package/lib/core/plugin/base-plugin.d.ts +23 -0
  13. package/lib/core/plugin/plugin-manager.d.ts +9 -0
  14. package/lib/core/types.d.ts +67 -46
  15. package/lib/features/registry.js.map +1 -1
  16. package/lib/features/reorder-rows.d.ts +3 -3
  17. package/lib/features/reorder-rows.js +1 -1
  18. package/lib/features/reorder-rows.js.map +1 -1
  19. package/lib/features/row-drag-drop.d.ts +9 -0
  20. package/lib/features/row-drag-drop.js +2 -0
  21. package/lib/features/row-drag-drop.js.map +1 -0
  22. package/lib/features/server-side.js.map +1 -1
  23. package/lib/plugins/clipboard/index.js +1 -1
  24. package/lib/plugins/clipboard/index.js.map +1 -1
  25. package/lib/plugins/column-virtualization/index.js +1 -1
  26. package/lib/plugins/column-virtualization/index.js.map +1 -1
  27. package/lib/plugins/context-menu/index.js +1 -1
  28. package/lib/plugins/context-menu/index.js.map +1 -1
  29. package/lib/plugins/editing/index.js +1 -1
  30. package/lib/plugins/editing/index.js.map +1 -1
  31. package/lib/plugins/export/ExportPlugin.d.ts +89 -0
  32. package/lib/plugins/export/index.d.ts +3 -2
  33. package/lib/plugins/export/index.js +1 -1
  34. package/lib/plugins/export/index.js.map +1 -1
  35. package/lib/plugins/export/types.d.ts +30 -0
  36. package/lib/plugins/filtering/FilteringPlugin.d.ts +15 -0
  37. package/lib/plugins/filtering/index.js +1 -1
  38. package/lib/plugins/filtering/index.js.map +1 -1
  39. package/lib/plugins/grouping-columns/index.js +1 -1
  40. package/lib/plugins/grouping-columns/index.js.map +1 -1
  41. package/lib/plugins/grouping-rows/index.js +2 -2
  42. package/lib/plugins/grouping-rows/index.js.map +1 -1
  43. package/lib/plugins/master-detail/index.js +1 -1
  44. package/lib/plugins/master-detail/index.js.map +1 -1
  45. package/lib/plugins/multi-sort/index.js +1 -1
  46. package/lib/plugins/multi-sort/index.js.map +1 -1
  47. package/lib/plugins/pinned-columns/index.js +1 -1
  48. package/lib/plugins/pinned-columns/index.js.map +1 -1
  49. package/lib/plugins/pinned-rows/index.js +1 -1
  50. package/lib/plugins/pinned-rows/index.js.map +1 -1
  51. package/lib/plugins/pivot/index.js +1 -1
  52. package/lib/plugins/pivot/index.js.map +1 -1
  53. package/lib/plugins/print/index.js +1 -1
  54. package/lib/plugins/print/index.js.map +1 -1
  55. package/lib/plugins/reorder-columns/index.js +1 -1
  56. package/lib/plugins/reorder-columns/index.js.map +1 -1
  57. package/lib/plugins/reorder-rows/RowReorderPlugin.d.ts +14 -156
  58. package/lib/plugins/reorder-rows/index.d.ts +10 -4
  59. package/lib/plugins/reorder-rows/index.js +1 -1
  60. package/lib/plugins/reorder-rows/index.js.map +1 -1
  61. package/lib/plugins/reorder-rows/types.d.ts +9 -86
  62. package/lib/plugins/responsive/index.js +1 -1
  63. package/lib/plugins/responsive/index.js.map +1 -1
  64. package/lib/plugins/row-drag-drop/RowDragDropPlugin.d.ts +146 -0
  65. package/lib/plugins/row-drag-drop/index.d.ts +9 -0
  66. package/lib/plugins/row-drag-drop/index.js +2 -0
  67. package/lib/plugins/row-drag-drop/index.js.map +1 -0
  68. package/lib/plugins/row-drag-drop/types.d.ts +276 -0
  69. package/lib/plugins/selection/index.js +1 -1
  70. package/lib/plugins/selection/index.js.map +1 -1
  71. package/lib/plugins/server-side/ServerSidePlugin.d.ts +13 -0
  72. package/lib/plugins/server-side/datasource-types.d.ts +54 -7
  73. package/lib/plugins/server-side/datasource.d.ts +10 -2
  74. package/lib/plugins/server-side/index.d.ts +1 -1
  75. package/lib/plugins/server-side/index.js +1 -1
  76. package/lib/plugins/server-side/index.js.map +1 -1
  77. package/lib/plugins/server-side/types.d.ts +1 -1
  78. package/lib/plugins/shared/drag-drop-protocol.d.ts +98 -0
  79. package/lib/plugins/tooltip/index.js +1 -1
  80. package/lib/plugins/tooltip/index.js.map +1 -1
  81. package/lib/plugins/tree/TreePlugin.d.ts +19 -6
  82. package/lib/plugins/tree/index.js +1 -1
  83. package/lib/plugins/tree/index.js.map +1 -1
  84. package/lib/plugins/undo-redo/index.js +1 -1
  85. package/lib/plugins/undo-redo/index.js.map +1 -1
  86. package/lib/plugins/visibility/index.js +1 -1
  87. package/lib/plugins/visibility/index.js.map +1 -1
  88. package/package.json +1 -1
  89. package/umd/grid.all.umd.js +1 -1
  90. package/umd/grid.all.umd.js.map +1 -1
  91. package/umd/grid.umd.js +1 -1
  92. package/umd/grid.umd.js.map +1 -1
  93. package/umd/plugins/export.umd.js +1 -1
  94. package/umd/plugins/export.umd.js.map +1 -1
  95. package/umd/plugins/filtering.umd.js +1 -1
  96. package/umd/plugins/filtering.umd.js.map +1 -1
  97. package/umd/plugins/reorder-rows.umd.js +1 -1
  98. package/umd/plugins/reorder-rows.umd.js.map +1 -1
  99. package/umd/plugins/row-drag-drop.umd.js +2 -0
  100. package/umd/plugins/row-drag-drop.umd.js.map +1 -0
  101. package/umd/plugins/selection.umd.js +1 -1
  102. package/umd/plugins/selection.umd.js.map +1 -1
  103. package/umd/plugins/server-side.umd.js +1 -1
  104. package/umd/plugins/server-side.umd.js.map +1 -1
  105. package/umd/plugins/tree.umd.js +1 -1
  106. package/umd/plugins/tree.umd.js.map +1 -1
@@ -1,5 +1,26 @@
1
1
  import { BaseGridPlugin, PluginManifest, PluginQuery } from '../../core/plugin/base-plugin';
2
+ import { ColumnConfig } from '../../core/types';
3
+ import { CsvOptions } from './csv';
2
4
  import { ExportConfig, ExportFormat, ExportParams } from './types';
5
+ /**
6
+ * Subset of {@link ExportParams} accepted by the pure formatters
7
+ * ({@link ExportPlugin.formatCsv} / {@link ExportPlugin.formatExcel}).
8
+ *
9
+ * The formatters operate on already-resolved data, so options that affect
10
+ * value resolution (`mode`, `rowIndices`, `format`, `fileName`,
11
+ * `fileExtension`) are intentionally excluded — if you need them, run them
12
+ * through {@link ExportPlugin.export} first or call the download/export
13
+ * methods.
14
+ *
15
+ * `processCell` **is** honoured: it runs once per cell on the values you pass
16
+ * in, just like the download methods.
17
+ */
18
+ export type FormatCsvParams = Pick<ExportParams, 'columns' | 'includeHeaders' | 'processCell' | 'processHeader'>;
19
+ /**
20
+ * Subset of {@link ExportParams} accepted by {@link ExportPlugin.formatExcel}.
21
+ * Same shape as {@link FormatCsvParams} plus `excelStyles`.
22
+ */
23
+ export type FormatExcelParams = FormatCsvParams & Pick<ExportParams, 'excelStyles'>;
3
24
  /**
4
25
  * Export Plugin for tbw-grid
5
26
  *
@@ -60,6 +81,7 @@ import { ExportConfig, ExportFormat, ExportParams } from './types';
60
81
  * @internal Extends BaseGridPlugin
61
82
  */
62
83
  export declare class ExportPlugin extends BaseGridPlugin<ExportConfig> {
84
+ #private;
63
85
  /**
64
86
  * Plugin manifest — declares queries for inter-plugin communication.
65
87
  * @internal
@@ -73,8 +95,75 @@ export declare class ExportPlugin extends BaseGridPlugin<ExportConfig> {
73
95
  private lastExportInfo;
74
96
  /** @internal */
75
97
  handleQuery(query: PluginQuery): unknown;
98
+ /**
99
+ * Resolve the columns and rows that an export with these params would
100
+ * include, plus a fully-defaulted ExportParams for downstream consumers.
101
+ *
102
+ * Honours `config.onlyVisible`, `config.onlySelected`, `params.columns`, and
103
+ * `params.rowIndices`.
104
+ */
105
+ private resolveExportData;
106
+ /**
107
+ * Apply the configured export `mode` to a single cell value.
108
+ *
109
+ * - `'raw'` : returns the underlying value (after optional `processCell`).
110
+ * - `'formatted'` : applies the column-type default formatter and `column.format`,
111
+ * returning the same string the grid displays. `processCell`
112
+ * runs last on the formatted value.
113
+ */
114
+ private resolveCellOutput;
76
115
  private performExport;
77
116
  private getSelectionState;
117
+ /**
118
+ * Returns the row data that would be included in an export, without
119
+ * producing a file. Honours `mode`, `onlyVisible`, `onlySelected`,
120
+ * `columns`, `rowIndices`, `processCell`, and (for `mode: 'formatted'`)
121
+ * `column.format`.
122
+ *
123
+ * Each returned object is keyed by `column.field` in column order.
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * // Underlying typed values (Date stays Date, number stays number)
128
+ * const raw = exporter.export();
129
+ *
130
+ * // What the user sees in each cell
131
+ * const display = exporter.export({ mode: 'formatted' });
132
+ * ```
133
+ */
134
+ export(params?: Partial<ExportParams>): Record<string, unknown>[];
135
+ /**
136
+ * Returns the columns (in order) that an export with these params would
137
+ * include. Useful when handing rows to a third-party serializer that needs
138
+ * header labels, widths, or types alongside the data.
139
+ */
140
+ getResolvedColumns(params?: Partial<ExportParams>): ColumnConfig[];
141
+ /**
142
+ * Format an array of row objects as a CSV string. Column order, headers,
143
+ * and which fields to emit are taken from the plugin's resolved columns
144
+ * (respecting `onlyVisible` and `params.columns`).
145
+ *
146
+ * This is a **pure formatter** — it does not re-resolve values from the
147
+ * grid. Pass `data` produced by {@link ExportPlugin.export} (or any
148
+ * compatible row objects keyed by `column.field`).
149
+ *
150
+ * `params.processCell` is honoured: it runs once per cell on the values in
151
+ * `data`. `mode` is **not** accepted here — apply it upstream via
152
+ * `export({ mode: 'formatted' })`.
153
+ *
154
+ * @example
155
+ * ```ts
156
+ * const csv = exporter.formatCsv(exporter.export());
157
+ * await navigator.clipboard.writeText(csv);
158
+ * ```
159
+ */
160
+ formatCsv(data: Record<string, unknown>[], params?: FormatCsvParams, options?: CsvOptions): string;
161
+ /**
162
+ * Format an array of row objects as an Excel XML Spreadsheet 2003 string.
163
+ * See {@link formatCsv} for the data-shape contract — this method is also a
164
+ * pure formatter and `params.processCell` is honoured the same way.
165
+ */
166
+ formatExcel(data: Record<string, unknown>[], params?: FormatExcelParams): string;
78
167
  /**
79
168
  * Export data to CSV format.
80
169
  * @param params - Optional export parameters
@@ -4,5 +4,6 @@
4
4
  *
5
5
  * @module Plugins/Export
6
6
  */
7
- export { ExportPlugin } from './ExportPlugin';
8
- export type { ExcelBorder, ExcelCellStyle, ExcelStyleConfig, ExportCompleteDetail, ExportConfig, ExportFormat, ExportParams, } from './types';
7
+ export type { CsvOptions } from './csv';
8
+ export { ExportPlugin, type FormatCsvParams, type FormatExcelParams } from './ExportPlugin';
9
+ export type { ExcelBorder, ExcelCellStyle, ExcelStyleConfig, ExportCompleteDetail, ExportConfig, ExportFormat, ExportMode, ExportParams, } from './types';
@@ -1,2 +1,2 @@
1
- const e=/* @__PURE__ */new WeakMap;function t(t,r,n=-1){if(!r.valueAccessor)return t?.[r.field];if("object"!=typeof t||null===t)return r.valueAccessor({row:t,column:r,rowIndex:n});const o=r.field;let s=e.get(t);if(s){if(s.has(o))return s.get(o)}else s=/* @__PURE__ */new Map,e.set(t,s);const i=r.valueAccessor({row:t,column:r,rowIndex:n});return s.set(o,i),i}function r(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function n(e,t,n,o){return`${r(n,o)} ${e}: ${t}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(e)}`}const o="__otorp__|__retteGenifed__|__retteSenifed__|rotcurtsnoc|wodniw|sihTlabolg|labolg|ssecorp|noitcnuF|tropmi|lave|tcelfeR|yxorP|rorrE|stnemugra|tnemucod|noitacol|eikooc|egarotSlacol|egarotSnoisses|BDdexedni|hctef|tseuqeRpttHLMX|tekcoSbeW|rekroW|rekroWderahS|rekroWecivreS|renepo|tnerap|pot|semarf|fles".split("|").map(e=>e.split("").reverse().join(""));new RegExp(`__(proto|defineGetter|defineSetter)|${o.slice(3).join("|")}|this\\b`);const s=new Set("script|iframe|object|embed|form|input|button|textarea|select|link|meta|base|style|template|slot|portal|frame|frameset|applet|noscript|noembed|plaintext|xmp|listing".split("|")),i=/^on\w+$/i,l=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),a=/^\s*(javascript|vbscript|data|blob):/i;function c(e){if(!e||"string"!=typeof e)return"";if(-1===e.indexOf("<"))return e;const t=document.createElement("template");return t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const n of r){const e=n.tagName.toLowerCase();if(s.has(e)){t.push(n);continue}if("svg"===e||"http://www.w3.org/2000/svg"===n.namespaceURI){if(Array.from(n.attributes).some(e=>i.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(n);continue}}const r=[];for(const t of n.attributes){const e=t.name.toLowerCase();i.test(e)?r.push(t.name):(l.has(e)&&a.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name)}r.forEach(e=>n.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content),t.innerHTML}const u='<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>',d={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:u,filterActive:u,print:"🖨️"};class f{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#e;get defaultConfig(){return{}}constructor(e={}){this.userConfig=e}attach(e){this.#e?.abort(),this.#e=new AbortController,this.grid=e,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#e?.abort(),this.#e=void 0}getPlugin(e){return this.grid?.getPlugin(e)}emit(e,t){this.grid?.dispatchEvent?.(new CustomEvent(e,{detail:t,bubbles:!0}))}emitCancelable(e,t){const r=new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(r),r.defaultPrevented}on(e,t){this.grid?._pluginManager?.subscribe(this,e,t)}off(e){this.grid?._pluginManager?.unsubscribe(this,e)}emitPluginEvent(e,t){this.grid?._pluginManager?.emitPluginEvent(e,t)}broadcast(e,t){this.emitPluginEvent(e,t),this.emit(e,t)}requestRender(){this.grid?.requestRender?.()}requestColumnsRender(){this.grid?.requestColumnsRender?.()}requestRenderWithFocus(){this.grid?.requestRenderWithFocus?.()}requestAfterRender(){this.grid?.requestAfterRender?.()}requestVirtualRefresh(){this.grid?.requestVirtualRefresh?.()}get rows(){return this.grid?.rows??[]}get sourceRows(){return this.grid?.sourceRows??[]}get columns(){return this.grid?.columns??[]}get visibleColumns(){return this.grid?._visibleColumns??[]}get gridElement(){return this.grid?._hostElement}get disconnectSignal(){return this.#e?.signal??this.grid?.disconnectSignal}get gridIcons(){const e=this.grid?.gridConfig?.icons??{};return{...d,...e}}get isAnimationEnabled(){const e=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===e||"off"===e)return!1;if(!0===e||"on"===e)return!0;const t=this.gridElement;if(t){return"0"!==getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const e=this.gridElement;if(e){const t=getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(),r=parseInt(t,10);if(!isNaN(r))return r}return 200}setIcon(e,t,r){e.dataset.icon=t.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===t?e.dataset.expanded="":"expand"===t&&delete e.dataset.expanded;const n=this.#t(t,r);void 0!==n?"string"==typeof n?e.innerHTML=c(n):n instanceof HTMLElement&&(e.innerHTML="",e.appendChild(n.cloneNode(!0))):e.innerHTML=""}#t(e,t){return void 0!==t?t:this.grid?.gridConfig?.icons?.[e]}updateSortIndicator(e,t){e.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove();const r=document.createElement("span");r.setAttribute("part","sort-indicator"),r.className="sort-indicator",t?(e.setAttribute("aria-sort","asc"===t?"ascending":"descending"),e.setAttribute("data-sort",t),this.setIcon(r,"asc"===t?"sortAsc":"sortDesc")):(e.setAttribute("aria-sort","none"),e.removeAttribute("data-sort"),this.setIcon(r,"sortNone"));const n=e.querySelector(".tbw-filter-btn")??e.querySelector(".resize-handle");return n?e.insertBefore(r,n):e.appendChild(r),r}warn(e,t){void 0!==t?console.warn(n(e,t,this.gridElement.id,this.name)):console.warn(`${r(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(e,t){throw new Error(n(e,t,this.gridElement.id,this.name))}}function g(e,t){return t?.length?[...t].sort((e,t)=>e-t).map(t=>e[t]).filter(e=>null!=e):e}function h(e,t=!0){if(null==e)return"";if(e instanceof Date)return e.toISOString();if("object"==typeof e)return JSON.stringify(e);const r=String(e);return t&&(r.includes(",")||r.includes('"')||r.includes("\n")||r.includes("\r"))?`"${r.replace(/"/g,'""')}"`:r}function m(e,t){const r=URL.createObjectURL(e),n=document.createElement("a");n.href=r,n.download=t,n.style.display="none",document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(r)}function p(e){return JSON.stringify(b(e))}function b(e){if(null==e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map(b);const t={};for(const r of Object.keys(e).sort())t[r]=b(e[r]);return t}class y{#r=/* @__PURE__ */new Map;#n=0;register(e){const t=p(e),r=this.#r.get(t);if(r)return r.id;this.#n++;const n=`s${this.#n}`;return this.#r.set(t,{id:n,style:e}),n}getStyleId(e){return this.#r.get(p(e))?.id}get size(){return this.#r.size}toXml(){if(0===this.#r.size)return"";let e="\n<Styles>";for(const{id:t,style:r}of this.#r.values())e+=S(t,r);return e+="\n</Styles>",e}}function S(e,t){let r=`\n<Style ss:ID="${e}">`;if(t.font&&(r+="<Font",t.font.name&&(r+=` ss:FontName="${t.font.name}"`),t.font.size&&(r+=` ss:Size="${t.font.size}"`),t.font.bold&&(r+=' ss:Bold="1"'),t.font.italic&&(r+=' ss:Italic="1"'),t.font.color&&(r+=` ss:Color="${t.font.color}"`),r+="/>"),t.fill){const e=t.fill.pattern??"Solid";r+=`<Interior ss:Color="${t.fill.color}" ss:Pattern="${e}"/>`}return t.numberFormat&&(r+=`<NumberFormat ss:Format="${t.numberFormat}"/>`),t.alignment&&(r+="<Alignment",t.alignment.horizontal&&(r+=` ss:Horizontal="${t.alignment.horizontal}"`),t.alignment.vertical&&(r+=` ss:Vertical="${t.alignment.vertical}"`),t.alignment.wrapText&&(r+=' ss:WrapText="1"'),r+="/>"),t.borders&&(r+="<Borders>",t.borders.top&&(r+=w("Top",t.borders.top)),t.borders.bottom&&(r+=w("Bottom",t.borders.bottom)),t.borders.left&&(r+=w("Left",t.borders.left)),t.borders.right&&(r+=w("Right",t.borders.right)),r+="</Borders>"),r+="</Style>",r}function w(e,t){let r=`<Border ss:Position="${e}" ss:LineStyle="Continuous" ss:Weight="${function(e){switch(e){case"Thin":return 1;case"Medium":return 2;case"Thick":return 3}}(t.style)}"`;return t.color&&(r+=` ss:Color="${t.color}"`),r+="/>",r}function v(e,t,r,n,o){if(t.cellStyle){const s=t.cellStyle(r,n,o);if(s)return e.register(s)}const s=t.columnStyles?.[n];return s?e.getStyleId(s):t.defaultStyle?e.getStyleId(t.defaultStyle):void 0}function x(e,t){const r=Math.min(t.length,50);let n=(e.header??e.field).length;for(let o=0;o<r;o++){const r=t[o][e.field],s=null==r?0:String(r).length;s>n&&(n=s)}return n+2}function C(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function E(e,r,n){const o=n.excelStyles,s=o?function(e){const t=new y;if(e.headerStyle&&t.register(e.headerStyle),e.defaultStyle&&t.register(e.defaultStyle),e.columnStyles)for(const r of Object.values(e.columnStyles))t.register(r);return t}(o):void 0;let i='<?xml version="1.0" encoding="UTF-8"?>\n<?mso-application progid="Excel.Sheet"?>\n<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"\n xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">';if(s){if(o.cellStyle)for(const n of e)for(const e of r){const r=t(n,e),i=o.cellStyle(r,e.field,n);i&&s.register(i)}i+=s.toXml()}i+='\n<Worksheet ss:Name="Sheet1">\n<Table>',o&&(i+=function(e,t,r){const n=r.columnWidths,o=r.autoFitColumns;if(!n&&!o)return"";let s="";for(const i of e){let e=n?.[i.field];null==e&&o&&(e=x(i,t)),s+=null!=e?`\n<Column ss:Width="${7*e}"/>`:"\n<Column/>"}return s}(r,e,o));const l=o?.headerStyle&&s?s.getStyleId(o.headerStyle):void 0;if(!1!==n.includeHeaders){i+="\n<Row>";for(const e of r){const t=e.header||e.field;i+=`<Cell${l?` ss:StyleID="${l}"`:""}><Data ss:Type="String">${C(n.processHeader?n.processHeader(t,e.field):t)}</Data></Cell>`}i+="</Row>"}for(const a of e){i+="\n<Row>";for(const e of r){let r=t(a,e);n.processCell&&(r=n.processCell(r,e.field,a));let l="String",c="";null==r?c="":"number"!=typeof r||isNaN(r)?r instanceof Date?(l="DateTime",c=r.toISOString()):c=C(String(r)):(l="Number",c=String(r));const u=s&&o?v(s,o,r,e.field,a):void 0;i+=`<Cell${u?` ss:StyleID="${u}"`:""}><Data ss:Type="${l}">${c}</Data></Cell>`}i+="</Row>"}return i+="\n</Table>\n</Worksheet>\n</Workbook>",i}class $ extends f{static manifest={queries:[{type:"export:csv",description:"Triggers a CSV export"}]};name="export";get defaultConfig(){return{fileName:"export",includeHeaders:!0,onlyVisible:!0,onlySelected:!1}}isExportingFlag=!1;lastExportInfo=null;handleQuery(e){if("export:csv"===e.type)return this.exportCsv(),!0}performExport(e,r){const n=this.config,o={format:e,fileName:r?.fileName??n.fileName??"export",includeHeaders:r?.includeHeaders??n.includeHeaders,processCell:r?.processCell,processHeader:r?.processHeader,columns:r?.columns,rowIndices:r?.rowIndices,excelStyles:r?.excelStyles,fileExtension:r?.fileExtension},s=function(e,t,r=!0){let n=e;if(r&&(n=n.filter(e=>!e.hidden&&!e.field.startsWith("__")&&!0!==e.utility)),t?.length){const e=new Set(t);n=n.filter(t=>e.has(t.field))}return n}(this.columns,r?.columns,n.onlyVisible);let i;if(r?.rowIndices)i=g(this.rows,r.rowIndices);else if(n.onlySelected){const e=this.getSelectionState();i=e?.selected?.size?g(this.rows,[...e.selected]):[...this.rows]}else i=[...this.rows];this.isExportingFlag=!0;let l=o.fileName;try{switch(e){case"csv":{const e=function(e,r,n,o={}){const s=o.delimiter??",",i=o.newline??"\n",l=[],a=o.bom?"\ufeff":"";if(!1!==n.includeHeaders){const e=r.map(e=>{const t=e.header||e.field;return h(n.processHeader?n.processHeader(t,e.field):t)});l.push(e.join(s))}for(const c of e){const e=r.map(e=>{let r=t(c,e);return n.processCell&&(r=n.processCell(r,e.field,c)),h(r)});l.push(e.join(s))}return a+l.join(i)}(i,s,o,{bom:!0});l=l.endsWith(".csv")?l:`${l}.csv`,function(e,t){m(new Blob([e],{type:"text/csv;charset=utf-8;"}),t)}(e,l);break}case"excel":{const e=E(i,s,o),t=o.fileExtension??".xls",r=t.startsWith(".")?t:`.${t}`;l=l.endsWith(r)?l:`${l}${r}`,function(e,t){m(new Blob([e],{type:"application/vnd.ms-excel;charset=utf-8;"}),t)}(e,l);break}case"json":{const e=i.map(e=>{const r={};for(const n of s){let s=t(e,n);o.processCell&&(s=o.processCell(s,n.field,e)),r[n.field]=s}return r}),r=JSON.stringify(e,null,2);l=l.endsWith(".json")?l:`${l}.json`;m(new Blob([r],{type:"application/json"}),l);break}}this.lastExportInfo={format:e,timestamp:/* @__PURE__ */new Date},this.emit("export-complete",{format:e,fileName:l,rowCount:i.length,columnCount:s.length})}finally{this.isExportingFlag=!1}}getSelectionState(){try{return this.grid?.getPluginState?.("selection")??null}catch{return null}}exportCsv(e){this.performExport("csv",e)}exportExcel(e){this.performExport("excel",e)}exportJson(e){this.performExport("json",e)}isExporting(){return this.isExportingFlag}getLastExport(){return this.lastExportInfo}}export{$ as ExportPlugin};
1
+ const e=/* @__PURE__ */new WeakMap;function t(t,r,n=-1){if(!r.valueAccessor)return t?.[r.field];if("object"!=typeof t||null===t)return r.valueAccessor({row:t,column:r,rowIndex:n});const o=r.field;let s=e.get(t);if(s){if(s.has(o))return s.get(o)}else s=/* @__PURE__ */new Map,e.set(t,s);const i=r.valueAccessor({row:t,column:r,rowIndex:n});return s.set(o,i),i}function r(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function n(e,t,n,o){return`${r(n,o)} ${e}: ${t}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(e)}`}const o="__otorp__|__retteGenifed__|__retteSenifed__|rotcurtsnoc|wodniw|sihTlabolg|labolg|ssecorp|noitcnuF|tropmi|lave|tcelfeR|yxorP|rorrE|stnemugra|tnemucod|noitacol|eikooc|egarotSlacol|egarotSnoisses|BDdexedni|hctef|tseuqeRpttHLMX|tekcoSbeW|rekroW|rekroWderahS|rekroWecivreS|renepo|tnerap|pot|semarf|fles".split("|").map(e=>e.split("").reverse().join(""));new RegExp(`__(proto|defineGetter|defineSetter)|${o.slice(3).join("|")}|this\\b`);const s=new Set("script|iframe|object|embed|form|input|button|textarea|select|link|meta|base|style|template|slot|portal|frame|frameset|applet|noscript|noembed|plaintext|xmp|listing".split("|")),i=/^on\w+$/i,l=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),a=/^\s*(javascript|vbscript|data|blob):/i;function c(e){if(!e||"string"!=typeof e)return"";if(-1===e.indexOf("<"))return e;const t=document.createElement("template");return t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const n of r){const e=n.tagName.toLowerCase();if(s.has(e)){t.push(n);continue}if("svg"===e||"http://www.w3.org/2000/svg"===n.namespaceURI){if(Array.from(n.attributes).some(e=>i.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(n);continue}}const r=[];for(const t of n.attributes){const e=t.name.toLowerCase();i.test(e)?r.push(t.name):(l.has(e)&&a.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name)}r.forEach(e=>n.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content),t.innerHTML}const u={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:"",filterActive:"",print:"🖨️"};class f{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#e;get defaultConfig(){return{}}constructor(e={}){this.userConfig=e}mergeConfigsFrom(e){if(0===e.length)return;const t={...this.userConfig},r={};for(const n of Object.keys(t))r[n]=this;for(const o of e){const e=o.userConfig;for(const[s,i]of Object.entries(e)){if(void 0===i)continue;if(!(s in t)){t[s]=i,r[s]=o;continue}if(t[s]===i)continue;const e=r[s]?.constructor.name??this.constructor.name,l=o.constructor.name,a=n("TBW025",`Cannot merge plugin configs for "${this.name}": conflicting value for "${s}" supplied by both ${e} and ${l}. Pass the option on a single instance, or remove the duplicate.`,void 0,this.name);throw new Error(a)}}Object.assign(this.userConfig,t)}attach(e){this.#e?.abort(),this.#e=new AbortController,this.grid=e,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#e?.abort(),this.#e=void 0}getPlugin(e){return this.grid?.getPlugin(e)}emit(e,t){this.grid?.dispatchEvent?.(new CustomEvent(e,{detail:t,bubbles:!0}))}emitCancelable(e,t){const r=new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(r),r.defaultPrevented}on(e,t){this.grid?._pluginManager?.subscribe(this,e,t)}off(e){this.grid?._pluginManager?.unsubscribe(this,e)}emitPluginEvent(e,t){this.grid?._pluginManager?.emitPluginEvent(e,t)}broadcast(e,t){this.emitPluginEvent(e,t),this.emit(e,t)}requestRender(){this.grid?.requestRender?.()}requestColumnsRender(){this.grid?.requestColumnsRender?.()}requestRenderWithFocus(){this.grid?.requestRenderWithFocus?.()}requestAfterRender(){this.grid?.requestAfterRender?.()}requestVirtualRefresh(){this.grid?.requestVirtualRefresh?.()}get rows(){return this.grid?.rows??[]}get sourceRows(){return this.grid?.sourceRows??[]}get columns(){return this.grid?.columns??[]}get visibleColumns(){return this.grid?._visibleColumns??[]}get gridElement(){return this.grid?._hostElement}get disconnectSignal(){return this.#e?.signal??this.grid?.disconnectSignal}get gridIcons(){const e=this.grid?.gridConfig?.icons??{};return{...u,...e}}get isAnimationEnabled(){const e=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===e||"off"===e)return!1;if(!0===e||"on"===e)return!0;const t=this.gridElement;if(t){return"0"!==getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const e=this.gridElement;if(e){const t=getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(),r=parseInt(t,10);if(!isNaN(r))return r}return 200}setIcon(e,t,r){e.dataset.icon=t.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===t?e.dataset.expanded="":"expand"===t&&delete e.dataset.expanded;const n=this.#t(t,r);void 0!==n?"string"==typeof n?e.innerHTML=c(n):n instanceof HTMLElement&&(e.innerHTML="",e.appendChild(n.cloneNode(!0))):e.innerHTML=""}#t(e,t){return void 0!==t?t:this.grid?.gridConfig?.icons?.[e]}updateSortIndicator(e,t){e.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove();const r=document.createElement("span");r.setAttribute("part","sort-indicator"),r.className="sort-indicator",t?(e.setAttribute("aria-sort","asc"===t?"ascending":"descending"),e.setAttribute("data-sort",t),this.setIcon(r,"asc"===t?"sortAsc":"sortDesc")):(e.setAttribute("aria-sort","none"),e.removeAttribute("data-sort"),this.setIcon(r,"sortNone"));const n=e.querySelector(".tbw-filter-btn")??e.querySelector(".resize-handle");return n?e.insertBefore(r,n):e.appendChild(r),r}warn(e,t){void 0!==t?console.warn(n(e,t,this.gridElement.id,this.name)):console.warn(`${r(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(e,t){throw new Error(n(e,t,this.gridElement.id,this.name))}}function d(e,t,r=!0){let n=e;if(r&&(n=n.filter(e=>!e.hidden&&!e.field.startsWith("__")&&!0!==e.utility)),t?.length){const e=new Set(t);n=n.filter(t=>e.has(t.field))}return n}function m(e,t){return t?.length?[...t].sort((e,t)=>e-t).map(t=>e[t]).filter(e=>null!=e):e}function p(e,t=!0){if(null==e)return"";if(e instanceof Date)return e.toISOString();if("object"==typeof e)return JSON.stringify(e);const r=String(e);return t&&(r.includes(",")||r.includes('"')||r.includes("\n")||r.includes("\r"))?`"${r.replace(/"/g,'""')}"`:r}function g(e,r,n,o={}){const s=o.delimiter??",",i=o.newline??"\n",l=o.quoteStrings??!0,a=[],c=o.bom?"\ufeff":"";if(!1!==n.includeHeaders){const e=r.map(e=>{const t=e.header||e.field;return p(n.processHeader?n.processHeader(t,e.field):t,l)});a.push(e.join(s))}for(const u of e){const e=r.map(e=>{let r=t(u,e);return n.processCell&&(r=n.processCell(r,e.field,u)),p(r,l)});a.push(e.join(s))}return c+a.join(i)}function h(e,t){const r=URL.createObjectURL(e),n=document.createElement("a");n.href=r,n.download=t,n.style.display="none",document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(r)}function b(e){return JSON.stringify(y(e))}function y(e){if(null==e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map(y);const t={};for(const r of Object.keys(e).sort())t[r]=y(e[r]);return t}class v{#r=/* @__PURE__ */new Map;#n=0;register(e){const t=b(e),r=this.#r.get(t);if(r)return r.id;this.#n++;const n=`s${this.#n}`;return this.#r.set(t,{id:n,style:e}),n}getStyleId(e){return this.#r.get(b(e))?.id}get size(){return this.#r.size}toXml(){if(0===this.#r.size)return"";let e="\n<Styles>";for(const{id:t,style:r}of this.#r.values())e+=S(t,r);return e+="\n</Styles>",e}}function S(e,t){let r=`\n<Style ss:ID="${e}">`;if(t.font&&(r+="<Font",t.font.name&&(r+=` ss:FontName="${t.font.name}"`),t.font.size&&(r+=` ss:Size="${t.font.size}"`),t.font.bold&&(r+=' ss:Bold="1"'),t.font.italic&&(r+=' ss:Italic="1"'),t.font.color&&(r+=` ss:Color="${t.font.color}"`),r+="/>"),t.fill){const e=t.fill.pattern??"Solid";r+=`<Interior ss:Color="${t.fill.color}" ss:Pattern="${e}"/>`}return t.numberFormat&&(r+=`<NumberFormat ss:Format="${t.numberFormat}"/>`),t.alignment&&(r+="<Alignment",t.alignment.horizontal&&(r+=` ss:Horizontal="${t.alignment.horizontal}"`),t.alignment.vertical&&(r+=` ss:Vertical="${t.alignment.vertical}"`),t.alignment.wrapText&&(r+=' ss:WrapText="1"'),r+="/>"),t.borders&&(r+="<Borders>",t.borders.top&&(r+=x("Top",t.borders.top)),t.borders.bottom&&(r+=x("Bottom",t.borders.bottom)),t.borders.left&&(r+=x("Left",t.borders.left)),t.borders.right&&(r+=x("Right",t.borders.right)),r+="</Borders>"),r+="</Style>",r}function x(e,t){let r=`<Border ss:Position="${e}" ss:LineStyle="Continuous" ss:Weight="${function(e){switch(e){case"Thin":return 1;case"Medium":return 2;case"Thick":return 3}}(t.style)}"`;return t.color&&(r+=` ss:Color="${t.color}"`),r+="/>",r}function w(e,t,r,n,o){if(t.cellStyle){const s=t.cellStyle(r,n,o);if(s)return e.register(s)}const s=t.columnStyles?.[n];return s?e.getStyleId(s):t.defaultStyle?e.getStyleId(t.defaultStyle):void 0}function C(e,t){const r=Math.min(t.length,50);let n=(e.header??e.field).length;for(let o=0;o<r;o++){const r=t[o][e.field],s=null==r?0:String(r).length;s>n&&(n=s)}return n+2}function E(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function $(e,r,n){const o=n.excelStyles,s=o?function(e){const t=new v;if(e.headerStyle&&t.register(e.headerStyle),e.defaultStyle&&t.register(e.defaultStyle),e.columnStyles)for(const r of Object.values(e.columnStyles))t.register(r);return t}(o):void 0;let i='<?xml version="1.0" encoding="UTF-8"?>\n<?mso-application progid="Excel.Sheet"?>\n<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"\n xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">';if(s){if(o.cellStyle)for(const n of e)for(const e of r){const r=t(n,e),i=o.cellStyle(r,e.field,n);i&&s.register(i)}i+=s.toXml()}i+='\n<Worksheet ss:Name="Sheet1">\n<Table>',o&&(i+=function(e,t,r){const n=r.columnWidths,o=r.autoFitColumns;if(!n&&!o)return"";let s="";for(const i of e){let e=n?.[i.field];null==e&&o&&(e=C(i,t)),s+=null!=e?`\n<Column ss:Width="${7*e}"/>`:"\n<Column/>"}return s}(r,e,o));const l=o?.headerStyle&&s?s.getStyleId(o.headerStyle):void 0;if(!1!==n.includeHeaders){i+="\n<Row>";for(const e of r){const t=e.header||e.field;i+=`<Cell${l?` ss:StyleID="${l}"`:""}><Data ss:Type="String">${E(n.processHeader?n.processHeader(t,e.field):t)}</Data></Cell>`}i+="</Row>"}for(const a of e){i+="\n<Row>";for(const e of r){let r=t(a,e);n.processCell&&(r=n.processCell(r,e.field,a));let l="String",c="";null==r?c="":"number"!=typeof r||isNaN(r)?r instanceof Date?(l="DateTime",c=r.toISOString()):c=E(String(r)):(l="Number",c=String(r));const u=s&&o?w(s,o,r,e.field,a):void 0;i+=`<Cell${u?` ss:StyleID="${u}"`:""}><Data ss:Type="${l}">${c}</Data></Cell>`}i+="</Row>"}return i+="\n</Table>\n</Worksheet>\n</Workbook>",i}class D extends f{static manifest={queries:[{type:"export:csv",description:"Triggers a CSV export"}]};name="export";get defaultConfig(){return{fileName:"export",includeHeaders:!0,onlyVisible:!0,onlySelected:!1}}isExportingFlag=!1;lastExportInfo=null;handleQuery(e){if("export:csv"===e.type)return this.exportCsv(),!0}resolveExportData(e,t){const r=this.config,n={format:e,fileName:t?.fileName??r.fileName??"export",includeHeaders:t?.includeHeaders??r.includeHeaders,processCell:t?.processCell,processHeader:t?.processHeader,mode:t?.mode??"raw",columns:t?.columns,rowIndices:t?.rowIndices,excelStyles:t?.excelStyles,fileExtension:t?.fileExtension},o=d(this.columns,t?.columns,r.onlyVisible);let s;if(t?.rowIndices)s=m(this.rows,t.rowIndices);else if(r.onlySelected){const e=this.getSelectionState();s=e?.selected?.size?m(this.rows,[...e.selected]):[...this.rows]}else s=[...this.rows];return{columns:o,rows:s,fullParams:n}}resolveCellOutput(e,t,r,n,o){let s=e;if("formatted"===n){const n=this.#o(t);if(n)try{const t=n(e,r);s=null==t?"":String(t)}catch{s=null==e?"":String(e)}else s="date"===t.type?function(e){if(null==e||""===e)return"";if(e instanceof Date)return isNaN(e.getTime())?"":e.toLocaleDateString();if("number"==typeof e||"string"==typeof e){const t=new Date(e);return isNaN(t.getTime())?"":t.toLocaleDateString()}return""}(e):"boolean"===t.type?!!e:e}return o&&(s=o(s,t.field,r)),s}performExport(e,t){const{columns:r,rows:n,fullParams:o}=this.resolveExportData(e,t);this.isExportingFlag=!0;let s=o.fileName??"export";const i=this.#s(r);try{switch(e){case"csv":{const e=g(this.#i(n,r,o),i,{...o,processCell:void 0},{bom:!0});s=s.endsWith(".csv")?s:`${s}.csv`,function(e,t){h(new Blob([e],{type:"text/csv;charset=utf-8;"}),t)}(e,s);break}case"excel":{const e=$(this.#i(n,r,o),i,{...o,processCell:void 0}),t=o.fileExtension??".xls",l=t.startsWith(".")?t:`.${t}`;s=s.endsWith(l)?s:`${s}${l}`,function(e,t){h(new Blob([e],{type:"application/vnd.ms-excel;charset=utf-8;"}),t)}(e,s);break}case"json":{const e=this.#i(n,r,o),t=JSON.stringify(e,null,2);s=s.endsWith(".json")?s:`${s}.json`;h(new Blob([t],{type:"application/json"}),s);break}}this.lastExportInfo={format:e,timestamp:/* @__PURE__ */new Date},this.emit("export-complete",{format:e,fileName:s,rowCount:n.length,columnCount:r.length})}finally{this.isExportingFlag=!1}}#i(e,r,n){const o=n.mode??"raw";return e.map(e=>{const s={};for(const i of r){const r=t(e,i);s[i.field]=this.resolveCellOutput(r,i,e,o,n.processCell)}return s})}getSelectionState(){try{return this.grid?.getPluginState?.("selection")??null}catch{return null}}export(e){const{columns:t,rows:r,fullParams:n}=this.resolveExportData("json",e);return this.#i(r,t,n)}getResolvedColumns(e){return d(this.columns,e?.columns,this.config.onlyVisible)}formatCsv(e,t,r){const{columns:n,fullParams:o}=this.resolveExportData("csv",t);return g(e,this.#s(n),o,r)}formatExcel(e,t){const{columns:r,fullParams:n}=this.resolveExportData("excel",t);return $(e,this.#s(r),n)}#s(e){return e.map(e=>e.valueAccessor?{...e,valueAccessor:void 0}:e)}#o(e){if(e.format)return e.format;if(!e.type)return;const t=this.grid,r=t?.__frameworkAdapter;if(!r?.getTypeDefault)return;const n=r.getTypeDefault(e.type,t?._hostElement);return n?.format}exportCsv(e){this.performExport("csv",e)}exportExcel(e){this.performExport("excel",e)}exportJson(e){this.performExport("json",e)}isExporting(){return this.isExportingFlag}getLastExport(){return this.lastExportInfo}}export{D as ExportPlugin};
2
2
  //# sourceMappingURL=index.js.map