import { useId } from 'react'; import classnames from 'classnames'; import borderStyles from './Borders.css'; import Box from './Box'; import InternalCheckbox from './Checkbox/InternalCheckbox'; import { useColorScheme } from './contexts/ColorSchemeProvider'; import { useDefaultLabelContext } from './contexts/DefaultLabelProvider'; import focusStyles from './Focus.css'; import Icon from './Icon'; import MaybeTooltip from './sharedSubcomponents/MaybeTooltip'; import styles from './TagData.css'; import TapArea from './TapArea'; import Text from './Text'; import useFocusVisible from './useFocusVisible'; import getCheckboxColors from './utils/datavizcolors/getCheckboxColor'; import getDataVisualizationColor from './utils/datavizcolors/getDataVisualizationColor'; import useInteractiveStates from './utils/useInteractiveStates'; import { Indexable } from './zIndex'; type DataVisualizationColors = | '01' | '02' | '03' | '04' | '05' | '06' | '07' | '08' | '09' | '10' | '11' | '12' | 'neutral'; export type TileChangeHandler = (arg1: { event: | React.MouseEvent | React.KeyboardEvent | React.MouseEvent | React.KeyboardEvent; selected: boolean; id?: string; }) => void; export type OnRemoveHandler = (arg1: { event: React.MouseEvent; id?: string; }) => void; type TooltipProps = { accessibilityLabel?: string; inline?: boolean; idealDirection?: 'up' | 'right' | 'down' | 'left'; text: string | ReadonlyArray; zIndex?: Indexable; }; export type Props = { /** * If your app uses [DefaultLabelProvider](https://gestalt.pinterest.systems/web/utilities/defaultlabelprovider), a default value for this label will be used. Using this prop will override the default label value with a more specific label if desired. This populates the `aria-label` on the remove icon. */ accessibilityRemoveIconLabel?: string; /** * The default color for TagData shown in an unselected state. */ baseColor?: 'primary' | 'secondary'; /** * A color code from the [data visualization palette](https://gestalt.pinterest.systems/foundations/data_visualization/color/palette) that appears when the TagData is selected. */ color?: DataVisualizationColors; /** * Indicates if TagData should be disabled. Disabled TagDatas are inactive and cannot be interacted with. See the [disabled variant](https://gestalt.pinterest.systems/web/tagdata#disabled) to learn more. */ disabled?: boolean; /** * An identifier to be passed back in the `onTap` callback. It can be helpful to distinguish multiple TagDatas. */ id?: string; /** * Handler if the item selection state was changed with a click or a keyboard press. */ onTap?: TileChangeHandler; /** * TagData can be dismissable by the "X" affordance, which triggers the `onRemove` callback. This handler should take care of state updates to no longer render the TagData. */ onRemove?: OnRemoveHandler; /** * Controls whether the TagData is selected or not. Use it alongside the `onTap` handler. */ selected?: boolean; /** * Defines the height of the TagData to render. See the [size variant](https://gestalt.pinterest.systems.com/web/tagdata#size) to learn more. */ size?: 'sm' | 'md' | 'lg'; /** * Shows a visible checkbox when Tagdata is in a selected state. See the [group variant](https://gestalt.pinterest.systems/web/tagdata#Group) to learn more. */ showCheckbox?: boolean; /** * Short text to render inside TagData. */ text: string; /** * Adds a tooltip on hover/focus of TagData. See the [with tooltip variant](https://gestalt.pinterest.systems/web/tagdata#tooltip) to learn more. */ tooltip?: TooltipProps; }; const sizes = { sm: { fontSize: '200' }, md: { fontSize: '200' }, lg: { fontSize: '300' }, } as const; /** * [TagData](https://gestalt.pinterest.systems/web/tagdata) enables users to select multiple categories to compare with each other in a graph or chart. It contains a label and can be used as a filter for different sources. * * ![TagData light mode](https://raw.githubusercontent.com/pinterest/gestalt/master/playwright/visual-test/tagdata.spec.ts-snapshots/tagdata-chromium-darwin.png) * ![TagData dark mode](https://raw.githubusercontent.com/pinterest/gestalt/master/playwright/visual-test/tagdata-dark.spec.ts-snapshots/tagdata-dark-chromium-darwin.png) */ export default function TagData({ accessibilityRemoveIconLabel, baseColor = 'primary', color = '05', disabled = false, id, onTap, onRemove, selected, showCheckbox, size = 'md', text, tooltip, }: Props) { const { accessibilityRemoveIconLabel: accessibilityRemoveIconLabelDefault } = useDefaultLabelContext('TagData'); const { colorSchemeName } = useColorScheme(); const borderColor = getDataVisualizationColor(colorSchemeName, color); const bgColor = getDataVisualizationColor(colorSchemeName, color, { lighten: true }); const fgColor = disabled ? 'subtle' : 'default'; const colorStyles: { borderColor?: string; backgroundColor?: string; } = { borderColor, backgroundColor: bgColor, }; const { handleOnBlur, handleOnMouseEnter, handleOnMouseLeave, isHovered } = useInteractiveStates(); const isFocusVisible = useFocusVisible(); const getTagClasses = () => classnames(borderStyles.solid, borderStyles.transparentBorder, { [styles.tagLarge]: size === 'lg', [styles.tagMedium]: size === 'md', [styles.tagSmall]: size === 'sm', [styles.primary]: baseColor === 'primary', [styles.secondary]: baseColor === 'secondary', [styles.hovered]: isHovered, [styles.disabled]: disabled, [styles.tagWrapperRounded]: true, }); const getRemoveIconClasses = () => classnames( borderStyles.solid, borderStyles.transparentBorder, styles.dismissButton, styles.dismissButtonRounding, styles.dismissButtonPosition, { [styles.primary]: baseColor === 'primary', [styles.secondary]: baseColor === 'secondary', [styles.disabled]: disabled, [styles.dismissHovered]: isHovered, [focusStyles.hideOutline]: !isFocusVisible, [focusStyles.accessibilityOutline]: isFocusVisible, }, ); const checkboxId = useId(); const tileStyle = selected && !disabled ? colorStyles : {}; const checkBoxStyle = getCheckboxColors({ state: { hovered: isHovered, selected: !!selected, disabled }, colorStyles, opts: { showByDefault: true, }, }); return ( onTap?.({ event, id, selected: !selected })} role="button" rounding={2} >
{showCheckbox && ( )} {text}
{onRemove && ( )}
); } TagData.displayName = 'TagData';