※ 사전 작업
아래 github 레포지토리로 가서 다운로드 받아서, ch03 아래의 ch03_4만 가져오기
https://github.com/yisj777s/doit-react-webapp-typescript/tree/main
챕터 3-5 프로젝트 폴더 생성
npx create-react-app ch03_5 --template typescript
패키지 설치 (버전 지정 주의)
npm i chance luxon @fontsource/material-icons
npm i -D @types/chance @types/luxon
npm i -D postcss autoprefixer tailwindcss@3.4.17 @tailwindcss/line-clamp daisyui@4.12.14
이전 프로젝트에서 쓰인 소스 코드들 전부 복사해온 후 page 내 파일들 삭제
cp -r ../ch03_4/src/* ./src
cp -r ../ch03_4/*.js .
rm src/pages/*
서브 디렉토리를 만들어서 실습하므로, 미리 오류가 나지 않게 처리 (상대 경로 문제)
src/copy/CopyMe.tsx
export default function CopyMe() {
return (
<section className="mt-4">
<h2 className="text-5xl font-bold text-center">CopyMe</h2>
<div className="mt-4"></div>
</section>
)
}
실습에 쓰기 위해 템플릿을 복사해오기 + 각각의 컴포넌트 디렉토리 안으로 복사 (버튼 따로, 인풋 따로)
mkdir -p src/copy/CopyMe
cd src/copy
cp CopyMe.tsx CopyMe/index.tsx
cd ../..
cd src
cp -r copy/CopyMe pages/ButtonTest
cp -r copy/CopyMe pages/InputText
cp copy/CopyMe/index.tsx pages/ModalTest.tsx
cd ..

App 파일에 미리 자리 깔아두기
src/App.tsx
import ButtonTest from './pages/ButtonTest'
import InputTest from './pages/InputTest'
import ModalTest from './pages/ModalTest'
export default function App() {
return (
<main>
<ButtonTest />
<InputTest />
<ModalTest />
</main>
)
}
daisy CSS 컴포넌트 만들기
mkdir -p src/theme/daisyui
cd src/theme/daisyui
touch index.ts Button.tsx
cd ../../..
Button 컴포넌트 구현
src/theme/daisyui/Button.tsx
import type {FC, DetailedHTMLProps, ButtonHTMLAttributes, PropsWithChildren} from 'react'
export type ReactButtonProps = DetailedHTMLProps<
ButtonHTMLAttributes<HTMLButtonElement>,
HTMLButtonElement
>
export type ButtonProps = ReactButtonProps & {}
export const Button: FC<PropsWithChildren<ButtonProps>> = ({
className: _className,
...buttonProps
}) => {
const className = ['btn', _className].join(' ')
return <button {...buttonProps} className={className} />
}
Button 컴포넌트 반영
src/theme/daisyui/index.ts
export * from './Button'
서브 컴포넌트 추가 생성 (기본 버튼, 버튼 사이즈 변화, 아이콘)
cd src
cp copy/CopyMe.tsx pages/ButtonTest/Basic.tsx
cp copy/CopyMe.tsx pages/ButtonTest/Size.tsx
cp copy/CopyMe.tsx pages/ButtonTest/IconTest.tsx
Button Test - index 구현
src/pages/ButtonTest/index.tsx
import Basic from './Basic'
import Size from './Size'
import IconTest from './IconTest'
export default function ButtonTest() {
return (
<section className="mt-4">
<h2 className="text-5xl font-bold text-center">ButtonTest</h2>
<div className="mt-4">
<IconTest />
<Size />
<Basic />
</div>
</section>
)
}
Button Test - 각각의 페이지 구현 (웹에 서빙)
src/pages/ButtonTest/Basic.tsx
import {Button} from '../../theme/daisyui'
export default function Basic() {
return (
<section className="mt-4">
<h2 className="text-5xl font-bold text-center">Basic</h2>
<div className="flex mt-4 justify-evenly">
<button className="btn btn-primary">DAYSIUI BUTTON</button>
<Button className="btn-primary">BUTTON</Button>
</div>
</section>
)
}

※ 'btn' 부분 생략하기 (안해도 됨)
Button Test - Size
size 컴포넌트 생성
cd src/pages/ButtonTest
cp Basic.tsx Size.tsx
cd ../../..
src/pages/ButtonTest/Size.tsx
import {Button} from '../../theme/daisyui'
export default function Size() {
return (
<section className="mt-4">
<h2 className="text-5xl font-bold text-center">Size</h2>
<div className="flex mt-4 justify-evenly">
<Button className="btn-lg btn-primary">BTN-LG</Button>
<Button className="btn-md btn-primary">BTN-MD</Button>
<Button className="btn-sm btn-primary">BTN-SM</Button>
<Button className="btn-xs btn-primary">BTN-XS</Button>
</div>
</section>
)
}

icon 컴포넌트 생성
touch src/theme/daisyui/Icon.tsx
icon 컴포넌트 구현
import type {FC} from 'react'
import type {ButtonProps} from './Button'
import type {IconProps as CIconProps} from '../../components'
import {Button} from './Button'
import {Icon as CIcon} from '../../components'
export type IconProps = ButtonProps &
CIconProps & {
iconClassName?: string
}
export const Icon: FC<IconProps> = ({name, iconClassName, className, ...buttonProps}) => {
const btnClassName = ['btn-circle', className].join(' ')
return (
<Button {...buttonProps} className={btnClassName}>
<CIcon className={iconClassName} name={name} />
</Button>
)
}
icon 컴포넌트 반영

icon 컴포넌트 사용
import {Icon} from '../../theme/daisyui'
//prettier-ignore
export default function IconTest() {
const onClick = () => alert('Icon clicked')
return (
<section className="mt-4">
<h2 className="text-5xl font-bold text-center">IconTest</h2>
<div className="flex items-center justify-around mt-4">
<Icon className="btn-primary btn-lg" iconClassName="text-5xl"
name="settings" onClick={onClick} />
<Icon className="btn-secondary btn-md" iconClassName="text-3xl"
name="done" onClick={onClick} />
<Icon className="btn-accent btn-sm" iconClassName="text-xl"
name="menu" onClick={onClick} />
<Icon className="btn-success btn-xs" name="file_upload" onClick={onClick} />
</div>
</section>
)
}

'Front-End > React' 카테고리의 다른 글
| React #13 (포트폴리오 용 여러가지 만들기-프로필 카드) (1) | 2025.07.15 |
|---|---|
| React #12-2 (CSS - daisyUI: Input & Modal) (1) | 2025.07.14 |
| React #11 (CSS - user & card) (0) | 2025.07.14 |
| React #10 (CSS - flexbox layout) (0) | 2025.07.14 |
| React #9 (CSS - 박스모델) (2) | 2025.07.10 |