sync current state
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import type React from 'react';
|
||||
import { cn } from '~/shared/lib/utils';
|
||||
|
||||
const variants = {
|
||||
info: 'bg-cyan-50 text-cyan-800 border border-cyan-200',
|
||||
warning: 'bg-amber-50 text-amber-800 border border-amber-200',
|
||||
error: 'bg-red-50 text-red-800 border border-red-200',
|
||||
success: 'bg-green-50 text-green-800 border border-green-200',
|
||||
} as const;
|
||||
|
||||
interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
variant?: keyof typeof variants;
|
||||
}
|
||||
|
||||
export function Alert({ variant = 'info', className, children, ...props }: AlertProps) {
|
||||
return (
|
||||
<div className={cn('p-3 rounded text-sm', variants[variant], className)} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { cn } from '~/shared/lib/utils';
|
||||
|
||||
const variants = {
|
||||
default: 'bg-gray-100 text-gray-600',
|
||||
keep: 'bg-green-100 text-green-800',
|
||||
remove: 'bg-red-100 text-red-800',
|
||||
pending: 'bg-gray-200 text-gray-600',
|
||||
approved: 'bg-green-100 text-green-800',
|
||||
skipped: 'bg-gray-200 text-gray-600',
|
||||
done: 'bg-cyan-100 text-cyan-800',
|
||||
error: 'bg-red-100 text-red-800',
|
||||
noop: 'bg-gray-200 text-gray-600',
|
||||
running: 'bg-amber-100 text-amber-800',
|
||||
manual: 'bg-orange-100 text-orange-800',
|
||||
} as const;
|
||||
|
||||
interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
||||
variant?: keyof typeof variants;
|
||||
}
|
||||
|
||||
export function Badge({ variant = 'default', className, children, ...props }: BadgeProps) {
|
||||
return (
|
||||
<span
|
||||
className={cn(
|
||||
'inline-block text-[0.67rem] font-semibold px-[0.45em] py-[0.1em] rounded-full uppercase tracking-[0.03em] whitespace-nowrap',
|
||||
variants[variant],
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
import type React from 'react';
|
||||
@@ -0,0 +1,26 @@
|
||||
import type React from 'react';
|
||||
import { cn } from '~/shared/lib/utils';
|
||||
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: 'primary' | 'secondary' | 'danger';
|
||||
size?: 'default' | 'sm' | 'xs';
|
||||
}
|
||||
|
||||
export function Button({ variant = 'primary', size = 'default', className, ...props }: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
className={cn(
|
||||
'inline-flex items-center justify-center gap-1 rounded font-medium cursor-pointer transition-colors border-0',
|
||||
variant === 'primary' && 'bg-blue-600 text-white hover:bg-blue-700',
|
||||
variant === 'secondary' && 'bg-white text-gray-700 border border-gray-300 hover:bg-gray-50',
|
||||
variant === 'danger' && 'bg-white text-red-600 border border-red-400 hover:bg-red-50',
|
||||
size === 'default' && 'px-3 py-1.5 text-sm',
|
||||
size === 'sm' && 'px-2.5 py-1 text-xs',
|
||||
size === 'xs' && 'px-2 py-0.5 text-xs',
|
||||
props.disabled && 'opacity-50 cursor-not-allowed',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import type React from 'react';
|
||||
import { cn } from '~/shared/lib/utils';
|
||||
|
||||
export function Input({ className, ...props }: React.InputHTMLAttributes<HTMLInputElement>) {
|
||||
return (
|
||||
<input
|
||||
className={cn(
|
||||
'border border-gray-300 rounded px-2.5 py-1.5 text-sm bg-white w-full',
|
||||
'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent',
|
||||
'disabled:bg-gray-100 disabled:text-gray-400 disabled:cursor-not-allowed',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import type React from 'react';
|
||||
import { cn } from '~/shared/lib/utils';
|
||||
|
||||
export function Select({ className, ...props }: React.SelectHTMLAttributes<HTMLSelectElement>) {
|
||||
return (
|
||||
<select
|
||||
className={cn(
|
||||
'border border-gray-300 rounded px-2 py-1.5 text-sm bg-white',
|
||||
'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent',
|
||||
'disabled:bg-gray-100 disabled:cursor-not-allowed',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import type React from 'react';
|
||||
import { cn } from '~/shared/lib/utils';
|
||||
|
||||
export function Textarea({ className, ...props }: React.TextareaHTMLAttributes<HTMLTextAreaElement>) {
|
||||
return (
|
||||
<textarea
|
||||
className={cn(
|
||||
'border border-gray-300 rounded px-2.5 py-1.5 text-sm bg-white w-full resize-vertical',
|
||||
'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user