Vite Setup com Styled-Components - Part 4


Esse daqui se você quiser dar skip, pode, eu só vou fazer porque prefiro muito mais styled components a outras coisas como Tailwind…(please don’t!). Para começar vamos só adicionar ao nosso projeto o styled-components.

  yarn add styled-components && yarn add @types/styled-components -D

Vamos criar uma pasta da raiz de src chamada styles e vamos adicionar dois arquivos: O resets.ts e o theme.ts.

└── styles
  └── resets.ts
  └── theme.ts

No reset teremos esses estilos aqui que deixarão resetados algumas coisas que de fato serão a base para o nosso css.

resets.ts:

import { createGlobalStyle } from "styled-components";

const ResetStyles = createGlobalStyle`


 html,
 body {
   padding: 0;
   margin: 0;
   font-family: 'Playfair Display', serif;
   background-color:  #f6f6f0;
 }


 a {
   color: inherit;
   text-decoration: none;
 }


 * {
   box-sizing: border-box;
 }


`;

export default ResetStyles;

E no arquivo de theme vamos deixar dessa forma:

export default {
  colors: {
    primary: "tomato",
  },
  spacings: {
    small: "1rem",
    medium: "2rem",
    large: "3rem",
  },
};

Na nossa main vamos precisar chamar o Provider do StyledComponent para que todo o nosso projeto possa receber/ter acesso ao arquivo de theme que criamos:

import React from "react";
import ReactDOM from "react-dom/client";
import { ThemeProvider } from "styled-components";

import ResetStyles from "styles/reset";
import theme from "styles/theme";

import App from "./App";

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <ResetStyles />
      <App />
    </ThemeProvider>
  </React.StrictMode>
);

Depois disso, vamos criar um outro folder na raiz de src chamado types, onde iremos declarar os tipos para poderem ser vistos e acessados em todo o nosso projeto e nele declarar o seguinte tipo: styled-components.d.ts

└── types
  └── styled-components.d.ts
import theme from "styles/theme";

type Theme = typeof theme;

declare module "styled-components" {
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
  export interface DefaultTheme extends Theme {}
}

Após isso nós iremos criar um component chamado Content que será usado somente para dar ao nosso App.js algumas zonas de respiro com alguns paddings. E vamos ter apenas dois files dentro do nosso component:

└── components
  └── Content
    └── index.tsx
    └── styles.tsx

styles.tsx:

import styled, { css } from "styled-components";

export const Wrapper = styled.main`
  ${({ theme }) => css`
    padding: ${theme.spacings.small};
  `};
`;

se você olhar bem, theme está sendo passado pelo nosso provider e sendo recebido no nosso wrapper e assim garantimos o valor do nosso padding.

index.tsx:

import * as S from "./styles";

export const Content = ({ children }: { children: React.ReactNode }) => {
  return <S.Wrapper className="content">{children}</S.Wrapper>;
};

No nosso Counter component iremos fazer outras novas mudanças

styles.tsx:

import styled from "styled-components";

export const Button = styled.button`
  background-color: ${({ theme }) => theme.colors.primary};
  color: white;
  font-size: 1.5rem;
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 0.5rem;
  cursor: pointer;
`;
import { useState } from "react";

import * as S from "./styles";

export const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <S.Button onClick={() => setCount((count) => count + 1)}>
        count is: {count}
      </S.Button>
    </div>
  );
};

E por fim, eu fiz mais algumas mudanças no nosso App.js e ele ficou assim:

import { Content } from "components/Content";
import { Counter } from "components/Counter";

function App() {
  return (
    <Content>
      <Counter />
    </Content>
  );
}

export default App;

Agora, para não quebrar o nosso storybook, precisamos fazer um wrapper dele no preview.cjs, o qual vamos precisar renomear para preview.jsx:

import { ThemeProvider } from "styled-components";

import ResetStyles from "styles/resets";
import theme from "styles/theme";

export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
};

export const decorators = [
  (Story) => (
    <ThemeProvider theme={theme}>
      <ResetStyles />
      <Story />
    </ThemeProvider>
  ),
];

E um último detalhe, no nosso vite config, nós iremos adicionar uma flag para evitar optimziações grandes e desnecessárias ao nosso projeto:

import react from "@vitejs/plugin-react-swc";
import { defineConfig } from "vite";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
  },
  preview: {
    port: 3000,
  },
  resolve: {
    alias: {
      components: `${__dirname}/src/components/`,
      styles: `${__dirname}/src/styles/`,
      types: `${__dirname}/src/types/`,
      utils: `${__dirname}/src/utils/`,
    },
  },
  optimizeDeps: {
    disabled: false,
  },
  define: {
    "process.env": process.env,
    global: "window",
  },
});

E bem, se você rodar agora o seu storybook ele deve ficar assim:

Creio que por hoje é somente isso! Próximo artigo iremos falar sobre Jest.

Até mais!

Github: Vite Setup