Skip to content

Conversation

@bakspace-itk
Copy link

@bakspace-itk bakspace-itk commented Jan 28, 2026

Motivation

When adding chips as tags in a popup, pressing anything other than Enter would lose the chip. This caused confusion with users when saving a popup or tabbing on to the next input field.

Implementation

Using the blur-events, we update the list of chips when the chip input loses focus. Input is stored as an internal value to avoid losing the reference when losing focus, which normally clears the input field.

Progress

  • I chose a meaningful title that completes the sentence: "If applied, this PR will..."
  • The implementation is complete.
  • If this PR addresses a security issue, it has been coordinated via the security advisory process.
  • Pytests have been added (or are not necessary).
  • Documentation has been added (or is not necessary).

This change adds a blur event handler to the input_chips component that automatically commits the current input value as a new chip when the input field loses focus. This provides a better user experience by allowing users to add chips without explicitly pressing Enter.

The implementation:
- Uses the existing addValue() method to respect the new-value-mode setting
- Only adds non-empty values (trimmed)
- Clears the input field after adding the value

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Kristian Bak <[email protected]>
…s loss

This change adds blur event handling to the input_chips component using Python event listeners instead of JavaScript. When the input field loses focus, any typed value is automatically added as a chip.

Implementation details:
- Added _handle_input_value_change() to track what user is typing
- Added _handle_blur() to process the value when field loses focus
- Respects new-value-mode setting (add, add-unique, toggle)
- Added comprehensive tests for blur functionality with all modes

The solution works by:
1. Listening to 'input-value' events to track current input
2. Listening to 'blur' events to trigger chip creation
3. Applying the appropriate new-value-mode logic (add/add-unique/toggle)
4. Updating the component value which triggers UI update

Tests:
- All existing tests pass
- New test_input_chips_blur_adds_value() validates blur behavior for all modes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Kristian Bak <[email protected]>
The previous test didn't properly test the different new-value-mode behaviors.
Now it mirrors the test_add_new_values test by:
- Adding 'x' once
- Adding 'y' twice
- Validating that toggle mode removes the second 'y' (leaving only 'x')
- Validating that add-unique mode keeps only one 'y'
- Validating that add mode keeps both 'y' values

This ensures blur behavior matches Enter key behavior for all modes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Kristian Bak <[email protected]>
Documentation improvements:
- Clarified docstring to explain blur behavior (Tab, click away)
- Added explicit new_value_mode behavior descriptions with examples
- Explained chip removal via "x" icon

Code improvements:
- Added explanatory comments in test showing expected behavior for each mode
- Fixed linting warnings (use unpacking instead of concatenation)

All tests pass, linting clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Kristian Bak <[email protected]>
@evnchn

This comment was marked as resolved.

@falkoschindler falkoschindler added the question Status: Needs clarification from the author label Jan 28, 2026
The _handle_blur method doesn't use the event parameter - it only uses
the tracked _current_input_value. Removing the parameter follows the
NiceGUI pattern where handlers without event data don't take parameters.

Pylint now rates the file 10.00/10.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Kristian Bak <[email protected]>
@evnchn
Copy link
Collaborator

evnchn commented Jan 28, 2026

Next time, be sure to run the pipeline on your own fork (you can enable that with https://github.com/bakspace-itk/nicegui/actions and it doesn't charge you money I think as you're doing it on public repo) and perhaps clean up the commit history a bit before opening the PR 😄

@bakspace-itk
Copy link
Author

Next time, be sure to run the pipeline on your own fork (you can enable that with https://github.com/bakspace-itk/nicegui/actions and it doesn't charge you money I think as you're doing it on public repo) and perhaps clean up the commit history a bit before opening the PR 😄

Thanks, will do! This is my first time contributing to anything outside our own pond, so it's very exciting :)

Added a comprehensive example showing how input_chips automatically adds
values when the field loses focus (Tab, click away) in addition to Enter key.

The example demonstrates all three new_value_mode options:
- toggle: Adds if absent, removes if present
- add: Always adds (allows duplicates)
- add-unique: Only adds if not already present

This provides users with a clear reference for the blur feature.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Kristian Bak <[email protected]>
@bakspace-itk

This comment was marked as resolved.

@falkoschindler falkoschindler added analysis Status: Requires team/community input and removed question Status: Needs clarification from the author labels Jan 28, 2026
@evnchn

This comment was marked as resolved.

@bakspace-itk

This comment was marked as resolved.

@falkoschindler

This comment was marked as resolved.

@falkoschindler
Copy link
Contributor

Ok, so here is a minimum example:

ui.input_chips()

Type a word and press Tab to lose focus. The word will be added as a chip.
Without this PR, the input would be cleared without adding a chip.

@evnchn
Copy link
Collaborator

evnchn commented Jan 28, 2026

Oh then sorry but I don't like this.

Speaking from keyboard perspective, in the past:

  • Confirm entry: ENTER (1 keyclick)
  • Cancel entry: simply continue to navigate the page (0 keyclick implicit)

Now it is:

  • Confirm entry: simply continue to navigate the page (0 keyclick implicit)
  • Cancel entry: Ctrl+A, Delete, continue to navigate the page (2 keyclick)

Not an expert but surely we are breaking some accessibilty rules here.

The way to cancel should not be 2 keyclick with a combo in-between.


And also the UI for click-operation is also non-intuitive either. Even in GitHub when you type the label then click elsewhere, it doesn't auto-apply for you.

image

I do recognize the efficiency if confirm entry is the hot use case, so if we want to proceed, may we have this non-default and document the cons. Thanks!

@evnchn
Copy link
Collaborator

evnchn commented Jan 28, 2026

@bakspace-itk I found a way to do what this PR does without modifications to the library code.

ic = ui.input_chips()
ic.on('blur', js_handler="(e) => {e.target.dispatchEvent(new KeyboardEvent('keydown', {code: 'Enter', keyCode: 13}));}")

Maybe we should close this PR as such, considering low necessity and UI/UX concerns. If you agree please close it. Thanks

PS: Welcome to open another PR to document this. Please look at website/documentation/content/input_chips_documentation.py on where the demo will fit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

analysis Status: Requires team/community input

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants