Skip to content

Bibliotecas do Widget Svelte ​

Tipo
Referência
Para
Desenvolvedor

Um Widget Svelte importa de uma lista fechada de pacotes, entre eles Highcharts, Chart.js, ApexCharts, d3, date-fns, lodash e xlsx. O servidor de compilação do Lumo resolve todo import entre os pacotes que tem instalados e embute no Widget as bibliotecas que ele importa; nada vem como variável global na página. Por isso o import é obrigatório e só funciona com os pacotes desta lista.

Pacotes ​

ParaPacoteVersãoImport
Componentesvelte4.2.19import { onMount, onDestroy, tick } from 'svelte'
Gráfico (recomendado)highcharts, @highcharts/svelte11.4.8, 1.1.1import Highcharts from 'highcharts' e import { Chart } from '@highcharts/svelte'
Gráficochart.js4.4.5import Chart from 'chart.js/auto'
Gráficoapexcharts3.54.1import ApexCharts from 'apexcharts'
Gráfico leve, série longauplot1.6.31import uPlot from 'uplot' e import 'uplot/dist/uPlot.min.css'
Visualização livred37.9.0import * as d3 from 'd3'
Datadate-fns4.1.0import { format } from 'date-fns' e import { ptBR } from 'date-fns/locale'
Datadayjs1.11.13import dayjs from 'dayjs'
Datamoment2.30.1import moment from 'moment' e import 'moment/locale/pt-br'
Dadoslodash4.17.21import _ from 'lodash'
Estatísticasimple-statistics7.8.7import * as ss from 'simple-statistics'
Planilhaxlsx0.18.5import * as XLSX from 'xlsx'
Corchroma-js3.1.2import chroma from 'chroma-js'
Ícone@iconify/svelte4.2.0import Icon from '@iconify/svelte'
Medida de texto@chenglou/pretext0.0.6import { prepareWithSegments, measureNaturalWidth } from '@chenglou/pretext'

Import de um pacote que não está na lista faz a compilação falhar, e o erro do compilador aparece no lugar do Widget. echarts, plotly.js, vega e numeral não estão instalados.

Exemplos ​

Highcharts ​

O caminho que o assistente de IA do editor segue, e o que dá menos trabalho: o componente <Chart> cria, atualiza e destrói o gráfico junto com o Widget.

svelte
<script>
  import Highcharts from 'highcharts';
  import { Chart } from '@highcharts/svelte';
  export let app;

  let options = null;
  app.fetchMatrix({ columns: ['[Vendas]."MES":YEARMONTH', '[Vendas]."VALOR":SUM'] })
    .then((res) => {
      options = {
        chart: { type: 'column', backgroundColor: 'transparent' },
        title: { text: null },
        xAxis: { categories: res.Result.map((r) => app.formatValue(r[0], res.Columns[0])) },
        series: [{ name: res.Columns[1].label, data: res.Result.map((r) => Number(r[1]) || 0) }],
        credits: { enabled: false },
      };
    });
</script>

