Browse Source

Merge pull request #867 from mrfelton/fix/ui-global-style-reset

style(global): update global styles
renovate/lint-staged-8.x
JimmyMow 6 years ago
committed by GitHub
parent
commit
c90e595d08
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .stylelintignore
  2. 5
      .svgrrc
  3. 4
      app/app.html
  4. 17
      app/components/Activity/Activity.js
  5. 36
      app/components/Activity/Activity.scss
  6. 5
      app/components/Activity/Transaction/Transaction.scss
  7. 10
      app/components/App/App.js
  8. 2
      app/components/App/App.scss
  9. 4
      app/components/Contacts/AddChannel/AddChannel.scss
  10. 2
      app/components/Contacts/ConnectManually/ConnectManually.js
  11. 3
      app/components/Contacts/ConnectManually/ConnectManually.scss
  12. 10
      app/components/Contacts/Network/Network.js
  13. 24
      app/components/Contacts/Network/Network.scss
  14. 2
      app/components/Contacts/SubmitChannelForm/SubmitChannelForm.js
  15. 3
      app/components/Contacts/SubmitChannelForm/SubmitChannelForm.scss
  16. 3
      app/components/Form/Pay/Pay.js
  17. 2
      app/components/Form/Request/Request.js
  18. 3
      app/components/Form/Request/Request.scss
  19. 16
      app/components/Icon/BigArrowLeft.js
  20. 4
      app/components/Icon/BigArrowRight.js
  21. 12
      app/components/Icon/Close.js
  22. 13
      app/components/Icon/Error.js
  23. 2
      app/components/Icon/IconPlus.js
  24. 22
      app/components/Icon/Lightning.js
  25. 29
      app/components/Icon/Onchain.js
  26. 21
      app/components/Icon/Spinner.js
  27. 21
      app/components/Icon/Success.js
  28. 6
      app/components/Icon/SystemError.js
  29. 6
      app/components/Icon/SystemSuccess.js
  30. 0
      app/components/Icon/Warning.js
  31. 25
      app/components/Icon/X.js
  32. 8
      app/components/Onboarding/ConnectionConfirm/ConnectionConfirm.js
  33. 8
      app/components/Onboarding/ConnectionConfirm/ConnectionConfirm.scss
  34. 2
      app/components/Onboarding/ConnectionType/ConnectionType.scss
  35. 2
      app/components/Onboarding/FormContainer/FormContainer.js
  36. 3
      app/components/Onboarding/Login/Login.js
  37. 1
      app/components/Onboarding/Signup/Signup.scss
  38. 2
      app/components/UI/BackgroundDark.js
  39. 2
      app/components/UI/BackgroundLight.js
  40. 2
      app/components/UI/BackgroundLightest.js
  41. 14
      app/components/UI/Bar.js
  42. 39
      app/components/UI/Button.js
  43. 23
      app/components/UI/Dropdown.js
  44. 22
      app/components/UI/FormFieldMessage.js
  45. 251
      app/components/UI/GlobalStyle.js
  46. 11
      app/components/UI/Heading.js
  47. 2
      app/components/UI/MenuItemGroup.js
  48. 44
      app/components/UI/Modal.js
  49. 26
      app/components/UI/Notification.js
  50. 21
      app/components/UI/Page.js
  51. 2
      app/components/UI/Range.js
  52. 2
      app/components/UI/Select.js
  53. 6
      app/components/UI/Sidebar.js
  54. 32
      app/components/UI/Spinner.js
  55. 2
      app/components/UI/Text.js
  56. 13
      app/components/Value/Value.js
  57. 1
      app/components/Wallet/ReceiveModal/ReceiveModal.scss
  58. 64
      app/components/Wallet/Wallet.js
  59. 4
      app/components/Wallet/Wallet.scss
  60. 3
      app/containers/App.js
  61. 15
      app/containers/Root.js
  62. 5
      app/icons/big-arrow-left.svg
  63. 6
      app/icons/big-arrow-right.svg
  64. 6
      app/icons/close.svg
  65. 3
      app/icons/error.svg
  66. 12
      app/icons/lightning.svg
  67. 13
      app/icons/onchain.svg
  68. 6
      app/icons/spinner.svg
  69. 6
      app/icons/success.svg
  70. 7
      app/icons/x.svg
  71. 2
      app/reducers/lnd.js
  72. 52
      app/styles/animated_checkmark.scss
  73. 97
      app/styles/app.global.scss
  74. 47
      app/styles/keyframes.scss
  75. 48
      app/styles/reset.scss
  76. 162
      app/styles/tooltip.scss
  77. 11
      app/themes/base.js
  78. 7
      app/themes/dark.js
  79. 7
      app/themes/light.js
  80. 34
      internals/webpack/webpack.config.base.js
  81. 69
      internals/webpack/webpack.config.renderer.dev.dll.js
  82. 72
      internals/webpack/webpack.config.renderer.dev.js
  83. 78
      internals/webpack/webpack.config.renderer.prod.js
  84. 1
      package.json
  85. 11
      stories/components/button.stories.js
  86. 2
      stories/components/form.stories.js
  87. 74
      stories/components/icon.stories.js
  88. 21
      stories/components/modal.stories.js
  89. 12
      test/unit/components/UI/Notification.spec.js
  90. 4
      test/unit/components/UI/__snapshots__/BackgroundDark.spec.js.snap
  91. 4
      test/unit/components/UI/__snapshots__/BackgroundLight.spec.js.snap
  92. 4
      test/unit/components/UI/__snapshots__/BackgroundLightest.spec.js.snap
  93. 7
      test/unit/components/UI/__snapshots__/Bar.spec.js.snap
  94. 16
      test/unit/components/UI/__snapshots__/Button.spec.js.snap
  95. 8
      test/unit/components/UI/__snapshots__/Dropdown.spec.js.snap
  96. 7
      test/unit/components/UI/__snapshots__/Heading.spec.js.snap
  97. 4
      test/unit/components/UI/__snapshots__/Input.spec.js.snap
  98. 4
      test/unit/components/UI/__snapshots__/LightningInvoiceInput.spec.js.snap
  99. 4
      test/unit/components/UI/__snapshots__/MainContent.spec.js.snap
  100. 2
      test/unit/components/UI/__snapshots__/Menu.spec.js.snap

3
.stylelintignore

@ -1,5 +1,2 @@
# Style reset
app/styles/reset.scss
# Storybook
storybook-static

5
.svgrrc

@ -1,9 +1,10 @@
{
"icon": true,
"replaceAttrValues": {
"#FD9800": "currentColor",
"#FFF": "currentColor",
"#F5A623": "currentColor",
"#010002": "currentColor"
"#010002": "currentColor",
"#E63939": "currentColor",
"#39E673": "currentColor"
}
}

4
app/app.html

@ -4,10 +4,6 @@
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="">
<title>Zap</title>
<link rel="stylesheet" href="https://s3.amazonaws.com/fonts.typotheque.com/WF-018717-007225.css" type="text/css" />
<link href='https://fonts.googleapis.com/css?family=Raleway:700' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Orbitron' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Noto+Sans:400,700|Roboto:300' rel='stylesheet' type='text/css'>
</head>
<body>
<div id="root"></div>

17
app/components/Activity/Activity.js

