@aarhus-university/au-lib-react-components 10.6.0 → 10.7.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.
Files changed (97) hide show
  1. package/.eslintrc.js +34 -34
  2. package/.storybook/main.js +20 -7
  3. package/.storybook/preview.js +10 -10
  4. package/README.md +19 -19
  5. package/__tests__/jest/AUButtonComponent.test.tsx +165 -163
  6. package/__tests__/jest/AUModalComponent.test.tsx +116 -0
  7. package/__tests__/jest/AUSpinnerComponent.test.tsx +57 -57
  8. package/__tests__/jest/AUToolbarComponent.test.tsx +46 -0
  9. package/__tests__/jest/helpers.test.ts +15 -15
  10. package/__tests__/jest/setupTests.ts +2 -2
  11. package/babel.config.js +8 -8
  12. package/build/umd/all.css +2 -2
  13. package/build/umd/all.js +1 -1
  14. package/build/umd/alphabox.js +1 -1
  15. package/build/umd/databox.js +1 -1
  16. package/build/umd/diagramme.js +1 -1
  17. package/build/umd/flowbox.js +1 -1
  18. package/build/umd/universe.js +1 -1
  19. package/package.json +107 -107
  20. package/src/components/AUAlertComponent.tsx +70 -70
  21. package/src/components/AUAutoSuggestComponent.js +158 -158
  22. package/src/components/AUButtonComponent.tsx +83 -77
  23. package/src/components/AUCalendarComponent.tsx +493 -493
  24. package/src/components/AUContentToggleComponent.tsx +33 -33
  25. package/src/components/AUDatepickerComponent.tsx +117 -117
  26. package/src/components/AUMobilePrefixComponent.tsx +15 -15
  27. package/src/components/AUModalComponent.tsx +64 -80
  28. package/src/components/AUReceiptComponent.tsx +33 -33
  29. package/src/components/AUSpinnerComponent.tsx +33 -33
  30. package/src/components/AUSubNavComponent.tsx +48 -48
  31. package/src/components/AUSubmitButtonContainerComponent.tsx +31 -31
  32. package/src/components/AUTabbedContentComponent.tsx +145 -145
  33. package/src/components/AUTableComponent.tsx +24 -24
  34. package/src/components/AUToastComponent.tsx +103 -103
  35. package/src/components/AUToolbarComponent.tsx +52 -45
  36. package/src/components/profile/AUProfileActions.js +128 -128
  37. package/src/components/profile/AUProfileAvatarComponent.js +83 -83
  38. package/src/components/profile/AUProfileAvatarV2Component.js +91 -91
  39. package/src/components/profile/AUProfileAvatarV3Component.tsx +42 -42
  40. package/src/components/profile/AUProfileContainerComponent.js +283 -283
  41. package/src/components/profile/AUProfileHooks.js +30 -30
  42. package/src/components/profile/AUProfileItemComponent.js +54 -54
  43. package/src/components/profile/AUProfileLanguageComponent.js +131 -131
  44. package/src/components/profile/AUProfileLoginComponent.tsx +26 -26
  45. package/src/components/profile/AUProfileMailComponent.js +307 -307
  46. package/src/components/profile/AUProfileMobileComponent.js +164 -164
  47. package/src/components/profile/AUProfileNameComponent.js +253 -253
  48. package/src/components/profile/AUProfileNextOfKinComponent.js +216 -216
  49. package/src/components/profile/AUProfileReducer.js +230 -230
  50. package/src/components/profile/AUProfileWidgetComponent.js +95 -95
  51. package/src/components/profile/AUProfileWidgetV2Component.js +116 -116
  52. package/src/components/profile/AUProfileWidgetV3Component.tsx +122 -122
  53. package/src/components/wrapping/AUEmbedComponent.js +47 -47
  54. package/src/layout-2016/components/alphabox/AlphaBoxComponent.js +143 -143
  55. package/src/layout-2016/components/alphabox/AlphaBoxContentComponent.js +136 -136
  56. package/src/layout-2016/components/common/AUCollapsibleComponent.js +152 -152
  57. package/src/layout-2016/components/common/AUSpinnerComponent.js +103 -103
  58. package/src/layout-2016/components/databox/DataBoxAlphabetComponent.js +144 -144
  59. package/src/layout-2016/components/databox/DataBoxAssociationComponent.js +122 -122
  60. package/src/layout-2016/components/databox/DataBoxButtonComponent.js +157 -157
  61. package/src/layout-2016/components/databox/DataBoxComponent.js +297 -297
  62. package/src/layout-2016/components/databox/DataBoxGroupingComponent.js +64 -64
  63. package/src/layout-2016/components/databox/DataBoxSearchResultComponent.js +36 -36
  64. package/src/layout-2016/components/databox/DataBoxStackedAssociationComponent.js +54 -54
  65. package/src/layout-2016/components/databox/DataBoxSuggestionComponent.js +39 -39
  66. package/src/layout-2016/components/diagramme/AUDiagrammeComponent.js +309 -309
  67. package/src/layout-2016/components/flowbox/FlowBoxComponent.js +126 -126
  68. package/src/layout-2016/components/flowbox/FlowBoxPhoneComponent.js +104 -104
  69. package/src/layout-2016/components/profile/AUProfileAvatar2016Component.js +103 -103
  70. package/src/layout-2016/components/universe/StaffTopComponent.js +363 -363
  71. package/src/layout-2016/components/universe/StudentTopComponent.js +137 -137
  72. package/src/layout-2016/components/universe/UniverseContainerComponent.js +65 -65
  73. package/src/layout-2016/lib/all.js +3 -3
  74. package/src/layout-2016/lib/au-alphabox.js +100 -100
  75. package/src/layout-2016/lib/au-databox.js +400 -400
  76. package/src/layout-2016/lib/au-diagramme.js +85 -85
  77. package/src/layout-2016/lib/au-flowbox.js +93 -93
  78. package/src/layout-2016/lib/universe.js +9 -9
  79. package/src/lib/helpers.ts +194 -194
  80. package/src/lib/hooks.ts +37 -33
  81. package/src/lib/i18n.ts +600 -600
  82. package/src/lib/tracking.ts +69 -69
  83. package/src/lib/wrapping.ts +21 -21
  84. package/src/styles/_settings.scss +10 -10
  85. package/src/styles/alphabox.scss +222 -222
  86. package/src/styles/app.scss +7 -7
  87. package/src/styles/autosuggest.scss +57 -57
  88. package/src/styles/databox.scss +563 -563
  89. package/src/styles/diagramme.scss +119 -119
  90. package/src/styles/flowbox.scss +72 -72
  91. package/src/styles/maps.scss +395 -395
  92. package/stories/AUButtonComponent.stories.tsx +85 -85
  93. package/stories/AUModalComponent.stories.tsx +92 -0
  94. package/stories/AUSpinnerComponent.stories.tsx +41 -41
  95. package/stories/AUToolbarComponent.stories.tsx +96 -0
  96. package/tsconfig.json +46 -46
  97. package/webpack.config.js +89 -89
