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 = () => ( ((pro className={twMerge(horizontal && theme.horizontal, !horizontal && theme.vertical, className)} {...restProps} > - {children} - {Icon ? ( + {children ? ( + {children} + ) : Icon ? ( From 77f5e078ca3d765b42ed03c70676e7b8969c6d97 Mon Sep 17 00:00:00 2001 From: nickxiaobai <640222350@qq.com> Date: Thu, 21 May 2026 10:41:57 +0800 Subject: [PATCH 2/2] chore: add changeset --- .changeset/gentle-timelines-share.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/gentle-timelines-share.md diff --git a/.changeset/gentle-timelines-share.md b/.changeset/gentle-timelines-share.md new file mode 100644 index 0000000000..ab1a68e329 --- /dev/null +++ b/.changeset/gentle-timelines-share.md @@ -0,0 +1,5 @@ +--- +"flowbite-react": patch +--- + +Allow `TimelinePoint` to render custom point markers.