@shotleybuilder/svelte-table-kit 0.1.0 → 0.2.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/README.md +13 -7
- package/dist/TableKit.svelte +383 -29
- package/dist/TableKit.svelte.d.ts +3 -0
- package/dist/types.d.ts +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**A comprehensive, AI-configurable data table component for Svelte and SvelteKit, built on TanStack Table v8.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@shotleybuilder/svelte-table-kit)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
8
|
Svelte Table Kit brings Airtable-like functionality to your Svelte applications with a headless, fully customizable table component. Perfect for dashboards, data grids, and complex data visualization needs.
|
|
@@ -13,13 +13,16 @@ Svelte Table Kit brings Airtable-like functionality to your Svelte applications
|
|
|
13
13
|
|
|
14
14
|
**Core Table Features:**
|
|
15
15
|
- 🎯 Column visibility picker with show/hide controls
|
|
16
|
-
- 📏 Column resizing with drag handles
|
|
16
|
+
- 📏 Column resizing with drag handles (62px-1000px range)
|
|
17
17
|
- 🔄 Column reordering via native HTML5 drag & drop
|
|
18
|
+
- 📐 **Row height control** - 4 sizes: short, medium, tall, extra tall
|
|
19
|
+
- ↔️ **Column spacing control** - 3 sizes: narrow, normal, wide
|
|
18
20
|
- 🔍 **Advanced filtering** - 12 operators with AND/OR logic
|
|
19
21
|
- 📊 **Multi-level grouping** - Up to 3 nested levels (like Airtable)
|
|
20
22
|
- ⬆️ Multi-column sorting with visual indicators
|
|
21
23
|
- 📄 Pagination with customizable page sizes
|
|
22
24
|
- 💾 LocalStorage persistence for all user preferences
|
|
25
|
+
- ✂️ Text truncation with ellipsis for long content
|
|
23
26
|
|
|
24
27
|
**Advanced Filtering:**
|
|
25
28
|
- 12 filter operators: equals, contains, starts with, greater than, etc.
|
|
@@ -56,13 +59,13 @@ Svelte Table Kit brings Airtable-like functionality to your Svelte applications
|
|
|
56
59
|
## 📦 Installation
|
|
57
60
|
|
|
58
61
|
```bash
|
|
59
|
-
npm install @
|
|
62
|
+
npm install @shotleybuilder/svelte-table-kit
|
|
60
63
|
```
|
|
61
64
|
|
|
62
65
|
Or using pnpm:
|
|
63
66
|
|
|
64
67
|
```bash
|
|
65
|
-
pnpm add @
|
|
68
|
+
pnpm add @shotleybuilder/svelte-table-kit
|
|
66
69
|
```
|
|
67
70
|
|
|
68
71
|
---
|
|
@@ -71,7 +74,7 @@ pnpm add @sertantai/svelte-table-kit
|
|
|
71
74
|
|
|
72
75
|
```svelte
|
|
73
76
|
<script>
|
|
74
|
-
import { TableKit } from '@
|
|
77
|
+
import { TableKit } from '@shotleybuilder/svelte-table-kit';
|
|
75
78
|
|
|
76
79
|
const data = [
|
|
77
80
|
{ id: 1, name: 'Alice', role: 'Developer', age: 28 },
|
|
@@ -108,7 +111,7 @@ Use AI-generated or predefined configurations:
|
|
|
108
111
|
|
|
109
112
|
```svelte
|
|
110
113
|
<script>
|
|
111
|
-
import { TableKit, presets } from '@
|
|
114
|
+
import { TableKit, presets } from '@shotleybuilder/svelte-table-kit';
|
|
112
115
|
|
|
113
116
|
const config = presets.dashboard; // or generate with AI
|
|
114
117
|
</script>
|
|
@@ -203,6 +206,9 @@ TableKit is headless by default. You can:
|
|
|
203
206
|
| `storageKey` | `string` | `undefined` | LocalStorage key for persistence |
|
|
204
207
|
| `persistState` | `boolean` | `true` | Enable state persistence |
|
|
205
208
|
| `theme` | `'light' \| 'dark' \| 'auto'` | `'light'` | Theme mode |
|
|
209
|
+
| `align` | `'left' \| 'center' \| 'right'` | `'left'` | Column text alignment |
|
|
210
|
+
| `rowHeight` | `'short' \| 'medium' \| 'tall' \| 'extra_tall'` | `'medium'` | Row height preset |
|
|
211
|
+
| `columnSpacing` | `'narrow' \| 'normal' \| 'wide'` | `'normal'` | Column horizontal spacing |
|
|
206
212
|
| `onRowClick` | `(row: T) => void` | `undefined` | Row click handler |
|
|
207
213
|
| `onRowSelect` | `(rows: T[]) => void` | `undefined` | Row selection handler |
|
|
208
214
|
| `onStateChange` | `(state: TableState) => void` | `undefined` | State change handler |
|
|
@@ -234,7 +240,7 @@ MIT © [Sertantai](https://github.com/shotleybuilder)
|
|
|
234
240
|
## 🔗 Links
|
|
235
241
|
|
|
236
242
|
- [GitHub Repository](https://github.com/shotleybuilder/svelte-table-kit)
|
|
237
|
-
- [npm Package](https://www.npmjs.com/package/@
|
|
243
|
+
- [npm Package](https://www.npmjs.com/package/@shotleybuilder/svelte-table-kit)
|
|
238
244
|
- [Issue Tracker](https://github.com/shotleybuilder/svelte-table-kit/issues)
|
|
239
245
|
|
|
240
246
|
---
|
package/dist/TableKit.svelte
CHANGED
|
@@ -27,6 +27,9 @@ export let data = [];
|
|
|
27
27
|
export let columns = [];
|
|
28
28
|
export let storageKey = "table-kit";
|
|
29
29
|
export let persistState = true;
|
|
30
|
+
export let align = "left";
|
|
31
|
+
export let rowHeight = "medium";
|
|
32
|
+
export let columnSpacing = "normal";
|
|
30
33
|
export let features = {
|
|
31
34
|
columnVisibility: true,
|
|
32
35
|
columnResizing: true,
|
|
@@ -55,6 +58,8 @@ let filterConditions = writable([]);
|
|
|
55
58
|
let filterLogic = writable("and");
|
|
56
59
|
let grouping = writable([]);
|
|
57
60
|
let expanded = writable(true);
|
|
61
|
+
$: horizontalPadding = columnSpacing === "narrow" ? 0.5 : columnSpacing === "wide" ? 2 : 1;
|
|
62
|
+
$: verticalPadding = rowHeight === "short" ? 0.375 : rowHeight === "tall" ? 1 : rowHeight === "extra_tall" ? 1.5 : 0.75;
|
|
58
63
|
$: filteredData = applyFilters(data, $filterConditions, $filterLogic);
|
|
59
64
|
$: if (persistState && storageKey && isBrowser) {
|
|
60
65
|
saveColumnVisibility(storageKey, $columnVisibility);
|
|
@@ -63,6 +68,8 @@ $: if (persistState && storageKey && isBrowser) {
|
|
|
63
68
|
saveColumnOrder(storageKey, $columnOrder);
|
|
64
69
|
}
|
|
65
70
|
let showColumnPicker = false;
|
|
71
|
+
let showRowHeightMenu = false;
|
|
72
|
+
let showColumnSpacingMenu = false;
|
|
66
73
|
let draggedColumnId = null;
|
|
67
74
|
const options = writable({
|
|
68
75
|
data: filteredData,
|
|
@@ -70,6 +77,11 @@ const options = writable({
|
|
|
70
77
|
columnResizeMode: "onChange",
|
|
71
78
|
enableColumnResizing: features.columnResizing !== false,
|
|
72
79
|
enableGrouping: features.grouping !== false,
|
|
80
|
+
defaultColumn: {
|
|
81
|
+
size: 180,
|
|
82
|
+
minSize: 62,
|
|
83
|
+
maxSize: 1e3
|
|
84
|
+
},
|
|
73
85
|
state: {
|
|
74
86
|
sorting: $sorting,
|
|
75
87
|
columnVisibility: $columnVisibility,
|
|
@@ -194,7 +206,7 @@ $: if (onStateChange) {
|
|
|
194
206
|
}
|
|
195
207
|
</script>
|
|
196
208
|
|
|
197
|
-
<div class="table-kit-container">
|
|
209
|
+
<div class="table-kit-container align-{align}">
|
|
198
210
|
<!-- Filters and Controls -->
|
|
199
211
|
{#if features.filtering !== false || features.grouping !== false || features.columnVisibility !== false}
|
|
200
212
|
<div class="table-kit-toolbar">
|
|
@@ -222,6 +234,172 @@ $: if (onStateChange) {
|
|
|
222
234
|
</div>
|
|
223
235
|
{/if}
|
|
224
236
|
|
|
237
|
+
<!-- View Controls: Row Height and Column Spacing -->
|
|
238
|
+
<div class="table-kit-view-controls">
|
|
239
|
+
<!-- Row Height Button -->
|
|
240
|
+
<div class="relative">
|
|
241
|
+
<button
|
|
242
|
+
on:click={() => (showRowHeightMenu = !showRowHeightMenu)}
|
|
243
|
+
class="view-control-btn"
|
|
244
|
+
title="Row Height"
|
|
245
|
+
>
|
|
246
|
+
<svg class="icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
247
|
+
<path
|
|
248
|
+
stroke-linecap="round"
|
|
249
|
+
stroke-linejoin="round"
|
|
250
|
+
stroke-width="2"
|
|
251
|
+
d="M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"
|
|
252
|
+
/>
|
|
253
|
+
</svg>
|
|
254
|
+
</button>
|
|
255
|
+
|
|
256
|
+
{#if showRowHeightMenu}
|
|
257
|
+
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
258
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
259
|
+
<div class="backdrop" on:click={() => (showRowHeightMenu = false)} />
|
|
260
|
+
<div class="dropdown-menu">
|
|
261
|
+
<div class="dropdown-header">
|
|
262
|
+
<span>Row Height</span>
|
|
263
|
+
</div>
|
|
264
|
+
<button
|
|
265
|
+
class="dropdown-item"
|
|
266
|
+
class:active={rowHeight === 'short'}
|
|
267
|
+
on:click={() => {
|
|
268
|
+
rowHeight = 'short';
|
|
269
|
+
showRowHeightMenu = false;
|
|
270
|
+
}}
|
|
271
|
+
>
|
|
272
|
+
<span class="item-icon">
|
|
273
|
+
<svg class="icon-sm" viewBox="0 0 16 16" fill="currentColor">
|
|
274
|
+
<rect x="2" y="7" width="12" height="2" />
|
|
275
|
+
</svg>
|
|
276
|
+
</span>
|
|
277
|
+
Short
|
|
278
|
+
</button>
|
|
279
|
+
<button
|
|
280
|
+
class="dropdown-item"
|
|
281
|
+
class:active={rowHeight === 'medium'}
|
|
282
|
+
on:click={() => {
|
|
283
|
+
rowHeight = 'medium';
|
|
284
|
+
showRowHeightMenu = false;
|
|
285
|
+
}}
|
|
286
|
+
>
|
|
287
|
+
<span class="item-icon">
|
|
288
|
+
<svg class="icon-sm" viewBox="0 0 16 16" fill="currentColor">
|
|
289
|
+
<rect x="2" y="6" width="12" height="4" />
|
|
290
|
+
</svg>
|
|
291
|
+
</span>
|
|
292
|
+
Medium
|
|
293
|
+
</button>
|
|
294
|
+
<button
|
|
295
|
+
class="dropdown-item"
|
|
296
|
+
class:active={rowHeight === 'tall'}
|
|
297
|
+
on:click={() => {
|
|
298
|
+
rowHeight = 'tall';
|
|
299
|
+
showRowHeightMenu = false;
|
|
300
|
+
}}
|
|
301
|
+
>
|
|
302
|
+
<span class="item-icon">
|
|
303
|
+
<svg class="icon-sm" viewBox="0 0 16 16" fill="currentColor">
|
|
304
|
+
<rect x="2" y="4" width="12" height="8" />
|
|
305
|
+
</svg>
|
|
306
|
+
</span>
|
|
307
|
+
Tall
|
|
308
|
+
</button>
|
|
309
|
+
<button
|
|
310
|
+
class="dropdown-item"
|
|
311
|
+
class:active={rowHeight === 'extra_tall'}
|
|
312
|
+
on:click={() => {
|
|
313
|
+
rowHeight = 'extra_tall';
|
|
314
|
+
showRowHeightMenu = false;
|
|
315
|
+
}}
|
|
316
|
+
>
|
|
317
|
+
<span class="item-icon">
|
|
318
|
+
<svg class="icon-sm" viewBox="0 0 16 16" fill="currentColor">
|
|
319
|
+
<rect x="2" y="2" width="12" height="12" />
|
|
320
|
+
</svg>
|
|
321
|
+
</span>
|
|
322
|
+
Extra Tall
|
|
323
|
+
</button>
|
|
324
|
+
</div>
|
|
325
|
+
{/if}
|
|
326
|
+
</div>
|
|
327
|
+
|
|
328
|
+
<!-- Column Spacing Button -->
|
|
329
|
+
<div class="relative">
|
|
330
|
+
<button
|
|
331
|
+
on:click={() => (showColumnSpacingMenu = !showColumnSpacingMenu)}
|
|
332
|
+
class="view-control-btn"
|
|
333
|
+
title="Column Spacing"
|
|
334
|
+
>
|
|
335
|
+
<svg class="icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
336
|
+
<path
|
|
337
|
+
stroke-linecap="round"
|
|
338
|
+
stroke-linejoin="round"
|
|
339
|
+
stroke-width="2"
|
|
340
|
+
d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"
|
|
341
|
+
/>
|
|
342
|
+
</svg>
|
|
343
|
+
</button>
|
|
344
|
+
|
|
345
|
+
{#if showColumnSpacingMenu}
|
|
346
|
+
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
347
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
348
|
+
<div class="backdrop" on:click={() => (showColumnSpacingMenu = false)} />
|
|
349
|
+
<div class="dropdown-menu">
|
|
350
|
+
<div class="dropdown-header">
|
|
351
|
+
<span>Column Spacing</span>
|
|
352
|
+
</div>
|
|
353
|
+
<button
|
|
354
|
+
class="dropdown-item"
|
|
355
|
+
class:active={columnSpacing === 'narrow'}
|
|
356
|
+
on:click={() => {
|
|
357
|
+
columnSpacing = 'narrow';
|
|
358
|
+
showColumnSpacingMenu = false;
|
|
359
|
+
}}
|
|
360
|
+
>
|
|
361
|
+
<span class="item-icon">
|
|
362
|
+
<svg class="icon-sm" viewBox="0 0 16 16" fill="currentColor">
|
|
363
|
+
<rect x="6" y="2" width="4" height="12" />
|
|
364
|
+
</svg>
|
|
365
|
+
</span>
|
|
366
|
+
Narrow
|
|
367
|
+
</button>
|
|
368
|
+
<button
|
|
369
|
+
class="dropdown-item"
|
|
370
|
+
class:active={columnSpacing === 'normal'}
|
|
371
|
+
on:click={() => {
|
|
372
|
+
columnSpacing = 'normal';
|
|
373
|
+
showColumnSpacingMenu = false;
|
|
374
|
+
}}
|
|
375
|
+
>
|
|
376
|
+
<span class="item-icon">
|
|
377
|
+
<svg class="icon-sm" viewBox="0 0 16 16" fill="currentColor">
|
|
378
|
+
<rect x="4" y="2" width="8" height="12" />
|
|
379
|
+
</svg>
|
|
380
|
+
</span>
|
|
381
|
+
Normal
|
|
382
|
+
</button>
|
|
383
|
+
<button
|
|
384
|
+
class="dropdown-item"
|
|
385
|
+
class:active={columnSpacing === 'wide'}
|
|
386
|
+
on:click={() => {
|
|
387
|
+
columnSpacing = 'wide';
|
|
388
|
+
showColumnSpacingMenu = false;
|
|
389
|
+
}}
|
|
390
|
+
>
|
|
391
|
+
<span class="item-icon">
|
|
392
|
+
<svg class="icon-sm" viewBox="0 0 16 16" fill="currentColor">
|
|
393
|
+
<rect x="2" y="2" width="12" height="12" />
|
|
394
|
+
</svg>
|
|
395
|
+
</span>
|
|
396
|
+
Wide
|
|
397
|
+
</button>
|
|
398
|
+
</div>
|
|
399
|
+
{/if}
|
|
400
|
+
</div>
|
|
401
|
+
</div>
|
|
402
|
+
|
|
225
403
|
<!-- Column Picker -->
|
|
226
404
|
{#if features.columnVisibility !== false}
|
|
227
405
|
<div class="table-kit-column-picker">
|
|
@@ -293,26 +471,31 @@ $: if (onStateChange) {
|
|
|
293
471
|
<tr>
|
|
294
472
|
{#each headerGroup.headers as header}
|
|
295
473
|
<th
|
|
296
|
-
draggable={features.columnReordering !== false}
|
|
297
|
-
on:dragstart={() => handleDragStart(header.column.id)}
|
|
298
474
|
on:dragover={handleDragOver}
|
|
299
475
|
on:drop|preventDefault={() => handleDrop(header.column.id)}
|
|
300
476
|
class:dragging={draggedColumnId === header.column.id}
|
|
301
|
-
style="width: {header.getSize()}px;
|
|
302
|
-
false
|
|
303
|
-
? 'grab'
|
|
304
|
-
: 'default'};"
|
|
477
|
+
style="width: {header.getSize()}px;"
|
|
305
478
|
>
|
|
306
479
|
{#if !header.isPlaceholder}
|
|
307
|
-
<div
|
|
480
|
+
<div
|
|
481
|
+
class="th-content"
|
|
482
|
+
style="padding: {verticalPadding}rem {horizontalPadding}rem; cursor: {features.columnReordering !==
|
|
483
|
+
false
|
|
484
|
+
? 'grab'
|
|
485
|
+
: 'default'};"
|
|
486
|
+
draggable={features.columnReordering !== false}
|
|
487
|
+
on:dragstart={() => handleDragStart(header.column.id)}
|
|
488
|
+
>
|
|
308
489
|
<button
|
|
309
490
|
class="sort-btn"
|
|
310
491
|
class:sortable={header.column.getCanSort()}
|
|
311
492
|
on:click={header.column.getToggleSortingHandler()}
|
|
312
493
|
>
|
|
313
|
-
<
|
|
314
|
-
|
|
315
|
-
|
|
494
|
+
<span class="header-text">
|
|
495
|
+
<svelte:component
|
|
496
|
+
this={flexRender(header.column.columnDef.header, header.getContext())}
|
|
497
|
+
/>
|
|
498
|
+
</span>
|
|
316
499
|
{#if features.sorting !== false && header.column.getCanSort()}
|
|
317
500
|
<span class="sort-icon">
|
|
318
501
|
{{
|
|
@@ -327,8 +510,14 @@ $: if (onStateChange) {
|
|
|
327
510
|
{#if features.columnResizing !== false && header.column.getCanResize()}
|
|
328
511
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
329
512
|
<div
|
|
330
|
-
on:mousedown={
|
|
331
|
-
|
|
513
|
+
on:mousedown={(e) => {
|
|
514
|
+
e.stopPropagation();
|
|
515
|
+
header.getResizeHandler()(e);
|
|
516
|
+
}}
|
|
517
|
+
on:touchstart={(e) => {
|
|
518
|
+
e.stopPropagation();
|
|
519
|
+
header.getResizeHandler()(e);
|
|
520
|
+
}}
|
|
332
521
|
class="resize-handle"
|
|
333
522
|
class:resizing={header.column.getIsResizing()}
|
|
334
523
|
/>
|
|
@@ -345,9 +534,10 @@ $: if (onStateChange) {
|
|
|
345
534
|
class:clickable={onRowClick !== undefined && !row.getIsGrouped()}
|
|
346
535
|
class:group-row={row.getIsGrouped()}
|
|
347
536
|
on:click={() => onRowClick && !row.getIsGrouped() && onRowClick(row.original)}
|
|
537
|
+
style="--cell-padding-vertical: {verticalPadding}rem; --cell-padding-horizontal: {horizontalPadding}rem;"
|
|
348
538
|
>
|
|
349
539
|
{#each row.getVisibleCells() as cell}
|
|
350
|
-
<td style="
|
|
540
|
+
<td style="text-align: {align}; width: {cell.column.getSize()}px;">
|
|
351
541
|
{#if cell.getIsGrouped()}
|
|
352
542
|
<!-- Grouping column - show expand/collapse button -->
|
|
353
543
|
<div class="group-cell">
|
|
@@ -396,11 +586,13 @@ $: if (onStateChange) {
|
|
|
396
586
|
<!-- Placeholder cell - empty -->
|
|
397
587
|
{:else}
|
|
398
588
|
<!-- Normal cell -->
|
|
399
|
-
<
|
|
400
|
-
<
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
589
|
+
<div class="cell-content">
|
|
590
|
+
<slot name="cell" {cell} column={cell.column.id}>
|
|
591
|
+
<svelte:component
|
|
592
|
+
this={flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
593
|
+
/>
|
|
594
|
+
</slot>
|
|
595
|
+
</div>
|
|
404
596
|
{/if}
|
|
405
597
|
</td>
|
|
406
598
|
{/each}
|
|
@@ -473,6 +665,7 @@ $: if (onStateChange) {
|
|
|
473
665
|
/* Container */
|
|
474
666
|
.table-kit-container {
|
|
475
667
|
width: 100%;
|
|
668
|
+
overflow-x: auto;
|
|
476
669
|
}
|
|
477
670
|
|
|
478
671
|
/* Toolbar */
|
|
@@ -511,6 +704,28 @@ $: if (onStateChange) {
|
|
|
511
704
|
position: relative;
|
|
512
705
|
}
|
|
513
706
|
|
|
707
|
+
.table-kit-view-controls {
|
|
708
|
+
display: flex;
|
|
709
|
+
gap: 0.5rem;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
.view-control-btn {
|
|
713
|
+
display: inline-flex;
|
|
714
|
+
align-items: center;
|
|
715
|
+
justify-content: center;
|
|
716
|
+
padding: 0.5rem;
|
|
717
|
+
color: #374151;
|
|
718
|
+
background: white;
|
|
719
|
+
border: 1px solid #d1d5db;
|
|
720
|
+
border-radius: 0.375rem;
|
|
721
|
+
cursor: pointer;
|
|
722
|
+
transition: background 0.15s;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
.view-control-btn:hover {
|
|
726
|
+
background: #f9fafb;
|
|
727
|
+
}
|
|
728
|
+
|
|
514
729
|
.column-picker-btn {
|
|
515
730
|
display: inline-flex;
|
|
516
731
|
align-items: center;
|
|
@@ -534,6 +749,72 @@ $: if (onStateChange) {
|
|
|
534
749
|
height: 1rem;
|
|
535
750
|
}
|
|
536
751
|
|
|
752
|
+
.icon-sm {
|
|
753
|
+
width: 0.875rem;
|
|
754
|
+
height: 0.875rem;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
.dropdown-menu {
|
|
758
|
+
position: absolute;
|
|
759
|
+
top: calc(100% + 0.25rem);
|
|
760
|
+
right: 0;
|
|
761
|
+
min-width: 10rem;
|
|
762
|
+
background: white;
|
|
763
|
+
border: 1px solid #d1d5db;
|
|
764
|
+
border-radius: 0.5rem;
|
|
765
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
|
766
|
+
z-index: 20;
|
|
767
|
+
overflow: hidden;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
.dropdown-header {
|
|
771
|
+
padding: 0.5rem 0.75rem;
|
|
772
|
+
font-size: 0.75rem;
|
|
773
|
+
font-weight: 600;
|
|
774
|
+
text-transform: uppercase;
|
|
775
|
+
letter-spacing: 0.05em;
|
|
776
|
+
color: #6b7280;
|
|
777
|
+
border-bottom: 1px solid #e5e7eb;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
.dropdown-item {
|
|
781
|
+
display: flex;
|
|
782
|
+
align-items: center;
|
|
783
|
+
gap: 0.75rem;
|
|
784
|
+
width: 100%;
|
|
785
|
+
padding: 0.625rem 0.75rem;
|
|
786
|
+
font-size: 0.875rem;
|
|
787
|
+
color: #374151;
|
|
788
|
+
background: white;
|
|
789
|
+
border: none;
|
|
790
|
+
text-align: left;
|
|
791
|
+
cursor: pointer;
|
|
792
|
+
transition: background 0.15s;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
.dropdown-item:hover {
|
|
796
|
+
background: #f9fafb;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
.dropdown-item.active {
|
|
800
|
+
background: #eff6ff;
|
|
801
|
+
color: #2563eb;
|
|
802
|
+
font-weight: 500;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.item-icon {
|
|
806
|
+
display: flex;
|
|
807
|
+
align-items: center;
|
|
808
|
+
justify-content: center;
|
|
809
|
+
width: 1.25rem;
|
|
810
|
+
height: 1.25rem;
|
|
811
|
+
color: #9ca3af;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
.dropdown-item.active .item-icon {
|
|
815
|
+
color: #2563eb;
|
|
816
|
+
}
|
|
817
|
+
|
|
537
818
|
.backdrop {
|
|
538
819
|
position: fixed;
|
|
539
820
|
inset: 0;
|
|
@@ -629,8 +910,9 @@ $: if (onStateChange) {
|
|
|
629
910
|
}
|
|
630
911
|
|
|
631
912
|
.table-kit-table {
|
|
632
|
-
width:
|
|
913
|
+
width: auto;
|
|
633
914
|
border-collapse: collapse;
|
|
915
|
+
table-layout: fixed;
|
|
634
916
|
}
|
|
635
917
|
|
|
636
918
|
thead {
|
|
@@ -639,7 +921,7 @@ $: if (onStateChange) {
|
|
|
639
921
|
|
|
640
922
|
th {
|
|
641
923
|
position: relative;
|
|
642
|
-
padding: 0
|
|
924
|
+
padding: 0;
|
|
643
925
|
text-align: left;
|
|
644
926
|
font-size: 0.75rem;
|
|
645
927
|
font-weight: 500;
|
|
@@ -649,6 +931,18 @@ $: if (onStateChange) {
|
|
|
649
931
|
transition: opacity 0.2s;
|
|
650
932
|
}
|
|
651
933
|
|
|
934
|
+
.table-kit-container.align-left th {
|
|
935
|
+
text-align: left !important;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
.table-kit-container.align-center th {
|
|
939
|
+
text-align: center !important;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
.table-kit-container.align-right th {
|
|
943
|
+
text-align: right !important;
|
|
944
|
+
}
|
|
945
|
+
|
|
652
946
|
th.dragging {
|
|
653
947
|
opacity: 0.5;
|
|
654
948
|
}
|
|
@@ -657,6 +951,21 @@ $: if (onStateChange) {
|
|
|
657
951
|
display: flex;
|
|
658
952
|
align-items: center;
|
|
659
953
|
gap: 0.25rem;
|
|
954
|
+
justify-content: flex-start;
|
|
955
|
+
overflow: hidden;
|
|
956
|
+
min-width: 0;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
.table-kit-container.align-left .th-content {
|
|
960
|
+
justify-content: flex-start !important;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
.table-kit-container.align-center .th-content {
|
|
964
|
+
justify-content: center !important;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
.table-kit-container.align-right .th-content {
|
|
968
|
+
justify-content: flex-end !important;
|
|
660
969
|
}
|
|
661
970
|
|
|
662
971
|
.sort-btn {
|
|
@@ -671,6 +980,18 @@ $: if (onStateChange) {
|
|
|
671
980
|
color: inherit;
|
|
672
981
|
text-transform: inherit;
|
|
673
982
|
letter-spacing: inherit;
|
|
983
|
+
overflow: hidden;
|
|
984
|
+
min-width: 0;
|
|
985
|
+
flex: 1;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
.header-text {
|
|
989
|
+
display: block;
|
|
990
|
+
overflow: hidden;
|
|
991
|
+
text-overflow: ellipsis;
|
|
992
|
+
white-space: nowrap;
|
|
993
|
+
min-width: 0;
|
|
994
|
+
max-width: 100%;
|
|
674
995
|
}
|
|
675
996
|
|
|
676
997
|
.sort-btn.sortable {
|
|
@@ -688,21 +1009,31 @@ $: if (onStateChange) {
|
|
|
688
1009
|
.resize-handle {
|
|
689
1010
|
position: absolute;
|
|
690
1011
|
top: 0;
|
|
691
|
-
right: 0;
|
|
1012
|
+
right: -0.375rem;
|
|
692
1013
|
height: 100%;
|
|
693
|
-
width: 0.
|
|
1014
|
+
width: 0.75rem;
|
|
694
1015
|
cursor: col-resize;
|
|
695
1016
|
user-select: none;
|
|
696
1017
|
touch-action: none;
|
|
697
1018
|
background: transparent;
|
|
698
|
-
|
|
699
|
-
transition:
|
|
1019
|
+
z-index: 10;
|
|
1020
|
+
transition: background 0.15s;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
.resize-handle:hover {
|
|
1024
|
+
background: rgba(79, 70, 229, 0.1);
|
|
700
1025
|
}
|
|
701
1026
|
|
|
702
|
-
.resize-handle:hover,
|
|
703
|
-
.resize-handle.resizing {
|
|
1027
|
+
.resize-handle:hover::after,
|
|
1028
|
+
.resize-handle.resizing::after {
|
|
1029
|
+
content: '';
|
|
1030
|
+
position: absolute;
|
|
1031
|
+
top: 0;
|
|
1032
|
+
left: 50%;
|
|
1033
|
+
transform: translateX(-50%);
|
|
1034
|
+
height: 100%;
|
|
1035
|
+
width: 0.125rem;
|
|
704
1036
|
background: #4f46e5;
|
|
705
|
-
opacity: 1;
|
|
706
1037
|
}
|
|
707
1038
|
|
|
708
1039
|
tbody tr {
|
|
@@ -718,9 +1049,32 @@ $: if (onStateChange) {
|
|
|
718
1049
|
}
|
|
719
1050
|
|
|
720
1051
|
td {
|
|
721
|
-
padding: 1rem 1.5rem;
|
|
722
1052
|
font-size: 0.875rem;
|
|
723
1053
|
color: #111827;
|
|
1054
|
+
text-align: left;
|
|
1055
|
+
overflow: hidden;
|
|
1056
|
+
text-overflow: ellipsis;
|
|
1057
|
+
white-space: nowrap;
|
|
1058
|
+
max-width: 0;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
.table-kit-container.align-left td {
|
|
1062
|
+
text-align: left !important;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
.table-kit-container.align-center td {
|
|
1066
|
+
text-align: center !important;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
.table-kit-container.align-right td {
|
|
1070
|
+
text-align: right !important;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
.cell-content {
|
|
1074
|
+
overflow: hidden;
|
|
1075
|
+
text-overflow: ellipsis;
|
|
1076
|
+
white-space: nowrap;
|
|
1077
|
+
padding: var(--cell-padding-vertical, 1rem) var(--cell-padding-horizontal, 1rem);
|
|
724
1078
|
}
|
|
725
1079
|
|
|
726
1080
|
/* Group Rows */
|
|
@@ -7,6 +7,9 @@ declare class __sveltets_Render<T> {
|
|
|
7
7
|
columns?: ColumnDef<T>[] | undefined;
|
|
8
8
|
storageKey?: TableKitProps<T_1>["storageKey"];
|
|
9
9
|
persistState?: TableKitProps<T_1>["persistState"];
|
|
10
|
+
align?: TableKitProps<T_1>["align"];
|
|
11
|
+
rowHeight?: TableKitProps<T_1>["rowHeight"];
|
|
12
|
+
columnSpacing?: TableKitProps<T_1>["columnSpacing"];
|
|
10
13
|
features?: TableKitProps<T_1>["features"];
|
|
11
14
|
onRowClick?: ((row: T) => void) | undefined;
|
|
12
15
|
onRowSelect?: ((rows: T[]) => void) | undefined;
|
package/dist/types.d.ts
CHANGED
|
@@ -8,6 +8,9 @@ export interface TableKitProps<T = any> {
|
|
|
8
8
|
persistState?: boolean;
|
|
9
9
|
theme?: 'light' | 'dark' | 'auto';
|
|
10
10
|
classNames?: Partial<ClassNameMap>;
|
|
11
|
+
align?: 'left' | 'center' | 'right';
|
|
12
|
+
rowHeight?: 'short' | 'medium' | 'tall' | 'extra_tall';
|
|
13
|
+
columnSpacing?: 'narrow' | 'normal' | 'wide';
|
|
11
14
|
onRowClick?: (row: T) => void;
|
|
12
15
|
onRowSelect?: (rows: T[]) => void;
|
|
13
16
|
onStateChange?: (state: TableState) => void;
|
package/package.json
CHANGED