Skip to content

UI API ​

POS 플러그인에서 제공하는 UI 컴포넌트 API예요. 바코드 스캔 팝업과 입력·안내 모달을 제공해요.

import 방식

ui는 posPluginSdk의 프로퍼티가 아닌 독립 export예요.

ts
import { ui } from '@tossplace/pos-plugin-sdk';

Types ​

ModalPageRequest ​

openModal에 전달하는 모달 구성이에요.

필드타입필수설명
titlestringO모달 제목
stepstringO모달을 구분하는 ID
descriptionstringX제목 아래에 표시할 설명
cta.submitModalCtaO제출 버튼
cta.cancelModalCtaX취소 버튼
elementsArray<ModalInputElement|ModalDescriptionElement>O모달에 표시할 요소. 배열 순서대로 표시돼요
onSubmit(form: ModalForm) => Promise<T>X제출 버튼을 누르면 실행돼요. 반환값이 ModalOpenResponse의 form으로 전달돼요. 에러가 발생하면 Alert이 표시되고 모달이 유지돼요. 생략하면 사용자가 입력한 값이 그대로 form으로 전달돼요. 자세한 동작은 onSubmit 동작을 참고해주세요

ModalForm은 Record<string, string | string[] | number | undefined>예요.

ModalCta ​

필드타입필수설명
textstringO버튼 문구
type'primary' | 'danger' | 'dark'O버튼 스타일

ModalInputElement ​

사용자 입력을 받는 요소예요. 모든 입력 요소에 category: 'input'과 id를 넣어요.

agreement를 제외한 입력 요소는 아래 공통 필드를 가져요.

필드타입필수설명
labelstringO입력 요소 이름
requiredbooleanO필수 입력 여부
errorMessagestringX값을 넣으면 해당 입력 요소가 오류 상태로 표시돼요

text ​

필드타입필수설명
type'text'O
defaultstringO기본값
placeholderstringX입력 전 안내 문구
suffixstringX입력값 뒤에 붙는 단위 문구

number ​

필드타입필수설명
type'number'O
defaultnumberO기본값
placeholderstringX입력 전 안내 문구
suffixstringX입력값 뒤에 붙는 단위 문구

password ​

필드타입필수설명
type'password'O
defaultstringO기본값
placeholderstringX입력 전 안내 문구

radio ​

하나를 선택해요. 선택된 항목의 values[].id가 string으로 반환돼요.

필드타입필수설명
type'radio'O
defaultstringO기본으로 선택할 values[].id
values{ id: string; title: string; description?: string }[]O선택지

checkbox ​

여러 개를 선택해요. 선택된 항목의 values[].id가 string[]로 반환돼요.

필드타입필수설명
type'checkbox'O
defaultstring[]O기본으로 선택할 values[].id 배열
values{ id: string; title: string; description?: string }[]O선택지

agreement ​

약관 동의를 받아요. 동의한 약관의 agreements[].id가 string[]로 반환돼요. 공통 필드(label, required, errorMessage)가 없어요.

필드타입필수설명
type'agreement'O
defaultstring[]O기본으로 동의 처리할 agreements[].id 배열
agreements[].idstringO약관 ID
agreements[].titlestringO약관 제목
agreements[].requiredbooleanO필수 약관 여부
agreements[].contentsstring[]O약관 본문

ModalDescriptionElement ​

안내를 표시하는 요소예요. 모든 설명 요소에 category: 'description'과 id를 넣어요.

type추가 필드설명
'image'url: string이미지를 표시해요
'text'text: string, style: { weight: 'regular' | 'medium' | 'bold'; size: number }텍스트를 표시해요
'ordered-text'text: string, subText: string, index: 1 ~ 9번호가 붙은 텍스트를 표시해요
'qna'question: string, answer: string질문과 답변을 표시해요
'horizontal-divider'-가로 구분선을 표시해요

ModalOpenResponse ​

ts
{
    event: 'SUBMITTED';
    form: T;             // onSubmit의 반환값. onSubmit이 없으면 입력값
} | {
    event: 'CANCELLED' | 'CLOSED';
}
필드타입설명
event'SUBMITTED' | 'CANCELLED' | 'CLOSED'모달 종료 결과. 사용자가 취소하거나 닫으면 'CANCELLED' 또는 'CLOSED'예요
formTonSubmit의 반환값이에요. onSubmit이 없으면 사용자가 입력한 값(ModalForm)이에요. event가 'SUBMITTED'일 때만 있어요

Methods ​

openBarcode ​

바코드 스캔 팝업을 표시해요.

ts
import { ui } from '@tossplace/pos-plugin-sdk';

const result = await ui.openBarcode({
    productName: '토스 POS 플러그인', // 팝업 왼쪽 상단에 표시
});

if (result.result === 'SUCCESS') {
    console.log('스캔된 바코드:', result.barcode);
} else {
    console.log('사용자가 취소했어요');
}

Parameters ​

파라미터타입필수설명
productNamestringO팝업 왼쪽 상단에 표시할 이름

Response ​

ts
{
    barcode: string;     // 스캔된 바코드 값
    result: 'SUCCESS';
} | {
    result: 'CANCELLED'; // 사용자 취소
}
필드타입설명
result'SUCCESS' | 'CANCELLED'스캔 결과. 사용자가 취소하면 'CANCELLED'예요
barcodestring스캔된 바코드 값. result가 'SUCCESS'일 때만 있어요

