Skip to content

Commit

Permalink
feat: universal modal transition refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
fulcanellee committed Dec 20, 2024
1 parent 8e0d982 commit fd7e84a
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 168 deletions.
50 changes: 13 additions & 37 deletions packages/universal-modal/src/Component.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { render, screen } from '@testing-library/react';
import { UniversalModalDesktop } from './desktop';
import { UniversalModalMobile } from './mobile';
import { getUniversalModalTestIds } from './utils';
import { getUniversalModalTestIds } from './utils/getUniversalModalTestIds';
import { UniversalModalResponsive } from './Component.responsive';

Object.defineProperty(window, 'matchMedia', {
Expand Down Expand Up @@ -163,9 +163,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 0');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 0');
});

it('position horizontal=start vertical=top', () => {
Expand All @@ -182,9 +180,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 0');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 0');
});

it('position horizontal=start vertical=bottom', () => {
Expand All @@ -201,9 +197,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 0');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 0');
});

it('position horizontal=end vertical=center', () => {
Expand All @@ -220,9 +214,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 0');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 0');
});

it('position horizontal=end vertical=top', () => {
Expand All @@ -239,9 +231,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 0');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 0');
});

it('position horizontal=end vertical=bottom', () => {
Expand All @@ -258,9 +248,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 0');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 0');
});
});

Expand Down Expand Up @@ -340,9 +328,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 12px');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 12px');
});

it('position horizontal=start vertical=top', () => {
Expand All @@ -360,9 +346,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 12px');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 12px');
});

it('position horizontal=start vertical=bottom', () => {
Expand All @@ -380,9 +364,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 12px');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 12px');
});

it('position horizontal=end vertical=center', () => {
Expand All @@ -400,9 +382,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 12px');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 12px');
});

it('position horizontal=end vertical=top', () => {
Expand All @@ -420,9 +400,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 12px');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 12px');
});

