From c7f06ec9e64d45ae6529b362020aed159e8f1502 Mon Sep 17 00:00:00 2001 From: syfxlin Date: Sun, 28 Jan 2024 23:17:00 +0800 Subject: [PATCH] feature(toc): Move the TOC closer to the content to improve usability --- src/components/templates/template/index.tsx | 8 +++- src/components/ui/link/index.tsx | 46 ++++++++++----------- src/components/widgets/toc/index.tsx | 6 +-- src/components/widgets/toc/styles.css.ts | 31 ++++++-------- 4 files changed, 42 insertions(+), 49 deletions(-) diff --git a/src/components/templates/template/index.tsx b/src/components/templates/template/index.tsx index db0a4b61..8412d157 100644 --- a/src/components/templates/template/index.tsx +++ b/src/components/templates/template/index.tsx @@ -35,9 +35,13 @@ export const Template: React.FC = async (props) => {
{props.before} {props.desc} -
{props.children}
+
+ {props.headings && } +
+ {props.children} +
+
{props.after} - {props.headings && } {(props.pagination?.prev || props.pagination?.next) && ( )} diff --git a/src/components/ui/link/index.tsx b/src/components/ui/link/index.tsx index 2266e8e7..e83422f2 100644 --- a/src/components/ui/link/index.tsx +++ b/src/components/ui/link/index.tsx @@ -1,5 +1,5 @@ "use client"; -import React, { AnchorHTMLAttributes, forwardRef } from "react"; +import React, { AnchorHTMLAttributes, ReactElement, forwardRef } from "react"; import Tippy, { TippyProps } from "@tippyjs/react"; import NLink, { LinkProps as NLinkProps } from "next/link"; import { cx } from "@syfxlin/reve"; @@ -11,29 +11,25 @@ export type LinkProps = AnchorHTMLAttributes & NLinkProps & { }; export const Link = forwardRef(({ tooltip, unstyled, href, ...props }, ref) => { - if (typeof href === "string" && /^(https?:)?\/\/|^#|\.[\da-z]+$/i.test(href)) { - const element = ; - return tooltip ? - ( - - {element} - - ) : - ( - element - ); - } else { - const element = ( - - ); - return tooltip ? - ( - - {element} - - ) : - ( - element - ); + let element: ReactElement | undefined; + if (typeof href === "string") { + if (/^(https?:)?\/\/|\.[\da-z]+$/i.test(href)) { + element = ; + } + if (/^#/i.test(href)) { + element = ; + } } + if (!element) { + element = ; + } + return tooltip ? + ( + + {element} + + ) : + ( + element + ); }); diff --git a/src/components/widgets/toc/index.tsx b/src/components/widgets/toc/index.tsx index 9250104b..a6fce6d1 100644 --- a/src/components/widgets/toc/index.tsx +++ b/src/components/widgets/toc/index.tsx @@ -1,10 +1,9 @@ "use client"; import React, { useState } from "react"; import { cx } from "@syfxlin/reve"; +import { TocData } from "@syfxlin/reks"; import { useIntersectionObserver } from "../../../hooks/use-intersection-observer"; -import { TocData } from "../../../contents/types"; import { Link } from "../../ui/link"; -import { Iconify } from "../../ui/iconify/client"; import * as styles from "./styles.css"; export interface TocProps { @@ -21,7 +20,7 @@ const Item: React.FC = ({ data, active }) => { {data.map(i => (
  • - {i.name} + - {i.name} {i.children && }
  • @@ -37,7 +36,6 @@ export const Toc: React.FC = ({ data }) => { return ( ); diff --git a/src/components/widgets/toc/styles.css.ts b/src/components/widgets/toc/styles.css.ts index d9e2f0fb..6b4f7584 100644 --- a/src/components/widgets/toc/styles.css.ts +++ b/src/components/widgets/toc/styles.css.ts @@ -3,34 +3,31 @@ import { theme } from "../../../theme/theme.css"; import { iconify } from "../../ui/iconify/query"; export const container = styled.css` - position: fixed; - top: 80px; - left: ${theme.fontSize.calc(1)}; + position: absolute; + top: 0; + right: ${theme.fontSize.calc(-1)}; padding: ${theme.spacing.calc(1)}; width: ${theme.fontSize.calc(18)}; - height: calc(100vh - 160px); + height: 100%; + transform: translateX(100%); @media screen and (max-width: ${theme.fontSize.calc(36 + 45)}) { display: none; } > ul { + position: sticky; + top: 40px; margin: 0; padding: 0; - height: 100%; - overflow-y: auto; - opacity: 0; - transition: opacity 0.6s; - } - - > span { opacity: 0.5; + overflow-y: auto; + overflow-x: hidden; transition: opacity 0.6s; } &:hover { - > ul, - > span { + > ul { opacity: 1; } } @@ -63,16 +60,14 @@ export const item = styled.css` font-size: ${theme.fontSize.calc(0.9)}; margin: 0 ${theme.spacing.calc(2.5)}; color: ${theme.color.text.description}; - transition: - color 0.3s, - border 0.3s; + border: none; + transition: color 0.3s; &.active, &:hover, &:focus, &:active { - color: ${theme.color.text.paragraph}; - border-bottom-color: ${theme.color.text.paragraph}; + color: ${theme.color.text.primary}; } } `;