Skip to content

Latest commit

 

History

History
424 lines (333 loc) · 8.64 KB

STYLEGUIDE.md

File metadata and controls

424 lines (333 loc) · 8.64 KB

DevHat JavaScript/React Style Guide() {

Reference Style Guide

Sumário:

  1. Regras básicas
  2. Estrutura de componentes
  3. Criando componentes
  4. Exportando arquivos
  5. Custom hooks
  6. Arquivos em PascalCase
  7. Nomeando coisas
  8. Class Component
  9. Estilizando componentes
  10. Tipando componentes
  11. Testes unitários
  12. Alt em imagens
  13. Estruturas de pastas

Regras básicas

  • Um componente por arquivo
  • Evite ao máximo o uso de any nas tipagens
  • Componentes unicamente em TSX
  • Código apenas em inglês

    Por que? Por mais que todos os contribuídores sejam brasileiros é importante padronizarmos todo o código em inglês para evitar uma mistura de inglês e português, algo do tipo "setNome()", um dos principais motivos também é a acessibilidade, muitas ferramentas de tradução automática e leitores de tela são mais eficazes quando lidam com texto em inglês.

Estrutura de componentes

  • Separe a pasta do seu componente em 4 arquivos
    • Componente.tsx (seu componente em si)
    • Componente.spec.tsx (testes do componente)
    • Componente.module.scss (seus estilos)
    • Componente.types.ts (interfaces e types do componente)
├─ components
│  ├─ MyComponent.module.scss
│  └─ MyComponent.spec.tsx
│  └─ MyComponent.tsx
|  └─ MyComponent.types.ts

Criando componentes

Todos os componentes serão criados em funções normais, arrow functions apenas dentro dos componentes

// Bom
function Component(props: IProps) {
	const handleSomething = () => { /* ... */ }
	return ( /* ... */ )
}

// Ruim
const Component = (props: IProps) => {
	const handleSomething = () => { /* ... */ }
	return ( /* ... */ )
}

// Ruim
const Component = (props: IProps) => {
	function handleSomething() { /* ... */ }
	return ( /* ... */ )
}

Exportando arquivos

Iremos usar SEMPRE export default nos componentes

// Bom
function Component(props: IProps) {
	return ( /* ... */ )
}

export default Component

// Ruim
export function Component(props: IProps) {
	return ( /* ... */ )
}

// Ruim
function Component(props: IProps) {
	const handleSomething = () => { /* ... */ }
	return ( /* ... */ )
}

Com excessão dos componentes, não iremos usar export default

// Bom
export interface IProps {
  /* ... */
}

// Ruim
interface IProps {
  /* ... */
}
export default IProps;

Isso também vale para custom hooks

// Bom
export const useHook = () => {
  /* ... */
};

// Ruim
const useHook = () => {
  /* ... */
};
export default useHook;

Custom hooks

Se precisar criar um custom hook, use arrow functions

// Bom
export const useHook = () => {
  /* ... */
};

// Ruim
export function useHook() {
  /* ... */
}

Componentes em PascalCase

Iremos seguir o padrão PascalCase que consiste em nomear todas as palavras com a primeira letra maiúscula.

├─ components
│  ├─ MyComponentHere.tsx

Nomeando coisas

Tirando componentes e interfaces, iremos utilizar camelCase para nomear tudo.

// Bom
const handleSomething = () => {
  /* ... */
};

// Ruim
const HandleSomething = () => {
  /* ... */
};

// Ruim
const handle_something = () => {
  /* ... */
};

Isso Inclue props de componentes

<MyComponent
	isHandsome
	name="hxsggsz"
/>

Se a prop é uma string sempre passe entre aspas, única excessão é se você for usar template string

// Bom
<MyComponent
	isHandsome
	name="hxsggsz"
/>

// Ruim
<MyComponent
	isHandsome
	name={"hxsggsz"}
/>

Oculte parâmetros que sempre serão true

// Bom
<button isLoading>teste<button>

// Ruim
<button isLoading={true}>teste<button>

Class component

Nosso projeto está sendo feito inteiramente com programação funcional, então apenas use functional components (salvo excessões bem excessíveis):

// Bom
function Component(props: IProps) { /* ... */ }

export default Component

// Ruim
class Component extends React.Component {
  // ...
  render() {
    return ( /* ... */ )
  }
}

Estilizando componentes

Estamos utilizando scss modules para estilização, ele tem umas diferenças do css normal

// Bom
.button {
  /* seu css aqui */
  &:hover {
    /* seu css de hover aqui*/
  }
}

// Ruim
.button {
  /* seu css aqui */
}
.button:hover {
  /* seu css de hover aqui*/
}

use scss modules sempre

// Bom
import scss from './Component.module.scss';

function Component(props: IProps) {
  return <div className={scss.style} />;
}

// Ruim
import './Component.scss';

function Component(props: IProps) {
  return <div className="style" />;
}

Evite inline-css, sempre crie uma classe para estilizar. Existem excessões em que é precisa usar inline styles, mas são casos específicos e estarão atrelados a apenas uma propriedade

// Bom
import scss from './Component.module.scss';

function Component(props: IProps) {
  return <div className={scss.style} />;
}

// Ruim
function Component(props: IProps) {
  return <div style={{ color: '#fff' }} />;
}

Tipando componentes

Priorize Interfaces no lugar de Types , ambos servem para fazer a mesma coisa, mas estamos seguindo o padrão de interfaces

// Bom
interface IProps {
  /* ... */
}

// Ruim
type IProps = {
  /* ... */
};

Use o Prefixo I na hora da criação de interfaces.

// Bom
interface IProps {
  /* ... */
}

// Ruim
interface PropTypes {
  /* ... */
}

Use o Prefixo T na hora da criação de tipos.

// Bom
type TProps = {
  /* ... */
};

// Ruim
type PropTypes = {
  /* ... */
};

Use o Prefixo E na hora da criação de enums.

// Bom
enum ECoisas = { /* ... */ }

// Ruim
type Coisas = { /* ... */ }

Testes unitários

Tente ser o mais claro para descrever seus testes, descreva a ação que você vai fazer como describe() e use o it() para descrever a ação esperada do teste. Siga esse padrão: Evite a palavra "should" seguida do it, faça sua sentença ser hiperativa, como "it has", "it renders", "it fails" e etc. Isso serve pra evitar que toda descrição de um teste inicie por "should".

describe('MyButtonComponent', () => {
  describe('when initialize', () => {
    it('shows the button on screen', () => {
      // ...
    });

    describe('when click', () => {
      it('calls the handleButton function ', () => {
        // ...
      });
    });
  });
});

Alt em imagens

SEMPRE coloque o atributo alt quando for usar alguma imagem no projeto, é bom por causa do SEO (mesmo que esse projeto não seja web) e acessibilidade.

// Bom
<img src={image} alt="me and my dog" />

// Ruim
<img src={image} />

Evite usar o prefixo image ou picture porque os leitores de tela ja adicionam esse prefixo na hora de ler o alt então ficaria duplicado

// Ruim
<img src={image} alt="image about me and my dog" />

Estrutura de pastas do projeto


├─ public
│  ├─ coisas de fato publicas como robots.txt, favicons, sitemap.xml e etc.
├─ src
│  ├─ App.tsx
|  |  ├─ Root provider
│  ├─ components
|  |  ├─ Componentes de alta usabilidade
│  ├─ hooks
|  |  ├─ Hooks customizados de alta reusabilidade
│  ├─ pages
|  |  ├─ Páginas da aplicação
│  ├─ store
|  |  ├─ Store geral da aplicação
│  ├─ styles
|  |  ├─ Estilos globais
│  ├─ utils
|  |  ├─ Funções/classes de alta reusabilidade
│  ├─ services
|  |  ├─ Serviços externos a aplicação
│  ├─ config
|  |  ├─ Configurações de módulos
│  ├─ snippets
|  |  ├─ Snippets usados na aplicação
│  ├─ interfaces
|  |  ├─ Interfaces que não são relativas a um módulo específico
│  ├─ constants
|  |  ├─ Constantes que não são relativas a um módulo específico
│  ├─ enums
|  |  ├─ Enums que não são relativos a um módulo específico