| name | prototype |
| description | Set up or tear down the UX prototype screen switcher in the Podman Desktop titlebar. Use when the user wants to start a new UI/UX prototype, add prototype screen states, or remove the prototype infrastructure after a prototype ships. Triggers: "set up a prototype", "new prototype", "prototype switcher", "remove prototype", "tear down prototype". |
UX Prototype Screen Switcher
Manages reusable prototype infrastructure that adds a screen switcher dropdown
to the Podman Desktop window titlebar. Each prototype defines named screens
with typed override data and optional timed phase transitions.
When invoked
Determine what the user needs:
- Set up - install the infrastructure files and help wire a new prototype
- Tear down - remove the infrastructure after a prototype ships
Set up
Step 1 - Install infrastructure files
Check whether these files already exist. If they do, skip to Step 2.
-
Create the store at packages/renderer/src/stores/prototype.ts
Copy the contents from references/prototype-store.ts (in this skill's directory).
-
Create the selector at packages/renderer/src/lib/ui/PrototypeSelector.svelte
Copy the contents from references/PrototypeSelector.svelte (in this skill's directory).
-
Patch TitleBar at packages/renderer/src/lib/ui/TitleBar.svelte
- Add import:
import PrototypeSelector from './PrototypeSelector.svelte';
(place it alphabetically among the relative imports, after any /@/ imports)
- In the
<!-- right --> section, add items-center to the div's classes
(skip if the class is already present)
- Add
<PrototypeSelector /> as the first child of that div, before WindowControlButtons
The right section should look like:
<!-- right -->
<div class="flex flex-row grow justify-end items-center">
<PrototypeSelector />
{#if platform !== 'darwin'}
<WindowControlButtons platform={platform} />
{/if}
</div>
Step 2 - Wire the prototype
Ask the user for:
- Prototype name - short title shown in the titlebar (e.g. "Badge visibility")
- Screens - list of named states to switch between
- Override shape - what data each screen provides to the consuming component
- Timelines (optional) - which screens have timed phase transitions
Then create the registration in the appropriate component. Pattern:
import { onDestroy } from 'svelte';
import { registerPrototype, unregisterPrototype } from '/@/stores/prototype';
interface MyOverride {
}
const override = registerPrototype<MyOverride>({
name: 'Prototype name here',
screens: [
{ value: 'idle', label: 'Idle state' },
{ value: 'active', label: 'Active state' },
],
overrides: {
idle: {
},
active: {
},
},
});
onDestroy(unregisterPrototype);
To consume the override reactively in the component:
let currentState: MyOverride | undefined;
const unsubscribe = override.subscribe(value => {
currentState = value;
});
onDestroy(unsubscribe);
Phase transitions
For screens that should auto-advance through phases on a timer, add timelines
and phase-keyed overrides using the screenValue:phaseNumber convention:
registerPrototype({
overrides: {
animated: { status: 'starting' },
'animated:1': { status: 'running' },
'animated:2': { status: 'complete' },
},
timelines: {
animated: [
{ delay: 3000, phase: 1 },
{ delay: 8000, phase: 2 },
],
},
});
Step 3 - Verify
- Run
pnpm typecheck:renderer - should pass with 0 errors
- Run
pnpm lint:check - no new errors in the changed files
- Run
pnpm watch - confirm the titlebar shows the selector when the prototype is registered
Tear down
When a prototype has shipped as a real feature and the switcher is no longer needed:
-
Remove registerPrototype() / unregisterPrototype() calls from the prototype's component(s)
-
Remove the prototype's override interface and config object
-
Check if any other prototype still uses the infrastructure:
grep -r "registerPrototype\|unregisterPrototype" packages/renderer/src/ --include="*.ts" --include="*.svelte"
-
If no other prototype uses it, remove the infrastructure:
- Delete
packages/renderer/src/stores/prototype.ts
- Delete
packages/renderer/src/lib/ui/PrototypeSelector.svelte
- Revert
packages/renderer/src/lib/ui/TitleBar.svelte:
- Remove the
PrototypeSelector import
- Remove
<PrototypeSelector /> from the right section
- Remove
items-center from the right section div
-
Verify clean removal:
grep -r "prototype" packages/renderer/src/stores/ --include="*.ts"
grep -r "PrototypeSelector" packages/renderer/src/ --include="*.svelte"
grep -r "registerPrototype\|unregisterPrototype" packages/renderer/src/
All three should return zero results.
Branch hygiene
The infrastructure files (prototype.ts, PrototypeSelector.svelte) and TitleBar patch
live in real production paths. They should only be committed to a prototype feature branch,
never to main. When the prototype work is done:
- If the files were committed: use tear-down above, then commit the removals.
- If the files were never committed:
git checkout -- <path> or delete from the working tree
before opening a PR.