dropdownButtonV2.tsx 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import {forwardRef} from 'react';
  2. import styled from '@emotion/styled';
  3. import Button, {ButtonLabel, ButtonProps} from 'sentry/components/button';
  4. import {IconChevron} from 'sentry/icons';
  5. import space from 'sentry/styles/space';
  6. export type DropdownButtonProps = {
  7. /**
  8. * Whether or not the button should render as open
  9. */
  10. isOpen?: boolean;
  11. /**
  12. * The fixed prefix text to show in the button eg: 'Sort By'
  13. */
  14. prefix?: React.ReactNode;
  15. /**
  16. * Should a chevron icon be shown?
  17. */
  18. showChevron?: boolean;
  19. } & Omit<ButtonProps, 'type' | 'prefix'>;
  20. const DropdownButton = forwardRef<HTMLElement, DropdownButtonProps>(
  21. (
  22. {
  23. children,
  24. prefix,
  25. isOpen = false,
  26. showChevron = true,
  27. disabled = false,
  28. priority = 'form',
  29. ...props
  30. }: DropdownButtonProps,
  31. ref
  32. ) => (
  33. <StyledButton
  34. {...props}
  35. type="button"
  36. hasPrefix={!!prefix}
  37. disabled={disabled}
  38. priority={priority}
  39. isOpen={isOpen}
  40. ref={ref}
  41. >
  42. {prefix && <LabelText>{prefix}</LabelText>}
  43. {children}
  44. {showChevron && (
  45. <StyledChevron size="xs" direction={isOpen ? 'up' : 'down'} aria-hidden="true" />
  46. )}
  47. </StyledButton>
  48. )
  49. );
  50. const StyledChevron = styled(IconChevron)`
  51. margin-left: ${space(0.75)};
  52. flex-shrink: 0;
  53. `;
  54. const StyledButton = styled(Button)<
  55. Required<Pick<DropdownButtonProps, 'isOpen' | 'disabled' | 'priority'>> & {
  56. hasPrefix: boolean;
  57. }
  58. >`
  59. position: relative;
  60. max-width: 100%;
  61. z-index: 2;
  62. ${p => (p.isOpen || p.disabled) && 'box-shadow: none;'}
  63. ${p => p.hasPrefix && `${ButtonLabel} {font-weight: 400;}`}
  64. `;
  65. const LabelText = styled('span')`
  66. &:after {
  67. content: ':';
  68. }
  69. font-weight: 600;
  70. padding-right: ${space(0.75)};
  71. `;
  72. export default DropdownButton;