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.mjs CHANGED
@@ -3082,6 +3082,18 @@ var DateTimeWidget = ({ fieldId }) => {
3082
3082
  showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
3083
3083
  ] });
3084
3084
  };
3085
+ function extractImageDisplayUrl(value) {
3086
+ if (value == null) return null;
3087
+ if (typeof value === "string") {
3088
+ return /^https?:\/\//i.test(value) ? value : null;
3089
+ }
3090
+ if (typeof value === "object") {
3091
+ const o = value;
3092
+ const u = o.presigned_url || o.value;
3093
+ if (typeof u === "string" && /^https?:\/\//i.test(u)) return u;
3094
+ }
3095
+ return null;
3096
+ }
3085
3097
  var ImageUploadWidget = ({ fieldId }) => {
3086
3098
  const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
3087
3099
  const store = useFormStore();
@@ -3089,7 +3101,14 @@ var ImageUploadWidget = ({ fieldId }) => {
3089
3101
  const [isUploading, setIsUploading] = useState(false);
3090
3102
  const [preview, setPreview] = useState(null);
3091
3103
  const fileInputRef = useRef(null);
3104
+ const blobUrlRef = useRef(null);
3092
3105
  const showError = !!error && (touched || state.submitAttempted);
3106
+ const revokeTrackedBlob = () => {
3107
+ if (blobUrlRef.current) {
3108
+ URL.revokeObjectURL(blobUrlRef.current);
3109
+ blobUrlRef.current = null;
3110
+ }
3111
+ };
3093
3112
  if (!fieldDef) return null;
3094
3113
  const uploadHandler = store.getUploadHandler();
3095
3114
  if (!uploadHandler) {
@@ -3102,12 +3121,24 @@ var ImageUploadWidget = ({ fieldId }) => {
3102
3121
  ] });
3103
3122
  }
3104
3123
  React15__default.useEffect(() => {
3105
- if (value && typeof value === "string") {
3106
- setPreview(value);
3107
- } else {
3124
+ const displayUrl = extractImageDisplayUrl(value);
3125
+ if (displayUrl) {
3126
+ revokeTrackedBlob();
3127
+ setPreview(displayUrl);
3128
+ return;
3129
+ }
3130
+ if (value === null || value === void 0 || value === "") {
3131
+ revokeTrackedBlob();
3108
3132
  setPreview(null);
3133
+ return;
3109
3134
  }
3110
3135
  }, [value]);
3136
+ React15__default.useEffect(
3137
+ () => () => {
3138
+ revokeTrackedBlob();
3139
+ },
3140
+ []
3141
+ );
3111
3142
  const handleFileSelect = async (event) => {
3112
3143
  const file = event.target.files?.[0];
3113
3144
  if (!file) return;
@@ -3123,15 +3154,18 @@ var ImageUploadWidget = ({ fieldId }) => {
3123
3154
  setIsUploading(true);
3124
3155
  setTouched();
3125
3156
  store.incrementPendingUploads();
3157
+ revokeTrackedBlob();
3158
+ const previewUrl = URL.createObjectURL(file);
3159
+ blobUrlRef.current = previewUrl;
3160
+ setPreview(previewUrl);
3126
3161
  try {
3127
- const previewUrl = URL.createObjectURL(file);
3128
- setPreview(previewUrl);
3129
3162
  const s3Key = await uploadHandler(file, file.name);
3130
3163
  setValue(s3Key);
3131
3164
  } catch (error2) {
3132
3165
  console.error("Upload failed:", error2);
3133
3166
  const errorMessage = error2 instanceof Error ? error2.message : "Upload failed. Please try again.";
3134
3167
  alert(errorMessage);
3168
+ revokeTrackedBlob();
3135
3169
  setPreview(null);
3136
3170
  } finally {
3137
3171
  setIsUploading(false);
@@ -3139,6 +3173,7 @@ var ImageUploadWidget = ({ fieldId }) => {
3139
3173
  }
3140
3174
  };
3141
3175
  const handleRemove = () => {
3176
+ revokeTrackedBlob();
3142
3177
  setValue(null);
3143
3178
  setPreview(null);
3144
3179
  if (fileInputRef.current) {
@@ -3216,6 +3251,18 @@ function isAcceptedMediaFile(file) {
3216
3251
  if (file.name.toLowerCase().endsWith(".pdf")) return true;
3217
3252
  return false;
3218
3253
  }
3254
+ function extractMediaDisplayUrl(value) {
3255
+ if (value == null) return null;
3256
+ if (typeof value === "string") {
3257
+ return /^https?:\/\//i.test(value) ? value : null;
3258
+ }
3259
+ if (typeof value === "object") {
3260
+ const o = value;
3261
+ const u = o.presigned_url || o.value;
3262
+ if (typeof u === "string" && /^https?:\/\//i.test(u)) return u;
3263
+ }
3264
+ return null;
3265
+ }
3219
3266
  var MediaUploadWidget = ({ fieldId }) => {
3220
3267
  const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
3221
3268
  const store = useFormStore();
@@ -3225,7 +3272,14 @@ var MediaUploadWidget = ({ fieldId }) => {
3225
3272
  const [previewIsPdf, setPreviewIsPdf] = useState(false);
3226
3273
  const fileInputRef = useRef(null);
3227
3274
  const pendingPreviewKindRef = useRef(null);
3275
+ const blobUrlRef = useRef(null);
3228
3276
  const showError = !!error && (touched || state.submitAttempted);
3277
+ const revokeTrackedBlob = () => {
3278
+ if (blobUrlRef.current) {
3279
+ URL.revokeObjectURL(blobUrlRef.current);
3280
+ blobUrlRef.current = null;
3281
+ }
3282
+ };
3229
3283
  if (!fieldDef) return null;
3230
3284
  const uploadHandler = store.getUploadHandler();
3231
3285
  if (!uploadHandler) {
@@ -3238,19 +3292,32 @@ var MediaUploadWidget = ({ fieldId }) => {
3238
3292
  ] });
3239
3293
  }
3240
3294
  React15__default.useEffect(() => {
3241
- if (value && typeof value === "string") {
3242
- setPreview(value);
3295
+ const displayUrl = extractMediaDisplayUrl(value);
3296
+ if (displayUrl) {
3297
+ revokeTrackedBlob();
3298
+ setPreview(displayUrl);
3243
3299
  if (pendingPreviewKindRef.current) {
3244
3300
  setPreviewIsPdf(pendingPreviewKindRef.current === "pdf");
3245
3301
  pendingPreviewKindRef.current = null;
3246
3302
  } else {
3247
- setPreviewIsPdf(urlLooksLikePdf(value));
3303
+ setPreviewIsPdf(urlLooksLikePdf(displayUrl));
3248
3304
  }
3249
- } else {
3305
+ return;
3306
+ }
3307
+ if (value === null || value === void 0 || value === "") {
3308
+ revokeTrackedBlob();
3309
+ pendingPreviewKindRef.current = null;
3250
3310
  setPreview(null);
3251
3311
  setPreviewIsPdf(false);
3312
+ return;
3252
3313
  }
3253
3314
  }, [value]);
3315
+ React15__default.useEffect(
3316
+ () => () => {
3317
+ revokeTrackedBlob();
3318
+ },
3319
+ []
3320
+ );
3254
3321
  const handleFileSelect = async (event) => {
3255
3322
  const file = event.target.files?.[0];
3256
3323
  if (!file) return;
@@ -3267,10 +3334,12 @@ var MediaUploadWidget = ({ fieldId }) => {
3267
3334
  setIsUploading(true);
3268
3335
  setTouched();
3269
3336
  store.incrementPendingUploads();
3337
+ revokeTrackedBlob();
3338
+ const previewUrl = URL.createObjectURL(file);
3339
+ blobUrlRef.current = previewUrl;
3340
+ setPreview(previewUrl);
3341
+ setPreviewIsPdf(isPdf);
3270
3342
  try {
3271
- const previewUrl = URL.createObjectURL(file);
3272
- setPreview(previewUrl);
3273
- setPreviewIsPdf(isPdf);
3274
3343
  const s3Key = await uploadHandler(file, file.name);
3275
3344
  pendingPreviewKindRef.current = isPdf ? "pdf" : "image";
3276
3345
  setValue(s3Key);
@@ -3278,6 +3347,8 @@ var MediaUploadWidget = ({ fieldId }) => {
3278
3347
  console.error("Upload failed:", error2);
3279
3348
  const errorMessage = error2 instanceof Error ? error2.message : "Upload failed. Please try again.";
3280
3349
  alert(errorMessage);
3350
+ pendingPreviewKindRef.current = null;
3351
+ revokeTrackedBlob();
3281
3352
  setPreview(null);
3282
3353
  setPreviewIsPdf(false);
3283
3354
  } finally {
@@ -3287,6 +3358,7 @@ var MediaUploadWidget = ({ fieldId }) => {
3287
3358
  };
3288
3359
  const handleRemove = () => {
3289
3360
  pendingPreviewKindRef.current = null;
3361
+ revokeTrackedBlob();
3290
3362
  setValue(null);
3291
3363
  setPreview(null);
3292
3364
  setPreviewIsPdf(false);