checkboxField.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import styled from '@emotion/styled';
  2. import Checkbox from 'sentry/components/checkbox';
  3. import FieldDescription from 'sentry/components/forms/field/fieldDescription';
  4. import FieldHelp from 'sentry/components/forms/field/fieldHelp';
  5. import FieldLabel from 'sentry/components/forms/field/fieldLabel';
  6. import FieldRequiredBadge from 'sentry/components/forms/field/fieldRequiredBadge';
  7. import FormField from 'sentry/components/forms/formField';
  8. import space from 'sentry/styles/space';
  9. type FormFieldProps = Omit<
  10. React.ComponentProps<typeof FormField>,
  11. 'children' | 'help' | 'disabled' | 'required'
  12. >;
  13. type Props = {
  14. /**
  15. * The input name
  16. */
  17. name: string;
  18. /**
  19. * Is the field disabled?
  20. */
  21. disabled?: boolean;
  22. /**
  23. * Help or description of the field
  24. */
  25. help?: React.ReactNode | React.ReactElement | ((props: Props) => React.ReactNode);
  26. /**
  27. * The control's `id` property
  28. */
  29. id?: string;
  30. /**
  31. * User visible field label
  32. */
  33. label?: React.ReactNode;
  34. /**
  35. * Is the field required?
  36. */
  37. required?: boolean;
  38. } & FormFieldProps;
  39. function CheckboxField(props: Props) {
  40. const {name, disabled, stacked, id, required, label, help} = props;
  41. const helpElement = typeof help === 'function' ? help(props) : help;
  42. return (
  43. <FormField name={name} inline={false} stacked={stacked}>
  44. {({onChange, value}) => {
  45. function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
  46. const newValue = e.target.checked;
  47. onChange?.(newValue, e);
  48. }
  49. return (
  50. <FieldLayout>
  51. <ControlWrapper>
  52. <Checkbox
  53. id={id}
  54. name={name}
  55. disabled={disabled}
  56. checked={value === true}
  57. onChange={handleChange}
  58. />
  59. </ControlWrapper>
  60. <FieldDescription htmlFor={id}>
  61. {label && (
  62. <FieldLabel disabled={disabled}>
  63. <span>
  64. {label}
  65. {required && <FieldRequiredBadge />}
  66. </span>
  67. </FieldLabel>
  68. )}
  69. {helpElement && (
  70. <FieldHelp stacked={stacked} inline>
  71. {helpElement}
  72. </FieldHelp>
  73. )}
  74. </FieldDescription>
  75. </FieldLayout>
  76. );
  77. }}
  78. </FormField>
  79. );
  80. }
  81. const ControlWrapper = styled('span')`
  82. align-self: flex-start;
  83. display: flex;
  84. margin-right: ${space(1)};
  85. & input {
  86. margin: 0;
  87. }
  88. `;
  89. const FieldLayout = styled('div')`
  90. display: flex;
  91. flex-direction: row;
  92. `;
  93. export default CheckboxField;