Files
cadence-ui/apps/docs/src/components/card.stories.tsx
T

151 lines
5.7 KiB
TypeScript

import {
Button,
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle
} from "@ai-ui/ui";
import type { Meta, StoryObj } from "@storybook/react";
const meta = {
title: "Components/Card",
component: Card,
args: {
tone: "default",
interactive: true
},
argTypes: {
className: {
control: false
},
interactive: {
control: "boolean"
},
tone: {
control: "radio",
options: ["default", "subtle", "accent"]
}
},
parameters: {
docs: {
description: {
component:
"Card is the base slab surface for panels, compact workflows, and supporting information blocks. It now defaults to a gentle interactive lift so common business cards feel alive by default, while `interactive={false}` remains available for deliberately static surfaces."
}
},
layout: "centered"
},
tags: ["autodocs"]
} satisfies Meta<typeof Card>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Playground: Story = {
render: (args) => (
<Card {...args} className="w-[420px]">
<CardHeader>
<CardTitle>Routing overview</CardTitle>
<CardDescription>Keep status, ownership, and the next action in one calm surface.</CardDescription>
</CardHeader>
<CardContent>
This base card now carries a light hover lift by default so common workflow slabs do not
feel inert.
</CardContent>
<CardFooter>
<Button size="sm">Open queue</Button>
<Button size="sm" variant="ghost">
Snooze
</Button>
</CardFooter>
</Card>
)
};
export const States: Story = {
parameters: {
docs: {
description: {
story:
"Use the default interactive treatment for navigable or actionable slabs, and opt out only when the card is meant to behave like a static document section."
}
}
},
render: () => (
<div className="grid w-[920px] gap-4 md:grid-cols-3">
<Card>
<CardHeader>
<CardTitle>Default interactive</CardTitle>
<CardDescription>Gentle lift and internal light cue for most business cards.</CardDescription>
</CardHeader>
<CardContent>Good for dashboards, queues, and next-step summaries.</CardContent>
</Card>
<Card interactive={false} tone="subtle">
<CardHeader>
<CardTitle>Static document slab</CardTitle>
<CardDescription>Opt out when the surface should read as anchored reference content.</CardDescription>
</CardHeader>
<CardContent>Useful for long-form notes, legal copy, and passive explanations.</CardContent>
</Card>
<Card tone="accent">
<CardHeader>
<CardTitle>Accent emphasis</CardTitle>
<CardDescription>Carry the same motion language while keeping the tonal emphasis richer.</CardDescription>
</CardHeader>
<CardContent>Use when the card itself is part of the call to action.</CardContent>
</Card>
</div>
)
};
export const Grid: Story = {
render: () => (
<div className="relative grid w-[940px] gap-6 overflow-hidden rounded-[2.3rem] bg-[linear-gradient(180deg,color-mix(in_oklch,var(--color-surface)_82%,white_18%),color-mix(in_oklch,var(--color-background)_88%,white_12%))] p-6 shadow-[0_24px_72px_color-mix(in_oklch,var(--color-primary)_10%,transparent)] md:grid-cols-[minmax(0,0.95fr)_minmax(0,1.05fr)]">
<div className="pointer-events-none absolute inset-0">
<div className="motion-drift absolute left-[-1.5rem] top-6 h-24 w-24 rounded-full bg-[color-mix(in_oklch,var(--color-primary-container)_58%,transparent)] blur-3xl" />
<div className="motion-breathe absolute right-10 top-0 h-20 w-20 rounded-full bg-[color-mix(in_oklch,var(--color-tertiary-container)_52%,transparent)] blur-3xl" />
</div>
<div className="relative grid gap-4 self-start">
<div className="space-y-2">
<p className="text-xs uppercase tracking-[var(--tracking-caps)] text-[var(--color-muted-foreground)]">
Showcase slabs
</p>
<h3 className="max-w-sm text-3xl font-semibold tracking-[var(--tracking-tight)] text-[var(--color-foreground)]">
Cards should feel like lit objects on a display plinth, not admin rectangles.
</h3>
</div>
<div className="grid gap-3 rounded-[1.6rem] bg-[color-mix(in_oklch,var(--color-surface-container)_82%,white_18%)] p-4 shadow-[inset_0_1px_0_rgba(255,255,255,0.4)]">
<div className="h-40 rounded-[1.4rem] bg-[linear-gradient(160deg,color-mix(in_oklch,var(--color-primary-container)_78%,white_22%),color-mix(in_oklch,var(--color-tertiary-container)_74%,white_26%))]" />
<div className="grid gap-2">
<span className="h-3 w-24 rounded-full bg-[var(--color-foreground)]/12" />
<span className="h-3 w-40 rounded-full bg-[var(--color-foreground)]/9" />
</div>
</div>
</div>
<div className="relative grid gap-4">
<Card className="motion-float">
<CardHeader>
<CardTitle>Default tone</CardTitle>
<CardDescription>Standard elevated panel with the new default hover cue.</CardDescription>
</CardHeader>
<CardContent>Reliable baseline for most admin surfaces.</CardContent>
</Card>
<Card className="motion-float-delayed justify-self-end md:w-[88%]" tone="accent">
<CardHeader>
<CardTitle>Interactive accent</CardTitle>
<CardDescription>Hover-capable treatment for navigable cards.</CardDescription>
</CardHeader>
<CardContent>Use sparingly for overview screens with clear primary actions.</CardContent>
</Card>
</div>
</div>
)
};