@spaethtech/svelte-ui 0.1.10 → 0.3.1-dev.3.e16df24
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 +180 -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,203 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
let {
|
|
3
|
-
notes = $bindable(""),
|
|
4
|
-
placeholder = "Add your notes...",
|
|
5
|
-
onSave,
|
|
6
|
-
className = ""
|
|
7
|
-
}: {
|
|
8
|
-
notes: string | undefined;
|
|
9
|
-
placeholder?: string;
|
|
10
|
-
onSave: (notes: string) => Promise<void>;
|
|
11
|
-
className?: string;
|
|
12
|
-
} = $props();
|
|
13
|
-
|
|
14
|
-
// State management
|
|
15
|
-
let saveState = $state<'idle' | 'typing' | 'saving' | 'saved' | 'error'>('idle');
|
|
16
|
-
let saveTimeout: ReturnType<typeof setTimeout>;
|
|
17
|
-
let lastSavedNotes = $state(notes || '');
|
|
18
|
-
|
|
19
|
-
// Auto-save effect - runs when notes change
|
|
20
|
-
$effect(() => {
|
|
21
|
-
const currentNotes = notes || '';
|
|
22
|
-
|
|
23
|
-
if (currentNotes !== lastSavedNotes && saveState !== 'saving') {
|
|
24
|
-
saveState = 'typing';
|
|
25
|
-
|
|
26
|
-
// Clear existing timeout
|
|
27
|
-
clearTimeout(saveTimeout);
|
|
28
|
-
|
|
29
|
-
// Set new timeout for auto-save
|
|
30
|
-
saveTimeout = setTimeout(async () => {
|
|
31
|
-
await handleSave();
|
|
32
|
-
}, 1000); // Save after 1 second of no typing
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
// Textarea reference for initial sizing
|
|
37
|
-
let textareaElement: HTMLTextAreaElement;
|
|
38
|
-
|
|
39
|
-
// Initial sizing effect - runs after component mounts
|
|
40
|
-
$effect(() => {
|
|
41
|
-
if (textareaElement && notes) {
|
|
42
|
-
// Use setTimeout to ensure DOM is fully rendered
|
|
43
|
-
setTimeout(() => {
|
|
44
|
-
resizeTextarea(textareaElement);
|
|
45
|
-
}, 0);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
// Ctrl+S listener for manual save
|
|
50
|
-
$effect(() => {
|
|
51
|
-
async function handleKeyDown(event: KeyboardEvent) {
|
|
52
|
-
// Check if Ctrl+S (or Cmd+S on Mac) is pressed and textarea is focused
|
|
53
|
-
if ((event.ctrlKey || event.metaKey) && event.key === 's' &&
|
|
54
|
-
textareaElement && document.activeElement === textareaElement) {
|
|
55
|
-
event.preventDefault();
|
|
56
|
-
event.stopPropagation();
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// Clear any pending auto-save timeout and save immediately
|
|
60
|
-
clearTimeout(saveTimeout);
|
|
61
|
-
await handleSave();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Add listener to document
|
|
66
|
-
document.addEventListener('keydown', handleKeyDown);
|
|
67
|
-
|
|
68
|
-
// Cleanup function
|
|
69
|
-
return () => {
|
|
70
|
-
document.removeEventListener('keydown', handleKeyDown);
|
|
71
|
-
};
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
async function handleSave() {
|
|
75
|
-
const currentNotes = notes || '';
|
|
76
|
-
|
|
77
|
-
if (currentNotes === lastSavedNotes) {
|
|
78
|
-
// Show brief "No changes" feedback for manual save attempts
|
|
79
|
-
saveState = 'saved';
|
|
80
|
-
setTimeout(() => {
|
|
81
|
-
if (saveState === 'saved') {
|
|
82
|
-
saveState = 'idle';
|
|
83
|
-
}
|
|
84
|
-
}, 1000);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
saveState = 'saving';
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
await onSave(currentNotes);
|
|
92
|
-
lastSavedNotes = currentNotes;
|
|
93
|
-
saveState = 'saved';
|
|
94
|
-
|
|
95
|
-
// Clear "saved" status after 2 seconds
|
|
96
|
-
setTimeout(() => {
|
|
97
|
-
if (saveState === 'saved') {
|
|
98
|
-
saveState = 'idle';
|
|
99
|
-
}
|
|
100
|
-
}, 2000);
|
|
101
|
-
} catch (error) {
|
|
102
|
-
console.error('Failed to save notes:', error);
|
|
103
|
-
saveState = 'error';
|
|
104
|
-
|
|
105
|
-
// Clear error status after 3 seconds
|
|
106
|
-
setTimeout(() => {
|
|
107
|
-
if (saveState === 'error') {
|
|
108
|
-
saveState = 'idle';
|
|
109
|
-
}
|
|
110
|
-
}, 3000);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Shared function to resize textarea
|
|
115
|
-
function resizeTextarea(target: HTMLTextAreaElement) {
|
|
116
|
-
// Get computed styles to calculate exact line height
|
|
117
|
-
const computedStyle = window.getComputedStyle(target);
|
|
118
|
-
const lineHeight = parseInt(computedStyle.lineHeight);
|
|
119
|
-
const paddingTop = parseInt(computedStyle.paddingTop);
|
|
120
|
-
const paddingBottom = parseInt(computedStyle.paddingBottom);
|
|
121
|
-
const borderTop = parseInt(computedStyle.borderTopWidth);
|
|
122
|
-
const borderBottom = parseInt(computedStyle.borderBottomWidth);
|
|
123
|
-
|
|
124
|
-
// Calculate heights based on actual lines
|
|
125
|
-
const minLines = 3;
|
|
126
|
-
const maxLines = 15;
|
|
127
|
-
const minHeight = (lineHeight * minLines) + paddingTop + paddingBottom + borderTop + borderBottom;
|
|
128
|
-
const maxHeight = (lineHeight * maxLines) + paddingTop + paddingBottom + borderTop + borderBottom;
|
|
129
|
-
|
|
130
|
-
// Reset height to measure content
|
|
131
|
-
target.style.height = 'auto';
|
|
132
|
-
|
|
133
|
-
// Set height based on content, capped at max
|
|
134
|
-
const contentHeight = target.scrollHeight;
|
|
135
|
-
const newHeight = Math.min(Math.max(contentHeight, minHeight), maxHeight);
|
|
136
|
-
target.style.height = newHeight + 'px';
|
|
137
|
-
|
|
138
|
-
// Only show scrollbar when content actually exceeds max height
|
|
139
|
-
if (contentHeight > maxHeight) {
|
|
140
|
-
target.style.overflowY = 'auto';
|
|
141
|
-
} else {
|
|
142
|
-
target.style.overflowY = 'hidden';
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function handleInput(event: Event) {
|
|
147
|
-
const target = event.target as HTMLTextAreaElement;
|
|
148
|
-
resizeTextarea(target);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
// Get status text and styling - simplified approach
|
|
153
|
-
let statusText = $state('');
|
|
154
|
-
let statusClass = $state('');
|
|
155
|
-
|
|
156
|
-
$effect(() => {
|
|
157
|
-
switch (saveState) {
|
|
158
|
-
case 'typing':
|
|
159
|
-
statusText = 'Typing...';
|
|
160
|
-
statusClass = 'text-gray-500';
|
|
161
|
-
break;
|
|
162
|
-
case 'saving':
|
|
163
|
-
statusText = 'Saving...';
|
|
164
|
-
statusClass = 'text-blue-500';
|
|
165
|
-
break;
|
|
166
|
-
case 'saved':
|
|
167
|
-
statusText = 'Saved';
|
|
168
|
-
statusClass = 'text-green-600';
|
|
169
|
-
break;
|
|
170
|
-
case 'error':
|
|
171
|
-
statusText = 'Save failed';
|
|
172
|
-
statusClass = 'text-red-500';
|
|
173
|
-
break;
|
|
174
|
-
default:
|
|
175
|
-
statusText = '';
|
|
176
|
-
statusClass = '';
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
</script>
|
|
180
|
-
|
|
181
|
-
<div class={className}>
|
|
182
|
-
<!-- Header with Notes label and status -->
|
|
183
|
-
<div class="flex items-center justify-between mb-2">
|
|
184
|
-
<label for="notes-textarea" class="block text-sm font-medium [color:var(--color-text)]">
|
|
185
|
-
Notes
|
|
186
|
-
</label>
|
|
187
|
-
<span class="text-xs {statusClass} min-h-[16px]">
|
|
188
|
-
{statusText}
|
|
189
|
-
</span>
|
|
190
|
-
</div>
|
|
191
|
-
|
|
192
|
-
<!-- Textarea -->
|
|
193
|
-
<textarea
|
|
194
|
-
id="notes-textarea"
|
|
195
|
-
bind:this={textareaElement}
|
|
196
|
-
bind:value={notes}
|
|
197
|
-
{placeholder}
|
|
198
|
-
class="w-full px-3 py-2 bg-transparent [color:var(--color-text)] [border-color:var(--color-secondary)] border-2 rounded-md focus:outline-none hover:[border-color:color-mix(in_srgb,var(--color-secondary)_80%,black)] focus:[border-color:color-mix(in_srgb,var(--color-secondary)_90%,black)] focus:[outline:2px_solid_color-mix(in_srgb,currentColor_70%,transparent)] focus:[outline-offset:0px] resize-none min-h-[80px] overflow-hidden"
|
|
199
|
-
rows="3"
|
|
200
|
-
oninput={handleInput}
|
|
201
|
-
></textarea>
|
|
202
|
-
|
|
203
|
-
</div>
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
type $$ComponentProps = {
|
|
2
|
-
notes: string | undefined;
|
|
3
|
-
placeholder?: string;
|
|
4
|
-
onSave: (notes: string) => Promise<void>;
|
|
5
|
-
className?: string;
|
|
6
|
-
};
|
|
7
|
-
declare const NotesEditor: import("svelte").Component<$$ComponentProps, {}, "notes">;
|
|
8
|
-
type NotesEditor = ReturnType<typeof NotesEditor>;
|
|
9
|
-
export default NotesEditor;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './NotesEditor.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './NotesEditor.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './NumberInput.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './NumberInput.svelte';
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import Input from '../Input/Input.svelte';
|
|
3
|
-
import { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
|
|
4
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
5
|
-
|
|
6
|
-
interface Props extends Omit<HTMLInputAttributes, 'type'> {
|
|
7
|
-
value: string;
|
|
8
|
-
class?: string;
|
|
9
|
-
inputClass?: string;
|
|
10
|
-
validate?: (value: string) => boolean | string;
|
|
11
|
-
valid?: boolean;
|
|
12
|
-
touched?: boolean;
|
|
13
|
-
element?: HTMLInputElement;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
let {
|
|
17
|
-
value = $bindable(),
|
|
18
|
-
valid = $bindable(true),
|
|
19
|
-
touched = $bindable(false),
|
|
20
|
-
element = $bindable(),
|
|
21
|
-
...restProps
|
|
22
|
-
}: Props = $props();
|
|
23
|
-
|
|
24
|
-
let showPassword = $state(false);
|
|
25
|
-
|
|
26
|
-
function toggleVisibility() {
|
|
27
|
-
showPassword = !showPassword;
|
|
28
|
-
}
|
|
29
|
-
</script>
|
|
30
|
-
|
|
31
|
-
<Input
|
|
32
|
-
bind:value
|
|
33
|
-
bind:valid
|
|
34
|
-
bind:touched
|
|
35
|
-
bind:element
|
|
36
|
-
type={showPassword ? 'text' : 'password'}
|
|
37
|
-
icon={showPassword ? faEye : faEyeSlash}
|
|
38
|
-
iconClickable={true}
|
|
39
|
-
onIconClick={toggleVisibility}
|
|
40
|
-
{...restProps}
|
|
41
|
-
/>
|
|
@@ -1,13 +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
|
-
}
|
|
11
|
-
declare const PasswordInput: import("svelte").Component<Props, {}, "element" | "value" | "valid" | "touched">;
|
|
12
|
-
type PasswordInput = ReturnType<typeof PasswordInput>;
|
|
13
|
-
export default PasswordInput;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './PasswordInput.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './PasswordInput.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Popup.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Popup.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Rating.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Rating.svelte';
|
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from "svelte";
|
|
3
|
-
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
-
|
|
5
|
-
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
6
|
-
showScrollbar?: boolean;
|
|
7
|
-
scrollbarWidth?: number;
|
|
8
|
-
class?: string;
|
|
9
|
-
disabled?: boolean;
|
|
10
|
-
children: Snippet;
|
|
11
|
-
view?: HTMLDivElement;
|
|
12
|
-
onScroll?: (data: {
|
|
13
|
-
scrollTop: number;
|
|
14
|
-
thumbTop: number;
|
|
15
|
-
scrollHeight: number;
|
|
16
|
-
clientHeight: number;
|
|
17
|
-
}) => void;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
let {
|
|
21
|
-
showScrollbar = true,
|
|
22
|
-
scrollbarWidth = 6,
|
|
23
|
-
class: className = "",
|
|
24
|
-
style = "",
|
|
25
|
-
disabled = false,
|
|
26
|
-
children,
|
|
27
|
-
view = $bindable(),
|
|
28
|
-
onScroll,
|
|
29
|
-
...restProps
|
|
30
|
-
}: Props = $props();
|
|
31
|
-
|
|
32
|
-
let isDragging = $state(false);
|
|
33
|
-
let dragStartY = $state(0);
|
|
34
|
-
let dragStartScrollTop = $state(0);
|
|
35
|
-
let scrollTop = $state(0);
|
|
36
|
-
let previousScrollTop = $state(0);
|
|
37
|
-
let scrollHeight = $state(0);
|
|
38
|
-
let clientHeight = $state(0);
|
|
39
|
-
let isScrolling = $state(false);
|
|
40
|
-
let isHovering = $state(false);
|
|
41
|
-
let scrollTimeout = $state<ReturnType<typeof setTimeout>>();
|
|
42
|
-
|
|
43
|
-
// Inset from edges (0.25rem = 4px)
|
|
44
|
-
const inset = 4;
|
|
45
|
-
|
|
46
|
-
// Generate unique ID for aria-controls if not provided
|
|
47
|
-
const scrollableId =
|
|
48
|
-
restProps.id ?? `scrollview-${Math.random().toString(36).substr(2, 9)}`;
|
|
49
|
-
|
|
50
|
-
// Split classes: height/sizing/border/rounded classes go to wrapper, everything else to view
|
|
51
|
-
const wrapperClasses = $derived(
|
|
52
|
-
className
|
|
53
|
-
.match(
|
|
54
|
-
/\b(h-|min-h-|max-h-|flex-\d|flex-grow|flex-shrink|flex-none|flex-auto|basis-|border|rounded)\S*/g,
|
|
55
|
-
)
|
|
56
|
-
?.join(" ") || "",
|
|
57
|
-
);
|
|
58
|
-
const viewClasses = $derived(
|
|
59
|
-
className
|
|
60
|
-
.split(/\s+/)
|
|
61
|
-
.filter((cls) => cls && !wrapperClasses.includes(cls))
|
|
62
|
-
.join(" "),
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
// Initialize dimensions when view is mounted
|
|
66
|
-
$effect(() => {
|
|
67
|
-
if (view) {
|
|
68
|
-
scrollTop = view.scrollTop;
|
|
69
|
-
scrollHeight = view.scrollHeight;
|
|
70
|
-
clientHeight = view.clientHeight;
|
|
71
|
-
|
|
72
|
-
// Fire initial callback if provided
|
|
73
|
-
if (onScroll) {
|
|
74
|
-
onScroll({ scrollTop, thumbTop, scrollHeight, clientHeight });
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Calculate thumb height based on view dimensions
|
|
80
|
-
const thumbHeight = $derived.by(() => {
|
|
81
|
-
if (scrollHeight === 0 || clientHeight === 0) return 20;
|
|
82
|
-
const visibleRatio = clientHeight / scrollHeight;
|
|
83
|
-
return Math.max(
|
|
84
|
-
20,
|
|
85
|
-
Math.min(clientHeight - inset * 2, visibleRatio * clientHeight),
|
|
86
|
-
);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// Calculate thumb position based on scroll position
|
|
90
|
-
const thumbTop = $derived.by(() => {
|
|
91
|
-
if (scrollHeight === 0 || clientHeight === 0) return inset;
|
|
92
|
-
const maxScrollTop = scrollHeight - clientHeight;
|
|
93
|
-
if (maxScrollTop <= 0) return inset;
|
|
94
|
-
const scrollRatio = scrollTop / maxScrollTop;
|
|
95
|
-
const trackHeight = clientHeight - thumbHeight - inset * 2;
|
|
96
|
-
return inset + scrollRatio * trackHeight;
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
// Check if scrollbar is needed
|
|
100
|
-
const needsScrollbar = $derived(
|
|
101
|
-
showScrollbar &&
|
|
102
|
-
!disabled &&
|
|
103
|
-
scrollHeight > 0 &&
|
|
104
|
-
clientHeight > 0 &&
|
|
105
|
-
scrollHeight > clientHeight,
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
// Calculate scroll percentage for aria-valuenow
|
|
109
|
-
const scrollPercentage = $derived(() => {
|
|
110
|
-
if (!view) return 0;
|
|
111
|
-
const maxScrollTop = view.scrollHeight - view.clientHeight;
|
|
112
|
-
if (maxScrollTop <= 0) return 0;
|
|
113
|
-
return Math.round((scrollTop / maxScrollTop) * 100);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// Calculate opacity based on state
|
|
117
|
-
const thumbOpacity = $derived(isScrolling || isHovering ? "80%" : "30%");
|
|
118
|
-
|
|
119
|
-
// Handle scrollbar thumb mouse down
|
|
120
|
-
function handleThumbMouseDown(event: MouseEvent) {
|
|
121
|
-
if (!view) return;
|
|
122
|
-
event.preventDefault();
|
|
123
|
-
isDragging = true;
|
|
124
|
-
dragStartY = event.clientY;
|
|
125
|
-
dragStartScrollTop = view.scrollTop;
|
|
126
|
-
|
|
127
|
-
document.addEventListener("mousemove", handleThumbMouseMove);
|
|
128
|
-
document.addEventListener("mouseup", handleThumbMouseUp);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Handle scrollbar thumb mouse move
|
|
132
|
-
function handleThumbMouseMove(event: MouseEvent) {
|
|
133
|
-
if (!isDragging || !view) return;
|
|
134
|
-
|
|
135
|
-
const deltaY = event.clientY - dragStartY;
|
|
136
|
-
const scrollRatio = deltaY / (view.clientHeight - thumbHeight);
|
|
137
|
-
const maxScrollTop = view.scrollHeight - view.clientHeight;
|
|
138
|
-
|
|
139
|
-
view.scrollTop = Math.max(
|
|
140
|
-
0,
|
|
141
|
-
Math.min(
|
|
142
|
-
maxScrollTop,
|
|
143
|
-
dragStartScrollTop + scrollRatio * maxScrollTop,
|
|
144
|
-
),
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Handle scrollbar thumb mouse up
|
|
149
|
-
function handleThumbMouseUp() {
|
|
150
|
-
isDragging = false;
|
|
151
|
-
document.removeEventListener("mousemove", handleThumbMouseMove);
|
|
152
|
-
document.removeEventListener("mouseup", handleThumbMouseUp);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Handle keyboard events - prevent scroll chaining while preserving smooth scrolling
|
|
156
|
-
function handleKeyDown(event: KeyboardEvent) {
|
|
157
|
-
if (disabled) return;
|
|
158
|
-
|
|
159
|
-
// Only handle if this ScrollView has focus (not a child element)
|
|
160
|
-
if (event.target !== view) return;
|
|
161
|
-
|
|
162
|
-
// Check for scroll keys
|
|
163
|
-
const scrollKeys = [
|
|
164
|
-
"ArrowDown",
|
|
165
|
-
"ArrowUp",
|
|
166
|
-
"PageDown",
|
|
167
|
-
"PageUp",
|
|
168
|
-
"Home",
|
|
169
|
-
"End",
|
|
170
|
-
" ",
|
|
171
|
-
];
|
|
172
|
-
if (!scrollKeys.includes(event.key)) return;
|
|
173
|
-
|
|
174
|
-
if (!view) return;
|
|
175
|
-
|
|
176
|
-
// ALWAYS prevent default and stop propagation to have full control
|
|
177
|
-
event.preventDefault();
|
|
178
|
-
event.stopPropagation();
|
|
179
|
-
|
|
180
|
-
// Calculate scroll amount based on key
|
|
181
|
-
const {
|
|
182
|
-
clientHeight: currentClientHeight,
|
|
183
|
-
scrollTop: currentScrollTop,
|
|
184
|
-
scrollHeight: currentScrollHeight,
|
|
185
|
-
} = view;
|
|
186
|
-
let scrollAmount = 0;
|
|
187
|
-
|
|
188
|
-
if (event.key === "ArrowDown") scrollAmount = 40;
|
|
189
|
-
else if (event.key === "ArrowUp") scrollAmount = -40;
|
|
190
|
-
else if (event.key === "PageDown")
|
|
191
|
-
scrollAmount = currentClientHeight * 0.9;
|
|
192
|
-
else if (event.key === "PageUp")
|
|
193
|
-
scrollAmount = -currentClientHeight * 0.9;
|
|
194
|
-
else if (event.key === " ")
|
|
195
|
-
scrollAmount = event.shiftKey
|
|
196
|
-
? -currentClientHeight * 0.9
|
|
197
|
-
: currentClientHeight * 0.9;
|
|
198
|
-
else if (event.key === "Home") scrollAmount = -currentScrollTop;
|
|
199
|
-
else if (event.key === "End")
|
|
200
|
-
scrollAmount =
|
|
201
|
-
currentScrollHeight - currentClientHeight - currentScrollTop;
|
|
202
|
-
|
|
203
|
-
// Apply scroll instantly (smooth behavior feels laggy with keyboard)
|
|
204
|
-
view.scrollBy({ top: scrollAmount, behavior: "auto" });
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Handle scroll and update state
|
|
208
|
-
function handleScroll() {
|
|
209
|
-
if (!view) return;
|
|
210
|
-
|
|
211
|
-
// Update scroll state
|
|
212
|
-
previousScrollTop = scrollTop;
|
|
213
|
-
scrollTop = view.scrollTop;
|
|
214
|
-
scrollHeight = view.scrollHeight;
|
|
215
|
-
clientHeight = view.clientHeight;
|
|
216
|
-
|
|
217
|
-
// Show scrollbar during scrolling
|
|
218
|
-
isScrolling = true;
|
|
219
|
-
|
|
220
|
-
// Clear previous timeout
|
|
221
|
-
if (scrollTimeout) {
|
|
222
|
-
clearTimeout(scrollTimeout);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Hide scrollbar after scrolling stops (500ms delay)
|
|
226
|
-
scrollTimeout = setTimeout(() => {
|
|
227
|
-
isScrolling = false;
|
|
228
|
-
}, 500);
|
|
229
|
-
|
|
230
|
-
// Fire onScroll callback
|
|
231
|
-
if (onScroll) {
|
|
232
|
-
onScroll({ scrollTop, thumbTop, scrollHeight, clientHeight });
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
</script>
|
|
236
|
-
|
|
237
|
-
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
238
|
-
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
239
|
-
<div
|
|
240
|
-
class="relative overflow-hidden p-0 flex-1 min-h-8 {wrapperClasses}"
|
|
241
|
-
{style}
|
|
242
|
-
{...restProps}
|
|
243
|
-
>
|
|
244
|
-
<div
|
|
245
|
-
bind:this={view}
|
|
246
|
-
id={scrollableId}
|
|
247
|
-
class="scrollview absolute inset-0 {disabled
|
|
248
|
-
? 'overflow-y-hidden'
|
|
249
|
-
: 'overflow-y-auto'} overflow-x-hidden [scrollbar-width:none] [-ms-overflow-style:none] [overscroll-behavior:contain] {viewClasses} {disabled
|
|
250
|
-
? '[background-color:color-mix(in_srgb,var(--color-text)_5%,transparent)] cursor-not-allowed'
|
|
251
|
-
: '[background-color:var(--color-background)]'} focus-visible:[outline:2px_solid_var(--color-primary)] focus-visible:[outline-offset:0px]"
|
|
252
|
-
onscroll={handleScroll}
|
|
253
|
-
onkeydown={handleKeyDown}
|
|
254
|
-
onmouseenter={() => (isHovering = true)}
|
|
255
|
-
onmouseleave={() => (isHovering = false)}
|
|
256
|
-
tabindex={disabled ? -1 : 0}
|
|
257
|
-
role="region"
|
|
258
|
-
aria-label="Scrollable content"
|
|
259
|
-
>
|
|
260
|
-
{@render children()}
|
|
261
|
-
</div>
|
|
262
|
-
|
|
263
|
-
<!-- Custom scrollbar thumb -->
|
|
264
|
-
{#if needsScrollbar}
|
|
265
|
-
<div
|
|
266
|
-
class="absolute rounded cursor-pointer pointer-events-auto z-10"
|
|
267
|
-
style="top: {thumbTop}px; right: {inset}px; height: {thumbHeight}px; width: {scrollbarWidth}px; background-color: color-mix(in srgb, var(--color-primary) {thumbOpacity}, transparent);"
|
|
268
|
-
onmousedown={handleThumbMouseDown}
|
|
269
|
-
role="scrollbar"
|
|
270
|
-
aria-controls={scrollableId}
|
|
271
|
-
aria-orientation="vertical"
|
|
272
|
-
aria-valuenow={scrollPercentage()}
|
|
273
|
-
aria-valuemin="0"
|
|
274
|
-
aria-valuemax="100"
|
|
275
|
-
tabindex="-1"
|
|
276
|
-
aria-label="Scroll thumb"
|
|
277
|
-
></div>
|
|
278
|
-
{/if}
|
|
279
|
-
</div>
|
|
280
|
-
|
|
281
|
-
<style>
|
|
282
|
-
.scrollview::-webkit-scrollbar {
|
|
283
|
-
display: none;
|
|
284
|
-
}
|
|
285
|
-
</style>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from "svelte";
|
|
2
|
-
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
-
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
-
showScrollbar?: boolean;
|
|
5
|
-
scrollbarWidth?: number;
|
|
6
|
-
class?: string;
|
|
7
|
-
disabled?: boolean;
|
|
8
|
-
children: Snippet;
|
|
9
|
-
view?: HTMLDivElement;
|
|
10
|
-
onScroll?: (data: {
|
|
11
|
-
scrollTop: number;
|
|
12
|
-
thumbTop: number;
|
|
13
|
-
scrollHeight: number;
|
|
14
|
-
clientHeight: number;
|
|
15
|
-
}) => void;
|
|
16
|
-
}
|
|
17
|
-
declare const ScrollView: import("svelte").Component<Props, {}, "view">;
|
|
18
|
-
type ScrollView = ReturnType<typeof ScrollView>;
|
|
19
|
-
export default ScrollView;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './ScrollView.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './ScrollView.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './SearchInput.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './SearchInput.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Select.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Select.svelte';
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { HTMLTextareaAttributes } from "svelte/elements";
|
|
2
|
-
interface Props extends HTMLTextareaAttributes {
|
|
3
|
-
value?: string;
|
|
4
|
-
lines?: string[];
|
|
5
|
-
class?: string;
|
|
6
|
-
textareaClass?: string;
|
|
7
|
-
validate?: (value: string) => boolean | string;
|
|
8
|
-
valid?: boolean;
|
|
9
|
-
touched?: boolean;
|
|
10
|
-
element?: HTMLTextAreaElement;
|
|
11
|
-
minRows?: number;
|
|
12
|
-
maxRows?: number;
|
|
13
|
-
lineHeightRem?: number;
|
|
14
|
-
required?: boolean;
|
|
15
|
-
allowCopy?: boolean;
|
|
16
|
-
}
|
|
17
|
-
declare const TextArea: import("svelte").Component<Props, {}, "element" | "value" | "valid" | "touched" | "lines" | "allowCopy">;
|
|
18
|
-
type TextArea = ReturnType<typeof TextArea>;
|
|
19
|
-
export default TextArea;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './TextArea.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './TextArea.svelte';
|