Skip to content

Commit 5771dc0

Browse files
committed
TCA-468 TCA-466 - fix issues with input error message
1 parent cc24e4d commit 5771dc0

File tree

4 files changed

+125
-36
lines changed

4 files changed

+125
-36
lines changed

client/src/assets/icons/warning.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from 'react';
2+
import { useTranslation } from 'react-i18next';
3+
4+
function Warning(
5+
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
6+
): JSX.Element {
7+
const { t } = useTranslation();
8+
9+
return (
10+
<svg
11+
width='10'
12+
height='9'
13+
viewBox='0 0 10 9'
14+
xmlns='http://www.w3.org/2000/svg'
15+
{...props}
16+
>
17+
<g>
18+
<title>{t('icons.fail')}</title>
19+
<path
20+
fillRule='evenodd'
21+
clipRule='evenodd'
22+
d={
23+
'M3.95423 0.859306C4.413 0.0437243 5.58725 0.0437239 6.04602 ' +
24+
'0.859306L9.3942 6.81163C9.84416 7.61155 9.2661 8.59994 8.34831 ' +
25+
'8.59994H1.65194C0.734151 8.59994 0.156094 7.61156 0.606052 ' +
26+
'6.81163L3.95423 0.859306ZM5.60007 6.80001C5.60007 7.13138 5.33144 ' +
27+
'7.40001 5.00007 7.40001C4.6687 7.40001 4.40007 7.13138 4.40007 ' +
28+
'6.80001C4.40007 6.46864 4.6687 6.20001 5.00007 6.20001C5.33144 ' +
29+
'6.20001 5.60007 6.46864 5.60007 6.80001ZM5.00007 2.00001C4.6687 ' +
30+
'2.00001 4.40007 2.26864 4.40007 2.60001V4.40001C4.40007 4.73138 ' +
31+
'4.6687 5.00001 5.00007 5.00001C5.33144 5.00001 5.60007 4.73138 ' +
32+
'5.60007 4.40001V2.60001C5.60007 2.26864 5.33144 2.00001 5.00007 ' +
33+
'2.00001Z'
34+
}
35+
fill='currentColor'
36+
/>
37+
</g>
38+
</svg>
39+
);
40+
}
41+
42+
Warning.displayName = 'Warning';
43+
44+
export default Warning;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
.input-help-box {
2+
max-width: 320px;
3+
margin-top: -11px;
4+
}
5+
6+
.input-message {
7+
font-family: 'Roboto';
8+
font-style: normal;
9+
font-weight: 400;
10+
font-size: 12px;
11+
line-height: 14px;
12+
display: flex;
13+
align-items: center;
14+
}
15+
16+
.input-message > svg {
17+
margin-right: 7px;
18+
}
19+
20+
.input-message.is-error {
21+
color: var(--tc-red-100);
22+
}
23+
24+
.input-message.is-warn {
25+
color: var(--tc-legacy-120);
26+
}

