EvoX Genesis
EvoX Genesis turns a high-level software objective into a persistent recursive software world: finite-lived agents recursively develop software, while only accepted consequences persist across develop
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Rich Text Editor for Websites
翻譯準備中
正在載入完整 README。
檢視完整 README ↗Lightweight rich text editor for React applications.
Beta (
0.5.0-beta.1) — the API may change before 1.0; see Known limitations.
versaedit.dev · Playground · Leia em português · Leer en español
VersaEdit edits HTML with the browser's own contentEditable, adds a toolbar, a sanitizer
(DOMPurify), its own undo/redo, cleanup of content pasted from web pages and Word, images, text boxes, tables,
dictation and file save/open. It has no backend dependency: it gives you HTML and you store it
wherever you want (Supabase, Firebase, REST…).
moduleResolution: node16/nodenextlocale), every text replaceable (labels)npm install versaedit@beta
import { useRef } from 'react'
import { VersaEdit, type VersaEditHandle } from 'versaedit'
export function PostEditor({
initialHtml,
onSave,
}: {
initialHtml: string
onSave: (html: string) => void
}) {
const editor = useRef<VersaEditHandle>(null)
return (
<>
<VersaEdit
ref={editor}
initialContent={initialHtml}
onChange={(html) => console.log('changed', html.length)}
width="100%"
height={480}
locale="en"
/>
<button onClick={() => onSave(editor.current!.getHTML())}>Save</button>
</>
)
}
initialContent is loaded (and sanitized) when it changes; the editor ignores the echo of its own
onChange, so you can use it as a controlled value.
| Prop | Type | Default | Description |
|---|---|---|---|
initialContent | string | '' | HTML to load. External changes reload the editor (and reset undo). |
onChange | (html) => void | — | Called when the HTML actually changes. |
onOverflowChange | (boolean) => void | — | Content does / doesn't fit the editor height. |
onFocus / onBlur | () => void | — | Focus entered / left the editor (toolbar buttons keep focus). |
onError | (VersaEditError) => void | alert() | Errors and warnings with a stable code (see below). |
onConfirm | (VersaEditConfirm) => boolean | Promise<boolean> | confirm() | Confirmations (e.g. replace content when opening a file). |
onSave | (html) => void | download | Save button gives you the HTML instead of downloading a .html file. |
onImageUpload | (file) => Promise<url> | base64 | Upload images and insert the returned URL (recommended). |
width | number | string | 640 | Total width; a number is px, a string is CSS ('100%'). |
height | number | 480 | Total height in px. |
toolbarWidth | number | string | width | Toolbar width (numbers center it over the editor). |
frame | { width, color, radius } | false | 1px #d0d7de, 8px | Border around the editing area. |
accentColor |
Toolbar groups (TOOLBAR_GROUPS, always shown in this order): dictation, file, history,
font, block, format, highlight, color, align, list, indent, link, insert,
textbox, clear. Without format, Ctrl+B/I/U don't format; without link, Ctrl+K doesn't open
the link form. Undo/redo shortcuts always work.
Error codes (VersaEditError.code): file-wrong-type, file-too-large, file-read,
file-empty, file-truncated (level warning), image-upload (with the original error in cause).
VersaEditHandle)getHTML() · setHTML(html) (resets undo) · focus() · clear() · undo() · redo() ·
core (the underlying VersaEditCore, experimental).
The editor injects its CSS by default. For sites with a strict Content Security Policy, turn injection off and import the file:
import 'versaedit/versaedit.css'
;<VersaEdit injectStyles={false} />
To display saved content on your site, wrap it and include the content stylesheet (image positions, text boxes with their drag handle hidden, tables, code, quotes):
import 'versaedit/versaedit-content.css'
;<div className="versaedit-content" dangerouslySetInnerHTML={{ __html: sanitizedHtml }} />
Formatting such as colors and font sizes is stored in inline style attributes; a CSP that blocks
inline style attributes (style-src-attr) will not render it.
examples/vite-react: one tab per use case (basic, integration callbacks,
customized toolbar, strict CSP, display, external dictation).examples/nextjs: Next.js 16 App Router with server rendering.npm run dev): open Show HTML → Properties to change props live, load sample
content, watch events and copy the equivalent JSX.Both examples run against the packed package (npm pack), installed outside the repository, in CI.
A microphone button converts speech to text using the browser's Web Speech API (Chrome, Edge,
Safari; hidden in Firefox), in the interface language (en-US, pt-BR or es-ES; speechLang
changes it). Spoken punctuation works ("comma", "period", "new line"…; in pt-BR "vírgula", "ponto
final", "nova linha"…; in Spanish "coma", "punto final", "nueva línea"…; Spanish gets only the
closing ? and !, not ¿ and ¡). Privacy: these browsers process the audio on the
vendor's servers (Google, Microsoft, Apple). Pass speechRecognition to use another engine with the
same interface, or showDictation={false} to remove it. VersaEditDictation renders the microphone
anywhere on the page (<VersaEditDictation editor={ref} />).
Report vulnerabilities privately — see SECURITY.md ([email protected]).
javascript: links and SVG are removed. A battery of 42
XSS vectors runs in CI.pasteImages (default true): pasted images keep pointing to the original site — readers'
browsers will request them from there, and that site may change or remove them. Use
onImageUpload, or pasteImages={false}.allowExternalMedia),
and the HTML you get back is unchanged.| Keys | Action |
|---|---|
| Ctrl+B / I / U | Bold / italic / underline |
| Ctrl+Z, Ctrl+Y (Ctrl+Shift+Z) | Undo, redo |
| Ctrl+K | Link form (Enter applies, Esc cancels) |
| Tab | Insert spaces |
| Delete / Backspace | Delete the selected image |
| Ctrl+arrows (Shift: 10px) | Nudge the selected image or text box |
| Alt+↑/↓, Alt+←/→ | Move it in the text flow / float it left or right |
| ←/→, Home/End, Esc (toolbar) | Move between toolbar controls, close palettes |
Automated tests run on every push in Chromium (Chrome/Edge). Firefox and WebKit (Safari) are run as a
diagnostic (VE_ALL_BROWSERS=1 npx playwright test --project=firefox --project=webkit):
| Browser | Status |
|---|---|
| Chrome, Edge | Full suite passing. |
| Firefox | Works; HTML differs in details (e.g. images inserted inside the paragraph). Paste is not covered by automated tests in Firefox. |
| Safari (WebKit) | Works; lists get extra <span style="font-size"> wrappers; other differences are cosmetic. |
document.execCommand (legacy but supported by all browsers); output HTML varies slightly
between browsers.<span style="font-weight: bold">
instead of <b> (works the same).npm install
npm run dev # playground at http://localhost:5180
npm run build # library build (dist/)
npm run lint
npm run typecheck
npm test # unit tests (Vitest) + browser tests (Playwright)
npm run test:package # npm pack → install in examples/ copies → type check, build, browser tests
npm run test:site # public site (versaedit.dev + /playground/) built into site/ and tested
Browser tests use playground/harness.html. Locally they run in the installed Microsoft Edge; in CI,
in Playwright's Chromium (with React 19 and React 18). Reference results live in
tests/e2e/__snapshots__/ — after an intentional behavior change, run
npm run test:e2e -- --update-snapshots and review the diff.
string#2563eb |
| Selection outlines, text boxes, handles. |
fontFamily / headingFontFamily | string | system font | Text and heading fonts. |
fontFamilies / fontSizes | arrays | defaults | Font menu ({ label, value }) and sizes (pt). |
colorPalette / highlightColors | string[] | defaults | Text/paper colors and highlighter colors ('transparent' = none). |
loadGoogleFonts | string[] | — | Families to load from Google Fonts (off by default). |
toolbar | ToolbarGroup[] | all | Toolbar groups to show (see below). [] hides the toolbar. |
showFileButtons | boolean | true | Save/Open file buttons. |
showDictation / speechLang / speechRecognition | — | true / locale / browser | Dictation (see below). |
pasteImages | boolean | true | Keep images when pasting (see Security). |
allowExternalMedia | boolean | false | Let <audio>/<video> in loaded content load inside the editor. |
scrollable | boolean | true | The editing area scrolls when content is taller. false: extra content is hidden, like a fixed-height block. |
truncateOnOverflow | boolean | false | Cut content that exceeds the editor height. |
singleLineBreaks | boolean | false | Paste: collapse consecutive blank lines. |
injectStyles | boolean | true | Inject the editor CSS; set false and import the CSS file instead. |
locale / labels | 'en' | 'pt-BR' | 'es' / partial | 'en' | Interface language and text overrides. |
contentClassName / contentStyle / placeholder | — | — | Editing area class, style and placeholder. |