@windrun-huaiin/third-ui 26.0.0 → 28.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/ai-prompt-textarea.d.ts +72 -0
- package/dist/ai/ai-prompt-textarea.js +114 -0
- package/dist/ai/ai-prompt-textarea.mjs +112 -0
- package/dist/ai/index.d.ts +1 -0
- package/dist/ai/index.js +2 -0
- package/dist/ai/index.mjs +1 -0
- package/dist/clerk/clerk-provider-client.js +0 -1
- package/dist/clerk/clerk-provider-client.mjs +0 -1
- package/dist/clerk/fingerprint/fingerprint-client.js +0 -4
- package/dist/clerk/fingerprint/fingerprint-client.mjs +0 -4
- package/dist/clerk/fingerprint/use-fingerprint.js +0 -6
- package/dist/clerk/fingerprint/use-fingerprint.mjs +0 -6
- package/dist/clerk/signin-with-fingerprint-client.js +0 -9
- package/dist/clerk/signin-with-fingerprint-client.mjs +0 -9
- package/dist/clerk/signup-button-with-fingerprint-client.js +0 -16
- package/dist/clerk/signup-button-with-fingerprint-client.mjs +0 -16
- package/dist/clerk/signup-with-fingerprint-client.js +0 -9
- package/dist/clerk/signup-with-fingerprint-client.mjs +0 -9
- package/dist/fuma/base/custom-header.js +10 -8
- package/dist/fuma/base/custom-header.mjs +10 -8
- package/dist/fuma/base/custom-home-layout.d.ts +0 -4
- package/dist/fuma/base/docs-root-provider.d.ts +19 -0
- package/dist/fuma/base/docs-root-provider.js +17 -0
- package/dist/fuma/base/docs-root-provider.mjs +15 -0
- package/dist/fuma/base/index.d.ts +5 -0
- package/dist/fuma/base/index.js +16 -7
- package/dist/fuma/base/index.mjs +5 -1
- package/dist/fuma/base/nav-config.d.ts +10 -0
- package/dist/fuma/base/nav-config.js +32 -0
- package/dist/fuma/base/nav-config.mjs +28 -0
- package/dist/fuma/base/site-docs-layout.d.ts +11 -0
- package/dist/fuma/base/site-docs-layout.js +15 -0
- package/dist/fuma/base/site-docs-layout.mjs +13 -0
- package/dist/fuma/base/site-home-layout.d.ts +24 -0
- package/dist/fuma/base/site-home-layout.js +16 -0
- package/dist/fuma/base/site-home-layout.mjs +14 -0
- package/dist/fuma/base/site-layout-shared.d.ts +89 -0
- package/dist/fuma/base/site-layout-shared.js +48 -0
- package/dist/fuma/base/site-layout-shared.mjs +42 -0
- package/dist/fuma/base/site-layout.d.ts +4 -116
- package/dist/fuma/base/site-layout.js +2 -2
- package/dist/fuma/base/site-layout.mjs +2 -2
- package/dist/fuma/fuma-page-genarator.d.ts +1 -1
- package/dist/fuma/fuma-page-genarator.js +65 -10
- package/dist/fuma/fuma-page-genarator.mjs +61 -6
- package/dist/fuma/llm-copy-handler.js +0 -9
- package/dist/fuma/llm-copy-handler.mjs +0 -9
- package/dist/fuma/mdx/index.d.ts +0 -1
- package/dist/fuma/mdx/index.js +0 -2
- package/dist/fuma/mdx/index.mjs +0 -1
- package/dist/fuma/mdx/suno-embed.js +3 -1
- package/dist/fuma/mdx/suno-embed.mjs +3 -1
- package/dist/fuma/mdx/toc-base.js +0 -1
- package/dist/fuma/mdx/toc-base.mjs +0 -1
- package/dist/fuma/server/features/widgets.js +5 -1
- package/dist/fuma/server/features/widgets.mjs +5 -1
- package/dist/fuma/server/llm-copy-handler.d.ts +2 -0
- package/dist/fuma/server/llm-copy-handler.js +7 -0
- package/dist/fuma/server/llm-copy-handler.mjs +1 -0
- package/dist/fuma/server/page-generator.d.ts +2 -0
- package/dist/fuma/server/page-generator.js +7 -0
- package/dist/fuma/server/page-generator.mjs +1 -0
- package/dist/lib/seo-metadata.js +3 -3
- package/dist/lib/seo-metadata.mjs +1 -1
- package/dist/lib/seo-util.js +4 -4
- package/dist/lib/seo-util.mjs +1 -1
- package/dist/lib/site-docs-helper.d.ts +51 -0
- package/dist/lib/site-docs-helper.js +68 -0
- package/dist/lib/site-docs-helper.mjs +66 -0
- package/dist/main/alert-dialog/index.js +14 -0
- package/dist/main/alert-dialog/index.mjs +5 -0
- package/dist/main/buttons/gradient-button.d.ts +20 -0
- package/dist/main/buttons/gradient-button.js +88 -0
- package/dist/main/buttons/gradient-button.mjs +86 -0
- package/dist/main/buttons/index.d.ts +3 -0
- package/dist/main/buttons/index.js +12 -0
- package/dist/main/buttons/index.mjs +4 -0
- package/dist/main/buttons/x-button.d.ts +39 -0
- package/dist/main/buttons/x-button.js +92 -0
- package/dist/main/buttons/x-button.mjs +90 -0
- package/dist/main/buttons/x-toggle-button.d.ts +32 -0
- package/dist/main/buttons/x-toggle-button.js +95 -0
- package/dist/main/buttons/x-toggle-button.mjs +74 -0
- package/dist/main/credit/credit-nav-button.js +25 -1
- package/dist/main/credit/credit-nav-button.mjs +25 -1
- package/dist/main/credit/credit-overview-client.js +3 -2
- package/dist/main/credit/credit-overview-client.mjs +3 -2
- package/dist/main/credit/index.d.ts +4 -0
- package/dist/main/credit/index.js +10 -0
- package/dist/main/credit/index.mjs +3 -0
- package/dist/main/credit/server.d.ts +2 -0
- package/dist/main/credit/server.js +7 -0
- package/dist/main/credit/server.mjs +1 -0
- package/dist/main/cta.js +4 -2
- package/dist/main/cta.mjs +4 -2
- package/dist/main/footer.js +3 -3
- package/dist/main/footer.mjs +1 -1
- package/dist/main/hero/index.d.ts +2 -0
- package/dist/main/hero/index.js +10 -0
- package/dist/main/hero/index.mjs +3 -0
- package/dist/main/home/server.d.ts +7 -0
- package/dist/main/home/server.js +19 -0
- package/dist/main/home/server.mjs +7 -0
- package/dist/main/index.d.ts +0 -15
- package/dist/main/index.js +0 -43
- package/dist/main/index.mjs +0 -21
- package/dist/main/loading/index.d.ts +1 -0
- package/dist/main/loading/index.js +9 -0
- package/dist/main/loading/index.mjs +2 -0
- package/dist/main/loading-frame/index.d.ts +1 -0
- package/dist/main/loading-frame/index.js +9 -0
- package/dist/main/loading-frame/index.mjs +2 -0
- package/dist/main/money-price/index.d.ts +4 -0
- package/dist/main/money-price/index.js +15 -0
- package/dist/main/money-price/index.mjs +4 -0
- package/dist/main/money-price/money-price-button.d.ts +1 -1
- package/dist/main/money-price/money-price-button.js +12 -9
- package/dist/main/money-price/money-price-button.mjs +12 -9
- package/dist/main/money-price/money-price-interactive.d.ts +1 -1
- package/dist/main/money-price/money-price-interactive.js +22 -25
- package/dist/main/money-price/money-price-interactive.mjs +22 -25
- package/dist/main/money-price/money-price-types.d.ts +2 -0
- package/dist/main/money-price/server.d.ts +5 -0
- package/dist/main/money-price/server.js +18 -0
- package/dist/main/money-price/server.mjs +4 -0
- package/package.json +94 -4
- package/src/ai/index.ts +1 -0
- package/src/clerk/clerk-provider-client.tsx +1 -3
- package/src/clerk/fingerprint/fingerprint-client.ts +0 -4
- package/src/clerk/fingerprint/use-fingerprint.ts +0 -6
- package/src/clerk/signin-with-fingerprint-client.tsx +0 -10
- package/src/clerk/signup-button-with-fingerprint-client.tsx +0 -17
- package/src/clerk/signup-with-fingerprint-client.tsx +0 -10
- package/src/fuma/base/custom-header.tsx +12 -8
- package/src/fuma/base/custom-home-layout.tsx +3 -6
- package/src/fuma/base/docs-root-provider.tsx +58 -0
- package/src/fuma/base/index.ts +5 -0
- package/src/fuma/base/nav-config.ts +81 -0
- package/src/fuma/base/site-docs-layout.tsx +35 -0
- package/src/fuma/base/site-home-layout.tsx +78 -0
- package/src/fuma/base/site-layout-shared.tsx +190 -0
- package/src/fuma/base/site-layout.tsx +4 -289
- package/src/fuma/fuma-banner-suit.tsx +1 -1
- package/src/fuma/fuma-page-genarator.tsx +61 -8
- package/src/fuma/llm-copy-handler.ts +0 -11
- package/src/fuma/mdx/index.ts +0 -1
- package/src/fuma/mdx/suno-embed.tsx +1 -1
- package/src/fuma/mdx/toc-base.tsx +0 -1
- package/src/fuma/mdx/toc-footer-wrapper.tsx +2 -2
- package/src/fuma/server/features/widgets.tsx +1 -1
- package/src/fuma/server/llm-copy-handler.ts +2 -0
- package/src/fuma/server/page-generator.ts +2 -0
- package/src/lib/seo-metadata.ts +1 -1
- package/src/lib/seo-util.ts +2 -2
- package/src/lib/server.ts +1 -1
- package/src/{fuma/mdx → main/buttons}/gradient-button.tsx +10 -21
- package/src/main/buttons/index.ts +5 -0
- package/src/main/{x-button.tsx → buttons/x-button.tsx} +28 -42
- package/src/main/credit/credit-nav-button.tsx +36 -3
- package/src/main/credit/credit-overview-client.tsx +1 -1
- package/src/main/credit/index.ts +11 -0
- package/src/main/credit/server.ts +7 -0
- package/src/main/cta.tsx +1 -1
- package/src/main/footer.tsx +1 -2
- package/src/main/hero/index.ts +4 -0
- package/src/main/home/server.ts +7 -0
- package/src/main/index.ts +1 -20
- package/src/main/language-detector.tsx +0 -1
- package/src/main/loading/index.ts +3 -0
- package/src/main/loading-frame/index.ts +3 -0
- package/src/main/money-price/index.ts +18 -0
- package/src/main/money-price/money-price-button.tsx +17 -9
- package/src/main/money-price/money-price-interactive.tsx +30 -25
- package/src/main/money-price/money-price-types.ts +2 -0
- package/src/main/money-price/server.ts +22 -0
- package/dist/fuma/mdx/features.d.ts +0 -8
- package/dist/fuma/mdx/features.js +0 -92
- package/dist/fuma/mdx/features.mjs +0 -85
- package/dist/fuma/mdx/image-grid.d.ts +0 -6
- package/dist/fuma/mdx/image-grid.js +0 -17
- package/dist/fuma/mdx/image-grid.mjs +0 -15
- package/dist/fuma/mdx/image-zoom.d.ts +0 -22
- package/dist/fuma/mdx/image-zoom.js +0 -39
- package/dist/fuma/mdx/image-zoom.mjs +0 -37
- package/dist/fuma/mdx/markdown-component-map.d.ts +0 -3
- package/dist/fuma/mdx/markdown-component-map.js +0 -79
- package/dist/fuma/mdx/markdown-component-map.mjs +0 -77
- package/dist/fuma/mdx/math.d.ts +0 -17
- package/dist/fuma/mdx/math.js +0 -60
- package/dist/fuma/mdx/math.mjs +0 -57
- package/dist/fuma/mdx/mermaid.d.ts +0 -13
- package/dist/fuma/mdx/mermaid.js +0 -360
- package/dist/fuma/mdx/mermaid.mjs +0 -358
- package/dist/fuma/mdx/site-mdx-components.d.ts +0 -13
- package/dist/fuma/mdx/site-mdx-components.js +0 -19
- package/dist/fuma/mdx/site-mdx-components.mjs +0 -17
- package/dist/fuma/mdx/site-mdx-presets.d.ts +0 -13
- package/dist/fuma/mdx/site-mdx-presets.js +0 -49
- package/dist/fuma/mdx/site-mdx-presets.mjs +0 -45
- package/dist/fuma/server/optional-features.d.ts +0 -6
- package/dist/fuma/server/optional-features.js +0 -17
- package/dist/fuma/server/optional-features.mjs +0 -6
- package/dist/fuma/server/site-mdx-components.d.ts +0 -13
- package/dist/fuma/server/site-mdx-components.js +0 -18
- package/dist/fuma/server/site-mdx-components.mjs +0 -16
- package/dist/fuma/server/site-mdx-presets.d.ts +0 -195
- package/dist/fuma/server/site-mdx-presets.js +0 -55
- package/dist/fuma/server/site-mdx-presets.mjs +0 -52
- /package/src/{main → ai}/ai-prompt-textarea.tsx +0 -0
- /package/src/main/{x-toggle-button.tsx → buttons/x-toggle-button.tsx} +0 -0
package/src/lib/seo-metadata.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Metadata } from 'next';
|
|
2
2
|
import { getTranslations } from 'next-intl/server';
|
|
3
|
-
import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib';
|
|
3
|
+
import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib/utils';
|
|
4
4
|
|
|
5
5
|
export interface CreateLocalizedSiteMetadataOptions {
|
|
6
6
|
locale: string;
|
package/src/lib/seo-util.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { MetadataRoute } from 'next';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib';
|
|
4
|
+
import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib/utils';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Generate robots.txt content
|
|
@@ -139,4 +139,4 @@ export function createSitemapHandler(
|
|
|
139
139
|
(sitemapHandler as any).dynamic = 'force-static';
|
|
140
140
|
|
|
141
141
|
return sitemapHandler;
|
|
142
|
-
}
|
|
142
|
+
}
|
package/src/lib/server.ts
CHANGED
|
@@ -23,12 +23,9 @@ export interface GradientButtonProps {
|
|
|
23
23
|
disabled?: boolean;
|
|
24
24
|
className?: string;
|
|
25
25
|
iconClassName?: string;
|
|
26
|
-
// for Link
|
|
27
26
|
href?: string;
|
|
28
27
|
openInNewTab?: boolean;
|
|
29
28
|
preserveReferrer?: boolean;
|
|
30
|
-
|
|
31
|
-
// for click
|
|
32
29
|
onClick?: () => void | Promise<void>;
|
|
33
30
|
loadingText?: React.ReactNode;
|
|
34
31
|
preventDoubleClick?: boolean;
|
|
@@ -52,7 +49,7 @@ export function GradientButton({
|
|
|
52
49
|
variant = 'default',
|
|
53
50
|
}: GradientButtonProps) {
|
|
54
51
|
const [isLoading, setIsLoading] = useState(false);
|
|
55
|
-
const actualLoadingText = loadingText || title?.toString().trim() || 'Loading...'
|
|
52
|
+
const actualLoadingText = loadingText || title?.toString().trim() || 'Loading...';
|
|
56
53
|
|
|
57
54
|
const defaultIconClass = "h-4 w-4";
|
|
58
55
|
const finalIconClass = cn(
|
|
@@ -60,14 +57,13 @@ export function GradientButton({
|
|
|
60
57
|
iconClassName || defaultIconClass
|
|
61
58
|
);
|
|
62
59
|
|
|
63
|
-
// set justify class according to alignment
|
|
64
60
|
const getAlignmentClass = () => {
|
|
65
61
|
switch (align) {
|
|
66
62
|
case 'center':
|
|
67
63
|
return 'justify-center';
|
|
68
64
|
case 'right':
|
|
69
65
|
return 'justify-end';
|
|
70
|
-
default:
|
|
66
|
+
default:
|
|
71
67
|
return 'justify-start';
|
|
72
68
|
}
|
|
73
69
|
};
|
|
@@ -80,11 +76,11 @@ export function GradientButton({
|
|
|
80
76
|
|
|
81
77
|
if (onClick) {
|
|
82
78
|
e.preventDefault();
|
|
83
|
-
|
|
79
|
+
|
|
84
80
|
if (preventDoubleClick) {
|
|
85
81
|
setIsLoading(true);
|
|
86
82
|
}
|
|
87
|
-
|
|
83
|
+
|
|
88
84
|
try {
|
|
89
85
|
await onClick();
|
|
90
86
|
} catch (error) {
|
|
@@ -98,10 +94,7 @@ export function GradientButton({
|
|
|
98
94
|
};
|
|
99
95
|
|
|
100
96
|
const isDisabled = disabled || isLoading;
|
|
101
|
-
|
|
102
97
|
const displayTitle = isLoading ? actualLoadingText : title;
|
|
103
|
-
|
|
104
|
-
// icon
|
|
105
98
|
const iconProvided = icon !== undefined;
|
|
106
99
|
|
|
107
100
|
const iconNode = (() => {
|
|
@@ -147,8 +140,6 @@ export function GradientButton({
|
|
|
147
140
|
? 'justify-center'
|
|
148
141
|
: 'justify-start';
|
|
149
142
|
|
|
150
|
-
// Base styles extracted from Button component + size="lg" (h-11 px-8)
|
|
151
|
-
// Removed [&_svg] constraints
|
|
152
143
|
const baseButtonStyles = "inline-flex items-center gap-2 whitespace-nowrap h-11 px-8 ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50";
|
|
153
144
|
const variantClassName = variant === 'soft'
|
|
154
145
|
? cn(
|
|
@@ -163,11 +154,11 @@ export function GradientButton({
|
|
|
163
154
|
themeIconColor,
|
|
164
155
|
'border border-neutral-200 shadow-sm hover:shadow-md hover:bg-neutral-50 dark:border-neutral-800 dark:hover:bg-neutral-800'
|
|
165
156
|
)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
157
|
+
: cn(
|
|
158
|
+
themeButtonGradientClass,
|
|
159
|
+
themeButtonGradientHoverClass,
|
|
160
|
+
'text-white shadow-lg hover:shadow-xl'
|
|
161
|
+
);
|
|
171
162
|
|
|
172
163
|
const buttonClassName = cn(
|
|
173
164
|
baseButtonStyles,
|
|
@@ -181,7 +172,6 @@ export function GradientButton({
|
|
|
181
172
|
return (
|
|
182
173
|
<div className={`flex flex-row gap-3 ${getAlignmentClass()}`}>
|
|
183
174
|
{onClick ? (
|
|
184
|
-
// for click
|
|
185
175
|
<button
|
|
186
176
|
type="button"
|
|
187
177
|
className={buttonClassName}
|
|
@@ -191,7 +181,6 @@ export function GradientButton({
|
|
|
191
181
|
{buttonContent}
|
|
192
182
|
</button>
|
|
193
183
|
) : (
|
|
194
|
-
// for Link
|
|
195
184
|
<Link
|
|
196
185
|
href={href || "#"}
|
|
197
186
|
className={cn(buttonClassName, "no-underline hover:no-underline")}
|
|
@@ -204,4 +193,4 @@ export function GradientButton({
|
|
|
204
193
|
)}
|
|
205
194
|
</div>
|
|
206
195
|
);
|
|
207
|
-
}
|
|
196
|
+
}
|
|
@@ -7,7 +7,6 @@ import { cn } from '@windrun-huaiin/lib/utils'
|
|
|
7
7
|
|
|
8
8
|
type XButtonVariant = 'default' | 'soft' | 'subtle'
|
|
9
9
|
|
|
10
|
-
// base button config
|
|
11
10
|
interface BaseButtonConfig {
|
|
12
11
|
icon: ReactNode
|
|
13
12
|
text: string
|
|
@@ -15,7 +14,6 @@ interface BaseButtonConfig {
|
|
|
15
14
|
disabled?: boolean
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
// menu item config
|
|
19
17
|
interface MenuItemConfig extends BaseButtonConfig {
|
|
20
18
|
tag?: {
|
|
21
19
|
text: string
|
|
@@ -24,7 +22,6 @@ interface MenuItemConfig extends BaseButtonConfig {
|
|
|
24
22
|
splitTopBorder?: boolean
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
// single button config
|
|
28
25
|
interface SingleButtonProps {
|
|
29
26
|
type: 'single'
|
|
30
27
|
button: BaseButtonConfig
|
|
@@ -35,7 +32,6 @@ interface SingleButtonProps {
|
|
|
35
32
|
variant?: XButtonVariant
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
// split button config
|
|
39
35
|
interface SplitButtonProps {
|
|
40
36
|
type: 'split'
|
|
41
37
|
mainButton: BaseButtonConfig
|
|
@@ -77,7 +73,6 @@ export function XButton(props: xButtonProps) {
|
|
|
77
73
|
return icon;
|
|
78
74
|
};
|
|
79
75
|
|
|
80
|
-
// click outside to close menu
|
|
81
76
|
useEffect(() => {
|
|
82
77
|
if (props.type === 'split') {
|
|
83
78
|
const handleClickOutside = (event: MouseEvent) => {
|
|
@@ -96,7 +91,6 @@ export function XButton(props: xButtonProps) {
|
|
|
96
91
|
}
|
|
97
92
|
}, [menuOpen, props.type])
|
|
98
93
|
|
|
99
|
-
// handle button click
|
|
100
94
|
const handleButtonClick = async (onClick: () => void | Promise<void>) => {
|
|
101
95
|
if (isLoading) return
|
|
102
96
|
|
|
@@ -110,7 +104,6 @@ export function XButton(props: xButtonProps) {
|
|
|
110
104
|
}
|
|
111
105
|
}
|
|
112
106
|
|
|
113
|
-
// base style class
|
|
114
107
|
const baseButtonClass = "flex items-center justify-center gap-2 px-4 py-2 text-sm font-semibold transition-colors"
|
|
115
108
|
const singleButtonVariantClass = variant === 'soft'
|
|
116
109
|
? cn(
|
|
@@ -125,7 +118,7 @@ export function XButton(props: xButtonProps) {
|
|
|
125
118
|
themeIconColor,
|
|
126
119
|
"border border-neutral-200 hover:bg-neutral-50 dark:border-neutral-800 dark:hover:bg-neutral-800"
|
|
127
120
|
)
|
|
128
|
-
|
|
121
|
+
: "bg-neutral-200 dark:bg-neutral-800 text-neutral-700 dark:text-white hover:bg-neutral-300 dark:hover:bg-neutral-700"
|
|
129
122
|
const splitMainButtonVariantClass = variant === 'soft'
|
|
130
123
|
? cn(
|
|
131
124
|
"bg-transparent hover:bg-black/5 dark:hover:bg-white/5",
|
|
@@ -136,7 +129,7 @@ export function XButton(props: xButtonProps) {
|
|
|
136
129
|
"bg-transparent hover:bg-neutral-50 dark:hover:bg-neutral-800",
|
|
137
130
|
themeIconColor
|
|
138
131
|
)
|
|
139
|
-
|
|
132
|
+
: "bg-neutral-200 dark:bg-neutral-800 text-neutral-700 dark:text-white hover:bg-neutral-300 dark:hover:bg-neutral-700"
|
|
140
133
|
const splitDropdownVariantClass = variant === 'soft'
|
|
141
134
|
? cn(
|
|
142
135
|
"bg-transparent hover:bg-black/5 dark:hover:bg-white/5 sm:border-l",
|
|
@@ -149,13 +142,12 @@ export function XButton(props: xButtonProps) {
|
|
|
149
142
|
themeIconColor,
|
|
150
143
|
"border-neutral-200 dark:border-neutral-800"
|
|
151
144
|
)
|
|
152
|
-
|
|
145
|
+
: "bg-neutral-200 dark:bg-neutral-800 text-neutral-700 dark:text-white hover:bg-neutral-300 dark:hover:bg-neutral-700 sm:border-l sm:border-neutral-300 sm:dark:border-neutral-700"
|
|
153
146
|
const disabledClass = "opacity-60 cursor-not-allowed"
|
|
154
147
|
|
|
155
148
|
if (props.type === 'single') {
|
|
156
149
|
const { button, loadingText, minWidth = 'min-w-[110px]', className = '' } = props
|
|
157
150
|
const isDisabled = button.disabled || isLoading
|
|
158
|
-
// loadingText: props.loadingText > button.text > 'Loading...'
|
|
159
151
|
const actualLoadingText = loadingText || button.text?.trim() || 'Loading...'
|
|
160
152
|
|
|
161
153
|
return (
|
|
@@ -188,36 +180,28 @@ export function XButton(props: xButtonProps) {
|
|
|
188
180
|
)
|
|
189
181
|
}
|
|
190
182
|
|
|
191
|
-
// Split button
|
|
192
183
|
const { mainButton, menuItems, loadingText, menuWidth = 'w-full sm:w-40', className = '', mainButtonClassName = '', dropdownButtonClassName = '' } = props
|
|
193
184
|
const isMainDisabled = mainButton.disabled || isLoading
|
|
194
|
-
// loadingText prioty:props.loadingText > mainButton.text > 'Loading...'
|
|
195
185
|
const actualLoadingText = loadingText || mainButton.text?.trim() || 'Loading...'
|
|
196
186
|
|
|
197
187
|
return (
|
|
198
188
|
<div className={cn(
|
|
199
189
|
"relative flex flex-row items-stretch w-full sm:w-auto rounded-full gap-0",
|
|
200
190
|
menuOpen && "z-90",
|
|
201
|
-
variant === 'soft'
|
|
202
|
-
? cn(themeBgColor, themeBorderColor, "border")
|
|
203
|
-
: variant === 'subtle'
|
|
204
|
-
? cn(themeMainBgColor, "border border-neutral-200 dark:border-neutral-800")
|
|
205
|
-
: "bg-neutral-200 dark:bg-neutral-800",
|
|
206
191
|
className
|
|
207
192
|
)}>
|
|
208
|
-
{/* left main button */}
|
|
209
193
|
<button
|
|
210
194
|
onClick={() => handleButtonClick(mainButton.onClick)}
|
|
211
195
|
disabled={isMainDisabled}
|
|
212
196
|
className={cn(
|
|
213
|
-
"min-w-0 flex-
|
|
197
|
+
"flex-1 min-w-0 sm:min-w-[100px] sm:flex-initial rounded-l-full",
|
|
214
198
|
baseButtonClass,
|
|
215
199
|
splitMainButtonVariantClass,
|
|
216
|
-
"rounded-l-full rounded-r-none",
|
|
217
200
|
isMainDisabled && disabledClass,
|
|
218
201
|
mainButtonClassName
|
|
219
202
|
)}
|
|
220
203
|
onMouseDown={e => { if (e.button === 2) e.preventDefault() }}
|
|
204
|
+
title={mainButton.text}
|
|
221
205
|
>
|
|
222
206
|
{isLoading ? (
|
|
223
207
|
<>
|
|
@@ -227,52 +211,54 @@ export function XButton(props: xButtonProps) {
|
|
|
227
211
|
) : (
|
|
228
212
|
<>
|
|
229
213
|
{renderIcon(mainButton.icon)}
|
|
230
|
-
<span
|
|
214
|
+
<span>{mainButton.text}</span>
|
|
231
215
|
</>
|
|
232
216
|
)}
|
|
233
217
|
</button>
|
|
234
218
|
|
|
235
|
-
{/* right dropdown button */}
|
|
236
219
|
<button
|
|
237
220
|
type="button"
|
|
221
|
+
onClick={() => setMenuOpen(!menuOpen)}
|
|
222
|
+
disabled={isLoading}
|
|
238
223
|
className={cn(
|
|
239
|
-
"
|
|
224
|
+
"w-12 rounded-r-full",
|
|
225
|
+
baseButtonClass,
|
|
240
226
|
splitDropdownVariantClass,
|
|
227
|
+
isLoading && disabledClass,
|
|
241
228
|
dropdownButtonClassName
|
|
242
229
|
)}
|
|
243
|
-
|
|
244
|
-
aria-label="More actions"
|
|
245
|
-
aria-expanded={menuOpen}
|
|
230
|
+
aria-label="Open menu"
|
|
246
231
|
>
|
|
247
|
-
<ChevronDownIcon className={chevronIconClass} />
|
|
232
|
+
<ChevronDownIcon className={cn(chevronIconClass, menuOpen && "rotate-180", "transition-transform")} />
|
|
248
233
|
</button>
|
|
249
234
|
|
|
250
|
-
{/* dropdown menu */}
|
|
251
235
|
{menuOpen && (
|
|
252
236
|
<div
|
|
253
237
|
ref={menuRef}
|
|
254
|
-
className={
|
|
238
|
+
className={cn(
|
|
239
|
+
"absolute top-full right-0 mt-2 bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 rounded-lg shadow-lg z-50 overflow-hidden",
|
|
240
|
+
menuWidth
|
|
241
|
+
)}
|
|
255
242
|
>
|
|
256
243
|
{menuItems.map((item, index) => (
|
|
257
244
|
<button
|
|
258
245
|
key={index}
|
|
246
|
+
type="button"
|
|
259
247
|
onClick={() => {
|
|
260
|
-
handleButtonClick(item.onClick)
|
|
261
248
|
setMenuOpen(false)
|
|
249
|
+
handleButtonClick(item.onClick)
|
|
262
250
|
}}
|
|
263
|
-
disabled={item.disabled}
|
|
264
|
-
className={
|
|
265
|
-
|
|
251
|
+
disabled={item.disabled || isLoading}
|
|
252
|
+
className={cn(
|
|
253
|
+
"w-full flex items-center gap-2 px-3 py-2 text-sm text-left hover:bg-neutral-100 dark:hover:bg-neutral-700 transition-colors",
|
|
254
|
+
item.disabled && disabledClass,
|
|
255
|
+
item.splitTopBorder && "border-t border-neutral-200 dark:border-neutral-700"
|
|
256
|
+
)}
|
|
266
257
|
>
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
<span>{item.text}</span>
|
|
270
|
-
</span>
|
|
258
|
+
{renderIcon(item.icon)}
|
|
259
|
+
<span className="flex-1">{item.text}</span>
|
|
271
260
|
{item.tag && (
|
|
272
|
-
<span
|
|
273
|
-
className="absolute right-3 top-1 text-[10px] font-semibold"
|
|
274
|
-
style={{ color: item.tag.color || '#A855F7', pointerEvents: 'none' }}
|
|
275
|
-
>
|
|
261
|
+
<span className={cn("px-1.5 py-0.5 text-xs rounded", item.tag.color || "bg-blue-100 text-blue-800")}>
|
|
276
262
|
{item.tag.text}
|
|
277
263
|
</span>
|
|
278
264
|
)}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
4
4
|
import { GemIcon, XIcon } from '@windrun-huaiin/base-ui/icons';
|
|
5
|
+
import { themeMainBgColor } from '@windrun-huaiin/base-ui/lib';
|
|
5
6
|
import {
|
|
6
7
|
AlertDialog,
|
|
7
8
|
AlertDialogContent,
|
|
@@ -21,7 +22,9 @@ import {
|
|
|
21
22
|
useState,
|
|
22
23
|
} from 'react';
|
|
23
24
|
import { MoneyPriceInteractive } from '../money-price/money-price-interactive';
|
|
24
|
-
import
|
|
25
|
+
import { getActiveProviderConfigUtil } from '../money-price/money-price-config-util';
|
|
26
|
+
import type { MoneyPriceData, SubscriptionProductConfig } from '../money-price/money-price-types';
|
|
27
|
+
import { dialogThemedOverlayClass } from '../alert-dialog/dialog-styles';
|
|
25
28
|
import type { CreditPricingContext, PricingModalMode } from './types';
|
|
26
29
|
|
|
27
30
|
interface CreditNavButtonProps {
|
|
@@ -172,6 +175,30 @@ export function CreditNavButton({
|
|
|
172
175
|
);
|
|
173
176
|
|
|
174
177
|
const isOnetimeModal = pricingModal.mode === 'onetime';
|
|
178
|
+
const modalInitialBillingType = useMemo(() => {
|
|
179
|
+
if (isOnetimeModal) {
|
|
180
|
+
return 'onetime';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const pricingContext = pricingModal.pricingContext;
|
|
184
|
+
const priceId = pricingContext?.initUserContext?.xSubscription?.priceId;
|
|
185
|
+
if (!pricingContext || !priceId) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const providerConfig = getActiveProviderConfigUtil(pricingContext.moneyPriceConfig);
|
|
190
|
+
const products: Record<string, SubscriptionProductConfig> =
|
|
191
|
+
providerConfig.subscriptionProducts || providerConfig.products || {};
|
|
192
|
+
for (const product of Object.values(products)) {
|
|
193
|
+
for (const [billingType, plan] of Object.entries(product.plans)) {
|
|
194
|
+
if (plan.priceId === priceId) {
|
|
195
|
+
return billingType;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return undefined;
|
|
201
|
+
}, [isOnetimeModal, pricingModal.pricingContext]);
|
|
175
202
|
|
|
176
203
|
return (
|
|
177
204
|
<CreditNavPopoverContext.Provider value={contextValue}>
|
|
@@ -225,7 +252,13 @@ export function CreditNavButton({
|
|
|
225
252
|
}))
|
|
226
253
|
}
|
|
227
254
|
>
|
|
228
|
-
<AlertDialogContent
|
|
255
|
+
<AlertDialogContent
|
|
256
|
+
className={cn(
|
|
257
|
+
'mt-5 sm:mt-6 md:mt-10 lg:mt-15 w-[95vw] max-w-[1200px] overflow-hidden border border-slate-200 p-0 shadow-[0_32px_90px_rgba(15,23,42,0.25)] ring-1 ring-black/5 dark:border-white/12 dark:shadow-[0_40px_120px_rgba(0,0,0,0.6)] dark:ring-white/10',
|
|
258
|
+
themeMainBgColor,
|
|
259
|
+
)}
|
|
260
|
+
overlayClassName={dialogThemedOverlayClass}
|
|
261
|
+
>
|
|
229
262
|
<AlertDialogHeader className="flex flex-row items-center justify-between border-b border-slate-200 px-6 pt-4 pb-1 dark:border-slate-800">
|
|
230
263
|
<AlertDialogTitle asChild>
|
|
231
264
|
<div className="flex flex-wrap items-baseline gap-3 text-slate-900 dark:text-white">
|
|
@@ -256,7 +289,7 @@ export function CreditNavButton({
|
|
|
256
289
|
checkoutApiEndpoint={pricingModal.pricingContext.checkoutApiEndpoint}
|
|
257
290
|
customerPortalApiEndpoint={pricingModal.pricingContext.customerPortalApiEndpoint}
|
|
258
291
|
enableSubscriptionUpgrade={pricingModal.pricingContext.enableSubscriptionUpgrade}
|
|
259
|
-
initialBillingType={
|
|
292
|
+
initialBillingType={modalInitialBillingType}
|
|
260
293
|
disableAutoDetectBilling={isOnetimeModal}
|
|
261
294
|
initUserContext={pricingModal.pricingContext.initUserContext}
|
|
262
295
|
/>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
export { CreditOverviewClient } from './credit-overview-client';
|
|
4
|
+
export { CreditNavButton } from './credit-nav-button';
|
|
5
|
+
export type { CreditOverviewTranslations } from './credit-overview-client';
|
|
6
|
+
export type {
|
|
7
|
+
CreditOverviewData,
|
|
8
|
+
CreditBucket,
|
|
9
|
+
CreditBucketStatus,
|
|
10
|
+
SubscriptionInfo,
|
|
11
|
+
} from './types';
|
package/src/main/cta.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getTranslations } from 'next-intl/server';
|
|
2
|
-
import { GradientButton } from "
|
|
2
|
+
import { GradientButton } from "./buttons";
|
|
3
3
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
4
4
|
import { themeIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
5
5
|
import { richText } from './rich-text-expert';
|
package/src/main/footer.tsx
CHANGED
|
@@ -3,9 +3,8 @@ import { MailIcon, ReceiptTextIcon, ShieldUserIcon } from '@windrun-huaiin/base-
|
|
|
3
3
|
import Link from "next/link";
|
|
4
4
|
import { FooterEmail } from './footer-email';
|
|
5
5
|
import { safeT } from '../lib/t-intl';
|
|
6
|
-
import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib';
|
|
6
|
+
import { cn, getAsNeededLocalizedUrl } from '@windrun-huaiin/lib/utils';
|
|
7
7
|
import { themeIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
8
|
-
import { cn } from '@windrun-huaiin/lib';
|
|
9
8
|
|
|
10
9
|
interface FooterData {
|
|
11
10
|
terms: string;
|
package/src/main/index.ts
CHANGED
|
@@ -1,28 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// Lightweight common client components.
|
|
4
4
|
export * from './go-to-top';
|
|
5
5
|
export * from './loading';
|
|
6
6
|
export * from './nprogress-bar';
|
|
7
|
-
export * from './alert-dialog';
|
|
8
|
-
export * from './x-button'
|
|
9
|
-
export * from './x-toggle-button'
|
|
10
|
-
export * from './ai-prompt-textarea'
|
|
11
7
|
export * from './rich-text-expert'
|
|
12
8
|
export * from './faq-interactive'
|
|
13
|
-
export * from './price-plan-interactive'
|
|
14
|
-
export * from './gallery/gallery-interactive'
|
|
15
|
-
export * from './delayed-img'
|
|
16
|
-
export * from './snake-loading-frame'
|
|
17
|
-
export * from './pill-select'
|
|
18
|
-
// Money Price Client Components
|
|
19
|
-
export { MoneyPriceInteractive } from './money-price/money-price-interactive';
|
|
20
|
-
export { MoneyPriceButton } from './money-price/money-price-button';
|
|
21
|
-
|
|
22
|
-
export { CreditOverviewClient } from './credit/credit-overview-client';
|
|
23
|
-
export { CreditNavButton } from './credit/credit-nav-button';
|
|
24
|
-
|
|
25
|
-
export { HeroMedia } from './hero-media';
|
|
26
|
-
export { HeroSection } from './hero-section';
|
|
27
|
-
|
|
28
9
|
export { InfoTooltip } from './info-tooltip';
|
|
@@ -76,7 +76,6 @@ export function LanguageDetector({ i18nConfig }: LanguageDetectorProps) {
|
|
|
76
76
|
|
|
77
77
|
// Use the automatic closing time from the configuration
|
|
78
78
|
const timer = setTimeout(() => {
|
|
79
|
-
console.log('[LanguageDetector] Auto closing after timeout')
|
|
80
79
|
setShow(false)
|
|
81
80
|
// Save the rejected state when the automatic closing occurs
|
|
82
81
|
savePreference(browserLang, 'rejected')
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
export { MoneyPriceInteractive } from './money-price-interactive';
|
|
4
|
+
export { MoneyPriceButton } from './money-price-button';
|
|
5
|
+
export type {
|
|
6
|
+
MoneyPriceConfig,
|
|
7
|
+
MoneyPriceData,
|
|
8
|
+
InitUserContext,
|
|
9
|
+
MoneyPriceInteractiveProps,
|
|
10
|
+
MoneyPriceButtonProps,
|
|
11
|
+
PaymentProvider,
|
|
12
|
+
PaymentProviderConfig,
|
|
13
|
+
EnhancePricePlan,
|
|
14
|
+
SubscriptionProductConfig,
|
|
15
|
+
CreditPackProductConfig,
|
|
16
|
+
UserContext,
|
|
17
|
+
} from './money-price-types';
|
|
18
|
+
export { UserState } from './money-price-types';
|
|
@@ -14,22 +14,25 @@ export function MoneyPriceButton({
|
|
|
14
14
|
onAction,
|
|
15
15
|
texts,
|
|
16
16
|
isProcessing = false,
|
|
17
|
+
isAnyProcessing = false,
|
|
17
18
|
isInitLoading = false,
|
|
18
19
|
enableSubscriptionUpgrade = true
|
|
19
20
|
}: MoneyPriceButtonProps) {
|
|
21
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
20
22
|
|
|
21
23
|
if (isInitLoading) {
|
|
22
24
|
return (
|
|
23
25
|
<div
|
|
24
|
-
className="w-full h-11 md:h-12 mt-4 md:mt-auto rounded-full bg-
|
|
26
|
+
className="relative w-full h-11 md:h-12 mt-4 md:mt-auto overflow-hidden rounded-full bg-gray-100/70 dark:bg-gray-800/40 animate-pulse transition-opacity duration-300 ease-out"
|
|
25
27
|
aria-hidden="true"
|
|
26
28
|
data-plan-button-placeholder={planKey}
|
|
27
|
-
|
|
29
|
+
>
|
|
30
|
+
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/50 to-transparent dark:via-white/10" />
|
|
31
|
+
</div>
|
|
28
32
|
);
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
const { isAuthenticated, subscriptionStatus } = userContext;
|
|
32
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
33
36
|
const subscriptionBilling = userContext.subscriptionType;
|
|
34
37
|
const planTier = planKey;
|
|
35
38
|
const planBilling = billingType;
|
|
@@ -224,19 +227,24 @@ export function MoneyPriceButton({
|
|
|
224
227
|
|
|
225
228
|
if (config.hidden) return null;
|
|
226
229
|
|
|
230
|
+
const hasActiveSubscription =
|
|
231
|
+
subscriptionStatus === UserState.ProUser ||
|
|
232
|
+
subscriptionStatus === UserState.UltraUser;
|
|
233
|
+
|
|
227
234
|
if (
|
|
228
235
|
!enableSubscriptionUpgrade &&
|
|
229
236
|
billingType !== 'onetime' &&
|
|
237
|
+
hasActiveSubscription &&
|
|
230
238
|
config.text === texts.upgrade &&
|
|
231
239
|
typeof config.onClick === 'function'
|
|
232
240
|
) {
|
|
233
241
|
return null;
|
|
234
242
|
}
|
|
235
243
|
|
|
236
|
-
const
|
|
237
|
-
const isDisabled = config.disabled ||
|
|
238
|
-
const displayText =
|
|
239
|
-
const isDisabledByConfigOnly = config.disabled && !
|
|
244
|
+
const isCurrentButtonBusy = isLoading || isProcessing;
|
|
245
|
+
const isDisabled = config.disabled || isCurrentButtonBusy || isAnyProcessing;
|
|
246
|
+
const displayText = isCurrentButtonBusy ? 'Processing...' : config.text;
|
|
247
|
+
const isDisabledByConfigOnly = config.disabled && !isCurrentButtonBusy && !isAnyProcessing;
|
|
240
248
|
|
|
241
249
|
const handleClick = async (e: React.MouseEvent) => {
|
|
242
250
|
if (isDisabled) {
|
|
@@ -265,9 +273,9 @@ export function MoneyPriceButton({
|
|
|
265
273
|
isDisabledByConfigOnly
|
|
266
274
|
? 'bg-gray-400 cursor-not-allowed'
|
|
267
275
|
: themeButtonGradientClass,
|
|
268
|
-
!isDisabledByConfigOnly && !
|
|
276
|
+
!isDisabledByConfigOnly && !isCurrentButtonBusy && !isAnyProcessing &&
|
|
269
277
|
themeButtonGradientHoverClass,
|
|
270
|
-
|
|
278
|
+
(isCurrentButtonBusy || isAnyProcessing) && !isDisabledByConfigOnly && 'opacity-70 cursor-not-allowed'
|
|
271
279
|
);
|
|
272
280
|
|
|
273
281
|
return (
|