@lumx/react 3.10.0 → 3.10.1-alpha.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 (101) hide show
  1. package/_internal/index.d.ts +1 -1
  2. package/index.d.ts +13 -5
  3. package/index.js +217 -202
  4. package/index.js.map +1 -1
  5. package/package.json +3 -3
  6. package/src/components/autocomplete/Autocomplete.test.tsx +9 -2
  7. package/src/components/autocomplete/Autocomplete.tsx +3 -1
  8. package/src/components/autocomplete/AutocompleteMultiple.test.tsx +9 -2
  9. package/src/components/autocomplete/AutocompleteMultiple.tsx +3 -1
  10. package/src/components/avatar/Avatar.test.tsx +14 -4
  11. package/src/components/avatar/Avatar.tsx +3 -2
  12. package/src/components/button/Button.test.tsx +9 -3
  13. package/src/components/button/Button.tsx +3 -2
  14. package/src/components/button/IconButton.test.tsx +9 -3
  15. package/src/components/button/IconButton.tsx +13 -2
  16. package/src/components/checkbox/Checkbox.test.tsx +9 -3
  17. package/src/components/checkbox/Checkbox.tsx +4 -4
  18. package/src/components/chip/Chip.test.tsx +14 -4
  19. package/src/components/chip/Chip.tsx +3 -2
  20. package/src/components/comment-block/CommentBlock.test.tsx +9 -3
  21. package/src/components/comment-block/CommentBlock.tsx +3 -2
  22. package/src/components/date-picker/DatePickerField.test.tsx +9 -3
  23. package/src/components/dialog/Dialog.test.tsx +17 -4
  24. package/src/components/dialog/Dialog.tsx +61 -58
  25. package/src/components/divider/Divider.test.tsx +9 -3
  26. package/src/components/divider/Divider.tsx +4 -4
  27. package/src/components/drag-handle/DragHandle.test.tsx +38 -0
  28. package/src/components/drag-handle/DragHandle.tsx +3 -1
  29. package/src/components/expansion-panel/ExpansionPanel.test.tsx +12 -3
  30. package/src/components/expansion-panel/ExpansionPanel.tsx +4 -4
  31. package/src/components/flag/Flag.test.tsx +14 -4
  32. package/src/components/flag/Flag.tsx +4 -4
  33. package/src/components/icon/Icon.test.tsx +13 -4
  34. package/src/components/icon/Icon.tsx +13 -1
  35. package/src/components/image-block/ImageBlock.test.tsx +12 -4
  36. package/src/components/image-block/ImageBlock.tsx +3 -2
  37. package/src/components/input-helper/InputHelper.test.tsx +14 -4
  38. package/src/components/input-helper/InputHelper.tsx +3 -2
  39. package/src/components/input-label/InputLabel.test.tsx +14 -4
  40. package/src/components/input-label/InputLabel.tsx +4 -4
  41. package/src/components/lightbox/Lightbox.test.tsx +17 -6
  42. package/src/components/lightbox/Lightbox.tsx +8 -5
  43. package/src/components/link-preview/LinkPreview.test.tsx +9 -3
  44. package/src/components/link-preview/LinkPreview.tsx +3 -2
  45. package/src/components/mosaic/Mosaic.test.tsx +9 -3
  46. package/src/components/mosaic/Mosaic.tsx +4 -4
  47. package/src/components/navigation/Navigation.test.tsx +18 -9
  48. package/src/components/navigation/Navigation.tsx +13 -5
  49. package/src/components/navigation/NavigationItem.tsx +3 -3
  50. package/src/components/navigation/NavigationSection.tsx +4 -4
  51. package/src/components/notification/Notification.tsx +3 -2
  52. package/src/components/popover/Popover.test.tsx +18 -4
  53. package/src/components/popover/Popover.tsx +2 -1
  54. package/src/components/post-block/PostBlock.test.tsx +9 -3
  55. package/src/components/post-block/PostBlock.tsx +3 -2
  56. package/src/components/progress/Progress.tsx +3 -2
  57. package/src/components/progress/ProgressCircular.test.tsx +9 -16
  58. package/src/components/progress/ProgressCircular.tsx +3 -2
  59. package/src/components/progress/ProgressLinear.test.tsx +13 -18
  60. package/src/components/progress/ProgressLinear.tsx +4 -4
  61. package/src/components/radio-button/RadioButton.test.tsx +9 -3
  62. package/src/components/radio-button/RadioButton.tsx +4 -4
  63. package/src/components/select/Select.test.tsx +9 -3
  64. package/src/components/select/Select.tsx +27 -23
  65. package/src/components/select/SelectMultiple.test.tsx +9 -3
  66. package/src/components/select/SelectMultiple.tsx +109 -103
  67. package/src/components/select/WithSelectContext.tsx +8 -6
  68. package/src/components/side-navigation/SideNavigation.tsx +3 -1
  69. package/src/components/skeleton/SkeletonCircle.test.tsx +9 -3
  70. package/src/components/skeleton/SkeletonCircle.tsx +4 -4
  71. package/src/components/skeleton/SkeletonRectangle.test.tsx +9 -3
  72. package/src/components/skeleton/SkeletonRectangle.tsx +3 -2
  73. package/src/components/skeleton/SkeletonTypography.test.tsx +9 -3
  74. package/src/components/skeleton/SkeletonTypography.tsx +4 -4
  75. package/src/components/slider/Slider.test.tsx +9 -3
  76. package/src/components/slider/Slider.tsx +3 -2
  77. package/src/components/slideshow/Slides.tsx +3 -1
  78. package/src/components/slideshow/Slideshow.test.tsx +9 -3
  79. package/src/components/slideshow/Slideshow.tsx +3 -2
  80. package/src/components/slideshow/SlideshowControls.tsx +3 -2
  81. package/src/components/switch/Switch.test.tsx +9 -3
  82. package/src/components/switch/Switch.tsx +3 -2
  83. package/src/components/table/Table.test.tsx +9 -3
  84. package/src/components/table/Table.tsx +4 -4
  85. package/src/components/tabs/TabList.test.tsx +9 -3
  86. package/src/components/tabs/TabList.tsx +11 -2
  87. package/src/components/text-field/TextField.test.tsx +9 -3
  88. package/src/components/text-field/TextField.tsx +3 -2
  89. package/src/components/thumbnail/Thumbnail.test.tsx +9 -3
  90. package/src/components/thumbnail/Thumbnail.tsx +3 -2
  91. package/src/components/uploader/Uploader.test.tsx +9 -3
  92. package/src/components/uploader/Uploader.tsx +13 -2
  93. package/src/components/user-block/UserBlock.test.tsx +9 -3
  94. package/src/components/user-block/UserBlock.tsx +3 -2
  95. package/src/index.ts +1 -0
  96. package/src/testing/utils/ThemeSentinel.tsx +11 -0
  97. package/src/testing/utils/commonTestsSuiteRTL.tsx +190 -0
  98. package/src/utils/theme/ThemeContext.ts +16 -0
  99. package/src/utils/theme/invertTheme.ts +4 -0
  100. package/src/testing/utils/commonTestsSuiteRTL.ts +0 -64
  101. package/src/utils/ThemeContext.ts +0 -4
