style: Import React in multiple components
This commit is contained in:
parent
bf9c64da68
commit
bc4729a5de
@ -1,3 +1,4 @@
|
|||||||
|
import React from "react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
export function Prose<T extends React.ElementType = "div">({
|
export function Prose<T extends React.ElementType = "div">({
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Link } from "@/components/common/Link";
|
import { Link } from "@/components/common/Link";
|
||||||
import { Icon } from "@syntax/Icon";
|
import { Icon } from "@syntax/Icon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
export function QuickLinks({ children }: { children: React.ReactNode }) {
|
export function QuickLinks({ children }: { children: React.ReactNode }) {
|
||||||
return <div className="not-prose my-12 grid grid-cols-1 gap-6 sm:grid-cols-2">{children}</div>;
|
return <div className="not-prose my-12 grid grid-cols-1 gap-6 sm:grid-cols-2">{children}</div>;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Highlight, Prism } from "prism-react-renderer";
|
import { Highlight, Prism } from "prism-react-renderer";
|
||||||
import { prismThemes } from "@/data/themes/prism";
|
import { prismThemes } from "@/data/themes/prism";
|
||||||
|
import React, { Fragment, useMemo } from "react";
|
||||||
import { useTheme } from "@/hooks/useTheme";
|
import { useTheme } from "@/hooks/useTheme";
|
||||||
import { Fragment, useMemo } from "react";
|
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
export function SSRSnippet({
|
export function SSRSnippet({
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useId, useState, useEffect, createContext, useContext, Fragment } from "react";
|
import React, { useId, useState, useEffect, createContext, useContext, Fragment } from "react";
|
||||||
import { SearchResult } from "@/services/FlexSearchService";
|
import { SearchResult } from "@/services/FlexSearchService";
|
||||||
import { Dialog, DialogPanel } from "@headlessui/react";
|
import { Dialog, DialogPanel } from "@headlessui/react";
|
||||||
import { useDebounce } from "@/hooks/useDebounce";
|
import { useDebounce } from "@/hooks/useDebounce";
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import type { Data } from "@/pages/docs/+data";
|
|||||||
import { clientOnly } from "vike-react/clientOnly";
|
import { clientOnly } from "vike-react/clientOnly";
|
||||||
import { useData } from "vike-react/useData";
|
import { useData } from "vike-react/useData";
|
||||||
import { SSRSnippet } from "./SSRSnippet";
|
import { SSRSnippet } from "./SSRSnippet";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
const CSRSnippet = clientOnly(() => import("./CSRSnippet"));
|
const CSRSnippet = clientOnly(() => import("./CSRSnippet"));
|
||||||
|
|
||||||
|
|||||||
@ -1,25 +1,23 @@
|
|||||||
"use client";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import { useCallback, useEffect, useState } from "react";
|
|
||||||
import { Link } from "@/components/common/Link";
|
import { Link } from "@/components/common/Link";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
import { type Section, type Subsection } from "@/lib/sections";
|
import { type Section, type Subsection } from "@/lib/sections";
|
||||||
|
|
||||||
export function TableOfContents({ tableOfContents }: { tableOfContents: Array<Section> }) {
|
export function TableOfContents({ tableOfContents }: { tableOfContents: Array<Section> }) {
|
||||||
let [currentSection, setCurrentSection] = useState(tableOfContents[0]?.id);
|
const [currentSection, setCurrentSection] = useState(tableOfContents[0]?.id);
|
||||||
|
|
||||||
let getHeadings = useCallback((tableOfContents: Array<Section>) => {
|
const getHeadings = useCallback((tableOfContents: Array<Section>) => {
|
||||||
return tableOfContents
|
return tableOfContents
|
||||||
.flatMap((node) => [node.id, ...node.children.map((child) => child.id)])
|
.flatMap((node) => [node.id, ...node.children.map((child) => child.id)])
|
||||||
.map((id) => {
|
.map((id) => {
|
||||||
let el = document.getElementById(id);
|
const el = document.getElementById(id);
|
||||||
if (!el) return null;
|
if (!el) return null;
|
||||||
|
|
||||||
let style = window.getComputedStyle(el);
|
const style = window.getComputedStyle(el);
|
||||||
let scrollMt = parseFloat(style.scrollMarginTop);
|
const scrollMt = parseFloat(style.scrollMarginTop);
|
||||||
|
|
||||||
let top = window.scrollY + el.getBoundingClientRect().top - scrollMt;
|
const top = window.scrollY + el.getBoundingClientRect().top - scrollMt;
|
||||||
return { id, top };
|
return { id, top };
|
||||||
})
|
})
|
||||||
.filter((x): x is { id: string; top: number } => x !== null);
|
.filter((x): x is { id: string; top: number } => x !== null);
|
||||||
@ -35,11 +33,8 @@ export function TableOfContents({ tableOfContents }: { tableOfContents: Array<Se
|
|||||||
let current = headings[0]?.id;
|
let current = headings[0]?.id;
|
||||||
|
|
||||||
for (const heading of headings) {
|
for (const heading of headings) {
|
||||||
if (top >= heading.top - 10) {
|
if (top < heading.top - 10) break;
|
||||||
current = heading.id;
|
current = heading.id;
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setCurrentSection(current);
|
setCurrentSection(current);
|
||||||
}
|
}
|
||||||
@ -51,12 +46,9 @@ export function TableOfContents({ tableOfContents }: { tableOfContents: Array<Se
|
|||||||
}, [getHeadings, tableOfContents]);
|
}, [getHeadings, tableOfContents]);
|
||||||
|
|
||||||
function isActive(section: Section | Subsection) {
|
function isActive(section: Section | Subsection) {
|
||||||
if (section.id === currentSection) {
|
if (section.id === currentSection) return true;
|
||||||
return true;
|
if (!section.children) return false;
|
||||||
}
|
|
||||||
if (!section.children) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return section.children.findIndex(isActive) > -1;
|
return section.children.findIndex(isActive) > -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Label, Listbox, ListboxButton, ListboxOption, ListboxOptions } from "@headlessui/react";
|
import { Label, Listbox, ListboxButton, ListboxOption, ListboxOptions } from "@headlessui/react";
|
||||||
import { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useTheme } from "@/hooks/useTheme";
|
import { useTheme } from "@/hooks/useTheme";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
@ -33,8 +33,8 @@ function DarkIcon(props: React.ComponentPropsWithoutRef<"svg">) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ThemeSelector(props: React.ComponentPropsWithoutRef<typeof Listbox<"div">>) {
|
export function ThemeSelector(props: React.ComponentPropsWithoutRef<typeof Listbox<"div">>) {
|
||||||
let [mounted, setMounted] = useState(false);
|
const [mounted, setMounted] = useState(false);
|
||||||
let { theme, setTheme } = useTheme();
|
const { theme, setTheme } = useTheme();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMounted(true);
|
setMounted(true);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
export function InstallationIcon({
|
export function InstallationIcon({
|
||||||
id,
|
id,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
export function LightbulbIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
export function LightbulbIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
export function PluginsIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
export function PluginsIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
export function PresetsIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
export function PresetsIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
export function QuestionIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
export function QuestionIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
export function ThemingIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
export function ThemingIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
import { DarkMode, Gradient, LightMode } from "@syntax/Icon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
export function WarningIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
export function WarningIcon({ id, color }: { id: string; color?: React.ComponentProps<typeof Gradient>["color"] }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -3,10 +3,10 @@ import { usePageContext } from "vike-react/usePageContext";
|
|||||||
import { ThemeProvider } from "@/providers/ThemeProvider";
|
import { ThemeProvider } from "@/providers/ThemeProvider";
|
||||||
import { ThemeSelector } from "@syntax/ThemeSelector";
|
import { ThemeSelector } from "@syntax/ThemeSelector";
|
||||||
import { clientOnly } from "vike-react/clientOnly";
|
import { clientOnly } from "vike-react/clientOnly";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
import { ToastContainer } from "react-toastify";
|
import { ToastContainer } from "react-toastify";
|
||||||
import { Navigation } from "@syntax/Navigation";
|
import { Navigation } from "@syntax/Navigation";
|
||||||
import { Link } from "@/components/common/Link";
|
import { Link } from "@/components/common/Link";
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { Hero } from "@syntax/Hero";
|
import { Hero } from "@syntax/Hero";
|
||||||
import { Logo } from "@syntax/Logo";
|
import { Logo } from "@syntax/Logo";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|||||||
@ -119,16 +119,17 @@ export const navigation: NavigationSection[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export function doesLinkSubitemExist(link: NavigationLink, subitemHref: string): boolean {
|
||||||
|
return link.subitems.some((subitem) => subitem.href === subitemHref);
|
||||||
|
}
|
||||||
|
|
||||||
export function findNavigationLink(namespace: string, href: string): NavigationLink | undefined {
|
export function findNavigationLink(namespace: string, href: string): NavigationLink | undefined {
|
||||||
const currentUrl = `/${namespace}/${href}`.replace(/\/+/g, "/").replace(/\/$/, "");
|
const currentUrl = `/${namespace}/${href}`.replace(/\/+/g, "/").replace(/\/$/, "");
|
||||||
|
|
||||||
const foundLink = navigation
|
const foundLink = navigation
|
||||||
.flatMap((section) => section.links)
|
.flatMap((section) => section.links)
|
||||||
.find((link) => {
|
.find((link) => {
|
||||||
link.href === currentUrl ||
|
return link.href === currentUrl || doesLinkSubitemExist(link, currentUrl);
|
||||||
link.subitems.some((subitem) => {
|
|
||||||
subitem.href === currentUrl;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return foundLink;
|
return foundLink;
|
||||||
|
|||||||
@ -50,8 +50,8 @@ function extractSections(node: Node, sections: Section[], isRoot: boolean = true
|
|||||||
if (node.type === "heading" || node.type === "paragraph") {
|
if (node.type === "heading" || node.type === "paragraph") {
|
||||||
const content = toString(node).trim();
|
const content = toString(node).trim();
|
||||||
|
|
||||||
if (node.type === "heading" && node.attributes?.level! <= 2) {
|
if (node.attributes?.level && node.type === "heading" && node.attributes.level <= 2) {
|
||||||
let hash = node.attributes?.id ?? slugify(content);
|
const hash = node.attributes?.id ?? slugify(content);
|
||||||
sections.push({ content, hash, subsections: [] });
|
sections.push({ content, hash, subsections: [] });
|
||||||
} else {
|
} else {
|
||||||
sections[sections.length - 1].subsections.push(content);
|
sections[sections.length - 1].subsections.push(content);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user