it('position horizontal=end vertical=bottom', () => {
Expand All @@ -440,9 +418,7 @@ describe('UniversalModal', () => {

const testIds = getUniversalModalTestIds(dti);

expect(
screen.getByTestId(testIds.modal).firstElementChild?.firstElementChild,
).toHaveStyle('margin: 12px');
expect(screen.getByTestId(testIds.modal).firstElementChild).toHaveStyle('margin: 12px');
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,28 @@
align-items: end;
}

.wrapperJustifyCenter {
justify-content: center;
}

.wrapperJustifyEnd {
justify-content: end;
}

.component {
display: flex;
align-items: start;
min-width: 500px;
min-height: 264px;
height: 100%;
border-radius: var(--border-radius-24);
overflow-x: hidden;
margin: unset;
background-color: unset;
will-change: transform;

&.componentAlignCenter {
align-items: center;
}

&.componentAlignEnd {
align-items: end;
}

&.overlayHidden {
box-shadow: var(--shadow-m);
}

& .content {
border-radius: var(--border-radius-24);
background-color: var(--color-light-modal-bg-primary);
overflow-x: hidden;

& .container {
height: 100%;
}
& .container {
height: 100%;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { forwardRef, useCallback, useEffect, useRef } from 'react';
import { TransitionProps } from 'react-transition-group/Transition';
import React, { forwardRef, useRef } from 'react';
import cn from 'classnames';

import { BaseModal } from '@alfalab/core-components-base-modal';
Expand All @@ -12,7 +11,7 @@ import { ModalBySideProps } from '../../types/props';
import { BaseUniversalModalContent } from '../base-universal-modal-content/base-universal-modal-content';

import styles from './side-modal.module.css';
import transitions from './transitions.module.css';
import { getMarginValues } from '../../../utils/getMarginValues';

export const SideModal = forwardRef<HTMLDivElement, ModalBySideProps>((props, ref) => {
const {
Expand All @@ -32,61 +31,17 @@ export const SideModal = forwardRef<HTMLDivElement, ModalBySideProps>((props, re
const componentRef = useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement>(null);

useModalMargin({ margin, open, componentRef: contentRef, horizontalAlign, verticalAlign });
useModalWidth(width, open, contentRef);
useModalHeight(height, open, contentRef);
useModalMargin({ margin, open, componentRef, horizontalAlign, verticalAlign });
useModalWidth(width, open, componentRef);
useModalHeight(height, open, componentRef);
const { wheelDeltaY, handleWheel } = useModalWheel(overlay);

const isHorizontalStart = horizontalAlign === 'start';
const isHorizontalEnd = horizontalAlign === 'end';
const isVerticalCenter = verticalAlign === 'center';
const isVerticalBottom = verticalAlign === 'bottom';

const enter = cn({
[transitions.enterLeft]: isHorizontalStart,
[transitions.enterRight]: isHorizontalEnd,
});

const transitionProps: Partial<TransitionProps> = {
appear: enter,
enter,
appearActive: transitions.enterActive,
enterActive: transitions.enterActive,
enterDone: transitions.enterDone,
exit: transitions.exit,
exitActive: cn({
[transitions.exitActiveLeft]: isHorizontalStart,
[transitions.exitActiveRight]: isHorizontalEnd,
}),
};

// главная обёртка компонента может содержать пустоты в виде отступов, необходимо закрывать мадалку при клике на них
const handleContentOutsideClick = useCallback(
(e: MouseEvent) => {
const target = e.target as HTMLElement;

if (contentRef.current && !contentRef.current.contains(target)) {
if (onClose) {
onClose();
}
}
},
[onClose],
);

useEffect(() => {
const element = componentRef.current;

if (element) {
element.addEventListener('click', handleContentOutsideClick);
}

return () => {
if (element) {
element.removeEventListener('click', handleContentOutsideClick);
}
};
}, [open, handleContentOutsideClick]);
const { right, left } = getMarginValues(margin);

return (
<BaseModal
Expand All @@ -101,16 +56,55 @@ export const SideModal = forwardRef<HTMLDivElement, ModalBySideProps>((props, re
wrapperClassName={cn({
[styles.wrapperAlignStart]: isHorizontalStart,
[styles.wrapperAlignEnd]: isHorizontalEnd,
[styles.wrapperJustifyCenter]: isVerticalCenter,
[styles.wrapperJustifyEnd]: isVerticalBottom,
})}
className={cn(className, styles.component, {
[styles.componentAlignCenter]: isVerticalCenter,
[styles.componentAlignEnd]: isVerticalBottom,
[styles.overlayHidden]: !overlay,
})}
contentClassName={styles.content}
transitionProps={{
classNames: transitionProps,
classNames: {},
timeout: 200,
onEnter: () => {
if (componentRef.current) {
if (isHorizontalStart) {
componentRef.current.style.transform = `translateX(calc(-100% - ${left}px))`;
}
if (isHorizontalEnd) {
componentRef.current.style.transform = `translateX(calc(100% + ${right}px))`;
}
}
},
onEntering: () => {
if (componentRef.current) {
componentRef.current.style.transform = 'translateX(0)';
componentRef.current.style.transition = 'transform 200ms ease-in';
}
},
onEntered: () => {
if (componentRef.current) {
componentRef.current.style.transform = 'translateX(0)';
}
},
onExit: () => {
if (componentRef.current) {
componentRef.current.style.transform = 'translateX(0)';
}
},
onExiting: () => {
if (componentRef.current) {
componentRef.current.style.transition = 'transform 200ms ease-out';

if (isHorizontalStart) {
componentRef.current.style.transform = `translateX(calc(-100% - ${left}px))`;
}

if (isHorizontalEnd) {
componentRef.current.style.transform = `translateX(calc(100% + ${right}px))`;
}
}
},
}}
backdropProps={{
transparent: !overlay,
Expand Down

This file was deleted.

8 changes: 2 additions & 6 deletions packages/universal-modal/src/desktop/types/props.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BaseModalProps } from '@alfalab/core-components-base-modal';

import { TMargin } from './typings';
import { TMargin } from '../../typings/margin-type';

export type BaseUniversalModalProps = {
/**
Expand Down Expand Up @@ -41,11 +41,7 @@ export type BaseUniversalModalProps = {
* Устанавливает отступы модального окна
* По умолчанию для бокового модала 0px, для центрального auto
*/
margin?:
| [TMargin, TMargin, TMargin, TMargin]
| [TMargin, TMargin, TMargin]
| [TMargin, TMargin]
| [TMargin];
margin?: TMargin;

/**
* Хэндлер закрытия модалки
Expand Down
Loading

0 comments on commit fd7e84a

Please sign in to comment.