@lumx/react 3.1.5 → 3.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.
Files changed (143) hide show
  1. package/_internal/types.d.ts +16 -5
  2. package/index.d.ts +45 -4
  3. package/index.js +609 -411
  4. package/index.js.map +1 -1
  5. package/package.json +3 -3
  6. package/src/components/alert-dialog/AlertDialog.stories.tsx +96 -165
  7. package/src/components/alert-dialog/AlertDialog.test.tsx +15 -23
  8. package/src/components/avatar/Avatar.stories.tsx +91 -62
  9. package/src/components/avatar/Avatar.test.tsx +9 -24
  10. package/src/components/badge/Badge.stories.tsx +63 -38
  11. package/src/components/button/Button.stories.tsx +147 -139
  12. package/src/components/button/IconButton.stories.tsx +45 -0
  13. package/src/components/checkbox/Checkbox.stories.tsx +37 -30
  14. package/src/components/chip/Chip.stories.tsx +77 -15
  15. package/src/components/comment-block/CommentBlock.stories.tsx +90 -25
  16. package/src/components/comment-block/CommentBlock.test.tsx +12 -17
  17. package/src/components/date-picker/DatePickerField.stories.tsx +52 -83
  18. package/src/components/dialog/Dialog.stories.tsx +131 -293
  19. package/src/components/dialog/Dialog.test.tsx +0 -32
  20. package/src/components/dropdown/Dropdown.stories.tsx +1 -186
  21. package/src/components/flag/Flag.stories.tsx +33 -18
  22. package/src/components/flag/Flag.test.tsx +1 -8
  23. package/src/components/flex-box/FlexBox.stories.tsx +151 -238
  24. package/src/components/flex-box/FlexBox.test.tsx +9 -49
  25. package/src/components/generic-block/GenericBlock.stories.jsx +1 -1
  26. package/src/components/grid-column/GridColumn.stories.tsx +46 -0
  27. package/src/components/heading/Heading.stories.tsx +57 -95
  28. package/src/components/icon/Icon.stories.tsx +67 -70
  29. package/src/components/image-block/ImageBlock.stories.tsx +103 -47
  30. package/src/components/image-block/ImageBlock.test.tsx +12 -17
  31. package/src/components/inline-list/InlineList.stories.tsx +45 -29
  32. package/src/components/input-helper/InputHelper.stories.tsx +31 -25
  33. package/src/components/input-label/InputLabel.stories.tsx +33 -10
  34. package/src/components/lightbox/Lightbox.stories.tsx +39 -77
  35. package/src/components/lightbox/Lightbox.test.tsx +12 -17
  36. package/src/components/link/Link.stories.tsx +98 -128
  37. package/src/components/link-preview/LinkPreview.stories.tsx +48 -75
  38. package/src/components/list/List.stories.tsx +59 -84
  39. package/src/components/list/List.test.tsx +8 -17
  40. package/src/components/list/ListDivider.stories.tsx +9 -4
  41. package/src/components/list/ListDivider.test.tsx +12 -17
  42. package/src/components/list/ListItem.stories.tsx +97 -59
  43. package/src/components/list/ListItem.test.tsx +12 -17
  44. package/src/components/list/ListSubheader.stories.tsx +8 -5
  45. package/src/components/list/ListSubheader.test.tsx +12 -18
  46. package/src/components/message/Message.stories.tsx +51 -22
  47. package/src/components/mosaic/Mosaic.stories.tsx +78 -74
  48. package/src/components/mosaic/Mosaic.test.tsx +0 -31
  49. package/src/components/navigation/Navigation.stories.tsx +67 -0
  50. package/src/components/navigation/Navigation.test.tsx +58 -0
  51. package/src/components/navigation/Navigation.tsx +62 -0
  52. package/src/components/navigation/NavigationItem.test.tsx +37 -0
  53. package/src/components/navigation/NavigationItem.tsx +89 -0
  54. package/src/components/navigation/NavigationSection.test.tsx +126 -0
  55. package/src/components/navigation/NavigationSection.tsx +109 -0
  56. package/src/components/navigation/context.tsx +6 -0
  57. package/src/components/navigation/index.ts +1 -0
  58. package/src/components/notification/Notifications.stories.tsx +52 -47
  59. package/src/components/popover/Popover.stories.tsx +68 -201
  60. package/src/components/popover-dialog/PopoverDialog.stories.tsx +26 -65
  61. package/src/components/post-block/PostBlock.test.tsx +12 -17
  62. package/src/components/progress/ProgressCircular.stories.tsx +24 -12
  63. package/src/components/progress/ProgressLinear.stories.tsx +6 -2
  64. package/src/components/radio-button/RadioButton.stories.tsx +35 -24
  65. package/src/components/select/Select.stories.tsx +19 -23
  66. package/src/components/skeleton/SkeletonCircle.stories.tsx +37 -21
  67. package/src/components/skeleton/SkeletonCircle.test.tsx +12 -17
  68. package/src/components/skeleton/SkeletonRectangle.stories.tsx +74 -99
  69. package/src/components/skeleton/SkeletonRectangle.test.tsx +12 -17
  70. package/src/components/skeleton/SkeletonTypography.test.tsx +12 -17
  71. package/src/components/slider/Slider.stories.tsx +41 -25
  72. package/src/components/slider/Slider.test.tsx +12 -18
  73. package/src/components/slideshow/Slideshow.stories.tsx +31 -61
  74. package/src/components/slideshow/Slideshow.test.tsx +15 -23
  75. package/src/components/slideshow/SlideshowControls.stories.tsx +4 -6
  76. package/src/components/switch/Switch.stories.tsx +35 -32
  77. package/src/components/table/Table.test.tsx +12 -17
  78. package/src/components/tabs/Tabs.stories.tsx +4 -3
  79. package/src/components/text/Text.stories.tsx +130 -0
  80. package/src/components/text-field/TextField.stories.tsx +114 -148
  81. package/src/components/thumbnail/Thumbnail.stories.tsx +106 -255
  82. package/src/components/thumbnail/Thumbnail.test.tsx +12 -35
  83. package/src/components/tooltip/Tooltip.stories.tsx +51 -136
  84. package/src/components/user-block/UserBlock.stories.tsx +67 -56
  85. package/src/components/user-block/UserBlock.test.tsx +1 -5
  86. package/src/index.ts +1 -0
  87. package/src/stories/controls/color.ts +6 -0
  88. package/src/stories/controls/element.ts +6 -0
  89. package/src/stories/controls/focusPoint.ts +1 -0
  90. package/src/stories/controls/icons.ts +6 -0
  91. package/src/stories/{knobs → controls}/image.ts +6 -16
  92. package/src/stories/controls/selectArgType.ts +4 -0
  93. package/src/stories/controls/theme.ts +3 -0
  94. package/src/stories/controls/typography.ts +5 -0
  95. package/src/stories/controls/withUndefined.ts +1 -0
  96. package/src/stories/decorators/withChromaticForceScreenSize.tsx +8 -0
  97. package/src/stories/decorators/withCombinations.tsx +99 -0
  98. package/src/stories/decorators/withNestedProps.tsx +23 -0
  99. package/src/stories/{withResizableBox.tsx → decorators/withResizableBox.tsx} +6 -10
  100. package/src/stories/decorators/withValueOnChange.tsx +18 -0
  101. package/src/stories/decorators/withWrapper.tsx +19 -0
  102. package/src/stories/utils/CustomLink.tsx +8 -2
  103. package/src/stories/{knobs → utils}/lorem.ts +9 -9
  104. package/src/testing/utils/commonTestsSuiteRTL.ts +2 -3
  105. package/src/testing/utils/index.ts +0 -2
  106. package/src/untypped-modules.d.ts +0 -2
  107. package/src/utils/MaterialThemeSwitcher/MaterialThemeSwitcher.tsx +1 -1
  108. package/src/utils/ThemeContext.ts +4 -0
  109. package/src/utils/forwardRefPolymorphic.ts +9 -0
  110. package/src/utils/type.ts +28 -4
  111. package/src/components/alert-dialog/__snapshots__/AlertDialog.test.tsx.snap +0 -558
  112. package/src/components/avatar/__snapshots__/Avatar.test.tsx.snap +0 -681
  113. package/src/components/comment-block/__snapshots__/CommentBlock.test.tsx.snap +0 -92
  114. package/src/components/dialog/__snapshots__/Dialog.test.tsx.snap +0 -1133
  115. package/src/components/expansion-panel/ExpansionPanel.stories.tsx +0 -65
  116. package/src/components/flag/__snapshots__/Flag.test.tsx.snap +0 -133
  117. package/src/components/flex-box/__snapshots__/FlexBox.test.tsx.snap +0 -492
  118. package/src/components/grid-column/GridColumn.stories.jsx +0 -56
  119. package/src/components/image-block/__snapshots__/ImageBlock.test.tsx.snap +0 -64
  120. package/src/components/lightbox/__snapshots__/Lightbox.test.tsx.snap +0 -194
  121. package/src/components/list/__snapshots__/List.test.tsx.snap +0 -360
  122. package/src/components/list/__snapshots__/ListDivider.test.tsx.snap +0 -7
  123. package/src/components/list/__snapshots__/ListItem.test.tsx.snap +0 -160
  124. package/src/components/list/__snapshots__/ListSubheader.test.tsx.snap +0 -9
  125. package/src/components/mosaic/__snapshots__/Mosaic.test.tsx.snap +0 -357
  126. package/src/components/post-block/__snapshots__/PostBlock.test.tsx.snap +0 -139
  127. package/src/components/skeleton/__snapshots__/SkeletonCircle.test.tsx.snap +0 -54
  128. package/src/components/skeleton/__snapshots__/SkeletonRectangle.test.tsx.snap +0 -177
  129. package/src/components/skeleton/__snapshots__/SkeletonTypography.test.tsx.snap +0 -174
  130. package/src/components/slider/__snapshots__/Slider.test.tsx.snap +0 -122
  131. package/src/components/slideshow/__snapshots__/Slideshow.test.tsx.snap +0 -157
  132. package/src/components/table/__snapshots__/Table.test.tsx.snap +0 -263
  133. package/src/components/text/Text.stories.jsx +0 -75
  134. package/src/components/thumbnail/__snapshots__/Thumbnail.test.tsx.snap +0 -130
  135. package/src/components/user-block/__snapshots__/UserBlock.test.tsx.snap +0 -362
  136. package/src/stories/chromaticForceScreenSize.tsx +0 -7
  137. package/src/stories/knobs/buttonKnob.ts +0 -9
  138. package/src/stories/knobs/emphasisKnob.ts +0 -8
  139. package/src/stories/knobs/enumKnob.ts +0 -14
  140. package/src/stories/knobs/focusKnob.ts +0 -3
  141. package/src/stories/knobs/sizeKnob.ts +0 -5
  142. package/src/stories/knobs/thumbnailsKnob.ts +0 -9
  143. package/src/testing/utils/itShouldRenderStories.tsx +0 -103
package/package.json CHANGED
@@ -7,8 +7,8 @@
7
7
  },
8
8
  "dependencies": {
9
9
  "@juggle/resize-observer": "^3.2.0",
10
- "@lumx/core": "^3.1.5",
11
- "@lumx/icons": "^3.1.5",
10
+ "@lumx/core": "^3.2.0",
11
+ "@lumx/icons": "^3.2.0",
12
12
  "@popperjs/core": "^2.5.4",
13
13
  "body-scroll-lock": "^3.1.5",
14
14
  "classnames": "^2.2.6",
@@ -113,5 +113,5 @@
113
113
  "build:storybook": "cd storybook && ./build"
114
114
  },
115
115
  "sideEffects": false,
116
- "version": "3.1.5"
116
+ "version": "3.2.0"
117
117
  }
@@ -1,11 +1,27 @@
1
- import React, { RefObject, useRef, useState } from 'react';
2
- import { Button, Theme, Link } from '@lumx/react';
1
+ /* eslint-disable react-hooks/rules-of-hooks */
2
+ import React, { RefObject, useRef } from 'react';
3
+ import { Button, Link, Kind } from '@lumx/react';
3
4
  import { DIALOG_TRANSITION_DURATION } from '@lumx/core/js/constants';
4
- import { chromaticForceScreenSize } from '../../stories/chromaticForceScreenSize';
5
+ import { useBooleanState } from '@lumx/react/hooks/useBooleanState';
6
+ import { withNestedProps } from '@lumx/react/stories/decorators/withNestedProps';
7
+ import { loremIpsum } from '@lumx/react/stories/utils/lorem';
8
+ import { getSelectArgType } from '@lumx/react/stories/controls/selectArgType';
9
+ import { withChromaticForceScreenSize } from '../../stories/decorators/withChromaticForceScreenSize';
5
10
  import { AlertDialog } from './AlertDialog';
