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

Commit

Permalink
Merge pull request #605 from mirumee/feature/new_product_description
Browse files Browse the repository at this point in the history
Feature/new product description
mateuszkula authored Feb 12, 2020
2 parents b7287b5 + 0c184fe commit e4a3df1
Showing 17 changed files with 399 additions and 39 deletions.
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,115 @@
// 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 {
cursor: pointer;
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 {
cursor: pointer;
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
@@ -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
@@ -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 {
@@ -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 {
Loading

0 comments on commit e4a3df1

Please sign in to comment.