@sveltia/ui 0.21.0 → 0.22.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 (174) hide show
  1. package/{package → dist}/components/button/button.svelte +1 -1
  2. package/{package → dist}/components/button/select-button-group.svelte +3 -0
  3. package/{package → dist}/components/calendar/calendar.svelte +1 -1
  4. package/{package → dist}/components/checkbox/checkbox.svelte +9 -2
  5. package/{package → dist}/components/grid/grid.svelte +1 -1
  6. package/{package → dist}/components/listbox/listbox.svelte +3 -0
  7. package/{package → dist}/components/menu/menu-button.svelte +1 -1
  8. package/{package → dist}/components/progressbar/progressbar.svelte +4 -1
  9. package/{package → dist}/components/radio/radio-group.svelte +9 -0
  10. package/{package → dist}/components/radio/radio.svelte +3 -3
  11. package/{package → dist}/components/select/combobox.svelte +6 -2
  12. package/{package → dist}/components/select/select-tags.svelte +1 -1
  13. package/{package → dist}/components/slider/slider.svelte +14 -7
  14. package/{package → dist}/components/switch/switch.svelte +4 -1
  15. package/{package → dist}/components/tabs/tab-list.svelte +1 -1
  16. package/{package → dist}/components/text-editor/core.js +79 -5
  17. package/{package → dist}/components/text-editor/index.js +6 -0
  18. package/dist/components/text-editor/lexical-root.svelte +288 -0
  19. package/{package → dist}/components/text-editor/text-editor.svelte +10 -4
  20. package/{package → dist}/components/text-editor/toolbar/toggle-block-menu-item.svelte +7 -0
  21. package/{package → dist}/components/text-field/number-input.svelte +31 -16
  22. package/{package → dist}/components/text-field/number-input.svelte.d.ts +8 -0
  23. package/{package → dist}/components/text-field/password-input.svelte +1 -0
  24. package/{package → dist}/components/text-field/password-input.svelte.d.ts +8 -0
  25. package/{package → dist}/components/text-field/search-bar.svelte +1 -0
  26. package/{package → dist}/components/text-field/search-bar.svelte.d.ts +8 -0
  27. package/{package → dist}/components/text-field/text-area.svelte +4 -4
  28. package/{package → dist}/components/text-field/text-input.svelte +7 -2
  29. package/{package → dist}/components/text-field/text-input.svelte.d.ts +13 -2
  30. package/{package → dist}/components/toast/toast.svelte +1 -1
  31. package/{package → dist}/components/toolbar/toolbar.svelte +2 -2
  32. package/{package → dist}/components/util/app-shell.svelte +6 -6
  33. package/{package → dist}/components/util/app-shell.svelte.d.ts +2 -2
  34. package/{package → dist}/components/util/popup.svelte +2 -2
  35. package/{package → dist}/locales/en.d.ts +1 -0
  36. package/{package → dist}/locales/en.js +1 -0
  37. package/{package → dist}/locales/ja.d.ts +1 -0
  38. package/{package → dist}/locales/ja.js +1 -0
  39. package/{package → dist}/styles/variables.scss +2 -2
  40. package/{package → dist}/typedefs.d.ts +1 -5
  41. package/{package → dist}/typedefs.js +14 -14
  42. package/package.json +18 -17
  43. package/package/components/text-editor/lexical-root.svelte +0 -150
  44. /package/{package → dist}/components/alert/alert.svelte +0 -0
  45. /package/{package → dist}/components/alert/alert.svelte.d.ts +0 -0
  46. /package/{package → dist}/components/button/button-group.svelte +0 -0
  47. /package/{package → dist}/components/button/button-group.svelte.d.ts +0 -0
  48. /package/{package → dist}/components/button/button.svelte.d.ts +0 -0
  49. /package/{package → dist}/components/button/select-button-group.svelte.d.ts +0 -0
  50. /package/{package → dist}/components/button/select-button.svelte +0 -0
  51. /package/{package → dist}/components/button/select-button.svelte.d.ts +0 -0
  52. /package/{package → dist}/components/button/split-button.svelte +0 -0
  53. /package/{package → dist}/components/button/split-button.svelte.d.ts +0 -0
  54. /package/{package → dist}/components/calendar/calendar.svelte.d.ts +0 -0
  55. /package/{package → dist}/components/checkbox/checkbox-group.svelte +0 -0
  56. /package/{package → dist}/components/checkbox/checkbox-group.svelte.d.ts +0 -0
  57. /package/{package → dist}/components/checkbox/checkbox.svelte.d.ts +0 -0
  58. /package/{package → dist}/components/dialog/alert-dialog.svelte +0 -0
  59. /package/{package → dist}/components/dialog/alert-dialog.svelte.d.ts +0 -0
  60. /package/{package → dist}/components/dialog/confirmation-dialog.svelte +0 -0
  61. /package/{package → dist}/components/dialog/confirmation-dialog.svelte.d.ts +0 -0
  62. /package/{package → dist}/components/dialog/dialog.svelte +0 -0
  63. /package/{package → dist}/components/dialog/dialog.svelte.d.ts +0 -0
  64. /package/{package → dist}/components/dialog/prompt-dialog.svelte +0 -0
  65. /package/{package → dist}/components/dialog/prompt-dialog.svelte.d.ts +0 -0
  66. /package/{package → dist}/components/disclosure/disclosure.svelte +0 -0
  67. /package/{package → dist}/components/disclosure/disclosure.svelte.d.ts +0 -0
  68. /package/{package → dist}/components/divider/divider.svelte +0 -0
  69. /package/{package → dist}/components/divider/divider.svelte.d.ts +0 -0
  70. /package/{package → dist}/components/divider/spacer.svelte +0 -0
  71. /package/{package → dist}/components/divider/spacer.svelte.d.ts +0 -0
  72. /package/{package → dist}/components/drawer/drawer.svelte +0 -0
  73. /package/{package → dist}/components/drawer/drawer.svelte.d.ts +0 -0
  74. /package/{package → dist}/components/grid/grid-body.svelte +0 -0
  75. /package/{package → dist}/components/grid/grid-body.svelte.d.ts +0 -0
  76. /package/{package → dist}/components/grid/grid-cell.svelte +0 -0
  77. /package/{package → dist}/components/grid/grid-cell.svelte.d.ts +0 -0
  78. /package/{package → dist}/components/grid/grid-col-header.svelte +0 -0
  79. /package/{package → dist}/components/grid/grid-col-header.svelte.d.ts +0 -0
  80. /package/{package → dist}/components/grid/grid-foot.svelte +0 -0
  81. /package/{package → dist}/components/grid/grid-foot.svelte.d.ts +0 -0
  82. /package/{package → dist}/components/grid/grid-head.svelte +0 -0
  83. /package/{package → dist}/components/grid/grid-head.svelte.d.ts +0 -0
  84. /package/{package → dist}/components/grid/grid-row-header.svelte +0 -0
  85. /package/{package → dist}/components/grid/grid-row-header.svelte.d.ts +0 -0
  86. /package/{package → dist}/components/grid/grid-row.svelte +0 -0
  87. /package/{package → dist}/components/grid/grid-row.svelte.d.ts +0 -0
  88. /package/{package → dist}/components/grid/grid.svelte.d.ts +0 -0
  89. /package/{package → dist}/components/icon/icon.svelte +0 -0
  90. /package/{package → dist}/components/icon/icon.svelte.d.ts +0 -0
  91. /package/{package → dist}/components/listbox/listbox.svelte.d.ts +0 -0
  92. /package/{package → dist}/components/listbox/option-group.svelte +0 -0
  93. /package/{package → dist}/components/listbox/option-group.svelte.d.ts +0 -0
  94. /package/{package → dist}/components/listbox/option.svelte +0 -0
  95. /package/{package → dist}/components/listbox/option.svelte.d.ts +0 -0
  96. /package/{package → dist}/components/menu/menu-button.svelte.d.ts +0 -0
  97. /package/{package → dist}/components/menu/menu-item-checkbox.svelte +0 -0
  98. /package/{package → dist}/components/menu/menu-item-checkbox.svelte.d.ts +0 -0
  99. /package/{package → dist}/components/menu/menu-item-group.svelte +0 -0
  100. /package/{package → dist}/components/menu/menu-item-group.svelte.d.ts +0 -0
  101. /package/{package → dist}/components/menu/menu-item-radio.svelte +0 -0
  102. /package/{package → dist}/components/menu/menu-item-radio.svelte.d.ts +0 -0
  103. /package/{package → dist}/components/menu/menu-item.svelte +0 -0
  104. /package/{package → dist}/components/menu/menu-item.svelte.d.ts +0 -0
  105. /package/{package → dist}/components/menu/menu.svelte +0 -0
  106. /package/{package → dist}/components/menu/menu.svelte.d.ts +0 -0
  107. /package/{package → dist}/components/progressbar/progressbar.svelte.d.ts +0 -0
  108. /package/{package → dist}/components/radio/radio-group.svelte.d.ts +0 -0
  109. /package/{package → dist}/components/radio/radio.svelte.d.ts +0 -0
  110. /package/{package → dist}/components/select/combobox.svelte.d.ts +0 -0
  111. /package/{package → dist}/components/select/select-tags.svelte.d.ts +0 -0
  112. /package/{package → dist}/components/select/select.svelte +0 -0
  113. /package/{package → dist}/components/select/select.svelte.d.ts +0 -0
  114. /package/{package → dist}/components/slider/slider.svelte.d.ts +0 -0
  115. /package/{package → dist}/components/switch/switch.svelte.d.ts +0 -0
  116. /package/{package → dist}/components/table/table-body.svelte +0 -0
  117. /package/{package → dist}/components/table/table-body.svelte.d.ts +0 -0
  118. /package/{package → dist}/components/table/table-cell.svelte +0 -0
  119. /package/{package → dist}/components/table/table-cell.svelte.d.ts +0 -0
  120. /package/{package → dist}/components/table/table-col-header.svelte +0 -0
  121. /package/{package → dist}/components/table/table-col-header.svelte.d.ts +0 -0
  122. /package/{package → dist}/components/table/table-foot.svelte +0 -0
  123. /package/{package → dist}/components/table/table-foot.svelte.d.ts +0 -0
  124. /package/{package → dist}/components/table/table-head.svelte +0 -0
  125. /package/{package → dist}/components/table/table-head.svelte.d.ts +0 -0
  126. /package/{package → dist}/components/table/table-row-header.svelte +0 -0
  127. /package/{package → dist}/components/table/table-row-header.svelte.d.ts +0 -0
  128. /package/{package → dist}/components/table/table-row.svelte +0 -0
  129. /package/{package → dist}/components/table/table-row.svelte.d.ts +0 -0
  130. /package/{package → dist}/components/table/table.svelte +0 -0
  131. /package/{package → dist}/components/table/table.svelte.d.ts +0 -0
  132. /package/{package → dist}/components/tabs/tab-box.svelte +0 -0
  133. /package/{package → dist}/components/tabs/tab-box.svelte.d.ts +0 -0
  134. /package/{package → dist}/components/tabs/tab-list.svelte.d.ts +0 -0
  135. /package/{package → dist}/components/tabs/tab-panel.svelte +0 -0
  136. /package/{package → dist}/components/tabs/tab-panel.svelte.d.ts +0 -0
  137. /package/{package → dist}/components/tabs/tab-panels.svelte +0 -0
  138. /package/{package → dist}/components/tabs/tab-panels.svelte.d.ts +0 -0
  139. /package/{package → dist}/components/tabs/tab.svelte +0 -0
  140. /package/{package → dist}/components/tabs/tab.svelte.d.ts +0 -0
  141. /package/{package → dist}/components/text-editor/core.d.ts +0 -0
  142. /package/{package → dist}/components/text-editor/index.d.ts +0 -0
  143. /package/{package → dist}/components/text-editor/lexical-root.svelte.d.ts +0 -0
  144. /package/{package → dist}/components/text-editor/text-editor.svelte.d.ts +0 -0
  145. /package/{package → dist}/components/text-editor/toolbar/editor-toolbar.svelte +0 -0
  146. /package/{package → dist}/components/text-editor/toolbar/editor-toolbar.svelte.d.ts +0 -0
  147. /package/{package → dist}/components/text-editor/toolbar/format-text-button.svelte +0 -0
  148. /package/{package → dist}/components/text-editor/toolbar/format-text-button.svelte.d.ts +0 -0
  149. /package/{package → dist}/components/text-editor/toolbar/insert-image-button.svelte +0 -0
  150. /package/{package → dist}/components/text-editor/toolbar/insert-image-button.svelte.d.ts +0 -0
  151. /package/{package → dist}/components/text-editor/toolbar/insert-link-button.svelte +0 -0
  152. /package/{package → dist}/components/text-editor/toolbar/insert-link-button.svelte.d.ts +0 -0
  153. /package/{package → dist}/components/text-editor/toolbar/insert-menu-button.svelte +0 -0
  154. /package/{package → dist}/components/text-editor/toolbar/insert-menu-button.svelte.d.ts +0 -0
  155. /package/{package → dist}/components/text-editor/toolbar/toggle-block-menu-item.svelte.d.ts +0 -0
  156. /package/{package → dist}/components/text-field/text-area.svelte.d.ts +0 -0
  157. /package/{package → dist}/components/toast/toast.svelte.d.ts +0 -0
  158. /package/{package → dist}/components/toolbar/toolbar.svelte.d.ts +0 -0
  159. /package/{package → dist}/components/util/group.svelte +0 -0
  160. /package/{package → dist}/components/util/group.svelte.d.ts +0 -0
  161. /package/{package → dist}/components/util/modal.svelte +0 -0
  162. /package/{package → dist}/components/util/modal.svelte.d.ts +0 -0
  163. /package/{package → dist}/components/util/placeholder.svelte +0 -0
  164. /package/{package → dist}/components/util/placeholder.svelte.d.ts +0 -0
  165. /package/{package → dist}/components/util/popup.svelte.d.ts +0 -0
  166. /package/{package → dist}/index.d.ts +0 -0
  167. /package/{package → dist}/index.js +0 -0
  168. /package/{package → dist}/services/events.svelte.d.ts +0 -0
  169. /package/{package → dist}/services/events.svelte.js +0 -0
  170. /package/{package → dist}/services/group.svelte.d.ts +0 -0
  171. /package/{package → dist}/services/group.svelte.js +0 -0
  172. /package/{package → dist}/services/popup.svelte.d.ts +0 -0
  173. /package/{package → dist}/services/popup.svelte.js +0 -0
  174. /package/{package → dist}/styles/core.scss +0 -0
