mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
feat(mobile): disable swipe back gesture when there is no back in header (#8876)
close AF-1663, AF-1756 - new global `ModalConfigContext` - new logic to judge whether inside modal - render `✕` for PageHeader back if inside modal - only enable `NavigationGesture` when there is `<` in PageHeader
This commit is contained in:
11
packages/frontend/component/src/ui/modal/context.ts
Normal file
11
packages/frontend/component/src/ui/modal/context.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
export interface ModalConfig {
|
||||
/**
|
||||
* add global callback for modal open/close
|
||||
*/
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
}
|
||||
export const ModalConfigContext = createContext<ModalConfig>({});
|
||||
|
||||
export const InsideModalContext = createContext<number>(0);
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './confirm-modal';
|
||||
export * from './context';
|
||||
export * from './modal';
|
||||
export * from './overlay-modal';
|
||||
export * from './prompt-modal';
|
||||
|
||||
@@ -10,12 +10,19 @@ import * as VisuallyHidden from '@radix-ui/react-visually-hidden';
|
||||
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
||||
import clsx from 'clsx';
|
||||
import type { CSSProperties } from 'react';
|
||||
import { forwardRef, useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import { startScopedViewTransition } from '../../utils';
|
||||
import type { IconButtonProps } from '../button';
|
||||
import { IconButton } from '../button';
|
||||
import { SafeArea } from '../safe-area';
|
||||
import { InsideModalContext, ModalConfigContext } from './context';
|
||||
import * as styles from './styles.css';
|
||||
|
||||
export interface ModalProps extends DialogProps {
|
||||
@@ -123,6 +130,7 @@ function createContainer() {
|
||||
|
||||
export const ModalInner = forwardRef<HTMLDivElement, ModalProps>(
|
||||
(props, ref) => {
|
||||
const modalConfig = useContext(ModalConfigContext);
|
||||
const {
|
||||
modal,
|
||||
portalOptions,
|
||||
@@ -164,6 +172,10 @@ export const ModalInner = forwardRef<HTMLDivElement, ModalProps>(
|
||||
null
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
modalConfig.onOpenChange?.(open ?? false);
|
||||
}, [modalConfig, open]);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
const container = createContainer();
|
||||
@@ -304,10 +316,20 @@ export const ModalInner = forwardRef<HTMLDivElement, ModalProps>(
|
||||
ModalInner.displayName = 'ModalInner';
|
||||
|
||||
export const Modal = forwardRef<HTMLDivElement, ModalProps>((props, ref) => {
|
||||
const insideModal = useContext(InsideModalContext);
|
||||
if (!props.open) {
|
||||
return;
|
||||
}
|
||||
return <ModalInner {...props} ref={ref} />;
|
||||
return (
|
||||
<InsideModalContext.Provider value={insideModal + 1}>
|
||||
<ModalInner {...props} ref={ref} />
|
||||
</InsideModalContext.Provider>
|
||||
);
|
||||
});
|
||||
|
||||
Modal.displayName = 'Modal';
|
||||
|
||||
export const useIsInsideModal = () => {
|
||||
const context = useContext(InsideModalContext);
|
||||
return context > 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user