Skip to content

Commit c3fb791

Browse files
authored
Merge pull request #21 from NHSDigital/feature/tjc-inputWidths
Fix: Input widths
2 parents 12d063b + ebad449 commit c3fb791

File tree

6 files changed

+126
-62
lines changed

6 files changed

+126
-62
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nhsuk-react-components",
3-
"version": "1.0.1",
3+
"version": "1.1.0",
44
"author": {
55
"email": "[email protected]",
66
"name": "Thomas Judd-Cooper",

src/components/date-input/DateInput.tsx

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ interface IDateInputContext {
1717
registerRef: (type: DateInputType, ref: HTMLInputElement | null) => void;
1818
name: string;
1919
autoCompletePrefix: string | undefined;
20-
error?: string;
20+
error?: string | boolean;
2121
}
2222

2323
const DateInputContext = createContext<IDateInputContext>({
@@ -123,10 +123,14 @@ type DateInputValue = {
123123
year: string;
124124
};
125125

126-
interface DateInputProps extends Omit<HTMLProps<HTMLDivElement>, 'onChange'>, FormElementProps {
126+
interface DateInputProps
127+
extends Omit<HTMLProps<HTMLDivElement>, 'onChange' | 'value' | 'defaultValue'>,
128+
FormElementProps {
127129
autoSelectNext?: boolean;
128130
onChange?: (e: DateInputEvent) => any;
129131
autoCompletePrefix?: string;
132+
value?: DateInputValue;
133+
defaultValue?: DateInputValue;
130134
}
131135

132136
type DateInputState = {
@@ -161,6 +165,8 @@ class DateInput extends PureComponent<DateInputProps, DateInputState> {
161165
};
162166

163167
onChange = (e: SyntheticEvent<HTMLInputElement>) => {
168+
e.stopPropagation();
169+
164170
const target = e.target as HTMLInputElement;
165171
const { value, name } = this.state;
166172
if (target && target.name) {
@@ -181,6 +187,7 @@ class DateInput extends PureComponent<DateInputProps, DateInputState> {
181187
target: { ...target, name, value },
182188
currentTarget: { ...target, name, value },
183189
};
190+
184191
if (this.props.onChange) {
185192
this.props.onChange(newEvent);
186193
}
@@ -211,9 +218,12 @@ class DateInput extends PureComponent<DateInputProps, DateInputState> {
211218
hint,
212219
error,
213220
label,
221+
onChange,
214222
labelProps,
215223
errorProps,
216224
hintProps,
225+
value,
226+
defaultValue,
217227
...rest
218228
} = this.props;
219229
const { name } = this.state;
@@ -245,9 +255,18 @@ class DateInput extends PureComponent<DateInputProps, DateInputState> {
245255
<DateInputContext.Provider value={contextValue}>
246256
{children || (
247257
<>
248-
<DateInput.Day />
249-
<DateInput.Month />
250-
<DateInput.Year />
258+
<DateInput.Day
259+
value={value ? value.day : undefined}
260+
defaultValue={defaultValue ? defaultValue.day : undefined}
261+
/>
262+
<DateInput.Month
263+
value={value ? value.month : undefined}
264+
defaultValue={defaultValue ? defaultValue.month : undefined}
265+
/>
266+
<DateInput.Year
267+
value={value ? value.year : undefined}
268+
defaultValue={defaultValue ? defaultValue.year : undefined}
269+
/>
251270
</>
252271
)}
253272
</DateInputContext.Provider>

src/util/types/FormTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { LabelProps } from '../../components/label/Label';
55
export interface FormElementProps {
66
label?: string;
77
labelProps?: LabelProps;
8-
error?: string;
8+
error?: string | boolean;
99
errorProps?: ErrorMessageProps;
1010
hint?: string;
1111
hintProps?: HintProps

src/util/types/NHSUKTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export type NHSUKSize = 's' | 'm' | 'l' | 'xl';
22

3-
export type InputWidth = '2' | '3' | '4' | '5' | '10';
3+
export type InputWidth = '2' | '3' | '4' | '5' | '10' | '20' | '30' | 2 | 3 | 4 | 5 | 10 | 20 | 30;
44

55
export type CareCardType = 'non-urgent' | 'urgent' | 'immediate';
66

stories/FormElementBehaviour/DateInput.stories.tsx

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,59 +5,106 @@ import { DateInput, Form } from '../../src';
55

66
const stories = storiesOf('FormElementBehaviour: DateInput', module);
77

8-
stories.add('Standard', () => (
9-
<div style={{ padding: 20 }}>
10-
<h2>Scenario: onChange and onInput handlers are bound without any other props</h2>
11-
<h5>Expected Behaviour</h5>
12-
<ul className="nhsuk-hint">
13-
<li>OnChange Handlers are fired using the generated IDs and Names</li>
14-
<li>The value is passed through</li>
15-
</ul>
16-
<h5>Component</h5>
17-
<Form>
18-
<DateInput onChange={e => console.log(e.target.value)} hint="Test hint" label="Test label" />
19-
</Form>
20-
</div>
21-
));
22-
23-
stories.add('Standard with Error', () => (
24-
<div style={{ padding: 20 }}>
25-
<h2>Scenario: onChange and onInput handlers are bound without any other props</h2>
26-
<h5>Expected Behaviour</h5>
27-
<ul className="nhsuk-hint">
28-
<li>OnChange Handlers are fired using the generated IDs and Names</li>
29-
<li>The value is passed through</li>
30-
</ul>
31-
<h5>Component</h5>
32-
<Form error>
33-
<DateInput onChange={e => console.log(e.target.value)} error="Test Error" hint="Test hint" label="Test label" />
34-
</Form>
35-
<h5>Component with specific field errors</h5>
36-
<Form error>
37-
<DateInput onChange={e => console.log(e.target.value)} error="Test Error" hint="Test hint" label="Test label">
38-
<DateInput.Day error={false} />
39-
<DateInput.Month />
40-
<DateInput.Year />
41-
</DateInput>
42-
</Form>
43-
</div>
44-
));
45-
46-
stories.add('Pre-populated', () => {
47-
const initialValue = { day: '20', month: '09', year: '1996' };
48-
return (
8+
stories
9+
.add('Standard', () => (
4910
<div style={{ padding: 20 }}>
11+
<h2>Scenario: onChange and onInput handlers are bound without any other props</h2>
12+
<h5>Expected Behaviour</h5>
13+
<ul className="nhsuk-hint">
14+
<li>OnChange Handlers are fired using the generated IDs and Names</li>
15+
<li>The value is passed through</li>
16+
</ul>
5017
<h5>Component</h5>
5118
<Form>
5219
<DateInput
20+
onChange={e => console.log(e.target.value)}
21+
hint="Test hint"
22+
label="Test label"
23+
/>
24+
</Form>
25+
</div>
26+
))
27+
.add('Standard with Error', () => (
28+
<div style={{ padding: 20 }}>
29+
<h2>Scenario: onChange and onInput handlers are bound without any other props</h2>
30+
<h5>Expected Behaviour</h5>
31+
<ul className="nhsuk-hint">
32+
<li>OnChange Handlers are fired using the generated IDs and Names</li>
33+
<li>The value is passed through</li>
34+
</ul>
35+
<h5>Component</h5>
36+
<Form error>
37+
<DateInput
38+
onChange={e => console.log(e.target.value)}
39+
error="Test Error"
40+
hint="Test hint"
41+
label="Test label"
42+
/>
43+
</Form>
44+
<h5>Component with specific field errors</h5>
45+
<Form error>
46+
<DateInput
47+
onChange={e => console.log(e.target.value)}
48+
error="Test Error"
5349
hint="Test hint"
5450
label="Test label"
5551
>
56-
<DateInput.Day value={initialValue.day} />
57-
<DateInput.Month value={initialValue.month} />
58-
<DateInput.Year value={initialValue.year} />
52+
<DateInput.Day error={false} />
53+
<DateInput.Month />
54+
<DateInput.Year />
5955
</DateInput>
6056
</Form>
6157
</div>
62-
);
63-
});
58+
))
59+
.add('Pre-populated (Individual Components)', () => {
60+
const defaultValue = { day: '20', month: '09', year: '1996' };
61+
return (
62+
<div style={{ padding: 20 }}>
63+
<h5>Component</h5>
64+
<Form>
65+
<DateInput hint="Test hint" label="Test label">
66+
<DateInput.Day defaultValue={defaultValue.day} />
67+
<DateInput.Month defaultValue={defaultValue.month} />
68+
<DateInput.Year defaultValue={defaultValue.year} />
69+
</DateInput>
70+
</Form>
71+
</div>
72+
);
73+
})
74+
.add('Pre-populated (Wrapper)', () => {
75+
const defaultValue = { day: '20', month: '09', year: '1996' };
76+
return (
77+
<div style={{ padding: 20 }}>
78+
<h5>Component</h5>
79+
<Form>
80+
<DateInput hint="Test hint" label="Test label" defaultValue={defaultValue} />
81+
</Form>
82+
</div>
83+
);
84+
})
85+
.add('Controlled Element (Individual Components)', () => {
86+
const value = { day: '20', month: '09', year: '1996' };
87+
return (
88+
<div style={{ padding: 20 }}>
89+
<h5>Component</h5>
90+
<Form>
91+
<DateInput hint="Test hint" label="Test label">
92+
<DateInput.Day value={value.day} />
93+
<DateInput.Month value={value.month} />
94+
<DateInput.Year value={value.year} />
95+
</DateInput>
96+
</Form>
97+
</div>
98+
);
99+
})
100+
.add('Controlled Element (Wrapper)', () => {
101+
const value = { day: '20', month: '09', year: '1996' };
102+
return (
103+
<div style={{ padding: 20 }}>
104+
<h5>Component</h5>
105+
<Form>
106+
<DateInput hint="Test hint" label="Test label" value={value} />
107+
</Form>
108+
</div>
109+
);
110+
});

stories/Input.stories.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ interface Props {
1010
disableErrorFromComponents?: boolean;
1111
}
1212

13-
const ExampleForm: FunctionComponent<Props> = (props) => {
13+
const ExampleForm: FunctionComponent<Props> = props => {
1414
const { disableErrorFromComponents } = props;
1515
const [firstName, setFirstName] = useState<string>('');
1616
const [middleName, setMiddleName] = useState<string>('');
@@ -65,7 +65,9 @@ const ExampleForm: FunctionComponent<Props> = (props) => {
6565
>
6666
Last name
6767
</Input>
68-
<Button style={{ display: 'block' }} type="submit">Submit</Button>
68+
<Button style={{ display: 'block' }} type="submit">
69+
Submit
70+
</Button>
6971
</Form>
7072
);
7173
};
@@ -120,9 +122,5 @@ stories
120122
width="10"
121123
/>
122124
))
123-
.add('Multiple Error States', () => (
124-
<ExampleForm />
125-
))
126-
.add('Form Error State Disabled', () => (
127-
<ExampleForm disableErrorFromComponents />
128-
));
125+
.add('Multiple Error States', () => <ExampleForm />)
126+
.add('Form Error State Disabled', () => <ExampleForm disableErrorFromComponents />);

0 commit comments

Comments
 (0)