팝확인

팝확인 (Popconfirm)

사용자에게 확인을 요청하는 간단하고 컴팩트한 대화상자예요. 정적인 전체 화면 confirm 모달보다 가벼운 방식이에요.

출처: 문서

본문

언제 사용하나요 (When To Use)

  • 사용자 확인을 요청하는 간단하고 컴팩트한 대화상자로 사용해요.
  • 정적으로 뜨는 전체 화면 confirm 모달과 달리 더 가벼워요.

예시 (Examples)

기본 (Basic)

기본 예시는 confirmation의 title과 description props를 지원해요.

description은 버전 5.1.0부터 지원돼요.

import React from 'react';
import type { PopconfirmProps } from 'antd';
import { Button, message, Popconfirm } from 'antd';

const App: React.FC = () => {
  const [messageApi, holder] = message.useMessage();

  const confirm: PopconfirmProps['onConfirm'] = (e) => {
    console.log(e);
    messageApi.success('Click on Yes');
  };

  const cancel: PopconfirmProps['onCancel'] = (e) => {
    console.log(e);
    messageApi.error('Click on No');
  };

  return (
    <>
      {holder}
      <Popconfirm
        title="Delete the task"
        description="Are you sure to delete this task?"
        onConfirm={confirm}
        onCancel={cancel}
        okText="Yes"
        cancelText="No"
      >
        <Button danger>Delete</Button>
      </Popconfirm>
    </>
  );
};

export default App;

로케일 텍스트 (Locale text)

okText와 cancelText props로 버튼의 라벨을 커스터마이즈해요.

import React from 'react';
import { Button, Popconfirm } from 'antd';

const App: React.FC = () => (
  <Popconfirm
    title="Delete the task"
    description="Are you sure to delete this task?"
    okText="Yes"
    cancelText="No"
  >
    <Button danger>Delete</Button>
  </Popconfirm>
);

export default App;

배치 (Placement)

12가지 placement 옵션이 있어요. 화살표가 대상의 중앙을 가리키길 원한다면 arrow: { pointAtCenter: true }를 사용해요.

import React from 'react';
import { Button, ConfigProvider, Flex, Popconfirm } from 'antd';

const text = 'Are you sure to delete this task?';
const description = 'Delete the task';
const buttonWidth = 80;

const App: React.FC = () => (
  <ConfigProvider button={{ style: { width: buttonWidth, margin: 4 } }}>
    <Flex vertical justify="center" align="center" className="demo">
      <Flex justify="center" align="center" style={{ whiteSpace: 'nowrap' }}>
        <Popconfirm
          placement="topLeft"
          title={text}
          description={description}
          okText="Yes"
          cancelText="No"
        >
          <Button>TL</Button>
        </Popconfirm>
        <Popconfirm
          placement="top"
          title={text}
          description={description}
          okText="Yes"
          cancelText="No"
        >
          <Button>Top</Button>
        </Popconfirm>
        <Popconfirm
          placement="topRight"
          title={text}
          description={description}
          okText="Yes"
          cancelText="No"
        >
          <Button>TR</Button>
        </Popconfirm>
      </Flex>
      <Flex style={{ width: buttonWidth * 5 + 32 }} justify="space-between" align="center">
        <Flex align="center" vertical>
          <Popconfirm
            placement="leftTop"
            title={text}
            description={description}
            okText="Yes"
            cancelText="No"
          >
            <Button>LT</Button>
          </Popconfirm>
          <Popconfirm
            placement="left"
            title={text}
            description={description}
            okText="Yes"
            cancelText="No"
          >
            <Button>Left</Button>
          </Popconfirm>
          <Popconfirm
            placement="leftBottom"
            title={text}
            description={description}
            okText="Yes"
            cancelText="No"
          >
            <Button>LB</Button>
          </Popconfirm>
        </Flex>
        <Flex align="center" vertical>
          <Popconfirm
            placement="rightTop"
            title={text}
            description={description}
            okText="Yes"
            cancelText="No"
          >
            <Button>RT</Button>
          </Popconfirm>
          <Popconfirm
            placement="right"
            title={text}
            description={description}
            okText="Yes"
            cancelText="No"
          >
            <Button>Right</Button>
          </Popconfirm>
          <Popconfirm
            placement="rightBottom"
            title={text}
            description={description}
            okText="Yes"
            cancelText="No"
          >
            <Button>RB</Button>
          </Popconfirm>
        </Flex>
      </Flex>
      <Flex justify="center" align="center" style={{ whiteSpace: 'nowrap' }}>
        <Popconfirm
          placement="bottomLeft"
          title={text}
          description={description}
          okText="Yes"
          cancelText="No"
        >
          <Button>BL</Button>
        </Popconfirm>
        <Popconfirm
          placement="bottom"
          title={text}
          description={description}
          okText="Yes"
          cancelText="No"
        >
          <Button>Bottom</Button>
        </Popconfirm>
        <Popconfirm
          placement="bottomRight"
          title={text}
          description={description}
          okText="Yes"
          cancelText="No"
        >
          <Button>BR</Button>
        </Popconfirm>
      </Flex>
    </Flex>
  </ConfigProvider>
);

