Skip to content

Commit c3b80cd

Browse files
committed
docs: core funtionalities section
1 parent 2aaaf9b commit c3b80cd

6 files changed

Lines changed: 440 additions & 10 deletions

File tree

docs/docs/core-functionalities/handling-events.md

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,56 @@ sidebar_position: 3
44

55
# Handling events
66

7-
<!-- TODO: write content for this page -->
7+
Since the input is [uncontrolled](/fundamentals/core-concepts#the-input-is-uncontrolled),
8+
events are how you observe it. You change content by calling ref methods; you
9+
react to changes by listening to the callbacks below.
10+
11+
Full payload shapes of the available callbacks can be found in the `EnrichedTextInput` reference.
12+
13+
## Content
14+
15+
- **`onChangeText`** - plain-text content changed.
16+
- **`onChangeHtml`** - the HTML changed.
17+
18+
:::tip
19+
20+
The `onChangeHtml` callbacks has to parse the content into HTML on every keystroke.
21+
This is a heavy, computational operation, which might slow down your app's performance. Consider using the `getHTML()` ref method instead if it meets your requirements.
22+
23+
:::
24+
25+
## Selection and style state
26+
27+
- **`onChangeSelection`** - the cursor moved or the selection changed. Gives you
28+
`start`, `end`, and the selected `text`. Useful for range-based methods like
29+
[`setLink`](/rich-text-formatting/links).
30+
- **`onChangeState`** - the active styles at the cursor changed. This is the
31+
event that drives a toolbar by using reported `isActive`, `isBlocking`, and
32+
`isConflicting`, plus the current `alignment`. See the
33+
[style state model](/fundamentals/core-concepts#the-style-state-model).
34+
35+
## Focus
36+
37+
- **`onFocus`** / **`onBlur`** - the input gained or lost focus.
38+
39+
## Mentions
40+
41+
- **`onStartMention`** - a mention started being edited.
42+
- **`onChangeMention`** - the query after the indicator changed.
43+
- **`onEndMention`** - editing a mention stopped.
44+
- **`onMentionDetected`** - the cursor entered or left a mention.
45+
46+
## Links
47+
48+
- **`onLinkDetected`** - the cursor entered or left a link.
49+
50+
## Images
51+
52+
- **`onPasteImages`** - the user pasted one or more images; hands you each
53+
image's data so you can upload and insert them with
54+
[`setImage`](/rich-text-formatting/inline-images).
55+
56+
## Keyboard and submission
57+
58+
- **`onKeyPress`** - a key was pressed.
59+
- **`onSubmitEditing`** - the user presses return/enter key. Fires when `submitBehavior` is set to either `submit` or `blurAndSubmit`.

docs/docs/core-functionalities/rendering-rich-text.md

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
sidebar_position: 2
3+
---
4+
5+
import InteractiveExample from '@site/src/components/InteractiveExample';
6+
import RenderingEditor from '@site/src/examples/RenderingEditor';
7+
import RenderingEditorSrc from '!!raw-loader!@site/src/examples/RenderingEditor';
8+
9+
# Rendering rich text
10+
11+
`EnrichedTextInput` is for editing. To _display_ rich text without an editor -
12+
a chat message, a comment, an article - use its read-only counterpart,
13+
**`EnrichedText`**.
14+
15+
Both components speak the same [HTML format](/fundamentals/html-format-and-supported-tags),
16+
so the typical flow is: edit in `EnrichedTextInput`, persist the
17+
`getHTML` output, and later feed that
18+
string to `EnrichedText`.
19+
20+
## Passing content
21+
22+
`EnrichedText` takes the HTML string as its `children`:
23+
24+
```tsx
25+
import { EnrichedText } from 'react-native-enriched-html';
26+
27+
<EnrichedText>{'<p>Hello <b>world</b></p>'}</EnrichedText>;
28+
```
29+
30+
## Styling
31+
32+
Styling mirrors the input. `style` controls the container and base typography,
33+
and `htmlStyle` controls per-element appearance. `EnrichedText` extends
34+
`htmlStyle` with **press states** for interactive elements, since links and
35+
mentions are pressable here:
36+
37+
```tsx
38+
<EnrichedText
39+
style={{ fontSize: 16, color: '#232736' }}
40+
htmlStyle={{
41+
a: { pressColor: '#1e40af' },
42+
mention: { pressColor: '#16a34a', pressBackgroundColor: '#dcfce7' },
43+
}}>
44+
{html}
45+
</EnrichedText>
46+
```
47+
48+
The added `pressColor` / `pressBackgroundColor` fields on `a` and `mention` are
49+
the only shape difference from the input's `htmlStyle`. See the
50+
`EnrichedText` reference for the full type.
51+
52+
## Notable props
53+
54+
- **`selectable`** - allow the user to select and copy the rendered text.
55+
Defaults to `false`.
56+
- **`onLinkPress` / `onMentionPress`** - fire when a link or mention is pressed.
57+
- **`numberOfLines` / `ellipsizeMode`** - truncate long content to a fixed
58+
number of lines with an ellipsis.
59+
- **`useHtmlNormalizer`** - normalize external or messy HTML into the library's canonical
60+
tag subset before rendering. Defaults to `true`. See
61+
[Normalization](/fundamentals/core-concepts#normalization).
62+
63+
:::note
64+
65+
On web, the default behavior of the pressed `<a>` tag is suppressed. To navigate to the link's URL, you need to properly handle the `onLinkPress` event.
66+
67+
:::
68+
69+
## Try it out
70+
71+
Format some text in the editor, then press **Render** - the current HTML is read
72+
with `getHTML()` and handed to an `EnrichedText` below.
73+
74+
<InteractiveExample src={RenderingEditorSrc} component={RenderingEditor} />
75+
76+
:::caution
77+
78+
On iOS and Android, `EnrichedText` does not sanitize HTML for you. Sanitize anything you render that
79+
came from users or other untrusted sources. To know more about the web's built-in sanitization, visit [Web support](/core-functionalities/web-support#sanitization).
80+
81+
:::

docs/docs/core-functionalities/styling-the-input.md

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,80 @@ sidebar_position: 1
44

55
# Styling the input
66

7-
<!-- TODO: write content for this page -->
7+
`EnrichedTextInput` is styled through two separate props. Together they cover
8+
everything from the container's dimensions down to the color of a bullet point.
9+
10+
- **`style`** - the container's layouting behavior and its base typography (`fontSize`, `color`, `fontFamily`, …). It accepts a subset of React Native's `TextStyle`, described by
11+
`EnrichedInputStyle`.
12+
- **`htmlStyle`** - the appearance of individual rich text elements: heading
13+
sizes, blockquote borders, code colors, list markers, mention colors, and so
14+
on.
15+
16+
```tsx
17+
<EnrichedTextInput
18+
style={{
19+
fontSize: 16,
20+
color: '#232736',
21+
padding: 12,
22+
borderRadius: 12,
23+
backgroundColor: '#eef0ff',
24+
}}
25+
htmlStyle={{
26+
h1: { fontSize: 28, bold: true },
27+
blockquote: { borderColor: '#57b495', borderWidth: 3 },
28+
code: { color: '#c026d3' },
29+
}}
30+
/>
31+
```
32+
33+
## `htmlStyle`
34+
35+
`htmlStyle` maps each supported element to a small config object. Anything you
36+
omit falls back to the built-in default. The available keys are:
37+
38+
| Key | Styles | Notable options |
39+
| ------------ | -------------- | ----------------------------------------------------------- |
40+
| `h1``h6` | Headings | `fontSize`, `bold` |
41+
| `blockquote` | Blockquote | `borderColor`, `borderWidth`, `gapWidth`, `color` |
42+
| `codeblock` | Code block | `color`, `backgroundColor`, `borderRadius` |
43+
| `code` | Inline code | `color`, `backgroundColor` |
44+
| `a` | Links | `color`, `textDecorationLine` |
45+
| `mention` | Mentions | `color`, `backgroundColor`, `textDecorationLine` |
46+
| `ol` | Ordered list | `markerColor`, `markerFontWeight`, `marginLeft`, `gapWidth` |
47+
| `ul` | Unordered list | `bulletColor`, `bulletSize`, `marginLeft`, `gapWidth` |
48+
| `ulCheckbox` | Checkbox list | `boxColor`, `boxSize`, `marginLeft`, `gapWidth` |
49+
50+
The full list of properties, defaults, and platform notes lives in the
51+
`EnrichedTextInput` reference.
52+
53+
### Styling mentions per indicator
54+
55+
`mention` accepts either a single config applied to every mention, or a record
56+
keyed by [indicator](/rich-text-formatting/mentions) so each mention type gets
57+
its own look:
58+
59+
```tsx
60+
htmlStyle={{
61+
mention: {
62+
'@': { color: '#2563eb', backgroundColor: '#dbeafe' },
63+
'#': { color: '#16a34a', backgroundColor: '#dcfce7' },
64+
},
65+
}}
66+
```
67+
68+
:::tip
69+
70+
You can also create a default `mention` style config, by using the `'default'` key.
71+
72+
```tsx
73+
htmlStyle={{
74+
mention: {
75+
'default': { color: '#2563eb', backgroundColor: '#dbeafe' },
76+
'#': { color: '#16a34a', backgroundColor: '#dcfce7' },
77+
},
78+
}}
79+
```
80+
81+
This way you can create a style for any mention indicator to fallback if it doesn't have one fully defined.
82+
83+
:::

docs/docs/core-functionalities/web-support.md

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,94 @@ sidebar_position: 4
44

55
# Web support
66

7-
<!-- TODO: write content for this page -->
7+
Both `EnrichedTextInput` and `EnrichedText` run on the web. On native the editor
8+
is backed by the platform's text engine; on the web it is built on
9+
[Tiptap](https://tiptap.dev/) (on top of ProseMirror). That implementation
10+
detail stays behind the same public API.
11+
12+
## One API across platforms
13+
14+
The web build exposes the **same props, ref methods, and events** as native.
15+
Events keep their native shape too - they arrive as
16+
`NativeSyntheticEvent`, read off `e.nativeEvent`, so
17+
[event-handling](/core-functionalities/handling-events) code is portable as-is:
18+
19+
```tsx
20+
<EnrichedTextInput
21+
onChangeHtml={e => setHtml(e.nativeEvent.value)}
22+
onChangeState={e => setState(e.nativeEvent)}
23+
/>
24+
```
25+
26+
The interactive examples throughout these docs are the web build running live.
27+
28+
## Keyboard shortcuts
29+
30+
The web editor ships desktop-style formatting shortcuts out of the box, along
31+
with native browser **undo/redo**. `Mod` is `` on macOS and `Ctrl` on
32+
Windows/Linux.
33+
34+
| Action | macOS | Windows / Linux |
35+
| ------------------- | -------------- | --------------------------- |
36+
| Bold | `⌘B` | `Ctrl+B` |
37+
| Italic | `⌘I` | `Ctrl+I` |
38+
| Underline | `⌘U` | `Ctrl+U` |
39+
| Strikethrough | `⌘⇧X` | `Ctrl+Shift+X` |
40+
| Inline code | `⌘⇧C` | `Ctrl+Shift+C` |
41+
| Code block | `⌘⌥⇧C` | `Ctrl+Alt+Shift+C` |
42+
| Normal paragraph | `⌘⌥0` | `Ctrl+Alt+0` |
43+
| Heading 1–6 | `⌘⌥1``⌘⌥6` | `Ctrl+Alt+1``Ctrl+Alt+6` |
44+
| Numbered list | `⌘⇧7` | `Ctrl+Shift+7` |
45+
| Unordered list | `⌘⇧8` | `Ctrl+Shift+8` |
46+
| Checkbox list | `⌘⇧9` | `Ctrl+Shift+9` |
47+
| Paste as plain text | `⌘⇧V` | `Ctrl+Shift+V` |
48+
| Undo | `⌘Z` | `Ctrl+Z` |
49+
| Redo | `⌘⇧Z` | `Ctrl+Shift+Z` |
50+
| Select all | `⌘A` | `Ctrl+A` |
51+
52+
## Platform differences
53+
54+
A few native-only features have no web equivalent and are ignored there:
55+
56+
- **`contextMenuItems`** - the native editing menu isn't available; use your own
57+
UI instead.
58+
- **`returnKeyLabel`** - can't be set inside a browser. `returnKeyType` maps to
59+
the browser's [`enterkeyhint`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint).
60+
- **RN layout ref methods** - `measure`, `measureInWindow`, `measureLayout`, and
61+
`setNativeProps` are no-ops.
62+
63+
The [`EnrichedTextInput`](/api-reference/enriched-text-input) and
64+
[`EnrichedText`](/api-reference/enriched-text) references note per-prop platform
65+
support.
66+
67+
:::note
68+
69+
On web, `onPasteImages` gives each image a `blob:` URL. If you hold onto those
70+
URIs, call `URL.revokeObjectURL(uri)` once you're done with them (e.g. after an
71+
upload) so the browser can release the memory.
72+
73+
:::
74+
75+
## Sanitization
76+
77+
Unlike the native platforms, the web build sanitizes HTML for you. It runs
78+
[DOMPurify](https://github.com/cure53/DOMPurify) at **every entrypoint** - the
79+
`children` of `EnrichedText`, and `defaultValue`, `setValue`, and pasted content
80+
on `EnrichedTextInput`. Sanitization is also run on the input component's **output** - `getHtml()`.
81+
All of it makes that untrusted markup can't inject scripts or unsafe attributes into the DOM.
82+
83+
:::caution
84+
85+
Sanitization is tied to link detection: the [`linkRegex`](/rich-text-formatting/links)
86+
you provide determines which `href` values are allowed to survive on `<a>`
87+
elements. Anchors whose URLs don't match the pattern have their `href` stripped
88+
during sanitization.
89+
90+
:::
91+
92+
## Server-side rendering
93+
94+
The library does **not** support SSR. Normalization and sanitization both need a
95+
DOM to work against, which isn't available during server rendering. In an SSR
96+
framework (Next.js, Remix, …), make sure both `EnrichedTextInput` and
97+
`EnrichedText` render **client-side only**.

0 commit comments

Comments
 (0)