@coreui/data-grid 0.1.0-rc.0 → 0.2.0-rc.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 (137) hide show
  1. package/README.md +5 -4
  2. package/dist/css/data-grid.css +149 -31
  3. package/dist/css/data-grid.css.map +1 -1
  4. package/dist/css/data-grid.min.css +2 -2
  5. package/dist/css/data-grid.min.css.map +1 -1
  6. package/dist/js/clipboard.cjs +56 -0
  7. package/dist/js/clipboard.cjs.map +1 -0
  8. package/dist/js/clipboard.mjs +54 -0
  9. package/dist/js/clipboard.mjs.map +1 -0
  10. package/dist/js/csv.cjs +36 -59
  11. package/dist/js/csv.cjs.map +1 -1
  12. package/dist/js/csv.mjs +35 -55
  13. package/dist/js/csv.mjs.map +1 -1
  14. package/dist/js/data-grid.esm.js +14078 -9332
  15. package/dist/js/data-grid.esm.js.map +1 -1
  16. package/dist/js/data-grid.esm.min.js +6 -6
  17. package/dist/js/data-grid.esm.min.js.map +1 -1
  18. package/dist/js/data-grid.js +14377 -9634
  19. package/dist/js/data-grid.js.map +1 -1
  20. package/dist/js/data-grid.lite.esm.js +10476 -0
  21. package/dist/js/data-grid.lite.esm.js.map +1 -0
  22. package/dist/js/data-grid.lite.esm.min.js +8 -0
  23. package/dist/js/data-grid.lite.esm.min.js.map +1 -0
  24. package/dist/js/data-grid.lite.js +10489 -0
  25. package/dist/js/data-grid.lite.js.map +1 -0
  26. package/dist/js/data-grid.lite.min.js +8 -0
  27. package/dist/js/data-grid.lite.min.js.map +1 -0
  28. package/dist/js/data-grid.lite.mjs +10476 -0
  29. package/dist/js/data-grid.lite.mjs.map +1 -0
  30. package/dist/js/data-grid.min.js +6 -6
  31. package/dist/js/data-grid.min.js.map +1 -1
  32. package/dist/js/data-grid.mjs +14078 -9332
  33. package/dist/js/data-grid.mjs.map +1 -1
  34. package/dist/js/drag.cjs +459 -0
  35. package/dist/js/drag.cjs.map +1 -0
  36. package/dist/js/drag.mjs +456 -0
  37. package/dist/js/drag.mjs.map +1 -0
  38. package/dist/js/export-table-CNAKStzj.mjs +26 -0
  39. package/dist/js/export-table-CNAKStzj.mjs.map +1 -0
  40. package/dist/js/export-table-doIwvE5U.cjs +55 -0
  41. package/dist/js/export-table-doIwvE5U.cjs.map +1 -0
  42. package/dist/js/filters.cjs +89 -132
  43. package/dist/js/filters.cjs.map +1 -1
  44. package/dist/js/filters.mjs +88 -128
  45. package/dist/js/filters.mjs.map +1 -1
  46. package/dist/js/labels.cjs +65 -70
  47. package/dist/js/labels.cjs.map +1 -1
  48. package/dist/js/labels.mjs +64 -66
  49. package/dist/js/labels.mjs.map +1 -1
  50. package/dist/js/print.cjs +66 -0
  51. package/dist/js/print.cjs.map +1 -0
  52. package/dist/js/print.mjs +64 -0
  53. package/dist/js/print.mjs.map +1 -0
  54. package/dist/js/validate.cjs +43 -0
  55. package/dist/js/validate.cjs.map +1 -0
  56. package/dist/js/validate.mjs +42 -0
  57. package/dist/js/validate.mjs.map +1 -0
  58. package/dist/js/xlsx.cjs +240 -0
  59. package/dist/js/xlsx.cjs.map +1 -0
  60. package/dist/js/xlsx.mjs +238 -0
  61. package/dist/js/xlsx.mjs.map +1 -0
  62. package/dist/types/base-component.d.ts +28 -18
  63. package/dist/types/data-grid.d.ts +26 -13
  64. package/dist/types/dom/data.d.ts +15 -0
  65. package/dist/types/dom/event-handler.d.ts +21 -10
  66. package/dist/types/dom/manipulator.d.ts +15 -8
  67. package/dist/types/engine/data-source.d.ts +1 -1
  68. package/dist/types/engine/features-lite.d.ts +25 -0
  69. package/dist/types/engine/features.d.ts +35 -0
  70. package/dist/types/engine/table.d.ts +3 -3
  71. package/dist/types/engine/validate.d.mts +1 -0
  72. package/dist/types/engine/validate.d.ts +20 -0
  73. package/dist/types/engine/virtualizer.d.ts +2 -0
  74. package/dist/types/icons.d.ts +6 -4
  75. package/dist/types/index-lite.d.mts +1 -0
  76. package/dist/types/index-lite.d.ts +19 -0
  77. package/dist/types/index.d.ts +11 -2
  78. package/dist/types/types.d.ts +53 -31
  79. package/dist/types/ui/body.d.ts +6 -3
  80. package/dist/types/ui/header.d.ts +3 -2
  81. package/dist/types/ui/loading.d.ts +1 -1
  82. package/dist/types/ui/pinning.d.ts +1 -1
  83. package/dist/types/ui/toolbar.d.ts +10 -2
  84. package/dist/types/util/clipboard.d.mts +1 -0
  85. package/dist/types/util/clipboard.d.ts +29 -0
  86. package/dist/types/util/config.d.ts +27 -10
  87. package/dist/types/util/csv.d.ts +5 -5
  88. package/dist/types/util/drag.d.mts +1 -0
  89. package/dist/types/util/drag.d.ts +48 -0
  90. package/dist/types/util/export-table.d.ts +47 -0
  91. package/dist/types/util/index.d.ts +66 -10
  92. package/dist/types/util/print.d.mts +1 -0
  93. package/dist/types/util/print.d.ts +32 -0
  94. package/dist/types/util/sanitizer.d.ts +15 -11
  95. package/dist/types/util/xlsx.d.mts +1 -0
  96. package/dist/types/util/xlsx.d.ts +17 -0
  97. package/dist/types/util/zip.d.ts +11 -0
  98. package/package.json +88 -10
  99. package/scss/data-grid.scss +204 -16
  100. package/src/{base-component.js → base-component.ts} +21 -17
  101. package/src/data-grid.ts +507 -200
  102. package/src/dom/{data.js → data.ts} +13 -10
  103. package/src/dom/event-handler.ts +380 -0
  104. package/src/dom/{manipulator.js → manipulator.ts} +11 -11
  105. package/src/engine/data-source.ts +7 -3
  106. package/src/engine/features-lite.ts +47 -0
  107. package/src/engine/features.ts +68 -0
  108. package/src/engine/table.ts +80 -47
  109. package/src/engine/validate.ts +64 -0
  110. package/src/engine/virtualizer.ts +17 -1
  111. package/src/icons.ts +11 -5
  112. package/src/index-lite.ts +85 -0
  113. package/src/index.ts +30 -2
  114. package/src/labels.ts +6 -4
  115. package/src/types.ts +87 -32
  116. package/src/ui/body.ts +73 -17
  117. package/src/ui/header.ts +51 -26
  118. package/src/ui/loading.ts +2 -2
  119. package/src/ui/pinning.ts +16 -16
  120. package/src/ui/toolbar.ts +27 -3
  121. package/src/util/clipboard.ts +112 -0
  122. package/src/util/{config.js → config.ts} +25 -11
  123. package/src/util/csv.ts +11 -30
  124. package/src/util/drag.ts +798 -0
  125. package/src/util/export-table.ts +86 -0
  126. package/src/util/{index.js → index.ts} +55 -35
  127. package/src/util/print.ts +125 -0
  128. package/src/util/{sanitizer.js → sanitizer.ts} +17 -13
  129. package/src/util/xlsx.ts +183 -0
  130. package/src/util/zip.ts +170 -0
  131. package/src/base-component.d.ts +0 -19
  132. package/src/dom/event-handler.d.ts +0 -11
  133. package/src/dom/event-handler.js +0 -331
  134. package/src/dom/manipulator.d.ts +0 -9
  135. package/src/util/config.d.ts +0 -11
  136. package/src/util/index.d.ts +0 -10
  137. package/src/util/sanitizer.d.ts +0 -11
