@sveltia/ui 0.8.3 → 0.10.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 (122) hide show
  1. package/package/components/alert/alert.svelte +2 -4
  2. package/package/components/alert/alert.svelte.d.ts +2 -2
  3. package/package/components/button/button.svelte +78 -26
  4. package/package/components/button/button.svelte.d.ts +73 -63
  5. package/package/components/button/select-button-group.svelte +6 -1
  6. package/package/components/button/select-button-group.svelte.d.ts +13 -13
  7. package/package/components/button/select-button.svelte +2 -1
  8. package/package/components/button/select-button.svelte.d.ts +19 -19
  9. package/package/components/button/split-button.svelte +111 -0
  10. package/package/components/button/split-button.svelte.d.ts +69 -0
  11. package/package/components/calendar/calendar.svelte +2 -2
  12. package/package/components/calendar/calendar.svelte.d.ts +2 -2
  13. package/package/components/checkbox/checkbox-group.svelte.d.ts +7 -7
  14. package/package/components/checkbox/checkbox.svelte +8 -6
  15. package/package/components/checkbox/checkbox.svelte.d.ts +22 -16
  16. package/package/components/dialog/alert-dialog.svelte.d.ts +6 -6
  17. package/package/components/dialog/confirmation-dialog.svelte.d.ts +8 -8
  18. package/package/components/dialog/dialog.svelte +17 -15
  19. package/package/components/dialog/dialog.svelte.d.ts +30 -24
  20. package/package/components/dialog/prompt-dialog.svelte +1 -1
  21. package/package/components/dialog/prompt-dialog.svelte.d.ts +12 -12
  22. package/package/components/disclosure/disclosure.svelte +6 -1
  23. package/package/components/disclosure/disclosure.svelte.d.ts +29 -19
  24. package/package/components/divider/divider.svelte.d.ts +5 -5
  25. package/package/components/divider/spacer.svelte.d.ts +4 -4
  26. package/package/components/drawer/drawer.svelte +34 -16
  27. package/package/components/drawer/drawer.svelte.d.ts +22 -16
  28. package/package/components/grid/grid-body.svelte.d.ts +4 -4
  29. package/package/components/grid/grid-cell.svelte.d.ts +2 -2
  30. package/package/components/grid/grid-col-header.svelte.d.ts +2 -2
  31. package/package/components/grid/grid-foot.svelte.d.ts +2 -2
  32. package/package/components/grid/grid-head.svelte.d.ts +2 -2
  33. package/package/components/grid/grid-row-header.svelte.d.ts +2 -2
  34. package/package/components/grid/grid-row.svelte +10 -2
  35. package/package/components/grid/grid-row.svelte.d.ts +8 -8
  36. package/package/components/grid/grid.svelte +7 -2
  37. package/package/components/grid/grid.svelte.d.ts +8 -8
  38. package/package/components/icon/icon.svelte.d.ts +4 -4
  39. package/package/components/listbox/listbox.svelte +11 -5
  40. package/package/components/listbox/listbox.svelte.d.ts +15 -15
  41. package/package/components/listbox/option-group.svelte.d.ts +7 -7
  42. package/package/components/listbox/option.svelte +4 -2
  43. package/package/components/listbox/option.svelte.d.ts +15 -13
  44. package/package/components/menu/menu-button.svelte +18 -2
  45. package/package/components/menu/menu-button.svelte.d.ts +20 -16
  46. package/package/components/menu/menu-item-checkbox.svelte +1 -1
  47. package/package/components/menu/menu-item-checkbox.svelte.d.ts +16 -16
  48. package/package/components/menu/menu-item-group.svelte +1 -1
  49. package/package/components/menu/menu-item-group.svelte.d.ts +7 -7
  50. package/package/components/menu/menu-item-radio.svelte +1 -1
  51. package/package/components/menu/menu-item-radio.svelte.d.ts +16 -16
  52. package/package/components/menu/menu-item.svelte +32 -19
  53. package/package/components/menu/menu-item.svelte.d.ts +32 -18
  54. package/package/components/menu/menu.svelte +13 -7
  55. package/package/components/menu/menu.svelte.d.ts +7 -7
  56. package/package/components/radio/radio-group.svelte +6 -1
  57. package/package/components/radio/radio-group.svelte.d.ts +15 -15
  58. package/package/components/radio/radio.svelte +1 -1
  59. package/package/components/radio/radio.svelte.d.ts +14 -14
  60. package/package/components/select/combobox.svelte +10 -8
  61. package/package/components/select/combobox.svelte.d.ts +22 -16
  62. package/package/components/select/select.svelte.d.ts +12 -12
  63. package/package/components/slider/slider.svelte +26 -22
  64. package/package/components/slider/slider.svelte.d.ts +23 -23
  65. package/package/components/switch/switch.svelte +5 -0
  66. package/package/components/switch/switch.svelte.d.ts +18 -14
  67. package/package/components/table/table-body.svelte.d.ts +4 -4
  68. package/package/components/table/table-cell.svelte.d.ts +2 -2
  69. package/package/components/table/table-col-header.svelte.d.ts +2 -2
  70. package/package/components/table/table-foot.svelte.d.ts +2 -2
  71. package/package/components/table/table-head.svelte.d.ts +2 -2
  72. package/package/components/table/table-row-header.svelte.d.ts +2 -2
  73. package/package/components/table/table-row.svelte.d.ts +2 -2
  74. package/package/components/table/table.svelte.d.ts +2 -2
  75. package/package/components/tabs/tab-box.svelte +30 -0
  76. package/package/components/tabs/tab-box.svelte.d.ts +33 -0
  77. package/package/components/tabs/tab-list.svelte +105 -22
  78. package/package/components/tabs/tab-list.svelte.d.ts +10 -10
  79. package/package/components/tabs/tab-panel.svelte +6 -2
  80. package/package/components/tabs/tab-panel.svelte.d.ts +2 -2
  81. package/package/components/tabs/tab-panels.svelte +32 -0
  82. package/package/components/tabs/tab-panels.svelte.d.ts +31 -0
  83. package/package/components/tabs/tab.svelte.d.ts +11 -11
  84. package/package/components/text-field/markdown-editor.svelte.d.ts +12 -12
  85. package/package/components/text-field/number-input.svelte +11 -4
  86. package/package/components/text-field/number-input.svelte.d.ts +40 -20
  87. package/package/components/text-field/password-input.svelte +7 -3
  88. package/package/components/text-field/password-input.svelte.d.ts +30 -18
  89. package/package/components/text-field/search-bar.svelte +7 -3
  90. package/package/components/text-field/search-bar.svelte.d.ts +46 -36
  91. package/package/components/text-field/text-area.svelte +4 -2
  92. package/package/components/text-field/text-area.svelte.d.ts +25 -21
  93. package/package/components/text-field/text-input.svelte +17 -2
  94. package/package/components/text-field/text-input.svelte.d.ts +53 -53
  95. package/package/components/toast/toast.svelte +16 -12
  96. package/package/components/toast/toast.svelte.d.ts +8 -8
  97. package/package/components/toolbar/toolbar.svelte.d.ts +8 -8
  98. package/package/components/util/app-shell.svelte +162 -74
  99. package/package/components/util/app-shell.svelte.d.ts +2 -0
  100. package/package/components/util/group.svelte.d.ts +5 -5
  101. package/package/components/util/modal.svelte +26 -9
  102. package/package/components/util/modal.svelte.d.ts +34 -34
  103. package/package/components/util/popup.svelte +58 -32
  104. package/package/components/util/popup.svelte.d.ts +34 -24
  105. package/package/components/util/portal.svelte +5 -3
  106. package/package/components/util/portal.svelte.d.ts +2 -2
  107. package/package/index.d.ts +6 -3
  108. package/package/index.js +7 -4
  109. package/package/locales/en.d.ts +4 -0
  110. package/package/locales/en.js +4 -0
  111. package/package/locales/ja.d.ts +4 -0
  112. package/package/locales/ja.js +4 -0
  113. package/package/services/events.d.ts +1 -1
  114. package/package/services/events.js +11 -8
  115. package/package/services/group.js +73 -30
  116. package/package/services/popup.d.ts +28 -11
  117. package/package/services/popup.js +27 -10
  118. package/package/services/util.d.ts +2 -2
  119. package/package/services/util.js +5 -5
  120. package/package/styles/core.scss +1 -0
  121. package/package/styles/variables.scss +24 -4
  122. package/package.json +49 -25
