@windrun-huaiin/third-ui 30.0.0 → 30.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fuma/fuma-page-genarator.d.ts +2 -6
- package/dist/fuma/fuma-page-genarator.js +3 -2
- package/dist/fuma/fuma-page-genarator.mjs +3 -2
- package/dist/main/404-page.d.ts +12 -0
- package/dist/main/404-page.js +66 -0
- package/dist/main/404-page.mjs +64 -0
- package/dist/main/anime/anime-404-page.d.ts +14 -0
- package/dist/main/anime/anime-404-page.js +197 -0
- package/dist/main/anime/anime-404-page.mjs +195 -0
- package/dist/main/anime/anime-not-found-page.d.ts +7 -0
- package/dist/main/anime/anime-not-found-page.js +142 -0
- package/dist/main/anime/anime-not-found-page.mjs +140 -0
- package/dist/main/anime/index.d.ts +1 -0
- package/dist/main/anime/index.js +2 -0
- package/dist/main/anime/index.mjs +1 -0
- package/dist/main/index.d.ts +1 -0
- package/dist/main/index.js +2 -0
- package/dist/main/index.mjs +1 -0
- package/dist/main/motion/creative-left-panel.d.ts +7 -0
- package/dist/main/motion/creative-left-panel.js +11 -0
- package/dist/main/motion/creative-left-panel.mjs +9 -0
- package/dist/main/motion/creative-right-panel.d.ts +7 -0
- package/dist/main/motion/creative-right-panel.js +11 -0
- package/dist/main/motion/creative-right-panel.mjs +9 -0
- package/dist/main/snake-loading-frame.js +1 -0
- package/dist/main/snake-loading-frame.mjs +1 -0
- package/package.json +4 -4
- package/src/fuma/fuma-page-genarator.tsx +2 -22
- package/src/main/404-page.tsx +162 -0
- package/src/main/anime/anime-404-page.tsx +344 -0
- package/src/main/anime/index.ts +1 -0
- package/src/main/index.ts +1 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
2
|
import type { LLMCopyButtonProps, LLMCopyButton } from './mdx/toc-base';
|
|
3
3
|
export type FumaPageTocRenderMode = 'portable-clerk' | 'fumadocs-clerk' | 'fumadocs-normal';
|
|
4
4
|
interface FumaPageParams {
|
|
@@ -8,10 +8,6 @@ interface FumaPageParams {
|
|
|
8
8
|
mdxSourceDir: string;
|
|
9
9
|
githubBaseUrl?: string;
|
|
10
10
|
copyButtonComponent?: ReactElement<LLMCopyButtonProps, typeof LLMCopyButton>;
|
|
11
|
-
siteIcon: ReactNode;
|
|
12
|
-
FallbackPage: React.ComponentType<{
|
|
13
|
-
siteIcon: ReactNode;
|
|
14
|
-
}>;
|
|
15
11
|
supportedLocales?: string[];
|
|
16
12
|
showBreadcrumb?: boolean;
|
|
17
13
|
showTableOfContent?: boolean;
|
|
@@ -20,7 +16,7 @@ interface FumaPageParams {
|
|
|
20
16
|
localePrefixAsNeeded?: boolean;
|
|
21
17
|
defaultLocale?: string;
|
|
22
18
|
}
|
|
23
|
-
export declare function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent,
|
|
19
|
+
export declare function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, supportedLocales, showBreadcrumb, showTableOfContent, tocRenderMode, showTableOfContentPopover, localePrefixAsNeeded, defaultLocale, }: FumaPageParams): {
|
|
24
20
|
Page: ({ params }: {
|
|
25
21
|
params: Promise<{
|
|
26
22
|
locale: string;
|
|
@@ -6,10 +6,11 @@ var page = require('fumadocs-ui/page');
|
|
|
6
6
|
var React = require('react');
|
|
7
7
|
var tocFooterWrapper = require('./mdx/toc-footer-wrapper.js');
|
|
8
8
|
var utils = require('@windrun-huaiin/lib/utils');
|
|
9
|
+
var navigation = require('next/navigation');
|
|
9
10
|
var tocClerkPortable = require('./mdx/toc-clerk-portable.js');
|
|
10
11
|
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
11
12
|
|
|
12
|
-
function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent,
|
|
13
|
+
function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, supportedLocales = ['en'], showBreadcrumb = true, showTableOfContent = true, tocRenderMode = 'portable-clerk', showTableOfContentPopover = false, localePrefixAsNeeded = true, defaultLocale = 'en', }) {
|
|
13
14
|
var _a;
|
|
14
15
|
const isLocalMdDebugEnabled = ((_a = process.env.LOCAL_MD_DEBUG) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'true';
|
|
15
16
|
const now = () => (typeof performance !== 'undefined' ? performance.now() : Date.now());
|
|
@@ -49,7 +50,7 @@ function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSour
|
|
|
49
50
|
totalElapsedMs: durationMs(pageStartedAt),
|
|
50
51
|
});
|
|
51
52
|
if (!page$1) {
|
|
52
|
-
|
|
53
|
+
navigation.notFound();
|
|
53
54
|
}
|
|
54
55
|
const path = githubBaseUrl ? `${mdxSourceDir}/${page$1.path}` : undefined;
|
|
55
56
|
const tocFooterElement = (jsxRuntime.jsx(tocFooterWrapper.TocFooterWrapper, { lastModified: page$1.data.date, copyButtonComponent: copyButtonComponent
|
|
@@ -4,10 +4,11 @@ import { DocsPage, DocsTitle, DocsDescription, DocsBody } from 'fumadocs-ui/page
|
|
|
4
4
|
import { cloneElement } from 'react';
|
|
5
5
|
import { TocFooterWrapper } from './mdx/toc-footer-wrapper.mjs';
|
|
6
6
|
import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib/utils';
|
|
7
|
+
import { notFound } from 'next/navigation';
|
|
7
8
|
import { PortableClerkTOC, PortableClerkTOCTitle } from './mdx/toc-clerk-portable.mjs';
|
|
8
9
|
import { themeSvgIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
9
10
|
|
|
10
|
-
function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent,
|
|
11
|
+
function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, supportedLocales = ['en'], showBreadcrumb = true, showTableOfContent = true, tocRenderMode = 'portable-clerk', showTableOfContentPopover = false, localePrefixAsNeeded = true, defaultLocale = 'en', }) {
|
|
11
12
|
var _a;
|
|
12
13
|
const isLocalMdDebugEnabled = ((_a = process.env.LOCAL_MD_DEBUG) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'true';
|
|
13
14
|
const now = () => (typeof performance !== 'undefined' ? performance.now() : Date.now());
|
|
@@ -47,7 +48,7 @@ function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSour
|
|
|
47
48
|
totalElapsedMs: durationMs(pageStartedAt),
|
|
48
49
|
});
|
|
49
50
|
if (!page) {
|
|
50
|
-
|
|
51
|
+
notFound();
|
|
51
52
|
}
|
|
52
53
|
const path = githubBaseUrl ? `${mdxSourceDir}/${page.path}` : undefined;
|
|
53
54
|
const tocFooterElement = (jsx(TocFooterWrapper, { lastModified: page.data.date, copyButtonComponent: copyButtonComponent
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type SupportedThemeColor } from '@windrun-huaiin/base-ui/lib';
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
interface NotFoundPageProps {
|
|
4
|
+
siteIcon: ReactNode;
|
|
5
|
+
errorIcon?: ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
compact?: boolean;
|
|
8
|
+
themeClass?: SupportedThemeColor;
|
|
9
|
+
animated?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function NotFoundPage({ siteIcon, errorIcon, className, compact, themeClass, animated, }: NotFoundPageProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var shared = require('@windrun-huaiin/base-ui/components/shared');
|
|
6
|
+
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
7
|
+
var utils = require('@windrun-huaiin/lib/utils');
|
|
8
|
+
var React = require('react');
|
|
9
|
+
|
|
10
|
+
const THEME_BG_CLASS_MAP = {
|
|
11
|
+
'text-purple-500': 'bg-purple-500/20',
|
|
12
|
+
'text-orange-500': 'bg-orange-500/20',
|
|
13
|
+
'text-indigo-500': 'bg-indigo-500/20',
|
|
14
|
+
'text-emerald-500': 'bg-emerald-500/20',
|
|
15
|
+
'text-rose-500': 'bg-rose-500/20',
|
|
16
|
+
};
|
|
17
|
+
const THEME_VIA_CLASS_MAP = {
|
|
18
|
+
'text-purple-500': 'via-purple-500/20',
|
|
19
|
+
'text-orange-500': 'via-orange-500/20',
|
|
20
|
+
'text-indigo-500': 'via-indigo-500/20',
|
|
21
|
+
'text-emerald-500': 'via-emerald-500/20',
|
|
22
|
+
'text-rose-500': 'via-rose-500/20',
|
|
23
|
+
};
|
|
24
|
+
function NotFoundPage({ siteIcon, errorIcon, className, compact = false, themeClass, animated = true, }) {
|
|
25
|
+
const [glitchText, setGlitchText] = React.useState('404');
|
|
26
|
+
const homeUrl = process.env.NEXT_PUBLIC_BASE_URL || '/';
|
|
27
|
+
const activeThemeClass = themeClass !== null && themeClass !== void 0 ? themeClass : lib.themeIconColor;
|
|
28
|
+
const activeGradientClass = themeClass ? lib.THEME_BUTTON_GRADIENT_CLASS_MAP[themeClass] : lib.themeButtonGradientClass;
|
|
29
|
+
const activeBgClass = themeClass ? THEME_BG_CLASS_MAP[themeClass] : lib.themeBgColor;
|
|
30
|
+
const activeViaClass = themeClass ? THEME_VIA_CLASS_MAP[themeClass] : lib.themeViaColor;
|
|
31
|
+
React.useEffect(() => {
|
|
32
|
+
if (!animated) {
|
|
33
|
+
setGlitchText('404');
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const glitchChars = ['4', '0', '4', '?', '#', '!', '*', '&', '%', '$'];
|
|
37
|
+
const interval = setInterval(() => {
|
|
38
|
+
if (Math.random() < 0.5) {
|
|
39
|
+
setGlitchText('404');
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const randomChars = Array.from({ length: 3 }, () => glitchChars[Math.floor(Math.random() * glitchChars.length)]).join('');
|
|
43
|
+
setGlitchText(randomChars);
|
|
44
|
+
}
|
|
45
|
+
}, 600);
|
|
46
|
+
return () => clearInterval(interval);
|
|
47
|
+
}, [animated]);
|
|
48
|
+
return (jsxRuntime.jsxs("div", { className: utils.cn('relative flex w-full flex-col items-center justify-center px-4 py-8', compact ? 'h-full min-h-full' : 'min-h-dvh', className), children: [jsxRuntime.jsxs("div", { className: "text-center space-y-8 max-w-2xl", children: [jsxRuntime.jsxs("div", { className: "relative flex justify-center", children: [jsxRuntime.jsx("h1", { className: utils.cn('text-8xl md:text-9xl font-bold bg-linear-to-r bg-clip-text text-transparent select-none', activeGradientClass), style: {
|
|
49
|
+
fontFamily: 'Montserrat, monospace',
|
|
50
|
+
textShadow: '0 0 30px rgba(172, 98, 253, 0.3)',
|
|
51
|
+
letterSpacing: '0.1em',
|
|
52
|
+
}, children: glitchText }), jsxRuntime.jsx("div", { className: "absolute inset-0 pointer-events-none", children: jsxRuntime.jsx("div", { className: utils.cn('h-full w-full bg-linear-to-b from-transparent to-transparent', animated && 'animate-pulse', activeViaClass) }) })] }), jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx("h2", { className: "text-2xl md:text-3xl font-semibold text-foreground", children: "Page Not Found" }), jsxRuntime.jsx("p", { className: "text-lg text-muted-foreground max-w-md mx-auto leading-relaxed", children: "The page you're looking for doesn't exist" }), jsxRuntime.jsx("a", { href: homeUrl, className: utils.cn('inline-flex text-sm font-medium underline underline-offset-4 transition-opacity hover:opacity-80', activeThemeClass, 'decoration-current'), children: "Back to Homepage" })] }), jsxRuntime.jsxs("div", { className: "flex justify-center items-center gap-8 pt-8 opacity-60", children: [jsxRuntime.jsxs("a", { href: homeUrl, className: "flex items-center gap-2 text-sm text-muted-foreground transition-opacity hover:opacity-80", children: [siteIcon, jsxRuntime.jsx("span", { children: "Woops!" })] }), jsxRuntime.jsx("div", { className: utils.cn('w-2 h-2 rounded-full', animated && 'animate-ping', activeBgClass) }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [errorIcon !== null && errorIcon !== void 0 ? errorIcon : jsxRuntime.jsx(shared.NotFoundIcon, {}), jsxRuntime.jsx("span", { children: "Error Code: 404" })] })] })] }), jsxRuntime.jsxs("div", { className: utils.cn('pointer-events-none inset-0 overflow-hidden -z-10', compact ? 'absolute' : 'fixed'), children: [jsxRuntime.jsx("div", { className: "absolute inset-0 opacity-[0.02] dark:opacity-[0.05]", style: {
|
|
53
|
+
backgroundImage: `
|
|
54
|
+
linear-gradient(rgba(172, 98, 253, 0.1) 1px, transparent 1px),
|
|
55
|
+
linear-gradient(90deg, rgba(172, 98, 253, 0.1) 1px, transparent 1px)
|
|
56
|
+
`,
|
|
57
|
+
backgroundSize: '50px 50px',
|
|
58
|
+
} }), Array.from({ length: 6 }).map((_, i) => (jsxRuntime.jsx("div", { className: utils.cn('absolute w-2 h-2 rounded-full', animated && 'animate-bounce', activeBgClass), style: {
|
|
59
|
+
left: `${20 + i * 15}%`,
|
|
60
|
+
top: `${30 + (i % 3) * 20}%`,
|
|
61
|
+
animationDelay: `${i * 0.5}s`,
|
|
62
|
+
animationDuration: `${2 + i * 0.3}s`,
|
|
63
|
+
} }, i)))] })] }));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
exports.NotFoundPage = NotFoundPage;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { NotFoundIcon } from '@windrun-huaiin/base-ui/components/shared';
|
|
4
|
+
import { THEME_BUTTON_GRADIENT_CLASS_MAP, themeButtonGradientClass, themeViaColor, themeIconColor, themeBgColor } from '@windrun-huaiin/base-ui/lib';
|
|
5
|
+
import { cn } from '@windrun-huaiin/lib/utils';
|
|
6
|
+
import { useState, useEffect } from 'react';
|
|
7
|
+
|
|
8
|
+
const THEME_BG_CLASS_MAP = {
|
|
9
|
+
'text-purple-500': 'bg-purple-500/20',
|
|
10
|
+
'text-orange-500': 'bg-orange-500/20',
|
|
11
|
+
'text-indigo-500': 'bg-indigo-500/20',
|
|
12
|
+
'text-emerald-500': 'bg-emerald-500/20',
|
|
13
|
+
'text-rose-500': 'bg-rose-500/20',
|
|
14
|
+
};
|
|
15
|
+
const THEME_VIA_CLASS_MAP = {
|
|
16
|
+
'text-purple-500': 'via-purple-500/20',
|
|
17
|
+
'text-orange-500': 'via-orange-500/20',
|
|
18
|
+
'text-indigo-500': 'via-indigo-500/20',
|
|
19
|
+
'text-emerald-500': 'via-emerald-500/20',
|
|
20
|
+
'text-rose-500': 'via-rose-500/20',
|
|
21
|
+
};
|
|
22
|
+
function NotFoundPage({ siteIcon, errorIcon, className, compact = false, themeClass, animated = true, }) {
|
|
23
|
+
const [glitchText, setGlitchText] = useState('404');
|
|
24
|
+
const homeUrl = process.env.NEXT_PUBLIC_BASE_URL || '/';
|
|
25
|
+
const activeThemeClass = themeClass !== null && themeClass !== void 0 ? themeClass : themeIconColor;
|
|
26
|
+
const activeGradientClass = themeClass ? THEME_BUTTON_GRADIENT_CLASS_MAP[themeClass] : themeButtonGradientClass;
|
|
27
|
+
const activeBgClass = themeClass ? THEME_BG_CLASS_MAP[themeClass] : themeBgColor;
|
|
28
|
+
const activeViaClass = themeClass ? THEME_VIA_CLASS_MAP[themeClass] : themeViaColor;
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!animated) {
|
|
31
|
+
setGlitchText('404');
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
const glitchChars = ['4', '0', '4', '?', '#', '!', '*', '&', '%', '$'];
|
|
35
|
+
const interval = setInterval(() => {
|
|
36
|
+
if (Math.random() < 0.5) {
|
|
37
|
+
setGlitchText('404');
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const randomChars = Array.from({ length: 3 }, () => glitchChars[Math.floor(Math.random() * glitchChars.length)]).join('');
|
|
41
|
+
setGlitchText(randomChars);
|
|
42
|
+
}
|
|
43
|
+
}, 600);
|
|
44
|
+
return () => clearInterval(interval);
|
|
45
|
+
}, [animated]);
|
|
46
|
+
return (jsxs("div", { className: cn('relative flex w-full flex-col items-center justify-center px-4 py-8', compact ? 'h-full min-h-full' : 'min-h-dvh', className), children: [jsxs("div", { className: "text-center space-y-8 max-w-2xl", children: [jsxs("div", { className: "relative flex justify-center", children: [jsx("h1", { className: cn('text-8xl md:text-9xl font-bold bg-linear-to-r bg-clip-text text-transparent select-none', activeGradientClass), style: {
|
|
47
|
+
fontFamily: 'Montserrat, monospace',
|
|
48
|
+
textShadow: '0 0 30px rgba(172, 98, 253, 0.3)',
|
|
49
|
+
letterSpacing: '0.1em',
|
|
50
|
+
}, children: glitchText }), jsx("div", { className: "absolute inset-0 pointer-events-none", children: jsx("div", { className: cn('h-full w-full bg-linear-to-b from-transparent to-transparent', animated && 'animate-pulse', activeViaClass) }) })] }), jsxs("div", { className: "space-y-4", children: [jsx("h2", { className: "text-2xl md:text-3xl font-semibold text-foreground", children: "Page Not Found" }), jsx("p", { className: "text-lg text-muted-foreground max-w-md mx-auto leading-relaxed", children: "The page you're looking for doesn't exist" }), jsx("a", { href: homeUrl, className: cn('inline-flex text-sm font-medium underline underline-offset-4 transition-opacity hover:opacity-80', activeThemeClass, 'decoration-current'), children: "Back to Homepage" })] }), jsxs("div", { className: "flex justify-center items-center gap-8 pt-8 opacity-60", children: [jsxs("a", { href: homeUrl, className: "flex items-center gap-2 text-sm text-muted-foreground transition-opacity hover:opacity-80", children: [siteIcon, jsx("span", { children: "Woops!" })] }), jsx("div", { className: cn('w-2 h-2 rounded-full', animated && 'animate-ping', activeBgClass) }), jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [errorIcon !== null && errorIcon !== void 0 ? errorIcon : jsx(NotFoundIcon, {}), jsx("span", { children: "Error Code: 404" })] })] })] }), jsxs("div", { className: cn('pointer-events-none inset-0 overflow-hidden -z-10', compact ? 'absolute' : 'fixed'), children: [jsx("div", { className: "absolute inset-0 opacity-[0.02] dark:opacity-[0.05]", style: {
|
|
51
|
+
backgroundImage: `
|
|
52
|
+
linear-gradient(rgba(172, 98, 253, 0.1) 1px, transparent 1px),
|
|
53
|
+
linear-gradient(90deg, rgba(172, 98, 253, 0.1) 1px, transparent 1px)
|
|
54
|
+
`,
|
|
55
|
+
backgroundSize: '50px 50px',
|
|
56
|
+
} }), Array.from({ length: 6 }).map((_, i) => (jsx("div", { className: cn('absolute w-2 h-2 rounded-full', animated && 'animate-bounce', activeBgClass), style: {
|
|
57
|
+
left: `${20 + i * 15}%`,
|
|
58
|
+
top: `${30 + (i % 3) * 20}%`,
|
|
59
|
+
animationDelay: `${i * 0.5}s`,
|
|
60
|
+
animationDuration: `${2 + i * 0.3}s`,
|
|
61
|
+
} }, i)))] })] }));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { NotFoundPage };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type SupportedThemeColor } from '@windrun-huaiin/base-ui/lib';
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
export interface AnimeNotFoundPageProps {
|
|
4
|
+
siteIcon: ReactNode;
|
|
5
|
+
homeUrl?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
compact?: boolean;
|
|
8
|
+
themeClass?: SupportedThemeColor;
|
|
9
|
+
themeColor?: string;
|
|
10
|
+
ambientAnimated?: boolean;
|
|
11
|
+
doorOpen?: boolean;
|
|
12
|
+
onDoorOpenChange?: (open: boolean) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function AnimeNotFoundPage({ siteIcon, homeUrl, className, compact, themeClass, themeColor, ambientAnimated, doorOpen, onDoorOpenChange, }: AnimeNotFoundPageProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
6
|
+
var utils = require('@windrun-huaiin/lib/utils');
|
|
7
|
+
var animejs = require('animejs');
|
|
8
|
+
var react = require('motion/react');
|
|
9
|
+
var React = require('react');
|
|
10
|
+
|
|
11
|
+
const THEME_BG_CLASS_MAP = {
|
|
12
|
+
'text-purple-500': 'bg-purple-500/20',
|
|
13
|
+
'text-orange-500': 'bg-orange-500/20',
|
|
14
|
+
'text-indigo-500': 'bg-indigo-500/20',
|
|
15
|
+
'text-emerald-500': 'bg-emerald-500/20',
|
|
16
|
+
'text-rose-500': 'bg-rose-500/20',
|
|
17
|
+
};
|
|
18
|
+
const dust = Array.from({ length: 10 }, (_, index) => ({
|
|
19
|
+
id: index,
|
|
20
|
+
left: `${12 + index * 8}%`,
|
|
21
|
+
top: `${18 + (index % 5) * 13}%`,
|
|
22
|
+
size: 3 + (index % 3),
|
|
23
|
+
}));
|
|
24
|
+
function AnimeNotFoundPage({ siteIcon, homeUrl = process.env.NEXT_PUBLIC_BASE_URL || '/', className, compact = false, themeClass, themeColor, ambientAnimated = true, doorOpen, onDoorOpenChange, }) {
|
|
25
|
+
const rootRef = React.useRef(null);
|
|
26
|
+
const timelineRef = React.useRef(null);
|
|
27
|
+
const shimmerRef = React.useRef(null);
|
|
28
|
+
const doorAnimationRef = React.useRef(null);
|
|
29
|
+
const lightAnimationRef = React.useRef(null);
|
|
30
|
+
const handleAnimationRef = React.useRef(null);
|
|
31
|
+
const messageAnimationRef = React.useRef(null);
|
|
32
|
+
const isDoorOpenRef = React.useRef(doorOpen !== null && doorOpen !== void 0 ? doorOpen : false);
|
|
33
|
+
const prefersReducedMotion = react.useReducedMotion();
|
|
34
|
+
const activeThemeClass = themeClass !== null && themeClass !== void 0 ? themeClass : lib.themeIconColor;
|
|
35
|
+
const activeGradientClass = themeClass ? lib.THEME_BUTTON_GRADIENT_CLASS_MAP[themeClass] : lib.themeButtonGradientClass;
|
|
36
|
+
const activeBgClass = themeClass ? THEME_BG_CLASS_MAP[themeClass] : lib.themeBgColor;
|
|
37
|
+
const doorStyle = React.useMemo(() => ({
|
|
38
|
+
'--not-found-theme': themeColor !== null && themeColor !== void 0 ? themeColor : lib.themeSvgIconColor,
|
|
39
|
+
}), [themeColor]);
|
|
40
|
+
React.useEffect(() => {
|
|
41
|
+
var _a, _b;
|
|
42
|
+
const root = rootRef.current;
|
|
43
|
+
if (!root || prefersReducedMotion) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const door = root.querySelector('[data-not-found-door]');
|
|
47
|
+
const light = root.querySelector('[data-not-found-light]');
|
|
48
|
+
const message = root.querySelector('[data-not-found-message]');
|
|
49
|
+
const plate = root.querySelector('[data-not-found-plate]');
|
|
50
|
+
const handle = root.querySelector('[data-not-found-handle]');
|
|
51
|
+
const dustNodes = Array.from(root.querySelectorAll('[data-not-found-dust]'));
|
|
52
|
+
if (!door || !light || !plate || !handle) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
door.style.transform = 'rotateY(-2deg) translateX(0)';
|
|
56
|
+
light.style.opacity = '0.2';
|
|
57
|
+
light.style.transform = 'scaleX(0.78)';
|
|
58
|
+
if (message) {
|
|
59
|
+
message.style.opacity = '0';
|
|
60
|
+
message.style.transform = 'translateY(8px)';
|
|
61
|
+
}
|
|
62
|
+
(_a = timelineRef.current) === null || _a === void 0 ? void 0 : _a.revert();
|
|
63
|
+
(_b = shimmerRef.current) === null || _b === void 0 ? void 0 : _b.revert();
|
|
64
|
+
timelineRef.current = null;
|
|
65
|
+
shimmerRef.current = null;
|
|
66
|
+
if (ambientAnimated) {
|
|
67
|
+
timelineRef.current = animejs.createTimeline({ loop: true })
|
|
68
|
+
.add(plate, {
|
|
69
|
+
translateY: [0, -3, 0],
|
|
70
|
+
scale: [1, 1.025, 1],
|
|
71
|
+
duration: 1400,
|
|
72
|
+
ease: 'inOutSine',
|
|
73
|
+
})
|
|
74
|
+
.add(plate, {
|
|
75
|
+
translateY: [0, -3, 0],
|
|
76
|
+
scale: [1, 1.025, 1],
|
|
77
|
+
duration: 1400,
|
|
78
|
+
ease: 'inOutSine',
|
|
79
|
+
}, '+=900')
|
|
80
|
+
.add(dustNodes, {
|
|
81
|
+
opacity: [0, 0.72, 0],
|
|
82
|
+
translateY: [14, -18],
|
|
83
|
+
translateX: (_target, index) => (index % 2 === 0 ? 10 : -10),
|
|
84
|
+
scale: [0.4, 1, 0.6],
|
|
85
|
+
duration: 1800,
|
|
86
|
+
delay: animejs.stagger(80),
|
|
87
|
+
ease: 'outSine',
|
|
88
|
+
}, '<+=200');
|
|
89
|
+
shimmerRef.current = animejs.animate(root.querySelectorAll('[data-not-found-shimmer]'), {
|
|
90
|
+
translateX: ['-120%', '120%'],
|
|
91
|
+
opacity: [0, 0.8, 0],
|
|
92
|
+
duration: 2400,
|
|
93
|
+
delay: animejs.stagger(160),
|
|
94
|
+
ease: 'inOutSine',
|
|
95
|
+
loop: true,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return () => {
|
|
99
|
+
var _a, _b, _c, _d, _e, _f;
|
|
100
|
+
(_a = timelineRef.current) === null || _a === void 0 ? void 0 : _a.revert();
|
|
101
|
+
timelineRef.current = null;
|
|
102
|
+
(_b = shimmerRef.current) === null || _b === void 0 ? void 0 : _b.revert();
|
|
103
|
+
shimmerRef.current = null;
|
|
104
|
+
(_c = doorAnimationRef.current) === null || _c === void 0 ? void 0 : _c.revert();
|
|
105
|
+
doorAnimationRef.current = null;
|
|
106
|
+
(_d = lightAnimationRef.current) === null || _d === void 0 ? void 0 : _d.revert();
|
|
107
|
+
lightAnimationRef.current = null;
|
|
108
|
+
(_e = handleAnimationRef.current) === null || _e === void 0 ? void 0 : _e.revert();
|
|
109
|
+
handleAnimationRef.current = null;
|
|
110
|
+
(_f = messageAnimationRef.current) === null || _f === void 0 ? void 0 : _f.revert();
|
|
111
|
+
messageAnimationRef.current = null;
|
|
112
|
+
};
|
|
113
|
+
}, [ambientAnimated, prefersReducedMotion]);
|
|
114
|
+
const setDoorOpen = React.useCallback((nextOpen) => {
|
|
115
|
+
var _a, _b, _c, _d;
|
|
116
|
+
const root = rootRef.current;
|
|
117
|
+
if (!root) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const door = root.querySelector('[data-not-found-door]');
|
|
121
|
+
const light = root.querySelector('[data-not-found-light]');
|
|
122
|
+
const handle = root.querySelector('[data-not-found-handle]');
|
|
123
|
+
const message = root.querySelector('[data-not-found-message]');
|
|
124
|
+
if (!door || !light || !handle) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
isDoorOpenRef.current = nextOpen;
|
|
128
|
+
(_a = doorAnimationRef.current) === null || _a === void 0 ? void 0 : _a.pause();
|
|
129
|
+
(_b = lightAnimationRef.current) === null || _b === void 0 ? void 0 : _b.pause();
|
|
130
|
+
(_c = handleAnimationRef.current) === null || _c === void 0 ? void 0 : _c.pause();
|
|
131
|
+
(_d = messageAnimationRef.current) === null || _d === void 0 ? void 0 : _d.pause();
|
|
132
|
+
doorAnimationRef.current = null;
|
|
133
|
+
lightAnimationRef.current = null;
|
|
134
|
+
handleAnimationRef.current = null;
|
|
135
|
+
messageAnimationRef.current = null;
|
|
136
|
+
if (prefersReducedMotion) {
|
|
137
|
+
door.style.transform = nextOpen ? 'rotateY(-72deg) translateX(-12px)' : 'rotateY(-2deg) translateX(0)';
|
|
138
|
+
light.style.opacity = nextOpen ? '0.8' : '0.2';
|
|
139
|
+
light.style.transform = nextOpen ? 'scaleX(1.28)' : 'scaleX(0.78)';
|
|
140
|
+
if (message) {
|
|
141
|
+
message.style.opacity = nextOpen ? '1' : '0';
|
|
142
|
+
message.style.transform = nextOpen ? 'translateY(0)' : 'translateY(8px)';
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
doorAnimationRef.current = animejs.animate(door, {
|
|
147
|
+
rotateY: nextOpen ? -72 : -2,
|
|
148
|
+
translateX: nextOpen ? -12 : 0,
|
|
149
|
+
duration: 1050,
|
|
150
|
+
ease: 'inOutCubic',
|
|
151
|
+
});
|
|
152
|
+
lightAnimationRef.current = animejs.animate(light, {
|
|
153
|
+
opacity: nextOpen ? 0.8 : 0.2,
|
|
154
|
+
scaleX: nextOpen ? 1.28 : 0.78,
|
|
155
|
+
duration: 1050,
|
|
156
|
+
ease: 'inOutSine',
|
|
157
|
+
});
|
|
158
|
+
handleAnimationRef.current = animejs.animate(handle, {
|
|
159
|
+
scale: [1, 1.05, 1],
|
|
160
|
+
duration: 520,
|
|
161
|
+
ease: 'inOutSine',
|
|
162
|
+
});
|
|
163
|
+
if (message) {
|
|
164
|
+
messageAnimationRef.current = animejs.animate(message, {
|
|
165
|
+
opacity: nextOpen ? [0, 1] : [1, 0],
|
|
166
|
+
translateY: nextOpen ? [10, 0] : [0, 4, 10],
|
|
167
|
+
scale: nextOpen ? [0.96, 1] : [1, 0.98],
|
|
168
|
+
duration: nextOpen ? 620 : 520,
|
|
169
|
+
delay: nextOpen ? 320 : 280,
|
|
170
|
+
ease: nextOpen ? 'outCubic' : 'inOutSine',
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}, [prefersReducedMotion]);
|
|
174
|
+
React.useEffect(() => {
|
|
175
|
+
if (doorOpen === undefined || doorOpen === isDoorOpenRef.current) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
setDoorOpen(doorOpen);
|
|
179
|
+
}, [doorOpen, setDoorOpen]);
|
|
180
|
+
const toggleDoor = () => {
|
|
181
|
+
const nextOpen = !isDoorOpenRef.current;
|
|
182
|
+
if (doorOpen !== undefined) {
|
|
183
|
+
onDoorOpenChange === null || onDoorOpenChange === void 0 ? void 0 : onDoorOpenChange(nextOpen);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
setDoorOpen(nextOpen);
|
|
187
|
+
onDoorOpenChange === null || onDoorOpenChange === void 0 ? void 0 : onDoorOpenChange(nextOpen);
|
|
188
|
+
};
|
|
189
|
+
return (jsxRuntime.jsxs("div", { ref: rootRef, className: utils.cn('relative flex w-full items-center justify-center overflow-hidden px-4 py-8', compact ? 'h-full min-h-full' : 'min-h-dvh', className), style: doorStyle, children: [jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(circle_at_50%_20%,rgba(255,255,255,0.75),transparent_34%),linear-gradient(180deg,rgba(250,250,250,0.96),rgba(244,244,245,0.72))] dark:bg-[radial-gradient(circle_at_50%_20%,rgba(255,255,255,0.08),transparent_34%),linear-gradient(180deg,rgba(24,24,27,0.96),rgba(9,9,11,0.92))]" }), jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 -z-10 h-1/2 bg-[linear-gradient(180deg,transparent,rgba(0,0,0,0.05))] dark:bg-[linear-gradient(180deg,transparent,rgba(0,0,0,0.34))]" }), jsxRuntime.jsxs("div", { className: "flex w-full max-w-3xl flex-col items-center gap-5", children: [jsxRuntime.jsx("section", { className: "text-center", children: jsxRuntime.jsx("h3", { className: utils.cn('whitespace-nowrap text-[clamp(2.15rem,8vw,3.4rem)] font-black leading-none tracking-normal bg-linear-to-r bg-clip-text text-transparent', activeGradientClass), children: "Page Not Found" }) }), jsxRuntime.jsx("section", { className: "flex w-full justify-center", children: jsxRuntime.jsxs("div", { className: "relative aspect-[0.78] w-full max-w-[270px] sm:max-w-[315px] md:max-w-[330px] perspective-distant", children: [jsxRuntime.jsx("div", { "data-not-found-light": "", className: "absolute left-[14%] top-[7%] h-[86%] w-[72%] rounded-[28px] bg-[radial-gradient(circle_at_50%_45%,rgba(255,255,255,0.96),color-mix(in_srgb,var(--not-found-theme)_42%,transparent)_42%,transparent_72%)] opacity-25 blur-xl" }), jsxRuntime.jsx("div", { className: "absolute inset-[4%] rounded-[32px] border border-black/10 bg-neutral-950/5 shadow-2xl shadow-black/10 dark:border-white/10 dark:bg-white/5" }), jsxRuntime.jsx("div", { className: "absolute inset-[8%] rounded-[26px] bg-[linear-gradient(180deg,rgba(255,255,255,0.88),rgba(228,228,231,0.86))] shadow-[inset_0_1px_0_rgba(255,255,255,0.85)] dark:bg-[linear-gradient(180deg,rgba(39,39,42,0.92),rgba(24,24,27,0.96))]" }), jsxRuntime.jsxs("p", { "data-not-found-message": "", className: "pointer-events-none absolute right-[16%] top-[29%] z-2 max-w-[46%] text-right text-sm font-medium leading-6 text-muted-foreground opacity-100", children: [jsxRuntime.jsx("span", { className: "block", children: "The page" }), jsxRuntime.jsx("span", { className: "block", children: "you're looking for" }), jsxRuntime.jsx("span", { className: "block", children: "doesn't exist" })] }), jsxRuntime.jsx("button", { type: "button", className: "absolute inset-[8%] z-1 rounded-[26px] outline-none focus-visible:ring-2 focus-visible:ring-(--not-found-theme)", "aria-label": "Toggle the 404 door", onClick: toggleDoor }), jsxRuntime.jsxs("div", { "data-not-found-door": "", className: "absolute inset-[8%] z-10 origin-left rounded-[26px] border border-black/10 bg-[linear-gradient(145deg,rgba(255,255,255,0.92),rgba(212,212,216,0.9))] shadow-2xl shadow-black/20 will-change-transform dark:border-white/10 dark:bg-[linear-gradient(145deg,rgba(63,63,70,0.96),rgba(24,24,27,0.98))]", children: [jsxRuntime.jsxs("div", { className: "absolute inset-4 overflow-hidden rounded-[20px]", children: [jsxRuntime.jsx("div", { "data-not-found-shimmer": "", className: "absolute inset-y-0 w-1/3 -skew-x-12 bg-white/35 blur-md dark:bg-white/12" }), jsxRuntime.jsxs("a", { href: homeUrl, className: "absolute inset-x-5 bottom-5 flex h-[39%] flex-col items-center justify-center gap-2 rounded-2xl border border-black/10 bg-white/25 text-sm text-muted-foreground transition-opacity hover:opacity-80 dark:border-white/10 dark:bg-white/5", children: [jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2", children: [siteIcon, jsxRuntime.jsx("span", { children: "Woops!" })] }), jsxRuntime.jsx("span", { className: utils.cn('text-xs font-semibold underline underline-offset-4', activeThemeClass, 'decoration-current'), children: "Back to Homepage" })] })] }), jsxRuntime.jsxs("div", { "data-not-found-plate": "", className: "absolute left-1/2 top-[18%] flex h-[88px] w-[156px] -translate-x-1/2 items-center justify-center overflow-hidden rounded-2xl border border-black/10 bg-white/86 shadow-lg shadow-black/10 dark:border-white/10 dark:bg-black/30", children: [jsxRuntime.jsx("div", { "data-not-found-shimmer": "", className: "absolute inset-y-0 w-1/2 -skew-x-12 bg-white/60 blur-md dark:bg-white/15" }), jsxRuntime.jsx("span", { className: utils.cn('relative text-5xl font-black tabular-nums bg-linear-to-r bg-clip-text text-transparent', activeGradientClass), children: "404" })] }), jsxRuntime.jsx("button", { type: "button", "data-not-found-handle": "", className: "group absolute right-[1%] top-[39%] z-10 flex size-12 items-center justify-center rounded-full outline-none ring-offset-2 transition-transform hover:scale-105 focus-visible:ring-2 focus-visible:ring-(--not-found-theme)", "aria-label": "Toggle the 404 door", onClick: toggleDoor, children: jsxRuntime.jsxs("span", { className: "relative grid h-8 w-6 place-items-center rounded-full border border-black/10 bg-white/50 shadow-inner shadow-black/10 backdrop-blur-sm transform-[rotateY(18deg)] dark:border-white/15 dark:bg-black/25", children: [jsxRuntime.jsx("span", { className: "absolute size-10 rounded-full bg-(--not-found-theme) opacity-0 blur-md transition-opacity duration-300 group-hover:opacity-25" }), jsxRuntime.jsx("span", { className: "relative grid size-4 place-items-center rounded-full border border-black/10 bg-(--not-found-theme) shadow-lg shadow-black/25 dark:border-white/15", children: jsxRuntime.jsx("span", { className: "absolute right-1 top-1 size-1 rounded-full bg-white/75" }) })] }) })] }), dust.map(dot => (jsxRuntime.jsx("span", { "data-not-found-dust": "", className: utils.cn('absolute rounded-full opacity-0', activeBgClass), style: {
|
|
190
|
+
left: dot.left,
|
|
191
|
+
top: dot.top,
|
|
192
|
+
width: dot.size,
|
|
193
|
+
height: dot.size,
|
|
194
|
+
} }, dot.id)))] }) })] })] }));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
exports.AnimeNotFoundPage = AnimeNotFoundPage;
|