@indico-data/design-system 2.10.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.css +7 -8
- package/lib/index.d.ts +18 -13
- package/lib/index.esm.css +7 -8
- package/lib/index.esm.js +28 -28
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +28 -28
- package/lib/index.js.map +1 -1
- package/lib/src/components/forms/checkbox/Checkbox.d.ts +2 -1
- package/lib/src/components/forms/form/Form.d.ts +14 -0
- package/lib/src/components/forms/form/Form.stories.d.ts +8 -0
- package/lib/src/components/forms/input/Input.d.ts +4 -4
- package/lib/src/components/forms/passwordInput/PasswordInput.d.ts +4 -3
- package/lib/src/components/forms/radio/Radio.d.ts +2 -1
- package/lib/src/components/forms/subcomponents/DisplayFormError.d.ts +5 -0
- package/lib/src/components/forms/textarea/Textarea.d.ts +4 -3
- package/lib/src/components/forms/toggle/Toggle.d.ts +2 -1
- package/package.json +5 -2
- package/src/components/forms/checkbox/Checkbox.stories.tsx +2 -2
- package/src/components/forms/checkbox/Checkbox.tsx +32 -41
- package/src/components/forms/form/Form.mdx +134 -0
- package/src/components/forms/form/Form.stories.tsx +413 -0
- package/src/components/forms/form/Form.tsx +64 -0
- package/src/components/forms/form/__tests__/Form.test.tsx +35 -0
- package/src/components/forms/form/index.ts +0 -0
- package/src/components/forms/form/styles/Form.scss +3 -0
- package/src/components/forms/input/Input.tsx +66 -65
- package/src/components/forms/input/__tests__/Input.test.tsx +2 -13
- package/src/components/forms/input/styles/Input.scss +1 -8
- package/src/components/forms/passwordInput/PasswordInput.stories.tsx +11 -12
- package/src/components/forms/passwordInput/PasswordInput.tsx +63 -59
- package/src/components/forms/passwordInput/__tests__/PasswordInput.test.tsx +1 -1
- package/src/components/forms/radio/Radio.tsx +32 -35
- package/src/components/forms/subcomponents/DisplayFormError.tsx +7 -0
- package/src/components/forms/textarea/Textarea.stories.tsx +15 -21
- package/src/components/forms/textarea/Textarea.tsx +64 -62
- package/src/components/forms/textarea/__tests__/Textarea.test.tsx +1 -1
- package/src/components/forms/textarea/styles/Textarea.scss +1 -1
- package/src/components/forms/toggle/Toggle.tsx +30 -37
- package/src/styles/index.scss +1 -0
- package/lib/src/components/forms/subcomponents/ErrorList.d.ts +0 -6
- package/src/components/forms/subcomponents/ErrorList.tsx +0 -14
- package/src/components/forms/subcomponents/__tests__/ErrorList.test.tsx +0 -16
- /package/lib/src/components/forms/{subcomponents/__tests__/ErrorList.test.d.ts → form/__tests__/Form.test.d.ts} +0 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Label } from '../subcomponents/Label';
|
|
3
|
-
import {
|
|
3
|
+
import { DisplayFormError } from '../subcomponents/DisplayFormError';
|
|
4
4
|
|
|
5
5
|
export interface TextareaProps {
|
|
6
6
|
ref?: React.LegacyRef<HTMLTextAreaElement>;
|
|
7
7
|
label: string;
|
|
8
8
|
name: string;
|
|
9
9
|
placeholder: string;
|
|
10
|
-
value
|
|
10
|
+
value?: string | undefined;
|
|
11
11
|
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
12
12
|
isRequired?: boolean;
|
|
13
13
|
isDisabled?: boolean;
|
|
14
|
-
|
|
14
|
+
errorMessage?: string | undefined;
|
|
15
15
|
helpText?: string;
|
|
16
16
|
hasHiddenLabel?: boolean;
|
|
17
17
|
rows?: number;
|
|
@@ -21,65 +21,67 @@ export interface TextareaProps {
|
|
|
21
21
|
form?: string;
|
|
22
22
|
maxLength?: number;
|
|
23
23
|
autofocus?: boolean;
|
|
24
|
+
defaultValue?: string;
|
|
24
25
|
}
|
|
26
|
+
export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
27
|
+
(
|
|
28
|
+
{
|
|
29
|
+
label,
|
|
30
|
+
name,
|
|
31
|
+
placeholder,
|
|
32
|
+
value,
|
|
33
|
+
onChange,
|
|
34
|
+
isRequired,
|
|
35
|
+
isDisabled,
|
|
36
|
+
errorMessage,
|
|
37
|
+
helpText,
|
|
38
|
+
hasHiddenLabel,
|
|
39
|
+
rows,
|
|
40
|
+
cols,
|
|
41
|
+
readonly,
|
|
42
|
+
wrap,
|
|
43
|
+
form,
|
|
44
|
+
maxLength,
|
|
45
|
+
autofocus,
|
|
46
|
+
...rest
|
|
47
|
+
},
|
|
48
|
+
ref,
|
|
49
|
+
) => {
|
|
50
|
+
const hasErrors = errorMessage && errorMessage.length > 0;
|
|
25
51
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<Label label={label} name={name} isRequired={isRequired} hasHiddenLabel={hasHiddenLabel} />
|
|
52
|
-
<div className="textarea-wrapper">
|
|
53
|
-
<textarea
|
|
54
|
-
ref={ref}
|
|
55
|
-
rows={rows}
|
|
56
|
-
cols={cols}
|
|
57
|
-
autoFocus={autofocus}
|
|
58
|
-
wrap={wrap}
|
|
59
|
-
form={form}
|
|
60
|
-
value={value}
|
|
61
|
-
maxLength={maxLength}
|
|
62
|
-
readOnly={readonly}
|
|
63
|
-
data-testid={`form-textarea-${name}`}
|
|
64
|
-
name={name}
|
|
65
|
-
disabled={isDisabled}
|
|
66
|
-
required={isRequired}
|
|
67
|
-
placeholder={placeholder}
|
|
68
|
-
onChange={onChange}
|
|
69
|
-
className={`textarea ${hasErrors ? 'error' : ''}`}
|
|
70
|
-
aria-invalid={hasErrors}
|
|
71
|
-
aria-describedby={hasErrors || helpText ? `${name}-helper` : undefined}
|
|
72
|
-
aria-required={isRequired}
|
|
73
|
-
aria-label={label}
|
|
74
|
-
{...rest}
|
|
75
|
-
/>
|
|
76
|
-
</div>
|
|
77
|
-
{hasErrors && <ErrorList errorList={errorList} name={name} />}
|
|
78
|
-
{helpText && (
|
|
79
|
-
<div data-testid={`${name}-help-text`} className="help-text" id={`${name}-helper`}>
|
|
80
|
-
{helpText}
|
|
52
|
+
return (
|
|
53
|
+
<div className="form-control">
|
|
54
|
+
<Label label={label} name={name} isRequired={isRequired} hasHiddenLabel={hasHiddenLabel} />
|
|
55
|
+
<div className="textarea-wrapper">
|
|
56
|
+
<textarea
|
|
57
|
+
ref={ref}
|
|
58
|
+
rows={rows}
|
|
59
|
+
cols={cols}
|
|
60
|
+
autoFocus={autofocus}
|
|
61
|
+
wrap={wrap}
|
|
62
|
+
form={form}
|
|
63
|
+
maxLength={maxLength}
|
|
64
|
+
readOnly={readonly}
|
|
65
|
+
data-testid={`form-textarea-${name}`}
|
|
66
|
+
name={name}
|
|
67
|
+
disabled={isDisabled}
|
|
68
|
+
placeholder={placeholder}
|
|
69
|
+
onChange={onChange}
|
|
70
|
+
className={`textarea ${hasErrors ? 'error' : ''}`}
|
|
71
|
+
aria-invalid={hasErrors ? true : undefined}
|
|
72
|
+
aria-describedby={hasErrors || helpText ? `${name}-helper` : undefined}
|
|
73
|
+
aria-required={isRequired}
|
|
74
|
+
aria-label={label}
|
|
75
|
+
{...rest}
|
|
76
|
+
/>
|
|
81
77
|
</div>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
78
|
+
{hasErrors && <DisplayFormError message={errorMessage} />}
|
|
79
|
+
{helpText && (
|
|
80
|
+
<div data-testid={`${name}-help-text`} className="help-text" id={`${name}-helper`}>
|
|
81
|
+
{helpText}
|
|
82
|
+
</div>
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
},
|
|
87
|
+
);
|
|
@@ -25,7 +25,7 @@ describe('Textarea', () => {
|
|
|
25
25
|
render(
|
|
26
26
|
<Textarea
|
|
27
27
|
isRequired={true}
|
|
28
|
-
|
|
28
|
+
errorMessage="You require a username value."
|
|
29
29
|
label="Enter your name"
|
|
30
30
|
helpText="In order to submit the form, this field is required."
|
|
31
31
|
name="name"
|
|
@@ -9,43 +9,36 @@ export interface ToggleProps {
|
|
|
9
9
|
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
10
10
|
isDisabled?: boolean;
|
|
11
11
|
isChecked?: boolean;
|
|
12
|
+
defaultChecked?: boolean;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
export const Toggle = (
|
|
15
|
-
ref
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
aria-describedby={id}
|
|
41
|
-
aria-label={label}
|
|
42
|
-
{...rest}
|
|
43
|
-
/>
|
|
44
|
-
<label htmlFor={id} className="switch"></label>
|
|
45
|
-
<label className={'toggle-label'} htmlFor={id}>
|
|
46
|
-
{label}
|
|
47
|
-
</label>
|
|
15
|
+
export const Toggle = React.forwardRef<HTMLInputElement, ToggleProps>(
|
|
16
|
+
({ id, label, name, value, onChange, isDisabled, isChecked, ...rest }, ref) => {
|
|
17
|
+
return (
|
|
18
|
+
<div className="form-control">
|
|
19
|
+
<div className="toggle-wrapper">
|
|
20
|
+
<input
|
|
21
|
+
data-testid={`form-toggle-input-${name}`}
|
|
22
|
+
className="toggle-input"
|
|
23
|
+
type="checkbox"
|
|
24
|
+
id={id}
|
|
25
|
+
checked={isChecked}
|
|
26
|
+
name={name}
|
|
27
|
+
value={value}
|
|
28
|
+
disabled={isDisabled}
|
|
29
|
+
ref={ref}
|
|
30
|
+
onChange={onChange}
|
|
31
|
+
tabIndex={0}
|
|
32
|
+
aria-describedby={id}
|
|
33
|
+
aria-label={label}
|
|
34
|
+
{...rest}
|
|
35
|
+
/>
|
|
36
|
+
<label htmlFor={id} className="switch"></label>
|
|
37
|
+
<label className={'toggle-label'} htmlFor={id}>
|
|
38
|
+
{label}
|
|
39
|
+
</label>
|
|
40
|
+
</div>
|
|
48
41
|
</div>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
);
|
package/src/styles/index.scss
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
@import '../components/forms/checkbox/styles/Checkbox.scss';
|
|
12
12
|
@import '../components/forms/textarea/styles/Textarea.scss';
|
|
13
13
|
@import '../components/forms/passwordInput/styles/PasswordInput.scss';
|
|
14
|
+
@import '../components/forms/form/styles/Form.scss';
|
|
14
15
|
|
|
15
16
|
@import '../components/forms/toggle/styles/Toggle.scss';
|
|
16
17
|
@import 'typography';
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
interface ErrorListProps {
|
|
2
|
-
name: string;
|
|
3
|
-
errorList: string[];
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export const ErrorList = ({ errorList, name }: ErrorListProps) => {
|
|
7
|
-
return (
|
|
8
|
-
<ul className="error-list" id={`${name}-helper`}>
|
|
9
|
-
{(errorList ?? []).map((error, index) => (
|
|
10
|
-
<li key={index}>{error}</li>
|
|
11
|
-
))}
|
|
12
|
-
</ul>
|
|
13
|
-
);
|
|
14
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import { ErrorList } from '@/components/forms/subcomponents/ErrorList';
|
|
3
|
-
|
|
4
|
-
describe('ErrorList', () => {
|
|
5
|
-
it('renders the error list', () => {
|
|
6
|
-
render(<ErrorList name="name" errorList={['error1', 'error2']} />);
|
|
7
|
-
expect(screen.getByText('error1')).toBeInTheDocument();
|
|
8
|
-
expect(screen.getByText('error2')).toBeInTheDocument();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('does not render the error list when it is empty', () => {
|
|
12
|
-
render(<ErrorList name="name" errorList={[]} />);
|
|
13
|
-
expect(screen.queryByText('error1')).not.toBeInTheDocument();
|
|
14
|
-
expect(screen.queryByText('error2')).not.toBeInTheDocument();
|
|
15
|
-
});
|
|
16
|
-
});
|
|
File without changes
|