@streamscloud/kit 0.76.5 → 0.78.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/core/utils/color-helper.d.ts +10 -0
- package/dist/core/utils/color-helper.js +25 -1
- package/dist/ui/form-field/cmp.form-field-validatable.svelte +3 -3
- package/dist/ui/form-field/cmp.form-field-validatable.svelte.d.ts +4 -4
- package/dist/ui/table/cmp.table-draggable.svelte +56 -304
- package/dist/ui/table/cmp.table-draggable.svelte.d.ts +30 -19
- package/dist/ui/table/cmp.table.svelte +23 -264
- package/dist/ui/table/cmp.table.svelte.d.ts +32 -18
- package/dist/ui/table/table-cells/table-checkbox-cell.svelte +0 -1
- package/dist/ui/table/table-cells/table-move-row-cell.svelte +0 -2
- package/dist/ui/table/table-cells/table-text-cell.svelte +0 -1
- package/dist/ui/table/table-column-models.svelte.d.ts +5 -0
- package/dist/ui/table/table-column-models.svelte.js +6 -0
- package/dist/ui/table/table-core.svelte +407 -0
- package/dist/ui/table/table-core.svelte.d.ts +88 -0
- package/dist/ui/table/table-headers/table-header-sortable.svelte +1 -4
- package/dist/ui/table/table-headers/table-header.svelte +1 -1
- package/dist/ui/table/table-localization.d.ts +1 -0
- package/dist/ui/table/table-localization.js +7 -0
- package/dist/ui/table/table-model.svelte.js +9 -1
- package/dist/ui/table/types.d.ts +22 -1
- package/dist/ui/validatable/cmp.validatable.svelte +3 -4
- package/dist/ui/validatable/cmp.validatable.svelte.d.ts +6 -6
- package/dist/ui/validatable/cmp.validation-error.svelte +4 -4
- package/dist/ui/validatable/cmp.validation-error.svelte.d.ts +7 -6
- package/dist/ui/validatable/field-frame.svelte +25 -15
- package/dist/ui/validatable/field-frame.svelte.d.ts +8 -8
- package/dist/ui/validatable/index.d.ts +1 -0
- package/dist/ui/validatable/types.d.ts +7 -0
- package/dist/ui/validatable/types.js +1 -0
- package/package.json +1 -1
- package/dist/ui/table/_table-styles.scss +0 -158
- package/dist/ui/table/table-view.svelte.d.ts +0 -15
- package/dist/ui/table/table-view.svelte.js +0 -47
|
@@ -14,4 +14,14 @@ export declare class ColorHelper {
|
|
|
14
14
|
* Check whether a color value fully hides what is behind it (valid, 100% alpha).
|
|
15
15
|
*/
|
|
16
16
|
static isOpaque(value: string | null | undefined): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Mix `color` towards `target` by `amount` (`0` = `color`, `1` = `target`) through the LAB color space — the same result as colord's `mix`.
|
|
19
|
+
* Returns a hex in the `normalizeHex` contract, or `''` when either input is invalid.
|
|
20
|
+
*/
|
|
21
|
+
static mix(color: string | null | undefined, target: string | null | undefined, amount: number): string;
|
|
22
|
+
/**
|
|
23
|
+
* Strict hex check: `#RGB`, `#RRGGBB` or `#RRGGBBAA`, case-insensitive. Unlike `normalizeHex`, colour names and functional notations (`red`, `rgb(…)`)
|
|
24
|
+
* are rejected.
|
|
25
|
+
*/
|
|
26
|
+
static isHex(value: string | null | undefined): boolean;
|
|
17
27
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { colord, extend } from 'colord';
|
|
2
|
+
import mixPlugin from 'colord/plugins/mix';
|
|
2
3
|
import namesPlugin from 'colord/plugins/names';
|
|
3
|
-
extend([namesPlugin]);
|
|
4
|
+
extend([namesPlugin, mixPlugin]);
|
|
5
|
+
const HEX_PATTERN = /^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
4
6
|
export class ColorHelper {
|
|
5
7
|
/**
|
|
6
8
|
* Normalize a color value to a clean hex string.
|
|
@@ -43,4 +45,26 @@ export class ColorHelper {
|
|
|
43
45
|
const parsed = colord(value);
|
|
44
46
|
return parsed.isValid() && parsed.alpha() === 1;
|
|
45
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Mix `color` towards `target` by `amount` (`0` = `color`, `1` = `target`) through the LAB color space — the same result as colord's `mix`.
|
|
50
|
+
* Returns a hex in the `normalizeHex` contract, or `''` when either input is invalid.
|
|
51
|
+
*/
|
|
52
|
+
static mix(color, target, amount) {
|
|
53
|
+
if (!color || !target || !Number.isFinite(amount)) {
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
const from = colord(color);
|
|
57
|
+
const to = colord(target);
|
|
58
|
+
if (!from.isValid() || !to.isValid()) {
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
return ColorHelper.normalizeHex(from.mix(to, amount).toHex());
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Strict hex check: `#RGB`, `#RRGGBB` or `#RRGGBBAA`, case-insensitive. Unlike `normalizeHex`, colour names and functional notations (`red`, `rgb(…)`)
|
|
65
|
+
* are rejected.
|
|
66
|
+
*/
|
|
67
|
+
static isHex(value) {
|
|
68
|
+
return !!value && HEX_PATTERN.test(value);
|
|
69
|
+
}
|
|
46
70
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends Record<string, unknown>, K extends keyof T & string">import { Validatable } from '../validatable';
|
|
2
2
|
import { default as FormField } from './cmp.form-field.svelte';
|
|
3
|
-
let { handler, name, label, hint, required = false, validateOn, debounceMs, disableTouchedTracking,
|
|
3
|
+
let { handler, name, label, hint, required = false, validateOn, debounceMs, disableTouchedTracking, errorPlacement, on, children } = $props();
|
|
4
4
|
</script>
|
|
5
5
|
|
|
6
6
|
<FormField label={label} hint={hint} required={required}>
|
|
@@ -10,7 +10,7 @@ let { handler, name, label, hint, required = false, validateOn, debounceMs, disa
|
|
|
10
10
|
validateOn={validateOn}
|
|
11
11
|
debounceMs={debounceMs}
|
|
12
12
|
disableTouchedTracking={disableTouchedTracking}
|
|
13
|
-
|
|
13
|
+
errorPlacement={errorPlacement}
|
|
14
14
|
on={on}
|
|
15
15
|
children={children} />
|
|
16
16
|
</FormField>
|
|
@@ -41,5 +41,5 @@ Identical visual output to:
|
|
|
41
41
|
</FormField>
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Both `FormField`'s label/required and `Validatable`'s
|
|
44
|
+
Both `FormField`'s label/required and `Validatable`'s error slot (`errorPlacement`) apply unchanged — this cmp adds no styling, just collapses the wiring.
|
|
45
45
|
-->
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FormValidationHandler } from '../../core/validation';
|
|
2
|
-
import { type FieldBinding, type ValidateOnEvent } from '../validatable';
|
|
2
|
+
import { type ErrorPlacement, type FieldBinding, type ValidateOnEvent } from '../validatable';
|
|
3
3
|
import type { Snippet } from 'svelte';
|
|
4
4
|
declare function $$render<T extends Record<string, unknown>, K extends keyof T & string>(): {
|
|
5
5
|
props: {
|
|
@@ -19,8 +19,8 @@ declare function $$render<T extends Record<string, unknown>, K extends keyof T &
|
|
|
19
19
|
debounceMs?: number;
|
|
20
20
|
/** Show errors before the field has been touched. Forwarded to `<Validatable>`. @default false */
|
|
21
21
|
disableTouchedTracking?: boolean;
|
|
22
|
-
/**
|
|
23
|
-
|
|
22
|
+
/** Where the error message sits. Forwarded to `<Validatable>`. @default 'overlay' */
|
|
23
|
+
errorPlacement?: ErrorPlacement;
|
|
24
24
|
/** Extra consumer callbacks. Forwarded to `<Validatable>`. */
|
|
25
25
|
on?: {
|
|
26
26
|
input?: (value: T[K]) => void;
|
|
@@ -74,7 +74,7 @@ interface $$IsomorphicComponent {
|
|
|
74
74
|
* </FormField>
|
|
75
75
|
* ```
|
|
76
76
|
*
|
|
77
|
-
* Both `FormField`'s label/required and `Validatable`'s
|
|
77
|
+
* Both `FormField`'s label/required and `Validatable`'s error slot (`errorPlacement`) apply unchanged — this cmp adds no styling, just collapses the wiring.
|
|
78
78
|
*/
|
|
79
79
|
declare const Cmp: $$IsomorphicComponent;
|
|
80
80
|
type Cmp<T extends Record<string, unknown>, K extends keyof T & string> = InstanceType<typeof Cmp<T, K>>;
|
|
@@ -1,334 +1,86 @@
|
|
|
1
|
-
<script lang="ts" generics="T extends {id: string}">import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import { TableLocalization } from './table-localization';
|
|
6
|
-
import { columnWidthStyle, createTableView } from './table-view.svelte';
|
|
7
|
-
import IconReorderDotsHorizontal from '@fluentui/svg-icons/icons/re_order_dots_horizontal_20_regular.svg?raw';
|
|
8
|
-
import { flip } from 'svelte/animate';
|
|
9
|
-
import { dndzone } from 'svelte-dnd-action';
|
|
10
|
-
let { model, showAlternativeView = false, noItemsPlaceholderEnabled, noItemsPlaceholderDelay, on, alternativeView, customNoItemsPlaceholder } = $props();
|
|
11
|
-
const localization = new TableLocalization();
|
|
12
|
-
const view = createTableView(() => model, () => on, () => noItemsPlaceholderEnabled, () => noItemsPlaceholderDelay);
|
|
13
|
-
const flipDurationMs = 200;
|
|
14
|
-
let tableRef = $state.raw(null);
|
|
1
|
+
<script lang="ts" generics="T extends {id: string}">import { TABLE_ROW_FLIP_DURATION_MS, default as TableCore, styleTableRowClone } from './table-core.svelte';
|
|
2
|
+
import { fromAction } from 'svelte/attachments';
|
|
3
|
+
import { dragHandle, dragHandleZone } from 'svelte-dnd-action';
|
|
4
|
+
let { model, on, ...shared } = $props();
|
|
15
5
|
let dndItems = $state.raw(null);
|
|
16
|
-
const
|
|
17
|
-
const
|
|
6
|
+
const orderedItems = $derived(dndItems ?? model.items);
|
|
7
|
+
const rows = $derived(orderedItems.map((item, index) => ({ kind: 'item', key: item.id, item, index })));
|
|
8
|
+
let body = null;
|
|
9
|
+
const isSameOrder = (next) => next.length === model.items.length && next.every((item, index) => item.id === model.items[index].id);
|
|
18
10
|
const handleConsider = (e) => {
|
|
19
11
|
dndItems = e.detail.items;
|
|
20
12
|
};
|
|
21
13
|
const handleFinalize = (e) => {
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
const next = e.detail.items;
|
|
15
|
+
if (!isSameOrder(next)) {
|
|
16
|
+
model.items = next;
|
|
17
|
+
on?.itemsReordered?.(next);
|
|
18
|
+
}
|
|
24
19
|
dndItems = null;
|
|
25
20
|
};
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
30
|
-
const transformDraggedElement = (draggedRow) => {
|
|
31
|
-
if (!draggedRow) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
const referenceRow = tableRef.querySelector('tbody tr:not([data-is-dnd-shadow-item-internal])') ?? tableRef.querySelector('tbody tr');
|
|
35
|
-
const referenceColumns = referenceRow?.querySelectorAll('td') ?? [];
|
|
36
|
-
const draggedColumns = draggedRow.querySelectorAll('td');
|
|
37
|
-
if (!referenceRow || referenceColumns.length !== draggedColumns.length) {
|
|
38
|
-
console.error('DraggableTable: dragged row column count does not match the reference row');
|
|
39
|
-
return;
|
|
21
|
+
const transformDraggedElement = (clone, _data, rowIndex) => {
|
|
22
|
+
if (clone && body && rowIndex !== undefined) {
|
|
23
|
+
styleTableRowClone(clone, body, rowIndex);
|
|
40
24
|
}
|
|
41
|
-
for (let i = 0, length = referenceColumns.length; i < length; i++) {
|
|
42
|
-
draggedColumns[i].style.width = `${referenceColumns[i].clientWidth}px`;
|
|
43
|
-
draggedColumns[i].style.height = `${referenceColumns[i].clientHeight}px`;
|
|
44
|
-
}
|
|
45
|
-
// Clone is reparented to <body>, losing the .table-container --_table--* vars; cells collapse without this.
|
|
46
|
-
const cellStyle = window.getComputedStyle(referenceColumns[0]);
|
|
47
|
-
draggedRow.style.setProperty('--_table--cell--font-size', cellStyle.fontSize);
|
|
48
|
-
draggedRow.style.setProperty('--_table--cell--horizontal-padding', cellStyle.paddingInlineStart);
|
|
49
|
-
// Without a value the var resolves to currentColor (dark) on the reparented clone — drop the row border while dragging.
|
|
50
|
-
draggedRow.style.setProperty('--_table--border-color', 'transparent');
|
|
51
25
|
};
|
|
26
|
+
const reorderZone = fromAction(dragHandleZone, () => ({
|
|
27
|
+
items: orderedItems,
|
|
28
|
+
dropFromOthersDisabled: true,
|
|
29
|
+
flipDurationMs: TABLE_ROW_FLIP_DURATION_MS,
|
|
30
|
+
dropTargetStyle: {},
|
|
31
|
+
transformDraggedElement,
|
|
32
|
+
type: 'table'
|
|
33
|
+
}));
|
|
34
|
+
const attachment = (node) => {
|
|
35
|
+
body = node;
|
|
36
|
+
node.addEventListener('consider', handleConsider);
|
|
37
|
+
node.addEventListener('finalize', handleFinalize);
|
|
38
|
+
reorderZone(node);
|
|
39
|
+
return () => {
|
|
40
|
+
node.removeEventListener('consider', handleConsider);
|
|
41
|
+
node.removeEventListener('finalize', handleFinalize);
|
|
42
|
+
body = null;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
const reorder = { attachment, handleAttachment: fromAction(dragHandle) };
|
|
52
46
|
</script>
|
|
53
47
|
|
|
54
|
-
{
|
|
55
|
-
{#if customNoItemsPlaceholder}
|
|
56
|
-
{@render customNoItemsPlaceholder()}
|
|
57
|
-
{:else}
|
|
58
|
-
<EmptyState graphic="zero-content" title={localization.noItemsFoundTitle} description={localization.noItemsFoundBody} />
|
|
59
|
-
{/if}
|
|
60
|
-
{/snippet}
|
|
61
|
-
|
|
62
|
-
<div
|
|
63
|
-
class="table-container table-container--{model.styles?.size ?? 'md'} table-container--{model.styles?.variant ?? 'plain'}"
|
|
64
|
-
class:table-container--zebra={model.styles?.zebra === true}>
|
|
65
|
-
{#if alternativeView && showAlternativeView}
|
|
66
|
-
{#if view.showNoItemsPlaceholder}
|
|
67
|
-
<div class="alternative-view__placeholder">{@render noItemsContent()}</div>
|
|
68
|
-
{:else}
|
|
69
|
-
{@render alternativeView()}
|
|
70
|
-
{/if}
|
|
71
|
-
{:else}
|
|
72
|
-
<table class="table" class:table--sticky-header={model.styles?.stickyHeader === true} bind:this={tableRef}>
|
|
73
|
-
<thead class="table__head">
|
|
74
|
-
<tr>
|
|
75
|
-
<th class="table__th table__drag-handle"> </th>
|
|
76
|
-
{#each model.columns as column (column)}
|
|
77
|
-
<TableHideableCell column={column}>
|
|
78
|
-
<th class="table__th" class:table__th--centered={column.centered} style={columnWidthStyle(column)} title={column.title}>
|
|
79
|
-
<DynamicComponent model={column.headerView} />
|
|
80
|
-
</th>
|
|
81
|
-
</TableHideableCell>
|
|
82
|
-
{/each}
|
|
83
|
-
</tr>
|
|
84
|
-
</thead>
|
|
85
|
-
<tbody
|
|
86
|
-
use:dndzone={{
|
|
87
|
-
items: rows,
|
|
88
|
-
dropFromOthersDisabled: true,
|
|
89
|
-
flipDurationMs,
|
|
90
|
-
dropTargetStyle: {},
|
|
91
|
-
transformDraggedElement,
|
|
92
|
-
type: 'table'
|
|
93
|
-
}}
|
|
94
|
-
onconsider={handleConsider}
|
|
95
|
-
onfinalize={handleFinalize}>
|
|
96
|
-
{#if view.showNoItemsPlaceholder}
|
|
97
|
-
<tr class="table__tr table__tr--placeholder">
|
|
98
|
-
<td colspan={visibleColspan}>
|
|
99
|
-
<div class="table__placeholder">{@render noItemsContent()}</div>
|
|
100
|
-
</td>
|
|
101
|
-
</tr>
|
|
102
|
-
{:else}
|
|
103
|
-
{#each rows as item, itemIndex (item)}
|
|
104
|
-
{@const isSelected = model.selection.has(item.id)}
|
|
105
|
-
{@const isHighlighted = model.highlightedItemIds.includes(item.id)}
|
|
106
|
-
{@const flushBottom = model.styles?.variant === 'card' && itemIndex === rows.length - 1}
|
|
107
|
-
{@const zebra = model.styles?.zebra === true && itemIndex % 2 === 1 && !isSelected && !isHighlighted}
|
|
108
|
-
<tr
|
|
109
|
-
animate:flip={{ duration: flipDurationMs }}
|
|
110
|
-
class="table__tr"
|
|
111
|
-
id={item.id}
|
|
112
|
-
class:table__tr--selected={isSelected}
|
|
113
|
-
class:table__tr--highlighted={isHighlighted}
|
|
114
|
-
class:table__tr--zebra={zebra}>
|
|
115
|
-
<td
|
|
116
|
-
class="table__td table__drag-handle table__drag-handle--dragging"
|
|
117
|
-
class:table__td--flush={flushBottom}
|
|
118
|
-
onmousedown={startDrag}
|
|
119
|
-
ontouchstart={startDrag}>
|
|
120
|
-
<Icon src={IconReorderDotsHorizontal} />
|
|
121
|
-
</td>
|
|
122
|
-
{#each model.columns as column (column)}
|
|
123
|
-
<TableHideableCell column={column}>
|
|
124
|
-
<td
|
|
125
|
-
class="table__td"
|
|
126
|
-
class:table__td--centered={column.centered}
|
|
127
|
-
class:table__td--clickable={!!column.onClick}
|
|
128
|
-
class:table__td--flush={flushBottom}
|
|
129
|
-
style={columnWidthStyle(column)}
|
|
130
|
-
onclick={() => column.onClick && column.onClick(item)}>
|
|
131
|
-
<TableCell model={model} item={item} column={column} itemIndex={itemIndex} on={{ itemsReordered: on?.itemsReordered }} />
|
|
132
|
-
</td>
|
|
133
|
-
</TableHideableCell>
|
|
134
|
-
{/each}
|
|
135
|
-
</tr>
|
|
136
|
-
{/each}
|
|
137
|
-
{/if}
|
|
138
|
-
</tbody>
|
|
139
|
-
</table>
|
|
140
|
-
{/if}
|
|
141
|
-
</div>
|
|
48
|
+
<TableCore {...shared} model={model} on={on} rows={rows} reorder={reorder} />
|
|
142
49
|
|
|
143
50
|
<!--
|
|
144
51
|
@component
|
|
145
52
|
Data table with drag-and-drop row reordering, plus everything `Table` offers (sorting, selection, column
|
|
146
|
-
visibility, group actions). A leading drag-handle column is rendered
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
### TableStyles (via `model.styles`)
|
|
150
|
-
| Field | Type | Effect |
|
|
151
|
-
|---|---|---|
|
|
152
|
-
| `size` | `'sm' \| 'md'` | Row height + cell padding + font-size preset (default `'md'`) |
|
|
153
|
-
| `variant` | `'plain' \| 'card'` | `'card'` wraps the table in a bordered rounded panel (default `'plain'`) |
|
|
154
|
-
| `zebra` | `boolean` | Alternates row backgrounds with `--sc-kit--color--bg--field-alt` |
|
|
155
|
-
| `stickyHeader` | `boolean` | Sticks `thead` to the scrolling ancestor |
|
|
156
|
-
| `actionsPopoverTopDirection` | `boolean` | Forces the per-row actions popover above instead of below |
|
|
53
|
+
visibility, group actions). A leading drag-handle column is rendered and a row is dragged by its handle only;
|
|
54
|
+
a drop that changes the order fires `on.itemsReordered` and preserves the current selection, a drop back in place
|
|
55
|
+
fires nothing. For non-reorderable tables use `Table` (it ships no dnd code).
|
|
157
56
|
|
|
158
57
|
### CSS Custom Properties
|
|
159
58
|
| Property | Description | Default |
|
|
160
59
|
|---|---|---|
|
|
161
|
-
| `--sc-kit--table--row--height` | Row height | per size (
|
|
162
|
-
| `--sc-kit--table--cell--
|
|
60
|
+
| `--sc-kit--table--row--height` | Row height | per size (36 / 44 px) |
|
|
61
|
+
| `--sc-kit--table--cell--padding-inline` | Cell inline padding | per size (`--space--3` / `--space--4`) |
|
|
163
62
|
| `--sc-kit--table--cell--font-size` | Cell font size | per size (`--font-size--sm` / `--md`) |
|
|
164
|
-
| `--sc-kit--table--
|
|
63
|
+
| `--sc-kit--table--cell--padding-block` | Cell block padding | `0` |
|
|
64
|
+
| `--sc-kit--table--cell--vertical-align` | Cell content alignment — `top` keeps inputs aligned when one cell grows | `middle` |
|
|
65
|
+
| `--sc-kit--table--head--height` | Header row height | per size (32 / 40 px) |
|
|
66
|
+
| `--sc-kit--table--head--background-color` | Header background | `--sc-kit--color--bg--field-alt`; with a `toolbar`, the card / panel background |
|
|
67
|
+
| `--sc-kit--table--toolbar--background-color` | Toolbar band background | `--sc-kit--color--bg--field-alt` |
|
|
68
|
+
| `--sc-kit--table--toolbar--padding-block` | Toolbar band block padding — `0` hands the band to the toolbar content | `--sc-kit--space--3` |
|
|
69
|
+
| `--sc-kit--table--toolbar--padding-inline` | Toolbar band inline padding | the cell inline padding |
|
|
165
70
|
| `--sc-kit--table--head--color` | Header text color | `--sc-kit--color--text--secondary` |
|
|
71
|
+
| `--sc-kit--table--head--font-size` | Header font size | `--sc-kit--font-size--sm` |
|
|
72
|
+
| `--sc-kit--table--head--font-weight` | Header font weight | `--sc-kit--font-weight--semibold` |
|
|
73
|
+
| `--sc-kit--table--head--letter-spacing` | Header letter spacing | `normal` |
|
|
74
|
+
| `--sc-kit--table--head--text-transform` | Header text transform | `none` |
|
|
166
75
|
| `--sc-kit--table--border-color` | Border color between rows | `--sc-kit--color--border` |
|
|
167
76
|
| `--sc-kit--table--row--color` | Row background | `transparent` |
|
|
168
77
|
| `--sc-kit--table--row--alternative-color` | Hover / highlighted row background | `--sc-kit--color--bg--hover` |
|
|
169
78
|
| `--sc-kit--table--zebra--color` | Zebra-row background (when `zebra` on) | `light-dark(#fcfcfd, #232323)` |
|
|
79
|
+
| `--sc-kit--table--selected--color` | Selected row background | `--sc-kit--color--accent--softer` |
|
|
80
|
+
| `--sc-kit--table--selected--color--hover` | Selected row background on hover | `--sc-kit--color--accent--soft` |
|
|
170
81
|
| `--sc-kit--table--card--background` | Card variant background | `--sc-kit--color--bg--panel` |
|
|
171
82
|
| `--sc-kit--table--card--border-color` | Card variant border | `--sc-kit--color--border` |
|
|
172
83
|
| `--sc-kit--table--card--border-radius` | Card variant radius | `--sc-kit--radius--lg` |
|
|
173
84
|
| `--sc-kit--table--card--padding-bottom` | Card variant bottom padding | `--sc-kit--space--4` |
|
|
85
|
+
| `--sc-kit--table--min-width` | Table floor — past it the columns scroll horizontally inside the chrome, the toolbar stays. The column-floor substitute under `layout: 'fixed'` | `auto` |
|
|
174
86
|
-->
|
|
175
|
-
|
|
176
|
-
<style>.alternative-view__placeholder {
|
|
177
|
-
width: 100%;
|
|
178
|
-
display: flex;
|
|
179
|
-
align-items: center;
|
|
180
|
-
justify-content: center;
|
|
181
|
-
font-size: 80%;
|
|
182
|
-
user-select: none;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.table-container {
|
|
186
|
-
--_table--row--height: var(--sc-kit--table--row--height, var(--_table--size-row-height));
|
|
187
|
-
--_table--cell--font-size: var(--sc-kit--table--cell--font-size, var(--_table--size-cell-font-size));
|
|
188
|
-
--_table--cell--horizontal-padding: var(--sc-kit--table--cell--horizontal-padding, var(--_table--size-cell-padding));
|
|
189
|
-
--_table--head--height: var(--sc-kit--table--head--height, var(--_table--size-head-height, var(--_table--row--height)));
|
|
190
|
-
--_table--head--background-color: var(--sc-kit--table--head--background-color, var(--sc-kit--color--bg--field-alt));
|
|
191
|
-
--_table--head--color: var(--sc-kit--table--head--color, var(--sc-kit--color--text--secondary));
|
|
192
|
-
--_table--border-color: var(--sc-kit--table--border-color, var(--sc-kit--color--border));
|
|
193
|
-
--_table--row--color: var(--sc-kit--table--row--color, transparent);
|
|
194
|
-
--_table--row--alternative-color: var(--sc-kit--table--row--alternative-color, var(--sc-kit--color--bg--hover));
|
|
195
|
-
--_table--zebra--color: var(--sc-kit--table--zebra--color, light-dark(#fcfcfd, #232323));
|
|
196
|
-
--_table--selected--color: var(--sc-kit--table--selected--color, var(--sc-kit--color--accent--softer));
|
|
197
|
-
--_table--selected--color-hover: var(--sc-kit--table--selected--color--hover, var(--sc-kit--color--accent--soft));
|
|
198
|
-
--_table--card--background: var(--sc-kit--table--card--background, var(--sc-kit--color--bg--panel));
|
|
199
|
-
--_table--card--border-color: var(--sc-kit--table--card--border-color, var(--sc-kit--color--border));
|
|
200
|
-
--_table--card--border-radius: var(--sc-kit--table--card--border-radius, var(--sc-kit--radius--lg));
|
|
201
|
-
--_table--card--padding-bottom: var(--sc-kit--table--card--padding-bottom, var(--sc-kit--space--4));
|
|
202
|
-
display: flex;
|
|
203
|
-
overflow-x: auto;
|
|
204
|
-
height: 100%;
|
|
205
|
-
--_cross-browser-scrollbar--thumb-color: var(--scrollbar--thumb-color, light-dark(#d1d5db, #4b5563));
|
|
206
|
-
--_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
|
|
207
|
-
}
|
|
208
|
-
.table-container::-webkit-scrollbar {
|
|
209
|
-
width: 6px;
|
|
210
|
-
height: 6px;
|
|
211
|
-
}
|
|
212
|
-
.table-container::-webkit-scrollbar-track {
|
|
213
|
-
background: var(--_cross-browser-scrollbar--track-color);
|
|
214
|
-
border-radius: 100vw;
|
|
215
|
-
}
|
|
216
|
-
.table-container::-webkit-scrollbar-thumb {
|
|
217
|
-
background: var(--_cross-browser-scrollbar--thumb-color);
|
|
218
|
-
border-radius: 100vw;
|
|
219
|
-
}
|
|
220
|
-
@supports (scrollbar-color: transparent transparent) {
|
|
221
|
-
.table-container {
|
|
222
|
-
scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
|
|
223
|
-
scrollbar-width: thin;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
.table-container--md {
|
|
227
|
-
--_table--size-row-height: 2.75rem;
|
|
228
|
-
--_table--size-head-height: 2.5rem;
|
|
229
|
-
--_table--size-cell-font-size: var(--sc-kit--font-size--md);
|
|
230
|
-
--_table--size-cell-padding: var(--sc-kit--space--4);
|
|
231
|
-
}
|
|
232
|
-
.table-container--sm {
|
|
233
|
-
--_table--size-row-height: 2.25rem;
|
|
234
|
-
--_table--size-head-height: 2rem;
|
|
235
|
-
--_table--size-cell-font-size: var(--sc-kit--font-size--sm);
|
|
236
|
-
--_table--size-cell-padding: var(--sc-kit--space--3);
|
|
237
|
-
}
|
|
238
|
-
.table-container--card {
|
|
239
|
-
background: var(--_table--card--background);
|
|
240
|
-
border: 1px solid var(--_table--card--border-color);
|
|
241
|
-
border-radius: var(--_table--card--border-radius);
|
|
242
|
-
padding-bottom: var(--_table--card--padding-bottom);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
.table {
|
|
246
|
-
width: 100%;
|
|
247
|
-
table-layout: auto;
|
|
248
|
-
height: fit-content;
|
|
249
|
-
border-collapse: separate;
|
|
250
|
-
border-spacing: 0;
|
|
251
|
-
}
|
|
252
|
-
.table__head {
|
|
253
|
-
height: var(--_table--head--height);
|
|
254
|
-
max-height: var(--_table--head--height);
|
|
255
|
-
background: var(--_table--head--background-color);
|
|
256
|
-
color: var(--_table--head--color);
|
|
257
|
-
font-size: var(--sc-kit--table--head--font-size, var(--sc-kit--font-size--sm));
|
|
258
|
-
font-weight: var(--sc-kit--font-weight--semibold);
|
|
259
|
-
}
|
|
260
|
-
.table__th {
|
|
261
|
-
padding: 0 var(--_table--cell--horizontal-padding);
|
|
262
|
-
text-align: left;
|
|
263
|
-
vertical-align: middle;
|
|
264
|
-
border-bottom: 1px solid var(--_table--border-color);
|
|
265
|
-
-webkit-user-drag: none;
|
|
266
|
-
user-select: none;
|
|
267
|
-
}
|
|
268
|
-
.table__th :global([contenteditable]) {
|
|
269
|
-
user-select: text;
|
|
270
|
-
}
|
|
271
|
-
.table__th--centered {
|
|
272
|
-
text-align: center;
|
|
273
|
-
--_table-header--justify-content: center;
|
|
274
|
-
}
|
|
275
|
-
.table__tr {
|
|
276
|
-
height: var(--_table--row--height);
|
|
277
|
-
max-height: var(--_table--row--height);
|
|
278
|
-
background: var(--_table--row--color);
|
|
279
|
-
}
|
|
280
|
-
.table__tr--zebra {
|
|
281
|
-
background: var(--_table--zebra--color);
|
|
282
|
-
}
|
|
283
|
-
.table__tr:hover, .table__tr--highlighted {
|
|
284
|
-
background: var(--_table--row--alternative-color);
|
|
285
|
-
--_table--move-row-cell-opacity: 1;
|
|
286
|
-
}
|
|
287
|
-
.table__tr--selected {
|
|
288
|
-
background: var(--_table--selected--color);
|
|
289
|
-
}
|
|
290
|
-
.table__tr--selected:hover {
|
|
291
|
-
background: var(--_table--selected--color-hover);
|
|
292
|
-
}
|
|
293
|
-
.table__tr--placeholder {
|
|
294
|
-
background: var(--_table--row--color) !important;
|
|
295
|
-
}
|
|
296
|
-
.table__td {
|
|
297
|
-
padding: 0 var(--_table--cell--horizontal-padding);
|
|
298
|
-
border-bottom: 1px solid var(--_table--border-color);
|
|
299
|
-
font-size: var(--_table--cell--font-size);
|
|
300
|
-
color: var(--sc-kit--color--text--primary);
|
|
301
|
-
vertical-align: middle;
|
|
302
|
-
}
|
|
303
|
-
.table__td--centered {
|
|
304
|
-
text-align: center;
|
|
305
|
-
}
|
|
306
|
-
.table__td--clickable {
|
|
307
|
-
cursor: pointer;
|
|
308
|
-
}
|
|
309
|
-
.table__td--flush {
|
|
310
|
-
border-bottom: none;
|
|
311
|
-
}
|
|
312
|
-
.table__placeholder {
|
|
313
|
-
display: flex;
|
|
314
|
-
align-items: center;
|
|
315
|
-
justify-content: center;
|
|
316
|
-
font-size: 80%;
|
|
317
|
-
user-select: none;
|
|
318
|
-
}
|
|
319
|
-
.table--sticky-header thead {
|
|
320
|
-
position: sticky;
|
|
321
|
-
top: 0;
|
|
322
|
-
z-index: 1;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
.table__drag-handle {
|
|
326
|
-
width: 2.25rem;
|
|
327
|
-
cursor: grab;
|
|
328
|
-
text-align: center;
|
|
329
|
-
--sc-kit--icon--size: 1.25rem;
|
|
330
|
-
--sc-kit--icon--color: var(--sc-kit--color--text--muted);
|
|
331
|
-
}
|
|
332
|
-
.table__drag-handle--dragging {
|
|
333
|
-
cursor: grabbing;
|
|
334
|
-
}</style>
|
|
@@ -6,10 +6,7 @@ declare function $$render<T extends {
|
|
|
6
6
|
props: {
|
|
7
7
|
model: TableModel<T>;
|
|
8
8
|
showAlternativeView?: boolean;
|
|
9
|
-
/**
|
|
10
|
-
* is never rendered over a non-empty list. @default true */
|
|
11
|
-
noItemsPlaceholderEnabled?: boolean;
|
|
12
|
-
/** Anti-flicker delay in ms before the placeholder appears, once `noItemsPlaceholderEnabled`. `0` shows it as soon as the list is empty. @default 0 */
|
|
9
|
+
/** Anti-flicker delay in ms before the placeholder appears. `0` shows it as soon as the list is empty. @default 0 */
|
|
13
10
|
noItemsPlaceholderDelay?: number;
|
|
14
11
|
on?: {
|
|
15
12
|
selectionChanged?: (e: T[]) => void;
|
|
@@ -18,7 +15,16 @@ declare function $$render<T extends {
|
|
|
18
15
|
itemsReordered?: (e: T[]) => void;
|
|
19
16
|
};
|
|
20
17
|
alternativeView?: Snippet;
|
|
21
|
-
|
|
18
|
+
/**
|
|
19
|
+
* What an empty list shows: the built-in empty state when omitted, your own content as a snippet, nothing with `false` — pairs with your own loading /
|
|
20
|
+
* empty UI. Rows always win: the placeholder is never rendered over a non-empty list.
|
|
21
|
+
*/
|
|
22
|
+
noItemsPlaceholder?: Snippet | false;
|
|
23
|
+
/**
|
|
24
|
+
* Band inside the table chrome above the column header row — a title and actions. With a toolbar the column header always sticks under it and takes
|
|
25
|
+
* the row background; an empty list drops the column header, leaving the toolbar and the no-items placeholder.
|
|
26
|
+
*/
|
|
27
|
+
toolbar?: Snippet;
|
|
22
28
|
};
|
|
23
29
|
exports: {};
|
|
24
30
|
bindings: "";
|
|
@@ -47,34 +53,39 @@ interface $$IsomorphicComponent {
|
|
|
47
53
|
}
|
|
48
54
|
/**
|
|
49
55
|
* Data table with drag-and-drop row reordering, plus everything `Table` offers (sorting, selection, column
|
|
50
|
-
* visibility, group actions). A leading drag-handle column is rendered
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* ### TableStyles (via `model.styles`)
|
|
54
|
-
* | Field | Type | Effect |
|
|
55
|
-
* |---|---|---|
|
|
56
|
-
* | `size` | `'sm' \| 'md'` | Row height + cell padding + font-size preset (default `'md'`) |
|
|
57
|
-
* | `variant` | `'plain' \| 'card'` | `'card'` wraps the table in a bordered rounded panel (default `'plain'`) |
|
|
58
|
-
* | `zebra` | `boolean` | Alternates row backgrounds with `--sc-kit--color--bg--field-alt` |
|
|
59
|
-
* | `stickyHeader` | `boolean` | Sticks `thead` to the scrolling ancestor |
|
|
60
|
-
* | `actionsPopoverTopDirection` | `boolean` | Forces the per-row actions popover above instead of below |
|
|
56
|
+
* visibility, group actions). A leading drag-handle column is rendered and a row is dragged by its handle only;
|
|
57
|
+
* a drop that changes the order fires `on.itemsReordered` and preserves the current selection, a drop back in place
|
|
58
|
+
* fires nothing. For non-reorderable tables use `Table` (it ships no dnd code).
|
|
61
59
|
*
|
|
62
60
|
* ### CSS Custom Properties
|
|
63
61
|
* | Property | Description | Default |
|
|
64
62
|
* |---|---|---|
|
|
65
|
-
* | `--sc-kit--table--row--height` | Row height | per size (
|
|
66
|
-
* | `--sc-kit--table--cell--
|
|
63
|
+
* | `--sc-kit--table--row--height` | Row height | per size (36 / 44 px) |
|
|
64
|
+
* | `--sc-kit--table--cell--padding-inline` | Cell inline padding | per size (`--space--3` / `--space--4`) |
|
|
67
65
|
* | `--sc-kit--table--cell--font-size` | Cell font size | per size (`--font-size--sm` / `--md`) |
|
|
68
|
-
* | `--sc-kit--table--
|
|
66
|
+
* | `--sc-kit--table--cell--padding-block` | Cell block padding | `0` |
|
|
67
|
+
* | `--sc-kit--table--cell--vertical-align` | Cell content alignment — `top` keeps inputs aligned when one cell grows | `middle` |
|
|
68
|
+
* | `--sc-kit--table--head--height` | Header row height | per size (32 / 40 px) |
|
|
69
|
+
* | `--sc-kit--table--head--background-color` | Header background | `--sc-kit--color--bg--field-alt`; with a `toolbar`, the card / panel background |
|
|
70
|
+
* | `--sc-kit--table--toolbar--background-color` | Toolbar band background | `--sc-kit--color--bg--field-alt` |
|
|
71
|
+
* | `--sc-kit--table--toolbar--padding-block` | Toolbar band block padding — `0` hands the band to the toolbar content | `--sc-kit--space--3` |
|
|
72
|
+
* | `--sc-kit--table--toolbar--padding-inline` | Toolbar band inline padding | the cell inline padding |
|
|
69
73
|
* | `--sc-kit--table--head--color` | Header text color | `--sc-kit--color--text--secondary` |
|
|
74
|
+
* | `--sc-kit--table--head--font-size` | Header font size | `--sc-kit--font-size--sm` |
|
|
75
|
+
* | `--sc-kit--table--head--font-weight` | Header font weight | `--sc-kit--font-weight--semibold` |
|
|
76
|
+
* | `--sc-kit--table--head--letter-spacing` | Header letter spacing | `normal` |
|
|
77
|
+
* | `--sc-kit--table--head--text-transform` | Header text transform | `none` |
|
|
70
78
|
* | `--sc-kit--table--border-color` | Border color between rows | `--sc-kit--color--border` |
|
|
71
79
|
* | `--sc-kit--table--row--color` | Row background | `transparent` |
|
|
72
80
|
* | `--sc-kit--table--row--alternative-color` | Hover / highlighted row background | `--sc-kit--color--bg--hover` |
|
|
73
81
|
* | `--sc-kit--table--zebra--color` | Zebra-row background (when `zebra` on) | `light-dark(#fcfcfd, #232323)` |
|
|
82
|
+
* | `--sc-kit--table--selected--color` | Selected row background | `--sc-kit--color--accent--softer` |
|
|
83
|
+
* | `--sc-kit--table--selected--color--hover` | Selected row background on hover | `--sc-kit--color--accent--soft` |
|
|
74
84
|
* | `--sc-kit--table--card--background` | Card variant background | `--sc-kit--color--bg--panel` |
|
|
75
85
|
* | `--sc-kit--table--card--border-color` | Card variant border | `--sc-kit--color--border` |
|
|
76
86
|
* | `--sc-kit--table--card--border-radius` | Card variant radius | `--sc-kit--radius--lg` |
|
|
77
87
|
* | `--sc-kit--table--card--padding-bottom` | Card variant bottom padding | `--sc-kit--space--4` |
|
|
88
|
+
* | `--sc-kit--table--min-width` | Table floor — past it the columns scroll horizontally inside the chrome, the toolbar stays. The column-floor substitute under `layout: 'fixed'` | `auto` |
|
|
78
89
|
*/
|
|
79
90
|
declare const Cmp: $$IsomorphicComponent;
|
|
80
91
|
type Cmp<T extends {
|