From 66cc64e823736d4ac3a37ea3e8c90c1371c7e1b0 Mon Sep 17 00:00:00 2001
From: nickxiaobai <640222350@qq.com>
Date: Thu, 21 May 2026 10:30:36 +0800
Subject: [PATCH 1/2] feat(timeline): allow custom point markers
---
apps/web/content/docs/components/timeline.mdx | 6 ++
apps/web/examples/timeline/index.ts | 1 +
.../timeline/timeline.activityLog.tsx | 93 +++++++++++++++++++
.../src/components/Timeline/Timeline.test.tsx | 29 ++++++
.../src/components/Timeline/TimelinePoint.tsx | 5 +-
5 files changed, 132 insertions(+), 2 deletions(-)
create mode 100644 apps/web/examples/timeline/timeline.activityLog.tsx
diff --git a/apps/web/content/docs/components/timeline.mdx b/apps/web/content/docs/components/timeline.mdx
index 62733b4891..4f6344b0a2 100644
--- a/apps/web/content/docs/components/timeline.mdx
+++ b/apps/web/content/docs/components/timeline.mdx
@@ -25,6 +25,12 @@ Use this example to show the timeline component and the child components in a ve
+## Activity log
+
+Use a custom point marker such as an avatar to display activity feeds and user events.
+
+
+
## Horizontal timeline
Use the `horizontal` prop to show the timeline component and the child components in a horizontal alignment.
diff --git a/apps/web/examples/timeline/index.ts b/apps/web/examples/timeline/index.ts
index 4792358164..87627d9cf5 100644
--- a/apps/web/examples/timeline/index.ts
+++ b/apps/web/examples/timeline/index.ts
@@ -1,3 +1,4 @@
+export { activityLog } from "./timeline.activityLog";
export { horizontal } from "./timeline.horizontal";
export { root } from "./timeline.root";
export { vertical } from "./timeline.vertical";
diff --git a/apps/web/examples/timeline/timeline.activityLog.tsx b/apps/web/examples/timeline/timeline.activityLog.tsx
new file mode 100644
index 0000000000..90d94e0ea0
--- /dev/null
+++ b/apps/web/examples/timeline/timeline.activityLog.tsx
@@ -0,0 +1,93 @@
+"use client";
+
+import {
+ Avatar,
+ Timeline,
+ TimelineBody,
+ TimelineContent,
+ TimelineItem,
+ TimelinePoint,
+ TimelineTime,
+ TimelineTitle,
+} from "flowbite-react";
+import type { CodeData } from "~/components/code-demo";
+
+const code = `
+"use client";
+
+import {
+ Avatar,
+ Timeline,
+ TimelineBody,
+ TimelineContent,
+ TimelineItem,
+ TimelinePoint,
+ TimelineTime,
+ TimelineTitle,
+} from "flowbite-react";
+
+export function Component() {
+ return (
+
+
+
+
+
+
+ just now
+ Bonnie Green uploaded a new file
+ Flowbite-react.fig was added to the project assets.
+
+
+
+
+
+
+
+ 2 hours ago
+ Jese Leos commented on your post
+ Looks good to me. The dashboard cards are ready for review.
+
+
+
+ );
+}
+`;
+
+export function Component() {
+ return (
+
+
+
+
+
+
+ just now
+ Bonnie Green uploaded a new file
+ Flowbite-react.fig was added to the project assets.
+
+
+
+
+
+
+
+ 2 hours ago
+ Jese Leos commented on your post
+ Looks good to me. The dashboard cards are ready for review.
+
+
+
+ );
+}
+
+export const activityLog: CodeData = {
+ type: "single",
+ code: {
+ fileName: "index",
+ language: "tsx",
+ code,
+ },
+ githubSlug: "timeline/timeline.activityLog.tsx",
+ component: ,
+};
diff --git a/packages/ui/src/components/Timeline/Timeline.test.tsx b/packages/ui/src/components/Timeline/Timeline.test.tsx
index b946a53e66..2ddd93711b 100644
--- a/packages/ui/src/components/Timeline/Timeline.test.tsx
+++ b/packages/ui/src/components/Timeline/Timeline.test.tsx
@@ -2,6 +2,7 @@ import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { ThemeProvider } from "../../theme/provider";
import type { CustomFlowbiteTheme } from "../../types";
+import { Avatar } from "../Avatar";
import type { TimelineProps } from "./Timeline";
import { Timeline } from "./Timeline";
import { TimelineBody } from "./TimelineBody";
@@ -62,6 +63,14 @@ describe("Components / Timeline", () => {
expect(timelinePoint().childNodes[0]).toContainHTML("svg");
});
+ it("should render children as the point marker", () => {
+ render();
+
+ expect(timelinePoint()).toBeInTheDocument();
+ expect(timelinePoint().childNodes).toHaveLength(1);
+ expect(screen.getByTestId("flowbite-avatar")).toBeInTheDocument();
+ });
+
it("should use `vertical` classes of content if provided", () => {
render(
@@ -141,6 +150,26 @@ function TestTimelineWithIcon({ horizontal, className }: TimelineProps): JSX.Ele
);
}
+function TestTimelineWithCustomPoint(): JSX.Element {
+ return (
+
+
+
+
+
+
+ February 2022
+ Application UI code in Tailwind CSS
+
+ Get access to over 20+ pages including a dashboard layout, charts, kanban board, calendar, and pre-order
+ E-commerce & Marketing pages.
+
+
+
+
+ );
+}
+
const IconSVG = () => (