import * as React from "react"; import { Button, Icon, Separator } from "@sparkle/components"; import { Sheet, SheetClose, SheetContainer, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger, } from "@sparkle/components/Sheet"; import { ChevronLeftIcon, ChevronRightIcon } from "@sparkle/icons/app"; import { cn } from "@sparkle/lib/utils"; interface MultiPageSheetPage { id: string; title: string; description?: string; icon?: React.ComponentType; content: React.ReactNode; fixedContent?: React.ReactNode; footerContent?: React.ReactNode; /** * Remove the default ScrollArea in the SheetContainer. * To be used if you want to manage the scroll yourself */ noScroll?: boolean; } interface MultiPageSheetProps { pages: MultiPageSheetPage[]; currentPageId: string; onPageChange: (pageId: string) => void; size?: React.ComponentProps["size"]; side?: React.ComponentProps["side"]; trapFocusScope?: boolean; showNavigation?: boolean; showHeaderNavigation?: boolean; onSave?: (e: React.MouseEvent) => void; className?: string; disableNext?: boolean; disableSave?: boolean; leftButton?: React.ComponentProps; centerButton?: React.ComponentProps; rightButton?: React.ComponentProps; addFooterSeparator?: boolean; } const MultiPageSheetRoot = Sheet; const MultiPageSheetTrigger = SheetTrigger; const MultiPageSheetClose = SheetClose; interface MultiPageSheetFooterProps extends React.HTMLAttributes { addTopSeparator: boolean; leftButton?: React.ComponentProps; centerButton?: React.ComponentProps; rightButton?: React.ComponentProps; } const MultiPageSheetFooter = ({ className, addTopSeparator, children, leftButton, centerButton, rightButton, ...props }: MultiPageSheetFooterProps) => { const content = (
{children && ( <> {children} )}
{leftButton &&
{centerButton &&
); return addTopSeparator ? ( <> {content} ) : ( <>{content} ); }; MultiPageSheetFooter.displayName = "MultiPageSheetFooter"; interface MultiPageSheetContentProps extends MultiPageSheetProps { children?: never; } const MultiPageSheetContent = React.forwardRef< React.ElementRef, MultiPageSheetContentProps >( ( { pages, currentPageId, onPageChange, size = "md", side = "right", trapFocusScope, showNavigation = true, showHeaderNavigation = true, className, disableNext = false, addFooterSeparator = false, leftButton, centerButton, rightButton, ...props }, ref ) => { const currentPageIndex = pages.findIndex( (page) => page.id === currentPageId ); const currentPage = pages[currentPageIndex]; const handlePrevious = ( e: React.MouseEvent ) => { e.preventDefault(); if (currentPageIndex > 0) { onPageChange(pages[currentPageIndex - 1].id); } }; const handleNext = (e: React.MouseEvent) => { e.preventDefault(); if (currentPageIndex < pages.length - 1) { onPageChange(pages[currentPageIndex + 1].id); } }; if (!currentPage) { console.warn(`Page with id "${currentPageId}" not found`); return null; } const hasPrevious = currentPageIndex > 0; const hasNext = currentPageIndex < pages.length - 1; const nextButtonDisabled = disableNext || !hasNext; return (
{showNavigation && showHeaderNavigation && (
)}
{currentPage.icon && ( )}
{currentPage.title} {currentPage.description && ( {currentPage.description} )}
{showNavigation && pages.length > 1 && (
{currentPageIndex + 1} / {pages.length}
)}
{currentPage.fixedContent && ( <>
{currentPage.fixedContent}
)} {currentPage.content}
{currentPage.footerContent}
); } ); MultiPageSheetContent.displayName = "MultiPageSheetContent"; export { MultiPageSheetRoot as MultiPageSheet, MultiPageSheetClose, MultiPageSheetContent, MultiPageSheetFooter, type MultiPageSheetFooterProps, type MultiPageSheetPage, type MultiPageSheetProps, MultiPageSheetTrigger, };