@streamscloud/kit 0.2.1 → 0.2.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.
Files changed (104) hide show
  1. package/dist/styles/_input.scss +98 -0
  2. package/dist/styles/_mixins.scss +2 -2
  3. package/dist/styles/reset.css +1 -1
  4. package/dist/ui/color-picker/cmp.color-picker.svelte +3 -12
  5. package/dist/ui/color-picker/cmp.color-picker.svelte.d.ts +3 -9
  6. package/dist/ui/dialog/cmp.dialog.svelte +1 -1
  7. package/dist/ui/dropdown/cmp.dropdown-item.svelte +93 -0
  8. package/dist/ui/dropdown/cmp.dropdown-item.svelte.d.ts +32 -0
  9. package/dist/ui/dropdown/cmp.dropdown-panel.svelte +29 -0
  10. package/dist/ui/dropdown/cmp.dropdown-panel.svelte.d.ts +18 -0
  11. package/dist/ui/dropdown/cmp.dropdown.svelte +72 -7
  12. package/dist/ui/dropdown/cmp.dropdown.svelte.d.ts +3 -1
  13. package/dist/ui/dropdown/index.d.ts +2 -0
  14. package/dist/ui/dropdown/index.js +2 -0
  15. package/dist/ui/dynamic-component/cmp.dynamic-component.svelte +0 -5
  16. package/dist/ui/dynamic-component/cmp.dynamic-component.svelte.d.ts +2 -8
  17. package/dist/ui/emoji-picker/cmp.emoji-panel.svelte +186 -0
  18. package/dist/ui/emoji-picker/cmp.emoji-panel.svelte.d.ts +21 -0
  19. package/dist/ui/emoji-picker/cmp.emoji-picker.svelte +35 -0
  20. package/dist/ui/emoji-picker/cmp.emoji-picker.svelte.d.ts +15 -0
  21. package/dist/ui/emoji-picker/emoji-list.d.ts +2 -0
  22. package/dist/ui/emoji-picker/emoji-list.js +1754 -0
  23. package/dist/ui/emoji-picker/emoji-picker-localization.d.ts +5 -0
  24. package/dist/ui/emoji-picker/emoji-picker-localization.js +40 -0
  25. package/dist/ui/emoji-picker/index.d.ts +2 -0
  26. package/dist/ui/emoji-picker/index.js +2 -0
  27. package/dist/ui/emoji-picker/types.d.ts +8 -0
  28. package/dist/ui/emoji-picker/types.js +1 -0
  29. package/dist/ui/form-group/cmp.form-group-label.svelte.d.ts +1 -0
  30. package/dist/ui/form-group/cmp.form-group.svelte.d.ts +1 -0
  31. package/dist/ui/icon-text/cmp.icon-text.svelte +0 -9
  32. package/dist/ui/icon-text/cmp.icon-text.svelte.d.ts +4 -9
  33. package/dist/ui/inputs/index.d.ts +6 -0
  34. package/dist/ui/inputs/index.js +5 -0
  35. package/dist/ui/inputs/input/cmp.input-validatable.svelte +57 -0
  36. package/dist/ui/inputs/input/cmp.input-validatable.svelte.d.ts +56 -0
  37. package/dist/ui/inputs/input/cmp.input.svelte +235 -0
  38. package/dist/ui/inputs/input/cmp.input.svelte.d.ts +60 -0
  39. package/dist/ui/inputs/input/index.d.ts +2 -0
  40. package/dist/ui/inputs/input/index.js +2 -0
  41. package/dist/ui/inputs/input-emoji-picker/cmp.input-emoji-picker.svelte +44 -0
  42. package/dist/ui/inputs/input-emoji-picker/cmp.input-emoji-picker.svelte.d.ts +9 -0
  43. package/dist/ui/inputs/input-emoji-picker/index.d.ts +2 -0
  44. package/dist/ui/inputs/input-emoji-picker/index.js +2 -0
  45. package/dist/ui/inputs/input-emoji-picker/input-emoji-picker-container.d.ts +2 -0
  46. package/dist/ui/inputs/input-emoji-picker/input-emoji-picker-container.js +16 -0
  47. package/dist/ui/inputs/numeral-input/cmp.numeral-input-validatable.svelte +55 -0
  48. package/dist/ui/inputs/numeral-input/cmp.numeral-input-validatable.svelte.d.ts +62 -0
  49. package/dist/ui/inputs/numeral-input/cmp.numeral-input.svelte +248 -0
  50. package/dist/ui/inputs/numeral-input/cmp.numeral-input.svelte.d.ts +66 -0
  51. package/dist/ui/inputs/numeral-input/index.d.ts +2 -0
  52. package/dist/ui/inputs/numeral-input/index.js +2 -0
  53. package/dist/ui/inputs/pin-input/cmp.pin-input.svelte +58 -0
  54. package/dist/ui/inputs/pin-input/cmp.pin-input.svelte.d.ts +23 -0
  55. package/dist/ui/inputs/pin-input/index.d.ts +1 -0
  56. package/dist/ui/inputs/pin-input/index.js +1 -0
  57. package/dist/ui/inputs/pin-input/pin-input-generator.d.ts +27 -0
  58. package/dist/ui/inputs/pin-input/pin-input-generator.js +114 -0
  59. package/dist/ui/inputs/rich-text-input/cmp.rich-text-input.svelte +55 -0
  60. package/dist/ui/inputs/rich-text-input/cmp.rich-text-input.svelte.d.ts +43 -0
  61. package/dist/ui/inputs/rich-text-input/index.d.ts +2 -0
  62. package/dist/ui/inputs/rich-text-input/index.js +1 -0
  63. package/dist/ui/inputs/rich-text-input/rich-text-input-localization.d.ts +12 -0
  64. package/dist/ui/inputs/rich-text-input/rich-text-input-localization.js +48 -0
  65. package/dist/ui/inputs/rich-text-input/tinymce-input.svelte +250 -0
  66. package/dist/ui/inputs/rich-text-input/tinymce-input.svelte.d.ts +25 -0
  67. package/dist/ui/inputs/rich-text-input/tinymce.declarations.d.ts +7 -0
  68. package/dist/ui/inputs/rich-text-input/types.d.ts +4 -0
  69. package/dist/ui/inputs/rich-text-input/types.js +1 -0
  70. package/dist/ui/inputs/rich-text-input/validated-link-button.d.ts +3 -0
  71. package/dist/ui/inputs/rich-text-input/validated-link-button.js +78 -0
  72. package/dist/ui/inputs/textarea/cmp.textarea-validatable.svelte +35 -0
  73. package/dist/ui/inputs/textarea/cmp.textarea-validatable.svelte.d.ts +53 -0
  74. package/dist/ui/inputs/textarea/cmp.textarea.svelte +247 -0
  75. package/dist/ui/inputs/textarea/cmp.textarea.svelte.d.ts +57 -0
  76. package/dist/ui/inputs/textarea/index.d.ts +2 -0
  77. package/dist/ui/inputs/textarea/index.js +2 -0
  78. package/dist/ui/media-viewer-dialog/cmp.media-viewer-dialog.svelte.d.ts +2 -0
  79. package/dist/ui/selects/_multiselect.scss +282 -0
  80. package/dist/ui/selects/_singleselect.scss +175 -0
  81. package/dist/ui/selects/cmp.multiselect.svelte +530 -0
  82. package/dist/ui/selects/cmp.multiselect.svelte.d.ts +85 -0
  83. package/dist/ui/selects/cmp.search-multiselect.svelte +532 -0
  84. package/dist/ui/selects/cmp.search-multiselect.svelte.d.ts +67 -0
  85. package/dist/ui/selects/cmp.singleselect.svelte +381 -0
  86. package/dist/ui/selects/cmp.singleselect.svelte.d.ts +78 -0
  87. package/dist/ui/selects/index.d.ts +5 -0
  88. package/dist/ui/selects/index.js +4 -0
  89. package/dist/ui/selects/select-localization.d.ts +6 -0
  90. package/dist/ui/selects/select-localization.js +27 -0
  91. package/dist/ui/selects/types.d.ts +29 -0
  92. package/dist/ui/selects/types.js +1 -0
  93. package/dist/ui/time-ago/cmp.time-ago.svelte +0 -6
  94. package/dist/ui/time-ago/cmp.time-ago.svelte.d.ts +2 -6
  95. package/dist/ui/validatable/_validatable.scss +34 -0
  96. package/dist/ui/validatable/cmp.validatable.svelte +57 -0
  97. package/dist/ui/validatable/cmp.validatable.svelte.d.ts +49 -0
  98. package/dist/ui/validatable/cmp.validation-error.svelte +52 -0
  99. package/dist/ui/validatable/cmp.validation-error.svelte.d.ts +42 -0
  100. package/dist/ui/validatable/index.d.ts +2 -0
  101. package/dist/ui/validatable/index.js +2 -0
  102. package/package.json +31 -5
  103. package/dist/ui/color-picker/cmp.input-stub.svelte +0 -98
  104. package/dist/ui/color-picker/cmp.input-stub.svelte.d.ts +0 -40