@@ -1,9 +1,8 @@
1
1
  import React from 'react';
2
2
 
3
3
  import { getByClassName } from '@lumx/react/testing/utils/queries';
4
- import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
4
+ import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
5
5
  import { render } from '@testing-library/react';
6
- import { Theme } from '@lumx/react';
7
6
 
8
7
  import { ProgressLinear, ProgressLinearProps } from './ProgressLinear';
9
8
 
@@ -12,26 +11,22 @@ const CLASSNAME = ProgressLinear.className as string;
12
11
  /**
13
12
  * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
14
13
  */
15
- const setup = (props: Partial<ProgressLinearProps> = {}) => {
16
- const { container } = render(<ProgressLinear {...(props as any)} />);
14
+ const setup = (props: Partial<ProgressLinearProps> = {}, { wrapper }: SetupRenderOptions = {}) => {
15
+ const { container } = render(<ProgressLinear {...(props as any)} />, { wrapper });
17
16
  const element = getByClassName(container, CLASSNAME);
18
17
  return { container, element, props };
19
18
  };
20
19
 
21
20
  describe(`<${ProgressLinear.displayName}>`, () => {
22
- it('should render default', () => {
23
- const { element } = setup();
24
- expect(element).toBeInTheDocument();
25
- expect(element).toHaveClass(CLASSNAME);
26
- expect(element).toHaveClass(`${CLASSNAME}--theme-light`);
21
+ commonTestsSuiteRTL(setup, {
22
+ baseClassName: CLASSNAME,
23
+ forwardClassName: 'element',
24
+ forwardAttributes: 'element',
25
+ applyTheme: {
26
+ affects: [{ element: 'element' }],
27
+ viaProp: true,
28
+ viaContext: true,
29
+ defaultTheme: 'light',
30
+ },
27
31
  });
28
-
29
- it('should render dark theme', () => {
30
- const { element } = setup({ theme: Theme.dark });
31
- expect(element).toBeInTheDocument();
32
- expect(element).toHaveClass(CLASSNAME);
33
- expect(element).toHaveClass(`${CLASSNAME}--theme-dark`);
34
- });
35
-
36
- commonTestsSuiteRTL(setup, { baseClassName: CLASSNAME, forwardClassName: 'element', forwardAttributes: 'element' });
37
32
  });
@@ -6,6 +6,7 @@ import { Theme } from '@lumx/react';
6
6
 
7
7
  import { Comp, GenericProps, HasTheme } from '@lumx/react/utils/type';
8
8
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
9
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
9
10
 
10
11
  export interface ProgressLinearProps extends GenericProps, HasTheme {}
11
12
 
@@ -22,9 +23,7 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
22
23
  /**
23
24
  * Component default props.
24
25
  */
25
- const DEFAULT_PROPS: Partial<ProgressLinearProps> = {
26
- theme: Theme.light,
27
- };
26
+ const DEFAULT_PROPS: Partial<ProgressLinearProps> = {};
28
27
 
29
28
  /**
30
29
  * ProgressLinear component.
@@ -34,7 +33,8 @@ const DEFAULT_PROPS: Partial<ProgressLinearProps> = {
34
33
  * @return React element.
35
34
  */
36
35
  export const ProgressLinear: Comp<ProgressLinearProps, HTMLDivElement> = forwardRef((props, ref) => {
37
- const { className, theme, ...forwardedProps } = props;
36
+ const defaultTheme = useTheme() || Theme.light;
37
+ const { className, theme = defaultTheme, ...forwardedProps } = props;
38
38
 
39
39
  return (
40
40
  <div
@@ -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 { getByClassName, getByTagName, queryByClassName } from '@lumx/react/testing/utils/queries';
5
5
  import { render } from '@testing-library/react';
6
6
  import userEvent from '@testing-library/user-event';
@@ -14,9 +14,9 @@ type SetupProps = Partial<RadioButtonProps>;
14
14
  /**
15
15
  * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
16
16
  */
17
- const setup = (propsOverride: SetupProps = {}) => {
17
+ const setup = (propsOverride: SetupProps = {}, { wrapper }: SetupRenderOptions = {}) => {
18
18
  const props: any = { id: 'fixedId', ...propsOverride };
19
- render(<RadioButton {...props} />);
19
+ render(<RadioButton {...props} />, { wrapper });
20
20
 
21
21
  const radioButton = getByClassName(document.body, CLASSNAME);
22
22
  const helper = queryByClassName(radioButton, `${CLASSNAME}__helper`);
@@ -105,5 +105,11 @@ describe(`<${RadioButton.displayName}>`, () => {
105
105
  baseClassName: CLASSNAME,
106
106
  forwardClassName: 'radioButton',
107
107
  forwardAttributes: 'radioButton',
108
+ applyTheme: {
109
+ affects: [{ element: 'radioButton' }],
110
+ viaProp: true,
111
+ viaContext: true,
112
+ defaultTheme: 'light',
113
+ },
108
114
  });
109
115
  });
@@ -7,6 +7,7 @@ import { InputHelper, InputLabel, Theme } from '@lumx/react';
7
7
  import { Comp, GenericProps, HasTheme } from '@lumx/react/utils/type';
8
8
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
9
9
  import { useId } from '@lumx/react/hooks/useId';
10
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
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.
@@ -59,6 +58,7 @@ const DEFAULT_PROPS: Partial<RadioButtonProps> = {
59
58
  * @return React element.
60
59
  */
61
60
  export const RadioButton: Comp<RadioButtonProps, HTMLDivElement> = forwardRef((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
@@ -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
  });
@@ -15,6 +15,7 @@ import { Comp } from '@lumx/react/utils/type';
15
15
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
16
16
  import { mergeRefs } from '@lumx/react/utils/mergeRefs';
17
17
 
18
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
18
19
  import { WithSelectContext } from './WithSelectContext';
19
20
  import { CoreSelectProps, SelectVariant } from './constants';
20
21
 
@@ -42,29 +43,32 @@ const stopPropagation = (evt: Event) => evt.stopPropagation();
42
43
  /**
43
44
  * Select component.
44
45
  */
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
- }) => {
46
+ const SelectField: React.FC<SelectProps> = (props) => {
47
+ const defaultTheme = useTheme();
48
+ const {
49
+ anchorRef,
50
+ clearButtonProps,
51
+ handleKeyboardNav,
52
+ hasError,
53
+ hasInputClear,
54
+ icon,
55
+ id,
56
+ isDisabled,
57
+ isEmpty,
58
+ isRequired,
59
+ isValid,
60
+ label,
61
+ onClear,
62
+ onInputClick,
63
+ placeholder,
64
+ selectedValueRender,
65
+ theme = defaultTheme,
66
+ value,
67
+ variant,
68
+ selectElementRef,
69
+ ...forwardedProps
70
+ } = props;
71
+
68
72
  return (
69
73
  <>
70
74
  {variant === SelectVariant.input && (
@@ -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
  });
@@ -12,6 +12,7 @@ import { InputLabel } from '@lumx/react/components/input-label/InputLabel';
12
12
  import { Comp } from '@lumx/react/utils/type';
13
13
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
14
14
  import { mergeRefs } from '@lumx/react/utils/mergeRefs';
15
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
15
16
 
16
17
  import { WithSelectContext } from './WithSelectContext';
17
18
  import { CoreSelectProps, SelectVariant } from './constants';
@@ -57,118 +58,123 @@ const DEFAULT_PROPS: Partial<SelectMultipleProps> = {
57
58
  selectedValueRender: (choice) => choice,
58
59
  };
59
60
 
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>
61
+ export const SelectMultipleField: React.FC<SelectMultipleProps> = (props) => {
62
+ const defaultTheme = useTheme();
63
+ const {
64
+ anchorRef,
65
+ handleKeyboardNav,
66
+ hasError,
67
+ icon,
68
+ id,
69
+ isDisabled,
70
+ isEmpty,
71
+ isRequired,
72
+ isValid,
73
+ label,
74
+ onClear,
75
+ onInputClick,
76
+ placeholder,
77
+ selectedChipRender,
78
+ selectedValueRender,
79
+ theme = defaultTheme,
80
+ value,
81
+ variant,
82
+ selectElementRef,
83
+ ...forwardedProps
84
+ } = props;
85
+
86
+ return (
87
+ <>
88
+ {variant === SelectVariant.input && (
89
+ <>
90
+ {label && (
91
+ <div className={`${CLASSNAME}__header`}>
92
+ <InputLabel
93
+ htmlFor={id}
94
+ className={`${CLASSNAME}__label`}
95
+ isRequired={isRequired}
96
+ theme={theme}
97
+ >
98
+ {label}
99
+ </InputLabel>
131
100
  </div>
132
101
  )}
133
102
 
134
- {(isValid || hasError) && (
135
- <div className={`${CLASSNAME}__input-validity`}>
136
- <Icon icon={isValid ? mdiCheckCircle : mdiAlertCircle} size={Size.xxs} />
103
+ {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
104
+ <div
105
+ ref={mergeRefs(anchorRef as RefObject<HTMLDivElement>, selectElementRef)}
106
+ id={id}
107
+ className={`${CLASSNAME}__wrapper`}
108
+ onClick={onInputClick}
109
+ onKeyDown={handleKeyboardNav}
110
+ tabIndex={isDisabled ? undefined : 0}
111
+ aria-disabled={isDisabled || undefined}
112
+ {...forwardedProps}
113
+ >
114
+ {icon && (
115
+ <Icon
116
+ className={`${CLASSNAME}__input-icon`}
117
+ color={theme === Theme.dark ? 'light' : undefined}
118
+ icon={icon}
119
+ size={Size.xs}
120
+ />
121
+ )}
122
+
123
+ <div className={`${CLASSNAME}__chips`}>
124
+ {!isEmpty &&
125
+ value.map((val, index) => selectedChipRender?.(val, index, onClear, isDisabled, theme))}
137
126
  </div>
138
- )}
139
127
 
140
- <div className={`${CLASSNAME}__input-indicator`}>
141
- <Icon icon={mdiMenuDown} size={Size.s} />
128
+ {isEmpty && placeholder && (
129
+ <div
130
+ className={classNames([
131
+ `${CLASSNAME}__input-native`,
132
+ `${CLASSNAME}__input-native--placeholder`,
133
+ ])}
134
+ >
135
+ <span>{placeholder}</span>
136
+ </div>
137
+ )}
138
+
139
+ {(isValid || hasError) && (
140
+ <div className={`${CLASSNAME}__input-validity`}>
141
+ <Icon icon={isValid ? mdiCheckCircle : mdiAlertCircle} size={Size.xxs} />
142
+ </div>
143
+ )}
144
+
145
+ <div className={`${CLASSNAME}__input-indicator`}>
146
+ <Icon icon={mdiMenuDown} size={Size.s} />
147
+ </div>
142
148
  </div>
143
- </div>
144
- </>
145
- )}
149
+ </>
150
+ )}
146
151
 
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>}
152
+ {variant === SelectVariant.chip && (
153
+ <Chip
154
+ id={id}
155
+ isSelected={!isEmpty}
156
+ isDisabled={isDisabled}
157
+ after={<Icon icon={isEmpty ? mdiMenuDown : mdiCloseCircle} />}
158
+ onAfterClick={isEmpty ? onInputClick : onClear}
159
+ onClick={onInputClick}
160
+ ref={mergeRefs(anchorRef as RefObject<HTMLAnchorElement>, selectElementRef)}
161
+ theme={theme}
162
+ {...forwardedProps}
163
+ >
164
+ {isEmpty && <span>{label}</span>}
160
165
 
161
- {!isEmpty && (
162
- <span>
163
- <span>{selectedValueRender?.(value[0])}</span>
166
+ {!isEmpty && (
167
+ <span>
168
+ <span>{selectedValueRender?.(value[0])}</span>
164
169
 
165
- {value.length > 1 && <span>&nbsp;+{value.length - 1}</span>}
166
- </span>
167
- )}
168
- </Chip>
169
- )}
170
- </>
171
- );
170
+ {value.length > 1 && <span>&nbsp;+{value.length - 1}</span>}
171
+ </span>
172
+ )}
173
+ </Chip>
174
+ )}
175
+ </>
176
+ );
177
+ };
172
178
 
173
179
  /**
174
180
  * SelectMultiple component.
@@ -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);
@@ -6,6 +6,7 @@ import { SideNavigationItem, Theme } from '@lumx/react';
6
6
 
7
7
  import { Comp, GenericProps, HasTheme, isComponent } from '@lumx/react/utils/type';
8
8
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
9
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
9
10
 
10
11
  /**
11
12
  * Defines the props of the component.
@@ -33,7 +34,8 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
33
34
  * @return React element.
34
35
  */
35
36
  export const SideNavigation: Comp<SideNavigationProps, HTMLUListElement> = forwardRef((props, ref) => {
36
- const { children, className, theme, ...forwardedProps } = props;
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,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
  });
@@ -4,6 +4,7 @@ import React, { forwardRef } from 'react';
4
4
  import { GlobalSize, Theme, ColorPalette } from '@lumx/react';
5
5
  import { Comp, GenericProps, HasTheme } from '@lumx/react/utils/type';
6
6
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
7
+ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
7
8
 
8
9
  /**
9
10
  * Defines the props of the component.
@@ -15,9 +16,7 @@ export interface SkeletonCircleProps extends GenericProps, HasTheme {
15
16
  color?: ColorPalette;
16
17
  }
17
18
 
18
- const DEFAULT_PROPS: Partial<SkeletonCircleProps> = {
19
- theme: Theme.light,
20
- };
19
+ const DEFAULT_PROPS: Partial<SkeletonCircleProps> = {};
21
20
 
22
21
  /**
23
22
  * Component display name.
@@ -37,7 +36,8 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
37
36
  * @return React element.
38
37
  */
39
38
  export const SkeletonCircle: Comp<SkeletonCircleProps, HTMLDivElement> = forwardRef((props, ref) => {
40
- const { className, size, color, theme, ...forwardedProps } = props;
39
+ const defaultTheme = useTheme() || Theme.light;
40
+ const { className, size, color, theme = defaultTheme, ...forwardedProps } = props;
41
41
 
42
42
  return (
43
43
  <div