feat: active navigation and back button

This commit is contained in:
iCrawl
2022-08-23 00:44:09 +02:00
parent 0fb2694871
commit f16b11a91d
6 changed files with 91 additions and 27 deletions

View File

@@ -1,4 +1,13 @@
import { createStyles, UnstyledButton, Group, ThemeIcon, Collapse, Box, Text } from '@mantine/core'; import {
createStyles,
UnstyledButton,
Group,
ThemeIcon,
Collapse,
Box,
Text,
useMantineColorScheme,
} from '@mantine/core';
import { type ReactNode, useState } from 'react'; import { type ReactNode, useState } from 'react';
import { VscChevronDown } from 'react-icons/vsc'; import { VscChevronDown } from 'react-icons/vsc';
@@ -8,9 +17,11 @@ const useStyles = createStyles((theme, { opened }: { opened: boolean }) => ({
width: '100%', width: '100%',
padding: theme.spacing.xs, padding: theme.spacing.xs,
color: theme.colorScheme === 'dark' ? theme.colors.dark![0] : theme.black, color: theme.colorScheme === 'dark' ? theme.colors.dark![0] : theme.black,
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![7] : 'transparent',
borderRadius: theme.radius.xs,
'&:hover': { '&:hover': {
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![6] : theme.colors.gray![0], backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![5] : theme.colors.gray![2],
color: theme.colorScheme === 'dark' ? theme.white : theme.black, color: theme.colorScheme === 'dark' ? theme.white : theme.black,
}, },
}, },
@@ -37,6 +48,7 @@ export function Section({
children: ReactNode; children: ReactNode;
}) { }) {
const [opened, setOpened] = useState(!defaultClosed); const [opened, setOpened] = useState(!defaultClosed);
const { colorScheme } = useMantineColorScheme();
const { classes } = useStyles({ opened }); const { classes } = useStyles({ opened });
return ( return (
@@ -44,7 +56,11 @@ export function Section({
<UnstyledButton className={classes.control} onClick={() => setOpened((o) => !o)}> <UnstyledButton className={classes.control} onClick={() => setOpened((o) => !o)}>
<Group position="apart"> <Group position="apart">
<Group> <Group>
{icon ? <ThemeIcon size={30}>{icon}</ThemeIcon> : null} {icon ? (
<ThemeIcon variant={colorScheme === 'dark' ? 'filled' : 'outline'} size={30}>
{icon}
</ThemeIcon>
) : null}
<Text weight={600} size="md"> <Text weight={600} size="md">
{title} {title}
</Text> </Text>

View File

@@ -1,5 +1,6 @@
import { createStyles, UnstyledButton, Group, Text } from '@mantine/core'; import { createStyles, Group, Text, NavLink } from '@mantine/core';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/router';
import type { Dispatch, SetStateAction } from 'react'; import type { Dispatch, SetStateAction } from 'react';
import { import {
VscSymbolClass, VscSymbolClass,
@@ -69,6 +70,7 @@ const useStyles = createStyles((theme) => ({
link: { link: {
fontWeight: 500, fontWeight: 500,
display: 'block', display: 'block',
width: 'unset',
padding: 5, padding: 5,
paddingLeft: 31, paddingLeft: 31,
marginLeft: 25, marginLeft: 25,
@@ -90,6 +92,7 @@ export function SidebarItems({
members: Members; members: Members;
setOpened: Dispatch<SetStateAction<boolean>>; setOpened: Dispatch<SetStateAction<boolean>>;
}) { }) {
const router = useRouter();
const { classes } = useStyles(); const { classes } = useStyles();
const groupItems = groupMembers(members); const groupItems = groupMembers(members);
@@ -101,18 +104,25 @@ export function SidebarItems({
<Section key={idx} title={group} icon={resolveIcon(group)}> <Section key={idx} title={group} icon={resolveIcon(group)}>
{groupItems[group].map((member, i) => ( {groupItems[group].map((member, i) => (
<Link key={i} href={member.path} passHref> <Link key={i} href={member.path} passHref>
<UnstyledButton className={classes.link} component="a" onClick={() => setOpened((o) => !o)}> <NavLink
<Group> className={classes.link}
<Text sx={{ textOverflow: 'ellipsis', overflow: 'hidden' }} className="line-clamp-1"> component="a"
{member.name} onClick={() => setOpened((o) => !o)}
</Text> label={
{member.overloadIndex && member.overloadIndex > 1 ? ( <Group>
<Text size="xs" color="dimmed"> <Text sx={{ textOverflow: 'ellipsis', overflow: 'hidden' }} className="line-clamp-1">
{member.overloadIndex} {member.name}
</Text> </Text>
) : null} {member.overloadIndex && member.overloadIndex > 1 ? (
</Group> <Text size="xs" color="dimmed">
</UnstyledButton> {member.overloadIndex}
</Text>
) : null}
</Group>
}
active={router.asPath === member.path}
variant="filled"
></NavLink>
</Link> </Link>
))} ))}
</Section> </Section>

View File

@@ -66,9 +66,11 @@ const useStyles = createStyles(
width: '100%', width: '100%',
padding: theme.spacing.xs, padding: theme.spacing.xs,
color: theme.colorScheme === 'dark' ? theme.colors.dark![0] : theme.black, color: theme.colorScheme === 'dark' ? theme.colors.dark![0] : theme.black,
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![6] : theme.colors.gray![1],
borderRadius: theme.radius.xs,
'&:hover': { '&:hover': {
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![6] : theme.colors.gray![0], backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![5] : theme.colors.gray![2],
color: theme.colorScheme === 'dark' ? theme.white : theme.black, color: theme.colorScheme === 'dark' ? theme.white : theme.black,
}, },
}, },
@@ -163,7 +165,7 @@ export function SidebarLayout({
<UnstyledButton className={classes.control}> <UnstyledButton className={classes.control}>
<Group position="apart"> <Group position="apart">
<Group> <Group>
<ThemeIcon size={30}> <ThemeIcon variant={colorScheme === 'dark' ? 'filled' : 'outline'} size={30}>
<VscPackage size={20} /> <VscPackage size={20} />
</ThemeIcon> </ThemeIcon>
<Text weight="600" size="md"> <Text weight="600" size="md">
@@ -187,7 +189,7 @@ export function SidebarLayout({
<UnstyledButton className={classes.control}> <UnstyledButton className={classes.control}>
<Group position="apart"> <Group position="apart">
<Group> <Group>
<ThemeIcon size={30}> <ThemeIcon variant={colorScheme === 'dark' ? 'filled' : 'outline'} size={30}>
<VscVersions size={20} /> <VscVersions size={20} />
</ThemeIcon> </ThemeIcon>
<Text weight="600" size="md"> <Text weight="600" size="md">

View File

@@ -1,4 +1,4 @@
import { createStyles, Group, Text, Box, Stack, ThemeIcon } from '@mantine/core'; import { createStyles, Group, Text, Box, Stack, ThemeIcon, useMantineColorScheme } from '@mantine/core';
import { VscListSelection, VscSymbolMethod, VscSymbolProperty } from 'react-icons/vsc'; import { VscListSelection, VscSymbolMethod, VscSymbolProperty } from 'react-icons/vsc';
import type { ApiClassJSON, ApiInterfaceJSON } from '~/DocModel/ApiNodeJSONEncoder'; import type { ApiClassJSON, ApiInterfaceJSON } from '~/DocModel/ApiNodeJSONEncoder';
@@ -8,7 +8,7 @@ const useStyles = createStyles((theme) => ({
...theme.fn.focusStyles(), ...theme.fn.focusStyles(),
display: 'block', display: 'block',
textDecoration: 'none', textDecoration: 'none',
color: theme.colorScheme === 'dark' ? theme.colors.dark![0] : theme.black, color: theme.colorScheme === 'dark' ? theme.colors.dark![0] : theme.colors.gray![7],
lineHeight: 1.2, lineHeight: 1.2,
fontSize: theme.fontSizes.sm, fontSize: theme.fontSizes.sm,
padding: theme.spacing.xs, padding: theme.spacing.xs,
@@ -17,6 +17,7 @@ const useStyles = createStyles((theme) => ({
borderTopRightRadius: theme.radius.sm, borderTopRightRadius: theme.radius.sm,
borderBottomRightRadius: theme.radius.sm, borderBottomRightRadius: theme.radius.sm,
borderLeft: `1px solid ${theme.colorScheme === 'dark' ? theme.colors.dark![4] : theme.colors.gray![3]}`, borderLeft: `1px solid ${theme.colorScheme === 'dark' ? theme.colors.dark![4] : theme.colors.gray![3]}`,
fontWeight: 500,
'&:hover': { '&:hover': {
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![6] : theme.colors.gray![0], backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![6] : theme.colors.gray![0],
@@ -32,6 +33,7 @@ export function TableOfContentItems({
methods: ApiClassJSON['methods'] | ApiInterfaceJSON['methods']; methods: ApiClassJSON['methods'] | ApiInterfaceJSON['methods'];
properties: ApiClassJSON['properties'] | ApiInterfaceJSON['properties']; properties: ApiClassJSON['properties'] | ApiInterfaceJSON['properties'];
}) { }) {
const { colorScheme } = useMantineColorScheme();
const { classes } = useStyles(); const { classes } = useStyles();
const propertyItems = properties.map((prop) => ( const propertyItems = properties.map((prop) => (
@@ -73,7 +75,7 @@ export function TableOfContentItems({
{propertyItems.length ? ( {propertyItems.length ? (
<Box> <Box>
<Group> <Group>
<ThemeIcon size={30}> <ThemeIcon variant={colorScheme === 'dark' ? 'filled' : 'outline'} size={30}>
<VscSymbolProperty size={20} /> <VscSymbolProperty size={20} />
</ThemeIcon> </ThemeIcon>
<Box p="sm" pl={0}> <Box p="sm" pl={0}>
@@ -88,7 +90,7 @@ export function TableOfContentItems({
{methodItems.length ? ( {methodItems.length ? (
<Box> <Box>
<Group spacing="xs"> <Group spacing="xs">
<ThemeIcon size={30}> <ThemeIcon variant={colorScheme === 'dark' ? 'filled' : 'outline'} size={30}>
<VscSymbolMethod size={20} /> <VscSymbolMethod size={20} />
</ThemeIcon> </ThemeIcon>
<Box p="sm" pl={0}> <Box p="sm" pl={0}>

View File

@@ -1,7 +1,20 @@
import { Container, UnstyledButton, createStyles, Group, ThemeIcon, Text, Stack, Box, Title } from '@mantine/core'; import {
Container,
UnstyledButton,
createStyles,
Group,
ThemeIcon,
Text,
Stack,
Box,
Title,
useMantineColorScheme,
Affix,
} from '@mantine/core';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/router';
import type { GetStaticPaths, GetStaticProps } from 'next/types'; import type { GetStaticPaths, GetStaticProps } from 'next/types';
import { VscArrowRight, VscPackage } from 'react-icons/vsc'; import { VscArrowLeft, VscArrowRight, VscPackage } from 'react-icons/vsc';
interface VersionProps { interface VersionProps {
packageName: string; packageName: string;
@@ -57,6 +70,7 @@ const useStyles = createStyles((theme) => ({
control: { control: {
padding: theme.spacing.xs, padding: theme.spacing.xs,
color: theme.colorScheme === 'dark' ? theme.colors.dark![0] : theme.black, color: theme.colorScheme === 'dark' ? theme.colors.dark![0] : theme.black,
borderRadius: theme.radius.xs,
'&:hover': { '&:hover': {
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![6] : theme.colors.gray![0], backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![6] : theme.colors.gray![0],
@@ -66,7 +80,9 @@ const useStyles = createStyles((theme) => ({
})); }));
export default function VersionsRoute(props: Partial<VersionProps> & { error?: string }) { export default function VersionsRoute(props: Partial<VersionProps> & { error?: string }) {
const router = useRouter();
const { classes } = useStyles(); const { classes } = useStyles();
const { colorScheme } = useMantineColorScheme();
return props.error ? ( return props.error ? (
<Box sx={{ display: 'flex', maxWidth: '100%', height: '100%' }}>{props.error}</Box> <Box sx={{ display: 'flex', maxWidth: '100%', height: '100%' }}>{props.error}</Box>
@@ -81,7 +97,7 @@ export default function VersionsRoute(props: Partial<VersionProps> & { error?: s
<UnstyledButton className={classes.control} component="a"> <UnstyledButton className={classes.control} component="a">
<Group position="apart"> <Group position="apart">
<Group> <Group>
<ThemeIcon size={30}> <ThemeIcon variant={colorScheme === 'dark' ? 'filled' : 'outline'} size={30}>
<VscPackage size={20} /> <VscPackage size={20} />
</ThemeIcon> </ThemeIcon>
<Text weight={600} size="md"> <Text weight={600} size="md">
@@ -94,6 +110,11 @@ export default function VersionsRoute(props: Partial<VersionProps> & { error?: s
</Link> </Link>
)) ?? null} )) ?? null}
</Stack> </Stack>
<Affix position={{ top: 20, left: 20 }}>
<UnstyledButton onClick={() => void router.push('/docs/packages')}>
<VscArrowLeft size={25} />
</UnstyledButton>
</Affix>
</Container> </Container>
); );
} }

View File

@@ -1,4 +1,14 @@
import { Container, UnstyledButton, createStyles, Group, ThemeIcon, Text, Stack, Title } from '@mantine/core'; import {
Container,
UnstyledButton,
createStyles,
Group,
ThemeIcon,
Text,
Stack,
Title,
useMantineColorScheme,
} from '@mantine/core';
import Link from 'next/link'; import Link from 'next/link';
import { VscArrowRight, VscPackage } from 'react-icons/vsc'; import { VscArrowRight, VscPackage } from 'react-icons/vsc';
@@ -6,6 +16,7 @@ const useStyles = createStyles((theme) => ({
control: { control: {
padding: theme.spacing.xs, padding: theme.spacing.xs,
color: theme.colorScheme === 'dark' ? theme.colors.dark![0] : theme.black, color: theme.colorScheme === 'dark' ? theme.colors.dark![0] : theme.black,
borderRadius: theme.radius.xs,
'&:hover': { '&:hover': {
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![6] : theme.colors.gray![0], backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark![6] : theme.colors.gray![0],
@@ -16,6 +27,8 @@ const useStyles = createStyles((theme) => ({
export default function PackagesRoute() { export default function PackagesRoute() {
const { classes } = useStyles(); const { classes } = useStyles();
const { colorScheme } = useMantineColorScheme();
const packages = ['builders', 'collection', 'proxy', 'rest', 'voice', 'ws']; const packages = ['builders', 'collection', 'proxy', 'rest', 'voice', 'ws'];
return ( return (
@@ -29,7 +42,7 @@ export default function PackagesRoute() {
<UnstyledButton className={classes.control} component="a"> <UnstyledButton className={classes.control} component="a">
<Group position="apart"> <Group position="apart">
<Group> <Group>
<ThemeIcon size={30}> <ThemeIcon variant={colorScheme === 'dark' ? 'filled' : 'outline'} size={30}>
<VscPackage size={20} /> <VscPackage size={20} />
</ThemeIcon> </ThemeIcon>
<Text weight={600} size="md"> <Text weight={600} size="md">