@svadmin/ui 0.63.0 → 0.65.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/dist/components/ActivityFeed.svelte +135 -0
- package/dist/components/ActivityFeed.svelte.d.ts +21 -0
- package/dist/components/ApprovalActionCard.svelte +248 -0
- package/dist/components/ApprovalActionCard.svelte.d.ts +22 -0
- package/dist/components/AutoTable.svelte +8 -0
- package/dist/components/AutoTable.svelte.d.ts +7 -1
- package/dist/components/CanvasAnnotation.svelte +389 -0
- package/dist/components/CanvasAnnotation.svelte.d.ts +17 -0
- package/dist/components/Cascader.svelte +205 -0
- package/dist/components/Cascader.svelte.d.ts +21 -0
- package/dist/components/ColumnHeaderFilter.svelte +178 -0
- package/dist/components/ColumnHeaderFilter.svelte.d.ts +12 -0
- package/dist/components/ColumnSettings.svelte +198 -0
- package/dist/components/ColumnSettings.svelte.d.ts +19 -0
- package/dist/components/DecisionTable.svelte +240 -0
- package/dist/components/DecisionTable.svelte.d.ts +22 -0
- package/dist/components/DraggableRowTable.svelte +117 -0
- package/dist/components/DraggableRowTable.svelte.d.ts +15 -0
- package/dist/components/DrawerForm.svelte +110 -26
- package/dist/components/DrawerForm.svelte.d.ts +20 -8
- package/dist/components/DynamicFormList.svelte +214 -0
- package/dist/components/DynamicFormList.svelte.d.ts +62 -0
- package/dist/components/EditableTable.svelte +195 -0
- package/dist/components/EditableTable.svelte.d.ts +25 -0
- package/dist/components/FieldRenderer.svelte +32 -0
- package/dist/components/FilterBuilder.svelte +310 -0
- package/dist/components/FilterBuilder.svelte.d.ts +23 -0
- package/dist/components/GanttChart.svelte +144 -0
- package/dist/components/GanttChart.svelte.d.ts +20 -0
- package/dist/components/ImageCropper.svelte +122 -0
- package/dist/components/ImageCropper.svelte.d.ts +12 -0
- package/dist/components/ImportWizard.svelte +336 -0
- package/dist/components/ImportWizard.svelte.d.ts +12 -0
- package/dist/components/JsonSchemaForm.svelte +149 -0
- package/dist/components/JsonSchemaForm.svelte.d.ts +10 -0
- package/dist/components/KanbanBoard.svelte +212 -0
- package/dist/components/KanbanBoard.svelte.d.ts +30 -0
- package/dist/components/MasterDetailView.svelte +134 -0
- package/dist/components/MasterDetailView.svelte.d.ts +16 -0
- package/dist/components/MediaLibraryModal.svelte +195 -0
- package/dist/components/MediaLibraryModal.svelte.d.ts +22 -0
- package/dist/components/MentionsInput.svelte +174 -0
- package/dist/components/MentionsInput.svelte.d.ts +21 -0
- package/dist/components/ModalForm.svelte +113 -28
- package/dist/components/ModalForm.svelte.d.ts +20 -8
- package/dist/components/MultiTabKeepAlive.svelte +143 -0
- package/dist/components/MultiTabKeepAlive.svelte.d.ts +21 -0
- package/dist/components/OfflineSyncBanner.svelte +172 -0
- package/dist/components/OfflineSyncBanner.svelte.d.ts +19 -0
- package/dist/components/PdfDocumentViewer.svelte +255 -0
- package/dist/components/PdfDocumentViewer.svelte.d.ts +22 -0
- package/dist/components/PivotTable.svelte +140 -0
- package/dist/components/PivotTable.svelte.d.ts +16 -0
- package/dist/components/PresenceAvatarGroup.svelte +89 -0
- package/dist/components/PresenceAvatarGroup.svelte.d.ts +15 -0
- package/dist/components/PrintableBill.svelte +149 -0
- package/dist/components/PrintableBill.svelte.d.ts +24 -0
- package/dist/components/SensitiveDataMask.svelte +125 -0
- package/dist/components/SensitiveDataMask.svelte.d.ts +13 -0
- package/dist/components/SignaturePad.svelte +264 -0
- package/dist/components/SignaturePad.svelte.d.ts +17 -0
- package/dist/components/SplitPaneLayout.svelte +113 -0
- package/dist/components/SplitPaneLayout.svelte.d.ts +13 -0
- package/dist/components/SpreadsheetView.svelte +363 -0
- package/dist/components/SpreadsheetView.svelte.d.ts +18 -0
- package/dist/components/StepForm.svelte +180 -0
- package/dist/components/StepForm.svelte.d.ts +23 -0
- package/dist/components/TableSummary.svelte +110 -0
- package/dist/components/TableSummary.svelte.d.ts +20 -0
- package/dist/components/Transfer.svelte +352 -0
- package/dist/components/Transfer.svelte.d.ts +28 -0
- package/dist/components/TreeSelect.svelte +307 -0
- package/dist/components/TreeSelect.svelte.d.ts +22 -0
- package/dist/components/TreeTable.svelte +237 -0
- package/dist/components/TreeTable.svelte.d.ts +28 -0
- package/dist/components/UnsavedChangesPrompt.svelte +44 -0
- package/dist/components/UnsavedChangesPrompt.svelte.d.ts +7 -0
- package/dist/components/VersionDiffViewer.svelte +196 -0
- package/dist/components/VersionDiffViewer.svelte.d.ts +12 -0
- package/dist/components/VirtualTable.svelte +86 -54
- package/dist/components/VirtualTable.svelte.d.ts +14 -21
- package/dist/components/Watermark.svelte +166 -0
- package/dist/components/Watermark.svelte.d.ts +26 -0
- package/dist/components/ui/navigation-menu/index.d.ts +11 -0
- package/dist/components/ui/navigation-menu/index.js +13 -0
- package/dist/components/ui/navigation-menu/navigation-menu-content.svelte +21 -0
- package/dist/components/ui/navigation-menu/navigation-menu-content.svelte.d.ts +4 -0
- package/dist/components/ui/navigation-menu/navigation-menu-indicator.svelte +22 -0
- package/dist/components/ui/navigation-menu/navigation-menu-indicator.svelte.d.ts +4 -0
- package/dist/components/ui/navigation-menu/navigation-menu-item.svelte +17 -0
- package/dist/components/ui/navigation-menu/navigation-menu-item.svelte.d.ts +4 -0
- package/dist/components/ui/navigation-menu/navigation-menu-link.svelte +20 -0
- package/dist/components/ui/navigation-menu/navigation-menu-link.svelte.d.ts +4 -0
- package/dist/components/ui/navigation-menu/navigation-menu-list.svelte +17 -0
- package/dist/components/ui/navigation-menu/navigation-menu-list.svelte.d.ts +4 -0
- package/dist/components/ui/navigation-menu/navigation-menu-trigger.svelte +28 -0
- package/dist/components/ui/navigation-menu/navigation-menu-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/navigation-menu/navigation-menu-viewport.svelte +22 -0
- package/dist/components/ui/navigation-menu/navigation-menu-viewport.svelte.d.ts +4 -0
- package/dist/components/ui/navigation-menu/navigation-menu.svelte +24 -0
- package/dist/components/ui/navigation-menu/navigation-menu.svelte.d.ts +4 -0
- package/dist/index.d.ts +68 -3
- package/dist/index.js +42 -3
- package/package.json +2 -2
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte';
|
|
3
|
+
import { Button } from './ui/button/index.js';
|
|
4
|
+
import { RotateCcw, Trash2, Check, Download } from '@lucide/svelte';
|
|
5
|
+
import { cn } from '../utils.js';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
value?: string;
|
|
9
|
+
width?: number;
|
|
10
|
+
height?: number;
|
|
11
|
+
strokeColor?: string;
|
|
12
|
+
strokeWidth?: number;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
onchange?: (dataUrl: string) => void;
|
|
15
|
+
onsave?: (dataUrl: string) => void;
|
|
16
|
+
class?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let {
|
|
20
|
+
value = $bindable(''),
|
|
21
|
+
width = 500,
|
|
22
|
+
height = 200,
|
|
23
|
+
strokeColor = 'currentColor',
|
|
24
|
+
strokeWidth = 2.5,
|
|
25
|
+
disabled = false,
|
|
26
|
+
onchange,
|
|
27
|
+
onsave,
|
|
28
|
+
class: className = '',
|
|
29
|
+
}: Props = $props();
|
|
30
|
+
|
|
31
|
+
let canvasEl = $state<HTMLCanvasElement | null>(null);
|
|
32
|
+
let isDrawing = $state(false);
|
|
33
|
+
let isEmpty = $state(true);
|
|
34
|
+
let history = $state<ImageData[]>([]);
|
|
35
|
+
|
|
36
|
+
interface Point {
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let points: Point[] = [];
|
|
42
|
+
|
|
43
|
+
function getCanvasPos(e: MouseEvent | TouchEvent): Point | null {
|
|
44
|
+
if (!canvasEl) return null;
|
|
45
|
+
const rect = canvasEl.getBoundingClientRect();
|
|
46
|
+
const scaleX = canvasEl.width / rect.width;
|
|
47
|
+
const scaleY = canvasEl.height / rect.height;
|
|
48
|
+
|
|
49
|
+
if ('touches' in e) {
|
|
50
|
+
if (e.touches.length === 0) return null;
|
|
51
|
+
const touch = e.touches[0];
|
|
52
|
+
if (!touch) return null;
|
|
53
|
+
return {
|
|
54
|
+
x: (touch.clientX - rect.left) * scaleX,
|
|
55
|
+
y: (touch.clientY - rect.top) * scaleY,
|
|
56
|
+
};
|
|
57
|
+
} else {
|
|
58
|
+
return {
|
|
59
|
+
x: (e.clientX - rect.left) * scaleX,
|
|
60
|
+
y: (e.clientY - rect.top) * scaleY,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function startDrawing(e: MouseEvent | TouchEvent) {
|
|
66
|
+
if (disabled || !canvasEl) return;
|
|
67
|
+
const pos = getCanvasPos(e);
|
|
68
|
+
if (!pos) return;
|
|
69
|
+
|
|
70
|
+
const ctx = canvasEl.getContext('2d');
|
|
71
|
+
if (ctx) {
|
|
72
|
+
history = [...history, ctx.getImageData(0, 0, canvasEl.width, canvasEl.height)];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
isDrawing = true;
|
|
76
|
+
points = [pos];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function draw(e: MouseEvent | TouchEvent) {
|
|
80
|
+
if (!isDrawing || disabled || !canvasEl) return;
|
|
81
|
+
const pos = getCanvasPos(e);
|
|
82
|
+
if (!pos) return;
|
|
83
|
+
|
|
84
|
+
points.push(pos);
|
|
85
|
+
const ctx = canvasEl.getContext('2d');
|
|
86
|
+
if (!ctx) return;
|
|
87
|
+
|
|
88
|
+
ctx.strokeStyle = strokeColor === 'currentColor' ? (canvasEl ? getComputedStyle(canvasEl).color : 'rgb(0,0,0)') : strokeColor;
|
|
89
|
+
ctx.lineWidth = strokeWidth;
|
|
90
|
+
ctx.lineCap = 'round';
|
|
91
|
+
ctx.lineJoin = 'round';
|
|
92
|
+
|
|
93
|
+
if (points.length < 3) {
|
|
94
|
+
const b = points[0];
|
|
95
|
+
if (b) {
|
|
96
|
+
ctx.beginPath();
|
|
97
|
+
ctx.arc(b.x, b.y, ctx.lineWidth / 2, 0, Math.PI * 2, !0);
|
|
98
|
+
ctx.fillStyle = ctx.strokeStyle;
|
|
99
|
+
ctx.fill();
|
|
100
|
+
ctx.closePath();
|
|
101
|
+
}
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
ctx.beginPath();
|
|
106
|
+
const p0 = points[0];
|
|
107
|
+
if (p0) {
|
|
108
|
+
ctx.moveTo(p0.x, p0.y);
|
|
109
|
+
}
|
|
110
|
+
for (let i = 1; i < points.length - 1; i++) {
|
|
111
|
+
const pi = points[i];
|
|
112
|
+
const pi1 = points[i + 1];
|
|
113
|
+
if (pi && pi1) {
|
|
114
|
+
const xc = (pi.x + pi1.x) / 2;
|
|
115
|
+
const yc = (pi.y + pi1.y) / 2;
|
|
116
|
+
ctx.quadraticCurveTo(pi.x, pi.y, xc, yc);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
ctx.stroke();
|
|
120
|
+
isEmpty = false;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function stopDrawing() {
|
|
124
|
+
if (!isDrawing || !canvasEl) return;
|
|
125
|
+
isDrawing = false;
|
|
126
|
+
points = [];
|
|
127
|
+
|
|
128
|
+
const dataUrl = canvasEl.toDataURL('image/png');
|
|
129
|
+
value = dataUrl;
|
|
130
|
+
onchange?.(dataUrl);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function clear() {
|
|
134
|
+
if (!canvasEl) return;
|
|
135
|
+
const ctx = canvasEl.getContext('2d');
|
|
136
|
+
if (!ctx) return;
|
|
137
|
+
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
|
|
138
|
+
history = [];
|
|
139
|
+
isEmpty = true;
|
|
140
|
+
value = '';
|
|
141
|
+
onchange?.('');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function undo() {
|
|
145
|
+
if (!canvasEl || history.length === 0) return;
|
|
146
|
+
const ctx = canvasEl.getContext('2d');
|
|
147
|
+
if (!ctx) return;
|
|
148
|
+
const previous = history[history.length - 1];
|
|
149
|
+
history = history.slice(0, -1);
|
|
150
|
+
if (previous) {
|
|
151
|
+
ctx.putImageData(previous, 0, 0);
|
|
152
|
+
}
|
|
153
|
+
isEmpty = history.length === 0;
|
|
154
|
+
const dataUrl = isEmpty ? '' : canvasEl.toDataURL('image/png');
|
|
155
|
+
value = dataUrl;
|
|
156
|
+
onchange?.(dataUrl);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function handleSave() {
|
|
160
|
+
if (isEmpty || !canvasEl) return;
|
|
161
|
+
const dataUrl = canvasEl.toDataURL('image/png');
|
|
162
|
+
onsave?.(dataUrl);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function handleDownload() {
|
|
166
|
+
if (isEmpty || !canvasEl) return;
|
|
167
|
+
const a = document.createElement('a');
|
|
168
|
+
a.href = canvasEl.toDataURL('image/png');
|
|
169
|
+
a.download = `signature_${Date.now()}.png`;
|
|
170
|
+
a.click();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
onMount(() => {
|
|
174
|
+
if (canvasEl && value) {
|
|
175
|
+
const img = new Image();
|
|
176
|
+
img.onload = () => {
|
|
177
|
+
const ctx = canvasEl?.getContext('2d');
|
|
178
|
+
if (ctx && canvasEl) {
|
|
179
|
+
ctx.drawImage(img, 0, 0);
|
|
180
|
+
isEmpty = false;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
img.src = value;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
</script>
|
|
187
|
+
|
|
188
|
+
<div class={cn('rounded-xl border border-border bg-card p-4 shadow-xs text-xs space-y-3', className)}>
|
|
189
|
+
<div class="flex items-center justify-between gap-2 pb-2 border-b border-border/60">
|
|
190
|
+
<div class="font-semibold text-foreground">
|
|
191
|
+
Electronic Signature <span class="text-muted-foreground font-normal">(Sign inside the box)</span>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div class="flex items-center gap-1.5">
|
|
195
|
+
<Button
|
|
196
|
+
variant="ghost"
|
|
197
|
+
size="sm"
|
|
198
|
+
class="h-7 text-xs gap-1 text-muted-foreground hover:text-foreground"
|
|
199
|
+
disabled={history.length === 0 || disabled}
|
|
200
|
+
onclick={undo}
|
|
201
|
+
>
|
|
202
|
+
<RotateCcw class="h-3 w-3" />
|
|
203
|
+
Undo
|
|
204
|
+
</Button>
|
|
205
|
+
|
|
206
|
+
<Button
|
|
207
|
+
variant="ghost"
|
|
208
|
+
size="sm"
|
|
209
|
+
class="h-7 text-xs gap-1 text-muted-foreground hover:text-destructive hover:bg-destructive/10"
|
|
210
|
+
disabled={isEmpty || disabled}
|
|
211
|
+
onclick={clear}
|
|
212
|
+
>
|
|
213
|
+
<Trash2 class="h-3 w-3" />
|
|
214
|
+
Clear
|
|
215
|
+
</Button>
|
|
216
|
+
|
|
217
|
+
{#if onsave}
|
|
218
|
+
<Button
|
|
219
|
+
size="sm"
|
|
220
|
+
class="h-7 text-xs gap-1"
|
|
221
|
+
disabled={isEmpty || disabled}
|
|
222
|
+
onclick={handleSave}
|
|
223
|
+
>
|
|
224
|
+
<Check class="h-3 w-3" />
|
|
225
|
+
Confirm
|
|
226
|
+
</Button>
|
|
227
|
+
{:else}
|
|
228
|
+
<Button
|
|
229
|
+
variant="outline"
|
|
230
|
+
size="sm"
|
|
231
|
+
class="h-7 text-xs gap-1"
|
|
232
|
+
disabled={isEmpty || disabled}
|
|
233
|
+
onclick={handleDownload}
|
|
234
|
+
>
|
|
235
|
+
<Download class="h-3 w-3" />
|
|
236
|
+
Download
|
|
237
|
+
</Button>
|
|
238
|
+
{/if}
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
<!-- Canvas Drawing Board -->
|
|
243
|
+
<div class="relative w-full rounded-lg border-2 border-dashed border-border/80 bg-background overflow-hidden flex items-center justify-center">
|
|
244
|
+
<canvas
|
|
245
|
+
bind:this={canvasEl}
|
|
246
|
+
{width}
|
|
247
|
+
{height}
|
|
248
|
+
class="touch-none cursor-crosshair max-w-full h-auto block"
|
|
249
|
+
onmousedown={startDrawing}
|
|
250
|
+
onmousemove={draw}
|
|
251
|
+
onmouseup={stopDrawing}
|
|
252
|
+
onmouseleave={stopDrawing}
|
|
253
|
+
ontouchstart={(e) => { e.preventDefault(); startDrawing(e); }}
|
|
254
|
+
ontouchmove={(e) => { e.preventDefault(); draw(e); }}
|
|
255
|
+
ontouchend={(e) => { e.preventDefault(); stopDrawing(); }}
|
|
256
|
+
></canvas>
|
|
257
|
+
|
|
258
|
+
{#if isEmpty}
|
|
259
|
+
<div class="absolute inset-0 flex items-center justify-center pointer-events-none text-muted-foreground/40 font-mono text-xs select-none">
|
|
260
|
+
Sign here with mouse or touch
|
|
261
|
+
</div>
|
|
262
|
+
{/if}
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
value?: string;
|
|
3
|
+
width?: number;
|
|
4
|
+
height?: number;
|
|
5
|
+
strokeColor?: string;
|
|
6
|
+
strokeWidth?: number;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
onchange?: (dataUrl: string) => void;
|
|
9
|
+
onsave?: (dataUrl: string) => void;
|
|
10
|
+
class?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const SignaturePad: import("svelte").Component<Props, {
|
|
13
|
+
clear: () => void;
|
|
14
|
+
undo: () => void;
|
|
15
|
+
}, "value">;
|
|
16
|
+
type SignaturePad = ReturnType<typeof SignaturePad>;
|
|
17
|
+
export default SignaturePad;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { untrack } from 'svelte';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import { cn } from '../utils.js';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
direction?: 'horizontal' | 'vertical';
|
|
8
|
+
initialRatio?: number;
|
|
9
|
+
minRatio?: number;
|
|
10
|
+
maxRatio?: number;
|
|
11
|
+
pane1?: Snippet;
|
|
12
|
+
pane2?: Snippet;
|
|
13
|
+
class?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
direction = 'horizontal',
|
|
18
|
+
initialRatio = 0.3,
|
|
19
|
+
minRatio = 0.15,
|
|
20
|
+
maxRatio = 0.85,
|
|
21
|
+
pane1,
|
|
22
|
+
pane2,
|
|
23
|
+
class: className = '',
|
|
24
|
+
}: Props = $props();
|
|
25
|
+
|
|
26
|
+
let containerEl = $state<HTMLDivElement | null>(null);
|
|
27
|
+
let ratio = $state(untrack(() => initialRatio));
|
|
28
|
+
let isDragging = $state(false);
|
|
29
|
+
|
|
30
|
+
function startDrag(e: MouseEvent | TouchEvent) {
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
isDragging = true;
|
|
33
|
+
|
|
34
|
+
function onMove(ev: MouseEvent | TouchEvent) {
|
|
35
|
+
if (!containerEl) return;
|
|
36
|
+
const rect = containerEl.getBoundingClientRect();
|
|
37
|
+
|
|
38
|
+
const clientPos =
|
|
39
|
+
direction === 'horizontal'
|
|
40
|
+
? ('touches' in ev ? ev.touches[0].clientX - rect.left : ev.clientX - rect.left)
|
|
41
|
+
: ('touches' in ev ? ev.touches[0].clientY - rect.top : ev.clientY - rect.top);
|
|
42
|
+
const totalSize = direction === 'horizontal' ? rect.width : rect.height;
|
|
43
|
+
|
|
44
|
+
if (totalSize > 0) {
|
|
45
|
+
const calculatedRatio = Math.max(minRatio, Math.min(maxRatio, clientPos / totalSize));
|
|
46
|
+
ratio = calculatedRatio;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function onEnd() {
|
|
51
|
+
isDragging = false;
|
|
52
|
+
window.removeEventListener('mousemove', onMove);
|
|
53
|
+
window.removeEventListener('mouseup', onEnd);
|
|
54
|
+
window.removeEventListener('touchmove', onMove);
|
|
55
|
+
window.removeEventListener('touchend', onEnd);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
window.addEventListener('mousemove', onMove);
|
|
59
|
+
window.addEventListener('mouseup', onEnd);
|
|
60
|
+
window.addEventListener('touchmove', onMove);
|
|
61
|
+
window.addEventListener('touchend', onEnd);
|
|
62
|
+
}
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<div
|
|
66
|
+
bind:this={containerEl}
|
|
67
|
+
class={cn(
|
|
68
|
+
'relative flex w-full h-full min-h-72 rounded-xl border border-border bg-card shadow-xs overflow-hidden select-none',
|
|
69
|
+
direction === 'horizontal' ? 'flex-row' : 'flex-col',
|
|
70
|
+
className
|
|
71
|
+
)}
|
|
72
|
+
>
|
|
73
|
+
<!-- Pane 1 -->
|
|
74
|
+
<div
|
|
75
|
+
style={direction === 'horizontal' ? `width: ${ratio * 100}%;` : `height: ${ratio * 100}%;`}
|
|
76
|
+
class="overflow-auto shrink-0 select-text p-4"
|
|
77
|
+
>
|
|
78
|
+
{#if pane1}
|
|
79
|
+
{@render pane1()}
|
|
80
|
+
{/if}
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<!-- Resizer Splitter -->
|
|
84
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
85
|
+
<div
|
|
86
|
+
onmousedown={startDrag}
|
|
87
|
+
ontouchstart={startDrag}
|
|
88
|
+
class={cn(
|
|
89
|
+
'shrink-0 bg-border hover:bg-primary/60 transition-colors z-10 flex items-center justify-center cursor-pointer',
|
|
90
|
+
direction === 'horizontal'
|
|
91
|
+
? 'w-1.5 cursor-col-resize hover:w-2'
|
|
92
|
+
: 'h-1.5 cursor-row-resize hover:h-2',
|
|
93
|
+
isDragging ? 'bg-primary w-2' : ''
|
|
94
|
+
)}
|
|
95
|
+
>
|
|
96
|
+
<div
|
|
97
|
+
class={cn(
|
|
98
|
+
'rounded-full bg-muted-foreground/40',
|
|
99
|
+
direction === 'horizontal' ? 'h-6 w-0.5' : 'w-6 h-0.5'
|
|
100
|
+
)}
|
|
101
|
+
></div>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<!-- Pane 2 -->
|
|
105
|
+
<div
|
|
106
|
+
style={direction === 'horizontal' ? `width: ${(1 - ratio) * 100}%;` : `height: ${(1 - ratio) * 100}%;`}
|
|
107
|
+
class="overflow-auto flex-1 select-text p-4"
|
|
108
|
+
>
|
|
109
|
+
{#if pane2}
|
|
110
|
+
{@render pane2()}
|
|
111
|
+
{/if}
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
direction?: 'horizontal' | 'vertical';
|
|
4
|
+
initialRatio?: number;
|
|
5
|
+
minRatio?: number;
|
|
6
|
+
maxRatio?: number;
|
|
7
|
+
pane1?: Snippet;
|
|
8
|
+
pane2?: Snippet;
|
|
9
|
+
class?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const SplitPaneLayout: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type SplitPaneLayout = ReturnType<typeof SplitPaneLayout>;
|
|
13
|
+
export default SplitPaneLayout;
|