Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[MdSidenav] - Sidenav Resizing Regression #6743

Closed
dereekb opened this issue Aug 30, 2017 · 42 comments · Fixed by #8488
Closed

[MdSidenav] - Sidenav Resizing Regression #6743

dereekb opened this issue Aug 30, 2017 · 42 comments · Fixed by #8488
Assignees
Labels
P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful
Milestone

Comments

@dereekb
Copy link
Contributor

dereekb commented Aug 30, 2017

Bug, feature request, or proposal:

Bug/Regression from 2.0.0-beta.8.

Also a feature request for an API to allow triggering recalculations for the MdSidenavContainer/MdDrawerContainer, or being able to update _styles manually and having the view update..

What is the expected behavior?

In the previous release 2.0.0-beta.8 the sidenav resized when the window was resized.

I have a responsive sidenav that uses Angular flex-layout for showing/hiding responsive content in the sidenav when the view changes from md to lg and vice-versa.

What is the current behavior?

In 2.0.0-beta.10 this is no longer the case. The changes made in #6189 made the sidenav update only when the sidenav is opening/closing.

Since flex-layout's changes occur without having to call open() or close() on the sidenav, the width recalculation doesn't occur.

example

What are the steps to reproduce?

Put dynamic/responsive content within a sidenav that is configured with "side".

What is the use-case or motivation for changing an existing behavior?

Being able to dynamically call a refresh of the MdSidenav/MdDrawer or MdSidenavContainer/MdDrawerContainer.

Even better would be an accessor to allow manually setting the margin of the sidenav to allow for pre-computing the _style variable and updating it when needed.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular 4.3.5
Angular Material 2.0.0-beta.10

Is there anything else we should know?

This is similar to #6583.

For right now I am using the following hack in my navigation directive to workaround whenever the ObservableMedia from angular flex-layout changes:

// Timeout required for flex-layout directives to update the child views/the width.
setTimeout(() => {
            (this._container as any)._updateStyles();
            (this._container as any)._changeDetectorRef.markForCheck();
}, 0);
emoralesb05 pushed a commit to Teradata/covalent that referenced this issue Aug 31, 2017
…opening sometimes at the beggining

possible issue would be angular/components#6743
emoralesb05 added a commit to Teradata/covalent that referenced this issue Sep 1, 2017
* chore(): upgrade to material/[email protected]

* chore(): update rollup script with cdk dependencies

* fix(): fix breaking changes from cdk imports and interface modifications in material

* feat(): rename mat-sidenav- classes to mat-drawer- and replace align input with position input

* fix(steps): fix demo to start in vertical mode

* chore(): rename md-line with mdLine

* chore(): rename md-tab-label to mdTabLabel

* chore(): rename md-card-avatar to mdCardAvatar

* chore(): rename md-input-container to md-form-field and its classes

* chore(): rename md-ripple to mdRipple

* chore(): rename md-list-icon and md-list-avatar to mdListIcon and mdListAvatar

* chore(): bump to [email protected] since its a requirement for angular/material now

* chore(): update platform package.json's with bumps

* fix(chips): md-basic-chip behaves diff now so click on chip was not working

* fix(data-table): fix color of pseudo checkboxes in data-table

* chore(paging): set fixed 30px in input since it has 200px by default in the paging demo

* fix(paging): fix padding on md-selects used in td-paging-bar

* chore(dynamic-forms): use flex row to stetch inputs/textareas

* chore(dynamic-forms): update slider label using new classes

* fix(layout-docs): workaround for now since MdSidenav has issues when opening sometimes at the beggining

possible issue would be angular/components#6743

* feat(chips): make demo be OnPush change detection

* docs(paging): updated 'md-input-container' to 'md-form-field'
@djfishe
Copy link

djfishe commented Sep 4, 2017

+1. Same issue I have after upgrading to 2.0.0-beta.10

@sbeaufort
Copy link

sbeaufort commented Sep 6, 2017

Same issue after upgrading from 2.0.0-beta.8 to 2.0.0-beta.10

My workarround :

app.component.html

<md-sidenav class="main-sidenav" #sidenav mode="side" opened="false">

app.component.ts

export class AppComponent implements  AfterViewInit {

  @ViewChild('sidenav') 
  private sidenav: MdSidenav;

  ngAfterViewInit(): void {
    setTimeout(() => {
      this.sidenav.open();
    }, 250);
  }
}

