@octane-xplat/tiptap 0.10.0 → 0.11.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.
@@ -1,7 +1,8 @@
1
- import { useImperativeHandle, useEffect, useRef } from 'octane'
1
+ import { useImperativeHandle, useEffect, useMemo, useRef } from 'octane'
2
2
  import { EditorContent, useEditor } from '@octanejs/tiptap'
3
3
  import StarterKit from '@tiptap/starter-kit'
4
- import type { TiptapEditorHandle, TiptapEditorProps, TiptapFormat } from './types'
4
+ import type { Extensions } from '@tiptap/core'
5
+ import type { TiptapEditorHandle, TiptapEditorProps, TiptapFormat, TiptapWebOptions } from './types'
5
6
 
6
7
  export const supported = true
7
8
 
@@ -56,6 +57,20 @@ function activeFormats(editor: any): TiptapFormat[] {
56
57
  return out
57
58
  }
58
59
 
60
+ /** Extension list for the web engine: the built-in StarterKit (optionally
61
+ * configured) followed by caller extras. `starterKit: false` or a
62
+ * starterKit-named caller entry hands the schema over to the caller —
63
+ * registering two StarterKits trips tiptap's duplicate-name warning. */
64
+ function resolveExtensions(web: TiptapWebOptions | undefined): Extensions {
65
+ const extras = web?.extensions ?? []
66
+ if (web?.starterKit === false || extras.some((ext) => ext?.name === 'starterKit')) {
67
+ return extras
68
+ }
69
+
70
+ const kit = web?.starterKit ? StarterKit.configure(web.starterKit) : StarterKit
71
+ return [kit, ...extras]
72
+ }
73
+
59
74
  /** Unified editor facade, web half — a thin adapter over the published
60
75
  * `@octanejs/tiptap` binding (useEditor + EditorContent + StarterKit). */
