Release Workflow Illustration
navdeep-singh/release-workflow-illustrationFreeComponent
An interactive release tracker with configurable workflow data and autoplay.
Install it
npx shadcn@latest add https://ui.navdeepsingh.dev/r/release-workflow-illustration.jsonSource
1'use client'23import { useEffect, useId, useState } from 'react'4import { AnimatePresence, motion, useReducedMotion } from 'motion/react'5import { Check, ChevronDown, GitCommit, Rocket } from 'lucide-react'67import { cn } from '@/lib/utils'89export type ContentSectionThreeRelease = {10 name: string11 version: string12 status: string13 time: string14 environment?: string15 commit?: string16 note?: string17}1819export type ContentSectionThreeWorkflow = {20 label?: string21 releases?: readonly ContentSectionThreeRelease[]22}2324export type ReleaseWorkflowIllustrationProps = {25 workflow?: ContentSectionThreeWorkflow26 autoPlay?: boolean27 interval?: number28}2930export const defaultReleaseWorkflow: ContentSectionThreeWorkflow = {31 label: 'Releases',32 releases: [33 {34 name: 'Platform',35 version: '2.4.0',36 status: 'Released',37 time: '2h ago',38 environment: 'Production',39 commit: '7f3c2a1',40 },41 {42 name: 'Dashboard',43 version: '1.18.0',44 status: 'Ready',45 time: 'Today',46 environment: 'Staging',47 commit: '8b61d4e',48 },49 {50 name: 'Mobile',51 version: '1.9.0',52 status: 'In review',53 time: 'Yesterday',54 environment: 'TestFlight',55 commit: 'c129ef4',56 },57 ],58}5960export function ReleaseWorkflowIllustration({61 workflow = defaultReleaseWorkflow,62 autoPlay = true,63 interval = 4000,64}: ReleaseWorkflowIllustrationProps) {65 const instanceId = useId()66 const shouldReduceMotion = useReducedMotion()6768 const releases = workflow.releases ?? defaultReleaseWorkflow.releases ?? []6970 const [selectedIndex, setSelectedIndex] = useState(0)71 const [isPointerInside, setIsPointerInside] = useState(false)72 const [hasFocusWithin, setHasFocusWithin] = useState(false)7374 const activeIndex = Math.min(selectedIndex, Math.max(releases.length - 1, 0))7576 const activeRelease = releases[activeIndex]77 const isPaused = isPointerInside || hasFocusWithin7879 useEffect(() => {80 if (!autoPlay || shouldReduceMotion || isPaused || releases.length <= 1) {81 return82 }8384 const timeout = window.setTimeout(() => {85 setSelectedIndex((currentIndex) => {86 return (currentIndex + 1) % releases.length87 })88 }, interval)8990 return () => window.clearTimeout(timeout)91 }, [activeIndex, autoPlay, interval, isPaused, releases.length, shouldReduceMotion])9293 return (94 <div95 id="release-workflow"96 aria-label="Interactive release tracking preview"97// … truncated
What it pulls in
npm packages
Files it writes
More from navdeep-singh
All 64 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Groupanimated-group | navdeep-singh | Components | Free | 1 dep | |
| Animated Numbersanimated-numbers | navdeep-singh | Components | Free | 1 dep | |
| Animated Tabsanimated-tabs | navdeep-singh | Components | Free | 2 deps | |
| Approval Panel Illustrationapproval-panel | navdeep-singh | Components | Free | 2 deps · 2 files | |
| Brand Logobrand-logo | navdeep-singh | Components | Free | 1 dep | |
| Contribution Graphcontribution-graph | navdeep-singh | Components | Free | no deps | |
| Designed for Focus Illustrationdesigned-for-focus-illustration | navdeep-singh | Components | Free | 1 dep | |
| Expandable Cardexpandable-card | navdeep-singh | Components | Free | 4 deps |
