@govbr-ds/webcomponents-vue

Wrapper Vue para a biblioteca de Web Components do GovBR-DS.
7,955
Install
npm install @govbr-ds/webcomponents-vue
Latest Version:2.4.0
Vue:3
License:MIT
Last Updated:Oct 16, 2026
Links: GitLab  ·  npm
Maintainer: govbrds

Vue – @govbr-ds/webcomponents-vue

Este wrapper Vue encapsula os Web Components GovBR-DS, permitindo que sejam utilizados como componentes nativos no Vue.

Compatibilidade

  • Faixa declarada: Vue 3, conforme as peerDependencies do pacote.
  • Núcleo de Web Components: @govbr-ds/webcomponents na mesma versão deste wrapper.
  • Navegadores: A mesma política Baseline Widely Available dos Web Components. Internet Explorer não é suportado.

[!NOTE] Essa faixa acompanha o peer exigido pelo runtime do output target Vue. O Vue Router não é um requisito do wrapper. O wrapper não faz requisições HTTP, autenticação, cache ou transporte de dados — essas responsabilidades permanecem na aplicação consumidora.

Por que usar este wrapper? 🤔

  • Verificação de tipos.
  • Integração com Vue Router.
  • Suporte a v-model para componentes de formulário.

Mais detalhes na documentação do Stencil.

Instalação 📦

npm install @govbr-ds/webcomponents-vue
# ou
pnpm add @govbr-ds/webcomponents-vue
# ou
yarn add @govbr-ds/webcomponents-vue

peerDependencies

peerDependencies são pacotes que este wrapper não instala automaticamente — o seu projeto precisa tê-los instalados.

Observe que algumas peerDependencies podem ter suas próprias peerDependencies que também precisam ser atendidas. Consulte a documentação de cada pacote para garantir que todas as dependências necessárias estejam presentes.

Por que existem: Garantem que o seu app Vue e o wrapper compartilhem a mesma instância do Vue e dos Web Components. Versões duplicadas causam erros em tempo de execução.

O que isso implica: Se as peers não estiverem instaladas ou forem incompatíveis, componentes podem não funcionar.

As peers declaradas neste pacote são:

  • vue
  • @govbr-ds/webcomponents

As versões aceitas estão em peerDependencies no package.json publicado deste pacote (também exibidas na página do npm e na política de compatibilidade). O peer @govbr-ds/webcomponents exige exatamente a mesma versão deste wrapper.

Se você seguiu o comando de instalação acima, ambas as peers já estão incluídas.

Nota importante: pnpm e tree-shaking

Se ao consumir estes pacotes você notar que o bundler não está removendo código não utilizado (tree‑shaking), pode haver uma incompatibilidade com o layout padrão do pnpm.

Solução rápida (opcional, somente se precisar): crie um arquivo .npmrc na raiz do seu projeto com:

node-linker=hoisted

Por que isso ajuda: por padrão, o pnpm organiza as dependências em pastas isoladas com symlinks. Alguns bundlers/otimizadores se baseiam na estrutura de node_modules e no campo sideEffects para decidir o que pode ser eliminado. O layout hoisted aproxima o formato “achatado” (similar ao npm/yarn), facilitando essa análise e, em muitos casos, restaurando o tree‑shaking.

Observações:

  • Use apenas se o tree‑shaking realmente não estiver funcionando.
  • Pode aumentar o uso de disco e alterar a resolução de dependências do seu projeto.

Quickstart Vue

Use o quickstart Vue como referência para configuração de projeto:

  • Repositório: govbr-ds-wbc-quickstart-vue
  • Servidor local: pnpm dev
  • Formulários: estado com v-model, binding manual e VeeValidate
  • Testes headless: pnpm test:e2e
  • Porta padrão: http://localhost:5173/

Uso 📚

Configuração do template

Ao usar @govbr-ds/webcomponents-vue, importe os componentes usados em cada SFC ou registre-os no aplicativo. Não marque br-* como isCustomElement: isso faz o compilador ignorar os proxies Vue e, com eles, a integração de v-model e eventos tipados. A opção isCustomElement serve somente para consumo direto de @govbr-ds/webcomponents, sem este wrapper.

Uso com componentes

import { BrButton } from '@govbr-ds/webcomponents-vue'

Uso com v-model:

<script setup lang="ts">
import { BrInput } from '@govbr-ds/webcomponents-vue'
import { ref } from 'vue'

const name = ref('Lorem ipsum')
</script>

<template>
  <h1>Olá {{ name }}</h1>
  <BrInput name="name" placeholder="Seu nome" v-model="name" />
</template>

O v-model padrão já aponta para a propriedade correta de cada proxy:

Componentes Propriedade/evento mapeados Valor do modelo Uso
input textual e textarea value / input string v-model="texto"
datas simples value / input Date | null v-model="data"
select e radio group value / change seleção v-model="selecao"
checkbox, radio e switch checked / change boolean v-model="marcado"
slider simples value / input number v-model="numero"
upload files / change FileList | null v-model="arquivos"
tag selecionável selected / change seleção v-model="selecionado"

Para aprender o contrato por baixo do wrapper, compare essa abordagem com o binding manual do quickstart, que usa :value/:checked e lê event.currentTarget em @input/@change.

Para datas simples, inicialize o ref com Date | null; não use a string exibida no campo como modelo. O componente só produz texto ao participar de FormData. Valores recuperados de JSON precisam ser convertidos e validados antes de voltar ao v-model.

Validação e acessibilidade com VeeValidate

O VeeValidate mantém o modelo e as regras; o Web Component continua responsável pela interface do campo e pela Constraint Validation nativa. Replique o erro em state, em texto e em aria-invalid.

<script setup lang="ts">
import { BrButton, BrInput, BrMessage } from '@govbr-ds/webcomponents-vue'
import { useField, useForm } from 'vee-validate'

const initialValues = { email: '' }
const { handleSubmit, resetForm } = useForm({ initialValues })
const { value: email, errorMessage: emailError, handleBlur } = useField<string>('email', (value) => {
  if (!value) return 'O e-mail é obrigatório.'
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || 'Informe um e-mail válido.'
})
const submit = handleSubmit((values) => console.log(values))
const clear = () => resetForm({ values: { ...initialValues } })
</script>

<template>
  <form @submit="submit" @reset="clear" novalidate>
    <BrInput
      name="email"
      label="E-mail"
      type="email"
      required
      v-model="email"
      :state="emailError ? 'danger' : undefined"
      :aria-invalid="Boolean(emailError)"
      @blur="handleBlur"
    />
    <BrMessage v-if="emailError" state="danger" is-feedback :message="emailError" />

    <BrButton type="reset" emphasis="secondary">Limpar</BrButton>
    <BrButton type="submit">Enviar</BrButton>
  </form>
</template>

O reset precisa alcançar as duas fontes de estado: o botão type="reset" limpa os controles associados, inclusive upload, e resetForm() restaura o modelo, erros e estado de interação do VeeValidate.

Modelos de intervalo

Para os componentes que trabalham com intervalo, o pacote oferece wrappers aditivos com v-model:range-value:

<script setup lang="ts">
import { ref } from 'vue'
import { BrSliderRange } from '@govbr-ds/webcomponents-vue'

const intervalo = ref({ start: 20, end: 80 })
</script>

<template>
  <BrSliderRange v-model:range-value="intervalo" :min="0" :max="100" />
</template>

Os dados assíncronos continuam sob controle da aplicação. Por exemplo, use loading, options e os eventos de busca do BrSelect; o wrapper não faz requisições HTTP, cache ou autenticação.

Dependências de Build 🛠️

Este pacote é um wrapper gerado automaticamente e depende dos artefatos produzidos pelo núcleo de Web Components.

Pacote Dependência de Build Motivo
@govbr-ds/webcomponents-vue webcomponents:build Necessita dos proxies gerados em src/stencil-generated; a preparação aponta esses proxies para o adaptador mantido em src/runtime.ts.

Desenvolvimento 👨‍💻

Estrutura do projeto

├── 📁 src
│   ├── 📁 stencil-generated
│   ├── 📄 runtime.ts
│   └── 📄 index.ts

[!WARNING] Tudo dentro de stencil-generated é sobrescrito ao gerar o build de Web Components.

src/runtime.ts não é gerado. Ele preserva o runtime oficial e impede que o marcador interno de uma prop ARIA ausente seja serializado como Symbol(). O passo de preparação reaplica automaticamente esse import após a geração dos proxies.

Scripts/Build

nx build webcomponents
nx build vue

Nuxt 3

O exemplo abaixo usa os Web Components diretamente no cliente, sem os proxies Vue. Nesse modo, configure vue.compilerOptions em nuxt.config.ts:

// nuxt.config.ts
export default defineNuxtConfig({
  vue: {
    compilerOptions: {
      isCustomElement: (tag) => tag.startsWith('br-'),
    },
  },
})

Use o plugin defineNuxtPlugin para registrar os Web Components apenas no cliente:

// plugins/govbr-ds.client.ts
import { defineCustomElements } from '@govbr-ds/webcomponents/loader'

export default defineNuxtPlugin(() => {
  defineCustomElements()
})

Essa configuração trata br-* como elemento nativo e, portanto, não oferece o v-model do wrapper. Se o aplicativo registrar BrInput, BrSelect e os demais proxies Vue, remova isCustomElement e use uma estratégia de plugin compatível com o modo de renderização escolhido.

Formatos do build 📦

A tarefa nx build vue compila o wrapper e gera a saída em dist/vue/. Abaixo estão os artefatos produzidos e quando utilizá-los.

Estrutura do dist/vue/

dist/vue/
├── src/
│   ├── index.js          ← Entrada principal (ESM)
│   ├── index.d.ts        ← Tipos TypeScript
│   └── stencil-generated/
│       └── components.js ← Componentes proxy com v-model (gerados pelo Stencil)
├── package.json
└── README.md

Quando usar cada formato

Artefato Quando usar Observações
src/index.js Aplicações Vue 3 (Vite, Webpack, Nuxt) Importação padrão via @govbr-ds/webcomponents-vue
src/index.d.ts Autocomplete e tipagem TypeScript Resolvido automaticamente pelo campo types do package.json

v-model e componentModels

Os componentes de formulário suportam v-model nativamente graças à configuração componentModels do Stencil Vue output target. Isso significa que:

  • br-input, br-select, br-checkbox, br-radio e outros componentes de formulário emitem o evento correto e expõem a prop adequada para two-way binding.
  • Não é necessário configuração extra — use v-model diretamente:
<script setup lang="ts">
import { ref } from 'vue'
import { BrInput } from '@govbr-ds/webcomponents-vue'

const nome = ref('')
</script>

<template>
  <BrInput v-model="nome" label="Nome" />
</template>

Documentações Complementares 📖

Contribuindo 🤝

Reportar Bugs/Problemas 🐛

Abra uma issue: gitlab.com/.../issues/new

Commits 📝

Padrões de branches e commits: gov.br/ds/wiki

Precisa de ajuda? 🆘

Créditos 🎉

Desenvolvido pelo SERPRO com a comunidade.

Related Packages

@govbr-ds-testing/webcomponents-vue

Biblioteca de integração dos Web Components GovBR-DS com o Vue

1,199
sanhaua

Sanhaua design system

3,820 1
@c2n/components

Every c2n web component in one package: one import per component, JSX and Vue te...

2,747 5
@7pmlabs/design-system

A Vue 3 component library built with TypeScript, Tailwind CSS 4, and Ant Design...

7,461 1

Version History

Version Released Vue License
2.4.0 >=3.4.38 <4.0.0 MIT
2.3.0 >=3.4.38 <4.0.0 MIT
2.2.0 >=3.4.38 <4.0.0 MIT
2.1.3 >=3.4.38 <4.0.0 MIT
2.1.2 >=3.4.38 <4.0.0 MIT
Pre-releases (62)
Version Released Vue License
2.0.0-next.67 >=3.3.0 MIT
2.0.0-next.66 >=3.3.0 MIT
2.0.0-next.65 >=3.3.0 MIT
2.0.0-next.64 >=3.3.0 MIT
2.0.0-next.63 >=3.3.0 MIT