From 6c06b6a2e336f27212cb8648887209f87387533e Mon Sep 17 00:00:00 2001 From: Shevchik Igor Date: Sat, 20 Jun 2026 09:50:32 +0000 Subject: [PATCH] feat(Modal/Slideover): add leave and enter events (#6596) Port of upstream nuxt/ui 006324ae. Modal and Slideover gain 'enter' and 'leave' emits (alongside the existing after:enter / after:leave), wired to the reka-ui dialog content's @enter / @leave transition hooks. - src/runtime/components/Modal.vue: add 'leave': [] and 'enter': [] to ModalEmits; add @enter/@leave handlers on the content. - src/runtime/components/Slideover.vue: same for SlideoverEmits and content. Direct 1:1 (both matched the upstream pre-change). Docs untouched (emit tables are generated from component-meta). Emit additions don't change markup, so no snapshot churn. Ledger: record the merge sha for the previous port (#202, f99778e3) and advance the sync cursor to 006324ae. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01Qz7EXMncvEGiCj4WbmYgJo --- ...06324aeb91ae4054c314c9cb4a9d552fe04e44e.md | 27 +++++++++++++++++++ .sync/nuxt-ui.json | 10 +++++-- src/runtime/components/Modal.vue | 4 +++ src/runtime/components/Slideover.vue | 4 +++ 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 .sync/log/006324aeb91ae4054c314c9cb4a9d552fe04e44e.md diff --git a/.sync/log/006324aeb91ae4054c314c9cb4a9d552fe04e44e.md b/.sync/log/006324aeb91ae4054c314c9cb4a9d552fe04e44e.md new file mode 100644 index 000000000..e0e601f25 --- /dev/null +++ b/.sync/log/006324aeb91ae4054c314c9cb4a9d552fe04e44e.md @@ -0,0 +1,27 @@ +# Port: feat(Modal/Slideover): add `leave` and `enter` events (#6596) + +**Upstream:** `006324aeb91ae4054c314c9cb4a9d552fe04e44e` (nuxt/ui) +**Decision:** port + +## Upstream change +`Modal.vue` and `Slideover.vue` gain `enter` and `leave` emits (alongside the +existing `after:enter` / `after:leave`), wired to the reka-ui dialog content's +`@enter` / `@leave` transition hooks. + +## b24ui adaptation +Direct 1:1 — both b24ui components matched the upstream pre-change exactly +(same `*Emits extends DialogRootEmits` interface, same `@after-enter` / +`@after-leave` handlers on the content). No `ui → b24ui` / icon / color +rewrites needed for these lines. +- `src/runtime/components/Modal.vue`: add `'leave': []` and `'enter': []` to + `ModalEmits`; add `@enter="emits('enter')"` and `@leave="emits('leave')"` on + the content element. +- `src/runtime/components/Slideover.vue`: same for `SlideoverEmits` and the + content element. + +Docs untouched (upstream didn't touch docs; b24ui Modal/Slideover emit tables +are generated from component-meta). + +## Verification (pnpm 11.6.0, gate ON) +dev:prepare · lint · typecheck · test · module build — green. Emit additions +don't change rendered markup → no snapshot churn. diff --git a/.sync/nuxt-ui.json b/.sync/nuxt-ui.json index 310ac22d0..30415f4c3 100644 --- a/.sync/nuxt-ui.json +++ b/.sync/nuxt-ui.json @@ -2,7 +2,7 @@ "upstream": "nuxt/ui", "branch": "v4", "sync_enabled": false, - "cursor": "f99778e3e7639c11f6b46a4e4c57fbc66077195a", + "cursor": "006324aeb91ae4054c314c9cb4a9d552fe04e44e", "_cursor_note": "cursor = last upstream commit ported into b24ui (oldest-first, manual cadence). sync_enabled stays false until Phase 2 (porter workflow #67 + CLAUDE_CODE_OAUTH_TOKEN) is wired and trusted. `processed` is maintained per port from now on (backfilled #68-#72 on 2026-06-09).", "stats": { "queue_depth": 0, @@ -611,10 +611,16 @@ "summary": "chore(deps): update tiptap to ^3.26.1 (#6593) — all @tiptap/* b24ui pins ^3.26.0->^3.26.1 (root 17 pkgs + extension-emoji/extension-text-align in docs/playgrounds nuxt+demo+vue; nuxt<->demo parity kept). b24ui pins the same tiptap set as upstream, no missing pkgs, peer ranges untouched. Combined into the deps-batch PR with 39090327+7e359508" }, "f99778e3e7639c11f6b46a4e4c57fbc66077195a": { + "pr": 202, + "b24ui_sha": "f0e21619", + "decision": "port", + "summary": "feat(ChatMessages): expose registerMessageRef (#6275) — ChatMessages.vue: defineExpose({ registerMessageRef }) + pass it to the default slot (), and type the default slot prop (registerMessageRef: (id, element: ComponentPublicInstance|null)=>void). Direct 1:1 (ui->b24ui already applied; registerMessageRef fn + imports already present). +docs Expose section. No snapshot churn (binding/expose don't change markup)" + }, + "006324aeb91ae4054c314c9cb4a9d552fe04e44e": { "pr": null, "b24ui_sha": "pending-merge", "decision": "port", - "summary": "feat(ChatMessages): expose registerMessageRef (#6275) — ChatMessages.vue: defineExpose({ registerMessageRef }) + pass it to the default slot (), and type the default slot prop (registerMessageRef: (id, element: ComponentPublicInstance|null)=>void). Direct 1:1 (ui->b24ui already applied; registerMessageRef fn + imports already present). +docs Expose section. No snapshot churn (binding/expose don't change markup)" + "summary": "feat(Modal/Slideover): add leave and enter events (#6596) — Modal.vue + Slideover.vue: add 'leave':[] and 'enter':[] to *Emits and wire @enter=emits('enter') / @leave=emits('leave') on the reka dialog content (alongside existing after:enter/after:leave). Direct 1:1 (both matched the pre-change). Docs untouched (emit tables generated from component-meta). No snapshot churn" } } } diff --git a/src/runtime/components/Modal.vue b/src/runtime/components/Modal.vue index 1e3a4f023..a0a6397cb 100644 --- a/src/runtime/components/Modal.vue +++ b/src/runtime/components/Modal.vue @@ -71,7 +71,9 @@ export interface ModalProps extends DialogRootProps { } export interface ModalEmits extends DialogRootEmits { + 'leave': [] 'after:leave': [] + 'enter': [] 'after:enter': [] 'close:prevent': [] } @@ -164,7 +166,9 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...(appConfig.b24ui?.modal data-slot="content" :class="b24ui.content({ class: [!slots.default && props.class, props.b24ui?.content] })" v-bind="contentProps" + @enter="emits('enter')" @after-enter="emits('after:enter')" + @leave="emits('leave')" @after-leave="emits('after:leave')" v-on="contentEvents" > diff --git a/src/runtime/components/Slideover.vue b/src/runtime/components/Slideover.vue index c6e7b2763..53e43fa8c 100644 --- a/src/runtime/components/Slideover.vue +++ b/src/runtime/components/Slideover.vue @@ -68,7 +68,9 @@ export interface SlideoverProps extends DialogRootProps { } export interface SlideoverEmits extends DialogRootEmits { + 'leave': [] 'after:leave': [] + 'enter': [] 'after:enter': [] 'close:prevent': [] } @@ -169,7 +171,9 @@ const isBtnCloseExternal = computed(() => (!props.inset && ['left', 'right', 'bo data-slot="content" :class="b24ui.content({ class: [!slots.default && props.class, props.b24ui?.content] })" v-bind="contentProps" + @enter="emits('enter')" @after-enter="emits('after:enter')" + @leave="emits('leave')" @after-leave="emits('after:leave')" v-on="contentEvents" >