23.9.0 (2026-08-12)
Multi-issue fix/enhancement release covering keyboard handling, typeahead emissions, virtual scroll measurement, disabled-state removal, SSR event replay, and non-searchable text selection.
Issues fixed
| Issue | Problem | Fix |
|---|---|---|
| #2517 | Disabled multiselect (or disabled items) could still be removed via × / clearItem
| unselect() now no-ops when the select or item is disabled
|
| #1504 | Selecting an item (or clearing search) re-emitted on typeahead (often null)
| Typeahead emits only on typing; select / close / clear no longer call typeahead.next
|
| #1475 | Virtual scroll optionHeight used clientHeight and ignored borders
| Measure with offsetHeight so border width is included
|
| #2549 | preventDefault threw during Angular event replay (SSR/hydration)
| Skip preventDefault when $event.eventPhase === EventPhase.REPLAY
|
| #2762 | _measureDimensions wrong with custom templates + groupBy + virtual scroll
| Measure group header and option heights separately; variable item offsets in the panel service |
| #2849 | Escape always called preventDefault, even when already closed
| Only close + preventDefault when the dropdown is open; parents/dialogs can handle Escape when closed
|
| #2744 | Keyboard nav / scroll broken with typeahead + custom option heights (empty → items) | Sync panel height after items arrive; retry measurement; keep virtual window in sync after programmatic scroll |
| #2669 | Could not highlight/copy selected label when searchable=false
| Allow text selection on .ng-value; pointer-events: none on .ng-input when not searchable
|
What's changed
Behavior
- Disabled removal guard —
unselect()ignores disabled select / disabled items. - Typeahead emit contract — emits on typing only; select / close / clear reset the search input without emitting. React via
(close)/(clear)instead. Docs updated accordingly. - Escape — consumed only when it closes an open dropdown.
- Non-searchable copy — selected value text is selectable/copyable without toggling the panel.
- SSR/hydration — mousedown handler is safe under Angular event replay.
Virtual scroll
- Option/group height measurement uses
offsetHeight. - Separate
itemHeight/groupHeightinNgDropdownPanelService, withgetItemHeight/getItemOffset/ variable-height range calculation. - Panel height refresh + measurement retry when items appear after an empty typeahead open.
- Re-render the virtual range when panel height sync grows
itemsPerViewport(content-sized → max-height). - Immediate virtual-range sync after keyboard-driven programmatic scroll.
Docs
- API + search example docs: typeahead emits on typing only; select / close / clear do not emit.
Notable commits (from #2851)
| Commit | Summary | Issues |
|---|---|---|
c0537b8
| Disabled unselect / remove-icon / clearItem guards
| #2517 |
1fdf433
| Typeahead emit-on-typing-only + docs | #1504 |
4cd672e
| Virtual scroll height via offsetHeight
| #1475 |
6ea28e5
| Skip preventDefault during EventPhase.REPLAY
| #2549 |
b7b9a5a
| Group vs option heights in panel service | #2762 |
efd1232
| Escape preventDefault only when open
| #2849 |
961b904
| Panel height sync for empty→items | #2744 |
25ac89b
| Copy/select selected label when not searchable | #2669 |
2884870
| Re-render virtual range after panel height sync (CI fix) | — |