UNPKG

@gravityforms/components

Version:

UI components for use in Gravity Forms development. Both React and vanilla js flavors.

195 lines (180 loc) 7 kB
import { React, classnames } from '@gravityforms/libraries'; import { useId } from '@gravityforms/react-utils'; import { spacerClasses } from '@gravityforms/utils'; import FileUpload from '../../elements/FileUpload'; import Icon from '../../elements/Icon'; import Droplist from '../Droplist'; const { forwardRef } = React; /** * @module Avatar * @description Renders an avatar component with optional file upload. * * @since 5.4.6 * * @param {React.ReactNode|React.ReactNode[]} [children] - React element children * @param {Record<string, any>} [customAttributes] - Custom attributes for the component * @param {string|string[]|Record<string, boolean>} [customClasses] - Custom classes for the component * @param {Record<string, any>} [droplistAttributes] - Custom attributes for the droplist component * @param {string|string[]|Record<string, boolean>} [droplistClasses] - Custom classes for the droplist component * @param {boolean} [hasActions=false] - Whether to show the actions droplist * @param {boolean} [hasBorder=false] - Whether the avatar has a border * @param {boolean} [hasUpload=false] - Whether to show the file upload * @param {boolean} [hideInitials=false] - Whether to hide the initials * @param {boolean} [hideLogo=false] - Whether to hide the logo * @param {boolean} [hideNoImageIcon=false] - Whether to show the no image icon in the background. * @param {Record<string, any>} [i18n] - The i18n strings for the component * @param {string} [id=''] - The ID of the component * @param {string} [imageFile=''] - The image file for the avatar * @param {string} [initials=''] - The initials for the avatar * @param {React.ComponentType} [Logo=null] - The logo component * @param {string} [noImageIcon='user'] - The icon to show when no image is present * @param {string} [noImageIconPrefix='gravity-component-icon'] - The icon prefix * @param {Record<string, any>} [selectButtonAttributes] - Custom attributes for the select button * @param {'2xs'|'xs'|'sm'|'md'|'lg'|'xl'|'2xl'} [size='lg'] - The size of the avatar * @param {string|number|string[]|Record<string, any>} [spacing=''] - The spacing for the component * @param {Record<string, any>} [uploadButtonAttributes] - Custom attributes for the upload button * @param {React.RefObject<HTMLElement>|null} ref - Ref to the component * * @return {JSX.Element} The avatar component. * * @example * import Avatar from '@gravityforms/components/react/admin/modules/Avatar'; * * return ( * <Avatar> * { 'children' } * </Avatar> * ); * */ const Avatar = forwardRef( ( { children = null, customAttributes = {}, customClasses = [], droplistAttributes = {}, droplistClasses = [], fileUploadAttributes = {}, hasActions = false, hasBorder = false, hasUpload = false, hideInitials = false, hideLogo = false, hideNoImageIcon = false, i18n = {}, id: idProp = '', imageFile = '', initials = '', Logo = null, noImageIcon = 'user', noImageIconPrefix = 'gravity-component-icon', selectButtonAttributes = {}, size = 'lg', spacing = '', uploadButtonAttributes = {}, }, ref ) => { const id = useId( idProp ); const style = {}; if ( ! hasUpload && imageFile ) { style.backgroundImage = `url(${ imageFile })`; } const avatarProps = { className: classnames( { 'gform-avatar': true, [ `gform-avatar--size-${ size }` ]: true, 'gform-avatar--has-image': imageFile.length > 0, 'gform-avatar--initials-hidden': hideInitials, 'gform-avatar--no-image-icon-hidden': hideNoImageIcon, 'gform-avatar--has-border': hasBorder, 'gform-avatar--has-upload': hasUpload, 'gform-avatar--has-actions': hasActions, ...spacerClasses( spacing ), }, customClasses ), ref, ...customAttributes, }; const avatarInnerProps = { className: 'gform-avatar__inner', style, }; const fileUploadProps = { fileURL: imageFile, uploadIcon: 'plus-regular', ...fileUploadAttributes, }; const noImageIconProps = { customClasses: [ 'gform-avatar__no-image-icon' ], icon: noImageIcon, iconPrefix: noImageIconPrefix, }; const initialsProps = { className: 'gform-avatar__initials', }; const renderLogo = () => { if ( Logo && ! hideLogo ) { return ( <div className="gform-avatar__logo"> <Logo /> </div> ); } }; const listItems = [ { key: 'upload', props: { element: 'button', iconBefore: 'upload-file', iconPrefix: 'gravity-component-icon', label: i18n?.upload || '', ...uploadButtonAttributes, }, }, { key: 'select', props: { element: 'button', iconBefore: 'photograph', iconPrefix: 'gravity-component-icon', label: i18n?.select || '', ...selectButtonAttributes, }, }, ]; const droplistProps = { align: 'left', closeOnClick: true, customClasses: classnames( [ 'gform-avatar__droplist' ], droplistClasses || [], ), listItems, width: 192, ...droplistAttributes, triggerAttributes: { ariaId: `${ id }-droplist-aria-labelledby`, ariaText: '', iconPosition: 'leading', iconPrefix: 'gravity-component-icon', icon: 'camera-plus', id: `${ id }-droplist-trigger`, label: ( imageFile ? i18n?.triggerHasImage : i18n?.triggerNoImage ) || '', size: 'size-height-s', type: 'icon-grey', ...( droplistAttributes?.triggerAttributes || {} ), }, }; return ( <div { ...avatarProps }> <div { ...avatarInnerProps }> { hasUpload && <FileUpload { ...fileUploadProps } /> } { ! imageFile && ! hideInitials && <span { ...initialsProps }>{ initials }</span> } { ! imageFile && ! hideNoImageIcon && <Icon { ...noImageIconProps } /> } { children } { renderLogo() } { hasActions && <Droplist { ...droplistProps } /> } </div> </div> ); } ); Avatar.displayName = 'Avatar'; export default Avatar;