
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, main has been updated via 62002e41e6c13144cfedf2e233f6025abba2303d (commit) via 4592b8d034178759a81fcf26f5d2fabd513a4bfc (commit) from 0d1fec8082165b2210551386db0dc1d5007bb92f (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 62002e41e6c13144cfedf2e233f6025abba2303d 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 4592b8d034178759a81fcf26f5d2fabd513a4bfc 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