From 07deebc7b8f4973e322b43fc24e485d945fffa29 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 1 May 2026 15:45:30 -0700 Subject: [PATCH 1/9] Add Storybook cleanup checklist --- TODO.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..93e15ce --- /dev/null +++ b/TODO.md @@ -0,0 +1,46 @@ +# Storybook Cleanup TODO + +## Wall Stories + +- [ ] Remove `Wall/Multi Pane Dark` and `Wall/Multi Pane Light`; theme-specific Wall stories are not needed. +- [ ] Fix `Wall/With Doors` so the story actually shows minimized doors. +- [ ] Remove `Wall/Marketing Demo`. +- [ ] Fix `Wall/Alert Enabled Idle Pane` so the alert-enabled state is visible. +- [ ] Fix `Wall/Alert Ringing Pane` so the ringing state is visible. +- [ ] Fix `Wall/Alert Ringing Door` so the minimized door shows the ringing state. +- [ ] Fix `Wall/Alert Modal Open` so the alert dialog is visible. +- [ ] Fix `Wall/Todo After Dismiss` so the TODO state is visible. +- [ ] Fix `Wall/Minimized Ringing Session` so the minimized session shows ringing and TODO state. +- [ ] Fix `Wall/Multiple Ringing Sessions` so all intended alert/TODO states are visible. + +## Terminal Header Stories + +- [ ] Fix or remove `TerminalPaneHeader/Todo Click To Dismiss`; it currently clicks a noop and matches `Todo And Alert Enabled`. + +## Text Selection Stories + +- [ ] Fix `TextSelection/Linewise Outline` so it is outline-only. +- [ ] Fix `TextSelection/Block Outline` so it is outline-only. + +## Selection Overlay Stories + +- [ ] Replace `SelectionOverlay` stories with stories that exercise the real selection overlay component instead of a hand-rolled `MarchingAntsRect` demo. + +## Update Banner Stories + +- [ ] Remove or reframe `UpdateBanner/Idle`; it renders blank because the component returns `null`. +- [ ] Remove or reframe `UpdateBanner/Dismissed`; it renders blank because the component returns `null`. +- [ ] Reframe `UpdateBanner/Long Version String` so the long-version stress case is obvious. +- [ ] Reframe `UpdateBanner/Narrow Viewport` so the constrained width is visible. + +## App Bar Stories + +- [ ] Make `AppBar/Default`, `AppBar/Single Shell`, and `AppBar/Many Shells` meaningfully different, likely by opening the shell dropdown or reducing the story set. + +## Kill Modal Stories + +- [ ] Fix or remove `KillModal/Shaking`; it is visually identical to `Default` in static capture. + +## Story Framing + +- [ ] Improve thin chrome story framing for `Door`, `TerminalPaneHeader`, `MouseHeaderIcon`, `UpdateBanner`, `AppBar`, and `Baseboard` so the target UI is not a tiny strip in a mostly blank fullscreen canvas. From 9de6ea07525344c3caad44782f04c60eecd8501a Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 1 May 2026 15:48:09 -0700 Subject: [PATCH 2/9] Clean up initial Wall stories --- TODO.md | 6 +++--- lib/src/stories/Wall.stories.tsx | 33 +++++++++----------------------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/TODO.md b/TODO.md index 93e15ce..355c3d0 100644 --- a/TODO.md +++ b/TODO.md @@ -2,9 +2,9 @@ ## Wall Stories -- [ ] Remove `Wall/Multi Pane Dark` and `Wall/Multi Pane Light`; theme-specific Wall stories are not needed. -- [ ] Fix `Wall/With Doors` so the story actually shows minimized doors. -- [ ] Remove `Wall/Marketing Demo`. +- [x] Remove `Wall/Multi Pane Dark` and `Wall/Multi Pane Light`; theme-specific Wall stories are not needed. +- [x] Fix `Wall/With Doors` so the story actually shows minimized doors. +- [x] Remove `Wall/Marketing Demo`. - [ ] Fix `Wall/Alert Enabled Idle Pane` so the alert-enabled state is visible. - [ ] Fix `Wall/Alert Ringing Pane` so the ringing state is visible. - [ ] Fix `Wall/Alert Ringing Door` so the minimized door shows the ringing state. diff --git a/lib/src/stories/Wall.stories.tsx b/lib/src/stories/Wall.stories.tsx index f961013..690f955 100644 --- a/lib/src/stories/Wall.stories.tsx +++ b/lib/src/stories/Wall.stories.tsx @@ -5,7 +5,6 @@ import { SCENARIO_SHELL_PROMPT, SCENARIO_LS_OUTPUT, SCENARIO_ANSI_COLORS, - SCENARIO_LONG_RUNNING, } from '../lib/platform'; import { getActivitySnapshot, primeActivity, type ActivityState } from '../lib/terminal-registry'; @@ -47,6 +46,13 @@ async function minimizeSelectedPane() { await wait(150); } +async function minimizeFirstVisiblePane() { + await wait(100); + const button = document.querySelector('button[aria-label="Minimize"]'); + button?.click(); + await wait(200); +} + async function openAlertDialog() { await wait(250); const alertButton = document.querySelector('[data-alert-button-for]'); @@ -71,33 +77,12 @@ export const MultiPane: Story = { play: splitPanes, }; -export const MultiPaneDark: Story = { - parameters: { fakePty: { scenario: flattenScenario(SCENARIO_LS_OUTPUT) } }, - globals: { theme: 'GitHub Dark Default' }, - play: splitPanes, -}; - -export const MultiPaneLight: Story = { - parameters: { fakePty: { scenario: flattenScenario(SCENARIO_LS_OUTPUT) } }, - globals: { theme: 'GitHub Light Default' }, - play: splitPanes, -}; - export const WithDoors: Story = { parameters: { fakePty: { scenario: flattenScenario(SCENARIO_LS_OUTPUT) } }, play: async () => { await splitPanes(); - await minimizeSelectedPane(); - }, -}; - -export const MarketingDemo: Story = { - parameters: { fakePty: { scenario: SCENARIO_LONG_RUNNING } }, - play: async () => { - await wait(1_500); - window.dispatchEvent(new KeyboardEvent('keydown', { key: '"', bubbles: true })); - await wait(1_000); - window.dispatchEvent(new KeyboardEvent('keydown', { key: '%', bubbles: true })); + await minimizeFirstVisiblePane(); + await minimizeFirstVisiblePane(); }, }; From 4ddd4cfbfe2d46f30be4a328a17f4442f1f503d3 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 1 May 2026 16:44:59 -0700 Subject: [PATCH 3/9] Fix Wall alert stories --- TODO.md | 14 +-- lib/src/stories/Wall.stories.tsx | 151 +++++++++++++++---------------- 2 files changed, 82 insertions(+), 83 deletions(-) diff --git a/TODO.md b/TODO.md index 355c3d0..8df97d8 100644 --- a/TODO.md +++ b/TODO.md @@ -5,13 +5,13 @@ - [x] Remove `Wall/Multi Pane Dark` and `Wall/Multi Pane Light`; theme-specific Wall stories are not needed. - [x] Fix `Wall/With Doors` so the story actually shows minimized doors. - [x] Remove `Wall/Marketing Demo`. -- [ ] Fix `Wall/Alert Enabled Idle Pane` so the alert-enabled state is visible. -- [ ] Fix `Wall/Alert Ringing Pane` so the ringing state is visible. -- [ ] Fix `Wall/Alert Ringing Door` so the minimized door shows the ringing state. -- [ ] Fix `Wall/Alert Modal Open` so the alert dialog is visible. -- [ ] Fix `Wall/Todo After Dismiss` so the TODO state is visible. -- [ ] Fix `Wall/Minimized Ringing Session` so the minimized session shows ringing and TODO state. -- [ ] Fix `Wall/Multiple Ringing Sessions` so all intended alert/TODO states are visible. +- [x] Fix `Wall/Alert Enabled Idle Pane` so the alert-enabled state is visible. +- [x] Fix `Wall/Alert Ringing Pane` so the ringing state is visible. +- [x] Fix `Wall/Alert Ringing Door` so the minimized door shows the ringing state. +- [x] Fix `Wall/Alert Modal Open` so the alert dialog is visible. +- [x] Fix `Wall/Todo After Dismiss` so the TODO state is visible. +- [x] Fix `Wall/Minimized Ringing Session` so the minimized session shows ringing and TODO state. +- [x] Fix `Wall/Multiple Ringing Sessions` so all intended alert/TODO states are visible. ## Terminal Header Stories diff --git a/lib/src/stories/Wall.stories.tsx b/lib/src/stories/Wall.stories.tsx index 690f955..751c6ca 100644 --- a/lib/src/stories/Wall.stories.tsx +++ b/lib/src/stories/Wall.stories.tsx @@ -6,7 +6,7 @@ import { SCENARIO_LS_OUTPUT, SCENARIO_ANSI_COLORS, } from '../lib/platform'; -import { getActivitySnapshot, primeActivity, type ActivityState } from '../lib/terminal-registry'; +import type { ActivityState } from '../lib/terminal-registry'; const meta: Meta = { title: 'App/Wall', @@ -20,14 +20,12 @@ function wait(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); } -function primeByIndex(states: Partial[]) { - const ids = [...getActivitySnapshot().keys()]; - states.forEach((state, index) => { - const id = ids[index]; - if (id) { - primeActivity(id, state); - } - }); +function withPrimedActivity(byId: Record>) { + return { + primedSessionState: { + byId, + }, + }; } async function splitPanes() { @@ -87,122 +85,123 @@ export const WithDoors: Story = { }; export const AlertEnabledIdlePane: Story = { + args: { + initialPaneIds: ['wall-alert-enabled'], + }, parameters: { fakePty: { scenario: flattenScenario(SCENARIO_SHELL_PROMPT) }, - primedSessionState: { - byIndex: [ - { - status: 'NOTHING_TO_SHOW', - - todo: false, - }, - ], - }, + ...withPrimedActivity({ + 'wall-alert-enabled': { + status: 'NOTHING_TO_SHOW', + todo: false, + }, + }), }, }; export const AlertRingingPane: Story = { + args: { + initialPaneIds: ['wall-alert-ringing'], + }, parameters: { fakePty: { scenario: flattenScenario(SCENARIO_SHELL_PROMPT) }, - primedSessionState: { - byIndex: [ - { - status: 'ALERT_RINGING', - - todo: false, - }, - ], - }, + ...withPrimedActivity({ + 'wall-alert-ringing': { + status: 'ALERT_RINGING', + todo: false, + }, + }), }, }; export const AlertRingingDoor: Story = { - parameters: { fakePty: { scenario: flattenScenario(SCENARIO_SHELL_PROMPT) } }, - play: async () => { - await minimizeSelectedPane(); - primeByIndex([ - { + args: { + initialPaneIds: ['wall-alert-ringing-door'], + }, + parameters: { + fakePty: { scenario: flattenScenario(SCENARIO_SHELL_PROMPT) }, + ...withPrimedActivity({ + 'wall-alert-ringing-door': { status: 'ALERT_RINGING', - todo: false, }, - ]); + }), + }, + play: async () => { + await minimizeSelectedPane(); await wait(100); }, }; export const AlertModalOpen: Story = { + args: { + initialPaneIds: ['wall-alert-modal'], + }, parameters: { fakePty: { scenario: flattenScenario(SCENARIO_SHELL_PROMPT) }, - primedSessionState: { - byIndex: [ - { - status: 'ALERT_RINGING', - - todo: false, - }, - ], - }, + ...withPrimedActivity({ + 'wall-alert-modal': { + status: 'ALERT_RINGING', + todo: false, + }, + }), }, play: openAlertDialog, }; export const TodoAfterDismiss: Story = { + args: { + initialPaneIds: ['wall-todo-after-dismiss'], + }, parameters: { fakePty: { scenario: flattenScenario(SCENARIO_SHELL_PROMPT) }, - primedSessionState: { - byIndex: [ - { - status: 'ALERT_RINGING', - - todo: true, - }, - ], - }, + ...withPrimedActivity({ + 'wall-todo-after-dismiss': { + status: 'ALERT_RINGING', + todo: true, + }, + }), }, }; export const MinimizedRingingSession: Story = { - parameters: { fakePty: { scenario: flattenScenario(SCENARIO_SHELL_PROMPT) } }, - play: async () => { - await minimizeSelectedPane(); - primeByIndex([ - { + args: { + initialPaneIds: ['wall-minimized-ringing'], + }, + parameters: { + fakePty: { scenario: flattenScenario(SCENARIO_SHELL_PROMPT) }, + ...withPrimedActivity({ + 'wall-minimized-ringing': { status: 'ALERT_RINGING', - todo: true, }, - { - status: 'NOTHING_TO_SHOW', - - todo: false, - }, - ]); + }), + }, + play: async () => { + await minimizeSelectedPane(); await wait(100); }, }; export const MultipleRingingSessions: Story = { - parameters: { fakePty: { scenario: flattenScenario(SCENARIO_SHELL_PROMPT) } }, - play: async () => { - await splitPanes(); - primeByIndex([ - { + args: { + initialPaneIds: ['wall-ringing-one', 'wall-ringing-todo', 'wall-alert-enabled-idle'], + }, + parameters: { + fakePty: { scenario: flattenScenario(SCENARIO_SHELL_PROMPT) }, + ...withPrimedActivity({ + 'wall-ringing-one': { status: 'ALERT_RINGING', - todo: false, }, - { + 'wall-ringing-todo': { status: 'ALERT_RINGING', - todo: true, }, - { + 'wall-alert-enabled-idle': { status: 'NOTHING_TO_SHOW', - todo: false, }, - ]); - await wait(100); + }), }, }; From 754b38fe5491ac4c202640823c94c9d9554aa64e Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 1 May 2026 16:55:14 -0700 Subject: [PATCH 4/9] Use real SelectionOverlay stories --- TODO.md | 2 +- lib/src/stories/SelectionOverlay.stories.tsx | 192 +++++++++++++------ 2 files changed, 130 insertions(+), 64 deletions(-) diff --git a/TODO.md b/TODO.md index 8df97d8..602bfd5 100644 --- a/TODO.md +++ b/TODO.md @@ -24,7 +24,7 @@ ## Selection Overlay Stories -- [ ] Replace `SelectionOverlay` stories with stories that exercise the real selection overlay component instead of a hand-rolled `MarchingAntsRect` demo. +- [x] Replace `SelectionOverlay` stories with stories that exercise the real selection overlay component instead of a hand-rolled `MarchingAntsRect` demo. ## Update Banner Stories diff --git a/lib/src/stories/SelectionOverlay.stories.tsx b/lib/src/stories/SelectionOverlay.stories.tsx index 3924b55..7b45f12 100644 --- a/lib/src/stories/SelectionOverlay.stories.tsx +++ b/lib/src/stories/SelectionOverlay.stories.tsx @@ -1,81 +1,147 @@ -import { useState, useRef, useEffect } from 'react'; +import { useEffect, useRef } from 'react'; import type { Meta, StoryObj } from '@storybook/react'; -import type { WallMode } from '../components/Wall'; -import { MarchingAntsRect } from '../components/Wall'; +import '@xterm/xterm/css/xterm.css'; +import { SelectionOverlay } from '../components/SelectionOverlay'; +import { + focusSession, + getOrCreateTerminal, + getTerminalOverlayDims, + mountElement, + refitSession, + unmountElement, +} from '../lib/terminal-registry'; +import { flattenScenario, SCENARIO_LS_OUTPUT } from '../lib/platform'; +import { + setHintToken, + setSelection, + type Selection, + type TokenHint, +} from '../lib/mouse-selection'; +import { TERMINAL_BOTTOM_RADIUS_CLASS } from '../components/design'; -function SelectionOverlayDemo({ initialMode = 'command' as WallMode }) { - const [mode, setMode] = useState(initialMode); - const containerRef = useRef(null); - const [size, setSize] = useState({ width: 484, height: 284 }); +function SelectionOverlayStory({ + id, + selection, + hintToken = null, +}: { + id: string; + selection: Omit; + hintToken?: TokenHint | null; +}) { + const terminalHostRef = useRef(null); useEffect(() => { - const el = containerRef.current; - if (!el) return; - const ro = new ResizeObserver(([entry]) => { - setSize({ width: entry.contentRect.width - 16, height: entry.contentRect.height - 16 }); - }); - ro.observe(el); - return () => ro.disconnect(); - }, []); - - const color = getComputedStyle(document.documentElement).getPropertyValue('--color-header-active-bg').trim() || '#094771'; - - const overlayStyle: React.CSSProperties = { - position: 'absolute', - inset: 8, - borderRadius: '0.5rem', - pointerEvents: 'none', - transition: 'border 150ms, box-shadow 150ms', - }; - - if (mode === 'passthrough') { - overlayStyle.border = `2px solid ${color}`; - overlayStyle.boxShadow = `0 0 15px color-mix(in srgb, ${color} 30%, transparent)`; - } + const terminalHost = terminalHostRef.current; + if (!terminalHost) return; + + getOrCreateTerminal(id); + mountElement(id, terminalHost); + + const observer = new ResizeObserver(() => refitSession(id)); + observer.observe(terminalHost); + + return () => { + observer.disconnect(); + unmountElement(id); + }; + }, [id]); + + useEffect(() => { + focusSession(id, true); + }, [id]); + + useEffect(() => { + let cancelled = false; + let timer: ReturnType; + + const applySelection = () => { + if (cancelled) return; + const dims = getTerminalOverlayDims(id); + if (!dims || dims.cellHeight === 0) { + timer = setTimeout(applySelection, 50); + return; + } + + setSelection(id, { ...selection, startedInScrollback: false }); + setHintToken(id, hintToken); + }; + + timer = setTimeout(applySelection, 100); + return () => { + cancelled = true; + clearTimeout(timer); + setSelection(id, null); + setHintToken(id, null); + }; + }, [id, selection, hintToken]); return ( -
- {/* Simulated terminal content */} -
-
user@mouseterm:~$ ls -la
-
total 48
-
drwxr-xr-x 12 user staff 384 Mar 16 10:30 .
-
- {/* Selection overlay */} - {mode === 'command' ? ( -
- -
- ) : ( -
- )} - {/* Mode toggle */} -
- - -
+
+
+
); } -const meta: Meta = { +const meta: Meta = { title: 'Components/SelectionOverlay', - component: SelectionOverlayDemo, + component: SelectionOverlayStory, + parameters: { + fakePty: { scenario: flattenScenario(SCENARIO_LS_OUTPUT) }, + }, }; export default meta; -type Story = StoryObj; +type Story = StoryObj; + +export const LinewiseDrag: Story = { + args: { + id: 'selection-overlay-linewise-drag', + selection: { + startRow: 2, + startCol: 5, + endRow: 6, + endCol: 24, + shape: 'linewise', + dragging: true, + }, + }, +}; -export const CommandMode: Story = { - args: { initialMode: 'command' }, +export const BlockDrag: Story = { + args: { + id: 'selection-overlay-block-drag', + selection: { + startRow: 2, + startCol: 6, + endRow: 5, + endCol: 26, + shape: 'block', + dragging: true, + }, + }, }; -export const PassthroughMode: Story = { - args: { initialMode: 'passthrough' }, +export const SmartPathHint: Story = { + args: { + id: 'selection-overlay-smart-path-hint', + selection: { + startRow: 2, + startCol: 5, + endRow: 6, + endCol: 24, + shape: 'linewise', + dragging: true, + }, + hintToken: { + kind: 'path', + row: 8, + startCol: 35, + endCol: 38, + text: 'src', + }, + }, }; From e1c2818db390fea767c33ac0e90a0a2d44f43e7c Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 1 May 2026 17:38:29 -0700 Subject: [PATCH 5/9] Differentiate AppBar stories --- TODO.md | 2 +- lib/src/stories/AppBar.stories.tsx | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 602bfd5..5f84253 100644 --- a/TODO.md +++ b/TODO.md @@ -35,7 +35,7 @@ ## App Bar Stories -- [ ] Make `AppBar/Default`, `AppBar/Single Shell`, and `AppBar/Many Shells` meaningfully different, likely by opening the shell dropdown or reducing the story set. +- [x] Make `AppBar/Default`, `AppBar/Single Shell`, and `AppBar/Many Shells` meaningfully different, likely by opening the shell dropdown or reducing the story set. ## Kill Modal Stories diff --git a/lib/src/stories/AppBar.stories.tsx b/lib/src/stories/AppBar.stories.tsx index 44cc60f..f0ff87f 100644 --- a/lib/src/stories/AppBar.stories.tsx +++ b/lib/src/stories/AppBar.stories.tsx @@ -7,6 +7,18 @@ const DEFAULT_SHELLS = [ { name: 'fish', path: '/usr/bin/fish' }, ]; +function wait(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +async function openShellSelector({ canvasElement }: { canvasElement: HTMLElement }) { + await wait(100); + const shellButton = Array.from(canvasElement.querySelectorAll('button[aria-haspopup="menu"]')) + .find((button) => DEFAULT_SHELLS.some((shell) => button.textContent?.includes(shell.name))); + shellButton?.click(); + await wait(100); +} + function AppBarStory(props: React.ComponentProps) { return (
@@ -32,6 +44,7 @@ export const SingleShell: Story = { args: { shells: [{ name: 'bash', path: '/bin/bash' }], }, + play: openShellSelector, }; export const ManyShells: Story = { @@ -44,4 +57,5 @@ export const ManyShells: Story = { { name: 'nu', path: '/usr/bin/nu' }, ], }, + play: openShellSelector, }; From 79354f521cb75a37dded7efcc4c5c2a87e4b9876 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 1 May 2026 17:45:34 -0700 Subject: [PATCH 6/9] Clarify UpdateBanner null states --- TODO.md | 6 +++--- lib/src/stories/UpdateBanner.stories.tsx | 15 ++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/TODO.md b/TODO.md index 5f84253..fb9a55f 100644 --- a/TODO.md +++ b/TODO.md @@ -28,9 +28,9 @@ ## Update Banner Stories -- [ ] Remove or reframe `UpdateBanner/Idle`; it renders blank because the component returns `null`. -- [ ] Remove or reframe `UpdateBanner/Dismissed`; it renders blank because the component returns `null`. -- [ ] Reframe `UpdateBanner/Long Version String` so the long-version stress case is obvious. +- [x] Keep `UpdateBanner/Idle` and mark the expected empty render in the story canvas. +- [x] Keep `UpdateBanner/Dismissed` and mark the expected empty render in the story canvas. +- [x] Remove `UpdateBanner/Long Version String`. - [ ] Reframe `UpdateBanner/Narrow Viewport` so the constrained width is visible. ## App Bar Stories diff --git a/lib/src/stories/UpdateBanner.stories.tsx b/lib/src/stories/UpdateBanner.stories.tsx index 29f9021..f42ace8 100644 --- a/lib/src/stories/UpdateBanner.stories.tsx +++ b/lib/src/stories/UpdateBanner.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { UpdateBanner, type UpdateBannerState } from '../../../standalone/src/UpdateBanner'; -function UpdateBannerStory({ state }: { state: UpdateBannerState }) { +function UpdateBannerStory({ state, expectedNullReason }: { state: UpdateBannerState; expectedNullReason?: string }) { return (
console.log('Open changelog')} onOpenDebug={() => console.log('Open debug')} /> + {expectedNullReason ? ( +
+ Expected empty banner: {expectedNullReason} +
+ ) : null}
); } @@ -43,18 +48,14 @@ export const PostUpdateFailure: Story = { export const Idle: Story = { args: { state: { status: 'idle' }, + expectedNullReason: 'idle has no update notice to show.', }, }; export const Dismissed: Story = { args: { state: { status: 'dismissed' }, - }, -}; - -export const LongVersionString: Story = { - args: { - state: { status: 'downloaded', version: '1.23.456-beta.7+build.2025.04.10' }, + expectedNullReason: 'the user has already dismissed this notice.', }, }; From f9d857c56828ba490d6fc158e778e504c7eb2e2c Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Mon, 4 May 2026 16:35:30 -0700 Subject: [PATCH 7/9] Remove redundant TerminalPaneHeader todo story --- TODO.md | 2 +- lib/src/stories/TerminalPaneHeader.stories.tsx | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/TODO.md b/TODO.md index fb9a55f..85d0d8d 100644 --- a/TODO.md +++ b/TODO.md @@ -15,7 +15,7 @@ ## Terminal Header Stories -- [ ] Fix or remove `TerminalPaneHeader/Todo Click To Dismiss`; it currently clicks a noop and matches `Todo And Alert Enabled`. +- [x] Remove `TerminalPaneHeader/Todo Click To Dismiss`; it clicked a noop and matched `Todo And Alert Enabled`. ## Text Selection Stories diff --git a/lib/src/stories/TerminalPaneHeader.stories.tsx b/lib/src/stories/TerminalPaneHeader.stories.tsx index 1eaa8e6..488dda0 100644 --- a/lib/src/stories/TerminalPaneHeader.stories.tsx +++ b/lib/src/stories/TerminalPaneHeader.stories.tsx @@ -92,13 +92,6 @@ async function openAlertRightClickDialog() { await wait(100); } -async function clickTodoPill() { - await wait(100); - const todoButton = document.querySelector(`[data-session-todo-for="${SESSION_ID}"]`); - todoButton?.click(); - await wait(100); -} - const meta: Meta = { title: 'Components/TerminalPaneHeader', component: TabStory, @@ -179,14 +172,6 @@ export const AlertRightClickDialog: Story = { play: openAlertRightClickDialog, }; -export const TodoClickToDismiss: Story = { - parameters: primedState({ - status: 'NOTHING_TO_SHOW', - todo: true, - }), - play: clickTodoPill, -}; - export const TodoOnly: Story = { parameters: primedState({ status: 'ALERT_DISABLED', From b19e66aaa5af0eb27c1505c9b0df641be5355ea8 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Mon, 4 May 2026 16:36:03 -0700 Subject: [PATCH 8/9] Mark TextSelection stories resolved --- TODO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index 85d0d8d..5aa0976 100644 --- a/TODO.md +++ b/TODO.md @@ -19,8 +19,8 @@ ## Text Selection Stories -- [ ] Fix `TextSelection/Linewise Outline` so it is outline-only. -- [ ] Fix `TextSelection/Block Outline` so it is outline-only. +- [x] Keep `TextSelection/Linewise Outline`; it is already good as-is. +- [x] Keep `TextSelection/Block Outline`; it is already good as-is. ## Selection Overlay Stories From 1ca36ba25c5875fb2bb7fa9c5b4071d8b96198c7 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Mon, 4 May 2026 16:44:30 -0700 Subject: [PATCH 9/9] Remove Storybook cleanup TODO --- TODO.md | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 TODO.md diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 5aa0976..0000000 --- a/TODO.md +++ /dev/null @@ -1,46 +0,0 @@ -# Storybook Cleanup TODO - -## Wall Stories - -- [x] Remove `Wall/Multi Pane Dark` and `Wall/Multi Pane Light`; theme-specific Wall stories are not needed. -- [x] Fix `Wall/With Doors` so the story actually shows minimized doors. -- [x] Remove `Wall/Marketing Demo`. -- [x] Fix `Wall/Alert Enabled Idle Pane` so the alert-enabled state is visible. -- [x] Fix `Wall/Alert Ringing Pane` so the ringing state is visible. -- [x] Fix `Wall/Alert Ringing Door` so the minimized door shows the ringing state. -- [x] Fix `Wall/Alert Modal Open` so the alert dialog is visible. -- [x] Fix `Wall/Todo After Dismiss` so the TODO state is visible. -- [x] Fix `Wall/Minimized Ringing Session` so the minimized session shows ringing and TODO state. -- [x] Fix `Wall/Multiple Ringing Sessions` so all intended alert/TODO states are visible. - -## Terminal Header Stories - -- [x] Remove `TerminalPaneHeader/Todo Click To Dismiss`; it clicked a noop and matched `Todo And Alert Enabled`. - -## Text Selection Stories - -- [x] Keep `TextSelection/Linewise Outline`; it is already good as-is. -- [x] Keep `TextSelection/Block Outline`; it is already good as-is. - -## Selection Overlay Stories - -- [x] Replace `SelectionOverlay` stories with stories that exercise the real selection overlay component instead of a hand-rolled `MarchingAntsRect` demo. - -## Update Banner Stories - -- [x] Keep `UpdateBanner/Idle` and mark the expected empty render in the story canvas. -- [x] Keep `UpdateBanner/Dismissed` and mark the expected empty render in the story canvas. -- [x] Remove `UpdateBanner/Long Version String`. -- [ ] Reframe `UpdateBanner/Narrow Viewport` so the constrained width is visible. - -## App Bar Stories - -- [x] Make `AppBar/Default`, `AppBar/Single Shell`, and `AppBar/Many Shells` meaningfully different, likely by opening the shell dropdown or reducing the story set. - -## Kill Modal Stories - -- [ ] Fix or remove `KillModal/Shaking`; it is visually identical to `Default` in static capture. - -## Story Framing - -- [ ] Improve thin chrome story framing for `Door`, `TerminalPaneHeader`, `MouseHeaderIcon`, `UpdateBanner`, `AppBar`, and `Baseboard` so the target UI is not a tiny strip in a mostly blank fullscreen canvas.