- Jelly UI v1.1 é uma biblioteca de Web Components sem dependências que combina controles de formulário reais com efeitos de física de corpo macio e gelatinoso, oferecendo 40 elementos personalizados
- A instalação é feita com um único script de módulo e há suporte a modo escuro, acompanhamento automático do tema do sistema operacional, alteração da cor de destaque e layout RTL, da direita para a esquerda
- Os botões usam um
<button>nativo, e os sliders usam uma entradarangeoculta para manter a semântica nativa para operação por teclado, leitores de tela e participação em formulários - De checkboxes e campos de entrada a toasts, abas e diálogos, vários elementos recebem animações táteis como pressionar, esticar, ondular e quicar
- Com tokens de cor WCAG AA e padrões ARIA integrados, permite criar interfaces de produto acessíveis mantendo efeitos visuais suaves
Instalação e tema
- O Jelly UI pode ser usado sem dependências, com 40 elementos personalizados e apenas uma tag
<script type="module"><script type="module" src="https://jelly-ui.com/package.js"></script> <jelly-theme mode="auto"> <jelly-button variant="mint">Publish</jelly-button> </jelly-theme> <jelly-theme>é um provedor de tema que aplica tokens de design de forma limitada à subárvoremodeaceitaauto,lightedark, permitindo seguir as configurações do sistema operacional ou forçar um tema específicoaccentpermite redefinir a cor de destaque
- As variações de cor comuns são
azure,rose,amber,mint,graphite,platinumewhite; os tamanhos são principalmentesmall,mediumelarge
Botões e elementos de ação
<jelly-button>é um botão em formato de cápsula que inclui internamente um<button>nativo real para dar suporte a teclado e leitores de tela- Permite configurar cor, tamanho, formatos
pillesquare, desativação e layout em bloco
- Permite configurar cor, tamanho, formatos
<jelly-icon-button>é um botão quadrado ou circular ajustado para um único ícone- O atributo
labeldefine o nome reconhecido por leitores de tela
- O atributo
Controles de entrada de formulário
<jelly-checkbox>participa de formulários, aceitacheckede estado indeterminado (indeterminate), e o quadrado gelatinoso salta quando o estado muda<jelly-input>é um campo de entrada de uma linha paratext,emailepassword- Ao receber foco, a superfície se eleva e a borda aparece; a cada entrada, uma onda se espalha a partir da posição do cursor
- Aceita
disabledereadonly
<jelly-label>se associa ao controle viafor- Ao clicar, leva o foco ao destino, o texto do rótulo se torna o nome acessível, e é possível definir obrigatoriedade e tamanho
<jelly-otp>é uma entrada de código de uso único que oferece uma caixa para cada dígito- Trata digitação, Backspace, teclas de seta e colagem, além de permitir configurar comprimento, cor, tamanho e desativação
<jelly-radio>forma um grupo entre itens que compartilham o mesmonamena mesma raiz- Aceita navegação por teclas de seta com
tabindexmóvel e considerando a direção do documento
- Aceita navegação por teclas de seta com
<jelly-radio-group>é um contêinerradiogroupcom rótulo parajelly-radio- Oferece legenda, layout de fluxo horizontal ou vertical e propagação de tamanho para os elementos filhos
<jelly-range>é um slider de dois handles para escolher um intervalo entre valor mínimo e máximo- Aplica
role="slider", foco e ARIA aos dois controles; ao arrastar, os handles gelatinosos são pressionados
- Aplica
<jelly-segmented>é uma trilha em formato de cápsula com opções mutuamente exclusivas- O indicador de seleção se comporta como uma pílula gelatinosa que se inclina e se estica ao se mover entre os segmentos
<jelly-select>é um dropdown integrado a formulários que usa os padrões ARIAcomboboxelistbox- Tanto o gatilho quanto o painel de opções são compostos por superfícies de corpo macio
- O painel se expande a partir do campo e, se não houver espaço suficiente abaixo, muda para cima
<jelly-slider>é um slider para escolher um único valor- Uma entrada
rangenativa oculta cuida da semântica e da participação no formulário, enquanto na tela aparece um handle gelatinoso pressionável
- Uma entrada
<jelly-switch>é um switch arrastável: o handle se estica como uma gota líquida, e as cores de desligado/ligado alternam entre si<jelly-textarea>cresce automaticamente entre alturas mínima e máxima conforme a entrada de várias linhas- A superfície também se estica de acordo com a altura; ao digitar, uma onda surge na posição do cursor, e há suporte a
disabledereadonly
- A superfície também se estica de acordo com a altura; ao digitar, uma onda surge na posição do cursor, e há suporte a
Estado e feedback
<jelly-alert>é um banner com quatro tons —info,success,warningedanger— e um botão de fechar opcional<jelly-badge>é um pequeno elemento usado para badges, tags e indicadores de status, que salta quando o texto muda- Permite configurar preenchimento ou contorno, formatos de pílula ou quadrado, e comportamentos
liveeinstant
- Permite configurar preenchimento ou contorno, formatos de pílula ou quadrado, e comportamentos
<jelly-progress>é uma barra de progresso cuja parte frontal do preenchimento oscila conforme o avanço- No modo indeterminado, o bloco quica entre as duas paredes
<jelly-skeleton>é um placeholder de carregamento que balança suavemente como se respirasse, em vez de brilhar- Aceita os formatos
line,rectecircle
- Aceita os formatos
<jelly-spinner>oferece um indicadordots, em forma de massa viscosa que se move entre três pontos, e umblob, que gira enquanto muda de forma<jelly-toaster>gerencia notificações toast que aparecem e desaparecem a partir da extremidade inline- Normalmente é chamado pelo helper
jellyToast('Saved!', { tone: 'success' }) - Ao definir
position="bottom"no elemento posicionado, a pilha de notificações cresce para cima
- Normalmente é chamado pelo helper
Superfícies de conteúdo
<jelly-accordion>agrupa vários itens<jelly-collapsible>- No modo
single, quando um item é aberto, os demais se fecham com efeito de quique
- No modo
<jelly-card>é um contêiner de superfície gelatinosa colocado abaixo do conteúdo- Ao adicionar
squish, ele é pressionado como uma almofada macia e atua como botão
- Ao adicionar
<jelly-chip>pode ser usado como rótulo estático, filtro alternável ou tag removível- Permite configurar se é selecionável, selecionado, removível ou desativado
<jelly-collapsible>é uma área expansível/recolhível que abre e fecha um painel com efeito de quique por meio de um botão de cabeçalho- É configurado para que a superfície se mova, não o texto
<jelly-divider>é uma linha divisória fina horizontal, vertical ou com rótulo<jelly-kbd>é uma keycap gelatinosa que pode ser pressionada- Ao vinculá-la a uma tecla real com
key, a keycap também desce enquanto essa tecla estiver sendo pressionada em qualquer lugar da página
- Ao vinculá-la a uma tecla real com
Navegação e layout
<jelly-resizable>é uma grade de painéis cujo tamanho pode ser ajustado arrastando divisórias gelatinosas ou pelo teclado- Aceita as direções
row,verticaleboth
- Aceita as direções
<jelly-tabs>é uma visualização em abas que usa semântica real detablist- O indicador de seleção em forma de pílula gelatinosa se move, e os painéis de abas aparecem com efeito de quique
Overlays
<jelly-dialog>é uma caixa de diálogo modal que aparece saltando como gelatina- Bloqueia a página e, depois de fechada, devolve o foco à posição anterior
- Pode ser fechada pela tecla Escape, pelo botão de fechar ou por clique no plano de fundo
<jelly-drawer>é uma folha flutuante que aparece com efeito de mola, passando levemente do limite e voltando- Pode abrir a partir do início ou fim inline, ou pela parte inferior
<jelly-popover>é um painel não modal aberto por clique- Fica ancorado ao gatilho e fecha com a tecla Escape ou clique externo
- Aceita posicionamentos
top,bottom,starteend
<jelly-tooltip>mostra um balão com tema acima do gatilho ao passar o mouse ou receber foco pelo teclado- Aceita posicionamento nas quatro direções e três tamanhos
1 comentários
Comentários no Hacker News
A janela estava meio engasgando, então fui investigar a causa, e esta biblioteca executa um loop de animação com requestAnimationFrame (RAF) a cada 8 ms em todos os componentes da página, fazendo o documento inteiro ser redesenhado
O comentário acima, de que “processa os componentes ativos juntos em um quadro e para quando está ocioso”, também parece ter sido gerado por IA. O
JellyEnginenão calcula a animação gelatinosa apenas quando ocorrem eventos de ponteiro; ele recalcula, a cada quadro, todos os componentes ativos da página. É uma implementação que uma pessoa comum olharia e diria: “não faça isso, é exagerado demais”Set()ativo e removê-los quando o movimento paraConcordo que o comentário parece um tanto gerado às pressas por IA, mas não encontrei nenhum problema evidente na abordagem em si, e, quando nada está acontecendo, o loop principal termina em poucos microssegundos
Gostei, mas parece não estar alinhado com as práticas padrão de UX
Acho que, se você mantiver pressionado e mover o mouse para fora do elemento, isso não deveria ser tratado como clique. Atualmente, o botão trata como clique, mas a caixa de seleção não, então falta consistência
É sinceramente fofo, e também gosto do fato de reduzir o recurso de forma natural em
@media (prefers-reduced-motion: reduce)Ainda assim, no site de demonstração seria bom permitir que o usuário sobrescrevesse isso sem alterar a configuração do sistema, ou pelo menos exibir um aviso de que a animação não está sendo mostrada
Sempre que aparece uma demo bacana dessas, demoro um pouco para lembrar da configuração e, enquanto isso, fico clicando decepcionado, pensando “o que isso tem de especial?”
Quando eu era mais jovem, teria adorado isso, mas hoje passo mais tempo removendo esse tipo de efeito com folhas de estilo locais ou usando modo escuro e modo de leitura. Os tempos mudaram muito
Seria bom se o efeito aparecesse com baixa intensidade também ao passar o mouse. Alguns controles, como barras de progresso e toasts, parecem não ter o efeito gelatinoso
O desempenho da página de demonstração também não é lá essas coisas e dá a impressão de sequestrar a rolagem, mas, no geral, é fofo e parece combinar bem com UIs de jogos
O elemento
Chipdeveria permanecer no lugar durante a transição, mas, ao clicar, ele sai para fora dos limites, o que não me agradaÉ fofo, mas a velocidade de resposta de alguns controles é ruim demais. Ao arrastar o slider para frente e para trás, ele fica muito atrás do cursor do mouse; deveria seguir o cursor como se estivesse colado a ele
Por outro lado, outros controles, como
jelly-resizable, se movem bem grudados ao cursor. O controle"Placeholder"parece não remover o placeholder quando clicadoFico me perguntando se alguém se lembra de que, por volta de 2007–2010, havia um efeito gelatinoso parecido nas bordas das páginas do site, blog e showcase do Paul Neave. Na época, era implementado em Flash
Naqueles tempos, Paul Neave era um herói pessoal para mim; se ele estiver lendo isto, espero que esteja bem
É difícil encontrar algo neste sistema de design de UI que possa ser chamado de efeito físico
Pode ser por causa do meu tipo de daltonismo ou da configuração do meu monitor, mas o vermelho e o âmbar são tão parecidos que eu nem conseguia distinguir se o botão havia sido pressionado