@sveltia/ui 0.8.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/components/alert/alert.svelte +2 -4
- package/package/components/alert/alert.svelte.d.ts +2 -2
- package/package/components/button/button.svelte +78 -26
- package/package/components/button/button.svelte.d.ts +73 -63
- package/package/components/button/select-button-group.svelte +6 -1
- package/package/components/button/select-button-group.svelte.d.ts +13 -13
- package/package/components/button/select-button.svelte +2 -1
- package/package/components/button/select-button.svelte.d.ts +19 -19
- package/package/components/button/split-button.svelte +111 -0
- package/package/components/button/split-button.svelte.d.ts +69 -0
- package/package/components/calendar/calendar.svelte +2 -2
- package/package/components/calendar/calendar.svelte.d.ts +2 -2
- package/package/components/checkbox/checkbox-group.svelte.d.ts +7 -7
- package/package/components/checkbox/checkbox.svelte +8 -6
- package/package/components/checkbox/checkbox.svelte.d.ts +22 -16
- package/package/components/dialog/alert-dialog.svelte.d.ts +6 -6
- package/package/components/dialog/confirmation-dialog.svelte.d.ts +8 -8
- package/package/components/dialog/dialog.svelte +17 -15
- package/package/components/dialog/dialog.svelte.d.ts +30 -24
- package/package/components/dialog/prompt-dialog.svelte +1 -1
- package/package/components/dialog/prompt-dialog.svelte.d.ts +12 -12
- package/package/components/disclosure/disclosure.svelte +6 -1
- package/package/components/disclosure/disclosure.svelte.d.ts +29 -19
- package/package/components/divider/divider.svelte.d.ts +5 -5
- package/package/components/divider/spacer.svelte.d.ts +4 -4
- package/package/components/drawer/drawer.svelte +34 -16
- package/package/components/drawer/drawer.svelte.d.ts +22 -16
- package/package/components/grid/grid-body.svelte.d.ts +4 -4
- package/package/components/grid/grid-cell.svelte.d.ts +2 -2
- package/package/components/grid/grid-col-header.svelte.d.ts +2 -2
- package/package/components/grid/grid-foot.svelte.d.ts +2 -2
- package/package/components/grid/grid-head.svelte.d.ts +2 -2
- package/package/components/grid/grid-row-header.svelte.d.ts +2 -2
- package/package/components/grid/grid-row.svelte +10 -2
- package/package/components/grid/grid-row.svelte.d.ts +8 -8
- package/package/components/grid/grid.svelte +7 -2
- package/package/components/grid/grid.svelte.d.ts +8 -8
- package/package/components/icon/icon.svelte.d.ts +4 -4
- package/package/components/listbox/listbox.svelte +11 -5
- package/package/components/listbox/listbox.svelte.d.ts +15 -15
- package/package/components/listbox/option-group.svelte.d.ts +7 -7
- package/package/components/listbox/option.svelte +4 -2
- package/package/components/listbox/option.svelte.d.ts +15 -13
- package/package/components/menu/menu-button.svelte +18 -2
- package/package/components/menu/menu-button.svelte.d.ts +20 -16
- package/package/components/menu/menu-item-checkbox.svelte +1 -1
- package/package/components/menu/menu-item-checkbox.svelte.d.ts +16 -16
- package/package/components/menu/menu-item-group.svelte +1 -1
- package/package/components/menu/menu-item-group.svelte.d.ts +7 -7
- package/package/components/menu/menu-item-radio.svelte +1 -1
- package/package/components/menu/menu-item-radio.svelte.d.ts +16 -16
- package/package/components/menu/menu-item.svelte +32 -19
- package/package/components/menu/menu-item.svelte.d.ts +32 -18
- package/package/components/menu/menu.svelte +13 -7
- package/package/components/menu/menu.svelte.d.ts +7 -7
- package/package/components/radio/radio-group.svelte +6 -1
- package/package/components/radio/radio-group.svelte.d.ts +15 -15
- package/package/components/radio/radio.svelte +1 -1
- package/package/components/radio/radio.svelte.d.ts +14 -14
- package/package/components/select/combobox.svelte +10 -8
- package/package/components/select/combobox.svelte.d.ts +22 -16
- package/package/components/select/select.svelte.d.ts +12 -12
- package/package/components/slider/slider.svelte +26 -22
- package/package/components/slider/slider.svelte.d.ts +23 -23
- package/package/components/switch/switch.svelte +5 -0
- package/package/components/switch/switch.svelte.d.ts +18 -14
- package/package/components/table/table-body.svelte.d.ts +4 -4
- package/package/components/table/table-cell.svelte.d.ts +2 -2
- package/package/components/table/table-col-header.svelte.d.ts +2 -2
- package/package/components/table/table-foot.svelte.d.ts +2 -2
- package/package/components/table/table-head.svelte.d.ts +2 -2
- package/package/components/table/table-row-header.svelte.d.ts +2 -2
- package/package/components/table/table-row.svelte.d.ts +2 -2
- package/package/components/table/table.svelte.d.ts +2 -2
- package/package/components/tabs/tab-box.svelte +30 -0
- package/package/components/tabs/tab-box.svelte.d.ts +33 -0
- package/package/components/tabs/tab-list.svelte +105 -22
- package/package/components/tabs/tab-list.svelte.d.ts +10 -10
- package/package/components/tabs/tab-panel.svelte +6 -2
- package/package/components/tabs/tab-panel.svelte.d.ts +2 -2
- package/package/components/tabs/tab-panels.svelte +32 -0
- package/package/components/tabs/tab-panels.svelte.d.ts +31 -0
- package/package/components/tabs/tab.svelte.d.ts +11 -11
- package/package/components/text-field/markdown-editor.svelte.d.ts +12 -12
- package/package/components/text-field/number-input.svelte +11 -4
- package/package/components/text-field/number-input.svelte.d.ts +40 -20
- package/package/components/text-field/password-input.svelte +7 -3
- package/package/components/text-field/password-input.svelte.d.ts +30 -18
- package/package/components/text-field/search-bar.svelte +7 -3
- package/package/components/text-field/search-bar.svelte.d.ts +46 -36
- package/package/components/text-field/text-area.svelte +4 -2
- package/package/components/text-field/text-area.svelte.d.ts +25 -21
- package/package/components/text-field/text-input.svelte +17 -2
- package/package/components/text-field/text-input.svelte.d.ts +53 -53
- package/package/components/toast/toast.svelte +16 -12
- package/package/components/toast/toast.svelte.d.ts +8 -8
- package/package/components/toolbar/toolbar.svelte.d.ts +8 -8
- package/package/components/util/app-shell.svelte +162 -74
- package/package/components/util/app-shell.svelte.d.ts +2 -0
- package/package/components/util/group.svelte.d.ts +5 -5
- package/package/components/util/modal.svelte +26 -9
- package/package/components/util/modal.svelte.d.ts +34 -34
- package/package/components/util/popup.svelte +58 -32
- package/package/components/util/popup.svelte.d.ts +34 -24
- package/package/components/util/portal.svelte +5 -3
- package/package/components/util/portal.svelte.d.ts +2 -2
- package/package/index.d.ts +6 -3
- package/package/index.js +7 -4
- package/package/locales/en.d.ts +4 -0
- package/package/locales/en.js +4 -0
- package/package/locales/ja.d.ts +4 -0
- package/package/locales/ja.js +4 -0
- package/package/services/events.d.ts +1 -1
- package/package/services/events.js +11 -8
- package/package/services/group.js +73 -30
- package/package/services/popup.d.ts +28 -11
- package/package/services/popup.js +27 -10
- package/package/services/util.d.ts +2 -2
- package/package/services/util.js +5 -5
- package/package/styles/core.scss +1 -0
- package/package/styles/variables.scss +24 -4
- package/package.json +49 -25
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
/** Generic popup helper. */
|
|
5
5
|
export default class Popup extends SvelteComponent<{
|
|
6
6
|
[x: string]: any;
|
|
7
|
-
anchor: HTMLElement;
|
|
8
|
-
class?: string;
|
|
9
|
-
position?: PopupPosition;
|
|
10
|
-
open?: import("svelte/store").Writable<boolean
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
anchor: HTMLElement | undefined;
|
|
8
|
+
class?: string | undefined;
|
|
9
|
+
position?: PopupPosition | undefined;
|
|
10
|
+
open?: import("svelte/store").Writable<boolean> | undefined;
|
|
11
|
+
showBackdrop?: boolean | undefined;
|
|
12
|
+
content?: HTMLElement | undefined;
|
|
13
|
+
positionBaseElement?: HTMLElement | undefined;
|
|
14
|
+
touchOptimized?: boolean | undefined;
|
|
13
15
|
}, {
|
|
14
16
|
opening: CustomEvent<any>;
|
|
15
17
|
open: CustomEvent<any>;
|
|
@@ -23,23 +25,29 @@ export default class Popup extends SvelteComponent<{
|
|
|
23
25
|
default: {};
|
|
24
26
|
}> {
|
|
25
27
|
/**accessor*/
|
|
26
|
-
set class(arg: string);
|
|
27
|
-
get class(): string;
|
|
28
|
+
set class(arg: string | undefined);
|
|
29
|
+
get class(): string | undefined;
|
|
28
30
|
/**accessor*/
|
|
29
|
-
set open(arg: import("svelte/store").Writable<boolean>);
|
|
30
|
-
get open(): import("svelte/store").Writable<boolean
|
|
31
|
+
set open(arg: import("svelte/store").Writable<boolean> | undefined);
|
|
32
|
+
get open(): import("svelte/store").Writable<boolean> | undefined;
|
|
31
33
|
/**accessor*/
|
|
32
|
-
set
|
|
33
|
-
get
|
|
34
|
+
set showBackdrop(arg: boolean | undefined);
|
|
35
|
+
get showBackdrop(): boolean | undefined;
|
|
34
36
|
/**accessor*/
|
|
35
|
-
set
|
|
36
|
-
get
|
|
37
|
+
set anchor(arg: HTMLElement | undefined);
|
|
38
|
+
get anchor(): HTMLElement | undefined;
|
|
37
39
|
/**accessor*/
|
|
38
|
-
set
|
|
39
|
-
get
|
|
40
|
+
set content(arg: HTMLElement | undefined);
|
|
41
|
+
get content(): HTMLElement | undefined;
|
|
40
42
|
/**accessor*/
|
|
41
|
-
set
|
|
42
|
-
get
|
|
43
|
+
set position(arg: PopupPosition | undefined);
|
|
44
|
+
get position(): PopupPosition | undefined;
|
|
45
|
+
/**accessor*/
|
|
46
|
+
set positionBaseElement(arg: HTMLElement | undefined);
|
|
47
|
+
get positionBaseElement(): HTMLElement | undefined;
|
|
48
|
+
/**accessor*/
|
|
49
|
+
set touchOptimized(arg: boolean | undefined);
|
|
50
|
+
get touchOptimized(): boolean | undefined;
|
|
43
51
|
}
|
|
44
52
|
export type PopupProps = typeof __propDef.props;
|
|
45
53
|
export type PopupEvents = typeof __propDef.events;
|
|
@@ -48,12 +56,14 @@ import { SvelteComponent } from "svelte";
|
|
|
48
56
|
declare const __propDef: {
|
|
49
57
|
props: {
|
|
50
58
|
[x: string]: any;
|
|
51
|
-
anchor: HTMLElement;
|
|
52
|
-
class?: string;
|
|
53
|
-
position?: PopupPosition;
|
|
54
|
-
open?: import(
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
anchor: HTMLElement | undefined;
|
|
60
|
+
class?: string | undefined;
|
|
61
|
+
position?: PopupPosition | undefined;
|
|
62
|
+
open?: import("svelte/store").Writable<boolean> | undefined;
|
|
63
|
+
showBackdrop?: boolean | undefined;
|
|
64
|
+
content?: HTMLElement | undefined;
|
|
65
|
+
positionBaseElement?: HTMLElement | undefined;
|
|
66
|
+
touchOptimized?: boolean | undefined;
|
|
57
67
|
};
|
|
58
68
|
events: {
|
|
59
69
|
opening: CustomEvent<any>;
|
|
@@ -13,15 +13,17 @@
|
|
|
13
13
|
|
|
14
14
|
export { className as class };
|
|
15
15
|
|
|
16
|
-
/** @type {HTMLElement} */
|
|
16
|
+
/** @type {HTMLElement | undefined} */
|
|
17
17
|
let ref;
|
|
18
18
|
|
|
19
19
|
onMount(() => {
|
|
20
|
-
|
|
20
|
+
if (ref) {
|
|
21
|
+
document.body.appendChild(ref);
|
|
22
|
+
}
|
|
21
23
|
});
|
|
22
24
|
|
|
23
25
|
onDestroy(() => {
|
|
24
|
-
ref
|
|
26
|
+
ref?.remove();
|
|
25
27
|
});
|
|
26
28
|
</script>
|
|
27
29
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
/** @see https://github.com/sveltejs/svelte/issues/3088 */
|
|
5
5
|
export default class Portal extends SvelteComponent<{
|
|
6
6
|
[x: string]: any;
|
|
7
|
-
class?: string;
|
|
7
|
+
class?: string | undefined;
|
|
8
8
|
}, {
|
|
9
9
|
[evt: string]: CustomEvent<any>;
|
|
10
10
|
}, {
|
|
@@ -18,7 +18,7 @@ import { SvelteComponent } from "svelte";
|
|
|
18
18
|
declare const __propDef: {
|
|
19
19
|
props: {
|
|
20
20
|
[x: string]: any;
|
|
21
|
-
class?: string;
|
|
21
|
+
class?: string | undefined;
|
|
22
22
|
};
|
|
23
23
|
events: {
|
|
24
24
|
[evt: string]: CustomEvent<any>;
|
package/package/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export function initLocales({ fallbackLocale, initialLocale }?: {
|
|
2
|
-
fallbackLocale?: string;
|
|
3
|
-
initialLocale?: string;
|
|
4
|
-
}): void;
|
|
2
|
+
fallbackLocale?: string | undefined;
|
|
3
|
+
initialLocale?: string | undefined;
|
|
4
|
+
} | undefined): void;
|
|
5
5
|
export { default as Alert } from "./components/alert/alert.svelte";
|
|
6
6
|
export { default as Button } from "./components/button/button.svelte";
|
|
7
7
|
export { default as SelectButtonGroup } from "./components/button/select-button-group.svelte";
|
|
8
8
|
export { default as SelectButton } from "./components/button/select-button.svelte";
|
|
9
|
+
export { default as SplitButton } from "./components/button/split-button.svelte";
|
|
9
10
|
export { default as Calendar } from "./components/calendar/calendar.svelte";
|
|
10
11
|
export { default as CheckboxGroup } from "./components/checkbox/checkbox-group.svelte";
|
|
11
12
|
export { default as Checkbox } from "./components/checkbox/checkbox.svelte";
|
|
@@ -49,8 +50,10 @@ export { default as TableHead } from "./components/table/table-head.svelte";
|
|
|
49
50
|
export { default as TableRowHeader } from "./components/table/table-row-header.svelte";
|
|
50
51
|
export { default as TableRow } from "./components/table/table-row.svelte";
|
|
51
52
|
export { default as Table } from "./components/table/table.svelte";
|
|
53
|
+
export { default as TabBox } from "./components/tabs/tab-box.svelte";
|
|
52
54
|
export { default as TabList } from "./components/tabs/tab-list.svelte";
|
|
53
55
|
export { default as TabPanel } from "./components/tabs/tab-panel.svelte";
|
|
56
|
+
export { default as TabPanels } from "./components/tabs/tab-panels.svelte";
|
|
54
57
|
export { default as Tab } from "./components/tabs/tab.svelte";
|
|
55
58
|
export { default as MarkdownEditor } from "./components/text-field/markdown-editor.svelte";
|
|
56
59
|
export { default as NumberInput } from "./components/text-field/number-input.svelte";
|
package/package/index.js
CHANGED
|
@@ -2,9 +2,9 @@ import { addMessages, init } from 'svelte-i18n';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Load strings and initialize the locales.
|
|
5
|
-
* @param {object} [init] Initialize options.
|
|
6
|
-
* @param {string} [init.fallbackLocale] Fallback locale.
|
|
7
|
-
* @param {string} [init.initialLocale] Initial locale.
|
|
5
|
+
* @param {object} [init] - Initialize options.
|
|
6
|
+
* @param {string} [init.fallbackLocale] - Fallback locale.
|
|
7
|
+
* @param {string} [init.initialLocale] - Initial locale.
|
|
8
8
|
* @see https://github.com/kaisermann/svelte-i18n/blob/main/docs/Getting%20Started.md
|
|
9
9
|
* @see https://vitejs.dev/guide/features.html#glob-import
|
|
10
10
|
*/
|
|
@@ -13,7 +13,7 @@ export const initLocales = ({ fallbackLocale = 'en', initialLocale = 'en' } = {}
|
|
|
13
13
|
const modules = import.meta.glob('./locales/*.js', { eager: true });
|
|
14
14
|
|
|
15
15
|
Object.entries(modules).forEach(([path, { strings }]) => {
|
|
16
|
-
const [, locale] = path.match(/([a-zA-Z-]+)\.js/);
|
|
16
|
+
const [, locale] = /** @type {string[]} */ (path.match(/([a-zA-Z-]+)\.js/));
|
|
17
17
|
|
|
18
18
|
// Add `_sui` suffix to avoid collision with app localization
|
|
19
19
|
addMessages(locale, /** @type {any} */ ({ _sui: strings }));
|
|
@@ -31,6 +31,7 @@ export { default as Alert } from './components/alert/alert.svelte';
|
|
|
31
31
|
export { default as Button } from './components/button/button.svelte';
|
|
32
32
|
export { default as SelectButtonGroup } from './components/button/select-button-group.svelte';
|
|
33
33
|
export { default as SelectButton } from './components/button/select-button.svelte';
|
|
34
|
+
export { default as SplitButton } from './components/button/split-button.svelte';
|
|
34
35
|
export { default as Calendar } from './components/calendar/calendar.svelte';
|
|
35
36
|
export { default as CheckboxGroup } from './components/checkbox/checkbox-group.svelte';
|
|
36
37
|
export { default as Checkbox } from './components/checkbox/checkbox.svelte';
|
|
@@ -74,8 +75,10 @@ export { default as TableHead } from './components/table/table-head.svelte';
|
|
|
74
75
|
export { default as TableRowHeader } from './components/table/table-row-header.svelte';
|
|
75
76
|
export { default as TableRow } from './components/table/table-row.svelte';
|
|
76
77
|
export { default as Table } from './components/table/table.svelte';
|
|
78
|
+
export { default as TabBox } from './components/tabs/tab-box.svelte';
|
|
77
79
|
export { default as TabList } from './components/tabs/tab-list.svelte';
|
|
78
80
|
export { default as TabPanel } from './components/tabs/tab-panel.svelte';
|
|
81
|
+
export { default as TabPanels } from './components/tabs/tab-panels.svelte';
|
|
79
82
|
export { default as Tab } from './components/tabs/tab.svelte';
|
|
80
83
|
export { default as MarkdownEditor } from './components/text-field/markdown-editor.svelte';
|
|
81
84
|
export { default as NumberInput } from './components/text-field/number-input.svelte';
|
package/package/locales/en.d.ts
CHANGED
package/package/locales/en.js
CHANGED
package/package/locales/ja.d.ts
CHANGED
package/package/locales/ja.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export function isMac(): boolean;
|
|
2
2
|
export function matchShortcuts(event: KeyboardEvent, shortcuts: string): boolean;
|
|
3
|
-
export function activateKeyShortcuts(element: (HTMLInputElement | HTMLButtonElement), shortcuts?: string): import('svelte/action').ActionReturn;
|
|
3
|
+
export function activateKeyShortcuts(element: (HTMLInputElement | HTMLButtonElement), shortcuts?: string | undefined): import('svelte/action').ActionReturn;
|
|
@@ -8,8 +8,8 @@ export const isMac = () =>
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Whether the event matches the given keyboard shortcuts.
|
|
11
|
-
* @param {KeyboardEvent} event `keydown` or `keypress` event.
|
|
12
|
-
* @param {string} shortcuts Keyboard shortcuts like `A` or `Ctrl+S`.
|
|
11
|
+
* @param {KeyboardEvent} event - `keydown` or `keypress` event.
|
|
12
|
+
* @param {string} shortcuts - Keyboard shortcuts like `A` or `Ctrl+S`.
|
|
13
13
|
* @returns {boolean} Result.
|
|
14
14
|
* @see https://w3c.github.io/aria/#aria-keyshortcuts
|
|
15
15
|
*/
|
|
@@ -47,10 +47,10 @@ export const matchShortcuts = (event, shortcuts) => {
|
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Activate keyboard shortcuts.
|
|
50
|
-
* @param {(HTMLInputElement | HTMLButtonElement)} element Element.
|
|
51
|
-
* @param {string} [shortcuts] Keyboard shortcuts like `A` or `Accel+S` to focus and click the
|
|
52
|
-
* field or button. Multiple shortcuts can be defined space-separated. The `Accel` modifier
|
|
53
|
-
* replaced with `Ctrl` on Windows/Linux and `Command` on macOS.
|
|
50
|
+
* @param {(HTMLInputElement | HTMLButtonElement)} element - Element.
|
|
51
|
+
* @param {string} [shortcuts] - Keyboard shortcuts like `A` or `Accel+S` to focus and click the
|
|
52
|
+
* text field or button. Multiple shortcuts can be defined space-separated. The `Accel` modifier
|
|
53
|
+
* will be replaced with `Ctrl` on Windows/Linux and `Command` on macOS.
|
|
54
54
|
* @returns {import('svelte/action').ActionReturn} Actions.
|
|
55
55
|
*/
|
|
56
56
|
export const activateKeyShortcuts = (element, shortcuts = '') => {
|
|
@@ -59,10 +59,13 @@ export const activateKeyShortcuts = (element, shortcuts = '') => {
|
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
61
|
* Handle the event.
|
|
62
|
-
* @param {KeyboardEvent} event `keydown` event.
|
|
62
|
+
* @param {KeyboardEvent} event - `keydown` event.
|
|
63
63
|
*/
|
|
64
64
|
const handler = (event) => {
|
|
65
|
-
if (
|
|
65
|
+
if (
|
|
66
|
+
!!element.offsetParent &&
|
|
67
|
+
matchShortcuts(event, /** @type {string} */ (platformKeyShortcuts))
|
|
68
|
+
) {
|
|
66
69
|
event.preventDefault();
|
|
67
70
|
|
|
68
71
|
if (!element.disabled) {
|
|
@@ -2,10 +2,10 @@ import { getRandomId, sleep } from './util';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @type {{ [role: string]: {
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* orientation: 'vertical' | 'horizontal',
|
|
6
|
+
* childRoles: string[],
|
|
7
|
+
* childSelectedAttr: 'aria-selected' | 'aria-checked',
|
|
8
|
+
* focusChild: boolean
|
|
9
9
|
* } }}
|
|
10
10
|
*/
|
|
11
11
|
const config = {
|
|
@@ -53,12 +53,14 @@ const config = {
|
|
|
53
53
|
class Group {
|
|
54
54
|
/**
|
|
55
55
|
* Initialize a new `Group` instance.
|
|
56
|
-
* @param {HTMLElement} parent Parent element.
|
|
56
|
+
* @param {HTMLElement} parent - Parent element.
|
|
57
57
|
* @todo Check for added elements probably with `MutationObserver`.
|
|
58
58
|
*/
|
|
59
59
|
constructor(parent) {
|
|
60
|
+
parent.dispatchEvent(new CustomEvent('initializing'));
|
|
61
|
+
|
|
60
62
|
this.parent = parent;
|
|
61
|
-
this.role = parent.getAttribute('role');
|
|
63
|
+
this.role = /** @type {string} */ (parent.getAttribute('role'));
|
|
62
64
|
this.grid = this.role === 'listbox' && parent.matches('.grid');
|
|
63
65
|
this.multi = this.parent.getAttribute('aria-multiselectable') === 'true';
|
|
64
66
|
this.id = getRandomId(this.role);
|
|
@@ -74,21 +76,29 @@ class Group {
|
|
|
74
76
|
this.childSelectedProp = childSelectedAttr.replace('aria-', '');
|
|
75
77
|
this.focusChild = focusChild;
|
|
76
78
|
|
|
77
|
-
const { allMembers } = this;
|
|
78
|
-
|
|
79
|
-
const hasSelected = allMembers.some((element) =>
|
|
80
|
-
element.matches(`[${childSelectedAttr}="true"]`),
|
|
81
|
-
);
|
|
79
|
+
const { allMembers, selected: defaultSelected } = this;
|
|
82
80
|
|
|
83
81
|
allMembers.forEach((element, index) => {
|
|
84
|
-
|
|
85
|
-
const
|
|
82
|
+
// Select the first one if no member has the `selected` attribute
|
|
83
|
+
const isSelected = defaultSelected ? element === defaultSelected : index === 0;
|
|
84
|
+
|
|
85
|
+
const controlTarget = /** @type {HTMLElement | null} */ (
|
|
86
|
+
document.querySelector(`#${element.getAttribute('aria-controls')}`)
|
|
87
|
+
);
|
|
86
88
|
|
|
87
89
|
element.id ||= `${this.id}-item-${index + 1}`;
|
|
88
|
-
element.tabIndex ||= isSelected
|
|
90
|
+
element.tabIndex ||= isSelected ? 0 : -1;
|
|
89
91
|
element.setAttribute(this.childSelectedAttr, String(isSelected));
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
|
|
93
|
+
if (controlTarget) {
|
|
94
|
+
controlTarget.inert = !isSelected;
|
|
95
|
+
controlTarget.setAttribute('aria-labelledby', element.id);
|
|
96
|
+
controlTarget.setAttribute('aria-hidden', String(!isSelected));
|
|
97
|
+
|
|
98
|
+
if (isSelected) {
|
|
99
|
+
controlTarget.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'auto' });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
92
102
|
});
|
|
93
103
|
|
|
94
104
|
parent.addEventListener('click', (event) => {
|
|
@@ -100,39 +110,66 @@ class Group {
|
|
|
100
110
|
parent.addEventListener('keydown', (event) => {
|
|
101
111
|
this.onKeyDown(event);
|
|
102
112
|
});
|
|
113
|
+
|
|
114
|
+
parent.dispatchEvent(new CustomEvent('initialized'));
|
|
103
115
|
}
|
|
104
116
|
|
|
105
|
-
/**
|
|
117
|
+
/**
|
|
118
|
+
* CSS selector to retrieve the members.
|
|
119
|
+
* @type {string}
|
|
120
|
+
*/
|
|
106
121
|
get selector() {
|
|
107
122
|
return this.childRoles.map((role) => `[role="${role}"]`).join(',');
|
|
108
123
|
}
|
|
109
124
|
|
|
110
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* List of all the members.
|
|
127
|
+
* @type {HTMLElement[]}
|
|
128
|
+
*/
|
|
111
129
|
get allMembers() {
|
|
112
130
|
return /** @type {HTMLElement[]} */ ([...this.parent.querySelectorAll(this.selector)]);
|
|
113
131
|
}
|
|
114
132
|
|
|
115
|
-
/**
|
|
133
|
+
/**
|
|
134
|
+
* List of the enabled and visible members.
|
|
135
|
+
* @type {HTMLElement[]}
|
|
136
|
+
*/
|
|
116
137
|
get activeMembers() {
|
|
117
138
|
return this.allMembers.filter(
|
|
118
139
|
(element) => !element.matches('[aria-disabled="true"], [aria-hidden="true"]'),
|
|
119
140
|
);
|
|
120
141
|
}
|
|
121
142
|
|
|
122
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* Get the currently selected member.
|
|
145
|
+
* @type {HTMLElement | undefined}
|
|
146
|
+
*/
|
|
147
|
+
get selected() {
|
|
148
|
+
return this.activeMembers.find((element) =>
|
|
149
|
+
element.matches(`[${this.childSelectedAttr}="true"]`),
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Whether the parent is disabled.
|
|
155
|
+
* @type {boolean}
|
|
156
|
+
*/
|
|
123
157
|
get isDisabled() {
|
|
124
158
|
return this.parent.matches('[aria-disabled="true"]');
|
|
125
159
|
}
|
|
126
160
|
|
|
127
|
-
/**
|
|
161
|
+
/**
|
|
162
|
+
* Whether the parent is read-only.
|
|
163
|
+
* @type {boolean}
|
|
164
|
+
*/
|
|
128
165
|
get isReadOnly() {
|
|
129
166
|
return this.parent.matches('[aria-readonly="true"]');
|
|
130
167
|
}
|
|
131
168
|
|
|
132
169
|
/**
|
|
133
170
|
* Select (and move focus to) the given target.
|
|
134
|
-
* @param {(MouseEvent | KeyboardEvent)} event Triggered event.
|
|
135
|
-
* @param {HTMLElement} newTarget Target element.
|
|
171
|
+
* @param {(MouseEvent | KeyboardEvent)} event - Triggered event.
|
|
172
|
+
* @param {HTMLElement} newTarget - Target element.
|
|
136
173
|
*/
|
|
137
174
|
selectTarget(event, newTarget) {
|
|
138
175
|
if (this.isDisabled || this.isReadOnly) {
|
|
@@ -164,7 +201,8 @@ class Group {
|
|
|
164
201
|
const singleSelect = isMenuItemRadio || !multiSelect;
|
|
165
202
|
const isTarget = element === newTarget;
|
|
166
203
|
const isSelected = element.matches(`[${this.childSelectedAttr}="true"]`);
|
|
167
|
-
const
|
|
204
|
+
const controlTargetId = element.getAttribute('aria-controls');
|
|
205
|
+
const controlTarget = controlTargetId ? document.getElementById(controlTargetId) : null;
|
|
168
206
|
|
|
169
207
|
if (multiSelect && isTarget && (selectByClick || selectByKeydown)) {
|
|
170
208
|
element.setAttribute(this.childSelectedAttr, String(!isSelected));
|
|
@@ -202,13 +240,18 @@ class Group {
|
|
|
202
240
|
element.classList.toggle('focused', isTarget);
|
|
203
241
|
}
|
|
204
242
|
|
|
205
|
-
if (
|
|
206
|
-
|
|
243
|
+
if (controlTarget) {
|
|
244
|
+
controlTarget.inert = !isTarget;
|
|
245
|
+
controlTarget.setAttribute('aria-hidden', String(!isTarget));
|
|
246
|
+
|
|
247
|
+
if (isTarget) {
|
|
248
|
+
controlTarget.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'auto' });
|
|
249
|
+
}
|
|
207
250
|
}
|
|
208
251
|
|
|
209
252
|
if (isTarget) {
|
|
210
253
|
this.parent.setAttribute('aria-activedescendant', element.id);
|
|
211
|
-
element.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: '
|
|
254
|
+
element.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'auto' });
|
|
212
255
|
}
|
|
213
256
|
});
|
|
214
257
|
|
|
@@ -224,7 +267,7 @@ class Group {
|
|
|
224
267
|
|
|
225
268
|
/**
|
|
226
269
|
* Handle the `click` event on the widget.
|
|
227
|
-
* @param {MouseEvent} event `click` event.
|
|
270
|
+
* @param {MouseEvent} event - `click` event.
|
|
228
271
|
*/
|
|
229
272
|
onClick(event) {
|
|
230
273
|
// eslint-disable-next-line prefer-destructuring
|
|
@@ -240,7 +283,7 @@ class Group {
|
|
|
240
283
|
|
|
241
284
|
/**
|
|
242
285
|
* Handle the `keydown` event on the widget.
|
|
243
|
-
* @param {KeyboardEvent} event `keydown` event.
|
|
286
|
+
* @param {KeyboardEvent} event - `keydown` event.
|
|
244
287
|
*/
|
|
245
288
|
onKeyDown(event) {
|
|
246
289
|
const { key, ctrlKey, metaKey, shiftKey, altKey } = event;
|
|
@@ -349,7 +392,7 @@ class Group {
|
|
|
349
392
|
|
|
350
393
|
/**
|
|
351
394
|
* Activate a new group.
|
|
352
|
-
* @param {HTMLElement} parent Parent element.
|
|
395
|
+
* @param {HTMLElement} parent - Parent element.
|
|
353
396
|
*/
|
|
354
397
|
export const activateGroup = (parent) => {
|
|
355
398
|
(async () => {
|
|
@@ -6,26 +6,43 @@ export function activatePopup(...args: any[]): Popup;
|
|
|
6
6
|
declare class Popup {
|
|
7
7
|
/**
|
|
8
8
|
* Initialize a new `Popup` instance.
|
|
9
|
-
* @param {HTMLButtonElement} anchorElement `<button>` element that triggers the popup.
|
|
10
|
-
* @param {HTMLDialogElement} popupElement `<dialog>` element to be used for the popup.
|
|
11
|
-
* @param {PopupPosition} position Where to show the popup content.
|
|
9
|
+
* @param {HTMLButtonElement} anchorElement - `<button>` element that triggers the popup.
|
|
10
|
+
* @param {HTMLDialogElement} popupElement - `<dialog>` element to be used for the popup.
|
|
11
|
+
* @param {PopupPosition} position - Where to show the popup content.
|
|
12
|
+
* @param {HTMLElement} [positionBaseElement] - The base element of the `position`. If omitted,
|
|
13
|
+
* this will be the `anchorElement`.
|
|
12
14
|
*/
|
|
13
|
-
constructor(anchorElement: HTMLButtonElement, popupElement: HTMLDialogElement, position: PopupPosition);
|
|
15
|
+
constructor(anchorElement: HTMLButtonElement, popupElement: HTMLDialogElement, position: PopupPosition, positionBaseElement?: HTMLElement | undefined);
|
|
14
16
|
open: import("svelte/store").Writable<boolean>;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
/**
|
|
18
|
+
* @type {import('svelte/store').Writable<{
|
|
19
|
+
* inset: string | undefined,
|
|
20
|
+
* zIndex: number | undefined,
|
|
21
|
+
* width: string | undefined,
|
|
22
|
+
* height: string | undefined,
|
|
23
|
+
* }>}
|
|
24
|
+
*/
|
|
25
|
+
style: import('svelte/store').Writable<{
|
|
26
|
+
inset: string | undefined;
|
|
27
|
+
zIndex: number | undefined;
|
|
28
|
+
width: string | undefined;
|
|
29
|
+
height: string | undefined;
|
|
20
30
|
}>;
|
|
21
31
|
observer: IntersectionObserver;
|
|
22
32
|
anchorElement: HTMLButtonElement;
|
|
23
33
|
popupElement: HTMLDialogElement;
|
|
24
34
|
position: PopupPosition;
|
|
35
|
+
positionBaseElement: HTMLElement;
|
|
25
36
|
id: string;
|
|
26
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Whether the anchor element is disabled.
|
|
39
|
+
* @type {boolean}
|
|
40
|
+
*/
|
|
27
41
|
get isDisabled(): boolean;
|
|
28
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* Whether the anchor element is read-only.
|
|
44
|
+
* @type {boolean}
|
|
45
|
+
*/
|
|
29
46
|
get isReadOnly(): boolean;
|
|
30
47
|
/**
|
|
31
48
|
* Check the position of the anchor element.
|
|
@@ -9,6 +9,14 @@ import { getRandomId } from './util';
|
|
|
9
9
|
class Popup {
|
|
10
10
|
open = writable(false);
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @type {import('svelte/store').Writable<{
|
|
14
|
+
* inset: string | undefined,
|
|
15
|
+
* zIndex: number | undefined,
|
|
16
|
+
* width: string | undefined,
|
|
17
|
+
* height: string | undefined,
|
|
18
|
+
* }>}
|
|
19
|
+
*/
|
|
12
20
|
style = writable({ inset: undefined, zIndex: undefined, width: undefined, height: undefined });
|
|
13
21
|
|
|
14
22
|
observer = new IntersectionObserver((entries) => {
|
|
@@ -18,7 +26,7 @@ class Popup {
|
|
|
18
26
|
}
|
|
19
27
|
|
|
20
28
|
const { scrollHeight: contentHeight, scrollWidth: contentWidth } =
|
|
21
|
-
this.popupElement.querySelector('.content');
|
|
29
|
+
/** @type {HTMLElement} */ (this.popupElement.querySelector('.content'));
|
|
22
30
|
|
|
23
31
|
const topMargin = intersectionRect.top - 8;
|
|
24
32
|
const bottomMargin = rootBounds.height - intersectionRect.bottom - 8;
|
|
@@ -86,14 +94,17 @@ class Popup {
|
|
|
86
94
|
|
|
87
95
|
/**
|
|
88
96
|
* Initialize a new `Popup` instance.
|
|
89
|
-
* @param {HTMLButtonElement} anchorElement `<button>` element that triggers the popup.
|
|
90
|
-
* @param {HTMLDialogElement} popupElement `<dialog>` element to be used for the popup.
|
|
91
|
-
* @param {PopupPosition} position Where to show the popup content.
|
|
97
|
+
* @param {HTMLButtonElement} anchorElement - `<button>` element that triggers the popup.
|
|
98
|
+
* @param {HTMLDialogElement} popupElement - `<dialog>` element to be used for the popup.
|
|
99
|
+
* @param {PopupPosition} position - Where to show the popup content.
|
|
100
|
+
* @param {HTMLElement} [positionBaseElement] - The base element of the `position`. If omitted,
|
|
101
|
+
* this will be the `anchorElement`.
|
|
92
102
|
*/
|
|
93
|
-
constructor(anchorElement, popupElement, position) {
|
|
103
|
+
constructor(anchorElement, popupElement, position, positionBaseElement) {
|
|
94
104
|
this.anchorElement = anchorElement;
|
|
95
105
|
this.popupElement = popupElement; // = backdrop
|
|
96
106
|
this.position = position;
|
|
107
|
+
this.positionBaseElement = positionBaseElement ?? anchorElement;
|
|
97
108
|
this.id = getRandomId('popup');
|
|
98
109
|
|
|
99
110
|
this.anchorElement.setAttribute('aria-controls', this.id);
|
|
@@ -154,12 +165,18 @@ class Popup {
|
|
|
154
165
|
});
|
|
155
166
|
}
|
|
156
167
|
|
|
157
|
-
/**
|
|
168
|
+
/**
|
|
169
|
+
* Whether the anchor element is disabled.
|
|
170
|
+
* @type {boolean}
|
|
171
|
+
*/
|
|
158
172
|
get isDisabled() {
|
|
159
173
|
return this.anchorElement.matches('[aria-disabled="true"]');
|
|
160
174
|
}
|
|
161
175
|
|
|
162
|
-
/**
|
|
176
|
+
/**
|
|
177
|
+
* Whether the anchor element is read-only.
|
|
178
|
+
* @type {boolean}
|
|
179
|
+
*/
|
|
163
180
|
get isReadOnly() {
|
|
164
181
|
return this.anchorElement.matches('[aria-readonly="true"]');
|
|
165
182
|
}
|
|
@@ -168,14 +185,14 @@ class Popup {
|
|
|
168
185
|
* Check the position of the anchor element.
|
|
169
186
|
*/
|
|
170
187
|
checkPosition() {
|
|
171
|
-
this.observer.unobserve(this.
|
|
172
|
-
this.observer.observe(this.
|
|
188
|
+
this.observer.unobserve(this.positionBaseElement);
|
|
189
|
+
this.observer.observe(this.positionBaseElement);
|
|
173
190
|
}
|
|
174
191
|
}
|
|
175
192
|
|
|
176
193
|
/**
|
|
177
194
|
* Activate a new popup.
|
|
178
|
-
* @param {...any} args Arguments.
|
|
195
|
+
* @param {...any} args - Arguments.
|
|
179
196
|
* @returns {Popup} New popup.
|
|
180
197
|
*/
|
|
181
198
|
// @ts-ignore
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export function getRandomId(prefix?: string, length?: number): string;
|
|
1
|
+
export function getRandomId(prefix?: string | undefined, length?: number | undefined): string;
|
|
2
2
|
export function isObject(input: any): boolean;
|
|
3
|
-
export function sleep(ms?: number): Promise<void>;
|
|
3
|
+
export function sleep(ms?: number | undefined): Promise<void>;
|