@geoffcox/sterling-svelte 1.0.11 → 2.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/.DS_Store +0 -0
- package/Button.svelte +25 -0
- package/Button.svelte.d.ts +9 -0
- package/{dist/Callout.svelte → Callout.svelte} +61 -78
- package/Callout.svelte.d.ts +15 -0
- package/Callout.types.d.ts +11 -0
- package/Checkbox.svelte +43 -0
- package/Checkbox.svelte.d.ts +10 -0
- package/{dist/Dialog.svelte → Dialog.svelte} +30 -38
- package/Dialog.svelte.d.ts +14 -0
- package/Dropdown.svelte +109 -0
- package/Dropdown.svelte.d.ts +18 -0
- package/Input.svelte +55 -0
- package/Input.svelte.d.ts +12 -0
- package/Label.svelte +91 -0
- package/Label.svelte.d.ts +17 -0
- package/Link.svelte +25 -0
- package/Link.svelte.d.ts +12 -0
- package/{dist/List.svelte → List.svelte} +35 -85
- package/List.svelte.d.ts +20 -0
- package/List.types.d.ts +5 -0
- package/ListItem.svelte +49 -0
- package/ListItem.svelte.d.ts +13 -0
- package/{dist/Menu.svelte → Menu.svelte} +18 -45
- package/Menu.svelte.d.ts +13 -0
- package/{dist/MenuBar.svelte → MenuBar.svelte} +36 -78
- package/MenuBar.svelte.d.ts +13 -0
- package/MenuButton.svelte +116 -0
- package/MenuButton.svelte.d.ts +20 -0
- package/{dist/MenuItem.svelte → MenuItem.svelte} +107 -151
- package/MenuItem.svelte.d.ts +22 -0
- package/{dist/MenuItem.types.d.ts → MenuItem.types.d.ts} +1 -9
- package/MenuSeparator.svelte +11 -0
- package/MenuSeparator.svelte.d.ts +6 -0
- package/{dist/Popover.svelte → Popover.svelte} +45 -64
- package/Popover.svelte.d.ts +15 -0
- package/Progress.constants.d.ts +1 -0
- package/Progress.constants.js +1 -0
- package/Progress.svelte +36 -0
- package/Progress.svelte.d.ts +12 -0
- package/Progress.types.d.ts +4 -0
- package/Radio.svelte +53 -0
- package/Radio.svelte.d.ts +13 -0
- package/{dist/Select.svelte → Select.svelte} +55 -94
- package/Select.svelte.d.ts +20 -0
- package/Slider.svelte +133 -0
- package/Slider.svelte.d.ts +19 -0
- package/Switch.svelte +61 -0
- package/Switch.svelte.d.ts +21 -0
- package/Tab.svelte +51 -0
- package/Tab.svelte.d.ts +12 -0
- package/{dist/TabList.svelte → TabList.svelte} +50 -76
- package/TabList.svelte.d.ts +18 -0
- package/TabList.types.d.ts +5 -0
- package/{dist/TextArea.svelte → TextArea.svelte} +17 -59
- package/TextArea.svelte.d.ts +19 -0
- package/Tooltip.svelte +63 -0
- package/Tooltip.svelte.d.ts +10 -0
- package/Tree.svelte +53 -0
- package/Tree.svelte.d.ts +15 -0
- package/Tree.types.d.ts +5 -0
- package/TreeChevron.svelte +27 -0
- package/TreeChevron.svelte.d.ts +9 -0
- package/{dist/TreeItem.svelte → TreeItem.svelte} +105 -159
- package/TreeItem.svelte.d.ts +22 -0
- package/TreeItem.types.d.ts +4 -0
- package/{dist/actions → actions}/clickOutside.d.ts +1 -0
- package/{dist/actions → actions}/clickOutside.js +1 -0
- package/actions/extraClass.d.ts +8 -0
- package/actions/extraClass.js +14 -0
- package/{dist/index.d.ts → index.d.ts} +4 -12
- package/{dist/index.js → index.js} +3 -9
- package/package.json +26 -28
- package/README.md +0 -18
- package/dist/Button.constants.d.ts +0 -2
- package/dist/Button.constants.js +0 -2
- package/dist/Button.svelte +0 -63
- package/dist/Button.svelte.d.ts +0 -65
- package/dist/Button.types.d.ts +0 -6
- package/dist/Callout.svelte.d.ts +0 -56
- package/dist/Checkbox.svelte +0 -79
- package/dist/Checkbox.svelte.d.ts +0 -63
- package/dist/ColorPicker.constants.d.ts +0 -1
- package/dist/ColorPicker.constants.js +0 -1
- package/dist/ColorPicker.svelte +0 -287
- package/dist/ColorPicker.svelte.d.ts +0 -52
- package/dist/ColorPicker.types.d.ts +0 -4
- package/dist/ColorPicker.types.js +0 -1
- package/dist/Dialog.svelte.d.ts +0 -37
- package/dist/Dropdown.svelte +0 -138
- package/dist/Dropdown.svelte.d.ts +0 -77
- package/dist/HexColorSliders.svelte +0 -103
- package/dist/HexColorSliders.svelte.d.ts +0 -51
- package/dist/HslColorSliders.svelte +0 -128
- package/dist/HslColorSliders.svelte.d.ts +0 -51
- package/dist/Input.svelte +0 -89
- package/dist/Input.svelte.d.ts +0 -74
- package/dist/Label.svelte +0 -197
- package/dist/Label.svelte.d.ts +0 -82
- package/dist/Label.types.d.ts +0 -6
- package/dist/Label.types.js +0 -1
- package/dist/Link.svelte +0 -57
- package/dist/Link.svelte.d.ts +0 -65
- package/dist/List.svelte.d.ts +0 -75
- package/dist/List.types.d.ts +0 -13
- package/dist/ListItem.svelte +0 -78
- package/dist/ListItem.svelte.d.ts +0 -67
- package/dist/Menu.svelte.d.ts +0 -63
- package/dist/MenuBar.svelte.d.ts +0 -58
- package/dist/MenuButton.svelte +0 -145
- package/dist/MenuButton.svelte.d.ts +0 -71
- package/dist/MenuItem.svelte.d.ts +0 -83
- package/dist/MenuItemDisplay.svelte +0 -32
- package/dist/MenuItemDisplay.svelte.d.ts +0 -39
- package/dist/MenuSeparator.svelte +0 -9
- package/dist/MenuSeparator.svelte.d.ts +0 -20
- package/dist/Popover.svelte.d.ts +0 -59
- package/dist/Progress.constants.d.ts +0 -1
- package/dist/Progress.constants.js +0 -1
- package/dist/Progress.svelte +0 -83
- package/dist/Progress.svelte.d.ts +0 -61
- package/dist/Progress.types.d.ts +0 -4
- package/dist/Radio.svelte +0 -126
- package/dist/Radio.svelte.d.ts +0 -65
- package/dist/RgbColorSliders.svelte +0 -93
- package/dist/RgbColorSliders.svelte.d.ts +0 -24
- package/dist/Select.svelte.d.ts +0 -83
- package/dist/Slider.svelte +0 -190
- package/dist/Slider.svelte.d.ts +0 -66
- package/dist/Switch.svelte +0 -110
- package/dist/Switch.svelte.d.ts +0 -74
- package/dist/Tab.svelte +0 -94
- package/dist/Tab.svelte.d.ts +0 -71
- package/dist/TabList.svelte.d.ts +0 -70
- package/dist/TabList.types.d.ts +0 -13
- package/dist/TextArea.svelte.d.ts +0 -69
- package/dist/Tooltip.svelte +0 -106
- package/dist/Tooltip.svelte.d.ts +0 -70
- package/dist/Tree.svelte +0 -104
- package/dist/Tree.svelte.d.ts +0 -67
- package/dist/Tree.types.d.ts +0 -13
- package/dist/TreeChevron.svelte +0 -66
- package/dist/TreeChevron.svelte.d.ts +0 -53
- package/dist/TreeItem.svelte.d.ts +0 -101
- package/dist/TreeItem.types.d.ts +0 -14
- package/dist/TreeItemDisplay.svelte +0 -74
- package/dist/TreeItemDisplay.svelte.d.ts +0 -73
- package/dist/css/Button.base.css +0 -74
- package/dist/css/Button.colorful.css +0 -17
- package/dist/css/Button.css +0 -7
- package/dist/css/Button.secondary.colorful.css +0 -15
- package/dist/css/Button.secondary.css +0 -11
- package/dist/css/Button.shapes.css +0 -14
- package/dist/css/Button.tool.colorful.css +0 -13
- package/dist/css/Button.tool.css +0 -18
- package/dist/css/Callout.base.css +0 -43
- package/dist/css/Callout.colorful.css +0 -5
- package/dist/css/Callout.css +0 -2
- package/dist/css/Checkbox.base.css +0 -145
- package/dist/css/Checkbox.colorful.css +0 -17
- package/dist/css/Checkbox.css +0 -2
- package/dist/css/ColorPicker.base.css +0 -23
- package/dist/css/ColorPicker.css +0 -1
- package/dist/css/Dialog.base.css +0 -114
- package/dist/css/Dialog.css +0 -1
- package/dist/css/Dropdown.base.css +0 -147
- package/dist/css/Dropdown.colorful.css +0 -23
- package/dist/css/Dropdown.css +0 -2
- package/dist/css/HexColorSliders.base.css +0 -106
- package/dist/css/HexColorSliders.css +0 -1
- package/dist/css/HslColorSliders.base.css +0 -124
- package/dist/css/HslColorSliders.css +0 -1
- package/dist/css/Input.base.css +0 -103
- package/dist/css/Input.colorful.css +0 -22
- package/dist/css/Input.composed.css +0 -8
- package/dist/css/Input.css +0 -3
- package/dist/css/Label.base.css +0 -118
- package/dist/css/Label.boxed.colorful.css +0 -21
- package/dist/css/Label.boxed.css +0 -31
- package/dist/css/Label.colorful.css +0 -3
- package/dist/css/Label.css +0 -4
- package/dist/css/Link.base.css +0 -54
- package/dist/css/Link.colorful.css +0 -15
- package/dist/css/Link.css +0 -10
- package/dist/css/Link.ghost.colorful.css +0 -7
- package/dist/css/Link.ghost.css +0 -11
- package/dist/css/Link.text-underline.css +0 -8
- package/dist/css/Link.text-underline.ghost.css +0 -13
- package/dist/css/Link.undecorated.colorful.css +0 -8
- package/dist/css/Link.undecorated.css +0 -8
- package/dist/css/Link.undecorated.ghost.css +0 -8
- package/dist/css/Link.undecorated.underline.css +0 -8
- package/dist/css/List.base.css +0 -98
- package/dist/css/List.css +0 -1
- package/dist/css/ListItem.base.css +0 -59
- package/dist/css/ListItem.css +0 -1
- package/dist/css/Menu.base.css +0 -21
- package/dist/css/Menu.css +0 -1
- package/dist/css/MenuBar.base.css +0 -9
- package/dist/css/MenuBar.css +0 -1
- package/dist/css/MenuButton.base.css +0 -13
- package/dist/css/MenuButton.css +0 -1
- package/dist/css/MenuItem.base.css +0 -48
- package/dist/css/MenuItem.css +0 -1
- package/dist/css/MenuItemDisplay.base.css +0 -108
- package/dist/css/MenuItemDisplay.css +0 -1
- package/dist/css/MenuSeparator.base.css +0 -5
- package/dist/css/MenuSeparator.css +0 -1
- package/dist/css/Popover.css +0 -21
- package/dist/css/Progress.base.css +0 -99
- package/dist/css/Progress.css +0 -1
- package/dist/css/Radio.base.css +0 -135
- package/dist/css/Radio.colorful.css +0 -18
- package/dist/css/Radio.css +0 -2
- package/dist/css/RgbColorSliders.base.css +0 -94
- package/dist/css/RgbColorSliders.css +0 -1
- package/dist/css/Select.base.css +0 -127
- package/dist/css/Select.colorful.css +0 -24
- package/dist/css/Select.composed.css +0 -12
- package/dist/css/Select.css +0 -3
- package/dist/css/Slider.base.css +0 -192
- package/dist/css/Slider.colorful.css +0 -11
- package/dist/css/Slider.composed.css +0 -8
- package/dist/css/Slider.css +0 -3
- package/dist/css/Switch.base.css +0 -206
- package/dist/css/Switch.colorful.css +0 -45
- package/dist/css/Switch.css +0 -2
- package/dist/css/Tab.base.css +0 -132
- package/dist/css/Tab.colorful.css +0 -13
- package/dist/css/Tab.css +0 -2
- package/dist/css/TabList.base.css +0 -34
- package/dist/css/TabList.css +0 -1
- package/dist/css/TextArea.base.css +0 -85
- package/dist/css/TextArea.colorful.css +0 -17
- package/dist/css/TextArea.composed.css +0 -8
- package/dist/css/TextArea.css +0 -3
- package/dist/css/Tooltip.base.css +0 -6
- package/dist/css/Tooltip.css +0 -1
- package/dist/css/Tree.base.css +0 -74
- package/dist/css/Tree.composed.css +0 -8
- package/dist/css/Tree.css +0 -2
- package/dist/css/TreeChevron.base.css +0 -86
- package/dist/css/TreeChevron.css +0 -1
- package/dist/css/TreeItem.base.css +0 -3
- package/dist/css/TreeItem.css +0 -1
- package/dist/css/TreeItemDisplay.base.css +0 -74
- package/dist/css/TreeItemDisplay.colorful.css +0 -9
- package/dist/css/TreeItemDisplay.css +0 -1
- package/dist/css/dark-mode.css +0 -134
- package/dist/css/light-mode.css +0 -134
- package/dist/css/sterling.css +0 -37
- package/dist/package.json +0 -108
- /package/{dist/@types → @types}/clickOutside.d.ts +0 -0
- /package/{dist/Button.types.js → Callout.types.js} +0 -0
- /package/{dist/Label.constants.d.ts → Label.constants.d.ts} +0 -0
- /package/{dist/Label.constants.js → Label.constants.js} +0 -0
- /package/{dist/List.constants.d.ts → List.constants.d.ts} +0 -0
- /package/{dist/List.constants.js → List.constants.js} +0 -0
- /package/{dist/List.types.js → List.types.js} +0 -0
- /package/{dist/MenuBar.constants.d.ts → MenuBar.constants.d.ts} +0 -0
- /package/{dist/MenuBar.constants.js → MenuBar.constants.js} +0 -0
- /package/{dist/MenuBar.types.d.ts → MenuBar.types.d.ts} +0 -0
- /package/{dist/MenuBar.types.js → MenuBar.types.js} +0 -0
- /package/{dist/MenuItem.constants.d.ts → MenuItem.constants.d.ts} +0 -0
- /package/{dist/MenuItem.constants.js → MenuItem.constants.js} +0 -0
- /package/{dist/MenuItem.types.js → MenuItem.types.js} +0 -0
- /package/{dist/MenuItem.utils.d.ts → MenuItem.utils.d.ts} +0 -0
- /package/{dist/MenuItem.utils.js → MenuItem.utils.js} +0 -0
- /package/{dist/Popover.constants.d.ts → Popover.constants.d.ts} +0 -0
- /package/{dist/Popover.constants.js → Popover.constants.js} +0 -0
- /package/{dist/Popover.types.d.ts → Popover.types.d.ts} +0 -0
- /package/{dist/Popover.types.js → Popover.types.js} +0 -0
- /package/{dist/Portal.constants.d.ts → Portal.constants.d.ts} +0 -0
- /package/{dist/Portal.constants.js → Portal.constants.js} +0 -0
- /package/{dist/Portal.types.d.ts → Portal.types.d.ts} +0 -0
- /package/{dist/Portal.types.js → Portal.types.js} +0 -0
- /package/{dist/Progress.types.js → Progress.types.js} +0 -0
- /package/{dist/TabList.constants.d.ts → TabList.constants.d.ts} +0 -0
- /package/{dist/TabList.constants.js → TabList.constants.js} +0 -0
- /package/{dist/TabList.types.js → TabList.types.js} +0 -0
- /package/{dist/TextArea.constants.d.ts → TextArea.constants.d.ts} +0 -0
- /package/{dist/TextArea.constants.js → TextArea.constants.js} +0 -0
- /package/{dist/TextArea.types.d.ts → TextArea.types.d.ts} +0 -0
- /package/{dist/TextArea.types.js → TextArea.types.js} +0 -0
- /package/{dist/Tree.constants.d.ts → Tree.constants.d.ts} +0 -0
- /package/{dist/Tree.constants.js → Tree.constants.js} +0 -0
- /package/{dist/Tree.types.js → Tree.types.js} +0 -0
- /package/{dist/TreeItem.constants.d.ts → TreeItem.constants.d.ts} +0 -0
- /package/{dist/TreeItem.constants.js → TreeItem.constants.js} +0 -0
- /package/{dist/TreeItem.types.js → TreeItem.types.js} +0 -0
- /package/{dist/actions → actions}/applyLightDarkMode.d.ts +0 -0
- /package/{dist/actions → actions}/applyLightDarkMode.js +0 -0
- /package/{dist/actions → actions}/forwardEvents.d.ts +0 -0
- /package/{dist/actions → actions}/forwardEvents.js +0 -0
- /package/{dist/actions → actions}/portal.d.ts +0 -0
- /package/{dist/actions → actions}/portal.js +0 -0
- /package/{dist/actions → actions}/trapKeyboardFocus.d.ts +0 -0
- /package/{dist/actions → actions}/trapKeyboardFocus.js +0 -0
- /package/{dist/idGenerator.d.ts → idGenerator.d.ts} +0 -0
- /package/{dist/idGenerator.js → idGenerator.js} +0 -0
- /package/{dist/mediaQueries → mediaQueries}/prefersColorSchemeDark.d.ts +0 -0
- /package/{dist/mediaQueries → mediaQueries}/prefersColorSchemeDark.js +0 -0
- /package/{dist/mediaQueries → mediaQueries}/prefersReducedMotion.d.ts +0 -0
- /package/{dist/mediaQueries → mediaQueries}/prefersReducedMotion.js +0 -0
- /package/{dist/mediaQueries → mediaQueries}/usingKeyboard.d.ts +0 -0
- /package/{dist/mediaQueries → mediaQueries}/usingKeyboard.js +0 -0
|
@@ -1,29 +1,14 @@
|
|
|
1
|
-
<
|
|
1
|
+
<svelte:options runes={true} />
|
|
2
|
+
|
|
3
|
+
<script lang="ts">import { getContext, onMount, tick } from 'svelte';
|
|
2
4
|
import { autoUpdate, computePosition, flip, offset } from '@floating-ui/dom';
|
|
3
5
|
import { portal } from './actions/portal';
|
|
4
6
|
import { STERLING_PORTAL_HOST_ID, STERLING_PORTAL_CONTEXT_ID } from './Portal.constants';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/** The offset towards or away from the side of the reference element. */
|
|
11
|
-
export let mainAxisOffset = 0;
|
|
12
|
-
/** When true, the popover is open and visible. */
|
|
13
|
-
export let open = false;
|
|
14
|
-
/** How the popover should be positioned relative to the reference element. */
|
|
15
|
-
export let placement = 'top-start';
|
|
16
|
-
/** The host container for the callout. */
|
|
17
|
-
export let portalHost = undefined;
|
|
18
|
-
/** The reference to the element anchoring the position of the popover. */
|
|
19
|
-
export let reference;
|
|
20
|
-
/** Additional class names to apply. */
|
|
21
|
-
export let variant = '';
|
|
22
|
-
// ----- State ----- //
|
|
23
|
-
let popupRef;
|
|
24
|
-
let popupPosition = { x: 0, y: 0 };
|
|
25
|
-
$: floatingUIPlacement = placement;
|
|
26
|
-
let bodyHeight = 0;
|
|
7
|
+
let { children, conditionalRender = $bindable(true), crossAxisOffset = $bindable(0), mainAxisOffset = $bindable(0), open = $bindable(false), placement = $bindable('top-start'), portalHost, reference, class: _class, ...rest } = $props();
|
|
8
|
+
let popupRef = $state(undefined);
|
|
9
|
+
let popupPosition = $state({ x: 0, y: 0 });
|
|
10
|
+
let floatingUIPlacement = $derived(placement);
|
|
11
|
+
let bodyHeight = $state(0);
|
|
27
12
|
let resizeObserver = undefined;
|
|
28
13
|
const { portalHost: contextPortalHost } = getContext(STERLING_PORTAL_CONTEXT_ID) || {
|
|
29
14
|
portalHost: undefined
|
|
@@ -46,13 +31,11 @@ const ensurePortalHost = async () => {
|
|
|
46
31
|
}
|
|
47
32
|
portalHost = host;
|
|
48
33
|
};
|
|
49
|
-
$: {
|
|
50
|
-
if ($contextPortalHost || !$contextPortalHost) {
|
|
51
|
-
ensurePortalHost();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
34
|
// ----- Position ----- //
|
|
55
|
-
|
|
35
|
+
let middleware = $derived([
|
|
36
|
+
offset({ mainAxis: mainAxisOffset, crossAxis: crossAxisOffset }),
|
|
37
|
+
flip()
|
|
38
|
+
]);
|
|
56
39
|
const computePopoverPosition = async () => {
|
|
57
40
|
if (reference && popupRef) {
|
|
58
41
|
popupPosition = await computePosition(reference, popupRef, {
|
|
@@ -72,10 +55,19 @@ const autoUpdatePopoverPosition = () => {
|
|
|
72
55
|
cleanupAutoUpdate = autoUpdate(reference, popupRef, computePopoverPosition);
|
|
73
56
|
}
|
|
74
57
|
};
|
|
75
|
-
|
|
76
|
-
|
|
58
|
+
$effect(() => {
|
|
59
|
+
autoUpdatePopoverPosition();
|
|
60
|
+
return () => {
|
|
61
|
+
cleanupAutoUpdate();
|
|
62
|
+
cleanupAutoUpdate = () => { };
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
$effect(() => {
|
|
66
|
+
bodyHeight;
|
|
67
|
+
computePopoverPosition();
|
|
68
|
+
});
|
|
77
69
|
// ----- EventHandlers ----- //
|
|
78
|
-
|
|
70
|
+
$effect(() => {
|
|
79
71
|
ensurePortalHost();
|
|
80
72
|
resizeObserver = new ResizeObserver((entries) => {
|
|
81
73
|
bodyHeight = entries[0].target.clientHeight;
|
|
@@ -92,49 +84,38 @@ const onKeydown = (event) => {
|
|
|
92
84
|
if (event.key === 'Escape') {
|
|
93
85
|
open = false;
|
|
94
86
|
}
|
|
87
|
+
rest.onkeydown?.(event);
|
|
95
88
|
};
|
|
89
|
+
//TODO: Is this necessary?
|
|
96
90
|
ensurePortalHost();
|
|
97
91
|
</script>
|
|
98
92
|
|
|
99
93
|
{#if open || !conditionalRender}
|
|
100
94
|
<div use:portal={{ target: portalHost }} class="sterling-popover-portal">
|
|
101
|
-
<!-- svelte-ignore
|
|
95
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
102
96
|
<div
|
|
103
97
|
bind:this={popupRef}
|
|
104
|
-
class={
|
|
98
|
+
class={['sterling-popover', _class].filter(Boolean).join(' ')}
|
|
105
99
|
class:open
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
on:keydown
|
|
121
|
-
on:keypress
|
|
122
|
-
on:keyup
|
|
123
|
-
on:mousedown
|
|
124
|
-
on:mouseenter
|
|
125
|
-
on:mouseleave
|
|
126
|
-
on:mousemove
|
|
127
|
-
on:mouseover
|
|
128
|
-
on:mouseout
|
|
129
|
-
on:mouseup
|
|
130
|
-
on:scroll
|
|
131
|
-
on:wheel|passive
|
|
132
|
-
on:paste
|
|
133
|
-
on:keydown={onKeydown}
|
|
134
|
-
{...$$restProps}
|
|
100
|
+
class:top={popupPosition.placement === 'top'}
|
|
101
|
+
class:top-start={popupPosition.placement === 'top-start'}
|
|
102
|
+
class:top-end={popupPosition.placement === 'top-end'}
|
|
103
|
+
class:right={popupPosition.placement === 'right'}
|
|
104
|
+
class:right-start={popupPosition.placement === 'right-start'}
|
|
105
|
+
class:right-end={popupPosition.placement === 'right-end'}
|
|
106
|
+
class:bottom={popupPosition.placement === 'bottom'}
|
|
107
|
+
class:bottom-start={popupPosition.placement === 'bottom-start'}
|
|
108
|
+
class:bottom-end={popupPosition.placement === 'bottom-end'}
|
|
109
|
+
class:left={popupPosition.placement === 'left'}
|
|
110
|
+
class:left-start={popupPosition.placement === 'left-start'}
|
|
111
|
+
class:left-end={popupPosition.placement === 'left-end'}
|
|
112
|
+
{...rest}
|
|
113
|
+
onkeydown={onKeydown}
|
|
135
114
|
style="left:{popupPosition.x}px; top:{popupPosition.y}px"
|
|
136
115
|
>
|
|
137
|
-
|
|
116
|
+
{#if children}
|
|
117
|
+
{@render children()}
|
|
118
|
+
{/if}
|
|
138
119
|
</div>
|
|
139
120
|
</div>
|
|
140
121
|
{/if}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="svelte" />
|
|
2
|
+
import type { PopoverPlacement } from './Popover.types';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
type Props = HTMLAttributes<HTMLDivElement> & {
|
|
5
|
+
conditionalRender?: boolean;
|
|
6
|
+
crossAxisOffset?: number;
|
|
7
|
+
mainAxisOffset?: number;
|
|
8
|
+
open?: boolean | null;
|
|
9
|
+
placement?: PopoverPlacement;
|
|
10
|
+
portalHost?: HTMLElement;
|
|
11
|
+
reference?: HTMLElement;
|
|
12
|
+
};
|
|
13
|
+
declare const Popover: import("svelte").Component<Props, {}, "conditionalRender" | "crossAxisOffset" | "mainAxisOffset" | "open" | "placement">;
|
|
14
|
+
type Popover = ReturnType<typeof Popover>;
|
|
15
|
+
export default Popover;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PROGRESS_ORIENTATIONS: string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PROGRESS_ORIENTATIONS = ['horizontal', 'vertical'];
|
package/Progress.svelte
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<svelte:options runes={true} />
|
|
2
|
+
|
|
3
|
+
<script lang="ts">let { class: _class, disabled = false, max = 100, percent = $bindable(0), //readonly
|
|
4
|
+
value = $bindable(0), vertical, ...rest } = $props();
|
|
5
|
+
//----- State ----- //
|
|
6
|
+
let clientHeight = $state(0);
|
|
7
|
+
let clientWidth = $state(0);
|
|
8
|
+
let clampMax = $derived(Math.max(1, max));
|
|
9
|
+
let clampValue = $derived(Math.max(0, Math.min(value, clampMax)));
|
|
10
|
+
let ratio = $derived(clampValue / clampMax);
|
|
11
|
+
$effect(() => {
|
|
12
|
+
percent = Math.round(ratio * 100);
|
|
13
|
+
});
|
|
14
|
+
let percentHeight = $derived(clientHeight * ratio);
|
|
15
|
+
let percentWidth = $derived(clientWidth * ratio);
|
|
16
|
+
let indicatorStyle = $derived(vertical ? `height: ${percentHeight}px` : `width: ${percentWidth}px`);
|
|
17
|
+
export {};
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<!-- svelte-ignore a11y_role_supports_aria_props -->
|
|
21
|
+
<div
|
|
22
|
+
aria-orientation={vertical ? 'vertical' : 'horizontal'}
|
|
23
|
+
class={['sterling-progress', _class].filter(Boolean).join(' ')}
|
|
24
|
+
class:disabled
|
|
25
|
+
class:horizontal={!vertical}
|
|
26
|
+
class:vertical
|
|
27
|
+
data-progress-percent={percent}
|
|
28
|
+
data-progress-max={max}
|
|
29
|
+
data-progress-value={value}
|
|
30
|
+
role="progressbar"
|
|
31
|
+
{...rest}
|
|
32
|
+
>
|
|
33
|
+
<div class="container" bind:clientWidth bind:clientHeight>
|
|
34
|
+
<div class="indicator" style={indicatorStyle}></div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/// <reference types="svelte" />
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type Props = HTMLAttributes<HTMLDivElement> & {
|
|
4
|
+
disabled?: boolean | null;
|
|
5
|
+
max?: number;
|
|
6
|
+
percent?: number;
|
|
7
|
+
value?: number;
|
|
8
|
+
vertical?: boolean | null;
|
|
9
|
+
};
|
|
10
|
+
declare const Progress: import("svelte").Component<Props, {}, "value" | "percent">;
|
|
11
|
+
type Progress = ReturnType<typeof Progress>;
|
|
12
|
+
export default Progress;
|
package/Radio.svelte
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<svelte:options runes={true} />
|
|
2
|
+
|
|
3
|
+
<script lang="ts">import { idGenerator } from './idGenerator';
|
|
4
|
+
import { usingKeyboard } from './mediaQueries/usingKeyboard';
|
|
5
|
+
let { id, children, checked = $bindable(false), class: _class, disabled = false, group = $bindable(), ...rest } = $props();
|
|
6
|
+
let inputRef;
|
|
7
|
+
$effect(() => {
|
|
8
|
+
if (children && id === undefined) {
|
|
9
|
+
id = idGenerator.nextId('Radio');
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
// ----- Methods ----- //
|
|
13
|
+
export const blur = () => {
|
|
14
|
+
inputRef?.blur();
|
|
15
|
+
};
|
|
16
|
+
export const click = () => {
|
|
17
|
+
inputRef?.click();
|
|
18
|
+
};
|
|
19
|
+
export const focus = (options) => {
|
|
20
|
+
inputRef?.focus(options);
|
|
21
|
+
};
|
|
22
|
+
// ----- Event Handlers ----- //
|
|
23
|
+
const onChange = (e) => {
|
|
24
|
+
console.log('onChange', e);
|
|
25
|
+
// if ((e.currentTarget && e.currentTarget.checked) || (e.target && e.target.checked)) {
|
|
26
|
+
// group = value;
|
|
27
|
+
// }
|
|
28
|
+
};
|
|
29
|
+
$effect(() => {
|
|
30
|
+
console.log(id, '-checked', checked);
|
|
31
|
+
});
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<!--
|
|
35
|
+
@component
|
|
36
|
+
A styled HTML input type=radio element with optional label.
|
|
37
|
+
-->
|
|
38
|
+
<div
|
|
39
|
+
class={`sterling-radio ${_class}`}
|
|
40
|
+
class:checked
|
|
41
|
+
class:disabled
|
|
42
|
+
class:using-keyboard={$usingKeyboard}
|
|
43
|
+
>
|
|
44
|
+
<div class="container">
|
|
45
|
+
<input bind:this={inputRef} checked {disabled} bind:group {id} type="radio" {...rest} />
|
|
46
|
+
<div class="indicator"></div>
|
|
47
|
+
</div>
|
|
48
|
+
{#if children}
|
|
49
|
+
<label for={id}>
|
|
50
|
+
{@render children()}
|
|
51
|
+
</label>
|
|
52
|
+
{/if}
|
|
53
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="svelte" />
|
|
2
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
+
type Props = HTMLInputAttributes & {
|
|
4
|
+
group?: any | null;
|
|
5
|
+
};
|
|
6
|
+
/** A styled HTML input type=radio element with optional label. */
|
|
7
|
+
declare const Radio: import("svelte").Component<Props, {
|
|
8
|
+
blur: () => void;
|
|
9
|
+
click: () => void;
|
|
10
|
+
focus: (options?: FocusOptions) => void;
|
|
11
|
+
}, "group" | "checked">;
|
|
12
|
+
type Radio = ReturnType<typeof Radio>;
|
|
13
|
+
export default Radio;
|
|
@@ -1,49 +1,32 @@
|
|
|
1
|
-
<
|
|
1
|
+
<svelte:options runes={true} />
|
|
2
|
+
|
|
3
|
+
<script lang="ts">import { tick } from 'svelte';
|
|
2
4
|
import { clickOutside } from './actions/clickOutside';
|
|
3
5
|
import { idGenerator } from './idGenerator';
|
|
4
6
|
import List from './List.svelte';
|
|
5
7
|
import Popover from './Popover.svelte';
|
|
8
|
+
let { buttonSnippet, children, class: _class, disabled = false, open = $bindable(false), onSelect, onPending, selectedValue = $bindable(), listClass, valueSnippet, ...rest } = $props();
|
|
6
9
|
const popupId = idGenerator.nextId('Select-popup');
|
|
7
|
-
// ----- Props ----- //
|
|
8
|
-
export let disabled = false;
|
|
9
|
-
/** When true, the select's dropdown is open. */
|
|
10
|
-
export let open = false;
|
|
11
|
-
/** The value of the selected item.*/
|
|
12
|
-
export let selectedValue = undefined;
|
|
13
|
-
/** Additional class names to apply. */
|
|
14
|
-
export let variant = '';
|
|
15
|
-
/** Additional class names to apply to the List*/
|
|
16
|
-
export let listVariant = '';
|
|
17
10
|
// ----- State ----- //
|
|
18
|
-
// Tracks the previous open state
|
|
19
|
-
let prevOpen = false;
|
|
20
11
|
// Tracks the pending selected index
|
|
21
|
-
let pendingSelectedValue = selectedValue;
|
|
22
|
-
|
|
12
|
+
let pendingSelectedValue = $state(selectedValue);
|
|
13
|
+
// svelte-ignore non_reactive_update
|
|
14
|
+
let selectRef = $state(undefined);
|
|
23
15
|
let listRef;
|
|
24
|
-
// ----- Events ----- //
|
|
25
|
-
const dispatch = createEventDispatcher();
|
|
26
|
-
const raiseSelect = (value) => {
|
|
27
|
-
dispatch('select', { value });
|
|
28
|
-
};
|
|
29
|
-
const raisePending = (value) => {
|
|
30
|
-
dispatch('pending', { value });
|
|
31
|
-
};
|
|
32
16
|
// ----- Reactions ----- //
|
|
33
|
-
|
|
17
|
+
$effect(() => {
|
|
34
18
|
pendingSelectedValue = selectedValue;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
19
|
+
});
|
|
20
|
+
$effect(() => {
|
|
21
|
+
onSelect?.(selectedValue);
|
|
22
|
+
});
|
|
23
|
+
$effect(() => {
|
|
40
24
|
if (open) {
|
|
41
|
-
|
|
25
|
+
onPending?.(pendingSelectedValue);
|
|
42
26
|
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (open
|
|
46
|
-
prevOpen = true;
|
|
27
|
+
});
|
|
28
|
+
$effect(() => {
|
|
29
|
+
if (open) {
|
|
47
30
|
tick().then(() => {
|
|
48
31
|
setTimeout(() => {
|
|
49
32
|
listRef?.focus();
|
|
@@ -51,11 +34,12 @@ $: {
|
|
|
51
34
|
}, 10);
|
|
52
35
|
});
|
|
53
36
|
}
|
|
54
|
-
|
|
55
|
-
|
|
37
|
+
});
|
|
38
|
+
$effect(() => {
|
|
39
|
+
if (!open) {
|
|
56
40
|
tick().then(() => selectRef?.focus());
|
|
57
41
|
}
|
|
58
|
-
}
|
|
42
|
+
});
|
|
59
43
|
// ----- Methods ----- //
|
|
60
44
|
export const blur = () => {
|
|
61
45
|
selectRef?.blur();
|
|
@@ -78,6 +62,7 @@ const onSelectClick = (event) => {
|
|
|
78
62
|
event.preventDefault();
|
|
79
63
|
event.stopPropagation();
|
|
80
64
|
}
|
|
65
|
+
rest.onclick?.(event);
|
|
81
66
|
};
|
|
82
67
|
const onSelectKeydown = (event) => {
|
|
83
68
|
if (!disabled && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
|
|
@@ -95,10 +80,10 @@ const onSelectKeydown = (event) => {
|
|
|
95
80
|
case 'ArrowUp':
|
|
96
81
|
{
|
|
97
82
|
if (selectedValue) {
|
|
98
|
-
listRef
|
|
83
|
+
listRef?.selectPreviousItem();
|
|
99
84
|
}
|
|
100
85
|
else {
|
|
101
|
-
listRef
|
|
86
|
+
listRef?.selectLastItem();
|
|
102
87
|
}
|
|
103
88
|
event.preventDefault();
|
|
104
89
|
event.stopPropagation();
|
|
@@ -108,10 +93,10 @@ const onSelectKeydown = (event) => {
|
|
|
108
93
|
case 'ArrowDown':
|
|
109
94
|
{
|
|
110
95
|
if (selectedValue) {
|
|
111
|
-
listRef
|
|
96
|
+
listRef?.selectNextItem();
|
|
112
97
|
}
|
|
113
98
|
else {
|
|
114
|
-
listRef
|
|
99
|
+
listRef?.selectFirstItem();
|
|
115
100
|
}
|
|
116
101
|
event.preventDefault();
|
|
117
102
|
event.stopPropagation();
|
|
@@ -120,6 +105,7 @@ const onSelectKeydown = (event) => {
|
|
|
120
105
|
break;
|
|
121
106
|
}
|
|
122
107
|
}
|
|
108
|
+
rest.onkeydown?.(event);
|
|
123
109
|
};
|
|
124
110
|
const onListKeydown = (event) => {
|
|
125
111
|
if (!disabled && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
|
|
@@ -151,8 +137,8 @@ const onListClick = (event) => {
|
|
|
151
137
|
event.stopPropagation();
|
|
152
138
|
return false;
|
|
153
139
|
};
|
|
154
|
-
const onListSelect = (
|
|
155
|
-
pendingSelectedValue =
|
|
140
|
+
const onListSelect = (value) => {
|
|
141
|
+
pendingSelectedValue = value;
|
|
156
142
|
if (!open) {
|
|
157
143
|
selectedValue = pendingSelectedValue;
|
|
158
144
|
}
|
|
@@ -164,71 +150,46 @@ const onListSelect = (event) => {
|
|
|
164
150
|
aria-controls={popupId}
|
|
165
151
|
aria-haspopup="listbox"
|
|
166
152
|
aria-expanded={open}
|
|
167
|
-
class={
|
|
153
|
+
class={['sterling-select', _class].filter(Boolean).join(' ')}
|
|
168
154
|
class:disabled
|
|
169
155
|
role="combobox"
|
|
170
156
|
tabindex="0"
|
|
171
|
-
use:clickOutside
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
on:cut
|
|
176
|
-
on:dblclick
|
|
177
|
-
on:dragend
|
|
178
|
-
on:dragenter
|
|
179
|
-
on:dragleave
|
|
180
|
-
on:dragover
|
|
181
|
-
on:dragstart
|
|
182
|
-
on:drop
|
|
183
|
-
on:focus
|
|
184
|
-
on:focusin
|
|
185
|
-
on:focusout
|
|
186
|
-
on:keydown
|
|
187
|
-
on:keypress
|
|
188
|
-
on:keyup
|
|
189
|
-
on:mousedown
|
|
190
|
-
on:mouseenter
|
|
191
|
-
on:mouseleave
|
|
192
|
-
on:mousemove
|
|
193
|
-
on:mouseover
|
|
194
|
-
on:mouseout
|
|
195
|
-
on:mouseup
|
|
196
|
-
on:wheel|passive
|
|
197
|
-
on:paste
|
|
198
|
-
on:click={onSelectClick}
|
|
199
|
-
on:click_outside={() => (open = false)}
|
|
200
|
-
on:keydown={onSelectKeydown}
|
|
201
|
-
{...$$restProps}
|
|
157
|
+
use:clickOutside={{ onclickoutside: () => (open = false) }}
|
|
158
|
+
{...rest}
|
|
159
|
+
onclick={onSelectClick}
|
|
160
|
+
onkeydown={onSelectKeydown}
|
|
202
161
|
>
|
|
203
162
|
<div class="value">
|
|
204
|
-
|
|
205
|
-
{
|
|
206
|
-
|
|
207
|
-
{
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
163
|
+
{#if valueSnippet}
|
|
164
|
+
{@render valueSnippet(selectedValue)}
|
|
165
|
+
{:else if selectedValue}
|
|
166
|
+
{selectedValue}
|
|
167
|
+
{:else}
|
|
168
|
+
<span> </span>
|
|
169
|
+
{/if}
|
|
211
170
|
</div>
|
|
212
171
|
<div class="button">
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
172
|
+
{#if buttonSnippet}
|
|
173
|
+
{@render buttonSnippet()}
|
|
174
|
+
{:else}
|
|
175
|
+
<div class="chevron"></div>
|
|
176
|
+
{/if}
|
|
218
177
|
</div>
|
|
219
178
|
<Popover reference={selectRef} bind:open id={popupId} conditionalRender={false}>
|
|
220
|
-
<div class={
|
|
179
|
+
<div class={['sterling-select-popup-content', _class].filter(Boolean).join(' ')}>
|
|
221
180
|
<List
|
|
222
181
|
bind:this={listRef}
|
|
223
182
|
{disabled}
|
|
224
183
|
selectedValue={pendingSelectedValue}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
184
|
+
onclick={onListClick}
|
|
185
|
+
onkeydown={onListKeydown}
|
|
186
|
+
onSelect={onListSelect}
|
|
187
|
+
tabindex={open ? 0 : -1}
|
|
188
|
+
class={`composed ${listClass}`}
|
|
230
189
|
>
|
|
231
|
-
|
|
190
|
+
{#if children}
|
|
191
|
+
{@render children()}
|
|
192
|
+
{/if}
|
|
232
193
|
</List>
|
|
233
194
|
</div>
|
|
234
195
|
</Popover>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type Props = HTMLAttributes<HTMLDivElement> & {
|
|
4
|
+
buttonSnippet?: Snippet;
|
|
5
|
+
disabled?: boolean | null;
|
|
6
|
+
listClass?: string;
|
|
7
|
+
onPending?: (value?: string) => void;
|
|
8
|
+
onSelect?: (value?: string) => void;
|
|
9
|
+
open?: boolean | null;
|
|
10
|
+
selectedValue?: string;
|
|
11
|
+
valueSnippet?: Snippet<[string | undefined]>;
|
|
12
|
+
};
|
|
13
|
+
declare const Select: import("svelte").Component<Props, {
|
|
14
|
+
blur: () => void;
|
|
15
|
+
click: () => void;
|
|
16
|
+
focus: (options?: FocusOptions) => void;
|
|
17
|
+
scrollToSelectedItem: () => void;
|
|
18
|
+
}, "open" | "selectedValue">;
|
|
19
|
+
type Select = ReturnType<typeof Select>;
|
|
20
|
+
export default Select;
|
package/Slider.svelte
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<svelte:options runes={true} />
|
|
2
|
+
|
|
3
|
+
<script lang="ts">import { round } from 'lodash-es';
|
|
4
|
+
let { class: _class, disabled, min = 0, max = 100, onChange, precision = 0, step = 1, value = $bindable(0), vertical, ...rest } = $props();
|
|
5
|
+
let sliderRef;
|
|
6
|
+
export const blur = () => {
|
|
7
|
+
sliderRef?.blur();
|
|
8
|
+
};
|
|
9
|
+
export const click = () => {
|
|
10
|
+
sliderRef?.click();
|
|
11
|
+
};
|
|
12
|
+
export const focus = (options) => {
|
|
13
|
+
sliderRef?.focus();
|
|
14
|
+
};
|
|
15
|
+
let ratio = $derived((value - min) / (max - min));
|
|
16
|
+
const setValue = (newValue) => {
|
|
17
|
+
const clamped = Math.max(min, Math.min(max, newValue));
|
|
18
|
+
value = precision !== undefined ? round(clamped, precision) : clamped;
|
|
19
|
+
};
|
|
20
|
+
// ensure min <= max
|
|
21
|
+
$effect(() => {
|
|
22
|
+
if (min > max) {
|
|
23
|
+
min = max;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
$effect(() => {
|
|
27
|
+
const clamped = Math.max(min, Math.min(max, value));
|
|
28
|
+
const newValue = precision !== undefined ? round(clamped, precision) : clamped;
|
|
29
|
+
if (value !== newValue) {
|
|
30
|
+
value = newValue;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const setValueByOffset = (offset) => {
|
|
34
|
+
if (sliderSize > 0) {
|
|
35
|
+
const positionRatio = Math.max(0, Math.min(1, offset / sliderSize));
|
|
36
|
+
const newValue = min + positionRatio * (max - min);
|
|
37
|
+
setValue(newValue);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
// Raise change event when value changes
|
|
41
|
+
$effect(() => {
|
|
42
|
+
onChange?.(value);
|
|
43
|
+
});
|
|
44
|
+
// ----- Size tracking ----- //
|
|
45
|
+
let sliderWidth = $state(0);
|
|
46
|
+
let sliderHeight = $state(0);
|
|
47
|
+
let sliderSize = $derived(vertical ? sliderHeight : sliderWidth);
|
|
48
|
+
let valueOffset = $derived(sliderSize * ratio);
|
|
49
|
+
// ----- Event handlers ----- //
|
|
50
|
+
const onPointerDown = (event) => {
|
|
51
|
+
if (!disabled) {
|
|
52
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
53
|
+
if (vertical) {
|
|
54
|
+
setValueByOffset(sliderRef.getBoundingClientRect().bottom - event.y);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
setValueByOffset(event.x - sliderRef.getBoundingClientRect().left);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
rest?.onpointerdown?.(event);
|
|
61
|
+
};
|
|
62
|
+
const onPointerMove = (event) => {
|
|
63
|
+
if (!disabled && event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
64
|
+
if (vertical) {
|
|
65
|
+
setValueByOffset(sliderRef.getBoundingClientRect().bottom - event.y);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
setValueByOffset(event.x - sliderRef.getBoundingClientRect().left);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
rest?.onpointermove?.(event);
|
|
72
|
+
};
|
|
73
|
+
const onPointerUp = (event) => {
|
|
74
|
+
if (!disabled) {
|
|
75
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
76
|
+
}
|
|
77
|
+
rest?.onpointerup?.(event);
|
|
78
|
+
};
|
|
79
|
+
const onKeyDown = (event) => {
|
|
80
|
+
if (!disabled && !event.ctrlKey && !event.shiftKey && !event.altKey) {
|
|
81
|
+
switch (event.code) {
|
|
82
|
+
case 'ArrowDown':
|
|
83
|
+
case 'ArrowLeft':
|
|
84
|
+
setValue(value - step);
|
|
85
|
+
event.preventDefault();
|
|
86
|
+
event.stopPropagation();
|
|
87
|
+
return;
|
|
88
|
+
case 'ArrowRight':
|
|
89
|
+
case 'ArrowUp':
|
|
90
|
+
setValue(value + step);
|
|
91
|
+
event.preventDefault();
|
|
92
|
+
event.stopPropagation();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
rest?.onkeydown?.(event);
|
|
97
|
+
};
|
|
98
|
+
</script>
|
|
99
|
+
|
|
100
|
+
<div
|
|
101
|
+
aria-disabled={disabled}
|
|
102
|
+
aria-valuemin={min}
|
|
103
|
+
aria-valuenow={value}
|
|
104
|
+
aria-valuemax={max}
|
|
105
|
+
class={`sterling-slider ${_class}`}
|
|
106
|
+
class:disabled
|
|
107
|
+
class:horizontal={!vertical}
|
|
108
|
+
class:vertical
|
|
109
|
+
role="slider"
|
|
110
|
+
tabindex={!disabled ? 0 : undefined}
|
|
111
|
+
{...rest}
|
|
112
|
+
onkeydown={onKeyDown}
|
|
113
|
+
onpointerdown={onPointerDown}
|
|
114
|
+
onpointermove={onPointerMove}
|
|
115
|
+
onpointerup={onPointerUp}
|
|
116
|
+
>
|
|
117
|
+
<div
|
|
118
|
+
class="container"
|
|
119
|
+
bind:this={sliderRef}
|
|
120
|
+
bind:clientWidth={sliderWidth}
|
|
121
|
+
bind:clientHeight={sliderHeight}
|
|
122
|
+
>
|
|
123
|
+
<div class="track"></div>
|
|
124
|
+
<div
|
|
125
|
+
class="fill"
|
|
126
|
+
style={vertical ? `height: ${valueOffset}px` : `width: ${valueOffset}px`}
|
|
127
|
+
></div>
|
|
128
|
+
<div
|
|
129
|
+
class="thumb"
|
|
130
|
+
style={vertical ? `bottom: ${valueOffset}px` : `left: ${valueOffset}px`}
|
|
131
|
+
></div>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|