@geoffcox/sterling-svelte 2.0.0 → 2.0.2
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.json +21 -23
- package/.DS_Store +0 -0
- package/@types/clickOutside.d.ts +0 -15
- package/Button.svelte +0 -25
- package/Button.svelte.d.ts +0 -9
- package/Callout.svelte +0 -177
- package/Callout.svelte.d.ts +0 -15
- package/Callout.types.d.ts +0 -11
- package/Callout.types.js +0 -1
- package/Checkbox.svelte +0 -43
- package/Checkbox.svelte.d.ts +0 -10
- package/Dialog.svelte +0 -151
- package/Dialog.svelte.d.ts +0 -14
- package/Dropdown.svelte +0 -109
- package/Dropdown.svelte.d.ts +0 -18
- package/Input.svelte +0 -55
- package/Input.svelte.d.ts +0 -12
- package/Label.constants.d.ts +0 -2
- package/Label.constants.js +0 -2
- package/Label.svelte +0 -91
- package/Label.svelte.d.ts +0 -17
- package/Link.svelte +0 -25
- package/Link.svelte.d.ts +0 -12
- package/List.constants.d.ts +0 -1
- package/List.constants.js +0 -1
- package/List.svelte +0 -203
- package/List.svelte.d.ts +0 -20
- package/List.types.d.ts +0 -5
- package/List.types.js +0 -1
- package/ListItem.svelte +0 -49
- package/ListItem.svelte.d.ts +0 -13
- package/Menu.svelte +0 -83
- package/Menu.svelte.d.ts +0 -13
- package/MenuBar.constants.d.ts +0 -1
- package/MenuBar.constants.js +0 -1
- package/MenuBar.svelte +0 -113
- package/MenuBar.svelte.d.ts +0 -13
- package/MenuBar.types.d.ts +0 -4
- package/MenuBar.types.js +0 -1
- package/MenuButton.svelte +0 -116
- package/MenuButton.svelte.d.ts +0 -20
- package/MenuItem.constants.d.ts +0 -2
- package/MenuItem.constants.js +0 -2
- package/MenuItem.svelte +0 -342
- package/MenuItem.svelte.d.ts +0 -22
- package/MenuItem.types.d.ts +0 -20
- package/MenuItem.types.js +0 -1
- package/MenuItem.utils.d.ts +0 -7
- package/MenuItem.utils.js +0 -36
- package/MenuSeparator.svelte +0 -11
- package/MenuSeparator.svelte.d.ts +0 -6
- package/Popover.constants.d.ts +0 -1
- package/Popover.constants.js +0 -14
- package/Popover.svelte +0 -121
- package/Popover.svelte.d.ts +0 -15
- package/Popover.types.d.ts +0 -4
- package/Popover.types.js +0 -1
- package/Portal.constants.d.ts +0 -2
- package/Portal.constants.js +0 -2
- package/Portal.types.d.ts +0 -6
- package/Portal.types.js +0 -1
- package/Progress.constants.d.ts +0 -1
- package/Progress.constants.js +0 -1
- package/Progress.svelte +0 -36
- package/Progress.svelte.d.ts +0 -12
- package/Progress.types.d.ts +0 -4
- package/Progress.types.js +0 -1
- package/Radio.svelte +0 -53
- package/Radio.svelte.d.ts +0 -13
- package/Select.svelte +0 -196
- package/Select.svelte.d.ts +0 -20
- package/Slider.svelte +0 -133
- package/Slider.svelte.d.ts +0 -19
- package/Switch.svelte +0 -61
- package/Switch.svelte.d.ts +0 -21
- package/Tab.svelte +0 -51
- package/Tab.svelte.d.ts +0 -12
- package/TabList.constants.d.ts +0 -1
- package/TabList.constants.js +0 -1
- package/TabList.svelte +0 -202
- package/TabList.svelte.d.ts +0 -18
- package/TabList.types.d.ts +0 -5
- package/TabList.types.js +0 -1
- package/TextArea.constants.d.ts +0 -1
- package/TextArea.constants.js +0 -1
- package/TextArea.svelte +0 -74
- package/TextArea.svelte.d.ts +0 -19
- package/TextArea.types.d.ts +0 -4
- package/TextArea.types.js +0 -1
- package/Tooltip.svelte +0 -63
- package/Tooltip.svelte.d.ts +0 -10
- package/Tree.constants.d.ts +0 -1
- package/Tree.constants.js +0 -1
- package/Tree.svelte +0 -53
- package/Tree.svelte.d.ts +0 -15
- package/Tree.types.d.ts +0 -5
- package/Tree.types.js +0 -1
- package/TreeChevron.svelte +0 -27
- package/TreeChevron.svelte.d.ts +0 -9
- package/TreeItem.constants.d.ts +0 -1
- package/TreeItem.constants.js +0 -1
- package/TreeItem.svelte +0 -329
- package/TreeItem.svelte.d.ts +0 -22
- package/TreeItem.types.d.ts +0 -4
- package/TreeItem.types.js +0 -1
- package/actions/applyLightDarkMode.d.ts +0 -10
- package/actions/applyLightDarkMode.js +0 -36
- package/actions/clickOutside.d.ts +0 -15
- package/actions/clickOutside.js +0 -28
- package/actions/extraClass.d.ts +0 -8
- package/actions/extraClass.js +0 -14
- package/actions/forwardEvents.d.ts +0 -12
- package/actions/forwardEvents.js +0 -32
- package/actions/portal.d.ts +0 -8
- package/actions/portal.js +0 -19
- package/actions/trapKeyboardFocus.d.ts +0 -3
- package/actions/trapKeyboardFocus.js +0 -52
- package/idGenerator.d.ts +0 -4
- package/idGenerator.js +0 -10
- package/index.d.ts +0 -59
- package/index.js +0 -54
- package/mediaQueries/prefersColorSchemeDark.d.ts +0 -2
- package/mediaQueries/prefersColorSchemeDark.js +0 -14
- package/mediaQueries/prefersReducedMotion.d.ts +0 -2
- package/mediaQueries/prefersReducedMotion.js +0 -14
- package/mediaQueries/usingKeyboard.d.ts +0 -2
- package/mediaQueries/usingKeyboard.js +0 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geoffcox/sterling-svelte",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"author": "Geoff Cox",
|
|
5
5
|
"description": "A modern, accessible, and lightweight UI component library for Svelte.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"files": [
|
|
49
|
-
"
|
|
49
|
+
"dist",
|
|
50
50
|
"!**/*.test.*",
|
|
51
51
|
"!**/*.spec.*"
|
|
52
52
|
],
|
|
@@ -60,40 +60,38 @@
|
|
|
60
60
|
"package": "svelte-kit sync && svelte-package && publint",
|
|
61
61
|
"preview": "vite preview",
|
|
62
62
|
"test": "npm run test:integration && npm run test:unit",
|
|
63
|
-
"test:integration": "playwright test",
|
|
64
63
|
"test:unit": "vitest"
|
|
65
64
|
},
|
|
66
65
|
"peerDependencies": {
|
|
67
66
|
"svelte": "^5.0.0"
|
|
68
67
|
},
|
|
69
68
|
"devDependencies": {
|
|
69
|
+
"@eslint/compat": "^1.2.5",
|
|
70
|
+
"@eslint/js": "^9.18.0",
|
|
70
71
|
"@fontsource/atkinson-hyperlegible": "^5.1.1",
|
|
71
|
-
"@fontsource/open-sans": "^4.5.14",
|
|
72
72
|
"@fontsource/source-code-pro": "^4.5.14",
|
|
73
|
-
"@geoffcox/sterling-svelte-themes": "^1.0.
|
|
74
|
-
"@
|
|
75
|
-
"@
|
|
76
|
-
"@sveltejs/adapter-auto": "^3.0.0",
|
|
77
|
-
"@sveltejs/adapter-static": "^3.0.0",
|
|
78
|
-
"@sveltejs/kit": "^2.0.0",
|
|
73
|
+
"@geoffcox/sterling-svelte-themes": "^1.0.4",
|
|
74
|
+
"@sveltejs/adapter-static": "^3.0.8",
|
|
75
|
+
"@sveltejs/kit": "^2.16.0",
|
|
79
76
|
"@sveltejs/package": "^2.0.0",
|
|
80
|
-
"@sveltejs/vite-plugin-svelte": "^
|
|
81
|
-
"@
|
|
77
|
+
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
|
78
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
79
|
+
"@testing-library/svelte": "^5.2.4",
|
|
82
80
|
"@types/lodash-es": "^4.17.6",
|
|
83
|
-
"eslint": "^9.
|
|
84
|
-
"eslint-config-prettier": "^
|
|
85
|
-
"eslint-plugin-svelte": "^
|
|
86
|
-
"globals": "^
|
|
87
|
-
"
|
|
88
|
-
"prettier
|
|
89
|
-
"
|
|
81
|
+
"eslint": "^9.18.0",
|
|
82
|
+
"eslint-config-prettier": "^10.0.1",
|
|
83
|
+
"eslint-plugin-svelte": "^3.0.0",
|
|
84
|
+
"globals": "^16.0.0",
|
|
85
|
+
"jsdom": "^26.0.0",
|
|
86
|
+
"prettier": "^3.4.2",
|
|
87
|
+
"prettier-plugin-svelte": "^3.3.3",
|
|
88
|
+
"publint": "^0.3.2",
|
|
90
89
|
"svelte": "^5.0.0",
|
|
91
90
|
"svelte-check": "^4.0.0",
|
|
92
|
-
"svelte-preprocess": "^6.0.3",
|
|
93
91
|
"typescript": "^5.0.0",
|
|
94
|
-
"typescript-eslint": "^8.
|
|
95
|
-
"vite": "^
|
|
96
|
-
"vitest": "^
|
|
92
|
+
"typescript-eslint": "^8.20.0",
|
|
93
|
+
"vite": "^6.0.0",
|
|
94
|
+
"vitest": "^3.0.0"
|
|
97
95
|
},
|
|
98
96
|
"dependencies": {
|
|
99
97
|
"@floating-ui/dom": "^1.1.0",
|
package/.DS_Store
DELETED
|
Binary file
|
package/@types/clickOutside.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { EventHandler } from 'svelte/elements';
|
|
2
|
-
|
|
3
|
-
export type ClickOutsideEventDetail = {
|
|
4
|
-
mouseEvent: MouseEvent;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export type ClickOutsideEvent = CustomEvent<ClickOutsideEventDetail>;
|
|
8
|
-
|
|
9
|
-
declare module 'svelte/elements' {
|
|
10
|
-
export interface DOMAttributes<T extends EventTarget> {
|
|
11
|
-
'on:click_outside'?: EventHandler<ClickOutsideEvent, T>;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export {}; // ensure this is not an ambient module, else types will be overridden instead of augmented
|
package/Button.svelte
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<svelte:options runes={true} />
|
|
2
|
-
|
|
3
|
-
<script lang="ts">let { children, class: _class, ...rest } = $props();
|
|
4
|
-
let buttonRef;
|
|
5
|
-
export const click = () => {
|
|
6
|
-
buttonRef?.click();
|
|
7
|
-
};
|
|
8
|
-
export const blur = () => {
|
|
9
|
-
buttonRef?.blur();
|
|
10
|
-
};
|
|
11
|
-
export const focus = (options) => {
|
|
12
|
-
buttonRef?.focus(options);
|
|
13
|
-
};
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
<button
|
|
17
|
-
bind:this={buttonRef}
|
|
18
|
-
class={['sterling-button', _class].filter(Boolean).join(' ')}
|
|
19
|
-
type="button"
|
|
20
|
-
{...rest}
|
|
21
|
-
>
|
|
22
|
-
{#if children}
|
|
23
|
-
{@render children()}
|
|
24
|
-
{/if}
|
|
25
|
-
</button>
|
package/Button.svelte.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/// <reference types="svelte" />
|
|
2
|
-
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
-
declare const Button: import("svelte").Component<HTMLButtonAttributes, {
|
|
4
|
-
click: () => void;
|
|
5
|
-
blur: () => void;
|
|
6
|
-
focus: (options?: FocusOptions) => void;
|
|
7
|
-
}, "">;
|
|
8
|
-
type Button = ReturnType<typeof Button>;
|
|
9
|
-
export default Button;
|
package/Callout.svelte
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
<svelte:options runes={true} />
|
|
2
|
-
|
|
3
|
-
<script lang="ts">import { getContext, tick } from 'svelte';
|
|
4
|
-
import { arrow, autoUpdate, computePosition, flip, offset } from '@floating-ui/dom';
|
|
5
|
-
import { portal } from './actions/portal';
|
|
6
|
-
import { fade } from 'svelte/transition';
|
|
7
|
-
import { prefersReducedMotion } from './mediaQueries/prefersReducedMotion';
|
|
8
|
-
import { STERLING_PORTAL_HOST_ID, STERLING_PORTAL_CONTEXT_ID } from './Portal.constants';
|
|
9
|
-
let { children, conditionalRender = $bindable(true), crossAxisOffset = $bindable(0), mainAxisOffset = $bindable(0), open = $bindable(false), placement = $bindable('top-start'), portalHost, reference, class: _class, ...rest } = $props();
|
|
10
|
-
let popupRef = $state(undefined);
|
|
11
|
-
let arrowRef = $state(undefined);
|
|
12
|
-
let popupPosition = $state({ x: 0, y: 0 });
|
|
13
|
-
let floatingUIPlacement = $derived(placement);
|
|
14
|
-
let bodyHeight = $state(0);
|
|
15
|
-
let resizeObserver = undefined;
|
|
16
|
-
const { portalHost: contextPortalHost } = getContext(STERLING_PORTAL_CONTEXT_ID) || {
|
|
17
|
-
portalHost: undefined
|
|
18
|
-
};
|
|
19
|
-
const ensurePortalHost = async () => {
|
|
20
|
-
await tick();
|
|
21
|
-
// use the host set from context, usually set from a Dialog
|
|
22
|
-
let host = $contextPortalHost;
|
|
23
|
-
// use or create the sterling portal host
|
|
24
|
-
if (!host && globalThis?.document) {
|
|
25
|
-
host = globalThis.document.querySelector(`#${STERLING_PORTAL_HOST_ID}`);
|
|
26
|
-
// fallback to creating the sterling portal host
|
|
27
|
-
if (!host) {
|
|
28
|
-
host = globalThis.document.createElement('div');
|
|
29
|
-
host.id = STERLING_PORTAL_HOST_ID;
|
|
30
|
-
host.style.overflow = 'visible';
|
|
31
|
-
globalThis.document.body.append(host);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
portalHost = host;
|
|
35
|
-
};
|
|
36
|
-
let middleware = $derived([
|
|
37
|
-
offset({ mainAxis: mainAxisOffset, crossAxis: crossAxisOffset }),
|
|
38
|
-
flip(),
|
|
39
|
-
arrowRef && arrow({ element: arrowRef, padding: 8 })
|
|
40
|
-
]);
|
|
41
|
-
const computeCalloutPosition = async () => {
|
|
42
|
-
if (reference && popupRef) {
|
|
43
|
-
popupPosition = await computePosition(reference, popupRef, {
|
|
44
|
-
placement: floatingUIPlacement,
|
|
45
|
-
middleware
|
|
46
|
-
});
|
|
47
|
-
console.log('popupPosition', popupPosition);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
popupPosition = { x: 0, y: 0 };
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
// whenever a positioned element is portaled it needs resubscription to auto-update
|
|
54
|
-
let cleanupAutoUpdate = () => { };
|
|
55
|
-
const autoUpdateCalloutPosition = () => {
|
|
56
|
-
cleanupAutoUpdate();
|
|
57
|
-
cleanupAutoUpdate = () => { };
|
|
58
|
-
if (reference && popupRef) {
|
|
59
|
-
cleanupAutoUpdate = autoUpdate(reference, popupRef, computeCalloutPosition);
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
$effect(() => {
|
|
63
|
-
autoUpdateCalloutPosition();
|
|
64
|
-
return () => {
|
|
65
|
-
cleanupAutoUpdate();
|
|
66
|
-
cleanupAutoUpdate = () => { };
|
|
67
|
-
};
|
|
68
|
-
});
|
|
69
|
-
$effect(() => {
|
|
70
|
-
bodyHeight;
|
|
71
|
-
reference;
|
|
72
|
-
computeCalloutPosition();
|
|
73
|
-
});
|
|
74
|
-
// ----- Arrow ----- //
|
|
75
|
-
const getArrowPlacementStyle = (position) => {
|
|
76
|
-
if (position?.placement && arrowRef) {
|
|
77
|
-
switch (position.placement) {
|
|
78
|
-
case 'top':
|
|
79
|
-
case 'top-start':
|
|
80
|
-
case 'top-end':
|
|
81
|
-
return (`bottom: -${arrowRef.offsetWidth}px;` + `transform:translate(0, -50%) rotate(135deg);`);
|
|
82
|
-
case 'right':
|
|
83
|
-
case 'right-start':
|
|
84
|
-
case 'right-end':
|
|
85
|
-
return (`left: -${arrowRef.offsetWidth}px;` + `transform:translate(50%, 0) rotate(225deg);`);
|
|
86
|
-
case 'bottom':
|
|
87
|
-
case 'bottom-start':
|
|
88
|
-
case 'bottom-end':
|
|
89
|
-
return `top: -${arrowRef.offsetWidth}px;` + `transform:translate(0, 50%) rotate(-45deg);`;
|
|
90
|
-
case 'left':
|
|
91
|
-
case 'left-start':
|
|
92
|
-
case 'left-end':
|
|
93
|
-
return (`right: -${arrowRef.offsetWidth}px;` + `transform:translate(-50%, 0) rotate(45deg);`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return '';
|
|
97
|
-
};
|
|
98
|
-
const getArrowOffsetStyle = (position) => {
|
|
99
|
-
const arrow = position?.middlewareData?.arrow;
|
|
100
|
-
if (arrow) {
|
|
101
|
-
if (arrow.x !== null && arrow.x !== undefined) {
|
|
102
|
-
return `left: ${arrow.x}px;`;
|
|
103
|
-
}
|
|
104
|
-
else if (arrow.y !== null && arrow.y !== undefined) {
|
|
105
|
-
return `top: ${arrow.y}px;`;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return '';
|
|
109
|
-
};
|
|
110
|
-
let arrowStyle = $derived(getArrowPlacementStyle(popupPosition) + getArrowOffsetStyle(popupPosition));
|
|
111
|
-
// ----- Animation ----- //
|
|
112
|
-
const fadeNoOp = (node, params) => {
|
|
113
|
-
return { delay: 0, duration: 0 };
|
|
114
|
-
};
|
|
115
|
-
let fadeMotion = $derived(!$prefersReducedMotion ? fade : fadeNoOp);
|
|
116
|
-
// ----- EventHandlers ----- //
|
|
117
|
-
const onKeydown = (event) => {
|
|
118
|
-
if (event.key === 'Escape') {
|
|
119
|
-
open = false;
|
|
120
|
-
}
|
|
121
|
-
rest.onkeydown?.(event);
|
|
122
|
-
};
|
|
123
|
-
$effect(() => {
|
|
124
|
-
ensurePortalHost();
|
|
125
|
-
resizeObserver = new ResizeObserver((entries) => {
|
|
126
|
-
bodyHeight = entries[0].target.clientHeight;
|
|
127
|
-
});
|
|
128
|
-
// start observing a DOM node
|
|
129
|
-
resizeObserver.observe(document.body);
|
|
130
|
-
return () => {
|
|
131
|
-
resizeObserver?.unobserve(document.body);
|
|
132
|
-
resizeObserver?.disconnect();
|
|
133
|
-
resizeObserver = undefined;
|
|
134
|
-
};
|
|
135
|
-
});
|
|
136
|
-
ensurePortalHost();
|
|
137
|
-
</script>
|
|
138
|
-
|
|
139
|
-
{#if open || !conditionalRender}
|
|
140
|
-
<div
|
|
141
|
-
use:portal={{ target: portalHost }}
|
|
142
|
-
class="sterling-callout-portal"
|
|
143
|
-
transition:fadeMotion|global={{ duration: 250 }}
|
|
144
|
-
>
|
|
145
|
-
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
146
|
-
<div
|
|
147
|
-
bind:this={popupRef}
|
|
148
|
-
class={['sterling-callout', _class].filter(Boolean).join(' ')}
|
|
149
|
-
class:open
|
|
150
|
-
class:top={popupPosition.placement === 'top'}
|
|
151
|
-
class:top-start={popupPosition.placement === 'top-start'}
|
|
152
|
-
class:top-end={popupPosition.placement === 'top-end'}
|
|
153
|
-
class:right={popupPosition.placement === 'right'}
|
|
154
|
-
class:right-start={popupPosition.placement === 'right-start'}
|
|
155
|
-
class:right-end={popupPosition.placement === 'right-end'}
|
|
156
|
-
class:bottom={popupPosition.placement === 'bottom'}
|
|
157
|
-
class:bottom-start={popupPosition.placement === 'bottom-start'}
|
|
158
|
-
class:bottom-end={popupPosition.placement === 'bottom-end'}
|
|
159
|
-
class:left={popupPosition.placement === 'left'}
|
|
160
|
-
class:left-start={popupPosition.placement === 'left-start'}
|
|
161
|
-
class:left-end={popupPosition.placement === 'left-end'}
|
|
162
|
-
role="tooltip"
|
|
163
|
-
{...rest}
|
|
164
|
-
onkeydown={onKeydown}
|
|
165
|
-
style="left:{popupPosition.x}px; top:{popupPosition.y}px"
|
|
166
|
-
>
|
|
167
|
-
{#if children}
|
|
168
|
-
{#if typeof children === 'string'}
|
|
169
|
-
<div class="callout-text">{children}</div>
|
|
170
|
-
{:else}
|
|
171
|
-
{@render children()}
|
|
172
|
-
{/if}
|
|
173
|
-
{/if}
|
|
174
|
-
<div class="arrow" bind:this={arrowRef} style={arrowStyle}></div>
|
|
175
|
-
</div>
|
|
176
|
-
</div>
|
|
177
|
-
{/if}
|
package/Callout.svelte.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
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 | null;
|
|
6
|
-
crossAxisOffset?: number;
|
|
7
|
-
mainAxisOffset?: number;
|
|
8
|
-
open?: boolean | null;
|
|
9
|
-
placement?: PopoverPlacement;
|
|
10
|
-
portalHost?: HTMLElement;
|
|
11
|
-
reference?: HTMLElement | null;
|
|
12
|
-
};
|
|
13
|
-
declare const Callout: import("svelte").Component<Props, {}, "conditionalRender" | "crossAxisOffset" | "mainAxisOffset" | "open" | "placement">;
|
|
14
|
-
type Callout = ReturnType<typeof Callout>;
|
|
15
|
-
export default Callout;
|
package/Callout.types.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
-
import type { PopoverPlacement } from './Popover.types';
|
|
3
|
-
export type CalloutProps = HTMLAttributes<HTMLDivElement> & {
|
|
4
|
-
conditionalRender?: boolean | null;
|
|
5
|
-
crossAxisOffset?: number;
|
|
6
|
-
mainAxisOffset?: number;
|
|
7
|
-
open?: boolean | null;
|
|
8
|
-
placement?: PopoverPlacement;
|
|
9
|
-
portalHost?: HTMLElement;
|
|
10
|
-
reference?: HTMLElement | null;
|
|
11
|
-
};
|
package/Callout.types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/Checkbox.svelte
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
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 = $bindable(false), ...rest } = $props();
|
|
6
|
-
let inputRef;
|
|
7
|
-
$effect(() => {
|
|
8
|
-
if (children && id === undefined) {
|
|
9
|
-
id = idGenerator.nextId('Checkbox');
|
|
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
|
-
</script>
|
|
23
|
-
|
|
24
|
-
<!--
|
|
25
|
-
@component
|
|
26
|
-
A styled HTML input type=checkbox element.
|
|
27
|
-
-->
|
|
28
|
-
<div
|
|
29
|
-
class={['sterling-checkbox', _class].filter(Boolean).join(' ')}
|
|
30
|
-
class:checked
|
|
31
|
-
class:disabled
|
|
32
|
-
class:using-keyboard={$usingKeyboard}
|
|
33
|
-
>
|
|
34
|
-
<div class="container">
|
|
35
|
-
<input bind:this={inputRef} bind:checked {disabled} {id} type="checkbox" {...rest} />
|
|
36
|
-
<div class="indicator"></div>
|
|
37
|
-
</div>
|
|
38
|
-
{#if children}
|
|
39
|
-
<label for={id}>
|
|
40
|
-
{@render children()}
|
|
41
|
-
</label>
|
|
42
|
-
{/if}
|
|
43
|
-
</div>
|
package/Checkbox.svelte.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/// <reference types="svelte" />
|
|
2
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
/** A styled HTML input type=checkbox element. */
|
|
4
|
-
declare const Checkbox: import("svelte").Component<HTMLInputAttributes, {
|
|
5
|
-
blur: () => void;
|
|
6
|
-
click: () => void;
|
|
7
|
-
focus: (options?: FocusOptions) => void;
|
|
8
|
-
}, "disabled" | "checked">;
|
|
9
|
-
type Checkbox = ReturnType<typeof Checkbox>;
|
|
10
|
-
export default Checkbox;
|
package/Dialog.svelte
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
<svelte:options runes={true} />
|
|
2
|
-
|
|
3
|
-
<script lang="ts">import { onMount, setContext, tick } from 'svelte';
|
|
4
|
-
import Button from './Button.svelte';
|
|
5
|
-
import { STERLING_PORTAL_CONTEXT_ID } from './Portal.constants';
|
|
6
|
-
import { writable } from 'svelte/store';
|
|
7
|
-
const dialogFadeDuration = 250;
|
|
8
|
-
let { backdropCloses = false, open = $bindable(false), body, class: _class, content, footer, header, returnValue = $bindable(''), headerTitle, ...rest } = $props();
|
|
9
|
-
let dialogRef;
|
|
10
|
-
let contentRef;
|
|
11
|
-
let formRef;
|
|
12
|
-
// svelte-ignore non_reactive_update
|
|
13
|
-
let closing = false;
|
|
14
|
-
const portalHostStore = writable(undefined);
|
|
15
|
-
// ----- Context ----- //
|
|
16
|
-
setContext(STERLING_PORTAL_CONTEXT_ID, { portalHost: portalHostStore });
|
|
17
|
-
// ----- Event Handlers ----- //
|
|
18
|
-
const onDocumentClick = (event) => {
|
|
19
|
-
// as tracking clicks outside the dialog is only active while the dialog is open
|
|
20
|
-
// the clickOutside action is not used and reimplemented here.
|
|
21
|
-
const targetNode = event?.target;
|
|
22
|
-
// the content must be used as the container because dialog::backdrop is considered
|
|
23
|
-
// part of the HTMLDialogElement
|
|
24
|
-
if (targetNode && !contentRef?.contains(targetNode) && backdropCloses) {
|
|
25
|
-
open = false;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
const showDialog = () => {
|
|
29
|
-
if (dialogRef?.open === false) {
|
|
30
|
-
// when open, track clicks outside the dialog (use capture = true)
|
|
31
|
-
document.addEventListener('click', onDocumentClick, true);
|
|
32
|
-
returnValue = '';
|
|
33
|
-
dialogRef.showModal();
|
|
34
|
-
}
|
|
35
|
-
open = true;
|
|
36
|
-
};
|
|
37
|
-
const closeDialog = async () => {
|
|
38
|
-
if (dialogRef?.open === true) {
|
|
39
|
-
// when closed, stop tracking clicks outside the dialog
|
|
40
|
-
document.removeEventListener('click', onDocumentClick);
|
|
41
|
-
// to allow time for the CSS transition animation, closing the dialog is delayed
|
|
42
|
-
closing = true;
|
|
43
|
-
await tick();
|
|
44
|
-
setTimeout(() => {
|
|
45
|
-
dialogRef.close(returnValue);
|
|
46
|
-
open = false;
|
|
47
|
-
closing = false;
|
|
48
|
-
}, dialogFadeDuration);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
open = false;
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
const updateDialog = (open) => {
|
|
55
|
-
if (open) {
|
|
56
|
-
showDialog();
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
closeDialog();
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
const onCancel = (event) => {
|
|
63
|
-
// Cancelling a dialog instantly hides the dialog.
|
|
64
|
-
// To allow animation with closeDialog, this event is canceled.
|
|
65
|
-
event.preventDefault();
|
|
66
|
-
event.stopPropagation();
|
|
67
|
-
returnValue = '';
|
|
68
|
-
closeDialog();
|
|
69
|
-
return false;
|
|
70
|
-
};
|
|
71
|
-
const onSubmit = (event) => {
|
|
72
|
-
// Submitting a form instantly hides the dialog.
|
|
73
|
-
// The dialog.close event is not cancellable, but form.submit is.
|
|
74
|
-
// To allow animation with closeDialog, this event is canceled.
|
|
75
|
-
// The form is resubmitted after the dialog closes to ensure the form is in the correct state.
|
|
76
|
-
const anyEvent = event;
|
|
77
|
-
if (anyEvent?.submitter.type === 'submit') {
|
|
78
|
-
if (dialogRef.open) {
|
|
79
|
-
const eventSubmitter = anyEvent?.submitter;
|
|
80
|
-
returnValue = eventSubmitter?.value ?? '';
|
|
81
|
-
closeDialog();
|
|
82
|
-
setTimeout(() => {
|
|
83
|
-
formRef.requestSubmit(eventSubmitter);
|
|
84
|
-
}, dialogFadeDuration);
|
|
85
|
-
event.preventDefault();
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
event.preventDefault();
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
$effect(() => {
|
|
95
|
-
updateDialog(open);
|
|
96
|
-
});
|
|
97
|
-
onMount(() => {
|
|
98
|
-
updateDialog(open);
|
|
99
|
-
// Use the dialog for any element portals
|
|
100
|
-
portalHostStore.set(dialogRef);
|
|
101
|
-
dialogRef.addEventListener('cancel', onCancel);
|
|
102
|
-
return () => {
|
|
103
|
-
dialogRef?.removeEventListener('cancel', onCancel);
|
|
104
|
-
portalHostStore.set(undefined);
|
|
105
|
-
};
|
|
106
|
-
});
|
|
107
|
-
</script>
|
|
108
|
-
|
|
109
|
-
<dialog
|
|
110
|
-
bind:this={dialogRef}
|
|
111
|
-
class={`sterling-dialog ${_class}`}
|
|
112
|
-
class:open
|
|
113
|
-
class:closing
|
|
114
|
-
{...rest}
|
|
115
|
-
>
|
|
116
|
-
<form method="dialog" bind:this={formRef} onsubmit={onSubmit}>
|
|
117
|
-
<div class="content" bind:this={contentRef}>
|
|
118
|
-
{#if content}
|
|
119
|
-
{@render content()}
|
|
120
|
-
{:else}
|
|
121
|
-
<div class="header">
|
|
122
|
-
{#if header}
|
|
123
|
-
{@render header()}
|
|
124
|
-
{:else}
|
|
125
|
-
<div class="title">
|
|
126
|
-
{#if headerTitle}
|
|
127
|
-
{#if typeof headerTitle === 'string'}
|
|
128
|
-
{headerTitle}
|
|
129
|
-
{:else}
|
|
130
|
-
{@render headerTitle()}
|
|
131
|
-
{/if}
|
|
132
|
-
{/if}
|
|
133
|
-
</div>
|
|
134
|
-
<div class="close">
|
|
135
|
-
<Button class={`circular tool`} onclick={() => closeDialog()}>
|
|
136
|
-
<div class="close-x"></div>
|
|
137
|
-
</Button>
|
|
138
|
-
</div>
|
|
139
|
-
{/if}
|
|
140
|
-
</div>
|
|
141
|
-
<div class="body">
|
|
142
|
-
{@render body?.()}
|
|
143
|
-
</div>
|
|
144
|
-
<div class="separator"></div>
|
|
145
|
-
<div class="footer">
|
|
146
|
-
{@render footer?.()}
|
|
147
|
-
</div>
|
|
148
|
-
{/if}
|
|
149
|
-
</div>
|
|
150
|
-
</form>
|
|
151
|
-
</dialog>
|
package/Dialog.svelte.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { HTMLDialogAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Snippet } from 'svelte';
|
|
3
|
-
type Props = HTMLDialogAttributes & {
|
|
4
|
-
backdropCloses?: boolean | null | undefined;
|
|
5
|
-
body?: Snippet;
|
|
6
|
-
content?: Snippet;
|
|
7
|
-
footer?: Snippet;
|
|
8
|
-
header?: Snippet;
|
|
9
|
-
returnValue?: string;
|
|
10
|
-
headerTitle?: string | Snippet;
|
|
11
|
-
};
|
|
12
|
-
declare const Dialog: import("svelte").Component<Props, {}, "open" | "returnValue">;
|
|
13
|
-
type Dialog = ReturnType<typeof Dialog>;
|
|
14
|
-
export default Dialog;
|
package/Dropdown.svelte
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
<svelte:options runes={true} />
|
|
2
|
-
|
|
3
|
-
<script lang="ts">import {} from 'svelte';
|
|
4
|
-
import Popover from './Popover.svelte';
|
|
5
|
-
import { clickOutside } from './actions/clickOutside';
|
|
6
|
-
import { idGenerator } from './idGenerator';
|
|
7
|
-
import { prefersReducedMotion } from './mediaQueries/prefersReducedMotion';
|
|
8
|
-
import { slide } from 'svelte/transition';
|
|
9
|
-
import { usingKeyboard } from './mediaQueries/usingKeyboard';
|
|
10
|
-
const popupId = idGenerator.nextId('Dropdown-popup');
|
|
11
|
-
let { class: _class, children, disabled = false, open = $bindable(false), onOpen, stayOpenOnClickAway = false, button, buttonIcon, value, ...rest } = $props();
|
|
12
|
-
// svelte-ignore non_reactive_update
|
|
13
|
-
let dropdownRef = $state(undefined);
|
|
14
|
-
// svelte-ignore non_reactive_update
|
|
15
|
-
let popupContentRef = $state(undefined);
|
|
16
|
-
// ----- Reactions ----- //
|
|
17
|
-
$effect(() => {
|
|
18
|
-
onOpen?.(open);
|
|
19
|
-
});
|
|
20
|
-
// ----- Methods ----- //
|
|
21
|
-
export const click = () => {
|
|
22
|
-
dropdownRef?.click();
|
|
23
|
-
};
|
|
24
|
-
export const blur = () => {
|
|
25
|
-
dropdownRef?.blur();
|
|
26
|
-
};
|
|
27
|
-
export const focus = (options) => {
|
|
28
|
-
dropdownRef?.focus(options);
|
|
29
|
-
};
|
|
30
|
-
const onClick = (event) => {
|
|
31
|
-
if (!disabled) {
|
|
32
|
-
open = !open;
|
|
33
|
-
event.preventDefault();
|
|
34
|
-
event.stopPropagation();
|
|
35
|
-
}
|
|
36
|
-
rest.onclick?.(event);
|
|
37
|
-
};
|
|
38
|
-
const onKeydown = (event) => {
|
|
39
|
-
if (!event.altKey && !event.ctrlKey && !event.shiftKey) {
|
|
40
|
-
switch (event.key) {
|
|
41
|
-
case ' ':
|
|
42
|
-
open = !open;
|
|
43
|
-
event.preventDefault();
|
|
44
|
-
event.stopPropagation();
|
|
45
|
-
case 'Escape':
|
|
46
|
-
open = false;
|
|
47
|
-
event.preventDefault();
|
|
48
|
-
event.stopPropagation();
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
rest.onkeydown?.(event);
|
|
52
|
-
};
|
|
53
|
-
const onClickOutside = (event) => {
|
|
54
|
-
if (!stayOpenOnClickAway) {
|
|
55
|
-
open = false;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
// ----- Animation ----- //
|
|
59
|
-
const slideNoOp = (node, params) => {
|
|
60
|
-
return { delay: 0, duration: 0 };
|
|
61
|
-
};
|
|
62
|
-
let slideMotion = $derived(!$prefersReducedMotion ? slide : slideNoOp);
|
|
63
|
-
</script>
|
|
64
|
-
|
|
65
|
-
<div
|
|
66
|
-
bind:this={dropdownRef}
|
|
67
|
-
aria-controls={popupId}
|
|
68
|
-
aria-haspopup={true}
|
|
69
|
-
aria-expanded={open}
|
|
70
|
-
class={`sterling-dropdown ${_class}`}
|
|
71
|
-
class:disabled
|
|
72
|
-
class:open
|
|
73
|
-
class:using-keyboard={$usingKeyboard}
|
|
74
|
-
role="combobox"
|
|
75
|
-
tabindex="0"
|
|
76
|
-
use:clickOutside={{ ignoreOthers: [popupContentRef!], onclickoutside: onClickOutside }}
|
|
77
|
-
{...rest}
|
|
78
|
-
onclick={onClick}
|
|
79
|
-
onkeydown={onKeydown}
|
|
80
|
-
>
|
|
81
|
-
<div class="value">
|
|
82
|
-
{#if value}
|
|
83
|
-
{#if typeof value === 'string'}
|
|
84
|
-
{value}
|
|
85
|
-
{:else}
|
|
86
|
-
{@render value()}
|
|
87
|
-
{/if}
|
|
88
|
-
{/if}
|
|
89
|
-
</div>
|
|
90
|
-
<div class="button">
|
|
91
|
-
{#if button}
|
|
92
|
-
{@render button()}
|
|
93
|
-
{:else if buttonIcon}
|
|
94
|
-
{@render buttonIcon()}
|
|
95
|
-
{:else}
|
|
96
|
-
<div class="chevron"></div>
|
|
97
|
-
{/if}
|
|
98
|
-
</div>
|
|
99
|
-
|
|
100
|
-
<Popover reference={dropdownRef} open={!disabled && open} placement="bottom-start">
|
|
101
|
-
<div
|
|
102
|
-
class={`sterling-dropdown-popup-content ${_class}`}
|
|
103
|
-
transition:slideMotion|global={{ duration: 200 }}
|
|
104
|
-
bind:this={popupContentRef}
|
|
105
|
-
>
|
|
106
|
-
{@render children?.()}
|
|
107
|
-
</div>
|
|
108
|
-
</Popover>
|
|
109
|
-
</div>
|