@windrun-huaiin/third-ui 27.0.0 → 28.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/fuma/base/custom-home-layout.d.ts +0 -5
  2. package/dist/fuma/base/docs-root-provider.d.ts +19 -0
  3. package/dist/fuma/base/docs-root-provider.js +17 -0
  4. package/dist/fuma/base/docs-root-provider.mjs +15 -0
  5. package/dist/fuma/base/index.d.ts +4 -0
  6. package/dist/fuma/base/index.js +12 -7
  7. package/dist/fuma/base/index.mjs +4 -1
  8. package/dist/fuma/base/site-docs-layout.d.ts +11 -0
  9. package/dist/fuma/base/site-docs-layout.js +15 -0
  10. package/dist/fuma/base/site-docs-layout.mjs +13 -0
  11. package/dist/fuma/base/site-home-layout.d.ts +24 -0
  12. package/dist/fuma/base/site-home-layout.js +16 -0
  13. package/dist/fuma/base/site-home-layout.mjs +14 -0
  14. package/dist/fuma/base/site-layout-shared.d.ts +89 -0
  15. package/dist/fuma/base/site-layout-shared.js +48 -0
  16. package/dist/fuma/base/site-layout-shared.mjs +42 -0
  17. package/dist/fuma/base/site-layout.d.ts +4 -120
  18. package/dist/fuma/fuma-page-genarator.js +5 -5
  19. package/dist/fuma/fuma-page-genarator.mjs +1 -1
  20. package/dist/fuma/server/llm-copy-handler.d.ts +2 -0
  21. package/dist/fuma/server/llm-copy-handler.js +7 -0
  22. package/dist/fuma/server/llm-copy-handler.mjs +1 -0
  23. package/dist/fuma/server/page-generator.d.ts +2 -0
  24. package/dist/fuma/server/page-generator.js +7 -0
  25. package/dist/fuma/server/page-generator.mjs +1 -0
  26. package/dist/lib/seo-metadata.js +3 -3
  27. package/dist/lib/seo-metadata.mjs +1 -1
  28. package/dist/lib/seo-util.js +4 -4
  29. package/dist/lib/seo-util.mjs +1 -1
  30. package/dist/main/credit/credit-nav-button.js +25 -1
  31. package/dist/main/credit/credit-nav-button.mjs +25 -1
  32. package/dist/main/footer.js +3 -3
  33. package/dist/main/footer.mjs +1 -1
  34. package/dist/main/money-price/money-price-button.js +2 -2
  35. package/dist/main/money-price/money-price-button.mjs +2 -2
  36. package/dist/main/money-price/money-price-interactive.d.ts +1 -1
  37. package/dist/main/money-price/money-price-interactive.js +14 -18
  38. package/dist/main/money-price/money-price-interactive.mjs +14 -18
  39. package/dist/main/money-price/money-price-types.d.ts +1 -0
  40. package/package.json +44 -4
  41. package/src/fuma/base/custom-header.tsx +1 -1
  42. package/src/fuma/base/custom-home-layout.tsx +0 -6
  43. package/src/fuma/base/docs-root-provider.tsx +58 -0
  44. package/src/fuma/base/index.ts +4 -0
  45. package/src/fuma/base/site-docs-layout.tsx +35 -0
  46. package/src/fuma/base/site-home-layout.tsx +78 -0
  47. package/src/fuma/base/site-layout-shared.tsx +190 -0
  48. package/src/fuma/base/site-layout.tsx +4 -295
  49. package/src/fuma/fuma-page-genarator.tsx +1 -1
  50. package/src/fuma/server/llm-copy-handler.ts +2 -0
  51. package/src/fuma/server/page-generator.ts +2 -0
  52. package/src/lib/seo-metadata.ts +1 -1
  53. package/src/lib/seo-util.ts +2 -2
  54. package/src/main/credit/credit-nav-button.tsx +36 -3
  55. package/src/main/footer.tsx +1 -2
  56. package/src/main/money-price/money-price-button.tsx +5 -3
  57. package/src/main/money-price/money-price-interactive.tsx +13 -15
  58. package/src/main/money-price/money-price-types.ts +1 -0
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { cn } from '@windrun-huaiin/lib/utils';
4
4
  import { GemIcon, XIcon } from '@windrun-huaiin/base-ui/icons';
