Ana içeriğe geç

Tema Özelleştirme

Bu bölümde, mevcut temaları nasıl özelleştirebileceğinizi ve genişletebileceğinizi öğreneceksiniz.

Mevcut Temayı Genişletme

Var olan bir temayı temel alarak yeni temalar oluşturabilirsiniz.

// Mevcut bir temayı genişletme örneği
// örnek: src/themes/extendedTheme.js
import { customTheme } from './customTheme';

// Var olan temayı genişletme
export const extendedTheme = {
// Önce tüm tema özelliklerini kopyala
...customTheme,

// Ardından belirli özellikleri değiştir veya ekle
colors: {
...customTheme.colors,
// Yeni renkler ekle
success: '#28a745',
warning: '#ffc107',
error: '#dc3545',
// Mevcut renkleri değiştir
primary: '#0088FF',
},

// Yeni bir özellik kategorisi ekle
borders: {
thin: '1px solid',
medium: '2px solid',
thick: '4px solid',
}
};

Dinamik Temalar Oluşturma

Kullanıcı girdilerine göre dinamik temalar oluşturabilirsiniz.

// Dinamik tema oluşturucu bileşen
// örnek: src/components/ThemeBuilder.jsx
import React, { useState } from 'react';
import { themeRegistry } from '../core/themes';
import { ChromePicker } from 'react-color';

const ThemeBuilder = ({ onThemeCreate }) => {
// Başlangıç tema ayarları
const [themeSettings, setThemeSettings] = useState({
name: 'custom-theme',
primaryColor: '#0088FF',
secondaryColor: '#FF5500',
backgroundColor: '#FFFFFF',
textColor: '#333333',
borderRadius: '4px',
});

// Renk değişikliklerini işle
const handleColorChange = (color, type) => {
setThemeSettings({
...themeSettings,
[type]: color.hex,
});
};

// Input değişikliklerini işle
const handleInputChange = (e) => {
const { name, value } = e.target;
setThemeSettings({
...themeSettings,
[name]: value,
});
};

// Tema oluştur
const createTheme = () => {
// Tema ayarlarından yeni tema oluştur
const newTheme = {
colors: {
primary: themeSettings.primaryColor,
secondary: themeSettings.secondaryColor,
background: themeSettings.backgroundColor,
text: themeSettings.textColor,
},
borders: {
radius: themeSettings.borderRadius,
},
fonts: {
body: 'Roboto, sans-serif',
heading: 'Montserrat, sans-serif',
},
spacing: {
small: '8px',
medium: '16px',
large: '24px',
}
};

// Tema kaydet
themeRegistry.register(themeSettings.name, newTheme);

// Parent bileşeni bilgilendir
if (onThemeCreate) {
onThemeCreate(themeSettings.name, newTheme);
}
};

return (
<div className="theme-builder">
<h2>Tema Oluşturucu</h2>

<div className="form-group">
<label>Tema Adı</label>
<input
type="text"
name="name"
value={themeSettings.name}
onChange={handleInputChange}
/>
</div>

<div className="color-pickers">
<div className="color-picker">
<label>Ana Renk</label>
<ChromePicker
color={themeSettings.primaryColor}
onChange={(color) => handleColorChange(color, 'primaryColor')}
/>
</div>

<div className="color-picker">
<label>İkincil Renk</label>
<ChromePicker
color={themeSettings.secondaryColor}
onChange={(color) => handleColorChange(color, 'secondaryColor')}
/>
</div>

<div className="color-picker">
<label>Arka Plan</label>
<ChromePicker
color={themeSettings.backgroundColor}
onChange={(color) => handleColorChange(color, 'backgroundColor')}
/>
</div>

<div className="color-picker">
<label>Metin Rengi</label>
<ChromePicker
color={themeSettings.textColor}
onChange={(color) => handleColorChange(color, 'textColor')}
/>
</div>
</div>

<div className="form-group">
<label>Köşe Yuvarlaklığı</label>
<select
name="borderRadius"
value={themeSettings.borderRadius}
onChange={handleInputChange}
>
<option value="0">Köşeli</option>
<option value="4px">Hafif Yuvarlak</option>
<option value="8px">Orta Yuvarlak</option>
<option value="16px">Çok Yuvarlak</option>
<option value="50%">Tam Yuvarlak</option>
</select>
</div>

<div className="preview" style={{
backgroundColor: themeSettings.backgroundColor,
color: themeSettings.textColor,
padding: '20px',
borderRadius: themeSettings.borderRadius,
}}>
<h3>Önizleme</h3>
<button style={{
backgroundColor: themeSettings.primaryColor,
color: '#fff',
borderRadius: themeSettings.borderRadius,
border: 'none',
padding: '8px 16px',
cursor: 'pointer',
}}>
Ana Buton
</button>
<button style={{
backgroundColor: themeSettings.secondaryColor,
color: '#fff',
borderRadius: themeSettings.borderRadius,
border: 'none',
padding: '8px 16px',
marginLeft: '10px',
cursor: 'pointer',
}}>
İkincil Buton
</button>
</div>

<button
className="create-theme-button"
onClick={createTheme}
>
Tema Oluştur
</button>
</div>
);
};

