sendou.ink/app/components/Label.tsx
Kalle fef1ffc955
Design refresh + a bunch of stuff (#2864)
Co-authored-by: hfcRed <hfcred@gmx.net>
2026-03-19 17:51:42 +02:00

50 lines
1.1 KiB
TypeScript

import clsx from "clsx";
import styles from "./Label.module.css";
type LabelProps = Pick<
React.DetailedHTMLProps<
React.LabelHTMLAttributes<HTMLLabelElement>,
HTMLLabelElement
>,
"children" | "htmlFor"
> & {
valueLimits?: {
current: number;
max: number;
};
required?: boolean;
className?: string;
labelClassName?: string;
spaced?: boolean;
};
export function Label({
valueLimits,
required,
children,
htmlFor,
className,
labelClassName,
spaced = true,
}: LabelProps) {
return (
<div className={clsx(styles.container, className, { "mb-0": !spaced })}>
<label htmlFor={htmlFor} className={labelClassName}>
{children} {required && <span className="text-error">*</span>}
</label>
{valueLimits ? (
<div className={clsx(styles.value, lengthWarning(valueLimits))}>
{valueLimits.current}/{valueLimits.max}
</div>
) : null}
</div>
);
}
function lengthWarning(valueLimits: NonNullable<LabelProps["valueLimits"]>) {
if (valueLimits.current > valueLimits.max) return styles.valueError;
if (valueLimits.current / valueLimits.max >= 0.9) return styles.valueWarning;
return;
}