@opensaas/stack-tiptap 0.1.0 → 0.1.2

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.
@@ -1,8 +1,10 @@
1
1
 
2
- > @opensaas/stack-tiptap@0.1.0 build /home/runner/work/stack/stack/packages/tiptap
2
+ > @opensaas/stack-tiptap@0.1.2 build /home/runner/work/stack/stack/packages/tiptap
3
3
  > tsc && npm run copy:css
4
4
 
5
+ npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
6
+ npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
5
7
 
6
- > @opensaas/stack-tiptap@0.1.0 copy:css
8
+ > @opensaas/stack-tiptap@0.1.2 copy:css
7
9
  > mkdir -p dist/styles && cp src/styles/tiptap.css dist/styles/
8
10
 
package/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # @opensaas/stack-tiptap
2
+
3
+ ## 0.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - @opensaas/stack-core@0.1.2
8
+ - @opensaas/stack-ui@0.1.2
9
+
10
+ ## 0.1.1
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies [9a3fda5]
15
+ - Updated dependencies [f8ebc0e]
16
+ - Updated dependencies [045c071]
17
+ - @opensaas/stack-core@0.1.1
18
+ - @opensaas/stack-ui@0.1.1
package/CLAUDE.md ADDED
@@ -0,0 +1,274 @@
1
+ # @opensaas/stack-tiptap
2
+
3
+ Third-party field package providing rich text editing with Tiptap editor for OpenSaas Stack.
4
+
5
+ ## Purpose
6
+
7
+ Demonstrates how to create third-party field packages that extend OpenSaas Stack without modifying core. Provides production-ready rich text editing with JSON storage.
8
+
9
+ ## Key Files & Exports
10
+
11
+ ### Field Builder (`src/fields/richText.ts`)
12
+
13
+ - `richText(options?)` - Field builder function
14
+ - Returns `RichTextField` type implementing `BaseFieldConfig`
15
+ - Methods: `getZodSchema()`, `getPrismaType()`, `getTypeScriptType()`
16
+
17
+ ### Component (`src/components/TiptapField.tsx`)
18
+
19
+ - `TiptapField` - React component (client component)
20
+ - Uses Tiptap editor with StarterKit
21
+ - Supports edit/read modes, custom toolbar
22
+
23
+ ### Main Exports (`src/index.ts`)
24
+
25
+ - Re-exports field builder and component
26
+ - Separate exports for `/fields` and `/components`
27
+
28
+ ## Architecture
29
+
30
+ ### Self-Contained Field Pattern
31
+
32
+ Complete third-party field implementation:
33
+
34
+ ```typescript
35
+ // Field builder
36
+ export function richText(options) {
37
+ return {
38
+ type: 'richText',
39
+ ...options,
40
+ getPrismaType: () => ({ type: 'Json', modifiers: '' }),
41
+ getTypeScriptType: () => ({ type: 'any', optional: !options?.validation?.isRequired }),
42
+ getZodSchema: (fieldName, operation) => {
43
+ return operation === 'create' && options?.validation?.isRequired
44
+ ? z.any().refine((val) => val, 'Required')
45
+ : z.any().optional()
46
+ },
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### Client-Side Registration
52
+
53
+ Due to Next.js server/client boundaries:
54
+
55
+ ```typescript
56
+ // lib/register-fields.ts
57
+ 'use client'
58
+ import { registerFieldComponent } from '@opensaas/stack-ui'
59
+ import { TiptapField } from '@opensaas/stack-tiptap'
60
+
61
+ registerFieldComponent('richText', TiptapField)
62
+
63
+ // app/admin/[[...admin]]/page.tsx
64
+ import '../../../lib/register-fields' // Side-effect import
65
+ ```
66
+
67
+ ### JSON Storage
68
+
69
+ Content stored as Prisma `Json` type:
70
+
71
+ ```prisma
72
+ model Article {
73
+ content Json // Tiptap JSON structure
74
+ }
75
+ ```
76
+
77
+ TypeScript type:
78
+
79
+ ```typescript
80
+ type Article = {
81
+ content: any // JSON structure
82
+ }
83
+ ```
84
+
85
+ ## Integration Points
86
+
87
+ ### With @opensaas/stack-core
88
+
89
+ - Implements `BaseFieldConfig` interface
90
+ - Works with generator system (no core changes)
91
+ - Compatible with access control and hooks
92
+
93
+ ### With @opensaas/stack-ui
94
+
95
+ - Uses component registry pattern
96
+ - Receives UI options as props via pass-through
97
+ - Follows field component prop interface
98
+
99
+ ### With Tiptap
100
+
101
+ - Uses `@tiptap/react` and `@tiptap/starter-kit`
102
+ - SSR-safe with `immediatelyRender: false`
103
+ - JSON content structure
104
+
105
+ ## Common Patterns
106
+
107
+ ### Basic Usage
108
+
109
+ ```typescript
110
+ // opensaas.config.ts
111
+ import { richText } from '@opensaas/stack-tiptap/fields'
112
+
113
+ fields: {
114
+ content: richText({
115
+ validation: { isRequired: true },
116
+ ui: {
117
+ placeholder: 'Start writing...',
118
+ minHeight: 200,
119
+ maxHeight: 800,
120
+ },
121
+ })
122
+ }
123
+ ```
124
+
125
+ ### With Access Control
126
+
127
+ ```typescript
128
+ content: richText({
129
+ access: {
130
+ read: () => true,
131
+ create: ({ session }) => !!session,
132
+ update: ({ session, item }) => session?.userId === item.authorId,
133
+ },
134
+ })
135
+ ```
136
+
137
+ ### Custom Extensions
138
+
139
+ ```typescript
140
+ // components/ExtendedTiptap.tsx
141
+ 'use client'
142
+ import { useEditor, EditorContent } from '@tiptap/react'
143
+ import StarterKit from '@tiptap/starter-kit'
144
+ import Link from '@tiptap/extension-link'
145
+ import Image from '@tiptap/extension-image'
146
+
147
+ export function ExtendedTiptap({ value, onChange, ...props }) {
148
+ const editor = useEditor({
149
+ extensions: [StarterKit, Link, Image],
150
+ content: value,
151
+ immediatelyRender: false,
152
+ onUpdate: ({ editor }) => onChange(editor.getJSON())
153
+ })
154
+
155
+ return <EditorContent editor={editor} />
156
+ }
157
+
158
+ // lib/register-fields.ts
159
+ registerFieldComponent('richTextExtended', ExtendedTiptap)
160
+
161
+ // opensaas.config.ts
162
+ content: richText({ ui: { fieldType: 'richTextExtended' } })
163
+ ```
164
+
165
+ ## Third-Party Field Package Requirements
166
+
167
+ This package demonstrates all requirements for third-party fields:
168
+
169
+ ### 1. Field Builder with Required Methods
170
+
171
+ ```typescript
172
+ export type RichTextField = BaseFieldConfig & {
173
+ type: 'richText'
174
+ // Custom options
175
+ }
176
+
177
+ export function richText(options?): RichTextField {
178
+ return {
179
+ type: 'richText',
180
+ ...options,
181
+ getZodSchema: (fieldName, operation) => {
182
+ /* ... */
183
+ },
184
+ getPrismaType: (fieldName) => {
185
+ /* ... */
186
+ },
187
+ getTypeScriptType: () => {
188
+ /* ... */
189
+ },
190
+ }
191
+ }
192
+ ```
193
+
194
+ ### 2. React Component with Standard Props
195
+
196
+ ```typescript
197
+ export interface TiptapFieldProps {
198
+ name: string
199
+ value: any
200
+ onChange: (value: any) => void
201
+ label: string
202
+ error?: string
203
+ disabled?: boolean
204
+ required?: boolean
205
+ mode?: 'read' | 'edit'
206
+ // Plus custom UI options
207
+ placeholder?: string
208
+ minHeight?: number
209
+ maxHeight?: number
210
+ }
211
+ ```
212
+
213
+ ### 3. Client-Side Registration
214
+
215
+ ```typescript
216
+ 'use client'
217
+ import { registerFieldComponent } from '@opensaas/stack-ui'
218
+ import { TiptapField } from '@opensaas/stack-tiptap'
219
+
220
+ registerFieldComponent('richText', TiptapField)
221
+ ```
222
+
223
+ ### 4. SSR Safety
224
+
225
+ ```typescript
226
+ const editor = useEditor({
227
+ extensions: [StarterKit],
228
+ content: value,
229
+ immediatelyRender: false, // Critical for Next.js SSR
230
+ onUpdate: ({ editor }) => onChange(editor.getJSON()),
231
+ })
232
+ ```
233
+
234
+ ## Package Structure
235
+
236
+ ```
237
+ packages/tiptap/
238
+ ├── src/
239
+ │ ├── fields/
240
+ │ │ └── richText.ts # Field builder
241
+ │ ├── components/
242
+ │ │ └── TiptapField.tsx # React component
243
+ │ ├── config/
244
+ │ │ └── types.ts # Type definitions
245
+ │ └── index.ts # Public exports
246
+ ├── package.json
247
+ └── README.md
248
+ ```
249
+
250
+ ## Exports
251
+
252
+ ```typescript
253
+ // Main export
254
+ import { richText, TiptapField } from '@opensaas/stack-tiptap'
255
+
256
+ // Subpath exports
257
+ import { richText } from '@opensaas/stack-tiptap/fields'
258
+ import { TiptapField } from '@opensaas/stack-tiptap/components'
259
+ ```
260
+
261
+ ## Example
262
+
263
+ See `examples/tiptap-demo` for complete working example.
264
+
265
+ ## Key Principles
266
+
267
+ 1. **No Core Modifications** - Extends stack via `BaseFieldConfig`
268
+ 2. **Self-Contained** - All behavior in field config methods
269
+ 3. **Client Registration** - Components registered on client side
270
+ 4. **UI Options Pass-Through** - Custom options automatically pass to component
271
+ 5. **SSR Safe** - Next.js compatible with proper hydration
272
+ 6. **Type Safe** - Full TypeScript support
273
+
274
+ This package serves as reference implementation for creating third-party field packages.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 OpenSaas Stack Contributors
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensaas/stack-tiptap",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Tiptap rich text editor integration for OpenSaas Stack",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,8 +28,8 @@
28
28
  "next": "^15.0.0 || ^16.0.0",
29
29
  "react": "^19.0.0",
30
30
  "react-dom": "^19.0.0",
31
- "@opensaas/stack-core": "0.1.0",
32
- "@opensaas/stack-ui": "0.1.0"
31
+ "@opensaas/stack-core": "0.1.2",
32
+ "@opensaas/stack-ui": "0.1.2"
33
33
  },
34
34
  "dependencies": {
35
35
  "@tiptap/react": "^3.7.2",
@@ -43,8 +43,8 @@
43
43
  "@types/react": "^19.2.2",
44
44
  "@types/react-dom": "^19.2.2",
45
45
  "typescript": "^5.9.3",
46
- "@opensaas/stack-core": "0.1.0",
47
- "@opensaas/stack-ui": "0.1.0"
46
+ "@opensaas/stack-core": "0.1.2",
47
+ "@opensaas/stack-ui": "0.1.2"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsc && npm run copy:css",