Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
59 changes: 33 additions & 26 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,10 @@ table.not-prose th {
}

/* Print styles for clean PDF export */
@page {
margin: 0.75in;
}

@media print {
/* Disable all transitions to prevent color flashing after print */
*,
Expand Down Expand Up @@ -1087,6 +1091,8 @@ table.not-prose th {
height: auto !important;
overflow: visible !important;
max-height: none !important;
width: 100% !important;
max-width: 100% !important;
border: none !important;
border-top: none !important;
border-bottom: none !important;
Expand All @@ -1097,8 +1103,8 @@ table.not-prose th {
padding: 0 !important;
}

/* Hide sidebar - target the first flex child that contains Sidebar */
#root > div > div:first-child {
/* Hide sidebar when printing */
[data-sidebar] {
display: none !important;
}

Expand All @@ -1118,26 +1124,10 @@ table.not-prose th {
display: none !important;
}

/* Hide the toolbar div with drag region */
[data-tauri-drag-region] {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
height: 0 !important;
max-height: 0 !important;
margin: 0 !important;
padding: 0 !important;
position: absolute !important;
pointer-events: none !important;
overflow: hidden !important;
}

/* Hide format bar by targeting its wrapper */
.flex-1 > div:has(> div[class*="border-b"]) {
/* Hide toolbar and format bar when printing */
[data-tauri-drag-region],
[data-format-bar] {
display: none !important;
height: 0 !important;
max-height: 0 !important;
overflow: hidden !important;
}

/* Make editor container expand for printing */
Expand All @@ -1146,20 +1136,35 @@ table.not-prose th {
height: auto !important;
}

/* Make editor full width for printing */
/* The editor content area and scroll container use absolute positioning
which collapses to zero height in print. Switch to static flow. */
[data-editor-content-area] {
position: static !important;
overflow: visible !important;
height: auto !important;
}

[data-editor-scroll] {
position: static !important;
overflow: visible !important;
height: auto !important;
}

/* Make editor full width for printing and remove editor padding */
.ProseMirror {
max-width: 100% !important;
padding: 0 !important;
margin: 0 !important;
overflow: visible !important;
height: auto !important;
overflow-wrap: break-word !important;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/* Add padding to prose content for proper margins */
.prose {
max-width: 100% !important;
padding: 0.75in 1in !important;
padding: 0 !important;
margin: 0 !important;
overflow-wrap: break-word !important;
}

/* Ensure page breaks work well */
Expand All @@ -1176,8 +1181,6 @@ table.not-prose th {
p,
blockquote,
pre,
ul,
ol,
table {
page-break-inside: avoid;
break-inside: avoid;
Expand Down Expand Up @@ -1233,6 +1236,10 @@ table.not-prose th {
table {
border: 1px solid #d0d0d0 !important;
border-collapse: collapse !important;
width: 100% !important;
max-width: 100% !important;
table-layout: fixed !important;
overflow-wrap: break-word !important;
}

th,
Expand Down
10 changes: 9 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,19 @@ function AppContent() {
}

// Cmd+P - Open command palette
if ((e.metaKey || e.ctrlKey) && e.key === "p") {
if ((e.metaKey || e.ctrlKey) && !e.shiftKey && e.key === "p") {
e.preventDefault();
setPaletteOpen(true);
return;
}

// Cmd+Shift+P - Print
if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === "p") {
e.preventDefault();
window.dispatchEvent(new CustomEvent("print-note"));
return;
}

// Cmd+/ - Open keyboard shortcuts
if ((e.metaKey || e.ctrlKey) && e.key === "/") {
e.preventDefault();
Expand Down Expand Up @@ -464,6 +471,7 @@ function AppContent() {
) : (
<>
<div
data-sidebar
className={`transition-all duration-500 ease-out overflow-hidden ${!sidebarVisible || focusMode ? "opacity-0 -translate-x-4 w-0 pointer-events-none" : "opacity-100 translate-x-0 w-64"}`}
>
<Sidebar onOpenSettings={toggleSettings} />
Expand Down
13 changes: 10 additions & 3 deletions src/components/editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1856,14 +1856,19 @@ export function Editor({
if (!editor || !currentNote) return;
try {
await downloadPdf(editor, currentNote.title);
// Note: window.print() opens the print dialog but doesn't wait for user action
// No success toast needed - the print dialog provides its own feedback
} catch (error) {
console.error("Failed to open print dialog:", error);
toast.error("Failed to open print dialog");
}
}, [editor, currentNote]);

// Listen for Cmd+P print shortcut
useEffect(() => {
const handler = () => handleDownloadPdf();
window.addEventListener("print-note", handler);
return () => window.removeEventListener("print-note", handler);
}, [handleDownloadPdf]);

const handleDownloadMarkdown = useCallback(async () => {
if (!editor || !currentNote) return;
try {
Expand Down Expand Up @@ -2354,6 +2359,7 @@ export function Editor({

{/* Format Bar – transition only after initial mount to avoid height animation on note load */}
<div
data-format-bar
className={`${focusMode || sourceMode ? "opacity-0 max-h-0 overflow-hidden pointer-events-none" : "opacity-100 max-h-20"} ${hasTransitioned ? `transition-all duration-400 ${needsSidebarDelay ? "delay-200" : ""}` : ""}`}
>
<FormatBar
Expand All @@ -2365,11 +2371,12 @@ export function Editor({
</div>

{/* Editor content area with resize handles overlay */}
<div className="flex-1 relative overflow-hidden">
<div data-editor-content-area className="flex-1 relative overflow-hidden">
{!focusMode && !sourceMode && (
<EditorWidthHandles containerRef={scrollContainerRef} />
)}
<div
data-editor-scroll
ref={scrollContainerRef}
className="absolute inset-0 overflow-y-auto overflow-x-hidden"
dir={textDirection}
Expand Down
13 changes: 13 additions & 0 deletions src/components/preview/PreviewApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,19 @@ export function PreviewApp({ filePath }: PreviewAppProps) {
return;
}

// Cmd+Shift+P: Print
if (modKey && e.shiftKey && e.key.toLowerCase() === "p") {
e.preventDefault();
window.dispatchEvent(new CustomEvent("print-note"));
return;
}

// Cmd+P: Block browser print dialog
if (modKey && !e.shiftKey && e.key === "p") {
e.preventDefault();
return;
}

// Cmd+R: Reload file from disk
if (modKey && e.key === "r") {
e.preventDefault();
Expand Down
1 change: 1 addition & 0 deletions src/lib/shortcuts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const shortcutCategories: ShortcutCategory[] = [
{ keys: [mod, "K"], description: "Add / edit link" },
{ keys: [mod, "F"], description: "Find in note" },
{ keys: [mod, shift, "C"], description: "Copy & Export" },
{ keys: [mod, shift, "P"], description: "Print / Export as PDF" },
{ keys: [mod, shift, "M"], description: "Markdown source" },
{ keys: [mod, shift, "Enter"], description: "Focus mode" },
{ keys: ["/"], description: "Slash commands" },
Expand Down
3 changes: 0 additions & 3 deletions src/services/pdf.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Editor } from "@tiptap/react";
import { save } from "@tauri-apps/plugin-dialog";
import { invoke } from "@tauri-apps/api/core";

/**
* Triggers the native print dialog for the editor content.
* Users can save as PDF or print to a physical printer.
Expand All @@ -16,8 +15,6 @@ export async function downloadPdf(
): Promise<void> {
if (!editor) throw new Error("Editor not available");

// Trigger native print dialog
// The user can choose "Save as PDF" in the print dialog
window.print();
}

Expand Down
Loading