ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ฐ˜์‘ํ˜•

๐ŸŽจ Tailwind๋กœ ๋งŒ๋“œ๋Š” ์ด๋ฏธ์ง€ ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ (์„ ํƒ ํ…Œ๋‘๋ฆฌ + ์ปค์Šคํ…€ X๋ฒ„ํŠผ ์œ„์น˜)

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋‹ค์Œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ธฐ์ดˆ ์ง€์‹์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

  • ์ด๋ฏธ์ง€๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์‚ฌ๊ฐํ˜• ๋ฒ„ํŠผ
  • ํด๋ฆญ ์‹œ ์„ ํƒ๋จ ์ƒํƒœ๋กœ ์ „ํ™˜๋˜๋ฉฐ border ํ‘œ์‹œ
  • X ๋ฒ„ํŠผ์€ ์˜ค๋ฅธ์ชฝ ์ƒ๋‹จ์— ์œ„์น˜ํ•˜๋ฉฐ, ์œ„์น˜๋Š” ์ž์œ ๋กญ๊ฒŒ ์กฐ์ • ๊ฐ€๋Šฅ
  • ์ด๋ฏธ์ง€ ๊ต์ฒด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋„๋ก props ๊ธฐ๋ฐ˜ ์„ค๊ณ„

โœ… ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ

React ๊ธฐ์ค€์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

๐Ÿ’ก ํ•ต์‹ฌ ๊ธฐ๋Šฅ

๊ธฐ๋Šฅ ๊ตฌํ˜„ ์š”์†Œ
์„ ํƒ ์—ฌ๋ถ€ selected prop์œผ๋กœ ์ œ์–ด
์ด๋ฏธ์ง€ ๊ฒฝ๋กœ imageSrc prop
X ๋ฒ„ํŠผ ์œ„์น˜ closeButtonPosition prop (absolute + Tailwind ์กฐํ•ฉ)
ํด๋ฆญ ํ•ธ๋“ค๋Ÿฌ onClick, onClose ๋ถ„๋ฆฌ

โœ… ์˜ˆ์ œ ์ฝ”๋“œ

import React from 'react'
import { X } from 'lucide-react' // X ์•„์ด์ฝ˜ (lucide-react ๋˜๋Š” HeroIcons ์‚ฌ์šฉ ๊ฐ€๋Šฅ)

function ImageSelectButton({
  imageSrc,
  selected = false,
  onClick,
  onClose,
  closeButtonPosition = 'top-1 right-1',
}) {
  return (
    <div
      onClick={onClick}
      className={`relative w-20 h-20 rounded-lg flex items-center justify-center
        ${selected ? 'border-4 border-blue-500' : 'border border-transparent'}
        bg-yellow-200 hover:cursor-pointer transition`}
    >
      <img src={imageSrc} alt="์„ ํƒ ์•„์ด์ฝ˜" className="w-10 h-10" />

      {onClose && (
        <button
          onClick={(e) => {
            e.stopPropagation()
            onClose()
          }}
          className={`absolute ${closeButtonPosition} bg-white rounded-full p-1 shadow-md`}
        >
          <X size={12} />
        </button>
      )}
    </div>
  )
}

export default ImageSelectButton

๐Ÿงช ์‚ฌ์šฉ ์˜ˆ์‹œ

<ImageSelectButton
  imageSrc="/icons/rice.png"
  selected={true}
  onClick={() => console.log('์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒ')}
  onClose={() => console.log('X ํด๋ฆญ๋จ')}
  closeButtonPosition="top-2 right-2"
/>

๐ŸŽฏ ๋งˆ๋ฌด๋ฆฌ

์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค:

  • ๋‹ค์–‘ํ•œ ์ด๋ฏธ์ง€๋ฅผ props๋กœ ๊ต์ฒด ๊ฐ€๋Šฅ
  • ์ƒํƒœ์— ๋”ฐ๋ผ border ์Šคํƒ€์ผ๋ง ๋ณ€๊ฒฝ
  • ๋‹ซ๊ธฐ ๋ฒ„ํŠผ์˜ ์œ„์น˜๋ฅผ Tailwind ํด๋ž˜์Šค ์กฐํ•ฉ์œผ๋กœ ์ž์œ ๋กญ๊ฒŒ ์„ค์ •

์•ž์œผ๋กœ ์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒ ๊ทธ๋ฆฌ๋“œ, ์‚ญ์ œ ๊ฐ€๋Šฅํ•œ ํƒœ๊ทธ ๋ชฉ๋ก, ์ปค์Šคํ…€ ๊ฐค๋Ÿฌ๋ฆฌ ๋“ฑ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œ ์ฐธ๊ณ 

  • X ์•„์ด์ฝ˜์€ lucide-react ๋˜๋Š” @heroicons/react ํŒจํ‚ค์ง€๋ฅผ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.
  • Tailwind์˜ absolute, top-1, right-1 ์กฐํ•ฉ์„ ํ™œ์šฉํ•˜๋ฉด ๋ฒ„ํŠผ ์œ„์น˜๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฐ˜์‘ํ˜•
๋Œ“๊ธ€
๋ฐ˜์‘ํ˜•
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
TAG more
ยซ   2025/06   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
๊ธ€ ๋ณด๊ด€ํ•จ