@@ -0,0 +1,288 @@
1
+ <script>
2
+ import { getContext, onMount } from 'svelte';
3
+
4
+ /**
5
+ * @typedef {object} Props
6
+ * @property {string} [value] - Input value.
7
+ * @property {string} [class] - The `class` attribute on the wrapper element.
8
+ * @property {boolean} [hidden] - Whether to hide the widget.
9
+ * @property {boolean} [disabled] - Whether to disable the widget. An alias of the `aria-disabled`
10
+ * attribute.
11
+ * @property {boolean} [readonly] - Whether to make the widget read-only. An alias of the
12
+ * `aria-readonly` attribute.
13
+ * @property {boolean} [required] - Whether to mark the widget required. An alias of the
14
+ * `aria-required` attribute.
15
+ * @property {boolean} [invalid] - Whether to mark the widget invalid. An alias of the
16
+ * `aria-invalid` attribute.
17
+ * @property {import('svelte').Snippet} [children] - Primary slot content.
18
+ */
19
+
20
+ /**
21
+ * @type {Props & Record<string, any>}
22
+ */
23
+ let {
24
+ /* eslint-disable prefer-const */
25
+ value = $bindable(),
26
+ class: className,
27
+ hidden = false,
28
+ disabled = false,
29
+ readonly = false,
30
+ required = false,
31
+ invalid = false,
32
+ children,
33
+ ...restProps
34
+ /* eslint-enable prefer-const */
35
+ } = $props();
36
+
37
+ /**
38
+ * Text editor state.
39
+ * @type {import('../../typedefs').TextEditorState}
40
+ */
41
+ const { editor, editorId, selectionBlockType, selectionInlineTypes, hasConverterError } =
42
+ getContext('state');
43
+
44
+ /**
45
+ * Reference to the Lexical editor root element.
46
+ * @type {HTMLElement | undefined}
47
+ */
48
+ let lexicalRoot = $state();
49
+
50
+ const editable = $derived(!(disabled || readonly));
51
+
52
+ $effect(() => {
53
+ $editor?.setEditable(editable);
54
+ });
55
+
56
+ /**
57
+ * Update {@link value} and other state variables whenever the editor content is updated.
58
+ * @param {Event} event - `Update` custom event.
59
+ */
60
+ const onUpdate = (event) => {
61
+ if ($hasConverterError) {
62
+ return;
63
+ }
64
+
65
+ const { detail } = /** @type {CustomEvent} */ (event);
66
+ const newValue = detail.value;
67
+
68
+ if (value !== newValue) {
69
+ value = newValue;
70
+ }
71
+
72
+ $selectionBlockType = detail.selectionBlockType;
73
+ $selectionInlineTypes = detail.selectionInlineTypes;
74
+ };
75
+
76
+ /**
77
+ * Listen to `click` events on the editor. Ignore a click on a link.
78
+ * @param {MouseEvent} event - `click` event.
79
+ */
80
+ const onClick = (event) => {
81
+ if (/** @type {HTMLElement} */ (event.target)?.matches('a')) {
82
+ event.preventDefault();
83
+ }
84
+ };
85
+
86
+ onMount(() => {
87
+ lexicalRoot?.addEventListener('Update', onUpdate);
88
+ lexicalRoot?.addEventListener('click', onClick);
89
+
90
+ return () => {
91
+ lexicalRoot?.removeEventListener('Update', onUpdate);
92
+ lexicalRoot?.removeEventListener('click', onClick);
93
+ };
94
+ });
95
+
96
+ $effect(() => {
97
+ if ($editor && lexicalRoot) {
98
+ $editor.setRootElement(lexicalRoot);
99
+ }
100
+ });
101
+ </script>
102
+
103
+ <div
104
+ bind:this={lexicalRoot}
105
+ {...restProps}
106
+ role="textbox"
107
+ aria-multiline="true"
108
+ aria-hidden={hidden}
109
+ aria-disabled={disabled}
110
+ aria-readonly={readonly}
111
+ aria-required={required}
112
+ aria-invalid={invalid}
113
+ class="lexical-root"
114
+ id="{$editorId}-lexical-root"
115
+ contenteditable={editable}
116
+ {hidden}
117
+ ></div>
118
+
119
+ <style>.lexical-root {
120
+ border: 1px solid var(--sui-textbox-border-color);
121
+ border-radius: 0 0 var(--sui-textbox-border-radius) var(--sui-textbox-border-radius) !important;
122
+ padding: var(--sui-textbox-multiline-padding);
123
+ min-height: 8em;
124
+ color: var(--sui-textbox-foreground-color);
125
+ background-color: var(--sui-textbox-background-color);
126
+ font-family: var(--sui-textbox-font-family);
127
+ font-size: var(--sui-textbox-font-size);
128
+ line-height: var(--sui-textbox-multiline-line-height);
129
+ }
130
+ .lexical-root:focus-visible {
131
+ outline: 0;
132
+ }
133
+ .lexical-root[aria-invalid=true] {
134
+ border-color: var(--sui-error-border-color);
135
+ }
136
+ .lexical-root > :global(:first-child) {
137
+ margin-top: 0;
138
+ }
139
+ .lexical-root > :global(:last-child) {
140
+ margin-bottom: 0;
141
+ }
142
+ .lexical-root :global(strong.italic) {
143
+ font-style: italic;
144
+ }
145
+ .lexical-root :global(li.nested) {
146
+ list-style-type: none;
147
+ }
148
+ .lexical-root :global(.code-block) {
149
+ position: relative;
150
+ display: block;
151
+ padding: 8px 8px 8px 56px;
152
+ background-color: var(--sui-code-background-color);
153
+ overflow-x: auto;
154
+ white-space: pre;
155
+ }
156
+ .lexical-root :global(.code-block:not(:first-child)) {
157
+ margin-top: 1em;
158
+ }
159
+ .lexical-root :global(.code-block:not(:last-child)) {
160
+ margin-bottom: 1em;
161
+ }
162
+ .lexical-root :global(.code-block::before) {
163
+ position: absolute;
164
+ inset: 0 auto 0 0;
165
+ content: attr(data-gutter);
166
+ padding: 8px;
167
+ min-width: 40px;
168
+ color: var(--sui-tertiary-foreground-color);
169
+ background-color: var(--sui-secondary-background-color);
170
+ text-align: right;
171
+ }
172
+ .lexical-root :global([data-lexical-text=true]) {
173
+ cursor: text;
174
+ }
175
+
176
+ :root[data-theme=light] .lexical-root :global(.token.comment),
177
+ :root[data-theme=light] .lexical-root :global(.token.prolog),
178
+ :root[data-theme=light] .lexical-root :global(.token.doctype),
179
+ :root[data-theme=light] .lexical-root :global(.token.cdata) {
180
+ color: slategray;
181
+ }
182
+ :root[data-theme=light] .lexical-root :global(.token.punctuation) {
183
+ color: #999;
184
+ }
185
+ :root[data-theme=light] .lexical-root :global(.token.namespace) {
186
+ opacity: 0.7;
187
+ }
188
+ :root[data-theme=light] .lexical-root :global(.token.property),
189
+ :root[data-theme=light] .lexical-root :global(.token.tag),
190
+ :root[data-theme=light] .lexical-root :global(.token.boolean),
191
+ :root[data-theme=light] .lexical-root :global(.token.number),
192
+ :root[data-theme=light] .lexical-root :global(.token.constant),
193
+ :root[data-theme=light] .lexical-root :global(.token.symbol),
194
+ :root[data-theme=light] .lexical-root :global(.token.deleted) {
195
+ color: #905;
196
+ }
197
+ :root[data-theme=light] .lexical-root :global(.token.selector),
198
+ :root[data-theme=light] .lexical-root :global(.token.attr-name),
199
+ :root[data-theme=light] .lexical-root :global(.token.string),
200
+ :root[data-theme=light] .lexical-root :global(.token.char),
201
+ :root[data-theme=light] .lexical-root :global(.token.builtin),
202
+ :root[data-theme=light] .lexical-root :global(.token.inserted) {
203
+ color: #690;
204
+ }
205
+ :root[data-theme=light] .lexical-root :global(.token.operator),
206
+ :root[data-theme=light] .lexical-root :global(.token.entity),
207
+ :root[data-theme=light] .lexical-root :global(.token.url),
208
+ :root[data-theme=light] .lexical-root :global(.language-css) :global(.token.string),
209
+ :root[data-theme=light] .lexical-root :global(.style) :global(.token.string) {
210
+ color: #9a6e3a;
211
+ }
212
+ :root[data-theme=light] .lexical-root :global(.token.atrule),
213
+ :root[data-theme=light] .lexical-root :global(.token.attr-value),
214
+ :root[data-theme=light] .lexical-root :global(.token.keyword) {
215
+ color: #07a;
216
+ }
217
+ :root[data-theme=light] .lexical-root :global(.token.function),
218
+ :root[data-theme=light] .lexical-root :global(.token.class-name) {
219
+ color: #dd4a68;
220
+ }
221
+ :root[data-theme=light] .lexical-root :global(.token.regex),
222
+ :root[data-theme=light] .lexical-root :global(.token.important),
223
+ :root[data-theme=light] .lexical-root :global(.token.variable) {
224
+ color: #e90;
225
+ }
226
+
227
+ :root[data-theme=dark] .lexical-root :global(.token.comment),
228
+ :root[data-theme=dark] .lexical-root :global(.token.block-comment),
229
+ :root[data-theme=dark] .lexical-root :global(.token.prolog),
230
+ :root[data-theme=dark] .lexical-root :global(.token.doctype),
231
+ :root[data-theme=dark] .lexical-root :global(.token.cdata) {
232
+ color: #999;
233
+ }
234
+ :root[data-theme=dark] .lexical-root :global(.token.punctuation) {
235
+ color: #ccc;
236
+ }
237
+ :root[data-theme=dark] .lexical-root :global(.token.tag),
238
+ :root[data-theme=dark] .lexical-root :global(.token.attr-name),
239
+ :root[data-theme=dark] .lexical-root :global(.token.namespace),
240
+ :root[data-theme=dark] .lexical-root :global(.token.deleted) {
241
+ color: #e2777a;
242
+ }
243
+ :root[data-theme=dark] .lexical-root :global(.token.function-name) {
244
+ color: #6196cc;
245
+ }
246
+ :root[data-theme=dark] .lexical-root :global(.token.boolean),
247
+ :root[data-theme=dark] .lexical-root :global(.token.number),
248
+ :root[data-theme=dark] .lexical-root :global(.token.function) {
249
+ color: #f08d49;
250
+ }
251
+ :root[data-theme=dark] .lexical-root :global(.token.property),
252
+ :root[data-theme=dark] .lexical-root :global(.token.class-name),
253
+ :root[data-theme=dark] .lexical-root :global(.token.constant),
254
+ :root[data-theme=dark] .lexical-root :global(.token.symbol) {
255
+ color: #f8c555;
256
+ }
257
+ :root[data-theme=dark] .lexical-root :global(.token.selector),
258
+ :root[data-theme=dark] .lexical-root :global(.token.important),
259
+ :root[data-theme=dark] .lexical-root :global(.token.atrule),
260
+ :root[data-theme=dark] .lexical-root :global(.token.keyword),
261
+ :root[data-theme=dark] .lexical-root :global(.token.builtin) {
262
+ color: #cc99cd;
263
+ }
264
+ :root[data-theme=dark] .lexical-root :global(.token.string),
265
+ :root[data-theme=dark] .lexical-root :global(.token.char),
266
+ :root[data-theme=dark] .lexical-root :global(.token.attr-value),
267
+ :root[data-theme=dark] .lexical-root :global(.token.regex),
268
+ :root[data-theme=dark] .lexical-root :global(.token.variable) {
269
+ color: #7ec699;
270
+ }
271
+ :root[data-theme=dark] .lexical-root :global(.token.operator),
272
+ :root[data-theme=dark] .lexical-root :global(.token.entity),
273
+ :root[data-theme=dark] .lexical-root :global(.token.url) {
274
+ color: #67cdcc;
275
+ }
276
+ :root[data-theme=dark] .lexical-root :global(.token.important),
277
+ :root[data-theme=dark] .lexical-root :global(.token.bold) {
278
+ font-weight: bold;
279
+ }
280
+ :root[data-theme=dark] .lexical-root :global(.token.italic) {
281
+ font-style: italic;
282
+ }
283
+ :root[data-theme=dark] .lexical-root :global(.token.entity) {
284
+ cursor: help;
285
+ }
286
+ :root[data-theme=dark] .lexical-root :global(.token.inserted) {
287
+ color: green;
288
+ }</style>
@@ -17,7 +17,7 @@
17
17
 
