mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 04:48:53 +00:00
@@ -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}
|
||||
>
|
||||
|
||||
@@ -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 = ({
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,9 +20,9 @@ export const DesktopMenuSub = ({
|
||||
} = {},
|
||||
}: MenuSubProps) => {
|
||||
const { className, children, otherProps } = useMenuItem({
|
||||
...triggerOptions,
|
||||
children: propsChildren,
|
||||
suffixIcon: <ArrowRightSmallIcon />,
|
||||
...triggerOptions,
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -30,3 +30,4 @@ export {
|
||||
};
|
||||
|
||||
export { Menu, MenuItem, MenuSeparator, MenuSub, MenuTrigger };
|
||||
export * from './mobile/hook';
|
||||
|
||||
@@ -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'>;
|
||||
|
||||
@@ -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'];
|
||||
};
|
||||
|
||||
18
packages/frontend/component/src/ui/menu/mobile/hook.ts
Normal file
18
packages/frontend/component/src/ui/menu/mobile/hook.ts
Normal 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 };
|
||||
};
|
||||
@@ -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}
|
||||
|
||||
@@ -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>;
|
||||
|
||||
Reference in New Issue
Block a user