@lavalogic/scoria 0.37.19 → 0.37.20
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/Table/Body/QuickSearchCell.svelte +3 -2
- package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +1 -7
- package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +30 -6
- package/dist/Components/Table/ColumnFactory.svelte.js +1 -0
- package/dist/Components/Table/Types/Columns/Definitions/Display/BubbleDef.svelte.d.ts +6 -0
- package/dist/Components/Table/Types/Columns/Definitions/Display/BubbleDef.svelte.js +3 -0
- package/dist/Components/Table/Types/Public/ColumnOptions.d.ts +6 -0
- package/dist/scss/_mixins.scss +14 -11
- package/package.json +1 -1
|
@@ -724,10 +724,11 @@
|
|
|
724
724
|
div.input-cell {
|
|
725
725
|
background-color: #f4f7f9;
|
|
726
726
|
height: var(--height);
|
|
727
|
-
overflow:
|
|
727
|
+
overflow-x: clip;
|
|
728
|
+
overflow-y: visible;
|
|
728
729
|
padding-left: 0;
|
|
729
730
|
padding-right: 0;
|
|
730
|
-
border-right:
|
|
731
|
+
border-right: none;
|
|
731
732
|
box-sizing: border-box;
|
|
732
733
|
}
|
|
733
734
|
div.input-cell div.stick-right {
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
import Action from '../../../Action.svelte';
|
|
8
8
|
import Checkbox from '../../../Checkbox.svelte';
|
|
9
9
|
import ThreeStateRadio from '../../../ThreeStateRadio.svelte';
|
|
10
|
-
import { ColumnType } from '../../Types/Columns/ColumnType.js';
|
|
11
10
|
import { TableContext } from '../../Types/Context/TableContext.svelte.js';
|
|
12
11
|
import type { Primitive } from '../../Types/Context/TableInitOptions.js';
|
|
13
12
|
import { Size } from '../../../../Types/Internal/Size.js';
|
|
@@ -18,7 +17,6 @@
|
|
|
18
17
|
|
|
19
18
|
const { columnDef }: ColumnListRowProps<T> = $props();
|
|
20
19
|
|
|
21
|
-
const isExpandColumn = $derived(columnDef?.columnType === ColumnType.Expand);
|
|
22
20
|
|
|
23
21
|
/**
|
|
24
22
|
* Position of this column inside the sorted column list, used to
|
|
@@ -412,13 +410,9 @@
|
|
|
412
410
|
Expand columns can never be pinned, so the group goes
|
|
413
411
|
fully disabled for them.
|
|
414
412
|
-->
|
|
415
|
-
<div
|
|
416
|
-
class="pin-selector"
|
|
417
|
-
class:disabled={isExpandColumn}
|
|
418
|
-
>
|
|
413
|
+
<div class="pin-selector">
|
|
419
414
|
<ThreeStateRadio
|
|
420
415
|
value={pinSide}
|
|
421
|
-
disabled={isExpandColumn}
|
|
422
416
|
noLabel="Pin to left"
|
|
423
417
|
neutralLabel="Unpinned"
|
|
424
418
|
yesLabel="Pin to right"
|
|
@@ -83,11 +83,17 @@
|
|
|
83
83
|
>
|
|
84
84
|
<div class="bubble-parent">
|
|
85
85
|
{#await values then values}
|
|
86
|
-
<!--
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
<!-- `maxBubbles` (default 3) caps how many pills render inline;
|
|
87
|
+
anything beyond gets a single `"+N more"` overflow chip with
|
|
88
|
+
the hidden labels as a hover tooltip. Key combines index and
|
|
89
|
+
value because duplicate labels would otherwise collapse and
|
|
90
|
+
reordering with identical labels would force unrelated
|
|
91
|
+
bubbles to swap. -->
|
|
92
|
+
{@const maxBubbles = (cell.column.columnDef as BubbleDef<T>).maxBubbles ?? 3}
|
|
93
|
+
{@const visibleBubbles = values.slice(0, maxBubbles)}
|
|
94
|
+
{@const overflowCount = Math.max(0, values.length - maxBubbles)}
|
|
95
|
+
{@const overflowTitle = values.slice(maxBubbles).join(', ')}
|
|
96
|
+
{#each visibleBubbles as value, index (`${index}:${value}`)}
|
|
91
97
|
{@const colourPromise = (cell.column.columnDef as BubbleDef<T>).getColour?.(
|
|
92
98
|
cell.row.original,
|
|
93
99
|
cell.row.originalIndex,
|
|
@@ -105,6 +111,12 @@
|
|
|
105
111
|
{/await}
|
|
106
112
|
{/if}
|
|
107
113
|
{/each}
|
|
114
|
+
{#if overflowCount > 0}
|
|
115
|
+
<span
|
|
116
|
+
class="bubble-overflow"
|
|
117
|
+
title={overflowTitle}
|
|
118
|
+
>+{overflowCount} more</span>
|
|
119
|
+
{/if}
|
|
108
120
|
{/await}
|
|
109
121
|
</div>
|
|
110
122
|
</div>
|
|
@@ -186,7 +198,7 @@
|
|
|
186
198
|
|
|
187
199
|
div.bubble-parent {
|
|
188
200
|
display: flex;
|
|
189
|
-
flex-flow: row
|
|
201
|
+
flex-flow: row nowrap;
|
|
190
202
|
max-width: 100%;
|
|
191
203
|
height: 100%;
|
|
192
204
|
overflow-x: clip;
|
|
@@ -194,4 +206,16 @@ div.bubble-parent {
|
|
|
194
206
|
align-items: center;
|
|
195
207
|
gap: 0.75rem;
|
|
196
208
|
--line-height: 1;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.bubble-overflow {
|
|
212
|
+
flex-shrink: 0;
|
|
213
|
+
padding: 0.125rem 0.5rem;
|
|
214
|
+
border-radius: 9999px;
|
|
215
|
+
background-color: #e9ecf1;
|
|
216
|
+
color: #647d8e;
|
|
217
|
+
font-size: 0.75rem;
|
|
218
|
+
font-weight: 500;
|
|
219
|
+
white-space: nowrap;
|
|
220
|
+
cursor: default;
|
|
197
221
|
}</style>
|
|
@@ -370,6 +370,7 @@ export function createColumnFactory() {
|
|
|
370
370
|
id,
|
|
371
371
|
...commonProps(opts, 'bubble'),
|
|
372
372
|
accessorFn: opts.value,
|
|
373
|
+
maxBubbles: opts.maxBubbles,
|
|
373
374
|
getColour: opts.colour,
|
|
374
375
|
// Default to a string-typed filter so bubble columns appear in
|
|
375
376
|
// the quick-filter row and advanced filter panel by default
|
|
@@ -14,6 +14,10 @@ import { AbstractDisplayDef, type AbstractDisplayDefProps } from './AbstractDisp
|
|
|
14
14
|
export interface BubbleDefProps<T extends object, in FilterValueType, out FilterOptionsType> extends AbstractDisplayDefProps<T, FilterValueType, FilterOptionsType> {
|
|
15
15
|
/** Per-bubble colour mapper. Invoked per bubble value per render. */
|
|
16
16
|
getColour?: (item: T, index: number, value: string) => BubbleColour | Promise<BubbleColour | null | undefined>;
|
|
17
|
+
/** Maximum number of pills shown per cell before the overflow chip
|
|
18
|
+
* kicks in. Pills beyond this cap are hidden and a single
|
|
19
|
+
* `"+N more"` chip is rendered in their place. Defaults to 3. */
|
|
20
|
+
maxBubbles?: number;
|
|
17
21
|
}
|
|
18
22
|
/**
|
|
19
23
|
* `BubbleDef<T, FilterValueType, FilterOptionsType>` renders the cell
|
|
@@ -29,4 +33,6 @@ export declare class BubbleDef<T extends object, in FilterValueType = StringFilt
|
|
|
29
33
|
set filterFn(v: FilterFn<T, FilterValueType> | undefined);
|
|
30
34
|
/** Per-bubble colour mapper. */
|
|
31
35
|
readonly getColour: ((item: T, index: number, value: string) => BubbleColour | Promise<BubbleColour | null | undefined>) | undefined;
|
|
36
|
+
/** Cap on rendered pills before the overflow chip. */
|
|
37
|
+
readonly maxBubbles: number;
|
|
32
38
|
}
|
|
@@ -15,6 +15,7 @@ export class BubbleDef extends AbstractDisplayDef {
|
|
|
15
15
|
// props.getColour re-derives the wrapper and discards the stale cache.
|
|
16
16
|
this.getColour = $derived(memoiseRowValueAccessor(props.getColour));
|
|
17
17
|
this._filterFn = $state(props.filterFn);
|
|
18
|
+
this.maxBubbles = $derived(props.maxBubbles ?? 3);
|
|
18
19
|
}
|
|
19
20
|
_filterFn;
|
|
20
21
|
/** Filter predicate. Reassignable. */
|
|
@@ -26,4 +27,6 @@ export class BubbleDef extends AbstractDisplayDef {
|
|
|
26
27
|
}
|
|
27
28
|
/** Per-bubble colour mapper. */
|
|
28
29
|
getColour;
|
|
30
|
+
/** Cap on rendered pills before the overflow chip. */
|
|
31
|
+
maxBubbles;
|
|
29
32
|
}
|
|
@@ -208,6 +208,12 @@ export interface BubbleColumnOptions<TRow extends object, TValue = unknown> exte
|
|
|
208
208
|
* supported (scoria internally wraps it in `Promise.resolve`).
|
|
209
209
|
*/
|
|
210
210
|
getOptions?: () => ReadonlyArray<SelectOption<TValue>> | Promise<ReadonlyArray<SelectOption<TValue>>>;
|
|
211
|
+
/**
|
|
212
|
+
* Maximum number of pills rendered before they collapse into an
|
|
213
|
+
* overflow chip (`"+N more"`). Defaults to 3. Set a larger number
|
|
214
|
+
* to show more pills inline; set `Infinity` to disable the cap.
|
|
215
|
+
*/
|
|
216
|
+
maxBubbles?: number;
|
|
211
217
|
}
|
|
212
218
|
/** Options for `col.progress({ header, value, ... })`. Renders a horizontal
|
|
213
219
|
* progress bar from a numeric ratio. */
|
package/dist/scss/_mixins.scss
CHANGED
|
@@ -1866,19 +1866,22 @@
|
|
|
1866
1866
|
div.input-cell {
|
|
1867
1867
|
background-color: colours.$ui-blue-1;
|
|
1868
1868
|
height: var(--height);
|
|
1869
|
-
overflow:
|
|
1869
|
+
// `overflow-x: clip` so a narrow filter cell's internal widget
|
|
1870
|
+
// (select chevron, filter-mode funnel, etc.) cannot paint past
|
|
1871
|
+
// the column boundary. The column-separator border now lives on
|
|
1872
|
+
// the outer grid item (`.quick-filter-row > .cell` in
|
|
1873
|
+
// `TableBody.svelte`), so clipping here keeps both the widget
|
|
1874
|
+
// AND the cell's own background inside the track and the border
|
|
1875
|
+
// stays visible. `overflow-y: visible` preserves the inline
|
|
1876
|
+
// dropdown spillage for select / date popups.
|
|
1877
|
+
overflow-x: clip;
|
|
1878
|
+
overflow-y: visible;
|
|
1870
1879
|
padding-left: 0;
|
|
1871
1880
|
padding-right: 0;
|
|
1872
|
-
//
|
|
1873
|
-
//
|
|
1874
|
-
//
|
|
1875
|
-
|
|
1876
|
-
// visually merge because the inner widget's background covers
|
|
1877
|
-
// the cell's table-cell-basic border. `!important` is here to
|
|
1878
|
-
// override the more-specific .focusable rule from
|
|
1879
|
-
// table-cell-basic that occasionally re-paints the right edge
|
|
1880
|
-
// transparent during focus.
|
|
1881
|
-
border-right: solid 1px colours.$ui-blue-4 !important;
|
|
1881
|
+
// Inner widget no longer paints a border-right - the outer cell
|
|
1882
|
+
// wrapper owns the column divider so adjacent filters cannot
|
|
1883
|
+
// visually merge regardless of what the widget paints inside.
|
|
1884
|
+
border-right: none;
|
|
1882
1885
|
box-sizing: border-box;
|
|
1883
1886
|
|
|
1884
1887
|
div.stick-right {
|