Gaëtan Renaudeau
7 years ago
committed by
GitHub
27 changed files with 355 additions and 298 deletions
@ -1,5 +1,8 @@ |
|||||
#/bin/bash |
#/bin/bash |
||||
|
|
||||
flow-typed install -s --overwrite |
flow-typed install -s --overwrite |
||||
rm flow-typed/npm/{react-i18next_v7.x.x.js,styled-components_v3.x.x.js} |
rm flow-typed/npm/{react-i18next_v7.x.x.js,styled-components_v3.x.x.js,redux_*} |
||||
|
|
||||
|
if [ "$SKIP_REBUILD" != "1" ]; then |
||||
electron-builder install-app-deps |
electron-builder install-app-deps |
||||
|
fi |
||||
|
@ -0,0 +1,64 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import styled from 'styled-components' |
||||
|
import { |
||||
|
alignItems, |
||||
|
borderRadius, |
||||
|
boxShadow, |
||||
|
color, |
||||
|
flex, |
||||
|
flexWrap, |
||||
|
fontSize, |
||||
|
justifyContent, |
||||
|
space, |
||||
|
style, |
||||
|
} from 'styled-system' |
||||
|
|
||||
|
import fontFamily from 'styles/styled/fontFamily' |
||||
|
|
||||
|
export const styledTextAlign = style({ prop: 'textAlign', cssProperty: 'textAlign' }) |
||||
|
export const styledCursor = style({ prop: 'cursor', cssProperty: 'cursor' }) |
||||
|
|
||||
|
export default styled.div` |
||||
|
${alignItems}; |
||||
|
${borderRadius}; |
||||
|
${boxShadow}; |
||||
|
${color}; |
||||
|
${flex}; |
||||
|
${flexWrap}; |
||||
|
${fontFamily}; |
||||
|
${fontSize}; |
||||
|
${justifyContent}; |
||||
|
${space}; |
||||
|
${styledTextAlign}; |
||||
|
${styledCursor}; |
||||
|
|
||||
|
display: flex; |
||||
|
flex-shrink: ${p => (p.noShrink === true ? '0' : p.shrink === true ? '1' : '')}; |
||||
|
flex-grow: ${p => (p.grow === true ? '1' : p.grow || '')}; |
||||
|
flex-direction: ${p => (p.horizontal ? 'row' : 'column')}; |
||||
|
|
||||
|
overflow-y: ${p => (p.scroll === true ? 'auto' : '')}; |
||||
|
position: ${p => (p.relative ? 'relative' : p.sticky ? 'absolute' : '')}; |
||||
|
|
||||
|
${p => |
||||
|
p.selectable && |
||||
|
` |
||||
|
user-select: text; |
||||
|
cursor: text; |
||||
|
`};
|
||||
|
|
||||
|
${p => |
||||
|
p.sticky && |
||||
|
` |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
`};
|
||||
|
|
||||
|
> * + * { |
||||
|
margin-top: ${p => (!p.horizontal && p.flow ? `${p.theme.space[p.flow]}px` : '')}; |
||||
|
margin-left: ${p => (p.horizontal && p.flow ? `${p.theme.space[p.flow]}px` : '')}; |
||||
|
} |
||||
|
` |
@ -0,0 +1,23 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import React from 'react' |
||||
|
import styled from 'styled-components' |
||||
|
|
||||
|
import Text from 'components/base/Text' |
||||
|
import Box from './Box' |
||||
|
|
||||
|
const RawCard = styled(Box).attrs({ bg: 'white', p: 3, boxShadow: 0, borderRadius: 1 })`` |
||||
|
|
||||
|
export default ({ title, ...props }: { title?: any }) => { |
||||
|
if (title) { |
||||
|
return ( |
||||
|
<Box flow={4} grow> |
||||
|
<Text color="dark" ff="Museo Sans" fontSize={6}> |
||||
|
{title} |
||||
|
</Text> |
||||
|
<RawCard grow {...props} /> |
||||
|
</Box> |
||||
|
) |
||||
|
} |
||||
|
return <RawCard {...props} /> |
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import React, { Component } from 'react' |
||||
|
import styled from 'styled-components' |
||||
|
|
||||
|
import { isGlobalTabEnabled } from 'renderer/init' |
||||
|
import { rgba } from 'styles/helpers' |
||||
|
|
||||
|
import Box from './Box' |
||||
|
|
||||
|
const KEY_ENTER = 13 |
||||
|
|
||||
|
export const focusedShadowStyle = ` |
||||
|
0 0 0 1px ${rgba('#0a84ff', 0.5)} inset, |
||||
|
0 0 0 1px ${rgba('#0a84ff', 0.3)}, |
||||
|
0 0 0 4px rgba(10, 132, 255, 0.1) |
||||
|
` |
||||
|
|
||||
|
const Raw = styled(Box)` |
||||
|
&:focus { |
||||
|
outline: none; |
||||
|
box-shadow: ${p => (p.isFocused && !p.unstyled ? focusedShadowStyle : 'none')}; |
||||
|
} |
||||
|
` |
||||
|
|
||||
|
export default class Tabbable extends Component< |
||||
|
{ disabled?: boolean, unstyled?: boolean, onClick?: any => void }, |
||||
|
{ isFocused: boolean }, |
||||
|
> { |
||||
|
state = { |
||||
|
isFocused: false, |
||||
|
} |
||||
|
|
||||
|
handleFocus = () => { |
||||
|
if (isGlobalTabEnabled()) { |
||||
|
this.setState({ isFocused: true }) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
handleBlur = () => this.setState({ isFocused: false }) |
||||
|
|
||||
|
handleKeyPress = (e: SyntheticKeyboardEvent<*>) => { |
||||
|
const { isFocused } = this.state |
||||
|
const { onClick } = this.props |
||||
|
const canPress = e.which === KEY_ENTER && isGlobalTabEnabled() && isFocused |
||||
|
if (canPress && onClick) onClick(e) |
||||
|
} |
||||
|
|
||||
|
render() { |
||||
|
const { disabled } = this.props |
||||
|
const { isFocused } = this.state |
||||
|
return ( |
||||
|
<Raw |
||||
|
tabIndex={disabled ? undefined : 0} |
||||
|
isFocused={isFocused} |
||||
|
onFocus={this.handleFocus} |
||||
|
onBlur={this.handleBlur} |
||||
|
onKeyPress={this.handleKeyPress} |
||||
|
{...this.props} |
||||
|
/> |
||||
|
) |
||||
|
} |
||||
|
} |
@ -1,136 +1,7 @@ |
|||||
// @flow
|
// @flow
|
||||
|
|
||||
import React, { PureComponent } from 'react' |
import Box from './Box' |
||||
import styled from 'styled-components' |
|
||||
import { |
|
||||
alignItems, |
|
||||
borderRadius, |
|
||||
boxShadow, |
|
||||
color, |
|
||||
flex, |
|
||||
flexWrap, |
|
||||
fontSize, |
|
||||
justifyContent, |
|
||||
space, |
|
||||
style, |
|
||||
} from 'styled-system' |
|
||||
|
|
||||
import fontFamily from 'styles/styled/fontFamily' |
|
||||
|
|
||||
import Text from 'components/base/Text' |
|
||||
|
|
||||
const textAlign = style({ |
|
||||
prop: 'textAlign', |
|
||||
cssProperty: 'textAlign', |
|
||||
}) |
|
||||
|
|
||||
const cursor = style({ |
|
||||
prop: 'cursor', |
|
||||
cssProperty: 'cursor', |
|
||||
}) |
|
||||
|
|
||||
const Box = styled.div` |
|
||||
${alignItems}; |
|
||||
${borderRadius}; |
|
||||
${boxShadow}; |
|
||||
${color}; |
|
||||
${flex}; |
|
||||
${flexWrap}; |
|
||||
${fontFamily}; |
|
||||
${fontSize}; |
|
||||
${justifyContent}; |
|
||||
${space}; |
|
||||
${textAlign}; |
|
||||
${cursor}; |
|
||||
|
|
||||
display: flex; |
|
||||
flex-shrink: ${p => (p.noShrink === true ? '0' : p.shrink === true ? '1' : '')}; |
|
||||
flex-grow: ${p => (p.grow === true ? '1' : p.grow || '')}; |
|
||||
flex-direction: ${p => (p.horizontal ? 'row' : 'column')}; |
|
||||
|
|
||||
overflow-y: ${p => (p.scroll === true ? 'auto' : '')}; |
|
||||
position: ${p => (p.relative ? 'relative' : p.sticky ? 'absolute' : '')}; |
|
||||
|
|
||||
${p => |
|
||||
p.selectable && |
|
||||
` |
|
||||
user-select: text; |
|
||||
cursor: text; |
|
||||
`};
|
|
||||
|
|
||||
${p => |
|
||||
p.sticky && |
|
||||
` |
|
||||
top: 0; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
bottom: 0; |
|
||||
`};
|
|
||||
|
|
||||
> * + * { |
|
||||
margin-top: ${p => (!p.horizontal && p.flow ? `${p.theme.space[p.flow]}px` : '')}; |
|
||||
margin-left: ${p => (p.horizontal && p.flow ? `${p.theme.space[p.flow]}px` : '')}; |
|
||||
} |
|
||||
` |
|
||||
// ^FIXME this `> * + * happen for all Box but we only need it when we do "grids".. which is not often. margin should be made explicit on user land.
|
|
||||
|
|
||||
const RawCard = styled(Box).attrs({ bg: 'white', p: 3, boxShadow: 0, borderRadius: 1 })`` |
|
||||
|
|
||||
export const Card = ({ title, ...props }: { title?: any }) => { |
|
||||
if (title) { |
|
||||
return ( |
|
||||
<Box flow={4} grow> |
|
||||
<Text color="dark" ff="Museo Sans" fontSize={6}> |
|
||||
{title} |
|
||||
</Text> |
|
||||
<RawCard grow {...props} /> |
|
||||
</Box> |
|
||||
) |
|
||||
} |
|
||||
return <RawCard {...props} /> |
|
||||
} |
|
||||
|
|
||||
Card.defaultProps = { |
|
||||
title: undefined, |
|
||||
} |
|
||||
|
|
||||
type TabbableState = { |
|
||||
isFocused: boolean, |
|
||||
} |
|
||||
|
|
||||
export class Tabbable extends PureComponent<any, TabbableState> { |
|
||||
state = { |
|
||||
isFocused: false, |
|
||||
} |
|
||||
|
|
||||
componentDidMount() { |
|
||||
window.addEventListener('keydown', this.handleKeydown) |
|
||||
} |
|
||||
|
|
||||
componentWillUnmount() { |
|
||||
window.removeEventListener('keydown', this.handleKeydown) |
|
||||
} |
|
||||
|
|
||||
handleFocus = () => this.setState({ isFocused: true }) |
|
||||
handleBlur = () => this.setState({ isFocused: false }) |
|
||||
|
|
||||
handleKeydown = (e: SyntheticKeyboardEvent<any>) => { |
|
||||
if ((e.which === 13 || e.which === 32) && this.state.isFocused && this.props.onClick) { |
|
||||
this.props.onClick(e) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
render() { |
|
||||
const { disabled } = this.props |
|
||||
return ( |
|
||||
<Box |
|
||||
tabIndex={disabled ? undefined : 0} |
|
||||
onFocus={this.handleFocus} |
|
||||
onBlur={this.handleBlur} |
|
||||
{...this.props} |
|
||||
/> |
|
||||
) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
export { default as Tabbable } from './Tabbable' |
||||
|
export { default as Card } from './Card' |
||||
export default Box |
export default Box |
||||
|
@ -1,39 +0,0 @@ |
|||||
import React from 'react' |
|
||||
import { getCryptoCurrencyById } from '@ledgerhq/live-common/lib/helpers/currencies' |
|
||||
|
|
||||
import render from '__mocks__/render' |
|
||||
import FormattedVal from '..' |
|
||||
|
|
||||
const bitcoinUnit = getCryptoCurrencyById('bitcoin').units[0] |
|
||||
|
|
||||
describe('components', () => { |
|
||||
describe('FormattedVal', () => { |
|
||||
it('renders a formatted val', () => { |
|
||||
const component = <FormattedVal unit={bitcoinUnit} val={400000000} /> |
|
||||
const tree = render(component) |
|
||||
expect(tree).toMatchSnapshot() |
|
||||
}) |
|
||||
|
|
||||
it('shows sign', () => { |
|
||||
const component = <FormattedVal alwaysShowSign unit={bitcoinUnit} val={400000000} /> |
|
||||
const tree = render(component) |
|
||||
expect(tree).toMatchSnapshot() |
|
||||
|
|
||||
const component2 = <FormattedVal alwaysShowSign unit={bitcoinUnit} val={-400000000} /> |
|
||||
const tree2 = render(component2) |
|
||||
expect(tree2).toMatchSnapshot() |
|
||||
}) |
|
||||
|
|
||||
it('shows code', () => { |
|
||||
const component = <FormattedVal showCode unit={bitcoinUnit} val={400000000} /> |
|
||||
const tree = render(component) |
|
||||
expect(tree).toMatchSnapshot() |
|
||||
}) |
|
||||
|
|
||||
it('renders a percent', () => { |
|
||||
const component = <FormattedVal isPercent val={30} /> |
|
||||
const tree = render(component) |
|
||||
expect(tree).toMatchSnapshot() |
|
||||
}) |
|
||||
}) |
|
||||
}) |
|
@ -1,46 +0,0 @@ |
|||||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|
||||
|
|
||||
exports[`components FormattedVal renders a formatted val 1`] = ` |
|
||||
<div |
|
||||
className="k45ou1-0 iqaJGf e345n3-0 cbufQL" |
|
||||
color="#66be54" |
|
||||
> |
|
||||
4 |
|
||||
</div> |
|
||||
`; |
|
||||
|
|
||||
exports[`components FormattedVal renders a percent 1`] = ` |
|
||||
<div |
|
||||
className="k45ou1-0 iqaJGf e345n3-0 cbufQL" |
|
||||
color="#66be54" |
|
||||
> |
|
||||
30 % |
|
||||
</div> |
|
||||
`; |
|
||||
|
|
||||
exports[`components FormattedVal shows code 1`] = ` |
|
||||
<div |
|
||||
className="k45ou1-0 iqaJGf e345n3-0 cbufQL" |
|
||||
color="#66be54" |
|
||||
> |
|
||||
BTC 4 |
|
||||
</div> |
|
||||
`; |
|
||||
|
|
||||
exports[`components FormattedVal shows sign 1`] = ` |
|
||||
<div |
|
||||
className="k45ou1-0 iqaJGf e345n3-0 cbufQL" |
|
||||
color="#66be54" |
|
||||
> |
|
||||
+ 4 |
|
||||
</div> |
|
||||
`; |
|
||||
|
|
||||
exports[`components FormattedVal shows sign 2`] = ` |
|
||||
<div |
|
||||
className="k45ou1-0 iqaJGf e345n3-0 eZFsmG" |
|
||||
color="#ea2e49" |
|
||||
> |
|
||||
- 4 |
|
||||
</div> |
|
||||
`; |
|
Loading…
Reference in new issue