18
18
  /**
19
19
  * @typedef {object} Props
20
- * @property {string | undefined} [value] - Input value.
20
+ * @property {string} [value] - Input value.
21
21
  * @property {boolean} [flex] - Make the text input container flexible.
22
22
  * @property {import('../../typedefs').TextEditorMode[]} [modes] - Enabled modes.
23
23
  * @property {(import('../../typedefs').TextEditorBlockType |
@@ -78,9 +78,6 @@
78
78
  const originalValue = inputValue;
79
79
 
80
80
  try {
81
- // We should avoid an empty editor; there should be at least one `<p>`, so give it an empty
82
- // string if the `value` is `undefined`
83
- // @see https://github.com/facebook/lexical/issues/2308
84
81
  await convertMarkdownToLexical($editor, inputValue ?? '');
85
82
  } catch (ex) {
86
83
  $hasConverterError = true;
@@ -90,6 +87,15 @@
90
87
  }
91
88
  };
92
89
 
90
+ $effect(() => {
91
+ // We should avoid an empty editor; there should be at least one `<p>`, so give it an empty
92
+ // string if the `value` is `undefined`
93
+ // @see https://github.com/facebook/lexical/issues/2308
94
+ if ($editor?.getEditorState().isEmpty()) {
95
+ convertMarkdownToLexical($editor, '');
96
+ }
97
+ });
98
+
93
99
  $effect(() => {
94
100
  void $editor;
95
101
 
@@ -1,4 +1,5 @@
1
1
  <script>
2
+ import { $createCodeNode as createCodeNode } from '@lexical/code';
2
3
  import { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND } from '@lexical/list';
3
4
  import {
4
5
  $createHeadingNode as createHeadingNode,
@@ -78,6 +79,12 @@
78
79
  setBlocksType(getSelection(), () => createQuoteNode());
79
80
  });
80
81
  }
82
+
83
+ if (type === 'code-block') {
84
+ $editor.update(() => {
85
+ setBlocksType(getSelection(), () => createCodeNode());
86
+ });
87
+ }
81
88
  };
82
89
  </script>
83
90
 
@@ -13,8 +13,9 @@
13
13
 
14
14
  /**
15
15
  * @typedef {object} Props
16
- * @property {number | undefined} [min] - Minimum allowed value.
17
- * @property {number | undefined} [max] - Maximum allowed value.
16
+ * @property {number} [value] - Input value.
17
+ * @property {number} [min] - Minimum allowed value.
18
+ * @property {number} [max] - Maximum allowed value.
18
19
  * @property {number} [step] - Value to be added or removed when using the up/down arrow key or
19
20
  * button.
20
21
  * @property {import('svelte').Snippet} [increaseIcon] - Increase icon slot content.
@@ -48,41 +49,50 @@
48
49
 
49
50
  const id = generateElementId('input');
50
51
  let edited = $state(false);
52
+ let inputValue = $state('');
51
53
 
52
54
  const maximumFractionDigits = $derived(String(step).split('.')[1]?.length || 0);
53
- const isMin = $derived(typeof min === 'number' && Number(value || 0) <= min);
54
- const isMax = $derived(typeof max === 'number' && Number(value || 0) >= max);
55
+ const isMin = $derived(typeof min === 'number' && Number(inputValue || 0) <= min);
56
+ const isMax = $derived(typeof max === 'number' && Number(inputValue || 0) >= max);
55
57
 
56
58
  $effect(() => {
57
- invalid =
58
- (required && edited && (value === undefined || value === '')) ||
59
- (value !== undefined &&
60
- value !== '' &&
61
- (Number.isNaN(Number(value)) ||
62
- (typeof min === 'number' && Number(value || 0) < min) ||
63
- (typeof max === 'number' && Number(value || 0) > max)));
59
+ const newValue = inputValue.trim() ? Number(inputValue) : NaN;
60
+
61
+ value = !Number.isNaN(newValue) ? newValue : undefined;
62
+ });
63
+
64
+ $effect(() => {
65
+ if (edited) {
66
+ invalid =
67
+ (required && (value === undefined || inputValue === '')) ||
68
+ (inputValue !== undefined &&
69
+ inputValue !== '' &&
70
+ (Number.isNaN(Number(inputValue)) ||
71
+ (typeof min === 'number' && Number(inputValue || 0) < min) ||
72
+ (typeof max === 'number' && Number(inputValue || 0) > max)));
73
+ }
64
74
  });
65
75
 
66
76
  /**
67
77
  * Decrease the number.
68
78
  */
