Skip to content

Commit

Permalink
onLoadRef
Browse files Browse the repository at this point in the history
  • Loading branch information
styfle committed Oct 13, 2022
1 parent ba320a5 commit b61c197
Showing 1 changed file with 42 additions and 8 deletions.
50 changes: 42 additions & 8 deletions packages/next/client/future/image.tsx
Expand Up @@ -48,7 +48,7 @@ type ImageLoaderPropsWithConfig = ImageLoaderProps & {
}

type PlaceholderValue = 'blur' | 'empty'

type OnLoad = React.ReactEventHandler<HTMLImageElement> | undefined
type OnLoadingComplete = (img: HTMLImageElement) => void

type ImgElementStyle = NonNullable<JSX.IntrinsicElements['img']['style']>
Expand Down Expand Up @@ -128,6 +128,7 @@ type ImageElementProps = Omit<ImageProps, 'src' | 'alt' | 'loader'> & {
unoptimized: boolean
loader: ImageLoaderWithConfig
placeholder: PlaceholderValue
onLoadRef: React.MutableRefObject<OnLoad | undefined>
onLoadingCompleteRef: React.MutableRefObject<OnLoadingComplete | undefined>
setBlurComplete: (b: boolean) => void
setShowAltText: (b: boolean) => void
Expand Down Expand Up @@ -245,6 +246,7 @@ function handleLoading(
img: ImgElementWithDataProp,
src: string,
placeholder: PlaceholderValue,
onLoadRef: React.MutableRefObject<OnLoad | undefined>,
onLoadingCompleteRef: React.MutableRefObject<OnLoadingComplete | undefined>,
setBlurComplete: (b: boolean) => void
) {
Expand All @@ -265,6 +267,30 @@ function handleLoading(
if (placeholder === 'blur') {
setBlurComplete(true)
}
if (onLoadRef.current) {
const event = new Event('load')
Object.defineProperty(event, 'target', { writable: false, value: img })
let prevented = false
let stopped = false
const sytheticEvent = {
...event,
nativeEvent: event,
currentTarget: img,
target: img,
isDefaultPrevented: () => prevented,
isPropagationStopped: () => stopped,
persist: () => {},
preventDefault: () => {
prevented = true
event.preventDefault()
},
stopPropagation: () => {
stopped = true
event.stopPropagation()
},
}
onLoadRef.current(sytheticEvent)
}
if (onLoadingCompleteRef?.current) {
onLoadingCompleteRef.current(img)
}
Expand Down Expand Up @@ -331,6 +357,7 @@ const ImageElement = ({
config,
unoptimized,
loader,
onLoadRef,
onLoadingCompleteRef,
setBlurComplete,
setShowAltText,
Expand All @@ -357,10 +384,10 @@ const ImageElement = ({
if (!img) {
return
}
if (onLoad || onError) {
// If the image loads or errors before react hydrates, then the event is lost.
if (onError) {
// If the image has an error before react hydrates, then the error is lost.
// The workaround is to wait until the image is mounted which is after hydration,
// then we set the src again to trigger the handler (if there was an event).
// then we set the src again to trigger the error handler (if there was an error).
// eslint-disable-next-line no-self-assign
img.src = img.src
}
Expand Down Expand Up @@ -397,6 +424,7 @@ const ImageElement = ({
img,
srcString,
placeholder,
onLoadRef,
onLoadingCompleteRef,
setBlurComplete
)
Expand All @@ -405,10 +433,10 @@ const ImageElement = ({
[
srcString,
placeholder,
onLoadRef,
onLoadingCompleteRef,
setBlurComplete,
onError,
onLoad,
]
)}
onLoad={(event) => {
Expand All @@ -417,12 +445,10 @@ const ImageElement = ({
img,
srcString,
placeholder,
onLoadRef,
onLoadingCompleteRef,
setBlurComplete
)
if (onLoad) {
onLoad(event)
}
}}
onError={(event) => {
// if the real image fails to load, this will ensure "alt" is visible
Expand Down Expand Up @@ -516,6 +542,7 @@ export default function Image({
height,
fill,
style,
onLoad,
onLoadingComplete,
placeholder = 'empty',
blurDataURL,
Expand Down Expand Up @@ -838,6 +865,12 @@ export default function Image({
crossOrigin: rest.crossOrigin,
}

const onLoadRef = useRef(onLoad)

useEffect(() => {
onLoadRef.current = onLoad
}, [onLoad])

const onLoadingCompleteRef = useRef(onLoadingComplete)

useEffect(() => {
Expand All @@ -860,6 +893,7 @@ export default function Image({
placeholder,
loader,
srcString,
onLoadRef,
onLoadingCompleteRef,
setBlurComplete,
setShowAltText,
Expand Down

0 comments on commit b61c197

Please sign in to comment.