@streamscloud/kit 0.48.0 → 0.50.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/popover/cmp.popover.svelte +81 -19
- package/dist/ui/popover/cmp.popover.svelte.d.ts +22 -2
- package/dist/ui/table/cmp.table-draggable.svelte +3 -3
- package/dist/ui/table/cmp.table.svelte +3 -3
- package/dist/ui/table/table-column-models.svelte.d.ts +2 -1
- package/dist/ui/table/table-column-models.svelte.js +5 -2
- package/dist/ui/table/table-model.svelte.js +3 -3
- package/dist/ui/table/table-view.svelte.d.ts +2 -1
- package/dist/ui/table/table-view.svelte.js +5 -1
- package/dist/ui/table/types.d.ts +7 -1
- package/package.json +1 -1
|
@@ -42,14 +42,24 @@ $effect(() => {
|
|
|
42
42
|
const t = triggerEl;
|
|
43
43
|
const c = contentEl;
|
|
44
44
|
const update = async () => {
|
|
45
|
-
const middleware = [
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
const middleware = [
|
|
46
|
+
offsetMiddleware(offset),
|
|
47
|
+
flip({ padding: boundaryMargin }),
|
|
48
|
+
shift({ padding: boundaryMargin }),
|
|
49
|
+
size({
|
|
50
|
+
padding: boundaryMargin,
|
|
51
|
+
apply({ rects, elements, availableWidth, availableHeight }) {
|
|
52
|
+
elements.floating.style.setProperty('--_--popover--available-width', `${availableWidth}px`);
|
|
53
|
+
elements.floating.style.setProperty('--_--popover--available-height', `${availableHeight}px`);
|
|
54
|
+
if (matchWidth) {
|
|
55
|
+
// Clamped here too, not just in CSS: the max-width rule is gated on `panel`, so panel={false} has no other bound.
|
|
56
|
+
const width = Math.min(rects.reference.width, availableWidth);
|
|
57
|
+
elements.floating.style.width = `${width}px`;
|
|
58
|
+
elements.floating.style.minWidth = `${width}px`;
|
|
59
|
+
}
|
|
50
60
|
}
|
|
51
|
-
})
|
|
52
|
-
|
|
61
|
+
})
|
|
62
|
+
];
|
|
53
63
|
const result = await computePosition(t, c, {
|
|
54
64
|
placement: position,
|
|
55
65
|
strategy: fixedPosition ? 'fixed' : 'absolute',
|
|
@@ -187,13 +197,15 @@ const handleBackdropClick = (e) => {
|
|
|
187
197
|
<div
|
|
188
198
|
bind:this={contentEl}
|
|
189
199
|
class="popover__content"
|
|
190
|
-
class:popover__content--
|
|
200
|
+
class:popover__content--bounded={panel}
|
|
191
201
|
data-placement={resolvedPlacement}
|
|
192
202
|
role="dialog"
|
|
193
203
|
tabindex="-1"
|
|
194
204
|
onclick={handleContentClick}
|
|
195
205
|
onkeydown={() => undefined}>
|
|
196
|
-
{
|
|
206
|
+
<div class="popover__panel" class:popover__panel--styled={panel}>
|
|
207
|
+
{@render children()}
|
|
208
|
+
</div>
|
|
197
209
|
</div>
|
|
198
210
|
{/if}
|
|
199
211
|
</div>
|
|
@@ -224,6 +236,23 @@ let dd: PopoverInstance | undefined = $state.raw(undefined);
|
|
|
224
236
|
<button onclick={() => dd?.open()}>Open externally</button>
|
|
225
237
|
```
|
|
226
238
|
|
|
239
|
+
With `panel` on, content sizes to `max-content` and, above the `min-width` floor, never exceeds the room Floating UI measures around the trigger: the `size()` middleware feeds the space left after
|
|
240
|
+
`flip` / `shift` into the max-width / max-height defaults. So the panel always has a definite width — which is what makes a consumer's own
|
|
241
|
+
`text-overflow: ellipsis` (on a `min-inline-size: 0` flex child) resolve inside the panel — and a long list scrolls instead of running off-screen. Set
|
|
242
|
+
`--sc-kit--popover--content--max-width` for a tighter cap than the available space.
|
|
243
|
+
|
|
244
|
+
Because the panel fits itself to the available height, it is a scroll container by default. With `panel={false}` none of the three bounds apply — no width
|
|
245
|
+
cap, no height fit, no clipping — since that consumer owns the box entirely. Floating content nested inside it — a submenu, a `Tooltip` on
|
|
246
|
+
an item — is not clipped **once the panel has appeared**: those bubbles resolve their position against the popover's own positioned box, which sits outside
|
|
247
|
+
the scrolling area, so `fixedPosition` on a nested Popover stays optional. During the appear animation the panel does carry a transform and therefore does
|
|
248
|
+
clip, so a bubble opening within that window (a `Tooltip` with a near-zero `delay`) is cut off for its duration.
|
|
249
|
+
|
|
250
|
+
Two consequences of the panel being a scroll container. `--sc-kit--popover--content--overflow: visible` removes the clipping but not the height fit — the
|
|
251
|
+
panel is still shrunk and its content would paint outside the chrome, so pair it with `--sc-kit--popover--content--max-height: none` to opt out of both. And
|
|
252
|
+
the clip is tight to the panel's box, whose inline padding is `0` by default: content that paints a focus ring outside its own border box (kit's pattern is
|
|
253
|
+
`outline: 2px` + `outline-offset: 2px`, so 4px) needs inline padding of its own — either via `--sc-kit--popover--content--padding` or a wrapper. `PopoverItem`
|
|
254
|
+
already carries the margin that keeps it clear.
|
|
255
|
+
|
|
227
256
|
### CSS Custom Properties
|
|
228
257
|
| Property | Description | Default |
|
|
229
258
|
|---|---|---|
|
|
@@ -232,7 +261,10 @@ let dd: PopoverInstance | undefined = $state.raw(undefined);
|
|
|
232
261
|
| `--sc-kit--popover--content--border-color` | Content border color | `var(--sc-kit--color--border)` |
|
|
233
262
|
| `--sc-kit--popover--content--border-radius` | Content corner radius | `var(--sc-kit--radius--md)` |
|
|
234
263
|
| `--sc-kit--popover--content--box-shadow` | Content shadow | `var(--sc-kit--shadow--lg)` |
|
|
235
|
-
| `--sc-kit--popover--content--
|
|
264
|
+
| `--sc-kit--popover--content--max-height` | Content max height. Applies only with `panel` on — a `panel={false}` consumer owns its own bounds | available height around the trigger |
|
|
265
|
+
| `--sc-kit--popover--content--max-width` | Content max width — the upper bound content shrinks against. Applies only with `panel` on | available width around the trigger |
|
|
266
|
+
| `--sc-kit--popover--content--min-width` | Content min width. Wins over max-width when the two conflict; ignored under `matchWidth` | `12.5rem` |
|
|
267
|
+
| `--sc-kit--popover--content--overflow` | Panel overflow, both axes. Applies only with `panel` on. `visible` opts out of clipping | `hidden auto` |
|
|
236
268
|
| `--sc-kit--popover--content--padding` | Content padding | `var(--sc-kit--space--1) 0` |
|
|
237
269
|
| `--sc-kit--popover--content--z-index` | Content z-index | `var(--sc-kit--z-index--popover)` |
|
|
238
270
|
|
|
@@ -298,7 +330,10 @@ Props for keeping the popover open during interaction:
|
|
|
298
330
|
--_dd--content-border-color: var(--sc-kit--popover--content--border-color, var(--sc-kit--color--border));
|
|
299
331
|
--_dd--content-border-radius: var(--sc-kit--popover--content--border-radius, var(--sc-kit--radius--md));
|
|
300
332
|
--_dd--content-shadow: var(--sc-kit--popover--content--box-shadow, var(--sc-kit--shadow--lg));
|
|
301
|
-
--_dd--content-
|
|
333
|
+
--_dd--content-max-height: var(--sc-kit--popover--content--max-height, var(--_--popover--available-height, 100vh));
|
|
334
|
+
--_dd--content-max-width: var(--sc-kit--popover--content--max-width, var(--_--popover--available-width, 100vw));
|
|
335
|
+
--_dd--content-min-width: var(--sc-kit--popover--content--min-width, 12.5rem);
|
|
336
|
+
--_dd--content-overflow: var(--sc-kit--popover--content--overflow, hidden auto);
|
|
302
337
|
--_dd--content-padding: var(--sc-kit--popover--content--padding, var(--sc-kit--space--1) 0);
|
|
303
338
|
--_dd--content-z-index: var(--sc-kit--popover--content--z-index, var(--sc-kit--z-index--popover));
|
|
304
339
|
--_dd--anim-shift-x: 0;
|
|
@@ -311,15 +346,9 @@ Props for keeping the popover open during interaction:
|
|
|
311
346
|
z-index: var(--_dd--content-z-index);
|
|
312
347
|
width: max-content;
|
|
313
348
|
min-width: var(--_dd--content-min-width);
|
|
314
|
-
transform-origin: var(--_dd--anim-origin-x) var(--_dd--anim-origin-y);
|
|
315
|
-
animation: popover-appear var(--sc-kit--duration--fast) var(--sc-kit--ease--out) both;
|
|
316
349
|
}
|
|
317
|
-
.popover__content--
|
|
318
|
-
|
|
319
|
-
border: 1px solid var(--_dd--content-border-color);
|
|
320
|
-
border-radius: var(--_dd--content-border-radius);
|
|
321
|
-
box-shadow: var(--_dd--content-shadow);
|
|
322
|
-
padding: var(--_dd--content-padding);
|
|
350
|
+
.popover__content--bounded {
|
|
351
|
+
max-width: var(--_dd--content-max-width);
|
|
323
352
|
}
|
|
324
353
|
.popover__content:focus-visible {
|
|
325
354
|
outline: none;
|
|
@@ -364,6 +393,39 @@ Props for keeping the popover open during interaction:
|
|
|
364
393
|
.popover__content[data-placement=right-end] {
|
|
365
394
|
--_dd--anim-origin-y: bottom;
|
|
366
395
|
}
|
|
396
|
+
.popover__panel {
|
|
397
|
+
transform-origin: var(--_dd--anim-origin-x) var(--_dd--anim-origin-y);
|
|
398
|
+
animation: popover-appear var(--sc-kit--duration--fast) var(--sc-kit--ease--out);
|
|
399
|
+
}
|
|
400
|
+
.popover__panel--styled {
|
|
401
|
+
background: var(--_dd--content-background);
|
|
402
|
+
border: 1px solid var(--_dd--content-border-color);
|
|
403
|
+
border-radius: var(--_dd--content-border-radius);
|
|
404
|
+
box-shadow: var(--_dd--content-shadow);
|
|
405
|
+
padding: var(--_dd--content-padding);
|
|
406
|
+
max-height: var(--_dd--content-max-height);
|
|
407
|
+
overflow: var(--_dd--content-overflow);
|
|
408
|
+
--_cross-browser-scrollbar--thumb-color: var(--scrollbar--thumb-color, light-dark(#d1d5db, #4b5563));
|
|
409
|
+
--_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
|
|
410
|
+
}
|
|
411
|
+
.popover__panel--styled::-webkit-scrollbar {
|
|
412
|
+
width: 6px;
|
|
413
|
+
height: 6px;
|
|
414
|
+
}
|
|
415
|
+
.popover__panel--styled::-webkit-scrollbar-track {
|
|
416
|
+
background: var(--_cross-browser-scrollbar--track-color);
|
|
417
|
+
border-radius: 100vw;
|
|
418
|
+
}
|
|
419
|
+
.popover__panel--styled::-webkit-scrollbar-thumb {
|
|
420
|
+
background: var(--_cross-browser-scrollbar--thumb-color);
|
|
421
|
+
border-radius: 100vw;
|
|
422
|
+
}
|
|
423
|
+
@supports (scrollbar-color: transparent transparent) {
|
|
424
|
+
.popover__panel--styled {
|
|
425
|
+
scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
|
|
426
|
+
scrollbar-width: thin;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
367
429
|
|
|
368
430
|
@keyframes popover-appear {
|
|
369
431
|
from {
|
|
@@ -12,7 +12,7 @@ type Props = {
|
|
|
12
12
|
boundaryMargin?: number;
|
|
13
13
|
/** Render a semi-transparent backdrop behind the content. */
|
|
14
14
|
backdrop?: boolean;
|
|
15
|
-
/** Make the content match the trigger element width. */
|
|
15
|
+
/** Make the content match the trigger element width, overriding `--sc-kit--popover--content--min-width` (never growing past the available space). */
|
|
16
16
|
matchWidth?: boolean;
|
|
17
17
|
/** Apply built-in panel styling (background, shadow, border-radius). @default true */
|
|
18
18
|
panel?: boolean;
|
|
@@ -61,6 +61,23 @@ type Props = {
|
|
|
61
61
|
* <button onclick={() => dd?.open()}>Open externally</button>
|
|
62
62
|
* ```
|
|
63
63
|
*
|
|
64
|
+
* With `panel` on, content sizes to `max-content` and, above the `min-width` floor, never exceeds the room Floating UI measures around the trigger: the `size()` middleware feeds the space left after
|
|
65
|
+
* `flip` / `shift` into the max-width / max-height defaults. So the panel always has a definite width — which is what makes a consumer's own
|
|
66
|
+
* `text-overflow: ellipsis` (on a `min-inline-size: 0` flex child) resolve inside the panel — and a long list scrolls instead of running off-screen. Set
|
|
67
|
+
* `--sc-kit--popover--content--max-width` for a tighter cap than the available space.
|
|
68
|
+
*
|
|
69
|
+
* Because the panel fits itself to the available height, it is a scroll container by default. With `panel={false}` none of the three bounds apply — no width
|
|
70
|
+
* cap, no height fit, no clipping — since that consumer owns the box entirely. Floating content nested inside it — a submenu, a `Tooltip` on
|
|
71
|
+
* an item — is not clipped **once the panel has appeared**: those bubbles resolve their position against the popover's own positioned box, which sits outside
|
|
72
|
+
* the scrolling area, so `fixedPosition` on a nested Popover stays optional. During the appear animation the panel does carry a transform and therefore does
|
|
73
|
+
* clip, so a bubble opening within that window (a `Tooltip` with a near-zero `delay`) is cut off for its duration.
|
|
74
|
+
*
|
|
75
|
+
* Two consequences of the panel being a scroll container. `--sc-kit--popover--content--overflow: visible` removes the clipping but not the height fit — the
|
|
76
|
+
* panel is still shrunk and its content would paint outside the chrome, so pair it with `--sc-kit--popover--content--max-height: none` to opt out of both. And
|
|
77
|
+
* the clip is tight to the panel's box, whose inline padding is `0` by default: content that paints a focus ring outside its own border box (kit's pattern is
|
|
78
|
+
* `outline: 2px` + `outline-offset: 2px`, so 4px) needs inline padding of its own — either via `--sc-kit--popover--content--padding` or a wrapper. `PopoverItem`
|
|
79
|
+
* already carries the margin that keeps it clear.
|
|
80
|
+
*
|
|
64
81
|
* ### CSS Custom Properties
|
|
65
82
|
* | Property | Description | Default |
|
|
66
83
|
* |---|---|---|
|
|
@@ -69,7 +86,10 @@ type Props = {
|
|
|
69
86
|
* | `--sc-kit--popover--content--border-color` | Content border color | `var(--sc-kit--color--border)` |
|
|
70
87
|
* | `--sc-kit--popover--content--border-radius` | Content corner radius | `var(--sc-kit--radius--md)` |
|
|
71
88
|
* | `--sc-kit--popover--content--box-shadow` | Content shadow | `var(--sc-kit--shadow--lg)` |
|
|
72
|
-
* | `--sc-kit--popover--content--
|
|
89
|
+
* | `--sc-kit--popover--content--max-height` | Content max height. Applies only with `panel` on — a `panel={false}` consumer owns its own bounds | available height around the trigger |
|
|
90
|
+
* | `--sc-kit--popover--content--max-width` | Content max width — the upper bound content shrinks against. Applies only with `panel` on | available width around the trigger |
|
|
91
|
+
* | `--sc-kit--popover--content--min-width` | Content min width. Wins over max-width when the two conflict; ignored under `matchWidth` | `12.5rem` |
|
|
92
|
+
* | `--sc-kit--popover--content--overflow` | Panel overflow, both axes. Applies only with `panel` on. `visible` opts out of clipping | `hidden auto` |
|
|
73
93
|
* | `--sc-kit--popover--content--padding` | Content padding | `var(--sc-kit--space--1) 0` |
|
|
74
94
|
* | `--sc-kit--popover--content--z-index` | Content z-index | `var(--sc-kit--z-index--popover)` |
|
|
75
95
|
*
|
|
@@ -3,7 +3,7 @@ import { EmptyState } from '../empty-state';
|
|
|
3
3
|
import { Icon } from '../icon';
|
|
4
4
|
import { TableCell, TableHideableCell } from './table-cells';
|
|
5
5
|
import { TableLocalization } from './table-localization';
|
|
6
|
-
import {
|
|
6
|
+
import { columnWidthStyle, createTableView } from './table-view.svelte';
|
|
7
7
|
import IconReorderDotsHorizontal from '@fluentui/svg-icons/icons/re_order_dots_horizontal_20_regular.svg?raw';
|
|
8
8
|
import { flip } from 'svelte/animate';
|
|
9
9
|
import { dndzone } from 'svelte-dnd-action';
|
|
@@ -73,7 +73,7 @@ const transformDraggedElement = (draggedRow) => {
|
|
|
73
73
|
<th class="table__th table__drag-handle"> </th>
|
|
74
74
|
{#each model.columns as column (column)}
|
|
75
75
|
<TableHideableCell column={column}>
|
|
76
|
-
<th class="table__th" class:table__th--centered={column.centered} style={
|
|
76
|
+
<th class="table__th" class:table__th--centered={column.centered} style={columnWidthStyle(column)} title={column.title}>
|
|
77
77
|
<DynamicComponent model={column.headerView} />
|
|
78
78
|
</th>
|
|
79
79
|
</TableHideableCell>
|
|
@@ -132,7 +132,7 @@ const transformDraggedElement = (draggedRow) => {
|
|
|
132
132
|
class:table__td--centered={column.centered}
|
|
133
133
|
class:table__td--clickable={!!column.onClick}
|
|
134
134
|
class:table__td--flush={flushBottom}
|
|
135
|
-
style={
|
|
135
|
+
style={columnWidthStyle(column)}
|
|
136
136
|
onclick={() => column.onClick && column.onClick(item)}>
|
|
137
137
|
<TableCell model={model} item={item} column={column} itemIndex={itemIndex} on={{ itemsReordered: on?.itemsReordered }} />
|
|
138
138
|
</td>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { EmptyState } from '../empty-state';
|
|
3
3
|
import { TableCell, TableHideableCell } from './table-cells';
|
|
4
4
|
import { TableLocalization } from './table-localization';
|
|
5
|
-
import {
|
|
5
|
+
import { columnWidthStyle, createTableView } from './table-view.svelte';
|
|
6
6
|
let { model, showPlaceholder = false, showAlternativeView = false, grouping, on, alternativeView, placeholderRow, customNoItemsPlaceholder } = $props();
|
|
7
7
|
const localization = new TableLocalization();
|
|
8
8
|
const view = createTableView(() => model, () => on);
|
|
@@ -58,7 +58,7 @@ const visibleColspan = $derived(model.columns.filter((column) => !column.hidden)
|
|
|
58
58
|
<tr>
|
|
59
59
|
{#each model.columns as column (column)}
|
|
60
60
|
<TableHideableCell column={column}>
|
|
61
|
-
<th class="table__th" class:table__th--centered={column.centered} style={
|
|
61
|
+
<th class="table__th" class:table__th--centered={column.centered} style={columnWidthStyle(column)} title={column.title}>
|
|
62
62
|
<DynamicComponent model={column.headerView} />
|
|
63
63
|
</th>
|
|
64
64
|
</TableHideableCell>
|
|
@@ -112,7 +112,7 @@ const visibleColspan = $derived(model.columns.filter((column) => !column.hidden)
|
|
|
112
112
|
class:table__td--centered={column.centered}
|
|
113
113
|
class:table__td--clickable={!!column.onClick}
|
|
114
114
|
class:table__td--flush={flushBottom}
|
|
115
|
-
style={
|
|
115
|
+
style={columnWidthStyle(column)}
|
|
116
116
|
onclick={() => column.onClick && column.onClick(item)}>
|
|
117
117
|
<TableCell model={model} item={item} column={column} itemIndex={itemIndex} on={{ itemsReordered: on?.itemsReordered }} />
|
|
118
118
|
</td>
|
|
@@ -24,7 +24,8 @@ export declare class ResolvedColumn<T extends WithId> {
|
|
|
24
24
|
get id(): keyof T;
|
|
25
25
|
get title(): string;
|
|
26
26
|
get centered(): boolean;
|
|
27
|
-
get
|
|
27
|
+
get cssWidth(): string;
|
|
28
|
+
get minCssWidth(): string;
|
|
28
29
|
get hideable(): boolean;
|
|
29
30
|
get sortLabelsOverride(): {
|
|
30
31
|
asc: string;
|
|
@@ -31,8 +31,11 @@ export class ResolvedColumn {
|
|
|
31
31
|
get centered() {
|
|
32
32
|
return this.def.centered ?? false;
|
|
33
33
|
}
|
|
34
|
-
get
|
|
35
|
-
return this.def.
|
|
34
|
+
get cssWidth() {
|
|
35
|
+
return this.def.cssWidth ?? '';
|
|
36
|
+
}
|
|
37
|
+
get minCssWidth() {
|
|
38
|
+
return this.def.minCssWidth ?? '';
|
|
36
39
|
}
|
|
37
40
|
get hideable() {
|
|
38
41
|
if ('hideable' in this.def) {
|
|
@@ -113,7 +113,7 @@ export class TableModel {
|
|
|
113
113
|
}
|
|
114
114
|
// Append actions column if needed
|
|
115
115
|
if (this._itemActions.length) {
|
|
116
|
-
const actionsColumn = new ResolvedColumn({ type: 'actions', centered: true,
|
|
116
|
+
const actionsColumn = new ResolvedColumn({ type: 'actions', centered: true, cssWidth: Css.em(75) });
|
|
117
117
|
actionsColumn.headerView = new DynamicComponentModel({
|
|
118
118
|
component: TableHeader,
|
|
119
119
|
props: { column: { title: 'Actions' } }
|
|
@@ -151,7 +151,7 @@ export class TableModel {
|
|
|
151
151
|
const resolved = new ResolvedColumn({
|
|
152
152
|
...column,
|
|
153
153
|
centered: true,
|
|
154
|
-
|
|
154
|
+
cssWidth: column.cssWidth || Css.em(50)
|
|
155
155
|
});
|
|
156
156
|
resolved.headerView = new DynamicComponentModel({
|
|
157
157
|
component: TableCheckboxHeader,
|
|
@@ -163,7 +163,7 @@ export class TableModel {
|
|
|
163
163
|
const resolved = new ResolvedColumn({
|
|
164
164
|
...column,
|
|
165
165
|
centered: true,
|
|
166
|
-
|
|
166
|
+
cssWidth: column.cssWidth || Css.em(75)
|
|
167
167
|
});
|
|
168
168
|
resolved.headerView = resolveSortableHeader(resolved);
|
|
169
169
|
return resolved;
|
|
@@ -6,7 +6,8 @@ type SelectionCallbacks<T> = {
|
|
|
6
6
|
itemsSelected?: (e: T[]) => void;
|
|
7
7
|
itemsDeselected?: (e: T[]) => void;
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
/** Inline width declarations for a column's `th` / `td`: the preferred width plus, when set, the floor the browser must honour. */
|
|
10
|
+
export declare const columnWidthStyle: <T extends WithId>(column: ResolvedColumn<T>) => string;
|
|
10
11
|
/** Shared presentation wiring for the table views: selection-event subscriptions + the debounced no-items placeholder. */
|
|
11
12
|
export declare const createTableView: <T extends WithId>(model: () => TableModel<T>, on: () => SelectionCallbacks<T> | undefined) => {
|
|
12
13
|
readonly showNoItemsPlaceholder: boolean;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { untrack } from 'svelte';
|
|
2
|
-
|
|
2
|
+
/** Inline width declarations for a column's `th` / `td`: the preferred width plus, when set, the floor the browser must honour. */
|
|
3
|
+
export const columnWidthStyle = (column) => {
|
|
4
|
+
const width = column.cssWidth ? `width: ${column.cssWidth};` : 'width: auto;';
|
|
5
|
+
return column.minCssWidth ? `${width} min-width: ${column.minCssWidth};` : width;
|
|
6
|
+
};
|
|
3
7
|
/** Shared presentation wiring for the table views: selection-event subscriptions + the debounced no-items placeholder. */
|
|
4
8
|
export const createTableView = (model, on) => {
|
|
5
9
|
let showNoItemsPlaceholder = $state(false);
|
package/dist/ui/table/types.d.ts
CHANGED
|
@@ -11,7 +11,13 @@ export type IOneOfTableColumn<T> = ITableBadgeColumn<T> | ITableButtonColumn<T>
|
|
|
11
11
|
export type TableColumnType = 'actions' | 'badge' | 'button' | 'by' | 'checkbox' | 'icon' | 'image' | 'move-row' | 'snippet' | 'text';
|
|
12
12
|
interface ITableColumnBase {
|
|
13
13
|
type: TableColumnType;
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Preferred column width. Under the table's `table-layout: auto` this is a suggestion: content can push a column wider, and a column with no width of its
|
|
16
|
+
* own is left with whatever the others do not claim. Use `minCssWidth` for a width the browser must honour.
|
|
17
|
+
*/
|
|
18
|
+
cssWidth?: string;
|
|
19
|
+
/** Floor the column will not shrink below, taken out of columns whose `cssWidth` is merely a suggestion. Use it on the column that must keep space. */
|
|
20
|
+
minCssWidth?: string;
|
|
15
21
|
centered?: boolean;
|
|
16
22
|
}
|
|
17
23
|
export interface ITableColumn<T> extends ITableColumnBase {
|