@uploadista/react 0.0.20-beta.2 → 0.0.20-beta.3
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/index.d.mts +3 -3
- package/dist/components/index.mjs +1 -1
- package/dist/flow-upload-list-SbpCaxRq.mjs +2 -0
- package/dist/flow-upload-list-SbpCaxRq.mjs.map +1 -0
- package/dist/hooks/index.d.mts +3 -3
- package/dist/hooks/index.mjs +1 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +1 -1
- package/dist/{uploadista-provider-D-N-eL2l.d.mts → uploadista-provider-C1l0iBc9.d.mts} +512 -318
- package/dist/uploadista-provider-C1l0iBc9.d.mts.map +1 -0
- package/dist/use-upload-BvvGROMR.mjs +2 -0
- package/dist/use-upload-BvvGROMR.mjs.map +1 -0
- package/dist/{use-uploadista-client-m9nF-irM.d.mts → use-uploadista-client-DHbLSpIb.d.mts} +120 -286
- package/dist/use-uploadista-client-DHbLSpIb.d.mts.map +1 -0
- package/dist/use-uploadista-events-BwUD-2Ck.mjs +2 -0
- package/dist/use-uploadista-events-BwUD-2Ck.mjs.map +1 -0
- package/dist/{use-upload-metrics-DhzS4lhG.d.mts → use-uploadista-events-CtDXJYrR.d.mts} +169 -371
- package/dist/use-uploadista-events-CtDXJYrR.d.mts.map +1 -0
- package/package.json +6 -6
- package/src/components/flow-primitives.tsx +839 -0
- package/src/components/index.tsx +31 -13
- package/src/hooks/index.ts +25 -37
- package/src/index.ts +90 -81
- package/dist/upload-zone-BjWHuP7p.mjs +0 -6
- package/dist/upload-zone-BjWHuP7p.mjs.map +0 -1
- package/dist/uploadista-provider-D-N-eL2l.d.mts.map +0 -1
- package/dist/use-upload-BDHVhQsI.mjs +0 -2
- package/dist/use-upload-BDHVhQsI.mjs.map +0 -1
- package/dist/use-upload-metrics-Df90wIos.mjs +0 -2
- package/dist/use-upload-metrics-Df90wIos.mjs.map +0 -1
- package/dist/use-upload-metrics-DhzS4lhG.d.mts.map +0 -1
- package/dist/use-uploadista-client-m9nF-irM.d.mts.map +0 -1
- package/src/components/flow-input.tsx +0 -299
- package/src/components/flow-upload-zone.tsx +0 -441
- package/src/hooks/use-flow-execution.ts +0 -502
- package/src/hooks/use-flow-upload.ts +0 -299
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
/** biome-ignore-all lint/a11y/useSemanticElements: button is inside a div*/
|
|
2
|
-
"use client";
|
|
3
|
-
|
|
4
|
-
import { useDragDrop } from "../hooks/use-drag-drop";
|
|
5
|
-
import type { FlowInputMetadata } from "../hooks/use-flow";
|
|
6
|
-
|
|
7
|
-
export interface FlowInputProps {
|
|
8
|
-
/** Input metadata from flow discovery */
|
|
9
|
-
input: FlowInputMetadata;
|
|
10
|
-
/** Accepted file types (e.g., "image/*", "video/*") */
|
|
11
|
-
accept?: string;
|
|
12
|
-
/** Whether the input should support URL input */
|
|
13
|
-
allowUrl?: boolean;
|
|
14
|
-
/** Current value (File or URL string) */
|
|
15
|
-
value?: File | string | null;
|
|
16
|
-
/** Callback when value changes */
|
|
17
|
-
onChange: (value: File | string) => void;
|
|
18
|
-
/** Whether the input is disabled */
|
|
19
|
-
disabled?: boolean;
|
|
20
|
-
/** Additional CSS classes */
|
|
21
|
-
className?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Input component for flow execution with file drag-and-drop and URL support.
|
|
26
|
-
*
|
|
27
|
-
* Features:
|
|
28
|
-
* - File drag-and-drop with visual feedback
|
|
29
|
-
* - URL input for remote files
|
|
30
|
-
* - Displays node name and description
|
|
31
|
-
* - Shows selected file/URL with size
|
|
32
|
-
* - Type validation and error display
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```tsx
|
|
36
|
-
* <FlowInput
|
|
37
|
-
* input={inputMetadata}
|
|
38
|
-
* accept="image/*"
|
|
39
|
-
* allowUrl={true}
|
|
40
|
-
* value={selectedValue}
|
|
41
|
-
* onChange={(value) => flow.setInput(inputMetadata.nodeId, value)}
|
|
42
|
-
* />
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export function FlowInput({
|
|
46
|
-
input,
|
|
47
|
-
accept = "*",
|
|
48
|
-
allowUrl = true,
|
|
49
|
-
value,
|
|
50
|
-
onChange,
|
|
51
|
-
disabled = false,
|
|
52
|
-
className = "",
|
|
53
|
-
}: FlowInputProps) {
|
|
54
|
-
const isFileValue = value instanceof File;
|
|
55
|
-
const isUrlValue = typeof value === "string" && value.length > 0;
|
|
56
|
-
|
|
57
|
-
// Determine input mode based on input type
|
|
58
|
-
const supportsFileUpload = input.inputTypeId === "streaming-input-v1";
|
|
59
|
-
const supportsUrl =
|
|
60
|
-
allowUrl &&
|
|
61
|
-
(input.inputTypeId === "url-input-v1" ||
|
|
62
|
-
input.inputTypeId === "streaming-input-v1");
|
|
63
|
-
|
|
64
|
-
const dragDrop = useDragDrop({
|
|
65
|
-
onFilesReceived: (files) => {
|
|
66
|
-
if (files[0]) {
|
|
67
|
-
onChange(files[0]);
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
accept: accept ? accept.split(",").map((type) => type.trim()) : undefined,
|
|
71
|
-
multiple: false,
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
75
|
-
const file = e.target.files?.[0];
|
|
76
|
-
if (file) {
|
|
77
|
-
onChange(file);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const handleUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
82
|
-
onChange(e.target.value);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const handleClear = () => {
|
|
86
|
-
onChange("");
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
<div className={`space-y-3 ${className}`}>
|
|
91
|
-
{/* Header */}
|
|
92
|
-
<div>
|
|
93
|
-
<div className="flex items-center gap-2 mb-1">
|
|
94
|
-
<h4 className="font-semibold text-gray-900">{input.nodeName}</h4>
|
|
95
|
-
{input.required && <span className="text-red-500 text-sm">*</span>}
|
|
96
|
-
<span className="text-xs px-2 py-1 rounded-full bg-blue-100 text-blue-700 font-medium">
|
|
97
|
-
{input.inputTypeId}
|
|
98
|
-
</span>
|
|
99
|
-
</div>
|
|
100
|
-
{input.nodeDescription && (
|
|
101
|
-
<p className="text-sm text-gray-600">{input.nodeDescription}</p>
|
|
102
|
-
)}
|
|
103
|
-
</div>
|
|
104
|
-
|
|
105
|
-
{/* File Upload Area */}
|
|
106
|
-
{supportsFileUpload && (
|
|
107
|
-
<div
|
|
108
|
-
role="button"
|
|
109
|
-
tabIndex={disabled ? -1 : 0}
|
|
110
|
-
{...dragDrop.dragHandlers}
|
|
111
|
-
onClick={() => !disabled && dragDrop.openFilePicker()}
|
|
112
|
-
onKeyDown={(e) => {
|
|
113
|
-
if ((e.key === "Enter" || e.key === " ") && !disabled) {
|
|
114
|
-
e.preventDefault();
|
|
115
|
-
dragDrop.openFilePicker();
|
|
116
|
-
}
|
|
117
|
-
}}
|
|
118
|
-
className={`
|
|
119
|
-
relative border-2 border-dashed rounded-xl p-6 text-center cursor-pointer transition-all
|
|
120
|
-
${
|
|
121
|
-
dragDrop.state.isDragging
|
|
122
|
-
? "border-indigo-500 bg-indigo-50"
|
|
123
|
-
: "border-gray-300 bg-gray-50 hover:border-indigo-400 hover:bg-indigo-50/50"
|
|
124
|
-
}
|
|
125
|
-
${disabled ? "opacity-50 cursor-not-allowed" : ""}
|
|
126
|
-
`}
|
|
127
|
-
>
|
|
128
|
-
{dragDrop.state.isDragging ? (
|
|
129
|
-
<div className="flex flex-col items-center gap-2">
|
|
130
|
-
<svg
|
|
131
|
-
className="w-8 h-8 text-indigo-600"
|
|
132
|
-
fill="none"
|
|
133
|
-
viewBox="0 0 24 24"
|
|
134
|
-
stroke="currentColor"
|
|
135
|
-
>
|
|
136
|
-
<title>Drop file</title>
|
|
137
|
-
<path
|
|
138
|
-
strokeLinecap="round"
|
|
139
|
-
strokeLinejoin="round"
|
|
140
|
-
strokeWidth={2}
|
|
141
|
-
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
|
|
142
|
-
/>
|
|
143
|
-
</svg>
|
|
144
|
-
<p className="text-sm font-medium text-indigo-600">
|
|
145
|
-
Drop file here
|
|
146
|
-
</p>
|
|
147
|
-
</div>
|
|
148
|
-
) : isFileValue ? (
|
|
149
|
-
<div className="flex items-center justify-between">
|
|
150
|
-
<div className="flex items-center gap-3">
|
|
151
|
-
<svg
|
|
152
|
-
className="w-5 h-5 text-green-500"
|
|
153
|
-
fill="currentColor"
|
|
154
|
-
viewBox="0 0 20 20"
|
|
155
|
-
aria-hidden="true"
|
|
156
|
-
>
|
|
157
|
-
<path
|
|
158
|
-
fillRule="evenodd"
|
|
159
|
-
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
|
|
160
|
-
clipRule="evenodd"
|
|
161
|
-
/>
|
|
162
|
-
</svg>
|
|
163
|
-
<div className="text-left">
|
|
164
|
-
<p className="text-sm font-medium text-gray-900">
|
|
165
|
-
{value.name}
|
|
166
|
-
</p>
|
|
167
|
-
<p className="text-xs text-gray-500">
|
|
168
|
-
{(value.size / 1024).toFixed(1)} KB
|
|
169
|
-
</p>
|
|
170
|
-
</div>
|
|
171
|
-
</div>
|
|
172
|
-
<button
|
|
173
|
-
type="button"
|
|
174
|
-
onClick={(e) => {
|
|
175
|
-
e.stopPropagation();
|
|
176
|
-
handleClear();
|
|
177
|
-
}}
|
|
178
|
-
className="px-3 py-1 text-sm text-red-600 hover:text-red-700 hover:bg-red-50 rounded-lg transition-colors"
|
|
179
|
-
>
|
|
180
|
-
Remove
|
|
181
|
-
</button>
|
|
182
|
-
</div>
|
|
183
|
-
) : (
|
|
184
|
-
<div className="flex flex-col items-center gap-2">
|
|
185
|
-
<svg
|
|
186
|
-
className="w-8 h-8 text-gray-400"
|
|
187
|
-
fill="none"
|
|
188
|
-
viewBox="0 0 24 24"
|
|
189
|
-
stroke="currentColor"
|
|
190
|
-
>
|
|
191
|
-
<title>Upload file</title>
|
|
192
|
-
<path
|
|
193
|
-
strokeLinecap="round"
|
|
194
|
-
strokeLinejoin="round"
|
|
195
|
-
strokeWidth={2}
|
|
196
|
-
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
|
|
197
|
-
/>
|
|
198
|
-
</svg>
|
|
199
|
-
<div>
|
|
200
|
-
<p className="text-sm font-medium text-gray-700">
|
|
201
|
-
Drag and drop a file here, or click to select
|
|
202
|
-
</p>
|
|
203
|
-
<p className="text-xs text-gray-500 mt-1">Accepted: {accept}</p>
|
|
204
|
-
</div>
|
|
205
|
-
</div>
|
|
206
|
-
)}
|
|
207
|
-
<input {...dragDrop.inputProps} />
|
|
208
|
-
</div>
|
|
209
|
-
)}
|
|
210
|
-
|
|
211
|
-
{/* Drag & Drop Errors */}
|
|
212
|
-
{dragDrop.state.errors.length > 0 && (
|
|
213
|
-
<div className="bg-red-50 border border-red-200 rounded-lg p-3">
|
|
214
|
-
{dragDrop.state.errors.map((error, index) => (
|
|
215
|
-
<p key={index} className="text-sm text-red-700">
|
|
216
|
-
{error}
|
|
217
|
-
</p>
|
|
218
|
-
))}
|
|
219
|
-
</div>
|
|
220
|
-
)}
|
|
221
|
-
|
|
222
|
-
{/* URL Input */}
|
|
223
|
-
{supportsUrl && supportsFileUpload && (
|
|
224
|
-
<div className="flex items-center gap-3">
|
|
225
|
-
<div className="flex-1 border-t border-gray-300" />
|
|
226
|
-
<span className="text-xs font-medium text-gray-500 uppercase">
|
|
227
|
-
Or
|
|
228
|
-
</span>
|
|
229
|
-
<div className="flex-1 border-t border-gray-300" />
|
|
230
|
-
</div>
|
|
231
|
-
)}
|
|
232
|
-
|
|
233
|
-
{supportsUrl && (
|
|
234
|
-
<div className="space-y-2">
|
|
235
|
-
{!supportsFileUpload && (
|
|
236
|
-
<label
|
|
237
|
-
htmlFor={`url-${input.nodeId}`}
|
|
238
|
-
className="block text-sm font-medium text-gray-700"
|
|
239
|
-
>
|
|
240
|
-
URL
|
|
241
|
-
</label>
|
|
242
|
-
)}
|
|
243
|
-
<div className="relative">
|
|
244
|
-
<input
|
|
245
|
-
id={`url-${input.nodeId}`}
|
|
246
|
-
type="url"
|
|
247
|
-
value={isUrlValue ? value : ""}
|
|
248
|
-
onChange={handleUrlChange}
|
|
249
|
-
disabled={disabled}
|
|
250
|
-
placeholder="https://example.com/file.jpg"
|
|
251
|
-
className="block w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed text-sm"
|
|
252
|
-
/>
|
|
253
|
-
{isUrlValue && (
|
|
254
|
-
<button
|
|
255
|
-
type="button"
|
|
256
|
-
onClick={handleClear}
|
|
257
|
-
disabled={disabled}
|
|
258
|
-
className="absolute right-2 top-1/2 -translate-y-1/2 p-1 text-gray-400 hover:text-gray-600 rounded-lg hover:bg-gray-100 transition-colors"
|
|
259
|
-
aria-label="Clear URL"
|
|
260
|
-
>
|
|
261
|
-
<svg
|
|
262
|
-
className="w-4 h-4"
|
|
263
|
-
fill="none"
|
|
264
|
-
viewBox="0 0 24 24"
|
|
265
|
-
stroke="currentColor"
|
|
266
|
-
>
|
|
267
|
-
<title>Clear</title>
|
|
268
|
-
<path
|
|
269
|
-
strokeLinecap="round"
|
|
270
|
-
strokeLinejoin="round"
|
|
271
|
-
strokeWidth={2}
|
|
272
|
-
d="M6 18L18 6M6 6l12 12"
|
|
273
|
-
/>
|
|
274
|
-
</svg>
|
|
275
|
-
</button>
|
|
276
|
-
)}
|
|
277
|
-
</div>
|
|
278
|
-
{isUrlValue && (
|
|
279
|
-
<div className="flex items-center gap-2 text-xs text-gray-600">
|
|
280
|
-
<svg
|
|
281
|
-
className="w-4 h-4 text-blue-500"
|
|
282
|
-
fill="currentColor"
|
|
283
|
-
viewBox="0 0 20 20"
|
|
284
|
-
aria-hidden="true"
|
|
285
|
-
>
|
|
286
|
-
<path
|
|
287
|
-
fillRule="evenodd"
|
|
288
|
-
d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z"
|
|
289
|
-
clipRule="evenodd"
|
|
290
|
-
/>
|
|
291
|
-
</svg>
|
|
292
|
-
<span className="truncate">{value}</span>
|
|
293
|
-
</div>
|
|
294
|
-
)}
|
|
295
|
-
</div>
|
|
296
|
-
)}
|
|
297
|
-
</div>
|
|
298
|
-
);
|
|
299
|
-
}
|