@@ -7,6 +7,12 @@
7
7
  <script>
8
8
  import { onMount } from 'svelte';
9
9
 
10
+ /**
11
+ * Orientation of the app shell’s children.
12
+ * @type {'horizontal' | 'vertical' | undefined}
13
+ */
14
+ export let orientation = undefined;
15
+
10
16
  const stylesheets = [
11
17
  // https://fonts.google.com/share?selection.family=Merriweather%20Sans:ital,wght@0,300;0,600;1,300%7CNoto%20Sans%20Mono
12
18
  'https://fonts.googleapis.com/css2?family=Merriweather+Sans:ital,wght@0,300;0,600;1,300&family=Noto+Sans+Mono&display=swap',
@@ -15,7 +21,7 @@
15
21
  'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block',
16
22
  ];
17
23
 
18
- /** @type {HTMLElement} */
24
+ /** @type {HTMLElement | undefined} */
19
25
  let fontLoader;
20
26
 
21
27
  onMount(() => {
@@ -23,7 +29,7 @@
23
29
  const { dataset } = document.documentElement;
24
30
 
25
31
  /**
26
- *
32
+ * Apply the Dark or Light theme.
27
33
  */
28
34
  const applyTheme = () => {
29
35
  if (dataset.autoTheming !== 'false') {
@@ -33,9 +39,7 @@
33
39
 
34
40
  applyTheme();
35
41
 
36
- /**
37
- *
38
- */
42
+ // eslint-disable-next-line jsdoc/require-jsdoc
39
43
  mediaQuery.onchange = () => {
40
44
  applyTheme();
41
45
  };
@@ -65,7 +69,7 @@
65
69
 
66
70
  <div
67
71
  role="none"
68
- class="sui app-shell"
72
+ class="sui app-shell {orientation ?? ''}"
69
73
  {...$$restProps}
70
74
  on:dragover|preventDefault
71
75
  on:drop|preventDefault
@@ -84,74 +88,6 @@
84
88
 
85
89
  <style global>@import url("https://fonts.googleapis.com/css2?family=Merriweather+Sans:ital,wght@0,300;0,600;1,300&family=Noto+Sans+Mono&display=swap");
86
90
  @import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block");
87
- :global(:root[data-theme=light]),
88
- :global(:host[data-theme=light]) {
89
- --sui-foreground-color-1-hsl: var(--sui-base-hue) 5% 5%;
90
- --sui-foreground-color-2-hsl: var(--sui-base-hue) 5% 25%;
91
- --sui-foreground-color-3-hsl: var(--sui-base-hue) 5% 35%;
92
- --sui-foreground-color-4-hsl: var(--sui-base-hue) 5% 45%;
93
- --sui-foreground-color-5-hsl: var(--sui-base-hue) 5% 65%;
94
- --sui-background-color-1-hsl: var(--sui-base-hue) 5% 100%;
95
- --sui-background-color-2-hsl: var(--sui-base-hue) 5% 98%;
96
- --sui-background-color-3-hsl: var(--sui-base-hue) 5% 96%;
97
- --sui-background-color-4-hsl: var(--sui-base-hue) 5% 94%;
98
- --sui-background-color-5-hsl: var(--sui-base-hue) 5% 74%;
99
- --sui-border-color-1-hsl: var(--sui-base-hue) 5% 50%;
100
- --sui-border-color-2-hsl: var(--sui-base-hue) 5% 74%;
101
- --sui-border-color-3-hsl: var(--sui-base-hue) 5% 70%;
102
- --sui-shadow-color: var(--sui-base-hue) 10% 0%;
103
- --sui-primary-accent-color-text: hsl(var(--sui-base-hue) 80% 40%);
104
- --sui-primary-accent-color-light: hsl(var(--sui-base-hue) 80% 45%);
105
- --sui-primary-accent-color: hsl(var(--sui-base-hue) 80% 40%);
106
- --sui-primary-accent-color-dark: hsl(var(--sui-base-hue) 80% 35%);
107
- --sui-primary-accent-color-inverted: hsl(var(--sui-base-hue) 10% 100%);
108
- --sui-primary-accent-color-translucent: hsl(var(--sui-base-hue) 80% 50% / 40%);
109
- --sui-error-color-hue: 0;
110
- --sui-warning-color-hue: 40;
111
- --sui-info-color-hue: 210;
112
- --sui-success-color-hue: 100;
113
- --sui-alert-foreground-color-saturation: 85%;
114
- --sui-alert-foreground-color-lightness: 25%;
115
- --sui-alert-background-color-saturation: 65%;
116
- --sui-alert-background-color-lightness: 90%;
117
- --sui-alert-border-color-saturation: 48%;
118
- --sui-alert-border-color-lightness: 68%;
119
- }
120
-
121
- :global(:root[data-theme=dark]),
122
- :global(:host[data-theme=dark]) {
123
- --sui-foreground-color-1-hsl: var(--sui-base-hue) 10% 95%;
124
- --sui-foreground-color-2-hsl: var(--sui-base-hue) 10% 75%;
125
- --sui-foreground-color-3-hsl: var(--sui-base-hue) 10% 65%;
126
- --sui-foreground-color-4-hsl: var(--sui-base-hue) 10% 55%;
127
- --sui-foreground-color-5-hsl: var(--sui-base-hue) 10% 35%;
128
- --sui-background-color-1-hsl: var(--sui-base-hue) 10% 10%;
129
- --sui-background-color-2-hsl: var(--sui-base-hue) 10% 12%;
130
- --sui-background-color-3-hsl: var(--sui-base-hue) 10% 14%;
131
- --sui-background-color-4-hsl: var(--sui-base-hue) 10% 16%;
132
- --sui-background-color-5-hsl: var(--sui-base-hue) 10% 26%;
133
- --sui-border-color-1-hsl: var(--sui-base-hue) 10% 50%;
134
- --sui-border-color-2-hsl: var(--sui-base-hue) 10% 26%;
135
- --sui-border-color-3-hsl: var(--sui-base-hue) 10% 22%;
136
- --sui-shadow-color: var(--sui-base-hue) 10% 0%;
137
- --sui-primary-accent-color-text: hsl(var(--sui-base-hue) 100% 60%);
138
- --sui-primary-accent-color-light: hsl(var(--sui-base-hue) 100% 45%);
139
- --sui-primary-accent-color: hsl(var(--sui-base-hue) 100% 40%);
140
- --sui-primary-accent-color-dark: hsl(var(--sui-base-hue) 100% 35%);
141
- --sui-primary-accent-color-inverted: hsl(var(--sui-base-hue) 10% 100%);
142
- --sui-primary-accent-color-translucent: hsl(var(--sui-base-hue) 80% 50% / 40%);
143
- --sui-error-color-hue: 0;
144
- --sui-warning-color-hue: 40;
145
- --sui-info-color-hue: 210;
146
- --sui-success-color-hue: 100;
147
- --sui-alert-foreground-color-saturation: 85%;
148
- --sui-alert-foreground-color-lightness: 75%;
149
- --sui-alert-background-color-saturation: 40%;
150
- --sui-alert-background-color-lightness: 10%;
151
- --sui-alert-border-color-saturation: 38%;
152
- --sui-alert-border-color-lightness: 18%;
153
- }
154
-
155
91
  :global(:root),
156
92
  :global(:host) {
157
93
  --sui-base-hue: 210;
@@ -290,6 +226,7 @@
290
226
  --sui-textbox-singleline-line-height: var(--sui-line-height-compact);
291
227
  --sui-textbox-multiline-min-width: 480px;
292
228
  --sui-textbox-multiline-line-height: var(--sui-line-height-comfortable);
229
+ --sui-tab-height: var(--sui-control-medium-height);
293
230
  --sui-tab-small-height: var(--sui-control-small-height);
294
231
  --sui-tab-medium-height: var(--sui-control-medium-height);
295
232
  --sui-tab-large-height: var(--sui-control-large-height);
@@ -319,6 +256,146 @@
319
256
  --sui-tertiary-background-color-translucent: hsl(var(--sui-background-color-4-hsl));
320
257
  }
321
258
  }
259
+ :global(:root[data-theme=light]),
260
+ :global(:host[data-theme=light]) {
261
+ color-scheme: light;
262
+ --sui-foreground-color-1-hsl: var(--sui-base-hue) 5% 5%;
263
+ --sui-foreground-color-2-hsl: var(--sui-base-hue) 5% 25%;
264
+ --sui-foreground-color-3-hsl: var(--sui-base-hue) 5% 35%;
265
+ --sui-foreground-color-4-hsl: var(--sui-base-hue) 5% 45%;
266
+ --sui-foreground-color-5-hsl: var(--sui-base-hue) 5% 65%;
267
+ --sui-background-color-1-hsl: var(--sui-base-hue) 5% 100%;
268
+ --sui-background-color-2-hsl: var(--sui-base-hue) 5% 98%;
269
+ --sui-background-color-3-hsl: var(--sui-base-hue) 5% 96%;
270
+ --sui-background-color-4-hsl: var(--sui-base-hue) 5% 94%;
271
+ --sui-background-color-5-hsl: var(--sui-base-hue) 5% 74%;
272
+ --sui-border-color-1-hsl: var(--sui-base-hue) 5% 50%;
273
+ --sui-border-color-2-hsl: var(--sui-base-hue) 5% 74%;
274
+ --sui-border-color-3-hsl: var(--sui-base-hue) 5% 70%;
275
+ --sui-shadow-color: var(--sui-base-hue) 10% 0%;
276
+ --sui-primary-accent-color-text: hsl(var(--sui-base-hue) 80% 40%);
277
+ --sui-primary-accent-color-light: hsl(var(--sui-base-hue) 80% 45%);
278
+ --sui-primary-accent-color: hsl(var(--sui-base-hue) 80% 40%);
279
+ --sui-primary-accent-color-dark: hsl(var(--sui-base-hue) 80% 35%);
280
+ --sui-primary-accent-color-inverted: hsl(var(--sui-base-hue) 10% 100%);
281
+ --sui-primary-accent-color-translucent: hsl(var(--sui-base-hue) 80% 50% / 40%);
282
+ --sui-error-color-hue: 0;
283
+ --sui-warning-color-hue: 40;
284
+ --sui-info-color-hue: 210;
285
+ --sui-success-color-hue: 100;
286
+ --sui-alert-foreground-color-saturation: 85%;
287
+ --sui-alert-foreground-color-lightness: 25%;
288
+ --sui-alert-background-color-saturation: 65%;
289
+ --sui-alert-background-color-lightness: 90%;
290
+ --sui-alert-border-color-saturation: 48%;
291
+ --sui-alert-border-color-lightness: 68%;
292
+ }
293
+ :global(:root[data-theme=dark]),
294
+ :global(:host[data-theme=dark]) {
295
+ color-scheme: dark;
296
+ --sui-foreground-color-1-hsl: var(--sui-base-hue) 10% 95%;
297
+ --sui-foreground-color-2-hsl: var(--sui-base-hue) 10% 75%;
298
+ --sui-foreground-color-3-hsl: var(--sui-base-hue) 10% 65%;
299
+ --sui-foreground-color-4-hsl: var(--sui-base-hue) 10% 55%;
300
+ --sui-foreground-color-5-hsl: var(--sui-base-hue) 10% 35%;
301
+ --sui-background-color-1-hsl: var(--sui-base-hue) 10% 10%;
302
+ --sui-background-color-2-hsl: var(--sui-base-hue) 10% 12%;
303
+ --sui-background-color-3-hsl: var(--sui-base-hue) 10% 14%;
304
+ --sui-background-color-4-hsl: var(--sui-base-hue) 10% 16%;
305
+ --sui-background-color-5-hsl: var(--sui-base-hue) 10% 26%;
306
+ --sui-border-color-1-hsl: var(--sui-base-hue) 10% 50%;
307
+ --sui-border-color-2-hsl: var(--sui-base-hue) 10% 26%;
308
+ --sui-border-color-3-hsl: var(--sui-base-hue) 10% 22%;
309
+ --sui-shadow-color: var(--sui-base-hue) 10% 0%;
310
+ --sui-primary-accent-color-text: hsl(var(--sui-base-hue) 100% 60%);
311
+ --sui-primary-accent-color-light: hsl(var(--sui-base-hue) 100% 45%);
312
+ --sui-primary-accent-color: hsl(var(--sui-base-hue) 100% 40%);
313
+ --sui-primary-accent-color-dark: hsl(var(--sui-base-hue) 100% 35%);
314
+ --sui-primary-accent-color-inverted: hsl(var(--sui-base-hue) 10% 100%);
315
+ --sui-primary-accent-color-translucent: hsl(var(--sui-base-hue) 80% 50% / 40%);
316
+ --sui-error-color-hue: 0;
317
+ --sui-warning-color-hue: 40;
318
+ --sui-info-color-hue: 210;
319
+ --sui-success-color-hue: 100;
320
+ --sui-alert-foreground-color-saturation: 85%;
321
+ --sui-alert-foreground-color-lightness: 75%;
322
+ --sui-alert-background-color-saturation: 40%;
323
+ --sui-alert-background-color-lightness: 10%;
324
+ --sui-alert-border-color-saturation: 38%;
325
+ --sui-alert-border-color-lightness: 18%;
326
+ }
327
+ @media (prefers-color-scheme: light) {
328
+ :global(:root:not([data-theme])),
329
+ :global(:host:not([data-theme])) {
330
+ color-scheme: light;
331
+ --sui-foreground-color-1-hsl: var(--sui-base-hue) 5% 5%;
332
+ --sui-foreground-color-2-hsl: var(--sui-base-hue) 5% 25%;
333
+ --sui-foreground-color-3-hsl: var(--sui-base-hue) 5% 35%;
334
+ --sui-foreground-color-4-hsl: var(--sui-base-hue) 5% 45%;
335
+ --sui-foreground-color-5-hsl: var(--sui-base-hue) 5% 65%;
336
+ --sui-background-color-1-hsl: var(--sui-base-hue) 5% 100%;
337
+ --sui-background-color-2-hsl: var(--sui-base-hue) 5% 98%;
338
+ --sui-background-color-3-hsl: var(--sui-base-hue) 5% 96%;
339
+ --sui-background-color-4-hsl: var(--sui-base-hue) 5% 94%;
340
+ --sui-background-color-5-hsl: var(--sui-base-hue) 5% 74%;
341
+ --sui-border-color-1-hsl: var(--sui-base-hue) 5% 50%;
342
+ --sui-border-color-2-hsl: var(--sui-base-hue) 5% 74%;
343
+ --sui-border-color-3-hsl: var(--sui-base-hue) 5% 70%;
344
+ --sui-shadow-color: var(--sui-base-hue) 10% 0%;
345
+ --sui-primary-accent-color-text: hsl(var(--sui-base-hue) 80% 40%);
346
+ --sui-primary-accent-color-light: hsl(var(--sui-base-hue) 80% 45%);
347
+ --sui-primary-accent-color: hsl(var(--sui-base-hue) 80% 40%);
348
+ --sui-primary-accent-color-dark: hsl(var(--sui-base-hue) 80% 35%);
349
+ --sui-primary-accent-color-inverted: hsl(var(--sui-base-hue) 10% 100%);
350
+ --sui-primary-accent-color-translucent: hsl(var(--sui-base-hue) 80% 50% / 40%);
351
+ --sui-error-color-hue: 0;
352
+ --sui-warning-color-hue: 40;
353
+ --sui-info-color-hue: 210;
354
+ --sui-success-color-hue: 100;
355
+ --sui-alert-foreground-color-saturation: 85%;
356
+ --sui-alert-foreground-color-lightness: 25%;
357
+ --sui-alert-background-color-saturation: 65%;
358
+ --sui-alert-background-color-lightness: 90%;
359
+ --sui-alert-border-color-saturation: 48%;
360
+ --sui-alert-border-color-lightness: 68%;
361
+ }
362
+ }
363
+ @media (prefers-color-scheme: dark) {
364
+ :global(:root:not([data-theme])),
365
+ :global(:host:not([data-theme])) {
366
+ color-scheme: dark;
367
+ --sui-foreground-color-1-hsl: var(--sui-base-hue) 10% 95%;
368
+ --sui-foreground-color-2-hsl: var(--sui-base-hue) 10% 75%;
369
+ --sui-foreground-color-3-hsl: var(--sui-base-hue) 10% 65%;
370
+ --sui-foreground-color-4-hsl: var(--sui-base-hue) 10% 55%;
371
+ --sui-foreground-color-5-hsl: var(--sui-base-hue) 10% 35%;
372
+ --sui-background-color-1-hsl: var(--sui-base-hue) 10% 10%;
373
+ --sui-background-color-2-hsl: var(--sui-base-hue) 10% 12%;
374
+ --sui-background-color-3-hsl: var(--sui-base-hue) 10% 14%;
375
+ --sui-background-color-4-hsl: var(--sui-base-hue) 10% 16%;
376
+ --sui-background-color-5-hsl: var(--sui-base-hue) 10% 26%;
377
+ --sui-border-color-1-hsl: var(--sui-base-hue) 10% 50%;
378
+ --sui-border-color-2-hsl: var(--sui-base-hue) 10% 26%;
379
+ --sui-border-color-3-hsl: var(--sui-base-hue) 10% 22%;
380
+ --sui-shadow-color: var(--sui-base-hue) 10% 0%;
381
+ --sui-primary-accent-color-text: hsl(var(--sui-base-hue) 100% 60%);
382
+ --sui-primary-accent-color-light: hsl(var(--sui-base-hue) 100% 45%);
383
+ --sui-primary-accent-color: hsl(var(--sui-base-hue) 100% 40%);
384
+ --sui-primary-accent-color-dark: hsl(var(--sui-base-hue) 100% 35%);
385
+ --sui-primary-accent-color-inverted: hsl(var(--sui-base-hue) 10% 100%);
386
+ --sui-primary-accent-color-translucent: hsl(var(--sui-base-hue) 80% 50% / 40%);
387
+ --sui-error-color-hue: 0;
388
+ --sui-warning-color-hue: 40;
389
+ --sui-info-color-hue: 210;
390
+ --sui-success-color-hue: 100;
391
+ --sui-alert-foreground-color-saturation: 85%;
392
+ --sui-alert-foreground-color-lightness: 75%;
393
+ --sui-alert-background-color-saturation: 40%;
394
+ --sui-alert-background-color-lightness: 10%;
395
+ --sui-alert-border-color-saturation: 38%;
396
+ --sui-alert-border-color-lightness: 18%;
397
+ }
398
+ }
322
399
 
323
400
  :global(.material-symbols-outlined) {
324
401
  font-variation-settings: "FILL" 0, "wght" 300, "GRAD" 0, "opsz" 24;
@@ -342,6 +419,7 @@
342
419
  :global(*),
343
420
  :global(::before),
344
421
  :global(::after) {
422
+ scroll-behavior: auto;
345
423
  transition-duration: 1ms !important;
346
424
  }
347
425
  }
@@ -446,4 +524,14 @@
446
524
  user-select: none;
447
525
  touch-action: none;
448
526
  cursor: default;
527
+ }
528
+ :global(.app-shell.horizontal) {
529
+ display: flex;
530
+ flex-direction: row;
531
+ overflow: hidden;
532
+ }
533
+ :global(.app-shell.vertical) {
534
+ display: flex;
535
+ flex-direction: column;
536
+ overflow: hidden;
449
537
  }</style>
@@ -8,6 +8,7 @@
8
8
  */
9
9
  export default class AppShell extends SvelteComponent<{
10
10
  [x: string]: any;
11
+ orientation?: "vertical" | "horizontal" | undefined;
11
12
  }, {
12
13
  dragover: DragEvent;
13
14
  drop: DragEvent;
@@ -24,6 +25,7 @@ import { SvelteComponent } from "svelte";
24
25
  declare const __propDef: {
25
26
  props: {
26
27
  [x: string]: any;
28
+ orientation?: 'horizontal' | 'vertical' | undefined;
27
29
  };
28
30
  events: {
29
31
  dragover: DragEvent;
@@ -7,9 +7,9 @@
7
7
  */
8
8
  export default class Group extends SvelteComponent<{
9
9
  [x: string]: any;
10
- class?: string;
11
- disabled?: boolean;
12
- hidden?: boolean;
10
+ class?: string | undefined;
11
+ disabled?: boolean | undefined;
12
+ hidden?: boolean | undefined;
13
13
  }, {
14
14
  [evt: string]: CustomEvent<any>;
15
15
  }, {
@@ -23,8 +23,8 @@ import { SvelteComponent } from "svelte";
23
23
  declare const __propDef: {
24
24
  props: {
25
25
  [x: string]: any;
26
- class?: string;
27
- disabled?: boolean;
26
+ class?: string | undefined;
27
+ disabled?: boolean | undefined;
28
28
  hidden?: boolean | undefined;
29
29
  };
30
30
  events: {
@@ -45,14 +45,18 @@
45
45
  export let keepContent = false;
46
46
  /**
47
47
  * A reference to the `<dialog>` element.
48
- * @type {HTMLDialogElement}
48
+ * @type {HTMLDialogElement | undefined}
49
49
  */
50
50
  export let dialog = undefined;
51
51
  /**
52
52
  * Close the modal.
53
- * @param {string} returnValue Return value to be used for `<dialog>`.
53
+ * @param {string} returnValue - Return value to be used for `<dialog>`.
54
54
  */
55
55
  export const close = (returnValue) => {
56
+ if (!dialog) {
57
+ return;
58
+ }
59
+
56
60
  dialog.returnValue = returnValue;
57
61
  open = false;
58
62
  };
@@ -69,7 +73,8 @@
69
73
  const waitForTransition = async () =>
70
74
  new Promise((resolve) => {
71
75
  /**
72
- * @param {TransitionEvent} event `transition` event.
76
+ * Transition event listener.
77
+ * @param {TransitionEvent} event - `transition` event.
73
78
  */
74
79
  const listener = (event) => {
75
80
  if (event.target === dialog) {
@@ -78,13 +83,17 @@
78
83
  }
79
84
  };
80
85
 
81
- dialog.addEventListener('transitionend', listener);
86
+ dialog?.addEventListener('transitionend', listener);
82
87
  });
83
88
 
84
89
  /**
85
90
  * Show the modal.
86
91
  */
87
92
  const openDialog = async () => {
93
+ if (!dialog) {
94
+ return;
95
+ }
96
+
88
97
  dispatch('opening');
89
98
  (document.querySelector('.sui.app-shell') ?? document.body).appendChild(dialog);
90
99
  showContent = true;
@@ -102,6 +111,10 @@
102
111
  * Hide the modal.
103
112
  */
104
113
  const closeDialog = async () => {
114
+ if (!dialog) {
115
+ return;
116
+ }
117
+
105
118
  dispatch('closing');
106
119
  setActiveClass = false;
107
120
  setOpenClass = false;
@@ -110,12 +123,12 @@
110
123
  dialog.close();
111
124
  dialog.remove();
112
125
 
113
- if (['ok', 'cancel'].includes(dialog?.returnValue)) {
126
+ if (['ok', 'cancel'].includes(dialog.returnValue)) {
114
127
  dispatch(dialog?.returnValue);
115
128
  }
116
129
 
117
- dispatch('close', dialog?.returnValue);
118
- dialog.returnValue = undefined;
130
+ dispatch('close', dialog.returnValue);
131
+ dialog.returnValue = '';
119
132
  };
120
133
 
121
134
  /**
@@ -138,7 +151,7 @@
138
151
  }
139
152
 
140
153
  onMount(() => {
141
- dialog.remove();
154
+ dialog?.remove();
142
155
 
143
156
  // onUnmount
144
157
  return () => {
@@ -157,7 +170,11 @@
157
170
  {...$$restProps}
158
171
  bind:this={dialog}
159
172
  on:click={({ target }) => {
160
- if (lightDismiss && /** @type {HTMLElement?} */ (target)?.matches('dialog')) {
173
+ if (
174
+ dialog &&
175
+ lightDismiss &&
176
+ /** @type {HTMLElement | undefined} */ (target)?.matches('dialog')
177
+ ) {
161
178
  dialog.returnValue = 'cancel';
162
179
  open = false;
163
180
  }
@@ -4,15 +4,15 @@
4
4
  /** A generic modal top-layer helper based on the HTML `<dialog>` element. */
5
5
  export default class Modal extends SvelteComponent<{
6
6
  [x: string]: any;
7
- class?: string;
8
- close?: (returnValue: string) => void;
9
- dialog?: HTMLDialogElement;
10
- role?: "dialog" | "none" | "alertdialog";
11
- open?: boolean;
12
- showBackdrop?: boolean;
13
- lightDismiss?: boolean;
14
- escapeDismiss?: boolean;
15
- keepContent?: boolean;
7
+ class?: string | undefined;
8
+ close?: ((returnValue: string) => void) | undefined;
9
+ dialog?: HTMLDialogElement | undefined;
10
+ role?: "dialog" | "none" | "alertdialog" | undefined;
11
+ open?: boolean | undefined;
12
+ showBackdrop?: boolean | undefined;
13
+ lightDismiss?: boolean | undefined;
14
+ escapeDismiss?: boolean | undefined;
15
+ keepContent?: boolean | undefined;
16
16
  }, {
17
17
  opening: CustomEvent<any>;
18
18
  open: CustomEvent<any>;
@@ -26,29 +26,29 @@ export default class Modal extends SvelteComponent<{
26
26
  }> {
27
27
  get close(): (returnValue: string) => void;
28
28
  /**accessor*/
29
- set class(arg: string);
30
- get class(): string;
29
+ set class(arg: string | undefined);
30
+ get class(): string | undefined;
31
31
  /**accessor*/
32
- set role(arg: "dialog" | "none" | "alertdialog");
33
- get role(): "dialog" | "none" | "alertdialog";
32
+ set role(arg: "dialog" | "none" | "alertdialog" | undefined);
33
+ get role(): "dialog" | "none" | "alertdialog" | undefined;
34
34
  /**accessor*/
35
- set open(arg: boolean);
36
- get open(): boolean;
35
+ set open(arg: boolean | undefined);
36
+ get open(): boolean | undefined;
37
37
  /**accessor*/
38
- set showBackdrop(arg: boolean);
39
- get showBackdrop(): boolean;
38
+ set showBackdrop(arg: boolean | undefined);
39
+ get showBackdrop(): boolean | undefined;
40
40
  /**accessor*/
41
- set lightDismiss(arg: boolean);
42
- get lightDismiss(): boolean;
41
+ set lightDismiss(arg: boolean | undefined);
42
+ get lightDismiss(): boolean | undefined;
43
43
  /**accessor*/
44
- set escapeDismiss(arg: boolean);
45
- get escapeDismiss(): boolean;
44
+ set escapeDismiss(arg: boolean | undefined);
45
+ get escapeDismiss(): boolean | undefined;
46
46
  /**accessor*/
47
- set keepContent(arg: boolean);
48
- get keepContent(): boolean;
47
+ set keepContent(arg: boolean | undefined);
48
+ get keepContent(): boolean | undefined;
49
49
  /**accessor*/
50
- set dialog(arg: HTMLDialogElement);
51
- get dialog(): HTMLDialogElement;
50
+ set dialog(arg: HTMLDialogElement | undefined);
51
+ get dialog(): HTMLDialogElement | undefined;
52
52
  }
53
53
  export type ModalProps = typeof __propDef.props;
54
54
  export type ModalEvents = typeof __propDef.events;
@@ -57,15 +57,15 @@ import { SvelteComponent } from "svelte";
57
57
  declare const __propDef: {
58
58
  props: {
59
59
  [x: string]: any;
60
- class?: string;
61
- close?: (returnValue: string) => void;
62
- dialog?: HTMLDialogElement;
63
- role?: 'dialog' | 'alertdialog' | 'none';
64
- open?: boolean;
65
- showBackdrop?: boolean;
66
- lightDismiss?: boolean;
67
- escapeDismiss?: boolean;
68
- keepContent?: boolean;
60
+ class?: string | undefined;
61
+ close?: ((returnValue: string) => void) | undefined;
62
+ dialog?: HTMLDialogElement | undefined;
63
+ role?: "dialog" | "none" | "alertdialog" | undefined;
64
+ open?: boolean | undefined;
65
+ showBackdrop?: boolean | undefined;
66
+ lightDismiss?: boolean | undefined;
67
+ escapeDismiss?: boolean | undefined;
68
+ keepContent?: boolean | undefined;
69
69
  };
70
70
  events: {
71
71
  opening: CustomEvent<any>;
@@ -22,14 +22,19 @@
22
22
  * @type {import('svelte/store').Writable<boolean>}
23
23
  */
24
24
  export let open = writable(false);
25
+ /**
26
+ * Whether to show the backdrop.
27
+ * @type {boolean}
28
+ */
29
+ export let showBackdrop = false;
25
30
  /**
26
31
  * A reference to the anchor element that opens the popup. Typically a `<button>`.
27
- * @type {HTMLElement}
32
+ * @type {HTMLElement | undefined}
28
33
  */
29
34
  export let anchor;
30
35
  /**
31
36
  * A reference to the content element.
32
- * @type {HTMLElement}
37
+ * @type {HTMLElement | undefined}
33
38
  */
34
39
  export let content = undefined;
35
40
  /**
@@ -37,6 +42,11 @@
37
42
  * @type {PopupPosition}
38
43
  */
39
44
  export let position = 'bottom-left';
45
+ /**
46
+ * The base element of {@link position}. If omitted, this will be {@link anchor}.
47
+ * @type {HTMLElement | undefined}
48
+ */
49
+ export let positionBaseElement = undefined;
40
50
  /**
41
51
  * Whether to show the popup at the center of the screen on mobile/tablet and ignore the defined
42
52
  * dropdown `position`.
@@ -57,7 +67,7 @@
57
67
  /**
58
68
  * The type of the content displayed in the popup, defined with the `aria-haspopup` attribute on
59
69
  * the anchor element.
60
- * @type {string}
70
+ * @type {string | undefined}
61
71
  * @see https://w3c.github.io/aria/#aria-haspopup
62
72
  */
63
73
  let contentType;
@@ -74,8 +84,8 @@
74
84
 
75
85
  $: {
76
86
  if (anchor && modal?.dialog) {
77
- ({ open, style } = activatePopup(anchor, modal.dialog, position));
78
- contentType = anchor.getAttribute('aria-haspopup');
87
+ ({ open, style } = activatePopup(anchor, modal.dialog, position, positionBaseElement));
88
+ contentType = anchor.getAttribute('aria-haspopup') ?? undefined;
79
89
  }
80
90
  }
81
91
 
@@ -90,7 +100,7 @@
90
100
  role="none"
91
101
  class="popup"
92
102
  bind:open={$open}
93
- showBackdrop={touch}
103
+ showBackdrop={showBackdrop ?? touch}
94
104
  lightDismiss={true}
95
105
  keepContent={true}
96
106
  bind:this={modal}
@@ -104,6 +114,10 @@
104
114
  on:open={async () => {
105
115
  await sleep(100);
106
116
 
117
+ if (!content) {
118
+ return;
119
+ }
120
+
107
121
  const target = /** @type {HTMLElement} */ (
108
122
  content.querySelector('[tabindex]:not([aria-disabled="true"])')
109
123
  );
@@ -131,7 +145,44 @@
131
145
  </div>
132
146
  </Modal>
133
147
 
134
- <style>.content.touch {
148
+ <style>.content {
149
+ position: absolute;
150
+ overflow-y: auto;
151
+ outline-width: 0 !important;
152
+ color: var(--sui-primary-foreground-color);
153
+ background-color: var(--sui-secondary-background-color-translucent);
154
+ box-shadow: 0 8px 16px var(--sui-popup-shadow-color);
155
+ -webkit-backdrop-filter: blur(16px);
156
+ backdrop-filter: blur(16px);
157
+ transition-property: opacity, transform;
158
+ }
159
+ .content.menu {
160
+ border-width: var(--sui-menu-border-width, 1px);
161
+ border-style: var(--sui-menu-border-style, solid);
162
+ border-color: var(--sui-menu-border-width, var(--sui-secondary-border-color));
163
+ border-radius: var(--sui-menu-border-radius, 4px);
164
+ padding: var(--sui-menu-padding, 4px);
165
+ }
166
+ .content.menu :global(.sui.menu) {
167
+ border-width: 0;
168
+ border-radius: 0;
169
+ padding: 0;
170
+ background-color: transparent;
171
+ }
172
+ .content.listbox {
173
+ border-width: var(--sui-listbox-border-width, 1px);
174
+ border-style: var(--sui-listbox-border-style, solid);
175
+ border-color: var(--sui-listbox-border-width, var(--sui-secondary-border-color));
176
+ border-radius: var(--sui-listbox-border-radius, 4px);
177
+ padding: var(--sui-listbox-padding, 4px);
178
+ }
179
+ .content.listbox :global(.sui.listbox) {
180
+ border-width: 0;
181
+ border-radius: 0;
182
+ padding: 0;
183
+ background-color: transparent;
184
+ }
185
+ .content.touch {
135
186
  position: static;
136
187
  border-width: 0 !important;
137
188
  border-radius: 4px !important;
@@ -159,29 +210,4 @@
159
210
  transition-duration: 300ms;
160
211
  opacity: 0;
161
212
  transform: translateY(-8px);
162
- }
163
-
164
- .content {
165
- position: absolute;
166
- overflow-y: auto;
167
- outline-width: 0 !important;
168
- color: var(--sui-primary-foreground-color);
169
- background-color: var(--sui-secondary-background-color-translucent);
170
- box-shadow: 0 8px 16px var(--sui-popup-shadow-color);
171
- -webkit-backdrop-filter: blur(16px);
172
- backdrop-filter: blur(16px);
173
- transition-property: opacity, transform;
174
- }
175
- .content.listbox, .content.menu {
176
- border-width: 1px;
177
- border-style: solid;
178
- border-color: var(--sui-secondary-border-color);
179
- border-radius: 4px;
180
- }
181
- .content.listbox :global(.sui.listbox),
182
- .content.listbox :global(.sui.menu), .content.menu :global(.sui.listbox),
183
- .content.menu :global(.sui.menu) {
184
- border-width: 0;
185
- border-radius: 0;
186
- background-color: transparent;
187
213
  }</style>