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

๋ฐ˜์‘ํ˜•

๐Ÿงฉ ์•„์ด์ฝ˜๊ณผ ํ…์ŠคํŠธ๊ฐ€ ํ•จ๊ป˜ ๋“ค์–ด๊ฐ„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ๊ฐ€๋Šฅํ•œ ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ (Tailwind + React)

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Tailwind CSS๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ,
์•„์ด์ฝ˜๊ณผ ํ…์ŠคํŠธ๊ฐ€ ํ•จ๊ป˜ ํ‘œ์‹œ๋˜๊ณ , ์ƒ‰์ƒ/ํฐํŠธ/๋ชจ์„œ๋ฆฌ ๋“ฑ์„ ์ž์œ ๋กญ๊ฒŒ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œ ๋ชฉํ‘œ ๋””์ž์ธ

  • ์•„์ด์ฝ˜ + ํ…์ŠคํŠธ ์ˆ˜ํ‰ ์ •๋ ฌ
  • ๋ฐฐ๊ฒฝ์ƒ‰, ํ…์ŠคํŠธ์ƒ‰, border-radius ๋“ฑ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ๊ฐ€๋Šฅ
  • ํด๋ฆญ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง ๊ฐ€๋Šฅ
  • ๋ฐ˜๋ณต ์‚ฌ์šฉ์ด ์‰ฌ์šด ์žฌ์‚ฌ์šฉํ˜• ๊ตฌ์กฐ

๐Ÿงฑ ButtonPresets.js (์Šคํƒ€์ผ ํ”„๋ฆฌ์…‹)

// src/styles/buttonPresets.js

export const buttonPresets = {
  default: {
    background: 'bg-gray-100',
    textColor: 'text-black',
    font: 'text-sm font-semibold',
    padding: 'px-4 py-2',
    radius: 'rounded-xl',
    iconSize: 'w-5 h-5',
    gap: 'gap-2',
  },
  outline: {
    background: 'bg-white border border-gray-300',
    textColor: 'text-gray-700',
    font: 'text-sm font-medium',
    padding: 'px-3 py-2',
    radius: 'rounded-md',
    iconSize: 'w-4 h-4',
    gap: 'gap-1.5',
  },
}

๐Ÿงฉ IconButton.jsx (์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„)

import React from 'react'
import { buttonPresets } from '../styles/buttonPresets'

function IconButton({
  icon,
  label,
  onClick,
  variant = 'default',
  customClass = '',
}) {
  const style = buttonPresets[variant] ?? buttonPresets.default

  return (
    <button
      onClick={onClick}
      className={`
        inline-flex items-center ${style.gap}
        ${style.padding} ${style.background} ${style.textColor} ${style.font} ${style.radius}
        hover:opacity-90 active:scale-95 transition ${customClass}
      `}
    >
      <span className={style.iconSize}>{icon}</span>
      <span>{label}</span>
    </button>
  )
}

export default IconButton

๐Ÿงช ์‚ฌ์šฉ ์˜ˆ์‹œ (App.jsx)

import { Pencil, Share2 } from 'lucide-react'
import IconButton from './components/IconButton'

function App() {
  return (
    <div className="flex gap-4 p-6 bg-gray-50">
      <IconButton
        icon={<Pencil />}
        label="์ˆ˜์ •ํ•˜๊ธฐ"
        onClick={() => alert('์ˆ˜์ • ํด๋ฆญ')}
        variant="default"
      />
      <IconButton
        icon={<Share2 />}
        label="๊ณต์œ ํ•˜๊ธฐ"
        onClick={() => alert('๊ณต์œ  ํด๋ฆญ')}
        variant="default"
      />
    </div>
  )
}

์•„์ด์ฝ˜์€ lucide-react ๋˜๋Š” @heroicons/react ๋“ฑ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
์„ค์น˜: npm install lucide-react


๐Ÿ’ก ํ™•์žฅ ์•„์ด๋””์–ด

  • ๋ฒ„ํŠผ์— disabled ์†์„ฑ ์ถ”๊ฐ€
  • iconPosition="left" | "right" ์œผ๋กœ ์•„์ด์ฝ˜ ์œ„์น˜ ๋ฐ”๊พธ๊ธฐ
  • ์ƒ‰์ƒ preset์„ primary, danger, success ๋“ฑ์œผ๋กœ ๋ถ„๋ฆฌ
  • ๋ฒ„ํŠผ ํฌ๊ธฐ preset (sm, md, lg) ๋„์ž…

โœ… ๋งˆ๋ฌด๋ฆฌ

์ด์ฒ˜๋Ÿผ ๋ฒ„ํŠผ์„ ์•„์ด์ฝ˜ + ํ…์ŠคํŠธ ์กฐํ•ฉ์œผ๋กœ ๋งŒ๋“ค๊ณ ,
Tailwind ์Šคํƒ€์ผ์„ preset์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ํ›จ์”ฌ ์‰ฌ์šด ๊ตฌ์กฐ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ“Œ ๋‹ค์Œ ๊ธ€ ์˜ˆ๊ณ 

๋‹ค์Œ ๊ธ€์—์„œ๋Š” ๋ฒ„ํŠผ ๊ทธ๋ฃน ๊ตฌ์„ฑ, ๋˜๋Š” ๋กœ๋”ฉ ์ƒํƒœ๊ฐ€ ์žˆ๋Š” ๋ฒ„ํŠผ (๋กœ๋”ฉ ์Šคํ”ผ๋„ˆ ํฌํ•จ) ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.
ํ•„์š”ํ•œ ์š”์†Œ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์„ธ์š”. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜Š

๋ฐ˜์‘ํ˜•
๋Œ“๊ธ€
๋ฐ˜์‘ํ˜•
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
TAG more
ยซ   2025/05   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
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 31
๊ธ€ ๋ณด๊ด€ํ•จ