/
githubmirror
/
gutenberg
Обзор
Документация
Войти
/
githubmirror
/
gutenberg
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
trunk
packages/format-library/src/math/index.js
190 строк
4 KB
Lena Morita
Components: Remove ValidatedTextControl private API (#80680)
11 авг 2026, 18:55
Не верифицирован
11 авг 2026, 18:55
5abfd41
Код
Авторство
О чём код?
import { __ } from '@wordpress/i18n'; import { useState, useEffect, useRef } from '@wordpress/element'; import { insert, insertObject, slice, getTextContent, useAnchor, } from '@wordpress/rich-text'; import { RichTextToolbarButton } from '@wordpress/block-editor'; import { Popover, privateApis as componentsPrivateApis, } from '@wordpress/components'; import { math as icon } from '@wordpress/icons'; import { unlock } from '../lock-unlock'; const { ValidatedInputControl } = unlock( componentsPrivateApis ); const name = 'core/math'; const title = __( 'Math' ); function InlineUI( { value, onChange, activeAttributes, contentRef, latexToMathML, } ) { const [ latex, setLatex ] = useState( activeAttributes?.[ 'data-latex' ] || '' ); const [ error, setError ] = useState( null ); const formRef = useRef(); const popoverAnchor = useAnchor( { editableContentElement: contentRef.current, settings: math, } ); // Update the math object in real-time as the user types const handleLatexChange = ( newLatex ) => { setLatex( newLatex ); let mathML = ''; if ( newLatex && latexToMathML ) { try { mathML = latexToMathML( newLatex, { displayMode: false } ); setError( null ); } catch ( err ) { setError( err.message ); } } else { setError( null ); } const newReplacements = value.replacements.slice(); newReplacements[ value.start ] = { type: name, attributes: { 'data-latex': newLatex, }, innerHTML: mathML, }; onChange( { ...value, replacements: newReplacements, } ); }; return ( <Popover placement="bottom-start" offset={ 8 } focusOnMount={ false } anchor={ popoverAnchor } // Surface any parsing error before focus leaves the popover. // An invalid field is refocused, keeping the popover open. onFocusOutside={ () => formRef.current?.reportValidity() } className="block-editor-format-toolbar__math-popover" > <form ref={ formRef } style={ { minWidth: '300px', padding: '4px' } } onSubmit={ ( event ) => event.preventDefault() } > <ValidatedInputControl hideLabelFromVision label={ __( 'LaTeX math syntax' ) } value={ latex } customValidity={ error ? { type: 'invalid', message: error } : undefined } onChange={ handleLatexChange } placeholder={ __( 'e.g., x^2, \\frac{a}{b}' ) } autoComplete="off" className="block-editor-format-toolbar__math-input" /> </form> </Popover> ); } function Edit( { value, onChange, onFocus, isObjectActive, activeObjectAttributes, contentRef, } ) { const [ latexToMathML, setLatexToMathML ] = useState(); useEffect( () => { import( '@wordpress/latex-to-mathml' ).then( ( module ) => { setLatexToMathML( () => module.default ); } ); }, [] ); function onClick() { let newValue; if ( isObjectActive ) { // Revert the active math object to its LaTeX source so clicking // the button toggles back to the exact text it was created from. // Keep the restored text selected so it can be edited or // re-marked right away. const latex = activeObjectAttributes?.[ 'data-latex' ] || ''; newValue = insert( value, latex ); newValue.start = newValue.end - latex.length; } else { // If there's a selection, seed the format with it so you can type // LaTeX inline and then mark it as math. const selectedText = getTextContent( slice( value ) ); let innerHTML = ''; if ( selectedText && latexToMathML ) { try { innerHTML = latexToMathML( selectedText, { displayMode: false, } ); } catch { // Leave unrendered; the popover opens with the text // prefilled so the expression can be corrected. } } newValue = insertObject( value, { type: name, attributes: { 'data-latex': selectedText }, innerHTML, } ); newValue.start = newValue.end - 1; } onChange( newValue ); onFocus(); } return ( <> <RichTextToolbarButton icon={ icon } title={ title } onClick={ onClick } isActive={ isObjectActive } /> { isObjectActive && ( <InlineUI value={ value } onChange={ onChange } activeAttributes={ activeObjectAttributes } contentRef={ contentRef } latexToMathML={ latexToMathML } /> ) } </> ); } export const math = { name, title, tagName: 'math', className: null, attributes: { 'data-latex': 'data-latex', }, contentEditable: false, edit: Edit, };