Skip to content

Commit

Permalink
Merge 0e898da into c05363f
Browse files Browse the repository at this point in the history
  • Loading branch information
Klynger committed Oct 23, 2019
2 parents c05363f + 0e898da commit 8969f9f
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 55 deletions.
6 changes: 3 additions & 3 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- Prop `buyButtonBehavior` to `ProductSummaryBuyButton`.
- `ProductSummarySKUSelector` component.

## [2.38.1] - 2019-10-22
### Fixed
Expand All @@ -31,9 +34,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- `width` and `height` props on `product-summary-image`.

### Added
- Prop `buyButtonBehavior` to `ProductSummaryBuyButton`.

### Fixed
- `BuyButton`adding to cart when the product has more than one SKU.

Expand Down
2 changes: 0 additions & 2 deletions README.md
Expand Up @@ -5,8 +5,6 @@
The VTEX Product Summary summarises the product informations such as name, price and picture.
This is a VTEX app that is used by store theme.

:loudspeaker: **Disclaimer:** Don't fork this project; use, contribute, or open issue with your feature request

## Release schedule

| Release | Status | Initial Release | Maintenance LTS Start | End-of-life | Store Compatibility |
Expand Down
66 changes: 66 additions & 0 deletions docs/ProductSummarySKUSelector.md
@@ -0,0 +1,66 @@
# Product Summary Name

## Description

`ProductSummarySKUSelector` is a VTEX Component that renders the product's name.
This Component can be imported and used by any VTEX App.

:loudspeaker: **Disclaimer:** Don't fork this project; use, contribute, or open issue with your feature request.