5
+ import { themeMainBgColor } from '@windrun-huaiin/base-ui/lib';
5
6
  import {
6
7
  AlertDialog,
7
8
  AlertDialogContent,
@@ -21,7 +22,9 @@ import {
21
22
  useState,
22
23
  } from 'react';
23
24
  import { MoneyPriceInteractive } from '../money-price/money-price-interactive';
24
- import type { MoneyPriceData } from '../money-price/money-price-types';
25
+ import { getActiveProviderConfigUtil } from '../money-price/money-price-config-util';
26
+ import type { MoneyPriceData, SubscriptionProductConfig } from '../money-price/money-price-types';
27
+ import { dialogThemedOverlayClass } from '../alert-dialog/dialog-styles';
25
28
  import type { CreditPricingContext, PricingModalMode } from './types';
26
29
 
27
30
  interface CreditNavButtonProps {
@@ -172,6 +175,30 @@ export function CreditNavButton({
172
175
  );
173
176
 
174
177
  const isOnetimeModal = pricingModal.mode === 'onetime';
178
+ const modalInitialBillingType = useMemo(() => {
179
+ if (isOnetimeModal) {
180
+ return 'onetime';
181
+ }
182
+
183
+ const pricingContext = pricingModal.pricingContext;
184
+ const priceId = pricingContext?.initUserContext?.xSubscription?.priceId;
185
+ if (!pricingContext || !priceId) {
186
+ return undefined;
187
+ }
188
+
189
+ const providerConfig = getActiveProviderConfigUtil(pricingContext.moneyPriceConfig);
190
+ const products: Record<string, SubscriptionProductConfig> =
191
+ providerConfig.subscriptionProducts || providerConfig.products || {};
192
+ for (const product of Object.values(products)) {
193
+ for (const [billingType, plan] of Object.entries(product.plans)) {
194
+ if (plan.priceId === priceId) {
195
+ return billingType;
196
+ }
197
+ }
198
+ }
199
+
200
+ return undefined;
201
+ }, [isOnetimeModal, pricingModal.pricingContext]);
175
202
 
176
203
  return (
177
204
  <CreditNavPopoverContext.Provider value={contextValue}>
@@ -225,7 +252,13 @@ export function CreditNavButton({
225
252
  }))
226
253
  }
227
254
  >
228
- <AlertDialogContent className="mt-5 sm:mt-6 md:mt-10 lg:mt-15 w-[95vw] max-w-[1200px] overflow-hidden border border-slate-200 bg-white p-0 shadow-[0_32px_90px_rgba(15,23,42,0.25)] ring-1 ring-black/5 dark:border-white/12 dark:bg-[#0f1222] dark:shadow-[0_40px_120px_rgba(0,0,0,0.6)] dark:ring-white/10">
255
+ <AlertDialogContent
256
+ className={cn(
257
+ 'mt-5 sm:mt-6 md:mt-10 lg:mt-15 w-[95vw] max-w-[1200px] overflow-hidden border border-slate-200 p-0 shadow-[0_32px_90px_rgba(15,23,42,0.25)] ring-1 ring-black/5 dark:border-white/12 dark:shadow-[0_40px_120px_rgba(0,0,0,0.6)] dark:ring-white/10',
258
+ themeMainBgColor,
259
+ )}
260
+ overlayClassName={dialogThemedOverlayClass}
261
+ >
229
262
  <AlertDialogHeader className="flex flex-row items-center justify-between border-b border-slate-200 px-6 pt-4 pb-1 dark:border-slate-800">
230
263
  <AlertDialogTitle asChild>
231
264
  <div className="flex flex-wrap items-baseline gap-3 text-slate-900 dark:text-white">
@@ -256,7 +289,7 @@ export function CreditNavButton({
256
289
  checkoutApiEndpoint={pricingModal.pricingContext.checkoutApiEndpoint}
257
290
  customerPortalApiEndpoint={pricingModal.pricingContext.customerPortalApiEndpoint}
258
291
  enableSubscriptionUpgrade={pricingModal.pricingContext.enableSubscriptionUpgrade}
259
- initialBillingType={isOnetimeModal ? 'onetime' : undefined}
292
+ initialBillingType={modalInitialBillingType}
260
293
  disableAutoDetectBilling={isOnetimeModal}
261
294
  initUserContext={pricingModal.pricingContext.initUserContext}
262
295
  />
@@ -3,9 +3,8 @@ import { MailIcon, ReceiptTextIcon, ShieldUserIcon } from '@windrun-huaiin/base-
3
3
  import Link from "next/link";
4
4
  import { FooterEmail } from './footer-email';
5
5
  import { safeT } from '../lib/t-intl';
6
- import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib';
6
+ import { cn, getAsNeededLocalizedUrl } from '@windrun-huaiin/lib/utils';
7
7
  import { themeIconColor } from '@windrun-huaiin/base-ui/lib';
8
- import { cn } from '@windrun-huaiin/lib';
9
8
 
10
9
  interface FooterData {
11
10
  terms: string;
@@ -18,19 +18,21 @@ export function MoneyPriceButton({
18
18
  isInitLoading = false,
19
19
  enableSubscriptionUpgrade = true
20
20
  }: MoneyPriceButtonProps) {
21
+ const [isLoading, setIsLoading] = useState(false);
21
22
 
22
23
  if (isInitLoading) {
23
24
  return (
24
25
  <div
25
- className="w-full h-11 md:h-12 mt-4 md:mt-auto rounded-full bg-transparent"
26
+ className="relative w-full h-11 md:h-12 mt-4 md:mt-auto overflow-hidden rounded-full bg-gray-100/70 dark:bg-gray-800/40 animate-pulse transition-opacity duration-300 ease-out"
26
27
  aria-hidden="true"
27
28
  data-plan-button-placeholder={planKey}
28
- />
29
+ >
30
+ <div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/50 to-transparent dark:via-white/10" />
31
+ </div>
29
32
  );
30
33
  }
31
34
 
32
35
  const { isAuthenticated, subscriptionStatus } = userContext;
33
- const [isLoading, setIsLoading] = useState(false);
34
36
  const subscriptionBilling = userContext.subscriptionType;
35
37
  const planTier = planKey;
36
38
  const planBilling = billingType;
@@ -47,6 +47,7 @@ export function MoneyPriceInteractive({
47
47
  initialBillingType,
48
48
  disableAutoDetectBilling = false,
49
49
  initUserContext,
50
+ isInitLoading = false,
50
51
  }: MoneyPriceInteractiveProps) {
51
52
  const { redirectToSignIn, redirectToSignUp, user: clerkUser, openSignUp } = useClerk();
52
53
  const router = useRouter();
@@ -148,23 +149,20 @@ export function MoneyPriceInteractive({
148
149
  priceIdsByCycle,
149
150
  ]);
150
151
 
151
- const initialBillingCandidate = useMemo(() => {
152
- if (initialBillingType) {
153
- return resolvedInitialBilling;
154
- }
155
- if (detectedBillingType) {
156
- return detectedBillingType;
152
+ const explicitInitialBilling = useMemo<BillingType | null>(() => {
153
+ if (
154
+ initialBillingType &&
155
+ billingOptions.some(option => option.key === initialBillingType)
156
+ ) {
157
+ return initialBillingType;
157
158
  }
158
- return resolvedInitialBilling;
159
- }, [initialBillingType, resolvedInitialBilling, detectedBillingType]);
159
+ return null;
160
+ }, [initialBillingType, billingOptions]);
160
161
 
161
- const [billingType, setBillingType] = useState<BillingType>(initialBillingCandidate);
162
+ const [userSelectedBillingType, setUserSelectedBillingType] = useState<BillingType | null>(null);
163
+ const billingType = userSelectedBillingType ?? explicitInitialBilling ?? detectedBillingType ?? resolvedInitialBilling;
162
164
  const navigationLockRef = useRef(false);
163
165
 
164
- useEffect(() => {
165
- setBillingType(prev => (prev === initialBillingCandidate ? prev : initialBillingCandidate));
166
- }, [initialBillingCandidate]);
167
-
168
166
  const [processingTarget, setProcessingTarget] = useState<ProcessingTarget>(null);
169
167
  const [isTouchDevice, setIsTouchDevice] = useState(false);
170
168
 
@@ -422,7 +420,7 @@ export function MoneyPriceInteractive({
422
420
  )}
423
421
  type="button"
424
422
  data-billing-button={option.key}
425
- onClick={() => setBillingType(option.key as BillingType)}
423
+ onClick={() => setUserSelectedBillingType(option.key)}
426
424
  >
427
425
  {option.name}
428
426
  </button>
@@ -568,7 +566,7 @@ export function MoneyPriceInteractive({
568
566
  processingTarget?.billing === billingType
569
567
  }
570
568
  isAnyProcessing={!!processingTarget}
571
- isInitLoading={false}
569
+ isInitLoading={isInitLoading}
572
570
  enableSubscriptionUpgrade={enableSubscriptionUpgrade}
573
571
  />
574
572
  </div>
@@ -119,6 +119,7 @@ export interface MoneyPriceInteractiveProps {
119
119
  initialBillingType?: string;
120
120
  disableAutoDetectBilling?: boolean;
121
121
  initUserContext?: InitUserContext;
122
+ isInitLoading?: boolean;
122
123
  }
123
124
 
124
125
  // 按钮组件属性