I am using Popper component of Material UI to render data inside popup when clicked on Item.
The issue I am facing is when certain item is clicked the Popper opens at the start of viewPort and then it corrects it's position to the anchor element.
The two possible reasons that might be true here is of Opening of Popper at the start of viewPort and then shifting to correct position with respect to anchor element is that initially it do has anchorElement as null or due to dynamic contnet rendring.
Here is my component code where I am using Popper :
const RightPanel = (props: any) => {
const { dispatch, state } = useContext(stateContext);
const { dprState, dprDispatch } = useContext(DPRContext);
// const [anchorEl, setAnchorEl]: any = useState(null);
const [anchorEl, setAnchorEl] = useState<PopperProps['anchorEl']>(document.getElementById(`icon-${0}`));
const [openIndex, setOpenIndex] = useState(-1);
const [sideMenuOptions, setSideMenuOptions] = useState<MenuOption[]>([]);
const [isMarkerEnabled, setIsMarkerEnabled] = useState(false);
const [isDataLoaded,setIsDataLoaded] = useState<boolean>(false)
const [markerMode, setMarkerMode] = useState<MarkerMode>();
const {
viewType,
setViewType,
showReport,
setShowReport,
setShowDprMedia,
showDprMedia,
showActivities,
setShowActivities,
modelIds,
marker,
viewer,
setManageScreen,
manageScreen,
setShowDrawingMenu,
} = props;
const classes = menuStyle();
const { dprAdmin, dprEditor, dprViewer } = useDprPermission();
const { track } = useAnalytics();
const projectId = useProjectId();
console.log("anchorEl",anchorEl)
useEffect(() => {
const menuOptions: MenuOption[] = [
{
img: info,
imgActive: infoActive,
imgDisabled:infoDisabled,
isMenu: true,
tooltipsText: 'Activity information',
show: true,
isDisabled:false,
id:"info",
isOpen:false
},
{
img: threeD,
imgActive: threeDActive,
imgDisabled:threeDDisabled,
isMenu: false,
tooltipsText: '3D view',
show: true,
isDisabled:false,
id:"3d",
},
{
img: twoD,
imgActive: twoDActive,
imgDisabled:twoDDisabled,
isMenu: false,
tooltipsText: '2D view',
show: true,
isDisabled:false,
id:"2d"
},
{
img: filter,
imgActive: filterActive,
imgDisabled:filterDisabled,
isMenu: true,
tooltipsText: 'Filters',
show: true,
isDisabled:false,
id:"filter",
isOpen:false
},
{
img: linkWhite,
imgActive: linkCyan,
isMenu: false,
tooltipsText: 'Marker setup mode',
show: dprAdmin || dprEditor,
isDisabled:false,
id:"link"
},
{
img: progressWhite,
imgActive: progressCyan,
isMenu: false,
tooltipsText: 'Marker progress mode',
show: dprAdmin || dprEditor,
isDisabled:false,
id:"progress"
},
{
img: analytics,
imgActive: analyticsActive,
isMenu: false,
tooltipsText: 'Progress view',
show: true,
isDisabled:false,
id:"analytics"
},
{
img: list,
imgActive: listActive,
isMenu: false,
tooltipsText: 'Progress List view',
show: true,
isDisabled:false,
id:"list"
},
{
img: photos,
imgActive: photosActive,
isMenu: false,
tooltipsText: 'Progress Media',
show: true,
isDisabled:false,
id:"photos"
},
{
img: files,
imgActive: filesActive,
isMenu: true,
tooltipsText: 'Manage',
show: true,
isDisabled:false,
id:"files"
},
];
setSideMenuOptions(menuOptions);
}, [state.selectedProjectToken]);
useEffect(
() => setupMarkerWithViewer(),
[marker?.mode, marker?.isEnabled, showReport]
);
useEffect(() => {
marker?.disable();
marker?.changeMode('setup');
setupMarkerWithViewer()
dprDispatch(setUpdateMarker(dprState.updateMarker + 1));
}, [state.selectedDprTaskDetails]);
useEffect(() => {
updateMarkerChanges();
}, [dprState.updateMarker]);
const setupMarkerWithViewer = () => {
if (!marker) return;
if (showReport) {
viewer?.deleteFilters(['selectedTaskElements']);
return;
}
viewer?.deleteFilters(['selectedTaskElements', 'completedFilter']);
if (marker?.isEnabled) {
if (
!state.selectedDprTaskDetails ||
!state.selectedDprTaskDetails?.projectTaskElementAssociations.length
) {
marker?.updateSelectableIds(null, {}, {});
marker.changeMode('setup');
} else {
if (
state.selectedDprTaskDetails.status !== 'To-Do' &&
marker.mode === 'setup'
) {
marker?.changeMode('progress');
addSelectedFilter(true);
marker?.enable();
dprDispatch(setUpdateMarker(dprState.updateMarker + 1));
return;
}
if (marker.mode === 'progress') {
addSelectedFilter(true);
marker?.enable();
} else {
const {selectableIndex, allIds} = getCompletedSelectedIds(state.selectedDprTaskDetails);
marker?.updateSelectableIds(null, {}, {});
marker?.enable(allIds, selectableIndex);
}
}
} else {
addSelectedFilter(false);
}
dprDispatch(setUpdateMarker(dprState.updateMarker + 1));
};
const addSelectedFilter = (updateMarker: boolean) => {
if(!state.selectedDprTaskDetails) return;
const {selectableIds, completedIds, selectableIndex, completedIndex, allIds} = getCompletedSelectedIds(state.selectedDprTaskDetails);
if (props.marker.isEnabled) {
props.viewer?.addOrUpdateFilter([getSelectedFilter(selectableIds, selectableIndex, completedIndex), getCompletedFilter(completedIds, selectableIndex, completedIndex, {}, {})]);
} else {
props.viewer?.addOrUpdateFilter([getSelectedFilter(allIds, selectableIndex, {})]);
}
updateMarker
? props.marker?.updateSelectableIds(selectableIds || [], selectableIndex, completedIndex)
: props.marker?.updateSelectableIds(null);
};
const handleMenu = (index: any, isMenu: any) => (event: any) => {
if (isMenu) {
const anchorEle = document.getElementById(`icon-${index}`)
setAnchorEl(anchorEle)
}
if (index === 1) {
setViewType('3D');
} else if (index === 2) {
setViewType('2D');
} else if (index === 4) {
if (
state.selectedDprTaskDetails &&
state.selectedDprTaskDetails.status === 'To-Do'
) {
(!marker.isEnabled || markerMode === 'progress') &&
!showReport &&
!showActivities &&
!showDprMedia
? marker?.enable()
: marker?.disable();
marker.changeMode('setup');
dprDispatch(setUpdateMarker(dprState.updateMarker + 1));
}
} else if (index === 5) {
if (
state.selectedDprTaskDetails &&
state.selectedDprTaskDetails?.projectTaskElementAssociations.length
) {
(!marker.isEnabled || markerMode === 'setup') &&
!showReport &&
!showActivities &&
!showDprMedia
? marker?.enable()
: marker?.disable();
marker.changeMode('progress');
dprDispatch(setUpdateMarker(dprState.updateMarker + 1));
}
} else if (index === 6) {
track(TrackingEvents["progress-view"])
setShowReport(!showReport);
const updatedMenuOptions = sideMenuOptions.map((menuOption) => {
if (["3d", "2d", "photos", "files", "list", "analytics", "filter"].includes(menuOption.id)) {
// These options should always be enabled
menuOption.isDisabled = false;
} else {
// For other options, update based on the showReport condition
menuOption.isDisabled = !showReport;
}
return menuOption;
});
setSideMenuOptions(updatedMenuOptions)
marker?.disable();
updateMarkerChanges();
setShowActivities(false);
setShowDprMedia(false);
} else if (index === 7) {
track(TrackingEvents["dpr-list-view"])
const updatedMenuOptions = sideMenuOptions.map((menuOption)=>{
if(menuOption.id !="photos" && menuOption.id !="files" && menuOption.id !="list" && menuOption.id !="analytics"){
menuOption.isDisabled = showActivities? false: true
}
return menuOption
})
setSideMenuOptions(updatedMenuOptions)
marker?.disable();
setShowReport(false);
setShowDprMedia(false);
setShowActivities(!showActivities);
} else if (index === 8) {
track(TrackingEvents["dpr-media-asset"])
const updatedMenuOptions = sideMenuOptions.map((menuOption,index)=>{
if(menuOption.id !="photos" && menuOption.id !="files" && menuOption.id !="list" && menuOption.id !="analytics"){
menuOption.isDisabled = showDprMedia? false: true
}
return menuOption
})
setSideMenuOptions(updatedMenuOptions)
marker?.disable();
setShowReport(false);
setShowActivities(false);
setShowDprMedia(!showDprMedia);
} else if (index === 9) {
track(TrackingEvents["manage"])
setManageScreen(!manageScreen);
dprDispatch(setCategoryFilters([]));
dprDispatch(setOtherFiltersList([]));
dprDispatch(setLevelList([]));
} else {
setOpenIndex(openIndex === index ? -1 : index); // set current menu index to open
}
};
useEffect(()=>{
if(openIndex==3){
track(TrackingEvents["filtering-geometry"],{projectId})
}
},[openIndex])
const handleMenuClose = (e:any) => {
// console.log("closing-menu",openIndex, e?.target,e)
setAnchorEl(null);
setOpenIndex(-1);
};
const updateMarkerChanges = () => {
setMarkerMode(marker?.mode);
setIsMarkerEnabled(marker?.isEnabled);
setShowDrawingMenu(marker?.isEnabled);
};
return (
<div className="rightPanelMain">
{sideMenuOptions?.map((option: any, index: number) => {
if (index === 1 && viewType === '3D') return <></>;
if (index === 2 && viewType === '2D') return <></>;
if (option.show) {
return (
<div key={index}>
<div
id={`icon-${index}`}
className="rightPanelMain__icon"
onClick={ option.isDisabled?()=>{return undefined}: handleMenu(index, option?.isMenu)}
>
<Tooltip title={`${option?.tooltipsText}`} placement="left">
<img
src={
(index === 1 && viewType === '3D') ||
(index === 2 && viewType === '2D') ||
(index === 4 &&
marker?.isEnabled &&
markerMode === 'setup') ||
(index === 5 &&
marker?.isEnabled &&
markerMode === 'progress') ||
(index === 6 && showReport) ||
(index === 7 && showActivities) ||
(index === 8 && showDprMedia) ||
openIndex === index
? option.imgActive
: option.img
}
className={
(index === 4 &&
(!state.selectedDprTaskDetails ||
state.selectedDprTaskDetails.status !== 'To-Do')) ||
(index === 5 &&
(!state.selectedDprTaskDetails ||
!state.selectedDprTaskDetails
?.projectTaskElementAssociations.length)) ||
((index === 4 || index === 5) && (showActivities ||
showDprMedia ||
showReport)) || option.isDisabled
? 'rightPanelMain__icon__disabled'
: ''
}
/>
</Tooltip>
</div>
{index !== sideMenuOptions?.length - 1 && (
<div className="rightPanelMain__divider"></div>
)}
{(openIndex !== -1 && anchorEl !=null) ? (
<Popper
id={`custom-popper-${index}`}
anchorEl={anchorEl}
open={Boolean(anchorEl) && (index === openIndex)}
placement={'left-start'}
sx={{zIndex:3}}
className={classes.paper}
keepMounted
>
<div className="floating-menu--container">
{openIndex === 0 ? (
<InfoTab marker={marker} modelIds={modelIds}/>
) : openIndex === 3 ? (
<Filters
modelIds={modelIds}
viewer={viewer}
marker={marker}
setIsDataLoaded={setIsDataLoaded}
/>
) : null}
</div>
</Popper>
) : null}
</div>
);
}
})}
</div>
);
};
Inside Popper I have two components InfoTab , Filters, that is getting rendered inside Popper and these two components data I am getting from Api.
The issue I am facing is when certain item is clicked the Popper opens at the start of viewPort and then it corrects it's position to the anchor element.
The two possible reasons that might be true here is of Opening of Popper at the start of viewPort and then shifting to correct position with respect to anchor element is that initially it do has anchorElement as null or due to dynamic contnet rendring.