@dnanpm/styleguide 3.9.4 → 3.9.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.
- package/build/cjs/components/Carousel/Carousel.d.ts +11 -0
- package/build/cjs/components/Carousel/Carousel.js +35 -3
- package/build/cjs/themes/globalStyles.js +5 -4
- package/build/es/components/Carousel/Carousel.d.ts +11 -0
- package/build/es/components/Carousel/Carousel.js +36 -4
- package/build/es/themes/globalStyles.js +5 -4
- package/package.json +1 -1
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { MouseEvent, ReactNode } from 'react';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
interface Responsive {
|
|
4
|
+
minItems: number;
|
|
5
|
+
maxItems: number;
|
|
6
|
+
minWidth: number;
|
|
7
|
+
maxWidth: number;
|
|
8
|
+
}
|
|
3
9
|
interface Props {
|
|
4
10
|
/**
|
|
5
11
|
* Unique ID for the component
|
|
@@ -43,6 +49,11 @@ interface Props {
|
|
|
43
49
|
* Allows to pass a custom className
|
|
44
50
|
*/
|
|
45
51
|
className?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Allows to define responsive configuration
|
|
54
|
+
* If not provided, visibleItems property will be used
|
|
55
|
+
*/
|
|
56
|
+
responsive?: Partial<Responsive>;
|
|
46
57
|
}
|
|
47
58
|
/** @visibleName Carousel */
|
|
48
59
|
declare const Carousel: ({ "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
|
|
@@ -55,6 +55,10 @@ const SlideItem = styled.default.div `
|
|
|
55
55
|
flex-basis: calc(
|
|
56
56
|
${({ visibleItems, itemWidthCorrection }) => `(100% / ${visibleItems}) - ${itemWidthCorrection}px`}
|
|
57
57
|
);
|
|
58
|
+
|
|
59
|
+
a {
|
|
60
|
+
pointer-events: ${({ isSwiping }) => (isSwiping ? 'none' : 'auto')};
|
|
61
|
+
}
|
|
58
62
|
`;
|
|
59
63
|
const Footer = styled.default.div `
|
|
60
64
|
${styledUtils.media.md `
|
|
@@ -146,9 +150,32 @@ const Carousel = (_a) => {
|
|
|
146
150
|
const slidesWrapperRef = React.useRef(null);
|
|
147
151
|
const scrollbarRef = React.useRef(null);
|
|
148
152
|
const knobRef = React.useRef(null);
|
|
149
|
-
const { isMobile } = useWindowSize.default(theme.default.breakpoints.md);
|
|
153
|
+
const { isMobile, width } = useWindowSize.default(theme.default.breakpoints.md);
|
|
150
154
|
const [currentIndex, setCurrentIndex] = React.useState(0);
|
|
151
|
-
const
|
|
155
|
+
const [isSwiping, setIsSwiping] = React.useState(false);
|
|
156
|
+
const [calculatedItems, setCalculatedItems] = React.useState(props.visibleItems || (isMobile ? 1.2 : 1));
|
|
157
|
+
React.useEffect(() => {
|
|
158
|
+
const calculateVisibleItems = () => {
|
|
159
|
+
const defaultValue = props.visibleItems || (isMobile ? 1.2 : 1);
|
|
160
|
+
const { minItems, maxItems, minWidth, maxWidth } = props.responsive || {};
|
|
161
|
+
if (!width || !minItems || !maxItems || !minWidth || !maxWidth) {
|
|
162
|
+
return defaultValue;
|
|
163
|
+
}
|
|
164
|
+
const calculatedMaxItems = React.Children.count(props.children) === 1 ? 1 : maxItems;
|
|
165
|
+
if (width < minWidth) {
|
|
166
|
+
return minItems;
|
|
167
|
+
}
|
|
168
|
+
if (width > maxWidth) {
|
|
169
|
+
return calculatedMaxItems;
|
|
170
|
+
}
|
|
171
|
+
return minItems + ((width - minWidth) / (maxWidth - minWidth)) * (maxItems - minItems);
|
|
172
|
+
};
|
|
173
|
+
const timeoutId = setTimeout(() => {
|
|
174
|
+
setCalculatedItems(calculateVisibleItems());
|
|
175
|
+
}, 100);
|
|
176
|
+
return () => clearTimeout(timeoutId);
|
|
177
|
+
}, [width, isMobile, props.responsive, props.visibleItems, props.children]);
|
|
178
|
+
const visibleItems = props.visibleItems || calculatedItems;
|
|
152
179
|
const slidesWrapperGapSizePx = 20;
|
|
153
180
|
const slideScreensCount = React.Children.count(props.children) - Math.floor(visibleItems) + 1;
|
|
154
181
|
const itemWidthCorrectionRatio = (slidesWrapperGapSizePx * visibleItems) % Math.floor(visibleItems) === 0
|
|
@@ -238,6 +265,7 @@ const Carousel = (_a) => {
|
|
|
238
265
|
}
|
|
239
266
|
setElementTransform(slidesWrapperRef, data.currentTransform, 0);
|
|
240
267
|
setElementTransform(knobRef, data.knobCurrentTransform, 0);
|
|
268
|
+
setIsSwiping(true);
|
|
241
269
|
};
|
|
242
270
|
const handlePointerUp = (e) => {
|
|
243
271
|
const endTime = Date.now();
|
|
@@ -264,6 +292,7 @@ const Carousel = (_a) => {
|
|
|
264
292
|
}
|
|
265
293
|
document.removeEventListener('pointermove', handlePointerMove);
|
|
266
294
|
document.removeEventListener('pointerup', handlePointerUp);
|
|
295
|
+
setIsSwiping(false);
|
|
267
296
|
};
|
|
268
297
|
const handleSlidesPointerDown = (e) => {
|
|
269
298
|
if (slidesWrapperRef.current && scrollbarRef.current && knobRef.current) {
|
|
@@ -279,6 +308,9 @@ const Carousel = (_a) => {
|
|
|
279
308
|
const handleScrollbarPointerDown = (e) => {
|
|
280
309
|
handleSlidesPointerDown(e);
|
|
281
310
|
};
|
|
311
|
+
const handlePointerDown = (e) => {
|
|
312
|
+
e.preventDefault();
|
|
313
|
+
};
|
|
282
314
|
React.useEffect(() => {
|
|
283
315
|
if (slidesWrapperRef.current && scrollbarRef.current) {
|
|
284
316
|
const isRest = React.Children.count(props.children) - (currentIndex + visibleItems) < 0;
|
|
@@ -315,7 +347,7 @@ const Carousel = (_a) => {
|
|
|
315
347
|
React__default.default.createElement(ButtonArrow.default, { direction: "left", "aria-label": "Previous", onClick: handleNavigationButtonPreviousClick, disabled: currentIndex <= 0 }),
|
|
316
348
|
React__default.default.createElement(ButtonArrow.default, { direction: "right", "aria-label": "Next", onClick: handleNavigationButtonNextClick, disabled: currentIndex + visibleItems >= React.Children.count(props.children) }))),
|
|
317
349
|
React__default.default.createElement(Content, { "data-testid": dataTestId && `${dataTestId}-content` },
|
|
318
|
-
React__default.default.createElement(SlidesWrapper, { ref: slidesWrapperRef, onPointerDown: handleSlidesPointerDown, gap: slidesWrapperGapSizePx / 16 }, React.Children.map(props.children, child => (React__default.default.createElement(SlideItem, { visibleItems: visibleItems, itemWidthCorrection: itemWidthCorrection }, child))))),
|
|
350
|
+
React__default.default.createElement(SlidesWrapper, { ref: slidesWrapperRef, onPointerDown: handleSlidesPointerDown, gap: slidesWrapperGapSizePx / 16 }, React.Children.map(props.children, child => (React__default.default.createElement(SlideItem, { visibleItems: visibleItems, itemWidthCorrection: itemWidthCorrection, isSwiping: isSwiping, onPointerDown: handlePointerDown }, child))))),
|
|
319
351
|
React__default.default.createElement(Footer, { "data-testid": dataTestId && `${dataTestId}-footer` },
|
|
320
352
|
React__default.default.createElement(Pagination, null, [...Array(slideScreensCount).keys()].map((value, index) => (React__default.default.createElement(PaginationItem, { key: value, "aria-label": `Move to step ${index + 1}`, "aria-current": index === currentIndex, isActive: index === currentIndex, onClick: handlePaginationItemClick })))),
|
|
321
353
|
React__default.default.createElement(Scrollbar, { ref: scrollbarRef, onPointerDown: handleScrollbarPointerDown },
|
|
@@ -220,19 +220,20 @@ const CheckboxAndRadioInputCore = styled.default.input `
|
|
|
220
220
|
|
|
221
221
|
&:disabled {
|
|
222
222
|
cursor: not-allowed;
|
|
223
|
-
color: ${theme.default.color.
|
|
224
|
-
|
|
225
|
-
|
|
223
|
+
color: ${theme.default.color.text.gray};
|
|
224
|
+
background-color: ${theme.default.color.line.L02};
|
|
225
|
+
border-color: ${theme.default.color.line.L01};
|
|
226
226
|
|
|
227
227
|
& + label {
|
|
228
228
|
cursor: not-allowed;
|
|
229
|
-
color: ${theme.default.color.text.
|
|
229
|
+
color: ${theme.default.color.text.gray};
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
&:disabled:checked {
|
|
234
234
|
color: ${theme.default.color.default.pink}${theme.default.color.transparency.T30};
|
|
235
235
|
border-color: ${theme.default.color.default.pink}${theme.default.color.transparency.T30};
|
|
236
|
+
background-color: ${theme.default.color.background.white.default};
|
|
236
237
|
}
|
|
237
238
|
`;
|
|
238
239
|
styled.createGlobalStyle `
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { MouseEvent, ReactNode } from 'react';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
interface Responsive {
|
|
4
|
+
minItems: number;
|
|
5
|
+
maxItems: number;
|
|
6
|
+
minWidth: number;
|
|
7
|
+
maxWidth: number;
|
|
8
|
+
}
|
|
3
9
|
interface Props {
|
|
4
10
|
/**
|
|
5
11
|
* Unique ID for the component
|
|
@@ -43,6 +49,11 @@ interface Props {
|
|
|
43
49
|
* Allows to pass a custom className
|
|
44
50
|
*/
|
|
45
51
|
className?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Allows to define responsive configuration
|
|
54
|
+
* If not provided, visibleItems property will be used
|
|
55
|
+
*/
|
|
56
|
+
responsive?: Partial<Responsive>;
|
|
46
57
|
}
|
|
47
58
|
/** @visibleName Carousel */
|
|
48
59
|
declare const Carousel: ({ "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __rest } from 'tslib';
|
|
2
2
|
import { ArrowRight } from '@dnanpm/icons';
|
|
3
|
-
import React__default, { useRef, useState, Children, useMemo
|
|
3
|
+
import React__default, { useRef, useState, useEffect, Children, useMemo } from 'react';
|
|
4
4
|
import useWindowSize from '../../hooks/useWindowSize.js';
|
|
5
5
|
import styled from '../../themes/styled.js';
|
|
6
6
|
import theme from '../../themes/theme.js';
|
|
@@ -47,6 +47,10 @@ const SlideItem = styled.div `
|
|
|
47
47
|
flex-basis: calc(
|
|
48
48
|
${({ visibleItems, itemWidthCorrection }) => `(100% / ${visibleItems}) - ${itemWidthCorrection}px`}
|
|
49
49
|
);
|
|
50
|
+
|
|
51
|
+
a {
|
|
52
|
+
pointer-events: ${({ isSwiping }) => (isSwiping ? 'none' : 'auto')};
|
|
53
|
+
}
|
|
50
54
|
`;
|
|
51
55
|
const Footer = styled.div `
|
|
52
56
|
${media.md `
|
|
@@ -138,9 +142,32 @@ const Carousel = (_a) => {
|
|
|
138
142
|
const slidesWrapperRef = useRef(null);
|
|
139
143
|
const scrollbarRef = useRef(null);
|
|
140
144
|
const knobRef = useRef(null);
|
|
141
|
-
const { isMobile } = useWindowSize(theme.breakpoints.md);
|
|
145
|
+
const { isMobile, width } = useWindowSize(theme.breakpoints.md);
|
|
142
146
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
143
|
-
const
|
|
147
|
+
const [isSwiping, setIsSwiping] = useState(false);
|
|
148
|
+
const [calculatedItems, setCalculatedItems] = useState(props.visibleItems || (isMobile ? 1.2 : 1));
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
const calculateVisibleItems = () => {
|
|
151
|
+
const defaultValue = props.visibleItems || (isMobile ? 1.2 : 1);
|
|
152
|
+
const { minItems, maxItems, minWidth, maxWidth } = props.responsive || {};
|
|
153
|
+
if (!width || !minItems || !maxItems || !minWidth || !maxWidth) {
|
|
154
|
+
return defaultValue;
|
|
155
|
+
}
|
|
156
|
+
const calculatedMaxItems = Children.count(props.children) === 1 ? 1 : maxItems;
|
|
157
|
+
if (width < minWidth) {
|
|
158
|
+
return minItems;
|
|
159
|
+
}
|
|
160
|
+
if (width > maxWidth) {
|
|
161
|
+
return calculatedMaxItems;
|
|
162
|
+
}
|
|
163
|
+
return minItems + ((width - minWidth) / (maxWidth - minWidth)) * (maxItems - minItems);
|
|
164
|
+
};
|
|
165
|
+
const timeoutId = setTimeout(() => {
|
|
166
|
+
setCalculatedItems(calculateVisibleItems());
|
|
167
|
+
}, 100);
|
|
168
|
+
return () => clearTimeout(timeoutId);
|
|
169
|
+
}, [width, isMobile, props.responsive, props.visibleItems, props.children]);
|
|
170
|
+
const visibleItems = props.visibleItems || calculatedItems;
|
|
144
171
|
const slidesWrapperGapSizePx = 20;
|
|
145
172
|
const slideScreensCount = Children.count(props.children) - Math.floor(visibleItems) + 1;
|
|
146
173
|
const itemWidthCorrectionRatio = (slidesWrapperGapSizePx * visibleItems) % Math.floor(visibleItems) === 0
|
|
@@ -230,6 +257,7 @@ const Carousel = (_a) => {
|
|
|
230
257
|
}
|
|
231
258
|
setElementTransform(slidesWrapperRef, data.currentTransform, 0);
|
|
232
259
|
setElementTransform(knobRef, data.knobCurrentTransform, 0);
|
|
260
|
+
setIsSwiping(true);
|
|
233
261
|
};
|
|
234
262
|
const handlePointerUp = (e) => {
|
|
235
263
|
const endTime = Date.now();
|
|
@@ -256,6 +284,7 @@ const Carousel = (_a) => {
|
|
|
256
284
|
}
|
|
257
285
|
document.removeEventListener('pointermove', handlePointerMove);
|
|
258
286
|
document.removeEventListener('pointerup', handlePointerUp);
|
|
287
|
+
setIsSwiping(false);
|
|
259
288
|
};
|
|
260
289
|
const handleSlidesPointerDown = (e) => {
|
|
261
290
|
if (slidesWrapperRef.current && scrollbarRef.current && knobRef.current) {
|
|
@@ -271,6 +300,9 @@ const Carousel = (_a) => {
|
|
|
271
300
|
const handleScrollbarPointerDown = (e) => {
|
|
272
301
|
handleSlidesPointerDown(e);
|
|
273
302
|
};
|
|
303
|
+
const handlePointerDown = (e) => {
|
|
304
|
+
e.preventDefault();
|
|
305
|
+
};
|
|
274
306
|
useEffect(() => {
|
|
275
307
|
if (slidesWrapperRef.current && scrollbarRef.current) {
|
|
276
308
|
const isRest = Children.count(props.children) - (currentIndex + visibleItems) < 0;
|
|
@@ -307,7 +339,7 @@ const Carousel = (_a) => {
|
|
|
307
339
|
React__default.createElement(ButtonArrow, { direction: "left", "aria-label": "Previous", onClick: handleNavigationButtonPreviousClick, disabled: currentIndex <= 0 }),
|
|
308
340
|
React__default.createElement(ButtonArrow, { direction: "right", "aria-label": "Next", onClick: handleNavigationButtonNextClick, disabled: currentIndex + visibleItems >= Children.count(props.children) }))),
|
|
309
341
|
React__default.createElement(Content, { "data-testid": dataTestId && `${dataTestId}-content` },
|
|
310
|
-
React__default.createElement(SlidesWrapper, { ref: slidesWrapperRef, onPointerDown: handleSlidesPointerDown, gap: slidesWrapperGapSizePx / 16 }, Children.map(props.children, child => (React__default.createElement(SlideItem, { visibleItems: visibleItems, itemWidthCorrection: itemWidthCorrection }, child))))),
|
|
342
|
+
React__default.createElement(SlidesWrapper, { ref: slidesWrapperRef, onPointerDown: handleSlidesPointerDown, gap: slidesWrapperGapSizePx / 16 }, Children.map(props.children, child => (React__default.createElement(SlideItem, { visibleItems: visibleItems, itemWidthCorrection: itemWidthCorrection, isSwiping: isSwiping, onPointerDown: handlePointerDown }, child))))),
|
|
311
343
|
React__default.createElement(Footer, { "data-testid": dataTestId && `${dataTestId}-footer` },
|
|
312
344
|
React__default.createElement(Pagination, null, [...Array(slideScreensCount).keys()].map((value, index) => (React__default.createElement(PaginationItem, { key: value, "aria-label": `Move to step ${index + 1}`, "aria-current": index === currentIndex, isActive: index === currentIndex, onClick: handlePaginationItemClick })))),
|
|
313
345
|
React__default.createElement(Scrollbar, { ref: scrollbarRef, onPointerDown: handleScrollbarPointerDown },
|
|
@@ -218,19 +218,20 @@ const CheckboxAndRadioInputCore = styled.input `
|
|
|
218
218
|
|
|
219
219
|
&:disabled {
|
|
220
220
|
cursor: not-allowed;
|
|
221
|
-
color: ${theme.color.
|
|
222
|
-
|
|
223
|
-
|
|
221
|
+
color: ${theme.color.text.gray};
|
|
222
|
+
background-color: ${theme.color.line.L02};
|
|
223
|
+
border-color: ${theme.color.line.L01};
|
|
224
224
|
|
|
225
225
|
& + label {
|
|
226
226
|
cursor: not-allowed;
|
|
227
|
-
color: ${theme.color.text.
|
|
227
|
+
color: ${theme.color.text.gray};
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
&:disabled:checked {
|
|
232
232
|
color: ${theme.color.default.pink}${theme.color.transparency.T30};
|
|
233
233
|
border-color: ${theme.color.default.pink}${theme.color.transparency.T30};
|
|
234
|
+
background-color: ${theme.color.background.white.default};
|
|
234
235
|
}
|
|
235
236
|
`;
|
|
236
237
|
createGlobalStyle `
|