Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Dialog Transitions

ASecurity

The `Transition` around a dialog decides when it is mounted and nothing else — the fade belongs to the `TransitionChild` overlay and panel inside it. Applies whenever adding or changing a transition in `src/components/styled`, or giving a dialog an animation of its own.

5 stars
0 votes
0 copies
1 views
Added 9/20/2026
developmentgo

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add lxsmnsyc/overwander --skill dialog-transitions --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dialog Transitions?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Dialog Transitions
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lxsmnsyc-dialog-transitions-overwander/badge)](https://www.skillsdirectory.com/skills/lxsmnsyc-dialog-transitions-overwander)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: dialog-transitions
description: >
  The `Transition` around a dialog decides when it is mounted and
  nothing else — the fade belongs to the `TransitionChild` overlay and
  panel inside it. Applies whenever adding or changing a transition in
  `src/components/styled`, or giving a dialog an animation of its own.
---

A dialog is wrapped in one `Transition` and holds two `TransitionChild` elements. The wrapper is the **coordinator**: it says when the dialog exists. The children are what animate.

## Rule

Never give the parent `Transition` enter/leave classes — no `{...FADE}`, no `enter`/`leave` of its own. Put the animation on the overlay and the panel.

```tsx
// Right: the wrapper only mounts and unmounts
<Transition appear show={props.isOpen}>
  <HeadlessDialog isOpen unmount={false} onClose={props.onClose}>
    <TransitionChild {...SHEER} class="fixed inset-0">
      <DialogOverlay class="size-full …" />
    </TransitionChild>
    <Suspense>
      <TransitionChild {...FADE} class={PANEL}>
        <DialogPanel class="contents">…</DialogPanel>
      </TransitionChild>
    </Suspense>
  </HeadlessDialog>
</Transition>

// Wrong: the wrapper animates too
<Transition appear show={props.isOpen} {...FADE}>…</Transition>
```

## Why

- **Opacity multiplies.** A panel at 0.5 inside a wrapper at 0.5 is drawn at 0.25, so an animated wrapper makes every child fade faster than it was told to and on a curve nobody wrote.
- **The wrapper is the clock.** Terracotta unmounts once the wrapper's own transition is over. Give the wrapper a transition and it can finish first, cutting a child's longer one off mid-fade; children that want different timings — an overlay slower than the panel — stop being possible.
- **It is a screen-wide layer.** The wrapper is a bare `div` around fixed-position children. Opacity on it makes one stacking context over the whole page and flattens the dialog into a single painted layer, which loses the panel's shadow over the overlay.

## Where the Suspense goes

The boundary is the panel's `TransitionChild` wrapper, inside the styled `Dialog` and with **no fallback**: a panel waiting on a read leaves the overlay and the frame it was opened in standing, and arrives when it has something to show. The slots (`title`, `description`, `lead`, `aside`, `bar`) are resolved inside it too, so a heading that reads a record does not suspend the screen the dialog was opened from.

A dialog that needs a resource therefore declares it and hands it to a body component, and writes no `Suspense` of its own. One written around the dialog reaches the whole screen instead.

Anything **refetched after a write** is read through `.latest`, not by calling the resource. A refetch suspends every plain read of it, and from inside the panel that detaches the panel mid-write: marking a favorite would blink the sheet for the length of one round trip. `latest` still suspends the first time, which is what makes the panel wait for its first record.

## Around it

- The fades live in [`transition.ts`](../../../src/components/styled/transition.ts), spread into each child. `FADE` fades **and grows**, and is for a **dialog's panel** and nothing else. Everything else takes `SHEER`, the same fade with no scale: the overlay, anything placed against the window (hover cards, tooltips), and anything dropped from the control that opened it — a popover, a listbox, a combobox. Two reasons to keep the scale off those: a list dropped from a button grows from the button rather than from itself, and a scale is a transform, which makes the element the containing block for anything `fixed` inside it — that put a hover card a whole viewport down the page.
- **Never put `inert` on anything a `Transition` or `TransitionChild` wraps.** Terracotta drives focus into a panel once it has entered and closes it again when focus leaves; an inert subtree refuses the focus, and the panel shuts the instant it opens. A dialog on its way out keeps `pointer-events-none` while it fades, and `data-open` is how anything outside tells an open dialog from a leaving one.
- Tailwind's `scale-*` sets the **`scale`** property, not `transform`. A transition naming `transform` animates nothing and the panel appears at full size, so `FADE` names `scale`.
- A `PopoverPanel` given `as={TransitionChild}` **never mounts**. The panel and the transition each decide separately whether to render, and the two do not agree; a `DialogPanel` and a `DialogOverlay` are fine that way, a popover's is not. Wrap the panel in the `Transition` and leave the panel itself plain.
- Write a transition as a **wrapper** rather than as `as={TransitionChild}` on the thing it animates: `<TransitionChild {...FADE}><DialogPanel class="contents"/></TransitionChild>`. The wrapper carries the placement and the fade, and the terracotta part inside it is boxless, so a scale has no second box to fight over. The polymorphic form works from terracotta 1.2.2; before it, a `PopoverPanel` written that way mounted nothing at all.

Attribution

lxsmnsyclxsmnsyc
View sourceMore from lxsmnsyc →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

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 (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

284972 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2222 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

10311 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →