@sveltia/ui 0.78.3 → 0.79.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 (181) hide show
  1. package/dist/components/alert/alert-content.svelte +51 -0
  2. package/dist/components/alert/alert-content.svelte.d.ts +39 -0
  3. package/dist/components/alert/alert.d.ts +3 -0
  4. package/dist/components/alert/alert.js +21 -0
  5. package/dist/components/alert/alert.svelte +6 -30
  6. package/dist/components/alert/infobar.svelte +7 -21
  7. package/dist/components/alert/infobar.svelte.d.ts +2 -2
  8. package/dist/components/button/button.svelte +11 -11
  9. package/dist/components/button/button.svelte.d.ts +2 -2
  10. package/dist/components/button/select-button.svelte +1 -1
  11. package/dist/components/button/select-button.svelte.d.ts +2 -2
  12. package/dist/components/button/split-button.svelte +1 -1
  13. package/dist/components/button/split-button.svelte.d.ts +3 -3
  14. package/dist/components/calendar/calendar.d.ts +2 -0
  15. package/dist/components/calendar/calendar.js +34 -0
  16. package/dist/components/calendar/calendar.svelte +49 -5
  17. package/dist/components/checkbox/checkbox.svelte +11 -4
  18. package/dist/components/checkbox/checkbox.svelte.d.ts +2 -2
  19. package/dist/components/dialog/alert-dialog.svelte +1 -1
  20. package/dist/components/dialog/alert-dialog.svelte.d.ts +2 -2
  21. package/dist/components/dialog/confirmation-dialog.svelte +1 -1
  22. package/dist/components/dialog/confirmation-dialog.svelte.d.ts +2 -2
  23. package/dist/components/dialog/dialog.svelte +8 -18
  24. package/dist/components/dialog/dialog.svelte.d.ts +2 -2
  25. package/dist/components/dialog/modal-close-button.svelte +50 -0
  26. package/dist/components/dialog/modal-close-button.svelte.d.ts +43 -0
  27. package/dist/components/dialog/prompt-dialog.svelte +1 -1
  28. package/dist/components/dialog/prompt-dialog.svelte.d.ts +4 -4
  29. package/dist/components/disclosure/disclosure.svelte +1 -1
  30. package/dist/components/drawer/drawer.svelte +12 -34
  31. package/dist/components/drawer/drawer.svelte.d.ts +1 -1
  32. package/dist/components/emoji/caret.d.ts +1 -1
  33. package/dist/components/emoji/caret.js +1 -1
  34. package/dist/components/emoji/emoji-suggestions.svelte +1 -1
  35. package/dist/components/emoji/emoji-suggestions.svelte.d.ts +3 -3
  36. package/dist/components/emoji/emoji.d.ts +2 -2
  37. package/dist/components/emoji/emoji.js +1 -1
  38. package/dist/components/emoji/position.d.ts +2 -2
  39. package/dist/components/emoji/position.js +1 -1
  40. package/dist/components/grid/grid-body.svelte +6 -2
  41. package/dist/components/grid/grid-cell.svelte +3 -9
  42. package/dist/components/grid/grid-col-header.svelte +3 -9
  43. package/dist/components/grid/grid-foot.svelte +4 -11
  44. package/dist/components/grid/grid-head.svelte +4 -11
  45. package/dist/components/grid/grid-row-header.svelte +3 -10
  46. package/dist/components/grid/grid-row.svelte +3 -16
  47. package/dist/components/listbox/listbox.svelte +1 -1
  48. package/dist/components/listbox/listbox.svelte.d.ts +1 -1
  49. package/dist/components/listbox/option.svelte +1 -1
  50. package/dist/components/listbox/option.svelte.d.ts +2 -2
  51. package/dist/components/menu/menu-button.svelte +2 -2
  52. package/dist/components/menu/menu-button.svelte.d.ts +4 -4
  53. package/dist/components/menu/menu-item-checkable.svelte +71 -0
  54. package/dist/components/menu/menu-item-checkable.svelte.d.ts +25 -0
  55. package/dist/components/menu/menu-item-checkbox.svelte +3 -36
  56. package/dist/components/menu/menu-item-checkbox.svelte.d.ts +3 -3
  57. package/dist/components/menu/menu-item-group.svelte +8 -5
  58. package/dist/components/menu/menu-item-group.svelte.d.ts +9 -1
  59. package/dist/components/menu/menu-item-radio.svelte +3 -36
  60. package/dist/components/menu/menu-item-radio.svelte.d.ts +3 -3
  61. package/dist/components/menu/menu-item.svelte +22 -6
  62. package/dist/components/menu/menu-item.svelte.d.ts +4 -4
  63. package/dist/components/radio/radio.svelte +12 -1
  64. package/dist/components/resizable-pane/resizable-handle.svelte +14 -18
  65. package/dist/components/resizable-pane/resizable-pane-group.svelte +9 -6
  66. package/dist/components/resizable-pane/resizable-pane.svelte +4 -4
  67. package/dist/components/resizable-pane/resizable-pane.svelte.d.ts +7 -6
  68. package/dist/components/resizable-pane/sizing.d.ts +5 -4
  69. package/dist/components/resizable-pane/sizing.js +84 -25
  70. package/dist/components/scroll/infinite-scroll.svelte +16 -21
  71. package/dist/components/select/combobox.svelte +43 -52
  72. package/dist/components/select/combobox.svelte.d.ts +2 -2
  73. package/dist/components/select/select-tags.svelte +7 -1
  74. package/dist/components/select/select.svelte +2 -22
  75. package/dist/components/select/select.svelte.d.ts +1 -1
  76. package/dist/components/slider/slider.d.ts +6 -0
  77. package/dist/components/slider/slider.js +55 -2
  78. package/dist/components/slider/slider.svelte +63 -32
  79. package/dist/components/table/table-cell.svelte +3 -9
  80. package/dist/components/table/table-col-header.svelte +3 -9
  81. package/dist/components/table/table-foot.svelte +4 -11
  82. package/dist/components/table/table-head.svelte +4 -11
  83. package/dist/components/table/table-part.svelte +69 -0
  84. package/dist/components/table/table-part.svelte.d.ts +48 -0
  85. package/dist/components/table/table-row-header.svelte +3 -10
  86. package/dist/components/table/table-row.svelte +3 -10
  87. package/dist/components/tabs/tab-list.svelte +12 -0
  88. package/dist/components/tabs/tab.svelte +1 -1
  89. package/dist/components/tabs/tab.svelte.d.ts +2 -2
  90. package/dist/components/text-editor/constants.d.ts +5 -5
  91. package/dist/components/text-editor/constants.js +1 -1
  92. package/dist/components/text-editor/core.d.ts +4 -5
  93. package/dist/components/text-editor/core.js +376 -273
  94. package/dist/components/text-editor/emoji-autocomplete.svelte +1 -1
  95. package/dist/components/text-editor/lexical-root.svelte +1 -1
  96. package/dist/components/text-editor/raw-markdown.d.ts +6 -33
  97. package/dist/components/text-editor/raw-markdown.js +63 -8
  98. package/dist/components/text-editor/shiki/facade.d.ts +1 -1
  99. package/dist/components/text-editor/shiki/facade.js +63 -48
  100. package/dist/components/text-editor/shiki/generated.d.ts +1 -1
  101. package/dist/components/text-editor/shiki/generated.js +1 -1
  102. package/dist/components/text-editor/shiki/highlighter.d.ts +6 -1
  103. package/dist/components/text-editor/shiki/highlighter.js +3 -4
  104. package/dist/components/text-editor/shiki/loader.d.ts +1 -1
  105. package/dist/components/text-editor/shiki/loader.js +1 -1
  106. package/dist/components/text-editor/shiki/version.d.ts +1 -1
  107. package/dist/components/text-editor/shiki/version.js +1 -1
  108. package/dist/components/text-editor/store.svelte.d.ts +1 -1
  109. package/dist/components/text-editor/store.svelte.js +5 -2
  110. package/dist/components/text-editor/text-editor.svelte +2 -2
  111. package/dist/components/text-editor/text-editor.svelte.d.ts +3 -3
  112. package/dist/components/text-editor/toolbar/code-language-switcher.svelte +24 -16
  113. package/dist/components/text-editor/toolbar/format-text-button.svelte +7 -31
  114. package/dist/components/text-editor/toolbar/format-text-button.svelte.d.ts +1 -1
  115. package/dist/components/text-editor/toolbar/insert-component.d.ts +3 -0
  116. package/dist/components/text-editor/toolbar/insert-component.js +34 -0
  117. package/dist/components/text-editor/toolbar/insert-item-button.svelte +4 -24
  118. package/dist/components/text-editor/toolbar/insert-item-button.svelte.d.ts +1 -1
  119. package/dist/components/text-editor/toolbar/insert-link-button.svelte +9 -25
  120. package/dist/components/text-editor/toolbar/insert-menu-button.svelte +4 -24
  121. package/dist/components/text-editor/toolbar/insert-menu-button.svelte.d.ts +1 -1
  122. package/dist/components/text-editor/toolbar/text-editor-toolbar.svelte +1 -1
  123. package/dist/components/text-editor/toolbar/toggle-block-menu-item.svelte +31 -35
  124. package/dist/components/text-editor/toolbar/toggle-block-menu-item.svelte.d.ts +1 -1
  125. package/dist/components/text-editor/toolbar/toolbar-wrapper.svelte +0 -10
  126. package/dist/components/text-editor/toolbar/toolbar-wrapper.svelte.d.ts +1 -11
  127. package/dist/components/text-editor/transformers/table.d.ts +0 -1
  128. package/dist/components/text-editor/transformers/table.js +1 -2
  129. package/dist/components/text-field/emoji-autocomplete.svelte +1 -1
  130. package/dist/components/text-field/masked-input.svelte +179 -0
  131. package/dist/components/text-field/masked-input.svelte.d.ts +42 -0
  132. package/dist/components/text-field/number-input.js +7 -1
  133. package/dist/components/text-field/number-input.svelte +13 -5
  134. package/dist/components/text-field/number-input.svelte.d.ts +3 -3
  135. package/dist/components/text-field/password-input.svelte +3 -116
  136. package/dist/components/text-field/password-input.svelte.d.ts +3 -3
  137. package/dist/components/text-field/search-bar.svelte +1 -1
  138. package/dist/components/text-field/search-bar.svelte.d.ts +3 -3
  139. package/dist/components/text-field/secret-input.svelte +3 -119
  140. package/dist/components/text-field/secret-input.svelte.d.ts +3 -3
  141. package/dist/components/text-field/text-area.svelte +1 -1
  142. package/dist/components/text-field/text-area.svelte.d.ts +3 -3
  143. package/dist/components/text-field/text-input.svelte +1 -1
  144. package/dist/components/text-field/text-input.svelte.d.ts +3 -3
  145. package/dist/components/toast/toast.svelte +11 -20
  146. package/dist/components/toast/toast.svelte.d.ts +1 -1
  147. package/dist/components/tree/tree-item.svelte +1 -1
  148. package/dist/components/tree/tree-item.svelte.d.ts +1 -1
  149. package/dist/components/tree/tree.svelte +1 -1
  150. package/dist/components/tree/tree.svelte.d.ts +1 -1
  151. package/dist/components/util/font-links.svelte +1 -0
  152. package/dist/components/util/modal.svelte +37 -1
  153. package/dist/components/util/modal.svelte.d.ts +1 -1
  154. package/dist/components/util/popup.svelte +2 -5
  155. package/dist/components/util/popup.svelte.d.ts +2 -2
  156. package/dist/components/util/visibility-observer.svelte +1 -0
  157. package/dist/locales/ar.yaml +1 -1
  158. package/dist/locales/sk.yaml +136 -0
  159. package/dist/services/group.svelte.d.ts +10 -1
  160. package/dist/services/group.svelte.js +361 -251
  161. package/dist/services/navigation.d.ts +19 -0
  162. package/dist/services/navigation.js +84 -0
  163. package/dist/services/popup-position.d.ts +90 -0
  164. package/dist/services/popup-position.js +275 -0
  165. package/dist/services/popup.svelte.d.ts +16 -17
  166. package/dist/services/popup.svelte.js +25 -169
  167. package/dist/services/scroll.d.ts +1 -0
  168. package/dist/services/scroll.js +17 -0
  169. package/dist/services/select.svelte.d.ts +2 -2
  170. package/dist/services/select.svelte.js +1 -1
  171. package/dist/services/text.d.ts +2 -0
  172. package/dist/services/text.js +28 -0
  173. package/dist/services/tree.svelte.d.ts +3 -11
  174. package/dist/services/tree.svelte.js +35 -77
  175. package/dist/services/type-ahead.d.ts +0 -4
  176. package/dist/services/type-ahead.js +3 -1
  177. package/dist/services/widget.d.ts +8 -0
  178. package/dist/services/widget.js +39 -0
  179. package/dist/shiki-engine.js +15 -15
  180. package/dist/styles/mixins.scss +126 -0
  181. package/package.json +38 -34
