# Alert Dialog URL: /lynx/components/alert-dialog Source: https://github.com/daangn/seed-design/blob/dev/docs/content/lynx/components/alert-dialog.mdx 사용자의 확인이 반드시 필요한 경우 강력한 표현 및 경고 수단으로 활용하는 컴포넌트입니다. Lynx Engine 최소 버전: 3.6 사용 XElement: 사용 가능 버전: @seed-design/lynx-react@0.8.0, @seed-design/lynx-css@0.12.0 ## Preview ```tsx import "./styles"; import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; export default function Example() { return ( 열기 주의 이 작업은 되돌릴 수 없습니다. 취소 확인 ); } ``` ## Installation - npm: npx @seed-design/cli add ui:alert-dialog - pnpm: pnpm dlx @seed-design/cli add ui:alert-dialog - yarn: yarn dlx @seed-design/cli add ui:alert-dialog - bun: bun x @seed-design/cli add ui:alert-dialog ## Usage ```tsx import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; export function App() { return ( 열기 주의 이 작업은 되돌릴 수 없습니다. 취소 확인 ); } ``` `AlertDialogTrigger`는 자식을 native `view`로 감쌉니다. 문자열 children에서 접근성 이름을 만들며, `accessibility-label`을 직접 지정하면 그 값을 사용합니다. raw ``처럼 이름을 만들 수 없는 자식에는 이름을 명시하세요. `AlertDialogAction`은 탭하면 Alert Dialog를 닫지만, `disabled` 또는 `loading` 상태에서는 닫지 않습니다. 사용자의 확인이 필요한 흐름을 위해 Backdrop 탭으로는 닫히지 않습니다. ## Props ### `AlertDialogRoot` `open`, `defaultOpen`, `onOpenChange`로 상태를 제어할 수 있으며 `skipAnimation`으로 열림·닫힘 transition을 건너뛸 수 있습니다. ### `AlertDialogTrigger` 고유 prop이 없습니다. ### `AlertDialogContent` `container`와 `overlayLevel`로 native overlay의 위치와 표시 순서를 지정합니다. ### `AlertDialogHeader` 고유 prop이 없습니다. `className`, `style`, `children`과 `padding`·`gap` 같은 스타일 prop을 받습니다. ### `AlertDialogTitle` ### `AlertDialogDescription` 고유 prop이 없습니다. `className`, `style`, `children`과 `padding`·`gap` 같은 스타일 prop을 받습니다. ### `AlertDialogFooter` 고유 prop이 없습니다. `className`, `style`, `children`과 `padding`·`gap` 같은 스타일 prop을 받습니다. ### `AlertDialogAction` ## Examples ### Responsive Wrapping React의 `ResponsivePair` 대신 Footer 안에 명시적인 세로 action layout을 구성합니다. Lynx에서는 native `view`의 `flex-direction` 등을 사용해 긴 버튼 레이블이 세로로 배치되도록 조정합니다. ```tsx import "./styles"; import IconCheckmarkFill from "@karrotmarket/lynx-monochrome-icon/IconCheckmarkFill"; import { ActionButton, PrefixIcon } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; export default function Example() { return ( 열기 Wrapping Lynx에서는 긴 버튼 레이블을 위해 action을 세로로 배치할 수 있습니다. 취소 } />긴 레이블 예시 ); } ``` ### Long Content 내용이 최대 높이를 넘으면 `AlertDialogContent` 안에서 스크롤되고, 끝까지 스크롤하면 Footer의 버튼이 보입니다. Content는 위아래 safe area inset과 recipe의 위아래 margin을 뺀 높이를 넘지 않습니다. ```tsx import "./styles"; import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; export default function Example() { return ( 열기 긴 내용 {Array.from( { length: 30 }, (_, index) => `${index + 1}. 내용이 최대 높이를 넘으면 AlertDialog 안에서 스크롤됩니다.`, ).join(" ")} 취소 확인 ); } ``` ### Single Action 확인 또는 닫기처럼 하나의 action만 제공하는 Alert Dialog입니다. ```tsx import "./styles"; import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; export default function Example() { return ( 열기 제목 단일 선택지를 제공합니다. 확인 ); } ``` ### Neutral Secondary Action 보조 action에 `neutralWeak`를 사용하고, 주요 action과 시각적 우선순위를 구분합니다. ```tsx import "./styles"; import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; export default function Example() { return ( 열기 제목 중립적인 선택지를 제공합니다. 취소 확인 ); } ``` ### Nonpreferred 주요 흐름에서 권장하지 않는 action 조합을 표현하는 예제입니다. ```tsx import "./styles"; import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; export default function Example() { return ( 열기 제목 중립적인 선택지를 제공합니다. 라벨 라벨 ); } ``` ### Critical Action 삭제처럼 되돌리기 어렵거나 위험한 action에는 `criticalSolid`를 사용합니다. ```tsx import "./styles"; import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; export default function Example() { return ( 열기 제목 파괴적, 비가역적 작업을 경고합니다. 취소 확인 ); } ``` ### Controlled Trigger 외의 방식으로 Alert Dialog를 열고 닫으려면 `open`과 boolean을 받는 `onOpenChange`로 상태를 제어합니다. ```tsx import "./styles"; import { useState } from "@lynx-js/react"; import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, } from "@/components/ui/alert-dialog"; export default function Example() { const [open, setOpen] = useState(false); function handleOpen() { "background only"; setOpen(true); } return ( 열림 상태: {open ? "true" : "false"} 열기 주의 이 작업은 되돌릴 수 없습니다. 취소 확인 ); } ``` ### Prevent Close Lynx의 `AlertDialogAction`에는 React 이벤트의 `preventDefault()` 방식이 없습니다. controlled Root에서 `onOpenChange(false)` 요청을 조건에 따라 무시하면 닫힘을 막을 수 있습니다. ```tsx import "./styles"; import { useState } from "@lynx-js/react"; import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, } from "@/components/ui/alert-dialog"; export default function Example() { const [open, setOpen] = useState(false); const [preventClose, setPreventClose] = useState(true); function handleOpen() { "background only"; setOpen(true); } function handleTogglePreventClose() { "background only"; setPreventClose((previous) => !previous); } function handleOpenChange(nextOpen: boolean) { "background only"; if (nextOpen || !preventClose) { setOpen(nextOpen); } } return ( 열림 상태: {open ? "true" : "false"} 열기 닫기 방지 닫힘 방지 상태에서는 확인 버튼을 눌러도 Alert Dialog가 닫히지 않습니다. 닫힘 방지: {preventClose ? "켜짐" : "꺼짐"} {preventClose ? "닫힘 허용" : "닫힘 방지"} 확인 ); } ``` ### Portalled `AlertDialogContent`의 `container`를 지정하면 native overlay 레이어에 렌더링됩니다. `overlayLevel`로 overlay 레이어의 표시 순서를 지정할 수 있습니다. ```tsx import "./styles"; import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; export default function Example() { return ( 열기 window overlay Lynx에서는 container와 overlayLevel로 네이티브 overlay 위치를 지정합니다. 취소 확인 ); } ``` ### Skip Animation `AlertDialogRoot`의 `skipAnimation` prop을 사용하여 Alert Dialog의 enter/exit transition을 건너뛸 수 있습니다. ```tsx import "./styles"; import { ActionButton } from "@seed-design/lynx-react"; import { AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; export default function Example() { return ( 애니메이션 없이 열기 즉시 표시 skipAnimation이 설정되어 열고 닫을 때 전환 애니메이션을 사용하지 않습니다. 취소 확인 ); } ``` ## 웹 버전과의 차이 - `onOpenChange`는 변경된 boolean 값만 전달합니다. 닫힌 원인이 필요하면 Trigger와 action의 이벤트 핸들러에서 별도 상태로 기록하세요. - Backdrop 탭과 ESC 키로 닫히지 않습니다. 필요한 닫기 흐름은 버튼과 controlled 상태로 구성하세요. - Trigger는 자식을 native `view`로 감싸며 `asChild`를 제공하지 않습니다. - DOM ref forwarding과 웹의 자동 focus 관리 API를 제공하지 않습니다. - `container`와 `overlayLevel`로 native overlay의 위치와 표시 순서를 지정합니다. - `ResponsivePair`는 제공하지 않습니다. Footer 안에서 action의 방향과 간격을 직접 지정하세요.