## Table of Contents
- [Usage](#usage)
- [Blocks API](#blocks-api)
- [Configuration](#configuration)
- [Styles API](#styles-api)

## Usage

You should follow the usage instruction in the main [README](https://github.com/vtex-apps/product-summary/blob/master/README.md#usage).

Then, add `product-summary-sku-selector` block into your app theme, as we do in our [Product Summary app](https://github.com/vtex-apps/product-summary/blob/master/store/blocks.json).

### Blocks API

This component has an interface that describes which rules must be implemented by a block when you want to use the `ProductSummarySKUSelector`.

```json
"product-summary-sku-selector": {
"component": "ProductSummarySKUSelector"
}
```

### Configuration

You can't configure anything of this component through Site Etor at the moment, only using the block of it.

You can find all options available in [Store Components SKU Selector app](https://github.com/vtex-apps/store-components/blob/master/docs/SKUSelector.md).

### Styles API

This app provides some CSS classes as an API for style customization.

To use this CSS API, you must add the `styles` builder and create an app styling CSS file.

1. Add the `styles` builder to your `manifest.json`:

```json
"builders": {
"styles": "1.x"
}
```

2. Create a file called `vtex.product-summary.css` inside the `styles/css` folder. Add your custom styles:

```css
.SKUSelectorContainer {
margin-top: 10px;
}
```

#### CSS namespaces

Below, we describe the namespaces that are defined in the menu.

| Token name | Description | Component Source |
| ------------ | ---------------------------------------------------- | ------------------------------------ |
| `SKUSelectorContainer` | The main container of SKUSelector | [index](/react/components/ProductSummarySKUSelector/index.js) |
1 change: 1 addition & 0 deletions manifest.json
Expand Up @@ -21,6 +21,7 @@
"vtex.store-resources": "0.x",
"vtex.product-review-interfaces": "1.x",
"vtex.product-summary-context": "0.x",
"vtex.product-context": "0.x",
"vtex.product-identifier": "0.x",
"vtex.styleguide": "9.x",
"vtex.pixel-manager": "1.x",
Expand Down
3 changes: 3 additions & 0 deletions react/ProductSummarySKUSelector.js
@@ -0,0 +1,3 @@
import ProductSummarySKUSelector from './components/ProductSummarySKUSelector'

export default ProductSummarySKUSelector
7 changes: 7 additions & 0 deletions react/__mocks__/vtex.product-context.js
@@ -0,0 +1,7 @@
import React, { createContext } from 'react'

const ProductContext = createContext({})

export const ProductContextProvider = ({ product, query, ...rest }) => {
return <ProductContext.Provider value={{ product, query }} {...rest} />
}
55 changes: 36 additions & 19 deletions react/components/ProductSummary.js
@@ -1,21 +1,23 @@
import React, { useCallback, useMemo, useEffect } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { pathOr, path } from 'ramda'
import { Link } from 'vtex.render-runtime'
import ProductSummaryContext from './ProductSummaryContext'
import {
ProductSummaryProvider,
useProductSummaryDispatch,
useProductSummary,
} from 'vtex.product-summary-context/ProductSummaryContext'
import { ProductContextProvider } from 'vtex.product-context'
import productSummary from '../productSummary.css'
import { productShape } from '../utils/propTypes'
import { mapCatalogProductToProductSummary } from '../utils/normalize'

const PRODUCT_SUMMARY_MAX_WIDTH = 300

const ProductSummaryCustom = ({ product, actionOnClick, children }) => {
const { isLoading, isHovering } = useProductSummary()
const { isLoading, isHovering, selectedItem, query } = useProductSummary()
const dispatch = useProductSummaryDispatch()

useEffect(() => {
Expand Down Expand Up @@ -68,29 +70,44 @@ const ProductSummaryCustom = ({ product, actionOnClick, children }) => {
)

const summaryClasses = classNames(
`${productSummary.element} pointer pt3 pb4 flex flex-column h-100`
productSummary.element,
'pointer pt3 pb4 flex flex-column h-100'
)

const linkClasses = classNames(
productSummary.clearLink,
'h-100 flex flex-column'
)

const skuId = pathOr(
path(['sku', 'itemId'], product),
['itemId'],
selectedItem
)

return (
<ProductSummaryContext.Provider value={oldContextProps}>
<section
className={containerClasses}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
style={{ maxWidth: PRODUCT_SUMMARY_MAX_WIDTH }}
>
<Link
className={`${productSummary.clearLink} h-100 flex flex-column`}
page="store.product"
params={{
slug: product && product.linkText,
id: product && product.productId,
}}
onClick={actionOnClick}
<ProductContextProvider product={product} query={{ skuId }}>
<section
className={containerClasses}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
style={{ maxWidth: PRODUCT_SUMMARY_MAX_WIDTH }}
>
<article className={summaryClasses}>{children}</article>
</Link>
</section>
<Link
className={linkClasses}
page="store.product"
params={{
slug: product && product.linkText,
id: product && product.productId,
}}
query={query}
onClick={actionOnClick}
>
<article className={summaryClasses}>{children}</article>
</Link>
</section>
</ProductContextProvider>
</ProductSummaryContext.Provider>
)
}
Expand Down
49 changes: 18 additions & 31 deletions react/components/ProductSummaryBuyButton/ProductSummaryBuyButton.js
Expand Up @@ -3,10 +3,8 @@ import PropTypes from 'prop-types'
import BuyButton from 'vtex.store-components/BuyButton'
import { withRuntimeContext } from 'vtex.render-runtime'
import { equals, path } from 'ramda'
import classNames from 'classnames'
import classnames from 'classnames'
import { IOMessage } from 'vtex.native-types'
import { Button } from 'vtex.styleguide'
import { Link } from 'vtex.render-runtime'

import { useProductSummary } from 'vtex.product-summary-context/ProductSummaryContext'
import displayButtonTypes, {
Expand Down Expand Up @@ -48,14 +46,18 @@ const ProductSummaryBuyButton = ({
mobile
)

const buyButtonClasses = classNames(
`${productSummary.buyButton} center mw-100`,
const buyButtonClasses = classnames(
productSummary.buyButton,
'center mw-100',
{
[productSummary.isHidden]: !hoverBuyButton,
}
)

const containerClass = `${productSummary.buyButtonContainer} pv3 w-100 db`
const containerClass = classnames(
productSummary.buyButtonContainer,
'pv3 w-100 db'
)

const selectedSeller = path(['seller'], selectedItem)
const isAvailable =
Expand All @@ -73,37 +75,22 @@ const ProductSummaryBuyButton = ({
// if the item is not available the behavior is just show the disabled BuyButton,
// but you still can go to the product page clicking in the summary
const shouldBeALink =
(items.length !== 1 || buyButtonBehavior !== BUY_BUTTON_BEHAVIOR_OPTIONS) &&
(items.length !== 1 || buyButtonBehavior !== DEFAULT_BUTTON_BEHAVIOR) &&
isAvailable

return (
showBuyButton && (
<div className={containerClass}>
<div className={buyButtonClasses}>
{shouldBeALink ? (
<Link
className="dib"
disabled
page="store.product"
params={{
slug: product && product.linkText,
id: product && product.productId,
}}
>
<Button>
<IOMessage id={buyButtonText} />
</Button>
</Link>
) : (
<BuyButton
customToastURL={customToastURL}
available={isAvailable}
skuItems={skuItems}
isOneClickBuy={isOneClickBuy}
>
<IOMessage id={buyButtonText} />
</BuyButton>
)}
<BuyButton
skuItems={skuItems}
available={isAvailable}
isOneClickBuy={isOneClickBuy}
customToastURL={customToastURL}
shouldAddToCart={!shouldBeALink}
>
<IOMessage id={buyButtonText} />
</BuyButton>
</div>
</div>
)
Expand Down
56 changes: 56 additions & 0 deletions react/components/ProductSummarySKUSelector/index.js
@@ -0,0 +1,56 @@
import React from 'react'
import { head } from 'ramda'
import { SKUSelector } from 'vtex.store-components'
import productSummary from '../../productSummary.css'
import {
useProductSummaryDispatch,
useProductSummary,
} from 'vtex.product-summary-context/ProductSummaryContext'

function ProductSummarySKUSelector(props) {
const stopBubblingUp = e => {
e.preventDefault()
e.stopPropagation()
}
const dispatch = useProductSummaryDispatch()
const { product } = useProductSummary()

const handleSKUSelected = skuId => {
const selectedItem =
product.items && product.items.find(item => item.itemId === skuId)

const sku = {
...selectedItem,
image: head(selectedItem.images),
seller: head(selectedItem.sellers),
}

const newProduct = {
...product,
selectedItem,
sku,
}

dispatch({
type: 'SET_PRODUCT',
args: { product: newProduct },
})

dispatch({
type: 'SET_PRODUCT_QUERY',
args: { query: `skuId=${skuId}` },
})
}

return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<div
className={productSummary.SKUSelectorContainer}
onClick={stopBubblingUp}
>
<SKUSelector onSKUSelected={handleSKUSelected} {...props} />
</div>
)
}

export default ProductSummarySKUSelector
2 changes: 2 additions & 0 deletions react/productSummary.css
Expand Up @@ -52,6 +52,8 @@
.priceContainer {
}

.SKUSelectorContainer {}

.attachmentListContainer {
}

Expand Down
4 changes: 4 additions & 0 deletions store/interfaces.json
Expand Up @@ -16,6 +16,7 @@
"product-summary-name",
"product-summary-price",
"product-identifier",
"product-summary-sku-selector",
"product-summary-space",
"product-summary-add-to-list-button",
"product-rating-inline",
Expand Down Expand Up @@ -121,6 +122,9 @@
}
}
},
"product-summary-sku-selector": {
"component": "ProductSummarySKUSelector"
},
"product-summary-specification-badges": {
"component": "ProductSummarySpecificationBadges"
},
Expand Down

0 comments on commit 8969f9f

Please sign in to comment.