Add Checkout Form components (https://github.com/woocommerce/woocommerce-blocks/pull/1351)
* initial commit at fields * add radio control * change input to be uncotrolled * tweak styles * populate block with boilerplate * update aria in radio * remove comment * fix typo * add missing colors * put reminder to put Disabled back * wrap text in i18n __ * reorder styles * rename wc-components to wc-blocks * use value instead of index for keys * add no shipping placeholder * change isEditor default to false * fix problem with responsive
This commit is contained in:
parent
af5af78266
commit
d58712ee2b
|
@ -47,5 +47,9 @@ $core-orange: #ca4a1f;
|
||||||
// @todo: replace those colors with the correct values once we settle on a design system palette.
|
// @todo: replace those colors with the correct values once we settle on a design system palette.
|
||||||
$gray-10: #c3c4c7;
|
$gray-10: #c3c4c7;
|
||||||
$gray-20: #a7aaad;
|
$gray-20: #a7aaad;
|
||||||
|
$gray-50: #646970;
|
||||||
$gray-60: #50575e;
|
$gray-60: #50575e;
|
||||||
$gray-80: #2c3338;
|
$gray-80: #2c3338;
|
||||||
|
// @todo: align those colors with what we have
|
||||||
|
$input-border-gray: #8d96a0;
|
||||||
|
$input-text-active: #2b2d2f;
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { Placeholder, Button } from '@wordpress/components';
|
||||||
|
import ShippingIcon from 'gridicons/dist/shipping';
|
||||||
|
import { ADMIN_URL } from '@woocommerce/settings';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
const NoShipping = () => {
|
||||||
|
return (
|
||||||
|
<Placeholder
|
||||||
|
icon={ <ShippingIcon /> }
|
||||||
|
label={ __( 'Shipping options', 'woo-gutenberg-products-block' ) }
|
||||||
|
className="wc-blocks-checkout__no-shipping"
|
||||||
|
>
|
||||||
|
<span className="wc-blocks-checkout__no-shipping-description">
|
||||||
|
{ __(
|
||||||
|
'Your store does not have any Shipping Options configured. Once you have added your Shipping Options they will appear here.',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
isDefault
|
||||||
|
href={ `${ ADMIN_URL }admin.php?page=wc-settings&tab=shipping` }
|
||||||
|
>
|
||||||
|
{ __(
|
||||||
|
'Configure Shipping Options',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
</Button>
|
||||||
|
</Placeholder>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NoShipping;
|
|
@ -0,0 +1,5 @@
|
||||||
|
.wc-blocks-checkout__no-shipping-description {
|
||||||
|
display: block;
|
||||||
|
margin: 0.25em 0 1em 0;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
const InputRow = ( { className, children } ) => {
|
||||||
|
return (
|
||||||
|
<div className={ classnames( 'wc-blocks-input-row', className ) }>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default InputRow;
|
|
@ -0,0 +1,21 @@
|
||||||
|
.wc-blocks-input-row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
& > .wc-blocks-text-input {
|
||||||
|
margin-right: $gap-small;
|
||||||
|
flex-grow: 1;
|
||||||
|
margin-top: $gap;
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Responsive media styles.
|
||||||
|
@include breakpoint( "<480px" ) {
|
||||||
|
.wc-blocks-text-input {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import Label from '../label';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
const RadioControl = ( {
|
||||||
|
className,
|
||||||
|
selected,
|
||||||
|
id,
|
||||||
|
onChange,
|
||||||
|
options = [],
|
||||||
|
} ) => {
|
||||||
|
const onChangeValue = ( event ) => onChange( event.target.value );
|
||||||
|
return (
|
||||||
|
options.length && (
|
||||||
|
<div
|
||||||
|
className={ classnames( 'wc-blocks-radio-control', className ) }
|
||||||
|
>
|
||||||
|
{ options.map(
|
||||||
|
( {
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
description,
|
||||||
|
secondaryLabel,
|
||||||
|
secondaryDescription,
|
||||||
|
} ) => (
|
||||||
|
<label
|
||||||
|
key={ `${ id }-${ value }` }
|
||||||
|
className="wc-blocks-radio-control__option"
|
||||||
|
htmlFor={ `${ id }-${ value }` }
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id={ `${ id }-${ value }` }
|
||||||
|
className="wc-blocks-radio-control__input"
|
||||||
|
type="radio"
|
||||||
|
name={ id }
|
||||||
|
value={ value }
|
||||||
|
onChange={ onChangeValue }
|
||||||
|
checked={ value === selected }
|
||||||
|
aria-describedby={ classnames( {
|
||||||
|
[ `${ id }-${ value }__label` ]: label,
|
||||||
|
[ `${ id }-${ value }__secondary-label` ]: secondaryLabel,
|
||||||
|
[ `${ id }-${ value }__description` ]: description,
|
||||||
|
[ `${ id }-${ value }__secondary-description` ]: secondaryDescription,
|
||||||
|
} ) }
|
||||||
|
/>
|
||||||
|
{ label && (
|
||||||
|
<Label
|
||||||
|
label={ label }
|
||||||
|
wrapperElement="span"
|
||||||
|
wrapperProps={ {
|
||||||
|
className:
|
||||||
|
'wc-blocks-radio-control__label',
|
||||||
|
id: `${ id }-${ value }__label`,
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
{ label }
|
||||||
|
</Label>
|
||||||
|
) }
|
||||||
|
{ secondaryLabel && (
|
||||||
|
<Label
|
||||||
|
label={ secondaryLabel }
|
||||||
|
wrapperElement="span"
|
||||||
|
wrapperProps={ {
|
||||||
|
className:
|
||||||
|
'wc-blocks-radio-control__secondary-label',
|
||||||
|
id: `${ id }-${ value }__secondary-label`,
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
{ secondaryLabel }
|
||||||
|
</Label>
|
||||||
|
) }
|
||||||
|
{ description && (
|
||||||
|
<Label
|
||||||
|
label={ description }
|
||||||
|
wrapperElement="span"
|
||||||
|
wrapperProps={ {
|
||||||
|
className:
|
||||||
|
'wc-blocks-radio-control__description',
|
||||||
|
id: `${ id }-${ value }__description`,
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
{ description }
|
||||||
|
</Label>
|
||||||
|
) }
|
||||||
|
{ secondaryDescription && (
|
||||||
|
<Label
|
||||||
|
label={ secondaryDescription }
|
||||||
|
wrapperElement="span"
|
||||||
|
wrapperProps={ {
|
||||||
|
className:
|
||||||
|
'wc-blocks-radio-control__secondary-description',
|
||||||
|
id: `${ id }-${ value }__secondary-description`,
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
{ secondaryDescription }
|
||||||
|
</Label>
|
||||||
|
) }
|
||||||
|
</label>
|
||||||
|
)
|
||||||
|
) }
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RadioControl;
|
|
@ -0,0 +1,36 @@
|
||||||
|
.wc-blocks-radio-control__option {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: $gap-small $gap-small $gap-small ($gap-larger * 2);
|
||||||
|
border-bottom: 1px solid $core-grey-light-600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-blocks-radio-control__input {
|
||||||
|
position: absolute;
|
||||||
|
left: $gap-large;
|
||||||
|
top: $gap-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-blocks-radio-control__label,
|
||||||
|
.wc-blocks-radio-control__secondary-label {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
color: $core-grey-dark-600;
|
||||||
|
flex-basis: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-blocks-radio-control__description,
|
||||||
|
.wc-blocks-radio-control__secondary-description {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: $core-grey-dark-400;
|
||||||
|
flex-basis: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-blocks-radio-control__secondary-label,
|
||||||
|
.wc-blocks-radio-control__secondary-description {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import { useState } from '@wordpress/element';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import Label from '../label';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
const TextInput = ( {
|
||||||
|
className,
|
||||||
|
id,
|
||||||
|
ariaLabel,
|
||||||
|
label,
|
||||||
|
screenReaderLabel,
|
||||||
|
disabled,
|
||||||
|
help,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
} ) => {
|
||||||
|
const [ isActive, setIsActive ] = useState( false );
|
||||||
|
const onChangeValue = ( event ) => onChange( event.target.value );
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={ classnames( 'wc-blocks-text-input', className, {
|
||||||
|
'is-active': isActive || value,
|
||||||
|
} ) }
|
||||||
|
>
|
||||||
|
<Label
|
||||||
|
label={ label }
|
||||||
|
screenReaderLabel={ screenReaderLabel || label }
|
||||||
|
wrapperElement="label"
|
||||||
|
wrapperProps={ {
|
||||||
|
htmlFor: id,
|
||||||
|
} }
|
||||||
|
htmlFor={ id }
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id={ id }
|
||||||
|
value={ value }
|
||||||
|
onChange={ onChangeValue }
|
||||||
|
onFocus={ () => setIsActive( true ) }
|
||||||
|
onBlur={ () => setIsActive( false ) }
|
||||||
|
aria-label={ ariaLabel || label }
|
||||||
|
disabled={ disabled }
|
||||||
|
aria-describedby={ !! help ? id + '__help' : undefined }
|
||||||
|
/>
|
||||||
|
{ !! help && (
|
||||||
|
<p id={ id + '__help' } className="wc-blocks-text-input__help">
|
||||||
|
{ help }
|
||||||
|
</p>
|
||||||
|
) }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
TextInput.propTypes = {
|
||||||
|
id: PropTypes.string,
|
||||||
|
value: PropTypes.string,
|
||||||
|
onChangeValue: PropTypes.func,
|
||||||
|
ariaLabel: PropTypes.string,
|
||||||
|
label: PropTypes.string,
|
||||||
|
screenReaderLabel: PropTypes.string,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
help: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TextInput;
|
|
@ -0,0 +1,36 @@
|
||||||
|
.wc-blocks-text-input {
|
||||||
|
position: relative;
|
||||||
|
margin-top: $gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-blocks-text-input label {
|
||||||
|
position: absolute;
|
||||||
|
transform: translateX(#{$gap}) translateY(#{$gap-small});
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
transition: all 200ms ease;
|
||||||
|
color: $gray-50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-blocks-text-input.is-active label {
|
||||||
|
transform: translateX(#{$gap - $gap-small}) translateY(#{$gap-smallest}) scale(0.75);
|
||||||
|
transition: all 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-blocks-text-input input[type="text"] {
|
||||||
|
padding: $gap-small $gap;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid $input-border-gray;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
font-family: inherit;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 48px;
|
||||||
|
color: $input-text-active;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-blocks-text-input.is-active input[type="text"] {
|
||||||
|
padding: $gap-large $gap $gap-smallest;
|
||||||
|
}
|
|
@ -1,12 +1,15 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { Fragment } from '@wordpress/element';
|
import { Fragment, useState } from '@wordpress/element';
|
||||||
import { Placeholder } from '@wordpress/components';
|
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import FormStep from '@woocommerce/base-components/checkout/form-step';
|
import FormStep from '@woocommerce/base-components/checkout/form-step';
|
||||||
import CheckoutForm from '@woocommerce/base-components/checkout/form';
|
import CheckoutForm from '@woocommerce/base-components/checkout/form';
|
||||||
|
import NoShipping from '@woocommerce/base-components/checkout/no-shipping';
|
||||||
|
import TextInput from '@woocommerce/base-components/text-input';
|
||||||
|
import RadioControl from '@woocommerce/base-components/radio-control';
|
||||||
|
import InputRow from '@woocommerce/base-components/input-row';
|
||||||
|
import { CheckboxControl, Placeholder } from '@wordpress/components';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
|
@ -15,7 +18,11 @@ import './style.scss';
|
||||||
/**
|
/**
|
||||||
* Component displaying an attribute filter.
|
* Component displaying an attribute filter.
|
||||||
*/
|
*/
|
||||||
const Block = () => {
|
const Block = ( { shippingMethods = [], isEditor = false } ) => {
|
||||||
|
const [ shippingMethod, setShippingMethod ] = useState( {} );
|
||||||
|
const [ contactFields, setContactFields ] = useState( {} );
|
||||||
|
const [ shouldSavePayment, setShouldSavePayment ] = useState( true );
|
||||||
|
const [ shippingFields, setShippingFields ] = useState( {} );
|
||||||
return (
|
return (
|
||||||
<CheckoutForm>
|
<CheckoutForm>
|
||||||
<FormStep
|
<FormStep
|
||||||
|
@ -42,8 +49,36 @@ const Block = () => {
|
||||||
</Fragment>
|
</Fragment>
|
||||||
) }
|
) }
|
||||||
>
|
>
|
||||||
<Placeholder>A checkout step, coming soon near you</Placeholder>
|
<TextInput
|
||||||
|
id="email-field"
|
||||||
|
label={ __(
|
||||||
|
'Email address',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ contactFields.email }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
setContactFields( {
|
||||||
|
...contactFields,
|
||||||
|
email: newValue,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<CheckboxControl
|
||||||
|
className="wc-blocks-checkout__keep-updated"
|
||||||
|
label={ __(
|
||||||
|
'Keep me up to date on news and exclusive offers',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
checked={ contactFields.keepUpdated }
|
||||||
|
onChange={ () =>
|
||||||
|
setContactFields( {
|
||||||
|
...contactFields,
|
||||||
|
keepUpdated: ! contactFields.keepUpdated,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
</FormStep>
|
</FormStep>
|
||||||
|
{ shippingMethods.length === 0 && (
|
||||||
<FormStep
|
<FormStep
|
||||||
id="shipping-fields"
|
id="shipping-fields"
|
||||||
className="wc-blocks-checkout__shipping-fields"
|
className="wc-blocks-checkout__shipping-fields"
|
||||||
|
@ -57,11 +92,174 @@ const Block = () => {
|
||||||
) }
|
) }
|
||||||
stepNumber={ 2 }
|
stepNumber={ 2 }
|
||||||
>
|
>
|
||||||
<Placeholder>A checkout step, coming soon near you</Placeholder>
|
{ isEditor && <NoShipping /> }
|
||||||
|
</FormStep>
|
||||||
|
) }
|
||||||
|
{ shippingMethods.length > 0 && (
|
||||||
|
<Fragment>
|
||||||
|
<FormStep
|
||||||
|
id="shipping-fields"
|
||||||
|
className="wc-blocks-checkout__shipping-fields"
|
||||||
|
title={ __(
|
||||||
|
'Shipping address',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
description={ __(
|
||||||
|
'Enter the physical address where you want us to deliver your order.',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
stepNumber={ 2 }
|
||||||
|
>
|
||||||
|
<InputRow>
|
||||||
|
<TextInput
|
||||||
|
id="shipping-first-name"
|
||||||
|
label={ __(
|
||||||
|
'First name',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ shippingFields.firstName }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
setShippingFields( {
|
||||||
|
...shippingFields,
|
||||||
|
firstName: newValue,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
id="shipping-last-name"
|
||||||
|
label={ __(
|
||||||
|
'Surname',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ shippingFields.lastName }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
setShippingFields( {
|
||||||
|
...shippingFields,
|
||||||
|
lastName: newValue,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</InputRow>
|
||||||
|
<TextInput
|
||||||
|
id="shipping-street-address"
|
||||||
|
label={ __(
|
||||||
|
'Street address',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ shippingFields.streetAddress }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
setShippingFields( {
|
||||||
|
...shippingFields,
|
||||||
|
streetAddress: newValue,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
id="shipping-apartment"
|
||||||
|
label={ __(
|
||||||
|
'Apartment, suite, etc.',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ shippingFields.apartment }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
setShippingFields( {
|
||||||
|
...shippingFields,
|
||||||
|
apartment: newValue,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<InputRow>
|
||||||
|
<TextInput
|
||||||
|
id="shipping-country"
|
||||||
|
label={ __(
|
||||||
|
'Country',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ shippingFields.country }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
setShippingFields( {
|
||||||
|
...shippingFields,
|
||||||
|
country: newValue,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
id="shipping-city"
|
||||||
|
label={ __(
|
||||||
|
'City',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ shippingFields.country }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
setShippingFields( {
|
||||||
|
...shippingFields,
|
||||||
|
country: newValue,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</InputRow>
|
||||||
|
<InputRow>
|
||||||
|
<TextInput
|
||||||
|
id="shipping-county"
|
||||||
|
label={ __(
|
||||||
|
'County',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ shippingFields.county }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
setShippingFields( {
|
||||||
|
...shippingFields,
|
||||||
|
county: newValue,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
id="shipping-postal-code"
|
||||||
|
label={ __(
|
||||||
|
'Postal code',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ shippingFields.postalCode }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
setShippingFields( {
|
||||||
|
...shippingFields,
|
||||||
|
postalCode: newValue,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</InputRow>
|
||||||
|
<TextInput
|
||||||
|
id="shipping-phone"
|
||||||
|
label={ __(
|
||||||
|
'Phone',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ shippingFields.phone }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
setShippingFields( {
|
||||||
|
...shippingFields,
|
||||||
|
phone: newValue,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<CheckboxControl
|
||||||
|
className="wc-blocks-checkout__use-address-for-billing"
|
||||||
|
label={ __(
|
||||||
|
'Use same address for billing',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
checked={ shippingFields.useSameForBilling }
|
||||||
|
onChange={ () =>
|
||||||
|
setShippingFields( {
|
||||||
|
...shippingFields,
|
||||||
|
useSameForBilling: ! shippingFields.useSameForBilling,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
</FormStep>
|
</FormStep>
|
||||||
<FormStep
|
<FormStep
|
||||||
id="shipping-methods"
|
id="shipping-option"
|
||||||
className="wc-blocks-checkout__shipping-methods"
|
className="wc-blocks-checkout__shipping-option"
|
||||||
title={ __(
|
title={ __(
|
||||||
'Shipping options',
|
'Shipping options',
|
||||||
'woo-gutenberg-products-block'
|
'woo-gutenberg-products-block'
|
||||||
|
@ -72,11 +270,56 @@ const Block = () => {
|
||||||
) }
|
) }
|
||||||
stepNumber={ 3 }
|
stepNumber={ 3 }
|
||||||
>
|
>
|
||||||
<Placeholder>A checkout step, coming soon near you</Placeholder>
|
<RadioControl
|
||||||
|
selected={ shippingMethod.method || 'collect' }
|
||||||
|
id="shipping-method"
|
||||||
|
onChange={ ( option ) =>
|
||||||
|
setShippingMethod( {
|
||||||
|
...shippingMethod,
|
||||||
|
method: option,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
options={ [
|
||||||
|
{
|
||||||
|
label: 'Click & Collect',
|
||||||
|
value: 'collect',
|
||||||
|
description:
|
||||||
|
'Pickup between 12:00 - 16:00 (Mon-Fri)',
|
||||||
|
secondaryLabel: 'FREE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Regular shipping',
|
||||||
|
value: 'usps-normal',
|
||||||
|
description: 'Dispatched via USPS',
|
||||||
|
secondaryLabel: '€10.00',
|
||||||
|
secondaryDescription: '5 business days',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Express shipping',
|
||||||
|
value: 'ups-express',
|
||||||
|
description: 'Dispatched via USPS',
|
||||||
|
secondaryLabel: '€50.00',
|
||||||
|
secondaryDescription: '2 business days',
|
||||||
|
},
|
||||||
|
] }
|
||||||
|
/>
|
||||||
|
<CheckboxControl
|
||||||
|
className="wc-blocks-checkout__add-note"
|
||||||
|
label="Add order notes?"
|
||||||
|
checked={ shippingMethod.orderNote }
|
||||||
|
onChange={ () =>
|
||||||
|
setShippingMethod( {
|
||||||
|
...shippingMethod,
|
||||||
|
orderNote: ! shippingMethod.orderNote,
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
</FormStep>
|
</FormStep>
|
||||||
|
</Fragment>
|
||||||
|
) }
|
||||||
<FormStep
|
<FormStep
|
||||||
id="payment-fields"
|
id="payment-method"
|
||||||
className="wc-blocks-checkout__payment-fields"
|
className="wc-blocks-checkout__payment-method"
|
||||||
title={ __( 'Payment method', 'woo-gutenberg-products-block' ) }
|
title={ __( 'Payment method', 'woo-gutenberg-products-block' ) }
|
||||||
description={ __(
|
description={ __(
|
||||||
'Select a payment method below.',
|
'Select a payment method below.',
|
||||||
|
@ -84,7 +327,18 @@ const Block = () => {
|
||||||
) }
|
) }
|
||||||
stepNumber={ 4 }
|
stepNumber={ 4 }
|
||||||
>
|
>
|
||||||
<Placeholder>A checkout step, coming soon near you</Placeholder>
|
<Placeholder>Payment methods, coming soon</Placeholder>
|
||||||
|
<CheckboxControl
|
||||||
|
className="wc-blocks-checkout__save-card-info"
|
||||||
|
label={ __(
|
||||||
|
'Save payment information to my account for future purchases.',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
checked={ shouldSavePayment }
|
||||||
|
onChange={ () =>
|
||||||
|
setShouldSavePayment( ! shouldSavePayment )
|
||||||
|
}
|
||||||
|
/>
|
||||||
</FormStep>
|
</FormStep>
|
||||||
</CheckoutForm>
|
</CheckoutForm>
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { Disabled } from '@wordpress/components';
|
|
||||||
import { withFeedbackPrompt } from '@woocommerce/block-hocs';
|
import { withFeedbackPrompt } from '@woocommerce/block-hocs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,12 +12,10 @@ import './editor.scss';
|
||||||
|
|
||||||
const CheckoutEditor = ( { attributes } ) => {
|
const CheckoutEditor = ( { attributes } ) => {
|
||||||
const { className } = attributes;
|
const { className } = attributes;
|
||||||
|
// @todo: wrap Block with Disabled once you finish building the form
|
||||||
return (
|
return (
|
||||||
<div className={ className }>
|
<div className={ className }>
|
||||||
<Disabled>
|
<Block attributes={ attributes } isEditor={ true } />
|
||||||
<Block attributes={ attributes } />
|
|
||||||
</Disabled>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,9 @@ import renderFrontend from '../../../utils/render-frontend.js';
|
||||||
|
|
||||||
const getProps = () => {
|
const getProps = () => {
|
||||||
return {
|
return {
|
||||||
attributes: {},
|
attributes: {
|
||||||
|
isEditor: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
// To be written
|
.wc-blocks-checkout__add-note,
|
||||||
|
.wc-blocks-checkout__keep-updated,
|
||||||
|
.wc-blocks-checkout__use-address-for-billing {
|
||||||
|
margin-top: $gap;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue