{"id":13406536,"url":"https://github.com/prabhuignoto/react-chrono","last_synced_at":"2025-05-10T09:13:05.866Z","repository":{"id":37630464,"uuid":"288540467","full_name":"prabhuignoto/react-chrono","owner":"prabhuignoto","description":"🕑 Modern Timeline Component for React","archived":false,"fork":false,"pushed_at":"2025-05-08T03:15:18.000Z","size":244416,"stargazers_count":4048,"open_issues_count":62,"forks_count":223,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-05-10T09:12:52.478Z","etag":null,"topics":["horizontal-timeline","javascript-timeline","react","react-timeline","reactjs","slideshow","timeline","timeline-component","typescript","vertical-timeline","vertical-timeline-react"],"latest_commit_sha":null,"homepage":"https://react-chrono.prabhumurthy.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/prabhuignoto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"prabhuignoto","ko_fi":"prabhuignoto","buy_me_a_coffee":"prabhuignoto","custom":["paypal.me/prabhuignoto"]}},"created_at":"2020-08-18T19:02:24.000Z","updated_at":"2025-05-10T08:39:52.000Z","dependencies_parsed_at":"2024-12-31T00:03:53.604Z","dependency_job_id":"6913f2a0-5c8b-45f1-8d9e-6672fd8b4a20","html_url":"https://github.com/prabhuignoto/react-chrono","commit_stats":{"total_commits":716,"total_committers":14,"mean_commits":"51.142857142857146","dds":0.05307262569832405,"last_synced_commit":"bfd27bb013b4fe89cfcc8bf43ecb0b92c2182d83"},"previous_names":[],"tags_count":81,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prabhuignoto%2Freact-chrono","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prabhuignoto%2Freact-chrono/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prabhuignoto%2Freact-chrono/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prabhuignoto%2Freact-chrono/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/prabhuignoto","download_url":"https://codeload.github.com/prabhuignoto/react-chrono/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253391772,"owners_count":21900957,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["horizontal-timeline","javascript-timeline","react","react-timeline","reactjs","slideshow","timeline","timeline-component","typescript","vertical-timeline","vertical-timeline-react"],"created_at":"2024-07-30T19:02:32.943Z","updated_at":"2025-05-10T09:13:05.834Z","avatar_url":"https://github.com/prabhuignoto.png","language":"TypeScript","funding_links":["https://github.com/sponsors/prabhuignoto","https://ko-fi.com/prabhuignoto","https://buymeacoffee.com/prabhuignoto","paypal.me/prabhuignoto","https://www.buymeacoffee.com/prabhuignoto"],"categories":["HTML","TypeScript","Datetime \u0026 Step","UI Components"],"sub_categories":["Static Code Checking(Lint)","Timeline"],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./readme-assets/social-logo-small.png\" alt=\"React Chrono Logo\" /\u003e\n  \u003ch1\u003eReact Chrono\u003c/h1\u003e\n  \u003cp\u003eA flexible and modern timeline component for React.\u003c/p\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![npm version](https://img.shields.io/npm/v/react-chrono.svg?style=flat)](https://www.npmjs.com/package/react-chrono)\n![npm downloads](https://img.shields.io/npm/dm/react-chrono.svg?label=npm%20downloads\u0026style=flat)\n![npm bundle size](https://img.shields.io/bundlephobia/minzip/react-chrono)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![styled with Prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://prettier.io/)\n\n\u003c!-- Build \u0026 Quality Badges --\u003e\n[![Build Status](https://dev.azure.com/prabhummurthy/react-chrono/_apis/build/status/prabhuignoto.react-chrono?branchName=master)](https://dev.azure.com/prabhummurthy/react-chrono/_build/latest?definitionId=7\u0026branchName=master)\n[![DeepScan grade](https://deepscan.io/api/teams/10074/projects/13644/branches/234929/badge/grade.svg)](https://deepscan.io/dashboard#view=project\u0026tid=10074\u0026pid=13644\u0026bid=234929)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/f2e24a98defd4e4fa7f6f24d86b8dab5)](https://www.codacy.com/manual/prabhuignoto/react-chrono?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=prabhuignoto/react-chrono\u0026utm_campaign=Badge_Grade)\n[![react-chrono](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/8zb5a5\u0026style=flat\u0026logo=cypress)](https://dashboard.cypress.io/projects/8zb5a5/runs)\n[![Known Vulnerabilities](https://snyk.io/test/github/prabhuignoto/react-chrono/badge.svg)](https://snyk.io/test/github/prabhuignoto/react-chrono)\n[![Depfu](https://badges.depfu.com/badges/48a23a6a830309649b7e516467cd9a48/overview.svg)](https://depfu.com/github/prabhuignoto/react-chrono?project_id=15325)\n[![Coverage Status](https://coveralls.io/repos/github/prabhuignoto/react-chrono/badge.svg?branch=master)](https://coveralls.io/github/prabhuignoto/react-chrono?branch=master)\n\u003ca href=\"https://5f985eb478dcb00022cfd60e-axcjutcmmg.chromatic.com/?path=/story/example-vertical--vertical-basic\" target=\"_blank\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/storybooks/brand/master/badge/badge-storybook.svg\" alt=\"Storybook\"\u003e\u003c/a\u003e\n\n\u003c/div\u003e\n\n\u003c!-- **Try it on CodeSandbox!**\n[![Edit react-chrono](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-chrono-bg56e?fontsize=14\u0026hidenavigation=1\u0026theme=dark) --\u003e\n\nReact Chrono is a modern timeline component for React that offers a variety of features and customization options. It allows you to render timelines in horizontal, vertical, and vertical-alternating modes, display images and videos, and much more.\n\n## Table of Contents\n\n- [✨ Features](#-features)\n- [💾 Installation](#-installation)\n- [🚀 Getting Started](#-getting-started)\n  - [Basic Horizontal Mode](#basic-horizontal-mode)\n  - [Vertical Mode](#vertical-mode)\n  - [Vertical Alternating Mode](#vertical-alternating-mode)\n- [⚙️ Props](#️-props)\n  - [Core Props](#core-props)\n  - [Timeline Item Model](#timeline-item-model)\n  - [Navigation \u0026 Interaction](#navigation--interaction)\n  - [Layout \u0026 Sizing](#layout--sizing)\n  - [Media Handling](#media-handling)\n  - [Content \u0026 Display](#content--display)\n  - [Theming \u0026 Styling](#theming--styling)\n  - [Slideshow](#slideshow)\n  - [Search](#search)\n  - [Miscellaneous](#miscellaneous)\n- [🎨 Customization](#-customization)\n  - [Rendering Custom Content](#rendering-custom-content-1)\n  - [Custom Icons](#custom-icons)\n  - [Nested Timelines](#nested-timelines-1)\n  - [Custom Class Names](#custom-class-names)\n  - [Custom Font Sizes](#custom-font-sizes)\n  - [Custom Button Alt Text](#custom-button-alt-text)\n- [📦 Examples \u0026 Demos](#-examples--demos)\n  - [CodeSandbox Examples](#codesandbox-examples)\n  - [Kitchen Sink Demo](#kitchen-sink-demo)\n  - [Storybook](#storybook)\n- [🛠️ Build Setup](#️-build-setup)\n- [🧪 Tests](#-tests)\n- [🤝 Contributing](#-contributing)\n- [🧱 Built With](#-built-with)\n- [💖 Support \u0026 Meta](#-support--meta)\n- [✨ Contributors](#-contributors)\n\n## ✨ Features\n\n-   🚥 **Multiple Modes**: Render timelines in Horizontal, Vertical, or Vertical-Alternating layouts.\n-   📺 **Slideshow**: Auto-play the timeline with slideshow functionality.\n-   🖼️ **Media Support**: Easily display images and videos within timeline cards.\n-   ⌨️ **Keyboard Accessible**: Navigate the timeline using keyboard controls.\n-   🔧 **Custom Content**: Render custom React components within timeline cards.\n-   🌿 **Nested Timelines**: Display timelines within timeline cards for complex narratives.\n-   ⚡ **Data-Driven API**: Configure the timeline dynamically using a simple data structure.\n-   🎨 **Theming**: Customize colors and appearance with ease.\n-   🎭 **Custom Icons**: Use your own icons for timeline points.\n-   💪 **TypeScript**: Built with TypeScript for robust development.\n-   💅 **Styled with Styled Component**: Leverages Styled Component for flexible styling.\n\n## 💾 Installation\n\n```bash\n# Using yarn\nyarn add react-chrono\n\n# Using npm\nnpm install react-chrono\n```\n\n## 🚀 Getting Started\n\nEnsure you wrap the `Chrono` component in a container with a specified `width` and `height`.\n\n### Basic Horizontal Mode\nBy default, if no `mode` is specified, the component renders in `HORIZONTAL` mode.\n\n```jsx\nimport React from \"react\";\nimport { Chrono } from \"react-chrono\";\n\nconst App = () =\u003e {\n  const items = [\n    {\n      title: \"May 1940\",\n      cardTitle: \"Dunkirk\",\n      url: \"http://www.history.com\",\n      cardSubtitle: \"Men of the British Expeditionary Force (BEF) wade out to a destroyer...\",\n      cardDetailedText: \"Men of the British Expeditionary Force (BEF) wade out to a destroyer during the evacuation from Dunkirk.\",\n      media: {\n        type: \"IMAGE\",\n        source: {\n          url: \"http://someurl/image.jpg\"\n        }\n      }\n    },\n    // ... more items\n  ];\n\n  return (\n    \u003cdiv style={{ width: \"800px\", height: \"400px\" }}\u003e\n      \u003cChrono items={items} /\u003e\n    \u003c/div\u003e\n  );\n};\n\nexport default App;\n```\n![Horizontal Timeline Example](./readme-assets/horizontal_all.jpg)\n\n### Vertical Mode\nTo render the timeline vertically, set the `mode` prop to `VERTICAL`.\n\n```jsx\n\u003cdiv style={{ width: '300px', height: '950px' }}\u003e\n  \u003cChrono items={items} mode=\"VERTICAL\" /\u003e\n\u003c/div\u003e\n```\n![Vertical Timeline Example](./readme-assets/vertical_basic.jpg)\n\n### Vertical Alternating Mode\nFor a layout where cards alternate sides, use `VERTICAL_ALTERNATING`.\n\n```jsx\n\u003cdiv style={{ width: '500px', height: '950px' }}\u003e\n  \u003cChrono items={items} mode=\"VERTICAL_ALTERNATING\" /\u003e\n\u003c/div\u003e\n```\n![Vertical Alternating Timeline Example](./readme-assets/vertical_alternating.jpg)\n\n## ⚙️ Props\n\nReact Chrono offers a wide range of props for customization.\n\n### Core Props\n\n| Name        | Type                                           | Default              | Description                                                                                                |\n| :---------- | :--------------------------------------------- | :------------------- | :--------------------------------------------------------------------------------------------------------- |\n| `items`     | `TimelineItemModel[]`                          | `[]`                 | An array of [Timeline Item objects](#timeline-item-model) to display.                                      |\n| `mode`      | `'HORIZONTAL'`, `'VERTICAL'`, `'VERTICAL_ALTERNATING'` | `'HORIZONTAL'`       | Sets the layout mode of the timeline. Changed to `HORIZONTAL` from `VERTICAL_ALTERNATING` for new projects. |\n| `theme`     | `Theme`                                        | `{...}`              | Customizes colors. See [Theming \u0026 Styling](#theming--styling) for details.                                 |\n\n### Timeline Item Model\n\nEach object in the `items` array can have the following properties:\n\n| Property           | Type               | Description                                                                                                |\n| :----------------- | :----------------- | :--------------------------------------------------------------------------------------------------------- |\n| `title`            | `string`           | Title of the timeline item (often a date or short label).                                                  |\n| `cardTitle`        | `string`           | Title displayed on the timeline card.                                                                      |\n| `cardSubtitle`     | `string`           | Subtitle text displayed on the timeline card.                                                              |\n| `cardDetailedText` | `string` or `string[]` | Detailed text for the card. An array of strings will render each string as a separate paragraph.         |\n| `media`            | `TimelineMediaModel` | Object to configure image or video display. See [Media Handling](#media-handling).                         |\n| `url`              | `string`           | URL associated with the timeline item's title. Clicking the title will navigate to this URL.               |\n| `date`             | `Date` or `string` | Date to be used in the title. If provided, this will override the `title` property for display purposes. |\n| `timelineContent`  | `ReactNode`        | Custom React content to render inside the card. Overrides `cardDetailedText`. See [Rendering Custom Content](#rendering-custom-content-1). |\n| `items`            | `TimelineItemModel[]` | Array of timeline items for creating [Nested Timelines](#nested-timelines-1).                            |\n| `active`           | `boolean`          | If true, this item will be initially active (only for the first matching item).                            |\n| `id`               | `string`           | A unique identifier for the timeline item.                                                                 |\n| `visible`          | `boolean`          | Controls the visibility of the timeline item.                                                              |\n\n\n**Example `TimelineItemModel`:**\n```js\n{\n  title: \"May 1940\",\n  cardTitle: \"Dunkirk\",\n  cardSubtitle: \"Evacuation of Allied soldiers from the beaches and harbour of Dunkirk, France.\",\n  cardDetailedText: [\"Paragraph one about Dunkirk.\", \"Paragraph two providing more details.\"],\n  media: {\n    type: \"IMAGE\", // \"VIDEO\"\n    source: {\n      url: \"http://someurl/dunkirk.jpg\"\n    },\n    name: \"Dunkirk Evacuation\"\n  },\n  url: \"https://en.wikipedia.org/wiki/Dunkirk_evacuation\",\n  // For nested timeline:\n  // items: [{ cardTitle: 'Sub-event 1' }, { cardTitle: 'Sub-event 2' }]\n}\n```\n\n### Navigation \u0026 Interaction\n\n| Name                       | Type        | Default   | Description                                                                                             |\n| :------------------------- | :---------- | :-------- | :------------------------------------------------------------------------------------------------------ |\n| `activeItemIndex`          | `number`    | `0`       | Index of the timeline item to be active on load.                                                        |\n| `disableNavOnKey`          | `boolean`   | `false`   | Disables keyboard navigation (\u003ckbd\u003eLEFT\u003c/kbd\u003e/\u003ckbd\u003eRIGHT\u003c/kbd\u003e for Horizontal, \u003ckbd\u003eUP\u003c/kbd\u003e/\u003ckbd\u003eDOWN\u003c/kbd\u003e for Vertical). |\n| `disableClickOnCircle`     | `boolean`   | `false`   | Disables click action on timeline points/circles.                                                       |\n| `disableAutoScrollOnClick` | `boolean`   | `false`   | Prevents auto-scrolling to the active card when a timeline card or point is clicked.                    |\n| `onItemSelected`           | `function`  |           | Callback function invoked when a timeline item is selected. Passes item data and index.                 |\n| `onScrollEnd`              | `function`  |           | Callback function invoked when the end of the timeline is reached during scrolling.                     |\n| `focusActiveItemOnLoad`    | `boolean`   | `true`    | Automatically scrolls to and focuses on the `activeItemIndex` when the timeline loads.                  |\n| `disableInteraction`       | `boolean`   | `false`   | Disables all user interactions with the timeline (clicks, keyboard navigation).                         |\n| `enableQuickJump`          | `boolean`   | `true`    | Allows quick jumping to a timeline item via controls (if toolbar is enabled).                           |\n| `useReadMore`              | `boolean`   | `true`    | Enables a \"read more\" button if card content exceeds available space. Set to `false` to always show all text. |\n\n**Keyboard Navigation:**\n-   **Horizontal Mode**: Use \u003ckbd\u003eLEFT\u003c/kbd\u003e and \u003ckbd\u003eRIGHT\u003c/kbd\u003e arrow keys.\n-   **Vertical/Vertical Alternating Mode**: Use \u003ckbd\u003eUP\u003c/kbd\u003e and \u003ckbd\u003eDOWN\u003c/kbd\u003e arrow keys.\n-   \u003ckbd\u003eHOME\u003c/kbd\u003e: Jump to the first item.\n-   \u003ckbd\u003eEND\u003c/kbd\u003e: Jump to the last item.\n\n### Layout \u0026 Sizing\n\n| Name                     | Type                               | Default          | Description                                                                                                                               |\n| :----------------------- | :--------------------------------- | :--------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |\n| `cardHeight`             | `number`                           | `200`            | Minimum height (in pixels) of timeline cards.                                                                                             |\n| `cardWidth`              | `number`                           | `450`            | Maximum width (in pixels) of timeline cards.                                                                                              |\n| `itemWidth`              | `number`                           | `300`            | Width (in pixels) of each timeline section in `HORIZONTAL` mode.                                                                          |\n| `contentDetailsHeight`   | `number`                           | `150`            | Height (in pixels) of the detailed content area within a card if `cardDetailedText` is used.                                              |\n| `lineWidth`              | `number`                           | `3`              | Width (in pixels) of the main timeline track line.                                                                                        |\n| `timelinePointDimension` | `number`                           | `16`             | Diameter (in pixels) of the circular points on the timeline.                                                                              |\n| `nestedCardHeight`       | `number`                           | `150`            | Height (in pixels) of cards within a [nested timeline](#nested-timelines-1).                                                              |\n| `scrollable`             | `boolean` or `{ scrollbar: boolean }` | `true`           | Makes `VERTICAL` and `VERTICAL_ALTERNATING` modes scrollable. Set to `{ scrollbar: true }` to show the scrollbar.                         |\n| `enableBreakPoint`       | `boolean`                          | `true`           | If true, `VERTICAL_ALTERNATING` mode automatically switches to `VERTICAL` mode when `responsiveBreakPoint` is reached.                     |\n| `responsiveBreakPoint`   | `number`                           | `768`            | Viewport width (in pixels) at which `VERTICAL_ALTERNATING` mode switches to `VERTICAL` if `enableBreakPoint` is true. Default changed to `768`. |\n| `cardPositionHorizontal` | `'TOP'` or `'BOTTOM'`              | `'BOTTOM'`       | Positions the card above or below the timeline in `HORIZONTAL` mode. Default changed to `'BOTTOM'`.                                       |\n| `flipLayout`             | `boolean`                          | `false`          | Reverses the layout direction (e.g., Right-to-Left for horizontal, or swaps sides for vertical alternating).                              |\n| `showAllCardsHorizontal` | `boolean`                          | `false`          | In `HORIZONTAL` mode, displays all cards simultaneously instead of only the active one.                                                   |\n\n### Media Handling\n\nThe `media` object within a [Timeline Item](#timeline-item-model) configures images or videos.\n\n| `media` Property | Type                               | Description                                                                                             |\n| :--------------- | :--------------------------------- | :------------------------------------------------------------------------------------------------------ |\n| `type`           | `'IMAGE'` or `'VIDEO'`             | Specifies the type of media.                                                                            |\n| `source`         | `{ url: string, type?: string }`   | `url`: URL of the image or video. `type` (for video): e.g., `'mp4'`, `'webm'`.                          |\n| `name`           | `string`                           | Alt text for images or a descriptive name for videos.                                                   |\n| `active`         | `boolean`                          | (Video only) If true, video will attempt to play when its card becomes active.                          |\n| `id`             | `string`                           | A unique ID for the media element.                                                                      |\n| `videoOptions`   | `HTMLVideoElement attributes`      | (Video only) An object containing standard HTML5 video attributes like `loop`, `muted`, `autoPlay`, etc. |\n\n\n**Image Example:**\n```js\nmedia: {\n  type: \"IMAGE\",\n  name: \"dunkirk beach\",\n  source: {\n    url: \"http://someurl/image.jpg\"\n  }\n}\n```\n\n**Video Example (auto-plays when active, muted):**\n```js\nmedia: {\n  type: \"VIDEO\",\n  name: \"Pearl Harbor\",\n  source: {\n    url: \"/pearl-harbor.mp4\", // or \"https://www.youtube.com/embed/f6cz9gtMTeI\"\n    type: \"mp4\" // Optional for local files if extension is clear, useful for YouTube embeds\n  },\n  videoOptions: { autoPlay: true, muted: true }\n}\n```\n![Timeline with Media](./readme-assets/media.png)\n\n**Media Settings Prop (`mediaSettings`):**\nThis top-level prop on `\u003cChrono\u003e` controls global media display:\n\n| Name    | Type                          | Default  | Description                                                                 |\n| :------ | :---------------------------- | :------- | :-------------------------------------------------------------------------- |\n| `align` | `'left'`, `'right'`, `'center'` | `'left'` | Alignment of media within the card. Default changed to `'left'`.            |\n| `fit`   | `'cover'`, `'contain'`, `'fill'`, `'none'`, `'scale-down'` | `'cover'`  | CSS `object-fit` property for images.                                       |\n\n```jsx\n\u003cChrono items={items} mediaSettings={{ align: 'right', fit: 'contain' }} /\u003e\n```\n\n### Content \u0026 Display\n\n| Name                   | Type        | Default        | Description                                                                                                                            |\n| :--------------------- | :---------- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------- |\n| `borderLessCards`      | `boolean`   | `false`        | Removes borders and shadows from timeline cards for a flatter look.                                                                    |\n| `cardLess`             | `boolean`   | `false`        | Hides timeline cards, showing only titles/points. Useful for a very compact timeline.                                                  |\n| `disableTimelinePoint` | `boolean`   | `false`        | Hides the circular points on the timeline track.                                                                                       |\n| `timelinePointShape`   | `'circle'`, `'square'`, `'diamond'` | `'circle'`     | Configures the shape of the points on the timeline.                                                                    |\n| `textOverlay`          | `boolean`   | `false`        | Displays text content as an overlay on top of media elements. Requires `text` property in timeline items.                              |\n| `parseDetailsAsHTML`   | `boolean`   | `false`        | If true, `cardDetailedText` will be parsed as HTML. Use with caution due to XSS risks if content is user-supplied.                     |\n| `titleDateFormat`      | `string`    | `'MMM DD, YYYY'` | Date format for item titles when using the `date` property in items. Supports all [day.js](https://day.js.org/) formats.             |\n| `textDensity`          | `'LOW'` or `'HIGH'` | `'HIGH'`       | Configures the amount of text displayed in cards. `'LOW'` might truncate more aggressively.                                        |\n\n**Text Overlay Mode:**\nEnable `textOverlay` and provide a `text` property in your `items`.\n```jsx\nconst items = [\n  {\n    title: 'First item',\n    media: { type: 'IMAGE', source: { url: 'https://example.com/image.jpg' }},\n    text: 'This is the caption for the first item, appearing over the image.'\n  }\n];\n\u003cChrono items={items} textOverlay /\u003e;\n```\n![Text Overlay Example](./readme-assets/text_overlay.jpg)\n\n### Theming \u0026 Styling\n\nUse the `theme` prop to customize colors:\n```jsx\n\u003cChrono\n  items={items}\n  theme={{\n    primary: 'red',          // Main timeline color (points, lines)\n    secondary: 'blue',       // Background color for timeline cards or other elements depending on mode\n    cardBgColor: 'yellow',   // Background color of the timeline cards\n    cardForeColor: 'black',  // Text color within timeline cards\n    titleColor: 'black',     // Color of the timeline item titles (e.g., dates)\n    titleColorActive: 'red', // Color of the active timeline item title\n  }}\n/\u003e\n```\n\u003e For a complete list of themeable properties, please refer to the `Theme` type definition in the source code or Storybook examples.\n\n**Dark Mode Toggle:**\n| Name               | Type       | Default | Description                                                                                                |\n| :----------------- | :--------- | :------ | :--------------------------------------------------------------------------------------------------------- |\n| `enableDarkToggle` | `boolean`  | `false` | Adds a toggle switch to the toolbar for enabling dark mode (if dark theme is configured).                  |\n| `onThemeChange`    | `function` |         | Callback invoked when the theme changes, e.g., via the dark mode toggle. Passes the new theme object.        |\n\n\n### Slideshow\n\n| Name                | Type                                     | Default            | Description                                                                                                                            |\n| :------------------ | :--------------------------------------- | :----------------- | :------------------------------------------------------------------------------------------------------------------------------------- |\n| `slideShow`         | `boolean`                                | `false`            | Enables slideshow mode and shows play/pause controls in the toolbar.                                                                   |\n| `slideItemDuration` | `number`                                 | `2000`             | Duration (in milliseconds) each timeline item remains active during a slideshow. Default changed to `2000`.                            |\n| `slideShowType`     | `'reveal'`, `'slide_from_sides'`, `'slide_in'` | Varies by `mode` | Type of animation for slideshow transitions. Defaults: `VERTICAL` -\u003e `'reveal'`, `VERTICAL_ALTERNATING` -\u003e `'slide_from_sides'`, `HORIZONTAL` -\u003e `'slide_in'`. |\n\n```jsx\n\u003cChrono items={items} slideShow slideItemDuration={3000} /\u003e\n```\n\u003e Slideshow can be stopped by clicking the stop button or pressing \u003ckbd\u003eESC\u003c/kbd\u003e.\n\n### Search\n\n| Name                | Type      | Default             | Description                                                                                                |\n| :------------------ | :-------- | :------------------ | :--------------------------------------------------------------------------------------------------------- |\n| `searchPlaceholder` | `string`  | `\"Search...\"`       | Placeholder text for the search input in the toolbar.                                                      |\n| `searchAriaLabel`   | `string`  | `\"Search timeline\"` | ARIA label for the search input for accessibility.                                                         |\n| `clearSearch`       | `string`  | `\"Clear search\"`    | Text/ARIA label for the clear search button.                                                               |\n\n```jsx\n\u003cChrono\n  items={data}\n  searchPlaceholder=\"Find in timeline...\"\n/\u003e\n```\n\u003e Search functionality is part of the toolbar. To hide search (and the toolbar), set `disableToolbar={true}`.\n\n### Miscellaneous\n\n| Name                     | Type        | Default   | Description                                                                                                                               |\n| :----------------------- | :---------- | :-------- | :---------------------------------------------------------------------------------------------------------------------------------------- |\n| `allowDynamicUpdate`     | `boolean`   | `false`   | Enables dynamic updates of timeline items. If true, changes to the `items` prop will re-render the timeline.                              |\n| `noUniqueId`             | `boolean`   | `false`   | Prevents generating a unique ID for the timeline wrapper. Use with `uniqueId` if you need to set a specific ID.                             |\n| `uniqueId`               | `string`    |           | Sets a custom unique ID for the timeline wrapper. Useful with `noUniqueId={true}`.                                                        |\n| `disableToolbar`         | `boolean`   | `false`   | Hides the entire toolbar/control panel.                                                                                                   |\n| `toolbarPosition`        | `'TOP'` or `'BOTTOM'` | `'TOP'`   | Positions the toolbar at the top or bottom of the timeline.                                                                       |\n| `highlightCardsOnHover`  | `boolean`   | `false`   | Highlights timeline cards on mouse hover.                                                                                                 |\n\n## 🎨 Customization\n\n### Rendering Custom Content\nPass React elements as children to `\u003cChrono\u003e`. Each child will be rendered into a timeline card. This can be combined with the `items` prop to provide titles or other metadata.\n\n```jsx\nconst customItems = [\n  { title: '2023-01-01', cardTitle: 'Event One' },\n  { title: '2023-02-15', cardTitle: 'Event Two' },\n];\n\n\u003cChrono mode=\"VERTICAL\" items={customItems}\u003e\n  \u003cdiv\u003e\n    \u003ch4\u003eCustom Content for Event One\u003c/h4\u003e\n    \u003cp\u003eThis is fully custom JSX rendered in the first card.\u003c/p\u003e\n  \u003c/div\u003e\n  \u003cdiv\u003e\n    \u003cimg src=\"\u003curl_to_image\u003e\" alt=\"Custom Image\" style={{width: \"100%\"}} /\u003e\n    \u003cp\u003eAn image in the second card.\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/Chrono\u003e\n```\n\n### Custom Icons\nProvide images for timeline points by wrapping them in a `div` with `className=\"chrono-icons\"` as a child of `\u003cChrono\u003e`. Icons are applied sequentially.\n\n```jsx\n\u003cChrono items={items} mode=\"VERTICAL_ALTERNATING\"\u003e\n  {/* Custom content for cards (optional) */}\n  \u003cdiv\u003eCard 1 Content\u003c/div\u003e\n  \u003cdiv\u003eCard 2 Content\u003c/div\u003e\n\n  {/* Custom icons for timeline points */}\n  \u003cdiv className=\"chrono-icons\"\u003e\n    \u003cimg src=\"image1.svg\" alt=\"icon1\" /\u003e\n    \u003cimg src=\"image2.svg\" alt=\"icon2\" /\u003e\n    {/* Add more images for more items */}\n  \u003c/div\u003e\n\u003c/Chrono\u003e\n```\n\n### Nested Timelines\nCreate timelines within timeline cards by providing an `items` array within a parent timeline item.\n```jsx\nconst itemsWithNested = [\n  {\n    title: 'Main Event 1',\n    cardTitle: 'Chapter 1',\n    items: [ // Nested timeline\n      { cardTitle: 'Sub-event 1.1', cardSubtitle: 'Details for 1.1' },\n      { cardTitle: 'Sub-event 1.2', media: { type: \"IMAGE\", source: { url: '...' } } },\n    ],\n  },\n  { title: 'Main Event 2', cardTitle: 'Chapter 2' },\n];\n\n\u003cChrono mode=\"VERTICAL\" items={itemsWithNested} nestedCardHeight={120} /\u003e\n```\n\n### Custom Class Names\nApply your own CSS classes to various parts of the timeline using the `classNames` prop.\n```jsx\n\u003cChrono\n  items={items}\n  classNames={{\n    card: 'my-custom-card',\n    cardMedia: 'my-card-media',\n    cardSubTitle: 'my-card-subtitle',\n    cardText: 'my-card-text',\n    cardTitle: 'my-card-title',\n    controls: 'my-timeline-controls', // Class for the toolbar\n    title: 'my-timeline-title',      // Class for the item titles (e.g., dates)\n    timelinePoint: 'my-timeline-point',\n    timelineTrack: 'my-timeline-track',\n  }}\n/\u003e\n```\n\n### Custom Font Sizes\nAdjust font sizes for card elements using the `fontSizes` prop.\n```jsx\n\u003cChrono\n  items={data}\n  fontSizes={{\n    cardSubtitle: '0.85rem',\n    cardText: '0.8rem',\n    cardTitle: '1.1rem',\n    title: '0.9rem', // Font size for the main timeline titles (dates)\n  }}\n/\u003e\n```\n\n### Custom Button Alt Text\nCustomize the `alt` text for toolbar navigation buttons via `buttonTexts`.\n```jsx\n\u003cChrono\n  items={data}\n  buttonTexts={{\n    first: 'Jump to First Item',\n    last: 'Jump to Last Item',\n    next: 'View Next Item',\n    previous: 'View Previous Item',\n    play: 'Start Slideshow',\n    stop: 'Stop Slideshow', // Added for completeness\n    jumpTo: 'Jump to specific item' // Added for completeness\n  }}\n/\u003e\n```\n**Default `buttonTexts` values:**\n| Property   | Value            |\n| :--------- | :--------------- |\n| `first`    | 'Go to First'    |\n| `last`     | 'Go to Last'     |\n| `next`     | 'Next'           |\n| `previous` | 'Previous'       |\n| `play`     | 'Play Slideshow' |\n| `stop`     | 'Stop Slideshow' |\n| `jumpTo`   | 'Jump to'        |\n\n\n## 📦 Examples \u0026 Demos\n\n### CodeSandbox Examples\nExplore various configurations of React Chrono:\n-   [Horizontal Basic](https://codesandbox.io/s/keen-shannon-gtjwn?file=/src/App.js)\n-   [Horizontal - Show all cards](https://codesandbox.io/s/show-all-cards-5vuf2x?file=/src/App.js)\n-   [Vertical Basic](https://codesandbox.io/s/react-chrono-vertical-basic-0rm1o?file=/src/App.js)\n-   [Vertical Alternating](https://codesandbox.io/s/react-chrono-tree-text-1fcs3?file=/src/App.js)\n-   [Vertical with All Images](https://codesandbox.io/s/react-chrono-tree-vertical-images-b5zri?file=/src/App.js)\n-   [Vertical with Custom Content](https://codesandbox.io/s/react-chrono-vertical-custom-qepnm?file=/src/App.js)\n-   [Vertical Custom Content with `items` prop](https://codesandbox.io/s/react-chrono-vertical-custom-2-uctcp?file=/src/App.js)\n-   [Custom Icons Example](https://codesandbox.io/s/react-chrono-custom-icons-x9s2k?file=/src/App.js)\n\n### Kitchen Sink Demo\nSee a comprehensive demo showcasing many features:\n-   [React Chrono Kitchen Sink](https://react-chrono-kitchen-sink.prabhumurthy.com/)\n\n### Storybook\nDive into a wide variety of examples hosted on Storybook:\n-   [Horizontal Collection](https://5f985eb478dcb00022cfd60e-axcjutcmmg.chromatic.com/?path=/story/example-horizontal--horizontal-timeline)\n-   [Vertical Collection](https://5f985eb478dcb00022cfd60e-axcjutcmmg.chromatic.com/?path=/story/example-vertical--vertical-basic)\n\n## 🛠️ Build Setup\n\n```bash\n# Install dependencies\npnpm install\n\n# Start development server\npnpm dev\n\n# Lint CSS\npnpm lint:css\n\n# ESLint\npnpm eslint\n\n# Prettier\npnpm lint\n\n# Build library\npnpm rollup\n```\n\n## 🧪 Tests\n\n```bash\n# Run unit tests\npnpm test\n\n# Run Cypress tests (interactive)\npnpm cypress:test # or pnpm cypress open\n\n# Run Cypress tests in headless mode\npnpm cypress:headless\n\n# Run Cypress tests in quiet mode (headless, less output)\npnpm cypress:quiet\n```\n\n## 🤝 Contributing\n\nContributions are welcome! Please follow these steps:\n1.  [Fork the repository](https://github.com/prabhuignoto/react-chrono/fork).\n2.  Create your feature branch (`git checkout -b new-feature`).\n3.  Commit your changes (`git commit -am 'Add: New amazing feature'`).\n4.  Push to the branch (`git push origin new-feature`).\n5.  Create a new Pull Request.\n\nPlease read `CONTRIBUTING.md` for more details on the process and `CODE_OF_CONDUCT.md`.\n\n## 🧱 Built With\n\n-   [TypeScript](https://www.typescriptlang.org/)\n-   Styled with [Emotion](https://emotion.sh/)\n\n## 💖 Support \u0026 Meta\n\nSpecial thanks to [BrowserStack](https://www.browserstack.com/) for providing an Open Source License for testing.\n\nDistributed under the MIT license. See `LICENSE` for more information.\n\nPrabhu Murthy – [@prabhumurthy2](https://twitter.com/prabhumurthy2) – \u003cprabhu.m.murthy@gmail.com\u003e\nGitHub: [https://github.com/prabhuignoto](https://github.com/prabhuignoto)\n\n\u003ca href=\"https://www.buymeacoffee.com/prabhuignoto\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-red.png\" alt=\"Buy Me A Coffee\" height=\"41\" width=\"174\" \u003e\u003c/a\u003e\n\n[![SonarCloud](https://sonarcloud.io/images/project_badges/sonarcloud-white.svg)](https://sonarcloud.io/project/overview?id=prabhuignoto_react-chrono)\n\n\n## ✨ Contributors\n\nThanks to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://aloisdg.github.io/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/3449303?v=4?s=60\" width=\"60px;\" alt=\"Alois\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAlois\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/prabhuignoto/react-chrono/commits?author=aloisdg\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://kojikoji.ga\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/474225?v=4?s=60\" width=\"60px;\" alt=\"Koji\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eKoji\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/prabhuignoto/react-chrono/commits?author=koji\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://alexgirard.com\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/373?v=4?s=60\" width=\"60px;\" alt=\"Alexandre Girard\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAlexandre Girard\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/prabhuignoto/react-chrono/commits?author=alx\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/Ryuyxx\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/69892552?v=4?s=60\" width=\"60px;\" alt=\"Ryuya\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eRyuya\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/prabhuignoto/react-chrono/commits?author=Ryuyxx\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/taqi457\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/2155219?v=4?s=60\" width=\"60px;\" alt=\"Taqi Abbas\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eTaqi Abbas\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/prabhuignoto/react-chrono/commits?author=taqi457\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/megasoft78\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/514958?v=4?s=60\" width=\"60px;\" alt=\"megasoft78\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003emegasoft78\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/prabhuignoto/react-chrono/commits?author=megasoft78\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://dev.bigdreamer.cc\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/39019913?v=4?s=60\" width=\"60px;\" alt=\"Eric（书生）\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eEric（书生）\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/prabhuignoto/react-chrono/commits?author=bigbigDreamer\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/DrakeXorn\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/3925261?v=4?s=60\" width=\"60px;\" alt=\"Christophe Bernard\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eChristophe Bernard\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/prabhuignoto/react-chrono/commits?author=DrakeXorn\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprabhuignoto%2Freact-chrono","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprabhuignoto%2Freact-chrono","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprabhuignoto%2Freact-chrono/lists"}