@streamscloud/kit 0.17.0 → 0.19.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/ui/badge/cmp.badge.svelte +4 -0
- package/dist/ui/badge/cmp.badge.svelte.d.ts +1 -0
- package/dist/ui/page-toolbar/cmp.reorderable-checkbox-list.svelte +131 -0
- package/dist/ui/page-toolbar/cmp.reorderable-checkbox-list.svelte.d.ts +31 -0
- package/dist/ui/page-toolbar/cmp.toolbar-checkbox.svelte +14 -0
- package/dist/ui/page-toolbar/cmp.toolbar-checkbox.svelte.d.ts +19 -0
- package/dist/ui/page-toolbar/cmp.toolbar-divider.svelte +19 -0
- package/dist/ui/page-toolbar/cmp.toolbar-divider.svelte.d.ts +35 -0
- package/dist/ui/page-toolbar/cmp.toolbar-filter-select.svelte +143 -0
- package/dist/ui/page-toolbar/cmp.toolbar-filter-select.svelte.d.ts +68 -0
- package/dist/ui/page-toolbar/cmp.toolbar-icon-button.svelte +71 -0
- package/dist/ui/page-toolbar/cmp.toolbar-icon-button.svelte.d.ts +32 -0
- package/dist/ui/page-toolbar/cmp.toolbar-option.svelte +189 -0
- package/dist/ui/page-toolbar/cmp.toolbar-option.svelte.d.ts +47 -0
- package/dist/ui/page-toolbar/cmp.toolbar-popover.svelte +23 -8
- package/dist/ui/page-toolbar/cmp.toolbar-popover.svelte.d.ts +14 -6
- package/dist/ui/page-toolbar/cmp.toolbar-section-title.svelte +46 -0
- package/dist/ui/page-toolbar/cmp.toolbar-section-title.svelte.d.ts +24 -0
- package/dist/ui/page-toolbar/cmp.toolbar-sort-select.svelte +31 -0
- package/dist/ui/page-toolbar/cmp.toolbar-sort-select.svelte.d.ts +44 -0
- package/dist/ui/page-toolbar/{cmp.toolbar-switch-item.svelte → cmp.toolbar-switch.svelte} +10 -10
- package/dist/ui/page-toolbar/{cmp.toolbar-switch-item.svelte.d.ts → cmp.toolbar-switch.svelte.d.ts} +2 -2
- package/dist/ui/page-toolbar/cmp.toolbar-toggle.svelte +14 -0
- package/dist/ui/page-toolbar/cmp.toolbar-toggle.svelte.d.ts +19 -0
- package/dist/ui/page-toolbar/cmp.toolbar-view-controls.svelte +51 -0
- package/dist/ui/page-toolbar/cmp.toolbar-view-controls.svelte.d.ts +27 -0
- package/dist/ui/page-toolbar/index.d.ts +12 -7
- package/dist/ui/page-toolbar/index.js +11 -6
- package/dist/ui/page-toolbar/reorderable-checkbox-list-localization.d.ts +5 -0
- package/dist/ui/page-toolbar/reorderable-checkbox-list-localization.js +17 -0
- package/dist/ui/page-toolbar/toolbar-filter-select-localization.d.ts +5 -0
- package/dist/ui/page-toolbar/toolbar-filter-select-localization.js +20 -0
- package/dist/ui/page-toolbar/toolbar-sort-select-localization.d.ts +3 -0
- package/dist/ui/page-toolbar/toolbar-sort-select-localization.js +9 -0
- package/dist/ui/page-toolbar/toolbar-view-controls-localization.d.ts +5 -0
- package/dist/ui/page-toolbar/toolbar-view-controls-localization.js +17 -0
- package/dist/ui/page-toolbar/types.d.ts +1 -1
- package/dist/ui/select/index.d.ts +1 -0
- package/dist/ui/select/index.js +1 -0
- package/dist/ui/select/select-listbox.svelte +11 -5
- package/dist/ui/select/select-listbox.svelte.d.ts +1 -1
- package/dist/ui/table/_table-styles.scss +156 -0
- package/dist/ui/table/cmp.table-draggable.svelte +338 -0
- package/dist/ui/table/cmp.table-draggable.svelte.d.ts +79 -0
- package/dist/ui/table/cmp.table.svelte +96 -265
- package/dist/ui/table/cmp.table.svelte.d.ts +16 -8
- package/dist/ui/table/index.d.ts +1 -0
- package/dist/ui/table/index.js +1 -0
- package/dist/ui/table/table-cells/index.d.ts +1 -12
- package/dist/ui/table/table-cells/index.js +1 -12
- package/dist/ui/table/table-cells/table-cell.svelte +77 -0
- package/dist/ui/table/table-cells/{table-select-cell.svelte.d.ts → table-cell.svelte.d.ts} +12 -6
- package/dist/ui/table/table-column-models.svelte.d.ts +1 -2
- package/dist/ui/table/table-column-models.svelte.js +0 -1
- package/dist/ui/table/table-columns-manager/cmp.table-columns-manager.svelte +20 -47
- package/dist/ui/table/table-columns-manager/cmp.table-columns-manager.svelte.d.ts +3 -7
- package/dist/ui/table/table-columns-manager/table-columns-manager-localization.d.ts +1 -1
- package/dist/ui/table/table-columns-manager/table-columns-manager-localization.js +7 -7
- package/dist/ui/table/table-localization.d.ts +0 -2
- package/dist/ui/table/table-localization.js +0 -14
- package/dist/ui/table/table-model.svelte.d.ts +2 -3
- package/dist/ui/table/table-model.svelte.js +5 -35
- package/dist/ui/table/table-view.svelte.d.ts +14 -0
- package/dist/ui/table/table-view.svelte.js +32 -0
- package/dist/ui/table/types.d.ts +5 -28
- package/dist/ui/toggle/cmp.toggle.svelte +32 -26
- package/dist/ui/toggle/cmp.toggle.svelte.d.ts +2 -0
- package/dist/ui/tree/cmp.tree-node-view.svelte +16 -10
- package/dist/ui/tree/cmp.tree-node-view.svelte.d.ts +2 -2
- package/dist/ui/tree/cmp.tree.svelte +14 -30
- package/dist/ui/tree/cmp.tree.svelte.d.ts +5 -5
- package/dist/ui/tree/tree-keyboard.svelte.d.ts +9 -0
- package/dist/ui/tree/tree-keyboard.svelte.js +107 -0
- package/dist/ui/tree/tree-node.svelte.d.ts +7 -3
- package/dist/ui/tree/tree-node.svelte.js +32 -16
- package/package.json +1 -1
- package/dist/ui/page-toolbar/cmp.reorderable-toggle-list.svelte +0 -153
- package/dist/ui/page-toolbar/cmp.reorderable-toggle-list.svelte.d.ts +0 -20
- package/dist/ui/page-toolbar/cmp.toolbar-checkbox-item.svelte +0 -19
- package/dist/ui/page-toolbar/cmp.toolbar-checkbox-item.svelte.d.ts +0 -12
- package/dist/ui/page-toolbar/cmp.toolbar-panel-button.svelte +0 -42
- package/dist/ui/page-toolbar/cmp.toolbar-panel-button.svelte.d.ts +0 -20
- package/dist/ui/page-toolbar/cmp.toolbar-panel.svelte +0 -57
- package/dist/ui/page-toolbar/cmp.toolbar-panel.svelte.d.ts +0 -19
- package/dist/ui/page-toolbar/cmp.toolbar-toggle-item.svelte +0 -16
- package/dist/ui/page-toolbar/cmp.toolbar-toggle-item.svelte.d.ts +0 -12
- package/dist/ui/table/table-cells/table-select-cell.svelte +0 -28
- package/dist/ui/table/table-cells/table-text-input-cell.svelte +0 -69
- package/dist/ui/table/table-cells/table-text-input-cell.svelte.d.ts +0 -38
- package/dist/ui/tree/tree-navigation.svelte.d.ts +0 -14
- package/dist/ui/tree/tree-navigation.svelte.js +0 -99
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DynamicComponentModel } from '../dynamic-component';
|
|
2
2
|
import type { IOneOfTableColumn, ITableActionsColumn, TableColumnSortDirection, TableColumnType, WithId } from './types';
|
|
3
|
-
export type ColumnDef<T extends WithId> = IOneOfTableColumn<T
|
|
3
|
+
export type ColumnDef<T extends WithId> = IOneOfTableColumn<T> | ITableActionsColumn;
|
|
4
4
|
export type SortableTableColumn = {
|
|
5
5
|
uniqueId: symbol;
|
|
6
6
|
title: string;
|
|
@@ -17,7 +17,6 @@ export declare class ResolvedColumn<T extends WithId> {
|
|
|
17
17
|
readonly def: ColumnDef<T>;
|
|
18
18
|
readonly uniqueId: symbol;
|
|
19
19
|
headerView: DynamicComponentModel;
|
|
20
|
-
editorColumn: ResolvedColumn<T> | null;
|
|
21
20
|
hidden: boolean;
|
|
22
21
|
sortDirection: TableColumnSortDirection;
|
|
23
22
|
constructor(def: ColumnDef<T>);
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends {id: string}">import { LocalStorageItem } from '../../../core/local-storage';
|
|
2
|
-
import {
|
|
3
|
-
import { IconText } from '../../icon-text';
|
|
4
|
-
import { ReorderableToggleList } from '../../page-toolbar';
|
|
5
|
-
import { Popover } from '../../popover';
|
|
2
|
+
import { ReorderableCheckboxList, ToolbarPopover } from '../../page-toolbar';
|
|
6
3
|
import { TableColumnsManagerLocalization } from './table-columns-manager-localization';
|
|
7
|
-
import IconChevronDown from '@fluentui/svg-icons/icons/chevron_down_20_regular.svg?raw';
|
|
8
4
|
import IconColumnTwo from '@fluentui/svg-icons/icons/text_column_two_20_regular.svg?raw';
|
|
9
5
|
import { untrack } from 'svelte';
|
|
10
6
|
let { model, localStorageKey, on } = $props();
|
|
@@ -16,15 +12,20 @@ const items = $derived(hideableColumns.map((col) => ({
|
|
|
16
12
|
label: col.title,
|
|
17
13
|
enabled: !col.hidden
|
|
18
14
|
})));
|
|
19
|
-
// Load from localStorage once columns are available
|
|
20
15
|
let initialized = false;
|
|
16
|
+
let standardItems = $state.raw([]);
|
|
21
17
|
$effect(() => {
|
|
22
18
|
const columns = hideableColumns;
|
|
23
|
-
if (
|
|
19
|
+
if (columns.length === 0 || initialized) {
|
|
24
20
|
return;
|
|
25
21
|
}
|
|
26
22
|
initialized = true;
|
|
27
|
-
|
|
23
|
+
standardItems = columns.map((col) => ({
|
|
24
|
+
id: String(col.id),
|
|
25
|
+
label: col.title,
|
|
26
|
+
enabled: !('hidden' in col.def && col.def.hidden === true)
|
|
27
|
+
}));
|
|
28
|
+
const saved = storage?.get();
|
|
28
29
|
if (!saved || !Array.isArray(saved)) {
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
@@ -75,46 +76,18 @@ const handleChange = (updatedItems) => {
|
|
|
75
76
|
};
|
|
76
77
|
</script>
|
|
77
78
|
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
<div class="columns-manager__body">
|
|
87
|
-
<ReorderableToggleList items={items} on={{ change: handleChange }} />
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
</Popover>
|
|
79
|
+
<ToolbarPopover triggerLabel={localization.view} icon={{ src: IconColumnTwo, color: 'accent' }}>
|
|
80
|
+
<ReorderableCheckboxList
|
|
81
|
+
items={items}
|
|
82
|
+
title={localization.columns}
|
|
83
|
+
standard={standardItems.length ? standardItems : undefined}
|
|
84
|
+
showClearAll={false}
|
|
85
|
+
on={{ change: handleChange }} />
|
|
86
|
+
</ToolbarPopover>
|
|
91
87
|
|
|
92
88
|
<!--
|
|
93
89
|
@component
|
|
94
|
-
Column visibility and order manager for tables.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
### CSS Custom Properties
|
|
98
|
-
| Property | Description | Default |
|
|
99
|
-
|---|---|---|
|
|
100
|
-
| `--sc-kit--table-columns-manager--title--color` | Title text color | `var(--sc-kit--color--text--primary)` |
|
|
90
|
+
Column visibility and order manager for tables. Opens a `ToolbarPopover` with a `ReorderableCheckboxList`
|
|
91
|
+
of the hideable columns — drag to reorder, click to show / hide. Supports optional localStorage persistence
|
|
92
|
+
of column order and visibility.
|
|
101
93
|
-->
|
|
102
|
-
|
|
103
|
-
<style>.columns-manager {
|
|
104
|
-
--_columns-manager--title--color: var(--sc-kit--table-columns-manager--title--color, var(--sc-kit--color--text--primary));
|
|
105
|
-
width: 21.875rem;
|
|
106
|
-
padding: 1.5rem;
|
|
107
|
-
}
|
|
108
|
-
.columns-manager__title {
|
|
109
|
-
font-size: 0.875rem;
|
|
110
|
-
font-weight: 600;
|
|
111
|
-
line-height: 1.25rem;
|
|
112
|
-
color: var(--_columns-manager--title--color);
|
|
113
|
-
margin-bottom: 0.5rem;
|
|
114
|
-
}
|
|
115
|
-
.columns-manager__body {
|
|
116
|
-
display: flex;
|
|
117
|
-
flex-direction: column;
|
|
118
|
-
gap: 1rem;
|
|
119
|
-
padding-block: 0.5rem;
|
|
120
|
-
}</style>
|
|
@@ -41,13 +41,9 @@ interface $$IsomorphicComponent {
|
|
|
41
41
|
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
* Column visibility and order manager for tables.
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* ### CSS Custom Properties
|
|
48
|
-
* | Property | Description | Default |
|
|
49
|
-
* |---|---|---|
|
|
50
|
-
* | `--sc-kit--table-columns-manager--title--color` | Title text color | `var(--sc-kit--color--text--primary)` |
|
|
44
|
+
* Column visibility and order manager for tables. Opens a `ToolbarPopover` with a `ReorderableCheckboxList`
|
|
45
|
+
* of the hideable columns — drag to reorder, click to show / hide. Supports optional localStorage persistence
|
|
46
|
+
* of column order and visibility.
|
|
51
47
|
*/
|
|
52
48
|
declare const Cmp: $$IsomorphicComponent;
|
|
53
49
|
type Cmp<T extends {
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { AppLocale } from '../../../core/locale';
|
|
2
2
|
export class TableColumnsManagerLocalization {
|
|
3
|
+
get view() {
|
|
4
|
+
return loc.view[AppLocale.current];
|
|
5
|
+
}
|
|
3
6
|
get columns() {
|
|
4
7
|
return loc.columns[AppLocale.current];
|
|
5
8
|
}
|
|
6
|
-
get selectColumns() {
|
|
7
|
-
return loc.selectColumns[AppLocale.current];
|
|
8
|
-
}
|
|
9
9
|
}
|
|
10
10
|
const loc = {
|
|
11
|
+
view: {
|
|
12
|
+
en: 'View',
|
|
13
|
+
no: 'Visning'
|
|
14
|
+
},
|
|
11
15
|
columns: {
|
|
12
16
|
en: 'Columns',
|
|
13
17
|
no: 'Kolonner'
|
|
14
|
-
},
|
|
15
|
-
selectColumns: {
|
|
16
|
-
en: 'Select Columns',
|
|
17
|
-
no: 'Velg kolonner'
|
|
18
18
|
}
|
|
19
19
|
};
|
|
@@ -6,12 +6,6 @@ export class TableLocalization {
|
|
|
6
6
|
get noItemsFoundBody() {
|
|
7
7
|
return loc.noItemsFoundBody[AppLocale.current];
|
|
8
8
|
}
|
|
9
|
-
get save() {
|
|
10
|
-
return loc.save[AppLocale.current];
|
|
11
|
-
}
|
|
12
|
-
get cancel() {
|
|
13
|
-
return loc.cancel[AppLocale.current];
|
|
14
|
-
}
|
|
15
9
|
}
|
|
16
10
|
const loc = {
|
|
17
11
|
noItemsFoundTitle: {
|
|
@@ -21,13 +15,5 @@ const loc = {
|
|
|
21
15
|
noItemsFoundBody: {
|
|
22
16
|
en: 'No data found. Create one to get started',
|
|
23
17
|
no: 'Ingen data funnet. Opprett en for å komme i gang'
|
|
24
|
-
},
|
|
25
|
-
save: {
|
|
26
|
-
en: 'Save',
|
|
27
|
-
no: 'Lagre'
|
|
28
|
-
},
|
|
29
|
-
cancel: {
|
|
30
|
-
en: 'Cancel',
|
|
31
|
-
no: 'Avbryt'
|
|
32
18
|
}
|
|
33
19
|
};
|
|
@@ -20,7 +20,6 @@ export declare class TableModel<T extends WithId> {
|
|
|
20
20
|
private _selection;
|
|
21
21
|
private _preserveSelection;
|
|
22
22
|
private _dataProvider;
|
|
23
|
-
private _editingItem;
|
|
24
23
|
private _highlightedItemIds;
|
|
25
24
|
constructor(init: TableModelInit<T>);
|
|
26
25
|
get items(): T[];
|
|
@@ -29,13 +28,13 @@ export declare class TableModel<T extends WithId> {
|
|
|
29
28
|
get itemGroupActions(): TableGroupAction<T>[];
|
|
30
29
|
get styles(): Readonly<TableStyles>;
|
|
31
30
|
get selection(): Repository<T>;
|
|
32
|
-
get editingItem(): T | null;
|
|
33
31
|
get highlightedItemIds(): string[];
|
|
34
32
|
set items(value: T[]);
|
|
35
33
|
set itemActions(value: TableItemAction<T>[]);
|
|
36
34
|
set columns(value: IAnyTableColumn<T>[]);
|
|
37
|
-
set editingItem(value: T | null);
|
|
38
35
|
set highlightedItemIds(value: string[]);
|
|
36
|
+
/** Reassign items as a pure reorder of the same set — preserves the current selection (unlike the `items` setter). */
|
|
37
|
+
reorderItems: (value: T[]) => void;
|
|
39
38
|
updateStyles: (styles: Partial<TableStyles>) => void;
|
|
40
39
|
setResolvedColumns: (columns: ResolvedColumn<T>[]) => void;
|
|
41
40
|
private reconcileColumns;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Css } from '../../core/css';
|
|
2
2
|
import { createRepository } from '../../core/repository';
|
|
3
|
-
import { Utils } from '../../core/utils';
|
|
4
3
|
import { DynamicComponentModel } from '../dynamic-component';
|
|
5
4
|
import { ResolvedColumn } from './table-column-models.svelte';
|
|
6
5
|
import { TableCheckboxHeader, TableHeader, TableHeaderSortable } from './table-headers';
|
|
@@ -15,7 +14,6 @@ export class TableModel {
|
|
|
15
14
|
_selection;
|
|
16
15
|
_preserveSelection = false;
|
|
17
16
|
_dataProvider;
|
|
18
|
-
_editingItem = $state(null);
|
|
19
17
|
_highlightedItemIds = $state.raw([]);
|
|
20
18
|
constructor(init) {
|
|
21
19
|
this._init = init;
|
|
@@ -64,9 +62,6 @@ export class TableModel {
|
|
|
64
62
|
get selection() {
|
|
65
63
|
return this._selection;
|
|
66
64
|
}
|
|
67
|
-
get editingItem() {
|
|
68
|
-
return this._editingItem;
|
|
69
|
-
}
|
|
70
65
|
get highlightedItemIds() {
|
|
71
66
|
return this._highlightedItemIds;
|
|
72
67
|
}
|
|
@@ -76,9 +71,6 @@ export class TableModel {
|
|
|
76
71
|
if (!this._preserveSelection) {
|
|
77
72
|
this._selection.clear();
|
|
78
73
|
}
|
|
79
|
-
if (this._editingItem && !this._items.find((x) => x.id === this._editingItem?.id)) {
|
|
80
|
-
this._editingItem = null;
|
|
81
|
-
}
|
|
82
74
|
}
|
|
83
75
|
set itemActions(value) {
|
|
84
76
|
this._itemActions = value;
|
|
@@ -86,17 +78,14 @@ export class TableModel {
|
|
|
86
78
|
set columns(value) {
|
|
87
79
|
this.reconcileColumns(value);
|
|
88
80
|
}
|
|
89
|
-
set editingItem(value) {
|
|
90
|
-
if (!this._items.find((x) => x.id === value?.id)) {
|
|
91
|
-
this._editingItem = null;
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
this._editingItem = structuredClone($state.snapshot(value));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
81
|
set highlightedItemIds(value) {
|
|
98
82
|
this._highlightedItemIds = value;
|
|
99
83
|
}
|
|
84
|
+
/** Reassign items as a pure reorder of the same set — preserves the current selection (unlike the `items` setter). */
|
|
85
|
+
reorderItems = (value) => {
|
|
86
|
+
this._items = value;
|
|
87
|
+
this._dataProvider.set(...value);
|
|
88
|
+
};
|
|
100
89
|
updateStyles = (styles) => {
|
|
101
90
|
Object.assign(this._styles, styles);
|
|
102
91
|
};
|
|
@@ -157,22 +146,6 @@ export class TableModel {
|
|
|
157
146
|
props: { column: resolved }
|
|
158
147
|
});
|
|
159
148
|
};
|
|
160
|
-
const resolveEditorColumn = (column) => {
|
|
161
|
-
switch (column.type) {
|
|
162
|
-
case 'text-input':
|
|
163
|
-
case 'select': {
|
|
164
|
-
const resolved = new ResolvedColumn(column);
|
|
165
|
-
resolved.headerView = new DynamicComponentModel({
|
|
166
|
-
component: TableHeader,
|
|
167
|
-
props: { column: resolved }
|
|
168
|
-
});
|
|
169
|
-
return resolved;
|
|
170
|
-
}
|
|
171
|
-
default: {
|
|
172
|
-
Utils.assertUnreachable(column);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
149
|
switch (column.type) {
|
|
177
150
|
case 'checkbox': {
|
|
178
151
|
const resolved = new ResolvedColumn({
|
|
@@ -198,9 +171,6 @@ export class TableModel {
|
|
|
198
171
|
case 'text': {
|
|
199
172
|
const resolved = new ResolvedColumn(column);
|
|
200
173
|
resolved.headerView = resolveSortableHeader(resolved);
|
|
201
|
-
if (column.editorColumn) {
|
|
202
|
-
resolved.editorColumn = resolveEditorColumn(column.editorColumn);
|
|
203
|
-
}
|
|
204
174
|
return resolved;
|
|
205
175
|
}
|
|
206
176
|
default: {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ResolvedColumn } from './table-column-models.svelte';
|
|
2
|
+
import type { TableModel } from './table-model.svelte';
|
|
3
|
+
import type { WithId } from './types';
|
|
4
|
+
type SelectionCallbacks<T> = {
|
|
5
|
+
selectionChanged?: (e: T[]) => void;
|
|
6
|
+
itemsSelected?: (e: T[]) => void;
|
|
7
|
+
itemsDeselected?: (e: T[]) => void;
|
|
8
|
+
};
|
|
9
|
+
export declare const cssWidth: <T extends WithId>(column: ResolvedColumn<T>) => string;
|
|
10
|
+
/** Shared presentation wiring for the table views: selection-event subscriptions + the debounced no-items placeholder. */
|
|
11
|
+
export declare const createTableView: <T extends WithId>(model: () => TableModel<T>, on: () => SelectionCallbacks<T> | undefined) => {
|
|
12
|
+
readonly showNoItemsPlaceholder: boolean;
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { untrack } from 'svelte';
|
|
2
|
+
export const cssWidth = (column) => (column.fixedCssWidth ? `width: ${column.fixedCssWidth};` : 'width: auto;');
|
|
3
|
+
/** Shared presentation wiring for the table views: selection-event subscriptions + the debounced no-items placeholder. */
|
|
4
|
+
export const createTableView = (model, on) => {
|
|
5
|
+
let showNoItemsPlaceholder = $state(false);
|
|
6
|
+
let timeout = 0;
|
|
7
|
+
$effect(() => untrack(() => {
|
|
8
|
+
const selection = model().selection;
|
|
9
|
+
const subscriptions = [
|
|
10
|
+
selection.subscribeOnChange((values) => on()?.selectionChanged?.(values)),
|
|
11
|
+
selection.subscribeOnAdd((values) => on()?.itemsSelected?.(values)),
|
|
12
|
+
selection.subscribeOnRemove((values) => on()?.itemsDeselected?.(values))
|
|
13
|
+
];
|
|
14
|
+
return () => subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
15
|
+
}));
|
|
16
|
+
$effect(() => {
|
|
17
|
+
if (model().items.length) {
|
|
18
|
+
clearTimeout(timeout);
|
|
19
|
+
showNoItemsPlaceholder = false;
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
timeout = window.setTimeout(() => {
|
|
23
|
+
showNoItemsPlaceholder = !model().items.length;
|
|
24
|
+
}, 700);
|
|
25
|
+
return () => clearTimeout(timeout);
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
get showNoItemsPlaceholder() {
|
|
29
|
+
return showNoItemsPlaceholder;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
};
|
package/dist/ui/table/types.d.ts
CHANGED
|
@@ -3,18 +3,13 @@ import type { BadgeVariant } from '../badge';
|
|
|
3
3
|
import type { ButtonSize, ButtonVariant } from '../button';
|
|
4
4
|
import { DynamicComponentModel } from '../dynamic-component';
|
|
5
5
|
import type { IconProp } from '../icon';
|
|
6
|
-
import type { SelectOption } from '../select';
|
|
7
6
|
import type { Snippet } from 'svelte';
|
|
8
|
-
import type { ISchema } from 'yup';
|
|
9
7
|
export type WithId = {
|
|
10
8
|
id: string;
|
|
11
9
|
};
|
|
12
|
-
export type IAnyTableColumn<T> =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export type IOneOfTableColumn<T, K extends keyof T> = ITableBadgeColumn<T> | ITableButtonColumn<T> | ITableByColumn<T> | ITableCheckboxColumn | ITableCustomColumn<T> | ITableIconColumn<T> | ITableImageColumn<T> | ITableMoveRowColumn | ITableSelectColumn<T, K> | ITableSnippetColumn<T> | ITableTextColumn<T> | ITableTextInputColumn<T>;
|
|
16
|
-
export type IEditorColumn<T> = ITableTextInputColumn<T> | ITableSelectColumn<T, keyof T>;
|
|
17
|
-
export type TableColumnType = 'actions' | 'badge' | 'button' | 'by' | 'checkbox' | 'custom' | 'icon' | 'image' | 'move-row' | 'select' | 'snippet' | 'text' | 'text-input';
|
|
10
|
+
export type IAnyTableColumn<T> = IOneOfTableColumn<T>;
|
|
11
|
+
export type IOneOfTableColumn<T> = ITableBadgeColumn<T> | ITableButtonColumn<T> | ITableByColumn<T> | ITableCheckboxColumn | ITableCustomColumn<T> | ITableIconColumn<T> | ITableImageColumn<T> | ITableMoveRowColumn | ITableSnippetColumn<T> | ITableTextColumn<T>;
|
|
12
|
+
export type TableColumnType = 'actions' | 'badge' | 'button' | 'by' | 'checkbox' | 'custom' | 'icon' | 'image' | 'move-row' | 'snippet' | 'text';
|
|
18
13
|
interface ITableColumnBase {
|
|
19
14
|
type: TableColumnType;
|
|
20
15
|
fixedCssWidth?: string;
|
|
@@ -45,7 +40,8 @@ export interface ITableBadgeColumn<T> extends ITableColumn<T> {
|
|
|
45
40
|
}
|
|
46
41
|
export interface ITableByColumn<T> extends ITableColumn<T> {
|
|
47
42
|
type: 'by';
|
|
48
|
-
|
|
43
|
+
/** The "when" — an ISO date string. */
|
|
44
|
+
valueFactory?: ((item: T) => string) | null;
|
|
49
45
|
byValueFactory?: ((item: T) => {
|
|
50
46
|
id: string;
|
|
51
47
|
name: string;
|
|
@@ -92,17 +88,6 @@ export interface ITableMoveRowColumn extends ITableColumnBase {
|
|
|
92
88
|
type: 'move-row';
|
|
93
89
|
disableFactory?: (() => boolean) | null;
|
|
94
90
|
}
|
|
95
|
-
export interface ITableSelectColumn<T, K extends keyof T> extends ITableColumn<T> {
|
|
96
|
-
id: K;
|
|
97
|
-
type: 'select';
|
|
98
|
-
valueFactory?: ((item: T) => T[K]) | null;
|
|
99
|
-
optionsFactory: (item: T) => SelectOption<T[K]>[];
|
|
100
|
-
placeholder?: string | null;
|
|
101
|
-
disabledFactory?: ((item: T) => boolean) | null;
|
|
102
|
-
visibilityFactory?: ((item: T) => boolean) | null;
|
|
103
|
-
clearable?: boolean;
|
|
104
|
-
onSelected: (item: T, value: T[K] | null) => void;
|
|
105
|
-
}
|
|
106
91
|
export interface ITableSnippetColumn<T> extends ITableColumn<T> {
|
|
107
92
|
type: 'snippet';
|
|
108
93
|
/** Render-prop snippet receiving the row item. Use for rich / custom cell composition without creating a separate cell component. */
|
|
@@ -114,14 +99,6 @@ export interface ITableTextColumn<T> extends ITableColumn<T> {
|
|
|
114
99
|
/** @default 1 */
|
|
115
100
|
maxLines?: number | 'single-line-no-trim' | null;
|
|
116
101
|
valueFactory?: ((item: T) => string) | null;
|
|
117
|
-
editorColumn?: IEditorColumn<T> | null;
|
|
118
|
-
}
|
|
119
|
-
export interface ITableTextInputColumn<T> extends ITableColumn<T> {
|
|
120
|
-
type: 'text-input';
|
|
121
|
-
inputType?: 'text' | 'number' | null;
|
|
122
|
-
validationSchema?: ISchema<unknown> | null;
|
|
123
|
-
onValidated?: ((item: T, error: string) => void) | null;
|
|
124
|
-
onInput?: ((item: T, value: string) => void) | null;
|
|
125
102
|
}
|
|
126
103
|
export type TableTextColumnFormat = 'text' | 'html' | 'money' | 'date' | 'date-time';
|
|
127
104
|
export type TableImageColumnFormat = 'circle' | 'square-contain' | 'square-cover';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script lang="ts">const { checked, size = 'md', disabled = false, layout = 'spread', label, sublabel, title, name, on } = $props();
|
|
1
|
+
<script lang="ts">const { checked, size = 'md', disabled = false, presentational = false, layout = 'spread', label, sublabel, title, name, on } = $props();
|
|
2
2
|
const hasLabel = $derived(label !== undefined || sublabel !== undefined);
|
|
3
3
|
const ariaLabel = $derived(typeof label === 'string' ? label : name);
|
|
4
4
|
const handleClick = (event) => {
|
|
@@ -12,19 +12,25 @@ export {};
|
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
14
|
{#snippet switchControl()}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
15
|
+
{#if presentational}
|
|
16
|
+
<span class="toggle toggle--{size}" class:toggle--on={checked} class:toggle--disabled={disabled} aria-hidden="true">
|
|
17
|
+
<span class="toggle__thumb"></span>
|
|
18
|
+
</span>
|
|
19
|
+
{:else}
|
|
20
|
+
<button
|
|
21
|
+
type="button"
|
|
22
|
+
class="toggle toggle--{size}"
|
|
23
|
+
class:toggle--on={checked}
|
|
24
|
+
class:toggle--disabled={disabled}
|
|
25
|
+
role="switch"
|
|
26
|
+
aria-checked={checked}
|
|
27
|
+
aria-label={ariaLabel}
|
|
28
|
+
title={hasLabel ? undefined : title}
|
|
29
|
+
disabled={disabled}
|
|
30
|
+
onclick={handleClick}>
|
|
31
|
+
<span class="toggle__thumb" aria-hidden="true"></span>
|
|
32
|
+
</button>
|
|
33
|
+
{/if}
|
|
28
34
|
{/snippet}
|
|
29
35
|
|
|
30
36
|
{#if hasLabel}
|
|
@@ -140,10 +146,10 @@ switch left + label right, intrinsic width).
|
|
|
140
146
|
}
|
|
141
147
|
|
|
142
148
|
.toggle {
|
|
143
|
-
--_toggle--track-width: var(--sc-kit--toggle--track-width, 2rem);
|
|
144
|
-
--_toggle--track-height: var(--sc-kit--toggle--track-height, 1.125rem);
|
|
145
|
-
--_toggle--thumb-size: var(--sc-kit--toggle--thumb-size, 0.875rem);
|
|
146
|
-
--_toggle--thumb-travel: var(--sc-kit--toggle--thumb-travel, 0.875rem);
|
|
149
|
+
--_toggle--track-width: var(--sc-kit--toggle--track-width, var(--_toggle--size-track-width, 2rem));
|
|
150
|
+
--_toggle--track-height: var(--sc-kit--toggle--track-height, var(--_toggle--size-track-height, 1.125rem));
|
|
151
|
+
--_toggle--thumb-size: var(--sc-kit--toggle--thumb-size, var(--_toggle--size-thumb-size, 0.875rem));
|
|
152
|
+
--_toggle--thumb-travel: var(--sc-kit--toggle--thumb-travel, var(--_toggle--size-thumb-travel, 0.875rem));
|
|
147
153
|
--_toggle--thumb-offset: var(--sc-kit--toggle--thumb-offset, 0.125rem);
|
|
148
154
|
--_toggle--thumb-translate: 0;
|
|
149
155
|
--_toggle--background: var(--sc-kit--toggle--background, var(--sc-kit--color--border--strong));
|
|
@@ -166,16 +172,16 @@ switch left + label right, intrinsic width).
|
|
|
166
172
|
outline-offset: 2px;
|
|
167
173
|
}
|
|
168
174
|
.toggle--sm {
|
|
169
|
-
--
|
|
170
|
-
--
|
|
171
|
-
--
|
|
172
|
-
--
|
|
175
|
+
--_toggle--size-track-width: 1.625rem;
|
|
176
|
+
--_toggle--size-track-height: 0.875rem;
|
|
177
|
+
--_toggle--size-thumb-size: 0.625rem;
|
|
178
|
+
--_toggle--size-thumb-travel: 0.75rem;
|
|
173
179
|
}
|
|
174
180
|
.toggle--md {
|
|
175
|
-
--
|
|
176
|
-
--
|
|
177
|
-
--
|
|
178
|
-
--
|
|
181
|
+
--_toggle--size-track-width: 2rem;
|
|
182
|
+
--_toggle--size-track-height: 1.125rem;
|
|
183
|
+
--_toggle--size-thumb-size: 0.875rem;
|
|
184
|
+
--_toggle--size-thumb-travel: 0.875rem;
|
|
179
185
|
}
|
|
180
186
|
.toggle--on {
|
|
181
187
|
--sc-kit--toggle--background: var(--sc-kit--toggle--background--on, var(--sc-kit--color--accent));
|
|
@@ -4,6 +4,8 @@ type Props = {
|
|
|
4
4
|
/** @default 'md' */
|
|
5
5
|
size?: 'sm' | 'md';
|
|
6
6
|
disabled?: boolean;
|
|
7
|
+
/** Render a non-interactive visual switch (a `<span>`, not a button) for embedding inside another interactive row that owns the click + semantics. @default false */
|
|
8
|
+
presentational?: boolean;
|
|
7
9
|
/** Label position relative to the switch. `spread` = label left, switch right (settings-row). `inline` = switch left, label right (compact). @default 'spread' */
|
|
8
10
|
layout?: 'spread' | 'inline';
|
|
9
11
|
/** Label: plain text or a snippet for rich content. */
|
|
@@ -10,7 +10,7 @@ import IconCheckmarkCircle from '@fluentui/svg-icons/icons/checkmark_circle_20_f
|
|
|
10
10
|
import IconChevronRight from '@fluentui/svg-icons/icons/chevron_right_20_regular.svg?raw';
|
|
11
11
|
import IconMoreVertical from '@fluentui/svg-icons/icons/more_vertical_20_regular.svg?raw';
|
|
12
12
|
import { slide } from 'svelte/transition';
|
|
13
|
-
let { node,
|
|
13
|
+
let { node, keyboard, hideExpandIcon = false, level = 0, showSelectedCheckmark } = $props();
|
|
14
14
|
let actionsOpened = $state(false);
|
|
15
15
|
let dbClickTimeout = undefined;
|
|
16
16
|
let dragExpandTimeout = undefined;
|
|
@@ -67,7 +67,6 @@ const handleDrop = (e) => {
|
|
|
67
67
|
};
|
|
68
68
|
const handleSelectNode = (e) => {
|
|
69
69
|
e.stopPropagation();
|
|
70
|
-
nav.setActive(node);
|
|
71
70
|
clearTimeout(dbClickTimeout);
|
|
72
71
|
if (node.expandOnDoubleClick) {
|
|
73
72
|
dbClickTimeout = window.setTimeout(() => {
|
|
@@ -80,7 +79,6 @@ const handleSelectNode = (e) => {
|
|
|
80
79
|
};
|
|
81
80
|
const handleExpandNode = (e) => {
|
|
82
81
|
e.stopPropagation();
|
|
83
|
-
nav.setActive(node);
|
|
84
82
|
if (node.expanded) {
|
|
85
83
|
node.collapse();
|
|
86
84
|
}
|
|
@@ -112,9 +110,7 @@ const handleMouseLeave = () => {
|
|
|
112
110
|
<div
|
|
113
111
|
class="tree-node"
|
|
114
112
|
style={`--_tree-node--level: ${level}`}
|
|
115
|
-
id={nav.itemId(node)}
|
|
116
113
|
role="treeitem"
|
|
117
|
-
tabindex="-1"
|
|
118
114
|
aria-level={level + 1}
|
|
119
115
|
aria-selected={node.selected}
|
|
120
116
|
aria-expanded={children.length ? node.expanded : undefined}>
|
|
@@ -122,7 +118,6 @@ const handleMouseLeave = () => {
|
|
|
122
118
|
<div
|
|
123
119
|
class="tree-node__leaf"
|
|
124
120
|
class:tree-node__leaf--active={node.selected}
|
|
125
|
-
class:tree-node__leaf--focused={nav.hasFocus && nav.activeId === node.id}
|
|
126
121
|
class:tree-node__leaf--draggable={node.dragConfig}
|
|
127
122
|
class:tree-node__leaf--expandable={children.length}
|
|
128
123
|
class:tree-node__leaf--drag-over={isDraggedOver}
|
|
@@ -150,8 +145,15 @@ const handleMouseLeave = () => {
|
|
|
150
145
|
</button>
|
|
151
146
|
{/if}
|
|
152
147
|
|
|
153
|
-
|
|
154
|
-
|
|
148
|
+
<div
|
|
149
|
+
class="tree-node__anchor"
|
|
150
|
+
id={keyboard.anchorId(node)}
|
|
151
|
+
role="button"
|
|
152
|
+
tabindex={keyboard.currentId === node.id ? 0 : -1}
|
|
153
|
+
onclick={handleSelectNode}
|
|
154
|
+
ondblclick={handleExpandOnDoubleClick}
|
|
155
|
+
onfocusin={() => keyboard.setFocused(node.id)}
|
|
156
|
+
onkeydown={(e) => keyboard.handleKeydown(node, e)}>
|
|
155
157
|
{#if !node.hideIcon}
|
|
156
158
|
<div class="tree-node__icon" class:tree-node__icon--active={node.selected}>
|
|
157
159
|
{#if node.icon}
|
|
@@ -196,7 +198,7 @@ const handleMouseLeave = () => {
|
|
|
196
198
|
{#if node.expanded && children.length}
|
|
197
199
|
<div transition:slide={{ duration: transitionDuration.base }} class="tree-node__children" role="group">
|
|
198
200
|
{#each children as child (child.id)}
|
|
199
|
-
<Self node={child}
|
|
201
|
+
<Self node={child} keyboard={keyboard} level={level + 1} hideExpandIcon={hideChildExpandIcon} showSelectedCheckmark={showSelectedCheckmark} />
|
|
200
202
|
{/each}
|
|
201
203
|
</div>
|
|
202
204
|
{/if}
|
|
@@ -235,7 +237,10 @@ const handleMouseLeave = () => {
|
|
|
235
237
|
color: var(--sc-kit--color--text--primary);
|
|
236
238
|
background: var(--sc-kit--color--bg--active);
|
|
237
239
|
}
|
|
238
|
-
.tree-node__leaf
|
|
240
|
+
.tree-node__leaf:focus-within {
|
|
241
|
+
--_tree-node--action-opacity: 1;
|
|
242
|
+
}
|
|
243
|
+
.tree-node__leaf:has(.tree-node__anchor:focus-visible) {
|
|
239
244
|
outline: 2px solid var(--sc-kit--color--border--focus);
|
|
240
245
|
outline-offset: -2px;
|
|
241
246
|
}
|
|
@@ -280,6 +285,7 @@ const handleMouseLeave = () => {
|
|
|
280
285
|
gap: var(--sc-kit--space--2);
|
|
281
286
|
min-width: 0;
|
|
282
287
|
padding: var(--_tree-node--padding-block) 0;
|
|
288
|
+
outline: none;
|
|
283
289
|
}
|
|
284
290
|
.tree-node__icon {
|
|
285
291
|
--sc-kit--icon--size: var(--_tree-node--icon-size);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TreeKeyboard } from './tree-keyboard.svelte';
|
|
2
2
|
import { type TreeNode } from './tree-node.svelte';
|
|
3
3
|
type Props = {
|
|
4
4
|
node: TreeNode;
|
|
5
|
-
|
|
5
|
+
keyboard: TreeKeyboard;
|
|
6
6
|
hideExpandIcon?: boolean;
|
|
7
7
|
level?: number;
|
|
8
8
|
showSelectedCheckmark?: boolean;
|