From c55e87d7e9a8abaf7095d13cf92c411a640db76c Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Wed, 8 Jun 2022 15:59:53 -0500 Subject: [PATCH 1/2] feat(autcomplete): initial commit --- src/api/docs/components/autocomplete.html | 7 + src/api/docs/customization/color.html | 18 +-- src/api/docs/customization/theming.html | 16 +-- ...omplete-simple-example.component.html.html | 16 +++ ...ocomplete-simple-example.component.ts.html | 13 ++ ...autocomplete-simple-example.module.ts.html | 23 ++++ .../demos/autocomplete.lazy.module.ts.html | 20 +++ ...autocomplete-simple-example.component.html | 16 +++ ...ocomplete-simple-example.component.spec.ts | 25 ++++ .../autocomplete-simple-example.component.ts | 12 ++ .../autocomplete-simple-example.module.ts | 22 +++ .../autocomplete.lazy.module.ts | 19 +++ .../autocomplete-demo/autocomplete.md | 10 ++ src/app/docs/element-registry.ts | 4 + src/app/routes.ts | 1 + src/lib/autocomplete/autocomplete-styles.ts | 10 ++ src/lib/autocomplete/autocomplete-trigger.ts | 126 ++++++++++++++++++ src/lib/autocomplete/autocomplete.html | 7 + src/lib/autocomplete/autocomplete.module.ts | 22 +++ src/lib/autocomplete/autocomplete.ts | 23 ++++ src/lib/autocomplete/index.ts | 1 + src/lib/autocomplete/public_api.ts | 2 + tsconfig.json | 1 + 23 files changed, 397 insertions(+), 17 deletions(-) create mode 100644 src/api/docs/components/autocomplete.html create mode 100644 src/api/docs/demos/autocomplete-simple-example.component.html.html create mode 100644 src/api/docs/demos/autocomplete-simple-example.component.ts.html create mode 100644 src/api/docs/demos/autocomplete-simple-example.module.ts.html create mode 100644 src/api/docs/demos/autocomplete.lazy.module.ts.html create mode 100644 src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.html create mode 100644 src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.spec.ts create mode 100644 src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.ts create mode 100644 src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.module.ts create mode 100644 src/app/docs/components/autocomplete-demo/autocomplete.lazy.module.ts create mode 100644 src/app/docs/components/autocomplete-demo/autocomplete.md create mode 100644 src/lib/autocomplete/autocomplete-styles.ts create mode 100644 src/lib/autocomplete/autocomplete-trigger.ts create mode 100644 src/lib/autocomplete/autocomplete.html create mode 100644 src/lib/autocomplete/autocomplete.module.ts create mode 100644 src/lib/autocomplete/autocomplete.ts create mode 100644 src/lib/autocomplete/index.ts create mode 100644 src/lib/autocomplete/public_api.ts diff --git a/src/api/docs/components/autocomplete.html b/src/api/docs/components/autocomplete.html new file mode 100644 index 000000000..c5bc4b690 --- /dev/null +++ b/src/api/docs/components/autocomplete.html @@ -0,0 +1,7 @@ + +

Autocomplete

+

The autocomplete is a normal text input enhanced by a panel of suggested options.

+

Simple Autocomplete

+ + + \ No newline at end of file diff --git a/src/api/docs/customization/color.html b/src/api/docs/customization/color.html index a47e7a7ad..d38d8c0ee 100644 --- a/src/api/docs/customization/color.html +++ b/src/api/docs/customization/color.html @@ -5,24 +5,24 @@

Color

Supported values

import { color } from '@alyle/ui/color';
 
-const Yellow = color(255, 255, 0);  // rgb
-const Black  = color(0);            // number
-const White  = color(0xffffff);     // hex
-const Text   = color(0, 0, 0, .87); // rgba
+const Yellow = color(255, 255, 0);  // rgb
+const Black  = color(0);            // number
+const White  = color(0xffffff);     // hex
+const Text   = color(0, 0, 0, .87); // rgba
 

