@snack-uikit/carousel 0.2.20-preview-94780dcd.0 → 0.2.21-preview-d46fe148.0
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/CHANGELOG.md +11 -0
- package/dist/components/Carousel/Carousel.js +1 -1
- package/dist/components/Control/Control.js +1 -3
- package/dist/components/ItemProvider/ItemProvider.d.ts +2 -1
- package/dist/components/ItemProvider/ItemProvider.js +19 -13
- package/package.json +5 -5
- package/src/components/Carousel/Carousel.tsx +1 -0
- package/src/components/Control/Control.tsx +1 -3
- package/src/components/ItemProvider/ItemProvider.tsx +39 -13
- package/src/components/ItemProvider/styles.module.scss +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 0.2.20 (2024-09-23)
|
|
7
|
+
|
|
8
|
+
### Only dependencies have been changed
|
|
9
|
+
* [@snack-uikit/icons@0.22.1](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/icons/CHANGELOG.md)
|
|
10
|
+
* [@snack-uikit/pagination@0.7.1](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/pagination/CHANGELOG.md)
|
|
11
|
+
* [@snack-uikit/utils@3.4.0](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/utils/CHANGELOG.md)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## 0.2.19 (2024-09-07)
|
|
7
18
|
|
|
8
19
|
|
|
@@ -41,7 +41,7 @@ export function Carousel(_a) {
|
|
|
41
41
|
}
|
|
42
42
|
onLeftArrowClick();
|
|
43
43
|
}, [onLeftArrowClick, onRightArrowClick]);
|
|
44
|
-
return (_jsxs("div", Object.assign({ className: cn(styles.carousel, className) }, extractSupportProps(rest), { children: [_jsxs("div", { className: styles.carouselBase, children: [_jsx(ItemProvider, { showItems: showItems, scrollBy: scrollBy, swipe: swipe, transition: transition, items: items, slideCallback: slideCallback, page: page, gap: gap, swipeActivateLength: swipeActivateLength }), arrows && (_jsxs(_Fragment, { children: [(infiniteScroll || page > 0) && (_jsx(Control, { onClick: onLeftArrowClick, variant: 'prev', "data-test-id": TEST_IDS.arrowPrev })), (infiniteScroll || page + 1 < total) && (_jsx(Control, { onClick: onRightArrowClick, variant: 'next', "data-test-id": TEST_IDS.arrowNext }))] }))] }), pagination && (_jsx("div", { className: styles.pagination, children: _jsx(PaginationSlider, { "data-test-id": TEST_IDS.pagination, page: page + 1, onChange: (page) => {
|
|
44
|
+
return (_jsxs("div", Object.assign({ className: cn(styles.carousel, className) }, extractSupportProps(rest), { children: [_jsxs("div", { className: styles.carouselBase, children: [_jsx(ItemProvider, { showItems: showItems, scrollBy: scrollBy, swipe: swipe, transition: transition, items: items, slideCallback: slideCallback, page: page, gap: gap, swipeActivateLength: swipeActivateLength, scrollToNextPage: onRightArrowClick }), arrows && (_jsxs(_Fragment, { children: [(infiniteScroll || page > 0) && (_jsx(Control, { onClick: onLeftArrowClick, variant: 'prev', "data-test-id": TEST_IDS.arrowPrev })), (infiniteScroll || page + 1 < total) && (_jsx(Control, { onClick: onRightArrowClick, variant: 'next', "data-test-id": TEST_IDS.arrowNext }))] }))] }), pagination && (_jsx("div", { className: styles.pagination, children: _jsx(PaginationSlider, { "data-test-id": TEST_IDS.pagination, page: page + 1, onChange: (page) => {
|
|
45
45
|
setPage(page - 1);
|
|
46
46
|
}, total: total }) }))] })));
|
|
47
47
|
}
|
|
@@ -16,7 +16,5 @@ import { extractSupportProps } from '@snack-uikit/utils';
|
|
|
16
16
|
import styles from './styles.module.css';
|
|
17
17
|
export const Control = forwardRef((_a, ref) => {
|
|
18
18
|
var { onClick, variant } = _a, rest = __rest(_a, ["onClick", "variant"]);
|
|
19
|
-
return (_jsx("button", Object.assign({ ref: ref, className: styles.control, onClick: ()
|
|
20
|
-
onClick === null || onClick === void 0 ? void 0 : onClick();
|
|
21
|
-
}, type: 'button', "data-variant": variant }, extractSupportProps(rest), { children: _jsx(ChevronLeftSVG, { size: 24, className: styles.icon }) })));
|
|
19
|
+
return (_jsx("button", Object.assign({ ref: ref, className: styles.control, onClick: onClick, type: 'button', "data-variant": variant }, extractSupportProps(rest), { children: _jsx(ChevronLeftSVG, { size: 24, className: styles.icon }) })));
|
|
22
20
|
});
|
|
@@ -4,10 +4,11 @@ export type ItemProviderProps = {
|
|
|
4
4
|
showItems: number;
|
|
5
5
|
scrollBy: number;
|
|
6
6
|
slideCallback(direction: number): void;
|
|
7
|
+
scrollToNextPage(): void;
|
|
7
8
|
transition: number;
|
|
8
9
|
swipe: boolean;
|
|
9
10
|
swipeActivateLength: number;
|
|
10
11
|
page: number;
|
|
11
12
|
gap?: string;
|
|
12
13
|
};
|
|
13
|
-
export declare function ItemProvider({ items, showItems, scrollBy, slideCallback, transition, swipe, swipeActivateLength, page, gap, }: ItemProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare function ItemProvider({ items, showItems, scrollBy, slideCallback, scrollToNextPage, transition, swipe, swipeActivateLength, page, gap, }: ItemProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import debounce from 'lodash.debounce';
|
|
3
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
4
4
|
import { TEST_IDS } from '../../testIds';
|
|
5
5
|
import { getPageX } from './helpers';
|
|
6
6
|
import styles from './styles.module.css';
|
|
7
|
-
export function ItemProvider({ items, showItems, scrollBy, slideCallback, transition, swipe, swipeActivateLength, page, gap, }) {
|
|
7
|
+
export function ItemProvider({ items, showItems, scrollBy, slideCallback, scrollToNextPage, transition, swipe, swipeActivateLength, page, gap, }) {
|
|
8
8
|
const containerRef = useRef(null);
|
|
9
9
|
const [computedValues, setComputedValues] = useState({
|
|
10
10
|
itemWidth: 200,
|
|
@@ -37,30 +37,28 @@ export function ItemProvider({ items, showItems, scrollBy, slideCallback, transi
|
|
|
37
37
|
return () => observer.disconnect();
|
|
38
38
|
}, [recalculateItemsSize]);
|
|
39
39
|
const itemsTrackerRef = useRef(null);
|
|
40
|
-
|
|
40
|
+
const hideNonVisibleItems = () => {
|
|
41
41
|
var _a;
|
|
42
|
-
(_a = itemsTrackerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`[data-test-id=${TEST_IDS.trackItem}]`).forEach(
|
|
42
|
+
(_a = itemsTrackerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`[data-test-id=${TEST_IDS.trackItem}]`).forEach(slide => {
|
|
43
43
|
slide.setAttribute('aria-hidden', '0');
|
|
44
|
-
slide.querySelectorAll('a, button, select, input, textarea, [tabindex="0"]').forEach(
|
|
44
|
+
slide.querySelectorAll('a, button, select, input, textarea, [tabindex="0"]').forEach(focusableElement => {
|
|
45
45
|
focusableElement.setAttribute('tabindex', '-5');
|
|
46
46
|
focusableElement.classList.add(styles.hiddenItem);
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
|
-
}
|
|
50
|
-
|
|
49
|
+
};
|
|
50
|
+
const showVisibleItems = (slide, page, show) => {
|
|
51
51
|
var _a;
|
|
52
52
|
(_a = itemsTrackerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`[data-test-id=${TEST_IDS.trackItem}]`).forEach((item, i) => {
|
|
53
53
|
if (i >= page * slide && i < page * slide + Math.trunc(show)) {
|
|
54
54
|
item.removeAttribute('aria-hidden');
|
|
55
|
-
item
|
|
56
|
-
.querySelectorAll('a, button, select, input, textarea, [tabindex="-5"]')
|
|
57
|
-
.forEach(function (focusableElement) {
|
|
55
|
+
item.querySelectorAll('a, button, select, input, textarea, [tabindex="-5"]').forEach(focusableElement => {
|
|
58
56
|
focusableElement.setAttribute('tabindex', '0');
|
|
59
57
|
focusableElement.classList.remove(styles.hiddenItem);
|
|
60
58
|
});
|
|
61
59
|
}
|
|
62
60
|
});
|
|
63
|
-
}
|
|
61
|
+
};
|
|
64
62
|
const transform = useMemo(() => Number(-(page * scrollBy * computedValues.itemWidth + computedValues.gap * page * scrollBy)), [computedValues.gap, computedValues.itemWidth, page, scrollBy]);
|
|
65
63
|
useEffect(() => {
|
|
66
64
|
hideNonVisibleItems();
|
|
@@ -117,8 +115,16 @@ export function ItemProvider({ items, showItems, scrollBy, slideCallback, transi
|
|
|
117
115
|
onMouseMove: handleDragMove,
|
|
118
116
|
}
|
|
119
117
|
: {};
|
|
120
|
-
|
|
118
|
+
const handleSlideClick = useCallback(e => {
|
|
119
|
+
const isHidden = e.currentTarget.hasAttribute('aria-hidden');
|
|
120
|
+
if (isHidden) {
|
|
121
|
+
scrollToNextPage();
|
|
122
|
+
}
|
|
123
|
+
}, [scrollToNextPage]);
|
|
124
|
+
return (_jsx("div", { ref: containerRef, className: styles.itemProvider, "data-pointers": !drag.pointers || undefined, "data-swipe": swipe || undefined, "data-gap": gap, style: Object.assign({}, (Boolean(gap) ? { '--gap': gap } : {})), children: _jsx("div", Object.assign({}, swipeProps, { className: styles.itemTracker, "data-test-id": TEST_IDS.trackLine, style: {
|
|
121
125
|
transform: `translateX(${transform - drag.drag}px)`,
|
|
122
126
|
transition: `transform ${transition}s ease 0s`,
|
|
123
|
-
}, ref: itemsTrackerRef, children: items.map((item, i) => (
|
|
127
|
+
}, ref: itemsTrackerRef, children: items.map((item, i) => (
|
|
128
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
129
|
+
_jsx("div", { style: { width: computedValues.itemWidth }, className: styles.itemContainer, role: 'group', "data-test-id": TEST_IDS.trackItem, onClick: handleSlideClick, children: item }, i))) })) }));
|
|
124
130
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.2.
|
|
7
|
+
"version": "0.2.21-preview-d46fe148.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"license": "Apache-2.0",
|
|
33
33
|
"scripts": {},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@snack-uikit/icons": "0.22.1
|
|
36
|
-
"@snack-uikit/pagination": "0.7.1
|
|
37
|
-
"@snack-uikit/utils": "3.
|
|
35
|
+
"@snack-uikit/icons": "0.22.1",
|
|
36
|
+
"@snack-uikit/pagination": "0.7.1",
|
|
37
|
+
"@snack-uikit/utils": "3.4.0",
|
|
38
38
|
"classnames": "2.3.2",
|
|
39
39
|
"lodash.debounce": "4.0.8",
|
|
40
40
|
"uncontrollable": "8.0.4"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "39027f47c1a2c50919d064ec52bc41730821fc55"
|
|
43
43
|
}
|
|
@@ -15,9 +15,7 @@ export const Control = forwardRef<HTMLButtonElement, ControlProps>(
|
|
|
15
15
|
<button
|
|
16
16
|
ref={ref}
|
|
17
17
|
className={styles.control}
|
|
18
|
-
onClick={
|
|
19
|
-
onClick?.();
|
|
20
|
-
}}
|
|
18
|
+
onClick={onClick}
|
|
21
19
|
type='button'
|
|
22
20
|
data-variant={variant}
|
|
23
21
|
{...extractSupportProps(rest)}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import debounce from 'lodash.debounce';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
MouseEvent,
|
|
4
|
+
MouseEventHandler,
|
|
5
|
+
ReactElement,
|
|
6
|
+
TouchEvent,
|
|
7
|
+
useCallback,
|
|
8
|
+
useEffect,
|
|
9
|
+
useMemo,
|
|
10
|
+
useRef,
|
|
11
|
+
useState,
|
|
12
|
+
} from 'react';
|
|
3
13
|
|
|
4
14
|
import { TEST_IDS } from '../../testIds';
|
|
5
15
|
import { getPageX } from './helpers';
|
|
@@ -10,6 +20,7 @@ export type ItemProviderProps = {
|
|
|
10
20
|
showItems: number;
|
|
11
21
|
scrollBy: number;
|
|
12
22
|
slideCallback(direction: number): void;
|
|
23
|
+
scrollToNextPage(): void;
|
|
13
24
|
transition: number;
|
|
14
25
|
swipe: boolean;
|
|
15
26
|
swipeActivateLength: number;
|
|
@@ -22,6 +33,7 @@ export function ItemProvider({
|
|
|
22
33
|
showItems,
|
|
23
34
|
scrollBy,
|
|
24
35
|
slideCallback,
|
|
36
|
+
scrollToNextPage,
|
|
25
37
|
transition,
|
|
26
38
|
swipe,
|
|
27
39
|
swipeActivateLength,
|
|
@@ -73,30 +85,28 @@ export function ItemProvider({
|
|
|
73
85
|
|
|
74
86
|
const itemsTrackerRef = useRef<HTMLDivElement>(null);
|
|
75
87
|
|
|
76
|
-
|
|
77
|
-
itemsTrackerRef.current?.querySelectorAll(`[data-test-id=${TEST_IDS.trackItem}]`).forEach(
|
|
88
|
+
const hideNonVisibleItems = () => {
|
|
89
|
+
itemsTrackerRef.current?.querySelectorAll(`[data-test-id=${TEST_IDS.trackItem}]`).forEach(slide => {
|
|
78
90
|
slide.setAttribute('aria-hidden', '0');
|
|
79
91
|
|
|
80
|
-
slide.querySelectorAll('a, button, select, input, textarea, [tabindex="0"]').forEach(
|
|
92
|
+
slide.querySelectorAll('a, button, select, input, textarea, [tabindex="0"]').forEach(focusableElement => {
|
|
81
93
|
focusableElement.setAttribute('tabindex', '-5');
|
|
82
94
|
focusableElement.classList.add(styles.hiddenItem);
|
|
83
95
|
});
|
|
84
96
|
});
|
|
85
|
-
}
|
|
97
|
+
};
|
|
86
98
|
|
|
87
|
-
|
|
99
|
+
const showVisibleItems = (slide: number, page: number, show: number) => {
|
|
88
100
|
itemsTrackerRef.current?.querySelectorAll(`[data-test-id=${TEST_IDS.trackItem}]`).forEach((item, i) => {
|
|
89
101
|
if (i >= page * slide && i < page * slide + Math.trunc(show)) {
|
|
90
102
|
item.removeAttribute('aria-hidden');
|
|
91
|
-
item
|
|
92
|
-
.
|
|
93
|
-
.
|
|
94
|
-
|
|
95
|
-
focusableElement.classList.remove(styles.hiddenItem);
|
|
96
|
-
});
|
|
103
|
+
item.querySelectorAll('a, button, select, input, textarea, [tabindex="-5"]').forEach(focusableElement => {
|
|
104
|
+
focusableElement.setAttribute('tabindex', '0');
|
|
105
|
+
focusableElement.classList.remove(styles.hiddenItem);
|
|
106
|
+
});
|
|
97
107
|
}
|
|
98
108
|
});
|
|
99
|
-
}
|
|
109
|
+
};
|
|
100
110
|
|
|
101
111
|
const transform = useMemo(
|
|
102
112
|
() => Number(-(page * scrollBy * computedValues.itemWidth + computedValues.gap * page * scrollBy)),
|
|
@@ -130,9 +140,11 @@ export function ItemProvider({
|
|
|
130
140
|
|
|
131
141
|
const handleDragFinish = (e: MouseEvent | TouchEvent) => {
|
|
132
142
|
e.persist();
|
|
143
|
+
|
|
133
144
|
if (drag.finished) {
|
|
134
145
|
return;
|
|
135
146
|
}
|
|
147
|
+
|
|
136
148
|
if (Math.abs(drag.drag) < swipeActivateLength) {
|
|
137
149
|
return setDrag({
|
|
138
150
|
initial: transform,
|
|
@@ -178,12 +190,24 @@ export function ItemProvider({
|
|
|
178
190
|
}
|
|
179
191
|
: {};
|
|
180
192
|
|
|
193
|
+
const handleSlideClick: MouseEventHandler = useCallback(
|
|
194
|
+
e => {
|
|
195
|
+
const isHidden = e.currentTarget.hasAttribute('aria-hidden');
|
|
196
|
+
|
|
197
|
+
if (isHidden) {
|
|
198
|
+
scrollToNextPage();
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
[scrollToNextPage],
|
|
202
|
+
);
|
|
203
|
+
|
|
181
204
|
return (
|
|
182
205
|
<div
|
|
183
206
|
ref={containerRef}
|
|
184
207
|
className={styles.itemProvider}
|
|
185
208
|
data-pointers={!drag.pointers || undefined}
|
|
186
209
|
data-swipe={swipe || undefined}
|
|
210
|
+
data-gap={gap}
|
|
187
211
|
style={{
|
|
188
212
|
...(Boolean(gap) ? { '--gap': gap } : {}),
|
|
189
213
|
}}
|
|
@@ -199,12 +223,14 @@ export function ItemProvider({
|
|
|
199
223
|
ref={itemsTrackerRef}
|
|
200
224
|
>
|
|
201
225
|
{items.map((item, i) => (
|
|
226
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
202
227
|
<div
|
|
203
228
|
key={i}
|
|
204
229
|
style={{ width: computedValues.itemWidth }}
|
|
205
230
|
className={styles.itemContainer}
|
|
206
231
|
role='group'
|
|
207
232
|
data-test-id={TEST_IDS.trackItem}
|
|
233
|
+
onClick={handleSlideClick}
|
|
208
234
|
>
|
|
209
235
|
{item}
|
|
210
236
|
</div>
|