@lumx/react 3.0.5-alpha.1 → 3.0.5
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.
- package/index.d.ts +2 -0
- package/index.js +43 -27
- package/index.js.map +1 -1
- package/package.json +4 -4
- package/src/components/expansion-panel/ExpansionPanel.test.tsx +64 -93
- package/src/components/expansion-panel/ExpansionPanel.tsx +1 -0
- package/src/components/radio-button/RadioButton.tsx +10 -5
- package/src/components/radio-button/__snapshots__/RadioButton.test.tsx.snap +2 -0
- package/src/components/switch/Switch.tsx +5 -4
- package/src/components/switch/__snapshots__/Switch.test.tsx.snap +3 -0
- package/src/hooks/useTransitionVisibility.ts +17 -16
- package/src/utils/userHasReducedMotion.ts +7 -0
- package/src/components/expansion-panel/__snapshots__/ExpansionPanel.test.tsx.snap +0 -32
package/package.json
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@juggle/resize-observer": "^3.2.0",
|
|
10
|
-
"@lumx/core": "^3.0.5
|
|
11
|
-
"@lumx/icons": "^3.0.5
|
|
10
|
+
"@lumx/core": "^3.0.5",
|
|
11
|
+
"@lumx/icons": "^3.0.5",
|
|
12
12
|
"@popperjs/core": "^2.5.4",
|
|
13
13
|
"body-scroll-lock": "^3.1.5",
|
|
14
14
|
"classnames": "^2.2.6",
|
|
@@ -114,6 +114,6 @@
|
|
|
114
114
|
"build:storybook": "cd storybook && ./build"
|
|
115
115
|
},
|
|
116
116
|
"sideEffects": false,
|
|
117
|
-
"version": "3.0.5
|
|
118
|
-
"gitHead": "
|
|
117
|
+
"version": "3.0.5",
|
|
118
|
+
"gitHead": "83eccabdc29dbf61fd519c88729002a5bb8d4790"
|
|
119
119
|
}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import '
|
|
3
|
+
import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
|
|
4
|
+
import { queryByRole, render } from '@testing-library/react';
|
|
5
|
+
import { getByClassName, queryByClassName } from '@lumx/react/testing/utils/queries';
|
|
6
|
+
import userEvent from '@testing-library/user-event';
|
|
7
|
+
import { ExpansionPanel, ExpansionPanelProps } from '.';
|
|
5
8
|
|
|
6
|
-
import { commonTestsSuite, Wrapper } from '@lumx/react/testing/utils';
|
|
7
|
-
import { getBasicClass } from '@lumx/react/utils/className';
|
|
8
|
-
|
|
9
|
-
import { Theme } from '@lumx/react';
|
|
10
|
-
import { ExpansionPanel, ExpansionPanelProps } from './ExpansionPanel';
|
|
11
|
-
|
|
12
|
-
const DEFAULT_PROPS = ExpansionPanel.defaultProps as any;
|
|
13
9
|
const CLASSNAME = ExpansionPanel.className as string;
|
|
14
10
|
|
|
15
11
|
type SetupProps = Partial<ExpansionPanelProps>;
|
|
@@ -17,63 +13,68 @@ type SetupProps = Partial<ExpansionPanelProps>;
|
|
|
17
13
|
/**
|
|
18
14
|
* Mounts the component and returns common DOM elements / data needed in multiple tests further down.
|
|
19
15
|
*/
|
|
20
|
-
const setup = (
|
|
16
|
+
const setup = (propsOverride: SetupProps = {}) => {
|
|
21
17
|
const props: ExpansionPanelProps = {
|
|
22
18
|
toggleButtonProps: { label: 'Toggle' },
|
|
23
19
|
...propsOverride,
|
|
24
20
|
};
|
|
25
|
-
const
|
|
26
|
-
const wrapper: Wrapper = renderer(<ExpansionPanel {...props} />);
|
|
21
|
+
const { container } = render(<ExpansionPanel {...props} />);
|
|
27
22
|
|
|
28
23
|
return {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
container,
|
|
25
|
+
element: getByClassName(container, CLASSNAME),
|
|
26
|
+
query: {
|
|
27
|
+
toggleButton: () => queryByRole(container, 'button', { name: /Toggle/i }),
|
|
28
|
+
header: () => queryByClassName(container, `${CLASSNAME}__header`),
|
|
29
|
+
content: () => queryByClassName(container, `${CLASSNAME}__wrapper`),
|
|
30
|
+
},
|
|
32
31
|
props,
|
|
33
|
-
root: wrapper.find('section'),
|
|
34
|
-
wrapper,
|
|
35
32
|
};
|
|
36
33
|
};
|
|
37
34
|
|
|
38
35
|
describe(`<${ExpansionPanel.displayName}>`, () => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
describe('Render', () => {
|
|
37
|
+
it('should render default', () => {
|
|
38
|
+
const { element, query } = setup();
|
|
39
|
+
expect(element).toBeInTheDocument();
|
|
40
|
+
expect(element).toHaveClass(CLASSNAME);
|
|
41
|
+
expect(element).toHaveClass(`${CLASSNAME}--is-close`);
|
|
42
|
+
expect(element).toHaveClass(`${CLASSNAME}--theme-light`);
|
|
43
|
+
|
|
44
|
+
// Header is visible
|
|
45
|
+
expect(query.header()).toBeInTheDocument();
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
expect(wrapper).toMatchSnapshot();
|
|
47
|
+
// Content is not visible
|
|
48
|
+
expect(query.content()).not.toBeInTheDocument();
|
|
46
49
|
|
|
47
|
-
expect(
|
|
48
|
-
expect(root).toHaveClassName(CLASSNAME);
|
|
50
|
+
expect(query.toggleButton()).toHaveAttribute('aria-expanded', 'false');
|
|
49
51
|
});
|
|
50
|
-
});
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
it('should render open', () => {
|
|
54
|
+
const { query } = setup({ isOpen: true });
|
|
55
|
+
|
|
56
|
+
// Content is visible
|
|
57
|
+
expect(query.content()).toBeInTheDocument();
|
|
55
58
|
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
expect(query.toggleButton()).toHaveAttribute('aria-expanded', 'true');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should show label', () => {
|
|
63
|
+
const labelText = 'Label text';
|
|
64
|
+
const { query } = setup({ label: labelText });
|
|
58
65
|
|
|
59
|
-
|
|
60
|
-
expect(root).toHaveClassName(
|
|
61
|
-
getBasicClass({ prefix: CLASSNAME, type: prop, value: DEFAULT_PROPS[prop] }),
|
|
62
|
-
);
|
|
63
|
-
}
|
|
66
|
+
expect(query.header()).toHaveTextContent(labelText);
|
|
64
67
|
});
|
|
65
68
|
|
|
66
|
-
it('should
|
|
67
|
-
const
|
|
69
|
+
it('should show header instead of label', () => {
|
|
70
|
+
const labelText = 'Label text';
|
|
71
|
+
const headerText = 'Header text';
|
|
72
|
+
const { query } = setup({ label: labelText, children: <header>{headerText}</header> });
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
root.hasClass('lumx-color-background-dark-L6');
|
|
71
|
-
root.hasClass('lumx-expansion-panel--theme-light');
|
|
72
|
-
root.hasClass('lumx-color-font-dark-N');
|
|
74
|
+
expect(query.header()).toHaveTextContent(headerText);
|
|
73
75
|
});
|
|
74
76
|
});
|
|
75
77
|
|
|
76
|
-
// 3. Test events.
|
|
77
78
|
describe('Events', () => {
|
|
78
79
|
const onOpen: jest.Mock = jest.fn();
|
|
79
80
|
const onClose: jest.Mock = jest.fn();
|
|
@@ -83,63 +84,33 @@ describe(`<${ExpansionPanel.displayName}>`, () => {
|
|
|
83
84
|
beforeEach(onClose.mockClear);
|
|
84
85
|
beforeEach(onToggleOpen.mockClear);
|
|
85
86
|
|
|
86
|
-
it('should
|
|
87
|
-
const {
|
|
88
|
-
header.simulate('click');
|
|
89
|
-
expect(onOpen).toHaveBeenCalled();
|
|
90
|
-
});
|
|
87
|
+
it('should open on click', async () => {
|
|
88
|
+
const { query } = setup({ isOpen: false, onOpen, onClose, onToggleOpen });
|
|
91
89
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
header.simulate('click');
|
|
95
|
-
expect(onClose).toHaveBeenCalled();
|
|
96
|
-
});
|
|
90
|
+
// Content is not visible
|
|
91
|
+
expect(query.content()).not.toBeInTheDocument();
|
|
97
92
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
expect(onToggleOpen).
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
// 4. Test conditions (i.e. things that display or not in the UI based on props).
|
|
107
|
-
describe('Conditions', () => {
|
|
108
|
-
// Here is an example of children types check.
|
|
109
|
-
|
|
110
|
-
it('should hide content when `isOpen` == false', () => {
|
|
111
|
-
const { content } = setup({ isOpen: false });
|
|
112
|
-
|
|
113
|
-
expect(content.exists()).toBe(false);
|
|
93
|
+
// Click on toggle button
|
|
94
|
+
await userEvent.click(query.toggleButton() as any);
|
|
95
|
+
expect(onOpen).toHaveBeenCalled();
|
|
96
|
+
expect(onClose).not.toHaveBeenCalled();
|
|
97
|
+
expect(onToggleOpen).toHaveBeenCalledWith(true);
|
|
114
98
|
});
|
|
115
99
|
|
|
116
|
-
it('should
|
|
117
|
-
const {
|
|
100
|
+
it('should close on click', async () => {
|
|
101
|
+
const { query } = setup({ isOpen: true, onOpen, onClose, onToggleOpen });
|
|
118
102
|
|
|
119
|
-
|
|
120
|
-
|
|
103
|
+
// Content is visible
|
|
104
|
+
expect(query.content()).toBeInTheDocument();
|
|
121
105
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
expect(
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should show header instead of label', () => {
|
|
130
|
-
const labelText = 'Label text';
|
|
131
|
-
const headerText = 'Header text';
|
|
132
|
-
const { header } = setup({ label: labelText, children: <header>{headerText}</header> });
|
|
133
|
-
|
|
134
|
-
expect(header.text()).toContain(headerText);
|
|
106
|
+
// Click on header
|
|
107
|
+
await userEvent.click(query.header() as any);
|
|
108
|
+
expect(onOpen).not.toHaveBeenCalled();
|
|
109
|
+
expect(onClose).toHaveBeenCalled();
|
|
110
|
+
expect(onToggleOpen).toHaveBeenCalledWith(false);
|
|
135
111
|
});
|
|
136
112
|
});
|
|
137
113
|
|
|
138
|
-
// 5. Test state.
|
|
139
|
-
describe('State', () => {
|
|
140
|
-
// Nothing to do here.
|
|
141
|
-
});
|
|
142
|
-
|
|
143
114
|
// Common tests suite.
|
|
144
|
-
|
|
115
|
+
commonTestsSuiteRTL(setup, { baseClassName: CLASSNAME, forwardClassName: 'element', forwardAttributes: 'element' });
|
|
145
116
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useMemo, forwardRef, ReactNode, SyntheticEvent } from 'react';
|
|
1
|
+
import React, { useMemo, forwardRef, ReactNode, SyntheticEvent, InputHTMLAttributes } from 'react';
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
import { uid } from 'uid';
|
|
@@ -30,6 +30,8 @@ export interface RadioButtonProps extends GenericProps, HasTheme {
|
|
|
30
30
|
value?: string;
|
|
31
31
|
/** On change callback. */
|
|
32
32
|
onChange?(value?: string, name?: string, event?: SyntheticEvent): void;
|
|
33
|
+
/** optional props for input */
|
|
34
|
+
inputProps?: InputHTMLAttributes<HTMLInputElement>;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -71,9 +73,10 @@ export const RadioButton: Comp<RadioButtonProps, HTMLDivElement> = forwardRef((p
|
|
|
71
73
|
onChange,
|
|
72
74
|
theme,
|
|
73
75
|
value,
|
|
76
|
+
inputProps,
|
|
74
77
|
...forwardedProps
|
|
75
78
|
} = props;
|
|
76
|
-
const
|
|
79
|
+
const inputId = useMemo(() => id || `${CLASSNAME.toLowerCase()}-${uid()}`, [id]);
|
|
77
80
|
|
|
78
81
|
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
79
82
|
if (onChange) {
|
|
@@ -101,13 +104,15 @@ export const RadioButton: Comp<RadioButtonProps, HTMLDivElement> = forwardRef((p
|
|
|
101
104
|
ref={inputRef}
|
|
102
105
|
className={`${CLASSNAME}__input-native`}
|
|
103
106
|
disabled={isDisabled}
|
|
104
|
-
id={
|
|
107
|
+
id={inputId}
|
|
105
108
|
tabIndex={isDisabled ? -1 : 0}
|
|
106
109
|
type="radio"
|
|
107
110
|
name={name}
|
|
108
111
|
value={value}
|
|
109
112
|
checked={isChecked}
|
|
110
113
|
onChange={handleChange}
|
|
114
|
+
aria-describedby={helper ? `${inputId}-helper` : undefined}
|
|
115
|
+
{...inputProps}
|
|
111
116
|
/>
|
|
112
117
|
|
|
113
118
|
<div className={`${CLASSNAME}__input-placeholder`}>
|
|
@@ -118,12 +123,12 @@ export const RadioButton: Comp<RadioButtonProps, HTMLDivElement> = forwardRef((p
|
|
|
118
123
|
|
|
119
124
|
<div className={`${CLASSNAME}__content`}>
|
|
120
125
|
{label && (
|
|
121
|
-
<InputLabel htmlFor={
|
|
126
|
+
<InputLabel htmlFor={inputId} theme={theme} className={`${CLASSNAME}__label`}>
|
|
122
127
|
{label}
|
|
123
128
|
</InputLabel>
|
|
124
129
|
)}
|
|
125
130
|
{helper && (
|
|
126
|
-
<InputHelper theme={theme} className={`${CLASSNAME}__helper`}>
|
|
131
|
+
<InputHelper id={`${inputId}-helper`} theme={theme} className={`${CLASSNAME}__helper`}>
|
|
127
132
|
{helper}
|
|
128
133
|
</InputHelper>
|
|
129
134
|
)}
|
|
@@ -72,6 +72,7 @@ exports[`<RadioButton> Snapshots and structure should render label & helper 1`]
|
|
|
72
72
|
className="lumx-radio-button__input-wrapper"
|
|
73
73
|
>
|
|
74
74
|
<input
|
|
75
|
+
aria-describedby="fixedId-helper"
|
|
75
76
|
className="lumx-radio-button__input-native"
|
|
76
77
|
id="fixedId"
|
|
77
78
|
onChange={[Function]}
|
|
@@ -101,6 +102,7 @@ exports[`<RadioButton> Snapshots and structure should render label & helper 1`]
|
|
|
101
102
|
</InputLabel>
|
|
102
103
|
<InputHelper
|
|
103
104
|
className="lumx-radio-button__helper"
|
|
105
|
+
id="fixedId-helper"
|
|
104
106
|
kind="info"
|
|
105
107
|
theme="light"
|
|
106
108
|
>
|
|
@@ -75,7 +75,7 @@ export const Switch: Comp<SwitchProps, HTMLDivElement> = forwardRef((props, ref)
|
|
|
75
75
|
inputProps = {},
|
|
76
76
|
...forwardedProps
|
|
77
77
|
} = props;
|
|
78
|
-
const
|
|
78
|
+
const inputId = useMemo(() => id || `switch-${uid()}`, [id]);
|
|
79
79
|
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
80
80
|
if (onChange) {
|
|
81
81
|
onChange(!isChecked, value, name, event);
|
|
@@ -103,7 +103,7 @@ export const Switch: Comp<SwitchProps, HTMLDivElement> = forwardRef((props, ref)
|
|
|
103
103
|
<input
|
|
104
104
|
type="checkbox"
|
|
105
105
|
role="switch"
|
|
106
|
-
id={
|
|
106
|
+
id={inputId}
|
|
107
107
|
className={`${CLASSNAME}__input-native`}
|
|
108
108
|
name={name}
|
|
109
109
|
value={value}
|
|
@@ -111,6 +111,7 @@ export const Switch: Comp<SwitchProps, HTMLDivElement> = forwardRef((props, ref)
|
|
|
111
111
|
checked={isChecked}
|
|
112
112
|
aria-checked={Boolean(isChecked)}
|
|
113
113
|
onChange={handleChange}
|
|
114
|
+
aria-describedby={helper ? `${inputId}-helper` : undefined}
|
|
114
115
|
{...inputProps}
|
|
115
116
|
/>
|
|
116
117
|
|
|
@@ -122,11 +123,11 @@ export const Switch: Comp<SwitchProps, HTMLDivElement> = forwardRef((props, ref)
|
|
|
122
123
|
|
|
123
124
|
{Children.count(children) > 0 && (
|
|
124
125
|
<div className={`${CLASSNAME}__content`}>
|
|
125
|
-
<InputLabel htmlFor={
|
|
126
|
+
<InputLabel htmlFor={inputId} theme={theme} className={`${CLASSNAME}__label`}>
|
|
126
127
|
{children}
|
|
127
128
|
</InputLabel>
|
|
128
129
|
{!isEmpty(helper) && (
|
|
129
|
-
<InputHelper theme={theme} className={`${CLASSNAME}__helper`}>
|
|
130
|
+
<InputHelper id={`${inputId}-helper`} theme={theme} className={`${CLASSNAME}__helper`}>
|
|
130
131
|
{helper}
|
|
131
132
|
</InputHelper>
|
|
132
133
|
)}
|
|
@@ -9,6 +9,7 @@ exports[`<Switch> Conditions should not display the \`helper\` if no \`label\` i
|
|
|
9
9
|
>
|
|
10
10
|
<input
|
|
11
11
|
aria-checked={false}
|
|
12
|
+
aria-describedby="switch-uid-helper"
|
|
12
13
|
className="lumx-switch__input-native"
|
|
13
14
|
id="switch-uid"
|
|
14
15
|
onChange={[Function]}
|
|
@@ -68,6 +69,7 @@ exports[`<Switch> Snapshots and structure should render correctly with a \`label
|
|
|
68
69
|
>
|
|
69
70
|
<input
|
|
70
71
|
aria-checked={false}
|
|
72
|
+
aria-describedby="switch-uid-helper"
|
|
71
73
|
className="lumx-switch__input-native"
|
|
72
74
|
id="switch-uid"
|
|
73
75
|
onChange={[Function]}
|
|
@@ -97,6 +99,7 @@ exports[`<Switch> Snapshots and structure should render correctly with a \`label
|
|
|
97
99
|
</InputLabel>
|
|
98
100
|
<InputHelper
|
|
99
101
|
className="lumx-switch__helper"
|
|
102
|
+
id="switch-uid-helper"
|
|
100
103
|
kind="info"
|
|
101
104
|
theme="light"
|
|
102
105
|
>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RefObject, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { userHasReducedMotion } from '@lumx/react/utils/userHasReducedMotion';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Returns true if the component is visible tracking the opacity transition.
|
|
@@ -16,29 +17,22 @@ export const useTransitionVisibility = (
|
|
|
16
17
|
const [isVisible, setVisible] = useState(isComponentVisible);
|
|
17
18
|
const previousVisibility = useRef(isVisible);
|
|
18
19
|
|
|
20
|
+
// On component visibility change.
|
|
19
21
|
useEffect(() => {
|
|
20
22
|
if (isComponentVisible) {
|
|
21
23
|
setVisible(true);
|
|
22
|
-
|
|
23
|
-
// Transition event is not available so visibility is set to false directly.
|
|
24
|
-
setVisible(false);
|
|
25
|
-
}
|
|
26
|
-
}, [isComponentVisible]);
|
|
27
|
-
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
if (onVisibilityChange && previousVisibility.current !== isVisible) {
|
|
30
|
-
onVisibilityChange(isVisible);
|
|
31
|
-
previousVisibility.current = isVisible;
|
|
24
|
+
return undefined;
|
|
32
25
|
}
|
|
33
|
-
}, [isVisible, onVisibilityChange]);
|
|
34
|
-
|
|
35
|
-
useEffect(() => {
|
|
36
26
|
const { current: element } = ref;
|
|
37
|
-
|
|
27
|
+
|
|
28
|
+
// Transition event is not supported or the user prefers reduced motion.
|
|
29
|
+
// => Skip `transitionend` event listening and set visibility to false directly.
|
|
30
|
+
if (!element || !window.TransitionEvent || userHasReducedMotion()) {
|
|
31
|
+
setVisible(false);
|
|
38
32
|
return undefined;
|
|
39
33
|
}
|
|
40
34
|
|
|
41
|
-
//
|
|
35
|
+
// Update visibility on opacity transition end.
|
|
42
36
|
const onTransitionEnd = (e: TransitionEvent) => {
|
|
43
37
|
if (e.target !== ref.current || e.propertyName !== 'opacity') return;
|
|
44
38
|
setVisible((wasVisible) => !wasVisible);
|
|
@@ -47,7 +41,14 @@ export const useTransitionVisibility = (
|
|
|
47
41
|
return () => {
|
|
48
42
|
element.removeEventListener('transitionend', onTransitionEnd);
|
|
49
43
|
};
|
|
50
|
-
});
|
|
44
|
+
}, [isComponentVisible, ref]);
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (onVisibilityChange && previousVisibility.current !== isVisible) {
|
|
48
|
+
onVisibilityChange(isVisible);
|
|
49
|
+
previousVisibility.current = isVisible;
|
|
50
|
+
}
|
|
51
|
+
}, [isVisible, onVisibilityChange]);
|
|
51
52
|
|
|
52
53
|
return isVisible || isComponentVisible;
|
|
53
54
|
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`<ExpansionPanel> Snapshots and structure should render correctly 1`] = `
|
|
4
|
-
<section
|
|
5
|
-
className="lumx-expansion-panel lumx-expansion-panel--is-close lumx-expansion-panel--theme-light"
|
|
6
|
-
>
|
|
7
|
-
<header
|
|
8
|
-
className="lumx-expansion-panel__header"
|
|
9
|
-
onClick={[Function]}
|
|
10
|
-
>
|
|
11
|
-
<div
|
|
12
|
-
className="lumx-expansion-panel__header-content"
|
|
13
|
-
>
|
|
14
|
-
<span
|
|
15
|
-
className="lumx-expansion-panel__label"
|
|
16
|
-
/>
|
|
17
|
-
</div>
|
|
18
|
-
<div
|
|
19
|
-
className="lumx-expansion-panel__header-toggle"
|
|
20
|
-
>
|
|
21
|
-
<IconButton
|
|
22
|
-
color="dark"
|
|
23
|
-
emphasis="low"
|
|
24
|
-
icon="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"
|
|
25
|
-
label="Toggle"
|
|
26
|
-
size="m"
|
|
27
|
-
theme="light"
|
|
28
|
-
/>
|
|
29
|
-
</div>
|
|
30
|
-
</header>
|
|
31
|
-
</section>
|
|
32
|
-
`;
|