@lumx/react 3.10.0 → 3.10.1-alpha.1

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 (146) hide show
  1. package/_internal/index.d.ts +1 -1
  2. package/index.d.ts +24 -16
  3. package/index.js +313 -293
  4. package/index.js.map +1 -1
  5. package/package.json +3 -3
  6. package/src/components/alert-dialog/AlertDialog.tsx +3 -4
  7. package/src/components/autocomplete/Autocomplete.test.tsx +9 -2
  8. package/src/components/autocomplete/Autocomplete.tsx +7 -4
  9. package/src/components/autocomplete/AutocompleteMultiple.test.tsx +9 -2
  10. package/src/components/autocomplete/AutocompleteMultiple.tsx +10 -7
  11. package/src/components/avatar/Avatar.test.tsx +14 -4
  12. package/src/components/avatar/Avatar.tsx +7 -5
  13. package/src/components/badge/Badge.tsx +7 -4
  14. package/src/components/badge/BadgeWrapper.tsx +7 -4
  15. package/src/components/button/Button.test.tsx +9 -3
  16. package/src/components/button/Button.tsx +8 -5
  17. package/src/components/button/ButtonGroup.tsx +4 -3
  18. package/src/components/button/ButtonRoot.tsx +4 -3
  19. package/src/components/button/IconButton.test.tsx +9 -3
  20. package/src/components/button/IconButton.tsx +16 -5
  21. package/src/components/checkbox/Checkbox.test.tsx +9 -3
  22. package/src/components/checkbox/Checkbox.tsx +8 -7
  23. package/src/components/chip/Chip.test.tsx +14 -4
  24. package/src/components/chip/Chip.tsx +11 -11
  25. package/src/components/chip/ChipGroup.tsx +5 -4
  26. package/src/components/comment-block/CommentBlock.test.tsx +9 -3
  27. package/src/components/comment-block/CommentBlock.tsx +7 -6
  28. package/src/components/date-picker/DatePicker.tsx +5 -3
  29. package/src/components/date-picker/DatePickerControlled.tsx +6 -3
  30. package/src/components/date-picker/DatePickerField.test.tsx +9 -3
  31. package/src/components/date-picker/DatePickerField.tsx +4 -3
  32. package/src/components/dialog/Dialog.test.tsx +17 -4
  33. package/src/components/dialog/Dialog.tsx +65 -61
  34. package/src/components/divider/Divider.test.tsx +9 -3
  35. package/src/components/divider/Divider.tsx +8 -7
  36. package/src/components/drag-handle/DragHandle.test.tsx +38 -0
  37. package/src/components/drag-handle/DragHandle.tsx +7 -4
  38. package/src/components/dropdown/Dropdown.tsx +4 -3
  39. package/src/components/expansion-panel/ExpansionPanel.test.tsx +12 -3
  40. package/src/components/expansion-panel/ExpansionPanel.tsx +8 -7
  41. package/src/components/flag/Flag.test.tsx +14 -4
  42. package/src/components/flag/Flag.tsx +9 -7
  43. package/src/components/flex-box/FlexBox.tsx +8 -5
  44. package/src/components/generic-block/GenericBlock.tsx +4 -1
  45. package/src/components/grid/Grid.tsx +4 -3
  46. package/src/components/grid/GridItem.tsx +4 -3
  47. package/src/components/grid-column/GridColumn.tsx +5 -5
  48. package/src/components/heading/Heading.tsx +8 -4
  49. package/src/components/icon/Icon.test.tsx +13 -4
  50. package/src/components/icon/Icon.tsx +18 -5
  51. package/src/components/image-block/ImageBlock.test.tsx +12 -4
  52. package/src/components/image-block/ImageBlock.tsx +7 -5
  53. package/src/components/image-lightbox/ImageLightbox.tsx +4 -3
  54. package/src/components/inline-list/InlineList.tsx +4 -3
  55. package/src/components/input-helper/InputHelper.test.tsx +14 -4
  56. package/src/components/input-helper/InputHelper.tsx +10 -6
  57. package/src/components/input-label/InputLabel.test.tsx +14 -4
  58. package/src/components/input-label/InputLabel.tsx +11 -8
  59. package/src/components/lightbox/Lightbox.test.tsx +17 -6
  60. package/src/components/lightbox/Lightbox.tsx +12 -8
  61. package/src/components/link/Link.tsx +4 -3
  62. package/src/components/link-preview/LinkPreview.test.tsx +9 -3
  63. package/src/components/link-preview/LinkPreview.tsx +7 -5
  64. package/src/components/list/List.tsx +7 -5
  65. package/src/components/list/ListDivider.tsx +4 -3
  66. package/src/components/list/ListItem.tsx +4 -3
  67. package/src/components/list/ListSubheader.tsx +4 -3
  68. package/src/components/message/Message.tsx +7 -4
  69. package/src/components/mosaic/Mosaic.test.tsx +9 -3
  70. package/src/components/mosaic/Mosaic.tsx +11 -9
  71. package/src/components/navigation/Navigation.test.tsx +18 -9
  72. package/src/components/navigation/Navigation.tsx +13 -5
  73. package/src/components/navigation/NavigationItem.tsx +4 -4
  74. package/src/components/navigation/NavigationSection.test.tsx +19 -6
  75. package/src/components/navigation/NavigationSection.tsx +4 -4
  76. package/src/components/notification/Notification.tsx +7 -8
  77. package/src/components/popover/Popover.test.tsx +18 -4
  78. package/src/components/popover/Popover.tsx +5 -3
  79. package/src/components/popover-dialog/PopoverDialog.tsx +5 -3
  80. package/src/components/post-block/PostBlock.test.tsx +9 -3
  81. package/src/components/post-block/PostBlock.tsx +7 -8
  82. package/src/components/progress/Progress.tsx +8 -6
  83. package/src/components/progress/ProgressCircular.test.tsx +9 -16
  84. package/src/components/progress/ProgressCircular.tsx +7 -6
  85. package/src/components/progress/ProgressLinear.test.tsx +13 -18
  86. package/src/components/progress/ProgressLinear.tsx +8 -8
  87. package/src/components/progress-tracker/ProgressTracker.tsx +5 -3
  88. package/src/components/progress-tracker/ProgressTrackerStep.tsx +5 -5
  89. package/src/components/progress-tracker/ProgressTrackerStepPanel.tsx +24 -24
  90. package/src/components/radio-button/RadioButton.test.tsx +9 -3
  91. package/src/components/radio-button/RadioButton.tsx +8 -8
  92. package/src/components/radio-button/RadioGroup.tsx +4 -3
  93. package/src/components/select/Select.test.tsx +9 -3
  94. package/src/components/select/Select.tsx +30 -28
  95. package/src/components/select/SelectMultiple.test.tsx +9 -3
  96. package/src/components/select/SelectMultiple.tsx +112 -108
  97. package/src/components/select/WithSelectContext.tsx +8 -6
  98. package/src/components/side-navigation/SideNavigation.tsx +7 -5
  99. package/src/components/side-navigation/SideNavigationItem.tsx +4 -5
  100. package/src/components/skeleton/SkeletonCircle.test.tsx +9 -3
  101. package/src/components/skeleton/SkeletonCircle.tsx +9 -7
  102. package/src/components/skeleton/SkeletonRectangle.test.tsx +9 -3
  103. package/src/components/skeleton/SkeletonRectangle.tsx +8 -5
  104. package/src/components/skeleton/SkeletonTypography.test.tsx +9 -3
  105. package/src/components/skeleton/SkeletonTypography.tsx +9 -7
  106. package/src/components/slider/Slider.test.tsx +9 -3
  107. package/src/components/slider/Slider.tsx +7 -7
  108. package/src/components/slideshow/Slides.tsx +9 -5
  109. package/src/components/slideshow/Slideshow.test.tsx +9 -3
  110. package/src/components/slideshow/Slideshow.tsx +8 -5
  111. package/src/components/slideshow/SlideshowControls.tsx +7 -5
  112. package/src/components/slideshow/SlideshowItem.tsx +4 -3
  113. package/src/components/slideshow/SlideshowItemGroup.tsx +5 -4
  114. package/src/components/switch/Switch.test.tsx +9 -3
  115. package/src/components/switch/Switch.tsx +7 -7
  116. package/src/components/table/Table.test.tsx +9 -3
  117. package/src/components/table/Table.tsx +8 -8
  118. package/src/components/table/TableBody.tsx +4 -3
  119. package/src/components/table/TableCell.tsx +5 -5
  120. package/src/components/table/TableHeader.tsx +4 -3
  121. package/src/components/table/TableRow.tsx +4 -3
  122. package/src/components/tabs/Tab.tsx +4 -3
  123. package/src/components/tabs/TabList.test.tsx +9 -3
  124. package/src/components/tabs/TabList.tsx +18 -6
  125. package/src/components/tabs/TabPanel.tsx +7 -5
  126. package/src/components/text/Text.tsx +6 -4
  127. package/src/components/text-field/TextField.test.tsx +9 -3
  128. package/src/components/text-field/TextField.tsx +7 -5
  129. package/src/components/thumbnail/Thumbnail.test.tsx +9 -3
  130. package/src/components/thumbnail/Thumbnail.tsx +8 -7
  131. package/src/components/toolbar/Toolbar.tsx +4 -3
  132. package/src/components/tooltip/Tooltip.tsx +4 -3
  133. package/src/components/uploader/Uploader.test.tsx +9 -3
  134. package/src/components/uploader/Uploader.tsx +18 -5
  135. package/src/components/user-block/UserBlock.test.tsx +9 -3
  136. package/src/components/user-block/UserBlock.tsx +9 -6
  137. package/src/index.ts +1 -0
  138. package/src/testing/utils/ThemeSentinel.tsx +11 -0
  139. package/src/testing/utils/commonTestsSuiteRTL.tsx +191 -0
  140. package/src/utils/react/forwardRef.ts +10 -0
  141. package/src/utils/react/forwardRefPolymorphic.ts +10 -0
  142. package/src/utils/theme/ThemeContext.ts +16 -0
  143. package/src/utils/theme/invertTheme.ts +4 -0
  144. package/src/testing/utils/commonTestsSuiteRTL.ts +0 -64
  145. package/src/utils/ThemeContext.ts +0 -4
  146. package/src/utils/forwardRefPolymorphic.ts +0 -9
