Migração v1 → v2

Guia para quem já usa o ozi-ui v1 e quer atualizar para a v2.

Princípio da v2: o ozi-ui não depende de biblioteca de terceiros. JavaScript puro — o jQuery sobrevive apenas na camada integrations/ (shims de compatibilidade).

Boa notícia: a maior parte do seu código não quebra. Os atributos data-ozi-* e data-zld-*, a API pública (OZI.components.* / window.OziX) e os aliases zld* continuam funcionando. O que muda de fato está listado abaixo.


1. Versões

O versionamento é major +1 por plugin — não uma versão única para todos.

Plugin v1 v2
ozi.js (índice) 1.0.7 2.0.0 (OZI.version)
ozi-conf 2.0.x 3.0.0
ozi-loaddata 4.x 5.0.0
ozi-select 5.x 6.0.0
ozi-autocomplete · ozi-editor · ozi-auth · ozi-search · ozi-audio 3.x 4.0.0
ozi-editor-md 1.x 2.0.0
ozi-check · ozi-toggle 2.x 3.0.0
ozi-validate 1.x 2.1.0
ozi-actions · ozi-suggest 1.x 2.0.0
ozi-helpers 1.0.x 1.1.0

O pacote Composer publica 2.0.0. A v1 permanece disponível na tag v1-final.

composer require ozi-ui/core:^2.0

2. Zero jQuery — o que fazer

Antes (v1): o ozi.js distribuía e usava jQuery; muitos projetos contavam com o window.$ que "vinha junto".

Depois (v2): o núcleo não usa jQuery e não o carrega no boot. Ele continua distribuído em core/jquery-3.7.1.min.js para quem precisar.

Ação: se o seu app dependia do jQuery que vinha com o ozi-ui, passe a incluí-lo por conta própria:

<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>

3. Contrato de eventos — a mudança mais importante

Na v1 os eventos eram dual-dispatch: $(el).trigger() (payload posicional do jQuery) e CustomEvent. Na v2 é CustomEvent nativo, com o payload em detail:

detail: { component: 'ozi-select', name: 'uf', value: 'SP', items: [...], source: 'user' }
// source: 'user' (interação do usuário) | 'api' (setValue programático)

Consumindo ozi:change

// ❌ v1 — jQuery posicional
$('[data-ozi-select="uf"]').on('ozi:change', function (e, items, instance, detail) {
    console.log(detail.value);
});

// ✅ v2 — CustomEvent nativo
document.addEventListener('ozi:change', function (e) {
    if (e.detail.component !== 'ozi-select') return;
    console.log(e.detail.name, e.detail.value);   // 'uf', 'SP'
});
<!-- ✅ v2 — Alpine -->
<div x-on:ozi:change="$wire.set('uf', $event.detail.value)"></div>

Mudanças de chave no detail

v1 v2
key name
instance removido — use OZI.components.select.get(el)
ozi-check: source (switch/group/item) level — o source agora é 'user'|'api'
ozi-search value = query; mantém query/matched/total
ozi-auth novidade v2 — agora emite CustomEvent (era jQuery-only)

Todos os componentes passaram a emitir ozi:init (após a inicialização) e ozi:destroy.

Compatibilidade sem reescrever (shims)

Se você tem consumidores no formato posicional da v1, ative o shim — ele escuta o CustomEvent e re-emite via jQuery no formato antigo. Nada no seu código precisa mudar.

  • integrations/adapters/ozi-change-v1-compat.shim.jsozi:change posicional
  • integrations/adapters/ozi-check-v1-events.shim.jsoziCheck:initFetched

Os shims são temporários e exigem jQuery. Migre para addEventListener quando puder.


4. Descontinuados: ozi-copy e ozi-paste

Foram removidos da v2. Os substitutos são receitas curtas em Alpine ou JS puro — sem dependência de FontAwesome.

<!-- Substituto do ozi-copy -->
<button x-data="{ ok: false }"
        x-on:click="navigator.clipboard.writeText($refs.alvo.value); ok = true; setTimeout(() => ok = false, 2000)">
    <span x-text="ok ? '✓' : 'Copiar'"></span>
</button>

Os plugins v1 continuam disponíveis na tag v1-final.

ozi-audio NÃO foi descontinuado — segue no escopo e foi migrado (v4.0.0).


5. Livewire

O adapter ganhou o modo nativo, que respeita os modificadores do wire:model:

<!-- Modo A (preferido): dispatch nativo — respeita .live/.debounce/.lazy -->
<div wire:ignore>
    <div data-ozi-select="uf" data-ozi-livewire-native="#uf-hidden"></div>
</div>
<input id="uf-hidden" type="hidden" wire:model="uf">

<!-- Modo B (compat): component.set() -->
<div data-ozi-select="uf" data-ozi-livewire-model="uf"></div>
  • Anti-loop: o adapter ignora ozi:change com source: 'api' (mudança vinda do próprio Livewire).
  • Re-init pós-morph: é papel do ozi-hooks — nada a fazer.
  • Guard LW3 × LW4 automático.

6. Temas

Tema = dados: 4 arquivos linkados no <head> (tokens.css, overrides.css, dark.css, classmap.js). O mesmo build JS serve os 3 temas — troca-se apenas oziConf({ theme }).

<link rel="stylesheet" href="/plugins/ozi-ui/themes/tailwind/tokens.css">
<link rel="stylesheet" href="/plugins/ozi-ui/themes/tailwind/overrides.css"><!-- novo na v2 -->
<link rel="stylesheet" href="/plugins/ozi-ui/themes/tailwind/dark.css">
<script>oziConf({ theme: 'tailwind' });</script>

Novidade v2: themes/tailwind/overrides.css, que não existia na v1. Para um tema próprio, copie themes/_template/.


7. Aliases legados

Continuam funcionando, com aviso no console se core.log: true. Serão removidos em uma versão futura:

Alias v1 Use na v2
window.oziCore window.OZI
window.oziLoaddata window.oziLoadData
window.OziFrameworks OZI.integrations
window.zldActions(arr) OZI.modules.actions.run(arr)
window.oziValidateContainer(c) OZI.modules.validate.container(c)
zldParseBool / zldGenerateId / … OZI.helpers.*

8. Checklist de migração

  • [ ] Incluir jQuery por conta própria se o app dependia do que vinha com o ozi-ui (§2)
  • [ ] Trocar consumidores de ozi:change para addEventListener + e.detail (§3) — ou ativar o shim
  • [ ] Substituir ozi-copy/ozi-paste pelas receitas Alpine (§4)
  • [ ] (Livewire) avaliar o modo A (data-ozi-livewire-native) para respeitar o wire:model (§5)
  • [ ] (Tailwind) linkar o novo overrides.css (§6)
  • [ ] Remover usos de aliases legados (§7)
  • [ ] Rodar o app com oziConf({ core: { log: true } }) para ver os avisos de depreciação

9. O que não muda

  • Atributos data-ozi-* e data-zld-* (markup declarativo)
  • API pública: OZI.components.<nome> e window.Ozi<Nome>
  • oziConf({...}), @oziScripts / @oziStyles (Blade), OZI.ready()
  • ozi-loaddata: fetch, destino DOM, coleta, progress, actions — comportamento idêntico