Reveal
Free · MITHeadless, accessible, and styled entirely through the attribute surface below — bring your own CSS system, or start from the reference theme.
Install
Without a flag you get no styling at all — plain HTML carrying the attribute surface below. --theme copies the same theme in two dialects;--bridge lumos re-points either one onto Lumos for Astro's tokens (it needs a theme to re-point, and Lumos itself, already in your project).
Unstyled — behavior only, you write the CSS
npx astrocraft-ui add media/revealPlain-CSS theme — no build step
npx astrocraft-ui add media/reveal --theme cssTailwind theme — needs Tailwind v4
npx astrocraft-ui add media/reveal --theme tailwindPlain-CSS theme, re-pointed onto Lumos tokens
npx astrocraft-ui add media/reveal --theme css --bridge lumosTailwind theme, re-pointed onto Lumos tokens
npx astrocraft-ui add media/reveal --theme tailwind --bridge lumosLive demo
Reveal
Scroll-driven, zero-JS — sixteen entrances, every one ending at the element's resting state, so content that never scrolls into view is still readable. animate= opts a call site out entirely — the last box.
Attribute surface
With no class-merging machinery, these attributes are the whole extension point. State is a data-attribute or a native attribute; visibility is the hiddenattribute. Generated from source by pnpm slots.
| Component | Slots | Variants | Runtime state | Native state |
|---|---|---|---|---|
| `Reveal.astro` | `reveal` | `data-animation`: `fade-in` · `fade-in-up` · `fade-in-down` · `fade-in-left` · `fade-in-right` · `zoom-in` · `blur-in` · `bounce-in` · `flip-in-x` · `flip-in-y` · `rotate-in` · `roll-in` · `wipe-in-up` · `wipe-in-down` · `wipe-in-left` · `wipe-in-right` `data-range`: `entry` · `cover` · `contain` | — | — |
Source
What the command copies — 2 files, alias-free so the copy lands standing alone. This is the whole component, shown without its comments; the files you install keep them, with the reasoning behind every rule.
---
import type { HTMLAttributes } from "astro/types";
type Props = HTMLAttributes<"div"> & {
as?: keyof HTMLElementTagNameMap;
animate?: boolean;
animation?:
| "fade-in"
| "fade-in-up"
| "fade-in-down"
| "fade-in-left"
| "fade-in-right"
| "zoom-in"
| "blur-in"
| "bounce-in"
| "flip-in-x"
| "flip-in-y"
| "rotate-in"
| "roll-in"
| "wipe-in-up"
| "wipe-in-down"
| "wipe-in-left"
| "wipe-in-right";
range?: "entry" | "cover" | "contain";
};
const {
animation = "fade-in-up",
range = "entry",
as,
animate = true,
class: className,
...rest
} = Astro.props;
const Tag = as ?? "div";
---
<Tag
class={className}
data-slot="reveal"
data-animation={animate ? animation : undefined}
data-range={animate ? range : undefined}
{...rest}><slot /></Tag
>
import Reveal from "./Reveal.astro";
export { Reveal };
export default Reveal;
What you get
The component source, copied into your project by npx astrocraft-ui add media/reveal — no package dependency, no CSS to fight. Whatever the paid blocks compose, this is it.