/** * Shared keyboard-bar toolbar for any markdown body input (issue * description, comment, agent prompt). Linear-mobile range of buttons: * * @ · list · checkbox · code · quote · image · file * * All buttons map to **literal-character insertion** — no WYSIWYG. After * a button fires, the user sees the raw markdown they just inserted; the * read-only renderer (mobile hybrid markdown) shows the final visual. * * No bold / italic / heading: those are "style" tools that require live * styled-text rendering inside ``, which RN can't do without * swapping to `react-native-enriched`. See plan / research doc. * * Image / file props are optional so step 3 can ship the literal buttons * before step 4 wires the picker + upload pipeline. */ import { Pressable, View } from "react-native"; import { Ionicons } from "@expo/vector-icons"; import { Text } from "@/components/ui/text"; import { cn } from "@/lib/utils"; export interface MarkdownToolbarProps { /** Toolbar `@` button → hook.handlers.onAtButtonPress. */ onAt: () => void; /** Insert `- ` at the start of the current line. */ onList: () => void; /** Insert `- [ ] ` at the start of the current line. */ onCheckbox: () => void; /** Insert a fenced code block; caret lands in the empty middle line. */ onCode: () => void; /** Insert `> ` at the start of the current line. */ onQuote: () => void; /** Open image picker → upload → insert `![](url)`. Hidden when omitted. */ onImage?: () => void; /** Open document picker → upload → insert `[📎 name](url)`. Hidden when omitted. */ onFile?: () => void; /** Disable all buttons (during submit / upload-in-flight). */ disabled?: boolean; } const ICON_COLOR = "#71717a"; // muted-foreground export function MarkdownToolbar({ onAt, onList, onCheckbox, onCode, onQuote, onImage, onFile, disabled, }: MarkdownToolbarProps) { return ( @ {/* Ionicons has no good quote glyph — use the literal " character at * a slightly larger size for visual parity with adjacent icons. */} " {onImage ? ( ) : null} {onFile ? ( ) : null} ); } function ToolbarButton({ onPress, disabled, accessibilityLabel, children, }: { onPress: () => void; disabled?: boolean; accessibilityLabel: string; children: React.ReactNode; }) { return ( {children} ); }