Map exact size/weight/line-height combos onto existing text-* utilities across cards, sections, navigation, modals, controls, and create-flow. Leave unmappable combos hardcoded for design review. Co-authored-by: Cursor <cursoragent@cursor.com>
75 lines
4.6 KiB
TypeScript
75 lines
4.6 KiB
TypeScript
import type { InputWithCounterProps } from "./InputWithCounter.types";
|
|
|
|
export function InputWithCounterView({
|
|
label,
|
|
placeholder,
|
|
value,
|
|
onChange,
|
|
maxLength,
|
|
showHelpIcon = false,
|
|
className = "",
|
|
inputClassName = "",
|
|
}: InputWithCounterProps) {
|
|
return (
|
|
<div className={`space-y-[var(--spacing-scale-008)] ${className}`}>
|
|
{/* Label with help icon */}
|
|
{label && (
|
|
<div className="flex items-center gap-[var(--spacing-scale-002)]">
|
|
<label className="text-[14px] leading-[20px] font-medium text-[var(--color-content-default-primary)]">
|
|
{label}
|
|
</label>
|
|
{showHelpIcon && (
|
|
<svg
|
|
width="12"
|
|
height="12"
|
|
viewBox="0 0 12 12"
|
|
fill="none"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
className="shrink-0 w-[12px] h-[12px]"
|
|
>
|
|
<mask
|
|
id="mask0_21296_8257"
|
|
style={{ maskType: "alpha" }}
|
|
maskUnits="userSpaceOnUse"
|
|
x="0"
|
|
y="0"
|
|
width="12"
|
|
height="12"
|
|
>
|
|
<rect width="12" height="12" fill="#D9D9D9" />
|
|
</mask>
|
|
<g mask="url(#mask0_21296_8257)">
|
|
<path
|
|
d="M5.99449 8.80766C6.13725 8.80766 6.25784 8.75838 6.35624 8.6598C6.45463 8.56123 6.50383 8.44055 6.50383 8.29779C6.50383 8.15502 6.45454 8.03444 6.35596 7.93605C6.25739 7.83765 6.13672 7.78845 5.99395 7.78845C5.85118 7.78845 5.7306 7.83774 5.63221 7.93631C5.53381 8.03489 5.48461 8.15556 5.48461 8.29833C5.48461 8.44109 5.5339 8.56168 5.63248 8.66008C5.73105 8.75847 5.85172 8.80766 5.99449 8.80766ZM5.64038 7.01729H6.34421C6.35062 6.77114 6.38668 6.5745 6.45239 6.42739C6.51809 6.28028 6.67754 6.08525 6.93075 5.8423C7.15062 5.62243 7.31905 5.41938 7.43604 5.23316C7.55302 5.04695 7.61151 4.82703 7.61151 4.57343C7.61151 4.14307 7.45687 3.80689 7.14759 3.5649C6.8383 3.32292 6.47243 3.20193 6.04999 3.20193C5.63269 3.20193 5.28734 3.3133 5.01394 3.53606C4.74055 3.75881 4.54552 4.02115 4.42885 4.32306L5.07114 4.58075C5.13204 4.41473 5.2362 4.25303 5.38364 4.09566C5.53108 3.93829 5.74999 3.8596 6.04038 3.8596C6.33589 3.8596 6.55432 3.94053 6.69566 4.1024C6.83701 4.26426 6.90769 4.4423 6.90769 4.63654C6.90769 4.80641 6.85929 4.96185 6.76249 5.10288C6.6657 5.2439 6.5423 5.38012 6.3923 5.51154C6.0641 5.80769 5.85673 6.0439 5.77019 6.22019C5.68365 6.39647 5.64038 6.66217 5.64038 7.01729ZM6.00082 10.75C5.34386 10.75 4.72634 10.6253 4.14828 10.376C3.5702 10.1266 3.06736 9.78827 2.63975 9.36085C2.21213 8.93343 1.8736 8.43081 1.62416 7.85299C1.37472 7.27518 1.25 6.65779 1.25 6.00083C1.25 5.34386 1.37467 4.72634 1.624 4.14828C1.87333 3.5702 2.21171 3.06736 2.63913 2.63975C3.06655 2.21213 3.56917 1.8736 4.14699 1.62416C4.7248 1.37472 5.34218 1.25 5.99915 1.25C6.65612 1.25 7.27363 1.37467 7.8517 1.624C8.42978 1.87333 8.93262 2.21171 9.36023 2.63913C9.78784 3.06655 10.1264 3.56917 10.3758 4.14699C10.6253 4.7248 10.75 5.34218 10.75 5.99915C10.75 6.65612 10.6253 7.27363 10.376 7.8517C10.1266 8.42978 9.78827 8.93262 9.36085 9.36023C8.93343 9.78784 8.43081 10.1264 7.85299 10.3758C7.27518 10.6253 6.65779 10.75 6.00082 10.75ZM5.99999 9.99999C7.11665 9.99999 8.06249 9.61249 8.83749 8.83749C9.61249 8.06249 9.99999 7.11665 9.99999 5.99999C9.99999 4.88332 9.61249 3.93749 8.83749 3.16249C8.06249 2.38749 7.11665 1.99999 5.99999 1.99999C4.88332 1.99999 3.93749 2.38749 3.16249 3.16249C2.38749 3.93749 1.99999 4.88332 1.99999 5.99999C1.99999 7.11665 2.38749 8.06249 3.16249 8.83749C3.93749 9.61249 4.88332 9.99999 5.99999 9.99999Z"
|
|
fill="var(--color-content-brand-darker-accent-2)"
|
|
/>
|
|
</g>
|
|
</svg>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
{/* Input field */}
|
|
<div className="relative">
|
|
<input
|
|
type="text"
|
|
placeholder={placeholder}
|
|
value={value}
|
|
onChange={(e) => {
|
|
if (e.target.value.length <= maxLength) {
|
|
onChange(e.target.value);
|
|
}
|
|
}}
|
|
maxLength={maxLength}
|
|
className={`w-full h-[36px] px-[12px] py-[8px] bg-[var(--color-surface-default-primary)] border-2 border-[var(--color-border-default-tertiary)] rounded-[var(--measures-radius-medium,8px)] text-medium-paragraph text-[var(--color-content-default-primary)] placeholder:text-[var(--color-content-default-tertiary)] focus:outline-none ${inputClassName}`}
|
|
/>
|
|
</div>
|
|
|
|
{/* Character counter */}
|
|
<p className="text-x-small-paragraph text-[var(--color-content-default-tertiary)]">
|
|
{value.length}/{maxLength}
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|