Add EditorOptionsGroup component (#18812)
* Add EditorOptionsGroup component * Add actions and more tests * Add initialIsCollapsed property
This commit is contained in:
parent
74868ebb2f
commit
cbbb4dc221
|
@ -20,6 +20,7 @@ export default {
|
||||||
],
|
],
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
'^ui/(.*)': '<rootDir>/src/ui/public/$1',
|
'^ui/(.*)': '<rootDir>/src/ui/public/$1',
|
||||||
|
'^test_utils/(.*)': '<rootDir>/src/test_utils/public/$1',
|
||||||
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/src/dev/jest/mocks/file_mock.js',
|
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/src/dev/jest/mocks/file_mock.js',
|
||||||
'\\.(css|less|scss)$': '<rootDir>/src/dev/jest/mocks/style_mock.js',
|
'\\.(css|less|scss)$': '<rootDir>/src/dev/jest/mocks/style_mock.js',
|
||||||
},
|
},
|
||||||
|
|
18
src/test_utils/public/static_html_id_generator.js
Normal file
18
src/test_utils/public/static_html_id_generator.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
* Import this test utility in your jest test (and only there!) if you want the
|
||||||
|
* htmlIdGenerator from EUI to generate static ids. That will be needed if you
|
||||||
|
* want to use snapshot tests for a component, that uses the htmlIdGenerator.
|
||||||
|
* By default every test run would result in different ids and thus not be comparable.
|
||||||
|
* You can solve this by just importing this file. It will mock the htmlIdGenerator
|
||||||
|
* for the test file that imported it to produce static, but therfore potentially
|
||||||
|
* duplicate ids.
|
||||||
|
*
|
||||||
|
* import 'test_utils/html_id_generator';
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* global jest */
|
||||||
|
jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
||||||
|
htmlIdGenerator: (prefix = 'staticGenerator') => {
|
||||||
|
return (suffix = 'staticId') => `${prefix}_${suffix}`;
|
||||||
|
}
|
||||||
|
}));
|
|
@ -0,0 +1,271 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`<EditorOptionsGroup/> renders as expected 1`] = `
|
||||||
|
<div
|
||||||
|
class="euiPanel euiPanel--paddingMedium euiPanel--flexGrowZero editorOptionsGroup__panel"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiAccordion euiAccordion-isOpen"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexGroup euiFlexGroup--alignItemsCenter euiFlexGroup--responsive"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexItem"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
aria-controls="eog_staticId"
|
||||||
|
aria-expanded="true"
|
||||||
|
class="euiAccordion__button"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexGroup euiFlexGroup--gutterSmall euiFlexGroup--alignItemsCenter"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="euiIcon euiIcon--medium"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<path
|
||||||
|
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
|
||||||
|
id="arrow_down-a"
|
||||||
|
/>
|
||||||
|
</defs>
|
||||||
|
<use
|
||||||
|
fill-rule="nonzero"
|
||||||
|
href="#arrow_down-a"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="euiFlexItem euiAccordion__buttonContent"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
class="euiTitle euiTitle--xsmall"
|
||||||
|
>
|
||||||
|
Some options
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="euiAccordion__childWrapper"
|
||||||
|
id="eog_staticId"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiSpacer euiSpacer--m"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
Children
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
within the editor group
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<EditorOptionsGroup/> renders as expected with actions 1`] = `
|
||||||
|
<div
|
||||||
|
class="euiPanel euiPanel--paddingMedium euiPanel--flexGrowZero editorOptionsGroup__panel"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiAccordion euiAccordion-isOpen"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexGroup euiFlexGroup--alignItemsCenter euiFlexGroup--responsive"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexItem"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
aria-controls="eog_staticId"
|
||||||
|
aria-expanded="true"
|
||||||
|
class="euiAccordion__button"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexGroup euiFlexGroup--gutterSmall euiFlexGroup--alignItemsCenter"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="euiIcon euiIcon--medium"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<path
|
||||||
|
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
|
||||||
|
id="arrow_down-a"
|
||||||
|
/>
|
||||||
|
</defs>
|
||||||
|
<use
|
||||||
|
fill-rule="nonzero"
|
||||||
|
href="#arrow_down-a"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="euiFlexItem euiAccordion__buttonContent"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
class="euiTitle euiTitle--xsmall"
|
||||||
|
>
|
||||||
|
Some actions
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
aria-label="Remove"
|
||||||
|
class="euiButtonIcon euiButtonIcon--text"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="euiIcon euiIcon--medium euiButtonIcon__icon"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<path
|
||||||
|
d="M11 3h5v1H0V3h5V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2zm-7.056 8H7v1H4.1l.392 2.519c.042.269.254.458.493.458h6.03c.239 0 .451-.189.493-.458l1.498-9.576H14l-1.504 9.73c-.116.747-.74 1.304-1.481 1.304h-6.03c-.741 0-1.365-.557-1.481-1.304l-1.511-9.73H9V5.95H3.157L3.476 8H8v1H3.632l.312 2zM6 3h4V1H6v2z"
|
||||||
|
id="trash-a"
|
||||||
|
/>
|
||||||
|
</defs>
|
||||||
|
<use
|
||||||
|
href="#trash-a"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="euiAccordion__childWrapper"
|
||||||
|
id="eog_staticId"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiSpacer euiSpacer--m"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
Some children
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<EditorOptionsGroup/> renders as expected with initial collapsed 1`] = `
|
||||||
|
<div
|
||||||
|
class="euiPanel euiPanel--paddingMedium euiPanel--flexGrowZero editorOptionsGroup__panel"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiAccordion"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexGroup euiFlexGroup--alignItemsCenter euiFlexGroup--responsive"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexItem"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
aria-controls="eog_staticId"
|
||||||
|
aria-expanded="false"
|
||||||
|
class="euiAccordion__button"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexGroup euiFlexGroup--gutterSmall euiFlexGroup--alignItemsCenter"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="euiIcon euiIcon--medium"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<path
|
||||||
|
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
|
||||||
|
id="arrow_right-a"
|
||||||
|
/>
|
||||||
|
</defs>
|
||||||
|
<use
|
||||||
|
fill-rule="nonzero"
|
||||||
|
href="#arrow_right-a"
|
||||||
|
transform="matrix(0 1 1 0 0 0)"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="euiFlexItem euiAccordion__buttonContent"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
class="euiTitle euiTitle--xsmall"
|
||||||
|
>
|
||||||
|
Some options
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="euiAccordion__childWrapper"
|
||||||
|
id="eog_staticId"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="euiSpacer euiSpacer--m"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
Children
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
within the editor group
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
62
src/ui/public/vis/editors/components/editor_options_group.js
Normal file
62
src/ui/public/vis/editors/components/editor_options_group.js
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import './editor_options_group.less';
|
||||||
|
|
||||||
|
import {
|
||||||
|
EuiAccordion,
|
||||||
|
EuiPanel,
|
||||||
|
EuiSpacer,
|
||||||
|
EuiTitle,
|
||||||
|
htmlIdGenerator,
|
||||||
|
} from '@elastic/eui';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A component to group different options in an editor together and give them
|
||||||
|
* a title. Should be used for all visualize editors when grouping options,
|
||||||
|
* to produce an aligned look and feel.
|
||||||
|
*/
|
||||||
|
function EditorOptionsGroup(props) {
|
||||||
|
return (
|
||||||
|
<EuiPanel
|
||||||
|
grow={false}
|
||||||
|
className="editorOptionsGroup__panel"
|
||||||
|
>
|
||||||
|
<EuiAccordion
|
||||||
|
id={htmlIdGenerator('eog')()}
|
||||||
|
initialIsOpen={!props.initialIsCollapsed}
|
||||||
|
extraAction={props.actions}
|
||||||
|
buttonContent={
|
||||||
|
<EuiTitle size="xs">
|
||||||
|
<h2>{props.title}</h2>
|
||||||
|
</EuiTitle>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<EuiSpacer size="m"/>
|
||||||
|
{ props.children }
|
||||||
|
</EuiAccordion>
|
||||||
|
</EuiPanel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorOptionsGroup.propTypes = {
|
||||||
|
/**
|
||||||
|
* The title of this options group, which will be shown with the group.
|
||||||
|
*/
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
/**
|
||||||
|
* Add additional elements as actions to the group.
|
||||||
|
*/
|
||||||
|
actions: PropTypes.node,
|
||||||
|
/**
|
||||||
|
* Whether the panel should be collapsed by default.
|
||||||
|
*/
|
||||||
|
initialIsCollapsed: PropTypes.bool,
|
||||||
|
/**
|
||||||
|
* All elements that should be within this group.
|
||||||
|
*/
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export { EditorOptionsGroup };
|
|
@ -0,0 +1,3 @@
|
||||||
|
.editorOptionsGroup__panel + .editorOptionsGroup__panel {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { render } from 'enzyme';
|
||||||
|
|
||||||
|
import 'test_utils/static_html_id_generator';
|
||||||
|
|
||||||
|
import { EuiButtonIcon } from '@elastic/eui';
|
||||||
|
import { EditorOptionsGroup } from './editor_options_group';
|
||||||
|
|
||||||
|
describe('<EditorOptionsGroup/>', () => {
|
||||||
|
it('renders as expected', () => {
|
||||||
|
const group = render(
|
||||||
|
<EditorOptionsGroup
|
||||||
|
title="Some options"
|
||||||
|
>
|
||||||
|
<span>Children</span>
|
||||||
|
<span>within the editor group</span>
|
||||||
|
</EditorOptionsGroup>
|
||||||
|
);
|
||||||
|
expect(group).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders as expected with actions', () => {
|
||||||
|
const group = render(
|
||||||
|
<EditorOptionsGroup
|
||||||
|
title="Some actions"
|
||||||
|
actions={
|
||||||
|
<EuiButtonIcon
|
||||||
|
iconType="trash"
|
||||||
|
color="text"
|
||||||
|
aria-label="Remove"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span>Some children</span>
|
||||||
|
</EditorOptionsGroup>
|
||||||
|
);
|
||||||
|
expect(group).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders as expected with initial collapsed', () => {
|
||||||
|
const group = render(
|
||||||
|
<EditorOptionsGroup
|
||||||
|
title="Some options"
|
||||||
|
initialIsCollapsed={true}
|
||||||
|
>
|
||||||
|
<span>Children</span>
|
||||||
|
<span>within the editor group</span>
|
||||||
|
</EditorOptionsGroup>
|
||||||
|
);
|
||||||
|
expect(group).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
1
src/ui/public/vis/editors/components/index.js
Normal file
1
src/ui/public/vis/editors/components/index.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { EditorOptionsGroup } from './editor_options_group';
|
1
src/ui/public/vis/editors/index.js
Normal file
1
src/ui/public/vis/editors/index.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { EditorOptionsGroup } from './components';
|
Loading…
Reference in a new issue