import React from 'react';
import type { CodeEditorHandle } from '../../../ui/CodeEditor';
/**
* Snippet buttons for the Edit HTML modal. `caret` is the offset from the
* start of the inserted text where the caret should land -- i.e. between the
* open and close tags, so the next keystroke types content rather than
* landing after the closing tag.
*/
export const SNIPPETS: { label: string; icon: string; title: string; text: string; caret: number }[] = [
{ label: 'div', icon: 'fa-square-o', title: 'Insert a div', text: '
', caret: 5 },
{ label: 'section', icon: 'fa-window-maximize', title: 'Insert a section', text: '', caret: 9 },
{ label: 'h2', icon: 'fa-header', title: 'Insert a heading', text: ' ', caret: 4 },
{ label: 'p', icon: 'fa-paragraph', title: 'Insert a paragraph', text: '
', caret: 3 },
{ label: 'a', icon: 'fa-link', title: 'Insert a link', text: ' ', caret: 12 },
{ label: 'ul', icon: 'fa-list-ul', title: 'Insert a list', text: '', caret: 11 },
{ label: 'img', icon: 'fa-image', title: 'Insert an image', text: ' ', caret: 10 },
];
const btnStyle: React.CSSProperties = {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
minWidth: 28, height: 28, padding: '0 7px',
background: '#27272a', color: '#e4e4e7',
border: '1px solid #3f3f46', borderRadius: 5,
fontSize: 11, cursor: 'pointer',
};
export const HtmlToolbar: React.FC<{
editorRef: React.RefObject;
onFormat: () => void;
}> = ({ editorRef, onFormat }) => {
const insert = (text: string, caret?: number): void => {
// The ref is null until CodeEditor mounts; clicking early must no-op.
// Only forward a second argument when a caret offset was actually
// given -- `insertAtCursor(text, undefined)` is a distinct call from
// `insertAtCursor(text)` (an explicit undefined still occupies the
// argument list), and the colour control relies on the latter so the
// caret lands at the end of the inserted attribute, not mid-string.
if (caret === undefined) {
editorRef.current?.insertAtCursor(text);
} else {
editorRef.current?.insertAtCursor(text, caret);
}
};
return (
{SNIPPETS.map((s) => (
insert(s.text, s.caret)}
>
))}
insert(` style="color: ${(e.target as HTMLInputElement).value}"`)}
style={{ width: 40, height: 34, border: 'none', background: 'none', cursor: 'pointer', padding: 0 }}
/>
Format
);
};