@streamscloud/kit 0.25.0 → 0.25.2
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/styles/_semantic.scss +6 -0
- package/dist/ui/page-toolbar/cmp.toolbar-filter-select.svelte +29 -20
- package/dist/ui/page-toolbar/cmp.toolbar-filter-select.svelte.d.ts +5 -2
- package/dist/ui/page-toolbar/cmp.toolbar-sort-select.svelte +5 -1
- package/dist/ui/progress-bar/cmp.progress-bar.svelte +3 -2
- package/dist/ui/progress-bar/cmp.progress-bar.svelte.d.ts +2 -1
- package/package.json +1 -1
|
@@ -65,16 +65,22 @@
|
|
|
65
65
|
// COLOR — TONES (categorical palette; fg + soft bg, component-neutral)
|
|
66
66
|
// ============================================================
|
|
67
67
|
--sc-kit--tone--gray--fg: light-dark(#{$color-neutral-500}, #{$color-neutral-400});
|
|
68
|
+
--sc-kit--tone--gray--muted: light-dark(#{$color-neutral-400}, #{$color-neutral-600});
|
|
68
69
|
--sc-kit--tone--gray--bg: light-dark(#{$color-neutral-50}, #{$color-dark-600});
|
|
69
70
|
--sc-kit--tone--blue--fg: light-dark(#{$color-blue-500}, #{$color-blue-400});
|
|
71
|
+
--sc-kit--tone--blue--muted: light-dark(#{$color-blue-200}, #{$color-blue-700});
|
|
70
72
|
--sc-kit--tone--blue--bg: light-dark(#{$color-blue-50}, #{$color-blue-900});
|
|
71
73
|
--sc-kit--tone--green--fg: light-dark(#{$color-green-500}, #{$color-green-400});
|
|
74
|
+
--sc-kit--tone--green--muted: light-dark(#{$color-green-200}, #{$color-green-700});
|
|
72
75
|
--sc-kit--tone--green--bg: light-dark(#{$color-green-50}, #{$color-green-900});
|
|
73
76
|
--sc-kit--tone--red--fg: light-dark(#{$color-red-500}, #{$color-red-400});
|
|
77
|
+
--sc-kit--tone--red--muted: light-dark(#{$color-red-200}, #{$color-red-700});
|
|
74
78
|
--sc-kit--tone--red--bg: light-dark(#{$color-red-50}, #{$color-red-900});
|
|
75
79
|
--sc-kit--tone--orange--fg: light-dark(#{$color-orange-500}, #{$color-orange-400});
|
|
80
|
+
--sc-kit--tone--orange--muted: light-dark(#{$color-orange-200}, #{$color-orange-700});
|
|
76
81
|
--sc-kit--tone--orange--bg: light-dark(#{$color-orange-100}, #{$color-orange-900});
|
|
77
82
|
--sc-kit--tone--teal--fg: light-dark(#3d7068, #5f938a);
|
|
83
|
+
--sc-kit--tone--teal--muted: light-dark(#3d7068, #5f938a);
|
|
78
84
|
--sc-kit--tone--teal--bg: light-dark(#eef4f3, #16302b);
|
|
79
85
|
|
|
80
86
|
// ============================================================
|
|
@@ -13,18 +13,22 @@ const isSelected = (candidate) => value.some((selected) => eq(selected, candidat
|
|
|
13
13
|
const withValue = (list, candidate) => (list.some((item) => eq(item, candidate)) ? list : [...list, candidate]);
|
|
14
14
|
const without = (list, candidate) => list.filter((item) => !eq(item, candidate));
|
|
15
15
|
const optionDisplay = $derived(single ? 'checkmark' : 'checkbox');
|
|
16
|
-
const
|
|
17
|
-
|
|
16
|
+
const selectedOptions = $derived(options
|
|
17
|
+
.flatMap((item) => isSelectGroup(item) ? (item.value !== undefined ? [{ label: item.label, value: item.value }, ...item.options] : item.options) : [item])
|
|
18
|
+
.filter((option) => isSelected(option.value)));
|
|
18
19
|
const summary = $derived.by(() => {
|
|
19
|
-
if (
|
|
20
|
+
if (selectedOptions.length === 0) {
|
|
20
21
|
return label;
|
|
21
22
|
}
|
|
22
|
-
if (
|
|
23
|
-
return `${label}: ${
|
|
23
|
+
if (selectedOptions.length === 1) {
|
|
24
|
+
return `${label}: ${selectedOptions[0].label}`;
|
|
24
25
|
}
|
|
25
|
-
return `${label}: ${localization.selectedCount(
|
|
26
|
+
return `${label}: ${localization.selectedCount(selectedOptions.length)}`;
|
|
26
27
|
});
|
|
27
28
|
const groupSelected = (group) => {
|
|
29
|
+
if (group.value !== undefined) {
|
|
30
|
+
return isSelected(group.value);
|
|
31
|
+
}
|
|
28
32
|
const selectedCount = group.options.filter((option) => isSelected(option.value)).length;
|
|
29
33
|
if (selectedCount === 0) {
|
|
30
34
|
return false;
|
|
@@ -41,7 +45,17 @@ const toggleOption = (option) => {
|
|
|
41
45
|
emit(isSelected(option.value) ? without(value, option.value) : withValue(value, option.value));
|
|
42
46
|
};
|
|
43
47
|
const toggleGroup = (group) => {
|
|
48
|
+
if (group.value !== undefined) {
|
|
49
|
+
if (single) {
|
|
50
|
+
pickSingle(group.value);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
emit(isSelected(group.value) ? without(value, group.value) : withValue(value, group.value));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
44
56
|
if (single) {
|
|
57
|
+
const hasSelectedChild = group.options.some((option) => isSelected(option.value));
|
|
58
|
+
emit(hasSelectedChild ? [] : group.options.slice(0, 1).map((option) => option.value));
|
|
45
59
|
return;
|
|
46
60
|
}
|
|
47
61
|
const allSelected = group.options.every((option) => isSelected(option.value));
|
|
@@ -49,22 +63,14 @@ const toggleGroup = (group) => {
|
|
|
49
63
|
for (const option of group.options) {
|
|
50
64
|
next = allSelected ? without(next, option.value) : withValue(next, option.value);
|
|
51
65
|
}
|
|
52
|
-
if (group.value !== undefined) {
|
|
53
|
-
next = allSelected ? without(next, group.value) : withValue(next, group.value);
|
|
54
|
-
}
|
|
55
66
|
emit(next);
|
|
56
67
|
};
|
|
57
|
-
const toggleChild = (
|
|
68
|
+
const toggleChild = (child) => {
|
|
58
69
|
if (single) {
|
|
59
70
|
pickSingle(child.value);
|
|
60
71
|
return;
|
|
61
72
|
}
|
|
62
|
-
|
|
63
|
-
if (group.value !== undefined) {
|
|
64
|
-
const anyChildSelected = group.options.some((option) => next.some((selected) => eq(selected, option.value)));
|
|
65
|
-
next = anyChildSelected ? withValue(next, group.value) : without(next, group.value);
|
|
66
|
-
}
|
|
67
|
-
emit(next);
|
|
73
|
+
emit(isSelected(child.value) ? without(value, child.value) : withValue(value, child.value));
|
|
68
74
|
};
|
|
69
75
|
const clearAll = () => emit([]);
|
|
70
76
|
</script>
|
|
@@ -75,7 +81,7 @@ const clearAll = () => emit([]);
|
|
|
75
81
|
{#if header}
|
|
76
82
|
{@render header()}
|
|
77
83
|
{/if}
|
|
78
|
-
{#each options as item (isSelectGroup(item) ? item.label : item.value)}
|
|
84
|
+
{#each options as item (isSelectGroup(item) ? (item.value ?? item.options[0]?.value ?? item.label) : item.value)}
|
|
79
85
|
{#if isSelectGroup(item)}
|
|
80
86
|
<ToolbarOption
|
|
81
87
|
size={optionSize}
|
|
@@ -87,7 +93,7 @@ const clearAll = () => emit([]);
|
|
|
87
93
|
size={optionSize}
|
|
88
94
|
indent
|
|
89
95
|
selectable={{ selected: isSelected(child.value), display: optionDisplay }}
|
|
90
|
-
on={{ click: () => toggleChild(
|
|
96
|
+
on={{ click: () => toggleChild(child) }}>{child.label}</ToolbarOption>
|
|
91
97
|
{/each}
|
|
92
98
|
{:else}
|
|
93
99
|
<ToolbarOption size={optionSize} selectable={{ selected: isSelected(item.value), display: optionDisplay }} on={{ click: () => toggleOption(item) }}
|
|
@@ -119,8 +125,11 @@ const clearAll = () => emit([]);
|
|
|
119
125
|
A compact toolbar filter dropdown: a secondary-button trigger whose label summarises the selection
|
|
120
126
|
(`Status` → `Status: Draft` → `Status: 2 selected`), and a `ToolbarOption` checklist panel with a
|
|
121
127
|
`Clear all` footer. Multi-select by default; `single` restricts to one (checkmark glyph). `options` is a
|
|
122
|
-
flat `SelectOption[]` or one level of groups (`SelectOptionGroup`)
|
|
123
|
-
|
|
128
|
+
flat `SelectOption[]` or one level of groups (`SelectOptionGroup`). Group behaviour depends on whether
|
|
129
|
+
the group has its own `value`: a label-group (no `value`) is a tri-state select-all header over its
|
|
130
|
+
children; a group WITH a `value` is an independent option — header and children toggle only themselves,
|
|
131
|
+
with no cascade or shared highlight. In `single` mode a value-group header selects its own value (re-click
|
|
132
|
+
deselects), same as any option.
|
|
124
133
|
`header` injects content above the list (preset rows, a `ToolbarSectionTitle`, …).
|
|
125
134
|
|
|
126
135
|
### CSS Custom Properties
|
|
@@ -54,8 +54,11 @@ interface $$IsomorphicComponent {
|
|
|
54
54
|
* A compact toolbar filter dropdown: a secondary-button trigger whose label summarises the selection
|
|
55
55
|
* (`Status` → `Status: Draft` → `Status: 2 selected`), and a `ToolbarOption` checklist panel with a
|
|
56
56
|
* `Clear all` footer. Multi-select by default; `single` restricts to one (checkmark glyph). `options` is a
|
|
57
|
-
* flat `SelectOption[]` or one level of groups (`SelectOptionGroup`)
|
|
58
|
-
*
|
|
57
|
+
* flat `SelectOption[]` or one level of groups (`SelectOptionGroup`). Group behaviour depends on whether
|
|
58
|
+
* the group has its own `value`: a label-group (no `value`) is a tri-state select-all header over its
|
|
59
|
+
* children; a group WITH a `value` is an independent option — header and children toggle only themselves,
|
|
60
|
+
* with no cascade or shared highlight. In `single` mode a value-group header selects its own value (re-click
|
|
61
|
+
* deselects), same as any option.
|
|
59
62
|
* `header` injects content above the list (preset rows, a `ToolbarSectionTitle`, …).
|
|
60
63
|
*
|
|
61
64
|
* ### CSS Custom Properties
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script lang="ts" generics="S">import { Button } from '../button';
|
|
2
|
+
import { IconText } from '../icon-text';
|
|
2
3
|
import ToolbarFilterSelect from './cmp.toolbar-filter-select.svelte';
|
|
3
4
|
import ToolbarIconButton from './cmp.toolbar-icon-button.svelte';
|
|
4
5
|
import ToolbarSectionTitle from './cmp.toolbar-section-title.svelte';
|
|
5
6
|
import { ToolbarSortSelectLocalization } from './toolbar-sort-select-localization';
|
|
7
|
+
import IconChevronDown from '@fluentui/svg-icons/icons/chevron_down_20_regular.svg?raw';
|
|
6
8
|
import IconFilter from '@fluentui/svg-icons/icons/filter_20_regular.svg?raw';
|
|
7
9
|
const { options, value, label, size = 'sm', trigger = 'icon', compare, on } = $props();
|
|
8
10
|
const localization = new ToolbarSortSelectLocalization();
|
|
@@ -21,7 +23,9 @@ const onChange = (next) => {
|
|
|
21
23
|
{/snippet}
|
|
22
24
|
|
|
23
25
|
{#snippet buttonTrigger()}
|
|
24
|
-
<Button type="presentational" variant="secondary" size={size}
|
|
26
|
+
<Button type="presentational" variant="secondary" size={size}>
|
|
27
|
+
<IconText icon={IconFilter} secondaryIcon={IconChevronDown} size={size} iconScale="large" trimText>{localization.sorting}</IconText>
|
|
28
|
+
</Button>
|
|
25
29
|
{/snippet}
|
|
26
30
|
|
|
27
31
|
<ToolbarFilterSelect
|
|
@@ -8,7 +8,7 @@ const currentLabel = $derived(currentStage?.label ?? '');
|
|
|
8
8
|
const tooltipLabel = $derived(!showLabel ? currentLabel : '');
|
|
9
9
|
const segmentColor = (s) => {
|
|
10
10
|
const value = s.color ?? 'gray';
|
|
11
|
-
return PROGRESS_BAR_TONES.includes(value) ? `var(--sc-kit--tone--${value}--
|
|
11
|
+
return PROGRESS_BAR_TONES.includes(value) ? `var(--sc-kit--tone--${value}--muted)` : value;
|
|
12
12
|
};
|
|
13
13
|
</script>
|
|
14
14
|
|
|
@@ -45,7 +45,8 @@ const segmentColor = (s) => {
|
|
|
45
45
|
Multi-stage workflow progress indicator. Pass `stages` as an array of `{ color, label? }`
|
|
46
46
|
descriptors — the bar renders one segment per stage; segments `0..stage` (inclusive) are filled,
|
|
47
47
|
the rest use the empty-segment color. Each stage's `color` is either a named tone from the shared
|
|
48
|
-
palette (
|
|
48
|
+
palette (resolved to its muted shade, e.g. `'green'` → `--sc-kit--tone--green--muted`) or a raw CSS
|
|
49
|
+
color / `var(--sc-kit--*)`. Useful
|
|
49
50
|
for content-lifecycle indicators (Ideas → Draft → Review → Scheduled → Published) in cards, table
|
|
50
51
|
cells, or post pages. `variant="pips"` renders compact fixed-size ticks (left-aligned) instead of
|
|
51
52
|
full-width segments — for dense table cells. `showLabel={false}` drops the inline current-stage
|
|
@@ -16,7 +16,8 @@ type Props = {
|
|
|
16
16
|
* Multi-stage workflow progress indicator. Pass `stages` as an array of `{ color, label? }`
|
|
17
17
|
* descriptors — the bar renders one segment per stage; segments `0..stage` (inclusive) are filled,
|
|
18
18
|
* the rest use the empty-segment color. Each stage's `color` is either a named tone from the shared
|
|
19
|
-
* palette (
|
|
19
|
+
* palette (resolved to its muted shade, e.g. `'green'` → `--sc-kit--tone--green--muted`) or a raw CSS
|
|
20
|
+
* color / `var(--sc-kit--*)`. Useful
|
|
20
21
|
* for content-lifecycle indicators (Ideas → Draft → Review → Scheduled → Published) in cards, table
|
|
21
22
|
* cells, or post pages. `variant="pips"` renders compact fixed-size ticks (left-aligned) instead of
|
|
22
23
|
* full-width segments — for dense table cells. `showLabel={false}` drops the inline current-stage
|