@windrun-huaiin/base-ui 14.0.0 → 14.0.2
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/components/404-page.js +5 -3
- package/dist/components/404-page.mjs +5 -3
- package/dist/components/global-icon.js +3 -2
- package/dist/components/global-icon.mjs +4 -3
- package/dist/lib/index.js +9 -0
- package/dist/lib/index.mjs +1 -1
- package/dist/lib/theme-util.d.ts +88 -3
- package/dist/lib/theme-util.js +111 -26
- package/dist/lib/theme-util.mjs +103 -27
- package/package.json +1 -1
- package/src/components/404-page.tsx +7 -5
- package/src/components/global-icon.tsx +4 -4
- package/src/lib/theme-util.ts +116 -30
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var globalIcon = require('./global-icon.js');
|
|
6
6
|
var React = require('react');
|
|
7
|
+
var themeUtil = require('../lib/theme-util.js');
|
|
8
|
+
var utils = require('@windrun-huaiin/lib/utils');
|
|
7
9
|
|
|
8
10
|
function NotFoundPage({ siteIcon }) {
|
|
9
11
|
const [glitchText, setGlitchText] = React.useState("404");
|
|
@@ -22,17 +24,17 @@ function NotFoundPage({ siteIcon }) {
|
|
|
22
24
|
}, 600); // every 1.5 seconds
|
|
23
25
|
return () => clearInterval(interval);
|
|
24
26
|
}, []);
|
|
25
|
-
return (jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center min-h-[75vh] w-full px-4 py-8", 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: "text-8xl md:text-9xl font-bold bg-linear-to-r
|
|
27
|
+
return (jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center min-h-[75vh] w-full px-4 py-8", 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", themeUtil.themeButtonGradientClass), style: {
|
|
26
28
|
fontFamily: "Montserrat, monospace",
|
|
27
29
|
textShadow: "0 0 30px rgba(172, 98, 253, 0.3)",
|
|
28
30
|
letterSpacing: "0.1em",
|
|
29
|
-
}, children: glitchText }), jsxRuntime.jsx("div", { className: "absolute inset-0 pointer-events-none", children: jsxRuntime.jsx("div", { className: "h-full w-full bg-linear-to-b from-transparent
|
|
31
|
+
}, 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 animate-pulse", themeUtil.themeViaColor) }) })] }), 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.jsxs("div", { className: "flex justify-center items-center gap-8 pt-8 opacity-60", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [siteIcon, jsxRuntime.jsx("span", { children: "Woops!" })] }), jsxRuntime.jsx("div", { className: utils.cn("w-2 h-2 rounded-full animate-ping", themeUtil.themeBgColor) }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [jsxRuntime.jsx(globalIcon.NotFoundIcon, {}), jsxRuntime.jsx("span", { children: "Error Code: 404" })] })] })] }), jsxRuntime.jsxs("div", { className: "fixed inset-0 pointer-events-none overflow-hidden -z-10", children: [jsxRuntime.jsx("div", { className: "absolute inset-0 opacity-[0.02] dark:opacity-[0.05]", style: {
|
|
30
32
|
backgroundImage: `
|
|
31
33
|
linear-gradient(rgba(172, 98, 253, 0.1) 1px, transparent 1px),
|
|
32
34
|
linear-gradient(90deg, rgba(172, 98, 253, 0.1) 1px, transparent 1px)
|
|
33
35
|
`,
|
|
34
36
|
backgroundSize: "50px 50px",
|
|
35
|
-
} }), Array.from({ length: 6 }).map((_, i) => (jsxRuntime.jsx("div", { className: "absolute w-2 h-2
|
|
37
|
+
} }), Array.from({ length: 6 }).map((_, i) => (jsxRuntime.jsx("div", { className: utils.cn("absolute w-2 h-2 rounded-full animate-bounce", themeUtil.themeBgColor), style: {
|
|
36
38
|
left: `${20 + i * 15}%`,
|
|
37
39
|
top: `${30 + (i % 3) * 20}%`,
|
|
38
40
|
animationDelay: `${i * 0.5}s`,
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { NotFoundIcon } from './global-icon.mjs';
|
|
4
4
|
import { useState, useEffect } from 'react';
|
|
5
|
+
import { themeButtonGradientClass, themeViaColor, themeBgColor } from '../lib/theme-util.mjs';
|
|
6
|
+
import { cn } from '@windrun-huaiin/lib/utils';
|
|
5
7
|
|
|
6
8
|
function NotFoundPage({ siteIcon }) {
|
|
7
9
|
const [glitchText, setGlitchText] = useState("404");
|
|
@@ -20,17 +22,17 @@ function NotFoundPage({ siteIcon }) {
|
|
|
20
22
|
}, 600); // every 1.5 seconds
|
|
21
23
|
return () => clearInterval(interval);
|
|
22
24
|
}, []);
|
|
23
|
-
return (jsxs("div", { className: "flex flex-col items-center justify-center min-h-[75vh] w-full px-4 py-8", children: [jsxs("div", { className: "text-center space-y-8 max-w-2xl", children: [jsxs("div", { className: "relative flex justify-center", children: [jsx("h1", { className: "text-8xl md:text-9xl font-bold bg-linear-to-r
|
|
25
|
+
return (jsxs("div", { className: "flex flex-col items-center justify-center min-h-[75vh] w-full px-4 py-8", 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", themeButtonGradientClass), style: {
|
|
24
26
|
fontFamily: "Montserrat, monospace",
|
|
25
27
|
textShadow: "0 0 30px rgba(172, 98, 253, 0.3)",
|
|
26
28
|
letterSpacing: "0.1em",
|
|
27
|
-
}, children: glitchText }), jsx("div", { className: "absolute inset-0 pointer-events-none", children: jsx("div", { className: "h-full w-full bg-linear-to-b from-transparent
|
|
29
|
+
}, 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 animate-pulse", themeViaColor) }) })] }), 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" })] }), jsxs("div", { className: "flex justify-center items-center gap-8 pt-8 opacity-60", children: [jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [siteIcon, jsx("span", { children: "Woops!" })] }), jsx("div", { className: cn("w-2 h-2 rounded-full animate-ping", themeBgColor) }), jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [jsx(NotFoundIcon, {}), jsx("span", { children: "Error Code: 404" })] })] })] }), jsxs("div", { className: "fixed inset-0 pointer-events-none overflow-hidden -z-10", children: [jsx("div", { className: "absolute inset-0 opacity-[0.02] dark:opacity-[0.05]", style: {
|
|
28
30
|
backgroundImage: `
|
|
29
31
|
linear-gradient(rgba(172, 98, 253, 0.1) 1px, transparent 1px),
|
|
30
32
|
linear-gradient(90deg, rgba(172, 98, 253, 0.1) 1px, transparent 1px)
|
|
31
33
|
`,
|
|
32
34
|
backgroundSize: "50px 50px",
|
|
33
|
-
} }), Array.from({ length: 6 }).map((_, i) => (jsx("div", { className: "absolute w-2 h-2
|
|
35
|
+
} }), Array.from({ length: 6 }).map((_, i) => (jsx("div", { className: cn("absolute w-2 h-2 rounded-full animate-bounce", themeBgColor), style: {
|
|
34
36
|
left: `${20 + i * 15}%`,
|
|
35
37
|
top: `${30 + (i % 3) * 20}%`,
|
|
36
38
|
animationDelay: `${i * 0.5}s`,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var index = require('../assets/index.js');
|
|
5
5
|
var themeUtil = require('../lib/theme-util.js');
|
|
6
|
+
var utils = require('@windrun-huaiin/lib/utils');
|
|
6
7
|
var limitedLucideIcons = require('./limited-lucide-icons.js');
|
|
7
8
|
var React = require('react');
|
|
8
9
|
|
|
@@ -107,10 +108,10 @@ function getIconElement(icon) {
|
|
|
107
108
|
return getGlobalIcon(icon, true);
|
|
108
109
|
}
|
|
109
110
|
// Define the default site icon as a functional component (for export)
|
|
110
|
-
const DefaultSiteIcon = () => (jsxRuntime.jsx(globalLucideIcons.Zap, { className:
|
|
111
|
+
const DefaultSiteIcon = () => (jsxRuntime.jsx(globalLucideIcons.Zap, { className: utils.cn("h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border", themeUtil.themeBorderColor, themeUtil.themeRingColor, themeUtil.themeIconColor) }));
|
|
111
112
|
// Note: SiteIcon is available from @base-ui/lib/site-icon as a separate client component
|
|
112
113
|
// Define 404 not found icon as a functional component (fixed, no configuration)
|
|
113
|
-
const NotFoundIcon = () => (jsxRuntime.jsx(globalLucideIcons.SquareTerminal, { className:
|
|
114
|
+
const NotFoundIcon = () => (jsxRuntime.jsx(globalLucideIcons.SquareTerminal, { className: utils.cn("h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border", themeUtil.themeBorderColor, themeUtil.themeRingColor, themeUtil.themeIconColor) }));
|
|
114
115
|
|
|
115
116
|
exports.DefaultSiteIcon = DefaultSiteIcon;
|
|
116
117
|
exports.NotFoundIcon = NotFoundIcon;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { BUILTIN_ICON_COMPONENTS } from '../assets/index.mjs';
|
|
3
|
-
import { themeIconColor, themeSvgIconSize } from '../lib/theme-util.mjs';
|
|
3
|
+
import { themeBorderColor, themeRingColor, themeIconColor, themeSvgIconSize } from '../lib/theme-util.mjs';
|
|
4
|
+
import { cn } from '@windrun-huaiin/lib/utils';
|
|
4
5
|
import * as limitedLucideIcons from './limited-lucide-icons.mjs';
|
|
5
6
|
import React__default from 'react';
|
|
6
7
|
|
|
@@ -105,9 +106,9 @@ function getIconElement(icon) {
|
|
|
105
106
|
return getGlobalIcon(icon, true);
|
|
106
107
|
}
|
|
107
108
|
// Define the default site icon as a functional component (for export)
|
|
108
|
-
const DefaultSiteIcon = () => (jsx(globalLucideIcons.Zap, { className:
|
|
109
|
+
const DefaultSiteIcon = () => (jsx(globalLucideIcons.Zap, { className: cn("h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border", themeBorderColor, themeRingColor, themeIconColor) }));
|
|
109
110
|
// Note: SiteIcon is available from @base-ui/lib/site-icon as a separate client component
|
|
110
111
|
// Define 404 not found icon as a functional component (fixed, no configuration)
|
|
111
|
-
const NotFoundIcon = () => (jsx(globalLucideIcons.SquareTerminal, { className:
|
|
112
|
+
const NotFoundIcon = () => (jsx(globalLucideIcons.SquareTerminal, { className: cn("h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border", themeBorderColor, themeRingColor, themeIconColor) }));
|
|
112
113
|
|
|
113
114
|
export { DefaultSiteIcon, NotFoundIcon, getGlobalIcon, getIconElement, globalLucideIcons };
|
package/dist/lib/index.js
CHANGED
|
@@ -7,16 +7,25 @@ var themeUtil = require('./theme-util.js');
|
|
|
7
7
|
exports.THEME_BUTTON_GRADIENT_CLASS_MAP = themeUtil.THEME_BUTTON_GRADIENT_CLASS_MAP;
|
|
8
8
|
exports.THEME_BUTTON_GRADIENT_HOVER_CLASS_MAP = themeUtil.THEME_BUTTON_GRADIENT_HOVER_CLASS_MAP;
|
|
9
9
|
exports.THEME_COLOR_HEX_MAP = themeUtil.THEME_COLOR_HEX_MAP;
|
|
10
|
+
exports.THEME_COLOR_NAME_TO_BG_CLASS_MAP = themeUtil.THEME_COLOR_NAME_TO_BG_CLASS_MAP;
|
|
11
|
+
exports.THEME_COLOR_NAME_TO_BORDER_CLASS_MAP = themeUtil.THEME_COLOR_NAME_TO_BORDER_CLASS_MAP;
|
|
10
12
|
exports.THEME_COLOR_NAME_TO_CLASS_MAP = themeUtil.THEME_COLOR_NAME_TO_CLASS_MAP;
|
|
13
|
+
exports.THEME_COLOR_NAME_TO_RING_CLASS_MAP = themeUtil.THEME_COLOR_NAME_TO_RING_CLASS_MAP;
|
|
14
|
+
exports.THEME_COLOR_NAME_TO_VIA_CLASS_MAP = themeUtil.THEME_COLOR_NAME_TO_VIA_CLASS_MAP;
|
|
11
15
|
exports.THEME_HERO_EYES_ON_CLASS_MAP = themeUtil.THEME_HERO_EYES_ON_CLASS_MAP;
|
|
12
16
|
exports.THEME_RICH_TEXT_MARK_CLASS_MAP = themeUtil.THEME_RICH_TEXT_MARK_CLASS_MAP;
|
|
13
17
|
exports.__SUPPORTED_THEME_COLORS = themeUtil.__SUPPORTED_THEME_COLORS;
|
|
18
|
+
exports.themeBgColor = themeUtil.themeBgColor;
|
|
19
|
+
exports.themeBorderColor = themeUtil.themeBorderColor;
|
|
14
20
|
exports.themeButtonGradientClass = themeUtil.themeButtonGradientClass;
|
|
15
21
|
exports.themeButtonGradientHoverClass = themeUtil.themeButtonGradientHoverClass;
|
|
16
22
|
exports.themeHeroEyesOnClass = themeUtil.themeHeroEyesOnClass;
|
|
17
23
|
exports.themeIconColor = themeUtil.themeIconColor;
|
|
24
|
+
exports.themeName = themeUtil.themeName;
|
|
18
25
|
exports.themeRichTextMarkClass = themeUtil.themeRichTextMarkClass;
|
|
26
|
+
exports.themeRingColor = themeUtil.themeRingColor;
|
|
19
27
|
exports.themeSvgIconColor = themeUtil.themeSvgIconColor;
|
|
20
28
|
exports.themeSvgIconSize = themeUtil.themeSvgIconSize;
|
|
29
|
+
exports.themeViaColor = themeUtil.themeViaColor;
|
|
21
30
|
exports.validateThemeColor = themeUtil.validateThemeColor;
|
|
22
31
|
exports.validateThemeName = themeUtil.validateThemeName;
|
package/dist/lib/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { THEME_BUTTON_GRADIENT_CLASS_MAP, THEME_BUTTON_GRADIENT_HOVER_CLASS_MAP, THEME_COLOR_HEX_MAP, THEME_COLOR_NAME_TO_CLASS_MAP, THEME_HERO_EYES_ON_CLASS_MAP, THEME_RICH_TEXT_MARK_CLASS_MAP, __SUPPORTED_THEME_COLORS, themeButtonGradientClass, themeButtonGradientHoverClass, themeHeroEyesOnClass, themeIconColor, themeRichTextMarkClass, themeSvgIconColor, themeSvgIconSize, validateThemeColor, validateThemeName } from './theme-util.mjs';
|
|
1
|
+
export { THEME_BUTTON_GRADIENT_CLASS_MAP, THEME_BUTTON_GRADIENT_HOVER_CLASS_MAP, THEME_COLOR_HEX_MAP, THEME_COLOR_NAME_TO_BG_CLASS_MAP, THEME_COLOR_NAME_TO_BORDER_CLASS_MAP, THEME_COLOR_NAME_TO_CLASS_MAP, THEME_COLOR_NAME_TO_RING_CLASS_MAP, THEME_COLOR_NAME_TO_VIA_CLASS_MAP, THEME_HERO_EYES_ON_CLASS_MAP, THEME_RICH_TEXT_MARK_CLASS_MAP, __SUPPORTED_THEME_COLORS, themeBgColor, themeBorderColor, themeButtonGradientClass, themeButtonGradientHoverClass, themeHeroEyesOnClass, themeIconColor, themeName, themeRichTextMarkClass, themeRingColor, themeSvgIconColor, themeSvgIconSize, themeViaColor, validateThemeColor, validateThemeName } from './theme-util.mjs';
|
package/dist/lib/theme-util.d.ts
CHANGED
|
@@ -3,11 +3,62 @@
|
|
|
3
3
|
* Maintainer: xxx
|
|
4
4
|
* Note:
|
|
5
5
|
* 1. Static color classes for Tailwind CSS 4.x scanning
|
|
6
|
-
* 2. Single config: NEXT_PUBLIC_STYLE_ICON_COLOR (
|
|
6
|
+
* 2. Single config: NEXT_PUBLIC_STYLE_ICON_COLOR (simple theme name only)
|
|
7
7
|
* 3. Premium/elegant color system (uppercase hex values)
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
declare const THEME_COLOR_META_MAP: Readonly<{
|
|
10
|
+
readonly purple: {
|
|
11
|
+
readonly label: "典雅紫·清";
|
|
12
|
+
readonly textColor: "text-purple-500";
|
|
13
|
+
readonly bgColor: "bg-purple-500/20";
|
|
14
|
+
readonly viaColor: "via-purple-500/20";
|
|
15
|
+
readonly ringColor: "ring-purple-500/20";
|
|
16
|
+
readonly borderColor: "border-purple-500";
|
|
17
|
+
readonly hex: "#AC62FD";
|
|
18
|
+
};
|
|
19
|
+
readonly orange: {
|
|
20
|
+
readonly label: "轻奢橙·暖";
|
|
21
|
+
readonly textColor: "text-orange-500";
|
|
22
|
+
readonly bgColor: "bg-orange-500/20";
|
|
23
|
+
readonly viaColor: "via-orange-500/20";
|
|
24
|
+
readonly ringColor: "ring-orange-500/20";
|
|
25
|
+
readonly borderColor: "border-orange-500";
|
|
26
|
+
readonly hex: "#F97316";
|
|
27
|
+
};
|
|
28
|
+
readonly indigo: {
|
|
29
|
+
readonly label: "沉稳蓝·冷";
|
|
30
|
+
readonly textColor: "text-indigo-500";
|
|
31
|
+
readonly bgColor: "bg-indigo-500/20";
|
|
32
|
+
readonly viaColor: "via-indigo-500/20";
|
|
33
|
+
readonly ringColor: "ring-indigo-500/20";
|
|
34
|
+
readonly borderColor: "border-indigo-500";
|
|
35
|
+
readonly hex: "#6366F1";
|
|
36
|
+
};
|
|
37
|
+
readonly emerald: {
|
|
38
|
+
readonly label: "温润绿·愈";
|
|
39
|
+
readonly textColor: "text-emerald-500";
|
|
40
|
+
readonly bgColor: "bg-emerald-500/20";
|
|
41
|
+
readonly viaColor: "via-emerald-500/20";
|
|
42
|
+
readonly ringColor: "ring-emerald-500/20";
|
|
43
|
+
readonly borderColor: "border-emerald-500";
|
|
44
|
+
readonly hex: "#10B981";
|
|
45
|
+
};
|
|
46
|
+
readonly rose: {
|
|
47
|
+
readonly label: "玫瑰红·柔";
|
|
48
|
+
readonly textColor: "text-rose-500";
|
|
49
|
+
readonly bgColor: "bg-rose-500/20";
|
|
50
|
+
readonly viaColor: "via-rose-500/20";
|
|
51
|
+
readonly ringColor: "ring-rose-500/20";
|
|
52
|
+
readonly borderColor: "border-rose-500";
|
|
53
|
+
readonly hex: "#F43F5E";
|
|
54
|
+
};
|
|
55
|
+
}>;
|
|
56
|
+
export type SupportedThemeName = keyof typeof THEME_COLOR_META_MAP;
|
|
57
|
+
export type SupportedThemeColor = (typeof THEME_COLOR_META_MAP)[SupportedThemeName]["textColor"];
|
|
58
|
+
export type SupportedThemeBgColor = (typeof THEME_COLOR_META_MAP)[SupportedThemeName]["bgColor"];
|
|
59
|
+
export type SupportedThemeViaColor = (typeof THEME_COLOR_META_MAP)[SupportedThemeName]["viaColor"];
|
|
60
|
+
export type SupportedThemeRingColor = (typeof THEME_COLOR_META_MAP)[SupportedThemeName]["ringColor"];
|
|
61
|
+
export type SupportedThemeBorderColor = (typeof THEME_COLOR_META_MAP)[SupportedThemeName]["borderColor"];
|
|
11
62
|
export declare const __SUPPORTED_THEME_COLORS: Readonly<{
|
|
12
63
|
readonly "text-purple-500": "典雅紫·清";
|
|
13
64
|
readonly "text-orange-500": "轻奢橙·暖";
|
|
@@ -29,9 +80,42 @@ export declare const THEME_COLOR_NAME_TO_CLASS_MAP: Readonly<{
|
|
|
29
80
|
readonly emerald: "text-emerald-500";
|
|
30
81
|
readonly rose: "text-rose-500";
|
|
31
82
|
}>;
|
|
83
|
+
export declare const THEME_COLOR_NAME_TO_BG_CLASS_MAP: Readonly<{
|
|
84
|
+
readonly purple: "bg-purple-500/20";
|
|
85
|
+
readonly orange: "bg-orange-500/20";
|
|
86
|
+
readonly indigo: "bg-indigo-500/20";
|
|
87
|
+
readonly emerald: "bg-emerald-500/20";
|
|
88
|
+
readonly rose: "bg-rose-500/20";
|
|
89
|
+
}>;
|
|
90
|
+
export declare const THEME_COLOR_NAME_TO_VIA_CLASS_MAP: Readonly<{
|
|
91
|
+
readonly purple: "via-purple-500/20";
|
|
92
|
+
readonly orange: "via-orange-500/20";
|
|
93
|
+
readonly indigo: "via-indigo-500/20";
|
|
94
|
+
readonly emerald: "via-emerald-500/20";
|
|
95
|
+
readonly rose: "via-rose-500/20";
|
|
96
|
+
}>;
|
|
97
|
+
export declare const THEME_COLOR_NAME_TO_RING_CLASS_MAP: Readonly<{
|
|
98
|
+
readonly purple: "ring-purple-500/20";
|
|
99
|
+
readonly orange: "ring-orange-500/20";
|
|
100
|
+
readonly indigo: "ring-indigo-500/20";
|
|
101
|
+
readonly emerald: "ring-emerald-500/20";
|
|
102
|
+
readonly rose: "ring-rose-500/20";
|
|
103
|
+
}>;
|
|
104
|
+
export declare const THEME_COLOR_NAME_TO_BORDER_CLASS_MAP: Readonly<{
|
|
105
|
+
readonly purple: "border-purple-500";
|
|
106
|
+
readonly orange: "border-orange-500";
|
|
107
|
+
readonly indigo: "border-indigo-500";
|
|
108
|
+
readonly emerald: "border-emerald-500";
|
|
109
|
+
readonly rose: "border-rose-500";
|
|
110
|
+
}>;
|
|
32
111
|
export declare const validateThemeColor: (colorClass: string) => colorClass is SupportedThemeColor;
|
|
33
112
|
export declare const validateThemeName: (colorName: string) => colorName is SupportedThemeName;
|
|
113
|
+
export declare const themeName: SupportedThemeName;
|
|
34
114
|
export declare const themeIconColor: SupportedThemeColor;
|
|
115
|
+
export declare const themeBgColor: SupportedThemeBgColor;
|
|
116
|
+
export declare const themeViaColor: SupportedThemeViaColor;
|
|
117
|
+
export declare const themeRingColor: SupportedThemeRingColor;
|
|
118
|
+
export declare const themeBorderColor: SupportedThemeBorderColor;
|
|
35
119
|
export declare const themeSvgIconColor: "#AC62FD" | "#F97316" | "#6366F1" | "#10B981" | "#F43F5E";
|
|
36
120
|
export declare const themeSvgIconSize: string | number;
|
|
37
121
|
export declare const THEME_BUTTON_GRADIENT_CLASS_MAP: Readonly<{
|
|
@@ -66,3 +150,4 @@ export declare const THEME_RICH_TEXT_MARK_CLASS_MAP: Readonly<{
|
|
|
66
150
|
readonly "text-rose-500": "bg-rose-300 dark:bg-rose-600";
|
|
67
151
|
}>;
|
|
68
152
|
export declare const themeRichTextMarkClass: "bg-purple-300 dark:bg-purple-600" | "bg-orange-300 dark:bg-orange-600" | "bg-indigo-300 dark:bg-indigo-600" | "bg-emerald-300 dark:bg-emerald-600" | "bg-rose-300 dark:bg-rose-600";
|
|
153
|
+
export {};
|
package/dist/lib/theme-util.js
CHANGED
|
@@ -5,32 +5,107 @@
|
|
|
5
5
|
* Maintainer: xxx
|
|
6
6
|
* Note:
|
|
7
7
|
* 1. Static color classes for Tailwind CSS 4.x scanning
|
|
8
|
-
* 2. Single config: NEXT_PUBLIC_STYLE_ICON_COLOR (
|
|
8
|
+
* 2. Single config: NEXT_PUBLIC_STYLE_ICON_COLOR (simple theme name only)
|
|
9
9
|
* 3. Premium/elegant color system (uppercase hex values)
|
|
10
10
|
*/
|
|
11
|
+
const THEME_COLOR_META_MAP = Object.freeze({
|
|
12
|
+
purple: {
|
|
13
|
+
label: "典雅紫·清",
|
|
14
|
+
textColor: "text-purple-500",
|
|
15
|
+
bgColor: "bg-purple-500/20",
|
|
16
|
+
viaColor: "via-purple-500/20",
|
|
17
|
+
ringColor: "ring-purple-500/20",
|
|
18
|
+
borderColor: "border-purple-500",
|
|
19
|
+
hex: "#AC62FD",
|
|
20
|
+
},
|
|
21
|
+
orange: {
|
|
22
|
+
label: "轻奢橙·暖",
|
|
23
|
+
textColor: "text-orange-500",
|
|
24
|
+
bgColor: "bg-orange-500/20",
|
|
25
|
+
viaColor: "via-orange-500/20",
|
|
26
|
+
ringColor: "ring-orange-500/20",
|
|
27
|
+
borderColor: "border-orange-500",
|
|
28
|
+
hex: "#F97316",
|
|
29
|
+
},
|
|
30
|
+
indigo: {
|
|
31
|
+
label: "沉稳蓝·冷",
|
|
32
|
+
textColor: "text-indigo-500",
|
|
33
|
+
bgColor: "bg-indigo-500/20",
|
|
34
|
+
viaColor: "via-indigo-500/20",
|
|
35
|
+
ringColor: "ring-indigo-500/20",
|
|
36
|
+
borderColor: "border-indigo-500",
|
|
37
|
+
hex: "#6366F1",
|
|
38
|
+
},
|
|
39
|
+
emerald: {
|
|
40
|
+
label: "温润绿·愈",
|
|
41
|
+
textColor: "text-emerald-500",
|
|
42
|
+
bgColor: "bg-emerald-500/20",
|
|
43
|
+
viaColor: "via-emerald-500/20",
|
|
44
|
+
ringColor: "ring-emerald-500/20",
|
|
45
|
+
borderColor: "border-emerald-500",
|
|
46
|
+
hex: "#10B981",
|
|
47
|
+
},
|
|
48
|
+
rose: {
|
|
49
|
+
label: "玫瑰红·柔",
|
|
50
|
+
textColor: "text-rose-500",
|
|
51
|
+
bgColor: "bg-rose-500/20",
|
|
52
|
+
viaColor: "via-rose-500/20",
|
|
53
|
+
ringColor: "ring-rose-500/20",
|
|
54
|
+
borderColor: "border-rose-500",
|
|
55
|
+
hex: "#F43F5E",
|
|
56
|
+
},
|
|
57
|
+
});
|
|
11
58
|
// Supported theme color classes (static for Tailwind scan)
|
|
12
59
|
const __SUPPORTED_THEME_COLORS = Object.freeze({
|
|
13
|
-
"text-purple-500":
|
|
14
|
-
"text-orange-500":
|
|
15
|
-
"text-indigo-500":
|
|
16
|
-
"text-emerald-500":
|
|
17
|
-
"text-rose-500":
|
|
60
|
+
"text-purple-500": THEME_COLOR_META_MAP.purple.label,
|
|
61
|
+
"text-orange-500": THEME_COLOR_META_MAP.orange.label,
|
|
62
|
+
"text-indigo-500": THEME_COLOR_META_MAP.indigo.label,
|
|
63
|
+
"text-emerald-500": THEME_COLOR_META_MAP.emerald.label,
|
|
64
|
+
"text-rose-500": THEME_COLOR_META_MAP.rose.label,
|
|
18
65
|
});
|
|
19
66
|
// Hex color map (uppercase, match Tailwind classes)
|
|
20
67
|
const THEME_COLOR_HEX_MAP = Object.freeze({
|
|
21
|
-
"text-purple-500":
|
|
22
|
-
"text-orange-500":
|
|
23
|
-
"text-indigo-500":
|
|
24
|
-
"text-emerald-500":
|
|
25
|
-
"text-rose-500":
|
|
68
|
+
"text-purple-500": THEME_COLOR_META_MAP.purple.hex,
|
|
69
|
+
"text-orange-500": THEME_COLOR_META_MAP.orange.hex,
|
|
70
|
+
"text-indigo-500": THEME_COLOR_META_MAP.indigo.hex,
|
|
71
|
+
"text-emerald-500": THEME_COLOR_META_MAP.emerald.hex,
|
|
72
|
+
"text-rose-500": THEME_COLOR_META_MAP.rose.hex,
|
|
26
73
|
});
|
|
27
74
|
// Short theme names for env configuration
|
|
28
75
|
const THEME_COLOR_NAME_TO_CLASS_MAP = Object.freeze({
|
|
29
|
-
purple:
|
|
30
|
-
orange:
|
|
31
|
-
indigo:
|
|
32
|
-
emerald:
|
|
33
|
-
rose:
|
|
76
|
+
purple: THEME_COLOR_META_MAP.purple.textColor,
|
|
77
|
+
orange: THEME_COLOR_META_MAP.orange.textColor,
|
|
78
|
+
indigo: THEME_COLOR_META_MAP.indigo.textColor,
|
|
79
|
+
emerald: THEME_COLOR_META_MAP.emerald.textColor,
|
|
80
|
+
rose: THEME_COLOR_META_MAP.rose.textColor,
|
|
81
|
+
});
|
|
82
|
+
const THEME_COLOR_NAME_TO_BG_CLASS_MAP = Object.freeze({
|
|
83
|
+
purple: THEME_COLOR_META_MAP.purple.bgColor,
|
|
84
|
+
orange: THEME_COLOR_META_MAP.orange.bgColor,
|
|
85
|
+
indigo: THEME_COLOR_META_MAP.indigo.bgColor,
|
|
86
|
+
emerald: THEME_COLOR_META_MAP.emerald.bgColor,
|
|
87
|
+
rose: THEME_COLOR_META_MAP.rose.bgColor,
|
|
88
|
+
});
|
|
89
|
+
const THEME_COLOR_NAME_TO_VIA_CLASS_MAP = Object.freeze({
|
|
90
|
+
purple: THEME_COLOR_META_MAP.purple.viaColor,
|
|
91
|
+
orange: THEME_COLOR_META_MAP.orange.viaColor,
|
|
92
|
+
indigo: THEME_COLOR_META_MAP.indigo.viaColor,
|
|
93
|
+
emerald: THEME_COLOR_META_MAP.emerald.viaColor,
|
|
94
|
+
rose: THEME_COLOR_META_MAP.rose.viaColor,
|
|
95
|
+
});
|
|
96
|
+
const THEME_COLOR_NAME_TO_RING_CLASS_MAP = Object.freeze({
|
|
97
|
+
purple: THEME_COLOR_META_MAP.purple.ringColor,
|
|
98
|
+
orange: THEME_COLOR_META_MAP.orange.ringColor,
|
|
99
|
+
indigo: THEME_COLOR_META_MAP.indigo.ringColor,
|
|
100
|
+
emerald: THEME_COLOR_META_MAP.emerald.ringColor,
|
|
101
|
+
rose: THEME_COLOR_META_MAP.rose.ringColor,
|
|
102
|
+
});
|
|
103
|
+
const THEME_COLOR_NAME_TO_BORDER_CLASS_MAP = Object.freeze({
|
|
104
|
+
purple: THEME_COLOR_META_MAP.purple.borderColor,
|
|
105
|
+
orange: THEME_COLOR_META_MAP.orange.borderColor,
|
|
106
|
+
indigo: THEME_COLOR_META_MAP.indigo.borderColor,
|
|
107
|
+
emerald: THEME_COLOR_META_MAP.emerald.borderColor,
|
|
108
|
+
rose: THEME_COLOR_META_MAP.rose.borderColor,
|
|
34
109
|
});
|
|
35
110
|
// Validate theme color class (type guard)
|
|
36
111
|
const validateThemeColor = (colorClass) => {
|
|
@@ -39,24 +114,25 @@ const validateThemeColor = (colorClass) => {
|
|
|
39
114
|
const validateThemeName = (colorName) => {
|
|
40
115
|
return Object.prototype.hasOwnProperty.call(THEME_COLOR_NAME_TO_CLASS_MAP, colorName);
|
|
41
116
|
};
|
|
42
|
-
// Theme
|
|
43
|
-
const
|
|
117
|
+
// Theme name configured from env, only supports simple names like purple/orange
|
|
118
|
+
const themeName = (() => {
|
|
44
119
|
const envColorRaw = process.env.NEXT_PUBLIC_STYLE_ICON_COLOR;
|
|
45
120
|
const envColor = envColorRaw === null || envColorRaw === void 0 ? void 0 : envColorRaw.trim().toLowerCase();
|
|
46
121
|
if (envColor) {
|
|
47
122
|
if (validateThemeName(envColor)) {
|
|
48
|
-
return THEME_COLOR_NAME_TO_CLASS_MAP[envColor];
|
|
49
|
-
}
|
|
50
|
-
// backward compatible: allow old full tailwind class value
|
|
51
|
-
if (validateThemeColor(envColor)) {
|
|
52
123
|
return envColor;
|
|
53
124
|
}
|
|
54
125
|
}
|
|
55
|
-
console.warn(`[ThemeUtil] Invalid NEXT_PUBLIC_STYLE_ICON_COLOR: ${envColorRaw}. Fallback to
|
|
56
|
-
Supported names: ${Object.keys(THEME_COLOR_NAME_TO_CLASS_MAP).join(", ")}
|
|
57
|
-
|
|
58
|
-
return "text-purple-500";
|
|
126
|
+
console.warn(`[ThemeUtil] Invalid NEXT_PUBLIC_STYLE_ICON_COLOR: ${envColorRaw}. Fallback to purple.
|
|
127
|
+
Supported names: ${Object.keys(THEME_COLOR_NAME_TO_CLASS_MAP).join(", ")}`);
|
|
128
|
+
return "purple";
|
|
59
129
|
})();
|
|
130
|
+
// Theme icon text color (type-safe, global)
|
|
131
|
+
const themeIconColor = THEME_COLOR_NAME_TO_CLASS_MAP[themeName];
|
|
132
|
+
const themeBgColor = THEME_COLOR_NAME_TO_BG_CLASS_MAP[themeName];
|
|
133
|
+
const themeViaColor = THEME_COLOR_NAME_TO_VIA_CLASS_MAP[themeName];
|
|
134
|
+
const themeRingColor = THEME_COLOR_NAME_TO_RING_CLASS_MAP[themeName];
|
|
135
|
+
const themeBorderColor = THEME_COLOR_NAME_TO_BORDER_CLASS_MAP[themeName];
|
|
60
136
|
// SVG icon color (auto-derived, type-safe - NO any type)
|
|
61
137
|
const themeSvgIconColor = THEME_COLOR_HEX_MAP[themeIconColor];
|
|
62
138
|
// SVG icon size (global)
|
|
@@ -102,16 +178,25 @@ const themeRichTextMarkClass = THEME_RICH_TEXT_MARK_CLASS_MAP[themeIconColor];
|
|
|
102
178
|
exports.THEME_BUTTON_GRADIENT_CLASS_MAP = THEME_BUTTON_GRADIENT_CLASS_MAP;
|
|
103
179
|
exports.THEME_BUTTON_GRADIENT_HOVER_CLASS_MAP = THEME_BUTTON_GRADIENT_HOVER_CLASS_MAP;
|
|
104
180
|
exports.THEME_COLOR_HEX_MAP = THEME_COLOR_HEX_MAP;
|
|
181
|
+
exports.THEME_COLOR_NAME_TO_BG_CLASS_MAP = THEME_COLOR_NAME_TO_BG_CLASS_MAP;
|
|
182
|
+
exports.THEME_COLOR_NAME_TO_BORDER_CLASS_MAP = THEME_COLOR_NAME_TO_BORDER_CLASS_MAP;
|
|
105
183
|
exports.THEME_COLOR_NAME_TO_CLASS_MAP = THEME_COLOR_NAME_TO_CLASS_MAP;
|
|
184
|
+
exports.THEME_COLOR_NAME_TO_RING_CLASS_MAP = THEME_COLOR_NAME_TO_RING_CLASS_MAP;
|
|
185
|
+
exports.THEME_COLOR_NAME_TO_VIA_CLASS_MAP = THEME_COLOR_NAME_TO_VIA_CLASS_MAP;
|
|
106
186
|
exports.THEME_HERO_EYES_ON_CLASS_MAP = THEME_HERO_EYES_ON_CLASS_MAP;
|
|
107
187
|
exports.THEME_RICH_TEXT_MARK_CLASS_MAP = THEME_RICH_TEXT_MARK_CLASS_MAP;
|
|
108
188
|
exports.__SUPPORTED_THEME_COLORS = __SUPPORTED_THEME_COLORS;
|
|
189
|
+
exports.themeBgColor = themeBgColor;
|
|
190
|
+
exports.themeBorderColor = themeBorderColor;
|
|
109
191
|
exports.themeButtonGradientClass = themeButtonGradientClass;
|
|
110
192
|
exports.themeButtonGradientHoverClass = themeButtonGradientHoverClass;
|
|
111
193
|
exports.themeHeroEyesOnClass = themeHeroEyesOnClass;
|
|
112
194
|
exports.themeIconColor = themeIconColor;
|
|
195
|
+
exports.themeName = themeName;
|
|
113
196
|
exports.themeRichTextMarkClass = themeRichTextMarkClass;
|
|
197
|
+
exports.themeRingColor = themeRingColor;
|
|
114
198
|
exports.themeSvgIconColor = themeSvgIconColor;
|
|
115
199
|
exports.themeSvgIconSize = themeSvgIconSize;
|
|
200
|
+
exports.themeViaColor = themeViaColor;
|
|
116
201
|
exports.validateThemeColor = validateThemeColor;
|
|
117
202
|
exports.validateThemeName = validateThemeName;
|
package/dist/lib/theme-util.mjs
CHANGED
|
@@ -3,32 +3,107 @@
|
|
|
3
3
|
* Maintainer: xxx
|
|
4
4
|
* Note:
|
|
5
5
|
* 1. Static color classes for Tailwind CSS 4.x scanning
|
|
6
|
-
* 2. Single config: NEXT_PUBLIC_STYLE_ICON_COLOR (
|
|
6
|
+
* 2. Single config: NEXT_PUBLIC_STYLE_ICON_COLOR (simple theme name only)
|
|
7
7
|
* 3. Premium/elegant color system (uppercase hex values)
|
|
8
8
|
*/
|
|
9
|
+
const THEME_COLOR_META_MAP = Object.freeze({
|
|
10
|
+
purple: {
|
|
11
|
+
label: "典雅紫·清",
|
|
12
|
+
textColor: "text-purple-500",
|
|
13
|
+
bgColor: "bg-purple-500/20",
|
|
14
|
+
viaColor: "via-purple-500/20",
|
|
15
|
+
ringColor: "ring-purple-500/20",
|
|
16
|
+
borderColor: "border-purple-500",
|
|
17
|
+
hex: "#AC62FD",
|
|
18
|
+
},
|
|
19
|
+
orange: {
|
|
20
|
+
label: "轻奢橙·暖",
|
|
21
|
+
textColor: "text-orange-500",
|
|
22
|
+
bgColor: "bg-orange-500/20",
|
|
23
|
+
viaColor: "via-orange-500/20",
|
|
24
|
+
ringColor: "ring-orange-500/20",
|
|
25
|
+
borderColor: "border-orange-500",
|
|
26
|
+
hex: "#F97316",
|
|
27
|
+
},
|
|
28
|
+
indigo: {
|
|
29
|
+
label: "沉稳蓝·冷",
|
|
30
|
+
textColor: "text-indigo-500",
|
|
31
|
+
bgColor: "bg-indigo-500/20",
|
|
32
|
+
viaColor: "via-indigo-500/20",
|
|
33
|
+
ringColor: "ring-indigo-500/20",
|
|
34
|
+
borderColor: "border-indigo-500",
|
|
35
|
+
hex: "#6366F1",
|
|
36
|
+
},
|
|
37
|
+
emerald: {
|
|
38
|
+
label: "温润绿·愈",
|
|
39
|
+
textColor: "text-emerald-500",
|
|
40
|
+
bgColor: "bg-emerald-500/20",
|
|
41
|
+
viaColor: "via-emerald-500/20",
|
|
42
|
+
ringColor: "ring-emerald-500/20",
|
|
43
|
+
borderColor: "border-emerald-500",
|
|
44
|
+
hex: "#10B981",
|
|
45
|
+
},
|
|
46
|
+
rose: {
|
|
47
|
+
label: "玫瑰红·柔",
|
|
48
|
+
textColor: "text-rose-500",
|
|
49
|
+
bgColor: "bg-rose-500/20",
|
|
50
|
+
viaColor: "via-rose-500/20",
|
|
51
|
+
ringColor: "ring-rose-500/20",
|
|
52
|
+
borderColor: "border-rose-500",
|
|
53
|
+
hex: "#F43F5E",
|
|
54
|
+
},
|
|
55
|
+
});
|
|
9
56
|
// Supported theme color classes (static for Tailwind scan)
|
|
10
57
|
const __SUPPORTED_THEME_COLORS = Object.freeze({
|
|
11
|
-
"text-purple-500":
|
|
12
|
-
"text-orange-500":
|
|
13
|
-
"text-indigo-500":
|
|
14
|
-
"text-emerald-500":
|
|
15
|
-
"text-rose-500":
|
|
58
|
+
"text-purple-500": THEME_COLOR_META_MAP.purple.label,
|
|
59
|
+
"text-orange-500": THEME_COLOR_META_MAP.orange.label,
|
|
60
|
+
"text-indigo-500": THEME_COLOR_META_MAP.indigo.label,
|
|
61
|
+
"text-emerald-500": THEME_COLOR_META_MAP.emerald.label,
|
|
62
|
+
"text-rose-500": THEME_COLOR_META_MAP.rose.label,
|
|
16
63
|
});
|
|
17
64
|
// Hex color map (uppercase, match Tailwind classes)
|
|
18
65
|
const THEME_COLOR_HEX_MAP = Object.freeze({
|
|
19
|
-
"text-purple-500":
|
|
20
|
-
"text-orange-500":
|
|
21
|
-
"text-indigo-500":
|
|
22
|
-
"text-emerald-500":
|
|
23
|
-
"text-rose-500":
|
|
66
|
+
"text-purple-500": THEME_COLOR_META_MAP.purple.hex,
|
|
67
|
+
"text-orange-500": THEME_COLOR_META_MAP.orange.hex,
|
|
68
|
+
"text-indigo-500": THEME_COLOR_META_MAP.indigo.hex,
|
|
69
|
+
"text-emerald-500": THEME_COLOR_META_MAP.emerald.hex,
|
|
70
|
+
"text-rose-500": THEME_COLOR_META_MAP.rose.hex,
|
|
24
71
|
});
|
|
25
72
|
// Short theme names for env configuration
|
|
26
73
|
const THEME_COLOR_NAME_TO_CLASS_MAP = Object.freeze({
|
|
27
|
-
purple:
|
|
28
|
-
orange:
|
|
29
|
-
indigo:
|
|
30
|
-
emerald:
|
|
31
|
-
rose:
|
|
74
|
+
purple: THEME_COLOR_META_MAP.purple.textColor,
|
|
75
|
+
orange: THEME_COLOR_META_MAP.orange.textColor,
|
|
76
|
+
indigo: THEME_COLOR_META_MAP.indigo.textColor,
|
|
77
|
+
emerald: THEME_COLOR_META_MAP.emerald.textColor,
|
|
78
|
+
rose: THEME_COLOR_META_MAP.rose.textColor,
|
|
79
|
+
});
|
|
80
|
+
const THEME_COLOR_NAME_TO_BG_CLASS_MAP = Object.freeze({
|
|
81
|
+
purple: THEME_COLOR_META_MAP.purple.bgColor,
|
|
82
|
+
orange: THEME_COLOR_META_MAP.orange.bgColor,
|
|
83
|
+
indigo: THEME_COLOR_META_MAP.indigo.bgColor,
|
|
84
|
+
emerald: THEME_COLOR_META_MAP.emerald.bgColor,
|
|
85
|
+
rose: THEME_COLOR_META_MAP.rose.bgColor,
|
|
86
|
+
});
|
|
87
|
+
const THEME_COLOR_NAME_TO_VIA_CLASS_MAP = Object.freeze({
|
|
88
|
+
purple: THEME_COLOR_META_MAP.purple.viaColor,
|
|
89
|
+
orange: THEME_COLOR_META_MAP.orange.viaColor,
|
|
90
|
+
indigo: THEME_COLOR_META_MAP.indigo.viaColor,
|
|
91
|
+
emerald: THEME_COLOR_META_MAP.emerald.viaColor,
|
|
92
|
+
rose: THEME_COLOR_META_MAP.rose.viaColor,
|
|
93
|
+
});
|
|
94
|
+
const THEME_COLOR_NAME_TO_RING_CLASS_MAP = Object.freeze({
|
|
95
|
+
purple: THEME_COLOR_META_MAP.purple.ringColor,
|
|
96
|
+
orange: THEME_COLOR_META_MAP.orange.ringColor,
|
|
97
|
+
indigo: THEME_COLOR_META_MAP.indigo.ringColor,
|
|
98
|
+
emerald: THEME_COLOR_META_MAP.emerald.ringColor,
|
|
99
|
+
rose: THEME_COLOR_META_MAP.rose.ringColor,
|
|
100
|
+
});
|
|
101
|
+
const THEME_COLOR_NAME_TO_BORDER_CLASS_MAP = Object.freeze({
|
|
102
|
+
purple: THEME_COLOR_META_MAP.purple.borderColor,
|
|
103
|
+
orange: THEME_COLOR_META_MAP.orange.borderColor,
|
|
104
|
+
indigo: THEME_COLOR_META_MAP.indigo.borderColor,
|
|
105
|
+
emerald: THEME_COLOR_META_MAP.emerald.borderColor,
|
|
106
|
+
rose: THEME_COLOR_META_MAP.rose.borderColor,
|
|
32
107
|
});
|
|
33
108
|
// Validate theme color class (type guard)
|
|
34
109
|
const validateThemeColor = (colorClass) => {
|
|
@@ -37,24 +112,25 @@ const validateThemeColor = (colorClass) => {
|
|
|
37
112
|
const validateThemeName = (colorName) => {
|
|
38
113
|
return Object.prototype.hasOwnProperty.call(THEME_COLOR_NAME_TO_CLASS_MAP, colorName);
|
|
39
114
|
};
|
|
40
|
-
// Theme
|
|
41
|
-
const
|
|
115
|
+
// Theme name configured from env, only supports simple names like purple/orange
|
|
116
|
+
const themeName = (() => {
|
|
42
117
|
const envColorRaw = process.env.NEXT_PUBLIC_STYLE_ICON_COLOR;
|
|
43
118
|
const envColor = envColorRaw === null || envColorRaw === void 0 ? void 0 : envColorRaw.trim().toLowerCase();
|
|
44
119
|
if (envColor) {
|
|
45
120
|
if (validateThemeName(envColor)) {
|
|
46
|
-
return THEME_COLOR_NAME_TO_CLASS_MAP[envColor];
|
|
47
|
-
}
|
|
48
|
-
// backward compatible: allow old full tailwind class value
|
|
49
|
-
if (validateThemeColor(envColor)) {
|
|
50
121
|
return envColor;
|
|
51
122
|
}
|
|
52
123
|
}
|
|
53
|
-
console.warn(`[ThemeUtil] Invalid NEXT_PUBLIC_STYLE_ICON_COLOR: ${envColorRaw}. Fallback to
|
|
54
|
-
Supported names: ${Object.keys(THEME_COLOR_NAME_TO_CLASS_MAP).join(", ")}
|
|
55
|
-
|
|
56
|
-
return "text-purple-500";
|
|
124
|
+
console.warn(`[ThemeUtil] Invalid NEXT_PUBLIC_STYLE_ICON_COLOR: ${envColorRaw}. Fallback to purple.
|
|
125
|
+
Supported names: ${Object.keys(THEME_COLOR_NAME_TO_CLASS_MAP).join(", ")}`);
|
|
126
|
+
return "purple";
|
|
57
127
|
})();
|
|
128
|
+
// Theme icon text color (type-safe, global)
|
|
129
|
+
const themeIconColor = THEME_COLOR_NAME_TO_CLASS_MAP[themeName];
|
|
130
|
+
const themeBgColor = THEME_COLOR_NAME_TO_BG_CLASS_MAP[themeName];
|
|
131
|
+
const themeViaColor = THEME_COLOR_NAME_TO_VIA_CLASS_MAP[themeName];
|
|
132
|
+
const themeRingColor = THEME_COLOR_NAME_TO_RING_CLASS_MAP[themeName];
|
|
133
|
+
const themeBorderColor = THEME_COLOR_NAME_TO_BORDER_CLASS_MAP[themeName];
|
|
58
134
|
// SVG icon color (auto-derived, type-safe - NO any type)
|
|
59
135
|
const themeSvgIconColor = THEME_COLOR_HEX_MAP[themeIconColor];
|
|
60
136
|
// SVG icon size (global)
|
|
@@ -97,4 +173,4 @@ const THEME_RICH_TEXT_MARK_CLASS_MAP = Object.freeze({
|
|
|
97
173
|
});
|
|
98
174
|
const themeRichTextMarkClass = THEME_RICH_TEXT_MARK_CLASS_MAP[themeIconColor];
|
|
99
175
|
|
|
100
|
-
export { THEME_BUTTON_GRADIENT_CLASS_MAP, THEME_BUTTON_GRADIENT_HOVER_CLASS_MAP, THEME_COLOR_HEX_MAP, THEME_COLOR_NAME_TO_CLASS_MAP, THEME_HERO_EYES_ON_CLASS_MAP, THEME_RICH_TEXT_MARK_CLASS_MAP, __SUPPORTED_THEME_COLORS, themeButtonGradientClass, themeButtonGradientHoverClass, themeHeroEyesOnClass, themeIconColor, themeRichTextMarkClass, themeSvgIconColor, themeSvgIconSize, validateThemeColor, validateThemeName };
|
|
176
|
+
export { THEME_BUTTON_GRADIENT_CLASS_MAP, THEME_BUTTON_GRADIENT_HOVER_CLASS_MAP, THEME_COLOR_HEX_MAP, THEME_COLOR_NAME_TO_BG_CLASS_MAP, THEME_COLOR_NAME_TO_BORDER_CLASS_MAP, THEME_COLOR_NAME_TO_CLASS_MAP, THEME_COLOR_NAME_TO_RING_CLASS_MAP, THEME_COLOR_NAME_TO_VIA_CLASS_MAP, THEME_HERO_EYES_ON_CLASS_MAP, THEME_RICH_TEXT_MARK_CLASS_MAP, __SUPPORTED_THEME_COLORS, themeBgColor, themeBorderColor, themeButtonGradientClass, themeButtonGradientHoverClass, themeHeroEyesOnClass, themeIconColor, themeName, themeRichTextMarkClass, themeRingColor, themeSvgIconColor, themeSvgIconSize, themeViaColor, validateThemeColor, validateThemeName };
|
package/package.json
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { NotFoundIcon } from "@base-ui/components/global-icon";
|
|
4
4
|
import { useEffect, useState, type ReactNode } from "react";
|
|
5
|
+
import { themeBgColor, themeViaColor, themeButtonGradientClass } from "@base-ui/lib";
|
|
6
|
+
import { cn } from "@windrun-huaiin/lib/utils";
|
|
5
7
|
|
|
6
8
|
interface NotFoundPageProps {
|
|
7
9
|
siteIcon: ReactNode;
|
|
@@ -37,7 +39,7 @@ export function NotFoundPage({ siteIcon }: NotFoundPageProps) {
|
|
|
37
39
|
{/* 404 number - glitch effect */}
|
|
38
40
|
<div className="relative flex justify-center">
|
|
39
41
|
<h1
|
|
40
|
-
className="text-8xl md:text-9xl font-bold bg-linear-to-r
|
|
42
|
+
className={cn("text-8xl md:text-9xl font-bold bg-linear-to-r bg-clip-text text-transparent select-none", themeButtonGradientClass)}
|
|
41
43
|
style={{
|
|
42
44
|
fontFamily: "Montserrat, monospace",
|
|
43
45
|
textShadow: "0 0 30px rgba(172, 98, 253, 0.3)",
|
|
@@ -48,7 +50,7 @@ export function NotFoundPage({ siteIcon }: NotFoundPageProps) {
|
|
|
48
50
|
</h1>
|
|
49
51
|
{/* scan line effect */}
|
|
50
52
|
<div className="absolute inset-0 pointer-events-none">
|
|
51
|
-
<div className="h-full w-full bg-linear-to-b from-transparent
|
|
53
|
+
<div className={cn("h-full w-full bg-linear-to-b from-transparent to-transparent animate-pulse", themeViaColor)} />
|
|
52
54
|
</div>
|
|
53
55
|
</div>
|
|
54
56
|
|
|
@@ -68,7 +70,7 @@ export function NotFoundPage({ siteIcon }: NotFoundPageProps) {
|
|
|
68
70
|
{siteIcon}
|
|
69
71
|
<span>Woops!</span>
|
|
70
72
|
</div>
|
|
71
|
-
<div className="w-
|
|
73
|
+
<div className={cn("w-2 h-2 rounded-full animate-ping", themeBgColor)} />
|
|
72
74
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
|
73
75
|
<NotFoundIcon />
|
|
74
76
|
<span>Error Code: 404</span>
|
|
@@ -94,7 +96,7 @@ export function NotFoundPage({ siteIcon }: NotFoundPageProps) {
|
|
|
94
96
|
{Array.from({ length: 6 }).map((_, i) => (
|
|
95
97
|
<div
|
|
96
98
|
key={i}
|
|
97
|
-
className="absolute w-2 h-2
|
|
99
|
+
className={cn("absolute w-2 h-2 rounded-full animate-bounce", themeBgColor)}
|
|
98
100
|
style={{
|
|
99
101
|
left: `${20 + i * 15}%`,
|
|
100
102
|
top: `${30 + (i % 3) * 20}%`,
|
|
@@ -106,4 +108,4 @@ export function NotFoundPage({ siteIcon }: NotFoundPageProps) {
|
|
|
106
108
|
</div>
|
|
107
109
|
</div>
|
|
108
110
|
);
|
|
109
|
-
}
|
|
111
|
+
}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { BUILTIN_ICON_COMPONENTS } from '@base-ui/assets';
|
|
9
|
-
import { themeIconColor, themeSvgIconSize } from '@base-ui/lib/theme-util';
|
|
10
|
-
|
|
9
|
+
import { themeIconColor, themeSvgIconSize, themeBorderColor, themeRingColor } from '@base-ui/lib/theme-util';
|
|
10
|
+
import { cn } from '@windrun-huaiin/lib/utils';
|
|
11
11
|
import * as limitedIconsModule from '@base-ui/components/limited-lucide-icons';
|
|
12
12
|
import { type LucideProps } from 'lucide-react';
|
|
13
13
|
import React from 'react';
|
|
@@ -184,12 +184,12 @@ export function getIconElement(
|
|
|
184
184
|
|
|
185
185
|
// Define the default site icon as a functional component (for export)
|
|
186
186
|
export const DefaultSiteIcon = () => (
|
|
187
|
-
<globalLucideIcons.Zap className={
|
|
187
|
+
<globalLucideIcons.Zap className={cn("h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border", themeBorderColor, themeRingColor, themeIconColor)} />
|
|
188
188
|
);
|
|
189
189
|
|
|
190
190
|
// Note: SiteIcon is available from @base-ui/lib/site-icon as a separate client component
|
|
191
191
|
|
|
192
192
|
// Define 404 not found icon as a functional component (fixed, no configuration)
|
|
193
193
|
export const NotFoundIcon = () => (
|
|
194
|
-
<globalLucideIcons.SquareTerminal className={
|
|
194
|
+
<globalLucideIcons.SquareTerminal className={cn("h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border", themeBorderColor, themeRingColor, themeIconColor)} />
|
|
195
195
|
);
|
package/src/lib/theme-util.ts
CHANGED
|
@@ -3,39 +3,122 @@
|
|
|
3
3
|
* Maintainer: xxx
|
|
4
4
|
* Note:
|
|
5
5
|
* 1. Static color classes for Tailwind CSS 4.x scanning
|
|
6
|
-
* 2. Single config: NEXT_PUBLIC_STYLE_ICON_COLOR (
|
|
6
|
+
* 2. Single config: NEXT_PUBLIC_STYLE_ICON_COLOR (simple theme name only)
|
|
7
7
|
* 3. Premium/elegant color system (uppercase hex values)
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const THEME_COLOR_META_MAP = Object.freeze({
|
|
11
|
+
purple: {
|
|
12
|
+
label: "典雅紫·清",
|
|
13
|
+
textColor: "text-purple-500",
|
|
14
|
+
bgColor: "bg-purple-500/20",
|
|
15
|
+
viaColor: "via-purple-500/20",
|
|
16
|
+
ringColor: "ring-purple-500/20",
|
|
17
|
+
borderColor: "border-purple-500",
|
|
18
|
+
hex: "#AC62FD",
|
|
19
|
+
},
|
|
20
|
+
orange: {
|
|
21
|
+
label: "轻奢橙·暖",
|
|
22
|
+
textColor: "text-orange-500",
|
|
23
|
+
bgColor: "bg-orange-500/20",
|
|
24
|
+
viaColor: "via-orange-500/20",
|
|
25
|
+
ringColor: "ring-orange-500/20",
|
|
26
|
+
borderColor: "border-orange-500",
|
|
27
|
+
hex: "#F97316",
|
|
28
|
+
},
|
|
29
|
+
indigo: {
|
|
30
|
+
label: "沉稳蓝·冷",
|
|
31
|
+
textColor: "text-indigo-500",
|
|
32
|
+
bgColor: "bg-indigo-500/20",
|
|
33
|
+
viaColor: "via-indigo-500/20",
|
|
34
|
+
ringColor: "ring-indigo-500/20",
|
|
35
|
+
borderColor: "border-indigo-500",
|
|
36
|
+
hex: "#6366F1",
|
|
37
|
+
},
|
|
38
|
+
emerald: {
|
|
39
|
+
label: "温润绿·愈",
|
|
40
|
+
textColor: "text-emerald-500",
|
|
41
|
+
bgColor: "bg-emerald-500/20",
|
|
42
|
+
viaColor: "via-emerald-500/20",
|
|
43
|
+
ringColor: "ring-emerald-500/20",
|
|
44
|
+
borderColor: "border-emerald-500",
|
|
45
|
+
hex: "#10B981",
|
|
46
|
+
},
|
|
47
|
+
rose: {
|
|
48
|
+
label: "玫瑰红·柔",
|
|
49
|
+
textColor: "text-rose-500",
|
|
50
|
+
bgColor: "bg-rose-500/20",
|
|
51
|
+
viaColor: "via-rose-500/20",
|
|
52
|
+
ringColor: "ring-rose-500/20",
|
|
53
|
+
borderColor: "border-rose-500",
|
|
54
|
+
hex: "#F43F5E",
|
|
55
|
+
},
|
|
56
|
+
} as const);
|
|
57
|
+
|
|
58
|
+
export type SupportedThemeName = keyof typeof THEME_COLOR_META_MAP;
|
|
59
|
+
export type SupportedThemeColor = (typeof THEME_COLOR_META_MAP)[SupportedThemeName]["textColor"];
|
|
60
|
+
export type SupportedThemeBgColor = (typeof THEME_COLOR_META_MAP)[SupportedThemeName]["bgColor"];
|
|
61
|
+
export type SupportedThemeViaColor = (typeof THEME_COLOR_META_MAP)[SupportedThemeName]["viaColor"];
|
|
62
|
+
export type SupportedThemeRingColor = (typeof THEME_COLOR_META_MAP)[SupportedThemeName]["ringColor"];
|
|
63
|
+
export type SupportedThemeBorderColor = (typeof THEME_COLOR_META_MAP)[SupportedThemeName]["borderColor"];
|
|
13
64
|
|
|
14
65
|
// Supported theme color classes (static for Tailwind scan)
|
|
15
66
|
export const __SUPPORTED_THEME_COLORS = Object.freeze({
|
|
16
|
-
"text-purple-500":
|
|
17
|
-
"text-orange-500":
|
|
18
|
-
"text-indigo-500":
|
|
19
|
-
"text-emerald-500":
|
|
20
|
-
"text-rose-500":
|
|
67
|
+
"text-purple-500": THEME_COLOR_META_MAP.purple.label,
|
|
68
|
+
"text-orange-500": THEME_COLOR_META_MAP.orange.label,
|
|
69
|
+
"text-indigo-500": THEME_COLOR_META_MAP.indigo.label,
|
|
70
|
+
"text-emerald-500": THEME_COLOR_META_MAP.emerald.label,
|
|
71
|
+
"text-rose-500": THEME_COLOR_META_MAP.rose.label,
|
|
21
72
|
} as const);
|
|
22
73
|
|
|
23
74
|
// Hex color map (uppercase, match Tailwind classes)
|
|
24
75
|
export const THEME_COLOR_HEX_MAP = Object.freeze({
|
|
25
|
-
"text-purple-500":
|
|
26
|
-
"text-orange-500":
|
|
27
|
-
"text-indigo-500":
|
|
28
|
-
"text-emerald-500":
|
|
29
|
-
"text-rose-500":
|
|
76
|
+
"text-purple-500": THEME_COLOR_META_MAP.purple.hex,
|
|
77
|
+
"text-orange-500": THEME_COLOR_META_MAP.orange.hex,
|
|
78
|
+
"text-indigo-500": THEME_COLOR_META_MAP.indigo.hex,
|
|
79
|
+
"text-emerald-500": THEME_COLOR_META_MAP.emerald.hex,
|
|
80
|
+
"text-rose-500": THEME_COLOR_META_MAP.rose.hex,
|
|
30
81
|
} as const);
|
|
31
82
|
|
|
32
83
|
// Short theme names for env configuration
|
|
33
84
|
export const THEME_COLOR_NAME_TO_CLASS_MAP = Object.freeze({
|
|
34
|
-
purple:
|
|
35
|
-
orange:
|
|
36
|
-
indigo:
|
|
37
|
-
emerald:
|
|
38
|
-
rose:
|
|
85
|
+
purple: THEME_COLOR_META_MAP.purple.textColor,
|
|
86
|
+
orange: THEME_COLOR_META_MAP.orange.textColor,
|
|
87
|
+
indigo: THEME_COLOR_META_MAP.indigo.textColor,
|
|
88
|
+
emerald: THEME_COLOR_META_MAP.emerald.textColor,
|
|
89
|
+
rose: THEME_COLOR_META_MAP.rose.textColor,
|
|
90
|
+
} as const);
|
|
91
|
+
|
|
92
|
+
export const THEME_COLOR_NAME_TO_BG_CLASS_MAP = Object.freeze({
|
|
93
|
+
purple: THEME_COLOR_META_MAP.purple.bgColor,
|
|
94
|
+
orange: THEME_COLOR_META_MAP.orange.bgColor,
|
|
95
|
+
indigo: THEME_COLOR_META_MAP.indigo.bgColor,
|
|
96
|
+
emerald: THEME_COLOR_META_MAP.emerald.bgColor,
|
|
97
|
+
rose: THEME_COLOR_META_MAP.rose.bgColor,
|
|
98
|
+
} as const);
|
|
99
|
+
|
|
100
|
+
export const THEME_COLOR_NAME_TO_VIA_CLASS_MAP = Object.freeze({
|
|
101
|
+
purple: THEME_COLOR_META_MAP.purple.viaColor,
|
|
102
|
+
orange: THEME_COLOR_META_MAP.orange.viaColor,
|
|
103
|
+
indigo: THEME_COLOR_META_MAP.indigo.viaColor,
|
|
104
|
+
emerald: THEME_COLOR_META_MAP.emerald.viaColor,
|
|
105
|
+
rose: THEME_COLOR_META_MAP.rose.viaColor,
|
|
106
|
+
} as const);
|
|
107
|
+
|
|
108
|
+
export const THEME_COLOR_NAME_TO_RING_CLASS_MAP = Object.freeze({
|
|
109
|
+
purple: THEME_COLOR_META_MAP.purple.ringColor,
|
|
110
|
+
orange: THEME_COLOR_META_MAP.orange.ringColor,
|
|
111
|
+
indigo: THEME_COLOR_META_MAP.indigo.ringColor,
|
|
112
|
+
emerald: THEME_COLOR_META_MAP.emerald.ringColor,
|
|
113
|
+
rose: THEME_COLOR_META_MAP.rose.ringColor,
|
|
114
|
+
} as const);
|
|
115
|
+
|
|
116
|
+
export const THEME_COLOR_NAME_TO_BORDER_CLASS_MAP = Object.freeze({
|
|
117
|
+
purple: THEME_COLOR_META_MAP.purple.borderColor,
|
|
118
|
+
orange: THEME_COLOR_META_MAP.orange.borderColor,
|
|
119
|
+
indigo: THEME_COLOR_META_MAP.indigo.borderColor,
|
|
120
|
+
emerald: THEME_COLOR_META_MAP.emerald.borderColor,
|
|
121
|
+
rose: THEME_COLOR_META_MAP.rose.borderColor,
|
|
39
122
|
} as const);
|
|
40
123
|
|
|
41
124
|
// Validate theme color class (type guard)
|
|
@@ -47,28 +130,31 @@ export const validateThemeName = (colorName: string): colorName is SupportedThem
|
|
|
47
130
|
return Object.prototype.hasOwnProperty.call(THEME_COLOR_NAME_TO_CLASS_MAP, colorName);
|
|
48
131
|
};
|
|
49
132
|
|
|
50
|
-
// Theme
|
|
51
|
-
export const
|
|
133
|
+
// Theme name configured from env, only supports simple names like purple/orange
|
|
134
|
+
export const themeName: SupportedThemeName = (() => {
|
|
52
135
|
const envColorRaw = process.env.NEXT_PUBLIC_STYLE_ICON_COLOR;
|
|
53
136
|
const envColor = envColorRaw?.trim().toLowerCase();
|
|
137
|
+
|
|
54
138
|
if (envColor) {
|
|
55
139
|
if (validateThemeName(envColor)) {
|
|
56
|
-
return THEME_COLOR_NAME_TO_CLASS_MAP[envColor];
|
|
57
|
-
}
|
|
58
|
-
// backward compatible: allow old full tailwind class value
|
|
59
|
-
if (validateThemeColor(envColor)) {
|
|
60
140
|
return envColor;
|
|
61
141
|
}
|
|
62
142
|
}
|
|
63
|
-
|
|
143
|
+
|
|
64
144
|
console.warn(
|
|
65
|
-
`[ThemeUtil] Invalid NEXT_PUBLIC_STYLE_ICON_COLOR: ${envColorRaw}. Fallback to
|
|
66
|
-
Supported names: ${Object.keys(THEME_COLOR_NAME_TO_CLASS_MAP).join(", ")}
|
|
67
|
-
Supported classes(legacy): ${Object.keys(THEME_COLOR_HEX_MAP).join(", ")}`
|
|
145
|
+
`[ThemeUtil] Invalid NEXT_PUBLIC_STYLE_ICON_COLOR: ${envColorRaw}. Fallback to purple.
|
|
146
|
+
Supported names: ${Object.keys(THEME_COLOR_NAME_TO_CLASS_MAP).join(", ")}`
|
|
68
147
|
);
|
|
69
|
-
return "
|
|
148
|
+
return "purple";
|
|
70
149
|
})();
|
|
71
150
|
|
|
151
|
+
// Theme icon text color (type-safe, global)
|
|
152
|
+
export const themeIconColor: SupportedThemeColor = THEME_COLOR_NAME_TO_CLASS_MAP[themeName];
|
|
153
|
+
export const themeBgColor: SupportedThemeBgColor = THEME_COLOR_NAME_TO_BG_CLASS_MAP[themeName];
|
|
154
|
+
export const themeViaColor: SupportedThemeViaColor = THEME_COLOR_NAME_TO_VIA_CLASS_MAP[themeName];
|
|
155
|
+
export const themeRingColor: SupportedThemeRingColor = THEME_COLOR_NAME_TO_RING_CLASS_MAP[themeName];
|
|
156
|
+
export const themeBorderColor: SupportedThemeBorderColor = THEME_COLOR_NAME_TO_BORDER_CLASS_MAP[themeName];
|
|
157
|
+
|
|
72
158
|
// SVG icon color (auto-derived, type-safe - NO any type)
|
|
73
159
|
export const themeSvgIconColor = THEME_COLOR_HEX_MAP[themeIconColor];
|
|
74
160
|
|