@promr-acorda/react
v0.6.7
Published
React UI for Promr Acorda electronic contract documents
Maintainers
Readme
@promr-acorda/react
@promr-acorda/core 문서를
다루는 React 뷰어 및 필드 편집 UI입니다. 필드 생성/이동/크기 조절(builder), 입력(fill),
서명(sign), 조회 전용(readonly) 모드와 서명/도장 입력 기능을 제공합니다.
설치
npm install @promr-acorda/react @promr-acorda/corepeer dependency로 react, react-dom(^18.2.0 || ^19.0.0)이 필요합니다.
빠른 시작
import { useState } from 'react';
import { ContractViewer } from '@promr-acorda/react';
import { createDocument, type ContractDocument } from '@promr-acorda/core';
function Viewer() {
const [doc, setDoc] = useState<ContractDocument>(() =>
createDocument({
id: 'contract-001',
title: '근로계약서',
pdfData: pdfBytes,
pageCount: 1,
pages: [{ index: 0, width: 612, height: 792 }],
})
);
return (
<ContractViewer
mode="fill"
document={doc}
onDocumentChange={setDoc}
pageWidth={900}
viewportHeight="80vh"
/>
);
}document.pdfData가 실제 PDF(이미지 기반 pageImages가 없는 경우)라면,
렌더링 전에 pdf.js worker를 한 번 설정해야 합니다. (설정하지 않으면 렌더링 시
에러가 발생합니다.)
import { configurePdfWorker } from '@promr-acorda/react';
configurePdfWorker('/pdf.worker.min.mjs');document.pageImages가 있으면(예: @promr-acorda/core의
createDocumentFromPdfData로 미리 렌더링한 이미지를 넣어둔 경우) 이미지 기반
렌더링을 우선 사용하므로 pdf.js worker 설정이 필요 없습니다.
모드
| 모드 | 설명 |
| --- | --- |
| builder | 필드 생성, 이동, 크기 조절 |
| fill | 필드 값 입력 |
| sign | 입력 + 서명/도장 입력 |
| readonly | 조회 전용 |
ContractViewer Props
| Prop | 타입 | 설명 |
| --- | --- | --- |
| mode | ContractMode | builder | fill | sign | readonly |
| document | ContractDocument | 렌더링할 문서 |
| onDocumentChange | (next) => void | 문서가 변경될 때마다 다음 문서를 전달받는 콜백 |
| onFieldValueChange? | (event) => void | 필드 값이 설정될 때 호출 |
| onFieldValueClear? | (event) => void | 필드 값이 제거될 때 호출 |
| onSignatureRequest? | (fieldId, mode) => void | 기본 서명/도장 입력 UI를 열어야 할 때 호출 |
| onStampRequest? | 아래 참고 | 기본 업로드 UI 대신 외부 도장 선택 흐름 연결 |
| pageWidth? | number | 렌더링 페이지 너비(px). 생략하면 뷰어 컨테이너 폭에 맞춰 자동 계산됩니다(240~1400px 범위) |
| viewportHeight? | number \| string | 뷰어 높이. 기본값 '80vh' |
| showPageNavigation? | boolean | 페이지 이동 UI 표시 여부 |
| showZoomBar? | boolean | 하단 줌 바 표시 여부. 기본값 true |
| pdfWorkerSrc? | string | pdf.js worker 경로 (configurePdfWorker 대신 사용 가능) |
| layoutMode? | 'pagination' \| 'scroll' | 아래 참고. 기본값 'pagination' |
| locale? | 'ko' \| 'en' | 기본값 'ko' |
| localeMessages? | Partial<TranslationMessages> | 특정 문구만 덮어쓰기 |
| className?, style? | - | 루트 엘리먼트에 적용 |
필드 텍스트는 실제 렌더링된 페이지 폭에 맞춰 함께 스케일되므로, 뷰어가
원본 크기로 표시되든(pageWidth 그대로) 화면이 작아 축소되든 항상 페이지 대비
비율이 유지됩니다.
layoutMode
'pagination'(기본값): 현재 선택된 페이지만 렌더링하고 페이지 네비게이션을 표시합니다.'scroll': 모든 페이지를 세로로 나열해서 보여주고, 화면 밖 페이지는 spacer로 대체 렌더링(가상화)해 렌더링 리소스를 절약합니다.
<ContractViewer mode="builder" document={doc} onDocumentChange={setDoc} layoutMode="scroll" />다국어(i18n)
기본 언어는 한국어('ko')이며, KO_MESSAGES/EN_MESSAGES를 내부에서
FieldBox, ContractCanvasPages 등 하위 컴포넌트에 일관되게 적용합니다.
<ContractViewer mode="fill" document={doc} onDocumentChange={setDoc} locale="en" />
// 일부 문구만 덮어쓰기
<ContractViewer
mode="fill"
document={doc}
onDocumentChange={setDoc}
locale="ko"
localeMessages={{ uploadStamp: '도장 첨부' }}
/>값 변경 처리
<ContractViewer
mode="sign"
document={doc}
onDocumentChange={setDoc}
onFieldValueChange={(event) => {
console.log(event.fieldId, event.value, event.nextDocument);
}}
onFieldValueClear={(event) => {
console.log('cleared', event.fieldId, event.nextDocument);
}}
onSignatureRequest={(fieldId, signatureMode) => {
console.log('signature requested', fieldId, signatureMode);
}}
/>외부 도장 선택 UI 연결 (onStampRequest)
onStampRequest는 signatureMode: 'stamp-only' 서명 필드의 도장 입력을
외부 앱(예: 등록된 도장 목록)에서 처리하기 위한 콜백입니다. 빈 상태의
Upload Stamp 버튼과 signatureActions.edit 액션에서 우선 호출됩니다.
type OnStampRequest = (
fieldId: string,
context: { field: ContractField; document: ContractDocument }
) =>
| Promise<ContractViewerBinaryImageInput | void>
| ContractViewerBinaryImageInput
| void;<ContractViewer
mode="sign"
document={doc}
onDocumentChange={setDoc}
onStampRequest={async (fieldId, { field, document }) => {
const selectedStamp = await openRegisteredStampPicker();
if (!selectedStamp) return; // 기본 업로드 UI로 fallback
return {
image: selectedStamp.bytes,
mimeType: selectedStamp.mimeType,
width: selectedStamp.width,
height: selectedStamp.height,
};
}}
/>반환값 처리 규칙:
- 이미지를 반환하면 뷰어가 내부적으로
setStampImage(fieldId, image)와 동일한 경로로 값을 저장하고, 기존과 동일하게onDocumentChange/onFieldValueChange를 호출합니다. void를 반환하거나 prop이 없으면 기존 파일 업로드 UI로 fallback합니다.- 콜백이 throw/reject되면 파일 업로드 UI로 fallback하지 않고 필드 위에 에러를 표시합니다.
- 같은 필드에 대해 요청이 이미 진행 중이면 중복 요청을 보내지 않습니다.
disabled,readonly, mirror 공유 필드처럼 편집할 수 없는 필드는 액션이 표시되지 않거나 동작하지 않습니다.
뷰어 Ref API
import { useRef } from 'react';
import { ContractViewer, type ContractViewerHandle } from '@promr-acorda/react';
const viewerRef = useRef<ContractViewerHandle>(null);
// 페이지 이동
viewerRef.current?.goToPage(2);
viewerRef.current?.nextPage();
viewerRef.current?.previousPage();
viewerRef.current?.getActivePageIndex();
viewerRef.current?.getPageCount();
// builder 모드에서 드래그로 필드 배치 시작/취소
viewerRef.current?.beginDragCreate('text', { placeholder: '이름 입력' });
viewerRef.current?.cancelDragCreate();
// 서명/도장 이미지 직접 주입
viewerRef.current?.setSignatureImage('employeeSignature', {
image: signaturePngBytes,
mimeType: 'image/png',
});
viewerRef.current?.setStampImage('employeeSignature', {
image: stampPngBytes,
mimeType: 'image/png',
});
// 서명/도장 구분 없이 필드 타입에 맞는 이미지 주입
viewerRef.current?.setFieldImage('employeeSignature', {
image: pngBytes,
mimeType: 'image/png',
});필드 표시 관련 세부 동작
- 텍스트 정렬/크기:
field.textAlign,field.textSize가 화면 렌더링에도 그대로 반영됩니다 (PDF export와 동일 기준). - 체크박스: 텍스트 대신 체크박스 아이콘으로 표시됩니다.
readonlyvsdisabled:readonly필드는 값만 표시하고,disabled필드는 테두리/placeholder 같은 입력 UI는 유지한 채 입력·이동·크기조절만 막습니다.- 공유 필드:
sharedMode: 'mirror'필드는 직접 입력할 수 없고source필드의 값을 따라갑니다.
그 외 내보낸 컴포넌트
ContractCanvasPages—ContractViewer내부에서 사용하는 캔버스 페이지 렌더러를 직접 제어해야 할 때 사용합니다.ContractPdfPages— pdf.js 기반 PDF 페이지 렌더링만 필요할 때 사용합니다.FieldBox— 단일 필드 오버레이 컴포넌트입니다.getDocumentPageCount(document),loadRenderedPage(document, pageIndex, signal?)— 페이지 렌더링을 직접 다룰 때 사용하는 저수준 유틸리티입니다.
라이선스
MIT
