{"name":"carousel","title":"Carousel","description":"A carousel for cycling through elements, images, or slides of content.","installCommand":"bunx marko-ui add carousel -y","usageTags":"<Carousel>","importSnippet":"import Carousel from \"@/components/ui/carousel/carousel.marko\";","usageSnippet":"static const slides = [\"Slide 1\", \"Slide 2\", \"Slide 3\"];\n\n<Carousel|item| items=slides>\n  <div>${item}</div>\n</Carousel>","tags":["Carousel"],"parts":[{"name":"slide","repeatable":true}],"props":[{"name":"allowMouseDrag","type":"boolean | undefined","required":false,"default":"false","description":"Whether to allow scrolling via dragging with mouse"},{"name":"autoplay","type":"boolean | { delay: number; } | undefined","required":false,"default":"false","description":"Whether to scroll automatically. The default delay is 4000ms."},{"name":"autoSize","type":"boolean | undefined","required":false,"default":"false","description":"Whether to enable variable width slides."},{"name":"defaultPage","type":"number | undefined","required":false,"default":"0","description":"The initial page to scroll to when rendered.\nUse when you don't need to control the page of the carousel."},{"name":"dir","type":"'ltr' | 'rtl' | undefined","required":false,"default":"ltr","description":"The document's text/writing direction."},{"name":"getRootNode","type":"(() => ShadowRoot | Document | Node) | undefined","required":false,"description":"A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron."},{"name":"ids","type":"ElementIds | undefined","required":false,"description":"The ids of the elements in the carousel. Useful for composition."},{"name":"inViewThreshold","type":"number | number[] | undefined","required":false,"default":"0.6","description":"The threshold for determining if an item is in view."},{"name":"items","type":"T[]","required":false},{"name":"loop","type":"boolean | undefined","required":false,"default":"false","description":"Whether the carousel should loop around."},{"name":"orientation","type":"'horizontal' | 'vertical' | undefined","required":false,"default":"horizontal","description":"The orientation of the element."},{"name":"padding","type":"string | undefined","required":false,"description":"Defines the extra space added around the scrollable area,\nenabling nearby items to remain partially in view."},{"name":"page","type":"number | undefined","required":false,"description":"The controlled page of the carousel."},{"name":"slidesPerMove","type":"number | 'auto' | undefined","required":false,"default":"auto","description":"The number of slides to scroll at a time.\n\nWhen set to `auto`, the number of slides to scroll is determined by the\n`slidesPerPage` property."},{"name":"slidesPerPage","type":"number | undefined","required":false,"default":"1","description":"The number of slides to show at a time."},{"name":"snapType","type":"'proximity' | 'mandatory' | undefined","required":false,"default":"mandatory","description":"The snap type of the item."},{"name":"spacing","type":"string | undefined","required":false,"default":"0px","description":"The amount of space between items."},{"name":"translations","type":"IntlTranslations | undefined","required":false,"description":"The localized messages to use."}],"events":[{"name":"onAutoplayStatusChange","arg":"AutoplayStatusDetails","description":"Function called when the autoplay status changes."},{"name":"onDragStatusChange","arg":"DragStatusDetails","description":"Function called when the drag status changes."},{"name":"onPageChange","arg":"PageChangeDetails","description":"Function called when the page changes."},{"name":"pageChange","arg":"number"}],"keyboard":[],"accessibilityNotes":[],"examples":[{"id":"carousel-demo","title":"Basic","source":"import Carousel from \"@marko-ui/shadcn/ui/carousel/carousel.marko\";\n\nstatic const SLIDES = [1, 2, 3, 4, 5];\n\n<Carousel|item| items=SLIDES class=\"w-full max-w-xs\">\n  <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card\">\n    <span class=\"text-4xl font-semibold\">${item}</span>\n  </div>\n</Carousel>","description":"Pass `items` and render each one through the tag's own body, taking the item as a default-body tag parameter. Use the previous/next triggers to move between pages."},{"id":"carousel-size","title":"Sizes","source":"import Carousel from \"@marko-ui/shadcn/ui/carousel/carousel.marko\";\n\nstatic const SLIDES = [1, 2, 3, 4, 5];\n\n<Carousel|item| items=SLIDES slidesPerPage=2 class=\"w-full max-w-sm\">\n  <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card mx-1\">\n    <span class=\"text-3xl font-semibold\">${item}</span>\n  </div>\n</Carousel>","description":"Set `slidesPerPage` to show more than one item at a time."},{"id":"carousel-spacing","title":"Spacing","source":"import Carousel from \"@marko-ui/shadcn/ui/carousel/carousel.marko\";\n\nstatic const SLIDES = [1, 2, 3, 4, 5];\n\n<Carousel|item| items=SLIDES slidesPerPage=3 spacing=\"1rem\" class=\"w-full max-w-sm\">\n  <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card\">\n    <span class=\"text-2xl font-semibold\">${item}</span>\n  </div>\n</Carousel>","description":"Set `spacing` to control the gap between items."},{"id":"carousel-orientation","title":"Orientation","source":"import Carousel from \"@marko-ui/shadcn/ui/carousel/carousel.marko\";\n\nstatic const SLIDES = [1, 2, 3, 4, 5];\n\n<Carousel|item| items=SLIDES orientation=\"vertical\" class=\"mx-auto h-[16rem] w-full max-w-xs\">\n  <div class=\"flex h-24 items-center justify-center rounded-lg border bg-card\">\n    <span class=\"text-3xl font-semibold\">${item}</span>\n  </div>\n</Carousel>","description":"Set `orientation` to `vertical` to stack slides top to bottom."},{"id":"carousel-api","title":"API","source":"import Carousel from \"@marko-ui/shadcn/ui/carousel/carousel.marko\";\n\nstatic const SLIDES = [1, 2, 3, 4, 5];\n\n<let/page=0/>\n\n<div class=\"mx-auto max-w-[10rem] sm:max-w-xs\">\n  <Carousel|item| items=SLIDES class=\"w-full max-w-xs\" pageChange(newPage) { page = newPage; }>\n    <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card m-px\">\n      <span class=\"text-4xl font-semibold\">${item}</span>\n    </div>\n  </Carousel>\n  <div class=\"py-2 text-center text-sm text-muted-foreground\">\n    Slide ${page + 1} of ${SLIDES.length}\n  </div>\n</div>","description":"A `<Carousel/carouselApi/>` tag-variable capture gives you the live, reactive machine api — read `carouselApi().page` and `carouselApi().pageSnapPoints` directly, no `setApi`/`useEffect` subscription needed."},{"id":"carousel-plugin","title":"Autoplay","source":"import Carousel from \"@marko-ui/shadcn/ui/carousel/carousel.marko\";\n\nstatic const SLIDES = [1, 2, 3, 4, 5];\n\n<let/paused=false/>\n\n<div\n  class=\"w-full max-w-[10rem] sm:max-w-xs\"\n  onMouseEnter() { paused = true; }\n  onMouseLeave() { paused = false; }\n>\n  <Carousel|item|\n    items=SLIDES\n    autoplay=(paused ? false : { delay: 2000 })\n    class=\"w-full\"\n  >\n    <div class=\"p-1\">\n      <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card\">\n        <span class=\"text-4xl font-semibold\">${item}</span>\n      </div>\n    </div>\n  </Carousel>\n</div>","description":"Our carousel is backed by `@zag-js/carousel`, which has autoplay built in — pass `autoplay={ delay }` instead of an Embla plugin, and call `api().pause()` / `api().play()` to stop on hover."},{"id":"carousel-rtl","title":"RTL","source":"import Carousel from \"@marko-ui/shadcn/ui/carousel/carousel.marko\";\n\nstatic const ARABIC_NUMERALS = [\"٠\", \"١\", \"٢\", \"٣\", \"٤\", \"٥\", \"٦\", \"٧\", \"٨\", \"٩\"];\nstatic function toArabicNumerals(num: number): string {\n  return String(num)\n    .split(\"\")\n    .map((digit) => ARABIC_NUMERALS[Number(digit)])\n    .join(\"\");\n}\n\nstatic const SLIDES = [1, 2, 3, 4, 5];\n\n<Carousel|item| items=SLIDES dir=\"rtl\" class=\"w-full max-w-[12rem] sm:max-w-xs\">\n  <div class=\"p-1\">\n    <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card\">\n\n      <span class=\"text-4xl font-semibold\">${toArabicNumerals(item as number)}</span>\n    </div>\n  </div>\n</Carousel>","description":"`dir=\"rtl\"` is a real machine prop: it flips scroll direction, keyboard arrows, and item order. The previous/next icons already carry `mu-rtl-flip` in the component, so no extra classes are needed."},{"id":"carousel-loop","title":"Loop","source":"import Carousel from \"@marko-ui/shadcn/ui/carousel/carousel.marko\";\n\nstatic const SLIDES = [1, 2, 3, 4, 5];\n\n<Carousel|item| items=SLIDES loop class=\"w-full max-w-xs\">\n  <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card\">\n    <span class=\"text-4xl font-semibold\">${item}</span>\n  </div>\n</Carousel>","description":"Set `loop` so the carousel wraps around at the first and last slide."},{"id":"carousel-controlled","title":"Controlled","source":"import Carousel from \"@marko-ui/shadcn/ui/carousel/carousel.marko\";\n\nstatic const SLIDES = [1, 2, 3, 4, 5];\n\n<let/page=0/>\n\n<div>\n  <p class=\"mb-4 text-sm text-muted-foreground\">Page: ${page}</p>\n  <Carousel|item|\n    items=SLIDES\n    page=page\n    pageChange(next) { page = next; }\n    class=\"w-full max-w-xs\"\n  >\n    <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card\">\n      <span class=\"text-4xl font-semibold\">${item}</span>\n    </div>\n  </Carousel>\n</div>","description":"The carousel is controlled: a `page` prop without `pageChange` never moves. Pair the two to drive the current page from your own state.","essential":true},{"id":"carousel-compound","title":"Compound (attr tags)","source":"import Carousel from \"@marko-ui/shadcn/ui/carousel/carousel.marko\";\n\n<Carousel class=\"w-full max-w-xs\">\n  <@slide>\n    <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card\">\n      <span class=\"text-4xl font-semibold\">1</span>\n    </div>\n  </@slide>\n  <@slide>\n    <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card\">\n      <span class=\"text-4xl font-semibold\">2</span>\n    </div>\n  </@slide>\n  <@slide>\n    <div class=\"flex aspect-square items-center justify-center rounded-lg border bg-card\">\n      <span class=\"text-4xl font-semibold\">3</span>\n    </div>\n  </@slide>\n</Carousel>","description":"Use `<@slide>` attribute tags instead of `items=` to compose each slide's markup directly.","essential":true}],"importInstallCommand":"bun add @marko-ui/shadcn marko-zag","body":{"param":"T | undefined, number","description":"Render prop for `items=` entries.\n\nThe item is `T | undefined`, not `T`: a bodyless `<@slide/>` produces an\nentry with no datum, and the render path below deliberately still invokes\nthis body for it (see the comment at the call site — the render prop owns\nplaceholder slides). Declaring it as `T` promised a value this component\ndoes not always pass."},"nativeAttributes":"div","composition":"`Carousel` is a single component, not four. Where upstream composes `Carousel` / `CarouselContent` / `CarouselItem` / `CarouselPrevious` / `CarouselNext`, this port folds the item group, previous/next triggers, and a page-indicator group into `Carousel` itself: pass `items=` and render each one through the tag's own body, taking the item as a default-body tag parameter (or use `@slide` attr tags for static markup), and the component renders the scroll container, buttons, and indicators for you. There is no separate `CarouselContent`, `CarouselItem`, `CarouselPrevious`, or `CarouselNext` tag to import."}
