import * as React from 'react'; import classNames from 'classnames'; import Text from '../text/Text'; import Link from '../text/Link'; import Icon from '../icons/Icon'; import Spinner from '../spinner/Spinner'; import type {IconTypeType} from '../icons/Icon'; export type FileHandlerColorType = 'gray-20' | 'white'; export const COLORS_MAP = { 'gray-20': 'gray-20', white: 'white', } as const; type AriaStatusLabelType = { loading?: string; uploaded?: string; }; export type FileHandlerPropsType = Readonly< { /** * Specify color of the background for FileHandler * @example * text * * @default 'gray-20' */ color?: FileHandlerColorType; /** * Specify iconType to display SG icon as the image inside FileHandler * @example * text * * @default attachment */ iconType?: IconTypeType; /** * Specify thumbnailSrc of the image inside FileHandler * @example * text * */ thumbnailSrc?: string; /** * Specify src of the file to display it in the new tab when link is clicked * @example * text * */ src?: string; /** * Optional boolean for loading state of FileHandler * @example * text * * @default false */ loading?: boolean; /** * Callback, called by clicking on **close** button. If specified, button will be added automatically * @example doSomething()}> * text * */ onClose?: (arg0: React.MouseEvent) => void; /** * Callback, called by clicking on link * @example doSomething()} * > * text * */ onClick?: ( arg0: React.MouseEvent ) => unknown; /** * Additional function to set ref for text */ textRef?: { current: HTMLSpanElement | null; }; /** * Additional class names */ className?: string; /** * Children to be rendered inside FileHandler * @example * text * */ children?: React.ReactNode; /** * An accessible, short-text description of `onClose` action, * defaults to 'Close' */ ariaCloseButtonLabel?: string; /** * An accessible, short-text description for loading * and uploded status. */ statusLabel?: AriaStatusLabelType; } & Omit< React.AllHTMLAttributes, | 'color' | 'iconType' | 'thumbnailSrc' | 'src' | 'loading' | 'onClose' | 'onClick' | 'textRef' | 'className' | 'children' | 'ariaCloseButtonLabel' | 'statusLabel' > >; const FileHandler = ({ children, color = 'gray-20', iconType = 'attachment', thumbnailSrc, src, loading = false, onClose, onClick, textRef, className, ariaCloseButtonLabel = 'Close', statusLabel, ...props }: FileHandlerPropsType) => { const fileHandlerClass = classNames( 'sg-file-handler', { 'sg-file-handler--closable': onClose, [`sg-file-handler--${COLORS_MAP[color]}`]: color, }, className ); const isActionProvided = src !== undefined || onClick; const clickProps = onClick ? { onClick, } : ({ href: src, } as const); const role = clickProps.onClick && 'button'; const asLink = clickProps.onClick ? 'button' : 'a'; const thumbnail = thumbnailSrc !== undefined ? ( ) : ( ); const interactiveThumbnail = isActionProvided ? ( {thumbnail} ) : ( thumbnail ); return ( {loading ? ( ) : ( interactiveThumbnail )} {!loading && (statusLabel?.uploaded || 'uploaded')} {isActionProvided ? ( {children} ) : ( {children} )} {onClose && ( )} ); }; export default FileHandler;