{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "retro-scrollbar",
  "title": "RetroScrollbar",
  "description": "A Mac OS 9 styled scroll area with 16px wide/tall scrollbars featuring raised bevel thumb, inset track, and arrow navigation buttons at each end, built on Radix UI ScrollArea.",
  "dependencies": [
    "@radix-ui/react-scroll-area"
  ],
  "registryDependencies": [
    "https://nostalgia-ui.com/r/nostalgia-theme.json"
  ],
  "files": [
    {
      "path": "registry/new-york/ui/retro-scrollbar.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* ------------------------------------------------------------------ */\n/*  Arrow SVG paths (filled triangles, 6x6 viewBox)                   */\n/* ------------------------------------------------------------------ */\nconst arrowPaths: Record<string, string> = {\n  up: \"M1 5 L3 1 L5 5 Z\",\n  down: \"M1 1 L3 5 L5 1 Z\",\n  left: \"M5 1 L1 3 L5 5 Z\",\n  right: \"M1 1 L5 3 L1 5 Z\",\n}\n\n/* ------------------------------------------------------------------ */\n/*  Viewport context: lets the arrow buttons scroll the viewport      */\n/* ------------------------------------------------------------------ */\nconst ScrollViewportContext =\n  React.createContext<React.RefObject<HTMLDivElement | null> | null>(null)\n\n/** Distance (px) a single arrow click scrolls the viewport. */\nconst ARROW_SCROLL_STEP = 40\n\n/* ------------------------------------------------------------------ */\n/*  ScrollArea arrow button (16x16 raised bevel with centered arrow)  */\n/* ------------------------------------------------------------------ */\nfunction ScrollArrowButton({\n  direction,\n  className,\n  onClick,\n  onPointerDown,\n  ...props\n}: React.ComponentProps<\"button\"> & {\n  direction: \"up\" | \"down\" | \"left\" | \"right\"\n}) {\n  const viewportRef = React.useContext(ScrollViewportContext)\n\n  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n    onClick?.(event)\n    if (event.defaultPrevented) return\n    // Prefer the viewport registered by RetroScrollArea; fall back to the\n    // sibling Radix viewport when the scrollbar is used with a bare Root.\n    const viewport =\n      viewportRef?.current ??\n      event.currentTarget\n        .closest(\"[data-orientation]\")\n        ?.parentElement?.querySelector<HTMLElement>(\n          \"[data-radix-scroll-area-viewport]\"\n        )\n    if (!viewport) return\n    const delta =\n      direction === \"up\" || direction === \"left\"\n        ? -ARROW_SCROLL_STEP\n        : ARROW_SCROLL_STEP\n    if (direction === \"up\" || direction === \"down\") {\n      viewport.scrollBy({ top: delta })\n    } else {\n      viewport.scrollBy({ left: delta })\n    }\n  }\n\n  return (\n    <button\n      type=\"button\"\n      tabIndex={-1}\n      aria-hidden=\"true\"\n      className={cn(\n        \"flex items-center justify-center p-0\",\n        \"size-[16px] shrink-0\",\n        \"border border-os9-black bg-os9-gray-300\",\n        \"shadow-[inset_1px_1px_0_var(--os9-white),inset_-1px_-1px_0_var(--os9-gray-700)]\",\n        \"active:shadow-[inset_1px_1px_0_var(--os9-gray-700),inset_-1px_-1px_0_var(--os9-white)]\",\n        className\n      )}\n      onPointerDown={(event) => {\n        onPointerDown?.(event)\n        // Stop Radix's scrollbar handler from treating this as a track click\n        event.stopPropagation()\n      }}\n      onClick={handleClick}\n      {...props}\n    >\n      <svg\n        width=\"6\"\n        height=\"6\"\n        viewBox=\"0 0 6 6\"\n        fill=\"none\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        aria-hidden=\"true\"\n      >\n        <path d={arrowPaths[direction]} fill=\"var(--os9-black)\" />\n      </svg>\n    </button>\n  )\n}\n\n/* ------------------------------------------------------------------ */\n/*  RetroScrollBar                                                    */\n/* ------------------------------------------------------------------ */\nfunction RetroScrollBar(\n  {\n    className,\n    orientation = \"vertical\",\n    ...props\n  }: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,\n  ref: React.ForwardedRef<\n    React.ComponentRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>\n  >\n) {\n  const isVertical = orientation === \"vertical\"\n\n  return (\n    <ScrollAreaPrimitive.ScrollAreaScrollbar\n      ref={ref}\n      orientation={orientation}\n      className={cn(\n        \"flex touch-none select-none\",\n        // Padding reserves room for the absolutely-positioned arrow buttons.\n        // Radix reads this padding so the thumb never travels over the arrows.\n        isVertical\n          ? \"h-full w-[16px] flex-col py-[16px] border-l border-os9-black\"\n          : \"h-[16px] w-full flex-row px-[16px] border-t border-os9-black\",\n        className\n      )}\n      {...props}\n    >\n      {/* Arrow button: start (up / left) */}\n      <ScrollArrowButton\n        direction={isVertical ? \"up\" : \"left\"}\n        className={cn(\n          \"absolute\",\n          isVertical ? \"top-0 right-0\" : \"left-0 bottom-0\"\n        )}\n      />\n\n      {/* Track */}\n      <div\n        className={cn(\n          \"relative flex-1\",\n          \"bg-os9-gray-600/30\",\n          \"border-x border-os9-black\",\n          isVertical ? \"border-x\" : \"border-y border-x-0\"\n        )}\n      >\n        <ScrollAreaPrimitive.ScrollAreaThumb\n          className={cn(\n            \"relative flex-1\",\n            isVertical ? \"!w-full min-h-[20px]\" : \"!h-full min-w-[20px]\",\n            \"bg-os9-gray-300\",\n            \"border border-os9-black\",\n            \"shadow-[inset_1px_1px_0_var(--os9-white),inset_-1px_-1px_0_var(--os9-gray-700)]\",\n            \"active:shadow-[inset_1px_1px_0_var(--os9-gray-700),inset_-1px_-1px_0_var(--os9-white)]\",\n            \"cursor-pointer\"\n          )}\n        />\n      </div>\n\n      {/* Arrow button: end (down / right) */}\n      <ScrollArrowButton\n        direction={isVertical ? \"down\" : \"right\"}\n        className={cn(\n          \"absolute\",\n          isVertical ? \"bottom-0 right-0\" : \"right-0 bottom-0\"\n        )}\n      />\n    </ScrollAreaPrimitive.ScrollAreaScrollbar>\n  )\n}\n\nconst ForwardedRetroScrollBar = React.forwardRef(RetroScrollBar)\nForwardedRetroScrollBar.displayName = \"RetroScrollBar\"\n\n/* ------------------------------------------------------------------ */\n/*  RetroScrollArea                                                   */\n/* ------------------------------------------------------------------ */\nfunction RetroScrollArea(\n  {\n    className,\n    children,\n    orientation = \"vertical\",\n    // OS9 scroll bars are always visible\n    type = \"always\",\n    ...props\n  }: React.ComponentProps<typeof ScrollAreaPrimitive.Root> & {\n    orientation?: \"vertical\" | \"horizontal\" | \"both\"\n  },\n  ref: React.ForwardedRef<\n    React.ComponentRef<typeof ScrollAreaPrimitive.Root>\n  >\n) {\n  const viewportRef = React.useRef<HTMLDivElement>(null)\n  const hasVertical = orientation === \"vertical\" || orientation === \"both\"\n  const hasHorizontal = orientation === \"horizontal\" || orientation === \"both\"\n  // Always-visible bars would otherwise overlay the last 16px of content\n  const reserveSpace = type === \"always\"\n\n  return (\n    <ScrollViewportContext.Provider value={viewportRef}>\n      <ScrollAreaPrimitive.Root\n        ref={ref}\n        type={type}\n        className={cn(\"relative overflow-hidden\", className)}\n        {...props}\n      >\n        <ScrollAreaPrimitive.Viewport\n          ref={viewportRef}\n          className={cn(\n            \"h-full w-full\",\n            reserveSpace && hasVertical && \"pr-[16px]\",\n            reserveSpace && hasHorizontal && \"pb-[16px]\"\n          )}\n        >\n          {children}\n        </ScrollAreaPrimitive.Viewport>\n\n        {hasVertical && <ForwardedRetroScrollBar orientation=\"vertical\" />}\n        {hasHorizontal && <ForwardedRetroScrollBar orientation=\"horizontal\" />}\n\n        <ScrollAreaPrimitive.Corner className=\"bg-os9-gray-300\" />\n      </ScrollAreaPrimitive.Root>\n    </ScrollViewportContext.Provider>\n  )\n}\n\nconst ForwardedRetroScrollArea = React.forwardRef(RetroScrollArea)\nForwardedRetroScrollArea.displayName = \"RetroScrollArea\"\n\n/* ------------------------------------------------------------------ */\n/*  Exports                                                           */\n/* ------------------------------------------------------------------ */\nexport {\n  ForwardedRetroScrollArea as RetroScrollArea,\n  ForwardedRetroScrollBar as RetroScrollBar,\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}