2 puntos por GN⁺ 14 시간 전 | 1 comentarios | Compartir por WhatsApp
  • Jelly UI v1.1 es una biblioteca de componentes web sin dependencias que combina controles de formulario reales con efectos suaves de física de cuerpo blando, y ofrece 40 elementos personalizados
  • Se instala con un solo script de módulo y soporta modo oscuro, seguimiento automático del tema del sistema operativo, cambio de color de acento y disposición RTL de derecha a izquierda
  • Los botones usan <button> nativo y los sliders usan una entrada range oculta para mantener la semántica nativa para manejo con teclado, lectores de pantalla y participación en formularios
  • Aplica animaciones táctiles como presión, estiramiento, ondas y rebote a varios elementos, desde casillas de verificación y campos de entrada hasta toasts, pestañas y diálogos
  • Incluye tokens de color WCAG AA y patrones ARIA para crear interfaces de producto accesibles sin perder los efectos visuales suaves

Instalación y tema

  • Jelly UI puede usarse sin dependencias, solo con 40 elementos personalizados y una etiqueta <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> es un proveedor de tema que aplica tokens de diseño de forma limitada al subárbol descendiente
    • mode soporta auto, light, dark, para seguir la configuración del sistema operativo o forzar un tema específico
    • Con accent se puede redefinir el color de acento
  • Las variaciones de color comunes son azure, rose, amber, mint, graphite, platinum, white, y los tamaños se componen principalmente de small, medium, large

Botones y elementos de acción

  • <jelly-button> es un botón tipo cápsula que contiene un <button> nativo real para soportar teclado y lectores de pantalla
    • Se pueden configurar color, tamaño, formas pill y square, estado deshabilitado y disposición en bloque
  • <jelly-icon-button> es un botón cuadrado o circular pensado para un solo ícono
    • El atributo label define el nombre que reconocerá el lector de pantalla

Controles de entrada de formulario

  • <jelly-checkbox> participa en formularios, soporta checked y el estado indeterminado (indeterminate), y el cuadro gelatinoso salta cuando cambia el estado
  • <jelly-input> es un campo de entrada de una sola línea para text, email, password
    • Al recibir foco, la superficie se eleva y aparece el borde, y con cada entrada se expande una onda desde la posición del cursor
    • Soporta disabled y readonly
  • <jelly-label> se conecta al control con for
    • Al hacer clic, enfoca el objetivo y el texto de la etiqueta se convierte en el nombre accesible; se puede indicar si es obligatorio y su tamaño
  • <jelly-otp> es un campo de código de un solo uso que ofrece una casilla por cada dígito
    • Maneja entrada, retroceso, teclas de flecha y pegado, y permite configurar longitud, color, tamaño y deshabilitación
  • <jelly-radio> forma grupos con elementos que comparten el mismo name dentro de la misma raíz
    • Soporta navegación con flechas considerando tabindex móvil y la dirección del documento
  • <jelly-radio-group> es un contenedor radiogroup con etiqueta para jelly-radio
    • Proporciona leyenda, disposición horizontal o vertical, y propagación de tamaño a los elementos hijos
  • <jelly-range> es un slider de doble manija para elegir un intervalo entre mínimo y máximo
    • Aplica role="slider", foco y ARIA a ambas manijas, y al arrastrarlas la manija gelatinosa se comprime
  • <jelly-segmented> es una pista tipo cápsula que contiene opciones mutuamente excluyentes
    • El indicador de selección funciona como una pastilla gelatinosa que se inclina y se estira al moverse entre segmentos
  • <jelly-select> es un desplegable conectado a formularios que usa los patrones ARIA combobox y listbox
    • Tanto el disparador como el panel de opciones están construidos con superficies de cuerpo blando
    • El panel se despliega desde el campo y, si falta espacio abajo, cambia hacia arriba
  • <jelly-slider> es un slider para seleccionar un solo valor
    • Una entrada range nativa oculta se encarga de la semántica y la participación en formularios, mientras en pantalla se muestra una manija gelatinosa que se comprime
  • <jelly-switch> es un interruptor arrastrable cuya perilla se estira como una gota líquida y cuyos colores de apagado y encendido cambian en transición cruzada
  • <jelly-textarea> crece automáticamente entre una altura mínima y máxima según la entrada multilínea
    • La superficie también se estira con la altura, se genera una onda desde la posición del cursor al escribir, y soporta disabled y readonly

