mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-31 10:22:36 +01:00
collapsable context menu
This commit is contained in:
parent
1266b79989
commit
c4fc67ac19
@ -87,7 +87,7 @@ export const AvatarInfoUseProductView: FC<AvatarInfoUseProductViewProps> = props
|
||||
}, [ item, updateConfirmingProduct ]);
|
||||
|
||||
return (
|
||||
<ContextMenuView objectId={ item.id } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.PET } close={ close }>
|
||||
<ContextMenuView objectId={ item.id } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.PET } close={ close } collapsable={ true }>
|
||||
<ContextMenuHeaderView>
|
||||
{ item.name }
|
||||
</ContextMenuHeaderView>
|
||||
|
@ -213,7 +213,7 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
||||
}, [ userData ]);
|
||||
|
||||
return (
|
||||
<ContextMenuView objectId={ userData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ userData.userType } close={ close }>
|
||||
<ContextMenuView objectId={ userData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ userData.userType } close={ close } collapsable={ true }>
|
||||
<ContextMenuHeaderView className="cursor-pointer" onClick={ event => GetUserProfile(userData.webID) }>
|
||||
{ userData.name }
|
||||
</ContextMenuHeaderView>
|
||||
|
@ -121,7 +121,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
||||
const isRidingHorse = IsRidingHorse();
|
||||
|
||||
return (
|
||||
<ContextMenuView objectId={ userData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ userData.userType } close={ close }>
|
||||
<ContextMenuView objectId={ userData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ userData.userType } close={ close } collapsable={ true }>
|
||||
|
||||
<ContextMenuHeaderView className="cursor-pointer" onClick={ event => GetUserProfile(userData.webID) }>
|
||||
{ userData.name }
|
||||
</ContextMenuHeaderView>
|
||||
|
@ -142,7 +142,7 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
|
||||
}, [ petData ]);
|
||||
|
||||
return (
|
||||
<ContextMenuView objectId={ petData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.PET } close={ close }>
|
||||
<ContextMenuView objectId={ petData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.PET } close={ close } collapsable={ true }>
|
||||
<ContextMenuHeaderView>
|
||||
{ petData.name }
|
||||
</ContextMenuHeaderView>
|
||||
|
@ -109,7 +109,7 @@ export const AvatarInfoWidgetPetView: FC<AvatarInfoWidgetPetViewProps> = props =
|
||||
}, [ petData ]);
|
||||
|
||||
return (
|
||||
<ContextMenuView objectId={ petData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.PET } close={ close }>
|
||||
<ContextMenuView objectId={ petData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.PET } close={ close } collapsable={ true }>
|
||||
<ContextMenuHeaderView>
|
||||
{ petData.name }
|
||||
</ContextMenuHeaderView>
|
||||
|
@ -136,7 +136,7 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
|
||||
const canControl = (rentableBotData.amIOwner || rentableBotData.amIAnyRoomController);
|
||||
|
||||
return (
|
||||
<ContextMenuView objectId={ rentableBotData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.RENTABLE_BOT } close={ close }>
|
||||
<ContextMenuView objectId={ rentableBotData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.RENTABLE_BOT } close={ close } collapsable={ true }>
|
||||
<ContextMenuHeaderView>
|
||||
{ rentableBotData.name }
|
||||
</ContextMenuHeaderView>
|
||||
|
@ -20,9 +20,11 @@
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
&:not(.name-only) {
|
||||
&:not(.name-only):not(.menu-hidden) {
|
||||
min-width: 125px;
|
||||
}
|
||||
|
||||
&:not(.name-only) {
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@ -49,6 +51,22 @@
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
&.menu-hidden {
|
||||
.menu-footer {
|
||||
padding-top:2px;
|
||||
padding-bottom:0;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-footer {
|
||||
color: $white;
|
||||
font-size: 16px;
|
||||
width:100%;
|
||||
min-width: 25px;
|
||||
padding-bottom:2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu-list-split-3 {
|
||||
|
||||
.menu-item {
|
||||
|
@ -0,0 +1,25 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { FC, useMemo } from 'react';
|
||||
import { Flex, FlexProps } from '../../../../common';
|
||||
|
||||
interface CaretViewProps extends FlexProps
|
||||
{
|
||||
collapsed?: boolean;
|
||||
}
|
||||
export const ContextMenuCaretView: FC<CaretViewProps> = props =>
|
||||
{
|
||||
const { justifyContent = 'center', alignItems = 'center', classNames = [], collapsed = true, ...rest } = props;
|
||||
|
||||
const getClassNames = useMemo(() =>
|
||||
{
|
||||
const newClassNames: string[] = [ 'menu-footer' ];
|
||||
|
||||
if(classNames.length) newClassNames.push(...classNames);
|
||||
|
||||
return newClassNames;
|
||||
}, [ classNames ]);
|
||||
|
||||
return <Flex justifyContent={ justifyContent } alignItems={ alignItems } classNames={ getClassNames } { ...rest }>
|
||||
<FontAwesomeIcon icon={ !collapsed ? 'caret-down' : 'caret-up' } className="align-self-center" />
|
||||
</Flex>
|
||||
}
|
@ -2,6 +2,7 @@ import { FixedSizeStack, NitroPoint, NitroRectangle, RoomObjectType } from '@nit
|
||||
import { CSSProperties, FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { GetNitroInstance, GetRoomObjectBounds, GetRoomObjectScreenLocation, GetRoomSession, GetTicker } from '../../../../api';
|
||||
import { Base, BaseProps } from '../../../../common';
|
||||
import { ContextMenuCaretView } from './ContextMenuCaretView';
|
||||
|
||||
interface ContextMenuViewProps extends BaseProps<HTMLDivElement>
|
||||
{
|
||||
@ -10,6 +11,7 @@ interface ContextMenuViewProps extends BaseProps<HTMLDivElement>
|
||||
userType?: number;
|
||||
fades?: boolean;
|
||||
close: () => void;
|
||||
collapsable?: boolean;
|
||||
}
|
||||
|
||||
const LOCATION_STACK_SIZE: number = 25;
|
||||
@ -18,9 +20,11 @@ const fadeDelay = 3000;
|
||||
const fadeLength = 75;
|
||||
const SPACE_AROUND_EDGES = 10;
|
||||
|
||||
let COLLAPSED = false;
|
||||
|
||||
export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||
{
|
||||
const { objectId = -1, category = -1, userType = -1, fades = false, close = null, position = 'absolute', classNames = [], style = {}, ...rest } = props;
|
||||
const { objectId = -1, category = -1, userType = -1, fades = false, close = null, position = 'absolute', classNames = [], style = {}, children = null, collapsable = false, ...rest } = props;
|
||||
const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: null, y: null });
|
||||
const [ deltaYStack, setDeltaYStack ] = useState<FixedSizeStack>(null);
|
||||
const [ currentDeltaY, setCurrentDeltaY ] = useState(-1000000);
|
||||
@ -30,6 +34,8 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||
const [ isFrozen, setIsFrozen ] = useState(false);
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
const [ collapsed, setCollapsed ] = useState(COLLAPSED);
|
||||
|
||||
const getOffset = useCallback((bounds: NitroRectangle) =>
|
||||
{
|
||||
let height = -(elementRef.current.offsetHeight);
|
||||
@ -119,12 +125,14 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||
{
|
||||
const newClassNames: string[] = [ 'nitro-context-menu' ];
|
||||
|
||||
if (collapsed) newClassNames.push('menu-hidden');
|
||||
|
||||
newClassNames.push((pos.x !== null) ? 'visible' : 'invisible');
|
||||
|
||||
if(classNames.length) newClassNames.push(...classNames);
|
||||
|
||||
return newClassNames;
|
||||
}, [ pos, classNames ]);
|
||||
}, [ pos, classNames, collapsed ]);
|
||||
|
||||
const getStyle = useMemo(() =>
|
||||
{
|
||||
@ -171,5 +179,14 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||
return () => clearTimeout(timeout);
|
||||
}, [ fades ]);
|
||||
|
||||
return <Base innerRef={ elementRef } position={ position } classNames={ getClassNames } style={ getStyle } onMouseOver={ event => setIsFrozen(true) } onMouseOut={ event => setIsFrozen(false) } { ...rest } />;
|
||||
|
||||
const toggleCollapse = () =>
|
||||
{
|
||||
COLLAPSED = !COLLAPSED;
|
||||
setCollapsed(COLLAPSED)
|
||||
}
|
||||
return <Base innerRef={ elementRef } position={ position } classNames={ getClassNames } style={ getStyle } onMouseOver={ event => setIsFrozen(true) } onMouseOut={ event => setIsFrozen(false) } { ...rest }>
|
||||
{ !(collapsable && COLLAPSED) && children }
|
||||
{ collapsable && <ContextMenuCaretView onClick={ () => toggleCollapse() } collapsed={ collapsed } /> }
|
||||
</Base>;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user