@@ -1,8 +1,12 @@
1
+ import React, { ReactNode } from 'react';
2
+
3
+ import classNames from 'classnames';
4
+
1
5
  import { Theme } from '@lumx/react';
2
- import { Comp, GenericProps, HasTheme } from '@lumx/react/utils/type';
6
+ import { GenericProps, HasTheme } from '@lumx/react/utils/type';
3
7
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
4
- import classNames from 'classnames';
5
- import React, { forwardRef, ReactNode } from 'react';
8
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
9
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
6
10
 
7
11
  /**
8
12
  * Defines the props of the component.
@@ -29,9 +33,7 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
29
33
  /**
30
34
  * Component default props.
31
35
  */
32
- const DEFAULT_PROPS: Partial<InputLabelProps> = {
33
- theme: Theme.light,
34
- };
36
+ const DEFAULT_PROPS: Partial<InputLabelProps> = {};
35
37
 
36
38
  /**
37
39
  * InputLabel component.
@@ -40,8 +42,9 @@ const DEFAULT_PROPS: Partial<InputLabelProps> = {
40
42
  * @param ref Component ref.
41
43
  * @return React element.
42
44
  */
43
- export const InputLabel: Comp<InputLabelProps, HTMLLabelElement> = forwardRef((props, ref) => {
44
- const { children, className, htmlFor, isRequired, theme, ...forwardedProps } = props;
45
+ export const InputLabel = forwardRef<InputLabelProps, HTMLLabelElement>((props, ref) => {
46
+ const defaultTheme = useTheme() || Theme.light;
47
+ const { children, className, htmlFor, isRequired, theme = defaultTheme, ...forwardedProps } = props;
45
48
 
46
49
  return (
47
50
  <label
@@ -1,18 +1,24 @@
1
1
  import React from 'react';
2
2
 
3
- import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
3
+ import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
4
4
  import { queryByClassName } from '@lumx/react/testing/utils/queries';
5
- import { render } from '@testing-library/react';
5
+ import { render, screen } from '@testing-library/react';
6
+ import { ThemeSentinel } from '@lumx/react/testing/utils/ThemeSentinel';
6
7
 
7
8
  import { Lightbox, LightboxProps } from './Lightbox';
8
9
 
9
10
  const CLASSNAME = Lightbox.className as string;
10
11
 
11
- const setup = (props: Partial<LightboxProps> = {}) => {
12
- const propsOverride = { isOpen: true, ...props } as any;
13
- const { container } = render(<Lightbox {...propsOverride} />);
12
+ const setup = (props: Partial<LightboxProps> = {}, { wrapper }: SetupRenderOptions = {}) => {
13
+ const propsOverride = {
14
+ isOpen: true,
15
+ children: <ThemeSentinel />,
16
+ ...props,
17
+ } as any;
18
+ const { container } = render(<Lightbox {...propsOverride} />, { wrapper });
14
19
  const lightbox = queryByClassName(document.body, CLASSNAME);
15
- return { props, container, lightbox };
20
+ const themeSentinel = screen.queryByTestId(ThemeSentinel.testId);
21
+ return { props, container, lightbox, themeSentinel };
16
22
  };
17
23
 
18
24
  describe(`<${Lightbox.displayName}>`, () => {
@@ -22,5 +28,10 @@ describe(`<${Lightbox.displayName}>`, () => {
22
28
  forwardClassName: 'lightbox',
23
29
  forwardAttributes: 'lightbox',
24
30
  forwardRef: 'lightbox',
31
+ applyTheme: {
32
+ affects: [{ not: { element: 'themeSentinel' } }],
33
+ viaProp: true,
34
+ viaContext: true,
35
+ },
25
36
  });
26
37
  });
@@ -1,4 +1,4 @@
1
- import React, { forwardRef, RefObject, useRef, useEffect, AriaAttributes } from 'react';
1
+ import React, { RefObject, useRef, useEffect, AriaAttributes } from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
  import { createPortal } from 'react-dom';
@@ -6,7 +6,7 @@ import { createPortal } from 'react-dom';
6
6
  import { mdiClose } from '@lumx/icons';
7
7
  import { IconButton, IconButtonProps } from '@lumx/react';
8
8
  import { DIALOG_TRANSITION_DURATION, DOCUMENT } from '@lumx/react/constants';
9
- import { Comp, GenericProps, HasTheme } from '@lumx/react/utils/type';
9
+ import { GenericProps, HasTheme } from '@lumx/react/utils/type';
10
10
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
11
11
 
12
12
  import { useFocusTrap } from '@lumx/react/hooks/useFocusTrap';
@@ -15,6 +15,8 @@ import { ClickAwayProvider } from '@lumx/react/utils/ClickAwayProvider';
15
15
  import { mergeRefs } from '@lumx/react/utils/mergeRefs';
16
16
  import { useCallbackOnEscape } from '@lumx/react/hooks/useCallbackOnEscape';
17
17
  import { useTransitionVisibility } from '@lumx/react/hooks/useTransitionVisibility';
18
+ import { ThemeProvider } from '@lumx/react/utils/theme/ThemeContext';
19
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
18
20
 
19
21
  /**
20
22
  * Defines the props of the component.
@@ -54,7 +56,7 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
54
56
  * @param ref Component ref.
55
57
  * @return React element.
56
58
  */
57
- export const Lightbox: Comp<LightboxProps, HTMLDivElement> = forwardRef((props, ref) => {
59
+ export const Lightbox = forwardRef<LightboxProps, HTMLDivElement>((props, ref) => {
58
60
  const {
59
61
  'aria-labelledby': propAriaLabelledBy,
60
62
  ariaLabelledBy = propAriaLabelledBy,
@@ -158,11 +160,13 @@ export const Lightbox: Comp<LightboxProps, HTMLDivElement> = forwardRef((props,
158
160
  />
159
161
  </div>
160
162
  )}
161
- <ClickAwayProvider callback={!preventAutoClose && onClose} childrenRefs={clickAwayRefs}>
162
- <div ref={childrenRef} className={`${CLASSNAME}__wrapper`} role="presentation">
163
- {children}
164
- </div>
165
- </ClickAwayProvider>
163
+ <ThemeProvider value={undefined}>
164
+ <ClickAwayProvider callback={!preventAutoClose && onClose} childrenRefs={clickAwayRefs}>
165
+ <div ref={childrenRef} className={`${CLASSNAME}__wrapper`} role="presentation">
166
+ {children}
167
+ </div>
168
+ </ClickAwayProvider>
169
+ </ThemeProvider>
166
170
  </div>,
167
171
  document.body,
168
172
  );
@@ -1,13 +1,14 @@
1
- import React, { forwardRef, RefObject, useMemo } from 'react';
1
+ import React, { RefObject, useMemo } from 'react';
2
2
 
3
3
  import isEmpty from 'lodash/isEmpty';
4
4
 
5
5
  import classNames from 'classnames';
6
6
 
7
7
  import { ColorPalette, ColorVariant, Icon, Size, Typography } from '@lumx/react';
8
- import { Comp, GenericProps } from '@lumx/react/utils/type';
8
+ import { GenericProps } from '@lumx/react/utils/type';
9
9
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
10
10
  import { renderLink } from '@lumx/react/utils/renderLink';
11
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
11
12
 
12
13
  type HTMLAnchorProps = React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>;
13
14
 
@@ -82,7 +83,7 @@ const getIconSize = (typography?: Typography) => {
82
83
  * @param ref Component ref.
83
84
  * @return React element.
84
85
  */
85
- export const Link: Comp<LinkProps, HTMLAnchorElement | HTMLButtonElement> = forwardRef((props, ref) => {
86
+ export const Link = forwardRef<LinkProps, HTMLAnchorElement | HTMLButtonElement>((props, ref) => {
86
87
  const {
87
88
  children,
88
89
  className,
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
3
+ import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
4
4
  import { Thumbnail } from '@lumx/react';
5
5
  import { render, screen, within } from '@testing-library/react';
6
6
  import { getByClassName, queryByClassName, queryAllByClassName } from '@lumx/react/testing/utils/queries';
@@ -15,10 +15,10 @@ type SetupProps = Partial<LinkPreviewProps>;
15
15
  /**
16
16
  * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
17
17
  */
18
- const setup = (propsOverride: SetupProps = {}) => {
18
+ const setup = (propsOverride: SetupProps = {}, { wrapper }: SetupRenderOptions = {}) => {
19
19
  const props: any = { ...propsOverride };
20
20
 
21
- render(<LinkPreview {...props} />);
21
+ render(<LinkPreview {...props} />, { wrapper });
22
22
  const linkPreview = getByClassName(document.body, CLASSNAME);
23
23
  const thumbnail = queryByClassName(linkPreview, Thumbnail.className as string);
24
24
  const title = queryByClassName(linkPreview, `${CLASSNAME}__title`);
@@ -97,5 +97,11 @@ describe(`<${LinkPreview.displayName}>`, () => {
97
97
  forwardClassName: 'linkPreview',
98
98
  forwardAttributes: 'linkPreview',
99
99
  forwardRef: 'linkPreview',
100
+ applyTheme: {
101
+ affects: [{ element: 'linkPreview' }],
102
+ viaProp: true,
103
+ viaContext: true,
104
+ defaultTheme: 'light',
105
+ },
100
106
  });
101
107
  });
@@ -1,4 +1,4 @@
1
- import React, { forwardRef } from 'react';
1
+ import React from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
 
@@ -14,8 +14,10 @@ import {
14
14
  ThumbnailProps,
15
15
  } from '@lumx/react';
16
16
 
17
- import { Comp, GenericProps, HeadingElement, HasTheme } from '@lumx/react/utils/type';
17
+ import { GenericProps, HeadingElement, HasTheme } from '@lumx/react/utils/type';
18
18
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
19
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
20
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
19
21
 
20
22
  /**
21
23
  * Defines the props of the component.
@@ -54,7 +56,6 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
54
56
  */
55
57
  const DEFAULT_PROPS = {
56
58
  size: Size.regular,
57
- theme: Theme.light,
58
59
  titleHeading: 'h2',
59
60
  } as const;
60
61
 
@@ -65,7 +66,8 @@ const DEFAULT_PROPS = {
65
66
  * @param ref Component ref.
66
67
  * @return React element.
67
68
  */
68
- export const LinkPreview: Comp<LinkPreviewProps, HTMLDivElement> = forwardRef((props, ref) => {
69
+ export const LinkPreview = forwardRef<LinkPreviewProps, HTMLDivElement>((props, ref) => {
70
+ const defaultTheme = useTheme() || Theme.light;
69
71
  const {
70
72
  className,
71
73
  description,
@@ -73,7 +75,7 @@ export const LinkPreview: Comp<LinkPreviewProps, HTMLDivElement> = forwardRef((p
73
75
  linkAs,
74
76
  linkProps,
75
77
  size,
76
- theme,
78
+ theme = defaultTheme,
77
79
  thumbnailProps,
78
80
  title,
79
81
  titleHeading,
@@ -1,12 +1,14 @@
1
- import { Size } from '@lumx/react';
1
+ import React, { Key, ReactNode, SyntheticEvent, useRef } from 'react';
2
+
3
+ import classNames from 'classnames';
2
4
 
5
+ import { Size } from '@lumx/react';
3
6
  import { useKeyboardListNavigation } from '@lumx/react/hooks/useKeyboardListNavigation';
4
- import { Comp, GenericProps } from '@lumx/react/utils/type';
7
+ import { GenericProps } from '@lumx/react/utils/type';
5
8
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
6
9
  import { mergeRefs } from '@lumx/react/utils/mergeRefs';
10
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
7
11
 
8
- import classNames from 'classnames';
9
- import React, { forwardRef, Key, ReactNode, SyntheticEvent, useRef } from 'react';
10
12
  import { useInteractiveList } from './useInteractiveList';
11
13
 
12
14
  /**
@@ -59,7 +61,7 @@ const DEFAULT_PROPS: Partial<ListProps> = {
59
61
  * @param ref Component ref.
60
62
  * @return React element.
61
63
  */
62
- const InternalList: Comp<ListProps, HTMLUListElement> = forwardRef((props, ref) => {
64
+ const InternalList = forwardRef<ListProps, HTMLUListElement>((props, ref) => {
63
65
  const { children, className, isClickable, itemPadding, onListItemSelected, tabIndex, ...forwardedProps } = props;
64
66
  const listElementRef = useRef<HTMLUListElement>(null);
65
67
 
@@ -1,9 +1,10 @@
1
- import React, { forwardRef } from 'react';
1
+ import React from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
 
5
- import { Comp, GenericProps } from '@lumx/react/utils/type';
5
+ import { GenericProps } from '@lumx/react/utils/type';
6
6
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
7
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
7
8
 
8
9
  /**
9
10
  * Defines the props of the component.
@@ -27,7 +28,7 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
27
28
  * @param ref Component ref.
28
29
  * @return React element.
29
30
  */
30
- export const ListDivider: Comp<ListDividerProps, HTMLLIElement> = forwardRef((props, ref) => {
31
+ export const ListDivider = forwardRef<ListDividerProps, HTMLLIElement>((props, ref) => {
31
32
  const { className, ...forwardedProps } = props;
32
33
 
33
34
  return (
@@ -1,13 +1,14 @@
1
- import React, { forwardRef, ReactNode, Ref, SyntheticEvent, useMemo } from 'react';
1
+ import React, { ReactNode, Ref, SyntheticEvent, useMemo } from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
  import isEmpty from 'lodash/isEmpty';
5
5
 
6
6
  import { ListProps, Size } from '@lumx/react';
7
- import { Comp, GenericProps } from '@lumx/react/utils/type';
7
+ import { GenericProps } from '@lumx/react/utils/type';
8
8
  import { onEnterPressed, onButtonPressed } from '@lumx/react/utils/event';
9
9
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
10
10
  import { renderLink } from '@lumx/react/utils/renderLink';
11
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
11
12
 
12
13
  export type ListItemSize = Extract<Size, 'tiny' | 'regular' | 'big' | 'huge'>;
13
14
 
@@ -74,7 +75,7 @@ export function isClickable({ linkProps, onItemSelected }: Partial<ListItemProps
74
75
  * @param ref Component ref.
75
76
  * @return React element.
76
77
  */
77
- export const ListItem: Comp<ListItemProps, HTMLLIElement> = forwardRef((props, ref) => {
78
+ export const ListItem = forwardRef<ListItemProps, HTMLLIElement>((props, ref) => {
78
79
  const {
79
80
  after,
80
81
  before,
@@ -1,9 +1,10 @@
1
- import React, { forwardRef, ReactNode } from 'react';
1
+ import React, { ReactNode } from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
 
5
- import { Comp, GenericProps } from '@lumx/react/utils/type';
5
+ import { GenericProps } from '@lumx/react/utils/type';
6
6
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
7
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
7
8
 
8
9
  /**
9
10
  * Defines the props of the component.
@@ -30,7 +31,7 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
30
31
  * @param ref Component ref.
31
32
  * @return React element.
32
33
  */
33
- export const ListSubheader: Comp<ListSubheaderProps, HTMLLIElement> = forwardRef((props, ref) => {
34
+ export const ListSubheader = forwardRef<ListSubheaderProps, HTMLLIElement>((props, ref) => {
34
35
  const { children, className, ...forwardedProps } = props;
35
36
 
36
37
  return (
@@ -1,9 +1,12 @@
1
+ import React, { ReactNode } from 'react';
2
+
3
+ import classNames from 'classnames';
4
+
1
5
  import { mdiAlert, mdiAlertCircle, mdiCheckCircle, mdiClose, mdiInformation } from '@lumx/icons';
2
6
  import { ColorPalette, Emphasis, Icon, IconButton, Kind, Size } from '@lumx/react';
3
- import { Comp, GenericProps } from '@lumx/react/utils/type';
7
+ import { GenericProps } from '@lumx/react/utils/type';
4
8
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
5
- import classNames from 'classnames';
6
- import React, { forwardRef, ReactNode } from 'react';
9
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
7
10
 
8
11
  /**
9
12
  * Defines the props of the component.
@@ -57,7 +60,7 @@ const CONFIG = {
57
60
  * @param ref Component ref.
58
61
  * @return React element.
59
62
  */
60
- export const Message: Comp<MessageProps, HTMLDivElement> = forwardRef((props, ref) => {
63
+ export const Message = forwardRef<MessageProps, HTMLDivElement>((props, ref) => {
61
64
  const { children, className, hasBackground, kind, icon: customIcon, closeButtonProps, ...forwardedProps } = props;
62
65
  const { color, icon } = CONFIG[kind as Kind] || {};
63
66
  const { onClick, label: closeButtonLabel } = closeButtonProps || {};
@@ -4,14 +4,14 @@ import { Mosaic, MosaicProps } from '@lumx/react/components/mosaic/Mosaic';
4
4
  import { render, screen, within } from '@testing-library/react';
5
5
  import { getByClassName, queryAllByClassName, queryByClassName } from '@lumx/react/testing/utils/queries';
6
6
  import { Thumbnail } from '@lumx/react';
7
- import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
7
+ import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
8
8
  import range from 'lodash/range';
9
9
  import userEvent from '@testing-library/user-event';
10
10
 
11
11
  const CLASSNAME = Mosaic.className as string;
12
12
 
13
- const setup = (props: Partial<MosaicProps> = {}) => {
14
- render(<Mosaic thumbnails={[]} {...props} />);
13
+ const setup = (props: Partial<MosaicProps> = {}, { wrapper }: SetupRenderOptions = {}) => {
14
+ render(<Mosaic thumbnails={[]} {...props} />, { wrapper });
15
15
  const mosaic = getByClassName(document.body, CLASSNAME);
16
16
  const thumbnails = queryAllByClassName(mosaic, Thumbnail.className as string);
17
17
  const overlay = queryByClassName(mosaic, `${CLASSNAME}__overlay`);
@@ -69,5 +69,11 @@ describe(`<${Mosaic.displayName}>`, () => {
69
69
  forwardClassName: 'mosaic',
70
70
  forwardAttributes: 'mosaic',
71
71
  forwardRef: 'mosaic',
72
+ applyTheme: {
73
+ affects: [{ element: 'mosaic' }, { element: 'thumbnails' }],
74
+ viaProp: true,
75
+ viaContext: true,
76
+ defaultTheme: 'light',
77
+ },
72
78
  });
73
79
  });
@@ -1,10 +1,13 @@
1
- import React, { forwardRef, MouseEventHandler, useMemo } from 'react';
1
+ import React, { MouseEventHandler, useMemo } from 'react';
2
2
 
3
- import { Alignment, AspectRatio, Theme, Thumbnail, ThumbnailProps } from '@lumx/react';
4
- import { Comp, GenericProps, HasTheme } from '@lumx/react/utils/type';
5
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
6
3
  import classNames from 'classnames';
7
4
  import take from 'lodash/take';
5
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
6
+
7
+ import { Alignment, AspectRatio, Theme, Thumbnail, ThumbnailProps } from '@lumx/react';
8
+ import { GenericProps, HasTheme } from '@lumx/react/utils/type';
9
+ import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
10
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
8
11
 
9
12
  /**
10
13
  * Defines the props of the component.
@@ -29,9 +32,7 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
29
32
  /**
30
33
  * Component default props.
31
34
  */
32
- const DEFAULT_PROPS: Partial<MosaicProps> = {
33
- theme: Theme.light,
34
- };
35
+ const DEFAULT_PROPS: Partial<MosaicProps> = {};
35
36
 
36
37
  /**
37
38
  * Mosaic component.
@@ -40,8 +41,9 @@ const DEFAULT_PROPS: Partial<MosaicProps> = {
40
41
  * @param ref Component ref.
41
42
  * @return React element.
42
43
  */
43
- export const Mosaic: Comp<MosaicProps, HTMLDivElement> = forwardRef((props, ref) => {
44
- const { className, theme, thumbnails, onImageClick, ...forwardedProps } = props;
44
+ export const Mosaic = forwardRef<MosaicProps, HTMLDivElement>((props, ref) => {
45
+ const defaultTheme = useTheme() || Theme.light;
46
+ const { className, theme = defaultTheme, thumbnails, onImageClick, ...forwardedProps } = props;
45
47
  const handleImageClick = useMemo(() => {
46
48
  if (!onImageClick) return undefined;
47
49
 
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
 
3
- import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
3
+ import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
4
4
  import { render } from '@testing-library/react';
5
- import { getByClassName } from '@lumx/react/testing/utils/queries';
5
+ import { getAllByClassName, getByClassName } from '@lumx/react/testing/utils/queries';
6
6
  import { Navigation, NavigationProps } from '.';
7
7
  import { Orientation } from '..';
8
8
 
@@ -14,7 +14,7 @@ type SetupProps = Partial<NavigationProps>;
14
14
  * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
15
15
  */
16
16
 
17
- const setup = (propsOverride: SetupProps = {}) => {
17
+ const setup = (propsOverride: SetupProps = {}, { wrapper }: SetupRenderOptions = {}) => {
18
18
  const props = { 'aria-label': 'navigation', ...propsOverride } as any;
19
19
  const { container } = render(
20
20
  <Navigation {...props}>
@@ -22,13 +22,12 @@ const setup = (propsOverride: SetupProps = {}) => {
22
22
  <Navigation.Item label="A link" as="button" />
23
23
  <Navigation.Item label="A link" href="" />
24
24
  </Navigation>,
25
+ { wrapper },
25
26
  );
26
27
 
27
- return {
28
- container,
29
- element: getByClassName(container, CLASSNAME),
30
- props,
31
- };
28
+ const element = getByClassName(container, CLASSNAME);
29
+ const items = getAllByClassName(element, Navigation.Item.className as string);
30
+ return { container, element, items, props };
32
31
  };
33
32
 
34
33
  describe(`<${Navigation.displayName}>`, () => {
@@ -54,5 +53,15 @@ describe(`<${Navigation.displayName}>`, () => {
54
53
  });
55
54
 
56
55
  // Common tests suite.
57
- commonTestsSuiteRTL(setup, { baseClassName: CLASSNAME, forwardClassName: 'element', forwardAttributes: 'element' });
56
+ commonTestsSuiteRTL(setup, {
57
+ baseClassName: CLASSNAME,
58
+ forwardClassName: 'element',
59
+ forwardAttributes: 'element',
60
+ applyTheme: {
61
+ affects: [{ element: 'element' }, { element: 'items' }],
62
+ viaProp: true,
63
+ viaContext: true,
64
+ defaultTheme: 'light',
65
+ },
66
+ });
58
67
  });
@@ -3,7 +3,7 @@ import classNames from 'classnames';
3
3
  import { HasAriaLabelOrLabelledBy, HasClassName, HasTheme } from '@lumx/react/utils/type';
4
4
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
5
5
  import { Orientation, Theme } from '@lumx/react';
6
- import { ThemeContext } from '@lumx/react/utils/ThemeContext';
6
+ import { ThemeProvider, useTheme } from '@lumx/react/utils/theme/ThemeContext';
7
7
  import { NavigationSection } from './NavigationSection';
8
8
  import { NavigationItem } from './NavigationItem';
9
9
  import { NavigationContext } from './context';
@@ -26,12 +26,20 @@ const COMPONENT_NAME = 'Navigation';
26
26
  */
27
27
  const CLASSNAME = getRootClassName(COMPONENT_NAME);
28
28
 
29
+ /**
30
+ * Component default props
31
+ */
32
+ const DEFAULT_PROPS = {
33
+ orientation: Orientation.vertical,
34
+ };
35
+
29
36
  export const Navigation = Object.assign(
30
37
  // eslint-disable-next-line react/display-name
31
38
  forwardRef<HTMLElement, NavigationProps>((props, ref) => {
32
- const { children, className, theme, orientation, ...forwardedProps } = props;
39
+ const defaultTheme = useTheme() || Theme.light;
40
+ const { children, className, theme = defaultTheme, orientation, ...forwardedProps } = props;
33
41
  return (
34
- <ThemeContext.Provider value={theme}>
42
+ <ThemeProvider value={theme}>
35
43
  <nav
36
44
  className={classNames(
37
45
  className,
@@ -48,13 +56,13 @@ export const Navigation = Object.assign(
48
56
  <ul className={`${CLASSNAME}__list`}>{children}</ul>
49
57
  </NavigationContext.Provider>
50
58
  </nav>
51
- </ThemeContext.Provider>
59
+ </ThemeProvider>
52
60
  );
53
61
  }),
54
62
  {
55
63
  displayName: COMPONENT_NAME,
56
64
  className: CLASSNAME,
57
- defaultProps: { theme: Theme.light, orientation: Orientation.vertical },
65
+ defaultProps: DEFAULT_PROPS,
58
66
  // Sub components
59
67
  Section: NavigationSection,
60
68
  Item: NavigationItem,
@@ -1,10 +1,10 @@
1
- import React, { ElementType, ReactNode, useContext } from 'react';
1
+ import React, { ElementType, ReactNode } from 'react';
2
2
  import { Icon, Placement, Size, Tooltip, Text } from '@lumx/react';
3
3
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
4
4
  import { ComponentRef, HasClassName, HasPolymorphicAs, HasTheme } from '@lumx/react/utils/type';
5
5
  import classNames from 'classnames';
6
- import { forwardRefPolymorphic } from '@lumx/react/utils/forwardRefPolymorphic';
7
- import { ThemeContext } from '@lumx/react/utils/ThemeContext';
6
+ import { forwardRefPolymorphic } from '@lumx/react/utils/react/forwardRefPolymorphic';
7
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
8
8
  import { useOverflowTooltipLabel } from '@lumx/react/hooks/useOverflowTooltipLabel';
9
9
 
10
10
  type BaseNavigationItemProps = {
@@ -41,7 +41,7 @@ export const CLASSNAME = getRootClassName(COMPONENT_NAME);
41
41
  export const NavigationItem = Object.assign(
42
42
  forwardRefPolymorphic(<E extends ElementType = 'a'>(props: NavigationItemProps<E>, ref: ComponentRef<E>) => {
43
43
  const { className, icon, label, isCurrentPage, as: Element = 'a', ...forwardedProps } = props;
44
- const theme = useContext(ThemeContext);
44
+ const theme = useTheme();
45
45
  const { tooltipLabel, labelRef } = useOverflowTooltipLabel();
46
46
 
47
47
  const buttonProps = Element === 'button' ? { type: 'button' } : {};
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
3
+ import { commonTestsSuiteRTL, RenderWrapper } from '@lumx/react/testing/utils';
4
4
  import { render, screen } from '@testing-library/react';
5
5
  import { getByClassName, queryByClassName } from '@lumx/react/testing/utils/queries';
6
6
  import userEvent from '@testing-library/user-event';
@@ -17,7 +17,10 @@ type SetupProps = Partial<NavigationSectionProps>;
17
17
  * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
18
18
  */
19
19
 
20
- const setup = (propsOverride: SetupProps = {}, orientation: Orientation = Orientation.vertical) => {
20
+ const setup = (
21
+ propsOverride: SetupProps = {},
22
+ { orientation = Orientation.vertical, wrapper }: { orientation?: Orientation; wrapper?: RenderWrapper } = {},
23
+ ) => {
21
24
  const props = { label: 'Section 1', ...propsOverride };
22
25
  const { container } = render(
23
26
  <NavigationContext.Provider value={{ orientation }}>
@@ -27,6 +30,7 @@ const setup = (propsOverride: SetupProps = {}, orientation: Orientation = Orient
27
30
  <NavigationItem label="A community" href="" />
28
31
  </NavigationSection>
29
32
  </NavigationContext.Provider>,
33
+ { wrapper },
30
34
  );
31
35
 
32
36
  const query = {
@@ -62,7 +66,7 @@ describe(`<${NavigationSection.displayName}>`, () => {
62
66
  });
63
67
 
64
68
  it('should be closed by default in horizontal mode', () => {
65
- const { element, query } = setup({}, Orientation.horizontal);
69
+ const { element, query } = setup({}, { orientation: Orientation.horizontal });
66
70
  expect(element).toBeInTheDocument();
67
71
  expect(element).toHaveClass(CLASSNAME);
68
72
  // Section is visible
@@ -91,7 +95,7 @@ describe(`<${NavigationSection.displayName}>`, () => {
91
95
  });
92
96
 
93
97
  it('should be in a popover and toggle on click in horizontal mode', async () => {
94
- const { query } = setup({}, Orientation.horizontal);
98
+ const { query } = setup({}, { orientation: Orientation.horizontal });
95
99
  // Content is not visible
96
100
  expect(query.popover()).not.toBeInTheDocument();
97
101
  // click to open
@@ -109,7 +113,7 @@ describe(`<${NavigationSection.displayName}>`, () => {
109
113
  });
110
114
 
111
115
  it('should also toggle on click away in horizontal mode', async () => {
112
- const { query } = setup({}, Orientation.horizontal);
116
+ const { query } = setup({}, { orientation: Orientation.horizontal });
113
117
  // Content is not visible
114
118
  expect(query.popover()).not.toBeInTheDocument();
115
119
  // click to open
@@ -121,5 +125,14 @@ describe(`<${NavigationSection.displayName}>`, () => {
121
125
  });
122
126
 
123
127
  // Common tests suite.
124
- commonTestsSuiteRTL(setup, { baseClassName: CLASSNAME, forwardClassName: 'element', forwardAttributes: 'button' });
128
+ commonTestsSuiteRTL(setup, {
129
+ baseClassName: CLASSNAME,
130
+ forwardClassName: 'element',
131
+ forwardAttributes: 'button',
132
+ applyTheme: {
133
+ affects: [{ element: 'element' }],
134
+ viaProp: false,
135
+ viaContext: true,
136
+ },
137
+ });
125
138
  });