Introdução as tecnologias
NextJS
- NextJS é um framework React com o intuito de SSR (Server Side Rendering).
Styled-components
- Styled-components é uma biblioteca para React que permite a escrita de CSS in JS.
Vamos começar!
Criando a aplicação
- Para criar a aplicação iremos rodar o comando
yarn create next-app <nome do projeto>
, após executar esse comando ele irá começar a criar o seu projeto NextJs (pode demorar um pouquinho).
Estruturando a aplicação
- Eu divido a minha estrutura do NextJS criando uma pasta
src
e colocando as minhas pastas e arquivos lá, apenas deixando a pastapublic
de fora, mas isso vai de acordo com o seu gosto!
Configurando o Typescript
- Para configurar o Typescript no projeto é bem simples, iremos adicioná-lo como dependência de desenvolvimento no projeto
yarn add typescript -D
- Agora iremos criar o arquivo
tsconfig.json
, no seu terminal escrevatouch tsconfig.json
- Iremos modificar o nome das nossas páginas dentro de
src/pages
removendo a extensão.js
e adicionando.tsx
- E se tudo deu certo
pelo menos eu espero que sim, podemos rodaryarn dev
no nosso terminal e abrirá a página do NextJS na porta:3000
Configurando o Styled-components
- Vamos começar adicionado o styled-components no projeto, portanto escreve no seu terminal
yarn add styled-components
-
Iremos criar um arquivo chamado
_document.tsx
dentro desrc/pages
, nele haverá o seguinte conteúdo. Isso é para as injeções de estilo no server side rendering.
import Document, { DocumentContext } from 'next/document'; import { ServerStyleSheet } from 'styled-components'; export default class MyDocument extends Document { static async getInitialProps(ctx: DocumentContext) { const sheet = new ServerStyleSheet(); const originalRenderPage = ctx.renderPage; try { ctx.renderPage = () => originalRenderPage({ enhanceApp: App => props => sheet.collectStyles(<App {...props} />), }); const initialProps = await Document.getInitialProps(ctx); return { ...initialProps, styles: ( <> {initialProps.styles} {sheet.getStyleElement()} </> ), }; } finally { sheet.seal(); } } }
-
Dentro da nossa pasta
src/styles
vamos criar o arquivostyled.d.ts
para sobrescrevermos os tipos do styled-components.
import 'styled-components'; declare module 'styled-components' { export interface DefaultTheme { title: string; colors: { primary: string; secundary: string; background: string; text: string; }; fontSizes: { small: string; medium: string; large: string; }; } export interface CustomTheme { title: string; colors: { primary: string; secundary: string; background: string; text: string; }; } }
-
Dentro no nosso arquivo tsconfig.json vamos adicionar o seguinte atributo.
.... "files": [ "src/styles/styled.d.ts" ]
-
Vamos rapidinho criar um estilo global para a aplicação, crie o arquivo global.ts dentro de
src/styles
import { createGlobalStyle } from 'styled-components'; export default createGlobalStyle` * { margin: 0; padding: 0; box-sizing: border-box; outline: 0; } body { background: #fff; color: black; } h1, h2, h3, h4, h5, h6, strong { font-weight: 700; } button { cursor: pointer; } `;
-
Agora vamos importá-lo no arquivo
index.tsx
, delete os arquivos de estilo.css
do projeto também!
import GlobalStyles from '../styles/global'; export default function Home() { return ( <> <GlobalStyles /> </> ); }
Criando os temas
- Vamos criar os temas agora! Dentro da pasta
src/styles
vamos criar uma pastathemes
e nela um arquivo dark.ts (para o dark mode) o arquivo light.ts para o (light modejura?) e um arquivo index.ts. -
O arquivo
dark.ts
terá as seguintes cores (isso você decide de acordo com o seu design)
export default { title: 'dark', colors: { primary: '#161616', secundary: '#555', background: '#333', text: '#fff', }, };
-
O arquivo
light.ts
terá as seguintes cores
export default { title: 'light', colors: { primary: '#666', secundary: '#777', background: '#fff', text: '#333', }, };
-
O arquivo
index.ts
será responsável por misturar as cores de cada tema com o que seria comum entre os dois, exemplo: tamanho de fonte.
import { DefaultTheme, CustomTheme } from 'styled-components'; import dark from './dark'; import light from './light'; const defaultTheme = { fontSizes: { small: '16px', medium: '18px', large: '20px', }, }; function combineTheme(theme: CustomTheme): DefaultTheme { return { ...defaultTheme, ...theme }; } export { combineTheme, dark, light };
Aplicando os temas!
-
Agora que já criamos nossos temas vamos importá-los e fazer as trocas dinâmicas de temas, em
src/pages
vamos fazer algumas alterações no nossoindex.tsx
, mas antes vamos adicionar um componente de switch para ficar mais estiloso já que estamos falando de temas, portanto, escreveyarn add react-switch
no seu terminal
import React, { useState } from 'react'; import { DefaultTheme, ThemeProvider } from 'styled-components'; import Switch from 'react-switch'; import { combineTheme, dark, light } from '../styles/themes'; import GlobalStyles from '../styles/global'; const Home: React.FC = () => { const [theme, setTheme] = useState<DefaultTheme>(combineTheme(light)); const toggleTheme = () => { setTheme(theme.title === 'light' ? combineTheme(dark) : combineTheme(light)); }; return ( <ThemeProvider theme={theme}> <GlobalStyles /> <Switch checked={theme.title === 'dark'} onChange={toggleTheme} /> </ThemeProvider> ); }; export default Home;
-
Agora vamos em
src/styles
no nosso arquivoglobal.ts
e vamos fazer as seguintes alterações!
import { createGlobalStyle } from 'styled-components'; export default createGlobalStyle` * { margin: 0; padding: 0; box-sizing: border-box; outline: 0; } body { background: ${props => props.theme.colors.background}; color: ${props => props.theme.colors.text}; font-size: ${props => props.theme.fontSizes.small} } h1, h2, h3, h4, h5, h6, strong { font-weight: 700; } button { cursor: pointer; } `;
E pronto!!! O resultado final ficará assim
Top comments (6)
Para persistir a categoria de tema, deixar salvo no localStorage.
const toggleTheme = () => {
if (theme.title === 'light') {
setTheme(combineTheme(dark))
localStorage.setItem('theme', 'dark')
}
if (theme.title === 'dark') {
setTheme(combineTheme(light))
localStorage.setItem('theme', 'light')
}
}
useEffect(() => {
function checkTheme() {
const typeTheme = localStorage.getItem('theme')
if (typeTheme != 'light') {
setTheme(combineTheme(dark))
}
if (typeTheme != 'dark') {
setTheme(combineTheme(light))
}
}
está bem basico, mas assim que puder eu atualizo.
Pra quem quiser persistir é só usar cookies, que funcionam da mesma forma que o localstorage
Cara, interessante, mas ai nao ta persistindo o dado no localStorage, logo, nao tem utilidade. Estou tentando a alguns dias fazer isso no next, mas travei.
Fui ver isso somente hoje, me perdoe, tem como vc persistir o tema no localStorage sim, na função do toggle vc pode colocar a lógica lá e salvar. Caso ainda precise de ajuda comente aqui de novo que eu ajudo sim!
Mano vc não tem noção do quanto me ajudou! Muito Obrigadoo!
Tamo junto demais!!!!