export default ThemeBuilder;

Tema Değişkenlerini Dışa Aktarma

Tema değişkenlerinizi stil dosyalarında veya CSS değişkenlerinde kullanabilirsiniz.

// Tema değişkenlerini CSS değişkenlerine dönüştürme
// örnek: src/utils/themeToCssVars.js
export const themeToCssVars = (theme) => {
// CSS değişkenlerini tutacak obje
const cssVars = {};

// Tema özelliklerini düzleştir ve CSS değişkeni formatına dönüştür
const flattenTheme = (obj, prefix = '') => {
for (const key in obj) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
// İç içe objeler için yineleme
flattenTheme(obj[key], `${prefix}${key}-`);
} else {
// Değeri CSS değişkeni olarak ekle
cssVars[`--${prefix}${key}`] = obj[key];
}
}
};

flattenTheme(theme);

return cssVars;
};

// Kullanım örneği
// örnek: src/ThemeRoot.jsx
import React from 'react';
import { themeToCssVars } from './utils/themeToCssVars';

const ThemeRoot = ({ theme, children }) => {
// Temayı CSS değişkenlerine dönüştür
const cssVars = themeToCssVars(theme);

return (
<div style={cssVars}>
{children}
</div>
);
};

export default ThemeRoot;

Tema Renk Paletiyle Çalışma

Tema renk paletleri oluşturmak ve yönetmek için yardımcı fonksiyonlar:

// Renk paleti oluşturma yardımcı fonksiyonları
// örnek: src/utils/colorUtils.js

// Renk açıklaştırma (daha açık ton oluşturma)
export const lighten = (color, amount) => {
// HEX rengi RGB'ye dönüştür
const r = parseInt(color.slice(1, 3), 16);
const g = parseInt(color.slice(3, 5), 16);
const b = parseInt(color.slice(5, 7), 16);

// Rengi açıklaştır
const lightenColor = (c) => Math.min(255, Math.round(c + (255 - c) * amount));

// Yeni RGB değerlerini HEX'e dönüştür
return `#${[r, g, b].map(c => {
const hex = lightenColor(c).toString(16);
return hex.length === 1 ? '0' + hex : hex;
}).join('')}`;
};

// Renk koyulaştırma (daha koyu ton oluşturma)
export const darken = (color, amount) => {
// HEX rengi RGB'ye dönüştür
const r = parseInt(color.slice(1, 3), 16);
const g = parseInt(color.slice(3, 5), 16);
const b = parseInt(color.slice(5, 7), 16);

// Rengi koyulaştır
const darkenColor = (c) => Math.max(0, Math.round(c * (1 - amount)));

// Yeni RGB değerlerini HEX'e dönüştür
return `#${[r, g, b].map(c => {
const hex = darkenColor(c).toString(16);
return hex.length === 1 ? '0' + hex : hex;
}).join('')}`;
};

// Ana renkten bir renk paleti oluşturma
export const createColorPalette = (mainColor) => {
return {
light3: lighten(mainColor, 0.7),
light2: lighten(mainColor, 0.5),
light1: lighten(mainColor, 0.3),
main: mainColor,
dark1: darken(mainColor, 0.2),
dark2: darken(mainColor, 0.4),
dark3: darken(mainColor, 0.6),
};
};

// Kullanım örneği
// örnek: src/themes/paletteTheme.js
import { createColorPalette } from '../utils/colorUtils';

export const paletteTheme = {
colors: {
primary: createColorPalette('#0088FF'),
secondary: createColorPalette('#FF5500'),
// Diğer tema renkleri...
},
// Diğer tema özellikleri...
};

Tema Ayarlarını Kaydetme ve Yükleme

