From ee591235d8ceefc12d09b00fc797847b84f6720a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= Date: Tue, 21 Jul 2026 11:43:14 +0200 Subject: [PATCH 01/12] docs: add api reference section --- .../docs/api-reference/enriched-text-input.md | 1393 ++++++++++++++++- docs/docs/api-reference/enriched-text.md | 225 ++- 2 files changed, 1616 insertions(+), 2 deletions(-) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index 1e71e6859..a38227480 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -4,4 +4,1395 @@ sidebar_position: 1 # EnrichedTextInput - +`EnrichedTextInput` is a rich text editor that styles text live as you type. +It is uncontrolled — content lives on the native side and you talk to it through +a `ref`. See [Core concepts](/fundamentals/core-concepts) for the mental model. + +## Reference + +```tsx +import { useRef } from 'react'; +import { EnrichedTextInput } from 'react-native-enriched-html'; +import type { EnrichedTextInputInstance } from 'react-native-enriched-html'; + +function App() { + const ref = useRef(null); + + return ( + { + // e.nativeEvent.bold.isActive, ... + }} + /> + ); +} +``` + +
+Type definitions + +```ts +interface EnrichedTextInputProps extends Omit { + ref?: RefObject; + autoFocus?: boolean; + editable?: boolean; + mentionIndicators?: string[]; + defaultValue?: string; + placeholder?: string; + placeholderTextColor?: ColorValue; + cursorColor?: ColorValue; + selectionColor?: ColorValue; + autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters'; + htmlStyle?: HtmlStyle; + style?: EnrichedInputStyle; + scrollEnabled?: boolean; + linkRegex?: RegExp | null; + returnKeyType?: ReturnKeyTypeOptions; + returnKeyLabel?: string; + submitBehavior?: 'submit' | 'blurAndSubmit' | 'newline'; + onFocus?: (e: FocusEvent) => void; + onBlur?: (e: BlurEvent) => void; + onChangeText?: (e: NativeSyntheticEvent) => void; + onChangeHtml?: (e: NativeSyntheticEvent) => void; + onChangeState?: (e: NativeSyntheticEvent) => void; + onLinkDetected?: (e: OnLinkDetected) => void; + onMentionDetected?: (e: OnMentionDetected) => void; + onStartMention?: (indicator: string) => void; + onChangeMention?: (e: OnChangeMentionEvent) => void; + onEndMention?: (indicator: string) => void; + onChangeSelection?: (e: NativeSyntheticEvent) => void; + onKeyPress?: (e: NativeSyntheticEvent) => void; + onSubmitEditing?: (e: NativeSyntheticEvent) => void; + onPasteImages?: (e: NativeSyntheticEvent) => void; + contextMenuItems?: ContextMenuItem[]; + textShortcuts?: TextShortcut[]; + androidExperimentalSynchronousEvents?: boolean; + useHtmlNormalizer?: boolean; + allowFontScaling?: boolean; +} +``` + +
+ +## Props + +### `allowFontScaling` {#allowfontscaling} + +If `true`, the input respects the system's accessibility font scaling settings. + +| Type | Default | Platforms | +| --------- | ------- | ------------ | +| `boolean` | `true` | Android, iOS | + +### `autoFocus` {#autofocus} + +If `true`, focuses the input when it mounts. + +| Type | Default | Platforms | +| --------- | ------- | ----------------- | +| `boolean` | `false` | Android, iOS, Web | + +### `autoCapitalize` {#autocapitalize} + +Tells the input to automatically capitalize certain characters. + +- `characters` — all characters +- `words` — first letter of each word +- `sentences` — first letter of each sentence +- `none` — don't auto-capitalize anything + +| Type | Default | Platforms | +| -------------------------------------------------- | ------------- | ----------------- | +| `'none' \| 'sentences' \| 'words' \| 'characters'` | `'sentences'` | Android, iOS, Web | + +### `contextMenuItems` {#contextmenuitems} + +An array of custom items to display in the native text editing menu. Each item +specifies a title, visibility flag, and a callback that fires when the item is +tapped. + +The `onPress` callback receives a single object argument with: + +- `text` — the currently selected text +- `selection` — an object with `start` and `end` indices of the current selection +- `styleState` — the latest `OnChangeStateEvent` payload reflecting active styles + at the time of the tap + +```ts +interface ContextMenuItem { + text: string; + onPress: (args: { + text: string; + selection: { start: number; end: number }; + styleState: OnChangeStateEvent; + }) => void; + visible?: boolean; +} +``` + +- `text` is the title displayed in the menu +- `onPress` is the callback invoked when the item is tapped +- `visible` controls whether the item is shown; defaults to `true` + +| Type | Default | Platforms | +| ------------------- | ------- | ------------ | +| `ContextMenuItem[]` | `[]` | Android, iOS | + +:::note + +On iOS, items appear in array order, before the system items (Copy/Paste/Cut). +On Android, there is no guaranteed order and custom items may be displayed in a +submenu, depending on the device manufacturer. + +::: + +### `cursorColor` {#cursorcolor} + +Sets the color of the cursor (caret) in the component. + +| Type | Default | Platforms | +| ---------------------------------------------- | -------------- | ------------ | +| [`color`](https://reactnative.dev/docs/colors) | system default | Android, Web | + +### `defaultValue` {#defaultvalue} + +Provides an initial value for the input. If the string is a valid HTML output of +`EnrichedTextInput` (or other HTML that the parser will accept), proper styles +are applied. + +| Type | Default | Platforms | +| -------- | ------- | ----------------- | +| `string` | — | Android, iOS, Web | + +### `editable` {#editable} + +If `false`, text is not editable. + +| Type | Default | Platforms | +| --------- | ------- | ----------------- | +| `boolean` | `true` | Android, iOS, Web | + +:::note + +Setting `editable` to `false` disables all user interactions with the input. +Some programmatic changes (like toggling styles or changing value imperatively) +via ref methods still work. + +::: + +### `htmlStyle` {#htmlstyle} + +Customizes the appearance of HTML elements inside the editor. See +[`HtmlStyle`](#htmlstyle-type). + +| Type | Default | Platforms | +| ----------- | -------------------------------------------------- | ----------------- | +| `HtmlStyle` | default values from [`HtmlStyle`](#htmlstyle-type) | Android, iOS, Web | + +### `mentionIndicators` {#mentionindicators} + +The recognized mention indicators. Each item must be a 1-character string. + +| Type | Default | Platforms | +| ---------- | ------- | ----------------- | +| `string[]` | `['@']` | Android, iOS, Web | + +### `linkRegex` {#linkregex} + +A custom regex pattern for detecting links in the input. If not provided, a +default regex is used. You can customize which patterns are recognized as links +— for example only `https://` URLs, or custom schemes. + +Not all JS regex features are supported; for example variable-width lookbehinds +won't work. + +| Type | Default | Platforms | +| ---------------- | ----------------------------- | ------------ | +| `RegExp \| null` | default native platform regex | Android, iOS | + +:::tip + +Pass `null` to disable link detection completely. + +::: + +### `onBlur` {#onblur} + +Called whenever the input loses focus. + +| Type | Default | Platforms | +| ------------------------ | ------- | ----------------- | +| `(e: BlurEvent) => void` | — | Android, iOS, Web | + +### `onChangeHtml` {#onchangehtml} + +Called when the input's HTML changes. + +```ts +interface OnChangeHtmlEvent { + value: string; +} +``` + +- `value` is the new HTML + +| Type | Default | Platforms | +| ---------------------------------------------------------- | ------- | ----------------- | +| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | + +:::tip + +Specifying `onChangeHtml` may have performance implications, especially with +large documents, as it requires continuous HTML parsing. If you only need the +HTML at specific moments (for example when saving), use the +[`getHTML`](#gethtml) ref method instead. When `onChangeHtml` is not provided, +the component avoids unnecessary HTML parsing. + +::: + +### `onChangeMention` {#onchangemention} + +Called whenever the user changes a mention that is being edited. + +```ts +interface OnChangeMentionEvent { + indicator: string; + text: string; +} +``` + +- `indicator` is the indicator of the currently edited mention +- `text` contains the whole text typed after the indicator + +| Type | Default | Platforms | +| --------------------------------------- | ------- | ----------------- | +| `(event: OnChangeMentionEvent) => void` | — | Android, iOS, Web | + +### `onChangeSelection` {#onchangeselection} + +Called each time the user changes the selection or moves the cursor. + +```ts +interface OnChangeSelectionEvent { + start: number; + end: number; + text: string; +} +``` + +- `start` is the index of the selection's beginning +- `end` is the first index after the selection's ending; for a cursor with no + selection, `start` equals `end` +- `text` is the input's text in the current selection + +| Type | Default | Platforms | +| --------------------------------------------------------------- | ------- | ----------------- | +| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | + +### `onChangeState` {#onchangestate} + +Called when any of the styles within the selection changes. Use this to drive +toolbar button state. See +[The style state model](/fundamentals/core-concepts#the-style-state-model). + +```ts +interface OnChangeStateEvent { + bold: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + italic: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + underline: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + strikeThrough: { + isActive: boolean; + isConflicting: boolean; + isBlocking: boolean; + }; + inlineCode: { + isActive: boolean; + isConflicting: boolean; + isBlocking: boolean; + }; + h1: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + h2: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + h3: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + h4: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + h5: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + h6: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + codeBlock: { + isActive: boolean; + isConflicting: boolean; + isBlocking: boolean; + }; + blockQuote: { + isActive: boolean; + isConflicting: boolean; + isBlocking: boolean; + }; + orderedList: { + isActive: boolean; + isConflicting: boolean; + isBlocking: boolean; + }; + unorderedList: { + isActive: boolean; + isConflicting: boolean; + isBlocking: boolean; + }; + link: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + image: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + mention: { isActive: boolean; isConflicting: boolean; isBlocking: boolean }; + checkboxList: { + isActive: boolean; + isConflicting: boolean; + isBlocking: boolean; + }; + alignment: string; +} +``` + +- `isActive` — the style is active within the current selection +- `isBlocking` — the style is blocked by another currently active style, so it + can't be toggled +- `isConflicting` — toggling the style removes a conflicting active style +- `alignment` — current text alignment of the paragraph at the cursor: + `'left'`, `'center'`, `'right'`, `'justify'`, or `'auto'` + +:::note + +On Android, `'justify'` is not supported. It is accepted in the type signature +but has no justified layout effect — text is shown with natural alignment +instead, the same as `'auto'`. + +::: + +| Type | Default | Platforms | +| ----------------------------------------------------------- | ------- | ----------------- | +| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | + +### `onChangeText` {#onchangetext} + +Called when any text changes occur in the input. + +```ts +interface OnChangeTextEvent { + value: string; +} +``` + +- `value` is the new plain-text value of the input + +| Type | Default | Platforms | +| ---------------------------------------------------------- | ------- | ----------------- | +| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | + +:::tip + +If you don't need the plain text value, omit `onChangeText` — continuous text +extraction can have performance implications. + +::: + +### `onEndMention` {#onendmention} + +Called when the user is no longer editing a mention actively — they moved the +cursor elsewhere, or typed a space and the cursor is no longer within the edited +mention. + +- `indicator` is the indicator of the mention that was being edited + +| Type | Default | Platforms | +| ----------------------------- | ------- | ----------------- | +| `(indicator: string) => void` | — | Android, iOS, Web | + +### `onFocus` {#onfocus} + +Called whenever the input is focused. + +| Type | Default | Platforms | +| ------------------------- | ------- | ----------------- | +| `(e: FocusEvent) => void` | — | Android, iOS, Web | + +### `onLinkDetected` {#onlinkdetected} + +Called when a new link has been added, or the user has moved the +cursor/selection onto a link. + +```ts +interface OnLinkDetected { + text: string; + url: string; + start: number; + end: number; +} +``` + +- `text` is the link's displayed text +- `url` is the underlying URL +- `start` is the starting index of the link +- `end` is the first index after the ending index of the link + +| Type | Default | Platforms | +| --------------------------------- | ------- | ----------------- | +| `(event: OnLinkDetected) => void` | — | Android, iOS, Web | + +### `onMentionDetected` {#onmentiondetected} + +Called when a mention has been detected — either a new mention was added, or the +user moved the cursor/selection onto a mention. + +```ts +interface OnMentionDetected { + text: string; + indicator: string; + attributes: Record; +} +``` + +- `text` is the mention's displayed text +- `indicator` is the indicator of the mention +- `attributes` are the additional user-defined attributes stored with the mention + +| Type | Default | Platforms | +| ------------------------------------ | ------- | ----------------- | +| `(event: OnMentionDetected) => void` | — | Android, iOS, Web | + +### `onStartMention` {#onstartmention} + +Called whenever mention editing starts (after placing the indicator). + +- `indicator` is the indicator of the mention that begins editing + +| Type | Default | Platforms | +| ----------------------------- | ------- | ----------------- | +| `(indicator: string) => void` | — | Android, iOS, Web | + +### `onKeyPress` {#onkeypress} + +Called when a key is pressed. See +[TextInput onKeyPress](https://reactnative.dev/docs/textinput#onkeypress) for +more details. + +```ts +interface OnKeyPressEvent { + key: string; +} +``` + +| Type | Default | Platforms | +| -------------------------------------------------------- | ------- | ----------------- | +| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | + +### `onSubmitEditing` {#onsubmitediting} + +Called when the user submits the input (presses the return/enter key while +`submitBehavior` is `'submit'` or `'blurAndSubmit'`). + +```ts +interface OnSubmitEditing { + text: string; +} +``` + +- `text` is the current plain-text content of the input at submission time + +| Type | Default | Platforms | +| -------------------------------------------------------- | ------- | ----------------- | +| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | + +### `onPasteImages` {#onpasteimages} + +Called when the user pastes one or more images or GIFs into the input. + +- `images` — an array of objects with URI, MIME type, and dimensions for each + pasted image/GIF +- **Web:** each `uri` is a `blob:` URL (`URL.createObjectURL`). If you retain + URIs, call `URL.revokeObjectURL` when finished so blobs can be released + +```ts +interface OnPasteImagesEvent { + images: { + uri: string; + type: string; + width: number; + height: number; + }[]; +} +``` + +| Type | Default | Platforms | +| ----------------------------------------------------------- | ------- | ----------------- | +| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | + +:::note + +On Web, `uri` is a blob URL (`blob:...`). Blob URLs hold memory until explicitly +released. Call `URL.revokeObjectURL(uri)` once you no longer need the image +(for example after the upload completes). + +::: + +### `placeholder` {#placeholder} + +The placeholder text displayed when nothing has been typed yet. Disappears when +something is typed. + +| Type | Default | Platforms | +| -------- | ------- | ----------------- | +| `string` | `''` | Android, iOS, Web | + +### `placeholderTextColor` {#placeholdertextcolor} + +Input placeholder's text color. + +| Type | Default | Platforms | +| ---------------------------------------------- | ----------------------- | ----------------- | +| [`color`](https://reactnative.dev/docs/colors) | input's [color](#style) | Android, iOS, Web | + +### `ref` {#ref} + +A React ref that lets you call any [ref methods](#ref-methods) on the input. + +| Type | Default | Platforms | +| ---------------------------------------------- | ------- | ----------------- | +| `RefObject` | — | Android, iOS, Web | + +### `returnKeyLabel` {#returnkeylabel} + +Overrides the return key label with a custom string. + +| Type | Default | Platforms | +| -------- | ------- | --------- | +| `string` | — | Android | + +### `returnKeyType` {#returnkeytype} + +Specifies the label or icon shown on the keyboard's return key. + +On Android, this prop is accepted but ignored, as `returnKeyType` doesn't work +with multiline inputs. + +Accepts the standard React Native `ReturnKeyTypeOptions` values: +`'go' | 'next' | 'search' | 'send' | 'done' | 'default' | 'google' | 'join' | 'route' | 'yahoo' | 'emergency-call' | 'previous' | 'none'`. + +| Type | Default | Platforms | +| ---------------------- | ----------- | --------- | +| `ReturnKeyTypeOptions` | `'default'` | iOS, Web | + +:::note + +On Web, this maps to the +[`enterkeyhint`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint) +attribute on the editor element. Only the values the browser recognises +(`'enter'`, `'done'`, `'go'`, `'next'`, `'previous'`, `'search'`, `'send'`) have +a visible effect; unsupported values are silently ignored and fall back to +`'enter'`. + +::: + +### `scrollEnabled` {#scrollenabled} + +If `false`, the editor's internal scroll view is disabled and the component +expands to fit all content. + +| Type | Default | Platforms | +| --------- | ------- | ----------------- | +| `boolean` | `true` | Android, iOS, Web | + +### `selectionColor` {#selectioncolor} + +Color of the selection rectangle drawn over the selected text. On iOS, the +cursor (caret) also uses this color. + +| Type | Default | Platforms | +| ---------------------------------------------- | -------------- | ----------------- | +| [`color`](https://reactnative.dev/docs/colors) | system default | Android, iOS, Web | + +### `style` {#style} + +Controls the layout, dimensions, typography, borders, shadows, opacity, and +similar container-level appearance of the editable content container. See +[`EnrichedInputStyle`](#enrichedinputstyle-type). + +| Type | Default | Platforms | +| -------------------- | ------- | ----------------- | +| `EnrichedInputStyle` | — | Android, iOS, Web | + +### `submitBehavior` {#submitbehavior} + +Controls what happens when the user presses the return/enter key. + +- `'newline'` — inserts a new line (default for multiline inputs) +- `'submit'` — fires `onSubmitEditing` without inserting a new line +- `'blurAndSubmit'` — fires `onSubmitEditing` and blurs the input + +| Type | Default | Platforms | +| ------------------------------------------ | ----------- | ----------------- | +| `'submit' \| 'blurAndSubmit' \| 'newline'` | `'newline'` | Android, iOS, Web | + +### `textShortcuts` {#textshortcuts} + +An array of shortcuts that auto-convert typed patterns into styles. Each entry +maps a `trigger` string to a `style`. These shortcuts allow users to format text +similarly to modern Markdown editors by typing familiar patterns directly in the +input. + +```ts +interface TextShortcut { + trigger: string; + style: TextShortcutStyle; +} + +type TextShortcutStyle = + | 'bold' + | 'italic' + | 'underline' + | 'strikethrough' + | 'inline_code' + | 'h1' + | 'h2' + | 'h3' + | 'h4' + | 'h5' + | 'h6' + | 'blockquote' + | 'codeblock' + | 'unordered_list' + | 'ordered_list' + | 'checkbox_list'; +``` + +- `trigger` is the typed pattern that activates the shortcut +- `style` is the style to apply when the trigger completes + +**[Paragraph styles](/fundamentals/html-format-and-supported-tags#paragraph-tags)** +fire at the start of a paragraph (e.g. `# ` → H1, `- ` → unordered list). +Supported styles: `h1`–`h6`, `blockquote`, `codeblock`, `unordered_list`, +`ordered_list`, `checkbox_list`. + +:::note + +Paragraph shortcuts are only effective on plain paragraphs. If the paragraph +already has an active paragraph style (for example it is already a heading or a +list item), typing the trigger pattern has no effect. + +::: + +**[Inline styles](/fundamentals/html-format-and-supported-tags#inline-tags)** +fire when a closing delimiter is typed around text (e.g. `**text**` → bold). The +trigger is the delimiter string (e.g. `**`, `*`, `~~`). Supported styles: +`bold`, `italic`, `underline`, `strikethrough`, `inline_code`. + +:::note + +Style rules still apply to shortcut-triggered styles: if the target style is +**blocked** by another currently active style (e.g. bold inside a codeblock), +the shortcut has no effect. If the target style **conflicts** with another +active style, the conflicting style is removed when the new one is applied. See +[Supported tags](/fundamentals/html-format-and-supported-tags) for the full +conflict and blocking rules. + +::: + +Default value: + +```ts +[ + { trigger: '- ', style: 'unordered_list' }, + { trigger: '1. ', style: 'ordered_list' }, +]; +``` + +| Type | Default | Platforms | +| ---------------- | --------- | ----------------- | +| `TextShortcut[]` | see above | Android, iOS, Web | + +:::note + +Pass an empty array to disable all shortcuts. + +::: + +### `useHtmlNormalizer` {#usehtmlnormalizer} + +If `true`, external HTML pasted or inserted into the input (for example from +Google Docs, Word, or web pages) is normalized into the canonical tag subset +that the enriched parser understands. See +[Normalization](/fundamentals/core-concepts#normalization). + +| Type | Default | Platforms | +| --------- | ------- | ----------------- | +| `boolean` | `true` | Android, iOS, Web | + +### `androidExperimentalSynchronousEvents` {#androidexperimentalsynchronousevents} + +:::caution + +Experimental. This feature has not been thoroughly tested. It may be enabled by +default in a future release. + +::: + +If `true`, Android uses experimental synchronous events. This can prevent input +flickering when updating component size. + +| Type | Default | Platforms | +| --------- | ------- | --------- | +| `boolean` | `false` | Android | + +### `ViewProps` {#viewprops} + +The input inherits +[ViewProps](https://reactnative.dev/docs/view#props), but some of those props +may not be supported. + +| Type | Default | Platforms | +| ----------- | ------- | ------------ | +| `ViewProps` | — | Android, iOS | + +## Ref methods + +All methods should be called on the input's [`ref`](#ref). + +### `.blur()` + +```ts +blur: () => void; +``` + +Blurs the input. + +### `.focus()` + +```ts +focus: () => void; +``` + +Focuses the input. + +### `.getHTML()` + +```ts +getHTML: () => Promise; +``` + +Returns a Promise that resolves with the current HTML content of the input. +Useful when you need the HTML on demand (for example when saving) without the +performance overhead of continuous parsing via `onChangeHtml`. + +### `.setImage()` + +```ts +setImage: (src: string, width: number, height: number) => void; +``` + +Sets an inline image at the current selection. + +- `src: string` — absolute path to a file or remote image address +- `width: number` — width of the image +- `height: number` — height of the image + +:::note + +It's the developer's responsibility to provide proper width and height, which +may require calculating aspect ratio. If the image source is incorrect, a static +placeholder is displayed. + +::: + +### `.setLink()` + +```ts +setLink: (start: number, end: number, text: string, url: string) => void; +``` + +Sets a link at the given place with the given displayed text and URL. The link +replaces any text between `start` and `end`. Setting a link with `start` equal +to `end` inserts it in place. + +- `start: number` — starting index where the link should be +- `end: number` — first index behind the new link's ending index +- `text: string` — displayed text of the link +- `url: string` — URL of the link + +### `.removeLink()` + +```ts +removeLink: (start: number, end: number) => void; +``` + +Removes link styling from any links found within the given range. The text +content is preserved; only the link attributes are stripped. Out-of-bounds +values are clamped to a valid range. + +- `start: number` — starting index of the range to remove links from +- `end: number` — first index behind the range's ending index + +### `.setMention()` + +```ts +setMention: ( + indicator: string, + text: string, + attributes?: Record +) => void; +``` + +Sets the currently edited mention with a given indicator, displayed text, and +custom attributes. + +- `indicator: string` — indicator of the set mention +- `text: string` — text displayed for the mention; anything the user typed is + replaced by that text. The mention indicator isn't added to that text +- `attributes?: Record` — additional custom attributes for the + mention, preserved through parsing to and from HTML + +### `.setValue()` + +```ts +setValue: (value: string) => void; +``` + +Sets the input's value. + +- `value: string` — value to set; either a supported HTML string or raw text + +### `.setSelection()` + +```ts +setSelection: (start: number, end: number) => void; +``` + +Sets the selection at the given indexes. + +- `start: number` — starting index of the selection +- `end: number` — first index after the selection's ending index; for a cursor + with no selection, `start` equals `end` + +### `.setTextAlignment()` + +```ts +setTextAlignment: ( + alignment: 'left' | 'center' | 'right' | 'justify' | 'auto' +) => void; +``` + +Sets text alignment for the paragraph(s) at the current selection. When inside a +list, the alignment is applied to all contiguous list items. + +- `alignment` — desired text alignment; use `'auto'` to reset to the system + natural alignment + +:::note + +On Android, `'justify'` is not supported. Calling +`setTextAlignment('justify')` does not apply justified text — the paragraph ends +up with natural alignment, the same as `'auto'`. + +::: + +### `.startMention()` + +```ts +startMention: (indicator: string) => void; +``` + +Starts a mention with the given indicator at the cursor/selection. + +- `indicator: string` — indicator that starts the new mention + +### `.toggleBlockQuote()` + +```ts +toggleBlockQuote: () => void; +``` + +Toggles blockquote style at the current selection. + +### `.toggleBold()` + +```ts +toggleBold: () => void; +``` + +Toggles bold formatting at the current selection. + +### `.toggleCodeBlock()` + +```ts +toggleCodeBlock: () => void; +``` + +Toggles codeblock formatting at the current selection. + +### `.toggleH1()` + +```ts +toggleH1: () => void; +``` + +Toggles heading 1 (H1) style at the current selection. + +### `.toggleH2()` + +```ts +toggleH2: () => void; +``` + +Toggles heading 2 (H2) style at the current selection. + +### `.toggleH3()` + +```ts +toggleH3: () => void; +``` + +Toggles heading 3 (H3) style at the current selection. + +### `.toggleH4()` + +```ts +toggleH4: () => void; +``` + +Toggles heading 4 (H4) style at the current selection. + +### `.toggleH5()` + +```ts +toggleH5: () => void; +``` + +Toggles heading 5 (H5) style at the current selection. + +### `.toggleH6()` + +```ts +toggleH6: () => void; +``` + +Toggles heading 6 (H6) style at the current selection. + +### `.toggleInlineCode()` + +```ts +toggleInlineCode: () => void; +``` + +Applies inline code formatting to the current selection. + +### `.toggleItalic()` + +```ts +toggleItalic: () => void; +``` + +Toggles italic formatting at the current selection. + +### `.toggleOrderedList()` + +```ts +toggleOrderedList: () => void; +``` + +Converts the current selection into an ordered list. + +### `.toggleStrikeThrough()` + +```ts +toggleStrikeThrough: () => void; +``` + +Applies strikethrough formatting to the current selection. + +### `.toggleUnderline()` + +```ts +toggleUnderline: () => void; +``` + +Applies underline formatting to the current selection. + +### `.toggleUnorderedList()` + +```ts +toggleUnorderedList: () => void; +``` + +Converts the current selection into an unordered list. + +### `.toggleCheckboxList()` + +```ts +toggleCheckboxList: (checked: boolean) => void; +``` + +Converts the current selection into an unordered list with checkboxes as items. +Each checkbox can be checked or unchecked. The user can later toggle each +checkbox individually by tapping on it. + +- `checked: boolean` — whether the checkboxes should be checked or unchecked by + default + +## HtmlStyle type + +Allows customizing HTML styles inside the editor. + +```ts +interface HtmlStyle { + h1?: { + fontSize?: number; + bold?: boolean; + }; + h2?: { + fontSize?: number; + bold?: boolean; + }; + h3?: { + fontSize?: number; + bold?: boolean; + }; + h4?: { + fontSize?: number; + bold?: boolean; + }; + h5?: { + fontSize?: number; + bold?: boolean; + }; + h6?: { + fontSize?: number; + bold?: boolean; + }; + blockquote?: { + borderColor?: ColorValue; + borderWidth?: number; + gapWidth?: number; + color?: ColorValue; + }; + codeblock?: { + color?: ColorValue; + borderRadius?: number; + backgroundColor?: ColorValue; + }; + code?: { + color?: ColorValue; + backgroundColor?: ColorValue; + }; + a?: { + color?: ColorValue; + textDecorationLine?: 'underline' | 'none'; + }; + mention?: Record | MentionStyleProperties; + ol?: { + gapWidth?: number; + marginLeft?: number; + markerFontWeight?: TextStyle['fontWeight']; + markerColor?: ColorValue; + }; + ul?: { + bulletColor?: ColorValue; + bulletSize?: number; + marginLeft?: number; + gapWidth?: number; + }; + ulCheckbox?: { + boxColor?: ColorValue; + boxSize?: number; + marginLeft?: number; + gapWidth?: number; + }; +} + +interface MentionStyleProperties { + color?: ColorValue; + backgroundColor?: ColorValue; + textDecorationLine?: 'underline' | 'none'; +} +``` + +### h1/h2/h3/h4/h5/h6 (headings) + +- `fontSize` — size of the heading's font. Defaults to `32` for `H1`, `24` for + `H2`, `20` for `H3`, `16` for `H4`, `14` for `H5`, `12` for `H6` +- `bold` — whether the heading should be bolded; defaults to `false` + +### blockquote + +- `borderColor` — color of the rectangular border drawn to the left of + blockquote text; takes a [color](https://reactnative.dev/docs/colors) value, + defaults to `darkgray` +- `borderWidth` — width of that border; defaults to `4` +- `gapWidth` — width of the gap between the border and the blockquote text; + defaults to `16` +- `color` — color of blockquote text; takes a + [color](https://reactnative.dev/docs/colors) value; if not set, uses the + input's [color](#style) + +### codeblock + +- `color` — color of codeblock text; takes a + [color](https://reactnative.dev/docs/colors) value, defaults to `black` +- `borderRadius` — radius of the codeblock's border; defaults to `8` +- `backgroundColor` — codeblock background color; takes a + [color](https://reactnative.dev/docs/colors) value, defaults to `darkgray` + +### code (inline code) + +- `color` — color of inline code text; takes a + [color](https://reactnative.dev/docs/colors) value, defaults to `red` +- `backgroundColor` — inline code background color; takes a + [color](https://reactnative.dev/docs/colors) value, defaults to `darkgray` + +### a (link) + +- `color` — color of link text; takes a + [color](https://reactnative.dev/docs/colors) value, defaults to `blue` +- `textDecorationLine` — whether links are underlined; `'underline'` or + `'none'`, defaults to `'underline'` + +### mention + +If only a single config is given, the style applies to all mention types. You +can also set a different config for each `mentionIndicator`; then the prop +should be a record with indicators as keys and configs as values. + +- `color` — color of mention text; takes a + [color](https://reactnative.dev/docs/colors) value, defaults to `blue` +- `backgroundColor` — mention background color; takes a + [color](https://reactnative.dev/docs/colors) value, defaults to `yellow` +- `textDecorationLine` — whether mentions are underlined; `'underline'` or + `'none'`, defaults to `'underline'` + +### ol (ordered list) + +By marker, we mean the number that denotes consecutive lines of the list. + +- `gapWidth` — gap between the marker and the list item's text; defaults to `16` +- `marginLeft` — margin to the left of the marker (between the marker and the + input's left edge); defaults to `16` +- `markerFontWeight` — font weight of the marker; takes a + [fontWeight](https://reactnative.dev/docs/text-style-props#fontweight) value; + if not set, defaults to the input's [fontWeight](#style) +- `markerColor` — text color of the marker; takes a + [color](https://reactnative.dev/docs/colors) value; if not set, defaults to + the input's [color](#style) + +### ul (unordered list) + +By bullet, we mean the dot that begins each line of the list. + +- `bulletColor` — color of the bullet; takes a + [color](https://reactnative.dev/docs/colors) value, defaults to `black` +- `bulletSize` — height and width of the bullet; defaults to `8` +- `marginLeft` — margin to the left of the bullet; defaults to `16` +- `gapWidth` — gap between the bullet and the list item's text; defaults to `16` + +### ulCheckbox (checkbox list) + +Unordered list with checkboxes instead of bullets. + +- `boxColor` — color of the checkbox; takes a + [color](https://reactnative.dev/docs/colors) value, defaults to `blue` +- `boxSize` — height and width of the checkbox; defaults to `24` +- `marginLeft` — margin to the left of the checkbox; defaults to `16` +- `gapWidth` — gap between the checkbox and the list item's text; defaults to + `16` + +## EnrichedInputStyle type + +Defines the [`style`](#style) prop's shape. This type is a subset of React +Native's [TextStyle](https://reactnative.dev/docs/text-style-props) — some +properties are not supported (for example `textAlign`, `textDecorationLine`, +`justifyContent`). Certain properties are platform-specific and include an +`@platform` directive in the type definition. + +Type definition + +
+Type definition + +```ts +export interface EnrichedInputStyle { + // Layout / FlexStyle + alignSelf?: FlexStyle['alignSelf']; + aspectRatio?: number | string; + borderBottomWidth?: number; + borderEndWidth?: number; + borderLeftWidth?: number; + borderRightWidth?: number; + borderStartWidth?: number; + borderTopWidth?: number; + borderWidth?: number; + bottom?: DimensionValue; + boxSizing?: TextStyle['boxSizing']; + display?: TextStyle['display']; + end?: DimensionValue; + flex?: number; + flexBasis?: DimensionValue; + flexGrow?: number; + flexShrink?: number; + height?: DimensionValue; + inset?: DimensionValue; + insetBlock?: DimensionValue; + insetBlockEnd?: DimensionValue; + insetBlockStart?: DimensionValue; + insetInline?: DimensionValue; + insetInlineEnd?: DimensionValue; + insetInlineStart?: DimensionValue; + left?: DimensionValue; + margin?: DimensionValue; + marginBlock?: DimensionValue; + marginBlockEnd?: DimensionValue; + marginBlockStart?: DimensionValue; + marginBottom?: DimensionValue; + marginEnd?: DimensionValue; + marginHorizontal?: DimensionValue; + marginInline?: DimensionValue; + marginInlineEnd?: DimensionValue; + marginInlineStart?: DimensionValue; + marginLeft?: DimensionValue; + marginRight?: DimensionValue; + marginStart?: DimensionValue; + marginTop?: DimensionValue; + marginVertical?: DimensionValue; + maxHeight?: DimensionValue; + maxWidth?: DimensionValue; + minHeight?: DimensionValue; + minWidth?: DimensionValue; + padding?: DimensionValue; + paddingBlock?: DimensionValue; + paddingBlockEnd?: DimensionValue; + paddingBlockStart?: DimensionValue; + paddingBottom?: DimensionValue; + paddingEnd?: DimensionValue; + paddingHorizontal?: DimensionValue; + paddingInline?: DimensionValue; + paddingInlineEnd?: DimensionValue; + paddingInlineStart?: DimensionValue; + paddingLeft?: DimensionValue; + paddingRight?: DimensionValue; + paddingStart?: DimensionValue; + paddingTop?: DimensionValue; + paddingVertical?: DimensionValue; + position?: FlexStyle['position']; + right?: DimensionValue; + start?: DimensionValue; + top?: DimensionValue; + width?: DimensionValue; + zIndex?: number; + + // Shadows + /** @platform ios */ + shadowColor?: ColorValue; + /** @platform ios */ + shadowOffset?: TextStyle['shadowOffset']; + /** @platform ios */ + shadowOpacity?: TextStyle['shadowOpacity']; + /** @platform ios */ + shadowRadius?: number; + + // Transforms + transform?: TextStyle['transform']; + transformOrigin?: TextStyle['transformOrigin']; + + // View appearance + /** @platform ios web */ + backfaceVisibility?: TextStyle['backfaceVisibility']; + backgroundColor?: ColorValue; + /** @platform ios web */ + borderBlockColor?: ColorValue; + /** @platform ios web */ + borderBlockEndColor?: ColorValue; + /** @platform ios web */ + borderBlockStartColor?: ColorValue; + /** @platform ios web */ + borderBottomColor?: ColorValue; + /** @platform ios web */ + borderBottomEndRadius?: TextStyle['borderBottomEndRadius']; + /** @platform ios web */ + borderBottomLeftRadius?: TextStyle['borderBottomLeftRadius']; + /** @platform ios web */ + borderBottomRightRadius?: TextStyle['borderBottomRightRadius']; + /** @platform ios web */ + borderBottomStartRadius?: TextStyle['borderBottomStartRadius']; + /** @platform ios web */ + borderColor?: ColorValue; + /** @platform ios web */ + borderEndColor?: ColorValue; + /** @platform ios web */ + borderEndEndRadius?: TextStyle['borderEndEndRadius']; + /** @platform ios web */ + borderEndStartRadius?: TextStyle['borderEndStartRadius']; + /** @platform ios web */ + borderLeftColor?: ColorValue; + /** @platform ios web */ + borderRadius?: TextStyle['borderRadius']; + /** @platform ios web */ + borderRightColor?: ColorValue; + /** @platform ios web */ + borderStartColor?: ColorValue; + /** @platform ios web */ + borderStartEndRadius?: TextStyle['borderStartEndRadius']; + /** @platform ios web */ + borderStartStartRadius?: TextStyle['borderStartStartRadius']; + /** @platform ios web */ + borderStyle?: TextStyle['borderStyle']; + /** @platform ios web */ + borderTopColor?: ColorValue; + /** @platform ios web */ + borderTopEndRadius?: TextStyle['borderTopEndRadius']; + /** @platform ios web */ + borderTopLeftRadius?: TextStyle['borderTopLeftRadius']; + /** @platform ios web */ + borderTopRightRadius?: TextStyle['borderTopRightRadius']; + /** @platform ios web */ + borderTopStartRadius?: TextStyle['borderTopStartRadius']; + boxShadow?: TextStyle['boxShadow']; + /** @platform web */ + cursor?: TextStyle['cursor']; + /** @platform android */ + elevation?: number; + /** @platform android web */ + filter?: TextStyle['filter']; + /** @platform android web */ + mixBlendMode?: TextStyle['mixBlendMode']; + opacity?: TextStyle['opacity']; + /** @platform ios web */ + outlineColor?: ColorValue; + outlineOffset?: TextStyle['outlineOffset']; + /** @platform android web */ + outlineStyle?: TextStyle['outlineStyle']; + outlineWidth?: TextStyle['outlineWidth']; + /** @platform ios web */ + pointerEvents?: TextStyle['pointerEvents']; + + // Typography + color?: ColorValue; + fontFamily?: string; + fontSize?: number; + fontStyle?: TextStyle['fontStyle']; + fontWeight?: TextStyle['fontWeight']; + lineHeight?: number; + /** @platform web */ + letterSpacing?: number; +} +``` + +
+ +## Remarks + +- The input is uncontrolled. Change content and formatting through ref methods; + observe changes through events. See + [Core concepts](/fundamentals/core-concepts#the-input-is-uncontrolled). +- Prefer [`getHTML`](#gethtml) over continuous `onChangeHtml` when you only need + HTML at specific moments. +- Sanitizing HTML is your responsibility. See + [Core concepts](/fundamentals/core-concepts#html-is-the-source-of-truth). +- For the full list of supported tags and style conflicts, see + [Supported tags](/fundamentals/html-format-and-supported-tags). + +## Platform compatibility + + diff --git a/docs/docs/api-reference/enriched-text.md b/docs/docs/api-reference/enriched-text.md index d2bde28cf..88105cdbb 100644 --- a/docs/docs/api-reference/enriched-text.md +++ b/docs/docs/api-reference/enriched-text.md @@ -4,4 +4,227 @@ sidebar_position: 2 # EnrichedText - +`EnrichedText` is a read-only component that renders rich text from an HTML string. +It accepts the same HTML format produced by [`EnrichedTextInput`](/api-reference/enriched-text-input). + +## Reference + +```tsx +import { EnrichedText } from 'react-native-enriched-html'; + +function App() { + return ( + + {'

