mirror of
https://github.com/zc-zhangchen/any-auto-register.git
synced 2026-05-15 10:56:45 +08:00
Remove unused UI components
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
export { Button, buttonVariants } from './button'
|
||||
export { Card, CardHeader, CardTitle, CardContent, CardFooter } from './card'
|
||||
export { Badge, badgeVariants } from './badge'
|
||||
export { Input } from './input'
|
||||
export { Select } from './select'
|
||||
export { Label } from './label'
|
||||
export { Switch } from './switch'
|
||||
export { Textarea } from './textarea'
|
||||
export { ToastContainer, toast, dismissToast } from './toast'
|
||||
@@ -1,33 +0,0 @@
|
||||
import * as React from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
error?: boolean
|
||||
}
|
||||
|
||||
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
({ className, type, error, ...props }, ref) => {
|
||||
return (
|
||||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
'flex h-9 w-full rounded-md px-3 py-2 text-sm',
|
||||
'bg-[var(--bg-input)] border',
|
||||
'text-[var(--text-primary)] placeholder:text-[var(--text-muted)]',
|
||||
'transition-all duration-200',
|
||||
'focus:outline-none focus:ring-2 focus:ring-[var(--accent)]/50 focus:border-[var(--accent)]',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
error
|
||||
? 'border-red-500/50 focus:ring-red-500/50'
|
||||
: 'border-[var(--border)]',
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
Input.displayName = 'Input'
|
||||
|
||||
export { Input }
|
||||
@@ -1,28 +0,0 @@
|
||||
import * as React from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
|
||||
required?: boolean
|
||||
}
|
||||
|
||||
const Label = React.forwardRef<HTMLLabelElement, LabelProps>(
|
||||
({ className, required, children, ...props }, ref) => {
|
||||
return (
|
||||
<label
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'text-xs font-medium text-[var(--text-secondary)]',
|
||||
'transition-colors duration-200',
|
||||
required && "after:content-['*'] after:text-red-400 after:ml-0.5",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</label>
|
||||
)
|
||||
}
|
||||
)
|
||||
Label.displayName = 'Label'
|
||||
|
||||
export { Label }
|
||||
@@ -1,28 +0,0 @@
|
||||
import * as React from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {}
|
||||
|
||||
const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
|
||||
({ className, ...props }, ref) => {
|
||||
return (
|
||||
<select
|
||||
className={cn(
|
||||
'flex h-9 w-full rounded-md px-3 py-2 text-sm',
|
||||
'bg-[var(--bg-input)] border border-[var(--border)]',
|
||||
'text-[var(--text-primary)]',
|
||||
'transition-all duration-200',
|
||||
'focus:outline-none focus:ring-2 focus:ring-[var(--accent)]/50 focus:border-[var(--accent)]',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'appearance-none bg-[length:16px_16px] bg-[right_12px_center] bg-no-repeat',
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
Select.displayName = 'Select'
|
||||
|
||||
export { Select }
|
||||
@@ -1,41 +0,0 @@
|
||||
import * as React from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
interface SwitchProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
checked: boolean
|
||||
onCheckedChange: (checked: boolean) => void
|
||||
}
|
||||
|
||||
const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>(
|
||||
({ className, checked, onCheckedChange, disabled, ...props }, ref) => {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={checked}
|
||||
ref={ref}
|
||||
disabled={disabled}
|
||||
onClick={() => onCheckedChange(!checked)}
|
||||
className={cn(
|
||||
'relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent',
|
||||
'transition-colors duration-200 ease-out',
|
||||
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--accent)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-base)]',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
checked ? 'bg-[var(--accent)]' : 'bg-[var(--border)]',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
'pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-lg transform transition-transform duration-200 ease-out',
|
||||
checked ? 'translate-x-4' : 'translate-x-0'
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
)
|
||||
Switch.displayName = 'Switch'
|
||||
|
||||
export { Switch }
|
||||
@@ -1,28 +0,0 @@
|
||||
import * as React from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
|
||||
|
||||
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
({ className, ...props }, ref) => {
|
||||
return (
|
||||
<textarea
|
||||
className={cn(
|
||||
'flex min-h-[80px] w-full rounded-md px-3 py-2 text-sm',
|
||||
'bg-[var(--bg-input)] border border-[var(--border)]',
|
||||
'text-[var(--text-primary)] placeholder:text-[var(--text-muted)]',
|
||||
'transition-all duration-200',
|
||||
'focus:outline-none focus:ring-2 focus:ring-[var(--accent)]/50 focus:border-[var(--accent)]',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'resize-none',
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
Textarea.displayName = 'Textarea'
|
||||
|
||||
export { Textarea }
|
||||
@@ -1,88 +0,0 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { CheckCircle, XCircle, AlertCircle, X } from 'lucide-react'
|
||||
|
||||
type ToastType = 'success' | 'error' | 'warning' | 'info'
|
||||
|
||||
interface Toast {
|
||||
id: string
|
||||
type: ToastType
|
||||
title: string
|
||||
message?: string
|
||||
}
|
||||
|
||||
const icons: Record<ToastType, React.ReactNode> = {
|
||||
success: <CheckCircle className="h-5 w-5 text-emerald-400" />,
|
||||
error: <XCircle className="h-5 w-5 text-red-400" />,
|
||||
warning: <AlertCircle className="h-5 w-5 text-amber-400" />,
|
||||
info: <AlertCircle className="h-5 w-5 text-blue-400" />,
|
||||
}
|
||||
|
||||
const bgColors: Record<ToastType, string> = {
|
||||
success: 'border-emerald-500/30 bg-emerald-500/10',
|
||||
error: 'border-red-500/30 bg-red-500/10',
|
||||
warning: 'border-amber-500/30 bg-amber-500/10',
|
||||
info: 'border-blue-500/30 bg-blue-500/10',
|
||||
}
|
||||
|
||||
let toastId = 0
|
||||
const listeners: Set<(toasts: Toast[]) => void> = new Set()
|
||||
let toasts: Toast[] = []
|
||||
|
||||
function notify(listeners: Set<any>, toasts: Toast[]) {
|
||||
listeners.forEach(l => l([...toasts]))
|
||||
}
|
||||
|
||||
export function toast(type: ToastType, title: string, message?: string) {
|
||||
const id = String(++toastId)
|
||||
toasts = [...toasts, { id, type, title, message }]
|
||||
notify(listeners, toasts)
|
||||
setTimeout(() => {
|
||||
toasts = toasts.filter(t => t.id !== id)
|
||||
notify(listeners, toasts)
|
||||
}, 4000)
|
||||
}
|
||||
|
||||
export function dismissToast(id: string) {
|
||||
toasts = toasts.filter(t => t.id !== id)
|
||||
notify(listeners, toasts)
|
||||
}
|
||||
|
||||
export function ToastContainer() {
|
||||
const [items, setItems] = useState<Toast[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
listeners.add(setItems)
|
||||
return () => { listeners.delete(setItems) }
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-4 right-4 z-50 flex flex-col gap-2">
|
||||
{items.map((t) => (
|
||||
<div
|
||||
key={t.id}
|
||||
className={cn(
|
||||
'flex items-start gap-3 p-4 rounded-lg border backdrop-blur-sm',
|
||||
'bg-[var(--bg-card)] shadow-lg',
|
||||
'animate-in slide-in-from-right fade-in duration-300',
|
||||
bgColors[t.type]
|
||||
)}
|
||||
>
|
||||
{icons[t.type]}
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-medium text-[var(--text-primary)]">{t.title}</p>
|
||||
{t.message && (
|
||||
<p className="text-xs text-[var(--text-muted)] mt-1">{t.message}</p>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => dismissToast(t.id)}
|
||||
className="text-[var(--text-muted)] hover:text-[var(--text-primary)] transition-colors"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user