@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.
Files changed (104) hide show
  1. package/dist/components/ActivityFeed.svelte +135 -0
  2. package/dist/components/ActivityFeed.svelte.d.ts +21 -0
  3. package/dist/components/ApprovalActionCard.svelte +248 -0
  4. package/dist/components/ApprovalActionCard.svelte.d.ts +22 -0
  5. package/dist/components/AutoTable.svelte +8 -0
  6. package/dist/components/AutoTable.svelte.d.ts +7 -1
  7. package/dist/components/CanvasAnnotation.svelte +389 -0
  8. package/dist/components/CanvasAnnotation.svelte.d.ts +17 -0
  9. package/dist/components/Cascader.svelte +205 -0
  10. package/dist/components/Cascader.svelte.d.ts +21 -0
  11. package/dist/components/ColumnHeaderFilter.svelte +178 -0
  12. package/dist/components/ColumnHeaderFilter.svelte.d.ts +12 -0
  13. package/dist/components/ColumnSettings.svelte +198 -0
  14. package/dist/components/ColumnSettings.svelte.d.ts +19 -0
  15. package/dist/components/DecisionTable.svelte +240 -0
  16. package/dist/components/DecisionTable.svelte.d.ts +22 -0
  17. package/dist/components/DraggableRowTable.svelte +117 -0
  18. package/dist/components/DraggableRowTable.svelte.d.ts +15 -0
  19. package/dist/components/DrawerForm.svelte +110 -26
  20. package/dist/components/DrawerForm.svelte.d.ts +20 -8
  21. package/dist/components/DynamicFormList.svelte +214 -0
  22. package/dist/components/DynamicFormList.svelte.d.ts +62 -0
  23. package/dist/components/EditableTable.svelte +195 -0
  24. package/dist/components/EditableTable.svelte.d.ts +25 -0
  25. package/dist/components/FieldRenderer.svelte +32 -0
  26. package/dist/components/FilterBuilder.svelte +310 -0
  27. package/dist/components/FilterBuilder.svelte.d.ts +23 -0
  28. package/dist/components/GanttChart.svelte +144 -0
  29. package/dist/components/GanttChart.svelte.d.ts +20 -0
  30. package/dist/components/ImageCropper.svelte +122 -0
  31. package/dist/components/ImageCropper.svelte.d.ts +12 -0
  32. package/dist/components/ImportWizard.svelte +336 -0
  33. package/dist/components/ImportWizard.svelte.d.ts +12 -0
  34. package/dist/components/JsonSchemaForm.svelte +149 -0
  35. package/dist/components/JsonSchemaForm.svelte.d.ts +10 -0
  36. package/dist/components/KanbanBoard.svelte +212 -0
  37. package/dist/components/KanbanBoard.svelte.d.ts +30 -0
  38. package/dist/components/MasterDetailView.svelte +134 -0
  39. package/dist/components/MasterDetailView.svelte.d.ts +16 -0
  40. package/dist/components/MediaLibraryModal.svelte +195 -0
  41. package/dist/components/MediaLibraryModal.svelte.d.ts +22 -0
  42. package/dist/components/MentionsInput.svelte +174 -0
  43. package/dist/components/MentionsInput.svelte.d.ts +21 -0
  44. package/dist/components/ModalForm.svelte +113 -28
  45. package/dist/components/ModalForm.svelte.d.ts +20 -8
  46. package/dist/components/MultiTabKeepAlive.svelte +143 -0
  47. package/dist/components/MultiTabKeepAlive.svelte.d.ts +21 -0
  48. package/dist/components/OfflineSyncBanner.svelte +172 -0
  49. package/dist/components/OfflineSyncBanner.svelte.d.ts +19 -0
  50. package/dist/components/PdfDocumentViewer.svelte +255 -0
  51. package/dist/components/PdfDocumentViewer.svelte.d.ts +22 -0
  52. package/dist/components/PivotTable.svelte +140 -0
  53. package/dist/components/PivotTable.svelte.d.ts +16 -0
  54. package/dist/components/PresenceAvatarGroup.svelte +89 -0
  55. package/dist/components/PresenceAvatarGroup.svelte.d.ts +15 -0
  56. package/dist/components/PrintableBill.svelte +149 -0
  57. package/dist/components/PrintableBill.svelte.d.ts +24 -0
  58. package/dist/components/SensitiveDataMask.svelte +125 -0
  59. package/dist/components/SensitiveDataMask.svelte.d.ts +13 -0
  60. package/dist/components/SignaturePad.svelte +264 -0
  61. package/dist/components/SignaturePad.svelte.d.ts +17 -0
  62. package/dist/components/SplitPaneLayout.svelte +113 -0
  63. package/dist/components/SplitPaneLayout.svelte.d.ts +13 -0
  64. package/dist/components/SpreadsheetView.svelte +363 -0
  65. package/dist/components/SpreadsheetView.svelte.d.ts +18 -0
  66. package/dist/components/StepForm.svelte +180 -0
  67. package/dist/components/StepForm.svelte.d.ts +23 -0
  68. package/dist/components/TableSummary.svelte +110 -0
  69. package/dist/components/TableSummary.svelte.d.ts +20 -0
  70. package/dist/components/Transfer.svelte +352 -0
  71. package/dist/components/Transfer.svelte.d.ts +28 -0
  72. package/dist/components/TreeSelect.svelte +307 -0
  73. package/dist/components/TreeSelect.svelte.d.ts +22 -0
  74. package/dist/components/TreeTable.svelte +237 -0
  75. package/dist/components/TreeTable.svelte.d.ts +28 -0
  76. package/dist/components/UnsavedChangesPrompt.svelte +44 -0
  77. package/dist/components/UnsavedChangesPrompt.svelte.d.ts +7 -0
  78. package/dist/components/VersionDiffViewer.svelte +196 -0
  79. package/dist/components/VersionDiffViewer.svelte.d.ts +12 -0
  80. package/dist/components/VirtualTable.svelte +86 -54
  81. package/dist/components/VirtualTable.svelte.d.ts +14 -21
  82. package/dist/components/Watermark.svelte +166 -0
  83. package/dist/components/Watermark.svelte.d.ts +26 -0
  84. package/dist/components/ui/navigation-menu/index.d.ts +11 -0
  85. package/dist/components/ui/navigation-menu/index.js +13 -0
  86. package/dist/components/ui/navigation-menu/navigation-menu-content.svelte +21 -0
  87. package/dist/components/ui/navigation-menu/navigation-menu-content.svelte.d.ts +4 -0
  88. package/dist/components/ui/navigation-menu/navigation-menu-indicator.svelte +22 -0
  89. package/dist/components/ui/navigation-menu/navigation-menu-indicator.svelte.d.ts +4 -0
  90. package/dist/components/ui/navigation-menu/navigation-menu-item.svelte +17 -0
  91. package/dist/components/ui/navigation-menu/navigation-menu-item.svelte.d.ts +4 -0
  92. package/dist/components/ui/navigation-menu/navigation-menu-link.svelte +20 -0
  93. package/dist/components/ui/navigation-menu/navigation-menu-link.svelte.d.ts +4 -0
  94. package/dist/components/ui/navigation-menu/navigation-menu-list.svelte +17 -0
  95. package/dist/components/ui/navigation-menu/navigation-menu-list.svelte.d.ts +4 -0
  96. package/dist/components/ui/navigation-menu/navigation-menu-trigger.svelte +28 -0
  97. package/dist/components/ui/navigation-menu/navigation-menu-trigger.svelte.d.ts +4 -0
  98. package/dist/components/ui/navigation-menu/navigation-menu-viewport.svelte +22 -0
  99. package/dist/components/ui/navigation-menu/navigation-menu-viewport.svelte.d.ts +4 -0
  100. package/dist/components/ui/navigation-menu/navigation-menu.svelte +24 -0
  101. package/dist/components/ui/navigation-menu/navigation-menu.svelte.d.ts +4 -0
  102. package/dist/index.d.ts +68 -3
  103. package/dist/index.js +42 -3
  104. 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;