@hh.ru/magritte-ui-scrollable-container 6.5.2 → 6.5.3

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.
Files changed (44) hide show
  1. package/ObservableValue.js +17 -17
  2. package/ObservableValue.js.map +1 -1
  3. package/ScrollStateProvider.d.ts +2 -2
  4. package/ScrollStateProvider.js +11 -11
  5. package/ScrollStateProvider.js.map +1 -1
  6. package/ScrollableContainer.d.ts +8 -8
  7. package/ScrollableContainer.js +99 -60
  8. package/ScrollableContainer.js.map +1 -1
  9. package/ScrollableContainerButton.d.ts +1 -1
  10. package/ScrollableContainerButton.js +15 -12
  11. package/ScrollableContainerButton.js.map +1 -1
  12. package/ScrollableContainerDefaultLayout.d.ts +1 -1
  13. package/ScrollableContainerDefaultLayout.js +130 -68
  14. package/ScrollableContainerDefaultLayout.js.map +1 -1
  15. package/ScrollableContainerDotPages.d.ts +1 -1
  16. package/ScrollableContainerDotPages.js +59 -47
  17. package/ScrollableContainerDotPages.js.map +1 -1
  18. package/ScrollableContainerGallery.d.ts +1 -1
  19. package/ScrollableContainerGallery.js +85 -54
  20. package/ScrollableContainerGallery.js.map +1 -1
  21. package/ScrollableItem.d.ts +1 -1
  22. package/ScrollableItem.js +22 -12
  23. package/ScrollableItem.js.map +1 -1
  24. package/index.css +19 -19
  25. package/index.d.ts +6 -6
  26. package/index.js +1 -1
  27. package/index.mock.d.ts +4 -4
  28. package/index.mock.js +21 -21
  29. package/index.mock.js.map +1 -1
  30. package/package.json +6 -6
  31. package/scrollableContainer-CWsF-84M.js +5 -0
  32. package/scrollableContainer-CWsF-84M.js.map +1 -0
  33. package/types.js +1 -1
  34. package/types.js.map +1 -1
  35. package/useScrollContainer.js +181 -157
  36. package/useScrollContainer.js.map +1 -1
  37. package/useScrollableControls.d.ts +2 -2
  38. package/useScrollableControls.js +90 -72
  39. package/useScrollableControls.js.map +1 -1
  40. package/utils.d.ts +2 -2
  41. package/utils.js +157 -254
  42. package/utils.js.map +1 -1
  43. package/scrollableContainer-C0a8z9uL.js +0 -5
  44. 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-C0a8z9uL.js';
12
+ import { s as styles } from './scrollableContainer-CWsF-84M.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
- medium: { padding: 8, buttonWidth: 44, minHeight: 40 },
20
- small: { padding: 4, buttonWidth: 36, minHeight: 32 },
19
+ medium: { padding: 8, buttonWidth: 44, minHeight: 40 },
20
+ small: { padding: 4, buttonWidth: 36, minHeight: 32 }
21
21
  };
22
- const ScrollableContainerDefaultLayout = ({ children, size = 'medium', fadeOnMobile = false, noFadeOnDesktop = false, buttonsOffset = 0, buttonsOnHover = false, leftButtonAriaLabel: _leftAriaLabel, rightButtonAriaLabel: _rightAriaLabel, leftAriaControls, rightAriaControls, }) => {
23
- const { padding: buttonPadding, buttonWidth: buttonWidthCorrection, minHeight } = SIZE_CONFIG[size];
24
- const scrollState = useScrollState();
25
- const displayLeftButton = useMotionValue('none');
26
- const displayRightButton = useMotionValue('none');
27
- const mask = useMotionValue('none');
28
- const breakpoint = useBreakpoint();
29
- const breakpointIndex = BREAKPOINTS_LIST.indexOf(breakpoint.breakpoint);
30
- const noButtonBreakpointIndex = BREAKPOINTS_LIST.indexOf(NO_BUTTONS_START_FROM_BREAKPOINT);
31
- const enableDefaultButtonsByBreakpoint = breakpointIndex > noButtonBreakpointIndex;
32
- const showFade = enableDefaultButtonsByBreakpoint ? !noFadeOnDesktop : fadeOnMobile;
33
- const leftAriaLabelTrl = useTranslation('ScrollableContainer', 'left');
34
- const leftButtonAriaLabel = _leftAriaLabel ?? leftAriaLabelTrl;
35
- const rightAriaLabelTrl = useTranslation('ScrollableContainer', 'right');
36
- const rightButtonAriaLabel = _rightAriaLabel ?? rightAriaLabelTrl;
37
- const updateFadeAndButtons = useInitOnce(() => () => {
38
- const position = scrollState.scrollPosition.get();
39
- const contentWidth = scrollState.contentWidth.get();
40
- const viewportWidth = scrollState.viewportWidth.get();
41
- const showLeftButton = position < 0;
42
- const showRightButton = Math.abs(position) < Math.max(0, contentWidth - viewportWidth);
43
- displayLeftButton.set(showLeftButton ? 'block' : 'none');
44
- displayRightButton.set(showRightButton ? 'block' : 'none');
45
- if (showLeftButton && showRightButton) {
46
- mask.set('var(--both-sides-mask)');
47
- }
48
- else if (showLeftButton) {
49
- mask.set('var(--left-fade-mask)');
50
- }
51
- else if (showRightButton) {
52
- mask.set('var(--right-fade-mask)');
53
- }
54
- else {
55
- mask.set('none');
56
- }
57
- });
58
- useEffect(() => {
59
- updateFadeAndButtons();
60
- const unsubscribe = [
61
- scrollState.scrollPosition.on('change', updateFadeAndButtons),
62
- scrollState.contentWidth.on('change', updateFadeAndButtons),
63
- scrollState.viewportWidth.on('change', updateFadeAndButtons),
64
- ];
65
- return () => {
66
- unsubscribe.forEach((fn) => fn());
67
- };
68
- }, [scrollState, updateFadeAndButtons]);
69
- useEffect(() => {
70
- // кнопка закрывает край контента на свою ширину плюс отступ от края
71
- scrollState.defaultButtonsCorrection.set(enableDefaultButtonsByBreakpoint ? buttonWidthCorrection + buttonsOffset : 0);
72
- return () => {
73
- scrollState.defaultButtonsCorrection.set(0);
74
- };
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, {
82
- [styles.scrollButtonsSmall]: size === 'small',
83
- }), style: {
84
- WebkitMask: showFade ? mask : 'none',
85
- mask: showFade ? mask : 'none',
86
- }, "data-qa": "scrollable-container__fade", children: children }), jsx(motion.div, { className: classnames(styles.scrollButton, styles.scrollButtonRight), style: { display: enableDefaultButtonsByBreakpoint ? displayRightButton : 'none' }, children: jsx(ScrollableContainerRight, { children: jsx(ChevronRightOutlinedSize24, { padding: buttonPadding, borderRadius: "halfHeight", initialColor: "secondary", backgroundStyle: "secondary", "aria-label": rightButtonAriaLabel, "aria-controls": rightAriaControls }) }) })] }));
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 '@hh.ru/magritte-ui-scrollable-container/types';
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-C0a8z9uL.js';
10
+ import { s as styles } from './scrollableContainer-CWsF-84M.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 = ({ onChangeDot, dotPagesProps, offsetTop = 8, }) => {
18
- const scrollState = useScrollState();
19
- const [activeDot, setActiveDot] = useState(DEFAULT_DOT);
20
- const [itemsCount, setItemsCount] = useState(0);
21
- const activeDotRef = useRef(DEFAULT_DOT);
22
- const onChangeDotRef = useRef(onChangeDot);
23
- onChangeDotRef.current = onChangeDot;
24
- const setDotAndEmitOnChange = useInitOnce(() => (dot) => {
25
- if (dot === activeDotRef.current) {
26
- return;
27
- }
28
- setActiveDot(dot);
29
- onChangeDotRef.current?.(dot);
30
- activeDotRef.current = dot;
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
- return (jsxs("div", { children: [jsx(VSpacing, { default: offsetTop }), jsx("div", { className: styles.dotContainer, children: jsx(DotPages, { active: activeDot, count: itemsCount, "data-qa": dotPagesProps?.['data-qa'] || 'scrollable-container__dot-pages', ...dotPagesProps }) })] }));
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":["_jsxs","_jsx"],"mappings":"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"}
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":";;;;;;;;;;;;;;AAWA,MAAM,WAAc,GAAA,CAAA,CAAA;AAEb,MAAM,8BAAoE,CAAC;AAAA,EAC9E,WAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAY,GAAA,CAAA;AAChB,CAAM,KAAA;AACF,EAAA,MAAM,cAAc,cAAe,EAAA,CAAA;AACnC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,WAAW,CAAA,CAAA;AACtD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,CAAC,CAAA,CAAA;AAC9C,EAAM,MAAA,YAAA,GAAe,OAAO,WAAW,CAAA,CAAA;AACvC,EAAM,MAAA,cAAA,GAAiB,OAAO,WAAW,CAAA,CAAA;AACzC,EAAA,cAAA,CAAe,OAAU,GAAA,WAAA,CAAA;AAEzB,EAAA,MAAM,qBAAwB,GAAA,WAAA,CAAY,MAAM,CAAC,GAAgB,KAAA;AAC7D,IAAI,IAAA,GAAA,KAAQ,aAAa,OAAS,EAAA;AAC9B,MAAA,OAAA;AAAA,KACJ;AACA,IAAA,YAAA,CAAa,GAAG,CAAA,CAAA;AAChB,IAAA,cAAA,CAAe,UAAU,GAAG,CAAA,CAAA;AAC5B,IAAA,YAAA,CAAa,OAAU,GAAA,GAAA,CAAA;AAAA,GAC1B,CAAA,CAAA;AAED,EAAM,MAAA,eAAA,GAAkB,WAAY,CAAA,MAAM,MAAM;AAC5C,IAAA,MAAM,EAAE,aAAA,EAAe,cAAgB,EAAA,KAAA,EAAU,GAAA,WAAA,CAAA;AACjD,IAAM,MAAA,MAAA,GAAS,cAAc,GAAI,EAAA,GAAI,IAAI,IAAK,CAAA,GAAA,CAAI,cAAe,CAAA,GAAA,EAAK,CAAA,CAAA;AACtE,IAAA,MAAM,gBAAgB,KAAM,CAAA,GAAA,GAAM,YAAa,CAAA,OAAA,GAAU,CAAC,CAAG,EAAA,OAAA,CAAA;AAC7D,IAAA,IACI,CAAC,aAAA,IACD,CAAC,aAAA,CAAc,WAAW,CACzB,IAAA,aAAA,CAAc,WAAW,CAAA,CAAE,QAAQ,MAAU,IAAA,aAAA,CAAc,WAAW,CAAA,CAAE,SAAS,MACpF,EAAA;AACE,MAAA,OAAA;AAAA,KACJ;AACA,IAAsB,qBAAA,CAAA,2BAAA,CAA4B,WAAW,CAAA,GAAI,CAAC,CAAA,CAAA;AAAA,GACrE,CAAA,CAAA;AAED,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,MAAM,WAAc,GAAA;AAAA,MAChB,WAAY,CAAA,cAAA,CAAe,EAAG,CAAA,QAAA,EAAU,eAAe,CAAA;AAAA,MACvD,WAAY,CAAA,KAAA,CAAM,EAAG,CAAA,QAAA,EAAU,CAAC,KAAU,KAAA;AACtC,QAAA,aAAA,CAAc,MAAM,MAAM,CAAA,CAAA;AAE1B,QAAA,IAAI,aAAa,OAAU,GAAA,KAAA,CAAM,MAAU,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AAC3D,UAAA,qBAAA,CAAsB,MAAM,YAAa,CAAA,OAAA,EAAS,GAAG,KAAM,CAAA,MAAA,GAAS,CAAC,CAAC,CAAA,CAAA;AACtE,UAAA,OAAA;AAAA,SACJ;AACA,QAAgB,eAAA,EAAA,CAAA;AAAA,OACnB,CAAA;AAAA,KACL,CAAA;AACA,IAAA,OAAO,MAAM;AACT,MAAA,WAAA,CAAY,OAAQ,CAAA,CAAC,EAAO,KAAA,EAAA,EAAI,CAAA,CAAA;AAAA,KACpC,CAAA;AAAA,GACD,EAAA,CAAC,WAAa,EAAA,eAAA,EAAiB,qBAAqB,CAAC,CAAA,CAAA;AAExD,EAAA,IAAI,eAAe,CAAG,EAAA;AAClB,IAAO,OAAA,IAAA,CAAA;AAAA,GACX;AAEA,EAAA,4BACK,KACG,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAC,GAAA,CAAA,QAAA,EAAA,EAAS,SAAS,SAAW,EAAA,CAAA;AAAA,oBAC7B,GAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,MAAA,CAAO,YACnB,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACG,MAAQ,EAAA,SAAA;AAAA,QACR,KAAO,EAAA,UAAA;AAAA,QACP,SAAA,EAAS,aAAgB,GAAA,SAAS,CAAK,IAAA,iCAAA;AAAA,QACtC,GAAG,aAAA;AAAA,OAAA;AAAA,KAEZ,EAAA,CAAA;AAAA,GACJ,EAAA,CAAA,CAAA;AAER;;;;"}
@@ -1,4 +1,4 @@
1
1
  import { type FC } from 'react';
2
- import type { ScrollableContainerGalleryProps, RegisterAndRemoveItem } from '@hh.ru/magritte-ui-scrollable-container/types';
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-C0a8z9uL.js';
9
+ import { s as styles } from './scrollableContainer-CWsF-84M.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
- registerItem: () => null,
19
- removeItem: () => null,
18
+ registerItem: () => null,
19
+ removeItem: () => null
20
20
  });
21
21
  const useGalleryContext = () => useContext(GalleryContext);
22
- const ScrollableContainerGallery = ({ children, onScroll, onReady, onChangeSize, ...props }) => {
23
- const scrollState = useScrollState();
24
- const onReadyRef = useRef(onReady);
25
- const onScrollRef = useRef(onScroll);
26
- const onChangeSizeRef = useRef(onChangeSize);
27
- onReadyRef.current = onReady;
28
- onScrollRef.current = onScroll;
29
- onChangeSizeRef.current = onChangeSize;
30
- const { registerItem, removeItem, initScrollHandlers, containerRef, positionContainerRef, isTouch } = useScrollContainer();
31
- useEffect(() => {
32
- const { scrollPosition, viewportWidth, contentWidth } = scrollState;
33
- const updateScrollPositionByResize = () => {
34
- const index = findIndexNearestToSnapPoint(scrollState);
35
- const scrollSnapBehavior = computeScrollSnapBehavior(scrollState);
36
- const target = scrollSnapBehavior(scrollState, index);
37
- if (target === null) {
38
- return;
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
- const position = clamp(target, viewportWidth.get() - contentWidth.get(), 0);
41
- onChangeSizeRef.current?.(getDisableState(scrollState));
42
- if (scrollPosition.get() === position) {
43
- return;
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 };