crossviewer-react
v1.0.1
Published
React component for CrossViewer document viewer
Maintainers
Readme
React CrossViewer
Namo CrossViewer의 React 지원 버전입니다.
소개
crossviewer-react는 Namo CrossViewer 문서 뷰어를 React 애플리케이션에서 쉽게 사용할 수 있도록 제공하는 컴포넌트 래퍼입니다. CrossViewer 컴포넌트와 useCrossViewer 훅을 통해 문서 뷰어를 간편하게 통합할 수 있습니다.
React Support
react 및 react-dom 모듈이 설치되지 않았다면, 설치단계에서 react 관련 의존 모듈 미설치에 관한 경고가 발생하게 됩니다. react 및 react-dom 설치 방법은 다음과 같습니다.
> npm install react react-dom --savecrossviewer-react 패키지는 react 18 버전 이상에서 지원됩니다.
TypeScript Support
crossviewer-react 패키지는 타입스크립트를 지원합니다. 다음 타입들을 제공합니다:
CrossViewerProps,CrossViewerHandle,CrossViewerEventCallbacksUseCrossViewerReturn,ViewerConfigOpenPayload,ErrorPayload,PageChangedPayload,SizeChangedPayload,PageThumbnailPayload
설치
React 환경에서 뷰어 컴포넌트를 생성하기 위해, crossviewer-react 패키지를 아래의 방법과 같이 설치할 수 있습니다.
> npm install crossviewer-react --save--save 옵션을 활용하여 향후 의존 모듈을 재설치할 때에도 자동으로 설치하도록 권장합니다. 설치 후 package.json 파일에 다음과 같이 crossviewer-react 모듈이 추가됩니다.
{
"dependencies": {
"crossviewer-react": "^1.x.x"
}
}CrossViewer 스크립트 설정
크로스뷰어 스크립트는 별도로 제공되며 crossviewer-react에는 크로스뷰어 스크립트 파일이 포함되어 있지 않습니다.
크로스뷰어에 방문하여 크로스뷰어 제품 체험판을 받아볼 수 있습니다.
제공된 크로스뷰어 스크립트는 설치할 프로젝트 폴더의 public 경로 안으로 설치할 수 있습니다.
Copy to the React public subdirectory.
ex) /example/basic/public/crossviewer기본 경로
crossviewer-react는 스크립트 및 설정 파일에 대해 다음과 같은 기본 경로를 사용합니다. 크로스뷰어 스크립트를 public/crossviewer 경로에 설치했다면 별도의 경로 설정 없이 바로 사용할 수 있습니다.
| props | 기본값 |
|-------|--------|
| crossviewerScriptUrl | /crossviewer/js/crossviewer.js |
| engineScriptUrl | /crossviewer/lib/crepas-viewer.min.js |
| configUrl | /crossviewer/config/config.json |
| viewerInfoUrl | /crossviewer/config/viewerInfo.json |
참고:
engineScriptUrl에 필요한clientId파라미터는viewerInfoUrl에서 지정한viewerInfo.json파일에서 자동으로 읽어와 엔진 스크립트 URL에 추가됩니다.
기본 경로와 다른 위치에 스크립트를 설치한 경우, 해당 props를 통해 경로를 직접 지정할 수 있습니다:
<CrossViewer
crossviewerScriptUrl="/custom/path/crossviewer.js"
engineScriptUrl="/custom/path/crepas-viewer.min.js"
configUrl="/custom/path/config.json"
viewerInfoUrl="/custom/path/viewerInfo.json"
/>사용법 - CrossViewer 컴포넌트
설치가 완료되었다면, CrossViewer를 임포트하여 사용할 수 있습니다.
import { useRef, useState } from 'react';
import { CrossViewer, type CrossViewerHandle } from 'crossviewer-react';
function App() {
const viewerRef = useRef<CrossViewerHandle>(null);
const [status, setStatus] = useState('뷰어 로딩 중...');
const [pageInfo, setPageInfo] = useState('');
return (
<div style={{ width: '100%', height: '100%' }}>
<CrossViewer
ref={viewerRef}
lang="kor"
onOpen={(payload) => {
if (payload.result > 0) {
setStatus(`문서 열림 (${payload.totalPages}페이지)`);
} else {
setStatus('문서 열기 실패');
}
}}
onOpenCompleted={() => {
setStatus((prev) => prev + ' - 렌더링 완료');
}}
onError={(payload) => {
setStatus(`에러: ${payload.message}`);
}}
onPageChanged={(info) => {
setPageInfo(`${info.page} / ${info.totalPages}`);
}}
onZoomChanged={(scale) => {
console.log('zoom:', scale);
}}
style={{ width: '100%', height: '100%' }}
/>
</div>
);
}
export default App;사용법 - useCrossViewer 훅
useCrossViewer 훅을 사용하면 뷰어의 ref, 준비 상태, 에러 상태를 간편하게 관리할 수 있습니다.
import { useCrossViewer } from 'crossviewer-react';
function App() {
const { ref, isReady, error } = useCrossViewer({
containerId: 'my-viewer',
lang: 'kor',
onPageChanged: (info) => console.log(info),
});
const handleOpenUrl = () => {
ref.current?.open.url('/documents/sample.pdf');
};
return (
<div>
{error && <p>에러: {error.message}</p>}
{!isReady && <p>뷰어 준비 중...</p>}
<div id="my-viewer" style={{ width: '100%', height: '600px' }} />
<button onClick={handleOpenUrl} disabled={!isReady}>
문서 열기
</button>
</div>
);
}Props
CrossViewerProps
| 속성 | 타입 | 필수 | 설명 |
|------|------|------|------|
| crossviewerScriptUrl | string | - | crossviewer.js 번들 경로 (스크립트 태그로 로드) |
| engineScriptUrl | string | - | crepas-viewer.min.js WASM 엔진 스크립트 경로 |
| instanceName | string | - | 멀티 인스턴스 구분용 이름 |
| className | string | - | 컨테이너 div className |
| style | CSSProperties | - | 컨테이너 div style |
| lang | string | - | 언어 설정 ('kor', 'enu', 'jpn', 'chs', 'cht', 'vit', 'ind', 'fra', 'auto') |
| theme | string | - | 테마 ('light', 'dark') |
| documentType | string | - | 문서 타입 |
| panel | object | - | 패널 설정 (useThumbnailPanel, initialThumbailPanel) |
| searchEnabled | boolean | - | 텍스트 검색 활성화 |
| downloadEnabled | boolean | - | 다운로드 활성화 |
| printEnabled | boolean | - | 인쇄 활성화 |
| initialScaleValue | Record<string, string> | - | 초기 줌 레벨 |
| scaleIncrement | number | - | 줌 증가 단위 |
| allowedFileExtensions | string[] | - | 허용 파일 확장자 목록 |
| allowFileUrlOpen | boolean | - | URL을 통한 파일 열기 허용 |
| fileStreamUrl | string | - | 파일 스트림 URL |
| configUrl | string | - | 설정 파일 경로 |
| instanceConfigUrl | string | - | 인스턴스 설정 파일 경로 |
| mobileConfigUrl | string | - | 모바일 설정 파일 경로 |
| mobileInstanceConfigUrl | string | - | 모바일 인스턴스 설정 파일 경로 |
| viewerInfoUrl | string | - | 뷰어 정보 파일 경로 |
| urlParams | Record<string, string> | - | URL 파라미터 |
| pageTransitionDirection | string | - | 페이지 전환 방향 ('vertical', 'horizontal') |
이벤트 콜백
CrossViewerEventCallbacks
| 콜백 | 파라미터 | 설명 |
|------|----------|------|
| onOpen | (payload: OpenPayload) => void | 문서 열기 결과 (성공/실패, 페이지 수) |
| onOpenCompleted | () => void | 문서 렌더링 완전 완료 (썸네일 포함) |
| onError | (payload: ErrorPayload) => void | 뷰어 에러 발생 |
| onPageChanged | (payload: PageChangedPayload) => void | 페이지 이동 |
| onZoomChanged | (scale: number) => void | 줌 레벨 변경 |
| onStateChange | (state: unknown) => void | 뷰어 전체 상태 변경 |
| onFindText | (status: number) => void | 텍스트 검색 결과 상태 |
| onSizeChanged | (payload: SizeChangedPayload) => void | 캔버스 크기 변경 |
| onPageThumbnail | (payload: PageThumbnailPayload) => void | 썸네일 렌더링 완료 |
이벤트 페이로드 타입
| 타입 | 필드 | 설명 |
|------|------|------|
| OpenPayload | result: number, page?: number, totalPages?: number | 문서 열기 결과 정보 |
| ErrorPayload | message: string | 에러 메시지 |
| PageChangedPayload | page: number, totalPages: number | 현재 페이지 및 전체 페이지 수 |
| SizeChangedPayload | width: number, height: number | 캔버스 크기 |
| PageThumbnailPayload | page: number, width: number, height: number | 썸네일 페이지 및 크기 |
Ref Handle API
CrossViewerHandle은 ref를 통해 뷰어 인스턴스를 제어할 수 있는 API를 제공합니다.
| 메서드 | 시그니처 | 설명 |
|--------|----------|------|
| open.url | (url: string) => Promise<boolean> | URL을 통해 문서 열기 |
| open.stream | (fileId: string) => Promise<boolean> | 파일 ID로 스트림 문서 열기 |
| open.streamURL | (url: string) => Promise<boolean> | URL로 스트림 문서 열기 |
| destroy | () => void | 뷰어 인스턴스 정리 |
| showLoading | (show: boolean) => void | 로딩 표시 제어 |
| showError | (args: { message: string }) => void | 에러 메시지 표시 |
| getInstance | () => unknown \| null | 내부 CrossViewer 인스턴스 직접 접근 (escape hatch) |
const viewerRef = useRef<CrossViewerHandle>(null);
// URL로 문서 열기
await viewerRef.current?.open.url('/documents/sample.pdf');
// 스트림으로 문서 열기
await viewerRef.current?.open.stream('file-id-123');
// 로딩 표시
viewerRef.current?.showLoading(true);
// 인스턴스 정리
viewerRef.current?.destroy();Documentation and Example
crossviewer-react의 사용 예제와 가이드를 제공합니다.
/example/README.md| 예제 | 경로 | 설명 |
|------|------|------|
| basic | /example/basic | JavaScript 기본 사용 예제 |
| basic-typescript | /example/basic-typescript | TypeScript 기본 사용 예제 |
| component-events-onLoaded | /example/component-events-onLoaded | onLoaded 이벤트 콜백 예제 |
| component-events-ref | /example/component-events-ref | ref를 통한 이벤트 제어 예제 |
| hook-events | /example/hook-events | useCrossViewer 훅 사용 예제 |
| router | /example/router | React Router 연동 예제 |
| server-side-rendering | /example/server-side-rendering | SSR(서버 사이드 렌더링) 예제 |
주의 사항
설정 변경 시 key prop 사용
lang, theme 등 설정 props는 마운트 시점에만 적용됩니다. 런타임에 설정을 변경하려면 key prop을 변경하여 컴포넌트를 다시 마운트하세요.
const [lang, setLang] = useState<'kor' | 'enu'>('kor');
<CrossViewer
key={lang} // lang 변경 시 재마운트
lang={lang}
// ...기타 props
/>라이선스
크로스뷰어의 자세한 옵션은 Namo CrossEditor를 참고하시기 바랍니다.
