feat: FAB 플로팅 액션 버튼 컴포넌트
This commit is contained in:
50
src/components/FAB.css
Normal file
50
src/components/FAB.css
Normal file
@@ -0,0 +1,50 @@
|
||||
/* FAB — Floating Action Button (mobile-only) */
|
||||
|
||||
.fab {
|
||||
display: none;
|
||||
position: fixed;
|
||||
right: 20px;
|
||||
bottom: calc(var(--bottom-nav-h) + var(--safe-area-bottom) + 16px);
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 50%;
|
||||
background: var(--gradient-accent);
|
||||
border: none;
|
||||
color: #000;
|
||||
font-size: 24px;
|
||||
z-index: 250;
|
||||
box-shadow: 0 0 0 1px var(--neon-cyan-dim), 0 4px 16px rgba(0, 255, 255, 0.25);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
transition: transform 0.15s var(--ease-out), box-shadow 0.15s var(--ease-out);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.fab {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.fab:active {
|
||||
transform: scale(0.92);
|
||||
}
|
||||
|
||||
.fab__icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Variant: positioned above a music mini-player */
|
||||
.fab--above-player {
|
||||
bottom: calc(var(--bottom-nav-h) + var(--safe-area-bottom) + 16px + 56px);
|
||||
}
|
||||
|
||||
/* Reduced motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.fab {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
37
src/components/FAB.jsx
Normal file
37
src/components/FAB.jsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { useIsMobile } from '../hooks/useIsMobile';
|
||||
import './FAB.css';
|
||||
|
||||
const PlusIcon = () => (
|
||||
<svg
|
||||
className="fab__icon"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M12 5v14M5 12h14"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export default function FAB({ onClick, icon, label = '액션', className = '' }) {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
if (!isMobile) return null;
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={`fab ${className}`}
|
||||
onClick={onClick}
|
||||
aria-label={label}
|
||||
>
|
||||
{icon ?? <PlusIcon />}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user