@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,12 +1,13 @@
1
- import React, { forwardRef, ReactNode, SyntheticEvent, InputHTMLAttributes } from 'react';
1
+ import React, { ReactNode, SyntheticEvent, InputHTMLAttributes } from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
 
5
5
  import { InputHelper, InputLabel, Theme } from '@lumx/react';
6
-
7
- import { Comp, GenericProps, HasTheme } from '@lumx/react/utils/type';
6
+ import { GenericProps, HasTheme } from '@lumx/react/utils/type';
8
7
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
9
8
  import { useId } from '@lumx/react/hooks/useId';
9
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
10
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
10
11
 
11
12
  /**
12
13
  * Defines the props of the component.
@@ -47,9 +48,7 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
47
48
  /**
48
49
  * Component default props.
49
50
  */
50
- const DEFAULT_PROPS: Partial<RadioButtonProps> = {
51
- theme: Theme.light,
52
- };
51
+ const DEFAULT_PROPS: Partial<RadioButtonProps> = {};
53
52
 
54
53
  /**
55
54
  * RadioButton component.
@@ -58,7 +57,8 @@ const DEFAULT_PROPS: Partial<RadioButtonProps> = {
58
57
  * @param ref Component ref.
59
58
  * @return React element.
60
59
  */
61
- export const RadioButton: Comp<RadioButtonProps, HTMLDivElement> = forwardRef((props, ref) => {
60
+ export const RadioButton = forwardRef<RadioButtonProps, HTMLDivElement>((props, ref) => {
61
+ const defaultTheme = useTheme() || Theme.light;
62
62
  const {
63
63
  checked,
64
64
  className,
@@ -71,7 +71,7 @@ export const RadioButton: Comp<RadioButtonProps, HTMLDivElement> = forwardRef((p
71
71
  label,
72
72
  name,
73
73
  onChange,
74
- theme,
74
+ theme = defaultTheme,
75
75
  value,
76
76
  inputProps,
77
77
  ...forwardedProps
@@ -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 RadioGroup: Comp<RadioGroupProps, HTMLDivElement> = forwardRef((props, ref) => {
34
+ export const RadioGroup = forwardRef<RadioGroupProps, HTMLDivElement>((props, ref) => {
34
35
  const { children, className, ...forwardedProps } = props;
35
36
 
36
37
  return (
@@ -5,7 +5,7 @@ import { Chip } from '@lumx/react/components/chip/Chip';
5
5
  import { Dropdown } from '@lumx/react/components/dropdown/Dropdown';
6
6
  import { getByClassName, queryAllByClassName, queryByClassName } from '@lumx/react/testing/utils/queries';
7
7
  import { render, within } from '@testing-library/react';
8
- import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
8
+ import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
9
9
  import userEvent from '@testing-library/user-event';
10
10
  import { isFocusVisible } from '@lumx/react/utils/isFocusVisible';
11
11
 
@@ -19,13 +19,13 @@ jest.mock('@lumx/react/hooks/useId', () => ({ useId: () => ':r1:' }));
19
19
  /**
20
20
  * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
21
21
  */
22
- const setup = (propsOverride: Partial<SelectProps> = {}) => {
22
+ const setup = (propsOverride: Partial<SelectProps> = {}, { wrapper }: SetupRenderOptions = {}) => {
23
23
  const props: SelectProps = {
24
24
  children: <span>Select Component</span>,
25
25
  value: '',
26
26
  ...propsOverride,
27
27
  };
28
- render(<Select {...props} />);
28
+ render(<Select {...props} />, { wrapper });
29
29
  const select = getByClassName(document.body, CLASSNAME);
30
30
  const getDropdown = () => queryByClassName(document.body, Dropdown.className as string);
31
31
  const helpers = queryAllByClassName(select, `${CLASSNAME}__helper`);
@@ -190,5 +190,11 @@ describe(`<${Select.displayName}>`, () => {
190
190
  forwardClassName: 'select',
191
191
  forwardAttributes: 'inputWrapper',
192
192
  forwardRef: 'select',
193
+ applyTheme: {
194
+ affects: [{ element: 'select' }],
195
+ viaProp: true,
196
+ viaContext: true,
197
+ defaultTheme: 'light',
198
+ },
193
199
  });
194
200
  });
@@ -1,20 +1,19 @@
1
- import React, { forwardRef, RefObject } from 'react';
1
+ import React, { RefObject } from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
  import lodashIsEmpty from 'lodash/isEmpty';
5
5
 
6
6
  import { mdiAlertCircle, mdiCheckCircle, mdiCloseCircle, mdiMenuDown } from '@lumx/icons';
7
-
8
7
  import { Emphasis, Size, Theme } from '@lumx/react/components';
9
8
  import { IconButton } from '@lumx/react/components/button/IconButton';
10
9
  import { Chip } from '@lumx/react/components/chip/Chip';
11
10
  import { Icon } from '@lumx/react/components/icon/Icon';
12
11
  import { InputLabel } from '@lumx/react/components/input-label/InputLabel';
13
-
14
- import { Comp } from '@lumx/react/utils/type';
15
12
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
16
13
  import { mergeRefs } from '@lumx/react/utils/mergeRefs';
14
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
17
15
 
16
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
18
17
  import { WithSelectContext } from './WithSelectContext';
19
18
  import { CoreSelectProps, SelectVariant } from './constants';
20
19
 
@@ -42,29 +41,32 @@ const stopPropagation = (evt: Event) => evt.stopPropagation();
42
41
  /**
43
42
  * Select component.
44
43
  */
45
- const SelectField: React.FC<SelectProps> = ({
46
- anchorRef,
47
- clearButtonProps,
48
- handleKeyboardNav,
49
- hasError,
50
- hasInputClear,
51
- icon,
52
- id,
53
- isDisabled,
54
- isEmpty,
55
- isRequired,
56
- isValid,
57
- label,
58
- onClear,
59
- onInputClick,
60
- placeholder,
61
- selectedValueRender,
62
- theme,
63
- value,
64
- variant,
65
- selectElementRef,
66
- ...forwardedProps
67
- }) => {
44
+ const SelectField: React.FC<SelectProps> = (props) => {
45
+ const defaultTheme = useTheme();
46
+ const {
47
+ anchorRef,
48
+ clearButtonProps,
49
+ handleKeyboardNav,
50
+ hasError,
51
+ hasInputClear,
52
+ icon,
53
+ id,
54
+ isDisabled,
55
+ isEmpty,
56
+ isRequired,
57
+ isValid,
58
+ label,
59
+ onClear,
60
+ onInputClick,
61
+ placeholder,
62
+ selectedValueRender,
63
+ theme = defaultTheme,
64
+ value,
65
+ variant,
66
+ selectElementRef,
67
+ ...forwardedProps
68
+ } = props;
69
+
68
70
  return (
69
71
  <>
70
72
  {variant === SelectVariant.input && (
@@ -167,7 +169,7 @@ const SelectField: React.FC<SelectProps> = ({
167
169
  * @param ref Component ref.
168
170
  * @return React element.
169
171
  */
170
- export const Select: Comp<SelectProps, HTMLDivElement> = forwardRef((props, ref) => {
172
+ export const Select = forwardRef<SelectProps, HTMLDivElement>((props, ref) => {
171
173
  const isEmpty = lodashIsEmpty(props.value);
172
174
  const hasInputClear = props.onClear && props.clearButtonProps && !isEmpty;
173
175
 
@@ -3,7 +3,7 @@ import React from 'react';
3
3
  import { Theme } from '@lumx/react/components';
4
4
  import { Chip } from '@lumx/react/components/chip/Chip';
5
5
  import { Dropdown } from '@lumx/react/components/dropdown/Dropdown';
6
- import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
6
+ import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
7
7
  import { render, within } from '@testing-library/react';
8
8
  import {
9
9
  getAllByClassName,
@@ -23,13 +23,13 @@ jest.mock('@lumx/react/hooks/useId', () => ({ useId: () => ':r1:' }));
23
23
  /**
24
24
  * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
25
25
  */
26
- const setup = (props: Partial<SelectMultipleProps> = {}) => {
26
+ const setup = (props: Partial<SelectMultipleProps> = {}, { wrapper }: SetupRenderOptions = {}) => {
27
27
  const setupProps: SelectMultipleProps = {
28
28
  children: <span>Select Component</span>,
29
29
  value: [],
30
30
  ...props,
31
31
  };
32
- render(<SelectMultiple {...setupProps} />);
32
+ render(<SelectMultiple {...setupProps} />, { wrapper });
33
33
  const select = getByClassName(document.body, CLASSNAME);
34
34
  const getDropdown = () => queryByClassName(document.body, Dropdown.className as string);
35
35
  const helpers = queryAllByClassName(select, `${CLASSNAME}__helper`);
@@ -205,5 +205,11 @@ describe('<SelectMultiple>', () => {
205
205
  forwardClassName: 'select',
206
206
  forwardAttributes: 'inputWrapper',
207
207
  forwardRef: 'select',
208
+ applyTheme: {
209
+ affects: [{ element: 'select' }],
210
+ viaProp: true,
211
+ viaContext: true,
212
+ defaultTheme: 'light',
213
+ },
208
214
  });
209
215
  });
@@ -1,17 +1,16 @@
1
- import React, { forwardRef, ReactNode, RefObject, SyntheticEvent } from 'react';
1
+ import React, { ReactNode, RefObject, SyntheticEvent } from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
 
5
5
  import { mdiAlertCircle, mdiCheckCircle, mdiClose, mdiCloseCircle, mdiMenuDown } from '@lumx/icons';
6
-
7
6
  import { Size, Theme } from '@lumx/react/components';
8
7
  import { Chip } from '@lumx/react/components/chip/Chip';
9
8
  import { Icon } from '@lumx/react/components/icon/Icon';
10
9
  import { InputLabel } from '@lumx/react/components/input-label/InputLabel';
11
-
12
- import { Comp } from '@lumx/react/utils/type';
13
10
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
14
11
  import { mergeRefs } from '@lumx/react/utils/mergeRefs';
12
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
13
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
15
14
 
16
15
  import { WithSelectContext } from './WithSelectContext';
17
16
  import { CoreSelectProps, SelectVariant } from './constants';
@@ -57,118 +56,123 @@ const DEFAULT_PROPS: Partial<SelectMultipleProps> = {
57
56
  selectedValueRender: (choice) => choice,
58
57
  };
59
58
 
60
- export const SelectMultipleField: React.FC<SelectMultipleProps> = ({
61
- anchorRef,
62
- handleKeyboardNav,
63
- hasError,
64
- icon,
65
- id,
66
- isDisabled,
67
- isEmpty,
68
- isRequired,
69
- isValid,
70
- label,
71
- onClear,
72
- onInputClick,
73
- placeholder,
74
- selectedChipRender,
75
- selectedValueRender,
76
- theme,
77
- value,
78
- variant,
79
- selectElementRef,
80
- ...forwardedProps
81
- }) => (
82
- <>
83
- {variant === SelectVariant.input && (
84
- <>
85
- {label && (
86
- <div className={`${CLASSNAME}__header`}>
87
- <InputLabel
88
- htmlFor={id}
89
- className={`${CLASSNAME}__label`}
90
- isRequired={isRequired}
91
- theme={theme}
92
- >
93
- {label}
94
- </InputLabel>
95
- </div>
96
- )}
97
-
98
- {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
99
- <div
100
- ref={mergeRefs(anchorRef as RefObject<HTMLDivElement>, selectElementRef)}
101
- id={id}
102
- className={`${CLASSNAME}__wrapper`}
103
- onClick={onInputClick}
104
- onKeyDown={handleKeyboardNav}
105
- tabIndex={isDisabled ? undefined : 0}
106
- aria-disabled={isDisabled || undefined}
107
- {...forwardedProps}
108
- >
109
- {icon && (
110
- <Icon
111
- className={`${CLASSNAME}__input-icon`}
112
- color={theme === Theme.dark ? 'light' : undefined}
113
- icon={icon}
114
- size={Size.xs}
115
- />
116
- )}
117
-
118
- <div className={`${CLASSNAME}__chips`}>
119
- {!isEmpty &&
120
- value.map((val, index) => selectedChipRender?.(val, index, onClear, isDisabled, theme))}
121
- </div>
122
-
123
- {isEmpty && placeholder && (
124
- <div
125
- className={classNames([
126
- `${CLASSNAME}__input-native`,
127
- `${CLASSNAME}__input-native--placeholder`,
128
- ])}
129
- >
130
- <span>{placeholder}</span>
59
+ export const SelectMultipleField: React.FC<SelectMultipleProps> = (props) => {
60
+ const defaultTheme = useTheme();
61
+ const {
62
+ anchorRef,
63
+ handleKeyboardNav,
64
+ hasError,
65
+ icon,
66
+ id,
67
+ isDisabled,
68
+ isEmpty,
69
+ isRequired,
70
+ isValid,
71
+ label,
72
+ onClear,
73
+ onInputClick,
74
+ placeholder,
75
+ selectedChipRender,
76
+ selectedValueRender,
77
+ theme = defaultTheme,
78
+ value,
79
+ variant,
80
+ selectElementRef,
81
+ ...forwardedProps
82
+ } = props;
83
+
84
+ return (
85
+ <>
86
+ {variant === SelectVariant.input && (
87
+ <>
88
+ {label && (
89
+ <div className={`${CLASSNAME}__header`}>
90
+ <InputLabel
91
+ htmlFor={id}
92
+ className={`${CLASSNAME}__label`}
93
+ isRequired={isRequired}
94
+ theme={theme}
95
+ >
96
+ {label}
97
+ </InputLabel>
131
98
  </div>
132
99
  )}
133
100
 
134
- {(isValid || hasError) && (
135
- <div className={`${CLASSNAME}__input-validity`}>
136
- <Icon icon={isValid ? mdiCheckCircle : mdiAlertCircle} size={Size.xxs} />
101
+ {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
102
+ <div
103
+ ref={mergeRefs(anchorRef as RefObject<HTMLDivElement>, selectElementRef)}
104
+ id={id}
105
+ className={`${CLASSNAME}__wrapper`}
106
+ onClick={onInputClick}
107
+ onKeyDown={handleKeyboardNav}
108
+ tabIndex={isDisabled ? undefined : 0}
109
+ aria-disabled={isDisabled || undefined}
110
+ {...forwardedProps}
111
+ >
112
+ {icon && (
113
+ <Icon
114
+ className={`${CLASSNAME}__input-icon`}
115
+ color={theme === Theme.dark ? 'light' : undefined}
116
+ icon={icon}
117
+ size={Size.xs}
118
+ />
119
+ )}
120
+
121
+ <div className={`${CLASSNAME}__chips`}>
122
+ {!isEmpty &&
123
+ value.map((val, index) => selectedChipRender?.(val, index, onClear, isDisabled, theme))}
137
124
  </div>
138
- )}
139
125
 
140
- <div className={`${CLASSNAME}__input-indicator`}>
141
- <Icon icon={mdiMenuDown} size={Size.s} />
126
+ {isEmpty && placeholder && (
127
+ <div
128
+ className={classNames([
129
+ `${CLASSNAME}__input-native`,
130
+ `${CLASSNAME}__input-native--placeholder`,
131
+ ])}
132
+ >
133
+ <span>{placeholder}</span>
134
+ </div>
135
+ )}
136
+
137
+ {(isValid || hasError) && (
138
+ <div className={`${CLASSNAME}__input-validity`}>
139
+ <Icon icon={isValid ? mdiCheckCircle : mdiAlertCircle} size={Size.xxs} />
140
+ </div>
141
+ )}
142
+
143
+ <div className={`${CLASSNAME}__input-indicator`}>
144
+ <Icon icon={mdiMenuDown} size={Size.s} />
145
+ </div>
142
146
  </div>
143
- </div>
144
- </>
145
- )}
147
+ </>
148
+ )}
146
149
 
147
- {variant === SelectVariant.chip && (
148
- <Chip
149
- id={id}
150
- isSelected={!isEmpty}
151
- isDisabled={isDisabled}
152
- after={<Icon icon={isEmpty ? mdiMenuDown : mdiCloseCircle} />}
153
- onAfterClick={isEmpty ? onInputClick : onClear}
154
- onClick={onInputClick}
155
- ref={mergeRefs(anchorRef as RefObject<HTMLAnchorElement>, selectElementRef)}
156
- theme={theme}
157
- {...forwardedProps}
158
- >
159
- {isEmpty && <span>{label}</span>}
150
+ {variant === SelectVariant.chip && (
151
+ <Chip
152
+ id={id}
153
+ isSelected={!isEmpty}
154
+ isDisabled={isDisabled}
155
+ after={<Icon icon={isEmpty ? mdiMenuDown : mdiCloseCircle} />}
156
+ onAfterClick={isEmpty ? onInputClick : onClear}
157
+ onClick={onInputClick}
158
+ ref={mergeRefs(anchorRef as RefObject<HTMLAnchorElement>, selectElementRef)}
159
+ theme={theme}
160
+ {...forwardedProps}
161
+ >
162
+ {isEmpty && <span>{label}</span>}
160
163
 
161
- {!isEmpty && (
162
- <span>
163
- <span>{selectedValueRender?.(value[0])}</span>
164
+ {!isEmpty && (
165
+ <span>
166
+ <span>{selectedValueRender?.(value[0])}</span>
164
167
 
165
- {value.length > 1 && <span>&nbsp;+{value.length - 1}</span>}
166
- </span>
167
- )}
168
- </Chip>
169
- )}
170
- </>
171
- );
168
+ {value.length > 1 && <span>&nbsp;+{value.length - 1}</span>}
169
+ </span>
170
+ )}
171
+ </Chip>
172
+ )}
173
+ </>
174
+ );
175
+ };
172
176
 
173
177
  /**
174
178
  * SelectMultiple component.
@@ -177,7 +181,7 @@ export const SelectMultipleField: React.FC<SelectMultipleProps> = ({
177
181
  * @param ref Component ref.
178
182
  * @return React element.
179
183
  */
180
- export const SelectMultiple: Comp<SelectMultipleProps, HTMLDivElement> = forwardRef((props, ref) => {
184
+ export const SelectMultiple = forwardRef<SelectMultipleProps, HTMLDivElement>((props, ref) => {
181
185
  return WithSelectContext(
182
186
  SelectMultipleField,
183
187
  {
@@ -11,6 +11,7 @@ import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/classNam
11
11
  import { mergeRefs } from '@lumx/react/utils/mergeRefs';
12
12
 
13
13
  import { useId } from '@lumx/react/hooks/useId';
14
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
14
15
  import { CoreSelectProps, SelectVariant } from './constants';
15
16
 
16
17
  /** The display name of the component. */
@@ -21,13 +22,16 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
21
22
 
22
23
  /** The default value of props. */
23
24
  export const DEFAULT_PROPS: Partial<CoreSelectProps> = {
24
- theme: Theme.light,
25
25
  variant: SelectVariant.input,
26
26
  };
27
27
 
28
28
  export const WithSelectContext = (
29
29
  SelectElement: React.FC<any>,
30
- {
30
+ props: CoreSelectProps,
31
+ ref: Ref<HTMLDivElement>,
32
+ ): React.ReactElement => {
33
+ const defaultTheme = useTheme() || Theme.light;
34
+ const {
31
35
  children,
32
36
  className,
33
37
  focusElement,
@@ -49,13 +53,11 @@ export const WithSelectContext = (
49
53
  onInfiniteScroll,
50
54
  onInputClick,
51
55
  placeholder,
52
- theme = DEFAULT_PROPS.theme,
56
+ theme = defaultTheme,
53
57
  value,
54
58
  variant = DEFAULT_PROPS.variant,
55
59
  ...forwardedProps
56
- }: CoreSelectProps,
57
- ref: Ref<HTMLDivElement>,
58
- ): React.ReactElement => {
60
+ } = props;
59
61
  const generatedSelectId = useId();
60
62
  const selectId = id || generatedSelectId;
61
63
  const anchorRef = useRef<HTMLElement>(null);
@@ -1,11 +1,12 @@
1
- import React, { Children, forwardRef, ReactNode } from 'react';
1
+ import React, { Children, ReactNode } from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
 
5
5
  import { SideNavigationItem, Theme } from '@lumx/react';
6
-
7
- import { Comp, GenericProps, HasTheme, isComponent } from '@lumx/react/utils/type';
6
+ import { GenericProps, HasTheme, isComponent } from '@lumx/react/utils/type';
8
7
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
8
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
9
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
9
10
 
10
11
  /**
11
12
  * Defines the props of the component.
@@ -32,8 +33,9 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
32
33
  * @param ref Component ref.
33
34
  * @return React element.
34
35
  */
35
- export const SideNavigation: Comp<SideNavigationProps, HTMLUListElement> = forwardRef((props, ref) => {
36
- const { children, className, theme, ...forwardedProps } = props;
36
+ export const SideNavigation = forwardRef<SideNavigationProps, HTMLUListElement>((props, ref) => {
37
+ const defaultTheme = useTheme();
38
+ const { children, className, theme = defaultTheme, ...forwardedProps } = props;
37
39
  const content = Children.toArray(children).filter(isComponent(SideNavigationItem));
38
40
 
39
41
  return (
@@ -1,17 +1,16 @@
1
- import React, { Children, forwardRef, ReactNode } from 'react';
1
+ import React, { Children, ReactNode } from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
  import isEmpty from 'lodash/isEmpty';
5
5
 
6
6
  import { mdiChevronDown, mdiChevronUp } from '@lumx/icons';
7
-
8
7
  import { Emphasis, Icon, Size, IconButton, IconButtonProps } from '@lumx/react';
9
-
10
- import { Comp, GenericProps, HasCloseMode, isComponent } from '@lumx/react/utils/type';
8
+ import { GenericProps, HasCloseMode, isComponent } from '@lumx/react/utils/type';
11
9
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
12
10
  import { renderLink } from '@lumx/react/utils/renderLink';
13
11
  import { renderButtonOrLink } from '@lumx/react/utils/renderButtonOrLink';
14
12
  import { useId } from '@lumx/react/hooks/useId';
13
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
15
14
 
16
15
  /**
17
16
  * Defines the props of the component.
@@ -67,7 +66,7 @@ const DEFAULT_PROPS: Partial<SideNavigationItemProps> = {
67
66
  * @param ref Component ref.
68
67
  * @return React element.
69
68
  */
70
- export const SideNavigationItem: Comp<SideNavigationItemProps, HTMLLIElement> = forwardRef((props, ref) => {
69
+ export const SideNavigationItem = forwardRef<SideNavigationItemProps, HTMLLIElement>((props, ref) => {
71
70
  const {
72
71
  children,
73
72
  className,
@@ -1,14 +1,14 @@
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
5
  import { queryByClassName } from '@lumx/react/testing/utils/queries';
6
6
  import { SkeletonCircle, SkeletonCircleProps } from './SkeletonCircle';
7
7
 
8
8
  const CLASSNAME = SkeletonCircle.className as string;
9
9
 
10
- const setup = (props: Partial<SkeletonCircleProps> = {}) => {
11
- render(<SkeletonCircle {...(props as any)} />);
10
+ const setup = (props: Partial<SkeletonCircleProps> = {}, { wrapper }: SetupRenderOptions = {}) => {
11
+ render(<SkeletonCircle {...(props as any)} />, { wrapper });
12
12
  const skeletonCircle = queryByClassName(document.body, CLASSNAME);
13
13
  return { props, skeletonCircle };
14
14
  };
@@ -19,5 +19,11 @@ describe(`<${SkeletonCircle.displayName}>`, () => {
19
19
  baseClassName: CLASSNAME,
20
20
  forwardClassName: 'skeletonCircle',
21
21
  forwardAttributes: 'skeletonCircle',
22
+ applyTheme: {
23
+ affects: [{ element: 'skeletonCircle' }],
24
+ viaProp: true,
25
+ viaContext: true,
26
+ defaultTheme: 'light',
27
+ },
22
28
  });
23
29
  });
@@ -1,9 +1,12 @@
1
+ import React from 'react';
2
+
1
3
  import classNames from 'classnames';
2
- import React, { forwardRef } from 'react';
3
4
 
4
5
  import { GlobalSize, Theme, ColorPalette } from '@lumx/react';
5
- import { Comp, GenericProps, HasTheme } from '@lumx/react/utils/type';
6
+ import { GenericProps, HasTheme } from '@lumx/react/utils/type';
6
7
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
8
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
9
+ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
7
10
 
8
11
  /**
9
12
  * Defines the props of the component.
@@ -15,9 +18,7 @@ export interface SkeletonCircleProps extends GenericProps, HasTheme {
15
18
  color?: ColorPalette;
16
19
  }
17
20
 
18
- const DEFAULT_PROPS: Partial<SkeletonCircleProps> = {
19
- theme: Theme.light,
20
- };
21
+ const DEFAULT_PROPS: Partial<SkeletonCircleProps> = {};
21
22
 
22
23
  /**
23
24
  * Component display name.
@@ -36,8 +37,9 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
36
37
  * @param ref Component ref.
37
38
  * @return React element.
38
39
  */
39
- export const SkeletonCircle: Comp<SkeletonCircleProps, HTMLDivElement> = forwardRef((props, ref) => {
40
- const { className, size, color, theme, ...forwardedProps } = props;
40
+ export const SkeletonCircle = forwardRef<SkeletonCircleProps, HTMLDivElement>((props, ref) => {
41
+ const defaultTheme = useTheme() || Theme.light;
42
+ const { className, size, color, theme = defaultTheme, ...forwardedProps } = props;
41
43
 
42
44
  return (
43
45
  <div