settingsNavItem.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import type {ReactElement} from 'react';
  2. import {Fragment} from 'react';
  3. import styled from '@emotion/styled';
  4. import type {LocationDescriptor} from 'history';
  5. import Badge from 'sentry/components/badge/badge';
  6. import FeatureBadge from 'sentry/components/badge/featureBadge';
  7. import HookOrDefault from 'sentry/components/hookOrDefault';
  8. import {SecondaryNav} from 'sentry/components/nav/secondary';
  9. import {Tooltip} from 'sentry/components/tooltip';
  10. import {t} from 'sentry/locale';
  11. import {space} from 'sentry/styles/space';
  12. import {locationDescriptorToTo} from 'sentry/utils/reactRouter6Compat/location';
  13. type Props = {
  14. label: React.ReactNode;
  15. to: LocationDescriptor;
  16. badge?: string | number | null | ReactElement;
  17. id?: string;
  18. index?: boolean;
  19. onClick?: (e: React.MouseEvent) => void;
  20. };
  21. const LabelHook = HookOrDefault({
  22. hookName: 'sidebar:item-label',
  23. defaultComponent: ({children}) => <Fragment>{children}</Fragment>,
  24. });
  25. function SettingsNavBadge({badge}: {badge: string | number | null | ReactElement}) {
  26. if (badge === 'new') {
  27. return <FeatureBadge type="new" />;
  28. }
  29. if (badge === 'beta') {
  30. return <FeatureBadge type="beta" />;
  31. }
  32. if (badge === 'warning') {
  33. return (
  34. <Tooltip title={t('This setting needs review')} position="right">
  35. <StyledBadge text={badge} type="warning" />
  36. </Tooltip>
  37. );
  38. }
  39. if (typeof badge === 'string' || typeof badge === 'number') {
  40. return <StyledBadge text={badge} />;
  41. }
  42. return badge;
  43. }
  44. function SettingsNavItem({badge, label, id, to, ...props}: Props) {
  45. // TODO(malwilley): Support `end` prop in `SecondaryNav.Item`
  46. return (
  47. <SecondaryNav.Item to={locationDescriptorToTo(to)} {...props}>
  48. <LabelHook id={id}>{label}</LabelHook>
  49. {badge ? <SettingsNavBadge badge={badge} /> : null}
  50. </SecondaryNav.Item>
  51. );
  52. }
  53. const StyledBadge = styled(Badge)`
  54. font-weight: ${p => p.theme.fontWeightNormal};
  55. height: auto;
  56. line-height: 1;
  57. font-size: ${p => p.theme.fontSizeExtraSmall};
  58. padding: 3px ${space(0.75)};
  59. vertical-align: middle;
  60. `;
  61. export default SettingsNavItem;