Skip to content

Commit

Permalink
Merge branch 'styled-components' of https://github.com/cmpsr/composer
Browse files Browse the repository at this point in the history
…into styled-snackbar

* 'styled-components' of https://github.com/cmpsr/composer:
  feat: create box container (#172)
  feat: create conversation list (#171)
  Styled List Items (#165)
  • Loading branch information
guilean committed Oct 27, 2020
2 parents 211e1b5 + 50b5288 commit e3cf3c3
Show file tree
Hide file tree
Showing 28 changed files with 608 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { Box } from '.';
import { text, select } from '@storybook/addon-knobs';
import styled from 'styled-components';

export default {
title: 'Containers/Box',
component: Box,
};

const StyledBox = styled(Box)`
background: #cdd7ff;
border: 2px solid black;
padding: 10px;
`;

export const Sizes = () => (
<>
<h1>Box sizes</h1>
{Object.keys(Box.Sizes).map((size: any) => (
<>
<StyledBox size={Box.Sizes[size]}>{size}</StyledBox>
<br />
</>
))}
</>
);

export const Playground = () => (
<>
<h1>Playground</h1>
<StyledBox size={select('Box size', Box.Sizes, Box.Sizes.Content)}>
{text('Children', 'Children')}
</StyledBox>
</>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import styled from 'styled-components';
import { getTheme } from 'utils/getTheme';

interface Props {
theme: any;
}

export const StyledBox = styled.div<Props>`
&.screen {
width: 100vw;
height: 100vh;
}
&.full {
width: 100%;
height: 100%;
}
&.content {
width: 100%;
height: 100%;
margin-right: auto;
margin-left: auto;
max-width: ${(props) => getTheme(props).breakpoints.xl};
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { Box } from '.';

describe('Box', () => {
const testId = 'box';
it('should render children', () => {
render(<Box>foo</Box>);
screen.getByText('foo');
});
it('should render class', () => {
render(<Box className="foo">foo</Box>);
const box = screen.getByTestId(testId);
expect(box).toHaveClass('foo');
});
it('should render screen size', () => {
render(<Box size={Box.Sizes.Screen}>foo</Box>);
const box = screen.getByTestId(testId);
expect(box).toHaveClass(Box.Sizes.Screen);
});
it('should render full size', () => {
render(<Box size={Box.Sizes.Full}>foo</Box>);
const box = screen.getByTestId(testId);
expect(box).toHaveClass(Box.Sizes.Full);
});
it('should render content size', () => {
render(<Box size={Box.Sizes.Content}>foo</Box>);
const box = screen.getByTestId(testId);
expect(box).toHaveClass(Box.Sizes.Content);
});
});
12 changes: 12 additions & 0 deletions packages/styled-components/src/components/containers/Box/Box.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import cn from 'classnames';
import { Props, Sizes } from './Box.types';
import { StyledBox } from './Box.styled';

export const Box = ({ children, className, size, testId = 'box' }: Props) => (
<StyledBox className={cn(className, size)} data-testid={testId}>
{children}
</StyledBox>
);

Box.Sizes = Sizes;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ReactNode } from 'react';

export type Props = {
children?: ReactNode;
className?: string;
size?: Sizes;
testId?: string;
};

export enum Sizes {
Full = 'full',
Screen = 'screen',
Content = 'content',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Box';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Box';
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React from 'react';
import { ConversationList } from '.';
import { action } from '@storybook/addon-actions';
import { text, boolean, number } from '@storybook/addon-knobs';

export default {
title: 'Primitives/Chat/ConversationList',
component: ConversationList,
};

export const Empty = () => (
<>
<h1>Empty</h1>
<ConversationList
conversations={[]}
emptyCaseElement={<div>You don't have any conversation yet</div>}
/>
</>
);

export const Conversations = () => (
<>
<h1>Conversations</h1>
<ConversationList
conversations={[
{
id: 1,
title: 'Pau Teruel',
description: 'Description',
message: 'Message',
time: '10:20 PM',
avatarText: 'PT',
isHighlighted: false,
isError: false,
unreadMessages: 0,
},
{
id: 2,
title: 'John Cena',
description: 'Description',
message: 'Message',
time: '10:23 PM',
avatarText: 'JC',
isHighlighted: true,
isError: false,
unreadMessages: 3,
},
]}
/>
</>
);

export const Playground = () => (
<>
<h1>Playground</h1>
<ConversationList
conversations={[
{
id: text('First Conversation id', '1'),
title: text('First Conversation title', 'Pau Teruel'),
description: text('First Conversation description', 'Description'),
message: text('First Conversation message', 'Message'),
time: text('First Conversation time', '10:20 PM'),
avatarText: text('First Conversation avatarText', 'PT'),
isHighlighted: boolean('First Conversation isHighlighted', false),
isError: boolean('First Conversation isError', false),
unreadMessages: number('First Conversation unreadMessages', 3),
onClick: action('First Conversation on click'),
},
{
id: text('Second Conversation id', '2'),
title: text('Second Conversation title', 'John Cena'),
description: text('Second Conversation description', 'Description'),
message: text('Second Conversation message', 'Message'),
time: text('Second Conversation time', '10:20 PM'),
avatarText: text('Second Conversation avatarText', 'PT'),
isHighlighted: boolean('Second Conversation isHighlighted', true),
isError: boolean('Second Conversation isError', false),
unreadMessages: number('Second Conversation unreadMessages', 5),
onClick: action('Second Conversation on click'),
},
]}
/>
</>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import styled from 'styled-components';
import { getTheme } from 'utils/getTheme';

interface Props {
theme: any;
}

export const StyledUnorderedList = styled.ul<Props>`
list-style-type: none;
`;

export const StyledDivider = styled.div<Props>`
margin-left: 2rem;
border-bottom: 1px solid
${(props) => getTheme(props).colors.outlineBackground400};
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { ConversationList } from '.';

describe('ConversationList', () => {
const testId = 'conversationList';
it('should render classname', () => {
render(<ConversationList className="foo" conversations={[]} />);
const conversationList = screen.getByTestId(testId);
expect(conversationList).toHaveClass('foo');
});
it('should render empty case', () => {
render(
<ConversationList
conversations={[]}
emptyCaseElement={<span>Empty</span>}
/>
);
screen.getByText('Empty');
});
it('should render conversations', () => {
render(
<ConversationList
conversations={[
{
id: '1',
title: 'title',
description: 'description',
message: 'message',
messageClassName: 'italic',
time: 'time',
avatarText: 'avatarText',
isHighlighted: false,
isActive: false,
isError: false,
unreadMessages: 3,
onClick: () => {},
},
{
id: '2',
title: 'title',
description: 'description',
message: 'message',
messageClassName: 'italic',
time: 'time',
avatarText: 'avatarText',
isHighlighted: false,
isActive: false,
isError: false,
unreadMessages: 3,
onClick: () => {},
},
]}
/>
);
const conversationList = screen.getByTestId(testId);
const conversationUnOrderedList = conversationList.lastChild;
const conversationUnOrderedItems = conversationList.lastChild.childNodes;
expect(conversationUnOrderedList).toBeInTheDocument();
expect(conversationUnOrderedItems).toHaveLength(2);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { ConversationSummary } from 'components/primitives/Chat/ConversationSummary';
import { Props } from './ConversationList.types';
import { StyledUnorderedList, StyledDivider } from './ConversationList.styled';

export const ConversationList = ({
id,
conversations,
emptyCaseElement,
className,
selectedConversationId,
testId = 'conversationList',
}: Props) => {
const hasConversations = conversations.length > 0;
const renderConversations = () => (
<StyledUnorderedList>
{conversations.map((conversation) => {
return (
<li key={conversation.id}>
<ConversationSummary
{...conversation}
isActive={conversation.id === selectedConversationId}
/>
<StyledDivider />
</li>
);
})}
</StyledUnorderedList>
);

return (
<div id={id} className={className} data-testid={testId}>
{hasConversations ? renderConversations() : emptyCaseElement}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ReactNode } from 'react';
import { Props as ConversationSummaryProps } from 'components/primitives/Chat/ConversationSummary/ConversationSummary.types';

export type Props = {
id?: string;
conversations: ConversationSummaryProps[];
selectedConversationId?: string;
emptyCaseElement?: ReactNode;
className?: string;
testId?: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ConversationList';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ReactNode } from 'react';

export type Props = {
className?: string;
children?: ReactNode;
onClick?: () => void;
disabled?: boolean;
testId?: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { ButtonItem } from '.';
import { text, boolean } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';

export default {
title: 'Primitives/List/Items/ButtonItem',
component: ButtonItem,
};

export const Playground = () => (
<ButtonItem disabled={boolean('Disabled', false)} onClick={action('Click')}>
{text('Content', 'Content')}
</ButtonItem>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import styled from 'styled-components';
import { getTheme } from 'utils/getTheme';
import { Button } from 'components/primitives/Button';

interface Props {
theme: any;
}

export const StyledButton = styled(Button)<Props>`
display: flex;
align-items: center;
justify-content: start;
padding: 1rem 1.5rem;
white-space: nowrap;
cursor: pointer;
&:hover {
background-color: ${(props) => getTheme(props).colors.fillStateUiHover};
}
&:focus {
outline: none;
}
`;
Loading

0 comments on commit e3cf3c3

Please sign in to comment.