Add "shouldForwardProp" util function
This commit is contained in:
@@ -8,12 +8,15 @@
|
|||||||
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import Typography, { TypographyProps } from '@mui/material/Typography';
|
import Typography, { TypographyProps } from '@mui/material/Typography';
|
||||||
|
import { shouldForwardProp } from '@/lib/ui/ShouldForwardProp.ts';
|
||||||
|
|
||||||
|
type TypographyMaxLinesProps = {
|
||||||
|
lines?: number;
|
||||||
|
};
|
||||||
|
|
||||||
export const TypographyMaxLines = styled(Typography, {
|
export const TypographyMaxLines = styled(Typography, {
|
||||||
shouldForwardProp: (prop) => prop !== 'lines',
|
shouldForwardProp: shouldForwardProp<TypographyMaxLinesProps>(['lines']),
|
||||||
})<{
|
})<TypographyMaxLinesProps>(({ lines = 2 }) => ({
|
||||||
lines?: number;
|
|
||||||
}>(({ lines = 2 }) => ({
|
|
||||||
lineHeight: '1.5rem',
|
lineHeight: '1.5rem',
|
||||||
maxHeight: '3rem',
|
maxHeight: '3rem',
|
||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
|
|||||||
@@ -45,10 +45,14 @@ import { Mangas } from '@/lib/data/Mangas';
|
|||||||
import { useNavBarContext } from '@/components/context/NavbarContext.tsx';
|
import { useNavBarContext } from '@/components/context/NavbarContext.tsx';
|
||||||
import { useResizeObserver } from '@/util/useResizeObserver.tsx';
|
import { useResizeObserver } from '@/util/useResizeObserver.tsx';
|
||||||
import { MediaQuery } from '@/lib/ui/MediaQuery.tsx';
|
import { MediaQuery } from '@/lib/ui/MediaQuery.tsx';
|
||||||
|
import { shouldForwardProp } from '@/lib/ui/ShouldForwardProp.ts';
|
||||||
|
|
||||||
const ChapterListHeader = styled(Stack, { shouldForwardProp: (prop) => prop !== 'scrollbarWidth' })<{
|
type ChapterListHeaderProps = {
|
||||||
scrollbarWidth: number;
|
scrollbarWidth: number;
|
||||||
}>(({ theme, scrollbarWidth }) => ({
|
};
|
||||||
|
const ChapterListHeader = styled(Stack, {
|
||||||
|
shouldForwardProp: shouldForwardProp<ChapterListHeaderProps>(['scrollbarWidth']),
|
||||||
|
})<ChapterListHeaderProps>(({ theme, scrollbarWidth }) => ({
|
||||||
padding: theme.spacing(1),
|
padding: theme.spacing(1),
|
||||||
paddingRight: `calc(${scrollbarWidth}px + ${theme.spacing(1)})`,
|
paddingRight: `calc(${scrollbarWidth}px + ${theme.spacing(1)})`,
|
||||||
paddingBottom: 0,
|
paddingBottom: 0,
|
||||||
@@ -57,16 +61,17 @@ const ChapterListHeader = styled(Stack, { shouldForwardProp: (prop) => prop !==
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledVirtuoso = styled(Virtuoso, { shouldForwardProp: (prop) => prop !== 'topOffset' })<{ topOffset: number }>(
|
type StyledVirtuosoProps = { topOffset: number };
|
||||||
({ theme, topOffset }) => ({
|
const StyledVirtuoso = styled(Virtuoso, {
|
||||||
listStyle: 'none',
|
shouldForwardProp: shouldForwardProp<StyledVirtuosoProps>(['topOffset']),
|
||||||
padding: 0,
|
})<StyledVirtuosoProps>(({ theme, topOffset }) => ({
|
||||||
[theme.breakpoints.up('md')]: {
|
listStyle: 'none',
|
||||||
height: `calc(100vh - ${topOffset}px)`,
|
padding: 0,
|
||||||
margin: 0,
|
[theme.breakpoints.up('md')]: {
|
||||||
},
|
height: `calc(100vh - ${topOffset}px)`,
|
||||||
}),
|
margin: 0,
|
||||||
);
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
export interface IChapterWithMeta extends ChapterWithMetaType<ComponentProps<typeof ChapterCard>['chapter']> {
|
export interface IChapterWithMeta extends ChapterWithMetaType<ComponentProps<typeof ChapterCard>['chapter']> {
|
||||||
selected: boolean | null;
|
selected: boolean | null;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import { MangaType, SourceType } from '@/lib/graphql/generated/graphql.ts';
|
|||||||
import { useLocalStorage } from '@/util/useStorage.tsx';
|
import { useLocalStorage } from '@/util/useStorage.tsx';
|
||||||
import { useResizeObserver } from '@/util/useResizeObserver.tsx';
|
import { useResizeObserver } from '@/util/useResizeObserver.tsx';
|
||||||
import { useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
import { useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
||||||
|
import { shouldForwardProp } from '@/lib/ui/ShouldForwardProp.ts';
|
||||||
|
|
||||||
const DetailsWrapper = styled('div')(({ theme }) => ({
|
const DetailsWrapper = styled('div')(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -51,12 +52,13 @@ const DetailsWrapper = styled('div')(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const TopContentWrapper = styled('div', {
|
type TopContentWrapperProps = {
|
||||||
shouldForwardProp: (prop) => !['url', 'mangaThumbnailBackdrop'].includes(prop as string),
|
|
||||||
})<{
|
|
||||||
url: string;
|
url: string;
|
||||||
mangaThumbnailBackdrop: boolean;
|
mangaThumbnailBackdrop: boolean;
|
||||||
}>(({ theme, url, mangaThumbnailBackdrop }) => ({
|
};
|
||||||
|
const TopContentWrapper = styled('div', {
|
||||||
|
shouldForwardProp: shouldForwardProp<TopContentWrapperProps>(['url', 'mangaThumbnailBackdrop']),
|
||||||
|
})<TopContentWrapperProps>(({ theme, url, mangaThumbnailBackdrop }) => ({
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
backgroundImage: mangaThumbnailBackdrop ? `url(${url})` : undefined,
|
backgroundImage: mangaThumbnailBackdrop ? `url(${url})` : undefined,
|
||||||
backgroundRepeat: mangaThumbnailBackdrop ? 'no-repeat' : undefined,
|
backgroundRepeat: mangaThumbnailBackdrop ? 'no-repeat' : undefined,
|
||||||
|
|||||||
@@ -8,12 +8,14 @@
|
|||||||
|
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
import Typography, { TypographyProps } from '@mui/material/Typography';
|
import Typography, { TypographyProps } from '@mui/material/Typography';
|
||||||
|
import { shouldForwardProp } from '@/lib/ui/ShouldForwardProp.ts';
|
||||||
|
|
||||||
export const StyledGroupHeader = styled(Typography, { shouldForwardProp: (prop) => prop !== 'isFirstItem' })<
|
type StyledGroupHeaderProps = {
|
||||||
{
|
isFirstItem: boolean;
|
||||||
isFirstItem: boolean;
|
};
|
||||||
} & TypographyProps
|
export const StyledGroupHeader = styled(Typography, {
|
||||||
>(({ theme, isFirstItem }) => ({
|
shouldForwardProp: shouldForwardProp<StyledGroupHeaderProps>(['isFirstItem']),
|
||||||
|
})<StyledGroupHeaderProps & TypographyProps>(({ theme, isFirstItem }) => ({
|
||||||
paddingLeft: theme.spacing(3),
|
paddingLeft: theme.spacing(3),
|
||||||
// 16px - 10px (bottom padding of the group items)
|
// 16px - 10px (bottom padding of the group items)
|
||||||
paddingTop: theme.spacing(0.75),
|
paddingTop: theme.spacing(0.75),
|
||||||
|
|||||||
18
src/lib/ui/ShouldForwardProp.ts
Normal file
18
src/lib/ui/ShouldForwardProp.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
type TupleUnion<U extends string | number | symbol, R extends any[] = []> = {
|
||||||
|
[S in U]: Exclude<U, S> extends never ? [...R, S] : TupleUnion<Exclude<U, S>, [...R, S]>;
|
||||||
|
}[U];
|
||||||
|
|
||||||
|
export const shouldForwardProp =
|
||||||
|
<TCustomProps extends Record<string, unknown>>(customProps: TupleUnion<keyof TCustomProps>) =>
|
||||||
|
(prop: string): boolean =>
|
||||||
|
// @ts-ignore - TS2589: Type instantiation is excessively deep and possibly infinite.
|
||||||
|
// this function should never be used without a strict type, thus, this error can be ignored
|
||||||
|
!customProps.includes(prop);
|
||||||
Reference in New Issue
Block a user