fix(web): VIN ikonundaki marka logolarını tutarlı 28px kareye sabitle

Tailwind Preflight img'lere height:auto uyguladığından statik-SVG logolar
en-boy oranına göre ölçekleniyordu (Opel ~17px küçük, Renault ~29px taşma).
VinBrandIcon artık sabit 28px kare + object-contain ile hem img hem svg
logolarını aynı boyutta gösteriyor; büyüteç optik denge için biraz küçük.
Playwright ile landing VIN textbox üzerinde doğrulandı.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-26 00:00:22 +03:00
parent 77de860211
commit d72e7bb758
3 changed files with 15 additions and 14 deletions

View File

@@ -6,6 +6,7 @@ import { Search } from "lucide-react";
interface VinBrandIconProps { interface VinBrandIconProps {
/** Mevcut VIN değeri — ilk 3 karakter (WMI) bilinen bir markaya denk gelirse logo gösterilir. */ /** Mevcut VIN değeri — ilk 3 karakter (WMI) bilinen bir markaya denk gelirse logo gösterilir. */
vin: string; vin: string;
/** İkon kutusunun kenar uzunluğu (px). Logolar bu kutu içinde object-contain ile ölçeklenir. */
size?: number; size?: number;
/** Konumlandırma için sarmalayıcıya verilen sınıf (örn. absolute left-4 ...). */ /** Konumlandırma için sarmalayıcıya verilen sınıf (örn. absolute left-4 ...). */
className?: string; className?: string;
@@ -15,25 +16,33 @@ interface VinBrandIconProps {
* VIN textbox'ının solundaki ikon. WMI (ilk 3 karakter) bilinen bir markaya * VIN textbox'ının solundaki ikon. WMI (ilk 3 karakter) bilinen bir markaya
* denk gelince büyüteç yerine ilgili marka logosu pop animasyonuyla görünür; * denk gelince büyüteç yerine ilgili marka logosu pop animasyonuyla görünür;
* WMI silinince tekrar büyüteç olur. * WMI silinince tekrar büyüteç olur.
*
* Logolar sabit bir kareye `object-contain` ile yerleştirilir; böylece dikey
* (Renault) veya yatay (Opel) viewBox'lı SVG'ler de tutarlı boyutta görünür
* (Tailwind Preflight'ın img'lere uyguladığı height:auto sorununu da çözer).
*/ */
export function VinBrandIcon({ vin, size = 20, className }: VinBrandIconProps) { export function VinBrandIcon({ vin, size = 28, className }: VinBrandIconProps) {
const wmi = vin.trim().toUpperCase().slice(0, 3); const wmi = vin.trim().toUpperCase().slice(0, 3);
const brand = wmi.length === 3 ? getBrandFromWmi(wmi) : null; const brand = wmi.length === 3 ? getBrandFromWmi(wmi) : null;
return ( return (
<span className={cn("pointer-events-none flex items-center justify-center", className)}> <span
style={{ width: size, height: size }}
className={cn("pointer-events-none flex items-center justify-center", className)}
>
{brand ? ( {brand ? (
<CarBrandLogo <CarBrandLogo
// key: marka değiştiğinde yeniden mount edip pop animasyonunu tetikler // key: marka değiştiğinde yeniden mount edip pop animasyonunu tetikler
key={`brand:${brand}`} key={`brand:${brand}`}
brandName={brand} brandName={brand}
size={size} size={size}
className="animate-icon-pop" className="size-full animate-icon-pop object-contain"
/> />
) : ( ) : (
// Büyüteç logolardan biraz küçük dursun (optik denge)
<Search <Search
key="search" key="search"
style={{ width: size, height: size }} style={{ width: size * 0.8, height: size * 0.8 }}
className="animate-icon-pop text-muted-foreground" className="animate-icon-pop text-muted-foreground"
/> />
)} )}

View File

@@ -501,11 +501,7 @@ function SearchPage() {
<form onSubmit={handleSearch} className="space-y-4"> <form onSubmit={handleSearch} className="space-y-4">
{/* Input */} {/* Input */}
<div className="relative"> <div className="relative">
<VinBrandIcon <VinBrandIcon vin={vin} className="absolute left-4 top-1/2 -translate-y-1/2" />
vin={vin}
size={22}
className="absolute left-4 top-1/2 size-6 -translate-y-1/2"
/>
<Input <Input
ref={inputRef} ref={inputRef}
placeholder="Şase numarasını girin (17 karakter)" placeholder="Şase numarasını girin (17 karakter)"

View File

@@ -841,11 +841,7 @@ export function HomePage() {
{/* VIN Input */} {/* VIN Input */}
<div className="mx-auto mt-8 flex max-w-xl flex-col gap-3 sm:flex-row"> <div className="mx-auto mt-8 flex max-w-xl flex-col gap-3 sm:flex-row">
<div className="relative flex-1"> <div className="relative flex-1">
<VinBrandIcon <VinBrandIcon vin={vin} className="absolute left-4 top-1/2 -translate-y-1/2" />
vin={vin}
size={22}
className="absolute left-4 top-1/2 size-6 -translate-y-1/2"
/>
<Input <Input
value={vin} value={vin}
onChange={(e) => setVin(e.target.value.toUpperCase())} onChange={(e) => setVin(e.target.value.toUpperCase())}