@nordwerk/scroll-carousel 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,78 +0,0 @@
1
- // src/math.ts
2
- var EPS = 2;
3
- var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
4
- var closest = (values, target) => {
5
- let best = 0;
6
- for (let i = 1; i < values.length; i++) {
7
- if (Math.abs(values[i] - target) < Math.abs(values[best] - target) - 0.5) best = i;
8
- }
9
- return best;
10
- };
11
- var snapPositions = ({ starts, sizes, port, padStart, padEnd, max, align }) => starts.map(
12
- (start, i) => clamp(
13
- align === "center" ? start + sizes[i] / 2 - padStart - (port - padStart - padEnd) / 2 : align === "end" ? start + sizes[i] - port + padEnd : start - padStart,
14
- 0,
15
- max
16
- )
17
- );
18
- var pageStarts = (geo, snaps, group, anchor) => {
19
- const count = snaps.length;
20
- const firsts = /* @__PURE__ */ new Set([0, anchor]);
21
- if (group === "page") {
22
- const fits = (from, last) => geo.starts[last] + geo.sizes[last] <= snaps[from] + geo.port - geo.padEnd + EPS;
23
- for (let i = anchor; i < count && snaps[i] < geo.max - EPS; ) {
24
- let next = i + 1;
25
- while (next < count && fits(i, next)) next++;
26
- if (next >= count) break;
27
- firsts.add(i = next);
28
- }
29
- for (let i = anchor; i > 0; ) {
30
- let first = i - 1;
31
- while (first > 0 && fits(first - 1, i - 1)) first--;
32
- firsts.add(i = first);
33
- }
34
- } else {
35
- for (let i = anchor % group; i < count; i += group) firsts.add(i);
36
- }
37
- return [...firsts].filter((i) => i >= 0 && i < count).sort((a, b) => a - b);
38
- };
39
- var buildPages = (geo, snaps, group, anchor) => {
40
- const pages = [];
41
- const add = (pos) => {
42
- const first = snaps.findIndex((snap) => snap >= pos - EPS);
43
- pages.push({ pos, first: first < 0 ? snaps.length - 1 : first });
44
- };
45
- for (const start of pageStarts(geo, snaps, group, anchor)) {
46
- if (!pages.length || snaps[start] > pages[pages.length - 1].pos + EPS) add(snaps[start]);
47
- }
48
- if (pages.length && pages[pages.length - 1].pos < geo.max - EPS) add(geo.max);
49
- return pages;
50
- };
51
- var pageOf = (pages, index) => {
52
- let page = 0;
53
- pages.forEach((candidate, i) => {
54
- if (candidate.first <= index) page = i;
55
- });
56
- return page;
57
- };
58
- var visibleRange = (pos, { starts, sizes, port }) => {
59
- let first = -1;
60
- let last = -1;
61
- starts.forEach((start, i) => {
62
- if (Math.min(start + sizes[i], pos + port) - Math.max(start, pos) >= sizes[i] / 2 - 0.5) {
63
- if (first < 0) first = i;
64
- last = i;
65
- }
66
- });
67
- return [first, last];
68
- };
69
-
70
- export {
71
- EPS,
72
- clamp,
73
- closest,
74
- snapPositions,
75
- buildPages,
76
- pageOf,
77
- visibleRange
78
- };
@@ -1,377 +0,0 @@
1
- import {
2
- EPS,
3
- buildPages,
4
- clamp,
5
- closest,
6
- pageOf,
7
- snapPositions,
8
- visibleRange
9
- } from "./chunk-3THCBXDW.js";
10
-
11
- // src/index.ts
12
- var LABELS = {
13
- page: (n, count) => `Page ${n} of ${count}`,
14
- status: (first, last, count) => first === last ? `Item ${first} of ${count}` : `Items ${first} to ${last} of ${count}`
15
- };
16
- var px = (value) => parseFloat(value) || 0;
17
- var lengthIn = (value, whole) => value.trim().endsWith("%") ? px(value) * whole / 100 : px(value);
18
- var instances = /* @__PURE__ */ new WeakMap();
19
- var getCarousel = (root) => instances.get(root);
20
- function attach(root, options = {}) {
21
- const existing = instances.get(root);
22
- if (existing) return existing;
23
- const track = root.querySelector("[data-sc-track]");
24
- const part = (name) => options[name] || root.querySelector(`[data-sc-${name}]`);
25
- const prevButton = part("prev");
26
- const nextButton = part("next");
27
- const dots = part("dots");
28
- const status = part("status");
29
- const labels = { ...LABELS, ...options.labels };
30
- const rewind = options.rewind === true ? "fade" : options.rewind || false;
31
- const motion = matchMedia("(prefers-reduced-motion: reduce)");
32
- const tabIndex = track.getAttribute("tabindex");
33
- const listeners = new AbortController();
34
- const listen = (target2, type, handler, opts) => target2?.addEventListener(type, handler, { signal: listeners.signal, ...opts });
35
- const hooks = { control: [], settle: [], measure: [] };
36
- const run = (name) => hooks[name].forEach((handler) => handler());
37
- let slides = [...track.children];
38
- const marked = slides.findIndex((slide) => slide.hasAttribute("data-sc-initial"));
39
- let anchor = Math.max(0, options.initial ?? marked);
40
- const anchorSlide = slides[anchor];
41
- let needsInitial = anchor > 0;
42
- let geo = { starts: [], sizes: [], port: 0, padStart: 0, padEnd: 0, max: 0, align: "start" };
43
- let snaps = [];
44
- let pages = [];
45
- let snap = "mandatory";
46
- let rtl = false;
47
- let pos = 0;
48
- let target = -1;
49
- let scrolling = false;
50
- let touching = false;
51
- let busy = false;
52
- let quiet = false;
53
- let state;
54
- let settled;
55
- let frame = 0;
56
- let measureFrame = 0;
57
- let settleTimer = 0;
58
- let fadeTimer = 0;
59
- const readPos = () => Math.abs(track.scrollLeft);
60
- const positions = () => pages.map((page) => page.pos);
61
- const moveTo = (position, behavior) => track.scrollTo({ left: rtl ? -position : position, behavior });
62
- function measure() {
63
- slides = [...track.children];
64
- const style = getComputedStyle(track);
65
- rtl = style.direction == "rtl";
66
- const configured = String(options.group ?? style.getPropertyValue("--sc-group")).trim();
67
- const group = configured == "page" ? "page" : Math.max(1, parseInt(configured) || 1);
68
- if (!track.hasAttribute("data-sc-dragging")) {
69
- const type = style.scrollSnapType;
70
- snap = type == "none" ? "none" : type.includes("mandatory") ? "mandatory" : "proximity";
71
- }
72
- const box = track.getBoundingClientRect();
73
- const edge = rtl ? box.right - px(style.borderRightWidth) : box.left + px(style.borderLeftWidth);
74
- const offset = readPos();
75
- const port = track.clientWidth;
76
- geo = {
77
- starts: [],
78
- sizes: [],
79
- port,
80
- padStart: lengthIn(style.scrollPaddingInlineStart, port),
81
- padEnd: lengthIn(style.scrollPaddingInlineEnd, port),
82
- max: Math.max(0, track.scrollWidth - port),
83
- align: style.getPropertyValue("--sc-align").trim() || "start"
84
- };
85
- for (const slide of slides) {
86
- const rect = slide.getBoundingClientRect();
87
- geo.starts.push((rtl ? edge - rect.right : rect.left - edge) + offset);
88
- geo.sizes.push(rect.width);
89
- }
90
- snaps = snapPositions(geo);
91
- if (anchorSlide?.parentNode == track) anchor = slides.indexOf(anchorSlide);
92
- anchor = Math.max(0, Math.min(anchor, slides.length - 1));
93
- pages = buildPages(geo, snaps, group, anchor);
94
- if (target >= pages.length) target = -1;
95
- const firsts = new Set(pages.map((page) => page.first));
96
- slides.forEach((slide, i) => slide.toggleAttribute("data-sc-snap-off", group != 1 && !firsts.has(i)));
97
- if (dots) {
98
- while (dots.children.length > pages.length) dots.lastElementChild.remove();
99
- while (dots.children.length < pages.length) {
100
- const dot = document.createElement("button");
101
- dot.type = "button";
102
- dot.className = "sc-dot";
103
- dots.append(dot);
104
- }
105
- [...dots.children].forEach((dot, i) => dot.setAttribute("aria-label", labels.page(i + 1, pages.length)));
106
- }
107
- if (needsInitial && port && pages.length) {
108
- needsInitial = false;
109
- const initial = pages[pageOf(pages, anchor)].pos;
110
- if (Math.abs(readPos() - initial) > 1) moveTo(initial, "instant");
111
- }
112
- pos = readPos();
113
- run("measure");
114
- }
115
- function update(isSettled, silent) {
116
- const moving = target >= 0;
117
- const here = moving ? pages[target].pos : pos;
118
- const page = moving ? target : closest(positions(), pos);
119
- state = {
120
- index: moving ? pages[target].first : closest(snaps, pos),
121
- page,
122
- pageCount: pages.length,
123
- isBeginning: here <= EPS,
124
- isEnd: here >= geo.max - EPS,
125
- overflow: geo.max > EPS
126
- };
127
- for (const [name, on] of [["overflow", state.overflow], ["start", state.isBeginning], ["end", state.isEnd]]) {
128
- root.toggleAttribute("data-sc-" + name, on);
129
- }
130
- if (tabIndex == "0") track.tabIndex = state.overflow ? 0 : -1;
131
- prevButton?.setAttribute("aria-disabled", String(state.isBeginning && !rewind));
132
- nextButton?.setAttribute("aria-disabled", String(state.isEnd && !rewind));
133
- if (dots) {
134
- [...dots.children].forEach((dot, i) => i == page ? dot.setAttribute("aria-current", "true") : dot.removeAttribute("aria-current"));
135
- }
136
- if (!isSettled) return;
137
- if (settled && ["index", "page", "pageCount"].every((key) => settled[key] == state[key])) return;
138
- const first = !settled;
139
- settled = state;
140
- if (first) return;
141
- root.dispatchEvent(new CustomEvent("sc:change", { detail: { ...state } }));
142
- options.onChange?.({ ...state });
143
- if (status && !silent && !quiet) {
144
- const [from, to] = visibleRange(pos, geo);
145
- if (from >= 0) status.textContent = labels.status(from + 1, to + 1, slides.length, slides);
146
- }
147
- quiet = false;
148
- }
149
- function armSettle() {
150
- clearTimeout(settleTimer);
151
- settleTimer = setTimeout(settle, "onscrollend" in window ? 400 : 120);
152
- }
153
- function settle() {
154
- clearTimeout(settleTimer);
155
- if (touching || busy) return;
156
- scrolling = false;
157
- target = -1;
158
- pos = readPos();
159
- run("settle");
160
- update(true);
161
- }
162
- function cancelFade() {
163
- clearTimeout(fadeTimer);
164
- track.removeAttribute("data-sc-fading");
165
- }
166
- function scrollToPos(position, how) {
167
- cancelFade();
168
- if (Math.abs(readPos() - position) < 1) return settle();
169
- if (how == "fade" && !motion.matches) {
170
- track.setAttribute("data-sc-fading", "");
171
- fadeTimer = setTimeout(() => {
172
- moveTo(position, "instant");
173
- track.removeAttribute("data-sc-fading");
174
- }, 160);
175
- return;
176
- }
177
- moveTo(position, how == "instant" || motion.matches ? "instant" : "smooth");
178
- armSettle();
179
- }
180
- function toPage(page, how) {
181
- if (!pages[page]) return;
182
- target = page;
183
- update();
184
- scrollToPos(pages[page].pos, how);
185
- }
186
- function step(direction, wrap, silent) {
187
- if (pages.length < 2) return;
188
- if (silent) quiet = true;
189
- const from = target >= 0 ? pages[target].pos : readPos();
190
- let next = -1;
191
- pages.forEach((page, i) => {
192
- if (direction > 0 ? next < 0 && page.pos > from + EPS : page.pos < from - EPS) next = i;
193
- });
194
- if (next >= 0) toPage(next);
195
- else if (wrap) toPage(direction > 0 ? 0 : pages.length - 1, rewind == "fade" ? "fade" : void 0);
196
- }
197
- function takeControl() {
198
- quiet = false;
199
- run("control");
200
- }
201
- function grab() {
202
- takeControl();
203
- cancelFade();
204
- target = -1;
205
- }
206
- const click = (button, direction) => listen(button, "click", () => {
207
- if (button.getAttribute("aria-disabled") == "true") return;
208
- takeControl();
209
- step(direction, !!rewind);
210
- });
211
- click(prevButton, -1);
212
- click(nextButton, 1);
213
- listen(dots, "click", (event) => {
214
- const dot = event.target.closest(".sc-dot");
215
- if (!dot) return;
216
- takeControl();
217
- toPage([...dots.children].indexOf(dot));
218
- });
219
- listen(track, "keydown", (event) => {
220
- if (event.target != track || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;
221
- const key = event.key;
222
- const forward = rtl ? "ArrowLeft" : "ArrowRight";
223
- if (![forward, rtl ? "ArrowRight" : "ArrowLeft", "Home", "End"].includes(key)) return;
224
- event.preventDefault();
225
- takeControl();
226
- if (key == "Home") toPage(0);
227
- else if (key == "End") toPage(pages.length - 1);
228
- else step(key == forward ? 1 : -1, false);
229
- });
230
- listen(
231
- track,
232
- "scroll",
233
- () => {
234
- scrolling = true;
235
- frame ||= requestAnimationFrame(() => {
236
- frame = 0;
237
- pos = readPos();
238
- update();
239
- });
240
- armSettle();
241
- },
242
- { passive: true }
243
- );
244
- listen(track, "scrollend", settle);
245
- listen(
246
- track,
247
- "touchstart",
248
- () => {
249
- touching = true;
250
- grab();
251
- },
252
- { passive: true }
253
- );
254
- for (const type of ["touchend", "touchcancel"]) {
255
- listen(
256
- track,
257
- type,
258
- () => {
259
- touching = false;
260
- armSettle();
261
- },
262
- { passive: true }
263
- );
264
- }
265
- listen(
266
- track,
267
- "wheel",
268
- (event) => {
269
- if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) grab();
270
- },
271
- { passive: true }
272
- );
273
- const resizes = new ResizeObserver(() => {
274
- measureFrame ||= requestAnimationFrame(() => {
275
- measureFrame = 0;
276
- measure();
277
- update(!scrolling, true);
278
- });
279
- });
280
- const observeSlides = () => {
281
- resizes.disconnect();
282
- for (const element of [track, ...slides]) resizes.observe(element);
283
- };
284
- const mutations = new MutationObserver(() => {
285
- const keep = !scrolling && target < 0 && !busy ? slides[state.index] : void 0;
286
- const seen = keep ? geo.starts[state.index] - pos : 0;
287
- measure();
288
- if (keep?.parentNode == track) {
289
- const wanted = clamp(geo.starts[slides.indexOf(keep)] - seen, 0, geo.max);
290
- if (Math.abs(readPos() - wanted) > 1) {
291
- moveTo(wanted, "instant");
292
- pos = readPos();
293
- }
294
- }
295
- observeSlides();
296
- update(!scrolling, true);
297
- });
298
- const context = {
299
- root,
300
- track,
301
- listen,
302
- layout: () => ({ pages, max: geo.max, rtl, snap, state }),
303
- toPage,
304
- scrollTo: scrollToPos,
305
- step,
306
- grab,
307
- hold: (on) => busy = on,
308
- on: (event, handler) => hooks[event].push(handler)
309
- };
310
- const api = {
311
- root,
312
- track,
313
- get slides() {
314
- return slides;
315
- },
316
- get state() {
317
- return { ...state };
318
- },
319
- next() {
320
- takeControl();
321
- step(1, !!rewind);
322
- },
323
- prev() {
324
- takeControl();
325
- step(-1, !!rewind);
326
- },
327
- slideTo(index, { instant } = {}) {
328
- takeControl();
329
- toPage(pageOf(pages, clamp(index, 0, slides.length - 1)), instant ? "instant" : void 0);
330
- },
331
- goToPage(page, { instant } = {}) {
332
- takeControl();
333
- toPage(clamp(page, 0, pages.length - 1), instant ? "instant" : void 0);
334
- },
335
- update() {
336
- measure();
337
- update(!scrolling, true);
338
- },
339
- destroy() {
340
- listeners.abort();
341
- resizes.disconnect();
342
- mutations.disconnect();
343
- cancelAnimationFrame(frame);
344
- cancelAnimationFrame(measureFrame);
345
- clearTimeout(settleTimer);
346
- cancelFade();
347
- cleanups.forEach((cleanup) => cleanup?.());
348
- for (const name of ["ready", "overflow", "start", "end"]) root.removeAttribute(`data-sc-${name}`);
349
- for (const slide of track.children) slide.removeAttribute("data-sc-snap-off");
350
- if (tabIndex != null) track.setAttribute("tabindex", tabIndex);
351
- prevButton?.removeAttribute("aria-disabled");
352
- nextButton?.removeAttribute("aria-disabled");
353
- dots?.replaceChildren();
354
- instances.delete(root);
355
- }
356
- };
357
- for (const key of ["index", "page", "pageCount", "isBeginning", "isEnd"]) {
358
- Object.defineProperty(api, key, { get: () => state[key] });
359
- }
360
- measure();
361
- update(true, true);
362
- observeSlides();
363
- mutations.observe(track, { childList: true });
364
- const cleanups = (options.plugins || []).map((plugin) => {
365
- const { destroy, ...extra } = plugin(context) || {};
366
- Object.assign(api, extra);
367
- return destroy;
368
- });
369
- instances.set(root, api);
370
- root.setAttribute("data-sc-ready", "");
371
- return api;
372
- }
373
-
374
- export {
375
- getCarousel,
376
- attach
377
- };
@@ -1,109 +0,0 @@
1
- import {
2
- attach
3
- } from "./chunk-HPGJKTV5.js";
4
- import {
5
- PRE_POSITION,
6
- baseVars,
7
- responsiveCss
8
- } from "./chunk-QHWWA243.js";
9
-
10
- // src/adapter.ts
11
- var chevron = (h, path) => h("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false" }, h("path", { d: path }));
12
- function createAdapter(framework) {
13
- const { createElement: h, Fragment, useState, useRef, useEffect, useLayoutEffect, useId, toChildArray } = framework;
14
- const useBeforePaint = typeof window == "undefined" ? useEffect : useLayoutEffect;
15
- function useCarousel(options = {}) {
16
- const ref = useRef(null);
17
- const latest = useRef(options);
18
- latest.current = options;
19
- const [carousel, setCarousel] = useState(null);
20
- const [state, setState] = useState(null);
21
- useBeforePaint(() => {
22
- if (!ref.current) return;
23
- const instance = attach(ref.current, {
24
- ...latest.current,
25
- onChange: (next) => {
26
- setState(next);
27
- latest.current.onChange?.(next);
28
- }
29
- });
30
- setCarousel(instance);
31
- setState(instance.state);
32
- return () => {
33
- instance.destroy();
34
- setCarousel(null);
35
- };
36
- }, []);
37
- return { ref, carousel, state };
38
- }
39
- function Carousel(props) {
40
- const id = useId();
41
- const { as = "div", label, children, className, style, slideClassName, slideRoles, centerFew } = props;
42
- const { arrows = true, dots = true, playButton, labels = {}, initial = 0, carouselRef } = props;
43
- const { ref, carousel } = useCarousel({
44
- group: typeof props.group == "object" ? void 0 : props.group,
45
- initial,
46
- rewind: props.rewind,
47
- labels,
48
- plugins: props.plugins,
49
- onChange: props.onChange
50
- });
51
- const handoff = useRef(carouselRef);
52
- handoff.current = carouselRef;
53
- useEffect(() => {
54
- if (!carousel) return;
55
- handoff.current?.(carousel);
56
- return () => handoff.current?.(null);
57
- }, [carousel]);
58
- const slides = toChildArray(children);
59
- const item = as == "ul" ? "li" : "div";
60
- const css = responsiveCss(id, props);
61
- const root = h(
62
- "div",
63
- {
64
- ref,
65
- className: ["sc", centerFew && "sc--center-few", className].filter(Boolean).join(" "),
66
- "data-sc-id": id,
67
- style: { ...baseVars(props), ...style }
68
- },
69
- // Raw, not as a text child: renderers may escape text inside <style>, which breaks the selectors.
70
- css && h("style", { dangerouslySetInnerHTML: { __html: css } }),
71
- h(
72
- as,
73
- { className: "sc-track", "data-sc-track": "", tabIndex: 0, "aria-label": label },
74
- slides.map(
75
- (child, i) => h(
76
- item,
77
- {
78
- key: child?.key ?? i,
79
- className: slideClassName,
80
- "data-sc-initial": i == initial && i > 0 ? "" : void 0,
81
- ...slideRoles && { role: "group", "aria-roledescription": "slide", "aria-label": `${i + 1} of ${slides.length}` }
82
- },
83
- child
84
- )
85
- )
86
- ),
87
- arrows && h(
88
- Fragment,
89
- null,
90
- h("button", { type: "button", className: "sc-nav sc-prev", "data-sc-prev": "", "aria-label": labels.prev || "Previous" }, chevron(h, "m15 18-6-6 6-6")),
91
- h("button", { type: "button", className: "sc-nav sc-next", "data-sc-next": "", "aria-label": labels.next || "Next" }, chevron(h, "m9 6 6 6-6 6"))
92
- ),
93
- playButton && h(
94
- "button",
95
- { type: "button", className: "sc-play", "data-sc-play": "", "aria-label": "Stop automatic scrolling" },
96
- h("svg", { className: "sc-icon-play", viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false" }, h("path", { d: "M8 5v14l11-7z" })),
97
- h("svg", { className: "sc-icon-pause", viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false" }, h("path", { d: "M7 5h3.5v14H7zM13.5 5H17v14h-3.5z" }))
98
- ),
99
- dots && h("div", { className: "sc-dots", "data-sc-dots": "" }),
100
- h("p", { className: "sc-status", "data-sc-status": "", "aria-live": "polite" })
101
- );
102
- return initial > 0 ? h(Fragment, null, root, h("script", { dangerouslySetInnerHTML: { __html: PRE_POSITION } })) : root;
103
- }
104
- return { Carousel, useCarousel };
105
- }
106
-
107
- export {
108
- createAdapter
109
- };
@@ -1,61 +0,0 @@
1
- // src/markup.ts
2
- var PROPERTIES = {
3
- perView: "per-view",
4
- slideSize: "slide-size",
5
- gap: "gap",
6
- offsetBefore: "offset-before",
7
- offsetAfter: "offset-after",
8
- snap: "snap",
9
- align: "align",
10
- group: "group",
11
- controls: "controls"
12
- };
13
- var LENGTHS = /* @__PURE__ */ new Set(["gap", "offsetBefore", "offsetAfter"]);
14
- function value(key, raw) {
15
- if (key == "controls") return raw ? "initial" : "none";
16
- return typeof raw == "number" && LENGTHS.has(key) ? `${raw}px` : String(raw).replace(/[<>]/g, "");
17
- }
18
- var isResponsive = (raw) => typeof raw == "object" && raw != null;
19
- function baseVars(props) {
20
- const vars = {};
21
- for (const [key, name] of Object.entries(PROPERTIES)) {
22
- const raw = props[key];
23
- const base = isResponsive(raw) ? raw[0] : raw;
24
- if (base !== void 0 && !(key == "controls" && base)) vars[`--sc-${name}`] = value(key, base);
25
- }
26
- if (props.centered) vars["--sc-centered"] = "1";
27
- return vars;
28
- }
29
- var baseStyle = (props) => Object.entries(baseVars(props)).map(([name, val]) => `${name}:${val}`).join(";");
30
- function responsiveCss(id, props) {
31
- const rules = /* @__PURE__ */ new Map();
32
- for (const [key, name] of Object.entries(PROPERTIES)) {
33
- const raw = props[key];
34
- if (!isResponsive(raw)) continue;
35
- for (const [width, val] of Object.entries(raw)) {
36
- if (+width <= 0) continue;
37
- if (!rules.has(+width)) rules.set(+width, []);
38
- rules.get(+width).push(`--sc-${name}:${value(key, val)}`);
39
- }
40
- }
41
- return [...rules].sort(([a], [b]) => a - b).map(([width, decls]) => `@container sc (min-width:${width}px){[data-sc-id="${id}"]>*{${decls.join(";")}}}`).join("");
42
- }
43
- var PRE_POSITION = "(function(r){var t=r.querySelector('[data-sc-track]'),s=t&&t.querySelector('[data-sc-initial]'),f=t&&t.firstElementChild;if(!s||s==f)return;var a=s.getBoundingClientRect(),b=f.getBoundingClientRect();t.scrollLeft=getComputedStyle(t).direction=='rtl'?a.right-b.right:a.left-b.left})(document.currentScript.previousElementSibling)";
44
- function templateLabels(templates = {}) {
45
- const fill = (template, values) => template.replace(/\{(\w+)\}/g, (match, name) => name in values ? String(values[name]) : match);
46
- const status = templates.status || templates.statusSingle;
47
- return {
48
- ...templates.page && { page: (n, count) => fill(templates.page, { n, count }) },
49
- ...status && {
50
- status: (first, last, count) => fill(first == last && templates.statusSingle ? templates.statusSingle : status, { first, last, count })
51
- }
52
- };
53
- }
54
-
55
- export {
56
- baseVars,
57
- baseStyle,
58
- responsiveCss,
59
- PRE_POSITION,
60
- templateLabels
61
- };