İçeriğe geç
Docs

Canlı Tema ve Karanlık Mod

Canlı tema — ThemeConfig, tema birleştirme sırası, Studio Tema paneli ve hazır paletler, --theme-* CSS değişkenleri, fontlar, karanlık mod (config.darkMode) ve tema yardımcıları.

Son güncelleme:

Studio’daki Tema paneli sayfanın renklerini, tipografisini ve boşluk değerlerini düzenler. Değişiklikler hem editöre hem kanvasa anında --theme-* CSS değişkenleri olarak uygulanır; yayında TecofRender aynı değişkenleri kendisi basar.

Tema modeli#

TypeScript
interface ThemeConfig {
  colors: ThemeColors;          // primary, secondary, accent, background, foreground, muted,
                                // mutedForeground, border, card, cardForeground, destructive
  darkColors?: Partial<ThemeColors>; // yalnız config.darkMode açıkken
  typography: ThemeTypography;  // fontFamily, headingFontFamily, baseFontSize, lineHeight,
                                // headingScale { h1…h6 }, fontWeightNormal/Medium/Bold
  spacing: ThemeSpacing;        // containerMaxWidth, sectionPaddingY/X, componentGap,
                                // borderRadius, borderRadiusLg, borderRadiusSm
  customTokens?: Record<string, string>;
  customFonts?: CustomFont[];   // yüklenen @font-face dosyaları
  fonts?: string[];             // kullanılan yerleşik font kimlikleri
}

Birleştirme sırası: yerleşik varsayılanlar ← config.theme (temanın marka değerleri) ← sayfanın kendi ayarı (root.props._tecofTheme, Tema panelinde düzenlenen). Tema sayfa verisinde saklandığı için kayda, geri al ve yinele akışına dahildir.

app/editor-config.tsx
export const editorConfig: StudioConfig = {
  components,
  theme: {
    colors: { primary: "#a3472f", background: "#f5f3ed", foreground: "#242721", border: "#d7d7cc" },
    typography: { fontFamily: "'Inter', sans-serif", headingFontFamily: "'Inter', sans-serif", lineHeight: 1.7 },
    spacing: { containerMaxWidth: 1440, sectionPaddingY: 96, borderRadius: 0 },
    fonts: ["inter"],
  },
  themePresets: [
    { id: "clay", label: "Kil", colors: { primary: "#a3472f", accent: "#a3472f", background: "#f5f3ed" } },
    { id: "forest", label: "Orman", colors: { primary: "#365745", accent: "#365745", background: "#f2f4ef" } },
  ],
};

themePresets Tema panelindeki Renkler bölümünün üstünde kart olarak listelenir; tıklayınca yalnız renkler _tecofTheme.colors üzerine uygulanır (tipografi ve boşluk değişmez), kullanıcı sonra tek tek renkleri düzenlemeye devam edebilir.

CSS değişkenleri#

generateCSSVariables(theme) aşağıdaki değişkenleri üretir:

GrupDeğişkenler
Renkler--theme-color-primary, -secondary, -accent, -background, -foreground, -muted, -muted-foreground, -border, -card, -card-foreground, -destructive
Tipografi--theme-font-family, --theme-heading-font-family, --theme-font-size-base, --theme-line-height, --theme-font-weight-normal/-medium/-bold, --theme-heading-h1 … -h6
Fontlar--font-<id> (ör. --font-inter)
Boşluk--theme-container-max-width, --theme-section-padding-y/-x, --theme-component-gap, --theme-border-radius, -lg, -sm

Bileşenlerinizde tema rengini doğrudan kullanın; tema panelindeki değişiklik bileşene yansır:

TSX
<section className="bg-[var(--theme-color-background)] text-[var(--theme-color-foreground)]">…</section>

Yayına uygulama#

TecofRender çözülmüş temadan <style data-tecof-theme> (tema değişkenleri), Google Fonts <link>’i ve yüklenen fontlar için @font-face kurallarını kendisi basar. Ek kurulum gerekmez.

