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
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { a as EditorContentType, E as EditorAttachment, b as EditorImageUploadKind } from './image-upload-kind-BJqItE_C.js';
|
|
3
|
+
|
|
4
|
+
type LinkEmbedData = {
|
|
5
|
+
description: string;
|
|
6
|
+
favicon: string | null;
|
|
7
|
+
image: string | null;
|
|
8
|
+
siteName: string;
|
|
9
|
+
title: string;
|
|
10
|
+
url: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type PreviewImageSource = string | {
|
|
14
|
+
src: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Shared image render props passed to a host-provided image renderer.
|
|
18
|
+
*/
|
|
19
|
+
type HostImageRenderProps = {
|
|
20
|
+
/** Accessible image alternative text. */
|
|
21
|
+
alt: string;
|
|
22
|
+
/** Optional class name applied by the package surface. */
|
|
23
|
+
className?: string;
|
|
24
|
+
/** Whether the image is expected to fill an absolutely positioned frame. */
|
|
25
|
+
fill?: boolean;
|
|
26
|
+
/** Optional responsive sizes hint forwarded to the host image primitive. */
|
|
27
|
+
sizes?: string;
|
|
28
|
+
/** Source value generated by the editor or renderer. */
|
|
29
|
+
src: PreviewImageSource;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Renders an image node with a host-specific image primitive.
|
|
33
|
+
*
|
|
34
|
+
* When omitted, the package falls back to its default <img>-based renderer.
|
|
35
|
+
*/
|
|
36
|
+
type HostImageRenderer = (props: HostImageRenderProps) => React.ReactNode;
|
|
37
|
+
/**
|
|
38
|
+
* Label overrides used by the built-in image viewer UI.
|
|
39
|
+
*/
|
|
40
|
+
type MarkdownImageViewerLabels = {
|
|
41
|
+
actionBarAriaLabel: string;
|
|
42
|
+
closeAriaLabel: string;
|
|
43
|
+
fitToScreenAriaLabel: string;
|
|
44
|
+
imageViewerAriaLabel?: string;
|
|
45
|
+
locateSourceAriaLabel: string;
|
|
46
|
+
nextAriaLabel: string;
|
|
47
|
+
openAriaLabel: string;
|
|
48
|
+
previousAriaLabel: string;
|
|
49
|
+
selectForFrameAriaLabel: string;
|
|
50
|
+
selectForFrameLabel: string;
|
|
51
|
+
thumbnailListAriaLabel: string;
|
|
52
|
+
zoomInAriaLabel: string;
|
|
53
|
+
zoomOutAriaLabel: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Uploads an editor image and returns the final public URL.
|
|
57
|
+
*
|
|
58
|
+
* When this adapter is omitted, image upload flows stay available only if the caller
|
|
59
|
+
* injects a different upload implementation through the relevant UI surface.
|
|
60
|
+
*/
|
|
61
|
+
type UploadEditorImage = (payload: {
|
|
62
|
+
/** Logical content type that scopes the upload target. */
|
|
63
|
+
contentType: EditorContentType;
|
|
64
|
+
/** Raw browser file selected by the user. */
|
|
65
|
+
file: File;
|
|
66
|
+
/** Upload intent used by the host to optimize the image differently when needed. */
|
|
67
|
+
imageKind: EditorImageUploadKind;
|
|
68
|
+
}) => Promise<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Uploads an editor attachment and returns the uploaded file metadata.
|
|
71
|
+
*
|
|
72
|
+
* When omitted, attachment upload UI can still render but should disable upload-specific actions.
|
|
73
|
+
*/
|
|
74
|
+
type UploadEditorFile = (payload: {
|
|
75
|
+
/** Logical content type that scopes the upload target. */
|
|
76
|
+
contentType: EditorContentType;
|
|
77
|
+
/** Raw browser file selected by the user. */
|
|
78
|
+
file: File;
|
|
79
|
+
}) => Promise<EditorAttachment>;
|
|
80
|
+
/**
|
|
81
|
+
* Uploads an editor video and returns the final public URL.
|
|
82
|
+
*
|
|
83
|
+
* When omitted, video helpers can fall back to URL-only insertion flows.
|
|
84
|
+
*/
|
|
85
|
+
type UploadEditorVideo = (payload: {
|
|
86
|
+
/** Logical content type that scopes the upload target. */
|
|
87
|
+
contentType: EditorContentType;
|
|
88
|
+
/** Raw browser file selected by the user. */
|
|
89
|
+
file: File;
|
|
90
|
+
/** Optional progress callback that receives a 0-100 percentage. */
|
|
91
|
+
onProgress?: (percentage: number) => void;
|
|
92
|
+
/** Optional abort signal for cancelable uploads. */
|
|
93
|
+
signal?: AbortSignal;
|
|
94
|
+
}) => Promise<string>;
|
|
95
|
+
/**
|
|
96
|
+
* Resolves the final attachment href in the host application.
|
|
97
|
+
*
|
|
98
|
+
* When omitted, the renderer uses the original href from markdown content.
|
|
99
|
+
*/
|
|
100
|
+
type ResolveAttachmentHref = (payload: {
|
|
101
|
+
fileName: string;
|
|
102
|
+
href: string;
|
|
103
|
+
}) => string | null;
|
|
104
|
+
/**
|
|
105
|
+
* Fetches metadata used by link preview cards.
|
|
106
|
+
*
|
|
107
|
+
* When omitted, link preview components fall back to plain link rendering.
|
|
108
|
+
*/
|
|
109
|
+
type FetchLinkPreviewMeta = (url: string, signal?: AbortSignal) => Promise<LinkEmbedData | null>;
|
|
110
|
+
/**
|
|
111
|
+
* Host-level adapters used by the markdown renderer and related UI.
|
|
112
|
+
*/
|
|
113
|
+
type MarkdownRendererHostAdapters = {
|
|
114
|
+
/** Optional metadata fetcher for rich link preview cards. */
|
|
115
|
+
fetchLinkPreviewMeta?: FetchLinkPreviewMeta;
|
|
116
|
+
/** Optional label overrides for the built-in image viewer. */
|
|
117
|
+
imageViewerLabels?: Partial<MarkdownImageViewerLabels>;
|
|
118
|
+
/** Optional image renderer override for framework-specific image primitives. */
|
|
119
|
+
renderImage?: HostImageRenderer;
|
|
120
|
+
/** Optional attachment href resolver. */
|
|
121
|
+
resolveAttachmentHref?: ResolveAttachmentHref;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Host-level adapters used by the editor toolbar, embed modals, and renderer.
|
|
125
|
+
*/
|
|
126
|
+
type MarkdownEditorHostAdapters = MarkdownRendererHostAdapters & {
|
|
127
|
+
/** Optional attachment upload implementation. */
|
|
128
|
+
uploadFile?: UploadEditorFile;
|
|
129
|
+
/** Optional image upload implementation. */
|
|
130
|
+
uploadImage?: UploadEditorImage;
|
|
131
|
+
/** Optional video upload implementation. */
|
|
132
|
+
uploadVideo?: UploadEditorVideo;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
type MarkdownImageViewerItem = {
|
|
136
|
+
alt: string;
|
|
137
|
+
src: string;
|
|
138
|
+
viewerId: string;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Collects markdown image nodes into a viewer-friendly item list.
|
|
142
|
+
*/
|
|
143
|
+
declare const collectMarkdownImages: (markdown: string) => MarkdownImageViewerItem[];
|
|
144
|
+
|
|
145
|
+
type MarkdownFragmentRenderer = (markdown: string, key: string) => ReactNode;
|
|
146
|
+
type ToggleHeadingLevel = 1 | 2 | 3 | 4 | null;
|
|
147
|
+
type MarkdownSegment = {
|
|
148
|
+
markdown: string;
|
|
149
|
+
type: 'markdown';
|
|
150
|
+
} | {
|
|
151
|
+
align: 'center' | 'left' | 'right';
|
|
152
|
+
content: string;
|
|
153
|
+
type: 'align';
|
|
154
|
+
} | {
|
|
155
|
+
content: string;
|
|
156
|
+
type: 'subtext';
|
|
157
|
+
} | {
|
|
158
|
+
content: string;
|
|
159
|
+
headingLevel: ToggleHeadingLevel;
|
|
160
|
+
title: string;
|
|
161
|
+
type: 'toggle';
|
|
162
|
+
} | {
|
|
163
|
+
contentType?: string;
|
|
164
|
+
fileName: string;
|
|
165
|
+
fileSize?: number;
|
|
166
|
+
href: string;
|
|
167
|
+
type: 'attachment';
|
|
168
|
+
} | {
|
|
169
|
+
formula: string;
|
|
170
|
+
isBlock: boolean;
|
|
171
|
+
type: 'math';
|
|
172
|
+
} | {
|
|
173
|
+
items: ReturnType<typeof collectMarkdownImages>;
|
|
174
|
+
type: 'gallery';
|
|
175
|
+
} | {
|
|
176
|
+
provider: 'upload' | 'youtube';
|
|
177
|
+
src?: string;
|
|
178
|
+
type: 'video';
|
|
179
|
+
videoId?: string;
|
|
180
|
+
};
|
|
181
|
+
type RichMarkdownRenderArgs = {
|
|
182
|
+
markdown: string;
|
|
183
|
+
renderMarkdownFragment: MarkdownFragmentRenderer;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Restores HTML entities escaped inside custom tag attributes.
|
|
187
|
+
*
|
|
188
|
+
* @param value Raw attribute value.
|
|
189
|
+
* @returns A decoded string.
|
|
190
|
+
*/
|
|
191
|
+
declare const decodeHtmlAttributeEntities: (value: string) => string;
|
|
192
|
+
/**
|
|
193
|
+
* Splits a toggle title into heading level metadata and visible text.
|
|
194
|
+
*
|
|
195
|
+
* @param rawTitle Raw title text after the toggle marker.
|
|
196
|
+
* @returns Parsed heading level and title.
|
|
197
|
+
*/
|
|
198
|
+
declare const parseToggleTitle: (rawTitle: string) => {
|
|
199
|
+
headingLevel: ToggleHeadingLevel;
|
|
200
|
+
title: string;
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Splits markdown into plain fragments and custom block segments.
|
|
204
|
+
*
|
|
205
|
+
* @param markdown Raw markdown string that may contain custom syntax.
|
|
206
|
+
* @returns Parsed segment list for rendering.
|
|
207
|
+
*/
|
|
208
|
+
declare const parseRichMarkdownSegments: (markdown: string) => MarkdownSegment[];
|
|
209
|
+
|
|
210
|
+
type MarkdownToolbarSectionKey = 'heading-and-subtext' | 'text-emphasis' | 'highlight-and-alignment' | 'block-syntax' | 'embed-and-media';
|
|
211
|
+
type MarkdownToolbarPresetItemKey = 'heading-popover' | 'subtext' | 'bold' | 'italic' | 'strike' | 'underline' | 'text-color' | 'background-color' | 'align' | 'horizontal-rule' | 'quote' | 'code-block' | 'table' | 'spoiler' | 'toggle-popover' | 'math-embed' | 'file-embed' | 'image-embed' | 'link-embed' | 'video-embed';
|
|
212
|
+
type MarkdownToolbarPresetSection = {
|
|
213
|
+
itemKeys: MarkdownToolbarPresetItemKey[];
|
|
214
|
+
key: MarkdownToolbarSectionKey;
|
|
215
|
+
};
|
|
216
|
+
type MarkdownToolbarResolvedSection<TItem> = {
|
|
217
|
+
items: TItem[];
|
|
218
|
+
key: MarkdownToolbarSectionKey;
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* Default toolbar preset expressed as pure section and item keys.
|
|
222
|
+
*/
|
|
223
|
+
declare const DEFAULT_MARKDOWN_TOOLBAR_PRESET: MarkdownToolbarPresetSection[];
|
|
224
|
+
/**
|
|
225
|
+
* Resolves the final toolbar sections from a preset and an item registry.
|
|
226
|
+
*
|
|
227
|
+
* @param itemRegistry Map from toolbar item keys to concrete section items.
|
|
228
|
+
* @param preset Optional toolbar preset.
|
|
229
|
+
* @returns Resolved toolbar sections.
|
|
230
|
+
*/
|
|
231
|
+
declare const resolveMarkdownToolbarPresetSections: <TItem>({ itemRegistry, preset, }: {
|
|
232
|
+
itemRegistry: Partial<Record<MarkdownToolbarPresetItemKey, TItem>>;
|
|
233
|
+
preset?: MarkdownToolbarPresetSection[];
|
|
234
|
+
}) => MarkdownToolbarResolvedSection<TItem>[];
|
|
235
|
+
|
|
236
|
+
export { DEFAULT_MARKDOWN_TOOLBAR_PRESET as D, type FetchLinkPreviewMeta as F, type HostImageRenderProps as H, type MarkdownEditorHostAdapters as M, type PreviewImageSource as P, type ResolveAttachmentHref as R, type UploadEditorFile as U, type HostImageRenderer as a, type MarkdownImageViewerLabels as b, type MarkdownRendererHostAdapters as c, type MarkdownSegment as d, type MarkdownToolbarPresetItemKey as e, type MarkdownToolbarPresetSection as f, type MarkdownToolbarResolvedSection as g, type MarkdownToolbarSectionKey as h, type RichMarkdownRenderArgs as i, type UploadEditorImage as j, type UploadEditorVideo as k, decodeHtmlAttributeEntities as l, parseToggleTitle as m, parseRichMarkdownSegments as p, resolveMarkdownToolbarPresetSections as r };
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { a as EditorContentType, E as EditorAttachment, b as EditorImageUploadKind } from './image-upload-kind-BJqItE_C.mjs';
|
|
3
|
+
|
|
4
|
+
type LinkEmbedData = {
|
|
5
|
+
description: string;
|
|
6
|
+
favicon: string | null;
|
|
7
|
+
image: string | null;
|
|
8
|
+
siteName: string;
|
|
9
|
+
title: string;
|
|
10
|
+
url: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type PreviewImageSource = string | {
|
|
14
|
+
src: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Shared image render props passed to a host-provided image renderer.
|
|
18
|
+
*/
|
|
19
|
+
type HostImageRenderProps = {
|
|
20
|
+
/** Accessible image alternative text. */
|
|
21
|
+
alt: string;
|
|
22
|
+
/** Optional class name applied by the package surface. */
|
|
23
|
+
className?: string;
|
|
24
|
+
/** Whether the image is expected to fill an absolutely positioned frame. */
|
|
25
|
+
fill?: boolean;
|
|
26
|
+
/** Optional responsive sizes hint forwarded to the host image primitive. */
|
|
27
|
+
sizes?: string;
|
|
28
|
+
/** Source value generated by the editor or renderer. */
|
|
29
|
+
src: PreviewImageSource;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Renders an image node with a host-specific image primitive.
|
|
33
|
+
*
|
|
34
|
+
* When omitted, the package falls back to its default <img>-based renderer.
|
|
35
|
+
*/
|
|
36
|
+
type HostImageRenderer = (props: HostImageRenderProps) => React.ReactNode;
|
|
37
|
+
/**
|
|
38
|
+
* Label overrides used by the built-in image viewer UI.
|
|
39
|
+
*/
|
|
40
|
+
type MarkdownImageViewerLabels = {
|
|
41
|
+
actionBarAriaLabel: string;
|
|
42
|
+
closeAriaLabel: string;
|
|
43
|
+
fitToScreenAriaLabel: string;
|
|
44
|
+
imageViewerAriaLabel?: string;
|
|
45
|
+
locateSourceAriaLabel: string;
|
|
46
|
+
nextAriaLabel: string;
|
|
47
|
+
openAriaLabel: string;
|
|
48
|
+
previousAriaLabel: string;
|
|
49
|
+
selectForFrameAriaLabel: string;
|
|
50
|
+
selectForFrameLabel: string;
|
|
51
|
+
thumbnailListAriaLabel: string;
|
|
52
|
+
zoomInAriaLabel: string;
|
|
53
|
+
zoomOutAriaLabel: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Uploads an editor image and returns the final public URL.
|
|
57
|
+
*
|
|
58
|
+
* When this adapter is omitted, image upload flows stay available only if the caller
|
|
59
|
+
* injects a different upload implementation through the relevant UI surface.
|
|
60
|
+
*/
|
|
61
|
+
type UploadEditorImage = (payload: {
|
|
62
|
+
/** Logical content type that scopes the upload target. */
|
|
63
|
+
contentType: EditorContentType;
|
|
64
|
+
/** Raw browser file selected by the user. */
|
|
65
|
+
file: File;
|
|
66
|
+
/** Upload intent used by the host to optimize the image differently when needed. */
|
|
67
|
+
imageKind: EditorImageUploadKind;
|
|
68
|
+
}) => Promise<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Uploads an editor attachment and returns the uploaded file metadata.
|
|
71
|
+
*
|
|
72
|
+
* When omitted, attachment upload UI can still render but should disable upload-specific actions.
|
|
73
|
+
*/
|
|
74
|
+
type UploadEditorFile = (payload: {
|
|
75
|
+
/** Logical content type that scopes the upload target. */
|
|
76
|
+
contentType: EditorContentType;
|
|
77
|
+
/** Raw browser file selected by the user. */
|
|
78
|
+
file: File;
|
|
79
|
+
}) => Promise<EditorAttachment>;
|
|
80
|
+
/**
|
|
81
|
+
* Uploads an editor video and returns the final public URL.
|
|
82
|
+
*
|
|
83
|
+
* When omitted, video helpers can fall back to URL-only insertion flows.
|
|
84
|
+
*/
|
|
85
|
+
type UploadEditorVideo = (payload: {
|
|
86
|
+
/** Logical content type that scopes the upload target. */
|
|
87
|
+
contentType: EditorContentType;
|
|
88
|
+
/** Raw browser file selected by the user. */
|
|
89
|
+
file: File;
|
|
90
|
+
/** Optional progress callback that receives a 0-100 percentage. */
|
|
91
|
+
onProgress?: (percentage: number) => void;
|
|
92
|
+
/** Optional abort signal for cancelable uploads. */
|
|
93
|
+
signal?: AbortSignal;
|
|
94
|
+
}) => Promise<string>;
|
|
95
|
+
/**
|
|
96
|
+
* Resolves the final attachment href in the host application.
|
|
97
|
+
*
|
|
98
|
+
* When omitted, the renderer uses the original href from markdown content.
|
|
99
|
+
*/
|
|
100
|
+
type ResolveAttachmentHref = (payload: {
|
|
101
|
+
fileName: string;
|
|
102
|
+
href: string;
|
|
103
|
+
}) => string | null;
|
|
104
|
+
/**
|
|
105
|
+
* Fetches metadata used by link preview cards.
|
|
106
|
+
*
|
|
107
|
+
* When omitted, link preview components fall back to plain link rendering.
|
|
108
|
+
*/
|
|
109
|
+
type FetchLinkPreviewMeta = (url: string, signal?: AbortSignal) => Promise<LinkEmbedData | null>;
|
|
110
|
+
/**
|
|
111
|
+
* Host-level adapters used by the markdown renderer and related UI.
|
|
112
|
+
*/
|
|
113
|
+
type MarkdownRendererHostAdapters = {
|
|
114
|
+
/** Optional metadata fetcher for rich link preview cards. */
|
|
115
|
+
fetchLinkPreviewMeta?: FetchLinkPreviewMeta;
|
|
116
|
+
/** Optional label overrides for the built-in image viewer. */
|
|
117
|
+
imageViewerLabels?: Partial<MarkdownImageViewerLabels>;
|
|
118
|
+
/** Optional image renderer override for framework-specific image primitives. */
|
|
119
|
+
renderImage?: HostImageRenderer;
|
|
120
|
+
/** Optional attachment href resolver. */
|
|
121
|
+
resolveAttachmentHref?: ResolveAttachmentHref;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Host-level adapters used by the editor toolbar, embed modals, and renderer.
|
|
125
|
+
*/
|
|
126
|
+
type MarkdownEditorHostAdapters = MarkdownRendererHostAdapters & {
|
|
127
|
+
/** Optional attachment upload implementation. */
|
|
128
|
+
uploadFile?: UploadEditorFile;
|
|
129
|
+
/** Optional image upload implementation. */
|
|
130
|
+
uploadImage?: UploadEditorImage;
|
|
131
|
+
/** Optional video upload implementation. */
|
|
132
|
+
uploadVideo?: UploadEditorVideo;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
type MarkdownImageViewerItem = {
|
|
136
|
+
alt: string;
|
|
137
|
+
src: string;
|
|
138
|
+
viewerId: string;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Collects markdown image nodes into a viewer-friendly item list.
|
|
142
|
+
*/
|
|
143
|
+
declare const collectMarkdownImages: (markdown: string) => MarkdownImageViewerItem[];
|
|
144
|
+
|
|
145
|
+
type MarkdownFragmentRenderer = (markdown: string, key: string) => ReactNode;
|
|
146
|
+
type ToggleHeadingLevel = 1 | 2 | 3 | 4 | null;
|
|
147
|
+
type MarkdownSegment = {
|
|
148
|
+
markdown: string;
|
|
149
|
+
type: 'markdown';
|
|
150
|
+
} | {
|
|
151
|
+
align: 'center' | 'left' | 'right';
|
|
152
|
+
content: string;
|
|
153
|
+
type: 'align';
|
|
154
|
+
} | {
|
|
155
|
+
content: string;
|
|
156
|
+
type: 'subtext';
|
|
157
|
+
} | {
|
|
158
|
+
content: string;
|
|
159
|
+
headingLevel: ToggleHeadingLevel;
|
|
160
|
+
title: string;
|
|
161
|
+
type: 'toggle';
|
|
162
|
+
} | {
|
|
163
|
+
contentType?: string;
|
|
164
|
+
fileName: string;
|
|
165
|
+
fileSize?: number;
|
|
166
|
+
href: string;
|
|
167
|
+
type: 'attachment';
|
|
168
|
+
} | {
|
|
169
|
+
formula: string;
|
|
170
|
+
isBlock: boolean;
|
|
171
|
+
type: 'math';
|
|
172
|
+
} | {
|
|
173
|
+
items: ReturnType<typeof collectMarkdownImages>;
|
|
174
|
+
type: 'gallery';
|
|
175
|
+
} | {
|
|
176
|
+
provider: 'upload' | 'youtube';
|
|
177
|
+
src?: string;
|
|
178
|
+
type: 'video';
|
|
179
|
+
videoId?: string;
|
|
180
|
+
};
|
|
181
|
+
type RichMarkdownRenderArgs = {
|
|
182
|
+
markdown: string;
|
|
183
|
+
renderMarkdownFragment: MarkdownFragmentRenderer;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Restores HTML entities escaped inside custom tag attributes.
|
|
187
|
+
*
|
|
188
|
+
* @param value Raw attribute value.
|
|
189
|
+
* @returns A decoded string.
|
|
190
|
+
*/
|
|
191
|
+
declare const decodeHtmlAttributeEntities: (value: string) => string;
|
|
192
|
+
/**
|
|
193
|
+
* Splits a toggle title into heading level metadata and visible text.
|
|
194
|
+
*
|
|
195
|
+
* @param rawTitle Raw title text after the toggle marker.
|
|
196
|
+
* @returns Parsed heading level and title.
|
|
197
|
+
*/
|
|
198
|
+
declare const parseToggleTitle: (rawTitle: string) => {
|
|
199
|
+
headingLevel: ToggleHeadingLevel;
|
|
200
|
+
title: string;
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Splits markdown into plain fragments and custom block segments.
|
|
204
|
+
*
|
|
205
|
+
* @param markdown Raw markdown string that may contain custom syntax.
|
|
206
|
+
* @returns Parsed segment list for rendering.
|
|
207
|
+
*/
|
|
208
|
+
declare const parseRichMarkdownSegments: (markdown: string) => MarkdownSegment[];
|
|
209
|
+
|
|
210
|
+
type MarkdownToolbarSectionKey = 'heading-and-subtext' | 'text-emphasis' | 'highlight-and-alignment' | 'block-syntax' | 'embed-and-media';
|
|
211
|
+
type MarkdownToolbarPresetItemKey = 'heading-popover' | 'subtext' | 'bold' | 'italic' | 'strike' | 'underline' | 'text-color' | 'background-color' | 'align' | 'horizontal-rule' | 'quote' | 'code-block' | 'table' | 'spoiler' | 'toggle-popover' | 'math-embed' | 'file-embed' | 'image-embed' | 'link-embed' | 'video-embed';
|
|
212
|
+
type MarkdownToolbarPresetSection = {
|
|
213
|
+
itemKeys: MarkdownToolbarPresetItemKey[];
|
|
214
|
+
key: MarkdownToolbarSectionKey;
|
|
215
|
+
};
|
|
216
|
+
type MarkdownToolbarResolvedSection<TItem> = {
|
|
217
|
+
items: TItem[];
|
|
218
|
+
key: MarkdownToolbarSectionKey;
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* Default toolbar preset expressed as pure section and item keys.
|
|
222
|
+
*/
|
|
223
|
+
declare const DEFAULT_MARKDOWN_TOOLBAR_PRESET: MarkdownToolbarPresetSection[];
|
|
224
|
+
/**
|
|
225
|
+
* Resolves the final toolbar sections from a preset and an item registry.
|
|
226
|
+
*
|
|
227
|
+
* @param itemRegistry Map from toolbar item keys to concrete section items.
|
|
228
|
+
* @param preset Optional toolbar preset.
|
|
229
|
+
* @returns Resolved toolbar sections.
|
|
230
|
+
*/
|
|
231
|
+
declare const resolveMarkdownToolbarPresetSections: <TItem>({ itemRegistry, preset, }: {
|
|
232
|
+
itemRegistry: Partial<Record<MarkdownToolbarPresetItemKey, TItem>>;
|
|
233
|
+
preset?: MarkdownToolbarPresetSection[];
|
|
234
|
+
}) => MarkdownToolbarResolvedSection<TItem>[];
|
|
235
|
+
|
|
236
|
+
export { DEFAULT_MARKDOWN_TOOLBAR_PRESET as D, type FetchLinkPreviewMeta as F, type HostImageRenderProps as H, type MarkdownEditorHostAdapters as M, type PreviewImageSource as P, type ResolveAttachmentHref as R, type UploadEditorFile as U, type HostImageRenderer as a, type MarkdownImageViewerLabels as b, type MarkdownRendererHostAdapters as c, type MarkdownSegment as d, type MarkdownToolbarPresetItemKey as e, type MarkdownToolbarPresetSection as f, type MarkdownToolbarResolvedSection as g, type MarkdownToolbarSectionKey as h, type RichMarkdownRenderArgs as i, type UploadEditorImage as j, type UploadEditorVideo as k, decodeHtmlAttributeEntities as l, parseToggleTitle as m, parseRichMarkdownSegments as p, resolveMarkdownToolbarPresetSections as r };
|
package/package.json
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "chaeditor",
|
|
3
|
+
"description": "Composable markdown editor toolkit for React applications.",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"homepage": "https://github.com/pcwadarong/chaeditor#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/pcwadarong/chaeditor.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/pcwadarong/chaeditor/issues"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"editor",
|
|
15
|
+
"markdown",
|
|
16
|
+
"react",
|
|
17
|
+
"storybook",
|
|
18
|
+
"toolbar",
|
|
19
|
+
"renderer"
|
|
20
|
+
],
|
|
21
|
+
"main": "./dist/index.cjs",
|
|
22
|
+
"module": "./dist/index.mjs",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.mjs",
|
|
28
|
+
"require": "./dist/index.cjs"
|
|
29
|
+
},
|
|
30
|
+
"./core": {
|
|
31
|
+
"types": "./dist/core.d.ts",
|
|
32
|
+
"import": "./dist/core.mjs",
|
|
33
|
+
"require": "./dist/core.cjs"
|
|
34
|
+
},
|
|
35
|
+
"./react": {
|
|
36
|
+
"types": "./dist/react.d.ts",
|
|
37
|
+
"import": "./dist/react.mjs",
|
|
38
|
+
"require": "./dist/react.cjs"
|
|
39
|
+
},
|
|
40
|
+
"./default-host": {
|
|
41
|
+
"types": "./dist/default-host.d.ts",
|
|
42
|
+
"import": "./dist/default-host.mjs",
|
|
43
|
+
"require": "./dist/default-host.cjs"
|
|
44
|
+
},
|
|
45
|
+
"./panda-primitives": {
|
|
46
|
+
"types": "./dist/panda-primitives.d.ts",
|
|
47
|
+
"import": "./dist/panda-primitives.mjs",
|
|
48
|
+
"require": "./dist/panda-primitives.cjs"
|
|
49
|
+
},
|
|
50
|
+
"./styles.css": "./styled-system/styles.css",
|
|
51
|
+
"./package.json": "./package.json"
|
|
52
|
+
},
|
|
53
|
+
"packageManager": "pnpm@10.18.3",
|
|
54
|
+
"files": [
|
|
55
|
+
"dist",
|
|
56
|
+
"recipes/host-presets",
|
|
57
|
+
"styled-system/styles.css",
|
|
58
|
+
"README.md"
|
|
59
|
+
],
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "pnpm run prepare && pnpm run clean && tsup",
|
|
62
|
+
"clean": "rm -rf dist",
|
|
63
|
+
"commit": "cz",
|
|
64
|
+
"format": "prettier --check .",
|
|
65
|
+
"format:write": "prettier --write .",
|
|
66
|
+
"lint": "eslint .",
|
|
67
|
+
"postinstall": "husky",
|
|
68
|
+
"prepack": "pnpm run build",
|
|
69
|
+
"prepare": "panda codegen && panda cssgen --outfile styled-system/styles.css",
|
|
70
|
+
"test": "vitest run",
|
|
71
|
+
"test:watch": "vitest",
|
|
72
|
+
"check-types": "tsc --noEmit",
|
|
73
|
+
"typecheck": "tsc --noEmit",
|
|
74
|
+
"storybook": "storybook dev -p 6006",
|
|
75
|
+
"build-storybook": "storybook build",
|
|
76
|
+
"chromatic": "npx chromatic --project-token=chpt_e7dfd62937e7687",
|
|
77
|
+
"verify:package-surface": "node ./scripts/verify-package-surface.mjs"
|
|
78
|
+
},
|
|
79
|
+
"version": "0.1.0",
|
|
80
|
+
"publishConfig": {
|
|
81
|
+
"access": "public"
|
|
82
|
+
},
|
|
83
|
+
"sideEffects": [
|
|
84
|
+
"./styled-system/styles.css"
|
|
85
|
+
],
|
|
86
|
+
"config": {
|
|
87
|
+
"commitizen": {
|
|
88
|
+
"path": "cz-customizable",
|
|
89
|
+
"config": ".cz-config.js"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"dependencies": {
|
|
93
|
+
"katex": "^0.16.44",
|
|
94
|
+
"mermaid": "^11.13.0",
|
|
95
|
+
"react-markdown": "^10.1.0",
|
|
96
|
+
"rehype-pretty-code": "^0.14.3",
|
|
97
|
+
"remark-breaks": "^4.0.0",
|
|
98
|
+
"remark-gfm": "^4.0.1",
|
|
99
|
+
"shiki": "^4.0.1",
|
|
100
|
+
"zod": "^4.3.6"
|
|
101
|
+
},
|
|
102
|
+
"peerDependencies": {
|
|
103
|
+
"react": "^19.0.0",
|
|
104
|
+
"react-dom": "^19.0.0"
|
|
105
|
+
},
|
|
106
|
+
"devDependencies": {
|
|
107
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
108
|
+
"@eslint/js": "^9.35.0",
|
|
109
|
+
"@pandacss/dev": "^1.9.0",
|
|
110
|
+
"@storybook/addon-docs": "10.3.3",
|
|
111
|
+
"@storybook/nextjs-vite": "^10.3.3",
|
|
112
|
+
"@testing-library/jest-dom": "^6.8.0",
|
|
113
|
+
"@testing-library/react": "^16.3.0",
|
|
114
|
+
"@types/node": "^24.4.0",
|
|
115
|
+
"@types/react": "^19.1.13",
|
|
116
|
+
"@types/react-dom": "^19.1.9",
|
|
117
|
+
"autoprefixer": "^10.4.27",
|
|
118
|
+
"chromatic": "^16.0.0",
|
|
119
|
+
"commitizen": "^4.3.1",
|
|
120
|
+
"cz-customizable": "^7.5.1",
|
|
121
|
+
"esbuild": "^0.27.4",
|
|
122
|
+
"eslint": "^9.35.0",
|
|
123
|
+
"eslint-config-next": "^15.5.3",
|
|
124
|
+
"eslint-config-prettier": "^10.1.8",
|
|
125
|
+
"eslint-plugin-import": "^2.32.0",
|
|
126
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
127
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
128
|
+
"eslint-plugin-storybook": "^10.3.3",
|
|
129
|
+
"husky": "^9.1.7",
|
|
130
|
+
"jsdom": "^27.0.0",
|
|
131
|
+
"lint-staged": "^16.1.6",
|
|
132
|
+
"next": "^15.5.3",
|
|
133
|
+
"prettier": "^3.6.2",
|
|
134
|
+
"storybook": "^10.3.3",
|
|
135
|
+
"tsup": "^8.5.0",
|
|
136
|
+
"typescript": "^5.9.2",
|
|
137
|
+
"typescript-eslint": "^8.43.0",
|
|
138
|
+
"vite": "^8.0.3",
|
|
139
|
+
"vite-plugin-svgr": "^5.0.0",
|
|
140
|
+
"vitest": "^3.2.4"
|
|
141
|
+
},
|
|
142
|
+
"lint-staged": {
|
|
143
|
+
"*.{js,jsx,ts,tsx,mjs,cjs}": [
|
|
144
|
+
"eslint --fix",
|
|
145
|
+
"prettier --write"
|
|
146
|
+
],
|
|
147
|
+
"*.{json,md,yml,yaml,css,scss}": [
|
|
148
|
+
"prettier --write"
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Host Preset Templates
|
|
2
|
+
|
|
3
|
+
이 폴더는 `chaeditor`를 host app 디자인 시스템에 연결할 때 바로 참고하거나 복사해서 시작할 수 있는 wrapper preset 초안을 모아둔 곳입니다.
|
|
4
|
+
|
|
5
|
+
포함된 템플릿:
|
|
6
|
+
|
|
7
|
+
- `tailwind-host-preset.tsx.template`
|
|
8
|
+
- `emotion-host-preset.tsx.template`
|
|
9
|
+
- `styled-components-host-preset.tsx.template`
|
|
10
|
+
- `vanilla-extract-host-preset.tsx.template`
|
|
11
|
+
|
|
12
|
+
공통 원칙:
|
|
13
|
+
|
|
14
|
+
- `createChaeditorThemeVars()`로 semantic theme variables를 먼저 주입합니다.
|
|
15
|
+
- `primitiveRegistry`로 `Button`, `Input`, `Textarea`, `Popover`, `Modal`, `Tooltip` shell을 교체합니다.
|
|
16
|
+
- 실제 서비스 코드에서는 파일명과 import 경로를 프로젝트 구조에 맞게 조정하면 됩니다.
|