settingsNavItem.tsx 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import React from 'react';
  2. import {Link} from 'react-router';
  3. import styled from '@emotion/styled';
  4. import Badge from 'app/components/badge';
  5. import FeatureBadge from 'app/components/featureBadge';
  6. import HookOrDefault from 'app/components/hookOrDefault';
  7. type Props = {
  8. to: React.ComponentProps<Link>['to'];
  9. label: React.ReactNode;
  10. badge?: string | number | null;
  11. index?: boolean;
  12. id?: string;
  13. onClick?: (e: React.MouseEvent) => void;
  14. };
  15. const SettingsNavItem = ({badge, label, index, id, ...props}: Props) => {
  16. const LabelHook = HookOrDefault({
  17. hookName: 'sidebar:item-label',
  18. defaultComponent: ({children}) => <React.Fragment>{children}</React.Fragment>,
  19. });
  20. const renderedBadge =
  21. badge === 'new' ? <FeatureBadge type="new" /> : <Badge text={badge} />;
  22. return (
  23. <StyledNavItem onlyActiveOnIndex={index} activeClassName="active" {...props}>
  24. <LabelHook id={id}>{label}</LabelHook>
  25. {badge ? renderedBadge : null}
  26. </StyledNavItem>
  27. );
  28. };
  29. const StyledNavItem = styled(Link)`
  30. display: block;
  31. color: ${p => p.theme.gray300};
  32. font-size: 14px;
  33. line-height: 30px;
  34. position: relative;
  35. &.active {
  36. color: ${p => p.theme.textColor};
  37. &:before {
  38. background: ${p => p.theme.active};
  39. }
  40. }
  41. &:hover,
  42. &:focus,
  43. &:active {
  44. color: ${p => p.theme.textColor};
  45. outline: none;
  46. }
  47. &.focus-visible {
  48. outline: none;
  49. background: ${p => p.theme.backgroundSecondary};
  50. padding-left: 15px;
  51. margin-left: -15px;
  52. border-radius: 3px;
  53. &:before {
  54. left: -15px;
  55. }
  56. }
  57. &:before {
  58. position: absolute;
  59. content: '';
  60. display: block;
  61. top: 4px;
  62. left: -30px;
  63. height: 20px;
  64. width: 4px;
  65. background: transparent;
  66. border-radius: 0 2px 2px 0;
  67. }
  68. `;
  69. export default SettingsNavItem;