@invopop/popui 0.1.34 → 0.1.40
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/BaseButton.svelte +4 -0
- package/dist/BaseDropdown.svelte +42 -3
- package/dist/BaseDropdown.svelte.d.ts +1 -0
- package/dist/BaseTableHeaderOrderBy.svelte +35 -12
- package/dist/ButtonSearch.svelte +82 -0
- package/dist/ButtonSearch.svelte.d.ts +4 -0
- package/dist/ButtonUuidCopy.svelte +1 -0
- package/dist/DatePicker.svelte +96 -27
- package/dist/DatePicker.svelte.d.ts +5 -1
- package/dist/DrawerContext.svelte +443 -34
- package/dist/DrawerContextItem.svelte +36 -29
- package/dist/DropdownSelect.svelte +68 -18
- package/dist/DropdownSelect.svelte.d.ts +4 -1
- package/dist/DropdownSelectGroup.svelte +15 -0
- package/dist/DropdownSelectGroup.svelte.d.ts +7 -0
- package/dist/EmptyState.svelte +6 -2
- package/dist/InputSearch.svelte +45 -5
- package/dist/InputSelect.svelte +12 -3
- package/dist/InputText.svelte +25 -8
- package/dist/InputToggle.svelte +23 -6
- package/dist/SeparatorHorizontal.svelte +2 -2
- package/dist/StepIcon.svelte +35 -0
- package/dist/StepIcon.svelte.d.ts +4 -0
- package/dist/StepIconList.svelte +24 -31
- package/dist/TagProgress.svelte +2 -2
- package/dist/TagStatus.svelte +1 -1
- package/dist/button/button.svelte +34 -3
- package/dist/button/button.svelte.d.ts +29 -0
- package/dist/clickOutside.d.ts +5 -2
- package/dist/clickOutside.js +9 -3
- package/dist/data-table/cells/boolean-cell.svelte +29 -0
- package/dist/data-table/cells/boolean-cell.svelte.d.ts +8 -0
- package/dist/data-table/cells/cell-skeleton.svelte +35 -0
- package/dist/data-table/cells/cell-skeleton.svelte.d.ts +4 -0
- package/dist/data-table/cells/currency-cell.svelte +10 -0
- package/dist/data-table/cells/currency-cell.svelte.d.ts +8 -0
- package/dist/data-table/cells/date-cell.svelte +10 -0
- package/dist/data-table/cells/date-cell.svelte.d.ts +8 -0
- package/dist/data-table/cells/tag-cell.svelte +12 -0
- package/dist/data-table/cells/tag-cell.svelte.d.ts +8 -0
- package/dist/data-table/cells/text-cell.svelte +10 -0
- package/dist/data-table/cells/text-cell.svelte.d.ts +8 -0
- package/dist/data-table/cells/uuid-cell.svelte +17 -0
- package/dist/data-table/cells/uuid-cell.svelte.d.ts +8 -0
- package/dist/data-table/column-definitions.d.ts +12 -0
- package/dist/data-table/column-definitions.js +42 -0
- package/dist/data-table/column-sizing-helpers.d.ts +6 -0
- package/dist/data-table/column-sizing-helpers.js +24 -0
- package/dist/data-table/create-columns.d.ts +3 -0
- package/dist/data-table/create-columns.js +67 -0
- package/dist/data-table/data-table-cell.svelte +94 -0
- package/dist/data-table/data-table-cell.svelte.d.ts +25 -0
- package/dist/data-table/data-table-header-cell.svelte +188 -0
- package/dist/data-table/data-table-header-cell.svelte.d.ts +25 -0
- package/dist/data-table/data-table-helpers.d.ts +10 -0
- package/dist/data-table/data-table-helpers.js +124 -0
- package/dist/data-table/data-table-pagination.svelte +214 -0
- package/dist/data-table/data-table-pagination.svelte.d.ts +4 -0
- package/dist/data-table/data-table-row.svelte +57 -0
- package/dist/data-table/data-table-row.svelte.d.ts +25 -0
- package/dist/data-table/data-table-svelte.svelte.d.ts +40 -0
- package/dist/data-table/data-table-svelte.svelte.js +115 -0
- package/dist/data-table/data-table-toolbar.svelte +19 -0
- package/dist/data-table/data-table-toolbar.svelte.d.ts +32 -0
- package/dist/data-table/data-table-types.d.ts +194 -0
- package/dist/data-table/data-table-types.js +1 -0
- package/dist/data-table/data-table-view-options.svelte +126 -0
- package/dist/data-table/data-table-view-options.svelte.d.ts +29 -0
- package/dist/data-table/data-table.svelte +428 -0
- package/dist/data-table/data-table.svelte.d.ts +25 -0
- package/dist/data-table/flex-render.svelte +40 -0
- package/dist/data-table/flex-render.svelte.d.ts +33 -0
- package/dist/data-table/index.d.ts +13 -0
- package/dist/data-table/index.js +13 -0
- package/dist/data-table/render-helpers.d.ts +90 -0
- package/dist/data-table/render-helpers.js +99 -0
- package/dist/data-table/table-setup.d.ts +39 -0
- package/dist/data-table/table-setup.js +151 -0
- package/dist/data-table/table-styles.d.ts +17 -0
- package/dist/data-table/table-styles.js +70 -0
- package/dist/drawer-dnd-helpers.d.ts +30 -0
- package/dist/drawer-dnd-helpers.js +72 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +3 -0
- package/dist/index.d.ts +15 -3
- package/dist/index.js +28 -5
- package/dist/skeleton/index.d.ts +5 -0
- package/dist/skeleton/index.js +7 -0
- package/dist/skeleton/skeleton-avatar.svelte +14 -0
- package/dist/skeleton/skeleton-avatar.svelte.d.ts +7 -0
- package/dist/skeleton/skeleton-card.svelte +22 -0
- package/dist/skeleton/skeleton-card.svelte.d.ts +9 -0
- package/dist/skeleton/skeleton-list.svelte +25 -0
- package/dist/skeleton/skeleton-list.svelte.d.ts +8 -0
- package/dist/skeleton/skeleton.svelte +17 -0
- package/dist/skeleton/skeleton.svelte.d.ts +5 -0
- package/dist/svg/IconDelivery.svelte +1 -1
- package/dist/svg/IconOrder.svelte +1 -1
- package/dist/svg/IconPayment.svelte +1 -1
- package/dist/table/table-cell.svelte +4 -2
- package/dist/table/table-head.svelte +4 -2
- package/dist/table/table-header.svelte +1 -1
- package/dist/table/table-row.svelte +4 -2
- package/dist/table/table.svelte +2 -2
- package/dist/tailwind.theme.css +30 -6
- package/dist/tooltip/index.d.ts +2 -1
- package/dist/tooltip/index.js +3 -2
- package/dist/tooltip/tooltip-auto-hide.svelte +31 -0
- package/dist/tooltip/tooltip-auto-hide.svelte.d.ts +7 -0
- package/dist/types.d.ts +51 -73
- package/package.json +14 -8
- package/dist/BaseTable.svelte +0 -391
- package/dist/BaseTable.svelte.d.ts +0 -4
- package/dist/BaseTableCellContent.svelte +0 -58
- package/dist/BaseTableCellContent.svelte.d.ts +0 -4
- package/dist/BaseTableCheckbox.svelte +0 -33
- package/dist/BaseTableCheckbox.svelte.d.ts +0 -4
- package/dist/BaseTableHeaderContent.svelte +0 -67
- package/dist/BaseTableHeaderContent.svelte.d.ts +0 -4
- package/dist/BaseTableRow.svelte +0 -127
- package/dist/BaseTableRow.svelte.d.ts +0 -4
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
<script lang="ts" generics="TData">
|
|
2
|
+
import {
|
|
3
|
+
type ColumnSizingState,
|
|
4
|
+
type ColumnSizingInfoState,
|
|
5
|
+
type ColumnOrderState,
|
|
6
|
+
type PaginationState,
|
|
7
|
+
type Row,
|
|
8
|
+
type RowSelectionState,
|
|
9
|
+
type SortingState,
|
|
10
|
+
type VisibilityState
|
|
11
|
+
} from '@tanstack/table-core'
|
|
12
|
+
import { onMount, onDestroy } from 'svelte'
|
|
13
|
+
import DataTableToolbar from './data-table-toolbar.svelte'
|
|
14
|
+
import DataTablePagination from './data-table-pagination.svelte'
|
|
15
|
+
import DataTableHeaderCell from './data-table-header-cell.svelte'
|
|
16
|
+
import DataTableRow from './data-table-row.svelte'
|
|
17
|
+
import FlexRender from './flex-render.svelte'
|
|
18
|
+
import * as Table from '../table/index.js'
|
|
19
|
+
import BaseTableActions from '../BaseTableActions.svelte'
|
|
20
|
+
import BaseDropdown from '../BaseDropdown.svelte'
|
|
21
|
+
import EmptyState from '../EmptyState.svelte'
|
|
22
|
+
import Skeleton from '../skeleton/skeleton.svelte'
|
|
23
|
+
import SkeletonAvatar from '../skeleton/skeleton-avatar.svelte'
|
|
24
|
+
import { Search } from '@invopop/ui-icons'
|
|
25
|
+
import { cn } from '../utils.js'
|
|
26
|
+
import type { DataTableProps } from './data-table-types.js'
|
|
27
|
+
import { calculateColumnSizing } from './column-sizing-helpers.js'
|
|
28
|
+
import { getCellStyle, getCellClasses } from './table-styles.js'
|
|
29
|
+
import { buildColumns, setupTable } from './table-setup.js'
|
|
30
|
+
import {
|
|
31
|
+
reorderFrozenColumn,
|
|
32
|
+
reorderUnfrozenColumn,
|
|
33
|
+
calculateFrozenOffset,
|
|
34
|
+
handleScrollEvent,
|
|
35
|
+
shouldIgnoreKeyEvent,
|
|
36
|
+
handleArrowDown,
|
|
37
|
+
handleArrowUp,
|
|
38
|
+
handleSelectKey
|
|
39
|
+
} from './data-table-helpers.js'
|
|
40
|
+
import clsx from 'clsx'
|
|
41
|
+
|
|
42
|
+
let {
|
|
43
|
+
data,
|
|
44
|
+
columns: columnConfig,
|
|
45
|
+
loading = false,
|
|
46
|
+
disableSelection = false,
|
|
47
|
+
disablePagination = false,
|
|
48
|
+
disableKeyboardNavigation = false,
|
|
49
|
+
disableControls = false,
|
|
50
|
+
rowActions = [],
|
|
51
|
+
getRowActions,
|
|
52
|
+
onRowAction,
|
|
53
|
+
initialPageSize = 10,
|
|
54
|
+
initialPage = 0,
|
|
55
|
+
initialSortColumn,
|
|
56
|
+
initialSortDirection,
|
|
57
|
+
initialFrozenColumns = [],
|
|
58
|
+
initialColumnOrder = [],
|
|
59
|
+
initialColumnVisibility = {},
|
|
60
|
+
initialColumnSizing = {},
|
|
61
|
+
emptyState = {
|
|
62
|
+
iconSource: Search,
|
|
63
|
+
title: 'No results',
|
|
64
|
+
description: 'Try adjusting your filters or search query'
|
|
65
|
+
},
|
|
66
|
+
onRowClick,
|
|
67
|
+
onSelectionChange,
|
|
68
|
+
filters,
|
|
69
|
+
paginationSlot,
|
|
70
|
+
manualPagination = false,
|
|
71
|
+
manualSorting = false,
|
|
72
|
+
pageCount,
|
|
73
|
+
rowCount,
|
|
74
|
+
onPageChange,
|
|
75
|
+
onPageSizeChange,
|
|
76
|
+
onSortingChange,
|
|
77
|
+
onFilterChange,
|
|
78
|
+
onFreezeChange,
|
|
79
|
+
onColumnResize,
|
|
80
|
+
onColumnOrderChange,
|
|
81
|
+
onColumnVisibilityChange,
|
|
82
|
+
getRowClassName,
|
|
83
|
+
getRowState,
|
|
84
|
+
children
|
|
85
|
+
}: DataTableProps<TData> = $props()
|
|
86
|
+
|
|
87
|
+
const enableSelection = !disableSelection
|
|
88
|
+
const enablePagination = !disablePagination
|
|
89
|
+
|
|
90
|
+
let rowSelection = $state<RowSelectionState>({})
|
|
91
|
+
let columnVisibility = $state<VisibilityState>(initialColumnVisibility)
|
|
92
|
+
let sorting = $state<SortingState>(
|
|
93
|
+
initialSortColumn && initialSortDirection
|
|
94
|
+
? [{ id: initialSortColumn, desc: initialSortDirection === 'desc' }]
|
|
95
|
+
: []
|
|
96
|
+
)
|
|
97
|
+
let pagination = $state<PaginationState>({ pageIndex: initialPage, pageSize: initialPageSize })
|
|
98
|
+
let columnSizing = $state<ColumnSizingState>(initialColumnSizing)
|
|
99
|
+
let columnSizingInfo = $state<ColumnSizingInfoState>({
|
|
100
|
+
columnSizingStart: [],
|
|
101
|
+
deltaOffset: null,
|
|
102
|
+
deltaPercentage: null,
|
|
103
|
+
isResizingColumn: false,
|
|
104
|
+
startOffset: null,
|
|
105
|
+
startSize: null
|
|
106
|
+
})
|
|
107
|
+
let columnOrder = $state<ColumnOrderState>(initialColumnOrder)
|
|
108
|
+
let containerRef = $state<HTMLDivElement | null>(null)
|
|
109
|
+
let columnDropdowns = $state<Record<string, BaseDropdown>>({})
|
|
110
|
+
let frozenColumns = $state<Set<string>>(new Set(initialFrozenColumns))
|
|
111
|
+
let focusedRowIndex = $state<number>(-1)
|
|
112
|
+
let tableBodyRef = $state<HTMLTableSectionElement | null>(null)
|
|
113
|
+
let tableRenderKey = $state<number>(0) // Force re-render when visibility changes
|
|
114
|
+
|
|
115
|
+
// Build TanStack columns from config
|
|
116
|
+
const columns = $derived.by(() =>
|
|
117
|
+
buildColumns<TData>(
|
|
118
|
+
columnConfig,
|
|
119
|
+
enableSelection,
|
|
120
|
+
RowActions,
|
|
121
|
+
getRowActions !== undefined || rowActions.length > 0
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
// Calculate initial column sizes based on available width
|
|
126
|
+
$effect(() => {
|
|
127
|
+
if (containerRef && Object.keys(columnSizing).length === 0) {
|
|
128
|
+
const containerWidth = containerRef.offsetWidth
|
|
129
|
+
const newSizing = calculateColumnSizing(columns, containerWidth)
|
|
130
|
+
if (newSizing) {
|
|
131
|
+
columnSizing = newSizing
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
// Sync pagination pageIndex with initialPage prop (for manual pagination resets)
|
|
137
|
+
$effect(() => {
|
|
138
|
+
if (manualPagination) {
|
|
139
|
+
pagination.pageIndex = initialPage
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// Reorder initial frozen columns on mount
|
|
144
|
+
$effect(() => {
|
|
145
|
+
if (initialFrozenColumns.length > 0 && columnOrder.length === 0) {
|
|
146
|
+
initialFrozenColumns.forEach((columnId) =>
|
|
147
|
+
reorderFrozenColumn(columnId, table, frozenColumns)
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
// Track selection changes
|
|
153
|
+
$effect(() => {
|
|
154
|
+
if (onSelectionChange) {
|
|
155
|
+
const selectedRows = Object.keys(rowSelection)
|
|
156
|
+
.filter((key) => rowSelection[key])
|
|
157
|
+
.map((key) => data[parseInt(key)])
|
|
158
|
+
onSelectionChange(selectedRows)
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
// Track column order changes
|
|
163
|
+
$effect(() => {
|
|
164
|
+
if (onColumnOrderChange && columnOrder.length > 0) {
|
|
165
|
+
onColumnOrderChange(columnOrder)
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
// Track column visibility changes
|
|
170
|
+
$effect(() => {
|
|
171
|
+
if (onColumnVisibilityChange && Object.keys(columnVisibility).length > 0) {
|
|
172
|
+
onColumnVisibilityChange(columnVisibility)
|
|
173
|
+
}
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
const table = setupTable<TData>({
|
|
177
|
+
getData: () => data,
|
|
178
|
+
getColumns: () => columns,
|
|
179
|
+
enableSelection,
|
|
180
|
+
enablePagination,
|
|
181
|
+
manualPagination,
|
|
182
|
+
manualSorting,
|
|
183
|
+
pageCount,
|
|
184
|
+
getRowCount: () => rowCount,
|
|
185
|
+
getRowSelection: () => rowSelection,
|
|
186
|
+
getColumnVisibility: () => columnVisibility,
|
|
187
|
+
getSorting: () => sorting,
|
|
188
|
+
getPagination: () => pagination,
|
|
189
|
+
getColumnSizing: () => columnSizing,
|
|
190
|
+
getColumnSizingInfo: () => columnSizingInfo,
|
|
191
|
+
getColumnOrder: () => columnOrder,
|
|
192
|
+
setRowSelection: (value) => (rowSelection = value),
|
|
193
|
+
setColumnVisibility: (value) => {
|
|
194
|
+
columnVisibility = value
|
|
195
|
+
// Increment render key to force table rebuild after visibility changes
|
|
196
|
+
tableRenderKey++
|
|
197
|
+
},
|
|
198
|
+
setSorting: (value) => (sorting = value),
|
|
199
|
+
setPagination: (value) => (pagination = value),
|
|
200
|
+
setColumnSizing: (value) => {
|
|
201
|
+
columnSizing = value
|
|
202
|
+
if (onColumnResize && Object.keys(value).length > 0) {
|
|
203
|
+
onColumnResize(value)
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
setColumnSizingInfo: (value) => (columnSizingInfo = value),
|
|
207
|
+
setColumnOrder: (value) => (columnOrder = value)
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
function handleFreezeColumn(columnId: string) {
|
|
211
|
+
const isFrozen = frozenColumns.has(columnId)
|
|
212
|
+
|
|
213
|
+
if (isFrozen) {
|
|
214
|
+
frozenColumns.delete(columnId)
|
|
215
|
+
frozenColumns = new Set(frozenColumns)
|
|
216
|
+
reorderUnfrozenColumn(columnId, table, frozenColumns)
|
|
217
|
+
} else {
|
|
218
|
+
frozenColumns.add(columnId)
|
|
219
|
+
frozenColumns = new Set(frozenColumns)
|
|
220
|
+
reorderFrozenColumn(columnId, table, frozenColumns)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Notify parent component of freeze change
|
|
224
|
+
onFreezeChange?.(columnId)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function handleKeydown(event: KeyboardEvent) {
|
|
228
|
+
const rows = table.getRowModel().rows
|
|
229
|
+
if (rows.length === 0) return
|
|
230
|
+
if (shouldIgnoreKeyEvent(event)) return
|
|
231
|
+
|
|
232
|
+
switch (event.key) {
|
|
233
|
+
case 'ArrowDown':
|
|
234
|
+
event.preventDefault()
|
|
235
|
+
focusedRowIndex = handleArrowDown(
|
|
236
|
+
focusedRowIndex,
|
|
237
|
+
rows,
|
|
238
|
+
event.shiftKey,
|
|
239
|
+
enableSelection,
|
|
240
|
+
scrollToFocusedRow
|
|
241
|
+
)
|
|
242
|
+
break
|
|
243
|
+
case 'ArrowUp':
|
|
244
|
+
event.preventDefault()
|
|
245
|
+
focusedRowIndex = handleArrowUp(
|
|
246
|
+
focusedRowIndex,
|
|
247
|
+
rows,
|
|
248
|
+
event.shiftKey,
|
|
249
|
+
enableSelection,
|
|
250
|
+
scrollToFocusedRow
|
|
251
|
+
)
|
|
252
|
+
break
|
|
253
|
+
case ' ':
|
|
254
|
+
case 'Enter':
|
|
255
|
+
event.preventDefault()
|
|
256
|
+
handleSelectKey(focusedRowIndex, rows, enableSelection)
|
|
257
|
+
break
|
|
258
|
+
case 'Escape':
|
|
259
|
+
focusedRowIndex = -1
|
|
260
|
+
break
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function scrollToFocusedRow() {
|
|
265
|
+
if (focusedRowIndex >= 0 && tableBodyRef) {
|
|
266
|
+
const rowElement = tableBodyRef.querySelector(`[data-row-index="${focusedRowIndex}"]`)
|
|
267
|
+
if (rowElement) {
|
|
268
|
+
rowElement.scrollIntoView({ block: 'nearest', behavior: 'smooth' })
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Close dropdowns on horizontal scroll
|
|
274
|
+
let lastScrollLeft = 0
|
|
275
|
+
function handleScroll(event: Event) {
|
|
276
|
+
lastScrollLeft = handleScrollEvent(event, lastScrollLeft, columnDropdowns)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Add global keyboard navigation
|
|
280
|
+
onMount(() => {
|
|
281
|
+
if (!disableKeyboardNavigation) {
|
|
282
|
+
document.addEventListener('keydown', handleKeydown)
|
|
283
|
+
}
|
|
284
|
+
if (containerRef) {
|
|
285
|
+
containerRef.addEventListener('scroll', handleScroll)
|
|
286
|
+
}
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
onDestroy(() => {
|
|
290
|
+
if (!disableKeyboardNavigation) {
|
|
291
|
+
document.removeEventListener('keydown', handleKeydown)
|
|
292
|
+
}
|
|
293
|
+
if (containerRef) {
|
|
294
|
+
containerRef.removeEventListener('scroll', handleScroll)
|
|
295
|
+
}
|
|
296
|
+
})
|
|
297
|
+
</script>
|
|
298
|
+
|
|
299
|
+
{#snippet StickyCellWrapper({
|
|
300
|
+
children,
|
|
301
|
+
align = 'left',
|
|
302
|
+
isFirst = false,
|
|
303
|
+
isLast = false,
|
|
304
|
+
isFrozen = false,
|
|
305
|
+
isLastFrozen = false
|
|
306
|
+
}: {
|
|
307
|
+
children: any
|
|
308
|
+
align?: 'left' | 'right'
|
|
309
|
+
isFirst?: boolean
|
|
310
|
+
isLast?: boolean
|
|
311
|
+
isFrozen?: boolean
|
|
312
|
+
isLastFrozen?: boolean
|
|
313
|
+
})}
|
|
314
|
+
<div
|
|
315
|
+
class={cn(
|
|
316
|
+
'absolute inset-0 flex items-center bg-background group-hover/row:bg-background-default-secondary group-data-[state=selected]/row:bg-background-selected group-data-[state=selected]/row:group-hover/row:bg-background-selected group-data-[state=error]/row:bg-background-critical group-data-[state=error]/row:group-hover/row:bg-background-critical group-data-[state=warning]/row:bg-background-warning group-data-[state=warning]/row:group-hover/row:bg-background-warning group-data-[state=success]/row:bg-background-selected group-data-[state=success]/row:group-hover/row:bg-background-selected group-data-[focused=true]/row:bg-background-default-secondary px-3 shadow-[inset_0_-1px_0_0_var(--color-border)]',
|
|
317
|
+
{
|
|
318
|
+
'justify-end': align === 'right',
|
|
319
|
+
'pl-4': isFirst,
|
|
320
|
+
'pr-4': isLast,
|
|
321
|
+
'border-r border-border': isFrozen && isLastFrozen
|
|
322
|
+
}
|
|
323
|
+
)}
|
|
324
|
+
>
|
|
325
|
+
<div class="relative z-10 flex items-center w-full">
|
|
326
|
+
{@render children()}
|
|
327
|
+
</div>
|
|
328
|
+
</div>
|
|
329
|
+
{/snippet}
|
|
330
|
+
|
|
331
|
+
{#snippet RowActions({ row }: { row: Row<TData> })}
|
|
332
|
+
<BaseTableActions
|
|
333
|
+
actions={getRowActions ? getRowActions(row.original) : rowActions}
|
|
334
|
+
onclick={(action) => {
|
|
335
|
+
if (onRowAction) {
|
|
336
|
+
onRowAction(action, row.original)
|
|
337
|
+
}
|
|
338
|
+
}}
|
|
339
|
+
/>
|
|
340
|
+
{/snippet}
|
|
341
|
+
|
|
342
|
+
<div class="flex flex-col h-full">
|
|
343
|
+
<DataTableToolbar
|
|
344
|
+
{table}
|
|
345
|
+
{filters}
|
|
346
|
+
{frozenColumns}
|
|
347
|
+
onFreezeColumn={handleFreezeColumn}
|
|
348
|
+
disabled={disableControls}
|
|
349
|
+
/>
|
|
350
|
+
<div class="flex-1 overflow-hidden flex flex-col">
|
|
351
|
+
<div
|
|
352
|
+
bind:this={containerRef}
|
|
353
|
+
class="relative bg-background flex-1 overflow-auto"
|
|
354
|
+
style="overscroll-behavior-x: none;"
|
|
355
|
+
>
|
|
356
|
+
{#if data.length === 0}
|
|
357
|
+
<div class="absolute inset-0 flex items-center justify-center pointer-events-none">
|
|
358
|
+
<div class="pointer-events-auto">
|
|
359
|
+
<EmptyState
|
|
360
|
+
icon={children}
|
|
361
|
+
iconSource={emptyState.iconSource}
|
|
362
|
+
title={emptyState.title}
|
|
363
|
+
description={emptyState.description}
|
|
364
|
+
/>
|
|
365
|
+
</div>
|
|
366
|
+
</div>
|
|
367
|
+
{:else}
|
|
368
|
+
<Table.Root>
|
|
369
|
+
<Table.Header>
|
|
370
|
+
{#each table.getHeaderGroups() as headerGroup (`${headerGroup.id}-${tableRenderKey}`)}
|
|
371
|
+
<Table.Row class="hover:!bg-transparent">
|
|
372
|
+
{#each headerGroup.headers as header, index (header.id)}
|
|
373
|
+
<DataTableHeaderCell
|
|
374
|
+
{header}
|
|
375
|
+
{index}
|
|
376
|
+
headers={headerGroup.headers}
|
|
377
|
+
{frozenColumns}
|
|
378
|
+
bind:columnDropdowns
|
|
379
|
+
onSortingChange={(columnId, direction) => {
|
|
380
|
+
if (manualPagination) {
|
|
381
|
+
table.setPageIndex(0)
|
|
382
|
+
}
|
|
383
|
+
onSortingChange?.(columnId, direction)
|
|
384
|
+
}}
|
|
385
|
+
{onFilterChange}
|
|
386
|
+
onFreezeChange={handleFreezeColumn}
|
|
387
|
+
{manualPagination}
|
|
388
|
+
{loading}
|
|
389
|
+
/>
|
|
390
|
+
{/each}
|
|
391
|
+
</Table.Row>
|
|
392
|
+
{/each}
|
|
393
|
+
</Table.Header>
|
|
394
|
+
<Table.Body bind:ref={tableBodyRef}>
|
|
395
|
+
{#each table.getRowModel().rows as row, rowIndex (row.id)}
|
|
396
|
+
<DataTableRow
|
|
397
|
+
{row}
|
|
398
|
+
{rowIndex}
|
|
399
|
+
{frozenColumns}
|
|
400
|
+
{focusedRowIndex}
|
|
401
|
+
{loading}
|
|
402
|
+
{onRowClick}
|
|
403
|
+
{getRowClassName}
|
|
404
|
+
{getRowState}
|
|
405
|
+
{StickyCellWrapper}
|
|
406
|
+
/>
|
|
407
|
+
{/each}
|
|
408
|
+
</Table.Body>
|
|
409
|
+
</Table.Root>
|
|
410
|
+
{/if}
|
|
411
|
+
</div>
|
|
412
|
+
{#if enablePagination}
|
|
413
|
+
<DataTablePagination
|
|
414
|
+
{table}
|
|
415
|
+
{data}
|
|
416
|
+
{rowCount}
|
|
417
|
+
{manualPagination}
|
|
418
|
+
{onPageChange}
|
|
419
|
+
{onPageSizeChange}
|
|
420
|
+
disabled={disableControls || loading}
|
|
421
|
+
>
|
|
422
|
+
{#if paginationSlot}
|
|
423
|
+
{@render paginationSlot()}
|
|
424
|
+
{/if}
|
|
425
|
+
</DataTablePagination>
|
|
426
|
+
{/if}
|
|
427
|
+
</div>
|
|
428
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DataTableProps } from './data-table-types.js';
|
|
2
|
+
declare function $$render<TData>(): {
|
|
3
|
+
props: DataTableProps<TData>;
|
|
4
|
+
exports: {};
|
|
5
|
+
bindings: "";
|
|
6
|
+
slots: {};
|
|
7
|
+
events: {};
|
|
8
|
+
};
|
|
9
|
+
declare class __sveltets_Render<TData> {
|
|
10
|
+
props(): ReturnType<typeof $$render<TData>>['props'];
|
|
11
|
+
events(): ReturnType<typeof $$render<TData>>['events'];
|
|
12
|
+
slots(): ReturnType<typeof $$render<TData>>['slots'];
|
|
13
|
+
bindings(): "";
|
|
14
|
+
exports(): {};
|
|
15
|
+
}
|
|
16
|
+
interface $$IsomorphicComponent {
|
|
17
|
+
new <TData>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData>['props']>, ReturnType<__sveltets_Render<TData>['events']>, ReturnType<__sveltets_Render<TData>['slots']>> & {
|
|
18
|
+
$$bindings?: ReturnType<__sveltets_Render<TData>['bindings']>;
|
|
19
|
+
} & ReturnType<__sveltets_Render<TData>['exports']>;
|
|
20
|
+
<TData>(internal: unknown, props: ReturnType<__sveltets_Render<TData>['props']> & {}): ReturnType<__sveltets_Render<TData>['exports']>;
|
|
21
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
22
|
+
}
|
|
23
|
+
declare const DataTable: $$IsomorphicComponent;
|
|
24
|
+
type DataTable<TData> = InstanceType<typeof DataTable<TData>>;
|
|
25
|
+
export default DataTable;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script
|
|
2
|
+
lang="ts"
|
|
3
|
+
generics="TData, TValue, TContext extends HeaderContext<TData, TValue> | CellContext<TData, TValue>"
|
|
4
|
+
>
|
|
5
|
+
import type { CellContext, ColumnDefTemplate, HeaderContext } from '@tanstack/table-core'
|
|
6
|
+
import { RenderComponentConfig, RenderSnippetConfig } from './render-helpers.js'
|
|
7
|
+
import type { Attachment } from 'svelte/attachments'
|
|
8
|
+
type Props = {
|
|
9
|
+
/** The cell or header field of the current cell's column definition. */
|
|
10
|
+
content?: TContext extends HeaderContext<TData, TValue>
|
|
11
|
+
? ColumnDefTemplate<HeaderContext<TData, TValue>>
|
|
12
|
+
: TContext extends CellContext<TData, TValue>
|
|
13
|
+
? ColumnDefTemplate<CellContext<TData, TValue>>
|
|
14
|
+
: never
|
|
15
|
+
/** The result of the `getContext()` function of the header or cell */
|
|
16
|
+
context: TContext
|
|
17
|
+
|
|
18
|
+
/** Used to pass attachments that can't be gotten through context */
|
|
19
|
+
attach?: Attachment
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let { content, context, attach }: Props = $props()
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
{#if typeof content === 'string'}
|
|
26
|
+
{content}
|
|
27
|
+
{:else if content instanceof Function}
|
|
28
|
+
<!-- It's unlikely that a CellContext will be passed to a Header -->
|
|
29
|
+
<!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
|
|
30
|
+
{@const result = content(context as any)}
|
|
31
|
+
{#if result instanceof RenderComponentConfig}
|
|
32
|
+
{@const { component: Component, props } = result}
|
|
33
|
+
<Component {...props} {attach} />
|
|
34
|
+
{:else if result instanceof RenderSnippetConfig}
|
|
35
|
+
{@const { snippet, params } = result}
|
|
36
|
+
{@render snippet({ ...params, attach })}
|
|
37
|
+
{:else}
|
|
38
|
+
{result}
|
|
39
|
+
{/if}
|
|
40
|
+
{/if}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CellContext, ColumnDefTemplate, HeaderContext } from '@tanstack/table-core';
|
|
2
|
+
import type { Attachment } from 'svelte/attachments';
|
|
3
|
+
declare function $$render<TData, TValue, TContext extends HeaderContext<TData, TValue> | CellContext<TData, TValue>>(): {
|
|
4
|
+
props: {
|
|
5
|
+
/** The cell or header field of the current cell's column definition. */
|
|
6
|
+
content?: TContext extends HeaderContext<TData, TValue> ? ColumnDefTemplate<HeaderContext<TData, TValue>> : TContext extends CellContext<TData, TValue> ? ColumnDefTemplate<CellContext<TData, TValue>> : never;
|
|
7
|
+
/** The result of the `getContext()` function of the header or cell */
|
|
8
|
+
context: TContext;
|
|
9
|
+
/** Used to pass attachments that can't be gotten through context */
|
|
10
|
+
attach?: Attachment;
|
|
11
|
+
};
|
|
12
|
+
exports: {};
|
|
13
|
+
bindings: "";
|
|
14
|
+
slots: {};
|
|
15
|
+
events: {};
|
|
16
|
+
};
|
|
17
|
+
declare class __sveltets_Render<TData, TValue, TContext extends HeaderContext<TData, TValue> | CellContext<TData, TValue>> {
|
|
18
|
+
props(): ReturnType<typeof $$render<TData, TValue, TContext>>['props'];
|
|
19
|
+
events(): ReturnType<typeof $$render<TData, TValue, TContext>>['events'];
|
|
20
|
+
slots(): ReturnType<typeof $$render<TData, TValue, TContext>>['slots'];
|
|
21
|
+
bindings(): "";
|
|
22
|
+
exports(): {};
|
|
23
|
+
}
|
|
24
|
+
interface $$IsomorphicComponent {
|
|
25
|
+
new <TData, TValue, TContext extends HeaderContext<TData, TValue> | CellContext<TData, TValue>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData, TValue, TContext>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData, TValue, TContext>['props']>, ReturnType<__sveltets_Render<TData, TValue, TContext>['events']>, ReturnType<__sveltets_Render<TData, TValue, TContext>['slots']>> & {
|
|
26
|
+
$$bindings?: ReturnType<__sveltets_Render<TData, TValue, TContext>['bindings']>;
|
|
27
|
+
} & ReturnType<__sveltets_Render<TData, TValue, TContext>['exports']>;
|
|
28
|
+
<TData, TValue, TContext extends HeaderContext<TData, TValue> | CellContext<TData, TValue>>(internal: unknown, props: ReturnType<__sveltets_Render<TData, TValue, TContext>['props']> & {}): ReturnType<__sveltets_Render<TData, TValue, TContext>['exports']>;
|
|
29
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any, any>['bindings']>;
|
|
30
|
+
}
|
|
31
|
+
declare const FlexRender: $$IsomorphicComponent;
|
|
32
|
+
type FlexRender<TData, TValue, TContext extends HeaderContext<TData, TValue> | CellContext<TData, TValue>> = InstanceType<typeof FlexRender<TData, TValue, TContext>>;
|
|
33
|
+
export default FlexRender;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { default as DataTable } from "./data-table.svelte";
|
|
2
|
+
export { default as DataTableToolbar } from "./data-table-toolbar.svelte";
|
|
3
|
+
export { default as DataTableViewOptions } from "./data-table-view-options.svelte";
|
|
4
|
+
export { default as FlexRender } from "./flex-render.svelte";
|
|
5
|
+
export { createSvelteTable } from "./data-table-svelte.svelte.js";
|
|
6
|
+
export { renderComponent, renderSnippet } from "./render-helpers.js";
|
|
7
|
+
export { createColumns } from "./create-columns.js";
|
|
8
|
+
export { default as TextCell } from "./cells/text-cell.svelte";
|
|
9
|
+
export { default as BooleanCell } from "./cells/boolean-cell.svelte";
|
|
10
|
+
export { default as TagCell } from "./cells/tag-cell.svelte";
|
|
11
|
+
export { default as DateCell } from "./cells/date-cell.svelte";
|
|
12
|
+
export { default as CurrencyCell } from "./cells/currency-cell.svelte";
|
|
13
|
+
export type { DataTableColumn, DataTableProps, CellType, TextCellConfig, BooleanCellConfig, TagCellConfig, DateCellConfig, CurrencyCellConfig, CellConfig } from "./data-table-types.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { default as DataTable } from "./data-table.svelte";
|
|
2
|
+
export { default as DataTableToolbar } from "./data-table-toolbar.svelte";
|
|
3
|
+
export { default as DataTableViewOptions } from "./data-table-view-options.svelte";
|
|
4
|
+
export { default as FlexRender } from "./flex-render.svelte";
|
|
5
|
+
export { createSvelteTable } from "./data-table-svelte.svelte.js";
|
|
6
|
+
export { renderComponent, renderSnippet } from "./render-helpers.js";
|
|
7
|
+
export { createColumns } from "./create-columns.js";
|
|
8
|
+
// Re-export cell components
|
|
9
|
+
export { default as TextCell } from "./cells/text-cell.svelte";
|
|
10
|
+
export { default as BooleanCell } from "./cells/boolean-cell.svelte";
|
|
11
|
+
export { default as TagCell } from "./cells/tag-cell.svelte";
|
|
12
|
+
export { default as DateCell } from "./cells/date-cell.svelte";
|
|
13
|
+
export { default as CurrencyCell } from "./cells/currency-cell.svelte";
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Component, ComponentProps, Snippet } from "svelte";
|
|
2
|
+
/**
|
|
3
|
+
* A helper class to make it easy to identify Svelte components in
|
|
4
|
+
* `columnDef.cell` and `columnDef.header` properties.
|
|
5
|
+
*
|
|
6
|
+
* > NOTE: This class should only be used internally by the adapter. If you're
|
|
7
|
+
* reading this and you don't know what this is for, you probably don't need it.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```svelte
|
|
11
|
+
* {@const result = content(context as any)}
|
|
12
|
+
* {#if result instanceof RenderComponentConfig}
|
|
13
|
+
* {@const { component: Component, props } = result}
|
|
14
|
+
* <Component {...props} />
|
|
15
|
+
* {/if}
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare class RenderComponentConfig<TComponent extends Component> {
|
|
19
|
+
component: TComponent;
|
|
20
|
+
props: ComponentProps<TComponent> | Record<string, never>;
|
|
21
|
+
constructor(component: TComponent, props?: ComponentProps<TComponent> | Record<string, never>);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A helper class to make it easy to identify Svelte Snippets in `columnDef.cell` and `columnDef.header` properties.
|
|
25
|
+
*
|
|
26
|
+
* > NOTE: This class should only be used internally by the adapter. If you're
|
|
27
|
+
* reading this and you don't know what this is for, you probably don't need it.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```svelte
|
|
31
|
+
* {@const result = content(context as any)}
|
|
32
|
+
* {#if result instanceof RenderSnippetConfig}
|
|
33
|
+
* {@const { snippet, params } = result}
|
|
34
|
+
* {@render snippet(params)}
|
|
35
|
+
* {/if}
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare class RenderSnippetConfig<TProps> {
|
|
39
|
+
snippet: Snippet<[TProps]>;
|
|
40
|
+
params: TProps;
|
|
41
|
+
constructor(snippet: Snippet<[TProps]>, params: TProps);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A helper function to help create cells from Svelte components through ColumnDef's `cell` and `header` properties.
|
|
45
|
+
*
|
|
46
|
+
* This is only to be used with Svelte Components - use `renderSnippet` for Svelte Snippets.
|
|
47
|
+
*
|
|
48
|
+
* @param component A Svelte component
|
|
49
|
+
* @param props The props to pass to `component`
|
|
50
|
+
* @returns A `RenderComponentConfig` object that helps svelte-table know how to render the header/cell component.
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* // +page.svelte
|
|
54
|
+
* const defaultColumns = [
|
|
55
|
+
* columnHelper.accessor('name', {
|
|
56
|
+
* header: header => renderComponent(SortHeader, { label: 'Name', header }),
|
|
57
|
+
* }),
|
|
58
|
+
* columnHelper.accessor('state', {
|
|
59
|
+
* header: header => renderComponent(SortHeader, { label: 'State', header }),
|
|
60
|
+
* }),
|
|
61
|
+
* ]
|
|
62
|
+
* ```
|
|
63
|
+
* @see {@link https://tanstack.com/table/latest/docs/guide/column-defs}
|
|
64
|
+
*/
|
|
65
|
+
export declare function renderComponent<T extends Component<any>, Props extends ComponentProps<T>>(component: T, props?: Props): RenderComponentConfig<T>;
|
|
66
|
+
/**
|
|
67
|
+
* A helper function to help create cells from Svelte Snippets through ColumnDef's `cell` and `header` properties.
|
|
68
|
+
*
|
|
69
|
+
* The snippet must only take one parameter.
|
|
70
|
+
*
|
|
71
|
+
* This is only to be used with Snippets - use `renderComponent` for Svelte Components.
|
|
72
|
+
*
|
|
73
|
+
* @param snippet
|
|
74
|
+
* @param params
|
|
75
|
+
* @returns - A `RenderSnippetConfig` object that helps svelte-table know how to render the header/cell snippet.
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* // +page.svelte
|
|
79
|
+
* const defaultColumns = [
|
|
80
|
+
* columnHelper.accessor('name', {
|
|
81
|
+
* cell: cell => renderSnippet(nameSnippet, { name: cell.row.name }),
|
|
82
|
+
* }),
|
|
83
|
+
* columnHelper.accessor('state', {
|
|
84
|
+
* cell: cell => renderSnippet(stateSnippet, { state: cell.row.state }),
|
|
85
|
+
* }),
|
|
86
|
+
* ]
|
|
87
|
+
* ```
|
|
88
|
+
* @see {@link https://tanstack.com/table/latest/docs/guide/column-defs}
|
|
89
|
+
*/
|
|
90
|
+
export declare function renderSnippet<TProps>(snippet: Snippet<[TProps]>, params?: TProps): RenderSnippetConfig<TProps>;
|