48 lines
1.3 KiB
TypeScript
48 lines
1.3 KiB
TypeScript
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]);
|
||
|
|
});
|
||
|
|
};
|
||
|
|
}
|