Skip to content

Commit

Permalink
refactor, feat: separate components, add Icon component
Browse files Browse the repository at this point in the history
  • Loading branch information
ooooorobo committed Aug 6, 2023
1 parent 49885b3 commit 8c30f95
Show file tree
Hide file tree
Showing 11 changed files with 192 additions and 156 deletions.
14 changes: 11 additions & 3 deletions src/client/view/App.tsx
@@ -1,18 +1,26 @@
import React from 'react';
import { initApiClient } from '../../agent/ApiClient';
import { BandalartSharePage } from './share';
import { BandalartSharePage } from './pages/share';
import { Provider } from 'react-redux';
import { Store } from 'redux';
import { css, cx } from '@linaria/core';
import { theme } from './theme';
import { EnvContextProvider } from './components/context/EnvContext';

initApiClient();

export const App = ({ store }: { store: Store }) => {
type AppProps = {
store: Store;
assetPath: string;
};

export const App = ({ store, assetPath }: AppProps) => {
return (
<Provider store={store}>
<div className={cx(globalStyle, 'theme-light')}>
<BandalartSharePage />
<EnvContextProvider assetPath={assetPath}>
<BandalartSharePage />
</EnvContextProvider>
</div>
</Provider>
);
Expand Down
@@ -1,6 +1,6 @@
import React, { CSSProperties } from 'react';
import { css, cx } from '@linaria/core';
import { BandalartDetail } from '../../../../types/BandalartDetail';
import { BandalartDetail } from '../../../types/BandalartDetail';
import dayjs from 'dayjs';

type HeaderSectionProps = {
Expand Down
22 changes: 22 additions & 0 deletions src/client/view/components/_common/Icon.tsx
@@ -0,0 +1,22 @@
import React, { useContext } from 'react';
import { EnvContext } from '../context/EnvContext';
import { LinariaClassName } from '@linaria/core';

export type IconProps = {
className: LinariaClassName;
alt: string;
iconName: IconName;
};

type IconName = 'check';

export const Icon = ({ className, alt, iconName }: IconProps) => {
const { assetPath } = useContext(EnvContext);
return (
<img
className={className}
src={`${assetPath}/icon/${iconName}.svg`}
alt={alt}
/>
);
};
22 changes: 22 additions & 0 deletions src/client/view/components/context/EnvContext.tsx
@@ -0,0 +1,22 @@
import React, { createContext, PropsWithChildren } from 'react';

type EnvContextState = {
assetPath: string;
};

const initialState: EnvContextState = {
assetPath: '',
};

export const EnvContext = createContext(initialState);

export const EnvContextProvider = ({
children,
assetPath,
}: PropsWithChildren<EnvContextState>) => {
return (
<EnvContext.Provider value={{ ...initialState, assetPath }}>
{children}
</EnvContext.Provider>
);
};
@@ -1,7 +1,7 @@
import { css, cx } from '@linaria/core';
import React from 'react';
import { Check } from '../../icons/Check';
import { CELL_SIZE, TABLE_SIZE } from '../../constants/table';
import { Icon } from '../_common/Icon';

type CellType = 'main' | 'sub' | 'task';

Expand All @@ -26,9 +26,7 @@ export const Cell = ({ type, title, isCompleted, position }: CellProps) => {
<div role={'checkbox'} className={className} aria-checked={isCompleted}>
{title}
{isCompleted && (
<div className={completedDim}>
<Check />
</div>
<Icon className={icon} iconName={'check'} alt={'달성 완료 체크 표시'} />
)}
</div>
);
Expand Down Expand Up @@ -98,16 +96,8 @@ const rb = css`
`;
const positionToStyle = { center, lt, rt, lb, rb } as const;

const completedDim = css`
const icon = css`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
svg {
position: absolute;
bottom: 4px;
right: 4px;
}
bottom: 4px;
right: 4px;
`;
84 changes: 84 additions & 0 deletions src/client/view/components/table/SubSection.tsx
@@ -0,0 +1,84 @@
import { Cell, CellPosition } from './Cell';
import { css, cx } from '@linaria/core';
import React from 'react';
import { GAP_BETWEEN_CELLS, PADDING_IN_SECTION } from '../../constants/table';
import { BandalartCell } from '../../../../types/BandalartCell';

type SubSectionProps = {
subCell: BandalartCell;
sectionPosition: CellPosition;
subCellIdxInSection: number;
};

export const SubSection = ({
subCell,
sectionPosition,
subCellIdxInSection,
}: SubSectionProps) => {
return (
<ul key={sectionPosition}>
<li>
<Cell
type={'sub'}
title={subCell.title}
isCompleted={subCell.isCompleted}
position={sectionPosition}
/>
<ul className={cx(subSection, sectionPosition)}>
{subCell.children.flatMap((task, taskIdx) => [
taskIdx === subCellIdxInSection && (
<li key={taskIdx} aria-hidden="true" />
),
<li key={task.key}>
<Cell
type={'task'}
title={task.title}
isCompleted={task.isCompleted}
/>
</li>,
])}
</ul>
</li>
</ul>
);
};

const subSection = css`
position: absolute;
border-radius: 12px;
background-color: var(--color-100);
display: grid;
gap: ${GAP_BETWEEN_CELLS}px;
padding: ${PADDING_IN_SECTION}px;
&.lt,
&.rb {
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
}
&.rt,
&.lb {
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(3, 1fr);
}
&.lt {
top: 0;
left: 0;
}
&.rt {
top: 0;
right: 0;
}
&.lb {
bottom: 0;
left: 0;
}
&.rb {
bottom: 0;
right: 0;
}
`;
42 changes: 42 additions & 0 deletions src/client/view/components/table/Table.tsx
@@ -0,0 +1,42 @@
import { BandalartCell } from '../../../../types/BandalartCell';
import React from 'react';
import { css } from '@linaria/core';
import { Cell, CellPosition } from './Cell';
import { TABLE_SIZE } from '../../constants/table';
import { SubSection } from './SubSection';

type TableProps = {
root: BandalartCell;
};

const subTaskPosition = [4, 2, 3, 1];
const subSectionPosition = ['lt', 'rt', 'lb', 'rb'] as CellPosition[];

export const Table = ({ root }: TableProps) => {
return (
<ul className={container}>
<li>
<Cell
type={'main'}
title={root.title}
isCompleted={root.isCompleted}
position={'center'}
/>
{root.children.map((subCell, subIdx) => (
<SubSection
key={subCell.key}
subCell={subCell}
subCellIdxInSection={subTaskPosition[subIdx]}
sectionPosition={subSectionPosition[subIdx]}
/>
))}
</li>
</ul>
);
};

const container = css`
position: relative;
width: ${TABLE_SIZE}px;
height: ${TABLE_SIZE}px;
`;
27 changes: 0 additions & 27 deletions src/client/view/icons/Check.tsx

This file was deleted.

@@ -1,10 +1,10 @@
import React, { CSSProperties } from 'react';
import { css } from '@linaria/core';
import { useSelector } from 'react-redux';
import { RootState } from '../../stores/createStore';
import { HeaderSection } from './components/HeaderSection';
import { Table } from './components/Table';
import { TABLE_SIZE } from '../constants/table';
import { RootState } from '../../../stores/createStore';
import { HeaderSection } from '../../components/HeaderSection';
import { Table } from '../../components/table/Table';
import { TABLE_SIZE } from '../../constants/table';

export const BandalartSharePage = () => {
const detail = useSelector((state: RootState) => state.bandalartDetail);
Expand Down

0 comments on commit 8c30f95

Please sign in to comment.