Skip to content

fix(ui5-toolbar-select): display not updating on programmatic option selection#13751

Open
NakataCode wants to merge 1 commit into
mainfrom
toolbar-select-programmatic-selection-sync
Open

fix(ui5-toolbar-select): display not updating on programmatic option selection#13751
NakataCode wants to merge 1 commit into
mainfrom
toolbar-select-programmatic-selection-sync

Conversation

@NakataCode

Copy link
Copy Markdown
Contributor

Problem

Since v2.15.0, changing the selected option programmatically (setting
ToolbarSelectOption.selected = true/false) correctly updated the outer
ui5-toolbar-select-option elements but left the inner ui5-select
display frozen on the initially selected option.

Two root causes:

  1. ToolbarSelectOption had a custom getter reading hasAttribute("selected").
    The framework sets the DOM attribute before calling the property setter, so
    change detection always saw old === new and skipped invalidation — meaning
    ToolbarSelect never re-rendered on programmatic changes.

  2. The template passed value={this.value} to the inner <Select>, feeding
    _valueStorage on every render. Once set, Select._applySelectionByValue
    locks the display to the stored string and ignores the selected attribute
    on inner options entirely.

Solution

  • ToolbarSelectOption — revert to plain @property, removing the broken
    getter/setter. Framework change detection now works correctly.
  • ToolbarSelectTemplate — remove value={this.value} from inner <Select>.
    Selection is driven by selected on inner <Option> elements as rendered by
    the template.
  • ToolbarSelect:
    • value setter: skip forwarding empty string to avoid poisoning _valueStorage
      on init.
    • value getter: read directly from the selected option, no _valueStorage
      dependency.
    • onBeforeRendering: enforce single-selection (last selected wins), guarded
      to avoid unnecessary writes that could trigger re-render loops.
    • onAfterRendering: deferred apply for explicit value= API only, clears
      _value after applying.
    • _syncOptions: clear _value on user interaction so a prior explicit
      value= assignment does not override the user's choice.

Fixes: #12619

@NakataCode NakataCode temporarily deployed to netlify-preview June 26, 2026 11:43 — with GitHub Actions Inactive

@PetyaMarkovaBogdanova PetyaMarkovaBogdanova left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

High: explicit clearing via value = "" no longer updates the inner select once rendered
ToolbarSelect.ts:152 returns early for falsy values and never forwards empty string to the rendered inner Select.
Impact: after the component is mounted, setting value to empty string can leave the old visual selection in place, which is a behavioral regression for programmatic API use.

High: stale _value can override later programmatic selected changes
In ToolbarSelect.ts:164, getter prioritizes _value when present.
In ToolbarSelect.ts:220, _value is cleared only when select.value !== _value.
If initial value matches current select.value on first render, _value stays set. A later selected change on options can then be overwritten in ToolbarSelect.ts:221, forcing old _value back into the inner Select. This can reintroduce a display/source mismatch in mixed usage flows.

Medium: regression tests do not cover the two risky value lifecycle paths above
The added test in ToolbarSelect.cy.tsx:348 validates multi-selected normalization and inner option sync, but there is no coverage for:

setting value to empty string after render
initializing with value, then changing selected programmatically later (stale _value path)
Open Questions / Assumptions

Should value = "" be treated as a real API command to clear selection post-render, or only as init-time absence?
Is _value intended to be strictly pre-render staging only? If yes, it should be cleared deterministically after first render pass, not conditionally.
Change Summary

The core direction is good and addresses the reported root causes: removing custom selected accessors in ToolbarSelectOption and dropping value forwarding in the template are both correct. The remaining risk is concentrated in ToolbarSelect value staging/clearing logic, which currently introduces two high-probability edge regressions.

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

Labels

None yet

2 participants