Skip to content

Add @js_action decorator for client-side open/close/toggle optimization (continuation of zauberzeug#5843) - #166

Draft
evnchn wants to merge 6 commits into
mainfrom
jsaction
Draft

Add @js_action decorator for client-side open/close/toggle optimization (continuation of zauberzeug#5843)#166
evnchn wants to merge 6 commits into
mainfrom
jsaction

Conversation

@evnchn

@evnchn evnchn commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Opened by Claude Code on Evan's behalf.

Continuation of zauberzeug#5843 (@js_action decorator for client-side open/close/toggle optimization), moved to the fork because:

  1. The performance-aware crowd this optimizes for is not the majority of NiceGUI users, so it doesn't justify upstream API surface right now.
  2. The original motivating signal is gone: nicegui.io's INP scores recovered in Google Search Console after the docs revamp (cause not fully understood, but the empirical result stands).

Kept here for the day the trade-off flips (e.g. INP regresses again, or upstream grows a client-side-actions story). Branch is jsaction as closed upstream; merge conflicts with upstream main are unresolved as of moving.

evnchn and others added 6 commits February 28, 2026 09:34
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The js_action JS handlers set element props and invalidate the vnode
cache, but Vue's reactivity doesn't trigger a re-render because the
cached render path short-circuits before reading element props, so the
dependency is never tracked. Adding $forceUpdate() ensures Vue picks up
the prop change after cache invalidation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Set LOOPBACK = False so backdrop/outside clicks update model-value
directly on the client without a server round-trip. Also fix the
client-side loopback handler: unwrap single-element args arrays and
call $forceUpdate() to ensure Vue re-renders after cache invalidation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add type: ignore for update_wrapper on _JsActionDescriptor
- Add type: ignore for JsAction callbacks passed to on() in fab/dropdown
- Replace ValueElement import with hasattr check to break cyclic import
  (nicegui.element -> nicegui.js_action -> nicegui.elements.mixins.value_element)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add type: ignore for JsAction callbacks passed to on() in button,
chip, and item elements. The JsAction handler type doesn't match
GenericEventArguments but works correctly at runtime since it
ignores event arguments entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use proper typing instead of suppressing mypy errors:
- Add JsAction to Element.on() handler type since it already handles it at runtime
- Use TypeGuard for has_js_action() to enable mypy type narrowing
- Replace functools.update_wrapper with manual attribute copying to avoid arg-type mismatch
- Use explicit _JsActionDescriptor return types instead of TypeVar cast

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant