@streamscloud/kit 0.16.2 → 0.18.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.
Files changed (113) hide show
  1. package/dist/styles/_semantic.scss +3 -0
  2. package/dist/ui/badge/cmp.badge.svelte +4 -0
  3. package/dist/ui/badge/cmp.badge.svelte.d.ts +1 -0
  4. package/dist/ui/button/cmp.button.svelte +6 -2
  5. package/dist/ui/button/cmp.button.svelte.d.ts +1 -1
  6. package/dist/ui/date-picker/cmp.date-picker.svelte +21 -18
  7. package/dist/ui/date-picker/cmp.date-picker.svelte.d.ts +1 -1
  8. package/dist/ui/form-field/cmp.form-field-validatable.svelte +1 -1
  9. package/dist/ui/form-field/cmp.form-field-validatable.svelte.d.ts +1 -1
  10. package/dist/ui/input/cmp.input.svelte +21 -18
  11. package/dist/ui/input/cmp.input.svelte.d.ts +1 -1
  12. package/dist/ui/numeral-input/cmp.numeral-input.svelte +21 -18
  13. package/dist/ui/numeral-input/cmp.numeral-input.svelte.d.ts +1 -1
  14. package/dist/ui/page-toolbar/cmp.reorderable-checkbox-list.svelte +131 -0
  15. package/dist/ui/page-toolbar/cmp.reorderable-checkbox-list.svelte.d.ts +31 -0
  16. package/dist/ui/page-toolbar/cmp.toolbar-checkbox.svelte +14 -0
  17. package/dist/ui/page-toolbar/cmp.toolbar-checkbox.svelte.d.ts +19 -0
  18. package/dist/ui/page-toolbar/cmp.toolbar-divider.svelte +19 -0
  19. package/dist/ui/page-toolbar/cmp.toolbar-divider.svelte.d.ts +35 -0
  20. package/dist/ui/page-toolbar/cmp.toolbar-filter-select.svelte +143 -0
  21. package/dist/ui/page-toolbar/cmp.toolbar-filter-select.svelte.d.ts +68 -0
  22. package/dist/ui/page-toolbar/cmp.toolbar-icon-button.svelte +71 -0
  23. package/dist/ui/page-toolbar/cmp.toolbar-icon-button.svelte.d.ts +32 -0
  24. package/dist/ui/page-toolbar/cmp.toolbar-option.svelte +189 -0
  25. package/dist/ui/page-toolbar/cmp.toolbar-option.svelte.d.ts +47 -0
  26. package/dist/ui/page-toolbar/cmp.toolbar-popover.svelte +23 -8
  27. package/dist/ui/page-toolbar/cmp.toolbar-popover.svelte.d.ts +14 -6
  28. package/dist/ui/page-toolbar/cmp.toolbar-section-title.svelte +46 -0
  29. package/dist/ui/page-toolbar/cmp.toolbar-section-title.svelte.d.ts +24 -0
  30. package/dist/ui/page-toolbar/cmp.toolbar-sort-select.svelte +31 -0
  31. package/dist/ui/page-toolbar/cmp.toolbar-sort-select.svelte.d.ts +44 -0
  32. package/dist/ui/page-toolbar/{cmp.toolbar-switch-item.svelte → cmp.toolbar-switch.svelte} +10 -10
  33. package/dist/ui/page-toolbar/{cmp.toolbar-switch-item.svelte.d.ts → cmp.toolbar-switch.svelte.d.ts} +2 -2
  34. package/dist/ui/page-toolbar/cmp.toolbar-toggle.svelte +14 -0
  35. package/dist/ui/page-toolbar/cmp.toolbar-toggle.svelte.d.ts +19 -0
  36. package/dist/ui/page-toolbar/cmp.toolbar-value-stepper.svelte +4 -1
  37. package/dist/ui/page-toolbar/cmp.toolbar-view-controls.svelte +51 -0
  38. package/dist/ui/page-toolbar/cmp.toolbar-view-controls.svelte.d.ts +27 -0
  39. package/dist/ui/page-toolbar/index.d.ts +12 -7
  40. package/dist/ui/page-toolbar/index.js +11 -6
  41. package/dist/ui/page-toolbar/reorderable-checkbox-list-localization.d.ts +5 -0
  42. package/dist/ui/page-toolbar/reorderable-checkbox-list-localization.js +17 -0
  43. package/dist/ui/page-toolbar/toolbar-filter-select-localization.d.ts +5 -0
  44. package/dist/ui/page-toolbar/toolbar-filter-select-localization.js +20 -0
  45. package/dist/ui/page-toolbar/toolbar-sort-select-localization.d.ts +3 -0
  46. package/dist/ui/page-toolbar/toolbar-sort-select-localization.js +9 -0
  47. package/dist/ui/page-toolbar/toolbar-view-controls-localization.d.ts +5 -0
  48. package/dist/ui/page-toolbar/toolbar-view-controls-localization.js +17 -0
  49. package/dist/ui/page-toolbar/types.d.ts +1 -1
  50. package/dist/ui/rich-text-input/cmp.rich-text-input.svelte +9 -6
  51. package/dist/ui/rich-text-input/cmp.rich-text-input.svelte.d.ts +1 -1
  52. package/dist/ui/segmented-control/cmp.segmented-control.svelte +4 -2
  53. package/dist/ui/segmented-control/cmp.segmented-control.svelte.d.ts +1 -1
  54. package/dist/ui/select/_select-trigger.scss +20 -17
  55. package/dist/ui/select/cmp.singleselect-async.svelte +20 -17
  56. package/dist/ui/select/index.d.ts +1 -0
  57. package/dist/ui/select/index.js +1 -0
  58. package/dist/ui/select/multiselect-base.svelte +21 -18
  59. package/dist/ui/select/select-listbox.svelte +11 -5
  60. package/dist/ui/select/select-listbox.svelte.d.ts +1 -1
  61. package/dist/ui/table/_table-styles.scss +156 -0
  62. package/dist/ui/table/cmp.table-draggable.svelte +338 -0
  63. package/dist/ui/table/cmp.table-draggable.svelte.d.ts +79 -0
  64. package/dist/ui/table/cmp.table.svelte +96 -265
  65. package/dist/ui/table/cmp.table.svelte.d.ts +16 -8
  66. package/dist/ui/table/index.d.ts +1 -0
  67. package/dist/ui/table/index.js +1 -0
  68. package/dist/ui/table/table-cells/index.d.ts +1 -12
  69. package/dist/ui/table/table-cells/index.js +1 -12
  70. package/dist/ui/table/table-cells/table-cell.svelte +77 -0
  71. package/dist/ui/table/table-cells/{table-select-cell.svelte.d.ts → table-cell.svelte.d.ts} +12 -6
  72. package/dist/ui/table/table-column-models.svelte.d.ts +1 -2
  73. package/dist/ui/table/table-column-models.svelte.js +0 -1
  74. package/dist/ui/table/table-columns-manager/cmp.table-columns-manager.svelte +20 -47
  75. package/dist/ui/table/table-columns-manager/cmp.table-columns-manager.svelte.d.ts +3 -7
  76. package/dist/ui/table/table-columns-manager/table-columns-manager-localization.d.ts +1 -1
  77. package/dist/ui/table/table-columns-manager/table-columns-manager-localization.js +7 -7
  78. package/dist/ui/table/table-localization.d.ts +0 -2
  79. package/dist/ui/table/table-localization.js +0 -14
  80. package/dist/ui/table/table-model.svelte.d.ts +2 -3
  81. package/dist/ui/table/table-model.svelte.js +5 -35
  82. package/dist/ui/table/table-view.svelte.d.ts +14 -0
  83. package/dist/ui/table/table-view.svelte.js +32 -0
  84. package/dist/ui/table/types.d.ts +5 -28
  85. package/dist/ui/textarea/cmp.textarea.svelte +17 -14
  86. package/dist/ui/textarea/cmp.textarea.svelte.d.ts +1 -1
  87. package/dist/ui/toggle/cmp.toggle.svelte +32 -26
  88. package/dist/ui/toggle/cmp.toggle.svelte.d.ts +2 -0
  89. package/dist/ui/tree/cmp.tree-node-view.svelte +7 -2
  90. package/dist/ui/tree/cmp.tree.svelte +9 -1
  91. package/dist/ui/tree/cmp.tree.svelte.d.ts +1 -1
  92. package/dist/ui/tree/tree-navigation.svelte.d.ts +2 -0
  93. package/dist/ui/tree/tree-navigation.svelte.js +3 -0
  94. package/dist/ui/validatable/cmp.validatable.svelte +5 -5
  95. package/dist/ui/validatable/cmp.validatable.svelte.d.ts +2 -2
  96. package/dist/ui/validatable/cmp.validation-error.svelte +4 -4
  97. package/dist/ui/validatable/cmp.validation-error.svelte.d.ts +1 -1
  98. package/dist/ui/validatable/{cmp.field-error.svelte → field-frame.svelte} +6 -6
  99. package/dist/ui/validatable/{cmp.field-error.svelte.d.ts → field-frame.svelte.d.ts} +4 -4
  100. package/package.json +1 -1
  101. package/dist/ui/page-toolbar/cmp.reorderable-toggle-list.svelte +0 -153
  102. package/dist/ui/page-toolbar/cmp.reorderable-toggle-list.svelte.d.ts +0 -20
  103. package/dist/ui/page-toolbar/cmp.toolbar-checkbox-item.svelte +0 -19
  104. package/dist/ui/page-toolbar/cmp.toolbar-checkbox-item.svelte.d.ts +0 -12
  105. package/dist/ui/page-toolbar/cmp.toolbar-panel-button.svelte +0 -42
  106. package/dist/ui/page-toolbar/cmp.toolbar-panel-button.svelte.d.ts +0 -20
  107. package/dist/ui/page-toolbar/cmp.toolbar-panel.svelte +0 -57
  108. package/dist/ui/page-toolbar/cmp.toolbar-panel.svelte.d.ts +0 -19
  109. package/dist/ui/page-toolbar/cmp.toolbar-toggle-item.svelte +0 -16
  110. package/dist/ui/page-toolbar/cmp.toolbar-toggle-item.svelte.d.ts +0 -12
  111. package/dist/ui/table/table-cells/table-select-cell.svelte +0 -28
  112. package/dist/ui/table/table-cells/table-text-input-cell.svelte +0 -69
  113. package/dist/ui/table/table-cells/table-text-input-cell.svelte.d.ts +0 -38
@@ -0,0 +1,35 @@
1
+ export default Cmp;
2
+ type Cmp = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ /**
10
+ * A thin horizontal separator for toolbar dropdown panels — use between option groups or above a
11
+ * footer. Compose it freely inside a `ToolbarFilterSelect` footer snippet.
12
+ *
13
+ * ### CSS Custom Properties
14
+ * | Property | Description | Default |
15
+ * |---|---|---|
16
+ * | `--sc-kit--toolbar-divider--color` | Line color | `var(--sc-kit--color--border)` |
17
+ */
18
+ declare const Cmp: $$__sveltets_2_IsomorphicComponent<{
19
+ [x: string]: never;
20
+ }, {
21
+ [evt: string]: CustomEvent<any>;
22
+ }, {}, {}, string>;
23
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
24
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
25
+ $$bindings?: Bindings;
26
+ } & Exports;
27
+ (internal: unknown, props: {
28
+ $$events?: Events;
29
+ $$slots?: Slots;
30
+ }): Exports & {
31
+ $set?: any;
32
+ $on?: any;
33
+ };
34
+ z_$$bindings?: Bindings;
35
+ }
@@ -0,0 +1,143 @@
1
+ <script lang="ts" generics="T">import { Button } from '../button';
2
+ import { IconText } from '../icon-text';
3
+ import { Popover } from '../popover';
4
+ import { isSelectGroup } from '../select';
5
+ import ToolbarDivider from './cmp.toolbar-divider.svelte';
6
+ import ToolbarOption from './cmp.toolbar-option.svelte';
7
+ import { ToolbarFilterSelectLocalization } from './toolbar-filter-select-localization';
8
+ import IconChevronDown from '@fluentui/svg-icons/icons/chevron_down_20_regular.svg?raw';
9
+ const { label, options, value, icon, header, footer, size = 'sm', trigger, borderless = false, optionSize = 'md', single = false, position = 'bottom-start', compare, on } = $props();
10
+ const localization = new ToolbarFilterSelectLocalization();
11
+ const eq = (a, b) => (compare ? compare(a, b) : a === b);
12
+ const isSelected = (candidate) => value.some((selected) => eq(selected, candidate));
13
+ const withValue = (list, candidate) => (list.some((item) => eq(item, candidate)) ? list : [...list, candidate]);
14
+ const without = (list, candidate) => list.filter((item) => !eq(item, candidate));
15
+ const optionDisplay = $derived(single ? 'checkmark' : 'checkbox');
16
+ const leaves = $derived(options.flatMap((item) => (isSelectGroup(item) ? item.options : [item])));
17
+ const selectedLeaves = $derived(leaves.filter((leaf) => isSelected(leaf.value)));
18
+ const summary = $derived.by(() => {
19
+ if (selectedLeaves.length === 0) {
20
+ return label;
21
+ }
22
+ if (selectedLeaves.length === 1) {
23
+ return `${label}: ${selectedLeaves[0].label}`;
24
+ }
25
+ return `${label}: ${localization.selectedCount(selectedLeaves.length)}`;
26
+ });
27
+ const groupSelected = (group) => {
28
+ const selectedCount = group.options.filter((option) => isSelected(option.value)).length;
29
+ if (selectedCount === 0) {
30
+ return false;
31
+ }
32
+ return selectedCount === group.options.length ? true : 'indeterminate';
33
+ };
34
+ const emit = (next) => on?.change?.(next);
35
+ const pickSingle = (candidate) => emit(isSelected(candidate) ? [] : [candidate]);
36
+ const toggleOption = (option) => {
37
+ if (single) {
38
+ pickSingle(option.value);
39
+ return;
40
+ }
41
+ emit(isSelected(option.value) ? without(value, option.value) : withValue(value, option.value));
42
+ };
43
+ const toggleGroup = (group) => {
44
+ if (single) {
45
+ return;
46
+ }
47
+ const allSelected = group.options.every((option) => isSelected(option.value));
48
+ let next = value;
49
+ for (const option of group.options) {
50
+ next = allSelected ? without(next, option.value) : withValue(next, option.value);
51
+ }
52
+ if (group.value !== undefined) {
53
+ next = allSelected ? without(next, group.value) : withValue(next, group.value);
54
+ }
55
+ emit(next);
56
+ };
57
+ const toggleChild = (group, child) => {
58
+ if (single) {
59
+ pickSingle(child.value);
60
+ return;
61
+ }
62
+ let next = isSelected(child.value) ? without(value, child.value) : withValue(value, child.value);
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);
68
+ };
69
+ const clearAll = () => emit([]);
70
+ </script>
71
+
72
+ <div class="toolbar-filter-select">
73
+ <Popover position={position} keepOpen aria-label={trigger ? label : undefined} trigger={triggerContent}>
74
+ <div class="filter">
75
+ {#if header}
76
+ {@render header()}
77
+ {/if}
78
+ {#each options as item (isSelectGroup(item) ? item.label : item.value)}
79
+ {#if isSelectGroup(item)}
80
+ <ToolbarOption
81
+ size={optionSize}
82
+ variant="emphasis"
83
+ selectable={{ selected: groupSelected(item), display: optionDisplay }}
84
+ on={{ click: () => toggleGroup(item) }}>{item.label}</ToolbarOption>
85
+ {#each item.options as child (child.value)}
86
+ <ToolbarOption
87
+ size={optionSize}
88
+ indent
89
+ selectable={{ selected: isSelected(child.value), display: optionDisplay }}
90
+ on={{ click: () => toggleChild(item, child) }}>{child.label}</ToolbarOption>
91
+ {/each}
92
+ {:else}
93
+ <ToolbarOption size={optionSize} selectable={{ selected: isSelected(item.value), display: optionDisplay }} on={{ click: () => toggleOption(item) }}
94
+ >{item.label}</ToolbarOption>
95
+ {/if}
96
+ {/each}
97
+ {#if footer}
98
+ {@render footer()}
99
+ {:else if footer !== false && value.length > 0}
100
+ <ToolbarDivider />
101
+ <ToolbarOption size={optionSize} variant="muted" on={{ click: clearAll }}>{single ? localization.clear : localization.clearAll}</ToolbarOption>
102
+ {/if}
103
+ </div>
104
+ </Popover>
105
+ </div>
106
+
107
+ {#snippet triggerContent()}
108
+ {#if trigger}
109
+ {@render trigger()}
110
+ {:else}
111
+ <Button type="presentational" variant={borderless ? 'ghost' : 'secondary'} size={size}>
112
+ <IconText icon={icon} secondaryIcon={IconChevronDown} size={size} iconScale="large" trimText>{summary}</IconText>
113
+ </Button>
114
+ {/if}
115
+ {/snippet}
116
+
117
+ <!--
118
+ @component
119
+ A compact toolbar filter dropdown: a secondary-button trigger whose label summarises the selection
120
+ (`Status` → `Status: Draft` → `Status: 2 selected`), and a `ToolbarOption` checklist panel with a
121
+ `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`) for a tree with a tri-state parent
123
+ row and `children-include-parent` cascade.
124
+ `header` injects content above the list (preset rows, a `ToolbarSectionTitle`, …).
125
+
126
+ ### CSS Custom Properties
127
+ | Property | Description | Default |
128
+ |---|---|---|
129
+ | `--sc-kit--toolbar-filter-select--trigger--max-width` | Trigger max width before the label truncates | `13.75rem` (220px) |
130
+ -->
131
+
132
+ <style>.toolbar-filter-select {
133
+ display: contents;
134
+ --sc-kit--popover--content--padding: var(--sc-kit--space--2);
135
+ --sc-kit--button--max-width: var(--sc-kit--toolbar-filter-select--trigger--max-width, 13.75rem);
136
+ }
137
+
138
+ .filter {
139
+ display: flex;
140
+ flex-direction: column;
141
+ gap: 0.125rem;
142
+ min-inline-size: 12.5rem;
143
+ }</style>
@@ -0,0 +1,68 @@
1
+ import type { IconProp } from '../icon';
2
+ import { type SelectItem } from '../select';
3
+ import type { Placement } from '@floating-ui/dom';
4
+ import type { Snippet } from 'svelte';
5
+ declare function $$render<T>(): {
6
+ props: {
7
+ label: string;
8
+ options: SelectItem<T>[];
9
+ value: T[];
10
+ /** Leading icon on the trigger button. */
11
+ icon?: IconProp;
12
+ /** Content rendered above the options list (e.g. preset rows + a `ToolbarSectionTitle`). */
13
+ header?: Snippet;
14
+ /** Trigger button density. @default 'sm' */
15
+ size?: "sm" | "md";
16
+ /** Custom presentational trigger content — replaces the default summary button. The popover is named by `label` (so an icon-only trigger stays accessible). */
17
+ trigger?: Snippet;
18
+ /** Render the default summary trigger as a borderless (ghost) button instead of secondary. @default false */
19
+ borderless?: boolean;
20
+ /** Option row density. @default 'md' */
21
+ optionSize?: "sm" | "md";
22
+ /** Restrict the selection to a single item — picking one replaces the previous (single-select). @default false */
23
+ single?: boolean;
24
+ /** Footer below the options: a snippet replaces the default `Clear all`; `false` removes it entirely. The default `Clear all` shows only while something is selected. A divider is drawn only when a footer renders. */
25
+ footer?: Snippet | false;
26
+ /** @default 'bottom-start' */
27
+ position?: Placement;
28
+ /** Equality comparator for `T`. Required when `T` is an object. @default (a, b) => a === b */
29
+ compare?: (a: T, b: T) => boolean;
30
+ on?: {
31
+ change?: (value: T[]) => void;
32
+ };
33
+ };
34
+ exports: {};
35
+ bindings: "";
36
+ slots: {};
37
+ events: {};
38
+ };
39
+ declare class __sveltets_Render<T> {
40
+ props(): ReturnType<typeof $$render<T>>['props'];
41
+ events(): ReturnType<typeof $$render<T>>['events'];
42
+ slots(): ReturnType<typeof $$render<T>>['slots'];
43
+ bindings(): "";
44
+ exports(): {};
45
+ }
46
+ interface $$IsomorphicComponent {
47
+ new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
48
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
49
+ } & ReturnType<__sveltets_Render<T>['exports']>;
50
+ <T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
51
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
52
+ }
53
+ /**
54
+ * A compact toolbar filter dropdown: a secondary-button trigger whose label summarises the selection
55
+ * (`Status` → `Status: Draft` → `Status: 2 selected`), and a `ToolbarOption` checklist panel with a
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`) for a tree with a tri-state parent
58
+ * row and `children-include-parent` cascade.
59
+ * `header` injects content above the list (preset rows, a `ToolbarSectionTitle`, …).
60
+ *
61
+ * ### CSS Custom Properties
62
+ * | Property | Description | Default |
63
+ * |---|---|---|
64
+ * | `--sc-kit--toolbar-filter-select--trigger--max-width` | Trigger max width before the label truncates | `13.75rem` (220px) |
65
+ */
66
+ declare const Cmp: $$IsomorphicComponent;
67
+ type Cmp<T> = InstanceType<typeof Cmp<T>>;
68
+ export default Cmp;
@@ -0,0 +1,71 @@
1
+ <script lang="ts">import { Icon } from '../icon';
2
+ const { icon, 'aria-label': ariaLabel, size = 'sm', active = false, disabled = false, presentational = false, on } = $props();
3
+ </script>
4
+
5
+ {#if presentational}
6
+ <span class="toolbar-icon-button toolbar-icon-button--{size}" class:toolbar-icon-button--active={active}>
7
+ <Icon src={icon} size="md" />
8
+ </span>
9
+ {:else}
10
+ <button
11
+ type="button"
12
+ class="toolbar-icon-button toolbar-icon-button--{size}"
13
+ class:toolbar-icon-button--active={active}
14
+ disabled={disabled}
15
+ aria-label={ariaLabel}
16
+ aria-pressed={active}
17
+ onclick={() => on?.click?.()}>
18
+ <Icon src={icon} size="md" />
19
+ </button>
20
+ {/if}
21
+
22
+ <!--
23
+ @component
24
+ A flat, square toolbar icon button (28px at `sm`, 32px at `md`, with a 20px glyph). Background appears on
25
+ hover only; `active` tints the glyph with the accent color (no background). Pass `presentational` to render
26
+ a non-interactive `<span>` for use inside a wrapper that owns the click + semantics (e.g. a Popover trigger).
27
+ Shared by `ToolbarViewControls` and the `ToolbarFilterSelect` icon trigger so they stay visually identical.
28
+
29
+ ### CSS Custom Properties
30
+ | Property | Description | Default |
31
+ |---|---|---|
32
+ | `--sc-kit--toolbar-icon-button--color` | Idle glyph color | `var(--sc-kit--color--text--muted)` |
33
+ | `--sc-kit--toolbar-icon-button--color--active` | Active glyph color | `var(--sc-kit--color--accent)` |
34
+ | `--sc-kit--toolbar-icon-button--background--hover` | Hover background | `var(--sc-kit--color--bg--hover)` |
35
+ -->
36
+
37
+ <style>.toolbar-icon-button {
38
+ --_tib--color: var(--sc-kit--toolbar-icon-button--color, var(--sc-kit--color--text--muted));
39
+ --_tib--color-active: var(--sc-kit--toolbar-icon-button--color--active, var(--sc-kit--color--accent));
40
+ --_tib--background-hover: var(--sc-kit--toolbar-icon-button--background--hover, var(--sc-kit--color--bg--hover));
41
+ --_tib--size: var(--_tib--size-height);
42
+ --sc-kit--icon--color: var(--_tib--color);
43
+ display: inline-flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ flex-shrink: 0;
47
+ inline-size: var(--_tib--size);
48
+ block-size: var(--_tib--size);
49
+ padding: 0;
50
+ border: 0;
51
+ background: transparent;
52
+ border-radius: var(--sc-kit--field--border-radius--sm);
53
+ cursor: pointer;
54
+ transition: background-color var(--sc-kit--duration--base) var(--sc-kit--ease--default), color var(--sc-kit--duration--base) var(--sc-kit--ease--default);
55
+ }
56
+ .toolbar-icon-button--sm {
57
+ --_tib--size-height: var(--sc-kit--field--height--sm);
58
+ }
59
+ .toolbar-icon-button--md {
60
+ --_tib--size-height: var(--sc-kit--field--height--md);
61
+ }
62
+ .toolbar-icon-button:hover {
63
+ background: var(--_tib--background-hover);
64
+ }
65
+ .toolbar-icon-button--active {
66
+ --sc-kit--icon--color: var(--_tib--color-active);
67
+ }
68
+ .toolbar-icon-button:disabled {
69
+ cursor: default;
70
+ opacity: 0.5;
71
+ }</style>
@@ -0,0 +1,32 @@
1
+ type Props = {
2
+ /** Glyph — a string SVG source. */
3
+ icon: string;
4
+ /** Accessible name. Required for the interactive button; omit for `presentational` (the wrapper owns the name). */
5
+ 'aria-label'?: string;
6
+ /** Button size — sm = 28px, md = 32px. @default 'sm' */
7
+ size?: 'sm' | 'md';
8
+ /** Selected state — tints the glyph with the accent color (no background). */
9
+ active?: boolean;
10
+ disabled?: boolean;
11
+ /** Render a non-interactive `<span>` for embedding inside another interactive wrapper (e.g. a Popover trigger). @default false */
12
+ presentational?: boolean;
13
+ on?: {
14
+ click?: () => void;
15
+ };
16
+ };
17
+ /**
18
+ * A flat, square toolbar icon button (28px at `sm`, 32px at `md`, with a 20px glyph). Background appears on
19
+ * hover only; `active` tints the glyph with the accent color (no background). Pass `presentational` to render
20
+ * a non-interactive `<span>` for use inside a wrapper that owns the click + semantics (e.g. a Popover trigger).
21
+ * Shared by `ToolbarViewControls` and the `ToolbarFilterSelect` icon trigger so they stay visually identical.
22
+ *
23
+ * ### CSS Custom Properties
24
+ * | Property | Description | Default |
25
+ * |---|---|---|
26
+ * | `--sc-kit--toolbar-icon-button--color` | Idle glyph color | `var(--sc-kit--color--text--muted)` |
27
+ * | `--sc-kit--toolbar-icon-button--color--active` | Active glyph color | `var(--sc-kit--color--accent)` |
28
+ * | `--sc-kit--toolbar-icon-button--background--hover` | Hover background | `var(--sc-kit--color--bg--hover)` |
29
+ */
30
+ declare const Cmp: import("svelte").Component<Props, {}, "">;
31
+ type Cmp = ReturnType<typeof Cmp>;
32
+ export default Cmp;
@@ -0,0 +1,189 @@
1
+ <script lang="ts">import { Icon } from '../icon';
2
+ import { Toggle } from '../toggle';
3
+ import IconCheckboxChecked from '@fluentui/svg-icons/icons/checkbox_checked_16_filled.svg?raw';
4
+ import IconCheckboxIndeterminate from '@fluentui/svg-icons/icons/checkbox_indeterminate_16_filled.svg?raw';
5
+ import IconCheckboxUnchecked from '@fluentui/svg-icons/icons/checkbox_unchecked_16_regular.svg?raw';
6
+ import IconCheckmark from '@fluentui/svg-icons/icons/checkmark_16_regular.svg?raw';
7
+ const { selectable, size = 'md', variant = 'normal', indent = false, disabled = false, prepend, children, on } = $props();
8
+ const display = $derived(selectable?.display ?? 'checkbox');
9
+ const checkboxState = $derived(selectable?.selected === 'indeterminate' ? 'indeterminate' : selectable?.selected ? 'checked' : 'unchecked');
10
+ const isChecked = $derived(selectable?.selected === true);
11
+ const tinted = $derived(isChecked && variant === 'normal');
12
+ const strong = $derived(isChecked && display === 'checkmark');
13
+ const ariaChecked = $derived(selectable && display === 'checkbox' ? (checkboxState === 'indeterminate' ? 'mixed' : checkboxState === 'checked') : undefined);
14
+ const ariaPressed = $derived(selectable && display !== 'checkbox' ? isChecked : undefined);
15
+ </script>
16
+
17
+ <button
18
+ type="button"
19
+ class="toolbar-option toolbar-option--{size} toolbar-option--{variant}"
20
+ class:toolbar-option--selected={tinted}
21
+ class:toolbar-option--strong={strong}
22
+ class:toolbar-option--indent={indent}
23
+ class:toolbar-option--disabled={disabled}
24
+ class:toolbar-option--muted-sm={variant === 'muted' && size === 'sm'}
25
+ class:toolbar-option--muted-md={variant === 'muted' && size === 'md'}
26
+ disabled={disabled}
27
+ role={selectable && display === 'checkbox' ? 'checkbox' : undefined}
28
+ aria-checked={ariaChecked}
29
+ aria-pressed={ariaPressed}
30
+ onclick={() => on?.click?.()}>
31
+ {#if prepend}
32
+ <span class="toolbar-option__prepend">{@render prepend()}</span>
33
+ {/if}
34
+ {#if selectable && display === 'checkbox'}
35
+ <span class="toolbar-option__check toolbar-option__check--{checkboxState}">
36
+ {#if checkboxState === 'checked'}
37
+ <Icon src={IconCheckboxChecked} />
38
+ {:else if checkboxState === 'indeterminate'}
39
+ <Icon src={IconCheckboxIndeterminate} />
40
+ {:else}
41
+ <Icon src={IconCheckboxUnchecked} />
42
+ {/if}
43
+ </span>
44
+ {/if}
45
+ <span class="toolbar-option__label">{@render children()}</span>
46
+ {#if selectable && display === 'checkmark'}
47
+ <span class="toolbar-option__checkmark" class:toolbar-option__checkmark--hidden={!isChecked}><Icon src={IconCheckmark} /></span>
48
+ {:else if selectable && display === 'switch'}
49
+ <span class="toolbar-option__switch"><Toggle presentational checked={isChecked} disabled={disabled} /></span>
50
+ {/if}
51
+ </button>
52
+
53
+ <!--
54
+ @component
55
+ A single row for toolbar dropdowns, matching the kit select listbox options. Pass `selectable` for a
56
+ multi (`display='checkbox'`, tri-state) or single (`display='checkmark'`) option; omit it for a plain
57
+ button-like row. `variant` covers group headers (`emphasis`) and secondary actions (`muted`). Mix
58
+ these — plus `ToolbarSectionTitle` — inside one panel to build column / field pickers.
59
+
60
+ ### CSS Custom Properties
61
+ | Property | Description | Default |
62
+ |---|---|---|
63
+ | `--sc-kit--toolbar-option--height` | Row height | per size (28 / 32px) |
64
+ | `--sc-kit--toolbar-option--padding-inline` | Horizontal padding | per size |
65
+ | `--sc-kit--toolbar-option--font-size` | Label font size | per size |
66
+ | `--sc-kit--toolbar-option--gap` | Gap between glyph and label | `var(--sc-kit--space--2)` |
67
+ | `--sc-kit--toolbar-option--border-radius` | Corner radius | `var(--sc-kit--radius--sm)` |
68
+ | `--sc-kit--toolbar-option--color` | Label color | `var(--sc-kit--color--text--primary)` |
69
+ | `--sc-kit--toolbar-option--color--selected` | Selected label + glyph color | `var(--sc-kit--color--accent)` |
70
+ | `--sc-kit--toolbar-option--color--muted` | `muted` variant color | `var(--sc-kit--color--text--secondary)` |
71
+ | `--sc-kit--toolbar-option--background--hover` | Hover background | `var(--sc-kit--color--accent--softer)` |
72
+ | `--sc-kit--toolbar-option--glyph--color` | Unselected checkbox glyph color | `var(--sc-kit--color--text--muted)` |
73
+ | `--sc-kit--toolbar-option--glyph--size` | Selection glyph (checkbox / checkmark) size | per size (14 / 16px) |
74
+ -->
75
+
76
+ <style>.toolbar-option {
77
+ --_opt--height: var(--sc-kit--toolbar-option--height, var(--_opt--size-height));
78
+ --_opt--padding-inline: var(--sc-kit--toolbar-option--padding-inline, var(--_opt--size-padding-inline));
79
+ --_opt--font-size: var(--sc-kit--toolbar-option--font-size, var(--_opt--size-font-size));
80
+ --_opt--gap: var(--sc-kit--toolbar-option--gap, var(--sc-kit--space--2));
81
+ --_opt--border-radius: var(--sc-kit--toolbar-option--border-radius, var(--sc-kit--radius--sm));
82
+ --_opt--color: var(--sc-kit--toolbar-option--color, var(--sc-kit--color--text--primary));
83
+ --_opt--color-selected: var(--sc-kit--toolbar-option--color--selected, var(--sc-kit--color--accent));
84
+ --_opt--color-muted: var(--sc-kit--toolbar-option--color--muted, var(--sc-kit--color--text--secondary));
85
+ --_opt--background-hover: var(--sc-kit--toolbar-option--background--hover, var(--sc-kit--color--accent--softer));
86
+ --_opt--glyph-color: var(--sc-kit--toolbar-option--glyph--color, var(--sc-kit--color--text--muted));
87
+ --_opt--glyph-size: var(--sc-kit--toolbar-option--glyph--size, var(--_opt--size-glyph-size));
88
+ appearance: none;
89
+ border: 0;
90
+ background: transparent;
91
+ text-align: inherit;
92
+ cursor: pointer;
93
+ user-select: none;
94
+ display: flex;
95
+ align-items: center;
96
+ gap: var(--_opt--gap);
97
+ flex-shrink: 0;
98
+ inline-size: 100%;
99
+ block-size: var(--_opt--height);
100
+ padding-block: 0;
101
+ padding-inline: var(--_opt--padding-inline);
102
+ border-radius: var(--_opt--border-radius);
103
+ color: var(--_opt--color);
104
+ font-size: var(--_opt--font-size);
105
+ line-height: var(--sc-kit--leading--tight);
106
+ transition: background-color var(--sc-kit--duration--base) var(--sc-kit--ease--default), color var(--sc-kit--duration--base) var(--sc-kit--ease--default);
107
+ }
108
+ .toolbar-option--sm {
109
+ --_opt--size-height: var(--sc-kit--field--height--sm);
110
+ --_opt--size-padding-inline: var(--sc-kit--space--2);
111
+ --_opt--size-font-size: var(--sc-kit--font-size--sm);
112
+ --_opt--size-glyph-size: var(--sc-kit--field--icon--size--sm);
113
+ }
114
+ .toolbar-option--md {
115
+ --_opt--size-height: var(--sc-kit--field--height--md);
116
+ --_opt--size-padding-inline: var(--sc-kit--space--3);
117
+ --_opt--size-font-size: var(--sc-kit--font-size--md);
118
+ --_opt--size-glyph-size: var(--sc-kit--field--icon--size--md);
119
+ }
120
+ .toolbar-option:hover {
121
+ background: var(--_opt--background-hover);
122
+ }
123
+ .toolbar-option--indent {
124
+ padding-inline-start: calc(var(--_opt--padding-inline) + var(--_opt--glyph-size) + var(--_opt--gap));
125
+ }
126
+ .toolbar-option--selected {
127
+ --_opt--color: var(--_opt--color-selected);
128
+ }
129
+ .toolbar-option--strong {
130
+ font-weight: var(--sc-kit--font-weight--semibold);
131
+ }
132
+ .toolbar-option--emphasis {
133
+ font-weight: var(--sc-kit--font-weight--semibold);
134
+ }
135
+ .toolbar-option--muted {
136
+ --_opt--color: var(--_opt--color-muted);
137
+ }
138
+ .toolbar-option--muted-sm {
139
+ --_opt--size-font-size: var(--sc-kit--font-size--xs);
140
+ }
141
+ .toolbar-option--muted-md {
142
+ --_opt--size-font-size: var(--sc-kit--font-size--sm);
143
+ }
144
+ .toolbar-option--disabled {
145
+ --_opt--color: var(--sc-kit--color--text--muted);
146
+ cursor: default;
147
+ }
148
+ .toolbar-option__prepend {
149
+ flex-shrink: 0;
150
+ display: inline-flex;
151
+ align-items: center;
152
+ }
153
+ .toolbar-option__check {
154
+ --sc-kit--icon--size: var(--_opt--glyph-size);
155
+ --sc-kit--icon--color: var(--_opt--glyph-color);
156
+ flex-shrink: 0;
157
+ display: inline-flex;
158
+ align-items: center;
159
+ }
160
+ .toolbar-option__check--checked, .toolbar-option__check--indeterminate {
161
+ --sc-kit--icon--color: var(--_opt--color-selected);
162
+ }
163
+ .toolbar-option__label {
164
+ flex: 1;
165
+ min-width: 0;
166
+ text-overflow: ellipsis;
167
+ max-width: 100%;
168
+ white-space: nowrap;
169
+ overflow: hidden;
170
+ }
171
+ .toolbar-option__checkmark {
172
+ --sc-kit--icon--size: var(--_opt--glyph-size);
173
+ --sc-kit--icon--color: var(--_opt--color-selected);
174
+ flex-shrink: 0;
175
+ display: inline-flex;
176
+ align-items: center;
177
+ }
178
+ .toolbar-option__checkmark--hidden {
179
+ visibility: hidden;
180
+ }
181
+ .toolbar-option__switch {
182
+ flex-shrink: 0;
183
+ display: inline-flex;
184
+ align-items: center;
185
+ --sc-kit--toggle--track-height: var(--_opt--glyph-size);
186
+ --sc-kit--toggle--track-width: calc(var(--_opt--glyph-size) * 1.8);
187
+ --sc-kit--toggle--thumb-size: calc(var(--_opt--glyph-size) - 0.25rem);
188
+ --sc-kit--toggle--thumb-travel: calc(var(--_opt--glyph-size) * 0.8);
189
+ }</style>
@@ -0,0 +1,47 @@
1
+ import type { Snippet } from 'svelte';
2
+ type Selectable = {
3
+ selected: boolean | 'indeterminate';
4
+ /** Glyph for the selection: a left checkbox (multi), a right checkmark (single / preset), or a right switch (toggle). @default 'checkbox' */
5
+ display?: 'checkbox' | 'checkmark' | 'switch';
6
+ };
7
+ type Props = {
8
+ /** Selection behavior. Omit entirely for a plain, button-like row (e.g. a `Clear all` action). */
9
+ selectable?: Selectable;
10
+ /** Row density. @default 'md' */
11
+ size?: 'sm' | 'md';
12
+ /** Label treatment: `emphasis` = semibold, never tinted (group headers); `muted` = dimmed + one step smaller font (secondary actions). @default 'normal' */
13
+ variant?: 'normal' | 'emphasis' | 'muted';
14
+ /** Indent under a section title / group header. @default false */
15
+ indent?: boolean;
16
+ disabled?: boolean;
17
+ /** Leading content drawn before the standard glyph + label, inside the option's own padding / gap (e.g. a drag handle). */
18
+ prepend?: Snippet;
19
+ children: Snippet;
20
+ on?: {
21
+ click?: () => void;
22
+ };
23
+ };
24
+ /**
25
+ * A single row for toolbar dropdowns, matching the kit select listbox options. Pass `selectable` for a
26
+ * multi (`display='checkbox'`, tri-state) or single (`display='checkmark'`) option; omit it for a plain
27
+ * button-like row. `variant` covers group headers (`emphasis`) and secondary actions (`muted`). Mix
28
+ * these — plus `ToolbarSectionTitle` — inside one panel to build column / field pickers.
29
+ *
30
+ * ### CSS Custom Properties
31
+ * | Property | Description | Default |
32
+ * |---|---|---|
33
+ * | `--sc-kit--toolbar-option--height` | Row height | per size (28 / 32px) |
34
+ * | `--sc-kit--toolbar-option--padding-inline` | Horizontal padding | per size |
35
+ * | `--sc-kit--toolbar-option--font-size` | Label font size | per size |
36
+ * | `--sc-kit--toolbar-option--gap` | Gap between glyph and label | `var(--sc-kit--space--2)` |
37
+ * | `--sc-kit--toolbar-option--border-radius` | Corner radius | `var(--sc-kit--radius--sm)` |
38
+ * | `--sc-kit--toolbar-option--color` | Label color | `var(--sc-kit--color--text--primary)` |
39
+ * | `--sc-kit--toolbar-option--color--selected` | Selected label + glyph color | `var(--sc-kit--color--accent)` |
40
+ * | `--sc-kit--toolbar-option--color--muted` | `muted` variant color | `var(--sc-kit--color--text--secondary)` |
41
+ * | `--sc-kit--toolbar-option--background--hover` | Hover background | `var(--sc-kit--color--accent--softer)` |
42
+ * | `--sc-kit--toolbar-option--glyph--color` | Unselected checkbox glyph color | `var(--sc-kit--color--text--muted)` |
43
+ * | `--sc-kit--toolbar-option--glyph--size` | Selection glyph (checkbox / checkmark) size | per size (14 / 16px) |
44
+ */
45
+ declare const Cmp: import("svelte").Component<Props, {}, "">;
46
+ type Cmp = ReturnType<typeof Cmp>;
47
+ export default Cmp;
@@ -1,31 +1,46 @@
1
1
  <script lang="ts">import { Button } from '../button';
2
2
  import { IconText } from '../icon-text';
3
3
  import { Popover } from '../popover';
4
- import ToolbarPanel from './cmp.toolbar-panel.svelte';
5
4
  import IconChevronDown from '@fluentui/svg-icons/icons/chevron_down_20_regular.svg?raw';
6
- const { title, triggerLabel, icon, size = 'sm', position = 'bottom-end', children, footer } = $props();
5
+ const { triggerLabel, icon, size = 'sm', borderless = false, position = 'bottom-start', columnFlex = true, children } = $props();
7
6
  </script>
8
7
 
9
8
  <div class="toolbar-popover">
10
9
  <Popover position={position} keepOpen>
11
10
  {#snippet trigger()}
12
- <Button type="presentational" variant="secondary" size={size}>
11
+ <Button type="presentational" variant={borderless ? 'ghost' : 'secondary'} size={size}>
13
12
  <IconText icon={icon} secondaryIcon={IconChevronDown} size={size} iconScale="large">{triggerLabel}</IconText>
14
13
  </Button>
15
14
  {/snippet}
16
- <ToolbarPanel title={title} footer={footer}>
15
+ {#if columnFlex}
16
+ <div class="toolbar-popover__content">{@render children()}</div>
17
+ {:else}
17
18
  {@render children()}
18
- </ToolbarPanel>
19
+ {/if}
19
20
  </Popover>
20
21
  </div>
21
22
 
22
23
  <!--
23
24
  @component
24
- A toolbar popover button. Opens a `ToolbarPanel` with a title, body content, and optional footer.
25
- The trigger is a secondary `Button` so size shares the same `sm | md | lg` preset as other field-shaped
26
- toolbar controls keeps everything aligned at the same row height.
25
+ A toolbar popover button a secondary `Button` trigger (sharing the `sm | md | lg` field size preset)
26
+ opening a `Popover` panel. By default the content is laid out as a flex column (`columnFlex`); pass
27
+ `columnFlex={false}` to render it raw. Compose the panel from `ToolbarOption`, `ToolbarSectionTitle`,
28
+ `ToolbarDivider`, etc.
29
+
30
+ ### CSS Custom Properties
31
+ | Property | Description | Default |
32
+ |---|---|---|
33
+ | `--sc-kit--toolbar-popover--gap` | Gap between flex-column children | `0.125rem` (2px) |
27
34
  -->
28
35
 
29
36
  <style>.toolbar-popover {
37
+ --_toolbar-popover--gap: var(--sc-kit--toolbar-popover--gap, 0.125rem);
30
38
  display: contents;
39
+ --sc-kit--popover--content--padding: var(--sc-kit--space--2);
40
+ }
41
+ .toolbar-popover__content {
42
+ display: flex;
43
+ flex-direction: column;
44
+ gap: var(--_toolbar-popover--gap);
45
+ min-inline-size: 12.5rem;
31
46
  }</style>