# Page Banner URL: /lynx/components/page-banner Source: https://github.com/daangn/seed-design/blob/dev/docs/content/lynx/components/page-banner.mdx 페이지 상단에서 전체 상태나 중요한 메시지를 전달하는 상위 레벨 메시지 컴포넌트입니다. Lynx Engine 최소 버전: 3.6 사용 가능 버전: @seed-design/lynx-react@0.6.0, @seed-design/lynx-css@0.10.0 ## Preview ```tsx import "./styles"; import { root, useState } from "@lynx-js/react"; import { useSeedClassName } from "@seed-design/lynx-react"; import { ActionablePageBanner, DismissiblePageBanner, PageBanner, } from "@/components/ui/page-banner"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); const [open, setOpen] = useState(true); function handleTap() { "background only"; } function handleDismiss() { "background only"; setOpen(false); } return ( ); } root.render(); ``` ## Installation - npm: npx @seed-design/cli@latest add ui:page-banner - pnpm: pnpm dlx @seed-design/cli@latest add ui:page-banner - yarn: yarn dlx @seed-design/cli@latest add ui:page-banner - bun: bun x @seed-design/cli@latest add ui:page-banner ## Props ### `PageBanner` ### `PageBannerButton` ### `ActionablePageBanner` ### `DismissiblePageBanner` ## Usage 설치한 snippet은 기본 배너와 전체 영역을 탭할 수 있는 배너, 닫을 수 있는 배너를 제공합니다. ```tsx import { PageBanner } from "@/components/ui/page-banner"; export function App() { return ; } ``` 저수준 조합이 필요하면 `@seed-design/lynx-react`의 compound API를 직접 사용할 수 있습니다. ```tsx import { PageBanner } from "@seed-design/lynx-react"; export function App() { return ( 알림 새로운 소식을 확인해 보세요. ); } ``` ## Examples ### With Button `PageBanner`의 `suffix`에 `PageBannerButton`을 전달하면 메시지 옆에 버튼을 배치할 수 있습니다. ```tsx import "./styles"; import { root } from "@lynx-js/react"; import { useSeedClassName } from "@seed-design/lynx-react"; import { PageBanner, PageBannerButton } from "@/components/ui/page-banner"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); function handleTap() { "background only"; } return ( 자세히 보기} /> ); } root.render(); ``` ### Tones and Variants `tone`은 `neutral`, `informative`, `positive`, `warning`, `critical`, `magic`을 지원합니다. `variant`는 `weak`과 `solid`를 지원합니다. 기본 조합은 `neutral`과 `weak`입니다. #### Neutral ```tsx import "./styles"; import IconExclamationmarkCircleFill from "@karrotmarket/lynx-monochrome-icon/IconExclamationmarkCircleFill"; import { root } from "@lynx-js/react"; import { useSeedClassName } from "@seed-design/lynx-react"; import { PageBanner, PageBannerButton } from "@/components/ui/page-banner"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); return ( } title="미노출" description="사업자 정보를 등록해 주세요." suffix={등록하기} /> } title="미노출" description="사업자 정보를 등록해 주세요." suffix={등록하기} /> ); } root.render(); ``` #### Informative ```tsx import "./styles"; import IconExclamationmarkCircleFill from "@karrotmarket/lynx-monochrome-icon/IconExclamationmarkCircleFill"; import { root } from "@lynx-js/react"; import { useSeedClassName } from "@seed-design/lynx-react"; import { PageBanner, PageBannerButton } from "@/components/ui/page-banner"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); return ( } title="안내" description="새로운 정보를 확인해 주세요." suffix={확인하기} /> } title="안내" description="새로운 정보를 확인해 주세요." suffix={확인하기} /> ); } root.render(); ``` #### Positive ```tsx import "./styles"; import IconCheckmarkCircleFill from "@karrotmarket/lynx-monochrome-icon/IconCheckmarkCircleFill"; import { root } from "@lynx-js/react"; import { useSeedClassName } from "@seed-design/lynx-react"; import { PageBanner, PageBannerButton } from "@/components/ui/page-banner"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); return ( } title="완료" description="설정이 저장되었어요." suffix={확인} /> } title="완료" description="설정이 저장되었어요." suffix={확인} /> ); } root.render(); ``` #### Warning ```tsx import "./styles"; import IconExclamationmarkTriangleFill from "@karrotmarket/lynx-monochrome-icon/IconExclamationmarkTriangleFill"; import { root } from "@lynx-js/react"; import { useSeedClassName } from "@seed-design/lynx-react"; import { PageBanner, PageBannerButton } from "@/components/ui/page-banner"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); return ( } title="주의" description="입력한 내용을 다시 확인해 주세요." suffix={확인} /> } title="주의" description="입력한 내용을 다시 확인해 주세요." suffix={확인} /> ); } root.render(); ``` #### Critical ```tsx import "./styles"; import IconExclamationmarkCircleFill from "@karrotmarket/lynx-monochrome-icon/IconExclamationmarkCircleFill"; import { root } from "@lynx-js/react"; import { useSeedClassName } from "@seed-design/lynx-react"; import { PageBanner, PageBannerButton } from "@/components/ui/page-banner"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); return ( } title="오류" description="요청을 처리하지 못했어요." suffix={다시 시도} /> } title="오류" description="요청을 처리하지 못했어요." suffix={다시 시도} /> ); } root.render(); ``` #### Magic `tone="magic"`은 `variant="weak"`과만 함께 사용할 수 있습니다. ```tsx import "./styles"; import IconSparkle2 from "@karrotmarket/lynx-multicolor-icon/IconSparkle2"; import { root } from "@lynx-js/react"; import { useSeedClassName } from "@seed-design/lynx-react"; import { PageBanner, PageBannerButton } from "@/components/ui/page-banner"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); return ( } title="새로운 기능" description="마법 같은 소식이 도착했어요!" suffix={둘러보기} /> ); } root.render(); ``` ## Action and Dismiss 전체 배너를 액션으로 사용하려면 `ActionablePageBanner`에 `bindtap`과 `accessibility-label`을 전달하세요. 닫기 상태를 직접 관리할 때는 `DismissiblePageBanner`의 `open`과 `onDismiss`를 사용합니다. ## Web Version Differences | 영역 | React Web | Lynx | | -------------------- | -------------------------- | -------------------------------- | | Native element | `div`, `span`, `button` | `view`, `text` | | Event | `onClick` | `bindtap`, `main-thread:bindtap` | | Accessibility | HTML semantics, ARIA | `accessibility-*` | | Polymorphism | `asChild` 지원 | 미지원 | | Interaction feedback | focus ring, scale feedback | pressed 배경색 | Lynx의 actionable Root는 터치되는 동안 `pressed` Recipe 상태를 적용합니다. `PageBannerButton`, actionable Root, CloseButton은 기본적으로 button trait를 사용합니다. ## Unsupported Lynx Features - `asChild`: Lynx에는 DOM Slot 기반 다형 렌더링이 없습니다. `PageBannerButton`은 Lynx `text` 요소로 렌더링됩니다. - 웹 focus ring과 동적 scale feedback: Lynx는 웹 키보드 포커스 모델을 사용하지 않습니다. - HTML attribute와 ARIA prop: 대응하는 Lynx native prop과 `accessibility-*`를 사용하세요.