@@ -0,0 +1,98 @@
1
+ @use 'colors';
2
+ @use 'functions';
3
+ @use 'transitions';
4
+
5
+ @mixin input-container() {
6
+ --_input--root--font-size: var(--_--input--root--font-size, 1rem);
7
+ --_input--height: var(--_--input--height, #{functions.em(32)});
8
+ --_input--width: var(--_--input--width, 100%);
9
+ --_input--background: var(--_--input--background, light-dark(#{colors.$color-white}, #{colors.$color-gray-900}));
10
+ --_input--background--disabled: var(--_--input--background--disabled, light-dark(#{colors.$color-neutral-50}, #{colors.$color-neutral-800}));
11
+ --_input--border-color: var(--_--input--border-color, light-dark(#{colors.$color-neutral-300}, #{colors.$color-neutral-600}));
12
+ --_input--border-radius: var(--_--input--border-radius, #{functions.em(4)});
13
+
14
+ --_input--icon--size: var(--_--input--icon--size, 1em);
15
+ --_input--icon--color: var(--_--input--icon--color, var(--_input--border-color));
16
+
17
+ --_input--text--font-size: var(--_--input--text--font-size, #{functions.em(14)});
18
+ --_input--text--color: var(--_--input--text--color, light-dark(#{colors.$color-gray-800}, #{colors.$color-white}));
19
+ --_input--placeholder--color: var(--_--input--placeholder--color, var(--_input--border-color));
20
+
21
+ --_input--accent-color: var(--_--input--accent-color, light-dark(#{colors.$color-primary-500}, #{colors.$color-primary-400}));
22
+
23
+ --_input--padding--inline: var(--_--input--padding--inline, #{functions.em(8)});
24
+ --_input--padding--block: var(--_--input--padding--block, 0);
25
+ --_input--padding-top: var(--_--input--padding-top, var(--_input--padding--block));
26
+ --_input--padding-right: var(--_--input--padding-right, var(--_input--padding--inline));
27
+ --_input--padding-bottom: var(--_--input--padding-bottom, var(--_input--padding--block));
28
+ --_input--padding-left: var(--_--input--padding-left, var(--_input--padding--inline));
29
+
30
+ font-size: var(--_input--root--font-size);
31
+ height: var(--_input--height);
32
+ color: var(--_input--text--color);
33
+ border: 1px solid var(--_input--border-color);
34
+ border-radius: var(--_input--border-radius);
35
+ width: var(--_input--width);
36
+ min-width: var(--_input--width);
37
+ background: var(--_input--background);
38
+
39
+ padding-top: var(--_input--padding-top);
40
+ padding-right: var(--_input--padding-right);
41
+ padding-bottom: var(--_input--padding-bottom);
42
+ padding-left: var(--_input--padding-left);
43
+
44
+ @include input-accent-shadow;
45
+
46
+ &--disabled {
47
+ background-color: var(--_input--background--disabled);
48
+ cursor: default;
49
+ }
50
+ }
51
+
52
+ @mixin input-text() {
53
+ font-size: var(--_input--text--font-size);
54
+ color: var(--_input--text--color);
55
+
56
+ &::placeholder {
57
+ color: var(--_input--placeholder--color);
58
+ }
59
+
60
+ &:-webkit-autofill {
61
+ -webkit-text-fill-color: var(--_input--text--color) !important;
62
+ }
63
+ }
64
+
65
+ @mixin input-icon() {
66
+ color: var(--_input--icon--color);
67
+ font-size: var(--_input--icon--size);
68
+ }
69
+
70
+ @mixin input-accent-shadow() {
71
+ --_input--default-shadow-color: transparent;
72
+ --_input--accent-shadow: var(--_input--explicit-shadow-color, var(--_input--default-shadow-color));
73
+ position: relative;
74
+ box-shadow: inset 0 -0.13em var(--_input--accent-shadow);
75
+ @include transitions.transition(box-shadow);
76
+
77
+ &:focus,
78
+ &:focus-within {
79
+ --_input--default-shadow-color: var(--_input--accent-color);
80
+ }
81
+ }
82
+
83
+ @mixin input-accented($color: null) {
84
+ @if ($color) {
85
+ --_input--explicit-shadow-color: #{$color};
86
+ } @else {
87
+ --_input--explicit-shadow-color: var(--_input--accent-color);
88
+ }
89
+ }
90
+
91
+ @mixin input-borderless() {
92
+ --_input--border-color: transparent;
93
+ --_input--background: transparent;
94
+ --_input--background--disabled: transparent;
95
+ --_input--accent-color: transparent;
96
+ --_input--explicit-shadow-color: transparent;
97
+ --_input--height: auto;
98
+ }
@@ -70,14 +70,14 @@
70
70
  max-height: 100%;
71
71
  }
72
72
 
73
- @mixin scrollbar($thumb-color: var(--scrollbar--thumb-color, light-dark(#999999, #333333)), $track-color: var(--scrollbar--track-color, transparent)) {
73
+ @mixin scrollbar($thumb-color: var(--scrollbar--thumb-color, light-dark(#d1d5db, #4b5563)), $track-color: var(--scrollbar--track-color, transparent)) {
74
74
  --_cross-browser-scrollbar--thumb-color: #{$thumb-color};
75
75
  --_cross-browser-scrollbar--track-color: #{$track-color};
76
76
 
77
77
  @include _cross-browser-scrollbar;
78
78
  }
79
79
 
80
- @mixin scrollbar-on-hover($thumb-color: var(--scrollbar--thumb-color, light-dark(#999999, #333333)), $track-color: var(--scrollbar--track-color, transparent)) {
80
+ @mixin scrollbar-on-hover($thumb-color: var(--scrollbar--thumb-color, light-dark(#d1d5db, #4b5563)), $track-color: var(--scrollbar--track-color, transparent)) {
81
81
  --_cross-browser-scrollbar--thumb-color: transparent;
82
82
  --_cross-browser-scrollbar--track-color: transparent;
83
83
 
@@ -121,7 +121,7 @@ input[type=number] {
121
121
  textarea {
122
122
  vertical-align: top;
123
123
  resize: vertical;
124
- --_cross-browser-scrollbar--thumb-color: var(--scrollbar--thumb-color, light-dark(#999999, #333333));
124
+ --_cross-browser-scrollbar--thumb-color: var(--scrollbar--thumb-color, light-dark(#d1d5db, #4b5563));
125
125
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
126
126
  }
127
127
  textarea::-webkit-scrollbar {
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">import { ColorHelper } from '../../core/utils';
2
2
  import { Dropdown } from '../dropdown';
3
3
  import { Icon } from '../icon';
4
- import { default as InputStub } from './cmp.input-stub.svelte';
4
+ import { Input } from '../inputs';
5
5
  import { ColorPickerLocalization } from './color-picker-localization';
6
6
  import IconChevronDown from '@fluentui/svg-icons/icons/chevron_down_20_regular.svg?raw';
7
7
  import IconColorF from '@fluentui/svg-icons/icons/color_20_regular.svg?raw';
@@ -55,7 +55,7 @@ const onColorPickerInput = ({ hex }) => {
55
55
  {#if children}
56
56
  {@render children()}
57
57
  {:else}
58
- <InputStub
58
+ <Input
59
59
  value={value || ''}
60
60
  on={{}}
61
61
  inert={true}
@@ -85,7 +85,7 @@ const onColorPickerInput = ({ hex }) => {
85
85
  </button>
86
86
  {/if}
87
87
  {/snippet}
88
- </InputStub>
88
+ </Input>
89
89
  {/if}
90
90
  </div>
91
91
  {/snippet}
@@ -100,15 +100,6 @@ const onColorPickerInput = ({ hex }) => {
100
100
  @component
101
101
  A color picker that displays a swatch preview trigger and opens a dropdown panel with a full color picker (powered by svelte-awesome-color-picker).
102
102
 
103
- ### Props
104
- | Prop | Type | Default | Description |
105
- |---|---|---|---|
106
- | `value` | `string \| null \| undefined` | — | Current color value (any CSS color format) |
107
- | `enableReset` | `boolean` | `false` | Show dismiss icon to clear the value |
108
- | `on.change` | `(value: string) => void` | — | Fires when color changes |
109
- | `children` | `Snippet` | — | Custom trigger snippet (replaces default preview) |
110
- | `defaultPreviewIcon` | `Snippet` | — | Custom icon in the default preview trigger |
111
-
112
103
  ### CSS Custom Properties
113
104
  | Property | Description | Default |
114
105
  |---|---|---|
@@ -1,25 +1,19 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  type Props = {
3
3
  value: string | null | undefined;
4
+ /** Show dismiss icon to clear the color value */
4
5
  enableReset?: boolean;
5
6
  on?: {
6
7
  change?: (value: string) => void;
7
8
  };
9
+ /** Custom trigger snippet (replaces default color preview) */
8
10
  children?: Snippet;
11
+ /** Custom icon in the default preview trigger */
9
12
  defaultPreviewIcon?: Snippet;
10
13
  };
11
14
  /**
12
15
  * A color picker that displays a swatch preview trigger and opens a dropdown panel with a full color picker (powered by svelte-awesome-color-picker).
13
16
  *
14
- * ### Props
15
- * | Prop | Type | Default | Description |
16
- * |---|---|---|---|
17
- * | `value` | `string \| null \| undefined` | — | Current color value (any CSS color format) |
18
- * | `enableReset` | `boolean` | `false` | Show dismiss icon to clear the value |
19
- * | `on.change` | `(value: string) => void` | — | Fires when color changes |
20
- * | `children` | `Snippet` | — | Custom trigger snippet (replaces default preview) |
21
- * | `defaultPreviewIcon` | `Snippet` | — | Custom icon in the default preview trigger |
22
- *
23
17
  * ### CSS Custom Properties
24
18
  * | Property | Description | Default |
25
19
  * |---|---|---|
@@ -104,7 +104,7 @@ A structured dialog panel with header (title + close button), scrollable body, a
104
104
  min-height: 0;
105
105
  overflow-y: auto;
106
106
  padding: var(--_dialog--body--padding-block) var(--_dialog--body--padding-inline);
107
- --_cross-browser-scrollbar--thumb-color: var(--scrollbar--thumb-color, light-dark(#999999, #333333));
107
+ --_cross-browser-scrollbar--thumb-color: var(--scrollbar--thumb-color, light-dark(#d1d5db, #4b5563));
108
108
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
109
109
  }
110
110
  .dialog__body::-webkit-scrollbar {
@@ -0,0 +1,93 @@
1
+ <script lang="ts">import { dropdownIgnore } from './dropdown-ignore';
2
+ let { disabled = false, keepDropdownOpen = false, on, children } = $props();
3
+ const handleClick = () => {
4
+ on?.click?.();
5
+ };
6
+ </script>
7
+
8
+ <div
9
+ class="dropdown-item"
10
+ use:dropdownIgnore={keepDropdownOpen}
11
+ class:dropdown-item--disabled={disabled}
12
+ onclick={handleClick}
13
+ onkeydown={() => ({})}
14
+ role="none">
15
+ <div class="dropdown-item__content">
16
+ {@render children()}
17
+ </div>
18
+ </div>
19
+
20
+ <!--
21
+ @component
22
+ A single item within a dropdown menu. Supports hover state, disabled state, and separator lines between items.
23
+
24
+ ### CSS Custom Properties
25
+ | Property | Description | Default |
26
+ |---|---|---|
27
+ | `--sc-kit--dropdown-item--min-width` | Minimum item width | `max-content` |
28
+ | `--sc-kit--dropdown-item--font-size` | Content font size | `0.875rem` |
29
+ | `--sc-kit--dropdown-item--padding` | Item padding | `0.625rem 0.875rem` |
30
+ | `--sc-kit--dropdown-item--color` | Text color | light-dark gray-800/white |
31
+ | `--sc-kit--dropdown-item--color--hover` | Text color on hover | light-dark gray-800/white |
32
+ | `--sc-kit--dropdown-item--color--disabled` | Text color when disabled | light-dark neutral-400/neutral-500 |
33
+ | `--sc-kit--dropdown-item--background` | Background color | light-dark white/gray-900 |
34
+ | `--sc-kit--dropdown-item--background--hover` | Background on hover | light-dark neutral-100/neutral-800 |
35
+ | `--sc-kit--dropdown-item--separator-color` | Separator line color | light-dark neutral-200/neutral-700 |
36
+ | `--sc-kit--dropdown-item--separator-indent` | Separator horizontal indent | `0.875rem` |
37
+ | `--sc-kit--dropdown-item--text-align` | Text alignment | `left` |
38
+ | `--sc-kit--dropdown-item--border-radius` | Item border radius | `0` |
39
+ -->
40
+
41
+ <style>.dropdown-item {
42
+ --_dropdown-item--min-width: var(--sc-kit--dropdown-item--min-width, max-content);
43
+ --_dropdown-item--font-size: var(--sc-kit--dropdown-item--font-size, 0.875rem);
44
+ --_dropdown-item--padding: var(--sc-kit--dropdown-item--padding, 0.625rem 0.875rem);
45
+ --_dropdown-item--color: var(--sc-kit--dropdown-item--color, light-dark(#2e2e2e, #ffffff));
46
+ --_dropdown-item--color--hover: var(--sc-kit--dropdown-item--color--hover, light-dark(#2e2e2e, #ffffff));
47
+ --_dropdown-item--color--disabled: var(--sc-kit--dropdown-item--color--disabled, light-dark(#9ca3af, #6b7280));
48
+ --_dropdown-item--background: var(--sc-kit--dropdown-item--background, light-dark(#ffffff, #1c1c1c));
49
+ --_dropdown-item--background--hover: var(
50
+ --sc-kit--dropdown-item--background--hover,
51
+ light-dark(#f2f2f3, #1f2937)
52
+ );
53
+ --_dropdown-item--separator-color: var(--sc-kit--dropdown-item--separator-color, light-dark(#e5e7eb, #374151));
54
+ --_dropdown-item--text-align: var(--sc-kit--dropdown-item--text-align, left);
55
+ --_dropdown-item--border-radius: var(--sc-kit--dropdown-item--border-radius, 0);
56
+ --_dropdown-item--separator-indent: var(--sc-kit--dropdown-item--separator-indent, 0.875rem);
57
+ cursor: pointer;
58
+ color: var(--_dropdown-item--color);
59
+ min-width: var(--_dropdown-item--min-width);
60
+ position: relative;
61
+ text-align: var(--_dropdown-item--text-align);
62
+ background: var(--_dropdown-item--background);
63
+ border-radius: var(--_dropdown-item--border-radius);
64
+ display: flex;
65
+ align-items: center;
66
+ padding: var(--_dropdown-item--padding);
67
+ }
68
+ .dropdown-item__content {
69
+ font-size: var(--_dropdown-item--font-size);
70
+ line-height: 1.2;
71
+ flex: 1;
72
+ }
73
+ .dropdown-item:before {
74
+ content: "";
75
+ display: block;
76
+ width: calc(100% - 2 * var(--_dropdown-item--separator-indent));
77
+ height: 1px;
78
+ background: var(--_dropdown-item--separator-color);
79
+ position: absolute;
80
+ bottom: 0;
81
+ left: var(--_dropdown-item--separator-indent);
82
+ }
83
+ .dropdown-item:last-child:before {
84
+ display: none;
85
+ }
86
+ .dropdown-item:hover {
87
+ color: var(--_dropdown-item--color--hover);
88
+ background: var(--_dropdown-item--background--hover);
89
+ }
90
+ .dropdown-item--disabled {
91
+ color: var(--_dropdown-item--color--disabled);
92
+ pointer-events: none;
93
+ }</style>
@@ -0,0 +1,32 @@
1
+ import type { Snippet } from 'svelte';
2
+ type Props = {
3
+ disabled?: boolean;
4
+ /** Prevent dropdown from closing on click */
5
+ keepDropdownOpen?: boolean;
6
+ on?: {
7
+ click?: () => void;
8
+ };
9
+ children: Snippet;
10
+ };
11
+ /**
12
+ * A single item within a dropdown menu. Supports hover state, disabled state, and separator lines between items.
13
+ *
14
+ * ### CSS Custom Properties
15
+ * | Property | Description | Default |
16
+ * |---|---|---|
17
+ * | `--sc-kit--dropdown-item--min-width` | Minimum item width | `max-content` |
18
+ * | `--sc-kit--dropdown-item--font-size` | Content font size | `0.875rem` |
19
+ * | `--sc-kit--dropdown-item--padding` | Item padding | `0.625rem 0.875rem` |
20
+ * | `--sc-kit--dropdown-item--color` | Text color | light-dark gray-800/white |
21
+ * | `--sc-kit--dropdown-item--color--hover` | Text color on hover | light-dark gray-800/white |
22
+ * | `--sc-kit--dropdown-item--color--disabled` | Text color when disabled | light-dark neutral-400/neutral-500 |
23
+ * | `--sc-kit--dropdown-item--background` | Background color | light-dark white/gray-900 |
24
+ * | `--sc-kit--dropdown-item--background--hover` | Background on hover | light-dark neutral-100/neutral-800 |
25
+ * | `--sc-kit--dropdown-item--separator-color` | Separator line color | light-dark neutral-200/neutral-700 |
26
+ * | `--sc-kit--dropdown-item--separator-indent` | Separator horizontal indent | `0.875rem` |
27
+ * | `--sc-kit--dropdown-item--text-align` | Text alignment | `left` |
28
+ * | `--sc-kit--dropdown-item--border-radius` | Item border radius | `0` |
29
+ */
30
+ declare const Cmp: import("svelte").Component<Props, {}, "">;
31
+ type Cmp = ReturnType<typeof Cmp>;
32
+ export default Cmp;
@@ -0,0 +1,29 @@
1
+ <script lang="ts">const { children } = $props();
2
+ export {};
3
+ </script>
4
+
5
+ <div class="dropdown-panel">
6
+ {@render children()}
7
+ </div>
8
+
9
+ <!--
10
+ @component
11
+ Visual panel wrapper for dropdown content — provides background, box-shadow, and border-radius.
12
+ Typically used as a direct child of `Dropdown`.
13
+
14
+ ### CSS Custom Properties
15
+ | Property | Description | Default |
16
+ |---|---|---|
17
+ | `--sc-kit--dropdown-panel--background` | Panel background | light-dark white/gray-900 |
18
+ | `--sc-kit--dropdown-panel--box-shadow` | Panel shadow | `0 2px 10px` light rgb(0 0 0 / 15%), dark rgb(255 255 255 / 20%) |
19
+ | `--sc-kit--dropdown-panel--border-radius` | Corner radius | `0` |
20
+ -->
21
+
22
+ <style>.dropdown-panel {
23
+ --_dropdown-panel--background: var(--sc-kit--dropdown-panel--background, light-dark(#ffffff, #1c1c1c));
24
+ --_dropdown-panel--box-shadow: var(--sc-kit--dropdown-panel--box-shadow, 0 2px 10px light-dark(rgb(0 0 0 / 15%), rgb(255 255 255 / 20%)));
25
+ --_dropdown-panel--border-radius: var(--sc-kit--dropdown-panel--border-radius, 0);
26
+ background: var(--_dropdown-panel--background);
27
+ box-shadow: var(--_dropdown-panel--box-shadow);
28
+ border-radius: var(--_dropdown-panel--border-radius);
29
+ }</style>
@@ -0,0 +1,18 @@
1
+ import type { Snippet } from 'svelte';
2
+ type Props = {
3
+ children: Snippet;
4
+ };
5
+ /**
6
+ * Visual panel wrapper for dropdown content — provides background, box-shadow, and border-radius.
7
+ * Typically used as a direct child of `Dropdown`.
8
+ *
9
+ * ### CSS Custom Properties
10
+ * | Property | Description | Default |
11
+ * |---|---|---|
12
+ * | `--sc-kit--dropdown-panel--background` | Panel background | light-dark white/gray-900 |
13
+ * | `--sc-kit--dropdown-panel--box-shadow` | Panel shadow | `0 2px 10px` light rgb(0 0 0 / 15%), dark rgb(255 255 255 / 20%) |
14
+ * | `--sc-kit--dropdown-panel--border-radius` | Corner radius | `0` |
15
+ */
16
+ declare const Cmp: import("svelte").Component<Props, {}, "">;
17
+ type Cmp = ReturnType<typeof Cmp>;
18
+ export default Cmp;
@@ -3,9 +3,10 @@ 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 = 8, boundaryMargin = 8, backdrop = false, isOpenRequested, on, children, trigger } = $props();
6
+ let { position = 'bottom-start', disabled = false, keepDropdownOpen = false, fixedPosition = false, offset = 4, boundaryMargin = 8, backdrop = false, isOpenRequested, matchTriggerWidth = false, on, children, trigger } = $props();
7
7
  let opened = $state(false);
8
8
  let dropdownEl = $state(null);
9
+ let actualPlacement = $state(untrack(() => position));
9
10
  $effect(() => untrack(() => {
10
11
  on?.mounted?.({
11
12
  toggleOpen: (value) => {
@@ -104,6 +105,23 @@ const initPopper = (node) => {
104
105
  boundary: document.body,
105
106
  padding: boundaryMargin
106
107
  }
108
+ },
109
+ {
110
+ name: 'sameWidth',
111
+ enabled: matchTriggerWidth,
112
+ phase: 'beforeWrite',
113
+ requires: ['computeStyles'],
114
+ fn: ({ state }) => {
115
+ state.styles.popper.width = `${state.rects.reference.width}px`;
116
+ }
117
+ },
118
+ {
119
+ name: 'syncPlacement',
120
+ enabled: true,
121
+ phase: 'afterWrite',
122
+ fn: ({ state }) => {
123
+ actualPlacement = state.placement;
124
+ }
107
125
  }
108
126
  ]
109
127
  });
@@ -135,8 +153,8 @@ const initPopper = (node) => {
135
153
  {/if}
136
154
  </button>
137
155
  {#if opened}
138
- <div use:initPopper class="dropdown__popper" role="tooltip" tabindex="-1">
139
- <div class="dropdown__content">
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}>
140
158
  {@render children()}
141
159
  </div>
142
160
  </div>
@@ -145,7 +163,7 @@ const initPopper = (node) => {
145
163
 
146
164
  <!--
147
165
  @component
148
- A Popper.js-powered dropdown that positions content relative to a trigger element, with click-outside-to-close, optional backdrop, and imperative open/close control.
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.
149
167
 
150
168
  ### CSS Custom Properties
151
169
  | Property | Description | Default |
@@ -183,12 +201,59 @@ A Popper.js-powered dropdown that positions content relative to a trigger elemen
183
201
  }
184
202
  .dropdown__popper {
185
203
  z-index: 999;
204
+ --_dd-origin-y: top;
205
+ --_dd-shift-x: 0;
206
+ --_dd-shift-y: -4px;
207
+ --_dd-origin-x: left;
208
+ }
209
+ .dropdown__popper[data-placement=bottom] {
210
+ --_dd-origin-x: center;
211
+ }
212
+ .dropdown__popper[data-placement=bottom-end] {
213
+ --_dd-origin-x: right;
214
+ }
215
+ .dropdown__popper[data-placement^=top] {
216
+ --_dd-origin-y: bottom;
217
+ --_dd-shift-y: 4px;
218
+ }
219
+ .dropdown__popper[data-placement=top] {
220
+ --_dd-origin-x: center;
221
+ }
222
+ .dropdown__popper[data-placement=top-end] {
223
+ --_dd-origin-x: right;
224
+ }
225
+ .dropdown__popper[data-placement^=left] {
226
+ --_dd-origin-x: right;
227
+ --_dd-origin-y: top;
228
+ --_dd-shift-x: 4px;
229
+ --_dd-shift-y: 0;
230
+ }
231
+ .dropdown__popper[data-placement=left] {
232
+ --_dd-origin-y: center;
233
+ }
234
+ .dropdown__popper[data-placement=left-end] {
235
+ --_dd-origin-y: bottom;
236
+ }
237
+ .dropdown__popper[data-placement^=right] {
238
+ --_dd-origin-x: left;
239
+ --_dd-origin-y: top;
240
+ --_dd-shift-x: -4px;
241
+ --_dd-shift-y: 0;
242
+ }
243
+ .dropdown__popper[data-placement=right] {
244
+ --_dd-origin-y: center;
245
+ }
246
+ .dropdown__popper[data-placement=right-end] {
247
+ --_dd-origin-y: bottom;
186
248
  }
187
249
  .dropdown__content {
188
250
  width: max-content;
189
- transform-origin: top left;
251
+ transform-origin: var(--_dd-origin-x) var(--_dd-origin-y);
190
252
  animation: dropdown-appear 150ms cubic-bezier(0, 0, 0.2, 1) both;
191
253
  }
254
+ .dropdown__content--match-width {
255
+ width: 100%;
256
+ }
192
257
  .dropdown :global([data-popper-escaped]) {
193
258
  visibility: hidden !important;
194
259
  }
@@ -196,10 +261,10 @@ A Popper.js-powered dropdown that positions content relative to a trigger elemen
196
261
  @keyframes dropdown-appear {
197
262
  from {
198
263
  opacity: 0;
199
- transform: scale(0.95) translateY(-4px);
264
+ transform: scale(0.95) translate(var(--_dd-shift-x), var(--_dd-shift-y));
200
265
  }
201
266
  to {
202
267
  opacity: 1;
203
- transform: scale(1) translateY(0);
268
+ transform: scale(1) translate(0, 0);
204
269
  }
205
270
  }</style>
@@ -16,6 +16,8 @@ type Props = {
16
16
  backdrop?: boolean;
17
17
  /** Programmatically request the dropdown to open */
18
18
  isOpenRequested?: boolean;
19
+ /** Make the popper content match the trigger element width */
20
+ matchTriggerWidth?: boolean;
19
21
  on?: {
20
22
  opened?: () => void;
21
23
  closed?: () => void;
@@ -29,7 +31,7 @@ type Props = {
29
31
  trigger?: Snippet;
30
32
  };
31
33
  /**
32
- * A Popper.js-powered dropdown that positions content relative to a trigger element, with click-outside-to-close, optional backdrop, and imperative open/close control.
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.
33
35
  *
34
36
  * ### CSS Custom Properties
35
37
  * | Property | Description | Default |
@@ -1,3 +1,5 @@
1
1
  export { default as Dropdown } from './cmp.dropdown.svelte';
2
+ export { default as DropdownItem } from './cmp.dropdown-item.svelte';
3
+ export { default as DropdownPanel } from './cmp.dropdown-panel.svelte';
2
4
  export type { Placement as DropdownPosition } from '@popperjs/core';
3
5
  export { dropdownIgnore } from './dropdown-ignore';
@@ -1,2 +1,4 @@
1
1
  export { default as Dropdown } from './cmp.dropdown.svelte';
2
+ export { default as DropdownItem } from './cmp.dropdown-item.svelte';
3
+ export { default as DropdownPanel } from './cmp.dropdown-panel.svelte';
2
4
  export { dropdownIgnore } from './dropdown-ignore';
@@ -7,9 +7,4 @@ export {};
7
7
  <!--
8
8
  @component
9
9
  Renders a dynamic Svelte component from a model object, spreading its props automatically.
10
-
11
- ### Props
12
- | Prop | Type | Description |
13
- |---|---|---|
14
- | `model` | `DynamicComponentModel` | Component reference and its props to render |
15
10
  -->
@@ -1,15 +1,9 @@
1
1
  import type { DynamicComponentModel } from './types.svelte';
2
2
  type Props = {
3
+ /** Component reference and its props to render */
3
4
  model: DynamicComponentModel;
4
5
  };
5
- /**
6
- * Renders a dynamic Svelte component from a model object, spreading its props automatically.
7
- *
8
- * ### Props
9
- * | Prop | Type | Description |
10
- * |---|---|---|
11
- * | `model` | `DynamicComponentModel` | Component reference and its props to render |
12
- */
6
+ /** Renders a dynamic Svelte component from a model object, spreading its props automatically. */
13
7
  declare const Cmp: import("svelte").Component<Props, {}, "">;
14
8
  type Cmp = ReturnType<typeof Cmp>;
15
9
  export default Cmp;