diff --git a/src/components/RichTextEditor.tsx b/src/components/RichTextEditor.tsx index 1ab257f9..146125cd 100644 --- a/src/components/RichTextEditor.tsx +++ b/src/components/RichTextEditor.tsx @@ -3,10 +3,7 @@ import { StyleSheet, View, Platform } from 'react-native'; import { WebView, type WebViewMessageEvent } from 'react-native-webview'; import { useColors } from '../theme/colors'; import type { ThemePalette } from '../theme/tokens'; - -// Minimum visible editor height (px). The editor auto-grows beyond this as the -// user types, and the parent ScrollView handles overflow. -const MIN_HEIGHT = 220; +import { buildEditorHtml, MIN_EDITOR_HEIGHT } from '../lib/editor-html'; export type RichTextCommand = | 'bold' @@ -66,273 +63,6 @@ interface Props { onBlur?: () => void; } -function buildEditorHtml(opts: { - initialHtml: string; - placeholder: string; - c: ThemePalette; -}): string { - const { initialHtml, placeholder, c } = opts; - // Inject initial content as a JSON-encoded string so any HTML/quotes inside - // are safely embedded (no template literal collision with the script body). - const initialJson = JSON.stringify(initialHtml); - const placeholderJson = JSON.stringify(placeholder); - - return ` - - - - - - - -
- - -`; -} - const RichTextEditor = React.forwardRef(function RichTextEditor( { initialHtml = '', placeholder = '', onChange, onSelectionChange, onFocus, onBlur }, ref, @@ -340,7 +70,7 @@ const RichTextEditor = React.forwardRef(function Ri const c = useColors(); const styles = React.useMemo(() => makeStyles(c), [c]); const webViewRef = React.useRef(null); - const [height, setHeight] = React.useState(MIN_HEIGHT); + const [height, setHeight] = React.useState(MIN_EDITOR_HEIGHT); const onChangeRef = React.useRef(onChange); const onSelectionRef = React.useRef(onSelectionChange); const onFocusRef = React.useRef(onFocus); @@ -400,7 +130,7 @@ const RichTextEditor = React.forwardRef(function Ri break; case 'height': { const h = typeof data.payload === 'number' ? data.payload : Number(data.payload); - if (!Number.isNaN(h) && h > 0) setHeight(Math.max(MIN_HEIGHT, h)); + if (!Number.isNaN(h) && h > 0) setHeight(Math.max(MIN_EDITOR_HEIGHT, h)); break; } case 'selection': diff --git a/src/lib/__tests__/editor-html.test.ts b/src/lib/__tests__/editor-html.test.ts new file mode 100644 index 00000000..b69f1808 --- /dev/null +++ b/src/lib/__tests__/editor-html.test.ts @@ -0,0 +1,50 @@ +import { describe, expect, it } from 'vitest'; +import { buildEditorHtml } from '../editor-html'; +import { LIGHT_COLORS, DARK_COLORS } from '../../theme/tokens'; + +function extractScript(html: string): string { + const m = html.match(/ + +`; +}