diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 4e314bd7..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "next", - "next/core-web-vitals", - "plugin:jsx-a11y/strict", - "prettier", - "plugin:tailwindcss/recommended" - ], - "plugins": [ - "prettier" - ] -} diff --git a/.prettierrc b/.prettierrc index d7650e67..6a5a6676 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,5 @@ { "singleQuote": true, "trailingComma": "none", - "plugins": ["prettier-plugin-tailwindcss"], - "tailwindConfig": "./tailwind.config.js" + "plugins": ["prettier-plugin-tailwindcss"] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 9e26dfee..4988eb6e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1 +1,5 @@ -{} \ No newline at end of file +{ + "files.associations": { + "*.css": "tailwindcss" + } +} diff --git a/README.md b/README.md index b1b2b648..8a88a45e 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,3 @@ install node, it is recommended to follow the guide provided by Node.js For comprehensive guidelines on writing documentation, including how to use custom nodes and tags, please refer to the [Writing Documentation](/WRITING_DOCS.md) page. - -## Generating a PDF - -This repository provides a tool for generating a PDFs from the documentation using [puppeteer](https://pptr.dev). -To run the tool, use the following commands: - -```bash -cd tools/pdf -npm install -npm run generate-pdf -``` diff --git a/app/[...slug]/layout.tsx b/app/[...slug]/layout.tsx index 4d791997..43a80ce4 100644 --- a/app/[...slug]/layout.tsx +++ b/app/[...slug]/layout.tsx @@ -1,8 +1,16 @@ // Copyright (c) ZeroC, Inc. import { PathProvider } from 'context/state'; +import { ReactNode } from 'react'; -export default function DocsLayout(props: any) { - const path = '/' + (props.params.slug?.join('/') ?? ''); +interface DocsLayoutProps { + children: ReactNode; + params: Promise<{ + slug?: string[]; + }>; +} + +export default async function DocsLayout(props: DocsLayoutProps) { + const path = '/' + ((await props.params).slug?.join('/') ?? ''); return {props.children}; } diff --git a/app/[...slug]/page.tsx b/app/[...slug]/page.tsx index 79182249..f807bbd8 100644 --- a/app/[...slug]/page.tsx +++ b/app/[...slug]/page.tsx @@ -20,9 +20,8 @@ type PageProps = { params: Params; }; -export async function generateMetadata({ - params -}: PageProps): Promise { +export async function generateMetadata(props: PageProps): Promise { + const params = await props.params; const path = '/' + (params.slug.join('/') ?? ''); const { frontmatter } = await getMarkdownContent(path); const title: string = frontmatter?.title ?? ''; @@ -38,8 +37,9 @@ export async function generateMetadata({ title, description, images: { - url: `https://docs.icerpc.dev/api/og?title=${baseUrls.includes(path) ? 'Overview' : title - }&description=${description}&path=${encodeURIComponent(path)}` + url: `https://docs.icerpc.dev/api/og?title=${ + baseUrls.includes(path) ? 'Overview' : title + }&description=${description}&path=${encodeURIComponent(path)}` } } }; @@ -90,7 +90,8 @@ export async function generateStaticParams() { })); } -export default async function Page({ params }: PageProps) { +export default async function Page(props: PageProps) { + const params = await props.params; const path = '/' + (params.slug.join('/') ?? ''); const { content } = await getMarkdownContent(path); @@ -104,7 +105,7 @@ export default async function Page({ params }: PageProps) { return (
-
+
diff --git a/app/api/og/route.tsx b/app/api/og/route.tsx index a32d123e..788affd8 100644 --- a/app/api/og/route.tsx +++ b/app/api/og/route.tsx @@ -28,8 +28,8 @@ export async function GET(request: NextRequest) { : pageImage(hostname, breadcrumbs, title, description); return image; - } catch (e: any) { - console.log(`${e.message}`); + } catch (e) { + console.log(`${e instanceof Error ? e.message : 'Unknown error'}`); return new NextResponse(`Failed to generate the image`, { status: 500 }); @@ -39,20 +39,18 @@ export async function GET(request: NextRequest) { // Image rendering functions const homeImage = (hostname: string | null) => { return new ImageResponse( - ( -
- ), +
, { width: 1200, height: 630 @@ -67,68 +65,65 @@ const pageImage = ( description: string | undefined ) => { return new ImageResponse( - ( +
-
-
    - {renderBreadcrumb(breadcrumbs)} -
-

- {title} -

-

- {description} -

-
+ {renderBreadcrumb(breadcrumbs)} + +

+ {title} +

+

+ {description} +

- ), +
, { - // @ts-ignore - The FontOptions type cannot be imported width: 1200, height: 630 } diff --git a/app/globals.css b/app/globals.css index 8e54c751..0a7b5abe 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,20 +1,108 @@ /* Copyright (c) ZeroC, Inc. */ -@tailwind base; -@tailwind components; -@tailwind utilities; - -:root { - --link-color: rgba(75, 85, 99, 1); - --highlighted-link-color: black; - --text-color: rgba(75, 85, 99, 1); - --text-color-secondary: #3d4356; - --docsearch-searchbox-height: 48px !important; - --docsearch-primary-color: #43a0f7 !important; +@import 'tailwindcss'; + +@plugin 'tailwindcss-animate'; +@plugin '@tailwindcss/typography'; +@plugin 'flowbite/plugin'; + +@custom-variant dark (&:where(.dark, .dark *)); + +@utility container { + margin-inline: auto; + padding-inline: 2rem; + @media (width >= --theme(--breakpoint-sm)) { + max-width: none; + } + @media (width >= 1400px) { + max-width: 1400px; + } } +@theme { + --color-primary: rgb(var(--primary-color)); + --color-light-border: #dce6e9; + --color-dark: rgb(26, 28, 33); + --color-dark-accent: rgb(35, 36, 41); + --color-dark-border: rgb(46, 46, 46); + + --breakpoint-5xl: 64rem; + + --background-image-dark-pattern: linear-gradient( + to right, + #000 0%, + #000 10%, + #010409 50%, + rgb(14, 17, 22) 75%, + rgb(14, 17, 22) 100% + ); + --background-image-og-image: url('/images/og.png'); + + --animate-accordion-down: accordion-down 0.2s ease-out; + --animate-accordion-up: accordion-up 0.2s ease-out; + --animate-fade-in-up: fade-in-up 0.5s ease-out; + + @keyframes fade-in-up { + 0% { + opacity: 0; + transform: translateY(10px); + } + 100% { + opacity: 1; + transform: translateY(0); + } + } + @keyframes accordion-down { + from { + height: 0; + } + to { + height: var(--radix-accordion-content-height); + } + } + @keyframes accordion-up { + from { + height: var(--radix-accordion-content-height); + } + to { + height: 0; + } + } +} + +@layer utilities { + :root { + --link-color: rgba(75, 85, 99, 1); + --highlighted-link-color: black; + --text-color: rgba(75, 85, 99, 1); + --text-color-secondary: #3d4356; + --docsearch-searchbox-height: 48px !important; + --docsearch-primary-color: #43a0f7 !important; + } +} @layer base { + /* + The default border color has changed to `currentcolor` in Tailwind CSS v4, + so we've added these compatibility styles to make sure everything still + looks the same as it did with Tailwind CSS v3. + + If we ever want to remove these styles, we need to add an explicit border + color utility to any element that depends on these defaults. + */ + *, + ::after, + ::before, + ::backdrop, + ::file-selector-button { + border-color: var(--color-gray-200, currentcolor); + } + + *, + *::before, + *::after { + box-sizing: border-box; + } :root { --primary-color: 67 160 247; @@ -24,9 +112,60 @@ --primary-color: 67 160 247; } + html { + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + + .DocSearch-Input:focus { + /* Disable the docsearch input ring */ + outline: none !important; + appearance: none !important; + box-shadow: var(--tw-ring-inset) 0 0 0 + calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + } + + body { + font-family: + Inter, + system-ui, + -apple-system, + Inter, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + 'Helvetica Neue', + Arial, + 'Noto Sans', + sans-serif, + 'Apple Color Emoji', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji'; + color: rgba(60, 66, 87, 1); + } + + h1 { + font-size: 52px; + color: #333333; + font-style: bold; + margin-top: 0; + } + + h3 { + margin: 1.5em 0; + color: #000000; + font-weight: bold; + font-size: large; + } + + a { + color: rgba(75, 85, 99, 1); + } + main article { - @apply prose max-w-none dark:prose-invert prose-a:no-underline prose-code:font-light - prose-code:text-[var(--tw-prose-body)] prose-code:before:hidden prose-code:after:hidden; + @apply prose dark:prose-invert prose-a:no-underline prose-code:font-light prose-code:text-(--tw-prose-body) prose-code:before:hidden prose-code:after:hidden max-w-none; } main article li { @@ -38,7 +177,7 @@ } main article .callout a { - @apply font-semibold !underline; + @apply underline! font-semibold; } li { @@ -46,7 +185,7 @@ } body { - @apply bg-white dark:bg-dark; + @apply dark:bg-dark bg-white; } h2 { @@ -58,72 +197,14 @@ } code { - @apply break-all rounded border-[1px] bg-slate-100 px-[4px] py-[2px] font-mono shadow-[inset_0px_0px_0px_1px_var(--tw-prose-code-ring)] dark:border-darkBorder dark:bg-transparent dark:text-white md:break-normal; + @apply dark:border-dark-border break-all rounded-sm border bg-slate-100 px-1 py-0.5 font-mono shadow-[inset_0px_0px_0px_1px_var(--tw-prose-code-ring)] md:break-normal dark:bg-transparent dark:text-white; } a code { - @apply rounded border-[1px] bg-slate-100 px-[4px] py-[2px] font-mono font-medium text-primary shadow-[inset_0px_0px_0px_1px_var(--tw-prose-code-ring)] hover:text-[rgb(64,131,193)] dark:border-darkBorder dark:bg-transparent dark:text-primary dark:hover:text-[rgb(64,131,193)]; + @apply text-primary dark:border-dark-border dark:text-primary rounded-sm border bg-slate-100 px-1 py-0.5 font-mono font-medium shadow-[inset_0px_0px_0px_1px_var(--tw-prose-code-ring)] hover:text-[rgb(64,131,193)] dark:bg-transparent dark:hover:text-[rgb(64,131,193)]; } } -*, -*::before, -*::after { - box-sizing: border-box; -} - -html { - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.DocSearch-Input:focus { - /* Diable the docsearch input ring */ - outline: none !important; - appearance: none !important; - box-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) - var(--tw-ring-color); -} - -body { - font-family: - Inter, - system-ui, - -apple-system, - Inter, - BlinkMacSystemFont, - 'Segoe UI', - Roboto, - 'Helvetica Neue', - Arial, - 'Noto Sans', - sans-serif, - 'Apple Color Emoji', - 'Segoe UI Emoji', - 'Segoe UI Symbol', - 'Noto Color Emoji'; - color: rgba(60, 66, 87, 1); -} - -h1 { - font-size: 52px; - color: #333333; - font-style: bold; - margin-top: 0; -} - -h3 { - margin: 1.5em 0; - color: #000000; - font-weight: bold; - font-size: large; -} - -a { - color: rgba(75, 85, 99, 1); -} - [data-testid='flowbite-tooltip-arrow'] { display: none !important; } diff --git a/app/hero.tsx b/app/hero.tsx index 724d4af9..70967083 100644 --- a/app/hero.tsx +++ b/app/hero.tsx @@ -6,10 +6,10 @@ import Link from 'next/link'; export const Hero = () => { return ( -
+
-
+
IceRPC Logo { priority={true} fill /> -
-
+
+
-

+

IceRPC

-

+

Documentation

-

+

IceRPC is a new open-source RPC framework that helps you build blazing fast networked applications with very little code.

-
+
Start with a tutorial @@ -43,7 +43,7 @@ export const Hero = () => { or View examples diff --git a/app/layout.tsx b/app/layout.tsx index 9102ce3c..c3854ab5 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -56,25 +56,26 @@ export const metadata: Metadata = { metadataBase: new URL('https://docs.icerpc.dev'), other: { 'application/ld+json': JSON.stringify({ - "@context": "https://schema.org", - "@type": "TechArticle", - "headline": "IceRPC Documentation", - "description": "Comprehensive guide to using IceRPC, including setup, usage, and advanced features.", - "mainEntityOfPage": "https://docs.icerpc.dev", - "author": { - "@type": "Organization", - "name": "IceRPC Team" + '@context': 'https://schema.org', + '@type': 'TechArticle', + headline: 'IceRPC Documentation', + description: + 'Comprehensive guide to using IceRPC, including setup, usage, and advanced features.', + mainEntityOfPage: 'https://docs.icerpc.dev', + author: { + '@type': 'Organization', + name: 'IceRPC Team' }, - "publisher": { - "@type": "Organization", - "name": "IceRPC", - "logo": { - "@type": "ImageObject", - "url": "https://docs.icerpc.dev/icerpc-logo.svg" + publisher: { + '@type': 'Organization', + name: 'IceRPC', + logo: { + '@type': 'ImageObject', + url: 'https://docs.icerpc.dev/icerpc-logo.svg' } - }, - }), - }, + } + }) + } }; const organizationSchema = { @@ -146,7 +147,11 @@ const navigationSchema = { ] }; -export default function RootLayout(props: any) { +interface RootLayoutProps { + children: React.ReactNode; +} + +export default function RootLayout(props: RootLayoutProps) { return ( diff --git a/app/not-found.tsx b/app/not-found.tsx index 2bbad270..f369c915 100644 --- a/app/not-found.tsx +++ b/app/not-found.tsx @@ -4,7 +4,7 @@ export default function NotFound() { return (
-

+

404

diff --git a/app/page.tsx b/app/page.tsx index 14cd042f..f0c6c3f8 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -10,12 +10,12 @@ import { License } from '@/components/tags/license'; export default async function Home() { return ( -
-
+
+
-
+

Welcome to the IceRPC documentation! You will find on this site a diff --git a/components/analytics/analytics.tsx b/components/analytics/analytics.tsx index a6867571..82ec3ab7 100644 --- a/components/analytics/analytics.tsx +++ b/components/analytics/analytics.tsx @@ -26,13 +26,13 @@ export function Analytics() { setEnableAnalytics(cookieValue === 'true' ? true : false); }, [cookieValue]); - const handleSetCookieSettings = (value: boolean) => { + const handleSetCookieSettings = async (value: boolean) => { setShowCookieButton(false); setShowBanner(false); setEnableAnalytics(value === true); // Safari workaround to keep the cookie stored for more than 7 days - fetch(`api/cookies?allow-cookies=${encodeURIComponent(value)}`); + await fetch(`api/cookies?allow-cookies=${encodeURIComponent(value)}`); }; const toggleShowBanner = () => setShowBanner(!showBanner); diff --git a/components/analytics/banner.tsx b/components/analytics/banner.tsx index dab5eea7..cb0cb925 100644 --- a/components/analytics/banner.tsx +++ b/components/analytics/banner.tsx @@ -1,11 +1,11 @@ // Copyright (c) ZeroC, Inc. -import { motion } from 'framer-motion'; +import { motion, Variants } from 'framer-motion'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faXmarkCircle } from '@fortawesome/free-solid-svg-icons'; // Constants -const bannerVariants = { +const bannerVariants: Variants = { hidden: { opacity: 0, scale: 0.5, y: 50 }, visible: { opacity: 1, @@ -36,7 +36,7 @@ export const Banner = ({ }: BannerProps) => (

-

+

This website uses cookies to analyze traffic and improve your experience.
-
+
By clicking "Accept," you consent to the use of these cookies. You can learn more about our cookies policy in our{' '} - + Privacy Policy .
-

+
@@ -80,7 +83,7 @@ export const Banner = ({ No thanks