@windrun-huaiin/third-ui 30.0.0 → 31.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.
Files changed (122) hide show
  1. package/README.md +109 -143
  2. package/dist/ai/ai-prompt-textarea.js +5 -5
  3. package/dist/ai/ai-prompt-textarea.mjs +5 -5
  4. package/dist/clerk/clerk-auth-appearance.d.ts +13 -0
  5. package/dist/clerk/clerk-auth-appearance.js +19 -0
  6. package/dist/clerk/clerk-auth-appearance.mjs +15 -0
  7. package/dist/clerk/clerk-auth-modal-appearance.d.ts +12 -0
  8. package/dist/clerk/clerk-auth-modal-appearance.js +17 -0
  9. package/dist/clerk/clerk-auth-modal-appearance.mjs +14 -0
  10. package/dist/clerk/clerk-page-context-generator.js +3 -3
  11. package/dist/clerk/clerk-page-context-generator.mjs +3 -3
  12. package/dist/clerk/clerk-page-generator.js +4 -4
  13. package/dist/clerk/clerk-page-generator.mjs +4 -4
  14. package/dist/clerk/clerk-user-client.js +2 -1
  15. package/dist/clerk/clerk-user-client.mjs +2 -1
  16. package/dist/clerk/fingerprint/fingerprint-client.d.ts +10 -10
  17. package/dist/clerk/fingerprint/fingerprint-client.js +20 -20
  18. package/dist/clerk/fingerprint/fingerprint-client.mjs +20 -20
  19. package/dist/clerk/fingerprint/fingerprint-provider.d.ts +3 -3
  20. package/dist/clerk/fingerprint/fingerprint-provider.js +8 -8
  21. package/dist/clerk/fingerprint/fingerprint-provider.mjs +8 -8
  22. package/dist/clerk/fingerprint/fingerprint-server.d.ts +12 -12
  23. package/dist/clerk/fingerprint/fingerprint-server.js +17 -17
  24. package/dist/clerk/fingerprint/fingerprint-server.mjs +17 -17
  25. package/dist/clerk/fingerprint/fingerprint-shared.d.ts +3 -3
  26. package/dist/clerk/fingerprint/fingerprint-shared.js +10 -10
  27. package/dist/clerk/fingerprint/fingerprint-shared.mjs +10 -10
  28. package/dist/clerk/fingerprint/types.d.ts +0 -1
  29. package/dist/clerk/fingerprint/use-fingerprint.js +7 -7
  30. package/dist/clerk/fingerprint/use-fingerprint.mjs +7 -7
  31. package/dist/clerk/signin-with-fingerprint-client.d.ts +2 -2
  32. package/dist/clerk/signin-with-fingerprint-client.js +7 -6
  33. package/dist/clerk/signin-with-fingerprint-client.mjs +7 -6
  34. package/dist/clerk/signup-button-with-fingerprint-client.js +6 -4
  35. package/dist/clerk/signup-button-with-fingerprint-client.mjs +6 -4
  36. package/dist/clerk/signup-with-fingerprint-client.d.ts +2 -2
  37. package/dist/clerk/signup-with-fingerprint-client.js +7 -6
  38. package/dist/clerk/signup-with-fingerprint-client.mjs +7 -6
  39. package/dist/fuma/fuma-page-genarator.d.ts +2 -6
  40. package/dist/fuma/fuma-page-genarator.js +3 -2
  41. package/dist/fuma/fuma-page-genarator.mjs +3 -2
  42. package/dist/fuma/heavy/mermaid.js +1 -1
  43. package/dist/fuma/heavy/mermaid.mjs +1 -1
  44. package/dist/fuma/site-x.js +0 -1
  45. package/dist/fuma/site-x.mjs +0 -1
  46. package/dist/main/404-page.d.ts +12 -0
  47. package/dist/main/404-page.js +66 -0
  48. package/dist/main/404-page.mjs +64 -0
  49. package/dist/main/anime/anime-404-page.d.ts +14 -0
  50. package/dist/main/anime/anime-404-page.js +197 -0
  51. package/dist/main/anime/anime-404-page.mjs +195 -0
  52. package/dist/main/anime/anime-not-found-page.d.ts +7 -0
  53. package/dist/main/anime/anime-not-found-page.js +142 -0
  54. package/dist/main/anime/anime-not-found-page.mjs +140 -0
  55. package/dist/main/anime/index.d.ts +1 -0
  56. package/dist/main/anime/index.js +2 -0
  57. package/dist/main/anime/index.mjs +1 -0
  58. package/dist/main/calendar/calendar-date-range-input.js +1 -1
  59. package/dist/main/calendar/calendar-date-range-input.mjs +1 -1
  60. package/dist/main/credit/types.d.ts +8 -8
  61. package/dist/main/index.d.ts +1 -0
  62. package/dist/main/index.js +2 -0
  63. package/dist/main/index.mjs +1 -0
  64. package/dist/main/money-price/index.d.ts +1 -1
  65. package/dist/main/money-price/money-price-button.js +10 -10
  66. package/dist/main/money-price/money-price-button.mjs +10 -10
  67. package/dist/main/money-price/money-price-config-util.d.ts +30 -30
  68. package/dist/main/money-price/money-price-config-util.js +48 -48
  69. package/dist/main/money-price/money-price-config-util.mjs +48 -48
  70. package/dist/main/money-price/money-price-interactive.js +30 -18
  71. package/dist/main/money-price/money-price-interactive.mjs +30 -18
  72. package/dist/main/money-price/money-price-types.d.ts +7 -1
  73. package/dist/main/money-price/money-price-types.js +2 -2
  74. package/dist/main/money-price/money-price-types.mjs +2 -2
  75. package/dist/main/money-price/server.d.ts +1 -1
  76. package/dist/main/motion/creative-left-panel.d.ts +7 -0
  77. package/dist/main/motion/creative-left-panel.js +11 -0
  78. package/dist/main/motion/creative-left-panel.mjs +9 -0
  79. package/dist/main/motion/creative-right-panel.d.ts +7 -0
  80. package/dist/main/motion/creative-right-panel.js +11 -0
  81. package/dist/main/motion/creative-right-panel.mjs +9 -0
  82. package/dist/main/pill-select/x-pill-select.js +2 -2
  83. package/dist/main/pill-select/x-pill-select.mjs +2 -2
  84. package/dist/main/server.d.ts +1 -1
  85. package/dist/main/snake-loading-frame.js +1 -0
  86. package/dist/main/snake-loading-frame.mjs +1 -0
  87. package/package.json +13 -7
  88. package/src/ai/ai-prompt-textarea.tsx +6 -6
  89. package/src/clerk/clerk-auth-appearance.ts +16 -0
  90. package/src/clerk/clerk-page-context-generator.tsx +3 -5
  91. package/src/clerk/clerk-page-generator.tsx +9 -8
  92. package/src/clerk/clerk-user-client.tsx +14 -5
  93. package/src/clerk/fingerprint/fingerprint-client.ts +20 -20
  94. package/src/clerk/fingerprint/fingerprint-provider.tsx +11 -11
  95. package/src/clerk/fingerprint/fingerprint-server.ts +17 -17
  96. package/src/clerk/fingerprint/fingerprint-shared.ts +10 -10
  97. package/src/clerk/fingerprint/types.ts +0 -1
  98. package/src/clerk/fingerprint/use-fingerprint.ts +7 -7
  99. package/src/clerk/signin-with-fingerprint-client.tsx +7 -7
  100. package/src/clerk/signup-button-with-fingerprint-client.tsx +7 -5
  101. package/src/clerk/signup-with-fingerprint-client.tsx +7 -7
  102. package/src/fuma/base/custom-home-layout.tsx +4 -4
  103. package/src/fuma/fuma-page-genarator.tsx +2 -22
  104. package/src/fuma/heavy/mermaid.tsx +1 -1
  105. package/src/fuma/site-x.tsx +0 -1
  106. package/src/main/404-page.tsx +162 -0
  107. package/src/main/anime/anime-404-page.tsx +344 -0
  108. package/src/main/anime/index.ts +1 -0
  109. package/src/main/calendar/calendar-date-range-input.tsx +1 -1
  110. package/src/main/credit/types.ts +8 -8
  111. package/src/main/gallery/gallery-mobile-swiper.tsx +0 -1
  112. package/src/main/gallery/gallery-server.tsx +2 -2
  113. package/src/main/index.ts +1 -0
  114. package/src/main/money-price/index.ts +2 -0
  115. package/src/main/money-price/money-price-button.tsx +10 -10
  116. package/src/main/money-price/money-price-config-util.ts +49 -49
  117. package/src/main/money-price/money-price-interactive.tsx +40 -20
  118. package/src/main/money-price/money-price-types.ts +21 -14
  119. package/src/main/money-price/server.ts +2 -0
  120. package/src/main/pill-select/x-pill-select.tsx +2 -2
  121. package/src/main/server.ts +3 -1
  122. package/src/styles/third-ui.css +8 -0
