diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..3f75f60 --- /dev/null +++ b/TODO.md @@ -0,0 +1,14 @@ +# TODO — Streams dense layout toggle + +- [ ] Add density state + toggle UI in `app/streams/StreamsPageContent.tsx` with localStorage persistence (`streampay.density`) +- [ ] Pass density to `app/components/StreamRow.tsx` and apply compact class +- [ ] Add compact CSS rules in `app/globals.css` (reduce padding/gaps for `.stream-row--compact` and related layouts) +- [ ] Update `app/streams/page.test.tsx` to cover: + - [ ] comfortable mode (default) -> non-compact + - [ ] compact mode -> compact class + - [ ] toggle interaction updates localStorage + - [ ] keyboard accessibility (role="switch" + aria-checked) +- [ ] Run `npm test -- app/streams/page.test.tsx` and ensure passing +- [ ] Commit changes with message: `feat: add dense-mode toggle to streams list` +- [ ] Provide manual visual testing notes for PR + diff --git a/app/components/StreamRow.tsx b/app/components/StreamRow.tsx index 7638d42..69f20cb 100644 --- a/app/components/StreamRow.tsx +++ b/app/components/StreamRow.tsx @@ -28,9 +28,13 @@ export type StreamRowData = { type StreamRowProps = { stream: StreamRowData; + density?: "compact" | "comfortable"; }; -export function StreamRow({ stream }: StreamRowProps) { +export function StreamRow({ stream, density = "comfortable" }: StreamRowProps) { + // Density is controlled by StreamsPageContent and affects only layout spacing. + // Keeping it as a prop avoids extra re-renders beyond StreamRow itself. + const [isProcessing, setIsProcessing] = useState(false); const [error, setError] = useState(null); const [isIncidentMode] = useState(false); @@ -101,7 +105,10 @@ export function StreamRow({ stream }: StreamRowProps) { }; return ( -
+
{/* Dynamic polite status messenger announcement node layer for assistive tech */}
{srAnnouncement} @@ -158,7 +165,7 @@ export function StreamRow({ stream }: StreamRowProps) { /> )} -
+
-
+
+
+ Density + +
@@ -154,9 +194,9 @@ export function StreamsPageContent({ title={streamListCopy.empty.title} /> ) : ( -
+
{streams.map((stream) => ( - + ))}
)} diff --git a/app/streams/page.test.tsx b/app/streams/page.test.tsx index 7482f7f..b2113ed 100644 --- a/app/streams/page.test.tsx +++ b/app/streams/page.test.tsx @@ -6,7 +6,14 @@ import { render } from "@testing-library/react"; const { screen } = require("@testing-library/react") as any; import { StreamsPageContent } from "./StreamsPageContent"; +const STORAGE_KEY = "streampay.density"; + + describe("StreamsPageContent", () => { + beforeEach(() => { + window.localStorage.clear(); + }); + it("renders the empty state", () => { render();