Merge pull request #1940 from lbryio/publish-overtake-amounts
Better messaging for takeover amounts on publish page
This commit is contained in:
commit
0b07ff61cf
7 changed files with 171 additions and 116 deletions
|
@ -1,72 +1,36 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import Button from 'component/button';
|
|
||||||
import { buildURI } from 'lbry-redux';
|
|
||||||
import type { Claim } from 'types/claim';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: ?string,
|
uri: ?string,
|
||||||
isResolvingUri: boolean,
|
isResolvingUri: boolean,
|
||||||
winningBidForClaimUri: ?number,
|
amountNeededForTakeover: ?number,
|
||||||
myClaimForUri: ?Claim,
|
|
||||||
isStillEditing: boolean,
|
|
||||||
onEditMyClaim: (any, string) => void,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BidHelpText extends React.PureComponent<Props> {
|
class BidHelpText extends React.PureComponent<Props> {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const { uri, isResolvingUri, amountNeededForTakeover } = this.props;
|
||||||
uri,
|
let bidHelpText;
|
||||||
isResolvingUri,
|
|
||||||
winningBidForClaimUri,
|
|
||||||
myClaimForUri,
|
|
||||||
onEditMyClaim,
|
|
||||||
isStillEditing,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if (!uri) {
|
if (uri) {
|
||||||
return __('Create a URL for this content.');
|
if (isResolvingUri) {
|
||||||
|
bidHelpText = __('Checking the winning claim amount...');
|
||||||
|
} else if (!amountNeededForTakeover) {
|
||||||
|
bidHelpText = __('Any amount will give you the winning bid.');
|
||||||
|
} else {
|
||||||
|
bidHelpText = `${__('If you bid more than')} ${amountNeededForTakeover} LBC, ${__(
|
||||||
|
'when someone navigates to'
|
||||||
|
)} ${uri} ${__('it will load your published content')}. ${__(
|
||||||
|
'However, you can get a longer version of this URL for any bid'
|
||||||
|
)}.`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStillEditing) {
|
return (
|
||||||
return __(
|
|
||||||
'You are currently editing this claim. If you change the URL, you will need to reselect a file.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isResolvingUri) {
|
|
||||||
return __('Checking the winning claim amount...');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (myClaimForUri) {
|
|
||||||
const editUri = buildURI({
|
|
||||||
contentName: myClaimForUri.name,
|
|
||||||
claimId: myClaimForUri.claim_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
{__('You already have a claim at')}
|
|
||||||
{` ${uri} `}
|
|
||||||
<Button
|
|
||||||
button="link"
|
|
||||||
label="Edit it"
|
|
||||||
onClick={() => onEditMyClaim(myClaimForUri, editUri)}
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
{__('Publishing will update your existing claim.')}
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return winningBidForClaimUri ? (
|
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{__('A deposit greater than')} {winningBidForClaimUri} {__('is needed to win')}
|
{__('This LBC remains yours and the deposit can be undone at any time.')}
|
||||||
{` ${uri}. `}
|
<div>{bidHelpText}</div>
|
||||||
{__('However, you can still get this URL for any amount.')}
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
) : (
|
|
||||||
__('Any amount will give you the winning bid.')
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
// @flow
|
||||||
|
import * as React from 'react';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import { buildURI } from 'lbry-redux';
|
||||||
|
import type { Claim } from 'types/claim';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
uri: ?string,
|
||||||
|
myClaimForUri: ?Claim,
|
||||||
|
isStillEditing: boolean,
|
||||||
|
onEditMyClaim: (any, string) => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
class NameHelpText extends React.PureComponent<Props> {
|
||||||
|
render() {
|
||||||
|
const { uri, myClaimForUri, onEditMyClaim, isStillEditing } = this.props;
|
||||||
|
|
||||||
|
let nameHelpText;
|
||||||
|
|
||||||
|
if (isStillEditing) {
|
||||||
|
nameHelpText = __(
|
||||||
|
'You are currently editing this claim. If you change the URL, you will need to reselect a file.'
|
||||||
|
);
|
||||||
|
} else if (uri && myClaimForUri) {
|
||||||
|
const editUri = buildURI({
|
||||||
|
contentName: myClaimForUri.name,
|
||||||
|
claimId: myClaimForUri.claim_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
nameHelpText = (
|
||||||
|
<React.Fragment>
|
||||||
|
{__('You already have a claim at')}
|
||||||
|
{` ${uri} `}
|
||||||
|
<Button
|
||||||
|
button="link"
|
||||||
|
label="Edit it"
|
||||||
|
onClick={() => onEditMyClaim(myClaimForUri, editUri)}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
{__('Publishing will update your existing claim.')}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <React.Fragment>{nameHelpText || __('Create a URL for this content.')}</React.Fragment>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NameHelpText;
|
|
@ -13,6 +13,7 @@ import { CHANNEL_NEW, CHANNEL_ANONYMOUS, MINIMUM_PUBLISH_BID } from 'constants/c
|
||||||
import * as icons from 'constants/icons';
|
import * as icons from 'constants/icons';
|
||||||
import type { Claim } from 'types/claim';
|
import type { Claim } from 'types/claim';
|
||||||
import BidHelpText from './internal/bid-help-text';
|
import BidHelpText from './internal/bid-help-text';
|
||||||
|
import NameHelpText from './internal/name-help-text';
|
||||||
import LicenseType from './internal/license-type';
|
import LicenseType from './internal/license-type';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -53,8 +54,9 @@ type Props = {
|
||||||
clearPublish: () => void,
|
clearPublish: () => void,
|
||||||
resolveUri: string => void,
|
resolveUri: string => void,
|
||||||
scrollToTop: () => void,
|
scrollToTop: () => void,
|
||||||
prepareEdit: ({ }) => void,
|
prepareEdit: ({}) => void,
|
||||||
resetThumbnailStatus: () => void,
|
resetThumbnailStatus: () => void,
|
||||||
|
amountNeededForTakeover: ?number,
|
||||||
};
|
};
|
||||||
|
|
||||||
class PublishForm extends React.PureComponent<Props> {
|
class PublishForm extends React.PureComponent<Props> {
|
||||||
|
@ -84,6 +86,7 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
// If they are midway through a channel creation, treat it as anonymous until it completes
|
// If they are midway through a channel creation, treat it as anonymous until it completes
|
||||||
const channelName = channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW ? '' : channel;
|
const channelName = channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW ? '' : channel;
|
||||||
|
|
||||||
|
// We are only going to store the full uri, but we need to resolve the uri with and without the channel name
|
||||||
let uri;
|
let uri;
|
||||||
try {
|
try {
|
||||||
uri = buildURI({ contentName: name, channelName });
|
uri = buildURI({ contentName: name, channelName });
|
||||||
|
@ -92,6 +95,11 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uri) {
|
if (uri) {
|
||||||
|
if (channelName) {
|
||||||
|
// resolve without the channel name so we know the winning bid for it
|
||||||
|
const uriLessChannel = buildURI({ contentName: name });
|
||||||
|
resolveUri(uriLessChannel);
|
||||||
|
}
|
||||||
resolveUri(uri);
|
resolveUri(uri);
|
||||||
return uri;
|
return uri;
|
||||||
}
|
}
|
||||||
|
@ -295,8 +303,9 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
{name && nameError && <div>{__('The URL you created is not valid')}</div>}
|
{name && nameError && <div>{__('The URL you created is not valid')}</div>}
|
||||||
{!bid && <div>{__('A bid amount is required')}</div>}
|
{!bid && <div>{__('A bid amount is required')}</div>}
|
||||||
{!!bid && bidError && <div>{bidError}</div>}
|
{!!bid && bidError && <div>{bidError}</div>}
|
||||||
{uploadThumbnailStatus === THUMBNAIL_STATUSES.IN_PROGRESS
|
{uploadThumbnailStatus === THUMBNAIL_STATUSES.IN_PROGRESS && (
|
||||||
&& <div>{__('Please wait for thumbnail to finish uploading')}</div>}
|
<div>{__('Please wait for thumbnail to finish uploading')}</div>
|
||||||
|
)}
|
||||||
{!tosAccepted && <div>{__('You must agree to the terms of service')}</div>}
|
{!tosAccepted && <div>{__('You must agree to the terms of service')}</div>}
|
||||||
{!!editingURI &&
|
{!!editingURI &&
|
||||||
!isStillEditing &&
|
!isStillEditing &&
|
||||||
|
@ -338,6 +347,7 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
thumbnailPath,
|
thumbnailPath,
|
||||||
resetThumbnailStatus,
|
resetThumbnailStatus,
|
||||||
isStillEditing,
|
isStillEditing,
|
||||||
|
amountNeededForTakeover,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const formDisabled = (!filePath && !editingURI) || publishing;
|
const formDisabled = (!filePath && !editingURI) || publishing;
|
||||||
|
@ -350,19 +360,17 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
submitLabel = !publishing ? __('Publish') : __('Publishing...');
|
submitLabel = !publishing ? __('Publish') : __('Publishing...');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const shortUri = buildURI({ contentName: name });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form onSubmit={this.handlePublish}>
|
<Form onSubmit={this.handlePublish}>
|
||||||
<section className={classnames('card card--section', { 'card--disabled': publishing })}>
|
<section className={classnames('card card--section', { 'card--disabled': publishing })}>
|
||||||
<div className="card__title">{__('Content')}</div>
|
<div className="card__title">{__('Content')}</div>
|
||||||
<div className="card__subtitle">
|
<div className="card__subtitle">
|
||||||
{isStillEditing ? __('Editing a claim') : __('What are you publishing?')}
|
{isStillEditing ? __('Editing a claim') : __('What are you publishing?')}{' '}
|
||||||
{' '}{__(
|
{__('Read our')}{' '}
|
||||||
'Read our'
|
|
||||||
)}{' '}
|
|
||||||
<Button button="link" label={__('FAQ')} href="https://lbry.io/faq/how-to-publish" />{' '}
|
<Button button="link" label={__('FAQ')} href="https://lbry.io/faq/how-to-publish" />{' '}
|
||||||
{__(
|
{__('to learn more.')}
|
||||||
'to learn more.'
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{(filePath || !!editingURI) && (
|
{(filePath || !!editingURI) && (
|
||||||
<div className="card-media__internal-links">
|
<div className="card-media__internal-links">
|
||||||
|
@ -420,12 +428,12 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
{uploadThumbnailStatus === THUMBNAIL_STATUSES.API_DOWN ? (
|
{uploadThumbnailStatus === THUMBNAIL_STATUSES.API_DOWN ? (
|
||||||
__('Enter a URL for your thumbnail.')
|
__('Enter a URL for your thumbnail.')
|
||||||
) : (
|
) : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{__('Upload your thumbnail (.png/.jpg/.jpeg/.gif) to')}{' '}
|
{__('Upload your thumbnail (.png/.jpg/.jpeg/.gif) to')}{' '}
|
||||||
<Button button="link" label={__('spee.ch')} href="https://spee.ch/about" />.{' '}
|
<Button button="link" label={__('spee.ch')} href="https://spee.ch/about" />.{' '}
|
||||||
{__('Recommended size: 800x450 (16:9)')}
|
{__('Recommended size: 800x450 (16:9)')}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<SelectThumbnail
|
<SelectThumbnail
|
||||||
thumbnailPath={thumbnailPath}
|
thumbnailPath={thumbnailPath}
|
||||||
|
@ -496,11 +504,12 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
<FormRow>
|
<FormRow>
|
||||||
<FormField
|
<FormField
|
||||||
stretch
|
stretch
|
||||||
|
label={__('Name')}
|
||||||
prefix={`lbry://${
|
prefix={`lbry://${
|
||||||
!channel || channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW
|
!channel || channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW
|
||||||
? ''
|
? ''
|
||||||
: `${channel}/`
|
: `${channel}/`
|
||||||
}`}
|
}`}
|
||||||
type="text"
|
type="text"
|
||||||
name="content_name"
|
name="content_name"
|
||||||
placeholder="myname"
|
placeholder="myname"
|
||||||
|
@ -508,12 +517,9 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
onChange={event => this.handleNameChange(event.target.value)}
|
onChange={event => this.handleNameChange(event.target.value)}
|
||||||
error={nameError}
|
error={nameError}
|
||||||
helper={
|
helper={
|
||||||
<BidHelpText
|
<NameHelpText
|
||||||
isStillEditing={isStillEditing}
|
isStillEditing={isStillEditing}
|
||||||
uri={uri}
|
uri={uri}
|
||||||
editingURI={editingURI}
|
|
||||||
isResolvingUri={isResolvingUri}
|
|
||||||
winningBidForClaimUri={winningBidForClaimUri}
|
|
||||||
myClaimForUri={myClaimForUri}
|
myClaimForUri={myClaimForUri}
|
||||||
onEditMyClaim={this.editExistingClaim}
|
onEditMyClaim={this.editExistingClaim}
|
||||||
/>
|
/>
|
||||||
|
@ -534,8 +540,14 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
min="0"
|
min="0"
|
||||||
disabled={!name}
|
disabled={!name}
|
||||||
onChange={event => this.handleBidChange(parseFloat(event.target.value))}
|
onChange={event => this.handleBidChange(parseFloat(event.target.value))}
|
||||||
helper={__('This LBC remains yours and the deposit can be undone at any time.')}
|
|
||||||
placeholder={winningBidForClaimUri ? winningBidForClaimUri + 0.1 : 0.1}
|
placeholder={winningBidForClaimUri ? winningBidForClaimUri + 0.1 : 0.1}
|
||||||
|
helper={
|
||||||
|
<BidHelpText
|
||||||
|
uri={shortUri}
|
||||||
|
isResolvingUri={isResolvingUri}
|
||||||
|
amountNeededForTakeover={amountNeededForTakeover}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -81,6 +81,7 @@ class FilePage extends React.Component<Props> {
|
||||||
this.checkSubscription(this.props);
|
this.checkSubscription(this.props);
|
||||||
|
|
||||||
setViewed(uri);
|
setViewed(uri);
|
||||||
|
console.log('claim', this.props.claim);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps: Props) {
|
componentWillReceiveProps(nextProps: Props) {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doResolveUri, selectClaimsByUri, selectResolvingUris, selectBalance } from 'lbry-redux';
|
import { doResolveUri, selectBalance } from 'lbry-redux';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import {
|
import {
|
||||||
selectPublishFormValues,
|
selectPublishFormValues,
|
||||||
selectIsStillEditing,
|
selectIsStillEditing,
|
||||||
selectMyClaimForUri,
|
selectMyClaimForUri,
|
||||||
|
selectIsResolvingPublishUris,
|
||||||
|
selectTakeOverAmount,
|
||||||
} from 'redux/selectors/publish';
|
} from 'redux/selectors/publish';
|
||||||
import {
|
import {
|
||||||
doResetThumbnailStatus,
|
doResetThumbnailStatus,
|
||||||
|
@ -15,43 +17,18 @@ import {
|
||||||
} from 'redux/actions/publish';
|
} from 'redux/actions/publish';
|
||||||
import PublishPage from './view';
|
import PublishPage from './view';
|
||||||
|
|
||||||
const select = state => {
|
const select = state => ({
|
||||||
const isStillEditing = selectIsStillEditing(state);
|
...selectPublishFormValues(state),
|
||||||
const myClaimForUri = selectMyClaimForUri(state);
|
// The winning claim for a short lbry uri
|
||||||
const publishState = selectPublishFormValues(state);
|
amountNeededForTakeover: selectTakeOverAmount(state),
|
||||||
const { uri } = publishState;
|
// My previously published claims under this short lbry uri
|
||||||
|
myClaimForUri: selectMyClaimForUri(state),
|
||||||
const resolvingUris = selectResolvingUris(state);
|
// If I clicked the "edit" button, have I changed the uri?
|
||||||
let isResolvingUri = false;
|
// Need this to make it easier to find the source on previously published content
|
||||||
if (uri) {
|
isStillEditing: selectIsStillEditing(state),
|
||||||
isResolvingUri = resolvingUris.includes(uri);
|
balance: selectBalance(state),
|
||||||
}
|
isResolvingUri: selectIsResolvingPublishUris(state),
|
||||||
|
});
|
||||||
let claimForUri;
|
|
||||||
let winningBidForClaimUri;
|
|
||||||
if (!myClaimForUri) {
|
|
||||||
// if the uri isn't from a users claim, find the winning bid needed for the vanity url
|
|
||||||
// in the future we may want to display this on users claims
|
|
||||||
// ex: "you own this, for 5 more lbc you will win this claim"
|
|
||||||
const claimsByUri = selectClaimsByUri(state);
|
|
||||||
claimForUri = claimsByUri[uri];
|
|
||||||
winningBidForClaimUri = claimForUri ? claimForUri.effective_amount : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...publishState,
|
|
||||||
isResolvingUri,
|
|
||||||
// The winning claim for a short lbry uri
|
|
||||||
claimForUri,
|
|
||||||
winningBidForClaimUri,
|
|
||||||
// My previously published claims under this short lbry uri
|
|
||||||
myClaimForUri,
|
|
||||||
// If I clicked the "edit" button, have I changed the uri?
|
|
||||||
// Need this to make it easier to find the source on previously published content
|
|
||||||
isStillEditing,
|
|
||||||
balance: selectBalance(state),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
updatePublishForm: value => dispatch(doUpdatePublishForm(value)),
|
updatePublishForm: value => dispatch(doUpdatePublishForm(value)),
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { parseURI, selectClaimsById, selectMyClaimsWithoutChannels } from 'lbry-redux';
|
import {
|
||||||
|
parseURI,
|
||||||
|
selectClaimsById,
|
||||||
|
selectMyClaimsWithoutChannels,
|
||||||
|
selectResolvingUris,
|
||||||
|
buildURI,
|
||||||
|
selectClaimsByUri,
|
||||||
|
} from 'lbry-redux';
|
||||||
|
|
||||||
const selectState = state => state.publish || {};
|
const selectState = state => state.publish || {};
|
||||||
|
|
||||||
|
@ -93,3 +100,48 @@ export const selectMyClaimForUri = createSelector(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectIsResolvingPublishUris = createSelector(
|
||||||
|
selectState,
|
||||||
|
selectResolvingUris,
|
||||||
|
({ uri, name }, resolvingUris) => {
|
||||||
|
if (uri) {
|
||||||
|
const isResolvingUri = resolvingUris.includes(uri);
|
||||||
|
const { isChannel } = parseURI(uri);
|
||||||
|
|
||||||
|
let isResolvingShortUri;
|
||||||
|
if (isChannel) {
|
||||||
|
const shortUri = buildURI({ contentName: name });
|
||||||
|
isResolvingShortUri = resolvingUris.includes(shortUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isResolvingUri || isResolvingShortUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectTakeOverAmount = createSelector(
|
||||||
|
selectState,
|
||||||
|
selectMyClaimForUri,
|
||||||
|
selectClaimsByUri,
|
||||||
|
({ name }, myClaimForUri, claimsByUri) => {
|
||||||
|
// We only care about the winning claim for the short uri
|
||||||
|
const shortUri = buildURI({ contentName: name });
|
||||||
|
const claimForShortUri = claimsByUri[shortUri];
|
||||||
|
|
||||||
|
if (!myClaimForUri && claimForShortUri) {
|
||||||
|
return claimForShortUri.effective_amount;
|
||||||
|
} else if (myClaimForUri && claimForShortUri) {
|
||||||
|
// https://github.com/lbryio/lbry/issues/1476
|
||||||
|
// We should check the current effective_amount on my claim to see how much additional lbc
|
||||||
|
// is needed to win the claim. Currently this is not possible during a takeover.
|
||||||
|
// With this, we could say something like, "You have x lbc in support, if you bid y additional LBC you will control the claim"
|
||||||
|
// For now just ignore supports. We will just show the winning claim's bid amount
|
||||||
|
return claimForShortUri.effective_amount || claimForShortUri.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
|
|
||||||
.form-field__help {
|
.form-field__help {
|
||||||
color: var(--color-help);
|
color: var(--color-help);
|
||||||
padding-top: $spacing-vertical * 2/3;
|
padding-top: $spacing-vertical * 1/3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-field__error {
|
.form-field__error {
|
||||||
|
|
Loading…
Reference in a new issue