Kullanıcıların tema özelleştirmelerini kaydetmelerini ve yüklemelerini sağlayabilirsiniz.

// Tema ayarlarını kaydetme ve yükleme
// örnek: src/components/ThemeManager.jsx
import React, { useState } from 'react';
import { themeRegistry } from '../core/themes';
import ThemeBuilder from './ThemeBuilder';

const ThemeManager = () => {
const [savedThemes, setSavedThemes] = useState(() => {
// LocalStorage'den kayıtlı temaları yükle
const storedThemes = localStorage.getItem('user_custom_themes');
return storedThemes ? JSON.parse(storedThemes) : {};
});

// Yeni tema oluşturulduğunda
const handleThemeCreate = (name, theme) => {
// Temayı kaydet
const updatedThemes = {
...savedThemes,
[name]: theme
};

setSavedThemes(updatedThemes);

// LocalStorage'e kaydet
localStorage.setItem('user_custom_themes', JSON.stringify(updatedThemes));
};

// Tema sil
const handleThemeDelete = (themeName) => {
const updatedThemes = { ...savedThemes };
delete updatedThemes[themeName];

setSavedThemes(updatedThemes);
localStorage.setItem('user_custom_themes', JSON.stringify(updatedThemes));

// Tema yöneticisinden de kaldır
themeRegistry.unregister(themeName);
};

// Temayı dışa aktar
const exportTheme = (themeName) => {
const theme = savedThemes[themeName];
if (!theme) return;

// JSON olarak dışa aktar
const dataStr = JSON.stringify(theme, null, 2);
const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);

// İndirme bağlantısı oluştur
const exportFileDefaultName = `${themeName}.json`;
const linkElement = document.createElement('a');
linkElement.setAttribute('href', dataUri);
linkElement.setAttribute('download', exportFileDefaultName);
linkElement.click();
};

// Tema içe aktar
const importTheme = (event) => {
const file = event.target.files[0];
if (!file) return;

const reader = new FileReader();
reader.onload = (e) => {
try {
const theme = JSON.parse(e.target.result);
const themeName = file.name.replace('.json', '');

// Temayı kaydet
handleThemeCreate(themeName, theme);

} catch (error) {
console.error('Tema içe aktarma hatası:', error);
alert('Geçersiz tema dosyası!');
}
};
reader.readAsText(file);
};

return (
<div className="theme-manager">
<h2>Tema Yöneticisi</h2>

{/* Tema Oluşturucu */}
<ThemeBuilder onThemeCreate={handleThemeCreate} />

{/* Kayıtlı Temalar */}
<div className="saved-themes">
<h3>Kayıtlı Temalarım</h3>
{Object.keys(savedThemes).length === 0 ? (
<p>Henüz kaydedilmiş tema bulunmuyor.</p>
) : (
<ul>
{Object.keys(savedThemes).map(themeName => (
<li key={themeName}>
<span>{themeName}</span>
<div className="theme-actions">
<button onClick={() => themeRegistry.setCurrentTheme(themeName)}>
Kullan
</button>
<button onClick={() => exportTheme(themeName)}>
Dışa Aktar
</button>
<button onClick={() => handleThemeDelete(themeName)}>
Sil
</button>
</div>
</li>
))}
</ul>
)}
</div>

{/* Tema İçe Aktarma */}
<div className="import-theme">
<h3>Tema İçe Aktar</h3>
<input
type="file"
accept=".json"
onChange={importTheme}
/>
<p>JSON formatında tema dosyası yükleyin.</p>
</div>
</div>
);
};

export default ThemeManager;

Özelleştirme İçin En İyi Uygulamalar

  1. Tema Yapısını Tutarlı Tutun: Yeni temalar oluştururken veya mevcut temaları genişletirken, temel tema yapısına sadık kalın.
  2. Varsayılan Değerler Sağlayın: Özelleştirilebilir temaların eksik değerlerde sorun yaşamaması için varsayılan değerler belirleyin.
  3. Erişilebilirlik İçin Kontrol Edin: Özelleştirilmiş renklerin erişilebilirlik standartlarına uygun olduğundan emin olun.
  4. Performansı Gözetin: Çok fazla dinamik hesaplama yapmaktan kaçının, özellikle tema geçişlerinde.
  5. Kullanıcı Tercihlerini Saklayın: Kullanıcıların özelleştirmelerini kalıcı olarak saklamak için localStorage veya veritabanı kullanın.