Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add keyboad navigation to select with autocomplete #3097

Merged
merged 11 commits into from
Aug 31, 2022
8 changes: 4 additions & 4 deletions src/app/playground-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1162,10 +1162,10 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [
name: 'Select Icon',
},
{
path: 'select-search-showcase.component',
link: '/select/select-search-showcase.component',
component: 'SelectSearchShowcaseComponent',
name: 'Select Search Showcase',
path: 'select-autocomplete-showcase.component',
link: '/select/select-autocomplete-showcase.component',
component: 'SelectAutocompleteShowcaseComponent',
name: 'Select Autocomplete Showcase',
},
],
},
Expand Down
34 changes: 18 additions & 16 deletions src/framework/theme/components/option/option.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,11 @@ import { NbSelectComponent } from '../select/select.component';
styleUrls: ['./option.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<nb-checkbox *ngIf="withCheckbox"
[checked]="selected"
[disabled]="disabled"
aria-hidden="true">
</nb-checkbox>
<nb-checkbox *ngIf="withCheckbox" [checked]="selected" [disabled]="disabled" aria-hidden="true"> </nb-checkbox>
<ng-content></ng-content>
`,
})
export class NbOptionComponent<T = any> implements OnDestroy, AfterViewInit, NbFocusableOption, NbHighlightableOption {

protected disabledByGroup = false;

/**
Expand Down Expand Up @@ -132,11 +127,13 @@ export class NbOptionComponent<T = any> implements OnDestroy, AfterViewInit, NbF
@HostBinding('attr.id')
id: string = `nb-option-${lastOptionId++}`;

constructor(@Optional() @Inject(NB_SELECT_INJECTION_TOKEN) parent,
protected elementRef: ElementRef,
protected cd: ChangeDetectorRef,
protected zone: NgZone,
protected renderer: Renderer2) {
constructor(
@Optional() @Inject(NB_SELECT_INJECTION_TOKEN) parent,
protected elementRef: ElementRef,
protected cd: ChangeDetectorRef,
protected zone: NgZone,
protected renderer: Renderer2,
) {
this.parent = parent;
}

Expand All @@ -146,9 +143,11 @@ export class NbOptionComponent<T = any> implements OnDestroy, AfterViewInit, NbF

ngAfterViewInit() {
// TODO: #2254
this.zone.runOutsideAngular(() => setTimeout(() => {
this.renderer.addClass(this.elementRef.nativeElement, 'nb-transition');
}));
this.zone.runOutsideAngular(() =>
setTimeout(() => {
this.renderer.addClass(this.elementRef.nativeElement, 'nb-transition');
}),
);
}

/**
Expand All @@ -162,6 +161,10 @@ export class NbOptionComponent<T = any> implements OnDestroy, AfterViewInit, NbF
return this.elementRef.nativeElement.textContent;
}

get hidden() {
return this.elementRef.nativeElement.hidden;
}

// TODO: replace with isShowCheckbox property to control this behaviour outside, issues/1965
@HostBinding('class.multiple')
get multiple() {
Expand All @@ -188,7 +191,7 @@ export class NbOptionComponent<T = any> implements OnDestroy, AfterViewInit, NbF
@HostBinding('class.active')
get activeClass() {
return this._active;
};
}
protected _active: boolean = false;

@HostListener('click', ['$event'])
Expand Down Expand Up @@ -252,5 +255,4 @@ export class NbOptionComponent<T = any> implements OnDestroy, AfterViewInit, NbF
this._active = false;
this.cd.markForCheck();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@use '../../styles/theming' as *;
@use '../form-field/form-field.component.theme' as form-field-theme;

@mixin select-with-autocomplete-filled {
nb-select-with-autocomplete.appearance-filled .select-button {
border-style: nb-theme(select-filled-border-style);
border-width: nb-theme(select-filled-border-width);
}

@each $size in nb-get-sizes() {
nb-select-with-autocomplete.appearance-filled.size-#{$size} .select-button {
padding: nb-theme(select-filled-#{$size}-padding);
@include nb-ltr(padding-right, nb-theme(select-icon-offset));
@include nb-rtl(padding-left, nb-theme(select-icon-offset));
}

@include form-field-theme.nb-form-field-with-prefix(
'nb-select-with-autocomplete.appearance-filled.size-#{$size} .select-button',
$size
);
}

@each $status in nb-get-statuses() {
nb-select-with-autocomplete.appearance-filled.status-#{$status} .select-button {
background-color: nb-theme(select-filled-#{$status}-background-color);
border-color: nb-theme(select-filled-#{$status}-border-color);
color: nb-theme(select-filled-#{$status}-text-color);

&.placeholder {
color: nb-theme(select-filled-#{$status}-placeholder-text-color);
}

&:focus {
background-color: nb-theme(select-filled-#{$status}-focus-background-color);
border-color: nb-theme(select-filled-#{$status}-focus-border-color);
}
&:hover {
background-color: nb-theme(select-filled-#{$status}-hover-background-color);
border-color: nb-theme(select-filled-#{$status}-hover-border-color);
}

&[disabled] {
background-color: nb-theme(select-filled-#{$status}-disabled-background-color);
border-color: nb-theme(select-filled-#{$status}-disabled-border-color);
color: nb-theme(select-filled-#{$status}-disabled-text-color);

nb-icon {
color: nb-theme(select-filled-#{$status}-disabled-icon-color);
}
}

nb-icon {
color: nb-theme(select-filled-#{$status}-icon-color);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@use '../../styles/theming' as *;
@use '../form-field/form-field.component.theme' as form-field-theme;

@mixin select-with-autocomplete-hero {
nb-select-with-autocomplete.appearance-hero .select-button {
border: none;
}

@each $size in nb-get-sizes() {
nb-select-with-autocomplete.appearance-hero.size-#{$size} .select-button {
padding: nb-theme(select-hero-#{$size}-padding);
@include nb-ltr(padding-right, nb-theme(select-icon-offset));
@include nb-rtl(padding-left, nb-theme(select-icon-offset));
}
@include form-field-theme.nb-form-field-with-prefix(
'nb-select-with-autocomplete.appearance-hero.size-#{$size} .select-button',
$size
);
}

@each $status in nb-get-statuses() {
nb-select-with-autocomplete.appearance-hero.status-#{$status} .select-button {
$left-color: nb-theme(select-hero-#{$status}-left-background-color);
$right-color: nb-theme(select-hero-#{$status}-right-background-color);
background-image: linear-gradient(to right, $left-color, $right-color);
color: nb-theme(select-hero-#{$status}-text-color);

&.placeholder {
color: nb-theme(select-hero-#{$status}-placeholder-text-color);
}

&:focus {
$left-color: nb-theme(select-hero-#{$status}-focus-left-background-color);
$right-color: nb-theme(select-hero-#{$status}-focus-right-background-color);
background-image: linear-gradient(to right, $left-color, $right-color);
}
&:hover {
$left-color: nb-theme(select-hero-#{$status}-hover-left-background-color);
$right-color: nb-theme(select-hero-#{$status}-hover-right-background-color);
background-image: linear-gradient(to right, $left-color, $right-color);
}
&[disabled] {
color: nb-theme(select-hero-#{$status}-disabled-text-color);
background-color: nb-theme(select-hero-#{$status}-disabled-background-color);
background-image: none;

nb-icon {
color: nb-theme(select-hero-#{$status}-disabled-icon-color);
}
}

nb-icon {
color: nb-theme(select-hero-#{$status}-icon-color);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
@use '../../styles/theming' as *;
@use '../form-field/form-field.component.theme' as form-field-theme;

@mixin select-with-autocomplete-outline {
nb-select-with-autocomplete.appearance-outline .select-button {
border-style: nb-theme(select-outline-border-style);
border-width: nb-theme(select-outline-border-width);

&.top {
border-top-style: nb-theme(select-outline-adjacent-border-style);
border-top-width: nb-theme(select-outline-adjacent-border-width);
}
&.bottom {
border-bottom-style: nb-theme(select-outline-adjacent-border-style);
border-bottom-width: nb-theme(select-outline-adjacent-border-width);
}
}

@each $status in nb-get-statuses() {
nb-select-with-autocomplete.appearance-outline.status-#{$status} .select-button {
background-color: nb-theme(select-outline-#{$status}-background-color);
border-color: nb-theme(select-outline-#{$status}-border-color);
color: nb-theme(select-outline-#{$status}-text-color);

&.placeholder {
color: nb-theme(select-outline-#{$status}-placeholder-text-color);
}
nb-icon {
color: nb-theme(select-outline-#{$status}-icon-color);
}

&:focus {
background-color: nb-theme(select-outline-#{$status}-focus-background-color);
border-color: nb-theme(select-outline-#{$status}-focus-border-color);
}
&:hover {
background-color: nb-theme(select-outline-#{$status}-hover-background-color);
border-color: nb-theme(select-outline-#{$status}-hover-border-color);
}

&[disabled] {
color: nb-theme(select-outline-#{$status}-disabled-text-color);
background-color: nb-theme(select-outline-#{$status}-disabled-background-color);
border-color: nb-theme(select-outline-#{$status}-disabled-border-color);

nb-icon {
color: nb-theme(select-outline-#{$status}-disabled-icon-color);
}
}

&.bottom,
&.top {
border-color: nb-theme(select-outline-#{$status}-open-border-color);
}

&.top {
border-top-color: nb-theme(select-outline-#{$status}-adjacent-border-color);
}
&.bottom {
border-bottom-color: nb-theme(select-outline-#{$status}-adjacent-border-color);
}
}
}

@each $size in nb-get-sizes() {
nb-select-with-autocomplete.appearance-outline.size-#{$size} .select-button {
padding: nb-theme(select-outline-#{$size}-padding);
@include nb-ltr(padding-right, nb-theme(select-icon-offset));
@include nb-rtl(padding-left, nb-theme(select-icon-offset));
}

@include form-field-theme.nb-form-field-with-prefix(
'nb-select-with-autocomplete.appearance-outline.size-#{$size} .select-button',
$size
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/

@use '../../styles/theming' as *;
@use '../form-field/form-field.component.theme' as form-field-theme;
@use 'select-with-autocomplete-outline';
@use 'select-with-autocomplete-filled';
@use 'select-with-autocomplete-hero';

@mixin nb-select-with-autocomplete-theme() {
nb-select-with-autocomplete .select-button {
min-width: nb-theme(select-min-width);
cursor: nb-theme(select-cursor);
font-family: nb-theme(select-text-font-family);

&.placeholder {
font-family: nb-theme(select-placeholder-text-font-family);
}
&:focus {
outline: none;
}
&[disabled] {
cursor: nb-theme(select-disabled-cursor);
}
}

@each $size in nb-get-sizes() {
nb-select-with-autocomplete.size-#{$size} {
.select-button {
font-size: nb-theme(select-#{$size}-text-font-size);
font-weight: nb-theme(select-#{$size}-text-font-weight);
line-height: nb-theme(select-#{$size}-text-line-height);

&.placeholder {
font-size: nb-theme(select-#{$size}-placeholder-text-font-size);
font-weight: nb-theme(select-#{$size}-placeholder-text-font-weight);
}

&.empty::before {
content: ' ';
display: block;
height: nb-theme(select-#{$size}-text-line-height);
}
}

&:not(.full-width) {
max-width: nb-theme(select-#{$size}-max-width);
}
}
}

@each $shape in nb-get-shapes() {
nb-select-with-autocomplete.shape-#{$shape} .select-button {
border-radius: nb-theme(select-#{$shape}-border-radius);
}
}

@include select-with-autocomplete-outline.select-with-autocomplete-outline();
@include select-with-autocomplete-filled.select-with-autocomplete-filled();
@include select-with-autocomplete-hero.select-with-autocomplete-hero();

@include form-field-theme.nb-form-field-root-component('nb-select-with-autocomplete');
}
Loading