@hh.ru/magritte-ui-scrollable-container 6.4.10 → 6.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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-u4jRkzqI.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-u4jRkzqI.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-u4jRkzqI.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-u4jRkzqI.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-u4jRkzqI.js';
17
17
 
18
18
  const ScrollableItem = ({ children, scrollToItemOnFocus, ...props }) => {
19
19
  const ref = useRef(null);
package/index.css CHANGED
@@ -2,16 +2,21 @@
2
2
  --magritte-gradient-component-chat-input-background-fade-v25-1-0:#ffffff00 0%, #ffffff 100%;
3
3
  }
4
4
 
5
+ :root{
6
+ --magritte-semantic-animation-time-s-duration-v25-1-0:200ms;
7
+ }
8
+
5
9
  .magritte-night-theme{
6
10
  --magritte-gradient-component-chat-input-background-fade-v25-1-0:#1b1b1b00 0%, #1b1b1b 100%;
7
11
  }
8
- .magritte-scroll-wrapper___vTdZl_6-4-10{
12
+ .magritte-scroll-wrapper___vTdZl_6-5-0{
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-0{
14
18
  display:block;
19
+ isolation:isolate;
15
20
  overflow-x:hidden;
16
21
  overflow-x:clip;
17
22
  overflow-y:visible;
@@ -26,10 +31,25 @@
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-0{
30
35
  position:relative;
31
36
  }
32
- .magritte-scroll-buttons___0SjoR_6-4-10{
37
+ .magritte-scroll-buttons-container-on-hover___PFUvV_6-5-0 .magritte-scroll-button___4GQu3_6-5-0{
38
+ opacity:0;
39
+ pointer-events:none;
40
+ transition:opacity var(--magritte-semantic-animation-time-s-duration-v25-1-0) ease-in-out;
41
+ }
42
+ .magritte-scroll-buttons-container-on-hover___PFUvV_6-5-0 .magritte-scroll-button___4GQu3_6-5-0:focus-within{
43
+ opacity:1;
44
+ pointer-events:auto;
45
+ }
46
+ @media (hover: hover){
47
+ .magritte-scroll-buttons-container-on-hover___PFUvV_6-5-0:hover .magritte-scroll-button___4GQu3_6-5-0{
48
+ opacity:1;
49
+ pointer-events:auto;
50
+ }
51
+ }
52
+ .magritte-scroll-buttons___0SjoR_6-5-0{
33
53
  --fade-left:linear-gradient(90deg, var(--magritte-gradient-component-chat-input-background-fade-v25-1-0));
34
54
  --fade-right:linear-gradient(270deg, var(--magritte-gradient-component-chat-input-background-fade-v25-1-0));
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;
@@ -38,29 +58,29 @@
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-0{
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-0{
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-0{
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-0{
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-0{
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-0{
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-u4jRkzqI.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-u4jRkzqI.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.0",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "sideEffects": [
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@hh.ru/magritte-common-func-utils": "1.3.15",
23
- "@hh.ru/magritte-common-use-translation": "3.5.0",
23
+ "@hh.ru/magritte-common-use-translation": "3.6.0",
24
24
  "@hh.ru/magritte-design-tokens": "25.1.0",
25
25
  "@hh.ru/magritte-internal-custom-scroll": "2.1.1",
26
26
  "@hh.ru/magritte-ui-breakpoint": "6.1.1",
@@ -37,5 +37,5 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "37c822e9d543ad23d6aec07b4a18c6d2d2b3ee3a"
40
+ "gitHead": "4420819c71c2d263ef47b3208c47942e9f0a1d30"
41
41
  }
@@ -0,0 +1,5 @@
1
+ import './index.css';
2
+ var styles = {"scroll-wrapper":"magritte-scroll-wrapper___vTdZl_6-5-0","scrollWrapper":"magritte-scroll-wrapper___vTdZl_6-5-0","scrollable-container":"magritte-scrollable-container___AKIUp_6-5-0","scrollableContainer":"magritte-scrollable-container___AKIUp_6-5-0","scroll-buttons-container":"magritte-scroll-buttons-container___ZeI5a_6-5-0","scrollButtonsContainer":"magritte-scroll-buttons-container___ZeI5a_6-5-0","scroll-buttons-container-on-hover":"magritte-scroll-buttons-container-on-hover___PFUvV_6-5-0","scrollButtonsContainerOnHover":"magritte-scroll-buttons-container-on-hover___PFUvV_6-5-0","scroll-button":"magritte-scroll-button___4GQu3_6-5-0","scrollButton":"magritte-scroll-button___4GQu3_6-5-0","scroll-buttons":"magritte-scroll-buttons___0SjoR_6-5-0","scrollButtons":"magritte-scroll-buttons___0SjoR_6-5-0","scroll-buttons-small":"magritte-scroll-buttons-small___xG3MS_6-5-0","scrollButtonsSmall":"magritte-scroll-buttons-small___xG3MS_6-5-0","scroll-button-left":"magritte-scroll-button-left___UueEY_6-5-0","scrollButtonLeft":"magritte-scroll-button-left___UueEY_6-5-0","scroll-button-right":"magritte-scroll-button-right___wZOn-_6-5-0","scrollButtonRight":"magritte-scroll-button-right___wZOn-_6-5-0","position-container":"magritte-position-container___1A4Bv_6-5-0","positionContainer":"magritte-position-container___1A4Bv_6-5-0","dot-container":"magritte-dot-container___ahtlG_6-5-0","dotContainer":"magritte-dot-container___ahtlG_6-5-0"};
3
+
4
+ export { styles as s };
5
+ //# sourceMappingURL=scrollableContainer-u4jRkzqI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrollableContainer-u4jRkzqI.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;;;;"}
@@ -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":";;;;"}