[Maps] fix tooltip text overlap and text overflow (#38271)

* [Maps] Use table to display tooltip properties

* Design cleanup

- Added dropshadow
- Cleaned SASS
- Removed unnecessary wrappers around close button and centered it
- Change loading state to be centered
- Fixed z-index so tooltip is on top of controls
- Condensed padding/spacing

* Fix overlays in IE

* revert yarn.lock changes
This commit is contained in:
Nathan Reese 2019-06-06 13:57:52 -06:00 committed by GitHub
parent 7d944a78ba
commit 348f10eeaa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 214 additions and 211 deletions

View file

@ -4,12 +4,15 @@
flex-grow: 1;
.mapboxgl-popup {
z-index: 100;
z-index: $euiZLevel2;
border-color: $euiColorEmptyShade;
}
.mapboxgl-popup-content {
@include euiBottomShadow($color: #000);
background-color: $euiColorEmptyShade;
padding: $euiSizeS;
overflow: hidden;
}
.mapboxgl-popup-tip {

View file

@ -2,129 +2,110 @@
exports[`FeatureTooltip should not show close button and not show filter button 1`] = `
<Fragment>
<EuiDescriptionList
listItems={Array []}
type="column"
/>
<table
className="mapFeatureTooltip_table"
>
<tbody />
</table>
</Fragment>
`;
exports[`FeatureTooltip should show both filter buttons and close button 1`] = `
<Fragment>
<EuiFlexGroup
direction="column"
gutterSize="none"
<EuiTextAlign
textAlign="center"
>
<EuiFlexItem
grow={true}
>
<EuiFlexGroup
alignItems="flexEnd"
direction="row"
justifyContent="flexEnd"
<EuiButtonIcon
aria-label="Close tooltip"
color="primary"
iconSize="m"
iconType="cross"
onClick={[Function]}
type="button"
/>
</EuiTextAlign>
<table
className="mapFeatureTooltip_table"
>
<tbody>
<tr
key="foo"
>
<EuiFlexItem
grow={false}
<td
className="eui-textOverflowWrap mapFeatureTooltip__propertyLabel"
>
foo
</td>
<td
className="eui-textOverflowWrap mapFeatureTooltip__propertyValue"
dangerouslySetInnerHTML={
Object {
"__html": "bar",
}
}
/>
<td>
<EuiButtonIcon
aria-label="Close tooltip"
aria-label="Filter on property"
className="mapFeatureTooltip__filterButton"
color="primary"
iconSize="m"
iconType="cross"
iconType="plusInCircle"
onClick={[Function]}
title="Filter on property"
type="button"
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
<EuiDescriptionList
listItems={
Array [
Object {
"description": <div>
<div
className="mapFeatureTooltip__lineDescription"
dangerouslySetInnerHTML={
Object {
"__html": "bar",
}
}
/>
<EuiButtonIcon
aria-label="Filter on property"
className="mapFeatureTooltip__filterButton"
color="primary"
iconSize="m"
iconType="plusInCircle"
onClick={[Function]}
title="Filter on property"
type="button"
/>
</div>,
"title": "foo",
},
Object {
"description": <div>
<div
className="mapFeatureTooltip__lineDescription"
dangerouslySetInnerHTML={
Object {
"__html": "bar",
}
}
/>
</div>,
"title": "foo",
},
]
}
type="column"
/>
</td>
</tr>
<tr
key="foo"
>
<td
className="eui-textOverflowWrap mapFeatureTooltip__propertyLabel"
>
foo
</td>
<td
className="eui-textOverflowWrap mapFeatureTooltip__propertyValue"
dangerouslySetInnerHTML={
Object {
"__html": "bar",
}
}
/>
</tr>
</tbody>
</table>
</Fragment>
`;
exports[`FeatureTooltip should show close button, but not filter button 1`] = `
<Fragment>
<EuiFlexGroup
direction="column"
gutterSize="none"
<EuiTextAlign
textAlign="center"
>
<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>
<EuiDescriptionList
listItems={Array []}
type="column"
/>
<EuiButtonIcon
aria-label="Close tooltip"
color="primary"
iconSize="m"
iconType="cross"
onClick={[Function]}
type="button"
/>
</EuiTextAlign>
<table
className="mapFeatureTooltip_table"
>
<tbody />
</table>
</Fragment>
`;
exports[`FeatureTooltip should show error message if unable to load tooltip content 1`] = `
<EuiCallOut
color="danger"
iconType="cross"
size="m"
iconType="alert"
size="s"
title="Unable to load tooltip content"
>
<p>
@ -135,48 +116,57 @@ exports[`FeatureTooltip should show error message if unable to load tooltip cont
exports[`FeatureTooltip should show only filter button for filterable properties 1`] = `
<Fragment>
<EuiDescriptionList
listItems={
Array [
Object {
"description": <div>
<div
className="mapFeatureTooltip__lineDescription"
dangerouslySetInnerHTML={
Object {
"__html": "bar",
}
}
/>
<EuiButtonIcon
aria-label="Filter on property"
className="mapFeatureTooltip__filterButton"
color="primary"
iconSize="m"
iconType="plusInCircle"
onClick={[Function]}
title="Filter on property"
type="button"
/>
</div>,
"title": "foo",
},
Object {
"description": <div>
<div
className="mapFeatureTooltip__lineDescription"
dangerouslySetInnerHTML={
Object {
"__html": "bar",
}
}
/>
</div>,
"title": "foo",
},
]
}
type="column"
/>
<table
className="mapFeatureTooltip_table"
>
<tbody>
<tr
key="foo"
>
<td
className="eui-textOverflowWrap mapFeatureTooltip__propertyLabel"
>
foo
</td>
<td
className="eui-textOverflowWrap mapFeatureTooltip__propertyValue"
dangerouslySetInnerHTML={
Object {
"__html": "bar",
}
}
/>
<td>
<EuiButtonIcon
aria-label="Filter on property"
className="mapFeatureTooltip__filterButton"
color="primary"
iconSize="m"
iconType="plusInCircle"
onClick={[Function]}
title="Filter on property"
type="button"
/>
</td>
</tr>
<tr
key="foo"
>
<td
className="eui-textOverflowWrap mapFeatureTooltip__propertyLabel"
>
foo
</td>
<td
className="eui-textOverflowWrap mapFeatureTooltip__propertyValue"
dangerouslySetInnerHTML={
Object {
"__html": "bar",
}
}
/>
</tr>
</tbody>
</table>
</Fragment>
`;

View file

@ -1,5 +1,14 @@
.mapFeatureTooltip__filterButton,
.mapFeatureTooltip__lineDescription {
display: inline;
.mapFeatureTooltip_table {
td {
padding: $euiSizeXS;
}
}
.mapFeatureTooltip__propertyLabel {
max-width: $euiSizeXL * 3;
font-weight: $euiFontWeightSemiBold;
}
.mapFeatureTooltip__propertyValue {
max-width: $euiSizeXL * 5;
}

View file

@ -6,12 +6,10 @@
import React, { Fragment } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
EuiButtonIcon,
EuiCallOut,
EuiLoadingSpinner,
EuiDescriptionList
EuiTextAlign,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
@ -83,58 +81,62 @@ export class FeatureTooltip extends React.Component {
}
}
_renderFilterButton(tooltipProperty) {
_renderFilterCell(tooltipProperty) {
if (!this.props.showFilterButtons || !tooltipProperty.isFilterable()) {
return null;
}
return (
<EuiButtonIcon
iconType="plusInCircle"
title={i18n.translate('xpack.maps.tooltip.filterOnPropertyTitle', {
defaultMessage: 'Filter on property'
})}
onClick={() => {
this.props.closeTooltip();
const filterAction = tooltipProperty.getFilterAction();
filterAction();
}}
aria-label={i18n.translate('xpack.maps.tooltip.filterOnPropertyAriaLabel', {
defaultMessage: 'Filter on property'
})}
className="mapFeatureTooltip__filterButton"
/>
<td>
<EuiButtonIcon
className="mapFeatureTooltip__filterButton"
iconType="plusInCircle"
title={i18n.translate('xpack.maps.tooltip.filterOnPropertyTitle', {
defaultMessage: 'Filter on property'
})}
onClick={() => {
this.props.closeTooltip();
const filterAction = tooltipProperty.getFilterAction();
filterAction();
}}
aria-label={i18n.translate('xpack.maps.tooltip.filterOnPropertyAriaLabel', {
defaultMessage: 'Filter on property'
})}
/>
</td>
);
}
_renderProperties(hasFilters) {
return this.state.properties.map(tooltipProperty => {
/*
* Justification for dangerouslySetInnerHTML:
* 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
* on the field formatter to only produce safe HTML.
*/
const htmlValue = (
<div>
<div
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
dangerouslySetInnerHTML={{
__html: tooltipProperty.getHtmlDisplayValue()
}}
_renderProperties() {
const rows = this.state.properties.map(tooltipProperty => {
const label = tooltipProperty.getPropertyName();
return (
<tr key={label}>
<td className="eui-textOverflowWrap mapFeatureTooltip__propertyLabel">
{label}
</td>
<td
className="eui-textOverflowWrap mapFeatureTooltip__propertyValue"
/*
* Justification for dangerouslySetInnerHTML:
* 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
* on the field formatter to only produce safe HTML.
*/
dangerouslySetInnerHTML={{ __html: tooltipProperty.getHtmlDisplayValue() }} //eslint-disable-line react/no-danger
/>
{this._renderFilterButton(tooltipProperty, hasFilters)}
</div>
{this._renderFilterCell(tooltipProperty)}
</tr>
);
return ({
title: tooltipProperty.getPropertyName(),
description: htmlValue,
});
});
return (
<table className="mapFeatureTooltip_table">
<tbody>
{rows}
</tbody>
</table>
);
}
_renderCloseButton() {
@ -142,30 +144,28 @@ export class FeatureTooltip extends React.Component {
return null;
}
return (
<EuiFlexGroup direction="column" gutterSize="none">
<EuiFlexItem grow={true}>
<EuiFlexGroup alignItems="flexEnd" direction="row" justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiButtonIcon
onClick={this.props.closeTooltip}
iconType="cross"
aria-label={i18n.translate('xpack.maps.tooltip.closeAriaLabel', {
defaultMessage: 'Close tooltip'
})}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
<EuiTextAlign textAlign="center">
<EuiButtonIcon
onClick={this.props.closeTooltip}
iconType="cross"
aria-label={i18n.translate('xpack.maps.tooltip.closeAriaLabel', {
defaultMessage: 'Close tooltip'
})}
/>
</EuiTextAlign>
);
}
render() {
if (!this.state.properties) {
const loadingMsg = i18n.translate('xpack.maps.tooltip.loadingMsg', {
defaultMessage: 'Loading'
});
return (
<div>
<EuiLoadingSpinner size="m" /> {' loading content'}
</div>
<EuiTextAlign textAlign="center">
<EuiLoadingSpinner size="m" />
{loadingMsg}
</EuiTextAlign>
);
}
@ -176,7 +176,8 @@ export class FeatureTooltip extends React.Component {
defaultMessage: 'Unable to load tooltip content'
})}
color="danger"
iconType="cross"
iconType="alert"
size="s"
>
<p>
{this.state.loadPropertiesErrorMsg}
@ -185,12 +186,10 @@ export class FeatureTooltip extends React.Component {
);
}
const tooltipProps = this._renderProperties();
return (
<Fragment>
{this._renderCloseButton()}
<EuiDescriptionList type="column" listItems={tooltipProps} />
{this._renderProperties()}
</Fragment>
);
}

View file

@ -10,6 +10,7 @@
top: $euiSizeM;
right: $euiSizeM;
bottom: $euiSizeM;
left: 0; // Necessary to have a left value for IE
pointer-events: none; /* 1 */
}

View file

@ -1,5 +1,6 @@
.mapAttributionControl {
@include mapOverlayIsTextOnly;
@include euiTextOverflowWrap;
pointer-events: all;
padding-left: $euiSizeM;
}