From 5fa9c36c82ec3964a3b08d4764f9aa016552da76 Mon Sep 17 00:00:00 2001 From: Bori-github Date: Fri, 17 Jul 2026 16:43:59 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix(docs):=20=EB=AC=B8=EC=84=9C=20=EC=82=AC?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95=20(boriguri=20=E2=86=92=20bori-g?= =?UTF-8?q?ithub)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 계정명이 Bori-github이라 Pages 도메인은 bori-github.github.io인데 레포 전체가 boriguri.github.io를 가리키고 있었다. 전부 404다. 가장 문제가 되는 곳: - apps/zpl-core/package.json, apps/react-zpl/package.json의 homepage 이미 npm에 배포된 패키지의 "Homepage" 링크가 404로 간다 - docs/rspress.config.ts, docs/docs/index.mdx의 og:url SNS 공유 카드가 깨진다 - 루트 package.json, README.md Pages 설정의 html_url(https://bori-github.github.io/zpl-kit/)과 대조해 확인했고, 수정 후 문서 사이트 링크 8개가 모두 200을 반환하는 것을 확인함. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 2 +- apps/react-zpl/package.json | 2 +- apps/zpl-core/package.json | 2 +- docs/docs/index.mdx | 2 +- docs/rspress.config.ts | 2 +- package.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) 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/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/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" From 3edd94cba672b7452f75558f2a69be0f3ed37feb Mon Sep 17 00:00:00 2001 From: Bori-github Date: Fri, 17 Jul 2026 16:44:15 +0900 Subject: [PATCH 2/2] =?UTF-8?q?docs(packages):=20zpl-core=C2=B7react-zpl?= =?UTF-8?q?=20README=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 두 패키지 모두 README 없이 npm에 배포되어 랜딩 페이지가 백지였다. files: ["dist"]이지만 npm은 README를 항상 tarball에 포함하므로 추가만으로 페이지가 채워진다 (pack해서 확인함). 수록한 예제는 전부 실제로 실행해 검증했다: - zpl-core: renderLabel, 렌더러 개별 호출, 커맨드 계층, 검증 에러 - react-zpl: 사용법, print(), 검증 에러 — 타입체크 + 런타임 둘 다 작성 중 확인한 사실들: - 두 패키지가 같은 라벨에 대해 바이트 단위로 동일한 ZPL을 낸다 - fieldOrigin의 파라미터는 { offsetX, offsetY }다 ({ x, y }가 아님) - 실제 출력에는 커맨드 사이에 \& 구분자가 들어간다 - zpl-core에는 engines 필드가 없어 Node 버전 요구사항을 적지 않았다 react-zpl README에 print() 사용법 경고를 넣었다. print()에 라벨을 감싼 컴포넌트를 형태로 넘기면 ^PWundefined가 조용히 생성된다. print()가 넘겨받은 엘리먼트의 props에서 크기를 읽기 때문이고, 타입 검사에도 걸리지 않는다. 동작하는 형태는 OrderLabel({...}) 호출이거나 ZplLabel 엘리먼트를 직접 넘기는 것이며, 데모 4개도 전자를 쓰고 있다. API 자체를 고치는 건 이 PR 범위 밖이라 문서로만 표시한다. Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/react-zpl/README.md | 116 +++++++++++++++++++++++++++++++ apps/zpl-core/README.md | 143 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 apps/react-zpl/README.md create mode 100644 apps/zpl-core/README.md 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/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