feat: dots() self-gating fallback control module
This commit is contained in:
+47
@@ -0,0 +1,47 @@
|
||||
import type { Carousel } from './index.ts';
|
||||
|
||||
const NOOP = () => {};
|
||||
|
||||
/**
|
||||
* Wire the developer's existing dot elements to a carousel.
|
||||
* Progressive fallback: no-ops where native ::scroll-marker is supported, so the
|
||||
* native marker group is the sole control there (no double dots).
|
||||
* @param c - carousel instance
|
||||
* @param container - element whose children are the dot controls
|
||||
* @returns cleanup function (a noop when native markers are used)
|
||||
*/
|
||||
export function dots(c: Carousel, container: HTMLElement): () => void {
|
||||
// Native markers present → let CSS own the controls.
|
||||
if (typeof CSS !== 'undefined' && CSS.supports('selector(::scroll-marker)')) {
|
||||
return NOOP;
|
||||
}
|
||||
|
||||
const items = Array.from(container.children) as HTMLElement[];
|
||||
|
||||
const handlers = items.map((el, i) => {
|
||||
const h = () => c.scrollToIndex(i);
|
||||
el.addEventListener('click', h);
|
||||
return h;
|
||||
});
|
||||
|
||||
function mark(active: number) {
|
||||
items.forEach((el, i) => {
|
||||
if (i === active) {
|
||||
el.setAttribute('aria-current', 'true');
|
||||
el.classList.add('active');
|
||||
} else {
|
||||
el.removeAttribute('aria-current');
|
||||
el.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
mark(c.index);
|
||||
const off = c.on('change', mark);
|
||||
|
||||
return () => {
|
||||
off();
|
||||
items.forEach((el, i) => {
|
||||
el.removeEventListener('click', handlers[i]);
|
||||
});
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user