@windrun-huaiin/base-ui 14.0.0 → 14.0.1

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.
@@ -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 from-purple-600 via-pink-500 to-purple-700 bg-clip-text text-transparent select-none", style: {
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 via-purple-500/10 to-transparent animate-pulse" }) })] }), 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: "w-1 h-1 bg-purple-500 rounded-full animate-ping" }), 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: {
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-1 h-1 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 bg-purple-500/20 rounded-full animate-bounce", style: {
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 from-purple-600 via-pink-500 to-purple-700 bg-clip-text text-transparent select-none", style: {
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 via-purple-500/10 to-transparent animate-pulse" }) })] }), 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: "w-1 h-1 bg-purple-500 rounded-full animate-ping" }), 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: {
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-1 h-1 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 bg-purple-500/20 rounded-full animate-bounce", style: {
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: `h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border border-purple-500 ring-purple-500/20 ${themeUtil.themeIconColor}` }));
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: `h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border border-purple-500 ring-purple-500/20 ${themeUtil.themeIconColor}` }));
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: `h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border border-purple-500 ring-purple-500/20 ${themeIconColor}` }));
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: `h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border border-purple-500 ring-purple-500/20 ${themeIconColor}` }));
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;
@@ -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';
@@ -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 (Tailwind class only)
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
- export type SupportedThemeColor = keyof typeof THEME_COLOR_HEX_MAP;
10
- export type SupportedThemeName = keyof typeof THEME_COLOR_NAME_TO_CLASS_MAP;
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 {};
@@ -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 (Tailwind class only)
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": "#AC62FD",
22
- "text-orange-500": "#F97316",
23
- "text-indigo-500": "#6366F1",
24
- "text-emerald-500": "#10B981",
25
- "text-rose-500": "#F43F5E",
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: "text-purple-500",
30
- orange: "text-orange-500",
31
- indigo: "text-indigo-500",
32
- emerald: "text-emerald-500",
33
- rose: "text-rose-500",
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 icon text color (type-safe, global)
43
- const themeIconColor = (() => {
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 text-purple-500.
56
- Supported names: ${Object.keys(THEME_COLOR_NAME_TO_CLASS_MAP).join(", ")}
57
- Supported classes(legacy): ${Object.keys(THEME_COLOR_HEX_MAP).join(", ")}`);
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;
@@ -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 (Tailwind class only)
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": "#AC62FD",
20
- "text-orange-500": "#F97316",
21
- "text-indigo-500": "#6366F1",
22
- "text-emerald-500": "#10B981",
23
- "text-rose-500": "#F43F5E",
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: "text-purple-500",
28
- orange: "text-orange-500",
29
- indigo: "text-indigo-500",
30
- emerald: "text-emerald-500",
31
- rose: "text-rose-500",
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 icon text color (type-safe, global)
41
- const themeIconColor = (() => {
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 text-purple-500.
54
- Supported names: ${Object.keys(THEME_COLOR_NAME_TO_CLASS_MAP).join(", ")}
55
- Supported classes(legacy): ${Object.keys(THEME_COLOR_HEX_MAP).join(", ")}`);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windrun-huaiin/base-ui",
3
- "version": "14.0.0",
3
+ "version": "14.0.1",
4
4
  "description": "Base UI components for windrun-huaiin projects",
5
5
  "type": "module",
6
6
  "exports": {
@@ -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 from-purple-600 via-pink-500 to-purple-700 bg-clip-text text-transparent select-none"
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 via-purple-500/10 to-transparent animate-pulse" />
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-1 h-1 bg-purple-500 rounded-full animate-ping" />
73
+ <div className={cn("w-1 h-1 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 bg-purple-500/20 rounded-full animate-bounce"
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={`h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border border-purple-500 ring-purple-500/20 ${themeIconColor}`} />
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={`h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border border-purple-500 ring-purple-500/20 ${themeIconColor}`} />
194
+ <globalLucideIcons.SquareTerminal className={cn("h-8 w-8 rounded-full p-1 shadow-lg ring-0.5 border", themeBorderColor, themeRingColor, themeIconColor)} />
195
195
  );
@@ -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 (Tailwind class only)
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
- // Define type for supported theme color classes (literal type)
11
- export type SupportedThemeColor = keyof typeof THEME_COLOR_HEX_MAP;
12
- export type SupportedThemeName = keyof typeof THEME_COLOR_NAME_TO_CLASS_MAP;
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": "#AC62FD",
26
- "text-orange-500": "#F97316",
27
- "text-indigo-500": "#6366F1",
28
- "text-emerald-500": "#10B981",
29
- "text-rose-500": "#F43F5E",
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: "text-purple-500",
35
- orange: "text-orange-500",
36
- indigo: "text-indigo-500",
37
- emerald: "text-emerald-500",
38
- rose: "text-rose-500",
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 icon text color (type-safe, global)
51
- export const themeIconColor: SupportedThemeColor = (() => {
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 text-purple-500.
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 "text-purple-500";
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