Use window scroll for grouped virtuosos
This commit is contained in:
@@ -18,6 +18,7 @@ import { TabsMenu } from '@/modules/core/components/tabs/TabsMenu.tsx';
|
|||||||
import { Migration } from '@/modules/migration/screens/Migration.tsx';
|
import { Migration } from '@/modules/migration/screens/Migration.tsx';
|
||||||
import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx';
|
import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx';
|
||||||
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
|
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
|
||||||
|
import { GROUPED_VIRTUOSO_Z_INDEX } from '@/modules/core/AppRoute.constants.ts';
|
||||||
|
|
||||||
enum Tabs {
|
enum Tabs {
|
||||||
SOURCE = 'source',
|
SOURCE = 'source',
|
||||||
@@ -51,6 +52,7 @@ export function Browse() {
|
|||||||
<TabsWrapper>
|
<TabsWrapper>
|
||||||
<TabsMenu
|
<TabsMenu
|
||||||
ref={tabsMenuRef}
|
ref={tabsMenuRef}
|
||||||
|
sx={{ zIndex: GROUPED_VIRTUOSO_Z_INDEX }}
|
||||||
variant="fullWidth"
|
variant="fullWidth"
|
||||||
value={tabName}
|
value={tabName}
|
||||||
onChange={(_, newTab) => setTabSearchParam(newTab, 'replaceIn')}
|
onChange={(_, newTab) => setTabSearchParam(newTab, 'replaceIn')}
|
||||||
|
|||||||
@@ -181,3 +181,5 @@ type ExtractStringPaths<T> = T extends { path: infer P }
|
|||||||
: ExtractChildRouteStringPaths<T>;
|
: ExtractChildRouteStringPaths<T>;
|
||||||
|
|
||||||
export type StaticAppRoute = ExtractStringPaths<(typeof AppRoutes)[keyof typeof AppRoutes]>;
|
export type StaticAppRoute = ExtractStringPaths<(typeof AppRoutes)[keyof typeof AppRoutes]>;
|
||||||
|
|
||||||
|
export const GROUPED_VIRTUOSO_Z_INDEX = 2;
|
||||||
|
|||||||
@@ -6,10 +6,19 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { GroupedVirtuoso } from 'react-virtuoso';
|
import { ContextProp, GroupedVirtuoso, TopItemListProps } from 'react-virtuoso';
|
||||||
import { ComponentProps } from 'react';
|
import { ComponentProps, useMemo } from 'react';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
|
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
|
||||||
|
|
||||||
|
const StickyVirtuosoHeaderWithOffset =
|
||||||
|
(topOffset: number) =>
|
||||||
|
({ children, ...args }: TopItemListProps & ContextProp<unknown>) => (
|
||||||
|
<Box {...args} style={{ ...args.style, top: topOffset }}>
|
||||||
|
{children}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
export const StyledGroupedVirtuoso = ({
|
export const StyledGroupedVirtuoso = ({
|
||||||
heightToSubtract = 0,
|
heightToSubtract = 0,
|
||||||
style,
|
style,
|
||||||
@@ -17,9 +26,19 @@ export const StyledGroupedVirtuoso = ({
|
|||||||
}: ComponentProps<typeof GroupedVirtuoso> & { heightToSubtract?: number }) => {
|
}: ComponentProps<typeof GroupedVirtuoso> & { heightToSubtract?: number }) => {
|
||||||
const { appBarHeight, bottomBarHeight } = useNavBarContext();
|
const { appBarHeight, bottomBarHeight } = useNavBarContext();
|
||||||
|
|
||||||
|
const TopItemList = useMemo(
|
||||||
|
() => StickyVirtuosoHeaderWithOffset(appBarHeight + heightToSubtract),
|
||||||
|
[appBarHeight, heightToSubtract],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GroupedVirtuoso
|
<GroupedVirtuoso
|
||||||
|
useWindowScroll
|
||||||
{...props}
|
{...props}
|
||||||
|
components={{
|
||||||
|
TopItemList,
|
||||||
|
...props.components,
|
||||||
|
}}
|
||||||
style={{
|
style={{
|
||||||
...style,
|
...style,
|
||||||
height: `calc(100vh - ${heightToSubtract}px - ${appBarHeight}px - ${bottomBarHeight}px - ${!bottomBarHeight ? 'env(safe-area-inset-bottom)' : '0px'})`,
|
height: `calc(100vh - ${heightToSubtract}px - ${appBarHeight}px - ${bottomBarHeight}px - ${!bottomBarHeight ? 'env(safe-area-inset-bottom)' : '0px'})`,
|
||||||
|
|||||||
@@ -86,10 +86,6 @@ export const History: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledGroupedVirtuoso
|
<StyledGroupedVirtuoso
|
||||||
style={{
|
|
||||||
// override Virtuoso default values and set them with class
|
|
||||||
height: 'undefined',
|
|
||||||
}}
|
|
||||||
components={{
|
components={{
|
||||||
Footer: () => (isLoading ? <LoadingPlaceholder usePadding /> : null),
|
Footer: () => (isLoading ? <LoadingPlaceholder usePadding /> : null),
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -23,9 +23,11 @@ import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
|||||||
import { ChapterUpdateCard } from '@/modules/updates/components/ChapterUpdateCard.tsx';
|
import { ChapterUpdateCard } from '@/modules/updates/components/ChapterUpdateCard.tsx';
|
||||||
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
|
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
|
||||||
import { Chapters } from '@/modules/chapter/services/Chapters.ts';
|
import { Chapters } from '@/modules/chapter/services/Chapters.ts';
|
||||||
|
import { GROUPED_VIRTUOSO_Z_INDEX } from '@/modules/core/AppRoute.constants.ts';
|
||||||
|
|
||||||
export const Updates: React.FC = () => {
|
export const Updates: React.FC = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { appBarHeight } = useNavBarContext();
|
||||||
|
|
||||||
const { setTitle, setAction } = useNavBarContext();
|
const { setTitle, setAction } = useNavBarContext();
|
||||||
const {
|
const {
|
||||||
@@ -107,6 +109,10 @@ export const Updates: React.FC = () => {
|
|||||||
<Typography
|
<Typography
|
||||||
ref={lastUpdateTimestampCompRef}
|
ref={lastUpdateTimestampCompRef}
|
||||||
sx={{
|
sx={{
|
||||||
|
position: 'sticky',
|
||||||
|
top: appBarHeight,
|
||||||
|
zIndex: GROUPED_VIRTUOSO_Z_INDEX,
|
||||||
|
backgroundColor: 'background.default',
|
||||||
marginLeft: '10px',
|
marginLeft: '10px',
|
||||||
paddingTop: (theme) => ({ [theme.breakpoints.up('sm')]: { paddingTop: '6px' } }),
|
paddingTop: (theme) => ({ [theme.breakpoints.up('sm')]: { paddingTop: '6px' } }),
|
||||||
}}
|
}}
|
||||||
@@ -117,10 +123,6 @@ export const Updates: React.FC = () => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<StyledGroupedVirtuoso
|
<StyledGroupedVirtuoso
|
||||||
heightToSubtract={lastUpdateTimestampCompHeight}
|
heightToSubtract={lastUpdateTimestampCompHeight}
|
||||||
style={{
|
|
||||||
// override Virtuoso default values and set them with class
|
|
||||||
height: 'undefined',
|
|
||||||
}}
|
|
||||||
components={{
|
components={{
|
||||||
Footer: () => (isLoading ? <LoadingPlaceholder usePadding /> : null),
|
Footer: () => (isLoading ? <LoadingPlaceholder usePadding /> : null),
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in New Issue
Block a user