client/src/components/formHelpers/form-fields.tsx

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import {
55
FormGroup,
66
HelpBlock
77
} from '@freecodecamp/react-bootstrap';
8-
import { kebabCase } from 'lodash-es';
8+
import { kebabCase, set } from 'lodash-es';
99
import normalizeUrl from 'normalize-url';
10-
import React from 'react';
10+
import React, { Fragment, useState } from 'react';
1111
import { Field } from 'react-final-form';
1212
import { useTranslation } from 'react-i18next';
13+
import Warning from '../../assets/icons/warning';
1314
import { FormOptions } from './form';
1415
import {
1516
editorValidator,
@@ -18,6 +19,7 @@ import {
1819
fCCValidator,
1920
httpValidator
2021
} from './form-validators';
22+
import './form-field.css';
2123

2224
type FormFieldsProps = {
2325
formFields: { name: string; label: string }[];
@@ -36,6 +38,10 @@ function FormFields(props: FormFieldsProps): JSX.Element {
3638
isLocalLinkAllowed = false
3739
} = options;
3840

41+
const [blured, setBlured] = useState<boolean[]>([]);
42+
const markAsBlured = (index: number) =>
43+
setBlured(prevState => set([...prevState], index, true));
44+
3945
const nullOrWarning = (
4046
value: string,
4147
error: unknown,
@@ -59,22 +65,29 @@ function FormFields(props: FormFieldsProps): JSX.Element {
5965
const message: string = (error ||
6066
validationError ||
6167
validationWarning) as string;
68+
69+
const hasError = error || validationError;
70+
const classNames = [
71+
'input-message',
72+
hasError && 'is-error',
73+
!hasError && 'is-warn'
74+
]
75+
.filter(Boolean)
76+
.join(' ');
6277
return message ? (
63-
<HelpBlock>
64-
<Alert
65-
bsStyle={error || validationError ? 'danger' : 'info'}
66-
closeLabel={t('buttons.close')}
67-
>
78+
<HelpBlock className='input-help-box'>
79+
<div className={classNames}>
80+
<Warning />
6881
{message}
69-
</Alert>
82+
</div>
7083
</HelpBlock>
7184
) : null;
7285
};
7386
return (
7487
<>
7588
{formFields
7689
.filter(formField => !ignored.includes(formField.name))
77-
.map(({ name, label }) => (
90+
.map(({ name, label }, i) => (
7891
// TODO: verify if the value is always a string
7992
<Field key={`${kebabCase(name)}-field`} name={name}>
8093
{({ input: { value, onChange }, meta: { pristine, error } }) => {
@@ -84,33 +97,37 @@ function FormFields(props: FormFieldsProps): JSX.Element {
8497
name in placeholders ? placeholders[name] : '';
8598
const isURL = types[name] === 'url';
8699
return (
87-
<FormGroup key={key} className='embedded'>
88-
{type === 'hidden' ? null : (
89-
<ControlLabel htmlFor={key}>
90-
{label}
91-
{required.includes(name) && (
92-
<span className='required-star'>*</span>
93-
)}
94-
</ControlLabel>
95-
)}
96-
<FormControl
97-
componentClass={type === 'textarea' ? type : 'input'}
98-
id={key}
99-
name={name}
100-
onChange={onChange}
101-
placeholder={placeholder}
102-
required={required.includes(name)}
103-
rows={4}
104-
type={type}
105-
value={value as string}
106-
/>
107-
{nullOrWarning(
108-
value as string,
109-
!pristine && error,
110-
isURL,
111-
name
112-
)}
113-
</FormGroup>
100+
<Fragment key={key}>
101+
<FormGroup className='embedded'>
102+
{type === 'hidden' ? null : (
103+
<ControlLabel htmlFor={key}>
104+
{label}
105+
{required.includes(name) && (
106+
<span className='required-star'>*</span>
107+
)}
108+
</ControlLabel>
109+
)}
110+
<FormControl
111+
componentClass={type === 'textarea' ? type : 'input'}
112+
id={key}
113+
name={name}
114+
onChange={onChange}
115+
placeholder={placeholder}
116+
required={required.includes(name)}
117+
rows={4}
118+
type={type}
119+
value={value as string}
120+
onBlur={() => markAsBlured(i)}
121+
/>
122+
</FormGroup>
123+
{blured[i] &&
124+
nullOrWarning(
125+
value as string,
126+
!pristine && error,
127+
isURL,
128+
name
129+
)}
130+
</Fragment>
114131
);
115132
}}
116133
</Field>

client/src/components/layouts/variables.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
--tc-blue-140: #16679a;
4646
--tc-blue-25: #bae1f9;
4747
--tc-blue-10: #eaf6fd;
48+
--tc-red-100: #ef476f;
49+
--tc-legacy-120: #f46500;
4850
}
4951

5052
.dark-palette {

0 commit comments

Comments
 (0)