feat(mobile): explorer create/rename operation (#8628)

close AF-1560
This commit is contained in:
CatsJuice
2024-11-04 05:28:05 +00:00
parent 12e3cf1d07
commit 4cbf4b74d6
44 changed files with 1139 additions and 252 deletions

View File

@@ -61,7 +61,7 @@ export const InviteModal = ({
confirmButtonOptions={{
loading: isMutating,
variant: 'primary',
['data-testid' as string]: 'confirm-enable-affine-cloud-button',
'data-testid': 'confirm-enable-affine-cloud-button',
}}
onConfirm={handleConfirm}
>

View File

@@ -70,6 +70,7 @@ export interface ButtonProps
tooltip?: TooltipProps['content'];
tooltipShortcut?: TooltipProps['shortcut'];
tooltipOptions?: Partial<Omit<TooltipProps, 'content' | 'shortcut'>>;
[key: `data-${string}`]: string;
}
const IconSlot = ({

View File

@@ -20,6 +20,7 @@ export type RowInputProps = {
type?: HTMLInputElement['type'];
style?: CSSProperties;
onEnter?: () => void;
[key: `data-${string}`]: string;
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'size' | 'onBlur'>;
// RowInput component that is used in the selector layout for search input

View File

@@ -20,9 +20,9 @@ export const DesktopMenuSub = ({
} = {},
}: MenuSubProps) => {
const { className, children, otherProps } = useMenuItem({
...triggerOptions,
children: propsChildren,
suffixIcon: <ArrowRightSmallIcon />,
...triggerOptions,
});
return (

View File

@@ -30,3 +30,4 @@ export {
};
export { Menu, MenuItem, MenuSeparator, MenuSub, MenuTrigger };
export * from './mobile/hook';

View File

@@ -36,7 +36,9 @@ export interface MenuItemProps
export interface MenuSubProps {
children: ReactNode;
items: ReactNode;
triggerOptions?: Omit<MenuItemProps, 'onSelect' | 'children' | 'suffixIcon'>;
triggerOptions?: Omit<MenuItemProps, 'onSelect' | 'children'> & {
[key: `data-${string}`]: string;
};
portalOptions?: Omit<DropdownMenuPortalProps, 'children'>;
subOptions?: Omit<DropdownMenuSubProps, 'children'>;
subContentOptions?: Omit<DropdownMenuSubContentProps, 'children'>;

View File

@@ -8,6 +8,11 @@ import {
import type { MenuSubProps } from '../menu.types';
export type SubMenuContent = {
/**
* Customize submenu's title
* @default "Back"
*/
title?: string;
items: ReactNode;
contentOptions?: MenuSubProps['subContentOptions'];
};

View File

@@ -0,0 +1,18 @@
import { useCallback, useContext } from 'react';
import { MobileMenuContext } from './context';
export const useMobileMenuController = () => {
const context = useContext(MobileMenuContext);
/**
* **A workaround to close mobile menu manually**
* By default, it will close automatically when `MenuItem` clicked.
* For custom menu content, you can use this method to close the menu.
*/
const close = useCallback(() => {
context.setOpen?.(false);
}, [context]);
return { close };
};

View File

@@ -134,9 +134,9 @@ export const MobileMenu = ({
className={styles.backButton}
prefix={<ArrowLeftSmallIcon />}
onClick={() => setSubMenus(prev => prev.slice(0, index))}
prefixStyle={{ width: 20, height: 20 }}
prefixStyle={{ width: 24, height: 24 }}
>
{t['com.affine.backButton']()}
{sub.title || t['com.affine.backButton']()}
</Button>
{sub.items}

View File

@@ -7,19 +7,20 @@ import { useMenuItem } from '../use-menu-item';
import { MobileMenuContext } from './context';
export const MobileMenuSub = ({
title,
children: propsChildren,
items,
triggerOptions,
subContentOptions: contentOptions = {},
}: MenuSubProps) => {
}: MenuSubProps & { title?: string }) => {
const {
className,
children,
otherProps: { onClick, ...otherTriggerOptions },
} = useMenuItem({
...triggerOptions,
children: propsChildren,
suffixIcon: <ArrowRightSmallPlusIcon />,
...triggerOptions,
});
return (
@@ -27,6 +28,7 @@ export const MobileMenuSub = ({
onClick={onClick}
items={items}
subContentOptions={contentOptions}
title={title}
>
<div className={className} {...otherTriggerOptions}>
{children}
@@ -36,19 +38,23 @@ export const MobileMenuSub = ({
};
export const MobileMenuSubRaw = ({
title,
onClick,
children,
items,
subContentOptions: contentOptions = {},
}: MenuSubProps & { onClick?: (e: MouseEvent<HTMLDivElement>) => void }) => {
}: MenuSubProps & {
onClick?: (e: MouseEvent<HTMLDivElement>) => void;
title?: string;
}) => {
const { setSubMenus } = useContext(MobileMenuContext);
const onItemClick = useCallback(
(e: MouseEvent<HTMLDivElement>) => {
onClick?.(e);
setSubMenus(prev => [...prev, { items, contentOptions }]);
setSubMenus(prev => [...prev, { items, contentOptions, title }]);
},
[contentOptions, items, onClick, setSubMenus]
[contentOptions, items, onClick, setSubMenus, title]
);
return <Slot onClick={onItemClick}>{children}</Slot>;