Alert

현재 화면 위에 창을 띄워, 사용자의 흐름을 잠시 멈추고 주의할 내용을 안내하는 컴포넌트입니다. 사용자가 반드시 확인하고 넘어가야 하는 주요한 상황에 사용합니다.

Basic alert

유저에게 중요한 액션을 실행할지 다시 한 번 묻고 싶을 때 사용합니다.

useAlert hook을 사용하면 Promise 형태로 사용할 수 있습니다.

import { FlexBox, Button, Typography, Alert, AlertContainer, AlertContent, AlertHeading, AlertDescription, AlertActionArea, AlertActionAreaButton, AlertTrigger } from '@wanteddev/wds';
import { useState } from 'react';

const Demo = () => {
  const [open, setOpen] = useState(false);
  const [result, setResult] = useState<string | null>(null);

  const handleOpen = () => {
    setOpen(true);
  }

  return (
    <FlexBox flexDirection="column" gap="16px">
      <Typography align="center">{result}</Typography>

      <Alert open={open} onOpenChange={setOpen}>
        <AlertTrigger>
          <Button onClick={handleOpen}>Open</Button>
        </AlertTrigger>

        <AlertContainer onDismiss={() => setResult('Dismissed')}>
          <AlertContent>
            <AlertHeading>Heading</AlertHeading>
            <AlertDescription>Description</AlertDescription>
          </AlertContent>
          <AlertActionArea>
            <AlertActionAreaButton variant="assistive" onClick={() => setResult('Cancel')}>
              Cancel
            </AlertActionAreaButton>
            <AlertActionAreaButton variant="normal" onClick={() => setResult('Confirm')}>
              Confirm
            </AlertActionAreaButton>
          </AlertActionArea>
        </AlertContainer>
      </Alert>
    </FlexBox>
  )
}

export default Demo;

Anatomy

Alert 은 여러 컴포넌트를 조합해서 사용합니다.

AlertTrigger 는 선택적으로 사용할 수 있습니다.

기본 구성은 아래와 같습니다.

<Alert>
  <AlertTrigger>
    <Button />
  </AlertTrigger>

  <AlertContainer>
    <AlertContent>
      <AlertHeading />
      <AlertDescription />
    </AlertContent>

    <AlertActionArea>
      <AlertActionAreaButton />
    </AlertActionArea>
  </AlertContainer>
</Alert>

Button variants

variant 옵션에 따라 버튼의 색상이 달라집니다.

  • normal
  • assistive
  • negative
import { FlexBox, Button, Alert, AlertContainer, AlertContent, AlertHeading, AlertDescription, AlertActionArea, AlertActionAreaButton, AlertTrigger } from '@wanteddev/wds';
import { useState } from 'react';

const Demo = () => {
  const [open, setOpen] = useState(false);

  const handleOpen = () => {
    setOpen(true);
  }

  return (
    <FlexBox flexDirection="column" gap="16px">
      <Alert open={open} onOpenChange={setOpen}>
        <AlertTrigger>
          <Button onClick={handleOpen}>Open</Button>
        </AlertTrigger>

        <AlertContainer>
          <AlertContent>
            <AlertHeading>Heading</AlertHeading>
            <AlertDescription>Description</AlertDescription>
          </AlertContent>
          <AlertActionArea>
            <AlertActionAreaButton variant="assistive">
              Assistive
            </AlertActionAreaButton>
            <AlertActionAreaButton variant="normal">
              Normal
            </AlertActionAreaButton>
            <AlertActionAreaButton variant="negative">
              Negative
            </AlertActionAreaButton>
          </AlertActionArea>
        </AlertContainer>
      </Alert>
    </FlexBox>
  )
}

export default Demo;

Prevent close

AlertActionAreaButton 은 기본적으로 클릭 시 Alert을 닫습니다.

이를 방지하고 싶다면 onClicke.preventDefault 를 추가해주세요.

import { FlexBox, Button, Alert, AlertContainer, AlertContent, AlertHeading, AlertDescription, AlertActionArea, AlertActionAreaButton, AlertTrigger } from '@wanteddev/wds';
import { useState } from 'react';

