@octane-xplat/richtext 0.9.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.
- package/README.md +117 -6
- package/dist/macos/browser.d.ts +1 -0
- package/dist/macos/browser.js +2 -0
- package/dist/native/RichTextEditor.android.js +48 -8
- package/dist/native/RichTextEditor.ios.js +194 -8
- package/dist/native/octane-client-build.json +1 -1
- package/dist/web/octane-client-build.json +1 -1
- package/nativescript.config.ts +22 -0
- package/package.json +27 -5
- package/platforms/ios/LICENSE-Aztec-MPL-2.0.txt +355 -0
- package/platforms/ios/UPSTREAM.md +14 -0
- package/platforms/ios/src/XplatAztecEditor.swift +357 -0
- package/platforms/macos/include/XplatEditorHost.h +1 -0
- package/platforms/macos/src/XplatEditorHost.swift +63 -0
- package/src/BrowserEditor.web.ts +107 -0
- package/src/Editor.macos.tsx +9 -0
- package/src/NativeEditor.macos.tsx +81 -0
- package/src/RichTextEditor.android.tsrx +42 -2
- package/src/RichTextEditor.ios.tsrx +221 -6
- package/src/RichTextEditor.windows.tsrx +15 -0
- package/src/browser-transport.web.ts +119 -0
- package/src/host-session.macos.ts +142 -0
- package/src/index.macos.ts +3 -9
- package/src/index.ts +2 -2
- package/src/types.ts +54 -9
- package/types/browser-transport.d.ts +2 -0
- package/types/index.macos.d.ts +5 -0
- package/types/macos-host.d.ts +11 -0
- package/types/types.d.ts +53 -9
package/README.md
CHANGED
|
@@ -1,22 +1,133 @@
|
|
|
1
1
|
# `@octane-xplat/richtext`
|
|
2
2
|
|
|
3
3
|
The native rich-text editing leaf: WordPress Aztec's `AztecText` on Android —
|
|
4
|
-
a `Spannable`-backed `EditText`, not a WebView. iOS mounts
|
|
5
|
-
|
|
6
|
-
return `supported: false` (the
|
|
4
|
+
a `Spannable`-backed `EditText`, not a WebView. iOS mounts AztecEditor-iOS
|
|
5
|
+
(`Aztec.TextView`) through the `XplatAztecEditorView` Swift facade in
|
|
6
|
+
`platforms/ios`; web and Windows return `supported: false` (the
|
|
7
|
+
`@octane-xplat/tiptap` facade covers web).
|
|
7
8
|
|
|
8
|
-
```
|
|
9
|
+
```tsx
|
|
10
|
+
import { useState } from 'octane'
|
|
9
11
|
import { RichTextEditor, supported } from '@octane-xplat/richtext'
|
|
12
|
+
import { Text } from '@octane-xplat/ui'
|
|
13
|
+
|
|
14
|
+
export function Notes() {
|
|
15
|
+
const [html, setHtml] = useState('<p>Trip notes</p>')
|
|
16
|
+
return supported ? (
|
|
17
|
+
<RichTextEditor value={html} onChange={setHtml} />
|
|
18
|
+
) : (
|
|
19
|
+
<Text>Editing is unavailable on this target</Text>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
10
22
|
```
|
|
11
23
|
|
|
12
24
|
Content in/out is document HTML via Aztec `fromHtml`/`toPlainHtml`. The
|
|
13
|
-
`
|
|
25
|
+
`ref` callback returns an imperative handle (`getHTML`/`setHTML`,
|
|
14
26
|
`apply(format)`, `linkTo`/`removeLink`, `isActive`, `undo`/`redo`,
|
|
15
27
|
`focus`/`blur`, `native`) once the editor exists, and `onSelectionChange`
|
|
16
28
|
reports the active `RichTextFormat` set at the caret.
|
|
17
29
|
|
|
30
|
+
Structural commands exist on the Aztec surface: `split()` breaks the block
|
|
31
|
+
at the caret, `join()` merges a block into the previous one from a
|
|
32
|
+
collapsed caret at its start, and `indent()`/`outdent()` demote or promote
|
|
33
|
+
the selected blocks — a real nested-list restructure on `<ul>`/`<ol>`, a
|
|
34
|
+
`\t` indent on plain blocks. `canIndent()`/`canOutdent()` report whether
|
|
35
|
+
the current selection can take the command. All six return `false` when
|
|
36
|
+
the command cannot apply; markup Aztec does not understand (for example
|
|
37
|
+
`<div data-*>` wrappers) is opaque to them. On AppKit the commands return
|
|
38
|
+
`false` — the engine transport cannot report a synchronous result.
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import { useRef } from 'octane'
|
|
42
|
+
import { RichTextEditor, type RichTextEditorHandle } from '@octane-xplat/richtext'
|
|
43
|
+
import { Button } from '@octane-xplat/ui'
|
|
44
|
+
|
|
45
|
+
export function Formatting() {
|
|
46
|
+
const editor = useRef<RichTextEditorHandle | null>(null)
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
<RichTextEditor
|
|
50
|
+
ref={(handle) => {
|
|
51
|
+
editor.current = handle
|
|
52
|
+
}}
|
|
53
|
+
onSelectionChange={({ active }) => console.log(active)}
|
|
54
|
+
/>
|
|
55
|
+
<Button onPress={() => editor.current?.apply('bold')}>Bold</Button>
|
|
56
|
+
<Button
|
|
57
|
+
onPress={() => {
|
|
58
|
+
const handle = editor.current
|
|
59
|
+
if (!handle) return
|
|
60
|
+
handle.setHTML('<p>New note</p>')
|
|
61
|
+
console.log(handle.getHTML(), handle.isActive('bold'))
|
|
62
|
+
handle.linkTo('https://example.com')
|
|
63
|
+
handle.removeLink()
|
|
64
|
+
handle.undo()
|
|
65
|
+
handle.redo()
|
|
66
|
+
handle.focus()
|
|
67
|
+
handle.blur()
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
Try editor commands
|
|
71
|
+
</Button>
|
|
72
|
+
</>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { useRef } from 'octane'
|
|
79
|
+
import { RichTextEditor, type RichTextEditorHandle } from '@octane-xplat/richtext'
|
|
80
|
+
import { Button } from '@octane-xplat/ui'
|
|
81
|
+
|
|
82
|
+
export function Formatting() {
|
|
83
|
+
const editor = useRef<RichTextEditorHandle | null>(null)
|
|
84
|
+
return (
|
|
85
|
+
<>
|
|
86
|
+
<RichTextEditor
|
|
87
|
+
ref={(handle) => {
|
|
88
|
+
editor.current = handle
|
|
89
|
+
}}
|
|
90
|
+
onSelectionChange={({ active }) => console.log(active)}
|
|
91
|
+
/>
|
|
92
|
+
<Button onPress={() => editor.current?.apply('bold')}>Bold</Button>
|
|
93
|
+
<Button
|
|
94
|
+
onPress={() => {
|
|
95
|
+
const handle = editor.current
|
|
96
|
+
if (!handle) return
|
|
97
|
+
handle.setHTML('<p>New note</p>')
|
|
98
|
+
console.log(handle.getHTML(), handle.isActive('bold'))
|
|
99
|
+
handle.linkTo('https://example.com')
|
|
100
|
+
handle.removeLink()
|
|
101
|
+
handle.undo()
|
|
102
|
+
handle.redo()
|
|
103
|
+
handle.focus()
|
|
104
|
+
handle.blur()
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
Try editor commands
|
|
108
|
+
</Button>
|
|
109
|
+
</>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
18
114
|
The Android Aztec dependency (`org.wordpress:aztec:v2.1.7`) arrives through
|
|
19
115
|
the leaf's `platforms/android/include.gradle` — no app-level gradle work.
|
|
116
|
+
On iOS the leaf declares AztecEditor-iOS as a pinned-revision Swift Package
|
|
117
|
+
in its plugin-level `nativescript.config.ts` and compiles
|
|
118
|
+
`platforms/ios/src/XplatAztecEditor.swift` into the app — NativeScript
|
|
119
|
+
plugin discovery applies both when the app depends on
|
|
120
|
+
`@octane-xplat/richtext`. iOS has no task-list or text-alignment surface:
|
|
121
|
+
`apply('taskList')` and the `align*` formats report a warning and leave the
|
|
122
|
+
document unchanged, and `isActive` returns `false` for them.
|
|
20
123
|
See the framework guide for the full contract and the demo:
|
|
21
|
-
[`docs/rich-text.md`](../../docs/rich-text.md) and
|
|
124
|
+
[`docs/app/rich-text.md`](../../docs/app/rich-text.md) and
|
|
22
125
|
[`packages/demos/src/RichTextEditorDemo.tsrx`](../demos/src/RichTextEditorDemo.tsrx).
|
|
126
|
+
|
|
127
|
+
## macOS AppKit
|
|
128
|
+
|
|
129
|
+
The macOS export mounts a bundled local editor document in WKWebView.
|
|
130
|
+
RichText uses StarterKit; Tiptap and Lexical use their existing web facades.
|
|
131
|
+
Wait for `onReady`; synchronous getters return the latest received snapshot
|
|
132
|
+
and commands cross WebKit asynchronously. The `native` handle is the Swift
|
|
133
|
+
host transport. See [AppKit setup and engine limits](../../docs/rich-text.md#macos-appkit-editing).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare const html: string; export default html
|