@spaethtech/svelte-ui 0.1.10 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +166 -42
- package/dist/components/Alert.svelte +119 -0
- package/dist/components/Alert.svelte.d.ts +29 -0
- package/dist/components/Badge/Badge.svelte +142 -69
- package/dist/components/Badge/Badge.svelte.d.ts +26 -6
- package/dist/components/Badge/index.d.ts +1 -1
- package/dist/components/Badge/index.js +1 -1
- package/dist/components/Banner.svelte +133 -0
- package/dist/components/Banner.svelte.d.ts +31 -0
- package/dist/components/Button.svelte +240 -0
- package/dist/components/Button.svelte.d.ts +33 -0
- package/dist/components/ButtonDropdown.svelte +145 -0
- package/dist/components/ButtonDropdown.svelte.d.ts +31 -0
- package/dist/components/Calendar.svelte +259 -0
- package/dist/components/Calendar.svelte.d.ts +27 -0
- package/dist/components/Card.svelte +78 -0
- package/dist/components/Card.svelte.d.ts +17 -0
- package/dist/components/CardBody.svelte +41 -0
- package/dist/components/CardBody.svelte.d.ts +17 -0
- package/dist/components/CardFooter.svelte +49 -0
- package/dist/components/CardFooter.svelte.d.ts +16 -0
- package/dist/components/CardHeader.svelte +49 -0
- package/dist/components/CardHeader.svelte.d.ts +16 -0
- package/dist/components/Checkbox.svelte +131 -0
- package/dist/components/Checkbox.svelte.d.ts +16 -0
- package/dist/components/DataTable.svelte +518 -0
- package/dist/components/DataTable.svelte.d.ts +74 -0
- package/dist/components/DatePicker.svelte +312 -0
- package/dist/components/DatePicker.svelte.d.ts +32 -0
- package/dist/components/DateTimeInput.svelte +93 -0
- package/dist/components/DateTimeInput.svelte.d.ts +20 -0
- package/dist/components/Dialog.svelte +132 -0
- package/dist/components/Dialog.svelte.d.ts +24 -0
- package/dist/components/{EmailInput/EmailInput.svelte → EmailInput.svelte} +17 -8
- package/dist/components/EmailInput.svelte.d.ts +21 -0
- package/dist/components/Input.svelte +369 -0
- package/dist/components/Input.svelte.d.ts +35 -0
- package/dist/components/{List/List.svelte → List.svelte} +194 -133
- package/dist/components/{List/List.svelte.d.ts → List.svelte.d.ts} +9 -1
- package/dist/components/Menu.svelte +117 -0
- package/dist/components/Menu.svelte.d.ts +20 -0
- package/dist/components/NotesEditor.svelte +127 -0
- package/dist/components/NotesEditor.svelte.d.ts +17 -0
- package/dist/components/{NumberInput/NumberInput.svelte → NumberInput.svelte} +146 -105
- package/dist/components/{NumberInput/NumberInput.svelte.d.ts → NumberInput.svelte.d.ts} +11 -4
- package/dist/components/PasswordInput.svelte +52 -0
- package/dist/components/PasswordInput.svelte.d.ts +20 -0
- package/dist/components/Popup.svelte +140 -0
- package/dist/components/Popup.svelte.d.ts +31 -0
- package/dist/components/Query.svelte +284 -0
- package/dist/components/Query.svelte.d.ts +15 -0
- package/dist/components/{Rating/Rating.svelte → Rating.svelte} +19 -10
- package/dist/components/Rating.svelte.d.ts +13 -0
- package/dist/components/{SearchInput/SearchInput.svelte → SearchInput.svelte} +19 -8
- package/dist/components/{SearchInput/SearchInput.svelte.d.ts → SearchInput.svelte.d.ts} +9 -2
- package/dist/components/{Select/Select.svelte → Select.svelte} +48 -76
- package/dist/components/{Select/Select.svelte.d.ts → Select.svelte.d.ts} +11 -1
- package/dist/components/SideBarMenu/SideBarMenu.svelte +724 -0
- package/dist/components/SideBarMenu/SideBarMenu.svelte.d.ts +109 -0
- package/dist/components/SideBarMenu/index.d.ts +2 -0
- package/dist/components/SideBarMenu/index.js +1 -0
- package/dist/components/TabStrip/TabStrip.svelte +384 -0
- package/dist/components/TabStrip/TabStrip.svelte.d.ts +50 -0
- package/dist/components/TabStrip/index.d.ts +3 -0
- package/dist/components/TabStrip/index.js +2 -0
- package/dist/components/{TextArea/TextArea.svelte → TextArea.svelte} +143 -112
- package/dist/components/TextArea.svelte.d.ts +38 -0
- package/dist/components/ThemeSelector.svelte +81 -0
- package/dist/components/ThemeSelector.svelte.d.ts +10 -0
- package/dist/components/TimePicker.svelte +148 -0
- package/dist/components/TimePicker.svelte.d.ts +28 -0
- package/dist/components/TimeRangeInput.svelte +203 -0
- package/dist/components/TimeRangeInput.svelte.d.ts +29 -0
- package/dist/components/TimeSpinner.svelte +202 -0
- package/dist/components/TimeSpinner.svelte.d.ts +26 -0
- package/dist/components/Toast/Toaster.svelte +51 -0
- package/dist/components/Toast/Toaster.svelte.d.ts +12 -0
- package/dist/components/Toast/toast.svelte.d.ts +29 -0
- package/dist/components/Toast/toast.svelte.js +27 -0
- package/dist/components/Toggle.svelte +93 -0
- package/dist/components/Toggle.svelte.d.ts +15 -0
- package/dist/data/dataset.d.ts +42 -0
- package/dist/data/dataset.js +3 -0
- package/dist/data/index.d.ts +3 -0
- package/dist/data/index.js +3 -0
- package/dist/data/query/ast.d.ts +62 -0
- package/dist/data/query/ast.js +12 -0
- package/dist/data/query/index.d.ts +3 -0
- package/dist/data/query/index.js +3 -0
- package/dist/data/query/lexer.d.ts +33 -0
- package/dist/data/query/lexer.js +225 -0
- package/dist/data/query/parser.d.ts +11 -0
- package/dist/data/query/parser.js +252 -0
- package/dist/data/table/grid.svelte.d.ts +57 -0
- package/dist/data/table/grid.svelte.js +139 -0
- package/dist/data/table/index.d.ts +2 -0
- package/dist/data/table/index.js +2 -0
- package/dist/data/table/types.d.ts +79 -0
- package/dist/index.d.ts +48 -22
- package/dist/index.js +45 -21
- package/dist/positioning/anchored.d.ts +61 -0
- package/dist/positioning/anchored.js +122 -0
- package/dist/positioning/tooltip.d.ts +41 -0
- package/dist/positioning/tooltip.js +147 -0
- package/dist/theme.css +205 -0
- package/dist/types/breakpoints.d.ts +24 -0
- package/dist/types/breakpoints.js +13 -0
- package/dist/types/responsive.d.ts +32 -0
- package/dist/types/responsive.js +54 -0
- package/dist/types/sizes.d.ts +10 -3
- package/dist/types/time.d.ts +19 -0
- package/dist/types/time.js +10 -0
- package/dist/types/variants.d.ts +8 -1
- package/dist/types/variants.js +16 -1
- package/package.json +93 -63
- package/dist/components/Button/Button.svelte +0 -172
- package/dist/components/Button/Button.svelte.d.ts +0 -32
- package/dist/components/Button/index.d.ts +0 -1
- package/dist/components/Button/index.js +0 -1
- package/dist/components/Dialog/Dialog.svelte +0 -101
- package/dist/components/Dialog/Dialog.svelte.d.ts +0 -18
- package/dist/components/Dialog/index.d.ts +0 -1
- package/dist/components/Dialog/index.js +0 -1
- package/dist/components/ElementManager/ElementManager.svelte +0 -397
- package/dist/components/ElementManager/ElementManager.svelte.d.ts +0 -43
- package/dist/components/ElementManager/index.d.ts +0 -1
- package/dist/components/ElementManager/index.js +0 -1
- package/dist/components/EmailInput/EmailInput.svelte.d.ts +0 -14
- package/dist/components/EmailInput/index.d.ts +0 -1
- package/dist/components/EmailInput/index.js +0 -1
- package/dist/components/Icon/Icon.svelte +0 -74
- package/dist/components/Icon/Icon.svelte.d.ts +0 -13
- package/dist/components/Icon/index.d.ts +0 -1
- package/dist/components/Icon/index.js +0 -1
- package/dist/components/Input/Input.svelte +0 -268
- package/dist/components/Input/Input.svelte.d.ts +0 -18
- package/dist/components/Input/index.d.ts +0 -1
- package/dist/components/Input/index.js +0 -1
- package/dist/components/List/index.d.ts +0 -1
- package/dist/components/List/index.js +0 -1
- package/dist/components/ListItem/ListItem.svelte +0 -175
- package/dist/components/ListItem/ListItem.svelte.d.ts +0 -24
- package/dist/components/ListItem/index.d.ts +0 -2
- package/dist/components/ListItem/index.js +0 -2
- package/dist/components/ListView/ListView.svelte +0 -463
- package/dist/components/ListView/ListView.svelte.d.ts +0 -37
- package/dist/components/ListView/index.d.ts +0 -2
- package/dist/components/ListView/index.js +0 -2
- package/dist/components/NodeGraph/BaseNode.d.ts +0 -57
- package/dist/components/NodeGraph/BaseNode.js +0 -30
- package/dist/components/NodeGraph/Edge.svelte +0 -60
- package/dist/components/NodeGraph/Edge.svelte.d.ts +0 -16
- package/dist/components/NodeGraph/ExpressionEvaluator.d.ts +0 -82
- package/dist/components/NodeGraph/ExpressionEvaluator.js +0 -152
- package/dist/components/NodeGraph/Node.svelte +0 -100
- package/dist/components/NodeGraph/Node.svelte.d.ts +0 -10
- package/dist/components/NodeGraph/NodeGraph.svelte +0 -52
- package/dist/components/NodeGraph/NodeGraph.svelte.d.ts +0 -14
- package/dist/components/NodeGraph/NodeInstance.svelte.d.ts +0 -80
- package/dist/components/NodeGraph/NodeInstance.svelte.js +0 -241
- package/dist/components/NodeGraph/NodePort.svelte +0 -75
- package/dist/components/NodeGraph/NodePort.svelte.d.ts +0 -11
- package/dist/components/NodeGraph/decorators.d.ts +0 -81
- package/dist/components/NodeGraph/decorators.js +0 -148
- package/dist/components/NodeGraph/index.d.ts +0 -9
- package/dist/components/NodeGraph/index.js +0 -9
- package/dist/components/NodeGraph/types.d.ts +0 -94
- package/dist/components/NodeGraph/types.js +0 -33
- package/dist/components/NotesEditor/NotesEditor.svelte +0 -203
- package/dist/components/NotesEditor/NotesEditor.svelte.d.ts +0 -9
- package/dist/components/NotesEditor/index.d.ts +0 -1
- package/dist/components/NotesEditor/index.js +0 -1
- package/dist/components/NumberInput/index.d.ts +0 -1
- package/dist/components/NumberInput/index.js +0 -1
- package/dist/components/PasswordInput/PasswordInput.svelte +0 -41
- package/dist/components/PasswordInput/PasswordInput.svelte.d.ts +0 -13
- package/dist/components/PasswordInput/index.d.ts +0 -1
- package/dist/components/PasswordInput/index.js +0 -1
- package/dist/components/Popup/index.d.ts +0 -1
- package/dist/components/Popup/index.js +0 -1
- package/dist/components/Rating/Rating.svelte.d.ts +0 -7
- package/dist/components/Rating/index.d.ts +0 -1
- package/dist/components/Rating/index.js +0 -1
- package/dist/components/ScrollView/ScrollView.svelte +0 -285
- package/dist/components/ScrollView/ScrollView.svelte.d.ts +0 -19
- package/dist/components/ScrollView/index.d.ts +0 -1
- package/dist/components/ScrollView/index.js +0 -1
- package/dist/components/SearchInput/index.d.ts +0 -1
- package/dist/components/SearchInput/index.js +0 -1
- package/dist/components/Select/index.d.ts +0 -1
- package/dist/components/Select/index.js +0 -1
- package/dist/components/TextArea/TextArea.svelte.d.ts +0 -19
- package/dist/components/TextArea/index.d.ts +0 -1
- package/dist/components/TextArea/index.js +0 -1
- package/dist/components/ThemeSelector/ThemeSelector.svelte +0 -64
- package/dist/components/ThemeSelector/ThemeSelector.svelte.d.ts +0 -3
- package/dist/components/ThemeSelector/index.d.ts +0 -1
- package/dist/components/ThemeSelector/index.js +0 -1
- package/dist/components/TooltipHandler/TooltipHandler.svelte +0 -593
- package/dist/components/TooltipHandler/TooltipHandler.svelte.d.ts +0 -10
- package/dist/components/TooltipHandler/index.d.ts +0 -1
- package/dist/components/TooltipHandler/index.js +0 -1
- package/dist/styles/sizes.d.ts +0 -78
- package/dist/styles/sizes.js +0 -120
- package/dist/styles/variants.d.ts +0 -106
- package/dist/styles/variants.js +0 -194
- package/dist/types/ManagerTypes.d.ts +0 -42
- /package/dist/{types/ManagerTypes.js → data/table/types.js} +0 -0
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import Button from '../Button/Button.svelte';
|
|
3
|
-
import type { Snippet } from 'svelte';
|
|
4
|
-
import type { Variant } from '../../types/variants.js';
|
|
5
|
-
|
|
6
|
-
interface Props {
|
|
7
|
-
isOpen: boolean;
|
|
8
|
-
title?: string;
|
|
9
|
-
message?: string;
|
|
10
|
-
confirmText?: string;
|
|
11
|
-
cancelText?: string;
|
|
12
|
-
onConfirm?: () => void;
|
|
13
|
-
onCancel?: () => void;
|
|
14
|
-
variant?: Variant;
|
|
15
|
-
showConfirm?: boolean;
|
|
16
|
-
showCancel?: boolean;
|
|
17
|
-
children?: Snippet;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
let {
|
|
21
|
-
isOpen = $bindable(),
|
|
22
|
-
title = "Dialog",
|
|
23
|
-
message,
|
|
24
|
-
confirmText = "Confirm",
|
|
25
|
-
cancelText = "Cancel",
|
|
26
|
-
onConfirm,
|
|
27
|
-
onCancel,
|
|
28
|
-
variant = "primary",
|
|
29
|
-
showConfirm = true,
|
|
30
|
-
showCancel = true,
|
|
31
|
-
children
|
|
32
|
-
}: Props = $props();
|
|
33
|
-
|
|
34
|
-
function handleConfirm() {
|
|
35
|
-
if (onConfirm) onConfirm();
|
|
36
|
-
isOpen = false;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function handleCancel() {
|
|
40
|
-
if (onCancel) onCancel();
|
|
41
|
-
isOpen = false;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function handleBackdropClick(event: MouseEvent) {
|
|
45
|
-
if (event.target === event.currentTarget) {
|
|
46
|
-
handleCancel();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function handleKeydown(event: KeyboardEvent) {
|
|
51
|
-
if (event.key === 'Escape') {
|
|
52
|
-
handleCancel();
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
</script>
|
|
56
|
-
|
|
57
|
-
<svelte:window on:keydown={handleKeydown} />
|
|
58
|
-
|
|
59
|
-
{#if isOpen}
|
|
60
|
-
<div
|
|
61
|
-
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-[9999]"
|
|
62
|
-
onclick={handleBackdropClick}
|
|
63
|
-
onkeydown={handleKeydown}
|
|
64
|
-
role="dialog"
|
|
65
|
-
aria-modal="true"
|
|
66
|
-
tabindex="-1"
|
|
67
|
-
>
|
|
68
|
-
<div class="[background-color:var(--color-background)] rounded-lg shadow-xl max-w-md w-full mx-4 z-[10000]" style="padding: calc(var(--ui-padding) * 2);">
|
|
69
|
-
<h3 class="text-lg font-medium [color:var(--color-text)]" style="margin-bottom: calc(var(--ui-padding) * 1.5);">
|
|
70
|
-
{title}
|
|
71
|
-
</h3>
|
|
72
|
-
|
|
73
|
-
{#if children}
|
|
74
|
-
{@render children()}
|
|
75
|
-
{:else if message}
|
|
76
|
-
<p class="text-sm [color:var(--color-secondary)]">
|
|
77
|
-
{message}
|
|
78
|
-
</p>
|
|
79
|
-
{/if}
|
|
80
|
-
|
|
81
|
-
{#if showConfirm || showCancel}
|
|
82
|
-
<div class="flex gap-3 justify-end" style="margin-top: calc(var(--ui-padding) * 1.5);">
|
|
83
|
-
{#if showCancel}
|
|
84
|
-
<Button
|
|
85
|
-
text={cancelText}
|
|
86
|
-
onclick={handleCancel}
|
|
87
|
-
variant="secondary"
|
|
88
|
-
/>
|
|
89
|
-
{/if}
|
|
90
|
-
{#if showConfirm}
|
|
91
|
-
<Button
|
|
92
|
-
text={confirmText}
|
|
93
|
-
onclick={handleConfirm}
|
|
94
|
-
variant={variant}
|
|
95
|
-
/>
|
|
96
|
-
{/if}
|
|
97
|
-
</div>
|
|
98
|
-
{/if}
|
|
99
|
-
</div>
|
|
100
|
-
</div>
|
|
101
|
-
{/if}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { Variant } from '../../types/variants.js';
|
|
3
|
-
interface Props {
|
|
4
|
-
isOpen: boolean;
|
|
5
|
-
title?: string;
|
|
6
|
-
message?: string;
|
|
7
|
-
confirmText?: string;
|
|
8
|
-
cancelText?: string;
|
|
9
|
-
onConfirm?: () => void;
|
|
10
|
-
onCancel?: () => void;
|
|
11
|
-
variant?: Variant;
|
|
12
|
-
showConfirm?: boolean;
|
|
13
|
-
showCancel?: boolean;
|
|
14
|
-
children?: Snippet;
|
|
15
|
-
}
|
|
16
|
-
declare const Dialog: import("svelte").Component<Props, {}, "isOpen">;
|
|
17
|
-
type Dialog = ReturnType<typeof Dialog>;
|
|
18
|
-
export default Dialog;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Dialog.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Dialog.svelte';
|
|
@@ -1,397 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
/**
|
|
3
|
-
* ElementManager - Utility component for automatic element discovery and management
|
|
4
|
-
*
|
|
5
|
-
* Separates element discovery from component logic for better architecture.
|
|
6
|
-
* Used as a foundation for building manager components like TooltipHandler, ModalManager, etc.
|
|
7
|
-
*
|
|
8
|
-
* @example Single Selector (backwards compatible)
|
|
9
|
-
* ```svelte
|
|
10
|
-
* <script>
|
|
11
|
-
* let tooltipElements = $state(new Map());
|
|
12
|
-
* </script>
|
|
13
|
-
*
|
|
14
|
-
* <ElementManager
|
|
15
|
-
* selector="[data-tooltip], [data-tooltip-text]"
|
|
16
|
-
* bind:elements={tooltipElements}
|
|
17
|
-
* />
|
|
18
|
-
*
|
|
19
|
-
* <TooltipHandler elements={tooltipElements} />
|
|
20
|
-
* <slot />
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* @example Multiple Selector Groups (new)
|
|
24
|
-
* ```svelte
|
|
25
|
-
* <script>
|
|
26
|
-
* let elementGroups = $state({});
|
|
27
|
-
* </script>
|
|
28
|
-
*
|
|
29
|
-
* <ElementManager
|
|
30
|
-
* selectors={{
|
|
31
|
-
* viewportTooltips: "[data-tooltip]:not([data-contained])",
|
|
32
|
-
* containerTooltips: "[data-tooltip][data-contained]",
|
|
33
|
-
* modals: "[data-modal]"
|
|
34
|
-
* }}
|
|
35
|
-
* bind:elements={elementGroups}
|
|
36
|
-
* >
|
|
37
|
-
* <TooltipHandler bind:elements={elementGroups.viewportTooltips} />
|
|
38
|
-
* <TooltipHandler bind:elements={elementGroups.containerTooltips} container=".modal" />
|
|
39
|
-
* <ModalManager bind:elements={elementGroups.modals} />
|
|
40
|
-
* <slot />
|
|
41
|
-
* </ElementManager>
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* @example With Event Callbacks
|
|
45
|
-
* ```svelte
|
|
46
|
-
* <ElementManager
|
|
47
|
-
* selectors={{ modals: "[data-modal]" }}
|
|
48
|
-
* bind:elements={elementGroups}
|
|
49
|
-
* onElementAdded={(element, data, group) => {
|
|
50
|
-
* console.log(`New ${group} trigger:`, element);
|
|
51
|
-
* }}
|
|
52
|
-
* onElementRemoved={(element, data, group) => {
|
|
53
|
-
* // Cleanup any modal state
|
|
54
|
-
* data.cleanup?.();
|
|
55
|
-
* }}
|
|
56
|
-
* />
|
|
57
|
-
* ```
|
|
58
|
-
*
|
|
59
|
-
* @example Custom Observer Options
|
|
60
|
-
* ```svelte
|
|
61
|
-
* <ElementManager
|
|
62
|
-
* selectors={{ editable: "[contenteditable]" }}
|
|
63
|
-
* observerOptions={{
|
|
64
|
-
* childList: true,
|
|
65
|
-
* characterData: true,
|
|
66
|
-
* subtree: true
|
|
67
|
-
* }}
|
|
68
|
-
* bind:elements={elementGroups}
|
|
69
|
-
* />
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
-->
|
|
73
|
-
<script lang="ts">
|
|
74
|
-
import { onMount, untrack } from 'svelte';
|
|
75
|
-
import type { Snippet } from 'svelte';
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Data structure for each discovered element
|
|
79
|
-
*/
|
|
80
|
-
interface ElementData {
|
|
81
|
-
/** The HTML element that was discovered */
|
|
82
|
-
element: HTMLElement;
|
|
83
|
-
/** Optional cleanup function called when element is removed */
|
|
84
|
-
cleanup?: () => void;
|
|
85
|
-
/** Allow extension by consumer components with additional properties */
|
|
86
|
-
[key: string]: any;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* ElementManager component props
|
|
91
|
-
*
|
|
92
|
-
* @example Basic usage
|
|
93
|
-
* ```svelte
|
|
94
|
-
* <ElementManager
|
|
95
|
-
* selectors={{
|
|
96
|
-
* tooltips: "[data-tooltip]",
|
|
97
|
-
* modals: "[data-modal]"
|
|
98
|
-
* }}
|
|
99
|
-
* bind:elements={elementGroups}
|
|
100
|
-
* />
|
|
101
|
-
* ```
|
|
102
|
-
*/
|
|
103
|
-
interface Props {
|
|
104
|
-
/** Multiple CSS selectors organized by group name */
|
|
105
|
-
selectors: Record<string, string>;
|
|
106
|
-
/** Bindable Record of Maps for discovered elements */
|
|
107
|
-
elements?: Record<string, Map<HTMLElement, ElementData>>;
|
|
108
|
-
/** Optional child content to wrap (uses class="contents" for transparent rendering) */
|
|
109
|
-
children?: Snippet;
|
|
110
|
-
/** Callback fired when a new element is discovered */
|
|
111
|
-
onElementAdded?: (element: HTMLElement, data: ElementData, group: string) => void;
|
|
112
|
-
/** Callback fired when an element is removed or no longer matches selector */
|
|
113
|
-
onElementRemoved?: (element: HTMLElement, data: ElementData, group: string) => void;
|
|
114
|
-
/** Custom MutationObserver configuration (defaults to childList, subtree, attributes) */
|
|
115
|
-
observerOptions?: MutationObserverInit;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
let {
|
|
119
|
-
selectors,
|
|
120
|
-
elements = $bindable(),
|
|
121
|
-
children,
|
|
122
|
-
onElementAdded,
|
|
123
|
-
onElementRemoved,
|
|
124
|
-
observerOptions
|
|
125
|
-
}: Props = $props();
|
|
126
|
-
|
|
127
|
-
// ===== DEVELOPMENT WARNINGS =====
|
|
128
|
-
|
|
129
|
-
if (import.meta.env.DEV) {
|
|
130
|
-
// Validate prop usage
|
|
131
|
-
if (!selectors || Object.keys(selectors).length === 0) {
|
|
132
|
-
console.warn('ElementManager: No selectors provided or selectors object is empty. No elements will be discovered.');
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// ===== COMPONENT STATE =====
|
|
137
|
-
let containerElement: HTMLElement;
|
|
138
|
-
let observer: MutationObserver | null = null;
|
|
139
|
-
let debounceTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
140
|
-
let initialized = false;
|
|
141
|
-
|
|
142
|
-
// Initialize selectors as empty object if not provided (for development warnings)
|
|
143
|
-
let currentSelectors = $derived(() => selectors || {});
|
|
144
|
-
|
|
145
|
-
// Initialize elements (runs before other effects)
|
|
146
|
-
$effect.pre(() => {
|
|
147
|
-
if (!elements && !initialized) {
|
|
148
|
-
initialized = true;
|
|
149
|
-
untrack(() => {
|
|
150
|
-
// Initialize with empty Maps for each group
|
|
151
|
-
const groups: Record<string, Map<HTMLElement, ElementData>> = {};
|
|
152
|
-
for (const group in currentSelectors()) {
|
|
153
|
-
groups[group] = new Map();
|
|
154
|
-
}
|
|
155
|
-
elements = groups;
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// ===== ELEMENT DISCOVERY =====
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Discovers elements matching the current selectors and updates the elements Map(s).
|
|
164
|
-
* Performs incremental updates to avoid full re-discovery on every change.
|
|
165
|
-
*/
|
|
166
|
-
function discoverElements() {
|
|
167
|
-
if (!containerElement || !containerElement.isConnected) return;
|
|
168
|
-
|
|
169
|
-
const selectorGroups = currentSelectors();
|
|
170
|
-
|
|
171
|
-
// Track all found elements by group
|
|
172
|
-
const foundByGroup: Record<string, Set<HTMLElement>> = {};
|
|
173
|
-
|
|
174
|
-
// Discover elements for each selector group
|
|
175
|
-
for (const [group, selectorString] of Object.entries(selectorGroups)) {
|
|
176
|
-
foundByGroup[group] = new Set();
|
|
177
|
-
|
|
178
|
-
try {
|
|
179
|
-
const foundElements = containerElement.querySelectorAll(selectorString);
|
|
180
|
-
|
|
181
|
-
// Warn in development if no elements found
|
|
182
|
-
if (import.meta.env.DEV && foundElements.length === 0) {
|
|
183
|
-
console.warn(`ElementManager: No elements matched selector "${selectorString}" for group "${group}"`);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
foundElements.forEach((el) => {
|
|
187
|
-
if (el instanceof HTMLElement) {
|
|
188
|
-
foundByGroup[group].add(el);
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
} catch (error) {
|
|
192
|
-
console.warn(`ElementManager: Invalid selector "${selectorString}" for group "${group}":`,
|
|
193
|
-
error instanceof Error ? error.message : error);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Update elements for each group
|
|
198
|
-
const groupedElements = elements as Record<string, Map<HTMLElement, ElementData>>;
|
|
199
|
-
const newGroupedElements: Record<string, Map<HTMLElement, ElementData>> = {};
|
|
200
|
-
|
|
201
|
-
for (const [group, foundSet] of Object.entries(foundByGroup)) {
|
|
202
|
-
const currentMap = groupedElements[group] || new Map();
|
|
203
|
-
const newMap = new Map(currentMap);
|
|
204
|
-
|
|
205
|
-
// Remove elements that no longer match
|
|
206
|
-
for (const [element, data] of currentMap) {
|
|
207
|
-
if (!foundSet.has(element)) {
|
|
208
|
-
// Call cleanup function if provided
|
|
209
|
-
if (data.cleanup) {
|
|
210
|
-
try {
|
|
211
|
-
data.cleanup();
|
|
212
|
-
} catch (error) {
|
|
213
|
-
console.warn('ElementManager: Error in element cleanup:', error);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Call removal callback
|
|
218
|
-
if (onElementRemoved) {
|
|
219
|
-
try {
|
|
220
|
-
onElementRemoved(element, data, group);
|
|
221
|
-
} catch (error) {
|
|
222
|
-
console.warn('ElementManager: Error in onElementRemoved callback:', error);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
newMap.delete(element);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Add new elements
|
|
231
|
-
foundSet.forEach((element) => {
|
|
232
|
-
if (!currentMap.has(element)) {
|
|
233
|
-
const elementData: ElementData = { element };
|
|
234
|
-
newMap.set(element, elementData);
|
|
235
|
-
|
|
236
|
-
// Call addition callback
|
|
237
|
-
if (onElementAdded) {
|
|
238
|
-
try {
|
|
239
|
-
onElementAdded(element, elementData, group);
|
|
240
|
-
} catch (error) {
|
|
241
|
-
console.warn('ElementManager: Error in onElementAdded callback:', error);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
newGroupedElements[group] = newMap;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Handle removed groups
|
|
251
|
-
for (const group in groupedElements) {
|
|
252
|
-
if (!(group in newGroupedElements)) {
|
|
253
|
-
// Clean up all elements in removed group
|
|
254
|
-
const currentMap = groupedElements[group];
|
|
255
|
-
for (const [element, data] of currentMap) {
|
|
256
|
-
if (data.cleanup) {
|
|
257
|
-
try {
|
|
258
|
-
data.cleanup();
|
|
259
|
-
} catch (error) {
|
|
260
|
-
console.warn('ElementManager: Error in element cleanup for removed group:', error);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
if (onElementRemoved) {
|
|
264
|
-
try {
|
|
265
|
-
onElementRemoved(element, data, group);
|
|
266
|
-
} catch (error) {
|
|
267
|
-
console.warn('ElementManager: Error in onElementRemoved callback for removed group:', error);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
elements = newGroupedElements;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Debounced version of discoverElements to prevent excessive updates during rapid DOM changes.
|
|
279
|
-
* Uses 16ms delay (~60fps) for smooth performance.
|
|
280
|
-
*/
|
|
281
|
-
function debouncedDiscoverElements() {
|
|
282
|
-
if (debounceTimeout) {
|
|
283
|
-
clearTimeout(debounceTimeout);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
debounceTimeout = setTimeout(() => {
|
|
287
|
-
discoverElements();
|
|
288
|
-
debounceTimeout = null;
|
|
289
|
-
}, 16); // ~60fps for smooth updates
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// ===== MUTATION OBSERVER MANAGEMENT =====
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Sets up MutationObserver to watch for DOM changes and trigger element re-discovery.
|
|
296
|
-
* Includes error handling and recovery mechanisms.
|
|
297
|
-
*/
|
|
298
|
-
function setupObserver() {
|
|
299
|
-
if (observer || !containerElement || !containerElement.isConnected) return;
|
|
300
|
-
|
|
301
|
-
observer = new MutationObserver(() => {
|
|
302
|
-
try {
|
|
303
|
-
debouncedDiscoverElements();
|
|
304
|
-
} catch (error) {
|
|
305
|
-
console.warn('ElementManager: Error in MutationObserver callback:', error);
|
|
306
|
-
// Attempt to recover by re-running discovery without debouncing
|
|
307
|
-
try {
|
|
308
|
-
discoverElements();
|
|
309
|
-
} catch (recoveryError) {
|
|
310
|
-
console.warn('ElementManager: Failed to recover from MutationObserver error:', recoveryError);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
try {
|
|
316
|
-
// Use custom options or simple defaults
|
|
317
|
-
const options: MutationObserverInit = observerOptions || {
|
|
318
|
-
childList: true,
|
|
319
|
-
subtree: true,
|
|
320
|
-
attributes: true
|
|
321
|
-
// No attributeFilter - watch all attribute changes for simplicity
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
observer.observe(containerElement, options);
|
|
325
|
-
} catch (error) {
|
|
326
|
-
console.warn('ElementManager: Failed to set up MutationObserver:', error);
|
|
327
|
-
observer = null;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Cleanup function called on component destruction.
|
|
333
|
-
* Disconnects observer, clears timeouts, and runs element cleanup callbacks.
|
|
334
|
-
*/
|
|
335
|
-
function cleanup() {
|
|
336
|
-
if (observer) {
|
|
337
|
-
observer.disconnect();
|
|
338
|
-
observer = null;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
if (debounceTimeout) {
|
|
342
|
-
clearTimeout(debounceTimeout);
|
|
343
|
-
debounceTimeout = null;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// Clean up all remaining elements
|
|
347
|
-
if (elements) {
|
|
348
|
-
const groupedElements = elements as Record<string, Map<HTMLElement, ElementData>>;
|
|
349
|
-
for (const group in groupedElements) {
|
|
350
|
-
const currentMap = groupedElements[group];
|
|
351
|
-
for (const [, data] of currentMap) {
|
|
352
|
-
if (data.cleanup) {
|
|
353
|
-
try {
|
|
354
|
-
data.cleanup();
|
|
355
|
-
} catch (error) {
|
|
356
|
-
console.warn('ElementManager: Error in element cleanup during component destruction:', error);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
currentMap.clear();
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// React to selector changes and handle initial setup
|
|
366
|
-
$effect(() => {
|
|
367
|
-
// Ensure selectors are tracked as dependencies
|
|
368
|
-
currentSelectors();
|
|
369
|
-
|
|
370
|
-
// Only proceed if we have a container and are initialized
|
|
371
|
-
if (containerElement && initialized) {
|
|
372
|
-
// Clean up existing observer
|
|
373
|
-
if (observer) {
|
|
374
|
-
observer.disconnect();
|
|
375
|
-
observer = null;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// Re-discover with new selectors (untrack to prevent reactivity loop)
|
|
379
|
-
untrack(() => {
|
|
380
|
-
discoverElements();
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
// Set up observer with new selectors
|
|
384
|
-
setupObserver();
|
|
385
|
-
}
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
onMount(() => {
|
|
389
|
-
return cleanup;
|
|
390
|
-
});
|
|
391
|
-
</script>
|
|
392
|
-
|
|
393
|
-
<div bind:this={containerElement} class="contents">
|
|
394
|
-
{#if children}
|
|
395
|
-
{@render children()}
|
|
396
|
-
{/if}
|
|
397
|
-
</div>
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
/**
|
|
3
|
-
* Data structure for each discovered element
|
|
4
|
-
*/
|
|
5
|
-
interface ElementData {
|
|
6
|
-
/** The HTML element that was discovered */
|
|
7
|
-
element: HTMLElement;
|
|
8
|
-
/** Optional cleanup function called when element is removed */
|
|
9
|
-
cleanup?: () => void;
|
|
10
|
-
/** Allow extension by consumer components with additional properties */
|
|
11
|
-
[key: string]: any;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* ElementManager component props
|
|
15
|
-
*
|
|
16
|
-
* @example Basic usage
|
|
17
|
-
* ```svelte
|
|
18
|
-
* <ElementManager
|
|
19
|
-
* selectors={{
|
|
20
|
-
* tooltips: "[data-tooltip]",
|
|
21
|
-
* modals: "[data-modal]"
|
|
22
|
-
* }}
|
|
23
|
-
* bind:elements={elementGroups}
|
|
24
|
-
* />
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
interface Props {
|
|
28
|
-
/** Multiple CSS selectors organized by group name */
|
|
29
|
-
selectors: Record<string, string>;
|
|
30
|
-
/** Bindable Record of Maps for discovered elements */
|
|
31
|
-
elements?: Record<string, Map<HTMLElement, ElementData>>;
|
|
32
|
-
/** Optional child content to wrap (uses class="contents" for transparent rendering) */
|
|
33
|
-
children?: Snippet;
|
|
34
|
-
/** Callback fired when a new element is discovered */
|
|
35
|
-
onElementAdded?: (element: HTMLElement, data: ElementData, group: string) => void;
|
|
36
|
-
/** Callback fired when an element is removed or no longer matches selector */
|
|
37
|
-
onElementRemoved?: (element: HTMLElement, data: ElementData, group: string) => void;
|
|
38
|
-
/** Custom MutationObserver configuration (defaults to childList, subtree, attributes) */
|
|
39
|
-
observerOptions?: MutationObserverInit;
|
|
40
|
-
}
|
|
41
|
-
declare const ElementManager: import("svelte").Component<Props, {}, "elements">;
|
|
42
|
-
type ElementManager = ReturnType<typeof ElementManager>;
|
|
43
|
-
export default ElementManager;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './ElementManager.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './ElementManager.svelte';
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
-
interface Props extends Omit<HTMLInputAttributes, 'type'> {
|
|
3
|
-
value: string;
|
|
4
|
-
class?: string;
|
|
5
|
-
inputClass?: string;
|
|
6
|
-
validate?: (value: string) => boolean | string;
|
|
7
|
-
valid?: boolean;
|
|
8
|
-
touched?: boolean;
|
|
9
|
-
element?: HTMLInputElement;
|
|
10
|
-
required?: boolean;
|
|
11
|
-
}
|
|
12
|
-
declare const EmailInput: import("svelte").Component<Props, {}, "element" | "value" | "valid" | "touched">;
|
|
13
|
-
type EmailInput = ReturnType<typeof EmailInput>;
|
|
14
|
-
export default EmailInput;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './EmailInput.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './EmailInput.svelte';
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
3
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
import type { Variant } from '../../types/variants.js';
|
|
5
|
-
|
|
6
|
-
interface Props extends HTMLAttributes<SVGElement> {
|
|
7
|
-
icon: IconDefinition;
|
|
8
|
-
class?: string;
|
|
9
|
-
size?: string;
|
|
10
|
-
color?: string;
|
|
11
|
-
variant?: Omit<Variant, 'ghost'>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
let {
|
|
15
|
-
icon,
|
|
16
|
-
class: className = '',
|
|
17
|
-
size,
|
|
18
|
-
color,
|
|
19
|
-
variant,
|
|
20
|
-
...restProps
|
|
21
|
-
}: Props = $props();
|
|
22
|
-
|
|
23
|
-
const getIconSize = (size?: string) => {
|
|
24
|
-
if (!size) return '1rem';
|
|
25
|
-
|
|
26
|
-
// Support explicit sizes (px, rem, em, etc.)
|
|
27
|
-
if (size.match(/^\d+(\.\d+)?(px|rem|em|%)$/)) {
|
|
28
|
-
return size;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Fallback to 1rem for invalid sizes
|
|
32
|
-
return '1rem';
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const svgWidth = $derived(icon.icon[0]);
|
|
36
|
-
const svgHeight = $derived(icon.icon[1]);
|
|
37
|
-
const svgPath = $derived(icon.icon[4]);
|
|
38
|
-
const iconSize = $derived(getIconSize(size));
|
|
39
|
-
|
|
40
|
-
// Color priority: explicit color > variant color > currentColor
|
|
41
|
-
const fillColor = $derived(() => {
|
|
42
|
-
if (color) return color;
|
|
43
|
-
if (variant) return `var(--color-${variant})`;
|
|
44
|
-
return 'currentColor';
|
|
45
|
-
});
|
|
46
|
-
</script>
|
|
47
|
-
|
|
48
|
-
<svg
|
|
49
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
50
|
-
viewBox="0 0 {svgWidth} {svgHeight}"
|
|
51
|
-
class="svg-inline--fa {className}"
|
|
52
|
-
aria-hidden="true"
|
|
53
|
-
focusable="false"
|
|
54
|
-
role="img"
|
|
55
|
-
style:fill={fillColor()}
|
|
56
|
-
style:height={iconSize}
|
|
57
|
-
{...restProps}
|
|
58
|
-
>
|
|
59
|
-
{#if typeof svgPath === 'string'}
|
|
60
|
-
<path d={svgPath} />
|
|
61
|
-
{:else if Array.isArray(svgPath)}
|
|
62
|
-
{#each svgPath as path}
|
|
63
|
-
<path d={path} />
|
|
64
|
-
{/each}
|
|
65
|
-
{/if}
|
|
66
|
-
</svg>
|
|
67
|
-
|
|
68
|
-
<style>
|
|
69
|
-
.svg-inline--fa {
|
|
70
|
-
display: inline-block;
|
|
71
|
-
overflow: visible;
|
|
72
|
-
vertical-align: -0.125em;
|
|
73
|
-
}
|
|
74
|
-
</style>
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
-
import type { Variant } from '../../types/variants.js';
|
|
4
|
-
interface Props extends HTMLAttributes<SVGElement> {
|
|
5
|
-
icon: IconDefinition;
|
|
6
|
-
class?: string;
|
|
7
|
-
size?: string;
|
|
8
|
-
color?: string;
|
|
9
|
-
variant?: Omit<Variant, 'ghost'>;
|
|
10
|
-
}
|
|
11
|
-
declare const Icon: import("svelte").Component<Props, {}, "">;
|
|
12
|
-
type Icon = ReturnType<typeof Icon>;
|
|
13
|
-
export default Icon;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Icon.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Icon.svelte';
|