Skip to content

Commit 9df657d

Browse files
committed
fix(inline-control-group): v. spacing of child items remove value prop
- Adjust the vertical spacing on inline control group items, so that we don't leave space below last child item - Remove the unused value prop and it's prop types
1 parent d000a4e commit 9df657d

File tree

4 files changed

+282
-44
lines changed

4 files changed

+282
-44
lines changed

.changeset/two-humans-press.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@twilio-paste/inline-control-group': patch
3+
'@twilio-paste/core': patch
4+
---
5+
6+
[InlineControlGroup] Adjusted the vertical spacing of `children`. This change improve the handling of RadioGroup and CheckboxGroup children.

packages/paste-core/components/form/stories/form.stories.tsx

Lines changed: 174 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,150 @@
11
import * as React from 'react';
2-
import {useUIDSeed} from '@twilio-paste/uid-library';
2+
import {useUID, useUIDSeed} from '@twilio-paste/uid-library';
3+
import {Text} from '@twilio-paste/text';
34
import {Box} from '@twilio-paste/box';
4-
import {Checkbox, FormLabel, FormInput, Select, Option, Radio, FormTextArea} from '../src';
5+
import {Grid, Column} from '@twilio-paste/grid';
6+
import {Anchor} from '@twilio-paste/anchor';
7+
import {Checkbox, FormLabel, FormInput, Select, Option, Radio, FormTextArea, CheckboxGroup, RadioGroup} from '../src';
8+
import type {FormInputProps, SelectProps, FormTextAreaProps, CheckboxGroupProps, RadioGroupProps} from '../src';
9+
10+
const InputField: React.FC<Pick<FormInputProps, 'disabled' | 'hasError'>> = ({disabled, hasError}) => {
11+
const inputIDSeed = useUIDSeed();
12+
return (
13+
<>
14+
<FormLabel htmlFor={inputIDSeed('input')} disabled={disabled}>
15+
Text Input
16+
</FormLabel>
17+
<FormInput id={inputIDSeed('input')} type="text" value="" disabled={disabled} hasError={hasError} />
18+
</>
19+
);
20+
};
21+
22+
const TextareaField: React.FC<Pick<FormTextAreaProps, 'disabled' | 'hasError'>> = ({disabled, hasError}) => {
23+
const inputIDSeed = useUIDSeed();
24+
return (
25+
<>
26+
<FormLabel htmlFor={inputIDSeed('textarea')} disabled={disabled}>
27+
Textarea textarea
28+
</FormLabel>
29+
<FormTextArea id={inputIDSeed('textarea')} value="" disabled={disabled} hasError={hasError} />
30+
</>
31+
);
32+
};
33+
34+
const SelectField: React.FC<Pick<SelectProps, 'disabled' | 'hasError'>> = ({disabled, hasError}) => {
35+
const inputIDSeed = useUIDSeed();
36+
return (
37+
<>
38+
<FormLabel htmlFor={inputIDSeed('select')} disabled={disabled}>
39+
Select Input
40+
</FormLabel>
41+
<Select id={inputIDSeed('select')} value="" onChange={() => {}} disabled={disabled} hasError={hasError}>
42+
<Option value="1">Option</Option>
43+
</Select>
44+
</>
45+
);
46+
};
47+
48+
const CheckboxGroupField: React.FC<Pick<CheckboxGroupProps, 'orientation' | 'errorText'>> = ({
49+
orientation,
50+
errorText,
51+
}) => {
52+
const [checked1, setChecked1] = React.useState(true);
53+
const [checked2, setChecked2] = React.useState(false);
54+
const [checked3, setChecked3] = React.useState(true);
55+
return (
56+
<CheckboxGroup
57+
name="bar"
58+
legend={
59+
<Text as="span" color="currentColor">
60+
This is some help text with a <Anchor href="http://paste.twilio.com">link</Anchor>.
61+
</Text>
62+
}
63+
helpText="Help text should go here."
64+
orientation={orientation}
65+
errorText={errorText}
66+
required
67+
>
68+
<Checkbox
69+
id={useUID()}
70+
value="1"
71+
checked={checked1}
72+
onChange={(event) => {
73+
setChecked1(event.currentTarget.checked);
74+
}}
75+
helpText={
76+
<Text as="span" color="currentColor">
77+
This is some help text with a <Anchor href="http://paste.twilio.com">link</Anchor>.
78+
</Text>
79+
}
80+
>
81+
First
82+
</Checkbox>
83+
<Checkbox
84+
checked={checked2}
85+
onChange={(event) => {
86+
setChecked2(event.currentTarget.checked);
87+
}}
88+
id={useUID()}
89+
value="2"
90+
helpText="This is some help text."
91+
>
92+
Second
93+
</Checkbox>
94+
<Checkbox
95+
checked={checked3}
96+
onChange={(event) => {
97+
setChecked3(event.currentTarget.checked);
98+
}}
99+
id={useUID()}
100+
value="3"
101+
helpText="This is some help text."
102+
>
103+
Third
104+
</Checkbox>
105+
</CheckboxGroup>
106+
);
107+
};
108+
109+
const RadioGroupField: React.FC<Pick<RadioGroupProps, 'orientation' | 'errorText'>> = ({orientation, errorText}) => {
110+
const [value, setValue] = React.useState('2');
111+
return (
112+
<RadioGroup
113+
name="bar"
114+
value={value}
115+
legend={
116+
<Text as="span" color="currentColor">
117+
This is some help text with a <Anchor href="http://paste.twilio.com">link</Anchor>.
118+
</Text>
119+
}
120+
helpText="Help text should go here."
121+
required
122+
errorText={errorText}
123+
orientation={orientation}
124+
onChange={(newValue) => {
125+
setValue(newValue);
126+
}}
127+
>
128+
<Radio
129+
id={useUID()}
130+
value="1"
131+
helpText={
132+
<Text as="span" color="currentColor">
133+
This is some legend text with a <Anchor href="http://paste.twilio.com">link</Anchor>.
134+
</Text>
135+
}
136+
>
137+
First
138+
</Radio>
139+
<Radio id={useUID()} value="2" helpText="This is some help text.">
140+
Second
141+
</Radio>
142+
<Radio id={useUID()} value="3" helpText="This is some help text.">
143+
Third
144+
</Radio>
145+
</RadioGroup>
146+
);
147+
};
5148

