shadcn-timeline
repository·main·Indexed 43 days ago
https://github.com/timdehof/shadcn-timelineAn accessible and customizable timeline component built on shadcn/ui using React, Tailwind CSS, and Framer Motion. Version 0.1.0 features a Timeline container and TimelineItem components with support for various statuses (completed, in-progress, pending), custom icons, and SSR compatibility.
What's inside shadcn-timeline
- The component is fully SSR compatible and handles hydration properly. To prevent hydration mismatches, date formatting is handled on the client side.
Install the Shadcn Timeline component
mainTo use this component, clone the repository, install the dependencies, and run Storybook to view the documentation and examples locally.
# Clone the repository git clone https://github.com/timDeHof/shadcn-timeline.git # Install dependencies npm install # Run Storybook locally npm run storybookgit clone https://github.com/timDeHof/shadcn-timeline.git npm install npm run storybookUse the Timeline component
mainThe
Timelinecomponent acts as a container forTimelineItemcomponents. You can customize the overall size and icon size via theTimelineprops.import { Timeline, TimelineItem } from '@/components/timeline'; import { Check } from 'lucide-react'; export default function Example() { return ( <Timeline> <TimelineItem date={new Date('2024-01-01')} title="Feature Released" description="New timeline component is now available" icon={<Check />} status="completed" /> <TimelineItem date={new Date('2024-01-02')} title="In Progress" description="Working on documentation" status="in-progress" /> <TimelineItem date={new Date('2024-01-03')} title="Upcoming" description="Planning future updates" status="pending" /> </Timeline> ); }TimelineTime component props
mainThe
TimelineTimecomponent is used for displaying and formatting dates.Prop Type Default Description dateDate | string | number- Date to display formatstring | Intl.DateTimeFormatOptions- Date formatting options classNamestring- Additional CSS classes Timeline component props
mainThe
Timelinecomponent controls the overall scale of the timeline.Prop Type Default Description size'sm' | 'md' | 'lg''md'Size of the timeline iconsize'sm' | 'md' | 'lg''md'Size of icons TimelineItem component props
mainThe
TimelineItemcomponent represents an individual event within the timeline.Prop Type Default Description dateDate | string | number- Date of the event titlestring- Title of the event descriptionstring- Description of the event iconReactNode- Custom icon iconColor'primary' | 'secondary' | 'muted' | 'accent''primary'Color theme of the icon status'completed' | 'in-progress' | 'pending''completed'Current status loadingbooleanfalseShow loading state errorstring- Show error state Configure next-sitemap settings
mainThe
next-sitemap.config.jsfile defines how sitemaps androbots.txtare generated for the project. It uses theIConfigtype from thenext-sitemappackage.Key configuration options include:
siteUrl: The base URL of your site (defaults tohttp://localhost:3000ifprocess.env.SITE_URLis not set).exclude: An array of paths to exclude from the sitemap (e.g., static assets like/favicon.ico).generateRobotsTxt: A boolean indicating whether to generate arobots.txtfile.generateIndexSitemap: A boolean indicating whether to generate an index sitemap (useful for very large sites).robotsTxtOptions: Configuration for therobots.txtfile, specifically thepoliciesarray which definesuserAgentandallow/disallowrules.
/** @type {import('next-sitemap').IConfig} */ module.exports = { siteUrl: process.env.SITE_URL || 'http://localhost:3000', exclude: ['/next.svg', '/vercel.svg', '/favicon.ico'], generateRobotsTxt: true, generateIndexSitemap: false, robotsTxtOptions: { policies: [ { userAgent: '*', allow: '/', }, ], }, };Run tests for Shadcn Timeline
mainUse the following commands to run the test suite, including Storybook tests and coverage reports.
# Run tests npm run test # Run Storybook tests npm run test-storybook # Run Storybook tests with coverage npm run test-storybook:coveragenpm run test npm run test-storybook npm run test-storybook:coverageImport Timeline components
mainThe
shadcn-timelinepackage exports all core components and layout utilities from its main entry point. You can import the primaryTimelinecomponents and layout helpers directly from the package root.import { Timeline, TimelineItem, TimelineTime, TimelineLayout } from '@/components/timeline';Reference TimelineSize, TimelineStatus, and TimelineColor types
mainThe timeline component uses specific union types for sizing, status, and color themes to ensure consistency with Shadcn UI patterns.
TimelineSize
smmdlg
TimelineStatus
completedin-progresspending
TimelineColor
primarysecondarymutedaccentdestructive
export type TimelineSize = 'sm' | 'md' | 'lg'; export type TimelineStatus = 'completed' | 'in-progress' | 'pending'; export type TimelineColor = 'primary' | 'secondary' | 'muted' | 'accent' | 'destructive';Configure the Timeline component with TimelineProps
mainThe
TimelinePropsinterface defines the configuration options for the mainTimelinecomponent. You must provide anitemsarray ofTimelineElementobjects. You can also customize the globalsize, animation behavior,iconColor,connectorColor, and CSSclassName.import { TimelineElement, TimelineSize, TimelineColor } from './types'; export interface TimelineProps { items: TimelineElement[]; size?: TimelineSize; animate?: boolean; iconColor?: TimelineColor; connectorColor?: TimelineColor; className?: string; }Define TimelineElement data structure
mainThe
TimelineElementinterface defines the shape of an individual item within the timeline. Each element requires anid,date,title, anddescription. Optional properties allow for customization of the visual state and content, including icons, status, color, and loading states.import { ReactNode } from 'react'; import { TimelineStatus, TimelineColor, TimelineSize } from './types'; export interface TimelineElement { id: number; date: string; title: string; description: string; icon?: ReactNode | (() => ReactNode); status?: TimelineStatus; color?: TimelineColor; size?: TimelineSize; loading?: boolean; error?: string; }