node.tsx 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import styled from '@emotion/styled';
  2. import {IconAdd, IconSubtract} from 'sentry/icons';
  3. import {t} from 'sentry/locale';
  4. type NodeProps = {
  5. id: string;
  6. isExpanded: boolean;
  7. label: string;
  8. onExpandClick: () => void;
  9. collapsible?: boolean;
  10. isFocused?: boolean;
  11. isSelected?: boolean;
  12. };
  13. function Node({
  14. label,
  15. id,
  16. isExpanded,
  17. isFocused,
  18. onExpandClick,
  19. collapsible = false,
  20. }: NodeProps) {
  21. return (
  22. <NodeContents aria-labelledby={`${id}-title`}>
  23. <IconWrapper
  24. aria-controls={id}
  25. aria-label={isExpanded ? t('Collapse') : t('Expand')}
  26. aria-expanded={isExpanded}
  27. isExpanded={isExpanded}
  28. onClick={onExpandClick}
  29. collapsible={collapsible}
  30. >
  31. {isExpanded ? (
  32. <IconSubtract legacySize="9px" color="white" />
  33. ) : (
  34. <IconAdd legacySize="9px" color="white" />
  35. )}
  36. </IconWrapper>
  37. <NodeTitle id={`${id}-title`} focused={isFocused}>
  38. {label}
  39. </NodeTitle>
  40. </NodeContents>
  41. );
  42. }
  43. export {Node};
  44. const NodeContents = styled('div')`
  45. padding-left: 0;
  46. display: block;
  47. white-space: nowrap;
  48. `;
  49. const NodeTitle = styled('span')<{focused?: boolean}>`
  50. cursor: pointer;
  51. ${({focused, theme}) =>
  52. focused &&
  53. `
  54. color: ${theme.white};
  55. `}
  56. `;
  57. const IconWrapper = styled('button')<{collapsible: boolean; isExpanded: boolean}>`
  58. padding: 0;
  59. border-radius: 2px;
  60. display: inline-flex;
  61. visibility: ${p => (p.collapsible ? 'visible' : 'hidden')};
  62. align-items: center;
  63. justify-content: center;
  64. cursor: pointer;
  65. margin-right: 4px;
  66. ${p =>
  67. p.isExpanded
  68. ? `
  69. background: ${p.theme.gray300};
  70. border: 1px solid ${p.theme.gray300};
  71. &:hover {
  72. background: ${p.theme.gray400};
  73. }
  74. `
  75. : `
  76. background: ${p.theme.blue300};
  77. border: 1px solid ${p.theme.blue300};
  78. &:hover {
  79. background: ${p.theme.blue200};
  80. }
  81. `}
  82. `;