@windrun-huaiin/third-ui 14.0.1 → 14.0.3

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.
@@ -16,6 +16,7 @@ export interface GradientButtonProps {
16
16
  // for Link
17
17
  href?: string;
18
18
  openInNewTab?: boolean;
19
+ preserveReferrer?: boolean;
19
20
 
20
21
  // for click
21
22
  onClick?: () => void | Promise<void>;
@@ -31,6 +32,7 @@ export function GradientButton({
31
32
  className = "",
32
33
  href,
33
34
  openInNewTab = true,
35
+ preserveReferrer = false,
34
36
  onClick,
35
37
  loadingText,
36
38
  preventDoubleClick = true,
@@ -157,7 +159,7 @@ export function GradientButton({
157
159
  <Link
158
160
  href={href || "#"}
159
161
  className={cn(buttonClassName, "no-underline hover:no-underline")}
160
- {...(openInNewTab ? { target: "_blank", rel: "noopener noreferrer" } : {})}
162
+ {...(openInNewTab ? { target: "_blank", rel: preserveReferrer ? 'noopener' : 'noopener noreferrer' } : {})}
161
163
  onClick={isDisabled ? (e) => e.preventDefault() : undefined}
162
164
  aria-disabled={isDisabled}
163
165
  >
@@ -0,0 +1,88 @@
1
+ "use client"
2
+
3
+ import Image, { type ImageProps } from "next/image"
4
+ import { useEffect, useState } from "react"
5
+ import { themeBgColor, themeViaColor } from "@windrun-huaiin/base-ui/lib"
6
+ import { cn } from "@windrun-huaiin/lib/utils"
7
+
8
+ interface DelayedImgProps extends ImageProps {
9
+ wrapperClassName?: string
10
+ placeholderClassName?: string
11
+ }
12
+
13
+ const ENV_DELAY_ENABLED =
14
+ process.env.NEXT_PUBLIC_DELAYED_IMG_ENABLED === "true" ||
15
+ process.env.NEXT_PUBLIC_DELAY_REVEAL_ENABLED === "true"
16
+
17
+ const rawDelaySeconds =
18
+ process.env.NEXT_PUBLIC_DELAYED_IMG_SECONDS ??
19
+ process.env.NEXT_PUBLIC_DELAY_REVEAL_SECONDS ??
20
+ "0"
21
+
22
+ const parsedDelaySeconds = Number(rawDelaySeconds)
23
+ const ENV_DELAY_MS = Number.isFinite(parsedDelaySeconds) && parsedDelaySeconds > 0
24
+ ? parsedDelaySeconds * 1000
25
+ : 0
26
+
27
+ export function DelayedImg({
28
+ alt,
29
+ wrapperClassName,
30
+ placeholderClassName,
31
+ className,
32
+ onLoad,
33
+ ...imageProps
34
+ }: DelayedImgProps) {
35
+ const shouldDelay = ENV_DELAY_ENABLED && ENV_DELAY_MS > 0
36
+ const [isMounted, setIsMounted] = useState(!shouldDelay)
37
+ const [isLoaded, setIsLoaded] = useState(false)
38
+
39
+ useEffect(() => {
40
+ if (!shouldDelay || isMounted) {
41
+ return
42
+ }
43
+
44
+ const timer = window.setTimeout(() => {
45
+ setIsMounted(true)
46
+ }, ENV_DELAY_MS)
47
+
48
+ return () => window.clearTimeout(timer)
49
+ }, [isMounted, shouldDelay])
50
+
51
+ return (
52
+ <div className={cn("relative", wrapperClassName)}>
53
+ {(!isMounted || !isLoaded) && (
54
+ <div
55
+ aria-hidden="true"
56
+ className={cn(
57
+ "absolute inset-0 rounded-[inherit] border animate-pulse shadow-sm bg-white/70 dark:bg-white/5",
58
+ themeBgColor,
59
+ placeholderClassName,
60
+ )}
61
+ >
62
+ <div
63
+ className={cn(
64
+ "absolute inset-x-0 top-0 h-28 rounded-[inherit] bg-linear-to-b from-white/80 to-transparent dark:from-white/14 dark:to-transparent",
65
+ themeViaColor,
66
+ )}
67
+ />
68
+ <div className="absolute inset-0 rounded-[inherit] bg-white/20 dark:bg-white/0" />
69
+ </div>
70
+ )}
71
+ {isMounted && (
72
+ <Image
73
+ {...imageProps}
74
+ alt={alt}
75
+ onLoad={(event) => {
76
+ setIsLoaded(true)
77
+ onLoad?.(event)
78
+ }}
79
+ className={cn(
80
+ "transition duration-300",
81
+ isLoaded ? "opacity-100" : "opacity-0",
82
+ className,
83
+ )}
84
+ />
85
+ )}
86
+ </div>
87
+ )
88
+ }
package/src/main/index.ts CHANGED
@@ -11,6 +11,7 @@ export * from './rich-text-expert'
11
11
  export * from './faq-interactive'
12
12
  export * from './price-plan-interactive'
13
13
  export * from './gallery/gallery-interactive'
14
+ export * from './delayed-img'
14
15
  // Money Price Client Components
15
16
  export { MoneyPriceInteractive } from './money-price/money-price-interactive';
16
17
  export { MoneyPriceButton } from './money-price/money-price-button';