Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement List molecule component/#18 #27

Merged
merged 18 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 3 additions & 3 deletions app/ui/view/atom/button/button.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './button';
import Button from './button';

const meta = {
title: 'ui/view/atom/Button',
Expand Down Expand Up @@ -71,10 +71,10 @@ export const SecondaryButton: StoryObj<typeof Button> = {
render: (args) => <Button {...args} />,
};

export const DeleteButton: StoryObj<typeof Button> = {
export const ListActionButton: StoryObj<typeof Button> = {
args: {
size: 'default',
variant: 'delete',
variant: 'list',
label: '์‚ญ์ œ',
},
render: (args) => <Button {...args} />,
Expand Down
10 changes: 6 additions & 4 deletions app/ui/view/atom/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import React from 'react';

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
label: string;
variant?: 'primary' | 'secondary' | 'text' | 'delete';
variant?: 'primary' | 'secondary' | 'text' | 'list';
size?: 'xs' | 'sm' | 'md' | 'lg' | 'default';
}

export const ButtonVariants = cva(`flex justify-center items-center`, {
variants: {
variant: {
primary: 'bg-primary rounded-[100px] text-white border-0 hover:bg-primary-hover',
secondary: 'bg-white rounded-[100px] border-solid border-[1px] border-gray hover:bg-white-hover',
secondary: 'bg-white rounded-[100px] border-solid border-[1px] border-gray-6 hover:bg-white-hover',
text: 'font-medium text-slate-400 text-sm hover:text-slate-600',
delete: 'py-2 px-3.5 bg-[#35353559] rounded-[7px] text-white leading-5 font-medium text-[18px]',
list: 'py-2 px-3.5 bg-neutral-400 rounded-[7px] text-white leading-5 font-medium text-[18px] hover:bg-neutral-500',
},
size: {
default: '',
Expand All @@ -25,7 +25,7 @@ export const ButtonVariants = cva(`flex justify-center items-center`, {
},
});

export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(
{ label, variant = 'primary', size = 'default', ...props },
ref,
) {
Expand All @@ -35,3 +35,5 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function
</button>
);
});

export default Button;
9 changes: 9 additions & 0 deletions app/ui/view/molecule/grid/grid-column.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ReactNode } from 'react';

type GridColumnProps = {
children: ReactNode;
};

export function GridColumn({ children }: GridColumnProps) {
return <div className={'place-self-center text-center'}>{children}</div>;
}
23 changes: 23 additions & 0 deletions app/ui/view/molecule/grid/grid-root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { cva } from 'class-variance-authority';
import { ReactNode } from 'react';

export type ColType = 3 | 4 | 5 | 6;

type GridRootProps = {
children: ReactNode;
cols: ColType;
};

export const GridVariants = cva('grid', {
variants: {
cols: {
3: 'grid-cols-3',
4: 'grid-cols-4',
5: 'grid-cols-5',
6: 'grid-cols-6',
},
},
});
export function GridRoot({ children, cols = 3 }: GridRootProps) {
return <div className={GridVariants({ cols })}>{children}</div>;
}
8 changes: 8 additions & 0 deletions app/ui/view/molecule/grid/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { GridColumn } from './grid-column';
import { GridRoot } from './grid-root';

const Grid = Object.assign(GridRoot, {
Column: GridColumn,
});

export default Grid;
8 changes: 8 additions & 0 deletions app/ui/view/molecule/list/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ListRoot } from './list-root';
import { ListRow } from './list-row';

const List = Object.assign(ListRoot, {
Row: ListRow,
});

export default List;
10 changes: 10 additions & 0 deletions app/ui/view/molecule/list/list-root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ReactNode } from 'react';

type ListRootProps<T> = {
data: T[];
render: (item: T) => ReactNode;
};

export function ListRoot<T>({ data, render }: ListRootProps<T>) {
return <div className="rounded-2xl border-[1px] border-black-2 w-full">{data.map((item) => render(item))}</div>;
}
19 changes: 19 additions & 0 deletions app/ui/view/molecule/list/list-row.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ReactNode } from 'react';
import { twMerge } from 'tailwind-merge';

type ListRowProps = {
children: ReactNode;
textColor?: 'red' | 'black';
};
export function ListRow({ children, textColor = 'black' }: ListRowProps) {
return (
<div
className={twMerge(
'border-solid border-gray-300 border-b-[1px] last:border-b-0 py-4 font-medium text-lg',
textColor === 'red' ? 'text-red-500' : 'text-black-2',
)}
>
{children}
</div>
);
}
8 changes: 8 additions & 0 deletions app/ui/view/molecule/table/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { TableHeader } from './table-header';
import { TableRoot } from './table-root';

