chaeditor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +21 -0
- package/README.ko.md +250 -0
- package/README.md +242 -0
- package/dist/core.cjs +1034 -0
- package/dist/core.d.mts +347 -0
- package/dist/core.d.ts +347 -0
- package/dist/core.mjs +988 -0
- package/dist/default-host.cjs +243 -0
- package/dist/default-host.d.mts +52 -0
- package/dist/default-host.d.ts +52 -0
- package/dist/default-host.mjs +239 -0
- package/dist/default-markdown-primitive-registry-B3PGEkqs.d.mts +12 -0
- package/dist/default-markdown-primitive-registry-CqzwhHj2.d.ts +12 -0
- package/dist/image-upload-kind-BJqItE_C.d.mts +18 -0
- package/dist/image-upload-kind-BJqItE_C.d.ts +18 -0
- package/dist/index.cjs +8736 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.mjs +8668 -0
- package/dist/markdown-editor-B1qvE40Z.d.mts +460 -0
- package/dist/markdown-editor-Ce6DpnQk.d.ts +460 -0
- package/dist/markdown-primitive-contract-BXsqbKwY.d.mts +124 -0
- package/dist/markdown-primitive-contract-BXsqbKwY.d.ts +124 -0
- package/dist/panda-primitives.cjs +1299 -0
- package/dist/panda-primitives.d.mts +21127 -0
- package/dist/panda-primitives.d.ts +21127 -0
- package/dist/panda-primitives.mjs +1285 -0
- package/dist/react.cjs +8558 -0
- package/dist/react.d.mts +35 -0
- package/dist/react.d.ts +35 -0
- package/dist/react.mjs +8531 -0
- package/dist/toolbar-preset-B9ttTEol.d.ts +236 -0
- package/dist/toolbar-preset-DIsQN390.d.mts +236 -0
- package/package.json +151 -0
- package/recipes/host-presets/README.md +16 -0
- package/recipes/host-presets/emotion-host-preset.tsx.template +109 -0
- package/recipes/host-presets/styled-components-host-preset.tsx.template +102 -0
- package/recipes/host-presets/tailwind-host-preset.tsx.template +116 -0
- package/recipes/host-presets/vanilla-extract-host-preset.tsx.template +116 -0
- package/styled-system/styles.css +3370 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Chaen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.ko.md
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# chaeditor
|
|
2
|
+
|
|
3
|
+
[English](./README.md) | 한국어
|
|
4
|
+
|
|
5
|
+
`chaeditor`는 React 애플리케이션을 위한 조합형 마크다운 에디터 툴킷입니다.
|
|
6
|
+
작성 보조 도구, 임베드 워크플로우, 리치 마크다운 렌더링을 하나의 패키지 안에서 제공하면서도, host 통합, 스타일, primitive shell은 외부에서 주입하거나 교체할 수 있도록 설계되어 있습니다.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 마크다운 작성 보조와 selection transform 유틸
|
|
11
|
+
- preset 기반 toolbar 조합
|
|
12
|
+
- attachment, gallery, math, Mermaid, spoiler, video를 포함한 리치 마크다운 렌더링
|
|
13
|
+
- upload, href 해석, 이미지 렌더링, 링크 미리보기 메타데이터를 위한 host adapter
|
|
14
|
+
- theme variable override와 primitive shell replacement
|
|
15
|
+
|
|
16
|
+
## 가이드
|
|
17
|
+
|
|
18
|
+
- [Next.js 통합 가이드](https://github.com/pcwadarong/chaeditor/wiki/KO-%3A-Next.js-%ED%86%B5%ED%95%A9-%EA%B0%80%EC%9D%B4%EB%93%9C)
|
|
19
|
+
- [패키지 표면과 import 매트릭스](https://github.com/pcwadarong/chaeditor/wiki/KO-%3A-%ED%8C%A8%ED%82%A4%EC%A7%80-%ED%91%9C%EB%A9%B4%EA%B3%BC-import-%EB%A7%A4%ED%8A%B8%EB%A6%AD%EC%8A%A4)
|
|
20
|
+
- [아키텍처와 폴더 책임](https://github.com/pcwadarong/chaeditor/wiki/KO-%3A--%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98%EC%99%80-%ED%8F%B4%EB%8D%94-%EC%B1%85%EC%9E%84)
|
|
21
|
+
|
|
22
|
+
## 설치
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install react react-dom chaeditor
|
|
26
|
+
pnpm add react react-dom chaeditor
|
|
27
|
+
yarn add react react-dom chaeditor
|
|
28
|
+
bun add react react-dom chaeditor
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
기본 Panda 스타일과 theme token을 같이 쓰려면 CSS도 불러옵니다.
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import 'chaeditor/styles.css';
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 패키지 표면
|
|
38
|
+
|
|
39
|
+
`chaeditor`는 하나의 패키지로 배포됩니다.
|
|
40
|
+
subpath를 따로 설치하는 구조가 아니라, `chaeditor`를 한 번 설치한 뒤 필요한 entrypoint만 골라 import하는 방식으로 사용합니다.
|
|
41
|
+
|
|
42
|
+
| Import 경로 | 제공 내용 | 사용할 때 |
|
|
43
|
+
| ---------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
|
|
44
|
+
| `chaeditor/react` | `MarkdownEditor`, `MarkdownToolbar`, `MarkdownRenderer` 같은 React surface와 primitive registry contract | 대부분의 앱 통합 |
|
|
45
|
+
| `chaeditor/core` | 순수 유틸, 마크다운 helper, parser contract, `createChaeditorThemeVars()` | UI 없이 로직만 쓸 때, 서버 안전 유틸이 필요할 때 |
|
|
46
|
+
| `chaeditor/default-host` | 기본 upload adapter 구현 | 번들된 기본 업로드 구현이 필요할 때만 |
|
|
47
|
+
| `chaeditor/panda-primitives` | 패키지에 번들된 Panda 기반 primitive shell | 기본 primitive 구현을 재사용하거나 감쌀 때만 |
|
|
48
|
+
| `chaeditor/styles.css` | 기본 theme token과 컴포넌트 스타일 | 패키지 기본 스타일을 쓸 때 |
|
|
49
|
+
|
|
50
|
+
## 선택적 import
|
|
51
|
+
|
|
52
|
+
설치는 `chaeditor` 한 번만 하고, 사용은 필요한 subpath만 import하면 됩니다.
|
|
53
|
+
`default-host`, `panda-primitives`는 opt-in surface입니다.
|
|
54
|
+
|
|
55
|
+
대표 예시는 아래 정도면 충분합니다.
|
|
56
|
+
|
|
57
|
+
### 기본 editor
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import 'chaeditor/styles.css';
|
|
61
|
+
|
|
62
|
+
import { MarkdownEditor } from 'chaeditor/react';
|
|
63
|
+
|
|
64
|
+
const Example = () => {
|
|
65
|
+
const [value, setValue] = useState('# Hello chaeditor');
|
|
66
|
+
|
|
67
|
+
return <MarkdownEditor contentType="article" onChange={setValue} value={value} />;
|
|
68
|
+
};
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### core 유틸만 사용
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import {
|
|
75
|
+
createImageGalleryMarkdown,
|
|
76
|
+
createMathEmbedMarkdown,
|
|
77
|
+
parseRichMarkdownSegments,
|
|
78
|
+
} from 'chaeditor/core';
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 기본 host adapter를 선택적으로 연결
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import 'chaeditor/styles.css';
|
|
85
|
+
|
|
86
|
+
import { uploadEditorFile, uploadEditorImage, uploadEditorVideo } from 'chaeditor/default-host';
|
|
87
|
+
import { MarkdownEditor } from 'chaeditor/react';
|
|
88
|
+
|
|
89
|
+
const Example = () => (
|
|
90
|
+
<MarkdownEditor
|
|
91
|
+
adapters={{
|
|
92
|
+
uploadFile: uploadEditorFile,
|
|
93
|
+
uploadImage: uploadEditorImage,
|
|
94
|
+
uploadVideo: uploadEditorVideo,
|
|
95
|
+
}}
|
|
96
|
+
contentType="article"
|
|
97
|
+
onChange={() => {}}
|
|
98
|
+
value=""
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Panda primitive를 선택적으로 재사용
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
import { Button, createPandaMarkdownPrimitiveRegistry } from 'chaeditor/panda-primitives';
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Theme Override
|
|
110
|
+
|
|
111
|
+
기본 스타일 구현은 Panda CSS를 사용하지만, 공개된 theme contract는 CSS variable 기반입니다.
|
|
112
|
+
즉 패키지 기본값을 그대로 써도 되고, host app이 필요한 값만 override해도 됩니다.
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import 'chaeditor/styles.css';
|
|
116
|
+
|
|
117
|
+
import { createChaeditorThemeVars } from 'chaeditor/core';
|
|
118
|
+
import { MarkdownEditor } from 'chaeditor/react';
|
|
119
|
+
|
|
120
|
+
const themeVars = createChaeditorThemeVars({
|
|
121
|
+
primary: '#0f766e',
|
|
122
|
+
primarySubtle: '#ccfbf1',
|
|
123
|
+
surface: '#f8fafc',
|
|
124
|
+
surfaceMuted: '#eff6ff',
|
|
125
|
+
text: '#0f172a',
|
|
126
|
+
textSubtle: '#475569',
|
|
127
|
+
sansFont: 'var(--app-font-sans), system-ui, sans-serif',
|
|
128
|
+
monoFont: "var(--font-d2coding), 'D2Coding', monospace",
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const Example = () => (
|
|
132
|
+
<div style={themeVars}>
|
|
133
|
+
<MarkdownEditor contentType="article" onChange={() => {}} value="" />
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
폰트 정책은 아래처럼 가져가면 됩니다.
|
|
139
|
+
|
|
140
|
+
- `sansFont`: host app의 기본 sans 폰트
|
|
141
|
+
- `sansJaFont`: 다국어 fallback이 필요할 때만 override
|
|
142
|
+
- `monoFont`: 필요하면 host mono를 넣고, 비워두면 D2Coding fallback chain이 기본으로 동작
|
|
143
|
+
|
|
144
|
+
## Styling Runtime Recipes
|
|
145
|
+
|
|
146
|
+
패키지 기본 스타일 런타임은 Panda CSS입니다.
|
|
147
|
+
host 쪽 스타일링 레시피는 host app이 variable을 override하거나 primitive shell을 교체하고 싶을 때만 필요합니다.
|
|
148
|
+
|
|
149
|
+
지원 예시는 아래 범위로 제공합니다.
|
|
150
|
+
|
|
151
|
+
- Tailwind CSS
|
|
152
|
+
- Emotion
|
|
153
|
+
- styled-components
|
|
154
|
+
- vanilla-extract
|
|
155
|
+
- primitive shell replacement
|
|
156
|
+
|
|
157
|
+
바로 가져다 쓸 수 있는 host wrapper 템플릿은 [recipes/host-presets](./recipes/host-presets/README.md)에 정리되어 있습니다.
|
|
158
|
+
|
|
159
|
+
## Primitive Shell Replacement
|
|
160
|
+
|
|
161
|
+
색상, 폰트, spacing 정도는 theme variable override로 충분하지만, 실제 `Button`, `Input`, `Textarea`, `Popover`, `Modal`, `Tooltip` shell 자체를 교체해야 할 수도 있습니다.
|
|
162
|
+
그럴 때는 `primitiveRegistry`를 사용합니다.
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
import 'chaeditor/styles.css';
|
|
166
|
+
|
|
167
|
+
import { MarkdownEditor } from 'chaeditor/react';
|
|
168
|
+
|
|
169
|
+
const HostButton = props => (
|
|
170
|
+
<button {...props} className={`host-button ${props.className ?? ''}`.trim()} />
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
const HostInput = props => (
|
|
174
|
+
<input {...props} className={`host-input ${props.className ?? ''}`.trim()} />
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const HostTextarea = props => (
|
|
178
|
+
<textarea {...props} className={`host-textarea ${props.className ?? ''}`.trim()} />
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
const HostPopover = props => (
|
|
182
|
+
<Popover
|
|
183
|
+
{...props}
|
|
184
|
+
panelClassName={`host-popover-panel ${props.panelClassName ?? ''}`.trim()}
|
|
185
|
+
triggerClassName={`host-popover-trigger ${props.triggerClassName ?? ''}`.trim()}
|
|
186
|
+
/>
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const HostModal = props => (
|
|
190
|
+
<Modal
|
|
191
|
+
{...props}
|
|
192
|
+
backdropClassName={`host-modal-backdrop ${props.backdropClassName ?? ''}`.trim()}
|
|
193
|
+
closeButtonClassName={`host-modal-close ${props.closeButtonClassName ?? ''}`.trim()}
|
|
194
|
+
frameClassName={`host-modal-frame ${props.frameClassName ?? ''}`.trim()}
|
|
195
|
+
/>
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
const HostTooltip = props => (
|
|
199
|
+
<Tooltip
|
|
200
|
+
{...props}
|
|
201
|
+
contentClassName={`host-tooltip ${props.contentClassName ?? ''}`.trim()}
|
|
202
|
+
portalClassName={`host-tooltip-portal ${props.portalClassName ?? ''}`.trim()}
|
|
203
|
+
/>
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const Example = () => (
|
|
207
|
+
<MarkdownEditor
|
|
208
|
+
contentType="article"
|
|
209
|
+
onChange={() => {}}
|
|
210
|
+
primitiveRegistry={{
|
|
211
|
+
Button: HostButton,
|
|
212
|
+
Input: HostInput,
|
|
213
|
+
Modal: HostModal,
|
|
214
|
+
Popover: HostPopover,
|
|
215
|
+
Textarea: HostTextarea,
|
|
216
|
+
Tooltip: HostTooltip,
|
|
217
|
+
}}
|
|
218
|
+
value=""
|
|
219
|
+
/>
|
|
220
|
+
);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
기준을 정리하면:
|
|
224
|
+
|
|
225
|
+
- `createChaeditorThemeVars()`는 semantic token을 바꿉니다.
|
|
226
|
+
- `primitiveRegistry`는 실제 shell 컴포넌트를 바꿉니다.
|
|
227
|
+
|
|
228
|
+
## 로컬 개발
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
pnpm install
|
|
232
|
+
pnpm lint
|
|
233
|
+
pnpm check-types
|
|
234
|
+
pnpm build
|
|
235
|
+
pnpm test
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## 이슈 제보
|
|
239
|
+
|
|
240
|
+
새 이슈를 열기 전에 같은 문제가 이미 등록되어 있는지 먼저 확인해 주세요.
|
|
241
|
+
버그를 제보할 때는 아래 정보를 함께 적어 주세요.
|
|
242
|
+
|
|
243
|
+
- 패키지 버전
|
|
244
|
+
- 런타임 또는 프레임워크 버전
|
|
245
|
+
- 에러 메시지나 스택 트레이스
|
|
246
|
+
- 관련 설정
|
|
247
|
+
|
|
248
|
+
## 기여하기
|
|
249
|
+
|
|
250
|
+
기여 가이드는 [CONTRIBUTING.ko.md](./CONTRIBUTING.ko.md)에서 확인할 수 있습니다.
|
package/README.md
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# chaeditor
|
|
2
|
+
|
|
3
|
+
English | [한국어](./README.ko.md)
|
|
4
|
+
|
|
5
|
+
`chaeditor` is a composable markdown editor toolkit for React applications.
|
|
6
|
+
It combines authoring helpers, embed workflows, and rich markdown rendering in a single package while keeping host integration, styling, and primitive shells open to override.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- markdown authoring helpers and selection transform utilities
|
|
11
|
+
- preset-based toolbar composition
|
|
12
|
+
- rich markdown rendering for attachments, galleries, math, Mermaid, spoilers, and video
|
|
13
|
+
- host adapters for uploads, href resolution, image rendering, and link preview metadata
|
|
14
|
+
- theme variable overrides and primitive shell replacement
|
|
15
|
+
|
|
16
|
+
## Guides
|
|
17
|
+
|
|
18
|
+
- [Next.js Integration](https://github.com/pcwadarong/chaeditor/wiki/EN-%3A-Next.js-Integration)
|
|
19
|
+
- [Package Surface and Import Matrix](https://github.com/pcwadarong/chaeditor/wiki/EN-%3A-Package-Surface-and-Import-Matrix)
|
|
20
|
+
- [Architecture and Folder Ownership](https://github.com/pcwadarong/chaeditor/wiki/EN-%3A-Architecture-and-Folder-Ownership)
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
Install `chaeditor` once, then import only the subpaths you need.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install react react-dom chaeditor
|
|
28
|
+
pnpm add react react-dom chaeditor
|
|
29
|
+
yarn add react react-dom chaeditor
|
|
30
|
+
bun add react react-dom chaeditor
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
If you want the bundled Panda-based default styles and theme tokens, import the package CSS as well.
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import 'chaeditor/styles.css';
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Package Surface
|
|
40
|
+
|
|
41
|
+
`chaeditor` is published as a single npm package.
|
|
42
|
+
You do not install subpaths separately. Install `chaeditor` once, then selectively import the entrypoints you actually need.
|
|
43
|
+
|
|
44
|
+
| Import path | Provides | Use when |
|
|
45
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
46
|
+
| `chaeditor/react` | React surfaces such as `MarkdownEditor`, `MarkdownToolbar`, `MarkdownRenderer`, and the primitive registry contract | most app integrations |
|
|
47
|
+
| `chaeditor/core` | pure utilities, markdown helpers, parser contracts, and `createChaeditorThemeVars()` | logic-only usage or server-safe helpers |
|
|
48
|
+
| `chaeditor/default-host` | bundled default upload adapters | only when you want the packaged upload implementations |
|
|
49
|
+
| `chaeditor/panda-primitives` | the bundled Panda-based primitive shells | only when you want to reuse or wrap the default primitives |
|
|
50
|
+
| `chaeditor/styles.css` | bundled theme tokens and component styles | when you want the default package styling |
|
|
51
|
+
|
|
52
|
+
## Selective Imports
|
|
53
|
+
|
|
54
|
+
Install `chaeditor` once, then import only the subpaths you need.
|
|
55
|
+
`default-host` and `panda-primitives` are opt-in surfaces.
|
|
56
|
+
|
|
57
|
+
Representative examples:
|
|
58
|
+
|
|
59
|
+
### Basic editor
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import 'chaeditor/styles.css';
|
|
63
|
+
|
|
64
|
+
import { MarkdownEditor } from 'chaeditor/react';
|
|
65
|
+
|
|
66
|
+
const Example = () => {
|
|
67
|
+
const [value, setValue] = useState('# Hello chaeditor');
|
|
68
|
+
|
|
69
|
+
return <MarkdownEditor contentType="article" onChange={setValue} value={value} />;
|
|
70
|
+
};
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Core utilities only
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import {
|
|
77
|
+
createImageGalleryMarkdown,
|
|
78
|
+
createMathEmbedMarkdown,
|
|
79
|
+
parseRichMarkdownSegments,
|
|
80
|
+
} from 'chaeditor/core';
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Optional default host adapters
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import 'chaeditor/styles.css';
|
|
87
|
+
|
|
88
|
+
import { uploadEditorFile, uploadEditorImage, uploadEditorVideo } from 'chaeditor/default-host';
|
|
89
|
+
import { MarkdownEditor } from 'chaeditor/react';
|
|
90
|
+
|
|
91
|
+
const Example = () => (
|
|
92
|
+
<MarkdownEditor
|
|
93
|
+
adapters={{
|
|
94
|
+
uploadFile: uploadEditorFile,
|
|
95
|
+
uploadImage: uploadEditorImage,
|
|
96
|
+
uploadVideo: uploadEditorVideo,
|
|
97
|
+
}}
|
|
98
|
+
contentType="article"
|
|
99
|
+
onChange={() => {}}
|
|
100
|
+
value=""
|
|
101
|
+
/>
|
|
102
|
+
);
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Optional Panda primitive reuse
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { Button, createPandaMarkdownPrimitiveRegistry } from 'chaeditor/panda-primitives';
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Theme Override
|
|
112
|
+
|
|
113
|
+
The default implementation uses Panda CSS, but the public theme contract is CSS-variable based.
|
|
114
|
+
You can keep the package defaults as-is, or override only the values your host app actually owns.
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
import 'chaeditor/styles.css';
|
|
118
|
+
|
|
119
|
+
import { createChaeditorThemeVars } from 'chaeditor/core';
|
|
120
|
+
import { MarkdownEditor } from 'chaeditor/react';
|
|
121
|
+
|
|
122
|
+
const themeVars = createChaeditorThemeVars({
|
|
123
|
+
primary: '#0f766e',
|
|
124
|
+
primarySubtle: '#ccfbf1',
|
|
125
|
+
surface: '#f8fafc',
|
|
126
|
+
surfaceMuted: '#eff6ff',
|
|
127
|
+
text: '#0f172a',
|
|
128
|
+
textSubtle: '#475569',
|
|
129
|
+
sansFont: 'var(--app-font-sans), system-ui, sans-serif',
|
|
130
|
+
monoFont: "var(--font-d2coding), 'D2Coding', monospace",
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const Example = () => (
|
|
134
|
+
<div style={themeVars}>
|
|
135
|
+
<MarkdownEditor contentType="article" onChange={() => {}} value="" />
|
|
136
|
+
</div>
|
|
137
|
+
);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Recommended font ownership:
|
|
141
|
+
|
|
142
|
+
- `sansFont`: host app sans font stack
|
|
143
|
+
- `sansJaFont`: optional multilingual fallback
|
|
144
|
+
- `monoFont`: optional host mono stack, otherwise the built-in D2Coding fallback chain is used
|
|
145
|
+
|
|
146
|
+
## Styling Runtime Recipes
|
|
147
|
+
|
|
148
|
+
The default package styling runtime is Panda CSS.
|
|
149
|
+
Host-side styling recipes are only needed when the host app wants to override variables or replace primitive shells.
|
|
150
|
+
|
|
151
|
+
Available examples:
|
|
152
|
+
|
|
153
|
+
- Tailwind CSS
|
|
154
|
+
- Emotion
|
|
155
|
+
- styled-components
|
|
156
|
+
- vanilla-extract
|
|
157
|
+
- primitive shell replacement
|
|
158
|
+
|
|
159
|
+
Ready-to-adapt host wrapper templates are available in [recipes/host-presets](./recipes/host-presets/README.md).
|
|
160
|
+
|
|
161
|
+
## Primitive Shell Replacement
|
|
162
|
+
|
|
163
|
+
Theme variables are enough for colors, fonts, and semantic tokens.
|
|
164
|
+
If you need to replace the actual `Button`, `Input`, `Textarea`, `Popover`, `Modal`, or `Tooltip` shells, use `primitiveRegistry`.
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
import 'chaeditor/styles.css';
|
|
168
|
+
|
|
169
|
+
import { MarkdownEditor } from 'chaeditor/react';
|
|
170
|
+
|
|
171
|
+
const HostButton = props => (
|
|
172
|
+
<button {...props} className={`host-button ${props.className ?? ''}`.trim()} />
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
const HostInput = props => (
|
|
176
|
+
<input {...props} className={`host-input ${props.className ?? ''}`.trim()} />
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
const HostTextarea = props => (
|
|
180
|
+
<textarea {...props} className={`host-textarea ${props.className ?? ''}`.trim()} />
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const HostPopover = props => (
|
|
184
|
+
<Popover
|
|
185
|
+
{...props}
|
|
186
|
+
panelClassName={`host-popover-panel ${props.panelClassName ?? ''}`.trim()}
|
|
187
|
+
triggerClassName={`host-popover-trigger ${props.triggerClassName ?? ''}`.trim()}
|
|
188
|
+
/>
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
const HostModal = props => (
|
|
192
|
+
<Modal
|
|
193
|
+
{...props}
|
|
194
|
+
backdropClassName={`host-modal-backdrop ${props.backdropClassName ?? ''}`.trim()}
|
|
195
|
+
closeButtonClassName={`host-modal-close ${props.closeButtonClassName ?? ''}`.trim()}
|
|
196
|
+
frameClassName={`host-modal-frame ${props.frameClassName ?? ''}`.trim()}
|
|
197
|
+
/>
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
const HostTooltip = props => (
|
|
201
|
+
<Tooltip
|
|
202
|
+
{...props}
|
|
203
|
+
contentClassName={`host-tooltip ${props.contentClassName ?? ''}`.trim()}
|
|
204
|
+
portalClassName={`host-tooltip-portal ${props.portalClassName ?? ''}`.trim()}
|
|
205
|
+
/>
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
const Example = () => (
|
|
209
|
+
<MarkdownEditor
|
|
210
|
+
contentType="article"
|
|
211
|
+
onChange={() => {}}
|
|
212
|
+
primitiveRegistry={{
|
|
213
|
+
Button: HostButton,
|
|
214
|
+
Input: HostInput,
|
|
215
|
+
Modal: HostModal,
|
|
216
|
+
Popover: HostPopover,
|
|
217
|
+
Textarea: HostTextarea,
|
|
218
|
+
Tooltip: HostTooltip,
|
|
219
|
+
}}
|
|
220
|
+
value=""
|
|
221
|
+
/>
|
|
222
|
+
);
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Rule of thumb:
|
|
226
|
+
|
|
227
|
+
- `createChaeditorThemeVars()` changes semantic tokens
|
|
228
|
+
- `primitiveRegistry` changes shell components
|
|
229
|
+
|
|
230
|
+
## Local Development
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
pnpm install
|
|
234
|
+
pnpm lint
|
|
235
|
+
pnpm check-types
|
|
236
|
+
pnpm build
|
|
237
|
+
pnpm test
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Contributing
|
|
241
|
+
|
|
242
|
+
If you want to contribute, see [CONTRIBUTING.md](./CONTRIBUTING.md).
|