Começar
Frameworks
A mesma base roda em HTML puro e tem adaptador oficial para React, Vue, Nuxt, Svelte, Angular e Astro.
Uma base, vários adaptadores
A base é um conjunto de 33 custom elements <u-*> que roda em qualquer página com JavaScript: HTML puro, PHP, Django, Rails, WordPress. Em cima dela há adaptadores oficiais, com tipos TypeScript, para React (Next e Vite), Vue, Nuxt, Svelte (SvelteKit), Angular e Astro.
Os nomes são os mesmos em todos: USankey, USlider, USelect. O adaptador só traduz props, eventos e o momento de registrar o elemento. A lógica do componente fica na base.
Qual pacote e como ligar
| Framework | Pacote | Valor | Eventos | SSR |
|---|---|---|---|---|
| React, Next | @leallabs/unslop-react | value + onChange | onChange, onApply, onReady | Sim |
| Vue | @leallabs/unslop-vue | v-model | @u-change | Sim |
| Nuxt | @leallabs/unslop-nuxt | v-model | @u-change | Sim |
| Svelte, SvelteKit | @leallabs/unslop-svelte | bind:value | onChange | Sim |
| Angular | @leallabs/unslop-angular | ngModel ou formControl | (u-change) | Sim |
| Astro | @leallabs/unslop-astro | Só o valor inicial | addEventListener("u-change") | Sim |
| HTML puro | Nenhum: unslop.css e unslop.elements.js | value | addEventListener("u-change") | Não se aplica |
O adaptador pede o @leallabs/unslop como peer e o npm instala junto. No Astro ele é opcional, então vai no mesmo comando. Os <u-*> e o define() vêm desse pacote; sem build, o unslop.elements.js da CDN define os mesmos <u-*>. O unslop.js antigo continua valendo, com data-u e o evento u:change.
Um exemplo em cada um
Cada exemplo liga um slider a um valor e põe uma lista de barras dentro de um card. Os trechos saem das fixtures do repositório, que passam no teste.
Instalar
npm install @leallabs/unslop-reactCSS e registro
CSS: uma vez, na raiz. No Next fica em app/layout.tsx; no Vite, em main.tsx.
import "@leallabs/unslop/css";Exemplo
Exemplo (de fixtures/vite-react/src/Demo.tsx e fixtures/next/components/Demo.tsx). No Next, o arquivo começa com "use client".
import { useState } from "react";
import { USlider, UBarlist } from "@leallabs/unslop-react";
const periods = [{
label: "Hoje", total: 120,
items: [{ label: "/docs", value: 80 }, { label: "/blog", value: 40 }],
}];
export default function Painel() {
const [nivel, setNivel] = useState(2);
return <>
<USlider min={0} max={4} value={nivel} label="Esforço" onChange={(e) => setNivel(e.detail.value)} />
<UBarlist card label="Visualizações" periods={periods} />
</>;
}Instalar
npm install @leallabs/unslop-vueCSS e registro
CSS e plugin, uma vez, em main.ts (de fixtures/vite-vue/src/main.ts).
import { Unslop } from "@leallabs/unslop-vue";
import "@leallabs/unslop/css";
createApp(App).use(Unslop).mount("#app");Exemplo
Exemplo (de fixtures/vite-vue/src/views/HomeView.vue).
<script setup lang="ts">
import { ref } from "vue";
import { USlider, UBarlist } from "@leallabs/unslop-vue";
const nivel = ref(2);
const periods = [{
label: "Hoje", total: 120,
items: [{ label: "/docs", value: 80 }, { label: "/blog", value: 40 }],
}];
</script>
<template>
<USlider v-model="nivel" :min="0" :max="4" label="Esforço" />
<UBarlist card label="Visualizações" :periods="periods" />
</template>Instalar
npm install @leallabs/unslop-nuxtCSS e registro
O módulo injeta o CSS e importa os componentes sozinho (de fixtures/nuxt/nuxt.config.ts).
export default defineNuxtConfig({
modules: ['@leallabs/unslop-nuxt'],
})Exemplo
Exemplo (de fixtures/nuxt/app/pages/index.vue). Sem import: ref e os componentes vêm do Nuxt.
<script setup lang="ts">
const nivel = ref(2)
const periods = [{
label: "Hoje", total: 120,
items: [{ label: "/docs", value: 80 }, { label: "/blog", value: 40 }],
}]
</script>
<template>
<USlider v-model="nivel" :min="0" :max="4" label="Esforço" />
<UBarlist card label="Visualizações" :periods="periods" />
</template>Instalar
npm install @leallabs/unslop-svelteCSS e registro
CSS, uma vez, em src/routes/+layout.svelte (de fixtures/sveltekit).
import '@leallabs/unslop/css';Exemplo
Exemplo (de fixtures/sveltekit/src/routes/+page.svelte).
<script lang="ts">
import { USlider, UBarlist } from '@leallabs/unslop-svelte';
let nivel = $state(2);
const periods = [{
label: 'Hoje', total: 120,
items: [{ label: '/docs', value: 80 }, { label: '/blog', value: 40 }],
}];
</script>
<USlider min={0} max={4} bind:value={nivel} label="Esforço" />
<UBarlist card label="Visualizações" {periods} />Instalar
npm install @leallabs/unslop-angularCSS e registro
CSS em src/styles.css e provideUnslop() em app.config.ts (de fixtures/angular).
"k-com">/* styles.css */
@import '@leallabs/unslop/css';
"k-com">// app.config.ts
providers: [provideUnslop()]Exemplo
Exemplo (de fixtures/angular/src/app/home.ts e home.html). A moldura do gráfico é o <article> escrito à mão.
import { Component, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { USlider, UBarlist } from '@leallabs/unslop-angular';
@Component({
selector: 'app-painel',
imports: [FormsModule, USlider, UBarlist],
template: `
<u-slider [(ngModel)]="nivel" [min]="0" [max]="4" label="Esforço" />
<article class="u-chartc-card">
<u-barlist [props]="barlist" />
</article>`,
})
export class Painel {
nivel = signal(2);
barlist = {
label: 'Visualizações',
periods: [{
label: 'Hoje', total: 120,
items: [{ label: '/docs', value: 80 }, { label: '/blog', value: 40 }],
}],
};
}Instalar
npm install @leallabs/unslop-astro @leallabs/unslopCSS e registro
A integração injeta o CSS e o define() (de fixtures/astro/astro.config.mjs).
import unslop from "@leallabs/unslop-astro";
export default defineConfig({ integrations: [unslop()] });Exemplo
Exemplo (de fixtures/astro/src/pages/index.astro). O valor é só o inicial.
---
import { USlider, UBarlist } from "@leallabs/unslop-astro/components";
const periods = [{
label: "Hoje", total: 120,
items: [{ label: "/docs", value: 80 }, { label: "/blog", value: 40 }],
}];
---
<USlider min={0} max={4} value={2} label="Esforço" />
<UBarlist card label="Visualizações" periods={periods} />Ligar na página
Sem build: o CSS e o JS vêm do próprio site, como em Instalação. O unslop.elements.js define os <u-*>, e a moldura do gráfico é escrita à mão.
Exemplo
Exemplo (a mesma marcação de Select e do bloco chart-barlist). Funciona em PHP, Django, Rails e WordPress, porque é só HTML. O <div data-u> com o unslop.js antigo continua funcionando.
<link rel="stylesheet" href="https://unslop.leallabs.dev/unslop.css">
<script src="https://unslop.leallabs.dev/unslop.elements.js" defer></script>
<u-select label="Período" value="Mês" props='{"options":["Semana","Mês","Ano"]}'></u-select>
<article class="u-chartc-card"><div class="u-chartc-panel">
<u-barlist label="Visualizações" props='{"periods":[{"label":"Hoje","total":120,"items":[{"label":"/docs","value":80},{"label":"/blog","value":40}]}]}'></u-barlist>
</div></article>
<script>
document.querySelector("u-select").addEventListener("u-change", (e) => console.log(e.detail));
</script>O que muda entre eles
- Angular não tem
card. A moldura do gráfico fica escrita à mão, porque gerar por fora quebraria a hidratação. - Astro só tem o valor inicial. Não há estado reativo no servidor; a leitura é pelo evento.
- Vue e Angular escutam
u-change. Ochangecolidiria com o evento nativo doinputinterno.
Como isso é testado
A cada versão, cada adaptador roda numa fixture real do framework e passa por renderização no servidor, hidratação, eventos, valor e vazamento de memória.