{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "booking-timeline-item",
  "title": "Booking Timeline Item",
  "description": "Booking timeline row primitive with indicator rail and content slot.",
  "registryDependencies": [
    "@blocks/map",
    "@circle-ui/button",
    "@circle-ui/utils"
  ],
  "files": [
    {
      "path": "registry/berlin/blocks/booking-timeline.tsx",
      "content": "// Generated from packages/ui/src/components/booking-timeline.tsx\nimport * as React from \"react\";\n\nimport { Button, type ButtonProps } from \"@/registry/berlin/circle-ui/button\";\nimport { Map, type MapProps } from \"@/registry/berlin/blocks/map\";\nimport { cn } from \"@/registry/berlin/lib/utils\";\n\nexport type BookingTimelineTheme = \"berlin\" | \"munich\";\nexport type BookingTimelineIndicatorState =\n  | \"current\"\n  | \"upcoming\"\n  | \"completed\";\nexport type BookingTimelineTodoStatus = \"complete\" | \"outstanding\";\n\nfunction CheckIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={className}\n      viewBox=\"0 0 16 16\"\n      fill=\"none\"\n    >\n      <path\n        d=\"M3.5 8 6.5 11 12.5 4.75\"\n        stroke=\"currentColor\"\n        strokeWidth=\"1.75\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n      />\n    </svg>\n  );\n}\n\nexport interface BookingTimelineProgressDotProps {\n  className?: string;\n  state?: BookingTimelineIndicatorState;\n  theme?: BookingTimelineTheme;\n}\n\nexport function BookingTimelineProgressDot({\n  className,\n  state = \"current\",\n  theme = \"berlin\",\n}: BookingTimelineProgressDotProps) {\n  if (theme === \"munich\") {\n    if (state === \"completed\") {\n      return (\n        <span\n          className={cn(\n            \"inline-flex size-6 items-center justify-center rounded-full text-circle-grey\",\n            className,\n          )}\n        >\n          <CheckIcon className=\"size-4\" />\n        </span>\n      );\n    }\n\n    return (\n      <span\n        className={cn(\n          \"inline-flex size-6 rounded-full border-solid border-background\",\n          state === \"current\"\n            ? \"border-4 bg-circle-gold\"\n            : \"border-[8px] bg-circle-beige\",\n          className,\n        )}\n      />\n    );\n  }\n\n  return (\n    <span\n      className={cn(\n        \"inline-flex size-6 rounded-full border-[6px] border-foreground bg-background\",\n        className,\n      )}\n    />\n  );\n}\n\nexport interface BookingTimelineProgressSeparatorProps {\n  className?: string;\n  state?: BookingTimelineIndicatorState;\n  theme?: BookingTimelineTheme;\n}\n\nexport function BookingTimelineProgressSeparator({\n  className,\n  state = \"current\",\n  theme = \"berlin\",\n}: BookingTimelineProgressSeparatorProps) {\n  if (theme === \"munich\") {\n    return (\n      <span\n        className={cn(\n          \"block w-1 rounded-lg\",\n          state === \"current\"\n            ? \"bg-[linear-gradient(180deg,var(--color-circle-gold)_0%,#DCCFBE_100%)]\"\n            : \"bg-[#dccfbe]\",\n          className,\n        )}\n      />\n    );\n  }\n\n  return (\n    <span\n      className={cn(\n        \"block w-1 border-l-2 border-dashed border-[rgba(40,44,47,0.2)]\",\n        className,\n      )}\n    />\n  );\n}\n\nexport interface BookingTimelineIndicatorProps {\n  className?: string;\n  dotClassName?: string;\n  lastChild?: boolean;\n  state?: BookingTimelineIndicatorState;\n  theme?: BookingTimelineTheme;\n}\n\nexport function BookingTimelineIndicator({\n  className,\n  dotClassName,\n  lastChild = false,\n  state = \"current\",\n  theme = \"berlin\",\n}: BookingTimelineIndicatorProps) {\n  const shouldOffset = !(theme === \"munich\" && state === \"completed\");\n  const showSeparator = !lastChild && state !== \"completed\";\n\n  return (\n    <div\n      className={cn(\n        \"flex w-6 shrink-0 flex-col items-center\",\n        shouldOffset && \"pt-3\",\n        className,\n      )}\n    >\n      <BookingTimelineProgressDot\n        className={cn(\"shrink-0\", dotClassName)}\n        state={state}\n        theme={theme}\n      />\n      {showSeparator ? (\n        <BookingTimelineProgressSeparator\n          className=\"mt-3 min-h-0 flex-1\"\n          state={state}\n          theme={theme}\n        />\n      ) : null}\n    </div>\n  );\n}\n\nexport interface BookingTimelineStepBasicsProps {\n  action?: React.ReactNode;\n  className?: string;\n  description?: React.ReactNode;\n  eyebrow?: React.ReactNode;\n  image?: React.ReactNode;\n  title: React.ReactNode;\n  variant?: \"generic\" | \"variant2\";\n}\n\nexport function BookingTimelineStepBasics({\n  action,\n  className,\n  description,\n  eyebrow,\n  image,\n  title,\n  variant = \"generic\",\n}: BookingTimelineStepBasicsProps) {\n  return (\n    <div className={cn(\"flex flex-col items-start\", className)}>\n      {eyebrow ? (\n        <div className=\"w-full text-[12px] leading-[18px] tracking-[-0.12px] text-muted-foreground\">\n          {eyebrow}\n        </div>\n      ) : null}\n      <div className=\"flex w-full items-start gap-4\">\n        <div className=\"min-w-0 flex-1 space-y-2\">\n          <div className=\"text-[16px] font-medium leading-6 tracking-[-0.02em]\">\n            {title}\n          </div>\n          {description ? (\n            <div className=\"text-[14px] leading-6 tracking-[-0.14px] text-muted-foreground\">\n              {description}\n            </div>\n          ) : null}\n          {variant === \"generic\" && action ? <div>{action}</div> : null}\n        </div>\n        {image ? (\n          <div className=\"size-16 shrink-0 overflow-hidden rounded-xl bg-muted\">\n            {image}\n          </div>\n        ) : null}\n      </div>\n      {variant === \"variant2\" && action ? (\n        <div className=\"mt-4\">{action}</div>\n      ) : null}\n    </div>\n  );\n}\n\nexport interface BookingTimelineStepContentNotesProps {\n  className?: string;\n  header?: React.ReactNode;\n  headerIcon?: React.ReactNode;\n  items: React.ReactNode[];\n}\n\nexport function BookingTimelineStepContentNotes({\n  className,\n  header = \"Important\",\n  headerIcon,\n  items,\n}: BookingTimelineStepContentNotesProps) {\n  return (\n    <div className={cn(\"flex flex-col gap-2\", className)}>\n      <div className=\"flex w-full items-center gap-1\">\n        {headerIcon ? (\n          <span className=\"inline-flex size-4 shrink-0 items-center justify-center\">\n            {headerIcon}\n          </span>\n        ) : null}\n        <div className=\"flex-1 text-[12px] font-semibold uppercase leading-4 tracking-[0.04em]\">\n          {header}\n        </div>\n      </div>\n      <ul className=\"space-y-2 pl-[21px] text-[14px] font-medium leading-6 tracking-[-0.02em] marker:text-current\">\n        {items.map((item, index) => (\n          <li key={index}>{item}</li>\n        ))}\n      </ul>\n    </div>\n  );\n}\n\nexport type BookingTimelineDirectionsRoute = {\n  icon: React.ReactNode;\n  id?: React.Key;\n  label: React.ReactNode;\n};\n\nexport interface BookingTimelineStepContentDirectionsProps {\n  address: React.ReactNode;\n  className?: string;\n  map?: React.ReactNode;\n  mapProps?: MapProps;\n  routes: BookingTimelineDirectionsRoute[];\n}\n\nexport function BookingTimelineStepContentDirections({\n  address,\n  className,\n  map,\n  mapProps,\n  routes,\n}: BookingTimelineStepContentDirectionsProps) {\n  const renderedMap = map ?? (\n    <Map\n      {...mapProps}\n      style={{\n        aspectRatio: \"309 / 175\",\n        minHeight: 175,\n        width: \"100%\",\n        ...mapProps?.style,\n      }}\n    />\n  );\n\n  return (\n    <div className={cn(\"flex flex-col gap-4\", className)}>\n      {routes.map((route, index) => (\n        <div\n          key={route.id ?? index}\n          className=\"flex items-start gap-2 text-[16px] leading-6 tracking-[-0.16px]\"\n        >\n          <span className=\"inline-flex size-6 shrink-0 items-center justify-center\">\n            {route.icon}\n          </span>\n          <span>{route.label}</span>\n        </div>\n      ))}\n      <div className=\"flex flex-col gap-2\">\n        <div className=\"overflow-hidden rounded-lg\">{renderedMap}</div>\n        <div className=\"pr-3 text-[16px] leading-6 tracking-[-0.16px] text-muted-foreground\">\n          {address}\n        </div>\n      </div>\n    </div>\n  );\n}\n\nexport interface BookingTimelineTodoStatusIndicatorProps {\n  className?: string;\n  status?: BookingTimelineTodoStatus;\n}\n\nexport function BookingTimelineTodoStatusIndicator({\n  className,\n  status = \"outstanding\",\n}: BookingTimelineTodoStatusIndicatorProps) {\n  if (status === \"complete\") {\n    return (\n      <span\n        className={cn(\n          \"inline-flex size-6 items-center justify-center rounded-full border-[1.5px] border-circle-gold bg-circle-gold text-white\",\n          className,\n        )}\n      >\n        <CheckIcon className=\"size-4\" />\n      </span>\n    );\n  }\n\n  return (\n    <span\n      className={cn(\n        \"inline-flex size-6 rounded-full border-2 border-dashed border-foreground/20\",\n        className,\n      )}\n    />\n  );\n}\n\nexport interface BookingTimelineTodoListItemProps {\n  action?: React.ReactNode;\n  className?: string;\n  label: React.ReactNode;\n  muted?: boolean;\n  status?: BookingTimelineTodoStatus;\n}\n\nexport function BookingTimelineTodoListItem({\n  action,\n  className,\n  label,\n  muted,\n  status = \"outstanding\",\n}: BookingTimelineTodoListItemProps) {\n  const isDimmed = muted ?? status === \"complete\";\n\n  return (\n    <div\n      className={cn(\n        \"flex min-h-20 items-center gap-4 border-t px-6\",\n        className,\n      )}\n    >\n      <BookingTimelineTodoStatusIndicator status={status} />\n      <div\n        className={cn(\n          \"min-w-0 flex-1 text-[16px] font-medium leading-6 tracking-[-0.02em]\",\n          isDimmed && \"opacity-50\",\n        )}\n      >\n        <div className=\"truncate\">{label}</div>\n      </div>\n      {action ? <div className=\"shrink-0\">{action}</div> : null}\n    </div>\n  );\n}\n\nexport interface BookingTimelineStepContentTodoListProps {\n  children?: React.ReactNode;\n  className?: string;\n  items?: BookingTimelineTodoListItemProps[];\n}\n\nexport function BookingTimelineStepContentTodoList({\n  children,\n  className,\n  items,\n}: BookingTimelineStepContentTodoListProps) {\n  return (\n    <div\n      className={cn(\n        \"overflow-hidden rounded-[var(--border-radius)] bg-card\",\n        className,\n      )}\n    >\n      {items?.map((item, index) => (\n        <BookingTimelineTodoListItem key={index} {...item} />\n      ))}\n      {children}\n    </div>\n  );\n}\n\nexport interface BookingTimelineStepProps {\n  children: React.ReactNode;\n  className?: string;\n}\n\nexport function BookingTimelineStep({\n  children,\n  className,\n}: BookingTimelineStepProps) {\n  return <div className={cn(\"flex flex-col gap-6\", className)}>{children}</div>;\n}\n\nexport interface BookingTimelineItemProps extends React.PropsWithChildren {\n  className?: string;\n  contentClassName?: string;\n  lastChild?: boolean;\n  state?: BookingTimelineIndicatorState;\n  theme?: BookingTimelineTheme;\n}\n\nexport function BookingTimelineItem({\n  children,\n  className,\n  contentClassName,\n  lastChild = false,\n  state = \"current\",\n  theme = \"berlin\",\n}: BookingTimelineItemProps) {\n  return (\n    <div className={cn(\"flex w-full gap-3\", className)}>\n      <BookingTimelineIndicator\n        className=\"self-stretch\"\n        lastChild={lastChild}\n        state={state}\n        theme={theme}\n      />\n      <div className={cn(\"min-w-0 flex-1 pb-8\", contentClassName)}>\n        {children}\n      </div>\n    </div>\n  );\n}\n\nexport interface BookingTimelineProps extends React.PropsWithChildren {\n  className?: string;\n}\n\nexport function BookingTimeline({ children, className }: BookingTimelineProps) {\n  return (\n    <div className={cn(\"flex w-full flex-col\", className)}>{children}</div>\n  );\n}\n\nexport function BookingTimelinePrimaryAction(\n  props: Omit<ButtonProps, \"size\" | \"variant\">,\n) {\n  return <Button size=\"small\" variant=\"primary\" {...props} />;\n}\n\nexport function BookingTimelineSecondaryAction(\n  props: Omit<ButtonProps, \"size\" | \"variant\">,\n) {\n  return <Button size=\"small\" variant=\"secondary\" {...props} />;\n}\n",
      "type": "registry:ui",
      "target": "src/components/ui/booking-timeline.tsx"
    }
  ],
  "type": "registry:ui"
}