Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add button, checkbox, radio button components #86

Merged
merged 19 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
85ef98e
Added button, checkbox, radiobutton components. Still need to add fun…
jasnakai Mar 27, 2024
d40afd1
Added Radio Group component and updated buton and checkbox components.
jasnakai Apr 18, 2024
d051d4f
Merge branch 'main' into jn/checkbox-radio-button-components
jasnakai Apr 18, 2024
3d656f9
Fixing linting issues.
jasnakai Apr 18, 2024
344995d
Fixing another missed linting issue for checkbox.
jasnakai Apr 18, 2024
244e2fc
Merge branch 'main' into jn/checkbox-radio-button-components
jasnakai Apr 22, 2024
8b06af8
Fixed sass type.
jasnakai Apr 22, 2024
90d6c0c
Merge branch 'main' into jn/checkbox-radio-button-components
danielnaab Apr 29, 2024
3add3d0
Format components with repo's Prettier config
danielnaab Apr 30, 2024
2e81d88
Get RadioGroup working
danielnaab Apr 30, 2024
27129a7
Fix props argument on checkbox component
danielnaab Apr 30, 2024
dca641c
Remove button component
danielnaab Apr 30, 2024
4413e06
Move updated RadioGroup into Form/components directory, and wrap with…
danielnaab Apr 30, 2024
a379c5f
Move updated checkbox component into Form/components and wrap it with…
danielnaab Apr 30, 2024
b1df862
Create and wire up checkbox pattern
danielnaab Apr 30, 2024
e43fc50
Add an initial radio group pattern that limits the ability to edit op…
danielnaab Apr 30, 2024
f1ea391
Add typing for RadioGroupPattern
danielnaab Apr 30, 2024
54469aa
Fix case mismatch - CheckBox -> Checkbox
danielnaab May 1, 2024
a6f0879
Radio group "add new" option button added; rename pattern parseData t…
danielnaab May 1, 2024
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
14 changes: 14 additions & 0 deletions packages/design/src/Form/components/Checkbox/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Checkbox from './Checkbox';

export default {
component: Checkbox,
title: 'Components/Checkbox',
tags: ['autodocs'],
};

export const Primary = {
args: {
id: '1',
label: 'Primary label Text',
},
};
25 changes: 25 additions & 0 deletions packages/design/src/Form/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';

type CheckboxProps = {
id: string;
name: string;
label: string;
defaultChecked: boolean;
};

export default function Checkbox(props: CheckboxProps) {
return (
<div className="usa-checkbox">
<input
id={props.id}
name={props.name}
type="checkbox"
className="usa-checkbox__input"
defaultChecked={props.defaultChecked}
/>
<label className="usa-checkbox__label" htmlFor={props.id}>
{props.label}
</label>
</div>
);
}
19 changes: 19 additions & 0 deletions packages/design/src/Form/components/Checkbox/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';

import { type CheckboxProps } from '@atj/forms';

import { type PatternComponent } from '../../../Form';
import Checkbox from './Checkbox';

const CheckboxPattern: PatternComponent<CheckboxProps> = props => {
return (
<Checkbox
id={props.id}
defaultChecked={props.defaultChecked}
name={props.name}
label={props.label}
/>
);
};

export default CheckboxPattern;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Meta, Story } from '@storybook/react';

import RadioGroup, { RadioInput } from './RadioGroup';
import React from 'react';

export default {
title: 'Components/RadioGroup',
component: RadioGroup,
tags: ['autodocs'],
} as Meta;

const Template: Story = () => (
<RadioGroup legend="Select an item">
<RadioInput
id="option-1"
name="select-item"
defaultValue="option1"
label="Option 1"
/>
<RadioInput
id="option-2"
name="select-item"
defaultValue="option2"
label="Option 2"
/>
<RadioInput
id="option-3"
name="select-item"
defaultValue="option3"
label="Option 3"
/>
</RadioGroup>
);

export const Default = Template.bind({});
Default.args = {};
41 changes: 41 additions & 0 deletions packages/design/src/Form/components/RadioGroup/RadioGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { type ReactElement } from 'react';

type RadioGroupProps = {
legend: string;
children: ReactElement<RadioProps> | ReactElement<RadioProps>[];
};

export default function RadioGroup({ legend, children }: RadioGroupProps) {
return (
<div className="usa-fieldset">
<legend className="usa-legend">{legend}</legend>
{children}
</div>
);
}

export type RadioProps = {
id: string;
name: string;
label: string;
disabled?: boolean;
defaultChecked: boolean;
};

