From a2e756e9b7b48bada6fe84b2af34db7859b925a8 Mon Sep 17 00:00:00 2001 From: meriadec Date: Wed, 14 Mar 2018 11:31:07 +0100 Subject: [PATCH 1/3] Prevent NaN on BalanceInfos --- src/components/BalanceSummary/BalanceInfos.js | 2 +- src/components/BalanceSummary/stories.js | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/components/BalanceSummary/stories.js diff --git a/src/components/BalanceSummary/BalanceInfos.js b/src/components/BalanceSummary/BalanceInfos.js index f2adaa67..8b3ad174 100644 --- a/src/components/BalanceSummary/BalanceInfos.js +++ b/src/components/BalanceSummary/BalanceInfos.js @@ -43,7 +43,7 @@ export function BalanceSincePercent(props: BalanceSinceProps) { diff --git a/src/components/BalanceSummary/stories.js b/src/components/BalanceSummary/stories.js new file mode 100644 index 00000000..fbcbfc9a --- /dev/null +++ b/src/components/BalanceSummary/stories.js @@ -0,0 +1,22 @@ +// @flow + +import React from 'react' +import { storiesOf } from '@storybook/react' +import { number } from '@storybook/addon-knobs' +import { translate } from 'react-i18next' + +import BalanceInfos from './BalanceInfos' + +const stories = storiesOf('Components', module) + +const BalanceInfosComp = translate()(BalanceInfos) + +stories.add('BalanceInfos', () => ( + +)) From f0dc41c952891527c0d3e9be64dd4385590349b2 Mon Sep 17 00:00:00 2001 From: meriadec Date: Wed, 14 Mar 2018 11:42:45 +0100 Subject: [PATCH 2/3] Flatten storybook --- src/components/Breadcrumb/stories.js | 4 +- src/components/RecipientAddress/stories.js | 4 +- src/components/SelectAccount/stories.js | 4 +- src/components/TransactionsList/stories.js | 4 +- src/components/base/Bar/stories.js | 4 +- src/components/base/Button/stories.js | 4 +- src/components/base/CheckBox/stories.js | 4 +- src/components/base/GrowScroll/stories.js | 4 +- src/components/base/Input/stories.js | 4 +- src/components/base/Modal/stories.js | 4 +- src/components/base/NewChart/stories.js | 4 +- src/components/base/Pills/stories.js | 4 +- src/components/base/QRCode/stories.js | 4 +- src/components/base/Radio/stories.js | 4 +- src/components/base/Search/stories.js | 79 ---------------------- src/components/base/Tabs/stories.js | 4 +- src/components/base/Tooltip/stories.js | 4 +- 17 files changed, 32 insertions(+), 111 deletions(-) delete mode 100644 src/components/base/Search/stories.js diff --git a/src/components/Breadcrumb/stories.js b/src/components/Breadcrumb/stories.js index 5240e39e..618b4768 100644 --- a/src/components/Breadcrumb/stories.js +++ b/src/components/Breadcrumb/stories.js @@ -6,9 +6,9 @@ import { number } from '@storybook/addon-knobs' import Breadcrumb from 'components/Breadcrumb' -const stories = storiesOf('Components/Breadcrumb', module) +const stories = storiesOf('Components', module) -stories.add('basic', () => ( +stories.add('Breadcrumb', () => ( { } } -stories.add('basic', () => ( +stories.add('RecipientAddress', () => ( ( ({ id: chance.string(), @@ -48,7 +48,7 @@ class Wrapper extends PureComponent { } } -stories.add('basic', () => ( +stories.add('SelectAccount', () => ( ( k} /> diff --git a/src/components/TransactionsList/stories.js b/src/components/TransactionsList/stories.js index 8f67dc80..ac7880bc 100644 --- a/src/components/TransactionsList/stories.js +++ b/src/components/TransactionsList/stories.js @@ -6,7 +6,7 @@ import { boolean } from '@storybook/addon-knobs' import TransactionsList from 'components/TransactionsList' -const stories = storiesOf('Components/TransactionsList', module) +const stories = storiesOf('Components', module) const transactions = [ { @@ -23,6 +23,6 @@ const transactions = [ }, ] -stories.add('basic', () => ( +stories.add('TransactionsList', () => ( )) diff --git a/src/components/base/Bar/stories.js b/src/components/base/Bar/stories.js index d1d79452..8e920897 100644 --- a/src/components/base/Bar/stories.js +++ b/src/components/base/Bar/stories.js @@ -7,6 +7,6 @@ import { storiesOf } from '@storybook/react' import Bar from 'components/base/Bar' -const stories = storiesOf('Components/Bar', module) +const stories = storiesOf('Components', module) -stories.add('basic', () => ) +stories.add('Bar', () => ) diff --git a/src/components/base/Button/stories.js b/src/components/base/Button/stories.js index 9c79523a..72bd84f2 100644 --- a/src/components/base/Button/stories.js +++ b/src/components/base/Button/stories.js @@ -6,7 +6,7 @@ import styled from 'styled-components' import Button from 'components/base/Button' -const stories = storiesOf('Components/Button', module) +const stories = storiesOf('Components', module) const Th = styled.th` padding: 20px; @@ -17,7 +17,7 @@ const Td = styled.td` min-width: 150px; ` -stories.add('all', () => ( +stories.add('Button', () => ( diff --git a/src/components/base/CheckBox/stories.js b/src/components/base/CheckBox/stories.js index fe006605..f196de87 100644 --- a/src/components/base/CheckBox/stories.js +++ b/src/components/base/CheckBox/stories.js @@ -5,8 +5,8 @@ import { action } from '@storybook/addon-actions' import CheckBox from 'components/base/CheckBox' -const stories = storiesOf('Components/CheckBox', module) +const stories = storiesOf('Components', module) -stories.add('basic', () => ( +stories.add('CheckBox', () => ( )) diff --git a/src/components/base/GrowScroll/stories.js b/src/components/base/GrowScroll/stories.js index f10eba34..ec18ad21 100644 --- a/src/components/base/GrowScroll/stories.js +++ b/src/components/base/GrowScroll/stories.js @@ -7,9 +7,9 @@ import { boolean } from '@storybook/addon-knobs' import Box from 'components/base/Box' import GrowScroll from 'components/base/GrowScroll' -const stories = storiesOf('Components/GrowScroll', module) +const stories = storiesOf('Components', module) -stories.add('basic', () => { +stories.add('GrowScroll', () => { const reverseColor = boolean('reverseColor', false) return ( diff --git a/src/components/base/Input/stories.js b/src/components/base/Input/stories.js index 91539535..196a7b12 100644 --- a/src/components/base/Input/stories.js +++ b/src/components/base/Input/stories.js @@ -5,6 +5,6 @@ import { storiesOf } from '@storybook/react' import Input from 'components/base/Input' -const stories = storiesOf('Components/Input', module) +const stories = storiesOf('Components', module) -stories.add('basic', () => ) +stories.add('Input', () => ) diff --git a/src/components/base/Modal/stories.js b/src/components/base/Modal/stories.js index b1544817..17078d48 100644 --- a/src/components/base/Modal/stories.js +++ b/src/components/base/Modal/stories.js @@ -6,9 +6,9 @@ import { boolean } from '@storybook/addon-knobs' import { Modal, ModalBody } from 'components/base/Modal' -const stories = storiesOf('Components/Modal', module) +const stories = storiesOf('Components', module) -stories.add('basic', () => { +stories.add('Modal', () => { const isOpened = boolean('isOpened', true) return ( { } } -stories.add('default', () => ) +stories.add('Chart', () => ) function generateRandomData(n) { const today = moment() diff --git a/src/components/base/Pills/stories.js b/src/components/base/Pills/stories.js index 191a9138..5344c775 100644 --- a/src/components/base/Pills/stories.js +++ b/src/components/base/Pills/stories.js @@ -5,7 +5,7 @@ import { storiesOf } from '@storybook/react' import Pills from 'components/base/Pills' -const stories = storiesOf('Components/Pills', module) +const stories = storiesOf('Components', module) type State = { key: string, @@ -32,4 +32,4 @@ class Wrapper extends PureComponent { } } -stories.add('basic', () => ) +stories.add('Pills', () => ) diff --git a/src/components/base/QRCode/stories.js b/src/components/base/QRCode/stories.js index c00c8d80..77613165 100644 --- a/src/components/base/QRCode/stories.js +++ b/src/components/base/QRCode/stories.js @@ -7,6 +7,6 @@ import { text, number } from '@storybook/addon-knobs' import QRCode from 'components/base/QRCode' -const stories = storiesOf('Components/QRCode', module) +const stories = storiesOf('Components', module) -stories.add('basic', () => ) +stories.add('QRCode', () => ) diff --git a/src/components/base/Radio/stories.js b/src/components/base/Radio/stories.js index daa31f83..f84e73d5 100644 --- a/src/components/base/Radio/stories.js +++ b/src/components/base/Radio/stories.js @@ -5,8 +5,8 @@ import { boolean } from '@storybook/addon-knobs' import Radio from 'components/base/Radio' -const stories = storiesOf('Components/Radio', module) +const stories = storiesOf('Components', module) -stories.add('basic', () => ( +stories.add('Radio', () => ( )) diff --git a/src/components/base/Search/stories.js b/src/components/base/Search/stories.js deleted file mode 100644 index 293ac3ae..00000000 --- a/src/components/base/Search/stories.js +++ /dev/null @@ -1,79 +0,0 @@ -// @flow - -import React from 'react' -import PropTypes from 'prop-types' -import { storiesOf } from '@storybook/react' -import { text, boolean } from '@storybook/addon-knobs' - -import Search from 'components/base/Search' - -const stories = storiesOf('Components/Search', module) - -const items = [ - { key: 'aleksandr-grichtchouk', name: 'Aleksandr Grichtchouk' }, - { key: 'fabiano-caruana', name: 'Fabiano Caruana' }, - { key: 'garry-kasparov', name: 'Garry Kasparov' }, - { key: 'hikaru-nakamura', name: 'Hikaru Nakamura' }, - { key: 'levon-aronian', name: 'Levon Aronian' }, - { key: 'magnus-carlsen', name: 'Magnus Carlsen' }, - { key: 'maxime-vachier-lagrave', name: 'Maxime Vachier-Lagrave' }, - { key: 'shakhriyar-mamedyarov', name: 'Shakhriyar Mamedyarov' }, - { key: 'veselin-topalov', name: 'Veselin Topalov' }, - { key: 'viswanathan-anand', name: 'Viswanathan Anand' }, - { key: 'vladimir-kramnik', name: 'Vladimir Kramnik' }, -] - -const Wrapper = ({ children }) => ( -
-
{'(Change the search value in knobs)'}
- {children} -
-) - -Wrapper.propTypes = { - children: PropTypes.any.isRequired, -} - -stories.add('basic', () => { - const value = text('value', '') - const filterEmpty = boolean('filterEmpty', false) - return ( - - items.map(item =>
{item.name}
)} - /> -
- ) -}) - -stories.add('highlight matches', () => { - const value = text('value', '') - const filterEmpty = boolean('filterEmpty', false) - return ( - - ( - - {text} - - )} - render={items => - items.map(item =>
{item.name_highlight || item.name}
) - } - /> -
- ) -}) diff --git a/src/components/base/Tabs/stories.js b/src/components/base/Tabs/stories.js index 7f9dc543..2447b428 100644 --- a/src/components/base/Tabs/stories.js +++ b/src/components/base/Tabs/stories.js @@ -6,9 +6,9 @@ import { storiesOf } from '@storybook/react' import Tabs from 'components/base/Tabs' -const stories = storiesOf('Components/Tabs', module) +const stories = storiesOf('Components', module) -stories.add('basic', () => ( +stories.add('Tabs', () => (
Oyo!
}>Hover me!
) +stories.add('Tooltip', () =>
Oyo!
}>Hover me!
) From bab00eb5caa10c603bef654ef3cc1077b3a9aa2a Mon Sep 17 00:00:00 2001 From: meriadec Date: Wed, 14 Mar 2018 12:34:28 +0100 Subject: [PATCH 3/3] Dynamic ticks & default tooltip in Chart component --- src/components/BalanceSummary/index.js | 32 ++---------------- src/components/DashboardPage/AccountCard.js | 1 + src/components/base/NewChart/Tooltip.js | 33 ++++++++++++++----- .../base/NewChart/handleMouseEvents.js | 4 +-- src/components/base/NewChart/index.js | 20 ++++++----- src/components/base/NewChart/refreshDraw.js | 28 +++++++++++++++- src/components/base/NewChart/stories.js | 7 ++-- 7 files changed, 74 insertions(+), 51 deletions(-) diff --git a/src/components/BalanceSummary/index.js b/src/components/BalanceSummary/index.js index 543f4481..da423d90 100644 --- a/src/components/BalanceSummary/index.js +++ b/src/components/BalanceSummary/index.js @@ -1,9 +1,8 @@ // @flow import React, { Fragment } from 'react' -import moment from 'moment' -import { formatShort, getFiatUnit } from '@ledgerhq/currencies' +import { getFiatUnit } from '@ledgerhq/currencies' import type { Accounts } from 'types/common' @@ -12,30 +11,6 @@ import Box, { Card } from 'components/base/Box' import CalculateBalance from 'components/CalculateBalance' import FormattedVal from 'components/base/FormattedVal' -function getTickCountX(selectedTime) { - switch (selectedTime) { - default: - case 'week': - return 7 - - case 'month': - return 10 - - case 'year': - return 13 - } -} - -function renderTickX(selectedTime) { - let format = 'MMM. D' - - if (selectedTime === 'year') { - format = 'MMM.' - } - - return t => moment(t).format(format) -} - type Props = { counterValue: string, chartColor: string, @@ -80,9 +55,8 @@ const BalanceSummary = ({ color={chartColor} data={allBalances} height={250} - nbTicksX={getTickCountX(selectedTime)} - renderTickX={renderTickX(selectedTime)} - renderTickY={t => formatShort(unit, t)} + unit={unit} + tickXScale={selectedTime} renderTooltip={d => ( )} diff --git a/src/components/base/NewChart/Tooltip.js b/src/components/base/NewChart/Tooltip.js index ace1533c..7b4aad3e 100644 --- a/src/components/base/NewChart/Tooltip.js +++ b/src/components/base/NewChart/Tooltip.js @@ -1,9 +1,12 @@ // @flow -import React, { Fragment } from 'react' +import React from 'react' + +import type { Unit } from '@ledgerhq/currencies' import { colors as themeColors } from 'styles/theme' import { TooltipContainer } from 'components/base/Tooltip' +import FormattedVal from 'components/base/FormattedVal' import type { Item } from './types' @@ -29,7 +32,17 @@ const Arrow = () => ( ) -const Tooltip = ({ d, renderTooltip }: { d: Item, renderTooltip?: Function }) => ( +const Tooltip = ({ + d, + renderTooltip, + fiat, + unit, +}: { + d: Item, + renderTooltip?: Function, + fiat?: string, + unit?: Unit, +}) => (
{renderTooltip ? ( renderTooltip(d) ) : ( - -
- {Math.round(d.value)} -
- {d.date} -
+ )}
@@ -62,6 +77,8 @@ const Tooltip = ({ d, renderTooltip }: { d: Item, renderTooltip?: Function }) => Tooltip.defaultProps = { renderTooltip: undefined, + fiat: undefined, + unit: undefined, } export default Tooltip diff --git a/src/components/base/NewChart/handleMouseEvents.js b/src/components/base/NewChart/handleMouseEvents.js index 656a404e..9f528a26 100644 --- a/src/components/base/NewChart/handleMouseEvents.js +++ b/src/components/base/NewChart/handleMouseEvents.js @@ -26,7 +26,7 @@ export default function handleMouseEvents({ renderTooltip?: Function, }) { const { MARGINS, HEIGHT, WIDTH, NODES, DATA, x, y } = ctx - const { hideAxis } = props + const { hideAxis, unit } = props const bisectDate = d3.bisector(d => d.parsedDate).left @@ -93,7 +93,7 @@ export default function handleMouseEvents({ .html( renderToString( - + , ), ) diff --git a/src/components/base/NewChart/index.js b/src/components/base/NewChart/index.js index 2f19ac8f..adb1637d 100644 --- a/src/components/base/NewChart/index.js +++ b/src/components/base/NewChart/index.js @@ -37,6 +37,8 @@ import React, { PureComponent } from 'react' import * as d3 from 'd3' import noop from 'lodash/noop' +import type { Unit } from '@ledgerhq/currencies' + import refreshNodes from './refreshNodes' import refreshDraw from './refreshDraw' import handleMouseEvents from './handleMouseEvents' @@ -46,27 +48,27 @@ import type { Data } from './types' export type Props = { data: Data, // eslint-disable-line react/no-unused-prop-types + unit: Unit, // eslint-disable-line react/no-unused-prop-types + + id?: string, // eslint-disable-line react/no-unused-prop-types + height?: number, + tickXScale: string, // eslint-disable-line react/no-unused-prop-types color?: string, // eslint-disable-line react/no-unused-prop-types hideAxis?: boolean, // eslint-disable-line react/no-unused-prop-types - interactive?: boolean, // eslint-disable-line react/no-unused-prop-types - height: number, dateFormat?: string, // eslint-disable-line react/no-unused-prop-types - id?: string, // eslint-disable-line react/no-unused-prop-types - nbTicksX: number, // eslint-disable-line react/no-unused-prop-types + interactive?: boolean, // eslint-disable-line react/no-unused-prop-types renderTooltip?: Function, // eslint-disable-line react/no-unused-prop-types - renderTickX?: Function, // eslint-disable-line react/no-unused-prop-types - renderTickY?: Function, // eslint-disable-line react/no-unused-prop-types } class Chart extends PureComponent { static defaultProps = { + id: 'chart', color: '#000', hideAxis: false, interactive: true, height: 400, dateFormat: '%Y-%m-%d', - id: 'chart', - nbTicksX: 5, + tickXScale: 'month', } componentDidMount() { @@ -132,7 +134,7 @@ class Chart extends PureComponent { } // Derived draw variables - ctx.HEIGHT = Math.max(0, height - ctx.MARGINS.top - ctx.MARGINS.bottom) + ctx.HEIGHT = Math.max(0, (height || 0) - ctx.MARGINS.top - ctx.MARGINS.bottom) ctx.WIDTH = Math.max(0, this._width - ctx.MARGINS.left - ctx.MARGINS.right) // Scales and areas diff --git a/src/components/base/NewChart/refreshDraw.js b/src/components/base/NewChart/refreshDraw.js index a44bba93..73ad70fb 100644 --- a/src/components/base/NewChart/refreshDraw.js +++ b/src/components/base/NewChart/refreshDraw.js @@ -1,15 +1,41 @@ // @flow import * as d3 from 'd3' +import moment from 'moment' +import { formatShort } from '@ledgerhq/currencies' import { colors as themeColors } from 'styles/theme' import type { Props } from '.' import type { CTX } from './types' +const TICK_X_SCALE = { + week: 7, + month: 10, + year: 13, + default: 10, +} + +function getTickXCount(tickXScale) { + return TICK_X_SCALE[tickXScale] || TICK_X_SCALE.default +} + +const RENDER_TICK_X = { + year: 'MMM.', + default: 'MMM. D', +} + +function getRenderTickX(selectedTime) { + return t => moment(t).format(RENDER_TICK_X[selectedTime] || RENDER_TICK_X.default) +} + export default function refreshDraw({ ctx, props }: { ctx: CTX, props: Props }) { const { NODES, WIDTH, HEIGHT, MARGINS, COLORS, INVALIDATED, DATA, x, y } = ctx - const { hideAxis, interactive, renderTickX, renderTickY, nbTicksX } = props + const { hideAxis, interactive, tickXScale, unit } = props + + const nbTicksX = getTickXCount(tickXScale) + const renderTickX = getRenderTickX(tickXScale) + const renderTickY = t => formatShort(unit, t) const area = d3 .area() diff --git a/src/components/base/NewChart/stories.js b/src/components/base/NewChart/stories.js index 5ad332d0..a4209187 100644 --- a/src/components/base/NewChart/stories.js +++ b/src/components/base/NewChart/stories.js @@ -1,6 +1,7 @@ // @flow import React, { Component, Fragment } from 'react' +import { getDefaultUnitByCoinType } from '@ledgerhq/currencies' import Chance from 'chance' import moment from 'moment' import { storiesOf } from '@storybook/react' @@ -12,6 +13,7 @@ import Chart from 'components/base/NewChart' const stories = storiesOf('Components', module) const data = generateRandomData(365) +const unit = getDefaultUnitByCoinType(0) type State = { start: number, @@ -45,7 +47,8 @@ class Wrapper extends Component { hideAxis={boolean('hideAxis', false)} color={color('color', '#5f8ced')} data={data.slice(start, stop)} - height={number('height', 300, { min: 100, max: 900 })} + height={number('height', 300)} + unit={unit} /> ) @@ -62,7 +65,7 @@ function generateRandomData(n) { while (!day.isSame(today)) { data.push({ date: day.format('YYYY-MM-DD'), - value: chance.integer({ min: 0, max: 50e3 }), + value: chance.integer({ min: 0.5e8, max: 1e8 }), }) day.add(1, 'day') }