From 316f1dafa02f15bf42a75eaaf54d4d67fd4790c8 Mon Sep 17 00:00:00 2001 From: bilalgursen Date: Fri, 9 Oct 2026 00:30:58 +0300 Subject: [PATCH] =?UTF-8?q?feat(tema):=20tema=20se=C3=A7ici=20ikonlar?= =?UTF-8?q?=C4=B1=20g=C3=BCne=C5=9F,=20ay=20ve=20logo=20kareleri?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Geçişte logonun dönüştüğü biçimlerin durağan hâli (tema-ikonu.tsx): Açık için güneş ve halesi, Koyu için hilal ve iki yıldız, Sistem için logonun üç karesi. lucide Sun/Moon/Monitor seçiciden kalktı. DESIGN §2.3 güncel. Co-Authored-By: Claude Opus 5.5 --- docs/tasarim/DESIGN.md | 4 ++- src/components/tema-ikonu.tsx | 53 ++++++++++++++++++++++++++++++++++ src/components/tema-secici.tsx | 15 +++++----- 3 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 src/components/tema-ikonu.tsx diff --git a/docs/tasarim/DESIGN.md b/docs/tasarim/DESIGN.md index e9b4e27..0eb0784 100644 --- a/docs/tasarim/DESIGN.md +++ b/docs/tasarim/DESIGN.md @@ -138,7 +138,9 @@ tema header'daki logodan **yumuşak bir halka** gibi açılır: kenarı keskin d tüylü (ışık yayılır gibi), 1100 ms, yumuşak kalkıp yumuşak durur. Aynı anda logonun kareleri yeni temanın biçimine dönüşür: koyuya geçişte şeftali kare hilale, mavi ve turuncu kareler iki yıldıza; açığa geçişte turuncu kare güneşe, şeftali kare halesine. Kısa bir an durur, yeniden -logoya toplanır (`animasyonlu-mark.tsx` `temaSekli`, 1,7 sn; yalnız header'daki logo). View Transitions + radyal degrade +logoya toplanır (`animasyonlu-mark.tsx` `temaSekli`, 1,7 sn; yalnız header'daki logo). Tema +seçicinin ikonları aynı biçimlerin durağan hâlidir (`tema-ikonu.tsx`: güneş, ay, Sistem için +logonun üç karesi); burada lucide ikonu kullanılmaz. View Transitions + radyal degrade maskesi: `src/lib/tema-gecisi.ts`, `globals.css` `.kt-tema-gecis`; hareket azaltılmışsa düz değişir. Denenip bırakılanlar: logo biçimli maske ("logo içinde logo"), düz crossfade, piksel ızgarası (sert bulundu). Kural: bu geçişte sert kenar ve ikinci bir şekil yok. diff --git a/src/components/tema-ikonu.tsx b/src/components/tema-ikonu.tsx new file mode 100644 index 0000000..8af093b --- /dev/null +++ b/src/components/tema-ikonu.tsx @@ -0,0 +1,53 @@ +import { useId } from "react"; + +// Tema seçicinin ikonları (DESIGN.md §2.3): tema geçişinde header'daki logonun +// dönüştüğü biçimlerin durağan hâli (animasyonlu-mark.tsx `temaSekli`). +// - "light": güneş — turuncu daire, arkasında şeftali hale. +// - "dark": ay — şeftali hilal, yanında mavi ve turuncu iki yıldız. +// - "system": logonun üç karesi — ikisine de dönüşebilen hâl. +// Renkler logonun renkleridir ve iki temada aynıdır (§2.3); 180'lik kutu +// public/kolay-tercih-mark.svg ile aynı. Dekoratiftir: anlamı yanındaki +// etiket taşır. + +const MAVI = "#3b82f6"; +const SEFTALI = "#fdc7a7"; +const TURUNCU = "#ff5a00"; + +export type TemaIkonuTuru = "light" | "dark" | "system"; + +export function TemaIkonu({ + tur, + className, +}: { + tur: TemaIkonuTuru; + className?: string; +}) { + const maskeId = useId(); + return ( + + ); +} diff --git a/src/components/tema-secici.tsx b/src/components/tema-secici.tsx index bc98272..7d7980a 100644 --- a/src/components/tema-secici.tsx +++ b/src/components/tema-secici.tsx @@ -2,15 +2,15 @@ import { useSyncExternalStore } from "react"; import { useTheme } from "next-themes"; -import { Monitor, Moon, Sun } from "lucide-react"; +import { TemaIkonu } from "@/components/tema-ikonu"; import { Kbd } from "@/components/ui/kbd"; import { temayiGecisle } from "@/lib/tema-gecisi"; import { cn } from "@/lib/utils"; const SECENEKLER = [ - { deger: "light", etiket: "Açık", ikon: Sun }, - { deger: "dark", etiket: "Koyu", ikon: Moon }, - { deger: "system", etiket: "Sistem", ikon: Monitor }, + { deger: "light", etiket: "Açık" }, + { deger: "dark", etiket: "Koyu" }, + { deger: "system", etiket: "Sistem" }, ] as const; const aboneOlma = () => () => {}; @@ -18,7 +18,8 @@ const aboneOlma = () => () => {}; /** * Tema seçici: açık / koyu / sistem (DESIGN.md §2.3). Seçili tema yalnızca * tarayıcıda bilinir; sunucu HTML'inde hiçbir seçenek işaretli gelmez, - * hydration sonrası işaretlenir (yerleşim oynamaz). Seçim logodan yumuşak bir halka + * hydration sonrası işaretlenir (yerleşim oynamaz). İkonlar geçişte logonun + * dönüştüğü biçimlerdir: güneş, ay ve logonun kendisi (tema-ikonu.tsx). Seçim logodan yumuşak bir halka * gibi yayılarak uygulanır (lib/tema-gecisi.ts); altında `D` kısayolu ipucu durur. */ export function TemaSecici({ className }: { className?: string }) { @@ -36,7 +37,7 @@ export function TemaSecici({ className }: { className?: string }) { aria-label="Tema" className="inline-flex items-center gap-1 rounded-full border border-slate-200 bg-card p-1" > - {SECENEKLER.map(({ deger, etiket, ikon: Ikon }) => { + {SECENEKLER.map(({ deger, etiket }) => { const secili = tarayicida && theme === deger; return ( );