diff --git a/src/app/preview/button/page.tsx b/src/app/preview/button/page.tsx
index 84f2e95..222cba6 100644
--- a/src/app/preview/button/page.tsx
+++ b/src/app/preview/button/page.tsx
@@ -1,23 +1,27 @@
'use client';
import { Button } from '@/components/ui/Button';
+import { FloatingButton } from '@/components/ui/FloatingButton';
import {
+ ArrowUp,
Download,
Heart,
LogOut,
MessageCircle,
+ Plus,
Settings,
Share2,
Star,
} from 'lucide-react';
-import React from 'react';
+import React, { useCallback, useState } from 'react';
export default function ButtonExamples() {
const handleClick = () => {
alert('hiii');
};
+
return (
-
+
{/* Default buttons with different variants */}
기본 버튼 스타일
@@ -36,7 +40,6 @@ export default function ButtonExamples() {
-
{/* Small buttons row */}
작은 크기 버튼
@@ -52,7 +55,6 @@ export default function ButtonExamples() {
-
{/* Disabled states */}
비활성화 상태
@@ -71,6 +73,40 @@ export default function ButtonExamples() {
+ {/* 찜 버튼 */}
+
+
찜 버튼
+
+
+
+
+ {/* 플로팅 버튼 섹션 */}
+ 플로팅 버튼
+ } className="bottom-24" />
+ }>
+ 모임 만들기
+
+ }
+ className="right-6 top-1/2 -translate-y-1/2" // 중간위치
+ />
);
}
+
+function LikeButton() {
+ const [isLiked, setIsLiked] = useState(false);
+
+ const handleLikeClick = useCallback(() => {
+ setIsLiked((prev) => !prev);
+ }, []);
+
+ return (
+ }
+ >
+ );
+}
diff --git a/src/components/ui/Button.tsx b/src/components/ui/Button.tsx
index 53c740e..1a1c88b 100644
--- a/src/components/ui/Button.tsx
+++ b/src/components/ui/Button.tsx
@@ -10,7 +10,6 @@ const buttonVariants = cva(
variant: {
solid: [
'bg-main',
- 'typo-button1',
'text-white',
'hover:opacity-90',
'disabled:bg-disable disabled:text-disable_text',
@@ -18,27 +17,24 @@ const buttonVariants = cva(
default: [
'bg-default',
'text-main',
- 'typo-button1',
'hover:opacity-90',
'disabled:bg-disable disabled:text-disable_text',
],
outline: [
'border border-main',
'text-main',
- 'typo-button1',
'hover:bg-default',
'disabled:border-disable disabled:text-disable_text',
],
text: [
'text-main',
- 'typo-button1',
'hover:text-opacity-80',
'disabled:text-disable_text',
],
},
size: {
- default: 'h-[46px] w-[332px]',
- sm: 'h-10 w-[120px]',
+ default: ['typo-button1 h-[46px] w-[332px]'],
+ sm: ['typo-button2 h-10 w-[120px]'],
},
},
defaultVariants: {
diff --git a/src/components/ui/FloatingButton.tsx b/src/components/ui/FloatingButton.tsx
new file mode 100644
index 0000000..bf3230d
--- /dev/null
+++ b/src/components/ui/FloatingButton.tsx
@@ -0,0 +1,63 @@
+import { cn } from '@/util/cn';
+import { Slot } from '@radix-ui/react-slot';
+import { type VariantProps, cva } from 'class-variance-authority';
+import * as React from 'react';
+
+const floatingButtonVariants = cva(
+ 'fixed bottom-6 right-6 inline-flex items-center justify-center gap-2 rounded-full bg-main text-white transition-colors hover:opacity-90 focus-visible:outline-none disabled:pointer-events-none disabled:bg-disable disabled:text-disable_text [&_svg]:pointer-events-none [&_svg]:shrink-0',
+ {
+ variants: {
+ variant: {
+ icon: ['h-14 w-14', '[&_svg]:size-6'],
+ text: ['typo-head3', 'p-4', '[&_svg]:size-6'],
+ },
+ },
+ defaultVariants: {
+ variant: 'icon',
+ },
+ },
+);
+
+export interface FloatingButtonProps
+ extends React.ButtonHTMLAttributes,
+ VariantProps {
+ asChild?: boolean;
+ icon?: React.ReactNode;
+}
+
+/**
+ * Floating Button 컴포넌트입니다.(기본 fixed 우측하단-6)
+ * @example
+ * // 아이콘만 있는 경우
+ * } />
+ *
+ * // 텍스트와 함께 사용
+ * } variant="text">모임 만들기
+ *
+ * @param {object} props
+ * @param {string} [props.className] - Tailwind CSS 클래스를 통한 커스텀 스타일
+ * @param {'icon' | 'text'} [props.variant='icon'] - 버튼의 스타일 variant (아이콘만 있는 경우 / 텍스트가 있는 경우)
+ * @param {React.ReactNode} [props.icon] - 버튼에 표시될 아이콘
+ * @param {boolean} [props.disabled] - 버튼 비활성화 상태
+ * @param {() => void} [props.onClick] - 클릭 이벤트 핸들러
+ * @param {boolean} [props.asChild=false] - true일 경우 다른 컴포넌트로 래핑 가능
+ */
+const FloatingButton = React.forwardRef(
+ ({ className, variant, icon, children, asChild = false, ...props }, ref) => {
+ const Comp = asChild ? Slot : 'button';
+ return (
+
+ {icon}
+ {children}
+
+ );
+ },
+);
+
+FloatingButton.displayName = 'FloatingButton';
+
+export { FloatingButton, floatingButtonVariants };