Skip to content

Commit

Permalink
Create ModalPopoutPortal to keep previous logic of SplitLayout
Browse files Browse the repository at this point in the history
In full mode we render Modal/Popout right after content
In other modes we render Modal/Popout as a child of the body
  • Loading branch information
andrey-medvedev-vk committed Oct 11, 2024
1 parent 923d880 commit efeeba8
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 6 deletions.
1 change: 1 addition & 0 deletions packages/vkui/src/components/AppRoot/AppRootPortal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface AppRootPortalProps extends HasChildren {
/**
* - При передаче `true` будет использовать `portalRoot` из контекста `AppRoot`.
* - При передаче элемента будут игнорироваться `portalRoot` и `disablePortal` из контекста `AppRoot`.
* - При передаче `in-app-after-content` будет использоваться контейнер внутри `SplitLayout`, сразу после контента приложения.
*/
usePortal?: boolean | HTMLElement | React.RefObject<HTMLElement> | null | 'in-app-after-content';
className?: string;
Expand Down
23 changes: 23 additions & 0 deletions packages/vkui/src/components/AppRoot/ModalPopoutPortal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use client';

import * as React from 'react';
import { AppRootContext } from './AppRootContext';
import { AppRootPortal, type AppRootPortalProps } from './AppRootPortal';

/* Специальный компонент для рендеринга ModalRoot и
* popout компонентов внутри SplitLayout после контента
* Как было раньше в v6 при передаче модалок и popout компонентов
* в свойства SplitLayout modal/popout в режиме full */
export function ModalPopoutPortal(props: AppRootPortalProps) {
const { mode } = React.useContext(AppRootContext);
const usePortalProp = props.usePortal;

let usePortal: AppRootPortalProps['usePortal'] = usePortalProp;

const shouldRenderInAppAfterContent = usePortalProp === undefined && mode === 'full';
if (shouldRenderInAppAfterContent) {
usePortal = 'in-app-after-content';
}

return <AppRootPortal {...props} usePortal={usePortal} />;
}
6 changes: 3 additions & 3 deletions packages/vkui/src/components/ModalRoot/ModalRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { type DOMProps, withDOM } from '../../lib/dom';
import { getNavId } from '../../lib/getNavId';
import { rubber } from '../../lib/touch';
import { warnOnce } from '../../lib/warnOnce';
import { AppRootPortal } from '../AppRoot/AppRootPortal';
import { ModalPopoutPortal } from '../AppRoot/ModalPopoutPortal';
import { ConfigProviderContext } from '../ConfigProvider/ConfigProviderContext';
import { FocusTrap } from '../FocusTrap/FocusTrap';
import { type CustomTouchEvent, Touch } from '../Touch/Touch';
Expand Down Expand Up @@ -545,7 +545,7 @@ class ModalRootTouchComponent extends React.Component<
}

return (
<AppRootPortal className={styles.host} usePortal="in-app-after-content">
<ModalPopoutPortal className={styles.host}>
<TouchRootContext.Provider value={true}>
<ModalRootContext.Provider value={this.modalRootContext}>
<Touch
Expand Down Expand Up @@ -605,7 +605,7 @@ class ModalRootTouchComponent extends React.Component<
</Touch>
</ModalRootContext.Provider>
</TouchRootContext.Provider>
</AppRootPortal>
</ModalPopoutPortal>
);
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/vkui/src/components/ScreenSpinner/ScreenSpinner.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import * as React from 'react';
import { AppRootPortal } from '../AppRoot/AppRootPortal';
import { ModalPopoutPortal } from '../AppRoot/ModalPopoutPortal';
import { useScrollLock } from '../AppRoot/ScrollContext';
import { PopoutWrapper } from '../PopoutWrapper/PopoutWrapper';
import { ScreenSpinnerContainer } from './ScreenSpinnerContainer';
Expand Down Expand Up @@ -32,14 +32,14 @@ export const ScreenSpinner: React.FC<ScreenSpinnerProps> & {
useScrollLock();

return (
<AppRootPortal>
<ModalPopoutPortal>
<PopoutWrapper className={className} style={style} noBackground>
<ScreenSpinnerContainer state={state} mode={mode} caption={caption} customIcon={customIcon}>
<ScreenSpinnerLoader {...restProps} />
<ScreenSpinnerSwapIcon onClick={onClick} cancelLabel={cancelLabel} />
</ScreenSpinnerContainer>
</PopoutWrapper>
</AppRootPortal>
</ModalPopoutPortal>
);
};

Expand Down

0 comments on commit efeeba8

Please sign in to comment.