화면 하단에서 올라오는 모달 컴포넌트입니다. 추가 정보나 액션 목록을 제공하면서도 현재 컨텍스트를 유지할 때 사용됩니다.
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetPreview = () => {
return (
< BottomSheetRoot >
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
{ /* If you need to omit padding, pass px={0}. */ }
< BottomSheetBody >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetPreview;
Stackflow와 Bottom Sheet를 함께 사용하는 방법에 대해 알아보세요.
npx @seed-design/cli@latest add ui:bottom-sheet pnpm dlx @seed-design/cli@latest add ui:bottom-sheet yarn dlx @seed-design/cli@latest add ui:bottom-sheet bun x @seed-design/cli@latest add ui:bottom-sheet
의존성 설치
npm install @karrotmarket/react-monochrome-icon @seed-design/react yarn add @karrotmarket/react-monochrome-icon @seed-design/react pnpm add @karrotmarket/react-monochrome-icon @seed-design/react bun add @karrotmarket/react-monochrome-icon @seed-design/react 아래 코드를 복사 후 붙여넣고 사용하세요 /**
* @file ui:bottom-sheet
* @requires @seed-design/react@^2.0.0
* @requires @seed-design/css@^2.0.0
**/
"use client" ;
import IconXmarkLine from "@karrotmarket/react-monochrome-icon/IconXmarkLine" ;
import { Icon, BottomSheet as SeedBottomSheet, VisuallyHidden } from "@seed-design/react" ;
import type * as React from "react" ;
import { forwardRef } from "react" ;
export interface BottomSheetRootProps extends SeedBottomSheet . RootProps {}
/**
* @see https://seed-design.io/react/components/action-sheet
*/
export const BottomSheetRoot = ( props : BottomSheetRootProps ) => {
const { children , ... otherProps } = props;
return < SeedBottomSheet.Root { ... otherProps}>{children}</ SeedBottomSheet.Root >;
};
export interface BottomSheetTriggerProps extends SeedBottomSheet . TriggerProps {}
export const BottomSheetTrigger = SeedBottomSheet.Trigger;
export interface BottomSheetContentProps extends Omit < SeedBottomSheet . ContentProps , "title" > {
title ?: React . ReactNode ;
description ?: React . ReactNode ;
layerIndex ?: number ;
/**
* @default true
*/
showCloseButton ?: boolean ;
/**
* @default false
*/
showHandle ?: boolean ;
}
export const BottomSheetContent = forwardRef < HTMLDivElement , BottomSheetContentProps >(
(
{
children,
title,
description,
layerIndex,
showCloseButton = true ,
showHandle = false ,
... otherProps
},
ref,
) => {
if (
! title &&
! otherProps[ "aria-labelledby" ] &&
! otherProps[ "aria-label" ] &&
process.env. NODE_ENV !== "production"
) {
console. warn (
"BottomSheetContent: aria-labelledby or aria-label should be provided if title is not provided." ,
);
}
const shouldRenderHeader = title || description;
return (
< SeedBottomSheet.Positioner style = {{ "--layer-index" : layerIndex } as React . CSSProperties }>
< SeedBottomSheet.Backdrop />
< SeedBottomSheet.Content ref = {ref} { ... otherProps}>
{showHandle && < SeedBottomSheet.Handle />}
{shouldRenderHeader && (
< SeedBottomSheet.Header >
{title ? (
< SeedBottomSheet.Title >{title}</ SeedBottomSheet.Title >
) : (
< VisuallyHidden asChild >
< SeedBottomSheet.Title >{otherProps[ "aria-label" ] || "" }</ SeedBottomSheet.Title >
</ VisuallyHidden >
)}
{description && (
< SeedBottomSheet.Description >{description}</ SeedBottomSheet.Description >
)}
</ SeedBottomSheet.Header >
)}
{children}
{showCloseButton && (
// You may implement your own i18n for dismiss label
< SeedBottomSheet.CloseButton aria-label = "닫기" >
< Icon svg = {< IconXmarkLine />} />
</ SeedBottomSheet.CloseButton >
)}
</ SeedBottomSheet.Content >
</ SeedBottomSheet.Positioner >
);
},
);
export interface BottomSheetBodyProps extends SeedBottomSheet . BodyProps {}
export const BottomSheetBody = SeedBottomSheet.Body;
export interface BottomSheetFooterProps extends SeedBottomSheet . FooterProps {}
export const BottomSheetFooter = SeedBottomSheet.Footer;
/**
* This file is a snippet from SEED Design, helping you get started quickly with @seed-design/* packages.
* You can extend this snippet however you want.
*/
children?React.ReactNode
activeSnapPoint?string | number | null | undefined
setActiveSnapPoint?(( snapPoint : number | string | null ) => void ) | undefined
open?boolean | undefined
onOpenChange?(( open : boolean , details ?: DrawerChangeDetails ) => void ) | undefined
onDrag?(( event : React . PointerEvent < HTMLDivElement >, percentageDragged : number ) => void ) | undefined
onRelease?(( event : React . PointerEvent < HTMLDivElement >, open : boolean ) => void ) | undefined
nested?boolean | undefined
onClose?(() => void ) | undefined
container?HTMLElement | null | undefined
autoFocus?boolean | undefined
title?React.ReactNode
description?React.ReactNode
layerIndex?number | undefined
showHandle?boolean | undefined
asChild?boolean | undefined
asChild?boolean | undefined
paddingX?ResponsiveValue < 0 | (string & {}) | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" > | undefined
height?ResponsiveValue < (string & {}) | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | "full" > | undefined
maxHeight?ResponsiveValue < (string & {}) | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | "full" > | undefined
minHeight?ResponsiveValue < (string & {}) | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | "full" > | undefined
justifyContent?"center" | "flex-start" | "flex-end" | "space-between" | "space-around" | undefined
alignItems?"center" | "flex-start" | "flex-end" | "stretch" | undefined
<BottomSheetTrigger>는 asChild 패턴을 사용해 자식 요소가 BottomSheet를 열 수 있도록 합니다.
<BottomSheetTrigger>는 aria-haspopup="dialog" 속성을 설정하고, BottomSheet의 open 상태에 따라 aria-expanded 속성을 자동으로 설정합니다. 이 속성은 스크린 리더와 같은 보조 기술에 유용합니다.
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetTriggerExample = () => {
return (
< BottomSheetRoot >
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" >
< BottomSheetBody minHeight = "x16" >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetTriggerExample;
Trigger 외의 방식으로 BottomSheet를 열고 닫을 수 있습니다. 이 경우 open prop을 사용하여 BottomSheet의 상태를 제어합니다.
import { useState } from "react" ;
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetControlled = () => {
const [ open , setOpen ] = useState ( false );
const scheduleOpen = () => {
setTimeout (() => {
setOpen ( true );
}, 1000 );
};
return (
<>
< ActionButton variant = "neutralSolid" onClick = {scheduleOpen}>
1초 후 열기
</ ActionButton >
< BottomSheetRoot open = {open} onOpenChange = {setOpen}>
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
{ /* If you need to omit padding, pass px={0}. */ }
< BottomSheetBody minHeight = "x16" >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</>
);
};
export default BottomSheetControlled;
onOpenChange 두 번째 인자로 details가 제공됩니다.
열릴 때 (open: true)
"trigger": BottomSheetTrigger (BottomSheet.Trigger)로 열림
닫힐 때 (open: false)
"closeButton": BottomSheet.CloseButton으로 닫힘
"escapeKeyDown": ESC 키 사용
"interactOutside": 외부 영역 클릭
"drag": 드래그로 닫힘
"handleClickOnLastSnapPoint": 마지막 스냅 포인트에서 핸들 클릭으로 닫힘
import { HStack, Text, VStack } from "@seed-design/react" ;
import { useState } from "react" ;
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const snapPoints = [ "200px" , "400px" , 1 ];
export default function BottomSheetOnOpenChangeReason () {
const [ open , setOpen ] = useState ( false );
const [ snap , setSnap ] = useState < number | string | null >(snapPoints[ 0 ]);
const [ openReason , setOpenReason ] = useState < string | null >( null );
const [ closeReason , setCloseReason ] = useState < string | null >( null );
return (
< VStack gap = "x4" align = "center" >
< BottomSheetRoot
open = {open}
onOpenChange = {( open , details ) => {
setOpen (open);
(open ? setOpenReason : setCloseReason)(details?.reason ?? null );
}}
snapPoints = {snapPoints}
activeSnapPoint = {snap}
setActiveSnapPoint = {setSnap}
>
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >열기</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "알림" showHandle style = {{ height: "100%" , maxHeight: "97%" }}>
< BottomSheetBody minHeight = "x16" >
< Text textStyle = "t4Medium" color = "fg.neutralMuted" >
ESC 키를 누르거나, 외부 영역을 클릭하거나, 아래로 스와이프하거나, 핸들을 탭하여 snap
point를 순환해보세요.
</ Text >
</ BottomSheetBody >
</ BottomSheetContent >
</ BottomSheetRoot >
< HStack gap = "x4" >
< Text fontSize = "t3" color = "fg.neutralMuted" >
마지막 열림 이유: {openReason ?? "-" }
</ Text >
< Text fontSize = "t3" color = "fg.neutralMuted" >
마지막 닫힘 이유: {closeReason ?? "-" }
</ Text >
</ HStack >
</ VStack >
);
}
<BottomSheetRoot>에 headerAlign prop을 설정하여 title과 description의 정렬을 설정할 수 있습니다.
import { HStack } from "@seed-design/react" ;
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetHeaderAlign = () => {
return (
< HStack gap = "x4" >
< BottomSheetRoot headerAlign = "left" >
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Left (기본값)</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
< BottomSheetRoot headerAlign = "center" >
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Center</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ HStack >
);
};
export default BottomSheetHeaderAlign;
<BottomSheetBody>에 maxHeight prop을 전달하여 BottomSheet의 최대 높이를 설정할 수 있습니다.
import { Box, VStack } from "@seed-design/react" ;
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetMaxHeight = () => {
return (
< BottomSheetRoot >
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
{ /* If you need to omit padding, pass px={0}. */ }
< BottomSheetBody >
< VStack maxHeight = "300px" overflowY = "auto" >
< VStack justifyContent = "center" alignItems = "center" gap = "x4" height = "100%" >
< Box width = "100%" height = "100px" bg = "bg.layerBasement" />
< Box width = "100%" height = "100px" bg = "bg.layerBasement" />
< Box width = "100%" height = "100px" bg = "bg.layerBasement" />
< Box width = "100%" height = "100px" bg = "bg.layerBasement" />
</ VStack >
</ VStack >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetMaxHeight;
snapPoints prop을 사용하여 BottomSheet의 커스텀 스냅 포인트를 설정할 수 있습니다.
import { useState } from "react" ;
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const snapPoints = [ "300px" , "500px" , 1 ];
const BottomSheetSnapPoints = () => {
const [ snap , setSnap ] = useState < number | string | null >(snapPoints[ 0 ]);
return (
< BottomSheetRoot snapPoints = {snapPoints} activeSnapPoint = {snap} setActiveSnapPoint = {setSnap}>
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent
title = "제목"
description = "설명을 작성할 수 있어요"
/**
* snap points를 사용할 때는 handle을 표시해야 합니다.
*/
showHandle
/**
* 높이를 100%로 설정해야 snap points가 제대로 작동합니다.
*/
style = {{ height: "100%" , maxHeight: "97%" }}
>
< BottomSheetBody >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetSnapPoints;
<BottomSheetRoot>에 fadeFromIndex prop을 전달하여 뒷 배경이 어두워지는 시작 인덱스를 설정할 수 있습니다.
import { useState } from "react" ;
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const snapPoints = [ "300px" , "500px" , 1 ];
const BottomSheetFadeFromIndex = () => {
const [ snap , setSnap ] = useState < number | string | null >(snapPoints[ 0 ]);
return (
< BottomSheetRoot
fadeFromIndex = { 0 }
snapPoints = {snapPoints}
activeSnapPoint = {snap}
setActiveSnapPoint = {setSnap}
>
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent
title = "제목"
description = "설명을 작성할 수 있어요"
/**
* snap points를 사용할 때는 handle을 표시해야 합니다.
*/
showHandle
/**
* 높이를 100%로 설정해야 snap points가 제대로 작동합니다.
*/
style = {{ height: "100%" , maxHeight: "97%" }}
>
< BottomSheetBody >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetFadeFromIndex;
<BottomSheetContent>에 showHandle prop을 전달하여 Handle을 표시할 수 있습니다.
기본 값은 false입니다.
import { useState } from "react" ;
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetShowHandle = () => {
const [ isSheetOpen , setIsSheetOpen ] = useState ( false );
return (
< BottomSheetRoot open = {isSheetOpen} onOpenChange = {setIsSheetOpen}>
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" showHandle >
{ /* If you need to omit padding, pass px={0}. */ }
< BottomSheetBody minHeight = "x16" >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" onClick = {() => setIsSheetOpen ( false )}>
닫기
</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetShowHandle;
<BottomSheetContent>에 showCloseButton prop을 전달하여 닫기 버튼을 표시할 수 있습니다.
기본 값은 true입니다.
showCloseButton을 false로 설정하면 닫기 버튼이 표시되지 않습니다.
이 경우 유저가 BottomSheet를 닫을 수 있는 방법을 제공해야 합니다.
import { useState } from "react" ;
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetShowCloseButton = () => {
const [ isSheetOpen , setIsSheetOpen ] = useState ( false );
return (
< BottomSheetRoot open = {isSheetOpen} onOpenChange = {setIsSheetOpen}>
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent
title = "제목"
description = "설명을 작성할 수 있어요"
showCloseButton = { false }
>
{ /* If you need to omit padding, pass px={0}. */ }
< BottomSheetBody minHeight = "x16" >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" onClick = {() => setIsSheetOpen ( false )}>
닫기
</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetShowCloseButton;
dismissible prop을 false로 설정하면 closeOnEscape, closeOnInteractOutside, draggable 기능이 비활성화됩니다.
의도적으로 BottomSheet를 닫을 수 없게 하고 싶을 때 사용합니다. 이외에는 유저가 BottomSheet를 닫을 수 있는 방법을 제공해야 합니다.
import { useState } from "react" ;
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetDismissible = () => {
const [ open , setOpen ] = useState ( false );
return (
< BottomSheetRoot open = {open} onOpenChange = {setOpen} dismissible = { false }>
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
{ /* If you need to omit padding, pass px={0}. */ }
< BottomSheetBody >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" onClick = {() => setOpen ( false )}>
닫기
</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetDismissible;
<BottomSheetBody>에 Scroll Fog 를 사용하여 스크롤 힌트 효과를 적용할 수 있습니다.
ScrollFog는 항상 효과를 표시하므로, 충분한 padding을 제공해야 합니다.
권장 padding인 하단 80px, 상단 20px을 유지해야 합니다.
import { Box, ScrollFog, VStack } from "@seed-design/react" ;
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetMaxHeight = () => {
return (
< BottomSheetRoot >
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
{ /* If you need to omit padding, pass px={0}. */ }
< BottomSheetBody >
< VStack maxHeight = "300px" overflowY = "auto" >
< ScrollFog placement = {[ "top" , "bottom" ]}>
< VStack
justifyContent = "center"
alignItems = "center"
gap = "x4"
height = "100%"
pb = "80px"
pt = "20px"
>
< Box width = "100%" height = "100px" bg = "bg.layerBasement" />
< Box width = "100%" height = "100px" bg = "bg.layerBasement" />
< Box width = "100%" height = "100px" bg = "bg.layerBasement" />
< Box width = "100%" height = "100px" bg = "bg.layerBasement" />
</ VStack >
</ ScrollFog >
</ VStack >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetMaxHeight;
<BottomSheetContent>에 style prop을 전달하여 아래 여백을 주기 위해 사용합니다.
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetBottomInset = () => {
return (
< BottomSheetRoot >
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent
title = "제목"
description = "설명을 작성할 수 있어요"
// 모바일 브라우저에서 아래 여백을 주기 위해 사용
style = {{ paddingBottom: "var(--seed-safe-area-bottom)" }}
>
{ /* If you need to omit padding, pass px={0}. */ }
< BottomSheetBody minHeight = "x16" >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetBottomInset;
<BottomSheetRoot>에 handleOnly prop을 제공하는 경우 쓸어서(swipe) Bottom Sheet를 움직일 수 있는 영역이 핸들 부분으로 제한됩니다.
이 옵션은 <BottomSheetContent showHandle={true}>와 함께 사용할 때만 작동합니다.
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetHandleOnly = () => {
return (
< BottomSheetRoot handleOnly >
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent showHandle title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetHandleOnly;
skipAnimation prop을 사용하여 BottomSheet의 enter/exit 애니메이션을 건너뛸 수 있습니다.
import { ActionButton } from "seed-design/ui/action-button" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "seed-design/ui/bottom-sheet" ;
const BottomSheetSkipAnimation = () => {
return (
< BottomSheetRoot skipAnimation >
< BottomSheetTrigger asChild >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody >Content</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
};
export default BottomSheetSkipAnimation;