본문 바로가기

Front-End/React

React #8 (CSS - TailwindCSS)

반응형

 

※ 사전 작업

더보기

아래 잘 정리되어 있는 레포에 가서 다운로드 받아 ch03에 있는 ch03_1 폴더를 가져오자.

https://github.com/yisj777s/doit-react-webapp-typescript/tree/main

 

VScode 터미널 (bash)

npm i chance luxon @fontsource/material-icons
npm i -D @types/chance @types/luxon

 

새로 만들어서 쓸 거니까 삭제

rm src/pages/*

 

이번에 새로 쓸 파일들 템플릿으로 복사하기

cd src			# src 경로로 이동
cp copy/CopyMe.tsx pages/Tailwindcss.tsx
cp copy/CopyMe.tsx pages/TextsTest.tsx
cp copy/CopyMe.tsx pages/Color.tsx

 

 미리 src/App.tsx에 다 넣어두자.

import './App.css'

import Tailwindcss from './pages/Tailwindcss'
import Color from './pages/Color'
import TextsTest from './pages/TextsTest'


export default function App() {
  return (
    <div>
      <TextsTest />
      <Color />
      <Tailwindcss />
    </div>
  )
}

 

 패키지 설치 

npm i -D postcss autoprefixer tailwindcss@3.4.17	# 인식 못하는 걸 막기 위해 버전 지정
npx tailwindcss init -p					# tailwindcss 의 구성 파일 생성 (초기 설정 세팅)

 

파일 생긴 거 확인

 

 

daisyui 설치 (버전 지정)

npm i -D daisyui@4.12.12

 

line-clamp 플러그인 설치

npm i -D @tailwindcss/line-clamp

 

tailwind 구성 파일 수정 (tailwind.config.js)

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js, jsx, ts, tsx}"
  ],
  theme: {
    extend: {},
  },
  safelist: [{pattern: /^line-clamp-(\d+)$/}],
  plugins: [require('@tailwindcss/line-clamp'), require('daisyui')],
}

 

 

테일윈드css 기능 반영하기 (src/index.css)

@tailwind base;
@tailwind components;
@tailwind utilities;

 

  

※ 위에서 수정했던 파일들 전부 저장 후, VSCode 껐다가 다시 켜기

 

 

Tailwindcss

src/pages/tailwindcss.tsx

import * as D from '../data'

export default function Tailwindcss() {
  return (
    <div className="bg-black/70">
      <p className="w-full p-4 text-3xl text-white">Tailwindcss</p>
      <p className="italic text-gray-50 line-clamp-3">{D.randomParagraphs(10)}</p>
      <button className="btn btn-primary" style={{textTransform: 'none'}}>
        Button
      </button>
    </div>
  )
}

 

(일단 아래처럼 나온다곤 하는데, 왜 난 이렇게 안 나오지...)

 

 

Color

src/pages/Color.tsx

export default function Color() {
  return (
    <div className="p-4 bg-sky-700">
      <p className="w-full p-4 text-3xl text-white">Color</p>
      <div className="mb-4">
        <p className="text-white">Email address</p>
        <input type="email" className="text-gray-900 border-4 border-sky-200" />
        <p className="text-rose-500">This field is required</p>
      </div>
    </div>
  )
}

 

 

 

TextsTest

 

src/components/textUtil.ts

//prettier-ignore
export const makeClassName = (setting: string, _className?: string, numberOfLines?: number) => [
  setting,
  numberOfLines ? `line-clamp-${numberOfLines}` : '',
  _className ]
  .join(' ')

 

src/components/Texts.tsx

import type {FC, DetailedHTMLProps, HTMLAttributes} from 'react'
import {makeClassName} from './textUtil'

type TextProps = DetailedHTMLProps<
  HTMLAttributes<HTMLParagraphElement>,
  HTMLParagraphElement
>

export type TitleProps = TextProps & {
  numberOfLines?: number
}
export const Title: FC<TitleProps> = ({
  className: _className,
  numberOfLines,
  ...props
}) => {
  const className = makeClassName(
    'font-bold text-5xl text-center whitespace-pre-line',
    _className,
    numberOfLines
  )
  return <p {...props} className={className} />
}

export type SubtitleProps = TitleProps & {}
export const Subtitle: FC<SubtitleProps> = ({
  className: _className,
  numberOfLines,
  ...props
}) => {
  const className = makeClassName(
    'font-semibold text-3xl text-center whitespace-pre-line',
    _className,
    numberOfLines
  )
  return <p {...props} className={className} />
}

export type SummaryProps = SubtitleProps & {}
export const Summary: FC<SummaryProps> = ({
  className: _className,
  numberOfLines,
  ...props
}) => {
  const className = makeClassName(
    'text-sm whitespace-pre-line',
    _className,
    numberOfLines
  )
  return <p {...props} className={className} />
}

export type ParagraphProps = SummaryProps & {}
export const Paragraph: FC<ParagraphProps> = ({
  className: _className,
  numberOfLines,
  ...props
}) => {
  const className = makeClassName(
    'font-normal text-base whitespace-pre-line',
    _className,
    numberOfLines
  )
  return <p {...props} className={className} />
}

 

src/components/index.ts

 

src/pages/TextsTest.tsx

import * as D from '../data'
import {Title, Subtitle, Summary, Paragraph} from '../components'

const paragraphs = D.makeArray(2).map(D.randomParagraphs).join('\n\n')
const summery = D.makeArray(3).map(D.randomSentence).join('\n')

export default function TextsTest() {
  return (
    <div>
      <Title>TextsTest</Title>
      <div>
        <Title className="text-blue-600">{D.randomTitleText()}</Title>
        <Subtitle className="text-blue-400">{D.randomSentence()}</Subtitle>
        <p className="text-xl italic font-bold text-center text-gray-900">
          {D.randomName()}
        </p>
        <Paragraph numberOfLines={5}>{paragraphs}</Paragraph>
        <Summary className="text-center text-gray-500">{summery}</Summary>
        <p className="text-center text-p">
          {D.randomDayMonthYear()} ({D.randomRelativeDate()})
        </p>
      </div>
    </div>
  )
}

 

 

 

 

※ Text 컴포넌트 흐름 파악하기

1. 텍스트 컴포넌트에 쓰일 유틸리티 함수 만들기
2. 텍스트로 활용할 부분부분마다 받을 타입 지정하고 텍스트로 활용할 부분 정의
3. 컴파일해서 넘겨줄 다리 놓아주기
4. 텍스트 컴포넌트를 활용할 함수 만들기

 

 

 

 

+ 추가 : TailwindCSS의 속성들 모음 및 요약 & 정리

https://github.com/leejaehee1/leejaehee1/blob/main/lecture-material/Tailwind%20CSS%20%EC%9A%94%EC%95%BD%ED%91%9C.md

 

leejaehee1/lecture-material/Tailwind CSS 요약표.md at main · leejaehee1/leejaehee1

TMD GEN AI 기반 웹 개발 저장소. Contribute to leejaehee1/leejaehee1 development by creating an account on GitHub.

github.com

 

 

 

 

 

반응형

'Front-End > React' 카테고리의 다른 글

React #10 (CSS - flexbox layout)  (0) 2025.07.14
React #9 (CSS - 박스모델)  (2) 2025.07.10
React #7 (CSS - 아이콘)  (2) 2025.07.09
React #6 (CSS - bootstrap)  (1) 2025.07.09
React #5 (이벤트)  (2) 2025.07.09