formanitor 0.0.45 → 0.0.46

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/index.cjs CHANGED
@@ -3117,6 +3117,18 @@ var DateTimeWidget = ({ fieldId }) => {
3117
3117
  showError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500", children: error })
3118
3118
  ] });
3119
3119
  };
3120
+ function extractImageDisplayUrl(value) {
3121
+ if (value == null) return null;
3122
+ if (typeof value === "string") {
3123
+ return /^https?:\/\//i.test(value) ? value : null;
3124
+ }
3125
+ if (typeof value === "object") {
3126
+ const o = value;
3127
+ const u = o.presigned_url || o.value;
3128
+ if (typeof u === "string" && /^https?:\/\//i.test(u)) return u;
3129
+ }
3130
+ return null;
3131
+ }
3120
3132
  var ImageUploadWidget = ({ fieldId }) => {
3121
3133
  const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
3122
3134
  const store = useFormStore();
@@ -3124,7 +3136,14 @@ var ImageUploadWidget = ({ fieldId }) => {
3124
3136
  const [isUploading, setIsUploading] = React15.useState(false);
3125
3137
  const [preview, setPreview] = React15.useState(null);
3126
3138
  const fileInputRef = React15.useRef(null);
3139
+ const blobUrlRef = React15.useRef(null);
3127
3140
  const showError = !!error && (touched || state.submitAttempted);
3141
+ const revokeTrackedBlob = () => {
3142
+ if (blobUrlRef.current) {
3143
+ URL.revokeObjectURL(blobUrlRef.current);
3144
+ blobUrlRef.current = null;
3145
+ }
3146
+ };
3128
3147
  if (!fieldDef) return null;
3129
3148
  const uploadHandler = store.getUploadHandler();
3130
3149
  if (!uploadHandler) {
@@ -3137,12 +3156,24 @@ var ImageUploadWidget = ({ fieldId }) => {
3137
3156
  ] });
3138
3157
  }
3139
3158
  React15__namespace.default.useEffect(() => {
3140
- if (value && typeof value === "string") {
3141
- setPreview(value);
3142
- } else {
3159
+ const displayUrl = extractImageDisplayUrl(value);
3160
+ if (displayUrl) {
3161
+ revokeTrackedBlob();
3162
+ setPreview(displayUrl);
3163
+ return;
3164
+ }
3165
+ if (value === null || value === void 0 || value === "") {
3166
+ revokeTrackedBlob();
3143
3167
  setPreview(null);
3168
+ return;
3144
3169
  }
3145
3170
  }, [value]);
3171
+ React15__namespace.default.useEffect(
3172
+ () => () => {
3173
+ revokeTrackedBlob();
3174
+ },
3175
+ []
3176
+ );
3146
3177
  const handleFileSelect = async (event) => {
3147
3178
  const file = event.target.files?.[0];
3148
3179
  if (!file) return;
@@ -3158,15 +3189,18 @@ var ImageUploadWidget = ({ fieldId }) => {
3158
3189
  setIsUploading(true);
3159
3190
  setTouched();
3160
3191
  store.incrementPendingUploads();
3192
+ revokeTrackedBlob();
3193
+ const previewUrl = URL.createObjectURL(file);
3194
+ blobUrlRef.current = previewUrl;
3195
+ setPreview(previewUrl);
3161
3196
  try {
3162
- const previewUrl = URL.createObjectURL(file);
3163
- setPreview(previewUrl);
3164
3197
  const s3Key = await uploadHandler(file, file.name);
3165
3198
  setValue(s3Key);
3166
3199
  } catch (error2) {
3167
3200
  console.error("Upload failed:", error2);
3168
3201
  const errorMessage = error2 instanceof Error ? error2.message : "Upload failed. Please try again.";
3169
3202
  alert(errorMessage);
3203
+ revokeTrackedBlob();
3170
3204
  setPreview(null);
3171
3205
  } finally {
3172
3206
  setIsUploading(false);
@@ -3174,6 +3208,7 @@ var ImageUploadWidget = ({ fieldId }) => {
3174
3208
  }
3175
3209
  };
3176
3210
  const handleRemove = () => {
3211
+ revokeTrackedBlob();
3177
3212
  setValue(null);
3178
3213
  setPreview(null);
3179
3214
  if (fileInputRef.current) {
@@ -3251,6 +3286,18 @@ function isAcceptedMediaFile(file) {
3251
3286
  if (file.name.toLowerCase().endsWith(".pdf")) return true;
3252
3287
  return false;
3253
3288
  }
3289
+ function extractMediaDisplayUrl(value) {
3290
+ if (value == null) return null;
3291
+ if (typeof value === "string") {
3292
+ return /^https?:\/\//i.test(value) ? value : null;
3293
+ }
3294
+ if (typeof value === "object") {
3295
+ const o = value;
3296
+ const u = o.presigned_url || o.value;
3297
+ if (typeof u === "string" && /^https?:\/\//i.test(u)) return u;
3298
+ }
3299
+ return null;
3300
+ }
3254
3301
  var MediaUploadWidget = ({ fieldId }) => {
3255
3302
  const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
3256
3303
  const store = useFormStore();
@@ -3260,7 +3307,14 @@ var MediaUploadWidget = ({ fieldId }) => {
3260
3307
  const [previewIsPdf, setPreviewIsPdf] = React15.useState(false);
3261
3308
  const fileInputRef = React15.useRef(null);
3262
3309
  const pendingPreviewKindRef = React15.useRef(null);
3310
+ const blobUrlRef = React15.useRef(null);
3263
3311
  const showError = !!error && (touched || state.submitAttempted);
3312
+ const revokeTrackedBlob = () => {
3313
+ if (blobUrlRef.current) {
3314
+ URL.revokeObjectURL(blobUrlRef.current);
3315
+ blobUrlRef.current = null;
3316
+ }
3317
+ };
3264
3318
  if (!fieldDef) return null;
3265
3319
  const uploadHandler = store.getUploadHandler();
3266
3320
  if (!uploadHandler) {
@@ -3273,19 +3327,32 @@ var MediaUploadWidget = ({ fieldId }) => {
3273
3327
  ] });
3274
3328
  }
3275
3329
  React15__namespace.default.useEffect(() => {
3276
- if (value && typeof value === "string") {
3277
- setPreview(value);
3330
+ const displayUrl = extractMediaDisplayUrl(value);
3331
+ if (displayUrl) {
3332
+ revokeTrackedBlob();
3333
+ setPreview(displayUrl);
3278
3334
  if (pendingPreviewKindRef.current) {
3279
3335
  setPreviewIsPdf(pendingPreviewKindRef.current === "pdf");
3280
3336
  pendingPreviewKindRef.current = null;
3281
3337
  } else {
3282
- setPreviewIsPdf(urlLooksLikePdf(value));
3338
+ setPreviewIsPdf(urlLooksLikePdf(displayUrl));
3283
3339
  }
3284
- } else {
3340
+ return;
3341
+ }
3342
+ if (value === null || value === void 0 || value === "") {
3343
+ revokeTrackedBlob();
3344
+ pendingPreviewKindRef.current = null;
3285
3345
  setPreview(null);
3286
3346
  setPreviewIsPdf(false);
3347
+ return;
3287
3348
  }
3288
3349
  }, [value]);
3350
+ React15__namespace.default.useEffect(
3351
+ () => () => {
3352
+ revokeTrackedBlob();
3353
+ },
3354
+ []
3355
+ );
3289
3356
  const handleFileSelect = async (event) => {
3290
3357
  const file = event.target.files?.[0];
3291
3358
  if (!file) return;
@@ -3302,10 +3369,12 @@ var MediaUploadWidget = ({ fieldId }) => {
3302
3369
  setIsUploading(true);
3303
3370
  setTouched();
3304
3371
  store.incrementPendingUploads();
3372
+ revokeTrackedBlob();
3373
+ const previewUrl = URL.createObjectURL(file);
3374
+ blobUrlRef.current = previewUrl;
3375
+ setPreview(previewUrl);
3376
+ setPreviewIsPdf(isPdf);
3305
3377
  try {
3306
- const previewUrl = URL.createObjectURL(file);
3307
- setPreview(previewUrl);
3308
- setPreviewIsPdf(isPdf);
3309
3378
  const s3Key = await uploadHandler(file, file.name);
3310
3379
  pendingPreviewKindRef.current = isPdf ? "pdf" : "image";
3311
3380
  setValue(s3Key);
@@ -3313,6 +3382,8 @@ var MediaUploadWidget = ({ fieldId }) => {
3313
3382
  console.error("Upload failed:", error2);
3314
3383
  const errorMessage = error2 instanceof Error ? error2.message : "Upload failed. Please try again.";
3315
3384
  alert(errorMessage);
3385
+ pendingPreviewKindRef.current = null;
3386
+ revokeTrackedBlob();
3316
3387
  setPreview(null);
3317
3388
  setPreviewIsPdf(false);
3318
3389
  } finally {
@@ -3322,6 +3393,7 @@ var MediaUploadWidget = ({ fieldId }) => {
3322
3393
  };
3323
3394
  const handleRemove = () => {
3324
3395
  pendingPreviewKindRef.current = null;
3396
+ revokeTrackedBlob();
3325
3397
  setValue(null);
3326
3398
  setPreview(null);
3327
3399
  setPreviewIsPdf(false);