@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,268 @@
1
+ <script lang="ts">
2
+ import Icon from '../Icon/Icon.svelte';
3
+ import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
4
+ import type { HTMLInputAttributes } from 'svelte/elements';
5
+
6
+ interface Props extends HTMLInputAttributes {
7
+ value: string;
8
+ icon?: IconDefinition;
9
+ iconPosition?: 'left' | 'right';
10
+ iconClickable?: boolean;
11
+ onIconClick?: () => void;
12
+ class?: string;
13
+ inputClass?: string;
14
+ validate?: (value: string) => boolean | string;
15
+ valid?: boolean;
16
+ touched?: boolean;
17
+ element?: HTMLInputElement;
18
+ }
19
+
20
+ let {
21
+ value = $bindable(),
22
+ icon,
23
+ iconPosition = 'right',
24
+ iconClickable = false,
25
+ onIconClick,
26
+ class: containerClass = '',
27
+ inputClass = '',
28
+ validate,
29
+ valid = $bindable(true),
30
+ touched = $bindable(false),
31
+ element = $bindable(),
32
+ type = 'text',
33
+ disabled = false,
34
+ readonly = false,
35
+ ...restProps
36
+ }: Props = $props();
37
+
38
+ let inputElement: HTMLInputElement;
39
+
40
+ // Sync element binding
41
+ $effect(() => {
42
+ element = inputElement;
43
+ });
44
+
45
+ // Validation logic
46
+ let validationResult = $state<boolean | string>(true);
47
+
48
+ function runValidation() {
49
+ if (!validate) {
50
+ valid = true;
51
+ validationResult = true;
52
+ return;
53
+ }
54
+
55
+ const result = validate(value);
56
+ validationResult = result;
57
+ valid = result === true;
58
+ }
59
+
60
+ // Run validation when value changes
61
+ $effect(() => {
62
+ runValidation();
63
+ });
64
+
65
+ // Computed classes
66
+ let containerClasses = $derived.by(() => {
67
+ const base = 'relative w-full';
68
+ return `${base} ${containerClass}`.trim();
69
+ });
70
+
71
+ let wrapperClasses = $derived.by(() => {
72
+ const base = 'w-full h-8 flex items-center rounded-md';
73
+
74
+ // Calculate padding based on icon presence and position
75
+ let paddingClasses = '';
76
+ if (icon) {
77
+ // Icon present - only pad the side without icon
78
+ if (iconPosition === 'left') {
79
+ paddingClasses = 'pl-0 pr-2'; // Icon on left, pad right only
80
+ } else {
81
+ paddingClasses = 'pl-2 pr-0'; // Icon on right, pad left only
82
+ }
83
+ } else {
84
+ // No icon - pad both sides
85
+ paddingClasses = 'px-2';
86
+ }
87
+
88
+ // Use new semantic color system with transparent background
89
+ const themeStyles = [
90
+ 'bg-transparent',
91
+ 'border-2',
92
+ paddingClasses,
93
+ '[border-color:var(--color-secondary)]',
94
+ 'hover:[border-color:color-mix(in_srgb,var(--color-secondary)_80%,black)]',
95
+ 'focus-within:[border-color:color-mix(in_srgb,var(--color-secondary)_90%,black)]',
96
+ 'focus-within:[outline:2px_solid_color-mix(in_srgb,currentColor_70%,transparent)]',
97
+ 'focus-within:[outline-offset:0px]'
98
+ ].join(' ');
99
+
100
+ // Validation state overrides
101
+ let validationStyles = '';
102
+ if (touched && !valid) {
103
+ validationStyles = '[border-color:var(--color-danger)] focus-within:[ring-color:var(--color-danger)]';
104
+ }
105
+
106
+ // Disabled and readonly state (with padding compensation for 1px border)
107
+ let disabledStyles = '';
108
+ if (disabled || readonly) {
109
+ let disabledPadding = '';
110
+ if (icon) {
111
+ // Icon present - adjust padding for 1px border compensation
112
+ if (iconPosition === 'left') {
113
+ disabledPadding = '!pl-[1px] !pr-[calc(0.5rem+1px)]'; // Icon on left
114
+ } else {
115
+ disabledPadding = '!pl-[calc(0.5rem+1px)] !pr-[1px]'; // Icon on right
116
+ }
117
+ } else {
118
+ // No icon - pad both sides with compensation
119
+ disabledPadding = '!px-[calc(0.5rem+1px)]';
120
+ }
121
+
122
+ disabledStyles = disabled
123
+ ? `![background-color:color-mix(in_srgb,var(--color-text)_5%,transparent)] [border-color:color-mix(in_srgb,var(--color-secondary)_50%,transparent)] !border ${disabledPadding} cursor-not-allowed`
124
+ : `[border-color:var(--color-secondary)] !border ${disabledPadding}`;
125
+ }
126
+
127
+ return `${base} ${themeStyles} ${validationStyles} ${disabledStyles}`.trim();
128
+ });
129
+
130
+ let inputClasses = $derived.by(() => {
131
+ const base = 'flex-1 h-full bg-transparent border-none outline-none text-sm leading-tight p-0 min-w-0';
132
+
133
+ // Use new semantic color system
134
+ const themeStyles = [
135
+ '[color:var(--color-text)]',
136
+ 'placeholder:[color:var(--color-secondary)]',
137
+ 'disabled:bg-transparent',
138
+ 'disabled:[color:color-mix(in_srgb,var(--color-text)_40%,transparent)]',
139
+ 'disabled:cursor-not-allowed'
140
+ ].join(' ');
141
+
142
+ return `${base} ${themeStyles} ${inputClass}`.trim();
143
+ });
144
+
145
+ let iconClasses = $derived.by(() => {
146
+ const base = 'w-8 h-8 flex items-center justify-center flex-shrink-0 select-none';
147
+
148
+ const interactive = iconClickable
149
+ ? 'cursor-pointer focus:outline-none transition-colors group'
150
+ : 'pointer-events-none';
151
+
152
+ return `${base} ${interactive}`.trim();
153
+ });
154
+
155
+ // Event handlers
156
+ function handleInput(event: Event & { currentTarget: EventTarget & HTMLInputElement }) {
157
+ const target = event.target as HTMLInputElement;
158
+ value = target.value;
159
+ if (restProps.oninput) restProps.oninput(event);
160
+ }
161
+
162
+ function handleFocus(event: FocusEvent & { currentTarget: EventTarget & HTMLInputElement }) {
163
+ touched = true;
164
+ if (restProps.onfocus) restProps.onfocus(event);
165
+ }
166
+
167
+ function handleIconKeydown(event: KeyboardEvent) {
168
+ if (event.key === 'Enter' || event.key === ' ') {
169
+ event.preventDefault();
170
+ onIconClick?.();
171
+ }
172
+ }
173
+
174
+ function handleIconMouseDown(event: MouseEvent) {
175
+ event.preventDefault(); // Prevent text selection on double-click
176
+ event.stopPropagation(); // Prevent event from bubbling
177
+ }
178
+
179
+ function handleIconSelectStart(event: Event) {
180
+ event.preventDefault(); // Prevent text selection
181
+ return false;
182
+ }
183
+
184
+ function handleIconDoubleClick(event: MouseEvent) {
185
+ event.preventDefault();
186
+ event.stopPropagation();
187
+ return false;
188
+ }
189
+
190
+ // Override browser validation
191
+ $effect(() => {
192
+ if (inputElement) {
193
+ inputElement.setCustomValidity('');
194
+ if (touched && !valid && typeof validationResult === 'string') {
195
+ inputElement.setCustomValidity(validationResult);
196
+ }
197
+ }
198
+ });
199
+ </script>
200
+
201
+ <div class={containerClasses}>
202
+ <div class={wrapperClasses} style="user-select: none;">
203
+ {#if icon && iconPosition === 'left'}
204
+ {#if iconClickable}
205
+ <div
206
+ class={iconClasses}
207
+ onclick={onIconClick}
208
+ onkeydown={handleIconKeydown}
209
+ onmousedown={handleIconMouseDown}
210
+ ondblclick={handleIconDoubleClick}
211
+ onselectstart={handleIconSelectStart}
212
+ role="button"
213
+ tabindex="0"
214
+ style="user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;"
215
+ >
216
+ {#key icon}
217
+ <Icon {icon} class="w-4 h-4 [color:var(--color-secondary)!important] group-hover:[color:color-mix(in_srgb,var(--color-secondary)_80%,black)!important] group-focus:[color:color-mix(in_srgb,currentColor_70%,transparent)!important] transition-colors" />
218
+ {/key}
219
+ </div>
220
+ {:else}
221
+ <div class={iconClasses}>
222
+ {#key icon}
223
+ <Icon {icon} class="w-4 h-4 [color:var(--color-secondary)!important] group-hover:[color:color-mix(in_srgb,var(--color-secondary)_80%,black)!important] group-focus:[color:color-mix(in_srgb,currentColor_70%,transparent)!important] transition-colors" />
224
+ {/key}
225
+ </div>
226
+ {/if}
227
+ {/if}
228
+
229
+ <input
230
+ bind:this={inputElement}
231
+ {type}
232
+ {value}
233
+ {disabled}
234
+ {readonly}
235
+ oninput={handleInput}
236
+ onfocus={handleFocus}
237
+ {...restProps}
238
+ class={inputClasses}
239
+ style="border: none !important; box-shadow: none !important; user-select: text !important;"
240
+ />
241
+
242
+ {#if icon && iconPosition === 'right'}
243
+ {#if iconClickable}
244
+ <div
245
+ class={iconClasses}
246
+ onclick={onIconClick}
247
+ onkeydown={handleIconKeydown}
248
+ onmousedown={handleIconMouseDown}
249
+ ondblclick={handleIconDoubleClick}
250
+ onselectstart={handleIconSelectStart}
251
+ role="button"
252
+ tabindex="0"
253
+ style="user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;"
254
+ >
255
+ {#key icon}
256
+ <Icon {icon} class="w-4 h-4 [color:var(--color-secondary)!important] group-hover:[color:color-mix(in_srgb,var(--color-secondary)_80%,black)!important] group-focus:[color:color-mix(in_srgb,currentColor_70%,transparent)!important] transition-colors" />
257
+ {/key}
258
+ </div>
259
+ {:else}
260
+ <div class={iconClasses}>
261
+ {#key icon}
262
+ <Icon {icon} class="w-4 h-4 [color:var(--color-secondary)!important] group-hover:[color:color-mix(in_srgb,var(--color-secondary)_80%,black)!important] group-focus:[color:color-mix(in_srgb,currentColor_70%,transparent)!important] transition-colors" />
263
+ {/key}
264
+ </div>
265
+ {/if}
266
+ {/if}
267
+ </div>
268
+ </div>
@@ -0,0 +1,18 @@
1
+ import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
2
+ import type { HTMLInputAttributes } from 'svelte/elements';
3
+ interface Props extends HTMLInputAttributes {
4
+ value: string;
5
+ icon?: IconDefinition;
6
+ iconPosition?: 'left' | 'right';
7
+ iconClickable?: boolean;
8
+ onIconClick?: () => void;
9
+ class?: string;
10
+ inputClass?: string;
11
+ validate?: (value: string) => boolean | string;
12
+ valid?: boolean;
13
+ touched?: boolean;
14
+ element?: HTMLInputElement;
15
+ }
16
+ declare const Input: import("svelte").Component<Props, {}, "element" | "value" | "valid" | "touched">;
17
+ type Input = ReturnType<typeof Input>;
18
+ export default Input;
@@ -0,0 +1 @@
1
+ export { default } from './Input.svelte';
@@ -0,0 +1 @@
1
+ export { default } from './Input.svelte';