AntDesign
Ant Design en popüler react ui araçlarından biridir. Bu kadar popüler olmasının en büyük sebebi de geniş bir araç kiti olması ve çeşitli gösterge panellerinin kolaylıkla projeye dahil edilmesi olarak düşünüyorum (antdesign-vision).
Not: Çok fazla uzatmıyorum çünkü antdesign ile alakalı ayrıca birkaç yazı yazmayı planlıyorum.
Problemimiz nedir?
Antdesign kendi komponentlerinde karanlık temayı bulunduran bir kit aslında. CSS stil dosyalarını Less stiline çeviriyor. React.js’de bunu yapmak için CSS dosyalarını derlemek ve ardından yapıya eklemek için gerekiyor. Bunun için de webpackten destek alıyoruz. Ancak bu işlem sonucunda da değiştiremeyeceğimiz anlamına geliyor.
Örnek Ufak Çözüm
Bu soruna karşı bir sürü kitaplık mevcut örneğin: react-app-rewire-antd-theme. Bu, less dosyasına doğrudan HTML'de değiştirilecek renkleri enjekte eder ve çalışma zamanında stilleri yeni değişkenlerle yeniden derlemek için
window.modifyVars
'ı kullanır. Bu, az sayıda değişkenle işe yarayabilir, ancak karanlık bir tema için yüzlerce değişken için bu mümkün değildir. Kullanıcının performansını öldürecektir.Çözüm
JoseRFelix bu konuda birçok deneme yapmış ve sonunda yılıp kendi dark mode kitaplığını yapmış.
Projesine aşağıdan ulaşabilirsiniz 👇
En büyük sıkıntılar derleme süresi, kullanıcının bilgisayarını yorması ve yapılan değişiklikleri gösteremesiydi. Ancak çözüm sayesinde sistem hiç yorulmadan basit bir şekilde halloluyor.
Less Dosyalarmızı oluşturalım
Yapmamız gereken ilk şey, AntD stillerini içerecek olan Less stil sayfalarını oluşturmak. Bunu başarmak için, her tema için ihtiyacımız olan değişkenleri ve stilleri içe aktarmamız yeterlidir.
Temanın Dosya Yapısı
Dosya düzenimiz soldaki gibi olacaktır. Bir
themes
klasörü oluşturun ve içine aşağıdaki less dosyalarını ekleyin.light tema için:
// light-theme.less @import '~antd/lib/style/color/colorPalette.less'; @import '~antd/dist/antd.less'; @import '~antd/lib/style/themes/default.less'; @primary-color: #00adb5; @border-radius-base: 4px;
dark tema için;
// dark-theme.less @import '~antd/lib/style/color/colorPalette.less'; @import '~antd/dist/antd.less'; @import '~antd/lib/style/themes/dark.less'; @primary-color: #00adb5; @border-radius-base: 4px; @component-background: #303030; @body-background: #303030; @popover-background: #303030; @border-color-base: #6f6c6c; @border-color-split: #424242; @table-header-sort-active-bg: #424242; @card-skeleton-bg: #424242; @skeleton-color: #424242; @table-header-sort-active-bg: #424242;
Gulp.js ile kontrol sende 💪
Tabi less dosyalarımızı yaptık ancak bunu derlemezsek hiçbir değişim göremeyiz. Webpack’ten yardım alabiliriz ancak en ufak değişiklikte bile yeniden derlemesi sistemi yorduğu için biz gulp kullanacağız. Gulp.js, tekrar eden işlerinizi tanımlamak ve çalıştırmak için kullanılır. Basit ve etkili bir javascript kütüphanesidir.
Dosyayı küçültmek, postcss kullanmak ve içe aktarmaları çözmek ve Gulp.js kurmak için aşağıdaki kodu çalıştırın (npm veya yarn hangisiniyle isterseniz kurun);
npm add -D gulp gulp-less gulp-postcss gulp-debug gulp-csso autoprefixer less-plugin-npm-import
Ve ana dizine bir
gulpfile.js
oluşturun:const gulp = require('gulp') const gulpless = require('gulp-less') const postcss = require('gulp-postcss') const debug = require('gulp-debug') var csso = require('gulp-csso') const autoprefixer = require('autoprefixer') const NpmImportPlugin = require('less-plugin-npm-import') gulp.task('less', function () { const plugins = [autoprefixer()] return gulp .src('src/themes/*-theme.less') .pipe(debug({title: 'Less files:'})) .pipe( gulpless({ javascriptEnabled: true, plugins: [new NpmImportPlugin({prefix: '~'})], }), ) .pipe(postcss(plugins)) .pipe( csso({ debug: true, }), ) .pipe(gulp.dest('./public')) })
İşlemler bittikten sonra terminale
npx gulp less
yazdığınızda css dosyalarınız derlenecek ve otomatik olarak public klasörüne, css çıktısı eklenecektir.Temalar Arası Geçiş
JoseRFelix hazırladığı npm paketini yüklemek için terminale alttaki kodu çalıştırın.
Ardından
index.js
bulunan kısımda ThemeSwitcherProvider
ile sarmalarız.Bu ayar ile mevcut ayarlarınız index dosyasında kalacak ve saklanacaktır.Peki Kalıcı Temayı Nasıl sağlayacağız?
Burada bir ufak sorunu nasıl çözdüğümü anlatmam gerekiyor. React kullanırken temanın karanlık veya aydınlık olduğunu useState kullanarak tutabilirsiniz. Ancak kullanıcı F5 yaptığında bu değişiklik gidecektir. Temanın default değeri olan aydınlık (light-theme.css) stil dosyası aktif olacaktır. Bu can sıkıcı durum aslında 👉
localStorage
ile basitçe çözülebilir. Bu sayede kişi tarayıcıdan bile çıksa tema kalıcı olarak kullanıcı tarafında çerez olarak tutulacaktır. Dosya yapılanmasına geçersek;index.js:
import React from "react"; import ReactDOM from "react-dom"; import "./index.css"; import App from "./App"; import { ThemeSwitcherProvider } from "react-css-theme-switcher"; const themes = { dark: `${process.env.PUBLIC_URL}/dark-theme.css`, light: `${process.env.PUBLIC_URL}/light-theme.css`, }; if (!localStorage.getItem("theme")) { localStorage.setItem("theme", "dark"); } ReactDOM.render( <React.StrictMode> <ThemeSwitcherProvider themeMap={themes} defaultTheme={localStorage.getItem("theme")} insertionPoint={document.getElementById("inject-styles-here")} > <App /> </ThemeSwitcherProvider> </React.StrictMode>, document.getElementById("root") );
getItem”theme”.. kısmında yazdığımız kod ile var olan temanın değerini almaya yoksa setItem ile temanın değerini ekliyoruz.
defaultTheme
kısmında ise setItem yaptığımız temayı geri getiriyoruz.App.js:
import React from "react"; import { useThemeSwitcher } from "react-css-theme-switcher"; import "./App.css"; import SwitchButton from "./components/switchButton"; function App() { const { currentTheme } = useThemeSwitcher(); return ( <div className="main fade-in"> <h1>The current theme is {currentTheme}</h1> <SwitchButton /> </div> ); } export default App;
Temayı değiştirmek için kullandığımız switch için direk komponent yazdım. direk SwitchButton kısmını ekleyerek projenizde çalıştırabilirsiniz.
SwitchButton.jsx:
import { Switch } from "antd"; import React from "react"; import { useThemeSwitcher } from "react-css-theme-switcher"; import darkLogo from "../themes/dark-icon.svg"; import lightLogo from "../themes/light-icon.svg"; export default function SwitchButton() { const { switcher, status, themes } = useThemeSwitcher(); const toggleTheme = (isChecked) => { switcher({ theme: isChecked ? themes.dark : themes.light }); if (isChecked) { localStorage.setItem("theme", "dark"); } else { localStorage.setItem("theme", "light"); } }; if (status === "loading") { return null; } return ( <Switch size="large" checked={localStorage.getItem("theme") === "dark" ? true : false} onChange={toggleTheme} checkedChildren={<img id="lightLogo" src={lightLogo} alt="light" />} unCheckedChildren={<img id="darkLogo" src={darkLogo} alt="dark" />} /> ); }
Sonuç
Evet yazımız burada son burada son bulurken projenin Github kodunu da paylaşalım. Bu sayede takıldığınız yerde oradan kontrol edebilirsiniz. 👉 antd-dynamic-theme-switch
Okuduğunuz için teşekkür ederim. Unutmadan demo linkini de alta ekliyorum oradan da test edebilirsiniz. 👇
Demo 🥳