Skip to content
This repository has been archived by the owner on Jul 14, 2022. It is now read-only.

Feature/new product description #605

Merged
merged 11 commits into from
Feb 12, 2020
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from "react";

import { RichTextContent } from "@components/atoms";

import * as S from "./styles";
import { IProps } from "./types";

enum TABS {
DESCRIPTION,
ATTRIBUTES,
}

export const ProductDescription: React.FC<IProps> = ({
description = "",
descriptionJson = "",
attributes,
}: IProps) => {
const [activeTab, setActiveTab] = React.useState<TABS>(TABS.DESCRIPTION);

return (
<S.Wrapper>
<S.Tabs>
<S.TabTitle
active={activeTab === TABS.DESCRIPTION}
onMouseEnter={evt => {
evt.stopPropagation();
setActiveTab(TABS.DESCRIPTION);
}}
onClick={evt => {
evt.stopPropagation();
setActiveTab(TABS.DESCRIPTION);
}}
>
DESCRIPTION
</S.TabTitle>
<S.TabTitle
active={activeTab === TABS.ATTRIBUTES}
onMouseEnter={evt => {
evt.stopPropagation();
setActiveTab(TABS.ATTRIBUTES);
}}
onClick={evt => {
evt.stopPropagation();
setActiveTab(TABS.ATTRIBUTES);
}}
>
ATTRIBUTES
</S.TabTitle>
</S.Tabs>
{activeTab === TABS.DESCRIPTION &&
(descriptionJson ? (
<RichTextContent descriptionJson={descriptionJson} />
) : (
<p>{description}</p>
))}
{activeTab === TABS.ATTRIBUTES && (
<S.AttributeList>
{attributes &&
attributes.map(attribute => (
<li>
<S.AttributeName>{attribute.attribute.name}: </S.AttributeName>{" "}
{attribute.values.map(value => value.name).join(", ")}
</li>
))}
</S.AttributeList>
)}
</S.Wrapper>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots @components/molecules/ProductDescription default 1`] = `
.c0 {
position: relative;
margin: 20px;
}

.c4 {
position: absolute;
width: 100%;
height: 100%;
border: 3px solid rgba(0,0,0,0.2);
top: 0;
left: 0;
pointer-events: none;
box-sizing: border-box;
}

.c1 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: none;
-ms-flex-wrap: none;
flex-wrap: none;
width: 100%;
border-bottom: 1px solid rgba(50,50,50,0.1);
margin-bottom: 70px;
overflow: hidden;
}

.c2 {
min-width: 230px;
font-size: 1.5rem;
font-weight: 600;
-webkit-letter-spacing: 0.02em;
-moz-letter-spacing: 0.02em;
-ms-letter-spacing: 0.02em;
letter-spacing: 0.02em;
color: #06847B;
border-bottom-width: 4px;
border-bottom-style: solid;
border-bottom-color: #06847B;
padding-bottom: 25px;
margin-right: 60px;
}

.c3 {
min-width: 230px;
font-size: 1.5rem;
font-weight: 600;
-webkit-letter-spacing: 0.02em;
-moz-letter-spacing: 0.02em;
-ms-letter-spacing: 0.02em;
letter-spacing: 0.02em;
border-bottom-width: 4px;
border-bottom-style: solid;
border-bottom-color: transparent;
padding-bottom: 25px;
margin-right: 60px;
}

@media (max-width:540px) {
.c2 {
font-size: 1.125rem;
min-width: 150px;
margin-right: 20px;
}
}

@media (max-width:540px) {
.c3 {
font-size: 1.125rem;
min-width: 150px;
margin-right: 20px;
}
}

<div
className="c0"
>
<div
className=""
>
<div
className="c1"
>
<div
className="c2"
onClick={[Function]}
onMouseEnter={[Function]}
>
DESCRIPTION
</div>
<div
className="c3"
onClick={[Function]}
onMouseEnter={[Function]}
>
ATTRIBUTES
</div>
</div>
<p>
This is some cool product description. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<div
className="c4"
/>
</div>
`;
56 changes: 56 additions & 0 deletions src/@next/components/molecules/ProductDescription/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
export const attributes = [
{
attribute: { name: "Author" },
values: [
{
name: "John Doe",
},
],
},
{
attribute: { name: "Country of Manufacture" },
values: [
{
name: "Poland",
},
{
name: "China",
},
],
},
{
attribute: { name: "Size" },
values: [
{
name: "40x40cm",
},
],
},
{
attribute: { name: "Material" },
values: [
{
name: "Polystyrene",
},
],
},
{
attribute: { name: "Manufacture time" },
values: [
{
name: "2 to 4 weeks",
},
],
},
{
attribute: { name: "SKU" },
values: [
{
name: "1244-SGG",
},
],
},
];

export const description =
"This is some cool product description. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
1 change: 1 addition & 0 deletions src/@next/components/molecules/ProductDescription/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ProductDescription";
10 changes: 10 additions & 0 deletions src/@next/components/molecules/ProductDescription/stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { storiesOf } from "@storybook/react";
import React from "react";

import { ProductDescription } from ".";
import { attributes, description } from "./fixtures";

storiesOf("@components/molecules/ProductDescription", module).add(
"default",
() => <ProductDescription attributes={attributes} description={description} />
);
61 changes: 61 additions & 0 deletions src/@next/components/molecules/ProductDescription/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { media, styled } from "@styles";

export const Wrapper = styled.div``;

export const AttributeList = styled.ul`
columns: 2;
column-width: 50%;

${media.mediumScreen`
column-width: 100%;
columns: 1;
`};
width: 100%;
padding: 0;
margin: 0;

li {
margin-bottom: 30px;
font-size: ${props => props.theme.typography.h4FontSize};
}

li::before {
content: "•";
margin-right: 20px;
color: ${props => props.theme.colors.listBullet};
}
`;

export const Tabs = styled.div`
display: flex;
flex-wrap: none;
width: 100%;
border-bottom: 1px solid ${props => props.theme.colors.tabsBorder};
margin-bottom: 70px;
overflow: hidden;
`;

export const TabTitle = styled.div<{ active?: boolean }>`
cursor: pointer;
min-width: 230px;
font-size: ${props => props.theme.typography.h3FontSize};
font-weight: ${props => props.theme.typography.boldFontWeight};
letter-spacing: 0.02em;
color: ${props => props.active && props.theme.colors.tabTitle};
border-bottom-width: 4px;
border-bottom-style: solid;
border-bottom-color: ${props =>
props.active ? props.theme.colors.tabTitle : "transparent"};
padding-bottom: 25px;
margin-right: 60px;

${media.smallScreen`
font-size: ${(props: any) => props.theme.typography.h4FontSize};
min-width: 150px;
margin-right: 20px;
`};
`;

export const AttributeName = styled.span`
color: ${props => props.theme.colors.listAttributeName};
`;
40 changes: 40 additions & 0 deletions src/@next/components/molecules/ProductDescription/test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { mount, shallow } from "enzyme";
import "jest-styled-components";
import React from "react";

import { ProductDescription } from ".";
import { attributes, description } from "./fixtures";
import * as S from "./styles";

describe("<ProductDescription />", () => {
it("exists", () => {
const wrapper = shallow(
<ProductDescription attributes={attributes} description={description} />
);

expect(wrapper.exists()).toEqual(true);
});

it("should contain and show by default product description", () => {
const wrapper = shallow(
<ProductDescription attributes={attributes} description={description} />
);

expect(wrapper.text()).toContain(description);
});

it("should show product attributes when clicking on attributes tab", () => {
const wrapper = mount(
<ProductDescription attributes={attributes} description={description} />
);

wrapper
.find(S.TabTitle)
.at(1)
.simulate("click");

attributes.forEach(attribute =>
expect(wrapper.text()).toContain(attribute.attribute.name)
);
});
});
8 changes: 8 additions & 0 deletions src/@next/components/molecules/ProductDescription/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface IProps {
description?: string;
descriptionJson?: string;
attributes?: Array<{
attribute: { name: string };
values: Array<{ name: string }>;
}>;
}
1 change: 1 addition & 0 deletions src/@next/components/molecules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from "./FilterAttribute";
export * from "./ResetPasswordForm";
export * from "./AddToWishlistButton";
export * from "./ProductTile";
export * from "./ProductDescription";
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ exports[`Storyshots @components/organisms/ProductVariantPicker default 1`] = `

.c2 {
display: grid;
grid-gap: 20px;
grid-template-columns: auto auto;
grid-template-columns: 1fr;
}

.c1 {
Expand Down Expand Up @@ -63,8 +62,7 @@ exports[`Storyshots @components/organisms/ProductVariantPicker with sidebar 1`]

.c2 {
display: grid;
grid-gap: 20px;
grid-template-columns: auto auto;
grid-template-columns: 1fr;
}

.c1 {
Expand Down
Loading