69
79
  const decrease = () => {
70
- if (isMin) {
80
+ if (isMin || Number.isNaN(Number(inputValue))) {
71
81
  return;
72
82
  }
73
83
 
74
- value = Number(Number(value || 0) - step).toFixed(maximumFractionDigits);
84
+ inputValue = Number(Number(inputValue || 0) - step).toFixed(maximumFractionDigits);
75
85
  };
76
86
 
77
87
  /**
78
88
  * Increase the number.
79
89
  */
80
90
  const increase = () => {
81
- if (isMax) {
91
+ if (isMax || Number.isNaN(Number(inputValue))) {
82
92
  return;
83
93
  }
84
94
 
85
- value = Number(Number(value || 0) + step).toFixed(maximumFractionDigits);
95
+ inputValue = Number(Number(inputValue || 0) + step).toFixed(maximumFractionDigits);
86
96
  };
87
97
  </script>
88
98
 
@@ -134,7 +144,7 @@
134
144
  {...restProps}
135
145
  role="spinbutton"
136
146
  {id}
137
- bind:value
147
+ bind:value={inputValue}
138
148
  spellcheck="false"
139
149
  {flex}
140
150
  {hidden}
@@ -164,6 +174,11 @@
164
174
  edited = true;
165
175
  }
166
176
  }}
