diff --git a/packages/vkui/src/components/BaseGallery/BaseGallery.tsx b/packages/vkui/src/components/BaseGallery/BaseGallery.tsx
index 0926ab9122..eaeceeedc2 100644
--- a/packages/vkui/src/components/BaseGallery/BaseGallery.tsx
+++ b/packages/vkui/src/components/BaseGallery/BaseGallery.tsx
@@ -143,6 +143,13 @@ export const BaseGallery = ({
localSlides.length <= layoutState.current.slides.length ||
layoutState.current.slides[slideIndex]?.coordX !== localSlides[slideIndex]?.coordX;
+ const currentSlideOffsetOnCenterAlignment =
+ (localContainerWidth - (localSlides[slideIndex]?.width ?? 0)) / 2;
+ const isFullyVisible =
+ align === 'center'
+ ? localLayerWidth + currentSlideOffsetOnCenterAlignment <= localContainerWidth
+ : localLayerWidth <= localContainerWidth;
+
layoutState.current = {
containerWidth: localContainerWidth,
viewportOffsetWidth: localViewportOffsetWidth,
@@ -161,7 +168,7 @@ export const BaseGallery = ({
align,
}),
slides: localSlides,
- isFullyVisible: localLayerWidth <= localContainerWidth,
+ isFullyVisible,
};
setShiftState((prevState) => ({
diff --git a/packages/vkui/src/components/Gallery/Gallery.test.tsx b/packages/vkui/src/components/Gallery/Gallery.test.tsx
index 67b81eeb37..3131864f76 100644
--- a/packages/vkui/src/components/Gallery/Gallery.test.tsx
+++ b/packages/vkui/src/components/Gallery/Gallery.test.tsx
@@ -73,13 +73,14 @@ const setup = ({
looped,
containerWidth: defaultContainerWidth,
isCustomSlideWidth = false,
- viewPortWidth,
+ viewPortWidth: defaultViewPortWidth,
align,
onChange,
onNext,
onPrev,
onDragStart,
onDragEnd,
+ numberOfSlides = 5,
}: {
defaultSlideIndex: number;
looped: boolean;
@@ -87,6 +88,7 @@ const setup = ({
isCustomSlideWidth?: boolean;
containerWidth: number;
viewPortWidth: number;
+ numberOfSlides?: number;
align?: AlignType;
onChange: VoidFunction;
onNext?: VoidFunction;
@@ -99,6 +101,7 @@ const setup = ({
let layerTransform = '';
let viewPort: HTMLDivElement;
let containerWidth = defaultContainerWidth;
+ let viewPortWidth = defaultViewPortWidth;
const mockContainerData = (element: HTMLDivElement) => {
if (!element) {
@@ -161,21 +164,15 @@ const setup = ({
getRootRef={mockContainerData}
getRef={mockViewportData}
>
- mockSlideData(e, 0)}>
- 1
-
- mockSlideData(e, 1)}>
- 2
-
- mockSlideData(e, 2)}>
- 3
-
- mockSlideData(e, 3)}>
- 4
-
- mockSlideData(e, 4)}>
- 5
-
+ {Array.from({ length: numberOfSlides }).map((_v, index) => (
+ mockSlideData(e, index)}
+ >
+ {index + 1}
+
+ ))}
);
@@ -200,6 +197,9 @@ const setup = ({
set containerWidth(newWidth: number) {
containerWidth = newWidth;
},
+ set viewPortWidth(newWidth: number) {
+ viewPortWidth = newWidth;
+ },
};
};
@@ -636,4 +636,70 @@ describe('Gallery', () => {
process.env.NODE_ENV = 'test';
});
});
+
+ it('checks gallery arrows and navigation in center alignment', () => {
+ const onChange = jest.fn();
+ const onDragStart = jest.fn();
+ const onDragEnd = jest.fn();
+
+ // в контейнере недостаточно места для
+ // двух слайдов с выравниванием по центру
+ // поэтому мы показываем кнопки и позволяем drag
+ const mockedData = setup({
+ numberOfSlides: 2,
+ defaultSlideIndex: 2,
+ slideWidth: 180,
+ containerWidth: 300,
+ viewPortWidth: 300,
+ align: 'center',
+ looped: false,
+ onDragStart,
+ onDragEnd,
+ onChange,
+ });
+ const {
+ component: { container },
+ rerender,
+ } = mockedData;
+
+ checkActiveSlide(container, 1);
+ expect(Array.from(container.getElementsByClassName(styles.arrow))).toHaveLength(1);
+
+ simulateDrag(mockedData.viewPort, [150, 0]);
+
+ expect(onDragStart).toHaveBeenCalledTimes(1);
+ expect(onDragEnd).toHaveBeenCalledTimes(1);
+
+ // это пограничное состояние при котором слайды ещё
+ // не помещаются в контейнер,
+ // при ширине контейнера 540 они уже будут влезать
+ mockedData.containerWidth = 539;
+ mockedData.viewPortWidth = 539;
+ onDragStart.mockClear();
+ onDragEnd.mockClear();
+
+ rerender({ slideIndex: 2 });
+
+ expect(Array.from(container.getElementsByClassName(styles.arrow))).toHaveLength(1);
+
+ simulateDrag(mockedData.viewPort, [150, 0]);
+
+ expect(onDragStart).toHaveBeenCalledTimes(1);
+ expect(onDragEnd).toHaveBeenCalledTimes(1);
+
+ // слайды полностью помещаются, поэтому мы отключаем drag и не показываем стрелочки
+ mockedData.containerWidth = 540;
+ mockedData.viewPortWidth = 540;
+ onDragStart.mockClear();
+ onDragEnd.mockClear();
+
+ rerender({ slideIndex: 2 });
+
+ expect(Array.from(container.getElementsByClassName(styles.arrow))).toHaveLength(0);
+
+ simulateDrag(mockedData.viewPort, [150, 0]);
+
+ expect(onDragStart).not.toHaveBeenCalled();
+ expect(onDragEnd).not.toHaveBeenCalled();
+ });
});