@utrecht/component-library-react 7.0.0 → 7.2.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/CHANGELOG.md +211 -0
- package/CONTRIBUTING.md +169 -0
- package/README.md +65 -76
- package/README.nl.md +82 -0
- package/TESTING.md +203 -0
- package/dist/.jest-test-results.json +1 -1
- package/dist/Blockquote.d.ts +4 -0
- package/dist/Blockquote.d.ts.map +1 -1
- package/dist/Checkbox.d.ts +1 -0
- package/dist/Checkbox.d.ts.map +1 -1
- package/dist/ColumnLayout.d.ts.map +1 -1
- package/dist/FormFieldCheckbox.d.ts +14 -0
- package/dist/FormFieldCheckbox.d.ts.map +1 -0
- package/dist/FormFieldTextarea.d.ts +14 -0
- package/dist/FormFieldTextarea.d.ts.map +1 -0
- package/dist/Logo.d.ts +5 -3
- package/dist/Logo.d.ts.map +1 -1
- package/dist/Paragraph.d.ts +9 -0
- package/dist/Paragraph.d.ts.map +1 -1
- package/dist/Textarea.d.ts +1 -0
- package/dist/Textarea.d.ts.map +1 -1
- package/dist/css-module/Blockquote.d.ts +4 -0
- package/dist/css-module/Blockquote.d.ts.map +1 -1
- package/dist/css-module/Checkbox.d.ts +1 -0
- package/dist/css-module/Checkbox.d.ts.map +1 -1
- package/dist/css-module/ColumnLayout.d.ts.map +1 -1
- package/dist/css-module/FormFieldCheckbox.d.ts +14 -0
- package/dist/css-module/FormFieldCheckbox.d.ts.map +1 -0
- package/dist/css-module/FormFieldTextarea.d.ts +14 -0
- package/dist/css-module/FormFieldTextarea.d.ts.map +1 -0
- package/dist/css-module/Logo.d.ts +5 -3
- package/dist/css-module/Logo.d.ts.map +1 -1
- package/dist/css-module/Paragraph.d.ts +9 -0
- package/dist/css-module/Paragraph.d.ts.map +1 -1
- package/dist/css-module/Textarea.d.ts +1 -0
- package/dist/css-module/Textarea.d.ts.map +1 -1
- package/dist/css-module/css-module/Accordion.d.ts +1 -0
- package/dist/css-module/css-module/Accordion.d.ts.map +1 -1
- package/dist/css-module/css-module/Button.d.ts +1 -1
- package/dist/css-module/css-module/Button.d.ts.map +1 -1
- package/dist/css-module/css-module/FormFieldCheckbox.d.ts +10 -0
- package/dist/css-module/css-module/FormFieldCheckbox.d.ts.map +1 -0
- package/dist/css-module/css-module/FormFieldTextarea.d.ts +10 -0
- package/dist/css-module/css-module/FormFieldTextarea.d.ts.map +1 -0
- package/dist/css-module/css-module/index.d.ts +6 -2
- package/dist/css-module/css-module/index.d.ts.map +1 -1
- package/dist/css-module/index.d.ts +4 -0
- package/dist/css-module/index.d.ts.map +1 -1
- package/dist/css-module/index.js +977 -692
- package/dist/css-module/index.js.map +1 -1
- package/dist/css-module/index.mjs +975 -692
- package/dist/css-module/index.mjs.map +1 -1
- package/dist/index.cjs.js +790 -566
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +789 -567
- package/dist/index.esm.js.map +1 -1
- package/package.json +27 -26
- package/tsconfig.md +51 -0
package/TESTING.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
<!-- @license CC0-1.0 -->
|
|
2
|
+
|
|
3
|
+
# Testing components
|
|
4
|
+
|
|
5
|
+
## Test for extensibility
|
|
6
|
+
|
|
7
|
+
### Class names
|
|
8
|
+
|
|
9
|
+
Front-end developers rely on the BEM class names to add their own CSS. When the component renames or removes a class name, there is a breaking change. Unit tests must check each class name, so they are reliable APIs.
|
|
10
|
+
|
|
11
|
+
You will find many tests like this:
|
|
12
|
+
|
|
13
|
+
```jsx
|
|
14
|
+
it("renders a design system BEM class name: my-component", () => {
|
|
15
|
+
const { container } = render(<MyComponent />);
|
|
16
|
+
|
|
17
|
+
const field = container.querySelector("div");
|
|
18
|
+
|
|
19
|
+
expect(field).toHaveClass(".my-component");
|
|
20
|
+
});
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### So I put some HTML in your HTML
|
|
24
|
+
|
|
25
|
+
Text in components can sometimes be improved with markup: language metadata, code, emphasis or images. Each property that ends up in the HTML should be tested to be extensible with rich text content.
|
|
26
|
+
|
|
27
|
+
```jsx
|
|
28
|
+
it("renders rich text content", () => {
|
|
29
|
+
const { container } = render(
|
|
30
|
+
<Heading1 {...defaultProps}>
|
|
31
|
+
The French national motto: <span lang="fr">Liberté, égalité, fraternité</span>
|
|
32
|
+
</Heading1>,
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const richText = container.querySelector("span");
|
|
36
|
+
|
|
37
|
+
expect(richText).toBeInTheDocument();
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Testing properties is perhaps even more important, because `children` usually already allows HTML content:
|
|
42
|
+
|
|
43
|
+
```jsx
|
|
44
|
+
it('renders rich text content', () => {
|
|
45
|
+
const { container } = render(
|
|
46
|
+
<FormFieldTextbox label={
|
|
47
|
+
<EmailIcon/> E-mail address
|
|
48
|
+
}></FormFieldTextbox>,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const richText = container.querySelector('svg');
|
|
52
|
+
|
|
53
|
+
expect(richText).toBeInTheDocument();
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Don't break native HTML
|
|
58
|
+
|
|
59
|
+
### Global attributes
|
|
60
|
+
|
|
61
|
+
[Global attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes) can be used on all HTML elements, so components that render HTML must support them too. In React this is easy to support using `...restProps`. The following code examples use global attributes:
|
|
62
|
+
|
|
63
|
+
- `<MyComponent id="main" />`
|
|
64
|
+
- `<MyComponent style={{ '--my-component-color': 'currentColor' }} />`
|
|
65
|
+
- `<MyComponent hidden />`
|
|
66
|
+
- `<MyComponent tabIndex={-1} />`
|
|
67
|
+
- `<MyComponent lang="en" />`
|
|
68
|
+
- `<MyComponent className="custom" />`
|
|
69
|
+
- `<MyComponent data-test-id="component" />`
|
|
70
|
+
- `<MyComponent role="group" />`
|
|
71
|
+
|
|
72
|
+
### The `hidden` property
|
|
73
|
+
|
|
74
|
+
The CSS for a component frequently break the `hidden` attribute, because code like `display: flex` overrides the default styles. Test that the `hidden` attribute still makes the invisible.
|
|
75
|
+
|
|
76
|
+
```jsx
|
|
77
|
+
it("can be hidden", () => {
|
|
78
|
+
const { container } = render(<MyComponent hidden />);
|
|
79
|
+
|
|
80
|
+
const component = container.querySelector("div");
|
|
81
|
+
|
|
82
|
+
expect(component).not.toBeVisible();
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### The `className` property
|
|
87
|
+
|
|
88
|
+
Components render BEM class names, but front-end developers need to by able to use their own class names as well. Additional class names must extend the class list, not overwrite the component class names.
|
|
89
|
+
|
|
90
|
+
```jsx
|
|
91
|
+
it("can have a additional class name", () => {
|
|
92
|
+
const { container } = render(<MyComponent className="large" />);
|
|
93
|
+
|
|
94
|
+
const component = container.querySelector(":only-child");
|
|
95
|
+
|
|
96
|
+
expect(component).toHaveClass("large");
|
|
97
|
+
expect(component).toHaveClass("my-component");
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Test the accessibility tree
|
|
102
|
+
|
|
103
|
+
### Landmarks
|
|
104
|
+
|
|
105
|
+
```jsx
|
|
106
|
+
it("renders an complementary role element", () => {
|
|
107
|
+
render(<Aside />);
|
|
108
|
+
|
|
109
|
+
const aside = screen.getByRole("complementary");
|
|
110
|
+
|
|
111
|
+
expect(aside).toBeInTheDocument();
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Label for landmarks
|
|
116
|
+
|
|
117
|
+
Some components have an API to configure the label:
|
|
118
|
+
|
|
119
|
+
```jsx
|
|
120
|
+
it("renders an complementary role element with a name", () => {
|
|
121
|
+
render(<BreadcrumbNav label="Breadcrumbs" />);
|
|
122
|
+
|
|
123
|
+
const nav = screen.getByRole("navigation", { name: "Breadcrumbs" });
|
|
124
|
+
|
|
125
|
+
expect(nav).toBeInTheDocument();
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Other components need to rely on `aria-labelledby` or `aria-label`.
|
|
130
|
+
|
|
131
|
+
```jsx
|
|
132
|
+
it('renders an complementary role element with a name', () => {
|
|
133
|
+
render(
|
|
134
|
+
<Aside aria-labelledby="heading">
|
|
135
|
+
<h2 id="heading">See also</h1>
|
|
136
|
+
</Aside>
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const aside = screen.getByRole('complementary', { name: 'See also' });
|
|
140
|
+
|
|
141
|
+
expect(aside).toBeInTheDocument();
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### States
|
|
146
|
+
|
|
147
|
+
Voor [WCAG 4.1.2](https://nldesignsystem.nl/wcag/4.1.2) is het belangrijk dat de state van componenten beschikbaar is in de accessibility tree. [Testing Library heeft APIs](https://testing-library.com/docs/queries/byrole) om de informatie uit de accessibility tree op te vragen, in plaats van via de DOM.
|
|
148
|
+
|
|
149
|
+
Voorbeelden van state zijn:
|
|
150
|
+
|
|
151
|
+
- Een `checkbox` die `checked` is.
|
|
152
|
+
- Een `textbox` die `disabled` is.
|
|
153
|
+
- Een `textarea` die `required` is.
|
|
154
|
+
- Een `button` die `expanded` is.
|
|
155
|
+
|
|
156
|
+
```jsx
|
|
157
|
+
describe("checked variant", () => {
|
|
158
|
+
it("is not checked by default", () => {
|
|
159
|
+
const { container } = render(<Checkbox />);
|
|
160
|
+
|
|
161
|
+
const checkbox = screen.getByRole("checkbox");
|
|
162
|
+
|
|
163
|
+
expect(checkbox).not.toBeChecked();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("can have a checked state", () => {
|
|
167
|
+
const handleChange = () => {};
|
|
168
|
+
render(<Checkbox checked onChange={handleChange} />);
|
|
169
|
+
|
|
170
|
+
const checkbox = screen.getByRole("checkbox");
|
|
171
|
+
|
|
172
|
+
expect(checkbox).toBeChecked();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("can have a defaultChecked state (in React)", () => {
|
|
176
|
+
render(<Checkbox defaultChecked />);
|
|
177
|
+
|
|
178
|
+
const checkbox = screen.getByRole("checkbox");
|
|
179
|
+
|
|
180
|
+
expect(checkbox).toBeChecked();
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Helaas ondersteunt Testing Library nog niet elke state in de accessibility tree. Maak alvast wel de test, maar sla de test over `todo`. Gebruik de DOM om de test op een alternative manier te doen.
|
|
186
|
+
|
|
187
|
+
```jsx
|
|
188
|
+
// `aria-disabled` is somehow not recognized as disabled state on a listbox by Testing Library
|
|
189
|
+
// https://github.com/testing-library/jest-dom/issues/144
|
|
190
|
+
it.todo("has a disabled listbox in the accessibility tree", () => {});
|
|
191
|
+
|
|
192
|
+
// Temporary alternative to the accessibility tree test
|
|
193
|
+
it("has a disabled listbox", () => {
|
|
194
|
+
render(<Listbox disabled />);
|
|
195
|
+
|
|
196
|
+
const listbox = screen.getByRole("listbox");
|
|
197
|
+
|
|
198
|
+
// Look at the DOM instead of the accessibility tree
|
|
199
|
+
expect(listbox).toHaveAttribute("aria-disabled", "true");
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Controleer periodiek of een nieuwe versie van Testing Library de state wel ondersteunt.
|