Migración v1 → v2
Guía para quien ya usa ozi-ui v1 y quiere actualizar a la v2.
Principio de la v2: ozi-ui no depende de ninguna biblioteca de terceros. JavaScript puro — jQuery sobrevive únicamente en la capa integrations/ (shims de compatibilidad).
Buena noticia: la mayor parte de tu código no se rompe. Los atributos
data-ozi-*ydata-zld-*, la API pública (OZI.components.*/window.OziX) y los aliaszld*siguen funcionando. Lo que sí cambia está listado abajo.
1. Versiones
El versionado es major +1 por plugin — no una versión ú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 |
El paquete Composer publica 2.0.0. La v1 permanece disponible en el tag v1-final.
composer require ozi-ui/core:^2.0
2. Cero jQuery — qué hacer
Antes (v1): ozi.js distribuía y usaba jQuery; muchos proyectos contaban con el window.$ que "venía incluido".
Después (v2): el núcleo no usa jQuery y no lo carga en el boot. Sigue distribuido en core/jquery-3.7.1.min.js para quien lo necesite.
Acción: si tu app dependía del jQuery que venía con ozi-ui, pasa a incluirlo por tu cuenta:
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
3. Contrato de eventos — el cambio más importante
En la v1 los eventos eran dual-dispatch: $(el).trigger() (payload posicional de jQuery) y CustomEvent. En la v2 es solo CustomEvent nativo, con el payload en detail:
detail: { component: 'ozi-select', name: 'uf', value: 'SP', items: [...], source: 'user' }
// source: 'user' (interacción del usuario) | 'api' (setValue programático)
Consumir 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>
Cambios de clave en el detail
| v1 | v2 |
|---|---|
key |
name |
instance |
eliminado — usa OZI.components.select.get(el) |
ozi-check: source (switch/group/item) |
level — source ahora es 'user'|'api' |
ozi-search |
value = query; mantiene query/matched/total |
ozi-auth |
novedad v2 — ahora emite CustomEvent (era solo jQuery) |
Todos los componentes pasaron a emitir ozi:init (tras la inicialización) y ozi:destroy.
Compatibilidad sin reescribir (shims)
Si tienes consumidores en el formato posicional de la v1, activa el shim — escucha el CustomEvent y lo re-emite vía jQuery en el formato antiguo. Nada de tu código necesita cambiar.
integrations/adapters/ozi-change-v1-compat.shim.js—ozi:changeposicionalintegrations/adapters/ozi-check-v1-events.shim.js—oziCheck:initFetched
Los shims son temporales y requieren jQuery. Migra a addEventListener cuando puedas.
4. Descontinuados: ozi-copy y ozi-paste
Fueron eliminados en la v2. Los sustitutos son recetas cortas en Alpine o JS puro — sin dependencia de FontAwesome.
<!-- Sustituto de ozi-copy -->
<button type="button"
x-data="{ copied: false }"
@click="navigator.clipboard.writeText('ABC-123').then(() => { copied = true; setTimeout(() => copied = false, 1500) })">
<span x-text="copied ? '✓ copiado' : 'Copiar'"></span>
</button>
Los plugins v1 siguen disponibles en el tag v1-final.
ozi-audioNO fue descontinuado — sigue en el alcance y fue migrado (v4.0.0).
5. Livewire
El adapter ganó el modo nativo, que respeta los modificadores de wire:model:
<!-- Modo A (preferido): dispatch nativo — respeta .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: el adapter ignora
ozi:changeconsource: 'api'(cambio proveniente del propio Livewire). - Re-init tras el morph: es tarea de
ozi-hooks— nada que hacer. - Guard LW3 × LW4 automático.
6. Temas
El tema es dato: 4 archivos enlazados en el <head> (tokens.css, overrides.css, dark.css, classmap.js). El mismo build JS sirve los 3 temas — solo se cambia oziConf({ theme }).
<link rel="stylesheet" href="/plugins/ozi-ui/themes/tailwind/tokens.css">
<link rel="stylesheet" href="/plugins/ozi-ui/themes/tailwind/overrides.css"><!-- nuevo en la v2 -->
<link rel="stylesheet" href="/plugins/ozi-ui/themes/tailwind/dark.css">
<script>oziConf({ theme: 'tailwind' });</script>
Novedad v2: themes/tailwind/overrides.css, que no existía en la v1. ¿Tema propio? Copia themes/_template/.
7. Alias heredados
Siguen funcionando, con aviso en consola si core.log: true. Serán eliminados en una versión futura:
| Alias v1 | Usa en la 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 migración
- [ ] Incluir jQuery por tu cuenta si la app dependía del que venía con ozi-ui (§2)
- [ ] Cambiar los consumidores de
ozi:changeaaddEventListener+e.detail(§3) — o activar el shim - [ ] Sustituir
ozi-copy/ozi-pastepor las recetas Alpine (§4) - [ ] (Livewire) evaluar el modo A (
data-ozi-livewire-native) para respetarwire:model(§5) - [ ] (Tailwind) enlazar el nuevo
overrides.css(§6) - [ ] Eliminar usos de alias heredados (§7)
- [ ] Ejecutar la app con
oziConf({ core: { log: true } })para ver los avisos de deprecación
9. Lo que no cambia
- Atributos
data-ozi-*ydata-zld-*(markup declarativo) - API pública:
OZI.components.<nombre>ywindow.Ozi<Nombre> oziConf({...}),@oziScripts/@oziStyles(Blade),OZI.ready()ozi-loaddata: fetch, destino DOM, recolección, progress, actions — comportamiento idéntico