@max-ts/svelte 1.8.3 → 1.8.4
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/dist/assets/src/components/Carousel/Content/styles.css.ts.vanilla-WeFKZGhD.css +27 -0
- package/dist/assets/src/components/Carousel/Item/{styles.css.ts.vanilla-DM_PUW76.css → styles.css.ts.vanilla-DH1QYb6c.css} +4 -2
- package/dist/components/Carousel/Arrows/Arrows.js +11 -12
- package/dist/components/Carousel/Carousel.js +16 -55
- package/dist/components/Carousel/Carousel.svelte.d.ts +1 -1
- package/dist/components/Carousel/Content/Content.js +18 -24
- package/dist/components/Carousel/Content/styles.css.d.ts +1 -2
- package/dist/components/Carousel/Content/styles.css.js +4 -5
- package/dist/components/Carousel/Dots/Dots.js +6 -6
- package/dist/components/Carousel/Item/Item.js +4 -4
- package/dist/components/Carousel/Item/styles.css.js +1 -2
- package/dist/components/Carousel/context.d.ts +3 -3
- package/dist/components/Carousel/context.js +7 -7
- package/dist/components/Carousel/store.svelte.d.ts +20 -0
- package/dist/components/Carousel/store.svelte.js +158 -0
- package/dist/components/Carousel/types.d.ts +23 -13
- package/package.json +1 -5
- package/dist/assets/src/components/Carousel/Content/styles.css.ts.vanilla-C4MEo1_C.css +0 -17
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.styles_content__ho48de0 {
|
|
2
|
+
display: flex;
|
|
3
|
+
overflow: hidden;
|
|
4
|
+
height: 100%;
|
|
5
|
+
width: 100%;
|
|
6
|
+
scroll-behavior: smooth;
|
|
7
|
+
-webkit-overflow-scrolling: touch;
|
|
8
|
+
overscroll-behavior: contain;
|
|
9
|
+
scrollbar-width: none;
|
|
10
|
+
}
|
|
11
|
+
.styles_content__ho48de0::-webkit-scrollbar {
|
|
12
|
+
display: none;
|
|
13
|
+
}
|
|
14
|
+
.styles_orientation_horizontal__ho48de1 {
|
|
15
|
+
overflow-x: auto;
|
|
16
|
+
overflow-y: hidden;
|
|
17
|
+
flex-direction: row;
|
|
18
|
+
scroll-snap-type: x mandatory;
|
|
19
|
+
column-gap: var(--spacing-4);
|
|
20
|
+
}
|
|
21
|
+
.styles_orientation_vertical__ho48de2 {
|
|
22
|
+
overflow-y: auto;
|
|
23
|
+
overflow-x: hidden;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
scroll-snap-type: y mandatory;
|
|
26
|
+
row-gap: var(--spacing-4);
|
|
27
|
+
}
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
flex-basis: 100%;
|
|
6
6
|
}
|
|
7
7
|
.styles_orientation_horizontal__ibhmv21 {
|
|
8
|
-
|
|
8
|
+
scroll-snap-align: center;
|
|
9
|
+
scroll-snap-stop: always;
|
|
9
10
|
}
|
|
10
11
|
.styles_orientation_vertical__ibhmv22 {
|
|
11
|
-
|
|
12
|
+
scroll-snap-align: start;
|
|
13
|
+
scroll-snap-stop: always;
|
|
12
14
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getCarouselContext } from "../context.js";
|
|
2
2
|
import __default__ from "./styles.css.js";
|
|
3
3
|
import "svelte/internal/disclose-version";
|
|
4
4
|
import * as $ from "svelte/internal/client";
|
|
@@ -15,17 +15,16 @@ function Arrows($$anchor, $$props) {
|
|
|
15
15
|
"$$legacy",
|
|
16
16
|
"class"
|
|
17
17
|
]);
|
|
18
|
-
const
|
|
19
|
-
const emblaPrevCtx = getEmblaContext("<Carousel.Previous/>");
|
|
18
|
+
const ctx = getCarouselContext("<Carousel.Arrows />");
|
|
20
19
|
var fragment = root();
|
|
21
20
|
var button = $.first_child(fragment);
|
|
22
21
|
$.attribute_effect(button, () => ({
|
|
23
22
|
type: "button",
|
|
24
23
|
"data-slot": "carousel-previous",
|
|
25
|
-
disabled: !
|
|
26
|
-
class: [__default__.buttonPrev[
|
|
27
|
-
onclick:
|
|
28
|
-
onkeydown:
|
|
24
|
+
disabled: !ctx.canScrollPrev,
|
|
25
|
+
class: [__default__.buttonPrev[ctx.orientation], $$props.class],
|
|
26
|
+
onclick: ctx.scrollPrev,
|
|
27
|
+
onkeydown: ctx.handleKeyDown,
|
|
29
28
|
"aria-label": "Previous slide",
|
|
30
29
|
...restProps
|
|
31
30
|
}));
|
|
@@ -37,11 +36,11 @@ function Arrows($$anchor, $$props) {
|
|
|
37
36
|
$.attribute_effect(button_1, () => ({
|
|
38
37
|
type: "button",
|
|
39
38
|
"data-slot": "carousel-next",
|
|
40
|
-
disabled: !
|
|
41
|
-
"aria-disabled": !
|
|
42
|
-
class: [__default__.buttonNext[
|
|
43
|
-
onclick:
|
|
44
|
-
onkeydown:
|
|
39
|
+
disabled: !ctx.canScrollNext,
|
|
40
|
+
"aria-disabled": !ctx.canScrollNext,
|
|
41
|
+
class: [__default__.buttonNext[ctx.orientation], $$props.class],
|
|
42
|
+
onclick: ctx.scrollNext,
|
|
43
|
+
onkeydown: ctx.handleKeyDown,
|
|
45
44
|
"aria-label": "Next slide",
|
|
46
45
|
...restProps
|
|
47
46
|
}));
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { setCarouselContext } from "./context.js";
|
|
2
|
+
import { CarouselStore } from "./store.svelte.js";
|
|
2
3
|
import __default__ from "./styles.css.js";
|
|
3
4
|
import "svelte/internal/disclose-version";
|
|
4
5
|
import * as $ from "svelte/internal/client";
|
|
6
|
+
import { onDestroy } from "svelte";
|
|
5
7
|
|
|
6
8
|
//#region src/components/Carousel/Carousel.svelte
|
|
7
9
|
var root = $.from_html(`<div><!></div>`);
|
|
@@ -12,67 +14,26 @@ function Carousel($$anchor, $$props) {
|
|
|
12
14
|
"$$events",
|
|
13
15
|
"$$legacy",
|
|
14
16
|
"ref",
|
|
15
|
-
"options",
|
|
16
|
-
"plugins",
|
|
17
17
|
"setApi",
|
|
18
18
|
"orientation",
|
|
19
|
+
"align",
|
|
19
20
|
"class",
|
|
20
21
|
"children"
|
|
21
22
|
]);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
canScrollPrev: false,
|
|
29
|
-
handleKeyDown,
|
|
30
|
-
options: {},
|
|
31
|
-
plugins: [],
|
|
32
|
-
onInit,
|
|
33
|
-
scrollSnaps: [],
|
|
34
|
-
selectedIndex: 0,
|
|
35
|
-
scrollTo
|
|
36
|
-
});
|
|
37
|
-
setEmblaContext(carouselState);
|
|
38
|
-
function scrollPrev() {
|
|
39
|
-
carouselState.api?.scrollPrev();
|
|
40
|
-
}
|
|
41
|
-
function scrollNext() {
|
|
42
|
-
carouselState.api?.scrollNext();
|
|
43
|
-
}
|
|
44
|
-
function scrollTo(index, jump) {
|
|
45
|
-
carouselState.api?.scrollTo(index, jump);
|
|
46
|
-
}
|
|
47
|
-
function onSelect() {
|
|
48
|
-
if (!carouselState.api) return;
|
|
49
|
-
carouselState.selectedIndex = carouselState.api.selectedScrollSnap();
|
|
50
|
-
carouselState.canScrollNext = carouselState.api.canScrollNext();
|
|
51
|
-
carouselState.canScrollPrev = carouselState.api.canScrollPrev();
|
|
52
|
-
}
|
|
53
|
-
function handleKeyDown(e) {
|
|
54
|
-
if (e.key === "ArrowLeft") {
|
|
55
|
-
e.preventDefault();
|
|
56
|
-
scrollPrev();
|
|
57
|
-
} else if (e.key === "ArrowRight") {
|
|
58
|
-
e.preventDefault();
|
|
59
|
-
scrollNext();
|
|
23
|
+
const carouselStore = new CarouselStore({
|
|
24
|
+
get orientation() {
|
|
25
|
+
return orientation();
|
|
26
|
+
},
|
|
27
|
+
get align() {
|
|
28
|
+
return $$props.align;
|
|
60
29
|
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
carouselState.api.on("select", onSelect);
|
|
67
|
-
onSelect();
|
|
68
|
-
}
|
|
30
|
+
});
|
|
31
|
+
setCarouselContext(carouselStore);
|
|
32
|
+
onDestroy(() => {
|
|
33
|
+
carouselStore.destroy();
|
|
34
|
+
});
|
|
69
35
|
$.user_effect(() => {
|
|
70
|
-
|
|
71
|
-
if ($$props.options) carouselState.options = $$props.options;
|
|
72
|
-
if ($$props.plugins?.length) carouselState.plugins = $$props.plugins;
|
|
73
|
-
return () => {
|
|
74
|
-
carouselState.api?.off("select", onSelect);
|
|
75
|
-
};
|
|
36
|
+
setApi()(carouselStore.api);
|
|
76
37
|
});
|
|
77
38
|
var div = root();
|
|
78
39
|
$.attribute_effect(div, () => ({
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getCarouselContext } from "../context.js";
|
|
2
2
|
import __default__ from "./styles.css.js";
|
|
3
3
|
import "svelte/internal/disclose-version";
|
|
4
4
|
import * as $ from "svelte/internal/client";
|
|
5
|
-
import
|
|
5
|
+
import { onMount } from "svelte";
|
|
6
6
|
|
|
7
7
|
//#region src/components/Carousel/Content/Content.svelte
|
|
8
|
-
var root = $.from_html(`<div
|
|
8
|
+
var root = $.from_html(`<div><!></div>`);
|
|
9
9
|
function Content($$anchor, $$props) {
|
|
10
10
|
$.push($$props, true);
|
|
11
11
|
let ref = $.prop($$props, "ref", 15, null), restProps = $.rest_props($$props, [
|
|
@@ -16,32 +16,26 @@ function Content($$anchor, $$props) {
|
|
|
16
16
|
"class",
|
|
17
17
|
"children"
|
|
18
18
|
]);
|
|
19
|
-
const
|
|
19
|
+
const carouselCtx = getCarouselContext("<Carousel.Content />");
|
|
20
|
+
onMount(() => {
|
|
21
|
+
carouselCtx.setViewport(ref());
|
|
22
|
+
return () => carouselCtx.setViewport(null);
|
|
23
|
+
});
|
|
20
24
|
var div = root();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class: [
|
|
24
|
-
|
|
25
|
+
$.attribute_effect(div, () => ({
|
|
26
|
+
"data-slot": "carousel-content",
|
|
27
|
+
class: [
|
|
28
|
+
__default__.content,
|
|
29
|
+
__default__.orientation[carouselCtx.orientation],
|
|
30
|
+
$$props.class
|
|
31
|
+
],
|
|
32
|
+
"data-orientation": carouselCtx.orientation,
|
|
25
33
|
...restProps
|
|
26
34
|
}));
|
|
27
|
-
var node = $.child(
|
|
35
|
+
var node = $.child(div);
|
|
28
36
|
$.snippet(node, () => $$props.children ?? $.noop);
|
|
29
|
-
$.reset(div_1);
|
|
30
|
-
$.bind_this(div_1, ($$value) => ref($$value), () => ref());
|
|
31
37
|
$.reset(div);
|
|
32
|
-
$.
|
|
33
|
-
options: {
|
|
34
|
-
container: "[data-embla-container]",
|
|
35
|
-
slides: "[data-embla-slide]",
|
|
36
|
-
...emblaCtx.options,
|
|
37
|
-
axis: emblaCtx.orientation === "horizontal" ? "x" : "y"
|
|
38
|
-
},
|
|
39
|
-
plugins: emblaCtx.plugins
|
|
40
|
-
}));
|
|
41
|
-
$.template_effect(() => $.set_class(div, 1, $.clsx([__default__.contentWrapper, $$props.class])));
|
|
42
|
-
$.event("emblaInit", div, function(...$$args) {
|
|
43
|
-
emblaCtx.onInit?.apply(this, $$args);
|
|
44
|
-
});
|
|
38
|
+
$.bind_this(div, ($$value) => ref($$value), () => ref());
|
|
45
39
|
$.append($$anchor, div);
|
|
46
40
|
$.pop();
|
|
47
41
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import "./../../../assets/src/theme.css.ts.vanilla-DlH7Hr_5.css";
|
|
2
|
-
import "./../../../assets/src/components/Carousel/Content/styles.css.ts.vanilla-
|
|
2
|
+
import "./../../../assets/src/components/Carousel/Content/styles.css.ts.vanilla-WeFKZGhD.css";
|
|
3
3
|
|
|
4
4
|
//#region src/components/Carousel/Content/styles.css.ts
|
|
5
5
|
var __default__ = {
|
|
6
|
-
|
|
7
|
-
container: "styles_container__ho48de1",
|
|
6
|
+
content: "styles_content__ho48de0",
|
|
8
7
|
orientation: {
|
|
9
|
-
horizontal: "
|
|
10
|
-
vertical: "
|
|
8
|
+
horizontal: "styles_orientation_horizontal__ho48de1",
|
|
9
|
+
vertical: "styles_orientation_vertical__ho48de2"
|
|
11
10
|
}
|
|
12
11
|
};
|
|
13
12
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getCarouselContext } from "../context.js";
|
|
2
2
|
import __default__ from "./styles.css.js";
|
|
3
3
|
import "svelte/internal/disclose-version";
|
|
4
4
|
import * as $ from "svelte/internal/client";
|
|
@@ -14,18 +14,18 @@ function Dots($$anchor, $$props) {
|
|
|
14
14
|
"$$legacy",
|
|
15
15
|
"class"
|
|
16
16
|
]);
|
|
17
|
-
const
|
|
17
|
+
const carouselCtx = getCarouselContext("<Carousel.Dots/>");
|
|
18
18
|
const onClick = (index) => {
|
|
19
|
-
|
|
19
|
+
carouselCtx.scrollTo(index);
|
|
20
20
|
};
|
|
21
21
|
var div = root();
|
|
22
22
|
$.attribute_effect(div, () => ({
|
|
23
|
-
class: [__default__.wrapper[
|
|
23
|
+
class: [__default__.wrapper[carouselCtx.orientation], $$props.class],
|
|
24
24
|
...restProps
|
|
25
25
|
}));
|
|
26
|
-
$.each(div, 21, () =>
|
|
26
|
+
$.each(div, 21, () => carouselCtx.scrollSnaps, $.index, ($$anchor, _, index) => {
|
|
27
27
|
var button = root_1();
|
|
28
|
-
$.template_effect(() => $.set_class(button, 1, $.clsx([__default__.dotButton[
|
|
28
|
+
$.template_effect(() => $.set_class(button, 1, $.clsx([__default__.dotButton[carouselCtx.orientation], { [__default__.selected]: index === carouselCtx.selectedIndex }])));
|
|
29
29
|
$.delegated("click", button, () => onClick(index));
|
|
30
30
|
$.append($$anchor, button);
|
|
31
31
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getCarouselContext } from "../context.js";
|
|
2
2
|
import __default__ from "./styles.css.js";
|
|
3
3
|
import "svelte/internal/disclose-version";
|
|
4
4
|
import * as $ from "svelte/internal/client";
|
|
@@ -15,18 +15,18 @@ function Item($$anchor, $$props) {
|
|
|
15
15
|
"class",
|
|
16
16
|
"children"
|
|
17
17
|
]);
|
|
18
|
-
const
|
|
18
|
+
const carouselCtx = getCarouselContext("<Carousel.Item/>");
|
|
19
19
|
var div = root();
|
|
20
20
|
$.attribute_effect(div, () => ({
|
|
21
21
|
"data-slot": "carousel-item",
|
|
22
|
+
"data-orientation": carouselCtx.orientation,
|
|
22
23
|
role: "group",
|
|
23
24
|
"aria-roledescription": "slide",
|
|
24
25
|
class: [
|
|
25
26
|
__default__.item,
|
|
26
|
-
__default__.orientation[
|
|
27
|
+
__default__.orientation[carouselCtx.orientation],
|
|
27
28
|
$$props.class
|
|
28
29
|
],
|
|
29
|
-
"data-embla-slide": "",
|
|
30
30
|
...restProps
|
|
31
31
|
}));
|
|
32
32
|
var node = $.child(div);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import "./../../../assets/src/
|
|
2
|
-
import "./../../../assets/src/components/Carousel/Item/styles.css.ts.vanilla-DM_PUW76.css";
|
|
1
|
+
import "./../../../assets/src/components/Carousel/Item/styles.css.ts.vanilla-DH1QYb6c.css";
|
|
3
2
|
|
|
4
3
|
//#region src/components/Carousel/Item/styles.css.ts
|
|
5
4
|
var __default__ = {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function
|
|
1
|
+
import type { CarouselContext } from './types';
|
|
2
|
+
export declare function setCarouselContext(config: CarouselContext): CarouselContext;
|
|
3
|
+
export declare function getCarouselContext(name?: string): CarouselContext;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { getContext, hasContext, setContext } from "svelte";
|
|
2
2
|
|
|
3
3
|
//#region src/components/Carousel/context.ts
|
|
4
|
-
const
|
|
5
|
-
function
|
|
6
|
-
setContext(
|
|
4
|
+
const CAROUSEL_CONTEXT = Symbol("CAROUSEL_CONTEXT");
|
|
5
|
+
function setCarouselContext(config) {
|
|
6
|
+
setContext(CAROUSEL_CONTEXT, config);
|
|
7
7
|
return config;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
if (!hasContext(
|
|
11
|
-
return getContext(
|
|
9
|
+
function getCarouselContext(name = "This component") {
|
|
10
|
+
if (!hasContext(CAROUSEL_CONTEXT)) throw new Error(`${name} must be used within a <Carousel.Root> component`);
|
|
11
|
+
return getContext(CAROUSEL_CONTEXT);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
//#endregion
|
|
15
|
-
export {
|
|
15
|
+
export { getCarouselContext, setCarouselContext };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CarouselAlign, CarouselAPI, CarouselContext, CarouselOrientation, CarouselProps } from './types';
|
|
2
|
+
export declare class CarouselStore implements CarouselContext {
|
|
3
|
+
#private;
|
|
4
|
+
api: CarouselAPI | undefined;
|
|
5
|
+
viewport: HTMLDivElement | null;
|
|
6
|
+
align: CarouselAlign;
|
|
7
|
+
orientation: CarouselOrientation;
|
|
8
|
+
canScrollNext: boolean;
|
|
9
|
+
canScrollPrev: boolean;
|
|
10
|
+
scrollSnaps: number[];
|
|
11
|
+
selectedIndex: number;
|
|
12
|
+
constructor({ orientation, align, }: Pick<CarouselProps, 'orientation' | 'align'>);
|
|
13
|
+
handleKeyDown: (e: KeyboardEvent) => void;
|
|
14
|
+
setViewport: (node: HTMLDivElement | null) => void;
|
|
15
|
+
scrollPrev: () => void;
|
|
16
|
+
scrollNext: () => void;
|
|
17
|
+
scrollTo: (index: number, jump?: boolean) => void;
|
|
18
|
+
refresh: () => void;
|
|
19
|
+
destroy: () => void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
//#region src/components/Carousel/store.svelte.ts
|
|
2
|
+
var CarouselStore = class {
|
|
3
|
+
api = $state(void 0);
|
|
4
|
+
viewport = $state(null);
|
|
5
|
+
align = $state("center");
|
|
6
|
+
orientation = $state("horizontal");
|
|
7
|
+
canScrollNext = $state(false);
|
|
8
|
+
canScrollPrev = $state(false);
|
|
9
|
+
scrollSnaps = $state([]);
|
|
10
|
+
selectedIndex = $state(0);
|
|
11
|
+
#listeners = /* @__PURE__ */ new Set();
|
|
12
|
+
#resizeObserver = null;
|
|
13
|
+
#mutationObserver = null;
|
|
14
|
+
#observedSlides = [];
|
|
15
|
+
#onScroll = () => this.refresh();
|
|
16
|
+
constructor({ orientation = "horizontal", align = "center" }) {
|
|
17
|
+
this.align = align;
|
|
18
|
+
this.orientation = orientation;
|
|
19
|
+
this.api = {
|
|
20
|
+
scrollPrev: this.scrollPrev,
|
|
21
|
+
scrollNext: this.scrollNext,
|
|
22
|
+
scrollTo: this.scrollTo,
|
|
23
|
+
canScrollNext: () => this.canScrollNext,
|
|
24
|
+
canScrollPrev: () => this.canScrollPrev,
|
|
25
|
+
selectedScrollSnap: () => this.selectedIndex,
|
|
26
|
+
scrollSnapList: () => this.scrollSnaps,
|
|
27
|
+
on: (event, callback) => {
|
|
28
|
+
if (event !== "select") return;
|
|
29
|
+
this.#listeners.add(callback);
|
|
30
|
+
},
|
|
31
|
+
off: (event, callback) => {
|
|
32
|
+
if (event !== "select") return;
|
|
33
|
+
this.#listeners.delete(callback);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
handleKeyDown = (e) => {
|
|
38
|
+
if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
this.scrollPrev();
|
|
41
|
+
} else if (e.key === "ArrowRight" || e.key === "ArrowDown") {
|
|
42
|
+
e.preventDefault();
|
|
43
|
+
this.scrollNext();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
setViewport = (node) => {
|
|
47
|
+
if (this.viewport === node) return;
|
|
48
|
+
this.#detachViewport();
|
|
49
|
+
this.viewport = node;
|
|
50
|
+
if (!node) {
|
|
51
|
+
this.refresh();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
node.addEventListener("scroll", this.#onScroll, { passive: true });
|
|
55
|
+
this.#resizeObserver = new ResizeObserver(() => this.refresh());
|
|
56
|
+
this.#resizeObserver.observe(node);
|
|
57
|
+
this.#mutationObserver = new MutationObserver(() => {
|
|
58
|
+
this.#rebindSlideObservers();
|
|
59
|
+
this.refresh();
|
|
60
|
+
});
|
|
61
|
+
this.#mutationObserver.observe(node, {
|
|
62
|
+
childList: true,
|
|
63
|
+
subtree: false
|
|
64
|
+
});
|
|
65
|
+
this.#rebindSlideObservers();
|
|
66
|
+
this.refresh();
|
|
67
|
+
};
|
|
68
|
+
scrollPrev = () => {
|
|
69
|
+
if (!this.viewport) return;
|
|
70
|
+
const index = Math.max(0, this.selectedIndex - 1);
|
|
71
|
+
this.scrollTo(index);
|
|
72
|
+
};
|
|
73
|
+
scrollNext = () => {
|
|
74
|
+
const slides = this.#getSlides();
|
|
75
|
+
if (!slides.length) return;
|
|
76
|
+
const index = Math.min(slides.length - 1, this.selectedIndex + 1);
|
|
77
|
+
this.scrollTo(index);
|
|
78
|
+
};
|
|
79
|
+
scrollTo = (index, jump) => {
|
|
80
|
+
this.#setScroll(this.#getTargetFor(index), jump);
|
|
81
|
+
};
|
|
82
|
+
refresh = () => {
|
|
83
|
+
const slides = this.#getSlides();
|
|
84
|
+
this.scrollSnaps = slides.map((_, index) => this.#getTargetFor(index));
|
|
85
|
+
if (!this.viewport || !slides.length) {
|
|
86
|
+
this.selectedIndex = 0;
|
|
87
|
+
this.canScrollPrev = false;
|
|
88
|
+
this.canScrollNext = false;
|
|
89
|
+
this.#emitSelect();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const scrollPosition = this.orientation === "horizontal" ? this.viewport.scrollLeft : this.viewport.scrollTop;
|
|
93
|
+
let nearestIndex = 0;
|
|
94
|
+
let nearestDistance = Number.POSITIVE_INFINITY;
|
|
95
|
+
for (let index = 0; index < this.scrollSnaps.length; index += 1) {
|
|
96
|
+
const distance = Math.abs(this.scrollSnaps[index] - scrollPosition);
|
|
97
|
+
if (distance < nearestDistance) {
|
|
98
|
+
nearestDistance = distance;
|
|
99
|
+
nearestIndex = index;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
this.selectedIndex = nearestIndex;
|
|
103
|
+
this.canScrollPrev = nearestIndex > 0;
|
|
104
|
+
this.canScrollNext = nearestIndex < slides.length - 1;
|
|
105
|
+
this.#emitSelect();
|
|
106
|
+
};
|
|
107
|
+
destroy = () => {
|
|
108
|
+
this.#detachViewport();
|
|
109
|
+
this.#listeners.clear();
|
|
110
|
+
};
|
|
111
|
+
#getSlides = () => {
|
|
112
|
+
if (!this.viewport) return [];
|
|
113
|
+
return Array.from(this.viewport.querySelectorAll("[data-slot=\"carousel-item\"]"));
|
|
114
|
+
};
|
|
115
|
+
#getTargetFor = (index) => {
|
|
116
|
+
if (!this.viewport) return 0;
|
|
117
|
+
const slide = this.#getSlides()[index];
|
|
118
|
+
if (!slide) return 0;
|
|
119
|
+
const viewportSize = this.orientation === "horizontal" ? this.viewport.clientWidth : this.viewport.clientHeight;
|
|
120
|
+
const slideSize = this.orientation === "horizontal" ? slide.offsetWidth : slide.offsetHeight;
|
|
121
|
+
const slideStart = this.orientation === "horizontal" ? slide.offsetLeft : slide.offsetTop;
|
|
122
|
+
let target = slideStart;
|
|
123
|
+
if (this.align === "center") target = slideStart - (viewportSize - slideSize) / 2;
|
|
124
|
+
else if (this.align === "end") target = slideStart - (viewportSize - slideSize);
|
|
125
|
+
const max = this.orientation === "horizontal" ? this.viewport.scrollWidth - this.viewport.clientWidth : this.viewport.scrollHeight - this.viewport.clientHeight;
|
|
126
|
+
return Math.max(0, Math.min(target, Math.max(0, max)));
|
|
127
|
+
};
|
|
128
|
+
#setScroll = (target, jump = false) => {
|
|
129
|
+
if (!this.viewport) return;
|
|
130
|
+
this.viewport.scrollTo(this.orientation === "horizontal" ? {
|
|
131
|
+
left: target,
|
|
132
|
+
behavior: jump ? "auto" : "smooth"
|
|
133
|
+
} : {
|
|
134
|
+
top: target,
|
|
135
|
+
behavior: jump ? "auto" : "smooth"
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
#emitSelect = () => {
|
|
139
|
+
for (const callback of this.#listeners) callback();
|
|
140
|
+
};
|
|
141
|
+
#detachViewport = () => {
|
|
142
|
+
if (this.viewport) this.viewport.removeEventListener("scroll", this.#onScroll);
|
|
143
|
+
this.#resizeObserver?.disconnect();
|
|
144
|
+
this.#mutationObserver?.disconnect();
|
|
145
|
+
this.#resizeObserver = null;
|
|
146
|
+
this.#mutationObserver = null;
|
|
147
|
+
this.#observedSlides = [];
|
|
148
|
+
};
|
|
149
|
+
#rebindSlideObservers = () => {
|
|
150
|
+
if (!this.#resizeObserver) return;
|
|
151
|
+
for (const slide of this.#observedSlides) this.#resizeObserver.unobserve(slide);
|
|
152
|
+
this.#observedSlides = this.#getSlides();
|
|
153
|
+
for (const slide of this.#observedSlides) this.#resizeObserver.observe(slide);
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
//#endregion
|
|
158
|
+
export { CarouselStore };
|
|
@@ -1,27 +1,37 @@
|
|
|
1
|
-
import type { EmblaCarouselSvelteType, default as emblaCarouselSvelte } from 'embla-carousel-svelte';
|
|
2
1
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
2
|
import type { WithElementRef } from '../../types.ts';
|
|
4
|
-
export type
|
|
5
|
-
type
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
export type CarouselAlign = 'start' | 'center' | 'end';
|
|
4
|
+
export type CarouselOrientation = 'horizontal' | 'vertical';
|
|
5
|
+
type CarouselEventName = 'select';
|
|
6
|
+
type CarouselEventCallback = () => void;
|
|
7
|
+
export type CarouselAPI = {
|
|
8
|
+
scrollPrev: () => void;
|
|
9
|
+
scrollNext: () => void;
|
|
10
|
+
scrollTo: (index: number, jump?: boolean) => void;
|
|
11
|
+
canScrollNext: () => boolean;
|
|
12
|
+
canScrollPrev: () => boolean;
|
|
13
|
+
selectedScrollSnap: () => number;
|
|
14
|
+
scrollSnapList: () => number[];
|
|
15
|
+
on: (event: CarouselEventName, callback: CarouselEventCallback) => void;
|
|
16
|
+
off: (event: CarouselEventName, callback: CarouselEventCallback) => void;
|
|
17
|
+
};
|
|
8
18
|
export interface CarouselProps extends WithElementRef<HTMLAttributes<HTMLDivElement>> {
|
|
9
|
-
options?: CarouselOptions;
|
|
10
|
-
plugins?: CarouselPlugins;
|
|
11
19
|
setApi?: (api: CarouselAPI | undefined) => void;
|
|
12
|
-
orientation?:
|
|
20
|
+
orientation?: CarouselOrientation;
|
|
21
|
+
align?: CarouselAlign;
|
|
13
22
|
}
|
|
14
|
-
export type
|
|
23
|
+
export type CarouselContext = {
|
|
15
24
|
api: CarouselAPI | undefined;
|
|
16
|
-
|
|
25
|
+
viewport: HTMLDivElement | null;
|
|
26
|
+
align: CarouselAlign;
|
|
27
|
+
orientation: CarouselOrientation;
|
|
17
28
|
scrollNext: () => void;
|
|
18
29
|
scrollPrev: () => void;
|
|
19
30
|
canScrollNext: boolean;
|
|
20
31
|
canScrollPrev: boolean;
|
|
21
32
|
handleKeyDown: (e: KeyboardEvent) => void;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
onInit: (e: CustomEvent<CarouselAPI>) => void;
|
|
33
|
+
setViewport: (node: HTMLDivElement | null) => void;
|
|
34
|
+
refresh: () => void;
|
|
25
35
|
scrollTo: (index: number, jump?: boolean) => void;
|
|
26
36
|
scrollSnaps: number[];
|
|
27
37
|
selectedIndex: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@max-ts/svelte",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Svelte component library.",
|
|
6
6
|
"author": "Tsepelev Maksim",
|
|
@@ -32,8 +32,6 @@
|
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@internationalized/date": "^3.10.1",
|
|
35
|
-
"embla-carousel-autoplay": "^8.6.0",
|
|
36
|
-
"embla-carousel-svelte": "^8.6.0",
|
|
37
35
|
"svelte": "^5.53.5"
|
|
38
36
|
},
|
|
39
37
|
"devDependencies": {
|
|
@@ -54,8 +52,6 @@
|
|
|
54
52
|
"@vanilla-extract/vite-plugin": "^5.1.4",
|
|
55
53
|
"@vitest/browser-playwright": "^4.0.18",
|
|
56
54
|
"bumpp": "^10.4.1",
|
|
57
|
-
"embla-carousel-autoplay": "^8.6.0",
|
|
58
|
-
"embla-carousel-svelte": "^8.6.0",
|
|
59
55
|
"rollup-plugin-svelte": "^7.2.3",
|
|
60
56
|
"storybook": "^10.2.13",
|
|
61
57
|
"svelte": "^5.53.5",
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
.styles_contentWrapper__ho48de0 {
|
|
2
|
-
overflow: hidden;
|
|
3
|
-
height: 100%;
|
|
4
|
-
}
|
|
5
|
-
.styles_container__ho48de1 {
|
|
6
|
-
display: flex;
|
|
7
|
-
height: 100%;
|
|
8
|
-
width: 100%;
|
|
9
|
-
}
|
|
10
|
-
.styles_orientation_horizontal__ho48de2 {
|
|
11
|
-
margin-left: calc(-1 * var(--spacing-4));
|
|
12
|
-
flex-direction: row;
|
|
13
|
-
}
|
|
14
|
-
.styles_orientation_vertical__ho48de3 {
|
|
15
|
-
margin-top: calc(-1 * var(--spacing-4));
|
|
16
|
-
flex-direction: column;
|
|
17
|
-
}
|