export default App;

자동 이동 (Auto Shift)

Popconfirm이 화면 가장자리에 가까워지면 팝업과 화살표 위치를 자동으로 조정해요. 제한을 초과하면 화면 밖으로 나갈 수 있어요.

import React from 'react';
import { Button, Popconfirm } from 'antd';

const style: React.CSSProperties = {
  width: '300vw',
  height: '300vh',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
};

const App: React.FC = () => {
  React.useEffect(() => {
    document.documentElement.scrollTop = document.documentElement.clientHeight;
    document.documentElement.scrollLeft = document.documentElement.clientWidth;
  }, []);
  return (
    <div style={style}>
      <Popconfirm title="Thanks for using antd. Have a nice day !" open>
        <Button type="primary">Scroll The Window</Button>
      </Popconfirm>
    </div>
  );
};

export default App;

조건부 트리거 (Conditional trigger)

어떤 조건에서만 팝업이 뜨게 할 수 있어요.

import React, { useState } from 'react';
import { Button, message, Popconfirm, Switch } from 'antd';

const App: React.FC = () => {
  const [messageApi, contextHolder] = message.useMessage();
  const [open, setOpen] = useState(false);
  const [condition, setCondition] = useState(true);

  const changeCondition = (checked: boolean) => {
    setCondition(checked);
  };

  const confirm = () => {
    setOpen(false);
    messageApi.success('Next step.');
  };

  const cancel = () => {
    setOpen(false);
    messageApi.error('Click on cancel.');
  };

  const handleOpenChange = (newOpen: boolean) => {
    if (!newOpen) {
      setOpen(newOpen);
      return;
    }
    // Determining condition before show the popconfirm.
    console.log(condition);
    if (condition) {
      confirm(); // next step
    } else {
      setOpen(newOpen);
    }
  };

  return (
    <>
      {contextHolder}
      <div>
        <Popconfirm
          title="Delete the task"
          description="Are you sure to delete this task?"
          open={open}
          onOpenChange={handleOpenChange}
          onConfirm={confirm}
          onCancel={cancel}
          okText="Yes"
          cancelText="No"
        >
          <Button danger>Delete a task</Button>
        </Popconfirm>
        <br />
        <br />
        Whether directly execute:
        <Switch defaultChecked onChange={changeCondition} />
      </div>
    </>
  );
};

export default App;

아이콘 커스터마이즈 (Customize icon)

icon props로 아이콘을 커스터마이즈해요.

import React from 'react';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { Button, Popconfirm } from 'antd';

const App: React.FC = () => (
  <Popconfirm
    title="Delete the task"
    description="Are you sure to delete this task?"
    icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
  >
    <Button danger>Delete</Button>
  </Popconfirm>
);

export default App;

비동기 닫기 (Asynchronously close)

OK 버튼을 눌렀을 때 Popconfirm을 비동기로 닫을 수 있어요. 예를 들어 폼을 제출할 때 이런 패턴을 사용할 수 있어요.

import React, { useState } from 'react';
import { Button, Popconfirm } from 'antd';

const App: React.FC = () => {
  const [open, setOpen] = useState(false);
  const [confirmLoading, setConfirmLoading] = useState(false);

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

  const handleOk = () => {
    setConfirmLoading(true);

    setTimeout(() => {
      setOpen(false);
      setConfirmLoading(false);
    }, 2000);
  };

  const handleCancel = () => {
    console.log('Clicked cancel button');
    setOpen(false);
  };

  return (
    <Popconfirm
      title="Title"
      description="Open Popconfirm with async logic"
      open={open}
      onConfirm={handleOk}
      okButtonProps={{ loading: confirmLoading }}
      onCancel={handleCancel}
    >
      <Button type="primary" onClick={showPopconfirm}>
        Open Popconfirm with async logic
      </Button>
    </Popconfirm>
  );
};

export default App;

Promise로 비동기 닫기 (Asynchronously close on Promise)

OK 버튼을 눌렀을 때 Popconfirm을 Promise로 비동기 닫을 수 있어요. 예를 들어 폼을 제출할 때 이런 패턴을 사용할 수 있어요.

import React from 'react';
import { Button, Popconfirm } from 'antd';

const App: React.FC = () => {
  const confirm = () =>
    new Promise((resolve) => {
      setTimeout(() => resolve(null), 3000);
    });

  return (
    <Popconfirm
      title="Title"
      description="Open Popconfirm with Promise"
      onConfirm={confirm}
      onOpenChange={() => console.log('open change')}
    >
      <Button type="primary">Open Popconfirm with Promise</Button>
    </Popconfirm>
  );
};

export default App;

시맨틱 DOM 스타일링 (Custom semantic dom styling)

