[redesign] Help, backup, other cleanup #1013

Merged
neb-b merged 1 commit from redesign-wip into redesign 2018-02-12 23:09:40 +01:00
35 changed files with 731 additions and 731 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

3
flow-typed/react-transition-group.js vendored Normal file
View file

@ -0,0 +1,3 @@
declare module 'react-transition-group' {
declare module.exports: any;
}

View file

@ -58,6 +58,7 @@
"react-paginate": "^5.0.0",
"react-redux": "^5.0.3",
"react-simplemde-editor": "^3.6.11",
"react-transition-group": "1.x",
"redux": "^3.6.0",
"redux-action-buffer": "^1.1.0",
"redux-logger": "^3.0.1",

View file

@ -4,7 +4,7 @@ import setupContextMenu from './menu/setupContextMenu';
export default deepLinkingURIArg => {
let windowConfiguration = {
backgroundColor: '#155B4A',
backgroundColor: '#44b098',
minWidth: 800,
minHeight: 600,
autoHideMenuBar: true,

View file

@ -23,12 +23,13 @@ export default class Address extends React.PureComponent<Props> {
return (
<FormField
stretch
name="address"
render={() => (
<React.Fragment>
<input
id="address"
className="input-copyable"
className="input-copyable form-field__input"
readOnly
value={address || ''}
ref={input => {

View file

@ -1,5 +1,6 @@
// @flow
import * as React from 'react';
import classnames from 'classnames';
type Props = {
name: string,
@ -13,22 +14,30 @@ type Props = {
onChange?: any => any,
defaultValue?: string | number,
placeholder?: string | number,
children?: React.Node,
stretch?: boolean
};
export class FormField extends React.PureComponent<Props> {
render() {
const { render, label, prefix, postfix, error, helper, name, type, ...inputProps } = this.props;
const { render, label, prefix, postfix, error, helper, name, type, children, stretch, ...inputProps } = this.props;
// Allow a type prop to determine the input or more customizability with a render prop
let Input;
if (type) {
Input = () => <input type={type} id={name} {...inputProps} />;
if (type === 'select') {
Input = () => (
<select id={name} {...inputProps}>{children}</select>
)
} else {
Input = () => <input type={type} id={name} {...inputProps} />;
}
} else if (render) {
Input = render;
}
return (
<div className="form-field">
<div className={classnames("form-field", { "form-field--stretch": stretch })}>
{label && (
<label className="form-field__label" htmlFor={name}>
{label}

View file

@ -0,0 +1,18 @@
// @flow
import React from 'react';
import QRCodeElement from 'qrcode.react';
type Props = {
value: string
}
const QRCode = (props: Props) => {
const { value } = props;
return (
<div className="qr-code">
<QRCodeElement value={value} />
</div>
)
}
export default QRCode;

View file

@ -1,6 +1,6 @@
import React from 'react';
import { buildURI } from 'lbryURI';
import FormField from 'component/formField';
import { FormField } from 'component/common/form';
import FileTile from 'component/fileTile';
import { BusyMessage } from 'component/common.js';

View file

@ -3,10 +3,8 @@
import React from 'react';
import lbry from 'lbry';
import { isNameValid, buildURI, regexInvalidURI } from 'lbryURI';
import FormField from 'component/formField';
import { Form, FormRow } from 'component/common/form';
import Link from 'component/link';
import FormFieldPrice from 'component/formFieldPrice';
import Modal from 'modal/modal';
import { BusyMessage } from 'component/common';
import ChannelSection from './internal/channelSection';
@ -516,367 +514,369 @@ class PublishForm extends React.PureComponent {
submitLabel = !submitting ? __('Update') : __('Updating...');
}
return (
<main className="main--single-column">
<Form onSubmit={this.handleSubmit.bind(this)}>
<section className="card">
<div className="card__title-primary">
<h4>{__('Content')}</h4>
<div className="card__subtitle">{__('What are you publishing?')}</div>
</div>
<div className="card__content">
<FormRow
name="file"
ref="file"
type="file"
onChange={event => {
this.onFileChange(event);
}}
helper={
this.myClaimExists()
? __(
"If you don't choose a file, the file from your existing claim will be used."
)
: null
}
/>
</div>
{!this.state.hasFile && !this.myClaimExists() ? null : (
<div>
<div className="card__content">
<FormRow
ref="meta_title"
label={__('Title')}
type="text"
name="title"
value={this.state.meta_title}
placeholder="Titular Title"
onChange={event => {
this.handleMetadataChange(event);
}}
/>
</div>
<div className="card__content">
<FormRow
type="text"
label={__('Thumbnail URL')}
name="thumbnail"
value={this.state.meta_thumbnail}
placeholder="http://spee.ch/mylogo"
onChange={event => {
this.handleMetadataChange(event);
}}
/>
</div>
<div className="card__content">
<FormRow
type="SimpleMDE"
label={__('Description')}
ref="meta_description"
name="description"
value={this.state.meta_description}
placeholder={__('Description of your content')}
onChange={text => {
this.handleDescriptionChanged(text);
}}
/>
</div>
<div className="card__content">
<FormRow
label={__('Language')}
type="select"
value={this.state.meta_language}
name="language"
onChange={event => {
this.handleMetadataChange(event);
}}
>
<option value="en">{__('English')}</option>
<option value="zh">{__('Chinese')}</option>
<option value="fr">{__('French')}</option>
<option value="de">{__('German')}</option>
<option value="jp">{__('Japanese')}</option>
<option value="ru">{__('Russian')}</option>
<option value="es">{__('Spanish')}</option>
</FormRow>
</div>
<div className="card__content">
<FormRow
type="select"
label={__('Maturity')}
value={this.state.meta_nsfw}
name="nsfw"
onChange={event => {
this.handleMetadataChange(event);
}}
>
{/* <option value=""></option> */}
<option value="0">{__('All Ages')}</option>
<option value="1">{__('Adults Only')}</option>
</FormRow>
</div>
</div>
)}
</section>
return null;
<section className="card">
<div className="card__title-primary">
<h4>{__('Price')}</h4>
<div className="card__subtitle">{__('How much does this content cost?')}</div>
</div>
<div className="card__content">
<FormRow
label={__('Free')}
type="radio"
name="isFree"
onChange={() => this.handleFeePrefChange(false)}
checked={!this.state.isFee}
/>
<FormField
type="radio"
name="isFree"
label={!this.state.isFee ? __('Choose price...') : __('Price ')}
onChange={() => {
this.handleFeePrefChange(true);
}}
checked={this.state.isFee}
/>
<span className={!this.state.isFee ? 'hidden' : ''}>
<FormFieldPrice
min="0"
defaultValue={{
amount: this._defaultPaidPrice,
currency: 'LBC',
}}
onChange={val => this.handleFeeChange(val)}
/>
</span>
{this.state.isFee && this.state.feeCurrency.toUpperCase() != 'LBC' ? (
<div className="form-field__helper">
{__(
'All content fees are charged in LBC. For non-LBC payment methods, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase.'
)}
</div>
) : null}
</div>
</section>
<section className="card">
<div className="card__title-primary">
<h4>{__('License')}</h4>
</div>
<div className="card__content">
<FormRow
type="select"
value={this.state.licenseType}
ref={row => {
this._meta_license = row;
}}
onChange={event => {
this.handleLicenseTypeChange(event);
}}
>
<option>{__('None')}</option>
<option value="publicDomain">{__('Public Domain')}</option>
<option
value="cc-by"
data-url="https://creativecommons.org/licenses/by/4.0/legalcode"
>
{__('Creative Commons Attribution 4.0 International')}
</option>
<option
value="cc-by-sa"
data-url="https://creativecommons.org/licenses/by-sa/4.0/legalcode"
>
{__('Creative Commons Attribution-ShareAlike 4.0 International')}
</option>
<option
value="cc-by-nd"
data-url="https://creativecommons.org/licenses/by-nd/4.0/legalcode"
>
{__('Creative Commons Attribution-NoDerivatives 4.0 International')}
</option>
<option
value="cc-by-nc"
data-url="https://creativecommons.org/licenses/by-nc/4.0/legalcode"
>
{__('Creative Commons Attribution-NonCommercial 4.0 International')}
</option>
<option
value="cc-by-nc-sa"
data-url="https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode"
>
{__('Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International')}
</option>
<option
value="cc-by-nc-nd"
data-url="https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode"
>
{__('Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International')}
</option>
<option value="copyright">{__('Copyrighted...')}</option>
<option value="other">{__('Other...')}</option>
</FormRow>
{this.state.licenseType == 'copyright' ? (
<FormRow
label={__('Copyright notice')}
type="text"
name="copyright-notice"
value={this.state.copyrightNotice}
onChange={event => {
this.handleCopyrightNoticeChange(event);
}}
/>
) : null}
{this.state.licenseType == 'other' ? (
<FormRow
label={__('License description')}
type="text"
name="other-license-description"
value={this.state.otherLicenseDescription}
onChange={event => {
this.handleOtherLicenseDescriptionChange(event);
}}
/>
) : null}
{this.state.licenseType == 'other' ? (
<FormRow
label={__('License URL')}
type="text"
name="other-license-url"
value={this.state.otherLicenseUrl}
onChange={event => {
this.handleOtherLicenseUrlChange(event);
}}
/>
) : null}
</div>
</section>
<ChannelSection
{...this.props}
handleChannelChange={this.handleChannelChange.bind(this)}
channel={this.state.channel}
/>
<section className="card">
<div className="card__title-primary">
<h4>{__('Content URL')}</h4>
<div className="card__subtitle">
{__(
'This is the exact address where people find your content (ex. lbry://myvideo).'
)}{' '}
<Link label={__('Learn more')} href="https://lbry.io/faq/naming" />.
</div>
</div>
<div className="card__content">
<FormRow
prefix={`lbry://${
this.state.channel === 'anonymous' ? '' : `${this.state.channel}/`
}`}
type="text"
ref="name"
placeholder="myname"
value={this.state.rawName}
onChange={event => {
this.handleNameChange(event);
}}
helper={this.getNameBidHelpText()}
/>
</div>
{this.state.rawName ? (
<div className="card__content">
<FormRow
ref="bid"
type="number"
step="any"
label={__('Deposit')}
postfix="LBC"
onChange={event => {
this.handleBidChange(event);
}}
value={this.state.bid}
placeholder={this.claim() ? this.topClaimValue() + 10 : 100}
helper={lbcInputHelp}
min="0"
/>
</div>
) : (
''
)}
</section>
<section className="card">
<div className="card__title-primary">
<h4>{__('Terms of Service')}</h4>
</div>
<div className="card__content">
<FormRow
ref="tosAgree"
label={
<span>
{__('I agree to the')}{' '}
<Link
href="https://www.lbry.io/termsofservice"
label={__('LBRY terms of service')}
/>
</span>
}
type="checkbox"
checked={this.state.tosAgree}
onChange={event => {
this.handleTOSChange(event);
}}
/>
</div>
</section>
<div className="card-series-submit">
<Link
type="submit"
label={!this.state.submitting ? __('Publish') : __('Publishing...')}
disabled={
this.props.balance <= 0 ||
this.state.submitting ||
(this.state.uri && this.props.resolvingUris.indexOf(this.state.uri) !== -1) ||
(this.claim() && !this.topClaimIsMine() && this.state.bid <= this.topClaimValue())
}
/>
<Link button="cancel" onClick={this.props.back} label={__('Cancel')} />
</div>
</Form>
<Modal
isOpen={this.state.modal == 'publishStarted'}
contentLabel={__('File published')}
onConfirmed={event => {
this.handlePublishStartedConfirmed(event);
}}
>
<p>
{__('Your file has been published to LBRY at the address')}{' '}
<code>{this.state.uri}</code>!
</p>
<p>
{__(
'The file will take a few minutes to appear for other LBRY users. Until then it will be listed as "pending" under your published files.'
)}
</p>
</Modal>
<Modal
isOpen={this.state.modal == 'error'}
contentLabel={__('Error publishing file')}
onConfirmed={event => {
this.closeModal(event);
}}
>
{__('The following error occurred when attempting to publish your file')}:{' '}
{this.state.errorMessage}
</Modal>
</main>
);
// return (
// <main className="main--single-column">
// <Form onSubmit={this.handleSubmit.bind(this)}>
// <section className="card">
// <div className="card__title-primary">
// <h4>{__('Content')}</h4>
// <div className="card__subtitle">{__('What are you publishing?')}</div>
// </div>
// <div className="card__content">
// <FormRow
// name="file"
// ref="file"
// type="file"
// onChange={event => {
// this.onFileChange(event);
// }}
// helper={
// this.myClaimExists()
// ? __(
// "If you don't choose a file, the file from your existing claim will be used."
// )
// : null
// }
// />
// </div>
// {!this.state.hasFile && !this.myClaimExists() ? null : (
// <div>
// <div className="card__content">
// <FormRow
// ref="meta_title"
// label={__('Title')}
// type="text"
// name="title"
// value={this.state.meta_title}
// placeholder="Titular Title"
// onChange={event => {
// this.handleMetadataChange(event);
// }}
// />
// </div>
// <div className="card__content">
// <FormRow
// type="text"
// label={__('Thumbnail URL')}
// name="thumbnail"
// value={this.state.meta_thumbnail}
// placeholder="http://spee.ch/mylogo"
// onChange={event => {
// this.handleMetadataChange(event);
// }}
// />
// </div>
// <div className="card__content">
// <FormRow
// type="SimpleMDE"
// label={__('Description')}
// ref="meta_description"
// name="description"
// value={this.state.meta_description}
// placeholder={__('Description of your content')}
// onChange={text => {
// this.handleDescriptionChanged(text);
// }}
// />
// </div>
// <div className="card__content">
// <FormRow
// label={__('Language')}
// type="select"
// value={this.state.meta_language}
// name="language"
// onChange={event => {
// this.handleMetadataChange(event);
// }}
// >
// <option value="en">{__('English')}</option>
// <option value="zh">{__('Chinese')}</option>
// <option value="fr">{__('French')}</option>
// <option value="de">{__('German')}</option>
// <option value="jp">{__('Japanese')}</option>
// <option value="ru">{__('Russian')}</option>
// <option value="es">{__('Spanish')}</option>
// </FormRow>
// </div>
// <div className="card__content">
// <FormRow
// type="select"
// label={__('Maturity')}
// value={this.state.meta_nsfw}
// name="nsfw"
// onChange={event => {
// this.handleMetadataChange(event);
// }}
// >
// {/* <option value=""></option> */}
// <option value="0">{__('All Ages')}</option>
// <option value="1">{__('Adults Only')}</option>
// </FormRow>
// </div>
// </div>
// )}
// </section>
//
// <section className="card">
// <div className="card__title-primary">
// <h4>{__('Price')}</h4>
// <div className="card__subtitle">{__('How much does this content cost?')}</div>
// </div>
// <div className="card__content">
// <FormRow
// label={__('Free')}
// type="radio"
// name="isFree"
// onChange={() => this.handleFeePrefChange(false)}
// checked={!this.state.isFee}
// />
// <FormField
// type="radio"
// name="isFree"
// label={!this.state.isFee ? __('Choose price...') : __('Price ')}
// onChange={() => {
// this.handleFeePrefChange(true);
// }}
// checked={this.state.isFee}
// />
// <span className={!this.state.isFee ? 'hidden' : ''}>
// <FormFieldPrice
// min="0"
// defaultValue={{
// amount: this._defaultPaidPrice,
// currency: 'LBC',
// }}
// onChange={val => this.handleFeeChange(val)}
// />
// </span>
// {this.state.isFee && this.state.feeCurrency.toUpperCase() != 'LBC' ? (
// <div className="form-field__helper">
// {__(
// 'All content fees are charged in LBC. For non-LBC payment methods, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase.'
// )}
// </div>
// ) : null}
// </div>
// </section>
// <section className="card">
// <div className="card__title-primary">
// <h4>{__('License')}</h4>
// </div>
// <div className="card__content">
// <FormRow
// type="select"
// value={this.state.licenseType}
// ref={row => {
// this._meta_license = row;
// }}
// onChange={event => {
// this.handleLicenseTypeChange(event);
// }}
// >
// <option>{__('None')}</option>
// <option value="publicDomain">{__('Public Domain')}</option>
// <option
// value="cc-by"
// data-url="https://creativecommons.org/licenses/by/4.0/legalcode"
// >
// {__('Creative Commons Attribution 4.0 International')}
// </option>
// <option
// value="cc-by-sa"
// data-url="https://creativecommons.org/licenses/by-sa/4.0/legalcode"
// >
// {__('Creative Commons Attribution-ShareAlike 4.0 International')}
// </option>
// <option
// value="cc-by-nd"
// data-url="https://creativecommons.org/licenses/by-nd/4.0/legalcode"
// >
// {__('Creative Commons Attribution-NoDerivatives 4.0 International')}
// </option>
// <option
// value="cc-by-nc"
// data-url="https://creativecommons.org/licenses/by-nc/4.0/legalcode"
// >
// {__('Creative Commons Attribution-NonCommercial 4.0 International')}
// </option>
// <option
// value="cc-by-nc-sa"
// data-url="https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode"
// >
// {__('Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International')}
// </option>
// <option
// value="cc-by-nc-nd"
// data-url="https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode"
// >
// {__('Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International')}
// </option>
// <option value="copyright">{__('Copyrighted...')}</option>
// <option value="other">{__('Other...')}</option>
// </FormRow>
//
// {this.state.licenseType == 'copyright' ? (
// <FormRow
// label={__('Copyright notice')}
// type="text"
// name="copyright-notice"
// value={this.state.copyrightNotice}
// onChange={event => {
// this.handleCopyrightNoticeChange(event);
// }}
// />
// ) : null}
//
// {this.state.licenseType == 'other' ? (
// <FormRow
// label={__('License description')}
// type="text"
// name="other-license-description"
// value={this.state.otherLicenseDescription}
// onChange={event => {
// this.handleOtherLicenseDescriptionChange(event);
// }}
// />
// ) : null}
//
// {this.state.licenseType == 'other' ? (
// <FormRow
// label={__('License URL')}
// type="text"
// name="other-license-url"
// value={this.state.otherLicenseUrl}
// onChange={event => {
// this.handleOtherLicenseUrlChange(event);
// }}
// />
// ) : null}
// </div>
// </section>
//
// <ChannelSection
// {...this.props}
// handleChannelChange={this.handleChannelChange.bind(this)}
// channel={this.state.channel}
// />
//
// <section className="card">
// <div className="card__title-primary">
// <h4>{__('Content URL')}</h4>
// <div className="card__subtitle">
// {__(
// 'This is the exact address where people find your content (ex. lbry://myvideo).'
// )}{' '}
// <Link label={__('Learn more')} href="https://lbry.io/faq/naming" />.
// </div>
// </div>
// <div className="card__content">
// <FormRow
// prefix={`lbry://${
// this.state.channel === 'anonymous' ? '' : `${this.state.channel}/`
// }`}
// type="text"
// ref="name"
// placeholder="myname"
// value={this.state.rawName}
// onChange={event => {
// this.handleNameChange(event);
// }}
// helper={this.getNameBidHelpText()}
// />
// </div>
// {this.state.rawName ? (
// <div className="card__content">
// <FormRow
// ref="bid"
// type="number"
// step="any"
// label={__('Deposit')}
// postfix="LBC"
// onChange={event => {
// this.handleBidChange(event);
// }}
// value={this.state.bid}
// placeholder={this.claim() ? this.topClaimValue() + 10 : 100}
// helper={lbcInputHelp}
// min="0"
// />
// </div>
// ) : (
// ''
// )}
// </section>
//
// <section className="card">
// <div className="card__title-primary">
// <h4>{__('Terms of Service')}</h4>
// </div>
// <div className="card__content">
// <FormRow
// ref="tosAgree"
// label={
// <span>
// {__('I agree to the')}{' '}
// <Link
// href="https://www.lbry.io/termsofservice"
// label={__('LBRY terms of service')}
// />
// </span>
// }
// type="checkbox"
// checked={this.state.tosAgree}
// onChange={event => {
// this.handleTOSChange(event);
// }}
// />
// </div>
// </section>
//
// <div className="card-series-submit">
// <Link
// type="submit"
// label={!this.state.submitting ? __('Publish') : __('Publishing...')}
// disabled={
// this.props.balance <= 0 ||
// this.state.submitting ||
// (this.state.uri && this.props.resolvingUris.indexOf(this.state.uri) !== -1) ||
// (this.claim() && !this.topClaimIsMine() && this.state.bid <= this.topClaimValue())
// }
// />
// <Link button="cancel" onClick={this.props.back} label={__('Cancel')} />
// </div>
// </Form>
//
// <Modal
// isOpen={this.state.modal == 'publishStarted'}
// contentLabel={__('File published')}
// onConfirmed={event => {
// this.handlePublishStartedConfirmed(event);
// }}
// >
// <p>
// {__('Your file has been published to LBRY at the address')}{' '}
// <code>{this.state.uri}</code>!
// </p>
// <p>
// {__(
// 'The file will take a few minutes to appear for other LBRY users. Until then it will be listed as "pending" under your published files.'
// )}
// </p>
// </Modal>
// <Modal
// isOpen={this.state.modal == 'error'}
// contentLabel={__('Error publishing file')}
// onConfirmed={event => {
// this.closeModal(event);
// }}
// >
// {__('The following error occurred when attempting to publish your file')}:{' '}
// {this.state.errorMessage}
// </Modal>
// </main>
// );
}
}

View file

@ -13,7 +13,7 @@ const RewardSummary = (props: Props) => {
return (
<section className="card card--section">
<h2>{__('Rewards')}</h2>
<div className="card__title">{__('Rewards')}</div>
<p className="card__subtitle">
{hasRewards ? (
<React.Fragment>

View file

@ -22,7 +22,7 @@ import SubscriptionsPage from 'page/subscriptions';
const route = (page, routesMap) => {
const component = routesMap[page];
return component;
return component || DiscoverPage;
};
const Router = props => {

View file

@ -1,6 +1,7 @@
// @flow
import * as React from 'react';
import QRCode from 'qrcode.react';
import QRCode from 'component/common/qr-code';
import { FormRow } from 'component/common/form';
import * as statuses from 'constants/shape_shift';
import Address from 'component/address';
import Link from 'component/link';
@ -92,12 +93,12 @@ class ActiveShapeShift extends React.PureComponent<Props> {
originCoinDepositMax={originCoinDepositMax}
/>
<div className="shapeshift__deposit-address-wrapper">
<Address address={shiftDepositAddress} showCopyButton />
<div className="shapeshift__qrcode">
{shiftDepositAddress && (
<FormRow verticallyCentered padded>
<Address address={shiftDepositAddress} showCopyButton />
<QRCode value={shiftDepositAddress} />
</div>
</div>
</FormRow>
)}
</div>
)}
@ -115,9 +116,9 @@ class ActiveShapeShift extends React.PureComponent<Props> {
<p>{__('Transaction complete! You should see the new LBC in your wallet.')}</p>
</div>
)}
<div className="card__actions card__actions--only-vertical">
<div className="card__actions">
<Link
button={shiftState === statuses.COMPLETE ? 'primary' : 'alt'}
primary
onClick={clearShapeShift}
label={
shiftState === statuses.COMPLETE || shiftState === statuses.RECEIVED
@ -126,13 +127,11 @@ class ActiveShapeShift extends React.PureComponent<Props> {
}
/>
{shiftOrderId && (
<span className="shapeshift__link">
<Link
button="text"
inverse
label={__('View the status on Shapeshift.io')}
href={`https://shapeshift.io/#/status/${shiftOrderId}`}
/>
</span>
)}
{shiftState === statuses.NO_DEPOSITS &&
shiftReturnAddress && (

View file

@ -1,7 +1,7 @@
// @flow
import React from 'react';
import { getExampleAddress } from 'util/shape_shift';
import { FormField, Submit } from 'component/common/form';
import { FormField, FormRow, Submit } from 'component/common/form';
import type { ShapeShiftFormValues, Dispatch } from 'redux/actions/shape_shift';
import ShiftMarketInfo from './market_info';
@ -50,59 +50,46 @@ export default (props: Props) => {
<FormField
prefix={__('Exchange')}
postfix={__('for LBC')}
render={() => (
<select
className="form-field__input form-field__input-select"
name="originCoin"
onChange={e => {
getCoinStats(e.target.value);
handleChange(e);
}}
>
{shiftSupportedCoins.map(coin => (
<option key={coin} value={coin}>
{coin}
</option>
))}
</select>
)}
type="select"
name="origin_coin"
onChange={e => {
getCoinStats(e.target.value);
handleChange(e);
}}>
{shiftSupportedCoins.map(coin => (
<option key={coin} value={coin}>
{coin}
</option>
))}
</FormField>
<ShiftMarketInfo
originCoin={originCoin}
shapeShiftRate={shapeShiftRate}
originCoinDepositFee={originCoinDepositFee}
originCoinDepositMin={originCoinDepositMin}
originCoinDepositMax={originCoinDepositMax}
/>
<div>
<div className="shapeshift__tx-info">
{!updating &&
originCoinDepositMax && (
<ShiftMarketInfo
originCoin={originCoin}
shapeShiftRate={shapeShiftRate}
originCoinDepositFee={originCoinDepositFee}
originCoinDepositMin={originCoinDepositMin}
originCoinDepositMax={originCoinDepositMax}
/>
)}
</div>
</div>
<FormRow padded>
<FormField
label={__('Return address')}
error={touched.returnAddress && !!errors.returnAddress && errors.returnAddress}
render={() => (
<input
type="text"
name="returnAddress"
placeholder={getExampleAddress(originCoin)}
onChange={handleChange}
onBlur={handleBlur}
value={values.returnAddress}
/>
)}
type="text"
name="return_address"
className="input--address"
placeholder={getExampleAddress(originCoin)}
onChange={handleChange}
onBlur={handleBlur}
value={values.returnAddress}
/>
</FormRow>
<span className="help">
<span>
({__('optional but recommended')}) {__('We will return your')} {originCoin}{' '}
({__('optional but recommended')})<br/>{__('We will return your')} {originCoin}{' '}
{__("to this address if the transaction doesn't go through.")}
</span>
</span>
<div className="card__actions card__actions--only-vertical">
<div className="card__actions">
<Submit
label={__('Begin Conversion')}
disabled={isSubmitting || !!Object.keys(errors).length}

View file

@ -67,7 +67,7 @@ class ShapeShift extends React.PureComponent<Props> {
return (
<section className="card card--section">
<h2>{__('Convert Crypto to LBC')}</h2>
<div className="card__title">{__('Convert Crypto to LBC')}</div>
<p className="card__subtitle">
{__('Powered by ShapeShift. Read our FAQ')}{' '}
<Link fakeLink label={__('here')} href="https://lbry.io/faq/shapeshift" />.
@ -75,11 +75,9 @@ class ShapeShift extends React.PureComponent<Props> {
shiftState !== 'complete' && <span>{__('This will update automatically.')}</span>}
</p>
<div className="card__content shapeshift__content">
<div className="card__content">
{error && <div className="form-field__error">{error}</div>}
{!loading &&
!hasActiveShift &&
!!shiftSupportedCoins.length && (
{!hasActiveShift && (
<Formik
onSubmit={createShapeShift}
validate={validateShapeShiftForm}

View file

@ -1,7 +1,9 @@
// @flow
import React from 'react';
import * as React from 'react';
import Button from 'component/link';
import classnames from 'classnames';
import Icon from 'component/common/icon';
import { CSSTransitionGroup } from 'react-transition-group'
type SideBarLink = {
label: string,
@ -59,36 +61,44 @@ const SideBar = (props: Props) => {
{navLinks.primary.map(({ label, path, active, icon }) => (
<li
key={path}
className={classnames('nav__link nav__primary-link', { 'nav__link--active': active })}
className={classnames('nav__link nav__link--primary', { 'nav__link--active': active })}
>
<Button noStyle navigate={path} label={label} icon={icon} />
</li>
))}
</ul>
<hr />
<ul className="nav__secondary">
<ul>
{navLinks.secondary.map(({ label, path, active, icon, subLinks = [] }) => (
<li
key={path}
className={classnames('nav__link nav__secondary-link', {
'nav__link--active': active && !subLinks.length,
key={label}
className={classnames('nav__link', {
'nav__link--active': active,
})}
>
<Button noStyle navigate={path} label={label} icon={icon} />
{!!subLinks.length &&
active && (
<ul className="nav__sub">
{subLinks.map(({ label: subLabel, path: subPath, active: subLinkActive }) => (
<li
key={subPath}
className={classnames('nav__link nav__sub-link', {
'nav__link--active': subLinkActive,
})}
>
<Button noStyle navigate={subPath} label={subLabel} />
</li>
))}
<Button noStyle navigate={path} label={label} icon={icon} />
{!!subLinks.length && active && (
<CSSTransitionGroup
transitionAppear
transitionLeave
transitionAppearTimeout={300}
transitionEnterTimeout={300}
transitionLeaveTimeout={300}
transitionName="nav__sub">
<ul key="0" className="nav__sub-links">
{subLinks.map(({ label: subLabel, path: subPath, active: subLinkActive }) => (
<li
key={subPath}
className={classnames('nav__link--sub', {
'nav__link--active': subLinkActive,
})}
>
{subPath ? <Button noStyle navigate={subPath} label={subLabel} /> : <span>{subLabel}</span>}
</li>
))}
</ul>
</CSSTransitionGroup>
)}
</li>
))}
@ -98,4 +108,5 @@ const SideBar = (props: Props) => {
);
};
export default SideBar;

View file

@ -22,7 +22,7 @@ class TransactionListRecent extends React.PureComponent<Props> {
return (
<section className="card card--section">
<h2>{__('Recent Transactions')}</h2>
<div className="card__title">{__('Recent Transactions')}</div>
<div className="card__content">
{fetchingTransactions && <BusyMessage message={__('Loading transactions')} />}
{!fetchingTransactions && (

View file

@ -20,9 +20,7 @@ class WalletAddress extends React.PureComponent<Props> {
return (
<section className="card card--section">
<div className="card__title-primary">
<h2>{__('Receive Credits')}</h2>
</div>
<div className="card__title">{__('Receive Credits')}</div>
<p className="card__subtitle">
{__('Use this wallet address to receive credits sent by another user (or yourself).')}
</p>

View file

@ -10,7 +10,7 @@ const WalletBalance = (props: Props) => {
const { balance } = props;
return (
<section className="card card--section">
<h2>{__('Balance')}</h2>
<div className="card__title">{__('Balance')}</div>
<span className="card__subtitle">{__('You currently have')}</span>
<div className="card__content">
{(balance || balance === 0) && <CreditAmount large amount={balance} precision={8} />}

View file

@ -29,9 +29,7 @@ class WalletSend extends React.PureComponent<Props> {
render() {
return (
<section className="card card--section">
<div className="card__title-primary">
<h2>{__('Send Credits')}</h2>
</div>
<div className="card__title">{__('Send Credits')}</div>
<div className="card__content">
<Formik
initialValues={{

View file

@ -1,45 +1,54 @@
import React from 'react';
// @flow
import * as React from 'react';
import Link from 'component/link';
import Page from 'component/page';
class BackupPage extends React.PureComponent {
type Props = {
daemonSettings: {
lbryum_wallet_dir: ?string
}
}
class BackupPage extends React.PureComponent<Props> {
render() {
const { daemonSettings } = this.props;
const { lbryum_wallet_dir } = daemonSettings;
if (!daemonSettings || Object.keys(daemonSettings).length === 0) {
return (
<main className="main--single-column">
<SubHeader />
<span className="empty">{__('Failed to load settings.')}</span>
</main>
);
}
const noDaemonSettings = Object.keys(daemonSettings).length === 0;
return (
<Page>
<section className="card card--section">
<div className="card__title-primary">
<h3>{__('Backup Your LBRY Credits')}</h3>
{noDaemonSettings ? (
<div className="card__title">{__('Failed to load settings.')}</div>
) : (
<React.Fragment>
<div className="card__title">
{__('Backup Your LBRY Credits')}
</div>
<p className="card__subtitle">
{__(
'Your LBRY credits are controllable by you and only you, via wallet file(s) stored locally on your computer.'
)}
</p>
<div className="card__content">
<p>
{__(
'Your LBRY credits are controllable by you and only you, via wallet file(s) stored locally on your computer.'
)}
</p>
<p>
{__(
'Currently, there is no automatic wallet backup. If you lose access to these files, you will lose your credits permanently.'
)}
</p>
</div>
<div className="card__content">
<p>
{__(
'However, it is fairly easy to back up manually. To backup your wallet, make a copy of the folder listed below:'
)}
</p>
<p>
<code>{__(`${daemonSettings.lbryum_wallet_dir}`)}</code>
<code>{lbryum_wallet_dir}</code>
</p>
</div>
<div className="card__content">
<p>
<strong>
{__(
@ -50,11 +59,14 @@ class BackupPage extends React.PureComponent {
<p>
For more details on backing up and best practices,{' '}
<Link
fakeLink
href="https://lbry.io/faq/how-to-backup-wallet"
label={__('see this article')}
/>.
</p>
</div>
</React.Fragment>
)}
</section>
</Page>
);

View file

@ -9,16 +9,16 @@ const GetCreditsPage = props => (
<RewardSummary />
<ShapeShift />
<section className="card card--section">
<div className="card__title-primary">
<h2>{__('From External Wallet')}</h2>
<div className="card__title">
{__('From External Wallet')}
</div>
<div className="card__actions">
<Link navigate="/send" label={__('Send / Receive')} />
</div>
</section>
<section className="card card--section">
<div className="card__title-primary">
<h2>{__('More ways to get LBRY Credits')}</h2>
<div className="card__title">
{__('More ways to get LBRY Credits')}
</div>
<div className="card__content">
<p>

View file

@ -19,7 +19,7 @@ class HelpPage extends React.PureComponent {
};
}
componentWillMount() {
componentDidMount() {
lbry.getAppVersionInfo().then(({ remoteVersion, localVersion, upgradeAvailable }) => {
this.setState({
uiVersion: localVersion,
@ -71,76 +71,71 @@ class HelpPage extends React.PureComponent {
return (
<Page>
<section className="card">
<div className="card__title-primary">
<h3>{__('Read the FAQ')}</h3>
<section className="card card--section">
<div className="card__title">
{__('Read the FAQ')}
</div>
<div className="card__content">
<p>{__('Our FAQ answers many common questions.')}</p>
<p>
<Link
href="https://lbry.io/faq"
label={__('Read the FAQ')}
icon="icon-question"
button="alt"
/>
</p>
</div>
</section>
<section className="card">
<div className="card__title-primary">
<h3>{__('Get Live Help')}</h3>
</div>
<div className="card__content">
<p>
{__('Live help is available most hours in the')} <strong>#help</strong>{' '}
{__('channel of our Discord chat room.')}
</p>
<p>
<Link
button="alt"
label={__('Join Our Chat')}
icon="icon-comments"
href="https://chat.lbry.io"
/>
</p>
</div>
</section>
<section className="card">
<div className="card__title-primary">
<h3>{__('Report a Bug')}</h3>
</div>
<div className="card__content">
<p>{__('Did you find something wrong?')}</p>
<p>
<Link
navigate="/report"
label={__('Submit a Bug Report')}
icon="icon-bug"
button="alt"
/>
</p>
<div className="meta">{__('Thanks! LBRY is made by its users.')}</div>
<p className="card__subtitle">{__('Our FAQ answers many common questions.')}</p>
<div className="card__actions">
<Link
href="https://lbry.io/faq"
label={__('Read the FAQ')}
icon="HelpCircle"
button="alt"
/>
</div>
</section>
<section className="card">
<div className="card__title-primary">
<h3>{__('About')}</h3>
<section className="card card--section">
<div className="card__title">
{__('Get Live Help')}
</div>
<p className="card__subtitle">
{__('Live help is available most hours in the')} <strong>#help</strong>{' '}
{__('channel of our Discord chat room.')}
</p>
<div className="card__actions">
<Link
label={__('Join Our Chat')}
icon="MessageCircle"
href="https://chat.lbry.io"
/>
</div>
</section>
<section className="card card--section">
<div className="card__title">
{__('Report a Bug')}
</div>
<p className="card__subtitle">{__('Did you find something wrong?')}</p>
<div className="card__actions">
<Link
navigate="/report"
label={__('Submit a Bug Report')}
icon="Flag"
button="alt"
/>
</div>
<div className="card__meta">{__('Thanks! LBRY is made by its users.')}</div>
</section>
<section className="card card--section">
<div className="card__title">
{__('About')}
</div>
<div className="card__content">
{this.state.upgradeAvailable === null ? (
''
) : this.state.upgradeAvailable ? (
<p>
{__('A newer version of LBRY is available.')}{' '}
<Link href={newVerLink} label={__('Download now!')} />
</p>
) : (
<p>{__('Your copy of LBRY is up to date.')}</p>
)}
{this.state.upgradeAvailable !== null && this.state.upgradeAvailable ? (
<p>
{__('A newer version of LBRY is available.')}{' '}
<Link href={newVerLink} label={__('Download now!')} />
</p>
) : (
<p>{__('Your LBRY app is up to date.')}</p>
)}
{this.state.uiVersion && ver ? (
<table className="table-standard table-stretch table-standard--definition-list">
<table className="card__content table-standard table-stretch table-standard--definition-list">
<tbody>
<tr>
<th>{__('App')}</th>
@ -171,9 +166,9 @@ class HelpPage extends React.PureComponent {
<th>{__('Reward Eligible')}</th>
<td>
{user && user.is_reward_approved ? (
<Icon icon="icon-check" />
__("Yes")
) : (
<Icon icon="icon-ban" />
__("No")
)}
</td>
</tr>
@ -189,7 +184,7 @@ class HelpPage extends React.PureComponent {
<th>{__('Access Token')}</th>
<td>
{this.state.accessTokenHidden && (
<Link label={__('show')} onClick={this.showAccessToken.bind(this)} />
<Link fakeLink label={__('View')} onClick={this.showAccessToken.bind(this)} />
)}
{!this.state.accessTokenHidden &&
accessToken && (

View file

@ -233,7 +233,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
<section className="card card--section">
<div className="card__title">{__('Content Settings')}</div>
<div className="card__content">
<FormField
type="checkbox"
name="show_unavailable"
@ -251,7 +250,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
'NSFW content may include nudity, intense sexuality, profanity, or other adult content. By displaying NSFW content, you are affirming you are of legal age to view mature content in your country or jurisdiction. '
)}
/>
</div>
</section>
<section className="card card--section">

View file

@ -27,6 +27,7 @@ const defaultState = {
},
isNight: false,
languages: {},
daemonSettings: {}
};
reducers[ACTIONS.DAEMON_SETTINGS_RECEIVED] = (state, action) =>

View file

@ -60,25 +60,42 @@ export const selectNavLinks = createSelector(
page === 'rewards' ||
page === 'history';
let walletLink;
if (isWalletPage(currentPage)) {
// If they are on a wallet page, the top level link should direct them to the overview page
walletLink = '/wallet';
} else {
// check to see if they've recently been on a wallet sub-link
const previousStack = historyStack.slice().reverse();
const isMyLbryPage = page =>
page === 'downloaded' ||
page === 'published' ||
page === 'settings';
const previousStack = historyStack.slice().reverse();
const getPreviousSubLinkPath = (checkIfValidPage) => {
for (let i = 0; i < previousStack.length; i += 1) {
const currentStackItem = previousStack[i];
// Trim off the "/" from the path
const pageInStack = currentStackItem.path.slice(1);
if (isWalletPage(pageInStack)) {
walletLink = currentStackItem.path;
break;
if (checkIfValidPage(pageInStack)) {
return currentStackItem.path;
}
}
}
// Gets the last active sublink in a section
const getActiveSublink = (category) => {
if (category === 'wallet') {
const previousPath = getPreviousSubLinkPath(isWalletPage);
return previousPath ? previousPath : '/wallet';
} else if (category === 'myLbry') {
const previousPath = getPreviousSubLinkPath(isMyLbryPage);
return previousPath ? previousPath : '/downloaded';
}
return undefined;
}
const isCurrentlyWalletPage = isWalletPage(currentPage);
const isCurrentlyMyLbryPage = isMyLbryPage(currentPage);
const walletSubLinks = [
{
label: 'Overview',
@ -101,12 +118,30 @@ export const selectNavLinks = createSelector(
active: currentPage === 'rewards',
},
{
label: 'My Transactions',
label: 'Transactions',
path: '/history',
active: currentPage === 'history',
},
];
const myLbrySubLinks = [
{
label: 'Downloads',
path: '/downloaded',
active: currentPage === 'downloaded',
},
{
label: 'Publishes',
path: '/published',
active: currentPage === 'published',
},
{
label: 'Settings',
path: '/settings',
active: currentPage === 'settings',
},
]
const navLinks = {
primary: [
{
@ -125,27 +160,20 @@ export const selectNavLinks = createSelector(
secondary: [
{
label: 'Wallet',
path: walletLink || '/wallet', // If they've never been to a wallet page, take them to the overview
active:
currentPage === 'wallet' ||
!!walletSubLinks.find(({ path }) => currentPage === path.slice(1)),
subLinks: walletSubLinks,
icon: 'CreditCard',
subLinks: walletSubLinks,
path: isCurrentlyWalletPage ? '/wallet' : getActiveSublink('wallet'),
active: isWalletPage(currentPage)
},
{
label: 'Publish',
path: '/publish',
active: currentPage === 'publish',
icon: 'UploadCloud',
},
{
label: 'Settings',
path: '/settings',
active: currentPage === 'settings',
label: 'My LBRY',
icon: 'Settings',
subLinks: myLbrySubLinks,
path: isCurrentlyMyLbryPage ? '/downloaded' : getActiveSublink('myLbry'),
active: isMyLbryPage(currentPage)
},
{
label: 'Backup Wallet',
label: 'Backup',
path: '/backup',
active: currentPage === 'backup',
icon: 'Save',
@ -158,6 +186,7 @@ export const selectNavLinks = createSelector(
},
],
};
return navLinks;
}
);

View file

@ -54,6 +54,10 @@ body {
overflow: hidden;
}
* {
box-sizing: border-box;
}
h1,
h2,
h3,

View file

@ -88,7 +88,7 @@ $width-page-constrained: 800px;
/* Button */
--btn-primary-color: #fff;
--button-alt-color: var(--text-color);
--btn-primary-bg: var(--color-primary-dark);
--btn-primary-bg: var(--color-primary);
--btn-inverse-color: var(--color-primary-dark);
--btn-inverse-bg: var(--color-white);
--btn-radius: 20px;

View file

@ -21,8 +21,5 @@
@import 'component/_markdown-editor.scss';
@import 'component/_scrollbar.scss';
@import 'component/_divider.scss';
@import 'component/_checkbox.scss';
@import 'component/_radio.scss';
@import 'component/_shapeshift.scss';
@import 'component/_spinner.scss';
@import 'component/_nav.scss';

View file

@ -37,7 +37,11 @@
min-width: var(--btn-height);
border-radius: var(--btn-radius);
color: var(--btn-primary-color);
background-color: var(--btn-primary-bg);
// TODO: Why does using --color-primary not work here? something is being overriden
// background-color: var(--color-primary);
background-color: #44b098;
display: flex;
align-items: center;
justify-content: center;
@ -111,7 +115,6 @@
&:hover {
box-shadow: none;
color: var(--color-primary);
}
}

View file

@ -67,8 +67,8 @@
}
.card__title {
font-size: 1.5em;
font-weight: 800;
font-size: 1.2em;
font-weight: 700;
padding: 0;
}
@ -88,6 +88,12 @@
padding-top: 0;
}
.card__meta {
color: var(--color-help);
font-size: 0.85em;
padding-top: $spacing-vertical * 2/3;
}
// .card-media__internal__links should always be inside a card
.card {
.card-media__internal-links {
@ -109,10 +115,6 @@
display: flex;
justify-content: space-between;
align-items: center;
.card__actions .btn:not(:first-of-type) {
margin-left: $spacing-vertical / 3;
}
}
.card__content {
@ -137,10 +139,14 @@
.card__actions {
margin-top: var(--card-margin);
display: flex;
.btn:nth-child(n + 2) {
margin-left: $spacing-vertical / 3;
}
}
.card__actions--no-margin {
magin-top: 0;
margin-top: 0;
}
.card__actions--vertical {

View file

@ -1,69 +0,0 @@
*,
*:before,
*:after {
box-sizing: border-box;
}
$md-checkbox-checked-color: var(--color-primary);
$md-checkbox-border-color: var(--input-border-color);
$md-checkbox-size: 20px;
$md-checkbox-padding: 4px;
$md-checkmark-width: 2px;
$md-checkmark-color: #fff;
.form-field--checkbox {
position: relative;
label {
cursor: pointer;
&:before,
&:after {
content: '';
position: absolute;
left: 0;
top: 0;
}
&:before {
// box
width: $md-checkbox-size;
height: $md-checkbox-size;
background: transparent;
border: 2px solid $md-checkbox-border-color;
border-radius: 2px;
cursor: pointer;
transition: background 0.3s;
}
&:after {
// checkmark
}
}
input[type='checkbox'] {
outline: 0;
visibility: hidden;
margin-right: 16px;
&:checked {
+ label:before {
background: $md-checkbox-checked-color;
border: none;
}
+ label:after {
$md-checkmark-size: $md-checkbox-size - 2*$md-checkbox-padding;
transform: rotate(-45deg);
top: ($md-checkbox-size / 2) - ($md-checkmark-size / 4) - $md-checkbox-size/10;
left: $md-checkbox-padding;
width: $md-checkmark-size;
height: $md-checkmark-size / 2;
border: $md-checkmark-width solid $md-checkmark-color;
border-top-style: none;
border-right-style: none;
}
}
}
}

View file

@ -14,6 +14,16 @@
&.form-row--centered {
align-items: center;
}
.form-field--strech {
flex: 1;
}
}
.form-field {
label {
cursor: pointer;
}
}
.form-field__input {
@ -26,18 +36,12 @@
}
}
.form-field {
label {
cursor: pointer;
}
}
.form-field__error {
color: var(--color-error);
}
.form-field__label {
color: var(--color-grey-dark);
color: var(--color-black);
}
.form-field__help {

View file

@ -1,51 +1,84 @@
.nav {
grid-area: nav;
background-color: var(--color-nav-bg);
padding-top: 16px;
hr {
width: 40px;
border: solid 1px var(--color-grey);
margin: $spacing-vertical $spacing-vertical * 2/3 $spacing-vertical * 2;
margin: $spacing-vertical $spacing-vertical * 2/3;
}
}
.nav__actions-top {
height: var(--header-height);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 5px;
padding: 0 $spacing-vertical * 1/3;
}
.nav__actions-history {
display: flex;
.btn {
margin-left: $spacing-vertical * 1/3;
}
}
// Sidebar links
.nav__primary {
padding-top: $spacing-vertical * 3;
padding-top: $spacing-vertical;
}
.nav__link {
padding: $spacing-vertical / 3 0 $spacing-vertical / 3 $spacing-vertical * 2/3;
font-weight: bold;
color: var(--color-grey-dark);
// The hover effect should be on the li
// Need to have the button grow
& .btn:hover {
.btn:hover {
color: var(--color-black);
}
.btn__label {
margin-left: $spacing-vertical * 1/3;
}
}
.nav__link--primary {
font-weight: bold;
}
.nav__link--sub {
font-size: .9em;
font-weight: 400;
margin-left: 5px;
color: var(--color-grey-dark);
padding: 5px $spacing-vertical * 2/3;
}
.nav__link--active {
color: var(--color-black);
}
.nav__sub-links {
padding-top: $spacing-vertical * 1/3;
}
// Sub links animations
// The -appear, -leave classes are added by 'react-transition-group'
.nav__sub-appear,
.nav__sub-leave {
max-height: 0;
opacity: 0;
}
.nav__sub-appear.nav__sub-appear-active {
// using max-height is a hack to animate to height "auto"
// Needs to be some arbitrarily large height
max-height: 500px;
opacity: 1;
transition: max-height .5s ease-in-out, opacity .5s ease-in-out;
}
.nav__sub {
padding-top: 5px;
}
.nav__sub-link {
padding: 5px $spacing-vertical * 2/3;
font-size: 0.8em;
}

View file

@ -1,54 +0,0 @@
$md-radio-checked-color: var(--color-primary);
$md-radio-border-color: var(--input-border-color);
$md-radio-size: 20px;
$md-radio-checked-size: 10px;
$md-radio-ripple-size: 15px;
.form-field--radio {
position: relative;
label {
cursor: pointer;
&:before,
&:after {
content: '';
position: absolute;
left: 0;
top: 0;
border-radius: 50%;
transition: all 0.3s ease;
transition-property: transform, border-color;
}
&:before {
width: $md-radio-size;
height: $md-radio-size;
background: transparent;
border: 2px solid $md-radio-border-color;
cursor: pointer;
}
&:after {
top: $md-radio-size / 2 - $md-radio-checked-size / 2;
left: $md-radio-size / 2 - $md-radio-checked-size / 2;
width: $md-radio-checked-size;
height: $md-radio-checked-size;
transform: scale(0);
background: $md-radio-checked-color;
}
}
input[type='radio'] {
visibility: hidden;
margin-right: 16px;
&:checked + label:before {
border-color: $md-radio-checked-color;
}
&:checked + label:after {
transform: scale(1);
}
}
}

View file

@ -1819,6 +1819,10 @@ center-align@^0.1.1:
align-text "^0.1.3"
lazy-cache "^1.0.3"
chain-function@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc"
chainsaw@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98"
@ -2756,6 +2760,10 @@ dom-converter@~0.1:
dependencies:
utila "~0.3"
dom-helpers@^3.2.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
dom-scroll-into-view@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz#e8f36732dd089b0201a88d7815dc3f88e6d66c7e"
@ -7342,7 +7350,7 @@ promzard@^0.3.0:
dependencies:
read "1"
prop-types@^15.5.1, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0:
prop-types@^15.5.1, prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0:
version "15.6.0"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
dependencies:
@ -7613,6 +7621,16 @@ react-simplemde-editor@^3.6.11:
react "^0.14.2"
simplemde "^1.11.2"
react-transition-group@1.x:
version "1.2.1"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6"
dependencies:
chain-function "^1.0.0"
dom-helpers "^3.2.0"
loose-envify "^1.3.1"
prop-types "^15.5.6"
warning "^3.0.0"
react@^0.14.2:
version "0.14.9"
resolved "https://registry.yarnpkg.com/react/-/react-0.14.9.tgz#9110a6497c49d44ba1c0edd317aec29c2e0d91d1"