Listicle short
Vertical numbered list: a title, then one scene per item with its number, point and optional image.
ListicleShort, defaults
Installation
npx shadcn add https://www.reelcn.dev/r/listicle-short.jsonFiles land in src/reelcn/ with the items it builds on. Dependencies: zod.
Register the composition
<Composition
id="ListicleShort"
component={ListicleShort}
schema={listicleShortSchema}
defaultProps={listicleShortDefaults}
calculateMetadata={listicleShortMetadata}
width={1080}
height={1920}
fps={30}
durationInFrames={1}
/>Render
npx remotion render ListicleShort # 16:9
npx remotion render ListicleShort --width=1080 --height=1920 # 9:16Props
PropTypeDescription
title*string
items*{ title: string; body?: string; image?: string; }[]
theme"daylight" | "midnight" | "mono" | "ledger" | "afterglow" | "chromewave" | "neon" | "paper" | "sunset"Theme preset. Inherits the surrounding `ThemeProvider` when omitted.
brand{ accent?: string; logo?: string; font?: string; }
sfxbooleanPlays a soft whoosh as each scene starts.
musicstringBackground music file, looped under everything at 25% volume.
Built from
Use
- "Three ways to…" and top-five shorts
- Splitting a blog post into a quick video
Avoid
- Mixed scene types. Use
storyboard
Make it with an agent
With the reelcn agent skill installed, ask for the video in plain words, such as "make a launch video for Relay with reelcn". The skill picks a template, sets its props, reviews a contact sheet and renders.
Guides
Components take their colors from a theme, their timing from motion props and their layout from the canvas.
Source
registry/items/listicle-short.tsx
/**
* @title Listicle Short
* @category templates
* @description Vertical numbered list: a title, then one scene per item with its number, point and optional image.
* @duration data-driven
* @use "Three ways to…" and top-five shorts
* @use Splitting a blog post into a quick video
* @avoid Mixed scene types. Use `storyboard`
* @tags listicle, list, short, top, template
* @example
* <Composition
* id="ListicleShort"
* component={ListicleShort}
* schema={listicleShortSchema}
* defaultProps={listicleShortDefaults}
* calculateMetadata={listicleShortMetadata}
* width={1080}
* height={1920}
* fps={30}
* durationInFrames={1}
* />
*/
import { z } from "zod";
import type { Scene, Story } from "./story";
import { Storyboard, templateMetadata, templateSchema, templateStory } from "./storyboard";
export const listicleShortSchema = templateSchema.extend({
title: z.string(),
items: z.array(z.object({ title: z.string(), body: z.string().optional(), image: z.string().optional() })).min(1),
});
export type ListicleShortProps = z.infer<typeof listicleShortSchema>;
export const listicleShortDefaults: ListicleShortProps = {
title: "Three habits of teams that ship weekly",
items: [
{ title: "Small pull requests", body: "Nothing over three hundred lines." },
{ title: "A fixed release day", body: "Thursday, every week." },
{ title: "One owner per launch", body: "Someone whose name is on it." },
],
};
export function listicleShortStory(props: ListicleShortProps): Story {
const { title, items } = props;
return templateStory(
props,
[
{ type: "title", title, background: "aurora" },
...items.map(
(item, index): Scene =>
item.image
? { type: "image", src: item.image, caption: `${index + 1}. ${item.title}` }
: { type: "title", kicker: `${index + 1} of ${items.length}`, title: item.title, subtitle: item.body },
),
],
"slice-slide",
);
}
export function ListicleShort(props: ListicleShortProps) {
return <Storyboard story={listicleShortStory(props)} />;
}
export const listicleShortMetadata = templateMetadata(listicleShortStory);