UNPKG

@nex-ui/react

Version:

🎉 A beautiful, modern, and reliable React component library.

155 lines (151 loc) • 4.18 kB
"use client"; 'use strict'; var jsxRuntime = require('react/jsx-runtime'); var react = require('react'); var AvatarGroupContext = require('./AvatarGroupContext.cjs'); var useDefaultProps = require('../utils/useDefaultProps.cjs'); var useStyles = require('../utils/useStyles.cjs'); var useSlotClasses = require('../utils/useSlotClasses.cjs'); var useSlot = require('../utils/useSlot.cjs'); var avatar = require('../../theme/recipes/avatar.cjs'); const slots = [ 'root', 'img' ]; const useLoaded = ({ src, srcSet })=>{ const [loaded, setLoaded] = react.useState(false); react.useEffect(()=>{ if (!src && !srcSet) { return; } setLoaded(false); let active = true; const image = new Image(); image.onload = ()=>{ if (!active) { return; } setLoaded('loaded'); }; image.onerror = ()=>{ if (!active) { return; } setLoaded('error'); }; image.src = src; if (srcSet) { image.srcset = srcSet; } return ()=>{ active = false; }; }, [ src, srcSet ]); return loaded; }; const useSlotAriaProps = (ownerState)=>{ const { alt, children, loaded, 'aria-label': ariaLabel, role = 'img' } = ownerState; return react.useMemo(()=>{ let root = {}; if (loaded === false || loaded === 'error') { if (typeof children === 'string') { root = { role, 'aria-label': ariaLabel ?? children }; } else if (typeof alt === 'string') { root = { role, 'aria-label': ariaLabel ?? alt }; } } return { root }; }, [ alt, ariaLabel, children, loaded, role ]); }; const Avatar = (inProps)=>{ const props = useDefaultProps.useDefaultProps({ name: 'Avatar', props: inProps }); const groupCtx = AvatarGroupContext.useAvatarGroup(); const inGroup = !!groupCtx; const { src, alt, srcSet, slotProps, classNames, children: childrenProp, size = groupCtx?.size ?? 'md', radius = groupCtx?.radius ?? size, color = groupCtx?.color ?? 'gray', outlined = groupCtx?.outlined ?? false, ...remainingProps } = props; const loaded = useLoaded({ src, srcSet }); const ownerState = { ...props, size, radius, color, outlined, inGroup, loaded }; const styles = useStyles.useStyles({ ownerState, name: 'Avatar', recipe: avatar.avatarRecipe }); const slotClasses = useSlotClasses.useSlotClasses({ name: 'Avatar', slots, classNames }); const slotAriaProps = useSlotAriaProps(ownerState); const [AvatarRoot, getAvatarRootProps] = useSlot.useSlot({ elementType: 'div', externalForwardedProps: remainingProps, classNames: slotClasses.root, style: styles.root, a11y: slotAriaProps.root, dataAttrs: { radius, size, color, outlined, inGroup } }); const [AvatarImg, getAvatarImgProps] = useSlot.useSlot({ elementType: 'img', externalSlotProps: slotProps?.img, classNames: slotClasses.img, style: styles.img, additionalProps: { src, alt, srcSet } }); let children = null; const hasImg = src || srcSet; if (hasImg && loaded === 'loaded') { children = /*#__PURE__*/ jsxRuntime.jsx(AvatarImg, { ...getAvatarImgProps() }); } else if (childrenProp) { children = childrenProp; } else if (hasImg && alt) { [children] = alt; } return /*#__PURE__*/ jsxRuntime.jsx(AvatarRoot, { ...getAvatarRootProps(), children: children }); }; Avatar.displayName = 'Avatar'; exports.Avatar = Avatar;