@@ -1,7 +1,7 @@
1
- // Vendored from https://github.com/coreui/coreui-pro/blob/bc4daf1cd79d527bf665d615c0a31f53ab0c3d4e/js/src/dom/data.js — sync manually
1
+ // Vendored from https://github.com/coreui/coreui-pro/blob/e9355580e/js/src/dom/data.ts — sync manually
2
2
  /**
3
3
  * --------------------------------------------------------------------------
4
- * CoreUI dom/data.js
4
+ * CoreUI dom/data.ts
5
5
  * Licensed under MIT (https://github.com/coreui/coreui/blob/main/LICENSE)
6
6
  *
7
7
  * This is a modified version of the Bootstrap's dom/data.js
@@ -13,15 +13,15 @@
13
13
  * Constants
14
14
  */
15
15
 
16
- const elementMap = new Map()
16
+ const elementMap = new Map<Element, Map<string, unknown>>()
17
17
 
18
18
  export default {
19
- set(element, key, instance) {
19
+ set(element: Element, key: string, instance: unknown): void {
20
20
  if (!elementMap.has(element)) {
21
21
  elementMap.set(element, new Map())
22
22
  }
23
23
 
24
- const instanceMap = elementMap.get(element)
24
+ const instanceMap = elementMap.get(element)!
25
25
 
26
26
  // make it clear we only want one instance per element
27
27
  // can be removed later when multiple key/instances are fine to be used
@@ -34,20 +34,23 @@ export default {
34
34
  instanceMap.set(key, instance)
35
35
  },
36
36
 
37
- get(element, key) {
38
- if (elementMap.has(element)) {
39
- return elementMap.get(element).get(key) || null
37
+ // Callers pass the result of getElement(), which can be null; Map.has(null)
38
+ // is simply false at runtime, so the parameter is widened without adding a
39
+ // guard that would change the emitted code.
40
+ get(element: Element | null, key: string): any {
41
+ if (elementMap.has(element as Element)) {
42
+ return elementMap.get(element as Element)!.get(key) || null
40
43
  }
41
44
 
42
45
  return null
43
46
  },
44
47
 
45
- remove(element, key) {
48
+ remove(element: Element, key: string): void {
46
49
  if (!elementMap.has(element)) {
47
50
  return
48
51
  }
49
52
 
50
- const instanceMap = elementMap.get(element)
53
+ const instanceMap = elementMap.get(element)!
51
54
 
52
55
  instanceMap.delete(key)
53
56
 
@@ -0,0 +1,380 @@
1
+ // Vendored from https://github.com/coreui/coreui-pro/blob/e9355580e/js/src/dom/event-handler.ts — sync manually
2
+ /**
3
+ * --------------------------------------------------------------------------
4
+ * CoreUI dom/event-handler.ts
5
+ * Licensed under MIT (https://github.com/coreui/coreui/blob/main/LICENSE)
6
+ *
7
+ * This is a modified version of the Bootstrap's dom/event-handler.ts
8
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
9
+ * --------------------------------------------------------------------------
10
+ */
11
+
12
+ import { getjQuery } from '../util/index.js'
13
+
14
+ /**
15
+ * Types
16
+ */
17
+
18
+ type CoreUIEvent = Event & Record<string, any>
19
+
20
+ type EventCallable = (this: any, event: CoreUIEvent) => any
21
+
22
+ interface WrappedHandler {
23
+ (this: Element, event: Event): any
24
+ oneOff?: boolean
25
+ uidEvent?: string | number
26
+ callable?: EventCallable
27
+ delegationSelector?: string | null
28
+ handlerTypeEvent?: string
29
+ }
30
+
31
+ interface NormalizedParameters {
32
+ isDelegated: boolean
33
+ callable: EventCallable
34
+ typeEvent: string
35
+ handlerTypeEvent: string
36
+ }
37
+
38
+ type ElementEvents = Record<string, Record<string, WrappedHandler>>
39
+
40
+ /**
41
+ * Constants
42
+ */
43
+
44
+ const namespaceRegex = /[^.]*(?=\..*)\.|.*/
45
+ const stripNameRegex = /\..*/
46
+ const stripUidRegex = /::\d+$/
47
+ const eventRegistry: Record<string | number, ElementEvents> = {} // Events storage
48
+ let uidEvent = 1
49
+ const customEvents: Record<string, string> = {
50
+ mouseenter: 'mouseover',
51
+ mouseleave: 'mouseout'
52
+ }
53
+
54
+ const nativeEvents = new Set([
55
+ 'click',
56
+ 'dblclick',
57
+ 'mouseup',
58
+ 'mousedown',
59
+ 'contextmenu',
60
+ 'mousewheel',
61
+ 'DOMMouseScroll',
62
+ 'mouseover',
63
+ 'mouseout',
64
+ 'mousemove',
65
+ 'selectstart',
66
+ 'selectend',
67
+ 'keydown',
68
+ 'keypress',
69
+ 'keyup',
70
+ 'beforeinput',
71
+ 'copy',
72
+ 'cut',
73
+ 'paste',
74
+ 'orientationchange',
75
+ 'touchstart',
76
+ 'touchmove',
77
+ 'touchend',
78
+ 'touchcancel',
79
+ 'pointerdown',
80
+ 'pointermove',
81
+ 'pointerup',
82
+ 'pointerleave',
83
+ 'pointercancel',
84
+ // Local addition over the coreui-pro source: HTML5 drag & drop events used
85
+ // by the data grid's column reordering.
86
+ 'drag',
87
+ 'dragstart',
88
+ 'dragend',
89
+ 'dragenter',
90
+ 'dragleave',
91
+ 'dragover',
92
+ 'drop',
93
+ 'gesturestart',
94
+ 'gesturechange',
95
+ 'gestureend',
96
+ 'focus',
97
+ 'blur',
98
+ 'change',
99
+ 'input',
100
+ 'reset',
101
+ 'select',
102
+ 'submit',
103
+ 'focusin',
104
+ 'focusout',
105
+ 'load',
106
+ 'unload',
107
+ 'beforeunload',
108
+ 'resize',
109
+ 'move',
110
+ 'DOMContentLoaded',
111
+ 'readystatechange',
112
+ 'error',
113
+ 'abort',
114
+ 'scroll'
115
+ ])
116
+
117
+ /**
118
+ * Private methods
119
+ */
120
+
121
+ function makeEventUid(element: any, uid?: string): string | number {
122
+ return (uid && `${uid}::${uidEvent++}`) || element.uidEvent || uidEvent++
123
+ }
124
+
125
+ function getElementEvents(element: Element & { uidEvent?: string | number }): ElementEvents {
126
+ const uid = makeEventUid(element)
127
+
128
+ element.uidEvent = uid
129
+ eventRegistry[uid] = eventRegistry[uid] || {}
130
+
131
+ return eventRegistry[uid]
132
+ }
133
+
134
+ // `mouseenter` and `mouseleave` ride on `mouseover` and `mouseout`, which also fire when
135
+ // the pointer moves between descendants of the listening element. Drop those events, so the
136
+ // handler only sees the pointer entering or leaving `delegateTarget` itself.
137
+ // `Node.contains()` is inclusive, so this also covers `relatedTarget === delegateTarget`.
138
+ function isMouseEventWithinTarget(event: CoreUIEvent): boolean {
139
+ const { delegateTarget, relatedTarget } = event
140
+
141
+ return Boolean(relatedTarget && delegateTarget.contains(relatedTarget))
142
+ }
143
+
144
+ function bootstrapHandler(element: Element, fn: EventCallable, handlerTypeEvent: string): WrappedHandler {
145
+ const isCustomMouseEvent = handlerTypeEvent in customEvents
146
+
147
+ return function handler(event: Event) {
148
+ const coreuiEvent = hydrateObj(event, { delegateTarget: element })
149
+
150
+ if (isCustomMouseEvent && isMouseEventWithinTarget(coreuiEvent)) {
151
+ return
152
+ }
153
+
154
+ if ((handler as WrappedHandler).oneOff) {
155
+ EventHandler.off(element, handlerTypeEvent, fn)
156
+ }
157
+
158
+ return fn.apply(element, [coreuiEvent])
159
+ } as WrappedHandler
160
+ }
161
+
162
+ function bootstrapDelegationHandler(element: Element, selector: string, fn: EventCallable, handlerTypeEvent: string): WrappedHandler {
163
+ const isCustomMouseEvent = handlerTypeEvent in customEvents
164
+
165
+ return function handler(this: Element, event: Event) {
166
+ const domElements = element.querySelectorAll(selector)
167
+
168
+ for (let { target } = event; target && target !== this; target = (target as Node).parentNode) {
169
+ for (const domElement of domElements) {
170
+ if (domElement !== target) {
171
+ continue
172
+ }
173
+
174
+ const coreuiEvent = hydrateObj(event, { delegateTarget: target })
175
+
176
+ if (isCustomMouseEvent && isMouseEventWithinTarget(coreuiEvent)) {
177
+ return
178
+ }
179
+
180
+ if ((handler as WrappedHandler).oneOff) {
181
+ EventHandler.off(element, handlerTypeEvent, selector, fn)
182
+ }
183
+
184
+ return fn.apply(target, [coreuiEvent])
185
+ }
186
+ }
187
+ } as WrappedHandler
188
+ }
189
+
190
+ function findHandler(events: Record<string, WrappedHandler>, callable: EventCallable, handlerTypeEvent: string, delegationSelector: string | null = null): WrappedHandler | undefined {
191
+ return Object.values(events)
192
+ .find(event => event.callable === callable && event.handlerTypeEvent === handlerTypeEvent && event.delegationSelector === delegationSelector)
193
+ }
194
+
195
+ // `typeEvent` is the DOM event type the listener is registered under. `handlerTypeEvent` is
196
+ // the type the caller asked for. The two differ only for `mouseenter` and `mouseleave`, which
197
+ // the registry must keep apart from the `mouseover` and `mouseout` listeners they share.
198
+ function normalizeParameters(originalTypeEvent: string, handler?: string | EventCallable, delegationFunction?: EventCallable): NormalizedParameters {
199
+ const isDelegated = typeof handler === 'string'
200
+ // TODO: tooltip passes `false` instead of selector, so we need to check
201
+ const callable = (isDelegated ? delegationFunction : (handler || delegationFunction)) as EventCallable
202
+ // Strip the namespace to get the plain event ('click.coreui.button' --> 'click')
203
+ const baseTypeEvent = originalTypeEvent.replace(stripNameRegex, '')
204
+ let typeEvent = customEvents[baseTypeEvent] || baseTypeEvent
205
+
206
+ if (!nativeEvents.has(typeEvent)) {
207
+ typeEvent = originalTypeEvent
208
+ }
209
+
210
+ const handlerTypeEvent = baseTypeEvent in customEvents ? baseTypeEvent : typeEvent
211
+
212
+ return {
213
+ isDelegated, callable, typeEvent, handlerTypeEvent
214
+ }
215
+ }
216
+
217
+ function addHandler(element: Element, originalTypeEvent: string, handler?: string | EventCallable, delegationFunction?: EventCallable, oneOff?: boolean): void {
218
+ if (typeof originalTypeEvent !== 'string' || !element) {
219
+ return
220
+ }
221
+
222
+ const { isDelegated, callable, typeEvent, handlerTypeEvent } = normalizeParameters(originalTypeEvent, handler, delegationFunction)
223
+ const events = getElementEvents(element)
224
+ const handlers = events[typeEvent] || (events[typeEvent] = {})
225
+ const previousFunction = findHandler(handlers, callable, handlerTypeEvent, isDelegated ? (handler as string) : null)
226
+
227
+ if (previousFunction) {
228
+ previousFunction.oneOff = previousFunction.oneOff && oneOff
229
+
230
+ return
231
+ }
232
+
233
+ const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''))
234
+ const fn = isDelegated ?
235
+ bootstrapDelegationHandler(element, handler as string, callable, handlerTypeEvent) :
236
+ bootstrapHandler(element, callable, handlerTypeEvent)
237
+
238
+ fn.delegationSelector = isDelegated ? (handler as string) : null
239
+ fn.callable = callable
240
+ fn.handlerTypeEvent = handlerTypeEvent
241
+ fn.oneOff = oneOff
242
+ fn.uidEvent = uid
243
+ handlers[uid] = fn
244
+
245
+ element.addEventListener(typeEvent, fn, isDelegated)
246
+ }
247
+
248
+ function removeHandler(element: Element, events: ElementEvents, typeEvent: string, handler: WrappedHandler): void {
249
+ element.removeEventListener(typeEvent, handler, Boolean(handler.delegationSelector))
250
+ delete events[typeEvent][handler.uidEvent!]
251
+ }
252
+
253
+ function removeNamespacedHandlers(element: Element, events: ElementEvents, typeEvent: string, namespace: string): void {
254
+ const storeElementEvent = events[typeEvent] || {}
255
+
256
+ for (const [handlerKey, event] of Object.entries(storeElementEvent)) {
257
+ if (handlerKey.includes(namespace)) {
258
+ removeHandler(element, events, typeEvent, event)
259
+ }
260
+ }
261
+ }
262
+
263
+ function getTypeEvent(event: string): string {
264
+ // allow to get the native events from namespaced events ('click.coreui.button' --> 'click')
265
+ event = event.replace(stripNameRegex, '')
266
+ return customEvents[event] || event
267
+ }
268
+
269
+ const EventHandler = {
270
+ on(element: EventTarget | null, event: string, handler?: string | EventCallable, delegationFunction?: EventCallable): void {
271
+ addHandler(element as Element, event, handler, delegationFunction, false)
272
+ },
273
+
274
+ one(element: EventTarget | null, event: string, handler?: string | EventCallable, delegationFunction?: EventCallable): void {
275
+ addHandler(element as Element, event, handler, delegationFunction, true)
276
+ },
277
+
278
+ off(element: EventTarget | null, originalTypeEvent: string, handler?: string | EventCallable, delegationFunction?: EventCallable): void {
279
+ if (typeof originalTypeEvent !== 'string' || !element) {
280
+ return
281
+ }
282
+
283
+ const { isDelegated, callable, typeEvent, handlerTypeEvent } = normalizeParameters(originalTypeEvent, handler, delegationFunction)
284
+ // The caller gave a namespace when neither event type matches what they passed in.
285
+ // `handlerTypeEvent` must take part, or plain `mouseenter` looks namespaced next to `mouseover`.
286
+ const inNamespace = typeEvent !== originalTypeEvent && handlerTypeEvent !== originalTypeEvent
287
+ const events = getElementEvents(element as Element)
288
+ const storeElementEvent = events[typeEvent] || {}
289
+ const isNamespace = originalTypeEvent.startsWith('.')
290
+
291
+ if (typeof callable !== 'undefined') {
292
+ // Simplest case: handler is passed, remove that listener ONLY.
293
+ if (!Object.keys(storeElementEvent).length) {
294
+ return
295
+ }
296
+
297
+ const fn = findHandler(storeElementEvent, callable, handlerTypeEvent, isDelegated ? (handler as string) : null)
298
+
299
+ if (fn) {
300
+ removeHandler(element as Element, events, typeEvent, fn)
301
+ }
302
+
303
+ return
304
+ }
305
+
306
+ if (isNamespace) {
307
+ for (const elementEvent of Object.keys(events)) {
308
+ removeNamespacedHandlers(element as Element, events, elementEvent, originalTypeEvent.slice(1))
309
+ }
310
+ }
311
+
312
+ for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {
313
+ const handlerKey = keyHandlers.replace(stripUidRegex, '')
314
+
315
+ if (event.handlerTypeEvent === handlerTypeEvent && (!inNamespace || originalTypeEvent.includes(handlerKey))) {
316
+ removeHandler(element as Element, events, typeEvent, event)
317
+ }
318
+ }
319
+ },
320
+
321
+ trigger(element: EventTarget | null, event: string, args?: Record<string, unknown>): CoreUIEvent | null {
322
+ if (typeof event !== 'string' || !element) {
323
+ return null
324
+ }
325
+
326
+ const $ = getjQuery()
327
+ const typeEvent = getTypeEvent(event)
328
+ const inNamespace = event !== typeEvent
329
+
330
+ let jQueryEvent = null
331
+ let bubbles = true
332
+ let nativeDispatch = true
333
+ let defaultPrevented = false
334
+
335
+ if (inNamespace && $) {
336
+ jQueryEvent = $.Event(event, args)
337
+
338
+ $(element).trigger(jQueryEvent)
339
+ bubbles = !jQueryEvent.isPropagationStopped()
340
+ nativeDispatch = !jQueryEvent.isImmediatePropagationStopped()
341
+ defaultPrevented = jQueryEvent.isDefaultPrevented()
342
+ }
343
+
344
+ const evt = hydrateObj(new Event(event, { bubbles, cancelable: true }), args)
345
+
346
+ if (defaultPrevented) {
347
+ evt.preventDefault()
348
+ }
349
+
350
+ if (nativeDispatch) {
351
+ element.dispatchEvent(evt)
352
+ }
353
+
354
+ if (evt.defaultPrevented && jQueryEvent) {
355
+ jQueryEvent.preventDefault()
356
+ }
357
+
358
+ return evt
359
+ }
360
+ }
361
+
362
+ function hydrateObj<T extends object>(obj: T, meta: Record<string, unknown> = {}): T & Record<string, any> {
363
+ for (const [key, value] of Object.entries(meta)) {
364
+ try {
365
+ (obj as Record<string, unknown>)[key] = value
366
+ } catch {
367
+ Object.defineProperty(obj, key, {
368
+ configurable: true,
369
+ get() {
370
+ return value
371
+ }
372
+ })
373
+ }
374
+ }
375
+
376
+ return obj
377
+ }
378
+
379
+ export default EventHandler
380
+ export type { CoreUIEvent, EventCallable }
@@ -1,15 +1,15 @@
1
- // Vendored from https://github.com/coreui/coreui-pro/blob/bc4daf1cd79d527bf665d615c0a31f53ab0c3d4e/js/src/dom/manipulator.js — sync manually
1
+ // Vendored from https://github.com/coreui/coreui-pro/blob/e9355580e/js/src/dom/manipulator.ts — sync manually
2
2
  /**
3
3
  * --------------------------------------------------------------------------
4
- * CoreUI dom/manipulator.js
4
+ * CoreUI dom/manipulator.ts
5
5
  * Licensed under MIT (https://github.com/coreui/coreui/blob/main/LICENSE)
6
6
  *
7
- * This is a modified version of the Bootstrap's dom/manipulator.js
7
+ * This is a modified version of the Bootstrap's dom/manipulator.ts
8
8
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
9
9
  * --------------------------------------------------------------------------
10
10
  */
11
11
 
12
- function normalizeData(value) {
12
+ function normalizeData(value: string | null | undefined): unknown {
13
13
  if (value === 'true') {
14
14
  return true
15
15
  }
@@ -37,25 +37,25 @@ function normalizeData(value) {
37
37
  }
38
38
  }
39
39
 
40
- function normalizeDataKey(key) {
40
+ function normalizeDataKey(key: string): string {
41
41
  return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)
42
42
  }
43
43
 
44
44
  const Manipulator = {
45
- setDataAttribute(element, key, value) {
46
- element.setAttribute(`data-coreui-${normalizeDataKey(key)}`, value)
45
+ setDataAttribute(element: Element, key: string, value: unknown): void {
46
+ element.setAttribute(`data-coreui-${normalizeDataKey(key)}`, value as string)
47
47
  },
48
48
 
49
- removeDataAttribute(element, key) {
49
+ removeDataAttribute(element: Element, key: string): void {
50
50
  element.removeAttribute(`data-coreui-${normalizeDataKey(key)}`)
51
51
  },
52
52
 
53
- getDataAttributes(element) {
53
+ getDataAttributes(element: HTMLElement | null): Record<string, unknown> {
54
54
  if (!element) {
55
55
  return {}
56
56
  }
57
57
 
58
- const attributes = {}
58
+ const attributes: Record<string, unknown> = {}
59
59
  const coreuiKeys = Object.keys(element.dataset).filter(key => key.startsWith('coreui') && !key.startsWith('coreuiConfig'))
60
60
 
61
61
  for (const key of coreuiKeys) {
@@ -67,7 +67,7 @@ const Manipulator = {
67
67
  return attributes
68
68
  },
69
69
 
70
- getDataAttribute(element, key) {
70
+ getDataAttribute(element: Element, key: string): unknown {
71
71
  return normalizeData(element.getAttribute(`data-coreui-${normalizeDataKey(key)}`))
72
72
  }
73
73
  }
@@ -12,7 +12,10 @@ const FETCH_DEBOUNCE_MS = 100
12
12
  export interface GridDataSourceContext {
13
13
  getRequest: () => DataGridDataRequest
14
14
  onError: (error: unknown) => void
15
- onLoad: (response: DataGridDataResponse) => void
15
+ // The request is handed back so an appending consumer can tell a first page
16
+ // (replace) from a follow-up one (append) without re-reading table state,
17
+ // which may already have moved on.
18
+ onLoad: (response: DataGridDataResponse, request: DataGridDataRequest) => void
16
19
  onLoadingChange: (loading: boolean) => void
17
20
  provider: (request: DataGridDataRequest) => Promise<DataGridDataResponse>
18
21
  }
@@ -36,12 +39,13 @@ export const createDataSource = (context: GridDataSourceContext): GridDataSource
36
39
  context.onLoadingChange(true)
37
40
 
38
41
  try {
39
- const response = await context.provider(context.getRequest())
42
+ const request = context.getRequest()
43
+ const response = await context.provider(request)
40
44
  if (id !== requestId) {
41
45
  return
42
46
  }
43
47
 
44
- context.onLoad(response)
48
+ context.onLoad(response, request)
45
49
  } catch (error) {
46
50
  if (id !== requestId) {
47
51
  return
@@ -0,0 +1,47 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI PRO data-grid engine/features-lite.ts
4
+ * License (https://coreui.io/pro/license/)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+
8
+ import {
9
+ columnFilteringFeature,
10
+ createFilteredRowModel,
11
+ createPaginatedRowModel,
12
+ createSortedRowModel,
13
+ filterFn_includesString as includesStringFilterFn,
14
+ globalFilteringFeature,
15
+ rowPaginationFeature,
16
+ rowSortingFeature,
17
+ sortFn_alphanumeric as alphanumericSortFn,
18
+ sortFn_datetime as datetimeSortFn,
19
+ sortFn_text as textSortFn,
20
+ tableFeatures
21
+ } from '@tanstack/table-core'
22
+ import { storeReactivityBindings } from '@tanstack/table-core/store-reactivity-bindings'
23
+
24
+ // The smallest set the grid renders with: sorting, filtering (incl. the
25
+ // toolbar search) and pagination. Everything column-shape related (visibility,
26
+ // ordering, pinning, sizing) and selection/faceting stays out - the grid
27
+ // falls back to core APIs for those. sortFns/filterFns stay in so a lite grid
28
+ // sorts and searches exactly like a full one. Kept in its own module so the
29
+ // lite bundle entry never reaches the full set.
30
+ export const dataGridLiteFeatures = tableFeatures({
31
+ coreReactivityFeature: storeReactivityBindings(),
32
+ columnFilteringFeature,
33
+ globalFilteringFeature,
34
+ rowPaginationFeature,
35
+ rowSortingFeature,
36
+ filteredRowModel: createFilteredRowModel(),
37
+ paginatedRowModel: createPaginatedRowModel(),
38
+ sortedRowModel: createSortedRowModel(),
39
+ filterFns: { includesString: includesStringFilterFn },
40
+ sortFns: {
41
+ alphanumeric: alphanumericSortFn,
42
+ datetime: datetimeSortFn,
43
+ text: textSortFn
44
+ }
45
+ })
46
+
47
+ export type DataGridLiteFeatures = typeof dataGridLiteFeatures
@@ -0,0 +1,68 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * CoreUI PRO data-grid engine/features.ts
4
+ * License (https://coreui.io/pro/license/)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+
8
+ import {
9
+ cellSelectionFeature,
10
+ columnFacetingFeature,
11
+ columnFilteringFeature,
12
+ columnOrderingFeature,
13
+ columnPinningFeature,
14
+ columnResizingFeature,
15
+ columnSizingFeature,
16
+ columnVisibilityFeature,
17
+ createFacetedRowModel,
18
+ createFacetedUniqueValues,
19
+ createFilteredRowModel,
20
+ createPaginatedRowModel,
21
+ createSortedRowModel,
22
+ filterFn_includesString as includesStringFilterFn,
23
+ globalFilteringFeature,
24
+ rowPaginationFeature,
25
+ rowSelectionFeature,
26
+ rowSortingFeature,
27
+ sortFn_alphanumeric as alphanumericSortFn,
28
+ sortFn_datetime as datetimeSortFn,
29
+ sortFn_text as textSortFn,
30
+ tableFeatures
31
+ } from '@tanstack/table-core'
32
+ import { storeReactivityBindings } from '@tanstack/table-core/store-reactivity-bindings'
33
+
34
+ // v9 exposes an API only when its feature is registered, so this is the full
35
+ // set of table-core behavior the grid can reach - options gate the behavior,
36
+ // not the registration. Prerequisites must precede dependents: sizing before
37
+ // resizing, filtering before global filtering and faceting, every row-model
38
+ // slot after its feature.
39
+ export const dataGridFeatures = tableFeatures({
40
+ coreReactivityFeature: storeReactivityBindings(),
41
+ cellSelectionFeature,
42
+ columnFilteringFeature,
43
+ globalFilteringFeature,
44
+ columnFacetingFeature,
45
+ columnOrderingFeature,
46
+ columnPinningFeature,
47
+ columnSizingFeature,
48
+ columnResizingFeature,
49
+ columnVisibilityFeature,
50
+ rowPaginationFeature,
51
+ rowSelectionFeature,
52
+ rowSortingFeature,
53
+ facetedRowModel: createFacetedRowModel(),
54
+ facetedUniqueValues: createFacetedUniqueValues(),
55
+ filteredRowModel: createFilteredRowModel(),
56
+ paginatedRowModel: createPaginatedRowModel(),
57
+ sortedRowModel: createSortedRowModel(),
58
+ filterFns: { includesString: includesStringFilterFn },
59
+ // The names column.getAutoSortFn() resolves for sampled value types; without
60
+ // them every column would silently fall back to the basic comparator.
61
+ sortFns: {
62
+ alphanumeric: alphanumericSortFn,
63
+ datetime: datetimeSortFn,
64
+ text: textSortFn
65
+ }
66
+ })
67
+
68
+ export type DataGridFeatures = typeof dataGridFeatures