npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

crossviewer-react

v1.0.1

Published

React component for CrossViewer document viewer

Readme

React CrossViewer

Namo CrossViewer의 React 지원 버전입니다.

소개

crossviewer-react는 Namo CrossViewer 문서 뷰어를 React 애플리케이션에서 쉽게 사용할 수 있도록 제공하는 컴포넌트 래퍼입니다. CrossViewer 컴포넌트와 useCrossViewer 훅을 통해 문서 뷰어를 간편하게 통합할 수 있습니다.

React Support

reactreact-dom 모듈이 설치되지 않았다면, 설치단계에서 react 관련 의존 모듈 미설치에 관한 경고가 발생하게 됩니다. reactreact-dom 설치 방법은 다음과 같습니다.

> npm install react react-dom --save

crossviewer-react 패키지는 react 18 버전 이상에서 지원됩니다.

TypeScript Support

crossviewer-react 패키지는 타입스크립트를 지원합니다. 다음 타입들을 제공합니다:

  • CrossViewerProps, CrossViewerHandle, CrossViewerEventCallbacks
  • UseCrossViewerReturn, ViewerConfig
  • OpenPayload, 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

CrossViewerHandleref를 통해 뷰어 인스턴스를 제어할 수 있는 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를 참고하시기 바랍니다.