design system token v0.1
This commit is contained in:
111
stories/Composition/CTASection.stories.tsx
Normal file
111
stories/Composition/CTASection.stories.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import { CTASection } from '@/components/ui/cta-section'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
const meta = {
|
||||
title: 'Composition/CTASection',
|
||||
component: CTASection,
|
||||
tags: ['autodocs'],
|
||||
parameters: { layout: 'fullscreen' },
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: 'select',
|
||||
options: ['centered', 'left-aligned'],
|
||||
},
|
||||
background: {
|
||||
control: 'select',
|
||||
options: ['default', 'muted', 'accent', 'subtle'],
|
||||
},
|
||||
},
|
||||
} satisfies Meta<typeof CTASection>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
const defaultActions = (
|
||||
<>
|
||||
<Button size="lg">Get Started</Button>
|
||||
<Button size="lg" variant="outline">Contact Sales</Button>
|
||||
</>
|
||||
)
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
heading: 'Ready to get started?',
|
||||
description: 'Join thousands of teams building better products with our design system.',
|
||||
actions: defaultActions,
|
||||
},
|
||||
}
|
||||
|
||||
export const Centered: Story = {
|
||||
args: {
|
||||
variant: 'centered',
|
||||
background: 'muted',
|
||||
heading: 'Start building today',
|
||||
description: 'Free for open source. Affordable for teams.',
|
||||
actions: defaultActions,
|
||||
},
|
||||
}
|
||||
|
||||
export const LeftAligned: Story = {
|
||||
args: {
|
||||
variant: 'left-aligned',
|
||||
background: 'muted',
|
||||
heading: 'Need help getting started?',
|
||||
description: 'Our team is ready to help you integrate the design system into your project.',
|
||||
actions: (
|
||||
<>
|
||||
<Button size="lg">Talk to us</Button>
|
||||
</>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
export const AccentBackground: Story = {
|
||||
args: {
|
||||
variant: 'centered',
|
||||
background: 'accent',
|
||||
heading: 'Upgrade your workflow',
|
||||
description: 'Take your team to the next level with our premium plan.',
|
||||
actions: (
|
||||
<>
|
||||
<Button size="lg" variant="secondary">Start Free Trial</Button>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="outline"
|
||||
className="border-primary-foreground/20 text-primary-foreground hover:bg-primary-foreground/10"
|
||||
>
|
||||
Learn More
|
||||
</Button>
|
||||
</>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
export const SubtleBackground: Story = {
|
||||
args: {
|
||||
variant: 'centered',
|
||||
background: 'subtle',
|
||||
heading: 'Stay in the loop',
|
||||
description: 'Subscribe to our newsletter for the latest updates and releases.',
|
||||
actions: (
|
||||
<Button size="lg">Subscribe</Button>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
export const DefaultBackground: Story = {
|
||||
args: {
|
||||
variant: 'centered',
|
||||
background: 'default',
|
||||
heading: 'Questions? We have answers.',
|
||||
description: 'Check out our documentation or reach out to our support team.',
|
||||
actions: (
|
||||
<>
|
||||
<Button size="lg">View Docs</Button>
|
||||
<Button size="lg" variant="ghost">Contact Support</Button>
|
||||
</>
|
||||
),
|
||||
},
|
||||
}
|
||||
92
stories/Composition/Footer.stories.tsx
Normal file
92
stories/Composition/Footer.stories.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import { Footer } from '@/components/ui/footer'
|
||||
import { Logo } from '@/components/ui/logo'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
const meta = {
|
||||
title: 'Composition/Footer',
|
||||
component: Footer,
|
||||
tags: ['autodocs'],
|
||||
parameters: { layout: 'fullscreen' },
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: 'select',
|
||||
options: ['minimal', 'full'],
|
||||
},
|
||||
},
|
||||
} satisfies Meta<typeof Footer>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Minimal: Story = {
|
||||
args: {
|
||||
variant: 'minimal',
|
||||
logo: <Logo size="sm" />,
|
||||
copyright: <>© 2026 Greyhaven. All rights reserved.</>,
|
||||
actions: (
|
||||
<div className="flex gap-4 text-sm text-muted-foreground">
|
||||
<a href="#" className="hover:text-foreground transition-colors">Privacy</a>
|
||||
<a href="#" className="hover:text-foreground transition-colors">Terms</a>
|
||||
<a href="#" className="hover:text-foreground transition-colors">Contact</a>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
export const Full: Story = {
|
||||
args: {
|
||||
variant: 'full',
|
||||
logo: <Logo size="md" />,
|
||||
copyright: <>© 2026 Greyhaven. All rights reserved.</>,
|
||||
linkGroups: [
|
||||
{
|
||||
title: 'Product',
|
||||
links: [
|
||||
{ label: 'Features', href: '#' },
|
||||
{ label: 'Pricing', href: '#' },
|
||||
{ label: 'Changelog', href: '#' },
|
||||
{ label: 'Docs', href: '#' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Company',
|
||||
links: [
|
||||
{ label: 'About', href: '#' },
|
||||
{ label: 'Blog', href: '#' },
|
||||
{ label: 'Careers', href: '#' },
|
||||
{ label: 'Contact', href: '#' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Legal',
|
||||
links: [
|
||||
{ label: 'Privacy Policy', href: '#' },
|
||||
{ label: 'Terms of Service', href: '#' },
|
||||
{ label: 'Cookie Policy', href: '#' },
|
||||
],
|
||||
},
|
||||
],
|
||||
actions: (
|
||||
<div className="flex gap-2">
|
||||
<Button variant="ghost" size="sm">Twitter</Button>
|
||||
<Button variant="ghost" size="sm">GitHub</Button>
|
||||
<Button variant="ghost" size="sm">Discord</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
export const MinimalNoCopyright: Story = {
|
||||
args: {
|
||||
variant: 'minimal',
|
||||
logo: <Logo size="sm" />,
|
||||
actions: (
|
||||
<div className="flex gap-4 text-sm text-muted-foreground">
|
||||
<a href="#" className="hover:text-foreground transition-colors">Docs</a>
|
||||
<a href="#" className="hover:text-foreground transition-colors">GitHub</a>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
}
|
||||
111
stories/Composition/Hero.stories.tsx
Normal file
111
stories/Composition/Hero.stories.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import { Hero } from '@/components/ui/hero'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
const meta = {
|
||||
title: 'Composition/Hero',
|
||||
component: Hero,
|
||||
tags: ['autodocs'],
|
||||
parameters: { layout: 'fullscreen' },
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: 'select',
|
||||
options: ['centered', 'left-aligned', 'split'],
|
||||
},
|
||||
background: {
|
||||
control: 'select',
|
||||
options: ['default', 'muted', 'accent', 'dark'],
|
||||
},
|
||||
},
|
||||
} satisfies Meta<typeof Hero>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
const defaultActions = (
|
||||
<>
|
||||
<Button size="lg">Get Started</Button>
|
||||
<Button size="lg" variant="outline">Learn More</Button>
|
||||
</>
|
||||
)
|
||||
|
||||
export const Centered: Story = {
|
||||
args: {
|
||||
variant: 'centered',
|
||||
heading: 'Build better products with Greyhaven',
|
||||
subheading:
|
||||
'A modern design system that helps you create consistent, accessible, and beautiful user interfaces.',
|
||||
actions: defaultActions,
|
||||
},
|
||||
}
|
||||
|
||||
export const LeftAligned: Story = {
|
||||
args: {
|
||||
variant: 'left-aligned',
|
||||
heading: 'Ship faster with confidence',
|
||||
subheading:
|
||||
'Pre-built components, design tokens, and patterns so your team can focus on what matters.',
|
||||
actions: defaultActions,
|
||||
},
|
||||
}
|
||||
|
||||
export const Split: Story = {
|
||||
args: {
|
||||
variant: 'split',
|
||||
heading: 'Design meets engineering',
|
||||
subheading:
|
||||
'Bridging the gap between design and code with a shared language of components and tokens.',
|
||||
actions: defaultActions,
|
||||
media: (
|
||||
<div className="w-full aspect-video bg-muted rounded-lg flex items-center justify-center text-muted-foreground">
|
||||
Image / Media Placeholder
|
||||
</div>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
export const MutedBackground: Story = {
|
||||
args: {
|
||||
variant: 'centered',
|
||||
background: 'muted',
|
||||
heading: 'Welcome to the platform',
|
||||
subheading: 'Everything you need to build and scale your project.',
|
||||
actions: defaultActions,
|
||||
},
|
||||
}
|
||||
|
||||
export const AccentBackground: Story = {
|
||||
args: {
|
||||
variant: 'centered',
|
||||
background: 'accent',
|
||||
heading: 'Start building today',
|
||||
subheading: 'Join thousands of developers using our design system.',
|
||||
actions: defaultActions,
|
||||
},
|
||||
}
|
||||
|
||||
export const DarkBackground: Story = {
|
||||
args: {
|
||||
variant: 'centered',
|
||||
background: 'dark',
|
||||
heading: 'The future of design systems',
|
||||
subheading: 'A bold new approach to building consistent user interfaces at scale.',
|
||||
actions: (
|
||||
<>
|
||||
<Button size="lg" variant="secondary">Get Started</Button>
|
||||
<Button size="lg" variant="outline" className="border-background/20 text-background hover:bg-background/10">
|
||||
Learn More
|
||||
</Button>
|
||||
</>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
export const WithoutActions: Story = {
|
||||
args: {
|
||||
variant: 'centered',
|
||||
heading: 'A hero section without action buttons',
|
||||
subheading: 'Sometimes you just need a heading and description.',
|
||||
},
|
||||
}
|
||||
167
stories/Composition/PageLayout.stories.tsx
Normal file
167
stories/Composition/PageLayout.stories.tsx
Normal file
@@ -0,0 +1,167 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import { PageLayout } from '@/components/ui/page-layout'
|
||||
import { Navbar, NavbarLink } from '@/components/ui/navbar'
|
||||
import { Footer } from '@/components/ui/footer'
|
||||
import { Hero } from '@/components/ui/hero'
|
||||
import { Section } from '@/components/ui/section'
|
||||
import { CTASection } from '@/components/ui/cta-section'
|
||||
import { Logo } from '@/components/ui/logo'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardDescription,
|
||||
CardContent,
|
||||
} from '@/components/ui/card'
|
||||
|
||||
const meta = {
|
||||
title: 'Composition/PageLayout',
|
||||
component: PageLayout,
|
||||
tags: ['autodocs'],
|
||||
parameters: { layout: 'fullscreen' },
|
||||
} satisfies Meta<typeof PageLayout>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
const navLinks = (
|
||||
<>
|
||||
<NavbarLink href="#" active>Home</NavbarLink>
|
||||
<NavbarLink href="#">Features</NavbarLink>
|
||||
<NavbarLink href="#">Pricing</NavbarLink>
|
||||
<NavbarLink href="#">Docs</NavbarLink>
|
||||
</>
|
||||
)
|
||||
|
||||
const navActions = (
|
||||
<>
|
||||
<Button variant="ghost" size="sm">Log in</Button>
|
||||
<Button size="sm">Sign up</Button>
|
||||
</>
|
||||
)
|
||||
|
||||
const sampleNavbar = (
|
||||
<Navbar
|
||||
variant="solid"
|
||||
logo={<Logo size="sm" />}
|
||||
actions={navActions}
|
||||
>
|
||||
{navLinks}
|
||||
</Navbar>
|
||||
)
|
||||
|
||||
const sampleFooter = (
|
||||
<Footer
|
||||
variant="minimal"
|
||||
logo={<Logo size="sm" />}
|
||||
copyright={<>© 2026 Greyhaven. All rights reserved.</>}
|
||||
actions={
|
||||
<div className="flex gap-4 text-sm text-muted-foreground">
|
||||
<a href="#" className="hover:text-foreground transition-colors">Privacy</a>
|
||||
<a href="#" className="hover:text-foreground transition-colors">Terms</a>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
)
|
||||
|
||||
export const FullPage: Story = {
|
||||
args: {
|
||||
navbar: sampleNavbar,
|
||||
footer: sampleFooter,
|
||||
children: (
|
||||
<>
|
||||
<Hero
|
||||
variant="centered"
|
||||
heading="Build something great"
|
||||
subheading="A complete design system for modern web applications."
|
||||
actions={
|
||||
<>
|
||||
<Button size="lg">Get Started</Button>
|
||||
<Button size="lg" variant="outline">View Docs</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Section
|
||||
title="Features"
|
||||
description="Everything you need to build beautiful interfaces."
|
||||
>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{['Components', 'Tokens', 'Patterns'].map((title) => (
|
||||
<Card key={title}>
|
||||
<CardHeader>
|
||||
<CardTitle>{title}</CardTitle>
|
||||
<CardDescription>
|
||||
Pre-built {title.toLowerCase()} for rapid development.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Fully customizable {title.toLowerCase()} that follow best practices.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
<CTASection
|
||||
background="muted"
|
||||
heading="Ready to start?"
|
||||
description="Get up and running in minutes."
|
||||
actions={<Button size="lg">Get Started Free</Button>}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
export const WithSidebar: Story = {
|
||||
args: {
|
||||
navbar: sampleNavbar,
|
||||
footer: sampleFooter,
|
||||
sidebar: (
|
||||
<nav className="p-4 space-y-2">
|
||||
<h3 className="font-semibold text-sm mb-4">Navigation</h3>
|
||||
{['Dashboard', 'Projects', 'Team', 'Settings'].map((item) => (
|
||||
<a
|
||||
key={item}
|
||||
href="#"
|
||||
className="block px-3 py-2 text-sm rounded-md text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
|
||||
>
|
||||
{item}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
),
|
||||
children: (
|
||||
<Section title="Dashboard" description="Overview of your workspace.">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{['Revenue', 'Users', 'Orders', 'Growth'].map((metric) => (
|
||||
<Card key={metric}>
|
||||
<CardHeader>
|
||||
<CardTitle>{metric}</CardTitle>
|
||||
<CardDescription>Last 30 days</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-2xl font-bold">1,234</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
export const ContentOnly: Story = {
|
||||
args: {
|
||||
children: (
|
||||
<Section title="Standalone Content" description="A page layout with no navbar or footer.">
|
||||
<p className="text-muted-foreground">
|
||||
This demonstrates the PageLayout component with only content, no navbar, sidebar, or footer.
|
||||
</p>
|
||||
</Section>
|
||||
),
|
||||
},
|
||||
}
|
||||
135
stories/Composition/Section.stories.tsx
Normal file
135
stories/Composition/Section.stories.tsx
Normal file
@@ -0,0 +1,135 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import { Section } from '@/components/ui/section'
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardDescription,
|
||||
CardContent,
|
||||
} from '@/components/ui/card'
|
||||
|
||||
const meta = {
|
||||
title: 'Composition/Section',
|
||||
component: Section,
|
||||
tags: ['autodocs'],
|
||||
parameters: { layout: 'fullscreen' },
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: 'select',
|
||||
options: ['default', 'highlighted', 'accent'],
|
||||
},
|
||||
width: {
|
||||
control: 'select',
|
||||
options: ['narrow', 'default', 'wide', 'full'],
|
||||
},
|
||||
},
|
||||
} satisfies Meta<typeof Section>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
const sampleCards = (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{['Design', 'Develop', 'Deploy'].map((title) => (
|
||||
<Card key={title}>
|
||||
<CardHeader>
|
||||
<CardTitle>{title}</CardTitle>
|
||||
<CardDescription>Description for the {title.toLowerCase()} phase.</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Content explaining the {title.toLowerCase()} process in detail.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
title: 'Our Process',
|
||||
description: 'How we build great products from concept to delivery.',
|
||||
children: sampleCards,
|
||||
},
|
||||
}
|
||||
|
||||
export const Highlighted: Story = {
|
||||
args: {
|
||||
variant: 'highlighted',
|
||||
title: 'Featured Section',
|
||||
description: 'This section uses a highlighted background to stand out.',
|
||||
children: sampleCards,
|
||||
},
|
||||
}
|
||||
|
||||
export const Accent: Story = {
|
||||
args: {
|
||||
variant: 'accent',
|
||||
title: 'Accent Section',
|
||||
description: 'A subtle accent background to differentiate this area.',
|
||||
children: sampleCards,
|
||||
},
|
||||
}
|
||||
|
||||
export const Narrow: Story = {
|
||||
args: {
|
||||
width: 'narrow',
|
||||
title: 'Narrow Section',
|
||||
description: 'Constrained width for focused reading.',
|
||||
children: (
|
||||
<p className="text-muted-foreground">
|
||||
This is a narrow section with max-w-3xl. Useful for text-heavy content that
|
||||
benefits from shorter line lengths for readability.
|
||||
</p>
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
export const Wide: Story = {
|
||||
args: {
|
||||
width: 'wide',
|
||||
title: 'Wide Section',
|
||||
description: 'Extended width for content-rich layouts.',
|
||||
children: sampleCards,
|
||||
},
|
||||
}
|
||||
|
||||
export const Full: Story = {
|
||||
args: {
|
||||
width: 'full',
|
||||
variant: 'highlighted',
|
||||
title: 'Full Width Section',
|
||||
description: 'Spans the full width of the viewport.',
|
||||
children: sampleCards,
|
||||
},
|
||||
}
|
||||
|
||||
export const NoHeader: Story = {
|
||||
args: {
|
||||
children: sampleCards,
|
||||
},
|
||||
}
|
||||
|
||||
export const AllCombinations: Story = {
|
||||
render: () => (
|
||||
<div>
|
||||
{(['default', 'highlighted', 'accent'] as const).map((variant) =>
|
||||
(['narrow', 'default', 'wide'] as const).map((width) => (
|
||||
<Section
|
||||
key={`${variant}-${width}`}
|
||||
variant={variant}
|
||||
width={width}
|
||||
title={`${variant} / ${width}`}
|
||||
description={`Section with variant="${variant}" and width="${width}".`}
|
||||
>
|
||||
<div className="h-20 rounded-lg border-2 border-dashed border-muted-foreground/25 flex items-center justify-center text-sm text-muted-foreground">
|
||||
Content area
|
||||
</div>
|
||||
</Section>
|
||||
)),
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
}
|
||||
Reference in New Issue
Block a user