fix(core): multi sub menu layer handling (#8916)

fix AF-1800, AF-1801

<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/T2klNLEk0wxLh4NRDzhk/7523df2b-2326-4878-b37a-d16e4275858d.mp4">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/T2klNLEk0wxLh4NRDzhk/7523df2b-2326-4878-b37a-d16e4275858d.mp4">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/7523df2b-2326-4878-b37a-d16e4275858d.mp4">20241126-0806-30.0904958.mp4</video>
This commit is contained in:
pengx17
2024-11-26 08:39:09 +00:00
parent e12d5f8750
commit d87a6f7068
6 changed files with 147 additions and 28 deletions
@@ -9,8 +9,11 @@ import { Button } from '../../button';
import { Modal } from '../../modal';
import { Scrollable } from '../../scrollbar';
import type { MenuProps } from '../menu.types';
import type { SubMenuContent } from './context';
import { MobileMenuContext } from './context';
import {
MobileMenuContext,
type SubMenuContent,
useMobileSubMenuHelper,
} from './context';
import * as styles from './styles.css';
import { MobileMenuSubRaw } from './sub';
@@ -32,12 +35,23 @@ export const MobileMenu = ({
}: MenuProps) => {
const [subMenus, setSubMenus] = useState<SubMenuContent[]>([]);
const [open, setOpen] = useState(false);
const mobileContextValue = {
subMenus,
setSubMenus,
setOpen,
};
const { removeSubMenu, removeAllSubMenus } =
useMobileSubMenuHelper(mobileContextValue);
const [sliderHeight, setSliderHeight] = useState(0);
const [sliderElement, setSliderElement] = useState<HTMLDivElement | null>(
null
);
const { setOpen: pSetOpen } = useContext(MobileMenuContext);
const finalOpen = rootOptions?.open ?? open;
// always show the last submenu, if any
const activeIndex = subMenus.length;
// dynamic height for slider
@@ -62,12 +76,12 @@ export const MobileMenu = ({
// a workaround to hack the onPointerDownOutside event
onPointerDownOutside?.({} as any);
onInteractOutside?.({} as any);
setSubMenus([]);
removeAllSubMenus();
}
setOpen(open);
rootOptions?.onOpenChange?.(open);
},
[onInteractOutside, onPointerDownOutside, rootOptions]
[onInteractOutside, onPointerDownOutside, removeAllSubMenus, rootOptions]
);
const onItemClick = useCallback(
@@ -93,7 +107,11 @@ export const MobileMenu = ({
* ```
*/
if (pSetOpen) {
return <MobileMenuSubRaw items={items}>{children}</MobileMenuSubRaw>;
return (
<MobileMenuSubRaw items={items} subOptions={rootOptions}>
{children}
</MobileMenuSubRaw>
);
}
return (
@@ -126,7 +144,7 @@ export const MobileMenu = ({
</div>
{subMenus.map((sub, index) => (
<div
key={index}
key={sub.id}
data-index={index + 1}
className={styles.menuContent}
>
@@ -135,7 +153,9 @@ export const MobileMenu = ({
variant="plain"
className={styles.backButton}
prefix={<ArrowLeftSmallIcon />}
onClick={() => setSubMenus(prev => prev.slice(0, index))}
onClick={() => {
removeSubMenu(sub.id);
}}
prefixStyle={{ width: 24, height: 24 }}
>
{sub.title || t['com.affine.backButton']()}