@aarhus-university/au-lib-react-components 11.1.0 → 11.1.2

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "sideEffects": false,
3
3
  "name": "@aarhus-university/au-lib-react-components",
4
- "version": "11.1.0",
4
+ "version": "11.1.2",
5
5
  "description": "Library for shared React components for various applications on au.dk",
6
6
  "scripts": {
7
7
  "test": "jest",
@@ -72,9 +72,9 @@
72
72
  "webpack-cli": "^4.9.2"
73
73
  },
74
74
  "dependencies": {
75
- "@aarhus-university/au-designsystem-delphinus": "0.34.2",
75
+ "@aarhus-university/au-designsystem-delphinus": "0.34.8",
76
76
  "@aarhus-university/au-designsystem-delphinus-dev": "0.2.0",
77
- "@aarhus-university/types": "^0.17.2",
77
+ "@aarhus-university/types": "^0.17.4",
78
78
  "@reduxjs/toolkit": "^1.8.3",
79
79
  "@types/google.analytics": "^0.0.42",
80
80
  "@types/history": "^5.0.0",
@@ -3,8 +3,6 @@ import React, {
3
3
  useRef,
4
4
  FC,
5
5
  } from 'react';
6
- // import { setContentToggle } from '@aarhus-university/au-desi
7
- // gnsystem-delphinus/source/js/components/content-toggle';
8
6
  import { setContentToggle } from '@aarhus-university/au-designsystem-delphinus/source/js/components/content-toggle';
9
7
 
10
8
  const AUContentToggleComponent: FC<AUContentToggleComponentProps> = ({
@@ -21,7 +21,7 @@ const AUErrorComponent: FC<AUErrorComponentExtendedProps> = ({
21
21
  type="warning"
22
22
  header={`${withStatus ? `${status}: ` : ''}${header}`}
23
23
  content={[
24
- <p>{message}</p>,
24
+ <p dangerouslySetInnerHTML={{ __html: message }} />,
25
25
  ]}
26
26
  />
27
27
  );
@@ -33,7 +33,7 @@ const AUErrorComponent: FC<AUErrorComponentExtendedProps> = ({
33
33
  type="warning"
34
34
  header={withStatus ? status : undefined}
35
35
  content={[
36
- <p>{error}</p>,
36
+ <p dangerouslySetInnerHTML={{ __html: error }} />,
37
37
  ]}
38
38
  />
39
39
  );
@@ -45,7 +45,7 @@ const AUErrorComponent: FC<AUErrorComponentExtendedProps> = ({
45
45
  type="warning"
46
46
  header={withStatus ? `${status}` : undefined}
47
47
  content={[
48
- <p>{JSON.stringify(data)}</p>,
48
+ <p dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />,
49
49
  ]}
50
50
  />
51
51
  );
@@ -57,7 +57,7 @@ const AUErrorComponent: FC<AUErrorComponentExtendedProps> = ({
57
57
  type="warning"
58
58
  header={withStatus ? code : undefined}
59
59
  content={[
60
- <p>{message}</p>,
60
+ <p dangerouslySetInnerHTML={{ __html: message || '' }} />,
61
61
  ]}
62
62
  />
63
63
  );
@@ -9,18 +9,17 @@ const AUSpinnerComponent: FC<AUSpinnerComponentProps> = ({
9
9
  className,
10
10
  children,
11
11
  }: AUSpinnerComponentProps) => {
12
+ let classNames = 'processing-state';
13
+ if (init === 'table' || init === 'box') {
14
+ classNames = `${classNames} processing-state--init-${init}`;
15
+ }
16
+ if (className) {
17
+ classNames = `${classNames} ${className}`;
18
+ }
12
19
  if (!loaded) {
13
- if (init === 'table' || init === 'box') {
14
- return (
15
- <div
16
- className={`processing-state processing-state--init-${init} ${className}`}
17
- style={{ minHeight: height }}
18
- />
19
- );
20
- }
21
20
  return (
22
21
  <div
23
- className={`processing-state ${className}`}
22
+ className={classNames}
24
23
  style={{ minHeight: height }}
25
24
  />
26
25
  );
@@ -29,5 +28,9 @@ const AUSpinnerComponent: FC<AUSpinnerComponentProps> = ({
29
28
  return children;
30
29
  };
31
30
 
31
+ AUSpinnerComponent.defaultProps = {
32
+ className: '',
33
+ };
34
+
32
35
  AUSpinnerComponent.displayName = 'AUSpinnerComponent';
33
36
  export default AUSpinnerComponent;
@@ -1,41 +1,41 @@
1
- import React, { FC } from 'react';
2
-
3
- const AUStepComponent: FC<AUStepComponentProps> = ({
4
- step,
5
- children,
6
- stepHeadlines,
7
- introElement,
8
- outroElement,
9
- }: AUStepComponentProps) => (
10
- <>
11
- {
12
- (step > -1 && step < children.length) && (
13
- <ol className="stepper" data-steps={children.length}>
14
- {
15
- stepHeadlines.map((headline, index) => (
16
- <li key={headline} className={`stepper__item${index === step ? ' stepper__item--active' : ''}`}>
17
- <span className="stepper__item__label">{headline}</span>
18
- </li>
19
- ))
20
- }
21
- </ol>
22
- )
23
- }
24
- {
25
- step < 0 && introElement
26
- }
27
- {(
28
- children[step]) || null}
29
- {
30
- (step > children.length - 1) && outroElement
31
- }
32
- </>
33
- );
34
-
35
- AUStepComponent.defaultProps = {
36
- introElement: undefined,
37
- outroElement: undefined,
38
- };
39
-
40
- AUStepComponent.displayName = 'AUStepComponent';
41
- export default AUStepComponent;
1
+ import React, { FC } from 'react';
2
+
3
+ const AUStepComponent: FC<AUStepComponentProps> = ({
4
+ step,
5
+ children,
6
+ stepHeadlines,
7
+ introElement,
8
+ outroElement,
9
+ }: AUStepComponentProps) => (
10
+ <>
11
+ {
12
+ (step > -1 && step < children.length) && (
13
+ <ol className="stepper" data-steps={children.length}>
14
+ {
15
+ stepHeadlines.map((headline, index) => (
16
+ <li key={headline} className={`stepper__item${index === step ? ' stepper__item--active' : ''}`}>
17
+ <span className="stepper__item__label">{headline}</span>
18
+ </li>
19
+ ))
20
+ }
21
+ </ol>
22
+ )
23
+ }
24
+ {
25
+ step < 0 && introElement
26
+ }
27
+ {(
28
+ children[step]) || null}
29
+ {
30
+ (step > children.length - 1) && outroElement
31
+ }
32
+ </>
33
+ );
34
+
35
+ AUStepComponent.defaultProps = {
36
+ introElement: undefined,
37
+ outroElement: undefined,
38
+ };
39
+
40
+ AUStepComponent.displayName = 'AUStepComponent';
41
+ export default AUStepComponent;
package/src/lib/hooks.ts CHANGED
@@ -14,6 +14,7 @@ const useModal = (
14
14
  onClose: () => void = () => { },
15
15
  ): void => {
16
16
  useEffect(() => {
17
+ let cleanUp: ExtendedCleanUpPair[] = [];
17
18
  const modalView = document.getElementById(domId);
18
19
  if (modalView) {
19
20
  const header = modalView.querySelector('.modal-view__header');
@@ -24,7 +25,7 @@ const useModal = (
24
25
  }
25
26
 
26
27
  if (sender && show) {
27
- showModal(domId, sender, () => {
28
+ cleanUp = showModal(domId, sender, () => {
28
29
  onClose();
29
30
  }, closeable);
30
31
  }
@@ -32,6 +33,17 @@ const useModal = (
32
33
  if (sender && !show && modalIsVisible(modalView)) {
33
34
  hideModal(domId, sender);
34
35
  }
36
+
37
+ return () => {
38
+ cleanUp.forEach((c) => {
39
+ if (c.clickEvent) {
40
+ c.element.removeEventListener('click', c.clickEvent);
41
+ }
42
+ if (c.keyUpEvent) {
43
+ c.element.removeEventListener('keyup', c.keyUpEvent);
44
+ }
45
+ });
46
+ };
35
47
  });
36
48
  };
37
49
 
@@ -21,7 +21,7 @@ export const AU_Error = Template.bind({});
21
21
  AU_Error.args = {
22
22
  error: {
23
23
  header: 'Our own custom error',
24
- message: 'With a nice header and descriptive error message',
24
+ message: 'With a nice header and descriptive error message, maybe a hint of some <a href="mailto:#">contact support info</a>',
25
25
  status: 500,
26
26
  },
27
27
  };
@@ -1,10 +1,11 @@
1
1
  import React from 'react';
2
2
  import { ComponentStory, ComponentMeta } from '@storybook/react';
3
- import { closeAllContentTogglesInToolbar, findToolbar } from '@aarhus-university/au-designsystem-delphinus/source/js/components/toolbar';
3
+ import { closeAllContentTogglesInToolbar, contentToggleEdgeHandling, findToolbar, lockBodyScroll, unlockBodyScroll } from '@aarhus-university/au-designsystem-delphinus/source/js/components/toolbar';
4
4
  import AUToolbarComponent from '../src/components/AUToolbarComponent';
5
5
  import AUButtonComponent from '../src/components/AUButtonComponent';
6
6
  import AUContentToggleComponent from '../src/components/AUContentToggleComponent';
7
7
  import { ThemeWrapper } from './lib/helpers';
8
+ import { isElementWithClassNameInEventPath } from '@aarhus-university/au-designsystem-delphinus/source/js/components/helpers';
8
9
 
9
10
  export default {
10
11
  title: 'Delphinus/Toolbar',
@@ -40,10 +41,15 @@ export const Form_Field_and_Buttons_and_Link = Template.bind({});
40
41
  Form_Field_and_Buttons_and_Link.args = {
41
42
  lang: 'da',
42
43
  elements: [
43
- <div className="form__field">
44
- <label htmlFor="demo-search">Search</label>
45
- <input type="search" autoComplete="off" autoCorrect="off" autoCapitalize="off" id="demo-search" />
46
- </div>,
44
+ <form className="form">
45
+ <div className="form__inline-submit">
46
+ <div className="form__field form__field--inline-label">
47
+ <label htmlFor="demo-search">Search</label>
48
+ <input type="search" autoComplete="off" autoCorrect="off" autoCapitalize="off" id="demo-search" />
49
+ </div>
50
+ <input className="form__inline-submit__button" type="submit" value="Submit" />
51
+ </div>
52
+ </form>,
47
53
  <AUButtonComponent icon="confirm-circle" label="Mark as read" />,
48
54
  <AUButtonComponent icon="delete" hideLabel label="Delete" />,
49
55
  <AUButtonComponent type="text" label="Select all" />,
@@ -102,16 +108,27 @@ Filter.args = {
102
108
  elements: [
103
109
  <AUContentToggleComponent
104
110
  toggled={false}
111
+ onClick={(popout: HTMLElement) => {
112
+ contentToggleEdgeHandling(popout);
113
+ lockBodyScroll();
114
+ }}
105
115
  beforeCallback={(content: HTMLElement) => closeAllContentTogglesInToolbar(findToolbar(content))}
106
- onClick={(content: HTMLElement, button: HTMLButtonElement) => console.log(content, button)}
107
116
  afterCallback={(content: HTMLElement, button: HTMLButtonElement) => {
108
- const toolbar = findToolbar(content);
109
117
  const ariaExpanded = button.getAttribute('aria-expanded');
118
+ const toolbar = findToolbar(content);
110
119
  if (ariaExpanded === 'true') {
111
120
  toolbar?.classList.add('toolbar--has-popout');
112
121
  } else {
113
122
  toolbar?.classList.remove('toolbar--has-popout');
114
123
  }
124
+
125
+ content.addEventListener('click', (event: MouseEvent) => {
126
+ if ((event.target as HTMLElement).classList.contains('toolbar__popout')
127
+ && !isElementWithClassNameInEventPath(event as MouseEvent, 'toolbar__filter__content')) {
128
+ closeAllContentTogglesInToolbar(toolbar);
129
+ unlockBodyScroll();
130
+ }
131
+ });
115
132
  }}
116
133
  >
117
134
  <div className="toolbar__filter">
@@ -119,55 +136,111 @@ Filter.args = {
119
136
  type="button"
120
137
  className="toolbar__filter__toggle content-toggle__toggle"
121
138
  aria-expanded={false}
139
+ aria-label="Filter 1"
122
140
  >
123
- Sted
141
+ Filter 1
124
142
  </button>
125
143
  <div
126
- className="toolbar__filter__content content-toggle__content"
144
+ className="toolbar__popout content-toggle__content"
127
145
  hidden
128
146
  >
129
- <fieldset className="selection-list">
130
- <legend>
131
- Vælg sted
132
- </legend>
133
- <div className="form__field form__field--inline-label">
134
- <label htmlFor="search-location">Søg</label>
135
- <input type="search" id="search-location" />
136
- </div>
137
- <div className="toolbar__filter__content__options">
138
- <div className="selection-list__option">
139
- <input type="checkbox" id="option-1" />
140
- <label htmlFor="option-1">Aarhus</label>
141
- </div>
142
- <div className="selection-list__option">
143
- <input type="checkbox" id="option-2" />
144
- <label htmlFor="option-2">København</label>
147
+ <div className="toolbar__filter__content toolbar__popout__content theme--normal">
148
+ <h3 className="toolbar__filter__content__title">
149
+ Vælg Filter 1
150
+ </h3>
151
+
152
+ <form className="form toolbar__filter__content__search">
153
+ <div className="form__inline-submit">
154
+ <div className="form__field form__field--inline-label">
155
+ <label htmlFor="search-filter-1">
156
+ Søg
157
+ </label>
158
+ <input
159
+ type="search"
160
+ id="search-filter-1"
161
+ />
162
+ </div>
163
+ <input className="form__inline-submit__button" type="submit" value="Søg" />
145
164
  </div>
146
- <div className="selection-list__option">
147
- <input type="checkbox" id="option-3" />
148
- <label htmlFor="option-3">Herning</label>
165
+ </form>
166
+ <form
167
+ className="toolbar__filter__content__options-and-actions"
168
+ onSubmit={(event) => {
169
+ event.preventDefault();
170
+ unlockBodyScroll();
171
+ }}
172
+ >
173
+ <div
174
+ className="toolbar__filter__content__options"
175
+ >
176
+ <div className="toolbar__filter__content__options__scroll-container">
177
+ <fieldset className="selection-list">
178
+ <legend>
179
+ 5 valgmuligheder
180
+ </legend>
181
+ <div className="selection-list__option">
182
+ <input type="checkbox" id="option-1" />
183
+ <label htmlFor="option-1">Valgmulighed 1</label>
184
+ </div>
185
+ <div className="selection-list__option">
186
+ <input type="checkbox" id="option-2" />
187
+ <label htmlFor="option-2">Valgmulighed 2</label>
188
+ </div>
189
+ <div className="selection-list__option">
190
+ <input type="checkbox" id="option-3" />
191
+ <label htmlFor="option-3">Valgmulighed 3</label>
192
+ </div>
193
+ <div className="selection-list__option">
194
+ <input type="checkbox" id="option-4" />
195
+ <label htmlFor="option-4">Valgmulighed 4</label>
196
+ </div>
197
+ <div className="selection-list__option">
198
+ <input type="checkbox" id="option-5" />
199
+ <label htmlFor="option-5">Valgmulighed 5</label>
200
+ </div>
201
+ </fieldset>
202
+ </div>
149
203
  </div>
150
- <div className="selection-list__option">
151
- <input type="checkbox" id="option-4" />
152
- <label htmlFor="option-4">Øvrige</label>
204
+ <div className="toolbar__filter__content__actions">
205
+ <div className="button-container">
206
+ <input type="submit" className="content-toggle__close button button--small" value="Gem" />
207
+ </div>
153
208
  </div>
154
- </div>
155
- </fieldset>
209
+ </form>
210
+ </div>
211
+ <button
212
+ type="button"
213
+ className="toolbar__popout__close content-toggle__close button button--icon button--icon--hide-label icon-close"
214
+ onClick={() => unlockBodyScroll()}
215
+ >
216
+ Luk
217
+ </button>
156
218
  </div>
157
219
  </div>
158
220
  </AUContentToggleComponent>,
159
221
  <AUContentToggleComponent
160
222
  toggled={false}
223
+ onClick={(popout: HTMLElement) => {
224
+ contentToggleEdgeHandling(popout);
225
+ lockBodyScroll();
226
+ }}
161
227
  beforeCallback={(content: HTMLElement) => closeAllContentTogglesInToolbar(findToolbar(content))}
162
- onClick={(content: HTMLElement, button: HTMLButtonElement) => console.log(content, button)}
163
228
  afterCallback={(content: HTMLElement, button: HTMLButtonElement) => {
164
- const toolbar = findToolbar(content);
165
229
  const ariaExpanded = button.getAttribute('aria-expanded');
230
+ const toolbar = findToolbar(content);
166
231
  if (ariaExpanded === 'true') {
167
232
  toolbar?.classList.add('toolbar--has-popout');
168
233
  } else {
169
234
  toolbar?.classList.remove('toolbar--has-popout');
170
235
  }
236
+
237
+ content.addEventListener('click', (event: MouseEvent) => {
238
+ if ((event.target as HTMLElement).classList.contains('toolbar__popout')
239
+ && !isElementWithClassNameInEventPath(event as MouseEvent, 'toolbar__filter__content')) {
240
+ closeAllContentTogglesInToolbar(toolbar);
241
+ unlockBodyScroll();
242
+ }
243
+ });
171
244
  }}
172
245
  >
173
246
  <div className="toolbar__filter">
@@ -175,44 +248,77 @@ Filter.args = {
175
248
  type="button"
176
249
  className="toolbar__filter__toggle content-toggle__toggle"
177
250
  aria-expanded={false}
251
+ aria-label="Filter 1"
178
252
  >
179
- Fakultet
253
+ Filter 2
180
254
  </button>
181
255
  <div
182
- className="toolbar__filter__content content-toggle__content"
256
+ className="toolbar__popout content-toggle__content"
183
257
  hidden
184
258
  >
185
- <fieldset className="selection-list">
186
- <legend>
187
- Vælg fakultet
188
- </legend>
189
- <div className="form__field form__field--inline-label">
190
- <label htmlFor="search-faculty">Søg</label>
191
- <input type="search" id="search-faculty" />
192
- </div>
193
- <div className="toolbar__filter__content__options">
194
- <div className="selection-list__option">
195
- <input type="checkbox" id="option-5" />
196
- <label htmlFor="option-5">Arts</label>
197
- </div>
198
- <div className="selection-list__option">
199
- <input type="checkbox" id="option-6" />
200
- <label htmlFor="option-6">Health</label>
201
- </div>
202
- <div className="selection-list__option">
203
- <input type="checkbox" id="option-7" />
204
- <label htmlFor="option-7">Natural Sciences</label>
259
+ <div className="toolbar__filter__content toolbar__popout__content theme--normal">
260
+ <h3 className="toolbar__filter__content__title">
261
+ Vælg Filter 2
262
+ </h3>
263
+
264
+ <form className="form toolbar__filter__content__search">
265
+ <div className="form__inline-submit">
266
+ <div className="form__field form__field--inline-label">
267
+ <label htmlFor="search-filter-2">
268
+ Søg
269
+ </label>
270
+ <input
271
+ type="search"
272
+ id="search-filter-2"
273
+ />
274
+ </div>
275
+ <input className="form__inline-submit__button" type="submit" value="Søg" />
205
276
  </div>
206
- <div className="selection-list__option">
207
- <input type="checkbox" id="option-8" />
208
- <label htmlFor="option-8">Technical Sciences</label>
277
+ </form>
278
+ <form
279
+ className="toolbar__filter__content__options-and-actions"
280
+ onSubmit={(event) => {
281
+ event.preventDefault();
282
+ unlockBodyScroll();
283
+ }}
284
+ >
285
+ <div
286
+ className="toolbar__filter__content__options"
287
+ >
288
+ <div className="toolbar__filter__content__options__scroll-container">
289
+ <fieldset className="selection-list">
290
+ <legend>
291
+ 3 valgmuligheder
292
+ </legend>
293
+ <div className="selection-list__option">
294
+ <input type="checkbox" id="option-10" />
295
+ <label htmlFor="option-10">Valgmulighed 1</label>
296
+ </div>
297
+ <div className="selection-list__option">
298
+ <input type="checkbox" id="option-20" />
299
+ <label htmlFor="option-20">Valgmulighed 2</label>
300
+ </div>
301
+ <div className="selection-list__option">
302
+ <input type="checkbox" id="option-30" />
303
+ <label htmlFor="option-30">Valgmulighed 3</label>
304
+ </div>
305
+ </fieldset>
306
+ </div>
209
307
  </div>
210
- <div className="selection-list__option">
211
- <input type="checkbox" id="option-9" />
212
- <label htmlFor="option-9">Aarhus BSS</label>
308
+ <div className="toolbar__filter__content__actions">
309
+ <div className="button-container">
310
+ <input type="submit" className="content-toggle__close button button--small" value="Gem" />
311
+ </div>
213
312
  </div>
214
- </div>
215
- </fieldset>
313
+ </form>
314
+ </div>
315
+ <button
316
+ type="button"
317
+ className="toolbar__popout__close content-toggle__close button button--icon button--icon--hide-label icon-close"
318
+ onClick={() => unlockBodyScroll()}
319
+ >
320
+ Luk
321
+ </button>
216
322
  </div>
217
323
  </div>
218
324
  </AUContentToggleComponent>