61
76
  export function TiptapEditor(props: TiptapEditorProps) @{
@@ -65,8 +80,15 @@ export function TiptapEditor(props: TiptapEditorProps) @{
65
80
  const lastJSONInput = useRef(JSON.stringify(props.json))
66
81
  const bound = useRef<TiptapEditorHandle | undefined>(undefined)
67
82
 
83
+ // tiptap fixes the schema at construction; memoized on the option values
84
+ // so a stable caller config never re-triggers setOptions.
85
+ const extensions = useMemo(
86
+ () => resolveExtensions(props.web),
87
+ [props.web?.extensions, props.web?.starterKit],
88
+ )
89
+
68
90
  const editor = useEditor({
69
- extensions: [StarterKit],
91
+ extensions,
70
92
  content: (props.json ?? props.value ?? '') as any,
71
93
  editable: props.editable !== false,
72
94
  autofocus: props.autofocus ?? false,
package/src/types.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import type { Octane } from 'octane/jsx-runtime'
2
+ import type { Extensions } from '@tiptap/core'
3
+ import type { StarterKitOptions } from '@tiptap/starter-kit'
2
4
 
3
5
  /** Format vocabulary shared by the web (tiptap StarterKit) and native
4
6
  * (Aztec) backends. On web, starter-kit covers everything except
@@ -35,6 +37,25 @@ export type TiptapFormat =
35
37
  * callers round-trip through tiptap's own schema on both platforms. */
36
38
  export type TiptapJSON = { type: string; content?: unknown[] } & Record<string, unknown>
37
39
 
40
+ /** Engine options for the web target only. The `.web` entry mounts a real
41
+ * tiptap `Editor`, so callers can extend its schema here. The Android
42
+ * facade (Aztec leaf) and the bundled AppKit engine cannot host DOM-bound
43
+ * ProseMirror/tiptap extension objects and ignore these options. Caller
44
+ * plugins, node views, and browser menus are web behavior, not shared
45
+ * contract. */
46
+ export interface TiptapWebOptions {
47
+ /** Extra tiptap extensions appended after the built-in StarterKit — any
48
+ * `Extension`/`Node`/`Mark` from `@tiptap/*` or app code. An entry named
49
+ * `starterKit` replaces the built-in instead of registering it twice.
50
+ * The editor fixes its schema at construction; keep the list
51
+ * referentially stable across renders. */
52
+ extensions?: Extensions
53
+ /** `StarterKit.configure()` options for the built-in StarterKit, or
54
+ * `false` to omit it — `extensions` must then supply a complete schema
55
+ * (document, paragraph, and text nodes at minimum). */
56
+ starterKit?: StarterKitOptions | false
57
+ }
58
+
38
59
  export interface TiptapEditorHandle {
39
60
  /** AppKit: returns the latest WebKit snapshot; commands are asynchronous. */
40
61
  getHTML(): string
@@ -69,7 +90,9 @@ export interface TiptapEditorProps {
69
90
  * setContent, preserving the diff loop the editor emitted is skipped). */
70
91
  value?: string
71
92
  /** Document JSON. Takes precedence over `value` when both arrive. On
72
- * native it waits for the schema modules (see `onJSONReady`). */
93
+ * native it waits for the schema modules and host readiness (see
94
+ * `onJSONReady`); a doc that arrives early is applied once both are up
95
+ * rather than dropped. */
73
96
  json?: TiptapJSON
74
97
  placeholder?: string
75
98
  editable?: boolean
@@ -88,6 +111,9 @@ export interface TiptapEditorProps {
88
111
  ref?: Octane.Ref<TiptapEditorHandle>
89
112
  android?: Record<string, any>
90
113
  ios?: Record<string, any>
114
+ /** Web-target engine configuration — tiptap extensions and StarterKit
115
+ * options. See `TiptapWebOptions`; ignored on native and AppKit. */
116
+ web?: TiptapWebOptions
91
117
  row?: number | string
92
118
  col?: number | string
93
119
  rowSpan?: number
package/types/types.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import type { Octane } from 'octane/jsx-runtime';
2
+ import type { Extensions } from '@tiptap/core';
3
+ import type { StarterKitOptions } from '@tiptap/starter-kit';
2
4
  /** Format vocabulary shared by the web (tiptap StarterKit) and native
3
5
  * (Aztec) backends. On web, starter-kit covers everything except
4
6
  * taskList/highlight/subscript/superscript/align* — those no-op there and
@@ -10,6 +12,24 @@ export type TiptapJSON = {
10
12
  type: string;
11
13
  content?: unknown[];
12
14
  } & Record<string, unknown>;
15
+ /** Engine options for the web target only. The `.web` entry mounts a real
16
+ * tiptap `Editor`, so callers can extend its schema here. The Android
17
+ * facade (Aztec leaf) and the bundled AppKit engine cannot host DOM-bound
18
+ * ProseMirror/tiptap extension objects and ignore these options. Caller
19
+ * plugins, node views, and browser menus are web behavior, not shared
20
+ * contract. */
21
+ export interface TiptapWebOptions {
22
+ /** Extra tiptap extensions appended after the built-in StarterKit — any
23
+ * `Extension`/`Node`/`Mark` from `@tiptap/*` or app code. An entry named
24
+ * `starterKit` replaces the built-in instead of registering it twice.
25
+ * The editor fixes its schema at construction; keep the list
26
+ * referentially stable across renders. */
27
+ extensions?: Extensions;
28
+ /** `StarterKit.configure()` options for the built-in StarterKit, or
29
+ * `false` to omit it — `extensions` must then supply a complete schema
30
+ * (document, paragraph, and text nodes at minimum). */
31
+ starterKit?: StarterKitOptions | false;
32
+ }
13
33
  export interface TiptapEditorHandle {
14
34
  /** AppKit: returns the latest WebKit snapshot; commands are asynchronous. */
15
35
  getHTML(): string;
@@ -43,7 +63,9 @@ export interface TiptapEditorProps {
43
63
  * setContent, preserving the diff loop the editor emitted is skipped). */
44
64
  value?: string;
45
65
  /** Document JSON. Takes precedence over `value` when both arrive. On
46
- * native it waits for the schema modules (see `onJSONReady`). */
66
+ * native it waits for the schema modules and host readiness (see
67
+ * `onJSONReady`); a doc that arrives early is applied once both are up
68
+ * rather than dropped. */
47
69
  json?: TiptapJSON;
48
70
  placeholder?: string;
49
71
  editable?: boolean;
@@ -66,6 +88,9 @@ export interface TiptapEditorProps {
66
88
  ref?: Octane.Ref<TiptapEditorHandle>;
67
89
  android?: Record<string, any>;
68
90
  ios?: Record<string, any>;
91
+ /** Web-target engine configuration — tiptap extensions and StarterKit
92
+ * options. See `TiptapWebOptions`; ignored on native and AppKit. */
93
+ web?: TiptapWebOptions;
69
94
  row?: number | string;
70
95
  col?: number | string;
71
96
  rowSpan?: number;