Skip to content

Commit

Permalink
fix: Table 코드 깔끔하게 정리
Browse files Browse the repository at this point in the history
  • Loading branch information
eugene028 committed Sep 22, 2024
1 parent 69f91a2 commit 07e9a82
Show file tree
Hide file tree
Showing 15 changed files with 230 additions and 223 deletions.
33 changes: 24 additions & 9 deletions packages/wow-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@
"require": "./dist/TableBodyContainer.cjs",
"import": "./dist/TableBodyContainer.js"
},
"./TableCell": {
"types": "./dist/components/Table/TableCell.d.ts",
"require": "./dist/TableCell.cjs",
"import": "./dist/TableCell.js"
},
"./TableContainer": {
"types": "./dist/components/Table/TableContainer.d.ts",
"require": "./dist/TableContainer.cjs",
Expand All @@ -60,10 +55,30 @@
"require": "./dist/TableHeader.cjs",
"import": "./dist/TableHeader.js"
},
"./TableRow": {
"types": "./dist/components/Table/TableRow.d.ts",
"require": "./dist/TableRow.cjs",
"import": "./dist/TableRow.js"
"./Tbody": {
"types": "./dist/components/Table/Tbody.d.ts",
"require": "./dist/Tbody.cjs",
"import": "./dist/Tbody.js"
},
"./Td": {
"types": "./dist/components/Table/Td.d.ts",
"require": "./dist/Td.cjs",
"import": "./dist/Td.js"
},
"./Th": {
"types": "./dist/components/Table/Th.d.ts",
"require": "./dist/Th.cjs",
"import": "./dist/Th.js"
},
"./Thead": {
"types": "./dist/components/Table/Thead.d.ts",
"require": "./dist/Thead.cjs",
"import": "./dist/Thead.js"
},
"./Tr": {
"types": "./dist/components/Table/Tr.d.ts",
"require": "./dist/Tr.cjs",
"import": "./dist/Tr.js"
},
"./Switch": {
"types": "./dist/components/Switch/index.d.ts",
Expand Down
7 changes: 5 additions & 2 deletions packages/wow-ui/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ export default {
Tag: "./src/components/Tag",
Table: "./src/components/Table/Table",
TableBodyContainer: "./src/components/Table/TableBodyContainer",
TableCell: "./src/components/Table/TableCell",
TableContainer: "./src/components/Table/TableContainer",
TableHeader: "./src/components/Table/TableHeader",
TableRow: "./src/components/Table/TableRow",
Tbody: "./src/components/Table/Tbody",
Td: "./src/components/Table/Td",
Th: "./src/components/Table/Th",
Thead: "./src/components/Table/Thead",
Tr: "./src/components/Table/Tr",
Switch: "./src/components/Switch",
Stepper: "./src/components/Stepper",
BlueSpinner: "./src/components/Spinner/BlueSpinner",
Expand Down
2 changes: 1 addition & 1 deletion packages/wow-ui/src/components/Table/Table.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ const ControlledTable = () => {
선택한 테이블 요소 모두 초기화
</Button>
<Table
selectedRowsProps={selectedRows}
selectedRowsProp={selectedRows}
showCheckbox={true}
onChange={handleSelectionChange}
>
Expand Down
78 changes: 18 additions & 60 deletions packages/wow-ui/src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,102 +2,71 @@
import { css, cva } from "@styled-system/css";
import { styled } from "@styled-system/jsx";
import { clsx } from "clsx";
import type {
CSSProperties,
ForwardRefExoticComponent,
ReactNode,
Ref,
} from "react";
import React, {
Children,
createContext,
forwardRef,
isValidElement,
useEffect,
useState,
} from "react";
import type { CSSProperties, ReactNode, Ref } from "react";
import { forwardRef } from "react";

import { TableContext } from "@/components/Table/TableContext";
import Tbody from "@/components/Table/Tbody";
import Td from "@/components/Table/Td";
import Th from "@/components/Table/Th";
import Thead from "@/components/Table/Thead";
import Tr from "@/components/Table/Tr";
import useCountRow from "@/hooks/useCountRow";
import useTableCheckState from "@/hooks/useTableCheckState";
import type { TableComponentType } from "@/types/table";

/**
* @description 데이터 및 비동기 결과물을 나타낼 수 있는 테이블 컴포넌트입니다.
* @param {string} [tableCaption] 테이블에 대한 설명을 나타내는 캡션입니다.
* @param {TableOptionProps<T>} [options] 테이블에 대한 상세한 옵션값을 설정합니다.
* @param {number[]} [selectedRows] default 값을 설정하거나, 외부에서 table의 체크 상태 관리할 수 있는 변수입니다.
* @param {showCheckbox} [boolean] 테이블에 대한 상세한 옵션값을 설정합니다.
* @param {number[]} [selectedRowsProp] default 값을 설정하거나, 외부에서 table의 체크 상태 관리할 수 있는 변수입니다.
* @param {(selectedRows: number[]) => void} [onChange] 외부 활성 상태가 변경될 때 호출되는 함수입니다.
* @param {() => void} [className] table 컴포넌트에게 전달할 className을 정의합니다.
* @param {() => void} [fullWidth=false] table 컴포넌트의 가로 길이를 결정할 수 있습니다.
* @param {() => void} [style] table 컴포넌트에 커스텀하게 전달할 style입니다.
* @param {Ref<HTMLTableElement>} [ref] ref 렌더링된 요소 또는 컴포넌트에 연결할 ref입니다.
*/

interface TableProps {
export interface TableProps {
tableCaption?: string;
showCheckbox?: boolean;
selectedRowsProps?: number[];
selectedRowsProp?: number[];
onChange?: (selectedRows: number[]) => void;
className?: string;
fullWidth?: boolean;
style?: CSSProperties;
children: ReactNode;
className?: string;
}

export const TableContext = createContext<any>(null);

const TableComponent = forwardRef<HTMLTableElement, TableProps>(
function PaginationTable(
function TableFunction(
{
tableCaption = "",
children,
showCheckbox,
className,
selectedRowsProps,
selectedRowsProp,
onChange,
fullWidth = false,
style,
...rest
}: TableProps,
ref: Ref<HTMLTableElement>
) {
const [rowValue, setRowValues] = useState<number[]>([]);
useEffect(() => {
Children.forEach(children, (child) => {
if (isValidElement(child) && child.type === Table.Tbody) {
Children.forEach(child.props.children, (row) => {
if (isValidElement(row) && row.type === Table.Tr) {
const rowProps = row.props as { value: number };
setRowValues((prevValues) => [...prevValues, rowProps.value]);
}
});
}
});
}, []);

const { rowValues } = useCountRow(children);
const {
handleRowCheckboxChange,
handleHeaderCheckboxChange,
selectedRows,
} = useTableCheckState(rowValue, selectedRowsProps, onChange);
} = useTableCheckState(rowValues, selectedRowsProp, onChange);

const contextValue: ReturnType<typeof useTableCheckState> &
TableProps & { rowValue: number[] } = {
rowValue,
handleRowCheckboxChange,
handleHeaderCheckboxChange,
Omit<TableProps, "children"> & { rowValues: number[] } = {
rowValues,
selectedRows,
children,
showCheckbox,
tableCaption,
selectedRowsProps,
onChange,
className,
fullWidth,
style,
handleRowCheckboxChange,
handleHeaderCheckboxChange,
};

return (
Expand Down Expand Up @@ -128,17 +97,6 @@ const TableComponent = forwardRef<HTMLTableElement, TableProps>(
}
);

interface TableComponentType
extends ForwardRefExoticComponent<
TableProps & React.RefAttributes<HTMLTableElement>
> {
Thead: typeof Thead;
Th: typeof Th;
Tbody: typeof Tbody;
Tr: typeof Tr;
Td: typeof Td;
}

const Table = TableComponent as TableComponentType;
Table.Thead = Thead;
Table.Th = Th;
Expand Down
21 changes: 0 additions & 21 deletions packages/wow-ui/src/components/Table/TableBodyContainer.tsx

This file was deleted.

12 changes: 12 additions & 0 deletions packages/wow-ui/src/components/Table/TableContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createContext } from "react";

import useSafeContext from "@/hooks/useSafeContext";

export const TableContext = createContext<any>(null);

export const useTableContext = () => {
const context = useSafeContext(TableContext);
return context;
};

export const TableCheckedContext = createContext<number | undefined>(0);
32 changes: 0 additions & 32 deletions packages/wow-ui/src/components/Table/TableHeader.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions packages/wow-ui/src/components/Table/Tbody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import React, { forwardRef } from "react";

interface TableBodyProps extends PropsWithChildren {
style?: CSSProperties;
className?: string;
}

const Tbody = forwardRef<HTMLTableSectionElement, TableBodyProps>(
(props, ref) => {
const { children } = props;

const { children, ...rest } = props;
return (
<styled.tbody ref={ref} role="rowgroup" {...props} textAlign="start">
<styled.tbody ref={ref} role="rowgroup" {...rest} textAlign="start">
{children}
</styled.tbody>
);
Expand Down
44 changes: 25 additions & 19 deletions packages/wow-ui/src/components/Table/Td.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
import { cva } from "@styled-system/css";
import { styled } from "@styled-system/jsx";
import { type CSSProperties, type PropsWithChildren, useContext } from "react";
import type { CSSProperties, PropsWithChildren, Ref } from "react";
import { forwardRef, useContext } from "react";

import { TableContext } from "@/components/Table/Table";
import { TableCheckedContext } from "@/components/Table/Tr";
import useSafeContext from "@/hooks/useSafeContext";
import {
TableCheckedContext,
useTableContext,
} from "@/components/Table/TableContext";

interface TableCellProps extends PropsWithChildren {
style?: CSSProperties;
className?: string;
}

const Td = (props: TableCellProps) => {
const { children } = props;
const { selectedRows } = useSafeContext(TableContext);
const value = useContext(TableCheckedContext);
const isSelected = selectedRows.some((row: number) => row === value);
const Td = forwardRef(
(props: TableCellProps, ref: Ref<HTMLTableCellElement>) => {
const { children, ...rest } = props;
const { selectedRows } = useTableContext();
const value = useContext(TableCheckedContext);
const isSelected = selectedRows.some((row: number) => row === value);

return (
<styled.td
className={TableCellStyle({ checked: isSelected })}
role="cell"
{...props}
>
{children}
</styled.td>
);
};
return (
<styled.td
className={TableCellStyle({ checked: isSelected })}
ref={ref}
role="cell"
{...rest}
>
{children}
</styled.td>
);
}
);

const TableCellStyle = cva({
base: {
Expand Down
22 changes: 13 additions & 9 deletions packages/wow-ui/src/components/Table/Th.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { css } from "@styled-system/css";
import type { CSSProperties, PropsWithChildren } from "react";
import type { CSSProperties, PropsWithChildren, Ref } from "react";
import { forwardRef } from "react";

interface TableHeaderProps extends PropsWithChildren {
style?: CSSProperties;
className?: string;
}
const Th = (props: TableHeaderProps) => {
const { children } = props;
return (
<th className={TableHeaderStyle} {...props}>
{children}
</th>
);
};
const Th = forwardRef<HTMLTableCellElement, TableHeaderProps>(
(props: TableHeaderProps, ref: Ref<HTMLTableCellElement>) => {
const { children, ...rest } = props;
return (
<th className={TableHeaderStyle} ref={ref} {...rest}>
{children}
</th>
);
}
);

const TableHeaderStyle = css({
alignItems: "center",
Expand Down
Loading

0 comments on commit 07e9a82

Please sign in to comment.