NoteToolbar.tsx

3.7 KB · raw

1import { Show } from "solid-js";2import { isNativePlatform } from "../../shared/native";34export type ToolbarExec = (cmd: string, val?: string) => void;56function applyBold(exec: ToolbarExec) { exec("bold"); }7function applyItalic(exec: ToolbarExec) { exec("italic"); }8function applyUnderline(exec: ToolbarExec) { exec("underline"); }9function applyHeading(exec: ToolbarExec) {10  const val = document.queryCommandValue("formatBlock").toLowerCase();11  exec("formatBlock", val === "h2" ? "p" : "h2");12}13function applyQuote(exec: ToolbarExec) {14  const val = document.queryCommandValue("formatBlock").toLowerCase();15  exec("formatBlock", val === "blockquote" ? "p" : "blockquote");16}17function applyBullet(exec: ToolbarExec) { exec("insertUnorderedList"); }18function applyNumbered(exec: ToolbarExec) { exec("insertOrderedList"); }1920interface ToolbarProps {21  exec: ToolbarExec;22  keyboardVisible?: boolean;23  onDismissKeyboard?: () => void;24  class?: string;25}2627export function NoteToolbar(props: ToolbarProps) {28  return (29    <Show30      when={isNativePlatform()}31      fallback={32        // Desktop: toolbar rendered inline above the body, shown always33        <div class={props.class ?? "peach-note-toolbar-desktop-inline"}>34          <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyBold(props.exec); }} title="Bold">B</button>35          <button class="peach-note-toolbar-btn peach-note-toolbar-btn--italic" onMouseDown={(e) => { e.preventDefault(); applyItalic(props.exec); }} title="Italic">I</button>36          <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyUnderline(props.exec); }} title="Underline">U</button>37          <div class="peach-note-toolbar-divider" />38          <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyHeading(props.exec); }} title="Heading">H</button>39          <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyQuote(props.exec); }} title="Quote">"</button>40          <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyBullet(props.exec); }} title="Bullet">•</button>41          <button class="peach-note-toolbar-btn" onMouseDown={(e) => { e.preventDefault(); applyNumbered(props.exec); }} title="Numbered">1.</button>42        </div>43      }44    >45      {/* Mobile: sits above keyboard when keyboard is visible */}46      <Show when={props.keyboardVisible}>47        <div class={props.class ?? "peach-note-toolbar-mobile"}>48          <button class="peach-note-toolbar-btn" onPointerDown={(e) => { e.preventDefault(); applyBold(props.exec); }}>B</button>49          <button class="peach-note-toolbar-btn peach-note-toolbar-btn--italic" onPointerDown={(e) => { e.preventDefault(); applyItalic(props.exec); }}>I</button>50          <button class="peach-note-toolbar-btn" onPointerDown={(e) => { e.preventDefault(); applyUnderline(props.exec); }}>U</button>51          <div class="peach-note-toolbar-divider" />52          <button class="peach-note-toolbar-btn" onPointerDown={(e) => { e.preventDefault(); applyHeading(props.exec); }}>H</button>53          <button class="peach-note-toolbar-btn" onPointerDown={(e) => { e.preventDefault(); applyQuote(props.exec); }}>"</button>54          <button class="peach-note-toolbar-btn" onPointerDown={(e) => { e.preventDefault(); applyBullet(props.exec); }}>•</button>55          <button class="peach-note-toolbar-btn" onPointerDown={(e) => { e.preventDefault(); applyNumbered(props.exec); }}>1.</button>56          <div class="peach-note-toolbar-spacer" />57          <button class="peach-note-toolbar-btn" onPointerDown={(e) => { e.preventDefault(); props.onDismissKeyboard?.(); }}>⌨</button>58        </div>59      </Show>60    </Show>61  );62}