const Demo = () => {
  const [open, setOpen] = useState(false);

  const handleOpen = () => {
    setOpen(true);
  }

  return (
    <FlexBox flexDirection="column" gap="16px">
      <Alert open={open} onOpenChange={setOpen}>
        <AlertTrigger>
          <Button onClick={handleOpen}>Open</Button>
        </AlertTrigger>

        <AlertContainer>
          <AlertContent>
            <AlertHeading>Heading</AlertHeading>
            <AlertDescription>Description</AlertDescription>
          </AlertContent>
          <AlertActionArea>
            <AlertActionAreaButton variant="assistive" onClick={e => e.preventDefault()}>
              Prevent
            </AlertActionAreaButton>
            <AlertActionAreaButton variant="normal">
              No Prevent
            </AlertActionAreaButton>
          </AlertActionArea>
        </AlertContainer>
      </Alert>
    </FlexBox>
  )
}

export default Demo;

API

Alert

NameTypesdefaultValue
open
boolean
-
defaultOpen
boolean
-
onOpenChange
(open: boolean) => void
-
children
ReactNode
-

AlertContainer

NameTypesdefaultValue
as
ElementType
-
forceMount
boolean
false
disablePortal
boolean
-
container
null | Element | DocumentFragment
-
wrapperProps
DefaultComponentProps<{}, 'div'>
-
disableOutsideClickClose
boolean
false
disableEscapeKeyDownClose
boolean
-
disableRemoveScroll
boolean
false
disableFocusScope
boolean
false
disableAriaHiddenOthers
boolean
false
onDismiss
() => void
-
dimmer
ReactNode
<AlertDimmer />
children
ReactNode
-
sx
SxProp
-
xl
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
lg
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
md
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
sm
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
xs
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
flexDirection
Property.FlexDirection | undefined
-
flexWrap
Property.FlexWrap | undefined
-
justifyContent
Property.JustifyContent | undefined
-
alignItems
Property.AlignItems | undefined
-
alignContent
Property.AlignContent | undefined
-
order
Property.Order | undefined
-
flex
Property.Flex<string | number> | undefined
-
flexGrow
Property.FlexGrow | undefined
-
flexShrink
Property.FlexShrink | undefined
-
flexBasis
Property.FlexBasis<string | number> | undefined
-
alignSelf
Property.AlignSelf | undefined
-
gap
Property.Gap<string | number> | undefined
-
rowGap
Property.RowGap<string | number> | undefined
-
columnGap
Property.ColumnGap<string | number> | undefined
-

AlertContent

FlexBox 와 동일한 Props를 사용합니다.

NameTypesdefaultValue
flexDirection
Property.FlexDirection | undefined
-
flexWrap
Property.FlexWrap | undefined
-
justifyContent
Property.JustifyContent | undefined
-
alignItems
Property.AlignItems | undefined
-
alignContent
Property.AlignContent | undefined
-
order
Property.Order | undefined
-
flex
Property.Flex<string | number> | undefined
-
flexGrow
Property.FlexGrow | undefined
-
flexShrink
Property.FlexShrink | undefined
-
flexBasis
Property.FlexBasis<string | number> | undefined
-
alignSelf
Property.AlignSelf | undefined
-
gap
Property.Gap<string | number> | undefined
-
rowGap
Property.RowGap<string | number> | undefined
-
columnGap
Property.ColumnGap<string | number> | undefined
-
children
ReactNode
-
sx
SxProp
-
xl
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
lg
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
md
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
sm
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
xs
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-

AlertHeading

Typography 와 동일한 Props를 사용합니다.

NameTypesdefaultValue
xl
Merge<Pick<TypographyDefaultProps, "variant" | "weight" | "align">, { sx?: CSSInterpolation; }> | undefined
-
lg
Merge<Pick<TypographyDefaultProps, "variant" | "weight" | "align">, { sx?: CSSInterpolation; }> | undefined
-
md
Merge<Pick<TypographyDefaultProps, "variant" | "weight" | "align">, { sx?: CSSInterpolation; }> | undefined
-
sm
Merge<Pick<TypographyDefaultProps, "variant" | "weight" | "align">, { sx?: CSSInterpolation; }> | undefined
-
xs
Merge<Pick<TypographyDefaultProps, "variant" | "weight" | "align">, { sx?: CSSInterpolation; }> | undefined
-
color
ThemeColorsToken
-
children
ReactNode
-
sx
SxProp
-
variant
"display1" | "display2" | "display3" | "title1" | "title2" | "title3" | "heading1" | "heading2" | "headline1" | "headline2" | "body1" | "body1-reading" | "body2" | "body2-reading" | "label1" | "label1-reading" | "label2" | "caption1" | "caption2"
-
weight
"medium" | "regular" | "bold"
-
align
Property.TextAlign | undefined
-
noWrap
boolean
-
display
Property.Display | undefined
-