11
+ import DialogStories from '../dialog/Dialog.stories';
6
12
 
7
13
  export default {
8
14
  title: 'LumX components/alert-dialog/AlertDialog',
15
+ component: AlertDialog,
16
+ args: {
17
+ ...AlertDialog.defaultProps,
18
+ 'confirmProps.label': 'Ok',
19
+ },
20
+ argTypes: {
21
+ size: DialogStories.argTypes.size,
22
+ kind: getSelectArgType(Kind),
23
+ 'confirmProps.onClick': { action: true },
24
+ },
9
25
  parameters: {
10
26
  // Delay Chromatic snapshot to wait for dialog to open.
11
27
  chromatic: {
@@ -13,184 +29,99 @@ export default {
13
29
  delay: DIALOG_TRANSITION_DURATION,
14
30
  },
15
31
  },
16
- // Force minimum chromatic screen size to make sure the dialog appears in view.
17
- decorators: [chromaticForceScreenSize],
18
- };
19
-
20
- const defaultProps = {
21
- id: 'alert-dialog',
22
- confirmProps: { onClick: () => alert('confirm'), label: 'OK' },
32
+ decorators: [
33
+ // Force minimum chromatic screen size to make sure the dialog appears in view.
34
+ withChromaticForceScreenSize(),
35
+ withNestedProps(),
36
+ ],
37
+ render(props: any) {
38
+ const buttonRef = useRef() as RefObject<HTMLButtonElement>;
39
+ const [isOpen, close, open] = useBooleanState(true);
40
+ return (
41
+ <>
42
+ <Button ref={buttonRef} onClick={open}>
43
+ Open dialog
44
+ </Button>
45
+ <AlertDialog {...props} isOpen={isOpen} onClose={close} parentElement={buttonRef} />
46
+ </>
47
+ );
48
+ },
23
49
  };
24
50
 
25
- function useOpenButton(theme: Theme) {
26
- const buttonRef = useRef() as RefObject<HTMLButtonElement>;
27
- const [isOpen, setOpen] = useState(true);
28
- const openDialog = () => setOpen(true);
29
- const closeDialog = () => setOpen(false);
30
-
31
- return {
32
- button: (
33
- <Button ref={buttonRef} onClick={openDialog} theme={theme}>
34
- Open dialog
35
- </Button>
36
- ),
37
- buttonRef,
38
- closeDialog,
39
- isOpen,
40
- };
41
- }
42
-
43
- export const Default = ({ theme }: any) => {
44
- const { button, buttonRef, closeDialog, isOpen } = useOpenButton(theme);
45
-
46
- return (
47
- <>
48
- {button}
49
- <AlertDialog
50
- isOpen={isOpen}
51
- onClose={closeDialog}
52
- parentElement={buttonRef}
53
- title="Default (info)"
54
- confirmProps={{ onClick: () => console.log('confirm'), label: 'Confirm' }}
55
- >
56
- Consequat deserunt officia aute laborum tempor anim sint est.
57
- </AlertDialog>
58
- </>
59
- );
51
+ /**
52
+ * Alert dialog with default kind
53
+ */
54
+ export const DefaultKind = {
55
+ args: {
56
+ title: 'Default (info)',
57
+ children: loremIpsum('tiny'),
58
+ },
60
59
  };
61
60
 
62
- export const Warning = ({ theme }: any) => {
63
- const { button, buttonRef, closeDialog, isOpen } = useOpenButton(theme);
64
-
65
- return (
66
- <>
67
- {button}
68
- <AlertDialog
69
- isOpen={isOpen}
70
- title="Warning"
71
- onClose={closeDialog}
72
- parentElement={buttonRef}
73
- kind="warning"
74
- {...defaultProps}
75
- >
76
- Consequat deserunt officia aute laborum tempor anim sint est.
77
- </AlertDialog>
78
- </>
79
- );
61
+ /**
62
+ * Alert dialog as warning
63
+ */
64
+ export const Warning = {
65
+ args: {
66
+ ...DefaultKind.args,
67
+ kind: Kind.warning,
68
+ title: 'Warning',
69
+ },
80
70
  };
81
71
 
82
- export const Success = ({ theme }: any) => {
83
- const { button, buttonRef, closeDialog, isOpen } = useOpenButton(theme);
84
-
85
- return (
86
- <>
87
- {button}
88
- <AlertDialog
89
- isOpen={isOpen}
90
- title="Success"
91
- onClose={closeDialog}
92
- parentElement={buttonRef}
93
- kind="success"
94
- {...defaultProps}
95
- >
96
- Consequat deserunt officia aute laborum tempor anim sint est.
97
- </AlertDialog>
98
- </>
99
- );
72
+ /**
73
+ * Alert dialog as success
74
+ */
75
+ export const Success = {
76
+ args: {
77
+ ...DefaultKind.args,
78
+ kind: Kind.success,
79
+ title: 'Success',
80
+ },
100
81
  };
101
82
 
102
- export const Error = ({ theme }: any) => {
103
- const { button, buttonRef, closeDialog, isOpen } = useOpenButton(theme);
104
-
105
- return (
106
- <>
107
- {button}
108
- <AlertDialog
109
- isOpen={isOpen}
110
- title="Error"
111
- onClose={closeDialog}
112
- parentElement={buttonRef}
113
- kind="error"
114
- {...defaultProps}
115
- >
116
- Consequat deserunt officia aute laborum tempor anim sint est.
117
- </AlertDialog>
118
- </>
119
- );
83
+ /**
84
+ * Alert dialog as error
85
+ */
86
+ export const Error = {
87
+ args: {
88
+ ...DefaultKind.args,
89
+ kind: Kind.error,
90
+ title: 'Error',
91
+ },
120
92
  };
121
93
 
122
- export const WithCancel = ({ theme }: any) => {
123
- const { button, buttonRef, closeDialog, isOpen } = useOpenButton(theme);
124
-
125
- return (
126
- <>
127
- {button}
128
- <AlertDialog
129
- {...defaultProps}
130
- title="With Cancel"
131
- isOpen={isOpen}
132
- onClose={closeDialog}
133
- parentElement={buttonRef}
134
- cancelProps={{
135
- label: 'Cancel',
136
- onClick: closeDialog,
137
- }}
138
- >
139
- Consequat deserunt officia aute laborum tempor anim sint est.
140
- </AlertDialog>
141
- </>
142
- );
94
+ /**
95
+ * Alert dialog with cancel button
96
+ */
97
+ export const WithCancel = {
98
+ argTypes: {
99
+ 'cancelProps.onClick': { action: true },
100
+ },
101
+ args: {
102
+ ...DefaultKind.args,
103
+ title: 'With Cancel',
104
+ 'cancelProps.label': 'Cancel',
105
+ },
143
106
  };
144
107
 
145
- export const RichDescription = ({ theme }: any) => {
146
- const { button, buttonRef, closeDialog, isOpen } = useOpenButton(theme);
147
-
148
- return (
149
- <>
150
- {button}
151
- <AlertDialog
152
- {...defaultProps}
153
- title="With Rich Description"
154
- isOpen={isOpen}
155
- onClose={closeDialog}
156
- parentElement={buttonRef}
157
- >
108
+ /**
109
+ * Alert dialog with rich description
110
+ */
111
+ export const RichDescription = {
112
+ argTypes: { children: { control: false } },
113
+ args: {
114
+ ...DefaultKind.args,
115
+ title: 'With Rich Description',
116
+ children: (
117
+ <>
158
118
  Amet ut elit dolore irure mollit <strong>sunt culpa esse</strong>.<br />
159
119
  Ea ut Lorem.
160
120
  <br />
161
121
  <Link href="https://example.com" target="_blank">
162
122
  Link
163
123
  </Link>
164
- </AlertDialog>
165
- </>
166
- );
167
- };
168
-
169
- export const WithForwardedProps = ({ theme }: any) => {
170
- const { button, buttonRef, closeDialog, isOpen } = useOpenButton(theme);
171
-
172
- return (
173
- <>
174
- {button}
175
- <AlertDialog
176
- {...defaultProps}
177
- title="With Forwarded Props"
178
- isOpen={isOpen}
179
- onClose={closeDialog}
180
- parentElement={buttonRef}
181
- cancelProps={{
182
- label: 'Cancel',
183
- onClick: closeDialog,
184
- style: { color: 'blue' },
185
- }}
186
- confirmProps={{
187
- onClick: () => alert('confirm'),
188
- label: 'OK',
189
- style: { color: 'red' },
190
- }}
191
- >
192
- Consequat deserunt officia aute laborum tempor anim sint est.
193
- </AlertDialog>
194
- </>
195
- );
124
+ </>
125
+ ),
126
+ },
196
127
  };
@@ -1,11 +1,9 @@
1
- import React, { ReactElement } from 'react';
1
+ import React from 'react';
2
2
 
3
- import { mount, shallow } from 'enzyme';
4
- import 'jest-enzyme';
5
-
6
- import { commonTestsSuite, itShouldRenderStories, Wrapper } from '@lumx/react/testing/utils';
3
+ import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
4
+ import { queryByClassName } from '@lumx/react/testing/utils/queries';
5
+ import { render } from '@testing-library/react';
7
6
  import { AlertDialog, AlertDialogProps } from './AlertDialog';
8
- import * as stories from './AlertDialog.stories';
9
7
 
10
8
  jest.mock('uid', () => ({ uid: () => 'uid' }));
11
9
 
@@ -14,30 +12,24 @@ const CLASSNAME = AlertDialog.className as string;
14
12
  /**
15
13
  * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
16
14
  */
17
- const setup = ({ ...propsOverride }: Partial<AlertDialogProps> = {}, shallowRendering = true) => {
15
+ const setup = (propsOverride: Partial<AlertDialogProps> = {}) => {
18
16
  const props: AlertDialogProps = {
19
17
  title: 'Alert',
18
+ isOpen: true,
20
19
  description: 'Deserunt et sunt qui consequat sint sit.',
21
- // eslint-disable-next-line no-alert
22
- confirmProps: { onClick: () => alert('confirm'), label: 'OK' },
20
+ confirmProps: { onClick: jest.fn(), label: 'OK' },
23
21
  ...propsOverride,
24
22
  };
25
- const renderer: (el: ReactElement) => Wrapper = shallowRendering ? shallow : mount;
26
- const wrapper: Wrapper = renderer(<AlertDialog {...props} />);
27
-
28
- return {
29
- AlertDialog: wrapper.find(`Dialog`),
30
- props,
31
- wrapper,
32
- };
23
+ render(<AlertDialog {...props} />);
24
+ const alertDialog = queryByClassName(document.body, CLASSNAME);
25
+ return { alertDialog, props };
33
26
  };
34
27
 
35
28
  describe(`<${AlertDialog.displayName}>`, () => {
36
- // 1. Test render via snapshot.
37
- describe('Snapshots and structure', () => {
38
- itShouldRenderStories(stories, AlertDialog);
39
- });
40
-
41
29
  // Common tests suite.
42
- commonTestsSuite(setup, { className: 'AlertDialog', prop: 'AlertDialog' }, { className: CLASSNAME });
30
+ commonTestsSuiteRTL(setup, {
31
+ baseClassName: CLASSNAME,
32
+ forwardClassName: 'alertDialog',
33
+ forwardAttributes: 'alertDialog',
34
+ });
43
35
  });
@@ -1,43 +1,71 @@
1
+ /* eslint-disable react/display-name */
1
2
  import React from 'react';
2
- import { select } from '@storybook/addon-knobs';
3
3
 
4
4
  import { mdiDelete, mdiEye, mdiPencil, mdiStar } from '@lumx/icons';
5
- import { Badge, ColorPalette, FlexBox, Icon, IconButton, Size } from '@lumx/react';
6
- import { AVATAR_IMAGES, avatarImageKnob, PORTRAIT_IMAGES } from '@lumx/react/stories/knobs/image';
5
+ import { AvatarSize, Badge, ColorPalette, FlexBox, Icon, IconButton, Size } from '@lumx/react';
6
+ import { avatarImageArgType, AVATAR_IMAGES } from '@lumx/react/stories/controls/image';
7
7
  import { CustomLink } from '@lumx/react/stories/utils/CustomLink';
8
8
 
9
+ import { getSelectArgType } from '@lumx/react/stories/controls/selectArgType';
10
+ import { withCombinations } from '@lumx/react/stories/decorators/withCombinations';
11
+ import { colorArgType } from '@lumx/react/stories/controls/color';
12
+ import { withNestedProps } from '@lumx/react/stories/decorators/withNestedProps';
13
+ import { iconArgType } from '@lumx/react/stories/controls/icons';
9
14
  import { Avatar } from './Avatar';
10
15
 
11
- export default { title: 'LumX components/avatar/Avatar' };
12
-
13
16
  const AVATAR_SIZES = [Size.xs, Size.s, Size.m, Size.l, Size.xl, Size.xxl];
14
17
 
18
+ export default {
19
+ title: 'LumX components/avatar/Avatar',
20
+ component: Avatar,
21
+ argTypes: {
22
+ image: avatarImageArgType,
23
+ size: getSelectArgType<AvatarSize>(AVATAR_SIZES),
24
+ },
25
+ args: { image: AVATAR_IMAGES.avatar1 },
26
+ };
27
+
15
28
  /**
16
- * Avatar stories showing a simple Avatar with different sizes.
17
- * @return component with different sizes.
29
+ * Default avatar
18
30
  */
19
- export const Sizes = () =>
20
- AVATAR_SIZES.map((size) => (
21
- <Avatar
22
- key={size}
23
- className="lumx-spacing-margin-bottom"
24
- image={avatarImageKnob('Avatar', AVATAR_IMAGES.avatar1)}
25
- alt={size}
26
- size={size}
27
- />
28
- ));
31
+ export const Default = {};
32
+
33
+ /**
34
+ * Having onClick transforming the avatar into a button
35
+ */
36
+ export const AvatarButton = {
37
+ argTypes: {
38
+ onClick: { action: true },
39
+ },
40
+ };
41
+
42
+ /**
43
+ * Having href transforming the avatar into a link
44
+ */
45
+ export const AvatarLink = {
46
+ args: {
47
+ href: 'https://example.com',
48
+ target: '_blank',
49
+ },
50
+ };
51
+
52
+ /**
53
+ * Having linkAs transforming the avatar into a custom link
54
+ */
55
+ export const AvatarCustomLink = {
56
+ args: {
57
+ linkAs: CustomLink,
58
+ },
59
+ };
29
60
 
30
61
  /**
31
- * Avatar story showing a simple avatar with different actions.
32
- * @return component with different actions.
62
+ * Avatar with actions
33
63
  */
34
- export const WithActions = () =>
35
- AVATAR_SIZES.map((size) => (
64
+ export const WithActions = {
65
+ args: { size: Size.xl },
66
+ render: (props: any) => (
36
67
  <Avatar
37
- key={size}
38
- image={avatarImageKnob('Avatar', AVATAR_IMAGES.avatar2)}
39
- alt={size}
40
- size={size}
68
+ {...props}
41
69
  actions={
42
70
  <FlexBox orientation="horizontal" gap="regular" vAlign="center">
43
71
  <IconButton label="Edit" emphasis="low" hasBackground icon={mdiPencil} size="s" />
@@ -46,47 +74,48 @@ export const WithActions = () =>
46
74
  </FlexBox>
47
75
  }
48
76
  />
49
- ));
77
+ ),
78
+ };
79
+
80
+ /**
81
+ * All sizes
82
+ */
83
+ export const AllSizes = {
84
+ argTypes: {
85
+ size: { control: false },
86
+ },
87
+ decorators: [
88
+ withCombinations({
89
+ combinations: {
90
+ cols: { key: 'size', options: AVATAR_SIZES },
91
+ },
92
+ }),
93
+ ],
94
+ };
50
95
 
51
- export const WithBadge = () =>
52
- AVATAR_SIZES.map((size) => (
96
+ /**
97
+ * All sizes with badge
98
+ */
99
+ export const AllSizesWithBadge = {
100
+ ...AllSizes,
101
+ args: {
102
+ 'badge.color': ColorPalette.blue,
103
+ 'badge.icon': mdiStar,
104
+ },
105
+ argTypes: {
106
+ ...AllSizes.argTypes,
107
+ 'badge.color': colorArgType,
108
+ 'badge.icon': iconArgType,
109
+ },
110
+ decorators: [...AllSizes.decorators, withNestedProps()],
111
+ render: ({ badge, ...props }: any) => (
53
112
  <Avatar
54
- key={size}
55
- className="lumx-spacing-margin-bottom"
56
- image={avatarImageKnob('Avatar', AVATAR_IMAGES.avatar3)}
57
- alt={size}
113
+ {...(props as any)}
58
114
  badge={
59
- <Badge color={select('Colors', ColorPalette, ColorPalette.blue)}>
60
- <Icon icon={mdiStar} />
115
+ <Badge color={badge.color}>
116
+ <Icon icon={badge.icon} />
61
117
  </Badge>
62
118
  }
63
- size={size}
64
- />
65
- ));
66
-
67
- export const WithRectangularImage = () =>
68
- AVATAR_SIZES.map((size) => (
69
- <Avatar
70
- key={size}
71
- className="lumx-spacing-margin-bottom"
72
- image={PORTRAIT_IMAGES.portrait3}
73
- alt={size}
74
- size={size}
75
119
  />
76
- ));
77
-
78
- export const Clickable = () => {
79
- const baseProps = { size: 'l', image: AVATAR_IMAGES.avatar2, alt: 'avatar2' } as any;
80
- return (
81
- <>
82
- <p>As a button</p>
83
- <Avatar {...baseProps} onClick={() => alert('clicked on avatar')} />
84
-
85
- <p>As a link</p>
86
- <Avatar {...baseProps} linkProps={{ href: 'https://example.com' }} />
87
-
88
- <p>As a custom link component</p>
89
- <Avatar {...baseProps} linkAs={CustomLink} />
90
- </>
91
- );
120
+ ),
92
121
  };
@@ -1,39 +1,24 @@
1
- import React, { ReactElement } from 'react';
1
+ import React from 'react';
2
2
 
3
- import { mount, shallow } from 'enzyme';
4
- import 'jest-enzyme';
5
-
6
- import { commonTestsSuite, itShouldRenderStories, Wrapper } from '@lumx/react/testing/utils';
3
+ import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
4
+ import { render } from '@testing-library/react';
5
+ import { queryByClassName } from '@lumx/react/testing/utils/queries';
7
6
  import { Avatar, AvatarProps } from './Avatar';
8
- import * as stories from './Avatar.stories';
9
7
 
10
8
  const CLASSNAME = Avatar.className as string;
11
9
 
12
- /**
13
- * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
14
- */
15
- const setup = ({ ...propsOverride }: Partial<AvatarProps> = {}, shallowRendering = true) => {
10
+ const setup = (propsOverride: Partial<AvatarProps> = {}) => {
16
11
  const props: AvatarProps = {
17
12
  image: 'path/to/avatar/image.png',
18
13
  alt: 'Image',
19
14
  ...propsOverride,
20
15
  };
21
- const renderer: (el: ReactElement) => Wrapper = shallowRendering ? shallow : mount;
22
- const wrapper: Wrapper = renderer(<Avatar {...props} />);
23
-
24
- return {
25
- avatar: wrapper.find(`div`),
26
- props,
27
- wrapper,
28
- };
16
+ render(<Avatar {...props} />);
17
+ const avatar = queryByClassName(document.body, CLASSNAME);
18
+ return { avatar, props };
29
19
  };
30
20
 
31
21
  describe(`<${Avatar.displayName}>`, () => {
32
- // 1. Test render via snapshot.
33
- describe('Snapshots and structure', () => {
34
- itShouldRenderStories(stories, Avatar);
35
- });
36
-
37
22
  // Common tests suite.
38
- commonTestsSuite(setup, { className: 'avatar', prop: 'avatar' }, { className: CLASSNAME });
23
+ commonTestsSuiteRTL(setup, { baseClassName: CLASSNAME, forwardClassName: 'avatar', forwardAttributes: 'avatar' });
39
24
  });