globalSelectionHeaderRow.tsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import React from 'react';
  2. import styled from '@emotion/styled';
  3. import CheckboxFancy from 'app/components/checkboxFancy/checkboxFancy';
  4. import space from 'app/styles/space';
  5. const defaultProps = {
  6. /**
  7. * This is a render prop which may be used to augment the checkbox rendered
  8. * to the right of the row. It will receive the default `checkbox` as a
  9. * prop along with the `checked` boolean.
  10. */
  11. renderCheckbox: (({checkbox}) => checkbox) as (options: {
  12. checkbox: React.ReactNode;
  13. checked?: boolean;
  14. }) => React.ReactNode,
  15. multi: true,
  16. };
  17. type Props = {
  18. checked: boolean;
  19. onCheckClick: (event: React.MouseEvent) => void;
  20. children: React.ReactNode;
  21. } & typeof defaultProps;
  22. class GlobalSelectionHeaderRow extends React.Component<Props> {
  23. static defaultProps = defaultProps;
  24. render() {
  25. const {checked, onCheckClick, multi, renderCheckbox, children, ...props} = this.props;
  26. const checkbox = <CheckboxFancy isDisabled={!multi} isChecked={checked} />;
  27. return (
  28. <Container isChecked={checked} {...props}>
  29. <Content multi={multi}>{children}</Content>
  30. <CheckboxHitbox onClick={multi ? onCheckClick : undefined}>
  31. {renderCheckbox({checkbox, checked})}
  32. </CheckboxHitbox>
  33. </Container>
  34. );
  35. }
  36. }
  37. const Container = styled('div')<{isChecked: boolean}>`
  38. display: flex;
  39. align-items: center;
  40. justify-content: space-between;
  41. font-size: 14px;
  42. font-weight: 400;
  43. padding-left: ${space(0.5)};
  44. height: ${p => p.theme.headerSelectorRowHeight}px;
  45. flex-shrink: 0;
  46. ${CheckboxFancy} {
  47. opacity: ${p => (p.isChecked ? 1 : 0.33)};
  48. }
  49. &:hover ${CheckboxFancy} {
  50. opacity: 1;
  51. }
  52. `;
  53. const Content = styled('div')<{multi: boolean}>`
  54. display: flex;
  55. flex-shrink: 1;
  56. overflow: hidden;
  57. align-items: center;
  58. height: 100%;
  59. flex-grow: 1;
  60. user-select: none;
  61. &:hover {
  62. text-decoration: ${p => (p.multi ? 'underline' : null)};
  63. color: ${p => (p.multi ? p.theme.blue300 : null)};
  64. }
  65. `;
  66. const CheckboxHitbox = styled('div')`
  67. margin: 0 -${space(1)} 0 0; /* pushes the click box to be flush with the edge of the menu */
  68. padding: 0 ${space(1.5)};
  69. height: 100%;
  70. display: flex;
  71. justify-content: flex-end;
  72. align-items: center;
  73. `;
  74. export default GlobalSelectionHeaderRow;