@geoffcox/sterling-svelte 0.0.30 → 1.0.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/@types/clickOutside.d.ts +11 -7
- package/Button.svelte +11 -183
- package/Button.svelte.d.ts +2 -6
- package/Callout.svelte +188 -0
- package/Callout.svelte.d.ts +54 -0
- package/Checkbox.svelte +15 -177
- package/Checkbox.svelte.d.ts +2 -2
- package/ColorPicker.svelte +204 -223
- package/ColorPicker.svelte.d.ts +1 -2
- package/Dialog.svelte +91 -187
- package/Dialog.svelte.d.ts +3 -1
- package/Dropdown.svelte +52 -219
- package/Dropdown.svelte.d.ts +4 -8
- package/HexColorSliders.svelte +77 -145
- package/HexColorSliders.svelte.d.ts +28 -1
- package/HslColorSliders.svelte +99 -179
- package/HslColorSliders.svelte.d.ts +28 -1
- package/Input.svelte +27 -136
- package/Input.svelte.d.ts +2 -3
- package/Label.constants.d.ts +1 -0
- package/Label.constants.js +1 -0
- package/Label.svelte +96 -169
- package/Label.svelte.d.ts +6 -1
- package/Label.types.d.ts +3 -1
- package/Link.svelte +9 -106
- package/Link.svelte.d.ts +0 -1
- package/List.svelte +142 -230
- package/List.svelte.d.ts +2 -3
- package/List.types.d.ts +6 -1
- package/ListItem.svelte +25 -94
- package/ListItem.svelte.d.ts +2 -0
- package/Menu.svelte +48 -64
- package/Menu.svelte.d.ts +4 -1
- package/MenuBar.svelte +84 -86
- package/MenuBar.svelte.d.ts +4 -1
- package/MenuButton.svelte +67 -74
- package/MenuButton.svelte.d.ts +7 -3
- package/MenuItem.svelte +256 -288
- package/MenuItem.svelte.d.ts +2 -2
- package/MenuItemDisplay.svelte +12 -116
- package/MenuItemDisplay.svelte.d.ts +21 -7
- package/MenuSeparator.svelte +6 -45
- package/MenuSeparator.svelte.d.ts +8 -78
- package/Popover.constants.d.ts +2 -0
- package/{floating-ui.constants.js → Popover.constants.js} +10 -9
- package/Popover.svelte +72 -82
- package/Popover.svelte.d.ts +10 -5
- package/Popover.types.d.ts +4 -0
- package/Progress.svelte +28 -126
- package/Progress.svelte.d.ts +4 -3
- package/Radio.svelte +49 -192
- package/Radio.svelte.d.ts +2 -2
- package/RgbColorSliders.svelte +48 -137
- package/RgbColorSliders.svelte.d.ts +5 -5
- package/Select.svelte +124 -251
- package/Select.svelte.d.ts +6 -2
- package/Slider.svelte +90 -259
- package/Slider.svelte.d.ts +1 -2
- package/Switch.svelte +24 -259
- package/Switch.svelte.d.ts +3 -1
- package/Tab.svelte +27 -175
- package/Tab.svelte.d.ts +6 -4
- package/TabList.svelte +146 -171
- package/TabList.svelte.d.ts +3 -2
- package/TabList.types.d.ts +6 -1
- package/TextArea.svelte +32 -129
- package/TextArea.svelte.d.ts +1 -1
- package/Tooltip.svelte +88 -222
- package/Tooltip.svelte.d.ts +21 -13
- package/Tree.constants.d.ts +0 -1
- package/Tree.constants.js +0 -1
- package/Tree.svelte +35 -119
- package/Tree.svelte.d.ts +4 -4
- package/Tree.types.d.ts +1 -3
- package/TreeChevron.svelte +18 -98
- package/TreeChevron.svelte.d.ts +1 -0
- package/TreeItem.constants.d.ts +1 -0
- package/TreeItem.constants.js +1 -0
- package/TreeItem.svelte +251 -211
- package/TreeItem.svelte.d.ts +7 -3
- package/TreeItem.types.d.ts +1 -1
- package/TreeItemDisplay.svelte +20 -104
- package/TreeItemDisplay.svelte.d.ts +2 -2
- package/actions/applyLightDarkMode.d.ts +10 -0
- package/actions/applyLightDarkMode.js +36 -0
- package/actions/forwardEvents.js +3 -3
- package/css/Button.base.css +74 -0
- package/css/Button.colorful.css +17 -0
- package/css/Button.css +7 -0
- package/css/Button.secondary.colorful.css +15 -0
- package/css/Button.secondary.css +11 -0
- package/css/Button.shapes.css +14 -0
- package/css/Button.tool.colorful.css +13 -0
- package/css/Button.tool.css +18 -0
- package/css/Callout.base.css +43 -0
- package/css/Callout.colorful.css +5 -0
- package/css/Callout.css +2 -0
- package/css/Checkbox.base.css +145 -0
- package/css/Checkbox.colorful.css +17 -0
- package/css/Checkbox.css +2 -0
- package/css/ColorPicker.base.css +23 -0
- package/css/ColorPicker.css +1 -0
- package/css/Dialog.base.css +116 -0
- package/css/Dialog.css +1 -0
- package/css/Dropdown.base.css +147 -0
- package/css/Dropdown.colorful.css +23 -0
- package/css/Dropdown.css +2 -0
- package/css/HexColorSliders.base.css +106 -0
- package/css/HexColorSliders.css +1 -0
- package/css/HslColorSliders.base.css +124 -0
- package/css/HslColorSliders.css +1 -0
- package/css/Input.base.css +100 -0
- package/css/Input.colorful.css +22 -0
- package/css/Input.composed.css +8 -0
- package/css/Input.css +3 -0
- package/css/Label.base.css +119 -0
- package/css/Label.boxed.colorful.css +21 -0
- package/css/Label.boxed.css +31 -0
- package/css/Label.colorful.css +3 -0
- package/css/Label.css +4 -0
- package/css/Link.base.css +52 -0
- package/css/Link.colorful.css +15 -0
- package/css/Link.css +6 -0
- package/css/Link.ghost.colorful.css +7 -0
- package/css/Link.ghost.css +11 -0
- package/css/Link.undecorated.colorful.css +6 -0
- package/css/Link.undecorated.css +6 -0
- package/css/List.base.css +98 -0
- package/css/List.css +1 -0
- package/css/ListItem.base.css +59 -0
- package/css/ListItem.css +1 -0
- package/css/Menu.base.css +21 -0
- package/css/Menu.css +1 -0
- package/css/MenuBar.base.css +9 -0
- package/css/MenuBar.css +1 -0
- package/css/MenuButton.base.css +13 -0
- package/css/MenuButton.css +1 -0
- package/css/MenuItem.base.css +48 -0
- package/css/MenuItem.css +1 -0
- package/css/MenuItemDisplay.base.css +104 -0
- package/css/MenuItemDisplay.css +1 -0
- package/css/MenuSeparator.base.css +5 -0
- package/css/MenuSeparator.css +1 -0
- package/css/Popover copy.css +21 -0
- package/css/Popover.css +21 -0
- package/css/Progress.base.css +99 -0
- package/css/Progress.css +1 -0
- package/css/Radio.base.css +135 -0
- package/css/Radio.colorful.css +18 -0
- package/css/Radio.css +2 -0
- package/css/RgbColorSliders.base.css +94 -0
- package/css/RgbColorSliders.css +1 -0
- package/css/Select.base.css +127 -0
- package/css/Select.colorful.css +24 -0
- package/css/Select.composed.css +12 -0
- package/css/Select.css +3 -0
- package/css/Slider.base.css +182 -0
- package/css/Slider.colorful.css +11 -0
- package/css/Slider.composed.css +8 -0
- package/css/Slider.css +3 -0
- package/css/Switch.base.css +193 -0
- package/css/Switch.colorful.css +39 -0
- package/css/Switch.css +2 -0
- package/css/Tab.base.css +135 -0
- package/css/Tab.colorful.css +13 -0
- package/css/Tab.css +2 -0
- package/css/TabList.base.css +34 -0
- package/css/TabList.css +1 -0
- package/css/TextArea.base.css +85 -0
- package/css/TextArea.colorful.css +17 -0
- package/css/TextArea.composed.css +8 -0
- package/css/TextArea.css +3 -0
- package/css/Tooltip.base.css +6 -0
- package/css/Tooltip.css +1 -0
- package/css/Tree.base.css +74 -0
- package/css/Tree.composed.css +8 -0
- package/css/Tree.css +2 -0
- package/css/TreeChevron.base.css +86 -0
- package/css/TreeChevron.css +1 -0
- package/css/TreeItem.base.css +3 -0
- package/css/TreeItem.css +1 -0
- package/css/TreeItemDisplay.base.css +74 -0
- package/css/TreeItemDisplay.colorful.css +9 -0
- package/css/TreeItemDisplay.css +1 -0
- package/css/dark-mode.css +134 -0
- package/css/light-mode.css +134 -0
- package/css/sterling.css +37 -0
- package/index.d.ts +13 -18
- package/index.js +11 -15
- package/mediaQueries/prefersColorSchemeDark.d.ts +2 -0
- package/mediaQueries/prefersColorSchemeDark.js +10 -0
- package/{stores → mediaQueries}/prefersReducedMotion.d.ts +1 -0
- package/{stores → mediaQueries}/usingKeyboard.d.ts +1 -0
- package/package.json +136 -19
- package/Link.constants.d.ts +0 -1
- package/Link.constants.js +0 -1
- package/Link.types.d.ts +0 -4
- package/Tooltip.constants.d.ts +0 -1
- package/Tooltip.constants.js +0 -1
- package/Tooltip.types.d.ts +0 -4
- package/Tooltip.types.js +0 -1
- package/floating-ui.constants.d.ts +0 -1
- package/floating-ui.types.d.ts +0 -4
- package/floating-ui.types.js +0 -1
- package/theme/applyDarkTheme.d.ts +0 -7
- package/theme/applyDarkTheme.js +0 -11
- package/theme/applyLightTheme.d.ts +0 -7
- package/theme/applyLightTheme.js +0 -11
- package/theme/applyTheme.d.ts +0 -7
- package/theme/applyTheme.js +0 -20
- package/theme/colors.d.ts +0 -54
- package/theme/colors.js +0 -82
- package/theme/darkTheme.d.ts +0 -2
- package/theme/darkTheme.js +0 -142
- package/theme/lightTheme.d.ts +0 -2
- package/theme/lightTheme.js +0 -119
- package/theme/toggleDarkTheme.d.ts +0 -18
- package/theme/toggleDarkTheme.js +0 -53
- package/theme/types.d.ts +0 -21
- package/theme/types.js +0 -1
- /package/{Link.types.js → Popover.types.js} +0 -0
- /package/{stores → mediaQueries}/prefersReducedMotion.js +0 -0
- /package/{stores → mediaQueries}/usingKeyboard.js +0 -0
package/Dialog.svelte
CHANGED
|
@@ -1,83 +1,114 @@
|
|
|
1
|
-
<script>import
|
|
2
|
-
import
|
|
1
|
+
<script>import '$lib/css/sterling.css';
|
|
2
|
+
import { onMount, tick } from 'svelte';
|
|
3
|
+
import Button from './Button.svelte';
|
|
3
4
|
const dialogFadeDuration = 250;
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
// ----- Props ----- //
|
|
6
|
+
/** When true, clicking outside the dialog causes the dialog close. */
|
|
6
7
|
export let backdropCloses = false;
|
|
8
|
+
/** When true, the dialog is open; otherwise the dialog is closed. */
|
|
9
|
+
export let open = false;
|
|
10
|
+
/**
|
|
11
|
+
* The return value from the dialog:
|
|
12
|
+
* - an empty string indicates cancellation
|
|
13
|
+
* - a value indicates form submission.
|
|
14
|
+
*/
|
|
15
|
+
export let returnValue = '';
|
|
16
|
+
/** Additional class names to apply. */
|
|
17
|
+
export let variant = '';
|
|
18
|
+
// ----- State ----- //
|
|
7
19
|
let dialogRef;
|
|
8
20
|
let contentRef;
|
|
9
21
|
let formRef;
|
|
10
22
|
let closing = false;
|
|
23
|
+
// ----- Event Handlers ----- //
|
|
11
24
|
const onDocumentClick = (event) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
// as tracking clicks outside the dialog is only active while the dialog is open
|
|
26
|
+
// the clickOutside action is not used and reimplemented here.
|
|
27
|
+
const targetNode = event?.target;
|
|
28
|
+
// the content must be used as the container because dialog::backdrop is considered
|
|
29
|
+
// part of the HTMLDialogElement
|
|
30
|
+
if (targetNode && !contentRef?.contains(targetNode) && backdropCloses) {
|
|
31
|
+
open = false;
|
|
32
|
+
}
|
|
16
33
|
};
|
|
17
34
|
const showDialog = () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
35
|
+
if (dialogRef?.open === false) {
|
|
36
|
+
// when open, track clicks outside the dialog (use capture = true)
|
|
37
|
+
document.addEventListener('click', onDocumentClick, true);
|
|
38
|
+
dialogRef.showModal();
|
|
39
|
+
}
|
|
40
|
+
open = true;
|
|
23
41
|
};
|
|
24
|
-
const closeDialog = (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
const closeDialog = (returnValue = '') => {
|
|
43
|
+
if (dialogRef?.open === true) {
|
|
44
|
+
// when closed, stop tracking clicks outside the dialog
|
|
45
|
+
document.removeEventListener('click', onDocumentClick);
|
|
46
|
+
// to allow time for the CSS transition animation, closing the dialog is delayed
|
|
47
|
+
closing = true;
|
|
48
|
+
tick();
|
|
49
|
+
setTimeout(() => {
|
|
50
|
+
dialogRef.close(returnValue);
|
|
51
|
+
open = false;
|
|
52
|
+
closing = false;
|
|
53
|
+
}, dialogFadeDuration);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
open = false;
|
|
57
|
+
}
|
|
37
58
|
};
|
|
38
|
-
const updateDialog = (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
59
|
+
const updateDialog = (open) => {
|
|
60
|
+
if (open) {
|
|
61
|
+
showDialog();
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
closeDialog();
|
|
65
|
+
}
|
|
44
66
|
};
|
|
45
67
|
const onCancel = (event) => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
68
|
+
// Cancelling a dialog instantly hides the dialog.
|
|
69
|
+
// To allow animation with closeDialog, this event is canceled.
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
event.stopPropagation();
|
|
72
|
+
closeDialog();
|
|
73
|
+
return false;
|
|
50
74
|
};
|
|
51
75
|
const onSubmit = (event) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
76
|
+
// Submitting a form instantly hides the dialog.
|
|
77
|
+
// The dialog.close event is not cancellable, but form.submit is.
|
|
78
|
+
// To allow animation with closeDialog, this event is canceled.
|
|
79
|
+
// The form is resubmitted after the dialog closes to ensure the form is in the correct state.
|
|
80
|
+
const anyEvent = event;
|
|
81
|
+
if (anyEvent?.submitter.type === 'submit') {
|
|
82
|
+
if (dialogRef.open) {
|
|
83
|
+
closeDialog(anyEvent?.submitter.value ?? '');
|
|
84
|
+
setTimeout(() => {
|
|
85
|
+
formRef.requestSubmit(anyEvent?.submitter);
|
|
86
|
+
}, dialogFadeDuration);
|
|
87
|
+
event.preventDefault();
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
return false;
|
|
61
94
|
}
|
|
62
|
-
} else {
|
|
63
|
-
event.preventDefault();
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
95
|
};
|
|
67
96
|
const onClose = (event) => {
|
|
68
|
-
|
|
97
|
+
// This event is not cancelable.
|
|
98
|
+
// Update the returnValue whenever the dialog closes.
|
|
99
|
+
returnValue = dialogRef.returnValue;
|
|
69
100
|
};
|
|
70
101
|
$: {
|
|
71
|
-
|
|
102
|
+
updateDialog(open);
|
|
72
103
|
}
|
|
73
104
|
onMount(() => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
105
|
+
updateDialog(open);
|
|
106
|
+
dialogRef.addEventListener('cancel', onCancel);
|
|
107
|
+
dialogRef.addEventListener('close', onClose);
|
|
108
|
+
return () => {
|
|
109
|
+
dialogRef?.removeEventListener('cancel', onCancel);
|
|
110
|
+
dialogRef?.removeEventListener('close', onClose);
|
|
111
|
+
};
|
|
81
112
|
});
|
|
82
113
|
</script>
|
|
83
114
|
|
|
@@ -89,7 +120,7 @@ A styled <dialog> element
|
|
|
89
120
|
-->
|
|
90
121
|
<dialog
|
|
91
122
|
bind:this={dialogRef}
|
|
92
|
-
class=
|
|
123
|
+
class={`sterling-dialog ${variant}`}
|
|
93
124
|
class:open
|
|
94
125
|
class:closing
|
|
95
126
|
on:close
|
|
@@ -105,7 +136,7 @@ A styled <dialog> element
|
|
|
105
136
|
<slot name="title" />
|
|
106
137
|
</div>
|
|
107
138
|
<div class="close">
|
|
108
|
-
<Button variant=
|
|
139
|
+
<Button variant={`circular tool ${variant}`} on:click={() => closeDialog()}>
|
|
109
140
|
<div class="close-x" />
|
|
110
141
|
</Button>
|
|
111
142
|
</div>
|
|
@@ -122,130 +153,3 @@ A styled <dialog> element
|
|
|
122
153
|
</div>
|
|
123
154
|
</form>
|
|
124
155
|
</dialog>
|
|
125
|
-
|
|
126
|
-
<style>
|
|
127
|
-
.dialog {
|
|
128
|
-
padding: 0;
|
|
129
|
-
border: none;
|
|
130
|
-
background: none;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.dialog::backdrop {
|
|
134
|
-
backdrop-filter: blur(2px);
|
|
135
|
-
background: rgba(0, 0, 0, 0.3);
|
|
136
|
-
transition: opacity 250ms;
|
|
137
|
-
opacity: 0;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
.dialog.open::backdrop {
|
|
141
|
-
opacity: 1;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
.dialog.closing::backdrop {
|
|
145
|
-
opacity: 0;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
.header {
|
|
149
|
-
background-color: var(--stsv-common__background-color--secondary);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.content {
|
|
153
|
-
background-color: var(--stsv-common__background-color);
|
|
154
|
-
border-color: var(--stsv-common__border-color);
|
|
155
|
-
border-radius: var(--stsv-common__border-radius);
|
|
156
|
-
border-style: var(--stsv-common__border-style);
|
|
157
|
-
border-width: var(--stsv-common__border-width);
|
|
158
|
-
box-sizing: border-box;
|
|
159
|
-
color: var(--stsv-common__color);
|
|
160
|
-
display: grid;
|
|
161
|
-
grid-template-columns: 1fr;
|
|
162
|
-
grid-template-rows: auto 1fr auto auto;
|
|
163
|
-
justify-content: stretch;
|
|
164
|
-
justify-items: stretch;
|
|
165
|
-
align-items: stretch;
|
|
166
|
-
transition: opacity 250ms;
|
|
167
|
-
opacity: 0;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.dialog.open .content {
|
|
171
|
-
opacity: 1;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
.dialog.closing .content {
|
|
175
|
-
opacity: 0;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.header {
|
|
179
|
-
display: grid;
|
|
180
|
-
grid-template-columns: 1fr auto;
|
|
181
|
-
grid-template-rows: 1fr;
|
|
182
|
-
justify-items: stretch;
|
|
183
|
-
align-items: center;
|
|
184
|
-
padding: 0.25em 0.5em;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
.title {
|
|
188
|
-
font-size: 1.4em;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.close {
|
|
192
|
-
justify-self: flex-end;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.close :global(button) {
|
|
196
|
-
width: 1.75em;
|
|
197
|
-
height: 1.75em;
|
|
198
|
-
padding: 0;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.close-x {
|
|
202
|
-
width: 1em;
|
|
203
|
-
height: 1em;
|
|
204
|
-
position: relative;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
.close-x:before,
|
|
208
|
-
.close-x:after {
|
|
209
|
-
content: '';
|
|
210
|
-
position: absolute;
|
|
211
|
-
width: 0.75em;
|
|
212
|
-
height: 0.125em;
|
|
213
|
-
background-color: currentColor;
|
|
214
|
-
top: 0.45em;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
.close-x:before {
|
|
218
|
-
transform: rotate(45deg);
|
|
219
|
-
left: 0.125em;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
.close-x:after {
|
|
223
|
-
transform: rotate(-45deg);
|
|
224
|
-
right: 0.125em;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
.body {
|
|
228
|
-
padding: 1em;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
.separator {
|
|
232
|
-
background-color: var(--stsv-common__background-color--secondary);
|
|
233
|
-
height: var(--stsv-common__border-width);
|
|
234
|
-
margin: 0 0.25em;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
.footer {
|
|
238
|
-
display: flex;
|
|
239
|
-
justify-content: flex-end;
|
|
240
|
-
justify-items: flex-end;
|
|
241
|
-
padding: 0.5em 1em;
|
|
242
|
-
gap: 5px;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
@media (prefers-reduced-motion) {
|
|
246
|
-
.dialog::backdrop,
|
|
247
|
-
.content {
|
|
248
|
-
transition: none;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
</style>
|
package/Dialog.svelte.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import '$lib/css/sterling.css';
|
|
2
3
|
declare const __propDef: {
|
|
3
4
|
props: {
|
|
4
5
|
[x: string]: any;
|
|
6
|
+
backdropCloses?: boolean | undefined;
|
|
5
7
|
open?: boolean | undefined;
|
|
6
8
|
returnValue?: string | undefined;
|
|
7
|
-
|
|
9
|
+
variant?: string | undefined;
|
|
8
10
|
};
|
|
9
11
|
events: {
|
|
10
12
|
close: Event;
|
package/Dropdown.svelte
CHANGED
|
@@ -1,66 +1,75 @@
|
|
|
1
|
-
<script>import { createEventDispatcher } from
|
|
2
|
-
import Popover from
|
|
3
|
-
import { clickOutside } from
|
|
4
|
-
import { idGenerator } from
|
|
5
|
-
import { prefersReducedMotion } from
|
|
6
|
-
import { slide } from
|
|
7
|
-
const popupId = idGenerator.nextId(
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
<script>import { createEventDispatcher } from 'svelte';
|
|
2
|
+
import Popover from './Popover.svelte';
|
|
3
|
+
import { clickOutside } from './actions/clickOutside';
|
|
4
|
+
import { idGenerator } from './idGenerator';
|
|
5
|
+
import { prefersReducedMotion } from './mediaQueries/prefersReducedMotion';
|
|
6
|
+
import { slide } from 'svelte/transition';
|
|
7
|
+
const popupId = idGenerator.nextId('Dropdown-popup');
|
|
8
|
+
// ----- Props ----- //
|
|
9
|
+
/** Disables the dropdown. */
|
|
10
10
|
export let disabled = false;
|
|
11
|
+
/** When true, the dropdown is open. */
|
|
11
12
|
export let open = false;
|
|
13
|
+
/** When the user clicks away from the dropdown, it remains open. */
|
|
12
14
|
export let stayOpenOnClickAway = false;
|
|
15
|
+
/** Additional class names to apply. */
|
|
16
|
+
export let variant = '';
|
|
17
|
+
// ----- State ----- //
|
|
13
18
|
let dropdownRef;
|
|
14
19
|
let popupContentRef;
|
|
20
|
+
// ----- Events ----- //
|
|
15
21
|
const dispatch = createEventDispatcher();
|
|
16
|
-
const raiseOpen = (
|
|
17
|
-
|
|
22
|
+
const raiseOpen = (open) => {
|
|
23
|
+
dispatch('open', { open });
|
|
18
24
|
};
|
|
25
|
+
// ----- Reactions ----- //
|
|
19
26
|
$: {
|
|
20
|
-
|
|
27
|
+
raiseOpen(open);
|
|
21
28
|
}
|
|
29
|
+
// ----- Methods ----- //
|
|
22
30
|
export const click = () => {
|
|
23
|
-
|
|
31
|
+
dropdownRef?.click();
|
|
24
32
|
};
|
|
25
33
|
export const blur = () => {
|
|
26
|
-
|
|
34
|
+
dropdownRef?.blur();
|
|
27
35
|
};
|
|
28
36
|
export const focus = (options) => {
|
|
29
|
-
|
|
37
|
+
dropdownRef?.focus(options);
|
|
30
38
|
};
|
|
39
|
+
// ----- Event Handlers ----- //
|
|
31
40
|
const onClick = (event) => {
|
|
32
|
-
|
|
33
|
-
open = !open;
|
|
34
|
-
event.preventDefault();
|
|
35
|
-
event.stopPropagation();
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
const onKeydown = (event) => {
|
|
39
|
-
if (!event.altKey && !event.ctrlKey && !event.shiftKey) {
|
|
40
|
-
switch (event.key) {
|
|
41
|
-
case " ":
|
|
41
|
+
if (!disabled) {
|
|
42
42
|
open = !open;
|
|
43
43
|
event.preventDefault();
|
|
44
44
|
event.stopPropagation();
|
|
45
|
-
return false;
|
|
46
|
-
case "Escape":
|
|
47
|
-
open = false;
|
|
48
|
-
event.preventDefault();
|
|
49
|
-
event.stopPropagation();
|
|
50
|
-
return false;
|
|
51
45
|
}
|
|
52
|
-
|
|
46
|
+
};
|
|
47
|
+
const onKeydown = (event) => {
|
|
48
|
+
if (!event.altKey && !event.ctrlKey && !event.shiftKey) {
|
|
49
|
+
switch (event.key) {
|
|
50
|
+
case ' ':
|
|
51
|
+
open = !open;
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
event.stopPropagation();
|
|
54
|
+
return false;
|
|
55
|
+
case 'Escape':
|
|
56
|
+
open = false;
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
event.stopPropagation();
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
53
62
|
};
|
|
54
63
|
const onClickOutside = (event) => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
if (!stayOpenOnClickAway) {
|
|
65
|
+
open = false;
|
|
66
|
+
}
|
|
58
67
|
};
|
|
68
|
+
// ----- Animation ----- //
|
|
59
69
|
const slideNoOp = (node, params) => {
|
|
60
|
-
|
|
70
|
+
return { delay: 0, duration: 0 };
|
|
61
71
|
};
|
|
62
|
-
$:
|
|
63
|
-
slideMotion = !$prefersReducedMotion ? slide : slideNoOp;
|
|
72
|
+
$: slideMotion = !$prefersReducedMotion ? slide : slideNoOp;
|
|
64
73
|
</script>
|
|
65
74
|
|
|
66
75
|
<div
|
|
@@ -68,9 +77,7 @@ $:
|
|
|
68
77
|
aria-controls={popupId}
|
|
69
78
|
aria-haspopup={true}
|
|
70
79
|
aria-expanded={open}
|
|
71
|
-
class=
|
|
72
|
-
class:colorful
|
|
73
|
-
class:composed
|
|
80
|
+
class={`sterling-dropdown ${variant}`}
|
|
74
81
|
class:disabled
|
|
75
82
|
role="combobox"
|
|
76
83
|
tabindex="0"
|
|
@@ -107,9 +114,9 @@ $:
|
|
|
107
114
|
{...$$restProps}
|
|
108
115
|
>
|
|
109
116
|
<div class="value">
|
|
110
|
-
<slot name="value" {
|
|
117
|
+
<slot name="value" {disabled} {open} {variant} />
|
|
111
118
|
</div>
|
|
112
|
-
<slot name="button" {
|
|
119
|
+
<slot name="button" {disabled} {open} {variant}>
|
|
113
120
|
<div class="button">
|
|
114
121
|
<div class="chevron" />
|
|
115
122
|
</div>
|
|
@@ -117,185 +124,11 @@ $:
|
|
|
117
124
|
|
|
118
125
|
<Popover reference={dropdownRef} open={!disabled && open}>
|
|
119
126
|
<div
|
|
120
|
-
class=
|
|
127
|
+
class={`sterling-dropdown-popup-content ${variant}`}
|
|
121
128
|
transition:slideMotion|global={{ duration: 200 }}
|
|
122
|
-
class:colorful
|
|
123
129
|
bind:this={popupContentRef}
|
|
124
130
|
>
|
|
125
|
-
<slot {
|
|
131
|
+
<slot {disabled} {open} {variant} />
|
|
126
132
|
</div>
|
|
127
133
|
</Popover>
|
|
128
134
|
</div>
|
|
129
|
-
|
|
130
|
-
<style>
|
|
131
|
-
.sterling-dropdown {
|
|
132
|
-
align-content: stretch;
|
|
133
|
-
align-items: stretch;
|
|
134
|
-
background-color: var(--stsv-input__background-color);
|
|
135
|
-
border-color: var(--stsv-input__border-color);
|
|
136
|
-
border-radius: var(--stsv-button__border-radius);
|
|
137
|
-
border-style: var(--stsv-input__border-style);
|
|
138
|
-
border-width: var(--stsv-input__border-width);
|
|
139
|
-
color: var(--stsv-input__color);
|
|
140
|
-
display: grid;
|
|
141
|
-
grid-template-columns: minmax(0, 1fr) auto;
|
|
142
|
-
grid-template-rows: auto;
|
|
143
|
-
outline: none;
|
|
144
|
-
overflow: hidden;
|
|
145
|
-
padding: 0;
|
|
146
|
-
position: relative;
|
|
147
|
-
transition: background-color 250ms, color 250ms, border-color 250ms;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.sterling-dropdown:hover {
|
|
151
|
-
background-color: var(--stsv-input__background-color--hover);
|
|
152
|
-
border-color: var(--stsv-input__border-color--hover);
|
|
153
|
-
color: var(--stsv-input__color--hover);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.sterling-dropdown:focus {
|
|
157
|
-
background-color: var(--stsv-input__background-color--focus);
|
|
158
|
-
border-color: var(--stsv-input__border-color--focus);
|
|
159
|
-
color: var(--stsv-input__color--focus);
|
|
160
|
-
outline-color: var(--stsv-common__outline-color);
|
|
161
|
-
outline-offset: var(--stsv-common__outline-offset);
|
|
162
|
-
outline-style: var(--stsv-common__outline-style);
|
|
163
|
-
outline-width: var(--stsv-common__outline-width);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.sterling-dropdown.colorful {
|
|
167
|
-
background-color: var(--stsv-input--colorful__background-color);
|
|
168
|
-
border-color: var(--stsv-input--colorful__border-color);
|
|
169
|
-
color: var(--stsv-input--colorful__color);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
.sterling-dropdown.colorful:hover {
|
|
173
|
-
background-color: var(--stsv-input--colorful__background-color--hover);
|
|
174
|
-
border-color: var(--stsv-input--colorful__border-color--hover);
|
|
175
|
-
color: var(--stsv-input--colorful__color--hover);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.sterling-dropdown.colorful:focus {
|
|
179
|
-
background-color: var(--stsv-input--colorful__background-color--focus);
|
|
180
|
-
border-color: var(--stsv-input--colorful__border-color--focus);
|
|
181
|
-
color: var(--stsv-input--colorful__color--focus);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
.sterling-dropdown.disabled {
|
|
185
|
-
cursor: not-allowed;
|
|
186
|
-
outline: none;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
.sterling-dropdown.disabled .button {
|
|
190
|
-
cursor: not-allowed;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
.sterling-dropdown::after {
|
|
194
|
-
background: repeating-linear-gradient(
|
|
195
|
-
var(--stsv-common--disabled__stripe-angle),
|
|
196
|
-
var(--stsv-common--disabled__stripe-color),
|
|
197
|
-
var(--stsv-common--disabled__stripe-color) var(--stsv-common--disabled__stripe-width),
|
|
198
|
-
var(--stsv-common--disabled__stripe-color--alt) var(--stsv-common--disabled__stripe-width),
|
|
199
|
-
var(--stsv-common--disabled__stripe-color--alt)
|
|
200
|
-
calc(2 * var(--stsv-common--disabled__stripe-width))
|
|
201
|
-
);
|
|
202
|
-
bottom: 0;
|
|
203
|
-
content: '';
|
|
204
|
-
left: 0;
|
|
205
|
-
opacity: 0;
|
|
206
|
-
position: absolute;
|
|
207
|
-
right: 0;
|
|
208
|
-
top: 0;
|
|
209
|
-
pointer-events: none;
|
|
210
|
-
transition: opacity 250ms;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
.sterling-dropdown.disabled::after {
|
|
214
|
-
opacity: 1;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
.sterling-dropdown.composed,
|
|
218
|
-
.sterling-dropdown.composed:hover,
|
|
219
|
-
.sterling-dropdown.composed.focus {
|
|
220
|
-
background: none;
|
|
221
|
-
border: none;
|
|
222
|
-
outline: none;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
.sterling-dropdown.composed.disabled::after {
|
|
226
|
-
opacity: 0;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.value {
|
|
230
|
-
overflow: hidden;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
.button {
|
|
234
|
-
align-self: center;
|
|
235
|
-
cursor: pointer;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
.chevron {
|
|
239
|
-
display: block;
|
|
240
|
-
position: relative;
|
|
241
|
-
border: none;
|
|
242
|
-
background: none;
|
|
243
|
-
margin: 0;
|
|
244
|
-
height: 100%;
|
|
245
|
-
min-width: 2em;
|
|
246
|
-
min-height: 2em;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
.chevron::after {
|
|
250
|
-
position: absolute;
|
|
251
|
-
content: '';
|
|
252
|
-
top: 50%;
|
|
253
|
-
left: 50%;
|
|
254
|
-
width: 7px;
|
|
255
|
-
height: 7px;
|
|
256
|
-
border-right: 3px solid currentColor;
|
|
257
|
-
border-top: 3px solid currentColor;
|
|
258
|
-
/*
|
|
259
|
-
The chevron is a right triangle, rotated to face down.
|
|
260
|
-
It should be moved up so it is centered vertically after rotation.
|
|
261
|
-
The amount to move is the hypotenuse of the right triangle of the chevron.
|
|
262
|
-
For a right triangle with equal a and b where c=1
|
|
263
|
-
a^2 + b^2 = c^2
|
|
264
|
-
a^2 + a^2 = c^2
|
|
265
|
-
2a^2 = c^2
|
|
266
|
-
2a^2 = 1
|
|
267
|
-
a^2 = 0.5
|
|
268
|
-
a = sqrt(0.5)
|
|
269
|
-
a = 0.707
|
|
270
|
-
*/
|
|
271
|
-
transform: translate(-50%, calc(-50% / 0.707)) rotate(135deg);
|
|
272
|
-
transform-origin: 50% 50%;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
.popup-content {
|
|
276
|
-
background-color: var(--stsv-common__background-color);
|
|
277
|
-
border-color: var(--stsv-common__border-color);
|
|
278
|
-
border-radius: var(--stsv-common__border-radius);
|
|
279
|
-
border-style: var(--stsv-common__border-style);
|
|
280
|
-
border-width: var(--stsv-common__border-width);
|
|
281
|
-
color: var(--stsv-common__color);
|
|
282
|
-
padding: 0.25em;
|
|
283
|
-
display: grid;
|
|
284
|
-
grid-template-columns: 1fr;
|
|
285
|
-
grid-template-rows: 1fr;
|
|
286
|
-
overflow: hidden;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
.popup-content.colorful {
|
|
290
|
-
background-color: var(--stsv-common--colorful__background-color);
|
|
291
|
-
border-color: var(--stsv-common--colorful__border-color);
|
|
292
|
-
color: var(--stsv-common--colorful__color);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
@media (prefers-reduced-motion) {
|
|
296
|
-
.sterling-dropdown,
|
|
297
|
-
.sterling-dropdown::after {
|
|
298
|
-
transition: none;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
</style>
|
package/Dropdown.svelte.d.ts
CHANGED
|
@@ -2,11 +2,10 @@ import { SvelteComponentTyped } from "svelte";
|
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
[x: string]: any;
|
|
5
|
-
colorful?: boolean | undefined;
|
|
6
|
-
composed?: boolean | undefined;
|
|
7
5
|
disabled?: boolean | undefined;
|
|
8
6
|
open?: boolean | undefined;
|
|
9
7
|
stayOpenOnClickAway?: boolean | undefined;
|
|
8
|
+
variant?: string | undefined;
|
|
10
9
|
click?: (() => void) | undefined;
|
|
11
10
|
blur?: (() => void) | undefined;
|
|
12
11
|
focus?: ((options?: FocusOptions) => void) | undefined;
|
|
@@ -44,22 +43,19 @@ declare const __propDef: {
|
|
|
44
43
|
};
|
|
45
44
|
slots: {
|
|
46
45
|
value: {
|
|
47
|
-
colorful: boolean;
|
|
48
|
-
composed: boolean;
|
|
49
46
|
disabled: boolean;
|
|
50
47
|
open: boolean;
|
|
48
|
+
variant: string;
|
|
51
49
|
};
|
|
52
50
|
button: {
|
|
53
|
-
colorful: boolean;
|
|
54
|
-
composed: boolean;
|
|
55
51
|
disabled: boolean;
|
|
56
52
|
open: boolean;
|
|
53
|
+
variant: string;
|
|
57
54
|
};
|
|
58
55
|
default: {
|
|
59
|
-
colorful: boolean;
|
|
60
|
-
composed: boolean;
|
|
61
56
|
disabled: boolean;
|
|
62
57
|
open: boolean;
|
|
58
|
+
variant: string;
|
|
63
59
|
};
|
|
64
60
|
};
|
|
65
61
|
};
|