Apresentando Shoelace, uma biblioteca UX independente de estrutura baseada em componentes PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Apresentando Shoelace, uma biblioteca UX baseada em componentes independente de framework

Este é um post sobre Cadarço, uma biblioteca de componentes por Cory La Viska, mas com uma reviravolta. Ele define todos os seus componentes padrão de UX: guias, modais, acordeões, preenchimentos automáticos e muito muito mais. Eles ficam lindos fora da caixa, são acessíveis e totalmente personalizáveis. Mas ao invés de criar esses componentes em React, ou Solid, ou Svelte, etc., ele os cria com Componentes da Web; isso significa que você pode usá-los com qualquer estrutura.

Algumas coisas preliminares

Os Web Components são ótimos, mas atualmente existem alguns pequenos problemas a serem observados.

Reagir

Eu disse que eles funcionam em qualquer framework JavaScript, mas como escrevi antes, o suporte do React para Web Components é atualmente pobre. Para resolver isso, Shoelace realmente wrappers criados apenas para reagir.

Outra opção, que eu pessoalmente gosto, é criar um componente React fino que aceite o nome da tag de um Web Component e todos os seus atributos e propriedades, então faça o trabalho sujo de lidar com as deficiências do React. falei sobre essa opção em uma postagem anterior. Eu gosto desta solução porque ela foi projetada para ser excluída. O problema de interoperabilidade do Web Component está atualmente corrigido na ramificação experimental do React, portanto, uma vez enviado, qualquer componente interoperável do Web Component thin que você estiver usando pode ser pesquisado e removido, deixando você com usos diretos do Web Component, sem nenhum wrapper do React.

Renderização do lado do servidor (SSR)

O suporte para SSR também é ruim no momento da redação deste artigo. Em teoria, existe algo chamado Shadow DOM declarativo (DSD) que habilitaria o SSR. Mas o suporte ao navegador é mínimo e, em qualquer caso, o DSD realmente requer suporte do servidor trabalhar direito, o que significa Próximo, Remix, ou o que você usar no servidor precisará se tornar capaz de algum tratamento especial.

Dito isso, existem outras maneiras de fazer com que os Web Components apenas trabalhe com um aplicativo da Web que é SSR com algo como Next. A versão curta é que os scripts que registram seus Web Components precisam ser executados em um script de bloqueio antes que sua marcação seja analisada. Mas isso é assunto para outro post.

Obviamente, se você estiver criando qualquer tipo de SPA renderizado pelo cliente, isso não será um problema. É com isso que trabalharemos neste post.

Vamos começar

Como quero que este post se concentre em cadarço e em sua natureza de componente da Web, usarei Esbelto para tudo. Eu também vou usar isso Projeto Stackblitz para demonstração. Construiremos esta demonstração juntos, passo a passo, mas sinta-se à vontade para abrir esse REPL a qualquer momento para ver o resultado final.

Mostrarei como usar cadarço e, mais importante, como personalizá-lo. Nós vamos falar sobre DOMs de sombra e quais estilos eles bloqueiam do mundo exterior (assim como quais eles não bloqueiam). Também falaremos sobre o ::part Seletor de CSS — o que pode ser totalmente novo para você — e veremos até como o Shoelace nos permite substituir e personalizar suas várias animações.

Se você achar que gosta de Shoelace depois de ler este post e quiser experimentá-lo em um projeto React, meu conselho é usar um invólucro como mencionei na introdução. Isso permitirá que você use qualquer um dos componentes do Shoelace, e ele pode ser removido completamente assim que o React enviar as correções do Web Component que eles já possuem (procure por isso na versão 19).

Apresentando cadarço

Cadarço tem bastante detalhado instruções de instalação. Na sua forma mais simples, você pode despejar e tags em seu documento HTML, e pronto. No entanto, para qualquer aplicativo de produção, você provavelmente desejará importar seletivamente apenas o que deseja, e também há instruções para isso.

Com o Shoelace instalado, vamos criar um componente Svelte para renderizar algum conteúdo e, em seguida, seguir as etapas para personalizá-lo totalmente. Para escolher algo bastante não trivial, usei as guias e os componentes de diálogo (comumente chamados de modal). Aqui está uma marcação retirado em grande parte dos documentos:


  General
  Custom
  Advanced
  Disabled

  This is the general tab panel.
  This is the custom tab panel.
  This is the advanced tab panel.
  This is a disabled tab panel.



  Hello World!
  



Isso renderiza algumas guias bonitas e estilizadas. O sublinhado na guia ativa até anima bem e desliza de uma guia ativa para a próxima.

Abas padrão no cadarço

Não vou perder seu tempo percorrendo cada centímetro das APIs que já estão bem documentadas no site da Shoelace. Em vez disso, vamos ver a melhor forma de interagir e personalizar totalmente esses Web Components.

Interagindo com a API: métodos e eventos

Chamar métodos e assinar eventos em um Web Component pode ser um pouco diferente do que você está acostumado com sua estrutura normal de escolha, mas não é muito complicado. Vamos ver como.

Tabs

O componente de guias () tem um show método, que mostra manualmente uma guia específica. Para chamar isso, precisamos obter acesso ao elemento DOM subjacente de nossas guias. Em Svelte, isso significa usar bind:this. Em React, seria um ref. E assim por diante. Já que estamos usando o Svelte, vamos declarar uma variável para nosso tabs instância:


  let tabs;

… e vinculá-lo:

Agora podemos adicionar um botão para chamá-lo:

É a mesma ideia para eventos. Há um sl-tab-show evento que é acionado quando uma nova guia é mostrada. Nós poderíamos usar addEventListener no nosso tabs variável, ou podemos usar Svelte on:event-name atalho.

 console.log(e)}>

Isso funciona e registra os objetos de evento à medida que você mostra guias diferentes.

Meta do objeto de evento mostrado no DevTools.
Apresentando Shoelace, uma biblioteca UX baseada em componentes independente de framework

Normalmente, renderizamos as guias e deixamos o usuário clicar entre elas, então esse trabalho geralmente nem é necessário, mas está lá se você precisar. Agora vamos tornar o componente de diálogo interativo.

diálogo

O componente de diálogo () leva um open prop que controla se a caixa de diálogo está… aberta. Vamos declará-lo em nosso componente Svelte:


  let tabs;
  let open = false;

Ele também tem um sl-hide evento para quando a caixa de diálogo estiver oculta. Vamos passar nosso open prop e ligar para o hide evento para que possamos redefini-lo quando o usuário clicar fora do conteúdo da caixa de diálogo para fechá-lo. E vamos adicionar um manipulador de cliques a esse botão fechar para definir nosso open prop para false, que também fecharia a caixa de diálogo.

 open = false}>
  Hello World!
  

Por fim, vamos conectar nosso botão de diálogo aberto:

E é isso. A interação com a API de uma biblioteca de componentes é mais ou menos direta. Se isso fosse tudo o que este post fez, seria muito chato.

Mas Shoelace — sendo construído com Web Components — significa que algumas coisas, particularmente estilos, funcionarão de maneira um pouco diferente do que estamos acostumados.

Personalize todos os estilos!

Até o momento, Shoelace ainda está na versão beta e o criador está considerando alterar alguns estilos padrão, possivelmente até removendo alguns padrões completamente para que eles não substituam mais os estilos do seu aplicativo host. Os conceitos que abordaremos são relevantes de qualquer maneira, mas não se surpreenda se algumas das especificidades do cadarço que mencionei forem diferentes quando você for usá-lo.

Por mais legais que sejam os estilos padrão do Shoelace, podemos ter nossos próprios designs em nosso aplicativo da web e queremos que nossos componentes de UX correspondam. Vamos ver como faríamos isso em um mundo de Web Components.

Nós não vamos tentar realmente melhorar nada. O criador do Shoelace é um designer muito melhor do que eu jamais serei. Em vez disso, veremos apenas como alterar coisas, para que você possa se adaptar aos seus próprios aplicativos da web.

Um tour rápido pelos Shadow DOMs

Dê uma olhada em um desses cabeçalhos de guia em seu DevTools; deve ser algo assim:

A marcação do componente de guias mostrada no DevTools.
Apresentando Shoelace, uma biblioteca UX baseada em componentes independente de framework

Nosso elemento tab criou um div recipiente com um .tab e .tab--active classe, e um tabindex, além de exibir o texto que inserimos para essa guia. Mas observe que ele está dentro de um raiz da sombra. Isso permite que os autores do Web Component adicionem sua própria marcação ao Web Component, ao mesmo tempo em que fornecem um local para o conteúdo we providenciar. Observe o elemento? Isso basicamente significa “colocar qualquer conteúdo que o usuário renderizou entre as tags do Web Component SUA PARTICIPAÇÃO FAZ A DIFERENÇA. "

Então o O componente cria uma raiz de sombra, adiciona algum conteúdo a ela para renderizar o cabeçalho da guia bem estilizado junto com um espaço reservado () que renderiza nosso conteúdo dentro.

Estilos encapsulados

Um dos problemas clássicos e mais frustrantes no desenvolvimento web sempre foram os estilos cascata para lugares onde não os queremos. Você pode se preocupar que quaisquer regras de estilo em nosso aplicativo que especifiquem algo como div.tab interferiria com essas guias. Acontece que isso não é um problema; raízes de sombra encapsulam estilos. Estilos de fora da raiz sombra não afetam o que está dentro da raiz sombra (com algumas exceções sobre as quais falaremos) e vice-versa.

As exceções a isso são estilos herdáveis. Você, é claro, não precisa aplicar um font-family estilo para cada elemento em seu aplicativo da web. Em vez disso, você pode especificar seu font-family uma vez, em :root or html e tê-lo herdar em todos os lugares abaixo dele. Essa herança, de fato, também perfurará a raiz da sombra.

Propriedades personalizadas CSS (muitas vezes chamadas de “variáveis ​​CSS”) são uma exceção relacionada. Uma raiz sombra pode absolutamente ler uma propriedade CSS definida fora da raiz sombra; isso se tornará relevante em um momento.

A ::part seletor

E os estilos que não herdar. E se quisermos personalizar algo como cursor, que não herda, em algo dentro da raiz sombra. Estamos sem sorte? Acontece que não somos. Dê outra olhada na imagem do elemento tab acima e sua raiz de sombra. Observe o part atributo no div? Isso permite que você direcione e estilize esse elemento de fora da raiz da sombra usando o ::part seletor. Vamos percorrer um exemplo é um pouco.

Substituindo estilos de cadarço

Vamos ver cada uma dessas abordagens em ação. A partir de agora, muito dos estilos de cadarço, incluindo fontes, recebem valores padrão das propriedades personalizadas do CSS. Para alinhar essas fontes com os estilos do seu aplicativo, substitua as props personalizadas em questão. Ver os documentos para obter informações sobre quais variáveis ​​CSS o Shoelace está usando, ou você pode simplesmente inspecionar os estilos em qualquer elemento no DevTools.

Herdando estilos por meio da raiz de sombra

Abra o app.css arquivo no src diretório do Projeto StackBlitz. No :root seção na parte inferior, você deve ver um letter-spacing: normal; declaração. Desde o letter-spacing propriedade é herdável, tente definir um novo valor, como 2px. Ao salvar, todo o conteúdo, incluindo os cabeçalhos das guias definidos na raiz sombra, serão ajustados de acordo.

Quatro cabeçalhos de guias horizontais com o primeiro ativo em azul com conteúdo plqceholder contido em um painel abaixo. O texto é ligeiramente esticado com espaçamento entre letras.
Apresentando Shoelace, uma biblioteca UX baseada em componentes independente de framework

Sobrescrevendo variáveis ​​CSS Shoelace

A componente lê um --indicator-color Propriedade customizada CSS para o sublinhado da guia ativa. Podemos substituir isso com algum CSS básico:

sl-tab-group {
  --indicator-color: green;
}

E assim, agora temos um indicador verde!

Quatro cabeçalhos de guias horizontais com o primeiro ativo com texto azul e um sublinhado verde.
Apresentando Shoelace, uma biblioteca UX baseada em componentes independente de framework

Peças de consulta

Na versão do Shoelace que estou usando agora (2.0.0-beta.83), qualquer aba não desativada tem um pointer cursor. Vamos mudar isso para um cursor padrão para a guia ativa (selecionada). Já vimos que o elemento adiciona um part="base" atributo no contêiner para o cabeçalho da guia. Além disso, a guia selecionada atualmente recebe um active atributo. Vamos usar esses fatos para direcionar a guia ativa e alterar o cursor:

sl-tab[active]::part(base) {
  cursor: default;
}

E é isso!

Personalização de animações

Para uma cereja no topo do bolo metafórico, vamos ver como Shoelace nos permite personalizar animações. Cadarço usa o API de animações da web, e expõe uma setDefaultAnimation API para controlar como diferentes elementos animam suas várias interações. Veja os documentos para detalhes, mas como exemplo, veja como você pode alterar a animação de diálogo padrão do Shoelace de expandir para fora e encolher para dentro, para animar a partir do topo e descer enquanto se esconde.

import { setDefaultAnimation } from "@shoelace-style/shoelace/dist/utilities/animation-registry";

setDefaultAnimation("dialog.show", {
  keyframes: [
    { opacity: 0, transform: "translate3d(0px, -20px, 0px)" },
    { opacity: 1, transform: "translate3d(0px, 0px, 0px)" },
  ],
  options: { duration: 250, easing: "cubic-bezier(0.785, 0.135, 0.150, 0.860)" },
});
setDefaultAnimation("dialog.hide", {
  keyframes: [
    { opacity: 1, transform: "translate3d(0px, 0px, 0px)" },
    { opacity: 0, transform: "translate3d(0px, 20px, 0px)" },
  ],
  options: { duration: 200, easing: "cubic-bezier(0.785, 0.135, 0.150, 0.860)" },
});

Esse código está no App.svelte Arquivo. Comente para ver a animação padrão original.

Resumindo

Shoelace é uma biblioteca de componentes incrivelmente ambiciosa construída com Web Components. Como os Web Components são independentes de framework, eles podem ser usados ​​em qualquer projeto, com qualquer framework. Com novas estruturas começando a surgir com características de desempenho incríveis e também facilidade de uso, a capacidade de usar widgets de experiência do usuário de qualidade que não estão vinculados a nenhuma estrutura nunca foi tão atraente.

Carimbo de hora:

Mais de Truques CSS