hide tooltip when blured

fixes #385
This commit is contained in:
Sérgio Ramos 2017-03-22 16:50:21 +00:00 committed by Judit Greskovits
parent 58d786c099
commit faabc8b6d8
8 changed files with 98 additions and 92 deletions

View File

@ -78,22 +78,18 @@ const arrowPosition = {
const Header = ({ const Header = ({
account, account,
handleToggle, onHeaderToggle,
tooltip, tooltip,
...props ...props
}) => { }) => {
const handleToggleClick = (ev) => { const handleHeaderToggle = (ev) => {
ev.preventDefault(); ev.preventDefault();
handleToggle(!tooltip); onHeaderToggle();
};
const handleHideToggle = (ev) => {
ev.preventDefault();
handleToggle(false);
}; };
const tooltipComponent = !tooltip ? null : ( const tooltipComponent = !tooltip ? null : (
<Tooltip <Tooltip
onBlur={handleHeaderToggle}
arrowPosition={arrowPosition} arrowPosition={arrowPosition}
right={0} right={0}
top={39} top={39}
@ -111,12 +107,7 @@ const Header = ({
); );
return ( return (
<StyledHeader <StyledHeader name='application-header' {...props}>
name='application-header'
onBlur={handleHideToggle}
onFocus={handleHideToggle}
{...props}
>
<Row> <Row>
<Column lg={10} xs={8}> <Column lg={10} xs={8}>
<Link to='/'> <Link to='/'>
@ -126,7 +117,7 @@ const Header = ({
<Column lg={2} xs={4}> <Column lg={2} xs={4}>
<StyledProfileWrapper> <StyledProfileWrapper>
<StyledAvatarWrapper toggled={tooltip}> <StyledAvatarWrapper toggled={tooltip}>
<EmptyButton onClick={handleToggleClick}> <EmptyButton onClick={handleHeaderToggle}>
<StyledName> <StyledName>
{account.name} {account.name}
</StyledName> </StyledName>
@ -147,7 +138,7 @@ const Header = ({
Header.propTypes = { Header.propTypes = {
account: PropTypes.account, account: PropTypes.account,
handleToggle: React.PropTypes.func, onHeaderToggle: React.PropTypes.func,
tooltip: React.PropTypes.bool tooltip: React.PropTypes.bool
}; };

View File

@ -1,41 +1,41 @@
import React from 'react'; import React from 'react';
import Tooltip, { TooltipButton, TooltipDivider } from '@ui/components/tooltip'; import Tooltip, { TooltipButton, TooltipDivider } from '@ui/components/tooltip';
// eslint-disable-next-line max-len
const scaleLink = 'https://projects.invisionapp.com/share/YDAKI8CW4#/screens/221841542_Deployed_Services_1-8';
const ServicesTooltip = ({ const ServicesTooltip = ({
show, show,
position position,
}) => { ...rest
// eslint-disable-next-line max-len }) => show ? (
const scaleLink = 'https://projects.invisionapp.com/share/YDAKI8CW4#/screens/221841542_Deployed_Services_1-8'; <Tooltip {...position} {...rest}>
return show ? ( <li>
<Tooltip {...position}> <TooltipButton href={scaleLink}>
<li> Scale
<TooltipButton href={scaleLink}> </TooltipButton>
Scale </li>
</TooltipButton> <li>
</li> <TooltipButton>Rollback</TooltipButton>
<li> </li>
<TooltipButton>Rollback</TooltipButton> <li>
</li> <TooltipButton>Reprovision</TooltipButton>
<li> </li>
<TooltipButton>Reprovision</TooltipButton> <li>
</li> <TooltipButton>Transfer</TooltipButton>
<li> </li>
<TooltipButton>Transfer</TooltipButton> <li>
</li> <TooltipButton>Setup metrics</TooltipButton>
<li> </li>
<TooltipButton>Setup metrics</TooltipButton> <TooltipDivider />
</li> <li>
<TooltipDivider /> <TooltipButton>Stop</TooltipButton>
<li> </li>
<TooltipButton>Stop</TooltipButton> <li>
</li> <TooltipButton>Delete</TooltipButton>
<li> </li>
<TooltipButton>Delete</TooltipButton> </Tooltip>
</li> ) : null;
</Tooltip>
) : null;
};
ServicesTooltip.propTypes = { ServicesTooltip.propTypes = {
position: React.PropTypes.object, position: React.PropTypes.object,

View File

@ -5,15 +5,10 @@ import Row from '@ui/components/row';
import Column from '@ui/components/column'; import Column from '@ui/components/column';
import { LayoutContainer } from '@components/layout'; import { LayoutContainer } from '@components/layout';
import { H2 } from '@ui/components/base-elements'; import { H2 } from '@ui/components/base-elements';
import { import { FormGroup, Toggle, ToggleList, Legend } from '@ui/components/form';
FormGroup,
Toggle,
ToggleList,
Legend
} from '@ui/components/form';
import TopologyFilter from '@components/services/topology-filter'; import TopologyFilter from '@components/services/topology-filter';
import styled from 'styled-components';
import { unitcalc, remcalc } from '@ui/shared/functions'; import { unitcalc, remcalc } from '@ui/shared/functions';
import styled from 'styled-components';
const StyledLegend = styled(Legend)` const StyledLegend = styled(Legend)`
float: left; float: left;
@ -37,6 +32,7 @@ const ServicesView = ({
evt.preventDefault(); evt.preventDefault();
const value = evt.target.value; const value = evt.target.value;
if(value !== toggleValue) { if(value !== toggleValue) {
onToggle(value); onToggle(value);
} }

View File

@ -10,7 +10,7 @@ const mapStateToProps = (state, ownProps) => ({
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
handleToggle: (bool) => dispatch(toggleHeaderTooltip(bool)) onHeaderToggle: (bool) => dispatch(toggleHeaderTooltip(bool))
}); });
export default connect( export default connect(

View File

@ -25,7 +25,6 @@ const duration = '1 hour';
const interval = '2 minutes'; const interval = '2 minutes';
class Services extends React.Component { class Services extends React.Component {
// we DON'T want to unsubscribe once we started going // we DON'T want to unsubscribe once we started going
componentWillMount() { componentWillMount() {
this.props.subscribeMetric(interval); this.props.subscribeMetric(interval);
@ -66,7 +65,7 @@ class Services extends React.Component {
}); });
}; };
const instances = null; const handleTooltipBlur = (evt) => onQuickActions(evt, uiTooltip.service);
const serviceList = services.map((service) => ( const serviceList = services.map((service) => (
<ServiceItem <ServiceItem
@ -79,13 +78,19 @@ class Services extends React.Component {
/> />
)); ));
// TODO replace `false` with a check for existence unmanaged instances
// eslint-disable-next-line no-constant-condition
const unmanagedInstances = false ? (
<UnmanagedInstances instances={0} />
) : null;
return ( return (
<LayoutContainer> <LayoutContainer>
{ instances && <UnmanagedInstances instances={instances} /> } {unmanagedInstances}
<StyledContainer> <StyledContainer>
<div ref={this.ref('container')}> <div ref={this.ref('container')}>
{serviceList} {serviceList}
<ServicesTooltip {...uiTooltip} /> <ServicesTooltip {...uiTooltip} onBlur={handleTooltipBlur} />
</div> </div>
</StyledContainer> </StyledContainer>
</LayoutContainer> </LayoutContainer>

View File

@ -6,7 +6,7 @@ export default handleActions({
...state, ...state,
ui: { ui: {
...state.ui, ...state.ui,
tooltip: action.payload tooltip: !state.ui.tooltip
} }
}) })
}, {}); }, {});

View File

@ -48,13 +48,13 @@ export default handleActions({
) )
}), }),
[toggleTooltip.toString()]: (state, action) => { [toggleTooltip.toString()]: (state, action) => {
const { const {
position, position,
service service
} = action.payload; } = action.payload;
const show = state.ui.tooltip.service !== service; const show = state.ui.tooltip.service !== service;
const tooltip = show ? { const tooltip = show ? {
show: true, show: true,
position: { position: {

View File

@ -1,7 +1,7 @@
import { remcalc, unitcalc } from '../../shared/functions'; import { remcalc, unitcalc } from '../../shared/functions';
import { boxes, colors } from '../../shared/constants'; import { boxes, colors } from '../../shared/constants';
import styled from 'styled-components'; import styled from 'styled-components';
import React from 'react'; import React, { Component } from 'react';
import { import {
absolutePosition, absolutePosition,
@ -12,12 +12,12 @@ import {
getMeasurement getMeasurement
} from '../../shared/composers'; } from '../../shared/composers';
const ItemPadder = 9;
const WrapperPadder = 24;
const StyledContainer = styled.div` const StyledContainer = styled.div`
${(props) => absolutePosition(props)} ${(props) => absolutePosition(props)}
&:focus {
outline: none;
}
`; `;
const StyledList = styled.ul` const StyledList = styled.ul`
@ -29,7 +29,6 @@ const StyledList = styled.ul`
list-style-type: none; list-style-type: none;
margin: 0; margin: 0;
padding: ${unitcalc(2)} 0; padding: ${unitcalc(2)} 0;
/*min-width: ${remcalc(200)};*/
position: absolute; position: absolute;
top: ${remcalc(4)}; top: ${remcalc(4)};
@ -42,6 +41,7 @@ const StyledList = styled.ul`
}}; }};
${props => props.styles} ${props => props.styles}
${baseBox({ ${baseBox({
shadow: boxes.tooltipShadow shadow: boxes.tooltipShadow
})} })}
@ -50,15 +50,6 @@ const StyledList = styled.ul`
amount: 1 amount: 1
})} })}
/*& > * {
padding: ${remcalc(ItemPadder)} ${remcalc(WrapperPadder)};
&:hover {
background: ${colors.base.grey};
}
}*/
&:after, &:before { &:after, &:before {
border: solid transparent; border: solid transparent;
height: 0; height: 0;
@ -73,6 +64,7 @@ const StyledList = styled.ul`
border-width: ${remcalc(3)}; border-width: ${remcalc(3)};
margin-left: ${remcalc(-3)}; margin-left: ${remcalc(-3)};
} }
&:before { &:before {
border-color: rgba(216, 216, 216, 0); border-color: rgba(216, 216, 216, 0);
border-bottom-color: ${colors.base.grey}; border-bottom-color: ${colors.base.grey};
@ -81,20 +73,42 @@ const StyledList = styled.ul`
} }
`; `;
const Tooltip = ({ class Tooltip extends Component {
children, componentDidMount() {
arrowPosition = { this._refs.ul.focus();
bottom: '100%', }
left: '50%'
}, ref(name) {
...props this._refs = this._refs || {};
}) => (
<StyledContainer {...props}> return (el) => {
<StyledList arrowPosition={arrowPosition} {...props}> this._refs[name] = el;
{children} };
</StyledList> }
</StyledContainer>
); render() {
const {
children,
arrowPosition = {
bottom: '100%',
left: '50%'
},
...rest
} = this.props;
return (
<StyledContainer
innerRef={this.ref('ul')}
tabIndex={-1}
{...rest}
>
<StyledList arrowPosition={arrowPosition} {...rest}>
{children}
</StyledList>
</StyledContainer>
);
}
}
Tooltip.propTypes = { Tooltip.propTypes = {
arrowPosition: React.PropTypes.object, arrowPosition: React.PropTypes.object,