@sveltia/ui 0.6.2 → 0.6.4
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/button/button.svelte +8 -0
- package/package/components/button/button.svelte.d.ts +9 -4
- package/package/components/button/select-button-group.svelte +1 -1
- package/package/components/checkbox/checkbox.svelte.d.ts +4 -4
- package/package/components/dialog/dialog.svelte.d.ts +2 -2
- package/package/components/drawer/drawer.svelte.d.ts +2 -2
- package/package/components/listbox/listbox.svelte.d.ts +2 -2
- package/package/components/menu/menu-item.svelte.d.ts +2 -2
- package/package/components/select/combobox.svelte.d.ts +2 -2
- package/package/components/slider/slider.svelte.d.ts +6 -6
- package/package/components/switch/switch.svelte.d.ts +2 -2
- package/package/components/text-field/number-input.svelte.d.ts +4 -4
- package/package/components/text-field/text-input.svelte +8 -0
- package/package/components/text-field/text-input.svelte.d.ts +7 -2
- package/package/components/util/app-shell.svelte +38 -7
- package/package/components/util/events.d.ts +3 -0
- package/package/components/util/events.js +110 -0
- package/package/components/util/popup.svelte +1 -0
- package/package/styles/core.scss +1 -6
- package/package/styles/variables.scss +1 -1
- package/package.json +8 -1
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
<svelte:options accessors={true} />
|
|
8
8
|
|
|
9
9
|
<script>
|
|
10
|
+
import { activateKeyShortcuts } from '../util/events';
|
|
10
11
|
import Popup from '../util/popup.svelte';
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -71,6 +72,12 @@
|
|
|
71
72
|
*/
|
|
72
73
|
export let popupPosition = 'bottom-left';
|
|
73
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Keyboard shortcuts.
|
|
77
|
+
* @type {string}
|
|
78
|
+
*/
|
|
79
|
+
export let keyShortcuts = '';
|
|
80
|
+
|
|
74
81
|
/** @type {?Popup} */
|
|
75
82
|
let popupComponent;
|
|
76
83
|
</script>
|
|
@@ -95,6 +102,7 @@
|
|
|
95
102
|
on:keydown
|
|
96
103
|
on:keyup
|
|
97
104
|
on:keypress
|
|
105
|
+
use:activateKeyShortcuts={keyShortcuts}
|
|
98
106
|
bind:this={element}
|
|
99
107
|
>
|
|
100
108
|
<slot name="start-icon" />
|
|
@@ -12,12 +12,13 @@ export default class Button extends SvelteComponent<{
|
|
|
12
12
|
label?: string;
|
|
13
13
|
type?: "reset" | "submit" | "button";
|
|
14
14
|
disabled?: boolean;
|
|
15
|
-
element?: HTMLButtonElement;
|
|
16
|
-
role?: string;
|
|
17
15
|
size?: "small" | "medium" | "large";
|
|
18
16
|
hidden?: boolean;
|
|
17
|
+
element?: HTMLButtonElement;
|
|
18
|
+
role?: string;
|
|
19
19
|
pressed?: boolean | "true" | "false" | "mixed";
|
|
20
20
|
popupPosition?: PopupPosition;
|
|
21
|
+
keyShortcuts?: string;
|
|
21
22
|
}, {
|
|
22
23
|
mouseenter: MouseEvent;
|
|
23
24
|
mouseleave: MouseEvent;
|
|
@@ -67,6 +68,9 @@ export default class Button extends SvelteComponent<{
|
|
|
67
68
|
/**accessor*/
|
|
68
69
|
set popupPosition(arg: PopupPosition);
|
|
69
70
|
get popupPosition(): PopupPosition;
|
|
71
|
+
/**accessor*/
|
|
72
|
+
set keyShortcuts(arg: string);
|
|
73
|
+
get keyShortcuts(): string;
|
|
70
74
|
}
|
|
71
75
|
export type ButtonProps = typeof __propDef.props;
|
|
72
76
|
export type ButtonEvents = typeof __propDef.events;
|
|
@@ -79,12 +83,13 @@ declare const __propDef: {
|
|
|
79
83
|
label?: string;
|
|
80
84
|
type?: ('button' | 'submit' | 'reset');
|
|
81
85
|
disabled?: boolean;
|
|
82
|
-
element?: HTMLButtonElement | null;
|
|
83
|
-
role?: string;
|
|
84
86
|
size?: ('small' | 'medium' | 'large');
|
|
85
87
|
hidden?: boolean;
|
|
88
|
+
element?: HTMLButtonElement | null;
|
|
89
|
+
role?: string;
|
|
86
90
|
pressed?: (boolean | 'false' | 'mixed' | 'true' | undefined);
|
|
87
91
|
popupPosition?: PopupPosition;
|
|
92
|
+
keyShortcuts?: string;
|
|
88
93
|
};
|
|
89
94
|
events: {
|
|
90
95
|
mouseenter: MouseEvent;
|
|
@@ -12,10 +12,10 @@ export default class Checkbox extends SvelteComponent<{
|
|
|
12
12
|
class?: string;
|
|
13
13
|
name?: string;
|
|
14
14
|
label?: string;
|
|
15
|
-
disabled?: boolean;
|
|
16
|
-
value?: string;
|
|
17
15
|
checked?: string | boolean;
|
|
16
|
+
disabled?: boolean;
|
|
18
17
|
indeterminate?: boolean;
|
|
18
|
+
value?: string;
|
|
19
19
|
}, {
|
|
20
20
|
change: CustomEvent<any>;
|
|
21
21
|
} & {
|
|
@@ -34,10 +34,10 @@ declare const __propDef: {
|
|
|
34
34
|
class?: string;
|
|
35
35
|
name?: string;
|
|
36
36
|
label?: string | null;
|
|
37
|
-
disabled?: boolean;
|
|
38
|
-
value?: string | null;
|
|
39
37
|
checked?: (boolean | string | undefined);
|
|
38
|
+
disabled?: boolean;
|
|
40
39
|
indeterminate?: boolean;
|
|
40
|
+
value?: string | null;
|
|
41
41
|
};
|
|
42
42
|
events: {
|
|
43
43
|
change: CustomEvent<any>;
|
|
@@ -10,8 +10,8 @@ export default class Dialog extends SvelteComponent<{
|
|
|
10
10
|
[x: string]: any;
|
|
11
11
|
class?: string;
|
|
12
12
|
title?: string;
|
|
13
|
-
open?: boolean;
|
|
14
13
|
size?: "small" | "medium" | "large" | "x-large";
|
|
14
|
+
open?: boolean;
|
|
15
15
|
modal?: boolean;
|
|
16
16
|
showCancel?: boolean;
|
|
17
17
|
showOk?: boolean;
|
|
@@ -45,8 +45,8 @@ declare const __propDef: {
|
|
|
45
45
|
[x: string]: any;
|
|
46
46
|
class?: string;
|
|
47
47
|
title?: string;
|
|
48
|
-
open?: boolean;
|
|
49
48
|
size?: ('small' | 'medium' | 'large' | 'x-large');
|
|
49
|
+
open?: boolean;
|
|
50
50
|
modal?: boolean;
|
|
51
51
|
showCancel?: boolean;
|
|
52
52
|
showOk?: boolean;
|
|
@@ -11,8 +11,8 @@ export default class Drawer extends SvelteComponent<{
|
|
|
11
11
|
class?: string;
|
|
12
12
|
title?: string;
|
|
13
13
|
position?: "top" | "right" | "bottom" | "left";
|
|
14
|
-
open?: boolean;
|
|
15
14
|
size?: "small" | "medium" | "large" | "x-large";
|
|
15
|
+
open?: boolean;
|
|
16
16
|
showClose?: false | "inside" | "outside";
|
|
17
17
|
closeOnBackdropClick?: boolean;
|
|
18
18
|
}, {
|
|
@@ -39,8 +39,8 @@ declare const __propDef: {
|
|
|
39
39
|
class?: string;
|
|
40
40
|
title?: string;
|
|
41
41
|
position?: ('top' | 'right' | 'bottom' | 'left');
|
|
42
|
-
open?: boolean;
|
|
43
42
|
size?: ('small' | 'medium' | 'large' | 'x-large');
|
|
43
|
+
open?: boolean;
|
|
44
44
|
showClose?: ('inside' | 'outside' | false);
|
|
45
45
|
closeOnBackdropClick?: boolean;
|
|
46
46
|
};
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
export default class Listbox extends SvelteComponent<{
|
|
11
11
|
[x: string]: any;
|
|
12
12
|
class?: string;
|
|
13
|
-
element?: HTMLElement;
|
|
14
13
|
multiple?: boolean;
|
|
14
|
+
element?: HTMLElement;
|
|
15
15
|
}, {
|
|
16
16
|
click: MouseEvent;
|
|
17
17
|
select: Event;
|
|
@@ -38,8 +38,8 @@ declare const __propDef: {
|
|
|
38
38
|
props: {
|
|
39
39
|
[x: string]: any;
|
|
40
40
|
class?: string;
|
|
41
|
-
element?: HTMLElement | null;
|
|
42
41
|
multiple?: boolean;
|
|
42
|
+
element?: HTMLElement | null;
|
|
43
43
|
};
|
|
44
44
|
events: {
|
|
45
45
|
click: MouseEvent;
|
|
@@ -9,8 +9,8 @@ export default class MenuItem extends SvelteComponent<{
|
|
|
9
9
|
[x: string]: any;
|
|
10
10
|
class?: string;
|
|
11
11
|
label?: string;
|
|
12
|
-
role?: "menuitem" | "menuitemcheckbox" | "menuitemradio";
|
|
13
12
|
checked?: boolean;
|
|
13
|
+
role?: "menuitem" | "menuitemcheckbox" | "menuitemradio";
|
|
14
14
|
iconName?: string;
|
|
15
15
|
iconLabel?: string;
|
|
16
16
|
}, {
|
|
@@ -30,8 +30,8 @@ declare const __propDef: {
|
|
|
30
30
|
[x: string]: any;
|
|
31
31
|
class?: string;
|
|
32
32
|
label?: string;
|
|
33
|
-
role?: ('menuitem' | 'menuitemcheckbox' | 'menuitemradio');
|
|
34
33
|
checked?: boolean;
|
|
34
|
+
role?: ('menuitem' | 'menuitemcheckbox' | 'menuitemradio');
|
|
35
35
|
iconName?: string;
|
|
36
36
|
iconLabel?: string;
|
|
37
37
|
};
|
|
@@ -12,8 +12,8 @@ export default class Combobox extends SvelteComponent<{
|
|
|
12
12
|
label?: string;
|
|
13
13
|
position?: PopupPosition;
|
|
14
14
|
disabled?: boolean;
|
|
15
|
-
value?: string | number;
|
|
16
15
|
readOnly?: boolean;
|
|
16
|
+
value?: string | number;
|
|
17
17
|
}, {
|
|
18
18
|
change: CustomEvent<any>;
|
|
19
19
|
} & {
|
|
@@ -36,8 +36,8 @@ declare const __propDef: {
|
|
|
36
36
|
label?: string;
|
|
37
37
|
position?: PopupPosition;
|
|
38
38
|
disabled?: boolean;
|
|
39
|
-
value?: (string | number | undefined);
|
|
40
39
|
readOnly?: boolean;
|
|
40
|
+
value?: (string | number | undefined);
|
|
41
41
|
};
|
|
42
42
|
events: {
|
|
43
43
|
change: CustomEvent<any>;
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
export default class Slider extends SvelteComponent<{
|
|
13
13
|
[x: string]: any;
|
|
14
14
|
class?: string;
|
|
15
|
+
max?: number;
|
|
16
|
+
min?: number;
|
|
17
|
+
step?: number;
|
|
15
18
|
value?: number;
|
|
16
19
|
sliderLabel?: string;
|
|
17
20
|
values?: [number, number];
|
|
18
21
|
sliderLabels?: [string, string];
|
|
19
|
-
min?: number;
|
|
20
|
-
max?: number;
|
|
21
|
-
step?: number;
|
|
22
22
|
optionLabels?: string[] | number[];
|
|
23
23
|
}, {
|
|
24
24
|
click: MouseEvent;
|
|
@@ -35,13 +35,13 @@ declare const __propDef: {
|
|
|
35
35
|
props: {
|
|
36
36
|
[x: string]: any;
|
|
37
37
|
class?: string;
|
|
38
|
+
max?: number;
|
|
39
|
+
min?: number;
|
|
40
|
+
step?: number;
|
|
38
41
|
value?: number;
|
|
39
42
|
sliderLabel?: string;
|
|
40
43
|
values?: [number, number];
|
|
41
44
|
sliderLabels?: [string, string];
|
|
42
|
-
min?: number;
|
|
43
|
-
max?: number;
|
|
44
|
-
step?: number;
|
|
45
45
|
optionLabels?: (string[] | number[]);
|
|
46
46
|
};
|
|
47
47
|
events: {
|
|
@@ -10,8 +10,8 @@ export default class Switch extends SvelteComponent<{
|
|
|
10
10
|
[x: string]: any;
|
|
11
11
|
class?: string;
|
|
12
12
|
label?: string;
|
|
13
|
-
disabled?: boolean;
|
|
14
13
|
checked?: boolean;
|
|
14
|
+
disabled?: boolean;
|
|
15
15
|
}, {
|
|
16
16
|
[evt: string]: CustomEvent<any>;
|
|
17
17
|
}, {
|
|
@@ -27,8 +27,8 @@ declare const __propDef: {
|
|
|
27
27
|
[x: string]: any;
|
|
28
28
|
class?: string;
|
|
29
29
|
label?: string;
|
|
30
|
-
disabled?: boolean;
|
|
31
30
|
checked?: boolean;
|
|
31
|
+
disabled?: boolean;
|
|
32
32
|
};
|
|
33
33
|
events: {
|
|
34
34
|
[evt: string]: CustomEvent<any>;
|
|
@@ -10,10 +10,10 @@ export default class NumberInput extends SvelteComponent<{
|
|
|
10
10
|
[x: string]: any;
|
|
11
11
|
class?: string;
|
|
12
12
|
disabled?: boolean;
|
|
13
|
-
value?: string;
|
|
14
|
-
min?: any;
|
|
15
13
|
max?: any;
|
|
14
|
+
min?: any;
|
|
16
15
|
step?: number;
|
|
16
|
+
value?: string;
|
|
17
17
|
}, {
|
|
18
18
|
keypress: KeyboardEvent;
|
|
19
19
|
input: Event;
|
|
@@ -30,10 +30,10 @@ declare const __propDef: {
|
|
|
30
30
|
[x: string]: any;
|
|
31
31
|
class?: string;
|
|
32
32
|
disabled?: boolean;
|
|
33
|
-
value?: string | null;
|
|
34
|
-
min?: any;
|
|
35
33
|
max?: any;
|
|
34
|
+
min?: any;
|
|
36
35
|
step?: number;
|
|
36
|
+
value?: string | null;
|
|
37
37
|
};
|
|
38
38
|
events: {
|
|
39
39
|
keypress: KeyboardEvent;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
<svelte:options accessors={true} />
|
|
8
8
|
|
|
9
9
|
<script>
|
|
10
|
+
import { activateKeyShortcuts } from '../util/events';
|
|
10
11
|
import { getRandomId } from '../util/util';
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -35,6 +36,12 @@
|
|
|
35
36
|
/** @type {(string | number | undefined)} */
|
|
36
37
|
export let value = undefined;
|
|
37
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Keyboard shortcuts.
|
|
41
|
+
* @type {string}
|
|
42
|
+
*/
|
|
43
|
+
export let keyShortcuts = '';
|
|
44
|
+
|
|
38
45
|
const id = getRandomId('input');
|
|
39
46
|
let ariaLabel = '';
|
|
40
47
|
|
|
@@ -66,6 +73,7 @@
|
|
|
66
73
|
on:keyup
|
|
67
74
|
on:keypress
|
|
68
75
|
on:change
|
|
76
|
+
use:activateKeyShortcuts={keyShortcuts}
|
|
69
77
|
/>
|
|
70
78
|
{#if ariaLabel}
|
|
71
79
|
<span id="{id}-label" class="label" class:hidden={!!value}>
|
|
@@ -11,10 +11,11 @@ export default class TextInput extends SvelteComponent<{
|
|
|
11
11
|
class?: string;
|
|
12
12
|
name?: string;
|
|
13
13
|
disabled?: boolean;
|
|
14
|
+
readOnly?: boolean;
|
|
14
15
|
value?: string | number;
|
|
15
16
|
element?: HTMLInputElement;
|
|
16
17
|
role?: "textbox" | "searchbox" | "combobox" | "spinbutton";
|
|
17
|
-
|
|
18
|
+
keyShortcuts?: string;
|
|
18
19
|
}, {
|
|
19
20
|
input: Event;
|
|
20
21
|
keydown: KeyboardEvent;
|
|
@@ -45,6 +46,9 @@ export default class TextInput extends SvelteComponent<{
|
|
|
45
46
|
/**accessor*/
|
|
46
47
|
set value(arg: string | number);
|
|
47
48
|
get value(): string | number;
|
|
49
|
+
/**accessor*/
|
|
50
|
+
set keyShortcuts(arg: string);
|
|
51
|
+
get keyShortcuts(): string;
|
|
48
52
|
}
|
|
49
53
|
export type TextInputProps = typeof __propDef.props;
|
|
50
54
|
export type TextInputEvents = typeof __propDef.events;
|
|
@@ -56,10 +60,11 @@ declare const __propDef: {
|
|
|
56
60
|
class?: string;
|
|
57
61
|
name?: string;
|
|
58
62
|
disabled?: boolean;
|
|
63
|
+
readOnly?: boolean;
|
|
59
64
|
value?: (string | number | undefined);
|
|
60
65
|
element?: HTMLInputElement | null;
|
|
61
66
|
role?: ('textbox' | 'searchbox' | 'combobox' | 'spinbutton');
|
|
62
|
-
|
|
67
|
+
keyShortcuts?: string;
|
|
63
68
|
};
|
|
64
69
|
events: {
|
|
65
70
|
input: Event;
|
|
@@ -7,6 +7,17 @@
|
|
|
7
7
|
<script>
|
|
8
8
|
import { onMount } from 'svelte';
|
|
9
9
|
|
|
10
|
+
const stylesheets = [
|
|
11
|
+
// https://fonts.google.com/share?selection.family=Merriweather%20Sans:ital,wght@0,300;0,600;1,300%7CNoto%20Sans%20Mono
|
|
12
|
+
'https://fonts.googleapis.com/css2?family=Merriweather+Sans:ital,wght@0,300;0,600;1,300&family=Noto+Sans+Mono&display=swap',
|
|
13
|
+
// https://fonts.google.com/icons?icon.set=Material+Symbols
|
|
14
|
+
// Use `font-display: block;` @see https://stackoverflow.com/q/41710834
|
|
15
|
+
'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block',
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
/** @type {HTMLElement} */
|
|
19
|
+
let fontLoader;
|
|
20
|
+
|
|
10
21
|
onMount(() => {
|
|
11
22
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
12
23
|
const { dataset } = document.documentElement;
|
|
@@ -28,9 +39,29 @@
|
|
|
28
39
|
mediaQuery.onchange = () => {
|
|
29
40
|
applyTheme();
|
|
30
41
|
};
|
|
42
|
+
|
|
43
|
+
window.setTimeout(() => {
|
|
44
|
+
fontLoader.remove();
|
|
45
|
+
}, 1000);
|
|
31
46
|
});
|
|
32
47
|
</script>
|
|
33
48
|
|
|
49
|
+
<svelte:head>
|
|
50
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
51
|
+
<meta name="google" content="notranslate" />
|
|
52
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
53
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous" />
|
|
54
|
+
{#each stylesheets as href}
|
|
55
|
+
<link rel="preload" {href} as="style" />
|
|
56
|
+
<link rel="stylesheet" {href} />
|
|
57
|
+
{/each}
|
|
58
|
+
</svelte:head>
|
|
59
|
+
|
|
60
|
+
<!-- Preload fonts, including the icons -->
|
|
61
|
+
<div class="font-loader" aria-hidden="true" bind:this={fontLoader}>
|
|
62
|
+
Sveltia UI <span class="material-symbols-outlined">favorite</span>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
34
65
|
<div
|
|
35
66
|
class="sui app-shell"
|
|
36
67
|
role="none"
|
|
@@ -163,7 +194,7 @@
|
|
|
163
194
|
);
|
|
164
195
|
--sui-primary-border-color: hsl(var(--sui-border-color-1-hsl));
|
|
165
196
|
--sui-secondary-border-color: hsl(var(--sui-border-color-2-hsl));
|
|
166
|
-
--sui-checkbox-border-color: hsl(var(--sui-foreground-color-
|
|
197
|
+
--sui-checkbox-border-color: hsl(var(--sui-foreground-color-4-hsl));
|
|
167
198
|
--sui-error-border-color: hsl(
|
|
168
199
|
var(--sui-error-color-hue) var(--sui-alert-border-color-saturation)
|
|
169
200
|
var(--sui-alert-border-color-lightness)
|
|
@@ -255,6 +286,7 @@
|
|
|
255
286
|
outline-color: transparent;
|
|
256
287
|
border-width: 0;
|
|
257
288
|
border-style: solid;
|
|
289
|
+
vertical-align: top;
|
|
258
290
|
}
|
|
259
291
|
|
|
260
292
|
:global(:focus) {
|
|
@@ -285,12 +317,6 @@
|
|
|
285
317
|
text-decoration: none;
|
|
286
318
|
}
|
|
287
319
|
|
|
288
|
-
:global(img),
|
|
289
|
-
:global(svg),
|
|
290
|
-
:global(iframe) {
|
|
291
|
-
vertical-align: top;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
320
|
:global(p),
|
|
295
321
|
:global(li) {
|
|
296
322
|
line-height: var(--sui-line-height-comfortable);
|
|
@@ -329,6 +355,11 @@
|
|
|
329
355
|
background: transparent;
|
|
330
356
|
}
|
|
331
357
|
|
|
358
|
+
:global(.font-loader) {
|
|
359
|
+
position: absolute;
|
|
360
|
+
left: -99999px;
|
|
361
|
+
}
|
|
362
|
+
|
|
332
363
|
:global(.app-shell) {
|
|
333
364
|
position: fixed;
|
|
334
365
|
inset: 0;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if the user agent is macOS.
|
|
3
|
+
* @returns {boolean} Result.
|
|
4
|
+
*/
|
|
5
|
+
export const isMac = () =>
|
|
6
|
+
/** @type {any} */ (navigator).userAgentData?.platform === 'macOS' ||
|
|
7
|
+
navigator.platform.startsWith('Mac');
|
|
8
|
+
|
|
9
|
+
/**
|
|
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`.
|
|
13
|
+
* @returns {boolean} Result.
|
|
14
|
+
* @see https://w3c.github.io/aria/#aria-keyshortcuts
|
|
15
|
+
*/
|
|
16
|
+
export const matchShortcuts = (event, shortcuts) => {
|
|
17
|
+
const { ctrlKey, metaKey, altKey, shiftKey, key } = event;
|
|
18
|
+
|
|
19
|
+
return shortcuts.split(/\s+/).some((shortcut) => {
|
|
20
|
+
const keys = shortcut.split('+');
|
|
21
|
+
|
|
22
|
+
// Check if required modifier keys are pressed
|
|
23
|
+
if (
|
|
24
|
+
(keys.includes('Ctrl') && !ctrlKey) ||
|
|
25
|
+
(keys.includes('Meta') && !metaKey) ||
|
|
26
|
+
(keys.includes('Alt') && !altKey) ||
|
|
27
|
+
(keys.includes('Shift') && !shiftKey)
|
|
28
|
+
) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Check if unnecessary modifier keys are not pressed
|
|
33
|
+
if (
|
|
34
|
+
(!keys.includes('Ctrl') && ctrlKey) ||
|
|
35
|
+
(!keys.includes('Meta') && metaKey) ||
|
|
36
|
+
(!keys.includes('Alt') && altKey) ||
|
|
37
|
+
(!keys.includes('Shift') && shiftKey)
|
|
38
|
+
) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return keys
|
|
43
|
+
.filter((_key) => !['Ctrl', 'Meta', 'Alt', 'Shift'].includes(_key))
|
|
44
|
+
.every((_key) => _key.toUpperCase() === key.toUpperCase());
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
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 text
|
|
52
|
+
* field or button. Multiple shortcuts can be defined space-separated. The `Accel` modifier will be
|
|
53
|
+
* replaced with `Ctrl` on Windows/Linux and `Command` on macOS.
|
|
54
|
+
* @returns {import('svelte/action').ActionReturn} Actions.
|
|
55
|
+
*/
|
|
56
|
+
export const activateKeyShortcuts = (element, shortcuts) => {
|
|
57
|
+
let platformKeyShortcuts;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Handle the event.
|
|
61
|
+
* @param {KeyboardEvent} event `keydown` event.
|
|
62
|
+
*/
|
|
63
|
+
const handler = (event) => {
|
|
64
|
+
if (!!element.offsetParent && matchShortcuts(event, platformKeyShortcuts)) {
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
|
|
67
|
+
if (!element.disabled) {
|
|
68
|
+
element.focus();
|
|
69
|
+
element.click();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Remove the event listener.
|
|
76
|
+
*/
|
|
77
|
+
const removeListener = () => {
|
|
78
|
+
window.removeEventListener('keydown', handler);
|
|
79
|
+
element.removeAttribute('aria-keyshortcuts');
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Add the event listener.
|
|
84
|
+
*/
|
|
85
|
+
const addListener = () => {
|
|
86
|
+
platformKeyShortcuts = shortcuts
|
|
87
|
+
? shortcuts.replace(/\bAccel\b/g, isMac() ? 'Meta' : 'Ctrl')
|
|
88
|
+
: undefined;
|
|
89
|
+
|
|
90
|
+
if (platformKeyShortcuts) {
|
|
91
|
+
window.addEventListener('keydown', handler);
|
|
92
|
+
element.setAttribute('aria-keyshortcuts', platformKeyShortcuts);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
addListener();
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
// eslint-disable-next-line jsdoc/require-jsdoc, no-shadow, no-unused-vars
|
|
100
|
+
update(shortcuts) {
|
|
101
|
+
removeListener();
|
|
102
|
+
addListener();
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
106
|
+
destroy() {
|
|
107
|
+
removeListener();
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
};
|
package/package/styles/core.scss
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
outline-color: transparent;
|
|
25
25
|
border-width: 0;
|
|
26
26
|
border-style: solid;
|
|
27
|
+
vertical-align: top;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
:focus {
|
|
@@ -54,12 +55,6 @@ a {
|
|
|
54
55
|
text-decoration: none;
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
img,
|
|
58
|
-
svg,
|
|
59
|
-
iframe {
|
|
60
|
-
vertical-align: top;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
58
|
p,
|
|
64
59
|
li {
|
|
65
60
|
line-height: var(--sui-line-height-comfortable);
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
// Borders
|
|
118
118
|
--sui-primary-border-color: hsl(var(--sui-border-color-1-hsl));
|
|
119
119
|
--sui-secondary-border-color: hsl(var(--sui-border-color-2-hsl));
|
|
120
|
-
--sui-checkbox-border-color: hsl(var(--sui-foreground-color-
|
|
120
|
+
--sui-checkbox-border-color: hsl(var(--sui-foreground-color-4-hsl));
|
|
121
121
|
--sui-error-border-color: hsl(
|
|
122
122
|
var(--sui-error-color-hue) var(--sui-alert-border-color-saturation)
|
|
123
123
|
var(--sui-alert-border-color-lightness)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltia/ui",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -291,6 +291,10 @@
|
|
|
291
291
|
"svelte": "./package/components/util/app-shell.svelte",
|
|
292
292
|
"default": "./package/components/util/app-shell.svelte"
|
|
293
293
|
},
|
|
294
|
+
"./components/util/events": {
|
|
295
|
+
"types": "./package/components/util/events.d.ts",
|
|
296
|
+
"default": "./package/components/util/events.js"
|
|
297
|
+
},
|
|
294
298
|
"./components/util/group": {
|
|
295
299
|
"types": "./package/components/util/group.d.ts",
|
|
296
300
|
"default": "./package/components/util/group.js"
|
|
@@ -485,6 +489,9 @@
|
|
|
485
489
|
"components/util/app-shell.svelte": [
|
|
486
490
|
"./package/components/util/app-shell.svelte.d.ts"
|
|
487
491
|
],
|
|
492
|
+
"components/util/events": [
|
|
493
|
+
"./package/components/util/events.d.ts"
|
|
494
|
+
],
|
|
488
495
|
"components/util/group": [
|
|
489
496
|
"./package/components/util/group.d.ts"
|
|
490
497
|
],
|