{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "marquee",
  "title": "Marquee",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-vue/components/marquee/Marquee.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n  defineProps<{\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    class?: HTMLAttributes['class']\n  }>(),\n  {\n    orientation: 'horizontal',\n    direction: 'left',\n    speed: 20,\n    pauseOnHover: false,\n    gap: 16,\n    repeat: 2,\n    paused: false,\n  },\n)\n\nconst isVertical = computed(() => props.orientation === 'vertical')\nconst reverse = computed(() => props.direction === 'right' || props.direction === 'down')\n\nconst durationStyle = computed(() => `${props.speed}s`)\nconst gapStyle = computed(() => `${props.gap}px`)\n\nconst containerClass = computed(() =>\n  cn(\n    'group flex overflow-hidden',\n    isVertical.value ? 'flex-col' : 'flex-row',\n    props.pauseOnHover ? 'hover:[&>[data-slot=marquee-track]]:[animation-play-state:paused]' : '',\n    props.class,\n  ),\n)\n\nconst trackClass = computed(() =>\n  cn(\n    'flex shrink-0',\n    isVertical.value ? 'flex-col' : 'flex-row',\n    props.paused ? '![animation-play-state:paused]' : '',\n  ),\n)\n</script>\n\n<template>\n  <div\n    data-uipkge\n    data-slot=\"marquee\"\n    :data-orientation=\"orientation\"\n    :data-direction=\"direction\"\n    :class=\"containerClass\"\n    :style=\"{\n      '--marquee-gap': gapStyle,\n    }\"\n  >\n    <div\n      v-for=\"i in repeat\"\n      :key=\"i\"\n      data-slot=\"marquee-track\"\n      :class=\"trackClass\"\n      :style=\"{\n        gap: 'var(--marquee-gap)',\n        animationName: isVertical ? 'uipkge-marquee-y' : 'uipkge-marquee-x',\n        animationDuration: `${props.speed}s`,\n        animationTimingFunction: 'linear',\n        animationIterationCount: 'infinite',\n        animationDirection: reverse ? 'reverse' : 'normal',\n      }\"\n      :aria-hidden=\"i > 1 ? 'true' : undefined\"\n    >\n      <slot />\n    </div>\n  </div>\n</template>\n\n<style>\n/* Global keyframes — must NOT be scoped so the inline animationName can find them */\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@media (prefers-reduced-motion: reduce) {\n  [data-slot='marquee-track'] {\n    animation: none !important;\n  }\n}\n</style>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/marquee/Marquee.vue"
    },
    {
      "path": "packages/registry-vue/components/marquee/index.ts",
      "content": "export { default as Marquee } from './Marquee.vue'\n",
      "type": "registry:ui",
      "target": "~/app/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"
  ]
}