화면 하단에서 올라오는 시트 컴포넌트로, 드래그·snap·dismiss 상호작용을 제공합니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton } from "@seed-design/lynx-react" ;
export default function Example () {
return (
< BottomSheetRoot >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
}
npx @seed-design/cli add ui:bottom-sheet pnpm dlx @seed-design/cli add ui:bottom-sheet yarn dlx @seed-design/cli add ui:bottom-sheet bun x @seed-design/cli add ui:bottom-sheet
의존성 설치
npm install @karrotmarket/lynx-monochrome-icon @seed-design/lynx-react yarn add @karrotmarket/lynx-monochrome-icon @seed-design/lynx-react pnpm add @karrotmarket/lynx-monochrome-icon @seed-design/lynx-react bun add @karrotmarket/lynx-monochrome-icon @seed-design/lynx-react 아래 코드를 복사 후 붙여넣고 사용하세요 /**
* @file ui:bottom-sheet
* @requires @seed-design/lynx-react@^1.0.0
* @requires @seed-design/lynx-css@^1.0.0
* @requires @karrotmarket/lynx-monochrome-icon@>=1.20.0 <2.0.0
**/
import IconXmarkLine from "@karrotmarket/lynx-monochrome-icon/IconXmarkLine" ;
import {
Icon,
BottomSheet as SeedBottomSheet,
type BottomSheetBodyProps as SeedBottomSheetBodyProps,
type BottomSheetContentProps as SeedBottomSheetContentProps,
type BottomSheetFooterProps as SeedBottomSheetFooterProps,
type BottomSheetRootProps as SeedBottomSheetRootProps,
type BottomSheetRootRef as SeedBottomSheetRootRef,
type BottomSheetTriggerProps as SeedBottomSheetTriggerProps,
} from "@seed-design/lynx-react" ;
import {
forwardRef,
type ForwardRefExoticComponent,
type PropsWithoutRef,
type ReactNode,
type RefAttributes,
} from "@lynx-js/react" ;
export interface BottomSheetRootProps extends SeedBottomSheetRootProps {}
export type BottomSheetRootRef = SeedBottomSheetRootRef ;
/**
* @see https://seed-design.io/lynx/components/bottom-sheet
*/
export const BottomSheetRoot : ForwardRefExoticComponent <
PropsWithoutRef < BottomSheetRootProps > & RefAttributes < SeedBottomSheetRootRef >
> = forwardRef < SeedBottomSheetRootRef , BottomSheetRootProps >(( props , ref ) => {
return < SeedBottomSheet.Root ref = {ref} { ... props} />;
});
BottomSheetRoot.displayName = "BottomSheetRoot" ;
export interface BottomSheetTriggerProps extends SeedBottomSheetTriggerProps {}
export const BottomSheetTrigger = SeedBottomSheet.Trigger;
export interface BottomSheetContentProps extends Omit < SeedBottomSheetContentProps , "title" > {
title ?: ReactNode ;
description ?: ReactNode ;
container ?: SeedBottomSheet . PositionerProps [ "container" ];
overlayLevel ?: SeedBottomSheet . PositionerProps [ "overlayLevel" ];
/**
* @default true
*/
showCloseButton ?: boolean ;
/**
* @default false
*/
showHandle ?: boolean ;
}
/**
* Positioner / Backdrop / Handle / Header / Title / Description / CloseButton을 내부에서
* 조립해 사용자가 단일 컴포넌트로 콘텐츠를 구성할 수 있도록 한다.
*
* 웹 BottomSheetContent와 달리 아래는 Lynx에서 미지원:
* - `accessibility-label` 기반 VisuallyHidden 제목 fallback (VisuallyHidden 미구현)
*/
export const BottomSheetContent = ( props : BottomSheetContentProps ) => {
const {
children ,
title ,
description ,
container ,
overlayLevel ,
showCloseButton = true ,
showHandle = false ,
... otherProps
} = props;
const shouldRenderHeader = title || description;
return (
< SeedBottomSheet.Positioner container = {container} overlayLevel = {overlayLevel}>
< SeedBottomSheet.Backdrop />
< SeedBottomSheet.Content { ... otherProps}>
{showHandle && < SeedBottomSheet.Handle />}
{shouldRenderHeader && (
< SeedBottomSheet.Header >
{title && < SeedBottomSheet.Title >{title}</ SeedBottomSheet.Title >}
{description && (
< SeedBottomSheet.Description >{description}</ SeedBottomSheet.Description >
)}
</ SeedBottomSheet.Header >
)}
{children}
{showCloseButton && (
// You may implement your own i18n for dismiss label
< SeedBottomSheet.CloseButton accessibility-label = "닫기" >
< Icon icon = {< IconXmarkLine />} />
</ SeedBottomSheet.CloseButton >
)}
</ SeedBottomSheet.Content >
</ SeedBottomSheet.Positioner >
);
};
export interface BottomSheetBodyProps extends SeedBottomSheetBodyProps {}
export const BottomSheetBody : ( props : BottomSheetBodyProps ) => ReactNode = SeedBottomSheet.Body;
export interface BottomSheetFooterProps extends SeedBottomSheetFooterProps {}
export const BottomSheetFooter : ( props : BottomSheetFooterProps ) => ReactNode =
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.
*/
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
export function App () {
return (
< BottomSheetRoot snapPoints = {[ "fit" , "80%" ]}>
< BottomSheetTrigger >
< text >시트 열기</ text >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "부가 설명" showHandle >
< BottomSheetBody >
< text >본문 콘텐츠</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< text >하단 액션 영역</ text >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
}
BottomSheetTrigger는 Content 밖에 두세요.
container를 지정하지 않으면 Bottom Sheet는 Lynx view 안에 렌더링됩니다. container="window"처럼 native container 이름을 지정하면 host 화면까지 덮는 native overlay에 렌더링됩니다. overlayLevel은 overlay의 표시 순서를 정합니다. 이 기능을 사용할 때는 앱의 Lynx Engine이 <overlay>를 지원해야 합니다.
BottomSheetRoot에 ref를 전달하면 open, close, snapTo, expand, collapse 메서드를 호출할 수 있습니다. 이 메서드로 바꾼 열림 상태는 onOpenChange로 알리지 않습니다. open을 제어하는 경우에는 메서드 대신 open 값을 바꾸세요.
import { useRef } from "@lynx-js/react" ;
import { BottomSheetRoot, type BottomSheetRootRef } from "@/components/ui/bottom-sheet" ;
export function App () {
const ref = useRef < BottomSheetRootRef >( null );
return (
< BottomSheetRoot ref = {ref} snapPoints = {[ "fit" , "80%" ]}>
{ /* ... */ }
</ BottomSheetRoot >
);
}
고유 prop이 없습니다. className, style, children, bindtap을 받습니다.
title?ReactNode
description?ReactNode
container?(string & {}) | "spark" | "bullet" | "bulletPopup" | undefined
overlayLevel?2 | 1 | 3 | 4 | undefined
showHandle?boolean | undefined
snapAnimation?SheetTransition | undefined
enterAnimation?SheetTransition | undefined
exitAnimation?SheetTransition | undefined
innerClassName?string | undefined
innerStyle?CSSProperties | undefined
고유 prop이 없습니다. className, style, children을 받습니다.
고유 prop이 없습니다. className, style, children을 받습니다.
<BottomSheetTrigger>를 탭하면 Bottom Sheet가 열립니다. Lynx는 asChild를 지원하지 않습니다. Trigger는 자식 요소를 감싸는 <view>를 렌더링합니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton } from "@seed-design/lynx-react" ;
export default function Example () {
return (
< BottomSheetRoot >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" >
< BottomSheetBody >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
}
Trigger 외의 방식으로 Bottom Sheet를 열고 닫으려면 open과 onOpenChange로 상태를 제어합니다. 다음 예제는 버튼을 탭한 뒤 1초 후 Bottom Sheet를 엽니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
} from "@/components/ui/bottom-sheet" ;
import { useState } from "@lynx-js/react" ;
import { ActionButton, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
const [ open , setOpen ] = useState ( false );
function scheduleOpen () {
"background only" ;
setTimeout (() => {
setOpen ( true );
}, 1000 );
}
return (
< VStack gap = "x3" style = {{ width: "100%" }}>
< ActionButton variant = "neutralSolid" bindtap = {scheduleOpen}>
1초 후 열기
</ ActionButton >
< BottomSheetRoot open = {open} onOpenChange = {setOpen}>
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ VStack >
);
}
onOpenChange의 두 번째 인자는 { reason }입니다. Trigger로 열면 "trigger", 닫기 버튼으로 닫으면 "closeButton", 배경을 탭해 닫으면 "interactOutside", 시트를 끌어 닫으면 "drag"입니다. 닫히는 중에 시트를 다시 끌어 올리면 open이 true인 "drag"가 전달됩니다. Root ref의 메서드나 open prop으로 바꾼 상태에는 호출되지 않습니다. React 버전의 escapeKeyDown처럼 Lynx에 해당 입력이 없는 reason은 제공하지 않습니다.
<BottomSheetRoot>의 headerAlign으로 title과 description을 왼쪽 또는 가운데에 정렬할 수 있습니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton, HStack } from "@seed-design/lynx-react" ;
export default function Example () {
return (
< HStack gap = "x4" >
< BottomSheetRoot headerAlign = "left" >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Left (기본값)</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
< BottomSheetRoot headerAlign = "center" >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Center</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ HStack >
);
}
내용에 맞춰 높이가 정해지는 시트는 화면 높이의 90%를 넘지 않고, 위쪽 inset이 그보다 크면 inset 아래까지로 제한됩니다. 제한에 닿으면 BottomSheetBody가 스크롤됩니다. Body가 스크롤된 상태에서 시작한 제스처는 Body만 움직이고, Body가 맨 위에 있을 때 아래로 끌어야 시트가 움직입니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton } from "@seed-design/lynx-react" ;
export default function Example () {
return (
< BottomSheetRoot >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent
title = "긴 내용"
description = "화면 높이의 90%에서 멈추고 Body가 스크롤됩니다"
>
< BottomSheetBody >
{Array. from ({ length: 40 }, ( _ , index ) => index + 1 ). map (( line ) => (
< text key = {line} className = "bottom-sheet-preview__body-text" >
{line}. 내용이 길면 Body가 스크롤됩니다.
</ text >
))}
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
}
BottomSheetBody는 내용이 넘치면 세로로 스크롤합니다. 스크롤 영역을 최대 300px로 제한하려면 Body에 maxHeight를 지정하세요.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
return (
< BottomSheetRoot >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody style = {{ maxHeight: "300px" }}>
< VStack className = "bottom-sheet-preview__blocks" gap = "x4" >
< view className = "bottom-sheet-preview__block" />
< view className = "bottom-sheet-preview__block" />
< view className = "bottom-sheet-preview__block" />
< view className = "bottom-sheet-preview__block" />
</ VStack >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
}
snapPoints에는 픽셀 숫자, 화면 높이 기준 백분율, 콘텐츠 크기에 맞추는 "fit"을 사용할 수 있습니다. 배열 순서가 snap index가 되며, initialSnap으로 처음 열릴 높이를 정합니다.
onSnapChange에서는 현재 index와 픽셀로 계산된 높이를 받을 수 있습니다. ref의 snapTo 메서드를 사용하면 원하는 높이로 이동할 수 있습니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
type BottomSheetRootRef,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { useRef, useState } from "@lynx-js/react" ;
import { ActionButton, HStack, VStack } from "@seed-design/lynx-react" ;
const snapPoints = [ "45%" , "80%" ];
export default function Example () {
const sheetRef = useRef < BottomSheetRootRef >( null );
const [ snapIndex , setSnapIndex ] = useState ( 0 );
function handleSnapToFirst () {
"background only" ;
sheetRef.current?. snapTo ( 0 );
}
function handleSnapToSecond () {
"background only" ;
sheetRef.current?. snapTo ( 1 );
}
function handleClose () {
"background only" ;
sheetRef.current?. close ();
}
return (
< VStack gap = "x3" style = {{ width: "100%" }}>
< text className = "bottom-sheet-preview__status" >snap index: { JSON . stringify (snapIndex)}</ text >
< BottomSheetRoot
ref = {sheetRef}
snapPoints = {snapPoints}
initialSnap = { 0 }
onSnapChange = {( index ) => setSnapIndex (index)}
>
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Snap Points 열기</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent
title = "Snap Points"
description = "핸들을 드래그하거나 버튼을 탭해 높이를 바꿔 보세요."
showHandle
>
< BottomSheetBody className = "bottom-sheet-preview__snap-body" >
< text className = "bottom-sheet-preview__body-text" >
현재 snap index: { JSON . stringify (snapIndex)}
</ text >
< HStack gap = "x2" >
< ActionButton flexGrow = { 1 } variant = "neutralWeak" bindtap = {handleSnapToFirst}>
45%
</ ActionButton >
< ActionButton flexGrow = { 1 } variant = "neutralWeak" bindtap = {handleSnapToSecond}>
80%
</ ActionButton >
</ HStack >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" bindtap = {handleClose}>
닫기
</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ VStack >
);
}
Lynx는 fadeFromIndex를 지원하지 않습니다. snap index에 따른 Backdrop 투명도 변경도 지원하지 않습니다.
<BottomSheetContent>에 showHandle을 전달하면 Handle을 표시합니다. 기본값은 false입니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { useState } from "@lynx-js/react" ;
import { ActionButton } from "@seed-design/lynx-react" ;
export default function Example () {
const [ open , setOpen ] = useState ( false );
function handleClose () {
"background only" ;
setOpen ( false );
}
return (
< BottomSheetRoot open = {open} onOpenChange = {setOpen}>
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" showHandle >
< BottomSheetBody >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" bindtap = {handleClose}>
닫기
</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
}
<BottomSheetContent>에 showCloseButton prop을 전달하여 닫기 버튼을 표시할 수 있습니다.
기본 값은 true입니다.
showCloseButton을 false로 설정하면 닫기 버튼이 표시되지 않습니다.
이 경우 유저가 BottomSheet를 닫을 수 있는 방법을 제공해야 합니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { useState } from "@lynx-js/react" ;
import { ActionButton } from "@seed-design/lynx-react" ;
export default function Example () {
const [ open , setOpen ] = useState ( false );
function handleClose () {
"background only" ;
setOpen ( false );
}
return (
< BottomSheetRoot open = {open} onOpenChange = {setOpen}>
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent
title = "제목"
description = "설명을 작성할 수 있어요"
showCloseButton = { false }
>
< BottomSheetBody >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" bindtap = {handleClose}>
닫기
</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
}
Lynx에는 배경 탭, 드래그, ESC 닫기를 한 번에 제어하는 dismissible prop이 없습니다. enableDragToClose={false}로 드래그 닫기만 막을 수 있으며, Registry에서는 배경 탭 닫기를 끌 수 없습니다. ESC 키 닫기도 지원하지 않습니다. 닫기 동작을 막았다면 Footer 등에 닫기 버튼을 제공하세요.
스크롤 힌트가 필요하면 Body 안에 Scroll Fog 와 세로 <scroll-view>를 배치하세요. Body의 스크롤 영역 안에서는 height: "100%"가 기준으로 삼을 높이가 없으므로, ScrollFog에 고정 높이를 지정해야 합니다. fog 방향과 크기는 ScrollFog의 placement·size로, 스크롤바와 스크롤 동작은 <scroll-view> prop으로 제어합니다. 다만 이 <scroll-view>의 스크롤은 시트 드래그와 조정되지 않아, 스크롤한 상태에서 아래로 끌면 시트도 함께 움직입니다.
ScrollFog는 스크롤 위치와 관계없이 항상 효과를 표시하므로, <scroll-view>에 권장 padding인 상단 20px, 하단 80px을 지정해야 합니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton, ScrollFog, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
return (
< BottomSheetRoot >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody >
< ScrollFog placement = {[ "top" , "bottom" ]} style = {{ width: "100%" , height: "300px" }}>
< scroll-view
className = "bottom-sheet-preview__scroll-fog-content"
scroll-orientation = "vertical"
scroll-bar-enable = { false }
style = {{ width: "100%" , height: "100%" }}
>
< VStack className = "bottom-sheet-preview__blocks" gap = "x4" >
< view className = "bottom-sheet-preview__block" />
< view className = "bottom-sheet-preview__block" />
< view className = "bottom-sheet-preview__block" />
< view className = "bottom-sheet-preview__block" />
</ VStack >
</ scroll-view >
</ ScrollFog >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
}
<BottomSheetRoot>에 handleOnly를 전달하면 Bottom Sheet를 움직이는 세로 제스처 영역이 Handle로 제한됩니다. 이 옵션은 <BottomSheetContent showHandle>과 함께 사용하세요. 본문이 길 때는 Body 안의 스크롤 영역과 시트 드래그가 겹치지 않도록 이 조합을 권장합니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton } from "@seed-design/lynx-react" ;
export default function Example () {
return (
< BottomSheetRoot handleOnly >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" showHandle >
< BottomSheetBody >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
}
skipAnimation을 전달하면 Bottom Sheet의 enter, exit, snap 애니메이션을 건너뜁니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton } from "@seed-design/lynx-react" ;
export default function Example () {
return (
< BottomSheetRoot skipAnimation >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
);
}
onOpenChange의 reason은 trigger, closeButton, interactOutside, drag만 제공합니다.
Trigger는 자식을 native view로 감싸며 asChild를 제공하지 않습니다.
Root ref의 open, close, snapTo, expand, collapse로 시트를 제어할 수 있습니다. ref로 바꾼 상태는 onOpenChange로 알리지 않습니다.
container와 overlayLevel로 native overlay의 위치와 표시 순서를 지정합니다.
Registry에서는 lazyMount와 unmountOnExit을 지원하지 않습니다.