Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
1aae1b8
feat: Add Table of Contents sidebar with sticky action buttons
thoroc Jan 30, 2026
7137cfa
fix: Correct typo in opencode.json (CALUDE -> CLAUDE)
thoroc Jan 30, 2026
6abf1d6
docs: Update testing documentation - separate UI tests from integrati…
thoroc Jan 30, 2026
298d9c7
fix(ui): prevent code block annotation from breaking syntax highlighting
thoroc Feb 5, 2026
1a3316f
test(ui): add comprehensive code block annotation regression tests
thoroc Feb 5, 2026
17cefa1
feat: update opencode.json to include additional documentation instru…
thoroc Feb 5, 2026
f096478
chore: stop tracking docs directory and opencode.json
thoroc Feb 5, 2026
a1df790
chore: move UI-TESTING.md to tests directory
thoroc Feb 5, 2026
7015ba4
docs: extract UI testing checklist into separate file
thoroc Feb 5, 2026
8933ef2
docs: update UI testing documentation
thoroc Feb 5, 2026
dc497ba
fix(ui): fix TOC active section tracking
backnotprop Feb 8, 2026
5cf22c5
revert: remove Playwright MCP from marketplace.json and stale README …
backnotprop Feb 8, 2026
5ed11db
style(ui): compact TOC styling and fix layout shifts
backnotprop Feb 8, 2026
9f6e0ce
feat(ui): add optional TOC and sticky actions settings
backnotprop Feb 8, 2026
7714551
refactor(ui): redesign Settings dialog with sidebar navigation
backnotprop Feb 8, 2026
746ee01
fix(ui): fix sticky action bar positioning and add scroll-aware card …
backnotprop Feb 8, 2026
79ac321
merge: resolve conflict with main (keep editorMode persistence + uiPr…
backnotprop Feb 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,8 @@
},
"dependencies": {
"@pierre/diffs": "^1.0.4"
},
"devDependencies": {
"happy-dom": "^20.5.0"
}
}
32 changes: 29 additions & 3 deletions packages/editor/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ import { ModeSwitcher } from '@plannotator/ui/components/ModeSwitcher';
import { TaterSpriteRunning } from '@plannotator/ui/components/TaterSpriteRunning';
import { TaterSpritePullup } from '@plannotator/ui/components/TaterSpritePullup';
import { Settings } from '@plannotator/ui/components/Settings';
import { TableOfContents } from '@plannotator/ui/components/TableOfContents';
import { useSharing } from '@plannotator/ui/hooks/useSharing';
import { useAgents } from '@plannotator/ui/hooks/useAgents';
import { useActiveSection } from '@plannotator/ui/hooks/useActiveSection';
import { storage } from '@plannotator/ui/utils/storage';
import { UpdateBanner } from '@plannotator/ui/components/UpdateBanner';
import { getObsidianSettings, getEffectiveVaultPath, CUSTOM_PATH_SENTINEL } from '@plannotator/ui/utils/obsidian';
import { getBearSettings } from '@plannotator/ui/utils/bear';
import { getAgentSwitchSettings, getEffectiveAgentName } from '@plannotator/ui/utils/agentSwitch';
import { getPlanSaveSettings } from '@plannotator/ui/utils/planSave';
import { getUIPreferences, type UIPreferences } from '@plannotator/ui/utils/uiPreferences';
import { getEditorMode, saveEditorMode } from '@plannotator/ui/utils/editorMode';
import {
getPermissionModeSettings,
Expand Down Expand Up @@ -338,6 +341,7 @@ const App: React.FC = () => {
const stored = storage.getItem('plannotator-tater-mode');
return stored === 'true';
});
const [uiPrefs, setUiPrefs] = useState(() => getUIPreferences());
const [isApiMode, setIsApiMode] = useState(false);
const [origin, setOrigin] = useState<'claude-code' | 'opencode' | null>(null);
const [globalAttachments, setGlobalAttachments] = useState<string[]>([]);
Expand All @@ -350,6 +354,11 @@ const App: React.FC = () => {
const [sharingEnabled, setSharingEnabled] = useState(true);
const [repoInfo, setRepoInfo] = useState<{ display: string; branch?: string } | null>(null);
const viewerRef = useRef<ViewerHandle>(null);
const containerRef = useRef<HTMLElement>(null);

// Track active section for TOC highlighting
const headingCount = useMemo(() => blocks.filter(b => b.type === 'heading').length, [blocks]);
const activeSection = useActiveSection(containerRef, headingCount);

// URL-based sharing
const {
Expand Down Expand Up @@ -657,6 +666,11 @@ const App: React.FC = () => {
setGlobalAttachments(prev => prev.filter(p => p !== path));
};

const handleTocNavigate = (blockId: string) => {
// Navigation handled by TableOfContents component
// This is just a placeholder for future custom logic
};

const diffOutput = useMemo(() => exportDiff(blocks, annotations, globalAttachments), [blocks, annotations, globalAttachments]);

const agentName = useMemo(() => {
Expand All @@ -671,7 +685,7 @@ const App: React.FC = () => {
{/* Tater sprites */}
{taterMode && <TaterSpriteRunning />}
{/* Minimal Header */}
<header className="h-12 flex items-center justify-between px-2 md:px-4 border-b border-border/50 bg-card/50 backdrop-blur-xl z-50">
<header className="h-12 flex items-center justify-between px-2 md:px-4 border-b border-border/50 bg-card/50 backdrop-blur-xl sticky top-0 z-20">
<div className="flex items-center gap-2 md:gap-3">
<a
href="https://plannotator.ai"
Expand Down Expand Up @@ -772,7 +786,7 @@ const App: React.FC = () => {
)}

<ModeToggle />
<Settings taterMode={taterMode} onTaterModeChange={handleTaterModeChange} onIdentityChange={handleIdentityChange} origin={origin} />
<Settings taterMode={taterMode} onTaterModeChange={handleTaterModeChange} onIdentityChange={handleIdentityChange} origin={origin} onUIPreferencesChange={setUiPrefs} />

<button
onClick={() => setIsPanelOpen(!isPanelOpen)}
Expand Down Expand Up @@ -802,8 +816,19 @@ const App: React.FC = () => {

{/* Main Content */}
<div className="flex-1 flex overflow-hidden">
{/* Table of Contents */}
{uiPrefs.tocEnabled && (
<TableOfContents
blocks={blocks}
annotations={annotations}
activeId={activeSection}
onNavigate={handleTocNavigate}
className="hidden lg:block w-60 sticky top-12 h-[calc(100vh-3rem)] flex-shrink-0"
/>
)}

{/* Document Area */}
<main className="flex-1 overflow-y-auto bg-grid">
<main ref={containerRef} className="flex-1 overflow-y-auto bg-grid">
<div className="min-h-full flex flex-col items-center px-4 py-3 md:px-10 md:py-8 xl:px-16">
{/* Mode Switcher */}
<div className="w-full max-w-[832px] 2xl:max-w-5xl mb-3 md:mb-4 flex justify-start">
Expand All @@ -825,6 +850,7 @@ const App: React.FC = () => {
onAddGlobalAttachment={handleAddGlobalAttachment}
onRemoveGlobalAttachment={handleRemoveGlobalAttachment}
repoInfo={repoInfo}
stickyActions={uiPrefs.stickyActionsEnabled}
/>
</div>
</main>
Expand Down
Loading