@radix-ui/react-avatar 1.2.0-rc.1781217402884 → 1.2.0

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.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/avatar.tsx"],
4
- "sourcesContent": ["'use client';\nexport {\n createAvatarScope,\n //\n Avatar,\n AvatarImage,\n AvatarFallback,\n //\n Root,\n Image,\n Fallback,\n} from './avatar';\nexport type { AvatarProps, AvatarImageProps, AvatarFallbackProps } from './avatar';\n", "import * as React from 'react';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useCallbackRef } from '@radix-ui/react-use-callback-ref';\nimport { useLayoutEffect } from '@radix-ui/react-use-layout-effect';\nimport { Primitive } from '@radix-ui/react-primitive';\n\nimport type { Scope } from '@radix-ui/react-context';\n\n/* -------------------------------------------------------------------------------------------------\n * Avatar\n * -----------------------------------------------------------------------------------------------*/\n\nconst AVATAR_NAME = 'Avatar';\n\ntype ScopedProps<P> = P & { __scopeAvatar?: Scope };\nconst [createAvatarContext, createAvatarScope] = createContextScope(AVATAR_NAME);\n\ntype ImageLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error';\n\ntype AvatarContextValue = {\n imageLoadingStatus: ImageLoadingStatus;\n setImageLoadingStatus: React.Dispatch<React.SetStateAction<ImageLoadingStatus>>;\n imageCount: number;\n setImageCount: React.Dispatch<React.SetStateAction<number>>;\n};\n\nconst STATIC_IMAGE_COUNT_STATE: [number, React.Dispatch<React.SetStateAction<number>>] = [\n 0,\n () => void 0,\n];\n\nconst [AvatarProvider, useAvatarContext] = createAvatarContext<AvatarContextValue>(AVATAR_NAME);\n\ntype AvatarElement = React.ComponentRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface AvatarProps extends PrimitiveSpanProps {}\n\nconst Avatar = React.forwardRef<AvatarElement, AvatarProps>(\n (props: ScopedProps<AvatarProps>, forwardedRef) => {\n const { __scopeAvatar, ...avatarProps } = props;\n const [imageLoadingStatus, setImageLoadingStatus] = React.useState<ImageLoadingStatus>('idle');\n const [imageCount, setImageCount] = useImageCount();\n\n return (\n <AvatarProvider\n scope={__scopeAvatar}\n imageLoadingStatus={imageLoadingStatus}\n setImageLoadingStatus={setImageLoadingStatus}\n imageCount={imageCount}\n setImageCount={setImageCount}\n >\n <Primitive.span {...avatarProps} ref={forwardedRef} />\n </AvatarProvider>\n );\n },\n);\n\nAvatar.displayName = AVATAR_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * AvatarImage\n * -----------------------------------------------------------------------------------------------*/\n\nconst IMAGE_NAME = 'AvatarImage';\n\ntype AvatarImageElement = React.ComponentRef<typeof Primitive.img>;\ntype PrimitiveImageProps = React.ComponentPropsWithoutRef<typeof Primitive.img>;\ninterface AvatarImageProps extends PrimitiveImageProps {\n onLoadingStatusChange?: (status: ImageLoadingStatus) => void;\n}\n\nconst AvatarImage = React.forwardRef<AvatarImageElement, AvatarImageProps>(\n (props: ScopedProps<AvatarImageProps>, forwardedRef) => {\n const { __scopeAvatar, src, onLoadingStatusChange, ...imageProps } = props;\n const context = useAvatarContext(IMAGE_NAME, __scopeAvatar);\n useUpdateImageCount(context.setImageCount);\n\n const imageLoadingStatus = useImageLoadingStatus(src, {\n referrerPolicy: imageProps.referrerPolicy,\n crossOrigin: imageProps.crossOrigin,\n loadingStatus: context.imageLoadingStatus,\n setLoadingStatus: context.setImageLoadingStatus,\n });\n const handleLoadingStatusChange = useCallbackRef((status: ImageLoadingStatus) => {\n onLoadingStatusChange?.(status);\n });\n\n const loadingStatusRef = React.useRef<ImageLoadingStatus>(imageLoadingStatus);\n\n useLayoutEffect(() => {\n const previousLoadingStatus = loadingStatusRef.current;\n loadingStatusRef.current = imageLoadingStatus;\n\n if (imageLoadingStatus !== previousLoadingStatus) {\n handleLoadingStatusChange(imageLoadingStatus);\n }\n }, [imageLoadingStatus, handleLoadingStatusChange]);\n\n return imageLoadingStatus === 'loaded' ? (\n <Primitive.img {...imageProps} ref={forwardedRef} src={src} />\n ) : null;\n },\n);\n\nAvatarImage.displayName = IMAGE_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * AvatarFallback\n * -----------------------------------------------------------------------------------------------*/\n\nconst FALLBACK_NAME = 'AvatarFallback';\n\ntype AvatarFallbackElement = React.ComponentRef<typeof Primitive.span>;\ninterface AvatarFallbackProps extends PrimitiveSpanProps {\n delayMs?: number;\n}\n\nconst AvatarFallback = React.forwardRef<AvatarFallbackElement, AvatarFallbackProps>(\n (props: ScopedProps<AvatarFallbackProps>, forwardedRef) => {\n const { __scopeAvatar, delayMs, ...fallbackProps } = props;\n const context = useAvatarContext(FALLBACK_NAME, __scopeAvatar);\n const [canRender, setCanRender] = React.useState(delayMs === undefined);\n\n React.useEffect(() => {\n if (delayMs !== undefined) {\n const timerId = window.setTimeout(() => setCanRender(true), delayMs);\n return () => window.clearTimeout(timerId);\n }\n }, [delayMs]);\n\n return canRender && context.imageLoadingStatus !== 'loaded' ? (\n <Primitive.span {...fallbackProps} ref={forwardedRef} />\n ) : null;\n },\n);\n\nAvatarFallback.displayName = FALLBACK_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\nfunction useImageLoadingStatus(\n src: string | undefined,\n {\n loadingStatus,\n setLoadingStatus,\n referrerPolicy,\n crossOrigin,\n }: {\n referrerPolicy: React.HTMLAttributeReferrerPolicy | undefined;\n crossOrigin: string | undefined;\n loadingStatus: ImageLoadingStatus;\n setLoadingStatus: React.Dispatch<React.SetStateAction<ImageLoadingStatus>>;\n },\n) {\n useLayoutEffect(() => {\n if (!src) {\n setLoadingStatus('error');\n return;\n }\n\n const image = new window.Image();\n const handleLoad = (event: Event) => {\n const image = event.currentTarget as HTMLImageElement;\n setLoadingStatus(getImageLoadingStatus(image));\n };\n const handleError = () => setLoadingStatus('error');\n image.addEventListener('load', handleLoad);\n image.addEventListener('error', handleError);\n if (referrerPolicy) {\n image.referrerPolicy = referrerPolicy;\n }\n image.crossOrigin = crossOrigin ?? null;\n image.src = src;\n\n setLoadingStatus(getImageLoadingStatus(image));\n return () => {\n image.removeEventListener('load', handleLoad);\n image.removeEventListener('error', handleError);\n setLoadingStatus('idle');\n };\n }, [src, crossOrigin, referrerPolicy, setLoadingStatus]);\n\n return loadingStatus;\n}\n\nfunction getImageLoadingStatus(image: HTMLImageElement) {\n return image.complete ? (image.naturalWidth > 0 ? 'loaded' : 'error') : 'loading';\n}\n\n// Image count is only used in development to warn about multiple images, which\n// is unsupported. Gating behind a development flag to avoid performance\n// overhead in production is safe because useState is guaranteed to run\n// consistently in the same environment.\n// oxlint-disable react-hooks/rules-of-hooks\nfunction useImageCount() {\n let state = STATIC_IMAGE_COUNT_STATE;\n if (process.env.NODE_ENV === 'development') {\n state = React.useState(0);\n const [imageCount] = state;\n const hasWarnedRef = React.useRef(false);\n React.useEffect(() => {\n if (imageCount > 1 && !hasWarnedRef.current) {\n hasWarnedRef.current = true;\n console.warn(\n 'Avatar: Only one `Avatar.Image` component should be rendered per `Avatar.Root`, but multiple were detected. This will lead to unexpected behavior.',\n );\n }\n }, [imageCount]);\n }\n\n return state;\n}\n\nfunction useUpdateImageCount(setImageCount: React.Dispatch<React.SetStateAction<number>>) {\n if (process.env.NODE_ENV === 'development') {\n React.useEffect(() => {\n setImageCount((imageCount) => imageCount + 1);\n return () => {\n setImageCount((imageCount) => imageCount - 1);\n };\n }, [setImageCount]);\n }\n}\n// oxlint-enable react-hooks/rules-of-hooks\n\nexport {\n createAvatarScope,\n //\n Avatar,\n AvatarImage,\n AvatarFallback,\n //\n Avatar as Root,\n AvatarImage as Image,\n AvatarFallback as Fallback,\n};\nexport type { AvatarProps, AvatarImageProps, AvatarFallbackProps };\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client';\nexport {\n createAvatarScope,\n //\n Avatar,\n AvatarImage,\n AvatarFallback,\n //\n Root,\n Image,\n Fallback,\n} from './avatar';\nexport type { AvatarProps, AvatarImageProps, AvatarFallbackProps } from './avatar';\n", "import * as React from 'react';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useCallbackRef } from '@radix-ui/react-use-callback-ref';\nimport { useLayoutEffect } from '@radix-ui/react-use-layout-effect';\nimport { Primitive } from '@radix-ui/react-primitive';\n\nimport type { Scope } from '@radix-ui/react-context';\n\n/* -------------------------------------------------------------------------------------------------\n * Avatar\n * -----------------------------------------------------------------------------------------------*/\n\nconst AVATAR_NAME = 'Avatar';\n\ntype ScopedProps<P> = P & { __scopeAvatar?: Scope };\nconst [createAvatarContext, createAvatarScope] = createContextScope(AVATAR_NAME);\n\ntype ImageLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error';\n\ntype AvatarContextValue = {\n imageLoadingStatus: ImageLoadingStatus;\n setImageLoadingStatus: React.Dispatch<React.SetStateAction<ImageLoadingStatus>>;\n imageCount: number;\n setImageCount: React.Dispatch<React.SetStateAction<number>>;\n};\n\nconst STATIC_IMAGE_COUNT_STATE: [number, React.Dispatch<React.SetStateAction<number>>] = [\n 0,\n () => void 0,\n];\n\nconst [AvatarProvider, useAvatarContext] = createAvatarContext<AvatarContextValue>(AVATAR_NAME);\n\ntype AvatarElement = React.ComponentRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface AvatarProps extends PrimitiveSpanProps {}\n\nconst Avatar = React.forwardRef<AvatarElement, AvatarProps>(\n (props: ScopedProps<AvatarProps>, forwardedRef) => {\n const { __scopeAvatar, ...avatarProps } = props;\n const [imageLoadingStatus, setImageLoadingStatus] = React.useState<ImageLoadingStatus>('idle');\n const [imageCount, setImageCount] = useImageCount();\n\n return (\n <AvatarProvider\n scope={__scopeAvatar}\n imageLoadingStatus={imageLoadingStatus}\n setImageLoadingStatus={setImageLoadingStatus}\n imageCount={imageCount}\n setImageCount={setImageCount}\n >\n <Primitive.span {...avatarProps} ref={forwardedRef} />\n </AvatarProvider>\n );\n },\n);\n\nAvatar.displayName = AVATAR_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * AvatarImage\n * -----------------------------------------------------------------------------------------------*/\n\nconst IMAGE_NAME = 'AvatarImage';\n\ntype AvatarImageElement = React.ComponentRef<typeof Primitive.img>;\ntype PrimitiveImageProps = React.ComponentPropsWithoutRef<typeof Primitive.img>;\ninterface AvatarImageProps extends PrimitiveImageProps {\n onLoadingStatusChange?: (status: ImageLoadingStatus) => void;\n}\n\nconst AvatarImage = React.forwardRef<AvatarImageElement, AvatarImageProps>(\n (props: ScopedProps<AvatarImageProps>, forwardedRef) => {\n const { __scopeAvatar, src, onLoadingStatusChange, ...imageProps } = props;\n const context = useAvatarContext(IMAGE_NAME, __scopeAvatar);\n useUpdateImageCount(context.setImageCount);\n\n const imageLoadingStatus = useImageLoadingStatus(src, {\n referrerPolicy: imageProps.referrerPolicy,\n crossOrigin: imageProps.crossOrigin,\n loadingStatus: context.imageLoadingStatus,\n setLoadingStatus: context.setImageLoadingStatus,\n });\n const handleLoadingStatusChange = useCallbackRef((status: ImageLoadingStatus) => {\n onLoadingStatusChange?.(status);\n });\n\n const loadingStatusRef = React.useRef<ImageLoadingStatus>(imageLoadingStatus);\n\n useLayoutEffect(() => {\n const previousLoadingStatus = loadingStatusRef.current;\n loadingStatusRef.current = imageLoadingStatus;\n\n if (imageLoadingStatus !== previousLoadingStatus) {\n handleLoadingStatusChange(imageLoadingStatus);\n }\n }, [imageLoadingStatus, handleLoadingStatusChange]);\n\n return imageLoadingStatus === 'loaded' ? (\n <Primitive.img {...imageProps} ref={forwardedRef} src={src} />\n ) : null;\n },\n);\n\nAvatarImage.displayName = IMAGE_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * AvatarFallback\n * -----------------------------------------------------------------------------------------------*/\n\nconst FALLBACK_NAME = 'AvatarFallback';\n\ntype AvatarFallbackElement = React.ComponentRef<typeof Primitive.span>;\ninterface AvatarFallbackProps extends PrimitiveSpanProps {\n delayMs?: number;\n}\n\nconst AvatarFallback = React.forwardRef<AvatarFallbackElement, AvatarFallbackProps>(\n (props: ScopedProps<AvatarFallbackProps>, forwardedRef) => {\n const { __scopeAvatar, delayMs, ...fallbackProps } = props;\n const context = useAvatarContext(FALLBACK_NAME, __scopeAvatar);\n const [canRender, setCanRender] = React.useState(delayMs === undefined);\n\n React.useEffect(() => {\n if (delayMs !== undefined) {\n const timerId = window.setTimeout(() => setCanRender(true), delayMs);\n return () => window.clearTimeout(timerId);\n }\n }, [delayMs]);\n\n return canRender && context.imageLoadingStatus !== 'loaded' ? (\n <Primitive.span {...fallbackProps} ref={forwardedRef} />\n ) : null;\n },\n);\n\nAvatarFallback.displayName = FALLBACK_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\nfunction useImageLoadingStatus(\n src: string | undefined,\n {\n loadingStatus,\n setLoadingStatus,\n referrerPolicy,\n crossOrigin,\n }: {\n referrerPolicy: React.HTMLAttributeReferrerPolicy | undefined;\n crossOrigin: string | undefined;\n loadingStatus: ImageLoadingStatus;\n setLoadingStatus: React.Dispatch<React.SetStateAction<ImageLoadingStatus>>;\n },\n) {\n useLayoutEffect(() => {\n if (!src) {\n setLoadingStatus('error');\n return;\n }\n\n const image = new window.Image();\n const handleLoad = (event: Event) => {\n const image = event.currentTarget as HTMLImageElement;\n setLoadingStatus(getImageLoadingStatus(image));\n };\n const handleError = () => setLoadingStatus('error');\n image.addEventListener('load', handleLoad);\n image.addEventListener('error', handleError);\n if (referrerPolicy) {\n image.referrerPolicy = referrerPolicy;\n }\n image.crossOrigin = crossOrigin ?? null;\n image.src = src;\n\n setLoadingStatus(getImageLoadingStatus(image));\n return () => {\n image.removeEventListener('load', handleLoad);\n image.removeEventListener('error', handleError);\n setLoadingStatus('idle');\n };\n }, [src, crossOrigin, referrerPolicy, setLoadingStatus]);\n\n return loadingStatus;\n}\n\nfunction getImageLoadingStatus(image: HTMLImageElement) {\n return image.complete ? (image.naturalWidth > 0 ? 'loaded' : 'error') : 'loading';\n}\n\n// Image count is only used in development to warn about multiple images, which\n// is unsupported. Gating behind a development flag to avoid performance\n// overhead in production is safe because useState is guaranteed to run\n// consistently in the same environment.\n// oxlint-disable react-hooks/rules-of-hooks\nfunction useImageCount() {\n let state = STATIC_IMAGE_COUNT_STATE;\n if (process.env.NODE_ENV !== 'production') {\n state = React.useState(0);\n const [imageCount] = state;\n const hasWarnedRef = React.useRef(false);\n React.useEffect(() => {\n if (imageCount > 1 && !hasWarnedRef.current) {\n hasWarnedRef.current = true;\n console.warn(\n 'Avatar: Only one `Avatar.Image` component should be rendered per `Avatar.Root`, but multiple were detected. This will lead to unexpected behavior.',\n );\n }\n }, [imageCount]);\n }\n\n return state;\n}\n\nfunction useUpdateImageCount(setImageCount: React.Dispatch<React.SetStateAction<number>>) {\n if (process.env.NODE_ENV !== 'production') {\n React.useEffect(() => {\n setImageCount((imageCount) => imageCount + 1);\n return () => {\n setImageCount((imageCount) => imageCount - 1);\n };\n }, [setImageCount]);\n }\n}\n// oxlint-enable react-hooks/rules-of-hooks\n\nexport {\n createAvatarScope,\n //\n Avatar,\n AvatarImage,\n AvatarFallback,\n //\n Avatar as Root,\n AvatarImage as Image,\n AvatarFallback as Fallback,\n};\nexport type { AvatarProps, AvatarImageProps, AvatarFallbackProps };\n"],
5
+ "mappings": "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",
6
6
  "names": ["image"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/avatar.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useCallbackRef } from '@radix-ui/react-use-callback-ref';\nimport { useLayoutEffect } from '@radix-ui/react-use-layout-effect';\nimport { Primitive } from '@radix-ui/react-primitive';\n\nimport type { Scope } from '@radix-ui/react-context';\n\n/* -------------------------------------------------------------------------------------------------\n * Avatar\n * -----------------------------------------------------------------------------------------------*/\n\nconst AVATAR_NAME = 'Avatar';\n\ntype ScopedProps<P> = P & { __scopeAvatar?: Scope };\nconst [createAvatarContext, createAvatarScope] = createContextScope(AVATAR_NAME);\n\ntype ImageLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error';\n\ntype AvatarContextValue = {\n imageLoadingStatus: ImageLoadingStatus;\n setImageLoadingStatus: React.Dispatch<React.SetStateAction<ImageLoadingStatus>>;\n imageCount: number;\n setImageCount: React.Dispatch<React.SetStateAction<number>>;\n};\n\nconst STATIC_IMAGE_COUNT_STATE: [number, React.Dispatch<React.SetStateAction<number>>] = [\n 0,\n () => void 0,\n];\n\nconst [AvatarProvider, useAvatarContext] = createAvatarContext<AvatarContextValue>(AVATAR_NAME);\n\ntype AvatarElement = React.ComponentRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface AvatarProps extends PrimitiveSpanProps {}\n\nconst Avatar = React.forwardRef<AvatarElement, AvatarProps>(\n (props: ScopedProps<AvatarProps>, forwardedRef) => {\n const { __scopeAvatar, ...avatarProps } = props;\n const [imageLoadingStatus, setImageLoadingStatus] = React.useState<ImageLoadingStatus>('idle');\n const [imageCount, setImageCount] = useImageCount();\n\n return (\n <AvatarProvider\n scope={__scopeAvatar}\n imageLoadingStatus={imageLoadingStatus}\n setImageLoadingStatus={setImageLoadingStatus}\n imageCount={imageCount}\n setImageCount={setImageCount}\n >\n <Primitive.span {...avatarProps} ref={forwardedRef} />\n </AvatarProvider>\n );\n },\n);\n\nAvatar.displayName = AVATAR_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * AvatarImage\n * -----------------------------------------------------------------------------------------------*/\n\nconst IMAGE_NAME = 'AvatarImage';\n\ntype AvatarImageElement = React.ComponentRef<typeof Primitive.img>;\ntype PrimitiveImageProps = React.ComponentPropsWithoutRef<typeof Primitive.img>;\ninterface AvatarImageProps extends PrimitiveImageProps {\n onLoadingStatusChange?: (status: ImageLoadingStatus) => void;\n}\n\nconst AvatarImage = React.forwardRef<AvatarImageElement, AvatarImageProps>(\n (props: ScopedProps<AvatarImageProps>, forwardedRef) => {\n const { __scopeAvatar, src, onLoadingStatusChange, ...imageProps } = props;\n const context = useAvatarContext(IMAGE_NAME, __scopeAvatar);\n useUpdateImageCount(context.setImageCount);\n\n const imageLoadingStatus = useImageLoadingStatus(src, {\n referrerPolicy: imageProps.referrerPolicy,\n crossOrigin: imageProps.crossOrigin,\n loadingStatus: context.imageLoadingStatus,\n setLoadingStatus: context.setImageLoadingStatus,\n });\n const handleLoadingStatusChange = useCallbackRef((status: ImageLoadingStatus) => {\n onLoadingStatusChange?.(status);\n });\n\n const loadingStatusRef = React.useRef<ImageLoadingStatus>(imageLoadingStatus);\n\n useLayoutEffect(() => {\n const previousLoadingStatus = loadingStatusRef.current;\n loadingStatusRef.current = imageLoadingStatus;\n\n if (imageLoadingStatus !== previousLoadingStatus) {\n handleLoadingStatusChange(imageLoadingStatus);\n }\n }, [imageLoadingStatus, handleLoadingStatusChange]);\n\n return imageLoadingStatus === 'loaded' ? (\n <Primitive.img {...imageProps} ref={forwardedRef} src={src} />\n ) : null;\n },\n);\n\nAvatarImage.displayName = IMAGE_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * AvatarFallback\n * -----------------------------------------------------------------------------------------------*/\n\nconst FALLBACK_NAME = 'AvatarFallback';\n\ntype AvatarFallbackElement = React.ComponentRef<typeof Primitive.span>;\ninterface AvatarFallbackProps extends PrimitiveSpanProps {\n delayMs?: number;\n}\n\nconst AvatarFallback = React.forwardRef<AvatarFallbackElement, AvatarFallbackProps>(\n (props: ScopedProps<AvatarFallbackProps>, forwardedRef) => {\n const { __scopeAvatar, delayMs, ...fallbackProps } = props;\n const context = useAvatarContext(FALLBACK_NAME, __scopeAvatar);\n const [canRender, setCanRender] = React.useState(delayMs === undefined);\n\n React.useEffect(() => {\n if (delayMs !== undefined) {\n const timerId = window.setTimeout(() => setCanRender(true), delayMs);\n return () => window.clearTimeout(timerId);\n }\n }, [delayMs]);\n\n return canRender && context.imageLoadingStatus !== 'loaded' ? (\n <Primitive.span {...fallbackProps} ref={forwardedRef} />\n ) : null;\n },\n);\n\nAvatarFallback.displayName = FALLBACK_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\nfunction useImageLoadingStatus(\n src: string | undefined,\n {\n loadingStatus,\n setLoadingStatus,\n referrerPolicy,\n crossOrigin,\n }: {\n referrerPolicy: React.HTMLAttributeReferrerPolicy | undefined;\n crossOrigin: string | undefined;\n loadingStatus: ImageLoadingStatus;\n setLoadingStatus: React.Dispatch<React.SetStateAction<ImageLoadingStatus>>;\n },\n) {\n useLayoutEffect(() => {\n if (!src) {\n setLoadingStatus('error');\n return;\n }\n\n const image = new window.Image();\n const handleLoad = (event: Event) => {\n const image = event.currentTarget as HTMLImageElement;\n setLoadingStatus(getImageLoadingStatus(image));\n };\n const handleError = () => setLoadingStatus('error');\n image.addEventListener('load', handleLoad);\n image.addEventListener('error', handleError);\n if (referrerPolicy) {\n image.referrerPolicy = referrerPolicy;\n }\n image.crossOrigin = crossOrigin ?? null;\n image.src = src;\n\n setLoadingStatus(getImageLoadingStatus(image));\n return () => {\n image.removeEventListener('load', handleLoad);\n image.removeEventListener('error', handleError);\n setLoadingStatus('idle');\n };\n }, [src, crossOrigin, referrerPolicy, setLoadingStatus]);\n\n return loadingStatus;\n}\n\nfunction getImageLoadingStatus(image: HTMLImageElement) {\n return image.complete ? (image.naturalWidth > 0 ? 'loaded' : 'error') : 'loading';\n}\n\n// Image count is only used in development to warn about multiple images, which\n// is unsupported. Gating behind a development flag to avoid performance\n// overhead in production is safe because useState is guaranteed to run\n// consistently in the same environment.\n// oxlint-disable react-hooks/rules-of-hooks\nfunction useImageCount() {\n let state = STATIC_IMAGE_COUNT_STATE;\n if (process.env.NODE_ENV === 'development') {\n state = React.useState(0);\n const [imageCount] = state;\n const hasWarnedRef = React.useRef(false);\n React.useEffect(() => {\n if (imageCount > 1 && !hasWarnedRef.current) {\n hasWarnedRef.current = true;\n console.warn(\n 'Avatar: Only one `Avatar.Image` component should be rendered per `Avatar.Root`, but multiple were detected. This will lead to unexpected behavior.',\n );\n }\n }, [imageCount]);\n }\n\n return state;\n}\n\nfunction useUpdateImageCount(setImageCount: React.Dispatch<React.SetStateAction<number>>) {\n if (process.env.NODE_ENV === 'development') {\n React.useEffect(() => {\n setImageCount((imageCount) => imageCount + 1);\n return () => {\n setImageCount((imageCount) => imageCount - 1);\n };\n }, [setImageCount]);\n }\n}\n// oxlint-enable react-hooks/rules-of-hooks\n\nexport {\n createAvatarScope,\n //\n Avatar,\n AvatarImage,\n AvatarFallback,\n //\n Avatar as Root,\n AvatarImage as Image,\n AvatarFallback as Fallback,\n};\nexport type { AvatarProps, AvatarImageProps, AvatarFallbackProps };\n"],
