Search code examples
angularangular-flex-layout

Show/Hide using custom breakpoints and angular/flex-layout


I'm using Angular(v5.0.2), and Angular-FlexLayout (v2.0.0-beta.10-4905443). I'm trying to use custom breakpoints with every directive provided by @angular/flex-layout.

I have added custom breakpoints:

import {DEFAULT_BREAKPOINTS, BREAKPOINTS} from '@angular/flex-layout';

const CUSTOM_BREAKPOINTS = [
  {
    alias: 'sm.landscape',
    suffix: 'SmLandscape',
    mediaQuery: 'screen and (min-width:55em) and (max-width: 80em) and (orientation: landscape)',
    overlapping: true
  }
];

export const CustomBreakPointsProvider = {
  provide: BREAKPOINTS,
  useValue: [...DEFAULT_BREAKPOINTS,...CUSTOM_BREAKPOINTS],
};

I have extended the ShowHideDirective:

import { Directive, ElementRef, Renderer2, Input, Optional, Self } from '@angular/core'
import { ShowHideDirective, negativeOf, LayoutDirective, MediaMonitor } from '@angular/flex-layout'

@Directive({
  selector: `
    [fxHide.sm.landscape],
    [fxShow.sm.landscape],
  `
})
export class CustomShowHideDirective extends ShowHideDirective {
  constructor(monitor: MediaMonitor, @Optional() @Self() protected _layout: LayoutDirective, protected elRef: ElementRef, protected renderer: Renderer2) {
    super(monitor, _layout, elRef, renderer)
  }

  @Input('fxHide.sm.landscape') set hideSmLandscape(val) {this._cacheInput("showSmLandscape", negativeOf(val))}
  @Input('fxShow.sm.landscape') set showSmLandscape(val: boolean) {this._cacheInput("showSmLandscape", <boolean>val)}
}

Removing the @Optional() @Self() to stay closer to the doc triggers errors: No provider found for LayoutDirective. Adding LayoutDirective, ElementRef to the providers triggers the same error as here. I thus extend the class following the source code.

I use what I have defined in my app.module:

@NgModule({
  declarations: [
    AppComponent,
    CustomShowHideDirective,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpModule,
    FlexLayoutModule,
  ],
  providers: [
    CustomBreakPointsProvider
  ],
  bootstrap: [AppComponent]
})

I show or hide elements depending on the screen's size:

<p>
  <span fxHide="false" fxHide.sm="true">fxHide.sm</span>
  <span fxShow="false" fxShow.sm="true">fxShow.sm</span>
</p>
<p>
  <span fxHide="false" fxHide.sm.landscape="true">fxHide.sm.landscape</span>
  <span fxShow="false" fxShow.sm.landscape="true">fxShow.sm.landscape</span>
</p>
<p>
  <span fxHide="true" fxHide.sm.landscape="false">hack fxShow.sm.landscape</span>
  <span fxShow="true" fxShow.sm.landscape="false">hack fxHide.sm.landscape</span>
</p>
<p>
  <span fxHide fxShow.sm.landscape>hack2 fxShow.sm.landscape</span>
  <span fxShow fxHide.sm.landscape>hack2 fxHide.sm.landscape</span>
</p>
<p>
  <span fxHide="false" fxHide.gt-sm="true">fxHide.gt-sm</span>
  <span fxShow="false" fxShow.gt-sm="true">fxShow.gt-sm</span>
</p>
<span *ngIf="media.isActive('sm')">sm</span>
<span *ngIf="media.isActive('sm.landscape')">sm.landscape</span>
<span *ngIf="media.isActive('md')">md</span>
<span *ngIf="media.isActive('lg')">lg</span>

The expected behavior is thus the following: - no matter the screen size, exactly one item is shown per line, except for the last one, where all available mediaQueries are displayed - on each line appears fxHide or fxShow depending on the screen size

The actual behavior is as presented on the attached screenshots: Large screen, Custom media query activated, Small screen.

You see that the ShowHideDirective doesn't work anymore for the default breakpoints. In addition, I can hide an element when the custom breakpoint is active, but the opposite behavior doesn't work.

I have already updated all my npm packages to the latest available, delete the node_modules folder and ran npm install again, without effect.

I also tried adding LayoutDirective, ElementRef to the list of providers. I then get the same error as here.

Adding a print in the showSmLandscape method of my CustomShowHideDirective shows that the method is indeed called, and with the right arguments (as far as I can tell). Same thing for the fxShow.

Adding the same kind of debug in show and hide (directly in my node_modules folder) shows that the ShowHideDirective is called with the right values.

Any idea/hint/comment is welcome. I haven't managed to create a plunker yet, due to errors loading operators from rxjs...

Edit: A working plunker is finally available here (working means showing the unexpected behavior ^^)

Thanks for any contribution ;)


Solution

  • This seems like a combination of out-dated docs and a bug: see this issue on the github repo, referencing the more precise bug

    Hoping this will be fixed soon ;)