
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Evergreen ILS". The branch, rel_3_15 has been updated via a74eee956bea793f9f7f769a48de3303b1fd109d (commit) via 8028098a2b737824e42e13a846d0780e22494f45 (commit) from 9e153c29bda5658390ea6a6f5aacb680f91021dc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a74eee956bea793f9f7f769a48de3303b1fd109d Author: Stephanie Leary <stephanie.leary@equinoxoli.org> Date: Tue Mar 11 14:24:41 2025 +0000 LP2085844 Org-select keyboard, focus, & scrolling Adds the scroll-into-view capability to the org-select component, as well as other keyboard- and focus-related features that have been implemented in combobox but were never copied into org-select. Release-note: Replicate combobox keyboard, focus features in org-select Signed-off-by: Stephanie Leary <stephanie.leary@equinoxoli.org> Signed-off-by: Llewellyn Marshall <llewellyn.marshall@dncr.nc.gov> Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org> diff --git a/Open-ILS/src/eg2/src/app/share/org-select/org-select.component.ts b/Open-ILS/src/eg2/src/app/share/org-select/org-select.component.ts index 1f033be1ad..fd4c23b747 100644 --- a/Open-ILS/src/eg2/src/app/share/org-select/org-select.component.ts +++ b/Open-ILS/src/eg2/src/app/share/org-select/org-select.component.ts @@ -66,6 +66,7 @@ export class OrgSelectComponent implements OnInit, AfterViewInit { valueFromSetting: number = null; sortedOrgs: IdlObject[] = []; orgSelectGroup: FormGroup; + controller: HTMLInputElement; // Disable the entire input @Input() disabled: boolean; @@ -78,6 +79,10 @@ export class OrgSelectComponent implements OnInit, AfterViewInit { // ARIA label for selector. Required if there is no <label> in the markup. @Input() ariaLabel?: string; + // Optionally provide an aria-labelledby for the input. This should be one or more + // space-delimited ids of elements that describe this combobox. + @Input() ariaLabelledby: string; + // ARIA describedby, for attaching error messages @Input() ariaDescribedby?: string = null; @@ -271,7 +276,9 @@ export class OrgSelectComponent implements OnInit, AfterViewInit { } ngAfterViewInit(): void { - this.elm.nativeElement.querySelector('input').addEventListener('keydown', this.onKeydown.bind(this)); + document.querySelectorAll('ngb-typeahead-window button[disabled]').forEach(b => b.setAttribute('tabindex', '-1')); + this.controller = this.instance['_elementRef'].nativeElement as HTMLInputElement; + this.controller.addEventListener('keydown', this.onKeydown.bind(this)); } getDisplayLabel(org: IdlObject): string { @@ -381,6 +388,9 @@ export class OrgSelectComponent implements OnInit, AfterViewInit { // console.debug('Key: ', $event); if (this.instance.isPopupOpen()) { + if ($event.key === 'ArrowUp' || $event.key === 'ArrowDown') { + this.scrollEntries(); + } return; } @@ -409,6 +419,27 @@ export class OrgSelectComponent implements OnInit, AfterViewInit { setTimeout(() => this.click$.next('')); } + closeMe($event) { + this.instance.dismissPopup(); + } + + scrollEntries() { + // adapted from https://github.com/ng-bootstrap/ng-bootstrap/issues/4789 + if (!this.controller) {return;} + + const listbox = document.getElementById(this.controller.getAttribute('aria-owns')); + // console.debug("Listbox: ", listbox); + + const activeItem = document.getElementById(this.controller.getAttribute('aria-activedescendant')); + if (activeItem) { + if (activeItem.offsetTop < listbox.scrollTop) { + listbox.scrollTo({ top: activeItem.offsetTop }); + } else if (activeItem.offsetTop + activeItem.offsetHeight > listbox.scrollTop + listbox.clientHeight) { + listbox.scrollTo({ top: activeItem.offsetTop + activeItem.offsetHeight - listbox.clientHeight }); + } + } + } + // NgbTypeahead doesn't offer a way to style the dropdown // button directly, so we have to reach up and style it ourselves. applyDisableStyle() { commit 8028098a2b737824e42e13a846d0780e22494f45 Author: Stephanie Leary <stephanie.leary@equinoxoli.org> Date: Mon Mar 10 21:27:25 2025 +0000 LP2085844 Scroll focused combobox option into view When using the arrow up/down keys to scroll through the list of combobox suggestions, the listbox now scrolls to keep the focused option in view. Based on commenters' solutions from: https://github.com/ng-bootstrap/ng-bootstrap/issues/4789 Release-note: Scroll focused combobox option into view on arrow up/down Signed-off-by: Stephanie Leary <stephanie.leary@equinoxoli.org> Signed-off-by: Llewellyn Marshall <llewellyn.marshall@dncr.nc.gov> Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org> diff --git a/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.ts b/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.ts index 201a7ef6cf..5805ccfe5a 100644 --- a/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.ts +++ b/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.ts @@ -57,6 +57,7 @@ implements ControlValueAccessor, OnInit, AfterViewInit, OnChanges { selected: ComboboxEntry; click$: Subject<string>; entrylist: ComboboxEntry[]; + controller: HTMLInputElement; @ViewChild('instance', {static: false}) instance: NgbTypeahead; @ViewChild('defaultDisplayTemplate', {static: true}) defaultDisplayTemplate: TemplateRef<any>; @@ -401,9 +402,10 @@ implements ControlValueAccessor, OnInit, AfterViewInit, OnChanges { if (!this.selectedId && !this.selected){ this.selected = this.entrylist.find(e => e.id == null); } - + document.querySelectorAll('ngb-typeahead-window button[disabled]').forEach(b => b.setAttribute('tabindex', '-1')); - this.elm.nativeElement.querySelector('input').addEventListener('keydown', this.onKeydown.bind(this)); + this.controller = this.instance['_elementRef'].nativeElement as HTMLInputElement; + this.controller.addEventListener('keydown', this.onKeydown.bind(this)); } ngOnChanges(changes: SimpleChanges) { @@ -474,6 +476,9 @@ implements ControlValueAccessor, OnInit, AfterViewInit, OnChanges { //console.debug('Key: ', $event); if (this.instance.isPopupOpen()) { + if ($event.key === 'ArrowUp' || $event.key === 'ArrowDown') { + this.scrollEntries(); + } return; } @@ -495,6 +500,24 @@ implements ControlValueAccessor, OnInit, AfterViewInit, OnChanges { this.comboboxEnter.emit(this.selected.id); } + scrollEntries() { + // adapted from https://github.com/ng-bootstrap/ng-bootstrap/issues/4789 + if (!this.controller) + return; + + const listbox = document.getElementById(this.controller.getAttribute('aria-owns')); + // console.debug("Listbox: ", listbox); + + const activeItem = document.getElementById(this.controller.getAttribute('aria-activedescendant')); + if (activeItem) { + if (activeItem.offsetTop < listbox.scrollTop) { + listbox.scrollTo({ top: activeItem.offsetTop }); + } else if (activeItem.offsetTop + activeItem.offsetHeight > listbox.scrollTop + listbox.clientHeight) { + listbox.scrollTo({ top: activeItem.offsetTop + activeItem.offsetHeight - listbox.clientHeight }); + } + } + } + openMe($event) { // Give the input a chance to focus then fire the click // handler to force open the typeahead ----------------------------------------------------------------------- Summary of changes: .../src/app/share/combobox/combobox.component.ts | 27 ++++++++++++++++-- .../app/share/org-select/org-select.component.ts | 33 +++++++++++++++++++++- 2 files changed, 57 insertions(+), 3 deletions(-) hooks/post-receive -- Evergreen ILS