Skip to content

Commit

Permalink
Merge pull request #3 from timDeHof/feat/add_buymeacoffee
Browse files Browse the repository at this point in the history
feat: enhance timeline component and project configuration
  • Loading branch information
timDeHof authored Jan 3, 2025
2 parents ebaf6b0 + e0bcac9 commit 9d8aa5a
Show file tree
Hide file tree
Showing 74 changed files with 64,452 additions and 435 deletions.
8 changes: 3 additions & 5 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import type { Preview } from '@storybook/react';
import '../src/app/globals.css';

import { withThemeByClassName } from '@storybook/addon-themes';
import '@/styles/globals.css';

const preview: Preview = {
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},

decorators: [
withThemeByClassName({
themes: {
// nameOfTheme: 'classNameForTheme',
light: '',
light: 'light',
dark: 'dark',
},
defaultTheme: 'light',
Expand Down
2 changes: 1 addition & 1 deletion .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import type { Preview } from '@storybook/react';
import '../src/app/globals.css';
import '../src/styles/globals.css';
import { ThemeProvider } from '../src/components/providers/theme-provider';

const preview: Preview = {
Expand Down
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Shadcn Timeline Component
<a href="https://www.buymeacoffee.com/timDeHof" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>

A beautiful, accessible, and customizable timeline component built with React and Tailwind CSS.
A beautiful, accessible, and customizable timeline component built on top of <a href="https://shadcn.com" target="_blank">shadcn/ui</a> with React and Tailwind CSS.

The same as shadcn/ui, all components are free to use for personal and commercial.

Just copy and paste to your project and customize to your needs. The code is yours.

## Demo & Documentation

Expand Down Expand Up @@ -98,14 +103,6 @@ export default function Example() {

The component is fully SSR compatible and handles hydration properly. Date formatting is handled on the client side to prevent hydration mismatches.

## License

MIT

## Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

## Development

To run Storybook locally:
Expand All @@ -130,3 +127,10 @@ npm run test-storybook
# Run Storybook tests with coverage
npm run test-storybook:coverage
```
## Contributing
- [Open an issue](https://github.com/timDeHof/shadcn-timeline/issues) if you believe you've encountered a bug.
- Make a [Pull request](https://github.com/timDeHof/shadcn-timeline/pulls) if you want to add a new feature/make quality of life improvements/ fix bugs.

## License

MIT
16 changes: 15 additions & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.buymeacoffee.com',
port: '',
pathname: '/buttons/v2/**',
}
],
},
eslint: {
ignoreDuringBuilds: true,
}
};

export default nextConfig;
14 changes: 5 additions & 9 deletions src/app/data.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
export interface TimelineElement {
id: number;
title: string;
date: string;
description: string;
icon?: React.ReactNode;
color?: string;
}
import type { TimelineElement } from '@/types';

export const timelineData: TimelineElement[] = [
{
Expand All @@ -14,21 +7,24 @@ export const timelineData: TimelineElement[] = [
date: '2022-01-01',
description:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Odio euismod lacinia at quis risus sed vulputate odio ut. Quam viverra orci sagittis eu volutpat odio facilisis mauris.',
status: 'completed',
},
{
id: 2,
title: 'Second event',
date: '2022-02-01',
description:
'Aut eius excepturi ex recusandae eius est minima molestiae. Nam dolores iusto ad fugit reprehenderit hic dolorem quisquam et quia omnis non suscipit nihil sit.',
status: 'in-progress',
},
{
id: 3,
title: 'Third event',
date: '2022-03-01',
description:
'Sit culpa quas ex nulla animi qui deleniti minus rem placeat mollitia. Et enim doloremque et quia sequi ea dolores voluptatem ea rerum vitae.',
status: 'pending',
},
];

export type TimelineData = (typeof timelineData)[number];
export type TimelineData = TimelineElement;
14 changes: 3 additions & 11 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';
import '@/styles/globals.css';
import { ThemeProvider } from '@/components/providers/theme-provider';
import { metadata, viewport } from '@/config/metadata';

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
title: 'shadcn-timeline',
description: 'A customizable timeline component for Shadcn to display chronological events.',
};
export const viewport = {
width: 'device-width',
initialScale: 1,
maximumScale: 1,
userScalable: 1,
};
export { metadata, viewport };

export default function RootLayout({
children,
Expand Down
186 changes: 6 additions & 180 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,188 +1,14 @@
import { TimelineLayout } from '@/components/timeline';
import Link from 'next/link';
import { Github, Calendar } from 'lucide-react';
import { buttonVariants } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import { timelineData } from './data';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { ThemeToggle } from '@/components/theme-toggle';
import { CodeBlock } from '@/components/code-block';

const installCode = `# 1. Clone the repository
git clone https://github.com/timDeHof/shadcn-timeline.git
# 2. Open the folder
cd shadcn-timeline
# 3. Install dependencies
npm install
# 4. Copy the timeline components to your project
# Copy from:
# /src/app/components/timeline/timeline-layout.tsx
# /src/app/components/timeline/timeline.tsx`;

const usageCode = `# Add to your component:
import { TimelineLayout } from "@/components/timeline/timeline-layout";
# Copy the timeline components to:
# /src/components/timeline/timeline-layout.tsx
# /src/components/timeline/timeline.tsx`;

const examples = {
basic: {
name: 'Basic',
code: `<TimelineLayout
items={timelineData}
size="md"
/>`,
component: <TimelineLayout items={timelineData} size="md" />,
},
customIcon: {
name: 'Custom Icon',
code: `<TimelineLayout
items={timelineData}
size="lg"
iconColor="primary"
customIcon={<CalendarIcon />}
/>`,
component: (
<TimelineLayout
items={timelineData}
size="lg"
iconColor="primary"
customIcon={<Calendar />}
/>
),
},
animated: {
name: 'Animated',
code: `<TimelineLayout
items={timelineData}
size="md"
animate={true}
/>`,
component: <TimelineLayout items={timelineData} size="md" animate={true} />,
},
};


import { Hero, Sidebar, Installation, Usage, Examples } from '@/components/sections';

export default function Home() {
return (
<div className="container flex min-h-screen w-full flex-col space-y-8 pb-16 pt-6 md:flex-row md:space-x-8 md:space-y-0 md:px-8">
{/* Sidebar */}
<aside className="flex-shrink-0 md:w-64">
<div className="sticky top-6">
<div className="space-y-4">
<div className="flex items-center justify-between">
<Link href="#" className="text-2xl font-bold">
shadcn-timeline
</Link>
<div className="flex items-center gap-2">
<ThemeToggle />
<Link
href="https://github.com/timDeHof/shadcn-timeline"
className={cn(buttonVariants({ variant: 'ghost', size: 'icon' }))}
>
<Github className="size-5" />
</Link>
</div>
</div>
<nav className="flex flex-col space-y-2">
<Link href="#installation" className="text-muted-foreground hover:text-foreground">
Installation
</Link>
<Link href="#usage" className="text-muted-foreground hover:text-foreground">
Usage
</Link>
<Link href="#examples" className="text-muted-foreground hover:text-foreground">
Examples
</Link>
</nav>
</div>
</div>
</aside>

{/* Main content */}
<Sidebar />
<main className="flex-1 space-y-12">
{/* Hero section */}
<div className="space-y-2">
<h1 className="scroll-m-20 text-4xl font-bold tracking-tight">Timeline</h1>
<p className="text-lg text-muted-foreground">
A customizable timeline component for displaying chronological events.
</p>
</div>

{/* Installation section */}
<section id="installation" className="space-y-4">
<h2 className="scroll-m-20 text-2xl font-semibold tracking-tight">Manual Installation</h2>
<p className="mb-4 text-muted-foreground">
Copy the timeline components into your project structure:
</p>
<div className="overflow-hidden rounded-lg">
<CodeBlock code={installCode} language="bash" />
</div>
</section>

{/* Usage section */}
<section id="usage" className="space-y-4">
<h2 className="scroll-m-20 text-2xl font-semibold tracking-tight">Usage</h2>
<div className="overflow-hidden rounded-lg">
<CodeBlock code={usageCode} />
</div>
</section>

{/* Examples section */}
<section id="examples" className="space-y-6">
<h2 className="scroll-m-20 text-2xl font-semibold tracking-tight">Examples</h2>
<div className="grid gap-6">
{Object.entries(examples).map(([key, example]) => (
<Card key={key} id={example.name}>
<CardHeader>
<CardTitle className="scroll-m-20 text-xl font-semibold tracking-tight">
{example.name}
</CardTitle>
</CardHeader>
<CardContent className="group relative my-4 flex flex-col space-y-2 [&_input]:max-w-xs">
<Tabs defaultValue="preview" className="mr-auto w-full">
<TabsList className="inline-flex h-9 w-full items-center justify-start rounded-none border-b bg-transparent p-0 text-muted-foreground">
<TabsTrigger
value="preview"
className="relative inline-flex h-9 items-center justify-center whitespace-nowrap rounded-none border-b-2 border-b-transparent bg-transparent px-4 py-1 pb-3 pt-2 text-sm font-semibold text-muted-foreground shadow-none ring-offset-background transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:border-b-primary data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-none"
>
Preview
</TabsTrigger>
<TabsTrigger
value="code"
className="relative inline-flex h-9 items-center justify-center whitespace-nowrap rounded-none border-b-2 border-b-transparent bg-transparent px-4 py-1 pb-3 pt-2 text-sm font-semibold text-muted-foreground shadow-none ring-offset-background transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:border-b-primary data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-none"
>
Code
</TabsTrigger>
</TabsList>
<TabsContent
value="preview"
className="relative mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<div className="w-full">
<div className="flex min-h-[350px] w-full items-center justify-center">
{example.component}
</div>
</div>
</TabsContent>
<TabsContent
value="code"
className="mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<CodeBlock code={example.code} />
</TabsContent>
</Tabs>
</CardContent>
</Card>
))}
</div>
</section>
<Hero />
<Installation />
<Usage />
<Examples />
</main>
</div>
);
Expand Down
Loading

0 comments on commit 9d8aa5a

Please sign in to comment.