From 3e4fe592c61e9e60d45d59287f678850333901f7 Mon Sep 17 00:00:00 2001 From: alexander-sei Date: Tue, 23 Dec 2025 16:13:40 +0200 Subject: [PATCH 1/4] Add Christmas --- src/components/Logo/Logo.tsx | 16 +++++- .../Snowflakes/Snowflakes.module.css | 25 ++++++++++ src/components/Snowflakes/Snowflakes.tsx | 49 +++++++++++++++++++ src/providers/DocsProviders.tsx | 2 + 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 src/components/Snowflakes/Snowflakes.module.css create mode 100644 src/components/Snowflakes/Snowflakes.tsx diff --git a/src/components/Logo/Logo.tsx b/src/components/Logo/Logo.tsx index 9bca0fa5..d8682524 100644 --- a/src/components/Logo/Logo.tsx +++ b/src/components/Logo/Logo.tsx @@ -1,6 +1,12 @@ export function Logo() { return ( - + + {/* Christmas Hat */} + + + + + + + {/* Christmas Hat */} + + + + + { + const [snowflakes, setSnowflakes] = useState([]); + + useEffect(() => { + // Generate snowflakes only on client side to avoid hydration mismatch + const flakes: Snowflake[] = Array.from({ length: 50 }).map((_, i) => ({ + id: i, + left: Math.random() * 100, + animationDuration: Math.random() * 3 + 5, // 5-8 seconds + animationDelay: Math.random() * 5, + opacity: Math.random() * 0.5 + 0.3, + size: Math.random() * 10 + 10 + })); + setSnowflakes(flakes); + }, []); + + return ( + + ); +}; diff --git a/src/providers/DocsProviders.tsx b/src/providers/DocsProviders.tsx index c41d2495..d6aa7a65 100644 --- a/src/providers/DocsProviders.tsx +++ b/src/providers/DocsProviders.tsx @@ -9,6 +9,7 @@ import { Footer } from '../components/Footer/Footer'; import { Theme } from '@radix-ui/themes'; import { ThemeSwitch } from 'nextra-theme-docs'; import { usePathname } from 'next/navigation'; +import { Snowflakes } from '../components/Snowflakes/Snowflakes'; // Defer Nextra Search until user clicks the trigger (client-only wrapper) const SearchDynamic = dynamic(() => import('../components/NextraSearch/NextraSearch'), { ssr: false, loading: () =>
}); @@ -85,6 +86,7 @@ export default function DocsProviders({ children, pageMap }) { pageMap={pageMap}> {isMobile && } + {!isMobile && } {children} From 055758533928f3b33e49c2e17d2c64a670cb02a5 Mon Sep 17 00:00:00 2001 From: alexander-sei Date: Tue, 23 Dec 2025 23:38:13 +0200 Subject: [PATCH 2/4] Add Christmas Flag --- src/components/Logo/Logo.tsx | 26 ++++++++++++++++---------- src/constants/featureFlags.ts | 1 + src/providers/DocsProviders.tsx | 3 ++- 3 files changed, 19 insertions(+), 11 deletions(-) create mode 100644 src/constants/featureFlags.ts diff --git a/src/components/Logo/Logo.tsx b/src/components/Logo/Logo.tsx index d8682524..45fec926 100644 --- a/src/components/Logo/Logo.tsx +++ b/src/components/Logo/Logo.tsx @@ -1,12 +1,16 @@ +import { ENABLE_CHRISTMAS_THEME } from '../../constants/featureFlags'; + export function Logo() { return ( {/* Christmas Hat */} - - - - - + {ENABLE_CHRISTMAS_THEME && ( + + + + + + )} {/* Christmas Hat */} - - - - - + {ENABLE_CHRISTMAS_THEME && ( + + + + + + )} import('../components/NextraSearch/NextraSearch'), { ssr: false, loading: () =>
}); @@ -86,7 +87,7 @@ export default function DocsProviders({ children, pageMap }) { pageMap={pageMap}> {isMobile && } - + {ENABLE_CHRISTMAS_THEME && } {!isMobile && } {children} From 23839ab7acce5a6cd063f541d708895beeec799f Mon Sep 17 00:00:00 2001 From: alexander-sei Date: Wed, 24 Dec 2025 00:30:04 +0200 Subject: [PATCH 3/4] Use react-snowfall --- package.json | 17 +++--- .../Snowflakes/Snowflakes.module.css | 25 --------- src/components/Snowflakes/Snowflakes.tsx | 54 +++++-------------- yarn.lock | 12 +++++ 4 files changed, 33 insertions(+), 75 deletions(-) delete mode 100644 src/components/Snowflakes/Snowflakes.module.css diff --git a/package.json b/package.json index 934a0dd2..64b6ca5c 100644 --- a/package.json +++ b/package.json @@ -34,19 +34,21 @@ "nextra-theme-docs": "^4.6.1", "react": "^19.2.3", "react-dom": "^19.2.3", + "react-snowfall": "^2.4.0", "sonner": "^2.0.7", "viem": "^2.43.1" }, "devDependencies": { "@playwright/test": "^1.56.1", - "playwright": "^1.56.1", "@react-native-async-storage/async-storage": "^2.1.2", + "@sparticuz/chromium": "^141.0.0", + "@sparticuz/chromium-min": "^141.0.0", "@types/node": "18.11.10", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "autoprefixer": "^10.4.23", - "cssnano": "^6.1.2", "concurrently": "^9.1.2", + "cssnano": "^6.1.2", "globby": "^14.1.0", "husky": "^9.1.7", "jest": "^29.7.0", @@ -56,19 +58,18 @@ "next-sitemap": "^4.2.3", "node-fetch": "^3.3.2", "pagefind": "^1.3.0", + "pino-pretty": "^13.0.0", + "playwright": "^1.56.1", "postcss": "^8.5.6", "postcss-simple-vars": "^7.0.1", "prettier": "^3.5.3", "puppeteer": "^24.31.0", + "puppeteer-core": "^24.31.0", "tailwindcss": "^4.1.18", + "terser": "^5.31.0", "tsx": "^4.19.3", "typescript": "^5.9.3", - "wait-on": "^9.0.1", - "puppeteer-core": "^24.31.0", - "pino-pretty": "^13.0.0", - "@sparticuz/chromium": "^141.0.0", - "@sparticuz/chromium-min": "^141.0.0", - "terser": "^5.31.0" + "wait-on": "^9.0.1" }, "resolutions": { "@istanbuljs/load-nyc-config/js-yaml": "3.14.2", diff --git a/src/components/Snowflakes/Snowflakes.module.css b/src/components/Snowflakes/Snowflakes.module.css deleted file mode 100644 index a93fb198..00000000 --- a/src/components/Snowflakes/Snowflakes.module.css +++ /dev/null @@ -1,25 +0,0 @@ -.snowflake { - position: fixed; - top: -20px; - color: #fff; - font-size: 1em; - font-family: Arial, sans-serif; - text-shadow: 0 0 5px #000; - user-select: none; - z-index: 9999; - pointer-events: none; - animation-name: fall; - animation-timing-function: linear; - animation-iteration-count: infinite; -} - -@keyframes fall { - 0% { - transform: translateY(-20px) translateX(0px) rotate(0deg); - opacity: 1; - } - 100% { - transform: translateY(100vh) translateX(20px) rotate(360deg); - opacity: 0.5; - } -} diff --git a/src/components/Snowflakes/Snowflakes.tsx b/src/components/Snowflakes/Snowflakes.tsx index feb910e7..38f93b97 100644 --- a/src/components/Snowflakes/Snowflakes.tsx +++ b/src/components/Snowflakes/Snowflakes.tsx @@ -1,49 +1,19 @@ 'use client'; -import React, { useEffect, useState } from 'react'; -import styles from './Snowflakes.module.css'; - -interface Snowflake { - id: number; - left: number; - animationDuration: number; - animationDelay: number; - opacity: number; - size: number; -} +import React from 'react'; +import Snowfall from 'react-snowfall'; export const Snowflakes = () => { - const [snowflakes, setSnowflakes] = useState([]); - - useEffect(() => { - // Generate snowflakes only on client side to avoid hydration mismatch - const flakes: Snowflake[] = Array.from({ length: 50 }).map((_, i) => ({ - id: i, - left: Math.random() * 100, - animationDuration: Math.random() * 3 + 5, // 5-8 seconds - animationDelay: Math.random() * 5, - opacity: Math.random() * 0.5 + 0.3, - size: Math.random() * 10 + 10 - })); - setSnowflakes(flakes); - }, []); - return ( - + ); }; diff --git a/yarn.lock b/yarn.lock index aa7eb1bd..470f7adb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7705,6 +7705,11 @@ react-dom@^19.2.3: dependencies: scheduler "^0.27.0" +react-fast-compare@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== + react-is@^18.0.0: version "18.3.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" @@ -7734,6 +7739,13 @@ react-remove-scroll@^2.6.3: use-callback-ref "^1.3.3" use-sidecar "^1.1.3" +react-snowfall@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/react-snowfall/-/react-snowfall-2.4.0.tgz#79ad34431f2353e842a87be1af3f1f5355e25806" + integrity sha512-KAPMiGnxt11PEgC2pTVrTQsvk5jt1kLUtG+ZamiKLphTZ7GiYT1Aa5kX6jp4jKWq1kqJHchnGT9CDm4g86A5Gg== + dependencies: + react-fast-compare "^3.2.2" + react-style-singleton@^2.2.2, react-style-singleton@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.3.tgz#4265608be69a4d70cfe3047f2c6c88b2c3ace388" From 3029df3cb4028237ef14301ab83af8ce2a34bee2 Mon Sep 17 00:00:00 2001 From: alexander-sei Date: Wed, 24 Dec 2025 01:49:24 +0200 Subject: [PATCH 4/4] Adjust logo --- src/components/Logo/Logo.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/Logo/Logo.tsx b/src/components/Logo/Logo.tsx index 45fec926..dad7fb5e 100644 --- a/src/components/Logo/Logo.tsx +++ b/src/components/Logo/Logo.tsx @@ -3,14 +3,6 @@ import { ENABLE_CHRISTMAS_THEME } from '../../constants/featureFlags'; export function Logo() { return ( - {/* Christmas Hat */} - {ENABLE_CHRISTMAS_THEME && ( - - - - - - )} + {/* Christmas Hat */} + {ENABLE_CHRISTMAS_THEME && ( + + + + + + )} ); }