@bleuscyther
Copy link

that is exactly what i did @sbeaufort. It creates a small animation at the first page load but its ok

@AppField
Copy link

I have the exact same issue.

@ghwyf
Copy link

ghwyf commented Sep 11, 2017

Here is my solution:
HTML

<md-sidenav-container #container>
    <md-sidenav  mode="side" opened="{{showMenu}}" class="shadow"></md-sidenav>
    <div class="my-content"></div>
</md-sidenav-container>

TS

export class MyComponent implements OnInit, AfterViewInit {
    @ViewChild('container') private _container;
    public showMenu: boolean = false;
    ...
    ngAfterViewInit() {
      setTimeout(()=>{
        this.showMenu = true;
      },0);
      this._container._ngZone.onMicrotaskEmpty.subscribe(() => {
        this._container._updateStyles();
        this._container._changeDetectorRef.markForCheck();
      })
    };
    ...
}

@AppField
Copy link

@ghwyf Thank you very much! This workaround also worked for me.

@benfontan
Copy link

Same issue for me upgrading to 2.0.0-beta.10.
I used @ghwyf fix which works perfectly, thank you.

@josephperrott
Copy link
Member

Closing as duplicate of #1130

@upstreamosGH
Copy link

upstreamosGH commented Sep 28, 2017

Join the responses of @angularexample in #1130 and @ghwyf here, works for me.
ngAfterViewInit seems too heavy for my application so I replace it with a specific call only when Subscription happens.

@adrm
Copy link

adrm commented Sep 28, 2017

@josephperrott I think the issues are about different things. The one you referenced is about opening and closing the sidenav automatically when viewport width changes. This one is about being able to resize the sidenav width while keeping it open.

Before the last update this worked with no problem. Right now, the main content is not being resized when the sidebar width is resized. Some people have shared workarounds for this, but I think it would be nice if Angular Material would support this use case which is quite popular in places like firebase.

Opened Closed
image image

@josephperrott
Copy link
Member

Reopening, sorry I misunderstood a bit there.

@josephperrott josephperrott reopened this Sep 28, 2017
@josephperrott josephperrott added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent responsive labels Sep 28, 2017
@axtho
Copy link

axtho commented Sep 29, 2017

It would be really helpful to give a guide on this. Are we going to do this with animations? Will there be a function on the sidenav (like sidenav.resize(width))?

I am on the material2-builds and use the new fixedInViewport, which is great. But when I animate the sidenav from 220px to 75px the main content section does not adjust (as it used to before).

Any comments as to what we will expect here?

@SpiderPork
Copy link

Same issue here.

@upstreamosGH
Copy link

After a while, I was forced to come back to 2.0.0-beta.8 when sidenav works perfect.

@adrm
Copy link

adrm commented Oct 3, 2017

I would like to know if material team thinks this has to be fixed. If not, I will apply a workaround and stop waiting for a fix.

Thanks a lot!

@jdazacon
Copy link

jdazacon commented Oct 6, 2017

Same problem here after upgrading to 2.0.0-beta.10 . The fix from @ghwyf doesn't work for me with angular 4.4.4

@halilibrahim
Copy link

Here's my temporary workaround to fix it:

<md-sidenav-container #sideNavContainer>
  <md-sidenav #sideNav align="start" mode="{{navMode}}" opened="true"
    [@sideNavAnim] (@sideNavAnim.done)="onSideNavAnimDone($event)">
    <!-- sidenav content -->
  </md-sidenav>
  <!-- primary content -->
  <router-outlet *ngIf="sideNavAnimFinished"></router-outlet>
</md-sidenav-container>
export class MyComponent {
  navMode = 'side';
  sideNavAnimFinished = false;
  ...
  onSideNavAnimDone(event) {
    this.sideNavAnimFinished = true;
  }
}

@axtho
Copy link

axtho commented Oct 9, 2017

the example mentioned by @sbeaufort does not work well when the component has changeDetection: ChangeDetectionStrategy.OnPush. In order to make it work you need to manually detect changes to the UI, example:

ngAfterViewInit(): void {
        const size = this.drawerState === 'open' ? 220 : 75;
        setTimeout(() => {
            this.sidenav.open();
            this.cd.detectChanges();
        }, size);
    }

@axtho
Copy link

axtho commented Oct 10, 2017

@crisbeto is the resize function on a roadmap for sidenav?
Would it not suffice to add a "closeTo" option which, when in side mode and when set, does not transform to visibility hidden but sets the drawer width to whatever was closeTo was set to?

@mpschaeuble
Copy link

I was using @ghwyf workaround until beta.11 as well. What worked for me in beta.12 is the following:

export class MyComponent implements OnInit, AfterViewInit {
    @ViewChild('container') private _container;
    public showMenu: boolean = false;
    ...
    ngAfterViewInit() {
      setTimeout(()=>{
        this.showMenu = true;
      },0);
      this._container._ngZone.onMicrotaskEmpty.subscribe(() => {
        this._container._updateContentMargins();
        this._container._changeDetectorRef.markForCheck();
      })
    };
    ...
}

@axtho
Copy link

axtho commented Oct 28, 2017

@mpschaeuble this does not seem to work anymore:
Property '_ngZone' is private and only accessible within class 'MatDrawerContainer'.

@mmalerba is there anything you guys can give us here?

crisbeto added a commit to crisbeto/material2 that referenced this issue Nov 17, 2017
Adds the `autosize` input that allows users to opt-in to drawers that auto-resize, similarly to the behavior before angular#6189. The behavior is off by default, because it's unnecessary for most use cases and can cause performance issues.

Fixes angular#6743.
crisbeto added a commit to crisbeto/material2 that referenced this issue Nov 17, 2017
Adds the `autosize` input that allows users to opt-in to drawers that auto-resize, similarly to the behavior before angular#6189. The behavior is off by default, because it's unnecessary for most use cases and can cause performance issues.

Fixes angular#6743.
@jelbourn jelbourn added this to the 5.0 milestone Nov 19, 2017
crisbeto added a commit to crisbeto/material2 that referenced this issue Nov 28, 2017
Adds the `autosize` input that allows users to opt-in to drawers that auto-resize, similarly to the behavior before angular#6189. The behavior is off by default, because it's unnecessary for most use cases and can cause performance issues.

Fixes angular#6743.
crisbeto added a commit to crisbeto/material2 that referenced this issue Dec 4, 2017
Adds the `autosize` input that allows users to opt-in to drawers that auto-resize, similarly to the behavior before angular#6189. The behavior is off by default, because it's unnecessary for most use cases and can cause performance issues.

Fixes angular#6743.
crisbeto added a commit to crisbeto/material2 that referenced this issue Dec 4, 2017
Adds the `autosize` input that allows users to opt-in to drawers that auto-resize, similarly to the behavior before angular#6189. The behavior is off by default, because it's unnecessary for most use cases and can cause performance issues.

Fixes angular#6743.
mmalerba pushed a commit that referenced this issue Dec 5, 2017
)

Adds the `autosize` input that allows users to opt-in to drawers that auto-resize, similarly to the behavior before #6189. The behavior is off by default, because it's unnecessary for most use cases and can cause performance issues.

Fixes #6743.
@axtho
Copy link

axtho commented Dec 5, 2017

@crisbeto thanks! Wonderful.

How does one achieve the minification of the sidenav now? Animations? Is there an example? Can I toggle to a certain width?

Thanks

@crisbeto
Copy link
Member

crisbeto commented Dec 5, 2017

@axtho what these changes do is allow you to opt in to having the drawer container resize once per change detection cycle, rather than on open/close.

@axtho
Copy link

axtho commented Dec 5, 2017

@crisbeto so it is correct to assume that I would need to trigger change detection after running an animation when the component is on OnPush?

@crisbeto
Copy link
Member

crisbeto commented Dec 5, 2017

You might not have to since the sidenav will check inside ngDoCheck which keeps firing not matter the change detection strategy.

@gerardcarbo
Copy link

Still happening in 6.4.7:

image

 "dependencies": {
    "@angular/animations": "6.1.8",
    "@angular/cdk": "^6.4.7",
    "@angular/common": "6.1.8",
    "@angular/compiler": "^6.1.8",
    "@angular/core": "6.1.8",
    "@angular/flex-layout": "^6.0.0-beta.18",
    "@angular/forms": "^6.1.8",
    "@angular/http": "6.1.8",
    "@angular/material": "^6.4.7",
    "@angular/platform-browser": "6.1.8",
    "@angular/platform-browser-dynamic": "6.1.8",
    "@angular/router": "6.1.8",
    "@angular/service-worker": "6.1.8",
    "@auth0/angular-jwt": "^2.0.0",
    "@ngx-formly/core": "^4.7.2",
    "@ngx-formly/material": "^4.7.2",
    "@ngx-translate/core": "^10.0.2",
    "@ngx-translate/http-loader": "^3.0.1",
    "core-js": "^2.5.2",
    "hammerjs": "^2.0.8",
    "material-design-icons-iconfont": "^3.0.3",
    "moment": "^2.22.1",
    "rxjs": "^6.3.2",
    "url": "^0.11.0",
    "util": "^0.11.0",
    "zone.js": "^0.8.26"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^0.8.3",
    "@angular/cli": "^6.2.3",
    "@angular/compiler-cli": "^6.1.8",
    "@angular/language-service": "6.1.8",
    "@biesbjerg/ngx-translate-extract": "^2.3.1",
    "@ngx-rocket/scripts": "^2.1.0",
    "@types/jasmine": "^2.5.52",
    "@types/jasminewd2": "^2.0.2",
    "@types/lodash": "^4.14.103",
    "@types/node": "^8.9.4",
    "codelyzer": "^4.1.0",
    "htmlhint": "^0.10.1",
    "https-proxy-agent": "^2.0.0",
    "jasmine-core": "~2.99.1",
    "jasmine-spec-reporter": "^4.2.1",
    "karma": "^3.0.0",
    "karma-chrome-launcher": "^2.2.0",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "^1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-junit-reporter": "^1.2.0",
    "protractor": "^5.4.0",
    "stylelint": "~9.1.1",
    "stylelint-config-recommended-scss": "~3.1.0",
    "stylelint-config-standard": "~18.2.0",
    "stylelint-scss": "~2.5.0",
    "ts-node": "~5.0.0",
    "tslint": "~5.9.1",
    "typescript": "^2.9.2"
  }

@ojpbay
Copy link

ojpbay commented Oct 11, 2018

Yep still an issue in 6.4.7
"@angular/material": "^6.4.7"

@kflo
Copy link

kflo commented Oct 19, 2018

Come on, wheres the fix...?

@aribrick
Copy link

Same. This is still an issue in 6.4.7

@brookesouza
Copy link

brookesouza commented Oct 19, 2018

This solution is still a bit of a hack, but it's less of a hack than setTimeout...

@ViewChild('sidenavContainer') private sidenavContainer: MatSidenavContainer;

this.sidenavContainer._contentMarginChanges
    .pipe(
        debounceTime(250),
        tap(() => this.sidenavContainer._contentMargins.left = this.sidenav._width),
    )
    .subscribe();

@bobbydowling
Copy link

this.sidenavContainer.autosize = true;

worked for me... after mucking with it for an hour. :(

@rb-mwindh
Copy link

I observed the same issue in 6.4.7, but only in certain cases:

  • when running the app in dev mode, there were no issues
  • when running the app in prod mode, the mat-sidenav-content was overlapped by the mat-sidenav
  • when disabling the buildOptimizer the issues disappeared
    When debugging the sourcecode of MatSidenavContainer, I recognized the code being executed to look like the source code of the 5.2.x branch
    (line 713): this._ngZone.run(() => this._contentMargins.next({left, right}));
    instead of
    (line 717): this._ngZone.run(() => this._contentMarginChanges.next(this._contentMargins));

Finally I identified the buildOptimizer cache as the culprit. After deleting <project>/node_modules/@angular-devkit/build-optimizer/src/.cache everything worked like a charm.

@FirstVertex
Copy link

@dereekb this issue should not be closed.
Still exists in the year 2019.
@bobbydowling solution is the only thing worked for me. And I mucked with it for like 3 hours.

@MeghnathDas
Copy link

MeghnathDas commented May 15, 2019

this.sidenavContainer.autosize = true;

worked for me... after mucking with it for an hour. :(

Where did you put autoSize = true ?
I have tried to put in OnInit() and AfterViewInit() but it didn't worked.

@FirstVertex
Copy link

@MeghnathDas here is documentation of autosize flag. It is option of mat-drawer-container
https://material.angular.io/components/sidenav/api#MatDrawerContainer
HTH

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful
Projects
None yet
Development

Successfully merging a pull request may close this issue.