| name | ideas |
| description | Compare multiple UI options in-browser with the ui.sh picker. |
Ideas
Use this when the user wants to use the ui.sh picker to see and pick between multiple UI implementations while previewing them in the browser.
Activation
Use For
- adding ui.sh picker scaffolding to compare multiple UI options
- annotating option groups with
data-uidotsh-pick and data-uidotsh-option
- injecting, verifying, or removing the ui.sh picker toolbar
- asking the user to choose between visible picker options
- cleaning up unselected options and picker-only artifacts
Do Not Use For
- creating design concepts or visual directions
- applying design guidelines
- one definitive implementation without picker comparison
- non-UI variation work, such as purely logic or data work
Load First
- No companion files are required.
Progress Updates
While running this skill, keep the user informed so longer runs do not look stuck.
- Send a short (one line) status update before each major phase.
- Keep updates concrete and lightweight: what you are doing now, not verbose logs.
- On larger codebases, post another brief update every few tool calls or when a step is taking longer than expected.
- If blocked, say what is blocking you and what you will try next.
Suggested phase updates:
- Cleaning prior picker scaffolding from earlier rounds.
- Scanning current UI and identifying picker decision points.
- Annotating option groups in existing files.
- Injecting/verifying the picker toolbar.
- Preparing selection question(s).
- Finalizing selected variant with partial or full cleanup.
- Running validation checks.
Start
- If this skill has already been used in the same conversation/project, run an iteration reset pass first.
- Use the currently selected/visible UI as the baseline.
- Remove lingering artifacts from earlier rounds: old unselected branches, stale
hidden attributes, and picker wrappers/attributes that are no longer needed.
- Keep one toolbar script tag if the user is still comparing options; remove duplicates only.
- Ensure each area is back to one clean implementation before generating new options.
Workflow
-
Define picker decision points before coding:
- Give each decision a human-readable label (for example:
Hero style, Pricing layout).
- Use existing option labels when variants already have names.
- When the current implementation is included, suffix its option label with
(current) (for example: Minimal (current)).
-
Annotate each decision with UI picker attributes:
- Parent wrapper:
data-uidotsh-pick="Human readable label"
- Option nodes:
data-uidotsh-option="Human readable option"
- When the current implementation is included, it must be the first option and include
(current) in its option label.
- Exactly one option visible; all others use
hidden
- Apply the Tailwind CSS
contents class to wrapper and option nodes so wrappers do not affect layout
-
After all variants are annotated, inject the toolbar script once in a shared app layout/root shell:
- Prefer framework-native script APIs when available.
- For Laravel, if
resources/views/layouts/app.blade.php exists, inject the script there once, right before </body>.
- For TanStack projects, update
src/routes/__root.tsx and inject the picker via the scripts array returned from the head option in createRootRoute (do not add a raw <script> tag in the route component markup).
- For Nuxt projects, use the
useHead composable in the root app.vue (or a layout file such as layouts/default.vue) to inject the script.
- For Vite projects, if an
index.html exists in the project root, inject the script there once, right before </body>.
- For Next.js, use
next/script (plain <script> in JSX can fail to execute until a full refresh in dev):
import Script from 'next/script'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script src="https://ui.sh/ui-picker.js" />
</body>
</html>
)
}
- If there is no framework script primitive, inject a plain script tag once in the shared root layout, right before
</body>:
<script src="https://ui.sh/ui-picker.js"></script>
- Do not place the script in leaf component files, and keep injection idempotent (do not add duplicates).
-
Let the user preview variants in-browser with the picker toolbar.
-
If the toolbar cannot load (for example CSP/offline), skip preview and ask for selection in chat using labels and descriptions.
-
Ask for selection in the agent using the question tool:
- Use explicit option labels matching the UI picker labels.
- For existing-design variation requests, keep the current implementation as the first choice and preserve the
(current) suffix in the label.
- Keep custom input enabled (so
Type your own answer remains available).
- For multiple decision points, ask one clear question per decision.
-
Finalize after selection:
- Keep only selected variants.
- Remove unselected variants and any now-unneeded picker wrapper attributes.
- Remove lingering
hidden attributes and empty wrappers created only for picker scaffolding.
- Remove temporary comments/suppressions used only for variant scaffolding.
- During cleanup, remove picker script usage/usages first, then remove any now-unused script-related imports (ideally in one file update) so intermediate saves do not create an invalid state.
- If the user wants another comparison round, keep a single toolbar script tag in place for faster iteration.
- If the user is done comparing (or asks for final cleanup), remove the toolbar script and any remaining picker-only scaffolding.
Verify
- Check desktop and mobile layouts.
- Ensure no broken semantics or duplicate
id attributes across surviving markup.
- Ensure no old picker artifacts remain before ending the run unless intentionally preparing a fresh new comparison immediately.
- Run relevant lint, typecheck, or tests when available.
Markup Patterns
HTML Example
<div data-uidotsh-pick="Hero style" class="contents">
<div data-uidotsh-option="Minimal" class="contents">...</div>
<div data-uidotsh-option="Bold" class="contents" hidden>...</div>
<div data-uidotsh-option="Editorial" class="contents" hidden>...</div>
</div>
React/TSX Example
<div data-uidotsh-pick="Hero style" className="contents">
<div data-uidotsh-option="Minimal" className="contents">
...
</div>
<div data-uidotsh-option="Bold" className="contents" hidden>
...
</div>
</div>
Guardrails
- Do all variant work in existing source files (no standalone preview file).
- Provide concise user-facing progress updates across major phases.
- Use
data-uidotsh-pick + data-uidotsh-option markers for every decision.
- Use the Tailwind CSS
contents class on wrapper and option nodes.
- When the current implementation is included, option 1 must be the current implementation and include
(current) in its label.
- Exactly one option starts visible; all others start
hidden.
- Before starting a new suggestion/options round, clean previous unselected picker artifacts so nothing old lingers.
- Ask for final selection in the agent, then remove all unpicked variants.
- Inject the picker script only after variants are in place; use framework script APIs when available (for Next.js:
next/script).
- During cleanup, remove script tags/usages before deleting related imports so stepwise saves never leave unresolved references.
- Remove the picker script only when the user is done comparing or explicitly asks for final cleanup.