tiptop-editor 1.1.0 → 1.3.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.
Files changed (30) hide show
  1. package/README.md +131 -2
  2. package/dist/components/editor/TableSelectionMenu.d.ts +4 -0
  3. package/dist/components/editor/TiptopEditor.d.ts +3 -0
  4. package/dist/components/editor/TiptopEditor.stories.d.ts +17 -0
  5. package/dist/components/editor/TiptopEditorContext.d.ts +3 -0
  6. package/dist/components/editor/createDefaultExtensions.d.ts +8 -0
  7. package/dist/components/editor/renderTiptopSlot.d.ts +4 -0
  8. package/dist/components/editor/useDuplicateExtensionWarnings.d.ts +2 -0
  9. package/dist/components/{ColorButton.d.ts → menus/ColorButton.d.ts} +1 -1
  10. package/dist/components/{TextSelectionMenu.d.ts → menus/TextSelectionMenu.d.ts} +1 -1
  11. package/dist/components/{EditorButton.d.ts → ui/EditorButton.d.ts} +1 -1
  12. package/dist/index.d.ts +2 -1
  13. package/dist/tiptop-editor.css +1 -1
  14. package/dist/tiptop-editor.es.js +2907 -2831
  15. package/dist/tiptop-editor.umd.js +18 -18
  16. package/dist/types.d.ts +26 -0
  17. package/package.json +7 -2
  18. package/dist/components/TableSelectionMenu.d.ts +0 -4
  19. package/dist/components/TiptopEditor.d.ts +0 -7
  20. /package/dist/components/{DragHandleColorList.d.ts → editor/DragHandleColorList.d.ts} +0 -0
  21. /package/dist/components/{TiptopDragHandle.d.ts → editor/TiptopDragHandle.d.ts} +0 -0
  22. /package/dist/components/{TransformIntoIcon.d.ts → editor/TransformIntoIcon.d.ts} +0 -0
  23. /package/dist/components/{ColorButtonMenu.d.ts → menus/ColorButtonMenu.d.ts} +0 -0
  24. /package/dist/components/{LinkButtonMenu.d.ts → menus/LinkButtonMenu.d.ts} +0 -0
  25. /package/dist/components/{MoreOptionsButtonMenu.d.ts → menus/MoreOptionsButtonMenu.d.ts} +0 -0
  26. /package/dist/components/{TableButtonMenu.d.ts → menus/TableButtonMenu.d.ts} +0 -0
  27. /package/dist/components/{TransformIntoButtonMenu.d.ts → menus/TransformIntoButtonMenu.d.ts} +0 -0
  28. /package/dist/components/{CloseIcon.d.ts → ui/CloseIcon.d.ts} +0 -0
  29. /package/dist/components/{ColorIcon.d.ts → ui/ColorIcon.d.ts} +0 -0
  30. /package/dist/components/{Icon.d.ts → ui/Icon.d.ts} +0 -0
package/README.md CHANGED
@@ -43,7 +43,134 @@ export function Editor() {
43
43
  }
