Menerapkan Mode Gelap Dalam Aplikasi Bereaksi Menggunakan komponen gaya
Diterbitkan: 2022-03-10Salah satu fitur perangkat lunak yang paling sering diminta adalah mode gelap (atau mode malam, sebagaimana orang lain menyebutnya). Kami melihat mode gelap di aplikasi yang kami gunakan setiap hari. Dari aplikasi seluler hingga web, mode gelap telah menjadi vital bagi perusahaan yang ingin menjaga mata penggunanya.
Mode gelap adalah fitur tambahan yang menampilkan sebagian besar permukaan gelap di UI. Sebagian besar perusahaan besar (seperti YouTube, Twitter, dan Netflix) telah mengadopsi mode gelap di aplikasi seluler dan web mereka.
Meskipun kita tidak akan membahas React dan komponen gaya secara mendalam, pengetahuan dasar tentang React, CSS, dan komponen gaya akan berguna. Tutorial ini akan bermanfaat bagi mereka yang ingin meningkatkan aplikasi web mereka dengan melayani mereka yang menyukai mode gelap.
Beberapa hari sebelum artikel ini ditulis, StackOverflow mengumumkan peluncuran mode gelapnya, yang memberi pengguna kesempatan untuk beralih di antara dua mode tersebut.
Mode gelap mengurangi ketegangan mata dan membantu saat Anda bekerja dalam waktu lama di komputer atau ponsel.
Apa itu Mode Gelap?
Mode gelap adalah skema warna antarmuka apa pun yang menampilkan teks terang dan elemen antarmuka pada latar belakang gelap, yang membuat layar sedikit lebih mudah dilihat di ponsel, tablet, dan komputer. Mode gelap mengurangi cahaya yang dipancarkan oleh layar, sambil mempertahankan rasio kontras warna minimum yang diperlukan untuk keterbacaan.
Mengapa Anda Harus Peduli Dengan Mode Gelap?
Mode gelap meningkatkan ergonomi visual dengan mengurangi ketegangan mata, menyesuaikan layar dengan kondisi cahaya saat ini, dan memberikan kemudahan penggunaan di malam hari atau di lingkungan yang gelap.
Sebelum menerapkan mode gelap di aplikasi kita, mari kita lihat manfaatnya.
Penghematan Baterai
Mode gelap di web dan aplikasi seluler dapat memperpanjang masa pakai baterai perangkat. Google telah mengkonfirmasi bahwa mode gelap pada layar OLED telah sangat membantu masa pakai baterai.
Misalnya, pada kecerahan 50%, mode gelap di aplikasi YouTube menghemat energi layar sekitar 15% lebih banyak daripada latar belakang putih datar. Pada kecerahan layar 100%, antarmuka gelap menghemat 60% energi layar.
Mode Gelap Itu Indah
Mode gelap itu indah, dan dapat meningkatkan daya tarik layar secara signifikan.
Sementara sebagian besar produk menginginkan tampilan putih lembut yang serupa, mode gelap menawarkan sesuatu yang berbeda yang terasa misterius dan baru.
Ini juga memberikan peluang besar untuk menyajikan konten grafis seperti dasbor, gambar, dan foto dengan cara yang segar.
Sekarang setelah Anda tahu mengapa Anda harus menerapkan mode gelap di aplikasi web berikutnya, mari selami komponen gaya, yang merupakan sumber daya penentu dari tutorial ini.
Mode gelap adalah skema warna antarmuka apa pun yang menampilkan teks terang dan elemen antarmuka pada latar belakang gelap, yang membuatnya sedikit lebih mudah dilihat di ponsel, tablet, dan komputer.
“
Apa itu komponen gaya?
Sepanjang artikel ini, kita akan sering menggunakan perpustakaan komponen gaya. Selalu ada banyak cara untuk mendesain aplikasi web modern. Ada metode penataan gaya tradisional di tingkat dokumen, yang mencakup pembuatan file index.css
dan menautkannya ke HTML atau penataan gaya di dalam file HTML.
Banyak yang telah berubah dalam gaya aplikasi web baru-baru ini, sejak diperkenalkannya CSS-in-JS.
CSS-in-JS mengacu pada pola di mana CSS disusun menggunakan JavaScript. Ini menggunakan literal templat yang diberi tag untuk menata komponen dalam file JavaScript.
Untuk mempelajari lebih lanjut tentang CSS-in-JS, lihat artikel Anna Monus tentang masalah ini.
styled-components adalah pustaka CSS-in-JS yang memungkinkan Anda menggunakan semua fitur CSS yang Anda sukai, termasuk kueri media, pemilih semu, dan bersarang.
Mengapa komponen bergaya?
komponen gaya dibuat karena alasan berikut:
- Tidak ada nama kelas sih
Alih-alih Anda menggaruk-garuk kepala untuk menemukan nama kelas untuk sebuah elemen, komponen gaya menghasilkan nama kelas yang unik untuk gaya Anda. Anda tidak perlu khawatir tentang salah eja atau menggunakan nama kelas yang tidak memiliki arti. - Menggunakan alat peraga
styled-components memungkinkan kita untuk memperluas properti styling menggunakan parameterprops
, yang biasa digunakan di React — dengan demikian, secara dinamis memengaruhi nuansa komponen melalui status aplikasi. - Mendukung sintaks Sass
Menulis sintaks Sass di luar kotak tanpa harus menyiapkan praprosesor apa pun atau alat build tambahan dimungkinkan dengan komponen gaya. Dalam definisi gaya Anda, Anda dapat menggunakan karakter&
untuk menargetkan komponen saat ini, menggunakan pemilih semu, dan bereksperimen dengan bersarang. - Bertema
komponen-gaya memiliki dukungan tema penuh dengan mengekspor komponen pembungkusThemeProvider
. Komponen ini menyediakan tema untuk semua komponen React di dalam dirinya sendiri melalui Context API. Di pohon rendering, semua komponen bergaya akan memiliki akses ke tema yang disediakan, bahkan ketika mereka memiliki kedalaman beberapa level. Saat kita melanjutkan tutorial ini, kita akan melihat lebih dalam fitur tema komponen gaya.
Untuk mempelajari lebih lanjut keuntungan dari komponen gaya, lihat artikel Kris Guzman.
Menerapkan Mode Gelap
Pada artikel ini, kita akan menerapkan mode gelap pada halaman web sederhana seperti YouTube.
Untuk mengikuti, pastikan Anda mengkloning repositori asli dari cabang starter
.
Pengaturan
Mari kita instal semua dependensi dalam file package.json
kita. Dari terminal, jalankan perintah berikut:
npm install
Setelah instalasi berhasil, jalankan npm start
. Inilah tampilan halaman web tanpa mode gelap yang diterapkan di dalamnya.
Untuk menginstal styled-components
, di terminal Anda jalankan npm install styled-components
.
Penerapan
Untuk menerapkan mode gelap, kita perlu membuat empat komponen berbeda.
-
Theme
Ini berisi properti warna dari tema terang dan gelap kami. -
GlobalStyles
Ini berisi gaya global untuk seluruh dokumen. -
Toggler
Ini memegang elemen tombol yang mengaktifkan fungsionalitas. -
useDarkMode
Kait khusus ini menangani logika di balik perubahan tema dan persistensi tema kita di penyimpanan lokal.
Komponen Tema
Di folder src
, Anda akan melihat komponen di folder components
. Buat file Themes.js
, dan tambahkan kode berikut ke dalamnya.
export const lightTheme = { body: '#FFF', text: '#363537', toggleBorder: '#FFF', background: '#363537', } export const darkTheme = { body: '#363537', text: '#FAFAFA', toggleBorder: '#6B8096', background: '#999', }
Di sini, kami telah mendefinisikan dan mengekspor objek lightTheme
dan darkTheme
dengan variabel warna yang berbeda. Jangan ragu untuk bereksperimen dan menyesuaikan variabel yang sesuai dengan Anda.
komponen gaya global
Sisa di folder components
Anda, buat file globalStyles.js
, dan tambahkan kode berikut:
import { createGlobalStyle} from "styled-components" export const GlobalStyles = createGlobalStyle` body { background: ${({ theme }) => theme.body}; color: ${({ theme }) => theme.text}; font-family: Tahoma, Helvetica, Arial, Roboto, sans-serif; transition: all 0.50s linear; } `
Kami telah mengimpor createGlobalStyle
dari komponen gaya. Metode createGlobalStyle
menggantikan metode injectGlobal yang sekarang tidak digunakan lagi dari komponen bergaya versi 3. Metode ini menghasilkan komponen React, yang, ketika ditambahkan ke pohon komponen Anda, akan menyuntikkan gaya global ke dalam dokumen, dalam kasus kami, App.js
.
Kami mendefinisikan komponen GlobalStyle
dan menetapkan background
dan properti color
ke nilai dari objek tema. Jadi, setiap kali kita mengganti tombol, nilainya akan berubah tergantung pada tema gelap atau objek tema terang yang kita lewati ke ThemeProvider
(yang akan dibuat nanti, saat kita melanjutkan).
Properti transisi 0.50s
memungkinkan perubahan ini terjadi sedikit lebih lancar, sehingga saat kita beralih bolak-balik, kita dapat melihat perubahan yang terjadi.
Membuat Fungsionalitas Beralih Tema
Untuk mengimplementasikan fungsi alih tema, kita hanya perlu menambahkan beberapa baris kode. Di file App.js
, tambahkan kode berikut (perhatikan bahwa kode yang disorot adalah yang harus Anda tambahkan):
import React, { useState, useEffect } from "react";
import {ThemeProvider} from "styled-components"; import { GlobalStyles } from "./components/Globalstyle"; import { lightTheme, darkTheme } from "./components/Themes"
import "./App.css"; import dummyData from "./data"; import CardList from "./components/CardList"; const App = () => { const [videos, setVideos] = useState([]);
const [theme, setTheme] = useState('light'); const themeToggler = () => { theme === 'light' ? setTheme('dark') : setTheme('light') }
useEffect(() => { const timer = setTimeout(() => { setVideos(dummyData); }, 1000); return () => clearTimeout(timer); }, []); return (
<ThemeProvider theme={theme === 'light' ? lightTheme : darkTheme}> <> <GlobalStyles/>
<div className="App">
<button onClick={themeToggler}>Switch Theme</button>
{ videos.map((list, index) => { return ( <section key={index}> <h2 className="section-title">{list.section}</h2> <CardList list={list} /> <hr /> </section> ); })} </div>
</> </ThemeProvider>
); }; export default App;
Kode yang disorot adalah yang baru ditambahkan ke App.js
. Kami telah mengimpor ThemeProvider
dari styled-components
. ThemeProvider
adalah komponen pembantu di perpustakaan komponen gaya yang menyediakan dukungan tema. Komponen pembantu ini menyuntikkan tema ke semua komponen Bereaksi di bawahnya sendiri melalui API Konteks.
Di pohon rendering, semua komponen bergaya akan memiliki akses ke tema yang disediakan, bahkan ketika mereka memiliki kedalaman beberapa level. Lihat bagian tentang "Tema".
Selanjutnya, kita mengimpor pembungkus GlobalStyle
dari ./components/Globalstyle
. Terakhir, dari atas, kita mengimpor objek lightTheme
dan darkTheme
dari ./components/Themes
.
Agar kita dapat membuat metode toggling, kita memerlukan status yang menyimpan nilai warna awal tema kita. Jadi, kita membuat status theme
, dan menyetel status awal ke light
, menggunakan kait useState
.
Sekarang, untuk fungsi toggling.
Metode themeToggler
menggunakan operator ternary untuk memeriksa status theme
, dan mengubah gelap atau terang berdasarkan nilai kondisinya.
ThemeProvider
, komponen pembantu komponen gaya, membungkus semuanya dalam pernyataan return
dan menyuntikkan komponen apa pun di bawahnya. Ingatlah bahwa GlobalStyles
kami menyuntikkan gaya global ke dalam komponen kami; karenanya, ini disebut di dalam komponen pembungkus ThemeProvider
.
Terakhir, kami membuat tombol dengan acara onClick
yang menetapkan metode themeToggler
kami untuk itu.
Mari kita lihat hasilnya sejauh ini.
File App.js
kami perlu difaktorkan ulang; banyak kode nya tidak KERING. (DRY adalah singkatan dari "jangan ulangi diri Anda sendiri", prinsip dasar pengembangan perangkat lunak yang bertujuan untuk mengurangi pengulangan.) Semua logika tampaknya ada di App.js
; itu praktik yang baik untuk memisahkan logika kita demi kejelasan. Jadi, kita akan membuat komponen yang menangani fungsi toggling.
Beralih Komponen
Masih di dalam folder components
, buat file Toggler.js
, dan tambahkan kode berikut ke dalamnya:
import React from 'react' import { func, string } from 'prop-types'; import styled from "styled-components" const Button = styled.button` background: ${({ theme }) => theme.background}; border: 2px solid ${({ theme }) => theme.toggleBorder}; color: ${({ theme }) => theme.text}; border-radius: 30px; cursor: pointer; font-size:0.8rem; padding: 0.6rem; } \`; const Toggle = ({theme, toggleTheme }) => { return ( <Button onClick={toggleTheme} > Switch Theme </Button> ); }; Toggle.propTypes = { theme: string.isRequired, toggleTheme: func.isRequired, } export default Toggle;
Untuk menjaga semuanya tetap rapi, kami telah mengatur gaya tombol sakelar kami di komponen Toggle
, menggunakan fungsi styled
dari komponen gaya.
Ini murni untuk presentasi; Anda dapat menata tombol sesuai keinginan Anda.
Di dalam komponen Toggle
, kita melewati dua props:
-
theme
menyediakan tema saat ini (terang atau gelap); - fungsi
toggleTheme
akan digunakan untuk beralih antar tema.
Selanjutnya, kita mengembalikan komponen Button
dan menetapkan fungsi toggleTheme
ke event onClick
.
Terakhir, kami menggunakan propTypes
untuk mendefinisikan tipe kami, memastikan bahwa theme
kami adalah string
dan isRequired
, sementara toggleTheme
kami adalah func
dan isRequired
.
Menggunakan Kait Kustom ( useDarkMode
)
Saat membangun aplikasi, skalabilitas adalah yang terpenting, artinya logika bisnis kita harus dapat digunakan kembali, sehingga kita dapat menggunakannya di banyak tempat dan bahkan di proyek yang berbeda.
Itulah mengapa akan sangat bagus untuk memindahkan fungsi toggling kami ke komponen yang terpisah. Untuk itu, kami akan membuat kait khusus kami sendiri.
Mari buat file baru bernama useDarkMode.js
di folder components
, dan pindahkan logika kita ke file ini, dengan beberapa penyesuaian. Tambahkan kode berikut ke file:
import { useEffect, useState } from 'react'; export const useDarkMode = () => { const [theme, setTheme] = useState('light'); const setMode = mode => { window.localStorage.setItem('theme', mode) setTheme(mode) }; const themeToggler = () => { theme === 'light' ? setMode('dark') : setMode('light') }; useEffect(() => { const localTheme = window.localStorage.getItem('theme'); localTheme && setTheme(localTheme) }, []); return [theme, themeToggler] };
Kami telah menambahkan beberapa hal di sini.
-
setMode
Kami menggunakanlocalStorage
untuk bertahan di antara sesi di browser. Jadi, jika pengguna telah memilih tema gelap atau terang, itulah yang akan mereka dapatkan pada kunjungan berikutnya ke aplikasi atau jika mereka memuat ulang halaman. Oleh karena itu, fungsi ini menetapkan status kita dan meneruskantheme
kelocalStorage
. -
themeToggler
Fungsi ini menggunakan operator ternary untuk memeriksa status tema dan beralih baik gelap atau terang berdasarkan kebenaran kondisi tersebut. -
useEffect
Kami telah menerapkan kaituseEffect
untuk memeriksa pemasangan komponen. Jika pengguna telah memilih tema sebelumnya, kami akan meneruskannya ke fungsisetTheme
kami. Pada akhirnya, kami akan mengembalikantheme
kami, yang berisitheme
yang dipilih dan fungsithemeToggler
untuk beralih antar mode.
Saya pikir Anda akan setuju bahwa komponen mode gelap kami terlihat ramping.
Mari menuju ke App.js
untuk sentuhan akhir.
import React, { useState, useEffect } from "react"; import {ThemeProvider} from "styled-components";
import {useDarkMode} from "./components/useDarkMode"
import { GlobalStyles } from "./components/Globalstyle"; import { lightTheme, darkTheme } from "./components/Themes" import Toggle from "./components/Toggler" import "./App.css"; import dummyData from "./data"; import CardList from "./components/CardList"; const App = () => { const [videos, setVideos] = useState([]);
const [theme, themeToggler] = useDarkMode(); const themeMode = theme === 'light' ? lightTheme : darkTheme;
useEffect(() => { const timer = setTimeout(() => { setVideos(dummyData); }, 1000); return () => clearTimeout(timer); }, []); return (
<ThemeProvider theme={themeMode}>
<> <GlobalStyles/> <div className="App">
<Toggle theme={theme} toggleTheme={themeToggler} />
{ videos.map((list, index) => { return ( <section key={index}> <h2 className="section-title">{list.section}</h2> <CardList list={list} /> <hr /> </section> ); })} </div> </> </ThemeProvider> ); }; export default App;
Kode yang disorot baru ditambahkan ke App.js
.
Pertama, kami mengimpor kait khusus kami, merusak struktur theme
dan alat peraga themeToggler
, dan mengaturnya dengan fungsi useDarkMode
.
Perhatikan bahwa metode useDarkMode
menggantikan status theme
kita, yang awalnya ada di App.js
.
Kami mendeklarasikan variabel themeMode
, yang merender tema terang atau gelap berdasarkan kondisi mode theme
saat itu.
Sekarang, komponen pembungkus ThemeProvider
kita diberikan variabel themeMode
yang baru saja kita buat ke prop theme
.
Dan terakhir, sebagai ganti tombol biasa, kami memasukkan komponen Toggle
.
Ingat bahwa dalam komponen Toggle
kami, kami mendefinisikan dan menata tombol dan meneruskan theme
dan toggleTheme
kepada mereka sebagai alat peraga. Jadi, yang harus kita lakukan adalah meneruskan props ini dengan tepat ke komponen Toggle
, yang akan bertindak sebagai tombol kita di App.js
.
Ya! Mode gelap kami disetel, dan tetap ada, tidak berubah warna saat halaman disegarkan atau dikunjungi di tab baru.
Mari kita lihat hasilnya dalam aksi:
Hampir semuanya bekerja dengan baik, tetapi ada satu hal kecil yang dapat kita lakukan untuk membuat pengalaman kita luar biasa. Beralih ke tema gelap lalu muat ulang halaman. Apakah Anda melihat bahwa warna biru pada tombol dimuat sebelum abu-abu untuk sesaat? Itu terjadi karena kait useState
kami memulai tema light
pada awalnya. Setelah itu, useEffect
berjalan, periksa localStorage
, dan baru kemudian setel theme
ke dark
. Mari lompat ke kait khusus useDarkMode.js
dan tambahkan sedikit kode:
import { useEffect, useState } from 'react'; export const useDarkMode = () => { const [theme, setTheme] = useState('light');
const [mountedComponent, setMountedComponent] = useState(false)
const setMode = mode => { window.localStorage.setItem('theme', mode) setTheme(mode) }; const themeToggler = () => { theme === 'light' ? setMode('dark') : setMode('light') }; useEffect(() => { const localTheme = window.localStorage.getItem('theme'); localTheme ? setTheme(localTheme) : setMode('light')
setMountedComponent(true)
}, []); return [theme, themeToggler,
}, []); return [theme, themeToggler,
mountedComponent
]
};
Kode yang disorot adalah satu-satunya yang ditambahkan ke useDarkMode.js
. Kami telah membuat status lain bernama mountedComponent
dan menyetel nilai default ke false
menggunakan kait useState
. Selanjutnya, di dalam kait useEffect
, kami mengatur status mountedComponent
menjadi true
menggunakan setMountedComponent
. Terakhir, dalam array return
, kami menyertakan status mountedComponent
.
Terakhir, mari tambahkan sedikit kode di App.js
agar semuanya berfungsi.
import React, { useState, useEffect } from "react"; import {ThemeProvider} from "styled-components"; import {useDarkMode} from "./components/useDarkMode" import { GlobalStyles } from "./components/Globalstyle"; import { lightTheme, darkTheme } from "./components/Themes" import Toggle from "./components/Toggler" import "./App.css"; import dummyData from "./data"; import CardList from "./components/CardList"; const App = () => { const [videos, setVideos] = useState([]);
const [theme, themeToggler, mountedComponent] = useDarkMode();
const themeMode = theme === 'light' ? lightTheme : darkTheme; useEffect(() => { const timer = setTimeout(() => { setVideos(dummyData); }, 1000); return () => clearTimeout(timer); }, []);
if(!mountedComponent) return <div/>
return ( <ThemeProvider theme={themeMode}> <> <GlobalStyles/> <div className="App"> <Toggle theme={theme} toggleTheme={themeToggler} /> { videos.map((list, index) => { return ( <section key={index}> <h2 className="section-title">{list.section}</h2> <CardList list={list} /> <hr /> </section> ); })} </div> </> </ThemeProvider> ); }; export default App;
Kami telah menambahkan status mountedComponent
kami sebagai penyangga di kait useDarkMode
kami, dan kami telah memeriksa apakah komponen kami telah dipasang, karena inilah yang terjadi di kait useEffect
. Jika belum terjadi, maka kita akan membuat div
kosong.
Mari kita lihat hasil halaman web mode gelap kita.
Sekarang, Anda akan melihat bahwa saat dalam mode gelap, saat halaman dimuat ulang, warna tombol tidak berubah.
Kesimpulan
Mode gelap semakin menjadi preferensi pengguna, dan mengimplementasikannya dalam aplikasi web React jauh lebih mudah saat menggunakan pembungkus tema ThemeProvider
di komponen bergaya. Silakan bereksperimen dengan komponen gaya saat Anda menerapkan mode gelap; Anda dapat menambahkan ikon alih-alih tombol.
Silakan bagikan umpan balik dan pengalaman Anda dengan fitur tema dalam komponen bergaya di bagian komentar di bawah. Saya ingin melihat apa yang Anda dapatkan!
Repositori pendukung untuk artikel ini tersedia di GitHub. Juga, periksa di CodeSandbox.
Referensi
- "Dokumentasi", komponen gaya
- “Buat Mode Gelap aplikasi Anda menggunakan Komponen Bergaya”, Tom Nolan, Medium