@stoker-platform/web-app 0.5.213 → 0.5.214

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @stoker-platform/web-app
2
2
 
3
+ ## 0.5.214
4
+
5
+ ### Patch Changes
6
+
7
+ - fix: fix Safari form image flicker
8
+
3
9
  ## 0.5.213
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stoker-platform/web-app",
3
- "version": "0.5.213",
3
+ "version": "0.5.214",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "scripts": {
@@ -14,10 +14,37 @@ import { Check, X } from "lucide-react"
14
14
  import { LoadingSpinner } from "@/components/ui/loading-spinner"
15
15
  import { Button } from "@/components/ui/button"
16
16
  import { preloadCacheEnabled } from "./preloadCacheEnabled"
17
- import { useState } from "react"
17
+ import { useEffect, useRef, useState } from "react"
18
18
  import { cn } from "@/lib/utils"
19
19
  import { getSafeUrl } from "./isSafeUrl"
20
20
 
21
+ const FormattedFieldImage = ({ src, alt, form }: { src: string; alt?: string; form?: boolean }) => {
22
+ const imgRef = useRef<HTMLImageElement | null>(null)
23
+ const [loadedSrc, setLoadedSrc] = useState<string | null>(null)
24
+ const isLoaded = loadedSrc === src
25
+
26
+ useEffect(() => {
27
+ if (imgRef.current?.complete && imgRef.current.naturalWidth > 0) {
28
+ setLoadedSrc(src)
29
+ }
30
+ }, [src])
31
+
32
+ return (
33
+ <img
34
+ ref={imgRef}
35
+ src={getSafeUrl(src)}
36
+ alt={alt || ""}
37
+ decoding="async"
38
+ onLoad={() => setLoadedSrc(src)}
39
+ className={cn(
40
+ isLoaded ? "opacity-100" : "opacity-0",
41
+ form ? "max-h-[300px]" : "max-h-[60px]",
42
+ "transition-opacity duration-200 ease-in-out max-w-full object-contain rounded",
43
+ )}
44
+ />
45
+ )
46
+ }
47
+
21
48
  export const getFormattedFieldValue = (
22
49
  customization: CollectionCustomization,
23
50
  field: CollectionField,
@@ -120,22 +147,6 @@ export const getFormattedFieldValue = (
120
147
  }
121
148
  }
122
149
 
123
- const Image = ({ src, alt }: { src: string; alt?: string }) => {
124
- const [loaded, setLoaded] = useState(false)
125
- return (
126
- <img
127
- src={getSafeUrl(src)}
128
- alt={alt || ""}
129
- onLoad={() => setLoaded(true)}
130
- className={cn(
131
- loaded ? "opacity-100" : "opacity-0",
132
- form ? "max-h-[300px]" : "max-h-[60px]",
133
- "transition-opacity duration-300 ease-in-out max-w-full object-contain rounded",
134
- )}
135
- />
136
- )
137
- }
138
-
139
150
  if (modified) {
140
151
  if (value === "tick") {
141
152
  return (
@@ -234,7 +245,7 @@ export const getFormattedFieldValue = (
234
245
  if (image) {
235
246
  return (
236
247
  <div className="w-full min-w-[100px]">
237
- <Image src={value} alt={field.name} />
248
+ <FormattedFieldImage src={value} alt={field.name} form={form} />
238
249
  </div>
239
250
  )
240
251
  }