@windrun-huaiin/third-ui 7.3.9 → 7.3.11
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/main/faq.js +2 -7
- package/dist/main/faq.mjs +2 -7
- package/dist/main/gallery.js +2 -7
- package/dist/main/gallery.mjs +2 -7
- package/dist/main/money-price/money-price-button.js +2 -14
- package/dist/main/money-price/money-price-button.mjs +1 -13
- package/dist/main/money-price/money-price-interactive.js +45 -43
- package/dist/main/money-price/money-price-interactive.mjs +45 -43
- package/dist/main/money-price/money-price.js +13 -1
- package/dist/main/money-price/money-price.mjs +13 -1
- package/dist/main/price-plan.js +2 -7
- package/dist/main/price-plan.mjs +2 -7
- package/dist/node_modules/.pnpm/cose-base@1.0.3/node_modules/cose-base/cose-base.js +1 -1
- package/dist/node_modules/.pnpm/cose-base@1.0.3/node_modules/cose-base/cose-base.mjs +1 -1
- package/dist/node_modules/.pnpm/cose-base@2.2.0/node_modules/cose-base/cose-base.js +1 -1
- package/dist/node_modules/.pnpm/cose-base@2.2.0/node_modules/cose-base/cose-base.mjs +1 -1
- package/dist/node_modules/.pnpm/layout-base@1.0.2/node_modules/layout-base/layout-base.js +1 -1
- package/dist/node_modules/.pnpm/layout-base@1.0.2/node_modules/layout-base/layout-base.mjs +1 -1
- package/dist/node_modules/.pnpm/layout-base@2.0.1/node_modules/layout-base/layout-base.js +1 -1
- package/dist/node_modules/.pnpm/layout-base@2.0.1/node_modules/layout-base/layout-base.mjs +1 -1
- package/package.json +3 -3
- package/src/main/money-price/money-price-button.tsx +1 -1
- package/src/main/money-price/money-price-interactive.tsx +60 -69
- package/src/main/money-price/money-price.tsx +8 -2
package/dist/main/faq.js
CHANGED
|
@@ -14,13 +14,8 @@ var faqInteractive = require('./faq-interactive.js');
|
|
|
14
14
|
require('next/navigation');
|
|
15
15
|
require('@clerk/nextjs');
|
|
16
16
|
require('../clerk/fingerprint/fingerprint-provider.js');
|
|
17
|
-
require('
|
|
18
|
-
require('
|
|
19
|
-
require('next/link');
|
|
20
|
-
require('fumadocs-ui/utils/use-copy-button');
|
|
21
|
-
require('fumadocs-core/link');
|
|
22
|
-
require('fumadocs-ui/components/ui/collapsible');
|
|
23
|
-
require('../fuma/mdx/banner.js');
|
|
17
|
+
require('react-dom');
|
|
18
|
+
require('@windrun-huaiin/third-ui/fuma/mdx');
|
|
24
19
|
require('./money-price/money-price-types.js');
|
|
25
20
|
|
|
26
21
|
function FAQ(_a) {
|
package/dist/main/faq.mjs
CHANGED
|
@@ -12,13 +12,8 @@ import { FAQInteractive } from './faq-interactive.mjs';
|
|
|
12
12
|
import 'next/navigation';
|
|
13
13
|
import '@clerk/nextjs';
|
|
14
14
|
import '../clerk/fingerprint/fingerprint-provider.mjs';
|
|
15
|
-
import '
|
|
16
|
-
import '
|
|
17
|
-
import 'next/link';
|
|
18
|
-
import 'fumadocs-ui/utils/use-copy-button';
|
|
19
|
-
import 'fumadocs-core/link';
|
|
20
|
-
import 'fumadocs-ui/components/ui/collapsible';
|
|
21
|
-
import '../fuma/mdx/banner.mjs';
|
|
15
|
+
import 'react-dom';
|
|
16
|
+
import '@windrun-huaiin/third-ui/fuma/mdx';
|
|
22
17
|
import './money-price/money-price-types.mjs';
|
|
23
18
|
|
|
24
19
|
function FAQ(_a) {
|
package/dist/main/gallery.js
CHANGED
|
@@ -14,13 +14,8 @@ require('next/navigation');
|
|
|
14
14
|
var galleryInteractive = require('./gallery-interactive.js');
|
|
15
15
|
require('@clerk/nextjs');
|
|
16
16
|
require('../clerk/fingerprint/fingerprint-provider.js');
|
|
17
|
-
require('
|
|
18
|
-
require('
|
|
19
|
-
require('next/link');
|
|
20
|
-
require('fumadocs-ui/utils/use-copy-button');
|
|
21
|
-
require('fumadocs-core/link');
|
|
22
|
-
require('fumadocs-ui/components/ui/collapsible');
|
|
23
|
-
require('../fuma/mdx/banner.js');
|
|
17
|
+
require('react-dom');
|
|
18
|
+
require('@windrun-huaiin/third-ui/fuma/mdx');
|
|
24
19
|
require('./money-price/money-price-types.js');
|
|
25
20
|
|
|
26
21
|
function Gallery(_a) {
|
package/dist/main/gallery.mjs
CHANGED
|
@@ -12,13 +12,8 @@ import 'next/navigation';
|
|
|
12
12
|
import { GalleryInteractive } from './gallery-interactive.mjs';
|
|
13
13
|
import '@clerk/nextjs';
|
|
14
14
|
import '../clerk/fingerprint/fingerprint-provider.mjs';
|
|
15
|
-
import '
|
|
16
|
-
import '
|
|
17
|
-
import 'next/link';
|
|
18
|
-
import 'fumadocs-ui/utils/use-copy-button';
|
|
19
|
-
import 'fumadocs-core/link';
|
|
20
|
-
import 'fumadocs-ui/components/ui/collapsible';
|
|
21
|
-
import '../fuma/mdx/banner.mjs';
|
|
15
|
+
import 'react-dom';
|
|
16
|
+
import '@windrun-huaiin/third-ui/fuma/mdx';
|
|
22
17
|
import './money-price/money-price-types.mjs';
|
|
23
18
|
|
|
24
19
|
function Gallery(_a) {
|
|
@@ -2,20 +2,8 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
require('
|
|
5
|
+
var mdx = require('@windrun-huaiin/third-ui/fuma/mdx');
|
|
6
6
|
var server = require('@windrun-huaiin/base-ui/components/server');
|
|
7
|
-
require('next-themes');
|
|
8
|
-
require('react');
|
|
9
|
-
require('fumadocs-core/framework');
|
|
10
|
-
require('@windrun-huaiin/lib/utils');
|
|
11
|
-
require('next/link');
|
|
12
|
-
var gradientButton = require('../../fuma/mdx/gradient-button.js');
|
|
13
|
-
require('next/navigation');
|
|
14
|
-
require('fumadocs-ui/utils/use-copy-button');
|
|
15
|
-
require('fumadocs-core/link');
|
|
16
|
-
require('@windrun-huaiin/base-ui/ui');
|
|
17
|
-
require('fumadocs-ui/components/ui/collapsible');
|
|
18
|
-
require('../../fuma/mdx/banner.js');
|
|
19
7
|
var moneyPriceTypes = require('./money-price-types.js');
|
|
20
8
|
|
|
21
9
|
function capitalize(str) {
|
|
@@ -89,7 +77,7 @@ function MoneyPriceButton({ planKey, userContext, billingType, onLogin, onUpgrad
|
|
|
89
77
|
const config = getButtonConfig();
|
|
90
78
|
if (config.hidden)
|
|
91
79
|
return null;
|
|
92
|
-
return (jsxRuntime.jsx(
|
|
80
|
+
return (jsxRuntime.jsx(mdx.GradientButton, { title: config.text, icon: config.icon, onClick: config.onClick, disabled: config.disabled || isProcessing, align: "center", className: "w-full", preventDoubleClick: true, loadingText: "Processing..." }));
|
|
93
81
|
}
|
|
94
82
|
|
|
95
83
|
exports.MoneyPriceButton = MoneyPriceButton;
|
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
import '
|
|
3
|
+
import { GradientButton } from '@windrun-huaiin/third-ui/fuma/mdx';
|
|
4
4
|
import { globalLucideIcons } from '@windrun-huaiin/base-ui/components/server';
|
|
5
|
-
import 'next-themes';
|
|
6
|
-
import 'react';
|
|
7
|
-
import 'fumadocs-core/framework';
|
|
8
|
-
import '@windrun-huaiin/lib/utils';
|
|
9
|
-
import 'next/link';
|
|
10
|
-
import { GradientButton } from '../../fuma/mdx/gradient-button.mjs';
|
|
11
|
-
import 'next/navigation';
|
|
12
|
-
import 'fumadocs-ui/utils/use-copy-button';
|
|
13
|
-
import 'fumadocs-core/link';
|
|
14
|
-
import '@windrun-huaiin/base-ui/ui';
|
|
15
|
-
import 'fumadocs-ui/components/ui/collapsible';
|
|
16
|
-
import '../../fuma/mdx/banner.mjs';
|
|
17
5
|
import { UserState } from './money-price-types.mjs';
|
|
18
6
|
|
|
19
7
|
function capitalize(str) {
|
|
@@ -8,6 +8,7 @@ var React = require('react');
|
|
|
8
8
|
var fingerprintProvider = require('../../clerk/fingerprint/fingerprint-provider.js');
|
|
9
9
|
var utils = require('@windrun-huaiin/lib/utils');
|
|
10
10
|
var navigation = require('next/navigation');
|
|
11
|
+
var ReactDOM = require('react-dom');
|
|
11
12
|
var moneyPriceButton = require('./money-price-button.js');
|
|
12
13
|
var moneyPriceConfigUtil = require('./money-price-config-util.js');
|
|
13
14
|
var moneyPriceTypes = require('./money-price-types.js');
|
|
@@ -131,55 +132,47 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
|
|
|
131
132
|
if (priceDiscountElement)
|
|
132
133
|
priceDiscountElement.style.display = 'none';
|
|
133
134
|
}
|
|
134
|
-
const priceSubtitleElement = document.querySelector(`[data-price-subtitle="${plan.key}"]`);
|
|
135
|
-
if (priceSubtitleElement && plan.showBillingSubTitle !== false) {
|
|
136
|
-
const billingOption = data.billingSwitch.options.find(opt => opt.key === newBillingType);
|
|
137
|
-
priceSubtitleElement.textContent = (billingOption === null || billingOption === void 0 ? void 0 : billingOption.subTitle) || '';
|
|
138
|
-
}
|
|
139
135
|
});
|
|
140
136
|
}, [config, data]);
|
|
141
|
-
// 更新按钮样式
|
|
142
|
-
const updateButtonStyles = React.useCallback((newBillingType) => {
|
|
143
|
-
const monthlyButton = document.querySelector('[data-billing-button="monthly"]');
|
|
144
|
-
const yearlyButton = document.querySelector('[data-billing-button="yearly"]');
|
|
145
|
-
const activeClasses = 'text-white bg-gradient-to-r from-purple-400 to-pink-500 hover:from-purple-500 hover:to-pink-600 dark:from-purple-500 dark:to-pink-600 dark:hover:from-purple-600 rounded-full shadow-sm';
|
|
146
|
-
const inactiveClasses = 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full';
|
|
147
|
-
if (monthlyButton && yearlyButton) {
|
|
148
|
-
if (newBillingType === 'monthly') {
|
|
149
|
-
monthlyButton.className = utils.cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', activeClasses);
|
|
150
|
-
yearlyButton.className = utils.cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', inactiveClasses);
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
monthlyButton.className = utils.cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', inactiveClasses);
|
|
154
|
-
yearlyButton.className = utils.cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', activeClasses);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}, []);
|
|
158
137
|
// 更新折扣信息
|
|
159
138
|
const updateDiscountInfo = React.useCallback((newBillingType) => {
|
|
160
139
|
const discountInfoElement = document.querySelector('[data-discount-info]');
|
|
161
|
-
if (
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
140
|
+
if (discountInfoElement) {
|
|
141
|
+
const billingOption = data.billingSwitch.options.find(opt => opt.key === newBillingType);
|
|
142
|
+
let hasDiscount = false;
|
|
143
|
+
let discountPercent = 0;
|
|
144
|
+
const providerConfig = moneyPriceConfigUtil.getActiveProviderConfig(config);
|
|
145
|
+
['pro', 'ultra'].forEach(planKey => {
|
|
146
|
+
const pricing = providerConfig.products[planKey].plans[newBillingType];
|
|
147
|
+
if (pricing.discountPercent) {
|
|
148
|
+
hasDiscount = true;
|
|
149
|
+
discountPercent = pricing.discountPercent;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
discountInfoElement.innerHTML = '';
|
|
153
|
+
if (hasDiscount && (billingOption === null || billingOption === void 0 ? void 0 : billingOption.discountText)) {
|
|
154
|
+
const discountBadge = document.createElement('span');
|
|
155
|
+
discountBadge.className = 'px-2 py-1 text-xs rounded bg-yellow-100 text-yellow-800 font-semibold align-middle text-center inline-flex items-center justify-center whitespace-nowrap';
|
|
156
|
+
discountBadge.textContent = billingOption.discountText.replace('{percent}', String(discountPercent));
|
|
157
|
+
discountInfoElement.appendChild(discountBadge);
|
|
173
158
|
}
|
|
174
|
-
});
|
|
175
|
-
discountInfoElement.innerHTML = '';
|
|
176
|
-
if (hasDiscount && (billingOption === null || billingOption === void 0 ? void 0 : billingOption.discountText)) {
|
|
177
|
-
const discountBadge = document.createElement('span');
|
|
178
|
-
discountBadge.className = 'px-2 py-1 text-xs rounded bg-yellow-100 text-yellow-800 font-semibold align-middle text-center inline-flex items-center justify-center whitespace-nowrap';
|
|
179
|
-
discountBadge.textContent = billingOption.discountText.replace('{percent}', String(discountPercent));
|
|
180
|
-
discountInfoElement.appendChild(discountBadge);
|
|
181
159
|
}
|
|
182
160
|
}, [config, data]);
|
|
161
|
+
// 更新按钮样式
|
|
162
|
+
const updateButtonStyles = React.useCallback((newBillingType) => {
|
|
163
|
+
const monthlyButton = document.querySelector('[data-billing-button="monthly"]');
|
|
164
|
+
const yearlyButton = document.querySelector('[data-billing-button="yearly"]');
|
|
165
|
+
if (monthlyButton) {
|
|
166
|
+
monthlyButton.className = newBillingType === 'monthly'
|
|
167
|
+
? utils.cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-white bg-gradient-to-r from-purple-400 to-pink-500 hover:from-purple-500 hover:to-pink-600 dark:from-purple-500 dark:to-pink-600 dark:hover:from-purple-600 rounded-full shadow-sm')
|
|
168
|
+
: utils.cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full');
|
|
169
|
+
}
|
|
170
|
+
if (yearlyButton) {
|
|
171
|
+
yearlyButton.className = newBillingType === 'yearly'
|
|
172
|
+
? utils.cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-white bg-gradient-to-r from-purple-400 to-pink-500 hover:from-purple-500 hover:to-pink-600 dark:from-purple-500 dark:to-pink-600 dark:hover:from-purple-600 rounded-full shadow-sm')
|
|
173
|
+
: utils.cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full');
|
|
174
|
+
}
|
|
175
|
+
}, []);
|
|
183
176
|
// 处理月付/年付切换和 tooltip 功能
|
|
184
177
|
React.useEffect(() => {
|
|
185
178
|
const monthlyButton = document.querySelector('[data-billing-button="monthly"]');
|
|
@@ -233,9 +226,18 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
|
|
|
233
226
|
}
|
|
234
227
|
});
|
|
235
228
|
});
|
|
229
|
+
// Inject buttons into placeholders using createPortal
|
|
230
|
+
data.plans.forEach((plan) => {
|
|
231
|
+
const placeholder = document.querySelector(`[data-button-placeholder="${plan.key}"]`);
|
|
232
|
+
if (placeholder) {
|
|
233
|
+
console.log('MoneyPriceButton', `[data-button-placeholder="${plan.key}"]`);
|
|
234
|
+
ReactDOM.createPortal(jsxRuntime.jsx(moneyPriceButton.MoneyPriceButton, { planKey: plan.key, userContext: userContext, billingType: billingType, onLogin: handleLogin, onUpgrade: handleUpgrade, texts: data.buttonTexts, isProcessing: isProcessing }), placeholder);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
// Initial updates
|
|
236
238
|
updatePriceDisplay(billingType);
|
|
237
239
|
updateDiscountInfo(billingType);
|
|
238
|
-
|
|
240
|
+
updateButtonStyles(billingType);
|
|
239
241
|
return () => {
|
|
240
242
|
if (monthlyButton) {
|
|
241
243
|
monthlyButton.removeEventListener('click', handleMonthlyClick);
|
|
@@ -249,7 +251,7 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
|
|
|
249
251
|
element.removeEventListener('mouseleave', handlers.mouseleave);
|
|
250
252
|
});
|
|
251
253
|
};
|
|
252
|
-
}, [data, billingType, updatePriceDisplay, updateButtonStyles, updateDiscountInfo]);
|
|
254
|
+
}, [data, billingType, updatePriceDisplay, updateButtonStyles, updateDiscountInfo, userContext, handleLogin, handleUpgrade, isProcessing]);
|
|
253
255
|
// Tooltip 组件
|
|
254
256
|
const Tooltip = ({ show, content, x, y }) => {
|
|
255
257
|
if (!show)
|
|
@@ -6,6 +6,7 @@ import { useState, useCallback, useMemo, useEffect } from 'react';
|
|
|
6
6
|
import { useFingerprintContextSafe } from '../../clerk/fingerprint/fingerprint-provider.mjs';
|
|
7
7
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
8
8
|
import { useRouter } from 'next/navigation';
|
|
9
|
+
import { createPortal } from 'react-dom';
|
|
9
10
|
import { MoneyPriceButton } from './money-price-button.mjs';
|
|
10
11
|
import { getActiveProviderConfig, getProductPricing } from './money-price-config-util.mjs';
|
|
11
12
|
import { UserState } from './money-price-types.mjs';
|
|
@@ -129,55 +130,47 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
|
|
|
129
130
|
if (priceDiscountElement)
|
|
130
131
|
priceDiscountElement.style.display = 'none';
|
|
131
132
|
}
|
|
132
|
-
const priceSubtitleElement = document.querySelector(`[data-price-subtitle="${plan.key}"]`);
|
|
133
|
-
if (priceSubtitleElement && plan.showBillingSubTitle !== false) {
|
|
134
|
-
const billingOption = data.billingSwitch.options.find(opt => opt.key === newBillingType);
|
|
135
|
-
priceSubtitleElement.textContent = (billingOption === null || billingOption === void 0 ? void 0 : billingOption.subTitle) || '';
|
|
136
|
-
}
|
|
137
133
|
});
|
|
138
134
|
}, [config, data]);
|
|
139
|
-
// 更新按钮样式
|
|
140
|
-
const updateButtonStyles = useCallback((newBillingType) => {
|
|
141
|
-
const monthlyButton = document.querySelector('[data-billing-button="monthly"]');
|
|
142
|
-
const yearlyButton = document.querySelector('[data-billing-button="yearly"]');
|
|
143
|
-
const activeClasses = 'text-white bg-gradient-to-r from-purple-400 to-pink-500 hover:from-purple-500 hover:to-pink-600 dark:from-purple-500 dark:to-pink-600 dark:hover:from-purple-600 rounded-full shadow-sm';
|
|
144
|
-
const inactiveClasses = 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full';
|
|
145
|
-
if (monthlyButton && yearlyButton) {
|
|
146
|
-
if (newBillingType === 'monthly') {
|
|
147
|
-
monthlyButton.className = cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', activeClasses);
|
|
148
|
-
yearlyButton.className = cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', inactiveClasses);
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
monthlyButton.className = cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', inactiveClasses);
|
|
152
|
-
yearlyButton.className = cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', activeClasses);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}, []);
|
|
156
135
|
// 更新折扣信息
|
|
157
136
|
const updateDiscountInfo = useCallback((newBillingType) => {
|
|
158
137
|
const discountInfoElement = document.querySelector('[data-discount-info]');
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
138
|
+
if (discountInfoElement) {
|
|
139
|
+
const billingOption = data.billingSwitch.options.find(opt => opt.key === newBillingType);
|
|
140
|
+
let hasDiscount = false;
|
|
141
|
+
let discountPercent = 0;
|
|
142
|
+
const providerConfig = getActiveProviderConfig(config);
|
|
143
|
+
['pro', 'ultra'].forEach(planKey => {
|
|
144
|
+
const pricing = providerConfig.products[planKey].plans[newBillingType];
|
|
145
|
+
if (pricing.discountPercent) {
|
|
146
|
+
hasDiscount = true;
|
|
147
|
+
discountPercent = pricing.discountPercent;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
discountInfoElement.innerHTML = '';
|
|
151
|
+
if (hasDiscount && (billingOption === null || billingOption === void 0 ? void 0 : billingOption.discountText)) {
|
|
152
|
+
const discountBadge = document.createElement('span');
|
|
153
|
+
discountBadge.className = 'px-2 py-1 text-xs rounded bg-yellow-100 text-yellow-800 font-semibold align-middle text-center inline-flex items-center justify-center whitespace-nowrap';
|
|
154
|
+
discountBadge.textContent = billingOption.discountText.replace('{percent}', String(discountPercent));
|
|
155
|
+
discountInfoElement.appendChild(discountBadge);
|
|
171
156
|
}
|
|
172
|
-
});
|
|
173
|
-
discountInfoElement.innerHTML = '';
|
|
174
|
-
if (hasDiscount && (billingOption === null || billingOption === void 0 ? void 0 : billingOption.discountText)) {
|
|
175
|
-
const discountBadge = document.createElement('span');
|
|
176
|
-
discountBadge.className = 'px-2 py-1 text-xs rounded bg-yellow-100 text-yellow-800 font-semibold align-middle text-center inline-flex items-center justify-center whitespace-nowrap';
|
|
177
|
-
discountBadge.textContent = billingOption.discountText.replace('{percent}', String(discountPercent));
|
|
178
|
-
discountInfoElement.appendChild(discountBadge);
|
|
179
157
|
}
|
|
180
158
|
}, [config, data]);
|
|
159
|
+
// 更新按钮样式
|
|
160
|
+
const updateButtonStyles = useCallback((newBillingType) => {
|
|
161
|
+
const monthlyButton = document.querySelector('[data-billing-button="monthly"]');
|
|
162
|
+
const yearlyButton = document.querySelector('[data-billing-button="yearly"]');
|
|
163
|
+
if (monthlyButton) {
|
|
164
|
+
monthlyButton.className = newBillingType === 'monthly'
|
|
165
|
+
? cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-white bg-gradient-to-r from-purple-400 to-pink-500 hover:from-purple-500 hover:to-pink-600 dark:from-purple-500 dark:to-pink-600 dark:hover:from-purple-600 rounded-full shadow-sm')
|
|
166
|
+
: cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full');
|
|
167
|
+
}
|
|
168
|
+
if (yearlyButton) {
|
|
169
|
+
yearlyButton.className = newBillingType === 'yearly'
|
|
170
|
+
? cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-white bg-gradient-to-r from-purple-400 to-pink-500 hover:from-purple-500 hover:to-pink-600 dark:from-purple-500 dark:to-pink-600 dark:hover:from-purple-600 rounded-full shadow-sm')
|
|
171
|
+
: cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full');
|
|
172
|
+
}
|
|
173
|
+
}, []);
|
|
181
174
|
// 处理月付/年付切换和 tooltip 功能
|
|
182
175
|
useEffect(() => {
|
|
183
176
|
const monthlyButton = document.querySelector('[data-billing-button="monthly"]');
|
|
@@ -231,9 +224,18 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
|
|
|
231
224
|
}
|
|
232
225
|
});
|
|
233
226
|
});
|
|
227
|
+
// Inject buttons into placeholders using createPortal
|
|
228
|
+
data.plans.forEach((plan) => {
|
|
229
|
+
const placeholder = document.querySelector(`[data-button-placeholder="${plan.key}"]`);
|
|
230
|
+
if (placeholder) {
|
|
231
|
+
console.log('MoneyPriceButton', `[data-button-placeholder="${plan.key}"]`);
|
|
232
|
+
createPortal(jsx(MoneyPriceButton, { planKey: plan.key, userContext: userContext, billingType: billingType, onLogin: handleLogin, onUpgrade: handleUpgrade, texts: data.buttonTexts, isProcessing: isProcessing }), placeholder);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
// Initial updates
|
|
234
236
|
updatePriceDisplay(billingType);
|
|
235
237
|
updateDiscountInfo(billingType);
|
|
236
|
-
|
|
238
|
+
updateButtonStyles(billingType);
|
|
237
239
|
return () => {
|
|
238
240
|
if (monthlyButton) {
|
|
239
241
|
monthlyButton.removeEventListener('click', handleMonthlyClick);
|
|
@@ -247,7 +249,7 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
|
|
|
247
249
|
element.removeEventListener('mouseleave', handlers.mouseleave);
|
|
248
250
|
});
|
|
249
251
|
};
|
|
250
|
-
}, [data, billingType, updatePriceDisplay, updateButtonStyles, updateDiscountInfo]);
|
|
252
|
+
}, [data, billingType, updatePriceDisplay, updateButtonStyles, updateDiscountInfo, userContext, handleLogin, handleUpgrade, isProcessing]);
|
|
251
253
|
// Tooltip 组件
|
|
252
254
|
const Tooltip = ({ show, content, x, y }) => {
|
|
253
255
|
if (!show)
|
|
@@ -6,6 +6,18 @@ var utils = require('@windrun-huaiin/lib/utils');
|
|
|
6
6
|
var server = require('next-intl/server');
|
|
7
7
|
var moneyPriceConfigUtil = require('./money-price-config-util.js');
|
|
8
8
|
var moneyPriceInteractive = require('./money-price-interactive.js');
|
|
9
|
+
require('@windrun-huaiin/base-ui/components/server');
|
|
10
|
+
require('next-themes');
|
|
11
|
+
require('react');
|
|
12
|
+
require('fumadocs-core/framework');
|
|
13
|
+
require('next/link');
|
|
14
|
+
var gradientButton = require('../../fuma/mdx/gradient-button.js');
|
|
15
|
+
require('next/navigation');
|
|
16
|
+
require('fumadocs-ui/utils/use-copy-button');
|
|
17
|
+
require('fumadocs-core/link');
|
|
18
|
+
require('@windrun-huaiin/base-ui/ui');
|
|
19
|
+
require('fumadocs-ui/components/ui/collapsible');
|
|
20
|
+
require('../../fuma/mdx/banner.js');
|
|
9
21
|
|
|
10
22
|
function MoneyPrice(_a) {
|
|
11
23
|
return tslib_es6.__awaiter(this, arguments, void 0, function* ({ locale, config, upgradeApiEndpoint, signInPath, sectionClassName }) {
|
|
@@ -67,7 +79,7 @@ function MoneyPrice(_a) {
|
|
|
67
79
|
return null;
|
|
68
80
|
return (jsxRuntime.jsx("span", { className: "px-2 py-1 text-xs rounded bg-yellow-100 text-yellow-800 font-semibold align-middle text-center inline-flex items-center justify-center whitespace-nowrap", children: opt.discountText.replace('{percent}', String(discountPercent)) }));
|
|
69
81
|
})() })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-8", children: data.plans.map((plan, _idx) => (jsxRuntime.jsxs("div", { "data-price-plan": plan.key, className: utils.cn('flex flex-col bg-white dark:bg-gray-800/60 rounded-2xl border border-gray-300 dark:border-[#7c3aed40] transition p-8 w-full h-full shadow-sm dark:shadow-none', // 添加 w-full
|
|
70
|
-
'hover:border-2 hover:border-purple-500', 'focus-within:border-2 focus-within:border-purple-500'), style: { minHeight: maxFeaturesCount * 100 }, children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [jsxRuntime.jsx("span", { className: "text-xl font-bold text-gray-900 dark:text-gray-100", children: plan.title }), plan.titleTags && plan.titleTags.map((tag, i) => (jsxRuntime.jsx("span", { className: "px-2 py-0.5 text-xs rounded bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200 font-semibold align-middle", children: tag }, i)))] }), renderPrice(plan), jsxRuntime.jsx("ul", { className: "flex-1 mb-6 mt-4", children: getFeatureRows(plan).map((feature, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-2 mb-2 min-h-[28px]", "data-feature-item": `${plan.key}-${i}`, children: [feature ? (jsxRuntime.jsx("span", { className: "inline-flex items-center justify-center w-5 h-5 rounded-full bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-200 mr-1", children: feature.icon ? jsxRuntime.jsx("span", { children: feature.icon }) : jsxRuntime.jsx("span", { className: "font-bold", children: "\u2713" }) })) : (jsxRuntime.jsx("span", { className: "inline-flex items-center justify-center w-5 h-5 rounded-full mr-1", children: "\u00A0" })), feature && feature.tag && (jsxRuntime.jsx("span", { className: "px-1 py-0.5 text-[6px] rounded bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 font-semibold align-middle", children: feature.tag })), feature ? (jsxRuntime.jsxs("span", { className: "relative group cursor-pointer text-sm text-gray-800 dark:text-gray-200", children: [feature.description, feature.tooltip && (jsxRuntime.jsx("span", { className: "ml-1 align-middle inline-flex", "data-tooltip-trigger": `${plan.key}-${i}`, "data-tooltip-content": feature.tooltip, children: jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }) }))] })) : (jsxRuntime.jsx("span", { children: "\u00A0" }))] }, i))) }), jsxRuntime.jsx("div", { className: "flex-1" }), jsxRuntime.jsx("div", { "data-button-placeholder": plan.key, className: "w-full" })] }, plan.key))) }), jsxRuntime.jsx(moneyPriceInteractive.MoneyPriceInteractive, { data: data, config: config, upgradeApiEndpoint: upgradeApiEndpoint, signInPath: signInPath })] }));
|
|
82
|
+
'hover:border-2 hover:border-purple-500', 'focus-within:border-2 focus-within:border-purple-500'), style: { minHeight: maxFeaturesCount * 100 }, children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [jsxRuntime.jsx("span", { className: "text-xl font-bold text-gray-900 dark:text-gray-100", children: plan.title }), plan.titleTags && plan.titleTags.map((tag, i) => (jsxRuntime.jsx("span", { className: "px-2 py-0.5 text-xs rounded bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200 font-semibold align-middle", children: tag }, i)))] }), renderPrice(plan), jsxRuntime.jsx("ul", { className: "flex-1 mb-6 mt-4", children: getFeatureRows(plan).map((feature, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-2 mb-2 min-h-[28px]", "data-feature-item": `${plan.key}-${i}`, children: [feature ? (jsxRuntime.jsx("span", { className: "inline-flex items-center justify-center w-5 h-5 rounded-full bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-200 mr-1", children: feature.icon ? jsxRuntime.jsx("span", { children: feature.icon }) : jsxRuntime.jsx("span", { className: "font-bold", children: "\u2713" }) })) : (jsxRuntime.jsx("span", { className: "inline-flex items-center justify-center w-5 h-5 rounded-full mr-1", children: "\u00A0" })), feature && feature.tag && (jsxRuntime.jsx("span", { className: "px-1 py-0.5 text-[6px] rounded bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 font-semibold align-middle", children: feature.tag })), feature ? (jsxRuntime.jsxs("span", { className: "relative group cursor-pointer text-sm text-gray-800 dark:text-gray-200", children: [feature.description, feature.tooltip && (jsxRuntime.jsx("span", { className: "ml-1 align-middle inline-flex", "data-tooltip-trigger": `${plan.key}-${i}`, "data-tooltip-content": feature.tooltip, children: jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }) }))] })) : (jsxRuntime.jsx("span", { children: "\u00A0" }))] }, i))) }), jsxRuntime.jsx("div", { className: "flex-1" }), jsxRuntime.jsx("div", { "data-button-placeholder": plan.key, children: jsxRuntime.jsx(gradientButton.GradientButton, { title: data.buttonTexts.getStarted, disabled: true, align: "center", className: "w-full" }) })] }, plan.key))) }), jsxRuntime.jsx(moneyPriceInteractive.MoneyPriceInteractive, { data: data, config: config, upgradeApiEndpoint: upgradeApiEndpoint, signInPath: signInPath })] }));
|
|
71
83
|
});
|
|
72
84
|
}
|
|
73
85
|
|
|
@@ -4,6 +4,18 @@ import { cn } from '@windrun-huaiin/lib/utils';
|
|
|
4
4
|
import { getTranslations } from 'next-intl/server';
|
|
5
5
|
import { getActiveProviderConfig } from './money-price-config-util.mjs';
|
|
6
6
|
import { MoneyPriceInteractive } from './money-price-interactive.mjs';
|
|
7
|
+
import '@windrun-huaiin/base-ui/components/server';
|
|
8
|
+
import 'next-themes';
|
|
9
|
+
import 'react';
|
|
10
|
+
import 'fumadocs-core/framework';
|
|
11
|
+
import 'next/link';
|
|
12
|
+
import { GradientButton } from '../../fuma/mdx/gradient-button.mjs';
|
|
13
|
+
import 'next/navigation';
|
|
14
|
+
import 'fumadocs-ui/utils/use-copy-button';
|
|
15
|
+
import 'fumadocs-core/link';
|
|
16
|
+
import '@windrun-huaiin/base-ui/ui';
|
|
17
|
+
import 'fumadocs-ui/components/ui/collapsible';
|
|
18
|
+
import '../../fuma/mdx/banner.mjs';
|
|
7
19
|
|
|
8
20
|
function MoneyPrice(_a) {
|
|
9
21
|
return __awaiter(this, arguments, void 0, function* ({ locale, config, upgradeApiEndpoint, signInPath, sectionClassName }) {
|
|
@@ -65,7 +77,7 @@ function MoneyPrice(_a) {
|
|
|
65
77
|
return null;
|
|
66
78
|
return (jsx("span", { className: "px-2 py-1 text-xs rounded bg-yellow-100 text-yellow-800 font-semibold align-middle text-center inline-flex items-center justify-center whitespace-nowrap", children: opt.discountText.replace('{percent}', String(discountPercent)) }));
|
|
67
79
|
})() })] }), jsx("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-8", children: data.plans.map((plan, _idx) => (jsxs("div", { "data-price-plan": plan.key, className: cn('flex flex-col bg-white dark:bg-gray-800/60 rounded-2xl border border-gray-300 dark:border-[#7c3aed40] transition p-8 w-full h-full shadow-sm dark:shadow-none', // 添加 w-full
|
|
68
|
-
'hover:border-2 hover:border-purple-500', 'focus-within:border-2 focus-within:border-purple-500'), style: { minHeight: maxFeaturesCount * 100 }, children: [jsxs("div", { className: "flex items-center gap-2 mb-2", children: [jsx("span", { className: "text-xl font-bold text-gray-900 dark:text-gray-100", children: plan.title }), plan.titleTags && plan.titleTags.map((tag, i) => (jsx("span", { className: "px-2 py-0.5 text-xs rounded bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200 font-semibold align-middle", children: tag }, i)))] }), renderPrice(plan), jsx("ul", { className: "flex-1 mb-6 mt-4", children: getFeatureRows(plan).map((feature, i) => (jsxs("li", { className: "flex items-center gap-2 mb-2 min-h-[28px]", "data-feature-item": `${plan.key}-${i}`, children: [feature ? (jsx("span", { className: "inline-flex items-center justify-center w-5 h-5 rounded-full bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-200 mr-1", children: feature.icon ? jsx("span", { children: feature.icon }) : jsx("span", { className: "font-bold", children: "\u2713" }) })) : (jsx("span", { className: "inline-flex items-center justify-center w-5 h-5 rounded-full mr-1", children: "\u00A0" })), feature && feature.tag && (jsx("span", { className: "px-1 py-0.5 text-[6px] rounded bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 font-semibold align-middle", children: feature.tag })), feature ? (jsxs("span", { className: "relative group cursor-pointer text-sm text-gray-800 dark:text-gray-200", children: [feature.description, feature.tooltip && (jsx("span", { className: "ml-1 align-middle inline-flex", "data-tooltip-trigger": `${plan.key}-${i}`, "data-tooltip-content": feature.tooltip, children: jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }) }))] })) : (jsx("span", { children: "\u00A0" }))] }, i))) }), jsx("div", { className: "flex-1" }), jsx("div", { "data-button-placeholder": plan.key, className: "w-full" })] }, plan.key))) }), jsx(MoneyPriceInteractive, { data: data, config: config, upgradeApiEndpoint: upgradeApiEndpoint, signInPath: signInPath })] }));
|
|
80
|
+
'hover:border-2 hover:border-purple-500', 'focus-within:border-2 focus-within:border-purple-500'), style: { minHeight: maxFeaturesCount * 100 }, children: [jsxs("div", { className: "flex items-center gap-2 mb-2", children: [jsx("span", { className: "text-xl font-bold text-gray-900 dark:text-gray-100", children: plan.title }), plan.titleTags && plan.titleTags.map((tag, i) => (jsx("span", { className: "px-2 py-0.5 text-xs rounded bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200 font-semibold align-middle", children: tag }, i)))] }), renderPrice(plan), jsx("ul", { className: "flex-1 mb-6 mt-4", children: getFeatureRows(plan).map((feature, i) => (jsxs("li", { className: "flex items-center gap-2 mb-2 min-h-[28px]", "data-feature-item": `${plan.key}-${i}`, children: [feature ? (jsx("span", { className: "inline-flex items-center justify-center w-5 h-5 rounded-full bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-200 mr-1", children: feature.icon ? jsx("span", { children: feature.icon }) : jsx("span", { className: "font-bold", children: "\u2713" }) })) : (jsx("span", { className: "inline-flex items-center justify-center w-5 h-5 rounded-full mr-1", children: "\u00A0" })), feature && feature.tag && (jsx("span", { className: "px-1 py-0.5 text-[6px] rounded bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 font-semibold align-middle", children: feature.tag })), feature ? (jsxs("span", { className: "relative group cursor-pointer text-sm text-gray-800 dark:text-gray-200", children: [feature.description, feature.tooltip && (jsx("span", { className: "ml-1 align-middle inline-flex", "data-tooltip-trigger": `${plan.key}-${i}`, "data-tooltip-content": feature.tooltip, children: jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }) }))] })) : (jsx("span", { children: "\u00A0" }))] }, i))) }), jsx("div", { className: "flex-1" }), jsx("div", { "data-button-placeholder": plan.key, children: jsx(GradientButton, { title: data.buttonTexts.getStarted, disabled: true, align: "center", className: "w-full" }) })] }, plan.key))) }), jsx(MoneyPriceInteractive, { data: data, config: config, upgradeApiEndpoint: upgradeApiEndpoint, signInPath: signInPath })] }));
|
|
69
81
|
});
|
|
70
82
|
}
|
|
71
83
|
|
package/dist/main/price-plan.js
CHANGED
|
@@ -14,13 +14,8 @@ var pricePlanInteractive = require('./price-plan-interactive.js');
|
|
|
14
14
|
require('@clerk/nextjs');
|
|
15
15
|
require('../clerk/fingerprint/fingerprint-provider.js');
|
|
16
16
|
require('next/navigation');
|
|
17
|
-
require('
|
|
18
|
-
require('
|
|
19
|
-
require('next/link');
|
|
20
|
-
require('fumadocs-ui/utils/use-copy-button');
|
|
21
|
-
require('fumadocs-core/link');
|
|
22
|
-
require('fumadocs-ui/components/ui/collapsible');
|
|
23
|
-
require('../fuma/mdx/banner.js');
|
|
17
|
+
require('react-dom');
|
|
18
|
+
require('@windrun-huaiin/third-ui/fuma/mdx');
|
|
24
19
|
require('./money-price/money-price-types.js');
|
|
25
20
|
|
|
26
21
|
function PricePlan(_a) {
|
package/dist/main/price-plan.mjs
CHANGED
|
@@ -12,13 +12,8 @@ import { PricePlanInteractive } from './price-plan-interactive.mjs';
|
|
|
12
12
|
import '@clerk/nextjs';
|
|
13
13
|
import '../clerk/fingerprint/fingerprint-provider.mjs';
|
|
14
14
|
import 'next/navigation';
|
|
15
|
-
import '
|
|
16
|
-
import '
|
|
17
|
-
import 'next/link';
|
|
18
|
-
import 'fumadocs-ui/utils/use-copy-button';
|
|
19
|
-
import 'fumadocs-core/link';
|
|
20
|
-
import 'fumadocs-ui/components/ui/collapsible';
|
|
21
|
-
import '../fuma/mdx/banner.mjs';
|
|
15
|
+
import 'react-dom';
|
|
16
|
+
import '@windrun-huaiin/third-ui/fuma/mdx';
|
|
22
17
|
import './money-price/money-price-types.mjs';
|
|
23
18
|
|
|
24
19
|
function PricePlan(_a) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var coseBase$1 = require('../../../../../_virtual/cose-
|
|
3
|
+
var coseBase$1 = require('../../../../../_virtual/cose-base2.js');
|
|
4
4
|
var layoutBase = require('../../../layout-base@1.0.2/node_modules/layout-base/layout-base.js');
|
|
5
5
|
|
|
6
6
|
var coseBase = coseBase$1.__module.exports;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as coseBase$1 } from '../../../../../_virtual/cose-
|
|
1
|
+
import { __module as coseBase$1 } from '../../../../../_virtual/cose-base.mjs';
|
|
2
2
|
import { __require as requireLayoutBase } from '../../../layout-base@1.0.2/node_modules/layout-base/layout-base.mjs';
|
|
3
3
|
|
|
4
4
|
var coseBase = coseBase$1.exports;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var coseBase$1 = require('../../../../../_virtual/cose-
|
|
3
|
+
var coseBase$1 = require('../../../../../_virtual/cose-base.js');
|
|
4
4
|
var layoutBase = require('../../../layout-base@2.0.1/node_modules/layout-base/layout-base.js');
|
|
5
5
|
|
|
6
6
|
var coseBase = coseBase$1.__module.exports;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as coseBase$1 } from '../../../../../_virtual/cose-
|
|
1
|
+
import { __module as coseBase$1 } from '../../../../../_virtual/cose-base2.mjs';
|
|
2
2
|
import { __require as requireLayoutBase } from '../../../layout-base@2.0.1/node_modules/layout-base/layout-base.mjs';
|
|
3
3
|
|
|
4
4
|
var coseBase = coseBase$1.exports;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windrun-huaiin/third-ui",
|
|
3
|
-
"version": "7.3.
|
|
3
|
+
"version": "7.3.11",
|
|
4
4
|
"description": "Third-party integrated UI components for windrun-huaiin projects",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
"mermaid": "^11.6.0",
|
|
76
76
|
"react-medium-image-zoom": "^5.2.14",
|
|
77
77
|
"zod": "^3.22.4",
|
|
78
|
-
"@windrun-huaiin/
|
|
79
|
-
"@windrun-huaiin/
|
|
78
|
+
"@windrun-huaiin/lib": "^7.1.2",
|
|
79
|
+
"@windrun-huaiin/base-ui": "^8.1.2"
|
|
80
80
|
},
|
|
81
81
|
"peerDependencies": {
|
|
82
82
|
"react": "19.1.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { GradientButton } from '@third-ui/fuma/mdx';
|
|
3
|
+
import { GradientButton } from '@windrun-huaiin/third-ui/fuma/mdx';
|
|
4
4
|
import { globalLucideIcons as icons } from '@windrun-huaiin/base-ui/components/server';
|
|
5
5
|
import { UserState, type MoneyPriceButtonProps } from './money-price-types';
|
|
6
6
|
|
|
@@ -5,6 +5,7 @@ import { useFingerprintContextSafe } from '@third-ui/clerk/fingerprint';
|
|
|
5
5
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
6
6
|
import { useRouter } from 'next/navigation';
|
|
7
7
|
import React, { useEffect, useState, useMemo, useCallback } from 'react';
|
|
8
|
+
import { createPortal } from 'react-dom';
|
|
8
9
|
import { MoneyPriceButton } from './money-price-button';
|
|
9
10
|
import { getActiveProviderConfig, getProductPricing } from './money-price-config-util';
|
|
10
11
|
import {
|
|
@@ -130,7 +131,6 @@ export function MoneyPriceInteractive({
|
|
|
130
131
|
|
|
131
132
|
const priceOriginalElement = document.querySelector(`[data-price-original="${plan.key}"]`) as HTMLElement;
|
|
132
133
|
const priceDiscountElement = document.querySelector(`[data-price-discount="${plan.key}"]`) as HTMLElement;
|
|
133
|
-
|
|
134
134
|
if (pricing.originalAmount && pricing.discountPercent) {
|
|
135
135
|
if (priceOriginalElement) {
|
|
136
136
|
priceOriginalElement.style.display = 'inline';
|
|
@@ -140,74 +140,57 @@ export function MoneyPriceInteractive({
|
|
|
140
140
|
priceDiscountElement.style.display = 'inline';
|
|
141
141
|
const billingOption = data.billingSwitch.options.find(opt => opt.key === newBillingType);
|
|
142
142
|
if (billingOption?.discountText) {
|
|
143
|
-
priceDiscountElement.textContent = billingOption.discountText.replace(
|
|
144
|
-
'{percent}',
|
|
145
|
-
String(pricing.discountPercent)
|
|
146
|
-
);
|
|
143
|
+
priceDiscountElement.textContent = billingOption.discountText.replace('{percent}', String(pricing.discountPercent));
|
|
147
144
|
}
|
|
148
145
|
}
|
|
149
146
|
} else {
|
|
150
147
|
if (priceOriginalElement) priceOriginalElement.style.display = 'none';
|
|
151
148
|
if (priceDiscountElement) priceDiscountElement.style.display = 'none';
|
|
152
149
|
}
|
|
153
|
-
|
|
154
|
-
const priceSubtitleElement = document.querySelector(`[data-price-subtitle="${plan.key}"]`) as HTMLElement;
|
|
155
|
-
if (priceSubtitleElement && plan.showBillingSubTitle !== false) {
|
|
156
|
-
const billingOption = data.billingSwitch.options.find(opt => opt.key === newBillingType);
|
|
157
|
-
priceSubtitleElement.textContent = billingOption?.subTitle || '';
|
|
158
|
-
}
|
|
159
150
|
});
|
|
160
151
|
}, [config, data]);
|
|
161
152
|
|
|
162
|
-
// 更新按钮样式
|
|
163
|
-
const updateButtonStyles = useCallback((newBillingType: string) => {
|
|
164
|
-
const monthlyButton = document.querySelector('[data-billing-button="monthly"]') as HTMLButtonElement;
|
|
165
|
-
const yearlyButton = document.querySelector('[data-billing-button="yearly"]') as HTMLButtonElement;
|
|
166
|
-
|
|
167
|
-
const activeClasses = 'text-white bg-gradient-to-r from-purple-400 to-pink-500 hover:from-purple-500 hover:to-pink-600 dark:from-purple-500 dark:to-pink-600 dark:hover:from-purple-600 rounded-full shadow-sm';
|
|
168
|
-
const inactiveClasses = 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full';
|
|
169
|
-
|
|
170
|
-
if (monthlyButton && yearlyButton) {
|
|
171
|
-
if (newBillingType === 'monthly') {
|
|
172
|
-
monthlyButton.className = cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', activeClasses);
|
|
173
|
-
yearlyButton.className = cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', inactiveClasses);
|
|
174
|
-
} else {
|
|
175
|
-
monthlyButton.className = cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', inactiveClasses);
|
|
176
|
-
yearlyButton.className = cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', activeClasses);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}, []);
|
|
180
|
-
|
|
181
153
|
// 更新折扣信息
|
|
182
154
|
const updateDiscountInfo = useCallback((newBillingType: string) => {
|
|
183
155
|
const discountInfoElement = document.querySelector('[data-discount-info]') as HTMLElement;
|
|
184
|
-
if (
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
156
|
+
if (discountInfoElement) {
|
|
157
|
+
const billingOption = data.billingSwitch.options.find(opt => opt.key === newBillingType);
|
|
158
|
+
let hasDiscount = false;
|
|
159
|
+
let discountPercent = 0;
|
|
160
|
+
const providerConfig = getActiveProviderConfig(config);
|
|
161
|
+
['pro', 'ultra'].forEach(planKey => {
|
|
162
|
+
const pricing = providerConfig.products[planKey as 'pro' | 'ultra'].plans[newBillingType as 'monthly' | 'yearly'];
|
|
163
|
+
if (pricing.discountPercent) {
|
|
164
|
+
hasDiscount = true;
|
|
165
|
+
discountPercent = pricing.discountPercent;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
discountInfoElement.innerHTML = '';
|
|
169
|
+
if (hasDiscount && billingOption?.discountText) {
|
|
170
|
+
const discountBadge = document.createElement('span');
|
|
171
|
+
discountBadge.className = 'px-2 py-1 text-xs rounded bg-yellow-100 text-yellow-800 font-semibold align-middle text-center inline-flex items-center justify-center whitespace-nowrap';
|
|
172
|
+
discountBadge.textContent = billingOption.discountText.replace('{percent}', String(discountPercent));
|
|
173
|
+
discountInfoElement.appendChild(discountBadge);
|
|
198
174
|
}
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
discountInfoElement.innerHTML = '';
|
|
202
|
-
|
|
203
|
-
if (hasDiscount && billingOption?.discountText) {
|
|
204
|
-
const discountBadge = document.createElement('span');
|
|
205
|
-
discountBadge.className = 'px-2 py-1 text-xs rounded bg-yellow-100 text-yellow-800 font-semibold align-middle text-center inline-flex items-center justify-center whitespace-nowrap';
|
|
206
|
-
discountBadge.textContent = billingOption.discountText.replace('{percent}', String(discountPercent));
|
|
207
|
-
discountInfoElement.appendChild(discountBadge);
|
|
208
175
|
}
|
|
209
176
|
}, [config, data]);
|
|
210
177
|
|
|
178
|
+
// 更新按钮样式
|
|
179
|
+
const updateButtonStyles = useCallback((newBillingType: string) => {
|
|
180
|
+
const monthlyButton = document.querySelector('[data-billing-button="monthly"]') as HTMLElement;
|
|
181
|
+
const yearlyButton = document.querySelector('[data-billing-button="yearly"]') as HTMLElement;
|
|
182
|
+
if (monthlyButton) {
|
|
183
|
+
monthlyButton.className = newBillingType === 'monthly'
|
|
184
|
+
? cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-white bg-gradient-to-r from-purple-400 to-pink-500 hover:from-purple-500 hover:to-pink-600 dark:from-purple-500 dark:to-pink-600 dark:hover:from-purple-600 rounded-full shadow-sm')
|
|
185
|
+
: cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full');
|
|
186
|
+
}
|
|
187
|
+
if (yearlyButton) {
|
|
188
|
+
yearlyButton.className = newBillingType === 'yearly'
|
|
189
|
+
? cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-white bg-gradient-to-r from-purple-400 to-pink-500 hover:from-purple-500 hover:to-pink-600 dark:from-purple-500 dark:to-pink-600 dark:hover:from-purple-600 rounded-full shadow-sm')
|
|
190
|
+
: cn('min-w-[120px] px-6 py-2 font-medium transition text-lg relative', 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100 rounded-full');
|
|
191
|
+
}
|
|
192
|
+
}, []);
|
|
193
|
+
|
|
211
194
|
// 处理月付/年付切换和 tooltip 功能
|
|
212
195
|
useEffect(() => {
|
|
213
196
|
const monthlyButton = document.querySelector('[data-billing-button="monthly"]') as HTMLButtonElement;
|
|
@@ -275,23 +258,31 @@ export function MoneyPriceInteractive({
|
|
|
275
258
|
});
|
|
276
259
|
});
|
|
277
260
|
|
|
261
|
+
// Inject buttons into placeholders using createPortal
|
|
262
|
+
data.plans.forEach((plan: any) => {
|
|
263
|
+
const placeholder = document.querySelector(`[data-button-placeholder="${plan.key}"]`) as HTMLElement;
|
|
264
|
+
if (placeholder) {
|
|
265
|
+
console.log('MoneyPriceButton', `[data-button-placeholder="${plan.key}"]`)
|
|
266
|
+
createPortal(
|
|
267
|
+
<MoneyPriceButton
|
|
268
|
+
planKey={plan.key}
|
|
269
|
+
userContext={userContext}
|
|
270
|
+
billingType={billingType}
|
|
271
|
+
onLogin={handleLogin}
|
|
272
|
+
onUpgrade={handleUpgrade}
|
|
273
|
+
texts={data.buttonTexts}
|
|
274
|
+
isProcessing={isProcessing}
|
|
275
|
+
/>,
|
|
276
|
+
placeholder
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Initial updates
|
|
278
282
|
updatePriceDisplay(billingType);
|
|
279
283
|
updateDiscountInfo(billingType);
|
|
284
|
+
updateButtonStyles(billingType);
|
|
280
285
|
|
|
281
|
-
data.plans.map((plan: any) => (
|
|
282
|
-
<div key={plan.key} data-button-placeholder={plan.key}>
|
|
283
|
-
<MoneyPriceButton
|
|
284
|
-
planKey={plan.key}
|
|
285
|
-
userContext={userContext}
|
|
286
|
-
billingType={billingType}
|
|
287
|
-
onLogin={handleLogin}
|
|
288
|
-
onUpgrade={handleUpgrade}
|
|
289
|
-
texts={data.buttonTexts}
|
|
290
|
-
isProcessing={isProcessing}
|
|
291
|
-
/>
|
|
292
|
-
</div>
|
|
293
|
-
))
|
|
294
|
-
|
|
295
286
|
return () => {
|
|
296
287
|
if (monthlyButton) {
|
|
297
288
|
monthlyButton.removeEventListener('click', handleMonthlyClick);
|
|
@@ -306,7 +297,7 @@ export function MoneyPriceInteractive({
|
|
|
306
297
|
element.removeEventListener('mouseleave', handlers.mouseleave);
|
|
307
298
|
});
|
|
308
299
|
};
|
|
309
|
-
}, [data, billingType, updatePriceDisplay, updateButtonStyles, updateDiscountInfo]);
|
|
300
|
+
}, [data, billingType, updatePriceDisplay, updateButtonStyles, updateDiscountInfo, userContext, handleLogin, handleUpgrade, isProcessing]);
|
|
310
301
|
|
|
311
302
|
// Tooltip 组件
|
|
312
303
|
const Tooltip = ({ show, content, x, y }: typeof tooltip) => {
|
|
@@ -331,5 +322,5 @@ export function MoneyPriceInteractive({
|
|
|
331
322
|
);
|
|
332
323
|
};
|
|
333
324
|
|
|
334
|
-
return <Tooltip {...tooltip}
|
|
325
|
+
return <Tooltip {...tooltip} />;
|
|
335
326
|
}
|
|
@@ -4,6 +4,7 @@ import { getTranslations } from 'next-intl/server';
|
|
|
4
4
|
import { getActiveProviderConfig } from './money-price-config-util';
|
|
5
5
|
import { MoneyPriceInteractive } from './money-price-interactive';
|
|
6
6
|
import type { MoneyPriceProps, MoneyPriceData } from './money-price-types';
|
|
7
|
+
import { GradientButton } from '@third-ui/fuma/mdx';
|
|
7
8
|
|
|
8
9
|
export async function MoneyPrice({
|
|
9
10
|
locale,
|
|
@@ -262,8 +263,13 @@ export async function MoneyPrice({
|
|
|
262
263
|
|
|
263
264
|
<div className="flex-1" />
|
|
264
265
|
|
|
265
|
-
<div data-button-placeholder={plan.key}
|
|
266
|
-
|
|
266
|
+
<div data-button-placeholder={plan.key}>
|
|
267
|
+
<GradientButton
|
|
268
|
+
title={data.buttonTexts.getStarted}
|
|
269
|
+
disabled={true}
|
|
270
|
+
align="center"
|
|
271
|
+
className="w-full"
|
|
272
|
+
/>
|
|
267
273
|
</div>
|
|
268
274
|
</div>
|
|
269
275
|
))}
|