본문 바로가기

Front-End/React

React #12-2 (CSS - daisyUI: Input & Modal)

반응형

※ 이전 글에서 실습했던 프로젝트 그대로 이어서 진행

https://chiro-j.tistory.com/76

 

React #12 (CSS - daisyUI: Button & Icon)

※ 사전 작업더보기아래 github 레포지토리로 가서 다운로드 받아서, ch03 아래의 ch03_4만 가져오기https://github.com/yisj777s/doit-react-webapp-typescript/tree/main 챕터 3-5 프로젝트 폴더 생성npx create-react-app ch03

chiro-j.tistory.com

 

 

input 컴포넌트 생성

touch src/theme/daisyui/Input.tsx

 

input 컴포넌트 구현

src/theme/daisyui/Input.tsx

import {FC, DetailedHTMLProps, InputHTMLAttributes} from 'react'

export type ReactInputProps = DetailedHTMLProps<
  InputHTMLAttributes<HTMLInputElement>,
  HTMLInputElement
>

export type InputProps = ReactInputProps & {}

export const Input: FC<InputProps> = ({className: _className, ...inputProps}) => {
  const className = ['input', _className].join(' ')
  
  return <input {...inputProps} className={className} />
}

 

input 컴포넌트 반영

src/theme/daisyui/index.ts

 

input Test index 구현

src/pages/InputTest/index.tsx

import Basic from './Basic'
import Color from './Color'
import Border from './Border'
import Size from './Size'


export default function inputTest() {
  return (
    <section className="mt-4">
      <h2 className="text-5xl font-bold text-center">inputTest</h2>
      <div className="mt-4">
        <Size />
        <Border />
        <Color />
        <Basic />
      </div>
    </section>
  )
}

 

 

input 컴포넌트 사용 - basic

src.pages/InputTest/Basic.tsx

import {Input} from '../../theme/daisyui'

export default function Basic() {
  return (
    <section className="mt-4">
      <h2 className="text-3xl font-bold text-center">Basic</h2>
      <div className="flex mt-4 justify-evenly">
        <input className="input input-primary" />
        <Input className="input-primary" />
      </div>
    </section>
  )
}

 

(app.tsx 에서 ButtonTest 쪽은 주석 처리 해둘 것)

 

Input Color 관련

src./pages/InputTest/Color.tsx

import {Input} from '../../theme/daisyui'

export default function Color() {

  return (
    <section className="mt-4">
      <h2 className="text-3xl font-bold text-center">Color</h2>
      <div className="flex flex-col p-4 mt-4">

        <div>
          <label className="label">input-primary</label>
          <Input className="input-primary" />
        </div>

        <div>
          <label className="label">input-secondary</label>
          <Input className="input-secondary" />
        </div>

        <div>
          <label className="label">input-accent</label>
          <Input className="input-accent" />
        </div>

        <div>
          <label className="label">input-info</label>
          <Input className="input-info" />
        </div>

        <div>
          <label className="label">input-success</label>
          <Input className="input-success" />
        </div>

        <div>
          <label className="label">input-warning</label>
          <Input className="input-warning" />
        </div>

        <div>
          <label className="label">input-error</label>
          <Input className="input-error" />
        </div>
        
      </div>
    </section>
  )
}

 

 

Input - Border (테두리) 관련 

 

src/pages/InputTest/Border.tsx

import {Input} from '../../theme/daisyui'

export default function Border() {
  
  return (
    <section className="mt-4">
      <h2 className="text-3xl font-bold text-center">Border</h2>
      <div className="flex mt-4 justify-evenly">

        <div>
          <label className="label">input-bordered</label>
          <Input className="input-bordered" />
        </div>

        <div>
          <label className="label">input-ghost</label>
          <Input className="input-ghost" />
        </div>
        
      </div>
    </section>
  )
}

 

(ghost는 일반적으로 테두리가 보이지 않으며, 클릭했을 때 보임)

 

 

 

