@toolbox-web/grid 2.0.0-rc.1 → 2.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -6
- package/all.js +2 -2
- package/all.js.map +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/lib/core/internal/sorting.d.ts +4 -0
- package/lib/core/plugin/base-plugin.d.ts +31 -0
- package/lib/core/plugin/plugin-manager.d.ts +4 -1
- package/lib/core/plugin/types.d.ts +2 -0
- package/lib/core/types.d.ts +20 -1
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts +8 -1
- package/lib/plugins/clipboard/index.js +1 -1
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +1 -1
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/index.js +1 -1
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/export/ExportPlugin.d.ts +8 -1
- package/lib/plugins/export/index.js +1 -1
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +1 -1
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js +1 -1
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +33 -1
- package/lib/plugins/grouping-rows/grouping-rows.d.ts +15 -1
- package/lib/plugins/grouping-rows/index.js +2 -2
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +1 -1
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +1 -1
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js +1 -1
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +1 -1
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/PivotPlugin.d.ts +10 -0
- package/lib/plugins/pivot/index.js +1 -1
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/print/index.js +1 -1
- package/lib/plugins/print/index.js.map +1 -1
- package/lib/plugins/reorder-columns/index.js +1 -1
- package/lib/plugins/reorder-columns/index.js.map +1 -1
- package/lib/plugins/reorder-rows/RowReorderPlugin.d.ts +3 -0
- package/lib/plugins/reorder-rows/index.js +1 -1
- package/lib/plugins/reorder-rows/index.js.map +1 -1
- package/lib/plugins/responsive/index.js +1 -1
- package/lib/plugins/responsive/index.js.map +1 -1
- package/lib/plugins/selection/index.js +1 -1
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tooltip/index.js +1 -1
- package/lib/plugins/tooltip/index.js.map +1 -1
- package/lib/plugins/tree/TreePlugin.d.ts +16 -0
- package/lib/plugins/tree/index.js +1 -1
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/tree/types.d.ts +6 -0
- package/lib/plugins/undo-redo/index.js +1 -1
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +1 -1
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +1 -1
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +1 -1
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/clipboard.umd.js +1 -1
- package/umd/plugins/clipboard.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/editing.umd.js +1 -1
- package/umd/plugins/editing.umd.js.map +1 -1
- package/umd/plugins/export.umd.js +1 -1
- package/umd/plugins/export.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/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- package/umd/plugins/pinned-columns.umd.js +1 -1
- package/umd/plugins/pinned-columns.umd.js.map +1 -1
- package/umd/plugins/pivot.umd.js +1 -1
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/reorder-rows.umd.js +1 -1
- package/umd/plugins/reorder-rows.umd.js.map +1 -1
- package/umd/plugins/selection.umd.js +1 -1
- package/umd/plugins/selection.umd.js.map +1 -1
- package/umd/plugins/server-side.umd.js +1 -1
- package/umd/plugins/server-side.umd.js.map +1 -1
- package/umd/plugins/tooltip.umd.js +1 -1
- package/umd/plugins/tooltip.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
|
@@ -74,5 +74,9 @@ export declare function reapplyCoreSort<T>(grid: InternalGrid<T>, rows: T[]): T[
|
|
|
74
74
|
*
|
|
75
75
|
* Uses custom sortHandler from gridConfig if provided, otherwise uses built-in sorting.
|
|
76
76
|
* Supports both sync and async handlers (for server-side sorting).
|
|
77
|
+
*
|
|
78
|
+
* When row-model plugins are active (grouping, tree, pivot), delegates to the render
|
|
79
|
+
* scheduler so the full pipeline (reapplyCoreSort → processRows) runs on base rows.
|
|
80
|
+
* This prevents sorting from corrupting plugin-generated row structures.
|
|
77
81
|
*/
|
|
78
82
|
export declare function applySort(grid: GridHost, col: ColumnConfig<any>, dir: 1 | -1): void;
|
|
@@ -274,6 +274,18 @@ export interface PluginManifest<TConfig = unknown> {
|
|
|
274
274
|
* ```
|
|
275
275
|
*/
|
|
276
276
|
events?: EventDefinition[];
|
|
277
|
+
/**
|
|
278
|
+
* Whether this plugin's `processRows` hook injects or removes rows
|
|
279
|
+
* (group headers, tree nodes, pivot aggregates, placeholders, etc.).
|
|
280
|
+
*
|
|
281
|
+
* When true, the core sorting module delegates to the render scheduler
|
|
282
|
+
* instead of sorting `_rows` in-place, because `_rows` may contain
|
|
283
|
+
* plugin-generated marker objects that would be corrupted by a direct sort.
|
|
284
|
+
*
|
|
285
|
+
* Plugins that only **filter** or **reorder** existing rows (e.g. Filtering,
|
|
286
|
+
* MultiSort) should leave this unset or set it to `false`.
|
|
287
|
+
*/
|
|
288
|
+
modifiesRowStructure?: boolean;
|
|
277
289
|
}
|
|
278
290
|
/** Convert camelCase icon key to kebab-case data-icon attribute value. */
|
|
279
291
|
export declare function toIconAttr(key: string): string;
|
|
@@ -496,6 +508,25 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> implements GridP
|
|
|
496
508
|
* ```
|
|
497
509
|
*/
|
|
498
510
|
protected emitPluginEvent<T>(eventType: string, detail: T): void;
|
|
511
|
+
/**
|
|
512
|
+
* Emit an event to **both** the plugin Event Bus (for inter-plugin communication)
|
|
513
|
+
* **and** the DOM (for external consumers via `addEventListener`).
|
|
514
|
+
*
|
|
515
|
+
* Use this when a state change is relevant to both other plugins and external
|
|
516
|
+
* consumers. For example, `sort-change` needs to invalidate Selection (plugin bus)
|
|
517
|
+
* and notify the host application (DOM event).
|
|
518
|
+
*
|
|
519
|
+
* @category Plugin Development
|
|
520
|
+
* @param eventType - The event type to broadcast
|
|
521
|
+
* @param detail - The event payload
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```typescript
|
|
525
|
+
* // Notify both plugins and consumers of a sort change
|
|
526
|
+
* this.broadcast('sort-change', { sortModel: [...this.sortModel] });
|
|
527
|
+
* ```
|
|
528
|
+
*/
|
|
529
|
+
protected broadcast<T>(eventType: string, detail: T): void;
|
|
499
530
|
/**
|
|
500
531
|
* Request a re-render of the grid.
|
|
501
532
|
* Uses ROWS phase - does NOT trigger processColumns hooks.
|
|
@@ -24,7 +24,10 @@ export declare class PluginManager {
|
|
|
24
24
|
/** Cached hook presence flags — invalidated on plugin attach/detach */
|
|
25
25
|
private _hasAfterCellRender;
|
|
26
26
|
private _hasAfterRowRender;
|
|
27
|
-
|
|
27
|
+
/** Whether any plugin has a processRows hook. */
|
|
28
|
+
_hasProcessRows: boolean;
|
|
29
|
+
/** Whether any plugin with `modifiesRowStructure` is attached. Exposed for the sorting module. */
|
|
30
|
+
_hasRowStructurePlugins: boolean;
|
|
28
31
|
/**
|
|
29
32
|
* Event listeners indexed by event type.
|
|
30
33
|
* Maps event type → Map<plugin instance → callback>.
|
|
@@ -329,6 +329,8 @@ export interface GridElementRef {
|
|
|
329
329
|
subscribe(plugin: unknown, eventType: string, callback: (detail: unknown) => void): void;
|
|
330
330
|
unsubscribe(plugin: unknown, eventType: string): void;
|
|
331
331
|
emitPluginEvent<T>(eventType: string, detail: T): void;
|
|
332
|
+
/** Whether any attached plugin injects/removes rows (group headers, tree nodes, etc.). */
|
|
333
|
+
_hasRowStructurePlugins: boolean;
|
|
332
334
|
};
|
|
333
335
|
/**
|
|
334
336
|
* Query plugins with a simplified API.
|
package/lib/core/types.d.ts
CHANGED
|
@@ -462,6 +462,10 @@ export interface InternalGrid<T = any> extends PublicGrid<T>, GridConfig<T> {
|
|
|
462
462
|
__hasSpecialColumns?: boolean;
|
|
463
463
|
/** Cached flag for whether any plugin has renderRow hooks. @internal */
|
|
464
464
|
__hasRenderRowPlugins?: boolean;
|
|
465
|
+
/** @internal Access the plugin manager's cached state. */
|
|
466
|
+
_pluginManager?: {
|
|
467
|
+
_hasRowStructurePlugins: boolean;
|
|
468
|
+
};
|
|
465
469
|
_gridTemplate: string;
|
|
466
470
|
_virtualization: VirtualState;
|
|
467
471
|
_focusRow: number;
|
|
@@ -1192,6 +1196,19 @@ export interface CellRenderContext<TRow = any, TValue = any> {
|
|
|
1192
1196
|
field: keyof TRow & string;
|
|
1193
1197
|
/** Column configuration reference. */
|
|
1194
1198
|
column: ColumnConfig<TRow>;
|
|
1199
|
+
/**
|
|
1200
|
+
* The grid element that owns this cell.
|
|
1201
|
+
* Use to access public grid API (e.g., `getPluginByName()`) from custom renderers.
|
|
1202
|
+
*
|
|
1203
|
+
* @example
|
|
1204
|
+
* ```typescript
|
|
1205
|
+
* const renderer: ColumnViewRenderer<MyRow> = (ctx) => {
|
|
1206
|
+
* const tree = ctx.grid?.getPluginByName('tree');
|
|
1207
|
+
* // ...
|
|
1208
|
+
* };
|
|
1209
|
+
* ```
|
|
1210
|
+
*/
|
|
1211
|
+
grid?: DataGridElement;
|
|
1195
1212
|
/**
|
|
1196
1213
|
* The cell DOM element being rendered into.
|
|
1197
1214
|
* Framework adapters can use this to cache per-cell state (e.g., React roots).
|
|
@@ -1433,9 +1450,11 @@ export interface FrameworkAdapter {
|
|
|
1433
1450
|
* Used by Angular's `GridTypeRegistry` and React's `GridTypeProvider`.
|
|
1434
1451
|
*
|
|
1435
1452
|
* @param type - The column type (e.g., 'date', 'currency', 'country')
|
|
1453
|
+
* @param gridEl - The owning `<tbw-grid>` element. Helps adapters resolve
|
|
1454
|
+
* the correct context provider in multi-grid scenarios.
|
|
1436
1455
|
* @returns Type defaults for renderer/editor, or undefined if not registered
|
|
1437
1456
|
*/
|
|
1438
|
-
getTypeDefault?<TRow = unknown>(type: string): TypeDefault<TRow> | undefined;
|
|
1457
|
+
getTypeDefault?<TRow = unknown>(type: string, gridEl?: HTMLElement): TypeDefault<TRow> | undefined;
|
|
1439
1458
|
/**
|
|
1440
1459
|
* Pre-process a grid config before the grid core applies it.
|
|
1441
1460
|
* Framework adapters use this to convert framework-specific component references
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseGridPlugin, GridElement, PluginDependency } from '../../core/plugin/base-plugin';
|
|
1
|
+
import { BaseGridPlugin, GridElement, PluginDependency, PluginManifest, PluginQuery } from '../../core/plugin/base-plugin';
|
|
2
2
|
import { ClipboardConfig, CopyOptions } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Clipboard Plugin for tbw-grid
|
|
@@ -72,6 +72,11 @@ import { ClipboardConfig, CopyOptions } from './types';
|
|
|
72
72
|
*/
|
|
73
73
|
export declare class ClipboardPlugin extends BaseGridPlugin<ClipboardConfig> {
|
|
74
74
|
#private;
|
|
75
|
+
/**
|
|
76
|
+
* Plugin manifest — declares queries for inter-plugin communication.
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
static readonly manifest: PluginManifest;
|
|
75
80
|
/**
|
|
76
81
|
* Plugin dependencies - ClipboardPlugin works best with SelectionPlugin.
|
|
77
82
|
*
|
|
@@ -91,6 +96,8 @@ export declare class ClipboardPlugin extends BaseGridPlugin<ClipboardConfig> {
|
|
|
91
96
|
/** @internal */
|
|
92
97
|
detach(): void;
|
|
93
98
|
/** @internal */
|
|
99
|
+
handleQuery(query: PluginQuery): unknown;
|
|
100
|
+
/** @internal */
|
|
94
101
|
onKeyDown(event: KeyboardEvent): boolean;
|
|
95
102
|
/**
|
|
96
103
|
* Get the text representation of the current selection (or specified data)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function e(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function t(t,n,r,o){return`${e(r,o)} ${t}: ${n}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(t)}`}["__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"].map(e=>e.split("").reverse().join(""));const n=/* @__PURE__ */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"]),r=/^on\w+$/i,o=/* @__PURE__ */new Set(["href","src","action","formaction","data","srcdoc","xlink:href","poster","srcset"]),i=/^\s*(javascript|vbscript|data|blob):/i;function s(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=[],s=e.querySelectorAll("*");for(const l of s){const e=l.tagName.toLowerCase();if(n.has(e)){t.push(l);continue}if("svg"===e||"http://www.w3.org/2000/svg"===l.namespaceURI){if(Array.from(l.attributes).some(e=>r.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(l);continue}}const s=[];for(const t of l.attributes){const e=t.name.toLowerCase();r.test(e)?s.push(t.name):(o.has(e)&&i.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&s.push(t.name)}s.forEach(e=>l.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content),t.innerHTML}const l='<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>',a={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:l,filterActive:l,print:"🖨️"};class c{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 n=new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(n),n.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)}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{...a,...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(),n=parseInt(t,10);if(!isNaN(n))return n}return 200}setIcon(e,t,n){e.dataset.icon=t.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===t?e.dataset.expanded="":"expand"===t&&delete e.dataset.expanded;const r=this.#t(t,n);void 0!==r?"string"==typeof r?e.innerHTML=s(r):r instanceof HTMLElement&&(e.innerHTML="",e.appendChild(r.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 n=document.createElement("span");n.setAttribute("part","sort-indicator"),n.className="sort-indicator",t?(e.setAttribute("aria-sort","asc"===t?"ascending":"descending"),e.setAttribute("data-sort",t),this.setIcon(n,"asc"===t?"sortAsc":"sortDesc")):(e.setAttribute("aria-sort","none"),e.removeAttribute("data-sort"),this.setIcon(n,"sortNone"));const r=e.querySelector(".tbw-filter-btn")??e.querySelector(".resize-handle");return r?e.insertBefore(n,r):e.appendChild(n),n}warn(n,r){void 0!==r?console.warn(t(n,r,this.gridElement.id,this.name)):console.warn(`${e(this.gridElement.id,this.name)} ${n}`)}throwDiagnostic(e,n){throw new Error(t(e,n,this.gridElement.id,this.name))}}function d(e,t,n=!0){let r=e;if(n&&(r=r.filter(e=>!e.hidden&&!e.field.startsWith("__")&&!0!==e.meta?.utility)),t?.length){const e=new Set(t);r=r.filter(t=>e.has(t.field))}return r}async function u(e){try{return await navigator.clipboard.writeText(e),!0}catch(s){n="TBW100",r=`Clipboard API failed: ${s}`,console.warn(t(n,r,o,i));const l=document.createElement("textarea");l.value=e,l.style.position="fixed",l.style.opacity="0",l.style.pointerEvents="none",document.body.appendChild(l),l.select();const a=document.execCommand("copy");return document.body.removeChild(l),a}var n,r,o,i}function h(e,t){const n=t.delimiter??"\t",r=t.newline??"\n",o=e.replace(/\r\n/g,"\n").replace(/\r/g,"\n"),i=[];let s=[],l="",a=!1;for(let c=0;c<o.length;c++){const e=o[c];'"'!==e||a?'"'===e&&a?'"'===o[c+1]?(l+='"',c++):a=!1:e!==n||a?e!==r||a?l+=e:(s.push(l),l="",(s.length>1||s.some(e=>""!==e.trim()))&&i.push(s),s=[]):(s.push(l),l=""):a=!0}return s.push(l),(s.length>1||s.some(e=>""!==e.trim()))&&i.push(s),i}function f(e,t){const{rows:n,target:r,fields:o}=e;if(!r)return;const i=t.rows,s=t.effectiveConfig.columns??[],l=s.map(e=>e.field),a=/* @__PURE__ */new Map;s.forEach(e=>{a.set(e.field,!0===e.editable)});const c=[...i],d=r.bounds?r.bounds.endRow:1/0;n.forEach((e,t)=>{const n=r.row+t;if(!(n>d)){if(r.bounds){if(n>=c.length)return}else for(;n>=c.length;){const e={};l.forEach(t=>e[t]=""),c.push(e)}c[n]={...c[n]},e.forEach((e,t)=>{const r=o[t];r&&a.get(r)&&(c[n][r]=e)})}}),t.rows=c}class g extends c{static dependencies=[{name:"selection",required:!1,reason:"Enables copy/paste of selected cells instead of entire grid"}];name="clipboard";get defaultConfig(){return{includeHeaders:!1,delimiter:"\t",newline:"\n",quoteStrings:!1}}lastCopied=null;attach(e){super.attach(e),e.addEventListener("paste",e=>this.#n(e),{signal:this.disconnectSignal})}detach(){this.lastCopied=null}onKeyDown(e){return!(!e.ctrlKey&&!e.metaKey||"c"!==e.key)&&(e.preventDefault(),this.#r(e.target),!0)}#r(e){const t=this.#o();if(t&&0===t.ranges.length){const t=this.#i(e);if(!t)return;const n=this.columns[t.col];if(!n)return;return void this.copy({rowIndices:[t.row],columns:[n.field]})}this.copy()}#n(e){const t=e.clipboardData?.getData("text/plain");if(!t)return;e.preventDefault();const n=h(t,this.config),r=this.#o(),o=r?.ranges?.[0],i=o?.from.row??0,s=o?.from.col??0,l=o&&("range"===r?.mode||"row"===r?.mode)&&(o.from.row!==o.to.row||o.from.col!==o.to.col)?{endRow:o.to.row,endCol:o.to.col}:null,a=l?.endCol??this.visibleColumns.length-1,c=this.visibleColumns[s],d=c?{row:i,col:s,field:c.field,bounds:l}:null,u=[],f=n[0]?.length??0;for(let h=0;h<f&&s+h<=a;h++){const e=this.visibleColumns[s+h];e&&u.push(e.field)}const g={rows:n,text:t,target:d,fields:u};this.emit("paste",g),this.#s(g)}#s(e){if(!this.grid)return;const{pasteHandler:t}=this.config;if(null===t)return;(t??f)(e,this.grid)}#o(){const e=this.grid?.query("getSelection");return e?.[0]}#l(e){const t=this.#o();let n,r;if(e?.columns)n=d(this.columns,e.columns);else if(t?.ranges.length&&"row"!==t.mode){const e=t.ranges[t.ranges.length-1],r=Math.min(e.from.col,e.to.col),o=Math.max(e.from.col,e.to.col);n=d(this.visibleColumns.slice(r,o+1))}else n=d(this.columns);if(e?.rowIndices)r=function(e,t){return t?.length?[...t].sort((e,t)=>e-t).map(t=>e[t]).filter(e=>null!=e):e}(this.rows,e.rowIndices);else if(t?.ranges.length){const e=t.ranges[t.ranges.length-1],n=Math.min(e.from.row,e.to.row),o=Math.max(e.from.row,e.to.row);r=[];for(let t=n;t<=o;t++){const e=this.rows[t];e&&r.push(e)}}else r=this.rows;return{columns:n,rows:r}}#a(e,t,n){const r=n?.delimiter??this.config.delimiter??"\t",o=n?.newline??this.config.newline??"\n",i=n?.includeHeaders??this.config.includeHeaders??!1,s=n?.processCell??this.config.processCell,l=[];i&&l.push(e.map(e=>e.header||e.field).join(r));for(const a of t){const t=e.map(e=>{const t=a[e.field];return s?s(t,e.field,a):this.#c(e,t,a)});l.push(t.join(r))}return l.join(o)}#c(e,t,n){if(e.format)try{const r=e.format(t,n);return null==r?"":String(r)}catch{}if(e.renderer||e.viewRenderer){const t=this.#d(e.field,n);if(null!=t)return t}return function(e){return null==e?"":e instanceof Date?e.toISOString():"object"==typeof e?JSON.stringify(e):String(e)}(t)}#d(e,t){const n=this.gridElement;if(!n)return null;const r=this.rows.indexOf(t);if(-1===r)return null;const o=n.querySelector(`.cell[data-row="${r}"][data-field="${e}"]`);return o?o.textContent?.trim()??null:null}#i(e){const t=e.closest("[data-field-cache]");if(!t)return null;const n=t.dataset.fieldCache,r=t.dataset.row;if(!n||!r)return null;const o=parseInt(r,10);if(isNaN(o))return null;const i=this.columns.findIndex(e=>e.field===n);return-1===i?null:{row:o,col:i}}getSelectionAsText(e){const{columns:t,rows:n}=this.#l(e);return 0===t.length||0===n.length?"":this.#a(t,n,e)}async copy(e){const{columns:t,rows:n}=this.#l(e);if(0===t.length||0===n.length)return"";const r=this.#a(t,n,e);return await u(r),this.lastCopied={text:r,timestamp:Date.now()},this.emit("copy",{text:r,rowCount:n.length,columnCount:t.length}),r}async copyRows(e,t){return 0===e.length?"":this.copy({...t,rowIndices:e})}async paste(){const e=await async function(){try{return await navigator.clipboard.readText()}catch{return""}}();return e?h(e,this.config):null}getLastCopied(){return this.lastCopied}}export{g as ClipboardPlugin,f as defaultPasteHandler};
|
|
1
|
+
function e(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function t(t,n,r,o){return`${e(r,o)} ${t}: ${n}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(t)}`}["__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"].map(e=>e.split("").reverse().join(""));const n=/* @__PURE__ */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"]),r=/^on\w+$/i,o=/* @__PURE__ */new Set(["href","src","action","formaction","data","srcdoc","xlink:href","poster","srcset"]),i=/^\s*(javascript|vbscript|data|blob):/i;function s(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=[],s=e.querySelectorAll("*");for(const l of s){const e=l.tagName.toLowerCase();if(n.has(e)){t.push(l);continue}if("svg"===e||"http://www.w3.org/2000/svg"===l.namespaceURI){if(Array.from(l.attributes).some(e=>r.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(l);continue}}const s=[];for(const t of l.attributes){const e=t.name.toLowerCase();r.test(e)?s.push(t.name):(o.has(e)&&i.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&s.push(t.name)}s.forEach(e=>l.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content),t.innerHTML}const l='<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>',a={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:l,filterActive:l,print:"🖨️"};class c{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 n=new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(n),n.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{...a,...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(),n=parseInt(t,10);if(!isNaN(n))return n}return 200}setIcon(e,t,n){e.dataset.icon=t.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===t?e.dataset.expanded="":"expand"===t&&delete e.dataset.expanded;const r=this.#t(t,n);void 0!==r?"string"==typeof r?e.innerHTML=s(r):r instanceof HTMLElement&&(e.innerHTML="",e.appendChild(r.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 n=document.createElement("span");n.setAttribute("part","sort-indicator"),n.className="sort-indicator",t?(e.setAttribute("aria-sort","asc"===t?"ascending":"descending"),e.setAttribute("data-sort",t),this.setIcon(n,"asc"===t?"sortAsc":"sortDesc")):(e.setAttribute("aria-sort","none"),e.removeAttribute("data-sort"),this.setIcon(n,"sortNone"));const r=e.querySelector(".tbw-filter-btn")??e.querySelector(".resize-handle");return r?e.insertBefore(n,r):e.appendChild(n),n}warn(n,r){void 0!==r?console.warn(t(n,r,this.gridElement.id,this.name)):console.warn(`${e(this.gridElement.id,this.name)} ${n}`)}throwDiagnostic(e,n){throw new Error(t(e,n,this.gridElement.id,this.name))}}function d(e,t,n=!0){let r=e;if(n&&(r=r.filter(e=>!e.hidden&&!e.field.startsWith("__")&&!0!==e.meta?.utility)),t?.length){const e=new Set(t);r=r.filter(t=>e.has(t.field))}return r}async function u(e){try{return await navigator.clipboard.writeText(e),!0}catch(s){n="TBW100",r=`Clipboard API failed: ${s}`,console.warn(t(n,r,o,i));const l=document.createElement("textarea");l.value=e,l.style.position="fixed",l.style.opacity="0",l.style.pointerEvents="none",document.body.appendChild(l),l.select();const a=document.execCommand("copy");return document.body.removeChild(l),a}var n,r,o,i}function h(e,t){const n=t.delimiter??"\t",r=t.newline??"\n",o=e.replace(/\r\n/g,"\n").replace(/\r/g,"\n"),i=[];let s=[],l="",a=!1;for(let c=0;c<o.length;c++){const e=o[c];'"'!==e||a?'"'===e&&a?'"'===o[c+1]?(l+='"',c++):a=!1:e!==n||a?e!==r||a?l+=e:(s.push(l),l="",(s.length>1||s.some(e=>""!==e.trim()))&&i.push(s),s=[]):(s.push(l),l=""):a=!0}return s.push(l),(s.length>1||s.some(e=>""!==e.trim()))&&i.push(s),i}function f(e,t){const{rows:n,target:r,fields:o}=e;if(!r)return;const i=t.rows,s=t.effectiveConfig.columns??[],l=s.map(e=>e.field),a=/* @__PURE__ */new Map;s.forEach(e=>{a.set(e.field,!0===e.editable)});const c=[...i],d=r.bounds?r.bounds.endRow:1/0;n.forEach((e,t)=>{const n=r.row+t;if(!(n>d)){if(r.bounds){if(n>=c.length)return}else for(;n>=c.length;){const e={};l.forEach(t=>e[t]=""),c.push(e)}c[n]={...c[n]},e.forEach((e,t)=>{const r=o[t];r&&a.get(r)&&(c[n][r]=e)})}}),t.rows=c}class g extends c{static manifest={queries:[{type:"clipboard:copy",description:"Triggers a copy operation and returns the copied text"}]};static dependencies=[{name:"selection",required:!1,reason:"Enables copy/paste of selected cells instead of entire grid"}];name="clipboard";get defaultConfig(){return{includeHeaders:!1,delimiter:"\t",newline:"\n",quoteStrings:!1}}lastCopied=null;attach(e){super.attach(e),e.addEventListener("paste",e=>this.#n(e),{signal:this.disconnectSignal})}detach(){this.lastCopied=null}handleQuery(e){if("clipboard:copy"===e.type)return this.copy(),!0}onKeyDown(e){return!(!e.ctrlKey&&!e.metaKey||"c"!==e.key)&&(e.preventDefault(),this.#r(e.target),!0)}#r(e){const t=this.#o();if(t&&0===t.ranges.length){const t=this.#i(e);if(!t)return;const n=this.columns[t.col];if(!n)return;return void this.copy({rowIndices:[t.row],columns:[n.field]})}this.copy()}#n(e){const t=e.clipboardData?.getData("text/plain");if(!t)return;e.preventDefault();const n=h(t,this.config),r=this.#o(),o=r?.ranges?.[0],i=o?.from.row??0,s=o?.from.col??0,l=o&&("range"===r?.mode||"row"===r?.mode)&&(o.from.row!==o.to.row||o.from.col!==o.to.col)?{endRow:o.to.row,endCol:o.to.col}:null,a=l?.endCol??this.visibleColumns.length-1,c=this.visibleColumns[s],d=c?{row:i,col:s,field:c.field,bounds:l}:null,u=[],f=n[0]?.length??0;for(let h=0;h<f&&s+h<=a;h++){const e=this.visibleColumns[s+h];e&&u.push(e.field)}const g={rows:n,text:t,target:d,fields:u};this.emit("paste",g),this.#s(g)}#s(e){if(!this.grid)return;const{pasteHandler:t}=this.config;if(null===t)return;(t??f)(e,this.grid)}#o(){const e=this.grid?.query("getSelection");return e?.[0]}#l(e){const t=this.#o();let n,r;if(e?.columns)n=d(this.columns,e.columns);else if(t?.ranges.length&&"row"!==t.mode){const e=t.ranges[t.ranges.length-1],r=Math.min(e.from.col,e.to.col),o=Math.max(e.from.col,e.to.col);n=d(this.visibleColumns.slice(r,o+1))}else n=d(this.columns);if(e?.rowIndices)r=function(e,t){return t?.length?[...t].sort((e,t)=>e-t).map(t=>e[t]).filter(e=>null!=e):e}(this.rows,e.rowIndices);else if(t?.ranges.length){const e=t.ranges[t.ranges.length-1],n=Math.min(e.from.row,e.to.row),o=Math.max(e.from.row,e.to.row);r=[];for(let t=n;t<=o;t++){const e=this.rows[t];e&&r.push(e)}}else r=this.rows;return{columns:n,rows:r}}#a(e,t,n){const r=n?.delimiter??this.config.delimiter??"\t",o=n?.newline??this.config.newline??"\n",i=n?.includeHeaders??this.config.includeHeaders??!1,s=n?.processCell??this.config.processCell,l=[];i&&l.push(e.map(e=>e.header||e.field).join(r));for(const a of t){const t=e.map(e=>{const t=a[e.field];return s?s(t,e.field,a):this.#c(e,t,a)});l.push(t.join(r))}return l.join(o)}#c(e,t,n){if(e.format)try{const r=e.format(t,n);return null==r?"":String(r)}catch{}if(e.renderer||e.viewRenderer){const t=this.#d(e.field,n);if(null!=t)return t}return function(e){return null==e?"":e instanceof Date?e.toISOString():"object"==typeof e?JSON.stringify(e):String(e)}(t)}#d(e,t){const n=this.gridElement;if(!n)return null;const r=this.rows.indexOf(t);if(-1===r)return null;const o=n.querySelector(`.cell[data-row="${r}"][data-field="${e}"]`);return o?o.textContent?.trim()??null:null}#i(e){const t=e.closest("[data-field-cache]");if(!t)return null;const n=t.dataset.fieldCache,r=t.dataset.row;if(!n||!r)return null;const o=parseInt(r,10);if(isNaN(o))return null;const i=this.columns.findIndex(e=>e.field===n);return-1===i?null:{row:o,col:i}}getSelectionAsText(e){const{columns:t,rows:n}=this.#l(e);return 0===t.length||0===n.length?"":this.#a(t,n,e)}async copy(e){const{columns:t,rows:n}=this.#l(e);if(0===t.length||0===n.length)return"";const r=this.#a(t,n,e);return await u(r),this.lastCopied={text:r,timestamp:Date.now()},this.emit("copy",{text:r,rowCount:n.length,columnCount:t.length}),r}async copyRows(e,t){return 0===e.length?"":this.copy({...t,rowIndices:e})}async paste(){const e=await async function(){try{return await navigator.clipboard.readText()}catch{return""}}();return e?h(e,this.config):null}getLastCopied(){return this.lastCopied}}export{g as ClipboardPlugin,f as defaultPasteHandler};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|