diff --git a/docs/docs/core-functionalities/handling-events.md b/docs/docs/core-functionalities/handling-events.md deleted file mode 100644 index f66526c28..000000000 --- a/docs/docs/core-functionalities/handling-events.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Handling events - - diff --git a/docs/docs/core-functionalities/handling-input-events.md b/docs/docs/core-functionalities/handling-input-events.md new file mode 100644 index 000000000..aeadd6351 --- /dev/null +++ b/docs/docs/core-functionalities/handling-input-events.md @@ -0,0 +1,67 @@ +--- +sidebar_position: 3 +--- + +# Handling input events + +Since the input is [uncontrolled](/fundamentals/core-concepts#the-input-is-uncontrolled), +events are how you observe it. You change content by calling ref methods; you +react to changes by listening to the callbacks below. + +Full payload shapes of the available callbacks can be found in the `EnrichedTextInput` reference. + +:::note + +This page covers `EnrichedTextInput` events. The read-only +[`EnrichedText`](/core-functionalities/rendering-rich-text) component only +exposes `onLinkPress` and `onMentionPress` callbacks. + +::: + +## Content + +- **`onChangeText`** - plain-text content changed. +- **`onChangeHtml`** - the HTML changed. + +:::tip + +The `onChangeHtml` callback has to parse the content into HTML on every keystroke. +This is a heavy computational operation that might slow down your app's performance. Consider using the `getHTML()` ref method instead if it meets your requirements. + +::: + +## Selection and style state + +- **`onChangeSelection`** - the cursor moved or the selection changed. Gives you + `start`, `end`, and the selected `text`. Useful for range-based methods like + [`setLink`](/rich-text-formatting/links). +- **`onChangeState`** - the active styles at the cursor changed. This is the + event that drives a toolbar by using reported `isActive`, `isBlocking`, and + `isConflicting`, plus the current `alignment`. See the + [style state model](/fundamentals/core-concepts#the-style-state-model). + +## Focus + +- **`onFocus`** / **`onBlur`** - the input gained or lost focus. + +## Mentions + +- **`onStartMention`** - a mention started being edited. +- **`onChangeMention`** - the query after the indicator changed. +- **`onEndMention`** - editing a mention stopped. +- **`onMentionDetected`** - the cursor entered or left a mention. + +## Links + +- **`onLinkDetected`** - the cursor entered or left a link. + +## Images + +- **`onPasteImages`** - the user pasted one or more images; hands you each + image's data so you can upload and insert them with + [`setImage`](/rich-text-formatting/inline-images). + +## Keyboard and submission + +- **`onKeyPress`** - a key was pressed. +- **`onSubmitEditing`** - the user pressed return/enter key. Fired when `submitBehavior` is set to either `submit` or `blurAndSubmit`. diff --git a/docs/docs/core-functionalities/rendering-rich-text.md b/docs/docs/core-functionalities/rendering-rich-text.md deleted file mode 100644 index be631660e..000000000 --- a/docs/docs/core-functionalities/rendering-rich-text.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rendering rich text - - diff --git a/docs/docs/core-functionalities/rendering-rich-text.mdx b/docs/docs/core-functionalities/rendering-rich-text.mdx new file mode 100644 index 000000000..0a26a9dba --- /dev/null +++ b/docs/docs/core-functionalities/rendering-rich-text.mdx @@ -0,0 +1,82 @@ +--- +sidebar_position: 2 +--- + +import InteractiveExample from '@site/src/components/InteractiveExample'; +import RenderingEditor from '@site/src/examples/RenderingEditor'; +import RenderingEditorSrc from '!!raw-loader!@site/src/examples/RenderingEditor'; + +# Rendering rich text + +`EnrichedTextInput` is for editing. To _display_ rich text without an editor - +a chat message, a comment, an article - use its read-only counterpart, +**`EnrichedText`**. + +Both components speak the same [HTML format](/fundamentals/html-format-and-supported-tags), +so the typical flow is: edit in `EnrichedTextInput`, persist the +`getHTML` output, and later feed that +string to `EnrichedText`. + +## Passing content + +`EnrichedText` takes the HTML string as its `children`: + +```tsx +import { EnrichedText } from 'react-native-enriched-html'; + +{'

Hello world

