multipleCheckbox.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import {Component} from 'react';
  2. import styled from '@emotion/styled';
  3. import {Choices} from 'sentry/types';
  4. import {defined} from 'sentry/utils';
  5. const MultipleCheckboxWrapper = styled('div')`
  6. display: flex;
  7. flex-wrap: wrap;
  8. `;
  9. const Label = styled('label')`
  10. font-weight: normal;
  11. white-space: nowrap;
  12. margin-right: 10px;
  13. margin-bottom: 10px;
  14. width: 20%;
  15. `;
  16. const CheckboxLabel = styled('span')`
  17. margin-left: 3px;
  18. `;
  19. type SelectedValue = (string | number)[];
  20. type Props = {
  21. choices: Choices;
  22. value: (string | number)[];
  23. disabled?: boolean;
  24. onChange?: (value: SelectedValue, event: React.ChangeEvent<HTMLInputElement>) => void;
  25. };
  26. class MultipleCheckbox extends Component<Props> {
  27. onChange = (selectedValue: string | number, e: React.ChangeEvent<HTMLInputElement>) => {
  28. const {value, onChange} = this.props;
  29. let newValue: SelectedValue = [];
  30. if (typeof onChange !== 'function') {
  31. return;
  32. }
  33. if (e.target.checked) {
  34. newValue = value ? [...value, selectedValue] : [value];
  35. } else {
  36. newValue = value.filter(v => v !== selectedValue);
  37. }
  38. onChange(newValue, e);
  39. };
  40. render() {
  41. const {disabled, choices, value} = this.props;
  42. return (
  43. <MultipleCheckboxWrapper>
  44. {choices.map(([choiceValue, choiceLabel]) => (
  45. <LabelContainer key={choiceValue}>
  46. <Label>
  47. <input
  48. type="checkbox"
  49. value={choiceValue}
  50. onChange={this.onChange.bind(this, choiceValue)}
  51. disabled={disabled}
  52. checked={defined(value) && value.indexOf(choiceValue) !== -1}
  53. />
  54. <CheckboxLabel>{choiceLabel}</CheckboxLabel>
  55. </Label>
  56. </LabelContainer>
  57. ))}
  58. </MultipleCheckboxWrapper>
  59. );
  60. }
  61. }
  62. export default MultipleCheckbox;
  63. const LabelContainer = styled('div')`
  64. width: 100%;
  65. @media (min-width: ${p => p.theme.breakpoints.small}) {
  66. width: 50%;
  67. }
  68. @media (min-width: ${p => p.theme.breakpoints.medium}) {
  69. width: 33.333%;
  70. }
  71. @media (min-width: ${p => p.theme.breakpoints.large}) {
  72. width: 25%;
  73. }
  74. `;