{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"timeline","type":"registry:ui","title":"Timeline","description":"","dependencies":["@base-ui/react","cn"],"registryDependencies":[],"files":[{"path":"timeline.tsx","type":"registry:ui","content":"\"use client\"\n\nimport { createContext, useCallback, useContext, useState } from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\n\nimport { cn } from \"cn\"\n\n// Types\ntype TimelineContextValue = {\n  activeStep: number\n  setActiveStep: (step: number) => void\n}\n\n// Context\nconst TimelineContext = createContext<TimelineContextValue | undefined>(\n  undefined\n)\n\nconst useTimeline = () => {\n  const context = useContext(TimelineContext)\n  if (!context) {\n    throw new Error(\"useTimeline must be used within a Timeline\")\n  }\n  return context\n}\n\n// Components\ninterface TimelineProps extends useRender.ComponentProps<\"div\"> {\n  defaultValue?: number\n  value?: number\n  onValueChange?: (value: number) => void\n  orientation?: \"horizontal\" | \"vertical\"\n}\n\nfunction Timeline({\n  defaultValue = 1,\n  value,\n  onValueChange,\n  orientation = \"vertical\",\n  className,\n  render,\n  children,\n  ...props\n}: TimelineProps) {\n  const [activeStep, setInternalStep] = useState(defaultValue)\n\n  const setActiveStep = useCallback(\n    (step: number) => {\n      if (value === undefined) {\n        setInternalStep(step)\n      }\n      onValueChange?.(step)\n    },\n    [value, onValueChange]\n  )\n\n  const currentStep = value ?? activeStep\n\n  const defaultProps = {\n    className: cn(\n      \"group/timeline flex data-[orientation=horizontal]:w-full data-[orientation=horizontal]:flex-row data-[orientation=vertical]:flex-col\",\n      className\n    ),\n    \"data-orientation\": orientation,\n    \"data-slot\": \"timeline\",\n    children,\n  }\n\n  return (\n    <TimelineContext.Provider\n      value={{ activeStep: currentStep, setActiveStep }}\n    >\n      {useRender({\n        defaultTagName: \"div\",\n        render,\n        props: mergeProps<\"div\">(defaultProps, props),\n      })}\n    </TimelineContext.Provider>\n  )\n}\n\n// TimelineContent\nfunction TimelineContent({\n  className,\n  render,\n  children,\n  ...props\n}: useRender.ComponentProps<\"div\">) {\n  const defaultProps = {\n    className: cn(\"text-muted-foreground text-sm\", className),\n    \"data-slot\": \"timeline-content\",\n    children,\n  }\n\n  return useRender({\n    defaultTagName: \"div\",\n    render,\n    props: mergeProps<\"div\">(defaultProps, props),\n  })\n}\n\n// TimelineDate\ntype TimelineDateProps = useRender.ComponentProps<\"time\">\n\nfunction TimelineDate({\n  className,\n  render,\n  children,\n  ...props\n}: TimelineDateProps) {\n  const defaultProps = {\n    className: cn(\n      \"mb-1 block font-medium text-muted-foreground text-xs group-data-[orientation=vertical]/timeline:max-sm:h-4\",\n      className\n    ),\n    \"data-slot\": \"timeline-date\",\n    children,\n  }\n\n  return useRender({\n    defaultTagName: \"time\",\n    render,\n    props: mergeProps<\"time\">(defaultProps, props),\n  })\n}\n\n// TimelineHeader\nfunction TimelineHeader({\n  className,\n  render,\n  children,\n  ...props\n}: useRender.ComponentProps<\"div\">) {\n  const defaultProps = {\n    className: cn(className),\n    \"data-slot\": \"timeline-header\",\n    children,\n  }\n\n  return useRender({\n    defaultTagName: \"div\",\n    render,\n    props: mergeProps<\"div\">(defaultProps, props),\n  })\n}\n\n// TimelineIndicator\ntype TimelineIndicatorProps = useRender.ComponentProps<\"div\">\n\nfunction TimelineIndicator({\n  className,\n  children,\n  render,\n  ...props\n}: TimelineIndicatorProps) {\n  const defaultProps = {\n    \"aria-hidden\": true,\n    className: cn(\n      \"group-data-[orientation=horizontal]/timeline:-top-6 group-data-[orientation=horizontal]/timeline:-translate-y-1/2 group-data-[orientation=vertical]/timeline:-left-6 group-data-[orientation=vertical]/timeline:-translate-x-1/2 absolute size-4 rounded-full border-2 border-primary/20 group-data-[orientation=vertical]/timeline:top-0 group-data-[orientation=horizontal]/timeline:left-0 group-data-completed/timeline-item:border-primary\",\n      className\n    ),\n    \"data-slot\": \"timeline-indicator\",\n    children,\n  }\n\n  return useRender({\n    defaultTagName: \"div\",\n    render,\n    props: mergeProps<\"div\">(defaultProps, props),\n  })\n}\n\n// TimelineItem\ninterface TimelineItemProps extends useRender.ComponentProps<\"div\"> {\n  step: number\n}\n\nfunction TimelineItem({\n  step,\n  className,\n  render,\n  children,\n  ...props\n}: TimelineItemProps) {\n  const { activeStep } = useTimeline()\n\n  const defaultProps = {\n    className: cn(\n      \"group/timeline-item relative flex flex-1 flex-col gap-0.5 group-data-[orientation=vertical]/timeline:ms-8 group-data-[orientation=horizontal]/timeline:mt-8 group-data-[orientation=horizontal]/timeline:not-last:pe-8 group-data-[orientation=vertical]/timeline:not-last:pb-6 has-[+[data-completed]]:**:data-[slot=timeline-separator]:bg-primary\",\n      className\n    ),\n    \"data-completed\": step <= activeStep || undefined,\n    \"data-slot\": \"timeline-item\",\n    children,\n  }\n\n  return useRender({\n    defaultTagName: \"div\",\n    render,\n    props: mergeProps<\"div\">(defaultProps, props),\n  })\n}\n\n// TimelineSeparator\nfunction TimelineSeparator({\n  className,\n  render,\n  children,\n  ...props\n}: useRender.ComponentProps<\"div\">) {\n  const defaultProps = {\n    \"aria-hidden\": true,\n    className: cn(\n      \"group-data-[orientation=horizontal]/timeline:-top-6 group-data-[orientation=horizontal]/timeline:-translate-y-1/2 group-data-[orientation=vertical]/timeline:-left-6 group-data-[orientation=vertical]/timeline:-translate-x-1/2 absolute self-start bg-primary/10 group-last/timeline-item:hidden group-data-[orientation=horizontal]/timeline:h-0.5 group-data-[orientation=vertical]/timeline:h-[calc(100%-1rem-0.25rem)] group-data-[orientation=horizontal]/timeline:w-[calc(100%-1rem-0.25rem)] group-data-[orientation=vertical]/timeline:w-0.5 group-data-[orientation=horizontal]/timeline:translate-x-4.5 group-data-[orientation=vertical]/timeline:translate-y-4.5\",\n      className\n    ),\n    \"data-slot\": \"timeline-separator\",\n    children,\n  }\n\n  return useRender({\n    defaultTagName: \"div\",\n    render,\n    props: mergeProps<\"div\">(defaultProps, props),\n  })\n}\n\n// TimelineTitle\nfunction TimelineTitle({\n  className,\n  render,\n  children,\n  ...props\n}: useRender.ComponentProps<\"h3\">) {\n  const defaultProps = {\n    className: cn(\"font-medium text-sm\", className),\n    \"data-slot\": \"timeline-title\",\n    children,\n  }\n\n  return useRender({\n    defaultTagName: \"h3\",\n    render,\n    props: mergeProps<\"h3\">(defaultProps, props),\n  })\n}\n\nexport {\n  Timeline,\n  TimelineContent,\n  TimelineDate,\n  TimelineHeader,\n  TimelineIndicator,\n  TimelineItem,\n  TimelineSeparator,\n  TimelineTitle,\n}","target":"components/reui/timeline.tsx"}]}