[Maps] Change tooltip to use description list for ie compat (#37396)

* Change tooltip to use description list for ie compat

* Remove commented out styles

* Test fixes and review feedback

* Remove unneeded wrapper div on button icon and update tests to reflect class changes

* Add comment explaining why we're setting html explicitly
This commit is contained in:
Aaron Caldwell 2019-05-31 15:26:39 -06:00 committed by GitHub
parent bc8beac750
commit e16842393f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 141 additions and 201 deletions

View file

@ -3,3 +3,4 @@
@import './layer_panel/index'; @import './layer_panel/index';
@import './widget_overlay/index'; @import './widget_overlay/index';
@import './toolbar_overlay/index'; @import './toolbar_overlay/index';
@import './map/feature_tooltip';

View file

@ -2,17 +2,10 @@
exports[`FeatureTooltip should not show close button and not show filter button 1`] = ` exports[`FeatureTooltip should not show close button and not show filter button 1`] = `
<Fragment> <Fragment>
<EuiFlexGroup <EuiDescriptionList
direction="column" listItems={Array []}
gutterSize="none" type="column"
> />
<EuiFlexItem>
<EuiFlexGroup
direction="column"
gutterSize="none"
/>
</EuiFlexItem>
</EuiFlexGroup>
</Fragment> </Fragment>
`; `;
@ -22,65 +15,45 @@ exports[`FeatureTooltip should show both filter buttons and close button 1`] = `
direction="column" direction="column"
gutterSize="none" gutterSize="none"
> >
<EuiFlexGroup <EuiFlexItem
direction="column" grow={true}
gutterSize="none"
> >
<EuiFlexItem
grow={true}
>
<EuiFlexGroup
alignItems="flexEnd"
direction="row"
justifyContent="flexEnd"
>
<EuiFlexItem
grow={false}
>
<EuiButtonIcon
aria-label="Close tooltip"
color="primary"
iconSize="m"
iconType="cross"
onClick={[Function]}
type="button"
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexItem>
<EuiFlexGroup <EuiFlexGroup
direction="column" alignItems="flexEnd"
gutterSize="none" direction="row"
justifyContent="flexEnd"
> >
<EuiFlexGroup <EuiFlexItem
key="0" grow={false}
> >
<EuiFlexItem <EuiButtonIcon
grow={4} aria-label="Close tooltip"
> color="primary"
<strong> iconSize="m"
foo iconType="cross"
</strong> onClick={[Function]}
</EuiFlexItem> type="button"
<EuiFlexItem />
grow={6} </EuiFlexItem>
> </EuiFlexGroup>
<span </EuiFlexItem>
</EuiFlexGroup>
<EuiDescriptionList
listItems={
Array [
Object {
"description": <div>
<div
className="mapFeatureTooltip__lineDescription"
dangerouslySetInnerHTML={ dangerouslySetInnerHTML={
Object { Object {
"__html": "bar", "__html": "bar",
} }
} }
/> />
</EuiFlexItem>
<EuiFlexItem
grow={false}
>
<EuiButtonIcon <EuiButtonIcon
aria-label="Filter on property" aria-label="Filter on property"
className="mapFeatureTooltipFilterButton" className="mapFeatureTooltip__filterButton"
color="primary" color="primary"
iconSize="m" iconSize="m"
iconType="plusInCircle" iconType="plusInCircle"
@ -88,33 +61,26 @@ exports[`FeatureTooltip should show both filter buttons and close button 1`] = `
title="Filter on property" title="Filter on property"
type="button" type="button"
/> />
</EuiFlexItem> </div>,
</EuiFlexGroup> "title": "foo",
<EuiFlexGroup },
key="1" Object {
> "description": <div>
<EuiFlexItem <div
grow={4} className="mapFeatureTooltip__lineDescription"
>
<strong>
foo
</strong>
</EuiFlexItem>
<EuiFlexItem
grow={6}
>
<span
dangerouslySetInnerHTML={ dangerouslySetInnerHTML={
Object { Object {
"__html": "bar", "__html": "bar",
} }
} }
/> />
</EuiFlexItem> </div>,
</EuiFlexGroup> "title": "foo",
</EuiFlexGroup> },
</EuiFlexItem> ]
</EuiFlexGroup> }
type="column"
/>
</Fragment> </Fragment>
`; `;
@ -124,40 +90,33 @@ exports[`FeatureTooltip should show close button, but not filter button 1`] = `
direction="column" direction="column"
gutterSize="none" gutterSize="none"
> >
<EuiFlexGroup <EuiFlexItem
direction="column" grow={true}
gutterSize="none"
> >
<EuiFlexItem
grow={true}
>
<EuiFlexGroup
alignItems="flexEnd"
direction="row"
justifyContent="flexEnd"
>
<EuiFlexItem
grow={false}
>
<EuiButtonIcon
aria-label="Close tooltip"
color="primary"
iconSize="m"
iconType="cross"
onClick={[Function]}
type="button"
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexItem>
<EuiFlexGroup <EuiFlexGroup
direction="column" alignItems="flexEnd"
gutterSize="none" direction="row"
/> justifyContent="flexEnd"
>
<EuiFlexItem
grow={false}
>
<EuiButtonIcon
aria-label="Close tooltip"
color="primary"
iconSize="m"
iconType="cross"
onClick={[Function]}
type="button"
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem> </EuiFlexItem>
</EuiFlexGroup> </EuiFlexGroup>
<EuiDescriptionList
listItems={Array []}
type="column"
/>
</Fragment> </Fragment>
`; `;
@ -176,42 +135,22 @@ exports[`FeatureTooltip should show error message if unable to load tooltip cont
exports[`FeatureTooltip should show only filter button for filterable properties 1`] = ` exports[`FeatureTooltip should show only filter button for filterable properties 1`] = `
<Fragment> <Fragment>
<EuiFlexGroup <EuiDescriptionList
direction="column" listItems={
gutterSize="none" Array [
> Object {
<EuiFlexItem> "description": <div>
<EuiFlexGroup <div
direction="column" className="mapFeatureTooltip__lineDescription"
gutterSize="none"
>
<EuiFlexGroup
key="0"
>
<EuiFlexItem
grow={4}
>
<strong>
foo
</strong>
</EuiFlexItem>
<EuiFlexItem
grow={6}
>
<span
dangerouslySetInnerHTML={ dangerouslySetInnerHTML={
Object { Object {
"__html": "bar", "__html": "bar",
} }
} }
/> />
</EuiFlexItem>
<EuiFlexItem
grow={false}
>
<EuiButtonIcon <EuiButtonIcon
aria-label="Filter on property" aria-label="Filter on property"
className="mapFeatureTooltipFilterButton" className="mapFeatureTooltip__filterButton"
color="primary" color="primary"
iconSize="m" iconSize="m"
iconType="plusInCircle" iconType="plusInCircle"
@ -219,32 +158,25 @@ exports[`FeatureTooltip should show only filter button for filterable properties
title="Filter on property" title="Filter on property"
type="button" type="button"
/> />
</EuiFlexItem> </div>,
</EuiFlexGroup> "title": "foo",
<EuiFlexGroup },
key="1" Object {
> "description": <div>
<EuiFlexItem <div
grow={4} className="mapFeatureTooltip__lineDescription"
>
<strong>
foo
</strong>
</EuiFlexItem>
<EuiFlexItem
grow={6}
>
<span
dangerouslySetInnerHTML={ dangerouslySetInnerHTML={
Object { Object {
"__html": "bar", "__html": "bar",
} }
} }
/> />
</EuiFlexItem> </div>,
</EuiFlexGroup> "title": "foo",
</EuiFlexGroup> },
</EuiFlexItem> ]
</EuiFlexGroup> }
type="column"
/>
</Fragment> </Fragment>
`; `;

View file

@ -0,0 +1,5 @@
.mapFeatureTooltip__filterButton,
.mapFeatureTooltip__lineDescription {
display: inline;
}

View file

@ -5,7 +5,14 @@
*/ */
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiButtonIcon, EuiCallOut, EuiLoadingSpinner } from '@elastic/eui'; import {
EuiFlexGroup,
EuiFlexItem,
EuiButtonIcon,
EuiCallOut,
EuiLoadingSpinner,
EuiDescriptionList
} from '@elastic/eui';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
@ -82,52 +89,51 @@ export class FeatureTooltip extends React.Component {
} }
return ( return (
<EuiFlexItem grow={false}> <EuiButtonIcon
<EuiButtonIcon iconType="plusInCircle"
iconType="plusInCircle" title={i18n.translate('xpack.maps.tooltip.filterOnPropertyTitle', {
title={i18n.translate('xpack.maps.tooltip.filterOnPropertyTitle', { defaultMessage: 'Filter on property'
defaultMessage: 'Filter on property' })}
})} onClick={() => {
onClick={() => { this.props.closeTooltip();
this.props.closeTooltip(); const filterAction = tooltipProperty.getFilterAction();
const filterAction = tooltipProperty.getFilterAction(); filterAction();
filterAction(); }}
}} aria-label={i18n.translate('xpack.maps.tooltip.filterOnPropertyAriaLabel', {
aria-label={i18n.translate('xpack.maps.tooltip.filterOnPropertyAriaLabel', { defaultMessage: 'Filter on property'
defaultMessage: 'Filter on property' })}
})} className="mapFeatureTooltip__filterButton"
className="mapFeatureTooltipFilterButton" />
/>
</EuiFlexItem>
); );
} }
_renderProperties(hasFilters) { _renderProperties(hasFilters) {
return this.state.properties.map((tooltipProperty, index) => { return this.state.properties.map(tooltipProperty => {
/* /*
* Justification for dangerouslySetInnerHTML: * Justification for dangerouslySetInnerHTML:
* Property value contains value generated by Field formatter * Property value contains value generated by Field formatter
* Since these formatters produce raw HTML, this component needs to be able to render them as-is, relying * Since these formatters produce raw HTML, this component needs to be able to render them as-is, relying
* on the field formatter to only produce safe HTML. * on the field formatter to only produce safe HTML.
*/ */
const htmlValue = (<span const htmlValue = (
// eslint-disable-next-line react/no-danger <div>
dangerouslySetInnerHTML={{ <div
__html: tooltipProperty.getHtmlDisplayValue() className="mapFeatureTooltip__lineDescription"
}} // It's necessary to explicitly set the html here as the function
/>); // returns html, not just text
// eslint-disable-next-line react/no-danger
return ( dangerouslySetInnerHTML={{
<EuiFlexGroup key={index}> __html: tooltipProperty.getHtmlDisplayValue()
<EuiFlexItem grow={4}> }}
<strong>{tooltipProperty.getPropertyName()}</strong> />
</EuiFlexItem>
<EuiFlexItem grow={6}>
{htmlValue}
</EuiFlexItem>
{this._renderFilterButton(tooltipProperty, hasFilters)} {this._renderFilterButton(tooltipProperty, hasFilters)}
</EuiFlexGroup> </div>
); );
return ({
title: tooltipProperty.getPropertyName(),
description: htmlValue,
});
}); });
} }
@ -179,16 +185,12 @@ export class FeatureTooltip extends React.Component {
); );
} }
const tooltipProps = this._renderProperties();
return ( return (
<Fragment> <Fragment>
<EuiFlexGroup direction="column" gutterSize="none"> {this._renderCloseButton()}
{this._renderCloseButton()} <EuiDescriptionList type="column" listItems={tooltipProps} />
<EuiFlexItem>
<EuiFlexGroup direction="column" gutterSize="none">
{this._renderProperties()}
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</Fragment> </Fragment>
); );
} }