UNPKG

@primer/components

Version:
121 lines (114 loc) 4.79 kB
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import React, { forwardRef } from 'react'; import styled, { css } from 'styled-components'; import TokenBase, { isTokenInteractive } from './TokenBase'; import RemoveTokenButton from './_RemoveTokenButton'; import tinycolor from 'tinycolor2'; import { useTheme } from '../ThemeProvider'; const colorModeConfigs = { dark: { bgOpacity: 0.18, borderThreshold: 0, borderOpacity: 0.3, lightnessThreshold: 0.6 }, light: { bgOpacity: 1, borderThreshold: 0.96, borderOpacity: 1, lightnessThreshold: 0.453 } }; const tokenBorderWidthPx = 1; const StyledTokenLabel = styled(TokenBase).withConfig({ displayName: "TokenLabel__StyledTokenLabel", componentId: "sc-1bdmgzv-0" })(["background-color:", ";border-width:", "px;border-style:solid;border-color:", ";color:", ";padding-right:", ";position:relative;", ""], props => props.bgColor, tokenBorderWidthPx, props => props.borderColor, props => props.textColor, props => !props.hideRemoveButton ? 0 : undefined, props => { if (props.isSelected) { return css(["&:after{content:'';position:absolute;z-index:1;top:-2px;right:-2px;bottom:-2px;left:-2px;display:block;pointer-events:none;box-shadow:0 0 0 2px ", ";border-radius:999px;}"], props.bgColor); } }); const TokenTextContainer = styled('span').withConfig({ displayName: "TokenLabel__TokenTextContainer", componentId: "sc-1bdmgzv-1" })(["flex-grow:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"]); const TokenLabel = /*#__PURE__*/forwardRef((props, forwardedRef) => { const { as, fillColor, handleRemove, id, isSelected, ref, text, variant, hideRemoveButton, ...rest } = props; const { colorScheme } = useTheme(); const { bgOpacity, borderOpacity, borderThreshold, lightnessThreshold } = colorModeConfigs[colorScheme || 'light']; let bgColor = fillColor; let borderColor = fillColor; let textColor = '#FFF'; const perceivedLightness = tinycolor(fillColor).getLuminance(); const isFillColorLight = perceivedLightness >= lightnessThreshold; if (colorScheme === 'dark') { const lightenBy = (perceivedLightness - lightnessThreshold) * 100 * (isFillColorLight ? 1 : 0); bgColor = isSelected ? tinycolor(fillColor).setAlpha(bgOpacity * 1.2).toRgbString() : tinycolor(fillColor).setAlpha(bgOpacity).toRgbString(); textColor = isSelected ? tinycolor(fillColor).lighten(lightenBy + 10).toString() : tinycolor(fillColor).lighten(lightenBy).toString(); borderColor = isSelected ? tinycolor(fillColor).lighten(lightenBy + 5).toRgbString() : tinycolor(fillColor).lighten(lightenBy).setAlpha(borderOpacity).toRgbString(); } else { const isFillColorDark = perceivedLightness < 0.1; borderColor = perceivedLightness >= borderThreshold ? tinycolor(fillColor).darken(25).toString() : 'transparent'; if (isFillColorLight) { textColor = '#000'; } if (isSelected) { bgColor = isFillColorDark ? tinycolor(fillColor).lighten(10).toString() // TODO: darken more than 10 if the fillColor is really bright and doesn't darken well // Examples of colors that don't darken well: // - #a2eeef // - #ffd78e // - #a4f287 : tinycolor(fillColor).darken(10).toString(); } } const hasMultipleActionTargets = isTokenInteractive(props) && Boolean(handleRemove) && !hideRemoveButton; const handleRemoveClick = e => { e.stopPropagation(); handleRemove && handleRemove(); }; return /*#__PURE__*/React.createElement(StyledTokenLabel // specific to labels , _extends({ fillColor: fillColor, bgColor: bgColor, borderColor: borderColor, textColor: textColor // common token props , as: as, hideRemoveButton: hideRemoveButton || !handleRemove, handleRemove: handleRemove, id: id === null || id === void 0 ? void 0 : id.toString(), isSelected: isSelected, ref: forwardedRef, text: text, variant: variant }, rest), /*#__PURE__*/React.createElement(TokenTextContainer, null, text), !hideRemoveButton && handleRemove ? /*#__PURE__*/React.createElement(RemoveTokenButton, { borderOffset: tokenBorderWidthPx, parentTokenTag: as || 'span', tabIndex: -1, onClick: handleRemoveClick, variant: variant, "aria-hidden": hasMultipleActionTargets ? "true" : "false" }) : null); }); TokenLabel.defaultProps = { fillColor: '#999' }; export default TokenLabel;