@lumx/react 2.2.18 → 2.2.20

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 (100) hide show
  1. package/esm/_internal/ButtonRoot.js.map +1 -1
  2. package/esm/_internal/Checkbox2.js +3 -1
  3. package/esm/_internal/Checkbox2.js.map +1 -1
  4. package/esm/_internal/ClickAwayProvider.js +90 -12
  5. package/esm/_internal/ClickAwayProvider.js.map +1 -1
  6. package/esm/_internal/DatePickerField.js +18 -11
  7. package/esm/_internal/DatePickerField.js.map +1 -1
  8. package/esm/_internal/Dialog2.js +2 -2
  9. package/esm/_internal/Dialog2.js.map +1 -1
  10. package/esm/_internal/GenericBlock.js +90 -0
  11. package/esm/_internal/GenericBlock.js.map +1 -0
  12. package/esm/_internal/Lightbox2.js +2 -2
  13. package/esm/_internal/Lightbox2.js.map +1 -1
  14. package/esm/_internal/LinkPreview.js +22 -12
  15. package/esm/_internal/LinkPreview.js.map +1 -1
  16. package/esm/_internal/Popover2.js +21 -8
  17. package/esm/_internal/Popover2.js.map +1 -1
  18. package/esm/_internal/SelectMultiple.js +16 -4
  19. package/esm/_internal/SelectMultiple.js.map +1 -1
  20. package/esm/_internal/Tooltip2.js +3 -7
  21. package/esm/_internal/Tooltip2.js.map +1 -1
  22. package/esm/_internal/UserBlock.js +9 -2
  23. package/esm/_internal/UserBlock.js.map +1 -1
  24. package/esm/_internal/alert-dialog.js +2 -2
  25. package/esm/_internal/autocomplete.js +2 -1
  26. package/esm/_internal/autocomplete.js.map +1 -1
  27. package/esm/_internal/button.js +2 -1
  28. package/esm/_internal/button.js.map +1 -1
  29. package/esm/_internal/comment-block.js +2 -1
  30. package/esm/_internal/comment-block.js.map +1 -1
  31. package/esm/_internal/date-picker.js +3 -2
  32. package/esm/_internal/date-picker.js.map +1 -1
  33. package/esm/_internal/dialog.js +2 -2
  34. package/esm/_internal/dropdown.js +2 -1
  35. package/esm/_internal/dropdown.js.map +1 -1
  36. package/esm/_internal/expansion-panel.js +1 -1
  37. package/esm/_internal/generic-block.js +12 -0
  38. package/esm/_internal/generic-block.js.map +1 -0
  39. package/esm/_internal/lightbox.js +3 -2
  40. package/esm/_internal/lightbox.js.map +1 -1
  41. package/esm/_internal/popover.js +2 -1
  42. package/esm/_internal/popover.js.map +1 -1
  43. package/esm/_internal/select.js +2 -1
  44. package/esm/_internal/select.js.map +1 -1
  45. package/esm/_internal/side-navigation.js +2 -1
  46. package/esm/_internal/side-navigation.js.map +1 -1
  47. package/esm/_internal/slideshow.js +2 -1
  48. package/esm/_internal/slideshow.js.map +1 -1
  49. package/esm/_internal/text-field.js +2 -1
  50. package/esm/_internal/text-field.js.map +1 -1
  51. package/esm/_internal/tooltip.js +2 -1
  52. package/esm/_internal/tooltip.js.map +1 -1
  53. package/esm/_internal/type.js.map +1 -1
  54. package/esm/_internal/useFocusTrap.js +65 -72
  55. package/esm/_internal/useFocusTrap.js.map +1 -1
  56. package/esm/_internal/user-block.js +1 -0
  57. package/esm/_internal/user-block.js.map +1 -1
  58. package/esm/index.js +4 -2
  59. package/esm/index.js.map +1 -1
  60. package/package.json +5 -5
  61. package/src/components/button/Button.stories.tsx +1 -0
  62. package/src/components/button/ButtonRoot.tsx +4 -4
  63. package/src/components/checkbox/Checkbox.tsx +2 -1
  64. package/src/components/checkbox/__snapshots__/Checkbox.test.tsx.snap +4 -0
  65. package/src/components/date-picker/DatePickerField.tsx +15 -16
  66. package/src/components/date-picker/types.ts +2 -2
  67. package/src/components/dialog/Dialog.stories.tsx +57 -14
  68. package/src/components/dialog/Dialog.tsx +1 -1
  69. package/src/components/dialog/__snapshots__/Dialog.test.tsx.snap +160 -91
  70. package/src/components/generic-block/GenericBlock.stories.tsx +149 -0
  71. package/src/components/generic-block/GenericBlock.test.tsx +28 -0
  72. package/src/components/generic-block/GenericBlock.tsx +120 -0
  73. package/src/components/generic-block/__snapshots__/GenericBlock.test.tsx.snap +92 -0
  74. package/src/components/generic-block/index.ts +1 -0
  75. package/src/components/lightbox/Lightbox.tsx +1 -1
  76. package/src/components/link-preview/LinkPreview.test.tsx +50 -55
  77. package/src/components/link-preview/LinkPreview.tsx +43 -16
  78. package/src/components/popover/Popover.tsx +20 -4
  79. package/src/components/select/Select.stories.tsx +2 -0
  80. package/src/components/select/Select.tsx +11 -1
  81. package/src/components/select/SelectMultiple.stories.tsx +2 -0
  82. package/src/components/select/SelectMultiple.tsx +11 -1
  83. package/src/components/select/constants.ts +2 -0
  84. package/src/components/table/__snapshots__/Table.test.tsx.snap +5 -0
  85. package/src/components/tooltip/Tooltip.tsx +2 -5
  86. package/src/components/user-block/UserBlock.stories.tsx +4 -4
  87. package/src/components/user-block/UserBlock.tsx +9 -3
  88. package/src/components/user-block/__snapshots__/UserBlock.test.tsx.snap +51 -8
  89. package/src/hooks/useBooleanState.tsx +4 -10
  90. package/src/hooks/useCallbackOnEscape.ts +21 -13
  91. package/src/hooks/useFocusTrap.ts +67 -76
  92. package/src/index.ts +1 -0
  93. package/src/stories/generated/Dialog/Demos.stories.tsx +1 -0
  94. package/src/stories/generated/GenericBlock/Demos.stories.tsx +6 -0
  95. package/src/utils/focus/getFirstAndLastFocusable.test.ts +128 -0
  96. package/src/utils/focus/getFirstAndLastFocusable.ts +27 -0
  97. package/src/utils/makeListenerTowerContext.ts +32 -0
  98. package/src/utils/type.ts +3 -0
  99. package/types.d.ts +50 -9
  100. package/src/components/link-preview/__snapshots__/LinkPreview.test.tsx.snap +0 -51
@@ -1,3 +1,4 @@
1
+ import noop from 'lodash/noop';
1
2
  import { mdiClose } from '@lumx/icons';
2
3
  import {
3
4
  AlertDialog,
@@ -17,7 +18,8 @@ import {
17
18
  } from '@lumx/react';
18
19
  import { DIALOG_TRANSITION_DURATION } from '@lumx/core/js/constants';
19
20
  import { select } from '@storybook/addon-knobs';
20
- import React, { RefObject, useRef, useState } from 'react';
21
+ import React, { RefObject, useCallback, useRef, useState } from 'react';
22
+ import { useBooleanState } from '@lumx/react/hooks/useBooleanState';
21
23
  import { Dialog, DialogSizes } from './Dialog';
22
24
  import { loremIpsum } from '../../stories/knobs/lorem';
23
25
  import { chromaticForceScreenSize } from '../../stories/chromaticForceScreenSize';
@@ -43,8 +45,8 @@ const footer = <footer className="lumx-spacing-padding">Dialog footer</footer>;
43
45
  function useOpenButton(theme: Theme, defaultState = true) {
44
46
  const buttonRef = useRef() as RefObject<HTMLButtonElement>;
45
47
  const [isOpen, setOpen] = useState(defaultState);
46
- const openDialog = () => setOpen(true);
47
- const closeDialog = () => setOpen(false);
48
+ const openDialog = useCallback(() => setOpen(true), []);
49
+ const closeDialog = useCallback(() => setOpen(false), []);
48
50
 
49
51
  return {
50
52
  button: (
@@ -283,7 +285,8 @@ export const ScrollableDialogWithHeaderAndFooter = ({ theme }: any) => {
283
285
  );
284
286
  };
285
287
 
286
- export const DialogWithFocusableElements = ({ theme }: any) => {
288
+ /** Test dialog focus trap (focus is contained inside the dialog) with all kinds of focusable and non-focusable items */
289
+ export const DialogFocusTrap = ({ theme }: any) => {
287
290
  const { button, buttonRef, closeDialog, isOpen } = useOpenButton(theme);
288
291
  const [textValue, setTextValue] = useState('value');
289
292
  const [checkboxValue, setCheckboxValue] = useState(false);
@@ -300,6 +303,9 @@ export const DialogWithFocusableElements = ({ theme }: any) => {
300
303
  };
301
304
  const [date, setDate] = useState<Date | undefined>(new Date('2020-05-18'));
302
305
 
306
+ const datePickerDialogButtonRef = useRef<HTMLButtonElement>(null);
307
+ const [isDatePickerDialogOpen, closeDatePickerDialog, openDatePickerDialog] = useBooleanState(false);
308
+
303
309
  return (
304
310
  <>
305
311
  {button}
@@ -334,16 +340,51 @@ export const DialogWithFocusableElements = ({ theme }: any) => {
334
340
  />
335
341
 
336
342
  <FlexBox orientation="horizontal" hAlign="bottom" gap="regular">
337
- <DatePickerField
338
- locale="fr"
339
- label="Start date"
340
- placeholder="Pick a date"
341
- theme={theme}
342
- onChange={setDate}
343
- value={date}
344
- nextButtonProps={{ label: 'Next month' }}
345
- previousButtonProps={{ label: 'Previous month' }}
346
- />
343
+ <Button ref={datePickerDialogButtonRef} onClick={openDatePickerDialog}>
344
+ Open date picker
345
+ </Button>
346
+ <Dialog
347
+ isOpen={isDatePickerDialogOpen}
348
+ parentElement={datePickerDialogButtonRef}
349
+ onClose={closeDatePickerDialog}
350
+ >
351
+ <header>
352
+ <Toolbar
353
+ label={<h1 className="lumx-typography-title">Date picker</h1>}
354
+ after={
355
+ <IconButton
356
+ label="Close"
357
+ icon={mdiClose}
358
+ onClick={closeDatePickerDialog}
359
+ emphasis={Emphasis.low}
360
+ />
361
+ }
362
+ />
363
+ </header>
364
+ <div className="lumx-spacing-padding">
365
+ <DatePickerField
366
+ locale="fr"
367
+ label="Start date"
368
+ placeholder="Pick a date"
369
+ theme={theme}
370
+ onChange={setDate}
371
+ value={date}
372
+ nextButtonProps={{ label: 'Next month' }}
373
+ previousButtonProps={{ label: 'Previous month' }}
374
+ />
375
+ <DatePickerField
376
+ locale="fr"
377
+ label="Start date"
378
+ placeholder="Pick a date"
379
+ theme={theme}
380
+ onChange={noop}
381
+ value={undefined}
382
+ nextButtonProps={{ label: 'Next month' }}
383
+ previousButtonProps={{ label: 'Previous month' }}
384
+ defaultMonth={new Date('2020-05-18')}
385
+ />
386
+ </div>
387
+ </Dialog>
347
388
 
348
389
  <Select
349
390
  className="lumx-spacing-margin-left-huge"
@@ -372,6 +413,8 @@ export const DialogWithFocusableElements = ({ theme }: any) => {
372
413
 
373
414
  {/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */}
374
415
  <div tabIndex={0}>Focus div</div>
416
+
417
+ <Button isDisabled={false}>Button explicitly not disabled (should focus)</Button>
375
418
  </div>
376
419
  </Dialog>
377
420
  </>
@@ -142,7 +142,7 @@ export const Dialog: Comp<DialogProps, HTMLDivElement> = forwardRef((props, ref)
142
142
  const localContentRef = useRef<HTMLDivElement>(null);
143
143
  // Handle focus trap.
144
144
  // eslint-disable-next-line react-hooks/rules-of-hooks
145
- useFocusTrap(wrapperRef.current, focusElement?.current);
145
+ useFocusTrap(isOpen && wrapperRef.current, focusElement?.current);
146
146
 
147
147
  // eslint-disable-next-line react-hooks/rules-of-hooks
148
148
  useDisableBodyScroll(isOpen && localContentRef.current);
@@ -1,82 +1,6 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`<Dialog> Snapshots and structure should render story DialogWithAlertDialog 1`] = `
4
- <Fragment>
5
- <Button
6
- emphasis="high"
7
- onClick={[Function]}
8
- size="m"
9
- theme="light"
10
- >
11
- Open dialog
12
- </Button>
13
- <Dialog
14
- isOpen={true}
15
- onClose={[Function]}
16
- parentElement={
17
- Object {
18
- "current": undefined,
19
- }
20
- }
21
- size="big"
22
- >
23
- <div
24
- className="lumx-spacing-padding"
25
- >
26
-
27
- Nihil hic munitissimus habendi senatus locus, nihil horum? At nos hinc posthac, sitientis piros
28
- Afros. Magna pars studiorum, prodita quaerimus. Integer legentibus erat a ante historiarum
29
- dapibus. Praeterea iter est quasdam res quas ex communi. Ullamco laboris nisi ut aliquid ex ea
30
- commodi consequat. Inmensae subtilitatis, obscuris et malesuada fames. Me non paenitet nullum
31
- festiviorem excogitasse ad hoc. Cum ceteris in veneratione tui montes, nascetur mus. Etiam
32
- habebis sem dicantur magna mollis euismod. Quis aute iure reprehenderit in voluptate velit esse.
33
- Phasellus laoreet lorem vel dolor tempus vehicula. Ambitioni dedisse scripsisse iudicaretur.
34
- Paullum deliquit, ponderibus modulisque suis ratio utitur. Ab illo tempore, ab est sed
35
- immemorabili. Nec dubitamus multa iter quae et nos invenerat. Tu quoque, Brute, fili mi, nihil
36
- timor populi, nihil! Morbi fringilla convallis sapien, id pulvinar odio volutpat. Cras mattis
37
- iudicium purus sit amet fermentum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus.
38
- Quisque ut dolor gravida, placerat libero vel, euismod. Unam incolunt Belgae, aliam Aquitani,
39
- tertiam. Cras mattis iudicium purus sit amet fermentum
40
- </div>
41
- <footer>
42
- <Toolbar
43
- after={
44
- <Button
45
- emphasis="low"
46
- onClick={[Function]}
47
- size="m"
48
- theme="light"
49
- >
50
- Close
51
- </Button>
52
- }
53
- />
54
- </footer>
55
- </Dialog>
56
- <AlertDialog
57
- confirmProps={
58
- Object {
59
- "label": "Confirm",
60
- "onClick": [Function],
61
- }
62
- }
63
- isOpen={false}
64
- kind="info"
65
- onClose={[Function]}
66
- parentElement={
67
- Object {
68
- "current": undefined,
69
- }
70
- }
71
- size="tiny"
72
- title="Default (info)"
73
- >
74
- Consequat deserunt officia aute laborum tempor anim sint est.
75
- </AlertDialog>
76
- </Fragment>
77
- `;
78
-
79
- exports[`<Dialog> Snapshots and structure should render story DialogWithFocusableElements 1`] = `
3
+ exports[`<Dialog> Snapshots and structure should render story DialogFocusTrap 1`] = `
80
4
  <Fragment>
81
5
  <Button
82
6
  emphasis="high"
@@ -156,23 +80,84 @@ exports[`<Dialog> Snapshots and structure should render story DialogWithFocusabl
156
80
  hAlign="bottom"
157
81
  orientation="horizontal"
158
82
  >
159
- <DatePickerField
160
- label="Start date"
161
- locale="fr"
162
- nextButtonProps={
163
- Object {
164
- "label": "Next month",
165
- }
166
- }
167
- onChange={[Function]}
168
- placeholder="Pick a date"
169
- previousButtonProps={
83
+ <Button
84
+ emphasis="high"
85
+ onClick={[Function]}
86
+ size="m"
87
+ theme="light"
88
+ >
89
+ Open date picker
90
+ </Button>
91
+ <Dialog
92
+ isOpen={false}
93
+ onClose={[Function]}
94
+ parentElement={
170
95
  Object {
171
- "label": "Previous month",
96
+ "current": null,
172
97
  }
173
98
  }
174
- value={2020-05-18T00:00:00.000Z}
175
- />
99
+ size="big"
100
+ >
101
+ <header>
102
+ <Toolbar
103
+ after={
104
+ <IconButton
105
+ emphasis="low"
106
+ icon="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
107
+ label="Close"
108
+ onClick={[Function]}
109
+ size="m"
110
+ theme="light"
111
+ />
112
+ }
113
+ label={
114
+ <h1
115
+ className="lumx-typography-title"
116
+ >
117
+ Date picker
118
+ </h1>
119
+ }
120
+ />
121
+ </header>
122
+ <div
123
+ className="lumx-spacing-padding"
124
+ >
125
+ <DatePickerField
126
+ label="Start date"
127
+ locale="fr"
128
+ nextButtonProps={
129
+ Object {
130
+ "label": "Next month",
131
+ }
132
+ }
133
+ onChange={[Function]}
134
+ placeholder="Pick a date"
135
+ previousButtonProps={
136
+ Object {
137
+ "label": "Previous month",
138
+ }
139
+ }
140
+ value={2020-05-18T00:00:00.000Z}
141
+ />
142
+ <DatePickerField
143
+ defaultMonth={2020-05-18T00:00:00.000Z}
144
+ label="Start date"
145
+ locale="fr"
146
+ nextButtonProps={
147
+ Object {
148
+ "label": "Next month",
149
+ }
150
+ }
151
+ onChange={[Function]}
152
+ placeholder="Pick a date"
153
+ previousButtonProps={
154
+ Object {
155
+ "label": "Previous month",
156
+ }
157
+ }
158
+ />
159
+ </div>
160
+ </Dialog>
176
161
  <Select
177
162
  className="lumx-spacing-margin-left-huge"
178
163
  isOpen={false}
@@ -226,11 +211,95 @@ exports[`<Dialog> Snapshots and structure should render story DialogWithFocusabl
226
211
  >
227
212
  Focus div
228
213
  </div>
214
+ <Button
215
+ emphasis="high"
216
+ isDisabled={false}
217
+ size="m"
218
+ theme="light"
219
+ >
220
+ Button explicitly not disabled (should focus)
221
+ </Button>
229
222
  </div>
230
223
  </Dialog>
231
224
  </Fragment>
232
225
  `;
233
226
 
227
+ exports[`<Dialog> Snapshots and structure should render story DialogWithAlertDialog 1`] = `
228
+ <Fragment>
229
+ <Button
230
+ emphasis="high"
231
+ onClick={[Function]}
232
+ size="m"
233
+ theme="light"
234
+ >
235
+ Open dialog
236
+ </Button>
237
+ <Dialog
238
+ isOpen={true}
239
+ onClose={[Function]}
240
+ parentElement={
241
+ Object {
242
+ "current": undefined,
243
+ }
244
+ }
245
+ size="big"
246
+ >
247
+ <div
248
+ className="lumx-spacing-padding"
249
+ >
250
+
251
+ Nihil hic munitissimus habendi senatus locus, nihil horum? At nos hinc posthac, sitientis piros
252
+ Afros. Magna pars studiorum, prodita quaerimus. Integer legentibus erat a ante historiarum
253
+ dapibus. Praeterea iter est quasdam res quas ex communi. Ullamco laboris nisi ut aliquid ex ea
254
+ commodi consequat. Inmensae subtilitatis, obscuris et malesuada fames. Me non paenitet nullum
255
+ festiviorem excogitasse ad hoc. Cum ceteris in veneratione tui montes, nascetur mus. Etiam
256
+ habebis sem dicantur magna mollis euismod. Quis aute iure reprehenderit in voluptate velit esse.
257
+ Phasellus laoreet lorem vel dolor tempus vehicula. Ambitioni dedisse scripsisse iudicaretur.
258
+ Paullum deliquit, ponderibus modulisque suis ratio utitur. Ab illo tempore, ab est sed
259
+ immemorabili. Nec dubitamus multa iter quae et nos invenerat. Tu quoque, Brute, fili mi, nihil
260
+ timor populi, nihil! Morbi fringilla convallis sapien, id pulvinar odio volutpat. Cras mattis
261
+ iudicium purus sit amet fermentum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus.
262
+ Quisque ut dolor gravida, placerat libero vel, euismod. Unam incolunt Belgae, aliam Aquitani,
263
+ tertiam. Cras mattis iudicium purus sit amet fermentum
264
+ </div>
265
+ <footer>
266
+ <Toolbar
267
+ after={
268
+ <Button
269
+ emphasis="low"
270
+ onClick={[Function]}
271
+ size="m"
272
+ theme="light"
273
+ >
274
+ Close
275
+ </Button>
276
+ }
277
+ />
278
+ </footer>
279
+ </Dialog>
280
+ <AlertDialog
281
+ confirmProps={
282
+ Object {
283
+ "label": "Confirm",
284
+ "onClick": [Function],
285
+ }
286
+ }
287
+ isOpen={false}
288
+ kind="info"
289
+ onClose={[Function]}
290
+ parentElement={
291
+ Object {
292
+ "current": undefined,
293
+ }
294
+ }
295
+ size="tiny"
296
+ title="Default (info)"
297
+ >
298
+ Consequat deserunt officia aute laborum tempor anim sint est.
299
+ </AlertDialog>
300
+ </Fragment>
301
+ `;
302
+
234
303
  exports[`<Dialog> Snapshots and structure should render story DialogWithHeaderFooterAndDivider 1`] = `
235
304
  <Fragment>
236
305
  <Button
@@ -0,0 +1,149 @@
1
+ import React from 'react';
2
+ import { mdiPencil } from '@lumx/icons';
3
+ import { GenericBlock, Button, Icon, Size, Orientation, Alignment } from '@lumx/react';
4
+
5
+ export default { title: 'LumX components/generic-block/GenericBlock' };
6
+
7
+ export const Horizontal = ({ theme }: any) => (
8
+ <GenericBlock
9
+ orientation={Orientation.horizontal}
10
+ figure={<Icon icon={mdiPencil} size={Size.m} />}
11
+ actionsProps={{
12
+ style: { border: '1px solid red' },
13
+ }}
14
+ figureProps={{
15
+ style: { border: '1px solid red' },
16
+ }}
17
+ contentProps={{
18
+ style: { border: '1px solid red' },
19
+ }}
20
+ actions={<Button theme={theme}>Button</Button>}
21
+ >
22
+ Content
23
+ </GenericBlock>
24
+ );
25
+
26
+ export const HorizontalWithAlignment = ({ theme }: any) => (
27
+ <GenericBlock
28
+ orientation={Orientation.horizontal}
29
+ figure={<Icon icon={mdiPencil} size={Size.m} />}
30
+ actionsProps={{
31
+ fillSpace: true,
32
+ style: { border: '1px solid red' },
33
+ vAlign: 'center',
34
+ }}
35
+ figureProps={{
36
+ style: { border: '1px solid red' },
37
+ }}
38
+ contentProps={{
39
+ style: { border: '1px solid red' },
40
+ }}
41
+ actions={<Button theme={theme}>Centered button</Button>}
42
+ >
43
+ Content
44
+ </GenericBlock>
45
+ );
46
+
47
+ export const HorizontalTop = ({ theme }: any) => (
48
+ <GenericBlock
49
+ orientation={Orientation.horizontal}
50
+ hAlign={Alignment.top}
51
+ figure={<Icon icon={mdiPencil} size={Size.m} />}
52
+ actionsProps={{
53
+ style: { border: '1px solid red' },
54
+ }}
55
+ figureProps={{
56
+ style: { border: '1px solid red' },
57
+ }}
58
+ contentProps={{
59
+ style: { border: '1px solid red' },
60
+ }}
61
+ actions={<Button theme={theme}>Centered button</Button>}
62
+ >
63
+ Content
64
+ </GenericBlock>
65
+ );
66
+
67
+ export const Vertical = ({ theme }: any) => (
68
+ <GenericBlock
69
+ orientation={Orientation.vertical}
70
+ figure={<Icon icon={mdiPencil} size={Size.m} />}
71
+ actionsProps={{
72
+ fillSpace: true,
73
+ style: { border: '1px solid red' },
74
+ }}
75
+ figureProps={{
76
+ style: { border: '1px solid red' },
77
+ }}
78
+ contentProps={{
79
+ style: { border: '1px solid red' },
80
+ }}
81
+ actions={<Button theme={theme}>Button</Button>}
82
+ >
83
+ Content
84
+ </GenericBlock>
85
+ );
86
+
87
+ export const GapSizes = ({ theme }: any) => (
88
+ <>
89
+ <GenericBlock
90
+ orientation={Orientation.vertical}
91
+ figure={<Icon icon={mdiPencil} size={Size.m} />}
92
+ gap={Size.regular}
93
+ style={{ marginBottom: 40 }}
94
+ actionsProps={{
95
+ style: { border: '1px solid red' },
96
+ }}
97
+ figureProps={{
98
+ style: { border: '1px solid red' },
99
+ }}
100
+ contentProps={{
101
+ style: { border: '1px solid red' },
102
+ }}
103
+ actions={<Button theme={theme}>Button</Button>}
104
+ >
105
+ <h2>Small gap size</h2>
106
+ <p>For small blocks</p>
107
+ </GenericBlock>
108
+
109
+ <GenericBlock
110
+ orientation={Orientation.vertical}
111
+ figure={<Icon icon={mdiPencil} size={Size.m} />}
112
+ gap={Size.big}
113
+ style={{ marginBottom: 40 }}
114
+ actionsProps={{
115
+ style: { border: '1px solid red' },
116
+ }}
117
+ figureProps={{
118
+ style: { border: '1px solid red' },
119
+ }}
120
+ contentProps={{
121
+ style: { border: '1px solid red' },
122
+ }}
123
+ actions={<Button theme={theme}>Button</Button>}
124
+ >
125
+ <h2>Medium gap size</h2>
126
+ <p>For medium blocks</p>
127
+ </GenericBlock>
128
+
129
+ <GenericBlock
130
+ orientation={Orientation.vertical}
131
+ figure={<Icon icon={mdiPencil} size={Size.m} />}
132
+ gap={Size.huge}
133
+ style={{ marginBottom: 40 }}
134
+ actionsProps={{
135
+ style: { border: '1px solid red' },
136
+ }}
137
+ figureProps={{
138
+ style: { border: '1px solid red' },
139
+ }}
140
+ contentProps={{
141
+ style: { border: '1px solid red' },
142
+ }}
143
+ actions={<Button theme={theme}>Button</Button>}
144
+ >
145
+ <h2>Big gap size</h2>
146
+ <p>For large blocks</p>
147
+ </GenericBlock>
148
+ </>
149
+ );
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { mount, shallow } from 'enzyme';
3
+ import 'jest-enzyme';
4
+ import { commonTestsSuite, itShouldRenderStories } from '@lumx/react/testing/utils';
5
+
6
+ import { GenericBlock, GenericBlockProps } from './GenericBlock';
7
+ import * as stories from '../../stories/generated/GenericBlock/Demos.stories';
8
+
9
+ const CLASSNAME = GenericBlock.className as string;
10
+
11
+ /**
12
+ * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
13
+ */
14
+ const setup = (props: Partial<GenericBlockProps> = {}, shallowRendering = true) => {
15
+ const renderer: any = shallowRendering ? shallow : mount;
16
+ const wrapper: any = renderer(<GenericBlock {...(props as any)} />);
17
+ return { props, wrapper };
18
+ };
19
+
20
+ describe(`<${GenericBlock.displayName}>`, () => {
21
+ // 1. Test render via snapshot.
22
+ describe('Snapshots and structure', () => {
23
+ itShouldRenderStories(stories, GenericBlock);
24
+ });
25
+
26
+ // Common tests suite.
27
+ commonTestsSuite(setup, { className: 'wrapper', prop: 'wrapper' }, { className: CLASSNAME });
28
+ });