diff --git a/packages/mosaic/core/option/option.ts b/packages/mosaic/core/option/option.ts index ddbf4fcd8..d3692ae67 100644 --- a/packages/mosaic/core/option/option.ts +++ b/packages/mosaic/core/option/option.ts @@ -160,6 +160,10 @@ export class McOption implements AfterViewChecked, OnDestroy { this.stateChanges.complete(); } + getHeight(): number { + return this.element.nativeElement.getClientRects()[0].height; + } + select(): void { if (!this._selected) { this._selected = true; diff --git a/packages/mosaic/select/select.component.ts b/packages/mosaic/select/select.component.ts index 62f64fcc2..427163c31 100644 --- a/packages/mosaic/select/select.component.ts +++ b/packages/mosaic/select/select.component.ts @@ -41,7 +41,9 @@ import { RIGHT_ARROW, SPACE, UP_ARROW, - A + A, + PAGE_UP, + PAGE_DOWN } from '@ptsecurity/cdk/keycodes'; import { CdkConnectedOverlay, @@ -738,6 +740,8 @@ export class McSelect extends McSelectMixinBase implements this._changeDetectorRef.detectChanges(); this.calculateOverlayOffsetX(); this.optionsContainer.nativeElement.scrollTop = this.scrollTop; + + this.updateScrollSize(); }); } @@ -835,6 +839,18 @@ export class McSelect extends McSelectMixinBase implements this._changeDetectorRef.markForCheck(); } + private getHeightOfOptionsContainer(): number { + return this.optionsContainer.nativeElement.getClientRects()[0].height; + } + + private updateScrollSize(): void { + if (!this.options.first) { return; } + + this.keyManager.withScrollSize( + Math.floor(this.getHeightOfOptionsContainer() / this.options.first.getHeight()) + ); + } + private getTotalItemsWidthInMatcher(): number { const triggerClone = this.trigger.nativeElement.cloneNode(true); triggerClone.querySelector('.mc-select__match-hidden-text').remove(); @@ -881,19 +897,26 @@ export class McSelect extends McSelectMixinBase implements const isArrowKey = keyCode === DOWN_ARROW || keyCode === UP_ARROW; const manager = this.keyManager; - if (keyCode === HOME || keyCode === END) { + if (isArrowKey && event.altKey) { + // Close the select on ALT + arrow key to match the native + manager.setPreviousPageItemActive(); + } else if (keyCode === PAGE_DOWN) { event.preventDefault(); - this.close(); + + manager.setNextPageItemActive(); } else if ((keyCode === ENTER || keyCode === SPACE) && manager.activeItem) { event.preventDefault(); manager.activeItem.selectViaInteraction(); diff --git a/packages/mosaic/tree-select/tree-select.component.spec.ts b/packages/mosaic/tree-select/tree-select.component.spec.ts index f3a9adcc3..eb9debf26 100644 --- a/packages/mosaic/tree-select/tree-select.component.spec.ts +++ b/packages/mosaic/tree-select/tree-select.component.spec.ts @@ -1579,7 +1579,7 @@ describe('McTreeSelect', () => { expect(formControl.value).toBeFalsy('Expected value not to have changed.'); })); - it('should should close when pressing ALT + DOWN_ARROW', fakeAsync(() => { + it('should close when pressing ALT + DOWN_ARROW', fakeAsync(() => { const { select: selectInstance } = fixture.componentInstance; selectInstance.open(); @@ -1595,7 +1595,7 @@ describe('McTreeSelect', () => { expect(event.defaultPrevented).toBe(true, 'Expected default action to be prevented.'); })); - it('should should close when pressing ALT + UP_ARROW', fakeAsync(() => { + it('should close when pressing ALT + UP_ARROW', fakeAsync(() => { const { select: selectInstance } = fixture.componentInstance; selectInstance.open(); diff --git a/packages/mosaic/tree-select/tree-select.component.ts b/packages/mosaic/tree-select/tree-select.component.ts index 7ab5f436a..cfe09f6a6 100644 --- a/packages/mosaic/tree-select/tree-select.component.ts +++ b/packages/mosaic/tree-select/tree-select.component.ts @@ -42,7 +42,7 @@ import { RIGHT_ARROW, SPACE, UP_ARROW, - A + A, PAGE_UP, PAGE_DOWN } from '@ptsecurity/cdk/keycodes'; import { CdkConnectedOverlay, @@ -544,8 +544,7 @@ export class McTreeSelect extends McTreeSelectMixinBase implements this.ngZone.onStable.asObservable() .pipe(take(1)) .subscribe(() => { - if (this.triggerFontSize && this.overlayDir.overlayRef && - this.overlayDir.overlayRef.overlayElement) { + if (this.triggerFontSize && this.overlayDir.overlayRef && this.overlayDir.overlayRef.overlayElement) { this.overlayDir.overlayRef.overlayElement.style.fontSize = `${this.triggerFontSize}px`; } }); @@ -688,6 +687,8 @@ export class McTreeSelect extends McTreeSelectMixinBase implements this.changeDetectorRef.detectChanges(); this.calculateOverlayOffsetX(); this.panel.nativeElement.scrollTop = this.scrollTop; + + this.tree.updateScrollSize(); }); } @@ -854,14 +855,22 @@ export class McTreeSelect extends McTreeSelectMixinBase implements this.close(); } else if (keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW) { return this.originalOnKeyDown.call(this.tree, event); - } else if (keyCode === HOME || keyCode === END) { + } else if (keyCode === HOME) { event.preventDefault(); - if (keyCode === HOME) { - this.tree.keyManager.setFirstItemActive(); - } else { - this.tree.keyManager.setLastItemActive(); - } + this.tree.keyManager.setFirstItemActive(); + } else if (keyCode === END) { + event.preventDefault(); + + this.tree.keyManager.setLastItemActive(); + } else if (keyCode === PAGE_UP) { + event.preventDefault(); + + this.tree.keyManager.setPreviousPageItemActive(); + } else if (keyCode === PAGE_DOWN) { + event.preventDefault(); + + this.tree.keyManager.setNextPageItemActive(); } else if ((keyCode === ENTER || keyCode === SPACE) && this.tree.keyManager.activeItem) { event.preventDefault(); diff --git a/packages/mosaic/tree-select/tree-select.html b/packages/mosaic/tree-select/tree-select.html index 5d0dd263d..4d60155a7 100644 --- a/packages/mosaic/tree-select/tree-select.html +++ b/packages/mosaic/tree-select/tree-select.html @@ -52,7 +52,8 @@ [style.font-size.px]="triggerFontSize" (keydown)="handleKeydown($event)"> -
diff --git a/packages/mosaic/tree-select/tree-select.scss b/packages/mosaic/tree-select/tree-select.scss index 5a83ae07e..51440bcb5 100644 --- a/packages/mosaic/tree-select/tree-select.scss +++ b/packages/mosaic/tree-select/tree-select.scss @@ -151,6 +151,10 @@ $mc-select-placeholder-arrow-space: 2 * ($mc-select-arrow-size + $mc-select-arro .mc-tree-select__content { height: 100%; + + & .mc-tree-selection { + height: 100%; + } } // Override optgroup and option to scale based on font-size of the trigger. diff --git a/packages/mosaic/tree/tree-option.ts b/packages/mosaic/tree/tree-option.ts index 76d4d9ffa..8d48de6f0 100644 --- a/packages/mosaic/tree/tree-option.ts +++ b/packages/mosaic/tree/tree-option.ts @@ -168,6 +168,7 @@ export class McTreeOption extends CdkTreeNode implements CanDisabl getHeight(): number { const clientRects = this.elementRef.nativeElement.getClientRects(); + if (clientRects.length) { return clientRects[0].height; } diff --git a/packages/mosaic/tree/tree-selection.ts b/packages/mosaic/tree/tree-selection.ts index 9074c34b3..fe1b12737 100644 --- a/packages/mosaic/tree/tree-selection.ts +++ b/packages/mosaic/tree/tree-selection.ts @@ -299,6 +299,7 @@ export class McTreeSelection extends McTreeSelectionBaseMixin getHeight(): number { const clientRects = this.elementRef.nativeElement.getClientRects(); + if (clientRects.length) { return clientRects[0].height; }