@streamscloud/kit 0.2.4 → 0.2.5

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 (65) hide show
  1. package/dist/ui/badge/cmp.badge.svelte +85 -0
  2. package/dist/ui/badge/cmp.badge.svelte.d.ts +26 -0
  3. package/dist/ui/badge/index.d.ts +2 -0
  4. package/dist/ui/badge/index.js +1 -0
  5. package/dist/ui/badge/types.d.ts +1 -0
  6. package/dist/ui/badge/types.js +1 -0
  7. package/dist/ui/button/cmp.button.svelte.d.ts +1 -0
  8. package/dist/ui/button/cmp.options-button.svelte.d.ts +1 -0
  9. package/dist/ui/checkbox/cmp.checkbox.svelte +102 -0
  10. package/dist/ui/checkbox/cmp.checkbox.svelte.d.ts +34 -0
  11. package/dist/ui/checkbox/cmp.three-state-checkbox.svelte +112 -0
  12. package/dist/ui/checkbox/cmp.three-state-checkbox.svelte.d.ts +37 -0
  13. package/dist/ui/checkbox/index.d.ts +3 -0
  14. package/dist/ui/checkbox/index.js +2 -0
  15. package/dist/ui/checkbox/types.d.ts +1 -0
  16. package/dist/ui/checkbox/types.js +1 -0
  17. package/dist/ui/confirmation-dialog/cmp.confirmation-dialog.svelte +58 -0
  18. package/dist/ui/confirmation-dialog/cmp.confirmation-dialog.svelte.d.ts +9 -0
  19. package/dist/ui/confirmation-dialog/confirmation-dialog-localization.d.ts +4 -0
  20. package/dist/ui/confirmation-dialog/confirmation-dialog-localization.js +19 -0
  21. package/dist/ui/confirmation-dialog/index.d.ts +19 -0
  22. package/dist/ui/confirmation-dialog/index.js +22 -0
  23. package/dist/ui/confirmation-dialog/types.d.ts +7 -0
  24. package/dist/ui/confirmation-dialog/types.js +1 -0
  25. package/dist/ui/datetime-picker/cmp.datetime-picker.svelte +286 -0
  26. package/dist/ui/datetime-picker/cmp.datetime-picker.svelte.d.ts +37 -0
  27. package/dist/ui/datetime-picker/datetime-picker-localization.d.ts +5 -0
  28. package/dist/ui/datetime-picker/datetime-picker-localization.js +26 -0
  29. package/dist/ui/datetime-picker/flatpickr-theme.d.ts +1 -0
  30. package/dist/ui/datetime-picker/flatpickr-theme.js +13 -0
  31. package/dist/ui/datetime-picker/index.d.ts +2 -0
  32. package/dist/ui/datetime-picker/index.js +1 -0
  33. package/dist/ui/datetime-picker/types.d.ts +16 -0
  34. package/dist/ui/datetime-picker/types.js +1 -0
  35. package/dist/ui/dialog/cmp.dialog-button.svelte.d.ts +1 -0
  36. package/dist/ui/dropdown/cmp.dropdown.svelte +23 -9
  37. package/dist/ui/dropdown/cmp.dropdown.svelte.d.ts +7 -2
  38. package/dist/ui/dropdown/index.d.ts +0 -1
  39. package/dist/ui/dropdown/index.js +0 -1
  40. package/dist/ui/icon-text/cmp.icon-text.svelte +1 -1
  41. package/dist/ui/inputs/input/cmp.input-validatable.svelte.d.ts +1 -0
  42. package/dist/ui/inputs/input/cmp.input.svelte.d.ts +1 -0
  43. package/dist/ui/inputs/textarea/cmp.textarea-validatable.svelte.d.ts +2 -1
  44. package/dist/ui/inputs/textarea/cmp.textarea.svelte.d.ts +1 -0
  45. package/dist/ui/placeholder/cmp.placeholder.svelte +65 -0
  46. package/dist/ui/placeholder/cmp.placeholder.svelte.d.ts +19 -0
  47. package/dist/ui/placeholder/index.d.ts +1 -0
  48. package/dist/ui/placeholder/index.js +1 -0
  49. package/dist/ui/selects/_multiselect.scss +3 -3
  50. package/dist/ui/selects/_singleselect.scss +1 -1
  51. package/dist/ui/selects/cmp.multiselect.svelte +2 -2
  52. package/dist/ui/selects/cmp.search-multiselect.svelte +2 -2
  53. package/dist/ui/toggle/cmp.toggle.svelte +103 -0
  54. package/dist/ui/toggle/cmp.toggle.svelte.d.ts +25 -0
  55. package/dist/ui/toggle/index.d.ts +1 -0
  56. package/dist/ui/toggle/index.js +1 -0
  57. package/dist/ui/tooltip/cmp.tooltip.svelte +192 -0
  58. package/dist/ui/tooltip/cmp.tooltip.svelte.d.ts +31 -0
  59. package/dist/ui/tooltip/index.d.ts +2 -0
  60. package/dist/ui/tooltip/index.js +1 -0
  61. package/dist/ui/tooltip/types.d.ts +2 -0
  62. package/dist/ui/tooltip/types.js +1 -0
  63. package/package.json +31 -1
  64. package/dist/ui/dropdown/cmp.dropdown-panel.svelte +0 -29
  65. package/dist/ui/dropdown/cmp.dropdown-panel.svelte.d.ts +0 -18
