Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

fix: prevent user lock in and visually destructed list boxes on small devices #365

Merged
merged 3 commits into from
Oct 10, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 38 additions & 8 deletions packages/sn-filter-pane/src/components/ListboxPopoverContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,21 @@ const popoverPaperProps = (selectedResource: boolean, isSmallDevice:boolean, sta
}
return {
style: {
height: selectedResource ? calcHeight : undefined,
width: isSmallDevice ? '100%' : '234px',
overflowX: 'hidden',
overflowY: selectedResource ? 'hidden' : 'auto',
backgroundColor,
maxWidth: isSmallDevice ? '100%' : 'calc(100% - 32px)',
maxHeight: isSmallDevice ? '100%' : 'calc(100% - 32px)',
...(isSmallDevice ? {
width: '100%',
height: '100%',
maxWidth: '100%',
maxHeight: '100%',
}
: {
height: selectedResource ? calcHeight : undefined,
width: '234px',
maxWidth: 'calc(100% - 32px)',
maxHeight: 'calc(100% - 32px)',
}),
},
};
};
Expand All @@ -49,6 +57,21 @@ const StyledDiv = styled('div')(() => ({
},
}));

const StyledPopover = styled(Popover, { shouldForwardProp: (p: string) => !['isSmallDevice'].includes(p) })(({ isSmallDevice }: { isSmallDevice: boolean }) => ({
'& .MuiPopover-paper': isSmallDevice ? {
// Override the top, left so the popover won't irrevocably go outside the viewport.
top: '0px !important',
left: '0px !important',
} : {},
}));

function resetZoom() {
const viewportMetaTag = document.querySelector('meta[name="viewport"]');
if (viewportMetaTag instanceof HTMLMetaElement) {
viewportMetaTag.content = 'width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0';
}
}

/**
* If a single resource is passed to this component a FoldedListbox is rendered.
* When the FoldedListbox is clicked, a Listbox is rendered in a Popover.
Expand All @@ -69,6 +92,10 @@ export const ListboxPopoverContainer = ({ resources, stores }: FoldedPopoverProp
const handleOpen = ({ event }: FoldedListboxClickEvent | { event: React.MouseEvent<HTMLButtonElement, MouseEvent> }) => {
if (event.currentTarget.contains(event.target as Node) && !constraints?.active) {
setPopoverOpen(true);
if (isSmallDevice) {
// Autofocus can cause the browser to zoom so we need to reset zoom.
resetZoom();
}
}
};
const handleClose = () => {
Expand Down Expand Up @@ -209,17 +236,20 @@ export const ListboxPopoverContainer = ({ resources, stores }: FoldedPopoverProp
{isSingle && !resources[0].alwaysExpanded
? <FoldedListbox onClick={handleOpen} resource={resources[0]} stores={stores} />
: <ExpandButton onClick={handleOpen} opened={popoverOpen} stores={stores} />}
<Popover
<StyledPopover
open={popoverOpen}
onClose={handleClose}
anchorEl={containerRef.current}
transitionDuration={transitionDuration}
isSmallDevice={isSmallDevice}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
slotProps={{ paper: popoverPaperProps(!!selectedResource, isSmallDevice, stardustTheme, muiTheme) }}
anchorReference= {isSmallDevice ? 'anchorPosition' : 'anchorEl'}
slotProps={{
paper: popoverPaperProps(!!selectedResource, isSmallDevice, stardustTheme, muiTheme),
}}
anchorReference={isSmallDevice ? 'anchorPosition' : 'anchorEl'}
anchorPosition= {{ left: 0, top: 0 }}
marginThreshold={isSmallDevice ? 0 : 16}
className='listbox-popover'
Expand All @@ -234,7 +264,7 @@ export const ListboxPopoverContainer = ({ resources, stores }: FoldedPopoverProp
))}
</Grid>
}
</Popover>
</StyledPopover>
</StyledDiv>
);
};
Loading