@bizapps/design-system-testing 1.0.11 → 1.6.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.
@@ -0,0 +1,318 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { Editor } from '@tiptap/react';
4
+ import * as _tiptap_core from '@tiptap/core';
5
+ import { ImageOptions } from '@tiptap/extension-image';
6
+
7
+ /**
8
+ * A toolbar entry is data, never a mark.
9
+ *
10
+ * An editor's marks are ProseMirror extensions — code with serialization and
11
+ * parsing rules — so they belong to whoever owns the document contract, not to
12
+ * this package. A consumer declares what its buttons do here and keeps its own
13
+ * custom marks; the toolbar only asks the editor whether something is active
14
+ * and runs the callback it was handed.
15
+ */
16
+ type ToolbarItem = {
17
+ kind: 'separator';
18
+ } | {
19
+ kind: 'button';
20
+ id: string;
21
+ /**
22
+ * A node, not an icon name: keeps this package off any icon library
23
+ * and lets a button pass bare text (a font's own name, say) instead.
24
+ */
25
+ icon: ReactNode;
26
+ /** Already translated. Names the button for both `title` and `aria-label`. */
27
+ label: string;
28
+ /**
29
+ * What to ask the editor for the pressed state. Omit for actions that
30
+ * only open a dialog and are never "on" — announcing those as a
31
+ * permanently-off toggle misleads a screen reader.
32
+ */
33
+ active?: {
34
+ name: string;
35
+ attrs?: Record<string, unknown>;
36
+ };
37
+ run: (editor: Editor) => void;
38
+ }
39
+ /** Escape hatch for entries that own state or render their own popover. */
40
+ | {
41
+ kind: 'custom';
42
+ id: string;
43
+ render: (editor: Editor | null) => ReactNode;
44
+ };
45
+ interface RichTextToolbarProps {
46
+ /** Null while the editor mounts; every button disables itself until then. */
47
+ editor: Editor | null;
48
+ items: ToolbarItem[];
49
+ }
50
+ /** Renders a declarative toolbar for a Tiptap editor. */
51
+ declare function RichTextToolbar({ editor, items }: RichTextToolbarProps): react.JSX.Element;
52
+
53
+ /**
54
+ * Base content styles for the editable area, exported so a consumer can pass
55
+ * them to `useEditor({ editorProps: { attributes: { class } } })` — ProseMirror
56
+ * needs that class at construction time, before this component renders.
57
+ *
58
+ * Compose rather than replace: `cn(EDITOR_CONTENT_STYLE, 'my-overrides')`.
59
+ */
60
+ declare const EDITOR_CONTENT_STYLE: string;
61
+ interface RichTextEditorProps {
62
+ /** Null while the editor mounts. Build it with Tiptap's `useEditor`. */
63
+ editor: Editor | null;
64
+ items: ToolbarItem[];
65
+ /**
66
+ * Already translated. Omit to render no visible label.
67
+ *
68
+ * Note that a visible label does NOT name the editable area on its own:
69
+ * ProseMirror renders that as role='textbox', and EditorContent's props land
70
+ * on a wrapper div rather than on the editable node. Give the editor its own
71
+ * name where you construct it:
72
+ *
73
+ * ```ts
74
+ * useEditor({
75
+ * editorProps: { attributes: { class: EDITOR_CONTENT_STYLE, 'aria-label': t('body') } },
76
+ * })
77
+ * ```
78
+ */
79
+ label?: string;
80
+ /** Already translated message. Drives the destructive border and the hint. */
81
+ error?: string;
82
+ /**
83
+ * Slot under the editor for product-specific actions, so the editor itself
84
+ * stays free of any one product's features.
85
+ */
86
+ footer?: ReactNode;
87
+ className?: string;
88
+ }
89
+ /** Chrome for a Tiptap editor: a declarative toolbar, the editable area, and an error slot. */
90
+ declare function RichTextEditor({ editor, items, label, error, footer, className }: RichTextEditorProps): react.JSX.Element;
91
+
92
+ interface TableMenuLabels {
93
+ trigger: string;
94
+ insert: string;
95
+ /**
96
+ * A function, not a string: this is the only label with variables, and
97
+ * formatting it here would mean reimplementing message interpolation. The
98
+ * consumer keeps that in whatever i18n layer it already has.
99
+ */
100
+ dimensions: (rows: number, columns: number) => string;
101
+ rowBefore: string;
102
+ rowAfter: string;
103
+ deleteRow: string;
104
+ columnBefore: string;
105
+ columnAfter: string;
106
+ deleteColumn: string;
107
+ toggleHeader: string;
108
+ deleteTable: string;
109
+ }
110
+ interface TableMenuProps {
111
+ editor: Editor | null;
112
+ labels: TableMenuLabels;
113
+ icon: ReactNode;
114
+ /**
115
+ * The picker grid's extent. These bound the visual picker only — a
116
+ * consumer whose document contract caps table size should also enforce
117
+ * that ceiling where it validates the document.
118
+ */
119
+ maxRows?: number;
120
+ maxColumns?: number;
121
+ }
122
+ /** Word-style table controls: a grid picker to insert, then row/column actions. */
123
+ declare function TableMenu({ editor, labels, icon, maxRows, maxColumns, }: TableMenuProps): react.JSX.Element;
124
+
125
+ interface InsertImageDialogLabels {
126
+ title: string;
127
+ urlLabel: string;
128
+ urlPlaceholder: string;
129
+ altLabel: string;
130
+ hint: string;
131
+ cancel: string;
132
+ apply: string;
133
+ remove: string;
134
+ }
135
+ interface InsertImageDialogProps {
136
+ open: boolean;
137
+ onOpenChange: (open: boolean) => void;
138
+ labels: InsertImageDialogLabels;
139
+ url: string;
140
+ onUrlChange: (url: string) => void;
141
+ alt: string;
142
+ onAltChange: (alt: string) => void;
143
+ file: File | null;
144
+ onFileChange: (file: File | null) => void;
145
+ /** True while the consumer is transferring the picked file. Locks the form. */
146
+ uploading: boolean;
147
+ onApply: () => void;
148
+ onCancel?: () => void;
149
+ /**
150
+ * True when editing an image already in the document — reveals the
151
+ * destructive remove action beside the apply button.
152
+ */
153
+ removable?: boolean;
154
+ onRemove?: () => void;
155
+ /** Upload limits belong to whoever receives the file, not to this dialog. */
156
+ maxSizeBytes?: number;
157
+ accept?: Record<string, string[]>;
158
+ }
159
+ /**
160
+ * A controlled form for inserting an image. It deliberately does NOT upload:
161
+ * the consumer owns the transfer (its own API, its own storage) and drives
162
+ * `uploading` / `onApply` from there, so this dialog stays reusable across
163
+ * products with different backends.
164
+ */
165
+ declare function InsertImageDialog({ open, onOpenChange, labels, url, onUrlChange, alt, onAltChange, file, onFileChange, uploading, onApply, onCancel, removable, onRemove, maxSizeBytes, accept, }: InsertImageDialogProps): react.JSX.Element;
166
+
167
+ /**
168
+ * One entry in the palette.
169
+ *
170
+ * `mark` is a mark name, not a colour value: a consumer's document contract
171
+ * decides which marks exist, and a palette of named marks costs nothing to
172
+ * validate server-side — unlike a mark carrying an arbitrary colour, which would
173
+ * change the shape of every stored span.
174
+ */
175
+ interface ColorSwatch {
176
+ /** The Tiptap mark this swatch toggles, e.g. `colorPrimary`. */
177
+ mark: string;
178
+ /** Already translated name, used as the swatch's accessible label. */
179
+ label: string;
180
+ /** CSS colour for the swatch preview only. */
181
+ preview: string;
182
+ }
183
+ interface ColorMenuLabels {
184
+ trigger: string;
185
+ /** Heading above the swatches. */
186
+ heading: string;
187
+ /** Clears whichever colour mark is applied. */
188
+ clear: string;
189
+ }
190
+ interface ColorMenuProps {
191
+ editor: Editor | null;
192
+ labels: ColorMenuLabels;
193
+ icon: ReactNode;
194
+ swatches: ColorSwatch[];
195
+ }
196
+ /**
197
+ * A palette dropdown that toggles one mark at a time.
198
+ *
199
+ * Deliberately not the design system's `ColorPicker`: a free picker offers
200
+ * millions of values, and an editor whose authors can pick any colour produces
201
+ * articles that no longer look like one publication. A short list of brand
202
+ * shades is the constraint that keeps them consistent.
203
+ */
204
+ declare function ColorMenu({ editor, labels, icon, swatches }: ColorMenuProps): react.JSX.Element;
205
+
206
+ /** One list style the consumer offers. */
207
+ interface ListOption {
208
+ /** The Tiptap node this entry toggles, e.g. `bulletList`. */
209
+ node: string;
210
+ /** Already translated name. */
211
+ label: string;
212
+ icon: ReactNode;
213
+ run: (editor: Editor) => void;
214
+ }
215
+ interface ListMenuProps {
216
+ editor: Editor | null;
217
+ /** Already translated. Names the trigger for assistive tech. */
218
+ triggerLabel: string;
219
+ /** Shown on the trigger when no list style is active. */
220
+ icon: ReactNode;
221
+ options: ListOption[];
222
+ }
223
+ /**
224
+ * Groups the list styles behind one trigger.
225
+ *
226
+ * A row of separate buttons costs three toolbar slots for choices that are
227
+ * mutually exclusive; one trigger showing the active style reads faster and
228
+ * leaves room for the rest of the toolbar. The trigger swaps to the active
229
+ * style's icon so the current state is visible without opening the menu.
230
+ */
231
+ declare function ListMenu({ editor, triggerLabel, icon, options }: ListMenuProps): react.JSX.Element;
232
+
233
+ interface InsertLinkDialogLabels {
234
+ title: string;
235
+ urlLabel: string;
236
+ urlPlaceholder: string;
237
+ /** Explains that clearing the field removes an existing link. */
238
+ hint: string;
239
+ /** Field for the visible text, shown only when there is no selection to wrap. */
240
+ textLabel: string;
241
+ textPlaceholder: string;
242
+ cancel: string;
243
+ apply: string;
244
+ }
245
+ interface InsertLinkDialogProps {
246
+ open: boolean;
247
+ onOpenChange: (open: boolean) => void;
248
+ labels: InsertLinkDialogLabels;
249
+ url: string;
250
+ onUrlChange: (url: string) => void;
251
+ /**
252
+ * The visible text for a brand-new link. Pass these three together with
253
+ * `needsText` when the editor has no selection to turn into a link — without
254
+ * them the dialog can only re-point an existing one.
255
+ */
256
+ text?: string;
257
+ onTextChange?: (text: string) => void;
258
+ /**
259
+ * True when there is nothing selected, so the link needs its own text.
260
+ * Reveals the text field and requires it before applying.
261
+ */
262
+ needsText?: boolean;
263
+ onApply: () => void;
264
+ onCancel?: () => void;
265
+ }
266
+ /**
267
+ * A controlled form for inserting or editing a link.
268
+ *
269
+ * Clearing the URL and applying is how a link is removed — the consumer decides
270
+ * what that means for its document, so this dialog only reports the values.
271
+ */
272
+ declare function InsertLinkDialog({ open, onOpenChange, labels, url, onUrlChange, text, onTextChange, needsText, onApply, onCancel, }: InsertLinkDialogProps): react.JSX.Element;
273
+
274
+ interface LinkBubbleMenuLabels {
275
+ open: string;
276
+ edit: string;
277
+ remove: string;
278
+ }
279
+ interface LinkBubbleMenuProps {
280
+ editor: Editor | null;
281
+ labels: LinkBubbleMenuLabels;
282
+ /** Opens the consumer's link dialog, pre-filled with the current href. */
283
+ onEdit: () => void;
284
+ /**
285
+ * Follows the link. Left to the consumer for the cases this package cannot
286
+ * judge — routing instead of navigating, or confirming first.
287
+ *
288
+ * Defaults to opening a new tab, which is also what Ctrl/Cmd-click does, so
289
+ * the author never loses unsaved work just by checking a URL.
290
+ */
291
+ onOpen?: (href: string) => void;
292
+ }
293
+ /**
294
+ * A floating bar that appears when the caret sits inside a link, offering to
295
+ * open, edit or unlink it.
296
+ *
297
+ * It exists because an editor cannot let a plain click navigate: clicking is how
298
+ * you place the caret to fix a typo, so `openOnClick` stays false and this gives
299
+ * the author a deliberate way out to the URL. Ctrl/Cmd-click is wired separately,
300
+ * on the editor itself, for people who expect the shortcut.
301
+ */
302
+ declare function LinkBubbleMenu({ editor, labels, onEdit, onOpen }: LinkBubbleMenuProps): react.JSX.Element | null;
303
+
304
+ interface ResizableImageOptions {
305
+ /** Already translated: names the resize handle for assistive tech. */
306
+ resizeLabel: string;
307
+ minWidth?: number;
308
+ }
309
+ /**
310
+ * Builds an Image extension whose node view carries a resize handle.
311
+ *
312
+ * A factory rather than a component because ProseMirror — not React —
313
+ * instantiates the node view, so there is no place to hand it props. Options
314
+ * ride on the extension instead, and the view reads them off `extension.options`.
315
+ */
316
+ declare function createResizableImage(options: ResizableImageOptions): _tiptap_core.Node<ImageOptions & ResizableImageOptions, any>;
317
+
318
+ export { ColorMenu, type ColorMenuLabels, type ColorMenuProps, type ColorSwatch, EDITOR_CONTENT_STYLE, InsertImageDialog, type InsertImageDialogLabels, type InsertImageDialogProps, InsertLinkDialog, type InsertLinkDialogLabels, type InsertLinkDialogProps, LinkBubbleMenu, type LinkBubbleMenuLabels, type LinkBubbleMenuProps, ListMenu, type ListMenuProps, type ListOption, type ResizableImageOptions, RichTextEditor, type RichTextEditorProps, RichTextToolbar, type RichTextToolbarProps, TableMenu, type TableMenuLabels, type TableMenuProps, type ToolbarItem, createResizableImage };
@@ -0,0 +1,318 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { Editor } from '@tiptap/react';
4
+ import * as _tiptap_core from '@tiptap/core';
5
+ import { ImageOptions } from '@tiptap/extension-image';
6
+
7
+ /**
8
+ * A toolbar entry is data, never a mark.
9
+ *
10
+ * An editor's marks are ProseMirror extensions — code with serialization and
11
+ * parsing rules — so they belong to whoever owns the document contract, not to
12
+ * this package. A consumer declares what its buttons do here and keeps its own
13
+ * custom marks; the toolbar only asks the editor whether something is active
14
+ * and runs the callback it was handed.
15
+ */
16
+ type ToolbarItem = {
17
+ kind: 'separator';
18
+ } | {
19
+ kind: 'button';
20
+ id: string;
21
+ /**
22
+ * A node, not an icon name: keeps this package off any icon library
23
+ * and lets a button pass bare text (a font's own name, say) instead.
24
+ */
25
+ icon: ReactNode;
26
+ /** Already translated. Names the button for both `title` and `aria-label`. */
27
+ label: string;
28
+ /**
29
+ * What to ask the editor for the pressed state. Omit for actions that
30
+ * only open a dialog and are never "on" — announcing those as a
31
+ * permanently-off toggle misleads a screen reader.
32
+ */
33
+ active?: {
34
+ name: string;
35
+ attrs?: Record<string, unknown>;
36
+ };
37
+ run: (editor: Editor) => void;
38
+ }
39
+ /** Escape hatch for entries that own state or render their own popover. */
40
+ | {
41
+ kind: 'custom';
42
+ id: string;
43
+ render: (editor: Editor | null) => ReactNode;
44
+ };
45
+ interface RichTextToolbarProps {
46
+ /** Null while the editor mounts; every button disables itself until then. */
47
+ editor: Editor | null;
48
+ items: ToolbarItem[];
49
+ }
50
+ /** Renders a declarative toolbar for a Tiptap editor. */
51
+ declare function RichTextToolbar({ editor, items }: RichTextToolbarProps): react.JSX.Element;
52
+
53
+ /**
54
+ * Base content styles for the editable area, exported so a consumer can pass
55
+ * them to `useEditor({ editorProps: { attributes: { class } } })` — ProseMirror
56
+ * needs that class at construction time, before this component renders.
57
+ *
58
+ * Compose rather than replace: `cn(EDITOR_CONTENT_STYLE, 'my-overrides')`.
59
+ */
60
+ declare const EDITOR_CONTENT_STYLE: string;
61
+ interface RichTextEditorProps {
62
+ /** Null while the editor mounts. Build it with Tiptap's `useEditor`. */
63
+ editor: Editor | null;
64
+ items: ToolbarItem[];
65
+ /**
66
+ * Already translated. Omit to render no visible label.
67
+ *
68
+ * Note that a visible label does NOT name the editable area on its own:
69
+ * ProseMirror renders that as role='textbox', and EditorContent's props land
70
+ * on a wrapper div rather than on the editable node. Give the editor its own
71
+ * name where you construct it:
72
+ *
73
+ * ```ts
74
+ * useEditor({
75
+ * editorProps: { attributes: { class: EDITOR_CONTENT_STYLE, 'aria-label': t('body') } },
76
+ * })
77
+ * ```
78
+ */
79
+ label?: string;
80
+ /** Already translated message. Drives the destructive border and the hint. */
81
+ error?: string;
82
+ /**
83
+ * Slot under the editor for product-specific actions, so the editor itself
84
+ * stays free of any one product's features.
85
+ */
86
+ footer?: ReactNode;
87
+ className?: string;
88
+ }
89
+ /** Chrome for a Tiptap editor: a declarative toolbar, the editable area, and an error slot. */
90
+ declare function RichTextEditor({ editor, items, label, error, footer, className }: RichTextEditorProps): react.JSX.Element;
91
+
92
+ interface TableMenuLabels {
93
+ trigger: string;
94
+ insert: string;
95
+ /**
96
+ * A function, not a string: this is the only label with variables, and
97
+ * formatting it here would mean reimplementing message interpolation. The
98
+ * consumer keeps that in whatever i18n layer it already has.
99
+ */
100
+ dimensions: (rows: number, columns: number) => string;
101
+ rowBefore: string;
102
+ rowAfter: string;
103
+ deleteRow: string;
104
+ columnBefore: string;
105
+ columnAfter: string;
106
+ deleteColumn: string;
107
+ toggleHeader: string;
108
+ deleteTable: string;
109
+ }
110
+ interface TableMenuProps {
111
+ editor: Editor | null;
112
+ labels: TableMenuLabels;
113
+ icon: ReactNode;
114
+ /**
115
+ * The picker grid's extent. These bound the visual picker only — a
116
+ * consumer whose document contract caps table size should also enforce
117
+ * that ceiling where it validates the document.
118
+ */
119
+ maxRows?: number;
120
+ maxColumns?: number;
121
+ }
122
+ /** Word-style table controls: a grid picker to insert, then row/column actions. */
123
+ declare function TableMenu({ editor, labels, icon, maxRows, maxColumns, }: TableMenuProps): react.JSX.Element;
124
+
125
+ interface InsertImageDialogLabels {
126
+ title: string;
127
+ urlLabel: string;
128
+ urlPlaceholder: string;
129
+ altLabel: string;
130
+ hint: string;
131
+ cancel: string;
132
+ apply: string;
133
+ remove: string;
134
+ }
135
+ interface InsertImageDialogProps {
136
+ open: boolean;
137
+ onOpenChange: (open: boolean) => void;
138
+ labels: InsertImageDialogLabels;
139
+ url: string;
140
+ onUrlChange: (url: string) => void;
141
+ alt: string;
142
+ onAltChange: (alt: string) => void;
143
+ file: File | null;
144
+ onFileChange: (file: File | null) => void;
145
+ /** True while the consumer is transferring the picked file. Locks the form. */
146
+ uploading: boolean;
147
+ onApply: () => void;
148
+ onCancel?: () => void;
149
+ /**
150
+ * True when editing an image already in the document — reveals the
151
+ * destructive remove action beside the apply button.
152
+ */
153
+ removable?: boolean;
154
+ onRemove?: () => void;
155
+ /** Upload limits belong to whoever receives the file, not to this dialog. */
156
+ maxSizeBytes?: number;
157
+ accept?: Record<string, string[]>;
158
+ }
159
+ /**
160
+ * A controlled form for inserting an image. It deliberately does NOT upload:
161
+ * the consumer owns the transfer (its own API, its own storage) and drives
162
+ * `uploading` / `onApply` from there, so this dialog stays reusable across
163
+ * products with different backends.
164
+ */
165
+ declare function InsertImageDialog({ open, onOpenChange, labels, url, onUrlChange, alt, onAltChange, file, onFileChange, uploading, onApply, onCancel, removable, onRemove, maxSizeBytes, accept, }: InsertImageDialogProps): react.JSX.Element;
166
+
167
+ /**
168
+ * One entry in the palette.
169
+ *
170
+ * `mark` is a mark name, not a colour value: a consumer's document contract
171
+ * decides which marks exist, and a palette of named marks costs nothing to
172
+ * validate server-side — unlike a mark carrying an arbitrary colour, which would
173
+ * change the shape of every stored span.
174
+ */
175
+ interface ColorSwatch {
176
+ /** The Tiptap mark this swatch toggles, e.g. `colorPrimary`. */
177
+ mark: string;
178
+ /** Already translated name, used as the swatch's accessible label. */
179
+ label: string;
180
+ /** CSS colour for the swatch preview only. */
181
+ preview: string;
182
+ }
183
+ interface ColorMenuLabels {
184
+ trigger: string;
185
+ /** Heading above the swatches. */
186
+ heading: string;
187
+ /** Clears whichever colour mark is applied. */
188
+ clear: string;
189
+ }
190
+ interface ColorMenuProps {
191
+ editor: Editor | null;
192
+ labels: ColorMenuLabels;
193
+ icon: ReactNode;
194
+ swatches: ColorSwatch[];
195
+ }
196
+ /**
197
+ * A palette dropdown that toggles one mark at a time.
198
+ *
199
+ * Deliberately not the design system's `ColorPicker`: a free picker offers
200
+ * millions of values, and an editor whose authors can pick any colour produces
201
+ * articles that no longer look like one publication. A short list of brand
202
+ * shades is the constraint that keeps them consistent.
203
+ */
204
+ declare function ColorMenu({ editor, labels, icon, swatches }: ColorMenuProps): react.JSX.Element;
205
+
206
+ /** One list style the consumer offers. */
207
+ interface ListOption {
208
+ /** The Tiptap node this entry toggles, e.g. `bulletList`. */
209
+ node: string;
210
+ /** Already translated name. */
211
+ label: string;
212
+ icon: ReactNode;
213
+ run: (editor: Editor) => void;
214
+ }
215
+ interface ListMenuProps {
216
+ editor: Editor | null;
217
+ /** Already translated. Names the trigger for assistive tech. */
218
+ triggerLabel: string;
219
+ /** Shown on the trigger when no list style is active. */
220
+ icon: ReactNode;
221
+ options: ListOption[];
222
+ }
223
+ /**
224
+ * Groups the list styles behind one trigger.
225
+ *
226
+ * A row of separate buttons costs three toolbar slots for choices that are
227
+ * mutually exclusive; one trigger showing the active style reads faster and
228
+ * leaves room for the rest of the toolbar. The trigger swaps to the active
229
+ * style's icon so the current state is visible without opening the menu.
230
+ */
231
+ declare function ListMenu({ editor, triggerLabel, icon, options }: ListMenuProps): react.JSX.Element;
232
+
233
+ interface InsertLinkDialogLabels {
234
+ title: string;
235
+ urlLabel: string;
236
+ urlPlaceholder: string;
237
+ /** Explains that clearing the field removes an existing link. */
238
+ hint: string;
239
+ /** Field for the visible text, shown only when there is no selection to wrap. */
240
+ textLabel: string;
241
+ textPlaceholder: string;
242
+ cancel: string;
243
+ apply: string;
244
+ }
245
+ interface InsertLinkDialogProps {
246
+ open: boolean;
247
+ onOpenChange: (open: boolean) => void;
248
+ labels: InsertLinkDialogLabels;
249
+ url: string;
250
+ onUrlChange: (url: string) => void;
251
+ /**
252
+ * The visible text for a brand-new link. Pass these three together with
253
+ * `needsText` when the editor has no selection to turn into a link — without
254
+ * them the dialog can only re-point an existing one.
255
+ */
256
+ text?: string;
257
+ onTextChange?: (text: string) => void;
258
+ /**
259
+ * True when there is nothing selected, so the link needs its own text.
260
+ * Reveals the text field and requires it before applying.
261
+ */
262
+ needsText?: boolean;
263
+ onApply: () => void;
264
+ onCancel?: () => void;
265
+ }
266
+ /**
267
+ * A controlled form for inserting or editing a link.
268
+ *
269
+ * Clearing the URL and applying is how a link is removed — the consumer decides
270
+ * what that means for its document, so this dialog only reports the values.
271
+ */
272
+ declare function InsertLinkDialog({ open, onOpenChange, labels, url, onUrlChange, text, onTextChange, needsText, onApply, onCancel, }: InsertLinkDialogProps): react.JSX.Element;
273
+
274
+ interface LinkBubbleMenuLabels {
275
+ open: string;
276
+ edit: string;
277
+ remove: string;
278
+ }
279
+ interface LinkBubbleMenuProps {
280
+ editor: Editor | null;
281
+ labels: LinkBubbleMenuLabels;
282
+ /** Opens the consumer's link dialog, pre-filled with the current href. */
283
+ onEdit: () => void;
284
+ /**
285
+ * Follows the link. Left to the consumer for the cases this package cannot
286
+ * judge — routing instead of navigating, or confirming first.
287
+ *
288
+ * Defaults to opening a new tab, which is also what Ctrl/Cmd-click does, so
289
+ * the author never loses unsaved work just by checking a URL.
290
+ */
291
+ onOpen?: (href: string) => void;
292
+ }
293
+ /**
294
+ * A floating bar that appears when the caret sits inside a link, offering to
295
+ * open, edit or unlink it.
296
+ *
297
+ * It exists because an editor cannot let a plain click navigate: clicking is how
298
+ * you place the caret to fix a typo, so `openOnClick` stays false and this gives
299
+ * the author a deliberate way out to the URL. Ctrl/Cmd-click is wired separately,
300
+ * on the editor itself, for people who expect the shortcut.
301
+ */
302
+ declare function LinkBubbleMenu({ editor, labels, onEdit, onOpen }: LinkBubbleMenuProps): react.JSX.Element | null;
303
+
304
+ interface ResizableImageOptions {
305
+ /** Already translated: names the resize handle for assistive tech. */
306
+ resizeLabel: string;
307
+ minWidth?: number;
308
+ }
309
+ /**
310
+ * Builds an Image extension whose node view carries a resize handle.
311
+ *
312
+ * A factory rather than a component because ProseMirror — not React —
313
+ * instantiates the node view, so there is no place to hand it props. Options
314
+ * ride on the extension instead, and the view reads them off `extension.options`.
315
+ */
316
+ declare function createResizableImage(options: ResizableImageOptions): _tiptap_core.Node<ImageOptions & ResizableImageOptions, any>;
317
+
318
+ export { ColorMenu, type ColorMenuLabels, type ColorMenuProps, type ColorSwatch, EDITOR_CONTENT_STYLE, InsertImageDialog, type InsertImageDialogLabels, type InsertImageDialogProps, InsertLinkDialog, type InsertLinkDialogLabels, type InsertLinkDialogProps, LinkBubbleMenu, type LinkBubbleMenuLabels, type LinkBubbleMenuProps, ListMenu, type ListMenuProps, type ListOption, type ResizableImageOptions, RichTextEditor, type RichTextEditorProps, RichTextToolbar, type RichTextToolbarProps, TableMenu, type TableMenuLabels, type TableMenuProps, type ToolbarItem, createResizableImage };