@spaethtech/svelte-ui 0.1.10

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.
Files changed (116) hide show
  1. package/README.md +81 -0
  2. package/dist/components/Badge/Badge.svelte +80 -0
  3. package/dist/components/Badge/Badge.svelte.d.ts +14 -0
  4. package/dist/components/Badge/index.d.ts +1 -0
  5. package/dist/components/Badge/index.js +1 -0
  6. package/dist/components/Button/Button.svelte +172 -0
  7. package/dist/components/Button/Button.svelte.d.ts +32 -0
  8. package/dist/components/Button/index.d.ts +1 -0
  9. package/dist/components/Button/index.js +1 -0
  10. package/dist/components/Dialog/Dialog.svelte +101 -0
  11. package/dist/components/Dialog/Dialog.svelte.d.ts +18 -0
  12. package/dist/components/Dialog/index.d.ts +1 -0
  13. package/dist/components/Dialog/index.js +1 -0
  14. package/dist/components/ElementManager/ElementManager.svelte +397 -0
  15. package/dist/components/ElementManager/ElementManager.svelte.d.ts +43 -0
  16. package/dist/components/ElementManager/index.d.ts +1 -0
  17. package/dist/components/ElementManager/index.js +1 -0
  18. package/dist/components/EmailInput/EmailInput.svelte +47 -0
  19. package/dist/components/EmailInput/EmailInput.svelte.d.ts +14 -0
  20. package/dist/components/EmailInput/index.d.ts +1 -0
  21. package/dist/components/EmailInput/index.js +1 -0
  22. package/dist/components/Icon/Icon.svelte +74 -0
  23. package/dist/components/Icon/Icon.svelte.d.ts +13 -0
  24. package/dist/components/Icon/index.d.ts +1 -0
  25. package/dist/components/Icon/index.js +1 -0
  26. package/dist/components/Input/Input.svelte +268 -0
  27. package/dist/components/Input/Input.svelte.d.ts +18 -0
  28. package/dist/components/Input/index.d.ts +1 -0
  29. package/dist/components/Input/index.js +1 -0
  30. package/dist/components/List/List.svelte +580 -0
  31. package/dist/components/List/List.svelte.d.ts +38 -0
  32. package/dist/components/List/index.d.ts +1 -0
  33. package/dist/components/List/index.js +1 -0
  34. package/dist/components/ListItem/ListItem.svelte +175 -0
  35. package/dist/components/ListItem/ListItem.svelte.d.ts +24 -0
  36. package/dist/components/ListItem/index.d.ts +2 -0
  37. package/dist/components/ListItem/index.js +2 -0
  38. package/dist/components/ListView/ListView.svelte +463 -0
  39. package/dist/components/ListView/ListView.svelte.d.ts +37 -0
  40. package/dist/components/ListView/index.d.ts +2 -0
  41. package/dist/components/ListView/index.js +2 -0
  42. package/dist/components/NodeGraph/BaseNode.d.ts +57 -0
  43. package/dist/components/NodeGraph/BaseNode.js +30 -0
  44. package/dist/components/NodeGraph/Edge.svelte +60 -0
  45. package/dist/components/NodeGraph/Edge.svelte.d.ts +16 -0
  46. package/dist/components/NodeGraph/ExpressionEvaluator.d.ts +82 -0
  47. package/dist/components/NodeGraph/ExpressionEvaluator.js +152 -0
  48. package/dist/components/NodeGraph/Node.svelte +100 -0
  49. package/dist/components/NodeGraph/Node.svelte.d.ts +10 -0
  50. package/dist/components/NodeGraph/NodeGraph.svelte +52 -0
  51. package/dist/components/NodeGraph/NodeGraph.svelte.d.ts +14 -0
  52. package/dist/components/NodeGraph/NodeInstance.svelte.d.ts +80 -0
  53. package/dist/components/NodeGraph/NodeInstance.svelte.js +241 -0
  54. package/dist/components/NodeGraph/NodePort.svelte +75 -0
  55. package/dist/components/NodeGraph/NodePort.svelte.d.ts +11 -0
  56. package/dist/components/NodeGraph/decorators.d.ts +81 -0
  57. package/dist/components/NodeGraph/decorators.js +148 -0
  58. package/dist/components/NodeGraph/index.d.ts +9 -0
  59. package/dist/components/NodeGraph/index.js +9 -0
  60. package/dist/components/NodeGraph/types.d.ts +94 -0
  61. package/dist/components/NodeGraph/types.js +33 -0
  62. package/dist/components/NotesEditor/NotesEditor.svelte +203 -0
  63. package/dist/components/NotesEditor/NotesEditor.svelte.d.ts +9 -0
  64. package/dist/components/NotesEditor/index.d.ts +1 -0
  65. package/dist/components/NotesEditor/index.js +1 -0
  66. package/dist/components/NumberInput/NumberInput.svelte +353 -0
  67. package/dist/components/NumberInput/NumberInput.svelte.d.ts +26 -0
  68. package/dist/components/NumberInput/index.d.ts +1 -0
  69. package/dist/components/NumberInput/index.js +1 -0
  70. package/dist/components/PasswordInput/PasswordInput.svelte +41 -0
  71. package/dist/components/PasswordInput/PasswordInput.svelte.d.ts +13 -0
  72. package/dist/components/PasswordInput/index.d.ts +1 -0
  73. package/dist/components/PasswordInput/index.js +1 -0
  74. package/dist/components/Popup/index.d.ts +1 -0
  75. package/dist/components/Popup/index.js +1 -0
  76. package/dist/components/Rating/Rating.svelte +77 -0
  77. package/dist/components/Rating/Rating.svelte.d.ts +7 -0
  78. package/dist/components/Rating/index.d.ts +1 -0
  79. package/dist/components/Rating/index.js +1 -0
  80. package/dist/components/ScrollView/ScrollView.svelte +285 -0
  81. package/dist/components/ScrollView/ScrollView.svelte.d.ts +19 -0
  82. package/dist/components/ScrollView/index.d.ts +1 -0
  83. package/dist/components/ScrollView/index.js +1 -0
  84. package/dist/components/SearchInput/SearchInput.svelte +50 -0
  85. package/dist/components/SearchInput/SearchInput.svelte.d.ts +15 -0
  86. package/dist/components/SearchInput/index.d.ts +1 -0
  87. package/dist/components/SearchInput/index.js +1 -0
  88. package/dist/components/Select/Select.svelte +278 -0
  89. package/dist/components/Select/Select.svelte.d.ts +35 -0
  90. package/dist/components/Select/index.d.ts +1 -0
  91. package/dist/components/Select/index.js +1 -0
  92. package/dist/components/TextArea/TextArea.svelte +734 -0
  93. package/dist/components/TextArea/TextArea.svelte.d.ts +19 -0
  94. package/dist/components/TextArea/index.d.ts +1 -0
  95. package/dist/components/TextArea/index.js +1 -0
  96. package/dist/components/ThemeSelector/ThemeSelector.svelte +64 -0
  97. package/dist/components/ThemeSelector/ThemeSelector.svelte.d.ts +3 -0
  98. package/dist/components/ThemeSelector/index.d.ts +1 -0
  99. package/dist/components/ThemeSelector/index.js +1 -0
  100. package/dist/components/TooltipHandler/TooltipHandler.svelte +593 -0
  101. package/dist/components/TooltipHandler/TooltipHandler.svelte.d.ts +10 -0
  102. package/dist/components/TooltipHandler/index.d.ts +1 -0
  103. package/dist/components/TooltipHandler/index.js +1 -0
  104. package/dist/index.d.ts +24 -0
  105. package/dist/index.js +26 -0
  106. package/dist/styles/sizes.d.ts +78 -0
  107. package/dist/styles/sizes.js +120 -0
  108. package/dist/styles/variants.d.ts +106 -0
  109. package/dist/styles/variants.js +194 -0
  110. package/dist/types/ManagerTypes.d.ts +42 -0
  111. package/dist/types/ManagerTypes.js +1 -0
  112. package/dist/types/sizes.d.ts +5 -0
  113. package/dist/types/sizes.js +1 -0
  114. package/dist/types/variants.d.ts +1 -0
  115. package/dist/types/variants.js +1 -0
  116. package/package.json +65 -0
