feat(08-02): migrate UI primitives to semantic MD3 token classes
- BackendCard: border-blue-600/bg-blue-50 -> border-primary/bg-primary/10, border-gray-200/bg-white -> border-outline/bg-surface-container, text-gray-900 -> text-on-surface, text-gray-500 -> text-on-surface-container/70 - FieldRenderer: text-gray-700 -> text-on-surface-container, text-red-500 -> text-error, text-blue-500/700 -> text-primary, bg-blue-50/border-blue-200 -> bg-primary/10/border-primary/30, border-red-500 -> border-error, focus:ring-red-300 -> focus:ring-error/50, border-gray-300 -> border-outline, focus:ring-blue-300 -> focus:ring-primary/50, text-gray-500 -> text-on-surface-container/70, text-red-600 -> text-error - PasswordField: same mapping as FieldRenderer + text-gray-400/hover:text-gray-700 -> text-on-surface-container/50 hover:text-on-surface-container
This commit is contained in:
@@ -16,13 +16,13 @@ export function BackendCard({ name, description, selected = false, onClick, ...r
|
|||||||
className={[
|
className={[
|
||||||
'flex flex-col items-start gap-1 rounded-lg border-2 p-4 text-left transition-colors',
|
'flex flex-col items-start gap-1 rounded-lg border-2 p-4 text-left transition-colors',
|
||||||
selected
|
selected
|
||||||
? 'border-blue-600 bg-blue-50'
|
? 'border-primary bg-primary/10'
|
||||||
: 'border-gray-200 bg-white hover:border-blue-400 hover:bg-gray-50',
|
: 'border-outline bg-surface-container hover:border-primary hover:bg-surface',
|
||||||
].join(' ')}
|
].join(' ')}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
<span className="font-semibold text-gray-900">{name}</span>
|
<span className="font-semibold text-on-surface">{name}</span>
|
||||||
<span className="text-sm text-gray-500">{description}</span>
|
<span className="text-sm text-on-surface-container/70">{description}</span>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,23 +41,23 @@ export function FieldRenderer({ field, register, error }: FieldRendererProps) {
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<label htmlFor={field.key} className="text-sm font-medium text-gray-700">
|
<label htmlFor={field.key} className="text-sm font-medium text-on-surface-container">
|
||||||
{field.label}
|
{field.label}
|
||||||
{field.required && <span className="ml-1 text-red-500">*</span>}
|
{field.required && <span className="ml-1 text-error">*</span>}
|
||||||
</label>
|
</label>
|
||||||
{field.tooltipText && (
|
{field.tooltipText && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowTooltip(v => !v)}
|
onClick={() => setShowTooltip(v => !v)}
|
||||||
aria-label={`More info about ${field.label}`}
|
aria-label={`More info about ${field.label}`}
|
||||||
className="text-blue-500 hover:text-blue-700 text-xs leading-none"
|
className="text-primary hover:text-primary text-xs leading-none"
|
||||||
>
|
>
|
||||||
ⓘ
|
ⓘ
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{field.tooltipText && showTooltip && (
|
{field.tooltipText && showTooltip && (
|
||||||
<p className="text-xs text-blue-700 bg-blue-50 border border-blue-200 rounded px-2 py-1.5 mt-1">
|
<p className="text-xs text-primary bg-primary/10 border border-primary/30 rounded px-2 py-1.5 mt-1">
|
||||||
{field.tooltipText}
|
{field.tooltipText}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
@@ -65,7 +65,7 @@ export function FieldRenderer({ field, register, error }: FieldRendererProps) {
|
|||||||
id={field.key}
|
id={field.key}
|
||||||
className={[
|
className={[
|
||||||
'w-full rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2',
|
'w-full rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2',
|
||||||
error ? 'border-red-500 focus:ring-red-300' : 'border-gray-300 focus:ring-blue-300',
|
error ? 'border-error focus:ring-error/50' : 'border-outline focus:ring-primary/50',
|
||||||
].join(' ')}
|
].join(' ')}
|
||||||
{...register(field.key)}
|
{...register(field.key)}
|
||||||
>
|
>
|
||||||
@@ -73,8 +73,8 @@ export function FieldRenderer({ field, register, error }: FieldRendererProps) {
|
|||||||
<option key={opt.value} value={opt.value}>{opt.label}</option>
|
<option key={opt.value} value={opt.value}>{opt.label}</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
{field.helpText && !error && <p className="text-xs text-gray-500">{field.helpText}</p>}
|
{field.helpText && !error && <p className="text-xs text-on-surface-container/70">{field.helpText}</p>}
|
||||||
{error && <p className="text-xs text-red-600">{error.message}</p>}
|
{error && <p className="text-xs text-error">{error.message}</p>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -85,13 +85,13 @@ export function FieldRenderer({ field, register, error }: FieldRendererProps) {
|
|||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<label htmlFor={field.key} className="text-sm font-medium text-gray-700">
|
<label htmlFor={field.key} className="text-sm font-medium text-gray-700">
|
||||||
{field.label}
|
{field.label}
|
||||||
{field.required && <span className="ml-1 text-red-500">*</span>}
|
{field.required && <span className="ml-1 text-error">*</span>}
|
||||||
</label>
|
</label>
|
||||||
{field.tooltipText && (
|
{field.tooltipText && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowTooltip(v => !v)}
|
onClick={() => setShowTooltip(v => !v)}
|
||||||
className="text-blue-500 hover:text-blue-700 text-xs leading-none"
|
className="text-primary hover:text-primary text-xs leading-none"
|
||||||
>
|
>
|
||||||
<span className="sr-only">More info about {field.label}</span>
|
<span className="sr-only">More info about {field.label}</span>
|
||||||
<span aria-hidden="true">ⓘ</span>
|
<span aria-hidden="true">ⓘ</span>
|
||||||
@@ -109,12 +109,12 @@ export function FieldRenderer({ field, register, error }: FieldRendererProps) {
|
|||||||
placeholder={field.placeholder}
|
placeholder={field.placeholder}
|
||||||
className={[
|
className={[
|
||||||
'w-full rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2',
|
'w-full rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2',
|
||||||
error ? 'border-red-500 focus:ring-red-300' : 'border-gray-300 focus:ring-blue-300',
|
error ? 'border-error focus:ring-error/50' : 'border-outline focus:ring-primary/50',
|
||||||
].join(' ')}
|
].join(' ')}
|
||||||
{...register(field.key)}
|
{...register(field.key)}
|
||||||
/>
|
/>
|
||||||
{field.helpText && !error && <p className="text-xs text-gray-500">{field.helpText}</p>}
|
{field.helpText && !error && <p className="text-xs text-on-surface-container/70">{field.helpText}</p>}
|
||||||
{error && <p className="text-xs text-red-600">{error.message}</p>}
|
{error && <p className="text-xs text-error">{error.message}</p>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ export function PasswordField({ id, label, error, registration, placeholder, hel
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<label htmlFor={id} className="text-sm font-medium text-gray-700">
|
<label htmlFor={id} className="text-sm font-medium text-on-surface-container">
|
||||||
{label}
|
{label}
|
||||||
</label>
|
</label>
|
||||||
{tooltipText && (
|
{tooltipText && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowTooltip(v => !v)}
|
onClick={() => setShowTooltip(v => !v)}
|
||||||
className="text-blue-500 hover:text-blue-700 text-xs leading-none"
|
className="text-primary hover:text-primary text-xs leading-none"
|
||||||
>
|
>
|
||||||
<span className="sr-only">More info about {label}</span>
|
<span className="sr-only">More info about {label}</span>
|
||||||
<span aria-hidden="true">ⓘ</span>
|
<span aria-hidden="true">ⓘ</span>
|
||||||
@@ -32,7 +32,7 @@ export function PasswordField({ id, label, error, registration, placeholder, hel
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{tooltipText && showTooltip && (
|
{tooltipText && showTooltip && (
|
||||||
<p className="text-xs text-blue-700 bg-blue-50 border border-blue-200 rounded px-2 py-1.5 mt-1">
|
<p className="text-xs text-primary bg-primary/10 border border-primary/30 rounded px-2 py-1.5 mt-1">
|
||||||
{tooltipText}
|
{tooltipText}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
@@ -43,7 +43,7 @@ export function PasswordField({ id, label, error, registration, placeholder, hel
|
|||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
className={[
|
className={[
|
||||||
'w-full rounded-md border px-3 py-2 pr-10 text-sm focus:outline-none focus:ring-2',
|
'w-full rounded-md border px-3 py-2 pr-10 text-sm focus:outline-none focus:ring-2',
|
||||||
error ? 'border-red-500 focus:ring-red-300' : 'border-gray-300 focus:ring-blue-300',
|
error ? 'border-error focus:ring-error/50' : 'border-outline focus:ring-primary/50',
|
||||||
].join(' ')}
|
].join(' ')}
|
||||||
{...registration}
|
{...registration}
|
||||||
/>
|
/>
|
||||||
@@ -51,13 +51,13 @@ export function PasswordField({ id, label, error, registration, placeholder, hel
|
|||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShow(v => !v)}
|
onClick={() => setShow(v => !v)}
|
||||||
aria-label={show ? 'Hide' : 'Show'}
|
aria-label={show ? 'Hide' : 'Show'}
|
||||||
className="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-700"
|
className="absolute right-2 top-1/2 -translate-y-1/2 text-on-surface-container/50 hover:text-on-surface-container"
|
||||||
>
|
>
|
||||||
{show ? 'Hide' : 'Show'}
|
{show ? 'Hide' : 'Show'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{helpText && !error && <p className="text-xs text-gray-500">{helpText}</p>}
|
{helpText && !error && <p className="text-xs text-on-surface-container/70">{helpText}</p>}
|
||||||
{error && <p className="text-xs text-red-600">{error.message}</p>}
|
{error && <p className="text-xs text-error">{error.message}</p>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user