DEV Community

Diogo Neves
Diogo Neves

Posted on

BemtvJS - Visão geral

BemtvJS:
Reatividade baseada em template,
Brackethtml,
CSS-In-Template,
SuperComponent,
CSS-In-JS,
Hooks,
DOM events,
CompVars,
Funções de transformação,
Roteamento automático,
e Divisão de código.

BemtvJS é uma biblioteca de UI que adota uma abordagem contrária à maioria das bibliotecas e estruturas. Normalmente as ferramentas de UI observam o estado (variáveis ​​e propriedades) e quando ele muda, atualiza o template e aplica o resultado ao DOM, a Bemtv faz o próprio template verificar se o estado mudou e se atualizar.

Brackethtml

Brackethtml é uma linguagem de marcação incorporada ao Bemtv que permite reduzir a redundância do HTML, suportá-lo e se parecer com ele:

const btn = `button[Click me!]`;
Enter fullscreen mode Exit fullscreen mode

Brackethtml também permite a inserção de CSS-In-Template, que simplesmente é CSS-In-JS inserido diretamente no template:

const btn = `button[color:blue; ~ Click me!]`;
Enter fullscreen mode Exit fullscreen mode

SuperComponent

Criando um componente:

import { _ } from "bemtv";

_`App`();
Enter fullscreen mode Exit fullscreen mode

O valor retornado é chamado de SuperComponent. Internamente, cada vez que o componente é usado, é criada uma instância leve que gerencia essa nova renderização do componente.

Essas instâncias assumem o “controle”, sempre que ocorre uma ação nelas, onde a reação é a execução de um callback passado anteriormente, normalmente em Hooks e eventos do DOM.

CSS-In-JS

Além do estilo que pode ser aplicado diretamente no template, uma ótima opção é utilizar o método css():

import { _ } from "bemtv";

const { css, template } = _`App`();

css`
  color: blue;
  font-size: 20px;
`;

template`h1[Hello world!]`;
Enter fullscreen mode Exit fullscreen mode

Hooks

Cada instância do componente passa por uma série de etapas, podemos executar funções chamadas hooks em cada uma dessas etapas:

import { _ } from "bemtv";

const { onInit, onMount, onUpdate, onUnmount } = _`App`();

onInit(() => {
  // Chamada(apenas uma vez) quando a instância é inicializada.
});
onMount(() => {
  // Chamada(apenas uma vez) depois que o template do componente foi montado no DOM.
});
onUpdate(() => {
  // Chamada após a atualização do template ser aplicada ao DOM.
});
onUnmount(() => {
  // Chamado(apenas uma vez) depois que o componente é removido/desmontado do template em que estava.
});
Enter fullscreen mode Exit fullscreen mode

Eventos do DOM

Podemos usar eventos DOM diretamente do SuperComponent:

import { _ } from "bemtv";

const { click$, mouseover$ } = _`App`();

click$(() => {}, { capture: true });

mouseover$(() => console.log("Hey!"));
Enter fullscreen mode Exit fullscreen mode

Variáveis de ​​componentes(compVars)

Podemos passar um objeto como argumento para o componente, este objeto é chamado compVars e todas as propriedades adicionadas a ele são isoladas a cada renderização do componente, incluindo estruturas de dados como Array, Set, Map e Object.

Conhecendo nossas “variáveis”, a Bemtv consegue fornecer açúcares sintáticos realmente doces.

Um exemplo é que podemos adicionar o caminho para a propriedade diretamente no template usando o símbolo $:

import { _ } from "bemtv";

const { template, render } = _`Message`({ message: "Hey!" });

template`button[Clicked: $message ]`;

render();
Enter fullscreen mode Exit fullscreen mode

Se tivermos uma propriedade com o mesmo nome de um atributo HTML podemos usar o símbolo @ para informar a Bemtv para tratar a propriedade como chave e valor:

import { _ } from "bemtv";

const { template, render } = _`Img`({
  src: "avatar.png",
  alt: "My avatar",
});

template`img[ @src @alt ]`;

render();
Enter fullscreen mode Exit fullscreen mode

Funções de transformação

As funções de transformação nos permitem adicionar uma “marca” a uma estrutura de dados e informa ao Bemtv para transformar a estrutura de dados somente quando necessário, isso nos permite focar apenas na estrutura de dados.

import { tFn } from "bemtv";

const tListJoin = tFn((list) => list.join(" br[] "));
Enter fullscreen mode Exit fullscreen mode

O exemplo acima cria uma função de transformação que pode ser usada com listas, e quando a lista é solicitada pelo template ele executa essa função e adiciona o resultado ao template:

import { _, tFn} from "bemtv";

const tListJoin = tFn((list) => list.join(" br[] "));

const { template } = _`List`({
  list: tListJoin(["user1", "user2", "user3"]),
});

template`div[Users: $list ]
Enter fullscreen mode Exit fullscreen mode

Sempre que esta lista for alterada (ex: $.list.push(item)), A Bemtv detectará e usará a função de transformação novamente e renderizará a alteração.

Roteamento automático

A Bemtv utiliza um inovador sistema de criação automática de rotas, isso é possível porque os componentes podem se comportar como rotas/páginas.

O Bemtv é capaz de descobrir automaticamente quando um componente “normal” também deve ser tratado como uma rota:

Um componente normal:

import { _ } from "bemtv";

const { template } = _`AboutUs`();

template`We are cool!`;
Enter fullscreen mode Exit fullscreen mode

O componente responsável por rendrizar o App:

import { _ } from "bemtv";

const { template, render } = _`App`();

template`
      Welcome!  br[]br[]

      #[] br[]br[]

      #AboutUs[ Link to about us ]`;

render();
Enter fullscreen mode Exit fullscreen mode

O segundo componente apresenta a utilização do simbolo #[], é dentro dele que as rotas são renderizadas.

Observe o #AboutUs[...], é aqui que a mágica acontece.
Primeiro, a Bemtv lerá o template de componente App e descobrirá que o componente AboutUs
também é uma rota (graças ao # antes dele), e quando o template for renderizado, tudo dentro do componente #AboutUs[...] será envolvido em uma tag a com o atributo href apontando para a rota.

O endereço da rota será o nome do componente em kebab-case: /about-us.

Quando o usuário clicar no link, o componente AboutUs será renderizado em #[].

A Bemtv também descobrirá que o componente é uma rota sempre que acessarmos algum método do componente que se destine a rotas, mesmo que não seja chamado(graças a Proxies).

Dividindo o Código (Code-Splitting)

Para automatizar o processo de importação de componentes, a Bemtv oferece a função autoImportComponents() que aceita um objeto onde o nome das propriedades deve ser o nome dos componentes e seus valores devem ser uma função que importa o componente usando importações dinâmicas(dynamic import):

import { autoImportComponents } from "bemtv";

autoImportComponents({
  Counter() {
    import("./components/Counter");
  },
});
Enter fullscreen mode Exit fullscreen mode

A Bemtv fará a importação do componente assim que componente for utilizado em um template, porém, irá ignorar o componente até o momento em que estiver disponível.

Fechamento

Essas não são todas as funcionalidades oferecidas pela Bemtv, por exemplo, não estamos falando do inovador sistema de compartilhamento de dados entre os componentes.
Você pode conferir tudo no repositório do projeto:

https://github.com/diogoneves07/bemtvjs.

Bemtv é um projeto recente, você é bem-vindo para fazer parte da construção desta ferramenta.

Qualquer dúvida ou se quiser contribuir com o projeto, pode entrar em contato comigo ou abrir uma PR.

Obrigado por chegar até aqui!

Top comments (0)