Input - Size 관련

 

src/pages/InputTest/Size.tsx

import { Input } from '../../theme/daisyui'

export default function Size() {

  return (
    <section className="mt-4">
      <h2 className="text-3xl font-bold text-center">Size</h2>

      <div className="flex mt-4 justify-evenly">
        <div>
          <label className="label">input-lg</label>
          <Input className="input-primary input-lg" />
        </div>

        <div>
          <label className="label">input-md</label>
          <Input className="input-primary input-md" />
        </div>

        <div>
          <label className="label">input-sm</label>
          <Input className="input-primary input-sm" />
        </div>

        <div>
          <label className="label">input-xs</label>
          <Input className="input-primary input-xs" />
        </div>
        
      </div>
    </section>
  )
}

 

 

 

Modal 컴포넌트

(App.tsx 가서 inputTest를 주석처리 해둘 것.)

 

modal 컴포넌트 생성

touch src/theme/daisyui/Modal.tsx

 

modal 컴포넌트 구현

src/theme/daisyui/Modal.tsx

import type {FC} from 'react'
import type {ReactDivProps} from '../../components'
import {Div} from '../../components'
import {Icon} from './Icon'


export type ModalProps = ReactDivProps & {
  open?: boolean
}

export const Modal: FC<ModalProps> = ({open, className: _className, ...props}) => {
  const className = ['modal', open ? 'modal-open' : '', _className].join(' ')
  return <div {...props} className={className} />
}

export type ModalContentProps = ReactDivProps & {
  onCloseIconClicked?: () => void
  closeIconClassName?: string
}

export const ModalContent: FC<ModalContentProps> = ({
  onCloseIconClicked,
  closeIconClassName: _closeIconClassName,
  className: _className,
  children,
  ...props
}) => {
  const showCloseIcon = onCloseIconClicked ? true : false
  const className = ['modal-box', showCloseIcon && 'relative', _className].join(' ')
  if (!showCloseIcon) return <div {...props} className={className} children={children} />

  const closeIconClassName = _closeIconClassName ?? 'btn-primary btn-outline btn-sm'
  
  return (
    <div {...props} className={className}>
      <Div className="absolute" right="0.5rem" top="0.5rem">
        <Icon name="close" className={closeIconClassName} onClick={onCloseIconClicked} />
      </Div>
      {children}
    </div>
  )
}

export type ModalActionProps = ReactDivProps & {}

export const ModalAction: FC<ModalActionProps> = ({className: _className, ...props}) => {
  const className = ['modal-action', _className].join(' ')
  
  return <div {...props} className={className} />
}

 

modal 컴포넌트 반영하기

src/theme/index.ts

 

 

modal 컴포넌트 사용하기

src/pages/ModalTest.tsx

import { Title, Subtitle } from '../components'
import { Modal, ModalContent, ModalAction, Button } from '../theme/daisyui'
import * as D from '../data'


export default function ModalTest() {
  const open = true // 혹은 false
  const closeClicked = () => alert('closeClicked')
  const acceptClicked = () => alert('acceptClicked')

  return (
    <section className="mt-4">

      <Title>ModalTest</Title>
      
      <Modal open={open}>
        <ModalContent onCloseIconClicked={closeClicked}>
          
          <Subtitle>Modal</Subtitle>
          <p className="mt-4 text-justify">{D.randomParagraphs()}</p>
          
          <ModalAction>
            <Button className="w-24 btn-primary btn-sm" onClick={acceptClicked}>
              Accept
            </Button>
            
            <Button className="w-24 btn-sm" onClick={closeClicked}>
              Close
            </Button>
          </ModalAction>
          
        </ModalContent>
      </Modal>
    </section>
  )
}

 

 

 

팝업은 아닌데, 이미지를 눌렀을 때 크게 볼 때나, 아마 광고에 쓰지 않았었나 싶다.

 

 

반응형