Skip to content
Open
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Key principles:

3. Open [http://localhost:5173](http://localhost:5173).

## Print stylesheet

Added `src/styles/print.css` to hide UI chrome and expand collapsible
sections when printing the `SortMenu` page. This improves printed output
by removing interactive controls and making content fully visible. (Closes #708)

## Scripts

| Command | Description |
Expand Down
1 change: 1 addition & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
import "./index.css";
import "./styles/print.css";
import { ThemeProvider } from "./ThemeContext";

const root = ReactDOM.createRoot(document.getElementById("root")!);
Expand Down
21 changes: 21 additions & 0 deletions src/pages/SortMenu.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import SortMenu from "./SortMenu";
import fs from "fs";
import path from "path";

describe("SortMenu print behavior", () => {
test("renders collapsible sections", () => {
render(<SortMenu />);
expect(screen.getByText("Sort Options")).toBeInTheDocument();
expect(screen.getByText("Advanced Filters")).toBeInTheDocument();
});

test("print stylesheet exists and contains print rules", () => {
const cssPath = path.resolve(__dirname, "../styles/print.css");
const css = fs.readFileSync(cssPath, "utf8");
expect(css).toMatch(/@media print/);
expect(css).toMatch(/\.no-print/);
expect(css).toMatch(/details\s*>\s*\*/);
});
});
53 changes: 53 additions & 0 deletions src/pages/SortMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from "react";

/**
* SortMenu page used for printing tests.
* - Contains small amount of UI "chrome" that should be hidden when printing
* - Contains collapsible sections which should be expanded when printing
*/
export default function SortMenu(): JSX.Element {
return (
<div className="sort-menu-page">
<header className="sort-menu-header no-print">
<h1>Sort & Filters</h1>
<div className="sort-menu-actions">
<button className="ghost-button">Close</button>
<button className="primary-button">Apply</button>
</div>
</header>

<section className="sort-menu-content">
<p className="no-print">This chrome is hidden on print (page header, buttons).</p>

<div className="sort-collapsible">
<details>
<summary>Sort Options</summary>
<div>
<label>
<input type="radio" name="sort" defaultChecked /> Relevance
</label>
<label>
<input type="radio" name="sort" /> Price: low → high
</label>
<label>
<input type="radio" name="sort" /> Popularity
</label>
</div>
</details>

<details>
<summary>Advanced Filters</summary>
<div>
<label>
<input type="checkbox" /> Include deprecated
</label>
<label>
<input type="checkbox" /> Show only free
</label>
</div>
</details>
</div>
</section>
</div>
);
}
39 changes: 39 additions & 0 deletions src/styles/print.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* Print stylesheet: hide UI chrome and expand collapsibles for printing SortMenu */

@media print {
/* Hide application chrome */
.no-print,
.sort-menu-header,
.sort-menu-actions,
button.ghost-button,
button.primary-button {
display: none !important;
}

/* Ensure details-based collapsibles show their content when printing */
.sort-collapsible details > * {
display: block !important;
visibility: visible !important;
height: auto !important;
overflow: visible !important;
}

/* Hide summary controls when printing to avoid duplicate controls */
.sort-collapsible summary {
display: none !important;
}

/* Make printed text clear and use light color scheme for consistent prints */
html, body {
background: #fff !important;
color: #000 !important;
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}

/* Remove any unnecessary outlines/box-shadows that don't print well */
* {
box-shadow: none !important;
text-shadow: none !important;
}
}