Hello world

'} +
+ ); +} +``` + +
+Type definitions + +```ts +interface EnrichedTextProps extends ViewProps { + children: string; + style?: TextStyle; + htmlStyle?: EnrichedTextHtmlStyle; + useHtmlNormalizer?: boolean; + ellipsizeMode?: 'head' | 'middle' | 'tail' | 'clip'; + numberOfLines?: number; + selectable?: boolean; + selectionColor?: ColorValue; + allowFontScaling?: boolean; + onLinkPress?: (event: OnLinkPressEvent) => void; + onMentionPress?: (event: OnMentionPressEvent) => void; +} +``` + +
+ +## Props + +### `allowFontScaling` {#allowfontscaling} + +If `true`, the text respects the system's accessibility font scaling settings. + +| Type | Default | Platforms | +| --------- | ------- | ------------ | +| `boolean` | `true` | Android, iOS | + +### `children` {#children} + +The HTML string to render. Accepts the HTML format produced by +[`EnrichedTextInput`](/api-reference/enriched-text-input). See +[Supported tags](/fundamentals/html-format-and-supported-tags) for the full tag set. + +| Type | Default | Platforms | +| -------- | ------- | ----------------- | +| `string` | — | Android, iOS, Web | + +### `style` {#style} + +Standard React Native `TextStyle` applied to the text. + +| Type | Default | Platforms | +| ----------- | ------- | ----------------- | +| `TextStyle` | — | Android, iOS, Web | + +### `htmlStyle` {#htmlstyle} + +Customizes styles of HTML elements, including press colors for interactive +elements. See [`EnrichedTextHtmlStyle`](#enrichedtexthtmlstyle-type). + +| Type | Default | Platforms | +| ----------------------- | ------- | ----------------- | +| `EnrichedTextHtmlStyle` | — | Android, iOS, Web | + +### `useHtmlNormalizer` {#usehtmlnormalizer} + +If `true`, external HTML (for example from Google Docs, Word, or web pages) is +normalized before rendering. This converts arbitrary HTML into the canonical +tag subset that the enriched parser understands. See +[Normalization](/fundamentals/core-concepts#normalization). + +| Type | Default | Platforms | +| --------- | ------- | ----------------- | +| `boolean` | `true` | Android, iOS, Web | + +### `ellipsizeMode` {#ellipsizemode} + +How the text should be truncated when `numberOfLines` is set and the text overflows. + +- `head` — truncates at the beginning, e.g. `...wxyz` +- `middle` — truncates in the middle, e.g. `ab...yz` +- `tail` — truncates at the end, e.g. `abcd...` +- `clip` — clips the text without inserting an ellipsis + +| Type | Default | Platforms | +| ---------------------------------------- | -------- | ------------ | +| `'head' \| 'middle' \| 'tail' \| 'clip'` | `'tail'` | Android, iOS | + +:::note + +On Android, when `numberOfLines` is set to a value higher than `1`, only +`tail` works correctly. + +::: + +### `numberOfLines` {#numberoflines} + +Limits the number of displayed lines. Set to `0` for unlimited lines. + +| Type | Default | Platforms | +| -------- | ------- | ------------ | +| `number` | `0` | Android, iOS | + +### `selectable` {#selectable} + +If `true`, the text can be selected by the user (for example for copy/paste). + +| Type | Default | Platforms | +| --------- | ------- | ----------------- | +| `boolean` | `false` | Android, iOS, Web | + +### `selectionColor` {#selectioncolor} + +The color of the text selection highlight. + +| Type | Default | Platforms | +| ---------------------------------------------- | -------------- | ----------------- | +| [`color`](https://reactnative.dev/docs/colors) | system default | Android, iOS, Web | + +### `onLinkPress` {#onlinkpress} + +Called when the user presses a link element. Receives an `OnLinkPressEvent` +containing the link's URL. + +```ts +interface OnLinkPressEvent { + url: string; +} +``` + +| Type | Default | Platforms | +| ----------------------------------- | ------- | ----------------- | +| `(event: OnLinkPressEvent) => void` | — | Android, iOS, Web | + +### `onMentionPress` {#onmentionpress} + +Called when the user presses a mention element. Receives an +`OnMentionPressEvent` with the mention's text, indicator character, and custom +attributes. + +```ts +interface OnMentionPressEvent { + text: string; + indicator: string; + attributes: Record; +} +``` + +| Type | Default | Platforms | +| -------------------------------------- | ------- | ----------------- | +| `(event: OnMentionPressEvent) => void` | — | Android, iOS, Web | + +## EnrichedTextHtmlStyle type + +Extends [`HtmlStyle`](/api-reference/enriched-text-input#htmlstyle-type) with +additional press-state styling for interactive elements. All properties from +`HtmlStyle` are supported except `a` and `mention`, which are replaced by the +extended versions below. + +```ts +interface EnrichedTextHtmlStyle extends Omit { + a?: { + color?: ColorValue; + textDecorationLine?: 'underline' | 'none'; + pressColor?: ColorValue; + }; + mention?: + | Record + | EnrichedTextMentionStyleProperties; +} + +interface EnrichedTextMentionStyleProperties { + color?: ColorValue; + backgroundColor?: ColorValue; + textDecorationLine?: 'underline' | 'none'; + pressColor?: ColorValue; + pressBackgroundColor?: ColorValue; +} +``` + +### a (link) + +Inherits all properties from [`HtmlStyle`'s `a`](/api-reference/enriched-text-input#a-link) +and adds: + +- `pressColor` — the color of the link text while it is being pressed. Takes a + [color](https://reactnative.dev/docs/colors) value. + +### mention + +Inherits all properties from +[`HtmlStyle`'s `mention`](/api-reference/enriched-text-input#mention) and adds: + +- `pressColor` — the color of the mention text while it is being pressed. Takes + a [color](https://reactnative.dev/docs/colors) value. +- `pressBackgroundColor` — the background color of the mention while it is being + pressed. Takes a [color](https://reactnative.dev/docs/colors) value. + +Same as in `HtmlStyle`, if only a single config is given the style applies to +all mention types. To style each indicator separately, pass a record with +indicators as keys and configs as values. + +## Remarks + +- `EnrichedText` is read-only. Use [`EnrichedTextInput`](/api-reference/enriched-text-input) + when the user needs to edit content. +- Pass the HTML string as `children`, not as a `value` prop. +- Sanitizing HTML is your responsibility. See + [Core concepts](/fundamentals/core-concepts#html-is-the-source-of-truth). + +## Platform compatibility + + From 06d9c7f370458a19d929ba218e4c7b5447720543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= <74975508+kacperzolkiewski@users.noreply.github.com> Date: Tue, 21 Jul 2026 11:52:51 +0200 Subject: [PATCH 02/12] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/docs/api-reference/enriched-text.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/api-reference/enriched-text.md b/docs/docs/api-reference/enriched-text.md index 88105cdbb..710a6baf8 100644 --- a/docs/docs/api-reference/enriched-text.md +++ b/docs/docs/api-reference/enriched-text.md @@ -26,6 +26,7 @@ function App() { ```ts interface EnrichedTextProps extends ViewProps { + ref?: RefObject; children: string; style?: TextStyle; htmlStyle?: EnrichedTextHtmlStyle; From 5e9f42afebf2b06e8057066e7ae3c7e1d1f53713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= <74975508+kacperzolkiewski@users.noreply.github.com> Date: Tue, 21 Jul 2026 11:53:23 +0200 Subject: [PATCH 03/12] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/docs/api-reference/enriched-text-input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index a38227480..050e9086a 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -139,7 +139,7 @@ interface ContextMenuItem { | Type | Default | Platforms | | ------------------- | ------- | ------------ | -| `ContextMenuItem[]` | `[]` | Android, iOS | +| `ContextMenuItem[]` | — | Android, iOS | :::note From b2fe84b13a684dc9ff47ed2a4b0974686cff0a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= <74975508+kacperzolkiewski@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:28:08 +0200 Subject: [PATCH 04/12] Update docs/docs/api-reference/enriched-text-input.md Co-authored-by: Krystian Sienkiewicz <146986839+hejsztynx@users.noreply.github.com> --- docs/docs/api-reference/enriched-text-input.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index 050e9086a..c0e631ccd 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -5,8 +5,7 @@ sidebar_position: 1 # EnrichedTextInput `EnrichedTextInput` is a rich text editor that styles text live as you type. -It is uncontrolled — content lives on the native side and you talk to it through -a `ref`. See [Core concepts](/fundamentals/core-concepts) for the mental model. +See [Core concepts](/fundamentals/core-concepts) for the mental model. ## Reference From 2774cd48a91626732ee2e97416f0222299cc1ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= <74975508+kacperzolkiewski@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:29:44 +0200 Subject: [PATCH 05/12] Update docs/docs/api-reference/enriched-text-input.md Co-authored-by: Krystian Sienkiewicz <146986839+hejsztynx@users.noreply.github.com> --- docs/docs/api-reference/enriched-text-input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index c0e631ccd..e84a5fc75 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -210,7 +210,7 @@ won't work. | Type | Default | Platforms | | ---------------- | ----------------------------- | ------------ | -| `RegExp \| null` | default native platform regex | Android, iOS | +| `RegExp \| null` | default native platform regex | Android, iOS, Web | :::tip From c26e19815695da16024ea17535cdc53c283f01f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= <74975508+kacperzolkiewski@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:30:26 +0200 Subject: [PATCH 06/12] Update docs/docs/api-reference/enriched-text-input.md Co-authored-by: Krystian Sienkiewicz <146986839+hejsztynx@users.noreply.github.com> --- docs/docs/api-reference/enriched-text-input.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index e84a5fc75..e48f5b1ad 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -247,8 +247,7 @@ interface OnChangeHtmlEvent { Specifying `onChangeHtml` may have performance implications, especially with large documents, as it requires continuous HTML parsing. If you only need the HTML at specific moments (for example when saving), use the -[`getHTML`](#gethtml) ref method instead. When `onChangeHtml` is not provided, -the component avoids unnecessary HTML parsing. +[`getHTML`](#gethtml) ref method instead. ::: From 801f5648a1be3da1490fb6a06976214c9d5ec878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= <74975508+kacperzolkiewski@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:31:31 +0200 Subject: [PATCH 07/12] Update docs/docs/api-reference/enriched-text-input.md Co-authored-by: Krystian Sienkiewicz <146986839+hejsztynx@users.noreply.github.com> --- docs/docs/api-reference/enriched-text-input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index e48f5b1ad..4b9622ee4 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -413,7 +413,7 @@ Called whenever the input is focused. ### `onLinkDetected` {#onlinkdetected} -Called when a new link has been added, or the user has moved the +Called when the user has moved the cursor/selection onto a link. ```ts From d54d822cac2f4107f32c19bf89802bb882c4ec38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= <74975508+kacperzolkiewski@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:31:55 +0200 Subject: [PATCH 08/12] Update docs/docs/api-reference/enriched-text-input.md Co-authored-by: Krystian Sienkiewicz <146986839+hejsztynx@users.noreply.github.com> --- docs/docs/api-reference/enriched-text-input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index 4b9622ee4..6d476c467 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -1389,7 +1389,7 @@ export interface EnrichedInputStyle { - Sanitizing HTML is your responsibility. See [Core concepts](/fundamentals/core-concepts#html-is-the-source-of-truth). - For the full list of supported tags and style conflicts, see - [Supported tags](/fundamentals/html-format-and-supported-tags). + [HTML format and supported tags](/fundamentals/html-format-and-supported-tags). ## Platform compatibility From 8cdbef9888985fea39410a245438b7704269e6ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= <74975508+kacperzolkiewski@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:33:04 +0200 Subject: [PATCH 09/12] Update docs/docs/api-reference/enriched-text-input.md Co-authored-by: Krystian Sienkiewicz <146986839+hejsztynx@users.noreply.github.com> --- docs/docs/api-reference/enriched-text-input.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index 6d476c467..2db04f3c1 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -845,6 +845,15 @@ custom attributes. - `attributes?: Record` — additional custom attributes for the mention, preserved through parsing to and from HTML +:::note + +The attributes you pass to `setMention` ride along in the HTML +and survive a round-trip through `getHTML` / `setValue`. Prefix custom keys with +`data-` if they need to outlive a sanitizer - see the note in +[Mentions](/rich-text-formatting/mentions). + +::: + ### `.setValue()` ```ts From eae4b5a88c04e2dbf0bdbd88fc18496308c7d7a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= <74975508+kacperzolkiewski@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:39:16 +0200 Subject: [PATCH 10/12] Apply suggestions from code review Co-authored-by: Krystian Sienkiewicz <146986839+hejsztynx@users.noreply.github.com> --- docs/docs/api-reference/enriched-text-input.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index 2db04f3c1..e23d144e2 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -436,7 +436,7 @@ interface OnLinkDetected { ### `onMentionDetected` {#onmentiondetected} -Called when a mention has been detected — either a new mention was added, or the +Called when the user moved the cursor/selection onto a mention. ```ts @@ -457,7 +457,7 @@ interface OnMentionDetected { ### `onStartMention` {#onstartmention} -Called whenever mention editing starts (after placing the indicator). +Called whenever mention editing starts. - `indicator` is the indicator of the mention that begins editing @@ -504,8 +504,6 @@ Called when the user pastes one or more images or GIFs into the input. - `images` — an array of objects with URI, MIME type, and dimensions for each pasted image/GIF -- **Web:** each `uri` is a `blob:` URL (`URL.createObjectURL`). If you retain - URIs, call `URL.revokeObjectURL` when finished so blobs can be released ```ts interface OnPasteImagesEvent { @@ -820,8 +818,7 @@ removeLink: (start: number, end: number) => void; ``` Removes link styling from any links found within the given range. The text -content is preserved; only the link attributes are stripped. Out-of-bounds -values are clamped to a valid range. +content is preserved; only the link attributes are stripped. - `start: number` — starting index of the range to remove links from - `end: number` — first index behind the range's ending index From 3a058cc4c2857040596e1a34cb54d77d629b980f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= Date: Tue, 21 Jul 2026 15:12:54 +0200 Subject: [PATCH 11/12] fix: reveiw changes --- .../docs/api-reference/enriched-text-input.md | 206 ++++++++++-------- docs/docs/api-reference/enriched-text.md | 27 +-- 2 files changed, 126 insertions(+), 107 deletions(-) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index e23d144e2..c654c32b1 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -98,10 +98,10 @@ If `true`, focuses the input when it mounts. Tells the input to automatically capitalize certain characters. -- `characters` — all characters -- `words` — first letter of each word -- `sentences` — first letter of each sentence -- `none` — don't auto-capitalize anything +- `characters` - all characters +- `words` - first letter of each word +- `sentences` - first letter of each sentence +- `none` - don't auto-capitalize anything | Type | Default | Platforms | | -------------------------------------------------- | ------------- | ----------------- | @@ -113,13 +113,6 @@ An array of custom items to display in the native text editing menu. Each item specifies a title, visibility flag, and a callback that fires when the item is tapped. -The `onPress` callback receives a single object argument with: - -- `text` — the currently selected text -- `selection` — an object with `start` and `end` indices of the current selection -- `styleState` — the latest `OnChangeStateEvent` payload reflecting active styles - at the time of the tap - ```ts interface ContextMenuItem { text: string; @@ -136,9 +129,16 @@ interface ContextMenuItem { - `onPress` is the callback invoked when the item is tapped - `visible` controls whether the item is shown; defaults to `true` +The `onPress` callback receives a single object argument with: + +- `text` - the currently selected text +- `selection` - an object with `start` and `end` indices of the current selection +- `styleState` - the latest `OnChangeStateEvent` payload reflecting active styles + at the time of the tap + | Type | Default | Platforms | | ------------------- | ------- | ------------ | -| `ContextMenuItem[]` | — | Android, iOS | +| `ContextMenuItem[]` | - | Android, iOS | :::note @@ -164,7 +164,7 @@ are applied. | Type | Default | Platforms | | -------- | ------- | ----------------- | -| `string` | — | Android, iOS, Web | +| `string` | - | Android, iOS, Web | ### `editable` {#editable} @@ -203,13 +203,14 @@ The recognized mention indicators. Each item must be a 1-character string. A custom regex pattern for detecting links in the input. If not provided, a default regex is used. You can customize which patterns are recognized as links -— for example only `https://` URLs, or custom schemes. + +- for example only `https://` URLs, or custom schemes. Not all JS regex features are supported; for example variable-width lookbehinds won't work. -| Type | Default | Platforms | -| ---------------- | ----------------------------- | ------------ | +| Type | Default | Platforms | +| ---------------- | ----------------------------- | ----------------- | | `RegExp \| null` | default native platform regex | Android, iOS, Web | :::tip @@ -224,7 +225,7 @@ Called whenever the input loses focus. | Type | Default | Platforms | | ------------------------ | ------- | ----------------- | -| `(e: BlurEvent) => void` | — | Android, iOS, Web | +| `(e: BlurEvent) => void` | - | Android, iOS, Web | ### `onChangeHtml` {#onchangehtml} @@ -240,7 +241,7 @@ interface OnChangeHtmlEvent { | Type | Default | Platforms | | ---------------------------------------------------------- | ------- | ----------------- | -| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | +| `(event: NativeSyntheticEvent) => void` | - | Android, iOS, Web | :::tip @@ -253,7 +254,7 @@ HTML at specific moments (for example when saving), use the ### `onChangeMention` {#onchangemention} -Called whenever the user changes a mention that is being edited. +Called whenever the text typed after the mention indicator changes while a mention is being edited. ```ts interface OnChangeMentionEvent { @@ -267,7 +268,7 @@ interface OnChangeMentionEvent { | Type | Default | Platforms | | --------------------------------------- | ------- | ----------------- | -| `(event: OnChangeMentionEvent) => void` | — | Android, iOS, Web | +| `(event: OnChangeMentionEvent) => void` | - | Android, iOS, Web | ### `onChangeSelection` {#onchangeselection} @@ -288,7 +289,7 @@ interface OnChangeSelectionEvent { | Type | Default | Platforms | | --------------------------------------------------------------- | ------- | ----------------- | -| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | +| `(event: NativeSyntheticEvent) => void` | - | Android, iOS, Web | ### `onChangeState` {#onchangestate} @@ -349,24 +350,24 @@ interface OnChangeStateEvent { } ``` -- `isActive` — the style is active within the current selection -- `isBlocking` — the style is blocked by another currently active style, so it +- `isActive` - the style is active within the current selection +- `isBlocking` - the style is blocked by another currently active style, so it can't be toggled -- `isConflicting` — toggling the style removes a conflicting active style -- `alignment` — current text alignment of the paragraph at the cursor: +- `isConflicting` - toggling the style removes a conflicting active style +- `alignment` - current text alignment of the paragraph at the cursor: `'left'`, `'center'`, `'right'`, `'justify'`, or `'auto'` :::note On Android, `'justify'` is not supported. It is accepted in the type signature -but has no justified layout effect — text is shown with natural alignment +but has no justified layout effect - text is shown with natural alignment instead, the same as `'auto'`. ::: | Type | Default | Platforms | | ----------------------------------------------------------- | ------- | ----------------- | -| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | +| `(event: NativeSyntheticEvent) => void` | - | Android, iOS, Web | ### `onChangeText` {#onchangetext} @@ -382,18 +383,18 @@ interface OnChangeTextEvent { | Type | Default | Platforms | | ---------------------------------------------------------- | ------- | ----------------- | -| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | +| `(event: NativeSyntheticEvent) => void` | - | Android, iOS, Web | :::tip -If you don't need the plain text value, omit `onChangeText` — continuous text +If you don't need the plain text value, omit `onChangeText` - continuous text extraction can have performance implications. ::: ### `onEndMention` {#onendmention} -Called when the user is no longer editing a mention actively — they moved the +Called when the user is no longer editing a mention actively - they moved the cursor elsewhere, or typed a space and the cursor is no longer within the edited mention. @@ -401,7 +402,7 @@ mention. | Type | Default | Platforms | | ----------------------------- | ------- | ----------------- | -| `(indicator: string) => void` | — | Android, iOS, Web | +| `(indicator: string) => void` | - | Android, iOS, Web | ### `onFocus` {#onfocus} @@ -409,7 +410,7 @@ Called whenever the input is focused. | Type | Default | Platforms | | ------------------------- | ------- | ----------------- | -| `(e: FocusEvent) => void` | — | Android, iOS, Web | +| `(e: FocusEvent) => void` | - | Android, iOS, Web | ### `onLinkDetected` {#onlinkdetected} @@ -432,7 +433,7 @@ interface OnLinkDetected { | Type | Default | Platforms | | --------------------------------- | ------- | ----------------- | -| `(event: OnLinkDetected) => void` | — | Android, iOS, Web | +| `(event: OnLinkDetected) => void` | - | Android, iOS, Web | ### `onMentionDetected` {#onmentiondetected} @@ -453,7 +454,7 @@ interface OnMentionDetected { | Type | Default | Platforms | | ------------------------------------ | ------- | ----------------- | -| `(event: OnMentionDetected) => void` | — | Android, iOS, Web | +| `(event: OnMentionDetected) => void` | - | Android, iOS, Web | ### `onStartMention` {#onstartmention} @@ -463,7 +464,7 @@ Called whenever mention editing starts. | Type | Default | Platforms | | ----------------------------- | ------- | ----------------- | -| `(indicator: string) => void` | — | Android, iOS, Web | +| `(indicator: string) => void` | - | Android, iOS, Web | ### `onKeyPress` {#onkeypress} @@ -479,7 +480,7 @@ interface OnKeyPressEvent { | Type | Default | Platforms | | -------------------------------------------------------- | ------- | ----------------- | -| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | +| `(event: NativeSyntheticEvent) => void` | - | Android, iOS, Web | ### `onSubmitEditing` {#onsubmitediting} @@ -496,13 +497,13 @@ interface OnSubmitEditing { | Type | Default | Platforms | | -------------------------------------------------------- | ------- | ----------------- | -| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | +| `(event: NativeSyntheticEvent) => void` | - | Android, iOS, Web | ### `onPasteImages` {#onpasteimages} Called when the user pastes one or more images or GIFs into the input. -- `images` — an array of objects with URI, MIME type, and dimensions for each +- `images` - an array of objects with URI, MIME type, and dimensions for each pasted image/GIF ```ts @@ -518,7 +519,7 @@ interface OnPasteImagesEvent { | Type | Default | Platforms | | ----------------------------------------------------------- | ------- | ----------------- | -| `(event: NativeSyntheticEvent) => void` | — | Android, iOS, Web | +| `(event: NativeSyntheticEvent) => void` | - | Android, iOS, Web | :::note @@ -551,7 +552,7 @@ A React ref that lets you call any [ref methods](#ref-methods) on the input. | Type | Default | Platforms | | ---------------------------------------------- | ------- | ----------------- | -| `RefObject` | — | Android, iOS, Web | +| `RefObject` | - | Android, iOS, Web | ### `returnKeyLabel` {#returnkeylabel} @@ -559,7 +560,7 @@ Overrides the return key label with a custom string. | Type | Default | Platforms | | -------- | ------- | --------- | -| `string` | — | Android | +| `string` | - | Android | ### `returnKeyType` {#returnkeytype} @@ -612,15 +613,15 @@ similar container-level appearance of the editable content container. See | Type | Default | Platforms | | -------------------- | ------- | ----------------- | -| `EnrichedInputStyle` | — | Android, iOS, Web | +| `EnrichedInputStyle` | - | Android, iOS, Web | ### `submitBehavior` {#submitbehavior} Controls what happens when the user presses the return/enter key. -- `'newline'` — inserts a new line (default for multiline inputs) -- `'submit'` — fires `onSubmitEditing` without inserting a new line -- `'blurAndSubmit'` — fires `onSubmitEditing` and blurs the input +- `'newline'` - inserts a new line (default for multiline inputs) +- `'submit'` - fires `onSubmitEditing` without inserting a new line +- `'blurAndSubmit'` - fires `onSubmitEditing` and blurs the input | Type | Default | Platforms | | ------------------------------------------ | ----------- | ----------------- | @@ -744,7 +745,7 @@ may not be supported. | Type | Default | Platforms | | ----------- | ------- | ------------ | -| `ViewProps` | — | Android, iOS | +| `ViewProps` | - | Android, iOS | ## Ref methods @@ -784,9 +785,9 @@ setImage: (src: string, width: number, height: number) => void; Sets an inline image at the current selection. -- `src: string` — absolute path to a file or remote image address -- `width: number` — width of the image -- `height: number` — height of the image +- `src: string` - absolute path to a file or remote image address +- `width: number` - width of the image +- `height: number` - height of the image :::note @@ -806,10 +807,10 @@ Sets a link at the given place with the given displayed text and URL. The link replaces any text between `start` and `end`. Setting a link with `start` equal to `end` inserts it in place. -- `start: number` — starting index where the link should be -- `end: number` — first index behind the new link's ending index -- `text: string` — displayed text of the link -- `url: string` — URL of the link +- `start: number` - starting index where the link should be +- `end: number` - first index behind the new link's ending index +- `text: string` - displayed text of the link +- `url: string` - URL of the link ### `.removeLink()` @@ -820,8 +821,8 @@ removeLink: (start: number, end: number) => void; Removes link styling from any links found within the given range. The text content is preserved; only the link attributes are stripped. -- `start: number` — starting index of the range to remove links from -- `end: number` — first index behind the range's ending index +- `start: number` - starting index of the range to remove links from +- `end: number` - first index behind the range's ending index ### `.setMention()` @@ -836,10 +837,10 @@ setMention: ( Sets the currently edited mention with a given indicator, displayed text, and custom attributes. -- `indicator: string` — indicator of the set mention -- `text: string` — text displayed for the mention; anything the user typed is +- `indicator: string` - indicator of the set mention +- `text: string` - text displayed for the mention; anything the user typed is replaced by that text. The mention indicator isn't added to that text -- `attributes?: Record` — additional custom attributes for the +- `attributes?: Record` - additional custom attributes for the mention, preserved through parsing to and from HTML :::note @@ -859,7 +860,7 @@ setValue: (value: string) => void; Sets the input's value. -- `value: string` — value to set; either a supported HTML string or raw text +- `value: string` - value to set; either a supported HTML string or raw text ### `.setSelection()` @@ -869,8 +870,8 @@ setSelection: (start: number, end: number) => void; Sets the selection at the given indexes. -- `start: number` — starting index of the selection -- `end: number` — first index after the selection's ending index; for a cursor +- `start: number` - starting index of the selection +- `end: number` - first index after the selection's ending index; for a cursor with no selection, `start` equals `end` ### `.setTextAlignment()` @@ -884,13 +885,13 @@ setTextAlignment: ( Sets text alignment for the paragraph(s) at the current selection. When inside a list, the alignment is applied to all contiguous list items. -- `alignment` — desired text alignment; use `'auto'` to reset to the system +- `alignment` - desired text alignment; use `'auto'` to reset to the system natural alignment :::note On Android, `'justify'` is not supported. Calling -`setTextAlignment('justify')` does not apply justified text — the paragraph ends +`setTextAlignment('justify')` does not apply justified text - the paragraph ends up with natural alignment, the same as `'auto'`. ::: @@ -903,7 +904,7 @@ startMention: (indicator: string) => void; Starts a mention with the given indicator at the cursor/selection. -- `indicator: string` — indicator that starts the new mention +- `indicator: string` - indicator that starts the new mention ### `.toggleBlockQuote()` @@ -1035,7 +1036,7 @@ Converts the current selection into an unordered list with checkboxes as items. Each checkbox can be checked or unchecked. The user can later toggle each checkbox individually by tapping on it. -- `checked: boolean` — whether the checkboxes should be checked or unchecked by +- `checked: boolean` - whether the checkboxes should be checked or unchecked by default ## HtmlStyle type @@ -1117,42 +1118,42 @@ interface MentionStyleProperties { ### h1/h2/h3/h4/h5/h6 (headings) -- `fontSize` — size of the heading's font. Defaults to `32` for `H1`, `24` for +- `fontSize` - size of the heading's font. Defaults to `32` for `H1`, `24` for `H2`, `20` for `H3`, `16` for `H4`, `14` for `H5`, `12` for `H6` -- `bold` — whether the heading should be bolded; defaults to `false` +- `bold` - whether the heading should be bolded; defaults to `false` ### blockquote -- `borderColor` — color of the rectangular border drawn to the left of +- `borderColor` - color of the rectangular border drawn to the left of blockquote text; takes a [color](https://reactnative.dev/docs/colors) value, defaults to `darkgray` -- `borderWidth` — width of that border; defaults to `4` -- `gapWidth` — width of the gap between the border and the blockquote text; +- `borderWidth` - width of that border; defaults to `4` +- `gapWidth` - width of the gap between the border and the blockquote text; defaults to `16` -- `color` — color of blockquote text; takes a +- `color` - color of blockquote text; takes a [color](https://reactnative.dev/docs/colors) value; if not set, uses the input's [color](#style) ### codeblock -- `color` — color of codeblock text; takes a +- `color` - color of codeblock text; takes a [color](https://reactnative.dev/docs/colors) value, defaults to `black` -- `borderRadius` — radius of the codeblock's border; defaults to `8` -- `backgroundColor` — codeblock background color; takes a +- `borderRadius` - radius of the codeblock's border; defaults to `8` +- `backgroundColor` - codeblock background color; takes a [color](https://reactnative.dev/docs/colors) value, defaults to `darkgray` ### code (inline code) -- `color` — color of inline code text; takes a +- `color` - color of inline code text; takes a [color](https://reactnative.dev/docs/colors) value, defaults to `red` -- `backgroundColor` — inline code background color; takes a +- `backgroundColor` - inline code background color; takes a [color](https://reactnative.dev/docs/colors) value, defaults to `darkgray` ### a (link) -- `color` — color of link text; takes a +- `color` - color of link text; takes a [color](https://reactnative.dev/docs/colors) value, defaults to `blue` -- `textDecorationLine` — whether links are underlined; `'underline'` or +- `textDecorationLine` - whether links are underlined; `'underline'` or `'none'`, defaults to `'underline'` ### mention @@ -1161,24 +1162,41 @@ If only a single config is given, the style applies to all mention types. You can also set a different config for each `mentionIndicator`; then the prop should be a record with indicators as keys and configs as values. -- `color` — color of mention text; takes a +- `color` - color of mention text; takes a [color](https://reactnative.dev/docs/colors) value, defaults to `blue` -- `backgroundColor` — mention background color; takes a +- `backgroundColor` - mention background color; takes a [color](https://reactnative.dev/docs/colors) value, defaults to `yellow` -- `textDecorationLine` — whether mentions are underlined; `'underline'` or +- `textDecorationLine` - whether mentions are underlined; `'underline'` or `'none'`, defaults to `'underline'` +:::tip + +You can also create a default `mention` style config, by using the `'default'` key. + +```tsx +htmlStyle={{ + mention: { + 'default': { color: '#2563eb', backgroundColor: '#dbeafe' }, + '#': { color: '#16a34a', backgroundColor: '#dcfce7' }, + }, +}} +``` + +This way you can create a style for any mention indicator to fallback if it doesn't have one fully defined. + +::: + ### ol (ordered list) By marker, we mean the number that denotes consecutive lines of the list. -- `gapWidth` — gap between the marker and the list item's text; defaults to `16` -- `marginLeft` — margin to the left of the marker (between the marker and the +- `gapWidth` - gap between the marker and the list item's text; defaults to `16` +- `marginLeft` - margin to the left of the marker (between the marker and the input's left edge); defaults to `16` -- `markerFontWeight` — font weight of the marker; takes a +- `markerFontWeight` - font weight of the marker; takes a [fontWeight](https://reactnative.dev/docs/text-style-props#fontweight) value; if not set, defaults to the input's [fontWeight](#style) -- `markerColor` — text color of the marker; takes a +- `markerColor` - text color of the marker; takes a [color](https://reactnative.dev/docs/colors) value; if not set, defaults to the input's [color](#style) @@ -1186,27 +1204,27 @@ By marker, we mean the number that denotes consecutive lines of the list. By bullet, we mean the dot that begins each line of the list. -- `bulletColor` — color of the bullet; takes a +- `bulletColor` - color of the bullet; takes a [color](https://reactnative.dev/docs/colors) value, defaults to `black` -- `bulletSize` — height and width of the bullet; defaults to `8` -- `marginLeft` — margin to the left of the bullet; defaults to `16` -- `gapWidth` — gap between the bullet and the list item's text; defaults to `16` +- `bulletSize` - height and width of the bullet; defaults to `8` +- `marginLeft` - margin to the left of the bullet; defaults to `16` +- `gapWidth` - gap between the bullet and the list item's text; defaults to `16` ### ulCheckbox (checkbox list) Unordered list with checkboxes instead of bullets. -- `boxColor` — color of the checkbox; takes a +- `boxColor` - color of the checkbox; takes a [color](https://reactnative.dev/docs/colors) value, defaults to `blue` -- `boxSize` — height and width of the checkbox; defaults to `24` -- `marginLeft` — margin to the left of the checkbox; defaults to `16` -- `gapWidth` — gap between the checkbox and the list item's text; defaults to +- `boxSize` - height and width of the checkbox; defaults to `24` +- `marginLeft` - margin to the left of the checkbox; defaults to `16` +- `gapWidth` - gap between the checkbox and the list item's text; defaults to `16` ## EnrichedInputStyle type Defines the [`style`](#style) prop's shape. This type is a subset of React -Native's [TextStyle](https://reactnative.dev/docs/text-style-props) — some +Native's [TextStyle](https://reactnative.dev/docs/text-style-props) - some properties are not supported (for example `textAlign`, `textDecorationLine`, `justifyContent`). Certain properties are platform-specific and include an `@platform` directive in the type definition. diff --git a/docs/docs/api-reference/enriched-text.md b/docs/docs/api-reference/enriched-text.md index 710a6baf8..fb0c89c39 100644 --- a/docs/docs/api-reference/enriched-text.md +++ b/docs/docs/api-reference/enriched-text.md @@ -61,7 +61,7 @@ The HTML string to render. Accepts the HTML format produced by | Type | Default | Platforms | | -------- | ------- | ----------------- | -| `string` | — | Android, iOS, Web | +| `string` | - | Android, iOS, Web | ### `style` {#style} @@ -69,7 +69,7 @@ Standard React Native `TextStyle` applied to the text. | Type | Default | Platforms | | ----------- | ------- | ----------------- | -| `TextStyle` | — | Android, iOS, Web | +| `TextStyle` | - | Android, iOS, Web | ### `htmlStyle` {#htmlstyle} @@ -78,7 +78,7 @@ elements. See [`EnrichedTextHtmlStyle`](#enrichedtexthtmlstyle-type). | Type | Default | Platforms | | ----------------------- | ------- | ----------------- | -| `EnrichedTextHtmlStyle` | — | Android, iOS, Web | +| `EnrichedTextHtmlStyle` | - | Android, iOS, Web | ### `useHtmlNormalizer` {#usehtmlnormalizer} @@ -95,10 +95,10 @@ tag subset that the enriched parser understands. See How the text should be truncated when `numberOfLines` is set and the text overflows. -- `head` — truncates at the beginning, e.g. `...wxyz` -- `middle` — truncates in the middle, e.g. `ab...yz` -- `tail` — truncates at the end, e.g. `abcd...` -- `clip` — clips the text without inserting an ellipsis +- `head` - truncates at the beginning, e.g. `...wxyz` +- `middle` - truncates in the middle, e.g. `ab...yz` +- `tail` - truncates at the end, e.g. `abcd...` +- `clip` - clips the text without inserting an ellipsis | Type | Default | Platforms | | ---------------------------------------- | -------- | ------------ | @@ -148,7 +148,7 @@ interface OnLinkPressEvent { | Type | Default | Platforms | | ----------------------------------- | ------- | ----------------- | -| `(event: OnLinkPressEvent) => void` | — | Android, iOS, Web | +| `(event: OnLinkPressEvent) => void` | - | Android, iOS, Web | ### `onMentionPress` {#onmentionpress} @@ -166,7 +166,7 @@ interface OnMentionPressEvent { | Type | Default | Platforms | | -------------------------------------- | ------- | ----------------- | -| `(event: OnMentionPressEvent) => void` | — | Android, iOS, Web | +| `(event: OnMentionPressEvent) => void` | - | Android, iOS, Web | ## EnrichedTextHtmlStyle type @@ -201,7 +201,7 @@ interface EnrichedTextMentionStyleProperties { Inherits all properties from [`HtmlStyle`'s `a`](/api-reference/enriched-text-input#a-link) and adds: -- `pressColor` — the color of the link text while it is being pressed. Takes a +- `pressColor` - the color of the link text while it is being pressed. Takes a [color](https://reactnative.dev/docs/colors) value. ### mention @@ -209,14 +209,15 @@ and adds: Inherits all properties from [`HtmlStyle`'s `mention`](/api-reference/enriched-text-input#mention) and adds: -- `pressColor` — the color of the mention text while it is being pressed. Takes +- `pressColor` - the color of the mention text while it is being pressed. Takes a [color](https://reactnative.dev/docs/colors) value. -- `pressBackgroundColor` — the background color of the mention while it is being +- `pressBackgroundColor` - the background color of the mention while it is being pressed. Takes a [color](https://reactnative.dev/docs/colors) value. Same as in `HtmlStyle`, if only a single config is given the style applies to all mention types. To style each indicator separately, pass a record with -indicators as keys and configs as values. +indicators as keys and configs as values. Use the `'default'` key for a fallback +style applied to any indicator without its own config. ## Remarks From 1fc7625565fdcd578bd29d32da49ec74cb288a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= Date: Wed, 22 Jul 2026 07:53:15 +0200 Subject: [PATCH 12/12] docs: fix conflicts description --- docs/docs/api-reference/enriched-text-input.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/api-reference/enriched-text-input.md b/docs/docs/api-reference/enriched-text-input.md index c654c32b1..7a1f8482b 100644 --- a/docs/docs/api-reference/enriched-text-input.md +++ b/docs/docs/api-reference/enriched-text-input.md @@ -685,8 +685,8 @@ trigger is the delimiter string (e.g. `**`, `*`, `~~`). Supported styles: Style rules still apply to shortcut-triggered styles: if the target style is **blocked** by another currently active style (e.g. bold inside a codeblock), the shortcut has no effect. If the target style **conflicts** with another -active style, the conflicting style is removed when the new one is applied. See -[Supported tags](/fundamentals/html-format-and-supported-tags) for the full +active inline style, the conflicting style is removed when the new one is +applied. See [Supported tags](/fundamentals/html-format-and-supported-tags) for the full conflict and blocking rules. :::