@@ -0,0 +1,286 @@
1
+ <script lang="ts">import { AppTheme } from '../../core/theme';
2
+ import { randomString, Utils } from '../../core/utils';
3
+ import { Icon } from '../icon';
4
+ import { DatetimePickerLocalization } from './datetime-picker-localization';
5
+ import { applyFlatpickrTheme } from './flatpickr-theme';
6
+ import IconDismiss from '@fluentui/svg-icons/icons/dismiss_20_regular.svg?raw';
7
+ import flatpickr from 'flatpickr';
8
+ let { datetime, placeholder = null, pickerOptions, disabled = false, icon, on } = $props();
9
+ const id = randomString(10);
10
+ const localization = new DatetimePickerLocalization();
11
+ let timePartHolder;
12
+ let showClearButton = $state(false);
13
+ let fpInstance = $state(undefined);
14
+ let picker;
15
+ const preprocessInitialValue = (datetime) => {
16
+ let date = undefined;
17
+ if (!datetime) {
18
+ if (pickerOptions.noValueHandler !== 'allow-empty') {
19
+ date = pickerOptions.noValueHandler === 'reset-to-now' || !pickerOptions.noValueHandler ? new Date() : pickerOptions.noValueHandler;
20
+ }
21
+ }
22
+ else {
23
+ date = new Date(datetime);
24
+ }
25
+ if (date && pickerOptions.mode === 'date') {
26
+ date.setHours(0, 0, 0, 0);
27
+ }
28
+ if (pickerOptions.mode === 'date-keeping-time') {
29
+ timePartHolder = date || new Date(2000, 1, 1, 12, 0);
30
+ }
31
+ notifyChangedValue(date);
32
+ return date;
33
+ };
34
+ const notifyChangedValue = (date) => {
35
+ if (!date && !datetime) {
36
+ return;
37
+ }
38
+ if (!date && datetime) {
39
+ on?.change?.(undefined);
40
+ return;
41
+ }
42
+ if (!datetime || date.toISOString() !== new Date(datetime).toISOString()) {
43
+ on?.change?.(date.toISOString());
44
+ }
45
+ };
46
+ const getDefaultPlaceholder = () => {
47
+ switch (pickerOptions.mode) {
48
+ case 'date':
49
+ case 'date-keeping-time':
50
+ return localization.date;
51
+ case 'time':
52
+ return localization.time;
53
+ default:
54
+ return localization.dateTime;
55
+ }
56
+ };
57
+ const initPicker = (node) => {
58
+ picker = node;
59
+ const opts = pickerOptions ?? {};
60
+ const mode = opts.mode ?? 'datetime';
61
+ const noValueHandler = opts.noValueHandler ?? 'reset-to-now';
62
+ let format;
63
+ switch (mode) {
64
+ case 'datetime':
65
+ format = { picker: 'd M Y H:i', enableTime: true, showCalendar: true };
66
+ break;
67
+ case 'date':
68
+ case 'date-keeping-time':
69
+ format = { picker: 'd M Y', enableTime: false, showCalendar: true };
70
+ break;
71
+ case 'time':
72
+ format = { picker: 'H:i', enableTime: true, showCalendar: false };
73
+ break;
74
+ default:
75
+ return Utils.assertUnreachable(mode);
76
+ }
77
+ const defaultDate = preprocessInitialValue(datetime);
78
+ fpInstance = flatpickr(picker, {
79
+ dateFormat: format.picker,
80
+ defaultDate,
81
+ enableTime: format.enableTime,
82
+ noCalendar: !format.showCalendar,
83
+ time_24hr: true,
84
+ wrap: true,
85
+ locale: { firstDayOfWeek: 1 },
86
+ minDate: opts.minDate,
87
+ maxDate: opts.maxDate,
88
+ positionElement: picker,
89
+ onChange: (selectedDates) => {
90
+ let dateToProcess = !selectedDates.length && noValueHandler instanceof Date ? noValueHandler : selectedDates[0];
91
+ dateToProcess = dateToProcess ? new Date(dateToProcess.getTime()) : null;
92
+ if (dateToProcess) {
93
+ if (mode === 'date-keeping-time') {
94
+ dateToProcess.setHours(timePartHolder.getHours(), timePartHolder.getMinutes());
95
+ }
96
+ fpInstance?.setDate(dateToProcess);
97
+ }
98
+ notifyChangedValue(dateToProcess);
99
+ },
100
+ onOpen: () => {
101
+ if (fpInstance?.selectedDates) {
102
+ fpInstance.jumpToDate(fpInstance.selectedDates[0]);
103
+ }
104
+ }
105
+ });
106
+ };
107
+ $effect(() => {
108
+ applyFlatpickrTheme(AppTheme.isDarkMode);
109
+ });
110
+ $effect(() => {
111
+ if (!datetime) {
112
+ showClearButton = false;
113
+ }
114
+ else {
115
+ const handler = pickerOptions.noValueHandler;
116
+ switch (handler) {
117
+ case 'reset-to-now':
118
+ showClearButton = false;
119
+ break;
120
+ case 'allow-empty':
121
+ showClearButton = true;
122
+ break;
123
+ default:
124
+ showClearButton = !!handler && new Date(datetime).getTime() !== handler.getTime();
125
+ }
126
+ }
127
+ });
128
+ $effect(() => {
129
+ if (fpInstance) {
130
+ const date = preprocessInitialValue(datetime);
131
+ if (date) {
132
+ fpInstance.setDate(date);
133
+ }
134
+ else {
135
+ fpInstance.clear();
136
+ }
137
+ fpInstance._input.disabled = disabled;
138
+ }
139
+ });
140
+ $effect(() => {
141
+ return () => {
142
+ fpInstance?.destroy();
143
+ };
144
+ });
145
+ </script>
146
+
147
+ <div class="datetime-picker" class:datetime-picker--disabled={disabled} use:initPicker id={id}>
148
+ {#if icon}
149
+ <div class="datetime-picker__icon">
150
+ {@render icon()}
151
+ </div>
152
+ {/if}
153
+ <input data-input class="datetime-picker__input" placeholder={placeholder ?? getDefaultPlaceholder()} disabled={disabled} />
154
+ <button type="button" class="datetime-picker__clear-button" class:datetime-picker__clear-button--hidden={!showClearButton || disabled} data-clear>
155
+ <Icon src={IconDismiss} />
156
+ </button>
157
+ </div>
158
+
159
+ <!--
160
+ @component
161
+ A date/time picker powered by flatpickr, supporting date, time, and datetime modes.
162
+
163
+ ### CSS Custom Properties
164
+ | Property | Description | Default |
165
+ |---|---|---|
166
+ | `--sc-kit--datetime-picker--root--font-size` | Root font size for em scaling | `1rem` |
167
+ | `--sc-kit--datetime-picker--height` | Container height | `2em` |
168
+ | `--sc-kit--datetime-picker--width` | Container width | `100%` |
169
+ | `--sc-kit--datetime-picker--padding--inline` | Inline (horizontal) padding | `0.5em` |
170
+ | `--sc-kit--datetime-picker--padding--block` | Block (vertical) padding | `0` |
171
+ | `--sc-kit--datetime-picker--background` | Background color | light-dark white/gray-900 |
172
+ | `--sc-kit--datetime-picker--background--disabled` | Disabled background | light-dark neutral-50/neutral-800 |
173
+ | `--sc-kit--datetime-picker--border-color` | Border color | light-dark neutral-300/neutral-600 |
174
+ | `--sc-kit--datetime-picker--border-radius` | Border radius | `0.25em` |
175
+ | `--sc-kit--datetime-picker--accent-color` | Focus accent color | light-dark primary-500/primary-400 |
176
+ | `--sc-kit--datetime-picker--text--font-size` | Text font size | `0.875em` |
177
+ | `--sc-kit--datetime-picker--text--color` | Text color | light-dark gray-800/white |
178
+ | `--sc-kit--datetime-picker--placeholder--color` | Placeholder color | inherited from border |
179
+ | `--sc-kit--datetime-picker--icon--size` | Icon size | `1em` |
180
+ | `--sc-kit--datetime-picker--icon--color` | Icon color | inherited from border |
181
+ -->
182
+
183
+ <style>.datetime-picker {
184
+ --_--input--root--font-size: var(--sc-kit--datetime-picker--root--font-size);
185
+ --_--input--height: var(--sc-kit--datetime-picker--height);
186
+ --_--input--width: var(--sc-kit--datetime-picker--width);
187
+ --_--input--background: var(--sc-kit--datetime-picker--background);
188
+ --_--input--background--disabled: var(--sc-kit--datetime-picker--background--disabled);
189
+ --_--input--border-color: var(--sc-kit--datetime-picker--border-color);
190
+ --_--input--border-radius: var(--sc-kit--datetime-picker--border-radius);
191
+ --_--input--icon--size: var(--sc-kit--datetime-picker--icon--size);
192
+ --_--input--icon--color: var(--sc-kit--datetime-picker--icon--color);
193
+ --_--input--text--font-size: var(--sc-kit--datetime-picker--text--font-size);
194
+ --_--input--text--color: var(--sc-kit--datetime-picker--text--color);
195
+ --_--input--placeholder--color: var(--sc-kit--datetime-picker--placeholder--color);
196
+ --_--input--accent-color: var(--sc-kit--datetime-picker--accent-color);
197
+ --_--input--padding--inline: var(--sc-kit--datetime-picker--padding--inline);
198
+ --_--input--padding--block: var(--sc-kit--datetime-picker--padding--block);
199
+ --_input--root--font-size: var(--_--input--root--font-size, 1rem);
200
+ --_input--height: var(--_--input--height, 2em);
201
+ --_input--width: var(--_--input--width, 100%);
202
+ --_input--background: var(--_--input--background, light-dark(#ffffff, #1c1c1c));
203
+ --_input--background--disabled: var(--_--input--background--disabled, light-dark(#f9fafb, #1f2937));
204
+ --_input--border-color: var(--_--input--border-color, light-dark(#d1d5db, #4b5563));
205
+ --_input--border-radius: var(--_--input--border-radius, 0.25em);
206
+ --_input--icon--size: var(--_--input--icon--size, 1em);
207
+ --_input--icon--color: var(--_--input--icon--color, var(--_input--border-color));
208
+ --_input--text--font-size: var(--_--input--text--font-size, 0.875em);
209
+ --_input--text--color: var(--_--input--text--color, light-dark(#2e2e2e, #ffffff));
210
+ --_input--placeholder--color: var(--_--input--placeholder--color, var(--_input--border-color));
211
+ --_input--accent-color: var(--_--input--accent-color, light-dark(#144ab0, #5a8dec));
212
+ --_input--padding--inline: var(--_--input--padding--inline, 0.5em);
213
+ --_input--padding--block: var(--_--input--padding--block, 0);
214
+ --_input--padding-top: var(--_--input--padding-top, var(--_input--padding--block));
215
+ --_input--padding-right: var(--_--input--padding-right, var(--_input--padding--inline));
216
+ --_input--padding-bottom: var(--_--input--padding-bottom, var(--_input--padding--block));
217
+ --_input--padding-left: var(--_--input--padding-left, var(--_input--padding--inline));
218
+ font-size: var(--_input--root--font-size);
219
+ height: var(--_input--height);
220
+ color: var(--_input--text--color);
221
+ border: 1px solid var(--_input--border-color);
222
+ border-radius: var(--_input--border-radius);
223
+ width: var(--_input--width);
224
+ min-width: var(--_input--width);
225
+ background: var(--_input--background);
226
+ padding-top: var(--_input--padding-top);
227
+ padding-right: var(--_input--padding-right);
228
+ padding-bottom: var(--_input--padding-bottom);
229
+ padding-left: var(--_input--padding-left);
230
+ --_input--default-shadow-color: transparent;
231
+ --_input--accent-shadow: var(--_input--explicit-shadow-color, var(--_input--default-shadow-color));
232
+ position: relative;
233
+ box-shadow: inset 0 -0.13em var(--_input--accent-shadow);
234
+ transition: box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1);
235
+ }
236
+ .datetime-picker:focus, .datetime-picker:focus-within {
237
+ --_input--default-shadow-color: var(--_input--accent-color);
238
+ }
239
+ .datetime-picker--disabled {
240
+ background-color: var(--_input--background--disabled);
241
+ cursor: default;
242
+ }
243
+ .datetime-picker {
244
+ display: flex;
245
+ align-items: center;
246
+ gap: 0.625em;
247
+ cursor: pointer;
248
+ position: relative;
249
+ }
250
+ .datetime-picker :global(.flatpickr-calendar) {
251
+ z-index: 9999993 !important;
252
+ display: none;
253
+ }
254
+ .datetime-picker :global(.flatpickr-calendar) :global(.flatpickr-time) :global(.numInputWrapper) :global(input[type=number]) {
255
+ outline: none;
256
+ border: none;
257
+ color: #2e2e2e;
258
+ height: inherit;
259
+ }
260
+ .datetime-picker__icon, .datetime-picker__clear-button {
261
+ display: flex;
262
+ align-items: center;
263
+ justify-content: center;
264
+ flex-shrink: 0;
265
+ color: var(--_input--icon--color);
266
+ font-size: var(--_input--icon--size);
267
+ }
268
+ .datetime-picker__input {
269
+ flex: 1;
270
+ min-width: 0;
271
+ height: 100%;
272
+ padding: 0;
273
+ background-color: transparent !important;
274
+ cursor: pointer;
275
+ font-size: var(--_input--text--font-size);
276
+ color: var(--_input--text--color);
277
+ }
278
+ .datetime-picker__input::placeholder {
279
+ color: var(--_input--placeholder--color);
280
+ }
281
+ .datetime-picker__input:-webkit-autofill {
282
+ -webkit-text-fill-color: var(--_input--text--color) !important;
283
+ }
284
+ .datetime-picker__clear-button--hidden {
285
+ display: none;
286
+ }</style>
@@ -0,0 +1,37 @@
1
+ import type { DatetimePickerOptions, LikeDate } from './types';
2
+ import type { Snippet } from 'svelte';
3
+ type Props = {
4
+ datetime: LikeDate | null | undefined;
5
+ placeholder?: string | null;
6
+ pickerOptions: DatetimePickerOptions;
7
+ disabled?: boolean;
8
+ on?: {
9
+ change: (value: string | undefined) => void;
10
+ };
11
+ icon?: Snippet;
12
+ };
13
+ /**
14
+ * A date/time picker powered by flatpickr, supporting date, time, and datetime modes.
15
+ *
16
+ * ### CSS Custom Properties
17
+ * | Property | Description | Default |
18
+ * |---|---|---|
19
+ * | `--sc-kit--datetime-picker--root--font-size` | Root font size for em scaling | `1rem` |
20
+ * | `--sc-kit--datetime-picker--height` | Container height | `2em` |
21
+ * | `--sc-kit--datetime-picker--width` | Container width | `100%` |
22
+ * | `--sc-kit--datetime-picker--padding--inline` | Inline (horizontal) padding | `0.5em` |
23
+ * | `--sc-kit--datetime-picker--padding--block` | Block (vertical) padding | `0` |
24
+ * | `--sc-kit--datetime-picker--background` | Background color | light-dark white/gray-900 |
25
+ * | `--sc-kit--datetime-picker--background--disabled` | Disabled background | light-dark neutral-50/neutral-800 |
26
+ * | `--sc-kit--datetime-picker--border-color` | Border color | light-dark neutral-300/neutral-600 |
27
+ * | `--sc-kit--datetime-picker--border-radius` | Border radius | `0.25em` |
28
+ * | `--sc-kit--datetime-picker--accent-color` | Focus accent color | light-dark primary-500/primary-400 |
29
+ * | `--sc-kit--datetime-picker--text--font-size` | Text font size | `0.875em` |
30
+ * | `--sc-kit--datetime-picker--text--color` | Text color | light-dark gray-800/white |
31
+ * | `--sc-kit--datetime-picker--placeholder--color` | Placeholder color | inherited from border |
32
+ * | `--sc-kit--datetime-picker--icon--size` | Icon size | `1em` |
33
+ * | `--sc-kit--datetime-picker--icon--color` | Icon color | inherited from border |
34
+ */
35
+ declare const Cmp: import("svelte").Component<Props, {}, "">;
36
+ type Cmp = ReturnType<typeof Cmp>;
37
+ export default Cmp;
@@ -0,0 +1,5 @@
1
+ export declare class DatetimePickerLocalization {
2
+ get date(): string;
3
+ get time(): string;
4
+ get dateTime(): string;
5
+ }
@@ -0,0 +1,26 @@
1
+ import { AppLocale } from '../../core/locale';
2
+ export class DatetimePickerLocalization {
3
+ get date() {
4
+ return loc.date[AppLocale.current];
5
+ }
6
+ get time() {
7
+ return loc.time[AppLocale.current];
8
+ }
9
+ get dateTime() {
10
+ return loc.dateTime[AppLocale.current];
11
+ }
12
+ }
13
+ const loc = {
14
+ date: {
15
+ en: 'Date',
16
+ no: 'Dato'
17
+ },
18
+ time: {
19
+ en: 'Time',
20
+ no: 'Tid'
21
+ },
22
+ dateTime: {
23
+ en: 'Date and time',
24
+ no: 'Dato og tid'
25
+ }
26
+ };
@@ -0,0 +1 @@
1
+ export declare const applyFlatpickrTheme: (isDark: boolean) => void;
@@ -0,0 +1,13 @@
1
+ import airbnbTheme from 'flatpickr/dist/themes/airbnb.css?inline';
2
+ import darkTheme from 'flatpickr/dist/themes/dark.css?inline';
3
+ let styleEl = null;
4
+ export const applyFlatpickrTheme = (isDark) => {
5
+ if (typeof document === 'undefined') {
6
+ return;
7
+ }
8
+ if (!styleEl) {
9
+ styleEl = document.createElement('style');
10
+ document.head.appendChild(styleEl);
11
+ }
12
+ styleEl.textContent = isDark ? darkTheme : airbnbTheme;
13
+ };
@@ -0,0 +1,2 @@
1
+ export { default as DatetimePicker } from './cmp.datetime-picker.svelte';
2
+ export type { DatetimePickerMode, DatetimePickerNoValueHandler, DatetimePickerOptions } from './types';
@@ -0,0 +1 @@
1
+ export { default as DatetimePicker } from './cmp.datetime-picker.svelte';
@@ -0,0 +1,16 @@
1
+ export type LikeDate = string | number | Date;
2
+ export type PickerFormat = {
3
+ picker: string;
4
+ enableTime: boolean;
5
+ showCalendar: boolean;
6
+ };
7
+ export type DatetimePickerMode = 'datetime' | 'date' | 'date-keeping-time' | 'time';
8
+ export type DatetimePickerNoValueHandler = 'reset-to-now' | 'allow-empty' | Date;
9
+ export type DatetimePickerOptions = {
10
+ /** @default 'datetime' */
11
+ mode?: DatetimePickerMode;
12
+ /** @default 'reset-to-now' */
13
+ noValueHandler?: DatetimePickerNoValueHandler;
14
+ minDate?: Date;
15
+ maxDate?: Date;
16
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,7 @@
1
1
  import type { ButtonVariant } from '../button/resources/types';
2
2
  import type { Snippet } from 'svelte';
3
3
  type Props = {
4
+ /** @default 'button' */
4
5
  type?: 'button' | 'submit' | 'reset';
5
6
  disabled?: boolean;
6
7
  autofocus?: boolean;
@@ -3,7 +3,7 @@ import { isIgnored } from './dropdown-ignore';
3
3
  import IconChevronDown from '@fluentui/svg-icons/icons/chevron_down_20_regular.svg?raw';
4
4
  import { createPopper } from '@popperjs/core';
5
5
  import { untrack } from 'svelte';
6
- let { position = 'bottom-start', disabled = false, keepDropdownOpen = false, fixedPosition = false, offset = 4, boundaryMargin = 8, backdrop = false, isOpenRequested, matchTriggerWidth = false, on, children, trigger } = $props();
6
+ let { position = 'bottom-start', disabled = false, keepDropdownOpen = false, fixedPosition = false, offset = 4, boundaryMargin = 8, backdrop = false, isOpenRequested, matchTriggerWidth = false, panel = true, on, children, trigger } = $props();
7
7
  let opened = $state(false);
8
8
  let dropdownEl = $state(null);
9
9
  let actualPlacement = $state(untrack(() => position));
@@ -35,17 +35,17 @@ $effect(() => {
35
35
  on?.closed?.();
36
36
  }
37
37
  });
38
- $effect(() => untrack(() => {
38
+ untrack(() => {
39
39
  if (isOpenRequested) {
40
40
  open();
41
41
  }
42
- }));
42
+ });
43
43
  $effect(() => {
44
44
  return () => {
45
- window.removeEventListener('click', handleOutsideClick, true);
45
+ window.removeEventListener('pointerdown', handleOutsidePointerDown, true);
46
46
  };
47
47
  });
48
- const handleOutsideClick = (event) => {
48
+ const handleOutsidePointerDown = (event) => {
49
49
  if (dropdownEl?.contains(event.target)) {
50
50
  return;
51
51
  }
@@ -53,11 +53,11 @@ const handleOutsideClick = (event) => {
53
53
  };
54
54
  const open = () => {
55
55
  opened = true;
56
- window.addEventListener('click', handleOutsideClick, true);
56
+ window.addEventListener('pointerdown', handleOutsidePointerDown, true);
57
57
  };
58
58
  const close = () => {
59
59
  opened = false;
60
- window.removeEventListener('click', handleOutsideClick, true);
60
+ window.removeEventListener('pointerdown', handleOutsidePointerDown, true);
61
61
  };
62
62
  const handleClick = (event) => {
63
63
  event.stopPropagation();
@@ -154,7 +154,7 @@ const initPopper = (node) => {
154
154
  </button>
155
155
  {#if opened}
156
156
  <div use:initPopper class="dropdown__popper" data-placement={actualPlacement} role="tooltip" tabindex="-1">
157
- <div class="dropdown__content" class:dropdown__content--match-width={matchTriggerWidth}>
157
+ <div class="dropdown__content" class:dropdown__content--match-width={matchTriggerWidth} class:dropdown__content--panel={panel}>
158
158
  {@render children()}
159
159
  </div>
160
160
  </div>
@@ -163,12 +163,15 @@ const initPopper = (node) => {
163
163
 
164
164
  <!--
165
165
  @component
166
- A Popper.js-powered dropdown that positions content relative to a trigger element, with click-outside-to-close, optional backdrop, imperative open/close control, and optional trigger-width matching.
166
+ A Popper.js-powered dropdown that positions content relative to a trigger element, with click-outside-to-close, optional backdrop, imperative open/close control, and optional trigger-width matching. Includes built-in panel styling (background, shadow, radius) enabled by default.
167
167
 
168
168
  ### CSS Custom Properties
169
169
  | Property | Description | Default |
170
170
  |---|---|---|
171
171
  | `--sc-kit--dropdown--width` | Trigger element width | `auto` |
172
+ | `--sc-kit--dropdown--content--background` | Content background | light-dark white/gray-900 |
173
+ | `--sc-kit--dropdown--content--box-shadow` | Content shadow | `0 2px 10px` light/dark |
174
+ | `--sc-kit--dropdown--content--border-radius` | Content corner radius | `0` |
172
175
  -->
173
176
 
174
177
  <style>.dropdown-backdrop {
@@ -180,6 +183,9 @@ A Popper.js-powered dropdown that positions content relative to a trigger elemen
180
183
 
181
184
  .dropdown {
182
185
  --_dropdown--width: var(--sc-kit--dropdown--width, auto);
186
+ --_dropdown--content--background: var(--sc-kit--dropdown--content--background);
187
+ --_dropdown--content--box-shadow: var(--sc-kit--dropdown--content--box-shadow);
188
+ --_dropdown--content--border-radius: var(--sc-kit--dropdown--content--border-radius);
183
189
  height: 100%;
184
190
  width: var(--_dropdown--width);
185
191
  -webkit-user-drag: none;
@@ -250,10 +256,18 @@ A Popper.js-powered dropdown that positions content relative to a trigger elemen
250
256
  width: max-content;
251
257
  transform-origin: var(--_dd-origin-x) var(--_dd-origin-y);
252
258
  animation: dropdown-appear 150ms cubic-bezier(0, 0, 0.2, 1) both;
259
+ background: var(--_dropdown--content--background);
260
+ box-shadow: var(--_dropdown--content--box-shadow);
261
+ border-radius: var(--_dropdown--content--border-radius);
253
262
  }
254
263
  .dropdown__content--match-width {
255
264
  width: 100%;
256
265
  }
266
+ .dropdown__content--panel {
267
+ --_dropdown--content--background: var(--sc-kit--dropdown--content--background, light-dark(#ffffff, #1c1c1c));
268
+ --_dropdown--content--box-shadow: var(--sc-kit--dropdown--content--box-shadow, 0 2px 10px light-dark(rgb(0 0 0 / 15%), rgb(255 255 255 / 20%)));
269
+ --_dropdown--content--border-radius: var(--sc-kit--dropdown--content--border-radius, 0);
270
+ }
257
271
  .dropdown :global([data-popper-escaped]) {
258
272
  visibility: hidden !important;
259
273
  }
@@ -8,7 +8,7 @@ type Props = {
8
8
  keepDropdownOpen?: boolean;
9
9
  /** Use `position: fixed` for the Popper strategy (useful inside overflow containers) */
10
10
  fixedPosition?: boolean;
11
- /** Distance in px between the trigger and the dropdown content @default 8 */
11
+ /** Distance in px between the trigger and the dropdown content @default 4 */
12
12
  offset?: number;
13
13
  /** Padding in px from the viewport boundary @default 8 */
14
14
  boundaryMargin?: number;
@@ -18,6 +18,8 @@ type Props = {
18
18
  isOpenRequested?: boolean;
19
19
  /** Make the popper content match the trigger element width */
20
20
  matchTriggerWidth?: boolean;
21
+ /** Apply content styling (background, box-shadow, border-radius) @default true */
22
+ panel?: boolean;
21
23
  on?: {
22
24
  opened?: () => void;
23
25
  closed?: () => void;
@@ -31,12 +33,15 @@ type Props = {
31
33
  trigger?: Snippet;
32
34
  };
33
35
  /**
34
- * A Popper.js-powered dropdown that positions content relative to a trigger element, with click-outside-to-close, optional backdrop, imperative open/close control, and optional trigger-width matching.
36
+ * A Popper.js-powered dropdown that positions content relative to a trigger element, with click-outside-to-close, optional backdrop, imperative open/close control, and optional trigger-width matching. Includes built-in panel styling (background, shadow, radius) enabled by default.
35
37
  *
36
38
  * ### CSS Custom Properties
37
39
  * | Property | Description | Default |
38
40
  * |---|---|---|
39
41
  * | `--sc-kit--dropdown--width` | Trigger element width | `auto` |
42
+ * | `--sc-kit--dropdown--content--background` | Content background | light-dark white/gray-900 |
43
+ * | `--sc-kit--dropdown--content--box-shadow` | Content shadow | `0 2px 10px` light/dark |
44
+ * | `--sc-kit--dropdown--content--border-radius` | Content corner radius | `0` |
40
45
  */
41
46
  declare const Cmp: import("svelte").Component<Props, {}, "">;
42
47
  type Cmp = ReturnType<typeof Cmp>;
@@ -1,5 +1,4 @@
1
1
  export { default as Dropdown } from './cmp.dropdown.svelte';
2
2
  export { default as DropdownItem } from './cmp.dropdown-item.svelte';
3
- export { default as DropdownPanel } from './cmp.dropdown-panel.svelte';
4
3
  export type { Placement as DropdownPosition } from '@popperjs/core';
5
4
  export { dropdownIgnore } from './dropdown-ignore';
@@ -1,4 +1,3 @@
1
1
  export { default as Dropdown } from './cmp.dropdown.svelte';
2
2
  export { default as DropdownItem } from './cmp.dropdown-item.svelte';
3
- export { default as DropdownPanel } from './cmp.dropdown-panel.svelte';
4
3
  export { dropdownIgnore } from './dropdown-ignore';
@@ -61,7 +61,7 @@ opposite side of the text from the primary icon.
61
61
  --_icon-text--icon--color: var(--sc-kit--icon-text--icon--color, var(--_icon-text--root--color));
62
62
  --_icon-text--gap: var(--sc-kit--icon-text--gap, 0.5em);
63
63
  --_icon-text--justify-content: var(--sc-kit--icon-text--justify-content, normal);
64
- --_icon-text--secondary-icon--font-size: var(--sc-kit--icon-text--secondary-icon--font-size, var(--_icon-text--text--font-size));
64
+ --_icon-text--secondary-icon--font-size: var(--sc-kit--icon-text--secondary-icon--font-size, var(--_icon-text--icon--font-size));
65
65
  --_icon-text--secondary-icon--color: var(--sc-kit--icon-text--secondary-icon--color, var(--_icon-text--root--color));
66
66
  display: flex;
67
67
  align-items: center;
@@ -7,6 +7,7 @@ declare function $$render<T extends Record<string, unknown>>(): {
7
7
  /** Form validation handler instance */
8
8
  handler: FormValidationHandler<T>;
9
9
  id?: string;
10
+ /** @default 'text' */
10
11
  type?: "text" | "password";
11
12
  /** Debounce delay in ms for input/change handlers @default 0 */
12
13
  debounce?: number;
@@ -1,6 +1,7 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  type Props = {
3
3
  value: string | null | undefined;
4
+ /** @default 'text' */
4
5
  type?: 'text' | 'password';
5
6
  name?: string;
6
7
  id?: string | null;
@@ -10,10 +10,11 @@ declare function $$render<T extends Record<string, unknown>>(): {
10
10
  debounce?: number;
11
11
  /** Hide placeholder text when focused @default true */
12
12
  hidePlaceholderOnFocus?: boolean;
13
- /** Fire submit callback on Enter key */
13
+ /** Fire submit callback on Enter key @default false */
14
14
  submitOnEnter?: boolean;
15
15
  /** Minimum visible rows @default 0 */
16
16
  rows?: number;
17
+ /** @default 50000 */
17
18
  maxlength?: number;
18
19
  id?: string;
19
20
  disabled?: boolean;
@@ -11,6 +11,7 @@ type Props = {
11
11
  singleLine?: boolean;
12
12
  /** Minimum visible rows (0 = auto height) @default 0 */
13
13
  rows?: number;
14
+ /** @default 50000 */
14
15
  maxlength?: number;
15
16
  id?: string;
16
17
  disabled?: boolean;