177
+ oninput={() => {
178
+ if (!edited) {
179
+ edited = true;
180
+ }
181
+ }}
167
182
  {onChange}
168
183
  />
169
184
  </div>
@@ -9,6 +9,10 @@ type NumberInput = {
9
9
  * @see https://w3c.github.io/aria/#textbox
10
10
  */
11
11
  declare const NumberInput: import("svelte").Component<import("../../typedefs").TextInputProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & import("../../typedefs").InputEventHandlers & {
12
+ /**
13
+ * - Input value.
14
+ */
15
+ value?: number | undefined;
12
16
  /**
13
17
  * - Minimum allowed value.
14
18
  */
@@ -32,6 +36,10 @@ declare const NumberInput: import("svelte").Component<import("../../typedefs").T
32
36
  decreaseIcon?: import("svelte").Snippet<[]> | undefined;
33
37
  } & Record<string, any>, {}, "invalid" | "value">;
34
38
  type Props = {
39
+ /**
40
+ * - Input value.
41
+ */
42
+ value?: number | undefined;
35
43
  /**
36
44
  * - Minimum allowed value.
37
45
  */
@@ -14,6 +14,7 @@
14
14
 
15
15
  /**
16
16
  * @typedef {object} Props
17
+ * @property {string} [value] - Input value.
17
18
  * @property {import('svelte').Snippet} [visibilityIcon] - Visibility icon slot content.
18
19
  */
19
20
 
@@ -10,12 +10,20 @@ type PasswordInput = {
10
10
  * @see https://w3c.github.io/aria/#textbox
11
11
  */
12
12
  declare const PasswordInput: import("svelte").Component<import("../../typedefs").TextInputProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & import("../../typedefs").InputEventHandlers & {
13
+ /**
14
+ * - Input value.
15
+ */
16
+ value?: string | undefined;
13
17
  /**
14
18
  * - Visibility icon slot content.
15
19
  */
16
20
  visibilityIcon?: import("svelte").Snippet<[]> | undefined;
17
21
  } & Record<string, any>, {}, "value">;
18
22
  type Props = {
23
+ /**
24
+ * - Input value.
25
+ */
26
+ value?: string | undefined;
19
27
  /**
20
28
  * - Visibility icon slot content.
21
29
  */
@@ -15,6 +15,7 @@
15
15
 
16
16
  /**
17
17
  * @typedef {object} Props
18
+ * @property {string} [value] - Input value.
18
19
  * @property {import('svelte').Snippet} [searchIcon] - Search icon slot content.
19
20
  * @property {import('svelte').Snippet} [closeIcon] - Close icon slot content.
20
21
  */
@@ -12,6 +12,10 @@ type SearchBar = {
12
12
  * @see https://w3c.github.io/aria/#search
13
13
  */
14
14
  declare const SearchBar: import("svelte").Component<import("../../typedefs").TextInputProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & import("../../typedefs").InputEventHandlers & {
15
+ /**
16
+ * - Input value.
17
+ */
18
+ value?: string | undefined;
15
19
  /**
16
20
  * - Search icon slot content.
17
21
  */
@@ -24,6 +28,10 @@ declare const SearchBar: import("svelte").Component<import("../../typedefs").Tex
24
28
  focus: () => void;
25
29
  }, "value">;
26
30
  type Props = {
31
+ /**
32
+ * - Input value.
33
+ */
34
+ value?: string | undefined;
27
35
  /**
28
36
  * - Search icon slot content.
29
37
  */
@@ -8,9 +8,9 @@
8
8
  <script>
9
9
  /**
10
10
  * @typedef {object} Props
11
- * @property {string | undefined} [value] - Input value.
11
+ * @property {string} [value] - Input value.
12
12
  * @property {boolean} [flex] - Make the text input container flexible.
13
- * @property {string | undefined} [name] - The `name` attribute on the `<textarea>` element.
13
+ * @property {string} [name] - The `name` attribute on the `<textarea>` element.
14
14
  * @property {boolean} [autoResize] - Whether to automatically resize the `<textarea>` based on
15
15
  * the content.
16
16
  * @property {string} [class] - The `class` attribute on the wrapper element.
@@ -71,7 +71,7 @@
71
71
  class:auto-resize={autoResize}
72
72
  ></textarea>
73
73
  {#if autoResize}
74
- <div class="clone" aria-hidden="true">{value ?? ''}</div>
74
+ <div class="clone" aria-hidden="true">{value}</div>
75
75
  {/if}
76
76
  </div>
77
77
 
@@ -138,7 +138,7 @@ textarea.auto-resize {
138
138
  resize: none;
139
139
  }
140
140
  textarea[aria-invalid=true] {
141
- border-color: var(--sui-error-foreground-color);
141
+ border-color: var(--sui-error-border-color);
142
142
  }
143
143
 
144
144
  .clone {
@@ -8,9 +8,14 @@
8
8
  import { generateElementId } from '@sveltia/utils/element';
9
9
  import { activateKeyShortcuts } from '../../services/events.svelte';
10
10
 
11
+ /**
12
+ * @typedef {object} Props
13
+ * @property {string} [value] - Input value.
14
+ */
15
+
11
16
  /**
12
17
  * @type {import('../../typedefs').TextInputProps & import('../../typedefs').CommonEventHandlers &
13
- * import('../../typedefs').InputEventHandlers & Record<string, any>}
18
+ * import('../../typedefs').InputEventHandlers & Props & Record<string, any>}
14
19
  */
15
20
  let {
16
21
  /* eslint-disable prefer-const */
@@ -125,7 +130,7 @@ input:disabled, input:read-only {
125
130
  background-color: var(--sui-disabled-background-color);
126
131
  }
127
132
  input[aria-invalid=true] {
128
- border-color: var(--sui-error-foreground-color);
133
+ border-color: var(--sui-error-border-color);
129
134
  }
130
135
  input ~ :global(button) {
131
136
  flex: none;
@@ -1,11 +1,22 @@
1
1
  export default TextInput;
2
2
  type TextInput = {
3
3
  $on?(type: string, callback: (e: any) => void): () => void;
4
- $set?(props: Partial<TextInputProps & KeyboardEventHandlers & MouseEventHandlers & FocusEventHandlers & DragEventHandlers & InputEventHandlers & Record<string, any>>): void;
4
+ $set?(props: Partial<TextInputProps & KeyboardEventHandlers & MouseEventHandlers & FocusEventHandlers & DragEventHandlers & InputEventHandlers & Props & Record<string, any>>): void;
5
5
  };
6
6
  /**
7
7
  * A generic, single-line text field. The equivalent of the HTML `<input type="text">` element.
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<import("../../typedefs").TextInputProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & import("../../typedefs").InputEventHandlers & Record<string, any>, {}, "value" | "element">;
11
+ declare const TextInput: import("svelte").Component<import("../../typedefs").TextInputProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & import("../../typedefs").InputEventHandlers & {
12
+ /**
13
+ * - Input value.
14
+ */
15
+ value?: string | undefined;
16
+ } & Record<string, any>, {}, "value" | "element">;
17
+ type Props = {
18
+ /**
19
+ * - Input value.
20
+ */
21
+ value?: string | undefined;
22
+ };
@@ -9,7 +9,7 @@
9
9
 
10
10
  /**
11
11
  * @typedef {object} Props
12
- * @property {string | number | undefined} [id] - The toast ID. If updated, the timer that hides
12
+ * @property {string | number} [id] - The toast ID. If updated, the timer that hides
13
13
  * the toast will be reset, meaning the same toast can be displayed for a longer period of time.
14
14
  * @property {boolean} [show] - Whether to show the toast.
15
15
  * @property {number} [duration] - Duration to automatically hide the toast. Use `0` to hide it
@@ -13,7 +13,7 @@
13
13
  * attribute.
14
14
  * @property {'horizontal' | 'vertical'} [orientation] - Orientation of the widget. An alias of
15
15
  * the `aria-orientation` attribute.
16
- * @property {'primary' | 'secondary' | undefined} [variant] - The style variant of the toolbar.
16
+ * @property {'primary' | 'secondary'} [variant] - The style variant of the toolbar.
17
17
  * @property {import('svelte').Snippet} [children] - Primary slot content.
18
18
  */
19
19
 
@@ -36,7 +36,7 @@
36
36
  <div
37
37
  {...restProps}
38
38
  role="toolbar"
39
- class="sui toolbar {orientation} {variant ?? ''} {className}"
39
+ class="sui toolbar {orientation} {variant} {className}"
40
40
  {hidden}
41
41
  aria-hidden={hidden}
42
42
  aria-disabled={disabled}
@@ -9,7 +9,7 @@
9
9
 
10
10
  /**
11
11
  * @typedef {object} Props
12
- * @property {'horizontal' | 'vertical' | undefined} [orientation] - Orientation of the app
12
+ * @property {'horizontal' | 'vertical'} [orientation] - Orientation of the app
13
13
  * shell’s children..
14
14
  * @property {import('svelte').Snippet} [children] - Primary slot content.
15
15
  */
@@ -82,7 +82,7 @@
82
82
  <div
83
83
  {...restProps}
84
84
  role="none"
85
- class="sui app-shell {orientation ?? ''}"
85
+ class="sui app-shell {orientation}"
86
86
  ondragover={(event) => event.preventDefault()}
87
87
  ondrop={(event) => event.preventDefault()}
88
88
  oncontextmenu={(event) => {
@@ -339,8 +339,8 @@
339
339
  --sui-alert-foreground-color-lightness: 75%;
340
340
  --sui-alert-background-color-saturation: 40%;
341
341
  --sui-alert-background-color-lightness: 10%;
342
- --sui-alert-border-color-saturation: 38%;
343
- --sui-alert-border-color-lightness: 18%;
342
+ --sui-alert-border-color-saturation: 48%;
343
+ --sui-alert-border-color-lightness: 38%;
344
344
  }
345
345
  @media (prefers-color-scheme: light) {
346
346
  :global(:root:not([data-theme])),
@@ -410,8 +410,8 @@
410
410
  --sui-alert-foreground-color-lightness: 75%;
411
411
  --sui-alert-background-color-saturation: 40%;
412
412
  --sui-alert-background-color-lightness: 10%;
413
- --sui-alert-border-color-saturation: 38%;
414
- --sui-alert-border-color-lightness: 18%;
413
+ --sui-alert-border-color-saturation: 48%;
414
+ --sui-alert-border-color-lightness: 38%;
415
415
  }
416
416
  }
417
417