import * as React from 'react'; import classNames from 'classnames'; import Text, {TEXT_COLOR} from '../text/Text'; import Icon, {TYPE as ICON_TYPE, ICON_COLOR} from '../icons/Icon'; import type {IconTypeType} from '../icons/Icon'; import {__DEV__, invariant} from '../utils'; export type LabelColorType = | 'blue' | 'green' | 'indigo' | 'red' | 'yellow' | 'gray' | 'achromatic'; export type LabelType = | 'default' | 'solid' | 'transparent' | 'transparent-color'; export const LABEL_TYPE = { DEFAULT: 'default', SOLID: 'solid', TRANSPARENT: 'transparent', TRANSPARENT_COLOR: 'transparent-color', } as const; export const COLORS_SOLID_MAP = { blue: 'blue-60', green: 'green-60', indigo: 'indigo-60', red: 'red-60', yellow: 'yellow-40', gray: 'gray-40', achromatic: 'black', } as const; const SOLID_COLOR_TEXT_MAP = { blue: 'text-white', green: 'text-white', indigo: 'text-white', red: 'text-white', yellow: 'text-black', gray: 'text-black', achromatic: 'text-white', } as const; const SOLID_ICON_COLOR_MAP = { blue: 'icon-white', green: 'icon-white', indigo: 'icon-white', red: 'icon-white', yellow: 'icon-black', gray: 'icon-black', achromatic: 'icon-white', } as const; export const COLORS_DEFAULT_MAP = { blue: 'blue-20', green: 'green-20', indigo: 'indigo-20', red: 'red-20', yellow: 'yellow-20', gray: 'gray-20', achromatic: 'white', } as const; const TRANSPARENT_COLOR_TEXT_MAP = { blue: 'text-blue-60', green: 'text-green-60', indigo: 'text-indigo-60', red: 'text-red-60', yellow: 'text-yellow-60', gray: 'text-gray-60', achromatic: 'text-black', } as const; const TRANSPARENT_ICON_COLOR_MAP = { blue: 'icon-blue-50', green: 'icon-green-50', indigo: 'icon-indigo-50', red: 'icon-red-50', yellow: 'icon-yellow-50', gray: 'icon-gray-50', achromatic: 'icon-black', } as const; export const LABEL_COLORS_SET = { BLUE: 'blue', GREEN: 'green', INDIGO: 'indigo', RED: 'red', YELLOW: 'yellow', GRAY: 'gray', ACHROMATIC: 'achromatic', } as const; export type LabelPropsType = Readonly< { /** * Specify type of label * @example * @see type="default" https://styleguide.brainly.com/latest/docs/interactive.html?type="default"#labels * @see type="solid" https://styleguide.brainly.com/latest/docs/interactive.html?type="solid"#labels * @see type="transparent" https://styleguide.brainly.com/latest/docs/interactive.html?type="transparent"#labels * @see type="transparent-color" https://styleguide.brainly.com/latest/docs/interactive.html?type="transparent-color"#labels */ type?: LabelType; /** * Specify color for label * @example * @see color="blue" https://styleguide.brainly.com/latest/docs/interactive.html?color="blue"#labels * @see color="green" https://styleguide.brainly.com/latest/docs/interactive.html?color="green"#labels * @see color="indigo" https://styleguide.brainly.com/latest/docs/interactive.html?color="indigo"#labels * @see color="red" https://styleguide.brainly.com/latest/docs/interactive.html?color="red"#labels * @see color="yellow" https://styleguide.brainly.com/latest/docs/interactive.html?color="yellow"#labels * @see color="gray" https://styleguide.brainly.com/latest/docs/interactive.html?color="gray"#labels * @see color="achromatic" https://styleguide.brainly.com/latest/docs/interactive.html?color="achromatic"#labels */ color?: LabelColorType; /** * Icons types example, see more in SG interactive * @example * @see type="iconType" https://styleguide.brainly.com/latest/docs/interactive.html?iconType=heart#labels */ iconType?: IconTypeType; /** * Callback, called by clicking on **close** button. If specified, button will be added automatically * @example */ onClose?: | ((arg0: React.SyntheticEvent) => void) | null | undefined; /** * Children to be rendered inside Label * @example */ children: React.ReactNode; /** * Additional class names */ className?: string; /** * Accessible label for **close** button */ closeButtonLabel?: string; /** * Accessible title for an icon */ iconTitle?: string; /** * Hiding icon from accessibility tree */ iconAriaHidden?: boolean; } & Omit< React.AllHTMLAttributes, | 'type' | 'color' | 'iconType' | 'onClose' | 'children' | 'className' | 'closeButtonLabel' | 'iconTitle' | 'iconAriaHidden' > >; const Label = ({ children, type = 'default', iconType, onClose, color = 'achromatic', className, closeButtonLabel, iconTitle, iconAriaHidden, ...props }: LabelPropsType) => { if (__DEV__) { invariant( !(!iconType && (iconAriaHidden || iconTitle)), 'You cannot hide an icon or name it, when `iconType` s not provided' ); invariant( !(!onClose && closeButtonLabel), // eslint-disable-next-line max-len 'Button is not rendered when `onClose` is not defined, so it cannot be named' ); } const backgroundColor = type === 'default' ? COLORS_DEFAULT_MAP[color] : COLORS_SOLID_MAP[color]; const labelClass = classNames( 'sg-label', { [`sg-label--${String(backgroundColor)}`]: backgroundColor && (type === 'solid' || type === 'default'), 'sg-label--closable': onClose, 'sg-label--transparent': type === 'transparent' || type === 'transparent-color', }, className ); const textColor = type === 'default' || type === 'transparent' ? TEXT_COLOR['text-black'] : type === 'solid' ? SOLID_COLOR_TEXT_MAP[color] : TRANSPARENT_COLOR_TEXT_MAP[color]; const iconColor = type === 'default' ? ICON_COLOR['icon-black'] : type === 'solid' ? SOLID_ICON_COLOR_MAP[color] : TRANSPARENT_ICON_COLOR_MAP[color]; const closeIconColor = type === 'default' || type === 'transparent' ? ICON_COLOR['icon-black'] : type === 'solid' ? SOLID_ICON_COLOR_MAP[color] : TRANSPARENT_ICON_COLOR_MAP[color]; return (
{iconType && (
)} {children} {onClose ? ( ) : null}
); }; export default Label; export {ICON_TYPE};