From fdeec209107abaa313353a7631aa65ce2497a393 Mon Sep 17 00:00:00 2001 From: Lenilson Nascimento Date: Mon, 24 May 2021 18:53:20 -0300 Subject: [PATCH] Started working on backend course --- gatsby-config.js | 15 +- gatsby-node.js | 32 +- package.json | 2 + src/assets/close_black.svg | 1 + src/components/Menu.js | 179 ++-- src/components/layout.js | 36 +- src/components/toc.js | 136 +++ src/markdown/backend/m1/00-logica.md | 59 ++ src/markdown/backend/m1/01-data-structures.md | 849 ++++++++++++++++++ .../{ => frontend}/m1/00-how-it-works.md | 4 +- .../m1/01-how-sites-are-built.md | 4 +- .../{ => frontend}/m1/02-html-hands-on.md | 4 +- .../{ => frontend}/m1/03-html-forms.md | 4 +- .../{ => frontend}/m1/04-html-semantic.md | 4 +- .../{ => frontend}/m1/05-css-intro.md | 4 +- .../{ => frontend}/m1/06-css-selectors.md | 4 +- .../{ => frontend}/m1/07-css-box-model.md | 4 +- .../{ => frontend}/m1/08-css-display.md | 4 +- .../{ => frontend}/m1/09-css-measures.md | 4 +- .../{ => frontend}/m1/10-css-flexbox.md | 4 +- src/markdown/{ => frontend}/m2/00-logica.md | 0 .../{ => frontend}/m2/01-simple-types.md | 0 .../{ => frontend}/m2/03-complex-types.md | 0 src/markdown/{ => frontend}/m2/04-loops.md | 0 .../{ => frontend}/m2/05-functions.md | 0 src/markdown/{ => frontend}/m2/06-switch.md | 0 src/markdown/{ => frontend}/m2/07-ES6.md | 0 src/templates/blogTemplate.js | 153 ++-- yarn.lock | 33 +- 29 files changed, 1326 insertions(+), 213 deletions(-) create mode 100644 src/assets/close_black.svg create mode 100644 src/components/toc.js create mode 100644 src/markdown/backend/m1/00-logica.md create mode 100644 src/markdown/backend/m1/01-data-structures.md rename src/markdown/{ => frontend}/m1/00-how-it-works.md (98%) rename src/markdown/{ => frontend}/m1/01-how-sites-are-built.md (96%) rename src/markdown/{ => frontend}/m1/02-html-hands-on.md (98%) rename src/markdown/{ => frontend}/m1/03-html-forms.md (96%) rename src/markdown/{ => frontend}/m1/04-html-semantic.md (98%) rename src/markdown/{ => frontend}/m1/05-css-intro.md (98%) rename src/markdown/{ => frontend}/m1/06-css-selectors.md (97%) rename src/markdown/{ => frontend}/m1/07-css-box-model.md (98%) rename src/markdown/{ => frontend}/m1/08-css-display.md (97%) rename src/markdown/{ => frontend}/m1/09-css-measures.md (98%) rename src/markdown/{ => frontend}/m1/10-css-flexbox.md (96%) rename src/markdown/{ => frontend}/m2/00-logica.md (100%) rename src/markdown/{ => frontend}/m2/01-simple-types.md (100%) rename src/markdown/{ => frontend}/m2/03-complex-types.md (100%) rename src/markdown/{ => frontend}/m2/04-loops.md (100%) rename src/markdown/{ => frontend}/m2/05-functions.md (100%) rename src/markdown/{ => frontend}/m2/06-switch.md (100%) rename src/markdown/{ => frontend}/m2/07-ES6.md (100%) diff --git a/gatsby-config.js b/gatsby-config.js index 0a89208..128fe92 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -26,10 +26,10 @@ module.exports = { fonts: [ `limelight`, `Open Sans\:300,400,700`, - `Roboto\:300,400,700` // you can also specify font weights and styles + `Roboto\:300,400,700`, // you can also specify font weights and styles ], - display: 'swap' - } + display: "swap", + }, }, { resolve: `gatsby-source-filesystem`, @@ -42,13 +42,14 @@ module.exports = { resolve: `gatsby-transformer-remark`, options: { plugins: [ + `gatsby-remark-autolink-headers`, { resolve: `gatsby-remark-highlight-code`, options: { - terminal: 'carbon', - theme: 'dracula', - lineNumbers: true - } + terminal: "carbon", + theme: "dracula", + lineNumbers: true, + }, }, ], }, diff --git a/gatsby-node.js b/gatsby-node.js index 285889f..81ca27f 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -24,11 +24,11 @@ exports.createPages = async ({ actions, graphql, reporter }) => { reporter.panicOnBuild(`Error while running GraphQL query.`) return } - const posts = result.data.allMarkdownRemark.edges; + const posts = result.data.allMarkdownRemark.edges const m1Content = posts.filter( - item => item.node.frontmatter.category === 'module-1' - ); + item => item.node.frontmatter.category === "frontend-module-1" + ) m1Content.forEach(({ node }, index) => { createPage({ @@ -38,8 +38,30 @@ exports.createPages = async ({ actions, graphql, reporter }) => { category: node.frontmatter.category, slug: node.frontmatter.slug, prev: index === 0 ? null : m1Content[index - 1].node, - next: index === (m1Content.length - 1) ? null : m1Content[index + 1].node + next: index === m1Content.length - 1 ? null : m1Content[index + 1].node, }, }) }) -}; \ No newline at end of file + + const backendM1Content = posts.filter( + item => item.node.frontmatter.category === "backend-module-1" + ) + + backendM1Content.forEach(({ node }, index) => { + console.log(node) + createPage({ + path: node.frontmatter.slug, + component: blogPostTemplate, + context: { + category: node.frontmatter.category, + slug: node.frontmatter.slug, + prev: index === 0 ? null : backendM1Content[index - 1].node, + next: + index === backendM1Content.length - 1 + ? null + : backendM1Content[index + 1].node, + showTableOfContents: true, + }, + }) + }) +} diff --git a/package.json b/package.json index c507a55..b739ff6 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "gatsby-plugin-offline": "^3.9.0", "gatsby-plugin-react-helmet": "^3.9.0", "gatsby-plugin-sharp": "^2.13.2", + "gatsby-remark-autolink-headers": "^4.2.0", "gatsby-remark-highlight-code": "^2.1.1", "gatsby-source-filesystem": "^2.11.0", "gatsby-transformer-remark": "^2.16.0", @@ -21,6 +22,7 @@ "react": "^16.12.0", "react-dom": "^16.12.0", "react-helmet": "^6.1.0", + "react-scroll": "^1.8.2", "rehype-react": "^6.2.0", "styled-components": "^5.2.1" }, diff --git a/src/assets/close_black.svg b/src/assets/close_black.svg new file mode 100644 index 0000000..aa52a27 --- /dev/null +++ b/src/assets/close_black.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Menu.js b/src/components/Menu.js index 21675dc..afc5bab 100644 --- a/src/components/Menu.js +++ b/src/components/Menu.js @@ -1,127 +1,116 @@ -import React, { Fragment, useState } from "react"; -import { Link } from "gatsby"; -import styled from "styled-components"; +import React, { Fragment, useState } from "react" +import { Link } from "gatsby" +import styled from "styled-components" // Images -import logo from '../assets/logo.svg'; -import menu from '../assets/menu.svg'; -import close from '../assets/close.svg'; +import logo from "../assets/logo.svg" +import menu from "../assets/menu.svg" +import close from "../assets/close.svg" const Container = styled.nav` - position: fixed; + position: fixed; width: 20vw; - height: 100vh; - padding: 1rem 0; - border-right: 1px solid #E6ECF1; - background-color: #F5F7F9; - overflow-y: scroll; + height: 100vh; + padding: 1rem 0; + border-right: 1px solid #e6ecf1; + background-color: #f5f7f9; + overflow-y: scroll; - @media (max-width: 667px) { - width: 80vw; - transform: ${props => props.isVisible ? 'translateX(0)' : 'translateX(-150%)'}; + @media (max-width: 667px) { + width: 80vw; + transform: ${props => + props.isVisible ? "translateX(0)" : "translateX(-150%)"}; } -`; +` const Button = styled.button` - position: fixed; - top: 5px; - left: 5px; - width: 45px; - height: 45px; - border: none; - border-radius: 12px; - outline: none; - background: #FFAC2D url(${menu}) no-repeat center; + position: fixed; + top: 5px; + left: 5px; + width: 45px; + height: 45px; + border: none; + border-radius: 12px; + outline: none; + background: #ffac2d url(${menu}) no-repeat center; - ${({ isVisible }) => isVisible && ` + ${({ isVisible }) => + isVisible && + ` left: calc(80vw + 5px); background: #FFAC2D url(${close}) no-repeat center; `} - @media(max-width: 667px) { - display: block; - } -`; + @media(max-width: 667px) { + display: block; + } +` const Logo = styled(Link)` - display: flex; - justify-content: center; - width: 70%; - margin: 0 auto 2rem; -`; + display: flex; + justify-content: center; + width: 70%; + margin: 0 auto 2rem; +` const Image = styled.img` - width: 70%; -`; + width: 70%; +` const Item = styled(Link)` - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 40px; - margin: .5rem 0; - padding: 0 5%; - color: #505050; - text-align: center; - text-decoration: none; - font: 700 .7rem 'Open Sans', sans-serif; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 40px; + margin: 0.5rem 0; + padding: 0 5%; + color: #505050; + text-align: center; + text-decoration: none; + font: 700 0.7rem "Open Sans", sans-serif; - ${({ active }) => active && ` + ${({ active }) => + active && + ` border: 1px solid #E6ECF1; border-right: none; color: #FFAC2D; background: #FFF; `} -`; - -const Menu = ({ - links, - location -}) => { - const [isVisible, setVisible] = useState(false); +` - const isActive = (item, location) => { - if (item.slug.includes(location.pathname)) { - return true - } - - return false; - } +const Menu = ({ links, location }) => { + const [isVisible, setVisible] = useState(false) - const renderLinks = () => { - return links.map((link) => ( - - {link.title} - - )) - }; + const renderLinks = () => { + return links.map(link => ( + + {link.title} + + )) + } return ( - - + + {isOpen && ( + <> + Tabela de Conteúdo + + {headings.map(heading => { + if (heading.depth > 3) { + return null + } + + return ( + + + {heading.value} + + + ) + })} + + Retornar ao Topo + + )} + + ) +} + +export default ToC diff --git a/src/markdown/backend/m1/00-logica.md b/src/markdown/backend/m1/00-logica.md new file mode 100644 index 0000000..1c1e2be --- /dev/null +++ b/src/markdown/backend/m1/00-logica.md @@ -0,0 +1,59 @@ +--- +slug: "/backend/module-1/logica" +date: "2021-05-24" +title: "00 - Lógica de Programação" +id: 0 +category: "backend-module-1" +--- + +# Lógica de Programação + +## FAQ + +### O que é lógica de programação? + +**R**: Lógica de programação é a organização coesa de uma sequência de instruções voltadas à resolução de um problema, ou à criação de um software ou aplicação. + +### Por que lógica é importante? + +**R**: Uma boa lógica faz um bom programador. Quanto melhor for seu pensamento lógico, mais rápido você conseguirá chegar à uma melhor solução para um problema computacional. + +> Recomendo a leitura deste artigo pois responde bem as duas perguntas acima. + +### Devo fazer este capítulo por completo? + +**R**: Cada aluno julgue a si mesmo se deve ou não pular este capítulo, dê uma olhada no índice e reflita se você se sente confortável com o conteúdo que será apresentado aqui. Eu indicaria não pular as seções referentes a Estruturas de Repetição e Recursividade. + + +## Apostila de lógica Unicamp + +Baixe a apostila no link, leia e faça todos os exercícios propostos antes de continuar este capítulo. + +## Como o computador executa instruções + +O vídeo abaixo explica de forma simplificada como um computador executa instruções: + + + +## Exercícios: Estruturas de condição em JavaScript + +### If e Else +### Switch/Case +### Ternários +### And e Or + +## Exercícios: Estruturas de repetição em JavaScript + +### Sequência Fibonacci + +### Palíndromo + +## Exercícios: Recursividade em JavaScript + +### Sequência Fibonacci + +### Palíndromo + +## Revisão + +## Referências diff --git a/src/markdown/backend/m1/01-data-structures.md b/src/markdown/backend/m1/01-data-structures.md new file mode 100644 index 0000000..62101bc --- /dev/null +++ b/src/markdown/backend/m1/01-data-structures.md @@ -0,0 +1,849 @@ +--- +slug: "/backend/module-1/data-structures" +date: "2021-05-24" +title: "01 - Estruturas de Dados" +id: 1 +category: "backend-module-1" +--- + +# Estruturas de Dados + +## FAQ + +### O que são estruturas de dados? + +Estrutura de dados é uma organização, gerenciamento e armazenamento de dados em um formato que viabiliza acesso e modificação de forma eficiente. Mais precisamente, uma estrutura de dados é uma coleção de valores de dados, o relacionamento entre eles, e as funções e operações que podem ser aplicados aos dados. + +### Por que é importante aprender Estruturas de Dados? + +A todo tempo utilizamos estruturas de dados na programação. Algumas são usadas com mais frequência, outras em casos mais específicos. Fato é que as estruturas de dados foram criadas para facilitar a forma como trabalhamos com os mesmos e são otimizadas até o ultimo bit para extrair o máximo de performance possível. +Não é necessário que você conheça todas as estruturas de dados, mas é muito vantajoso que saiba trabalhar com as mais básicas, como arrays e objetos no JavaScript. + +## Arrays + +Arrays, são estruturas capazes de armazenar dados em uma espécie de lista. São chamados também de vetores por serem similares a vetores na matemática. +A seguir, alguns exemplos de arrays em várias linguagens: + +#### C ou C++ + +Em C ou C++ devemos indicar o tipo de dado armazenado no array (int, string, char, etc). Também devemos dizer o tamanho do vetor para que o programa reserve exatamente aquele espaço de memória para o array, já que em C o programador tem total controle da alocação de memória. + +```cpp +int vetor[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} +``` + +Caso você não saiba exatamente o tamanho que terá o array, é possível criá-lo sem especificar esta informação. + +```cpp +int vetor2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} +``` + +#### Go + +Em go podemos criar arrays de duas formas: + +1. Alocando memória e iniciando o array depois: + +```go +var vetor [3]int +vetor[0] = 1 +vetor[1] = 2 +vetor[2] = 3 +``` + +2. Iniciando diretamente o array: + +```go +vetor := [3]int{1, 2, 3} +``` + +#### Python + +Python trabalha com o conceito de listas, que fundamentalmente são a mesma coisa que array. As listas em python podem conter elementos de diversos tipos e a alocação de memória é feita dinâmicamente. + +```python +lista = [0, 1, 2, "tres", 4, "cinco"] +``` + +#### JavaScript + +Similarmente ao python, arrays em JavaScript podem ter tipos variados de dados e a linguagem é responsável por reservar a memória necessária: + +```javascript +const lista = [0, 1, 2, "tres", 4, "cinco"] +``` + +> Neste curso iremos forcar em JavaScript e TypeScript. Logo, todos os exemplos à partir de agora serão nessas linguagens + +## Operações com arrays + +Veremos agora algumas operações possíveis com arrays em JavaScript. + +### Concat + +Concat é uma forma de juntar dois arrays em um. Ao utilizar a função concat, um novo array é retornado. + +Exemplo: + +```javascript +const array1 = [0, 1, 2] +const array2 = [3, 4, 5] +const array3 = array1.concat(array2) // [0, 1, 2, 3, 4, 5] +``` + +> Uma outra forma de fazer a junção de arrays é utilizando o spread operator. + +Exemplo com spread operator: + +```javascript +const array1 = [0, 1, 2] +const array2 = [3, 4, 5] +const array3 = [...array1, ...array2] // [0, 1, 2, 3, 4, 5] +``` + +### Join + +Usar a função join em um array, o transformará em uma string. Você pode definir um separador para cada elemento do array. + +Exemplo: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const str = array.join(",") // note que o separador é a vírgula +console.log(str) // "0, 1, 2, 3, 4, 5" + +const array2 = ["as", "três", "marias"] +const str2 = array2.join(" ") // o separador é um espaço +console.log(str2) // "as três marias" +``` + +### Pop e Shift + +A função pop remove o último elemento de um array e retorna este elemento. + +Exemplo: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const ultimo = array.pop() +console.log(array) // [0, 1, 2, 3, 4] +console.log(ultimo) // 5 +``` + +A função shift remove o primeiro elemento de um array e retorna este elemento. + +Exemplo: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const primeiro = array.shift() +console.log(array) // [1, 2, 3, 4, 5] +console.log(primeiro) // 0 +``` + +### Push e Unshift + +A função push adiciona um novo elemento ao final do array e retorna o seu tamanho. + +Exemplo: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const tamanho = array.push(6) +console.log(array) // [0, 1, 2, 3, 4, 5, 6] +console.log(tamanho) // 7 +``` + +A função unshift adiciona um novo elemento ao início do array e retorna o seu tamanho. + +Exemplo: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const tamanho = array.unshift(6) +console.log(array) // [6, 0, 1, 2, 3, 4, 5] +console.log(tamanho) // 7 +``` + +### ForEach + +A função forEach irá iterar sobre todos os elementos de um array e aplicar uma função especificada pelo programador. + +Neste exemplo iremos criar um novo array elevando todos os elementos de um dado array ao quadrado. + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const quadrados = [] + +function quadrado(numero) { + // Eleva o número a potência 2 e adiciona o mesmo ao array de quadrados + quadrados.push(Math.pow(numero, 2)) +} + +array.forEach(quadrado) + +console.log(array) // [0, 1, 2, 3, 4, 5] +console.log(quadrados) // [0, 1, 4, 9, 16, 25] +``` + +Uma outra forma de alcançar o mesmo objetivo é criar a função na passagem de parâmetro para o forEach: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const quadrados = [] + +// Note que invés de criar a função anteriormente, já criamos como parâmetro do forEach +array.forEach(function (numero) { + // Eleva o número a potência 2 e adiciona o mesmo ao array de quadrados + quadrados.push(Math.pow(numero, 2)) +}) + +console.log(array) // [0, 1, 2, 3, 4, 5] +console.log(quadrados) // [0, 1, 4, 9, 16, 25] +``` + +### Map + +A função map similar ao forEach, itera sobre todos os elementos do array. Porém o map irá retornar um array de mesmo tamanho. + +Usaremos o mesmo exemplo de elevar um número ao quadrado. + +```javascript +const array = [0, 1, 2, 3, 4, 5] + +function quadrado(numero) { + // Retorna o número elevado à potência 2 + return Math.pow(numero, 2) +} + +const quadrados = array.map(quadrado) + +console.log(array) // [0, 1, 2, 3, 4, 5] +console.log(quadrados) // [0, 1, 4, 9, 16, 25] +``` + +Uma outra forma de alcançar o mesmo objetivo é criar a função na passagem de parâmetro para o map: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const quadrados = [] + +// Note que invés de criar a função anteriormente, já criamos como parâmetro do map +const quadrados = array.map(function (numero) { + // Retorna o número elevado à potência 2 + return Math.pow(numero, 2) +}) + +console.log(array) // [0, 1, 2, 3, 4, 5] +console.log(quadrados) // [0, 1, 4, 9, 16, 25] +``` + +> Note que é importante que a função passada para o map sempre tenha um ***return***. Do contrário, o elemento não será modificado e você terá como resultado o array original. + +### Reduce + +A função reduce irá "reduzir" o array à um único elemento baseado na função passada como parâmetro. + +Por exemplo, se quisermos fazer a média dos números em um array: + +```javascript +const array = [0, 1, 2, 3, 4, 5] + +/** +* Primeiro precisamos encontrar a soma de todos os elementos do array. +* Usaremos a função soma, que recebe o elemento anterior e o atual da função reduce +*/ + +function soma (anterior, atual) { + return anterior + atual +} + +/** +* Aplicamos a soma como parâmetro do reduce, o segundo parâmetro é o valor inicial. +*/ + +const total = array.reduce(soma, 0) // 15 + +/** +* Agora basta dividir o total pela quantidade de números no array +*/ + +const media = total / array.length + +console.log(media) // 2.5 +``` + +Assim como nas funções forEach e map, podemos também criar a função já como parâmetro do reduce: + +```javascript +const array = [0, 1, 2, 3, 4, 5] + +/** +* Primeiro precisamos encontrar a soma de todos os elementos do array. +* Aplicamos a soma como parâmetro do reduce a função que recebe o elemento anterior e o atual da função reduce e soma os mesmos +*/ +const total = array.reduce(function (anterior, atual) { + return anterior + atual +}, 0) // 15 + +/** +* Agora basta dividir o total pela quantidade de números no array +*/ + +const media = total / array.length + +console.log(media) // 2.5 +``` + +### Filter + +A função filter irá percorrer o array e retornar todos os elementos que satisfaçam a condição da função passada por parâmetro. + +Neste exemplo iremos buscar todos os números maiores que 3: + +```javascript +const array = [0, 1, 2, 3, 4, 5] + +function ehMaiorQueTres(numero) { + return numero > 3 +} + +const maioresQueTres = array.filter(ehMaiorQueTres) + +console.log(maioresQueTres) // [4, 5] +``` + +Criando a função na passagem de parâmetro: + +```javascript +const array = [0, 1, 2, 3, 4, 5] + +const maioresQueTres = array.filter(function (numero) { + return numero > 3 +}) + +console.log(maioresQueTres) // [4, 5] +``` + +## Objetos + +### O que são objetos em JavaScript + +O JavaScript trabalha com objetos de uma maneira bem única. Assim como os dicts (dicionários) em python, objetos no JavaScript nada mais são que um conjunto chave e valor. + +Por exemplo, se quisermos salvar os dados do João: + +```javascript +const dados = { + //chave valor + nome: "João", + idade: 16, + email: "joão@ninguem.com" +} +``` + +Objetos podem conter outras estruturas de dados, como arrays e outros objetos: + +```javascript +const dados = { + //chave valor + nome: "João", + idade: 16, + email: "joão@ninguem.com", + // array como valor + coresFavoritas: ["azul", "vermelho", "rosa"], + // objeto como valor + endereco: { + //chave valor + rua: "Rua do Bobos" + numero: 0 + } +} +``` + +Objetos podem também conter funções como valores: + +```javascript +const Matematica = { + soma: function (num1, num2) { return num1 + num2}, + sub: function (num1, num2) { return num1 - num2}, + mult: function (num1, num2) { return num1 * num2}, + div: function (num1, num2) { return num1 / num2}, +} + +console.log(Matematica.mult(2, 4)) // 8 +``` + +## Métodos especiais da classe Object + +A classe Object possui vários métodos especiais para lidar com objetos, alguns deles sendo: + +### Object.keys + +O método Object.keys retorna um array contendo as chaves de um objeto, por exemplo: + +```javascript +const objeto = { + nome: "Jõao", + idade: 16, +} + +const chaves = Object.keys(objeto) + +console.log(chaves) // [nome, idade] +``` + +### Object.values + +O método Object.values retorna um array contendoos valores de um objeto, por exemplo: + +```javascript +const objeto = { + nome: "Jõao", + idade: 16, +} + +const valores = Object.values(objeto) + +console.log(valores) // ["João", 16] +``` + +### Object.entries + +O método Object.entries retorna um array contendo arrays onde o primeiro elemento é a chave e o segundo elemento o valor. Por exemplo: + +```javascript +const objeto = { + nome: "Jõao", + idade: 16, +} + +const entradas = Object.entries(objeto) + +console.log(entradas) // [["nome", "João"], ["idade", 16]] +``` + +### Object.fromEntries + +O método Object.fromEntries faz o inverso do Object.entries, sendo assim, dado um array contendo contendo arrays onde o primeiro elemento é a chave e o segundo elemento o valor, um objeto será criado. Exemplo: + +```javascript +const entradas = [["nome", "João"], ["idade", 16]] + +const objeto = Object.fromEntries(entradas) + +console.log(objeto) // {nome: "João", idade: 16} +``` + +### Object.assign + +O método Object.assign recebe dois objetos e cria um novo objeto com todas as propriedades dos objetos recebidos. Exemplo: + +```javascript +const dados = { + nome: "Jõao", + idade: 16, +} + +const informacoesDeContato = { + email: "joao@ninguem.com", + telefone: "45988054596", +} + +const dadosComContato = Object.assign(dados, informacoesDeContato) + +console.log(dadosComContato) +// {nome: "Jõao", idade: 16, email: "joao@ninguem.com", telefone: "45988054596"} +``` + +O mesmo comportamento do Object.assign pode ser obtido ao usar o spread operator, como no exemplo a seguir: {.is-info} + +```javascript +const dados = { + nome: "Jõao", + idade: 16, +} + +const informacoesDeContato = { + email: "joao@ninguem.com", + telefone: "45988054596", +} + +const dadosComContato = { + ...dados, + ...informacoesDeContato, +} + +console.log(dadosComContato) +// {nome: "Jõao", idade: 16, email: "joao@ninguem.com", telefone: "45988054596"} +``` + +### Object.hasOwnProperty + +O método hasOwnProperty verifica se o objeto possui a propriedade e retorna true ou false. Exemplo: + +```javascript +const dados = { + nome: "Jõao", + idade: 16, +} + +console.log(dados.hasOwnProperty("nome")) // true +console.log(dados.hasOwnProperty("email")) // false +``` + +### Object.toString + +O método toString irá retornar por padrão [object Object]. Porém, o mesmo pode ser reescrito a fim de obter-se uma string do objeto. Exemplo: + +```javascript +const dados = { + nome: "Jõao", + idade: 16, +} + +console.log(dados.toString()) // [object Object] + +/** + * Sobrescrevendo o método toString + */ + +dados.toString = function() { + return `Me chamo ${this.nome} e tenho ${this.idade} anos.` +} + +console.log(dados.toString()) // Me chamo Jõao e tenho 16 anos. +``` + +## Imutabilidade + +### O que é imutabilidade? + +Imutabilidade é um paradigma de programação, usado principalmente em JavaScript, onde objetos e arrays se tornam imutáveis. Sendo assim, um array ou objeto não pode ser alterado diretamente ou sobrescrito, um novo objeto ou array deve ser criado com as modificações necessárias. + +### Por que aplicar este princípio? + +Este princípio é usado para prevenir bugs, facilitar testes e compreensão do código. Ajuda também a evitar erros quando programando em equipe. +Podemos aplicar imutabilidade através de bibliotecas como o Immutable.js. Ou também usando ferramentas da própria linguagem. + +### Imutabilidade em arrays + +Durante este capítulo, vimos que é possível adicionar, remover e alterar elementos de um array por meio de funções disponíveis na linguagem, como: pop, shift, push e unshift. Ao usar este tipo de função, estamos alterando diretamente o array e mudando seus valores em memória. + +Quando modificamos um array diretamente, perdemos a referência de memória do array original, o que torna difícil "debugar" o código, ou mesmo testar. De acordo com o princípio da imutabilidade, não devemos alterar o array original para não perdermos a referência. Devemos criar um novo array, atribuindo à este os valores do array original, para então podermos alterar os dados com a garantia de que preservamos a informação original. + +#### Aplicando imutabilidade em arrays + +Vamos adicionar um elemento ao array, aplicando imutabilidade. As regras são as seguintes: + +1. O array original tem de se manter intacto +2. Um novo array deve ser criado com o novo elemento + + +#### Exemplo 1 - Adicionando um elemento ao *fim* do array + +Exemplo **sem imutabilidade**: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +array.push(6) +console.log(array) // [0, 1, 2, 3, 4, 5, 6] +``` +> O array original foi modificado, logo não é imutável. + +Podemos usar a função concat para fazer a concatenação dos dados e retornar um novo array: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const novoArray = array.concat([6]) +console.log(novoArray) // [0, 1, 2, 3, 4, 5, 6] +``` + +> Apesar de podermos usar concat, a melhor forma atualmente é utilizar o spread operator como no exemplo abaixo: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const novoArray = [...array, 6] +console.log(novoArray) // [0, 1, 2, 3, 4, 5, 6] +``` + +#### Exemplo 1 - Adicionando um elemento ao *início* do array + +Exemplo **sem imutabilidade**: +```javascript +const array = [0, 1, 2, 3, 4, 5] +array.unshift(6) +console.log(array) // [6, 0, 1, 2, 3, 4, 5] +``` + +> O array original foi modificado, logo não é imutável. + +Podemos usar a função concat para concatenar o array original ao novo array: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const novoArray = [6].concat(array) +console.log(novoArray) // [6, 0, 1, 2, 3, 4, 5] +``` + +> Apesar de podermos usar concat, a melhor forma atualmente é utilizar o spread operator como no exemplo abaixo: + +```javascript +const array = [0, 1, 2, 3, 4, 5] +const novoArray = [6, ...array] +console.log(novoArray) // [6, 0, 1, 2, 3, 4, 5] +``` + +#### E se quisermos alterar um elemento do array? + +Vamos modificar o quarto elemento do array (posição 3), substituindo o valor `3` por `45`. + +Podemos usar as funções slice e concat para criar cópias do array e modificar o elemento desejado: + +```javascript +const array = [0, 1, 2, 3, 4, 5] + +const novoArray = array.slice(0, 3).concat(45).concat(array.slice(4)) + +console.log(novoArray) // [0, 1, 2, 45, 4, 5] +``` + +Usando spread operator: + +```javascript +const array = [0, 1, 2, 3, 4, 5] + +const novoArray = [...array.slice(0, 3), 45, ...array.slice(4)] + +console.log(novoArray) // [0, 1, 2, 45, 4, 5] +``` + +### Imutabilidade em objetos + +As regras para imutabilidade de objetos são as mesmas dos arrays: +1. O objeto original deve ser preservado. +2. Um novo objeto deve ser criado, com as propriedades modificadas. + +#### Adicionando ou removendo dados de um objeto + +Dado o objeto: + +```javascript +const dados = { + nome: "João", + idade: 16, +} +``` + +#### Vamos adicionar o email ao objeto. + +#### Sem aplicar imutabilidade: + +```javascript +const dados = { + nome: "João", + idade: 16, +} + +dados["email"] = "joão@ninguem.com" + +console.log(dados) // {nome: "João", "idade": 16, email: "joão@ninguem.com"} +``` + +#### Aplicando imutabilidade de forma clássica: + +```javascript +const dados = { + nome: "João", + idade: 16, +} + +const dadosModificados = { + nome: dados.nome, + idade: dados.idade, + email: "joão@ninguem.com" +} + +console.log(dadosModificados) // {nome: "João", "idade": 16, email: "joão@ninguem.com"} +``` + +#### Aplicando imutabilidade usando a função Objetct.assign. + +A função Object.assign irá criar um novo objeto com as propriedades dos dois objetos passados como parâmetro. + +```javascript +const dados = { + nome: "João", + idade: 16, +} + +const informacoesDeContato = { + email: "joão@ninguem.com" +} + +const dadosModificados = Object.assign(dados, informacoesDeContato) + +console.log(dadosModificados) // {nome: "João", "idade": 16, email: "joão@ninguem.com"} + +/** +* Note que também é possível criar o objeto na chamada da função +*/ + +const dadosModificados2 = Object.assign(dados, { + email: "joão@ninguem.com" +}) +``` + +#### Aplicando imutabilidade usando spread operator: + +```javascript +const dados = { + nome: "João", + idade: 16, +} + +const dadosModificados = { + ...dados, + email: "joão@ninguem.com" +} + +console.log(dadosModificados) // {nome: "João", "idade": 16, email: "joão@ninguem.com"} +``` + +#### Dado o objeto: + +```javascript +const dados = { + nome: "João", + idade: 16, + email: "joao@ninguem.com", +} +``` + +#### Vamos remover a propriedade idade do objeto. + +#### Sem aplicar imutabilidade: + +```javascript +const dados = { + nome: "João", + idade: 16, + email: "joao@ninguem.com", +} + +delete dados.idade + +console.log(dados) // {nome: "João", email: "joão@ninguem.com"} +``` + +#### Aplicando imutabilidade de forma clássica: + +```javascript +const dados = { + nome: "João", + idade: 16, + email: "joao@ninguem.com", +} + +const dadosModificados = { + nome: dados.nome, + email: dados.email +} + +console.log(dadosModificados) // {nome: "João", email: "joão@ninguem.com"} +``` + +### Aplicando imutabilidade usando desestruturação de objetos: + +```javascript +const dados = { + nome: "João", + idade: 16, + email: "joao@ninguem.com", +} + +const {nome, email} = dados + +const dadosModificados = { + nome, + email +} + +console.log(dadosModificados) // {nome: "João", email: "joão@ninguem.com"} +``` + +#### Modificando os dados de um objeto + +#### Vamos mudar a propriedade idade do objeto a seguir: + +```javascript +const dados = { + nome: "João", + idade: 16, + email: "joao@ninguem.com", +} +``` + +#### Sem aplicar imutabilidade + +```javascript +const dados = { + nome: "João", + idade: 16, + email: "joao@ninguem.com", +} + +dados.idade = 37 + +console.log(dados) // {nome: "João", "idade": 37, email: "joão@ninguem.com"} +``` + +### Aplicando imutabilidade de forma clássica + +```javascript +const dados = { + nome: "João", + idade: 16, + email: "joao@ninguem.com", +} + +const dadosModificados = { + nome: dados.nome, + idade: 37, + email: dados.email +} + +console.log(dadosModificados) // {nome: "João", "idade": 37, email: "joão@ninguem.com"} +``` + +#### Aplicando imutabilidade com spread operator + +```javascript +const dados = { + nome: "João", + idade: 16, + email: "joao@ninguem.com", +} + +const dadosModificados = { + ...dados, + idade: 37 +} + +console.log(dadosModificados) // {nome: "João", "idade": 37, email: "joão@ninguem.com"} +``` + +### Por fim + +Podemos aplicar imutabilidade de várias formas para garantirmos a integridade dos dados originais. Voce pode escolher a forma como aplicar, desde que aplique. Pois este paradigma evita bugs, facilita testes e a compreensão do código. + +> Obs: A forma como aplicamos imutabilidade aqui, não contém todos os conceitos como aplicados na biblioteca Immutable.js. + +## Conclusão +Ao fim deste capítulo, esperamos que você tenha entendido bem como usar arrays e objetos em JavaScript, pois são as estruturas de dados mais básicas da linguagem e as mais utilizadas. + +## Referências + +- Objetos - JavaScript | MDN. +- Arrays - JavaScript | MDN. +- Immutable.js. \ No newline at end of file diff --git a/src/markdown/m1/00-how-it-works.md b/src/markdown/frontend/m1/00-how-it-works.md similarity index 98% rename from src/markdown/m1/00-how-it-works.md rename to src/markdown/frontend/m1/00-how-it-works.md index 1260f5e..4a80aa3 100644 --- a/src/markdown/m1/00-how-it-works.md +++ b/src/markdown/frontend/m1/00-how-it-works.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/how-it-works" +slug: "/frontend/module-1/how-it-works" date: "2021-02-05" title: "00 - Como a internet funciona?" id: 0 -category: "module-1" +category: "frontend-module-1" --- # 00 - Como funciona a internet? diff --git a/src/markdown/m1/01-how-sites-are-built.md b/src/markdown/frontend/m1/01-how-sites-are-built.md similarity index 96% rename from src/markdown/m1/01-how-sites-are-built.md rename to src/markdown/frontend/m1/01-how-sites-are-built.md index 93271b0..b4c26a7 100644 --- a/src/markdown/m1/01-how-sites-are-built.md +++ b/src/markdown/frontend/m1/01-how-sites-are-built.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/how-sites-are-built" +slug: "/frontend/module-1/how-sites-are-built" date: "2021-02-05" title: "01 - Como os sites são construídos?" id: 1 -category: "module-1" +category: "frontend-module-1" --- # 01 - Como os sites são construídos? diff --git a/src/markdown/m1/02-html-hands-on.md b/src/markdown/frontend/m1/02-html-hands-on.md similarity index 98% rename from src/markdown/m1/02-html-hands-on.md rename to src/markdown/frontend/m1/02-html-hands-on.md index 36d61f7..1271b9d 100644 --- a/src/markdown/m1/02-html-hands-on.md +++ b/src/markdown/frontend/m1/02-html-hands-on.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/html-hands-on" +slug: "/frontend/module-1/html-hands-on" date: "2021-02-05" title: "02 - HTML na prática: Títulos, Textos, Listas, Imagens e Links" id: 2 -category: "module-1" +category: "frontend-module-1" --- # 02 - HTML na prática: Títulos, Textos, Listas, Imagens e Links diff --git a/src/markdown/m1/03-html-forms.md b/src/markdown/frontend/m1/03-html-forms.md similarity index 96% rename from src/markdown/m1/03-html-forms.md rename to src/markdown/frontend/m1/03-html-forms.md index b26b071..89135dc 100644 --- a/src/markdown/m1/03-html-forms.md +++ b/src/markdown/frontend/m1/03-html-forms.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/html-forms" +slug: "/frontend/module-1/html-forms" date: "2021-02-05" title: "03 - HTML na prática: Forms" id: 3 -category: "module-1" +category: "frontend-module-1" --- # 03 - HTML na prática: Forms diff --git a/src/markdown/m1/04-html-semantic.md b/src/markdown/frontend/m1/04-html-semantic.md similarity index 98% rename from src/markdown/m1/04-html-semantic.md rename to src/markdown/frontend/m1/04-html-semantic.md index 4a114d3..97bb045 100644 --- a/src/markdown/m1/04-html-semantic.md +++ b/src/markdown/frontend/m1/04-html-semantic.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/html-semantic" +slug: "/frontend/module-1/html-semantic" date: "2021-02-05" title: "04 - Semântica & Acessibilidade" id: 4 -category: "module-1" +category: "frontend-module-1" --- # 04 - Semântica & Acessibilidade diff --git a/src/markdown/m1/05-css-intro.md b/src/markdown/frontend/m1/05-css-intro.md similarity index 98% rename from src/markdown/m1/05-css-intro.md rename to src/markdown/frontend/m1/05-css-intro.md index 9da6a1c..95481bb 100644 --- a/src/markdown/m1/05-css-intro.md +++ b/src/markdown/frontend/m1/05-css-intro.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/css-intro" +slug: "/frontend/module-1/css-intro" date: "2021-02-05" title: "05 - CSS" id: 5 -category: "module-1" +category: "frontend-module-1" --- diff --git a/src/markdown/m1/06-css-selectors.md b/src/markdown/frontend/m1/06-css-selectors.md similarity index 97% rename from src/markdown/m1/06-css-selectors.md rename to src/markdown/frontend/m1/06-css-selectors.md index 19c3034..d8cd34f 100644 --- a/src/markdown/m1/06-css-selectors.md +++ b/src/markdown/frontend/m1/06-css-selectors.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/css-selectors" +slug: "/frontend/module-1/css-selectors" date: "2021-02-05" title: "06 - Seletores CSS" id: 6 -category: "module-1" +category: "frontend-module-1" --- diff --git a/src/markdown/m1/07-css-box-model.md b/src/markdown/frontend/m1/07-css-box-model.md similarity index 98% rename from src/markdown/m1/07-css-box-model.md rename to src/markdown/frontend/m1/07-css-box-model.md index b4ec304..9801859 100644 --- a/src/markdown/m1/07-css-box-model.md +++ b/src/markdown/frontend/m1/07-css-box-model.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/css-box-model" +slug: "/frontend/module-1/css-box-model" date: "2021-02-05" title: "07 - CSS: Box Model" id: 7 -category: "module-1" +category: "frontend-module-1" --- diff --git a/src/markdown/m1/08-css-display.md b/src/markdown/frontend/m1/08-css-display.md similarity index 97% rename from src/markdown/m1/08-css-display.md rename to src/markdown/frontend/m1/08-css-display.md index 9dba7cb..9c5f5c2 100644 --- a/src/markdown/m1/08-css-display.md +++ b/src/markdown/frontend/m1/08-css-display.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/css-display" +slug: "/frontend/module-1/css-display" date: "2021-02-05" title: "08 - CSS: Display" id: 8 -category: "module-1" +category: "frontend-module-1" --- diff --git a/src/markdown/m1/09-css-measures.md b/src/markdown/frontend/m1/09-css-measures.md similarity index 98% rename from src/markdown/m1/09-css-measures.md rename to src/markdown/frontend/m1/09-css-measures.md index a0e690c..2b92967 100644 --- a/src/markdown/m1/09-css-measures.md +++ b/src/markdown/frontend/m1/09-css-measures.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/css-measures" +slug: "/frontend/module-1/css-measures" date: "2021-02-05" title: "09 - CSS: Medidas" id: 9 -category: "module-1" +category: "frontend-module-1" --- diff --git a/src/markdown/m1/10-css-flexbox.md b/src/markdown/frontend/m1/10-css-flexbox.md similarity index 96% rename from src/markdown/m1/10-css-flexbox.md rename to src/markdown/frontend/m1/10-css-flexbox.md index 1f41775..79e3ecf 100644 --- a/src/markdown/m1/10-css-flexbox.md +++ b/src/markdown/frontend/m1/10-css-flexbox.md @@ -1,9 +1,9 @@ --- -slug: "/module-1/css-flexbox" +slug: "/frontend/module-1/css-flexbox" date: "2021-02-05" title: "10 - CSS: Flexbox" id: 10 -category: "module-1" +category: "frontend-module-1" --- diff --git a/src/markdown/m2/00-logica.md b/src/markdown/frontend/m2/00-logica.md similarity index 100% rename from src/markdown/m2/00-logica.md rename to src/markdown/frontend/m2/00-logica.md diff --git a/src/markdown/m2/01-simple-types.md b/src/markdown/frontend/m2/01-simple-types.md similarity index 100% rename from src/markdown/m2/01-simple-types.md rename to src/markdown/frontend/m2/01-simple-types.md diff --git a/src/markdown/m2/03-complex-types.md b/src/markdown/frontend/m2/03-complex-types.md similarity index 100% rename from src/markdown/m2/03-complex-types.md rename to src/markdown/frontend/m2/03-complex-types.md diff --git a/src/markdown/m2/04-loops.md b/src/markdown/frontend/m2/04-loops.md similarity index 100% rename from src/markdown/m2/04-loops.md rename to src/markdown/frontend/m2/04-loops.md diff --git a/src/markdown/m2/05-functions.md b/src/markdown/frontend/m2/05-functions.md similarity index 100% rename from src/markdown/m2/05-functions.md rename to src/markdown/frontend/m2/05-functions.md diff --git a/src/markdown/m2/06-switch.md b/src/markdown/frontend/m2/06-switch.md similarity index 100% rename from src/markdown/m2/06-switch.md rename to src/markdown/frontend/m2/06-switch.md diff --git a/src/markdown/m2/07-ES6.md b/src/markdown/frontend/m2/07-ES6.md similarity index 100% rename from src/markdown/m2/07-ES6.md rename to src/markdown/frontend/m2/07-ES6.md diff --git a/src/templates/blogTemplate.js b/src/templates/blogTemplate.js index 0b1988c..e7bbd56 100644 --- a/src/templates/blogTemplate.js +++ b/src/templates/blogTemplate.js @@ -1,18 +1,19 @@ -import React from "react"; -import { graphql, Link } from "gatsby"; -import styled from "styled-components"; -import RehypeReact from "rehype-react"; -import { - defineCustomElements as deckDeckGoHighlightElement -} from "@deckdeckgo/highlight-code/dist/loader"; +import React from "react" +import { graphql, Link } from "gatsby" +import styled from "styled-components" +import RehypeReact from "rehype-react" +import { defineCustomElements as deckDeckGoHighlightElement } from "@deckdeckgo/highlight-code/dist/loader" // Layout -import Layout from '../components/layout'; +import Layout from "../components/layout" + +// Components +import ToC from "../components/toc" // Assets -import arrow from '../assets/arrow.svg'; +import arrow from "../assets/arrow.svg" -deckDeckGoHighlightElement(); +deckDeckGoHighlightElement() const Article = styled.article` width: 85%; @@ -25,52 +26,52 @@ const Article = styled.article` margin-left: 0; padding: 0 2%; } -`; +` const Title = styled.h1` text-align: center; - font: 700 2.25rem 'Open Sans', sans-serif; -`; + font: 700 2.25rem "Open Sans", sans-serif; +` const SubTitle = styled.h2` margin: 3rem 0; - font: 700 1.5rem 'Open Sans', sans-serif; -`; + font: 700 1.5rem "Open Sans", sans-serif; +` const ThirdTitle = styled.h3` margin: 3rem 0; - font: 700 1.15rem 'Open Sans', sans-serif; -`; + font: 700 1.15rem "Open Sans", sans-serif; +` const FourthTitle = styled.h3` margin: 3rem 0; - font: 700 1rem 'Open Sans', sans-serif; -`; + font: 700 1rem "Open Sans", sans-serif; +` const Paragraph = styled.p` margin: 1.5rem 0; color: #505050; - font: 400 .95rem 'Open Sans', sans-serif; + font: 400 0.95rem "Open Sans", sans-serif; line-height: 1.75; -`; +` const Image = styled.img` display: block; max-width: 100%; object-fit: contain; margin: 4rem auto; -`; +` const List = styled.ol` margin: 2rem 0; padding: 0; - font: 400 1rem 'Open Sans', sans-serif; -`; + font: 400 1rem "Open Sans", sans-serif; +` const Item = styled.li` - margin: .75rem 0; - font: 400 1rem 'Open Sans', sans-serif; -`; + margin: 0.75rem 0; + font: 400 1rem "Open Sans", sans-serif; +` const Links = styled.nav` display: flex; @@ -78,18 +79,27 @@ const Links = styled.nav` width: 100%; margin: 1rem 0 4rem; - ${({ prev, next }) => prev && !next &&` + ${({ prev, next }) => + prev && + !next && + ` justify-content: flex-start; `} - ${({ prev, next }) => !prev && next &&` + ${({ prev, next }) => + !prev && + next && + ` justify-content: flex-end; `} - ${({ prev, next }) => prev && next &&` + ${({ prev, next }) => + prev && + next && + ` justify-content: space-around; `} -`; +` const NavItem = styled(Link)` position: relative; @@ -103,38 +113,57 @@ const NavItem = styled(Link)` box-shadow: rgb(116 129 141 / 10%) 0px 3px 8px 0px; color: #505050; text-decoration: none; - font: 400 .95rem 'Open Sans', sans-serif; + font: 400 0.95rem "Open Sans", sans-serif; - ${({ prev }) => prev &&` + ${({ prev }) => + prev && + ` justify-content: flex-start; `} - ${({ next }) => next &&` + ${({ next }) => + next && + ` justify-content: flex-end; text-align: right; `} &:hover { - color: #FFAC2D; + color: #ffac2d; } -`; +` const Icon = styled.img` position: absolute; top: 50%; width: 20px; height: 20px; - - ${({ prev }) => prev &&` + + ${({ prev }) => + prev && + ` left: 8px; transform: translateY(-50%) rotate(180deg); `} - ${({ next }) => next &&` + ${({ next }) => + next && + ` right: 8px; transform: translateY(-50%); `} -`; +` + +const Blockquote = styled.blockquote` + margin: 1.5em 10px; + padding: 0.5em 10px; + border-left: 10px solid #ccc; + background: #f9f9f9; + + p { + display: inline; + } +` const renderAst = new RehypeReact({ createElement: React.createElement, @@ -147,61 +176,55 @@ const renderAst = new RehypeReact({ img: Image, ol: List, li: Item, + blockquote: Blockquote, }, -}).Compiler; +}).Compiler export default function Template({ data, // this prop will be injected by the GraphQL query below. pageContext, - location + location, }) { const { markdownRemark } = data // data.markdownRemark holds your post data - const { htmlAst } = markdownRemark; + const { htmlAst } = markdownRemark return (
{renderAst(htmlAst)} - + {pageContext.showTableOfContents && ( + + )} + {pageContext.prev && ( - + {pageContext.prev.frontmatter.title} - + )} {pageContext.next && ( - + {pageContext.next.frontmatter.title} - + )}
) -}; +} export const pageQuery = graphql` query($slug: String!) { markdownRemark(frontmatter: { slug: { eq: $slug } }) { html htmlAst + headings { + id + depth + value + } frontmatter { date(formatString: "MMMM DD, YYYY") slug @@ -209,4 +232,4 @@ export const pageQuery = graphql` } } } -`; \ No newline at end of file +` diff --git a/yarn.lock b/yarn.lock index f941ad9..6fcdb1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6365,6 +6365,17 @@ gatsby-recipes@^0.8.0: xstate "^4.9.1" yoga-layout-prebuilt "^1.9.6" +gatsby-remark-autolink-headers@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/gatsby-remark-autolink-headers/-/gatsby-remark-autolink-headers-4.2.0.tgz#eb4b2c92eb5c4eb5243b0c817018c491babfb5f2" + integrity sha512-v3YVeHMFGsskkUsdMY+cAtYAXPgy6ccY1bET0cmAjizWhxObRIXnaJw4uV78EusqDPMfu9kwYZnhfiGeMQopXg== + dependencies: + "@babel/runtime" "^7.12.5" + github-slugger "^1.3.0" + lodash "^4.17.21" + mdast-util-to-string "^2.0.0" + unist-util-visit "^2.0.3" + gatsby-remark-highlight-code@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/gatsby-remark-highlight-code/-/gatsby-remark-highlight-code-2.1.1.tgz#77364643aae4c3b5ebe0b44231de27057eee0aec" @@ -6721,7 +6732,7 @@ github-from-package@0.0.0: resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= -github-slugger@^1.2.1: +github-slugger@^1.2.1, github-slugger@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.3.0.tgz#9bd0a95c5efdfc46005e82a906ef8e2a059124c9" integrity sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q== @@ -8760,6 +8771,11 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "^3.0.0" +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" @@ -8775,6 +8791,11 @@ lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + logalot@^2.0.0, logalot@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/logalot/-/logalot-2.1.0.tgz#5f8e8c90d304edf12530951a5554abb8c5e3f552" @@ -11280,6 +11301,14 @@ react-refresh@^0.8.3: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== +react-scroll@^1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/react-scroll/-/react-scroll-1.8.2.tgz#68e35b74ae296c88e7863393c9fd49f05afa29f5" + integrity sha512-f2ZEG5fsPbPTySI9ekcFpETCcNlqbmwbQj9hhzYK8tkgv+PA8APatSt66o/q0KSkDZxyT98ONTtXp9x0lyowEw== + dependencies: + lodash.throttle "^4.1.1" + prop-types "^15.7.2" + react-side-effect@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.0.tgz#1ce4a8b4445168c487ed24dab886421f74d380d3" @@ -13613,7 +13642,7 @@ unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.3.0, unist dependencies: unist-util-visit-parents "^2.0.0" -unist-util-visit@^2.0.0, unist-util-visit@^2.0.2: +unist-util-visit@^2.0.0, unist-util-visit@^2.0.2, unist-util-visit@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==