Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Implemented bare minimum list component #19

Merged
merged 2 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions src/components/List/List.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react";
import { userEvent, waitFor, within } from "@storybook/testing-library";
import { expect } from "@storybook/jest";

import { List } from "./List";
import { ListItem } from "./ListItem/ListItem";

const meta: Meta<typeof List> = {
component: List,
};

export default meta;

export const Default: StoryObj<typeof meta> = {
render: () => {
const [workingIndex, setWorkingIndex] = useState(1);

return (
<>
<List>
<ListItem isCompleted={workingIndex >= 1} nthItem={1}>
Hello World
</ListItem>
<ListItem isCompleted={workingIndex >= 2} nthItem={2}>
Bonjour le monde
</ListItem>
<ListItem isCompleted={workingIndex >= 3} nthItem={3}>
你好, 世界
</ListItem>
</List>
<br />
<button type="button" onClick={() => setWorkingIndex(workingIndex + 1)}>
Complete
</button>
</>
);
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement.parentElement);
const button = canvas.getByText("Complete");

expect(canvas.getAllByLabelText("complete")).toHaveLength(1);
valentinpalkovic marked this conversation as resolved.
Show resolved Hide resolved

userEvent.click(button);
valentinpalkovic marked this conversation as resolved.
Show resolved Hide resolved

await waitFor(() =>
expect(canvas.getAllByLabelText("complete")).toHaveLength(2)
valentinpalkovic marked this conversation as resolved.
Show resolved Hide resolved
);
},
};
9 changes: 9 additions & 0 deletions src/components/List/List.styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { styled } from "@storybook/theming";

export const ListWrapper = styled.ul(() => ({
display: "flex",
flexDirection: "column",
rowGap: 16,
padding: 0,
margin: 0,
}));
10 changes: 10 additions & 0 deletions src/components/List/List.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from "react";
import { ListWrapper } from "./List.styled";

interface ListProps {
children: React.ReactNode;
}

export const List = ({ children }: ListProps) => {
return <ListWrapper>{children}</ListWrapper>;
};
31 changes: 31 additions & 0 deletions src/components/List/ListItem/ListItem.styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { styled } from "@storybook/theming";

export const ListItemWrapper = styled.li(() => ({
display: "flex",
alignItems: "flex-start",
columnGap: 12,
}));

export const ListItemContentWrapper = styled.div(({ theme }) => ({
fontFamily: theme.typography.fonts.base,
color: theme.color.darker,
fontSize: "13px",
}));

export const ListItemIndexWrapper = styled.div<{ isCompleted: boolean }>(
({ isCompleted, theme }) => ({
display: "flex",
alignItems: "center",
justifyContent: "center",
border: !isCompleted && `1px solid ${theme.color.medium}`,
minWidth: 20,
width: 20,
height: 20,
borderRadius: "50%",
backgroundColor: isCompleted ? theme.color.green : "white",
fontFamily: theme.typography.fonts.base,
fontSize: 10,
fontWeight: 600,
color: theme.color.dark,
})
);
27 changes: 27 additions & 0 deletions src/components/List/ListItem/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import { Icons } from "@storybook/components";
import {
ListItemContentWrapper,
ListItemIndexWrapper,
ListItemWrapper,
} from "./ListItem.styled";

interface ListItemProps {
children: React.ReactNode;
nthItem: number;
valentinpalkovic marked this conversation as resolved.
Show resolved Hide resolved
isCompleted?: boolean;
}

export const ListItem = ({ children, nthItem, isCompleted }: ListItemProps) => {
return (
<ListItemWrapper>
<ListItemIndexWrapper
aria-label={isCompleted ? "complete" : "not complete"}
isCompleted={isCompleted}
>
{isCompleted ? <Icons icon="check" color="white" /> : nthItem}
valentinpalkovic marked this conversation as resolved.
Show resolved Hide resolved
</ListItemIndexWrapper>
<ListItemContentWrapper>{children}</ListItemContentWrapper>
</ListItemWrapper>
);
};