templates2.Admin.Next/components/ui/index.tsx
w4c-templates c64f7ffa9e
Some checks failed
CI / quality (push) Has been cancelled
chore(template): publish Admin.Next
2026-10-11 23:25:34 +03:00

69 lines
2.1 KiB
TypeScript

import type { ReactNode } from 'react';
export function Card({ title, children, actions }: { title?: ReactNode; children: ReactNode; actions?: ReactNode }) {
return (
<section className="card">
{(title || actions) && (
<header className="mb-4 flex items-center justify-between gap-4">
{title ? <h2 className="text-lg font-semibold">{title}</h2> : <span />}
{actions}
</header>
)}
{children}
</section>
);
}
const badgeTones: Record<string, string> = {
neutral: 'bg-slate-200 text-slate-800 dark:bg-slate-700 dark:text-slate-100',
success: 'bg-emerald-600 text-white',
warning: 'bg-amber-300 text-black',
danger: 'bg-red-600 text-white',
brand: 'bg-brand-600 text-white',
};
export function Badge({ children, tone = 'neutral' }: { children: ReactNode; tone?: keyof typeof badgeTones }) {
return <span className={`badge ${badgeTones[tone] ?? badgeTones.neutral}`}>{children}</span>;
}
const alertTones: Record<string, string> = {
info: 'border-brand-400 bg-brand-50 text-brand-700 dark:bg-brand-700/20 dark:text-brand-100',
success: 'border-emerald-500 bg-emerald-50 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-100',
warning: 'border-amber-400 bg-amber-50 text-black',
error: 'border-red-500 bg-red-50 text-red-800 dark:bg-red-900/30 dark:text-red-100',
};
export function Alert({ children, tone = 'info' }: { children: ReactNode; tone?: keyof typeof alertTones }) {
return (
<div role="status" className={`rounded-lg border px-4 py-3 text-sm ${alertTones[tone] ?? alertTones.info}`}>
{children}
</div>
);
}
export function Field({
label,
htmlFor,
hint,
children,
}: {
label: string;
htmlFor: string;
hint?: string;
children: ReactNode;
}) {
return (
<div>
<label className="label" htmlFor={htmlFor}>
{label}
</label>
{children}
{hint && <p className="muted mt-1 text-xs">{hint}</p>}
</div>
);
}
export function EmptyState({ children }: { children?: ReactNode }) {
return <p className="muted py-6 text-center text-sm">{children ?? 'Nothing here yet.'}</p>;
}