mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[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:
parent
7d944a78ba
commit
348f10eeaa
6 changed files with 214 additions and 211 deletions
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
top: $euiSizeM;
|
||||
right: $euiSizeM;
|
||||
bottom: $euiSizeM;
|
||||
left: 0; // Necessary to have a left value for IE
|
||||
pointer-events: none; /* 1 */
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
.mapAttributionControl {
|
||||
@include mapOverlayIsTextOnly;
|
||||
@include euiTextOverflowWrap;
|
||||
pointer-events: all;
|
||||
padding-left: $euiSizeM;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue