GSCalixto / frontend-guideline

Front-end Guideline by Juntos Somos Mais

Home Page:https://juntossomosmais.github.io/frontend-guideline/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

juntos-somos-devs

Front-end - Guideline

Guideline Webpage

GitHub contributors GitHub contributors

"Every line of code should appear to be written by a single person, no matter the number of contributors." - Chinese Proverb.

The following document describes generic rules of writing in development languages that we use on our Front-end projects, that HTML, CSS, JavaScript, React, and Vue

The idea of this repository is not to be a complete guideline, the target is just to help developers who participate in our projects to be able to inform the coding standards used.

As this is a live document, some rules may not have been applied in old projects and changes can occur at any time.

We are hiring! πŸ”₯

If you are looking opportunities as Front-end Developer we are hiring!

You can check all our job opportunities and apply if you like it 😁

This is our Front-end Challenge

πŸ“– Summary

  1. General Code Patterns
  2. Architecture
  3. Git
  4. HTML
  5. CSS
  6. JavaScript
  7. React
  8. Vue
  9. Storybook

1. General Code Patterns

1.1 Code Syntax

Use soft tabs with two spaces. You need to configure your editor for this.

βœ… Good:

const obj = {
  prop: "value",
  prop2: "value2",
  prop3: "value3",
}
.foo {
  color: red;
}
<div>
  <p>Hello World</p>
</div>

❌ Bad:

const obj = {
    prop: "value",
    prop2: "value2",
    prop3: "value3",
}
.foo {
    color: red;
}
<div>
    <p>Hello World</p>
</div>

2. Architecture

The proper architecture for projects, and how to create and name files and folders.

2.1 File Name

βœ… Good:

  • UserProfile/UserProfile.vue
  • UserProfile/index.js
  • UserProfile/index.ts
  • UserProfile/styles.js
  • UserProfile/UserProfile.scss
  • UserProfile/UserProfile.stories.mdx

❌ Bad:

  • UserProfile/component.vue
  • src/UserProfile.js
  • UserProfile/component.ts
  • UserProfile/style.scss
  • UserProfileStyles.js
  • UserProfile/UserProfile.mdx

2.2 Folder Architecture

Global Components/Helpers

Global Components should only be components used in more than one place.

For example:

┣ πŸ“‚ src/components \
┣ ┣ πŸ“‚ component \
┣ ┃ ┣ πŸ“œ index.js
┣ ┃ ┣ πŸ“œ styles.js
┣ ┃ ┣ πŸ“œ index.spec.js
┣ ┃ ┣ πŸ“œ index.stories.mdx

Scoped Components/Helpers

We need to add inside pages/**/components, for example, all components that is need used just a context or scope, like a components that be used just a some place or specific page.

If we need to used the component again in another context or page it need to be moved to src/components.

For example:

┣ πŸ“‚ pages \
┣ ┣ πŸ“‚ Home \
┣ ┃ ┣ πŸ“œ Home.js \
┣ ┃ ┣ πŸ“œ Home.style.js \
┣ ┃ ┣ πŸ“œ Home.spec.js \
┣ ┃ ┣ πŸ“‚ components \
┣ ┃ ┃ ┣ πŸ“‚ UserProfile \
┣ ┣ ┃ ┃ ┣ πŸ“œ UserProfile.style.js \
┣ ┣ ┃ ┃ ┣ πŸ“œ UserProfile.spec.js \
┣ ┣ ┃ ┃ ┣ πŸ“œ UserProfile.stories.mdx \

⬆ back to summary


3. Git

3.1 Commit Messages

In order to facilitate the contribution of anyone in a project, all commit messages must be in English.

We also use conventional commit messages, that is, the commit message must be in the form of a sentence, with the first word being an action, and the rest of the sentence a describing text.

βœ… Good:

git commit -m "feat: allow provided config object to extend configs"
git commit -m "docs: correct spelling of CHANGELOG"
git commit -m "feat(lang): add the Portuguese language"

❌ Bad:

git commit -m "Add placeholder on input"

⬆ back to summary


4. HTML

We main reference for HTML good patterns is W3C and MDN, behind these docs we could learn a lot with semantic and another good practices.

We don't guest the scope of HTML components inside page, so when we start a new component, we should use a semantic tag, like section or article for example, to be able to starting to use the heading tags by context.

βœ… Good:

<section class="component">
  <h1 class="title">Title</h1>
  <p>Paragraph</p>
</section>

❌ Bad:

<div class="component">
  <h4 class="title">Title</h4>
  <p>Paragraph</p>
</div>

5. CSS

The tips above could be used in any CSS framework or preprocessor, like SCSS, Styled Components and etc

5.1 CSS Syntax

Keep one declaration per line.

βœ… Good:

.selector-1,
.selector-2,
.selector-3 {
  ...
}

❌ Bad:

.selector-1, .selector-2, .selector-3 {
  ...
}

Separate each ruleset by a blank line.

βœ… Good:

.selector-1 {
  ...
}

.selector-2 {
  ...
}

❌ Bad:

.selector-1 {
  ...
}
.selector-2 {
  ...
}

Use lowercase and avoid specifying units is zero-values.

βœ… Good:

.selector-1 {
  color: #aaaaaa;
  margin: 0;
}

❌ Bad:

.selector-1 {
  color: #aaaaaa;
  margin: 0px;
}

5.2 CSS Declaration Order

The declarations should be added in alphabetical order.

βœ… Good:

.selector {
  background: #fff;
  border: #333 solid 1px;
  color: #333;
  display: flex;
  height: 200px;
  margin: 5px;
  padding: 5px;
  width: 200px;
}

❌ Bad:

.selector {
  padding: 5px;
  height: 200px;
  background: #fff;
  margin: 5px;
  width: 200px;
  color: #333;
  border: #333 solid 1px;
  display: flex;
}

5.3 CSS Class Names

Keep class lowercase and use dashes to separate the classname.

βœ… Good:

.page-header { ... }

❌ Bad:

.pageHeader { ... }
.page_header { ... }

Is a good idea follows a BEM naming convention to avoid conflicts with other components. If you are using CSS-in-JS like a Styled-Component, you can use BEM if you need to nesting elements inside parent.

The main pattern is use single dash to element name, double underline to element block and double dash to style modification.

βœ… Good:

/* Good */
.page-header__title { ... }
.page-header--active { ... }

.button--active { ... }

❌ Bad:

.page-header-title { ... }
.page-header-active { ... }

.active { ... }
.primary { ... }

Dashes and underline serve as natural breaks in related class. Prefix class based on the closest parent or base class.

βœ… Good:

.nav { ... }
.nav__item { ... }
.nav__link { ... }

❌ Bad:

.item-nav { ... }
.link-nav { ... }

Avoid giving too short names for class and always choose meaningful names that provide the class function.

βœ… Good:

/* Good */
.button { ... }
.page-header { ... }
.progress-bar { ... }

❌ Bad:

.s { ... }
.btn { ... }
.ph { ... }
.block { ... }

5.4 CSS Good Practices

Avoid use values like colors, spacing and etc directly in the elements, use variables instead, and it can be CSS variables or some preprocessor variables, always check the context.

βœ… Good:

.button {
  color: var(--color-primary);
  padding: var(--space-sm);
}

❌ Bad:

.button {
  color: #333;
  padding: 16px;
}

Never use IDs to style elements, always use classes instead.

βœ… Good:

.header { ... }
.section { ... }

❌ Bad:

#header { ... }
#section { ... }

Do not style directly the elements, it will create a lot of conflicts, always use classes instead.

βœ… Good:

.form-control { ... }
.header { ... }
.section { ... }

❌ Bad:

input[type="text"] { ... }
header
section

Avoid nesting elements, because it decrease performance and increase the specificity of the CSS, always use classes instead.

βœ… Good:

.navbar { ... }
.nav { ... }
.nav__item { ... }
.nav__link { ... }

❌ Bad:

.navbar ul { ... }
.navbar ul li { ... }
.navbar ul li a { ... }

5.5 CSS Media Queries

Start the development with generic rules and add media queries inside scope using mobile first. Also is important keep the media queries as close to their relevant rule sets whenever possible.

βœ… Good:

.navbar {
  margin-bottom: var(--space);

  @media (min-width: 480px) {
    padding: 10px;
  }

  @media (min-width: 768px) {
    position: absolute;
    top: 0;
    left: 0;
  }

  @media (min-width: 992px) {
    position: fixed;
  }
}

❌ Bad:

.navbar {
  position: fixed;
  top: 0;
  left: 0;

  @media (max-width: 767px) {
    position: static;
    padding: var(--space-sm);
  }
}

⬆ back to summary

6. JavaScript

6.1 JavaScript Code Syntax

Never use semicolons.

βœ… Good:

const foo = "bar"
const baz = "qux"
const func = () => {}

❌ Bad:

const foo = "bar";
const baz = "qux";
const func = () => {};

Always use single quotes or template literals

βœ… Good:

const string = 'foo'
const template = `foo`

❌ Bad:

const string = "foo"
const template = "foo"

For strict equality checks === should be used in favor of ==.

βœ… Good:

