@rozie-ui/embla-lit
v0.1.12
Published
Idiomatic Lit carousel wrapping Embla Carousel — one Rozie source compiled to Lit.
Maintainers
Readme
@rozie-ui/embla-lit
Idiomatic lit Carousel — a cross-framework carousel compiled from one Rozie source wrapping Embla Carousel (v8). The current snap is two-way bound via selectedIndex; slides come as a slides config array or as default-slot DOM. This package is generated; do not edit src/ by hand.
Declarative-mode slides must carry
class="rozie-embla__slide". The component pins Embla'sslidesoption to that exact selector, so unclassed default-slot children are not measured as slides. On Lit specifically, declarative (default-slot) slides do not resolve at all today — the selector is queried from inside the shadow root, which cannot see light-DOM children assigned through<slot>; use theslidesconfig-array prop on Lit instead.
Install
npm i @rozie-ui/embla-litPeer dependencies: the embla-carousel (^8.6) + embla-carousel-autoplay (^8.6) engine packages + lit + @lit-labs/preact-signals + @preact/signals-core. Install them alongside this package.
Also installed: @rozie/runtime-lit — Rozie's small, tree-shaken runtime helper package (controllable state, keyboard navigation, event modifiers, and safe interpolation). It arrives as a regular dependency, so npm pulls it for you. Your bundler keeps only the helpers this component actually uses — typically a few hundred bytes to a few KB, minified and gzipped. What's in it and what it costs.
No engine CSS to import — the carousel skeleton styles (overflow: hidden viewport, flex container, slide sizing) ship scoped inside the component.
Usage
import '@rozie-ui/embla-lit';
// <rozie-carousel> is a custom element. Bind `slides`/`selectedIndex` as
// properties and listen for `selected-index-change` (the two-way change channel)
// + `select`.
const el = document.querySelector('rozie-carousel');
el.slides = ['A', 'B', 'C'];
el.loop = true;
el.addEventListener('selected-index-change', (e) => { el.selectedIndex = e.detail; });
el.addEventListener('select', (e) => console.log('snap', e.detail));Props
| Name | Type | Default | Two-way (model) | Required |
| --- | --- | --- | :---: | :---: |
| slides | Array | [] | | |
| loop | Boolean | false | | |
| align | String | "center" | | |
| axis | String | "x" | | |
| slidesToScroll | Number | 1 | | |
| dragFree | Boolean | false | | |
| draggable | Boolean | true | | |
| containScroll | String | "trimSnaps" | | |
| startIndex | Number | 0 | | |
| skipSnaps | Boolean | false | | |
| duration | Number | 25 | | |
| direction | String | "ltr" | | |
| autoplay | Boolean | false | | |
| autoplayDelay | Number | 4000 | | |
| dots | Boolean | false | | |
| arrows | Boolean | false | | |
| thumbnails | Boolean | false | | |
| plugins | Array | [] | | |
| options | Object | {} | | |
| selectedIndex | Number | 0 | ✓ | |
Events
addEventListener name — the Lit target dispatches multi-word event names kebab-cased (reInit dispatches as re-init, not reinit).
| Event | Payload | Description |
| --- | --- | --- |
| select | index: number | Fires on every snap change (drag, scroll, or programmatic). Distinct from the selectedIndex model prop — a model prop must not share a name with an emit. |
| settle | — | Fires when carousel motion stops (after a drag, scroll, or reInit settles). |
| re-init | — | Fires when the engine re-initialises (an option flip, a slide add/remove, or a manual reInitCarousel() call). The current snap is preserved across it. |
| pointer-down | — | Fires when a pointer drag begins on the viewport. |
Imperative handle
Beyond props, the component exposes imperative methods (declared once in the Rozie source via $expose). Grab a handle with the native ref mechanism and call them directly:
// The custom element IS the handle — its exposed methods are public
// element methods.
const el = document.querySelector('rozie-carousel');
el.scrollNext();
const i = el.getSelectedIndex();| Method | Description |
| --- | --- |
| scrollNext | Scroll to the next snap — scrollNext(jump?) (jump skips the transition). No-op before mount. |
| scrollPrev | Scroll to the previous snap — scrollPrev(jump?). No-op before mount. |
| scrollToIndex | Scroll to a specific snap index — scrollToIndex(index, jump?) (Embla scrollTo). Named to avoid the inherited DOM HTMLElement.scrollTo(x, y). No-op before mount. |
| reInitCarousel | Re-initialise the Embla engine (recompute snaps) — reInitCarousel(opts?). Pass raw EmblaOptionsType to override; omit to re-apply the current prop-derived options. (NOT reInit, which is the emitted event.) |
| canScrollNext | Return whether a next snap is reachable — canScrollNext(). False before mount. |
| canScrollPrev | Return whether a previous snap is reachable — canScrollPrev(). False before mount. |
| getSelectedIndex | Return the current scroll-snap index — getSelectedIndex() (Embla selectedScrollSnap()). 0 before mount. (NOT selectedIndex, which is the two-way model prop.) |
| scrollSnapList | Return the snap-point progress array — scrollSnapList() (numbers in [0, 1]). Empty before mount. |
| scrollProgress | Return the overall scroll progress in [0, 1] — scrollProgress() — to drive a custom progress bar / scrollbar thumb. 0 before mount. |
| slidesInView | Return the indices of slides currently in view — slidesInView() — for lazy-loading or highlighting in-view dots. Empty before mount. |
| slidesNotInView | Return the indices of slides currently out of view — slidesNotInView() — to unload heavy off-screen content. Empty before mount. |
| previousScrollSnap | Return the previously selected snap index — previousScrollSnap() — to compute transition direction. 0 before mount. |
| getPlugins | Return the live plugin API map — getPlugins() (e.g. getPlugins().autoplay?.play()/.stop()) for imperative autoplay pause/resume. (NOT plugins, which is a prop.) Null before mount. |
| getInstance | Return the underlying EmblaCarouselType instance for direct API access (the engine escape hatch). Null before mount. |
Slots
| Slot | Params | | --- | --- | | slide | slide, index | | (default) | | | thumb | slide, index |