Note that a 6-digit hexadecimal is different from a 3-digit hexadecimal.

-
color(0xffffff).css() !== color(0xfff).css(); // true
+
color(0xffffff).css() !== color(0xfff).css(); // true
 

How to use color

color and the previously mentioned methods returns an immutable Color.

import { color } from '@alyle/ui/color';
 
-const Yellow = color(255, 255, 0);
+const Yellow = color(255, 255, 0);
 

Using methods:

-
const Yellow = color(255, 255, 0);
+
const Yellow = color(255, 255, 0);
 Yellow.darken(2).alpha(.94).css(); // --> rgba(145,156,0,0.94)
 
-
color(0xffffff).luminance(); // --> 1
-color(0xffffff).luminance(0.5); // --> rgb(194,194,0)
+
color(0xffffff).luminance(); // --> 1
+color(0xffffff).luminance(0.5); // --> rgb(194,194,0)
 
\ No newline at end of file diff --git a/src/api/docs/customization/theming.html b/src/api/docs/customization/theming.html index 47e9d0005..fc98d2ffb 100644 --- a/src/api/docs/customization/theming.html +++ b/src/api/docs/customization/theming.html @@ -25,12 +25,12 @@

Overwriting the variables of a the export class CustomMinimaLight implements PartialThemeVariables { name = 'minima-light'; primary = { - default: color(0x2196f3), - contrast: color(0xffffff) + default: color(0x2196f3), + contrast: color(0xffffff) }; accent = { - default: color(0xe91e63), - contrast: color(0xffffff) + default: color(0xe91e63), + contrast: color(0xffffff) }; } @@ -41,12 +41,12 @@