@@ -10,6 +10,9 @@ import { getActiveProviderConfigUtil, getProductPricing } from './money-price-co
10
10
  import { UserState } from './money-price-types.mjs';
11
11
  import { redirectToCustomerPortal } from './customer-portal.mjs';
12
12
  import { themeButtonGradientClass, themeButtonGradientHoverClass, themeIconColor } from '@windrun-huaiin/base-ui/lib';
13
+ import { AnimeBeamFrame } from '../anime/anime-beam-frame.mjs';
14
+ import 'animejs';
15
+ import '../anime/anime-404-page.mjs';
13
16
 
14
17
  const PLAN_KEYS = ['F1', 'P2', 'U3'];
15
18
  function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPortalApiEndpoint, enableClerkModal = false, enabledBillingTypes, enableSubscriptionUpgrade = true, initialBillingType, disableAutoDetectBilling = false, initUserContext, isInitLoading = false, }) {
@@ -19,11 +22,11 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
19
22
  const providerConfig = useMemo(() => getActiveProviderConfigUtil(config), [config]);
20
23
  const billingOptions = useMemo(() => {
21
24
  const options = data.billingSwitch.options;
22
- // 如果配置了 enabledBillingTypes,只显示配置的类型
25
+ // If enabledBillingTypes is configured, show only those billing types.
23
26
  if (enabledBillingTypes === null || enabledBillingTypes === void 0 ? void 0 : enabledBillingTypes.length) {
24
27
  return options.filter(option => enabledBillingTypes.includes(option.key));
25
28
  }
26
- // 否则显示所有配置的选项
29
+ // Otherwise show all configured options.
27
30
  return options;
28
31
  }, [data.billingSwitch.options, enabledBillingTypes]);
29
32
  const billingOptionMap = useMemo(() => {
@@ -35,11 +38,11 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
35
38
  const defaultBilling = useMemo(() => {
36
39
  var _a;
37
40
  const defaultKey = data.billingSwitch.defaultKey;
38
- // 如果默认值在可用选项中,使用默认值
41
+ // Use the default value when it is available.
39
42
  if (billingOptions.some(opt => opt.key === defaultKey)) {
40
43
  return defaultKey;
41
44
  }
42
- // 否则使用第一个可用选项
45
+ // Otherwise use the first available option.
43
46
  return ((_a = billingOptions[0]) === null || _a === void 0 ? void 0 : _a.key) || 'monthly';
44
47
  }, [data.billingSwitch.defaultKey, billingOptions]);
45
48
  const resolvedInitialBilling = useMemo(() => {
@@ -51,18 +54,18 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
51
54
  }, [initialBillingType, billingOptions, defaultBilling]);
52
55
  const priceIdsByCycle = useMemo(() => {
53
56
  const priceIds = {};
54
- // 为每个可用的计费类型创建价格ID数组
57
+ // Build a price ID list for each available billing type.
55
58
  billingOptions.forEach(option => {
56
59
  priceIds[option.key] = [];
57
60
  if (option.key === 'onetime') {
58
- // 处理积分包产品
61
+ // Handle credit pack products.
59
62
  const creditPacks = providerConfig.creditPackProducts || {};
60
63
  Object.values(creditPacks).forEach((pack) => {
61
64
  priceIds[option.key].push(pack.priceId);
62
65
  });
63
66
  }
64
67
  else {
65
- // 处理订阅产品
68
+ // Handle subscription products.
66
69
  const products = providerConfig.subscriptionProducts || providerConfig.products || {};
67
70
  PLAN_KEYS.forEach(planKey => {
68
71
  const product = products[planKey];
@@ -261,7 +264,7 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
261
264
  userContext,
262
265
  enableSubscriptionUpgrade
263
266
  ]);
264
- // 根据当前计费类型动态选择要显示的 plans
267
+ // Select visible plans dynamically based on the current billing type.
265
268
  const currentPlans = useMemo(() => {
266
269
  if (billingType === 'onetime') {
267
270
  return data.creditsPlans || [];
@@ -286,11 +289,11 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
286
289
  const discountBadgeText = useMemo(() => {
287
290
  if (!(selectedBillingOption === null || selectedBillingOption === void 0 ? void 0 : selectedBillingOption.discountText))
288
291
  return null;
289
- // 对于 onetime 模式,直接显示 discountText,不依赖 discountPercent
292
+ // In one-time mode, show discountText directly without relying on discountPercent.
290
293
  if (billingType === 'onetime') {
291
294
  return selectedBillingOption.discountText;
292
295
  }
293
- // 对于订阅模式,查找 discountPercent 并替换
296
+ // In subscription mode, find discountPercent and interpolate it.
294
297
  let discountPercent = null;
295
298
  const products = providerConfig.subscriptionProducts || providerConfig.products || {};
296
299
  PLAN_KEYS.forEach(planKey => {
@@ -304,7 +307,7 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
304
307
  return null;
305
308
  return selectedBillingOption.discountText.replace('{percent}', String(discountPercent));
306
309
  }, [selectedBillingOption, providerConfig, billingType]);
307
- // 配置移动端BillingTypeButton悬浮样式
310
+ // Configure the mobile floating style for BillingTypeButton.
308
311
  return (jsxs(Fragment, { children: [jsx("div", { className: "flex justify-center mb-6 max-md:sticky max-md:top-30 max-md:z-30 max-md:py-2 max-md:bg-transparent", children: jsx("div", { className: "inline-flex bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-700 rounded-full px-2 py-2 sm:px-3 sm:py-3 max-md:w-full max-md:max-w-[340px] max-md:mx-auto shadow-sm", "data-billing-switch": true, children: billingOptions.map(option => {
309
312
  const isActive = option.key === billingType;
310
313
  const buttonClasses = isActive
@@ -313,6 +316,7 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
313
316
  const showBadge = option.key === billingType && !!discountBadgeText;
314
317
  return (jsxs("div", { className: "relative flex items-center justify-center mx-1", children: [showBadge && (jsx("span", { className: "absolute z-10 left-1/2 -translate-x-1/2 -top-3 sm:-top-4 translate-y-[-50%] px-3 py-0.5 text-[0.625rem] sm:text-xs rounded-md bg-yellow-100 text-yellow-800 font-semibold shadow-sm whitespace-nowrap", children: discountBadgeText })), jsx("button", { className: cn('text-sm md:text-base font-medium transition relative text-center z-10 px-2 sm:px-4 py-2 min-w-[100px] sm:min-w-[120px]', buttonClasses), type: "button", "data-billing-button": option.key, onClick: () => setUserSelectedBillingType(option.key), children: option.name })] }, option.key));
315
318
  }) }) }), jsx("div", { className: "w-full", children: jsx("div", { className: "flex flex-wrap justify-center gap-5 md:gap-6 xl:gap-8 w-full max-w-6xl mx-auto", children: currentPlans.map((plan) => {
319
+ var _a, _b;
316
320
  const planKey = plan.key;
317
321
  if (!PLAN_KEYS.includes(planKey)) {
318
322
  console.warn(`Unknown plan key "${plan.key}" detected in pricing plans`);
@@ -321,13 +325,21 @@ function MoneyPriceInteractive({ data, config, checkoutApiEndpoint, customerPort
321
325
  const pricing = getPricingForPlan(planKey);
322
326
  const showBillingSubtitle = plan.showBillingSubTitle !== false;
323
327
  const hasDiscount = !!pricing.discountPercent && !!pricing.originalAmount;
324
- // 移动端宽度样式
325
- return (jsxs("div", { "data-price-plan": planKey, className: cn('flex flex-col bg-white dark:bg-gray-800/60 rounded-2xl border border-gray-300 dark:border-[#7c3aed40] transition p-5 md:p-8 h-full shadow-sm dark:shadow-none w-[85vw] max-w-[360px]', 'md:w-[clamp(280px,32vw,360px)] md:max-w-[360px] md:shrink-0', 'hover:border-2 hover:border-current', 'focus-within:border-2 focus-within:border-current', themeIconColor), style: { minHeight: maxFeaturesCount * (isTouchDevice ? 86 : 100) }, children: [jsxs("div", { className: "flex items-center gap-2 mb-2", children: [jsx("span", { className: "text-lg md: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)))] }), jsxs("div", { className: "flex flex-col items-start w-full", "data-price-container": planKey, children: [jsxs("div", { className: "flex items-end gap-2", children: [jsx("span", { className: "text-3xl md:text-4xl font-extrabold text-gray-900 dark:text-gray-100", "data-price-value": planKey, children: pricing.amount === 0 ? 'Free' : `${data.currency}${pricing.amount}` }), pricing.amount > 0 && (jsx("span", { className: "text-base md:text-lg text-gray-700 dark:text-gray-300 font-medium mb-1", "data-price-unit": planKey, children: (selectedBillingOption === null || selectedBillingOption === void 0 ? void 0 : selectedBillingOption.unit) || '/month' }))] }), jsxs("div", { className: "flex flex-col md:flex-row items-start md:items-center gap-1 md:gap-2 min-h-[28px] mt-1", children: [hasDiscount && (jsxs(Fragment, { children: [jsxs("span", { className: "text-sm md:text-base text-gray-400 line-through", "data-price-original": planKey, children: [data.currency, pricing.originalAmount] }), (selectedBillingOption === null || selectedBillingOption === void 0 ? void 0 : selectedBillingOption.discountText) && (jsx("span", { className: "px-2 py-0.5 text-[11px] md:text-xs rounded bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 font-semibold align-middle", "data-price-discount": planKey, children: selectedBillingOption.discountText.replace('{percent}', String(pricing.discountPercent)) }))] })), jsx("div", { className: cn('flex items-center gap-2 text-[11px] md:text-xs', !showBillingSubtitle && 'opacity-0 select-none'), "data-price-subtitle": planKey, children: showBillingSubtitle && billingType === 'onetime' ? (
326
- // OneTime 模式下的特殊处理:普通文本 + 带样式的产品副标题
327
- jsxs(Fragment, { children: [(selectedBillingOption === null || selectedBillingOption === void 0 ? void 0 : selectedBillingOption.subTitle) && (jsx("span", { className: "text-[11px] md:text-xs text-gray-700 dark:text-gray-300 font-medium", children: selectedBillingOption.subTitle })), plan.subtitle && (jsxs("span", { className: "px-2 py-0.5 text-[11px] md:text-xs rounded bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 font-semibold align-middle", children: ["+", plan.subtitle] }))] })) : (
328
- // 其他模式下保持原逻辑
329
- showBillingSubtitle && (jsx("span", { className: "text-[11px] md:text-xs text-gray-700 dark:text-gray-300 font-medium", children: (selectedBillingOption === null || selectedBillingOption === void 0 ? void 0 : selectedBillingOption.subTitle) || '' }))) })] })] }), jsx("ul", { className: "flex-1 mb-6 mt-4 text-xs md:text-sm leading-5", children: getFeatureRows(plan).map((feature, i) => (jsxs("li", { className: "flex items-start gap-2 mb-2 min-h-[24px] md:min-h-[28px]", "data-feature-item": `${planKey}-${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("div", { className: "flex-1 text-gray-800 dark:text-gray-200", children: [jsx("span", { children: feature.description }), feature.tooltip && (jsx("span", { className: "block text-[11px] text-gray-500 dark:text-gray-400 mt-1", children: feature.tooltip }))] })) : (jsx("span", { children: "\u00A0" }))] }, i))) }), jsx("div", { className: "flex-1" }), jsx(MoneyPriceButton, { planKey: planKey, userContext: userContext, billingType: billingType, onAuth: handleAuth, onAction: handleAction, texts: data.buttonTexts, isProcessing: (processingTarget === null || processingTarget === void 0 ? void 0 : processingTarget.plan) === planKey &&
330
- (processingTarget === null || processingTarget === void 0 ? void 0 : processingTarget.billing) === billingType, isAnyProcessing: !!processingTarget, isInitLoading: isInitLoading, enableSubscriptionUpgrade: enableSubscriptionUpgrade })] }, plan.key));
328
+ const hasStrictDiffAnime = Object.prototype.hasOwnProperty.call((_a = plan.strictDiffAnime) !== null && _a !== void 0 ? _a : {}, billingType);
329
+ const animeTone = hasStrictDiffAnime
330
+ ? (_b = plan.strictDiffAnime) === null || _b === void 0 ? void 0 : _b[billingType]
331
+ : plan.animeTone;
332
+ const hasAnimeTone = !!animeTone;
333
+ return (jsx(AnimeBeamFrame, { active: false, interactive: hasAnimeTone, tone: animeTone !== null && animeTone !== void 0 ? animeTone : 'theme', radius: 16, className: cn('h-full w-[85vw] max-w-[360px]', 'md:w-[clamp(280px,32vw,360px)] md:max-w-[360px] md:shrink-0'), children: jsxs("div", { "data-price-plan": planKey, className: cn('flex flex-col bg-white dark:bg-gray-800/60 rounded-2xl border border-gray-300 dark:border-[#7c3aed40] transition p-5 md:p-8 h-full shadow-sm dark:shadow-none', !hasAnimeTone && [
334
+ 'hover:border-current',
335
+ 'focus-within:border-current',
336
+ themeIconColor,
337
+ ]), style: { minHeight: maxFeaturesCount * (isTouchDevice ? 86 : 100) }, children: [jsxs("div", { className: "flex items-center gap-2 mb-2", children: [jsx("span", { className: "text-lg md: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)))] }), jsxs("div", { className: "flex flex-col items-start w-full", "data-price-container": planKey, children: [jsxs("div", { className: "flex items-end gap-2", children: [jsx("span", { className: "text-3xl md:text-4xl font-extrabold text-gray-900 dark:text-gray-100", "data-price-value": planKey, children: pricing.amount === 0 ? 'Free' : `${data.currency}${pricing.amount}` }), pricing.amount > 0 && (jsx("span", { className: "text-base md:text-lg text-gray-700 dark:text-gray-300 font-medium mb-1", "data-price-unit": planKey, children: (selectedBillingOption === null || selectedBillingOption === void 0 ? void 0 : selectedBillingOption.unit) || '/month' }))] }), jsxs("div", { className: "flex flex-col md:flex-row items-start md:items-center gap-1 md:gap-2 min-h-[28px] mt-1", children: [hasDiscount && (jsxs(Fragment, { children: [jsxs("span", { className: "text-sm md:text-base text-gray-400 line-through", "data-price-original": planKey, children: [data.currency, pricing.originalAmount] }), (selectedBillingOption === null || selectedBillingOption === void 0 ? void 0 : selectedBillingOption.discountText) && (jsx("span", { className: "px-2 py-0.5 text-[11px] md:text-xs rounded bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 font-semibold align-middle", "data-price-discount": planKey, children: selectedBillingOption.discountText.replace('{percent}', String(pricing.discountPercent)) }))] })), jsx("div", { className: cn('flex items-center gap-2 text-[11px] md:text-xs', !showBillingSubtitle && 'opacity-0 select-none'), "data-price-subtitle": planKey, children: showBillingSubtitle && billingType === 'onetime' ? (
338
+ // Special one-time mode rendering: plain text plus styled product subtitle.
339
+ jsxs(Fragment, { children: [(selectedBillingOption === null || selectedBillingOption === void 0 ? void 0 : selectedBillingOption.subTitle) && (jsx("span", { className: "text-[11px] md:text-xs text-gray-700 dark:text-gray-300 font-medium", children: selectedBillingOption.subTitle })), plan.subtitle && (jsxs("span", { className: "px-2 py-0.5 text-[11px] md:text-xs rounded bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 font-semibold align-middle", children: ["+", plan.subtitle] }))] })) : (
340
+ // Keep the original rendering for other modes.
341
+ showBillingSubtitle && (jsx("span", { className: "text-[11px] md:text-xs text-gray-700 dark:text-gray-300 font-medium", children: (selectedBillingOption === null || selectedBillingOption === void 0 ? void 0 : selectedBillingOption.subTitle) || '' }))) })] })] }), jsx("ul", { className: "flex-1 mb-6 mt-4 text-xs md:text-sm leading-5", children: getFeatureRows(plan).map((feature, i) => (jsxs("li", { className: "flex items-start gap-2 mb-2 min-h-[24px] md:min-h-[28px]", "data-feature-item": `${planKey}-${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("div", { className: "flex-1 text-gray-800 dark:text-gray-200", children: [jsx("span", { children: feature.description }), feature.tooltip && (jsx("span", { className: "block text-[11px] text-gray-500 dark:text-gray-400 mt-1", children: feature.tooltip }))] })) : (jsx("span", { children: "\u00A0" }))] }, i))) }), jsx("div", { className: "flex-1" }), jsx(MoneyPriceButton, { planKey: planKey, userContext: userContext, billingType: billingType, onAuth: handleAuth, onAction: handleAction, texts: data.buttonTexts, isProcessing: (processingTarget === null || processingTarget === void 0 ? void 0 : processingTarget.plan) === planKey &&
342
+ (processingTarget === null || processingTarget === void 0 ? void 0 : processingTarget.billing) === billingType, isAnyProcessing: !!processingTarget, isInitLoading: isInitLoading, enableSubscriptionUpgrade: enableSubscriptionUpgrade })] }) }, `${billingType}-${plan.key}-${animeTone !== null && animeTone !== void 0 ? animeTone : 'none'}`));
331
343
  }) }) })] }));
332
344
  }
333
345
 
@@ -1,7 +1,7 @@
1
1
  import type { XCredit, XSubscription, XUser } from '../../clerk/fingerprint/types';
2
2
  /**
3
3
  * Money Price Component Types
4
- * 价格组件类型定义
4
+ * Pricing component type definitions.
5
5
  */
6
6
  export declare enum UserState {
7
7
  Anonymous = "anonymous",
@@ -117,6 +117,8 @@ export interface MoneyPriceButtonProps {
117
117
  isInitLoading: boolean;
118
118
  enableSubscriptionUpgrade?: boolean;
119
119
  }
120
+ export type MoneyPriceAnimeTone = 'theme' | 'rainbow' | 'mono' | 'warm' | 'cool';
121
+ export type MoneyPriceStrictDiffAnime = Record<string, MoneyPriceAnimeTone | null | undefined>;
120
122
  export interface MoneyPriceData {
121
123
  title: string;
122
124
  subtitle: string;
@@ -133,6 +135,8 @@ export interface MoneyPriceData {
133
135
  subscriptionPlans: Array<{
134
136
  key: string;
135
137
  title: string;
138
+ animeTone?: MoneyPriceAnimeTone;
139
+ strictDiffAnime?: MoneyPriceStrictDiffAnime;
136
140
  showBillingSubTitle?: boolean;
137
141
  titleTags?: string[];
138
142
  features?: Array<{
@@ -146,6 +150,8 @@ export interface MoneyPriceData {
146
150
  key: string;
147
151
  title: string;
148
152
  subtitle?: string;
153
+ animeTone?: MoneyPriceAnimeTone;
154
+ strictDiffAnime?: MoneyPriceStrictDiffAnime;
149
155
  showBillingSubTitle?: boolean;
150
156
  titleTags?: string[];
151
157
  features?: Array<{
@@ -2,9 +2,9 @@
2
2
 
3
3
  /**
4
4
  * Money Price Component Types
5
- * 价格组件类型定义
5
+ * Pricing component type definitions.
6
6
  */
7
- // 用户状态枚举
7
+ // User status enum.
8
8
  exports.UserState = void 0;
9
9
  (function (UserState) {
10
10
  UserState["Anonymous"] = "anonymous";
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Money Price Component Types
3
- * 价格组件类型定义
3
+ * Pricing component type definitions.
4
4
  */
5
- // 用户状态枚举
5
+ // User status enum.
6
6
  var UserState;
7
7
  (function (UserState) {
8
8
  UserState["Anonymous"] = "anonymous";
@@ -1,5 +1,5 @@
1
1
  export { MoneyPrice } from './money-price';
2
2
  export { getActiveProviderConfigUtil, getCreditsFromPriceIdUtil, getPriceConfigUtil, } from './money-price-config-util';
3
3
  export { buildMoneyPriceData } from './money-price-data';
4
- export type { MoneyPriceConfig, MoneyPriceProps, MoneyPriceInteractiveProps, MoneyPriceButtonProps, MoneyPriceData, InitUserContext, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext, } from './money-price-types';
4
+ export type { MoneyPriceConfig, MoneyPriceProps, MoneyPriceInteractiveProps, MoneyPriceButtonProps, MoneyPriceData, MoneyPriceAnimeTone, MoneyPriceStrictDiffAnime, InitUserContext, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext, } from './money-price-types';
5
5
  export { UserState } from './money-price-types';
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from 'react';
2
+ interface CreativeLeftPanelProps {
3
+ children: ReactNode;
4
+ className?: string;
5
+ }
6
+ export declare function CreativeLeftPanel({ children, className }: CreativeLeftPanelProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var react = require('motion/react');
6
+
7
+ function CreativeLeftPanel({ children, className = '' }) {
8
+ return (jsxRuntime.jsx("div", { className: `relative h-full ${className}`, children: jsxRuntime.jsxs("div", { className: "relative h-full overflow-hidden rounded-[28px] border border-border/60 bg-background/95 backdrop-blur-2xl shadow-xl", children: [jsxRuntime.jsx("div", { className: "absolute -left-1 -top-1 z-30", children: jsxRuntime.jsxs("div", { className: "relative h-28 w-32 bg-linear-to-br from-orange-500 via-orange-600 to-orange-700 rounded-br-[2.75rem] shadow-lg", children: [jsxRuntime.jsx("div", { className: "absolute left-4 top-4 h-10 w-10 rounded-full bg-white/30 blur-sm" }), jsxRuntime.jsx("div", { className: "absolute left-6 top-6 h-5 w-14 rotate-12 rounded bg-white/20" })] }) }), jsxRuntime.jsxs("svg", { className: "absolute bottom-0 left-0 z-20 h-[380px] w-full pointer-events-none", viewBox: "0 0 680 420", preserveAspectRatio: "none", fill: "none", children: [jsxRuntime.jsx("defs", { children: jsxRuntime.jsxs("linearGradient", { id: "leftGlow", x1: "0%", y1: "100%", x2: "100%", y2: "30%", children: [jsxRuntime.jsx("stop", { offset: "0%", stopColor: "#f97316", stopOpacity: "0.25" }), jsxRuntime.jsx("stop", { offset: "100%", stopColor: "#fb923c", stopOpacity: "0.08" })] }) }), jsxRuntime.jsx(react.motion.path, { d: "M 0 380 \n Q 85 425 165 355 \n Q 255 265 355 285 \n Q 480 310 555 245 \n Q 615 195 680 235", stroke: "url(#leftGlow)", strokeWidth: "22", strokeLinecap: "round", strokeLinejoin: "round", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.4, ease: "easeOut" } }), jsxRuntime.jsx(react.motion.path, { d: "M 0 380 \n Q 85 425 165 355 \n Q 255 265 355 285 \n Q 480 310 555 245 \n Q 615 195 680 235", stroke: "#fbbf24", strokeWidth: "3", strokeOpacity: "0.45", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.6, ease: "easeOut" } })] }), jsxRuntime.jsx("div", { className: "relative z-10 h-full p-6 sm:p-8 pb-16", children: children })] }) }));
9
+ }
10
+
11
+ exports.CreativeLeftPanel = CreativeLeftPanel;
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { motion } from 'motion/react';
4
+
5
+ function CreativeLeftPanel({ children, className = '' }) {
6
+ return (jsx("div", { className: `relative h-full ${className}`, children: jsxs("div", { className: "relative h-full overflow-hidden rounded-[28px] border border-border/60 bg-background/95 backdrop-blur-2xl shadow-xl", children: [jsx("div", { className: "absolute -left-1 -top-1 z-30", children: jsxs("div", { className: "relative h-28 w-32 bg-linear-to-br from-orange-500 via-orange-600 to-orange-700 rounded-br-[2.75rem] shadow-lg", children: [jsx("div", { className: "absolute left-4 top-4 h-10 w-10 rounded-full bg-white/30 blur-sm" }), jsx("div", { className: "absolute left-6 top-6 h-5 w-14 rotate-12 rounded bg-white/20" })] }) }), jsxs("svg", { className: "absolute bottom-0 left-0 z-20 h-[380px] w-full pointer-events-none", viewBox: "0 0 680 420", preserveAspectRatio: "none", fill: "none", children: [jsx("defs", { children: jsxs("linearGradient", { id: "leftGlow", x1: "0%", y1: "100%", x2: "100%", y2: "30%", children: [jsx("stop", { offset: "0%", stopColor: "#f97316", stopOpacity: "0.25" }), jsx("stop", { offset: "100%", stopColor: "#fb923c", stopOpacity: "0.08" })] }) }), jsx(motion.path, { d: "M 0 380 \n Q 85 425 165 355 \n Q 255 265 355 285 \n Q 480 310 555 245 \n Q 615 195 680 235", stroke: "url(#leftGlow)", strokeWidth: "22", strokeLinecap: "round", strokeLinejoin: "round", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.4, ease: "easeOut" } }), jsx(motion.path, { d: "M 0 380 \n Q 85 425 165 355 \n Q 255 265 355 285 \n Q 480 310 555 245 \n Q 615 195 680 235", stroke: "#fbbf24", strokeWidth: "3", strokeOpacity: "0.45", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.6, ease: "easeOut" } })] }), jsx("div", { className: "relative z-10 h-full p-6 sm:p-8 pb-16", children: children })] }) }));
7
+ }
8
+
9
+ export { CreativeLeftPanel };
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from 'react';
2
+ interface CreativeRightPanelProps {
3
+ children: ReactNode;
4
+ className?: string;
5
+ }
6
+ export declare function CreativeRightPanel({ children, className }: CreativeRightPanelProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var react = require('motion/react');
6
+
7
+ function CreativeRightPanel({ children, className = '' }) {
8
+ return (jsxRuntime.jsx("div", { className: `relative h-full ${className}`, children: jsxRuntime.jsxs("div", { className: "relative h-full overflow-hidden rounded-[28px] border border-border/60 bg-background/95 backdrop-blur-2xl shadow-xl", children: [jsxRuntime.jsx("svg", { className: "absolute bottom-0 right-0 z-20 h-[380px] w-full pointer-events-none", viewBox: "0 0 680 420", preserveAspectRatio: "none", fill: "none", children: jsxRuntime.jsx(react.motion.path, { d: "M 0 235 \n Q 65 195 145 245 \n Q 220 310 345 285 \n Q 445 265 535 355 \n Q 615 425 680 380", stroke: "#f97316", strokeWidth: "18", strokeOpacity: "0.18", strokeLinecap: "round", strokeLinejoin: "round", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.2, ease: "easeOut" } }) }), jsxRuntime.jsx("div", { className: "relative z-10 h-full p-6 sm:p-8 pb-12", children: children })] }) }));
9
+ }
10
+
11
+ exports.CreativeRightPanel = CreativeRightPanel;
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { motion } from 'motion/react';
4
+
5
+ function CreativeRightPanel({ children, className = '' }) {
6
+ return (jsx("div", { className: `relative h-full ${className}`, children: jsxs("div", { className: "relative h-full overflow-hidden rounded-[28px] border border-border/60 bg-background/95 backdrop-blur-2xl shadow-xl", children: [jsx("svg", { className: "absolute bottom-0 right-0 z-20 h-[380px] w-full pointer-events-none", viewBox: "0 0 680 420", preserveAspectRatio: "none", fill: "none", children: jsx(motion.path, { d: "M 0 235 \n Q 65 195 145 245 \n Q 220 310 345 285 \n Q 445 265 535 355 \n Q 615 425 680 380", stroke: "#f97316", strokeWidth: "18", strokeOpacity: "0.18", strokeLinecap: "round", strokeLinejoin: "round", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.2, ease: "easeOut" } }) }), jsx("div", { className: "relative z-10 h-full p-6 sm:p-8 pb-12", children: children })] }) }));
7
+ }
8
+
9
+ export { CreativeRightPanel };
@@ -26,7 +26,7 @@ function XPillSelect(props) {
26
26
  const isAllSelected = props.mode === 'multiple' &&
27
27
  allOptionValues.length > 0 &&
28
28
  allOptionValues.every((value) => selectedValues.includes(value));
29
- const aggregatedSelectedLabel = isAllSelected ? (allSelectedLabel === null || allSelectedLabel === void 0 ? void 0 : allSelectedLabel.trim()) || '全部' : null;
29
+ const aggregatedSelectedLabel = isAllSelected ? (allSelectedLabel === null || allSelectedLabel === void 0 ? void 0 : allSelectedLabel.trim()) || 'All' : null;
30
30
  const hasVisiblePillLimit = props.mode === 'multiple' && typeof maxVisiblePills === 'number' && maxVisiblePills >= 0;
31
31
  const visibleSelectedValues = aggregatedSelectedLabel || !hasVisiblePillLimit
32
32
  ? selectedValues
@@ -126,7 +126,7 @@ function XPillSelect(props) {
126
126
  event.stopPropagation();
127
127
  removeValue(selectedValue);
128
128
  }, disabled: disabled, className: utils.cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'gap-1 px-2.5 py-0.5 text-[11px]' : 'gap-1.5 px-3 py-1 text-xs', lib.themeBgColor, lib.themeIconColor, 'hover:brightness-95 dark:hover:brightness-110', disabled && 'cursor-not-allowed opacity-60'), title: optionLabel, children: jsxRuntime.jsx("span", { className: utils.cn('truncate', maxPillWidthClassName), children: optionLabel }) }, selectedValue));
129
- }), hiddenSelectedCount > 0 ? (jsxRuntime.jsxs("span", { className: utils.cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'px-2.5 py-0.5 text-[11px]' : 'px-3 py-1 text-xs', 'bg-neutral-200 text-neutral-700 dark:bg-neutral-800 dark:text-white'), title: `还有 ${hiddenSelectedCount} 项未展开`, children: ["+", hiddenSelectedCount] })) : null] }))) : (jsxRuntime.jsx("span", { className: utils.cn(compact ? 'text-xs' : 'text-sm', 'text-slate-500 dark:text-slate-400'), children: emptyLabel })) }), jsxRuntime.jsx(icons.ChevronDownIcon, { className: utils.cn(compact ? 'h-3.5 w-3.5' : 'h-4 w-4', 'shrink-0 text-slate-500 transition-transform dark:text-slate-400', open && 'rotate-180') })] }), open ? (jsxRuntime.jsxs("div", { role: "listbox", "aria-multiselectable": props.mode === 'multiple' ? true : undefined, className: utils.cn('absolute left-0 right-0 top-[calc(100%+0.375rem)] z-50 rounded-3xl border border-black/10 bg-neutral-100 shadow-xl dark:border-white/10 dark:bg-neutral-900', compact ? 'space-y-2.5 p-3' : 'space-y-3 p-4', open && lib.themeBorderColor), children: [inputEnabled ? (jsxRuntime.jsx("input", { value: draftValue, onChange: (event) => setDraftValue(event.target.value.replaceAll(',', '')), onKeyDown: (event) => {
129
+ }), hiddenSelectedCount > 0 ? (jsxRuntime.jsxs("span", { className: utils.cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'px-2.5 py-0.5 text-[11px]' : 'px-3 py-1 text-xs', 'bg-neutral-200 text-neutral-700 dark:bg-neutral-800 dark:text-white'), title: `${hiddenSelectedCount} items remain unexpanded`, children: ["+", hiddenSelectedCount] })) : null] }))) : (jsxRuntime.jsx("span", { className: utils.cn(compact ? 'text-xs' : 'text-sm', 'text-slate-500 dark:text-slate-400'), children: emptyLabel })) }), jsxRuntime.jsx(icons.ChevronDownIcon, { className: utils.cn(compact ? 'h-3.5 w-3.5' : 'h-4 w-4', 'shrink-0 text-slate-500 transition-transform dark:text-slate-400', open && 'rotate-180') })] }), open ? (jsxRuntime.jsxs("div", { role: "listbox", "aria-multiselectable": props.mode === 'multiple' ? true : undefined, className: utils.cn('absolute left-0 right-0 top-[calc(100%+0.375rem)] z-50 rounded-3xl border border-black/10 bg-neutral-100 shadow-xl dark:border-white/10 dark:bg-neutral-900', compact ? 'space-y-2.5 p-3' : 'space-y-3 p-4', open && lib.themeBorderColor), children: [inputEnabled ? (jsxRuntime.jsx("input", { value: draftValue, onChange: (event) => setDraftValue(event.target.value.replaceAll(',', '')), onKeyDown: (event) => {
130
130
  if (event.key !== 'Enter') {
131
131
  return;
132
132
  }
@@ -24,7 +24,7 @@ function XPillSelect(props) {
24
24
  const isAllSelected = props.mode === 'multiple' &&
25
25
  allOptionValues.length > 0 &&
26
26
  allOptionValues.every((value) => selectedValues.includes(value));
27
- const aggregatedSelectedLabel = isAllSelected ? (allSelectedLabel === null || allSelectedLabel === void 0 ? void 0 : allSelectedLabel.trim()) || '全部' : null;
27
+ const aggregatedSelectedLabel = isAllSelected ? (allSelectedLabel === null || allSelectedLabel === void 0 ? void 0 : allSelectedLabel.trim()) || 'All' : null;
28
28
  const hasVisiblePillLimit = props.mode === 'multiple' && typeof maxVisiblePills === 'number' && maxVisiblePills >= 0;
29
29
  const visibleSelectedValues = aggregatedSelectedLabel || !hasVisiblePillLimit
30
30
  ? selectedValues
@@ -124,7 +124,7 @@ function XPillSelect(props) {
124
124
  event.stopPropagation();
125
125
  removeValue(selectedValue);
126
126
  }, disabled: disabled, className: cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'gap-1 px-2.5 py-0.5 text-[11px]' : 'gap-1.5 px-3 py-1 text-xs', themeBgColor, themeIconColor, 'hover:brightness-95 dark:hover:brightness-110', disabled && 'cursor-not-allowed opacity-60'), title: optionLabel, children: jsx("span", { className: cn('truncate', maxPillWidthClassName), children: optionLabel }) }, selectedValue));
127
- }), hiddenSelectedCount > 0 ? (jsxs("span", { className: cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'px-2.5 py-0.5 text-[11px]' : 'px-3 py-1 text-xs', 'bg-neutral-200 text-neutral-700 dark:bg-neutral-800 dark:text-white'), title: `还有 ${hiddenSelectedCount} 项未展开`, children: ["+", hiddenSelectedCount] })) : null] }))) : (jsx("span", { className: cn(compact ? 'text-xs' : 'text-sm', 'text-slate-500 dark:text-slate-400'), children: emptyLabel })) }), jsx(ChevronDownIcon, { className: cn(compact ? 'h-3.5 w-3.5' : 'h-4 w-4', 'shrink-0 text-slate-500 transition-transform dark:text-slate-400', open && 'rotate-180') })] }), open ? (jsxs("div", { role: "listbox", "aria-multiselectable": props.mode === 'multiple' ? true : undefined, className: cn('absolute left-0 right-0 top-[calc(100%+0.375rem)] z-50 rounded-3xl border border-black/10 bg-neutral-100 shadow-xl dark:border-white/10 dark:bg-neutral-900', compact ? 'space-y-2.5 p-3' : 'space-y-3 p-4', open && themeBorderColor), children: [inputEnabled ? (jsx("input", { value: draftValue, onChange: (event) => setDraftValue(event.target.value.replaceAll(',', '')), onKeyDown: (event) => {
127
+ }), hiddenSelectedCount > 0 ? (jsxs("span", { className: cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'px-2.5 py-0.5 text-[11px]' : 'px-3 py-1 text-xs', 'bg-neutral-200 text-neutral-700 dark:bg-neutral-800 dark:text-white'), title: `${hiddenSelectedCount} items remain unexpanded`, children: ["+", hiddenSelectedCount] })) : null] }))) : (jsx("span", { className: cn(compact ? 'text-xs' : 'text-sm', 'text-slate-500 dark:text-slate-400'), children: emptyLabel })) }), jsx(ChevronDownIcon, { className: cn(compact ? 'h-3.5 w-3.5' : 'h-4 w-4', 'shrink-0 text-slate-500 transition-transform dark:text-slate-400', open && 'rotate-180') })] }), open ? (jsxs("div", { role: "listbox", "aria-multiselectable": props.mode === 'multiple' ? true : undefined, className: cn('absolute left-0 right-0 top-[calc(100%+0.375rem)] z-50 rounded-3xl border border-black/10 bg-neutral-100 shadow-xl dark:border-white/10 dark:bg-neutral-900', compact ? 'space-y-2.5 p-3' : 'space-y-3 p-4', open && themeBorderColor), children: [inputEnabled ? (jsx("input", { value: draftValue, onChange: (event) => setDraftValue(event.target.value.replaceAll(',', '')), onKeyDown: (event) => {
128
128
  if (event.key !== 'Enter') {
129
129
  return;
130
130
  }
@@ -12,5 +12,5 @@ export type { CreditOverviewData, CreditBucket, CreditBucketStatus, Subscription
12
12
  export { MoneyPrice } from './money-price/money-price';
13
13
  export { getActiveProviderConfigUtil, getCreditsFromPriceIdUtil, getPriceConfigUtil } from './money-price/money-price-config-util';
14
14
  export { buildMoneyPriceData } from './money-price/money-price-data';
15
- export type { MoneyPriceConfig, MoneyPriceProps, MoneyPriceInteractiveProps, MoneyPriceButtonProps, MoneyPriceData, InitUserContext, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext } from './money-price/money-price-types';
15
+ export type { MoneyPriceConfig, MoneyPriceProps, MoneyPriceInteractiveProps, MoneyPriceButtonProps, MoneyPriceData, MoneyPriceAnimeTone, MoneyPriceStrictDiffAnime, InitUserContext, PaymentProvider, PaymentProviderConfig, EnhancePricePlan, SubscriptionProductConfig, CreditPackProductConfig, UserContext } from './money-price/money-price-types';
16
16
  export { UserState } from './money-price/money-price-types';
@@ -7,6 +7,7 @@ var react = require('motion/react');
7
7
  var utils = require('@windrun-huaiin/lib/utils');
8
8
  var animeBeamFrame = require('./anime/anime-beam-frame.js');
9
9
  require('animejs');
10
+ require('./anime/anime-404-page.js');
10
11
 
11
12
  const DEFAULT_THEME_COLOR = '#3b82f6';
12
13
  const EXIT_DURATION_MS = 260;
@@ -5,6 +5,7 @@ import { motion } from 'motion/react';
5
5
  import { cn } from '@windrun-huaiin/lib/utils';
6
6
  import { AnimeBeamFrame } from './anime/anime-beam-frame.mjs';
7
7
  import 'animejs';
8
+ import './anime/anime-404-page.mjs';
8
9
 
9
10
  const DEFAULT_THEME_COLOR = '#3b82f6';
10
11
  const EXIT_DURATION_MS = 260;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windrun-huaiin/third-ui",
3
- "version": "30.0.0",
3
+ "version": "31.0.0",
4
4
  "description": "Third-party integrated UI components for windrun-huaiin projects",
5
5
  "exports": {
6
6
  "./clerk": {
@@ -221,9 +221,9 @@
221
221
  "LICENSE"
222
222
  ],
223
223
  "dependencies": {
224
- "@clerk/localizations": "^4.2.2",
225
- "@clerk/nextjs": "^7.0.5",
226
- "@clerk/shared": "^4.3.1",
224
+ "@clerk/localizations": "^4.6.2",
225
+ "@clerk/nextjs": "^7.3.3",
226
+ "@clerk/shared": "^4.10.2",
227
227
  "@fingerprintjs/fingerprintjs": "^5.1.0",
228
228
  "animejs": "^4.4.1",
229
229
  "class-variance-authority": "^0.7.1",
@@ -243,9 +243,9 @@
243
243
  "tslib": "^2.8.1",
244
244
  "unified": "^11.0.5",
245
245
  "zod": "^4.3.6",
246
- "@windrun-huaiin/contracts": "^30.0.0",
247
- "@windrun-huaiin/base-ui": "^30.0.0",
248
- "@windrun-huaiin/lib": "^30.0.0"
246
+ "@windrun-huaiin/base-ui": "^31.0.0",
247
+ "@windrun-huaiin/lib": "^31.0.0",
248
+ "@windrun-huaiin/contracts": "^31.0.0"
249
249
  },
250
250
  "peerDependencies": {
251
251
  "clsx": "^2.1.1",
@@ -281,6 +281,12 @@
281
281
  "publishConfig": {
282
282
  "access": "public"
283
283
  },
284
+ "homepage": "https://d8ger.com",
285
+ "repository": {
286
+ "type": "git",
287
+ "url": "git+https://github.com/caofanCPU/next-ai-build.git",
288
+ "directory": "packages/third-ui"
289
+ },
284
290
  "scripts": {
285
291
  "build": "rollup -c rollup.config.mjs",
286
292
  "build:prod": "rollup -c rollup.config.mjs",
@@ -188,7 +188,7 @@ export function AIPromptTextarea({
188
188
  }
189
189
  }
190
190
 
191
- // 渲染标题组件
191
+ // Render the title component.
192
192
  const renderTitle = () => {
193
193
  if (!title?.trim()) return null
194
194
 
@@ -200,7 +200,7 @@ export function AIPromptTextarea({
200
200
  )
201
201
  }
202
202
 
203
- // 渲染textarea组件
203
+ // Render the textarea component.
204
204
  const renderTextarea = (isEmbedded = false) => (
205
205
  <textarea
206
206
  ref={textareaRef}
@@ -220,7 +220,7 @@ export function AIPromptTextarea({
220
220
  />
221
221
  )
222
222
 
223
- // 渲染单词计数
223
+ // Render the word count.
224
224
  const renderWordCount = () => {
225
225
  if (!showWordCount) return null
226
226
 
@@ -238,7 +238,7 @@ export function AIPromptTextarea({
238
238
  )
239
239
  }
240
240
 
241
- // 如果有标题且需要嵌入,则渲染内部标题布局
241
+ // Render the embedded title layout when a title is present and embedded mode is enabled.
242
242
  if (embed && (title)) {
243
243
  return (
244
244
  <div className="space-y-2">
@@ -256,7 +256,7 @@ export function AIPromptTextarea({
256
256
  )
257
257
  }
258
258
 
259
- // 默认布局:外部标题或无标题
259
+ // Default layout: external title or no title.
260
260
  return (
261
261
  <div className="space-y-2">
262
262
  {renderTitle()}
@@ -264,4 +264,4 @@ export function AIPromptTextarea({
264
264
  {renderWordCount()}
265
265
  </div>
266
266
  )
267
- }
267
+ }
@@ -0,0 +1,16 @@
1
+ export const clerkAuthModalAppearance = {
2
+ elements: {
3
+ modalContent: '!items-start !pt-16 sm:!pt-24',
4
+ cardBox: '!mt-0',
5
+ },
6
+ };
7
+
8
+ export const clerkAuthPageAppearance = {
9
+ elements: {
10
+ rootBox: 'w-full',
11
+ cardBox: 'mx-auto',
12
+ },
13
+ };
14
+
15
+ export const clerkAuthPageContainerClassName =
16
+ 'flex min-h-[calc(100dvh-var(--fd-banner-height,0px)-var(--fd-header-height,3.5rem))] w-full items-start justify-center px-6 pt-[calc(var(--fd-header-height,3.5rem)+2rem)] pb-6 md:px-8 md:pt-[calc(var(--fd-header-height,3.5rem)+4.5rem)] md:pb-8';
@@ -7,9 +7,7 @@
7
7
 
8
8
  import { SignUpWithFingerprint } from './signup-with-fingerprint-client';
9
9
  import { SignInWithFingerprint } from './signin-with-fingerprint-client';
10
-
11
- const clerkPageContainerClassName =
12
- 'flex min-h-dvh w-full items-start justify-center px-6 pt-[calc(var(--fd-banner-height,0px)+var(--fd-header-height,3.5rem)+1rem)] pb-6 md:px-8 md:pt-[calc(var(--fd-banner-height,0px)+var(--fd-header-height,3.5rem)+1.5rem)] md:pb-8';
10
+ import { clerkAuthPageContainerClassName } from './clerk-auth-appearance';
13
11
 
14
12
  /**
15
13
  * Create a SignUp page with fingerprint support
@@ -18,7 +16,7 @@ const clerkPageContainerClassName =
18
16
  export function createSignUpPageWithFingerprint() {
19
17
  return function SignUpPage() {
20
18
  return (
21
- <div className={clerkPageContainerClassName}>
19
+ <div className={clerkAuthPageContainerClassName}>
22
20
  <SignUpWithFingerprint />
23
21
  </div>
24
22
  );
@@ -32,7 +30,7 @@ export function createSignUpPageWithFingerprint() {
32
30
  export function createSignInPageWithFingerprint() {
33
31
  return function SignInPage() {
34
32
  return (
35
- <div className={clerkPageContainerClassName}>
33
+ <div className={clerkAuthPageContainerClassName}>
36
34
  <SignInWithFingerprint />
37
35
  </div>
38
36
  );
@@ -1,14 +1,15 @@
1
1
  import { SignIn, SignUp, Waitlist } from '@clerk/nextjs';
2
-
3
- const clerkPageContainerClassName =
4
- 'flex min-h-dvh w-full items-start justify-center px-6 pt-[calc(var(--fd-banner-height,0px)+var(--fd-header-height,3.5rem)+1rem)] pb-6 md:px-8 md:pt-[calc(var(--fd-banner-height,0px)+var(--fd-header-height,3.5rem)+1.5rem)] md:pb-8';
2
+ import {
3
+ clerkAuthPageAppearance,
4
+ clerkAuthPageContainerClassName,
5
+ } from './clerk-auth-appearance';
5
6
 
6
7
  // Legacy page generators (for backward compatibility)
7
8
  export function createSignInPage() {
8
9
  return function SignInPage() {
9
10
  return (
10
- <div className={clerkPageContainerClassName}>
11
- <SignIn />
11
+ <div className={clerkAuthPageContainerClassName}>
12
+ <SignIn appearance={clerkAuthPageAppearance} />
12
13
  </div>
13
14
  );
14
15
  };
@@ -17,8 +18,8 @@ export function createSignInPage() {
17
18
  export function createSignUpPage() {
18
19
  return function SignUpPage() {
19
20
  return (
20
- <div className={clerkPageContainerClassName}>
21
- <SignUp />
21
+ <div className={clerkAuthPageContainerClassName}>
22
+ <SignUp appearance={clerkAuthPageAppearance} />
22
23
  </div>
23
24
  );
24
25
  };
@@ -27,7 +28,7 @@ export function createSignUpPage() {
27
28
  export function createWaitlistPage() {
28
29
  return function WaitlistPage() {
29
30
  return (
30
- <div className={clerkPageContainerClassName}>
31
+ <div className={clerkAuthPageContainerClassName}>
31
32
  <Waitlist />
32
33
  </div>
33
34
  );
@@ -4,6 +4,7 @@ import { useState } from 'react';
4
4
  import { ClerkLoaded, ClerkLoading, SignInButton, UserButton, useAuth } from "@clerk/nextjs";
5
5
  import { ReceiptTextIcon, ShieldUserIcon } from '@windrun-huaiin/base-ui/icons';
6
6
  import { themeButtonGradientClass } from '@windrun-huaiin/base-ui/lib';
7
+ import { clerkAuthModalAppearance } from './clerk-auth-appearance';
7
8
  import { SignUpButtonWithFingerprint } from './signup-button-with-fingerprint-client';
8
9
 
9
10
  interface ClerkUserData {
@@ -51,11 +52,19 @@ export function ClerkUserClient({ data }: { data: ClerkUserData }) {
51
52
  )}
52
53
  </div>
53
54
  )}
54
- <SignInButton mode={data.clerkAuthInModal ? 'modal' : 'redirect'}>
55
- <button className="w-16 sm:w-20 h-8 sm:h-9 px-1.5 sm:px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-xs sm:text-sm whitespace-nowrap">
56
- {data.signIn}
57
- </button>
58
- </SignInButton>
55
+ {data.clerkAuthInModal ? (
56
+ <SignInButton mode="modal" appearance={clerkAuthModalAppearance}>
57
+ <button className="w-16 sm:w-20 h-8 sm:h-9 px-1.5 sm:px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-xs sm:text-sm whitespace-nowrap">
58
+ {data.signIn}
59
+ </button>
60
+ </SignInButton>
61
+ ) : (
62
+ <SignInButton mode="redirect">
63
+ <button className="w-16 sm:w-20 h-8 sm:h-9 px-1.5 sm:px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-xs sm:text-sm whitespace-nowrap">
64
+ {data.signIn}
65
+ </button>
66
+ </SignInButton>
67
+ )}
59
68
  </>
60
69
  )}
61
70