@suryapamenang/ui 0.1.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/README.md +81 -0
- package/dist/components/basic-blocks-base-kit.d.ts +6 -0
- package/dist/components/basic-blocks-base-kit.d.ts.map +1 -0
- package/dist/components/basic-blocks-base-kit.js +17 -0
- package/dist/components/basic-blocks-kit.d.ts +6 -0
- package/dist/components/basic-blocks-kit.d.ts.map +1 -0
- package/dist/components/basic-blocks-kit.js +68 -0
- package/dist/components/basic-marks-base-kit.d.ts +20 -0
- package/dist/components/basic-marks-base-kit.d.ts.map +1 -0
- package/dist/components/basic-marks-base-kit.js +15 -0
- package/dist/components/basic-marks-kit.d.ts +20 -0
- package/dist/components/basic-marks-kit.d.ts.map +1 -0
- package/dist/components/basic-marks-kit.js +27 -0
- package/dist/components/basic-nodes-kit.d.ts +24 -0
- package/dist/components/basic-nodes-kit.d.ts.map +1 -0
- package/dist/components/basic-nodes-kit.js +3 -0
- package/dist/components/file-upload.d.ts +15 -0
- package/dist/components/file-upload.d.ts.map +1 -0
- package/dist/components/file-upload.js +29 -0
- package/dist/components/multi-step-viewer.d.ts +23 -0
- package/dist/components/multi-step-viewer.d.ts.map +1 -0
- package/dist/components/multi-step-viewer.js +73 -0
- package/dist/components/plate-editor.d.ts +2 -0
- package/dist/components/plate-editor.d.ts.map +1 -0
- package/dist/components/plate-editor.js +44 -0
- package/dist/hooks/use-file-upload.d.ts +46 -0
- package/dist/hooks/use-file-upload.d.ts.map +1 -0
- package/dist/hooks/use-file-upload.js +228 -0
- package/dist/hooks/use-mobile.d.ts +2 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -0
- package/dist/hooks/use-mobile.js +15 -0
- package/dist/hooks/use-multi-step-viewer.d.ts +30 -0
- package/dist/hooks/use-multi-step-viewer.d.ts.map +1 -0
- package/dist/hooks/use-multi-step-viewer.js +72 -0
- package/dist/index.css +3645 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +5 -0
- package/dist/primitives/accordion.d.ts +8 -0
- package/dist/primitives/accordion.d.ts.map +1 -0
- package/dist/primitives/accordion.js +17 -0
- package/dist/primitives/alert-dialog.d.ts +15 -0
- package/dist/primitives/alert-dialog.d.ts.map +1 -0
- package/dist/primitives/alert-dialog.js +38 -0
- package/dist/primitives/avatar.d.ts +7 -0
- package/dist/primitives/avatar.d.ts.map +1 -0
- package/dist/primitives/avatar.js +13 -0
- package/dist/primitives/badge.d.ts +10 -0
- package/dist/primitives/badge.d.ts.map +1 -0
- package/dist/primitives/badge.js +22 -0
- package/dist/primitives/blockquote-node-static.d.ts +3 -0
- package/dist/primitives/blockquote-node-static.d.ts.map +1 -0
- package/dist/primitives/blockquote-node-static.js +5 -0
- package/dist/primitives/blockquote-node.d.ts +3 -0
- package/dist/primitives/blockquote-node.d.ts.map +1 -0
- package/dist/primitives/blockquote-node.js +5 -0
- package/dist/primitives/breadcrumb.d.ts +14 -0
- package/dist/primitives/breadcrumb.d.ts.map +1 -0
- package/dist/primitives/breadcrumb.js +29 -0
- package/dist/primitives/button.d.ts +11 -0
- package/dist/primitives/button.d.ts.map +1 -0
- package/dist/primitives/button.js +33 -0
- package/dist/primitives/calendar.d.ts +9 -0
- package/dist/primitives/calendar.d.ts.map +1 -0
- package/dist/primitives/calendar.js +73 -0
- package/dist/primitives/card.d.ts +10 -0
- package/dist/primitives/card.d.ts.map +1 -0
- package/dist/primitives/card.js +24 -0
- package/dist/primitives/chart.d.ts +42 -0
- package/dist/primitives/chart.d.ts.map +1 -0
- package/dist/primitives/chart.js +132 -0
- package/dist/primitives/checkbox.d.ts +5 -0
- package/dist/primitives/checkbox.d.ts.map +1 -0
- package/dist/primitives/checkbox.js +8 -0
- package/dist/primitives/code-node-static.d.ts +3 -0
- package/dist/primitives/code-node-static.d.ts.map +1 -0
- package/dist/primitives/code-node-static.js +5 -0
- package/dist/primitives/code-node.d.ts +3 -0
- package/dist/primitives/code-node.d.ts.map +1 -0
- package/dist/primitives/code-node.js +5 -0
- package/dist/primitives/command.d.ts +19 -0
- package/dist/primitives/command.d.ts.map +1 -0
- package/dist/primitives/command.js +33 -0
- package/dist/primitives/datepicker.d.ts +8 -0
- package/dist/primitives/datepicker.d.ts.map +1 -0
- package/dist/primitives/datepicker.js +42 -0
- package/dist/primitives/datepicker2.d.ts +8 -0
- package/dist/primitives/datepicker2.d.ts.map +1 -0
- package/dist/primitives/datepicker2.js +13 -0
- package/dist/primitives/dialog.d.ts +16 -0
- package/dist/primitives/dialog.d.ts.map +1 -0
- package/dist/primitives/dialog.js +35 -0
- package/dist/primitives/drawer.d.ts +14 -0
- package/dist/primitives/drawer.d.ts.map +1 -0
- package/dist/primitives/drawer.js +34 -0
- package/dist/primitives/dropdown-menu.d.ts +26 -0
- package/dist/primitives/dropdown-menu.d.ts.map +1 -0
- package/dist/primitives/dropdown-menu.js +50 -0
- package/dist/primitives/dropzone.d.ts +12 -0
- package/dist/primitives/dropzone.d.ts.map +1 -0
- package/dist/primitives/dropzone.js +7 -0
- package/dist/primitives/editor-static.d.ts +9 -0
- package/dist/primitives/editor-static.d.ts.map +1 -0
- package/dist/primitives/editor-static.js +29 -0
- package/dist/primitives/editor.d.ts +29 -0
- package/dist/primitives/editor.d.ts.map +1 -0
- package/dist/primitives/editor.js +56 -0
- package/dist/primitives/field.d.ts +27 -0
- package/dist/primitives/field.d.ts.map +1 -0
- package/dist/primitives/field.js +77 -0
- package/dist/primitives/fixed-toolbar.d.ts +3 -0
- package/dist/primitives/fixed-toolbar.d.ts.map +1 -0
- package/dist/primitives/fixed-toolbar.js +6 -0
- package/dist/primitives/form.d.ts +24 -0
- package/dist/primitives/form.d.ts.map +1 -0
- package/dist/primitives/form.js +58 -0
- package/dist/primitives/heading-node-static.d.ts +15 -0
- package/dist/primitives/heading-node-static.d.ts.map +1 -0
- package/dist/primitives/heading-node-static.js +37 -0
- package/dist/primitives/heading-node.d.ts +15 -0
- package/dist/primitives/heading-node.d.ts.map +1 -0
- package/dist/primitives/heading-node.js +37 -0
- package/dist/primitives/highlight-node-static.d.ts +3 -0
- package/dist/primitives/highlight-node-static.d.ts.map +1 -0
- package/dist/primitives/highlight-node-static.js +5 -0
- package/dist/primitives/highlight-node.d.ts +3 -0
- package/dist/primitives/highlight-node.d.ts.map +1 -0
- package/dist/primitives/highlight-node.js +5 -0
- package/dist/primitives/hr-node-static.d.ts +3 -0
- package/dist/primitives/hr-node-static.d.ts.map +1 -0
- package/dist/primitives/hr-node-static.js +6 -0
- package/dist/primitives/hr-node.d.ts +3 -0
- package/dist/primitives/hr-node.d.ts.map +1 -0
- package/dist/primitives/hr-node.js +9 -0
- package/dist/primitives/input.d.ts +4 -0
- package/dist/primitives/input.d.ts.map +1 -0
- package/dist/primitives/input.js +6 -0
- package/dist/primitives/kbd-node-static.d.ts +3 -0
- package/dist/primitives/kbd-node-static.d.ts.map +1 -0
- package/dist/primitives/kbd-node-static.js +5 -0
- package/dist/primitives/kbd-node.d.ts +3 -0
- package/dist/primitives/kbd-node.d.ts.map +1 -0
- package/dist/primitives/kbd-node.js +5 -0
- package/dist/primitives/kbd.d.ts +4 -0
- package/dist/primitives/kbd.d.ts.map +1 -0
- package/dist/primitives/kbd.js +9 -0
- package/dist/primitives/label.d.ts +5 -0
- package/dist/primitives/label.d.ts.map +1 -0
- package/dist/primitives/label.js +7 -0
- package/dist/primitives/mark-toolbar-button.d.ts +7 -0
- package/dist/primitives/mark-toolbar-button.d.ts.map +1 -0
- package/dist/primitives/mark-toolbar-button.js +8 -0
- package/dist/primitives/pagination.d.ts +14 -0
- package/dist/primitives/pagination.d.ts.map +1 -0
- package/dist/primitives/pagination.js +29 -0
- package/dist/primitives/paragraph-node-static.d.ts +3 -0
- package/dist/primitives/paragraph-node-static.d.ts.map +1 -0
- package/dist/primitives/paragraph-node-static.js +6 -0
- package/dist/primitives/paragraph-node.d.ts +3 -0
- package/dist/primitives/paragraph-node.d.ts.map +1 -0
- package/dist/primitives/paragraph-node.js +6 -0
- package/dist/primitives/popover.d.ts +8 -0
- package/dist/primitives/popover.d.ts.map +1 -0
- package/dist/primitives/popover.js +16 -0
- package/dist/primitives/progress.d.ts +5 -0
- package/dist/primitives/progress.d.ts.map +1 -0
- package/dist/primitives/progress.js +7 -0
- package/dist/primitives/radio-group.d.ts +6 -0
- package/dist/primitives/radio-group.d.ts.map +1 -0
- package/dist/primitives/radio-group.js +11 -0
- package/dist/primitives/scroll-area.d.ts +6 -0
- package/dist/primitives/scroll-area.d.ts.map +1 -0
- package/dist/primitives/scroll-area.js +12 -0
- package/dist/primitives/select.d.ts +16 -0
- package/dist/primitives/select.d.ts.map +1 -0
- package/dist/primitives/select.js +37 -0
- package/dist/primitives/separator.d.ts +5 -0
- package/dist/primitives/separator.d.ts.map +1 -0
- package/dist/primitives/separator.js +7 -0
- package/dist/primitives/sheet.d.ts +14 -0
- package/dist/primitives/sheet.d.ts.map +1 -0
- package/dist/primitives/sheet.js +39 -0
- package/dist/primitives/sidebar.d.ts +71 -0
- package/dist/primitives/sidebar.d.ts.map +1 -0
- package/dist/primitives/sidebar.js +212 -0
- package/dist/primitives/skeleton.d.ts +3 -0
- package/dist/primitives/skeleton.d.ts.map +1 -0
- package/dist/primitives/skeleton.js +6 -0
- package/dist/primitives/sonner.d.ts +4 -0
- package/dist/primitives/sonner.d.ts.map +1 -0
- package/dist/primitives/sonner.js +20 -0
- package/dist/primitives/spinner.d.ts +3 -0
- package/dist/primitives/spinner.d.ts.map +1 -0
- package/dist/primitives/spinner.js +7 -0
- package/dist/primitives/table.d.ts +11 -0
- package/dist/primitives/table.d.ts.map +1 -0
- package/dist/primitives/table.js +27 -0
- package/dist/primitives/tabs.d.ts +8 -0
- package/dist/primitives/tabs.d.ts.map +1 -0
- package/dist/primitives/tabs.js +16 -0
- package/dist/primitives/textarea.d.ts +4 -0
- package/dist/primitives/textarea.d.ts.map +1 -0
- package/dist/primitives/textarea.js +6 -0
- package/dist/primitives/toggle-group.d.ts +10 -0
- package/dist/primitives/toggle-group.d.ts.map +1 -0
- package/dist/primitives/toggle-group.js +21 -0
- package/dist/primitives/toggle.d.ts +10 -0
- package/dist/primitives/toggle.d.ts.map +1 -0
- package/dist/primitives/toggle.js +25 -0
- package/dist/primitives/toolbar.d.ts +43 -0
- package/dist/primitives/toolbar.d.ts.map +1 -0
- package/dist/primitives/toolbar.js +110 -0
- package/dist/primitives/tooltip.d.ts +8 -0
- package/dist/primitives/tooltip.d.ts.map +1 -0
- package/dist/primitives/tooltip.js +16 -0
- package/package.json +88 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { useCallback, useRef, useState, } from "react";
|
|
2
|
+
export const useFileUpload = (options = {}) => {
|
|
3
|
+
const { maxFiles = Infinity, accept = "*", multiple = false, initialFiles = [], onFilesChange, onFilesAdded, } = options;
|
|
4
|
+
const [state, setState] = useState({
|
|
5
|
+
files: initialFiles.map((file) => ({
|
|
6
|
+
file,
|
|
7
|
+
id: file.id,
|
|
8
|
+
preview: file.url,
|
|
9
|
+
})),
|
|
10
|
+
isDragging: false,
|
|
11
|
+
errors: [],
|
|
12
|
+
});
|
|
13
|
+
const inputRef = useRef(null);
|
|
14
|
+
const createPreview = useCallback((file) => {
|
|
15
|
+
if (file instanceof File) {
|
|
16
|
+
return URL.createObjectURL(file);
|
|
17
|
+
}
|
|
18
|
+
return file.url;
|
|
19
|
+
}, []);
|
|
20
|
+
const generateUniqueId = useCallback((file) => {
|
|
21
|
+
if (file instanceof File) {
|
|
22
|
+
return `${file.name}-${crypto.randomUUID()}`;
|
|
23
|
+
}
|
|
24
|
+
return file.id;
|
|
25
|
+
}, []);
|
|
26
|
+
const clearFiles = useCallback(() => {
|
|
27
|
+
setState((prev) => {
|
|
28
|
+
// Clean up object URLs
|
|
29
|
+
prev.files.forEach((file) => {
|
|
30
|
+
if (file.preview &&
|
|
31
|
+
file.file instanceof File &&
|
|
32
|
+
file.file.type.startsWith("image/")) {
|
|
33
|
+
URL.revokeObjectURL(file.preview);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
if (inputRef.current) {
|
|
37
|
+
inputRef.current.value = "";
|
|
38
|
+
}
|
|
39
|
+
const newState = {
|
|
40
|
+
...prev,
|
|
41
|
+
files: [],
|
|
42
|
+
errors: [],
|
|
43
|
+
};
|
|
44
|
+
onFilesChange?.(newState.files);
|
|
45
|
+
return newState;
|
|
46
|
+
});
|
|
47
|
+
}, [onFilesChange]);
|
|
48
|
+
const addFiles = useCallback((newFiles) => {
|
|
49
|
+
if (!newFiles || newFiles.length === 0)
|
|
50
|
+
return;
|
|
51
|
+
const newFilesArray = Array.from(newFiles);
|
|
52
|
+
const errors = [];
|
|
53
|
+
// Clear existing errors when new files are uploaded
|
|
54
|
+
setState((prev) => ({ ...prev, errors: [] }));
|
|
55
|
+
// In single file mode, clear existing files first
|
|
56
|
+
if (!multiple) {
|
|
57
|
+
clearFiles();
|
|
58
|
+
}
|
|
59
|
+
// Check if adding these files would exceed maxFiles (only in multiple mode)
|
|
60
|
+
if (multiple &&
|
|
61
|
+
maxFiles !== Infinity &&
|
|
62
|
+
state.files.length + newFilesArray.length > maxFiles) {
|
|
63
|
+
errors.push(`You can only upload a maximum of ${maxFiles} files.`);
|
|
64
|
+
setState((prev) => ({ ...prev, errors }));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const validFiles = [];
|
|
68
|
+
newFilesArray.forEach((file) => {
|
|
69
|
+
// Only check for duplicates if multiple files are allowed
|
|
70
|
+
if (multiple) {
|
|
71
|
+
const isDuplicate = state.files.some((existingFile) => existingFile.file.name === file.name &&
|
|
72
|
+
existingFile.file.size === file.size);
|
|
73
|
+
// Skip duplicate files silently
|
|
74
|
+
if (isDuplicate) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
validFiles.push({
|
|
79
|
+
file,
|
|
80
|
+
id: generateUniqueId(file),
|
|
81
|
+
preview: createPreview(file),
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
// Only update state if we have valid files to add
|
|
85
|
+
if (validFiles.length > 0) {
|
|
86
|
+
// Call the onFilesAdded callback with the newly added valid files
|
|
87
|
+
onFilesAdded?.(validFiles);
|
|
88
|
+
setState((prev) => {
|
|
89
|
+
const newFiles = !multiple
|
|
90
|
+
? validFiles
|
|
91
|
+
: [...prev.files, ...validFiles];
|
|
92
|
+
onFilesChange?.(newFiles);
|
|
93
|
+
return {
|
|
94
|
+
...prev,
|
|
95
|
+
files: newFiles,
|
|
96
|
+
errors,
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
else if (errors.length > 0) {
|
|
101
|
+
setState((prev) => ({
|
|
102
|
+
...prev,
|
|
103
|
+
errors,
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
// Reset input value after handling files
|
|
107
|
+
if (inputRef.current) {
|
|
108
|
+
inputRef.current.value = "";
|
|
109
|
+
}
|
|
110
|
+
}, [
|
|
111
|
+
state.files,
|
|
112
|
+
maxFiles,
|
|
113
|
+
multiple,
|
|
114
|
+
// validateFile,
|
|
115
|
+
createPreview,
|
|
116
|
+
generateUniqueId,
|
|
117
|
+
clearFiles,
|
|
118
|
+
onFilesChange,
|
|
119
|
+
onFilesAdded,
|
|
120
|
+
]);
|
|
121
|
+
const removeFile = useCallback((id) => {
|
|
122
|
+
setState((prev) => {
|
|
123
|
+
const fileToRemove = prev.files.find((file) => file.id === id);
|
|
124
|
+
if (fileToRemove?.preview &&
|
|
125
|
+
fileToRemove.file instanceof File &&
|
|
126
|
+
fileToRemove.file.type.startsWith("image/")) {
|
|
127
|
+
URL.revokeObjectURL(fileToRemove.preview);
|
|
128
|
+
}
|
|
129
|
+
const newFiles = prev.files.filter((file) => file.id !== id);
|
|
130
|
+
onFilesChange?.(newFiles);
|
|
131
|
+
return {
|
|
132
|
+
...prev,
|
|
133
|
+
files: newFiles,
|
|
134
|
+
errors: [],
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
}, [onFilesChange]);
|
|
138
|
+
const clearErrors = useCallback(() => {
|
|
139
|
+
setState((prev) => ({
|
|
140
|
+
...prev,
|
|
141
|
+
errors: [],
|
|
142
|
+
}));
|
|
143
|
+
}, []);
|
|
144
|
+
const handleDragEnter = useCallback((e) => {
|
|
145
|
+
e.preventDefault();
|
|
146
|
+
e.stopPropagation();
|
|
147
|
+
setState((prev) => ({ ...prev, isDragging: true }));
|
|
148
|
+
}, []);
|
|
149
|
+
const handleDragLeave = useCallback((e) => {
|
|
150
|
+
e.preventDefault();
|
|
151
|
+
e.stopPropagation();
|
|
152
|
+
if (e.currentTarget.contains(e.relatedTarget)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
setState((prev) => ({ ...prev, isDragging: false }));
|
|
156
|
+
}, []);
|
|
157
|
+
const handleDragOver = useCallback((e) => {
|
|
158
|
+
e.preventDefault();
|
|
159
|
+
e.stopPropagation();
|
|
160
|
+
}, []);
|
|
161
|
+
const handleDrop = useCallback((e) => {
|
|
162
|
+
e.preventDefault();
|
|
163
|
+
e.stopPropagation();
|
|
164
|
+
setState((prev) => ({ ...prev, isDragging: false }));
|
|
165
|
+
// Don't process files if the input is disabled
|
|
166
|
+
if (inputRef.current?.disabled) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
|
170
|
+
// In single file mode, only use the first file
|
|
171
|
+
if (!multiple) {
|
|
172
|
+
const file = e.dataTransfer.files[0];
|
|
173
|
+
if (file) {
|
|
174
|
+
addFiles([file]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
addFiles(e.dataTransfer.files);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}, [addFiles, multiple]);
|
|
182
|
+
const handleFileChange = useCallback((e) => {
|
|
183
|
+
if (e.target.files && e.target.files.length > 0) {
|
|
184
|
+
addFiles(e.target.files);
|
|
185
|
+
}
|
|
186
|
+
}, [addFiles]);
|
|
187
|
+
const openFileDialog = useCallback(() => {
|
|
188
|
+
if (inputRef.current) {
|
|
189
|
+
inputRef.current.click();
|
|
190
|
+
}
|
|
191
|
+
}, []);
|
|
192
|
+
const getInputProps = useCallback((props = {}) => {
|
|
193
|
+
return {
|
|
194
|
+
...props,
|
|
195
|
+
type: "file",
|
|
196
|
+
onChange: handleFileChange,
|
|
197
|
+
accept: props.accept || accept,
|
|
198
|
+
multiple: props.multiple !== undefined ? props.multiple : multiple,
|
|
199
|
+
ref: inputRef,
|
|
200
|
+
};
|
|
201
|
+
}, [accept, multiple, handleFileChange]);
|
|
202
|
+
return [
|
|
203
|
+
state,
|
|
204
|
+
{
|
|
205
|
+
addFiles,
|
|
206
|
+
removeFile,
|
|
207
|
+
clearFiles,
|
|
208
|
+
clearErrors,
|
|
209
|
+
handleDragEnter,
|
|
210
|
+
handleDragLeave,
|
|
211
|
+
handleDragOver,
|
|
212
|
+
handleDrop,
|
|
213
|
+
handleFileChange,
|
|
214
|
+
openFileDialog,
|
|
215
|
+
getInputProps,
|
|
216
|
+
},
|
|
217
|
+
];
|
|
218
|
+
};
|
|
219
|
+
export const formatBytes = (bytes, decimals = 2) => {
|
|
220
|
+
if (bytes === 0)
|
|
221
|
+
return "0 Bytes";
|
|
222
|
+
const k = 1024;
|
|
223
|
+
const dm = decimals < 0 ? 0 : decimals;
|
|
224
|
+
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
225
|
+
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), sizes.length - 1);
|
|
226
|
+
const value = Number.parseFloat((bytes / k ** i).toFixed(dm));
|
|
227
|
+
return `${value} ${sizes[i]}`;
|
|
228
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mobile.d.ts","sourceRoot":"","sources":["../../src/hooks/use-mobile.ts"],"names":[],"mappings":"AAIA,wBAAgB,WAAW,YAgB1B"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
const MOBILE_BREAKPOINT = 768;
|
|
3
|
+
export function useIsMobile() {
|
|
4
|
+
const [isMobile, setIsMobile] = React.useState(undefined);
|
|
5
|
+
React.useEffect(() => {
|
|
6
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
7
|
+
const onChange = () => {
|
|
8
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
9
|
+
};
|
|
10
|
+
mql.addEventListener("change", onChange);
|
|
11
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
12
|
+
return () => mql.removeEventListener("change", onChange);
|
|
13
|
+
}, []);
|
|
14
|
+
return !!isMobile;
|
|
15
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { LucideIcon } from "lucide-react";
|
|
2
|
+
import type { JSX, ReactNode } from "react";
|
|
3
|
+
export interface Stepfields {
|
|
4
|
+
fields: string[];
|
|
5
|
+
component: JSX.Element;
|
|
6
|
+
title?: string;
|
|
7
|
+
icon?: LucideIcon;
|
|
8
|
+
}
|
|
9
|
+
export interface UseMultiFormStepsReturn {
|
|
10
|
+
steps: Stepfields[];
|
|
11
|
+
currentStepIndex: number;
|
|
12
|
+
currentStepData: Stepfields;
|
|
13
|
+
progress: number;
|
|
14
|
+
isFirstStep: boolean;
|
|
15
|
+
isLastStep: boolean;
|
|
16
|
+
goToNext: () => Promise<boolean>;
|
|
17
|
+
goToPrevious: () => void;
|
|
18
|
+
goToFirstStep: () => void;
|
|
19
|
+
goToStep: (stepNumber: number) => void;
|
|
20
|
+
setSteps: (newSteps: Stepfields[]) => void;
|
|
21
|
+
}
|
|
22
|
+
interface MultiStepFormProviderProps {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
stepsFields: Stepfields[];
|
|
25
|
+
onStepValidation?: (step: Stepfields) => Promise<boolean> | boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function MultiStepFormProvider({ children, stepsFields, onStepValidation, }: MultiStepFormProviderProps): JSX.Element;
|
|
28
|
+
export declare function useMultiStepForm(): UseMultiFormStepsReturn;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=use-multi-step-viewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-multi-step-viewer.d.ts","sourceRoot":"","sources":["../../src/hooks/use-multi-step-viewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG5C,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,UAAU,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;CAC5C;AAWD,UAAU,0BAA0B;IAClC,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACrE;AAGD,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,WAAW,EACX,gBAAgB,GACjB,EAAE,0BAA0B,eAsE5B;AAGD,wBAAgB,gBAAgB,IAAI,uBAAuB,CAU1D"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useState } from "react";
|
|
3
|
+
// Create context
|
|
4
|
+
const MultiStepFormContext = createContext(null);
|
|
5
|
+
// Provider component
|
|
6
|
+
export function MultiStepFormProvider({ children, stepsFields, onStepValidation, }) {
|
|
7
|
+
const [steps, setStepsState] = useState(stepsFields);
|
|
8
|
+
const [currentStepIndex, setCurrentStepIndex] = useState(1);
|
|
9
|
+
const goToNext = async () => {
|
|
10
|
+
const currentStepData = steps[currentStepIndex - 1];
|
|
11
|
+
if (onStepValidation) {
|
|
12
|
+
const isValid = await onStepValidation(currentStepData);
|
|
13
|
+
if (!isValid)
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
if (currentStepIndex < steps.length) {
|
|
17
|
+
setCurrentStepIndex((prev) => prev + 1);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
};
|
|
22
|
+
const goToPrevious = () => {
|
|
23
|
+
if (currentStepIndex > 1) {
|
|
24
|
+
setCurrentStepIndex((prev) => prev - 1);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const goToFirstStep = () => {
|
|
28
|
+
setCurrentStepIndex(1);
|
|
29
|
+
};
|
|
30
|
+
const goToStep = async (stepNumber) => {
|
|
31
|
+
if (stepNumber < 1 || stepNumber > steps.length)
|
|
32
|
+
return;
|
|
33
|
+
if (stepNumber > currentStepIndex && onStepValidation) {
|
|
34
|
+
for (let i = currentStepIndex; i < stepNumber; i++) {
|
|
35
|
+
const stepData = steps[i - 1];
|
|
36
|
+
const isValid = await onStepValidation(stepData);
|
|
37
|
+
if (!isValid)
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
setCurrentStepIndex(stepNumber);
|
|
42
|
+
};
|
|
43
|
+
const setSteps = (newSteps) => {
|
|
44
|
+
setStepsState(newSteps);
|
|
45
|
+
// Reset to first step if current step is out of bounds
|
|
46
|
+
if (currentStepIndex > newSteps.length) {
|
|
47
|
+
setCurrentStepIndex(1);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const value = {
|
|
51
|
+
steps,
|
|
52
|
+
currentStepIndex: currentStepIndex,
|
|
53
|
+
currentStepData: steps[currentStepIndex - 1],
|
|
54
|
+
progress: (currentStepIndex / steps.length) * 100,
|
|
55
|
+
isFirstStep: currentStepIndex === 1,
|
|
56
|
+
isLastStep: currentStepIndex === steps.length,
|
|
57
|
+
goToNext,
|
|
58
|
+
goToPrevious,
|
|
59
|
+
goToFirstStep,
|
|
60
|
+
goToStep,
|
|
61
|
+
setSteps,
|
|
62
|
+
};
|
|
63
|
+
return (_jsx(MultiStepFormContext.Provider, { value: value, children: children }));
|
|
64
|
+
}
|
|
65
|
+
// Hook to consume context
|
|
66
|
+
export function useMultiStepForm() {
|
|
67
|
+
const context = useContext(MultiStepFormContext);
|
|
68
|
+
if (!context) {
|
|
69
|
+
throw new Error("useMultiStepForm must be used within a MultiStepFormProvider");
|
|
70
|
+
}
|
|
71
|
+
return context;
|
|
72
|
+
}
|