@shnea/editor
v0.1.5
Published
Reusable Tiptap-based editor and viewer package with configurable file-service upload integration.
Readme
@shnea/editor
@shnea/editor is a reusable Tiptap-based editor package for Shnea services.
It provides:
ShneaEditor: a rich text editor wrapper for article, comment, sms, and no-toolbar presetsShneaViewer: a sanitized HTML viewer with click-to-zoom image previewcreateFileServiceUploadAdapter: a file-service integration helper for image and file uploads
ShneaEditor itself is not tied to file-service.
If your app has its own upload API, pass a custom uploadAdapter.
Use createFileServiceUploadAdapter only when you want to call Shnea file-service.
Install
npm install @shnea/editorUsage
import { ShneaEditor, createFileServiceUploadAdapter } from '@shnea/editor';
import '@shnea/editor/editor.css';
const uploadAdapter = createFileServiceUploadAdapter({
baseUrl: import.meta.env.VITE_FILE_SERVICE_BASE_URL,
bearerToken: accessToken,
retentionCategory: 'editor',
});
<ShneaEditor
mode="article"
value={value}
onChange={(html) => setValue(html)}
uploadAdapter={uploadAdapter}
/>;Modes
article: full toolbar presetcomment: compact writing presetsms: byte-limited presetno-toolbar: editor preset without toolbar UI
Fonts
Pretendard400/600 is loaded by default for editor font selection.- Other bundled font options are loaded lazily when selected in the toolbar.
Upload adapter choice
Use one of these two patterns:
- Use
createFileServiceUploadAdapterwhen you want to upload to Shnea file-service. - Use a custom
uploadAdapterwhen you want to upload to your own file API.
@shnea/editor does not read env vars or manage tokens by itself.
The consuming app is responsible for preparing and passing upload configuration.
Editor upload behavior:
- Raster images are converted to compressed
webpbefore upload. - Large images are resized down to a max edge of
2560pxbefore encoding. gifandsvguploads are left unchanged.- The editor shows an in-place loading overlay while uploads are running.
1. Use Shnea file-service
import { ShneaEditor, createFileServiceUploadAdapter } from '@shnea/editor';
const uploadAdapter = createFileServiceUploadAdapter({
baseUrl: import.meta.env.VITE_FILE_SERVICE_BASE_URL,
bearerToken: accessToken,
retentionCategory: 'editor',
});2. Use your own upload API
import { ShneaEditor } from '@shnea/editor';
const uploadAdapter = async (file: File) => {
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/api/uploads', {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error('Upload failed');
}
const data = await response.json();
return {
url: data.previewUrl ?? data.url,
name: data.name ?? file.name,
fileId: data.fileId,
previewUrl: data.previewUrl ?? data.url,
downloadUrl: data.downloadUrl ?? data.url,
mimeType: file.type,
size: file.size,
};
};File service integration
- Uploads use
POST /files/uploadwith Bearer JWT. createFileServiceUploadAdaptersendsretentionCategory=editorby default.- Override
retentionCategoryper consumer app when a different retention policy is required. - Reads use the returned
previewUrlordownloadUrl. - Store
fileIdas the canonical attachment reference in the consuming service. - Handle
401,413, and507as explicit upload failures.
Detailed integration docs:
Scripts
npm run build: build the packagenpm run check: TypeScript type-checknpm run test: alias ofcheck
Environment
The package itself does not read env vars directly.
If you use createFileServiceUploadAdapter, the consuming app should provide:
FILE_SERVICE_BASE_URL- a valid upload Bearer token
