From b9f21fad2ada79d0616332c177bc774f77d1bd58 Mon Sep 17 00:00:00 2001 From: Pritam Date: Thu, 21 Nov 2024 14:45:21 +0530 Subject: [PATCH] "feat: add Timeline component" --- apps/www/__registry__/index.tsx | 64 +++++++++ .../new-york/block/chart-area-interactive.tsx | 7 +- apps/www/config/docs.ts | 6 + apps/www/content/docs/components/timeline.mdx | 133 ++++++++++++++++++ apps/www/public/r/index.json | 13 ++ .../r/styles/default/timeline-demo.json | 15 ++ .../www/public/r/styles/default/timeline.json | 15 ++ .../new-york/chart-area-interactive.json | 2 +- .../r/styles/new-york/timeline-demo.json | 15 ++ .../public/r/styles/new-york/timeline.json | 15 ++ .../default/example/timeline-demo.tsx | 51 +++++++ apps/www/registry/default/ui/timeline.tsx | 75 ++++++++++ .../new-york/example/timeline-demo.tsx | 51 +++++++ apps/www/registry/new-york/ui/timeline.tsx | 75 ++++++++++ apps/www/registry/registry-examples.ts | 11 ++ apps/www/registry/registry-ui.ts | 11 ++ package.json | 2 +- 17 files changed, 556 insertions(+), 5 deletions(-) create mode 100644 apps/www/content/docs/components/timeline.mdx create mode 100644 apps/www/public/r/styles/default/timeline-demo.json create mode 100644 apps/www/public/r/styles/default/timeline.json create mode 100644 apps/www/public/r/styles/new-york/timeline-demo.json create mode 100644 apps/www/public/r/styles/new-york/timeline.json create mode 100644 apps/www/registry/default/example/timeline-demo.tsx create mode 100644 apps/www/registry/default/ui/timeline.tsx create mode 100644 apps/www/registry/new-york/example/timeline-demo.tsx create mode 100644 apps/www/registry/new-york/ui/timeline.tsx diff --git a/apps/www/__registry__/index.tsx b/apps/www/__registry__/index.tsx index d7ed6f1dd59..01aee359206 100644 --- a/apps/www/__registry__/index.tsx +++ b/apps/www/__registry__/index.tsx @@ -749,6 +749,22 @@ export const Index: Record = { subcategory: "", chunks: [] }, + "timeline": { + name: "timeline", + description: "", + type: "registry:ui", + registryDependencies: ["timeline-demo"], + files: [{ + path: "registry/new-york/ui/timeline.tsx", + type: "registry:ui", + target: "" + }], + component: React.lazy(() => import("@/registry/new-york/ui/timeline.tsx")), + source: "", + category: "", + subcategory: "", + chunks: [] + }, "tooltip": { name: "tooltip", description: "", @@ -765,6 +781,22 @@ export const Index: Record = { subcategory: "", chunks: [] }, + "timeline-demo": { + name: "timeline-demo", + description: "", + type: "registry:example", + registryDependencies: ["timeline"], + files: [{ + path: "registry/new-york/example/timeline-demo.tsx", + type: "registry:example", + target: "" + }], + component: React.lazy(() => import("@/registry/new-york/example/timeline-demo.tsx")), + source: "", + category: "", + subcategory: "", + chunks: [] + }, "accordion-demo": { name: "accordion-demo", description: "", @@ -6242,6 +6274,22 @@ export const Index: Record = { subcategory: "", chunks: [] }, + "timeline": { + name: "timeline", + description: "", + type: "registry:ui", + registryDependencies: ["timeline-demo"], + files: [{ + path: "registry/default/ui/timeline.tsx", + type: "registry:ui", + target: "" + }], + component: React.lazy(() => import("@/registry/default/ui/timeline.tsx")), + source: "", + category: "", + subcategory: "", + chunks: [] + }, "tooltip": { name: "tooltip", description: "", @@ -6258,6 +6306,22 @@ export const Index: Record = { subcategory: "", chunks: [] }, + "timeline-demo": { + name: "timeline-demo", + description: "", + type: "registry:example", + registryDependencies: ["timeline"], + files: [{ + path: "registry/default/example/timeline-demo.tsx", + type: "registry:example", + target: "" + }], + component: React.lazy(() => import("@/registry/default/example/timeline-demo.tsx")), + source: "", + category: "", + subcategory: "", + chunks: [] + }, "accordion-demo": { name: "accordion-demo", description: "", diff --git a/apps/www/__registry__/new-york/block/chart-area-interactive.tsx b/apps/www/__registry__/new-york/block/chart-area-interactive.tsx index 1cd672af11c..cd8e7e6b288 100644 --- a/apps/www/__registry__/new-york/block/chart-area-interactive.tsx +++ b/apps/www/__registry__/new-york/block/chart-area-interactive.tsx @@ -141,15 +141,16 @@ export default function Component() { const filteredData = chartData.filter((item) => { const date = new Date(item.date) - const now = new Date() + const referenceDate = new Date("2024-06-30") let daysToSubtract = 90 if (timeRange === "30d") { daysToSubtract = 30 } else if (timeRange === "7d") { daysToSubtract = 7 } - now.setDate(now.getDate() - daysToSubtract) - return date >= now + const startDate = new Date(referenceDate) + startDate.setDate(startDate.getDate() - daysToSubtract) + return date >= startDate }) return ( diff --git a/apps/www/config/docs.ts b/apps/www/config/docs.ts index 62ae2f818b6..a8759eee6fe 100644 --- a/apps/www/config/docs.ts +++ b/apps/www/config/docs.ts @@ -145,6 +145,12 @@ export const docsConfig: DocsConfig = { { title: "Components", items: [ + { + title: "Timeline", + href: "/docs/components/timeline", + items: [], + label: "New", + }, { title: "Sidebar", href: "/docs/components/sidebar", diff --git a/apps/www/content/docs/components/timeline.mdx b/apps/www/content/docs/components/timeline.mdx new file mode 100644 index 00000000000..8a73d82337d --- /dev/null +++ b/apps/www/content/docs/components/timeline.mdx @@ -0,0 +1,133 @@ +--- +title: Timeline +description: A vertical timeline component for displaying chronological events or activities. +component: true +--- + + + +## Installation + + + + + CLI + Manual + + + +```bash +npx shadcn@latest add timeline +``` + + + + + + + +Copy and paste the following code into your project. + + + +Update the import paths to match your project setup. + + + + + + + +## Usage + +```tsx +import { + Timeline, + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, +} from "@/components/ui/timeline" + +export function TimelineDemo() { + return ( + + + + + +

First Event

+

+ Description of the first event. +

+
+
+ + + + +

Second Event

+

+ Description of the second event. +

+
+
+ + + +

Third Event

+

+ Description of the third event. +

+
+
+
+ ) +} +``` + +## Examples + +### With Custom Colors + +You can customize the colors of the timeline dots and connectors using Tailwind CSS classes. + +```tsx + + + + + Custom colored timeline item + + +``` + +### With Icons + +You can add icons to the timeline dots. + +```tsx + + + + + + + Timeline item with icon + + +``` + +### Vertical Alignment + +By default, the content is aligned with the top of the dot. You can modify this by adjusting the `pt-1` class on `TimelineContent`. + +```tsx + + + + + Aligned with dot + + +``` diff --git a/apps/www/public/r/index.json b/apps/www/public/r/index.json index 590d2f98ca6..9f983d20222 100644 --- a/apps/www/public/r/index.json +++ b/apps/www/public/r/index.json @@ -697,6 +697,19 @@ } ] }, + { + "name": "timeline", + "type": "registry:ui", + "registryDependencies": [ + "timeline-demo" + ], + "files": [ + { + "path": "ui/timeline.tsx", + "type": "registry:ui" + } + ] + }, { "name": "tooltip", "type": "registry:ui", diff --git a/apps/www/public/r/styles/default/timeline-demo.json b/apps/www/public/r/styles/default/timeline-demo.json new file mode 100644 index 00000000000..d5f023e24fc --- /dev/null +++ b/apps/www/public/r/styles/default/timeline-demo.json @@ -0,0 +1,15 @@ +{ + "name": "timeline-demo", + "type": "registry:example", + "registryDependencies": [ + "timeline" + ], + "files": [ + { + "path": "example/timeline-demo.tsx", + "content": "import { CalendarIcon, CheckCircleIcon, StarIcon } from \"lucide-react\"\nimport {\n Timeline,\n TimelineConnector,\n TimelineContent,\n TimelineDot,\n TimelineItem,\n} from \"@/registry/default/ui/timeline\"\n\nexport default function TimelineDemo() {\n return (\n \n \n \n \n \n \n \n

Project Started

\n

\n Kickoff meeting with the team\n

\n
\n
\n \n \n \n \n \n \n

Design Phase Complete

\n

\n UI/UX designs approved by stakeholders\n

\n
\n
\n \n \n \n \n \n

Development In Progress

\n

\n Frontend implementation started\n

\n
\n
\n
\n )\n}\n", + "type": "registry:example", + "target": "" + } + ] +} \ No newline at end of file diff --git a/apps/www/public/r/styles/default/timeline.json b/apps/www/public/r/styles/default/timeline.json new file mode 100644 index 00000000000..4a89958e7dd --- /dev/null +++ b/apps/www/public/r/styles/default/timeline.json @@ -0,0 +1,15 @@ +{ + "name": "timeline", + "type": "registry:ui", + "registryDependencies": [ + "timeline-demo" + ], + "files": [ + { + "path": "ui/timeline.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Timeline = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n
\n))\nTimeline.displayName = \"Timeline\"\n\nconst TimelineItem = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n
\n))\nTimelineItem.displayName = \"TimelineItem\"\n\nconst TimelineDot = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes & {\n variant?: \"default\" | \"success\" | \"error\" | \"warning\"\n }\n>(({ className, variant = \"default\", ...props }, ref) => (\n \n))\nTimelineDot.displayName = \"TimelineDot\"\n\nconst TimelineConnector = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n))\nTimelineConnector.displayName = \"TimelineConnector\"\n\nconst TimelineContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n
\n))\nTimelineContent.displayName = \"TimelineContent\"\n\nexport {\n Timeline,\n TimelineItem,\n TimelineDot,\n TimelineConnector,\n TimelineContent,\n}\n", + "type": "registry:ui", + "target": "" + } + ] +} \ No newline at end of file diff --git a/apps/www/public/r/styles/new-york/chart-area-interactive.json b/apps/www/public/r/styles/new-york/chart-area-interactive.json index eae1d903051..1b8f590eda0 100644 --- a/apps/www/public/r/styles/new-york/chart-area-interactive.json +++ b/apps/www/public/r/styles/new-york/chart-area-interactive.json @@ -10,7 +10,7 @@ "files": [ { "path": "block/chart-area-interactive.tsx", - "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Area, AreaChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/registry/new-york/ui/card\"\nimport {\n ChartConfig,\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n} from \"@/registry/new-york/ui/chart\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/new-york/ui/select\"\nconst chartData = [\n { date: \"2024-04-01\", desktop: 222, mobile: 150 },\n { date: \"2024-04-02\", desktop: 97, mobile: 180 },\n { date: \"2024-04-03\", desktop: 167, mobile: 120 },\n { date: \"2024-04-04\", desktop: 242, mobile: 260 },\n { date: \"2024-04-05\", desktop: 373, mobile: 290 },\n { date: \"2024-04-06\", desktop: 301, mobile: 340 },\n { date: \"2024-04-07\", desktop: 245, mobile: 180 },\n { date: \"2024-04-08\", desktop: 409, mobile: 320 },\n { date: \"2024-04-09\", desktop: 59, mobile: 110 },\n { date: \"2024-04-10\", desktop: 261, mobile: 190 },\n { date: \"2024-04-11\", desktop: 327, mobile: 350 },\n { date: \"2024-04-12\", desktop: 292, mobile: 210 },\n { date: \"2024-04-13\", desktop: 342, mobile: 380 },\n { date: \"2024-04-14\", desktop: 137, mobile: 220 },\n { date: \"2024-04-15\", desktop: 120, mobile: 170 },\n { date: \"2024-04-16\", desktop: 138, mobile: 190 },\n { date: \"2024-04-17\", desktop: 446, mobile: 360 },\n { date: \"2024-04-18\", desktop: 364, mobile: 410 },\n { date: \"2024-04-19\", desktop: 243, mobile: 180 },\n { date: \"2024-04-20\", desktop: 89, mobile: 150 },\n { date: \"2024-04-21\", desktop: 137, mobile: 200 },\n { date: \"2024-04-22\", desktop: 224, mobile: 170 },\n { date: \"2024-04-23\", desktop: 138, mobile: 230 },\n { date: \"2024-04-24\", desktop: 387, mobile: 290 },\n { date: \"2024-04-25\", desktop: 215, mobile: 250 },\n { date: \"2024-04-26\", desktop: 75, mobile: 130 },\n { date: \"2024-04-27\", desktop: 383, mobile: 420 },\n { date: \"2024-04-28\", desktop: 122, mobile: 180 },\n { date: \"2024-04-29\", desktop: 315, mobile: 240 },\n { date: \"2024-04-30\", desktop: 454, mobile: 380 },\n { date: \"2024-05-01\", desktop: 165, mobile: 220 },\n { date: \"2024-05-02\", desktop: 293, mobile: 310 },\n { date: \"2024-05-03\", desktop: 247, mobile: 190 },\n { date: \"2024-05-04\", desktop: 385, mobile: 420 },\n { date: \"2024-05-05\", desktop: 481, mobile: 390 },\n { date: \"2024-05-06\", desktop: 498, mobile: 520 },\n { date: \"2024-05-07\", desktop: 388, mobile: 300 },\n { date: \"2024-05-08\", desktop: 149, mobile: 210 },\n { date: \"2024-05-09\", desktop: 227, mobile: 180 },\n { date: \"2024-05-10\", desktop: 293, mobile: 330 },\n { date: \"2024-05-11\", desktop: 335, mobile: 270 },\n { date: \"2024-05-12\", desktop: 197, mobile: 240 },\n { date: \"2024-05-13\", desktop: 197, mobile: 160 },\n { date: \"2024-05-14\", desktop: 448, mobile: 490 },\n { date: \"2024-05-15\", desktop: 473, mobile: 380 },\n { date: \"2024-05-16\", desktop: 338, mobile: 400 },\n { date: \"2024-05-17\", desktop: 499, mobile: 420 },\n { date: \"2024-05-18\", desktop: 315, mobile: 350 },\n { date: \"2024-05-19\", desktop: 235, mobile: 180 },\n { date: \"2024-05-20\", desktop: 177, mobile: 230 },\n { date: \"2024-05-21\", desktop: 82, mobile: 140 },\n { date: \"2024-05-22\", desktop: 81, mobile: 120 },\n { date: \"2024-05-23\", desktop: 252, mobile: 290 },\n { date: \"2024-05-24\", desktop: 294, mobile: 220 },\n { date: \"2024-05-25\", desktop: 201, mobile: 250 },\n { date: \"2024-05-26\", desktop: 213, mobile: 170 },\n { date: \"2024-05-27\", desktop: 420, mobile: 460 },\n { date: \"2024-05-28\", desktop: 233, mobile: 190 },\n { date: \"2024-05-29\", desktop: 78, mobile: 130 },\n { date: \"2024-05-30\", desktop: 340, mobile: 280 },\n { date: \"2024-05-31\", desktop: 178, mobile: 230 },\n { date: \"2024-06-01\", desktop: 178, mobile: 200 },\n { date: \"2024-06-02\", desktop: 470, mobile: 410 },\n { date: \"2024-06-03\", desktop: 103, mobile: 160 },\n { date: \"2024-06-04\", desktop: 439, mobile: 380 },\n { date: \"2024-06-05\", desktop: 88, mobile: 140 },\n { date: \"2024-06-06\", desktop: 294, mobile: 250 },\n { date: \"2024-06-07\", desktop: 323, mobile: 370 },\n { date: \"2024-06-08\", desktop: 385, mobile: 320 },\n { date: \"2024-06-09\", desktop: 438, mobile: 480 },\n { date: \"2024-06-10\", desktop: 155, mobile: 200 },\n { date: \"2024-06-11\", desktop: 92, mobile: 150 },\n { date: \"2024-06-12\", desktop: 492, mobile: 420 },\n { date: \"2024-06-13\", desktop: 81, mobile: 130 },\n { date: \"2024-06-14\", desktop: 426, mobile: 380 },\n { date: \"2024-06-15\", desktop: 307, mobile: 350 },\n { date: \"2024-06-16\", desktop: 371, mobile: 310 },\n { date: \"2024-06-17\", desktop: 475, mobile: 520 },\n { date: \"2024-06-18\", desktop: 107, mobile: 170 },\n { date: \"2024-06-19\", desktop: 341, mobile: 290 },\n { date: \"2024-06-20\", desktop: 408, mobile: 450 },\n { date: \"2024-06-21\", desktop: 169, mobile: 210 },\n { date: \"2024-06-22\", desktop: 317, mobile: 270 },\n { date: \"2024-06-23\", desktop: 480, mobile: 530 },\n { date: \"2024-06-24\", desktop: 132, mobile: 180 },\n { date: \"2024-06-25\", desktop: 141, mobile: 190 },\n { date: \"2024-06-26\", desktop: 434, mobile: 380 },\n { date: \"2024-06-27\", desktop: 448, mobile: 490 },\n { date: \"2024-06-28\", desktop: 149, mobile: 200 },\n { date: \"2024-06-29\", desktop: 103, mobile: 160 },\n { date: \"2024-06-30\", desktop: 446, mobile: 400 },\n]\n\nconst chartConfig = {\n visitors: {\n label: \"Visitors\",\n },\n desktop: {\n label: \"Desktop\",\n color: \"hsl(var(--chart-1))\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"hsl(var(--chart-2))\",\n },\n} satisfies ChartConfig\n\nexport default function Component() {\n const [timeRange, setTimeRange] = React.useState(\"90d\")\n\n const filteredData = chartData.filter((item) => {\n const date = new Date(item.date)\n const now = new Date()\n let daysToSubtract = 90\n if (timeRange === \"30d\") {\n daysToSubtract = 30\n } else if (timeRange === \"7d\") {\n daysToSubtract = 7\n }\n now.setDate(now.getDate() - daysToSubtract)\n return date >= now\n })\n\n return (\n \n \n
\n Area Chart - Interactive\n \n Showing total visitors for the last 3 months\n \n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {\n const date = new Date(value)\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n />\n {\n return new Date(value).toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n indicator=\"dot\"\n />\n }\n />\n \n \n } />\n \n \n \n
\n )\n}\n", + "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Area, AreaChart, CartesianGrid, XAxis } from \"recharts\"\n\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/registry/new-york/ui/card\"\nimport {\n ChartConfig,\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n} from \"@/registry/new-york/ui/chart\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/new-york/ui/select\"\nconst chartData = [\n { date: \"2024-04-01\", desktop: 222, mobile: 150 },\n { date: \"2024-04-02\", desktop: 97, mobile: 180 },\n { date: \"2024-04-03\", desktop: 167, mobile: 120 },\n { date: \"2024-04-04\", desktop: 242, mobile: 260 },\n { date: \"2024-04-05\", desktop: 373, mobile: 290 },\n { date: \"2024-04-06\", desktop: 301, mobile: 340 },\n { date: \"2024-04-07\", desktop: 245, mobile: 180 },\n { date: \"2024-04-08\", desktop: 409, mobile: 320 },\n { date: \"2024-04-09\", desktop: 59, mobile: 110 },\n { date: \"2024-04-10\", desktop: 261, mobile: 190 },\n { date: \"2024-04-11\", desktop: 327, mobile: 350 },\n { date: \"2024-04-12\", desktop: 292, mobile: 210 },\n { date: \"2024-04-13\", desktop: 342, mobile: 380 },\n { date: \"2024-04-14\", desktop: 137, mobile: 220 },\n { date: \"2024-04-15\", desktop: 120, mobile: 170 },\n { date: \"2024-04-16\", desktop: 138, mobile: 190 },\n { date: \"2024-04-17\", desktop: 446, mobile: 360 },\n { date: \"2024-04-18\", desktop: 364, mobile: 410 },\n { date: \"2024-04-19\", desktop: 243, mobile: 180 },\n { date: \"2024-04-20\", desktop: 89, mobile: 150 },\n { date: \"2024-04-21\", desktop: 137, mobile: 200 },\n { date: \"2024-04-22\", desktop: 224, mobile: 170 },\n { date: \"2024-04-23\", desktop: 138, mobile: 230 },\n { date: \"2024-04-24\", desktop: 387, mobile: 290 },\n { date: \"2024-04-25\", desktop: 215, mobile: 250 },\n { date: \"2024-04-26\", desktop: 75, mobile: 130 },\n { date: \"2024-04-27\", desktop: 383, mobile: 420 },\n { date: \"2024-04-28\", desktop: 122, mobile: 180 },\n { date: \"2024-04-29\", desktop: 315, mobile: 240 },\n { date: \"2024-04-30\", desktop: 454, mobile: 380 },\n { date: \"2024-05-01\", desktop: 165, mobile: 220 },\n { date: \"2024-05-02\", desktop: 293, mobile: 310 },\n { date: \"2024-05-03\", desktop: 247, mobile: 190 },\n { date: \"2024-05-04\", desktop: 385, mobile: 420 },\n { date: \"2024-05-05\", desktop: 481, mobile: 390 },\n { date: \"2024-05-06\", desktop: 498, mobile: 520 },\n { date: \"2024-05-07\", desktop: 388, mobile: 300 },\n { date: \"2024-05-08\", desktop: 149, mobile: 210 },\n { date: \"2024-05-09\", desktop: 227, mobile: 180 },\n { date: \"2024-05-10\", desktop: 293, mobile: 330 },\n { date: \"2024-05-11\", desktop: 335, mobile: 270 },\n { date: \"2024-05-12\", desktop: 197, mobile: 240 },\n { date: \"2024-05-13\", desktop: 197, mobile: 160 },\n { date: \"2024-05-14\", desktop: 448, mobile: 490 },\n { date: \"2024-05-15\", desktop: 473, mobile: 380 },\n { date: \"2024-05-16\", desktop: 338, mobile: 400 },\n { date: \"2024-05-17\", desktop: 499, mobile: 420 },\n { date: \"2024-05-18\", desktop: 315, mobile: 350 },\n { date: \"2024-05-19\", desktop: 235, mobile: 180 },\n { date: \"2024-05-20\", desktop: 177, mobile: 230 },\n { date: \"2024-05-21\", desktop: 82, mobile: 140 },\n { date: \"2024-05-22\", desktop: 81, mobile: 120 },\n { date: \"2024-05-23\", desktop: 252, mobile: 290 },\n { date: \"2024-05-24\", desktop: 294, mobile: 220 },\n { date: \"2024-05-25\", desktop: 201, mobile: 250 },\n { date: \"2024-05-26\", desktop: 213, mobile: 170 },\n { date: \"2024-05-27\", desktop: 420, mobile: 460 },\n { date: \"2024-05-28\", desktop: 233, mobile: 190 },\n { date: \"2024-05-29\", desktop: 78, mobile: 130 },\n { date: \"2024-05-30\", desktop: 340, mobile: 280 },\n { date: \"2024-05-31\", desktop: 178, mobile: 230 },\n { date: \"2024-06-01\", desktop: 178, mobile: 200 },\n { date: \"2024-06-02\", desktop: 470, mobile: 410 },\n { date: \"2024-06-03\", desktop: 103, mobile: 160 },\n { date: \"2024-06-04\", desktop: 439, mobile: 380 },\n { date: \"2024-06-05\", desktop: 88, mobile: 140 },\n { date: \"2024-06-06\", desktop: 294, mobile: 250 },\n { date: \"2024-06-07\", desktop: 323, mobile: 370 },\n { date: \"2024-06-08\", desktop: 385, mobile: 320 },\n { date: \"2024-06-09\", desktop: 438, mobile: 480 },\n { date: \"2024-06-10\", desktop: 155, mobile: 200 },\n { date: \"2024-06-11\", desktop: 92, mobile: 150 },\n { date: \"2024-06-12\", desktop: 492, mobile: 420 },\n { date: \"2024-06-13\", desktop: 81, mobile: 130 },\n { date: \"2024-06-14\", desktop: 426, mobile: 380 },\n { date: \"2024-06-15\", desktop: 307, mobile: 350 },\n { date: \"2024-06-16\", desktop: 371, mobile: 310 },\n { date: \"2024-06-17\", desktop: 475, mobile: 520 },\n { date: \"2024-06-18\", desktop: 107, mobile: 170 },\n { date: \"2024-06-19\", desktop: 341, mobile: 290 },\n { date: \"2024-06-20\", desktop: 408, mobile: 450 },\n { date: \"2024-06-21\", desktop: 169, mobile: 210 },\n { date: \"2024-06-22\", desktop: 317, mobile: 270 },\n { date: \"2024-06-23\", desktop: 480, mobile: 530 },\n { date: \"2024-06-24\", desktop: 132, mobile: 180 },\n { date: \"2024-06-25\", desktop: 141, mobile: 190 },\n { date: \"2024-06-26\", desktop: 434, mobile: 380 },\n { date: \"2024-06-27\", desktop: 448, mobile: 490 },\n { date: \"2024-06-28\", desktop: 149, mobile: 200 },\n { date: \"2024-06-29\", desktop: 103, mobile: 160 },\n { date: \"2024-06-30\", desktop: 446, mobile: 400 },\n]\n\nconst chartConfig = {\n visitors: {\n label: \"Visitors\",\n },\n desktop: {\n label: \"Desktop\",\n color: \"hsl(var(--chart-1))\",\n },\n mobile: {\n label: \"Mobile\",\n color: \"hsl(var(--chart-2))\",\n },\n} satisfies ChartConfig\n\nexport default function Component() {\n const [timeRange, setTimeRange] = React.useState(\"90d\")\n\n const filteredData = chartData.filter((item) => {\n const date = new Date(item.date)\n const referenceDate = new Date(\"2024-06-30\")\n let daysToSubtract = 90\n if (timeRange === \"30d\") {\n daysToSubtract = 30\n } else if (timeRange === \"7d\") {\n daysToSubtract = 7\n }\n const startDate = new Date(referenceDate)\n startDate.setDate(startDate.getDate() - daysToSubtract)\n return date >= startDate\n })\n\n return (\n \n \n
\n Area Chart - Interactive\n \n Showing total visitors for the last 3 months\n \n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {\n const date = new Date(value)\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n />\n {\n return new Date(value).toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n })\n }}\n indicator=\"dot\"\n />\n }\n />\n \n \n } />\n \n \n \n
\n )\n}\n", "type": "registry:component", "target": "" } diff --git a/apps/www/public/r/styles/new-york/timeline-demo.json b/apps/www/public/r/styles/new-york/timeline-demo.json new file mode 100644 index 00000000000..561320cab8f --- /dev/null +++ b/apps/www/public/r/styles/new-york/timeline-demo.json @@ -0,0 +1,15 @@ +{ + "name": "timeline-demo", + "type": "registry:example", + "registryDependencies": [ + "timeline" + ], + "files": [ + { + "path": "example/timeline-demo.tsx", + "content": "import { CalendarIcon, CheckCircleIcon, StarIcon } from \"lucide-react\"\nimport {\n Timeline,\n TimelineConnector,\n TimelineContent,\n TimelineDot,\n TimelineItem,\n} from \"@/registry/new-york/ui/timeline\"\n\nexport default function TimelineDemo() {\n return (\n \n \n \n \n \n \n \n

Project Started

\n

\n Kickoff meeting with the team\n

\n
\n
\n \n \n \n \n \n \n

Design Phase Complete

\n

\n UI/UX designs approved by stakeholders\n

\n
\n
\n \n \n \n \n \n

Development In Progress

\n

\n Frontend implementation started\n

\n
\n
\n
\n )\n}\n", + "type": "registry:example", + "target": "" + } + ] +} \ No newline at end of file diff --git a/apps/www/public/r/styles/new-york/timeline.json b/apps/www/public/r/styles/new-york/timeline.json new file mode 100644 index 00000000000..a1c80900b32 --- /dev/null +++ b/apps/www/public/r/styles/new-york/timeline.json @@ -0,0 +1,15 @@ +{ + "name": "timeline", + "type": "registry:ui", + "registryDependencies": [ + "timeline-demo" + ], + "files": [ + { + "path": "ui/timeline.tsx", + "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Timeline = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n
\n))\nTimeline.displayName = \"Timeline\"\n\nconst TimelineItem = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n
\n))\nTimelineItem.displayName = \"TimelineItem\"\n\nconst TimelineDot = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes & {\n variant?: \"default\" | \"success\" | \"error\" | \"warning\"\n }\n>(({ className, variant = \"default\", ...props }, ref) => (\n \n))\nTimelineDot.displayName = \"TimelineDot\"\n\nconst TimelineConnector = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n))\nTimelineConnector.displayName = \"TimelineConnector\"\n\nconst TimelineContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n
\n))\nTimelineContent.displayName = \"TimelineContent\"\n\nexport {\n Timeline,\n TimelineConnector,\n TimelineContent,\n TimelineDot,\n TimelineItem,\n}\n", + "type": "registry:ui", + "target": "" + } + ] +} \ No newline at end of file diff --git a/apps/www/registry/default/example/timeline-demo.tsx b/apps/www/registry/default/example/timeline-demo.tsx new file mode 100644 index 00000000000..66d7f27ed74 --- /dev/null +++ b/apps/www/registry/default/example/timeline-demo.tsx @@ -0,0 +1,51 @@ +import { CalendarIcon, CheckCircleIcon, StarIcon } from "lucide-react" + +import { + Timeline, + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, +} from "@/registry/default/ui/timeline" + +export default function TimelineDemo() { + return ( + + + + + + + +

Project Started

+

+ Kickoff meeting with the team +

+
+
+ + + + + + +

Design Phase Complete

+

+ UI/UX designs approved by stakeholders +

+
+
+ + + + + +

Development In Progress

+

+ Frontend implementation started +

+
+
+
+ ) +} diff --git a/apps/www/registry/default/ui/timeline.tsx b/apps/www/registry/default/ui/timeline.tsx new file mode 100644 index 00000000000..550a94eeec0 --- /dev/null +++ b/apps/www/registry/default/ui/timeline.tsx @@ -0,0 +1,75 @@ +"use client" + +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Timeline = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Timeline.displayName = "Timeline" + +const TimelineItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TimelineItem.displayName = "TimelineItem" + +const TimelineDot = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & { + variant?: "default" | "success" | "error" | "warning" + } +>(({ className, variant = "default", ...props }, ref) => ( +
+)) +TimelineDot.displayName = "TimelineDot" + +const TimelineConnector = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TimelineConnector.displayName = "TimelineConnector" + +const TimelineContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TimelineContent.displayName = "TimelineContent" + +export { + Timeline, + TimelineItem, + TimelineDot, + TimelineConnector, + TimelineContent, +} diff --git a/apps/www/registry/new-york/example/timeline-demo.tsx b/apps/www/registry/new-york/example/timeline-demo.tsx new file mode 100644 index 00000000000..634f29e035a --- /dev/null +++ b/apps/www/registry/new-york/example/timeline-demo.tsx @@ -0,0 +1,51 @@ +import { CalendarIcon, CheckCircleIcon, StarIcon } from "lucide-react" + +import { + Timeline, + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, +} from "@/registry/new-york/ui/timeline" + +export default function TimelineDemo() { + return ( + + + + + + + +

Project Started

+

+ Kickoff meeting with the team +

+
+
+ + + + + + +

Design Phase Complete

+

+ UI/UX designs approved by stakeholders +

+
+
+ + + + + +

Development In Progress

+

+ Frontend implementation started +

+
+
+
+ ) +} diff --git a/apps/www/registry/new-york/ui/timeline.tsx b/apps/www/registry/new-york/ui/timeline.tsx new file mode 100644 index 00000000000..b8012fa7b0b --- /dev/null +++ b/apps/www/registry/new-york/ui/timeline.tsx @@ -0,0 +1,75 @@ +"use client" + +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Timeline = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Timeline.displayName = "Timeline" + +const TimelineItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TimelineItem.displayName = "TimelineItem" + +const TimelineDot = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & { + variant?: "default" | "success" | "error" | "warning" + } +>(({ className, variant = "default", ...props }, ref) => ( +
+)) +TimelineDot.displayName = "TimelineDot" + +const TimelineConnector = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TimelineConnector.displayName = "TimelineConnector" + +const TimelineContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TimelineContent.displayName = "TimelineContent" + +export { + Timeline, + TimelineConnector, + TimelineContent, + TimelineDot, + TimelineItem, +} diff --git a/apps/www/registry/registry-examples.ts b/apps/www/registry/registry-examples.ts index c4806706582..2efdd928bcd 100644 --- a/apps/www/registry/registry-examples.ts +++ b/apps/www/registry/registry-examples.ts @@ -1,6 +1,17 @@ import { Registry } from "@/registry/schema" export const examples: Registry = [ + { + name: "timeline-demo", + type: "registry:example", + registryDependencies: ["timeline"], + files: [ + { + path: "example/timeline-demo.tsx", + type: "registry:example", + }, + ], + }, { name: "accordion-demo", type: "registry:example", diff --git a/apps/www/registry/registry-ui.ts b/apps/www/registry/registry-ui.ts index 4870f3abb1c..bb4e7ff5a09 100644 --- a/apps/www/registry/registry-ui.ts +++ b/apps/www/registry/registry-ui.ts @@ -598,6 +598,17 @@ export const ui: Registry = [ }, ], }, + { + name: "timeline", + type: "registry:ui", + files: [ + { + path: "ui/timeline.tsx", + type: "registry:ui", + }, + ], + registryDependencies: ["timeline-demo"], + }, { name: "tooltip", type: "registry:ui", diff --git a/package.json b/package.json index d33ecaae951..a137c1275c2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "ui", + "name": "shadcnui", "version": "0.0.1", "private": true, "license": "MIT",