{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "scroll-area",
  "title": "Scroll Area",
  "description": "Native scrolling for Astro panels, with custom tracks, keyboard access, and optional edge fades.",
  "dependencies": [
    "cn@0.4.0"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "packages/ui/src/components/ui/scroll-area/index.ts",
      "content": "export { default as ScrollArea } from './scroll-area.astro'\nexport { default as ScrollAreaRoot } from './scroll-area-root.astro'\nexport { default as ScrollAreaViewport } from './scroll-area-viewport.astro'\nexport { default as ScrollAreaContent } from './scroll-area-content.astro'\nexport {\n    default as ScrollAreaScrollbar,\n    default as ScrollBar,\n} from './scroll-area-scrollbar.astro'\nexport { default as ScrollAreaThumb } from './scroll-area-thumb.astro'\nexport { default as ScrollAreaCorner } from './scroll-area-corner.astro'\nexport type { ScrollAreaOptions } from './types'\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/index.ts"
    },
    {
      "path": "packages/ui/src/components/ui/scroll-area/scroll-area-content.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport { cn } from \"cn\"\n\ntype Props = HTMLAttributes<\"div\">\nconst { class: className, ...props } = Astro.props\n---\n\n<div\n  data-slot=\"scroll-area-content\"\n  class={cn(\"flow-root\", className)}\n  {...props}\n>\n  <slot />\n</div>\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/scroll-area-content.astro"
    },
    {
      "path": "packages/ui/src/components/ui/scroll-area/scroll-area-corner.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport { cn } from \"cn\"\n\ntype Props = HTMLAttributes<\"div\">\nconst { class: className, ...props } = Astro.props\n---\n\n<div\n  data-slot=\"scroll-area-corner\"\n  aria-hidden=\"true\"\n  class={cn(\n    \"pointer-events-none absolute inset-e-0 bottom-0 size-2.5\",\n    className,\n  )}\n  {...props}\n></div>\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/scroll-area-corner.astro"
    },
    {
      "path": "packages/ui/src/components/ui/scroll-area/scroll-area-element.ts",
      "content": "const clamp = (value: number, max: number) => Math.max(0, Math.min(max, value))\n\n/** Native scrolling with custom pointer controls. Each instance owns its observers. */\nexport class ScrollAreaElement extends HTMLElement {\n    private cleanup?: () => void\n    private setupFrame = 0\n\n    connectedCallback() {\n        // Wait until the parser has added the component parts.\n        this.setupFrame = requestAnimationFrame(() => {\n            if (this.isConnected && !this.cleanup) this.initialize()\n        })\n    }\n\n    disconnectedCallback() {\n        cancelAnimationFrame(this.setupFrame)\n        this.cleanup?.()\n        this.cleanup = undefined\n    }\n\n    private initialize() {\n        const viewport = this.querySelector<HTMLElement>(\n            ':scope > [data-slot=\"scroll-area-viewport\"]',\n        )\n        const content = viewport?.querySelector<HTMLElement>(\n            ':scope > [data-slot=\"scroll-area-content\"]',\n        )\n        if (!viewport || !content) return\n\n        const bars = [\n            ...this.querySelectorAll<HTMLElement>(\n                ':scope > [data-slot=\"scroll-area-scrollbar\"]',\n            ),\n        ].flatMap((track) => {\n            const thumb = track.querySelector<HTMLElement>(\n                ':scope > [data-slot=\"scroll-area-thumb\"]',\n            )\n            return thumb\n                ? [\n                      {\n                          track,\n                          thumb,\n                          horizontal:\n                              track.dataset.orientation === 'horizontal',\n                      },\n                  ]\n                : []\n        })\n        // Keep native controls if a manual composition has no scrollbar for an enabled axis.\n        const direction = this.dataset.orientation ?? 'vertical'\n        const complete =\n            (direction === 'horizontal' ||\n                bars.some((bar) => !bar.horizontal)) &&\n            (direction === 'vertical' || bars.some((bar) => bar.horizontal))\n        const corner = this.querySelector<HTMLElement>(\n            ':scope > [data-slot=\"scroll-area-corner\"]',\n        )\n        const events = new AbortController()\n        let frame = 0\n        let scrollTimer: ReturnType<typeof setTimeout> | undefined\n        let drag:\n            | {\n                  track: HTMLElement\n                  pointerId: number\n                  horizontal: boolean\n                  offset: number\n              }\n            | undefined\n\n        const measure = () => {\n            const maxX = Math.max(\n                0,\n                viewport.scrollWidth - viewport.clientWidth,\n            )\n            const maxY = Math.max(\n                0,\n                viewport.scrollHeight - viewport.clientHeight,\n            )\n            const rtl = getComputedStyle(viewport).direction === 'rtl'\n            const x = clamp(\n                rtl ? -viewport.scrollLeft : viewport.scrollLeft,\n                maxX,\n            )\n            const y = clamp(viewport.scrollTop, maxY)\n            return { maxX, maxY, rtl, x, y }\n        }\n        const update = () => {\n            frame = 0\n            const { maxX, maxY, rtl, x, y } = measure()\n            const hasX = direction !== 'vertical' && maxX > 1\n            const hasY = direction !== 'horizontal' && maxY > 1\n            for (const element of [this, viewport]) {\n                element.toggleAttribute('data-has-overflow-x', hasX)\n                element.toggleAttribute('data-has-overflow-y', hasY)\n                element.toggleAttribute('data-overflow-x-start', hasX && x > 1)\n                element.toggleAttribute(\n                    'data-overflow-x-end',\n                    hasX && maxX - x > 1,\n                )\n                element.toggleAttribute('data-overflow-y-start', hasY && y > 1)\n                element.toggleAttribute(\n                    'data-overflow-y-end',\n                    hasY && maxY - y > 1,\n                )\n            }\n            const distances = {\n                left: hasX ? (rtl ? maxX - x : x) : 0,\n                right: hasX ? (rtl ? x : maxX - x) : 0,\n                top: hasY ? y : 0,\n                bottom: hasY ? maxY - y : 0,\n            }\n            for (const [edge, value] of Object.entries(distances)) {\n                viewport.style.setProperty(\n                    `--scroll-area-${edge}`,\n                    `${value}px`,\n                )\n            }\n            if (corner) corner.hidden = !hasX || !hasY\n            for (const { track, thumb, horizontal } of bars) {\n                track.hidden = horizontal ? !hasX : !hasY\n                if (track.hidden) continue\n                const length = horizontal\n                    ? track.clientWidth\n                    : track.clientHeight\n                const visible = horizontal\n                    ? viewport.clientWidth\n                    : viewport.clientHeight\n                const total = horizontal\n                    ? viewport.scrollWidth\n                    : viewport.scrollHeight\n                const size = Math.min(\n                    length,\n                    Math.max(18, (length * visible) / total),\n                )\n                const progress = horizontal\n                    ? maxX\n                        ? x / maxX\n                        : 0\n                    : maxY\n                      ? y / maxY\n                      : 0\n                const position =\n                    (length - size) *\n                    (horizontal && rtl ? 1 - progress : progress)\n                thumb.style.width = horizontal ? `${size}px` : '100%'\n                thumb.style.height = horizontal ? '100%' : `${size}px`\n                // Position from the physical left edge, including in RTL layouts.\n                thumb.style.position = 'absolute'\n                thumb.style.left = '0'\n                thumb.style.top = '0'\n                thumb.style.transform = horizontal\n                    ? `translateX(${position}px)`\n                    : `translateY(${position}px)`\n            }\n        }\n        const schedule = () => {\n            if (!frame) frame = requestAnimationFrame(update)\n        }\n        const onScroll = () => {\n            this.setAttribute('data-scrolling', '')\n            clearTimeout(scrollTimer)\n            scrollTimer = setTimeout(\n                () => this.removeAttribute('data-scrolling'),\n                150,\n            )\n            schedule()\n        }\n        const move = (event: PointerEvent) => {\n            if (!drag || event.pointerId !== drag.pointerId) return\n            const { track, horizontal, offset } = drag\n            const thumb = track.querySelector<HTMLElement>(\n                '[data-slot=\"scroll-area-thumb\"]',\n            )!\n            const rect = track.getBoundingClientRect()\n            const thumbRect = thumb.getBoundingClientRect()\n            const length = horizontal ? rect.width : rect.height\n            const size = horizontal ? thumbRect.width : thumbRect.height\n            const position =\n                (horizontal\n                    ? event.clientX - rect.left\n                    : event.clientY - rect.top) - offset\n            const progress =\n                length > size\n                    ? clamp(position, length - size) / (length - size)\n                    : 0\n            const { maxX, maxY, rtl } = measure()\n            if (horizontal)\n                viewport.scrollLeft = rtl\n                    ? -(1 - progress) * maxX\n                    : progress * maxX\n            else viewport.scrollTop = progress * maxY\n            schedule()\n        }\n        const release = () => {\n            if (drag?.track.hasPointerCapture(drag.pointerId))\n                drag.track.releasePointerCapture(drag.pointerId)\n            drag = undefined\n            this.removeAttribute('data-dragging')\n        }\n        for (const { track, thumb, horizontal } of bars) {\n            track.addEventListener(\n                'pointerdown',\n                (event) => {\n                    if (event.button !== 0 || !event.isPrimary || drag) return\n                    event.preventDefault()\n                    const rect = thumb.getBoundingClientRect()\n                    const onThumb =\n                        event.target instanceof Node &&\n                        thumb.contains(event.target)\n                    const offset = onThumb\n                        ? horizontal\n                            ? event.clientX - rect.left\n                            : event.clientY - rect.top\n                        : (horizontal ? rect.width : rect.height) / 2\n                    drag = {\n                        track,\n                        pointerId: event.pointerId,\n                        horizontal,\n                        offset,\n                    }\n                    viewport.focus({ preventScroll: true })\n                    track.setPointerCapture(event.pointerId)\n                    this.setAttribute('data-dragging', '')\n                    if (!onThumb) move(event)\n                },\n                { signal: events.signal },\n            )\n            track.addEventListener('pointermove', move, {\n                signal: events.signal,\n            })\n            for (const type of [\n                'pointerup',\n                'pointercancel',\n                'lostpointercapture',\n            ]) {\n                track.addEventListener(type, release, { signal: events.signal })\n            }\n            // The overlaid track is outside the native viewport's wheel event path.\n            track.addEventListener(\n                'wheel',\n                (event) => {\n                    if (event.ctrlKey) return\n                    const unit =\n                        event.deltaMode === 1\n                            ? 16\n                            : event.deltaMode === 2\n                              ? viewport.clientHeight\n                              : 1\n                    const beforeX = viewport.scrollLeft\n                    const beforeY = viewport.scrollTop\n                    if (horizontal)\n                        viewport.scrollLeft +=\n                            (event.deltaX ||\n                                (getComputedStyle(viewport).direction === 'rtl'\n                                    ? -event.deltaY\n                                    : event.deltaY)) * unit\n                    else viewport.scrollTop += event.deltaY * unit\n                    if (\n                        beforeX !== viewport.scrollLeft ||\n                        beforeY !== viewport.scrollTop ||\n                        this.hasAttribute('data-overscroll-contain')\n                    )\n                        event.preventDefault()\n                },\n                { passive: false, signal: events.signal },\n            )\n        }\n        viewport.addEventListener('scroll', onScroll, {\n            passive: true,\n            signal: events.signal,\n        })\n        viewport.addEventListener('load', schedule, {\n            capture: true,\n            signal: events.signal,\n        })\n        const resize = new ResizeObserver(schedule)\n        const observe = () => {\n            resize.disconnect()\n            for (const element of [\n                viewport,\n                content,\n                ...content.children,\n                ...bars.map((bar) => bar.track),\n            ])\n                resize.observe(element)\n            schedule()\n        }\n        const mutations = new MutationObserver(observe)\n        mutations.observe(content, {\n            childList: true,\n            subtree: true,\n            characterData: true,\n        })\n        this.toggleAttribute('data-enhanced', complete)\n        observe()\n        cancelAnimationFrame(frame)\n        update()\n        this.cleanup = () => {\n            events.abort()\n            resize.disconnect()\n            mutations.disconnect()\n            cancelAnimationFrame(frame)\n            clearTimeout(scrollTimer)\n            release()\n            this.removeAttribute('data-enhanced')\n            this.removeAttribute('data-scrolling')\n        }\n    }\n}\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/scroll-area-element.ts"
    },
    {
      "path": "packages/ui/src/components/ui/scroll-area/scroll-area-root.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport { cn } from \"cn\"\nimport type { ScrollAreaOptions } from \"./types\"\nimport \"./scroll-area.css\"\n\ntype Props = HTMLAttributes<\"div\"> & ScrollAreaOptions\n\nconst {\n  class: className,\n  orientation = \"vertical\",\n  scrollFade = false,\n  scrollbarGutter = false,\n  fill = false,\n  clampContentMinWidth = true,\n  overscrollContain = false,\n  ...props\n} = Astro.props\n---\n\n<gnostic-scroll-area\n  data-slot=\"scroll-area\"\n  data-orientation={orientation}\n  data-scroll-fade={scrollFade ? \"\" : undefined}\n  data-scrollbar-gutter={scrollbarGutter ? \"\" : undefined}\n  data-fill={fill ? \"\" : undefined}\n  data-clamp-content={clampContentMinWidth ? \"\" : undefined}\n  data-overscroll-contain={overscrollContain ? \"\" : undefined}\n  class={cn(\n    \"relative grid min-h-0 min-w-0 max-h-[inherit] grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] rounded-[inherit]\",\n    className,\n  )}\n  {...props}\n>\n  <slot />\n</gnostic-scroll-area>\n\n<script>\n  import { ScrollAreaElement } from \"./scroll-area-element\"\n\n  if (!customElements.get(\"gnostic-scroll-area\")) {\n    customElements.define(\"gnostic-scroll-area\", ScrollAreaElement)\n  }\n</script>\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/scroll-area-root.astro"
    },
    {
      "path": "packages/ui/src/components/ui/scroll-area/scroll-area-scrollbar.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport { cn } from \"cn\"\nimport ScrollAreaThumb from \"./scroll-area-thumb.astro\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n  orientation?: \"vertical\" | \"horizontal\"\n}\nconst { class: className, orientation = \"vertical\", ...props } = Astro.props\n---\n\n<div\n  data-slot=\"scroll-area-scrollbar\"\n  data-orientation={orientation}\n  aria-hidden=\"true\"\n  class={cn(\"absolute touch-none select-none\", className)}\n  {...props}\n>\n  <slot>\n    <ScrollAreaThumb />\n  </slot>\n</div>\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/scroll-area-scrollbar.astro"
    },
    {
      "path": "packages/ui/src/components/ui/scroll-area/scroll-area-thumb.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport { cn } from \"cn\"\n\ntype Props = HTMLAttributes<\"div\">\nconst { class: className, ...props } = Astro.props\n---\n\n<div\n  data-slot=\"scroll-area-thumb\"\n  class={cn(\"relative rounded-full bg-foreground/20\", className)}\n  {...props}\n>\n  <slot />\n</div>\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/scroll-area-thumb.astro"
    },
    {
      "path": "packages/ui/src/components/ui/scroll-area/scroll-area-viewport.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport { cn } from \"cn\"\n\ntype Props = HTMLAttributes<\"div\">\nconst { class: className, role, tabindex = 0, ...props } = Astro.props\nconst hasLabel = Boolean(props[\"aria-label\"] || props[\"aria-labelledby\"])\n---\n\n<div\n  data-slot=\"scroll-area-viewport\"\n  tabindex={tabindex}\n  role={role ?? (hasLabel ? \"region\" : undefined)}\n  class={cn(\n    \"min-h-0 min-w-0 rounded-[inherit] outline-none transition-shadow focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background\",\n    className,\n  )}\n  {...props}\n>\n  <slot />\n</div>\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/scroll-area-viewport.astro"
    },
    {
      "path": "packages/ui/src/components/ui/scroll-area/scroll-area.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { ScrollAreaOptions } from \"./types\"\nimport ScrollAreaRoot from \"./scroll-area-root.astro\"\nimport ScrollAreaViewport from \"./scroll-area-viewport.astro\"\nimport ScrollAreaContent from \"./scroll-area-content.astro\"\nimport ScrollAreaScrollbar from \"./scroll-area-scrollbar.astro\"\nimport ScrollAreaCorner from \"./scroll-area-corner.astro\"\n\ntype Props = HTMLAttributes<\"div\"> &\n  ScrollAreaOptions & {\n    viewportProps?: HTMLAttributes<\"div\">\n  }\n\nconst {\n  \"aria-label\": label,\n  \"aria-labelledby\": labelledBy,\n  \"aria-describedby\": describedBy,\n  role,\n  tabindex,\n  viewportProps,\n  ...props\n} = Astro.props\n---\n\n<ScrollAreaRoot {...props}>\n  <ScrollAreaViewport\n    aria-label={label}\n    aria-labelledby={labelledBy}\n    aria-describedby={describedBy}\n    role={role}\n    tabindex={tabindex ?? 0}\n    {...viewportProps}\n  >\n    <ScrollAreaContent>\n      <slot />\n    </ScrollAreaContent>\n  </ScrollAreaViewport>\n  <ScrollAreaScrollbar />\n  <ScrollAreaScrollbar orientation=\"horizontal\" />\n  <ScrollAreaCorner />\n</ScrollAreaRoot>\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/scroll-area.astro"
    },
    {
      "path": "packages/ui/src/components/ui/scroll-area/scroll-area.css",
      "content": "/* Keep component defaults after the reset when this sheet loads first. */\n@layer theme, base, components, utilities, appearance;\n\n@layer components {\n    [data-slot=\"scroll-area\"] {\n        --scroll-area-bar-size: 6px;\n        --scroll-area-bar-inset: 4px;\n        --scroll-area-fade-size: 1.5rem;\n    }\n\n    [data-slot=\"scroll-area\"] > [data-slot=\"scroll-area-viewport\"] {\n        overflow: auto;\n        scrollbar-width: thin;\n        scrollbar-color: var(--muted-foreground) transparent;\n    }\n\n    [data-slot=\"scroll-area\"][data-orientation=\"vertical\"]\n        > [data-slot=\"scroll-area-viewport\"] {\n        overflow-x: hidden;\n    }\n\n    [data-slot=\"scroll-area\"][data-orientation=\"horizontal\"]\n        > [data-slot=\"scroll-area-viewport\"] {\n        overflow-y: hidden;\n    }\n\n    [data-slot=\"scroll-area\"][data-enhanced]\n        > [data-slot=\"scroll-area-viewport\"] {\n        scrollbar-width: none;\n    }\n\n    [data-slot=\"scroll-area\"][data-enhanced]\n        > [data-slot=\"scroll-area-viewport\"]::-webkit-scrollbar {\n        display: none;\n    }\n\n    [data-slot=\"scroll-area-content\"] {\n        min-width: fit-content;\n    }\n\n    [data-slot=\"scroll-area\"][data-clamp-content]\n        > [data-slot=\"scroll-area-viewport\"]\n        > [data-slot=\"scroll-area-content\"] {\n        min-width: 0;\n    }\n\n    [data-slot=\"scroll-area\"][data-fill]\n        > [data-slot=\"scroll-area-viewport\"]\n        > [data-slot=\"scroll-area-content\"] {\n        width: 100%;\n        height: 100%;\n    }\n\n    [data-slot=\"scroll-area\"][data-scrollbar-gutter]:not(\n            [data-orientation=\"horizontal\"]\n        )\n        > [data-slot=\"scroll-area-viewport\"] {\n        padding-inline-end: calc(\n            var(--scroll-area-bar-size) + var(--scroll-area-bar-inset)\n        );\n    }\n\n    [data-slot=\"scroll-area\"][data-scrollbar-gutter]:not(\n            [data-orientation=\"vertical\"]\n        )\n        > [data-slot=\"scroll-area-viewport\"] {\n        padding-bottom: calc(\n            var(--scroll-area-bar-size) + var(--scroll-area-bar-inset)\n        );\n    }\n\n    [data-slot=\"scroll-area\"][data-overscroll-contain][data-has-overflow-y]\n        > [data-slot=\"scroll-area-viewport\"] {\n        overscroll-behavior-y: contain;\n    }\n\n    [data-slot=\"scroll-area\"][data-overscroll-contain][data-has-overflow-x]\n        > [data-slot=\"scroll-area-viewport\"] {\n        overscroll-behavior-x: contain;\n    }\n\n    [data-slot=\"scroll-area\"][data-enhanced][data-scroll-fade]\n        > [data-slot=\"scroll-area-viewport\"] {\n        mask-image:\n            linear-gradient(\n                to right,\n                transparent,\n                black min(var(--scroll-area-fade-size), var(--scroll-area-left)),\n                black\n                    calc(\n                        100% -\n                            min(\n                                var(--scroll-area-fade-size),\n                                var(--scroll-area-right)\n                            )\n                    ),\n                transparent\n            ),\n            linear-gradient(\n                to bottom,\n                transparent,\n                black min(var(--scroll-area-fade-size), var(--scroll-area-top)),\n                black\n                    calc(\n                        100% -\n                            min(\n                                var(--scroll-area-fade-size),\n                                var(--scroll-area-bottom)\n                            )\n                    ),\n                transparent\n            );\n        mask-composite: intersect;\n    }\n\n    [data-slot=\"scroll-area-scrollbar\"] {\n        z-index: 1;\n        opacity: 0;\n        transition: opacity 150ms 300ms;\n    }\n\n    [data-slot=\"scroll-area\"]:not([data-enhanced])\n        > [data-slot=\"scroll-area-scrollbar\"],\n    [data-slot=\"scroll-area\"]:not([data-enhanced])\n        > [data-slot=\"scroll-area-corner\"],\n    [data-slot=\"scroll-area-scrollbar\"][hidden],\n    [data-slot=\"scroll-area-corner\"][hidden] {\n        display: none;\n    }\n\n    [data-slot=\"scroll-area\"]:is(\n            :hover,\n            :focus-within,\n            [data-scrolling],\n            [data-dragging]\n        )\n        > [data-slot=\"scroll-area-scrollbar\"] {\n        opacity: 1;\n        transition-duration: 100ms;\n        transition-delay: 0ms;\n    }\n\n    [data-slot=\"scroll-area-scrollbar\"][data-orientation=\"vertical\"] {\n        inset-block: var(--scroll-area-bar-inset);\n        inset-inline-end: var(--scroll-area-bar-inset);\n        width: var(--scroll-area-bar-size);\n    }\n\n    [data-slot=\"scroll-area-scrollbar\"][data-orientation=\"horizontal\"] {\n        inset-inline: var(--scroll-area-bar-inset);\n        bottom: var(--scroll-area-bar-inset);\n        height: var(--scroll-area-bar-size);\n    }\n\n    [data-slot=\"scroll-area\"][data-has-overflow-x]\n        > [data-slot=\"scroll-area-scrollbar\"][data-orientation=\"vertical\"] {\n        bottom: calc(\n            var(--scroll-area-bar-size) + 2 * var(--scroll-area-bar-inset)\n        );\n    }\n\n    [data-slot=\"scroll-area\"][data-has-overflow-y]\n        > [data-slot=\"scroll-area-scrollbar\"][data-orientation=\"horizontal\"] {\n        inset-inline-end: calc(\n            var(--scroll-area-bar-size) + 2 * var(--scroll-area-bar-inset)\n        );\n    }\n\n    [data-slot=\"scroll-area-thumb\"] {\n        width: 100%;\n        height: 100%;\n    }\n\n    @media (prefers-reduced-motion: reduce) {\n        [data-slot=\"scroll-area-scrollbar\"] {\n            transition: none;\n        }\n    }\n\n    @media (forced-colors: active) {\n        [data-slot=\"scroll-area-thumb\"] {\n            background: CanvasText;\n        }\n    }\n}\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/scroll-area.css"
    },
    {
      "path": "packages/ui/src/components/ui/scroll-area/types.ts",
      "content": "/** Options for `ScrollArea` and `ScrollAreaRoot`. */\nexport interface ScrollAreaOptions {\n    /**\n     * Allowed scroll directions.\n     * @default 'vertical'\n     */\n    orientation?: 'vertical' | 'horizontal' | 'both'\n    /**\n     * Fade edges that have more content.\n     * @default false\n     */\n    scrollFade?: boolean\n    /**\n     * Reserve space for the enabled scrollbars.\n     * @default false\n     */\n    scrollbarGutter?: boolean\n    /**\n     * Size the content wrapper to fill the viewport.\n     * @default false\n     */\n    fill?: boolean\n    /**\n     * Allow the content wrapper to shrink to the viewport width.\n     * @default true\n     */\n    clampContentMinWidth?: boolean\n    /**\n     * Contain scroll input on overflowing axes.\n     * @default false\n     */\n    overscrollContain?: boolean\n}\n",
      "type": "registry:file",
      "target": "~/src/components/ui/scroll-area/types.ts"
    }
  ],
  "meta": {
    "framework": "astro",
    "source": "@gnosticai/ui"
  },
  "docs": "https://ui.gnosticai.com/components/scroll-area",
  "categories": [
    "ui"
  ],
  "type": "registry:ui"
}
