Tooltips with react-intl (#4549)
* Tooltips support intl strings * FormattedMessage for strings to Tooltip * Fix TabBar tooltip display * r after o (PR comment)
This commit is contained in:
parent
812017f9b3
commit
efe76d7004
@ -15,12 +15,13 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { FlatButton } from 'material-ui';
|
||||
import ActionDoneAll from 'material-ui/svg-icons/action/done-all';
|
||||
import ContentClear from 'material-ui/svg-icons/content/clear';
|
||||
import NavigationArrowForward from 'material-ui/svg-icons/navigation/arrow-forward';
|
||||
|
||||
import { CancelIcon, DoneIcon, NextIcon } from '~/ui/Icons';
|
||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||
|
||||
import { newTooltip, nextTooltip, closeTooltips } from '../actions';
|
||||
|
||||
@ -30,15 +31,15 @@ let tooltipId = 0;
|
||||
|
||||
class Tooltip extends Component {
|
||||
static propTypes = {
|
||||
title: PropTypes.string,
|
||||
text: PropTypes.string,
|
||||
right: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
currentId: PropTypes.number,
|
||||
maxId: PropTypes.number,
|
||||
className: PropTypes.string,
|
||||
onNewTooltip: PropTypes.func,
|
||||
onNextTooltip: PropTypes.func,
|
||||
onCloseTooltips: PropTypes.func
|
||||
onCloseTooltips: PropTypes.func,
|
||||
right: PropTypes.bool,
|
||||
text: nodeOrStringProptype(),
|
||||
title: nodeOrStringProptype()
|
||||
}
|
||||
|
||||
state = {
|
||||
@ -54,8 +55,7 @@ class Tooltip extends Component {
|
||||
|
||||
render () {
|
||||
const { id } = this.state;
|
||||
const { className, currentId, maxId, right, onCloseTooltips, onNextTooltip } = this.props;
|
||||
const classes = `${styles.box} ${right ? styles.arrowRight : styles.arrowLeft} ${className}`;
|
||||
const { className, currentId, maxId, right, onCloseTooltips, onNextTooltip, text, title } = this.props;
|
||||
|
||||
if (id !== currentId) {
|
||||
return null;
|
||||
@ -64,32 +64,57 @@ class Tooltip extends Component {
|
||||
const buttons = id !== maxId
|
||||
? [
|
||||
<FlatButton
|
||||
icon={ <CancelIcon /> }
|
||||
key='skipButton'
|
||||
icon={ <ContentClear /> }
|
||||
label='Skip'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='ui.tooltips.button.skip'
|
||||
defaultMessage='Skip'
|
||||
/>
|
||||
}
|
||||
onTouchTap={ onCloseTooltips }
|
||||
/>,
|
||||
<FlatButton
|
||||
icon={ <NextIcon /> }
|
||||
key='nextButton'
|
||||
icon={ <NavigationArrowForward /> }
|
||||
label='Next'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='ui.tooltips.button.next'
|
||||
defaultMessage='Next'
|
||||
/>
|
||||
}
|
||||
onTouchTap={ onNextTooltip }
|
||||
/>
|
||||
] : (
|
||||
<FlatButton
|
||||
icon={ <ActionDoneAll /> }
|
||||
label='Done'
|
||||
icon={ <DoneIcon /> }
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='ui.tooltips.button.done'
|
||||
defaultMessage='Done'
|
||||
/>
|
||||
}
|
||||
onTouchTap={ onCloseTooltips }
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={ classes }>
|
||||
<div
|
||||
className={
|
||||
[
|
||||
styles.box,
|
||||
right
|
||||
? styles.arrowRight
|
||||
: styles.arrowLeft,
|
||||
className
|
||||
].join(' ')
|
||||
}
|
||||
>
|
||||
<div className={ styles.title }>
|
||||
{ this.props.title }
|
||||
{ title }
|
||||
</div>
|
||||
<div className={ styles.text }>
|
||||
{ this.props.text }
|
||||
{ text }
|
||||
</div>
|
||||
<div className={ styles.buttons }>
|
||||
{ buttons }
|
||||
@ -102,7 +127,10 @@ class Tooltip extends Component {
|
||||
function mapStateToProps (state) {
|
||||
const { currentId, maxId } = state.tooltip;
|
||||
|
||||
return { currentId, maxId };
|
||||
return {
|
||||
currentId,
|
||||
maxId
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
|
68
js/src/ui/Tooltips/Tooltip/tooltip.spec.js
Normal file
68
js/src/ui/Tooltips/Tooltip/tooltip.spec.js
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import Tooltip from './';
|
||||
|
||||
let component;
|
||||
let store;
|
||||
|
||||
function createRedux (currentId = 0) {
|
||||
store = {
|
||||
dispatch: sinon.stub(),
|
||||
subscribe: sinon.stub(),
|
||||
getState: () => {
|
||||
return {
|
||||
tooltip: {
|
||||
currentId,
|
||||
maxId: 2
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
function render () {
|
||||
component = shallow(
|
||||
<Tooltip />,
|
||||
{
|
||||
context: {
|
||||
store: createRedux()
|
||||
}
|
||||
}
|
||||
).find('Tooltip').shallow();
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('ui/Tooltips/Tooltip', () => {
|
||||
beforeEach(() => {
|
||||
render();
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component.get(0)).to.be.ok;
|
||||
});
|
||||
|
||||
it('renders null when id !== currentId', () => {
|
||||
expect(render(1).get(0)).to.be.null;
|
||||
});
|
||||
});
|
@ -14,8 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import Tooltip from './Tooltip';
|
||||
import tooltipReducer from './reducers';
|
||||
|
||||
export default from './tooltips';
|
||||
export { Tooltip, tooltipReducer };
|
||||
|
||||
export Tooltip from './Tooltip';
|
||||
export tooltipReducer from './reducers';
|
||||
|
@ -29,7 +29,6 @@ class Tooltips extends Component {
|
||||
|
||||
static propTypes = {
|
||||
currentId: PropTypes.number,
|
||||
closed: PropTypes.bool,
|
||||
onNextTooltip: PropTypes.func
|
||||
}
|
||||
|
||||
@ -72,7 +71,9 @@ class Tooltips extends Component {
|
||||
function mapStateToProps (state) {
|
||||
const { currentId } = state.tooltip;
|
||||
|
||||
return { currentId };
|
||||
return {
|
||||
currentId
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
|
76
js/src/ui/Tooltips/tooltips.spec.js
Normal file
76
js/src/ui/Tooltips/tooltips.spec.js
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import Tooltips from './';
|
||||
|
||||
let component;
|
||||
let router;
|
||||
let store;
|
||||
|
||||
function createRedux () {
|
||||
store = {
|
||||
dispatch: sinon.stub(),
|
||||
subscribe: sinon.stub(),
|
||||
getState: () => {
|
||||
return {
|
||||
tooltip: {
|
||||
currentId: 1
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
function createRouter () {
|
||||
router = {
|
||||
push: sinon.stub()
|
||||
};
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
function render () {
|
||||
component = shallow(
|
||||
<Tooltips />,
|
||||
{
|
||||
context: {
|
||||
store: createRedux()
|
||||
}
|
||||
}
|
||||
).find('Tooltips').shallow({
|
||||
context: {
|
||||
router: createRouter()
|
||||
}
|
||||
});
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('ui/Tooltips', () => {
|
||||
beforeEach(() => {
|
||||
render();
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component.get(0)).to.be.ok;
|
||||
});
|
||||
});
|
@ -15,6 +15,7 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import ContentAdd from 'material-ui/svg-icons/content/add';
|
||||
@ -88,7 +89,12 @@ class Accounts extends Component {
|
||||
<Page>
|
||||
<Tooltip
|
||||
className={ styles.accountTooltip }
|
||||
text='your accounts are visible for easy access, allowing you to edit the meta information, make transfers, view transactions and fund the account'
|
||||
text={
|
||||
<FormattedMessage
|
||||
id='accounts.tooltip.overview'
|
||||
defaultMessage='your accounts are visible for easy access, allowing you to edit the meta information, make transfers, view transactions and fund the account'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
{ this.renderWallets() }
|
||||
@ -228,7 +234,12 @@ class Accounts extends Component {
|
||||
<Tooltip
|
||||
className={ styles.toolbarTooltip }
|
||||
right
|
||||
text='actions relating to the current view are available on the toolbar for quick access, be it for performing actions or creating a new item'
|
||||
text={
|
||||
<FormattedMessage
|
||||
id='accounts.tooltip.actions'
|
||||
defaultMessage='actions relating to the current view are available on the toolbar for quick access, be it for performing actions or creating a new item'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Actionbar>
|
||||
);
|
||||
|
@ -26,13 +26,12 @@ const SIGNER_ID = 'signer';
|
||||
|
||||
export default class Tab extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node,
|
||||
pendings: PropTypes.number,
|
||||
view: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
render () {
|
||||
const { view, children } = this.props;
|
||||
const { view } = this.props;
|
||||
|
||||
return (
|
||||
<MUITab
|
||||
@ -42,9 +41,7 @@ export default class Tab extends Component {
|
||||
? this.renderSignerLabel()
|
||||
: this.renderLabel(view.id)
|
||||
}
|
||||
>
|
||||
{ children }
|
||||
</MUITab>
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ let instance;
|
||||
function render (id = 'signer') {
|
||||
component = shallow(
|
||||
<Tab
|
||||
children={ <div>testChildren</div> }
|
||||
pending={ 5 }
|
||||
view={ { id } }
|
||||
/>
|
||||
|
@ -60,8 +60,8 @@
|
||||
}
|
||||
|
||||
.tabbarTooltip {
|
||||
left: 3.3em;
|
||||
top: 0.5em;
|
||||
left: 3em;
|
||||
top: 4em;
|
||||
}
|
||||
|
||||
.label {
|
||||
|
@ -15,6 +15,7 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import { Link } from 'react-router';
|
||||
import { Toolbar, ToolbarGroup } from 'material-ui/Toolbar';
|
||||
@ -49,6 +50,15 @@ class TabBar extends Component {
|
||||
</ToolbarGroup>
|
||||
<div className={ styles.tabs }>
|
||||
{ this.renderTabItems() }
|
||||
<Tooltip
|
||||
className={ styles.tabbarTooltip }
|
||||
text={
|
||||
<FormattedMessage
|
||||
id='tabBar.tooltip.overview'
|
||||
defaultMessage='navigate between the different parts and views of the application, switching between an account view, token view and distributed application view'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<ToolbarGroup className={ styles.last }>
|
||||
<div />
|
||||
@ -61,15 +71,6 @@ class TabBar extends Component {
|
||||
const { views, pending } = this.props;
|
||||
|
||||
return views.map((view, index) => {
|
||||
const body = (view.id === 'accounts')
|
||||
? (
|
||||
<Tooltip
|
||||
className={ styles.tabbarTooltip }
|
||||
text='navigate between the different parts and views of the application, switching between an account view, token view and distributed application view'
|
||||
/>
|
||||
)
|
||||
: null;
|
||||
|
||||
return (
|
||||
<Link
|
||||
activeClassName={ styles.tabactive }
|
||||
@ -80,9 +81,7 @@ class TabBar extends Component {
|
||||
<Tab
|
||||
pendings={ pending.length }
|
||||
view={ view }
|
||||
>
|
||||
{ body }
|
||||
</Tab>
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user