화면 하단에서 올라오는 시트 컴포넌트로, 드래그·snap·dismiss 상호작용을 제공합니다.
@seed-design/lynx-react@0.1.0, @seed-design/lynx-css@0.1.0
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton, useSeedClassName, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-bottom-sheet-root` }>
< VStack className = "bottom-sheet-preview" >
< BottomSheetRoot >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody className = "bottom-sheet-preview__body" >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ VStack >
</ view >
);
}
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 @seed-design/lynx-react yarn add @seed-design/lynx-react pnpm add @seed-design/lynx-react bun add @seed-design/lynx-react 아래 코드를 복사 후 붙여넣고 사용하세요 /**
* @file ui:bottom-sheet
* @requires @seed-design/lynx-react@>=0.1.0 <1.0.0
* @requires @seed-design/lynx-css@>=0.1.0 <1.0.0
**/
import {
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 ;
/**
* @default false
*/
showHandle ?: boolean ;
}
/**
* Positioner / Backdrop / Handle / Header / Title / Description을 내부에서 조립해
* 사용자가 단일 컴포넌트로 콘텐츠를 구성할 수 있도록 한다.
*
* 웹 BottomSheetContent와 달리 아래는 Lynx에서 미지원:
* - `showCloseButton` (Tier B: SVG 지원 후 추가 예정)
* - `accessibility-label` 기반 VisuallyHidden 제목 fallback (VisuallyHidden 미구현)
*/
export const BottomSheetContent = ( props : BottomSheetContentProps ) => {
const { children , title , description , showHandle = false , ... otherProps } = props;
const shouldRenderHeader = title || description;
return (
< SeedBottomSheet.Positioner >
< 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}
</ 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.
*/
@seed-design/lynx-react의 BottomSheet는 @lynx-js/lynx-ui-sheet 를 래핑합니다. 드래그, spring, snap, presence 동작은 lynx-ui-sheet가 담당합니다. SEED는 공개 API와 recipe 슬롯 스타일을 제공합니다.
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 >
);
}
Registry의 BottomSheetContent는 Positioner, Backdrop, Header를 내부에서 조립합니다. BottomSheetTrigger는 Content 밖에 두어야 탭으로 시트를 열 수 있습니다.
저수준 package API에서 BottomSheet.Positioner에 container를 지정하면 <overlay> XElement를 사용합니다. Registry의 기본 경로는 <view>를 사용합니다. container가 필요하다면 앱의 Lynx Engine이 <overlay>를 지원하는지 확인하세요.
BottomSheetRoot에 ref를 전달하면 open, close, snapTo, expand, collapse 메서드를 호출할 수 있습니다.
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 >
);
}
style?CSSProperties | undefined
children?ReactNode
className?string | undefined
bindtap?EventHandler < BaseTouchEvent < Target >> | undefined
title?ReactNode
description?ReactNode
showHandle?boolean | undefined
style?CSSProperties | undefined
children?ReactNode
className?string | undefined
<BottomSheetTrigger>를 탭하면 Bottom Sheet가 열립니다. Lynx는 asChild를 지원하지 않습니다. Trigger는 자식 요소를 감싸는 <view>를 렌더링합니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton, useSeedClassName, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-bottom-sheet-root` }>
< VStack className = "bottom-sheet-preview" >
< BottomSheetRoot >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" >
< BottomSheetBody className = "bottom-sheet-preview__body" >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ VStack >
</ view >
);
}
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, useSeedClassName, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
const [ open , setOpen ] = useState ( false );
function scheduleOpen () {
"background only" ;
setTimeout (() => {
setOpen ( true );
}, 1000 );
}
return (
< view className = { `${ seedClassName } docs-lynx-bottom-sheet-root` }>
< VStack className = "bottom-sheet-preview" >
< ActionButton variant = "neutralSolid" bindtap = {scheduleOpen}>
1초 후 열기
</ ActionButton >
< BottomSheetRoot open = {open} onOpenChange = {setOpen}>
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody className = "bottom-sheet-preview__body" >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ VStack >
</ view >
);
}
Lynx의 onOpenChange는 변경된 open 값만 전달합니다. React 버전의 details.reason은 지원하지 않습니다. 열고 닫는 원인이 필요하면 앱이 소유한 버튼과 Trigger의 이벤트 핸들러에서 원인을 별도 상태로 기록하세요. 배경 탭과 드래그는 콜백 값만으로 구분할 수 없습니다.
<BottomSheetRoot>의 headerAlign으로 title과 description을 왼쪽 또는 가운데에 정렬할 수 있습니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton, HStack, useSeedClassName } from "@seed-design/lynx-react" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-bottom-sheet-root` }>
< HStack className = "bottom-sheet-preview" gap = "x4" >
< BottomSheetRoot headerAlign = "left" >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Left (기본값)</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody className = "bottom-sheet-preview__body" >
< 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 className = "bottom-sheet-preview__body" >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ HStack >
</ view >
);
}
BottomSheetBody는 native <view>를 렌더링합니다. 최대 300px인 스크롤 영역을 만들려면 Body 안에 <scroll-view>를 배치하고 height, maxHeight, flex: "none"을 함께 지정하세요. Lynx의 scroll-view에 maxHeight만 지정하면 콘텐츠 크기를 높이로 계산하지 못해 영역이 0px로 축소될 수 있습니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton, useSeedClassName, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-bottom-sheet-root` }>
< VStack className = "bottom-sheet-preview" >
< BottomSheetRoot >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody style = {{ flex: "none" }}>
< scroll-view scroll-y style = {{ height: "300px" , maxHeight: "300px" , flex: "none" }}>
< 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 >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ VStack >
</ view >
);
}
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, useSeedClassName, VStack } from "@seed-design/lynx-react" ;
const snapPoints = [ "45%" , "80%" ];
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
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 (
< view className = { `${ seedClassName } docs-lynx-bottom-sheet-root` }>
< VStack className = "bottom-sheet-preview" gap = "x3" >
< 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 >
</ view >
);
}
Lynx는 fadeFromIndex를 지원하지 않습니다. Registry가 제공하는 기본 Backdrop을 사용하세요. snap index별 dim 변화가 꼭 필요하면 저수준 package API로 Backdrop을 직접 조립하고 onSnapChange 상태에 따라 투명도를 제어해야 합니다.
<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, useSeedClassName, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
const [ open , setOpen ] = useState ( false );
function handleClose () {
"background only" ;
setOpen ( false );
}
return (
< view className = { `${ seedClassName } docs-lynx-bottom-sheet-root` }>
< VStack className = "bottom-sheet-preview" >
< BottomSheetRoot open = {open} onOpenChange = {setOpen}>
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" showHandle >
< BottomSheetBody className = "bottom-sheet-preview__body" >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" bindtap = {handleClose}>
닫기
</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ VStack >
</ view >
);
}
Lynx의 BottomSheetContent는 showCloseButton과 CloseButton을 지원하지 않습니다. 닫기 버튼이 필요하면 controlled 상태를 사용하고 BottomSheetFooter의 버튼에서 open을 false로 바꾸세요.
Lynx에는 배경 탭, 드래그, ESC 닫기를 한 번에 제어하는 dismissible prop이 없습니다. 드래그는 BottomSheetRoot의 enableDragToClose={false}로 막을 수 있습니다. 배경 탭까지 막아야 한다면 저수준 package API로 조립하고 BottomSheet.Backdrop에 clickToClose={false}를 전달하세요. Lynx에는 웹의 ESC 키 닫기 동작이 없습니다. 닫기 동작을 막았다면 Footer 등에 명시적인 닫기 버튼을 제공하세요.
BottomSheetBody는 스크롤 방식을 정하지 않는 native <view>입니다. 스크롤 힌트가 필요하면 Body 안에 ScrollFog를 직접 배치하세요. 이 구조에서는 size, placement, hideScrollBar와 native scroll-view prop을 사용하는 곳에서 직접 제어할 수 있습니다.
네이티브 fading-edge-length는 스크롤할 콘텐츠가 남아 있는 edge에서만 fog를 표시합니다. 처음에는 아래쪽, 끝까지 스크롤하면 위쪽에 표시됩니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton, ScrollFog, useSeedClassName, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-bottom-sheet-root` }>
< VStack className = "bottom-sheet-preview" >
< BottomSheetRoot >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody className = "bottom-sheet-preview__scroll-fog-body" >
< ScrollFog
hideScrollBar
placement = {[ "top" , "bottom" ]}
style = {{ width: "100%" , height: "100%" }}
>
< VStack
className = "bottom-sheet-preview__blocks bottom-sheet-preview__scroll-fog-content"
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 >
</ ScrollFog >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ VStack >
</ view >
);
}
Lynx의 BottomSheetContent는 기기의 safeAreaInsetBottom을 내부 padding으로 적용합니다. React 예제처럼 --seed-safe-area-bottom을 직접 전달할 필요가 없습니다.
<BottomSheetRoot>에 handleOnly를 전달하면 Bottom Sheet를 움직이는 세로 제스처 영역이 Handle로 제한됩니다. 이 옵션은 <BottomSheetContent showHandle>과 함께 사용하세요. 본문이 길 때는 Body 안의 스크롤 영역과 시트 드래그가 겹치지 않도록 이 조합을 권장합니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton, useSeedClassName, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-bottom-sheet-root` }>
< VStack className = "bottom-sheet-preview" >
< BottomSheetRoot handleOnly >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" showHandle >
< BottomSheetBody className = "bottom-sheet-preview__body" >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ VStack >
</ view >
);
}
skipAnimation을 전달하면 Bottom Sheet의 enter, exit, snap 애니메이션을 건너뜁니다.
import "./styles" ;
import {
BottomSheetBody,
BottomSheetContent,
BottomSheetFooter,
BottomSheetRoot,
BottomSheetTrigger,
} from "@/components/ui/bottom-sheet" ;
import { ActionButton, useSeedClassName, VStack } from "@seed-design/lynx-react" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-bottom-sheet-root` }>
< VStack className = "bottom-sheet-preview" >
< BottomSheetRoot skipAnimation >
< BottomSheetTrigger >
< ActionButton variant = "neutralSolid" >Open</ ActionButton >
</ BottomSheetTrigger >
< BottomSheetContent title = "제목" description = "설명을 작성할 수 있어요" >
< BottomSheetBody className = "bottom-sheet-preview__body" >
< text className = "bottom-sheet-preview__body-text" >Content</ text >
</ BottomSheetBody >
< BottomSheetFooter >
< ActionButton variant = "neutralSolid" >확인</ ActionButton >
</ BottomSheetFooter >
</ BottomSheetContent >
</ BottomSheetRoot >
</ VStack >
</ view >
);
}
항목 웹 Lynx 사용자 이벤트 onClickbindtap렌더링 요소 HTML 요소 네이티브 <view>, <text>, <scroll-view> 상태 prop open, defaultOpen, onOpenChange동일. 내부에서 lynx-ui-sheet의 상태 API로 연결 마운트 제어 lazyMount, unmountOnExitRegistry에서 미지원. 저수준 BottomSheet.Positioner의 forceMount로 제어 Trigger 합성 asChild 지원미지원. <view> 렌더링 imperative ref API 없음 open, close, snapTo, expand, collapse