tiptop-editor 1.6.5 → 2.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/README.md CHANGED
@@ -25,6 +25,32 @@ https://tiptap.dev/docs/ui-components/templates/notion-like-editor
25
25
  npm install tiptop-editor
26
26
  ```
27
27
 
28
+ ## Setup
29
+
30
+ This package requires HeroUI v3. Add its styles import to your CSS entry file:
31
+
32
+ ```css
33
+ @import "tailwindcss";
34
+ @import "@heroui/styles";
35
+ ```
36
+
37
+ No `HeroUIProvider` wrapper is needed in your app — HeroUI v3 works without a root provider.
38
+
39
+ If you use the toast notifications, render `Toast.Provider` once near the root of your app:
40
+
41
+ ```tsx
42
+ import { Toast } from '@heroui/react'
43
+
44
+ export function App() {
45
+ return (
46
+ <>
47
+ <YourApp />
48
+ <Toast.Provider placement="top end" />
49
+ </>
50
+ )
51
+ }
52
+ ```
53
+
28
54
  ## Basic Usage
29
55
 
30
56
  ```tsx
@@ -122,6 +148,7 @@ Supported slots:
122
148
  - `selectionMenuAppend`
123
149
  - `tableMenuPrepend`
124
150
  - `tableMenuAppend`
151
+ - `dragHandleDropdown`
125
152
 
126
153
  Each slot accepts either:
127
154
 
@@ -140,6 +167,24 @@ Each slot accepts either:
140
167
  />
141
168
  ```
142
169
 
170
+ The `dragHandleDropdown` slot injects additional items into the block drag-handle dropdown. The slot content must be wrapped in a `<Dropdown.Section>`:
171
+
172
+ ```tsx
173
+ import { Dropdown, Label } from '@heroui/react'
174
+
175
+ <TiptopEditor
176
+ slots={{
177
+ dragHandleDropdown: ({ editor }) => (
178
+ <Dropdown.Section>
179
+ <Dropdown.Item id="ai_rewrite" textValue="AI Rewrite" onPress={() => console.log('AI rewrite', editor)}>
180
+ <Label>AI Rewrite</Label>
181
+ </Dropdown.Item>
182
+ </Dropdown.Section>
183
+ ),
184
+ }}
185
+ />
186
+ ```
187
+
143
188
  ### Use the editor context hook
144
189
 
145
190
  For slotted components, you can consume the current editor instance through `useTiptopEditor()` instead of passing `editor` down manually.
@@ -192,6 +237,12 @@ export function EditorWithSlots() {
192
237
  Controls whether the block drag handle is rendered. Default: `true`.
193
238
  - `extraExtensions`
194
239
  Appends custom Tiptap extensions after the built-in editor set.
240
+ - `imgUploadUrl`
241
+ The URL of the server endpoint that receives image uploads.
242
+ - `imgUploadResponseKey`
243
+ Locates the image URL in the server response. Accepts a top-level key, a dot-separated path, a path array, or a resolver function.
244
+ - `imgUploadHeaders`
245
+ Custom HTTP headers sent with every image upload request (e.g. `Authorization`).
195
246
 
196
247
  ## Built-in Extensions
197
248
 
@@ -322,6 +373,33 @@ The editor sends a `POST` request with `multipart/form-data` and the file under
322
373
  />
323
374
  ```
324
375
 
376
+ ### Sending custom headers
377
+
378
+ Use `imgUploadHeaders` to attach custom HTTP headers to every upload request. This is the standard way to pass an authorization token or any other API header.
379
+
380
+ ```tsx
381
+ <TiptopEditor
382
+ editorOptions={{
383
+ imgUploadUrl: '/api/upload',
384
+ imgUploadResponseKey: 'url',
385
+ imgUploadHeaders: {
386
+ Authorization: 'Bearer YOUR_TOKEN',
387
+ },
388
+ }}
389
+ />
390
+ ```
391
+
392
+ Multiple headers are supported:
393
+
394
+ ```tsx
395
+ imgUploadHeaders: {
396
+ Authorization: 'Bearer YOUR_TOKEN',
397
+ 'X-Api-Key': 'YOUR_API_KEY',
398
+ }
399
+ ```
400
+
401
+ > **Note**: The editor sends `multipart/form-data`. Do **not** include a `Content-Type` header in `imgUploadHeaders` — the browser sets it automatically with the correct boundary string.
402
+
325
403
  Your server response must include the uploaded image URL at the location you describe with `imgUploadResponseKey`.
