Conversation
falkoschindler
left a comment
There was a problem hiding this comment.
Thanks for the pull request, @evnchn! Now I finally looked into it more closely. After merging from main and fixing some obvious linter errors there are still several unresolved issues:
- Mypy isn't happy with
action['class'] = f'text-{color} ' + action.get('class', '')because the class could be any type. Same for "style". - But I don't see the point of adding
action.get('class', '')because it should be always undefined. Same for "style". - Why should we ask the user for an event name and not provide a
handlerparameter directly? I thinkjs_handlerand otheronparameters aren't needed for now.
And here is Claude's review:
BLOCKER
1. assert used for input validation (notification.py:227)
assert '"' not in event_name, 'Event names must not contain double quotes (")'assert statements are stripped when Python runs with -O (optimize). This is the only guard against injection into the :handler JS string. Should be a proper ValueError:
- assert '"' not in event_name, 'Event names must not contain double quotes (")'
+ if '"' in event_name:
+ raise ValueError('Event names must not contain double quotes (")')2. Insufficient sanitization of event_name — potential JS injection (notification.py:235)
The handler string is:
f'() => getElement({self.id}).$emit("{event_name}")'Only " is blocked. But backslashes and other characters could break out of the string context. For example, event_name = 'x\\")+alert(1)//' or crafted sequences with backslash escapes. Consider allowlisting (e.g., re.match(r'^[a-zA-Z0-9_-]+$', event_name)) rather than blocklisting a single character.
3. Missing tests
The PR checklist marks tests as not done. For a new public API method on a core element, tests are needed — at minimum verifying the actions dict structure, color handling for all three branches (Quasar/Tailwind/CSS), the no_dismiss flag, and that invalid event names are rejected.
MAJOR
4. kwargs can silently overwrite color-derived keys (notification.py:243)
action.update(kwargs)If a user passes class_='some-class' or style='...' via kwargs, it will overwrite the Tailwind class or CSS style set by the color logic just above. The color handling should either merge with kwargs or run after update(kwargs). For example:
action.update(kwargs)
# Then apply color on top, or merge rather than overwrite5. icon: None is always included in the action dict (notification.py:234)
When icon is None, it's still sent as 'icon': None. The notification constructor itself skips the key when icon is None (line 86-87). For consistency and to avoid sending unnecessary props to Quasar:
action = {
'noDismiss': no_dismiss,
'label': text,
- 'icon': icon,
':handler': f'() => getElement({self.id}).$emit("{event_name}")',
}
+ if icon is not None:
+ action['icon'] = icon6. Documentation claim is inaccurate
The demo docstring says "It takes the same arguments as ui.button" but it doesn't — it takes text, color, icon, and no_dismiss, plus Quasar QBtn kwargs. The ui.button API is much broader (with on_click, validation, etc.). This could mislead users.
CLEANUP
7. label parameter naming
The parameter is called text but maps to 'label' in the dict. NiceGUI's ui.button also uses text and maps to label internally, so this is consistent. Just noting it's fine.
8. The setdefault + append pattern could be simplified
self._props['options'].setdefault('actions', [])
# ...
self._props['options']['actions'].append(action)Could be one line shorter but it's readable as-is — no action needed.
…tization and tests - Replace event_name param with on_click callback (auto-generates internal event names) - Remove js_handler param (not needed per review) - Apply kwargs before color logic so color-derived class/style cannot be overwritten - Only include icon in action dict when not None - Fix docstring to accurately describe parameters - Add 11 tests covering structure, colors, no_dismiss, chaining, kwargs ordering - Update demo to use new on_click API Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Motivation
Addresses NiceGUI Wishlist (view), how we had to leverage
kwargsto define actions for notifications.Implementation
ui.notification_action, since:.onmethod, which covers both Python handler and JavaScript handlernotification.add_action, which lets adding a button (yep the action is a QBtn definition, check Quasar docs) which triggers an event when clicked.onto listen to the event we just defined.mixins.color_elements, but now since it is not an element but just a dictionary, we update it a bit differently.Progress
-> Do we need pytest? If so, tell me and I'll take a shot at it...
Feature request: #4514