svelte-tably 1.0.0-next.16 → 1.0.0-next.17
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 +11 -7
- package/dist/table/Table.svelte +39 -13
- package/dist/table/table.svelte.js +2 -1
- package/dist/utility.svelte.d.ts +4 -0
- package/dist/utility.svelte.js +24 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ A high performant, feature rich, dynamic table
|
|
|
21
21
|
- [x] Row context menus
|
|
22
22
|
- [x] Expandable rows
|
|
23
23
|
- [x] to CSV
|
|
24
|
-
- [
|
|
24
|
+
- [x] Auto: Table based on data, sortable
|
|
25
25
|
|
|
26
26
|
### Usage Notes
|
|
27
27
|
|
|
@@ -38,6 +38,9 @@ A high performant, feature rich, dynamic table
|
|
|
38
38
|
let selected = $state([]) as typeof data
|
|
39
39
|
</script>
|
|
40
40
|
|
|
41
|
+
<!-- Auto: Generate Columns for you -->
|
|
42
|
+
<Table auto {data} resizeable={false} filters=[...] />
|
|
43
|
+
|
|
41
44
|
<Table {data} panel={activePanel} select bind:selected>
|
|
42
45
|
{#snippet content({ Column, Panel, Expandable, Row, state, data })}
|
|
43
46
|
<Column id='name' sticky sort>
|
|
@@ -97,14 +100,15 @@ For quick styling
|
|
|
97
100
|
|
|
98
101
|
| CSS Variable | Description | Default |
|
|
99
102
|
| - | - | - |
|
|
100
|
-
| --tably-bg |
|
|
101
|
-
| --tably-color | color | `hsl(0, 0%, 0%)` |
|
|
102
|
-
| --tably-border |
|
|
103
|
+
| --tably-bg | Background color | `hsl(0, 0%, 100%)` |
|
|
104
|
+
| --tably-color | Text color | `hsl(0, 0%, 0%)` |
|
|
105
|
+
| --tably-border | Border for sticky columns and header | `hsl(0, 0%, 90%)` |
|
|
106
|
+
| --tably-border-grid | Border for the table-grid | `hsl(0, 0%, 98%)` |
|
|
103
107
|
| --tably-statusbar | background-color for the statusbar | `hsl(0, 0%, 98%)` |
|
|
104
108
|
| --tably-padding-y | Padding above/below each column | `.5rem` |
|
|
105
109
|
| --tably-padding-x | Padding left of each column | `1rem` |
|
|
106
110
|
| --tably-radius | Table radius | `.25rem` |
|
|
107
111
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
> [!NOTE]
|
|
113
|
+
> Advanced styling can be done via `:global(.svelte-tably)`
|
|
114
|
+
> `table > thead > tr > th, table > tbody > tr > td, table > tfoot > tr > td`
|
package/dist/table/Table.svelte
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
import { TableState, type HeaderSelectCtx, type RowCtx, type RowSelectCtx, type TableProps } from './table.svelte.js'
|
|
22
22
|
import Panel from '../panel/Panel.svelte'
|
|
23
23
|
import Column from '../column/Column.svelte'
|
|
24
|
-
import { assignDescriptors, fromProps, mounted } from '../utility.svelte.js'
|
|
24
|
+
import { assignDescriptors, capitalize, fromProps, mounted, segmentize } from '../utility.svelte.js'
|
|
25
25
|
import { conditional } from '../conditional.svelte.js'
|
|
26
26
|
import { ColumnState, type RowColumnCtx } from '../column/column.svelte.js'
|
|
27
27
|
import Expandable from '../expandable/Expandable.svelte'
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
panel: _panel = $bindable(),
|
|
56
56
|
data: _data = $bindable([]),
|
|
57
57
|
...restProps
|
|
58
|
-
}: TableProps<T> & { content
|
|
58
|
+
}: TableProps<T> & { content?: ContentSnippet } = $props()
|
|
59
59
|
|
|
60
60
|
const properties = fromProps(restProps, {
|
|
61
61
|
selected: [() => _selected, v => _selected = v],
|
|
@@ -309,14 +309,18 @@
|
|
|
309
309
|
<tr>
|
|
310
310
|
{#each renderedColumns as column}
|
|
311
311
|
<td>
|
|
312
|
-
{
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
312
|
+
{#if column.snippets.row}
|
|
313
|
+
{@render column.snippets.row(row, {
|
|
314
|
+
index: i,
|
|
315
|
+
value: column.options.value?.(row),
|
|
316
|
+
isHovered: false,
|
|
317
|
+
itemState: { index: i, dragging: false, positioning: false } as ItemState<any>,
|
|
318
|
+
selected: false,
|
|
319
|
+
expanded: false
|
|
320
|
+
})}
|
|
321
|
+
{:else}
|
|
322
|
+
{column.options.value?.(row)}
|
|
323
|
+
{/if}
|
|
320
324
|
</td>
|
|
321
325
|
{/each}
|
|
322
326
|
</tr>
|
|
@@ -346,7 +350,7 @@
|
|
|
346
350
|
{/snippet}
|
|
347
351
|
|
|
348
352
|
{#snippet dragSnippet()}
|
|
349
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
|
353
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" style='opacity: .3'>
|
|
350
354
|
<path
|
|
351
355
|
fill="currentColor"
|
|
352
356
|
d="M5.5 5a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3m0 4.5a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3m1.5 3a1.5 1.5 0 1 1-3 0a1.5 1.5 0 0 1 3 0M10.5 5a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3M12 8a1.5 1.5 0 1 1-3 0a1.5 1.5 0 0 1 3 0m-1.5 6a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3"
|
|
@@ -662,10 +666,10 @@
|
|
|
662
666
|
id='__fixed'
|
|
663
667
|
{table}
|
|
664
668
|
fixed
|
|
665
|
-
width={Math.max(
|
|
669
|
+
width={Math.max(48, 0
|
|
666
670
|
+ (select && show !== 'never' ? 34 : 0)
|
|
667
671
|
+ (reorderable ? 34 : 0)
|
|
668
|
-
+ (expandable?.options.chevron !== 'never' ? 34 : 0)
|
|
672
|
+
+ (expandable && expandable?.options.chevron !== 'never' ? 34 : 0)
|
|
669
673
|
)}
|
|
670
674
|
resizeable={false}
|
|
671
675
|
>
|
|
@@ -740,6 +744,21 @@
|
|
|
740
744
|
{/if}
|
|
741
745
|
{/if}
|
|
742
746
|
|
|
747
|
+
{#if table.options.auto}
|
|
748
|
+
{#each Object.keys(data.current[0] || {}) as key}
|
|
749
|
+
<Column
|
|
750
|
+
id={key}
|
|
751
|
+
value={r => r[key]}
|
|
752
|
+
header={capitalize(segmentize(key))}
|
|
753
|
+
sort={
|
|
754
|
+
typeof data.current[0]?.[key] === 'number'
|
|
755
|
+
? (a, b) => a - b
|
|
756
|
+
: (a, b) => String(a).localeCompare(String(b))
|
|
757
|
+
}
|
|
758
|
+
/>
|
|
759
|
+
{/each}
|
|
760
|
+
{/if}
|
|
761
|
+
|
|
743
762
|
{@render content?.({
|
|
744
763
|
Column,
|
|
745
764
|
Panel,
|
|
@@ -1045,8 +1064,15 @@
|
|
|
1045
1064
|
}
|
|
1046
1065
|
|
|
1047
1066
|
.row > .column {
|
|
1067
|
+
background-color: var(--tably-bg);
|
|
1048
1068
|
padding: var(--tably-padding-y) 0;
|
|
1049
1069
|
}
|
|
1070
|
+
|
|
1071
|
+
:global(#runic-drag .row) {
|
|
1072
|
+
border: 1px solid var(--tably-border-grid);
|
|
1073
|
+
border-top: 2px solid var(--tably-border-grid);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1050
1076
|
.row > * {
|
|
1051
1077
|
border-left: 1px solid var(--tably-border-grid);
|
|
1052
1078
|
border-bottom: 1px solid var(--tably-border-grid);
|
|
@@ -28,7 +28,8 @@ export class TableState {
|
|
|
28
28
|
resizeable: this.#props.resizeable ?? true,
|
|
29
29
|
reorderable: this.#props.reorderable ?? false,
|
|
30
30
|
href: this.#props.href,
|
|
31
|
-
select: this.#props.select ?? false
|
|
31
|
+
select: this.#props.select ?? false,
|
|
32
|
+
auto: this.#props.auto ?? false
|
|
32
33
|
});
|
|
33
34
|
add(state) {
|
|
34
35
|
if (state instanceof ColumnState) {
|
package/dist/utility.svelte.d.ts
CHANGED
|
@@ -14,4 +14,8 @@ type SetterRecord = Record<PropertyKey, [() => any, (v: any) => void]>;
|
|
|
14
14
|
export declare function withSetters<T extends SetterRecord>(obj: T): T;
|
|
15
15
|
export declare function fromProps<T extends AnyRecord, B extends SetterRecord>(props: T, boundProps?: B): Simplify<{ [K in keyof B]: ReturnType<B[K][0]>; } & { readonly [K in keyof T]: T[K]; }>;
|
|
16
16
|
export declare function assignDescriptors<T extends AnyRecord, B extends AnyRecord>(target: T, source: B): T & B;
|
|
17
|
+
/** Capitalize by space */
|
|
18
|
+
export declare function capitalize(str: string): string;
|
|
19
|
+
/** Split words when going from lower case to uppercase; `someWords-split` -> `some Word Split...` */
|
|
20
|
+
export declare function segmentize(str: string): string;
|
|
17
21
|
export {};
|
package/dist/utility.svelte.js
CHANGED
|
@@ -78,3 +78,27 @@ export function assignDescriptors(target, source) {
|
|
|
78
78
|
}
|
|
79
79
|
return target;
|
|
80
80
|
}
|
|
81
|
+
/** Capitalize by space */
|
|
82
|
+
export function capitalize(str) {
|
|
83
|
+
let parts = str.split(' ');
|
|
84
|
+
let result = '';
|
|
85
|
+
for (let part of parts) {
|
|
86
|
+
result += part.charAt(0).toUpperCase() + part.slice(1) + ' ';
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
/** Split words when going from lower case to uppercase; `someWords-split` -> `some Word Split...` */
|
|
91
|
+
export function segmentize(str) {
|
|
92
|
+
let result = '';
|
|
93
|
+
for (let i = 0; i < str.length; i++) {
|
|
94
|
+
const char = str[i];
|
|
95
|
+
const prevChar = i > 0 ? str[i - 1] : '';
|
|
96
|
+
if ((char === '-' || char === char.toUpperCase()) && prevChar !== ' ' && prevChar !== prevChar.toUpperCase()) {
|
|
97
|
+
result += ' ';
|
|
98
|
+
if (char === '-')
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
result += char;
|
|
102
|
+
}
|
|
103
|
+
return result.trim();
|
|
104
|
+
}
|