@hh.ru/magritte-ui-scrollable-container 6.4.10 → 6.5.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.
@@ -11,7 +11,7 @@ import { ScrollableContainerGallery } from './ScrollableContainerGallery.js';
11
11
  import { ScrollableItem } from './ScrollableItem.js';
12
12
  import { useScrollableControlsWithState } from './useScrollableControls.js';
13
13
  import { getActualCorrection, useInitOnce } from './utils.js';
14
- import { s as styles } from './scrollableContainer-C7JpsOHd.js';
14
+ import { s as styles } from './scrollableContainer-DFe-eO3O.js';
15
15
  import 'motion/react';
16
16
  import './ObservableValue.js';
17
17
  import '@hh.ru/magritte-common-use-translation';
@@ -9,7 +9,7 @@ import { ChevronLeftOutlinedSize24, ChevronRightOutlinedSize24 } from '@hh.ru/ma
9
9
  import { useScrollState } from './ScrollStateProvider.js';
10
10
  import { ScrollableContainerLeft, ScrollableContainerRight } from './ScrollableContainerButton.js';
11
11
  import { BREAKPOINTS_LIST, NO_BUTTONS_START_FROM_BREAKPOINT, useInitOnce } from './utils.js';
12
- import { s as styles } from './scrollableContainer-C7JpsOHd.js';
12
+ import { s as styles } from './scrollableContainer-DFe-eO3O.js';
13
13
  import './ObservableValue.js';
14
14
  import './useScrollableControls.js';
15
15
  import '@hh.ru/magritte-internal-custom-scroll';
@@ -19,7 +19,7 @@ const SIZE_CONFIG = {
19
19
  medium: { padding: 8, buttonWidth: 44, minHeight: 40 },
20
20
  small: { padding: 4, buttonWidth: 36, minHeight: 32 },
21
21
  };