Overwriting the variables of a the export class CustomMinimaDark implements PartialThemeVariables { name = 'minima-dark'; primary = { - default: color(0x9c27b0), - contrast: color(0xffffff) + default: color(0x9c27b0), + contrast: color(0xffffff) }; accent = { - default: color(0x69f0ae), - contrast: color(0x202020) + default: color(0x69f0ae), + contrast: color(0x202020) }; } diff --git a/src/api/docs/demos/autocomplete-simple-example.component.html.html b/src/api/docs/demos/autocomplete-simple-example.component.html.html new file mode 100644 index 000000000..6c6f02258 --- /dev/null +++ b/src/api/docs/demos/autocomplete-simple-example.component.html.html @@ -0,0 +1,16 @@ +
<form>
+  <ly-field class="example-full-width" appearance="filled">
+    <ly-label>Number</ly-label>
+    <input type="text"
+           placeholder="Pick one"
+           aria-label="Number"
+           lyInput
+           [formControl]="myControl"
+           [lyAutocomplete]="auto">
+    <ly-autocomplete #auto="lyAutocomplete">
+      <div *ngFor="let option of options">
+        {{ option }}
+      </div>
+    </ly-autocomplete>
+  </ly-field>
+</form>
\ No newline at end of file diff --git a/src/api/docs/demos/autocomplete-simple-example.component.ts.html b/src/api/docs/demos/autocomplete-simple-example.component.ts.html new file mode 100644 index 000000000..968983962 --- /dev/null +++ b/src/api/docs/demos/autocomplete-simple-example.component.ts.html @@ -0,0 +1,13 @@ +
import { Component, ChangeDetectionStrategy } from '@angular/core';
+import { FormControl } from '@angular/forms';
+
+@Component({
+  selector: 'aui-autocomplete-simple-example',
+  templateUrl: './autocomplete-simple-example.component.html',
+  changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class AutocompleteSimpleExampleComponent {
+  readonly myControl = new FormControl('');
+  options: string[] = ['One', 'Two', 'Three'];
+}
+
\ No newline at end of file diff --git a/src/api/docs/demos/autocomplete-simple-example.module.ts.html b/src/api/docs/demos/autocomplete-simple-example.module.ts.html new file mode 100644 index 000000000..df036afd3 --- /dev/null +++ b/src/api/docs/demos/autocomplete-simple-example.module.ts.html @@ -0,0 +1,23 @@ +
import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { ReactiveFormsModule } from '@angular/forms';
+import { LyFieldModule } from '@alyle/ui/field';
+import { LyAutocompleteModule } from '@alyle/ui/autocomplete';
+
+import { AutocompleteSimpleExampleComponent } from './autocomplete-simple-example.component';
+
+
+
+@NgModule({
+  declarations: [
+    AutocompleteSimpleExampleComponent
+  ],
+  imports: [
+    CommonModule,
+    ReactiveFormsModule,
+    LyFieldModule,
+    LyAutocompleteModule
+  ]
+})
+export class AutocompleteSimpleExampleModule { }
+
\ No newline at end of file diff --git a/src/api/docs/demos/autocomplete.lazy.module.ts.html b/src/api/docs/demos/autocomplete.lazy.module.ts.html new file mode 100644 index 000000000..be1c43261 --- /dev/null +++ b/src/api/docs/demos/autocomplete.lazy.module.ts.html @@ -0,0 +1,20 @@ +
import { NgModule, Type } from '@angular/core';
+import { WithCustomElementComponent } from '@app/docs/element-registry';
+import { AutocompleteSimpleExampleComponent } from './autocomplete-simple-example/autocomplete-simple-example.component';
+import { AutocompleteSimpleExampleModule } from './autocomplete-simple-example/autocomplete-simple-example.module';
+
+
+
+const elements = [
+  AutocompleteSimpleExampleComponent,
+];
+
+@NgModule({
+  imports: [
+    AutocompleteSimpleExampleModule,
+  ],
+})
+export class LazyModule implements WithCustomElementComponent {
+  customElementComponents: Type<any>[] = elements;
+}
+
\ No newline at end of file diff --git a/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.html b/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.html new file mode 100644 index 000000000..6eb537ba7 --- /dev/null +++ b/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.html @@ -0,0 +1,16 @@ +
+ + Number + + +
+ {{ option }} +
+
+
+
\ No newline at end of file diff --git a/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.spec.ts b/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.spec.ts new file mode 100644 index 000000000..8cb41ef2f --- /dev/null +++ b/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AutocompleteSimpleExampleComponent } from './autocomplete-simple-example.component'; + +describe('AutocompleteSimpleExampleComponent', () => { + let component: AutocompleteSimpleExampleComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AutocompleteSimpleExampleComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AutocompleteSimpleExampleComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.ts b/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.ts new file mode 100644 index 000000000..1b44324f9 --- /dev/null +++ b/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.component.ts @@ -0,0 +1,12 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { FormControl } from '@angular/forms'; + +@Component({ + selector: 'aui-autocomplete-simple-example', + templateUrl: './autocomplete-simple-example.component.html', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class AutocompleteSimpleExampleComponent { + readonly myControl = new FormControl(''); + options: string[] = ['One', 'Two', 'Three']; +} diff --git a/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.module.ts b/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.module.ts new file mode 100644 index 000000000..eb3a15fd7 --- /dev/null +++ b/src/app/docs/components/autocomplete-demo/autocomplete-simple-example/autocomplete-simple-example.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { LyFieldModule } from '@alyle/ui/field'; +import { LyAutocompleteModule } from '@alyle/ui/autocomplete'; + +import { AutocompleteSimpleExampleComponent } from './autocomplete-simple-example.component'; + + + +@NgModule({ + declarations: [ + AutocompleteSimpleExampleComponent + ], + imports: [ + CommonModule, + ReactiveFormsModule, + LyFieldModule, + LyAutocompleteModule + ] +}) +export class AutocompleteSimpleExampleModule { } diff --git a/src/app/docs/components/autocomplete-demo/autocomplete.lazy.module.ts b/src/app/docs/components/autocomplete-demo/autocomplete.lazy.module.ts new file mode 100644 index 000000000..69ef41d26 --- /dev/null +++ b/src/app/docs/components/autocomplete-demo/autocomplete.lazy.module.ts @@ -0,0 +1,19 @@ +import { NgModule, Type } from '@angular/core'; +import { WithCustomElementComponent } from '@app/docs/element-registry'; +import { AutocompleteSimpleExampleComponent } from './autocomplete-simple-example/autocomplete-simple-example.component'; +import { AutocompleteSimpleExampleModule } from './autocomplete-simple-example/autocomplete-simple-example.module'; + + + +const elements = [ + AutocompleteSimpleExampleComponent, +]; + +@NgModule({ + imports: [ + AutocompleteSimpleExampleModule, + ], +}) +export class LazyModule implements WithCustomElementComponent { + customElementComponents: Type[] = elements; +} diff --git a/src/app/docs/components/autocomplete-demo/autocomplete.md b/src/app/docs/components/autocomplete-demo/autocomplete.md new file mode 100644 index 000000000..14190eb7d --- /dev/null +++ b/src/app/docs/components/autocomplete-demo/autocomplete.md @@ -0,0 +1,10 @@ +# Autocomplete +{@path /components} + +The autocomplete is a normal text input enhanced by a panel of suggested options. + +## Simple Autocomplete + + + + \ No newline at end of file diff --git a/src/app/docs/element-registry.ts b/src/app/docs/element-registry.ts index db4a2bb0d..ec460a7f6 100644 --- a/src/app/docs/element-registry.ts +++ b/src/app/docs/element-registry.ts @@ -126,6 +126,10 @@ export const ELEMENT_MODULE_LOAD_CALLBACKS_AS_ROUTES = [ path: '/components/table', loadChildren: () => import('./components/table-demo/table.lazy.module').then(mod => mod.LazyModule) }, + { + path: '/components/autocomplete', + loadChildren: () => import('./components/autocomplete-demo/autocomplete.lazy.module').then(mod => mod.LazyModule) + }, ]; /** diff --git a/src/app/routes.ts b/src/app/routes.ts index 3bfbefb03..9b65b82fa 100644 --- a/src/app/routes.ts +++ b/src/app/routes.ts @@ -90,6 +90,7 @@ export const AUIRoutes: { { route: 'slider', api: true , name: 'Slider' }, { route: 'skeleton', api: true , name: 'Skeleton' }, { route: 'table', api: true , name: 'Table' }, + { route: 'autocomplete', api: true , name: 'Autocomplete' }, ].sort(sort) } ]; diff --git a/src/lib/autocomplete/autocomplete-styles.ts b/src/lib/autocomplete/autocomplete-styles.ts new file mode 100644 index 000000000..8ba675d59 --- /dev/null +++ b/src/lib/autocomplete/autocomplete-styles.ts @@ -0,0 +1,10 @@ +import { lyl, ThemeVariables } from '@alyle/ui'; + +export const STYLES = (_theme: ThemeVariables) => { + return { + root: lyl `{ + display: block + }`, + trigger: null, + }; +}; diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts new file mode 100644 index 000000000..f24b85542 --- /dev/null +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -0,0 +1,126 @@ +import { Directive, ElementRef, forwardRef, Input, ViewContainerRef } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { LyOverlay, OverlayFactory, StyleRenderer } from '@alyle/ui'; +import { STYLES as FIELD_STYLES } from '@alyle/ui/field'; +import { STYLES as AUTOCOMPLETE_STYLES } from './autocomplete-styles'; +import type { LyAutocomplete } from './autocomplete'; +import { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes'; + +/** + * Provider that allows the autocomplete to register as a ControlValueAccessor. + * @docs-private + */ +export const LY_AUTOCOMPLETE_VALUE_ACCESSOR: any = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => LyAutocompleteTrigger), + multi: true, +}; + +@Directive({ + selector: `input[lyAutocomplete], textarea[lyAutocomplete]`, + host: { + // Note: we use `focusin`, as opposed to `focus`, in order to open the panel + // a little earlier. + '(focusin)': '_handleFocus()', + '(blur)': '_onTouched()', + '(input)': '_handleInput($event)', + '(keydown)': '_handleKeydown($event)', + '(click)': '_handleClick()', + }, + exportAs: 'lyAutocompleteTrigger', + providers: [ + LY_AUTOCOMPLETE_VALUE_ACCESSOR, + StyleRenderer + ], +}) +export class LyAutocompleteTrigger { + readonly classes = this.sRenderer.renderSheet(AUTOCOMPLETE_STYLES, 'trigger'); + + private _overlayRef: OverlayFactory | null; + + /** The autocomplete panel to be attached to this trigger. */ + @Input('lyAutocomplete') autocomplete: LyAutocomplete; + + /** `View -> model callback called when value changes` */ + _onChange: (value: any) => void = () => {}; + + /** `View -> model callback called when autocomplete has been touched` */ + _onTouched = () => {}; + + constructor( + readonly sRenderer: StyleRenderer, + private _element: ElementRef, + private _overlay: LyOverlay, + private _viewContainerRef: ViewContainerRef, + ) { + this.sRenderer.renderSheet(FIELD_STYLES, 'inputNative'); + } + + /** Opens the autocomplete suggestion panel. */ + openPanel(): void { + this._attachOverlay(); + } + + _attachOverlay() { + if (!this.autocomplete) { + return; + } + let overlayRef = this._overlayRef; + + if (!overlayRef) { + overlayRef = this._overlay.create(this.autocomplete.template, { + $implicit: this, + data: {} + }, { + styles: { + top: 0, + left: 0, + pointerEvents: null + }, + fnDestroy: this.detach.bind(this), + hasBackdrop: false + }); + } else { + + } + } + + _handleFocus() { + + } + + _handleInput(_event: KeyboardEvent) { + + } + + _handleKeydown(event: KeyboardEvent) { + const keyCode = event.keyCode; + const hasModifier = hasModifierKey(event); + if (keyCode === ESCAPE && !hasModifier) { + event.preventDefault(); + } + } + + _handleClick() { + + } + + // Implemented as part of ControlValueAccessor. + writeValue(_value: any): void { } + + // Implemented as part of ControlValueAccessor. + registerOnChange(fn: (value: any) => {}): void { + this._onChange = fn; + } + + // Implemented as part of ControlValueAccessor. + registerOnTouched(fn: () => {}) { + this._onTouched = fn; + } + + // Implemented as part of ControlValueAccessor. + setDisabledState(isDisabled: boolean) { + this._element.nativeElement.disabled = isDisabled; + } + +} diff --git a/src/lib/autocomplete/autocomplete.html b/src/lib/autocomplete/autocomplete.html new file mode 100644 index 000000000..b4d54bc5d --- /dev/null +++ b/src/lib/autocomplete/autocomplete.html @@ -0,0 +1,7 @@ + +
+ +
+
diff --git a/src/lib/autocomplete/autocomplete.module.ts b/src/lib/autocomplete/autocomplete.module.ts new file mode 100644 index 000000000..72237347f --- /dev/null +++ b/src/lib/autocomplete/autocomplete.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { LyCommonModule } from '@alyle/ui'; +import { LyAutocomplete } from './autocomplete'; +import { LyAutocompleteTrigger } from './autocomplete-trigger'; + +@NgModule({ + imports: [ + CommonModule, + LyCommonModule + ], + declarations: [ + LyAutocomplete, + LyAutocompleteTrigger + ], + exports: [ + LyCommonModule, + LyAutocomplete, + LyAutocompleteTrigger + ], +}) +export class LyAutocompleteModule { } diff --git a/src/lib/autocomplete/autocomplete.ts b/src/lib/autocomplete/autocomplete.ts new file mode 100644 index 000000000..a5f9b68d5 --- /dev/null +++ b/src/lib/autocomplete/autocomplete.ts @@ -0,0 +1,23 @@ +import { ChangeDetectionStrategy, Component, TemplateRef, ViewChild } from '@angular/core'; +import { StyleRenderer } from '@alyle/ui'; +import { STYLES as AUTOCOMPLETE_STYLES } from './autocomplete-styles'; + +@Component({ + selector: 'ly-autocomplete', + templateUrl: 'autocomplete.html', + exportAs: 'lyAutocomplete', + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [ + StyleRenderer + ] +}) +export class LyAutocomplete { + readonly classes = this.sRenderer.renderSheet(AUTOCOMPLETE_STYLES); + + /** @docs-private */ + @ViewChild(TemplateRef, { static: true }) readonly template: TemplateRef; + + constructor( + readonly sRenderer: StyleRenderer + ) { } +} diff --git a/src/lib/autocomplete/index.ts b/src/lib/autocomplete/index.ts new file mode 100644 index 000000000..4aaf8f92e --- /dev/null +++ b/src/lib/autocomplete/index.ts @@ -0,0 +1 @@ +export * from './public_api'; diff --git a/src/lib/autocomplete/public_api.ts b/src/lib/autocomplete/public_api.ts new file mode 100644 index 000000000..1dd765795 --- /dev/null +++ b/src/lib/autocomplete/public_api.ts @@ -0,0 +1,2 @@ +export * from './autocomplete'; +export * from './autocomplete.module'; diff --git a/tsconfig.json b/tsconfig.json index 96fdff97b..5e7682fca 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -52,6 +52,7 @@ "@alyle/ui/color": ["./src/lib/color"], "@alyle/ui/skeleton": ["./src/lib/skeleton"], "@alyle/ui/table": ["./src/lib/table"], + "@alyle/ui/autocomplete": ["./src/lib/autocomplete"], "@alyle/ui/schematics/testing": ["./src/lib/schematics/testing"], "@env/*": ["./src/environments/*"], "@shared/*": ["./src/app/shared/*"], From a2faccb696700daf2039b5dc84742acbd156dde8 Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Fri, 10 Jun 2022 16:16:44 -0500 Subject: [PATCH 2/2] update --- src/api/docs/customization/color.html | 18 ++++++------- src/api/docs/customization/theming.html | 16 ++++++------ src/lib/autocomplete/autocomplete-trigger.ts | 27 ++++++++++++++------ src/lib/autocomplete/autocomplete.ts | 8 +++++- 4 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/api/docs/customization/color.html b/src/api/docs/customization/color.html index d38d8c0ee..3545988ff 100644 --- a/src/api/docs/customization/color.html +++ b/src/api/docs/customization/color.html @@ -5,24 +5,24 @@

Color

Supported values

import { color } from '@alyle/ui/color';
 
-const Yellow = color(255, 255, 0);  // rgb
-const Black  = color(0);            // number
-const White  = color(0xffffff);     // hex
-const Text   = color(0, 0, 0, .87); // rgba
+const Yellow = color(255, 255, 0);  // rgb
+const Black  = color(0);            // number
+const White  = color(0xffffff);     // hex
+const Text   = color(0, 0, 0, .87); // rgba
 

Note that a 6-digit hexadecimal is different from a 3-digit hexadecimal.

-
color(0xffffff).css() !== color(0xfff).css(); // true
+
color(0xffffff).css() !== color(0xfff).css(); // true
 

How to use color

color and the previously mentioned methods returns an immutable Color.

import { color } from '@alyle/ui/color';
 
-const Yellow = color(255, 255, 0);
+const Yellow = color(255, 255, 0);
 

Using methods:

-
const Yellow = color(255, 255, 0);
+
const Yellow = color(255, 255, 0);
 Yellow.darken(2).alpha(.94).css(); // --> rgba(145,156,0,0.94)
 
-
color(0xffffff).luminance(); // --> 1
-color(0xffffff).luminance(0.5); // --> rgb(194,194,0)
+
color(0xffffff).luminance(); // --> 1
+color(0xffffff).luminance(0.5); // --> rgb(194,194,0)
 
\ No newline at end of file diff --git a/src/api/docs/customization/theming.html b/src/api/docs/customization/theming.html index fc98d2ffb..25fcdbc8f 100644 --- a/src/api/docs/customization/theming.html +++ b/src/api/docs/customization/theming.html @@ -25,12 +25,12 @@

Overwriting the variables of a the export class CustomMinimaLight implements PartialThemeVariables { name = 'minima-light'; primary = { - default: color(0x2196f3), - contrast: color(0xffffff) + default: color(0x2196f3), + contrast: color(0xffffff) }; accent = { - default: color(0xe91e63), - contrast: color(0xffffff) + default: color(0xe91e63), + contrast: color(0xffffff) }; } @@ -41,12 +41,12 @@

Overwriting the variables of a the export class CustomMinimaDark implements PartialThemeVariables { name = 'minima-dark'; primary = { - default: color(0x9c27b0), - contrast: color(0xffffff) + default: color(0x9c27b0), + contrast: color(0xffffff) }; accent = { - default: color(0x69f0ae), - contrast: color(0x202020) + default: color(0x69f0ae), + contrast: color(0x202020) }; } diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index f24b85542..c206d9671 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -1,4 +1,4 @@ -import { Directive, ElementRef, forwardRef, Input, ViewContainerRef } from '@angular/core'; +import { Directive, ElementRef, forwardRef, Input } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { LyOverlay, OverlayFactory, StyleRenderer } from '@alyle/ui'; import { STYLES as FIELD_STYLES } from '@alyle/ui/field'; @@ -51,7 +51,6 @@ export class LyAutocompleteTrigger { readonly sRenderer: StyleRenderer, private _element: ElementRef, private _overlay: LyOverlay, - private _viewContainerRef: ViewContainerRef, ) { this.sRenderer.renderSheet(FIELD_STYLES, 'inputNative'); } @@ -61,14 +60,19 @@ export class LyAutocompleteTrigger { this._attachOverlay(); } + /** Closes the autocomplete suggestion panel. */ + closePanel(): void { + this.destroy(); + } + _attachOverlay() { if (!this.autocomplete) { return; } - let overlayRef = this._overlayRef; + const overlayRef = this._overlayRef; if (!overlayRef) { - overlayRef = this._overlay.create(this.autocomplete.template, { + this._overlayRef = this._overlay.create(this.autocomplete.template, { $implicit: this, data: {} }, { @@ -77,16 +81,23 @@ export class LyAutocompleteTrigger { left: 0, pointerEvents: null }, - fnDestroy: this.detach.bind(this), - hasBackdrop: false + fnDestroy: this.destroy.bind(this), + hasBackdrop: false, }); - } else { + } + } + /** @docs-private */ + destroy() { + if (this._overlayRef) { + this._overlayRef.detach(); + this._overlayRef.remove(); + this._overlayRef = null; } } _handleFocus() { - + this.openPanel(); } _handleInput(_event: KeyboardEvent) { diff --git a/src/lib/autocomplete/autocomplete.ts b/src/lib/autocomplete/autocomplete.ts index a5f9b68d5..33b67dafd 100644 --- a/src/lib/autocomplete/autocomplete.ts +++ b/src/lib/autocomplete/autocomplete.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, TemplateRef, ViewChild } from '@angular/core'; +import { ChangeDetectionStrategy, Component, EventEmitter, Output, TemplateRef, ViewChild } from '@angular/core'; import { StyleRenderer } from '@alyle/ui'; import { STYLES as AUTOCOMPLETE_STYLES } from './autocomplete-styles'; @@ -17,6 +17,12 @@ export class LyAutocomplete { /** @docs-private */ @ViewChild(TemplateRef, { static: true }) readonly template: TemplateRef; + /** Event that is emitted when the autocomplete panel is opened. */ + @Output() readonly opened = new EventEmitter(); + + /** Event that is emitted when the autocomplete panel is closed. */ + @Output() readonly closed = new EventEmitter(); + constructor( readonly sRenderer: StyleRenderer ) { }