const Table = Object.assign(TableRoot, {
Header: TableHeader,
});

export default Table;
19 changes: 19 additions & 0 deletions app/ui/view/molecule/table/table-header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Grid from '../grid';
import { ColType } from '../grid/grid-root';

type TableHeaderProps = {
headerInfo: string[];
cols: ColType;
};

export function TableHeader({ cols, headerInfo }: TableHeaderProps) {
return (
<div className="text-light-blue-6 leading-4 text-lg font-bold bg-light-blue-1 py-5 rounded-[100px]">
<Grid cols={cols}>
{headerInfo.map((info) => (
<Grid.Column key={info}>{info}</Grid.Column>
))}
</Grid>
</div>
);
}
41 changes: 41 additions & 0 deletions app/ui/view/molecule/table/table-root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { TableHeader } from './table-header';
import { ColType } from '../grid/grid-root';
import List from '../list';
import Grid from '../grid';

type TableRootProps = {
headerInfo: string[];
data: string[][];
actionButton?: JSX.Element;
};

function isCol(cols: number): cols is ColType {
if (cols === 3 || cols === 4 || cols === 5 || cols === 6) {
return true;
}
return false;
}

export function TableRoot({ data, headerInfo, actionButton }: TableRootProps) {
const cols = actionButton ? headerInfo.length + 1 : headerInfo.length;

const render = (item: string[]) => {
return (
<List.Row>
<Grid cols={isCol(cols) ? cols : 6}>
{item.map((info) => (
<Grid.Column key={info}>{info}</Grid.Column>
))}
{actionButton ? <Grid.Column>{actionButton}</Grid.Column> : null}
</Grid>
</List.Row>
);
};

return (
<div className="flex flex-col gap-2.5 w-[800px]">
<TableHeader headerInfo={headerInfo} cols={isCol(cols) ? cols : 6} />
<List data={data} render={render}></List>
</div>
);
}
44 changes: 44 additions & 0 deletions app/ui/view/molecule/table/table.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { Meta, StoryObj } from '@storybook/react';
import Table from '.';
import Button from '../../atom/button/button';

const meta = {
title: 'ui/view/molecule/Table',
component: Table,
} satisfies Meta<typeof Table>;

export default meta;

export const TakenLectureTable: StoryObj = {
render: () => {
const headerInfo = ['๊ณผ๋ชฉ์ฝ”๋“œ', '๊ณผ๋ชฉ๋ช…', 'ํ•™์ '];
const lectures = [
['HEC01208', '๋ฐ์ดํ„ฐ๊ตฌ์กฐ์™€์•Œ๊ณ ๋ฆฌ์ฆ˜1', '3'],
['HEC01208', '๋ฐ์ดํ„ฐ๊ตฌ์กฐ์™€์•Œ๊ณ ๋ฆฌ์ฆ˜1', '3'],
['HEC01208', '๋ฐ์ดํ„ฐ๊ตฌ์กฐ์™€์•Œ๊ณ ๋ฆฌ์ฆ˜1', '3'],
];

return (
<main>
<Table data={lectures} headerInfo={headerInfo} />
</main>
);
},
};

export const ButtonLectureTable: StoryObj = {
render: () => {
const headerInfo = ['์ˆ˜๊ฐ•๋…„๋„', '์ˆ˜๊ฐ•ํ•™๊ธฐ', '๊ณผ๋ชฉ์ฝ”๋“œ', '๊ณผ๋ชฉ๋ช…', 'ํ•™์ '];
const lectures = [
['2022', '2ํ•™๊ธฐ', 'HEC01208', '๋ฐ์ดํ„ฐ๊ตฌ์กฐ์™€์•Œ๊ณ ๋ฆฌ์ฆ˜1', '3'],
['2022', '2ํ•™๊ธฐ', 'HEC01208', '๋ฐ์ดํ„ฐ๊ตฌ์กฐ์™€์•Œ๊ณ ๋ฆฌ์ฆ˜1', '3'],
['2022', '2ํ•™๊ธฐ', 'HEC01208', '๋ฐ์ดํ„ฐ๊ตฌ์กฐ์™€์•Œ๊ณ ๋ฆฌ์ฆ˜1', '3'],
];
const actionButton = <Button variant="list" label="์‚ญ์ œ" />;
return (
<main>
<Table headerInfo={headerInfo} data={lectures} actionButton={actionButton} />
</main>
);
},
};
Loading