section.tsx 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import styled from '@emotion/styled';
  2. import {useMenuSection} from '@react-aria/menu';
  3. import {Node} from '@react-types/shared';
  4. import {space} from 'sentry/styles/space';
  5. import {MenuItemProps} from './item';
  6. type DropdownMenuSectionProps = {
  7. children: React.ReactNode;
  8. node: Node<MenuItemProps>;
  9. };
  10. /**
  11. * A wrapper component for menu sections. See:
  12. * https://react-spectrum.adobe.com/react-aria/useMenu.html
  13. */
  14. function DropdownMenuSection({node, children}: DropdownMenuSectionProps) {
  15. const {itemProps, headingProps, groupProps} = useMenuSection({
  16. heading: node.rendered,
  17. 'aria-label': node['aria-label'],
  18. });
  19. return (
  20. <DropdownMenuSectionWrap {...itemProps}>
  21. {node.rendered && <Heading {...headingProps}>{node.rendered}</Heading>}
  22. <Group {...groupProps}>{children}</Group>
  23. </DropdownMenuSectionWrap>
  24. );
  25. }
  26. export default DropdownMenuSection;
  27. const DropdownMenuSectionWrap = styled('li')`
  28. list-style-type: none;
  29. `;
  30. const Heading = styled('span')`
  31. display: inline-block;
  32. font-weight: 600;
  33. font-size: ${p => p.theme.fontSizeSmall};
  34. color: ${p => p.theme.subText};
  35. text-transform: uppercase;
  36. white-space: nowrap;
  37. margin: ${space(1)} ${space(1.5)} ${space(0.5)};
  38. padding-right: ${space(1)};
  39. ${DropdownMenuSectionWrap}:first-of-type & {
  40. margin-top: ${space(0.5)};
  41. }
  42. `;
  43. const Group = styled('ul')`
  44. list-style-type: none;
  45. padding: 0;
  46. margin: 0;
  47. `;