feat: 更新 ESLint 和 Prettier 配置,增强代码质量管理
- 在 .gitignore 中添加 public/audio/* 以忽略音频文件。 - 更新 bun.lock,添加 eslint-config-prettier 和 eslint-plugin-prettier 依赖,确保 ESLint 与 Prettier 的兼容性。 - 修改 eslint.config.ts,整合 Prettier 规则,优化代码风格一致性。 - 在 package.json 中添加 lint:fix 和 format 脚本,简化代码格式化和修复流程。 - 更新 tailwind.config.ts 和其他组件文件,统一代码风格,提升可读性。
This commit is contained in:
1 parent
5d00adc1a5
commit
76c67b492e
216 files changed
+12454
-13976
No files matched your search
@@ -1,16 +1,16 @@
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ImageProps } from "./image.types";
|
||||
import { useState, useRef, useEffect } from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
import type { ImageProps } from './image.types'
|
||||
|
||||
export function Image({
|
||||
src,
|
||||
alt = "",
|
||||
alt = '',
|
||||
className,
|
||||
width,
|
||||
height,
|
||||
objectFit = "cover",
|
||||
objectPosition = "center",
|
||||
loading = "lazy",
|
||||
objectFit = 'cover',
|
||||
objectPosition = 'center',
|
||||
loading = 'lazy',
|
||||
placeholder,
|
||||
fallback,
|
||||
onLoad,
|
||||
@@ -21,81 +21,77 @@ export function Image({
|
||||
style,
|
||||
...restProps
|
||||
}: ImageProps) {
|
||||
const [imageSrc, setImageSrc] = useState(src);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [hasError, setHasError] = useState(false);
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
const imgRef = useRef<HTMLImageElement>(null);
|
||||
const [imageSrc, setImageSrc] = useState(src)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [hasError, setHasError] = useState(false)
|
||||
const [isLoaded, setIsLoaded] = useState(false)
|
||||
const imgRef = useRef<HTMLImageElement>(null)
|
||||
|
||||
// 处理图片加载
|
||||
const handleLoad = () => {
|
||||
setIsLoading(false);
|
||||
setIsLoaded(true);
|
||||
setHasError(false);
|
||||
onLoad?.();
|
||||
};
|
||||
setIsLoading(false)
|
||||
setIsLoaded(true)
|
||||
setHasError(false)
|
||||
onLoad?.()
|
||||
}
|
||||
|
||||
// 处理图片错误
|
||||
const handleError = () => {
|
||||
setIsLoading(false);
|
||||
setHasError(true);
|
||||
setIsLoading(false)
|
||||
setHasError(true)
|
||||
if (fallback && imageSrc !== fallback) {
|
||||
setImageSrc(fallback);
|
||||
setImageSrc(fallback)
|
||||
}
|
||||
onError?.();
|
||||
};
|
||||
onError?.()
|
||||
}
|
||||
|
||||
// 重置状态当src改变时
|
||||
useEffect(() => {
|
||||
if (src !== imageSrc) {
|
||||
setImageSrc(src);
|
||||
setIsLoading(true);
|
||||
setHasError(false);
|
||||
setIsLoaded(false);
|
||||
setImageSrc(src)
|
||||
setIsLoading(true)
|
||||
setHasError(false)
|
||||
setIsLoaded(false)
|
||||
}
|
||||
}, [src, imageSrc]);
|
||||
}, [src, imageSrc])
|
||||
|
||||
// 懒加载处理
|
||||
useEffect(() => {
|
||||
if (
|
||||
loading === "lazy" &&
|
||||
typeof IntersectionObserver !== "undefined" &&
|
||||
imgRef.current
|
||||
) {
|
||||
if (loading === 'lazy' && typeof IntersectionObserver !== 'undefined' && imgRef.current) {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
setImageSrc(src);
|
||||
observer.disconnect();
|
||||
setImageSrc(src)
|
||||
observer.disconnect()
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
{ threshold: 0.1 }
|
||||
);
|
||||
)
|
||||
|
||||
observer.observe(imgRef.current);
|
||||
return () => observer.disconnect();
|
||||
observer.observe(imgRef.current)
|
||||
return () => observer.disconnect()
|
||||
}
|
||||
}, [loading, src]);
|
||||
}, [loading, src])
|
||||
|
||||
const imageStyle: React.CSSProperties = {
|
||||
width,
|
||||
height,
|
||||
objectFit,
|
||||
objectPosition,
|
||||
filter: blur ? "blur(4px)" : "none",
|
||||
transition: "filter 0.3s ease",
|
||||
filter: blur ? 'blur(4px)' : 'none',
|
||||
transition: 'filter 0.3s ease',
|
||||
...style,
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"relative",
|
||||
width === "100%" ? "block" : "inline-block",
|
||||
'relative',
|
||||
width === '100%' ? 'block' : 'inline-block',
|
||||
button &&
|
||||
"cursor-pointer transition-all duration-300 hover:scale-105 hover:brightness-110 hover:contrast-110 active:scale-95",
|
||||
'cursor-pointer transition-all duration-300 hover:scale-105 hover:brightness-110 hover:contrast-110 active:scale-95',
|
||||
className
|
||||
)}
|
||||
style={{ width, height }}
|
||||
@@ -107,8 +103,8 @@ export function Image({
|
||||
className="w-full h-full bg-gray-200 flex items-center justify-center"
|
||||
style={{
|
||||
backgroundImage: `url(${placeholder})`,
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}}
|
||||
>
|
||||
<div className="animate-pulse bg-gray-300 rounded w-full h-full" />
|
||||
@@ -155,11 +151,11 @@ export function Image({
|
||||
onLoad={handleLoad}
|
||||
onError={handleError}
|
||||
className={cn(
|
||||
"transition-opacity duration-300",
|
||||
isLoaded ? "opacity-100" : "opacity-0",
|
||||
"w-full h-full"
|
||||
'transition-opacity duration-300',
|
||||
isLoaded ? 'opacity-100' : 'opacity-0',
|
||||
'w-full h-full'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
@@ -1,36 +1,36 @@
|
||||
import type { HTMLAttributes } from "react";
|
||||
import type { HTMLAttributes } from 'react'
|
||||
|
||||
export interface ImageProps extends HTMLAttributes<HTMLDivElement> {
|
||||
/** 图片地址 */
|
||||
src: string;
|
||||
src: string
|
||||
/** 图片替代文本 */
|
||||
alt?: string;
|
||||
alt?: string
|
||||
/** 自定义类名 */
|
||||
className?: string;
|
||||
className?: string
|
||||
/** 图片宽度 */
|
||||
width?: number | string;
|
||||
width?: number | string
|
||||
/** 图片高度 */
|
||||
height?: number | string;
|
||||
height?: number | string
|
||||
/** 图片填充方式 */
|
||||
objectFit?: "cover" | "contain" | "fill" | "none" | "scale-down";
|
||||
objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'
|
||||
/** 图片位置 */
|
||||
objectPosition?: string;
|
||||
objectPosition?: string
|
||||
/** 加载方式 */
|
||||
loading?: "lazy" | "eager";
|
||||
loading?: 'lazy' | 'eager'
|
||||
/** 占位图 */
|
||||
placeholder?: string;
|
||||
placeholder?: string
|
||||
/** 加载失败时的回退图片 */
|
||||
fallback?: string;
|
||||
fallback?: string
|
||||
/** 图片加载完成回调 */
|
||||
onLoad?: () => void;
|
||||
onLoad?: () => void
|
||||
/** 图片加载失败回调 */
|
||||
onError?: () => void;
|
||||
onError?: () => void
|
||||
/** 是否可拖拽 */
|
||||
draggable?: boolean;
|
||||
draggable?: boolean
|
||||
/** 模糊效果 */
|
||||
blur?: boolean;
|
||||
blur?: boolean
|
||||
/** 图片质量(仅用于提示) */
|
||||
quality?: number;
|
||||
quality?: number
|
||||
/** 是否启用按钮样式(hover 和 active 效果) */
|
||||
button?: boolean;
|
||||
button?: boolean
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from "./image";
|
||||
export * from "./image.types";
|
||||
export * from './image'
|
||||
export * from './image.types'
|
||||
Reference in new issue
Block a user