diff --git a/client/landing/gutenboarding/components/card/README.md b/client/landing/gutenboarding/components/card/README.md new file mode 100644 index 00000000000000..915f90f70e057d --- /dev/null +++ b/client/landing/gutenboarding/components/card/README.md @@ -0,0 +1,104 @@ +# THIS IS TEMPORARY + +This is an unreleased component copied from +[`@wordpress/components`](https://github.com/WordPress/gutenberg/tree/master/packages/components/src/card). + +_It should not be heavily modified, it will be replaced with the published component soon._ + +# Card + +Card provides a flexible and extensible content container. + +## Usage + +```jsx +import { Card, CardBody } from '@wordpress/components'; + +const Example = () => ( + + ... + +); +``` + +## Props + +| Name | Type | Default | Description | +| -------------- | --------- | -------- | ------------------------------------------------- | +| `isBorderless` | `boolean` | `false` | Determines the border style of the card. | +| `isElevated` | `boolean` | `false` | Determines the elevation style of the card. | +| `size` | `string` | `medium` | Determines the amount of padding within the card. | + +## Sub-Components + +This component provides a collection of sub-component that can be used to compose various interfaces. + +- [``](./docs/body.md) +- [``](./docs/divider.md) +- [``](./docs/footer.md) +- [``](./docs/header.md) +- [``](./docs/media.md) + +### Sub-Components Example + +```jsx +import { + Card, + CardBody, + CardDivider, + CardFooter, + CardHeader, + CardMedia +} from '@wordpress/components'; + +const Example = () => ( + + + ... + + + ... + + + + ... + + + + + + ... + + +); +``` + +### Context + +``'s sub-components are connected to `` using [Context](https://reactjs.org/docs/context.html). Certain props like `size` and `variant` are passed through to the sub-components. + +In the following example, the `` will render with a size of `small`: + +```jsx +import { Card, CardBody } from '@wordpress/components'; + +const Example = () => ( + + ... + +); +``` + +These sub-components are designed to be flexible. The Context props can be overridden by the sub-component(s) as required. In the following example, the last `` will render it's specified size: + +```jsx +import { Card, CardBody } from '@wordpress/components'; + +const Example = () => ( + + ... + ... + ... + +); +``` diff --git a/client/landing/gutenboarding/components/card/body.js b/client/landing/gutenboarding/components/card/body.js new file mode 100644 index 00000000000000..3949340c14349c --- /dev/null +++ b/client/landing/gutenboarding/components/card/body.js @@ -0,0 +1,33 @@ +/** + * External dependencies + */ +import React from 'react'; +import classnames from 'classnames'; + +/** + * Internal dependencies + */ +import { BodyUI } from './styles/card-styles'; +import { useCardContext } from './context'; + +export const defaultProps = { + isShady: false, + size: 'medium', +}; + +export function CardBody( props ) { + const { className, isShady, ...additionalProps } = props; + const mergedProps = { ...defaultProps, ...useCardContext(), ...props }; + const { size } = mergedProps; + + const classes = classnames( + 'components-card__body', + isShady && 'is-shady', + size && `is-size-${ size }`, + className + ); + + return ; +} + +export default CardBody; diff --git a/client/landing/gutenboarding/components/card/context.js b/client/landing/gutenboarding/components/card/context.js new file mode 100644 index 00000000000000..9cbe600ff435b0 --- /dev/null +++ b/client/landing/gutenboarding/components/card/context.js @@ -0,0 +1,7 @@ +/** + * External dependencies + */ +import { createContext, useContext } from '@wordpress/element'; + +export const CardContext = createContext( {} ); +export const useCardContext = () => useContext( CardContext ); diff --git a/client/landing/gutenboarding/components/card/divider.js b/client/landing/gutenboarding/components/card/divider.js new file mode 100644 index 00000000000000..d5ee214c2dffdb --- /dev/null +++ b/client/landing/gutenboarding/components/card/divider.js @@ -0,0 +1,22 @@ +/** + * External dependencies + */ +import React from 'react'; +import classnames from 'classnames'; + +/** + * Internal dependencies + */ +import { DividerUI } from './styles/card-styles'; + +export function CardDivider( props ) { + const { className, ...additionalProps } = props; + + const classes = classnames( 'components-card__divider', className ); + + return ( + + ); +} + +export default CardDivider; diff --git a/client/landing/gutenboarding/components/card/footer.js b/client/landing/gutenboarding/components/card/footer.js new file mode 100644 index 00000000000000..e0dcc04eb27f11 --- /dev/null +++ b/client/landing/gutenboarding/components/card/footer.js @@ -0,0 +1,35 @@ +/** + * External dependencies + */ +import React from 'react'; +import classnames from 'classnames'; + +/** + * Internal dependencies + */ +import { FooterUI } from './styles/card-styles'; +import { useCardContext } from './context'; + +export const defaultProps = { + isBorderless: false, + isShady: false, + size: 'medium', +}; + +export function CardFooter( props ) { + const { className, isShady, ...additionalProps } = props; + const mergedProps = { ...defaultProps, ...useCardContext(), ...props }; + const { isBorderless, size } = mergedProps; + + const classes = classnames( + 'components-card__footer', + isBorderless && 'is-borderless', + isShady && 'is-shady', + size && `is-size-${ size }`, + className + ); + + return ; +} + +export default CardFooter; diff --git a/client/landing/gutenboarding/components/card/header.js b/client/landing/gutenboarding/components/card/header.js new file mode 100644 index 00000000000000..fd746a2ca29a45 --- /dev/null +++ b/client/landing/gutenboarding/components/card/header.js @@ -0,0 +1,35 @@ +/** + * External dependencies + */ +import React from 'react'; +import classnames from 'classnames'; + +/** + * Internal dependencies + */ +import { HeaderUI } from './styles/card-styles'; +import { useCardContext } from './context'; + +export const defaultProps = { + isBorderless: false, + isShady: false, + size: 'medium', +}; + +export function CardHeader( props ) { + const { className, isShady, ...additionalProps } = props; + const mergedProps = { ...defaultProps, ...useCardContext(), ...props }; + const { isBorderless, size } = mergedProps; + + const classes = classnames( + 'components-card__header', + isBorderless && 'is-borderless', + isShady && 'is-shady', + size && `is-size-${ size }`, + className + ); + + return ; +} + +export default CardHeader; diff --git a/client/landing/gutenboarding/components/card/index.js b/client/landing/gutenboarding/components/card/index.js new file mode 100644 index 00000000000000..ee4ed0607b7fe4 --- /dev/null +++ b/client/landing/gutenboarding/components/card/index.js @@ -0,0 +1,46 @@ +/** + * External dependencies + */ +import React from 'react'; +import classnames from 'classnames'; + +/** + * Internal dependencies + */ +import { CardContext } from './context'; +import { CardUI } from './styles/card-styles'; + +export const defaultProps = { + isBorderless: false, + isElevated: false, + size: 'medium', +}; + +export function Card( props ) { + const { className, isBorderless, isElevated, size, ...additionalProps } = props; + const { Provider } = CardContext; + + const contextProps = { + isBorderless, + isElevated, + size, + }; + + const classes = classnames( + 'components-card', + isBorderless && 'is-borderless', + isElevated && 'is-elevated', + size && `is-size-${ size }`, + className + ); + + return ( + + + + ); +} + +Card.defaultProps = defaultProps; + +export default Card; diff --git a/client/landing/gutenboarding/components/card/media.js b/client/landing/gutenboarding/components/card/media.js new file mode 100644 index 00000000000000..c473b3f051b3b2 --- /dev/null +++ b/client/landing/gutenboarding/components/card/media.js @@ -0,0 +1,20 @@ +/** + * External dependencies + */ +import React from 'react'; +import classnames from 'classnames'; + +/** + * Internal dependencies + */ +import { MediaUI } from './styles/card-styles'; + +export function CardMedia( props ) { + const { className, ...additionalProps } = props; + + const classes = classnames( 'components-card__media', className ); + + return ; +} + +export default CardMedia; diff --git a/client/landing/gutenboarding/components/card/styles/card-styles.js b/client/landing/gutenboarding/components/card/styles/card-styles.js new file mode 100644 index 00000000000000..db20cd46a2a801 --- /dev/null +++ b/client/landing/gutenboarding/components/card/styles/card-styles.js @@ -0,0 +1,167 @@ +/** + * External dependencies + */ +import styled from '@emotion/styled'; + +/** + * Internal dependencies + */ +import { HorizontalRule } from '@wordpress/components'; + +export const styleProps = { + borderColor: color( 'lightGray.500' ), + borderRadius: '3px', + backgroundShady: color( 'lightGray.200' ), +}; + +const { borderColor, borderRadius, backgroundShady } = styleProps; + +export const CardUI = styled.div` + background: ${color( 'white' )}; + box-sizing: border-box; + border-radius: ${borderRadius}; + border: 1px solid ${borderColor}; + + ${handleBorderless}; + + &.is-elevated { + box-shadow: 0px 1px 3px 0px rgba( 0, 0, 0, 0.2 ), 0px 1px 1px 0px rgba( 0, 0, 0, 0.14 ), + 0px 2px 1px -1px rgba( 0, 0, 0, 0.12 ); + } +`; + +export const HeaderUI = styled.div` + border-bottom: 1px solid ${borderColor}; + border-top-left-radius: ${borderRadius}; + border-top-right-radius: ${borderRadius}; + box-sizing: border-box; + + &:last-child { + border-bottom: none; + } + + ${headerFooterSizes}; + ${handleBorderless}; + ${handleShady}; +`; + +export const MediaUI = styled.div` + box-sizing: border-box; + overflow: hidden; + + & > img, + & > iframe { + display: block; + height: auto; + max-width: 100%; + width: 100%; + } + + &:first-of-type { + border-top-left-radius: ${borderRadius}; + border-top-right-radius: ${borderRadius}; + } + + &:last-of-type { + border-bottom-left-radius: ${borderRadius}; + border-bottom-right-radius: ${borderRadius}; + } +`; + +export const BodyUI = styled.div` + box-sizing: border-box; + + ${bodySize}; + ${handleShady}; +`; + +export const FooterUI = styled.div` + border-top: 1px solid ${borderColor}; + border-bottom-left-radius: ${borderRadius}; + border-bottom-right-radius: ${borderRadius}; + box-sizing: border-box; + + &:first-of-type { + border-top: none; + } + + ${headerFooterSizes}; + ${handleBorderless}; + ${handleShady}; +`; + +export const DividerUI = styled( HorizontalRule )` + all: unset; + border-top: 1px solid ${borderColor}; + box-sizing: border-box; + display: block; + height: 0; + width: 100%; +`; + +export function bodySize() { + return ` + &.is-size { + &-large { + padding: 28px; + } + &-medium { + padding: 20px; + } + &-small { + padding: 12px; + } + &-extraSmall { + padding: 8px; + } + } + `; +} + +export function headerFooterSizes() { + return ` + &.is-size { + &-large { + padding: 20px 28px; + } + &-medium { + padding: 12px 20px; + } + &-small { + padding: 8px 12px; + } + &-extraSmall { + padding: 4px 8px; + } + } + `; +} + +export function handleBorderless() { + return ` + &.is-borderless { + border: none; + } + `; +} + +export function handleShady() { + return ` + &.is-shady { + background: ${ backgroundShady }; + } + `; +} + +// hack around https://github.com/WordPress/gutenberg/blob/master/packages/components/src/utils/colors.js +function color( value ) { + switch ( value ) { + case 'lightGray.500': + return '#e2e4e7'; + case 'lightGray.200': + return '#f3f4f5'; + case 'white': + return '#fff'; + } + return '#000'; +} diff --git a/client/landing/gutenboarding/gutenboard.tsx b/client/landing/gutenboarding/gutenboard.tsx index 9a4bc37c7691b2..a537bb35cb7937 100644 --- a/client/landing/gutenboarding/gutenboard.tsx +++ b/client/landing/gutenboarding/gutenboard.tsx @@ -105,7 +105,7 @@ export function Gutenboard() { value={ [ onboardingBlock.current ] } settings={ { templateLock: 'all' } } > -
+
{ const siteVertical = useSelect( @@ -23,20 +26,23 @@ export default () => { const homepageTemplates = templates.filter( template => template.category === 'home' ); - const [ previewedTemplate, setPreviewedTemplate ] = useState< string | null >( null ); + const [ selectedDesign, setSelectedDesign ] = useState< string | undefined >(); return ( -
- +
+ { homepageTemplates.map( template => ( + setSelectedDesign( template.slug ) } + > + + { + + + ) ) }
); }; diff --git a/client/landing/gutenboarding/onboarding-block/design-selector/style.scss b/client/landing/gutenboarding/onboarding-block/design-selector/style.scss new file mode 100644 index 00000000000000..741f4f4706fc65 --- /dev/null +++ b/client/landing/gutenboarding/onboarding-block/design-selector/style.scss @@ -0,0 +1,18 @@ +.design-selector { + display: grid; + grid-gap: 4.5em; + + @include breakpoint( '>660px' ) { + // stylelint-disable unit-whitelist + grid-template-columns: repeat( 2, 1fr ); + // stylelint-enable unit-whitelist + } +} + +.design-selector__design-option { + transition: transform 100ms ease-in-out; + + &.is-selected { + transform: scale( 1.1 ); + } +} diff --git a/client/landing/gutenboarding/style.scss b/client/landing/gutenboarding/style.scss index 3b59734079a330..20d2f138bc93c7 100644 --- a/client/landing/gutenboarding/style.scss +++ b/client/landing/gutenboarding/style.scss @@ -13,6 +13,10 @@ $admin-sidebar-width-collapsed: 0; @import '~@wordpress/block-editor/src/style.scss'; @import '~@wordpress/format-library/src/style.scss'; +.gutenboard__edit-post-layout-content { + position: static; +} + .wp-block { max-width: 1100px; // Overrides default $content-width }