{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "marquee",
  "title": "Marquee",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-svelte/components/marquee/Marquee.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface MarqueeProps extends HTMLAttributes<HTMLDivElement> {\n    /** Scroll axis. */\n    orientation?: 'horizontal' | 'vertical'\n    /** Travel direction. */\n    direction?: 'left' | 'right' | 'up' | 'down'\n    /** Animation duration in seconds. Lower = faster. */\n    speed?: number\n    /** Pause the animation on hover. */\n    pauseOnHover?: boolean\n    /** Gap between repeated content groups (px). */\n    gap?: number\n    /** Number of times the slot content is duplicated for a seamless loop. */\n    repeat?: number\n    /** Hard pause the animation. */\n    paused?: boolean\n    ref?: HTMLDivElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { cn } from '$lib/utils'\n\n  let {\n    class: className,\n    orientation = 'horizontal',\n    direction = 'left',\n    speed = 20,\n    pauseOnHover = false,\n    gap = 16,\n    repeat = 2,\n    paused = false,\n    children,\n    ref = $bindable(null),\n    ...restProps\n  }: MarqueeProps = $props()\n\n  const isVertical = $derived(orientation === 'vertical')\n  const reverse = $derived(direction === 'right' || direction === 'down')\n\n  const containerClass = $derived(\n    cn(\n      'group flex overflow-hidden',\n      isVertical ? 'flex-col' : 'flex-row',\n      pauseOnHover ? 'hover:[&>[data-slot=marquee-track]]:[animation-play-state:paused]' : '',\n      className,\n    ),\n  )\n\n  const trackClass = $derived(\n    cn('flex shrink-0', isVertical ? 'flex-col' : 'flex-row', paused ? '![animation-play-state:paused]' : ''),\n  )\n</script>\n\n<div\n  bind:this={ref}\n  data-uipkge=\"\"\n  data-slot=\"marquee\"\n  data-orientation={orientation}\n  data-direction={direction}\n  class={containerClass}\n  style:--marquee-gap=\"{gap}px\"\n  role=\"region\"\n  aria-roledescription=\"marquee\"\n  {...restProps}\n>\n  {#each Array.from({ length: repeat }, (_, i) => i + 1), i (i)}\n    <div\n      data-slot=\"marquee-track\"\n      class={trackClass}\n      style:gap=\"var(--marquee-gap)\"\n      style:animation-name={isVertical ? 'uipkge-marquee-y' : 'uipkge-marquee-x'}\n      style:animation-duration=\"{speed}s\"\n      style:animation-timing-function=\"linear\"\n      style:animation-iteration-count=\"infinite\"\n      style:animation-direction={reverse ? 'reverse' : 'normal'}\n      aria-hidden={i > 1 ? 'true' : undefined}\n    >\n      {@render children?.()}\n    </div>\n  {/each}\n</div>\n\n<style>\n  /* Global keyframes — must NOT be scoped so the inline animation-name can find them */\n  :global {\n    @keyframes uipkge-marquee-x {\n      from {\n        transform: translateX(0);\n      }\n      to {\n        transform: translateX(-100%);\n      }\n    }\n\n    @keyframes uipkge-marquee-y {\n      from {\n        transform: translateY(0);\n      }\n      to {\n        transform: translateY(-100%);\n      }\n    }\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    :global([data-slot='marquee-track']) {\n      animation: none !important;\n    }\n  }\n</style>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/marquee/Marquee.svelte"
    },
    {
      "path": "packages/registry-svelte/components/marquee/index.ts",
      "content": "export { default as Marquee, type MarqueeProps } from './Marquee.svelte'\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/marquee/index.ts"
    }
  ],
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Continuously auto-scrolling content. Scrolls horizontally or vertically in any direction, with configurable speed, gap, repeat count for a seamless loop, pause-on-hover, and a hard pause prop. Respects prefers-reduced-motion.",
  "categories": [
    "display"
  ]
}