123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- import {memo} from 'react';
- import styled from '@emotion/styled';
- import space from 'sentry/styles/space';
- import {Theme} from 'sentry/utils/theme';
- type PillType = 'positive' | 'negative' | 'error';
- type Props = {
- children?: React.ReactNode;
- className?: string;
- name?: React.ReactNode;
- type?: PillType;
- value?: number | string | boolean | null;
- };
- const Pill = memo(({name, value, children, type, className}: Props) => {
- const getTypeAndValue = (): Partial<{renderValue: string; valueType: PillType}> => {
- if (value === undefined) {
- return {};
- }
- switch (value) {
- case 'true':
- case true:
- return {
- valueType: 'positive',
- renderValue: 'true',
- };
- case 'false':
- case false:
- return {
- valueType: 'negative',
- renderValue: 'false',
- };
- case null:
- case undefined:
- return {
- valueType: 'error',
- renderValue: 'n/a',
- };
- default:
- return {
- valueType: undefined,
- renderValue: String(value),
- };
- }
- };
- const {valueType, renderValue} = getTypeAndValue();
- return (
- <StyledPill type={type ?? valueType} className={className}>
- <PillName>{name}</PillName>
- <PillValue>{children ?? renderValue}</PillValue>
- </StyledPill>
- );
- });
- const getPillStyle = ({type, theme}: {theme: Theme; type?: PillType}) => {
- switch (type) {
- case 'error':
- return `
- background: ${theme.red100};
- border: 1px solid ${theme.red300};
- `;
- default:
- return `
- border: 1px solid ${theme.border};
- `;
- }
- };
- const getPillValueStyle = ({type, theme}: {theme: Theme; type?: PillType}) => {
- switch (type) {
- case 'positive':
- return `
- background: ${theme.green100};
- border: 1px solid ${theme.green300};
- border-left-color: ${theme.green300};
- font-family: ${theme.text.familyMono};
- margin: -1px;
- `;
- case 'error':
- return `
- border-left-color: ${theme.red300};
- background: ${theme.red100};
- border: 1px solid ${theme.red300};
- margin: -1px;
- `;
- case 'negative':
- return `
- border-left-color: ${theme.red300};
- background: ${theme.red100};
- border: 1px solid ${theme.red300};
- font-family: ${theme.text.familyMono};
- margin: -1px;
- `;
- default:
- return `
- background: ${theme.backgroundSecondary};
- font-family: ${theme.text.familyMono};
- `;
- }
- };
- const PillName = styled('span')`
- padding: ${space(0.5)} ${space(1)};
- min-width: 0;
- white-space: nowrap;
- display: flex;
- align-items: center;
- `;
- const PillValue = styled(PillName)`
- border-left: 1px solid ${p => p.theme.border};
- border-radius: ${p =>
- `0 ${p.theme.button.borderRadius} ${p.theme.button.borderRadius} 0`};
- max-width: 100%;
- display: flex;
- align-items: center;
- > a {
- max-width: 100%;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- display: inline-block;
- vertical-align: text-bottom;
- }
- .pill-icon,
- .external-icon {
- display: inline;
- margin: 0 0 0 ${space(1)};
- color: ${p => p.theme.gray300};
- &:hover {
- color: ${p => p.theme.textColor};
- }
- }
- `;
- const StyledPill = styled('li')<{type?: PillType}>`
- white-space: nowrap;
- margin: 0 ${space(1)} ${space(1)} 0;
- display: flex;
- border-radius: ${p => p.theme.button.borderRadius};
- box-shadow: ${p => p.theme.dropShadowLightest};
- line-height: 1.2;
- max-width: 100%;
- :last-child {
- margin-right: 0;
- }
- ${getPillStyle};
- ${PillValue} {
- ${getPillValueStyle};
- }
- `;
- export default Pill;
|