{#if options}<Chart {Highcharts} {options} />{/if}

Módulos extras do Highcharts vêm do próprio pacote e se ligam passando o Highcharts:

javascript
import Highcharts from 'highcharts';
import HighchartsMore from 'highcharts/highcharts-more';   // gauge, arearange, bubble
import Exporting from 'highcharts/modules/exporting';
HighchartsMore(Highcharts);
Exporting(Highcharts);

Chart.js, ApexCharts e uPlot ​

Estas três desenham num elemento que você entrega. Crie no onMount e destrua no retorno dele, senão cada recarga do Dashboard deixa um gráfico órfão.

svelte
<script>
  import { onMount } from 'svelte';
  import Chart from 'chart.js/auto';
  let canvas;
  onMount(() => {
    const grafico = new Chart(canvas, { type: 'line', data: { labels: ['Jan', 'Fev'], datasets: [{ data: [10, 14] }] } });
    return () => grafico.destroy();
  });
</script>

<canvas bind:this={canvas}></canvas>

d3 ​

javascript
import * as d3 from 'd3';
const escala = d3.scaleLinear().domain([0, d3.max(valores)]).range([0, largura]);

Datas ​

javascript
import { format, startOfMonth } from 'date-fns';
import { ptBR } from 'date-fns/locale';
format(startOfMonth(new Date()), "MMMM 'de' yyyy", { locale: ptBR }); // "novembro de 2026"

Para formatar um valor que veio da consulta, use app.formatValue, que já respeita a máscara da coluna.

lodash e simple-statistics ​

javascript
import _ from 'lodash';
import * as ss from 'simple-statistics';
const porLoja = _.groupBy(linhas, (l) => l.loja);
const mediana = ss.median(linhas.map((l) => l.valor));

xlsx ​

javascript
import * as XLSX from 'xlsx';
function baixar() {
  const planilha = XLSX.utils.aoa_to_sheet([res.Columns.map((c) => c.label), ...res.Result]);
  const livro = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(livro, planilha, 'Dados');
  XLSX.writeFile(livro, 'vendas.xlsx');
}

chroma-js ​

javascript
import chroma from 'chroma-js';
const escala = chroma.scale(['#fee2e2', '#dc2626']).domain([min, max]);
const cor = escala(valor).hex();

Ícones ​

svelte
<script>import Icon from '@iconify/svelte';</script>
<Icon icon="mdi:alert-circle" width="20" class="text-amber-500 dark:text-amber-400" />

O nome é conjunto:ícone (mdi, lucide, tabler, ph, entre outros), e a busca fica em icon-sets.iconify.design. A cor segue currentColor, então a classe de texto do Tailwind pinta o ícone. O desenho de cada ícone é baixado da API pública do Iconify quando o Widget aparece; numa rede que bloqueia api.iconify.design, o ícone fica em branco.

pretext ​

Mede texto sem esperar o navegador desenhar, para ajustar o tamanho da fonte ao espaço do Widget. É o que o KPI do Lumo usa para caber o número no cartão.

javascript
import { prepareWithSegments, measureNaturalWidth } from '@chenglou/pretext';
const medido = prepareWithSegments('R$ 1.234.567', '700 100px Poppins');
const largura = measureNaturalWidth(medido); // largura em px na fonte de 100px
const tamanho = Math.min(48, (larguraDisponivel / largura) * 100);

Tailwind ​

As classes do Tailwind 3.4 funcionam direto, inclusive dark: (o modo escuro segue a classe dark da página). O compilador gera só as classes que aparecem escritas no código, então a classe precisa estar inteira no texto.

svelte
<!-- certo: as duas classes aparecem inteiras -->
<div class={alerta ? 'bg-red-100 text-red-700' : 'bg-slate-100 text-slate-700'}>

<!-- errado: grid-cols-3 nunca aparece escrita e não é gerada -->
<div class="grid grid-cols-{n}">

Além das cores padrão, o tema tem as do Lumo: navy-50 a navy-900 (a paleta do modo escuro), primary, accent, secondary, info, success, warning, error, slate-150; tamanhos de fonte text-tiny, text-tiny+, text-xs+, text-sm+; e as sombras shadow-soft e shadow-soft-dark. Quais classes usar para fundo, borda e texto está em Boas práticas.

Arquivos seus ​

O código pode ter mais de um arquivo. O principal se chama Main.svelte, e os outros entram por import relativo:

javascript
import Linha from './Linha.svelte';
import { somar } from './calculos.js';

Sem Main.svelte, a compilação falha com "Main.svelte must be included".

Limites ​

  • Svelte 4. A sintaxe do Svelte 5 (runes, onclick) não funciona; veja Boas práticas.
  • O pacote compilado fica em cache pelo texto do código: o mesmo código não é compilado de novo, e qualquer mudança compila sozinha na próxima abertura.

Relacionado ​