Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs-ui/stories/components/form-fields.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {action} from '@storybook/addon-actions';
import {Panel} from 'app/components/panels';
import Switch from 'app/components/switchButton';
import NewBooleanField from 'app/views/settings/components/forms/booleanField';
import CheckboxField from 'app/views/settings/components/forms/checkboxField';
import RadioGroup from 'app/views/settings/components/forms/controls/radioGroup';
import RangeSlider from 'app/views/settings/components/forms/controls/rangeSlider';
import DatePickerField from 'app/views/settings/components/forms/datePickerField';
Expand Down Expand Up @@ -153,6 +154,22 @@ export const __BooleanField = () => (

__BooleanField.storyName = 'Boolean';

export const _CheckboxField = () => (
<Form>
<CheckboxField key="agree" name="agree" id="agree" label="Do you agree?" />
<CheckboxField
key="compelled"
name="compelled"
id="compelled"
label="You are compelled to agree"
help="More content to help you decide."
required
/>
</Form>
);

_CheckboxField.storyName = 'Checkbox';

export const _DatePickerField = () => (
<Form>
<DatePickerField name="field" label="Date Picker Field" />
Expand Down
104 changes: 104 additions & 0 deletions static/app/views/settings/components/forms/checkboxField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import styled from '@emotion/styled';

import Checkbox from 'app/components/checkbox';
import space from 'app/styles/space';
import FieldDescription from 'app/views/settings/components/forms/field/fieldDescription';
import FieldHelp from 'app/views/settings/components/forms/field/fieldHelp';
import FieldLabel from 'app/views/settings/components/forms/field/fieldLabel';
import FieldRequiredBadge from 'app/views/settings/components/forms/field/fieldRequiredBadge';
import FormField from 'app/views/settings/components/forms/formField';

type FormFieldProps = Omit<
React.ComponentProps<typeof FormField>,
'help' | 'disabled' | 'required'
>;

type Props = {
/**
* The input name
*/
name: string;
/**
* User visible field label
*/
label?: React.ReactNode;
/**
* Is the field disabled?
*/
disabled?: boolean;
/**
* Is the field required?
*/
required?: boolean;
/**
* Help or description of the field
*/
help?: React.ReactNode | React.ReactElement | ((props: Props) => React.ReactNode);
/**
* The control's `id` property
*/
id?: string;
} & FormFieldProps;

function CheckboxField(props: Props) {
const {name, disabled, stacked, id, required, label, help} = props;

const helpElement = typeof help === 'function' ? help(props) : help;

return (
<FormField name={name} inline={false}>
{({onChange, value}) => {
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
const newValue = e.target.checked;
onChange?.(newValue, e);
}

return (
<FieldLayout>
<ControlWrapper>
<Checkbox
id={id}
name={name}
disabled={disabled}
checked={value === true}
onChange={handleChange}
/>
</ControlWrapper>
<FieldDescription htmlFor={id}>
{label && (
<FieldLabel disabled={disabled}>
<span>
{label}
{required && <FieldRequiredBadge />}
</span>
</FieldLabel>
)}
{helpElement && (
<FieldHelp stacked={stacked} inline>
{helpElement}
</FieldHelp>
)}
</FieldDescription>
</FieldLayout>
);
}}
</FormField>
);
}

const ControlWrapper = styled('span')`
align-self: flex-start;
display: flex;
margin-right: ${space(1)};

& input {
margin: 0;
}
`;

const FieldLayout = styled('div')`
display: flex;
flex-direction: row;
`;

export default CheckboxField;