1export type ToolbarExec = (cmd: string, val?: string) => void;23const BoldIcon = () => (4 <svg viewBox="0 0 14 14" aria-hidden="true">5 <path d="M4 2h3.75a2.5 2.5 0 0 1 0 5H4V2Zm0 5h4.25a2.5 2.5 0 0 1 0 5H4V7Z" />6 </svg>7);89const ItalicIcon = () => (10 <svg viewBox="0 0 14 14" aria-hidden="true">11 <path d="M6 2h5M3 12h5M8.5 2l-3 10" />12 </svg>13);1415const UnderlineIcon = () => (16 <svg viewBox="0 0 14 14" aria-hidden="true">17 <path d="M3.5 2v4.25a3.5 3.5 0 0 0 7 0V2M2.5 12h9" />18 </svg>19);2021const StrikeIcon = () => (22 <svg viewBox="0 0 14 14" aria-hidden="true">23 <path d="M10.5 3.25C9.75 2.4 8.65 2 7.2 2 5.35 2 4 2.8 4 4.2c0 1.2.95 1.75 2.55 2.15M3.5 10.5c.85 1 2.1 1.5 3.75 1.5 1.9 0 3.25-.8 3.25-2.2 0-1.15-.9-1.75-2.45-2.15M2 7h10" />24 </svg>25);2627const HeadingIcon = () => (28 <svg viewBox="0 0 14 14" aria-hidden="true">29 <path d="M2 2.5v9M8 2.5v9M2 7h6M10 9.25c.25-.6.7-.9 1.35-.9.8 0 1.3.45 1.3 1.1 0 .55-.35.95-1.2 1.55L10.2 12h2.65" />30 </svg>31);3233const QuoteIcon = () => (34 <svg viewBox="0 0 14 14" aria-hidden="true">35 <path d="M2.25 4.25h3v3h-2c0 1.4.55 2.45 1.65 3.15M8.25 4.25h3v3h-2c0 1.4.55 2.45 1.65 3.15" />36 </svg>37);3839const BulletIcon = () => (40 <svg viewBox="0 0 14 14" aria-hidden="true">41 <path d="M5 3h7M5 7h7M5 11h7" />42 <circle cx="2" cy="3" r=".75" />43 <circle cx="2" cy="7" r=".75" />44 <circle cx="2" cy="11" r=".75" />45 </svg>46);4748const NumberedIcon = () => (49 <svg viewBox="0 0 14 14" aria-hidden="true">50 <path d="M5 3h7M5 7h7M5 11h7M1.25 2.25h.8V4M1.2 6.15c.2-.35.5-.55.95-.55.55 0 .9.3.9.75 0 .4-.25.65-.8 1.05l-1 .7h1.9M1.2 10.15c.25-.3.55-.45.95-.45.55 0 .9.25.9.65 0 .35-.25.6-.7.65.5.05.8.3.8.7 0 .45-.4.75-1 .75-.45 0-.8-.15-1.05-.45" />51 </svg>52);5354const RuleIcon = () => (55 <svg viewBox="0 0 14 14" aria-hidden="true">56 <path d="M1.5 7h11" />57 </svg>58);5960function applyBold(exec: ToolbarExec) { exec("bold"); }61function applyItalic(exec: ToolbarExec) { exec("italic"); }62function applyUnderline(exec: ToolbarExec) { exec("underline"); }63function applyStrike(exec: ToolbarExec) { exec("strikeThrough"); }64function applyHeading(exec: ToolbarExec) {65 const val = document.queryCommandValue("formatBlock").toLowerCase();66 exec("formatBlock", val === "h2" ? "p" : "h2");67}68function applyQuote(exec: ToolbarExec) {69 const val = document.queryCommandValue("formatBlock").toLowerCase();70 exec("formatBlock", val === "blockquote" ? "p" : "blockquote");71}72function applyBullet(exec: ToolbarExec) { exec("insertUnorderedList"); }73function applyNumbered(exec: ToolbarExec) { exec("insertOrderedList"); }74function applyRule(exec: ToolbarExec) { exec("insertHorizontalRule"); }7576interface ToolbarProps {77 exec: ToolbarExec;78 class?: string;79}8081export function NoteToolbar(props: ToolbarProps) {82 return (83 <div class={props.class ?? "peach-note-toolbar-desktop-inline"}>84 <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyBold(props.exec); }} title="Bold" aria-label="Bold"><BoldIcon /></button>85 <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyItalic(props.exec); }} title="Italic" aria-label="Italic"><ItalicIcon /></button>86 <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyUnderline(props.exec); }} title="Underline" aria-label="Underline"><UnderlineIcon /></button>87 <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyStrike(props.exec); }} title="Strikethrough" aria-label="Strikethrough"><StrikeIcon /></button>88 <div class="peach-note-toolbar-divider" />89 <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyHeading(props.exec); }} title="Heading" aria-label="Heading"><HeadingIcon /></button>90 <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyQuote(props.exec); }} title="Quote" aria-label="Quote"><QuoteIcon /></button>91 <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyBullet(props.exec); }} title="Bullet list" aria-label="Bullet list"><BulletIcon /></button>92 <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyNumbered(props.exec); }} title="Numbered list" aria-label="Numbered list"><NumberedIcon /></button>93 <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyRule(props.exec); }} title="Divider" aria-label="Divider"><RuleIcon /></button>94 </div>95 );96}