Files
m5wp.momentry.ddns.net/plugins/code-snippets/js/components/SnippetForm/fields/CodeEditor.tsx
OpenCode 09ef1f000f Initial commit: WordPress wp-content (themes, plugins, languages)
- Theme: momentry (custom theme with REST API routes)
- Plugins: code-snippets (contains all API proxies)
- Languages: zh_TW translations
- Excludes: cache, backups, uploads, logs
2026-05-29 19:07:56 +08:00

95 lines
3.0 KiB
TypeScript

import React, { useEffect, useRef } from 'react'
import { __ } from '@wordpress/i18n'
import { useSubmitSnippet } from '../../../hooks/useSubmitSnippet'
import { handleUnknownError } from '../../../utils/errors'
import { isMacOS } from '../../../utils/screen'
import { useSnippetForm } from '../../../hooks/useSnippetForm'
import { Button } from '../../common/Button'
import { ExpandIcon } from '../../common/icons/ExpandIcon'
import { MinimiseIcon } from '../../common/icons/MinimiseIcon'
import { CodeEditorShortcuts } from './CodeEditorShortcuts'
import type { Dispatch, RefObject, SetStateAction } from 'react'
interface EditorTextareaProps {
textareaRef: RefObject<HTMLTextAreaElement>
}
const EditorTextarea: React.FC<EditorTextareaProps> = ({ textareaRef }) => {
const { snippet, setSnippet } = useSnippetForm()
return (
<div className="snippet-editor">
<textarea
ref={textareaRef}
id="snippet-code"
name="snippet_code"
value={snippet.code}
rows={200}
spellCheck={false}
onChange={event => {
setSnippet(previous => ({ ...previous, code: event.target.value }))
}}
/>
<CodeEditorShortcuts editorTheme={window.CODE_SNIPPETS_EDIT?.editorTheme ?? 'default'} />
</div>
)
}
export interface CodeEditorProps {
isExpanded: boolean
setIsExpanded: Dispatch<SetStateAction<boolean>>
}
export const CodeEditor: React.FC<CodeEditorProps> = ({ isExpanded, setIsExpanded }) => {
const { snippet, setSnippet, codeEditorInstance, setCodeEditorInstance } = useSnippetForm()
const { submitSnippet } = useSubmitSnippet()
const textareaRef = useRef<HTMLTextAreaElement>(null)
useEffect(() => {
setCodeEditorInstance(editorInstance => {
if (textareaRef.current && !editorInstance) {
editorInstance = window.wp.codeEditor.initialize(textareaRef.current)
editorInstance.codemirror.on('changes', instance => {
setSnippet(previous => ({ ...previous, code: instance.getValue() }))
})
}
return editorInstance
})
}, [setCodeEditorInstance, textareaRef, setSnippet])
useEffect(() => {
if (codeEditorInstance) {
const extraKeys = codeEditorInstance.codemirror.getOption('extraKeys') ?? {}
const controlKey = isMacOS() ? 'Cmd' : 'Ctrl'
const onSave = () => {
submitSnippet()
.then(() => undefined)
.catch(handleUnknownError)
}
codeEditorInstance.codemirror.setOption('extraKeys', {
...'object' === typeof extraKeys ? extraKeys : undefined,
[`${controlKey}-S`]: onSave,
[`${controlKey}-Enter`]: onSave
})
}
}, [submitSnippet, codeEditorInstance, snippet])
return (
<div className="snippet-code-container">
<div className="above-snippet-code">
<h2><label htmlFor="snippet-code">{__('Snippet Content', 'code-snippets')}</label></h2>
<Button small className="expand-editor-button" onClick={() => setIsExpanded(current => !current)}>
{isExpanded ? <MinimiseIcon /> : <ExpandIcon />}
{isExpanded ? __('Minimize', 'code-snippets') : __('Expand', 'code-snippets')}
</Button>
</div>
<EditorTextarea textareaRef={textareaRef} />
</div>
)
}