326
404
 
327
405
  Example:
@@ -1,5 +1,6 @@
1
1
  import { Editor } from '@tiptap/react';
2
- declare const TiptopDragHandle: ({ editor }: {
2
+ declare const TiptopDragHandle: ({ editor, dragHandleSlot }: {
3
3
  editor: Editor;
4
+ dragHandleSlot?: React.ReactNode;
4
5
  }) => import("react/jsx-runtime").JSX.Element;
5
6
  export default TiptopDragHandle;
@@ -15,3 +15,5 @@ type Story = StoryObj<typeof meta>;
15
15
  export declare const Default: Story;
16
16
  export declare const Frameless: Story;
17
17
  export declare const WithSlots: Story;
18
+ export declare const ViewMode: Story;
19
+ export declare const WithDragHandleSlot: Story;
@@ -3,6 +3,7 @@ import { ImageUploadResponseResolver } from '../../types';
3
3
  interface CreateDefaultExtensionsOptions {
4
4
  imgUploadUrl?: string;
5
5
  imgUploadResponseKey?: ImageUploadResponseResolver;
6
+ imgUploadHeaders?: Record<string, string>;
6
7
  }
7
- export declare const createDefaultExtensions: ({ imgUploadUrl, imgUploadResponseKey, }: CreateDefaultExtensionsOptions) => Extensions;
8
+ export declare const createDefaultExtensions: ({ imgUploadUrl, imgUploadResponseKey, imgUploadHeaders, }: CreateDefaultExtensionsOptions) => Extensions;
8
9
  export {};
@@ -1,4 +1,4 @@
1
1
  import { EditorButtonProps } from '../../types';
2
2
  import { default as React } from 'react';
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>;
3
+ declare const _default: React.MemoExoticComponent<({ editor, buttonKey, tooltipText, isIconOnly, variant, isDisabled, icon, iconClass, text, withActive, onPressed, }: EditorButtonProps) => import("react/jsx-runtime").JSX.Element>;
4
4
  export default _default;
package/dist/helpers.d.ts CHANGED
@@ -19,11 +19,12 @@ export declare const removeAllFormatting: (editor: Editor) => void;
19
19
  export declare const transformNodeToAlternative: (editor: Editor, targetOption: SlashCommandGroupCommandsProps) => void;
20
20
  export declare const addOrUpdateLink: (editor: Editor, url: string) => void;
21
21
  export declare const unsetLink: (editor: Editor) => void;
22
- export declare const uploadWithProgress: ({ file, url, onProgress, signal }: {
22
+ export declare const uploadWithProgress: ({ file, url, onProgress, signal, headers }: {
23
23
  file: File;
24
24
  url: string;
25
25
  onProgress: (percent: number) => boolean | void;
26
26
  signal?: AbortSignal;
27
+ headers?: Record<string, string>;
27
28
  }) => Promise<Record<string, unknown>>;
28
29
  export declare const getValueAtPath: (source: Record<string, unknown>, path: string | string[]) => unknown;
29
30
  export declare const generateUniqueId: () => string;
@@ -31,7 +32,7 @@ export declare const updateNodeByPos: (editor: Editor, find: {
31
32
  id?: string;
32
33
  pos?: number;
33
34
  }, attrs: Record<string, string | boolean | number | File | null>) => void;
34
- export declare const showToast: (title?: string, color?: "primary" | "default" | "foreground" | "secondary" | "success" | "warning" | "danger" | undefined, description?: string) => void;
35
+ export declare const showToast: (title?: string, color?: "accent" | "default" | "success" | "warning" | "danger" | undefined, description?: string) => void;
35
36
  export declare const getUploaderAtPos: (state: Editor["state"], pos: number) => {
36
37
  pos: number;
37
38
  start: number;