classNames와 styles로 객체나 함수를 전달해 Popconfirm의 시맨틱 DOM 스타일을 커스터마이즈할 수 있어요.

import React from 'react';
import { Button, Flex, Popconfirm } from 'antd';
import type { GetProp, PopconfirmProps } from 'antd';
import { createStaticStyles } from 'antd-style';

const classNames = createStaticStyles(({ css }) => ({
  container: css`
    padding: 10px;
  `,
}));

const styles: PopconfirmProps['styles'] = {
  container: {
    backgroundColor: '#eee',
    boxShadow: 'inset 5px 5px 3px #fff, inset -5px -5px 3px #ddd, 0 0 3px rgba(0,0,0,0.2)',
  },
  title: {
    color: '#262626',
  },
  content: {
    color: '#262626',
  },
};

const stylesFn: PopconfirmProps['styles'] = (
  info,
): GetProp<PopconfirmProps, 'styles', 'Return'> => {
  if (!info.props.arrow) {
    return {
      container: {
        backgroundColor: 'rgba(53, 71, 125, 0.8)',
        padding: 12,
        borderRadius: 4,
      },
      title: {
        color: '#fff',
      },
      content: {
        color: '#fff',
      },
    };
  }
};

const App: React.FC = () => {
  return (
    <Flex gap="medium">
      <Popconfirm
        title="Object text"
        description="Object description"
        classNames={classNames}
        styles={styles}
        arrow={false}
      >
        <Button>Object Style</Button>
      </Popconfirm>
      <Popconfirm
        title="Function text"
        description="Function description"
        classNames={classNames}
        styles={stylesFn}
        arrow={false}
        okButtonProps={{
          styles: { root: { backgroundColor: 'rgba(53, 71, 125, 0.6)', color: '#fff' } },
        }}
        cancelButtonProps={{
          styles: {
            root: {
              borderColor: 'rgba(53, 71, 125, 0.6)',
              backgroundColor: '#fff',
              color: 'rgba(53, 71, 125, 0.8)',
            },
          },
        }}
      >
        <Button type="primary">Function Style</Button>
      </Popconfirm>
    </Flex>
  );
};

export default App;

API

공통 props는 Common props를 참고해요.

속성 (Property) 설명 (Description) 타입 (Type) 기본값 (Default) 버전 (Version) 글로벌 설정
cancelButtonProps 취소 버튼의 props ButtonProps - ×
cancelText 취소 버튼의 텍스트 string Cancel ×
disabled 자식 노드를 클릭했을 때 popconfirm을 보여 줄지 여부예요. boolean false ×
icon 확인 창의 아이콘을 커스터마이즈해요. ReactNode <ExclamationCircleFilled /> ×
okButtonProps 확인 버튼의 props ButtonProps - ×
okText 확인 버튼의 텍스트 string OK ×
okType 확인 버튼의 Button type string primary ×
showCancel 취소 버튼을 보여 줄지 여부예요. boolean true 4.18.0 ×
title 확인 상자의 제목 ReactNode | () => ReactNode - ×
description 확인 상자 제목의 설명 ReactNode | () => ReactNode - 5.1.0 ×
onCancel 취소 콜백 function(e) - ×
onConfirm 확인 콜백 function(e) - ×
onPopupClick 팝업 클릭 콜백 function(e) - 5.5.0 ×

공통 API는 Tooltip 문서의 공유 props를 참고해요. (shared props embed)

시맨틱 DOM (Semantic DOM)

시맨틱 DOM 구조는 https://ant.design/components/popconfirm/semantic.md 에서 확인할 수 있어요.

디자인 토큰 (Design Token)

컴포넌트 토큰 (Popconfirm) (Component Token)

토큰 이름 (Token Name) 설명 (Description) 타입 (Type) 기본값 (Default Value)
zIndexPopup Popconfirm의 z-index number 1060

글로벌 토큰 (Global Token)

토큰 이름 (Token Name) 설명 (Description) 타입 (Type) 기본값 (Default Value)
colorText W3C 표준을 따르는 기본 텍스트 색이에요. 가장 어두운 중성색이기도 해요. string
colorTextHeading 제목의 글자 색을 제어해요. string
colorWarning Notification, Alert 등 경고를 나타내는 map 토큰에 사용돼요. Alert나 Input 같은 컨트롤 컴포넌트도 이 map 토큰을 사용해요. string
fontSize 디자인 시스템에서 가장 널리 쓰이는 글자 크기로, 여기서 텍스트 그라데이션이 파생돼요. number
fontWeightStrong 제목 컴포넌트(h1, h2, h3 등)나 선택된 항목의 글자 굵기를 제어해요. number
marginXS 작은 크기의 요소 여백을 제어해요. number
marginXXS 가장 작은 크기의 요소 여백을 제어해요. number

FAQ

공통 FAQ는 Tooltip FAQ를 참고해요. 더 많은 질문은 Tooltip 문서를 확인해 주세요.

더 알아보기 (Learn more)