@sveltia/ui 0.55.1 → 0.57.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.
- package/dist/components/listbox/option.svelte +107 -33
- package/dist/components/select/combobox.svelte +126 -50
- package/dist/components/text-editor/constants.d.ts +0 -4
- package/dist/components/text-editor/constants.js +0 -5
- package/dist/components/text-editor/toolbar/{insert-image-button.svelte → insert-item-button.svelte} +12 -5
- package/dist/components/text-editor/toolbar/{insert-image-button.svelte.d.ts → insert-item-button.svelte.d.ts} +5 -5
- package/dist/components/text-editor/toolbar/insert-menu-button.svelte +6 -2
- package/dist/components/text-editor/toolbar/text-editor-toolbar.svelte +12 -16
- package/dist/components/util/modal.svelte +210 -66
- package/dist/components/util/popup.svelte +28 -20
- package/dist/locales/nl.yaml +113 -0
- package/dist/locales/pl.yaml +113 -0
- package/dist/services/group.svelte.d.ts +57 -0
- package/dist/services/group.svelte.js +294 -7
- package/dist/services/popup.svelte.d.ts +37 -5
- package/dist/services/popup.svelte.js +132 -19
- package/dist/services/select.svelte.d.ts +49 -0
- package/dist/services/select.svelte.js +99 -1
- package/dist/typedefs.d.ts +38 -2
- package/dist/typedefs.js +17 -2
- package/package.json +7 -7
|
@@ -31,8 +31,18 @@ class Popup {
|
|
|
31
31
|
} else if (this.anchorElement.getAttribute('aria-expanded') === 'true') {
|
|
32
32
|
// Wait for the popup to close before focusing the anchor, otherwise the focus will be lost
|
|
33
33
|
window.requestAnimationFrame(() => {
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
const { activeElement } = document;
|
|
35
|
+
|
|
36
|
+
// Only take focus back if it’s still inside the popup, or nowhere because the popup took it
|
|
37
|
+
// down with itself. If it has already moved on — the user tabbed out of the menu, say —
|
|
38
|
+
// pulling it back would undo what they just did.
|
|
39
|
+
if (
|
|
40
|
+
!activeElement ||
|
|
41
|
+
activeElement === document.body ||
|
|
42
|
+
this.popupElement?.contains(activeElement)
|
|
43
|
+
) {
|
|
44
|
+
this.anchorElement.focus();
|
|
45
|
+
}
|
|
36
46
|
});
|
|
37
47
|
}
|
|
38
48
|
|
|
@@ -59,7 +69,18 @@ class Popup {
|
|
|
59
69
|
return;
|
|
60
70
|
}
|
|
61
71
|
|
|
62
|
-
|
|
72
|
+
// Use the tracked content element rather than searching the popup element, which for a nested
|
|
73
|
+
// popup is the shared parent `<dialog>` and would yield the parent’s content
|
|
74
|
+
const content = /** @type {HTMLElement | null} */ (
|
|
75
|
+
this.contentElement ?? this.popupElement?.querySelector('.content') ?? null
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// The content is not in the DOM tree yet; `checkPosition()` will be called again once the
|
|
79
|
+
// popup element is attached
|
|
80
|
+
if (!content) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
63
84
|
const { scrollHeight: contentHeight, scrollWidth: contentWidth } = content;
|
|
64
85
|
const topMargin = intersectionRect.top - 8;
|
|
65
86
|
const bottomMargin = rootBounds.height - intersectionRect.bottom - 8;
|
|
@@ -155,22 +176,44 @@ class Popup {
|
|
|
155
176
|
});
|
|
156
177
|
|
|
157
178
|
/**
|
|
158
|
-
*
|
|
179
|
+
* A reference to the `<dialog>` element used for the popup, which also serves as the backdrop.
|
|
180
|
+
* This is `undefined` while the element is not in the DOM tree, which is the case for a closed
|
|
181
|
+
* popup that doesn’t keep its content.
|
|
182
|
+
* @type {HTMLDialogElement | undefined}
|
|
183
|
+
*/
|
|
184
|
+
popupElement = undefined;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* A reference to the element holding the popup content. Unlike {@link popupElement}, which a
|
|
188
|
+
* nested popup shares with its parent, this element belongs to this popup alone, so it’s the one
|
|
189
|
+
* that carries the {@link id} and that the anchor’s `aria-controls` points at.
|
|
190
|
+
* @type {HTMLElement | undefined}
|
|
191
|
+
*/
|
|
192
|
+
contentElement = undefined;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Function that removes the event listeners added to the current {@link popupElement}.
|
|
196
|
+
* @type {(() => void) | undefined}
|
|
197
|
+
*/
|
|
198
|
+
#removeEventListeners = undefined;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Initialize a new `Popup` instance. Note that the `popupElement` is optional, because the
|
|
202
|
+
* element is typically mounted only while the popup is open. Use {@link attachPopupElement} to
|
|
203
|
+
* provide it later.
|
|
159
204
|
* @param {HTMLButtonElement} anchorElement `<button>` element that triggers the popup.
|
|
160
|
-
* @param {HTMLDialogElement} popupElement `<dialog>` element to be used for the
|
|
205
|
+
* @param {HTMLDialogElement | undefined} popupElement `<dialog>` element to be used for the
|
|
206
|
+
* popup, if it’s already in the DOM tree.
|
|
161
207
|
* @param {PopupPosition} position Where to show the popup content.
|
|
162
208
|
* @param {HTMLElement} [positionBaseElement] The base element of the `position`. If omitted, this
|
|
163
209
|
* will be the `anchorElement`.
|
|
164
210
|
*/
|
|
165
211
|
constructor(anchorElement, popupElement, position, positionBaseElement) {
|
|
166
212
|
this.anchorElement = anchorElement;
|
|
167
|
-
this.popupElement = popupElement; // = backdrop
|
|
168
213
|
this.position = position;
|
|
169
214
|
this.positionBaseElement = positionBaseElement ?? anchorElement;
|
|
170
215
|
this.id = generateElementId('popup');
|
|
171
216
|
|
|
172
|
-
this.anchorElement.setAttribute('aria-controls', this.id);
|
|
173
|
-
this.popupElement.setAttribute('id', this.id);
|
|
174
217
|
this.anchorElement.setAttribute('aria-expanded', 'false');
|
|
175
218
|
|
|
176
219
|
on(anchorElement, 'click', () => {
|
|
@@ -203,8 +246,45 @@ class Popup {
|
|
|
203
246
|
});
|
|
204
247
|
this.intersectionObserver.observe(this.anchorElement);
|
|
205
248
|
|
|
249
|
+
// Update the popup width when the base element is resized
|
|
250
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
251
|
+
cancelAnimationFrame(this._rafId);
|
|
252
|
+
this._rafId = requestAnimationFrame(() => this.checkPosition());
|
|
253
|
+
});
|
|
254
|
+
this.resizeObserver.observe(this.positionBaseElement);
|
|
255
|
+
|
|
256
|
+
if (popupElement) {
|
|
257
|
+
this.attachPopupElement(popupElement);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Attach the `<dialog>` element used for the popup. This is called every time the element is
|
|
263
|
+
* mounted, which happens on each open.
|
|
264
|
+
* @param {HTMLDialogElement} popupElement `<dialog>` element to be used for the popup. A nested
|
|
265
|
+
* popup shares this with its parent, so it must not be labelled as belonging to this popup.
|
|
266
|
+
* @param {HTMLElement} [contentElement] Element holding this popup’s content. When omitted, the
|
|
267
|
+
* `popupElement` is assumed to hold the content on its own.
|
|
268
|
+
*/
|
|
269
|
+
attachPopupElement(popupElement, contentElement) {
|
|
270
|
+
if (this.popupElement === popupElement && this.contentElement === contentElement) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
this.detachPopupElement();
|
|
275
|
+
this.popupElement = popupElement;
|
|
276
|
+
this.contentElement = contentElement;
|
|
277
|
+
|
|
278
|
+
// Identify the popup by the element that actually holds its content. Labelling the `<dialog>`
|
|
279
|
+
// would be wrong for a nested popup, which shares its parent’s: it would overwrite the parent’s
|
|
280
|
+
// own `id` and leave the anchor pointing at the parent instead of the submenu.
|
|
281
|
+
const identifiedElement = contentElement ?? popupElement;
|
|
282
|
+
|
|
283
|
+
identifiedElement.id = this.id;
|
|
284
|
+
this.anchorElement.setAttribute('aria-controls', this.id);
|
|
285
|
+
|
|
206
286
|
// Close the popup when the backdrop, a menu item or an option is clicked
|
|
207
|
-
on(
|
|
287
|
+
const removeClickListener = on(popupElement, 'click', (event) => {
|
|
208
288
|
event.stopPropagation();
|
|
209
289
|
|
|
210
290
|
// eslint-disable-next-line prefer-destructuring
|
|
@@ -218,7 +298,7 @@ class Popup {
|
|
|
218
298
|
}
|
|
219
299
|
});
|
|
220
300
|
|
|
221
|
-
on(
|
|
301
|
+
const removeKeyDownListener = on(popupElement, 'keydown', (event) => {
|
|
222
302
|
const { key, ctrlKey, metaKey, shiftKey, altKey } = event;
|
|
223
303
|
const hasModifier = shiftKey || altKey || ctrlKey || metaKey;
|
|
224
304
|
|
|
@@ -229,12 +309,32 @@ class Popup {
|
|
|
229
309
|
}
|
|
230
310
|
});
|
|
231
311
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
312
|
+
/**
|
|
313
|
+
* Remove the listeners added above.
|
|
314
|
+
*/
|
|
315
|
+
this.#removeEventListeners = () => {
|
|
316
|
+
removeClickListener();
|
|
317
|
+
removeKeyDownListener();
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Detach the `<dialog>` element, typically because it’s being unmounted. The `aria-controls`
|
|
323
|
+
* attribute on the anchor is left to the {@link open} setter, which removes it once the closing
|
|
324
|
+
* animation is complete.
|
|
325
|
+
*/
|
|
326
|
+
detachPopupElement() {
|
|
327
|
+
this.#removeEventListeners?.();
|
|
328
|
+
this.#removeEventListeners = undefined;
|
|
329
|
+
|
|
330
|
+
// The content is leaving the DOM tree, so the anchor must stop referencing it. Only clear a
|
|
331
|
+
// reference this popup owns; the consumer may have pointed the anchor somewhere else.
|
|
332
|
+
if (this.anchorElement.getAttribute('aria-controls') === this.id) {
|
|
333
|
+
this.anchorElement.removeAttribute('aria-controls');
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
this.popupElement = undefined;
|
|
337
|
+
this.contentElement = undefined;
|
|
238
338
|
}
|
|
239
339
|
|
|
240
340
|
/**
|
|
@@ -254,9 +354,14 @@ class Popup {
|
|
|
254
354
|
}
|
|
255
355
|
|
|
256
356
|
/**
|
|
257
|
-
* Check the position of the anchor element.
|
|
357
|
+
* Check the position of the anchor element. This is a no-op while the popup element is not in the
|
|
358
|
+
* DOM tree; the caller is expected to call this again once the element is attached.
|
|
258
359
|
*/
|
|
259
360
|
checkPosition() {
|
|
361
|
+
if (!this.popupElement) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
260
365
|
this.observer.unobserve(this.positionBaseElement);
|
|
261
366
|
this.observer.observe(this.positionBaseElement);
|
|
262
367
|
}
|
|
@@ -265,16 +370,24 @@ class Popup {
|
|
|
265
370
|
* Hide the popup immediately (when the anchor is being hidden).
|
|
266
371
|
*/
|
|
267
372
|
async hideImmediately() {
|
|
268
|
-
this.popupElement
|
|
373
|
+
if (this.popupElement) {
|
|
374
|
+
this.popupElement.hidden = true;
|
|
375
|
+
}
|
|
376
|
+
|
|
269
377
|
this.open = false;
|
|
270
378
|
await sleep(50);
|
|
271
|
-
|
|
379
|
+
|
|
380
|
+
// The element may have been unmounted in the meantime
|
|
381
|
+
if (this.popupElement) {
|
|
382
|
+
this.popupElement.hidden = false;
|
|
383
|
+
}
|
|
272
384
|
}
|
|
273
385
|
|
|
274
386
|
/**
|
|
275
387
|
* Dispose of the popup, disconnecting observers and canceling pending work.
|
|
276
388
|
*/
|
|
277
389
|
destroy() {
|
|
390
|
+
this.detachPopupElement();
|
|
278
391
|
this.intersectionObserver?.disconnect();
|
|
279
392
|
this.resizeObserver?.disconnect();
|
|
280
393
|
this.observer?.disconnect();
|
|
@@ -1,2 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reactive registry of the `<Option>`s declared within a `<Combobox>`.
|
|
3
|
+
*
|
|
4
|
+
* The options only render their DOM while the dropdown is expanded, so a collapsed combobox can’t
|
|
5
|
+
* look them up with `querySelector`. Each `<Option>` instead registers a live view of its own props
|
|
6
|
+
* here, which lets the combobox resolve the current label and the initially selected value without
|
|
7
|
+
* keeping the option elements in the DOM tree.
|
|
8
|
+
*
|
|
9
|
+
* The order of the registered options is not significant. Svelte still renders the options itself,
|
|
10
|
+
* in declaration order, so nothing here has to reproduce that order.
|
|
11
|
+
*/
|
|
12
|
+
export class OptionRegistry {
|
|
13
|
+
/**
|
|
14
|
+
* Whether the dropdown is expanded, meaning the options should render their DOM.
|
|
15
|
+
* @type {boolean}
|
|
16
|
+
*/
|
|
17
|
+
expanded: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Number of registered options.
|
|
20
|
+
* @returns {number} Count.
|
|
21
|
+
*/
|
|
22
|
+
get count(): number;
|
|
23
|
+
/**
|
|
24
|
+
* The option that is currently marked as selected, if any.
|
|
25
|
+
* @returns {OptionEntry | undefined} Matching option.
|
|
26
|
+
*/
|
|
27
|
+
get selectedEntry(): OptionEntry | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Register an option.
|
|
30
|
+
* @param {OptionEntry} entry Live view of the option’s props.
|
|
31
|
+
* @returns {() => void} Function to unregister the option.
|
|
32
|
+
*/
|
|
33
|
+
register(entry: OptionEntry): () => void;
|
|
34
|
+
/**
|
|
35
|
+
* Find the option with the given value.
|
|
36
|
+
* @param {any} value Value to look for.
|
|
37
|
+
* @returns {OptionEntry | undefined} Matching option.
|
|
38
|
+
*/
|
|
39
|
+
find(value: any): OptionEntry | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Mark the option with the given value as the only selected one.
|
|
42
|
+
* @param {any} value Value to select.
|
|
43
|
+
*/
|
|
44
|
+
selectOnly(value: any): void;
|
|
45
|
+
#private;
|
|
46
|
+
}
|
|
47
|
+
export function createOptionRegistry(): OptionRegistry;
|
|
48
|
+
export function getOptionRegistry(): OptionRegistry | undefined;
|
|
1
49
|
export function getSelectedItemDetail(target: HTMLElement): SelectedItemDetail;
|
|
50
|
+
import type { OptionEntry } from '../typedefs';
|
|
2
51
|
import type { SelectedItemDetail } from '../typedefs';
|
|
@@ -1,6 +1,104 @@
|
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @import { OptionEntry, SelectedItemDetail } from '../typedefs';
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Context key for {@link OptionRegistry}.
|
|
9
|
+
*/
|
|
10
|
+
const CONTEXT_KEY = Symbol('sui-option-registry');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Reactive registry of the `<Option>`s declared within a `<Combobox>`.
|
|
14
|
+
*
|
|
15
|
+
* The options only render their DOM while the dropdown is expanded, so a collapsed combobox can’t
|
|
16
|
+
* look them up with `querySelector`. Each `<Option>` instead registers a live view of its own props
|
|
17
|
+
* here, which lets the combobox resolve the current label and the initially selected value without
|
|
18
|
+
* keeping the option elements in the DOM tree.
|
|
19
|
+
*
|
|
20
|
+
* The order of the registered options is not significant. Svelte still renders the options itself,
|
|
21
|
+
* in declaration order, so nothing here has to reproduce that order.
|
|
22
|
+
*/
|
|
23
|
+
export class OptionRegistry {
|
|
24
|
+
/**
|
|
25
|
+
* Whether the dropdown is expanded, meaning the options should render their DOM.
|
|
26
|
+
* @type {boolean}
|
|
27
|
+
*/
|
|
28
|
+
expanded = $state(false);
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Registered options. This is a raw state so that the entries, which expose their properties as
|
|
32
|
+
* getters onto the `<Option>`’s props, are not wrapped in a reactive proxy.
|
|
33
|
+
* @type {OptionEntry[]}
|
|
34
|
+
*/
|
|
35
|
+
#entries = $state.raw([]);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Number of registered options.
|
|
39
|
+
* @returns {number} Count.
|
|
40
|
+
*/
|
|
41
|
+
get count() {
|
|
42
|
+
return this.#entries.length;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The option that is currently marked as selected, if any.
|
|
47
|
+
* @returns {OptionEntry | undefined} Matching option.
|
|
48
|
+
*/
|
|
49
|
+
get selectedEntry() {
|
|
50
|
+
return this.#entries.find((entry) => entry.selected);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Register an option.
|
|
55
|
+
* @param {OptionEntry} entry Live view of the option’s props.
|
|
56
|
+
* @returns {() => void} Function to unregister the option.
|
|
57
|
+
*/
|
|
58
|
+
register(entry) {
|
|
59
|
+
this.#entries = [...this.#entries, entry];
|
|
60
|
+
|
|
61
|
+
return () => {
|
|
62
|
+
this.#entries = this.#entries.filter((item) => item !== entry);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Find the option with the given value.
|
|
68
|
+
* @param {any} value Value to look for.
|
|
69
|
+
* @returns {OptionEntry | undefined} Matching option.
|
|
70
|
+
*/
|
|
71
|
+
find(value) {
|
|
72
|
+
return this.#entries.find((entry) => entry.value === value);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Mark the option with the given value as the only selected one.
|
|
77
|
+
* @param {any} value Value to select.
|
|
78
|
+
*/
|
|
79
|
+
selectOnly(value) {
|
|
80
|
+
this.#entries.forEach((entry) => {
|
|
81
|
+
const selected = entry.value === value;
|
|
82
|
+
|
|
83
|
+
if (entry.selected !== selected) {
|
|
84
|
+
entry.selected = selected;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Create an option registry and provide it to the descendant `<Option>`s.
|
|
92
|
+
* @returns {OptionRegistry} New registry.
|
|
93
|
+
*/
|
|
94
|
+
export const createOptionRegistry = () => setContext(CONTEXT_KEY, new OptionRegistry());
|
|
95
|
+
|
|
1
96
|
/**
|
|
2
|
-
*
|
|
97
|
+
* Get the option registry provided by an ancestor `<Combobox>`.
|
|
98
|
+
* @returns {OptionRegistry | undefined} Registry, or `undefined` when the `<Option>` is used
|
|
99
|
+
* standalone within a `<Listbox>`.
|
|
3
100
|
*/
|
|
101
|
+
export const getOptionRegistry = () => getContext(CONTEXT_KEY);
|
|
4
102
|
|
|
5
103
|
/**
|
|
6
104
|
* Get the detail of the selected element.
|
package/dist/typedefs.d.ts
CHANGED
|
@@ -148,8 +148,9 @@ export type ModalProps = {
|
|
|
148
148
|
*/
|
|
149
149
|
escapeDismiss?: boolean | undefined;
|
|
150
150
|
/**
|
|
151
|
-
* Whether to keep the
|
|
152
|
-
* not displayed.
|
|
151
|
+
* Whether to keep the `<dialog>` element and its content in the
|
|
152
|
+
* DOM tree while the modal is not displayed. By default, these are mounted only while the modal is
|
|
153
|
+
* open, and unmounted once the closing transition is complete.
|
|
153
154
|
*/
|
|
154
155
|
keepContent?: boolean | undefined;
|
|
155
156
|
/**
|
|
@@ -351,6 +352,36 @@ export type MenuItemProps = {
|
|
|
351
352
|
*/
|
|
352
353
|
onSelect?: ((event: CustomEvent) => void) | undefined;
|
|
353
354
|
};
|
|
355
|
+
/**
|
|
356
|
+
* A live view of an `<Option>`’s props, registered with the ancestor `<Combobox>` so that it can
|
|
357
|
+
* resolve labels and the initial value while the options are not rendered.
|
|
358
|
+
*/
|
|
359
|
+
export type OptionEntry = {
|
|
360
|
+
/**
|
|
361
|
+
* The option’s value.
|
|
362
|
+
*/
|
|
363
|
+
value: any;
|
|
364
|
+
/**
|
|
365
|
+
* The option’s text label.
|
|
366
|
+
*/
|
|
367
|
+
label: string;
|
|
368
|
+
/**
|
|
369
|
+
* The option’s name.
|
|
370
|
+
*/
|
|
371
|
+
name?: string | undefined;
|
|
372
|
+
/**
|
|
373
|
+
* Data type of the `value`.
|
|
374
|
+
*/
|
|
375
|
+
type: string;
|
|
376
|
+
/**
|
|
377
|
+
* Whether the option is selected. Writable.
|
|
378
|
+
*/
|
|
379
|
+
selected: boolean;
|
|
380
|
+
/**
|
|
381
|
+
* Whether the option is disabled.
|
|
382
|
+
*/
|
|
383
|
+
disabled: boolean;
|
|
384
|
+
};
|
|
354
385
|
export type ComboboxProps = {
|
|
355
386
|
/**
|
|
356
387
|
* The `class` attribute on the wrapper element.
|
|
@@ -683,6 +714,11 @@ export type TextEditorComponent = {
|
|
|
683
714
|
* Material Symbols icon name.
|
|
684
715
|
*/
|
|
685
716
|
icon?: string | undefined;
|
|
717
|
+
/**
|
|
718
|
+
* Trigger UI of the component. Default: `menuitem`. A
|
|
719
|
+
* menu item is placed under the Insert menu, while a button is placed directly on the toolbar.
|
|
720
|
+
*/
|
|
721
|
+
trigger?: "button" | "menuitem" | undefined;
|
|
686
722
|
/**
|
|
687
723
|
* Lexical node class implementation.
|
|
688
724
|
*/
|
package/dist/typedefs.js
CHANGED
|
@@ -54,8 +54,9 @@
|
|
|
54
54
|
* @property {boolean} [lightDismiss] Whether to close the modal when the backdrop (outside of the
|
|
55
55
|
* modal) is clicked.
|
|
56
56
|
* @property {boolean} [escapeDismiss] Whether to close the modal when the Escape key is pressed.
|
|
57
|
-
* @property {boolean} [keepContent] Whether to keep the
|
|
58
|
-
* not displayed.
|
|
57
|
+
* @property {boolean} [keepContent] Whether to keep the `<dialog>` element and its content in the
|
|
58
|
+
* DOM tree while the modal is not displayed. By default, these are mounted only while the modal is
|
|
59
|
+
* open, and unmounted once the closing transition is complete.
|
|
59
60
|
* @property {HTMLDialogElement} [dialog] A reference to the `<dialog>` element.
|
|
60
61
|
* @property {Snippet} [children] Primary slot content.
|
|
61
62
|
* @property {Snippet} [extraContent] Extra slot content.
|
|
@@ -122,6 +123,18 @@
|
|
|
122
123
|
* @property {(event: CustomEvent) => void} [onSelect] Custom `Select` event handler.
|
|
123
124
|
*/
|
|
124
125
|
|
|
126
|
+
/**
|
|
127
|
+
* A live view of an `<Option>`’s props, registered with the ancestor `<Combobox>` so that it can
|
|
128
|
+
* resolve labels and the initial value while the options are not rendered.
|
|
129
|
+
* @typedef {object} OptionEntry
|
|
130
|
+
* @property {any} value The option’s value.
|
|
131
|
+
* @property {string} label The option’s text label.
|
|
132
|
+
* @property {string} [name] The option’s name.
|
|
133
|
+
* @property {string} type Data type of the `value`.
|
|
134
|
+
* @property {boolean} selected Whether the option is selected. Writable.
|
|
135
|
+
* @property {boolean} disabled Whether the option is disabled.
|
|
136
|
+
*/
|
|
137
|
+
|
|
125
138
|
/**
|
|
126
139
|
* @typedef {object} ComboboxProps
|
|
127
140
|
* @property {string} [class] The `class` attribute on the wrapper element.
|
|
@@ -284,6 +297,8 @@
|
|
|
284
297
|
* @property {string} id Component ID.
|
|
285
298
|
* @property {string} label Component label.
|
|
286
299
|
* @property {string} [icon] Material Symbols icon name.
|
|
300
|
+
* @property {'menuitem' | 'button'} [trigger] Trigger UI of the component. Default: `menuitem`. A
|
|
301
|
+
* menu item is placed under the Insert menu, while a button is placed directly on the toolbar.
|
|
287
302
|
* @property {LexicalNode} node Lexical node class implementation.
|
|
288
303
|
* @property {(props?: Record<string, any>) => LexicalNode} createNode Function to create a new node
|
|
289
304
|
* instance.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltia/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.57.0",
|
|
4
4
|
"description": "A collection of Svelte components and utilities for building user interfaces.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -56,20 +56,20 @@
|
|
|
56
56
|
"@sveltejs/adapter-auto": "^7.0.1",
|
|
57
57
|
"@sveltejs/kit": "^2.70.2",
|
|
58
58
|
"@sveltejs/package": "^2.5.8",
|
|
59
|
-
"@sveltejs/vite-plugin-svelte": "^7.
|
|
59
|
+
"@sveltejs/vite-plugin-svelte": "^7.3.0",
|
|
60
60
|
"@vitest/coverage-v8": "^4.1.10",
|
|
61
61
|
"cspell": "^10.0.1",
|
|
62
62
|
"eslint": "^9.39.5",
|
|
63
63
|
"eslint-config-airbnb-extended": "^3.2.0",
|
|
64
64
|
"eslint-config-prettier": "^10.1.8",
|
|
65
65
|
"eslint-plugin-import": "^2.32.0",
|
|
66
|
-
"eslint-plugin-jsdoc": "^
|
|
66
|
+
"eslint-plugin-jsdoc": "^64.0.1",
|
|
67
67
|
"eslint-plugin-package-json": "^1.6.3",
|
|
68
68
|
"eslint-plugin-svelte": "^3.22.0",
|
|
69
69
|
"globals": "^17.9.0",
|
|
70
|
-
"happy-dom": "^20.11.
|
|
70
|
+
"happy-dom": "^20.11.2",
|
|
71
71
|
"oxlint": "^1.77.0",
|
|
72
|
-
"postcss": "^8.5.
|
|
72
|
+
"postcss": "^8.5.26",
|
|
73
73
|
"postcss-html": "^2.0.0",
|
|
74
74
|
"prettier": "^3.9.6",
|
|
75
75
|
"prettier-plugin-svelte": "^4.1.1",
|
|
@@ -78,10 +78,10 @@
|
|
|
78
78
|
"stylelint-config-recommended-scss": "^17.0.1",
|
|
79
79
|
"stylelint-scss": "^7.2.0",
|
|
80
80
|
"svelte": "^5.56.8",
|
|
81
|
-
"svelte-check": "^4.7.
|
|
81
|
+
"svelte-check": "^4.7.5",
|
|
82
82
|
"svelte-preprocess": "^6.0.5",
|
|
83
83
|
"tslib": "^2.8.1",
|
|
84
|
-
"vite": "^8.2.
|
|
84
|
+
"vite": "^8.2.1",
|
|
85
85
|
"vitest": "^4.1.10"
|
|
86
86
|
},
|
|
87
87
|
"peerDependencies": {
|