featureBadge.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import * as React from 'react';
  2. import {withTheme} from '@emotion/react';
  3. import styled from '@emotion/styled';
  4. import CircleIndicator from 'app/components/circleIndicator';
  5. import Tag from 'app/components/tagDeprecated';
  6. import Tooltip from 'app/components/tooltip';
  7. import {t} from 'app/locale';
  8. import space from 'app/styles/space';
  9. import {Theme} from 'app/utils/theme';
  10. type BadgeProps = {
  11. type: 'alpha' | 'beta' | 'new';
  12. theme: Theme;
  13. variant?: 'indicator' | 'badge';
  14. title?: string;
  15. noTooltip?: boolean;
  16. };
  17. type Props = Omit<React.HTMLAttributes<HTMLDivElement>, keyof BadgeProps> & BadgeProps;
  18. const defaultTitles = {
  19. alpha: t('This feature is in alpha and may be unstable'),
  20. beta: t('This feature is in beta and may change in the future'),
  21. new: t('This is a new feature'),
  22. };
  23. const labels = {
  24. alpha: t('alpha'),
  25. beta: t('beta'),
  26. new: t('new'),
  27. };
  28. const FeaturedBadge = ({
  29. type,
  30. variant = 'badge',
  31. title,
  32. theme,
  33. noTooltip,
  34. ...p
  35. }: Props) => (
  36. <div {...p}>
  37. <Tooltip title={title ?? defaultTitles[type]} disabled={noTooltip} position="right">
  38. <React.Fragment>
  39. {variant === 'badge' && <StyledTag priority={type}>{labels[type]}</StyledTag>}
  40. {variant === 'indicator' && (
  41. <CircleIndicator color={theme.badge[type].indicatorColor} size={8} />
  42. )}
  43. </React.Fragment>
  44. </Tooltip>
  45. </div>
  46. );
  47. const StyledTag = styled(Tag)`
  48. padding: 3px ${space(0.75)};
  49. `;
  50. const StyledFeatureBadge = styled(withTheme(FeaturedBadge))`
  51. display: inline-flex;
  52. align-items: center;
  53. margin-left: ${space(0.75)};
  54. position: relative;
  55. top: -1px;
  56. `;
  57. export default StyledFeatureBadge;