@wishbone-media/spark 0.46.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3633 -3596
- package/package.json +1 -1
- package/src/assets/css/spark-table.css +17 -3
- package/src/components/SparkTable.vue +92 -33
package/package.json
CHANGED
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
td {
|
|
40
|
-
@apply
|
|
40
|
+
@apply whitespace-nowrap text-gray-500 text-sm align-middle h-auto;
|
|
41
|
+
padding: var(--spark-table-cell-py, 16px) var(--spark-table-cell-px, 24px);
|
|
41
42
|
@apply !border-l-0 !border-r-0 !border-gray-200;
|
|
42
43
|
|
|
43
44
|
&:not(.read-only) {
|
|
@@ -48,6 +49,18 @@
|
|
|
48
49
|
td:not(:last-child) {
|
|
49
50
|
@apply !border-r-0;
|
|
50
51
|
}
|
|
52
|
+
|
|
53
|
+
td.spark-table-word-wrap {
|
|
54
|
+
@apply whitespace-normal break-words;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
td.spark-table-align-center {
|
|
58
|
+
@apply text-center;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
td.spark-table-align-right {
|
|
62
|
+
@apply text-right;
|
|
63
|
+
}
|
|
51
64
|
}
|
|
52
65
|
}
|
|
53
66
|
|
|
@@ -66,7 +79,7 @@
|
|
|
66
79
|
@apply text-left text-xs font-semibold bg-gray-50 text-gray-800 whitespace-normal
|
|
67
80
|
tracking-wider focus:outline-hidden filter flex items-center;
|
|
68
81
|
|
|
69
|
-
|
|
82
|
+
padding: var(--spark-table-header-py, 12px) var(--spark-table-header-px, 20px) !important;
|
|
70
83
|
|
|
71
84
|
.fa-sort-up,
|
|
72
85
|
.fa-sort-down {
|
|
@@ -119,7 +132,8 @@
|
|
|
119
132
|
}
|
|
120
133
|
|
|
121
134
|
.spark-table-head-sorting {
|
|
122
|
-
@apply absolute
|
|
135
|
+
@apply absolute w-5 h-5 border border-gray-200 rounded-md grid place-items-center;
|
|
136
|
+
right: var(--spark-table-header-px, 20px);
|
|
123
137
|
}
|
|
124
138
|
|
|
125
139
|
.spark-table-head-title-wrapper {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="spark-table">
|
|
2
|
+
<div class="spark-table" :style="spacingStyles">
|
|
3
3
|
<!-- Header Toolbar: All plugins flow left to right -->
|
|
4
4
|
<SparkTableToolbar
|
|
5
5
|
v-if="sparkTable.computed.ready && headerPlugins && headerPlugins.length"
|
|
@@ -75,6 +75,12 @@ const defaultTableSettings = {
|
|
|
75
75
|
readOnlyCellClassName: 'read-only',
|
|
76
76
|
licenseKey: 'non-commercial-and-evaluation',
|
|
77
77
|
}
|
|
78
|
+
|
|
79
|
+
const spacingPresets = {
|
|
80
|
+
sm: { cellPx: 12, cellPy: 8, headerPx: 12, headerPy: 12 },
|
|
81
|
+
base: { cellPx: 24, cellPy: 16, headerPx: 20, headerPy: 12 },
|
|
82
|
+
lg: { cellPx: 32, cellPy: 20, headerPx: 24, headerPy: 16 },
|
|
83
|
+
}
|
|
78
84
|
</script>
|
|
79
85
|
<script setup>
|
|
80
86
|
import { computed, onMounted, onUnmounted, ref, reactive, inject, watch } from 'vue'
|
|
@@ -178,6 +184,23 @@ const props = defineProps({
|
|
|
178
184
|
type: Boolean,
|
|
179
185
|
default: false,
|
|
180
186
|
},
|
|
187
|
+
|
|
188
|
+
spacing: {
|
|
189
|
+
type: [String, Object],
|
|
190
|
+
default: null,
|
|
191
|
+
},
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
const spacingStyles = computed(() => {
|
|
195
|
+
if (!props.spacing) return {}
|
|
196
|
+
const values = typeof props.spacing === 'string' ? spacingPresets[props.spacing] : props.spacing
|
|
197
|
+
if (!values) return {}
|
|
198
|
+
const styles = {}
|
|
199
|
+
if (values.cellPx !== undefined) styles['--spark-table-cell-px'] = `${values.cellPx}px`
|
|
200
|
+
if (values.cellPy !== undefined) styles['--spark-table-cell-py'] = `${values.cellPy}px`
|
|
201
|
+
if (values.headerPx !== undefined) styles['--spark-table-header-px'] = `${values.headerPx}px`
|
|
202
|
+
if (values.headerPy !== undefined) styles['--spark-table-header-py'] = `${values.headerPy}px`
|
|
203
|
+
return styles
|
|
181
204
|
})
|
|
182
205
|
|
|
183
206
|
registerAllCellTypes()
|
|
@@ -356,40 +379,76 @@ const sparkTable = reactive({
|
|
|
356
379
|
...props.options,
|
|
357
380
|
})),
|
|
358
381
|
|
|
359
|
-
tableSettings: computed(() =>
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
382
|
+
tableSettings: computed(() => {
|
|
383
|
+
const columns = get(props.settings, 'columns', [])
|
|
384
|
+
|
|
385
|
+
const transformedColumns = columns.map((col) => {
|
|
386
|
+
if (!col.wordWrap && !col.align) return col
|
|
387
|
+
const classes = [col.className]
|
|
388
|
+
if (col.wordWrap) classes.push('spark-table-word-wrap')
|
|
389
|
+
if (col.align === 'center') classes.push('spark-table-align-center')
|
|
390
|
+
if (col.align === 'right') classes.push('spark-table-align-right')
|
|
391
|
+
return { ...col, className: classes.filter(Boolean).join(' ') }
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
const hasClampedColumns = columns.some(
|
|
395
|
+
(col) => typeof col.wordWrap === 'object' && col.wordWrap?.maxLines,
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
const userAfterRenderer = props.settings.afterRenderer
|
|
399
|
+
|
|
400
|
+
return {
|
|
401
|
+
...defaultTableSettings,
|
|
402
|
+
nestedHeaders: get(props.settings, 'nestedHeaders', []),
|
|
403
|
+
...(!get(props.settings, 'nestedHeaders') && {
|
|
404
|
+
afterGetColHeader: (col, th) => customiseHeader(col, th, sparkTable),
|
|
405
|
+
}),
|
|
406
|
+
afterChange: (changes, source) => updateRow(changes, source, sparkTable),
|
|
407
|
+
afterRender: () => syncSortClasses(sparkTable),
|
|
408
|
+
beforeStretchingColumnWidth: (stretchedWidth, column) => {
|
|
409
|
+
const columnSettings = columns[column]
|
|
410
|
+
if (columnSettings && columnSettings.width !== undefined) {
|
|
411
|
+
return columnSettings.width
|
|
412
|
+
}
|
|
413
|
+
return stretchedWidth
|
|
414
|
+
},
|
|
415
|
+
beforeCopy: (data, coords) => {
|
|
416
|
+
const hot = table.value?.hotInstance
|
|
417
|
+
if (!hot) return
|
|
418
|
+
coords.forEach((range) => {
|
|
419
|
+
for (let row = range.startRow; row <= range.endRow; row++) {
|
|
420
|
+
for (let col = range.startCol; col <= range.endCol; col++) {
|
|
421
|
+
const td = hot.getCell(row, col)
|
|
422
|
+
if (td) {
|
|
423
|
+
const dataRow = row - coords[0].startRow
|
|
424
|
+
const dataCol = col - coords[0].startCol
|
|
425
|
+
data[dataRow][dataCol] = td.dataset.copyValue ?? td.textContent ?? ''
|
|
426
|
+
}
|
|
386
427
|
}
|
|
387
428
|
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
429
|
+
})
|
|
430
|
+
},
|
|
431
|
+
...props.settings,
|
|
432
|
+
columns: transformedColumns,
|
|
433
|
+
...(hasClampedColumns && {
|
|
434
|
+
afterRenderer: (td, row, col) => {
|
|
435
|
+
userAfterRenderer?.(td, row, col)
|
|
436
|
+
const colConfig = columns[col]
|
|
437
|
+
const wordWrap = colConfig?.wordWrap
|
|
438
|
+
if (!wordWrap || wordWrap === true || !wordWrap.maxLines) return
|
|
439
|
+
|
|
440
|
+
const wrapper = document.createElement('div')
|
|
441
|
+
wrapper.style.display = '-webkit-box'
|
|
442
|
+
wrapper.style.webkitBoxOrient = 'vertical'
|
|
443
|
+
wrapper.style.webkitLineClamp = wordWrap.maxLines
|
|
444
|
+
wrapper.style.overflow = 'hidden'
|
|
445
|
+
|
|
446
|
+
while (td.firstChild) wrapper.appendChild(td.firstChild)
|
|
447
|
+
td.appendChild(wrapper)
|
|
448
|
+
},
|
|
449
|
+
}),
|
|
450
|
+
}
|
|
451
|
+
}),
|
|
393
452
|
})
|
|
394
453
|
|
|
395
454
|
// Empty state detection - true when data has loaded but contains no records
|