refactor: css

This commit is contained in:
iCrawl
2022-08-23 13:21:32 +02:00
parent a57b9ba5c4
commit 5b4672bad3
10 changed files with 100 additions and 103 deletions

View File

@@ -1,6 +1,6 @@
import { ActionIcon, Badge, Box, Group, MediaQuery, Stack, Title } from '@mantine/core'; import { ActionIcon, Badge, Box, createStyles, Group, MediaQuery, Stack, Title } from '@mantine/core';
import { useMediaQuery } from '@mantine/hooks'; import { useMediaQuery } from '@mantine/hooks';
import type { ReactNode } from 'react'; import type { PropsWithChildren } from 'react';
import { FiLink } from 'react-icons/fi'; import { FiLink } from 'react-icons/fi';
import { HyperlinkedText } from './HyperlinkedText'; import { HyperlinkedText } from './HyperlinkedText';
import { InheritanceText } from './InheritanceText'; import { InheritanceText } from './InheritanceText';
@@ -14,6 +14,17 @@ export enum CodeListingSeparatorType {
Value = '=', Value = '=',
} }
const useStyles = createStyles((theme) => ({
outer: {
display: 'flex',
gap: 16,
[theme.fn.smallerThan('sm')]: {
flexDirection: 'column',
},
},
}));
export function CodeListing({ export function CodeListing({
name, name,
separator = CodeListingSeparatorType.Type, separator = CodeListingSeparatorType.Type,
@@ -25,7 +36,7 @@ export function CodeListing({
comment, comment,
deprecation, deprecation,
inheritanceData, inheritanceData,
}: { }: PropsWithChildren<{
name: string; name: string;
separator?: CodeListingSeparatorType; separator?: CodeListingSeparatorType;
typeTokens: TokenDocumentation[]; typeTokens: TokenDocumentation[];
@@ -33,25 +44,15 @@ export function CodeListing({
optional?: boolean; optional?: boolean;
summary?: ApiItemJSON['summary']; summary?: ApiItemJSON['summary'];
comment?: AnyDocNodeJSON | null; comment?: AnyDocNodeJSON | null;
children?: ReactNode;
deprecation?: AnyDocNodeJSON | null; deprecation?: AnyDocNodeJSON | null;
inheritanceData?: InheritanceData | null; inheritanceData?: InheritanceData | null;
}) { }>) {
const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); const { classes } = useStyles();
const matches = useMediaQuery('(max-width: 768px)');
return ( return (
<Stack id={name} className="scroll-mt-30" spacing="xs"> <Stack id={name} className="scroll-mt-30" spacing="xs">
<Box <Box className={classes.outer} ml={matches ? 0 : -45}>
sx={(theme) => ({
display: 'flex',
gap: 16,
[theme.fn.smallerThan('sm')]: {
flexDirection: 'column',
},
})}
ml={matches ? 0 : -45}
>
<MediaQuery smallerThan="sm" styles={{ display: 'none' }}> <MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
<ActionIcon component="a" href={`#${name}`} variant="transparent"> <ActionIcon component="a" href={`#${name}`} variant="transparent">
<FiLink size={20} /> <FiLink size={20} />

View File

@@ -1,7 +1,7 @@
import { Group, Stack, Title, Text, Box, MediaQuery, Aside, ScrollArea, Skeleton, Divider } from '@mantine/core'; import { Group, Stack, Title, Text, Box, MediaQuery, Aside, ScrollArea, Skeleton, Divider } from '@mantine/core';
import { useMediaQuery } from '@mantine/hooks'; import { useMediaQuery } from '@mantine/hooks';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { Fragment, type ReactNode } from 'react'; import { Fragment, type PropsWithChildren } from 'react';
import { import {
VscSymbolClass, VscSymbolClass,
VscSymbolMethod, VscSymbolMethod,
@@ -23,19 +23,18 @@ import type { TypeParameterData } from '~/DocModel/TypeParameterMixin';
import type { AnyDocNodeJSON } from '~/DocModel/comment/CommentNode'; import type { AnyDocNodeJSON } from '~/DocModel/comment/CommentNode';
import type { TokenDocumentation } from '~/util/parse.server'; import type { TokenDocumentation } from '~/util/parse.server';
interface DocContainerProps { type DocContainerProps = PropsWithChildren<{
name: string; name: string;
kind: string; kind: string;
excerpt: string; excerpt: string;
summary?: ApiItemJSON['summary']; summary?: ApiItemJSON['summary'];
children?: ReactNode;
extendsTokens?: TokenDocumentation[] | null; extendsTokens?: TokenDocumentation[] | null;
implementsTokens?: TokenDocumentation[][]; implementsTokens?: TokenDocumentation[][];
typeParams?: TypeParameterData[]; typeParams?: TypeParameterData[];
comment?: AnyDocNodeJSON | null; comment?: AnyDocNodeJSON | null;
methods?: ApiClassJSON['methods'] | ApiInterfaceJSON['methods'] | null; methods?: ApiClassJSON['methods'] | ApiInterfaceJSON['methods'] | null;
properties?: ApiClassJSON['properties'] | ApiInterfaceJSON['properties'] | null; properties?: ApiClassJSON['properties'] | ApiInterfaceJSON['properties'] | null;
} }>;
function generateIcon(kind: string) { function generateIcon(kind: string) {
const icons = { const icons = {
@@ -63,7 +62,7 @@ export function DocContainer({
properties, properties,
}: DocContainerProps) { }: DocContainerProps) {
const router = useRouter(); const router = useRouter();
const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); const matches = useMediaQuery('(max-width: 768px)');
return ( return (
<Group> <Group>

View File

@@ -4,7 +4,7 @@ import type { InheritanceData } from '~/DocModel/ApiNodeJSONEncoder';
export function InheritanceText({ data }: { data: InheritanceData }) { export function InheritanceText({ data }: { data: InheritanceData }) {
return ( return (
<Text className="font-semibold"> <Text weight={600}>
{'Inherited from '} {'Inherited from '}
<Link href={data.path} passHref> <Link href={data.path} passHref>
<Anchor component="a" className="font-mono"> <Anchor component="a" className="font-mono">

View File

@@ -1,4 +1,4 @@
import { ActionIcon, Badge, Box, Group, MediaQuery, Stack, Title } from '@mantine/core'; import { ActionIcon, Badge, Box, createStyles, Group, MediaQuery, Stack, Title } from '@mantine/core';
import { useMediaQuery } from '@mantine/hooks'; import { useMediaQuery } from '@mantine/hooks';
import { FiLink } from 'react-icons/fi'; import { FiLink } from 'react-icons/fi';
import { HyperlinkedText } from './HyperlinkedText'; import { HyperlinkedText } from './HyperlinkedText';
@@ -8,6 +8,17 @@ import { TSDoc } from './tsdoc/TSDoc';
import type { ApiMethodJSON, ApiMethodSignatureJSON } from '~/DocModel/ApiNodeJSONEncoder'; import type { ApiMethodJSON, ApiMethodSignatureJSON } from '~/DocModel/ApiNodeJSONEncoder';
import { Visibility } from '~/DocModel/Visibility'; import { Visibility } from '~/DocModel/Visibility';
const useStyles = createStyles((theme) => ({
outer: {
display: 'flex',
gap: 16,
[theme.fn.smallerThan('sm')]: {
flexDirection: 'column',
},
},
}));
function getShorthandName(data: ApiMethodJSON | ApiMethodSignatureJSON) { function getShorthandName(data: ApiMethodJSON | ApiMethodSignatureJSON) {
return `${data.name}${data.optional ? '?' : ''}(${data.parameters.reduce((prev, cur, index) => { return `${data.name}${data.optional ? '?' : ''}(${data.parameters.reduce((prev, cur, index) => {
if (index === 0) { if (index === 0) {
@@ -19,7 +30,8 @@ function getShorthandName(data: ApiMethodJSON | ApiMethodSignatureJSON) {
} }
export function MethodItem({ data }: { data: ApiMethodJSON | ApiMethodSignatureJSON }) { export function MethodItem({ data }: { data: ApiMethodJSON | ApiMethodSignatureJSON }) {
const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); const { classes } = useStyles();
const matches = useMediaQuery('(max-width: 768px)');
const method = data as ApiMethodJSON; const method = data as ApiMethodJSON;
const key = `${data.name}${data.overloadIndex && data.overloadIndex > 1 ? `:${data.overloadIndex}` : ''}`; const key = `${data.name}${data.overloadIndex && data.overloadIndex > 1 ? `:${data.overloadIndex}` : ''}`;
@@ -27,17 +39,7 @@ export function MethodItem({ data }: { data: ApiMethodJSON | ApiMethodSignatureJ
<Stack id={key} className="scroll-mt-30" spacing="xs"> <Stack id={key} className="scroll-mt-30" spacing="xs">
<Group> <Group>
<Stack> <Stack>
<Box <Box className={classes.outer} ml={matches ? 0 : -45}>
sx={(theme) => ({
display: 'flex',
gap: 16,
[theme.fn.smallerThan('sm')]: {
flexDirection: 'column',
},
})}
ml={matches ? 0 : -45}
>
<MediaQuery smallerThan="sm" styles={{ display: 'none' }}> <MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
<ActionIcon component="a" href={`#${key}`} variant="transparent"> <ActionIcon component="a" href={`#${key}`} variant="transparent">
<FiLink size={20} /> <FiLink size={20} />

View File

@@ -8,7 +8,7 @@ import {
Text, Text,
useMantineColorScheme, useMantineColorScheme,
} from '@mantine/core'; } from '@mantine/core';
import { type ReactNode, useState, useEffect } from 'react'; import { useState, useEffect, type PropsWithChildren } from 'react';
import { VscChevronDown } from 'react-icons/vsc'; import { VscChevronDown } from 'react-icons/vsc';
const useStyles = createStyles((theme, { opened }: { opened: boolean }) => ({ const useStyles = createStyles((theme, { opened }: { opened: boolean }) => ({
@@ -39,14 +39,13 @@ export function Section({
dense = false, dense = false,
defaultClosed = false, defaultClosed = false,
children, children,
}: { }: PropsWithChildren<{
title: string; title: string;
icon?: JSX.Element; icon?: JSX.Element;
padded?: boolean; padded?: boolean;
dense?: boolean; dense?: boolean;
defaultClosed?: boolean; defaultClosed?: boolean;
children: ReactNode; }>) {
}) {
const [opened, setOpened] = useState(!defaultClosed); const [opened, setOpened] = useState(!defaultClosed);
const { colorScheme } = useMantineColorScheme(); const { colorScheme } = useMantineColorScheme();
const { classes } = useStyles({ opened }); const { classes } = useStyles({ opened });

View File

@@ -10,7 +10,7 @@ import type { ApiClassJSON, ApiConstructorJSON, ApiInterfaceJSON } from '~/DocMo
import type { ParameterDocumentation } from '~/util/parse.server'; import type { ParameterDocumentation } from '~/util/parse.server';
export function PropertiesSection({ data }: { data: ApiClassJSON['properties'] | ApiInterfaceJSON['properties'] }) { export function PropertiesSection({ data }: { data: ApiClassJSON['properties'] | ApiInterfaceJSON['properties'] }) {
const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); const matches = useMediaQuery('(max-width: 768px)');
return data.length ? ( return data.length ? (
<Section title="Properties" icon={<VscSymbolProperty size={20} />} padded dense={matches}> <Section title="Properties" icon={<VscSymbolProperty size={20} />} padded dense={matches}>
@@ -20,7 +20,7 @@ export function PropertiesSection({ data }: { data: ApiClassJSON['properties'] |
} }
export function MethodsSection({ data }: { data: ApiClassJSON['methods'] | ApiInterfaceJSON['methods'] }) { export function MethodsSection({ data }: { data: ApiClassJSON['methods'] | ApiInterfaceJSON['methods'] }) {
const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); const matches = useMediaQuery('(max-width: 768px)');
return data.length ? ( return data.length ? (
<Section title="Methods" icon={<VscSymbolMethod size={20} />} padded dense={matches}> <Section title="Methods" icon={<VscSymbolMethod size={20} />} padded dense={matches}>
@@ -30,7 +30,7 @@ export function MethodsSection({ data }: { data: ApiClassJSON['methods'] | ApiIn
} }
export function ParametersSection({ data }: { data: ParameterDocumentation[] }) { export function ParametersSection({ data }: { data: ParameterDocumentation[] }) {
const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); const matches = useMediaQuery('(max-width: 768px)');
return data.length ? ( return data.length ? (
<Section title="Parameters" icon={<VscSymbolConstant size={20} />} padded dense={matches}> <Section title="Parameters" icon={<VscSymbolConstant size={20} />} padded dense={matches}>
@@ -40,7 +40,7 @@ export function ParametersSection({ data }: { data: ParameterDocumentation[] })
} }
export function ConstructorSection({ data }: { data: ApiConstructorJSON }) { export function ConstructorSection({ data }: { data: ApiConstructorJSON }) {
const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); const matches = useMediaQuery('(max-width: 768px)');
const getShorthandName = () => const getShorthandName = () =>
`constructor(${data.parameters.reduce((prev, cur, index) => { `constructor(${data.parameters.reduce((prev, cur, index) => {

View File

@@ -88,6 +88,47 @@ const useStyles = createStyles(
transition: 'transform 150ms ease', transition: 'transform 150ms ease',
transform: openedVersion ? 'rotate(180deg)' : 'rotate(0deg)', transform: openedVersion ? 'rotate(180deg)' : 'rotate(0deg)',
}, },
content: {
position: 'relative',
minHeight: 'calc(100vh - 50px)',
zIndex: 1,
background: theme.colorScheme === 'dark' ? theme.colors.dark![8] : theme.colors.gray![0],
boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
},
footer: {
position: 'fixed',
bottom: 0,
left: 0,
right: 0,
height: 200,
background: theme.colorScheme === 'dark' ? theme.colors.dark![7] : theme.colors.gray![0],
paddingLeft: 324,
[theme.fn.smallerThan('lg')]: {
paddingRight: 24,
},
[theme.fn.smallerThan('md')]: {
paddingLeft: 24,
},
[theme.fn.smallerThan('sm')]: {
height: 300,
},
},
links: {
display: 'flex',
justifyContent: 'space-between',
[theme.fn.smallerThan('sm')]: {
flexDirection: 'column',
alignItems: 'center',
gap: 50,
},
},
}), }),
); );
@@ -281,59 +322,18 @@ export function SidebarLayout({
} }
> >
<article> <article>
<Box <Box className={classes.content} p="lg" pb={80}>
sx={(theme) => ({
position: 'relative',
minHeight: 'calc(100vh - 50px)',
zIndex: 1,
background: theme.colorScheme === 'dark' ? theme.colors.dark![8] : theme.colors.gray![0],
boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
})}
p="lg"
pb={80}
>
{children} {children}
</Box> </Box>
<Box sx={(theme) => ({ height: 200, [theme.fn.smallerThan('sm')]: { height: 300 } })}></Box> <Box sx={(theme) => ({ height: 200, [theme.fn.smallerThan('sm')]: { height: 300 } })}></Box>
<Box <Box
component="footer" component="footer"
sx={(theme) => ({ sx={{ paddingRight: data?.member?.kind !== 'Class' && data?.member?.kind !== 'Interface' ? 24 : 324 }}
position: 'fixed', className={classes.footer}
bottom: 0,
left: 0,
right: 0,
height: 200,
background: theme.colorScheme === 'dark' ? theme.colors.dark![7] : theme.colors.gray![0],
paddingLeft: 324,
paddingRight: data?.member?.kind !== 'Class' && data?.member?.kind !== 'Interface' ? 24 : 324,
[theme.fn.smallerThan('lg')]: {
paddingRight: 24,
},
[theme.fn.smallerThan('md')]: {
paddingLeft: 24,
},
[theme.fn.smallerThan('sm')]: {
height: 300,
},
})}
pt={50} pt={50}
> >
<Container> <Container>
<Box <Box className={classes.links}>
sx={(theme) => ({
display: 'flex',
justifyContent: 'space-between',
[theme.fn.smallerThan('sm')]: {
flexDirection: 'column',
alignItems: 'center',
gap: 50,
},
})}
>
<Link href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss" passHref> <Link href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss" passHref>
<a title="Vercel"> <a title="Vercel">
<Image <Image

View File

@@ -9,7 +9,7 @@ import type { ApiEnumJSON } from '~/DocModel/ApiNodeJSONEncoder';
export function Enum({ data }: { data: ApiEnumJSON }) { export function Enum({ data }: { data: ApiEnumJSON }) {
const router = useRouter(); const router = useRouter();
const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false }); const matches = useMediaQuery('(max-width: 768px)');
return ( return (
<DocContainer name={data.name} kind={data.kind} excerpt={data.excerpt} summary={data.summary}> <DocContainer name={data.name} kind={data.kind} excerpt={data.excerpt} summary={data.summary}>

View File

@@ -1,9 +1,9 @@
import { Alert, Box, Title, Text } from '@mantine/core'; import { Alert, Box, Title, Text } from '@mantine/core';
import { StandardTags } from '@microsoft/tsdoc'; import { StandardTags } from '@microsoft/tsdoc';
import type { ReactNode } from 'react'; import type { PropsWithChildren } from 'react';
import { VscWarning } from 'react-icons/vsc'; import { VscWarning } from 'react-icons/vsc';
export function Block({ children, title }: { children: ReactNode; title: string }) { export function Block({ children, title }: PropsWithChildren<{ title: string }>) {
return ( return (
<Box> <Box>
<Title order={5}>{title}</Title> <Title order={5}>{title}</Title>
@@ -15,14 +15,11 @@ export function Block({ children, title }: { children: ReactNode; title: string
export function ExampleBlock({ export function ExampleBlock({
children, children,
exampleIndex, exampleIndex,
}: { }: PropsWithChildren<{ exampleIndex?: number | undefined }>): JSX.Element {
children: ReactNode;
exampleIndex?: number | undefined;
}): JSX.Element {
return <Block title={`Example ${exampleIndex ? exampleIndex : ''}`}>{children}</Block>; return <Block title={`Example ${exampleIndex ? exampleIndex : ''}`}>{children}</Block>;
} }
export function DeprecatedBlock({ children }: { children: ReactNode }): JSX.Element { export function DeprecatedBlock({ children }: PropsWithChildren): JSX.Element {
return ( return (
<Alert icon={<VscWarning />} title="Deprecated" variant="outline" color="red" radius="sm"> <Alert icon={<VscWarning />} title="Deprecated" variant="outline" color="red" radius="sm">
{children} {children}
@@ -30,11 +27,11 @@ export function DeprecatedBlock({ children }: { children: ReactNode }): JSX.Elem
); );
} }
export function DefaultValueBlock({ children }: { children: ReactNode }): JSX.Element { export function DefaultValueBlock({ children }: PropsWithChildren): JSX.Element {
return <Block title="Default value">{children}</Block>; return <Block title="Default value">{children}</Block>;
} }
export function RemarksBlock({ children }: { children: ReactNode }): JSX.Element { export function RemarksBlock({ children }: PropsWithChildren): JSX.Element {
return <Block title="Remarks">{children}</Block>; return <Block title="Remarks">{children}</Block>;
} }
@@ -42,11 +39,10 @@ export function BlockComment({
children, children,
tagName, tagName,
index, index,
}: { }: PropsWithChildren<{
tagName: string; tagName: string;
children: ReactNode;
index?: number | undefined; index?: number | undefined;
}): JSX.Element { }>): JSX.Element {
switch (tagName.toUpperCase()) { switch (tagName.toUpperCase()) {
case StandardTags.example.tagNameWithUpperCase: case StandardTags.example.tagNameWithUpperCase:
return <ExampleBlock exampleIndex={index}>{children}</ExampleBlock>; return <ExampleBlock exampleIndex={index}>{children}</ExampleBlock>;

View File

@@ -203,7 +203,7 @@ const member = (props?: ApiItemJSON | undefined) => {
export default function SlugPage(props: Partial<SidebarLayoutProps & { error?: string }>) { export default function SlugPage(props: Partial<SidebarLayoutProps & { error?: string }>) {
const router = useRouter(); const router = useRouter();
const [scroll, scrollTo] = useWindowScroll(); const [scroll, scrollTo] = useWindowScroll();
const matches = useMediaQuery('(max-width: 1200px)', true, { getInitialValueInEffect: false }); const matches = useMediaQuery('(max-width: 1200px)');
const name = `discord.js${props.data?.member?.name ? ` | ${props.data.member.name}` : ''}`; const name = `discord.js${props.data?.member?.name ? ` | ${props.data.member.name}` : ''}`;