@mpdev_ab/document-creator 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/README.md +260 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,260 @@
1
+ # @mpdev_ab/document-creator
2
+
3
+ A rich text editor Vue 3 component built on Tiptap. Drop-in replacement for TinyMCE with font selection, tables, image upload (base64), templates, and full formatting — outputs HTML.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @mpdev_ab/document-creator
9
+ ```
10
+
11
+ ### Peer dependencies
12
+
13
+ Your project needs Vue 3 and the Tiptap packages:
14
+
15
+ ```bash
16
+ npm install vue@^3.3.0 @tiptap/core @tiptap/vue-3 @tiptap/pm @tiptap/starter-kit @tiptap/extension-text-style @tiptap/extension-font-family @tiptap/extension-image @tiptap/extension-table @tiptap/extension-table-row @tiptap/extension-table-cell @tiptap/extension-table-header @tiptap/extension-underline @tiptap/extension-subscript @tiptap/extension-superscript @tiptap/extension-text-align @tiptap/extension-link @tiptap/extension-color @tiptap/extension-placeholder
17
+ ```
18
+
19
+ ## Basic usage
20
+
21
+ ```vue
22
+ <template>
23
+ <DocumentEditor
24
+ v-model="content"
25
+ :api="api"
26
+ />
27
+ </template>
28
+
29
+ <script setup>
30
+ import { ref } from 'vue'
31
+ import { DocumentEditor } from '@mpdev_ab/document-creator'
32
+
33
+ const content = ref('')
34
+
35
+ const api = {
36
+ saveDocument: '/api/documents',
37
+ saveTemplate: '/api/templates',
38
+ loadTemplates: '/api/templates',
39
+ deleteTemplate: '/api/templates',
40
+ }
41
+ </script>
42
+ ```
43
+
44
+ ## Nuxt 3
45
+
46
+ Create a plugin at `plugins/document-creator.client.ts`:
47
+
48
+ ```ts
49
+ import { DocumentEditor } from '@mpdev_ab/document-creator'
50
+
51
+ export default defineNuxtPlugin((nuxtApp) => {
52
+ nuxtApp.vueApp.component('DocumentEditor', DocumentEditor)
53
+ })
54
+ ```
55
+
56
+ Then use it in any page/component:
57
+
58
+ ```vue
59
+ <template>
60
+ <ClientOnly>
61
+ <DocumentEditor v-model="content" :api="api" />
62
+ </ClientOnly>
63
+ </template>
64
+ ```
65
+
66
+ Wrap in `<ClientOnly>` since the editor requires the DOM.
67
+
68
+ ## Props
69
+
70
+ | Prop | Type | Required | Default | Description |
71
+ |------|------|----------|---------|-------------|
72
+ | `v-model` | `string` | Yes | — | HTML content (two-way binding) |
73
+ | `api` | `ApiConfig` | Yes | — | API endpoint URLs for save/templates |
74
+ | `mode` | `'document' \| 'template'` | No | `'document'` | Determines which save endpoint is used |
75
+ | `templateMeta` | `TemplateMeta` | No | — | Name and type sent when saving in template mode |
76
+ | `image` | `ImageConfig` | No | `{ maxSize: 5MB, allowedTypes: ['image/jpeg', 'image/png', 'image/gif'] }` | Image upload constraints |
77
+ | `theme` | `Partial<ThemeConfig>` | No | See defaults below | Tailwind class overrides |
78
+ | `placeholder` | `string` | No | `''` | Placeholder text when editor is empty |
79
+ | `readonly` | `boolean` | No | `false` | Hides toolbar and disables editing |
80
+
81
+ ## Events
82
+
83
+ | Event | Payload | Description |
84
+ |-------|---------|-------------|
85
+ | `update:modelValue` | `string` | Emitted on every content change (used by v-model) |
86
+ | `save` | `unknown` | Emitted with the API response after a successful save |
87
+ | `error` | `{ message: string; detail: unknown }` | Emitted on save/template/image errors |
88
+
89
+ ## ApiConfig (required)
90
+
91
+ All four endpoint URLs are required. The component uses `fetch` with `POST` method and `Content-Type: application/json`.
92
+
93
+ ```ts
94
+ const api = {
95
+ saveDocument: '/api/documents', // POST { content: "<html>" }
96
+ saveTemplate: '/api/templates', // POST { name, type, content }
97
+ loadTemplates: '/api/templates', // GET — must return Template[]
98
+ deleteTemplate: '/api/templates', // DELETE /{id}
99
+ headers: { // Optional — added to all requests
100
+ 'Authorization': 'Bearer your-token',
101
+ },
102
+ }
103
+ ```
104
+
105
+ ### Expected API responses
106
+
107
+ **GET loadTemplates** — return an array:
108
+ ```json
109
+ [
110
+ { "id": 1, "name": "Invoice", "type": "document", "content": "<h1>Invoice</h1>..." },
111
+ { "id": 2, "name": "Signature", "type": "snippet", "content": "<p>Regards,</p>..." }
112
+ ]
113
+ ```
114
+
115
+ **DELETE deleteTemplate** — called as `DELETE {deleteTemplate}/{id}`
116
+
117
+ ## ImageConfig
118
+
119
+ ```ts
120
+ const imageConfig = {
121
+ maxSize: 10 * 1024 * 1024, // 10MB (default: 5MB)
122
+ allowedTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
123
+ }
124
+ ```
125
+
126
+ Images are converted to base64 and stored inline in the HTML. After inserting, users can resize images using preset buttons (25%, 50%, 75%, 100%) or enter a custom width.
127
+
128
+ ## ThemeConfig
129
+
130
+ Override any part of the default Tailwind classes:
131
+
132
+ ```vue
133
+ <DocumentEditor
134
+ v-model="content"
135
+ :api="api"
136
+ :theme="{
137
+ toolbar: 'bg-gray-900 border-b border-gray-700 p-2 flex flex-wrap items-center gap-1',
138
+ toolbarButton: 'hover:bg-gray-700 rounded p-1.5 text-gray-300 cursor-pointer',
139
+ toolbarButtonActive: 'bg-blue-900 text-blue-300',
140
+ editor: 'bg-gray-800 text-white min-h-[400px] p-4 prose prose-invert max-w-none',
141
+ dropdown: 'bg-gray-800 border border-gray-700 rounded shadow-lg py-1 z-50',
142
+ modal: 'bg-gray-800 text-white rounded-lg shadow-xl p-6',
143
+ saveButton: 'bg-blue-500 text-white rounded px-4 py-2 hover:bg-blue-600',
144
+ }"
145
+ />
146
+ ```
147
+
148
+ **Defaults:**
149
+ | Key | Default classes |
150
+ |-----|----------------|
151
+ | `toolbar` | `bg-white border-b border-gray-200 p-2 flex flex-wrap items-center gap-1` |
152
+ | `toolbarButton` | `hover:bg-gray-100 rounded p-1.5 text-gray-600 cursor-pointer` |
153
+ | `toolbarButtonActive` | `bg-blue-100 text-blue-600` |
154
+ | `editor` | `bg-white min-h-[400px] p-4 prose max-w-none focus:outline-none` |
155
+ | `dropdown` | `bg-white border border-gray-200 rounded shadow-lg py-1 z-50` |
156
+ | `modal` | `bg-white rounded-lg shadow-xl p-6` |
157
+ | `saveButton` | `bg-blue-600 text-white rounded px-4 py-2 hover:bg-blue-700` |
158
+
159
+ ## useDocumentEditor composable
160
+
161
+ Access the editor instance from child components:
162
+
163
+ ```vue
164
+ <script setup>
165
+ import { useDocumentEditor } from '@mpdev_ab/document-creator'
166
+
167
+ const { editor, getHTML, getText, setContent, focus, isEmpty } = useDocumentEditor()
168
+
169
+ // Get current HTML
170
+ const html = getHTML()
171
+
172
+ // Set content programmatically
173
+ setContent('<p>New content</p>')
174
+
175
+ // Check if empty
176
+ if (isEmpty()) {
177
+ // ...
178
+ }
179
+ </script>
180
+ ```
181
+
182
+ This must be called from a component that is a child of `<DocumentEditor>`.
183
+
184
+ ## Template mode
185
+
186
+ Save the editor content as a reusable template:
187
+
188
+ ```vue
189
+ <DocumentEditor
190
+ v-model="content"
191
+ mode="template"
192
+ :template-meta="{ name: 'My Template', type: 'document' }"
193
+ :api="api"
194
+ @save="(res) => console.log('Template saved', res)"
195
+ />
196
+ ```
197
+
198
+ When `mode="template"`, clicking Save sends `{ name, type, content }` to `api.saveTemplate` instead of `api.saveDocument`.
199
+
200
+ Template types:
201
+ - `document` — replaces the entire editor content when loaded
202
+ - `snippet` — inserts at the cursor position when loaded
203
+
204
+ ## Full example
205
+
206
+ ```vue
207
+ <template>
208
+ <DocumentEditor
209
+ v-model="content"
210
+ mode="document"
211
+ placeholder="Write your document..."
212
+ :readonly="false"
213
+ :api="{
214
+ saveDocument: '/api/documents',
215
+ saveTemplate: '/api/templates',
216
+ loadTemplates: '/api/templates',
217
+ deleteTemplate: '/api/templates',
218
+ headers: { 'Authorization': `Bearer ${token}` },
219
+ }"
220
+ :image="{
221
+ maxSize: 10 * 1024 * 1024,
222
+ allowedTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
223
+ }"
224
+ @save="onSave"
225
+ @error="onError"
226
+ />
227
+ </template>
228
+
229
+ <script setup>
230
+ import { ref } from 'vue'
231
+ import { DocumentEditor } from '@mpdev_ab/document-creator'
232
+
233
+ const content = ref('<p>Hello world</p>')
234
+ const token = 'your-auth-token'
235
+
236
+ function onSave(response) {
237
+ console.log('Saved:', response)
238
+ }
239
+
240
+ function onError(error) {
241
+ console.error(error.message, error.detail)
242
+ }
243
+ </script>
244
+ ```
245
+
246
+ ## Features
247
+
248
+ - Bold, italic, underline, strikethrough, subscript, superscript
249
+ - Font family (web-safe fonts), font size, font color
250
+ - Text alignment (left, center, right, justify)
251
+ - Line height
252
+ - Headings (H1-H6) and paragraph
253
+ - Bullet lists, numbered lists, blockquotes, horizontal rules
254
+ - Links with URL input
255
+ - Image upload (base64) with in-editor resize (25/50/75/100% presets + custom width)
256
+ - Tables with Google Docs-style grid picker, row/column operations, merge/split cells, header toggle, cell background color, column resize
257
+ - Video embed (YouTube/Vimeo URL)
258
+ - Save/load templates (full documents and snippets)
259
+ - Readonly mode
260
+ - Tailwind CSS theming via class string props
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpdev_ab/document-creator",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"