@@ -0,0 +1,278 @@
1
+ <script lang="ts">
2
+ import { slide } from 'svelte/transition';
3
+ import type { Snippet } from 'svelte';
4
+ import { faChevronDown } from '@fortawesome/free-solid-svg-icons';
5
+ import Input from '../Input/Input.svelte';
6
+ import List from '../List/List.svelte';
7
+
8
+ type Option = Record<string, any> & {
9
+ value: string;
10
+ label: string;
11
+ };
12
+
13
+ let {
14
+ options = [],
15
+ value = $bindable(""),
16
+ multiSelect = false,
17
+ placeholder = "Select an option...",
18
+ maxVisibleItems = 10,
19
+ itemHeight = 32,
20
+ autoAdvance = false,
21
+ class: className = "",
22
+ inputClass = "",
23
+ dropdownClass = "",
24
+ itemClass = "",
25
+ itemSnippet,
26
+ methods = $bindable(),
27
+ // API integration props
28
+ url,
29
+ searchParam,
30
+ transform,
31
+ debounceMs = 300,
32
+ maxResults,
33
+ headers = {},
34
+ searchTerm = $bindable(""),
35
+ onError,
36
+ onLoadStart,
37
+ onLoadEnd,
38
+ onSelection,
39
+ disabled = false,
40
+ ...restProps
41
+ }: {
42
+ options?: Option[];
43
+ value: string | string[];
44
+ multiSelect?: boolean;
45
+ placeholder?: string;
46
+ maxVisibleItems?: number;
47
+ itemHeight?: number;
48
+ autoAdvance?: boolean;
49
+ class?: string;
50
+ inputClass?: string;
51
+ dropdownClass?: string;
52
+ itemClass?: string;
53
+ itemSnippet?: Snippet<[Option, number, boolean, boolean]>; // option, index, isSelected, isFocused
54
+ methods?: any;
55
+ // API integration
56
+ url?: string;
57
+ searchParam?: string;
58
+ transform?: (apiResponse: any) => Option[];
59
+ debounceMs?: number;
60
+ maxResults?: number;
61
+ headers?: Record<string, string>;
62
+ searchTerm?: string;
63
+ onError?: (error: Error) => void;
64
+ onLoadStart?: () => void;
65
+ onLoadEnd?: () => void;
66
+ onSelection?: (option: Option) => void;
67
+ disabled?: boolean;
68
+ } & Record<string, any> = $props();
69
+
70
+ let isOpen = $state(false);
71
+ let inputElement = $state<HTMLInputElement>();
72
+ let listElement = $state<any>();
73
+
74
+ // Get display text for selected value
75
+ const selectedLabel = $derived(() => {
76
+ if (multiSelect && Array.isArray(value)) {
77
+ if (value.length === 0) return "";
78
+ if (value.length === 1) {
79
+ const selectedOption = options.find(option => option.value === value[0]);
80
+ return selectedOption?.label || "";
81
+ }
82
+ return `${value.length} items selected`;
83
+ } else {
84
+ const selectedOption = options.find(option => option.value === value);
85
+ return selectedOption?.label || "";
86
+ }
87
+ });
88
+
89
+ // Global dropdown manager - only one dropdown open at a time
90
+ let dropdownId = Math.random().toString(36).substring(2, 9);
91
+ let zIndex = $state(50);
92
+
93
+ function toggleDropdown(event?: MouseEvent | KeyboardEvent) {
94
+ event?.stopPropagation();
95
+ event?.preventDefault(); // Prevent text selection
96
+ if (disabled) return;
97
+
98
+ isOpen = !isOpen;
99
+
100
+ if (isOpen) {
101
+ // Set focus to the selected item in the list
102
+ setTimeout(() => {
103
+ if (listElement?.focus) {
104
+ listElement.focus();
105
+ }
106
+ }, 50);
107
+ }
108
+ }
109
+
110
+ function handleInputMouseDown(event: MouseEvent) {
111
+ event.preventDefault(); // Prevent text selection on mousedown
112
+ toggleDropdown(event);
113
+ }
114
+
115
+ function handleInputDoubleClick(event: MouseEvent) {
116
+ event.preventDefault(); // Prevent text selection on double-click
117
+ event.stopPropagation();
118
+ }
119
+
120
+ function handleSelection(option: Option) {
121
+ // In single-select mode, close dropdown. In multi-select mode, keep it open
122
+ if (!multiSelect) {
123
+ isOpen = false;
124
+ }
125
+
126
+ if (onSelection) {
127
+ onSelection(option);
128
+ }
129
+
130
+ if (!multiSelect && autoAdvance) {
131
+ // Move to next focusable element (only in single-select mode)
132
+ setTimeout(() => {
133
+ if (inputElement) {
134
+ const focusableElements = document.querySelectorAll(
135
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
136
+ );
137
+ const currentIndex = Array.from(focusableElements).indexOf(inputElement);
138
+ const nextElement = focusableElements[currentIndex + 1] as HTMLElement;
139
+ nextElement?.focus();
140
+ }
141
+ }, 50);
142
+ } else if (!multiSelect) {
143
+ inputElement?.focus();
144
+ }
145
+ // In multi-select mode, keep focus on the list for continued selection
146
+ }
147
+
148
+ function handleKeydown(event: KeyboardEvent) {
149
+ if (event.key === 'Escape') {
150
+ isOpen = false;
151
+ inputElement?.focus();
152
+ } else if (event.key === 'Enter') {
153
+ if (isOpen) {
154
+ // Close dropdown and allow Enter to propagate for form submission
155
+ isOpen = false;
156
+ inputElement?.focus();
157
+ } else {
158
+ // Open dropdown when closed
159
+ event.preventDefault();
160
+ toggleDropdown(event);
161
+ }
162
+ } else if (event.key === ' ') {
163
+ event.preventDefault();
164
+ toggleDropdown(event);
165
+ } else if (event.key === 'ArrowDown' && !isOpen) {
166
+ event.preventDefault();
167
+ isOpen = true;
168
+ }
169
+ }
170
+
171
+ // Expose methods to parent
172
+ $effect(() => {
173
+ methods = {
174
+ openDropdown: () => {
175
+ isOpen = true;
176
+ setTimeout(() => {
177
+ if (listElement?.focus) {
178
+ listElement.focus();
179
+ }
180
+ }, 50);
181
+ }
182
+ };
183
+ });
184
+
185
+ // Close dropdown when clicking outside or when another dropdown opens
186
+ $effect(() => {
187
+ if (isOpen) {
188
+ // Increment z-index for newly opened dropdown
189
+ zIndex = 50 + Date.now() % 1000;
190
+
191
+ // Set this as the active dropdown
192
+ document.dispatchEvent(new CustomEvent('dropdown-opened', { detail: { id: dropdownId } }));
193
+
194
+ const handleClickOutside = (event: MouseEvent) => {
195
+ const target = event.target as Element;
196
+ if (!target.closest('.select-container')) {
197
+ isOpen = false;
198
+ }
199
+ };
200
+
201
+ const handleOtherDropdownOpen = (event: CustomEvent) => {
202
+ if (event.detail.id !== dropdownId) {
203
+ isOpen = false;
204
+ }
205
+ };
206
+
207
+ document.addEventListener('click', handleClickOutside);
208
+ document.addEventListener('dropdown-opened', handleOtherDropdownOpen as EventListener);
209
+
210
+ return () => {
211
+ document.removeEventListener('click', handleClickOutside);
212
+ document.removeEventListener('dropdown-opened', handleOtherDropdownOpen as EventListener);
213
+ };
214
+ }
215
+ });
216
+ </script>
217
+
218
+ <div class="relative select-container {className}">
219
+ <Input
220
+ bind:element={inputElement}
221
+ value={selectedLabel()}
222
+ {placeholder}
223
+ readonly={true}
224
+ icon={faChevronDown}
225
+ iconPosition="right"
226
+ iconClickable={true}
227
+ onIconClick={toggleDropdown}
228
+ onmousedown={handleInputMouseDown}
229
+ ondblclick={handleInputDoubleClick}
230
+ onkeydown={handleKeydown}
231
+ {disabled}
232
+ class={inputClass}
233
+ inputClass={disabled ? "!cursor-default select-none" : "!cursor-pointer select-none"}
234
+ {...restProps}
235
+ />
236
+
237
+ <!-- Always render List to maintain cache, show/hide with CSS -->
238
+ <div
239
+ class="absolute w-full {isOpen ? '' : 'opacity-0 pointer-events-none'}"
240
+ style="z-index: {isOpen ? zIndex : -1}; top: calc(100% + 0.25rem);"
241
+ >
242
+ <List
243
+ bind:this={listElement}
244
+ {options}
245
+ bind:value
246
+ {multiSelect}
247
+ {maxVisibleItems}
248
+ {itemHeight}
249
+ {itemSnippet}
250
+ onSelection={handleSelection}
251
+ class={dropdownClass}
252
+ {itemClass}
253
+ {url}
254
+ {searchParam}
255
+ {transform}
256
+ {debounceMs}
257
+ {maxResults}
258
+ {headers}
259
+ {searchTerm}
260
+ {onError}
261
+ {onLoadStart}
262
+ {onLoadEnd}
263
+ />
264
+ </div>
265
+
266
+ <!-- Transition effect overlay -->
267
+ {#if isOpen}
268
+ <div
269
+ class="absolute w-full pointer-events-none"
270
+ style="z-index: {zIndex + 1}; top: calc(100% + 0.25rem);"
271
+ transition:slide={{ duration: 200 }}
272
+ >
273
+ <div style="height: {maxVisibleItems * itemHeight}px; opacity: 0;">
274
+ <!-- Invisible placeholder for slide transition -->
275
+ </div>
276
+ </div>
277
+ {/if}
278
+ </div>
@@ -0,0 +1,35 @@
1
+ import type { Snippet } from 'svelte';
2
+ type Option = Record<string, any> & {
3
+ value: string;
4
+ label: string;
5
+ };
6
+ type $$ComponentProps = {
7
+ options?: Option[];
8
+ value: string | string[];
9
+ multiSelect?: boolean;
10
+ placeholder?: string;
11
+ maxVisibleItems?: number;
12
+ itemHeight?: number;
13
+ autoAdvance?: boolean;
14
+ class?: string;
15
+ inputClass?: string;
16
+ dropdownClass?: string;
17
+ itemClass?: string;
18
+ itemSnippet?: Snippet<[Option, number, boolean, boolean]>;
19
+ methods?: any;
20
+ url?: string;
21
+ searchParam?: string;
22
+ transform?: (apiResponse: any) => Option[];
23
+ debounceMs?: number;
24
+ maxResults?: number;
25
+ headers?: Record<string, string>;
26
+ searchTerm?: string;
27
+ onError?: (error: Error) => void;
28
+ onLoadStart?: () => void;
29
+ onLoadEnd?: () => void;
30
+ onSelection?: (option: Option) => void;
31
+ disabled?: boolean;
32
+ } & Record<string, any>;
33
+ declare const Select: import("svelte").Component<$$ComponentProps, {}, "value" | "searchTerm" | "methods">;
34
+ type Select = ReturnType<typeof Select>;
35
+ export default Select;
@@ -0,0 +1 @@
1
+ export { default } from './Select.svelte';
@@ -0,0 +1 @@
1
+ export { default } from './Select.svelte';