22
- const ScrollableContainerDefaultLayout = ({ children, size = 'medium', fadeOnMobile = false, leftButtonAriaLabel: _leftAriaLabel, rightButtonAriaLabel: _rightAriaLabel, leftAriaControls, rightAriaControls, }) => {
22
+ const ScrollableContainerDefaultLayout = ({ children, size = 'medium', fadeOnMobile = false, noFadeOnDesktop = false, buttonsOffset = 0, buttonsOnHover = false, leftButtonAriaLabel: _leftAriaLabel, rightButtonAriaLabel: _rightAriaLabel, leftAriaControls, rightAriaControls, }) => {
23
23
  const { padding: buttonPadding, buttonWidth: buttonWidthCorrection, minHeight } = SIZE_CONFIG[size];
24
24
  const scrollState = useScrollState();
25
25
  const displayLeftButton = useMotionValue('none');
@@ -29,7 +29,7 @@ const ScrollableContainerDefaultLayout = ({ children, size = 'medium', fadeOnMob
29
29
  const breakpointIndex = BREAKPOINTS_LIST.indexOf(breakpoint.breakpoint);
30
30
  const noButtonBreakpointIndex = BREAKPOINTS_LIST.indexOf(NO_BUTTONS_START_FROM_BREAKPOINT);
31
31
  const enableDefaultButtonsByBreakpoint = breakpointIndex > noButtonBreakpointIndex;
32
- const showFade = enableDefaultButtonsByBreakpoint || fadeOnMobile;
32
+ const showFade = enableDefaultButtonsByBreakpoint ? !noFadeOnDesktop : fadeOnMobile;
33
33
  const leftAriaLabelTrl = useTranslation('ScrollableContainer', 'left');
34
34
  const leftButtonAriaLabel = _leftAriaLabel ?? leftAriaLabelTrl;
35
35
  const rightAriaLabelTrl = useTranslation('ScrollableContainer', 'right');
@@ -67,12 +67,18 @@ const ScrollableContainerDefaultLayout = ({ children, size = 'medium', fadeOnMob
67
67
  };
68
68
  }, [scrollState, updateFadeAndButtons]);
69
69
  useEffect(() => {
70
- scrollState.defaultButtonsCorrection.set(enableDefaultButtonsByBreakpoint ? buttonWidthCorrection : 0);
70
+ // кнопка закрывает край контента на свою ширину плюс отступ от края
71
+ scrollState.defaultButtonsCorrection.set(enableDefaultButtonsByBreakpoint ? buttonWidthCorrection + buttonsOffset : 0);
71
72
  return () => {
72
73
  scrollState.defaultButtonsCorrection.set(0);
73
74
  };
74
- }, [scrollState, enableDefaultButtonsByBreakpoint, buttonWidthCorrection]);
75
- return (jsxs("div", { className: styles.scrollButtonsContainer, style: { '--magritte-ui-scrollable-container-min-height': `${minHeight}px` }, children: [jsx(motion.div, { className: classnames(styles.scrollButton, styles.scrollButtonLeft), style: { display: enableDefaultButtonsByBreakpoint ? displayLeftButton : 'none' }, children: jsx(ScrollableContainerLeft, { children: jsx(ChevronLeftOutlinedSize24, { padding: buttonPadding, borderRadius: "halfHeight", initialColor: "secondary", backgroundStyle: "secondary", "aria-label": leftButtonAriaLabel, "aria-controls": leftAriaControls }) }) }), jsx(motion.div, { className: classnames(styles.scrollButtons, {
75
+ }, [scrollState, enableDefaultButtonsByBreakpoint, buttonWidthCorrection, buttonsOffset]);
76
+ return (jsxs("div", { className: classnames(styles.scrollButtonsContainer, {
77
+ [styles.scrollButtonsContainerOnHover]: buttonsOnHover,
78
+ }), style: {
79
+ '--magritte-ui-scrollable-container-min-height': `${minHeight}px`,
80
+ '--magritte-ui-scrollable-container-buttons-offset': `${buttonsOffset}px`,
81
+ }, children: [jsx(motion.div, { className: classnames(styles.scrollButton, styles.scrollButtonLeft), style: { display: enableDefaultButtonsByBreakpoint ? displayLeftButton : 'none' }, children: jsx(ScrollableContainerLeft, { children: jsx(ChevronLeftOutlinedSize24, { padding: buttonPadding, borderRadius: "halfHeight", initialColor: "secondary", backgroundStyle: "secondary", "aria-label": leftButtonAriaLabel, "aria-controls": leftAriaControls }) }) }), jsx(motion.div, { className: classnames(styles.scrollButtons, {
76
82
  [styles.scrollButtonsSmall]: size === 'small',
77
83
  }), style: {
78
84
  WebkitMask: showFade ? mask : 'none',
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollableContainerDefaultLayout.js","sources":["src/ScrollableContainerDefaultLayout.tsx"],"sourcesContent":["import { type CSSProperties, type FC, useEffect } from 'react';\nimport classnames from 'classnames';\nimport { useMotionValue, motion } from 'motion/react';\n\nimport { useTranslation } from '@hh.ru/magritte-common-use-translation';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { ChevronRightOutlinedSize24, ChevronLeftOutlinedSize24 } from '@hh.ru/magritte-ui-icon/icon';\nimport { useScrollState } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport {\n ScrollableContainerLeft,\n ScrollableContainerRight,\n} from '@hh.ru/magritte-ui-scrollable-container/ScrollableContainerButton';\nimport type { ScrollableContainerDefaultLayoutProps } from '@hh.ru/magritte-ui-scrollable-container/types';\nimport {\n BREAKPOINTS_LIST,\n NO_BUTTONS_START_FROM_BREAKPOINT,\n useInitOnce,\n} from '@hh.ru/magritte-ui-scrollable-container/utils';\n\nimport styles from './scrollableContainer.less';\n\nconst SIZE_CONFIG = {\n medium: { padding: 8, buttonWidth: 44, minHeight: 40 },\n small: { padding: 4, buttonWidth: 36, minHeight: 32 },\n} as const;\n\nexport const ScrollableContainerDefaultLayout: FC<ScrollableContainerDefaultLayoutProps> = ({\n children,\n size = 'medium',\n fadeOnMobile = false,\n leftButtonAriaLabel: _leftAriaLabel,\n rightButtonAriaLabel: _rightAriaLabel,\n leftAriaControls,\n rightAriaControls,\n}) => {\n const { padding: buttonPadding, buttonWidth: buttonWidthCorrection, minHeight } = SIZE_CONFIG[size];\n const scrollState = useScrollState();\n const displayLeftButton = useMotionValue<'none' | 'block'>('none');\n const displayRightButton = useMotionValue<'none' | 'block'>('none');\n const mask = useMotionValue<string | number>('none');\n\n const breakpoint = useBreakpoint();\n const breakpointIndex = BREAKPOINTS_LIST.indexOf(breakpoint.breakpoint);\n const noButtonBreakpointIndex = BREAKPOINTS_LIST.indexOf(NO_BUTTONS_START_FROM_BREAKPOINT);\n const enableDefaultButtonsByBreakpoint = breakpointIndex > noButtonBreakpointIndex;\n const showFade = enableDefaultButtonsByBreakpoint || fadeOnMobile;\n\n const leftAriaLabelTrl = useTranslation('ScrollableContainer', 'left');\n const leftButtonAriaLabel = _leftAriaLabel ?? leftAriaLabelTrl;\n const rightAriaLabelTrl = useTranslation('ScrollableContainer', 'right');\n const rightButtonAriaLabel = _rightAriaLabel ?? rightAriaLabelTrl;\n\n const updateFadeAndButtons = useInitOnce(() => () => {\n const position = scrollState.scrollPosition.get();\n const contentWidth = scrollState.contentWidth.get();\n const viewportWidth = scrollState.viewportWidth.get();\n\n const showLeftButton = position < 0;\n const showRightButton = Math.abs(position) < Math.max(0, contentWidth - viewportWidth);\n\n displayLeftButton.set(showLeftButton ? 'block' : 'none');\n displayRightButton.set(showRightButton ? 'block' : 'none');\n\n if (showLeftButton && showRightButton) {\n mask.set('var(--both-sides-mask)');\n } else if (showLeftButton) {\n mask.set('var(--left-fade-mask)');\n } else if (showRightButton) {\n mask.set('var(--right-fade-mask)');\n } else {\n mask.set('none');\n }\n });\n\n useEffect(() => {\n updateFadeAndButtons();\n const unsubscribe = [\n scrollState.scrollPosition.on('change', updateFadeAndButtons),\n scrollState.contentWidth.on('change', updateFadeAndButtons),\n scrollState.viewportWidth.on('change', updateFadeAndButtons),\n ];\n return () => {\n unsubscribe.forEach((fn) => fn());\n };\n }, [scrollState, updateFadeAndButtons]);\n\n useEffect(() => {\n scrollState.defaultButtonsCorrection.set(enableDefaultButtonsByBreakpoint ? buttonWidthCorrection : 0);\n return () => {\n scrollState.defaultButtonsCorrection.set(0);\n };\n }, [scrollState, enableDefaultButtonsByBreakpoint, buttonWidthCorrection]);\n\n return (\n <div\n className={styles.scrollButtonsContainer}\n style={{ '--magritte-ui-scrollable-container-min-height': `${minHeight}px` } as CSSProperties}\n >\n <motion.div\n className={classnames(styles.scrollButton, styles.scrollButtonLeft)}\n style={{ display: enableDefaultButtonsByBreakpoint ? displayLeftButton : 'none' }}\n >\n <ScrollableContainerLeft>\n <ChevronLeftOutlinedSize24\n padding={buttonPadding}\n borderRadius=\"halfHeight\"\n initialColor=\"secondary\"\n backgroundStyle=\"secondary\"\n aria-label={leftButtonAriaLabel}\n aria-controls={leftAriaControls}\n />\n </ScrollableContainerLeft>\n </motion.div>\n <motion.div\n className={classnames(styles.scrollButtons, {\n [styles.scrollButtonsSmall]: size === 'small',\n })}\n style={{\n WebkitMask: showFade ? mask : 'none',\n mask: showFade ? mask : 'none',\n }}\n data-qa=\"scrollable-container__fade\"\n >\n {children}\n </motion.div>\n <motion.div\n className={classnames(styles.scrollButton, styles.scrollButtonRight)}\n style={{ display: enableDefaultButtonsByBreakpoint ? displayRightButton : 'none' }}\n >\n <ScrollableContainerRight>\n <ChevronRightOutlinedSize24\n padding={buttonPadding}\n borderRadius=\"halfHeight\"\n initialColor=\"secondary\"\n backgroundStyle=\"secondary\"\n aria-label={rightButtonAriaLabel}\n aria-controls={rightAriaControls}\n />\n </ScrollableContainerRight>\n </motion.div>\n </div>\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"ScrollableContainerDefaultLayout.js","sources":["src/ScrollableContainerDefaultLayout.tsx"],"sourcesContent":["import { type CSSProperties, type FC, useEffect } from 'react';\nimport classnames from 'classnames';\nimport { useMotionValue, motion } from 'motion/react';\n\nimport { useTranslation } from '@hh.ru/magritte-common-use-translation';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { ChevronRightOutlinedSize24, ChevronLeftOutlinedSize24 } from '@hh.ru/magritte-ui-icon/icon';\nimport { useScrollState } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport {\n ScrollableContainerLeft,\n ScrollableContainerRight,\n} from '@hh.ru/magritte-ui-scrollable-container/ScrollableContainerButton';\nimport type { ScrollableContainerDefaultLayoutProps } from '@hh.ru/magritte-ui-scrollable-container/types';\nimport {\n BREAKPOINTS_LIST,\n NO_BUTTONS_START_FROM_BREAKPOINT,\n useInitOnce,\n} from '@hh.ru/magritte-ui-scrollable-container/utils';\n\nimport styles from './scrollableContainer.less';\n\nconst SIZE_CONFIG = {\n medium: { padding: 8, buttonWidth: 44, minHeight: 40 },\n small: { padding: 4, buttonWidth: 36, minHeight: 32 },\n} as const;\n\nexport const ScrollableContainerDefaultLayout: FC<ScrollableContainerDefaultLayoutProps> = ({\n children,\n size = 'medium',\n fadeOnMobile = false,\n noFadeOnDesktop = false,\n buttonsOffset = 0,\n buttonsOnHover = false,\n leftButtonAriaLabel: _leftAriaLabel,\n rightButtonAriaLabel: _rightAriaLabel,\n leftAriaControls,\n rightAriaControls,\n}) => {\n const { padding: buttonPadding, buttonWidth: buttonWidthCorrection, minHeight } = SIZE_CONFIG[size];\n const scrollState = useScrollState();\n const displayLeftButton = useMotionValue<'none' | 'block'>('none');\n const displayRightButton = useMotionValue<'none' | 'block'>('none');\n const mask = useMotionValue<string | number>('none');\n\n const breakpoint = useBreakpoint();\n const breakpointIndex = BREAKPOINTS_LIST.indexOf(breakpoint.breakpoint);\n const noButtonBreakpointIndex = BREAKPOINTS_LIST.indexOf(NO_BUTTONS_START_FROM_BREAKPOINT);\n const enableDefaultButtonsByBreakpoint = breakpointIndex > noButtonBreakpointIndex;\n const showFade = enableDefaultButtonsByBreakpoint ? !noFadeOnDesktop : fadeOnMobile;\n\n const leftAriaLabelTrl = useTranslation('ScrollableContainer', 'left');\n const leftButtonAriaLabel = _leftAriaLabel ?? leftAriaLabelTrl;\n const rightAriaLabelTrl = useTranslation('ScrollableContainer', 'right');\n const rightButtonAriaLabel = _rightAriaLabel ?? rightAriaLabelTrl;\n\n const updateFadeAndButtons = useInitOnce(() => () => {\n const position = scrollState.scrollPosition.get();\n const contentWidth = scrollState.contentWidth.get();\n const viewportWidth = scrollState.viewportWidth.get();\n\n const showLeftButton = position < 0;\n const showRightButton = Math.abs(position) < Math.max(0, contentWidth - viewportWidth);\n\n displayLeftButton.set(showLeftButton ? 'block' : 'none');\n displayRightButton.set(showRightButton ? 'block' : 'none');\n\n if (showLeftButton && showRightButton) {\n mask.set('var(--both-sides-mask)');\n } else if (showLeftButton) {\n mask.set('var(--left-fade-mask)');\n } else if (showRightButton) {\n mask.set('var(--right-fade-mask)');\n } else {\n mask.set('none');\n }\n });\n\n useEffect(() => {\n updateFadeAndButtons();\n const unsubscribe = [\n scrollState.scrollPosition.on('change', updateFadeAndButtons),\n scrollState.contentWidth.on('change', updateFadeAndButtons),\n scrollState.viewportWidth.on('change', updateFadeAndButtons),\n ];\n return () => {\n unsubscribe.forEach((fn) => fn());\n };\n }, [scrollState, updateFadeAndButtons]);\n\n useEffect(() => {\n // кнопка закрывает край контента на свою ширину плюс отступ от края\n scrollState.defaultButtonsCorrection.set(\n enableDefaultButtonsByBreakpoint ? buttonWidthCorrection + buttonsOffset : 0\n );\n return () => {\n scrollState.defaultButtonsCorrection.set(0);\n };\n }, [scrollState, enableDefaultButtonsByBreakpoint, buttonWidthCorrection, buttonsOffset]);\n\n return (\n <div\n className={classnames(styles.scrollButtonsContainer, {\n [styles.scrollButtonsContainerOnHover]: buttonsOnHover,\n })}\n style={\n {\n '--magritte-ui-scrollable-container-min-height': `${minHeight}px`,\n '--magritte-ui-scrollable-container-buttons-offset': `${buttonsOffset}px`,\n } as CSSProperties\n }\n >\n <motion.div\n className={classnames(styles.scrollButton, styles.scrollButtonLeft)}\n style={{ display: enableDefaultButtonsByBreakpoint ? displayLeftButton : 'none' }}\n >\n <ScrollableContainerLeft>\n <ChevronLeftOutlinedSize24\n padding={buttonPadding}\n borderRadius=\"halfHeight\"\n initialColor=\"secondary\"\n backgroundStyle=\"secondary\"\n aria-label={leftButtonAriaLabel}\n aria-controls={leftAriaControls}\n />\n </ScrollableContainerLeft>\n </motion.div>\n <motion.div\n className={classnames(styles.scrollButtons, {\n [styles.scrollButtonsSmall]: size === 'small',\n })}\n style={{\n WebkitMask: showFade ? mask : 'none',\n mask: showFade ? mask : 'none',\n }}\n data-qa=\"scrollable-container__fade\"\n >\n {children}\n </motion.div>\n <motion.div\n className={classnames(styles.scrollButton, styles.scrollButtonRight)}\n style={{ display: enableDefaultButtonsByBreakpoint ? displayRightButton : 'none' }}\n >\n <ScrollableContainerRight>\n <ChevronRightOutlinedSize24\n padding={buttonPadding}\n borderRadius=\"halfHeight\"\n initialColor=\"secondary\"\n backgroundStyle=\"secondary\"\n aria-label={rightButtonAriaLabel}\n aria-controls={rightAriaControls}\n />\n </ScrollableContainerRight>\n </motion.div>\n </div>\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -7,7 +7,7 @@ import { useScrollState } from './ScrollStateProvider.js';
7
7
  import { OFFSET_ATTR } from './types.js';
8
8
  import { useInitOnce, findIndexNearestToSnapPoint } from './utils.js';
9
9
  import { VSpacing } from '@hh.ru/magritte-ui-spacing';
10
- import { s as styles } from './scrollableContainer-C7JpsOHd.js';
10
+ import { s as styles } from './scrollableContainer-DFe-eO3O.js';
11
11
  import 'motion/react';
12
12
  import './ObservableValue.js';
13
13
  import '@hh.ru/magritte-internal-custom-scroll';
@@ -6,7 +6,7 @@ import { clamp } from '@hh.ru/magritte-internal-custom-scroll/initScrollHandlers
6
6
  import { useScrollState } from './ScrollStateProvider.js';
7
7
  import { useScrollContainer } from './useScrollContainer.js';
8
8
  import { getDisableState, findIndexNearestToSnapPoint, computeScrollSnapBehavior } from './utils.js';
9
- import { s as styles } from './scrollableContainer-C7JpsOHd.js';
9
+ import { s as styles } from './scrollableContainer-DFe-eO3O.js';
10
10
  import './ObservableValue.js';
11
11
  import '@hh.ru/magritte-common-func-utils';
12
12
  import '@hh.ru/magritte-internal-custom-scroll';
package/ScrollableItem.js CHANGED
@@ -13,7 +13,7 @@ import '@hh.ru/magritte-internal-custom-scroll';
13
13
  import './types.js';
14
14
  import './utils.js';
15
15
  import '@hh.ru/magritte-ui-breakpoint';
16
- import './scrollableContainer-C7JpsOHd.js';
16
+ import './scrollableContainer-DFe-eO3O.js';
17
17
 
18
18
  const ScrollableItem = ({ children, scrollToItemOnFocus, ...props }) => {
19
19
  const ref = useRef(null);
package/index.css CHANGED
@@ -1,17 +1,22 @@
1
1
  :root{
2
- --magritte-gradient-component-chat-input-background-fade-v25-1-0:#ffffff00 0%, #ffffff 100%;
2
+ --magritte-gradient-component-chat-input-background-fade-v25-1-1:#ffffff00 0%, #ffffff 100%;
3
+ }
4
+
5
+ :root{
6
+ --magritte-semantic-animation-time-s-duration-v25-1-1:200ms;
3
7
  }
4
8
 
5
9
  .magritte-night-theme{
6
- --magritte-gradient-component-chat-input-background-fade-v25-1-0:#1b1b1b00 0%, #1b1b1b 100%;
10
+ --magritte-gradient-component-chat-input-background-fade-v25-1-1:#1b1b1b00 0%, #1b1b1b 100%;
7
11
  }
8
- .magritte-scroll-wrapper___vTdZl_6-4-10{
12
+ .magritte-scroll-wrapper___vTdZl_6-5-1{
9
13
  position:relative;
10
14
  touch-action:pan-y pinch-zoom;
11
15
  contain:layout;
12
16
  }
13
- .magritte-scrollable-container___AKIUp_6-4-10{
17
+ .magritte-scrollable-container___AKIUp_6-5-1{
14
18
  display:block;
19
+ isolation:isolate;
15
20
  overflow-x:hidden;
16
21
  overflow-x:clip;
17
22
  overflow-y:visible;
@@ -26,41 +31,56 @@
26
31
  margin-left:var(--magritte-ui-scrollabe-container-ml, -4px);
27
32
  margin-right:var(--magritte-ui-scrollabe-container-mr, -4px);
28
33
  }
29
- .magritte-scroll-buttons-container___ZeI5a_6-4-10{
34
+ .magritte-scroll-buttons-container___ZeI5a_6-5-1{
30
35
  position:relative;
31
36
  }
32
- .magritte-scroll-buttons___0SjoR_6-4-10{
33
- --fade-left:linear-gradient(90deg, var(--magritte-gradient-component-chat-input-background-fade-v25-1-0));
34
- --fade-right:linear-gradient(270deg, var(--magritte-gradient-component-chat-input-background-fade-v25-1-0));
37
+ .magritte-scroll-buttons-container-on-hover___PFUvV_6-5-1 .magritte-scroll-button___4GQu3_6-5-1{
38
+ opacity:0;
39
+ pointer-events:none;
40
+ transition:opacity var(--magritte-semantic-animation-time-s-duration-v25-1-1) ease-in-out;
41
+ }
42
+ .magritte-scroll-buttons-container-on-hover___PFUvV_6-5-1 .magritte-scroll-button___4GQu3_6-5-1:focus-within{
43
+ opacity:1;
44
+ pointer-events:auto;
45
+ }
46
+ @media (hover: hover){
47
+ .magritte-scroll-buttons-container-on-hover___PFUvV_6-5-1:hover .magritte-scroll-button___4GQu3_6-5-1{
48
+ opacity:1;
49
+ pointer-events:auto;
50
+ }
51
+ }
52
+ .magritte-scroll-buttons___0SjoR_6-5-1{
53
+ --fade-left:linear-gradient(90deg, var(--magritte-gradient-component-chat-input-background-fade-v25-1-1));
54
+ --fade-right:linear-gradient(270deg, var(--magritte-gradient-component-chat-input-background-fade-v25-1-1));
35
55
  --left-fade-mask:var(--fade-left) 30px 0 / 128px 100% no-repeat, linear-gradient(#000, #000) right / calc(100% - 158px) 100% no-repeat;
36
56
  --right-fade-mask:var(--fade-right) calc(100% - 30px) 0 / 128px 100% no-repeat, linear-gradient(#000, #000) left / calc(100% - 158px) 100% no-repeat;
37
57
  --both-sides-mask:var(--fade-left) 30px 0 / 128px 100% no-repeat, var(--fade-right) calc(100% - 30px) 0 / 128px 100% no-repeat, linear-gradient(#000, #000) center / calc(100% - 158px - 158px) 100% no-repeat;
38
58
  -webkit-mask:none;
39
59
  mask:none;
40
60
  }
41
- .magritte-scroll-buttons-small___xG3MS_6-4-10{
61
+ .magritte-scroll-buttons-small___xG3MS_6-5-1{
42
62
  --left-fade-mask:var(--fade-left) 0px 0 / 44px 100% no-repeat, linear-gradient(#000, #000) right / calc(100% - 44px) 100% no-repeat;
43
63
  --right-fade-mask:var(--fade-right) calc(100% - 0px) 0 / 44px 100% no-repeat, linear-gradient(#000, #000) left / calc(100% - 44px) 100% no-repeat;
44
64
  --both-sides-mask:var(--fade-left) 0px 0 / 44px 100% no-repeat, var(--fade-right) calc(100% - 0px) 0 / 44px 100% no-repeat, linear-gradient(#000, #000) center / calc(100% - 44px - 44px) 100% no-repeat;
45
65
  }
46
- .magritte-scroll-button___4GQu3_6-4-10{
66
+ .magritte-scroll-button___4GQu3_6-5-1{
47
67
  display:none;
48
68
  position:absolute;
49
69
  top:50%;
50
70
  transform:translateY(-50%);
51
71
  }
52
- .magritte-scroll-button-left___UueEY_6-4-10{
72
+ .magritte-scroll-button-left___UueEY_6-5-1{
53
73
  z-index:1;
54
- left:0;
74
+ left:var(--magritte-ui-scrollable-container-buttons-offset, 0);
55
75
  }
56
- .magritte-scroll-button-right___wZOn-_6-4-10{
57
- right:0;
76
+ .magritte-scroll-button-right___wZOn-_6-5-1{
77
+ right:var(--magritte-ui-scrollable-container-buttons-offset, 0);
58
78
  }
59
- .magritte-position-container___1A4Bv_6-4-10{
79
+ .magritte-position-container___1A4Bv_6-5-1{
60
80
  box-sizing:border-box;
61
81
  width:100%;
62
82
  }
63
- .magritte-dot-container___ahtlG_6-4-10{
83
+ .magritte-dot-container___ahtlG_6-5-1{
64
84
  display:flex;
65
85
  justify-content:center;
66
86
  }
package/index.js CHANGED
@@ -13,7 +13,7 @@ import './ScrollableContainerDefaultLayout.js';
13
13
  import 'motion/react';
14
14
  import '@hh.ru/magritte-common-use-translation';
15
15
  import '@hh.ru/magritte-ui-icon/icon';
16
- import './scrollableContainer-C7JpsOHd.js';
16
+ import './scrollableContainer-DFe-eO3O.js';
17
17
  import './ScrollableContainerDotPages.js';
18
18
  import '@hh.ru/magritte-internal-custom-scroll/initScrollHandlers';
19
19
  import '@hh.ru/magritte-ui-dot-pages';
package/index.mock.js CHANGED
@@ -13,7 +13,7 @@ import 'react/jsx-runtime';
13
13
  import '@hh.ru/magritte-internal-custom-scroll/initScrollHandlers';
14
14
  import './useScrollContainer.js';
15
15
  import '@hh.ru/magritte-common-func-utils';
16
- import './scrollableContainer-C7JpsOHd.js';
16
+ import './scrollableContainer-DFe-eO3O.js';
17
17
  import './ObservableValue.js';
18
18
 
19
19
  const staticProps = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hh.ru/magritte-ui-scrollable-container",
3
- "version": "6.4.10",
3
+ "version": "6.5.1",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "sideEffects": [
@@ -12,22 +12,22 @@
12
12
  "prepack": "yarn root:prepack $(pwd)",
13
13
  "postpublish": "yarn root:postpublish $(pwd)",
14
14
  "stylelint-check": "yarn root:stylelint-check $(pwd)",
15
- "eslint-check": "yarn root:eslint-check $(pwd)",
15
+ "lint-check": "yarn root:lint-check $(pwd)",
16
16
  "ts-config": "yarn root:ts-config $(pwd)",
17
17
  "ts-check": "yarn root:ts-check $(pwd)",
18
18
  "test": "yarn root:test $(pwd)",
19
19
  "watch": "yarn root:watch $(pwd)"
20
20
  },
21
21
  "dependencies": {
22
- "@hh.ru/magritte-common-func-utils": "1.3.15",
23
- "@hh.ru/magritte-common-use-translation": "3.5.0",
24
- "@hh.ru/magritte-design-tokens": "25.1.0",
25
- "@hh.ru/magritte-internal-custom-scroll": "2.1.1",
26
- "@hh.ru/magritte-ui-breakpoint": "6.1.1",
27
- "@hh.ru/magritte-ui-dot-pages": "4.0.34",
28
- "@hh.ru/magritte-ui-icon": "15.1.2",
29
- "@hh.ru/magritte-ui-mock-component": "1.1.7",
30
- "@hh.ru/magritte-ui-spacing": "2.1.28"
22
+ "@hh.ru/magritte-common-func-utils": "1.3.16",
23
+ "@hh.ru/magritte-common-use-translation": "3.6.1",
24
+ "@hh.ru/magritte-design-tokens": "25.1.1",
25
+ "@hh.ru/magritte-internal-custom-scroll": "2.1.2",
26
+ "@hh.ru/magritte-ui-breakpoint": "6.1.2",
27
+ "@hh.ru/magritte-ui-dot-pages": "4.0.35",
28
+ "@hh.ru/magritte-ui-icon": "15.1.3",
29
+ "@hh.ru/magritte-ui-mock-component": "1.1.8",
30
+ "@hh.ru/magritte-ui-spacing": "2.1.29"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "classnames": ">=2.3.2",
@@ -37,5 +37,5 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "37c822e9d543ad23d6aec07b4a18c6d2d2b3ee3a"
40
+ "gitHead": "46d606980abbb523a41afba452c0a852ee902864"
41
41
  }
@@ -0,0 +1,5 @@
1
+ import './index.css';
2
+ var styles = {"scroll-wrapper":"magritte-scroll-wrapper___vTdZl_6-5-1","scrollWrapper":"magritte-scroll-wrapper___vTdZl_6-5-1","scrollable-container":"magritte-scrollable-container___AKIUp_6-5-1","scrollableContainer":"magritte-scrollable-container___AKIUp_6-5-1","scroll-buttons-container":"magritte-scroll-buttons-container___ZeI5a_6-5-1","scrollButtonsContainer":"magritte-scroll-buttons-container___ZeI5a_6-5-1","scroll-buttons-container-on-hover":"magritte-scroll-buttons-container-on-hover___PFUvV_6-5-1","scrollButtonsContainerOnHover":"magritte-scroll-buttons-container-on-hover___PFUvV_6-5-1","scroll-button":"magritte-scroll-button___4GQu3_6-5-1","scrollButton":"magritte-scroll-button___4GQu3_6-5-1","scroll-buttons":"magritte-scroll-buttons___0SjoR_6-5-1","scrollButtons":"magritte-scroll-buttons___0SjoR_6-5-1","scroll-buttons-small":"magritte-scroll-buttons-small___xG3MS_6-5-1","scrollButtonsSmall":"magritte-scroll-buttons-small___xG3MS_6-5-1","scroll-button-left":"magritte-scroll-button-left___UueEY_6-5-1","scrollButtonLeft":"magritte-scroll-button-left___UueEY_6-5-1","scroll-button-right":"magritte-scroll-button-right___wZOn-_6-5-1","scrollButtonRight":"magritte-scroll-button-right___wZOn-_6-5-1","position-container":"magritte-position-container___1A4Bv_6-5-1","positionContainer":"magritte-position-container___1A4Bv_6-5-1","dot-container":"magritte-dot-container___ahtlG_6-5-1","dotContainer":"magritte-dot-container___ahtlG_6-5-1"};
3
+
4
+ export { styles as s };
5
+ //# sourceMappingURL=scrollableContainer-DFe-eO3O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrollableContainer-DFe-eO3O.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
package/types.d.ts CHANGED
@@ -157,6 +157,25 @@ export interface ScrollableContainerDefaultLayoutProps {
157
157
  * @default false
158
158
  */
159
159
  fadeOnMobile?: boolean;
160
+ /**
161
+ * Отключает краевые фейды на десктопных брейкпоинтах (с M), где показываются кнопки листания;
162
+ * сами кнопки при этом остаются. Вместе с `fadeOnMobile` позволяет задать фейды для мобильных
163
+ * и десктопных брейкпоинтов независимо.
164
+ * @default false
165
+ */
166
+ noFadeOnDesktop?: boolean;
167
+ /**
168
+ * Отступ кнопок листания от краёв контейнера в пикселях. Учитывается при прокрутке к элементам,
169
+ * чтобы они не оказывались под кнопками
170
+ * @default 0
171
+ */
172
+ buttonsOffset?: number;
173
+ /**
174
+ * Показывать кнопки листания только при наведении курсора на контейнер (и при фокусе кнопки
175
+ * с клавиатуры). На устройствах без ховера кнопки не показываются
176
+ * @default false
177
+ */
178
+ buttonsOnHover?: boolean;
160
179
  /** aria-label кнопки налево */
161
180
  leftButtonAriaLabel?: string;
162
181
  /** aria-label кнопки направо */
package/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["src/types.ts"],"sourcesContent":["import type { HTMLAttributes, RefObject, MouseEventHandler, ReactNode } from 'react';\n\nimport { TokenBaseStaticSpace } from '@hh.ru/magritte-design-tokens/types';\nimport type { DotPagesProps } from '@hh.ru/magritte-ui-dot-pages';\n\nexport const OFFSET_ATTR = Symbol('scroll-item-offset');\nexport interface ItemOffset {\n left: number;\n right: number;\n}\nexport interface ItemWithOffset {\n [OFFSET_ATTR]: ItemOffset;\n}\n\nexport interface ControlWithClick {\n onClick?: MouseEventHandler;\n 'data-qa'?: string;\n}\n\nexport interface RegisterAndRemoveItem {\n /** колбэк для регистрации элемента галерии */\n registerItem: (ref: RefObject<HTMLElement>) => void;\n /** колбэк для удаления элемента галерии */\n removeItem: (ref: RefObject<HTMLElement>) => void;\n}\n\nexport interface ScrollDisableState {\n /** заблокирован ли скролл влево */\n isScrollRightDisabled: boolean;\n /** заблокирован ли скролл вправо */\n isScrollLeftDisabled: boolean;\n}\n\nexport interface ScrollableControls {\n /** двигаем ScrollableContainer налево */\n scrollLeft: () => void;\n /** двигаем ScrollableContainer направо */\n scrollRight: () => void;\n /** двигаем ScrollableContainer к первому элементу */\n scrollToFirstItem: () => void;\n /** двигаем ScrollableContainer к последнему элементу */\n scrollToLastItem: () => void;\n /** скролл к элементу по индексу, элементы сортируются по расположению справа налево */\n scrollToIndex: (index: number) => void;\n /**\n * скролл к элементу по ref, должен передаваться ref на элемент который был\n * зарегистрирован с помощью registerItem API\n **/\n scrollToItem: (ref: RefObject<HTMLElement>) => void;\n /** моментальный скролл к элементу по индексу */\n jumpToIndex: (index: number) => void;\n /**\n * моментальный сдвиг позиции на дельту\n * не выравнивает элемент по scrollSnapAlign (безопасен посреди жеста)\n **/\n jumpBy: (delta: number) => void;\n}\n\n/**\n * Пропы для настройки коррекции отступов в режиме без кнопок, когда надо чтобы край скролла соответствовал\n * краю родительского контейнера, у которого могут быть отступы. Задаются в виде положительного числа.\n * более специфичные пропсы переопределяют менее специфичные. При выборе значения коррекции для разрешения выбирается\n * ближайшее заданное значение для разрешений меньшего или равного размера. Т.е. если задано correction и correctionM,\n * то для разрешений S и XS будет использовано correction, а для остальных correctionM. Если задано\n * еще и correctionLeftM, то для разрешений начиная с M и больше для левого края будет использовано\n * correctionLeftM, а для правого correctionM.\n */\nexport interface SpacingCorrectionProps {\n /** Величина коррекции отступа, положительное число или 0 */\n correction?: number;\n /** Величина коррекции отступа для разрешения XS и больше, положительное число или 0 */\n correctionXS?: number;\n /** Величина коррекции отступа для разрешения S и больше, положительное число или 0 */\n correctionS?: number;\n /** Величина коррекции отступа для разрешения M и больше, положительное число или 0 */\n correctionM?: number;\n /** Величина коррекции отступа для разрешения L и больше, положительное число или 0 */\n correctionL?: number;\n /** Величина коррекции отступа для разрешения XL и больше, положительное число или 0 */\n correctionXL?: number;\n /** Величина коррекции отступа для разрешения XXL и больше, положительное число или 0 */\n correctionXXL?: number;\n /** Величина коррекции отступа слева для разрешения XS и больше, положительное число или 0 */\n correctionLeftXS?: number;\n /** Величина коррекции левого отступа для разрешения S и больше, положительное число или 0 */\n correctionLeftS?: number;\n /** Величина коррекции левого отступа для разрешения M и больше, положительное число или 0 */\n correctionLeftM?: number;\n /** Величина коррекции левого отступа для разрешения L и больше, положительное число или 0 */\n correctionLeftL?: number;\n /** Величина коррекции левого отступа для разрешения XL и больше, положительное число или 0 */\n correctionLeftXL?: number;\n /** Величина коррекции левого отступа для разрешения XXL и больше, положительное число или 0 */\n correctionLeftXXL?: number;\n /** Величина коррекции отступа справа для разрешения XS и больше, положительное число или 0 */\n correctionRightXS?: number;\n /** Величина коррекции отступа справа для разрешения S и больше, положительное число или 0 */\n correctionRightS?: number;\n /** Величина коррекции отступа справа для разрешения M и больше, положительное число или 0 */\n correctionRightM?: number;\n /** Величина коррекции отступа справа для разрешения L и больше, положительное число или 0 */\n correctionRightL?: number;\n /** Величина коррекции отступа справа для разрешения XL и больше, положительное число или 0 */\n correctionRightXL?: number;\n /** Величина коррекции отступа справа для разрешения XXL и больше, положительное число или 0 */\n correctionRightXXL?: number;\n}\n\nexport type ScrollSnapAlign = 'start' | 'end' | 'center' | 'none';\n\nexport type ScrollableContainerProps = SpacingCorrectionProps & {\n /** Контент ScrollableContainer */\n children: ReactNode;\n /**\n * Определяет, как ближайший элемент будет размещён во вьюпорте при автоматическом скролле\n *\n * - `center` - ближайший элемент центрируется во вьюпорте\n * - `start` - ближайший элемент выравнивается по левой границе вьюпорта\n * - `end` - ближайший элемент выравнивается по правой границе вьюпорта\n */\n scrollSnapAlign?: ScrollSnapAlign;\n} & HTMLAttributes<HTMLDivElement>;\n\nexport interface ScrollableItemProps extends HTMLAttributes<HTMLDivElement> {\n /** Элемент галереи */\n children: ReactNode;\n /** Нужно ли скролить к элементу при фокусе */\n scrollToItemOnFocus?: boolean;\n}\n\nexport interface ScrollableContainerGalleryProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onScroll'> {\n /** Колбэк при прокрутке контейнера */\n onScroll?: (scrollInfo: ScrollDisableState) => void;\n /** Колбэк при инициализации контейнера */\n onReady?: (scrollInfo: ScrollDisableState) => void;\n /** Колбэк при изменении размеров контейнера */\n onChangeSize?: (scrollInfo: ScrollDisableState) => void;\n /** Элементы галереи, которые отображаются внутри контейнера и прокручиваются по горизонтали */\n children: ReactNode;\n}\n\nexport interface ScrollableContainerDotPagesProps {\n /** Колбэк при изменении active dot в компоненте dot-pages*/\n onChangeDot?: (dot: number) => void;\n /** Свойства dot-pages*/\n dotPagesProps?: Omit<DotPagesProps, 'active' | 'count'>;\n /** Верхний отступ для DotPages */\n offsetTop?: TokenBaseStaticSpace;\n}\n\nexport interface ScrollableContainerButtonProps {\n /** Кнопка для скрола налево/направо */\n children: ReactNode;\n}\n\nexport type ScrollableContainerDefaultLayoutSize = 'medium' | 'small';\n\nexport interface ScrollableContainerDefaultLayoutProps {\n /** Контент ScrollableContainerGallery */\n children: ReactNode;\n /**\n * Размер кнопок листания\n *\n * - `medium` - иконка 24px с паддингом 8px (кнопка 40px)\n * - `small` - иконка 24px с паддингом 4px (кнопка 32px)\n * @default medium\n */\n size?: ScrollableContainerDefaultLayoutSize;\n /**\n * Показывать краевые фейды на мобильных брейкпоинтах (XS/S), где кнопки листания\n * скрыты. По умолчанию фейды видны только вместе с кнопками — с брейкпоинта M.\n * @default false\n */\n fadeOnMobile?: boolean;\n /** aria-label кнопки налево */\n leftButtonAriaLabel?: string;\n /** aria-label кнопки направо */\n rightButtonAriaLabel?: string;\n /** aria-controls кнопки налево */\n leftAriaControls?: string;\n /** aria-controls кнопки направо */\n rightAriaControls?: string;\n}\n"],"names":[],"mappings":"MAKa,WAAW,GAAG,MAAM,CAAC,oBAAoB;;;;"}
1
+ {"version":3,"file":"types.js","sources":["src/types.ts"],"sourcesContent":["import type { HTMLAttributes, RefObject, MouseEventHandler, ReactNode } from 'react';\n\nimport { TokenBaseStaticSpace } from '@hh.ru/magritte-design-tokens/types';\nimport type { DotPagesProps } from '@hh.ru/magritte-ui-dot-pages';\n\nexport const OFFSET_ATTR = Symbol('scroll-item-offset');\nexport interface ItemOffset {\n left: number;\n right: number;\n}\nexport interface ItemWithOffset {\n [OFFSET_ATTR]: ItemOffset;\n}\n\nexport interface ControlWithClick {\n onClick?: MouseEventHandler;\n 'data-qa'?: string;\n}\n\nexport interface RegisterAndRemoveItem {\n /** колбэк для регистрации элемента галерии */\n registerItem: (ref: RefObject<HTMLElement>) => void;\n /** колбэк для удаления элемента галерии */\n removeItem: (ref: RefObject<HTMLElement>) => void;\n}\n\nexport interface ScrollDisableState {\n /** заблокирован ли скролл влево */\n isScrollRightDisabled: boolean;\n /** заблокирован ли скролл вправо */\n isScrollLeftDisabled: boolean;\n}\n\nexport interface ScrollableControls {\n /** двигаем ScrollableContainer налево */\n scrollLeft: () => void;\n /** двигаем ScrollableContainer направо */\n scrollRight: () => void;\n /** двигаем ScrollableContainer к первому элементу */\n scrollToFirstItem: () => void;\n /** двигаем ScrollableContainer к последнему элементу */\n scrollToLastItem: () => void;\n /** скролл к элементу по индексу, элементы сортируются по расположению справа налево */\n scrollToIndex: (index: number) => void;\n /**\n * скролл к элементу по ref, должен передаваться ref на элемент который был\n * зарегистрирован с помощью registerItem API\n **/\n scrollToItem: (ref: RefObject<HTMLElement>) => void;\n /** моментальный скролл к элементу по индексу */\n jumpToIndex: (index: number) => void;\n /**\n * моментальный сдвиг позиции на дельту\n * не выравнивает элемент по scrollSnapAlign (безопасен посреди жеста)\n **/\n jumpBy: (delta: number) => void;\n}\n\n/**\n * Пропы для настройки коррекции отступов в режиме без кнопок, когда надо чтобы край скролла соответствовал\n * краю родительского контейнера, у которого могут быть отступы. Задаются в виде положительного числа.\n * более специфичные пропсы переопределяют менее специфичные. При выборе значения коррекции для разрешения выбирается\n * ближайшее заданное значение для разрешений меньшего или равного размера. Т.е. если задано correction и correctionM,\n * то для разрешений S и XS будет использовано correction, а для остальных correctionM. Если задано\n * еще и correctionLeftM, то для разрешений начиная с M и больше для левого края будет использовано\n * correctionLeftM, а для правого correctionM.\n */\nexport interface SpacingCorrectionProps {\n /** Величина коррекции отступа, положительное число или 0 */\n correction?: number;\n /** Величина коррекции отступа для разрешения XS и больше, положительное число или 0 */\n correctionXS?: number;\n /** Величина коррекции отступа для разрешения S и больше, положительное число или 0 */\n correctionS?: number;\n /** Величина коррекции отступа для разрешения M и больше, положительное число или 0 */\n correctionM?: number;\n /** Величина коррекции отступа для разрешения L и больше, положительное число или 0 */\n correctionL?: number;\n /** Величина коррекции отступа для разрешения XL и больше, положительное число или 0 */\n correctionXL?: number;\n /** Величина коррекции отступа для разрешения XXL и больше, положительное число или 0 */\n correctionXXL?: number;\n /** Величина коррекции отступа слева для разрешения XS и больше, положительное число или 0 */\n correctionLeftXS?: number;\n /** Величина коррекции левого отступа для разрешения S и больше, положительное число или 0 */\n correctionLeftS?: number;\n /** Величина коррекции левого отступа для разрешения M и больше, положительное число или 0 */\n correctionLeftM?: number;\n /** Величина коррекции левого отступа для разрешения L и больше, положительное число или 0 */\n correctionLeftL?: number;\n /** Величина коррекции левого отступа для разрешения XL и больше, положительное число или 0 */\n correctionLeftXL?: number;\n /** Величина коррекции левого отступа для разрешения XXL и больше, положительное число или 0 */\n correctionLeftXXL?: number;\n /** Величина коррекции отступа справа для разрешения XS и больше, положительное число или 0 */\n correctionRightXS?: number;\n /** Величина коррекции отступа справа для разрешения S и больше, положительное число или 0 */\n correctionRightS?: number;\n /** Величина коррекции отступа справа для разрешения M и больше, положительное число или 0 */\n correctionRightM?: number;\n /** Величина коррекции отступа справа для разрешения L и больше, положительное число или 0 */\n correctionRightL?: number;\n /** Величина коррекции отступа справа для разрешения XL и больше, положительное число или 0 */\n correctionRightXL?: number;\n /** Величина коррекции отступа справа для разрешения XXL и больше, положительное число или 0 */\n correctionRightXXL?: number;\n}\n\nexport type ScrollSnapAlign = 'start' | 'end' | 'center' | 'none';\n\nexport type ScrollableContainerProps = SpacingCorrectionProps & {\n /** Контент ScrollableContainer */\n children: ReactNode;\n /**\n * Определяет, как ближайший элемент будет размещён во вьюпорте при автоматическом скролле\n *\n * - `center` - ближайший элемент центрируется во вьюпорте\n * - `start` - ближайший элемент выравнивается по левой границе вьюпорта\n * - `end` - ближайший элемент выравнивается по правой границе вьюпорта\n */\n scrollSnapAlign?: ScrollSnapAlign;\n} & HTMLAttributes<HTMLDivElement>;\n\nexport interface ScrollableItemProps extends HTMLAttributes<HTMLDivElement> {\n /** Элемент галереи */\n children: ReactNode;\n /** Нужно ли скролить к элементу при фокусе */\n scrollToItemOnFocus?: boolean;\n}\n\nexport interface ScrollableContainerGalleryProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onScroll'> {\n /** Колбэк при прокрутке контейнера */\n onScroll?: (scrollInfo: ScrollDisableState) => void;\n /** Колбэк при инициализации контейнера */\n onReady?: (scrollInfo: ScrollDisableState) => void;\n /** Колбэк при изменении размеров контейнера */\n onChangeSize?: (scrollInfo: ScrollDisableState) => void;\n /** Элементы галереи, которые отображаются внутри контейнера и прокручиваются по горизонтали */\n children: ReactNode;\n}\n\nexport interface ScrollableContainerDotPagesProps {\n /** Колбэк при изменении active dot в компоненте dot-pages*/\n onChangeDot?: (dot: number) => void;\n /** Свойства dot-pages*/\n dotPagesProps?: Omit<DotPagesProps, 'active' | 'count'>;\n /** Верхний отступ для DotPages */\n offsetTop?: TokenBaseStaticSpace;\n}\n\nexport interface ScrollableContainerButtonProps {\n /** Кнопка для скрола налево/направо */\n children: ReactNode;\n}\n\nexport type ScrollableContainerDefaultLayoutSize = 'medium' | 'small';\n\nexport interface ScrollableContainerDefaultLayoutProps {\n /** Контент ScrollableContainerGallery */\n children: ReactNode;\n /**\n * Размер кнопок листания\n *\n * - `medium` - иконка 24px с паддингом 8px (кнопка 40px)\n * - `small` - иконка 24px с паддингом 4px (кнопка 32px)\n * @default medium\n */\n size?: ScrollableContainerDefaultLayoutSize;\n /**\n * Показывать краевые фейды на мобильных брейкпоинтах (XS/S), где кнопки листания\n * скрыты. По умолчанию фейды видны только вместе с кнопками — с брейкпоинта M.\n * @default false\n */\n fadeOnMobile?: boolean;\n /**\n * Отключает краевые фейды на десктопных брейкпоинтах (с M), где показываются кнопки листания;\n * сами кнопки при этом остаются. Вместе с `fadeOnMobile` позволяет задать фейды для мобильных\n * и десктопных брейкпоинтов независимо.\n * @default false\n */\n noFadeOnDesktop?: boolean;\n /**\n * Отступ кнопок листания от краёв контейнера в пикселях. Учитывается при прокрутке к элементам,\n * чтобы они не оказывались под кнопками\n * @default 0\n */\n buttonsOffset?: number;\n /**\n * Показывать кнопки листания только при наведении курсора на контейнер (и при фокусе кнопки\n * с клавиатуры). На устройствах без ховера кнопки не показываются\n * @default false\n */\n buttonsOnHover?: boolean;\n /** aria-label кнопки налево */\n leftButtonAriaLabel?: string;\n /** aria-label кнопки направо */\n rightButtonAriaLabel?: string;\n /** aria-controls кнопки налево */\n leftAriaControls?: string;\n /** aria-controls кнопки направо */\n rightAriaControls?: string;\n}\n"],"names":[],"mappings":"MAKa,WAAW,GAAG,MAAM,CAAC,oBAAoB;;;;"}
@@ -61,11 +61,10 @@ const useScrollContainer = () => {
61
61
  scrollState.indexForDeferScroll = -1;
62
62
  }
63
63
  }, [scrollState, scrollToIndex, jumpToIndex]);
64
- // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps
64
+ // eslint-disable-next-line react-hooks/exhaustive-deps
65
65
  const recalculateItemPositionsDebounced = useCallback(debounce(recalculateItemPositions, 10), [
66
66
  recalculateItemPositions,
67
67
  ]);
68
- // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps
69
68
  const scrollToItemDebounced = useInitOnce(() => debounce(() => {
70
69
  if (scrollState.scrollSnapAlign === 'none') {
71
70
  return;
@@ -84,7 +83,7 @@ const useScrollContainer = () => {
84
83
  state.containerRef.current && observer.observe(state.containerRef.current);
85
84
  resizeOberverRef.current = observer;
86
85
  return () => observer.disconnect();
87
- // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps
86
+ // eslint-disable-next-line react-hooks/exhaustive-deps
88
87
  }, []);
89
88
  // Слушатель нужен, чтобы не вызывать скролл в родительском контейнере (например в bs)
90
89
  useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollContainer.js","sources":["src/useScrollContainer.ts"],"sourcesContent":["import { useRef, useEffect, type RefObject, useCallback, useState } from 'react';\n\nimport { requestAnimation, debounce } from '@hh.ru/magritte-common-func-utils';\nimport { clamp, type ScrollGestureEvent, initScrollHandlers } from '@hh.ru/magritte-internal-custom-scroll';\nimport { useScrollState } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport { type ItemWithOffset, OFFSET_ATTR } from '@hh.ru/magritte-ui-scrollable-container/types';\nimport { useScrollableControls } from '@hh.ru/magritte-ui-scrollable-container/useScrollableControls';\nimport {\n useInitOnce,\n findIndexNearestToSnapPoint,\n animateScrollToPosition,\n computeScrollSnapBehavior,\n} from '@hh.ru/magritte-ui-scrollable-container/utils';\n\nconst EPSILON = 0.5;\nconst MIN_DELTA_FOR_TOUCH = 5;\nconst MAX_OFFSET = { [OFFSET_ATTR]: { left: Number.MAX_SAFE_INTEGER } };\n\n/**\n * Переменные полностью описывающие состояние скролла, хранятся в одном объекте, чтобы не плодить\n * кучу ref'ов и передавать всё состояние в функции одним аргументом, а не длинным списком переменных\n */\nexport interface ScrollInternalState {\n /** контейнер, в котором лежит positionContainer (определяет видимую область) */\n containerRef: RefObject<HTMLDivElement>;\n /** контейнер, с помощью изменения положения которого обеспечивается скролл */\n positionContainerRef: RefObject<HTMLDivElement>;\n /** размер коррекции отступов */\n correction: { leftCorrection: number; rightCorrection: number };\n /* Было ли взаимодействие с компонентом - скролл или прокрутка к элементу */\n wasInteracted: boolean;\n}\n\ninterface UseScrollContainer {\n registerItem: (ref: RefObject<HTMLElement>) => void;\n removeItem: (ref: RefObject<HTMLElement>) => void;\n initScrollHandlers: () => VoidFunction;\n containerRef: RefObject<HTMLDivElement>;\n positionContainerRef: RefObject<HTMLDivElement>;\n isTouch: boolean;\n}\n\nexport const useScrollContainer = (): UseScrollContainer => {\n const scrollState = useScrollState();\n const { scrollToIndex, jumpToIndex } = useScrollableControls();\n const [isTouch, setIsTouch] = useState(false);\n const leftCorrection = scrollState.leftCorrection.get();\n const rightCorrection = scrollState.rightCorrection.get();\n const scrollStateRef = useRef<ScrollInternalState>({\n containerRef: useRef<HTMLDivElement>(null),\n positionContainerRef: useRef<HTMLDivElement>(null),\n correction: { leftCorrection, rightCorrection },\n wasInteracted: false,\n });\n scrollStateRef.current.correction = { leftCorrection, rightCorrection };\n const resizeOberverRef = useRef<ResizeObserver | null>(null);\n\n // recalc positions + report widths into store\n const recalculateItemPositions = useCallback(() => {\n const state = scrollStateRef.current;\n const { containerRef, correction, positionContainerRef } = state;\n const { leftCorrection, rightCorrection } = correction;\n const items = scrollState.items.get();\n if (!containerRef.current || !positionContainerRef.current) {\n return;\n }\n const offsetLeft = positionContainerRef.current?.getBoundingClientRect().left ?? 0;\n items.forEach((itemRef) => {\n if (!itemRef.current) {\n return;\n }\n const rect = itemRef.current.getBoundingClientRect();\n itemRef.current[OFFSET_ATTR] = { left: rect.left - offsetLeft, right: rect.right - offsetLeft };\n });\n items.sort((a, b) => (a.current || MAX_OFFSET)[OFFSET_ATTR].left - (b.current || MAX_OFFSET)[OFFSET_ATTR].left);\n const viewportWidth = containerRef.current.offsetWidth - leftCorrection - rightCorrection;\n const contentWidth = items.reduce(\n (pos, itemRef) => Math.max(pos, itemRef.current?.[OFFSET_ATTR]?.right || 0),\n 0\n );\n scrollState.viewportWidth.set(viewportWidth);\n scrollState.contentWidth.set(contentWidth);\n scrollState.items.set(items);\n if (scrollState.indexForDeferScroll !== -1) {\n if (scrollState.behaviorScrollTypeDeferScroll === 'instant') {\n jumpToIndex(scrollState.indexForDeferScroll);\n } else {\n scrollToIndex(scrollState.indexForDeferScroll);\n }\n scrollState.behaviorScrollTypeDeferScroll = 'animate';\n scrollState.indexForDeferScroll = -1;\n }\n }, [scrollState, scrollToIndex, jumpToIndex]);\n\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n const recalculateItemPositionsDebounced = useCallback(debounce(recalculateItemPositions, 10), [\n recalculateItemPositions,\n ]);\n\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n const scrollToItemDebounced = useInitOnce(() =>\n debounce(() => {\n if (scrollState.scrollSnapAlign === 'none') {\n return;\n }\n const targetItemIndex = findIndexNearestToSnapPoint(scrollState);\n const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);\n const target = scrollSnapBehavior(scrollState, targetItemIndex);\n animateScrollToPosition(scrollState, target);\n }, 100)\n );\n\n useEffect(() => {\n const state = scrollStateRef.current;\n const observer = new ResizeObserver(\n requestAnimation(() => {\n recalculateItemPositions();\n })\n );\n\n scrollState.items.get().forEach((item) => item.current && observer.observe(item.current));\n state.containerRef.current && observer.observe(state.containerRef.current);\n resizeOberverRef.current = observer;\n return () => observer.disconnect();\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n }, []);\n\n // Слушатель нужен, чтобы не вызывать скролл в родительском контейнере (например в bs)\n useEffect(() => {\n const wrapperRef = scrollStateRef.current.containerRef.current;\n if (!wrapperRef) {\n return void 0;\n }\n const handleTouchStartHandler = (event: TouchEvent) => {\n event.stopPropagation();\n };\n wrapperRef.addEventListener('touchstart', handleTouchStartHandler);\n return () => {\n wrapperRef.removeEventListener('touchstart', handleTouchStartHandler);\n };\n }, []);\n\n // события тача\n const didContainerMove = useRef(false);\n const onTouchStart = useCallback(() => {\n setIsTouch(true);\n didContainerMove.current = false;\n scrollState.scrollPosition.stop();\n }, [scrollState]);\n\n const onTouchMove = useCallback(\n (event: ScrollGestureEvent) => {\n if (!didContainerMove.current) {\n // надо отличить тач от свайпа\n didContainerMove.current = Math.abs(event.delta) > MIN_DELTA_FOR_TOUCH;\n }\n scrollState.scrollPosition.set(\n clamp(\n scrollState.scrollPosition.get() + event.delta,\n scrollState.viewportWidth.get() - scrollState.contentWidth.get(),\n 0\n )\n );\n },\n [scrollState]\n );\n\n const onTouchEnd = useCallback(() => {\n if (didContainerMove.current) {\n scrollToItemDebounced();\n }\n }, [scrollToItemDebounced]);\n\n // события мыши\n const didContainerHovered = useRef(false);\n const onMouseEnter = useCallback(() => {\n didContainerHovered.current = true;\n }, []);\n\n const onWheelMove = useCallback(\n (event: ScrollGestureEvent) => {\n setIsTouch(false);\n if (!didContainerHovered.current) {\n return;\n }\n const currentPosition = scrollState.scrollPosition.get();\n const nextPosition = clamp(\n currentPosition + event.delta,\n scrollState.viewportWidth.get() - scrollState.contentWidth.get(),\n 0\n );\n if (Math.abs(nextPosition - currentPosition) > EPSILON) {\n scrollState.scrollPosition.set(nextPosition);\n scrollToItemDebounced();\n event.preventDefault();\n }\n },\n [scrollToItemDebounced, scrollState]\n );\n\n const onMouseLeave = useCallback(() => {\n didContainerHovered.current = false;\n }, []);\n\n const _initScrollHandlers = useCallback(\n () =>\n initScrollHandlers({\n axis: 'horizontal',\n wrapperRef: scrollStateRef.current.containerRef,\n onTouchStart,\n onTouchMove,\n onTouchEnd,\n onMouseEnter,\n onWheelMove,\n onMouseLeave,\n }),\n [onTouchMove, onTouchEnd, onWheelMove, onTouchStart, onMouseEnter, onMouseLeave]\n );\n\n const registerItem = useCallback(\n (ref: RefObject<HTMLElement>) => {\n if (!ref.current) {\n return;\n }\n scrollState.items.get().push(ref as unknown as RefObject<HTMLElement & ItemWithOffset>);\n scrollState.items.set(scrollState.items.get());\n resizeOberverRef.current?.observe(ref.current);\n recalculateItemPositions();\n },\n [recalculateItemPositions, scrollState]\n );\n\n const removeItem = useCallback(\n (ref: RefObject<HTMLElement>) => {\n if (!ref.current) {\n return;\n }\n scrollState.items.set(scrollState.items.get().filter((stored) => stored.current !== ref.current));\n resizeOberverRef.current?.unobserve(ref.current);\n recalculateItemPositionsDebounced();\n },\n [recalculateItemPositionsDebounced, scrollState]\n );\n\n return {\n registerItem,\n removeItem,\n initScrollHandlers: _initScrollHandlers,\n containerRef: scrollStateRef.current.containerRef,\n positionContainerRef: scrollStateRef.current.positionContainerRef,\n isTouch,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useScrollContainer.js","sources":["src/useScrollContainer.ts"],"sourcesContent":["import { useRef, useEffect, type RefObject, useCallback, useState } from 'react';\n\nimport { requestAnimation, debounce } from '@hh.ru/magritte-common-func-utils';\nimport { clamp, type ScrollGestureEvent, initScrollHandlers } from '@hh.ru/magritte-internal-custom-scroll';\nimport { useScrollState } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport { type ItemWithOffset, OFFSET_ATTR } from '@hh.ru/magritte-ui-scrollable-container/types';\nimport { useScrollableControls } from '@hh.ru/magritte-ui-scrollable-container/useScrollableControls';\nimport {\n useInitOnce,\n findIndexNearestToSnapPoint,\n animateScrollToPosition,\n computeScrollSnapBehavior,\n} from '@hh.ru/magritte-ui-scrollable-container/utils';\n\nconst EPSILON = 0.5;\nconst MIN_DELTA_FOR_TOUCH = 5;\nconst MAX_OFFSET = { [OFFSET_ATTR]: { left: Number.MAX_SAFE_INTEGER } };\n\n/**\n * Переменные полностью описывающие состояние скролла, хранятся в одном объекте, чтобы не плодить\n * кучу ref'ов и передавать всё состояние в функции одним аргументом, а не длинным списком переменных\n */\nexport interface ScrollInternalState {\n /** контейнер, в котором лежит positionContainer (определяет видимую область) */\n containerRef: RefObject<HTMLDivElement>;\n /** контейнер, с помощью изменения положения которого обеспечивается скролл */\n positionContainerRef: RefObject<HTMLDivElement>;\n /** размер коррекции отступов */\n correction: { leftCorrection: number; rightCorrection: number };\n /* Было ли взаимодействие с компонентом - скролл или прокрутка к элементу */\n wasInteracted: boolean;\n}\n\ninterface UseScrollContainer {\n registerItem: (ref: RefObject<HTMLElement>) => void;\n removeItem: (ref: RefObject<HTMLElement>) => void;\n initScrollHandlers: () => VoidFunction;\n containerRef: RefObject<HTMLDivElement>;\n positionContainerRef: RefObject<HTMLDivElement>;\n isTouch: boolean;\n}\n\nexport const useScrollContainer = (): UseScrollContainer => {\n const scrollState = useScrollState();\n const { scrollToIndex, jumpToIndex } = useScrollableControls();\n const [isTouch, setIsTouch] = useState(false);\n const leftCorrection = scrollState.leftCorrection.get();\n const rightCorrection = scrollState.rightCorrection.get();\n const scrollStateRef = useRef<ScrollInternalState>({\n containerRef: useRef<HTMLDivElement>(null),\n positionContainerRef: useRef<HTMLDivElement>(null),\n correction: { leftCorrection, rightCorrection },\n wasInteracted: false,\n });\n scrollStateRef.current.correction = { leftCorrection, rightCorrection };\n const resizeOberverRef = useRef<ResizeObserver | null>(null);\n\n // recalc positions + report widths into store\n const recalculateItemPositions = useCallback(() => {\n const state = scrollStateRef.current;\n const { containerRef, correction, positionContainerRef } = state;\n const { leftCorrection, rightCorrection } = correction;\n const items = scrollState.items.get();\n if (!containerRef.current || !positionContainerRef.current) {\n return;\n }\n const offsetLeft = positionContainerRef.current?.getBoundingClientRect().left ?? 0;\n items.forEach((itemRef) => {\n if (!itemRef.current) {\n return;\n }\n const rect = itemRef.current.getBoundingClientRect();\n itemRef.current[OFFSET_ATTR] = { left: rect.left - offsetLeft, right: rect.right - offsetLeft };\n });\n items.sort((a, b) => (a.current || MAX_OFFSET)[OFFSET_ATTR].left - (b.current || MAX_OFFSET)[OFFSET_ATTR].left);\n const viewportWidth = containerRef.current.offsetWidth - leftCorrection - rightCorrection;\n const contentWidth = items.reduce(\n (pos, itemRef) => Math.max(pos, itemRef.current?.[OFFSET_ATTR]?.right || 0),\n 0\n );\n scrollState.viewportWidth.set(viewportWidth);\n scrollState.contentWidth.set(contentWidth);\n scrollState.items.set(items);\n if (scrollState.indexForDeferScroll !== -1) {\n if (scrollState.behaviorScrollTypeDeferScroll === 'instant') {\n jumpToIndex(scrollState.indexForDeferScroll);\n } else {\n scrollToIndex(scrollState.indexForDeferScroll);\n }\n scrollState.behaviorScrollTypeDeferScroll = 'animate';\n scrollState.indexForDeferScroll = -1;\n }\n }, [scrollState, scrollToIndex, jumpToIndex]);\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const recalculateItemPositionsDebounced = useCallback(debounce(recalculateItemPositions, 10), [\n recalculateItemPositions,\n ]);\n\n const scrollToItemDebounced = useInitOnce(() =>\n debounce(() => {\n if (scrollState.scrollSnapAlign === 'none') {\n return;\n }\n const targetItemIndex = findIndexNearestToSnapPoint(scrollState);\n const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);\n const target = scrollSnapBehavior(scrollState, targetItemIndex);\n animateScrollToPosition(scrollState, target);\n }, 100)\n );\n\n useEffect(() => {\n const state = scrollStateRef.current;\n const observer = new ResizeObserver(\n requestAnimation(() => {\n recalculateItemPositions();\n })\n );\n\n scrollState.items.get().forEach((item) => item.current && observer.observe(item.current));\n state.containerRef.current && observer.observe(state.containerRef.current);\n resizeOberverRef.current = observer;\n return () => observer.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Слушатель нужен, чтобы не вызывать скролл в родительском контейнере (например в bs)\n useEffect(() => {\n const wrapperRef = scrollStateRef.current.containerRef.current;\n if (!wrapperRef) {\n return void 0;\n }\n const handleTouchStartHandler = (event: TouchEvent) => {\n event.stopPropagation();\n };\n wrapperRef.addEventListener('touchstart', handleTouchStartHandler);\n return () => {\n wrapperRef.removeEventListener('touchstart', handleTouchStartHandler);\n };\n }, []);\n\n // события тача\n const didContainerMove = useRef(false);\n const onTouchStart = useCallback(() => {\n setIsTouch(true);\n didContainerMove.current = false;\n scrollState.scrollPosition.stop();\n }, [scrollState]);\n\n const onTouchMove = useCallback(\n (event: ScrollGestureEvent) => {\n if (!didContainerMove.current) {\n // надо отличить тач от свайпа\n didContainerMove.current = Math.abs(event.delta) > MIN_DELTA_FOR_TOUCH;\n }\n scrollState.scrollPosition.set(\n clamp(\n scrollState.scrollPosition.get() + event.delta,\n scrollState.viewportWidth.get() - scrollState.contentWidth.get(),\n 0\n )\n );\n },\n [scrollState]\n );\n\n const onTouchEnd = useCallback(() => {\n if (didContainerMove.current) {\n scrollToItemDebounced();\n }\n }, [scrollToItemDebounced]);\n\n // события мыши\n const didContainerHovered = useRef(false);\n const onMouseEnter = useCallback(() => {\n didContainerHovered.current = true;\n }, []);\n\n const onWheelMove = useCallback(\n (event: ScrollGestureEvent) => {\n setIsTouch(false);\n if (!didContainerHovered.current) {\n return;\n }\n const currentPosition = scrollState.scrollPosition.get();\n const nextPosition = clamp(\n currentPosition + event.delta,\n scrollState.viewportWidth.get() - scrollState.contentWidth.get(),\n 0\n );\n if (Math.abs(nextPosition - currentPosition) > EPSILON) {\n scrollState.scrollPosition.set(nextPosition);\n scrollToItemDebounced();\n event.preventDefault();\n }\n },\n [scrollToItemDebounced, scrollState]\n );\n\n const onMouseLeave = useCallback(() => {\n didContainerHovered.current = false;\n }, []);\n\n const _initScrollHandlers = useCallback(\n () =>\n initScrollHandlers({\n axis: 'horizontal',\n wrapperRef: scrollStateRef.current.containerRef,\n onTouchStart,\n onTouchMove,\n onTouchEnd,\n onMouseEnter,\n onWheelMove,\n onMouseLeave,\n }),\n [onTouchMove, onTouchEnd, onWheelMove, onTouchStart, onMouseEnter, onMouseLeave]\n );\n\n const registerItem = useCallback(\n (ref: RefObject<HTMLElement>) => {\n if (!ref.current) {\n return;\n }\n scrollState.items.get().push(ref as unknown as RefObject<HTMLElement & ItemWithOffset>);\n scrollState.items.set(scrollState.items.get());\n resizeOberverRef.current?.observe(ref.current);\n recalculateItemPositions();\n },\n [recalculateItemPositions, scrollState]\n );\n\n const removeItem = useCallback(\n (ref: RefObject<HTMLElement>) => {\n if (!ref.current) {\n return;\n }\n scrollState.items.set(scrollState.items.get().filter((stored) => stored.current !== ref.current));\n resizeOberverRef.current?.unobserve(ref.current);\n recalculateItemPositionsDebounced();\n },\n [recalculateItemPositionsDebounced, scrollState]\n );\n\n return {\n registerItem,\n removeItem,\n initScrollHandlers: _initScrollHandlers,\n containerRef: scrollStateRef.current.containerRef,\n positionContainerRef: scrollStateRef.current.positionContainerRef,\n isTouch,\n };\n};\n"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- import './index.css';
2
- var styles = {"scroll-wrapper":"magritte-scroll-wrapper___vTdZl_6-4-10","scrollWrapper":"magritte-scroll-wrapper___vTdZl_6-4-10","scrollable-container":"magritte-scrollable-container___AKIUp_6-4-10","scrollableContainer":"magritte-scrollable-container___AKIUp_6-4-10","scroll-buttons-container":"magritte-scroll-buttons-container___ZeI5a_6-4-10","scrollButtonsContainer":"magritte-scroll-buttons-container___ZeI5a_6-4-10","scroll-buttons":"magritte-scroll-buttons___0SjoR_6-4-10","scrollButtons":"magritte-scroll-buttons___0SjoR_6-4-10","scroll-buttons-small":"magritte-scroll-buttons-small___xG3MS_6-4-10","scrollButtonsSmall":"magritte-scroll-buttons-small___xG3MS_6-4-10","scroll-button":"magritte-scroll-button___4GQu3_6-4-10","scrollButton":"magritte-scroll-button___4GQu3_6-4-10","scroll-button-left":"magritte-scroll-button-left___UueEY_6-4-10","scrollButtonLeft":"magritte-scroll-button-left___UueEY_6-4-10","scroll-button-right":"magritte-scroll-button-right___wZOn-_6-4-10","scrollButtonRight":"magritte-scroll-button-right___wZOn-_6-4-10","position-container":"magritte-position-container___1A4Bv_6-4-10","positionContainer":"magritte-position-container___1A4Bv_6-4-10","dot-container":"magritte-dot-container___ahtlG_6-4-10","dotContainer":"magritte-dot-container___ahtlG_6-4-10"};
3
-
4
- export { styles as s };
5
- //# sourceMappingURL=scrollableContainer-C7JpsOHd.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scrollableContainer-C7JpsOHd.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}