Kosmesis
Components

Animated List

A list whose items fade/slide in with a per-item stagger delay. Purely presentational — no Morphos equivalent.

Installation

npx kosmesis add animated-list
pnpm dlx kosmesis add animated-list
yarn dlx kosmesis add animated-list
bunx kosmesis add animated-list

Copy and paste the following code into your project.

animated-list.tsx
import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import type { Children } from "@praxisjs/shared";import { cn } from "@/lib/utils";export interface AnimatedListProps {  class?: string;  id?: string;  children?: Children;}@Component()export class AnimatedList extends StatelessComponent<AnimatedListProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <div id={id} data-slot="animated-list" class={cn("flex flex-col gap-2", cls)}>        {children}      </div>    );  }}export interface AnimatedListItemProps {  index?: number;  class?: string;  id?: string;  children?: Children;}// Stagger delay is inline (a dynamic per-item value, so it can't be a static Tailwind class).@Component()export class AnimatedListItem extends StatelessComponent<AnimatedListItemProps> {  render() {    const { index = 0, class: cls, id, children } = this.props;    return (      <div        id={id}        data-slot="animated-list-item"        class={cn("animate-in fade-in slide-in-from-top-2", cls)}        style={{ animationDelay: `${String(index * 80)}ms`, animationDuration: "300ms", animationFillMode: "backwards" }}      >        {children}      </div>    );  }}

Install the following dependencies:

npm install @praxisjs/css
pnpm add @praxisjs/css
yarn add @praxisjs/css
bun add @praxisjs/css

Copy and paste the following code into your project.

animated-list.tsx
import { StatelessComponent } from "@praxisjs/core";import { cx, keyframes, Stylesheet, Styled } from "@praxisjs/css";import { Component } from "@praxisjs/decorators";import type { Children } from "@praxisjs/shared";const fadeSlideIn = keyframes("kosmesis-animated-list-item", {  from: { opacity: "0", transform: "translateY(-0.5rem)" },  to: { opacity: "1", transform: "translateY(0)" },});class AnimatedListStyles extends Stylesheet {  $root = this.css({ display: "flex", flexDirection: "column", gap: "0.5rem" });  $item = this.css({ animation: `${fadeSlideIn} 300ms ease both` });}export interface AnimatedListProps {  class?: string;  id?: string;  children?: Children;}@Component()export class AnimatedList extends StatelessComponent<AnimatedListProps> {  @Styled(AnimatedListStyles) $s!: AnimatedListStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <div id={id} data-slot="animated-list" class={cx(this.$s.$root, cls)}>        {children}      </div>    );  }}export interface AnimatedListItemProps {  index?: number;  class?: string;  id?: string;  children?: Children;}// Stagger delay is inline (a dynamic per-item value, so it can't be a static class).@Component()export class AnimatedListItem extends StatelessComponent<AnimatedListItemProps> {  @Styled(AnimatedListStyles) $s!: AnimatedListStyles;  render() {    const { index = 0, class: cls, id, children } = this.props;    return (      <div        id={id}        data-slot="animated-list-item"        class={cx(this.$s.$item, cls)}        style={{ animationDelay: `${String(index * 80)}ms` }}      >        {children}      </div>    );  }}

Examples

About

Purely presentational — no Morphos equivalent. The Tailwind flavor reuses tw-animate-css's animate-in/fade-in/slide-in-from-top utilities (already a Kosmesis runtime dependency, see Dialog/Popover); the @praxisjs/css flavor defines the same fade+slide as a local keyframes(). Either way, the per-item stagger delay (index * 80ms) is a dynamic value applied via inline style.

Usage

import { AnimatedList, AnimatedListItem } from "@/components/ui/animated-list";

<AnimatedList>
  {items.map((item, i) => (
    <AnimatedListItem key={item.id} index={i}>{item.text}</AnimatedListItem>
  ))}
</AnimatedList>

Props

AnimatedListItem

PropTypeDefault
indexnumber0
classstring

AnimatedList accepts class, id, and children only.

On this page