@festo-ui/angular 8.3.0-dev.664 → 8.3.0-dev.667

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,15 +49,14 @@ If you only want to load the styles for popovers or image gallery you can use fo
49
49
 
50
50
  ### Modules
51
51
 
52
- After installation you have to import the **FestoAngularModule** and the **BrowserAnimationsModule** to your root module (called `app.module.ts` in the majority of projects). Have a look at the following example:
52
+ After installation you have to import the **FestoAngularModule** to your root module (called `app.module.ts` in the majority of projects). Have a look at the following example:
53
53
 
54
54
  ```typescript
55
55
  import { FestoAngularModule } from '@festo-ui/angular';
56
- import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
57
56
 
58
57
  @NgModule({
59
58
  declarations: [AppComponent],
60
- imports: [BrowserModule, BrowserAnimationsModule, FormsModule, ReactiveFormsModule, FestoAngularModule, AppRoutingModule],
59
+ imports: [BrowserModule, FormsModule, ReactiveFormsModule, FestoAngularModule, AppRoutingModule],
61
60
  providers: []
62
61
  })
63
62
  export class AppModule {}
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { ViewEncapsulation, Component, ContentChild, SimpleChange, ContentChildren, Input, EventEmitter, Output, HostListener, Directive, HostBinding, Optional, TemplateRef, Injector, Injectable, ViewChild, Pipe, DOCUMENT, Inject, ChangeDetectionStrategy, inject, ViewContainerRef, ElementRef, NgModule, forwardRef, CUSTOM_ELEMENTS_SCHEMA, LOCALE_ID, SecurityContext } from '@angular/core';
2
+ import { ViewEncapsulation, Component, ContentChild, SimpleChange, ContentChildren, Input, EventEmitter, Output, HostListener, Directive, HostBinding, Optional, TemplateRef, Injector, Injectable, ViewChild, Pipe, signal, output, DOCUMENT, Inject, ChangeDetectionStrategy, inject, ViewContainerRef, ElementRef, NgModule, forwardRef, CUSTOM_ELEMENTS_SCHEMA, LOCALE_ID, SecurityContext } from '@angular/core';
3
3
  import { Subject, BehaviorSubject, noop, Subscription } from 'rxjs';
4
4
  import * as i1 from '@angular/router';
5
5
  import { RouterModule, NavigationStart } from '@angular/router';
@@ -12,7 +12,6 @@ import { ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
12
12
  import SimpleBar from 'simplebar';
13
13
  import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
14
14
  import * as i1$3 from '@angular/platform-browser';
15
- import { trigger, state, transition, style, animate, sequence } from '@angular/animations';
16
15
  import { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';
17
16
  import * as i1$4 from '@angular/forms';
18
17
  import { FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
@@ -1666,15 +1665,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
1666
1665
 
1667
1666
  class FngSnackbarComponent {
1668
1667
  constructor() {
1669
- this.data = {};
1670
- this.close = new EventEmitter();
1671
- this.action = new EventEmitter();
1672
- this.blockDisplay = 'block';
1673
- this.animationState = 'init';
1668
+ this.data = signal({}, ...(ngDevMode ? [{ debugName: "data" }] : []));
1669
+ this.close = output();
1670
+ this.action = output();
1671
+ this.isShown = signal(false, ...(ngDevMode ? [{ debugName: "isShown" }] : []));
1672
+ this.stackIndex = signal(0, ...(ngDevMode ? [{ debugName: "stackIndex" }] : []));
1673
+ }
1674
+ get transform() {
1675
+ // calculate the translateY values based on stack index
1676
+ const stackIndex = this.stackIndex();
1677
+ // when entering, the snackbar will animate up to this value
1678
+ const enteringValue = stackIndex * 24;
1679
+ // when leaving, the snackbar will animate back to this value
1680
+ const leavingValue = (stackIndex - 1) * 24;
1681
+ return this.isShown()
1682
+ ? `translateY(-${enteringValue}px)`
1683
+ : `translateY(-${leavingValue}px)`;
1674
1684
  }
1675
1685
  ngAfterViewInit() {
1676
- if (this.data && this.data.disappearAfter) {
1677
- this.timeout = setTimeout(() => this.onClose(), this.data.disappearAfter);
1686
+ // delay to allow for initial rendering before showing
1687
+ setTimeout(() => {
1688
+ this.isShown.set(true);
1689
+ }, 100);
1690
+ const data = this.data();
1691
+ if (data && data.disappearAfter) {
1692
+ this.timeout = setTimeout(() => this.onClose(), data.disappearAfter);
1678
1693
  }
1679
1694
  }
1680
1695
  ngOnDestroy() {
@@ -1686,59 +1701,19 @@ class FngSnackbarComponent {
1686
1701
  this.action.emit();
1687
1702
  }
1688
1703
  onClose() {
1689
- this.close.emit();
1704
+ this.isShown.set(false);
1705
+ // delay to allow for animation before emitting close event
1706
+ setTimeout(() => {
1707
+ this.close.emit();
1708
+ }, 300);
1690
1709
  }
1691
1710
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FngSnackbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1692
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: FngSnackbarComponent, isStandalone: true, selector: "fng-snackbar", inputs: { data: "data" }, outputs: { close: "close", action: "action" }, host: { properties: { "style.display": "this.blockDisplay", "@appearDisappear": "this.animationState" } }, ngImport: i0, template: "<div\n [ngClass]=\"{\n 'fwe-snackbar': true,\n 'fwe-snackbar-b': data?.variant === 'b',\n 'fwe-snackbar-c': data?.variant === 'c',\n 'fwe-snackbar-info': data?.type === 'info',\n 'fwe-snackbar-warning': data?.type === 'warning',\n 'fwe-snackbar-error': data?.type === 'error',\n 'fwe-snackbar-shadow': data?.darkBackground\n }\"\n >\n <span>{{ data?.text }}</span>\n @if (data?.action) {\n <button aria-label=\"UserAction\" type=\"button\" class=\"fwe-snackbar-link-btn\" (click)=\"onAction()\">\n {{ data?.action }}\n </button>\n }\n\n @if (data?.action && data?.showClose) {\n <div class=\"fwe-snackbar-separator\"></div>\n }\n\n @if (data?.showClose) {\n <button aria-label=\"Close\" type=\"button\" class=\"fwe-snackbar-close-btn\" (click)=\"onClose()\">\n <span class=\"fwe-sr-only\">Close</span>\n </button>\n }\n</div>\n", styles: [".fwe-snackbar{pointer-events:all}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], animations: [
1693
- trigger('appearDisappear', [
1694
- state('init', style({ opacity: 0 })),
1695
- state('first', style({
1696
- opacity: 1,
1697
- transform: 'translateY(0)'
1698
- })),
1699
- state('fadeIn', style({ opacity: '1' })),
1700
- transition('void => fadeIn', [style({ opacity: 0 }), animate('0.6s ease-out')]),
1701
- transition('void => first', [style({ transform: 'translateY(100px)' }), animate('0.6s ease-out')]),
1702
- transition(':leave', sequence([
1703
- style({ 'margin-bottom': '24px' }),
1704
- animate('0.3s ease-out', style({ opacity: 0 })),
1705
- animate('0.3s ease-out', style({ height: '0px', 'margin-bottom': '0px' }))
1706
- ]))
1707
- ])
1708
- ], encapsulation: i0.ViewEncapsulation.None }); }
1711
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: FngSnackbarComponent, isStandalone: true, selector: "fng-snackbar", outputs: { close: "close", action: "action" }, ngImport: i0, template: "<div\n [ngClass]=\"{\n 'fwe-snackbar': true,\n 'fwe-snackbar-b': data()?.variant === 'b',\n 'fwe-snackbar-c': data()?.variant === 'c',\n 'fwe-snackbar-info': data()?.type === 'info',\n 'fwe-snackbar-warning': data()?.type === 'warning',\n 'fwe-snackbar-error': data()?.type === 'error',\n 'fwe-snackbar-shadow': data()?.darkBackground,\n 'fng-snackbar-entering': isShown(),\n 'fng-snackbar-leaving': !isShown(),\n 'fng-snackbar-first': stackIndex() === 0\n }\"\n [style.transform]=\"transform\"\n >\n <span>{{ data()?.text }}</span>\n @if (data()?.action) {\n <button aria-label=\"UserAction\" type=\"button\" class=\"fwe-snackbar-link-btn\" (click)=\"onAction()\">\n {{ data()?.action }}\n </button>\n }\n\n @if (data()?.action && data()?.showClose) {\n <div class=\"fwe-snackbar-separator\"></div>\n }\n\n @if (data()?.showClose) {\n <button aria-label=\"Close\" type=\"button\" class=\"fwe-snackbar-close-btn\" (click)=\"onClose()\">\n <span class=\"fwe-sr-only\">Close</span>\n </button>\n }\n</div>\n", styles: [":host{display:block}.fwe-snackbar{pointer-events:all;transition:transform .3s ease-out,opacity .25s ease-out;opacity:0;margin-bottom:0!important}.fwe-snackbar.fng-snackbar-first{margin-bottom:24px!important;opacity:1;transform:translateY(100px)}.fwe-snackbar.fng-snackbar-entering{opacity:1}.fwe-snackbar.fng-snackbar-leaving{opacity:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], encapsulation: i0.ViewEncapsulation.None }); }
1709
1712
  }
1710
1713
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FngSnackbarComponent, decorators: [{
1711
1714
  type: Component,
1712
- args: [{ imports: [CommonModule], selector: 'fng-snackbar', encapsulation: ViewEncapsulation.None, animations: [
1713
- trigger('appearDisappear', [
1714
- state('init', style({ opacity: 0 })),
1715
- state('first', style({
1716
- opacity: 1,
1717
- transform: 'translateY(0)'
1718
- })),
1719
- state('fadeIn', style({ opacity: '1' })),
1720
- transition('void => fadeIn', [style({ opacity: 0 }), animate('0.6s ease-out')]),
1721
- transition('void => first', [style({ transform: 'translateY(100px)' }), animate('0.6s ease-out')]),
1722
- transition(':leave', sequence([
1723
- style({ 'margin-bottom': '24px' }),
1724
- animate('0.3s ease-out', style({ opacity: 0 })),
1725
- animate('0.3s ease-out', style({ height: '0px', 'margin-bottom': '0px' }))
1726
- ]))
1727
- ])
1728
- ], template: "<div\n [ngClass]=\"{\n 'fwe-snackbar': true,\n 'fwe-snackbar-b': data?.variant === 'b',\n 'fwe-snackbar-c': data?.variant === 'c',\n 'fwe-snackbar-info': data?.type === 'info',\n 'fwe-snackbar-warning': data?.type === 'warning',\n 'fwe-snackbar-error': data?.type === 'error',\n 'fwe-snackbar-shadow': data?.darkBackground\n }\"\n >\n <span>{{ data?.text }}</span>\n @if (data?.action) {\n <button aria-label=\"UserAction\" type=\"button\" class=\"fwe-snackbar-link-btn\" (click)=\"onAction()\">\n {{ data?.action }}\n </button>\n }\n\n @if (data?.action && data?.showClose) {\n <div class=\"fwe-snackbar-separator\"></div>\n }\n\n @if (data?.showClose) {\n <button aria-label=\"Close\" type=\"button\" class=\"fwe-snackbar-close-btn\" (click)=\"onClose()\">\n <span class=\"fwe-sr-only\">Close</span>\n </button>\n }\n</div>\n", styles: [".fwe-snackbar{pointer-events:all}\n"] }]
1729
- }], propDecorators: { data: [{
1730
- type: Input
1731
- }], close: [{
1732
- type: Output
1733
- }], action: [{
1734
- type: Output
1735
- }], blockDisplay: [{
1736
- type: HostBinding,
1737
- args: ['style.display']
1738
- }], animationState: [{
1739
- type: HostBinding,
1740
- args: ['@appearDisappear']
1741
- }] } });
1715
+ args: [{ imports: [CommonModule], selector: 'fng-snackbar', encapsulation: ViewEncapsulation.None, template: "<div\n [ngClass]=\"{\n 'fwe-snackbar': true,\n 'fwe-snackbar-b': data()?.variant === 'b',\n 'fwe-snackbar-c': data()?.variant === 'c',\n 'fwe-snackbar-info': data()?.type === 'info',\n 'fwe-snackbar-warning': data()?.type === 'warning',\n 'fwe-snackbar-error': data()?.type === 'error',\n 'fwe-snackbar-shadow': data()?.darkBackground,\n 'fng-snackbar-entering': isShown(),\n 'fng-snackbar-leaving': !isShown(),\n 'fng-snackbar-first': stackIndex() === 0\n }\"\n [style.transform]=\"transform\"\n >\n <span>{{ data()?.text }}</span>\n @if (data()?.action) {\n <button aria-label=\"UserAction\" type=\"button\" class=\"fwe-snackbar-link-btn\" (click)=\"onAction()\">\n {{ data()?.action }}\n </button>\n }\n\n @if (data()?.action && data()?.showClose) {\n <div class=\"fwe-snackbar-separator\"></div>\n }\n\n @if (data()?.showClose) {\n <button aria-label=\"Close\" type=\"button\" class=\"fwe-snackbar-close-btn\" (click)=\"onClose()\">\n <span class=\"fwe-sr-only\">Close</span>\n </button>\n }\n</div>\n", styles: [":host{display:block}.fwe-snackbar{pointer-events:all;transition:transform .3s ease-out,opacity .25s ease-out;opacity:0;margin-bottom:0!important}.fwe-snackbar.fng-snackbar-first{margin-bottom:24px!important;opacity:1;transform:translateY(100px)}.fwe-snackbar.fng-snackbar-entering{opacity:1}.fwe-snackbar.fng-snackbar-leaving{opacity:0}\n"] }]
1716
+ }] });
1742
1717
 
1743
1718
  class FngSnackbarService {
1744
1719
  constructor() {
@@ -1784,17 +1759,16 @@ class FngSnackbarContainerDirective {
1784
1759
  const complete = new Subject();
1785
1760
  const componentRef = this.viewContainerRef.createComponent(FngSnackbarComponent);
1786
1761
  const componentInstance = componentRef.instance;
1787
- componentInstance.data = { ...this.fngSnackbarContainer, ...snackDescription.data };
1788
- componentInstance.animationState = this.snacks.length === 0 ? 'first' : 'fadeIn';
1762
+ componentInstance.data.set({ ...this.fngSnackbarContainer, ...snackDescription.data });
1789
1763
  const snackbarRef = { componentRef, complete };
1790
- componentInstance.close.pipe(takeUntil(complete)).subscribe(() => {
1764
+ componentInstance.close.subscribe(() => {
1791
1765
  this.remove(snackbarRef);
1792
1766
  if (snackDescription.closeCallback) {
1793
1767
  snackDescription.closeCallback();
1794
1768
  }
1795
1769
  });
1796
- componentInstance.action.pipe(takeUntil(complete)).subscribe(() => {
1797
- if (componentInstance.data?.closeOnAction) {
1770
+ componentInstance.action.subscribe(() => {
1771
+ if (componentInstance.data()?.closeOnAction) {
1798
1772
  this.remove(snackbarRef);
1799
1773
  }
1800
1774
  if (snackDescription.actionCallback) {
@@ -1802,12 +1776,14 @@ class FngSnackbarContainerDirective {
1802
1776
  }
1803
1777
  });
1804
1778
  this.snacks.push(snackbarRef);
1779
+ this.updateStackIndices();
1805
1780
  snackDescription.resolve(snackbarRef.componentRef);
1806
1781
  }
1807
1782
  remove(snackbarRef) {
1808
1783
  const index = this.snacks.indexOf(snackbarRef);
1809
1784
  if (index !== -1) {
1810
1785
  const deletedSnackbarRef = this.snacks.splice(index, 1);
1786
+ this.updateStackIndices();
1811
1787
  if (deletedSnackbarRef != null && deletedSnackbarRef.length > 0) {
1812
1788
  const deletedSnackbar = deletedSnackbarRef[0];
1813
1789
  if (deletedSnackbar.complete != null) {
@@ -1821,6 +1797,11 @@ class FngSnackbarContainerDirective {
1821
1797
  }
1822
1798
  }
1823
1799
  }
1800
+ updateStackIndices() {
1801
+ this.snacks.forEach((snack, index) => {
1802
+ snack.componentRef.instance.stackIndex.set(this.snacks.length - index - 1);
1803
+ });
1804
+ }
1824
1805
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FngSnackbarContainerDirective, deps: [{ token: i0.ViewContainerRef }, { token: FngSnackbarService }], target: i0.ɵɵFactoryTarget.Directive }); }
1825
1806
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.4", type: FngSnackbarContainerDirective, isStandalone: true, selector: "[fngSnackbarContainer]", inputs: { fngSnackbarContainer: "fngSnackbarContainer" }, ngImport: i0 }); }
1826
1807
  }