@ -6,7 +6,7 @@ import FaRepeat from 'react-icons/lib/fa/repeat'
import { FormattedMessage, injectIntl } from 'react-intl'
import { Flex } from 'rebass'
import { Button } from 'components/UI'
import { Button, Text } from 'components/UI'
import Wallet from 'components/Wallet'
import Invoice from './Invoice'
import Payment from './Payment'
@ -175,8 +175,9 @@ class Activity extends Component {
className={f.key === filter.key ? styles.activeFilter : undefined}
onClick={() => changeFilter(f)}
>
<FormattedMessage {...messages[f.name]} />
<Text fontWeight="normal">
<FormattedMessage {...messages[f.name]} />
</Text>
<div className={f.key === filter.key ? styles.activeBorder : undefined} />
</li>
))}
@ -191,7 +192,13 @@ class Activity extends Component {
this.repeat = ref
}}
>
{refreshing ? <FaRepeat /> : <FormattedMessage {...messages.refresh} />}
{refreshing ? (
<FaRepeat />
) : (
<Text fontWeight="normal">
<FormattedMessage {...messages.refresh} />
</Text>
)}
</span>
</li>
<li className={styles.activeFilter} onClick={() => updateSearchActive(true)}>
@ -219,7 +226,7 @@ class Activity extends Component {
{showExpiredToggle &&
currentActivity.length > 0 && (
<Flex justifyContent="center">
<Button onClick={toggleExpiredRequests} mx="auto">
<Button size="small" onClick={toggleExpiredRequests} mx="auto">
{showExpiredRequests ? (
<FormattedMessage {...messages.hide_expired} />
) : (

36
app/components/Activity/Activity.scss

@ -37,7 +37,7 @@
background: var(--darkestBackground);
color: var(--primaryText);
margin: 0 auto;
padding: 0 40px;
padding: 0 60px;
border-bottom: 1px solid $spaceborder;
display: flex;
flex-direction: row;
@ -66,10 +66,9 @@
width: 100%;
}
.xIcon svg {
width: 25px;
height: 25px;
stroke: var(--white);
.xIcon {
cursor: pointer;
color: var(--white);
}
}
@ -82,7 +81,6 @@
li {
position: relative;
opacity: 0.5;
font-size: 14px;
cursor: pointer;
&.activeFilter {
@ -96,7 +94,7 @@
span {
display: block;
position: relative;
margin: 0 15px;
margin: 0 20px;
}
svg {
@ -114,13 +112,15 @@
}
.activeBorder {
left: 15px;
right: 15px;
width: auto;
margin-left: auto;
margin-right: auto;
left: 0px;
right: 0px;
width: 50px;
height: 1px;
background: var(--primaryText);
background: var(--lightningOrange);
position: absolute;
bottom: -1px;
bottom: -6px;
}
}
}
@ -129,7 +129,7 @@
.activityContainer {
background: var(--primaryBackground);
transition: opacity 0.25s;
height: calc(100vh - 225px);
height: calc(100vh - 275px);
overflow-y: auto;
overflow-x: hidden;
padding-top: 20px;
@ -147,8 +147,7 @@
h2 {
color: var(--primaryText);
font-size: 10px;
font-weight: bold;
font-weight: 400;
border-bottom: 0.2px solid #a0a0a0;
padding: 10px 0;
}
@ -230,6 +229,7 @@
align-items: center;
padding-right: 50px;
min-width: 90px;
font-weight: 400;
section {
margin: 2.5px 0;
@ -239,10 +239,6 @@
width: 12.5px;
height: 12.5px;
}
time {
font-size: 12px;
}
}
.data {
@ -295,7 +291,7 @@
h3 {
display: inline-block;
font-size: 14px;
font-weight: bold;
font-weight: 300;
letter-spacing: 1.2px;
&::after {

5
app/components/Activity/Transaction/Transaction.scss

@ -67,13 +67,8 @@
flex: 1 0;
padding-left: 20px;
&.negative {
font-weight: 200;
}
&.positive {
color: $main;
font-weight: 500;
}
span {

10
app/components/App/App.js

@ -31,18 +31,10 @@ class App extends React.Component {
}
componentDidMount() {
const {
currentTicker,
fetchInfo,
fetchSuggestedNodes,
fetchTicker,
fetchDescribeNetwork
} = this.props
const { currentTicker, fetchInfo, fetchSuggestedNodes, fetchDescribeNetwork } = this.props
// If we don't yet have any ticker information then it must be our first time mounting this component.
if (!currentTicker) {
// fetch ticker data.
fetchTicker()
// fetch node info.
fetchInfo()
// fetch suggested nodes list from zap.jackmallers.com/suggested-peers.

2
app/components/App/App.scss

@ -6,6 +6,6 @@
display: inline-block;
vertical-align: top;
overflow-y: auto;
background: var(--lightBackground);
background: var(--lightestBackground);
padding-top: 20px;
}

4
app/components/Contacts/AddChannel/AddChannel.scss

@ -58,7 +58,7 @@
h2 {
font-size: 10px;
font-weight: bold;
font-weight: 400;
letter-spacing: 1.3px;
span {
@ -67,7 +67,7 @@
&:nth-child(1) {
font-size: 10px;
font-weight: bold;
font-weight: 400;
letter-spacing: 1.3px;
}

2
app/components/Contacts/ConnectManually/ConnectManually.js

@ -82,7 +82,7 @@ class ConnectManually extends React.Component {
</section>
<section className={styles.submit}>
<Button disabled={!manualFormIsValid.isValid} onClick={formSubmitted} size="large">
<Button disabled={!manualFormIsValid.isValid} onClick={formSubmitted}>
<FormattedMessage {...messages.submit} />
</Button>
</section>

3
app/components/Contacts/ConnectManually/ConnectManually.scss

@ -55,7 +55,7 @@
h1 {
font-size: 22px;
font-weight: 100;
font-weight: 300;
margin-top: 10px;
letter-spacing: 1.5px;
}
@ -75,7 +75,6 @@
color: var(--lightningOrange);
-webkit-text-fill-color: var(--primaryText);
width: 100%;
font-weight: 200;
}
}

10
app/components/Contacts/Network/Network.js

@ -7,7 +7,7 @@ import FaAngleDown from 'react-icons/lib/fa/angle-down'
import { btc, blockExplorer } from 'lib/utils'
import Plus from 'components/Icon/Plus'
import Search from 'components/Icon/Search'
import { BackgroundLight, Text } from 'components/UI'
import Value from 'components/Value'
import { FormattedNumber, FormattedMessage, injectIntl } from 'react-intl'
@ -165,7 +165,7 @@ class Network extends Component {
)
const { refreshing } = this.state
return (
<div className={styles.network}>
<BackgroundLight className={styles.network}>
<header className={styles.header}>
<section>
<h2>
@ -200,9 +200,9 @@ class Network extends Component {
onClick={openContactsForm}
data-hint={intl.formatMessage({ ...messages.open_channel })}
>
<span className={styles.plusContainer}>
<Text fontSize="xl">
<Plus />
</span>
</Text>
</section>
</header>
@ -384,7 +384,7 @@ class Network extends Component {
/>
</footer>
)}
</div>
</BackgroundLight>
)
}
}

24
app/components/Contacts/Network/Network.scss

@ -6,7 +6,6 @@
display: inline-block;
vertical-align: top;
height: 100vh;
background: var(--lightestBackground);
padding-top: 20px;
}
@ -14,13 +13,12 @@
display: flex;
flex-direction: row;
justify-content: space-between;
background: var(--lightestBackground);
padding: 10px 20px;
color: var(--primaryText);
h2 {
font-size: 14px;
font-weight: bold;
font-weight: 400;
letter-spacing: 1.2px;
margin-bottom: 5px;
}
@ -33,16 +31,16 @@
.addChannel {
cursor: pointer;
transition: all 0.25s;
width: 120px;
text-align: right;
svg {
border-radius: 5px;
}
&:hover {
opacity: 0.5;
svg {
background: #272931;
background: var(--lightestBackground);
}
}
}
@ -100,7 +98,6 @@
span {
color: var(--primaryText);
opacity: 1;
font-size: 10px;
cursor: pointer;
transition: all 0.25s;
@ -112,7 +109,7 @@
ul {
margin-top: 20px;
height: calc(100vh - 200px);
height: calc(100vh - 208px);
overflow-y: auto;
overflow-x: hidden;
}
@ -128,11 +125,11 @@
cursor: pointer;
&:hover {
background: var(--lightBackground);
background: var(--darkBackground);
}
&.selectedChannel {
background: var(--lightBackground);
background: var(--darkBackground);
padding-bottom: 0;
.channelDetails {
@ -154,7 +151,6 @@
&:nth-child(2) {
margin-left: 10px;
font-size: 12px;
font-weight: 300;
letter-spacing: 0.6px;
line-height: 17px;
}
@ -196,11 +192,11 @@
.search {
position: absolute;
bottom: 20px;
width: calc(100% - 40px);
bottom: 0;
width: 100%;
padding: 10px 20px;
border-top: 1px solid $darkestgrey;
background: var(--lightestBackground);
background: var(--darkBackground);
.input {
display: inline-block;

2
app/components/Contacts/SubmitChannelForm/SubmitChannelForm.js

@ -132,7 +132,7 @@ class SubmitChannelForm extends React.Component {
</section>
<section className={styles.submit}>
<Button disabled={!(contactCapacity > 0)} onClick={formSubmitted} size="large">
<Button disabled={!(contactCapacity > 0)} onClick={formSubmitted}>
<FormattedMessage {...messages.submit} />
</Button>
</section>

3
app/components/Contacts/SubmitChannelForm/SubmitChannelForm.scss

@ -13,7 +13,7 @@
h1 {
margin: 10px 0 15px 0;
font-size: 22px;
font-weight: 100;
font-weight: 300;
letter-spacing: 1.5px;
}
@ -80,7 +80,6 @@
color: var(--lightningOrange);
-webkit-text-fill-color: var(--primaryText);
width: 100%;
font-weight: 200;
}
}

3
app/components/Form/Pay/Pay.js

@ -7,7 +7,6 @@ import AmountInput from 'components/AmountInput'
import { Button, Dropdown } from 'components/UI'
import { FormattedNumber, FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from './Pay.scss'
class Pay extends Component {
@ -177,7 +176,7 @@ class Pay extends Component {
</section>
<section className={styles.submit}>
<Button disabled={!isValid} onClick={onPaySubmit} size="large" width={200}>
<Button disabled={!isValid} onClick={onPaySubmit} width={200}>
<FormattedMessage {...messages.pay} />
</Button>
</section>

2
app/components/Form/Request/Request.js

@ -85,7 +85,7 @@ const Request = ({
</section>
<section className={styles.submit}>
<Button disabled={!(amount > 0)} onClick={onRequestSubmit} size="large" width={200}>
<Button disabled={!(amount > 0)} onClick={onRequestSubmit} width={200}>
<FormattedMessage {...messages.request} />
</Button>
</section>

3
app/components/Form/Request/Request.scss

@ -13,7 +13,7 @@
h1 {
font-size: 22px;
font-weight: 100;
font-weight: 300;
margin-top: 10px;
letter-spacing: 1.5px;
}
@ -66,7 +66,6 @@
-webkit-text-fill-color: var(--primaryText);
font-size: 20px;
width: 100%;
font-weight: 200;
padding: 15px;
}

16
app/components/Icon/BigArrowLeft.js

@ -0,0 +1,16 @@
import React from 'react'
const SvgBigArrowLeft = props => (
<svg viewBox="0 0 16 12" width="1em" height="1em" {...props}>
<path
d="M1 6h14m-8.474 5L1 6l5.526-5"
fill="none"
fillRule="evenodd"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
)
export default SvgBigArrowLeft

4
app/components/Icon/BigArrowRight.js

@ -1,9 +1,9 @@
import React from 'react'
const SvgBigArrowRight = props => (
<svg viewBox="0 0 9 4" width="1em" height="1em" {...props}>
<svg viewBox="0 0 40 28" width="1em" height="1em" {...props}>
<path
d="M1 2h6M6 4l2-2-2-2"
d="M1 14h38M24 27l15-13L24 1"
fill="none"
fillRule="evenodd"
stroke="currentColor"

12
app/components/Icon/Close.js

@ -0,0 +1,12 @@
import React from 'react'
const SvgClose = props => (
<svg viewBox="0 0 10 10" width="1em" height="1em" {...props}>
<g fill="currentColor" fillRule="evenodd">
<path d="M7.744 1.077a.833.833 0 1 1 1.179 1.179L2.256 8.923a.833.833 0 1 1-1.179-1.179l6.667-6.667z" />
<path d="M1.077 2.256a.833.833 0 1 1 1.179-1.179l6.667 6.667a.833.833 0 1 1-1.179 1.179L1.077 2.256z" />
</g>
</svg>
)
export default SvgClose

13
app/components/Icon/Error.js

@ -0,0 +1,13 @@
import React from 'react'
const SvgError = props => (
<svg viewBox="0 0 17 17" width="1em" height="1em" {...props}>
<path
fill="currentColor"
fillRule="evenodd"
d="M9.512 8.333l1.91-1.91a.833.833 0 0 0-1.178-1.179l-1.91 1.91-1.911-1.91a.833.833 0 1 0-1.179 1.179l1.91 1.91-1.91 1.911a.833.833 0 1 0 1.179 1.179l1.91-1.911 1.911 1.91a.833.833 0 0 0 1.179-1.178l-1.911-1.91zm-1.179 8.334A8.333 8.333 0 1 1 8.333 0a8.333 8.333 0 0 1 0 16.667z"
/>
</svg>
)
export default SvgError

2
app/components/Icon/IconPlus.js

@ -2,7 +2,7 @@ import React from 'react'
const SvgIconPlus = props => (
<svg viewBox="0 0 18 18" width="1em" height="1em" {...props}>
<g fill="none" fillRule="evenodd" stroke="currentColor" transform="translate(1 1)">
<g fill="none" fillRule="evenodd" stroke="#FD9800" transform="translate(1 1)">
<path d="M8.09 5v6M5 8.09h6" strokeLinecap="round" strokeLinejoin="round" />
<circle cx={8} cy={8} r={8} />
</g>

22
app/components/Icon/Lightning.js

@ -0,0 +1,22 @@
import React from 'react'
const SvgLightning = props => (
<svg viewBox="0 0 50 50" width="1em" height="1em" {...props}>
<defs>
<linearGradient id="b" x1="0%" y1="0%" y2="100%">
<stop offset="0%" stopColor="#FFBD59" />
<stop offset="100%" stopColor="#FD9800" />
</linearGradient>
</defs>
<g fill="none" fillRule="evenodd">
<circle cx={25} cy={25} r={25} fill="url(#b)" />
<path
fill="currentColor"
fillRule="nonzero"
d="M22.999 39.764l.708-3.28 1.26-5.827.53-2.454c.044-.207-.094-.415-.316-.415h-7.85l.283.493 1.218-1.865 2.875-4.4 3.358-5.139 2.669-4.085.852-1.305-.599-.253-.709 3.28-1.259 5.824-.53 2.453c-.045.207.094.415.316.415h7.865l-.284-.493-1.22 1.866-2.878 4.4-3.362 5.141-2.673 4.086-.854 1.306c-.232.355.336.683.567.33l1.22-1.865 2.878-4.4 3.362-5.141 2.672-4.087.854-1.305c.138-.212-.044-.493-.283-.493h-7.864l.316.414.71-3.28 1.258-5.824.53-2.453c.08-.365-.393-.567-.599-.252l-1.218 1.865-2.875 4.4-3.357 5.139-2.67 4.085-.852 1.305c-.138.212.044.493.283.493h7.849l-.317-.414-.709 3.28-1.259 5.827-.53 2.454c-.089.412.543.587.633.174z"
/>
</g>
</svg>
)
export default SvgLightning

29
app/components/Icon/Onchain.js

@ -0,0 +1,29 @@
import React from 'react'
const SvgOnchain = props => (
<svg viewBox="0 0 50 50" width="1em" height="1em" {...props}>
<defs>
<linearGradient id="c" x1="0%" y1="0%" y2="100%">
<stop offset="0%" stopColor="#FFBD59" />
<stop offset="100%" stopColor="#FD9800" />
</linearGradient>
</defs>
<g fill="none" fillRule="evenodd">
<circle cx={25} cy={25} r={25} fill="url(#c)" />
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
d="M23 26.675c.946 1.347 2.394 2.19 3.97 2.31 1.574.12 3.12-.494 4.237-1.684l3.265-3.477c2.063-2.275 2.033-5.89-.066-8.126-2.1-2.236-5.494-2.268-7.63-.07l-1.871 1.982"
/>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
d="M27 24.325c-.946-1.347-2.394-2.19-3.97-2.31-1.574-.12-3.12.494-4.237 1.684l-3.265 3.477c-2.063 2.275-2.033 5.89.066 8.126 2.1 2.236 5.494 2.268 7.63.07l1.86-1.982"
/>
</g>
</svg>
)
export default SvgOnchain

21
app/components/Icon/Spinner.js

@ -0,0 +1,21 @@
import React from 'react'
const SvgSpinner = props => (
<svg
xmlnsXlink="http://www.w3.org/1999/xlink"
viewBox="0 0 14 14"
width="1em"
height="1em"
{...props}
>
<defs>
<path
id="d"
d="M0 7a.778.778 0 1 1 1.556 0c0 1.464.58 2.835 1.594 3.85a5.444 5.444 0 1 0 1.766-8.881A.778.778 0 1 1 4.32.53 7 7 0 1 1 0 7z"
/>
</defs>
<use fill="currentColor" xlinkHref="#d" />
</svg>
)
export default SvgSpinner

21
app/components/Icon/Success.js

@ -0,0 +1,21 @@
import React from 'react'
const SvgSuccess = props => (
<svg
xmlnsXlink="http://www.w3.org/1999/xlink"
viewBox="0 0 17 17"
width="1em"
height="1em"
{...props}
>
<defs>
<path
id="a"
d="M8.333 16.667A8.333 8.333 0 1 1 8.333 0a8.333 8.333 0 0 1 0 16.667zM11.095 5.66l-4.41 4.41-1.513-1.51a.833.833 0 1 0-1.179 1.178l2.101 2.101a.833.833 0 0 0 1.179 0l5-5a.833.833 0 0 0-1.179-1.178z"
/>
</defs>
<use fill="currentColor" fillRule="evenodd" xlinkHref="#a" />
</svg>
)
export default SvgSuccess

6
app/components/Icon/SystemError.js

@ -1,6 +0,0 @@
import React from 'react'
import FaTimesCircle from 'react-icons/lib/fa/times-circle'
const SystemIcon = props => <FaTimesCircle {...props} />
export default SystemIcon

6
app/components/Icon/SystemSuccess.js

@ -1,6 +0,0 @@
import React from 'react'
import FaCheckCircle from 'react-icons/lib/fa/check-circle'
const SystemIcon = props => <FaCheckCircle {...props} />
export default SystemIcon

0
app/components/Icon/SystemWarning.js → app/components/Icon/Warning.js

25
app/components/Icon/X.js

@ -2,18 +2,27 @@ import React from 'react'
const SvgX = props => (
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
className="feather feather-x"
xmlnsXlink="http://www.w3.org/1999/xlink"
viewBox="0 0 22 20"
width="1em"
height="1em"
{...props}
>
<path d="M18 6L6 18M6 6l12 12" />
<defs>
<path
id="a"
d="M10 10L0 20l10-10L0 0l10 10L20 0l-8.394 8.394L10 10l1.606 1.606L20 20 10 10z"
/>
</defs>
<use
fill="none"
fillRule="evenodd"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
transform="translate(1)"
xlinkHref="#a"
/>
</svg>
)

8
app/components/Onboarding/ConnectionConfirm/ConnectionConfirm.js

@ -6,14 +6,12 @@ import styles from './ConnectionConfirm.scss'
const ConnectionConfirm = ({ connectionHost }) => (
<div className={styles.container}>
<p>
<h2>
<FormattedMessage {...messages.verify_host_title} />{' '}
<span className={styles.host}>{connectionHost.split(':')[0]}</span>?{' '}
</p>
</h2>
<p>
<strong>
<FormattedMessage {...messages.verify_host_description} />
</strong>
<FormattedMessage {...messages.verify_host_description} />
</p>
</div>
)

8
app/components/Onboarding/ConnectionConfirm/ConnectionConfirm.scss

@ -3,12 +3,10 @@
.container {
color: var(--primaryText);
p {
h2 {
font-size: 16px;
margin-bottom: 20px;
}
strong {
font-weight: bold;
font-weight: 300;
}
.host {

2
app/components/Onboarding/ConnectionType/ConnectionType.scss

@ -7,8 +7,8 @@
margin: 0;
display: flex;
align-items: center;
font-weight: 200;
line-height: 20px;
font-size: 16px;
.description {
width: 80%;

2
app/components/Onboarding/FormContainer/FormContainer.js

@ -6,7 +6,7 @@ import FaAngleLeft from 'react-icons/lib/fa/angle-left'
import FaAngleRight from 'react-icons/lib/fa/angle-right'
import ZapLogo from 'components/Icon/ZapLogo'
import ZapLogoBlack from 'components/Icon/ZapLogoBlack'
import { Button } from 'components/UI'
import Button from 'components/UI/Button'
import messages from './messages'
import styles from './FormContainer.scss'

3
app/components/Onboarding/Login/Login.js

@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import { FormattedMessage, injectIntl } from 'react-intl'
import { Button } from 'components/UI'
import Button from 'components/UI/Button'
import messages from './messages'
import styles from './Login.scss'
@ -37,7 +37,6 @@ const Login = ({
disabled={!passwordIsValid || unlockingWallet}
onClick={() => unlockWallet(password)}
processing={unlockingWallet}
size="large"
>
{unlockingWallet ? (
<FormattedMessage {...messages.unlocking} />

1
app/components/Onboarding/Signup/Signup.scss

@ -40,7 +40,6 @@
padding: 20px;
border: 1px solid var(--primaryText);
border-radius: 5px;
font-weight: 200;
cursor: pointer;
transition: all 0.25s;
}

2
app/components/UI/BackgroundDark.js

@ -9,7 +9,7 @@ import { Box } from 'rebass'
*/
class BackgroundDark extends React.Component {
render() {
return <Box bg="darkestBackground" color="white" {...this.props} />
return <Box bg="darkestBackground" color="primaryText" {...this.props} />
}
}

2
app/components/UI/BackgroundLight.js

@ -9,7 +9,7 @@ import { Box } from 'rebass'
*/
class BackgroundLight extends React.Component {
render() {
return <Box bg="lightBackground" color="white" {...this.props} />
return <Box bg="lightBackground" color="primaryText" {...this.props} />
}
}

2
app/components/UI/BackgroundLightest.js

@ -9,7 +9,7 @@ import { Box } from 'rebass'
*/
class BackgroundLightest extends React.Component {
render() {
return <Box bg="lightestBackground" color="white" {...this.props} />
return <Box bg="lightestBackground" color="primaryText" {...this.props} />
}
}

14
app/components/UI/Bar.js

@ -1,5 +1,5 @@
import React from 'react'
import { Box } from 'rebass'
import { Card } from 'rebass'
/**
* @render react
@ -9,7 +9,17 @@ import { Box } from 'rebass'
*/
class Bar extends React.PureComponent {
render() {
return <Box width={1} bg="white" css={{ height: '1px' }} {...this.props} as="hr" />
return (
<Card
width={1}
{...this.props}
borderColor="primaryText"
opacity={0.6}
border={1}
css={{ 'border-bottom': 'none !important' }}
as="hr"
/>
)
}
}

39
app/components/UI/Button.js

@ -8,7 +8,7 @@ const Wrapper = styled(BaseButton)`
transition: all 0.25s;
outline: none;
border-radius: 5;
font-weight: normal;
font-weight: 300;
line-height: '18px';
&:disabled {
opacity: 0.5;
@ -34,43 +34,38 @@ class Button extends React.PureComponent {
}
static propTypes = {
processing: PropTypes.bool,
size: PropTypes.oneOf(['small', 'medium', 'large']),
size: PropTypes.oneOf(['small', 'medium']),
variant: PropTypes.string
}
render() {
const { children, processing, size, ...rest } = this.props
let { children, processing, size, ...rest } = this.props
const sizes = {
small: {
x: 3,
y: 2,
fontSize: 's'
y: 2
},
medium: {
x: 3,
y: 2,
fontSize: 'm'
},
large: {
x: 5,
y: 3,
fontSize: 'l'
y: 3
}
}
size = sizes[size] || sizes['medium']
return (
<Wrapper
px={sizes[size]['x']}
py={sizes[size]['y']}
fontSize={sizes[size]['fontSize']}
{...rest}
>
<Wrapper px={size['x']} py={size['y']} {...rest}>
{processing ? (
<Flex>
{processing && <Spinner size="2em" mr="0.5em" />}
<Text fontFamily="sans">{children}</Text>
<Flex alignItems="center">
{processing && <Spinner />}
<Text fontWeight="normal" fontFamily="sans" ml={2}>
{children}
</Text>
</Flex>
) : (
<Text fontFamily="sans">{children}</Text>
<Text fontWeight="normal" fontFamily="sans">
{children}
</Text>
)}
</Wrapper>
)

23
app/components/UI/Dropdown.js

@ -35,8 +35,7 @@ const DropdownButton = styled(Box)({
DropdownButton.defaultProps = {
as: 'button',
m: 0,
px: 0,
py: 2,
p: 0,
textAlign: 'left'
}
@ -60,6 +59,7 @@ const Menu = styled(Box)({
Menu.defaultProps = {
as: 'ul',
m: 0,
mt: 1,
p: 0,
bg: 'lightestBackground'
}
@ -99,12 +99,7 @@ class Dropdown extends React.Component {
static propTypes = {
activeKey: PropTypes.string.isRequired,
items: PropTypes.arrayOf(
PropTypes.shape({
key: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
})
).isRequired,
items: PropTypes.array.isRequired,
onChange: PropTypes.func
}
@ -143,7 +138,17 @@ class Dropdown extends React.Component {
render() {
const { isOpen } = this.state
const { activeKey, items, theme, ...rest } = this.props
let { activeKey, items, theme, ...rest } = this.props
// coerce array of strings into array of objects.
items = items.map(item => {
if (typeof item === 'string') {
return {
name: item,
key: item
}
}
return item
})
const selectedItem = items.find(c => c.key === activeKey)
return (
<DropdownContainer ref={this.setWrapperRef} {...rest}>

22
app/components/UI/FormFieldMessage.js

@ -1,9 +1,9 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Box, Flex } from 'rebass'
import SystemSuccess from 'components/Icon/SystemSuccess'
import SystemWarning from 'components/Icon/SystemWarning'
import SystemError from 'components/Icon/SystemError'
import { Box, Flex, Text } from 'rebass'
import Success from 'components/Icon/Success'
import Warning from 'components/Icon/Warning'
import Error from 'components/Icon/Error'
import styled from 'styled-components'
import { variant } from 'styled-system'
@ -26,15 +26,17 @@ class FormFieldMessage extends React.Component {
}
render() {
const { children, variant } = this.props
const { children, variant, ...rest } = this.props
return (
<Message {...this.props} variant={variant}>
<Message {...rest} variant={variant} alignItems="center">
<Box mr={1}>
{variant === 'success' && <SystemSuccess />}
{variant === 'warning' && <SystemWarning />}
{variant === 'error' && <SystemError />}
{variant === 'success' && <Success />}
{variant === 'warning' && <Warning />}
{variant === 'error' && <Error />}
</Box>
{children}
<Text fontSize="s" fontWeight="normal">
{children}
</Text>
</Message>
)
}

251
app/components/UI/GlobalStyle.js

@ -1,20 +1,271 @@
import { createGlobalStyle } from 'styled-components'
import reset from 'styled-reset'
/* eslint-disable max-len */
const GlobalStyle = createGlobalStyle`
/* stylelint-disable font-family-no-missing-generic-family-keyword */
${reset}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fBBc4AMP6lQ.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
position: relative;
overflow-y: hidden;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
font-family: 'Roboto', Arial, Helvetica, sans-serif;
font-weight: 300;
font-size: 13px;
}
.element-show {
display: inherit;
}
.element-hide {
display: none;
}
/*
*Tooltips
*/
[data-hint] {
position: relative;
}
[data-hint]::before,
[data-hint]::after {
position: absolute;
will-change: transform;
visibility: hidden;
opacity: 0;
z-index: 999;
pointer-events: none;
transition: 0.2s ease;
transition-delay: 0ms;
}
[data-hint]::before {
content: '';
position: absolute;
background: transparent;
border: 6px solid transparent;
z-index: 999;
}
[data-hint]::after {
content: attr(data-hint);
background: ${props => props.theme.colors.lightestBackground};
color: ${props => props.theme.colors.primaryText};
border: 1px solid ${props => props.theme.colors.gray};
border-radius: 3px;
max-width: 260px;
line-height: 1.4;
padding: 6px 10px;
word-wrap: break-word;
box-shadow: 0 3px 4px 0 rgba(30, 30, 30, 0.5), 0 2px 4px 0 rgba(0, 0, 0, 0.5);
}
[data-hint]:hover::before,
[data-hint]:hover::after {
visibility: visible;
opacity: 1;
}
.hint--bottom::before,
.hint--bottom-left::before {
border-bottom-color: #404040;
}
.hint--top::before,
.hint--top-left::before {
border-top-color: #404040;
}
.hint--bottom::before {
margin-top: -12px;
}
.hint--bottom::after {
margin-left: -18px;
}
.hint--bottom::before,
.hint--bottom::after {
top: 100%;
left: 50%;
}
.hint--bottom:hover::after,
.hint--bottom:hover::before {
transform: translateY(8px);
}
.hint--top::before {
margin-bottom: -12px;
}
.hint--top::after {
margin-left: -18px;
}
.hint--top::before,
.hint--top::after {
bottom: 100%;
left: 50%;
}
.hint--top:hover::after,
.hint--top:hover::before {
transform: translateY(-8px);
}
.hint--top-left::before {
margin-bottom: -12px;
}
.hint--top-left::after {
margin-right: -6px;
}
.hint--top-left::before,
.hint--top-left::after {
bottom: 100%;
right: 12px;
}
.hint--top-left:hover::after,
.hint--top-left:hover::before {
transform: translateY(-8px);
}
.hint--bottom-left::before {
margin-top: -12px;
}
.hint--bottom-left::after {
margin-right: -6px;
}
.hint--bottom-left::before,
.hint--bottom-left::after {
top: 100%;
right: 12px;
}
.hint--bottom-left:hover::after,
.hint--bottom-left:hover::before {
transform: translateY(8px);
}
.hint--left::before {
margin-right: -12px;
margin-top: -6px;
}
.hint--left::after {
margin-right: -14px;
}
.hint--left::before,
.hint--left::after {
right: 100%;
bottom: 50%;
}
.hint--left:hover::after,
.hint--left:hover::before {
transform: translateX(-8px);
}
/*
*Animated Checkmark
*/
.checkmark__circle {
stroke-dasharray: 166;
stroke-dashoffset: 166;
stroke-width: 2;
stroke-miterlimit: 10;
stroke: ${props => props.theme.colors.superGreen};
fill: none;
animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
}
.checkmark {
width: 20px;
height: 20px;
border-radius: 50%;
stroke-width: 2;
stroke: #fff;
stroke-miterlimit: 10;
box-shadow: inset 0 0 0 ${props => props.theme.colors.superGreen};
animation: fill 0.4s ease-in-out 0.4s forwards, scale 0.3s ease-in-out 0.9s both;
}
.checkmark__check {
transform-origin: 50% 50%;
stroke-dasharray: 48;
stroke-dashoffset: 48;
animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;
}
@keyframes stroke {
100% {
stroke-dashoffset: 0;
}
}
@keyframes scale {
0%,
100% {
transform: none;
}
50% {
transform: scale3d(1.1, 1.1, 1);
}
}
@keyframes fill {
100% {
box-shadow: inset 0 0 0 30px ${props => props.theme.colors.superGreen};
}
}
/*
*Generic spin animation.
*/
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
`
export default GlobalStyle

11
app/components/UI/Heading.js

@ -11,7 +11,16 @@ class Heading extends React.PureComponent {
static displayName = 'Heading'
render() {
return <BaseHeading fontSize={5} as="h2" {...this.props} />
return (
<BaseHeading
as="h2"
lineHeight="1.4"
fontWeight="light"
fontSize={5}
color="primaryText"
{...this.props}
/>
)
}
}

2
app/components/UI/MenuItemGroup.js

@ -14,7 +14,7 @@ const SystemMenuItemGroup = system(
const StyledMenuItemGroup = styled(SystemMenuItemGroup)`
list-style-type: none;
> .rc-menu-item-group-title {
font-weight: bold;
font-weight: 400;
padding: ${props => props.theme.space[2]}px 0;
}
> .rc-menu-item-group-list {

44
app/components/UI/Modal.js

@ -1,7 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Box, Flex } from 'rebass'
import { BackgroundDark } from 'components/UI'
import X from 'components/Icon/X'
/**
@ -10,24 +9,47 @@ import X from 'components/Icon/X'
* @example
* <Modal>Some content</Modal>
*/
class Modal extends React.PureComponent {
class Modal extends React.Component {
static displayName = 'Modal'
static propTypes = {
children: PropTypes.node
children: PropTypes.node,
onClose: PropTypes.func
}
state = {
hover: false
}
hoverOn = () => {
this.setState({ hover: true })
}
hoverOff = () => {
this.setState({ hover: false })
}
render() {
const { children } = this.props
const { hover } = this.state
const { children, onClose } = this.props
return (
<Box css={{ height: '100vh' }}>
<BackgroundDark p={2} css={{ height: '100%' }}>
<Flex justifyContent="flex-end">
<Flex flexDirection="column" width={1} p={3} bg="darkestBackground" css={{ height: '100%' }}>
<Flex justifyContent="flex-end" as="header" color="primaryText">
<Box
css={{ cursor: 'pointer' }}
ml="auto"
onClick={onClose}
onMouseEnter={this.hoverOn}
onMouseLeave={this.hoverOff}
color={hover ? 'lightningOrange' : null}
>
<X width="2em" height="2em" />
</Flex>
<Box m={3}>{children}</Box>
</BackgroundDark>
</Box>
</Box>
</Flex>
<Box as="section" p={2} css={{ flex: 1 }}>
{children}
</Box>
</Flex>
)
}
}

26
app/components/UI/Notification.js

@ -2,9 +2,9 @@ import React from 'react'
import PropTypes from 'prop-types'
import { Card, Flex, Text } from 'rebass'
import X from 'components/Icon/X'
import SystemSuccess from 'components/Icon/SystemSuccess'
import SystemWarning from 'components/Icon/SystemWarning'
import SystemError from 'components/Icon/SystemError'
import Success from 'components/Icon/Success'
import Warning from 'components/Icon/Warning'
import Error from 'components/Icon/Error'
import Spinner from './Spinner'
/**
@ -57,14 +57,20 @@ class Notification extends React.Component {
onMouseLeave={this.hoverOff}
>
<Flex justifyContent="space-between">
<Flex>
{processing && <Spinner size="2em" mr="0.5em" />}
{!processing && variant === 'success' && <SystemSuccess />}
{!processing && variant === 'warning' && <SystemWarning />}
{!processing && variant === 'error' && <SystemError />}
<Text ml={2}>{children}</Text>
<Flex alignItems="center">
<Text fontSize="xl">
{processing && <Spinner size="2em" mr="0.5em" />}
{!processing && variant === 'success' && <Success />}
{!processing && variant === 'warning' && <Warning />}
{!processing && variant === 'error' && <Error />}
</Text>
<Text fontWeight="normal" ml={2}>
{children}
</Text>
</Flex>
<X strokeWidth={hover ? 2 : null} />
<Text fontSize="xs">
<X strokeWidth={hover ? 5 : 4} />
</Text>
</Flex>
</Card>
)

21
app/components/UI/Page.js

@ -7,18 +7,21 @@ import { Flex } from 'rebass'
* @example
* <Page>Some content</Page>
*/
const Page = props => (
const Page = ({ css, ...rest }) => (
<Flex
{...props}
as="article"
alignItems="stretch"
bg="darkestBackground"
css={{
'min-height': '700px',
'min-width': '950px',
'overflow-y': 'hidden',
'box-shadow': '0 3px 4px 0 rgba(30, 30, 30, 0.5)'
}}
as="article"
css={Object.assign(
{
'min-width': '950px',
'min-height': '600px',
'overflow-y': 'hidden',
'box-shadow': '0 20px 70px rgba(0, 0, 0, 0.55)'
},
css
)}
{...rest}
/>
)

2
app/components/UI/Range.js

@ -20,7 +20,7 @@ const Input = styled.input`
appearance: none;
height: 8px;
cursor: ew-resize;
background: ${props => props.theme.colors.white};
background: ${props => props.theme.colors.primaryText};
box-shadow: -1000px 0 0 1000px orange;
}
`

2
app/components/UI/Select.js

@ -138,7 +138,7 @@ class Select extends React.PureComponent {
style={{
backgroundColor:
highlightedIndex === index ? theme.colors.lightningOrange : null,
fontWeight: selectedItem === item ? 'bold' : 'normal'
fontWeight: selectedItem === item ? 'normal' : 'light'
}}
>
{item.label || item.value}

6
app/components/UI/Sidebar.js

@ -1,5 +1,5 @@
import React from 'react'
import { BackgroundLightest } from 'components/UI'
import { BackgroundLight } from 'components/UI'
/**
* @render react
@ -7,9 +7,7 @@ import { BackgroundLightest } from 'components/UI'
* @example
* <Sidebar>Some content</Sidebar>
*/
const Sidebar = props => (
<BackgroundLightest as="aside" p={3} css={{ height: '100%' }} width={4 / 12} {...props} />
)
const Sidebar = props => <BackgroundLight as="aside" p={3} width={4 / 12} {...props} />
Sidebar.small = props => <Sidebar {...props} width={3 / 12} />
Sidebar.medium = props => <Sidebar {...props} width={4 / 12} />

32
app/components/UI/Spinner.js

@ -1,5 +1,7 @@
import React from 'react'
import styled, { keyframes } from 'styled-components'
import { Card } from 'rebass'
import Spinner from 'components/Icon/Spinner'
import system from '@rebass/components'
const rotate360 = keyframes`
from {
@ -10,26 +12,28 @@ const rotate360 = keyframes`
}
`
const Wrapper = system(
{
color: 'lightningOrange'
},
'space',
'color'
)
/**
* @render react
* @name Spinner
* @example
* <Spinner />
*/
const Spinner = styled(Card)`
border: 1px solid rgba(235, 184, 100, 0.1);
border-left-color: rgba(235, 184, 100, 0.6);
display: inline-block;
const SpinningSpinner = styled(Spinner)`
animation: ${rotate360} 1s linear infinite;
`
Spinner.displayName = 'Spinner'
Spinner.defaultProps = {
borderRadius: 999,
width: '1em',
css: {
height: '1em'
}
}
const WrappedSpinner = props => (
<Wrapper {...props}>
<SpinningSpinner />
</Wrapper>
)
export default Spinner
export default WrappedSpinner

2
app/components/UI/Text.js

@ -18,7 +18,7 @@ class Text extends React.PureComponent {
render() {
const { children } = this.props
return (
<BaseText fontSize="m" {...this.props}>
<BaseText lineHeight="1.4" fontSize="m" color="primaryText" {...this.props}>
{children}
</BaseText>
)

13
app/components/Value/Value.js

@ -1,20 +1,23 @@
import React from 'react'
import PropTypes from 'prop-types'
import { btc } from 'lib/utils'
import { convert } from 'lib/utils/btc'
const Value = ({ value, currency, currentTicker, fiatTicker }) => {
if (currency === 'sats') {
return <i>{value > 0 ? value : value * -1}</i>
}
return <i>{btc.convert('sats', currency, value, currentTicker[fiatTicker].last)}</i>
let price
if (currency === 'fiat') {
price = currentTicker[fiatTicker].last
}
return <i>{convert('sats', currency, value, price)}</i>
}
Value.propTypes = {
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
currency: PropTypes.string.isRequired,
currentTicker: PropTypes.object.isRequired,
fiatTicker: PropTypes.string.isRequired
currentTicker: PropTypes.object,
fiatTicker: PropTypes.string
}
export default Value

1
app/components/Wallet/ReceiveModal/ReceiveModal.scss

@ -101,7 +101,6 @@
flex-direction: row;
align-items: center;
font-size: 10px;
font-weight: 200;
background: var(--lightestBackground);
.data,

64
app/components/Wallet/Wallet.js

@ -11,7 +11,6 @@ import CheckAnimated from 'components/Icon/CheckAnimated'
import ZapLogo from 'components/Icon/ZapLogo'
import ZapLogoBlack from 'components/Icon/ZapLogoBlack'
import Qrcode from 'components/Icon/Qrcode'
import { FormattedNumber, FormattedMessage } from 'react-intl'
import messages from './messages'
@ -70,43 +69,48 @@ const Wallet = ({
</Box>
</Flex>
<Flex as="header" justifyContent="space-between" mt={4}>
<Flex as="header" justifyContent="space-between" mt={5}>
<Box as="section">
<Flex alignItems="baseline">
<Box onClick={openReceiveModal} className={styles.qrCode} mr={2}>
<Qrcode width="20px" height="20px" />
<Flex alignItems="center">
<Box onClick={openReceiveModal} className={styles.qrCode} mr={3}>
<Qrcode width="21px" height="21px" />
</Box>
<Flex flexDirection="column">
<Text fontSize="24px" letterSpacing={2}>
<Value
value={parseFloat(balance.walletBalance) + parseFloat(balance.channelBalance)}
currency={ticker.currency}
currentTicker={currentTicker}
fiatTicker={ticker.fiatTicker}
<Box>
<Flex alignItems="baseline">
<Text fontSize="xxl">
<Value
value={parseFloat(balance.walletBalance) + parseFloat(balance.channelBalance)}
currency={ticker.currency}
currentTicker={currentTicker}
fiatTicker={ticker.fiatTicker}
/>
</Text>
<Dropdown
activeKey={ticker.currency}
items={currencyFilters}
onChange={setCurrency}
ml={1}
/>
</Text>
</Flex>
<Dropdown
activeKey={ticker.currency}
items={currencyFilters}
onChange={setCurrency}
ml={2}
/>
</Flex>
{Boolean(fiatAmount) && (
<Text color="gray">
{'≈ '}
<FormattedNumber
currency={ticker.fiatTicker}
style="currency"
value={fiatAmount}
/>
</Text>
)}
</Box>
</Flex>
<Box ml={30} mt={1}>
{Boolean(fiatAmount) && (
<span>
{'≈ '}
<FormattedNumber currency={ticker.fiatTicker} style="currency" value={fiatAmount} />
</span>
)}
</Box>
</Box>
<Box as="section">
<Button onClick={openPayForm} variant="primary" mx={7.5} width={100}>
<Button onClick={openPayForm} mr={2} width={145}>
<FormattedMessage {...messages.pay} />
</Button>
<Button onClick={openRequestForm} variant="primary" mx={7.5} width={100}>
<Button onClick={openRequestForm} width={145}>
<FormattedMessage {...messages.request} />
</Button>
</Box>

4
app/components/Wallet/Wallet.scss

@ -1,9 +1,9 @@
@import 'styles/variables.scss';
.wallet {
background: var(--lightBackground);
background: var(--lightestBackground);
color: var(--primaryText);
height: 180px;
height: 200px;
padding: 20px 40px;
}

3
app/containers/App.js

@ -5,7 +5,7 @@ import get from 'lodash.get'
import { btc } from 'lib/utils'
import { themeSelectors } from 'reducers/theme'
import { setCurrency, tickerSelectors, fetchTicker } from 'reducers/ticker'
import { setCurrency, tickerSelectors } from 'reducers/ticker'
import { closeWalletModal } from 'reducers/address'
import { fetchInfo, infoSelectors } from 'reducers/info'
import { setFormType } from 'reducers/form'
@ -68,7 +68,6 @@ const mapDispatchToProps = {
fetchBalance,
fetchChannels,
fetchSuggestedNodes,
fetchTicker,
openChannel,
closeChannel,
toggleFilterPulldown,

15
app/containers/Root.js

@ -9,6 +9,7 @@ import { clearError, errorSelectors } from 'reducers/error'
import { loadingSelectors, setLoading, setMounted } from 'reducers/loading'
import { initCurrency, initLocale } from 'reducers/locale'
import { initTheme, themeSelectors } from 'reducers/theme'
import { fetchTicker, tickerSelectors } from 'reducers/ticker'
import { Page, Titlebar, GlobalStyle } from 'components/UI'
import GlobalError from 'components/GlobalError'
@ -29,8 +30,10 @@ const SPLASH_SCREEN_TIME = 1500
class Root extends React.Component {
static propTypes = {
clearError: PropTypes.func.isRequired,
currentTicker: PropTypes.object,
theme: PropTypes.object,
error: PropTypes.string,
fetchTicker: PropTypes.func.isRequired,
history: PropTypes.object.isRequired,
initLocale: PropTypes.func.isRequired,
initCurrency: PropTypes.func.isRequired,
@ -56,13 +59,16 @@ class Root extends React.Component {
*/
componentDidMount() {
const {
currentTicker,
fetchTicker,
initLocale,
initCurrency,
initTheme,
isLoading,
isMounted,
setLoading,
setMounted
setMounted,
theme
} = this.props
// If this is the first time the app has mounted, initialise things.
@ -71,10 +77,11 @@ class Root extends React.Component {
initTheme()
initLocale()
initCurrency()
fetchTicker()
}
// Hide the loading screen after a set time.
if (isLoading) {
if (isLoading || !currentTicker || !theme) {
const timer = setTimeout(() => setLoading(false), SPLASH_SCREEN_TIME)
this.setState({ timer })
}
@ -91,7 +98,7 @@ class Root extends React.Component {
render() {
const { clearError, theme, error, history, isLoading } = this.props
// Wait until we have determined the user's theme preference before displaying the app.
// Wait until we have loaded essential data before displaying anything..
if (!theme) {
return null
}
@ -119,6 +126,7 @@ class Root extends React.Component {
}
const mapStateToProps = state => ({
currentTicker: tickerSelectors.currentTicker(state),
theme: themeSelectors.currentThemeSettings(state),
error: errorSelectors.getErrorState(state),
isLoading: loadingSelectors.isLoading(state),
@ -127,6 +135,7 @@ const mapStateToProps = state => ({
const mapDispatchToProps = {
clearError,
fetchTicker,
initCurrency,
initLocale,
initTheme,

5
app/icons/big-arrow-left.svg

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="12" viewBox="0 0 16 12">
<g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path d="M1 6h14M6.526 11L1 6l5.526-5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 258 B

6
app/icons/big-arrow-right.svg

@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 9 4">
<g fill="none" fill-rule="evenodd" stroke="#FFF" stroke-linecap="round" stroke-linejoin="round">
<path d="M1 2h6M6 4l2-2-2-2"/>
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="28" viewBox="0 0 40 28">
<g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path d="M1 14h38M24 27l15-13L24 1"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 238 B

After

Width:  |  Height:  |  Size: 255 B

6
app/icons/close.svg

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 10 10">
<g fill="#E63939" fill-rule="evenodd">
<path d="M7.744 1.077a.833.833 0 1 1 1.179 1.179L2.256 8.923a.833.833 0 1 1-1.179-1.179l6.667-6.667z"/>
<path d="M1.077 2.256a.833.833 0 1 1 1.179-1.179l6.667 6.667a.833.833 0 1 1-1.179 1.179L1.077 2.256z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 367 B

3
app/icons/error.svg

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" viewBox="0 0 17 17">
<path fill="#E63939" fill-rule="evenodd" d="M9.512 8.333l1.91-1.91a.833.833 0 0 0-1.178-1.179l-1.91 1.91-1.911-1.91a.833.833 0 1 0-1.179 1.179l1.91 1.91-1.91 1.911a.833.833 0 1 0 1.179 1.179l1.91-1.911 1.911 1.91a.833.833 0 0 0 1.179-1.178l-1.911-1.91zm-1.179 8.334A8.333 8.333 0 1 1 8.333 0a8.333 8.333 0 0 1 0 16.667z"/>
</svg>

After

Width:  |  Height:  |  Size: 418 B

12
app/icons/lightning.svg

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 50 50">
<defs>
<linearGradient id="b" x1="0%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#FFBD59"/>
<stop offset="100%" stop-color="#FD9800"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<circle cx="25" cy="25" r="25" fill="url(#b)"/>
<path fill="#FFF" fill-rule="nonzero" d="M22.999 39.764l.708-3.28 1.26-5.827.53-2.454c.044-.207-.094-.415-.316-.415h-7.85l.283.493 1.218-1.865 2.875-4.4 3.358-5.139 2.669-4.085.852-1.305-.599-.253-.709 3.28-1.259 5.824-.53 2.453c-.045.207.094.415.316.415h7.865l-.284-.493-1.22 1.866-2.878 4.4-3.362 5.141-2.673 4.086-.854 1.306c-.232.355.336.683.567.33l1.22-1.865 2.878-4.4 3.362-5.141 2.672-4.087.854-1.305c.138-.212-.044-.493-.283-.493H25.805l.316.414.71-3.28 1.258-5.824.53-2.453c.08-.365-.393-.567-.599-.252l-1.218 1.865-2.875 4.4-3.357 5.139-2.67 4.085-.852 1.305c-.138.212.044.493.283.493H25.18l-.317-.414-.709 3.28-1.259 5.827-.53 2.454c-.089.412.543.587.633.174z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

13
app/icons/onchain.svg

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 50 50">
<defs>
<linearGradient id="a" x1="0%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#FFBD59"/>
<stop offset="100%" stop-color="#FD9800"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<circle cx="25" cy="25" r="25" fill="url(#a)"/>
<path stroke="#FFF" stroke-linecap="round" stroke-linejoin="round" d="M23 26.675c.946 1.347 2.394 2.19 3.97 2.31 1.574.12 3.12-.494 4.237-1.684l3.265-3.477c2.063-2.275 2.033-5.89-.066-8.126-2.1-2.236-5.494-2.268-7.63-.07l-1.871 1.982"/>
<path stroke="#FFF" stroke-linecap="round" stroke-linejoin="round" d="M27 24.325c-.946-1.347-2.394-2.19-3.97-2.31-1.574-.12-3.12.494-4.237 1.684l-3.265 3.477c-2.063 2.275-2.033 5.89.066 8.126 2.1 2.236 5.494 2.268 7.63.07l1.86-1.982"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 900 B

6
app/icons/spinner.svg

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="14" viewBox="0 0 14 14">
<defs>
<path id="c" d="M0 7a.778.778 0 1 1 1.556 0c0 1.464.58 2.835 1.594 3.85a5.444 5.444 0 1 0 1.766-8.881A.778.778 0 1 1 4.32.53 7 7 0 1 1 0 7z"/>
</defs>
<use fill="currentColor" fill-rule="nonzero" xlink:href="#c"/>
</svg>

After

Width:  |  Height:  |  Size: 375 B

6
app/icons/success.svg

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17" height="17" viewBox="0 0 17 17">
<defs>
<path id="a" d="M8.333 16.667A8.333 8.333 0 1 1 8.333 0a8.333 8.333 0 0 1 0 16.667zM11.095 5.66l-4.41 4.41L5.172 8.56a.833.833 0 1 0-1.179 1.178l2.101 2.101a.833.833 0 0 0 1.179 0l5-5a.833.833 0 0 0-1.179-1.178z"/>
</defs>
<use fill="#39E673" fill-rule="evenodd" xlink:href="#a"/>
</svg>

After

Width:  |  Height:  |  Size: 442 B

7
app/icons/x.svg

@ -1 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="22" height="20" viewBox="0 0 22 20">
<defs>
<path id="a" d="M10 10L0 20l10-10L0 0l10 10L20 0l-8.394 8.394L10 10l1.606 1.606L20 20 10 10z"/>
</defs>
<use fill="none" fill-rule="evenodd" stroke="#FFF" stroke-linecap="round" stroke-linejoin="round" transform="translate(1)" xlink:href="#a"/>
</svg>

Before

Width:  |  Height:  |  Size: 299 B

After

Width:  |  Height:  |  Size: 406 B

2
app/reducers/lnd.js

@ -1,7 +1,6 @@
import { createSelector } from 'reselect'
import { showNotification } from 'lib/utils/notifications'
import db from 'store/db'
import { fetchTicker } from './ticker'
import { fetchBalance } from './balance'
import { fetchInfo, setHasSynced, infoSelectors } from './info'
import { lndWalletStarted, lndWalletUnlockerStarted } from './onboarding'
@ -55,7 +54,6 @@ export const lndSyncStatus = (event, status) => async (dispatch, getState) => {
dispatch(setHasSynced(true))
// Fetch data now that we know LND is synced
dispatch(fetchTicker())
dispatch(fetchBalance())
dispatch(fetchInfo())

52
app/styles/animated_checkmark.scss

@ -1,52 +0,0 @@
$curve: cubic-bezier(0.65, 0, 0.45, 1);
.checkmark__circle {
stroke-dasharray: 166;
stroke-dashoffset: 166;
stroke-width: 2;
stroke-miterlimit: 10;
stroke: $green;
fill: none;
animation: stroke 0.6s $curve forwards;
}
.checkmark {
width: 20px;
height: 20px;
border-radius: 50%;
stroke-width: 2;
stroke: #fff;
stroke-miterlimit: 10;
box-shadow: inset 0 0 0 $green;
animation: fill 0.4s ease-in-out 0.4s forwards, scale 0.3s ease-in-out 0.9s both;
}
.checkmark__check {
transform-origin: 50% 50%;
stroke-dasharray: 48;
stroke-dashoffset: 48;
animation: stroke 0.3s $curve 0.8s forwards;
}
@keyframes stroke {
100% {
stroke-dashoffset: 0;
}
}
@keyframes scale {
0%,
100% {
transform: none;
}
50% {
transform: scale3d(1.1, 1.1, 1);
}
}
@keyframes fill {
100% {
box-shadow: inset 0 0 0 30px $green;
}
}

97
app/styles/app.global.scss

@ -1,98 +1 @@
@import '~font-awesome/css/font-awesome.css';
@import 'reset.scss';
@import 'variables.scss';
@import 'tooltip.scss';
@import 'animated_checkmark.scss';
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'),
url(https://fonts.gstatic.com/s/roboto/v15/Fl4y0QdOxyyTHEGMXX8kcaCWcynf_cDxXwCLxiixG1c.ttf)
format('truetype');
}
body {
font-family: 'Roboto', Arial, Helvetica, sans-serif;
}
// disable the pinball scrollers for windows
*,
input[type='text'],
input[type='number'] {
&::-webkit-inner-spin-button,
&::-webkit-outer-spin-button {
-webkit-appearance: none;
}
}
.load-draw-svg {
stroke-dasharray: 211;
stroke-dashoffset: 2110;
stroke-width: 2;
stroke-linecap: round;
animation: dash 15s linear infinite;
fill-opacity: 0;
stroke: $main;
}
@keyframes dash {
0% {
stroke-dashoffset: 2110;
opacity: 1;
stroke: $main;
}
15% {
opacity: 1;
stroke: $main;
}
70% {
opacity: 1;
stroke: $main;
}
100% {
stroke-dashoffset: 0;
opacity: 1;
stroke: darken($main, 10%);
}
}
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
// network
@keyframes dash {
to {
stroke-dashoffset: 1000;
}
}
// each node in the map
// .network-node {
//
// }
// each channel in the map
.network-link {
opacity: 0.6;
}
.active-peer {
fill: #5589f3;
}
.active-channel {
opacity: 1;
stroke: #88d4a2;
stroke-width: 15;
stroke-dasharray: 100;
animation: dash 2.5s infinite linear;
}

47
app/styles/keyframes.scss

@ -1,47 +0,0 @@
@import 'variables';
@keyframes fadeinOutD6 {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(6deg);
}
100% {
transform: rotate(0deg);
}
}
@keyframes fadeinOutD13 {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(13deg);
}
100% {
transform: rotate(0deg);
}
}
@keyframes colorchange {
0% { color: $white; }
25% { color: $gold; }
50% { color: $white; }
75% { color: $gold; }
100% { color: $white; }
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

48
app/styles/reset.scss

@ -1,48 +0,0 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

162
app/styles/tooltip.scss

@ -1,162 +0,0 @@
@import 'styles/variables.scss';
/* Tooltips */
[data-hint] {
position: relative;
// display: inline-block;
}
[data-hint]::before,
[data-hint]::after {
position: absolute;
will-change: transform;
visibility: hidden;
opacity: 0;
z-index: z('tooltip', 'after');
pointer-events: none;
transition: 0.2s ease;
transition-delay: 0ms;
}
[data-hint]::before {
content: '';
position: absolute;
background: transparent;
border: 6px solid transparent;
z-index: z('tooltip', 'before');
}
[data-hint]::after {
content: attr(data-hint);
background: #404040;
color: #e0e0e0;
text-shadow: 0 -1px 0 black;
padding: 8px 10px;
line-height: 12px;
white-space: nowrap;
border-radius: 2px;
box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);
letter-spacing: normal;
font-size: 12px;
font-weight: normal;
font-style: inherit;
font-family: 'Noto Sans', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, Sans-Serif;
}
[data-hint]:hover::before,
[data-hint]:hover::after {
visibility: visible;
opacity: 1;
}
.hint--bottom::before,
.hint--bottom-left::before {
border-bottom-color: #404040;
}
.hint--top::before,
.hint--top-left::before {
border-top-color: #404040;
}
.hint--bottom::before {
margin-top: -12px;
}
.hint--bottom::after {
margin-left: -18px;
}
.hint--bottom::before,
.hint--bottom::after {
top: 100%;
left: 50%;
}
.hint--bottom:hover::after,
.hint--bottom:hover::before {
-webkit-transform: translateY(8px);
transform: translateY(8px);
}
.hint--top::before {
margin-bottom: -12px;
}
.hint--top::after {
margin-left: -18px;
}
.hint--top::before,
.hint--top::after {
bottom: 100%;
left: 50%;
}
.hint--top:hover::after,
.hint--top:hover::before {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
}
.hint--top-left::before {
margin-bottom: -12px;
}
.hint--top-left::after {
margin-right: -6px;
}
.hint--top-left::before,
.hint--top-left::after {
bottom: 100%;
right: 30%;
}
.hint--top-left:hover::after,
.hint--top-left:hover::before {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
}
.hint--bottom-left::before {
margin-top: -12px;
}
.hint--bottom-left::after {
margin-right: -6px;
}
.hint--bottom-left::before,
.hint--bottom-left::after {
top: 100%;
right: 30%;
}
.hint--bottom-left:hover::after,
.hint--bottom-left:hover::before {
-webkit-transform: translateY(8px);
transform: translateY(8px);
}
.hint--left::before {
margin-right: -12px;
margin-top: -6px;
}
.hint--left::after {
margin-right: -14px;
}
.hint--left::before,
.hint--left::after {
right: 100%;
bottom: 50%;
}
.hint--left:hover::after,
.hint--left:hover::before {
-webkit-transform: translateX(-8px);
transform: translateX(-8px);
}

11
app/themes/base.js

@ -1,4 +1,4 @@
export const space = [0, 4, 8, 16, 32, 64, 128, 256]
export const space = [0, 4, 8, 16, 32, 45, 72, 108]
export const palette = {
white: '#ffffff',
@ -35,14 +35,13 @@ fontSizes[6] = fontSizes['xxl']
fontSizes[7] = fontSizes['xxxl']
export const fontWeights = {
normal: 400,
bold: 600
light: 300,
normal: 400
}
export const fonts = {
0: '"Roboto Light", Roboto, system-ui, sans-serif',
sans: '"Roboto Light", Roboto, system-ui, sans-serif',
mono: '"SF Mono", "Roboto Mono", Menlo, monospace'
0: 'Roboto, system-ui, sans-serif',
sans: 'Roboto, system-ui, sans-serif'
}
export const letterSpacings = {

7
app/themes/dark.js

@ -27,13 +27,14 @@ const buttons = {
color: colors.white
},
secondary: {
opacity: 0.6,
backgroundColor: 'transparent',
color: colors.white,
color: colors.primaryText,
'&:hover:enabled': {
color: colors.lightningOrange
opacity: 1
},
'&:focus': {
color: colors.lightningOrange
opacity: 1
}
}
}

7
app/themes/light.js

@ -27,13 +27,14 @@ const buttons = {
color: colors.white
},
secondary: {
opacity: 0.6,
backgroundColor: 'transparent',
color: colors.lightningOrange,
color: colors.primaryText,
'&:hover:enabled': {
color: colors.black
opacity: 1
},
'&:focus': {
color: colors.black
opacity: 1
}
}
}

34
internals/webpack/webpack.config.base.js

@ -20,6 +20,7 @@ export default {
module: {
rules: [
// JSX
{
test: /\.jsx?$/,
exclude: /node_modules/,
@ -29,6 +30,39 @@ export default {
cacheDirectory: true
}
}
},
// WOFF Font
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// WOFF2 Font
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// TTF Font
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream'
}
}
}
]
},

69
internals/webpack/webpack.config.renderer.dev.dll.js

@ -25,37 +25,6 @@ export default merge.smart(baseConfig, {
*/
module: {
rules: [
{
test: /\.global\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /^((?!\.global).)*\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
importLoaders: 1,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
}
]
},
// Add SASS support - compile all .global.scss files and pipe it to style.css
{
test: /\.global\.scss$/,
@ -101,44 +70,6 @@ export default merge.smart(baseConfig, {
}
]
},
// WOFF Font
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// WOFF2 Font
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// TTF Font
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream'
}
}
},
// EOT Font
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader'
},
// SVG Font
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,

72
internals/webpack/webpack.config.renderer.dev.js

@ -13,7 +13,6 @@ import webpack from 'webpack'
import merge from 'webpack-merge'
import { spawn, execSync } from 'child_process'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import CopyWebpackPlugin from 'copy-webpack-plugin'
import AddAssetHtmlPlugin from 'add-asset-html-webpack-plugin'
import CspHtmlWebpackPlugin from 'csp-html-webpack-plugin'
import baseConfig, { rootDir } from './webpack.config.base'
@ -64,27 +63,6 @@ export default merge.smart(baseConfig, {
}
}
},
// Extract all .global.css to style.css as is
{
test: /\.global\.css$/,
use: ['style-loader']
},
// Pipe other styles through css modules and append to style.css
{
test: /^((?!\.global).)*\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
importLoaders: 1,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
}
]
},
// Add SASS support - compile all .global.scss files and pipe it to style.css
{
test: /\.global\.scss$/,
@ -128,44 +106,6 @@ export default merge.smart(baseConfig, {
}
]
},
// WOFF Font
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// WOFF2 Font
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// TTF Font
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream'
}
}
},
// EOT Font
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader'
},
// SVG Font
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
@ -196,8 +136,6 @@ export default merge.smart(baseConfig, {
debug: true
}),
new CopyWebpackPlugin([path.join('app', 'empty.html')]),
new HtmlWebpackPlugin({
template: path.join('app', 'app.html')
}),
@ -224,18 +162,10 @@ export default merge.smart(baseConfig, {
"'self'",
'data:',
'http://localhost:*',
'https://fonts.googleapis.com',
'https://s3.amazonaws.com',
'https://fonts.gstatic.com'
],
'style-src': [
"'self'",
'blob:',
'https://fonts.googleapis.com',
'https://s3.amazonaws.com',
'https://fonts.gstatic.com',
"'unsafe-inline'"
]
'style-src': ["'self'", 'blob:', 'https://s3.amazonaws.com', "'unsafe-inline'"]
})
],

78
internals/webpack/webpack.config.renderer.prod.js

@ -5,7 +5,6 @@
import path from 'path'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import CopyWebpackPlugin from 'copy-webpack-plugin'
import CspHtmlWebpackPlugin from 'csp-html-webpack-plugin'
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
import CleanWebpackPlugin from 'clean-webpack-plugin'
@ -33,26 +32,6 @@ export default merge.smart(baseConfig, {
module: {
rules: [
// Extract all .global.css to style.css as is
{
test: /\.global\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
// Pipe other styles through css modules and append to style.css
{
test: /^((?!\.global).)*\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
}
]
},
// Add SASS support - compile all .global.scss files and pipe it to style.css
{
test: /\.global\.scss$/,
@ -88,44 +67,6 @@ export default merge.smart(baseConfig, {
}
]
},
// WOFF Font
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// WOFF2 Font
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// TTF Font
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream'
}
}
},
// EOT Font
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader'
},
// SVG Font
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
@ -148,8 +89,6 @@ export default merge.smart(baseConfig, {
plugins: [
new CleanWebpackPlugin([path.join('app', 'dist')]),
new CopyWebpackPlugin([path.join('app', 'empty.html')]),
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
@ -161,21 +100,8 @@ export default merge.smart(baseConfig, {
'object-src': "'none'",
'connect-src': ["'self'", 'https://blockchain.info', 'https://zap.jackmallers.com'],
'script-src': ["'self'"],
'font-src': [
"'self'",
'data:',
'https://fonts.googleapis.com',
'https://s3.amazonaws.com',
'https://fonts.gstatic.com'
],
'style-src': [
"'self'",
'blob:',
'https://fonts.googleapis.com',
'https://s3.amazonaws.com',
'https://fonts.gstatic.com',
"'unsafe-inline'"
]
'font-src': ["'self'", 'data:', 'https://s3.amazonaws.com', 'https://fonts.gstatic.com'],
'style-src': ["'self'", 'blob:', 'https://s3.amazonaws.com', "'unsafe-inline'"]
}),
new BundleAnalyzerPlugin({

1
package.json

@ -349,6 +349,7 @@
"source-map-support": "^0.5.9",
"split2": "^3.0.0",
"styled-components": "^4.0.3",
"styled-reset": "^1.6.0",
"tildify": "^1.2.0",
"untildify": "^3.0.3",
"validator": "^10.8.0"

11
stories/components/button.stories.js

@ -44,13 +44,4 @@ storiesOf('Components.Button', module)
Small button
</Button>
))
.add('Medium', () => (
<Button onClick={action('clicked')} size="medium">
Medium button
</Button>
))
.add('Large', () => (
<Button onClick={action('clicked')} size="large">
Large button
</Button>
))
.add('Normal', () => <Button onClick={action('clicked')}>Medium button</Button>)

2
stories/components/form.stories.js

@ -91,7 +91,7 @@ storiesOf('Components.Form', module)
))
.add('Range', () => (
<Form>
<Range field="range" />
<Range initialValue={25} field="range" />
</Form>
))
.add('Example form', () => (

74
stories/components/icon.stories.js

@ -2,14 +2,8 @@ import React from 'react'
import { storiesOf } from '@storybook/react'
import { Box, Flex } from 'rebass'
import SystemArrowLeft from 'components/Icon/SystemArrowLeft'
import SystemArrowRight from 'components/Icon/SystemArrowRight'
import SystemError from 'components/Icon/SystemError'
import SystemNavNext from 'components/Icon/SystemNavNext'
import SystemNavPrevious from 'components/Icon/SystemNavPrevious'
import SystemSuccess from 'components/Icon/SystemSuccess'
import SystemWarning from 'components/Icon/SystemWarning'
import BigArrowLeft from 'components/Icon/BigArrowLeft'
import BigArrowRight from 'components/Icon/BigArrowRight'
import Bitcoin from 'components/Icon/Bitcoin'
import Btcpay from 'components/Icon/Btcpay'
import ChainLink from 'components/Icon/ChainLink'
@ -18,32 +12,41 @@ import Check from 'components/Icon/Check'
import CheckAnimated from 'components/Icon/CheckAnimated'
import CheckCircle from 'components/Icon/CheckCircle'
import Clock from 'components/Icon/Clock'
import CloudLightning from 'components/Icon/CloudLightning'
import Cloudbolt from 'components/Icon/Cloudbolt'
import CloudLightning from 'components/Icon/CloudLightning'
import Contacts from 'components/Icon/Contacts'
import Copy from 'components/Icon/Copy'
import Error from 'components/Icon/Error'
import Eye from 'components/Icon/Eye'
import Globe from 'components/Icon/Globe'
import Hand from 'components/Icon/Hand'
import Help from 'components/Icon/Help'
import Help2 from 'components/Icon/Help2'
import BigArrowRight from 'components/Icon/BigArrowRight'
import IconPlus from 'components/Icon/IconPlus'
import Lightning from 'components/Icon/Lightning'
import Litecoin from 'components/Icon/Litecoin'
import LndLogo from 'components/Icon/LndLogo'
import LtcLogo from 'components/Icon/LtcLogo'
import Network from 'components/Icon/Network'
import Onchain from 'components/Icon/Onchain'
import PaperPlane from 'components/Icon/PaperPlane'
import Peers from 'components/Icon/Peers'
import PlusCircle from 'components/Icon/PlusCircle'
import Plus from 'components/Icon/Plus'
import PlusCircle from 'components/Icon/PlusCircle'
import Qrcode from 'components/Icon/Qrcode'
import Search from 'components/Icon/Search'
import Settings from 'components/Icon/Settings'
import SkinnyBitcoin from 'components/Icon/SkinnyBitcoin'
import Spinner from 'components/Icon/Spinner'
import Success from 'components/Icon/Success'
import SystemArrowLeft from 'components/Icon/SystemArrowLeft'
import SystemArrowRight from 'components/Icon/SystemArrowRight'
import SystemNavNext from 'components/Icon/SystemNavNext'
import SystemNavPrevious from 'components/Icon/SystemNavPrevious'
import User from 'components/Icon/User'
import Wallet from 'components/Icon/Wallet'
import Wallet2 from 'components/Icon/Wallet2'
import Warning from 'components/Icon/Warning'
import X from 'components/Icon/X'
import Zap from 'components/Icon/Zap'
import ZapLogo from 'components/Icon/ZapLogo'
@ -52,47 +55,58 @@ import ZapLogoBlack from 'components/Icon/ZapLogoBlack'
const iconSizes = [16, 32, 64, 128]
const zapIconsList = {
BigArrowLeft,
BigArrowRight,
Bitcoin,
Btcpay,
Channels,
ChainLink,
Channels,
Check,
CheckAnimated,
CheckCircle,
Clock,
CloudLightning,
Cloudbolt,
CloudLightning,
Contacts,
Copy,
Error,
Eye,
Globe,
Hand,
Help,
Help2,
BigArrowRight,
IconPlus,
Lightning,
Litecoin,
LndLogo,
LtcLogo,
Network,
Onchain,
PaperPlane,
Peers,
PlusCircle,
Plus,
PlusCircle,
Qrcode,
Search,
Settings,
SkinnyBitcoin,
Spinner,
Success,
SystemArrowLeft,
SystemArrowRight,
SystemNavNext,
SystemNavPrevious,
User,
Wallet,
Wallet2,
Warning,
X,
Zap,
ZapLogo,
ZapLogoBlack
}
const zapIconStories = storiesOf('Components.Icon.Zap', module)
const zapIconStories = storiesOf('Components.Icon', module)
Object.keys(zapIconsList).forEach(name => {
var Icon = zapIconsList[name]
@ -109,31 +123,3 @@ Object.keys(zapIconsList).forEach(name => {
</React.Fragment>
))
})
const systemIconsList = {
SystemArrowLeft,
SystemArrowRight,
SystemError,
SystemNavNext,
SystemNavPrevious,
SystemSuccess,
SystemWarning
}
const systemIconStories = storiesOf('Components.Icon.System', module)
Object.keys(systemIconsList).forEach(name => {
var Icon = systemIconsList[name]
systemIconStories.add(name, () => (
<React.Fragment>
{iconSizes.map(size => (
<Flex key={`${name}-${size}`} alignItems="center" mb={3}>
<Box mr={2}>
{size} x {size}:
</Box>
<Icon width={size} height={size} />
</Flex>
))}
</React.Fragment>
))
})

21
stories/components/modal.stories.js

@ -1,13 +1,18 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import { Modal } from 'components/UI'
import { action } from '@storybook/addon-actions'
import { Modal, Page, Text } from 'components/UI'
storiesOf('Components.Modal', module).add('Modal', () => (
<Modal>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</Modal>
<Page>
<Modal onClose={action('clicked')}>
<Text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</Text>
</Modal>
</Page>
))

12
test/unit/components/UI/Notification.spec.js

@ -2,9 +2,9 @@ import React from 'react'
import renderer from 'react-test-renderer'
import { configure, shallow } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import SystemSuccess from 'components/Icon/SystemSuccess'
import SystemWarning from 'components/Icon/SystemWarning'
import SystemError from 'components/Icon/SystemError'
import Success from 'components/Icon/Success'
import Warning from 'components/Icon/Warning'
import Error from 'components/Icon/Error'
import { Notification, Spinner } from 'components/UI'
configure({ adapter: new Adapter() })
@ -18,21 +18,21 @@ describe('component.UI.Notification', () => {
describe('variant = success', () => {
it('should render with the success icon', () => {
const wrapper = shallow(<Notification variant="success" />)
expect(wrapper.find(SystemSuccess)).toHaveLength(1)
expect(wrapper.find(Success)).toHaveLength(1)
})
})
describe('variant = warning', () => {
it('should render with the warning icon', () => {
const wrapper = shallow(<Notification variant="warning" />)
expect(wrapper.find(SystemWarning)).toHaveLength(1)
expect(wrapper.find(Warning)).toHaveLength(1)
})
})
describe('variant = error', () => {
it('should render with the error icon', () => {
const wrapper = shallow(<Notification variant="error" />)
expect(wrapper.find(SystemError)).toHaveLength(1)
expect(wrapper.find(Error)).toHaveLength(1)
})
})

4
test/unit/components/UI/__snapshots__/BackgroundDark.spec.js.snap

@ -2,12 +2,12 @@
exports[`component.UI.BackgroundDark should render correctly 1`] = `
.c0 {
color: white;
color: primaryText;
background-color: darkestBackground;
}
<div
className="c0"
color="white"
color="primaryText"
/>
`;

4
test/unit/components/UI/__snapshots__/BackgroundLight.spec.js.snap

@ -2,12 +2,12 @@
exports[`component.UI.BackgroundLight should render correctly 1`] = `
.c0 {
color: white;
color: primaryText;
background-color: lightBackground;
}
<div
className="c0"
color="white"
color="primaryText"
/>
`;

4
test/unit/components/UI/__snapshots__/BackgroundLightest.spec.js.snap

@ -2,12 +2,12 @@
exports[`component.UI.BackgroundLightest should render correctly 1`] = `
.c0 {
color: white;
color: primaryText;
background-color: lightestBackground;
}
<div
className="c0"
color="white"
color="primaryText"
/>
`;

7
test/unit/components/UI/__snapshots__/Bar.spec.js.snap

@ -3,12 +3,15 @@
exports[`component.UI.Bar should render correctly 1`] = `
.c0 {
width: 100%;
background-color: white;
height: 1px;
border-bottom: none !important;
border: 1px solid;
border-color: primaryText;
opacity: 0.6;
}
<hr
className="c0"
opacity={0.6}
width={1}
/>
`;

16
test/unit/components/UI/__snapshots__/Button.spec.js.snap

@ -3,15 +3,16 @@
exports[`component.UI.Button should render correctly 1`] = `
.c1 {
font-family: sans;
font-weight: normal;
}
.c0 {
margin: 0px;
padding-left: 16px;
padding-right: 16px;
padding-top: 8px;
padding-bottom: 8px;
font-size: m;
padding-left: 64px;
padding-right: 64px;
padding-top: 16px;
padding-bottom: 16px;
font-size: inherit;
color: white;
background-color: blue;
-webkit-appearance: none;
@ -29,7 +30,7 @@ exports[`component.UI.Button should render correctly 1`] = `
transition: all 0.25s;
outline: none;
border-radius: 5;
font-weight: normal;
font-weight: 300;
line-height: '18px';
}
@ -44,12 +45,13 @@ exports[`component.UI.Button should render correctly 1`] = `
<button
className="c0"
color="white"
fontSize="m"
fontSize="inherit"
fontWeight="bold"
>
<div
className="c1"
fontFamily="sans"
fontWeight="normal"
/>
</button>
`;

8
test/unit/components/UI/__snapshots__/Dropdown.spec.js.snap

@ -3,7 +3,9 @@
exports[`component.Dropdown should render correctly 1`] = `
.c2 {
font-size: m;
color: primaryText;
text-align: left;
line-height: 1.4;
}
.c0 {
@ -21,10 +23,7 @@ exports[`component.Dropdown should render correctly 1`] = `
.c1 {
margin: 0px;
padding-left: 0px;
padding-right: 0px;
padding-top: 8px;
padding-bottom: 8px;
padding: 0px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
@ -52,6 +51,7 @@ exports[`component.Dropdown should render correctly 1`] = `
>
<div
className="c2"
color="primaryText"
fontSize="m"
>
BTC

7
test/unit/components/UI/__snapshots__/Heading.spec.js.snap

@ -4,13 +4,16 @@ exports[`component.UI.Heading should render correctly 1`] = `
.c0 {
margin: 0px;
font-size: 32px;
font-weight: bold;
color: primaryText;
font-weight: light;
line-height: 1.4;
}
<h2
className="c0"
color="primaryText"
fontSize={5}
fontWeight="bold"
fontWeight="light"
>
Heading here
</h2>

4
test/unit/components/UI/__snapshots__/Input.spec.js.snap

@ -19,8 +19,8 @@ exports[`component.UI.Input should render correctly 1`] = `
background-color: transparent;
color: #fff;
background-color: transparent;
font-family: "Roboto Light",Roboto,system-ui,sans-serif;
font-weight: light;
font-family: Roboto,system-ui,sans-serif;
font-weight: 300;
border: 1px solid;
border: 1px solid;
border-color: #959595;

4
test/unit/components/UI/__snapshots__/LightningInvoiceInput.spec.js.snap

@ -19,8 +19,8 @@ exports[`component.UI.LightningInvoiceInput should render correctly 1`] = `
background-color: transparent;
color: #fff;
background-color: transparent;
font-family: "Roboto Light",Roboto,system-ui,sans-serif;
font-weight: light;
font-family: Roboto,system-ui,sans-serif;
font-weight: 300;
border: 1px solid;
border: 1px solid;
border-color: #959595;

4
test/unit/components/UI/__snapshots__/MainContent.spec.js.snap

@ -4,14 +4,14 @@ exports[`component.UI.MainContent should render correctly 1`] = `
.c0 {
padding: 16px;
width: 100%;
color: white;
color: primaryText;
background-color: darkestBackground;
height: 100%;
}
<article
className="c0"
color="white"
color="primaryText"
width={1}
/>
`;

2
test/unit/components/UI/__snapshots__/Menu.spec.js.snap

@ -28,7 +28,7 @@ exports[`component.UI.Menu should render correctly 1`] = `
}
.c1 > .rc-menu-item-group-title {
font-weight: bold;
font-weight: 400;
padding: 8px 0;
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save