openModal ​

입력 요소와 안내 요소로 구성한 모달을 표시해요. 제출 버튼을 누르면 onSubmit이 실행되고, 성공하면 반환값과 함께 모달이 닫혀요. onSubmit에서 에러가 발생하면 Alert이 표시되고 모달은 닫히지 않아서, 사용자가 값을 고쳐 다시 제출할 수 있어요.

ts
import { ui } from '@tossplace/pos-plugin-sdk';

const result = await ui.openModal({
    title: '회원 정보 입력',
    step: 'member-info',
    description: '포인트를 적립할 회원의 휴대폰 번호를 입력해주세요',
    cta: {
        cancel: { text: '취소', type: 'dark' },
        submit: { text: '확인', type: 'primary' },
    },
    elements: [
        {
            category: 'input',
            id: 'phone',
            type: 'text',
            label: '휴대폰 번호',
            required: true,
            default: '',
            placeholder: '01012345678',
        },
        {
            category: 'input',
            id: 'terms',
            type: 'agreement',
            default: [],
            agreements: [
                {
                    id: 'privacy',
                    title: '개인정보 수집·이용 동의',
                    required: true,
                    contents: ['포인트 적립을 위해 휴대폰 번호를 수집해요.'],
                },
            ],
        },
    ],
    onSubmit: async (form) => {
        const phone = String(form.phone);
        if (!/^01\d{8,9}$/.test(phone)) {
            throw new Error('휴대폰 번호를 확인해주세요'); // Alert이 표시되고 모달은 닫히지 않아요
        }
        return { phone };
    },
});

if (result.event === 'SUBMITTED') {
    console.log('입력된 휴대폰 번호:', result.form.phone);
} else {
    console.log('사용자가 모달을 닫았어요');
}

onSubmit 동작 ​

제출 버튼을 누르면 onSubmit이 입력값(form)을 받아 실행돼요. 결과에 따라 아래처럼 동작해요.

경우모달openModal 응답
onSubmit이 값을 반환닫혀요{ event: 'SUBMITTED', form: 반환값 }
onSubmit에서 에러 발생닫히지 않아요. 에러 메시지가 Alert으로 표시돼요아직 반환하지 않아요
onSubmit 생략닫혀요{ event: 'SUBMITTED', form: 입력값 }
에러가 발생하면 ​

위 예시에서 휴대폰 번호 형식이 맞지 않으면 throw new Error('휴대폰 번호를 확인해주세요')가 실행돼요. 이때 다음 순서로 동작해요.

  1. 에러의 message인 "휴대폰 번호를 확인해주세요"가 Alert으로 표시돼요.
  2. 모달은 닫히지 않아요. openModal도 응답을 반환하지 않고 기다려요.
  3. 사용자가 값을 고쳐 제출 버튼을 다시 누르면 onSubmit이 다시 실행돼요. 이번에 값을 반환하면 모달이 닫히고 openModal이 SUBMITTED를 반환해요.
  4. 사용자가 다시 제출하지 않고 취소하거나 닫으면 openModal이 CANCELLED 또는 CLOSED를 반환해요.

입력값 검증이나 서버 저장처럼 실패했을 때 사용자가 다시 시도해야 하는 작업은 onSubmit 안에서 처리하고, 실패하면 사용자에게 보여줄 메시지와 함께 에러를 던지세요.

onSubmit이 없으면 ​

onSubmit은 선택 항목이에요. 넣지 않거나 undefined를 넣으면 아래처럼 동작해요.

  • 제출 버튼을 누르면 실행할 핸들러 없이 바로 모달이 닫혀요.
  • openModal은 { event: 'SUBMITTED', form: 입력값 }을 반환해요. 사용자가 입력한 값이 ModalForm 형태로 그대로 전달돼요.
  • 핸들러가 없으니 에러가 발생할 일도 없고, 제출 버튼을 누르면 항상 모달이 닫혀요.

별도 검증 없이 입력값만 받으면 되는 모달이라면 onSubmit 없이 쓸 수 있어요.

ts
import { ui } from '@tossplace/pos-plugin-sdk';

const result = await ui.openModal({
    title: '메모 입력',
    step: 'memo',
    cta: {
        submit: { text: '확인', type: 'primary' },
    },
    elements: [
        {
            category: 'input',
            id: 'memo',
            type: 'text',
            label: '메모',
            required: false,
            default: '',
        },
    ],
});

if (result.event === 'SUBMITTED') {
    console.log('입력된 메모:', result.form.memo);
}
모달마다 다른 step을 사용해주세요 ​

onSubmit은 step 값을 기준으로 등록돼요. 같은 step으로 openModal을 다시 호출하면 이전에 등록한 onSubmit을 덮어쓰니, 모달마다 서로 다른 step을 넣어주세요.

Parameters ​

파라미터타입필수설명
pageModalPageRequestO표시할 모달 구성

Response ​

Promise<ModalOpenResponse>를 반환해요.

openInputModal은 deprecated 됐어요

0.0.30부터 openInputModal은 deprecated 됐어요. 입력 모달이 필요하면 openModal을 사용해주세요.