@dnanpm/styleguide 3.9.3 → 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.
@@ -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 visibleItems = props.visibleItems || (isMobile ? 1.2 : 1);
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;
@@ -293,9 +325,13 @@ const Carousel = (_a) => {
293
325
  data.lastItemX /
294
326
  (scrollbarRef.current.offsetWidth -
295
327
  scrollbarRef.current.offsetWidth / slideScreensCount);
296
- const slidesTransform = data.itemWidth * currentIndex +
297
- slidesWrapperGapSizePx * currentIndex -
298
- (isRest ? data.itemWidth * (visibleItems % 1) + slidesWrapperGapSizePx : 0);
328
+ let slidesTransform = 0;
329
+ if (React.Children.count(props.children) >= visibleItems) {
330
+ slidesTransform =
331
+ data.itemWidth * currentIndex +
332
+ slidesWrapperGapSizePx * currentIndex -
333
+ (isRest ? data.itemWidth * (visibleItems % 1) + slidesWrapperGapSizePx : 0);
334
+ }
299
335
  setElementTransform(slidesWrapperRef, -slidesTransform);
300
336
  setElementTransform(knobRef, slidesTransform / data.scrollbarToSlidesRatio);
301
337
  }
@@ -311,7 +347,7 @@ const Carousel = (_a) => {
311
347
  React__default.default.createElement(ButtonArrow.default, { direction: "left", "aria-label": "Previous", onClick: handleNavigationButtonPreviousClick, disabled: currentIndex <= 0 }),
312
348
  React__default.default.createElement(ButtonArrow.default, { direction: "right", "aria-label": "Next", onClick: handleNavigationButtonNextClick, disabled: currentIndex + visibleItems >= React.Children.count(props.children) }))),
