settingsNavItemDeprecated.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import type {ReactElement} from 'react';
  2. import {Fragment} from 'react';
  3. import {NavLink as RouterNavLink} from 'react-router-dom';
  4. import styled from '@emotion/styled';
  5. import type {LocationDescriptor} from 'history';
  6. import Badge from 'sentry/components/badge/badge';
  7. import FeatureBadge from 'sentry/components/badge/featureBadge';
  8. import HookOrDefault from 'sentry/components/hookOrDefault';
  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 SettingsNavItemDeprecated({badge, label, index, id, to, ...props}: Props) {
  26. let renderedBadge: React.ReactNode;
  27. if (badge === 'new') {
  28. renderedBadge = <FeatureBadge type="new" />;
  29. } else if (badge === 'beta') {
  30. renderedBadge = <FeatureBadge type="beta" />;
  31. } else if (badge === 'alpha') {
  32. renderedBadge = <FeatureBadge type="alpha" />;
  33. } else if (badge === 'warning') {
  34. renderedBadge = (
  35. <Tooltip title={t('This setting needs review')} position="right">
  36. <StyledBadge text={badge} type="warning" />
  37. </Tooltip>
  38. );
  39. } else if (typeof badge === 'string' || typeof badge === 'number') {
  40. renderedBadge = <StyledBadge text={badge} />;
  41. } else {
  42. renderedBadge = badge;
  43. }
  44. return (
  45. <StyledNavItem end={index} to={locationDescriptorToTo(to)} {...props}>
  46. <LabelHook id={id}>{label}</LabelHook>
  47. {badge ? renderedBadge : null}
  48. </StyledNavItem>
  49. );
  50. }
  51. const StyledNavItem = styled(RouterNavLink)`
  52. display: block;
  53. color: ${p => p.theme.gray300};
  54. font-size: 14px;
  55. line-height: 30px;
  56. position: relative;
  57. &.active {
  58. color: ${p => p.theme.textColor};
  59. &:before {
  60. background: ${p => p.theme.active};
  61. }
  62. }
  63. &:hover,
  64. &:focus,
  65. &:active {
  66. color: ${p => p.theme.textColor};
  67. outline: none;
  68. }
  69. &:focus-visible {
  70. outline: none;
  71. background: ${p => p.theme.backgroundSecondary};
  72. padding-left: 15px;
  73. margin-left: -15px;
  74. border-radius: 3px;
  75. &:before {
  76. left: -15px;
  77. }
  78. }
  79. &:before {
  80. position: absolute;
  81. content: '';
  82. display: block;
  83. top: 4px;
  84. left: -30px;
  85. height: 20px;
  86. width: 4px;
  87. background: transparent;
  88. border-radius: 0 2px 2px 0;
  89. }
  90. `;
  91. const StyledBadge = styled(Badge)`
  92. font-weight: ${p => p.theme.fontWeightNormal};
  93. height: auto;
  94. line-height: 1;
  95. font-size: ${p => p.theme.fontSizeExtraSmall};
  96. padding: 3px ${space(0.75)};
  97. vertical-align: middle;
  98. `;
  99. export default SettingsNavItemDeprecated;