compote-ui 0.40.2 → 0.41.1
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/components/card/card-content.svelte +1 -1
- package/dist/components/card/card-header.svelte +1 -1
- package/dist/components/data-table/create-table.js +2 -1
- package/dist/components/data-table/data-table-head.svelte +34 -4
- package/dist/components/data-table/data-table-head.svelte.d.ts +1 -0
- package/dist/components/data-table/data-table-utils.d.ts +2 -0
- package/dist/components/data-table/data-table-utils.js +6 -0
- package/dist/components/data-table/data-table-virtual-rows.svelte +4 -1
- package/dist/components/data-table/data-table.svelte +15 -4
- package/dist/components/data-table/types.d.ts +2 -0
- package/dist/components/scroll-area/scroll-area-viewport.svelte +1 -1
- package/dist/components/splitter/splitter.svelte +43 -40
- package/dist/components/tree-view/tree-view.svelte +62 -64
- package/package.json +1 -1
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
let { class: className, children, ...rest }: HTMLAttributes<HTMLDivElement> = $props();
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
|
-
<div class={cn('flex flex-col gap-1.5
|
|
8
|
+
<div class={cn('flex flex-col gap-1.5 p-4', className)} {...rest}>
|
|
9
9
|
{@render children?.()}
|
|
10
10
|
</div>
|
|
@@ -113,7 +113,8 @@ function createColumns(columns, localeCtx) {
|
|
|
113
113
|
align: column.align,
|
|
114
114
|
type: column.type,
|
|
115
115
|
formatOptions: column.formatOptions,
|
|
116
|
-
formatLocale: column.formatLocale
|
|
116
|
+
formatLocale: column.formatLocale,
|
|
117
|
+
grow: column.grow
|
|
117
118
|
}
|
|
118
119
|
};
|
|
119
120
|
if (typeof column.accessorFn === 'function') {
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
resizeHandleStyle,
|
|
19
19
|
sortButtonDirectionClass,
|
|
20
20
|
virtualColumnSizeStyle,
|
|
21
|
+
virtualGroupWithGrowSizeStyle,
|
|
22
|
+
virtualGrowColumnSizeStyle,
|
|
21
23
|
virtualSelectionColumnSizeStyle
|
|
22
24
|
} from './data-table-utils';
|
|
23
25
|
|
|
@@ -29,6 +31,7 @@
|
|
|
29
31
|
isMultiRowSelectionEnabled: boolean;
|
|
30
32
|
allRowsSelectionState: boolean | 'indeterminate';
|
|
31
33
|
isVirtual?: boolean;
|
|
34
|
+
hasGrowColumn?: boolean;
|
|
32
35
|
};
|
|
33
36
|
|
|
34
37
|
let {
|
|
@@ -38,14 +41,41 @@
|
|
|
38
41
|
isRowSelectionEnabled,
|
|
39
42
|
isMultiRowSelectionEnabled,
|
|
40
43
|
allRowsSelectionState,
|
|
41
|
-
isVirtual = false
|
|
44
|
+
isVirtual = false,
|
|
45
|
+
hasGrowColumn = false
|
|
42
46
|
}: Props = $props();
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
type Header = HeaderGroup<DataTableFeatures, T>['headers'][number];
|
|
49
|
+
|
|
50
|
+
function findGrowLeafHeader(header: Header): Header | undefined {
|
|
51
|
+
if (header.subHeaders.length === 0) {
|
|
52
|
+
return getColumnMeta(header.column.columnDef)?.grow ? header : undefined;
|
|
53
|
+
}
|
|
54
|
+
for (const sub of header.subHeaders) {
|
|
55
|
+
const found = findGrowLeafHeader(sub);
|
|
56
|
+
if (found) return found;
|
|
57
|
+
}
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function headerCellStyle(header: Header) {
|
|
45
62
|
const canPinHeader = header.subHeaders.length === 0;
|
|
46
63
|
|
|
64
|
+
let virtualSizeStyle: string | undefined;
|
|
65
|
+
if (isVirtual) {
|
|
66
|
+
const isGrowLeaf = canPinHeader && getColumnMeta(header.column.columnDef)?.grow;
|
|
67
|
+
if (isGrowLeaf) {
|
|
68
|
+
virtualSizeStyle = virtualGrowColumnSizeStyle();
|
|
69
|
+
} else {
|
|
70
|
+
const growLeaf = findGrowLeafHeader(header);
|
|
71
|
+
virtualSizeStyle = growLeaf
|
|
72
|
+
? virtualGroupWithGrowSizeStyle(header.getSize() - growLeaf.getSize())
|
|
73
|
+
: virtualColumnSizeStyle(header.getSize());
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
47
77
|
return joinStyles(
|
|
48
|
-
|
|
78
|
+
virtualSizeStyle,
|
|
49
79
|
canPinHeader ? getPinningStyle(header.column, true, isRowSelectionEnabled) : undefined
|
|
50
80
|
);
|
|
51
81
|
}
|
|
@@ -155,7 +185,7 @@
|
|
|
155
185
|
{/if}
|
|
156
186
|
</th>
|
|
157
187
|
{/each}
|
|
158
|
-
{#if !isVirtual}
|
|
188
|
+
{#if !isVirtual && !hasGrowColumn}
|
|
159
189
|
<th aria-hidden="true" class="h-9 border-b border-surface-3 bg-surface-2 p-0"></th>
|
|
160
190
|
{/if}
|
|
161
191
|
</tr>
|
|
@@ -16,6 +16,8 @@ export declare function selectionColumnSizeStyle(): string;
|
|
|
16
16
|
export declare function virtualColumnSizeStyle(size: number): string;
|
|
17
17
|
export declare function virtualSelectionColumnSizeStyle(): string;
|
|
18
18
|
export declare function tableSizeStyle<T extends RowData>(table: DataTableInstance<T>, isRowSelectionEnabled: boolean): string;
|
|
19
|
+
export declare function virtualGrowColumnSizeStyle(): string;
|
|
20
|
+
export declare function virtualGroupWithGrowSizeStyle(fixedPortion: number): string;
|
|
19
21
|
export declare function resizeHandleStyle<T extends RowData>(table: DataTableInstance<T>, header: Header<DataTableFeatures, T, CellData>): string | undefined;
|
|
20
22
|
export declare function resizeHandleClass(headerIndex: number, headerCount: number): import("tailwind-variants").CnReturn;
|
|
21
23
|
export declare function getHeaderSortDirection<T extends RowData>(header: Header<DataTableFeatures, T, CellData>, sortingState: unknown): false | import("@tanstack/table-core").SortDirection;
|
|
@@ -27,6 +27,12 @@ export function virtualSelectionColumnSizeStyle() {
|
|
|
27
27
|
export function tableSizeStyle(table, isRowSelectionEnabled) {
|
|
28
28
|
return `width: max(100%, ${table.getTotalSize() + (isRowSelectionEnabled ? 40 : 0)}px)`;
|
|
29
29
|
}
|
|
30
|
+
export function virtualGrowColumnSizeStyle() {
|
|
31
|
+
return 'display: flex; flex: 1; min-width: 0';
|
|
32
|
+
}
|
|
33
|
+
export function virtualGroupWithGrowSizeStyle(fixedPortion) {
|
|
34
|
+
return `display: flex; flex: 1 0 ${fixedPortion}px; width: ${fixedPortion}px`;
|
|
35
|
+
}
|
|
30
36
|
export function resizeHandleStyle(table, header) {
|
|
31
37
|
if (table.options.columnResizeMode !== 'onEnd')
|
|
32
38
|
return undefined;
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
justifyClass,
|
|
19
19
|
openUrlCell,
|
|
20
20
|
virtualColumnSizeStyle,
|
|
21
|
+
virtualGrowColumnSizeStyle,
|
|
21
22
|
virtualSelectionColumnSizeStyle
|
|
22
23
|
} from './data-table-utils';
|
|
23
24
|
|
|
@@ -116,7 +117,9 @@
|
|
|
116
117
|
cell.column.getIsPinned() && 'bg-(--row-bg)'
|
|
117
118
|
)}
|
|
118
119
|
style={joinStyles(
|
|
119
|
-
|
|
120
|
+
getColumnMeta(cell.column.columnDef)?.grow
|
|
121
|
+
? virtualGrowColumnSizeStyle()
|
|
122
|
+
: virtualColumnSizeStyle(cell.column.getSize()),
|
|
120
123
|
getPinningStyle(cell.column, false, isRowSelectionEnabled)
|
|
121
124
|
)}
|
|
122
125
|
>
|
|
@@ -59,6 +59,8 @@
|
|
|
59
59
|
trackTableState();
|
|
60
60
|
return table.getVisibleLeafColumns();
|
|
61
61
|
});
|
|
62
|
+
const growColumn = $derived(visibleLeafColumns.find((col) => getColumnMeta(col.columnDef)?.grow));
|
|
63
|
+
const hasGrowColumn = $derived(growColumn !== undefined);
|
|
62
64
|
const visibleColumnCount = $derived(visibleLeafColumns.length);
|
|
63
65
|
const isRowSelectionEnabled = $derived(Boolean(table.options.enableRowSelection));
|
|
64
66
|
const isMultiRowSelectionEnabled = $derived(table.options.enableMultiRowSelection !== false);
|
|
@@ -93,9 +95,15 @@
|
|
|
93
95
|
<col style={selectionColumnSizeStyle()} />
|
|
94
96
|
{/if}
|
|
95
97
|
{#each visibleLeafColumns as column (column.id)}
|
|
96
|
-
<col
|
|
98
|
+
<col
|
|
99
|
+
style={getColumnMeta(column.columnDef)?.grow
|
|
100
|
+
? undefined
|
|
101
|
+
: columnSizeStyle(column.getSize())}
|
|
102
|
+
/>
|
|
97
103
|
{/each}
|
|
98
|
-
|
|
104
|
+
{#if !hasGrowColumn}
|
|
105
|
+
<col />
|
|
106
|
+
{/if}
|
|
99
107
|
</colgroup>
|
|
100
108
|
{#if caption}
|
|
101
109
|
<caption class="sr-only">{caption}</caption>
|
|
@@ -107,6 +115,7 @@
|
|
|
107
115
|
{isRowSelectionEnabled}
|
|
108
116
|
{isMultiRowSelectionEnabled}
|
|
109
117
|
{allRowsSelectionState}
|
|
118
|
+
{hasGrowColumn}
|
|
110
119
|
/>
|
|
111
120
|
<tbody>
|
|
112
121
|
{#each rowModel.rows as row (row.id)}
|
|
@@ -189,8 +198,10 @@
|
|
|
189
198
|
{/if}
|
|
190
199
|
</td>
|
|
191
200
|
{/each}
|
|
192
|
-
|
|
193
|
-
|
|
201
|
+
{#if !hasGrowColumn}
|
|
202
|
+
<td aria-hidden="true" class="border-b border-surface-2 p-0 group-last/row:border-b-0"
|
|
203
|
+
></td>
|
|
204
|
+
{/if}
|
|
194
205
|
</tr>
|
|
195
206
|
{:else}
|
|
196
207
|
<tr>
|
|
@@ -22,6 +22,7 @@ export type DataTableLeafColumnBase<T extends RowData> = DataTableColumnOptions<
|
|
|
22
22
|
formatOptions?: Intl.NumberFormatOptions;
|
|
23
23
|
formatLocale?: string;
|
|
24
24
|
pinned?: 'left' | 'right';
|
|
25
|
+
grow?: boolean;
|
|
25
26
|
columns?: never;
|
|
26
27
|
};
|
|
27
28
|
export type DataTableAccessorKeyColumn<T extends RowData> = DataTableLeafColumnBase<T> & {
|
|
@@ -54,4 +55,5 @@ export type DataTableColumnMeta = {
|
|
|
54
55
|
type?: DataTableColumnType;
|
|
55
56
|
formatOptions?: Intl.NumberFormatOptions;
|
|
56
57
|
formatLocale?: string;
|
|
58
|
+
grow?: boolean;
|
|
57
59
|
};
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<ScrollArea.Viewport
|
|
14
14
|
{...rest}
|
|
15
15
|
class={cn(
|
|
16
|
-
'h-full
|
|
16
|
+
'h-full scrollbar-none overscroll-contain outline-none [&::-webkit-scrollbar]:hidden',
|
|
17
17
|
'focus-visible:ring-2 focus-visible:ring-ring',
|
|
18
18
|
className
|
|
19
19
|
)}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Splitter } from '@ark-ui/svelte/splitter';
|
|
3
3
|
import { cn } from 'tailwind-variants';
|
|
4
4
|
import type { SplitterProps } from './types';
|
|
5
|
+
import { ClientOnly } from '@ark-ui/svelte/client-only';
|
|
5
6
|
|
|
6
7
|
let {
|
|
7
8
|
panels,
|
|
@@ -15,46 +16,48 @@
|
|
|
15
16
|
const arkPanels = $derived(panels.map(({ content: _content, ...rest }) => rest));
|
|
16
17
|
</script>
|
|
17
18
|
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{@render panelConfig.content()}
|
|
30
|
-
</Splitter.Panel>
|
|
31
|
-
|
|
32
|
-
{#if i < panels.length - 1}
|
|
33
|
-
<Splitter.ResizeTrigger
|
|
34
|
-
id={`${panelConfig.id}:${panels[i + 1].id}`}
|
|
35
|
-
aria-label={`Resize ${panelConfig.id} and ${panels[i + 1].id}`}
|
|
36
|
-
class={cn(
|
|
37
|
-
'group relative flex shrink-0 items-center justify-center border-none bg-transparent p-0 outline-none',
|
|
38
|
-
isHorizontal ? 'w-1.5 cursor-col-resize' : 'h-1.5 cursor-row-resize'
|
|
39
|
-
)}
|
|
19
|
+
<ClientOnly>
|
|
20
|
+
<Splitter.Root
|
|
21
|
+
{orientation}
|
|
22
|
+
panels={arkPanels}
|
|
23
|
+
{...restProps}
|
|
24
|
+
class={cn('flex h-full w-full', !isHorizontal && 'flex-col', className)}
|
|
25
|
+
>
|
|
26
|
+
{#each panels as panelConfig, i (panelConfig.id)}
|
|
27
|
+
<Splitter.Panel
|
|
28
|
+
id={panelConfig.id}
|
|
29
|
+
class={cn('overflow-auto p-2', isHorizontal ? 'min-w-0' : 'min-h-0')}
|
|
40
30
|
>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
)}
|
|
49
|
-
></div>
|
|
50
|
-
<!-- Handle pill -->
|
|
51
|
-
<div
|
|
31
|
+
{@render panelConfig.content()}
|
|
32
|
+
</Splitter.Panel>
|
|
33
|
+
|
|
34
|
+
{#if i < panels.length - 1}
|
|
35
|
+
<Splitter.ResizeTrigger
|
|
36
|
+
id={`${panelConfig.id}:${panels[i + 1].id}`}
|
|
37
|
+
aria-label={`Resize ${panelConfig.id} and ${panels[i + 1].id}`}
|
|
52
38
|
class={cn(
|
|
53
|
-
'relative
|
|
54
|
-
isHorizontal ? '
|
|
39
|
+
'group relative flex shrink-0 items-center justify-center border-none bg-transparent p-0 outline-none',
|
|
40
|
+
isHorizontal ? 'w-1.5 cursor-col-resize' : 'h-1.5 cursor-row-resize'
|
|
55
41
|
)}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
42
|
+
>
|
|
43
|
+
<!-- Divider line -->
|
|
44
|
+
<div
|
|
45
|
+
class={cn(
|
|
46
|
+
'absolute bg-surface-3 transition-colors group-focus-within:bg-primary group-hover:bg-primary/40 group-data-dragging:bg-primary',
|
|
47
|
+
isHorizontal
|
|
48
|
+
? 'inset-y-0 left-1/2 w-px -translate-x-1/2'
|
|
49
|
+
: 'inset-x-0 top-1/2 h-px -translate-y-1/2'
|
|
50
|
+
)}
|
|
51
|
+
></div>
|
|
52
|
+
<!-- Handle pill -->
|
|
53
|
+
<div
|
|
54
|
+
class={cn(
|
|
55
|
+
'relative z-10 rounded-full bg-surface-3 shadow-sm transition-colors group-hover:bg-primary/40 group-data-dragging:bg-primary',
|
|
56
|
+
isHorizontal ? 'h-6 w-1' : 'h-1 w-6'
|
|
57
|
+
)}
|
|
58
|
+
></div>
|
|
59
|
+
</Splitter.ResizeTrigger>
|
|
60
|
+
{/if}
|
|
61
|
+
{/each}
|
|
62
|
+
</Splitter.Root>
|
|
63
|
+
</ClientOnly>
|
|
@@ -74,8 +74,7 @@
|
|
|
74
74
|
}
|
|
75
75
|
</script>
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
<!--
|
|
77
|
+
<!--
|
|
79
78
|
| Varijabla | Vrednost | Opis |
|
|
80
79
|
|---|---|---|
|
|
81
80
|
| `--tree-indent` | `0.75rem` | indent po nivou |
|
|
@@ -83,70 +82,69 @@
|
|
|
83
82
|
| `--tree-gap` | `0.5rem` | razmak između elemenata |
|
|
84
83
|
| `--tree-px` | `0.75rem` | bazni levi padding
|
|
85
84
|
-->
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
<div class="flex gap-2 p-3">
|
|
112
|
-
<TreeView.Context>
|
|
113
|
-
{#snippet render(tree)}
|
|
114
|
-
<Button
|
|
115
|
-
variant="outline"
|
|
116
|
-
size="icon-lg"
|
|
117
|
-
title="Collapse all"
|
|
118
|
-
onclick={() => tree().collapse()}
|
|
119
|
-
>
|
|
120
|
-
<PhArrowsInSimple class="size-4" />
|
|
121
|
-
</Button>
|
|
122
|
-
{/snippet}
|
|
123
|
-
</TreeView.Context>
|
|
85
|
+
<TreeView.Root
|
|
86
|
+
oncontextmenu={handleContextMenu}
|
|
87
|
+
{...restProps}
|
|
88
|
+
{collection}
|
|
89
|
+
{selectionMode}
|
|
90
|
+
{selectedValue}
|
|
91
|
+
{expandedValue}
|
|
92
|
+
{checkedValue}
|
|
93
|
+
onSelectionChange={(details) => {
|
|
94
|
+
onSelectionChange?.(details);
|
|
95
|
+
}}
|
|
96
|
+
onExpandedChange={(details) => {
|
|
97
|
+
userExpandedValue = details.expandedValue;
|
|
98
|
+
onExpandedChange?.(details);
|
|
99
|
+
}}
|
|
100
|
+
onCheckedChange={(details) => {
|
|
101
|
+
checkedValue = details.checkedValue;
|
|
102
|
+
onCheckedChange?.(details);
|
|
103
|
+
}}
|
|
104
|
+
class="flex h-full flex-col gap-3"
|
|
105
|
+
style="--tree-indent: 0rem; --tree-icon: 1rem; --tree-gap: 0.5rem; --tree-px: 0.75rem"
|
|
106
|
+
>
|
|
107
|
+
{#if label}
|
|
108
|
+
<TreeView.Label class="font-medium">{label}</TreeView.Label>
|
|
109
|
+
{/if}
|
|
124
110
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
111
|
+
<div class="flex gap-1">
|
|
112
|
+
<TreeView.Context>
|
|
113
|
+
{#snippet render(tree)}
|
|
114
|
+
<Button
|
|
115
|
+
variant="outline"
|
|
116
|
+
size="icon-lg"
|
|
117
|
+
title="Collapse all"
|
|
118
|
+
onclick={() => tree().collapse()}
|
|
119
|
+
>
|
|
120
|
+
<PhArrowsInSimple class="size-4" />
|
|
121
|
+
</Button>
|
|
122
|
+
{/snippet}
|
|
123
|
+
</TreeView.Context>
|
|
124
|
+
<div class="flex-1">
|
|
125
|
+
<Field.Root>
|
|
126
|
+
<Field.Input bind:value={searchTerm} placeholder="Search...">
|
|
127
|
+
{#snippet startIcon()}
|
|
128
|
+
<PhMagnifyingGlass class="size-4" />
|
|
129
|
+
{/snippet}
|
|
130
|
+
{#snippet endIcon()}
|
|
131
|
+
<Button variant="ghost" size="icon" onclick={() => (searchTerm = '')}>
|
|
132
|
+
<PhX />
|
|
133
|
+
</Button>
|
|
134
|
+
{/snippet}
|
|
135
|
+
</Field.Input>
|
|
136
|
+
</Field.Root>
|
|
139
137
|
</div>
|
|
138
|
+
</div>
|
|
140
139
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
</div>
|
|
140
|
+
<div class="flex-1 overflow-x-hidden overflow-y-auto">
|
|
141
|
+
<TreeView.Tree class="flex flex-col text-sm">
|
|
142
|
+
{#each collection.rootNode.children ?? [] as node, index (node.value)}
|
|
143
|
+
{@render renderNode(node as T, [index])}
|
|
144
|
+
{/each}
|
|
145
|
+
</TreeView.Tree>
|
|
146
|
+
</div>
|
|
147
|
+
</TreeView.Root>
|
|
150
148
|
|
|
151
149
|
{#snippet nodeCheckbox()}
|
|
152
150
|
<TreeView.NodeCheckbox
|
|
@@ -186,7 +184,7 @@
|
|
|
186
184
|
</TreeView.BranchText>
|
|
187
185
|
</TreeView.BranchControl>
|
|
188
186
|
<TreeView.BranchContent class="relative">
|
|
189
|
-
<TreeView.BranchIndentGuide class="absolute inset-y-0 w-px bg-border" />
|
|
187
|
+
<!-- <TreeView.BranchIndentGuide class="absolute inset-y-0 w-px bg-border" /> -->
|
|
190
188
|
{#each node.children as child, childIndex (child.value)}
|
|
191
189
|
{@render renderNode(child as T, [...indexPath, childIndex])}
|
|
192
190
|
{/each}
|