Sayfayı kendiniz render ediyor ya da <head>’i kendiniz kuruyorsanız aynı çıktıyı yardımcılarla üretin:

TypeScript
import { generateCSSVariables, getDefaultTheme, mergeTheme, themeGoogleFontsHref, themeFontFaceCss } from "@tecof/theme-editor";

const theme = mergeTheme(getDefaultTheme(), editorConfig.theme ?? {});
const css = generateCSSVariables(theme);            // ":root { --theme-color-primary: … }"
const fontsHref = themeGoogleFontsHref(theme);       // Google Fonts adresi ya da boş
const fontFaces = themeFontFaceCss(theme);           // yüklenen fontlar için @font-face

Ek yardımcılar: hexToHsl, hslToHex, lighten, darken, deriveDarkColors, googleFontsHref, customFontFaceCss, BUILTIN_FONTS.

Fontlar#

Tema panelindeki font seçici önizlemeli, küratörlü bir listeden seçtirir ve özel font yüklemeye izin verir. Yerleşik font kimlikleri: system, georgia, inter, roboto, open-sans, lato, montserrat, poppins, nunito, work-sans, dm-sans, raleway, playfair-display, merriweather, lora, oswald, bebas-neue, jetbrains-mono. Seçilen font hem tema değişkenine hem theme.fonts listesine yazılır; Stil sekmesindeki düğüm bazlı yazı tipi [var(--font-<id>)] token’ı kullanır.

Karanlık mod#

Karanlık mod isteğe bağlıdır ve temanın config’inde açılır. darkMode yoksa karanlık arayüz, karanlık CSS ve çalışma zamanı hiç yüklenmez.

TSX
export const editorConfig: StudioConfig = {
  components,
  darkMode: true, // ya da { defaultMode: "system" | "light" | "dark", storageKey: "shop-scheme" }
};

Strateji: <html> üzerindeki .dark sınıfı --theme-color-* değişkenlerinin değerlerini değiştirir; generateCSSVariables ikinci bir blok basar:

CSS
:root      { --theme-color-background: #ffffff; /* … */ }
:root.dark { --theme-color-background: #09090b; /* … */ }

Sayfa içeriğinin sınıfları değişmez (bg-[var(--theme-color-primary)] aynı kalır); yalnız değişkenin çözüldüğü değer değişir. Bu yüzden dark: varyantı kullanılmaz ve hiçbir safelist gerekmez.

  • Koyu renkler Tema panelinde düzenlenir (theme.darkColors) ya da “Koyu palet üret” ile açık paletten türetilir (deriveDarkColors). Girilmeyen anahtar açık moddaki değerine düşer.
  • Editörde önizleme: üst çubuktaki güneş/ay düğmesi kanvası koyu palete çevirir (yalnız darkMode açıkken görünür; dokümana yazılmaz).
  • Ziyaretçi düğmesi: sayfaya class="tecof-darkmode-toggle" taşıyan herhangi bir buton koyun. Çalışma zamanı tıklamayı delege dinler, .dark’ı çevirir ve seçimi localStorage’a yazar (varsayılan anahtar tecof-color-scheme).
  • İlk şema: defaultMode — system (varsayılan, işletim sistemini izler), light ya da dark. Ziyaretçinin kayıtlı seçimi her zaman kazanır.
  • Yanlış tema flaşı olmasın: TecofRender <head> üretmez; sıfır flaş için <head>’e darkModeHeadScript(config) çıktısını satır içi betik olarak koyun.
app/layout.tsx
import { darkModeHeadScript } from "@tecof/theme-editor";
import { editorConfig } from "@/app/editor-config";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="tr" suppressHydrationWarning>
      <head>
        <script dangerouslySetInnerHTML={{ __html: darkModeHeadScript(editorConfig) }} />
      </head>
      <body>{children}</body>
    </html>
  );
}

Kendi sayfasını render eden host’lar için: initDarkMode(document), darkModeHeadScript(config), deriveDarkColors(light), DARK_MODE_STORAGE_KEY.