AlertDescription

Typography 와 동일한 Props를 사용합니다.

NameTypesdefaultValue
xl
Merge<Pick<TypographyDefaultProps, "variant" | "weight" | "align">, { sx?: CSSInterpolation; }> | undefined
-
lg
Merge<Pick<TypographyDefaultProps, "variant" | "weight" | "align">, { sx?: CSSInterpolation; }> | undefined
-
md
Merge<Pick<TypographyDefaultProps, "variant" | "weight" | "align">, { sx?: CSSInterpolation; }> | undefined
-
sm
Merge<Pick<TypographyDefaultProps, "variant" | "weight" | "align">, { sx?: CSSInterpolation; }> | undefined
-
xs
Merge<Pick<TypographyDefaultProps, "variant" | "weight" | "align">, { sx?: CSSInterpolation; }> | undefined
-
color
ThemeColorsToken
-
children
ReactNode
-
sx
SxProp
-
variant
"display1" | "display2" | "display3" | "title1" | "title2" | "title3" | "heading1" | "heading2" | "headline1" | "headline2" | "body1" | "body1-reading" | "body2" | "body2-reading" | "label1" | "label1-reading" | "label2" | "caption1" | "caption2"
-
weight
"medium" | "regular" | "bold"
-
align
Property.TextAlign | undefined
-
noWrap
boolean
-
display
Property.Display | undefined
-

AlertActionArea

FlexBox 과 동일한 Props를 사용합니다.

NameTypesdefaultValue
flexDirection
Property.FlexDirection | undefined
-
flexWrap
Property.FlexWrap | undefined
-
justifyContent
Property.JustifyContent | undefined
-
alignItems
Property.AlignItems | undefined
-
alignContent
Property.AlignContent | undefined
-
order
Property.Order | undefined
-
flex
Property.Flex<string | number> | undefined
-
flexGrow
Property.FlexGrow | undefined
-
flexShrink
Property.FlexShrink | undefined
-
flexBasis
Property.FlexBasis<string | number> | undefined
-
alignSelf
Property.AlignSelf | undefined
-
gap
Property.Gap<string | number> | undefined
-
rowGap
Property.RowGap<string | number> | undefined
-
columnGap
Property.ColumnGap<string | number> | undefined
-
children
ReactNode
-
sx
SxProp
-
xl
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
lg
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
md
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
sm
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-
xs
Merge<Omit<FlexBoxDefaultProps, "children" | "sx">, { sx?: CSSInterpolation; }> | undefined
-

AlertActionAreaButton

NameTypesdefaultValue
as
ElementType
-
variant
"normal" | "assistive" | "negative"
"normal"
children
ReactNode
-
disabled
boolean
-
sx
SxProp
-
xl
Merge<Pick<TextButtonDefaultProps, "size">, { sx?: CSSInterpolation; }> | undefined
-
lg
Merge<Pick<TextButtonDefaultProps, "size">, { sx?: CSSInterpolation; }> | undefined
-
md
Merge<Pick<TextButtonDefaultProps, "size">, { sx?: CSSInterpolation; }> | undefined
-
sm
Merge<Pick<TextButtonDefaultProps, "size">, { sx?: CSSInterpolation; }> | undefined
-
xs
Merge<Pick<TextButtonDefaultProps, "size">, { sx?: CSSInterpolation; }> | undefined
-
disableInteraction
boolean
-
leadingContent
ReactNode
-
trailingContent
ReactNode
-
loading
boolean
-
disableLoadingPreventEvents
boolean
-
size
"small" | "medium"
-

© 2026 Wanted Lab, Inc.