base create and list

This commit is contained in:
hamid zarghami
2025-08-31 12:26:26 +03:30
parent 54c3c59a12
commit 6191fb15a4
18 changed files with 1380 additions and 11 deletions
+26 -8
View File
@@ -6,24 +6,42 @@ import { clx } from '../helpers/utils'
type Props = {
className?: string;
isLoading?: boolean,
variant?: 'primary' | 'outline' | 'ghost' | 'danger';
size?: 'sm' | 'md' | 'lg';
} & ButtonHTMLAttributes<HTMLButtonElement> &
XOR<{ children: ReactNode }, { label: string }>;
const Button: FC<Props> = memo((props: Props) => {
const Button: FC<Props> = memo((props) => {
const { variant = 'primary', size = 'md', className, ...restProps } = props;
const buttonClass = clx(
'flex rounded-xl items-center justify-center text-center h-10 text-sm bg-primary text-white w-full',
props.disabled && 'cursor-not-allowed opacity-60',
props.className
'flex rounded-xl items-center justify-center text-center font-medium transition-colors',
// Variant styles
variant === 'primary' && 'bg-primary text-white hover:bg-primary/90',
variant === 'outline' && 'bg-transparent border border-gray-300 text-gray-700 hover:bg-gray-50 hover:border-gray-400',
variant === 'ghost' && 'bg-transparent text-gray-700 hover:bg-gray-100',
variant === 'danger' && 'bg-red-500 text-white hover:bg-red-600',
// Size styles
size === 'sm' && 'h-8 px-3 text-xs',
size === 'md' && 'h-10 px-4 text-sm',
size === 'lg' && 'h-12 px-6 text-base',
// Disabled state
restProps.disabled && 'cursor-not-allowed opacity-60',
// Default width
'w-full'
);
return (
<button disabled={props.isLoading} {...props} className={`${buttonClass} ${props.className}`} >
<button
disabled={restProps.isLoading}
{...restProps}
className={clx(buttonClass, className)}
>
{
props.isLoading ?
<MoonLoader color="white" size={16} />
restProps.isLoading ?
<MoonLoader color={variant === 'primary' || variant === 'danger' ? "white" : "#6B7280"} size={16} />
:
props.label || props.children
restProps.label || restProps.children
}
</button>
)
+50
View File
@@ -0,0 +1,50 @@
import { Fragment } from 'react'
import { Switch } from '@headlessui/react'
import ReactLoading from 'react-spinners/MoonLoader'
interface Props {
active: boolean,
onChange: (value: boolean) => void,
isLoading?: boolean,
label?: string,
}
const SwitchComponent = (props: Props) => {
const handleChange = (value: boolean) => {
props.onChange(value)
}
if (props.isLoading) {
return (
<ReactLoading color='black' size={20} className='ml-4' />
)
}
return (
<div className='dltr w-fit flex gap-2 items-center'>
<Switch checked={props.active} onChange={handleChange} as={Fragment}>
{({ checked }) => (
<button
className={`${checked ? 'bg-primary' : 'bg-gray-200'
} relative inline-flex h-6 w-11 items-center rounded-full`}
>
<span className="sr-only">Enable notifications</span>
<span
className={`${checked ? 'translate-x-6' : 'translate-x-1'
} inline-block h-4 w-4 transform rounded-full bg-white transition`}
/>
</button>
)}
</Switch>
{
props.label &&
<div className='text-sm'>
: {props.label}
</div>
}
</div>
)
}
export default SwitchComponent