export const RadioInput = (props: RadioProps) => {
return (
<div className="usa-radio">
<input
id={props.id}
name={props.name}
className="usa-radio__input"
type="radio"
disabled={props.disabled}
defaultChecked={props.defaultChecked}
/>
<label htmlFor={props.id} className="usa-radio__label">
{props.label}
</label>
</div>
);
};
23 changes: 23 additions & 0 deletions packages/design/src/Form/components/RadioGroup/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';

import { type RadioGroupProps } from '@atj/forms';

import { type PatternComponent } from '../../../Form';
import RadioGroup, { RadioInput } from './RadioGroup';

const RadioGroupPattern: PatternComponent<RadioGroupProps> = props => {
return (
<RadioGroup legend={props.legend}>
{props.options.map((option, index) => (
<RadioInput
key={index}
id={option.id}
name={option.name}
label={option.label}
defaultChecked={option.defaultChecked}
></RadioInput>
))}
</RadioGroup>
);
};
export default RadioGroupPattern;
4 changes: 4 additions & 0 deletions packages/design/src/Form/components/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { type ComponentForPattern } from '..';

import Address from './Address';
import Checkbox from './Checkbox';
import Fieldset from './Fieldset';
import FormSummary from './FormSummary';
import Paragraph from './Paragraph';
import RadioGroup from './RadioGroup';
import Sequence from './Sequence';
import SubmissionConfirmation from './SubmissionConfirmation';
import TextInput from './TextInput';

export const defaultPatternComponents: ComponentForPattern = {
address: Address,
checkbox: Checkbox,
fieldset: Fieldset,
'form-summary': FormSummary,
input: TextInput,
paragraph: Paragraph,
'radio-group': RadioGroup,
sequence: Sequence,
'submission-confirmation': SubmissionConfirmation,
};
7 changes: 4 additions & 3 deletions packages/design/src/Form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ export type FormUIContext = {
uswdsRoot: `${string}/`;
};

export type ComponentForPattern<
T extends PatternProps = PatternProps<unknown>,
> = Record<string, PatternComponent<T>>;
export type ComponentForPattern<T extends PatternProps = PatternProps> = Record<
string,
PatternComponent<T>
>;

export type PatternComponent<T extends PatternProps = PatternProps<unknown>> =
React.ComponentType<
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React from 'react';

import { type CheckboxProps, type PatternId } from '@atj/forms';

import Checkbox from '../../../Form/components/Checkbox';
import { useFormManagerStore } from '../../store';
import { PatternEditComponent } from '../types';

import { PatternEditActions } from './common/PatternEditActions';
import {
PatternEditForm,
usePatternEditFormContext,
} from './common/PatternEditForm';

const CheckboxPatternEdit: PatternEditComponent<CheckboxProps> = props => {
const isSelected = useFormManagerStore(
state => state.focusedPattern?.id === props.previewProps._patternId
);
return (
<>
{isSelected ? (
<PatternEditForm
patternId={props.previewProps._patternId}
editComponent={
<CheckboxEditComponent patternId={props.previewProps._patternId} />
}
></PatternEditForm>
) : (
<Checkbox {...props.previewProps} />
)}
</>
);
};

const CheckboxEditComponent = ({ patternId }: { patternId: PatternId }) => {
const pattern = useFormManagerStore(state => state.form.patterns[patternId]);
const methods = usePatternEditFormContext();

return (
<div className="grid-row grid-gap">
<div className="tablet:grid-col-6 mobile-lg:grid-col-12">
<label className="usa-label" htmlFor={`${pattern.id}.data.label`}>
Field label
</label>
<input
className="usa-input"
id={`${pattern.id}.data.label`}
defaultValue={`${pattern.id}`}
{...methods.register(`${pattern.id}.data.label`)}
type="text"
></input>
</div>
<div className="tablet:grid-col-6 mobile-lg:grid-col-12">
<div className="usa-checkbox">
<input
id={`${pattern.id}.data.defaultChecked`}
type="checkbox"
{...methods.register(`${pattern.id}.data.defaultChecked`)}
className="usa-checkbox__input"
/>
<label
className="usa-checkbox__label"
htmlFor={`${pattern.id}.data.defaultChecked`}
>
Default field value
</label>
</div>
</div>
<div className="grid-col-12">
<PatternEditActions>
<span className="usa-checkbox">
<input
style={{ display: 'inline-block' }}
className="usa-checkbox__input"
type="checkbox"
id={`${pattern.id}.data.required`}
{...methods.register(`${pattern.id}.data.required`)}
/>
<label
style={{ display: 'inline-block' }}
className="usa-checkbox__label"
htmlFor={`${pattern.id}.data.required`}
>
Required
</label>
</span>
</PatternEditActions>
</div>
</div>
);
};

export default CheckboxPatternEdit;
Loading
Loading