@squirkle-ui/swiper 0.0.0-stage → 0.1.1
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.
- package/LICENSE +21 -0
- package/README.md +35 -2
- package/dist/styles.css +47 -0
- package/dist/types/SqSwiper.vue.d.ts +503 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/vue2/index.cjs +230 -0
- package/dist/vue2/index.cjs.map +1 -0
- package/dist/vue2/index.mjs +230 -0
- package/dist/vue2/index.mjs.map +1 -0
- package/dist/vue3/index.cjs +319 -0
- package/dist/vue3/index.cjs.map +1 -0
- package/dist/vue3/index.mjs +319 -0
- package/dist/vue3/index.mjs.map +1 -0
- package/dist/vue3/styles.css +47 -0
- package/package.json +60 -3
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const vue = require("vue");
|
|
4
|
+
const core = require("@squirkle-ui/core");
|
|
5
|
+
const ui = require("@squirkle-ui/ui");
|
|
6
|
+
const _sfc_main = vue.defineComponent({
|
|
7
|
+
name: "SqSwiper",
|
|
8
|
+
components: { SqBtn: ui.SqBtn, SqShape: ui.SqShape },
|
|
9
|
+
model: ui.vModel,
|
|
10
|
+
props: {
|
|
11
|
+
modelValue: { type: Number, default: 0 },
|
|
12
|
+
items: { type: Array, default: () => [] },
|
|
13
|
+
itemKey: { type: String, default: void 0 },
|
|
14
|
+
slidesPerView: { type: Number, default: 1 },
|
|
15
|
+
spaceBetween: { type: Number, default: 16 },
|
|
16
|
+
/** { 640: { slidesPerView: 2 }, 1024: { slidesPerView: 3 } } — keys are min container widths. */
|
|
17
|
+
breakpoints: { type: Object, default: void 0 },
|
|
18
|
+
effect: { type: String, default: "slide" },
|
|
19
|
+
loop: Boolean,
|
|
20
|
+
centered: Boolean,
|
|
21
|
+
vertical: Boolean,
|
|
22
|
+
/** Autoplay delay in ms; 0 disables. */
|
|
23
|
+
autoplay: { type: Number, default: 0 },
|
|
24
|
+
pauseOnHover: { type: Boolean, default: true },
|
|
25
|
+
speed: { type: Number, default: 420 },
|
|
26
|
+
navigation: { type: Boolean, default: true },
|
|
27
|
+
pagination: { type: [String, Boolean], default: "dots" },
|
|
28
|
+
height: { type: [Number, String], default: 320 },
|
|
29
|
+
rounded: { type: [String, Number], default: "xl" },
|
|
30
|
+
label: { type: String, default: "Carousel" }
|
|
31
|
+
},
|
|
32
|
+
emits: ["update:modelValue", "change"],
|
|
33
|
+
setup(props, { emit }) {
|
|
34
|
+
const model = ui.useProxiedModel(props, emit);
|
|
35
|
+
const root = vue.ref(null);
|
|
36
|
+
const size = vue.ref(800);
|
|
37
|
+
const drag = vue.ref(0);
|
|
38
|
+
const dragging = vue.ref(false);
|
|
39
|
+
const hovering = vue.ref(false);
|
|
40
|
+
const jumping = vue.ref(/* @__PURE__ */ new Set());
|
|
41
|
+
const list = vue.computed(() => props.items);
|
|
42
|
+
const n = vue.computed(() => list.value.length);
|
|
43
|
+
const keyOf = (item, i) => props.itemKey ? core.getByPath(item, props.itemKey) : i;
|
|
44
|
+
const responsive = vue.computed(() => {
|
|
45
|
+
let r = { slidesPerView: props.slidesPerView, spaceBetween: props.spaceBetween };
|
|
46
|
+
if (props.breakpoints) {
|
|
47
|
+
for (const bp of Object.keys(props.breakpoints).map(Number).sort((a, b) => a - b)) if (size.value >= bp) r = { ...r, ...props.breakpoints[bp] };
|
|
48
|
+
}
|
|
49
|
+
if (props.effect !== "slide") r = { ...r, slidesPerView: 1 };
|
|
50
|
+
return r;
|
|
51
|
+
});
|
|
52
|
+
const spv = vue.computed(() => Math.max(1, Math.min(responsive.value.slidesPerView, n.value || 1)));
|
|
53
|
+
const slideSize = vue.computed(() => (size.value - responsive.value.spaceBetween * (spv.value - 1)) / spv.value);
|
|
54
|
+
const step = vue.computed(() => slideSize.value + responsive.value.spaceBetween);
|
|
55
|
+
const maxIndex = vue.computed(() => props.loop || props.centered ? n.value - 1 : Math.max(0, n.value - spv.value));
|
|
56
|
+
const normIndex = vue.computed(() => n.value ? (model.value % n.value + n.value) % n.value : 0);
|
|
57
|
+
const pageCount = vue.computed(() => props.loop || props.centered ? n.value : maxIndex.value + 1);
|
|
58
|
+
const canPrev = vue.computed(() => props.loop || normIndex.value > 0);
|
|
59
|
+
const canNext = vue.computed(() => props.loop || normIndex.value < maxIndex.value);
|
|
60
|
+
const offsetOf = (i) => {
|
|
61
|
+
let o = i - normIndex.value;
|
|
62
|
+
if (props.loop && n.value > 1) {
|
|
63
|
+
const half = n.value / 2;
|
|
64
|
+
o = ((o + half) % n.value + n.value) % n.value - half;
|
|
65
|
+
}
|
|
66
|
+
return o;
|
|
67
|
+
};
|
|
68
|
+
const prevOffsets = /* @__PURE__ */ new Map();
|
|
69
|
+
vue.watch(normIndex, () => {
|
|
70
|
+
const jumps = /* @__PURE__ */ new Set();
|
|
71
|
+
for (let i = 0; i < n.value; i++) {
|
|
72
|
+
const o = offsetOf(i);
|
|
73
|
+
const was = prevOffsets.get(i);
|
|
74
|
+
if (was != null && Math.abs(o - was) > 1.5) jumps.add(i);
|
|
75
|
+
prevOffsets.set(i, o);
|
|
76
|
+
}
|
|
77
|
+
jumping.value = jumps;
|
|
78
|
+
requestAnimationFrame(() => requestAnimationFrame(() => jumping.value = /* @__PURE__ */ new Set()));
|
|
79
|
+
emit("change", normIndex.value);
|
|
80
|
+
});
|
|
81
|
+
const isVisible = (i) => {
|
|
82
|
+
const o = offsetOf(i);
|
|
83
|
+
return props.centered ? Math.abs(o) <= spv.value / 2 : o >= 0 && o < spv.value;
|
|
84
|
+
};
|
|
85
|
+
const slideStyle = (i) => {
|
|
86
|
+
const o = offsetOf(i);
|
|
87
|
+
const dragFrac = drag.value / step.value;
|
|
88
|
+
const pos = o + dragFrac;
|
|
89
|
+
const center = props.centered ? (size.value - slideSize.value) / 2 : 0;
|
|
90
|
+
const axis = props.vertical ? "Y" : "X";
|
|
91
|
+
const s = { [props.vertical ? "height" : "width"]: `${slideSize.value}px`, transitionDuration: dragging.value ? "0ms" : `${props.speed}ms` };
|
|
92
|
+
if (props.effect === "fade") {
|
|
93
|
+
s.opacity = String(Math.max(0, 1 - Math.abs(pos)));
|
|
94
|
+
s.zIndex = String(o === 0 ? 2 : 1);
|
|
95
|
+
} else if (props.effect === "coverflow") {
|
|
96
|
+
const x = (size.value - slideSize.value) / 2 + pos * slideSize.value * 0.62;
|
|
97
|
+
s.transform = `translate${axis}(${x}px) perspective(900px) rotateY(${Math.max(-1, Math.min(1, pos)) * -42}deg) scale(${1 - Math.min(1, Math.abs(pos)) * 0.18})`;
|
|
98
|
+
s.zIndex = String(100 - Math.round(Math.abs(pos) * 10));
|
|
99
|
+
s.opacity = Math.abs(pos) > 2.5 ? "0" : "1";
|
|
100
|
+
} else if (props.effect === "cards") {
|
|
101
|
+
const p = Math.max(-1, pos);
|
|
102
|
+
s.transform = p < 0 ? `translateX(${p * size.value}px) rotate(${p * 8}deg)` : `translateY(${Math.min(p, 3) * 14}px) scale(${1 - Math.min(p, 3) * 0.06})`;
|
|
103
|
+
s.zIndex = String(100 - Math.round(Math.abs(pos) * 10));
|
|
104
|
+
s.opacity = pos > 3 ? "0" : "1";
|
|
105
|
+
} else s.transform = `translate${axis}(${center + pos * step.value}px)`;
|
|
106
|
+
return s;
|
|
107
|
+
};
|
|
108
|
+
const goTo = (i) => {
|
|
109
|
+
if (!n.value) return;
|
|
110
|
+
if (props.loop) {
|
|
111
|
+
const target = (i % n.value + n.value) % n.value;
|
|
112
|
+
model.value = model.value + offsetOfTarget(target);
|
|
113
|
+
} else model.value = Math.max(0, Math.min(maxIndex.value, i));
|
|
114
|
+
};
|
|
115
|
+
const offsetOfTarget = (target) => {
|
|
116
|
+
let d = target - normIndex.value;
|
|
117
|
+
const half = n.value / 2;
|
|
118
|
+
d = ((d + half) % n.value + n.value) % n.value - half;
|
|
119
|
+
return d;
|
|
120
|
+
};
|
|
121
|
+
const next = () => canNext.value ? props.loop ? model.value = model.value + 1 : goTo(normIndex.value + 1) : props.autoplay && goTo(0);
|
|
122
|
+
const prev = () => canPrev.value && (props.loop ? model.value = model.value - 1 : goTo(normIndex.value - 1));
|
|
123
|
+
let start = 0;
|
|
124
|
+
let startT = 0;
|
|
125
|
+
const onMove = (e) => {
|
|
126
|
+
const d = (props.vertical ? e.clientY : e.clientX) - start;
|
|
127
|
+
const edge = !props.loop && (normIndex.value === 0 && d > 0 || normIndex.value >= maxIndex.value && d < 0);
|
|
128
|
+
drag.value = edge ? d * 0.3 : d;
|
|
129
|
+
};
|
|
130
|
+
const onUp = () => {
|
|
131
|
+
window.removeEventListener("pointermove", onMove);
|
|
132
|
+
window.removeEventListener("pointerup", onUp);
|
|
133
|
+
const d = drag.value;
|
|
134
|
+
const fast = Math.abs(d) > 30 && Date.now() - startT < 250;
|
|
135
|
+
const steps = Math.round(-d / step.value) || (fast ? -Math.sign(d) : 0);
|
|
136
|
+
dragging.value = false;
|
|
137
|
+
drag.value = 0;
|
|
138
|
+
if (steps) props.loop ? model.value = model.value + steps : goTo(normIndex.value + steps);
|
|
139
|
+
};
|
|
140
|
+
const onDown = (e) => {
|
|
141
|
+
if (e.button !== 0 || e.target.closest("button, a, input")) return;
|
|
142
|
+
start = props.vertical ? e.clientY : e.clientX;
|
|
143
|
+
startT = Date.now();
|
|
144
|
+
dragging.value = true;
|
|
145
|
+
window.addEventListener("pointermove", onMove);
|
|
146
|
+
window.addEventListener("pointerup", onUp);
|
|
147
|
+
};
|
|
148
|
+
let timer;
|
|
149
|
+
const restart = () => {
|
|
150
|
+
clearInterval(timer);
|
|
151
|
+
if (props.autoplay > 0) timer = setInterval(() => !(props.pauseOnHover && hovering.value) && !dragging.value && !document.hidden && next(), props.autoplay);
|
|
152
|
+
};
|
|
153
|
+
vue.watch(() => props.autoplay, restart);
|
|
154
|
+
let ro;
|
|
155
|
+
vue.onMounted(() => {
|
|
156
|
+
const measure = () => root.value && (size.value = props.vertical ? root.value.clientHeight : root.value.clientWidth);
|
|
157
|
+
measure();
|
|
158
|
+
if (typeof ResizeObserver !== "undefined" && root.value) {
|
|
159
|
+
ro = new ResizeObserver(measure);
|
|
160
|
+
ro.observe(root.value);
|
|
161
|
+
}
|
|
162
|
+
for (let i = 0; i < n.value; i++) prevOffsets.set(i, offsetOf(i));
|
|
163
|
+
restart();
|
|
164
|
+
});
|
|
165
|
+
vue.onBeforeUnmount(() => {
|
|
166
|
+
clearInterval(timer);
|
|
167
|
+
ro?.disconnect();
|
|
168
|
+
onUp();
|
|
169
|
+
});
|
|
170
|
+
const rootStyle = vue.computed(() => ({ height: typeof props.height === "number" ? `${props.height}px` : props.height, "--sq-r": ui.radiusValue(props.rounded), "--sq-bg": "var(--sq-surface-variant)" }));
|
|
171
|
+
return { root, list, keyOf, normIndex, pageCount, canPrev, canNext, slideStyle, isVisible, goTo, next, prev, onDown, dragging, hovering, jumping, rootStyle };
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
const _export_sfc = (sfc, props) => {
|
|
175
|
+
const target = sfc.__vccOpts || sfc;
|
|
176
|
+
for (const [key, val] of props) {
|
|
177
|
+
target[key] = val;
|
|
178
|
+
}
|
|
179
|
+
return target;
|
|
180
|
+
};
|
|
181
|
+
const _hoisted_1 = ["aria-label"];
|
|
182
|
+
const _hoisted_2 = ["aria-label", "aria-hidden"];
|
|
183
|
+
const _hoisted_3 = {
|
|
184
|
+
key: 1,
|
|
185
|
+
class: "sq-swiper__dots"
|
|
186
|
+
};
|
|
187
|
+
const _hoisted_4 = ["aria-label", "onClick"];
|
|
188
|
+
const _hoisted_5 = {
|
|
189
|
+
key: 2,
|
|
190
|
+
class: "sq-swiper__fraction"
|
|
191
|
+
};
|
|
192
|
+
const _hoisted_6 = {
|
|
193
|
+
key: 3,
|
|
194
|
+
class: "sq-swiper__progress"
|
|
195
|
+
};
|
|
196
|
+
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
197
|
+
const _component_SqShape = vue.resolveComponent("SqShape");
|
|
198
|
+
const _component_SqBtn = vue.resolveComponent("SqBtn");
|
|
199
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
200
|
+
ref: "root",
|
|
201
|
+
class: vue.normalizeClass(["sq-swiper sq-surface", [`sq-swiper--${_ctx.effect}`, { "sq-swiper--dragging": _ctx.dragging, "sq-swiper--vertical": _ctx.vertical }]]),
|
|
202
|
+
style: vue.normalizeStyle(_ctx.rootStyle),
|
|
203
|
+
role: "region",
|
|
204
|
+
"aria-roledescription": "carousel",
|
|
205
|
+
"aria-label": _ctx.label,
|
|
206
|
+
tabindex: "0",
|
|
207
|
+
onKeydown: [
|
|
208
|
+
_cache[1] || (_cache[1] = vue.withKeys(vue.withModifiers(($event) => !_ctx.vertical && _ctx.prev(), ["prevent"]), ["left"])),
|
|
209
|
+
_cache[2] || (_cache[2] = vue.withKeys(vue.withModifiers(($event) => !_ctx.vertical && _ctx.next(), ["prevent"]), ["right"])),
|
|
210
|
+
_cache[3] || (_cache[3] = vue.withKeys(vue.withModifiers(($event) => _ctx.vertical && _ctx.prev(), ["prevent"]), ["up"])),
|
|
211
|
+
_cache[4] || (_cache[4] = vue.withKeys(vue.withModifiers(($event) => _ctx.vertical && _ctx.next(), ["prevent"]), ["down"]))
|
|
212
|
+
],
|
|
213
|
+
onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.hovering = true),
|
|
214
|
+
onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.hovering = false)
|
|
215
|
+
}, [
|
|
216
|
+
vue.createVNode(_component_SqShape, { clip: "" }),
|
|
217
|
+
vue.createElementVNode(
|
|
218
|
+
"div",
|
|
219
|
+
{
|
|
220
|
+
class: "sq-swiper__track",
|
|
221
|
+
onPointerdown: _cache[0] || (_cache[0] = (...args) => _ctx.onDown && _ctx.onDown(...args))
|
|
222
|
+
},
|
|
223
|
+
[
|
|
224
|
+
(vue.openBlock(true), vue.createElementBlock(
|
|
225
|
+
vue.Fragment,
|
|
226
|
+
null,
|
|
227
|
+
vue.renderList(_ctx.list, (item, i) => {
|
|
228
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
229
|
+
key: _ctx.keyOf(item, i),
|
|
230
|
+
class: vue.normalizeClass(["sq-swiper__slide", { "sq-swiper__slide--active": i === _ctx.normIndex, "sq-swiper__slide--jump": _ctx.jumping.has(i) }]),
|
|
231
|
+
style: vue.normalizeStyle(_ctx.slideStyle(i)),
|
|
232
|
+
role: "group",
|
|
233
|
+
"aria-roledescription": "slide",
|
|
234
|
+
"aria-label": `${i + 1} / ${_ctx.list.length}`,
|
|
235
|
+
"aria-hidden": _ctx.isVisible(i) ? void 0 : "true"
|
|
236
|
+
}, [
|
|
237
|
+
vue.renderSlot(_ctx.$slots, "default", {
|
|
238
|
+
item,
|
|
239
|
+
index: i,
|
|
240
|
+
active: i === _ctx.normIndex
|
|
241
|
+
})
|
|
242
|
+
], 14, _hoisted_2);
|
|
243
|
+
}),
|
|
244
|
+
128
|
|
245
|
+
/* KEYED_FRAGMENT */
|
|
246
|
+
))
|
|
247
|
+
],
|
|
248
|
+
32
|
|
249
|
+
/* NEED_HYDRATION */
|
|
250
|
+
),
|
|
251
|
+
_ctx.navigation && _ctx.list.length > 1 ? (vue.openBlock(), vue.createElementBlock(
|
|
252
|
+
vue.Fragment,
|
|
253
|
+
{ key: 0 },
|
|
254
|
+
[
|
|
255
|
+
vue.createVNode(_component_SqBtn, {
|
|
256
|
+
class: "sq-swiper__nav sq-swiper__nav--prev",
|
|
257
|
+
icon: _ctx.vertical ? "chevronUp" : "chevronLeft",
|
|
258
|
+
color: "surface",
|
|
259
|
+
variant: "elevated",
|
|
260
|
+
size: "small",
|
|
261
|
+
disabled: !_ctx.canPrev,
|
|
262
|
+
"aria-label": "Previous slide",
|
|
263
|
+
onClick: _ctx.prev
|
|
264
|
+
}, null, 8, ["icon", "disabled", "onClick"]),
|
|
265
|
+
vue.createVNode(_component_SqBtn, {
|
|
266
|
+
class: "sq-swiper__nav sq-swiper__nav--next",
|
|
267
|
+
icon: _ctx.vertical ? "chevronDown" : "chevronRight",
|
|
268
|
+
color: "surface",
|
|
269
|
+
variant: "elevated",
|
|
270
|
+
size: "small",
|
|
271
|
+
disabled: !_ctx.canNext,
|
|
272
|
+
"aria-label": "Next slide",
|
|
273
|
+
onClick: _ctx.next
|
|
274
|
+
}, null, 8, ["icon", "disabled", "onClick"])
|
|
275
|
+
],
|
|
276
|
+
64
|
|
277
|
+
/* STABLE_FRAGMENT */
|
|
278
|
+
)) : vue.createCommentVNode("v-if", true),
|
|
279
|
+
_ctx.pagination === "dots" && _ctx.pageCount > 1 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3, [
|
|
280
|
+
(vue.openBlock(true), vue.createElementBlock(
|
|
281
|
+
vue.Fragment,
|
|
282
|
+
null,
|
|
283
|
+
vue.renderList(_ctx.pageCount, (p) => {
|
|
284
|
+
return vue.openBlock(), vue.createElementBlock("button", {
|
|
285
|
+
key: p,
|
|
286
|
+
type: "button",
|
|
287
|
+
class: vue.normalizeClass(["sq-swiper__dot", { "sq-swiper__dot--active": p - 1 === _ctx.normIndex }]),
|
|
288
|
+
"aria-label": `Go to slide ${p}`,
|
|
289
|
+
onClick: ($event) => _ctx.goTo(p - 1)
|
|
290
|
+
}, null, 10, _hoisted_4);
|
|
291
|
+
}),
|
|
292
|
+
128
|
|
293
|
+
/* KEYED_FRAGMENT */
|
|
294
|
+
))
|
|
295
|
+
])) : _ctx.pagination === "fraction" ? (vue.openBlock(), vue.createElementBlock(
|
|
296
|
+
"div",
|
|
297
|
+
_hoisted_5,
|
|
298
|
+
vue.toDisplayString(_ctx.normIndex + 1) + " / " + vue.toDisplayString(_ctx.list.length),
|
|
299
|
+
1
|
|
300
|
+
/* TEXT */
|
|
301
|
+
)) : _ctx.pagination === "progress" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6, [
|
|
302
|
+
vue.createElementVNode(
|
|
303
|
+
"div",
|
|
304
|
+
{
|
|
305
|
+
style: vue.normalizeStyle({ width: (_ctx.normIndex + 1) / Math.max(1, _ctx.list.length) * 100 + "%" })
|
|
306
|
+
},
|
|
307
|
+
null,
|
|
308
|
+
4
|
|
309
|
+
/* STYLE */
|
|
310
|
+
)
|
|
311
|
+
])) : vue.createCommentVNode("v-if", true)
|
|
312
|
+
], 46, _hoisted_1);
|
|
313
|
+
}
|
|
314
|
+
const SqSwiper = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
|
|
315
|
+
const componentNames = ["SqSwiper"];
|
|
316
|
+
exports.SqSwiper = SqSwiper;
|
|
317
|
+
exports.componentNames = componentNames;
|
|
318
|
+
exports.default = SqSwiper;
|
|
319
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/SqSwiper.vue","../../src/index.ts"],"sourcesContent":["<template>\n <div\n ref=\"root\"\n class=\"sq-swiper sq-surface\"\n :class=\"[`sq-swiper--${effect}`, { 'sq-swiper--dragging': dragging, 'sq-swiper--vertical': vertical }]\"\n :style=\"rootStyle\"\n role=\"region\"\n aria-roledescription=\"carousel\"\n :aria-label=\"label\"\n tabindex=\"0\"\n @keydown.left.prevent=\"!vertical && prev()\"\n @keydown.right.prevent=\"!vertical && next()\"\n @keydown.up.prevent=\"vertical && prev()\"\n @keydown.down.prevent=\"vertical && next()\"\n @mouseenter=\"hovering = true\"\n @mouseleave=\"hovering = false\"\n >\n <SqShape clip />\n <div class=\"sq-swiper__track\" @pointerdown=\"onDown\">\n <div\n v-for=\"(item, i) in list\"\n :key=\"keyOf(item, i)\"\n class=\"sq-swiper__slide\"\n :class=\"{ 'sq-swiper__slide--active': i === normIndex, 'sq-swiper__slide--jump': jumping.has(i) }\"\n :style=\"slideStyle(i)\"\n role=\"group\"\n aria-roledescription=\"slide\"\n :aria-label=\"`${i + 1} / ${list.length}`\"\n :aria-hidden=\"isVisible(i) ? undefined : 'true'\"\n >\n <slot :item=\"item\" :index=\"i\" :active=\"i === normIndex\" />\n </div>\n </div>\n <template v-if=\"navigation && list.length > 1\">\n <SqBtn class=\"sq-swiper__nav sq-swiper__nav--prev\" :icon=\"vertical ? 'chevronUp' : 'chevronLeft'\" color=\"surface\" variant=\"elevated\" size=\"small\" :disabled=\"!canPrev\" aria-label=\"Previous slide\" @click=\"prev\" />\n <SqBtn class=\"sq-swiper__nav sq-swiper__nav--next\" :icon=\"vertical ? 'chevronDown' : 'chevronRight'\" color=\"surface\" variant=\"elevated\" size=\"small\" :disabled=\"!canNext\" aria-label=\"Next slide\" @click=\"next\" />\n </template>\n <div v-if=\"pagination === 'dots' && pageCount > 1\" class=\"sq-swiper__dots\">\n <button v-for=\"p in pageCount\" :key=\"p\" type=\"button\" class=\"sq-swiper__dot\" :class=\"{ 'sq-swiper__dot--active': p - 1 === normIndex }\" :aria-label=\"`Go to slide ${p}`\" @click=\"goTo(p - 1)\"></button>\n </div>\n <div v-else-if=\"pagination === 'fraction'\" class=\"sq-swiper__fraction\">{{ normIndex + 1 }} / {{ list.length }}</div>\n <div v-else-if=\"pagination === 'progress'\" class=\"sq-swiper__progress\"><div :style=\"{ width: ((normIndex + 1) / Math.max(1, list.length)) * 100 + '%' }\"></div></div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { computed, defineComponent, onBeforeUnmount, onMounted, ref, watch, type PropType } from 'vue'\nimport { getByPath } from '@squirkle-ui/core'\nimport { SqBtn, SqShape, radiusValue, useProxiedModel, vModel } from '@squirkle-ui/ui'\n\ntype Effect = 'slide' | 'fade' | 'coverflow' | 'cards'\ninterface Responsive { slidesPerView?: number; spaceBetween?: number }\n\n/**\n * Touch/mouse swiper. `loop` is a real infinite loop without cloned slides: every slide is positioned\n * at its wrapped offset from the active index, and slides that wrap around jump without animating.\n */\nexport default defineComponent({\n name: 'SqSwiper',\n components: { SqBtn, SqShape },\n model: vModel,\n props: {\n modelValue: { type: Number, default: 0 },\n items: { type: Array as PropType<unknown[]>, default: () => [] },\n itemKey: { type: String, default: undefined },\n slidesPerView: { type: Number, default: 1 },\n spaceBetween: { type: Number, default: 16 },\n /** { 640: { slidesPerView: 2 }, 1024: { slidesPerView: 3 } } — keys are min container widths. */\n breakpoints: { type: Object as PropType<Record<number, Responsive>>, default: undefined },\n effect: { type: String as PropType<Effect>, default: 'slide' },\n loop: Boolean,\n centered: Boolean,\n vertical: Boolean,\n /** Autoplay delay in ms; 0 disables. */\n autoplay: { type: Number, default: 0 },\n pauseOnHover: { type: Boolean, default: true },\n speed: { type: Number, default: 420 },\n navigation: { type: Boolean, default: true },\n pagination: { type: [String, Boolean] as PropType<'dots' | 'fraction' | 'progress' | false>, default: 'dots' },\n height: { type: [Number, String], default: 320 },\n rounded: { type: [String, Number], default: 'xl' },\n label: { type: String, default: 'Carousel' },\n },\n emits: ['update:modelValue', 'change'],\n setup(props, { emit }) {\n const model = useProxiedModel<number>(props, emit)\n const root = ref<HTMLElement | null>(null)\n const size = ref(800)\n const drag = ref(0)\n const dragging = ref(false)\n const hovering = ref(false)\n const jumping = ref(new Set<number>())\n const list = computed(() => props.items)\n const n = computed(() => list.value.length)\n const keyOf = (item: unknown, i: number) => (props.itemKey ? (getByPath(item, props.itemKey) as string) : i)\n\n const responsive = computed<Required<Responsive>>(() => {\n let r: Required<Responsive> = { slidesPerView: props.slidesPerView, spaceBetween: props.spaceBetween }\n if (props.breakpoints) for (const bp of Object.keys(props.breakpoints).map(Number).sort((a, b) => a - b)) if (size.value >= bp) r = { ...r, ...props.breakpoints[bp] }\n if (props.effect !== 'slide') r = { ...r, slidesPerView: 1 }\n return r\n })\n const spv = computed(() => Math.max(1, Math.min(responsive.value.slidesPerView, n.value || 1)))\n const slideSize = computed(() => (size.value - responsive.value.spaceBetween * (spv.value - 1)) / spv.value)\n const step = computed(() => slideSize.value + responsive.value.spaceBetween)\n const maxIndex = computed(() => (props.loop || props.centered ? n.value - 1 : Math.max(0, n.value - spv.value)))\n const normIndex = computed(() => (n.value ? ((model.value % n.value) + n.value) % n.value : 0))\n const pageCount = computed(() => (props.loop || props.centered ? n.value : maxIndex.value + 1))\n const canPrev = computed(() => props.loop || normIndex.value > 0)\n const canNext = computed(() => props.loop || normIndex.value < maxIndex.value)\n\n const offsetOf = (i: number) => {\n let o = i - normIndex.value\n if (props.loop && n.value > 1) {\n const half = n.value / 2\n o = ((((o + half) % n.value) + n.value) % n.value) - half\n }\n return o\n }\n const prevOffsets = new Map<number, number>()\n watch(normIndex, () => {\n const jumps = new Set<number>()\n for (let i = 0; i < n.value; i++) {\n const o = offsetOf(i)\n const was = prevOffsets.get(i)\n if (was != null && Math.abs(o - was) > 1.5) jumps.add(i)\n prevOffsets.set(i, o)\n }\n jumping.value = jumps\n requestAnimationFrame(() => requestAnimationFrame(() => (jumping.value = new Set())))\n emit('change', normIndex.value)\n })\n\n const isVisible = (i: number) => {\n const o = offsetOf(i)\n return props.centered ? Math.abs(o) <= spv.value / 2 : o >= 0 && o < spv.value\n }\n const slideStyle = (i: number) => {\n const o = offsetOf(i)\n const dragFrac = drag.value / step.value\n const pos = o + dragFrac\n const center = props.centered ? (size.value - slideSize.value) / 2 : 0\n const axis = props.vertical ? 'Y' : 'X'\n const s: Record<string, string> = { [props.vertical ? 'height' : 'width']: `${slideSize.value}px`, transitionDuration: dragging.value ? '0ms' : `${props.speed}ms` }\n if (props.effect === 'fade') {\n s.opacity = String(Math.max(0, 1 - Math.abs(pos)))\n s.zIndex = String(o === 0 ? 2 : 1)\n } else if (props.effect === 'coverflow') {\n const x = (size.value - slideSize.value) / 2 + pos * slideSize.value * 0.62\n s.transform = `translate${axis}(${x}px) perspective(900px) rotateY(${Math.max(-1, Math.min(1, pos)) * -42}deg) scale(${1 - Math.min(1, Math.abs(pos)) * 0.18})`\n s.zIndex = String(100 - Math.round(Math.abs(pos) * 10))\n s.opacity = Math.abs(pos) > 2.5 ? '0' : '1'\n } else if (props.effect === 'cards') {\n const p = Math.max(-1, pos)\n s.transform = p < 0 ? `translateX(${p * size.value}px) rotate(${p * 8}deg)` : `translateY(${Math.min(p, 3) * 14}px) scale(${1 - Math.min(p, 3) * 0.06})`\n s.zIndex = String(100 - Math.round(Math.abs(pos) * 10))\n s.opacity = pos > 3 ? '0' : '1'\n } else s.transform = `translate${axis}(${center + pos * step.value}px)`\n return s\n }\n\n const goTo = (i: number) => {\n if (!n.value) return\n if (props.loop) {\n const target = ((i % n.value) + n.value) % n.value\n model.value = model.value + offsetOfTarget(target)\n } else model.value = Math.max(0, Math.min(maxIndex.value, i))\n }\n const offsetOfTarget = (target: number) => {\n let d = target - normIndex.value\n const half = n.value / 2\n d = ((((d + half) % n.value) + n.value) % n.value) - half\n return d\n }\n const next = () => (canNext.value ? (props.loop ? (model.value = model.value + 1) : goTo(normIndex.value + 1)) : props.autoplay && goTo(0))\n const prev = () => canPrev.value && (props.loop ? (model.value = model.value - 1) : goTo(normIndex.value - 1))\n\n // drag\n let start = 0\n let startT = 0\n const onMove = (e: PointerEvent) => {\n const d = (props.vertical ? e.clientY : e.clientX) - start\n const edge = !props.loop && ((normIndex.value === 0 && d > 0) || (normIndex.value >= maxIndex.value && d < 0))\n drag.value = edge ? d * 0.3 : d\n }\n const onUp = () => {\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', onUp)\n const d = drag.value\n const fast = Math.abs(d) > 30 && Date.now() - startT < 250\n const steps = Math.round(-d / step.value) || (fast ? -Math.sign(d) : 0)\n dragging.value = false\n drag.value = 0\n if (steps) props.loop ? (model.value = model.value + steps) : goTo(normIndex.value + steps)\n }\n const onDown = (e: PointerEvent) => {\n if (e.button !== 0 || (e.target as HTMLElement).closest('button, a, input')) return\n start = props.vertical ? e.clientY : e.clientX\n startT = Date.now()\n dragging.value = true\n window.addEventListener('pointermove', onMove)\n window.addEventListener('pointerup', onUp)\n }\n\n // autoplay\n let timer: ReturnType<typeof setInterval> | undefined\n const restart = () => {\n clearInterval(timer)\n if (props.autoplay > 0) timer = setInterval(() => !(props.pauseOnHover && hovering.value) && !dragging.value && !document.hidden && next(), props.autoplay)\n }\n watch(() => props.autoplay, restart)\n\n let ro: ResizeObserver | undefined\n onMounted(() => {\n const measure = () => root.value && (size.value = props.vertical ? root.value.clientHeight : root.value.clientWidth)\n measure()\n if (typeof ResizeObserver !== 'undefined' && root.value) { ro = new ResizeObserver(measure); ro.observe(root.value) }\n for (let i = 0; i < n.value; i++) prevOffsets.set(i, offsetOf(i))\n restart()\n })\n onBeforeUnmount(() => { clearInterval(timer); ro?.disconnect(); onUp() })\n\n const rootStyle = computed(() => ({ height: typeof props.height === 'number' ? `${props.height}px` : props.height, '--sq-r': radiusValue(props.rounded as string), '--sq-bg': 'var(--sq-surface-variant)' }))\n return { root, list, keyOf, normIndex, pageCount, canPrev, canNext, slideStyle, isVisible, goTo, next, prev, onDown, dragging, hovering, jumping, rootStyle }\n },\n})\n</script>\n\n<style>\n.sq-swiper { position: relative; overflow: hidden; outline: none; touch-action: pan-y; user-select: none; }\n.sq-swiper--vertical { touch-action: pan-x; }\n.sq-swiper:focus-visible { box-shadow: var(--sq-focus-ring); }\n.sq-swiper__track { position: relative; width: 100%; height: 100%; cursor: grab; }\n.sq-swiper--dragging .sq-swiper__track { cursor: grabbing; }\n.sq-swiper__slide { position: absolute; top: 0; left: 0; height: 100%; transition-property: transform, opacity; transition-timing-function: var(--sq-ease); will-change: transform; }\n.sq-swiper--vertical .sq-swiper__slide { width: 100%; height: auto; }\n.sq-swiper__slide--jump { transition: none !important; }\n.sq-swiper__slide > * { width: 100%; height: 100%; }\n.sq-swiper--fade .sq-swiper__slide, .sq-swiper--cards .sq-swiper__slide { width: 100% !important; }\n.sq-swiper--cards { overflow: visible; --sq-bg: transparent; }\n.sq-swiper__nav { position: absolute; top: 50%; z-index: 120; transform: translateY(-50%); }\n.sq-swiper__nav--prev { left: var(--sq-space-3); }\n.sq-swiper__nav--next { right: var(--sq-space-3); }\n.sq-swiper--vertical .sq-swiper__nav { left: 50%; top: auto; transform: translateX(-50%); }\n.sq-swiper--vertical .sq-swiper__nav--prev { top: var(--sq-space-3); }\n.sq-swiper--vertical .sq-swiper__nav--next { bottom: var(--sq-space-3); }\n.sq-swiper__dots { position: absolute; z-index: 120; left: 50%; bottom: var(--sq-space-3); transform: translateX(-50%); display: flex; gap: 6px; padding: 6px 8px; border-radius: var(--sq-radius-pill); background: color-mix(in srgb, var(--sq-overlay) 28%, transparent); backdrop-filter: blur(8px); }\n.sq-swiper__dot { width: 7px; height: 7px; padding: 0; border: 0; border-radius: var(--sq-radius-pill); background: rgb(255 255 255 / 0.55); cursor: pointer; transition: width var(--sq-duration) var(--sq-ease), background var(--sq-duration); }\n.sq-swiper__dot--active { width: 22px; background: #fff; }\n.sq-swiper__fraction { position: absolute; z-index: 120; right: var(--sq-space-3); bottom: var(--sq-space-3); padding: 2px 10px; border-radius: var(--sq-radius-pill); background: color-mix(in srgb, var(--sq-overlay) 45%, transparent); color: #fff; font-size: var(--sq-text-xs); font-weight: var(--sq-weight-semibold); }\n.sq-swiper__progress { position: absolute; z-index: 120; left: 0; right: 0; bottom: 0; height: 4px; background: color-mix(in srgb, var(--sq-overlay) 20%, transparent); }\n.sq-swiper__progress > div { height: 100%; background: var(--sq-primary); transition: width var(--sq-duration-slow) var(--sq-ease); }\n</style>\n","import SqSwiper from './SqSwiper.vue'\n\nexport { SqSwiper }\nexport const componentNames = ['SqSwiper'] as const\nexport default SqSwiper\n"],"names":["defineComponent","SqBtn","SqShape","vModel","useProxiedModel","ref","computed","getByPath","watch","onMounted","onBeforeUnmount","radiusValue","_createElementBlock","_normalizeClass","_normalizeStyle","_withKeys","_withModifiers","_createVNode","_createElementVNode","_openBlock","_Fragment","_renderList","_renderSlot","_toDisplayString"],"mappings":"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"}
|