if (foo === "foo") {
  statement
}

❌ Bad:

if (foo == "foo") {
  statement
}

6.2 Variables

Use meaningful, pronounceable, and in English variable names.

βœ… Good:

const currentDate = new Date().toLocaleDateString("pt-BR")

❌ Bad:

const xpto = new Date().toLocaleDateString("pt-BR")

6.3 Descriptive validations (if)

Creating const to describe validations.

βœ… Good:

const hasFullUserName = user.firstName && user.lastname

if (hasFullUserName) {
  //do awesome something
}

❌ Bad:

if (user.firstName && user.lastname) {
  //do something
}

⬆ back to summary


7. React

7.1 Keys in lists

The best way to pick a key is to use a string that uniquely identifies a list item among its siblings.

It is not recommended to use indexes for keys if the order of items can change. This can negatively affect performance and can cause problems with the component's state.

βœ… Good:

array.map((item, index) => <Component key={item.id} {...item}>)

❌ Bad:

array.map((item, index) => <Component key={index} {...item}>)

7.2 useState functional updates

If the new state is calculated using the previous state, you can pass a function to setState. Thus avoiding competition between states and preventing possible bugs.

βœ… Good:

const [number, setNumber] = useState(1)

return (
  <div>
    <h1>{number}</h1>
    <button onClick={() => setNumber((prevNumber) => prevNumber + 1)}>
      Increase
    </button>
    <button onClick={() => setNumber((prevNumber) => prevNumber - 1)}>
      Decrease
    </button>
  </div>
)

❌ Bad:

const [number, setNumber] = useState(1)

return (
  <div>
    <h1>{number}</h1>
    <button onClick={() => setNumber(number + 1)}>Increase</button>
    <button onClick={() => setNumber(number - 1}>Decrease</button>
  </div>
)

7.3 useEffect dependencies array

Use the useEffect dependency array to trigger side effects, and make your code cleaner.

βœ… Good:

const [page, setPage] = useState(1)

useEffect(() => {
  requestListUser()
  // calls useEffect when page state changes
}, [page])

return (
  <div>
    <button onClick={() => setPage((prevState) => prevState + 1)}>
      Next Page
    </button>
  </div>
)

❌ Bad:

const [page, setPage] = useState(1)

useEffect(() => {
  requestListUser()
}, [])

const requestListUser = () => {
  setPage((prevState) => prevState + 1)
  // ...
  // any code to return user list
}

return (
  <div>
    <button onClick={() => requestListUser()}>Next Page</button>
  </div>
)

7.4 Readable components

Avoid creating very large components. If possible divided into sub-components, improving the understanding and reading of the code.

βœ… Good:

const Screen = () => (
  <Container>
    <Header>
      <Title />
      <Button background="black">Filter</Button>
    </Header>

    <Main>
      <List>
        {data.map((item) => (
          <Card key={item.id} name={item.name} />
        ))}
      </List>
    </Main>
  </Container>
)

❌ Bad:

const Screen = () => (
  <Box padding={1}>
    <Box alignItems="center">
      <Text>Titulo</Text>
      <Button background="black">Filter</Button>
    </Box>
    <Box marginTop={5}>
      <Box>
        {data.map((item) => (
          <Box key={item.id}>
            <Text color="red">{item.name}</Text>
          </Box>
        ))}
      </Box>
    </Box>
  </Box>
)

⬆ back to summary


8. Vue

8.1 Keys in lists

The best way to pick a key is to use a string that uniquely identifies a list item among its siblings.

It is not recommended to use indexes for keys if the order of items can change. This can negatively affect performance and can cause problems with the component's state.

βœ… Good:

<template v-for="item in items">
   <Component :key="item.id" v-bind="{...item}">
</template>

❌ Bad:

<template v-for="(item, index) in items">
   <Component :key="index" v-bind="{...item}">
</template>

8.2 Use Computed for real time updates

If you need listen changes at data use computeds instead of methods

βœ… Good:

computed: {
  fullName(){
    return `${this.name} ${this.lastName}`
  }
}

❌ Bad:

methods: {
  fullName() {
    this.fullName = `${this.name} ${this.lastName}`
  }
}

⬆ back to summary


9. Storybook

9.1 Story file

Create a file with the same name of your component, or index, and with the suffix .stories.mdx.

βœ… Good:

  • Button.stories.mdx
  • Dialog/index.stories.mdx

❌ Bad:

  • Input.mdx
  • Dialog/index.mdx

⬆ back to summary


About

Front-end Guideline by Juntos Somos Mais

https://juntossomosmais.github.io/frontend-guideline/

License:MIT License