@sveltia/ui 0.2.4 → 0.3.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/{core → button}/button.svelte +2 -1
- package/package/components/{core → button}/button.svelte.d.ts +6 -5
- package/package/components/{composite → button}/select-button-group.svelte +8 -5
- package/package/components/{composite → button}/select-button-group.svelte.d.ts +6 -6
- package/package/components/{core → button}/select-button.svelte +2 -2
- package/package/components/{core → button}/select-button.svelte.d.ts +2 -2
- package/package/components/{composite → calendar}/calendar.svelte +9 -5
- package/package/components/{composite → calendar}/calendar.svelte.d.ts +1 -0
- package/package/components/{composite → checkbox}/checkbox-group.svelte +3 -2
- package/package/components/{composite → checkbox}/checkbox-group.svelte.d.ts +2 -2
- package/package/components/{core → checkbox}/checkbox.svelte +38 -17
- package/package/components/{core → checkbox}/checkbox.svelte.d.ts +7 -3
- package/package/components/{core → dialog}/dialog.svelte +5 -4
- package/package/components/{core → dialog}/dialog.svelte.d.ts +2 -1
- package/package/components/{composite → disclosure}/disclosure.svelte +5 -4
- package/package/components/{composite → disclosure}/disclosure.svelte.d.ts +2 -1
- package/package/components/{core/separator.svelte → divider/divider.svelte} +5 -4
- package/package/components/divider/divider.svelte.d.ts +29 -0
- package/package/components/{core → divider}/spacer.svelte +4 -0
- package/package/components/{core → divider}/spacer.svelte.d.ts +1 -0
- package/package/components/{core → drawer}/drawer.svelte +5 -4
- package/package/components/{core → drawer}/drawer.svelte.d.ts +2 -1
- package/package/components/{core → icon}/icon.svelte +5 -0
- package/package/components/{core → icon}/icon.svelte.d.ts +6 -2
- package/package/components/listbox/listbox.svelte +74 -0
- package/package/components/{composite → listbox}/listbox.svelte.d.ts +3 -1
- package/package/components/listbox/option-group.svelte +47 -0
- package/package/components/listbox/option-group.svelte.d.ts +38 -0
- package/package/components/{core → listbox}/option.svelte +34 -2
- package/package/components/{core → listbox}/option.svelte.d.ts +7 -3
- package/package/components/{core → menu}/menu-button.svelte +3 -17
- package/package/components/{core → menu}/menu-button.svelte.d.ts +4 -1
- package/package/components/{core → menu}/menu-item-checkbox.svelte +1 -0
- package/package/components/{core → menu}/menu-item-checkbox.svelte.d.ts +4 -1
- package/package/components/{composite → menu}/menu-item-group.svelte +5 -1
- package/package/components/{composite → menu}/menu-item-group.svelte.d.ts +1 -0
- package/package/components/{core → menu}/menu-item-radio.svelte +2 -0
- package/package/components/{core → menu}/menu-item-radio.svelte.d.ts +5 -1
- package/package/components/{core → menu}/menu-item.svelte +6 -6
- package/package/components/{core → menu}/menu-item.svelte.d.ts +4 -1
- package/package/components/{composite → menu}/menu.svelte +3 -2
- package/package/components/{composite → menu}/menu.svelte.d.ts +2 -1
- package/package/components/{composite/radio-button-group.svelte → radio/radio-group.svelte} +15 -10
- package/package/components/radio/radio-group.svelte.d.ts +40 -0
- package/package/components/{core/radio-button.svelte → radio/radio.svelte} +45 -18
- package/package/components/radio/radio.svelte.d.ts +43 -0
- package/package/components/{composite → select}/combobox.svelte +7 -6
- package/package/components/{composite → select}/combobox.svelte.d.ts +4 -3
- package/package/components/{composite → select}/select.svelte +3 -1
- package/package/components/{composite → select}/select.svelte.d.ts +7 -3
- package/package/components/{core → slider}/slider.svelte +82 -57
- package/package/components/{core → slider}/slider.svelte.d.ts +12 -10
- package/package/components/{core → switch}/switch.svelte +36 -19
- package/package/components/{core → switch}/switch.svelte.d.ts +4 -3
- package/package/components/table/table-body.svelte +23 -0
- package/package/components/table/table-body.svelte.d.ts +34 -0
- package/package/components/table/table-cell.svelte +23 -0
- package/package/components/table/table-cell.svelte.d.ts +34 -0
- package/package/components/table/table-col-header.svelte +23 -0
- package/package/components/table/table-col-header.svelte.d.ts +34 -0
- package/package/components/table/table-foot.svelte +23 -0
- package/package/components/table/table-foot.svelte.d.ts +34 -0
- package/package/components/table/table-head.svelte +23 -0
- package/package/components/table/table-head.svelte.d.ts +34 -0
- package/package/components/table/table-row-header.svelte +23 -0
- package/package/components/table/table-row-header.svelte.d.ts +34 -0
- package/package/components/table/table-row.svelte +23 -0
- package/package/components/table/table-row.svelte.d.ts +38 -0
- package/package/components/table/table.svelte +44 -0
- package/package/components/table/table.svelte.d.ts +36 -0
- package/package/components/{composite → tabs}/tab-list.svelte +3 -2
- package/package/components/{composite → tabs}/tab-list.svelte.d.ts +7 -6
- package/package/components/{core → tabs}/tab-panel.svelte +2 -1
- package/package/components/{core → tabs}/tab-panel.svelte.d.ts +2 -1
- package/package/components/{core → tabs}/tab.svelte +3 -2
- package/package/components/{core → tabs}/tab.svelte.d.ts +2 -1
- package/package/components/{editor/markdown.svelte → text-field/markdown-editor.svelte} +10 -6
- package/package/components/text-field/markdown-editor.svelte.d.ts +26 -0
- package/package/components/{core → text-field}/number-input.svelte +22 -12
- package/package/components/{core → text-field}/number-input.svelte.d.ts +7 -3
- package/package/components/{core → text-field}/password-input.svelte +5 -2
- package/package/components/{core → text-field}/password-input.svelte.d.ts +8 -3
- package/package/components/{core → text-field}/search-bar.svelte +5 -2
- package/package/components/{core → text-field}/search-bar.svelte.d.ts +8 -3
- package/package/components/{core → text-field}/text-area.svelte +2 -0
- package/package/components/{core → text-field}/text-area.svelte.d.ts +9 -5
- package/package/components/{core → text-field}/text-input.svelte +3 -1
- package/package/components/{core → text-field}/text-input.svelte.d.ts +11 -7
- package/package/components/{core → toolbar}/toolbar.svelte +2 -1
- package/package/components/{core → toolbar}/toolbar.svelte.d.ts +3 -2
- package/package/components/util/app-shell.svelte +10 -36
- package/package/components/util/group.js +305 -0
- package/package/components/{core → util}/group.svelte +5 -11
- package/package/components/{core → util}/group.svelte.d.ts +4 -2
- package/package/components/util/popup.d.ts +30 -0
- package/package/components/{helpers → util}/popup.js +36 -26
- package/package/components/util/popup.svelte +14 -5
- package/package/components/util/{misc.d.ts → util.d.ts} +1 -0
- package/package/components/util/{misc.js → util.js} +15 -0
- package/package/index.d.ts +46 -41
- package/package/index.js +48 -83
- package/package/styles/core.scss +5 -34
- package/package/styles/variables.scss +5 -4
- package/package.json +362 -328
- package/package/components/composite/grid.svelte +0 -24
- package/package/components/composite/grid.svelte.d.ts +0 -31
- package/package/components/composite/listbox.svelte +0 -63
- package/package/components/composite/radio-button-group.svelte.d.ts +0 -36
- package/package/components/core/grid-cell.svelte +0 -13
- package/package/components/core/grid-cell.svelte.d.ts +0 -29
- package/package/components/core/radio-button.svelte.d.ts +0 -37
- package/package/components/core/row-group.svelte +0 -13
- package/package/components/core/row-group.svelte.d.ts +0 -29
- package/package/components/core/row.svelte +0 -13
- package/package/components/core/row.svelte.d.ts +0 -33
- package/package/components/core/separator.svelte.d.ts +0 -26
- package/package/components/editor/markdown.svelte.d.ts +0 -25
- package/package/components/helpers/group.js +0 -251
- package/package/components/helpers/popup.d.ts +0 -30
- package/package/components/helpers/util.d.ts +0 -1
- package/package/components/helpers/util.js +0 -14
- /package/package/components/{helpers → util}/group.d.ts +0 -0
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component
|
|
3
|
+
The equivalent of the HTML `<input type="radio">` element.
|
|
4
|
+
@see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio
|
|
3
5
|
@see https://w3c.github.io/aria/#radio
|
|
4
|
-
@see https://
|
|
6
|
+
@see https://www.w3.org/WAI/ARIA/apg/patterns/radio/
|
|
5
7
|
-->
|
|
6
8
|
<script>
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
9
|
+
import Button from '../button/button.svelte';
|
|
10
|
+
import Icon from '../icon/icon.svelte';
|
|
11
|
+
import { getRandomId } from '../util/util';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* CSS class name on the button.
|
|
@@ -19,12 +21,18 @@
|
|
|
19
21
|
/** @type {string} */
|
|
20
22
|
export let name = '';
|
|
21
23
|
|
|
24
|
+
/** @type {string?} */
|
|
25
|
+
export let label = undefined;
|
|
26
|
+
|
|
22
27
|
/** @type {string?} */
|
|
23
28
|
export let value = undefined;
|
|
24
29
|
|
|
25
30
|
/** @type {boolean} */
|
|
26
31
|
export let selected = false;
|
|
27
32
|
|
|
33
|
+
/** @type {boolean} */
|
|
34
|
+
export let disabled = false;
|
|
35
|
+
|
|
28
36
|
const id = getRandomId('checkbox');
|
|
29
37
|
/** @type {Button} */
|
|
30
38
|
let buttonComponent;
|
|
@@ -36,7 +44,7 @@
|
|
|
36
44
|
|
|
37
45
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
38
46
|
<span
|
|
39
|
-
class="sui radio
|
|
47
|
+
class="sui radio {className}"
|
|
40
48
|
on:click={(event) => {
|
|
41
49
|
if (!(/** @type {HTMLElement} */ (event.target).matches('button'))) {
|
|
42
50
|
buttonComponent.element.click();
|
|
@@ -45,23 +53,32 @@
|
|
|
45
53
|
>
|
|
46
54
|
<Button
|
|
47
55
|
{id}
|
|
56
|
+
{disabled}
|
|
57
|
+
{name}
|
|
58
|
+
{value}
|
|
48
59
|
role="radio"
|
|
49
60
|
aria-checked={selected}
|
|
50
61
|
aria-labelledby="{id}-label"
|
|
51
62
|
bind:this={buttonComponent}
|
|
52
63
|
on:click={(event) => {
|
|
53
64
|
event.preventDefault();
|
|
54
|
-
selected =
|
|
65
|
+
selected = true;
|
|
55
66
|
}}
|
|
56
67
|
>
|
|
57
68
|
<Icon slot="start-icon" name="circle" />
|
|
58
69
|
</Button>
|
|
59
|
-
|
|
60
|
-
<
|
|
61
|
-
|
|
70
|
+
{#if $$slots.default || label}
|
|
71
|
+
<label id="{id}-label">
|
|
72
|
+
{#if $$slots.default}
|
|
73
|
+
<slot />
|
|
74
|
+
{:else}
|
|
75
|
+
{label}
|
|
76
|
+
{/if}
|
|
77
|
+
</label>
|
|
78
|
+
{/if}
|
|
62
79
|
</span>
|
|
63
80
|
|
|
64
|
-
<style>.radio
|
|
81
|
+
<style>.radio {
|
|
65
82
|
display: inline-flex;
|
|
66
83
|
align-items: center;
|
|
67
84
|
gap: 8px;
|
|
@@ -70,24 +87,34 @@
|
|
|
70
87
|
-webkit-user-select: none;
|
|
71
88
|
user-select: none;
|
|
72
89
|
}
|
|
73
|
-
.radio
|
|
90
|
+
.radio.disabled {
|
|
91
|
+
cursor: default;
|
|
92
|
+
}
|
|
93
|
+
.radio.disabled label {
|
|
94
|
+
color: var(--disabled-foreground-color);
|
|
95
|
+
}
|
|
96
|
+
.radio :global(button) {
|
|
74
97
|
justify-content: center;
|
|
75
98
|
overflow: hidden;
|
|
76
99
|
border-width: 2px;
|
|
77
|
-
border-color: var(--
|
|
100
|
+
border-color: var(--checkbox-border-color);
|
|
78
101
|
border-radius: 24px;
|
|
79
|
-
width:
|
|
80
|
-
height:
|
|
102
|
+
width: 20px;
|
|
103
|
+
height: 20px;
|
|
81
104
|
color: var(--primary-accent-color-lighter);
|
|
82
105
|
transition: all 200ms;
|
|
83
106
|
}
|
|
84
|
-
.radio
|
|
85
|
-
font-size:
|
|
107
|
+
.radio :global(button) :global(.icon) {
|
|
108
|
+
font-size: 14px;
|
|
86
109
|
font-variation-settings: "FILL" 1, "wght" 400, "GRAD" 0, "opsz" 48;
|
|
87
110
|
}
|
|
88
|
-
.radio
|
|
111
|
+
.radio :global(button[aria-checked="true"]) {
|
|
112
|
+
border-color: var(--primary-accent-color-lighter);
|
|
89
113
|
color: var(--primary-accent-color-lighter);
|
|
90
114
|
}
|
|
91
|
-
.radio
|
|
115
|
+
.radio :global(button[aria-checked="false"]) {
|
|
92
116
|
color: transparent;
|
|
117
|
+
}
|
|
118
|
+
.radio label {
|
|
119
|
+
cursor: inherit;
|
|
93
120
|
}</style>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} RadioProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} RadioEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} RadioSlots */
|
|
4
|
+
/**
|
|
5
|
+
* The equivalent of the HTML `<input type="radio">` element.
|
|
6
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio
|
|
7
|
+
* @see https://w3c.github.io/aria/#radio
|
|
8
|
+
* @see https://www.w3.org/WAI/ARIA/apg/patterns/radio/
|
|
9
|
+
*/
|
|
10
|
+
export default class Radio extends SvelteComponentTyped<{
|
|
11
|
+
label?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
name?: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
class?: string;
|
|
16
|
+
selected?: boolean;
|
|
17
|
+
}, {
|
|
18
|
+
[evt: string]: CustomEvent<any>;
|
|
19
|
+
}, {
|
|
20
|
+
default: {};
|
|
21
|
+
}> {
|
|
22
|
+
}
|
|
23
|
+
export type RadioProps = typeof __propDef.props;
|
|
24
|
+
export type RadioEvents = typeof __propDef.events;
|
|
25
|
+
export type RadioSlots = typeof __propDef.slots;
|
|
26
|
+
import { SvelteComponentTyped } from "svelte";
|
|
27
|
+
declare const __propDef: {
|
|
28
|
+
props: {
|
|
29
|
+
label?: string | null;
|
|
30
|
+
disabled?: boolean;
|
|
31
|
+
name?: string;
|
|
32
|
+
value?: string | null;
|
|
33
|
+
class?: string;
|
|
34
|
+
selected?: boolean;
|
|
35
|
+
};
|
|
36
|
+
events: {
|
|
37
|
+
[evt: string]: CustomEvent<any>;
|
|
38
|
+
};
|
|
39
|
+
slots: {
|
|
40
|
+
default: {};
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export {};
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component
|
|
3
|
+
A variant of the `<Select>` widget with an auto-complete text input field.
|
|
3
4
|
@see https://w3c.github.io/aria/#combobox
|
|
4
|
-
@see https://
|
|
5
|
+
@see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
|
|
5
6
|
-->
|
|
6
7
|
<script>
|
|
7
8
|
import { createEventDispatcher } from 'svelte';
|
|
8
9
|
import { _ } from 'svelte-i18n';
|
|
9
10
|
import { writable } from 'svelte/store';
|
|
10
|
-
import Button from '../
|
|
11
|
-
import Icon from '../
|
|
12
|
-
import
|
|
13
|
-
import
|
|
11
|
+
import Button from '../button/button.svelte';
|
|
12
|
+
import Icon from '../icon/icon.svelte';
|
|
13
|
+
import Listbox from '../listbox/listbox.svelte';
|
|
14
|
+
import TextInput from '../text-field/text-input.svelte';
|
|
14
15
|
import Popup from '../util/popup.svelte';
|
|
15
|
-
import
|
|
16
|
+
import { getRandomId } from '../util/util';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* CSS class name on the button.
|
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
/** @typedef {typeof __propDef.events} ComboboxEvents */
|
|
3
3
|
/** @typedef {typeof __propDef.slots} ComboboxSlots */
|
|
4
4
|
/**
|
|
5
|
+
* A variant of the `<Select>` widget with an auto-complete text input field.
|
|
5
6
|
* @see https://w3c.github.io/aria/#combobox
|
|
6
|
-
* @see https://
|
|
7
|
+
* @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
|
|
7
8
|
*/
|
|
8
9
|
export default class Combobox extends SvelteComponentTyped<{
|
|
9
10
|
[x: string]: any;
|
|
10
11
|
label?: string;
|
|
11
12
|
position?: PopupPosition;
|
|
12
|
-
class?: string;
|
|
13
13
|
disabled?: boolean;
|
|
14
14
|
value?: string | number;
|
|
15
|
+
class?: string;
|
|
15
16
|
readOnly?: boolean;
|
|
16
17
|
}, {
|
|
17
18
|
change: CustomEvent<any>;
|
|
@@ -30,9 +31,9 @@ declare const __propDef: {
|
|
|
30
31
|
[x: string]: any;
|
|
31
32
|
label?: string;
|
|
32
33
|
position?: PopupPosition;
|
|
33
|
-
class?: string;
|
|
34
34
|
disabled?: boolean;
|
|
35
35
|
value?: (string | number | undefined);
|
|
36
|
+
class?: string;
|
|
36
37
|
readOnly?: boolean;
|
|
37
38
|
};
|
|
38
39
|
events: {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component
|
|
3
|
-
A read-only variant of `<Combobox>`.
|
|
3
|
+
A read-only variant of `<Combobox>`. The equivalent of the HTML `<select>` element.
|
|
4
|
+
@see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select
|
|
5
|
+
@see https://w3c.github.io/aria/#combobox
|
|
4
6
|
-->
|
|
5
7
|
<script>
|
|
6
8
|
import Combobox from './combobox.svelte';
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/** @typedef {typeof __propDef.props} SelectProps */
|
|
2
2
|
/** @typedef {typeof __propDef.events} SelectEvents */
|
|
3
3
|
/** @typedef {typeof __propDef.slots} SelectSlots */
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* A read-only variant of `<Combobox>`. The equivalent of the HTML `<select>` element.
|
|
6
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select
|
|
7
|
+
* @see https://w3c.github.io/aria/#combobox
|
|
8
|
+
*/
|
|
5
9
|
export default class Select extends SvelteComponentTyped<{
|
|
6
10
|
[x: string]: any;
|
|
7
11
|
label?: string;
|
|
8
|
-
class?: string;
|
|
9
12
|
value?: string;
|
|
13
|
+
class?: string;
|
|
10
14
|
}, {
|
|
11
15
|
change: CustomEvent<any>;
|
|
12
16
|
} & {
|
|
@@ -23,8 +27,8 @@ declare const __propDef: {
|
|
|
23
27
|
props: {
|
|
24
28
|
[x: string]: any;
|
|
25
29
|
label?: string;
|
|
26
|
-
class?: string;
|
|
27
30
|
value?: string | null;
|
|
31
|
+
class?: string;
|
|
28
32
|
};
|
|
29
33
|
events: {
|
|
30
34
|
change: CustomEvent<any>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component
|
|
3
|
+
The equivalent of the HTML `<input type="range">` element, but it comes with the multi-thumb
|
|
4
|
+
support.
|
|
3
5
|
@see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/range
|
|
4
6
|
@see https://w3c.github.io/aria/#slider
|
|
5
7
|
@see https://www.w3.org/WAI/ARIA/apg/patterns/slider/
|
|
@@ -18,11 +20,14 @@
|
|
|
18
20
|
|
|
19
21
|
export let value = 0;
|
|
20
22
|
export let sliderLabel = '';
|
|
23
|
+
/** @type {[number, number]} */
|
|
21
24
|
export let values = undefined;
|
|
22
|
-
|
|
25
|
+
/** @type {[string, string]} */
|
|
26
|
+
export let sliderLabels = undefined;
|
|
23
27
|
export let min = 0;
|
|
24
28
|
export let max = 100;
|
|
25
29
|
export let step = 1;
|
|
30
|
+
/** @type {(string[] | number[])} */
|
|
26
31
|
export let optionLabels = [];
|
|
27
32
|
|
|
28
33
|
$: multiThumb = !!values;
|
|
@@ -40,57 +45,59 @@
|
|
|
40
45
|
let targetValueIndex = 0;
|
|
41
46
|
|
|
42
47
|
/**
|
|
43
|
-
*
|
|
44
|
-
* @param {number} diff
|
|
48
|
+
* Move a thumb with mouse.
|
|
49
|
+
* @param {number} diff Distance from the original X position in pixels.
|
|
45
50
|
*/
|
|
46
|
-
const
|
|
47
|
-
if (diff
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
const moveThumb = (diff) => {
|
|
52
|
+
if (diff < 0) {
|
|
53
|
+
diff = 0;
|
|
54
|
+
} else if (diff > barWidth) {
|
|
55
|
+
diff = barWidth;
|
|
56
|
+
}
|
|
50
57
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
? fromIndex
|
|
54
|
-
: toIndex;
|
|
58
|
+
const fromIndex = positionList.findLastIndex((s) => s <= diff);
|
|
59
|
+
const toIndex = positionList.findIndex((s) => diff <= s);
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
(targetValueIndex === 1 && sliderPositions[0] >= positionList[index])))
|
|
61
|
-
) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
61
|
+
const index =
|
|
62
|
+
Math.abs(positionList[fromIndex] - diff) < Math.abs(positionList[toIndex] - diff)
|
|
63
|
+
? fromIndex
|
|
64
|
+
: toIndex;
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
if (
|
|
67
|
+
sliderPositions[targetValueIndex] === positionList[index] ||
|
|
68
|
+
(multiThumb &&
|
|
69
|
+
((targetValueIndex === 0 && sliderPositions[1] <= positionList[index]) ||
|
|
70
|
+
(targetValueIndex === 1 && sliderPositions[0] >= positionList[index])))
|
|
71
|
+
) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
66
74
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
value = valueList[index];
|
|
72
|
-
dispatch('change', { value });
|
|
73
|
-
}
|
|
75
|
+
if (multiThumb) {
|
|
76
|
+
values[targetValueIndex] = valueList[index];
|
|
77
|
+
} else {
|
|
78
|
+
value = valueList[index];
|
|
74
79
|
}
|
|
75
80
|
};
|
|
76
81
|
|
|
77
82
|
/**
|
|
78
|
-
*
|
|
83
|
+
* Handle the `keydown` event fired on the slider.
|
|
79
84
|
* @param {KeyboardEvent} event `keydown` event.
|
|
80
|
-
* @param {number} [valueIndex]
|
|
85
|
+
* @param {number} [valueIndex] Index in the {@link values} array to be used to get/set the value.
|
|
81
86
|
*/
|
|
82
87
|
const onKeyDown = (event, valueIndex = 0) => {
|
|
83
|
-
const { key,
|
|
88
|
+
const { key, ctrlKey, metaKey, shiftKey, altKey } = event;
|
|
89
|
+
const hasModifier = shiftKey || altKey || ctrlKey || metaKey;
|
|
84
90
|
|
|
85
|
-
if (
|
|
91
|
+
if (hasModifier) {
|
|
86
92
|
return;
|
|
87
93
|
}
|
|
88
94
|
|
|
95
|
+
const _value = multiThumb ? values[valueIndex] : value;
|
|
89
96
|
let index = -1;
|
|
90
97
|
|
|
91
98
|
if (['ArrowDown', 'ArrowLeft'].includes(key)) {
|
|
92
|
-
if (
|
|
93
|
-
index = valueList.indexOf(
|
|
99
|
+
if (_value > min) {
|
|
100
|
+
index = valueList.indexOf(_value) - 1;
|
|
94
101
|
}
|
|
95
102
|
|
|
96
103
|
event.preventDefault();
|
|
@@ -98,8 +105,8 @@
|
|
|
98
105
|
}
|
|
99
106
|
|
|
100
107
|
if (['ArrowUp', 'ArrowRight'].includes(key)) {
|
|
101
|
-
if (
|
|
102
|
-
index = valueList.indexOf(
|
|
108
|
+
if (_value < max) {
|
|
109
|
+
index = valueList.indexOf(_value) + 1;
|
|
103
110
|
}
|
|
104
111
|
|
|
105
112
|
event.preventDefault();
|
|
@@ -115,22 +122,18 @@
|
|
|
115
122
|
return;
|
|
116
123
|
}
|
|
117
124
|
|
|
118
|
-
sliderPositions[valueIndex] = positionList[index];
|
|
119
|
-
|
|
120
125
|
if (multiThumb) {
|
|
121
126
|
values[valueIndex] = valueList[index];
|
|
122
|
-
dispatch('change', { values });
|
|
123
127
|
} else {
|
|
124
128
|
value = valueList[index];
|
|
125
|
-
dispatch('change', { value });
|
|
126
129
|
}
|
|
127
130
|
}
|
|
128
131
|
};
|
|
129
132
|
|
|
130
133
|
/**
|
|
131
|
-
*
|
|
134
|
+
* Handle the `mousedown` event fired on the slider.
|
|
132
135
|
* @param {MouseEvent} event `mousedown` event.
|
|
133
|
-
* @param {number} [valueIndex]
|
|
136
|
+
* @param {number} [valueIndex] Index in the {@link values} array to be used to get/set the value.
|
|
134
137
|
*/
|
|
135
138
|
const onMouseDown = (event, valueIndex = 0) => {
|
|
136
139
|
const { clientX, screenX } = event;
|
|
@@ -142,22 +145,31 @@
|
|
|
142
145
|
};
|
|
143
146
|
|
|
144
147
|
/**
|
|
145
|
-
*
|
|
148
|
+
* Handle the `mousemove` event fired anywhere on the page.
|
|
146
149
|
* @param {MouseEvent} event `mousemove` event.
|
|
147
150
|
*/
|
|
148
151
|
const onMouseMove = (event) => {
|
|
149
152
|
if (dragging) {
|
|
150
|
-
|
|
153
|
+
moveThumb(startX + (event.screenX - startScreenX));
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Handle the `mouseup` event fired anywhere on the page.
|
|
159
|
+
*/
|
|
160
|
+
const onMouseUp = () => {
|
|
161
|
+
if (dragging) {
|
|
162
|
+
dragging = false;
|
|
151
163
|
}
|
|
152
164
|
};
|
|
153
165
|
|
|
154
166
|
/**
|
|
155
|
-
*
|
|
167
|
+
* Handle the `click` event fired on the slider.
|
|
156
168
|
* @param {MouseEvent} event `click` event.
|
|
157
169
|
*/
|
|
158
170
|
const onClick = (event) => {
|
|
159
171
|
if (!multiThumb && !dragging) {
|
|
160
|
-
|
|
172
|
+
moveThumb(/** @type {any} */ (event).layerX);
|
|
161
173
|
}
|
|
162
174
|
|
|
163
175
|
if (dragging) {
|
|
@@ -165,6 +177,20 @@
|
|
|
165
177
|
}
|
|
166
178
|
};
|
|
167
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Update the thumb position and fire the `change` event when the value is changed.
|
|
182
|
+
*/
|
|
183
|
+
const onValueChange = () => {
|
|
184
|
+
if (multiThumb) {
|
|
185
|
+
sliderPositions[0] = positionList[valueList.indexOf(values[0])];
|
|
186
|
+
sliderPositions[1] = positionList[valueList.indexOf(values[1])];
|
|
187
|
+
dispatch('change', { values });
|
|
188
|
+
} else {
|
|
189
|
+
sliderPositions[0] = positionList[valueList.indexOf(value)];
|
|
190
|
+
dispatch('change', { value });
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
168
194
|
onMount(() => {
|
|
169
195
|
barWidth = base.clientWidth;
|
|
170
196
|
|
|
@@ -174,17 +200,16 @@
|
|
|
174
200
|
valueList = new Array(stepCount).fill(0).map((_, index) => index * step + min, 10);
|
|
175
201
|
positionList = new Array(stepCount).fill(0).map((_, index) => index * stepWidth);
|
|
176
202
|
|
|
177
|
-
|
|
178
|
-
sliderPositions[0] = positionList[valueList.indexOf(values[0])];
|
|
179
|
-
sliderPositions[1] = positionList[valueList.indexOf(values[1])];
|
|
180
|
-
} else {
|
|
181
|
-
sliderPositions[0] = positionList[valueList.indexOf(value)];
|
|
182
|
-
}
|
|
203
|
+
onValueChange();
|
|
183
204
|
});
|
|
205
|
+
|
|
206
|
+
// @ts-ignore Arguments are triggers
|
|
207
|
+
$: onValueChange(value, values);
|
|
184
208
|
</script>
|
|
185
209
|
|
|
186
210
|
<svelte:body
|
|
187
211
|
on:mousemove={onMouseMove}
|
|
212
|
+
on:mouseup={onMouseUp}
|
|
188
213
|
on:click={() => {
|
|
189
214
|
dragging = false;
|
|
190
215
|
}}
|
|
@@ -206,12 +231,12 @@
|
|
|
206
231
|
style:width="{multiThumb ? sliderPositions[1] - sliderPositions[0] : sliderPositions[0]}px"
|
|
207
232
|
/>
|
|
208
233
|
<div
|
|
209
|
-
role="slider"
|
|
210
234
|
tabindex="0"
|
|
211
|
-
|
|
235
|
+
role="slider"
|
|
236
|
+
aria-label={multiThumb ? sliderLabels?.[0] || '' : sliderLabel}
|
|
212
237
|
aria-valuemin={min}
|
|
213
238
|
aria-valuemax={max}
|
|
214
|
-
aria-valuenow={value}
|
|
239
|
+
aria-valuenow={multiThumb ? values[0] : value}
|
|
215
240
|
style:left="{sliderPositions[0]}px"
|
|
216
241
|
on:mousedown={(event) => {
|
|
217
242
|
onMouseDown(event, 0);
|
|
@@ -222,12 +247,12 @@
|
|
|
222
247
|
/>
|
|
223
248
|
{#if multiThumb}
|
|
224
249
|
<div
|
|
225
|
-
role="slider"
|
|
226
250
|
tabindex="0"
|
|
227
|
-
|
|
251
|
+
role="slider"
|
|
252
|
+
aria-label={sliderLabels?.[1] || ''}
|
|
228
253
|
aria-valuemin={min}
|
|
229
254
|
aria-valuemax={max}
|
|
230
|
-
aria-valuenow={
|
|
255
|
+
aria-valuenow={values[1]}
|
|
231
256
|
style:left="{sliderPositions[1]}px"
|
|
232
257
|
on:mousedown={(event) => {
|
|
233
258
|
onMouseDown(event, 1);
|
|
@@ -2,21 +2,23 @@
|
|
|
2
2
|
/** @typedef {typeof __propDef.events} SliderEvents */
|
|
3
3
|
/** @typedef {typeof __propDef.slots} SliderSlots */
|
|
4
4
|
/**
|
|
5
|
+
* The equivalent of the HTML `<input type="range">` element, but it comes with the multi-thumb
|
|
6
|
+
* support.
|
|
5
7
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/range
|
|
6
8
|
* @see https://w3c.github.io/aria/#slider
|
|
7
9
|
* @see https://www.w3.org/WAI/ARIA/apg/patterns/slider/
|
|
8
10
|
* @see https://www.w3.org/WAI/ARIA/apg/patterns/slider-multithumb/
|
|
9
11
|
*/
|
|
10
12
|
export default class Slider extends SvelteComponentTyped<{
|
|
11
|
-
class?: string;
|
|
12
13
|
value?: number;
|
|
14
|
+
class?: string;
|
|
15
|
+
sliderLabel?: string;
|
|
16
|
+
values?: [number, number];
|
|
17
|
+
sliderLabels?: [string, string];
|
|
13
18
|
min?: number;
|
|
14
19
|
max?: number;
|
|
15
20
|
step?: number;
|
|
16
|
-
|
|
17
|
-
values?: any;
|
|
18
|
-
sliderLabels?: any[];
|
|
19
|
-
optionLabels?: any[];
|
|
21
|
+
optionLabels?: string[] | number[];
|
|
20
22
|
}, {
|
|
21
23
|
click: MouseEvent;
|
|
22
24
|
change: CustomEvent<any>;
|
|
@@ -30,15 +32,15 @@ export type SliderSlots = typeof __propDef.slots;
|
|
|
30
32
|
import { SvelteComponentTyped } from "svelte";
|
|
31
33
|
declare const __propDef: {
|
|
32
34
|
props: {
|
|
33
|
-
class?: string;
|
|
34
35
|
value?: number;
|
|
36
|
+
class?: string;
|
|
37
|
+
sliderLabel?: string;
|
|
38
|
+
values?: [number, number];
|
|
39
|
+
sliderLabels?: [string, string];
|
|
35
40
|
min?: number;
|
|
36
41
|
max?: number;
|
|
37
42
|
step?: number;
|
|
38
|
-
|
|
39
|
-
values?: any;
|
|
40
|
-
sliderLabels?: any[];
|
|
41
|
-
optionLabels?: any[];
|
|
43
|
+
optionLabels?: (string[] | number[]);
|
|
42
44
|
};
|
|
43
45
|
events: {
|
|
44
46
|
click: MouseEvent;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component
|
|
3
|
+
A variant of `<Checkbox>`, looking like a switch that can be often seen on mobile apps.
|
|
3
4
|
@see https://w3c.github.io/aria/#switch
|
|
4
|
-
@see https://
|
|
5
|
+
@see https://www.w3.org/WAI/ARIA/apg/patterns/switch/
|
|
5
6
|
-->
|
|
6
7
|
<script>
|
|
7
8
|
/**
|
|
@@ -19,49 +20,65 @@
|
|
|
19
20
|
export let disabled = false;
|
|
20
21
|
</script>
|
|
21
22
|
|
|
22
|
-
<
|
|
23
|
-
|
|
23
|
+
<button
|
|
24
|
+
class="sui switch {className}"
|
|
25
|
+
{disabled}
|
|
26
|
+
role="switch"
|
|
27
|
+
aria-disabled={disabled}
|
|
28
|
+
aria-checked={checked}
|
|
29
|
+
on:click={() => {
|
|
30
|
+
checked = !checked;
|
|
31
|
+
}}
|
|
32
|
+
>
|
|
24
33
|
<span />
|
|
25
34
|
{#if label}
|
|
26
35
|
{label}
|
|
27
36
|
{:else}
|
|
28
37
|
<slot />
|
|
29
38
|
{/if}
|
|
30
|
-
</
|
|
39
|
+
</button>
|
|
31
40
|
|
|
32
|
-
<style>
|
|
41
|
+
<style>button {
|
|
33
42
|
display: inline-flex;
|
|
34
43
|
align-items: center;
|
|
35
44
|
gap: 8px;
|
|
45
|
+
border-width: 0;
|
|
46
|
+
border-style: solid;
|
|
47
|
+
border-color: transparent;
|
|
48
|
+
padding: 0;
|
|
49
|
+
color: inherit;
|
|
50
|
+
background-color: transparent;
|
|
51
|
+
box-shadow: none;
|
|
52
|
+
font: inherit;
|
|
53
|
+
text-align: left;
|
|
36
54
|
cursor: pointer;
|
|
37
55
|
-webkit-user-select: none;
|
|
38
56
|
user-select: none;
|
|
39
57
|
}
|
|
40
|
-
|
|
58
|
+
button:disabled {
|
|
41
59
|
cursor: default;
|
|
42
60
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
position: absolute;
|
|
46
|
-
left: -99999px;
|
|
61
|
+
button:disabled span {
|
|
62
|
+
opacity: 0.4;
|
|
47
63
|
}
|
|
48
|
-
|
|
49
|
-
|
|
64
|
+
button:focus-visible {
|
|
65
|
+
outline: 0;
|
|
50
66
|
}
|
|
51
|
-
|
|
52
|
-
|
|
67
|
+
button:focus-visible span::before {
|
|
68
|
+
outline-offset: 1px;
|
|
69
|
+
outline-width: 2px;
|
|
70
|
+
outline-style: solid;
|
|
71
|
+
outline-color: var(--primary-accent-color-lighter);
|
|
72
|
+
}
|
|
73
|
+
button[aria-checked=true] span {
|
|
53
74
|
background-color: var(--primary-accent-color);
|
|
54
75
|
border-color: transparent;
|
|
55
76
|
}
|
|
56
|
-
|
|
77
|
+
button[aria-checked=true] span::before {
|
|
57
78
|
transform: translateX(22px);
|
|
58
79
|
background-color: var(--primary-accent-color-foreground);
|
|
59
80
|
}
|
|
60
81
|
|
|
61
|
-
input:disabled + span {
|
|
62
|
-
opacity: 0.4;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
82
|
span {
|
|
66
83
|
position: relative;
|
|
67
84
|
width: 42px;
|