toggleSidebar.tsx 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import styled from '@emotion/styled';
  2. import {Button} from 'sentry/components/button';
  3. import {IconChevron} from 'sentry/icons/iconChevron';
  4. import {t} from 'sentry/locale';
  5. import {space} from 'sentry/styles/space';
  6. import {useSyncedLocalStorageState} from 'sentry/utils/useSyncedLocalStorageState';
  7. export function ToggleSidebar({size = 'lg'}: {size?: 'lg' | 'sm'}) {
  8. const [sidebarOpen, setSidebarOpen] = useSyncedLocalStorageState(
  9. 'issue-details-sidebar-open',
  10. true
  11. );
  12. const direction = sidebarOpen ? 'right' : 'left';
  13. return (
  14. <ToggleContainer
  15. sidebarOpen={sidebarOpen}
  16. style={{paddingTop: size === 'lg' ? '4px' : '0px'}}
  17. >
  18. <ToggleButton
  19. onClick={() => setSidebarOpen(!sidebarOpen)}
  20. aria-label={sidebarOpen ? t('Close sidebar') : t('Open sidebar')}
  21. style={{height: size === 'lg' ? '30px' : '26px'}}
  22. analyticsEventKey="issue_details.sidebar_toggle"
  23. analyticsEventName="Issue Details: Sidebar Toggle"
  24. analyticsParams={{
  25. sidebar_open: !sidebarOpen,
  26. }}
  27. >
  28. <LeftChevron direction={direction} />
  29. <RightChevron direction={direction} />
  30. </ToggleButton>
  31. </ToggleContainer>
  32. );
  33. }
  34. const ToggleContainer = styled('div')<{sidebarOpen: boolean}>`
  35. width: ${p => (p.sidebarOpen ? '30px' : '50px')};
  36. position: relative;
  37. @media (max-width: ${p => p.theme.breakpoints.large}) {
  38. display: none;
  39. }
  40. `;
  41. // The extra 1px on width is to display above the sidebar border
  42. const ToggleButton = styled(Button)`
  43. border-radius: ${p => p.theme.borderRadiusLeft};
  44. border-right-color: ${p => p.theme.background} !important;
  45. box-shadow: none;
  46. position: absolute;
  47. padding: 0;
  48. left: ${space(0.5)};
  49. width: calc(100% - ${space(0.5)} + 1px);
  50. outline: 0;
  51. min-height: unset;
  52. `;
  53. const LeftChevron = styled(IconChevron)`
  54. position: absolute;
  55. color: ${p => p.theme.subText};
  56. height: 10px;
  57. width: 10px;
  58. left: ${space(0.75)};
  59. `;
  60. const RightChevron = styled(LeftChevron)`
  61. left: ${space(1.5)};
  62. `;