refactor: 统一使用 Button 组件替换原有 button 元素
- 在 CopyButton、SwitchButtonGroup 和 TextInputArea 组件中,将原有的 button 元素替换为统一的 Button 组件,提升代码一致性和可维护性。 - 更新相关样式和属性以适应新组件,确保功能正常。
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { Check, Copy } from 'lucide-react';
|
import { Check, Copy } from 'lucide-react';
|
||||||
import { copyTextToClipboard } from '@/utils/clipboard';
|
import { copyTextToClipboard } from '@/utils/clipboard';
|
||||||
import { cn } from '@/lib/utils';
|
import { Button, type ButtonProps } from '@/components/ui/button';
|
||||||
import { buttonVariants, type ButtonProps } from '@/components/ui/button';
|
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
|
|
||||||
interface CopyButtonProps extends Omit<ButtonProps, 'children' | 'onClick'> {
|
interface CopyButtonProps extends Omit<ButtonProps, 'children' | 'onClick'> {
|
||||||
@@ -47,17 +46,14 @@ export const CopyButton: React.FC<CopyButtonProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleCopy}
|
onClick={handleCopy}
|
||||||
title={tooltip ?? '复制'}
|
title={tooltip ?? '复制'}
|
||||||
aria-label={tooltip ?? '复制'}
|
aria-label={tooltip ?? '复制'}
|
||||||
className={cn(
|
variant={variant}
|
||||||
buttonVariants({ variant, size }),
|
size={size}
|
||||||
copied &&
|
className={className}
|
||||||
'bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 hover:bg-emerald-500/10',
|
|
||||||
className,
|
|
||||||
)}
|
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{copied ? (
|
{copied ? (
|
||||||
@@ -65,7 +61,7 @@ export const CopyButton: React.FC<CopyButtonProps> = ({
|
|||||||
) : (
|
) : (
|
||||||
<Copy className="h-[1.2em] w-[1.2em]" />
|
<Copy className="h-[1.2em] w-[1.2em]" />
|
||||||
)}
|
)}
|
||||||
</button>
|
</Button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
export interface SwitchOption<T extends string | number = string> {
|
export interface SwitchOption<T extends string | number = string> {
|
||||||
@@ -45,21 +46,20 @@ export default function SwitchButtonGroup<T extends string | number = string>({
|
|||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{options.map((option) => (
|
{options.map((option) => (
|
||||||
<button
|
<Button
|
||||||
key={option.value}
|
key={option.value}
|
||||||
type="button"
|
type="button"
|
||||||
|
variant="ghost"
|
||||||
onClick={() => onChange(option.value)}
|
onClick={() => onChange(option.value)}
|
||||||
className={cn(
|
className={cn(
|
||||||
'flex-1 inline-flex items-center justify-center font-medium whitespace-nowrap transition-all',
|
'flex-1 transition-all',
|
||||||
'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
||||||
'disabled:pointer-events-none disabled:opacity-50',
|
|
||||||
SIZE_CLASSES[size],
|
SIZE_CLASSES[size],
|
||||||
value === option.value ? SELECTED_CLASSES : UNSELECTED_CLASSES,
|
value === option.value ? SELECTED_CLASSES : UNSELECTED_CLASSES,
|
||||||
buttonClassName,
|
buttonClassName,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{option.label}
|
{option.label}
|
||||||
</button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { X } from 'lucide-react';
|
|||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { toast } from 'sonner'; // 推荐使用 shadcn 的默认 Toast
|
import { toast } from 'sonner'; // 推荐使用 shadcn 的默认 Toast
|
||||||
import { CopyButton } from '@/components/CopyButton';
|
import { CopyButton } from '@/components/CopyButton';
|
||||||
|
import { Button } from './ui/button';
|
||||||
|
|
||||||
export type ValidateRule = {
|
export type ValidateRule = {
|
||||||
validator: (value: string) => boolean;
|
validator: (value: string) => boolean;
|
||||||
@@ -273,14 +274,16 @@ const TextInputArea = forwardRef<HTMLTextAreaElement, TextInputAreaProps>((props
|
|||||||
<CopyButton text={value} tooltip={'复制内容'} size="sm" className="h-7 w-7 p-1" />
|
<CopyButton text={value} tooltip={'复制内容'} size="sm" className="h-7 w-7 p-1" />
|
||||||
)}
|
)}
|
||||||
{showClear && value && !disabled && !readOnly && (
|
{showClear && value && !disabled && !readOnly && (
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleClear}
|
onClick={handleClear}
|
||||||
aria-label={'清空'}
|
aria-label={'清空'}
|
||||||
className="p-1 h-7 w-7 flex items-center justify-center rounded-md text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
className="h-7 w-7 text-muted-foreground hover:text-destructive hover:bg-destructive/10"
|
||||||
>
|
>
|
||||||
<X className="h-4 w-4" />
|
<X className="h-4 w-4" />
|
||||||
</button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user