From 8edf4b6eb3885089ce950e3a2d19dbe7b0ef78d5 Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Mon, 17 Aug 2020 15:03:26 -0500 Subject: [PATCH 01/10] Support for Angular 9 From 002fdd76c1d32b213506b689f044d57cba514f30 Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Sun, 30 Aug 2020 14:49:47 -0500 Subject: [PATCH 02/10] =?UTF-8?q?=C2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 4a68dd94fe23bc947d6ee5698ad368f671055480 Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Sun, 30 Aug 2020 16:09:24 -0500 Subject: [PATCH 03/10] =?UTF-8?q?=C2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + src/api/docs/components/field.html | 8 + src/api/docs/components/tabs.html | 4 +- src/api/docs/customization/color.html | 18 +- src/api/docs/customization/theming.html | 16 +- .../demos/basic-field.component.html.html | 2 +- .../docs/demos/basic-tabs.component.html.html | 6 +- .../docs/demos/basic-tabs.component.ts.html | 14 +- .../demos/complex-checkbox.component.ts.html | 2 +- .../demos/dialog-responsive.component.ts.html | 6 +- .../demos/dialog-with-select-dialog.html.html | 2 +- .../demos/dialog-with-select-dialog.ts.html | 2 +- ...ield-with-display-with.component.html.html | 9 + .../field-with-display-with.component.ts.html | 12 + .../field-with-display-with.module.ts.html | 19 + ...with-prefix-and-suffix.component.html.html | 40 ++ ...d-with-prefix-and-suffix.component.ts.html | 9 + ...ield-with-prefix-and-suffix.module.ts.html | 25 ++ src/api/docs/demos/field.lazy.module.ts.html | 12 +- .../demos/simple-form.component.html.html | 20 +- .../demos/tabs-placement.component.html.html | 6 +- .../demos/tabs-placement.component.ts.html | 15 +- ...h-asynchronously-loading.component.ts.html | 2 +- ...tabs-with-lazy-loading.component.html.html | 6 +- .../tabs-with-lazy-loading.component.ts.html | 12 +- .../docs/getting-started/installation.html | 5 +- src/app/app.module.ts | 14 +- src/app/demo-view/view/view.component.html | 1 + src/app/demo-view/view/view.component.ts | 6 +- .../complex-checkbox.component.ts | 2 +- .../dialog-with-select-dialog.html | 2 +- .../dialog-with-select-dialog.ts | 2 +- .../basic-field/basic-field.component.html | 2 +- .../field-with-display-with.component.html | 9 + .../field-with-display-with.component.spec.ts | 25 ++ .../field-with-display-with.component.ts | 11 + .../field-with-display-with.module.ts | 18 + ...ield-with-prefix-and-suffix.component.html | 40 ++ ...d-with-prefix-and-suffix.component.spec.ts | 25 ++ .../field-with-prefix-and-suffix.component.ts | 8 + .../field-with-prefix-and-suffix.module.ts | 24 ++ .../field-demo/field.lazy.module.ts | 12 +- src/app/docs/components/field-demo/field.md | 13 + .../simple-form/simple-form.component.html | 20 +- src/app/docs/getting-started/installation.md | 5 +- .../basic-tabs/basic-tabs.component.html | 6 +- .../basic-tabs/basic-tabs.component.ts | 14 +- .../tabs-placement.component.html | 6 +- .../tabs-placement.component.ts | 15 +- ...s-with-asynchronously-loading.component.ts | 2 +- .../tabs-with-lazy-loading.component.html | 6 +- .../tabs-with-lazy-loading.component.ts | 12 +- src/app/docs/layout/tabs-demo/tabs.md | 4 +- src/browserslist | 9 - src/index.html | 6 +- src/lib/card/card.directive.ts | 26 +- src/lib/checkbox/checkbox.ts | 4 +- src/lib/expansion/accordion.ts | 2 +- src/lib/field/display-with.ts | 22 ++ src/lib/field/field-control-base.ts | 2 + src/lib/field/field.html | 28 +- src/lib/field/field.module.ts | 18 +- src/lib/field/field.ts | 182 +++++---- src/lib/menu/menu.ts | 70 ++-- src/lib/select/select.ts | 8 +- src/lib/slider/slider.ts | 152 ++++---- src/lib/src/focus-state/focus-state.ts | 2 +- src/lib/src/minimal/component-destroyed.ts | 2 +- src/lib/src/minimal/renderer-style.ts | 10 +- src/lib/src/position/position.ts | 4 +- src/lib/src/style-utils.ts | 4 +- src/lib/src/theme/common.module.ts | 6 +- src/lib/src/theme/style.directive.ts | 106 +----- src/lib/src/theme/theme2.service.ts | 20 +- src/lib/tabs/tabs.html | 21 +- src/lib/tabs/tabs.module.ts | 9 +- src/lib/tabs/tabs.ts | 353 +++++++++++------- src/lib/themes/minima/base.ts | 108 +++--- src/lib/tooltip/tooltip.ts | 10 +- src/lib/typography/typography.directive.ts | 10 +- 80 files changed, 1044 insertions(+), 727 deletions(-) create mode 100644 src/api/docs/demos/field-with-display-with.component.html.html create mode 100644 src/api/docs/demos/field-with-display-with.component.ts.html create mode 100644 src/api/docs/demos/field-with-display-with.module.ts.html create mode 100644 src/api/docs/demos/field-with-prefix-and-suffix.component.html.html create mode 100644 src/api/docs/demos/field-with-prefix-and-suffix.component.ts.html create mode 100644 src/api/docs/demos/field-with-prefix-and-suffix.module.ts.html create mode 100644 src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.html create mode 100644 src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.spec.ts create mode 100644 src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.ts create mode 100644 src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.module.ts create mode 100644 src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.html create mode 100644 src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.spec.ts create mode 100644 src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.ts create mode 100644 src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.module.ts delete mode 100644 src/browserslist create mode 100644 src/lib/field/display-with.ts diff --git a/.gitignore b/.gitignore index ea6081020..3450d388a 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ firebase-debug.log #others publish.sh /others +sync-config.json \ No newline at end of file diff --git a/src/api/docs/components/field.html b/src/api/docs/components/field.html index fc00b4ac6..67c12eb97 100644 --- a/src/api/docs/components/field.html +++ b/src/api/docs/components/field.html @@ -13,6 +13,14 @@

Automatically resizing a +

Format values on blur

+ + + +

Field with prefix & suffix

+ + +

Field Playground

diff --git a/src/api/docs/components/tabs.html b/src/api/docs/components/tabs.html index adcfc0cf4..91768c3f5 100644 --- a/src/api/docs/components/tabs.html +++ b/src/api/docs/components/tabs.html @@ -32,6 +32,6 @@

Placement

Limitations

    -
  • When using keepContent attribute with headerPlacement="before" or headerPlacement="after" you must explicitly set a height to ly-tabs for it to work properly.

  • -
  • headerPlacement="before" or headerPlacement="after" does not work with dynamicHeight.

  • +
  • When using keepContent attribute with headerPlacement="before" or headerPlacement="after" you must explicitly set a height to ly-tabs for it to work properly.

  • +
  • headerPlacement="before" or headerPlacement="after" does not work with dynamicHeight.

\ No newline at end of file diff --git a/src/api/docs/customization/color.html b/src/api/docs/customization/color.html index b7e8c9ef1..7680ac843 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 cbe722cd7..065512269 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/basic-field.component.html.html b/src/api/docs/demos/basic-field.component.html.html index 253be6702..0edd4e3e7 100644 --- a/src/api/docs/demos/basic-field.component.html.html +++ b/src/api/docs/demos/basic-field.component.html.html @@ -1,6 +1,6 @@
<ly-field>
+  <ly-label>Label</ly-label>
   <input lyNativeControl
-    placeholder="Label"
     value="Hi!"
   >
 </ly-field>
diff --git a/src/api/docs/demos/basic-tabs.component.html.html b/src/api/docs/demos/basic-tabs.component.html.html
index 70357fffa..2af511be7 100644
--- a/src/api/docs/demos/basic-tabs.component.html.html
+++ b/src/api/docs/demos/basic-tabs.component.html.html
@@ -2,17 +2,17 @@
   <ly-tabs [selectedIndex]="1">
     <ly-tab>
       <button ly-tab-label>Item One</button>
-      <div [withClass]="classes.content" lyTyp="body1">Item One</div>
+      <div [lyP]="4" lyTyp="body1">Item One</div>
     </ly-tab>
     <ly-tab>
       <button ly-tab-label>Item Two</button>
-      <div [withClass]="classes.content" lyTyp="body1">
+      <div [lyP]="4" lyTyp="body1">
         Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati unde dignissimos quia fuga? Saepe laudantium cupiditate iusto, delectus voluptatum omnis, exercitationem necessitatibus fuga deleniti incidunt beatae magni eos natus architecto!
       </div>
     </ly-tab>
     <ly-tab>
       <button ly-tab-label>Item Three</button>
-      <div [withClass]="classes.content" lyTyp="body1">Item Three</div>
+      <div [lyP]="4" lyTyp="body1">Item Three</div>
     </ly-tab>
   </ly-tabs>
 </div>
diff --git a/src/api/docs/demos/basic-tabs.component.ts.html b/src/api/docs/demos/basic-tabs.component.ts.html
index 027262624..27f00eaa3 100644
--- a/src/api/docs/demos/basic-tabs.component.ts.html
+++ b/src/api/docs/demos/basic-tabs.component.ts.html
@@ -1,21 +1,9 @@
 
import { Component, ChangeDetectionStrategy } from '@angular/core';
-import { LyTheme2 } from '@alyle/ui';
-
-const styles = ({
-  content: {
-    padding: '2em'
-  }
-});
 
 @Component({
   selector: 'aui-basic-tabs',
   templateUrl: './basic-tabs.component.html',
   changeDetection: ChangeDetectionStrategy.OnPush
 })
-export class BasicTabsComponent {
-  classes = this.theme.addStyleSheet(styles);
-  constructor(
-    private theme: LyTheme2
-  ) { }
-}
+export class BasicTabsComponent { }
 
