@hh.ru/magritte-ui-scrollable-container 6.5.2 → 6.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ObservableValue.js +17 -17
- package/ObservableValue.js.map +1 -1
- package/ScrollStateProvider.d.ts +2 -2
- package/ScrollStateProvider.js +11 -11
- package/ScrollStateProvider.js.map +1 -1
- package/ScrollableContainer.d.ts +8 -8
- package/ScrollableContainer.js +99 -60
- package/ScrollableContainer.js.map +1 -1
- package/ScrollableContainerButton.d.ts +1 -1
- package/ScrollableContainerButton.js +15 -12
- package/ScrollableContainerButton.js.map +1 -1
- package/ScrollableContainerDefaultLayout.d.ts +1 -1
- package/ScrollableContainerDefaultLayout.js +130 -68
- package/ScrollableContainerDefaultLayout.js.map +1 -1
- package/ScrollableContainerDotPages.d.ts +1 -1
- package/ScrollableContainerDotPages.js +59 -47
- package/ScrollableContainerDotPages.js.map +1 -1
- package/ScrollableContainerGallery.d.ts +1 -1
- package/ScrollableContainerGallery.js +85 -54
- package/ScrollableContainerGallery.js.map +1 -1
- package/ScrollableItem.d.ts +1 -1
- package/ScrollableItem.js +22 -12
- package/ScrollableItem.js.map +1 -1
- package/index.css +19 -19
- package/index.d.ts +6 -6
- package/index.js +1 -1
- package/index.mock.d.ts +4 -4
- package/index.mock.js +21 -21
- package/index.mock.js.map +1 -1
- package/package.json +12 -11
- package/scrollableContainer-BVvxwRcp.js +5 -0
- package/scrollableContainer-BVvxwRcp.js.map +1 -0
- package/types.js +1 -1
- package/types.js.map +1 -1
- package/useScrollContainer.js +181 -157
- package/useScrollContainer.js.map +1 -1
- package/useScrollableControls.d.ts +2 -2
- package/useScrollableControls.js +90 -72
- package/useScrollableControls.js.map +1 -1
- package/utils.d.ts +2 -2
- package/utils.js +157 -254
- package/utils.js.map +1 -1
- package/scrollableContainer-C0a8z9uL.js +0 -5
- package/scrollableContainer-C0a8z9uL.js.map +0 -1
|
@@ -9,81 +9,143 @@ 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-
|
|
12
|
+
import { s as styles } from './scrollableContainer-BVvxwRcp.js';
|
|
13
13
|
import './ObservableValue.js';
|
|
14
14
|
import './useScrollableControls.js';
|
|
15
15
|
import '@hh.ru/magritte-internal-custom-scroll';
|
|
16
16
|
import './types.js';
|
|
17
17
|
|
|
18
18
|
const SIZE_CONFIG = {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
medium: { padding: 8, buttonWidth: 44, minHeight: 40 },
|
|
20
|
+
small: { padding: 4, buttonWidth: 36, minHeight: 32 }
|
|
21
21
|
};
|
|
22
|
-
const ScrollableContainerDefaultLayout = ({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
22
|
+
const ScrollableContainerDefaultLayout = ({
|
|
23
|
+
children,
|
|
24
|
+
size = "medium",
|
|
25
|
+
fadeOnMobile = false,
|
|
26
|
+
noFadeOnDesktop = false,
|
|
27
|
+
buttonsOffset = 0,
|
|
28
|
+
buttonsOnHover = false,
|
|
29
|
+
leftButtonAriaLabel: _leftAriaLabel,
|
|
30
|
+
rightButtonAriaLabel: _rightAriaLabel,
|
|
31
|
+
leftAriaControls,
|
|
32
|
+
rightAriaControls
|
|
33
|
+
}) => {
|
|
34
|
+
const { padding: buttonPadding, buttonWidth: buttonWidthCorrection, minHeight } = SIZE_CONFIG[size];
|
|
35
|
+
const scrollState = useScrollState();
|
|
36
|
+
const displayLeftButton = useMotionValue("none");
|
|
37
|
+
const displayRightButton = useMotionValue("none");
|
|
38
|
+
const mask = useMotionValue("none");
|
|
39
|
+
const breakpoint = useBreakpoint();
|
|
40
|
+
const breakpointIndex = BREAKPOINTS_LIST.indexOf(breakpoint.breakpoint);
|
|
41
|
+
const noButtonBreakpointIndex = BREAKPOINTS_LIST.indexOf(NO_BUTTONS_START_FROM_BREAKPOINT);
|
|
42
|
+
const enableDefaultButtonsByBreakpoint = breakpointIndex > noButtonBreakpointIndex;
|
|
43
|
+
const showFade = enableDefaultButtonsByBreakpoint ? !noFadeOnDesktop : fadeOnMobile;
|
|
44
|
+
const leftAriaLabelTrl = useTranslation("ScrollableContainer", "left");
|
|
45
|
+
const leftButtonAriaLabel = _leftAriaLabel ?? leftAriaLabelTrl;
|
|
46
|
+
const rightAriaLabelTrl = useTranslation("ScrollableContainer", "right");
|
|
47
|
+
const rightButtonAriaLabel = _rightAriaLabel ?? rightAriaLabelTrl;
|
|
48
|
+
const updateFadeAndButtons = useInitOnce(() => () => {
|
|
49
|
+
const position = scrollState.scrollPosition.get();
|
|
50
|
+
const contentWidth = scrollState.contentWidth.get();
|
|
51
|
+
const viewportWidth = scrollState.viewportWidth.get();
|
|
52
|
+
const showLeftButton = position < 0;
|
|
53
|
+
const showRightButton = Math.abs(position) < Math.max(0, contentWidth - viewportWidth);
|
|
54
|
+
displayLeftButton.set(showLeftButton ? "block" : "none");
|
|
55
|
+
displayRightButton.set(showRightButton ? "block" : "none");
|
|
56
|
+
if (showLeftButton && showRightButton) {
|
|
57
|
+
mask.set("var(--both-sides-mask)");
|
|
58
|
+
} else if (showLeftButton) {
|
|
59
|
+
mask.set("var(--left-fade-mask)");
|
|
60
|
+
} else if (showRightButton) {
|
|
61
|
+
mask.set("var(--right-fade-mask)");
|
|
62
|
+
} else {
|
|
63
|
+
mask.set("none");
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
updateFadeAndButtons();
|
|
68
|
+
const unsubscribe = [
|
|
69
|
+
scrollState.scrollPosition.on("change", updateFadeAndButtons),
|
|
70
|
+
scrollState.contentWidth.on("change", updateFadeAndButtons),
|
|
71
|
+
scrollState.viewportWidth.on("change", updateFadeAndButtons)
|
|
72
|
+
];
|
|
73
|
+
return () => {
|
|
74
|
+
unsubscribe.forEach((fn) => fn());
|
|
75
|
+
};
|
|
76
|
+
}, [scrollState, updateFadeAndButtons]);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
scrollState.defaultButtonsCorrection.set(
|
|
79
|
+
enableDefaultButtonsByBreakpoint ? buttonWidthCorrection + buttonsOffset : 0
|
|
80
|
+
);
|
|
81
|
+
return () => {
|
|
82
|
+
scrollState.defaultButtonsCorrection.set(0);
|
|
83
|
+
};
|
|
84
|
+
}, [scrollState, enableDefaultButtonsByBreakpoint, buttonWidthCorrection, buttonsOffset]);
|
|
85
|
+
return /* @__PURE__ */ jsxs(
|
|
86
|
+
"div",
|
|
87
|
+
{
|
|
88
|
+
className: classnames(styles.scrollButtonsContainer, {
|
|
89
|
+
[styles.scrollButtonsContainerOnHover]: buttonsOnHover
|
|
90
|
+
}),
|
|
91
|
+
style: {
|
|
92
|
+
"--magritte-ui-scrollable-container-min-height": `${minHeight}px`,
|
|
93
|
+
"--magritte-ui-scrollable-container-buttons-offset": `${buttonsOffset}px`
|
|
94
|
+
},
|
|
95
|
+
children: [
|
|
96
|
+
/* @__PURE__ */ jsx(
|
|
97
|
+
motion.div,
|
|
98
|
+
{
|
|
99
|
+
className: classnames(styles.scrollButton, styles.scrollButtonLeft),
|
|
100
|
+
style: { display: enableDefaultButtonsByBreakpoint ? displayLeftButton : "none" },
|
|
101
|
+
children: /* @__PURE__ */ jsx(ScrollableContainerLeft, { children: /* @__PURE__ */ jsx(
|
|
102
|
+
ChevronLeftOutlinedSize24,
|
|
103
|
+
{
|
|
104
|
+
padding: buttonPadding,
|
|
105
|
+
borderRadius: "halfHeight",
|
|
106
|
+
initialColor: "secondary",
|
|
107
|
+
backgroundStyle: "secondary",
|
|
108
|
+
"aria-label": leftButtonAriaLabel,
|
|
109
|
+
"aria-controls": leftAriaControls
|
|
110
|
+
}
|
|
111
|
+
) })
|
|
112
|
+
}
|
|
113
|
+
),
|
|
114
|
+
/* @__PURE__ */ jsx(
|
|
115
|
+
motion.div,
|
|
116
|
+
{
|
|
117
|
+
className: classnames(styles.scrollButtons, {
|
|
118
|
+
[styles.scrollButtonsSmall]: size === "small"
|
|
119
|
+
}),
|
|
120
|
+
style: {
|
|
121
|
+
WebkitMask: showFade ? mask : "none",
|
|
122
|
+
mask: showFade ? mask : "none"
|
|
123
|
+
},
|
|
124
|
+
"data-qa": "scrollable-container__fade",
|
|
125
|
+
children
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ jsx(
|
|
129
|
+
motion.div,
|
|
130
|
+
{
|
|
131
|
+
className: classnames(styles.scrollButton, styles.scrollButtonRight),
|
|
132
|
+
style: { display: enableDefaultButtonsByBreakpoint ? displayRightButton : "none" },
|
|
133
|
+
children: /* @__PURE__ */ jsx(ScrollableContainerRight, { children: /* @__PURE__ */ jsx(
|
|
134
|
+
ChevronRightOutlinedSize24,
|
|
135
|
+
{
|
|
136
|
+
padding: buttonPadding,
|
|
137
|
+
borderRadius: "halfHeight",
|
|
138
|
+
initialColor: "secondary",
|
|
139
|
+
backgroundStyle: "secondary",
|
|
140
|
+
"aria-label": rightButtonAriaLabel,
|
|
141
|
+
"aria-controls": rightAriaControls
|
|
142
|
+
}
|
|
143
|
+
) })
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
);
|
|
87
149
|
};
|
|
88
150
|
|
|
89
151
|
export { ScrollableContainerDefaultLayout };
|
|
@@ -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 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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"}
|
|
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":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type FC } from 'react';
|
|
2
|
-
import { ScrollableContainerDotPagesProps } from '
|
|
2
|
+
import { ScrollableContainerDotPagesProps } from './types';
|
|
3
3
|
export declare const ScrollableContainerDotPages: FC<ScrollableContainerDotPagesProps>;
|
|
@@ -7,60 +7,72 @@ 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-
|
|
10
|
+
import { s as styles } from './scrollableContainer-BVvxwRcp.js';
|
|
11
11
|
import 'motion/react';
|
|
12
12
|
import './ObservableValue.js';
|
|
13
13
|
import '@hh.ru/magritte-internal-custom-scroll';
|
|
14
14
|
import '@hh.ru/magritte-ui-breakpoint';
|
|
15
15
|
|
|
16
16
|
const DEFAULT_DOT = 1;
|
|
17
|
-
const ScrollableContainerDotPages = ({
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
const updateActiveDot = useInitOnce(() => () => {
|
|
33
|
-
const { viewportWidth, scrollPosition, items } = scrollState;
|
|
34
|
-
const center = viewportWidth.get() / 2 + Math.abs(scrollPosition.get());
|
|
35
|
-
const activeDotItem = items.get()[activeDotRef.current - 1]?.current;
|
|
36
|
-
if (!activeDotItem ||
|
|
37
|
-
!activeDotItem[OFFSET_ATTR] ||
|
|
38
|
-
(activeDotItem[OFFSET_ATTR].left <= center && activeDotItem[OFFSET_ATTR].right >= center)) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
setDotAndEmitOnChange(findIndexNearestToSnapPoint(scrollState) + 1);
|
|
42
|
-
});
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
const unsubscribe = [
|
|
45
|
-
scrollState.scrollPosition.on('change', updateActiveDot),
|
|
46
|
-
scrollState.items.on('change', (items) => {
|
|
47
|
-
setItemsCount(items.length);
|
|
48
|
-
// удалили последний элемент и он был активный
|
|
49
|
-
if (activeDotRef.current > items.length && items.length !== 0) {
|
|
50
|
-
setDotAndEmitOnChange(clamp(activeDotRef.current, 0, items.length - 1));
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
updateActiveDot();
|
|
54
|
-
}),
|
|
55
|
-
];
|
|
56
|
-
return () => {
|
|
57
|
-
unsubscribe.forEach((fn) => fn());
|
|
58
|
-
};
|
|
59
|
-
}, [scrollState, updateActiveDot, setDotAndEmitOnChange]);
|
|
60
|
-
if (itemsCount === 0) {
|
|
61
|
-
return null;
|
|
17
|
+
const ScrollableContainerDotPages = ({
|
|
18
|
+
onChangeDot,
|
|
19
|
+
dotPagesProps,
|
|
20
|
+
offsetTop = 8
|
|
21
|
+
}) => {
|
|
22
|
+
const scrollState = useScrollState();
|
|
23
|
+
const [activeDot, setActiveDot] = useState(DEFAULT_DOT);
|
|
24
|
+
const [itemsCount, setItemsCount] = useState(0);
|
|
25
|
+
const activeDotRef = useRef(DEFAULT_DOT);
|
|
26
|
+
const onChangeDotRef = useRef(onChangeDot);
|
|
27
|
+
onChangeDotRef.current = onChangeDot;
|
|
28
|
+
const setDotAndEmitOnChange = useInitOnce(() => (dot) => {
|
|
29
|
+
if (dot === activeDotRef.current) {
|
|
30
|
+
return;
|
|
62
31
|
}
|
|
63
|
-
|
|
32
|
+
setActiveDot(dot);
|
|
33
|
+
onChangeDotRef.current?.(dot);
|
|
34
|
+
activeDotRef.current = dot;
|
|
35
|
+
});
|
|
36
|
+
const updateActiveDot = useInitOnce(() => () => {
|
|
37
|
+
const { viewportWidth, scrollPosition, items } = scrollState;
|
|
38
|
+
const center = viewportWidth.get() / 2 + Math.abs(scrollPosition.get());
|
|
39
|
+
const activeDotItem = items.get()[activeDotRef.current - 1]?.current;
|
|
40
|
+
if (!activeDotItem || !activeDotItem[OFFSET_ATTR] || activeDotItem[OFFSET_ATTR].left <= center && activeDotItem[OFFSET_ATTR].right >= center) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
setDotAndEmitOnChange(findIndexNearestToSnapPoint(scrollState) + 1);
|
|
44
|
+
});
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const unsubscribe = [
|
|
47
|
+
scrollState.scrollPosition.on("change", updateActiveDot),
|
|
48
|
+
scrollState.items.on("change", (items) => {
|
|
49
|
+
setItemsCount(items.length);
|
|
50
|
+
if (activeDotRef.current > items.length && items.length !== 0) {
|
|
51
|
+
setDotAndEmitOnChange(clamp(activeDotRef.current, 0, items.length - 1));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
updateActiveDot();
|
|
55
|
+
})
|
|
56
|
+
];
|
|
57
|
+
return () => {
|
|
58
|
+
unsubscribe.forEach((fn) => fn());
|
|
59
|
+
};
|
|
60
|
+
}, [scrollState, updateActiveDot, setDotAndEmitOnChange]);
|
|
61
|
+
if (itemsCount === 0) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
65
|
+
/* @__PURE__ */ jsx(VSpacing, { default: offsetTop }),
|
|
66
|
+
/* @__PURE__ */ jsx("div", { className: styles.dotContainer, children: /* @__PURE__ */ jsx(
|
|
67
|
+
DotPages,
|
|
68
|
+
{
|
|
69
|
+
active: activeDot,
|
|
70
|
+
count: itemsCount,
|
|
71
|
+
"data-qa": dotPagesProps?.["data-qa"] || "scrollable-container__dot-pages",
|
|
72
|
+
...dotPagesProps
|
|
73
|
+
}
|
|
74
|
+
) })
|
|
75
|
+
] });
|
|
64
76
|
};
|
|
65
77
|
|
|
66
78
|
export { ScrollableContainerDotPages };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScrollableContainerDotPages.js","sources":["src/ScrollableContainerDotPages.tsx"],"sourcesContent":["import { type FC, useState, useEffect, useRef } from 'react';\n\nimport { clamp } from '@hh.ru/magritte-internal-custom-scroll/initScrollHandlers';\nimport { DotPages } from '@hh.ru/magritte-ui-dot-pages';\nimport { useScrollState } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport { OFFSET_ATTR, ScrollableContainerDotPagesProps } from '@hh.ru/magritte-ui-scrollable-container/types';\nimport { useInitOnce, findIndexNearestToSnapPoint } from '@hh.ru/magritte-ui-scrollable-container/utils';\nimport { VSpacing } from '@hh.ru/magritte-ui-spacing';\n\nimport styles from './scrollableContainer.less';\n\nconst DEFAULT_DOT = 1;\n\nexport const ScrollableContainerDotPages: FC<ScrollableContainerDotPagesProps> = ({\n onChangeDot,\n dotPagesProps,\n offsetTop = 8,\n}) => {\n const scrollState = useScrollState();\n const [activeDot, setActiveDot] = useState(DEFAULT_DOT);\n const [itemsCount, setItemsCount] = useState(0);\n const activeDotRef = useRef(DEFAULT_DOT);\n const onChangeDotRef = useRef(onChangeDot);\n onChangeDotRef.current = onChangeDot;\n\n const setDotAndEmitOnChange = useInitOnce(() => (dot: number) => {\n if (dot === activeDotRef.current) {\n return;\n }\n setActiveDot(dot);\n onChangeDotRef.current?.(dot);\n activeDotRef.current = dot;\n });\n\n const updateActiveDot = useInitOnce(() => () => {\n const { viewportWidth, scrollPosition, items } = scrollState;\n const center = viewportWidth.get() / 2 + Math.abs(scrollPosition.get());\n const activeDotItem = items.get()[activeDotRef.current - 1]?.current;\n if (\n !activeDotItem ||\n !activeDotItem[OFFSET_ATTR] ||\n (activeDotItem[OFFSET_ATTR].left <= center && activeDotItem[OFFSET_ATTR].right >= center)\n ) {\n return;\n }\n setDotAndEmitOnChange(findIndexNearestToSnapPoint(scrollState) + 1);\n });\n\n useEffect(() => {\n const unsubscribe = [\n scrollState.scrollPosition.on('change', updateActiveDot),\n scrollState.items.on('change', (items) => {\n setItemsCount(items.length);\n // удалили последний элемент и он был активный\n if (activeDotRef.current > items.length && items.length !== 0) {\n setDotAndEmitOnChange(clamp(activeDotRef.current, 0, items.length - 1));\n return;\n }\n updateActiveDot();\n }),\n ];\n return () => {\n unsubscribe.forEach((fn) => fn());\n };\n }, [scrollState, updateActiveDot, setDotAndEmitOnChange]);\n\n if (itemsCount === 0) {\n return null;\n }\n\n return (\n <div>\n <VSpacing default={offsetTop} />\n <div className={styles.dotContainer}>\n <DotPages\n active={activeDot}\n count={itemsCount}\n data-qa={dotPagesProps?.['data-qa'] || 'scrollable-container__dot-pages'}\n {...dotPagesProps}\n />\n </div>\n </div>\n );\n};\n"],"names":[
|
|
1
|
+
{"version":3,"file":"ScrollableContainerDotPages.js","sources":["src/ScrollableContainerDotPages.tsx"],"sourcesContent":["import { type FC, useState, useEffect, useRef } from 'react';\n\nimport { clamp } from '@hh.ru/magritte-internal-custom-scroll/initScrollHandlers';\nimport { DotPages } from '@hh.ru/magritte-ui-dot-pages';\nimport { useScrollState } from '@hh.ru/magritte-ui-scrollable-container/ScrollStateProvider';\nimport { OFFSET_ATTR, ScrollableContainerDotPagesProps } from '@hh.ru/magritte-ui-scrollable-container/types';\nimport { useInitOnce, findIndexNearestToSnapPoint } from '@hh.ru/magritte-ui-scrollable-container/utils';\nimport { VSpacing } from '@hh.ru/magritte-ui-spacing';\n\nimport styles from './scrollableContainer.less';\n\nconst DEFAULT_DOT = 1;\n\nexport const ScrollableContainerDotPages: FC<ScrollableContainerDotPagesProps> = ({\n onChangeDot,\n dotPagesProps,\n offsetTop = 8,\n}) => {\n const scrollState = useScrollState();\n const [activeDot, setActiveDot] = useState(DEFAULT_DOT);\n const [itemsCount, setItemsCount] = useState(0);\n const activeDotRef = useRef(DEFAULT_DOT);\n const onChangeDotRef = useRef(onChangeDot);\n onChangeDotRef.current = onChangeDot;\n\n const setDotAndEmitOnChange = useInitOnce(() => (dot: number) => {\n if (dot === activeDotRef.current) {\n return;\n }\n setActiveDot(dot);\n onChangeDotRef.current?.(dot);\n activeDotRef.current = dot;\n });\n\n const updateActiveDot = useInitOnce(() => () => {\n const { viewportWidth, scrollPosition, items } = scrollState;\n const center = viewportWidth.get() / 2 + Math.abs(scrollPosition.get());\n const activeDotItem = items.get()[activeDotRef.current - 1]?.current;\n if (\n !activeDotItem ||\n !activeDotItem[OFFSET_ATTR] ||\n (activeDotItem[OFFSET_ATTR].left <= center && activeDotItem[OFFSET_ATTR].right >= center)\n ) {\n return;\n }\n setDotAndEmitOnChange(findIndexNearestToSnapPoint(scrollState) + 1);\n });\n\n useEffect(() => {\n const unsubscribe = [\n scrollState.scrollPosition.on('change', updateActiveDot),\n scrollState.items.on('change', (items) => {\n setItemsCount(items.length);\n // удалили последний элемент и он был активный\n if (activeDotRef.current > items.length && items.length !== 0) {\n setDotAndEmitOnChange(clamp(activeDotRef.current, 0, items.length - 1));\n return;\n }\n updateActiveDot();\n }),\n ];\n return () => {\n unsubscribe.forEach((fn) => fn());\n };\n }, [scrollState, updateActiveDot, setDotAndEmitOnChange]);\n\n if (itemsCount === 0) {\n return null;\n }\n\n return (\n <div>\n <VSpacing default={offsetTop} />\n <div className={styles.dotContainer}>\n <DotPages\n active={activeDot}\n count={itemsCount}\n data-qa={dotPagesProps?.['data-qa'] || 'scrollable-container__dot-pages'}\n {...dotPagesProps}\n />\n </div>\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type FC } from 'react';
|
|
2
|
-
import type { ScrollableContainerGalleryProps, RegisterAndRemoveItem } from '
|
|
2
|
+
import type { ScrollableContainerGalleryProps, RegisterAndRemoveItem } from './types';
|
|
3
3
|
export declare const useGalleryContext: () => RegisterAndRemoveItem;
|
|
4
4
|
export declare const ScrollableContainerGallery: FC<ScrollableContainerGalleryProps>;
|
|
@@ -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-
|
|
9
|
+
import { s as styles } from './scrollableContainer-BVvxwRcp.js';
|
|
10
10
|
import './ObservableValue.js';
|
|
11
11
|
import '@hh.ru/magritte-common-func-utils';
|
|
12
12
|
import '@hh.ru/magritte-internal-custom-scroll';
|
|
@@ -15,62 +15,93 @@ import './useScrollableControls.js';
|
|
|
15
15
|
import '@hh.ru/magritte-ui-breakpoint';
|
|
16
16
|
|
|
17
17
|
const GalleryContext = createContext({
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
registerItem: () => null,
|
|
19
|
+
removeItem: () => null
|
|
20
20
|
});
|
|
21
21
|
const useGalleryContext = () => useContext(GalleryContext);
|
|
22
|
-
const ScrollableContainerGallery = ({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
22
|
+
const ScrollableContainerGallery = ({
|
|
23
|
+
children,
|
|
24
|
+
onScroll,
|
|
25
|
+
onReady,
|
|
26
|
+
onChangeSize,
|
|
27
|
+
...props
|
|
28
|
+
}) => {
|
|
29
|
+
const scrollState = useScrollState();
|
|
30
|
+
const onReadyRef = useRef(onReady);
|
|
31
|
+
const onScrollRef = useRef(onScroll);
|
|
32
|
+
const onChangeSizeRef = useRef(onChangeSize);
|
|
33
|
+
onReadyRef.current = onReady;
|
|
34
|
+
onScrollRef.current = onScroll;
|
|
35
|
+
onChangeSizeRef.current = onChangeSize;
|
|
36
|
+
const { registerItem, removeItem, initScrollHandlers, containerRef, positionContainerRef, isTouch } = useScrollContainer();
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const { scrollPosition, viewportWidth, contentWidth } = scrollState;
|
|
39
|
+
const updateScrollPositionByResize = () => {
|
|
40
|
+
const index = findIndexNearestToSnapPoint(scrollState);
|
|
41
|
+
const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);
|
|
42
|
+
const target = scrollSnapBehavior(scrollState, index);
|
|
43
|
+
if (target === null) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const position = clamp(target, viewportWidth.get() - contentWidth.get(), 0);
|
|
47
|
+
onChangeSizeRef.current?.(getDisableState(scrollState));
|
|
48
|
+
if (scrollPosition.get() === position) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
animate(scrollPosition, position, {
|
|
52
|
+
velocity: Math.max(scrollPosition.getVelocity(), 1)
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
const unsubscribe = [
|
|
56
|
+
scrollPosition.on("change", () => {
|
|
57
|
+
onScrollRef.current?.(getDisableState(scrollState));
|
|
58
|
+
}),
|
|
59
|
+
viewportWidth.on("change", updateScrollPositionByResize),
|
|
60
|
+
contentWidth.on("change", updateScrollPositionByResize)
|
|
61
|
+
];
|
|
62
|
+
return () => {
|
|
63
|
+
unsubscribe.forEach((fn) => fn());
|
|
64
|
+
};
|
|
65
|
+
}, [scrollState]);
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
onReadyRef.current?.(getDisableState(scrollState));
|
|
68
|
+
return initScrollHandlers();
|
|
69
|
+
}, [initScrollHandlers, scrollState]);
|
|
70
|
+
const springScrollPosition = useSpring(scrollState.scrollPosition, {
|
|
71
|
+
stiffness: 1800,
|
|
72
|
+
damping: 75,
|
|
73
|
+
mass: 0.5
|
|
74
|
+
});
|
|
75
|
+
scrollState.springScrollPosition = springScrollPosition;
|
|
76
|
+
return /* @__PURE__ */ jsx(
|
|
77
|
+
GalleryContext.Provider,
|
|
78
|
+
{
|
|
79
|
+
value: {
|
|
80
|
+
registerItem,
|
|
81
|
+
removeItem
|
|
82
|
+
},
|
|
83
|
+
children: /* @__PURE__ */ jsx(
|
|
84
|
+
"div",
|
|
85
|
+
{
|
|
86
|
+
ref: containerRef,
|
|
87
|
+
role: "list",
|
|
88
|
+
className: styles.scrollableContainer,
|
|
89
|
+
"data-qa": "scrollable-container__overflow-container",
|
|
90
|
+
...props,
|
|
91
|
+
children: /* @__PURE__ */ jsx(
|
|
92
|
+
motion.div,
|
|
93
|
+
{
|
|
94
|
+
ref: positionContainerRef,
|
|
95
|
+
"data-qa": "scrollable-container__position-container",
|
|
96
|
+
className: styles.positionContainer,
|
|
97
|
+
style: { x: isTouch ? scrollState.scrollPosition : springScrollPosition },
|
|
98
|
+
children
|
|
39
99
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
animate(scrollPosition, position, {
|
|
46
|
-
velocity: Math.max(scrollPosition.getVelocity(), 1),
|
|
47
|
-
});
|
|
48
|
-
};
|
|
49
|
-
const unsubscribe = [
|
|
50
|
-
scrollPosition.on('change', () => {
|
|
51
|
-
onScrollRef.current?.(getDisableState(scrollState));
|
|
52
|
-
}),
|
|
53
|
-
viewportWidth.on('change', updateScrollPositionByResize),
|
|
54
|
-
contentWidth.on('change', updateScrollPositionByResize),
|
|
55
|
-
];
|
|
56
|
-
return () => {
|
|
57
|
-
unsubscribe.forEach((fn) => fn());
|
|
58
|
-
};
|
|
59
|
-
}, [scrollState]);
|
|
60
|
-
useEffect(() => {
|
|
61
|
-
onReadyRef.current?.(getDisableState(scrollState));
|
|
62
|
-
return initScrollHandlers();
|
|
63
|
-
}, [initScrollHandlers, scrollState]);
|
|
64
|
-
const springScrollPosition = useSpring(scrollState.scrollPosition, {
|
|
65
|
-
stiffness: 1800,
|
|
66
|
-
damping: 75,
|
|
67
|
-
mass: 0.5,
|
|
68
|
-
});
|
|
69
|
-
scrollState.springScrollPosition = springScrollPosition;
|
|
70
|
-
return (jsx(GalleryContext.Provider, { value: {
|
|
71
|
-
registerItem,
|
|
72
|
-
removeItem,
|
|
73
|
-
}, children: jsx("div", { ref: containerRef, role: "list", className: styles.scrollableContainer, "data-qa": "scrollable-container__overflow-container", ...props, children: jsx(motion.div, { ref: positionContainerRef, "data-qa": "scrollable-container__position-container", className: styles.positionContainer, style: { x: isTouch ? scrollState.scrollPosition : springScrollPosition }, children: children }) }) }));
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
);
|
|
74
105
|
};
|
|
75
106
|
|
|
76
107
|
export { ScrollableContainerGallery, useGalleryContext };
|