From 5036cf2908792cef45f06256e71f10920f647f49 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Wed, 28 May 2025 19:03:21 +0000 Subject: (김준회) 기술영업 조선 RFQ (SHI/벤더) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ui/back-button.tsx | 112 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 components/ui/back-button.tsx (limited to 'components/ui/back-button.tsx') diff --git a/components/ui/back-button.tsx b/components/ui/back-button.tsx new file mode 100644 index 00000000..364c0b96 --- /dev/null +++ b/components/ui/back-button.tsx @@ -0,0 +1,112 @@ +"use client" + +import * as React from "react" +import { useRouter, usePathname } from "next/navigation" +import { ArrowLeft } from "lucide-react" +import { Button } from "@/components/ui/button" +import { cn } from "@/lib/utils" + +/** + * BackButton 컴포넌트 - 세그먼트를 동적으로 제거하여 상위 경로로 이동 + * + * 사용 예시: + * + * // 기본 사용 (1개 세그먼트 제거) + * 목록으로 + * + * // 2개 세그먼트 제거 (/a/b/c/d -> /a/b) + * 상위 목록으로 + * + * // 커스텀 경로로 이동 + * 대시보드로 + * + * // 아이콘 없이 사용 + * 돌아가기 + * + * // 커스텀 스타일링 + * + * 이전 페이지 + * + */ + +interface BackButtonProps extends React.ComponentPropsWithoutRef { + /** + * 제거할 세그먼트 개수 (기본값: 1) + * 예: segmentsToRemove=1이면 /a/b/c -> /a/b + * segmentsToRemove=2이면 /a/b/c -> /a + */ + segmentsToRemove?: number + + /** + * 버튼에 표시할 텍스트 (기본값: "목록으로") + */ + children?: React.ReactNode + + /** + * 아이콘을 표시할지 여부 (기본값: true) + */ + showIcon?: boolean + + /** + * 커스텀 경로를 지정할 경우 (segmentsToRemove 대신 사용) + */ + customPath?: string +} + +export const BackButton = React.forwardRef< + React.ElementRef, + BackButtonProps +>(({ + segmentsToRemove = 1, + children = "Go Back", + showIcon = true, + customPath, + className, + onClick, + ...props +}, ref) => { + const router = useRouter() + const pathname = usePathname() + + const handleClick = React.useCallback((event: React.MouseEvent) => { + // 커스텀 onClick이 있으면 먼저 실행 + if (onClick) { + onClick(event) + // preventDefault가 호출되었으면 기본 동작 중단 + if (event.defaultPrevented) { + return + } + } + + let targetPath: string + + if (customPath) { + targetPath = customPath + } else { + // 현재 경로에서 세그먼트 제거 + const segments = pathname.split('/').filter(Boolean) + const newSegments = segments.slice(0, -segmentsToRemove) + targetPath = newSegments.length > 0 ? `/${newSegments.join('/')}` : '/' + } + + router.push(targetPath) + }, [router, pathname, segmentsToRemove, customPath, onClick]) + + return ( + + ) +}) + +BackButton.displayName = "BackButton" \ No newline at end of file -- cgit v1.2.3