From 7c83d3b37e8a060b34e31055cc8bc3d75d8190a2 Mon Sep 17 00:00:00 2001 From: GauthierWebDev Date: Sun, 13 Apr 2025 14:40:42 +0200 Subject: [PATCH] feat: Update Button component with size prop --- app/components/syntax/Button.tsx | 15 ++++++--- app/components/syntax/CSRFence.tsx | 52 ++++++++++++++++++++++++++++++ app/components/syntax/Fence.tsx | 21 +++++++++--- app/fastify-entry.ts | 4 +++ app/layouts/prism.css | 8 +++++ app/package.json | 6 +++- app/pnpm-lock.yaml | 51 +++++++++++++++++++++++++++++ app/vite.config.ts | 4 +++ 8 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 app/components/syntax/CSRFence.tsx diff --git a/app/components/syntax/Button.tsx b/app/components/syntax/Button.tsx index 5d326cc..fb0a7f2 100644 --- a/app/components/syntax/Button.tsx +++ b/app/components/syntax/Button.tsx @@ -3,17 +3,24 @@ import clsx from "clsx"; const variantStyles = { primary: - "rounded-full bg-violet-300 py-2 px-4 text-sm font-semibold text-slate-900 hover:bg-violet-200 focus:outline-hidden focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-violet-300/50 active:bg-violet-500", + "bg-violet-300 font-semibold text-slate-900 hover:bg-violet-200 focus:outline-hidden focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-violet-300/50 active:bg-violet-500", secondary: - "rounded-full bg-slate-800 py-2 px-4 text-sm font-medium text-white hover:bg-slate-700 focus:outline-hidden focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white/50 active:text-slate-400", + "bg-slate-800 font-medium text-white hover:bg-slate-700 focus:outline-hidden focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white/50 active:text-slate-400", +}; + +const sizeStyles = { + sm: "rounded-md py-1 px-2 text-xs", + md: "rounded-full py-2 px-4 text-sm", + lg: "rounded-full py-3 px-6 text-base", }; type ButtonProps = { variant?: keyof typeof variantStyles; + size?: keyof typeof sizeStyles; } & (React.ComponentPropsWithoutRef | (React.ComponentPropsWithoutRef<"button"> & { href?: undefined })); -export function Button({ variant = "primary", className, ...props }: ButtonProps) { - className = clsx(variantStyles[variant], "cursor-pointer", className); +export function Button({ variant = "primary", size = "md", className, ...props }: ButtonProps) { + className = clsx(variantStyles[variant], sizeStyles[size], "cursor-pointer", className); return typeof props.href === "undefined" ? ( + + ); +} diff --git a/app/components/syntax/Fence.tsx b/app/components/syntax/Fence.tsx index 61a4b38..0f270f2 100644 --- a/app/components/syntax/Fence.tsx +++ b/app/components/syntax/Fence.tsx @@ -1,17 +1,20 @@ +import { Highlight, Prism } from "prism-react-renderer"; import { prismThemes } from "@/data/themes/prism"; -import { Highlight } from "prism-react-renderer"; import { useTheme } from "@/hooks/useTheme"; import { Fragment, useMemo } from "react"; -export function Fence({ children, language }: { children: string; language: string }) { - const { theme } = useTheme(); +import { clientOnly } from "vike-react/clientOnly"; +const CSRFence = clientOnly(() => import("./CSRFence")); + +function SSRFence({ children, language }: { children: string; language: string }) { + const { theme } = useTheme(); const prismTheme = useMemo(() => { return prismThemes[theme]; }, [theme]); return ( - + {({ className, style, tokens, getTokenProps }) => (
           
@@ -31,3 +34,13 @@ export function Fence({ children, language }: { children: string; language: stri
     
   );
 }
+
+export function Fence({ children, language }: { children: string; language: string }) {
+  return (
+    
+ }> + {children} + +
+ ); +} diff --git a/app/fastify-entry.ts b/app/fastify-entry.ts index 1bf2846..6aad9ab 100644 --- a/app/fastify-entry.ts +++ b/app/fastify-entry.ts @@ -5,6 +5,10 @@ import { fileURLToPath } from "node:url"; import { dirname } from "node:path"; import Fastify from "fastify"; +import { Prism } from "prism-react-renderer"; +(typeof global !== "undefined" ? global : window).Prism = Prism; +require("prismjs/components/prism-bash"); + const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); diff --git a/app/layouts/prism.css b/app/layouts/prism.css index afd7e5d..0b4c69a 100644 --- a/app/layouts/prism.css +++ b/app/layouts/prism.css @@ -45,3 +45,11 @@ pre[class*="language-"] { .token.combinator { color: var(--color-slate-400); } + +.prism-code { + margin: 0; +} + +.prism-code + .prism-code { + margin-bottom: 1rem; +} diff --git a/app/package.json b/app/package.json index 7867145..bbaa12e 100644 --- a/app/package.json +++ b/app/package.json @@ -27,21 +27,25 @@ "js-yaml": "^4.1.0", "npm-run-all": "^4.1.5", "prism-react-renderer": "^2.4.1", + "prismjs": "^1.30.0", "react": "^19.0.0", "react-dom": "^19.0.0", "react-highlight-words": "^0.21.0", + "react-toastify": "^11.0.5", "reading-time-estimator": "^1.12.0", "simple-functional-loader": "^1.2.1", "telefunc": "^0.1.87", "unplugin-fonts": "^1.3.1", "vike": "^0.4.224", - "vike-react": "^0.5.13" + "vike-react": "^0.5.13", + "vite-plugin-prismjs": "^0.0.11" }, "devDependencies": { "@eslint/js": "^9.22.0", "@tailwindcss/vite": "^4.0.12", "@types/js-yaml": "^4.0.9", "@types/node": "^18.19.76", + "@types/prismjs": "^1.26.5", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", "@types/react-highlight-words": "^0.20.0", diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml index 6821b0e..cb89e61 100644 --- a/app/pnpm-lock.yaml +++ b/app/pnpm-lock.yaml @@ -68,6 +68,9 @@ importers: prism-react-renderer: specifier: ^2.4.1 version: 2.4.1(react@19.1.0) + prismjs: + specifier: ^1.30.0 + version: 1.30.0 react: specifier: ^19.0.0 version: 19.1.0 @@ -77,6 +80,9 @@ importers: react-highlight-words: specifier: ^0.21.0 version: 0.21.0(react@19.1.0) + react-toastify: + specifier: ^11.0.5 + version: 11.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) reading-time-estimator: specifier: ^1.12.0 version: 1.12.0 @@ -95,6 +101,9 @@ importers: vike-react: specifier: ^0.5.13 version: 0.5.13(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vike@0.4.228(react-streaming@0.3.50(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.2.6(@types/node@18.19.86)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3))) + vite-plugin-prismjs: + specifier: ^0.0.11 + version: 0.0.11(prismjs@1.30.0) devDependencies: '@eslint/js': specifier: ^9.22.0 @@ -108,6 +117,9 @@ importers: '@types/node': specifier: ^18.19.76 version: 18.19.86 + '@types/prismjs': + specifier: ^1.26.5 + version: 1.26.5 '@types/react': specifier: ^19.0.10 version: 19.1.1 @@ -1237,6 +1249,11 @@ packages: avvio@9.1.0: resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==} + babel-plugin-prismjs@2.1.0: + resolution: {integrity: sha512-ehzSKYfeAz4U78zi/sfwsjDPlq0LvDKxNefcZTJ/iKBu+plsHsLqZhUeGf1+82LAcA35UZGbU6ksEx2Utphc/g==} + peerDependencies: + prismjs: ^1.18.0 + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -2322,6 +2339,10 @@ packages: peerDependencies: react: '>=16.0.0' + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + process-warning@4.0.1: resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} @@ -2368,6 +2389,12 @@ packages: react: '>=18' react-dom: '>=18' + react-toastify@11.0.5: + resolution: {integrity: sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==} + peerDependencies: + react: ^18 || ^19 + react-dom: ^18 || ^19 + react@19.1.0: resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} engines: {node: '>=0.10.0'} @@ -2822,6 +2849,10 @@ packages: vite: optional: true + vite-plugin-prismjs@0.0.11: + resolution: {integrity: sha512-20NBQxg/zH+3FTrlU6BQTob720xkuXNYtrx7psAQ4E6pMcRDeLEK77QU9kXURU587+f2To7ASH1JVTGbXVV/vQ==} + engines: {node: '>=12.0.0'} + vite@6.2.6: resolution: {integrity: sha512-9xpjNl3kR4rVDZgPNdTL0/c6ao4km69a/2ihNQbcANz8RuCOK3hQBmLSJf3bRKVQjVMda+YvizNE8AwvogcPbw==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -3911,6 +3942,10 @@ snapshots: '@fastify/error': 4.1.0 fastq: 1.19.1 + babel-plugin-prismjs@2.1.0(prismjs@1.30.0): + dependencies: + prismjs: 1.30.0 + balanced-match@1.0.2: {} big.js@5.2.2: {} @@ -5118,6 +5153,8 @@ snapshots: clsx: 2.1.1 react: 19.1.0 + prismjs@1.30.0: {} + process-warning@4.0.1: {} process-warning@5.0.0: {} @@ -5165,6 +5202,12 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) + react-toastify@11.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + clsx: 2.1.1 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react@19.1.0: {} read-pkg@3.0.0: @@ -5693,6 +5736,14 @@ snapshots: react-streaming: 0.3.50(react-dom@19.1.0(react@19.1.0))(react@19.1.0) vite: 6.2.6(@types/node@18.19.86)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3) + vite-plugin-prismjs@0.0.11(prismjs@1.30.0): + dependencies: + '@babel/core': 7.26.10 + babel-plugin-prismjs: 2.1.0(prismjs@1.30.0) + transitivePeerDependencies: + - prismjs + - supports-color + vite@6.2.6(@types/node@18.19.86)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3): dependencies: esbuild: 0.25.2 diff --git a/app/vite.config.ts b/app/vite.config.ts index bd82e86..f57de65 100644 --- a/app/vite.config.ts +++ b/app/vite.config.ts @@ -1,3 +1,4 @@ +import prismjsVitePlugin from "vite-plugin-prismjs"; import tailwindcss from "@tailwindcss/vite"; import Unfonts from "unplugin-fonts/vite"; import { telefunc } from "telefunc/vite"; @@ -7,6 +8,9 @@ import vike from "vike/plugin"; export default defineConfig({ plugins: [ + prismjsVitePlugin({ + languages: ["javascript", "typescript", "tsx", "jsx", "css", "html", "bash"], + }), Unfonts({ fontsource: { families: ["Inter Variable", "Lexend Variable"],