\ No newline at end of file diff --git a/src/api/docs/demos/complex-checkbox.component.ts.html b/src/api/docs/demos/complex-checkbox.component.ts.html index 79f20d791..3586a7908 100644 --- a/src/api/docs/demos/complex-checkbox.component.ts.html +++ b/src/api/docs/demos/complex-checkbox.component.ts.html @@ -40,7 +40,7 @@ })) ) }); - fruitsAbstractControlArray: AbstractControl[] = (<FormArray>this.form.get('fruits')).controls; + fruitsAbstractControlArray: AbstractControl[] = (this.form.get('fruits') as FormArray).controls; get selectedFruits() { const fruits = this.fruits.filter(_ => !_.disabled); diff --git a/src/api/docs/demos/dialog-responsive.component.ts.html b/src/api/docs/demos/dialog-responsive.component.ts.html index 91f79923c..5591451c2 100644 --- a/src/api/docs/demos/dialog-responsive.component.ts.html +++ b/src/api/docs/demos/dialog-responsive.component.ts.html @@ -5,8 +5,10 @@ const STYLES = (theme: ThemeVariables) => { return { dialog: lyl `{ - @media ${theme.breakpoints['Small']}, - ${theme.breakpoints['XSmall']} { + @media ${[ + theme.breakpoints['Small'], + theme.breakpoints['XSmall'] + ].join()} { border-radius: 0 } }` diff --git a/src/api/docs/demos/dialog-with-select-dialog.html.html b/src/api/docs/demos/dialog-with-select-dialog.html.html index 147be4572..cfcdb871c 100644 --- a/src/api/docs/demos/dialog-with-select-dialog.html.html +++ b/src/api/docs/demos/dialog-with-select-dialog.html.html @@ -11,7 +11,7 @@ > <ly-hint>Hint</ly-hint> <ly-error *ngIf="username.hasError('minlength')">Min 5 characters</ly-error> - <ly-error *ngIf="username.hasError('maxlength')">Max 16 characters</ly-error> + <ly-error *ngIf="username.hasError('maxlength')">Max 32 characters</ly-error> <ly-error *ngIf="username.hasError('required')">Required</ly-error> <ly-hint [align]="'after'">{{ username.value?.length || 0 }}/32</ly-hint> </ly-field> diff --git a/src/api/docs/demos/dialog-with-select-dialog.ts.html b/src/api/docs/demos/dialog-with-select-dialog.ts.html index cecc5bf1d..cec2592a6 100644 --- a/src/api/docs/demos/dialog-with-select-dialog.ts.html +++ b/src/api/docs/demos/dialog-with-select-dialog.ts.html @@ -12,7 +12,7 @@ username: new FormControl('', [ Validators.required, Validators.minLength(5), - Validators.maxLength(16) + Validators.maxLength(32) ]), option: new FormControl('', Validators.required) }); diff --git a/src/api/docs/demos/field-with-display-with.component.html.html b/src/api/docs/demos/field-with-display-with.component.html.html new file mode 100644 index 000000000..7522360c5 --- /dev/null +++ b/src/api/docs/demos/field-with-display-with.component.html.html @@ -0,0 +1,9 @@ +
<ly-field appearance="filled">
+  <input lyNativeControl
+    type="number"
+    [formControl]="price"
+  >
+  <ly-label>Price</ly-label>
+  <ly-display-with>{{ price.value | currency }}</ly-display-with>
+  <ly-hint>Hint</ly-hint>
+</ly-field>
\ No newline at end of file diff --git a/src/api/docs/demos/field-with-display-with.component.ts.html b/src/api/docs/demos/field-with-display-with.component.ts.html new file mode 100644 index 000000000..64db8fb37 --- /dev/null +++ b/src/api/docs/demos/field-with-display-with.component.ts.html @@ -0,0 +1,12 @@ +
import { Component, ChangeDetectionStrategy } from '@angular/core';
+import { FormControl } from '@angular/forms';
+
+@Component({
+  selector: 'aui-field-with-display-with',
+  templateUrl: './field-with-display-with.component.html',
+  changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class FieldWithDisplayWithComponent {
+  readonly price = new FormControl(14000);
+}
+
\ No newline at end of file diff --git a/src/api/docs/demos/field-with-display-with.module.ts.html b/src/api/docs/demos/field-with-display-with.module.ts.html new file mode 100644 index 000000000..6dbb0162e --- /dev/null +++ b/src/api/docs/demos/field-with-display-with.module.ts.html @@ -0,0 +1,19 @@ +
import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { ReactiveFormsModule } from '@angular/forms';
+import { LyFieldModule } from '@alyle/ui/field';
+
+import { FieldWithDisplayWithComponent } from './field-with-display-with.component';
+
+
+
+@NgModule({
+  declarations: [FieldWithDisplayWithComponent],
+  imports: [
+    CommonModule,
+    ReactiveFormsModule,
+    LyFieldModule,
+  ]
+})
+export class FieldWithDisplayWithModule { }
+
\ No newline at end of file diff --git a/src/api/docs/demos/field-with-prefix-and-suffix.component.html.html b/src/api/docs/demos/field-with-prefix-and-suffix.component.html.html new file mode 100644 index 000000000..ba7dc81fd --- /dev/null +++ b/src/api/docs/demos/field-with-prefix-and-suffix.component.html.html @@ -0,0 +1,40 @@ +
<ly-grid container [spacing]="16">
+  <ly-grid item col="4 6@XSmall@Small">
+    <ly-field appearance="outlined" [lyWidth]="1">
+      <span lySuffix>Kg</span>
+      <input lyNativeControl
+        type="number"
+        value="10"
+      >
+      <ly-label>Weight</ly-label>
+      <ly-hint>Hint</ly-hint>
+    </ly-field>
+  </ly-grid>
+  <ly-grid item col="4 6@XSmall@Small">
+    <ly-field appearance="outlined" [lyWidth]="1">
+      <input lyNativeControl
+        type="string"
+        value="example"
+      >
+      <span lySuffix>@gmail.com</span>
+      <ly-label>Email</ly-label>
+      <ly-hint>Hint</ly-hint>
+    </ly-field>
+  </ly-grid>
+  <ly-grid item col="4 6@XSmall@Small">
+    <ly-field appearance="outlined" [lyWidth]="1">
+      <input lyNativeControl
+        type="string"
+        value="example"
+      >
+      <button ly-button appearance="icon" lyPrefix [lyMf]="'0.25em'">
+        <ly-icon>add_circle</ly-icon>
+      </button>
+      <button ly-button appearance="icon" lySuffix>
+        <ly-icon>mic</ly-icon>
+      </button>
+      <ly-label>Label</ly-label>
+      <ly-hint>Hint</ly-hint>
+    </ly-field>
+  </ly-grid>
+</ly-grid>
\ No newline at end of file diff --git a/src/api/docs/demos/field-with-prefix-and-suffix.component.ts.html b/src/api/docs/demos/field-with-prefix-and-suffix.component.ts.html new file mode 100644 index 000000000..ecee04ac9 --- /dev/null +++ b/src/api/docs/demos/field-with-prefix-and-suffix.component.ts.html @@ -0,0 +1,9 @@ +
import { Component, ChangeDetectionStrategy } from '@angular/core';
+
+@Component({
+  selector: 'aui-field-with-prefix-and-suffix',
+  templateUrl: './field-with-prefix-and-suffix.component.html',
+  changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class FieldWithPrefixAndSuffixComponent { }
+
\ No newline at end of file diff --git a/src/api/docs/demos/field-with-prefix-and-suffix.module.ts.html b/src/api/docs/demos/field-with-prefix-and-suffix.module.ts.html new file mode 100644 index 000000000..e76ab3580 --- /dev/null +++ b/src/api/docs/demos/field-with-prefix-and-suffix.module.ts.html @@ -0,0 +1,25 @@ +
import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { ReactiveFormsModule } from '@angular/forms';
+import { LyFieldModule } from '@alyle/ui/field';
+import { LyGridModule } from '@alyle/ui/grid';
+import { LyButtonModule } from '@alyle/ui/button';
+import { LyIconModule } from '@alyle/ui/icon';
+
+import { FieldWithPrefixAndSuffixComponent } from './field-with-prefix-and-suffix.component';
+
+
+
+@NgModule({
+  declarations: [FieldWithPrefixAndSuffixComponent],
+  imports: [
+    CommonModule,
+    ReactiveFormsModule,
+    LyFieldModule,
+    LyGridModule,
+    LyButtonModule,
+    LyIconModule
+  ]
+})
+export class FieldWithPrefixAndSuffixModule { }
+
\ No newline at end of file diff --git a/src/api/docs/demos/field.lazy.module.ts.html b/src/api/docs/demos/field.lazy.module.ts.html index 499830ca4..f036c3296 100644 --- a/src/api/docs/demos/field.lazy.module.ts.html +++ b/src/api/docs/demos/field.lazy.module.ts.html @@ -8,12 +8,18 @@ import { SimpleFormModule } from './simple-form/simple-form.module'; import { FieldWithCdkAutosizeModule } from './field-with-cdk-autosize/field-with-cdk-autosize.module'; import { FieldWithCdkAutosizeComponent } from './field-with-cdk-autosize/field-with-cdk-autosize.component'; +import { FieldWithPrefixAndSuffixComponent } from './field-with-prefix-and-suffix/field-with-prefix-and-suffix.component'; +import { FieldWithPrefixAndSuffixModule } from './field-with-prefix-and-suffix/field-with-prefix-and-suffix.module'; +import { FieldWithDisplayWithModule } from './field-with-display-with/field-with-display-with.module'; +import { FieldWithDisplayWithComponent } from './field-with-display-with/field-with-display-with.component'; const elements = [ BasicFieldComponent, FieldPlaygroundComponent, SimpleFormComponent, - FieldWithCdkAutosizeComponent + FieldWithCdkAutosizeComponent, + FieldWithPrefixAndSuffixComponent, + FieldWithDisplayWithComponent ]; @NgModule({ @@ -21,7 +27,9 @@ BasicFieldModule, FieldPlaygroundModule, SimpleFormModule, - FieldWithCdkAutosizeModule + FieldWithCdkAutosizeModule, + FieldWithPrefixAndSuffixModule, + FieldWithDisplayWithModule ], entryComponents: elements }) diff --git a/src/api/docs/demos/simple-form.component.html.html b/src/api/docs/demos/simple-form.component.html.html index ad76e8829..3ec64d509 100644 --- a/src/api/docs/demos/simple-form.component.html.html +++ b/src/api/docs/demos/simple-form.component.html.html @@ -2,20 +2,19 @@ (ngSubmit)="onSubmit()" [className]="classes.container" > - <ly-field appearance="filled" fullWidth> + <ly-field appearance="filled" [lyWidth]="1" [persistentHint]="true"> <input lyNativeControl type="text" - placeholder="Username" formControlName="username" > - <ly-hint>Hint</ly-hint> + <ly-label>Username</ly-label> <ly-error *ngIf="username.hasError('minlength')">Min 5 characters</ly-error> <ly-error *ngIf="username.hasError('maxlength')">Max 16 characters</ly-error> <ly-error *ngIf="username.hasError('required')">Required</ly-error> <ly-hint [align]="'after'">{{ username.value?.length || 0 }}/16</ly-hint> </ly-field> - <ly-field appearance="filled" fullWidth> + <ly-field appearance="filled" [lyWidth]="1"> <textarea lyNativeControl formControlName="bio"></textarea> <ly-label>Bio <ly-icon>favorite</ly-icon></ly-label> <ly-hint>Hint</ly-hint> @@ -24,28 +23,29 @@ <ly-error *ngIf="bio.hasError('maxlength')">Max 256 characters</ly-error> </ly-field> - <ly-field appearance="filled" fullWidth> + <ly-field appearance="filled" [lyWidth]="1"> + <ly-label>Phone number</ly-label> <input lyNativeControl type="number" - placeholder="Phone number" formControlName="phone" > <ly-hint>Hint</ly-hint> <ly-error>Required</ly-error> </ly-field> - <ly-field appearance="filled" fullWidth> + <ly-field appearance="filled" [lyWidth]="1"> + <ly-label>Email address</ly-label> <input lyNativeControl type="text" - placeholder="Email address" formControlName="email" > <ly-hint>Hint</ly-hint> <ly-error>Required</ly-error> </ly-field> - <ly-field appearance="filled" fullWidth> - <ly-select placeholder="Select something" + <ly-field appearance="filled" [lyWidth]="1"> + <ly-label>Select something</ly-label> + <ly-select formControlName="option" > <ly-option value="opt-1">Item 1</ly-option> diff --git a/src/api/docs/demos/tabs-placement.component.html.html b/src/api/docs/demos/tabs-placement.component.html.html index 0ca8a08ee..5a95397fd 100644 --- a/src/api/docs/demos/tabs-placement.component.html.html +++ b/src/api/docs/demos/tabs-placement.component.html.html @@ -8,16 +8,16 @@ </p> <ly-paper> - <ly-tabs [headerPlacement]="_placement.value" [alignTabs]="'center'"> + <ly-tabs [headerPlacement]="_placement.value"> <ly-tab> <button ly-tab-label>Item One</button> - <div [className]="classes.content" lyTyp="body1"> + <div [lyP]="4" lyTyp="body1"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Ullam dolorem saepe iusto, voluptates labore praesentium, earum voluptatibus, eaque atque itaque aut magnam quo voluptatem nobis voluptate incidunt. Porro, consequatur minus! </div> </ly-tab> <ly-tab> <button ly-tab-label>Item Two</button> - <div [className]="classes.content" lyTyp="body1">Item Two</div> + <div [lyP]="4" lyTyp="body1">Item Two</div> </ly-tab> </ly-tabs> </ly-paper>
\ No newline at end of file diff --git a/src/api/docs/demos/tabs-placement.component.ts.html b/src/api/docs/demos/tabs-placement.component.ts.html index 4578c1702..e4f5e7f82 100644 --- a/src/api/docs/demos/tabs-placement.component.ts.html +++ b/src/api/docs/demos/tabs-placement.component.ts.html @@ -1,21 +1,8 @@
import { Component } from '@angular/core';
-import { LyTheme2 } from '@alyle/ui';
-
-const styles = ({
-  content: {
-    padding: '2em'
-  }
-});
 
 @Component({
   selector: 'aui-tabs-placement',
   templateUrl: './tabs-placement.component.html'
 })
-export class TabsPlacementComponent {
-  readonly classes = this.theme.addStyleSheet(styles);
-  constructor(
-    private theme: LyTheme2
-  ) { }
-
-}
+export class TabsPlacementComponent { }
 
\ No newline at end of file diff --git a/src/api/docs/demos/tabs-with-asynchronously-loading.component.ts.html b/src/api/docs/demos/tabs-with-asynchronously-loading.component.ts.html index 457620a88..fae18fc3d 100644 --- a/src/api/docs/demos/tabs-with-asynchronously-loading.component.ts.html +++ b/src/api/docs/demos/tabs-with-asynchronously-loading.component.ts.html @@ -18,7 +18,7 @@ constructor( platform: Platform ) { - this.asyncTabs = Observable.create((observer: Observer<ExampleTab[]>) => { + this.asyncTabs = new Observable((observer: Observer<ExampleTab[]>) => { if (platform.isBrowser) { setTimeout(() => { observer.next([ diff --git a/src/api/docs/demos/tabs-with-lazy-loading.component.html.html b/src/api/docs/demos/tabs-with-lazy-loading.component.html.html index 7d4521c29..dc5d851e0 100644 --- a/src/api/docs/demos/tabs-with-lazy-loading.component.html.html +++ b/src/api/docs/demos/tabs-with-lazy-loading.component.html.html @@ -3,7 +3,7 @@ <ly-tab> <button ly-tab-label>Home</button> <ng-template ly-tab-content> - <p lyTyp="body1" [withClass]="classes.content"> + <p lyTyp="body1" [lyP]="4"> Home content - loaded: {{ getTime(1) | date:'EEEE, h:mm:ss a' }} </p> </ng-template> @@ -11,7 +11,7 @@ <ly-tab> <button ly-tab-label>Pages</button> <ng-template ly-tab-content> - <p lyTyp="body1" [withClass]="classes.content"> + <p lyTyp="body1" [lyP]="4"> Pages content - loaded: {{ getTime(2) | date:'EEEE, h:mm:ss a' }} </p> </ng-template> @@ -19,7 +19,7 @@ <ly-tab> <button ly-tab-label>Post</button> <ng-template ly-tab-content> - <p lyTyp="body1" [withClass]="classes.content"> + <p lyTyp="body1" [lyP]="4"> Post content - loaded: {{ getTime(3) | date:'EEEE, h:mm:ss a' }} </p> </ng-template> diff --git a/src/api/docs/demos/tabs-with-lazy-loading.component.ts.html b/src/api/docs/demos/tabs-with-lazy-loading.component.ts.html index 1c4ca0767..97a6e40b9 100644 --- a/src/api/docs/demos/tabs-with-lazy-loading.component.ts.html +++ b/src/api/docs/demos/tabs-with-lazy-loading.component.ts.html @@ -1,11 +1,4 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
-import { LyTheme2 } from '@alyle/ui';
-
-const styles = ({
-  content: {
-    padding: '2em'
-  }
-});
 
 @Component({
   selector: 'aui-tabs-with-lazy-loading',
@@ -13,12 +6,9 @@
   changeDetection: ChangeDetectionStrategy.OnPush
 })
 export class TabsWithLazyLoadingComponent {
-  readonly classes = this.theme.addStyleSheet(styles);
   tabLoadTimes: Date[] = [];
 
-  constructor(
-    private theme: LyTheme2
-  ) { }
+  constructor() { }
 
   getTime(index: number) {
     if (!this.tabLoadTimes[index]) {
diff --git a/src/api/docs/getting-started/installation.html b/src/api/docs/getting-started/installation.html
index 5e516b8fe..4298c639a 100644
--- a/src/api/docs/getting-started/installation.html
+++ b/src/api/docs/getting-started/installation.html
@@ -7,7 +7,7 @@ 

Installation

href="https://cli.angular.io/">Angular CLI and for an existing one follow the next steps.

-

Currently the latest version of Alyle UI supports Angular 9, if your project uses Angular 8, you can use version @alyle/ui@8.0.1.

+

Currently the latest version of Alyle UI supports Angular 10, if your project uses Angular 9, you can use Alyle UI 9.

Angular CLI

Using with the Angular CLI command will update your Angular project so that it is ready to be used.

@@ -58,7 +58,8 @@

Step 2: Import Alyle UI in AppModul // Add components LyButtonModule, LyToolbarModule, - LyImageCropperModule + LyImageCropperModule, + // ... // Gestures HammerModule ], diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 2dfb6e1e7..b3a2e1727 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -9,8 +9,17 @@ import { ServiceWorkerModule } from '@angular/service-worker'; import { LyDrawerModule } from '@alyle/ui/drawer'; import { LyToolbarModule } from '@alyle/ui/toolbar'; import { LyMenuModule } from '@alyle/ui/menu'; -import { LyCommonModule, LY_THEME, LY_THEME_GLOBAL_VARIABLES, RecursivePartial, LY_THEME_NAME, LyTheme2, lyl, StyleRenderer, LyHammerGestureConfig } from '@alyle/ui'; -import { ResponsiveModule } from '@alyle/ui/responsive'; +import { + LyCommonModule, + LY_THEME, + LY_THEME_GLOBAL_VARIABLES, + RecursivePartial, + LY_THEME_NAME, + LyTheme2, + lyl, + StyleRenderer, + LyHammerGestureConfig +} from '@alyle/ui'; import { LyButtonModule } from '@alyle/ui/button'; import { AppComponent } from './app.component'; @@ -143,7 +152,6 @@ export function themeNameProviderFactory() { BrowserAnimationsModule, RouterModule, // LyThemeModule.setTheme('minima-light'), - ResponsiveModule, LyCommonModule, LyButtonModule, LyDrawerModule, diff --git a/src/app/demo-view/view/view.component.html b/src/app/demo-view/view/view.component.html index 0264018fb..869b90835 100644 --- a/src/app/demo-view/view/view.component.html +++ b/src/app/demo-view/view/view.component.html @@ -31,6 +31,7 @@ [elevation]="8" [shadowColor]="'demoBg'" scrollable + [animationDuration]="0" > diff --git a/src/app/demo-view/view/view.component.ts b/src/app/demo-view/view/view.component.ts index 1f431ae84..d71ad3c57 100644 --- a/src/app/demo-view/view/view.component.ts +++ b/src/app/demo-view/view/view.component.ts @@ -303,9 +303,9 @@ export class GlobalVariables { '@angular/platform-browser-dynamic': VERSION.full, 'core-js': '^2.6.1', 'zone.js': '^0.9.1', - 'rxjs': '^6.4.0', - 'hammerjs': '2.0.8', - 'tslib': '^1.10.0', + rxjs: '^6.4.0', + hammerjs: '2.0.8', + tslib: '^1.10.0', 'web-animations-js': 'latest' }, settings: { diff --git a/src/app/docs/components/checkbox-demo/complex-checkbox/complex-checkbox.component.ts b/src/app/docs/components/checkbox-demo/complex-checkbox/complex-checkbox.component.ts index 901a6e383..db6f5a6e1 100644 --- a/src/app/docs/components/checkbox-demo/complex-checkbox/complex-checkbox.component.ts +++ b/src/app/docs/components/checkbox-demo/complex-checkbox/complex-checkbox.component.ts @@ -40,7 +40,7 @@ export class ComplexCheckboxComponent { })) ) }); - fruitsAbstractControlArray: AbstractControl[] = (this.form.get('fruits')).controls; + fruitsAbstractControlArray: AbstractControl[] = (this.form.get('fruits') as FormArray).controls; get selectedFruits() { const fruits = this.fruits.filter(_ => !_.disabled); diff --git a/src/app/docs/components/dialog-demo/dialog-with-select/dialog-with-select-dialog.html b/src/app/docs/components/dialog-demo/dialog-with-select/dialog-with-select-dialog.html index f73552745..4d7851b4e 100644 --- a/src/app/docs/components/dialog-demo/dialog-with-select/dialog-with-select-dialog.html +++ b/src/app/docs/components/dialog-demo/dialog-with-select/dialog-with-select-dialog.html @@ -11,7 +11,7 @@

Hi!

> Hint Min 5 characters - Max 16 characters + Max 32 characters Required {{ username.value?.length || 0 }}/32 diff --git a/src/app/docs/components/dialog-demo/dialog-with-select/dialog-with-select-dialog.ts b/src/app/docs/components/dialog-demo/dialog-with-select/dialog-with-select-dialog.ts index f79a64c57..74e11eb44 100644 --- a/src/app/docs/components/dialog-demo/dialog-with-select/dialog-with-select-dialog.ts +++ b/src/app/docs/components/dialog-demo/dialog-with-select/dialog-with-select-dialog.ts @@ -12,7 +12,7 @@ export class DialogWithSelectDialog { username: new FormControl('', [ Validators.required, Validators.minLength(5), - Validators.maxLength(16) + Validators.maxLength(32) ]), option: new FormControl('', Validators.required) }); diff --git a/src/app/docs/components/field-demo/basic-field/basic-field.component.html b/src/app/docs/components/field-demo/basic-field/basic-field.component.html index 3aee05dab..c92ef9e62 100644 --- a/src/app/docs/components/field-demo/basic-field/basic-field.component.html +++ b/src/app/docs/components/field-demo/basic-field/basic-field.component.html @@ -1,6 +1,6 @@ + Label diff --git a/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.html b/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.html new file mode 100644 index 000000000..3c7029e28 --- /dev/null +++ b/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.html @@ -0,0 +1,9 @@ + + + Price + {{ price.value | currency }} + Hint + \ No newline at end of file diff --git a/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.spec.ts b/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.spec.ts new file mode 100644 index 000000000..096533aff --- /dev/null +++ b/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FieldWithDisplayWithComponent } from './field-with-display-with.component'; + +describe('FieldWithDisplayWithComponent', () => { + let component: FieldWithDisplayWithComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FieldWithDisplayWithComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FieldWithDisplayWithComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.ts b/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.ts new file mode 100644 index 000000000..0a6548974 --- /dev/null +++ b/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.component.ts @@ -0,0 +1,11 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { FormControl } from '@angular/forms'; + +@Component({ + selector: 'aui-field-with-display-with', + templateUrl: './field-with-display-with.component.html', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class FieldWithDisplayWithComponent { + readonly price = new FormControl(14000); +} diff --git a/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.module.ts b/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.module.ts new file mode 100644 index 000000000..b835f45c2 --- /dev/null +++ b/src/app/docs/components/field-demo/field-with-display-with/field-with-display-with.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { LyFieldModule } from '@alyle/ui/field'; + +import { FieldWithDisplayWithComponent } from './field-with-display-with.component'; + + + +@NgModule({ + declarations: [FieldWithDisplayWithComponent], + imports: [ + CommonModule, + ReactiveFormsModule, + LyFieldModule, + ] +}) +export class FieldWithDisplayWithModule { } diff --git a/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.html b/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.html new file mode 100644 index 000000000..f2f62da8a --- /dev/null +++ b/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.html @@ -0,0 +1,40 @@ + + + + Kg + + Weight + Hint + + + + + + @gmail.com + Email + Hint + + + + + + + + Label + Hint + + + \ No newline at end of file diff --git a/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.spec.ts b/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.spec.ts new file mode 100644 index 000000000..79196de86 --- /dev/null +++ b/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FieldWithPrefixAndSuffixComponent } from './field-with-prefix-and-suffix.component'; + +describe('FieldWithPrefixAndSuffixComponent', () => { + let component: FieldWithPrefixAndSuffixComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FieldWithPrefixAndSuffixComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FieldWithPrefixAndSuffixComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.ts b/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.ts new file mode 100644 index 000000000..d20bb593d --- /dev/null +++ b/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.component.ts @@ -0,0 +1,8 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; + +@Component({ + selector: 'aui-field-with-prefix-and-suffix', + templateUrl: './field-with-prefix-and-suffix.component.html', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class FieldWithPrefixAndSuffixComponent { } diff --git a/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.module.ts b/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.module.ts new file mode 100644 index 000000000..5004d9440 --- /dev/null +++ b/src/app/docs/components/field-demo/field-with-prefix-and-suffix/field-with-prefix-and-suffix.module.ts @@ -0,0 +1,24 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { LyFieldModule } from '@alyle/ui/field'; +import { LyGridModule } from '@alyle/ui/grid'; +import { LyButtonModule } from '@alyle/ui/button'; +import { LyIconModule } from '@alyle/ui/icon'; + +import { FieldWithPrefixAndSuffixComponent } from './field-with-prefix-and-suffix.component'; + + + +@NgModule({ + declarations: [FieldWithPrefixAndSuffixComponent], + imports: [ + CommonModule, + ReactiveFormsModule, + LyFieldModule, + LyGridModule, + LyButtonModule, + LyIconModule + ] +}) +export class FieldWithPrefixAndSuffixModule { } diff --git a/src/app/docs/components/field-demo/field.lazy.module.ts b/src/app/docs/components/field-demo/field.lazy.module.ts index 8730b3b5f..754ee23c3 100644 --- a/src/app/docs/components/field-demo/field.lazy.module.ts +++ b/src/app/docs/components/field-demo/field.lazy.module.ts @@ -8,12 +8,18 @@ import { FieldPlaygroundModule } from './field-playground/field-playground.modul import { SimpleFormModule } from './simple-form/simple-form.module'; import { FieldWithCdkAutosizeModule } from './field-with-cdk-autosize/field-with-cdk-autosize.module'; import { FieldWithCdkAutosizeComponent } from './field-with-cdk-autosize/field-with-cdk-autosize.component'; +import { FieldWithPrefixAndSuffixComponent } from './field-with-prefix-and-suffix/field-with-prefix-and-suffix.component'; +import { FieldWithPrefixAndSuffixModule } from './field-with-prefix-and-suffix/field-with-prefix-and-suffix.module'; +import { FieldWithDisplayWithModule } from './field-with-display-with/field-with-display-with.module'; +import { FieldWithDisplayWithComponent } from './field-with-display-with/field-with-display-with.component'; const elements = [ BasicFieldComponent, FieldPlaygroundComponent, SimpleFormComponent, - FieldWithCdkAutosizeComponent + FieldWithCdkAutosizeComponent, + FieldWithPrefixAndSuffixComponent, + FieldWithDisplayWithComponent ]; @NgModule({ @@ -21,7 +27,9 @@ const elements = [ BasicFieldModule, FieldPlaygroundModule, SimpleFormModule, - FieldWithCdkAutosizeModule + FieldWithCdkAutosizeModule, + FieldWithPrefixAndSuffixModule, + FieldWithDisplayWithModule ], entryComponents: elements }) diff --git a/src/app/docs/components/field-demo/field.md b/src/app/docs/components/field-demo/field.md index 71c63a41d..280793d18 100644 --- a/src/app/docs/components/field-demo/field.md +++ b/src/app/docs/components/field-demo/field.md @@ -18,7 +18,20 @@ Text fields let users enter and edit text. +## Format values on blur + + + + + +## Field with prefix & suffix + + + + + ## Field Playground + diff --git a/src/app/docs/components/field-demo/simple-form/simple-form.component.html b/src/app/docs/components/field-demo/simple-form/simple-form.component.html index fc5dc8a65..9ba1365e4 100644 --- a/src/app/docs/components/field-demo/simple-form/simple-form.component.html +++ b/src/app/docs/components/field-demo/simple-form/simple-form.component.html @@ -2,20 +2,19 @@ (ngSubmit)="onSubmit()" [className]="classes.container" > - + - Hint + Username Min 5 characters Max 16 characters Required {{ username.value?.length || 0 }}/16 - + Bio favorite Hint @@ -24,28 +23,29 @@ Max 256 characters - + + Phone number Hint Required - + + Email address Hint Required - - + Select something + Item 1 diff --git a/src/app/docs/getting-started/installation.md b/src/app/docs/getting-started/installation.md index e4904fd5d..ad7f4d784 100644 --- a/src/app/docs/getting-started/installation.md +++ b/src/app/docs/getting-started/installation.md @@ -7,7 +7,7 @@ href="https://cli.angular.io/">Angular CLI and for an existing one follow the next steps.

-> Currently the latest version of Alyle UI supports Angular 9, if your project uses Angular 8, you can use version `@alyle/ui@8.0.1`. +> Currently the latest version of Alyle UI supports Angular 10, if your project uses Angular 9, you can use Alyle UI 9. ## Angular CLI @@ -71,7 +71,8 @@ import { MinimaLight, MinimaDark } from '@alyle/ui/themes/minima'; // Add components LyButtonModule, LyToolbarModule, - LyImageCropperModule + LyImageCropperModule, + // ... // Gestures HammerModule ], diff --git a/src/app/docs/layout/tabs-demo/basic-tabs/basic-tabs.component.html b/src/app/docs/layout/tabs-demo/basic-tabs/basic-tabs.component.html index b8ce08724..baf497e46 100644 --- a/src/app/docs/layout/tabs-demo/basic-tabs/basic-tabs.component.html +++ b/src/app/docs/layout/tabs-demo/basic-tabs/basic-tabs.component.html @@ -2,17 +2,17 @@ -
Item One
+
Item One
-
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati unde dignissimos quia fuga? Saepe laudantium cupiditate iusto, delectus voluptatum omnis, exercitationem necessitatibus fuga deleniti incidunt beatae magni eos natus architecto!
-
Item Three
+
Item Three
diff --git a/src/app/docs/layout/tabs-demo/basic-tabs/basic-tabs.component.ts b/src/app/docs/layout/tabs-demo/basic-tabs/basic-tabs.component.ts index cf341fa28..ec88cb15b 100644 --- a/src/app/docs/layout/tabs-demo/basic-tabs/basic-tabs.component.ts +++ b/src/app/docs/layout/tabs-demo/basic-tabs/basic-tabs.component.ts @@ -1,20 +1,8 @@ import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { LyTheme2 } from '@alyle/ui'; - -const styles = ({ - content: { - padding: '2em' - } -}); @Component({ selector: 'aui-basic-tabs', templateUrl: './basic-tabs.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) -export class BasicTabsComponent { - classes = this.theme.addStyleSheet(styles); - constructor( - private theme: LyTheme2 - ) { } -} +export class BasicTabsComponent { } diff --git a/src/app/docs/layout/tabs-demo/tabs-placement/tabs-placement.component.html b/src/app/docs/layout/tabs-demo/tabs-placement/tabs-placement.component.html index c7b3d1c14..9e5238a3f 100644 --- a/src/app/docs/layout/tabs-demo/tabs-placement/tabs-placement.component.html +++ b/src/app/docs/layout/tabs-demo/tabs-placement/tabs-placement.component.html @@ -8,16 +8,16 @@

- + -
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Ullam dolorem saepe iusto, voluptates labore praesentium, earum voluptatibus, eaque atque itaque aut magnam quo voluptatem nobis voluptate incidunt. Porro, consequatur minus!
-
Item Two
+
Item Two
\ No newline at end of file diff --git a/src/app/docs/layout/tabs-demo/tabs-placement/tabs-placement.component.ts b/src/app/docs/layout/tabs-demo/tabs-placement/tabs-placement.component.ts index 925731e1f..bce9b2ce8 100644 --- a/src/app/docs/layout/tabs-demo/tabs-placement/tabs-placement.component.ts +++ b/src/app/docs/layout/tabs-demo/tabs-placement/tabs-placement.component.ts @@ -1,20 +1,7 @@ import { Component } from '@angular/core'; -import { LyTheme2 } from '@alyle/ui'; - -const styles = ({ - content: { - padding: '2em' - } -}); @Component({ selector: 'aui-tabs-placement', templateUrl: './tabs-placement.component.html' }) -export class TabsPlacementComponent { - readonly classes = this.theme.addStyleSheet(styles); - constructor( - private theme: LyTheme2 - ) { } - -} +export class TabsPlacementComponent { } diff --git a/src/app/docs/layout/tabs-demo/tabs-with-asynchronously-loading/tabs-with-asynchronously-loading.component.ts b/src/app/docs/layout/tabs-demo/tabs-with-asynchronously-loading/tabs-with-asynchronously-loading.component.ts index 9f423a827..59f227284 100644 --- a/src/app/docs/layout/tabs-demo/tabs-with-asynchronously-loading/tabs-with-asynchronously-loading.component.ts +++ b/src/app/docs/layout/tabs-demo/tabs-with-asynchronously-loading/tabs-with-asynchronously-loading.component.ts @@ -18,7 +18,7 @@ export class TabsWithAsynchronouslyLoadingComponent { constructor( platform: Platform ) { - this.asyncTabs = Observable.create((observer: Observer) => { + this.asyncTabs = new Observable((observer: Observer) => { if (platform.isBrowser) { setTimeout(() => { observer.next([ diff --git a/src/app/docs/layout/tabs-demo/tabs-with-lazy-loading/tabs-with-lazy-loading.component.html b/src/app/docs/layout/tabs-demo/tabs-with-lazy-loading/tabs-with-lazy-loading.component.html index 310724526..1933c7413 100644 --- a/src/app/docs/layout/tabs-demo/tabs-with-lazy-loading/tabs-with-lazy-loading.component.html +++ b/src/app/docs/layout/tabs-demo/tabs-with-lazy-loading/tabs-with-lazy-loading.component.html @@ -3,7 +3,7 @@ -

+

Home content - loaded: {{ getTime(1) | date:'EEEE, h:mm:ss a' }}

@@ -11,7 +11,7 @@ -

+

Pages content - loaded: {{ getTime(2) | date:'EEEE, h:mm:ss a' }}

@@ -19,7 +19,7 @@ -

+

Post content - loaded: {{ getTime(3) | date:'EEEE, h:mm:ss a' }}

diff --git a/src/app/docs/layout/tabs-demo/tabs-with-lazy-loading/tabs-with-lazy-loading.component.ts b/src/app/docs/layout/tabs-demo/tabs-with-lazy-loading/tabs-with-lazy-loading.component.ts index b894b6104..4ad514b55 100644 --- a/src/app/docs/layout/tabs-demo/tabs-with-lazy-loading/tabs-with-lazy-loading.component.ts +++ b/src/app/docs/layout/tabs-demo/tabs-with-lazy-loading/tabs-with-lazy-loading.component.ts @@ -1,11 +1,4 @@ import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { LyTheme2 } from '@alyle/ui'; - -const styles = ({ - content: { - padding: '2em' - } -}); @Component({ selector: 'aui-tabs-with-lazy-loading', @@ -13,12 +6,9 @@ const styles = ({ changeDetection: ChangeDetectionStrategy.OnPush }) export class TabsWithLazyLoadingComponent { - readonly classes = this.theme.addStyleSheet(styles); tabLoadTimes: Date[] = []; - constructor( - private theme: LyTheme2 - ) { } + constructor() { } getTime(index: number) { if (!this.tabLoadTimes[index]) { diff --git a/src/app/docs/layout/tabs-demo/tabs.md b/src/app/docs/layout/tabs-demo/tabs.md index abdf49aba..1e88c0c7a 100644 --- a/src/app/docs/layout/tabs-demo/tabs.md +++ b/src/app/docs/layout/tabs-demo/tabs.md @@ -46,8 +46,8 @@ The tab content will animate its height according to the height of the active ta ## Limitations -* When using `keepContent` attribute with `headerPlacement="before"` or `headerPlacement="after"` you must explicitly set a height to `ly-tabs` for it to work properly. +* ~~When using `keepContent` attribute with `headerPlacement="before"` or `headerPlacement="after"` you must explicitly set a height to `ly-tabs` for it to work properly.~~ -* `headerPlacement="before"` or `headerPlacement="after"` does not work with `dynamicHeight`. +* ~~`headerPlacement="before"` or `headerPlacement="after"` does not work with `dynamicHeight`.~~ diff --git a/src/browserslist b/src/browserslist deleted file mode 100644 index 2e82330ff..000000000 --- a/src/browserslist +++ /dev/null @@ -1,9 +0,0 @@ -# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers -# For additional information regarding the format and rule options, please see: -# https://github.com/browserslist/browserslist#queries -# For IE 9-11 support, please uncomment the last line of the file and adjust as needed -> 0.5% -last 4 versions -Firefox ESR -not dead -IE 9-11 \ No newline at end of file diff --git a/src/index.html b/src/index.html index 94aa50025..d67647318 100644 --- a/src/index.html +++ b/src/index.html @@ -9,9 +9,6 @@ - - - + + + diff --git a/src/lib/card/card.directive.ts b/src/lib/card/card.directive.ts index be84ac4ed..f5e42b72f 100644 --- a/src/lib/card/card.directive.ts +++ b/src/lib/card/card.directive.ts @@ -213,16 +213,6 @@ export class LyCardActions implements OnInit { ] }) export class LyCardMedia implements WithStyles, OnInit { - static readonly и = 'LyCardMedia'; - static readonly $priority = STYLE_PRIORITY; - - private _ratio: string; - - @Input() - @Style((val) => () => lyl `{ - background-image: url('${val}') - }`) - bgImg: string; /** * Aspect ratio @@ -254,7 +244,6 @@ export class LyCardMedia implements WithStyles, OnInit { get ratio() { return this._ratio; } - [0x2]: string; constructor( readonly sRenderer: StyleRenderer, @@ -262,12 +251,23 @@ export class LyCardMedia implements WithStyles, OnInit { ) { sRenderer.addClass(card.classes.bgImg); } + static readonly и = 'LyCardMedia'; + static readonly $priority = STYLE_PRIORITY; + + static ngAcceptInputType_bgImg: string; + + private _ratio: string; + + @Input() + @Style((val) => () => lyl `{ + background-image: url('${val}') + }`) + bgImg: string; + [0x2]: string; ngOnInit() { if (!this.ratio) { this.ratio = DEFAULT_ASPECT_RATIO; } } - - static ngAcceptInputType_bgImg: string; } diff --git a/src/lib/checkbox/checkbox.ts b/src/lib/checkbox/checkbox.ts index 991cdf496..fc87258c7 100644 --- a/src/lib/checkbox/checkbox.ts +++ b/src/lib/checkbox/checkbox.ts @@ -254,8 +254,8 @@ export class LyCheckbox extends LyCheckboxMixinBase implements WithStyles, Contr set checked(val: boolean) { const newVal = toBoolean(val); // if (newVal !== this.checked) { - this._checked = newVal; - if (newVal) { + this._checked = newVal; + if (newVal) { this._renderer.addClass(this._el.nativeElement, this.classes.checked); } else { this._renderer.removeClass(this._el.nativeElement, this.classes.checked); diff --git a/src/lib/expansion/accordion.ts b/src/lib/expansion/accordion.ts index 885585b3d..608ca6758 100644 --- a/src/lib/expansion/accordion.ts +++ b/src/lib/expansion/accordion.ts @@ -177,7 +177,7 @@ export class LyAccordion implements OnInit { private _el: ElementRef) { } ngOnInit() { - const { expansion } = this._theme.variables; + const { expansion } = this._theme.variables as ExpansionVariables; if (expansion) { this._renderer.addClass(this._el.nativeElement, this.classes.root); diff --git a/src/lib/field/display-with.ts b/src/lib/field/display-with.ts new file mode 100644 index 000000000..1276b6dc1 --- /dev/null +++ b/src/lib/field/display-with.ts @@ -0,0 +1,22 @@ +import { Directive, Inject } from '@angular/core'; +import { StyleRenderer, WithStyles } from '@alyle/ui'; +import { LY_FIELD_STYLES_TOKEN } from './field-styles-token'; + +/** + * Only show when input is not focused, and hides input`. + * You can use it to display formatted values. + */ +@Directive({ + selector: 'ly-display-with', + providers: [ + StyleRenderer + ] +}) +export class LyDisplayWith implements WithStyles { + constructor( + readonly sRenderer: StyleRenderer, + @Inject(LY_FIELD_STYLES_TOKEN) styles: any + ) { + sRenderer.renderSheet(styles, 'displayWith'); + } +} diff --git a/src/lib/field/field-control-base.ts b/src/lib/field/field-control-base.ts index d0841cf61..02d3d1194 100644 --- a/src/lib/field/field-control-base.ts +++ b/src/lib/field/field-control-base.ts @@ -1,5 +1,6 @@ import { NgControl } from '@angular/forms'; import { Subject } from 'rxjs'; +import { StyleRenderer } from '@alyle/ui'; /** An interface which allows a control to work inside of a `LyField`. */ export abstract class LyFieldControlBase { @@ -14,6 +15,7 @@ export abstract class LyFieldControlBase { readonly disabled: boolean; readonly required: boolean; readonly floatingLabel: boolean; + readonly sRenderer: StyleRenderer; /** Handles a click on the control's container. */ abstract onContainerClick?(event: MouseEvent): void; } diff --git a/src/lib/field/field.html b/src/lib/field/field.html index c442f1558..83db5ef58 100644 --- a/src/lib/field/field.html +++ b/src/lib/field/field.html @@ -1,16 +1,30 @@ -
-
+
+
+ + + -
- + + -
-
+ +
@@ -37,5 +51,5 @@ - {{ _control?.placeholder }} + {{ _control?.placeholder }} diff --git a/src/lib/field/field.module.ts b/src/lib/field/field.module.ts index ba584e7d1..a4514743d 100644 --- a/src/lib/field/field.module.ts +++ b/src/lib/field/field.module.ts @@ -1,6 +1,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { LyCommonModule } from '@alyle/ui'; +import { ObserversModule } from '@angular/cdk/observers'; import { LyField, LyNativeControl, STYLES } from './field'; import { LyPlaceholder } from './placeholder'; import { LyLabel } from './label'; @@ -9,11 +10,13 @@ import { LySuffix } from './suffix'; import { LyHint } from './hint'; import { LyError } from './error'; import { LY_FIELD_STYLES_TOKEN } from './field-styles-token'; +import { LyDisplayWith } from './display-with'; @NgModule({ imports: [ CommonModule, - LyCommonModule + LyCommonModule, + ObserversModule ], exports: [ LyField, @@ -24,6 +27,7 @@ import { LY_FIELD_STYLES_TOKEN } from './field-styles-token'; LySuffix, LyHint, LyError, + LyDisplayWith, LyCommonModule ], providers: [ @@ -32,6 +36,16 @@ import { LY_FIELD_STYLES_TOKEN } from './field-styles-token'; useValue: STYLES } ], - declarations: [ LyField, LyPlaceholder, LyLabel, LyNativeControl, LyPrefix, LySuffix, LyHint, LyError ] + declarations: [ + LyField, + LyPlaceholder, + LyLabel, + LyNativeControl, + LyPrefix, + LySuffix, + LyHint, + LyError, + LyDisplayWith + ] }) export class LyFieldModule { } diff --git a/src/lib/field/field.ts b/src/lib/field/field.ts index 4f237894d..2b6652443 100644 --- a/src/lib/field/field.ts +++ b/src/lib/field/field.ts @@ -26,9 +26,7 @@ import { import { LyTheme2, ThemeVariables, - ElementObserver, toBoolean, - DirAlias, StyleCollection, LyClasses, StyleTemplate, @@ -50,6 +48,8 @@ import { NgControl, NgForm, FormGroupDirective } from '@angular/forms'; import { LyError } from './error'; import { LyFieldControlBase } from './field-control-base'; import { Platform } from '@angular/cdk/platform'; +import { LyDisplayWith } from './display-with'; +import { takeUntil } from 'rxjs/operators'; export interface LyFieldTheme { /** Styles for Field Component */ @@ -151,8 +151,7 @@ export const STYLES = (theme: ThemeVariables & LyFieldVariables, ref: ThemeRef) root: ( ) => lyl `{ display: inline-block position: relative - margin-top: 1em - line-height: 1.5 + line-height: 1.125 & ${classes.hint}, & ${classes.error} { display: block font-size: .75em @@ -163,6 +162,11 @@ export const STYLES = (theme: ThemeVariables & LyFieldVariables, ref: ThemeRef) font-size: inherit } } + ${classes.prefix}, ${classes.suffix} { + position: relative + white-space: nowrap + flex: none + } { ...${ (theme.field @@ -176,7 +180,7 @@ export const STYLES = (theme: ThemeVariables & LyFieldVariables, ref: ThemeRef) }`, animations: ( ) => lyl `{ & ${classes.labelSpan} { - transition: font-size ${theme.animations.curves.deceleration} .${theme.animations.durations.complex}s + transition: transform ${theme.animations.curves.deceleration} .${theme.animations.durations.complex}s } & ${classes.label} { transition: ${theme.animations.curves.deceleration} .${theme.animations.durations.complex}s @@ -185,9 +189,10 @@ export const STYLES = (theme: ThemeVariables & LyFieldVariables, ref: ThemeRef) container: lyl `{ height: 100% display: flex - align-items: center + align-items: baseline position: relative -webkit-tap-highlight-color: transparent + box-sizing: border-box &:after { ...${LY_COMMON_STYLES.fill} content: '' @@ -204,27 +209,18 @@ export const STYLES = (theme: ThemeVariables & LyFieldVariables, ref: ThemeRef) padding: 0 height: 2px }`, - labelSpan: lyl `{ - max-width: 100% - display: inline-block - }`, prefix: lyl `{ max-height: 2em - display: flex - align-items: center }`, infix: lyl `{ display: inline-flex position: relative - align-items: baseline min-width: 0 width: 180px - flex: 1 0 + flex: auto }`, suffix: lyl `{ max-height: 2em - display: flex - align-items: center }`, labelContainer: lyl `{ ...${LY_COMMON_STYLES.fill} @@ -245,24 +241,35 @@ export const STYLES = (theme: ThemeVariables & LyFieldVariables, ref: ThemeRef) margin: 0 border: none pointer-events: none + overflow: hidden + width: 100% + height: 100% + }`, + labelSpan: lyl `{ white-space: nowrap text-overflow: ellipsis overflow: hidden + display: block width: 100% + height: 100% + transform-origin: ${before} 0 }`, isFloatingLabel: null, floatingLabel: ( ) => lyl `{ ${classes.labelSpan} { - font-size: 75% + transform: scale(.75) + width: 133% } }`, placeholder: lyl `{ ...${LY_COMMON_STYLES.fill} pointer-events: none + white-space: nowrap + text-overflow: ellipsis + overflow: hidden }`, focused: null, inputNative: lyl `{ - resize: vertical padding: 0 outline: none border: none @@ -270,6 +277,12 @@ export const STYLES = (theme: ThemeVariables & LyFieldVariables, ref: ThemeRef) color: inherit font: inherit width: 100% + textarea& { + padding: 2px 0 + margin: -2px 0 + resize: vertical + overflow: auto + } select& { -moz-appearance: none -webkit-appearance: none @@ -299,6 +312,18 @@ export const STYLES = (theme: ThemeVariables & LyFieldVariables, ref: ThemeRef) background: 0 0 } }`, + /** Is used to hide the input when `displayWith` is shown */ + _hiddenInput: lyl `{ + color: transparent + }`, + displayWith: lyl `{ + ...${LY_COMMON_STYLES.fill} + white-space: nowrap + text-overflow: ellipsis + overflow: hidden + width: 100% + pointer-events: none + }`, hintContainer: lyl `{ min-height: 1.25em line-height: 1.25 @@ -312,7 +337,7 @@ export const STYLES = (theme: ThemeVariables & LyFieldVariables, ref: ThemeRef) }`, disabled: ( ) => lyl `{ &, & ${classes.label}, & ${classes.container}:after { - color: ${theme.disabled.default} + color: ${theme.disabled.contrast} cursor: default } }`, @@ -355,9 +380,8 @@ export const STYLES = (theme: ThemeVariables & LyFieldVariables, ref: ThemeRef) border-left: 0.3125em solid transparent border-right: 0.3125em solid transparent border-top: 0.3125em solid - top: 50% + top: 0 ${after}: 0 - margin-top: -0.15625em pointer-events: none } } @@ -390,20 +414,21 @@ export class LyField implements WithStyles, OnInit, AfterContentInit, AfterViewI protected _colorClass: string; protected _isFloating: boolean; protected _floatingLabel: boolean; + private _destroyed = new Subject(); private _fielsetSpanClass: string; - private _marginStartClass: string; - private _marginEndClass: string; private _fullWidth: boolean; private _fullWidthClass?: string; + private _updateFielsetSpanOnStable: boolean; + @ViewChild('_container', { static: true }) _container: ElementRef; @ViewChild('_labelContainer') _labelContainer: ElementRef; @ViewChild('_labelContainer2') _labelContainer2: ElementRef; @ViewChild('_labelSpan') _labelSpan: ElementRef; @ViewChild('_prefixContainer') _prefixContainer: ElementRef; @ViewChild('_suffixContainer') _suffixContainer: ElementRef; - @ViewChild('_fieldsetLegend') _fieldsetLegend: ElementRef; @ContentChild(forwardRef(() => LyFieldControlBase)) _control?: LyFieldControlBase; @ContentChild(LyPlaceholder) _placeholderChild: LyPlaceholder; @ContentChild(LyLabel) _labelChild: LyLabel; + @ContentChild(LyDisplayWith) readonly _displayWithChild: QueryList; @ContentChildren(LyHint) _hintChildren: QueryList; @ContentChildren(LyPrefix) _prefixChildren: QueryList; @ContentChildren(LySuffix) _suffixChildren: QueryList; @@ -413,6 +438,14 @@ export class LyField implements WithStyles, OnInit, AfterContentInit, AfterViewI return this._control ? this._control.errorState : false; } + get displayWithStatus() { + return !!(this._displayWithChild + && this._control + && !this._control.empty + && !this._control.focused + && !this._control.errorState); + } + @Input() persistentHint: boolean; @Input() @@ -503,7 +536,9 @@ export class LyField implements WithStyles, OnInit, AfterContentInit, AfterViewI }, STYLE_PRIORITY ) - appearance: string | null; + set appearance(_val: string | null) { + this._updateFielsetSpan(); + } @HostListener('focus') onFocus() { this._el.nativeElement.focus(); @@ -512,7 +547,6 @@ export class LyField implements WithStyles, OnInit, AfterContentInit, AfterViewI constructor( private _renderer: Renderer2, private _el: ElementRef, - private _elementObserver: ElementObserver, private _theme: LyTheme2, private _cd: ChangeDetectorRef, private _ngZone: NgZone, @@ -534,6 +568,7 @@ export class LyField implements WithStyles, OnInit, AfterContentInit, AfterViewI ngAfterContentInit() { this._control!.stateChanges.subscribe(() => { this._updateFloatingLabel(); + this._updateDisplayWith(); this._markForCheck(); }); @@ -541,83 +576,66 @@ export class LyField implements WithStyles, OnInit, AfterContentInit, AfterViewI // Run change detection if the value changes. if (ngControl && ngControl.valueChanges) { - ngControl.valueChanges.subscribe(() => { + ngControl.valueChanges.pipe(takeUntil(this._destroyed)).subscribe(() => { this._updateFloatingLabel(); this._markForCheck(); }); } - } - ngAfterViewInit() { - this._updateFloatingLabel(); - if (this._platform.isBrowser) { - this._ngZone.runOutsideAngular(() => { - if (this._prefixContainer) { - const el = this._prefixContainer.nativeElement; - this._updateFielset(el, DirAlias.before); - this._elementObserver.observe(el, () => { - this._updateFielset(el, DirAlias.before); - }); - } - if (this._suffixContainer) { - const el = this._suffixContainer.nativeElement; - this._updateFielset(el, DirAlias.after); - this._elementObserver.observe(el, () => { - this._updateFielset(el, DirAlias.after); - }); - } - if (this._labelSpan) { - const el = this._labelSpan.nativeElement; + this._ngZone.runOutsideAngular(() => { + this._ngZone.onStable.pipe(takeUntil(this._destroyed)).subscribe(() => { + if (this._updateFielsetSpanOnStable) { this._updateFielsetSpan(); - this._elementObserver.observe(el, () => { - this._updateFielsetSpan(); - }); } }); - } - // this fix with of label + }); + } + + ngAfterViewInit() { + this._updateFloatingLabel(); + this._updateDisplayWith(); this._renderer.addClass(this._el.nativeElement, this.classes.animations); } ngOnDestroy() { - if (this._prefixContainer) { - const el = this._prefixContainer; - this._elementObserver.destroy(el); - } - if (this._suffixContainer) { - const el = this._suffixContainer; - this._elementObserver.destroy(el); - } - if (this._labelSpan) { - const el = this._labelSpan; - this._elementObserver.destroy(el); - } + this._destroyed.next(); + this._destroyed.complete(); } - private _updateFielset(el: Element, dir: DirAlias) { - const { width } = el.getBoundingClientRect(); - const newClass = this._theme.addStyle(`fieldLegendstyle.margin${dir}:${width}`, () => ({ - [`& .${this.classes.fieldsetSpan}`]: { - [`margin-${dir}`]: `${width}px` - } - }), undefined, undefined, STYLE_PRIORITY); - if (dir === DirAlias.before) { - this._marginStartClass = this._theme.updateClass(this._el.nativeElement, this._renderer, newClass, this._marginStartClass); - } else { - this._marginEndClass = this._theme.updateClass(this._el.nativeElement, this._renderer, newClass, this._marginEndClass); + _updateFielsetSpan() { + if (!this._platform.isBrowser) { + return; } - } - private _updateFielsetSpan() { - let { width } = this._labelSpan.nativeElement.getBoundingClientRect(); + const label = this._isLabel() ? this._labelSpan.nativeElement : null; + const labelFirstChild = this._isLabel() ? this._labelSpan.nativeElement.firstElementChild! : null; + if (this.appearance !== 'outlined' || !label) { + return; + } + const before = this._theme.variables.before; + const fieldsetLegend = this._getHostElement().querySelector('legend'); + if (!fieldsetLegend) { + this._updateFielsetSpanOnStable = true; + return; + } + const labelRect = label.getBoundingClientRect(); + const containerRect = this._container.nativeElement.getBoundingClientRect(); + const beforeMargin = Math.abs(containerRect[before] - labelRect[before]); + let { width } = labelFirstChild!.getBoundingClientRect(); if (!this._isFloating) { width -= width / 100 * 25; } /** Add 6px of spacing */ width += 6; + width = width > labelRect.width + ? labelRect.width + : width; + width = Math.round(width); + fieldsetLegend.style[`margin-${before}`] = `${beforeMargin - 12}px`; this._fielsetSpanClass = this._theme.addStyle(`style.fieldsetSpanFocused:${width}`, { [`&.${this.classes.isFloatingLabel} .${this.classes.fieldsetSpan}`]: {width: `${width}px`} }, this._el.nativeElement, this._fielsetSpanClass, STYLE_PRIORITY); + this._updateFielsetSpanOnStable = false; } /** @ignore */ _isLabel() { @@ -666,6 +684,10 @@ export class LyField implements WithStyles, OnInit, AfterContentInit, AfterViewI } } + private _updateDisplayWith() { + this._control!.sRenderer.toggleClass(this.classes._hiddenInput, this.displayWithStatus); + } + private _markForCheck() { this._cd.markForCheck(); } @@ -681,6 +703,7 @@ export class LyField implements WithStyles, OnInit, AfterContentInit, AfterViewI 'input[lyInput], textarea[lyInput], input[lyNativeControl], textarea[lyNativeControl], select[lyNativeControl]', exportAs: 'LyNativeControl', providers: [ + StyleRenderer, { provide: LyFieldControlBase, useExisting: LyNativeControl } ] }) @@ -784,6 +807,7 @@ export class LyNativeControl implements LyFieldControlBase, OnInit, DoCheck, OnD constructor( private _theme: LyTheme2, + readonly sRenderer: StyleRenderer, private _el: ElementRef, private _renderer: Renderer2, @Optional() private _field: LyField, diff --git a/src/lib/menu/menu.ts b/src/lib/menu/menu.ts index 020ce7f24..b30a67d8c 100644 --- a/src/lib/menu/menu.ts +++ b/src/lib/menu/menu.ts @@ -148,9 +148,39 @@ const ANIMATIONS = [ }) export class LyMenu implements OnChanges, OnInit, AfterViewInit, OnDestroy { + /** Menu Trigger */ + @Input() + set ref(value: LyMenuTriggerFor) { + this._ref = value; + this._menuRef = value._menuRef!; + } + get ref() { + return this._ref; + } + + /** Whether the menu has a backdrop. */ + @Input() + get hasBackdrop(): boolean { + return this._hasBackdrop; + } + set hasBackdrop(value: boolean) { + this._hasBackdrop = coerceBooleanProperty(value); + } + + constructor( + private _theme: LyTheme2, + private _el: ElementRef, + private _renderer: Renderer2, + private _viewportRuler: ViewportRuler, + readonly sRenderer: StyleRenderer + ) { } + /** @docs-private */ static readonly и = 'LyMenu'; + + static ngAcceptInputType_hasBackdrop: BooleanInput; + /** * styles * @docs-private @@ -174,16 +204,6 @@ export class LyMenu implements OnChanges, OnInit, AfterViewInit, OnDestroy { destroy: () => void; @ViewChild('container') _container?: ElementRef; @ContentChildren(forwardRef(() => LyMenuItem)) readonly menuItems?: QueryList; - - /** Menu Trigger */ - @Input() - set ref(value: LyMenuTriggerFor) { - this._ref = value; - this._menuRef = value._menuRef!; - } - get ref() { - return this._ref; - } private _ref: LyMenuTriggerFor; /** The point in the anchor where the menu `xAxis` will be attached. */ @@ -216,24 +236,11 @@ export class LyMenu implements OnChanges, OnInit, AfterViewInit, OnDestroy { * @deprecated Use `yAxis` instead. */ @Input() yPosition: YPosition; - - /** Whether the menu has a backdrop. */ - @Input() - get hasBackdrop(): boolean { - return this._hasBackdrop; - } - set hasBackdrop(value: boolean) { - this._hasBackdrop = coerceBooleanProperty(value); - } private _hasBackdrop: boolean = true; + private _mouseenterListen?: () => void; + private _mouseleaveListen?: () => void; - constructor( - private _theme: LyTheme2, - private _el: ElementRef, - private _renderer: Renderer2, - private _viewportRuler: ViewportRuler, - readonly sRenderer: StyleRenderer - ) { } + @HostBinding('@transformMenuLeave') transformMenuLeave: unknown; ngOnChanges() { if (this.ref?._menuRef && this._container) { @@ -308,8 +315,6 @@ export class LyMenu implements OnChanges, OnInit, AfterViewInit, OnDestroy { ); } } - private _mouseenterListen?: () => void; - private _mouseleaveListen?: () => void; /** Remove listeners */ private _removeOpenOnHoverListeners() { @@ -322,7 +327,7 @@ export class LyMenu implements OnChanges, OnInit, AfterViewInit, OnDestroy { } /** Update Menu Position */ - private _updatePlacement () { + private _updatePlacement() { const el = this.ref._menuRef?.containerElement; const container = this._container?.nativeElement; @@ -369,8 +374,6 @@ export class LyMenu implements OnChanges, OnInit, AfterViewInit, OnDestroy { } } - - @HostBinding('@transformMenuLeave') transformMenuLeave: unknown; @HostListener('@transformMenuLeave.start', ['$event']) _onAnimationStart(event: AnimationEvent) { this._isAnimating = true; if (event.triggerName === 'transformMenuLeave' && event.toState === 'void') { @@ -384,9 +387,6 @@ export class LyMenu implements OnChanges, OnInit, AfterViewInit, OnDestroy { this.ref.destroy(this._menuRef); } } - - - static ngAcceptInputType_hasBackdrop: BooleanInput; } @Directive({ @@ -405,6 +405,7 @@ export class LyMenuItem { ) { renderer.addClass(el.nativeElement, _menu.classes.item); } + private _itemSubMenuTrigger?: LyMenuTriggerFor; _handleClick() { if (this._menu.ref && this._menu.ref._menuRef) { @@ -452,7 +453,6 @@ export class LyMenuItem { _getItemSubMenuTrigger() { return this._itemSubMenuTrigger; } - private _itemSubMenuTrigger?: LyMenuTriggerFor; } diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index 6423c1e07..3058429b6 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -67,7 +67,8 @@ import { StyleCollection, LyClasses, StyleTemplate, - ThemeRef + ThemeRef, + StyleRenderer } from '@alyle/ui'; import { Subject } from 'rxjs'; import { take, takeUntil, startWith } from 'rxjs/operators'; @@ -93,8 +94,7 @@ export const STYLES = (theme: ThemeVariables & LySelectVariables, ref: ThemeRef) root: () => lyl `{ display: block padding-${after}: 1em - min-width: em - min-height: 1.5em + min-height: 1em -webkit-tap-highlight-color: transparent { ...${ @@ -221,6 +221,7 @@ export class LySelectTrigger { } animations: [...ANIMATIONS], inputs: ['tabIndex'], providers: [ + StyleRenderer, { provide: LyFieldControlBase, useExisting: LySelect } ] }) @@ -448,6 +449,7 @@ export class LySelect } constructor(private _theme: LyTheme2, + readonly sRenderer: StyleRenderer, private _renderer: Renderer2, private _el: ElementRef, private _overlay: LyOverlay, diff --git a/src/lib/slider/slider.ts b/src/lib/slider/slider.ts index 9ea79eb53..aac2222ef 100644 --- a/src/lib/slider/slider.ts +++ b/src/lib/slider/slider.ts @@ -361,73 +361,6 @@ export interface LySliderMark { } }) export class LySlider implements OnChanges, OnInit, OnDestroy, ControlValueAccessor { - static и = 'LySlider'; - readonly classes = this._theme.renderStyleSheet(STYLES); - - private _disabled: boolean; - private _disabledClass: string | null; - private _color: string; - private _colorClass: string; - - private _vertical: boolean; - private _verticalClass?: string | null; - - private _appearance: string; - private _appearanceClass: string; - - private _value: number | (number | null)[] | null = null; - private _thumbsOnSlideStart: Thumb[] | null; - private _valueOnSlideStart: number | (number | null)[] | null; - - private _min: number = 0; - private _max: number = 100; - - private _step: number = 1; - private _stepPrecision?: number | null; - - private _closestIndex: number | null; - private _currentRect: DOMRect | null; - - _changes = new Subject(); - - /** Min percentage, this is for mark. */ - _minPercent: number; - /** Max percentage, this is for mark. */ - _maxPercent: number; - - /** - * Whether or not the thumb is sliding. - */ - _isSliding: boolean; - _slidingThumbValue?: number | null; - - _thumbs: Thumb[] = []; - - _rootClasses = new Set(); - - @ViewChild('bg') _bg?: ElementRef; - @ViewChild('track', { static: true }) _track: ElementRef; - @ViewChild('ticksRef', { static: true }) _ticksRef: ElementRef; - @ViewChildren('thumbsRef') _thumbsRef?: QueryList>; - - @Input() displayWith: (value: number | null) => string | number; - - /** Event emitted when the slider value has changed. */ - @Output() readonly change: EventEmitter = new EventEmitter(); - - /** Event emitted when the slider thumb moves. */ - @Output() readonly input: EventEmitter = new EventEmitter(); - - /** @docs-private */ - @Output() readonly valueChange: EventEmitter = new EventEmitter(); - - /** - * The registered callback function called when a blur event occurs on the input element. - * @docs-private - */ - onTouched = () => {}; - - private _controlValueAccessorChangeFn: (value: any) => void = () => {}; /** Whether or not to show the thumb. */ @Input() @@ -449,8 +382,6 @@ export class LySlider implements OnChanges, OnInit, OnDestroy, ControlValueAcces } } - private _thumbVisible: boolean | null; - /** Whether or not to show the marks, also accepts an array of marks. */ @Input() get marks() { @@ -481,10 +412,6 @@ export class LySlider implements OnChanges, OnInit, OnDestroy, ControlValueAcces } - private _marks: boolean | LySliderMark[]; - private _marksClass: string | null; - _marksList?: LySliderMark[] | null; - /** The maximum value that the slider can have. */ @Input() get max(): number { @@ -704,12 +631,9 @@ export class LySlider implements OnChanges, OnInit, OnDestroy, ControlValueAcces const newValue = toNumber(val, toBoolean(val)); this._ticks = newValue; } - private _ticks: number | boolean; - _tickInterval: number; get _tickList() { return this.__tickList; } - private __tickList: number[]; // private _ngClass: NgClass; constructor( private _theme: LyTheme2, @@ -722,6 +646,82 @@ export class LySlider implements OnChanges, OnInit, OnDestroy, ControlValueAcces ) { _renderer.addClass(_el.nativeElement, this.classes.root); } + static и = 'LySlider'; + readonly classes = this._theme.renderStyleSheet(STYLES); + + private _disabled: boolean; + private _disabledClass: string | null; + private _color: string; + private _colorClass: string; + + private _vertical: boolean; + private _verticalClass?: string | null; + + private _appearance: string; + private _appearanceClass: string; + + private _value: number | (number | null)[] | null = null; + private _thumbsOnSlideStart: Thumb[] | null; + private _valueOnSlideStart: number | (number | null)[] | null; + + private _min: number = 0; + private _max: number = 100; + + private _step: number = 1; + private _stepPrecision?: number | null; + + private _closestIndex: number | null; + private _currentRect: DOMRect | null; + + _changes = new Subject(); + + /** Min percentage, this is for mark. */ + _minPercent: number; + /** Max percentage, this is for mark. */ + _maxPercent: number; + + /** + * Whether or not the thumb is sliding. + */ + _isSliding: boolean; + _slidingThumbValue?: number | null; + + _thumbs: Thumb[] = []; + + _rootClasses = new Set(); + + @ViewChild('bg') _bg?: ElementRef; + @ViewChild('track', { static: true }) _track: ElementRef; + @ViewChild('ticksRef', { static: true }) _ticksRef: ElementRef; + @ViewChildren('thumbsRef') _thumbsRef?: QueryList>; + + @Input() displayWith: (value: number | null) => string | number; + + /** Event emitted when the slider value has changed. */ + @Output() readonly change: EventEmitter = new EventEmitter(); + + /** Event emitted when the slider thumb moves. */ + @Output() readonly input: EventEmitter = new EventEmitter(); + + /** @docs-private */ + @Output() readonly valueChange: EventEmitter = new EventEmitter(); + + private _thumbVisible: boolean | null; + + private _marks: boolean | LySliderMark[]; + private _marksClass: string | null; + _marksList?: LySliderMark[] | null; + private _ticks: number | boolean; + _tickInterval: number; + private __tickList: number[]; + + /** + * The registered callback function called when a blur event occurs on the input element. + * @docs-private + */ + onTouched = () => {}; + + private _controlValueAccessorChangeFn: (value: any) => void = () => {}; ngOnChanges() { this._updateTickValues(); diff --git a/src/lib/src/focus-state/focus-state.ts b/src/lib/src/focus-state/focus-state.ts index 26d139b2f..1a50b352b 100644 --- a/src/lib/src/focus-state/focus-state.ts +++ b/src/lib/src/focus-state/focus-state.ts @@ -103,7 +103,7 @@ export class LyFocusState implements OnDestroy { return; } - const eventListenerOptions = supportsPassiveEventListeners + const eventListenerOptions = supportsPassiveEventListeners() ? { passive: true, capture: true diff --git a/src/lib/src/minimal/component-destroyed.ts b/src/lib/src/minimal/component-destroyed.ts index 7dd750736..7e51c4ada 100644 --- a/src/lib/src/minimal/component-destroyed.ts +++ b/src/lib/src/minimal/component-destroyed.ts @@ -12,7 +12,7 @@ function componentDestroyed(component: OnDestroy): Observable { } const oldNgOnDestroy = component.ngOnDestroy; const stop$ = new ReplaySubject(); - modifiedComponent.ngOnDestroy = function () { + modifiedComponent.ngOnDestroy = function() { if (oldNgOnDestroy) { oldNgOnDestroy.apply(component); } diff --git a/src/lib/src/minimal/renderer-style.ts b/src/lib/src/minimal/renderer-style.ts index abc642936..5c8dda10c 100644 --- a/src/lib/src/minimal/renderer-style.ts +++ b/src/lib/src/minimal/renderer-style.ts @@ -146,7 +146,7 @@ export class StyleRenderer { null, null, TypeStyle.LylStyle); - oldClass = style as string; + oldClass = style as string; } } else if (len === 3) { if (typeof id === 'string') { @@ -307,7 +307,7 @@ export function Style( const _propertyKey = `_${propertyKey}`; if (descriptor) { const set = descriptor.set!; - descriptor.set = function (val: INPUT) { + descriptor.set = function(val: INPUT) { createStyle( this, propertyKey, @@ -318,7 +318,7 @@ export function Style( set.call(this, val); }; if (!descriptor.get) { - descriptor.get = function () { + descriptor.get = function() { return this[_propertyKey]; }; } @@ -344,7 +344,7 @@ export function Style( } /** - * Create a style for component with a key + * Create a responsive style for component with a key * @param c The component * @param propertyKeyConfig Style key * @param value value @@ -394,7 +394,7 @@ export function createStyle( const val = value[index]; if (typeof val === 'number' || val === null || val === undefined) { _renderStyle(c, propertyKeyConfig, val, null, style, priority); - } if (typeof val === 'string') { + } else if (typeof val === 'string') { parseMediaQueryFromString(val).forEach((_) => { _renderStyle(c, propertyKeyConfig, _[0], _[1], style, priority); }); diff --git a/src/lib/src/position/position.ts b/src/lib/src/position/position.ts index 41ec15d00..a4db4e55f 100644 --- a/src/lib/src/position/position.ts +++ b/src/lib/src/position/position.ts @@ -129,7 +129,7 @@ export class Positioning { ox = 'center', oy = 'center'; // if (this.placement) { - if (this.placement === YPosition.above) { + if (this.placement === YPosition.above) { x += (this._originRect.width - this._overlayElementRect.width) / 2; y += -this._overlayElementRect.height; oy = 'bottom'; @@ -162,7 +162,7 @@ export class Positioning { } } - if (this.xPosition) { + if (this.xPosition) { const dir = this._themeVariables.getDirection(this.xPosition as any); if (dir === DirPosition.right) { ox = '0%'; diff --git a/src/lib/src/style-utils.ts b/src/lib/src/style-utils.ts index 21b1005a2..b9dee75b2 100644 --- a/src/lib/src/style-utils.ts +++ b/src/lib/src/style-utils.ts @@ -161,7 +161,7 @@ export function withMediaInline( }); } } else if (typeof str === 'number' || str === null || str === undefined) { - styleCollection.add(transformer(str, null)); + styleCollection.add(transformer(str as any, null)); } else { for (let index = 0; index < str.length; index++) { const val = str[index]; @@ -246,7 +246,7 @@ export function eachMedia( } } } else if (typeof str === 'number' || typeof str === 'string' || str === null || str === undefined) { - resolveMediaEachItemStyle(fn, str, null, 0, styleCollection); + resolveMediaEachItemStyle(fn, str as any, null, 0, styleCollection); } else { // is array for (let index = 0; index < str.length; index++) { diff --git a/src/lib/src/theme/common.module.ts b/src/lib/src/theme/common.module.ts index 839b4603a..54379f373 100644 --- a/src/lib/src/theme/common.module.ts +++ b/src/lib/src/theme/common.module.ts @@ -2,11 +2,11 @@ import { NgModule } from '@angular/core'; import { LyPaper } from './paper'; import { LyWithClass } from './with-class.directive'; -import { LyStyle, LyStyleDeprecated } from './style.directive'; +import { LyStyle } from './style.directive'; @NgModule({ - declarations: [LyStyle, LyWithClass, LyPaper, LyStyleDeprecated], - exports: [LyStyle, LyWithClass, LyPaper, LyStyleDeprecated] + declarations: [LyStyle, LyWithClass, LyPaper], + exports: [LyStyle, LyWithClass, LyPaper] }) export class LyCommonModule { } diff --git a/src/lib/src/theme/style.directive.ts b/src/lib/src/theme/style.directive.ts index b610323cb..6ae0bf318 100644 --- a/src/lib/src/theme/style.directive.ts +++ b/src/lib/src/theme/style.directive.ts @@ -1,4 +1,4 @@ -import { Directive, OnChanges, SimpleChanges, ElementRef } from '@angular/core'; +import { Directive } from '@angular/core'; import { lyl } from '../parse'; import { StyleRenderer, Style, WithStyles, InputStyle } from '../minimal/renderer-style'; import { ThemeVariables } from './theme-config'; @@ -58,10 +58,21 @@ const STYLE_PRIORITY = -0.5; ] }) export class LyStyle implements WithStyles { + + set size(value: string | number | null) { + this.width = value; + this.height = value; + } + + constructor( + readonly sRenderer: StyleRenderer + ) { } /** @docs-private */ static readonly и = 'LyStyle'; static readonly $priority = STYLE_PRIORITY; + static readonly with: InputStyle; + @Style( (value) => (theme: ThemeVariables) => ( lyl `{ @@ -209,8 +220,6 @@ export class LyStyle implements WithStyles { }` ) ) my: string | number | null; - - static readonly with: InputStyle; @Style( (val, media) => ({breakpoints}: ThemeVariables) => ( lyl `{ @@ -271,11 +280,6 @@ export class LyStyle implements WithStyles { ) ) minHeight: string | number | null; - set size(value: string | number | null) { - this.width = value; - this.height = value; - } - @Style( (val, media) => ({breakpoints}: ThemeVariables) => ( lyl `{ @@ -429,92 +433,6 @@ export class LyStyle implements WithStyles { ) ) lyStyle: string | null; - - constructor( - readonly sRenderer: StyleRenderer - ) { } -} - -/** - * @dynamic - * Spacing - * [p], [pf], [pe], [pt], [pb], [px], [py], - * [m], [mf], [me], [mt], [mb], [mx], [my], - * Sizing - * [size], - * [width], [maxWidth], [minWidth], - * [height], [maxHeight], [minHeight], - * Others - * [lyStyle] - */ -@Directive({ - selector: ` - [p], [pf], [pe], [pt], [pb], [px], [py], - [m], [mf], [me], [mt], [mb], [mx], [my], - [size]:not([ly-button]), - [width]:not(svg):not(canvas):not(embed):not(iframe):not(img):not(input):not(object):not(video), - [maxWidth], [minWidth], - [height]:not(svg):not(canvas):not(embed):not(iframe):not(img):not(input):not(object):not(video), - [maxHeight], [minHeight], - [display], - [flex], - [flexBasis], - [flexDirection], - [flexGrow], - [flexSelf], - [flexShrink], - [flexWrap], - [justifyContent], - [justifyItems], - [justifySelf], - [alignContent], - [alignItems], - [order]`, - providers: [ - StyleRenderer - ], - inputs: [ - 'p', 'pf', 'pe', 'pt', 'pb', 'px', 'py', - 'm', 'mf', 'me', 'mt', 'mb', 'mx', 'my', - 'size', - 'width', 'maxWidth', 'minWidth', - 'height', 'maxHeight', 'minHeight', - 'display', - 'flex', - 'flexBasis', - 'flexDirection', - 'flexGrow', - 'flexSelf', - 'flexShrink', - 'flexWrap', - 'justifyContent', - 'justifyItems', - 'justifySelf', - 'alignContent', - 'alignItems', - 'order', - ] -}) -export class LyStyleDeprecated extends LyStyle implements OnChanges { - - constructor( - sRenderer: StyleRenderer, - private _el: ElementRef - ) { - super(sRenderer); - } - ngOnChanges(changes: SimpleChanges) { - for (const key in changes) { - if (changes.hasOwnProperty(key)) { - const message = `[${key}] is deprecated, use [ly${key.charAt(0).toUpperCase() + key.slice(1)}] instead.`; - console.error({ - message, - element: this._el.nativeElement - }); - throw new Error(message); - } - } - } } /** diff --git a/src/lib/src/theme/theme2.service.ts b/src/lib/src/theme/theme2.service.ts index e019f4733..3fc6fe5c7 100644 --- a/src/lib/src/theme/theme2.service.ts +++ b/src/lib/src/theme/theme2.service.ts @@ -151,14 +151,14 @@ export class LyTheme2 { * @param style Styles * @param el Element * @param instance The instance of this, this replaces the existing style with a new one when it changes - * @param parentStyle + * @param parentStyle Parent Style */ addStyle(id: string, - style?: StyleDeclarationsBlock, - el?: any, - instance?: string | null, - priority?: number | null, - parentStyle?: Styles) { + style?: StyleDeclarationsBlock, + el?: any, + instance?: string | null, + priority?: number | null, + parentStyle?: Styles) { const newClass = this._createStyleContent2(style, id, priority, TypeStyle.OnlyOne, false, parentStyle) as string; if (newClass === instance) { return newClass; @@ -284,7 +284,7 @@ export class LyTheme2 { if (!_STYLE_MAP.has(styles)) { _STYLE_MAP.set(styles, { isNewStyle: true, - styles: styles, + styles: styles as unknown as Styles, type: TypeStyle.Multiple, css: {}, id: null @@ -497,7 +497,7 @@ function groupStyleToString( const themeNameForSelectors = getThemeNameForSelectors(themeName); const classesMap = styleMap[themeName] || (styleMap[themeName] = {}); const selectorsMap = styleMap[themeNameForSelectors] || (styleMap[themeNameForSelectors] = {}); - const styleGroup = styles; + const styleGroup = styles as StyleGroup; let content = ''; const name = styleGroup.$name ? `${styleGroup.$name}-` : ''; @@ -532,7 +532,9 @@ function groupStyleToString( } else if (typeof value === 'object' || value === null) { // set new id if not exist if (!(key in classesMap)) { - classesMap[key] = isDevMode() ? toValidClassName(`y-${name}${key}-${createNextClassId(classNamePrefix)}`) : createNextClassId(classNamePrefix); + classesMap[key] = isDevMode() + ? toValidClassName(`y-${name}${key}-${createNextClassId(classNamePrefix)}`) + : createNextClassId(classNamePrefix); } } else { diff --git a/src/lib/tabs/tabs.html b/src/lib/tabs/tabs.html index 2bfea2a97..b28492dd6 100644 --- a/src/lib/tabs/tabs.html +++ b/src/lib/tabs/tabs.html @@ -1,22 +1,17 @@ -
-
+
-
- -
-
- -
+
+
+
+
- +
- \ No newline at end of file diff --git a/src/lib/tabs/tabs.module.ts b/src/lib/tabs/tabs.module.ts index b0d4aea64..7b2f449bf 100644 --- a/src/lib/tabs/tabs.module.ts +++ b/src/lib/tabs/tabs.module.ts @@ -3,9 +3,16 @@ import { CommonModule } from '@angular/common'; import { NgTranscludeModule, LyCommonModule, LyThemeModule } from '@alyle/ui'; import { LyTabs, LyTabLabel, LyTab } from './tabs'; import { LyTabContent } from './tab-content.directive'; +import { PortalModule } from '@angular/cdk/portal'; @NgModule({ - imports: [LyThemeModule, CommonModule, LyCommonModule, NgTranscludeModule], + imports: [ + LyThemeModule, + CommonModule, + LyCommonModule, + NgTranscludeModule, + PortalModule + ], exports: [LyCommonModule, LyTabs, LyTab, LyTabLabel, LyTabContent], declarations: [LyTabs, LyTab, LyTabLabel, LyTabContent] }) diff --git a/src/lib/tabs/tabs.ts b/src/lib/tabs/tabs.ts index 0814bc2ec..53ecb8d5d 100644 --- a/src/lib/tabs/tabs.ts +++ b/src/lib/tabs/tabs.ts @@ -22,7 +22,8 @@ import { ViewChild, ViewEncapsulation, Optional, - ViewChildren + ViewChildren, + ViewContainerRef } from '@angular/core'; import { LyTheme2, @@ -55,10 +56,11 @@ import { } from '@alyle/ui'; import { LyButton } from '@alyle/ui/button'; import { LyTabContent } from './tab-content.directive'; -import { Subscription } from 'rxjs'; +import { Subscription, Subject } from 'rxjs'; import { ViewportRuler } from '@angular/cdk/scrolling'; import { Platform } from '@angular/cdk/platform'; - +import { TemplatePortal } from '@angular/cdk/portal'; +import { takeUntil, take, switchMapTo } from 'rxjs/operators'; export interface LyTabTheme { /** Styles for Tab Component */ root?: StyleCollection<((classes: LyClasses) => StyleTemplate)> @@ -100,15 +102,16 @@ export const STYLES = (theme: ThemeVariables & LyTabVariables, ref: ThemeRef) => position: relative display: inline-flex }`, - /** Tab content */ + /** Tab container */ contentContainer: lyl `{ display: flex overflow: hidden flex-grow: 1 width: 100% + position: relative }`, /** Tab header */ - tabsLabels: lyl `{ + labels: lyl `{ display: flex position: relative height: 100% @@ -149,30 +152,32 @@ export const STYLES = (theme: ThemeVariables & LyTabVariables, ref: ThemeRef) => padding: 0 12px } }`, - tabLabelActive: lyl `{ + labelActive: lyl `{ opacity: 1 }`, - tabContents: lyl `{ + contents: lyl `{ display: flex - transition: 450ms cubic-bezier(.1, 1, 0.5, 1) - will-change: transform width: 100% }`, - tabContent: lyl `{ + content: lyl `{ + ...${LY_COMMON_STYLES.fill} width: 100% height: 100% - flex-shrink: 0 - position: relative + position: absolute overflow: auto }`, - tabContentInner: null, - tabsIndicator: lyl `{ + contentActive: lyl `{ + position: relative + z-index: 1 + }`, + contentInner: null, + indicator: lyl `{ position: absolute height: 2px transition: 450ms cubic-bezier(.1, 1, 0.5, 1) background: currentColor }`, - tabsIndicatorForServer: lyl `{ + indicatorForServer: lyl `{ position: absolute background: currentColor }`, @@ -183,10 +188,6 @@ export const STYLES = (theme: ThemeVariables & LyTabVariables, ref: ThemeRef) => scrollable: null, hiddenContent: () => lyl `{ visibility: hidden - transition: visibility linear 1s - ${__.column} & { - height: 0 - } }`, column: null, row: null @@ -258,13 +259,14 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV private _alignTabsClass: string; private _textColor: string; private _textColorClass: string; - private _selectedIndexClass: string; private _tabResizeSub: Subscription; private _scrollable: boolean; private _timeoutIds: { [index: number]: number } = {}; + /** Emits whenever the component is destroyed. */ + private readonly _destroy = new Subject(); @ViewChild('tabs', { static: true }) tabsRef: ElementRef; - @ViewChild('tabContents', { static: true }) tabContents: ElementRef; + @ViewChild('tabContents', { static: true }) tabContents: ElementRef; @ViewChild('tabsIndicator', { static: true, read: ElementRef }) tabsIndicator?: ElementRef; @Input() selectedIndexOnChange: 'auto' | number = 'auto'; /** @@ -282,6 +284,19 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV } private _keepContent: boolean; + /** Animation duration in milliseconds */ + @Input() + set animationDuration(val: number) { + this._animationDuration = val; + Promise.resolve().then(() => { + this.tabContents.nativeElement.style.transitionDuration = `${val}ms`; + }); + } + get animationDuration() { + return this._animationDuration; + } + private _animationDuration: number; + /** * Whether the tab group should grow to the size of the active tab. */ @@ -314,7 +329,7 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV val => (theme, ref) => { const __ = ref.selectorsOf(STYLES); return lyl `{ - ${__.tabsIndicator} { + ${__.indicator} { color:${theme.colorOf(val)} } }`; @@ -374,23 +389,22 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV [`&`]: { flexDirection: flexDirectionContainer }, - [`& .${this.classes.tabsIndicator},& .${this.classes.tabsIndicatorForServer}`]: { + [`& .${this.classes.indicator},& .${this.classes.indicatorForServer}`]: { [position]: 0, height, width }, - [`.${this.classes.tabsIndicatorForServer}`]: { + [`.${this.classes.indicatorForServer}`]: { width: widthServer, height: heightServer }, - [`& .${this.classes.tabsLabels},& .${this.classes.tabContents}`]: { flexDirection }, - [`.${this.classes.tabContents}`]: { flexDirection } + [`& .${this.classes.labels},& .${this.classes.contents}`]: { flexDirection }, + [`.${this.classes.contents}`]: { flexDirection } }; }, this.el.nativeElement, this._headerPlacementClass, STYLE_PRIORITY); - this._updateStylesOfSelectedTab(); } } get headerPlacement() { @@ -403,12 +417,12 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV this._alignTabsClass = this.theme.addStyle(`lyAlignTabs: ${val}`, ( val === 'stretch' ? { - [`& .${this.classes.tabsLabels} .${this.classes.tab}`]: { + [`& .${this.classes.labels} .${this.classes.tab}`]: { flexBasis: 0, flexGrow: 1 } } : { - [`& .${this.classes.tabsLabels}`]: { + [`& .${this.classes.labels}`]: { justifyContent: val in AlignAlias ? AlignAlias[val] : val } } @@ -426,7 +440,7 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV this._textColor = val; this._textColorClass = this.theme.addStyle(`lyTabs.textColor:${val}`, (theme: ThemeVariables) => ({ - [`& .${this.classes.tabLabelActive}`]: { + [`& .${this.classes.labelActive}`]: { color: theme.colorOf(val) } }), @@ -444,11 +458,13 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV this._selectedBeforeIndex = this._selectedIndex as number; this._selectedIndex = this._findIndex(val, 'auto'); this._selectedBeforeTab = this._selectedTab!; + if (this._isViewInitLoaded) { + this._updateTabs(); + } else { + Promise.resolve(null).then(() => this._updateTabs()); + } this.selectedIndexChange.emit(this._selectedIndex); this._markForCheck(); - Promise.resolve(null).then(() => { - this._updateStylesOfSelectedTab(); - }); } } get selectedIndex() { @@ -466,10 +482,12 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV private cd: ChangeDetectorRef, private _viewportRuler: ViewportRuler, readonly sRenderer: StyleRenderer, - private _platform: Platform + private _platform: Platform, + private _ngZone: NgZone ) { super(theme); this.setAutoContrast(); + this.animationDuration = 500; } ngOnChanges() { @@ -484,7 +502,7 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV } this.renderer.addClass(this.el.nativeElement, this.classes.root); const tabsIndicatorEl = this.tabsIndicator!.nativeElement; - this.renderer.addClass(tabsIndicatorEl, this.classes.tabsIndicator); + this.renderer.addClass(tabsIndicatorEl, this.classes.indicator); /** Set default Color */ if (!this.indicatorColor && !this.bg && !this.textColor && !this.elevation) { this.indicatorColor = DEFAULT_INDICATOR_COLOR; @@ -506,8 +524,18 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV } ngAfterViewInit() { - this.updateStyle(this.tabsRef.nativeElement); this._isViewInitLoaded = true; + this.tabsList.changes + .pipe( + switchMapTo(this._ngZone.onStable.asObservable().pipe(take(1))), + takeUntil(this._destroy) + ) + .subscribe(() => { + this._updateTabs(); + }); + this._updateTabs(); + + this.updateStyle(this.tabsRef.nativeElement); if (this._platform.isBrowser) { this._tabResizeSub = this._viewportRuler.change().subscribe(() => { if (this._selectedTab) { @@ -519,12 +547,13 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV } ngOnDestroy() { + this._destroy.next(); + this._destroy.complete(); this._tabsSubscription.unsubscribe(); if (this._tabResizeSub) { this._tabResizeSub.unsubscribe(); } - Object.keys(this._timeoutIds) - .forEach((key) => clearTimeout(this._timeoutIds[key])); + this._clearTimeouts(); } private _findIndex(selectedIndex: number, index: string | number) { @@ -558,128 +587,68 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV } } - private _updateStylesOfSelectedTab() { - const index = this._selectedIndex; - const placement = this.headerPlacement; - this._selectedIndexClass = this._theme.addStyle(`lyTabs.selectedIndex:${index}+${placement}`, (theme: ThemeVariables) => { - let sign = 1; - const position = this._getFlexDirection(placement) === 'column' ? 'Y' : 'X'; - if (theme.direction === Dir.ltr || position === 'Y') { - sign = -1; - } - return { - transform: `translate${position}(${index * 100 * sign}%)` - }; - }, this.tabContents.nativeElement, this._selectedIndexClass, STYLE_PRIORITY); - this.renderer.addClass(this.tabContents.nativeElement, this._selectedIndexClass); + _markForCheck() { + this.cd.markForCheck(); } - private _updateDynamicHeight(container: HTMLDivElement, tabIndex: number) { - if (this._timeoutIds[tabIndex] != null) { - window.clearTimeout(this._timeoutIds[tabIndex]); + private _updateTabs() { + if (!this._isViewInitLoaded) { + return; } - if (this.selectedIndex === tabIndex) { - const contentInnerHeightBefore = this._platform.isBrowser - ? (this.tabContents.nativeElement as HTMLElement) - .getBoundingClientRect().height - : null; - this.renderer.removeClass(container, this.classes.hiddenContent); - - if (this._platform.isBrowser && this.dynamicHeight) { - if (this._timeoutIds[tabIndex] != null) { - window.clearTimeout(this._timeoutIds[tabIndex]); - } - const { headerPlacement: placement } = this; - const { - height: contentInnerHeight, - } = (container.firstElementChild! as HTMLElement) - .getBoundingClientRect(); - const { curves, durations } = this._theme.variables.animations; - // row - if (placement === 'above' || placement === 'below') { - container.style.height = `${contentInnerHeightBefore}px`; - window.getComputedStyle(container).getPropertyValue('opacity'); - container.style.transition = `height ${curves.standard} ${durations.complex}ms`; - container.style.height = `${contentInnerHeight}px`; - } - this._timeoutIds[`_${tabIndex}`] = setTimeout(() => { - container.style.height = ''; - container.style.transition = ''; - delete this._timeoutIds[`_${tabIndex}`]; - }, 450); - } - - } else { - if (this._platform.isBrowser) { - const indexBefore = this._selectedBeforeIndex; - if (indexBefore === tabIndex) { - if (this.dynamicHeight) { - const { nativeElement: contentAfter } = this.tabContentList - .find((_, index) => index === this._selectedIndex)!; - const { nativeElement: contentBefore } = this.tabContentList - .find((_, index) => index === tabIndex)!; - const { - height: contentInnerHeightBefore, - } = (this.tabContents.nativeElement as HTMLElement) - .getBoundingClientRect(); - const { - height: contentInnerHeightAfter, - } = (contentAfter.firstElementChild! as HTMLElement) - .getBoundingClientRect(); - - const { curves, durations } = this._theme.variables.animations; - contentBefore.style.height = `${contentInnerHeightBefore}px`; - window.getComputedStyle(contentBefore).getPropertyValue('opacity'); - contentBefore.style.transition = `height ${curves.standard} ${durations.complex}ms`; - contentBefore.style.height = `${contentInnerHeightAfter}px`; - this._timeoutIds[`__${tabIndex}`] = window.setTimeout(() => { - contentBefore.style.height = ''; - contentBefore.style.transition = ''; - delete this._timeoutIds[`_${tabIndex}`]; - }, 450); - } - } - this._timeoutIds[tabIndex] = window.setTimeout(() => { - this.renderer.addClass(container, this.classes.hiddenContent); - delete this._timeoutIds[tabIndex]; - }, 450); + const tabsContents = this.tabContentList.toArray(); + const tabsForUpdate: [LyTab, HTMLDivElement, number][] = []; + this.tabsList.forEach((tab, index) => { + const tabContent = tabsContents[index].nativeElement; + if (this.selectedIndex === index || this._selectedBeforeIndex === index) { + tab._activeContent = true; + tabsForUpdate.push([tab, tabContent, index]); } else { - this.renderer.addClass(container, this.classes.hiddenContent); + if (this.keepContent) { + this.renderer.addClass(tabContent, this.classes.hiddenContent); + } } - } + }); + this._ngZone.run(() => { + this._markForCheck(); + }); + this._ngZone.onStable.asObservable() + .pipe( + take(1), + takeUntil(this._destroy) + ) + .subscribe(() => + tabsForUpdate.forEach(parms => + this._updateContentStyle(...parms))); } - _markForCheck() { - this.cd.markForCheck(); - } - loadTemplate(tab: LyTab, index: number, tabContent: HTMLDivElement): TemplateRef | null { + loadTemplate(tab: LyTab, index: number): TemplatePortal | null { tab.index = index; if (this.selectedIndex === tab.index) { // set 0 if is null this._selectedTab = tab; Promise.resolve(null).then(() => { - this._updateDynamicHeight(tabContent, index); + // this._updateDynamicHeight(tabContent, index); if (this._platform.isBrowser) { this._updateIndicator(tab); } else { // for server const selectedBeforeTab = this._selectedBeforeTab; if (selectedBeforeTab) { - this.renderer.removeClass(selectedBeforeTab._tabIndicator.nativeElement, this.classes.tabsIndicatorForServer); + this.renderer.removeClass(selectedBeforeTab._tabIndicator.nativeElement, this.classes.indicatorForServer); } - this.renderer.addClass(this._selectedTab!._tabIndicator.nativeElement, this.classes.tabsIndicatorForServer); + this.renderer.addClass(this._selectedTab!._tabIndicator.nativeElement, this.classes.indicatorForServer); } }); - } else { - Promise.resolve(null).then(() => this._updateDynamicHeight(tabContent, index)); + } else if (this._selectedBeforeIndex === index) { + // Promise.resolve(null).then(() => this._updateDynamicHeight(tabContent, index)); } tab._tabLabel._updateTabState(); if (this.keepContent) { - return tab._templateRefLazy || tab._templateRef; + return tab.content; } - if (this.selectedIndex === tab.index) { - return tab._templateRefLazy || tab._templateRef; + if (tab._activeContent) { + return tab.content; } return null; } @@ -693,6 +662,97 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV } return flexDirection; } + + private _updateContentStyle(tab: LyTab, tabContent: HTMLDivElement, index: number) { + if (this.selectedIndex === index || this._selectedBeforeIndex === index) { + const prevIndex = this._selectedBeforeIndex; + const currentIndex = this.selectedIndex; + const dynamicHeight = this.dynamicHeight && this._platform.isBrowser; + const contentInner = tabContent.firstElementChild as HTMLDivElement; + const contentHeight = dynamicHeight ? contentInner.getBoundingClientRect().height : null; + const contentHeightPrev = dynamicHeight + ? this.tabContentList.toArray()[prevIndex]?.nativeElement.firstElementChild!.getBoundingClientRect().height + : null; + if (currentIndex === index) { + this.renderer.addClass(tabContent, this.classes.contentActive); + if (this.keepContent) { + this.renderer.removeClass(tabContent, this.classes.hiddenContent); + } + } else { + this.renderer.removeClass(tabContent, this.classes.contentActive); + } + + if (prevIndex == null || !this._platform.isBrowser || prevIndex === currentIndex) { + return; + } + + this._clearTimeouts(index); + const { before } = this._theme.variables; + const isDirRow = this.headerPlacement === XPosition.after + || this.headerPlacement === XPosition.before; + const x = before === 'left' + ? 100 + : isDirRow + ? 100 + : -100; + if (currentIndex === index) { + const sign = prevIndex < index ? 1 : -1; + const pos = isDirRow ? `0,${x * sign}%` : `${x * sign}%, 0`; + tabContent.style.overflow = 'hidden'; + if (dynamicHeight) { + tabContent.style.height = `${contentHeightPrev}px`; + } + tabContent.style.transform = `translate3d(${pos}, 0)`; + enforceStyleRecalculation(tabContent); + tabContent.style.transition = `${this.animationDuration}ms cubic-bezier(0.35, 0, 0.25, 1)`; + tabContent.style.transform = `translate3d(0%, 0, 0)`; + if (dynamicHeight) { + tabContent.style.height = `${contentHeight}px`; + } + } else { + const sign = currentIndex < index ? 1 : -1; + const pos = isDirRow ? `0,${x * sign}%` : `${x * sign}%, 0`; + tabContent.style.overflow = 'hidden'; + tabContent.style.transform = `translate3d(0%, 0, 0)`; + enforceStyleRecalculation(tabContent); + tabContent.style.transition = `${this.animationDuration}ms cubic-bezier(0.35, 0, 0.25, 1)`; + tabContent.style.transform = `translate3d(${pos}, 0)`; + } + this._runTimeoutOutsideZone(index, () => { + tabContent.style.transform = ``; + tabContent.style.transition = ``; + tabContent.style.overflow = ``; + if (dynamicHeight) { + tabContent.style.height = ``; + } + if (currentIndex !== index) { + if (this.keepContent) { + this.renderer.addClass(tabContent, this.classes.hiddenContent); + } + tab._activeContent = false; + this._ngZone.run(() => this._markForCheck()); + } + }, this.animationDuration); + } + } + + /** Runs a timeout outside of the Angular zone to avoid triggering the change detection. */ + private _runTimeoutOutsideZone(index: number, fn: () => void, delay = 0) { + this._ngZone.runOutsideAngular(() => this._timeoutIds[`_${index}`] = window.setTimeout(fn, delay)); + } + + private _clearTimeouts(tabIndex?: number) { + if (tabIndex != null) { + const key = `_${tabIndex}`; + if (this._timeoutIds[key] != null) { + window.clearTimeout(this._timeoutIds[key]); + delete this._timeoutIds[key]; + } + } else { + Object.keys(this._timeoutIds) + .forEach(key => window.clearTimeout(this._timeoutIds[`_${key}`])); + } + } } @Component({ @@ -713,16 +773,31 @@ export class LyTab implements OnInit { @ViewChild('tabIndicator') _tabIndicator: ElementRef; @ContentChild(forwardRef(() => LyTabLabel), { static: true }) _tabLabel: LyTabLabel & { }; + /** Portal that will be the hosted content of the tab */ + private _contentPortal: TemplatePortal | null = null; + + /** @docs-private */ + get content(): TemplatePortal | null { + return this._contentPortal; + } + + _activeContent: boolean; + constructor( private _tabs: LyTabs, public _renderer: Renderer2, public _el: ElementRef, readonly sRenderer: StyleRenderer, - private _platform: Platform + private _platform: Platform, + private _viewContainerRef: ViewContainerRef, ) { } ngOnInit() { this._renderer.addClass(this._el.nativeElement, this._tabs.classes.tab); + this._contentPortal = new TemplatePortal( + this._templateRefLazy || this._templateRef, + this._viewContainerRef + ); } } @@ -796,12 +871,12 @@ export class LyTabLabel extends LyButton implements OnInit, AfterViewInit { if (this._tabs._selectedIndex === this._tab.index) { if (!this._activeTabStyle) { this._activeTabStyle = true; - this._renderer.addClass(this._el.nativeElement, this._tabs.classes.tabLabelActive); + this._renderer.addClass(this._el.nativeElement, this._tabs.classes.labelActive); this._updateTabScroll(); } } else if (this._activeTabStyle) { this._activeTabStyle = false; - this._renderer.removeClass(this._el.nativeElement, this._tabs.classes.tabLabelActive); + this._renderer.removeClass(this._el.nativeElement, this._tabs.classes.labelActive); } } @@ -825,3 +900,7 @@ export class LyTabLabel extends LyButton implements OnInit, AfterViewInit { ngAfterViewInit() { } } +/** Enforces a style recalculation of a DOM element by computing its styles. */ +function enforceStyleRecalculation(element: HTMLElement) { + window.getComputedStyle(element).getPropertyValue('opacity'); +} diff --git a/src/lib/themes/minima/base.ts b/src/lib/themes/minima/base.ts index adb4551fd..750ced1df 100644 --- a/src/lib/themes/minima/base.ts +++ b/src/lib/themes/minima/base.ts @@ -145,18 +145,18 @@ export class MinimaBase extends LyStyleUtils { &:not(${classes.disabled}) ${classes.container}:hover:after { border-bottom-color: currentColor } + ${classes.infix} { + border-top: ${1.125 * 0.75}em solid transparent + } + ${classes.infix}, ${classes.placeholder}, ${classes.displayWith} { + padding: .5em 0 + } &${classes.disabled} ${classes.container}:after { border-bottom-style: dotted border-color: inherit } - textarea${classes.inputNative} { - margin: 0.25em 0 - } - ${classes.inputNative}:not(textarea) { - padding: 0.25em 0 - } & ${classes.container} { - padding: 1em 0 0 + padding-top: 0.75em &:after { border-bottom-style: solid border-bottom-width: 1px @@ -169,13 +169,12 @@ export class MinimaBase extends LyStyleUtils { } } & ${classes.label} { - margin: 0.25em 0 - } - & ${classes.placeholder} { - margin: 0.25em 0 + padding-top: ${1.125 * 0.75}em + margin-top: ${-1.125 * 0.75 + 0.5}em } & ${classes.floatingLabel} { - transform: translateY(-1.25em) + transform: translateY(${1.125 * -0.75 - 0.5}em) + transform-origin: ${this.before} } }` ), @@ -184,16 +183,16 @@ export class MinimaBase extends LyStyleUtils { &:not(${classes.focused}):not({disabled}):hover ${classes.fieldset} { border-color: currentColor } + ${classes.infix} { + border-top: ${1.125 * 0.75}em solid transparent + } + ${classes.infix}, ${classes.placeholder}, ${classes.displayWith} { + padding: 1em 0 + } &${classes.focused} ${classes.fieldset} { border-width: 2px border-color: inherit } - & textarea${classes.inputNative} { - margin: 1em 0 - } - & ${classes.inputNative}:not(textarea) { - padding: 1em 0 - } & ${classes.container} { padding: 0 0.75em } @@ -201,25 +200,19 @@ export class MinimaBase extends LyStyleUtils { border-width: 1px border-radius: 5px padding: 0 .5em + margin-top: .25em } - & ${classes.prefix} { - &:after { - padding: 0.25em - } - } - & ${classes.suffix} { - &:after { - padding: 0.25em + ${classes.prefix}, ${classes.suffix} { + [ly-button] { + top: 0.25em } } & ${classes.label} { - margin: 1em 0 + padding-top: ${1.125 * 0.75}em + margin-top: ${1.125 * 0.75 - 1}em } - & ${classes.placeholder} { - margin: 1em 0 - } - & ${classes.floatingLabel}${classes.label} { - transform: translateY(-1.75em) + & ${classes.floatingLabel} { + transform: translateY(${-1.125 * 0.75 - 0.75}em) } & ${classes.hintContainer} { padding: 0 0.75em @@ -231,15 +224,15 @@ export class MinimaBase extends LyStyleUtils { &:not(${classes.focused}):not(${classes.disabled}) ${classes.container}:hover:after { border-bottom-width: 1px } - textarea${classes.inputNative} { - margin: 1.59375em 0 0.40625em + ${classes.infix} { + border-top: ${1.125 * 0.75}em solid transparent } - ${classes.inputNative}:not(textarea) { - padding: 1.59375em 0 0.40625em + ${classes.infix}, ${classes.placeholder}, ${classes.displayWith} { + padding: 0.25em 0 0.75em } & ${classes.container} { + padding: .75em .75em 0 .75em border-radius: 5px 5px 0 0 - padding: 0 0.75em &:after { border-bottom-style: solid border-bottom-color: currentColor @@ -251,14 +244,13 @@ export class MinimaBase extends LyStyleUtils { border-bottom-width: 2px } } - & ${classes.placeholder} { - margin: 1.59375em 0 0.40625em - } & ${classes.label} { - margin: 1em 0 + padding-top: ${1.125 * 0.75}em + margin-top: ${-1.125 * 0.75 - .25}em } - & ${classes.floatingLabel}${classes.label} { - transform: translateY(-.75em) + & ${classes.floatingLabel} { + transform: translateY(${1.125 * -0.75 + 0.25}em) + transform-origin: ${this.before} } & ${classes.hintContainer} { padding: 0 0.75em @@ -297,7 +289,7 @@ export class MinimaBase extends LyStyleUtils { thumbVisible, thumbNotVisible, sliding - }, color) => lyl `{ + }, color) => lyl `{ & ${track}, & ${thumb}, & ${thumbLabel}, & ${bg}, & ${tick} { background-color: ${color} } @@ -340,18 +332,20 @@ export class MinimaBase extends LyStyleUtils { } } }`, - disabled: ({ - track, - thumb, - thumbContainer, - thumbContent, - thumbLabel, - bg, - tick, - tickActive, - horizontal, - vertical - }, color) => { + disabled: ( + { + track, + thumb, + thumbContainer, + thumbContent, + thumbLabel, + bg, + tick, + tickActive, + horizontal, + vertical + }, + color ) => { const colorDisabled = color.darken(2) .desaturate(2.5); const colorDisabledLum0_4 = colorDisabled.luminance(.4); @@ -435,7 +429,7 @@ export class MinimaBase extends LyStyleUtils { }`), body1: new StyleCollection(() => lyl `{ font-size: ${this.pxToRem(16)} - font-weight: 400, + font-weight: 400 letter-spacing: ${0.5 / 16}em }`), body2: new StyleCollection(() => lyl `{ diff --git a/src/lib/tooltip/tooltip.ts b/src/lib/tooltip/tooltip.ts index 05724c07a..c2b1c7da7 100644 --- a/src/lib/tooltip/tooltip.ts +++ b/src/lib/tooltip/tooltip.ts @@ -164,7 +164,7 @@ export class LyTooltip implements OnInit, OnDestroy { if (!this._tooltipOverlay && this.tooltip && !this._showTimeoutId) { const tooltipRef = this.tooltip; - this._showTimeoutId = setTimeout(() => { + this._showTimeoutId = setTimeout(() => { // const rect = this._el.nativeElement.getBoundingClientRect(); const tooltip = this._tooltipOverlay = this._overlay.create(tooltipRef, undefined, { styles: { @@ -190,8 +190,6 @@ export class LyTooltip implements OnInit, OnDestroy { hasBackdrop: false }); this._updatePosition(); - // const position = new Positioning(this.placement, this.xPosition, this.yPosition, this._el.nativeElement, tooltip.containerElement, this._theme.variables, 13); - // tooltip.containerElement.style.transform = `translate3d(${position.x}px,${position.y}px,0)`; this._theme.requestAnimationFrame(() => { this._theme.addStyle('lyTooltip:open', ({ @@ -201,7 +199,7 @@ export class LyTooltip implements OnInit, OnDestroy { this._showTimeoutId = null; this._markForCheck(); - }, delay); + }, delay) as any; } } @@ -215,14 +213,14 @@ export class LyTooltip implements OnInit, OnDestroy { } if (tooltipOverlay && !this._hideTimeoutId) { - this._hideTimeoutId = setTimeout(() => { + this._hideTimeoutId = setTimeout(() => { this._renderer.removeClass(tooltipOverlay.containerElement, this._theme.addStyle('lyTooltip:open', null)); setTimeout(() => tooltipOverlay.destroy(), 300); this._tooltipOverlay = null; this._hideTimeoutId = null; this._markForCheck(); - }, delay); + }, delay) as any; } } diff --git a/src/lib/typography/typography.directive.ts b/src/lib/typography/typography.directive.ts index 23d20f666..bec348618 100644 --- a/src/lib/typography/typography.directive.ts +++ b/src/lib/typography/typography.directive.ts @@ -75,10 +75,10 @@ export const LyTypographyMixinBase = mixinStyleUpdater( ] }) export class LyTypography extends LyTypographyMixinBase implements OnInit, OnChanges { - /** @docs-private */ - readonly classes = this._theme.renderStyleSheet(STYLES); /** @docs-private */ static readonly и = 'LyTypography'; + /** @docs-private */ + readonly classes = this._theme.renderStyleSheet(STYLES); private _lyTyp: string; private _lyTypClass: string | null; @@ -101,7 +101,7 @@ export class LyTypography extends LyTypographyMixinBase implements OnInit, OnCha } } } - get lyTyp() { + get lyTyp(): string { return this._lyTyp; } @@ -121,7 +121,7 @@ export class LyTypography extends LyTypographyMixinBase implements OnInit, OnCha this._noWrapClass = undefined; } } - get noWrap() { + get noWrap(): boolean { return this._noWrap; } @@ -188,7 +188,7 @@ export class LyTypography extends LyTypographyMixinBase implements OnInit, OnCha (theme: LyTypographyVariables) => { if (theme.typography && theme.typography.lyTyp) { const lyTyp = theme.typography.lyTyp[val]; - if (lyTyp) { + if (lyTyp) { return lyTyp instanceof StyleCollection ? lyTyp.setTransformer((_) => _()).css : lyTyp(); From 91a994a60584b5a31a0fbbee8771a4490d1a6f30 Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Sun, 30 Aug 2020 16:18:15 -0500 Subject: [PATCH 04/10] =?UTF-8?q?=C2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From b281741d08dbe8be7d4e295888172d46aeb1dd3b Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Sun, 30 Aug 2020 16:20:01 -0500 Subject: [PATCH 05/10] =?UTF-8?q?=C2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 1f080ac486de75db25e5ed2e7a9537e8b8681b7e Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Sun, 30 Aug 2020 16:20:03 -0500 Subject: [PATCH 06/10] =?UTF-8?q?=C2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 96fd33fe5b0aa1af7644bdb7873c0e72b37fb987 Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Sun, 30 Aug 2020 16:31:16 -0500 Subject: [PATCH 07/10] =?UTF-8?q?=C2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/tabs/tabs.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/tabs/tabs.ts b/src/lib/tabs/tabs.ts index 53ecb8d5d..14b8f4921 100644 --- a/src/lib/tabs/tabs.ts +++ b/src/lib/tabs/tabs.ts @@ -667,11 +667,11 @@ export class LyTabs extends LyTabsMixinBase implements OnChanges, OnInit, AfterV if (this.selectedIndex === index || this._selectedBeforeIndex === index) { const prevIndex = this._selectedBeforeIndex; const currentIndex = this.selectedIndex; - const dynamicHeight = this.dynamicHeight && this._platform.isBrowser; + const dynamicHeight = this.dynamicHeight && this._platform.isBrowser && prevIndex != null; const contentInner = tabContent.firstElementChild as HTMLDivElement; const contentHeight = dynamicHeight ? contentInner.getBoundingClientRect().height : null; const contentHeightPrev = dynamicHeight - ? this.tabContentList.toArray()[prevIndex]?.nativeElement.firstElementChild!.getBoundingClientRect().height + ? this.tabContentList.toArray()[prevIndex].nativeElement.firstElementChild!.getBoundingClientRect().height : null; if (currentIndex === index) { this.renderer.addClass(tabContent, this.classes.contentActive); From be161d0f4ae93a9473125410653751f731734874 Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Sun, 30 Aug 2020 17:54:33 -0500 Subject: [PATCH 08/10] =?UTF-8?q?release=20@alyle/ui=20v9.1.0=20?= =?UTF-8?q?=F0=9F=8E=89=20[ci=20skip]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .package.conf.yml | 4 ++-- CHANGELOG.md | 4 ++++ package.json | 2 +- src/lib/package.json | 2 +- src/lib/schematics/ng-add/index.ts | 2 +- src/lib/src/version.ts | 4 ++-- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.package.conf.yml b/.package.conf.yml index 3fcca740c..77da3d454 100644 --- a/.package.conf.yml +++ b/.package.conf.yml @@ -1,5 +1,5 @@ -version: 9.0.1 -lastUpdate: '2020-08-15T00:25:36.312Z' +version: 9.1.0 +lastUpdate: '2020-08-30T22:33:58.002Z' components: '@alyle/ui': / '@alyle/ui/color': color diff --git a/CHANGELOG.md b/CHANGELOG.md index cbe15e45d..f4bafcc6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# [9.1.0](https://github.com/A-l-y-l-e/Alyle-UI/compare/10.2.0...9.1.0) (2020-08-30) + + + ## [9.0.1](https://github.com/A-l-y-l-e/Alyle-UI/compare/9.0.0...9.0.1) (2020-08-15) diff --git a/package.json b/package.json index c8e6b80f9..50212763c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "alyle-ui-srcs", - "version": "9.0.1", + "version": "9.1.0", "license": "MIT", "engines": { "node": ">=12.13.0 <13.0.0" diff --git a/src/lib/package.json b/src/lib/package.json index 3e649a397..6a11566e5 100644 --- a/src/lib/package.json +++ b/src/lib/package.json @@ -1,6 +1,6 @@ { "name": "@alyle/ui", - "version": "9.0.1", + "version": "9.1.0", "description": "Minimal Design, a set of components for Angular", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" diff --git a/src/lib/schematics/ng-add/index.ts b/src/lib/schematics/ng-add/index.ts index 63030d92c..180c464d4 100644 --- a/src/lib/schematics/ng-add/index.ts +++ b/src/lib/schematics/ng-add/index.ts @@ -3,7 +3,7 @@ import { NodePackageInstallTask, RunSchematicTask } from '@angular-devkit/schema import { Schema } from './schema'; import { addPackageToPackageJson, getPackageVersionFromPackageJson } from '../utils/package-config'; -const AUI_VERSION = '9.0.1'; +const AUI_VERSION = '9.1.0'; const HAMMERJS_VERSION = '^2.0.8'; const ANGULAR_CDK_VERSION = '^9.2.4'; diff --git a/src/lib/src/version.ts b/src/lib/src/version.ts index 79de4fa1d..7838900e0 100644 --- a/src/lib/src/version.ts +++ b/src/lib/src/version.ts @@ -1,2 +1,2 @@ -export const AUI_VERSION = '9.0.1'; -export const AUI_LAST_UPDATE = '2020-08-15T00:25:36.312Z'; +export const AUI_VERSION = '9.1.0'; +export const AUI_LAST_UPDATE = '2020-08-30T22:33:58.002Z'; From 797a4cb516c0dfe16b1a9efb458ff7d3289ce3e8 Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Thu, 24 Sep 2020 16:08:14 -0500 Subject: [PATCH 09/10] =?UTF-8?q?=C2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/select/select.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index 2c83cde0d..6f890737e 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -898,7 +898,6 @@ export class LySelect .withTypeAhead(this._typeaheadDebounceInterval) .withVerticalOrientation() .withHorizontalOrientation(this._theme.variables.direction) - .withHomeAndEnd() .withAllowedModifierKeys(['shiftKey']); this._keyManager.tabOut.pipe(takeUntil(this._destroy)).subscribe(() => { From 5bc9414cc242d333aa2af583a03128c2e3dea97f Mon Sep 17 00:00:00 2001 From: Enlcxx Date: Thu, 24 Sep 2020 19:03:12 -0500 Subject: [PATCH 10/10] =?UTF-8?q?release=20@alyle/ui@9.2.0=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .package.conf.yml | 4 ++-- CHANGELOG.md | 4 ++++ package.json | 2 +- src/lib/package.json | 2 +- src/lib/schematics/ng-add/index.ts | 2 +- src/lib/src/version.ts | 4 ++-- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.package.conf.yml b/.package.conf.yml index 77da3d454..bbda7b313 100644 --- a/.package.conf.yml +++ b/.package.conf.yml @@ -1,5 +1,5 @@ -version: 9.1.0 -lastUpdate: '2020-08-30T22:33:58.002Z' +version: 9.2.0 +lastUpdate: '2020-09-24T21:56:04.032Z' components: '@alyle/ui': / '@alyle/ui/color': color diff --git a/CHANGELOG.md b/CHANGELOG.md index 62b427e69..a196f61eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# [9.2.0](https://github.com/A-l-y-l-e/Alyle-UI/compare/10.3.0...9.2.0) (2020-09-24) + + + # [9.1.0](https://github.com/A-l-y-l-e/Alyle-UI/compare/10.2.0...9.1.0) (2020-08-30) diff --git a/package.json b/package.json index 50212763c..4f94a7a35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "alyle-ui-srcs", - "version": "9.1.0", + "version": "9.2.0", "license": "MIT", "engines": { "node": ">=12.13.0 <13.0.0" diff --git a/src/lib/package.json b/src/lib/package.json index 6a11566e5..4ec00ed40 100644 --- a/src/lib/package.json +++ b/src/lib/package.json @@ -1,6 +1,6 @@ { "name": "@alyle/ui", - "version": "9.1.0", + "version": "9.2.0", "description": "Minimal Design, a set of components for Angular", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" diff --git a/src/lib/schematics/ng-add/index.ts b/src/lib/schematics/ng-add/index.ts index 180c464d4..2ac44b4e0 100644 --- a/src/lib/schematics/ng-add/index.ts +++ b/src/lib/schematics/ng-add/index.ts @@ -3,7 +3,7 @@ import { NodePackageInstallTask, RunSchematicTask } from '@angular-devkit/schema import { Schema } from './schema'; import { addPackageToPackageJson, getPackageVersionFromPackageJson } from '../utils/package-config'; -const AUI_VERSION = '9.1.0'; +const AUI_VERSION = '9.2.0'; const HAMMERJS_VERSION = '^2.0.8'; const ANGULAR_CDK_VERSION = '^9.2.4'; diff --git a/src/lib/src/version.ts b/src/lib/src/version.ts index 7838900e0..5a1305bb2 100644 --- a/src/lib/src/version.ts +++ b/src/lib/src/version.ts @@ -1,2 +1,2 @@ -export const AUI_VERSION = '9.1.0'; -export const AUI_LAST_UPDATE = '2020-08-30T22:33:58.002Z'; +export const AUI_VERSION = '9.2.0'; +export const AUI_LAST_UPDATE = '2020-09-24T21:56:04.032Z';