6149
// eslint-disable-next-line import/no-default-export
7150
export default {
@@ -13,14 +156,19 @@ export const All = (): React.ReactNode => {
13156
return (
14157
<>
15158
<Box marginBottom="space70">
16-
<FormLabel htmlFor={inputIDSeed('input')}>Text Input</FormLabel>
17-
<FormInput id={inputIDSeed('input')} type="text" value="" />
18-
<FormLabel htmlFor={inputIDSeed('textarea')}>Textarea textarea</FormLabel>
19-
<FormTextArea id={inputIDSeed('textarea')} value="" />
20-
<FormLabel htmlFor={inputIDSeed('select')}>Select Input</FormLabel>
21-
<Select id={inputIDSeed('select')} value="" onChange={() => {}}>
22-
<Option value="1">Option</Option>
23-
</Select>
159+
<InputField />
160+
<Grid>
161+
<Column>
162+
<CheckboxGroupField />
163+
</Column>
164+
<Column>
165+
<RadioGroupField />
166+
</Column>
167+
</Grid>
168+
<TextareaField />
169+
<CheckboxGroupField orientation="horizontal" />
170+
<RadioGroupField orientation="horizontal" />
171+
<SelectField />
24172
<Checkbox id={inputIDSeed('chcekbox1')} value="1" name="foo">
25173
Label
26174
</Checkbox>
@@ -35,20 +183,9 @@ export const All = (): React.ReactNode => {
35183
</Radio>
36184
</Box>
37185
<Box marginBottom="space70">
38-
<FormLabel disabled htmlFor={inputIDSeed('disabledinput')}>
39-
Text Input
40-
</FormLabel>
41-
<FormInput disabled id={inputIDSeed('disabledinput')} type="text" value="" />
42-
<FormLabel disabled htmlFor={inputIDSeed('disabledtextarea')}>
43-
Textarea Input
44-
</FormLabel>
45-
<FormTextArea disabled id={inputIDSeed('disabledtextarea')} value="" />
46-
<FormLabel disabled htmlFor={inputIDSeed('disabledselect')}>
47-
Select Input
48-
</FormLabel>
49-
<Select disabled id={inputIDSeed('disabledselect')} value="" onChange={() => {}}>
50-
<Option value="1">Option</Option>
51-
</Select>
186+
<InputField disabled />
187+
<TextareaField disabled />
188+
<SelectField disabled />
52189
<Checkbox disabled id={inputIDSeed('disabledcheckbox1')} value="1" name="foo">
53190
Label
54191
</Checkbox>
@@ -63,14 +200,19 @@ export const All = (): React.ReactNode => {
63200
</Radio>
64201
</Box>
65202
<Box marginBottom="space70">
66-
<FormLabel htmlFor={inputIDSeed('errorinput')}>Text Input</FormLabel>
67-
<FormInput hasError id={inputIDSeed('errorinput')} type="text" value="" />
68-
<FormLabel htmlFor={inputIDSeed('errortextarea')}>Textarea Input</FormLabel>
69-
<FormTextArea hasError id={inputIDSeed('errortextarea')} value="" />
70-
<FormLabel htmlFor={inputIDSeed('errorselect')}>Select Input</FormLabel>
71-
<Select hasError id={inputIDSeed('errorselect')} value="" onChange={() => {}}>
72-
<Option value="1">Option</Option>
73-
</Select>
203+
<InputField hasError />
204+
<Grid>
205+
<Column>
206+
<CheckboxGroupField errorText="this is an error" />
207+
</Column>
208+
<Column>
209+
<RadioGroupField errorText="this is an error" />
210+
</Column>
211+
</Grid>
212+
<TextareaField hasError />
213+
<CheckboxGroupField orientation="horizontal" errorText="this is an error" />
214+
<RadioGroupField orientation="horizontal" errorText="this is an error" />
215+
<SelectField hasError />
74216
<Checkbox hasError id={inputIDSeed('errorcheck1')} value="1" name="foo">
75217
Label
76218
</Checkbox>

packages/paste-core/components/inline-control-group/src/InlineControlGroup.tsx

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ export interface InlineControlGroupProps extends Omit<React.FieldsetHTMLAttribut
1313
orientation?: 'vertical' | 'horizontal';
1414
ref?: any;
1515
required?: boolean;
16-
value?: string;
1716
}
1817

1918
const InlineControlGroup = React.forwardRef<HTMLFieldSetElement, InlineControlGroupProps>(
20-
({children, disabled, errorText, helpText, legend, orientation, required, value, ...props}, ref) => {
19+
({children, disabled, errorText, helpText, legend, orientation = 'vertical', required, ...props}, ref) => {
2120
return (
2221
<Box
2322
{...safelySpreadBoxProps(props)}
@@ -31,22 +30,22 @@ const InlineControlGroup = React.forwardRef<HTMLFieldSetElement, InlineControlGr
3130
{legend}
3231
</Label>
3332
{helpText && <HelpText marginTop="space0">{helpText}</HelpText>}
34-
<Box marginLeft="space20" marginRight="space20" marginTop="space40">
33+
<Box marginLeft="space20" marginRight="space20">
3534
{React.Children.map(children, (child) => {
3635
return (
3736
<Box
3837
display={orientation === 'horizontal' ? 'inline-block' : 'block'}
39-
marginBottom="space40"
38+
marginTop="space40"
4039
marginRight={orientation === 'horizontal' ? 'space70' : null}
4140
>
4241
{child}
4342
</Box>
4443
);
4544
})}
4645
{errorText && (
47-
<HelpText marginTop="space0" variant="error">
48-
{errorText}
49-
</HelpText>
46+
<Box marginTop="space40">
47+
<HelpText variant="error">{errorText}</HelpText>
48+
</Box>
5049
)}
5150
</Box>
5251
</Box>
@@ -56,10 +55,6 @@ const InlineControlGroup = React.forwardRef<HTMLFieldSetElement, InlineControlGr
5655

5756
InlineControlGroup.displayName = 'InlineControlGroup';
5857

59-
InlineControlGroup.defaultProps = {
60-
orientation: 'vertical',
61-
};
62-
6358
if (process.env.NODE_ENV === 'development') {
6459
InlineControlGroup.propTypes = {
6560
children: PropTypes.node.isRequired,
@@ -70,7 +65,6 @@ if (process.env.NODE_ENV === 'development') {
7065
name: PropTypes.string.isRequired,
7166
orientation: PropTypes.oneOf(['vertical', 'horizontal']),
7267
required: PropTypes.bool,
73-
value: PropTypes.string,
7468
};
7569
}
7670

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import * as React from 'react';
2+
import {Box} from '@twilio-paste/box';
3+
import {Grid, Column} from '@twilio-paste/grid';
4+
import {InlineControlGroup} from '../src';
5+
import type {InlineControlGroupProps} from '../src';
6+
7+
const MockChild: React.FC = ({children}) => {
8+
return <Box backgroundColor="colorBackground">{children}</Box>;
9+
};
10+
11+
const MockControlGroup: React.FC<{
12+
showRequired?: boolean;
13+
showHelpText?: boolean;
14+
showErrorText?: boolean;
15+
orientation?: InlineControlGroupProps['orientation'];
16+
}> = ({showRequired, showHelpText, showErrorText, orientation = 'vertical'}) => {
17+
return (
18+
<InlineControlGroup
19+
errorText={showErrorText && 'It can take error text'}
20+
helpText={showHelpText && 'It can take help text'}
21+
required={showRequired}
22+
orientation={orientation}
23+
legend="Inline control group is used for spacing inline controls such as checkboxes and radio groups"
24+
>
25+
<MockChild>Child 1</MockChild>
26+
<MockChild>Child 2</MockChild>
27+
<MockChild>Child 3</MockChild>
28+
</InlineControlGroup>
29+
);
30+
};
31+
32+
// eslint-disable-next-line import/no-default-export
33+
export default {
34+
title: 'Components/Inline contol group',
35+
};
36+
37+
export const Vertical = (): React.ReactNode => {
38+
return <MockControlGroup />;
39+
};
40+
41+
export const VerticalRequired = (): React.ReactNode => {
42+
return <MockControlGroup showRequired />;
43+
};
44+
45+
export const VerticalHelpText = (): React.ReactNode => {
46+
return <MockControlGroup showHelpText />;
47+
};
48+
49+
export const VerticalErrorText = (): React.ReactNode => {
50+
return <MockControlGroup showErrorText />;
51+
};
52+
53+
export const VerticalAllOptions = (): React.ReactNode => {
54+
return <MockControlGroup showRequired showErrorText showHelpText />;
55+
};
56+
57+
export const Horizontal = (): React.ReactNode => {
58+
return <MockControlGroup orientation="horizontal" />;
59+
};
60+
61+
export const HorizontalRequired = (): React.ReactNode => {
62+
return <MockControlGroup orientation="horizontal" showRequired />;
63+
};
64+
65+
export const HorizontalHelpText = (): React.ReactNode => {
66+
return <MockControlGroup orientation="horizontal" showHelpText />;
67+
};
68+
69+
export const HorizontalErrorText = (): React.ReactNode => {
70+
return <MockControlGroup orientation="horizontal" showErrorText />;
71+
};
72+
73+
export const HorizontalAllOptions = (): React.ReactNode => {
74+
return <MockControlGroup orientation="horizontal" showRequired showErrorText showHelpText />;
75+
};
76+
77+
export const ControlSpacingTest = (): React.ReactNode => {
78+
return (
79+
<Grid gutter="space40">
80+
<Column>
81+
<MockChild>Mock UI element</MockChild>
82+
<MockControlGroup showRequired showHelpText />
83+
<MockChild>Mock UI element</MockChild>
84+
<MockControlGroup orientation="horizontal" showRequired showHelpText />
85+
<MockChild>Mock UI element</MockChild>
86+
</Column>
87+
<Column>
88+
<MockChild>Mock UI element</MockChild>
89+
<MockControlGroup showRequired showErrorText showHelpText />
90+
<MockChild>Mock UI element</MockChild>
91+
<MockControlGroup orientation="horizontal" showRequired showErrorText showHelpText />
92+
<MockChild>Mock UI element</MockChild>
93+
</Column>
94+
</Grid>
95+
);
96+
};

0 commit comments

Comments
 (0)