Files
community-rule/app/components/controls/TextInput/TextInput.view.tsx
T
adilalloandCursor 2321a1e761 Adopt remaining typography token classes (CR-24)
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>
2026-08-17 11:40:10 -06:00

98 lines
3.0 KiB
TypeScript

import { forwardRef } from "react";
import { getAssetPath, ASSETS } from "../../../../lib/assetUtils";
import type { TextInputViewProps } from "./TextInput.types";
export const TextInputView = forwardRef<HTMLInputElement, TextInputViewProps>(
(
{
inputId,
labelId,
label,
placeholder,
value,
name,
type,
disabled,
error: _error,
className: _className,
containerClasses,
labelClasses,
inputClasses,
borderRadius,
handleChange,
handleFocus,
handleBlur,
handleMouseDown,
showHelpIcon = true,
inputWrapperClasses = "relative",
focusRingClasses = "",
textHint = false,
formHeader = true,
maxLength,
helpIconAlt,
hintDefault,
},
ref,
) => {
return (
<div className={containerClasses}>
{formHeader && label && (
<div className="flex flex-wrap gap-[var(--measures-spacing-200,4px_8px)] items-baseline pr-[var(--measures-spacing-100,4px)] relative shrink-0 w-full">
<div className="flex gap-[var(--measures-spacing-050,2px)] items-center relative shrink-0">
<label
id={labelId}
htmlFor={inputId}
className={`${labelClasses} font-medium text-[var(--color-content-default-primary)]`}
>
{label}
</label>
{showHelpIcon && (
<div className="relative shrink-0 size-[12px]">
{/* eslint-disable-next-line @next/next/no-img-element -- icon asset */}
<img
src={getAssetPath(ASSETS.ICON_HELP)}
alt={helpIconAlt}
className="block max-w-none size-full"
/>
</div>
)}
</div>
</div>
)}
<div className={inputWrapperClasses}>
<div className={disabled ? "opacity-40" : ""}>
<input
ref={ref}
id={inputId}
name={name}
type={type}
value={value}
placeholder={placeholder}
onChange={handleChange}
onFocus={handleFocus}
onBlur={handleBlur}
onMouseDown={handleMouseDown}
disabled={disabled}
maxLength={maxLength}
className={inputClasses}
style={{ borderRadius }}
/>
</div>
{focusRingClasses && (
<div className={focusRingClasses} aria-hidden="true" />
)}
</div>
{textHint && (
<div className="flex items-start relative shrink-0 w-full">
<p className="flex-[1_0_0] text-x-small-paragraph min-h-px min-w-px relative text-[color:var(--color-content-default-tertiary,#b4b4b4)]">
{typeof textHint === "string" ? textHint : hintDefault}
</p>
</div>
)}
</div>
);
},
);
TextInputView.displayName = "TextInputView";