Como criar aplicativos para terminal com React
Primeiramente, gostaria de agredecer mais uma fez a todos os que estão interessados no projeto do tabnews em CLI. No momento que estou escrevendo isto, meu post é o primeiro a aparecer na aba "Relevantes", e o repositório do projeto já está com 13 estrelas.
Ainda hoje pretendo fazer um post mostrando melhor a ferramenta.
Introdução
Atendando a pedidos, vou fazer um mini overview do Ink, uma biblioteca que permite criar aplicativos para terminal com React.
Seu funcionamento é bem simples. Assim como o React Native, o Ink fornece componentes própios para serem usados. Também existem alguns hooks, para coisas como receber entrada do usuário ou executar alguma ação.
Segundo o README do Ink, até onde se tenha conhecimento, todas as funcionalidades do React (o React "puro", obviamente), são suportadas. Então podemos utilizar todo o poder e agilidade que temos na web dentro do terminal. O Ink também utiliza o Yoga, uma biblioteca que permite construir layouts para terminla utilizando flexbox. Então essa parte de construção de layouts também é bem parecida como fazemos para a web.
Mas lambrando que o Ink roda com o Node, então algumas coisas são diferentes da web. Consequentente, algumas bibliotecas podem não funcionar. Mas qualquer biblioteca que não utilize algum recurso própio do javascript de navegador deve funcionar. Nesse projeto por exemplo, eu utilizei o SWR.
Para utilizar o Ink, basta chamar a função render
passando o seu componente para ela:
import React from "react"
import { render, Text } from "ink"
const Examplo: React.FC = () => {
return (
<>
<Text bold>Olá mundo!</Text>
</>
)
}
render(<Examplo />)
Principais componentes
<Text>
Componente utilizado para exibir textos, qualquer texto precisa ser filho desse componente. Você pode passar alguns parâmetros para por exemplo mudar a cor do texto, mudar a cor de fundo, ou deixar o texto em negrito, itálico, sublinhado ou riscado.
Exemplo:
import React from "react"
import { render, Text } from "ink"
const Examplo: React.FC = () => {
return (
<>
<Text color="green">Verde</Text>
<Text color="black" backgroundColor="white">Preto com fundo branco</Text>
<Text bold>Negrito</Text>
<Text italic>Itálico</Text>
<Text underline>Sublinhado</Text>
<Text strikethrough>Riscado</Text>
<Text inverse>Cor e cor de fundo invertida</Text>
</>
)
}
render(<Examplo />)
Resultado:
<Box>
O componente box funciona como um <div style="display: flex">
no navegador. E fornece várias opções, como ajustar o tamanho, a margem, o padding, o alinhamento, etc. Também é possível ajustar a borda:
<Box flexDirection="column">
<Box>
<Box borderStyle="single" marginRight={2}>
<Text>single</Text>
</Box>
<Box borderStyle="double" marginRight={2}>
<Text>double</Text>
</Box>
<Box borderStyle="round" marginRight={2}>
<Text>round</Text>
</Box>
<Box borderStyle="bold">
<Text>bold</Text>
</Box>
</Box>
<Box marginTop={1}>
<Box borderStyle="singleDouble" marginRight={2}>
<Text>singleDouble</Text>
</Box>
<Box borderStyle="doubleSingle" marginRight={2}>
<Text>doubleSingle</Text>
</Box>
<Box borderStyle="classic">
<Text>classic</Text>
</Box>
</Box>
</Box>
Principais hooks
useInput
Serve para obter a entrada do usuário (eventos do teclado)
import { useInput } from "ink"
const Input = () => {
useInput((input, key) => {
if (input === "q") {
// Sair do programa
}
if (key.leftArrow) {
// Seta para a esquerda pressionada
}
})
return ...
}
Essa postagem foi apenas para dar uma visão geral. Para se aprofundar, dê uma olhada na documentação do Ink.