Exécution de commandes
3 min
jusqu’à présent, tout ce que nous avons appris portait sur la manière d’écrire une logique ponctuelle pour votre éditeur slate spécifique mais l’un des aspects les plus puissants de slate est qu’il vous permet de modéliser votre « domaine » de texte enrichi spécifique comme vous le souhaitez, et d’écrire moins de code ponctuel dans les guides précédents, nous avons écrit du code utile pour gérer le formatage de blocs de code et les marques de gras et nous avons connecté le gestionnaire onkeydown pour invoquer ce code mais nous l’avons toujours fait en utilisant directement les aides intégrées de éditeur au lieu d’utiliser des « commandes » slate vous permet d’augmenter l’objet éditeur intégré pour gérer vos propres commandes de texte enrichi personnalisées et vous pouvez même utiliser des « plugins » préemballés qui ajoutent un ensemble donné de fonctionnalités voyons comment cela fonctionne nous allons commencer avec notre application vue précédemment const initialvalue = \[ { type 'paragraph', children \[{ text 'a line of text in a paragraph ' }], }, ] const app = () => { const editor = usememo(() => withreact(createeditor()), \[]) const renderelement = usecallback(props => { switch (props element type) { case 'code' return \<codeelement { props} /> default return \<defaultelement { props} /> } }, \[]) const renderleaf = usecallback(props => { return \<leaf { props} /> }, \[]) return ( \<slate editor={editor} value={initialvalue}> \<editable renderelement={renderelement} renderleaf={renderleaf} onkeydown={event => { if (!event ctrlkey) { return } switch (event key) { case '`' { event preventdefault() const \[match] = editor nodes(editor, { match n => n type === 'code', }) transforms setnodes( editor, { type match ? null 'code' }, { match n => editor isblock(editor, n) } ) break } case 'b' { event preventdefault() transforms setnodes( editor, { bold true }, { match n => text istext(n), split true } ) break } } }} /> \</slate> ) } il contient le concept de « blocs de code » et de « formatage en gras » mais ces éléments sont tous définis dans des cas ponctuels à l’intérieur du gestionnaire onkeydown si vous vouliez réutiliser cette logique ailleurs, vous devriez l’extraire nous pouvons plutôt implémenter ces concepts spécifiques au domaine en créant des fonctions d’aide personnalisées // define our own custom set of helpers const customeditor = { isboldmarkactive(editor) { const \[match] = editor nodes(editor, { match n => n bold === true, universal true, }) return !!match }, iscodeblockactive(editor) { const \[match] = editor nodes(editor, { match n => n type === 'code', }) return !!match }, toggleboldmark(editor) { const isactive = customeditor isboldmarkactive(editor) transforms setnodes( editor, { bold isactive ? null true }, { match n => text istext(n), split true } ) }, togglecodeblock(editor) { const isactive = customeditor iscodeblockactive(editor) transforms setnodes( editor, { type isactive ? null 'code' }, { match n => editor isblock(editor, n) } ) }, } const initialvalue = \[ { type 'paragraph', children \[{ text 'a line of text in a paragraph ' }], }, ] const app = () => { const editor = usememo(() => withreact(createeditor()), \[]) const renderelement = usecallback(props => { switch (props element type) { case 'code' return \<codeelement { props} /> default return \<defaultelement { props} /> } }, \[]) const renderleaf = usecallback(props => { return \<leaf { props} /> }, \[]) return ( \<slate editor={editor} value={initialvalue}> \<editable renderelement={renderelement} renderleaf={renderleaf} onkeydown={event => { if (!event ctrlkey) { return } // replace the `onkeydown` logic with our new commands switch (event key) { case '`' { event preventdefault() customeditor togglecodeblock(editor) break } case 'b' { event preventdefault() customeditor toggleboldmark(editor) break } } }} /> \</slate> ) } désormais, nos commandes sont clairement définies et vous pouvez les invoquer depuis n’importe où nous avons accès à notre objet éditeur par exemple, depuis des boutons d’une barre d’outils hypothétique const initialvalue = \[ { type 'paragraph', children \[{ text 'a line of text in a paragraph ' }], }, ] const app = () => { const editor = usememo(() => withreact(createeditor()), \[]) const renderelement = usecallback(props => { switch (props element type) { case 'code' return \<codeelement { props} /> default return \<defaultelement { props} /> } }, \[]) const renderleaf = usecallback(props => { return \<leaf { props} /> }, \[]) return ( // add a toolbar with buttons that call the same methods \<slate editor={editor} value={initialvalue}> \<div> \<button onmousedown={event => { event preventdefault() customeditor toggleboldmark(editor) }} \> bold \</button> \<button onmousedown={event => { event preventdefault() customeditor togglecodeblock(editor) }} \> code block \</button> \</div> \<editable editor={editor} renderelement={renderelement} renderleaf={renderleaf} onkeydown={event => { if (!event ctrlkey) { return } switch (event key) { case '`' { event preventdefault() customeditor togglecodeblock(editor) break } case 'b' { event preventdefault() customeditor toggleboldmark(editor) break } } }} /> \</slate> ) } c’est l’avantage d’extraire la logique et voilà ! nous venons d’ajouter une tonne de fonctionnalités à l’éditeur avec très peu de travail et nous pouvons garder toute notre logique de commande testée et isolée dans un seul endroit, ce qui rend le code plus facile à maintenir