필터 및 화면 수정사항 반영
This commit is contained in:
162
frontend/src/app/demo/floating-button/page.tsx
Normal file
162
frontend/src/app/demo/floating-button/page.tsx
Normal file
@@ -0,0 +1,162 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { ArrowUp, ChevronUp, ChevronsUp, MoveUp } from 'lucide-react'
|
||||
|
||||
export default function FloatingButtonDemo() {
|
||||
const [selectedStyle, setSelectedStyle] = useState<number>(1)
|
||||
|
||||
const styles = [
|
||||
{
|
||||
id: 1,
|
||||
name: '기본 프라이머리',
|
||||
className: 'bg-primary text-white shadow-lg hover:bg-primary/90',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '그라데이션 블루',
|
||||
className: 'bg-gradient-to-r from-blue-500 to-indigo-600 text-white shadow-xl shadow-blue-500/30 hover:shadow-blue-500/50',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '글래스모피즘',
|
||||
className: 'bg-white/80 backdrop-blur-md border border-white/50 text-slate-700 shadow-lg hover:bg-white/90',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '아웃라인',
|
||||
className: 'bg-white border-2 border-primary text-primary hover:bg-primary hover:text-white',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '미니멀 다크',
|
||||
className: 'bg-slate-800 text-white shadow-lg hover:bg-slate-700',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: '소프트 그레이',
|
||||
className: 'bg-slate-100 text-slate-600 shadow-md hover:bg-slate-200 hover:text-slate-800',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: '그린 그라데이션',
|
||||
className: 'bg-gradient-to-r from-emerald-500 to-teal-600 text-white shadow-xl shadow-emerald-500/30',
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: '네온 퍼플',
|
||||
className: 'bg-violet-600 text-white shadow-xl shadow-violet-500/40 hover:shadow-violet-500/60',
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: '오렌지 웜',
|
||||
className: 'bg-gradient-to-r from-orange-400 to-rose-500 text-white shadow-xl shadow-orange-500/30',
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: '심플 화이트',
|
||||
className: 'bg-white text-slate-500 shadow-xl border border-slate-200 hover:text-primary hover:border-primary',
|
||||
},
|
||||
]
|
||||
|
||||
const icons = [
|
||||
{ id: 'arrow', icon: ArrowUp, name: 'ArrowUp' },
|
||||
{ id: 'chevron', icon: ChevronUp, name: 'ChevronUp' },
|
||||
{ id: 'chevrons', icon: ChevronsUp, name: 'ChevronsUp' },
|
||||
{ id: 'move', icon: MoveUp, name: 'MoveUp' },
|
||||
]
|
||||
|
||||
const [selectedIcon, setSelectedIcon] = useState('arrow')
|
||||
const SelectedIconComponent = icons.find(i => i.id === selectedIcon)?.icon || ArrowUp
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-50 p-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h1 className="text-3xl font-bold mb-2">플로팅 버튼 스타일 데모</h1>
|
||||
<p className="text-slate-600 mb-8">원하는 스타일을 선택해보세요. 우하단에 실제 버튼이 표시됩니다.</p>
|
||||
|
||||
{/* 아이콘 선택 */}
|
||||
<div className="mb-8">
|
||||
<h2 className="text-lg font-semibold mb-4">아이콘 선택</h2>
|
||||
<div className="flex gap-3">
|
||||
{icons.map((icon) => {
|
||||
const IconComp = icon.icon
|
||||
return (
|
||||
<button
|
||||
key={icon.id}
|
||||
onClick={() => setSelectedIcon(icon.id)}
|
||||
className={`flex flex-col items-center gap-2 p-4 rounded-xl border-2 transition-all ${
|
||||
selectedIcon === icon.id
|
||||
? 'border-primary bg-primary/5'
|
||||
: 'border-slate-200 bg-white hover:border-slate-300'
|
||||
}`}
|
||||
>
|
||||
<IconComp className="w-6 h-6" />
|
||||
<span className="text-xs text-slate-600">{icon.name}</span>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 스타일 선택 그리드 */}
|
||||
<h2 className="text-lg font-semibold mb-4">스타일 선택</h2>
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4 mb-12">
|
||||
{styles.map((style) => (
|
||||
<button
|
||||
key={style.id}
|
||||
onClick={() => setSelectedStyle(style.id)}
|
||||
className={`p-4 rounded-xl border-2 transition-all ${
|
||||
selectedStyle === style.id
|
||||
? 'border-primary bg-primary/5'
|
||||
: 'border-slate-200 bg-white hover:border-slate-300'
|
||||
}`}
|
||||
>
|
||||
<div className="flex justify-center mb-3">
|
||||
<div
|
||||
className={`w-12 h-12 rounded-full flex items-center justify-center transition-all ${style.className}`}
|
||||
>
|
||||
<SelectedIconComponent className="w-6 h-6" />
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm font-medium text-center">{style.name}</p>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 코드 표시 */}
|
||||
<div className="bg-slate-900 rounded-xl p-6 mb-8">
|
||||
<p className="text-slate-400 text-sm mb-2">선택한 스타일 코드:</p>
|
||||
<code className="text-green-400 text-sm break-all">
|
||||
{`className="${styles.find(s => s.id === selectedStyle)?.className}"`}
|
||||
</code>
|
||||
</div>
|
||||
|
||||
{/* 스크롤 테스트용 더미 콘텐츠 */}
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-lg font-semibold">스크롤 테스트</h2>
|
||||
<p className="text-slate-600">아래로 스크롤해서 버튼 동작을 확인하세요.</p>
|
||||
{Array.from({ length: 20 }).map((_, i) => (
|
||||
<div key={i} className="p-6 bg-white rounded-xl border border-slate-200">
|
||||
<h3 className="font-semibold mb-2">더미 콘텐츠 #{i + 1}</h3>
|
||||
<p className="text-slate-600">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 실제 플로팅 버튼 */}
|
||||
<button
|
||||
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
|
||||
className={`fixed bottom-6 right-6 z-50 w-14 h-14 rounded-full flex items-center justify-center transition-all duration-300 hover:scale-110 active:scale-95 ${
|
||||
styles.find(s => s.id === selectedStyle)?.className
|
||||
}`}
|
||||
aria-label="맨 위로"
|
||||
>
|
||||
<SelectedIconComponent className="w-6 h-6" />
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user