313
349
  React__default.default.createElement(Content, { "data-testid": dataTestId && `${dataTestId}-content` },
314
- 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))))),
315
351
  React__default.default.createElement(Footer, { "data-testid": dataTestId && `${dataTestId}-footer` },
316
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 })))),
317
353
  React__default.default.createElement(Scrollbar, { ref: scrollbarRef, onPointerDown: handleScrollbarPointerDown },
@@ -41,6 +41,10 @@ interface Props {
41
41
  * Allows to pass a custom className
42
42
  */
43
43
  className?: string;
44
+ /**
45
+ * Allows to pass a custom aria-label for mobile dropdown button
46
+ */
47
+ dropdownButtonAriaLabel?: string;
44
48
  /**
45
49
  * Allows to pass testid string for testing purposes
46
50
  */
@@ -280,7 +280,9 @@ const PriorityNavigation = (_a) => {
280
280
  !isMobile && props.categoryLabel && React__default.default.createElement(Category, null, props.categoryLabel),
281
281
  React__default.default.createElement("nav", { "aria-label": props.navigationLabel },
282
282
  React__default.default.createElement(ListsContainer, { ref: listsContainerRef },
283
- isMobile && selectedItem && (React__default.default.createElement(MobileDropdown, { onClick: toggleMobileNavigation, "aria-label": props.categoryLabel && selectedItem, isCategoryLabel: Boolean(props.categoryLabel) },
283
+ isMobile && selectedItem && (React__default.default.createElement(MobileDropdown, { onClick: toggleMobileNavigation, "aria-label": (props.categoryLabel && selectedItem) ||
284
+ (props.dropdownButtonAriaLabel &&
285
+ `${props.dropdownButtonAriaLabel}: ${selectedItem}`), "aria-expanded": isMobileNavigationOpen, isCategoryLabel: Boolean(props.categoryLabel) },
284
286
  React__default.default.createElement(MobileDropdownContent, null,
285
287
  props.categoryLabel && React__default.default.createElement(Category, null, props.categoryLabel),
286
288
  selectedItem),
@@ -220,19 +220,20 @@ const CheckboxAndRadioInputCore = styled.default.input `
220
220
 
221
221
  &:disabled {
222
222
  cursor: not-allowed;
223
- color: ${theme.default.color.line.L01}${theme.default.color.transparency.T30};
224
- border-color: ${theme.default.color.line.L01}${theme.default.color.transparency.T30};
225
- background-color: ${theme.default.color.background.white.default}${theme.default.color.transparency.T30};
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.black}${theme.default.color.transparency.T30};
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, useEffect } from 'react';
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 visibleItems = props.visibleItems || (isMobile ? 1.2 : 1);
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;
@@ -285,9 +317,13 @@ const Carousel = (_a) => {
285
317
  data.lastItemX /
286
318
  (scrollbarRef.current.offsetWidth -
287
319
  scrollbarRef.current.offsetWidth / slideScreensCount);
288
- const slidesTransform = data.itemWidth * currentIndex +
289
- slidesWrapperGapSizePx * currentIndex -
290
- (isRest ? data.itemWidth * (visibleItems % 1) + slidesWrapperGapSizePx : 0);
320
+ let slidesTransform = 0;
321
+ if (Children.count(props.children) >= visibleItems) {
322
+ slidesTransform =
323
+ data.itemWidth * currentIndex +
324
+ slidesWrapperGapSizePx * currentIndex -
325
+ (isRest ? data.itemWidth * (visibleItems % 1) + slidesWrapperGapSizePx : 0);
326
+ }
291
327
  setElementTransform(slidesWrapperRef, -slidesTransform);
292
328
  setElementTransform(knobRef, slidesTransform / data.scrollbarToSlidesRatio);
293
329
  }
@@ -303,7 +339,7 @@ const Carousel = (_a) => {
303
339
  React__default.createElement(ButtonArrow, { direction: "left", "aria-label": "Previous", onClick: handleNavigationButtonPreviousClick, disabled: currentIndex <= 0 }),
304
340
  React__default.createElement(ButtonArrow, { direction: "right", "aria-label": "Next", onClick: handleNavigationButtonNextClick, disabled: currentIndex + visibleItems >= Children.count(props.children) }))),
305
341
  React__default.createElement(Content, { "data-testid": dataTestId && `${dataTestId}-content` },
306
- 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))))),
307
343
  React__default.createElement(Footer, { "data-testid": dataTestId && `${dataTestId}-footer` },
308
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 })))),
309
345
  React__default.createElement(Scrollbar, { ref: scrollbarRef, onPointerDown: handleScrollbarPointerDown },
@@ -41,6 +41,10 @@ interface Props {
41
41
  * Allows to pass a custom className
42
42
  */
43
43
  className?: string;
44
+ /**
45
+ * Allows to pass a custom aria-label for mobile dropdown button
46
+ */
47
+ dropdownButtonAriaLabel?: string;
44
48
  /**
45
49
  * Allows to pass testid string for testing purposes
46
50
  */
@@ -272,7 +272,9 @@ const PriorityNavigation = (_a) => {
272
272
  !isMobile && props.categoryLabel && React__default.createElement(Category, null, props.categoryLabel),
273
273
  React__default.createElement("nav", { "aria-label": props.navigationLabel },
274
274
  React__default.createElement(ListsContainer, { ref: listsContainerRef },
275
- isMobile && selectedItem && (React__default.createElement(MobileDropdown, { onClick: toggleMobileNavigation, "aria-label": props.categoryLabel && selectedItem, isCategoryLabel: Boolean(props.categoryLabel) },
275
+ isMobile && selectedItem && (React__default.createElement(MobileDropdown, { onClick: toggleMobileNavigation, "aria-label": (props.categoryLabel && selectedItem) ||
276
+ (props.dropdownButtonAriaLabel &&
277
+ `${props.dropdownButtonAriaLabel}: ${selectedItem}`), "aria-expanded": isMobileNavigationOpen, isCategoryLabel: Boolean(props.categoryLabel) },
276
278
  React__default.createElement(MobileDropdownContent, null,
277
279
  props.categoryLabel && React__default.createElement(Category, null, props.categoryLabel),
278
280
  selectedItem),
@@ -218,19 +218,20 @@ const CheckboxAndRadioInputCore = styled.input `
218
218
 
219
219
  &:disabled {
220
220
  cursor: not-allowed;
221
- color: ${theme.color.line.L01}${theme.color.transparency.T30};
222
- border-color: ${theme.color.line.L01}${theme.color.transparency.T30};
223
- background-color: ${theme.color.background.white.default}${theme.color.transparency.T30};
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.black}${theme.color.transparency.T30};
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 `
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dnanpm/styleguide",
3
3
  "sideEffects": false,
4
- "version": "v3.9.3",
4
+ "version": "v3.9.5",
5
5
  "main": "build/cjs/index.js",
6
6
  "module": "build/es/index.js",
7
7
  "jsnext:main": "build/es/index.js",