@@ -21,7 +21,7 @@
21
21
 
22
22
  /**
23
23
  * @import { Snippet } from 'svelte';
24
- * @import { CommonEventHandlers, InputEventHandlers, TextInputProps } from '../../typedefs';
24
+ * @import { CommonEventHandlers, InputEventHandlers, TextInputProps } from '../../typedefs.js';
25
25
  */
26
26
 
27
27
  /**
@@ -55,6 +55,8 @@
55
55
  increaseIcon,
56
56
  decreaseIcon,
57
57
  onChange,
58
+ onkeydown,
59
+ oninput,
58
60
  ...restProps
59
61
  /* eslint-enable prefer-const */
60
62
  } = $props();
@@ -174,20 +176,22 @@
174
176
  {readonly}
175
177
  {required}
176
178
  {invalid}
177
- aria-valuenow={Number(value || 0)}
179
+ aria-valuenow={Number.isFinite(value) ? value : undefined}
178
180
  aria-valuemin={min}
179
181
  aria-valuemax={max}
180
182
  inputmode={maximumFractionDigits > 0 ? 'decimal' : 'numeric'}
181
183
  onkeydown={(event) => {
182
184
  const { key, ctrlKey, metaKey, altKey, shiftKey } = event;
183
185
  const hasModifier = shiftKey || altKey || ctrlKey || metaKey;
186
+ // A read-only field can’t be stepped, just like the spin buttons
187
+ const canStep = !disabled && !readonly && !hasModifier;
184
188
 
185
- if (key === 'ArrowDown' && !hasModifier) {
189
+ if (key === 'ArrowDown' && canStep) {
186
190
  event.preventDefault();
187
191
  decrease();
188
192
  }
189
193
 
190
- if (key === 'ArrowUp' && !hasModifier) {
194
+ if (key === 'ArrowUp' && canStep) {
191
195
  event.preventDefault();
192
196
  increase();
193
197
  }
@@ -195,11 +199,15 @@
195
199
  if (!edited) {
196
200
  edited = true;
197
201
  }
202
+
203
+ onkeydown?.(event);
198
204
  }}
199
- oninput={() => {
205
+ oninput={(event) => {
200
206
  if (!edited) {
201
207
  edited = true;
202
208
  }
209
+
210
+ oninput?.(event);
203
211
  }}
204
212
  {onChange}
205
213
  />
@@ -8,7 +8,7 @@ type NumberInput = {
8
8
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number
9
9
  * @see https://w3c.github.io/aria/#textbox
10
10
  */
11
- declare const NumberInput: import("svelte").Component<TextInputProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & InputEventHandlers & {
11
+ declare const NumberInput: import("svelte").Component<TextInputProps & import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & InputEventHandlers & {
12
12
  /**
13
13
  * Input value.
14
14
  */
@@ -62,6 +62,6 @@ type Props = {
62
62
  */
63
63
  decreaseIcon?: Snippet<[]> | undefined;
64
64
  };
65
- import type { TextInputProps } from '../../typedefs';
66
- import type { InputEventHandlers } from '../../typedefs';
65
+ import type { TextInputProps } from '../../typedefs.js';
66
+ import type { InputEventHandlers } from '../../typedefs.js';
67
67
  import type { Snippet } from 'svelte';
@@ -6,14 +6,11 @@
6
6
  @see https://w3c.github.io/aria/#textbox
7
7
  -->
8
8
  <script>
9
- import { _ } from '@sveltia/i18n';
10
- import Button from '../button/button.svelte';
11
- import Icon from '../icon/icon.svelte';
12
- import TextInput from './text-input.svelte';
9
+ import MaskedInput from './masked-input.svelte';
13
10
 
14
11
  /**
15
12
  * @import { Snippet } from 'svelte';
16
- * @import { CommonEventHandlers, InputEventHandlers, TextInputProps } from '../../typedefs';
13
+ * @import { CommonEventHandlers, InputEventHandlers, TextInputProps } from '../../typedefs.js';
17
14
  */
18
15
 
19
16
  /**
@@ -28,119 +25,9 @@
28
25
  let {
29
26
  /* eslint-disable prefer-const */
30
27
  value = $bindable(),
31
- flex = false,
32
- monospace = true,
33
- class: className,
34
- hidden = false,
35
- disabled = false,
36
- readonly = false,
37
- required = false,
38
- invalid = false,
39
- children,
40
- visibilityIcon,
41
28
  ...restProps
42
29
  /* eslint-enable prefer-const */
43
30
  } = $props();
44
-
45
- const id = $props.id();
46
-
47
- /**
48
- * Reference to the `<input>` element.
49
- * @type {HTMLInputElement | undefined}
50
- */
51
- let inputElement = $state();
52
- let passwordVisible = $state(false);
53
-
54
- $effect(() => {
55
- inputElement?.setAttribute('type', passwordVisible ? 'text' : 'password');
56
- });
57
31
  </script>
58
32
 
59
- <div
60
- role="none"
61
- class="sui password-input {className}"
62
- class:flex
63
- class:disabled
64
- class:readonly
65
- {hidden}
66
- >
67
- <TextInput
68
- dir="ltr"
69
- bind:element={inputElement}
70
- {...restProps}
71
- {id}
72
- bind:value
73
- type="password"
74
- spellcheck="false"
75
- {flex}
76
- {monospace}
77
- {hidden}
78
- {disabled}
79
- {readonly}
80
- {required}
81
- {invalid}
82
- />
83
- <Button
84
- iconic
85
- disabled={disabled || readonly}
86
- pressed={passwordVisible}
87
- aria-label={_(
88
- passwordVisible ? '_sui.password_input.hide_password' : '_sui.password_input.show_password',
89
- )}
90
- aria-controls={id}
91
- onclick={() => {
92
- passwordVisible = !passwordVisible;
93
- }}
94
- >
95
- {#snippet startIcon()}
96
- {#if visibilityIcon}
97
- {@render visibilityIcon()}
98
- {:else}
99
- <Icon name={passwordVisible ? 'visibility_off' : 'visibility'} />
100
- {/if}
101
- {/snippet}
102
- </Button>
103
- </div>
104
-
105
- <style>.password-input {
106
- display: inline-flex;
107
- align-items: center;
108
- margin: var(--sui-focus-ring-width);
109
- min-width: var(--sui-textbox-singleline-min-width);
110
- }
111
- .password-input.flex:not([hidden]) {
112
- display: inline-flex;
113
- width: -moz-available;
114
- width: -webkit-fill-available;
115
- width: stretch;
116
- min-width: 0;
117
- }
118
- .password-input :global(.text-input) {
119
- flex: auto;
120
- margin: 0 !important;
121
- width: 0;
122
- min-width: 0 !important;
123
- }
124
- .password-input :global(input) {
125
- border-start-end-radius: 0;
126
- border-end-end-radius: 0;
127
- }
128
- .password-input :global(button) {
129
- flex: none;
130
- margin-block: 0;
131
- margin-inline-start: -1px;
132
- margin-inline-end: 0;
133
- border-width: 1px;
134
- border-color: var(--sui-textbox-border-color);
135
- width: var(--sui-textbox-height);
136
- aspect-ratio: 1/1;
137
- }
138
- .password-input :global(button:last-child) {
139
- border-start-start-radius: 0;
140
- border-start-end-radius: 4px;
141
- border-end-end-radius: 4px;
142
- border-end-start-radius: 0;
143
- }
144
- .password-input :global(button) :global(.icon) {
145
- font-size: var(--sui-font-size-xx-large);
146
- }</style>
33
+ <MaskedInput bind:value {...restProps} mask="type" />
@@ -9,7 +9,7 @@ type PasswordInput = {
9
9
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/password
10
10
  * @see https://w3c.github.io/aria/#textbox
11
11
  */
12
- declare const PasswordInput: import("svelte").Component<TextInputProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & InputEventHandlers & {
12
+ declare const PasswordInput: import("svelte").Component<TextInputProps & import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & InputEventHandlers & {
13
13
  /**
14
14
  * Input value.
15
15
  */
@@ -29,6 +29,6 @@ type Props = {
29
29
  */
30
30
  visibilityIcon?: Snippet<[]> | undefined;
31
31
  };
32
- import type { TextInputProps } from '../../typedefs';
33
- import type { InputEventHandlers } from '../../typedefs';
32
+ import type { TextInputProps } from '../../typedefs.js';
33
+ import type { InputEventHandlers } from '../../typedefs.js';
34
34
  import type { Snippet } from 'svelte';
@@ -14,7 +14,7 @@
14
14
 
15
15
  /**
16
16
  * @import { Snippet } from 'svelte';
17
- * @import { CommonEventHandlers, InputEventHandlers, TextInputProps } from '../../typedefs';
17
+ * @import { CommonEventHandlers, InputEventHandlers, TextInputProps } from '../../typedefs.js';
18
18
  */
19
19
 
20
20
  /**
@@ -11,7 +11,7 @@ type SearchBar = {
11
11
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/search
12
12
  * @see https://w3c.github.io/aria/#search
13
13
  */
14
- declare const SearchBar: import("svelte").Component<TextInputProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & InputEventHandlers & {
14
+ declare const SearchBar: import("svelte").Component<TextInputProps & import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & InputEventHandlers & {
15
15
  /**
16
16
  * Input value.
17
17
  */
@@ -49,6 +49,6 @@ type Props = {
49
49
  */
50
50
  onClear?: (() => void) | undefined;
51
51
  };
52
- import type { TextInputProps } from '../../typedefs';
53
- import type { InputEventHandlers } from '../../typedefs';
52
+ import type { TextInputProps } from '../../typedefs.js';
53
+ import type { InputEventHandlers } from '../../typedefs.js';
54
54
  import type { Snippet } from 'svelte';
@@ -6,14 +6,11 @@
6
6
  @see https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/-webkit-text-security
7
7
  -->
8
8
  <script>
9
- import { _ } from '@sveltia/i18n';
10
- import Button from '../button/button.svelte';
11
- import Icon from '../icon/icon.svelte';
12
- import TextInput from './text-input.svelte';
9
+ import MaskedInput from './masked-input.svelte';
13
10
 
14
11
  /**
15
12
  * @import { Snippet } from 'svelte';
16
- * @import { CommonEventHandlers, InputEventHandlers, TextInputProps } from '../../typedefs';
13
+ * @import { CommonEventHandlers, InputEventHandlers, TextInputProps } from '../../typedefs.js';
17
14
  */
18
15
 
19
16
  /**
@@ -28,122 +25,9 @@
28
25
  let {
29
26
  /* eslint-disable prefer-const */
30
27
  value = $bindable(),
31
- flex = false,
32
- monospace = true,
33
- class: className,
34
- hidden = false,
35
- disabled = false,
36
- readonly = false,
37
- required = false,
38
- invalid = false,
39
- children,
40
- visibilityIcon,
41
28
  ...restProps
42
29
  /* eslint-enable prefer-const */
43
30
  } = $props();
44
-
45
- const id = $props.id();
46
-
47
- /**
48
- * Reference to the `<input>` element.
49
- * @type {HTMLInputElement | undefined}
50
- */
51
- let inputElement = $state();
52
- let show = $state(false);
53
31
  </script>
54
32
 
55
- <div
56
- role="none"
57
- class="sui secret-input {className}"
58
- class:flex
59
- class:disabled
60
- class:readonly
61
- class:show
62
- {hidden}
63
- >
64
- <!-- The field is masked with CSS rather than `type="password"`, so opt out of the features that
65
- would remember the secret, like autofill history and the keyboard’s learned words -->
66
- <TextInput
67
- dir="ltr"
68
- autocomplete="off"
69
- autocapitalize="off"
70
- autocorrect="off"
71
- bind:element={inputElement}
72
- {...restProps}
73
- {id}
74
- bind:value
75
- spellcheck="false"
76
- {flex}
77
- {monospace}
78
- {hidden}
79
- {disabled}
80
- {readonly}
81
- {required}
82
- {invalid}
83
- />
84
- <Button
85
- iconic
86
- disabled={disabled || readonly}
87
- pressed={show}
88
- aria-label={_(show ? '_sui.secret_input.hide_secret' : '_sui.secret_input.show_secret')}
89
- aria-controls={id}
90
- onclick={() => {
91
- show = !show;
92
- }}
93
- >
94
- {#snippet startIcon()}
95
- {#if visibilityIcon}
96
- {@render visibilityIcon()}
97
- {:else}
98
- <Icon name={show ? 'visibility_off' : 'visibility'} />
99
- {/if}
100
- {/snippet}
101
- </Button>
102
- </div>
103
-
104
- <style>.secret-input {
105
- display: inline-flex;
106
- align-items: center;
107
- margin: var(--sui-focus-ring-width);
108
- min-width: var(--sui-textbox-singleline-min-width);
109
- }
110
- .secret-input.flex:not([hidden]) {
111
- display: inline-flex;
112
- width: -moz-available;
113
- width: -webkit-fill-available;
114
- width: stretch;
115
- min-width: 0;
116
- }
117
- .secret-input.show :global(input) {
118
- -webkit-text-security: none;
119
- }
120
- .secret-input :global(.text-input) {
121
- flex: auto;
122
- margin: 0 !important;
123
- width: 0;
124
- min-width: 0 !important;
125
- }
126
- .secret-input :global(input) {
127
- border-start-end-radius: 0;
128
- border-end-end-radius: 0;
129
- -webkit-text-security: disc;
130
- }
131
- .secret-input :global(button) {
132
- flex: none;
133
- margin-block: 0;
134
- margin-inline-start: -1px;
135
- margin-inline-end: 0;
136
- border-width: 1px;
137
- border-color: var(--sui-textbox-border-color);
138
- width: var(--sui-textbox-height);
139
- aspect-ratio: 1/1;
140
- }
141
- .secret-input :global(button:last-child) {
142
- border-start-start-radius: 0;
143
- border-start-end-radius: 4px;
144
- border-end-end-radius: 4px;
145
- border-end-start-radius: 0;
146
- }
147
- .secret-input :global(button) :global(.icon) {
148
- font-size: var(--sui-font-size-xx-large);
149
- }</style>
33
+ <MaskedInput bind:value {...restProps} mask="css" />
@@ -9,7 +9,7 @@ type SecretInput = {
9
9
  * the password.
10
10
  * @see https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/-webkit-text-security
11
11
  */
12
- declare const SecretInput: import("svelte").Component<TextInputProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & InputEventHandlers & {
12
+ declare const SecretInput: import("svelte").Component<TextInputProps & import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & InputEventHandlers & {
13
13
  /**
14
14
  * Input value.
15
15
  */
@@ -29,6 +29,6 @@ type Props = {
29
29
  */
30
30
  visibilityIcon?: Snippet<[]> | undefined;
31
31
  };
32
- import type { TextInputProps } from '../../typedefs';
33
- import type { InputEventHandlers } from '../../typedefs';
32
+ import type { TextInputProps } from '../../typedefs.js';
33
+ import type { InputEventHandlers } from '../../typedefs.js';
34
34
  import type { Snippet } from 'svelte';
@@ -10,7 +10,7 @@
10
10
 
11
11
  /**
12
12
  * @import { Snippet } from 'svelte';
13
- * @import { CommonEventHandlers, HighlightedToken, InputEventHandlers } from '../../typedefs';
13
+ * @import { CommonEventHandlers, HighlightedToken, InputEventHandlers } from '../../typedefs.js';
14
14
  */
15
15
 
16
16
  /**
@@ -9,7 +9,7 @@ type TextArea = {
9
9
  * @see https://w3c.github.io/aria/#textbox
10
10
  * @see https://css-tricks.com/the-cleanest-trick-for-autogrowing-textareas/
11
11
  */
12
- declare const TextArea: import("svelte").Component<import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & InputEventHandlers & {
12
+ declare const TextArea: import("svelte").Component<import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & InputEventHandlers & {
13
13
  /**
14
14
  * Input value.
15
15
  */
@@ -153,6 +153,6 @@ type Props = {
153
153
  */
154
154
  children?: Snippet<[]> | undefined;
155
155
  };
156
- import type { InputEventHandlers } from '../../typedefs';
157
- import type { HighlightedToken } from '../../typedefs';
156
+ import type { InputEventHandlers } from '../../typedefs.js';
157
+ import type { HighlightedToken } from '../../typedefs.js';
158
158
  import type { Snippet } from 'svelte';
@@ -10,7 +10,7 @@
10
10
  import EmojiAutocomplete from './emoji-autocomplete.svelte';
11
11
 
12
12
  /**
13
- * @import { CommonEventHandlers, InputEventHandlers, TextInputProps } from '../../typedefs';
13
+ * @import { CommonEventHandlers, InputEventHandlers, TextInputProps } from '../../typedefs.js';
14
14
  */
15
15
 
16
16
  /**
@@ -8,7 +8,7 @@ type TextInput = {
8
8
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/text
9
9
  * @see https://w3c.github.io/aria/#textbox
10
10
  */
11
- declare const TextInput: import("svelte").Component<TextInputProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & InputEventHandlers & {
11
+ declare const TextInput: import("svelte").Component<TextInputProps & import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & InputEventHandlers & {
12
12
  /**
13
13
  * Input value.
14
14
  */
@@ -30,5 +30,5 @@ type Props = {
30
30
  */
31
31
  useEmojiAutocomplete?: boolean | undefined;
32
32
  };
33
- import type { TextInputProps } from '../../typedefs';
34
- import type { InputEventHandlers } from '../../typedefs';
33
+ import type { TextInputProps } from '../../typedefs.js';
34
+ import type { InputEventHandlers } from '../../typedefs.js';
@@ -179,11 +179,11 @@
179
179
  </script>
180
180
 
181
181
  <script>
182
- import { onMount, untrack } from 'svelte';
182
+ import { onMount } from 'svelte';
183
183
 
184
184
  /**
185
185
  * @import { Snippet } from 'svelte';
186
- * @import { ToastPosition } from '../../typedefs';
186
+ * @import { ToastPosition } from '../../typedefs.js';
187
187
  */
188
188
 
189
189
  /**
@@ -220,10 +220,6 @@
220
220
  * @type {HTMLElement | undefined}
221
221
  */
222
222
  let toast = $state();
223
- /**
224
- * @type {number}
225
- */
226
- let timerId = $state(0);
227
223
  /**
228
224
  * Whether the pointer is over the toast or the focus is inside it. The auto-hide countdown is
229
225
  * held while it is, so a toast with a control in it can’t vanish from under the user (WCAG
@@ -323,23 +319,18 @@
323
319
  void duration;
324
320
  void held;
325
321
 
326
- untrack(() => {
327
- globalThis.clearTimeout(timerId);
328
- });
329
-
330
- if (show && duration && !held) {
331
- timerId = /** @type {number} */ (
332
- /** @type {unknown} */ (
333
- globalThis.setTimeout(() => {
334
- show = false;
335
- }, duration)
336
- )
337
- );
322
+ if (!show || !duration || held) {
323
+ return undefined;
338
324
  }
339
325
 
340
- // Stop the countdown when the toast is destroyed, or it would still hide the toast later
326
+ const timer = globalThis.setTimeout(() => {
327
+ show = false;
328
+ }, duration);
329
+
330
+ // Stop the countdown when any of the above changes, so the previous timer can’t fire, or when
331
+ // the toast is destroyed, or it would still hide the toast later
341
332
  return () => {
342
- globalThis.clearTimeout(timerId);
333
+ globalThis.clearTimeout(timer);
343
334
  };
344
335
  });
345
336
  </script>
@@ -59,5 +59,5 @@ type Props = {
59
59
  */
60
60
  children?: Snippet<[]> | undefined;
61
61
  };
62
- import type { ToastPosition } from '../../typedefs';
62
+ import type { ToastPosition } from '../../typedefs.js';
63
63
  import type { Snippet } from 'svelte';
@@ -14,7 +14,7 @@
14
14
  /**
15
15
  * @import { Snippet } from 'svelte';
16
16
  * @import { Attachment } from 'svelte/attachments';
17
- * @import { CommonEventHandlers } from '../../typedefs';
17
+ * @import { CommonEventHandlers } from '../../typedefs.js';
18
18
  */
19
19
 
20
20
  /**
@@ -9,7 +9,7 @@ type TreeItem = {
9
9
  * @see https://w3c.github.io/aria/#treeitem
10
10
  * @see https://www.w3.org/WAI/ARIA/apg/patterns/treeview/
11
11
  */
12
- declare const TreeItem: import("svelte").Component<import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & {
12
+ declare const TreeItem: import("svelte").Component<import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & {
13
13
  /**
14
14
  * The `class` attribute on the wrapper element.
15
15
  */
@@ -10,7 +10,7 @@
10
10
 
11
11
  /**
12
12
  * @import { Snippet } from 'svelte';
13
- * @import { CommonEventHandlers } from '../../typedefs';
13
+ * @import { CommonEventHandlers } from '../../typedefs.js';
14
14
  */
15
15
 
16
16
  /**
@@ -9,7 +9,7 @@ type Tree = {
9
9
  * @see https://w3c.github.io/aria/#tree
10
10
  * @see https://www.w3.org/WAI/ARIA/apg/patterns/treeview/
11
11
  */
12
- declare const Tree: import("svelte").Component<import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & {
12
+ declare const Tree: import("svelte").Component<import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & {
13
13
  /**
14
14
  * A reference to the wrapper element.
15
15
  */
@@ -60,4 +60,5 @@
60
60
  -moz-font-feature-settings: 'liga';
61
61
  font-feature-settings: 'liga';
62
62
  }
63
+
63
64
  </style>
@@ -25,7 +25,7 @@
25
25
  import Placeholder from './placeholder.svelte';
26
26
 
27
27
  /**
28
- * @import { ModalProps } from '../../typedefs';
28
+ * @import { ModalProps } from '../../typedefs.js';
29
29
  */
30
30
 
31
31
  /**
@@ -154,6 +154,14 @@
154
154
  */
155
155
  let lastActiveElement;
156
156
 
157
+ /**
158
+ * The element the last `pointerdown` event in the modal was fired on. A click that lands on the
159
+ * backdrop only dismisses the modal if the pointer was also pressed there, so selecting text in
160
+ * the content by dragging and releasing the pointer over the backdrop doesn’t close it.
161
+ * @type {EventTarget | null | undefined}
162
+ */
163
+ let pointerDownTarget;
164
+
157
165
  /**
158
166
  * Timer used to defer the focus restoration in {@link moveFocusBack}.
159
167
  * @type {number | undefined}
@@ -404,7 +412,19 @@
404
412
  class:backdrop={showBackdrop}
405
413
  class:open={setOpenClass}
406
414
  class:active={setActiveClass}
415
+ onpointerdown={({ target }) => {
416
+ pointerDownTarget = target;
417
+ }}
407
418
  onclick={({ target }) => {
419
+ const downTarget = pointerDownTarget;
420
+
421
+ pointerDownTarget = undefined;
422
+
423
+ // A click with no `pointerdown` before it, like one dispatched by a script, is taken as is
424
+ if (downTarget && downTarget !== dialog) {
425
+ return;
426
+ }
427
+
408
428
  if (
409
429
  dialog &&
410
430
  lightDismiss &&
@@ -423,6 +443,22 @@
423
443
  open = false;
424
444
  }
425
445
  }}
446
+ onclose={() => {
447
+ // Closed by `closeDialog()` or on unmount, or already shown again by `openDialog()`
448
+ if (!requestedOpen || !dialog?.isConnected || dialog.open) {
449
+ return;
450
+ }
451
+
452
+ // The browser has closed the dialog on its own. The `cancel` event can’t always be
453
+ // prevented: Chrome makes it non-cancelable when Escape is pressed again without any user
454
+ // activation in between. Show the dialog again if it shouldn’t be dismissed with Escape,
455
+ // otherwise bring the state in line, so the usual closing steps run.
456
+ if (!escapeDismiss) {
457
+ dialog.showModal();
458
+ } else {
459
+ open = false;
460
+ }
461
+ }}
426
462
  >
427
463
  {@render extraContent?.()}
428
464
  {@render children?.()}
@@ -11,4 +11,4 @@ declare const Modal: import("svelte").Component<ModalProps & Record<string, any>
11
11
  focus: () => void;
12
12
  close: (returnValue: string) => void;
13
13
  }, "dialog" | "open">;
14
- import type { ModalProps } from '../../typedefs';
14
+ import type { ModalProps } from '../../typedefs.js';