[Infra UI] Change waffle map node to button for accessibility (#31764)
* Fixes #28158 - Change waffle map node to button for accessibility * intl-izing the aria-labels; changing size to eui
This commit is contained in:
parent
f89faec278
commit
32dbb82bf8
|
@ -10,6 +10,7 @@ import { darken, readableColor } from 'polished';
|
|||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import { InfraNodeType } from '../../../server/lib/adapters/nodes';
|
||||
import { InfraTimerangeInput } from '../../graphql/types';
|
||||
import { InfraWaffleMapBounds, InfraWaffleMapNode, InfraWaffleMapOptions } from '../../lib/lib';
|
||||
|
@ -30,71 +31,90 @@ interface Props {
|
|||
bounds: InfraWaffleMapBounds;
|
||||
nodeType: InfraNodeType;
|
||||
timeRange: InfraTimerangeInput;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
export class Node extends React.PureComponent<Props, State> {
|
||||
public readonly state: State = initialState;
|
||||
public render() {
|
||||
const { nodeType, node, options, squareSize, bounds, formatter, timeRange } = this.props;
|
||||
const { isPopoverOpen } = this.state;
|
||||
const { metric } = node;
|
||||
const valueMode = squareSize > 70;
|
||||
const ellipsisMode = squareSize > 30;
|
||||
const rawValue = (metric && metric.value) || 0;
|
||||
const color = colorFromValue(options.legend, rawValue, bounds);
|
||||
const value = formatter(rawValue);
|
||||
const newTimerange = {
|
||||
...timeRange,
|
||||
from: moment(timeRange.to)
|
||||
.subtract(1, 'hour')
|
||||
.valueOf(),
|
||||
};
|
||||
return (
|
||||
<NodeContextMenu
|
||||
node={node}
|
||||
nodeType={nodeType}
|
||||
isPopoverOpen={isPopoverOpen}
|
||||
closePopover={this.closePopover}
|
||||
options={options}
|
||||
timeRange={newTimerange}
|
||||
>
|
||||
<EuiToolTip position="top" content={`${node.name} | ${value}`}>
|
||||
<NodeContainer
|
||||
style={{ width: squareSize || 0, height: squareSize || 0 }}
|
||||
onClick={this.togglePopover}
|
||||
>
|
||||
<SquareOuter color={color}>
|
||||
<SquareInner color={color}>
|
||||
{valueMode ? (
|
||||
<ValueInner>
|
||||
<Label color={color}>{node.name}</Label>
|
||||
<Value color={color}>{value}</Value>
|
||||
</ValueInner>
|
||||
) : (
|
||||
ellipsisMode && (
|
||||
<ValueInner>
|
||||
<Label color={color}>...</Label>
|
||||
export const Node = injectI18n(
|
||||
class extends React.PureComponent<Props, State> {
|
||||
public readonly state: State = initialState;
|
||||
public render() {
|
||||
const {
|
||||
nodeType,
|
||||
node,
|
||||
options,
|
||||
squareSize,
|
||||
bounds,
|
||||
formatter,
|
||||
timeRange,
|
||||
intl,
|
||||
} = this.props;
|
||||
const { isPopoverOpen } = this.state;
|
||||
const { metric } = node;
|
||||
const valueMode = squareSize > 70;
|
||||
const ellipsisMode = squareSize > 30;
|
||||
const rawValue = (metric && metric.value) || 0;
|
||||
const color = colorFromValue(options.legend, rawValue, bounds);
|
||||
const value = formatter(rawValue);
|
||||
const newTimerange = {
|
||||
...timeRange,
|
||||
from: moment(timeRange.to)
|
||||
.subtract(1, 'hour')
|
||||
.valueOf(),
|
||||
};
|
||||
const nodeAriaLabel = intl.formatMessage(
|
||||
{
|
||||
id: 'xpack.infra.node.ariaLabel',
|
||||
defaultMessage: '{nodeName}, click to open menu',
|
||||
},
|
||||
{ nodeName: node.name }
|
||||
);
|
||||
return (
|
||||
<NodeContextMenu
|
||||
node={node}
|
||||
nodeType={nodeType}
|
||||
isPopoverOpen={isPopoverOpen}
|
||||
closePopover={this.closePopover}
|
||||
options={options}
|
||||
timeRange={newTimerange}
|
||||
>
|
||||
<EuiToolTip position="top" content={`${node.name} | ${value}`}>
|
||||
<NodeContainer
|
||||
style={{ width: squareSize || 0, height: squareSize || 0 }}
|
||||
onClick={this.togglePopover}
|
||||
>
|
||||
<SquareOuter color={color}>
|
||||
<SquareInner color={color}>
|
||||
{valueMode ? (
|
||||
<ValueInner aria-label={nodeAriaLabel}>
|
||||
<Label color={color}>{node.name}</Label>
|
||||
<Value color={color}>{value}</Value>
|
||||
</ValueInner>
|
||||
)
|
||||
)}
|
||||
</SquareInner>
|
||||
</SquareOuter>
|
||||
</NodeContainer>
|
||||
</EuiToolTip>
|
||||
</NodeContextMenu>
|
||||
);
|
||||
}
|
||||
|
||||
private togglePopover = () => {
|
||||
this.setState(prevState => ({ isPopoverOpen: !prevState.isPopoverOpen }));
|
||||
};
|
||||
|
||||
private closePopover = () => {
|
||||
if (this.state.isPopoverOpen) {
|
||||
this.setState({ isPopoverOpen: false });
|
||||
) : (
|
||||
ellipsisMode && (
|
||||
<ValueInner aria-label={nodeAriaLabel}>
|
||||
<Label color={color}>...</Label>
|
||||
</ValueInner>
|
||||
)
|
||||
)}
|
||||
</SquareInner>
|
||||
</SquareOuter>
|
||||
</NodeContainer>
|
||||
</EuiToolTip>
|
||||
</NodeContextMenu>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private togglePopover = () => {
|
||||
this.setState(prevState => ({ isPopoverOpen: !prevState.isPopoverOpen }));
|
||||
};
|
||||
|
||||
private closePopover = () => {
|
||||
if (this.state.isPopoverOpen) {
|
||||
this.setState({ isPopoverOpen: false });
|
||||
}
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
const NodeContainer = styled.div`
|
||||
position: relative;
|
||||
|
@ -126,7 +146,7 @@ const SquareInner = styled<ColorProps, 'div'>('div')`
|
|||
background-color: ${props => props.color};
|
||||
`;
|
||||
|
||||
const ValueInner = styled.div`
|
||||
const ValueInner = styled.button`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
@ -139,6 +159,14 @@ const ValueInner = styled.div`
|
|||
padding: 1em;
|
||||
overflow: hidden;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
border: none;
|
||||
&:focus {
|
||||
outline: none !important;
|
||||
border: ${params => params.theme.eui.euiFocusRingSize} solid
|
||||
${params => params.theme.eui.euiFocusRingColor};
|
||||
box-shadow: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const Value = styled<ColorProps, 'div'>('div')`
|
||||
|
|
Loading…
Reference in a new issue