@coreui/data-grid 0.3.0-rc.0 → 0.4.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.
Files changed (122) hide show
  1. package/dist/css/data-grid.css +1 -1
  2. package/dist/css/data-grid.css.map +1 -1
  3. package/dist/css/data-grid.min.css +1 -1
  4. package/dist/css/data-grid.min.css.map +1 -1
  5. package/dist/css/data-grid.standalone.css +6 -6
  6. package/dist/css/data-grid.standalone.css.map +1 -1
  7. package/dist/css/data-grid.standalone.min.css +1 -1
  8. package/dist/css/data-grid.standalone.min.css.map +1 -1
  9. package/dist/js/clipboard.cjs +2 -3
  10. package/dist/js/clipboard.mjs +2 -3
  11. package/dist/js/csv.cjs +5 -6
  12. package/dist/js/csv.cjs.map +1 -1
  13. package/dist/js/csv.mjs +5 -6
  14. package/dist/js/csv.mjs.map +1 -1
  15. package/dist/js/data-grid.esm.js +5899 -5667
  16. package/dist/js/data-grid.esm.js.map +1 -1
  17. package/dist/js/data-grid.esm.min.js +2 -2
  18. package/dist/js/data-grid.esm.min.js.map +1 -1
  19. package/dist/js/data-grid.js +5899 -5668
  20. package/dist/js/data-grid.js.map +1 -1
  21. package/dist/js/data-grid.lite.esm.js +2669 -2622
  22. package/dist/js/data-grid.lite.esm.js.map +1 -1
  23. package/dist/js/data-grid.lite.esm.min.js +2 -2
  24. package/dist/js/data-grid.lite.esm.min.js.map +1 -1
  25. package/dist/js/data-grid.lite.js +2669 -2623
  26. package/dist/js/data-grid.lite.js.map +1 -1
  27. package/dist/js/data-grid.lite.min.js +2 -2
  28. package/dist/js/data-grid.lite.min.js.map +1 -1
  29. package/dist/js/data-grid.lite.mjs +2669 -2622
  30. package/dist/js/data-grid.lite.mjs.map +1 -1
  31. package/dist/js/data-grid.min.js +2 -2
  32. package/dist/js/data-grid.min.js.map +1 -1
  33. package/dist/js/data-grid.mjs +5899 -5667
  34. package/dist/js/data-grid.mjs.map +1 -1
  35. package/dist/js/direction.cjs +3 -4
  36. package/dist/js/direction.cjs.map +1 -1
  37. package/dist/js/direction.mjs +3 -4
  38. package/dist/js/direction.mjs.map +1 -1
  39. package/dist/js/drag.cjs +6 -6
  40. package/dist/js/drag.cjs.map +1 -1
  41. package/dist/js/drag.mjs +6 -6
  42. package/dist/js/drag.mjs.map +1 -1
  43. package/dist/js/{export-table-BdabEbJG.mjs → export-table-BggGRmzQ.mjs} +3 -4
  44. package/dist/js/{export-table-BdabEbJG.mjs.map → export-table-BggGRmzQ.mjs.map} +1 -1
  45. package/dist/js/{export-table-D762wrZ1.cjs → export-table-BiB3_lVo.cjs} +3 -4
  46. package/dist/js/{export-table-D762wrZ1.cjs.map → export-table-BiB3_lVo.cjs.map} +1 -1
  47. package/dist/js/filters.cjs +2 -3
  48. package/dist/js/filters.mjs +2 -3
  49. package/dist/js/labels.cjs +2 -3
  50. package/dist/js/labels.mjs +2 -3
  51. package/dist/js/print.cjs +2 -3
  52. package/dist/js/print.mjs +2 -3
  53. package/dist/js/selector.cjs +22 -0
  54. package/dist/js/selector.cjs.map +1 -0
  55. package/dist/js/selector.mjs +21 -0
  56. package/dist/js/selector.mjs.map +1 -0
  57. package/dist/js/validate.cjs +2 -3
  58. package/dist/js/validate.mjs +2 -3
  59. package/dist/js/xlsx.cjs +5 -7
  60. package/dist/js/xlsx.cjs.map +1 -1
  61. package/dist/js/xlsx.mjs +5 -7
  62. package/dist/js/xlsx.mjs.map +1 -1
  63. package/dist/types/base-component.d.mts +29 -0
  64. package/dist/types/data-grid.d.mts +141 -0
  65. package/dist/types/dom/data.d.mts +15 -0
  66. package/dist/types/dom/event-handler.d.mts +22 -0
  67. package/dist/types/dom/manipulator.d.mts +16 -0
  68. package/dist/types/engine/active-cell.d.mts +33 -0
  69. package/dist/types/engine/data-source.d.mts +19 -0
  70. package/dist/types/engine/features-lite.d.mts +25 -0
  71. package/dist/types/engine/features.d.mts +35 -0
  72. package/dist/types/engine/scheduler.d.mts +11 -0
  73. package/dist/types/engine/table.d.mts +9 -0
  74. package/dist/types/engine/validate.d.mts +20 -1
  75. package/dist/types/engine/virtualizer.d.mts +23 -0
  76. package/dist/types/filters.d.mts +13 -1
  77. package/dist/types/icons.d.mts +23 -0
  78. package/dist/types/index-lite.d.mts +19 -1
  79. package/dist/types/index.d.mts +21 -1
  80. package/dist/types/labels.d.mts +9 -1
  81. package/dist/types/types.d.mts +284 -0
  82. package/dist/types/ui/body.d.mts +37 -0
  83. package/dist/types/ui/column-chooser.d.mts +27 -0
  84. package/dist/types/ui/editor.d.mts +8 -0
  85. package/dist/types/ui/filter-menu.d.mts +21 -0
  86. package/dist/types/ui/header.d.mts +51 -0
  87. package/dist/types/ui/loading.d.mts +12 -0
  88. package/dist/types/ui/menu.d.mts +17 -0
  89. package/dist/types/ui/pagination.d.mts +17 -0
  90. package/dist/types/ui/pinning.d.mts +17 -0
  91. package/dist/types/ui/toolbar.d.mts +42 -0
  92. package/dist/types/ui/tooltip.d.mts +10 -0
  93. package/dist/types/util/clipboard.d.mts +29 -1
  94. package/dist/types/util/config.d.mts +28 -0
  95. package/dist/types/util/csv.d.mts +19 -1
  96. package/dist/types/util/debounce.d.mts +7 -0
  97. package/dist/types/util/direction.d.mts +17 -1
  98. package/dist/types/util/drag.d.mts +48 -1
  99. package/dist/types/util/export-table.d.mts +47 -0
  100. package/dist/types/util/index.d.mts +66 -0
  101. package/dist/types/util/print.d.mts +32 -1
  102. package/dist/types/util/sanitizer.d.mts +15 -0
  103. package/dist/types/util/selector.d.mts +12 -0
  104. package/dist/types/util/selector.d.ts +12 -0
  105. package/dist/types/util/xlsx.d.mts +17 -1
  106. package/dist/types/util/zip.d.mts +11 -0
  107. package/package.json +29 -16
  108. package/scss/data-grid.scss +1 -1
  109. package/src/data-grid.ts +4 -3
  110. package/src/engine/active-cell.ts +2 -6
  111. package/src/index-lite.ts +1 -1
  112. package/src/index.ts +1 -1
  113. package/src/ui/column-chooser.ts +4 -4
  114. package/src/ui/filter-menu.ts +5 -5
  115. package/src/ui/menu.ts +4 -4
  116. package/src/ui/pagination.ts +1 -1
  117. package/src/ui/tooltip.ts +2 -2
  118. package/src/util/csv.ts +2 -2
  119. package/src/util/direction.ts +4 -3
  120. package/src/util/drag.ts +5 -3
  121. package/src/util/selector.ts +16 -0
  122. package/src/util/xlsx.ts +1 -1
@@ -1 +1,48 @@
1
- export * from './drag.js'
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI PRO data-grid util/drag.ts
4
+ * License (https://coreui.io/pro/license/)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+ export type DragAxis = 'x' | 'y';
8
+ export interface DragHit {
9
+ id: string;
10
+ element: HTMLElement;
11
+ }
12
+ export interface DragDrop {
13
+ id: string;
14
+ after: boolean;
15
+ }
16
+ export interface DragControllerOptions {
17
+ axis: DragAxis;
18
+ root: HTMLElement;
19
+ handle: string;
20
+ resolveSource: (handle: HTMLElement, target: HTMLElement) => DragHit | null;
21
+ items: DragItems;
22
+ canDrop: (sourceId: string, targetId: string) => boolean;
23
+ getScrollElement: () => HTMLElement | null;
24
+ ghostLabel?: (source: DragHit) => string;
25
+ preview?: boolean;
26
+ onDrop: (sourceId: string, drop: DragDrop) => void;
27
+ }
28
+ export interface DragItems {
29
+ getOrderedIds: () => string[];
30
+ getElements: (id: string) => HTMLElement[];
31
+ }
32
+ export interface DragController {
33
+ dispose: () => void;
34
+ }
35
+ export declare const createDragController: (options: DragControllerOptions) => DragController;
36
+ export interface ColumnDragOptions {
37
+ root: HTMLElement;
38
+ getScrollElement: () => HTMLElement | null;
39
+ canDrop: (sourceKey: string, targetKey: string) => boolean;
40
+ onReorder: (sourceKey: string, targetKey: string, after: boolean) => void;
41
+ }
42
+ export declare const createColumnDragController: (options: ColumnDragOptions) => DragController;
43
+ export interface RowDragOptions {
44
+ root: HTMLElement;
45
+ getScrollElement: () => HTMLElement | null;
46
+ onReorder: (sourceIndex: number, targetIndex: number, after: boolean) => void;
47
+ }
48
+ export declare const createRowDragController: (options: RowDragOptions) => DragController;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI PRO data-grid util/export-table.ts
4
+ * License (https://coreui.io/pro/license/)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+ import type { DataGridItem } from '../types.mjs';
8
+ export interface ExportColumnMeta {
9
+ label?: string;
10
+ formatter?: (value: unknown, item: DataGridItem) => string;
11
+ width?: number;
12
+ }
13
+ export interface ExportColumn {
14
+ id: string;
15
+ columnDef: {
16
+ meta?: unknown;
17
+ };
18
+ }
19
+ export interface ExportRow {
20
+ original: DataGridItem;
21
+ getValue: (columnId: string) => unknown;
22
+ }
23
+ export interface ExportTable {
24
+ getAllLeafColumns: () => ExportColumn[];
25
+ getCenterVisibleLeafColumns?: () => ExportColumn[];
26
+ getCoreRowModel: () => {
27
+ rows: ExportRow[];
28
+ };
29
+ getEndVisibleLeafColumns?: () => ExportColumn[];
30
+ getFilteredRowModel?: () => {
31
+ rows: ExportRow[];
32
+ };
33
+ getSelectedRowModel?: () => {
34
+ rows: ExportRow[];
35
+ };
36
+ getSortedRowModel?: () => {
37
+ rows: ExportRow[];
38
+ };
39
+ getStartVisibleLeafColumns?: () => ExportColumn[];
40
+ getVisibleLeafColumns?: () => ExportColumn[];
41
+ }
42
+ export type ExportScope = 'filtered' | 'all' | 'selected';
43
+ export declare const rowsFor: (table: ExportTable, scope: ExportScope | undefined) => ExportRow[];
44
+ export declare const columnsFor: (table: ExportTable) => ExportColumn[];
45
+ export declare const headerFor: (column: ExportColumn) => string;
46
+ export declare const formatterFor: (column: ExportColumn) => ExportColumnMeta["formatter"];
47
+ export declare const widthFor: (column: ExportColumn) => number | undefined;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI util/index.ts
4
+ * Licensed under MIT (https://github.com/coreui/coreui/blob/main/LICENSE)
5
+ *
6
+ * This is a modified version of the Bootstrap's util/index.ts
7
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
8
+ * --------------------------------------------------------------------------
9
+ */
10
+ type JQueryStatic = ((selector: unknown) => any) & Record<string, any> & {
11
+ fn: Record<string, any>;
12
+ };
13
+ type JQueryPlugin = {
14
+ NAME: string;
15
+ jQueryInterface: (...args: any[]) => unknown;
16
+ };
17
+ declare global {
18
+ interface Window {
19
+ jQuery?: JQueryStatic;
20
+ }
21
+ }
22
+ /**
23
+ * Properly escape IDs selectors to handle weird IDs
24
+ * @param {string} selector
25
+ * @returns {string}
26
+ */
27
+ declare const parseSelector: (selector: string) => string;
28
+ declare const toType: (object: unknown) => string;
29
+ /**
30
+ * Public Util API
31
+ */
32
+ declare const getUID: (prefix: string) => string;
33
+ declare const getTransitionDurationFromElement: (element: Element | null) => number;
34
+ declare const triggerTransitionEnd: (element: Element) => void;
35
+ declare const isElement: (object: unknown) => object is Element;
36
+ declare const getElement: (object: unknown) => HTMLElement | null;
37
+ declare const isVisible: (element: unknown) => boolean;
38
+ declare const isDisabled: (element: Element | null | undefined) => boolean;
39
+ declare const findShadowRoot: (element: Node) => ShadowRoot | null;
40
+ declare const noop: () => void;
41
+ /**
42
+ * Trick to restart an element's animation
43
+ *
44
+ * @param {HTMLElement} element
45
+ * @return void
46
+ *
47
+ * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
48
+ */
49
+ declare const reflow: (element: HTMLElement) => void;
50
+ declare const getjQuery: () => JQueryStatic | null;
51
+ declare const onDOMContentLoaded: (callback: () => void) => void;
52
+ declare const isRTL: () => boolean;
53
+ declare const defineJQueryPlugin: (plugin: JQueryPlugin) => void;
54
+ declare const execute: <T = any>(possibleCallback: T | ((...functionArgs: any[]) => T), args?: any[], defaultValue?: T | ((...functionArgs: any[]) => T)) => T;
55
+ declare const executeAfterTransition: (callback: () => void, transitionElement: Element, waitForTransition?: boolean) => void;
56
+ /**
57
+ * Return the previous/next element of a list.
58
+ *
59
+ * @param {array} list The list of elements
60
+ * @param activeElement The active element
61
+ * @param shouldGetNext Choose to get next or previous element
62
+ * @param isCycleAllowed
63
+ * @return {Element|elem} The proper element
64
+ */
65
+ declare const getNextActiveElement: <T>(list: T[], activeElement: T, shouldGetNext: boolean, isCycleAllowed?: boolean) => T;
66
+ export { defineJQueryPlugin, execute, executeAfterTransition, findShadowRoot, getElement, getjQuery, getNextActiveElement, getTransitionDurationFromElement, getUID, isDisabled, isElement, isRTL, isVisible, noop, onDOMContentLoaded, parseSelector, reflow, triggerTransitionEnd, toType };
@@ -1 +1,32 @@
1
- export * from './print.js'
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI PRO data-grid util/print.ts
4
+ * License (https://coreui.io/pro/license/)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+ import type { DataGridItem } from '../types.mjs';
8
+ export interface PrintColumn {
9
+ id: string;
10
+ label: string;
11
+ formatter?: (value: unknown, item: DataGridItem) => string;
12
+ }
13
+ export interface PrintRow {
14
+ getValue: (columnId: string) => unknown;
15
+ original: DataGridItem;
16
+ }
17
+ export interface PrintTable {
18
+ getSortedRowModel?: () => {
19
+ rows: PrintRow[];
20
+ };
21
+ getFilteredRowModel?: () => {
22
+ rows: PrintRow[];
23
+ };
24
+ getCoreRowModel: () => {
25
+ rows: PrintRow[];
26
+ };
27
+ }
28
+ export interface PrintOptions {
29
+ title?: string;
30
+ }
31
+ export declare const createPrintTable: (table: PrintTable, columns: PrintColumn[], options?: PrintOptions) => HTMLElement;
32
+ export declare const printGrid: (table: PrintTable, columns: PrintColumn[], options?: PrintOptions) => void;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI util/sanitizer.ts
4
+ * Licensed under MIT (https://github.com/coreui/coreui/blob/main/LICENSE)
5
+ *
6
+ * This is a modified version of the Bootstrap's util/sanitizer.ts
7
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
8
+ * --------------------------------------------------------------------------
9
+ */
10
+ type SanitizerAllowList = Record<string, Array<string | RegExp>>;
11
+ export declare const DefaultAllowlist: SanitizerAllowList;
12
+ export declare const SVGAllowlist: SanitizerAllowList;
13
+ export declare function escapeHtml(unsafeText: string): string;
14
+ export declare function sanitizeHtml(unsafeHtml: string, allowList: SanitizerAllowList, sanitizeFunction?: ((unsafeHtml: string) => string) | null): string;
15
+ export type { SanitizerAllowList };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI PRO data-grid util/selector.ts
4
+ * License (https://coreui.io/pro/license/)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+ /**
8
+ * Escapes a column key or row index for a double-quoted CSS attribute selector value.
9
+ * @param value The key or index interpolated into `[data-…="…"]`.
10
+ * @returns The value as a string, with `"` and `\` backslash-escaped and line breaks as hex escapes.
11
+ */
12
+ export declare const escapeAttributeValue: (value: string | number) => string;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI PRO data-grid util/selector.ts
4
+ * License (https://coreui.io/pro/license/)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+ /**
8
+ * Escapes a column key or row index for a double-quoted CSS attribute selector value.
9
+ * @param value The key or index interpolated into `[data-…="…"]`.
10
+ * @returns The value as a string, with `"` and `\` backslash-escaped and line breaks as hex escapes.
11
+ */
12
+ export declare const escapeAttributeValue: (value: string | number) => string;
@@ -1 +1,17 @@
1
- export * from './xlsx.js'
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI PRO data-grid util/xlsx.ts
4
+ * License (https://coreui.io/pro/license/)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+ import { type ExportScope, type ExportTable } from './export-table.mjs';
8
+ export interface XlsxOptions {
9
+ scope?: ExportScope;
10
+ sheetName?: string;
11
+ }
12
+ export interface XlsxDownloadOptions extends XlsxOptions {
13
+ filename?: string;
14
+ }
15
+ export type XlsxTable = ExportTable;
16
+ export declare const exportXlsx: (table: XlsxTable, options?: XlsxOptions) => Uint8Array;
17
+ export declare const downloadXlsx: (table: XlsxTable, options?: XlsxDownloadOptions) => void;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI PRO data-grid util/zip.ts
4
+ * License (https://coreui.io/pro/license/)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+ export interface ZipEntry {
8
+ name: string;
9
+ data: Uint8Array;
10
+ }
11
+ export declare const zip: (entries: ZipEntry[]) => Uint8Array;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@coreui/data-grid",
3
- "description": "High-performance vanilla JavaScript data grid for CoreUI \u2014 100,000 rows with sorting, filtering, selection, pagination, and server-side data",
4
- "version": "0.3.0-rc.0",
3
+ "description": "High-performance vanilla JavaScript data grid for CoreUI — 100,000 rows with sorting, filtering, selection, pagination, and server-side data",
4
+ "version": "0.4.0",
5
5
  "keywords": [
6
6
  "coreui",
7
7
  "data-grid",
@@ -26,7 +26,7 @@
26
26
  "js": "npm-run-all js-compile js-types js-minify",
27
27
  "js-compile": "rolldown --config build/rolldown.config.mjs --sourcemap",
28
28
  "js-minify": "npm-run-all --aggregate-output --parallel js-minify-*",
29
- "js-types": "tsc --project tsconfig.types.json && node build/types-esm-shims.mjs",
29
+ "js-types": "tsc --project tsconfig.types.json && node build/types-esm.mjs dist/types",
30
30
  "js-minify-lite": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/data-grid.lite.js.map,includeSources,url=data-grid.lite.min.js.map\" --output dist/js/data-grid.lite.min.js dist/js/data-grid.lite.js",
31
31
  "js-minify-lite-esm": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/data-grid.lite.esm.js.map,includeSources,url=data-grid.lite.esm.min.js.map\" --output dist/js/data-grid.lite.esm.min.js dist/js/data-grid.lite.esm.js",
32
32
  "js-minify-standalone": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/data-grid.js.map,includeSources,url=data-grid.min.js.map\" --output dist/js/data-grid.min.js dist/js/data-grid.js",
@@ -134,6 +134,16 @@
134
134
  "default": "./dist/js/direction.cjs"
135
135
  }
136
136
  },
137
+ "./selector": {
138
+ "import": {
139
+ "types": "./dist/types/util/selector.d.mts",
140
+ "default": "./dist/js/selector.mjs"
141
+ },
142
+ "require": {
143
+ "types": "./dist/types/util/selector.d.ts",
144
+ "default": "./dist/js/selector.cjs"
145
+ }
146
+ },
137
147
  "./validate": {
138
148
  "import": {
139
149
  "types": "./dist/types/engine/validate.d.mts",
@@ -188,6 +198,9 @@
188
198
  "direction": [
189
199
  "dist/types/util/direction.d.ts"
190
200
  ],
201
+ "selector": [
202
+ "dist/types/util/selector.d.ts"
203
+ ],
191
204
  "validate": [
192
205
  "dist/types/engine/validate.d.ts"
193
206
  ],
@@ -208,26 +221,26 @@
208
221
  },
209
222
  "license": "SEE LICENSE IN LICENSE",
210
223
  "dependencies": {
211
- "@tanstack/store": "^0.11.0",
212
- "@tanstack/table-core": "^9.0.0",
213
- "@tanstack/virtual-core": "^3.17.3"
224
+ "@tanstack/store": "^0.11.2",
225
+ "@tanstack/table-core": "^9.3.1",
226
+ "@tanstack/virtual-core": "^3.19.6"
214
227
  },
215
228
  "devDependencies": {
216
- "@vitest/coverage-v8": "^4.1.10",
217
- "autoprefixer": "^10.5.2",
218
- "browserslist": "^4.28.7",
229
+ "@vitest/coverage-v8": "^5.0.5",
230
+ "autoprefixer": "^10.6.1",
231
+ "browserslist": "^4.29.4",
219
232
  "clean-css-cli": "^5.6.3",
220
233
  "jsdom": "^29.1.1",
221
234
  "npm-run-all": "^4.1.5",
222
- "postcss": "^8.5.15",
223
- "postcss-cli": "^11.0.1",
235
+ "postcss": "^8.5.31",
236
+ "postcss-cli": "^12.0.0",
224
237
  "rimraf": "^6.1.3",
225
- "rolldown": "^1.2.3",
226
- "sass-embedded": "^1.100.0",
227
- "terser": "5.48.0",
238
+ "rolldown": "^1.2.15",
239
+ "sass-embedded": "^1.106.1",
240
+ "terser": "5.51.2",
228
241
  "tslib": "^2.8.1",
229
- "typescript": "^5.9.3",
230
- "vitest": "^4.1.10"
242
+ "typescript": "~6.0.3",
243
+ "vitest": "^5.0.5"
231
244
  },
232
245
  "files": [
233
246
  "dist/{css,js,types}/**",
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * CoreUI PRO data-grid.scss v0.3.0
2
+ * CoreUI PRO data-grid.scss v0.4.0
3
3
  * License (https://coreui.io/pro/license/)
4
4
  */
5
5
 
package/src/data-grid.ts CHANGED
@@ -51,6 +51,7 @@ import {
51
51
  } from './util/csv'
52
52
  import { debounce } from './util/debounce'
53
53
  import { DefaultAllowlist, sanitizeHtml, SVGAllowlist } from './util/sanitizer.js'
54
+ import { escapeAttributeValue } from './util/selector'
54
55
 
55
56
  /**
56
57
  * Constants
@@ -1660,12 +1661,12 @@ private _undoStack: DataGridEditCommitEntry[] = []
1660
1661
  private _cellElementFor(cell: ActiveCell): HTMLElement | null {
1661
1662
  if (cell.rowIndex === -1) {
1662
1663
  return this._header.element.querySelector<HTMLElement>(
1663
- `tr:first-child th[data-coreui-column="${cell.columnId}"]`
1664
+ `tr:first-child th[data-coreui-column="${escapeAttributeValue(cell.columnId)}"]`
1664
1665
  )
1665
1666
  }
1666
1667
 
1667
- const rowElement = this._body.element.querySelector<HTMLElement>(`tr[data-coreui-index="${cell.rowIndex}"]`)
1668
- return rowElement?.querySelector<HTMLElement>(`td[data-coreui-column="${cell.columnId}"]`) ?? null
1668
+ const rowElement = this._body.element.querySelector<HTMLElement>(`tr[data-coreui-index="${escapeAttributeValue(cell.rowIndex)}"]`)
1669
+ return rowElement?.querySelector<HTMLElement>(`td[data-coreui-column="${escapeAttributeValue(cell.columnId)}"]`) ?? null
1669
1670
  }
1670
1671
 
1671
1672
  // The roving-tabindex pass: runs after every render/recycle flush, in the
@@ -89,15 +89,11 @@ export const resolveNavigation = (
89
89
 
90
90
  switch (key) {
91
91
  case 'ArrowLeft': {
92
- return rtl ?
93
- cell(current.rowIndex, Math.min(columnIndex + 1, lastColumn)) :
94
- cell(current.rowIndex, Math.max(columnIndex - 1, 0))
92
+ return cell(current.rowIndex, rtl ? Math.min(columnIndex + 1, lastColumn) : Math.max(columnIndex - 1, 0))
95
93
  }
96
94
 
97
95
  case 'ArrowRight': {
98
- return rtl ?
99
- cell(current.rowIndex, Math.max(columnIndex - 1, 0)) :
100
- cell(current.rowIndex, Math.min(columnIndex + 1, lastColumn))
96
+ return cell(current.rowIndex, rtl ? Math.max(columnIndex - 1, 0) : Math.min(columnIndex + 1, lastColumn))
101
97
  }
102
98
 
103
99
  case 'ArrowUp': {
package/src/index-lite.ts CHANGED
@@ -20,7 +20,7 @@ class DataGrid<TFeatures extends TableFeatures = DataGridLiteFeatures> extends D
20
20
  // The lite preset is deliberately narrower than the options' invariant
21
21
  // features type - the coverage assertion, not the type, polices a config
22
22
  // the set cannot serve.
23
- return { ...DataGridBase.Default, features: dataGridLiteFeatures as unknown as DataGridFeatures }
23
+ return { ...super.Default, features: dataGridLiteFeatures as unknown as DataGridFeatures }
24
24
  }
25
25
  }
26
26
 
package/src/index.ts CHANGED
@@ -16,7 +16,7 @@ import { defineJQueryPlugin } from './util/index.js'
16
16
  // keeps the full set out of the lite bundle.
17
17
  class DataGrid<TFeatures extends TableFeatures = DataGridFeatures> extends DataGridBase<TFeatures> {
18
18
  static get Default(): DataGridOptions {
19
- return { ...DataGridBase.Default, features: dataGridFeatures }
19
+ return { ...super.Default, features: dataGridFeatures }
20
20
  }
21
21
  }
22
22
 
@@ -57,8 +57,8 @@ export const createColumnChooser = (context: GridColumnChooserContext): GridColu
57
57
 
58
58
  trigger = null
59
59
  element.remove()
60
- document.removeEventListener('pointerdown', onOutsidePointerDown, true)
61
- window.removeEventListener('scroll', onWindowChange, true)
60
+ document.removeEventListener('pointerdown', onOutsidePointerDown, { capture: true })
61
+ window.removeEventListener('scroll', onWindowChange, { capture: true })
62
62
  window.removeEventListener('resize', onWindowChange)
63
63
  }
64
64
 
@@ -156,8 +156,8 @@ export const createColumnChooser = (context: GridColumnChooserContext): GridColu
156
156
  element.style.top = `${buttonRect.bottom - rootRect.top}px`
157
157
  element.style.left = `${Math.max(buttonRect.left - rootRect.left, 0)}px`
158
158
 
159
- document.addEventListener('pointerdown', onOutsidePointerDown, true)
160
- window.addEventListener('scroll', onWindowChange, true)
159
+ document.addEventListener('pointerdown', onOutsidePointerDown, { capture: true })
160
+ window.addEventListener('scroll', onWindowChange, { capture: true })
161
161
  window.addEventListener('resize', onWindowChange)
162
162
  element.querySelector<HTMLElement>('input:not(:disabled)')?.focus()
163
163
  }
@@ -82,8 +82,8 @@ export const createFilterMenu = (context: GridFilterMenuContext): GridFilterMenu
82
82
 
83
83
  trigger = null
84
84
  element.remove()
85
- document.removeEventListener('pointerdown', onOutsidePointerDown, true)
86
- window.removeEventListener('scroll', onWindowChange, true)
85
+ document.removeEventListener('pointerdown', onOutsidePointerDown, { capture: true })
86
+ window.removeEventListener('scroll', onWindowChange, { capture: true })
87
87
  window.removeEventListener('resize', onWindowChange)
88
88
  }
89
89
 
@@ -157,7 +157,6 @@ export const createFilterMenu = (context: GridFilterMenuContext): GridFilterMenu
157
157
  const readCondition = (row: HTMLElement): DataGridFilterCondition | null => {
158
158
  const operator = row.querySelector('select')!.value as DataGridFilterOperator
159
159
  const { value } = (row.querySelector<HTMLInputElement>('[data-coreui-filter-value]')!)
160
- const value2 = row.querySelector<HTMLInputElement>('[data-coreui-filter-value2]')!.value
161
160
 
162
161
  if (VALUELESS_OPERATORS.has(operator)) {
163
162
  return { operator }
@@ -167,6 +166,7 @@ export const createFilterMenu = (context: GridFilterMenuContext): GridFilterMenu
167
166
  return null
168
167
  }
169
168
 
169
+ const value2 = row.querySelector<HTMLInputElement>('[data-coreui-filter-value2]')!.value
170
170
  return {
171
171
  operator,
172
172
  value,
@@ -371,8 +371,8 @@ export const createFilterMenu = (context: GridFilterMenuContext): GridFilterMenu
371
371
  element.style.top = `${buttonRect.bottom - rootRect.top}px`
372
372
  element.style.left = `${Math.max(buttonRect.right - rootRect.left - element.offsetWidth, 0)}px`
373
373
 
374
- document.addEventListener('pointerdown', onOutsidePointerDown, true)
375
- window.addEventListener('scroll', onWindowChange, true)
374
+ document.addEventListener('pointerdown', onOutsidePointerDown, { capture: true })
375
+ window.addEventListener('scroll', onWindowChange, { capture: true })
376
376
  window.addEventListener('resize', onWindowChange)
377
377
  element.querySelector<HTMLElement>('select, input')?.focus()
378
378
  }
package/src/ui/menu.ts CHANGED
@@ -49,8 +49,8 @@ export const createMenu = (context: GridMenuContext): GridMenu => {
49
49
 
50
50
  trigger = null
51
51
  element.remove()
52
- document.removeEventListener('pointerdown', onOutsidePointerDown, true)
53
- window.removeEventListener('scroll', onWindowChange, true)
52
+ document.removeEventListener('pointerdown', onOutsidePointerDown, { capture: true })
53
+ window.removeEventListener('scroll', onWindowChange, { capture: true })
54
54
  window.removeEventListener('resize', onWindowChange)
55
55
  }
56
56
 
@@ -191,8 +191,8 @@ export const createMenu = (context: GridMenuContext): GridMenu => {
191
191
  // sits at the cell's right edge, where a left-aligned menu would overflow.
192
192
  element.style.left = `${Math.max(buttonRect.right - rootRect.left - element.offsetWidth, 0)}px`
193
193
 
194
- document.addEventListener('pointerdown', onOutsidePointerDown, true)
195
- window.addEventListener('scroll', onWindowChange, true)
194
+ document.addEventListener('pointerdown', onOutsidePointerDown, { capture: true })
195
+ window.addEventListener('scroll', onWindowChange, { capture: true })
196
196
  window.addEventListener('resize', onWindowChange)
197
197
  items()[0]?.focus()
198
198
  }
@@ -137,7 +137,7 @@ export const createPagination = (context: GridPaginationContext): GridPagination
137
137
 
138
138
  // A configured pageSize outside pageSizeOptions would leave the select
139
139
  // blank; surface it as an extra option in numeric position.
140
- if (![...select.options].some(option => option.value === String(state.pageSize))) {
140
+ if ([...select.options].every(option => option.value !== String(state.pageSize))) {
141
141
  const option = document.createElement('option')
142
142
  option.value = String(state.pageSize)
143
143
  option.textContent = String(state.pageSize)
package/src/ui/tooltip.ts CHANGED
@@ -96,7 +96,7 @@ export const createTooltip = (root: HTMLElement): GridTooltip => {
96
96
  root.addEventListener('pointerdown', hide)
97
97
  root.addEventListener('focusin', onFocusIn as EventListener)
98
98
  root.addEventListener('focusout', hide)
99
- window.addEventListener('scroll', hide, true)
99
+ window.addEventListener('scroll', hide, { capture: true })
100
100
 
101
101
  return {
102
102
  dispose() {
@@ -106,7 +106,7 @@ export const createTooltip = (root: HTMLElement): GridTooltip => {
106
106
  root.removeEventListener('pointerdown', hide)
107
107
  root.removeEventListener('focusin', onFocusIn as EventListener)
108
108
  root.removeEventListener('focusout', hide)
109
- window.removeEventListener('scroll', hide, true)
109
+ window.removeEventListener('scroll', hide, { capture: true })
110
110
  element.remove()
111
111
  }
112
112
  }
package/src/util/csv.ts CHANGED
@@ -43,12 +43,12 @@ export const exportCsv = (table: CsvTable, options: CsvOptions = {}): string =>
43
43
  const value = row.getValue(column.id)
44
44
  const formatter = formatterFor(column)
45
45
  // Coerce: a formatter may return a number/null in plain-JS usage.
46
- return formatter ? String(formatter(value, row.original) ?? '') : String(value ?? '')
46
+ return String(formatter ? formatter(value, row.original) ?? '' : value ?? '')
47
47
  }))
48
48
  )
49
49
 
50
50
  const csv = [header, ...body].join('\r\n')
51
- return options.bom ? `\uFEFF${csv}` : csv
51
+ return options.bom ? `\u{FEFF}${csv}` : csv
52
52
  }
53
53
 
54
54
  export const downloadCsv = (table: CsvTable, options: CsvDownloadOptions = {}): void => {
@@ -13,9 +13,10 @@
13
13
  // layout to have a direction. LTR is the right answer there: the server-side
14
14
  // pass emits logical markup either way, and the client corrects on hydration.
15
15
  export const isElementRTL = (element: Element | null | undefined): boolean =>
16
- typeof getComputedStyle === 'function' && element ?
17
- getComputedStyle(element).direction === 'rtl' :
18
- false
16
+ typeof getComputedStyle === 'function' &&
17
+ element !== null &&
18
+ element !== undefined &&
19
+ getComputedStyle(element).direction === 'rtl'
19
20
 
20
21
  interface ResizeDirectionTable {
21
22
  options: { columnResizeDirection?: 'ltr' | 'rtl' }
package/src/util/drag.ts CHANGED
@@ -5,6 +5,8 @@
5
5
  * --------------------------------------------------------------------------
6
6
  */
7
7
 
8
+ import { escapeAttributeValue } from './selector'
9
+
8
10
  // The one drag implementation behind every reorder in the grid: column drag
9
11
  // (axis 'x', over the header) and row drag (axis 'y', over the body). It is
10
12
  // headless in the sense that matters — it never reads the table, only what the
@@ -726,7 +728,7 @@ const columnItems = (root: HTMLElement): DragItems => ({
726
728
  [...root.querySelectorAll<HTMLTableCellElement>('thead tr:first-child th[data-coreui-column]')]
727
729
  .map(cell => cell.dataset.coreuiColumn ?? ''),
728
730
  getElements(id) {
729
- const header = root.querySelector<HTMLTableCellElement>(`thead th[data-coreui-column="${id}"]`)
731
+ const header = root.querySelector<HTMLTableCellElement>(`thead th[data-coreui-column="${escapeAttributeValue(id)}"]`)
730
732
  if (!header) {
731
733
  return []
732
734
  }
@@ -775,7 +777,7 @@ export const createColumnDragController = (options: ColumnDragOptions): DragCont
775
777
  // consumer's own veto — an immovable column is not somewhere to land.
776
778
  canDrop: (sourceId, targetId) =>
777
779
  sourceId !== targetId &&
778
- Boolean(options.root.querySelector(`th[data-coreui-column="${targetId}"][data-coreui-draggable]`)) &&
780
+ Boolean(options.root.querySelector(`th[data-coreui-column="${escapeAttributeValue(targetId)}"][data-coreui-draggable]`)) &&
779
781
  options.canDrop(sourceId, targetId),
780
782
  preview: true,
781
783
  onDrop: (sourceKey, drop) => options.onReorder(sourceKey, drop.id, drop.after)
@@ -788,7 +790,7 @@ const rowItems = (root: HTMLElement): DragItems => ({
788
790
  getOrderedIds: () =>
789
791
  [...root.querySelectorAll<HTMLElement>(`tbody ${SELECTOR_ROW}`)].map(row => row.dataset.coreuiIndex ?? ''),
790
792
  getElements(id) {
791
- const row = root.querySelector<HTMLElement>(`tbody tr[data-coreui-index="${id}"]`)
793
+ const row = root.querySelector<HTMLElement>(`tbody tr[data-coreui-index="${escapeAttributeValue(id)}"]`)
792
794
  return row ? [row] : []
793
795
  }
794
796
  })
@@ -0,0 +1,16 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI PRO data-grid util/selector.ts
4
+ * License (https://coreui.io/pro/license/)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+
8
+ /**
9
+ * Escapes a column key or row index for a double-quoted CSS attribute selector value.
10
+ * @param value The key or index interpolated into `[data-…="…"]`.
11
+ * @returns The value as a string, with `"` and `\` backslash-escaped and line breaks as hex escapes.
12
+ */
13
+ export const escapeAttributeValue = (value: string | number): string =>
14
+ String(value)
15
+ .replace(/["\\]/g, '\\$&')
16
+ .replace(/[\n\r\f]/g, character => `\\${character.codePointAt(0)!.toString(16)} `)
package/src/util/xlsx.ts CHANGED
@@ -33,7 +33,7 @@ const MAX_COLUMN_WIDTH = 120
33
33
  // XML 1.0 forbids most control characters outright - Excel refuses to open a
34
34
  // file containing them, so they are dropped rather than escaped.
35
35
  // eslint-disable-next-line no-control-regex -- matching them is the point
36
- const CONTROL_CHARACTERS = /[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g
36
+ const CONTROL_CHARACTERS = /[\u{0}-\u{8}\u{B}\u{C}\u{E}-\u{1F}]/gu
37
37
 
38
38
  const escapeXml = (value: string): string =>
39
39
  value