@windrun-huaiin/third-ui 14.0.0 → 14.0.2

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.
@@ -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
+ }
@@ -61,7 +61,7 @@ export async function Features({
61
61
  <div
62
62
  key={feature.id}
63
63
  data-feature-id={feature.id}
64
- className="bg-white dark:bg-gray-800/60 p-8 rounded-xl border border-gray-200 dark:border-gray-700 hover:border-purple-300 dark:hover:border-purple-500/50 transition shadow-sm dark:shadow-none"
64
+ className={cn("bg-white dark:bg-gray-800/60 p-8 rounded-xl border border-gray-200 dark:border-gray-700 hover:border-current transition shadow-sm dark:shadow-none", themeIconColor)}
65
65
  >
66
66
  <div className="text-4xl mb-4 flex items-center justify-start">
67
67
  <Icon className="w-8 h-8" />
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';
@@ -4,6 +4,13 @@ import { themeRichTextMarkClass } from '@windrun-huaiin/base-ui/lib';
4
4
 
5
5
  // default tag renderers
6
6
  const defaultTagRenderers = {
7
+ // text next line
8
+ br: (chunks: React.ReactNode) => (
9
+ <React.Fragment>
10
+ <br />
11
+ {chunks}
12
+ </React.Fragment>
13
+ ),
7
14
  // text Stong
8
15
  strong: (chunks: React.ReactNode) => <strong>{chunks}</strong>,
9
16
  // text Emphasis