Estado y retroalimentación

  • <jelly-alert> es un banner que ofrece cuatro tonos: info, success, warning, danger, y un botón de cierre opcional
  • <jelly-badge> es un elemento pequeño para insignias, etiquetas o estados, y salta cuando cambia el texto
    • Se pueden configurar estilos relleno y contorno, formas tipo píldora y cuadrada, y comportamientos live e instant
  • <jelly-progress> es una barra de progreso en la que la parte delantera del relleno se sacude según el avance
    • En modo indeterminado, la masa rebota entre ambas paredes
  • <jelly-skeleton> es un marcador de carga que se balancea suavemente como si respirara, en vez de usar brillo
    • Soporta las formas line, rect, circle
  • <jelly-spinner> ofrece un indicador dots con una masa viscosa que se mueve entre tres puntos y un indicador blob que rota cambiando de forma
  • <jelly-toaster> gestiona notificaciones toast que aparecen y desaparecen desde el extremo en línea
    • Normalmente se invoca con el helper jellyToast('Saved!', { tone: 'success' })
    • Si al elemento colocado se le da position="bottom", la pila de notificaciones crece hacia arriba

Superficies de contenido

  • <jelly-accordion> agrupa varios elementos <jelly-collapsible>
    • En modo single, cuando uno se abre los demás se cierran con rebote
  • <jelly-card> es un contenedor de superficie gelatinosa que se coloca debajo del contenido
    • Si se añade squish, actúa como botón al comprimirse como un cojín suave
  • <jelly-chip> puede usarse como etiqueta estática, filtro conmutables o tag removible
    • Permite configurar si es seleccionable, su estado seleccionado, si se puede quitar y si está deshabilitado
  • <jelly-collapsible> es un área expandible/colapsable que abre y cierra un panel con rebote mediante un botón de encabezado
    • Está diseñado para que se mueva la superficie, no el texto
  • <jelly-divider> es una línea divisoria delgada horizontal, vertical o con etiqueta
  • <jelly-kbd> es una tecla gelatinosa que se puede presionar
    • Si se conecta a una tecla real con key, la tecla visual también baja mientras esa tecla se mantenga presionada en cualquier parte de la página

Navegación y diseño

  • <jelly-resizable> es una cuadrícula de paneles cuyo tamaño se ajusta arrastrando un divisor gelatinoso o con el teclado
    • Soporta las direcciones row, vertical, both
  • <jelly-tabs> es una vista de pestañas que usa semántica real de tablist
    • El indicador de selección con forma de pastilla gelatinosa se mueve y el panel de pestañas aparece con rebote

Superposiciones

  • <jelly-dialog> es un cuadro de diálogo modal que aparece rebotando como gelatina
    • Bloquea la página y, después de cerrarse, devuelve el foco a la posición previa
    • Puede cerrarse con la tecla Escape, el botón de cierre o haciendo clic en el fondo
  • <jelly-drawer> es una lámina flotante que aparece con un efecto de resorte que sobrepasa un poco y regresa desde el borde
    • Puede abrirse desde el inicio en línea, el final en línea o desde abajo
  • <jelly-popover> es un panel no modal que se abre con clic
    • Queda anclado al disparador y se cierra con la tecla Escape o con clic afuera
    • Soporta las posiciones top, bottom, start, end
  • <jelly-tooltip> muestra un globo temático sobre el disparador al pasar el mouse o recibir foco de teclado
    • Soporta ubicación en cuatro direcciones y tres tamaños