44
44
  ```
45
45
 
46
- `editorOptions` accepts the same options as `useEditor` from `@tiptap/react`, except `extensions`, which is managed internally by the package.
46
+ `editorOptions` accepts the same options as `useEditor` from `@tiptap/react`, except `extensions`, which is managed internally by the package. To add your own extensions, use `editorOptions.extraExtensions`.
47
+
48
+ ## Editor Ref and Events
49
+
50
+ You can access the editor instance and bind Tiptap runtime event listeners through the component ref.
51
+
52
+ ```tsx
53
+ import { useEffect, useRef } from 'react'
54
+ import { TiptopEditor, type TiptopEditorHandle } from 'tiptop-editor'
55
+
56
+ export function EditorWithEvents() {
57
+ const editorRef = useRef<TiptopEditorHandle>(null)
58
+
59
+ useEffect(() => {
60
+ const handleUpdate = ({ editor }: { editor: NonNullable<ReturnType<TiptopEditorHandle['getEditor']>> }) => {
61
+ console.log(editor.getHTML())
62
+ }
63
+
64
+ editorRef.current?.on('update', handleUpdate)
65
+
66
+ return () => {
67
+ editorRef.current?.off('update', handleUpdate)
68
+ }
69
+ }, [])
70
+
71
+ return <TiptopEditor ref={editorRef} />
72
+ }
73
+ ```
74
+
75
+ Available ref methods:
76
+
77
+ - `getEditor()`
78
+ - `on(event, callback)`
79
+ - `off(event, callback?)`
80
+ - `once(event, callback)`
81
+
82
+ ## Extending the Editor
83
+
84
+ The package now supports two extension points:
85
+
86
+ - `editorOptions.extraExtensions`
87
+ Appends custom Tiptap extensions after the built-in set.
88
+ - `slots`
89
+ Lets you inject custom React UI around the editor and inside the selection menus.
90
+
91
+ ### Add custom Tiptap extensions
92
+
93
+ ```tsx
94
+ import { Extension } from '@tiptap/core'
95
+ import { TiptopEditor } from 'tiptop-editor'
96
+
97
+ const MyExtension = Extension.create({
98
+ name: 'myExtension',
99
+ })
100
+
101
+ export function EditorWithExtraExtensions() {
102
+ return (
103
+ <TiptopEditor
104
+ editorOptions={{
105
+ immediatelyRender: false,
106
+ extraExtensions: [MyExtension],
107
+ }}
108
+ />
109
+ )
110
+ }
111
+ ```
112
+
113
+ `extraExtensions` is additive only. If you pass an extension with the same name as one of the built-in extensions, the editor will warn in the console and show a toast because duplicate extension names can lead to unstable behavior.
114
+
115
+ ### Add custom UI with slots
116
+
117
+ Supported slots:
118
+
119
+ - `editorTop`
120
+ - `editorBottom`
121
+ - `selectionMenuPrepend`
122
+ - `selectionMenuAppend`
123
+ - `tableMenuPrepend`
124
+ - `tableMenuAppend`
125
+
126
+ Each slot accepts either:
127
+
128
+ - a React node
129
+ - a render function receiving `{ editor }`
130
+
131
+ ```tsx
132
+ <TiptopEditor
133
+ slots={{
134
+ editorTop: ({ editor }) => (
135
+ <button onClick={() => editor.chain().focus().insertContent('<p>Draft</p>').run()}>
136
+ Insert draft
137
+ </button>
138
+ ),
139
+ }}
140
+ />
141
+ ```
142
+
143
+ ### Use the editor context hook
144
+
145
+ For slotted components, you can consume the current editor instance through `useTiptopEditor()` instead of passing `editor` down manually.
146
+
147
+ ```tsx
148
+ import { TiptopEditor, useTiptopEditor } from 'tiptop-editor'
149
+
150
+ function AiToolbar() {
151
+ const editor = useTiptopEditor()
152
+
153
+ if (!editor) {
154
+ return null
155
+ }
156
+
157
+ return (
158
+ <button onClick={() => editor.chain().focus().insertContent('<p>AI draft</p>').run()}>
159
+ Insert draft
160
+ </button>
161
+ )
162
+ }
163
+
164
+ export function EditorWithSlots() {
165
+ return (
166
+ <TiptopEditor
167
+ slots={{
168
+ editorTop: <AiToolbar />,
169
+ }}
170
+ />
171
+ )
172
+ }
173
+ ```
47
174
 
48
175
  ## Custom Editor UI Options
49
176
 
@@ -63,6 +190,8 @@ export function Editor() {
63
190
  Disables the default HeroUI `Card` wrapper and removes the editor's built-in padding. Use this when you want the editor to live inside your own container/layout.
64
191
  - `showDragHandle`
65
192
  Controls whether the block drag handle is rendered. Default: `true`.
193
+ - `extraExtensions`
194
+ Appends custom Tiptap extensions after the built-in editor set.
66
195
 
67
196
  ## Built-in Extensions
68
197
 
@@ -208,7 +337,7 @@ Example:
208
337
  ## Notes
209
338
 
210
339
  - If you use SSR, keep `immediatelyRender: false`.
211
- - The package manages the editor extensions internally, so custom `extensions` are intentionally not accepted yet.
340
+ - The package manages the built-in editor extensions internally. Use `editorOptions.extraExtensions` to append your own feature extensions.
212
341
 
213
342
  ## Feedback
214
343
 
@@ -0,0 +1,4 @@
1
+ import { default as React } from 'react';
2
+ import { TextSelectionMenuProps } from '../../types';
3
+ declare const _default: React.MemoExoticComponent<({ editor, prepend, append }: TextSelectionMenuProps) => import("react/jsx-runtime").JSX.Element>;
4
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { TiptopEditorHandle, TiptopEditorProps } from '../../types';
2
+ declare const TiptopEditor: import('react').ForwardRefExoticComponent<Omit<TiptopEditorProps, "ref"> & import('react').RefAttributes<TiptopEditorHandle>>;
3
+ export default TiptopEditor;
@@ -0,0 +1,17 @@
1
+ import { StoryObj } from '@storybook/react-vite';
2
+ declare const meta: {
3
+ title: string;
4
+ component: import('react').ForwardRefExoticComponent<Omit<import('../..').TiptopEditorProps, "ref"> & import('react').RefAttributes<import('../..').TiptopEditorHandle>>;
5
+ tags: string[];
6
+ args: {
7
+ editorOptions: {
8
+ content: string;
9
+ immediatelyRender: false;
10
+ };
11
+ };
12
+ };
13
+ export default meta;
14
+ type Story = StoryObj<typeof meta>;
15
+ export declare const Default: Story;
16
+ export declare const Frameless: Story;
17
+ export declare const WithSlots: Story;
@@ -0,0 +1,3 @@
1
+ import { Editor } from '@tiptap/react';
2
+ export declare const TiptopEditorContext: import('react').Context<Editor | null>;
3
+ export declare const useTiptopEditor: () => Editor | null;
@@ -0,0 +1,8 @@
1
+ import { Extensions } from '@tiptap/core';
2
+ import { ImageUploadResponseResolver } from '../../types';
3
+ interface CreateDefaultExtensionsOptions {
4
+ imgUploadUrl?: string;
5
+ imgUploadResponseKey?: ImageUploadResponseResolver;
6
+ }
7
+ export declare const createDefaultExtensions: ({ imgUploadUrl, imgUploadResponseKey, }: CreateDefaultExtensionsOptions) => Extensions;
8
+ export {};
@@ -0,0 +1,4 @@
1
+ import { Editor } from '@tiptap/react';
2
+ import { ReactNode } from 'react';
3
+ import { TiptopEditorSlot } from '../../types';
4
+ export declare const renderTiptopSlot: (slot: TiptopEditorSlot | undefined, editor: Editor | null) => ReactNode;
@@ -0,0 +1,2 @@
1
+ import { Extensions } from '@tiptap/core';
2
+ export declare const useDuplicateExtensionWarnings: (baseExtensions: Extensions, extraExtensions: Extensions) => void;
@@ -1,4 +1,4 @@
1
1
  import { default as React } from 'react';
2
- import { ColorButtonProps } from '../types';
2
+ import { ColorButtonProps } from '../../types';
3
3
  declare const _default: React.MemoExoticComponent<({ editor, buttonType, hsl, color, bgColor, tooltipText, tooltipDisabled, }: ColorButtonProps) => import("react/jsx-runtime").JSX.Element>;
4
4
  export default _default;
@@ -1,4 +1,4 @@
1
1
  import { default as React } from 'react';
2
- import { TextSelectionMenuProps } from '../types';
2
+ import { TextSelectionMenuProps } from '../../types';
3
3
  declare const _default: React.MemoExoticComponent<({ editor, prepend, append }: TextSelectionMenuProps) => import("react/jsx-runtime").JSX.Element>;
4
4
  export default _default;
@@ -1,4 +1,4 @@
1
- import { EditorButtonProps } from '../types';
1
+ import { EditorButtonProps } from '../../types';
2
2
  import { default as React } from 'react';
3
3
  declare const _default: React.MemoExoticComponent<({ editor, buttonKey, tooltipText, isIconOnly, color, variant, isDisabled, icon, iconClass, text, withActive, onPressed, }: EditorButtonProps) => import("react/jsx-runtime").JSX.Element>;
4
4
  export default _default;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export { default as TiptopEditor } from './components/TiptopEditor';
1
+ export { default as TiptopEditor } from './components/editor/TiptopEditor';
2
+ export { TiptopEditorContext, useTiptopEditor } from './components/editor/TiptopEditorContext';
2
3
  export * from './types';