diff --git a/plugins/woocommerce-blocks/assets/css/abstracts/_colors.scss b/plugins/woocommerce-blocks/assets/css/abstracts/_colors.scss
index e8115fc6b0a..afcaf435024 100644
--- a/plugins/woocommerce-blocks/assets/css/abstracts/_colors.scss
+++ b/plugins/woocommerce-blocks/assets/css/abstracts/_colors.scss
@@ -47,5 +47,9 @@ $core-orange: #ca4a1f;
// @todo: replace those colors with the correct values once we settle on a design system palette.
$gray-10: #c3c4c7;
$gray-20: #a7aaad;
+$gray-50: #646970;
$gray-60: #50575e;
$gray-80: #2c3338;
+// @todo: align those colors with what we have
+$input-border-gray: #8d96a0;
+$input-text-active: #2b2d2f;
diff --git a/plugins/woocommerce-blocks/assets/js/base/components/checkout/no-shipping/index.js b/plugins/woocommerce-blocks/assets/js/base/components/checkout/no-shipping/index.js
new file mode 100644
index 00000000000..2c71c8c4f57
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/base/components/checkout/no-shipping/index.js
@@ -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 (
+ }
+ label={ __( 'Shipping options', 'woo-gutenberg-products-block' ) }
+ className="wc-blocks-checkout__no-shipping"
+ >
+
+ { __(
+ 'Your store does not have any Shipping Options configured. Once you have added your Shipping Options they will appear here.',
+ 'woo-gutenberg-products-block'
+ ) }
+
+
+
+ );
+};
+
+export default NoShipping;
diff --git a/plugins/woocommerce-blocks/assets/js/base/components/checkout/no-shipping/style.scss b/plugins/woocommerce-blocks/assets/js/base/components/checkout/no-shipping/style.scss
new file mode 100644
index 00000000000..92b11c945f9
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/base/components/checkout/no-shipping/style.scss
@@ -0,0 +1,5 @@
+.wc-blocks-checkout__no-shipping-description {
+ display: block;
+ margin: 0.25em 0 1em 0;
+ font-size: 13px;
+}
diff --git a/plugins/woocommerce-blocks/assets/js/base/components/input-row/index.js b/plugins/woocommerce-blocks/assets/js/base/components/input-row/index.js
new file mode 100644
index 00000000000..e6d853f9821
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/base/components/input-row/index.js
@@ -0,0 +1,19 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+
+/**
+ * Internal dependencies
+ */
+import './style.scss';
+
+const InputRow = ( { className, children } ) => {
+ return (
+
+ { children }
+
+ );
+};
+
+export default InputRow;
diff --git a/plugins/woocommerce-blocks/assets/js/base/components/input-row/style.scss b/plugins/woocommerce-blocks/assets/js/base/components/input-row/style.scss
new file mode 100644
index 00000000000..694033a22bb
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/base/components/input-row/style.scss
@@ -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;
+ }
+ }
+}
diff --git a/plugins/woocommerce-blocks/assets/js/base/components/radio-control/index.js b/plugins/woocommerce-blocks/assets/js/base/components/radio-control/index.js
new file mode 100644
index 00000000000..336bd68e1b3
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/base/components/radio-control/index.js
@@ -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 && (
+
+ { options.map(
+ ( {
+ value,
+ label,
+ description,
+ secondaryLabel,
+ secondaryDescription,
+ } ) => (
+
+ )
+ ) }
+
+ )
+ );
+};
+
+export default RadioControl;
diff --git a/plugins/woocommerce-blocks/assets/js/base/components/radio-control/style.scss b/plugins/woocommerce-blocks/assets/js/base/components/radio-control/style.scss
new file mode 100644
index 00000000000..093ba6e53c9
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/base/components/radio-control/style.scss
@@ -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;
+}
+
diff --git a/plugins/woocommerce-blocks/assets/js/base/components/text-input/index.js b/plugins/woocommerce-blocks/assets/js/base/components/text-input/index.js
new file mode 100644
index 00000000000..e5c4c5590d4
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/base/components/text-input/index.js
@@ -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 (
+
+
+
setIsActive( true ) }
+ onBlur={ () => setIsActive( false ) }
+ aria-label={ ariaLabel || label }
+ disabled={ disabled }
+ aria-describedby={ !! help ? id + '__help' : undefined }
+ />
+ { !! help && (
+
+ { help }
+
+ ) }
+
+ );
+};
+
+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;
diff --git a/plugins/woocommerce-blocks/assets/js/base/components/text-input/style.scss b/plugins/woocommerce-blocks/assets/js/base/components/text-input/style.scss
new file mode 100644
index 00000000000..b1826b9e4b1
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/base/components/text-input/style.scss
@@ -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;
+}
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/block.js b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/block.js
index 882cfc319aa..ebaf52c6add 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/block.js
+++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/block.js
@@ -1,12 +1,15 @@
/**
* External dependencies
*/
-import { Fragment } from '@wordpress/element';
-import { Placeholder } from '@wordpress/components';
+import { Fragment, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import FormStep from '@woocommerce/base-components/checkout/form-step';
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
*/
@@ -15,7 +18,11 @@ import './style.scss';
/**
* 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 (
{
) }
>
- A checkout step, coming soon near you
+
+ setContactFields( {
+ ...contactFields,
+ email: newValue,
+ } )
+ }
+ />
+
+ setContactFields( {
+ ...contactFields,
+ keepUpdated: ! contactFields.keepUpdated,
+ } )
+ }
+ />
+ { shippingMethods.length === 0 && (
+
+ { isEditor && }
+
+ ) }
+ { shippingMethods.length > 0 && (
+
+
+
+
+ setShippingFields( {
+ ...shippingFields,
+ firstName: newValue,
+ } )
+ }
+ />
+
+ setShippingFields( {
+ ...shippingFields,
+ lastName: newValue,
+ } )
+ }
+ />
+
+
+ setShippingFields( {
+ ...shippingFields,
+ streetAddress: newValue,
+ } )
+ }
+ />
+
+ setShippingFields( {
+ ...shippingFields,
+ apartment: newValue,
+ } )
+ }
+ />
+
+
+ setShippingFields( {
+ ...shippingFields,
+ country: newValue,
+ } )
+ }
+ />
+
+ setShippingFields( {
+ ...shippingFields,
+ country: newValue,
+ } )
+ }
+ />
+
+
+
+ setShippingFields( {
+ ...shippingFields,
+ county: newValue,
+ } )
+ }
+ />
+
+ setShippingFields( {
+ ...shippingFields,
+ postalCode: newValue,
+ } )
+ }
+ />
+
+
+ setShippingFields( {
+ ...shippingFields,
+ phone: newValue,
+ } )
+ }
+ />
+
+ setShippingFields( {
+ ...shippingFields,
+ useSameForBilling: ! shippingFields.useSameForBilling,
+ } )
+ }
+ />
+
+
+
+ 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',
+ },
+ ] }
+ />
+
+ setShippingMethod( {
+ ...shippingMethod,
+ orderNote: ! shippingMethod.orderNote,
+ } )
+ }
+ />
+
+
+ ) }
- A checkout step, coming soon near you
-
-
- A checkout step, coming soon near you
-
- {
) }
stepNumber={ 4 }
>
- A checkout step, coming soon near you
+ Payment methods, coming soon
+
+ setShouldSavePayment( ! shouldSavePayment )
+ }
+ />
);
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/edit.js b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/edit.js
index 740da959a4a..cd2d7704828 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/edit.js
+++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/edit.js
@@ -2,7 +2,6 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
-import { Disabled } from '@wordpress/components';
import { withFeedbackPrompt } from '@woocommerce/block-hocs';
/**
@@ -13,12 +12,10 @@ import './editor.scss';
const CheckoutEditor = ( { attributes } ) => {
const { className } = attributes;
-
+ // @todo: wrap Block with Disabled once you finish building the form
return (
-
-
-
+
);
};
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/frontend.js b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/frontend.js
index bb508e5557c..101ba2403d2 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/frontend.js
+++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/frontend.js
@@ -11,7 +11,9 @@ import renderFrontend from '../../../utils/render-frontend.js';
const getProps = () => {
return {
- attributes: {},
+ attributes: {
+ isEditor: false,
+ },
};
};
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/style.scss b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/style.scss
index da3ad0454b1..91eb945f9bb 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/style.scss
+++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/style.scss
@@ -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;
+}