1 comentarios

 
Opiniones de Hacker News
  • La ventana se sentía algo trabada, así que investigué la causa, y esta biblioteca ejecuta un bucle de animación requestAnimationFrame (RAF) cada 8 ms en todos los componentes de la página, haciendo que se redibuje todo el documento.
    El comentario de arriba sobre “procesar juntos los componentes activos en un frame y detenerse cuando estén inactivos” también parece generado por IA. JellyEngine no calcula la animación gelatinosa solo cuando ocurren eventos del puntero, sino que recalcula en cada frame todos los componentes activos de la página. Es una implementación que una persona normal vería y diría: “así no se hace, es demasiado”.

    • Al hacer profiling de rendimiento en Chrome, no encontré respaldo para esa explicación. El bucle parece gestionar los componentes que hay que actualizar con un Set() activo y eliminarlos cuando el movimiento se detiene.
      Coincido en que los comentarios suenan un poco generados a la ligera por IA, pero no encontré ningún problema evidente en el enfoque en sí, y cuando no hay ninguna acción el bucle principal termina en unos pocos microsegundos.
    • No es un enfoque excesivo. El 99.99% de los videojuegos funciona literalmente así: redibujan toda la pantalla continuamente mientras lo permitan la frecuencia de actualización con sincronización vertical o el rendimiento del hardware.
  • Me gusta, pero no parece ajustarse a las prácticas estándar de UX.
    Creo que si mantienes presionado y mueves el mouse fuera del elemento, no debería registrarse como clic. Actualmente el botón sí lo registra como clic, pero el checkbox no, así que no es consistente.

    • Era un problema constante al trabajar con desarrolladores de Flash. Era común el principio de “si no puedes implementar todas las funciones de una barra de desplazamiento, no reinventes la barra de desplazamiento”, pero al final terminábamos corrigiéndolo más de cinco veces y gastando días en ello.
    • Buen hallazgo; corregí la lógica del botón, y ahora no se dispara el clic si el cursor está fuera de los límites del botón.
  • Es genuinamente adorable, y también me gusta que reduzca la funcionalidad de forma natural con @media (prefers-reduced-motion: reduce).
    Aun así, en el sitio de demo estaría bien permitir que el usuario lo sobrescriba sin cambiar la configuración del sistema, o al menos mostrar un aviso de que las animaciones no se están mostrando.

    • No me di cuenta de que estaba reduciendo el movimiento intencionalmente y pensé que estaba roto. También había olvidado que había activado esa configuración antes.
    • Se puede configurar Reducir movimiento en menú Apple > Configuración del Sistema > Accesibilidad > Movimiento.
      Cada vez que aparece una demo genial como esta, tardo un momento en recordar la configuración, y mientras tanto hago clic decepcionado pensando: “¿qué tiene de especial?”.
    • Ahora muestra una notificación, y también permite sobrescribir la configuración del sistema pulsando un lindo ícono de conejo.
  • Si fuera más joven me habría encantado, pero hoy paso más tiempo eliminando estos efectos con hojas de estilo locales o usando modo oscuro y modo lectura. Los tiempos cambiaron mucho.

    • Me gusta la animación porque da feedback que resalta lo que está ocurriendo o cambiando en ese momento. Los componentes nativos no siempre lo expresan bien, y una animación bien usada no es solo decoración: tiene valor real para la UX.
    • Más o menos una vez al año quiero que el software sea más divertido, y luego vuelvo a desear simplemente que no estorbe.
  • Estaría bueno que el efecto apareciera también al pasar el mouse por encima, aunque con baja intensidad. Parece que algunos controles, como la barra de progreso y los toasts, no tienen efecto gelatinoso.
    El rendimiento de la página de demo tampoco es muy bueno y se siente como si secuestrara el scroll, pero en general es adorable y parece encajar bien en una UI de juegos.

  • El elemento Chip debería permanecer en su lugar al hacer la transición, pero al hacer clic se sale fuera de los límites, y eso no me gusta.

  • Es adorable, pero la velocidad de respuesta de algunos controles es demasiado mala. Si arrastras el slider hacia adelante y atrás, queda muy por detrás del cursor del mouse; debería seguirlo como si estuviera pegado con pegamento.
    En cambio, otros controles como jelly-resizable sí se mantienen bien pegados al cursor. El control "Placeholder" parece no hacer desaparecer el placeholder al hacer clic.

  • Me pregunto si alguien recuerda que, alrededor de 2007–2010, el sitio web, blog y showcase de Paul Neave tenían un efecto gelatinoso similar en los bordes de la página. En aquel entonces estaba implementado en Flash.
    En esa época Paul Neave era un héroe personal para mí, y si está leyendo esto, espero que esté bien.

  • Me cuesta encontrar algo en este sistema de diseño de UI que pueda llamarse efecto físico.

    • Esta biblioteca respeta la configuración de reducir movimiento del cliente y desactiva todos los efectos de animación.
  • Puede que sea por mi tipo de daltonismo o por la configuración de mi monitor, pero el rojo y el ámbar se parecían tanto que ni siquiera podía distinguir si había pulsado el botón.