5
- "mappings": ";;;AAAA,YAAY,WAAW;AACvB,SAAS,0BAA0B;AACnC,SAAS,sBAAsB;AAC/B,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AA+ClB;AAvCR,IAAM,cAAc;AAGpB,IAAM,CAAC,qBAAqB,iBAAiB,IAAI,mBAAmB,WAAW;AAW/E,IAAM,2BAAmF;AAAA,EACvF;AAAA,EACA,MAAM;AACR;AAEA,IAAM,CAAC,gBAAgB,gBAAgB,IAAI,oBAAwC,WAAW;AAM9F,IAAM,SAAe;AAAA,EACnB,CAAC,OAAiC,iBAAiB;AACjD,UAAM,EAAE,eAAe,GAAG,YAAY,IAAI;AAC1C,UAAM,CAAC,oBAAoB,qBAAqB,IAAU,eAA6B,MAAM;AAC7F,UAAM,CAAC,YAAY,aAAa,IAAI,cAAc;AAElD,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA,8BAAC,UAAU,MAAV,EAAgB,GAAG,aAAa,KAAK,cAAc;AAAA;AAAA,IACtD;AAAA,EAEJ;AACF;AAEA,OAAO,cAAc;AAMrB,IAAM,aAAa;AAQnB,IAAM,cAAoB;AAAA,EACxB,CAAC,OAAsC,iBAAiB;AACtD,UAAM,EAAE,eAAe,KAAK,uBAAuB,GAAG,WAAW,IAAI;AACrE,UAAM,UAAU,iBAAiB,YAAY,aAAa;AAC1D,wBAAoB,QAAQ,aAAa;AAEzC,UAAM,qBAAqB,sBAAsB,KAAK;AAAA,MACpD,gBAAgB,WAAW;AAAA,MAC3B,aAAa,WAAW;AAAA,MACxB,eAAe,QAAQ;AAAA,MACvB,kBAAkB,QAAQ;AAAA,IAC5B,CAAC;AACD,UAAM,4BAA4B,eAAe,CAAC,WAA+B;AAC/E,8BAAwB,MAAM;AAAA,IAChC,CAAC;AAED,UAAM,mBAAyB,aAA2B,kBAAkB;AAE5E,oBAAgB,MAAM;AACpB,YAAM,wBAAwB,iBAAiB;AAC/C,uBAAiB,UAAU;AAE3B,UAAI,uBAAuB,uBAAuB;AAChD,kCAA0B,kBAAkB;AAAA,MAC9C;AAAA,IACF,GAAG,CAAC,oBAAoB,yBAAyB,CAAC;AAElD,WAAO,uBAAuB,WAC5B,oBAAC,UAAU,KAAV,EAAe,GAAG,YAAY,KAAK,cAAc,KAAU,IAC1D;AAAA,EACN;AACF;AAEA,YAAY,cAAc;AAM1B,IAAM,gBAAgB;AAOtB,IAAM,iBAAuB;AAAA,EAC3B,CAAC,OAAyC,iBAAiB;AACzD,UAAM,EAAE,eAAe,SAAS,GAAG,cAAc,IAAI;AACrD,UAAM,UAAU,iBAAiB,eAAe,aAAa;AAC7D,UAAM,CAAC,WAAW,YAAY,IAAU,eAAS,YAAY,MAAS;AAEtE,IAAM,gBAAU,MAAM;AACpB,UAAI,YAAY,QAAW;AACzB,cAAM,UAAU,OAAO,WAAW,MAAM,aAAa,IAAI,GAAG,OAAO;AACnE,eAAO,MAAM,OAAO,aAAa,OAAO;AAAA,MAC1C;AAAA,IACF,GAAG,CAAC,OAAO,CAAC;AAEZ,WAAO,aAAa,QAAQ,uBAAuB,WACjD,oBAAC,UAAU,MAAV,EAAgB,GAAG,eAAe,KAAK,cAAc,IACpD;AAAA,EACN;AACF;AAEA,eAAe,cAAc;AAI7B,SAAS,sBACP,KACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMA;AACA,kBAAgB,MAAM;AACpB,QAAI,CAAC,KAAK;AACR,uBAAiB,OAAO;AACxB;AAAA,IACF;AAEA,UAAM,QAAQ,IAAI,OAAO,MAAM;AAC/B,UAAM,aAAa,CAAC,UAAiB;AACnC,YAAMA,SAAQ,MAAM;AACpB,uBAAiB,sBAAsBA,MAAK,CAAC;AAAA,IAC/C;AACA,UAAM,cAAc,MAAM,iBAAiB,OAAO;AAClD,UAAM,iBAAiB,QAAQ,UAAU;AACzC,UAAM,iBAAiB,SAAS,WAAW;AAC3C,QAAI,gBAAgB;AAClB,YAAM,iBAAiB;AAAA,IACzB;AACA,UAAM,cAAc,eAAe;AACnC,UAAM,MAAM;AAEZ,qBAAiB,sBAAsB,KAAK,CAAC;AAC7C,WAAO,MAAM;AACX,YAAM,oBAAoB,QAAQ,UAAU;AAC5C,YAAM,oBAAoB,SAAS,WAAW;AAC9C,uBAAiB,MAAM;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,KAAK,aAAa,gBAAgB,gBAAgB,CAAC;AAEvD,SAAO;AACT;AAEA,SAAS,sBAAsB,OAAyB;AACtD,SAAO,MAAM,WAAY,MAAM,eAAe,IAAI,WAAW,UAAW;AAC1E;AAOA,SAAS,gBAAgB;AACvB,MAAI,QAAQ;AACZ,MAAI,MAAwC;AAC1C,YAAc,eAAS,CAAC;AACxB,UAAM,CAAC,UAAU,IAAI;AACrB,UAAM,eAAqB,aAAO,KAAK;AACvC,IAAM,gBAAU,MAAM;AACpB,UAAI,aAAa,KAAK,CAAC,aAAa,SAAS;AAC3C,qBAAa,UAAU;AACvB,gBAAQ;AAAA,UACN;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG,CAAC,UAAU,CAAC;AAAA,EACjB;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,eAA6D;AACxF,MAAI,MAAwC;AAC1C,IAAM,gBAAU,MAAM;AACpB,oBAAc,CAAC,eAAe,aAAa,CAAC;AAC5C,aAAO,MAAM;AACX,sBAAc,CAAC,eAAe,aAAa,CAAC;AAAA,MAC9C;AAAA,IACF,GAAG,CAAC,aAAa,CAAC;AAAA,EACpB;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useCallbackRef } from '@radix-ui/react-use-callback-ref';\nimport { useLayoutEffect } from '@radix-ui/react-use-layout-effect';\nimport { Primitive } from '@radix-ui/react-primitive';\n\nimport type { Scope } from '@radix-ui/react-context';\n\n/* -------------------------------------------------------------------------------------------------\n * Avatar\n * -----------------------------------------------------------------------------------------------*/\n\nconst AVATAR_NAME = 'Avatar';\n\ntype ScopedProps<P> = P & { __scopeAvatar?: Scope };\nconst [createAvatarContext, createAvatarScope] = createContextScope(AVATAR_NAME);\n\ntype ImageLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error';\n\ntype AvatarContextValue = {\n imageLoadingStatus: ImageLoadingStatus;\n setImageLoadingStatus: React.Dispatch<React.SetStateAction<ImageLoadingStatus>>;\n imageCount: number;\n setImageCount: React.Dispatch<React.SetStateAction<number>>;\n};\n\nconst STATIC_IMAGE_COUNT_STATE: [number, React.Dispatch<React.SetStateAction<number>>] = [\n 0,\n () => void 0,\n];\n\nconst [AvatarProvider, useAvatarContext] = createAvatarContext<AvatarContextValue>(AVATAR_NAME);\n\ntype AvatarElement = React.ComponentRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface AvatarProps extends PrimitiveSpanProps {}\n\nconst Avatar = React.forwardRef<AvatarElement, AvatarProps>(\n (props: ScopedProps<AvatarProps>, forwardedRef) => {\n const { __scopeAvatar, ...avatarProps } = props;\n const [imageLoadingStatus, setImageLoadingStatus] = React.useState<ImageLoadingStatus>('idle');\n const [imageCount, setImageCount] = useImageCount();\n\n return (\n <AvatarProvider\n scope={__scopeAvatar}\n imageLoadingStatus={imageLoadingStatus}\n setImageLoadingStatus={setImageLoadingStatus}\n imageCount={imageCount}\n setImageCount={setImageCount}\n >\n <Primitive.span {...avatarProps} ref={forwardedRef} />\n </AvatarProvider>\n );\n },\n);\n\nAvatar.displayName = AVATAR_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * AvatarImage\n * -----------------------------------------------------------------------------------------------*/\n\nconst IMAGE_NAME = 'AvatarImage';\n\ntype AvatarImageElement = React.ComponentRef<typeof Primitive.img>;\ntype PrimitiveImageProps = React.ComponentPropsWithoutRef<typeof Primitive.img>;\ninterface AvatarImageProps extends PrimitiveImageProps {\n onLoadingStatusChange?: (status: ImageLoadingStatus) => void;\n}\n\nconst AvatarImage = React.forwardRef<AvatarImageElement, AvatarImageProps>(\n (props: ScopedProps<AvatarImageProps>, forwardedRef) => {\n const { __scopeAvatar, src, onLoadingStatusChange, ...imageProps } = props;\n const context = useAvatarContext(IMAGE_NAME, __scopeAvatar);\n useUpdateImageCount(context.setImageCount);\n\n const imageLoadingStatus = useImageLoadingStatus(src, {\n referrerPolicy: imageProps.referrerPolicy,\n crossOrigin: imageProps.crossOrigin,\n loadingStatus: context.imageLoadingStatus,\n setLoadingStatus: context.setImageLoadingStatus,\n });\n const handleLoadingStatusChange = useCallbackRef((status: ImageLoadingStatus) => {\n onLoadingStatusChange?.(status);\n });\n\n const loadingStatusRef = React.useRef<ImageLoadingStatus>(imageLoadingStatus);\n\n useLayoutEffect(() => {\n const previousLoadingStatus = loadingStatusRef.current;\n loadingStatusRef.current = imageLoadingStatus;\n\n if (imageLoadingStatus !== previousLoadingStatus) {\n handleLoadingStatusChange(imageLoadingStatus);\n }\n }, [imageLoadingStatus, handleLoadingStatusChange]);\n\n return imageLoadingStatus === 'loaded' ? (\n <Primitive.img {...imageProps} ref={forwardedRef} src={src} />\n ) : null;\n },\n);\n\nAvatarImage.displayName = IMAGE_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * AvatarFallback\n * -----------------------------------------------------------------------------------------------*/\n\nconst FALLBACK_NAME = 'AvatarFallback';\n\ntype AvatarFallbackElement = React.ComponentRef<typeof Primitive.span>;\ninterface AvatarFallbackProps extends PrimitiveSpanProps {\n delayMs?: number;\n}\n\nconst AvatarFallback = React.forwardRef<AvatarFallbackElement, AvatarFallbackProps>(\n (props: ScopedProps<AvatarFallbackProps>, forwardedRef) => {\n const { __scopeAvatar, delayMs, ...fallbackProps } = props;\n const context = useAvatarContext(FALLBACK_NAME, __scopeAvatar);\n const [canRender, setCanRender] = React.useState(delayMs === undefined);\n\n React.useEffect(() => {\n if (delayMs !== undefined) {\n const timerId = window.setTimeout(() => setCanRender(true), delayMs);\n return () => window.clearTimeout(timerId);\n }\n }, [delayMs]);\n\n return canRender && context.imageLoadingStatus !== 'loaded' ? (\n <Primitive.span {...fallbackProps} ref={forwardedRef} />\n ) : null;\n },\n);\n\nAvatarFallback.displayName = FALLBACK_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\nfunction useImageLoadingStatus(\n src: string | undefined,\n {\n loadingStatus,\n setLoadingStatus,\n referrerPolicy,\n crossOrigin,\n }: {\n referrerPolicy: React.HTMLAttributeReferrerPolicy | undefined;\n crossOrigin: string | undefined;\n loadingStatus: ImageLoadingStatus;\n setLoadingStatus: React.Dispatch<React.SetStateAction<ImageLoadingStatus>>;\n },\n) {\n useLayoutEffect(() => {\n if (!src) {\n setLoadingStatus('error');\n return;\n }\n\n const image = new window.Image();\n const handleLoad = (event: Event) => {\n const image = event.currentTarget as HTMLImageElement;\n setLoadingStatus(getImageLoadingStatus(image));\n };\n const handleError = () => setLoadingStatus('error');\n image.addEventListener('load', handleLoad);\n image.addEventListener('error', handleError);\n if (referrerPolicy) {\n image.referrerPolicy = referrerPolicy;\n }\n image.crossOrigin = crossOrigin ?? null;\n image.src = src;\n\n setLoadingStatus(getImageLoadingStatus(image));\n return () => {\n image.removeEventListener('load', handleLoad);\n image.removeEventListener('error', handleError);\n setLoadingStatus('idle');\n };\n }, [src, crossOrigin, referrerPolicy, setLoadingStatus]);\n\n return loadingStatus;\n}\n\nfunction getImageLoadingStatus(image: HTMLImageElement) {\n return image.complete ? (image.naturalWidth > 0 ? 'loaded' : 'error') : 'loading';\n}\n\n// Image count is only used in development to warn about multiple images, which\n// is unsupported. Gating behind a development flag to avoid performance\n// overhead in production is safe because useState is guaranteed to run\n// consistently in the same environment.\n// oxlint-disable react-hooks/rules-of-hooks\nfunction useImageCount() {\n let state = STATIC_IMAGE_COUNT_STATE;\n if (process.env.NODE_ENV !== 'production') {\n state = React.useState(0);\n const [imageCount] = state;\n const hasWarnedRef = React.useRef(false);\n React.useEffect(() => {\n if (imageCount > 1 && !hasWarnedRef.current) {\n hasWarnedRef.current = true;\n console.warn(\n 'Avatar: Only one `Avatar.Image` component should be rendered per `Avatar.Root`, but multiple were detected. This will lead to unexpected behavior.',\n );\n }\n }, [imageCount]);\n }\n\n return state;\n}\n\nfunction useUpdateImageCount(setImageCount: React.Dispatch<React.SetStateAction<number>>) {\n if (process.env.NODE_ENV !== 'production') {\n React.useEffect(() => {\n setImageCount((imageCount) => imageCount + 1);\n return () => {\n setImageCount((imageCount) => imageCount - 1);\n };\n }, [setImageCount]);\n }\n}\n// oxlint-enable react-hooks/rules-of-hooks\n\nexport {\n createAvatarScope,\n //\n Avatar,\n AvatarImage,\n AvatarFallback,\n //\n Avatar as Root,\n AvatarImage as Image,\n AvatarFallback as Fallback,\n};\nexport type { AvatarProps, AvatarImageProps, AvatarFallbackProps };\n"],
5
+ "mappings": "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",
6
6
  "names": ["image"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radix-ui/react-avatar",
3
- "version": "1.2.0-rc.1781217402884",
3
+ "version": "1.2.0",
4
4
  "license": "MIT",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./dist/index.js",
@@ -11,8 +11,8 @@
11
11
  ],
12
12
  "sideEffects": false,
13
13
  "dependencies": {
14
- "@radix-ui/react-primitive": "2.1.6-rc.1781217402884",
15
14
  "@radix-ui/react-context": "1.1.4",
15
+ "@radix-ui/react-primitive": "2.1.6",
16
16
  "@radix-ui/react-use-callback-ref": "1.1.2",
17
17
  "@radix-ui/react-use-is-hydrated": "0.1.1",
18
18
  "@radix-ui/react-use-layout-effect": "1.1.2"
@@ -23,8 +23,8 @@
23
23
  "react": "^19.2.0",
24
24
  "react-dom": "^19.2.0",
25
25
  "typescript": "^5.9.3",
26
- "@repo/typescript-config": "0.0.0",
27
- "@repo/builder": "0.0.0"
26
+ "@repo/builder": "0.0.0",
27
+ "@repo/typescript-config": "0.0.0"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "@types/react": "*",