Skip to content

Commit 9d8aa5a

Browse files
authored
Merge pull request #3 from timDeHof/feat/add_buymeacoffee
feat: enhance timeline component and project configuration
2 parents ebaf6b0 + e0bcac9 commit 9d8aa5a

File tree

74 files changed

+64452
-435
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+64452
-435
lines changed

.storybook/preview.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
import type { Preview } from '@storybook/react';
2-
import '../src/app/globals.css';
3-
42
import { withThemeByClassName } from '@storybook/addon-themes';
3+
import '@/styles/globals.css';
54

65
const preview: Preview = {
76
parameters: {
7+
actions: { argTypesRegex: '^on[A-Z].*' },
88
controls: {
99
matchers: {
1010
color: /(background|color)$/i,
1111
date: /Date$/i,
1212
},
1313
},
1414
},
15-
1615
decorators: [
1716
withThemeByClassName({
1817
themes: {
19-
// nameOfTheme: 'classNameForTheme',
20-
light: '',
18+
light: 'light',
2119
dark: 'dark',
2220
},
2321
defaultTheme: 'light',

.storybook/preview.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import type { Preview } from '@storybook/react';
3-
import '../src/app/globals.css';
3+
import '../src/styles/globals.css';
44
import { ThemeProvider } from '../src/components/providers/theme-provider';
55

66
const preview: Preview = {

README.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Shadcn Timeline Component
2+
<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>
23

3-
A beautiful, accessible, and customizable timeline component built with React and Tailwind CSS.
4+
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.
5+
6+
The same as shadcn/ui, all components are free to use for personal and commercial.
7+
8+
Just copy and paste to your project and customize to your needs. The code is yours.
49

510
## Demo & Documentation
611

@@ -98,14 +103,6 @@ export default function Example() {
98103

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

101-
## License
102-
103-
MIT
104-
105-
## Contributing
106-
107-
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
108-
109106
## Development
110107

111108
To run Storybook locally:
@@ -130,3 +127,10 @@ npm run test-storybook
130127
# Run Storybook tests with coverage
131128
npm run test-storybook:coverage
132129
```
130+
## Contributing
131+
- [Open an issue](https://github.com/timDeHof/shadcn-timeline/issues) if you believe you've encountered a bug.
132+
- 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.
133+
134+
## License
135+
136+
MIT

next.config.mjs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
11
/** @type {import('next').NextConfig} */
2-
const nextConfig = {};
2+
const nextConfig = {
3+
images: {
4+
remotePatterns: [
5+
{
6+
protocol: 'https',
7+
hostname: 'cdn.buymeacoffee.com',
8+
port: '',
9+
pathname: '/buttons/v2/**',
10+
}
11+
],
12+
},
13+
eslint: {
14+
ignoreDuringBuilds: true,
15+
}
16+
};
317

418
export default nextConfig;

src/app/data.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
export interface TimelineElement {
2-
id: number;
3-
title: string;
4-
date: string;
5-
description: string;
6-
icon?: React.ReactNode;
7-
color?: string;
8-
}
1+
import type { TimelineElement } from '@/types';
92

103
export const timelineData: TimelineElement[] = [
114
{
@@ -14,21 +7,24 @@ export const timelineData: TimelineElement[] = [
147
date: '2022-01-01',
158
description:
169
'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.',
10+
status: 'completed',
1711
},
1812
{
1913
id: 2,
2014
title: 'Second event',
2115
date: '2022-02-01',
2216
description:
2317
'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.',
18+
status: 'in-progress',
2419
},
2520
{
2621
id: 3,
2722
title: 'Third event',
2823
date: '2022-03-01',
2924
description:
3025
'Sit culpa quas ex nulla animi qui deleniti minus rem placeat mollitia. Et enim doloremque et quia sequi ea dolores voluptatem ea rerum vitae.',
26+
status: 'pending',
3127
},
3228
];
3329

34-
export type TimelineData = (typeof timelineData)[number];
30+
export type TimelineData = TimelineElement;

src/app/layout.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
import type { Metadata } from 'next';
22
import { Inter } from 'next/font/google';
3-
import './globals.css';
3+
import '@/styles/globals.css';
44
import { ThemeProvider } from '@/components/providers/theme-provider';
5+
import { metadata, viewport } from '@/config/metadata';
56

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

8-
export const metadata: Metadata = {
9-
title: 'shadcn-timeline',
10-
description: 'A customizable timeline component for Shadcn to display chronological events.',
11-
};
12-
export const viewport = {
13-
width: 'device-width',
14-
initialScale: 1,
15-
maximumScale: 1,
16-
userScalable: 1,
17-
};
9+
export { metadata, viewport };
1810

1911
export default function RootLayout({
2012
children,

src/app/page.tsx

Lines changed: 6 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -1,188 +1,14 @@
1-
import { TimelineLayout } from '@/components/timeline';
2-
import Link from 'next/link';
3-
import { Github, Calendar } from 'lucide-react';
4-
import { buttonVariants } from '@/components/ui/button';
5-
import { cn } from '@/lib/utils';
6-
import { timelineData } from './data';
7-
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
8-
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
9-
import { ThemeToggle } from '@/components/theme-toggle';
10-
import { CodeBlock } from '@/components/code-block';
11-
12-
const installCode = `# 1. Clone the repository
13-
git clone https://github.com/timDeHof/shadcn-timeline.git
14-
15-
# 2. Open the folder
16-
cd shadcn-timeline
17-
18-
# 3. Install dependencies
19-
npm install
20-
21-
# 4. Copy the timeline components to your project
22-
# Copy from:
23-
# /src/app/components/timeline/timeline-layout.tsx
24-
# /src/app/components/timeline/timeline.tsx`;
25-
26-
const usageCode = `# Add to your component:
27-
import { TimelineLayout } from "@/components/timeline/timeline-layout";
28-
29-
# Copy the timeline components to:
30-
# /src/components/timeline/timeline-layout.tsx
31-
# /src/components/timeline/timeline.tsx`;
32-
33-
const examples = {
34-
basic: {
35-
name: 'Basic',
36-
code: `<TimelineLayout
37-
items={timelineData}
38-
size="md"
39-
/>`,
40-
component: <TimelineLayout items={timelineData} size="md" />,
41-
},
42-
customIcon: {
43-
name: 'Custom Icon',
44-
code: `<TimelineLayout
45-
items={timelineData}
46-
size="lg"
47-
iconColor="primary"
48-
customIcon={<CalendarIcon />}
49-
/>`,
50-
component: (
51-
<TimelineLayout
52-
items={timelineData}
53-
size="lg"
54-
iconColor="primary"
55-
customIcon={<Calendar />}
56-
/>
57-
),
58-
},
59-
animated: {
60-
name: 'Animated',
61-
code: `<TimelineLayout
62-
items={timelineData}
63-
size="md"
64-
animate={true}
65-
/>`,
66-
component: <TimelineLayout items={timelineData} size="md" animate={true} />,
67-
},
68-
};
69-
70-
1+
import { Hero, Sidebar, Installation, Usage, Examples } from '@/components/sections';
712

723
export default function Home() {
734
return (
745
<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">
75-
{/* Sidebar */}
76-
<aside className="flex-shrink-0 md:w-64">
77-
<div className="sticky top-6">
78-
<div className="space-y-4">
79-
<div className="flex items-center justify-between">
80-
<Link href="#" className="text-2xl font-bold">
81-
shadcn-timeline
82-
</Link>
83-
<div className="flex items-center gap-2">
84-
<ThemeToggle />
85-
<Link
86-
href="https://github.com/timDeHof/shadcn-timeline"
87-
className={cn(buttonVariants({ variant: 'ghost', size: 'icon' }))}
88-
>
89-
<Github className="size-5" />
90-
</Link>
91-
</div>
92-
</div>
93-
<nav className="flex flex-col space-y-2">
94-
<Link href="#installation" className="text-muted-foreground hover:text-foreground">
95-
Installation
96-
</Link>
97-
<Link href="#usage" className="text-muted-foreground hover:text-foreground">
98-
Usage
99-
</Link>
100-
<Link href="#examples" className="text-muted-foreground hover:text-foreground">
101-
Examples
102-
</Link>
103-
</nav>
104-
</div>
105-
</div>
106-
</aside>
107-
108-
{/* Main content */}
6+
<Sidebar />
1097
<main className="flex-1 space-y-12">
110-
{/* Hero section */}
111-
<div className="space-y-2">
112-
<h1 className="scroll-m-20 text-4xl font-bold tracking-tight">Timeline</h1>
113-
<p className="text-lg text-muted-foreground">
114-
A customizable timeline component for displaying chronological events.
115-
</p>
116-
</div>
117-
118-
{/* Installation section */}
119-
<section id="installation" className="space-y-4">
120-
<h2 className="scroll-m-20 text-2xl font-semibold tracking-tight">Manual Installation</h2>
121-
<p className="mb-4 text-muted-foreground">
122-
Copy the timeline components into your project structure:
123-
</p>
124-
<div className="overflow-hidden rounded-lg">
125-
<CodeBlock code={installCode} language="bash" />
126-
</div>
127-
</section>
128-
129-
{/* Usage section */}
130-
<section id="usage" className="space-y-4">
131-
<h2 className="scroll-m-20 text-2xl font-semibold tracking-tight">Usage</h2>
132-
<div className="overflow-hidden rounded-lg">
133-
<CodeBlock code={usageCode} />
134-
</div>
135-
</section>
136-
137-
{/* Examples section */}
138-
<section id="examples" className="space-y-6">
139-
<h2 className="scroll-m-20 text-2xl font-semibold tracking-tight">Examples</h2>
140-
<div className="grid gap-6">
141-
{Object.entries(examples).map(([key, example]) => (
142-
<Card key={key} id={example.name}>
143-
<CardHeader>
144-
<CardTitle className="scroll-m-20 text-xl font-semibold tracking-tight">
145-
{example.name}
146-
</CardTitle>
147-
</CardHeader>
148-
<CardContent className="group relative my-4 flex flex-col space-y-2 [&_input]:max-w-xs">
149-
<Tabs defaultValue="preview" className="mr-auto w-full">
150-
<TabsList className="inline-flex h-9 w-full items-center justify-start rounded-none border-b bg-transparent p-0 text-muted-foreground">
151-
<TabsTrigger
152-
value="preview"
153-
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"
154-
>
155-
Preview
156-
</TabsTrigger>
157-
<TabsTrigger
158-
value="code"
159-
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"
160-
>
161-
Code
162-
</TabsTrigger>
163-
</TabsList>
164-
<TabsContent
165-
value="preview"
166-
className="relative mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
167-
>
168-
<div className="w-full">
169-
<div className="flex min-h-[350px] w-full items-center justify-center">
170-
{example.component}
171-
</div>
172-
</div>
173-
</TabsContent>
174-
<TabsContent
175-
value="code"
176-
className="mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
177-
>
178-
<CodeBlock code={example.code} />
179-
</TabsContent>
180-
</Tabs>
181-
</CardContent>
182-
</Card>
183-
))}
184-
</div>
185-
</section>
8+
<Hero />
9+
<Installation />
10+
<Usage />
11+
<Examples />
18612
</main>
18713
</div>
18814
);

0 commit comments

Comments
 (0)