'}
; +``` + +## Styling + +Styling mirrors the input. `style` controls the container and base typography, +and `htmlStyle` controls per-element appearance. `EnrichedText` extends +`htmlStyle` with **press states** for interactive elements, since links and +mentions are pressable here: + +```tsx + + {html} + +``` + +The added `pressColor` / `pressBackgroundColor` fields on `a` and `mention` are +the only shape difference from the input's `htmlStyle`. See the +[`EnrichedText`](/api-reference/enriched-text) reference for the full type. + +## Notable props + +- **`selectable`** - allow the user to select and copy the rendered text. + Defaults to `false`. +- **`onLinkPress` / `onMentionPress`** - fire when a link or mention is pressed. +- **`numberOfLines` / `ellipsizeMode`** - truncate long content to a fixed + number of lines with an ellipsis. +- **`useHtmlNormalizer`** - normalize external or messy HTML into the library's canonical + tag subset before rendering. Defaults to `true`. See + [Normalization](/fundamentals/core-concepts#normalization). +- **`allowFontScaling`** - whether to respect the system's accessibility font scaling settings. + +:::note + +On web, the default behavior of the pressed `` tag is suppressed. To navigate to the link's URL, you need to properly handle the `onLinkPress` event. + +::: + +## Try it out + +Format some text in the editor, then press **Render** - the current HTML is read +with `getHTML()` and handed to an `EnrichedText` below. + + + +:::caution + +On iOS and Android, `EnrichedText` does not sanitize HTML for you. Sanitize anything you render that +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). + +::: diff --git a/docs/docs/core-functionalities/styling-the-input.md b/docs/docs/core-functionalities/styling-the-input.md deleted file mode 100644 index f517a6deb..000000000 --- a/docs/docs/core-functionalities/styling-the-input.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Styling the input - - diff --git a/docs/docs/core-functionalities/styling-the-input.mdx b/docs/docs/core-functionalities/styling-the-input.mdx new file mode 100644 index 000000000..2375ff183 --- /dev/null +++ b/docs/docs/core-functionalities/styling-the-input.mdx @@ -0,0 +1,110 @@ +--- +sidebar_position: 1 +--- + +# Styling the input + +`EnrichedTextInput` is styled through two separate props. Together they cover +everything from the container's dimensions down to the color of a bullet point. + +- **`style`** - the container's layout behavior and its base typography (`fontSize`, `color`, `fontFamily`, …). It accepts a subset of React Native's `TextStyle`, described by + `EnrichedInputStyle`. +- **`htmlStyle`** - the appearance of individual rich text elements: heading + sizes, blockquote borders, code colors, list markers, mention colors, and so + on. +- **`placeholderTextColor`** - the color of the placeholder text. +- **`selectionColor`** - the color of the text selection highlight. +- **`cursorColor`** - the color of the text cursor. + +:::note + +`cursorColor` is not supported on iOS. For more platform differences, see [Compatibility](/misc/compatibility). + +::: + +Here's an interactive live example - edit the `style` and `htmlStyle` values below and the preview updates live. +You can also check the full API reference for `htmlStyle` and `style`, come back and experiment around here. + +```jsx live +function StylingExample() { + return ( + + ); +} +``` + +## `style` + +`style` accepts a subset of React Native's `TextStyle` - layout, appearance, +and base typography - described by `EnrichedInputStyle`. Most of these map directly +to their React Native `TextStyle` counterparts. Some are platform-limited +(e.g. `shadowColor` is iOS-only, `elevation` is Android-only) - see the +`EnrichedTextInput` reference for the full property list. + +## `htmlStyle` + +`htmlStyle` maps each supported element to a small config object. Anything you +omit falls back to the built-in default. The available keys are: + +| Key | Styles | Notable options | +| ------------ | -------------- | ----------------------------------------------------------- | +| `h1`–`h6` | Headings | `fontSize`, `bold` | +| `blockquote` | Blockquote | `borderColor`, `borderWidth`, `gapWidth`, `color` | +| `codeblock` | Code block | `color`, `backgroundColor`, `borderRadius` | +| `code` | Inline code | `color`, `backgroundColor` | +| `a` | Links | `color`, `textDecorationLine` | +| `mention` | Mentions | `color`, `backgroundColor`, `textDecorationLine` | +| `ol` | Ordered list | `markerColor`, `markerFontWeight`, `marginLeft`, `gapWidth` | +| `ul` | Unordered list | `bulletColor`, `bulletSize`, `marginLeft`, `gapWidth` | +| `ulCheckbox` | Checkbox list | `boxColor`, `boxSize`, `marginLeft`, `gapWidth` | + +The full list of properties, defaults, and platform notes lives in the +`EnrichedTextInput` reference. + +### Styling mentions per indicator + +`mention` accepts either a single config applied to every mention, or a record +keyed by [indicator](/rich-text-formatting/mentions) so each mention type gets +its own look: + +```tsx +htmlStyle={{ + mention: { + '@': { color: '#2563eb', backgroundColor: '#dbeafe' }, + '#': { color: '#16a34a', backgroundColor: '#dcfce7' }, + }, +}} +``` + +:::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. + +::: diff --git a/docs/docs/core-functionalities/web-support.md b/docs/docs/core-functionalities/web-support.md index bc5958b68..dd82cfe3b 100644 --- a/docs/docs/core-functionalities/web-support.md +++ b/docs/docs/core-functionalities/web-support.md @@ -4,4 +4,91 @@ sidebar_position: 4 # Web support - +Both `EnrichedTextInput` and `EnrichedText` run on the web. On native the editor +is backed by the platform's text engine; on the web it is built on +[Tiptap](https://tiptap.dev/). That implementation +detail stays behind the same public API. + +## One API across platforms + +The web build exposes the same core API as native - **props, ref methods, and events** - +with one web-only addition - `sanitizationConfig` prop. +Events keep their native shape too - they arrive as +`NativeSyntheticEvent`, read off `e.nativeEvent`, so +[event-handling](/core-functionalities/handling-input-events) code is portable as-is: + +```tsx + setHtml(e.nativeEvent.value)} + onChangeState={e => setState(e.nativeEvent)} +/> +``` + +The interactive examples throughout these docs are the web build running live. + +## Keyboard shortcuts + +The web editor ships desktop-style formatting shortcuts out of the box, along +with native browser **undo/redo**. + +| Action | macOS | Windows / Linux | +| ------------------- | -------------- | --------------------------- | +| Bold | `⌘B` | `Ctrl+B` | +| Italic | `⌘I` | `Ctrl+I` | +| Underline | `⌘U` | `Ctrl+U` | +| Strikethrough | `⌘⇧X` | `Ctrl+Shift+X` | +| Inline code | `⌘⇧C` | `Ctrl+Shift+C` | +| Code block | `⌘⌥⇧C` | `Ctrl+Alt+Shift+C` | +| Normal paragraph | `⌘⌥0` | `Ctrl+Alt+0` | +| Heading 1–6 | `⌘⌥1` – `⌘⌥6` | `Ctrl+Alt+1` – `Ctrl+Alt+6` | +| Numbered list | `⌘⇧7` | `Ctrl+Shift+7` | +| Unordered list | `⌘⇧8` | `Ctrl+Shift+8` | +| Checkbox list | `⌘⇧9` | `Ctrl+Shift+9` | +| Paste as plain text | `⌘⇧V` | `Ctrl+Shift+V` | +| Undo | `⌘Z` | `Ctrl+Z` | +| Redo | `⌘⇧Z` | `Ctrl+Shift+Z` | +| Select all | `⌘A` | `Ctrl+A` | + +## Platform differences + +A few native-only features have no web equivalent and are ignored there: + +- **`contextMenuItems`** - the native editing menu isn't available; use your own + UI instead. +- **`returnKeyLabel`** - can't be set inside a browser. `returnKeyType` maps to + the browser's [`enterkeyhint`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint). +- **RN layout ref methods** - `measure`, `measureInWindow`, `measureLayout`, and + `setNativeProps` are no-ops. + +The [`EnrichedTextInput`](/api-reference/enriched-text-input) and +[`EnrichedText`](/api-reference/enriched-text) references note per-prop platform +support. + +:::note + +On web, `onPasteImages` gives each image a `blob:` URL. If you hold onto those +URIs, call `URL.revokeObjectURL(uri)` once you're done with them (e.g. after an +upload) so the browser can release the memory. + +::: + +## Sanitization + +Unlike the native platforms, the web build sanitizes HTML for you. It runs +[DOMPurify](https://github.com/cure53/DOMPurify) at **every entrypoint** - the +`children` of `EnrichedText`, `defaultValue`, `setValue` and content pasted into `EnrichedTextInput`. Sanitization is also run on the input component's **output** - `getHTML()`. +This ensures untrusted markup can't inject scripts or unsafe attributes into the DOM. + +:::note + +Sanitization can be customized with the `sanitizationConfig` prop. It allows you to set a `linkRegex` that +will define, which URI-containing attributes will actually be preserved by the sanitizer. + +::: + +## Server-side rendering + +The library does **not** support SSR yet. Normalization and sanitization both need a +DOM to work against, which isn't available during server rendering. In an SSR +framework (Next.js, Remix, …), make sure both `EnrichedTextInput` and +`EnrichedText` render **client-side only**. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index f33e901a8..0eb4ad73c 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -96,7 +96,7 @@ const config = { mermaid: true, }, - themes: ['@docusaurus/theme-mermaid'], + themes: ['@docusaurus/theme-mermaid', '@docusaurus/theme-live-codeblock'], i18n: { defaultLocale: 'en', diff --git a/docs/package.json b/docs/package.json index bf23e7443..65022e2a0 100644 --- a/docs/package.json +++ b/docs/package.json @@ -21,6 +21,7 @@ "@docusaurus/preset-classic": "3.9.2", "@docusaurus/theme-classic": "3.9.2", "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-live-codeblock": "3.9.2", "@docusaurus/theme-mermaid": "3.9.2", "@docusaurus/theme-search-algolia": "3.9.2", "@emotion/react": "^11.14.0", diff --git a/docs/src/css/overrides.css b/docs/src/css/overrides.css index ad338fc08..1f3e7eec6 100644 --- a/docs/src/css/overrides.css +++ b/docs/src/css/overrides.css @@ -88,6 +88,38 @@ table thead tr { margin-right: 1em; } +/* Match the live (`jsx live`) code block playground to the look of the docs */ +[class*='playgroundContainer'] { + border: 1px solid var(--swm-border); + border-radius: var(--ifm-code-border-radius); + box-shadow: none; +} + +[class*='playgroundHeader'], +[class*='playgroundHeader']:first-of-type { + background-color: var(--swm-off-background) !important; + color: var(--ifm-color-content) !important; + text-transform: none !important; + font-weight: 500 !important; + letter-spacing: normal !important; + font-size: var(--ifm-code-font-size) !important; + padding: 0.5rem var(--ifm-pre-padding) !important; + border-bottom: 1px solid var(--swm-border); +} + +[class*='playgroundEditor'] { + background-color: var(--swm-off-background) !important; +} + +[class*='playgroundEditor'] pre { + border: none; +} + +[class*='playgroundPreview'] { + background-color: var(--ifm-background-color); + border-top: 1px solid var(--swm-border); +} + .theme-doc-version-badge { color: var(--swm-version-badge); background: var(--swm-version-badge-background); diff --git a/docs/src/examples/RenderingEditor.tsx b/docs/src/examples/RenderingEditor.tsx new file mode 100644 index 000000000..3040dd015 --- /dev/null +++ b/docs/src/examples/RenderingEditor.tsx @@ -0,0 +1,129 @@ +import { EnrichedTextInput, EnrichedText } from 'react-native-enriched-html'; +import type { + EnrichedTextInputInstance, + OnChangeStateEvent, +} from 'react-native-enriched-html'; +import { useRef, useState } from 'react'; +import { View, StyleSheet, Pressable, Text } from 'react-native'; + +export default function App() { + const ref = useRef(null); + const [state, setState] = useState(null); + const [html, setHtml] = useState( + '

Edit the input above, then press Render.

' + ); + + const buttons = [ + { + label: 'Bold', + state: state?.bold, + onPress: () => ref.current?.toggleBold(), + }, + { + label: 'Italic', + state: state?.italic, + onPress: () => ref.current?.toggleItalic(), + }, + { label: 'H1', state: state?.h1, onPress: () => ref.current?.toggleH1() }, + { + label: 'Quote', + state: state?.blockQuote, + onPress: () => ref.current?.toggleBlockQuote(), + }, + ]; + + // Pull the current HTML off the editor and hand it to the viewer. + const render = async () => { + const value = await ref.current?.getHTML(); + if (value) setHtml(value); + }; + + return ( + + setState(e.nativeEvent)} + /> + + {buttons.map(button => ( + + + {button.label} + + + ))} + + + + + Render ↓ + + + + + {html} + + + ); +} + +const styles = StyleSheet.create({ + container: { gap: 12 }, + input: { + fontSize: 18, + color: '#232736', + padding: 12, + borderRadius: 12, + minHeight: 96, + backgroundColor: '#eef0ff', + }, + row: { + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'center', + gap: 8, + }, + button: { + width: 90, + padding: 8, + borderRadius: 24, + borderWidth: 1, + borderColor: '#919fcf', + }, + buttonActive: { + borderColor: '#57b495', + backgroundColor: '#57b495', + }, + buttonDisabled: { + opacity: 0.4, + }, + text: { + textAlign: 'center', + color: '#919fcf', + }, + textActive: { + color: '#eef0ff', + }, + viewer: { + fontSize: 18, + color: '#232736', + padding: 12, + borderRadius: 12, + minHeight: 64, + backgroundColor: '#eef0ff', + }, +}); diff --git a/docs/src/theme/CodeBlock/index.js b/docs/src/theme/CodeBlock/index.js new file mode 100644 index 000000000..cbda85cce --- /dev/null +++ b/docs/src/theme/CodeBlock/index.js @@ -0,0 +1,20 @@ +import React from 'react'; +import { MDXComponents as trexMDXComponents } from '@swmansion/t-rex-ui'; +import LiveCodeBlock from '@theme/LiveCodeBlock'; + +// t-rex-ui's own `code` component already picks between its branded +// CodeInline and CodeBlock - reuse it as-is so styling stays identical +// for everything that isn't a live code block. +const TrexCode = trexMDXComponents.code; + +function isLiveCodeBlock(props) { + return !!props.live; +} + +export default function CodeBlock(props) { + return isLiveCodeBlock(props) ? ( + + ) : ( + + ); +} diff --git a/docs/src/theme/MDXComponents.js b/docs/src/theme/MDXComponents.js index a0079bd2a..f0d74a9f5 100644 --- a/docs/src/theme/MDXComponents.js +++ b/docs/src/theme/MDXComponents.js @@ -1,4 +1,5 @@ import MDXComponents from '@theme-original/MDXComponents'; +import Code from '@theme/CodeBlock'; import Details from '@site/src/theme/MDXComponents/Details'; import CollapsibleCode from '@site/src/components/CollapsibleCode'; import InteractiveExample from '@site/src/components/InteractiveExample'; @@ -16,6 +17,7 @@ import { Badges } from '@swmansion/t-rex-ui'; export default { ...MDXComponents, + code: Code, details: Details, CollapsibleCode, InteractiveExample, diff --git a/docs/src/theme/ReactLiveScope/index.js b/docs/src/theme/ReactLiveScope/index.js new file mode 100644 index 000000000..12da40021 --- /dev/null +++ b/docs/src/theme/ReactLiveScope/index.js @@ -0,0 +1,14 @@ +import React from 'react'; +import { EnrichedTextInput } from 'react-native-enriched-html'; +import { StyleSheet } from 'react-native' + +// Exposed as globals inside every ```jsx live``` code block on the site +// (see https://docusaurus.io/docs/markdown-features/code-blocks#interactive-code-editor). +const ReactLiveScope = { + React, + ...React, + EnrichedTextInput, + StyleSheet +}; + +export default ReactLiveScope; diff --git a/docs/yarn.lock b/docs/yarn.lock index 3917b83a6..e4eac96c6 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -2631,6 +2631,26 @@ __metadata: languageName: node linkType: hard +"@docusaurus/theme-live-codeblock@npm:3.9.2": + version: 3.9.2 + resolution: "@docusaurus/theme-live-codeblock@npm:3.9.2" + dependencies: + "@docusaurus/core": "npm:3.9.2" + "@docusaurus/theme-common": "npm:3.9.2" + "@docusaurus/theme-translations": "npm:3.9.2" + "@docusaurus/utils-validation": "npm:3.9.2" + "@philpl/buble": "npm:^0.19.7" + clsx: "npm:^2.0.0" + fs-extra: "npm:^11.1.1" + react-live: "npm:^4.1.6" + tslib: "npm:^2.6.0" + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + checksum: 10c0/a50510e1ef18de7f9eda14e9a64b856956ab29b851399089ee8fb8eeb74e293f1abf6394f8c2b5998651dde9aecfb335b19d1bbc3748dd0b81edc5b7dd75c439 + languageName: node + linkType: hard + "@docusaurus/theme-mermaid@npm:3.9.2": version: 3.9.2 resolution: "@docusaurus/theme-mermaid@npm:3.9.2" @@ -2992,7 +3012,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": +"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": version: 0.3.13 resolution: "@jridgewell/gen-mapping@npm:0.3.13" dependencies: @@ -3680,6 +3700,25 @@ __metadata: languageName: node linkType: hard +"@philpl/buble@npm:^0.19.7": + version: 0.19.7 + resolution: "@philpl/buble@npm:0.19.7" + dependencies: + acorn: "npm:^6.1.1" + acorn-class-fields: "npm:^0.2.1" + acorn-dynamic-import: "npm:^4.0.0" + acorn-jsx: "npm:^5.0.1" + chalk: "npm:^2.4.2" + magic-string: "npm:^0.25.2" + minimist: "npm:^1.2.0" + os-homedir: "npm:^1.0.1" + regexpu-core: "npm:^4.5.4" + bin: + buble: ./bin/buble + checksum: 10c0/3347a4f5ae1bde6b9cd40e1e9d6f1b7e8defa1d7d1d148f0a0a87f1f4489d7c6826bd0c2334add1233bbf378eb6397d9d3b9269baeb66341df7773751483a8ef + languageName: node + linkType: hard + "@pnpm/config.env-replace@npm:^1.1.0": version: 1.1.0 resolution: "@pnpm/config.env-replace@npm:1.1.0" @@ -5070,6 +5109,24 @@ __metadata: languageName: node linkType: hard +"acorn-class-fields@npm:^0.2.1": + version: 0.2.1 + resolution: "acorn-class-fields@npm:0.2.1" + peerDependencies: + acorn: ^6.0.0 + checksum: 10c0/45f27a849178974e5b0fd727bbb63b5aa5498a58d9417b0bb3ad52979c66c94ec43b4de2c5a34f269b204bdad0cf47d55879a98f2171a8cc6bd3dde9c2a6f118 + languageName: node + linkType: hard + +"acorn-dynamic-import@npm:^4.0.0": + version: 4.0.0 + resolution: "acorn-dynamic-import@npm:4.0.0" + peerDependencies: + acorn: ^6.0.0 + checksum: 10c0/5450c917d28f39cabf64495928a711f446cb6a4731d45fcd8f160cc3ceb6fee3e1b4a8cb308b5ba4e9a0e450742f67d7295322033ffaa378a355af6cd2232693 + languageName: node + linkType: hard + "acorn-import-phases@npm:^1.0.3": version: 1.0.4 resolution: "acorn-import-phases@npm:1.0.4" @@ -5079,7 +5136,7 @@ __metadata: languageName: node linkType: hard -"acorn-jsx@npm:^5.0.0": +"acorn-jsx@npm:^5.0.0, acorn-jsx@npm:^5.0.1": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" peerDependencies: @@ -5097,6 +5154,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^6.1.1": + version: 6.4.2 + resolution: "acorn@npm:6.4.2" + bin: + acorn: bin/acorn + checksum: 10c0/52a72d5d785fa64a95880f2951021a38954f8f69a4944dfeab6fb1449b0f02293eae109a56d55b58ff31a90a00d16a804658a12db8ef834c20b3d1201fe5ba5b + languageName: node + linkType: hard + "acorn@npm:^8.0.0, acorn@npm:^8.0.4, acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.16.0": version: 8.17.0 resolution: "acorn@npm:8.17.0" @@ -5269,6 +5335,15 @@ __metadata: languageName: node linkType: hard +"ansi-styles@npm:^3.2.1": + version: 3.2.1 + resolution: "ansi-styles@npm:3.2.1" + dependencies: + color-convert: "npm:^1.9.0" + checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b + languageName: node + linkType: hard + "ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": version: 4.3.0 resolution: "ansi-styles@npm:4.3.0" @@ -5292,6 +5367,13 @@ __metadata: languageName: node linkType: hard +"any-promise@npm:^1.0.0": + version: 1.3.0 + resolution: "any-promise@npm:1.3.0" + checksum: 10c0/60f0298ed34c74fef50daab88e8dab786036ed5a7fad02e012ab57e376e0a0b4b29e83b95ea9b5e7d89df762f5f25119b83e00706ecaccb22cfbacee98d74889 + languageName: node + linkType: hard + "anymatch@npm:~3.1.2": version: 3.1.3 resolution: "anymatch@npm:3.1.3" @@ -5798,6 +5880,17 @@ __metadata: languageName: node linkType: hard +"chalk@npm:^2.4.2": + version: 2.4.2 + resolution: "chalk@npm:2.4.2" + dependencies: + ansi-styles: "npm:^3.2.1" + escape-string-regexp: "npm:^1.0.5" + supports-color: "npm:^5.3.0" + checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 + languageName: node + linkType: hard + "chalk@npm:^4.0.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" @@ -6025,6 +6118,15 @@ __metadata: languageName: node linkType: hard +"color-convert@npm:^1.9.0": + version: 1.9.3 + resolution: "color-convert@npm:1.9.3" + dependencies: + color-name: "npm:1.1.3" + checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -6034,6 +6136,13 @@ __metadata: languageName: node linkType: hard +"color-name@npm:1.1.3": + version: 1.1.3 + resolution: "color-name@npm:1.1.3" + checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6 + languageName: node + linkType: hard + "color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" @@ -6097,6 +6206,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^4.0.0": + version: 4.1.1 + resolution: "commander@npm:4.1.1" + checksum: 10c0/84a76c08fe6cc08c9c93f62ac573d2907d8e79138999312c92d4155bc2325d487d64d13f669b2000c9f8caf70493c1be2dac74fec3c51d5a04f8bc3ae1830bab + languageName: node + linkType: hard + "commander@npm:^5.1.0": version: 5.1.0 resolution: "commander@npm:5.1.0" @@ -7260,6 +7376,7 @@ __metadata: "@docusaurus/preset-classic": "npm:3.9.2" "@docusaurus/theme-classic": "npm:3.9.2" "@docusaurus/theme-common": "npm:3.9.2" + "@docusaurus/theme-live-codeblock": "npm:3.9.2" "@docusaurus/theme-mermaid": "npm:3.9.2" "@docusaurus/theme-search-algolia": "npm:3.9.2" "@docusaurus/tsconfig": "npm:3.9.2" @@ -8430,6 +8547,13 @@ __metadata: languageName: node linkType: hard +"has-flag@npm:^3.0.0": + version: 3.0.0 + resolution: "has-flag@npm:3.0.0" + checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 + languageName: node + linkType: hard + "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" @@ -9480,6 +9604,15 @@ __metadata: languageName: node linkType: hard +"jsesc@npm:~0.5.0": + version: 0.5.0 + resolution: "jsesc@npm:0.5.0" + bin: + jsesc: bin/jsesc + checksum: 10c0/f93792440ae1d80f091b65f8ceddf8e55c4bb7f1a09dee5dcbdb0db5612c55c0f6045625aa6b7e8edb2e0a4feabd80ee48616dbe2d37055573a84db3d24f96d9 + languageName: node + linkType: hard + "json-buffer@npm:3.0.1": version: 3.0.1 resolution: "json-buffer@npm:3.0.1" @@ -9747,6 +9880,15 @@ __metadata: languageName: node linkType: hard +"magic-string@npm:^0.25.2": + version: 0.25.9 + resolution: "magic-string@npm:0.25.9" + dependencies: + sourcemap-codec: "npm:^1.4.8" + checksum: 10c0/37f5e01a7e8b19a072091f0b45ff127cda676232d373ce2c551a162dd4053c575ec048b9cbb4587a1f03adb6c5d0fd0dd49e8ab070cd2c83a4992b2182d9cb56 + languageName: node + linkType: hard + "makeerror@npm:1.0.12": version: 1.0.12 resolution: "makeerror@npm:1.0.12" @@ -11075,6 +11217,17 @@ __metadata: languageName: node linkType: hard +"mz@npm:^2.7.0": + version: 2.7.0 + resolution: "mz@npm:2.7.0" + dependencies: + any-promise: "npm:^1.0.0" + object-assign: "npm:^4.0.1" + thenify-all: "npm:^1.0.0" + checksum: 10c0/103114e93f87362f0b56ab5b2e7245051ad0276b646e3902c98397d18bb8f4a77f2ea4a2c9d3ad516034ea3a56553b60d3f5f78220001ca4c404bd711bd0af39 + languageName: node + linkType: hard + "nanoid@npm:^3.3.12": version: 3.3.15 resolution: "nanoid@npm:3.3.15" @@ -11260,7 +11413,7 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": +"object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 @@ -11378,6 +11531,13 @@ __metadata: languageName: node linkType: hard +"os-homedir@npm:^1.0.1": + version: 1.0.2 + resolution: "os-homedir@npm:1.0.2" + checksum: 10c0/6be4aa67317ee247b8d46142e243fb4ef1d2d65d3067f54bfc5079257a2f4d4d76b2da78cba7af3cb3f56dbb2e4202e0c47f26171d11ca1ed4008d842c90363f + languageName: node + linkType: hard + "p-cancelable@npm:^3.0.0": version: 3.0.0 resolution: "p-cancelable@npm:3.0.0" @@ -11643,6 +11803,13 @@ __metadata: languageName: node linkType: hard +"pirates@npm:^4.0.1": + version: 4.0.7 + resolution: "pirates@npm:4.0.7" + checksum: 10c0/a51f108dd811beb779d58a76864bbd49e239fa40c7984cd11596c75a121a8cc789f1c8971d8bb15f0dbf9d48b76c05bb62fcbce840f89b688c0fa64b37e8478a + languageName: node + linkType: hard + "pkg-dir@npm:^7.0.0": version: 7.0.0 resolution: "pkg-dir@npm:7.0.0" @@ -12545,7 +12712,7 @@ __metadata: languageName: node linkType: hard -"prism-react-renderer@npm:^2.1.0, prism-react-renderer@npm:^2.3.0": +"prism-react-renderer@npm:^2.1.0, prism-react-renderer@npm:^2.3.0, prism-react-renderer@npm:^2.4.0": version: 2.4.1 resolution: "prism-react-renderer@npm:2.4.1" dependencies: @@ -12848,6 +13015,20 @@ __metadata: languageName: node linkType: hard +"react-live@npm:^4.1.6": + version: 4.1.8 + resolution: "react-live@npm:4.1.8" + dependencies: + prism-react-renderer: "npm:^2.4.0" + sucrase: "npm:^3.35.0" + use-editable: "npm:^2.3.3" + peerDependencies: + react: ">=18.0.0" + react-dom: ">=18.0.0" + checksum: 10c0/fa96ca176bc9074e4892d6a079b94488ba74e95907ea187678afb17e4a23cc7760c3774ef17f4429d2ba562f1fda852a822e18a161ef386676371c56a7585970 + languageName: node + linkType: hard + "react-loadable-ssr-addon-v5-slorber@npm:^1.0.1": version: 1.0.3 resolution: "react-loadable-ssr-addon-v5-slorber@npm:1.0.3" @@ -13119,6 +13300,15 @@ __metadata: languageName: node linkType: hard +"regenerate-unicode-properties@npm:^9.0.0": + version: 9.0.0 + resolution: "regenerate-unicode-properties@npm:9.0.0" + dependencies: + regenerate: "npm:^1.4.2" + checksum: 10c0/dc648891572f1d8326c01b335b126d766fe6684e5e760d4daa6c1d214d162b8c027fe0e6ee0a3e3d8d20bd869567f363f6be60bdfc054a14e7ad7d347891a506 + languageName: node + linkType: hard + "regenerate@npm:^1.4.2": version: 1.4.2 resolution: "regenerate@npm:1.4.2" @@ -13133,6 +13323,20 @@ __metadata: languageName: node linkType: hard +"regexpu-core@npm:^4.5.4": + version: 4.8.0 + resolution: "regexpu-core@npm:4.8.0" + dependencies: + regenerate: "npm:^1.4.2" + regenerate-unicode-properties: "npm:^9.0.0" + regjsgen: "npm:^0.5.2" + regjsparser: "npm:^0.7.0" + unicode-match-property-ecmascript: "npm:^2.0.0" + unicode-match-property-value-ecmascript: "npm:^2.0.0" + checksum: 10c0/cea09893ae49956ba11c3a7433295c61bfbaa92792f565fb54c463dfdd5a81a150ba67a22cd4ecded005425cbb78dc0ea34d5ff771f07f9d31931bafb189e367 + languageName: node + linkType: hard + "regexpu-core@npm:^6.3.1": version: 6.4.0 resolution: "regexpu-core@npm:6.4.0" @@ -13165,6 +13369,13 @@ __metadata: languageName: node linkType: hard +"regjsgen@npm:^0.5.2": + version: 0.5.2 + resolution: "regjsgen@npm:0.5.2" + checksum: 10c0/66cd5a9427a6db11a18eb544ecadf6866c8eeb3bf66d57185a9788929263b42641068df014d7e4d32a5cfbf114676f9bdd3013629203f03b1538416a1f4050e3 + languageName: node + linkType: hard + "regjsgen@npm:^0.8.0": version: 0.8.0 resolution: "regjsgen@npm:0.8.0" @@ -13183,6 +13394,17 @@ __metadata: languageName: node linkType: hard +"regjsparser@npm:^0.7.0": + version: 0.7.0 + resolution: "regjsparser@npm:0.7.0" + dependencies: + jsesc: "npm:~0.5.0" + bin: + regjsparser: bin/parser + checksum: 10c0/4b891ff0d2c835717d6e7ad9194da7f5271e410422fe51fa73b1f33978df8f6784e2a079938c9827f62fd13c258ae7e7e69f910799bb003b6a0b5e8854801719 + languageName: node + linkType: hard + "rehype-raw@npm:^7.0.0": version: 7.0.0 resolution: "rehype-raw@npm:7.0.0" @@ -13940,6 +14162,13 @@ __metadata: languageName: node linkType: hard +"sourcemap-codec@npm:^1.4.8": + version: 1.4.8 + resolution: "sourcemap-codec@npm:1.4.8" + checksum: 10c0/f099279fdaae070ff156df7414bbe39aad69cdd615454947ed3e19136bfdfcb4544952685ee73f56e17038f4578091e12b17b283ed8ac013882916594d95b9e6 + languageName: node + linkType: hard + "space-separated-tokens@npm:^2.0.0": version: 2.0.2 resolution: "space-separated-tokens@npm:2.0.2" @@ -14183,6 +14412,33 @@ __metadata: languageName: node linkType: hard +"sucrase@npm:^3.35.0": + version: 3.35.1 + resolution: "sucrase@npm:3.35.1" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.2" + commander: "npm:^4.0.0" + lines-and-columns: "npm:^1.1.6" + mz: "npm:^2.7.0" + pirates: "npm:^4.0.1" + tinyglobby: "npm:^0.2.11" + ts-interface-checker: "npm:^0.1.9" + bin: + sucrase: bin/sucrase + sucrase-node: bin/sucrase-node + checksum: 10c0/6fa22329c261371feb9560630d961ad0d0b9c87dce21ea74557c5f3ffbe5c1ee970ea8bcce9962ae9c90c3c47165ffa7dd41865c7414f5d8ea7a40755d612c5c + languageName: node + linkType: hard + +"supports-color@npm:^5.3.0": + version: 5.5.0 + resolution: "supports-color@npm:5.5.0" + dependencies: + has-flag: "npm:^3.0.0" + checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 + languageName: node + linkType: hard + "supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" @@ -14319,6 +14575,24 @@ __metadata: languageName: node linkType: hard +"thenify-all@npm:^1.0.0": + version: 1.6.0 + resolution: "thenify-all@npm:1.6.0" + dependencies: + thenify: "npm:>= 3.1.0 < 4" + checksum: 10c0/9b896a22735e8122754fe70f1d65f7ee691c1d70b1f116fda04fea103d0f9b356e3676cb789506e3909ae0486a79a476e4914b0f92472c2e093d206aed4b7d6b + languageName: node + linkType: hard + +"thenify@npm:>= 3.1.0 < 4": + version: 3.3.1 + resolution: "thenify@npm:3.3.1" + dependencies: + any-promise: "npm:^1.0.0" + checksum: 10c0/f375aeb2b05c100a456a30bc3ed07ef03a39cbdefe02e0403fb714b8c7e57eeaad1a2f5c4ecfb9ce554ce3db9c2b024eba144843cd9e344566d9fcee73b04767 + languageName: node + linkType: hard + "thingies@npm:^2.5.0": version: 2.6.0 resolution: "thingies@npm:2.6.0" @@ -14363,7 +14637,7 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15": +"tinyglobby@npm:^0.2.11, tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15": version: 0.2.17 resolution: "tinyglobby@npm:0.2.17" dependencies: @@ -14447,6 +14721,13 @@ __metadata: languageName: node linkType: hard +"ts-interface-checker@npm:^0.1.9": + version: 0.1.13 + resolution: "ts-interface-checker@npm:0.1.13" + checksum: 10c0/232509f1b84192d07b81d1e9b9677088e590ac1303436da1e92b296e9be8e31ea042e3e1fd3d29b1742ad2c959e95afe30f63117b8f1bc3a3850070a5142fea7 + languageName: node + linkType: hard + "tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" @@ -14564,7 +14845,7 @@ __metadata: languageName: node linkType: hard -"unicode-match-property-value-ecmascript@npm:^2.2.1": +"unicode-match-property-value-ecmascript@npm:^2.0.0, unicode-match-property-value-ecmascript@npm:^2.2.1": version: 2.2.1 resolution: "unicode-match-property-value-ecmascript@npm:2.2.1" checksum: 10c0/93acd1ad9496b600e5379d1aaca154cf551c5d6d4a0aefaf0984fc2e6288e99220adbeb82c935cde461457fb6af0264a1774b8dfd4d9a9e31548df3352a4194d @@ -14735,6 +15016,15 @@ __metadata: languageName: node linkType: hard +"use-editable@npm:^2.3.3": + version: 2.3.3 + resolution: "use-editable@npm:2.3.3" + peerDependencies: + react: ">= 16.8.0" + checksum: 10c0/6e8ae63ed0b9ad9a79d1f88992c6a594da0ad3dd1c67da7c12b73722b2a41f787c611dbe9e640f9cee5738168028219ca3c7b4cf739f096cee8069e82968a7b9 + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2"