@sveltia/ui 0.67.0 → 0.67.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/alert/infobar.svelte +3 -0
- package/dist/components/alert/infobar.svelte.d.ts +8 -0
- package/dist/components/text-editor/shiki/generated.d.ts +1 -1
- package/dist/components/text-editor/shiki/generated.js +1 -1
- package/dist/components/text-editor/toolbar/insert-link-button.svelte +4 -0
- package/dist/components/util/modal.svelte +32 -9
- package/dist/typedefs.d.ts +7 -0
- package/dist/typedefs.js +4 -0
- package/package.json +6 -6
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* @property {'off' | 'polite' | 'assertive'} [ariaLive] ARIA live region politeness.
|
|
16
16
|
* @property {Snippet} [children] Primary slot content.
|
|
17
17
|
* @property {Snippet} [icon] Icon slot content.
|
|
18
|
+
* @property {() => void} [onDismiss] Callback invoked when the close button is clicked.
|
|
18
19
|
*/
|
|
19
20
|
|
|
20
21
|
/** @type {Props} */
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
ariaLive = 'polite',
|
|
27
28
|
children = undefined,
|
|
28
29
|
icon = undefined,
|
|
30
|
+
onDismiss,
|
|
29
31
|
/* eslint-enable prefer-const */
|
|
30
32
|
} = $props();
|
|
31
33
|
</script>
|
|
@@ -49,6 +51,7 @@
|
|
|
49
51
|
aria-label={_('_sui.dismiss')}
|
|
50
52
|
onclick={() => {
|
|
51
53
|
show = false;
|
|
54
|
+
onDismiss?.();
|
|
52
55
|
}}
|
|
53
56
|
>
|
|
54
57
|
<Icon name="close" />
|
|
@@ -28,6 +28,10 @@ declare const Infobar: import("svelte").Component<{
|
|
|
28
28
|
* Icon slot content.
|
|
29
29
|
*/
|
|
30
30
|
icon?: Snippet<[]> | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Callback invoked when the close button is clicked.
|
|
33
|
+
*/
|
|
34
|
+
onDismiss?: (() => void) | undefined;
|
|
31
35
|
}, {}, "show">;
|
|
32
36
|
type Props = {
|
|
33
37
|
/**
|
|
@@ -54,5 +58,9 @@ type Props = {
|
|
|
54
58
|
* Icon slot content.
|
|
55
59
|
*/
|
|
56
60
|
icon?: Snippet<[]> | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Callback invoked when the close button is clicked.
|
|
63
|
+
*/
|
|
64
|
+
onDismiss?: (() => void) | undefined;
|
|
57
65
|
};
|
|
58
66
|
import type { Snippet } from 'svelte';
|
|
@@ -7,7 +7,7 @@ export const SHIKI_VERSION: "4.4.3";
|
|
|
7
7
|
/**
|
|
8
8
|
* Version of this package, used to resolve the prebuilt Shiki engine chunk from a CDN.
|
|
9
9
|
*/
|
|
10
|
-
export const UI_VERSION: "0.67.
|
|
10
|
+
export const UI_VERSION: "0.67.2";
|
|
11
11
|
/**
|
|
12
12
|
* Available syntax highlighting languages, sorted by display name.
|
|
13
13
|
* @type {{ id: string, name: string, aliases?: string[] }[]}
|
|
@@ -10,7 +10,7 @@ export const SHIKI_VERSION = "4.4.3";
|
|
|
10
10
|
/**
|
|
11
11
|
* Version of this package, used to resolve the prebuilt Shiki engine chunk from a CDN.
|
|
12
12
|
*/
|
|
13
|
-
export const UI_VERSION = "0.67.
|
|
13
|
+
export const UI_VERSION = "0.67.2";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Available syntax highlighting languages, sorted by display name.
|
|
@@ -148,6 +148,9 @@
|
|
|
148
148
|
|
|
149
149
|
await focusEditor(editorStore.editor);
|
|
150
150
|
editorStore.editor.dispatchCommand(TOGGLE_LINK_COMMAND, anchorURL);
|
|
151
|
+
} else if (editorStore.editor) {
|
|
152
|
+
// The dialog leaves the focus alone (see `restoreFocus` below), so bring it back here
|
|
153
|
+
await focusEditor(editorStore.editor);
|
|
151
154
|
}
|
|
152
155
|
|
|
153
156
|
anchorURL = '';
|
|
@@ -202,6 +205,7 @@
|
|
|
202
205
|
bind:value={anchorURL}
|
|
203
206
|
okDisabled={!anchorURL}
|
|
204
207
|
okLabel={dialogMode === 'create' ? _('_sui.insert') : _('_sui.update')}
|
|
208
|
+
restoreFocus={false}
|
|
205
209
|
onClose={(event) => {
|
|
206
210
|
onDialogClose(event);
|
|
207
211
|
}}
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
lightDismiss = false,
|
|
41
41
|
escapeDismiss = true,
|
|
42
42
|
keepContent = false,
|
|
43
|
+
restoreFocus = true,
|
|
43
44
|
children,
|
|
44
45
|
extraContent,
|
|
45
46
|
onOpening,
|
|
@@ -152,26 +153,44 @@
|
|
|
152
153
|
*/
|
|
153
154
|
let lastActiveElement;
|
|
154
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Timer used to defer the focus restoration in {@link moveFocusBack}.
|
|
158
|
+
* @type {number | undefined}
|
|
159
|
+
*/
|
|
160
|
+
let restoreFocusTimer;
|
|
161
|
+
|
|
155
162
|
/**
|
|
156
163
|
* Move the focus back to the element that had it before the modal was opened. This is done
|
|
157
164
|
* manually rather than relying on the browser’s own focus restoration, because the modal is
|
|
158
165
|
* closed while `<body>` is `inert`, which prevents the focus from being restored.
|
|
159
166
|
*/
|
|
160
|
-
const
|
|
161
|
-
const { activeElement } = document;
|
|
167
|
+
const moveFocusBack = () => {
|
|
162
168
|
const element = lastActiveElement;
|
|
163
169
|
|
|
164
170
|
lastActiveElement = undefined;
|
|
165
171
|
|
|
166
|
-
if (!element
|
|
172
|
+
if (!restoreFocus || !element) {
|
|
167
173
|
return;
|
|
168
174
|
}
|
|
169
175
|
|
|
170
|
-
//
|
|
171
|
-
//
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
176
|
+
// Wait for the current task to finish before moving the focus. The modal is typically closed
|
|
177
|
+
// from within an event handler, and the event that triggered it is still being processed:
|
|
178
|
+
// Firefox dispatches `keypress` to whatever holds the focus at that point, so restoring it
|
|
179
|
+
// synchronously would let the Enter key that submitted the modal activate the button that
|
|
180
|
+
// opened it, immediately reopening the modal.
|
|
181
|
+
restoreFocusTimer = window.setTimeout(() => {
|
|
182
|
+
const { activeElement } = document;
|
|
183
|
+
|
|
184
|
+
if (!element.isConnected) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Only take the focus back if it’s still inside the modal, or nowhere because the modal took
|
|
189
|
+
// it down with itself. If it has already moved on, pulling it back would undo what happened.
|
|
190
|
+
if (!activeElement || activeElement === document.body || dialog?.contains(activeElement)) {
|
|
191
|
+
element.focus();
|
|
192
|
+
}
|
|
193
|
+
});
|
|
175
194
|
};
|
|
176
195
|
|
|
177
196
|
/**
|
|
@@ -235,6 +254,9 @@
|
|
|
235
254
|
const gen = generation;
|
|
236
255
|
const { activeElement } = document;
|
|
237
256
|
|
|
257
|
+
// Cancel a pending restoration from a previous close, which would otherwise pull the focus out
|
|
258
|
+
// of the modal that’s being opened right now
|
|
259
|
+
window.clearTimeout(restoreFocusTimer);
|
|
238
260
|
lastActiveElement = activeElement instanceof HTMLElement ? activeElement : undefined;
|
|
239
261
|
|
|
240
262
|
onOpening?.(new CustomEvent('Opening'));
|
|
@@ -291,7 +313,7 @@
|
|
|
291
313
|
document.body.inert = false;
|
|
292
314
|
}
|
|
293
315
|
|
|
294
|
-
|
|
316
|
+
moveFocusBack();
|
|
295
317
|
setActiveClass = false;
|
|
296
318
|
setOpenClass = false;
|
|
297
319
|
|
|
@@ -340,6 +362,7 @@
|
|
|
340
362
|
|
|
341
363
|
// onUnmount
|
|
342
364
|
return () => {
|
|
365
|
+
window.clearTimeout(restoreFocusTimer);
|
|
343
366
|
dialog?.close();
|
|
344
367
|
unmount(placeholder);
|
|
345
368
|
};
|
package/dist/typedefs.d.ts
CHANGED
|
@@ -153,6 +153,13 @@ export type ModalProps = {
|
|
|
153
153
|
* open, and unmounted once the closing transition is complete.
|
|
154
154
|
*/
|
|
155
155
|
keepContent?: boolean | undefined;
|
|
156
|
+
/**
|
|
157
|
+
* Whether to move the focus back to the element that had it
|
|
158
|
+
* before the modal was opened. Default: `true`. Disable this if the consumer takes care of the
|
|
159
|
+
* focus itself once the modal is closed, such as when the modal is opened from a rich text editor,
|
|
160
|
+
* where refocusing the element would reset the caret and discard the user’s selection.
|
|
161
|
+
*/
|
|
162
|
+
restoreFocus?: boolean | undefined;
|
|
156
163
|
/**
|
|
157
164
|
* A reference to the `<dialog>` element.
|
|
158
165
|
*/
|
package/dist/typedefs.js
CHANGED
|
@@ -57,6 +57,10 @@
|
|
|
57
57
|
* @property {boolean} [keepContent] Whether to keep the `<dialog>` element and its content in the
|
|
58
58
|
* DOM tree while the modal is not displayed. By default, these are mounted only while the modal is
|
|
59
59
|
* open, and unmounted once the closing transition is complete.
|
|
60
|
+
* @property {boolean} [restoreFocus] Whether to move the focus back to the element that had it
|
|
61
|
+
* before the modal was opened. Default: `true`. Disable this if the consumer takes care of the
|
|
62
|
+
* focus itself once the modal is closed, such as when the modal is opened from a rich text editor,
|
|
63
|
+
* where refocusing the element would reset the caret and discard the user’s selection.
|
|
60
64
|
* @property {HTMLDialogElement} [dialog] A reference to the `<dialog>` element.
|
|
61
65
|
* @property {Snippet} [children] Primary slot content.
|
|
62
66
|
* @property {Snippet} [extraContent] Extra slot content.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltia/ui",
|
|
3
|
-
"version": "0.67.
|
|
3
|
+
"version": "0.67.2",
|
|
4
4
|
"description": "A collection of Svelte components and utilities for building user interfaces.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -66,23 +66,23 @@
|
|
|
66
66
|
"eslint-plugin-package-json": "^1.7.1",
|
|
67
67
|
"eslint-plugin-svelte": "^3.23.0",
|
|
68
68
|
"globals": "^17.11.0",
|
|
69
|
-
"happy-dom": "^20.11.
|
|
69
|
+
"happy-dom": "^20.11.6",
|
|
70
70
|
"oxlint": "^1.79.0",
|
|
71
71
|
"postcss": "^8.5.26",
|
|
72
72
|
"postcss-html": "^2.0.0",
|
|
73
73
|
"prettier": "^3.9.6",
|
|
74
74
|
"prettier-plugin-svelte": "^4.1.1",
|
|
75
|
-
"rolldown": "^1.2.
|
|
76
|
-
"sass": "^1.
|
|
75
|
+
"rolldown": "^1.2.5",
|
|
76
|
+
"sass": "^1.103.1",
|
|
77
77
|
"shiki": "^4.4.3",
|
|
78
78
|
"stylelint": "^17.14.1",
|
|
79
79
|
"stylelint-config-recommended-scss": "^17.0.1",
|
|
80
80
|
"stylelint-scss": "^7.2.0",
|
|
81
|
-
"svelte": "^5.56.
|
|
81
|
+
"svelte": "^5.56.10",
|
|
82
82
|
"svelte-check": "^4.7.6",
|
|
83
83
|
"svelte-preprocess": "^6.0.5",
|
|
84
84
|
"tslib": "^2.8.1",
|
|
85
|
-
"vite": "^8.2.
|
|
85
|
+
"vite": "^8.2.2",
|
|
86
86
|
"vitest": "^4.1.11"
|
|
87
87
|
},
|
|
88
88
|
"peerDependencies": {
|