Skip to content
Back to skills

Building A Screen

ASecurity

Get a designed screen onto the glass without the classic desktop-app faults — a panel that will not fill its window, a popover clipped by its parent, a list that re-renders forever, text in the wrong direction. Use when writing or changing any UI code, and before saying a screen is done.

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 30, 2026
ai-agentsrustgoreact

Works with

  • cli

Security analysis

A100/100

Scanned September 30, 2026

npx -y skills add mirzaaghazadeh/StandBye --skill building-a-screen --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Building A Screen?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Building A Screen
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mirzaaghazadeh-building-a-screen/badge)](https://www.skillsdirectory.com/skills/mirzaaghazadeh-building-a-screen)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: building-a-screen
description: Get a designed screen onto the glass without the classic desktop-app faults — a panel that will not fill its window, a popover clipped by its parent, a list that re-renders forever, text in the wrong direction. Use when writing or changing any UI code, and before saying a screen is done.
---

# Building a screen

The bugs here are not logic bugs. The code is right, the data is right, and the window still looks
broken. They are the same handful every time.

## Fill the window, or explain why not

A screen that sizes to its content leaves its footer floating in the middle of an empty window —
the single most common fault, and the easiest to miss on a machine with a small window.

A column that must fill needs **both** `flex: 1` and `min-height: 0`. Without the second, a flex
child refuses to shrink below its content and the scroll happens on the wrong element, or not at
all. The same applies horizontally with `min-width: 0`.

Match how the screens around you attach to the layout. If every other screen returns its toolbar
and body as direct children of the scrolling container, a new one that wraps them in an extra
`div` is a screen that will not fill — the wrapper is an unstyled block and the flex chain stops
there. Check the class you reach for actually exists before trusting it to do something.

## Never scroll the whole window sideways

Wide content — a table, a diff, a code block, a long path — scrolls **inside its own box**, with
`overflow-x: auto` on that box and `min-width: 0` on its flex parent. A horizontal scrollbar on
the window itself is always a bug, and it is caused by one child that refuses to shrink.

Long unbroken strings need `overflow-wrap: anywhere` or a truncation with the full value in a
`title`. A hash, a URL and a file path will all otherwise push the layout wider than the screen.

## Anything that floats goes in a portal

Menus, popovers, pickers, tooltips: render them through a portal with fixed positioning, measured
from the trigger's bounding box. Inside the normal flow they get clipped by the first ancestor
with `overflow: hidden` — which is every scrolling pane — and they will widen the layout when the
window is small. Close on outside click and on Escape, both.

## Do not make the list re-render forever

A selector that builds a new array or object each call returns a new reference every time, and a
subscription that compares by reference will re-render without end. Return the stored value, or a
module-level constant for the empty case. Never `.filter()`, `.map()` or `{...spread}` inside a
selector.

Derive in a memo keyed on what it actually depends on, not on the whole store.

## Text has a direction

Content is written by people and agents in whatever language they use, often mixed — Persian prose
quoting English identifiers is normal. Put `dir="auto"` on each block of user or agent content and
let the browser decide per block. Never set a global direction and never assume left-to-right for
anything you did not write yourself. Code blocks are the exception: those stay `ltr`.

## Every async thing has four endings

Loading, empty, failed, and stale. Write all four before you write the happy path, or you will
ship a screen that shows a spinner for ever when the request rejects. A response that arrives
after a newer one must be dropped, not rendered — keep a sequence number and ignore the stale one.

## Before you call it done

- Open it. Actually look at it — build and run, do not reason about it from the source.
- Resize: narrow, then very wide. Nothing overlaps, nothing clips, no sideways scroll.
- Check the empty state and the error state on purpose; they are the ones nobody sees until a user
  does.
- Read the console. A React key warning or an unhandled rejection is a real bug you can still fix
  cheaply.
- Typecheck. A screen that compiles is not a screen that works, but a screen that does not compile
  is not a screen at all.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…