package/.eslintrc.js CHANGED
@@ -1,34 +1,34 @@
1
- module.exports = {
2
- root: true,
3
- extends: ['airbnb', 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', 'plugin:storybook/recommended'],
4
- plugins: ['react', 'react-hooks', '@typescript-eslint'],
5
- parser: '@typescript-eslint/parser',
6
- rules: {
7
- 'import/extensions': [0],
8
- 'react/jsx-filename-extension': [0],
9
- 'no-use-before-define': [0],
10
- '@typescript-eslint/no-use-before-define': ['error'],
11
- 'no-shadow': 'off',
12
- '@typescript-eslint/no-shadow': ['error'],
13
- 'react/no-danger': [0],
14
- 'linebreak-style': [0],
15
- 'react/function-component-definition': [2, {
16
- namedComponents: 'arrow-function',
17
- unnamedComponents: 'arrow-function',
18
- }],
19
- 'react-hooks/rules-of-hooks': 'error',
20
- },
21
- settings: {
22
- react: {
23
- version: 'detect',
24
- },
25
- 'import/resolver': {
26
- typescript: {},
27
- },
28
- },
29
- ignorePatterns: ['stories'],
30
- globals: {
31
- AU: true,
32
- $: true,
33
- },
34
- };
1
+ module.exports = {
2
+ root: true,
3
+ extends: ['airbnb', 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', 'plugin:storybook/recommended'],
4
+ plugins: ['react', 'react-hooks', '@typescript-eslint'],
5
+ parser: '@typescript-eslint/parser',
6
+ rules: {
7
+ 'import/extensions': [0],
8
+ 'react/jsx-filename-extension': [0],
9
+ 'no-use-before-define': [0],
10
+ '@typescript-eslint/no-use-before-define': ['error'],
11
+ 'no-shadow': 'off',
12
+ '@typescript-eslint/no-shadow': ['error'],
13
+ 'react/no-danger': [0],
14
+ 'linebreak-style': [0],
15
+ 'react/function-component-definition': [2, {
16
+ namedComponents: 'arrow-function',
17
+ unnamedComponents: 'arrow-function',
18
+ }],
19
+ 'react-hooks/rules-of-hooks': 'error',
20
+ },
21
+ settings: {
22
+ react: {
23
+ version: 'detect',
24
+ },
25
+ 'import/resolver': {
26
+ typescript: {},
27
+ },
28
+ },
29
+ ignorePatterns: ['stories'],
30
+ globals: {
31
+ AU: true,
32
+ $: true,
33
+ },
34
+ };
@@ -1,8 +1,21 @@
1
- module.exports = {
2
- "stories": ["../**/*.stories.mdx", "../**/*.stories.@(js|jsx|ts|tsx)"],
3
- "addons": ["@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-interactions"],
4
- "framework": "@storybook/react",
5
- core: {
6
- builder: "webpack5"
7
- }
1
+ const path = require('path');
2
+
3
+ module.exports = {
4
+ "stories": ["../**/*.stories.mdx", "../**/*.stories.@(js|jsx|ts|tsx)"],
5
+ "addons": ["@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-interactions"],
6
+ "framework": "@storybook/react",
7
+ core: {
8
+ builder: "webpack5"
9
+ },
10
+ webpackFinal: async (config) => {
11
+ config.module.rules.push({
12
+ test: /\.(ts|js)x?$/,
13
+ include: path.resolve(__dirname, '../node_modules/@aarhus-university/au-designsystem-delphinus/source'),
14
+ use: {
15
+ loader: 'babel-loader',
16
+ },
17
+ });
18
+ return config;
19
+ // return { ...config, module: { ...config.module, rules: custom.module.rules } };
20
+ },
8
21
  };
@@ -1,11 +1,11 @@
1
- import '@aarhus-university/au-designsystem-delphinus/build/style.css';
2
-
3
- export const parameters = {
4
- actions: { argTypesRegex: "^on[A-Z].*" },
5
- controls: {
6
- matchers: {
7
- color: /(background|color)$/i,
8
- date: /Date$/,
9
- },
10
- },
1
+ import '@aarhus-university/au-designsystem-delphinus/build/style.css';
2
+
3
+ export const parameters = {
4
+ actions: { argTypesRegex: "^on[A-Z].*" },
5
+ controls: {
6
+ matchers: {
7
+ color: /(background|color)$/i,
8
+ date: /Date$/,
9
+ },
10
+ },
11
11
  };
package/README.md CHANGED
@@ -1,19 +1,19 @@
1
- # AU Lib React Components
2
- > @aarhus-university/au-lib-react-components
3
-
4
- ## Beskrivelse
5
- > React-komponentbibliotek, der kan anvendes på tværs af andre React-projekter
6
-
7
- ## Kræver
8
- Nodejs/npm
9
-
10
- ## Installation
11
- * Kør `npm install` i en terminal for at installere npm-afhængigheder til dette projekt.
12
- * Kør `npm install @aarhus-university/au-lib-react-components@latest --save` i en terminal for at installere dette projekt som en afhængighed i et andet npm-projekt.
13
-
14
- ## Afvikling
15
- * `npm run build` for at bygge de færdige Universal Module Definition-filer (til brug som selvstændige applikationer)
16
-
17
- ## Versionering og udgivelse
18
- * `npm version major|minor|patch` for 'version bump'.
19
- * `npm publish` for udgivelse i npm-registry.
1
+ # AU Lib React Components
2
+ > @aarhus-university/au-lib-react-components
3
+
4
+ ## Beskrivelse
5
+ > React-komponentbibliotek, der kan anvendes på tværs af andre React-projekter
6
+
7
+ ## Kræver
8
+ Nodejs/npm
9
+
10
+ ## Installation
11
+ * Kør `npm install` i en terminal for at installere npm-afhængigheder til dette projekt.
12
+ * Kør `npm install @aarhus-university/au-lib-react-components@latest --save` i en terminal for at installere dette projekt som en afhængighed i et andet npm-projekt.
13
+
14
+ ## Afvikling
15
+ * `npm run build` for at bygge de færdige Universal Module Definition-filer (til brug som selvstændige applikationer)
16
+
17
+ ## Versionering og udgivelse
18
+ * `npm version major|minor|patch` for 'version bump'.
19
+ * `npm publish` for udgivelse i npm-registry.
@@ -1,163 +1,165 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import React from 'react';
3
- import { render, screen, fireEvent } from '@testing-library/react';
4
- // import userEvent from '@testing-library/user-event';
5
- import '@testing-library/jest-dom';
6
- import AUButtonComponent from '../../src/components/AUButtonComponent';
7
-
8
- describe('<AUButtonComponent />', () => {
9
- it('renders a default sized button', () => {
10
- render(
11
- <AUButtonComponent
12
- label="Min knap"
13
- />,
14
- );
15
-
16
- const button = screen.getByText('Min knap');
17
- expect(button).toBeInTheDocument();
18
- });
19
-
20
- it('renders a default sized disabled button', () => {
21
- render(
22
- <AUButtonComponent
23
- label="Min knap"
24
- disabled
25
- />,
26
- );
27
-
28
- const button = screen.getByText('Min knap');
29
- expect(button).toBeDisabled();
30
- });
31
-
32
- it('renders a large enabled button with no icon', () => {
33
- const { container } = render(
34
- <AUButtonComponent
35
- label="Min knap"
36
- size="large"
37
- />,
38
- );
39
-
40
- const button = container?.querySelector('button');
41
- const classList = button?.classList;
42
- expect(classList?.contains('button--large')).toBe(true);
43
- expect(button?.hasAttribute('data-icon')).toBe(false);
44
- expect(button).toBeEnabled();
45
- });
46
-
47
- it('renders a small dimmed button', () => {
48
- const { container } = render(
49
- <AUButtonComponent
50
- label="Min knap"
51
- size="small"
52
- type="dimmed"
53
- />,
54
- );
55
-
56
- const classList = container?.querySelector('button')?.classList;
57
- expect(classList?.contains('button--small')).toBe(true);
58
- expect(classList?.contains('button--dimmed')).toBe(true);
59
- });
60
-
61
- it('renders a default sized text button with a narwhal icon to the right', () => {
62
- const { container } = render(
63
- <AUButtonComponent
64
- label="Min knap"
65
- type="text"
66
- icon=""
67
- iconPosition="right"
68
- />,
69
- );
70
-
71
- const button = container?.querySelector('button');
72
- const classList = button?.classList;
73
- expect(classList?.contains('button--small')).toBe(false);
74
- expect(classList?.contains('button--large')).toBe(false);
75
- expect(classList?.contains('button--text')).toBe(true);
76
- expect(classList?.contains('button--icon')).toBe(true);
77
- expect(classList?.contains('button--icon--right')).toBe(true);
78
- expect(button?.getAttribute('data-icon')).toBe('');
79
- });
80
-
81
- it('renders a button with a narwhal icon with a hidden label', () => {
82
- const { container } = render(
83
- <AUButtonComponent
84
- label="Min knap"
85
- icon=""
86
- hideLabel
87
- />,
88
- );
89
-
90
- const button = container?.querySelector('button');
91
- const classList = button?.classList;
92
- expect(classList?.contains('button--icon')).toBe(true);
93
- expect(classList?.contains('button--icon--hide-label')).toBe(true);
94
- expect(button?.getAttribute('data-icon')).toBe('');
95
- expect(button?.getAttribute('title')).toBe('Min knap');
96
- });
97
-
98
- it('renders a default sized ireversable (sic) action button', () => {
99
- const { container } = render(
100
- <AUButtonComponent
101
- label="Min knap"
102
- mode="ireversable-action"
103
- />,
104
- );
105
-
106
- const classList = container?.querySelector('button')?.classList;
107
- expect(classList?.contains('button--ireversable-action')).toBe(true);
108
- });
109
-
110
- it('renders a large confirmable action button with a check icon and a hidden label', () => {
111
- const { container } = render(
112
- <AUButtonComponent
113
- label="Min knap"
114
- size="large"
115
- mode="confirmable-action"
116
- icon=""
117
- hideLabel
118
- />,
119
- );
120
-
121
- const button = container?.querySelector('button');
122
- const classList = button?.classList;
123
- expect(classList?.contains('button--large')).toBe(true);
124
- expect(classList?.contains('button--confirmable-action')).toBe(true);
125
- expect(classList?.contains('button--icon')).toBe(true);
126
- expect(classList?.contains('button--icon--hide-label')).toBe(true);
127
- expect(button?.getAttribute('data-icon')).toBe('');
128
- expect(button?.getAttribute('title')).toBe('Min knap');
129
- });
130
-
131
- it('renders a small disabled processing button', () => {
132
- const { container } = render(
133
- <AUButtonComponent
134
- label="Min knap"
135
- size="small"
136
- mode="processing"
137
- disabled
138
- />,
139
- );
140
-
141
- const button = container?.querySelector('button');
142
- const classList = button?.classList;
143
- expect(classList?.contains('button--small')).toBe(true);
144
- expect(classList?.contains('button--processing')).toBe(true);
145
- expect(button).toBeDisabled();
146
- });
147
-
148
- it('does something when clicked', () => {
149
- const handleClick = jest.fn();
150
- const { container } = render(
151
- <AUButtonComponent
152
- label="Min knap"
153
- onClick={handleClick}
154
- />,
155
- );
156
-
157
- const button = container?.querySelector('button');
158
- if (button) {
159
- fireEvent.click(button);
160
- expect(handleClick).toHaveBeenCalledTimes(1);
161
- }
162
- });
163
- });
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React from 'react';
3
+ import { render, screen, fireEvent } from '@testing-library/react';
4
+ // import userEvent from '@testing-library/user-event';
5
+ import '@testing-library/jest-dom';
6
+ import AUButtonComponent from '../../src/components/AUButtonComponent';
7
+
8
+ describe('<AUButtonComponent />', () => {
9
+ it('renders a default sized button', () => {
10
+ render(
11
+ <AUButtonComponent
12
+ label="Min knap"
13
+ />,
14
+ );
15
+
16
+ const button = screen.getByText('Min knap');
17
+ expect(button).toBeInTheDocument();
18
+ });
19
+
20
+ it('renders a default sized disabled button', () => {
21
+ render(
22
+ <AUButtonComponent
23
+ label="Min knap"
24
+ disabled
25
+ />,
26
+ );
27
+
28
+ const button = screen.getByText('Min knap');
29
+ expect(button).toBeDisabled();
30
+ });
31
+
32
+ it('renders a large enabled button with no icon', () => {
33
+ const { container } = render(
34
+ <AUButtonComponent
35
+ label="Min knap"
36
+ size="large"
37
+ />,
38
+ );
39
+
40
+ const button = container?.querySelector('button');
41
+ const classList = button?.classList;
42
+ expect(classList?.contains('button--large')).toBe(true);
43
+ expect(button?.hasAttribute('data-icon')).toBe(false);
44
+ expect(button).toBeEnabled();
45
+ });
46
+
47
+ it('renders a small dimmed button with an extra classname', () => {
48
+ const { container } = render(
49
+ <AUButtonComponent
50
+ label="Min knap"
51
+ size="small"
52
+ type="dimmed"
53
+ classNames={['fubar']}
54
+ />,
55
+ );
56
+
57
+ const classList = container?.querySelector('button')?.classList;
58
+ expect(classList?.contains('button--small')).toBe(true);
59
+ expect(classList?.contains('button--dimmed')).toBe(true);
60
+ expect(classList?.contains('fubar')).toBe(true);
61
+ });
62
+
63
+ it('renders a default sized text button with a narwhal icon to the right', () => {
64
+ const { container } = render(
65
+ <AUButtonComponent
66
+ label="Min knap"
67
+ type="text"
68
+ icon=""
69
+ iconPosition="right"
70
+ />,
71
+ );
72
+
73
+ const button = container?.querySelector('button');
74
+ const classList = button?.classList;
75
+ expect(classList?.contains('button--small')).toBe(false);
76
+ expect(classList?.contains('button--large')).toBe(false);
77
+ expect(classList?.contains('button--text')).toBe(true);
78
+ expect(classList?.contains('button--icon')).toBe(true);
79
+ expect(classList?.contains('button--icon--right')).toBe(true);
80
+ expect(button?.getAttribute('data-icon')).toBe('');
81
+ });
82
+
83
+ it('renders a button with a narwhal icon with a hidden label', () => {
84
+ const { container } = render(
85
+ <AUButtonComponent
86
+ label="Min knap"
87
+ icon=""
88
+ hideLabel
89
+ />,
90
+ );
91
+
92
+ const button = container?.querySelector('button');
93
+ const classList = button?.classList;
94
+ expect(classList?.contains('button--icon')).toBe(true);
95
+ expect(classList?.contains('button--icon--hide-label')).toBe(true);
96
+ expect(button?.getAttribute('data-icon')).toBe('');
97
+ expect(button?.getAttribute('title')).toBe('Min knap');
98
+ });
99
+
100
+ it('renders a default sized ireversable (sic) action button', () => {
101
+ const { container } = render(
102
+ <AUButtonComponent
103
+ label="Min knap"
104
+ mode="ireversable-action"
105
+ />,
106
+ );
107
+
108
+ const classList = container?.querySelector('button')?.classList;
109
+ expect(classList?.contains('button--ireversable-action')).toBe(true);
110
+ });
111
+
112
+ it('renders a large confirmable action button with a check icon and a hidden label', () => {
113
+ const { container } = render(
114
+ <AUButtonComponent
115
+ label="Min knap"
116
+ size="large"
117
+ mode="confirmable-action"
118
+ icon=""
119
+ hideLabel
120
+ />,
121
+ );
122
+
123
+ const button = container?.querySelector('button');
124
+ const classList = button?.classList;
125
+ expect(classList?.contains('button--large')).toBe(true);
126
+ expect(classList?.contains('button--confirmable-action')).toBe(true);
127
+ expect(classList?.contains('button--icon')).toBe(true);
128
+ expect(classList?.contains('button--icon--hide-label')).toBe(true);
129
+ expect(button?.getAttribute('data-icon')).toBe('');
130
+ expect(button?.getAttribute('title')).toBe('Min knap');
131
+ });
132
+
133
+ it('renders a small disabled processing button', () => {
134
+ const { container } = render(
135
+ <AUButtonComponent
136
+ label="Min knap"
137
+ size="small"
138
+ mode="processing"
139
+ disabled
140
+ />,
141
+ );
142
+
143
+ const button = container?.querySelector('button');
144
+ const classList = button?.classList;
145
+ expect(classList?.contains('button--small')).toBe(true);
146
+ expect(classList?.contains('button--processing')).toBe(true);
147
+ expect(button).toBeDisabled();
148
+ });
149
+
150
+ it('does something when clicked', () => {
151
+ const handleClick = jest.fn();
152
+ const { container } = render(
153
+ <AUButtonComponent
154
+ label="Min knap"
155
+ onClick={handleClick}
156
+ />,
157
+ );
158
+
159
+ const button = container?.querySelector('button');
160
+ if (button) {
161
+ fireEvent.click(button);
162
+ expect(handleClick).toHaveBeenCalledTimes(1);
163
+ }
164
+ });
165
+ });
@@ -0,0 +1,116 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React, {
3
+ ReactNode, ReactPortal, useRef, useState,
4
+ } from 'react';
5
+ import ReactDOM from 'react-dom';
6
+ import { fireEvent, render } from '@testing-library/react';
7
+ // import userEvent from '@testing-library/user-event';
8
+ import '@testing-library/jest-dom';
9
+ import AUModalComponent from '../../src/components/AUModalComponent';
10
+ import AUButtonComponent from '../../src/components/AUButtonComponent';
11
+
12
+ const ModalWrapper: React.FC = () => {
13
+ const [showModal, setShowModal] = useState(false);
14
+ const btnRef = useRef<HTMLButtonElement>(null);
15
+ return (
16
+ <>
17
+ <AUButtonComponent
18
+ label="Open modal"
19
+ btnRef={btnRef}
20
+ onClick={() => {
21
+ setShowModal(true);
22
+ }}
23
+ />
24
+ <AUModalComponent
25
+ domId="test-modal"
26
+ show={showModal}
27
+ sender={btnRef.current}
28
+ onClose={() => setShowModal(false)}
29
+ >
30
+ <div className="modal-view__body">
31
+ <h2 className="modal-view__header theme--dark">
32
+ Header
33
+ </h2>
34
+ <div className="modal-view__content">
35
+ <p>Content</p>
36
+ </div>
37
+ </div>
38
+ </AUModalComponent>
39
+ </>
40
+ );
41
+ };
42
+
43
+ describe('<AUModalComponent />', () => {
44
+ const fakeBtn = document.createElement('button');
45
+ const oldCreatePortal = ReactDOM.createPortal;
46
+ beforeAll(async () => {
47
+ ReactDOM.createPortal = (node: ReactNode): ReactPortal => node as ReactPortal;
48
+ });
49
+
50
+ afterAll(() => {
51
+ ReactDOM.createPortal = oldCreatePortal;
52
+ });
53
+ it('renders a visible modal view with some content', () => {
54
+ const { container } = render(
55
+ <div className="page">
56
+ <AUModalComponent
57
+ domId="test-modal"
58
+ show
59
+ sender={fakeBtn}
60
+ >
61
+ <div className="modal-view__body">
62
+ <h2 className="modal-view__header theme--dark">
63
+ Header
64
+ </h2>
65
+ <div className="modal-view__content">
66
+ <p>Content</p>
67
+ </div>
68
+ </div>
69
+ </AUModalComponent>
70
+ </div>,
71
+ );
72
+
73
+ const modal = container.querySelector('.modal-view.modal-view--visible');
74
+ expect(modal).toBeInTheDocument();
75
+ });
76
+
77
+ it('renders a modal view with domId "test-modal" but it is not visible', () => {
78
+ const { container } = render(
79
+ <div className="page">
80
+ <AUModalComponent
81
+ domId="test-modal"
82
+ show={false}
83
+ sender={fakeBtn}
84
+ >
85
+ <div className="modal-view__body">
86
+ <h2 className="modal-view__header theme--dark">
87
+ Header
88
+ </h2>
89
+ <div className="modal-view__content">
90
+ <p>Content</p>
91
+ </div>
92
+ </div>
93
+ </AUModalComponent>
94
+ </div>,
95
+ );
96
+
97
+ const modal = container.querySelector('#test-modal');
98
+ expect(modal).toBeInTheDocument();
99
+ expect(modal?.classList.contains('modal-view--visible')).toBe(false);
100
+ });
101
+
102
+ it('renders a non-visible modal view until button is clicked', () => {
103
+ const { container, getByText } = render(
104
+ <div className="page">
105
+ <ModalWrapper />
106
+ </div>,
107
+ );
108
+
109
+ const modal = container.querySelector('.modal-view');
110
+ const btn = getByText('Open modal');
111
+ expect(modal).toBeInTheDocument();
112
+ expect(modal?.classList.contains('modal-view--visible')).toBe(false);
113
+ fireEvent.click(btn);
114
+ expect(modal?.classList.contains('modal-view--visible')).toBe(true);
115
+ });
116
+ });