Skip to content

Commit

Permalink
fix: menu rendering in edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Sky-FE committed Nov 26, 2024
1 parent 7264c78 commit df79996
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 173 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ export const Calendar = (props: ICalendarProps) => {
</DialogContent>
</Dialog>
)}
<EventMenu containerRef={containerRef} />
<EventMenu />
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import {
CommandItem,
CommandList,
CommandSeparator,
Popover,
PopoverContent,
PopoverTrigger,
} from '@teable/ui-lib/shadcn';
import { useTranslation } from 'next-i18next';
import { Fragment, useMemo, useRef } from 'react';
import { Fragment, useRef } from 'react';
import { useClickAway } from 'react-use';
import { tableConfig } from '@/features/i18n/table.config';
import { useEventMenuStore } from '../hooks';
Expand All @@ -30,39 +33,31 @@ enum MenuItemType {
}

const iconClassName = 'mr-2 h-4 w-4 shrink-0';
const MENU_WIDTH = 220;

export const EventMenu = ({ containerRef }: { containerRef: React.RefObject<HTMLDivElement> }) => {
export const EventMenu = () => {
const { eventMenu, closeEventMenu } = useEventMenuStore();
const { t } = useTranslation(tableConfig.i18nNamespaces);
const tableId = useTableId();
const view = useView();
const viewId = view?.id;
const recordMenuRef = useRef<HTMLDivElement>(null);

const { eventId, position } = eventMenu ?? {};
const { eventId } = eventMenu ?? {};

useClickAway(recordMenuRef, () => {
closeEventMenu();
});

const style = useMemo(() => {
if (!position) return {};

const { x, y } = position;

if (!containerRef.current) return { left: x, top: y };

const containerRect = containerRef.current.getBoundingClientRect();
const relativeX = Math.min(x, containerRect.width - MENU_WIDTH);
const relativeY = Math.min(y, containerRect.height - 90);

return { left: relativeX, top: relativeY };
}, [containerRef, position]);

if (eventMenu == null || !eventId) return null;

const { permission } = eventMenu;
const { permission, position } = eventMenu;
const visible = Boolean(eventMenu);
const style = position
? {
left: position.x,
top: position.y,
}
: {};

const menuItemGroups: IMenuItemProps<MenuItemType>[][] = [
[
Expand Down Expand Up @@ -101,44 +96,44 @@ export const EventMenu = ({ containerRef }: { containerRef: React.RefObject<HTML
}

return (
<Command
ref={recordMenuRef}
className="absolute z-10 h-auto rounded-sm border shadow-sm"
style={{
...style,
width: MENU_WIDTH,
}}
>
<CommandList>
{menuItemGroups.map((items, index) => {
const nextItems = menuItemGroups[index + 1] ?? [];
if (!items.length) return null;

return (
<Fragment key={index}>
<CommandGroup aria-valuetext="name">
{items.map(({ type, name, icon, className, onClick }) => {
return (
<CommandItem
className={cn('px-4 py-2', className)}
key={type}
value={name}
onSelect={async () => {
onClick();
closeEventMenu();
}}
>
{icon}
{name}
</CommandItem>
);
})}
</CommandGroup>
{nextItems.length > 0 && <CommandSeparator />}
</Fragment>
);
})}
</CommandList>
</Command>
<Popover open={visible}>
<PopoverTrigger asChild style={style} className="absolute">
<div className="size-0 opacity-0" />
</PopoverTrigger>
<PopoverContent className="h-auto w-56 rounded-md p-0" align="start">
<Command ref={recordMenuRef} className="rounded-md border-none shadow-none" style={style}>
<CommandList>
{menuItemGroups.map((items, index) => {
const nextItems = menuItemGroups[index + 1] ?? [];
if (!items.length) return null;

return (
<Fragment key={index}>
<CommandGroup aria-valuetext="name">
{items.map(({ type, name, icon, className, onClick }) => {
return (
<CommandItem
className={cn('px-4 py-2', className)}
key={type}
value={name}
onSelect={async () => {
onClick();
closeEventMenu();
}}
>
{icon}
{name}
</CommandItem>
);
})}
</CommandGroup>
{nextItems.length > 0 && <CommandSeparator />}
</Fragment>
);
})}
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import {
CommandItem,
CommandList,
CommandSeparator,
Popover,
PopoverContent,
PopoverTrigger,
Sheet,
SheetContent,
SheetHeader,
Expand Down Expand Up @@ -356,49 +359,54 @@ export const FieldMenu = () => {
</SheetContent>
</Sheet>
) : (
<Command
ref={fieldSettingRef}
className={cn('absolute rounded-lg shadow-sm w-60 h-auto border', {
hidden: !visible,
})}
style={style}
>
<CommandList className="max-h-96">
{menuGroups.map((items, index) => {
const nextItems = menuGroups[index + 1] ?? [];
if (!items.length) return null;
<Popover open={visible}>
<PopoverTrigger asChild style={style} className="absolute">
<div className="size-0 opacity-0" />
</PopoverTrigger>
<PopoverContent className="h-auto w-60 rounded-md p-0" align="start">
<Command
ref={fieldSettingRef}
className="rounded-md border-none shadow-none"
style={style}
>
<CommandList className="max-h-96">
{menuGroups.map((items, index) => {
const nextItems = menuGroups[index + 1] ?? [];
if (!items.length) return null;

return (
<Fragment key={index}>
<CommandGroup aria-valuetext="name">
{items.map(({ type, name, icon, disabled, className, onClick }) => (
<CommandItem
className={cn('px-4 py-2', className, {
'cursor-not-allowed': disabled,
'opacity-50': disabled,
})}
key={type}
value={name}
onSelect={async () => {
if (disabled) {
return;
}
await onClick();
onSelectionClear?.();
closeHeaderMenu();
}}
>
{icon}
{name}
</CommandItem>
))}
</CommandGroup>
{nextItems.length > 0 && <CommandSeparator />}
</Fragment>
);
})}
</CommandList>
</Command>
return (
<Fragment key={index}>
<CommandGroup aria-valuetext="name">
{items.map(({ type, name, icon, disabled, className, onClick }) => (
<CommandItem
className={cn('px-4 py-2', className, {
'cursor-not-allowed': disabled,
'opacity-50': disabled,
})}
key={type}
value={name}
onSelect={async () => {
if (disabled) {
return;
}
await onClick();
onSelectionClear?.();
closeHeaderMenu();
}}
>
{icon}
{name}
</CommandItem>
))}
</CommandGroup>
{nextItems.length > 0 && <CommandSeparator />}
</Fragment>
);
})}
</CommandList>
</Command>
</PopoverContent>
</Popover>
)}
</>
);
Expand Down
Loading

0 comments on commit df79996

Please sign in to comment.