diff --git a/README.md b/README.md index 087bf68..aa54898 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ const zpl = ZplLabel.print( ); ``` -자세한 내용은 [문서](https://boriguri.github.io/zpl-kit/)를 참고해 주세요. +자세한 내용은 [문서](https://bori-github.github.io/zpl-kit/)를 참고해 주세요. ## 프로젝트 구조 diff --git a/apps/react-zpl/README.md b/apps/react-zpl/README.md new file mode 100644 index 0000000..6f1d4e2 --- /dev/null +++ b/apps/react-zpl/README.md @@ -0,0 +1,116 @@ +# @zpl-kit/react-zpl + +ZPL(Zebra Programming Language) 라벨을 React 컴포넌트로 작성합니다. + +JSX로 라벨을 조립하면 프린터에 보낼 ZPL 문자열이 나옵니다. 화면에 렌더링하는 라이브러리가 아니라, **컴포넌트 트리를 ZPL로 변환**하는 라이브러리입니다. + +> **0.1.0-rc.1** — 릴리즈 후보입니다. 정식 전까지 공개 API가 바뀔 수 있습니다. + +## 설치 + +```bash +pnpm add @zpl-kit/react-zpl +``` + +React 18 또는 19가 필요합니다. `@zpl-kit/zpl-core`는 의존성으로 함께 설치됩니다. + +## 사용법 + +```tsx +import { ZplLabel, Text, Line, QrCode } from '@zpl-kit/react-zpl'; + +const zpl = ZplLabel.print( + + + 주문번호 A-1024 + + + + https://example.com/o/1024 + + +); +``` + +`zpl`에 담기는 값: + +``` +^XA^PW400^LL300...^XZ +``` + +좌표 단위는 **도트**입니다. 실제 크기는 프린터 해상도(dpmm)에 따라 달라집니다 — 203dpi(8dpmm) 프린터에서 `width: 400`은 50mm입니다. + +## `ZplLabel.print()` + +라벨을 ZPL 문자열로 바꾸는 진입점입니다. React DOM이 필요 없고 렌더링도 일어나지 않으므로, 서버·CLI·브라우저 어디서든 호출할 수 있습니다. + +`print()`에는 **`ZplLabel` 엘리먼트**를 넘겨야 합니다. 라벨을 컴포넌트로 나눠 쓸 때는 JSX 태그가 아니라 **함수를 호출**해서 넘기세요. + +```tsx +const OrderLabel = ({ orderNo }: { orderNo: string }) => ( + + + {orderNo} + + +); + +ZplLabel.print(OrderLabel({ orderNo: 'A-1024' })); // ✅ +ZplLabel.print(); // ❌ +``` + +> ⚠️ `print()`에 ``처럼 **감싼 컴포넌트를 넘기면 `^PWundefined`가 나옵니다.** `print()`가 넘겨받은 엘리먼트의 props에서 라벨 크기를 읽는데, 그 자리에 `OrderLabel`의 props가 들어오기 때문입니다. 예외 없이 조용히 잘못된 ZPL이 생성되고 타입 검사에도 걸리지 않으니 주의하세요. + +## 컴포넌트 + +| 컴포넌트 | ZPL | 용도 | +| -------------- | ----------- | ------------------------------------------- | +| `ZplLabel` | `^XA` `^XZ` | 라벨 루트. 크기·기본 폰트·인코딩을 정합니다 | +| `Text` | `^A` `^FD` | 텍스트 | +| `Line` | `^GB` | 수평·수직선 | +| `DiagonalLine` | `^GD` | 대각선 | +| `Circle` | `^GC` | 원 | +| `Ellipse` | `^GE` | 타원 | +| `QrCode` | `^BQ` | QR 코드 | + +`ZplLabel`의 주요 props: + +| 이름 | 타입 | 기본값 | 설명 | +| --------------------------------------- | -------- | ------ | --------------------- | +| `width` | `number` | 필수 | 라벨 폭 (도트) | +| `height` | `number` | 필수 | 라벨 길이 (도트) | +| `offsetX`, `offsetY` | `number` | `0` | 라벨 원점 이동 | +| `defaultFontName` | `string` | `'J'` | 기본 폰트 | +| `defaultFontWidth`, `defaultFontHeight` | `number` | `30` | 기본 폰트 크기 (도트) | + +`Text`·`QrCode`는 내용을 children으로 받습니다. 나머지는 props만 씁니다. + +## 검증 + +프린터가 받아주지 않을 값은 `print()` 시점에 `Error`를 던집니다. + +```tsx +ZplLabel.print( + + + +); +// Error: renderCircle: diameter는 3~4095 사이여야 합니다. (diameter=5000) +``` + +## zpl-core와의 관계 + +이 패키지는 [`@zpl-kit/zpl-core`](https://www.npmjs.com/package/@zpl-kit/zpl-core)의 JSX 어댑터입니다. ZPL 생성은 전부 코어가 담당하고, 같은 라벨은 **양쪽에서 동일한 ZPL**을 냅니다. + +React 없이 쓰거나, 렌더러·커맨드 계층을 직접 다루고 싶다면 코어를 쓰세요. + +## 문서 + +- [가이드](https://bori-github.github.io/zpl-kit/guide/react-zpl-getting-started) +- [컴포넌트](https://bori-github.github.io/zpl-kit/guide/react-zpl-components) +- [API 레퍼런스](https://bori-github.github.io/zpl-kit/guide/react-zpl-api/zpl-label) +- [ZPL 미리보기](https://zpl-kit-viewer.vercel.app/) — 생성한 ZPL을 브라우저에서 확인 + +## 라이선스 + +MIT diff --git a/apps/react-zpl/package.json b/apps/react-zpl/package.json index 138c8f9..4707b3c 100644 --- a/apps/react-zpl/package.json +++ b/apps/react-zpl/package.json @@ -3,7 +3,7 @@ "version": "0.1.0-rc.1", "author": "boriguri ", "license": "MIT", - "homepage": "https://boriguri.github.io/zpl-kit/", + "homepage": "https://bori-github.github.io/zpl-kit/", "repository": { "type": "git", "url": "https://github.com/Bori-github/zpl-kit.git", diff --git a/apps/zpl-core/README.md b/apps/zpl-core/README.md new file mode 100644 index 0000000..30a5cab --- /dev/null +++ b/apps/zpl-core/README.md @@ -0,0 +1,143 @@ +# @zpl-kit/zpl-core + +ZPL(Zebra Programming Language) 라벨을 코드로 만드는 프레임워크 비의존 라이브러리입니다. + +라벨을 일반 객체로 기술하면 프린터에 보낼 ZPL 문자열이 나옵니다. 런타임 의존성이 없고 Node.js·브라우저 어디서나 동작합니다. + +React를 쓰신다면 [`@zpl-kit/react-zpl`](https://www.npmjs.com/package/@zpl-kit/react-zpl)이 이 패키지를 감싼 JSX 인터페이스를 제공합니다. + +## 설치 + +```bash +pnpm add @zpl-kit/zpl-core +``` + +## 사용법 + +```ts +import { renderLabel } from '@zpl-kit/zpl-core'; + +const zpl = renderLabel({ + type: 'label', + props: { width: 400, height: 300 }, + children: [ + { type: 'text', props: { text: '주문번호 A-1024', fieldOriginX: 20, fieldOriginY: 20 } }, + { + type: 'line', + props: { direction: 'horizontal', length: 360, fieldOriginX: 20, fieldOriginY: 60 }, + }, + { + type: 'qrCode', + props: { + text: 'https://example.com/o/1024', + fieldOriginX: 20, + fieldOriginY: 80, + magnification: 5, + }, + }, + ], +}); +``` + +`zpl`에 담기는 값: + +``` +^XA^PW400^LL300...^XZ +``` + +좌표 단위는 **도트**입니다. 실제 크기는 프린터 해상도(dpmm)에 따라 달라집니다 — 203dpi(8dpmm) 프린터에서 `width: 400`은 50mm입니다. + +## 라벨 구조 + +`renderLabel`은 루트 노드 하나를 받습니다. + +```ts +{ + type: 'label', + props: LabelCoreProps, + children: ChildLabelNode[] +} +``` + +`props`에서 자주 쓰는 값: + +| 이름 | 타입 | 기본값 | 설명 | +| --------------------------------------- | ------------- | ------------- | --------------------- | +| `width` | `number` | 필수 | 라벨 폭 (도트) | +| `height` | `number` | 필수 | 라벨 길이 (도트) | +| `offsetX`, `offsetY` | `number` | `0` | 라벨 원점 이동 | +| `labelOrientation` | `ORIENTATION` | `NO_ROTATION` | 라벨 전체 회전 | +| `defaultFontName` | `string` | `'J'` | 기본 폰트 | +| `defaultFontWidth`, `defaultFontHeight` | `number` | `30` | 기본 폰트 크기 (도트) | + +`children`에 넣을 수 있는 노드는 6종입니다. + +| `type` | 렌더러 | ZPL | +| -------------- | -------------------- | ---------- | +| `text` | `renderText` | `^A` `^FD` | +| `line` | `renderLine` | `^GB` | +| `diagonalLine` | `renderDiagonalLine` | `^GD` | +| `circle` | `renderCircle` | `^GC` | +| `ellipse` | `renderEllipse` | `^GE` | +| `qrCode` | `renderQrCode` | `^BQ` | + +각 렌더러는 개별로도 호출할 수 있습니다. 조합을 직접 제어하고 싶을 때 씁니다. + +```ts +import { createLabelContext, renderText } from '@zpl-kit/zpl-core'; + +const context = createLabelContext({ width: 400, height: 300 }); +const field = renderText({ text: 'hello', fieldOriginX: 10, fieldOriginY: 10 }, context); +``` + +`renderText`·`renderQrCode`는 라벨의 기본 폰트·방향을 상속받으므로 두 번째 인자로 컨텍스트를 받습니다. 나머지 렌더러는 props만 받습니다. + +## 커맨드 계층 + +렌더러보다 낮은 층에서 ZPL 커맨드를 직접 만들 수도 있습니다. 렌더러가 다루지 않는 조합이 필요할 때 씁니다. + +```ts +import { startFormat, printWidth, fieldOrigin, fieldData, endFormat } from '@zpl-kit/zpl-core'; + +const zpl = [ + startFormat(), + printWidth(400), + fieldOrigin({ offsetX: 10, offsetY: 10 }), + fieldData('hello'), + endFormat(), +].join(''); +// ^XA^PW400^FO10,10^FDhello...^XZ +``` + +지원하는 커맨드 17개: + +`^XA` `^XZ` `^PW` `^LL` `^LH` `^FO` `^FD` `^FB` `^FW` `^A` `^CF` `^CI` `^GB` `^GC` `^GD` `^GE` `^BQ` + +> ZPL 명세 전체를 덮지는 않습니다. 위 목록에 없는 커맨드는 아직 지원하지 않습니다. + +## 상수 + +문자열 리터럴 대신 상수를 쓰면 오타를 컴파일 단계에서 잡습니다. + +```ts +import { ALIGN, COLOR, ORIENTATION, DIAGONAL_ORIENTATION } from '@zpl-kit/zpl-core'; +``` + +## 검증 + +렌더러는 프린터가 받아주지 않을 값을 미리 막습니다. 범위를 벗어나면 `Error`를 던집니다. + +```ts +renderCircle({ diameter: 5000, fieldOriginX: 0, fieldOriginY: 0 }); +// Error: renderCircle: diameter는 3~4095 사이여야 합니다. (diameter=5000) +``` + +## 문서 + +- [가이드](https://bori-github.github.io/zpl-kit/guide/zpl-core-getting-started) +- [API 레퍼런스](https://bori-github.github.io/zpl-kit/guide/zpl-core-api/render-label) +- [ZPL 미리보기](https://zpl-kit-viewer.vercel.app/) — 생성한 ZPL을 브라우저에서 확인 + +## 라이선스 + +MIT diff --git a/apps/zpl-core/package.json b/apps/zpl-core/package.json index 6c824f5..7f5ba3b 100644 --- a/apps/zpl-core/package.json +++ b/apps/zpl-core/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "author": "boriguri ", "license": "MIT", - "homepage": "https://boriguri.github.io/zpl-kit/", + "homepage": "https://bori-github.github.io/zpl-kit/", "repository": { "type": "git", "url": "https://github.com/Bori-github/zpl-kit.git", diff --git a/docs/docs/index.mdx b/docs/docs/index.mdx index fe07a65..f29a658 100644 --- a/docs/docs/index.mdx +++ b/docs/docs/index.mdx @@ -10,7 +10,7 @@ head: content: 'Core primitives for Node.js, declarative components for React.' - - meta - property: og:url - content: 'https://boriguri.github.io/zpl-kit/' + content: 'https://bori-github.github.io/zpl-kit/' hero: name: '@zpl-kit' diff --git a/docs/rspress.config.ts b/docs/rspress.config.ts index a7db225..6ad064e 100644 --- a/docs/rspress.config.ts +++ b/docs/rspress.config.ts @@ -28,7 +28,7 @@ export default defineConfig({ 'Core primitives for Node.js, declarative components for React. Build and preview ZPL labels.', }, ], - ['meta', { property: 'og:url', content: 'https://boriguri.github.io/zpl-kit/' }], + ['meta', { property: 'og:url', content: 'https://bori-github.github.io/zpl-kit/' }], // Twitter Card ['meta', { name: 'twitter:card', content: 'summary' }], ['meta', { name: 'twitter:title', content: '@zpl-kit — Composable ZPL for modern JavaScript' }], diff --git a/package.json b/package.json index ae7aa5f..6702e69 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "author": "boriguri ", "license": "MIT", - "homepage": "https://boriguri.github.io/zpl-kit/", + "homepage": "https://bori-github.github.io/zpl-kit/", "repository": { "type": "git", "url": "https://github.com/Bori-github/zpl-kit.git"