tagDeprecated.tsx 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import {cloneElement, isValidElement} from 'react';
  2. import styled from '@emotion/styled';
  3. import space from 'sentry/styles/space';
  4. import {Theme} from 'sentry/utils/theme';
  5. type Props = React.HTMLAttributes<HTMLDivElement> & {
  6. border?: boolean;
  7. icon?: string | React.ReactNode;
  8. inline?: boolean;
  9. priority?: keyof Theme['badge'] | keyof Theme['alert'];
  10. size?: string;
  11. };
  12. type StyleFuncProps = Props & {theme: Theme};
  13. /**
  14. * Get priority from alerts or badge styles
  15. */
  16. const getPriority = (p: StyleFuncProps) => {
  17. if (p.priority) {
  18. return p.theme.alert[p.priority] ?? p.theme.badge[p.priority] ?? null;
  19. }
  20. return null;
  21. };
  22. const getMarginLeft = (p: StyleFuncProps) =>
  23. p.inline ? `margin-left: ${p.size === 'small' ? '0.25em' : '0.5em'};` : '';
  24. const getBorder = (p: StyleFuncProps) =>
  25. p.border ? `border: 1px solid ${getPriority(p)?.border ?? p.theme.border};` : '';
  26. const Tag = styled(
  27. ({
  28. children,
  29. icon,
  30. inline: _inline,
  31. priority: _priority,
  32. size: _size,
  33. border: _border,
  34. ...props
  35. }: Props) => (
  36. <div {...props}>
  37. {icon && (
  38. <IconWrapper>
  39. {isValidElement(icon) && cloneElement(icon, {size: 'xs'})}
  40. </IconWrapper>
  41. )}
  42. {children}
  43. </div>
  44. )
  45. )`
  46. display: inline-flex;
  47. box-sizing: border-box;
  48. padding: ${p => (p.size === 'small' ? '0.1em 0.4em 0.2em' : '0.35em 0.8em 0.4em')};
  49. font-size: ${p => p.theme.fontSizeExtraSmall};
  50. line-height: 1;
  51. color: ${p => (p.priority ? p.theme.background : p.theme.textColor)};
  52. text-align: center;
  53. white-space: nowrap;
  54. vertical-align: middle;
  55. align-items: center;
  56. border-radius: ${p => (p.size === 'small' ? '0.25em' : '2em')};
  57. text-transform: lowercase;
  58. font-weight: ${p => (p.size === 'small' ? 'bold' : 'normal')};
  59. background: ${p => getPriority(p)?.background ?? p.theme.gray100};
  60. ${p => getBorder(p)};
  61. ${p => getMarginLeft(p)};
  62. `;
  63. const IconWrapper = styled('span')`
  64. margin-right: ${space(0.5)};
  65. `;
  66. export default Tag;