# Callout URL: /lynx/components/callout Source: https://github.com/daangn/seed-design/blob/dev/docs/content/lynx/components/callout.mdx 사용자에게 중요한 정보나 팁을 시각적으로 강조하여 전달하는 메시지 컴포넌트입니다. 사용 가능 버전: @seed-design/lynx-react@0.5.0, @seed-design/lynx-css@0.9.0 ## Preview ```tsx import "./styles"; import IconChevronRightLine from "@karrotmarket/lynx-monochrome-icon/IconChevronRightLine"; import IconXmarkLine from "@karrotmarket/lynx-monochrome-icon/IconXmarkLine"; import { root } from "@lynx-js/react"; import { Callout, SuffixIcon, useSeedClassName } from "@seed-design/lynx-react"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); function handleTap() { "background only"; } return ( 새로운 소식을 확인해 보세요. 알림 새로운 소식을 확인해 보세요. } /> 닫을 수 있는 안내 메시지예요. } /> ); } root.render(); ``` ## Installation - npm: npx @seed-design/cli@latest add ui:callout - pnpm: pnpm dlx @seed-design/cli@latest add ui:callout - yarn: yarn dlx @seed-design/cli@latest add ui:callout - bun: bun x @seed-design/cli@latest add ui:callout ## Props ### `Callout` ### `ActionableCallout` ### `DismissibleCallout` ## Usage 설치한 snippet은 기본 Callout, 전체 영역을 탭할 수 있는 ActionableCallout, 닫을 수 있는 DismissibleCallout을 export합니다. ```tsx import { Callout } from "@/components/ui/callout"; export function App() { return ; } ``` 저수준 조합이 필요하면 `@seed-design/lynx-react`의 compound API를 직접 사용할 수 있습니다. ```tsx import { Callout } from "@seed-design/lynx-react"; export function App() { return ( 알림 새로운 소식을 확인해 보세요. ); } ``` ## Prefix Icon 메시지의 의미를 보조하는 아이콘은 `prefixIcon`에 전달합니다. Lynx monochrome icon을 사용하면 `PrefixIcon` wrapper가 tone에 맞는 색상과 크기를 자동으로 적용합니다. ```tsx import "./styles"; import IconBellFill from "@karrotmarket/lynx-monochrome-icon/IconBellFill"; import { root } from "@lynx-js/react"; import { useSeedClassName } from "@seed-design/lynx-react"; import { Callout } from "@/components/ui/callout"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); return ( } title="알림" description="새로운 소식을 확인해 보세요." /> ); } root.render(); ``` 저수준 compound API에서는 `Callout.Root`의 첫 번째 child로 `PrefixIcon`을 배치하세요. ```tsx import IconBellFill from "@karrotmarket/lynx-monochrome-icon/IconBellFill"; import { Callout, PrefixIcon } from "@seed-design/lynx-react"; } /> 알림 새로운 소식을 확인해 보세요. ; ``` ## Tones `tone`은 `neutral`, `informative`, `positive`, `warning`, `critical`, `magic`을 지원합니다. 기본값은 `neutral`입니다. ```tsx import "./styles"; import { root } from "@lynx-js/react"; import { Callout, useSeedClassName } from "@seed-design/lynx-react"; const tones = ["neutral", "informative", "positive", "warning", "critical", "magic"] as const; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); return ( {tones.map((tone) => ( {tone} Callout의 {tone} tone입니다. ))} ); } root.render(); ``` ## Actionable Callout 전체 Callout을 액션으로 사용할 때는 `bindtap`을 전달합니다. 내부에 별도의 Link를 함께 두지 마세요. ```tsx import "./styles"; import IconChevronRightLine from "@karrotmarket/lynx-monochrome-icon/IconChevronRightLine"; import { root, useState } from "@lynx-js/react"; import { Callout, SuffixIcon, useSeedClassName } from "@seed-design/lynx-react"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); const [tapCount, setTapCount] = useState(0); function handleTap() { "background only"; setTapCount((count) => count + 1); } return ( 탭 횟수: {JSON.stringify(tapCount)} 업데이트 새로운 기능을 확인해 보세요. } /> ); } root.render(); ``` ## Dismissible Callout `DismissibleCallout`과 저수준 `Callout.Root`는 `open`, `defaultOpen`, `onDismiss`를 지원합니다. 닫기 버튼에는 현지화된 `dismissLabel` 또는 `accessibility-label`을 제공하세요. ```tsx import "./styles"; import IconXmarkLine from "@karrotmarket/lynx-monochrome-icon/IconXmarkLine"; import { root, useState } from "@lynx-js/react"; import { ActionButton, Callout, SuffixIcon, useSeedClassName } from "@seed-design/lynx-react"; function Root() { const seedClassName = useSeedClassName({ colorMode: "system" }); const [open, setOpen] = useState(true); function handleDismiss() { "background only"; setOpen(false); } function handleOpen() { "background only"; setOpen(true); } return ( 열림: {JSON.stringify(open)} 완료 설정이 저장되었어요. } /> {!open ? 다시 열기 : null} ); } root.render(); ``` ## 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` 지원 | 미지원 | | Link underline | `text-decoration` | Lynx preset 제약으로 border 기반 표현 | Lynx에서는 actionable Root가 터치되는 동안 `pressed` recipe variant를 적용합니다. `Callout.Link`는 기본적으로 `accessibility-traits="link"`, actionable Root와 CloseButton은 button trait를 사용합니다. ## Unsupported Lynx Features - `asChild`: Lynx에는 DOM Slot 기반 다형 렌더링이 없습니다. - 웹 focus ring: Lynx는 웹 키보드 포커스 모델을 사용하지 않습니다. - HTML attribute와 ARIA prop: 대응하는 Lynx native prop과 `accessibility-*`를 사용하세요.