Repository: react-materialize/react-materialize
Pull request #670 (2018-10-13 13:28:59)

3.0.0-SideNav
# Description

This Pull Request is for #605 

Dropping 'jQuery' support, now using `M.Sidenav.init()`.

Adding new options (as per the [documentation](https://materializecss.com/sidenav.html#options)):

-  inDuration
- outDuration
- onOpenStart
- onOpenEnd
- onCloseStart
- onCloseEnd
- preventScrolling

Removing deprecated options:

- menuWidth
- closeOnClick

## Type of change

- [x] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [x] This change requires a documentation update

# How Has This Been Tested?

I've generated new snapshot and used the new mocker.

# Checklist:

- [x] I have commented my code, particularly in hard-to-understand areas
- [x] My changes generate no new warnings
- [x] I have not generated a new package version. (the maintainers will handle that)


alextrastero: Fixes #605 

Patch:
diff --git a/src/SideNav.js b/src/SideNav.js
index cf1f56d..e45e6e6 100644
--- a/src/SideNav.js
+++ b/src/SideNav.js
@@ -10,8 +10,14 @@ class SideNav extends Component {
   }
 
   componentDidMount() {
-    const { options = {} } = this.props;
-    $('.sidenav').sidenav(options);
+    if (typeof M !== 'undefined') {
+      const { options } = this.props;
+      this.instance = M.Sidenav.init(this._sidenav, options);
+    }
+  }
+
+  componentWillUnmount() {
+    this.instance && this.instance.destroy();
   }
 
   render() {


Test patch:
diff --git a/test/SideNav.spec.js b/test/SideNav.spec.js
index ff07f1d..9c2b783 100644
--- a/test/SideNav.spec.js
+++ b/test/SideNav.spec.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import { shallow, mount } from 'enzyme';
 import SideNav from '../src/SideNav';
-import mocker from './helper/mocker';
+import mocker from './helper/new-mocker';
 
 function setup(props = {}, children, mounted) {
   const propsIn = {
@@ -26,8 +26,17 @@ function setup(props = {}, children, mounted) {
 }
 
 describe('<SideNav />', () => {
-  const sideNavMock = jest.fn();
-  const restore = mocker('sidenav', sideNavMock);
+  const sideNavInitMock = jest.fn();
+  const sideNavInstanceDestroyMock = jest.fn();
+  const sideNavMock = {
+    init: (el, options) => {
+      sideNavInitMock(options);
+      return {
+        destroy: sideNavInstanceDestroyMock
+      };
+    }
+  };
+  const restore = mocker('Sidenav', sideNavMock);
 
   afterAll(() => {
     restore();
@@ -43,21 +52,22 @@ describe('<SideNav />', () => {
     expect(sideNav).toMatchSnapshot();
   });
 
-  test('should render fixed if not passed trigger or fixed', () => {
-    const { wrapper } = setup({ className: 'red' });
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('should render trigger on large screens not fixed`', () => {
+  test('can render a `trigger`', () => {
     const { trigger } = setup({ className: 'green' });
     expect(trigger).toMatchSnapshot();
   });
 
   test('should be fixed if no trigger is passed', () => {
+    const { sideNavProps } = setup({
+      id: 'test123',
+      options: {},
+      shouldTransfer: true
+    });
     const component = <SideNav className="red" />;
     const wrapper = shallow(component);
-    const sideNav = wrapper.find('.sidenav');
+    const sideNav = wrapper.find('.sidenav-fixed');
     expect(sideNav).toMatchSnapshot();
+    expect(sideNavProps.trigger).toBeUndefined();
   });
 
   test('should render a given id', () => {
@@ -65,7 +75,6 @@ describe('<SideNav />', () => {
     expect(sideNavProps.id).toEqual('test');
     expect(triggerProps['data-target']).toEqual('test');
   });
-
   test('should render children', () => {
     const { sideNav } = setup({}, <span className="test-child" />);
     const children = sideNav.find('.test-child');
@@ -79,10 +88,6 @@ describe('<SideNav />', () => {
       options: {},
       shouldTransfer: true
     });
-
-    expect(sideNavProps.trigger).toBeUndefined();
-    expect(sideNavProps.options).toBeUndefined();
-    expect(sideNavProps.shouldTransfer).toBeTruthy();
   });
 
   test('should call sideNav with the given options', () => {
@@ -91,6 +96,12 @@ describe('<SideNav />', () => {
       edge: 'right'
     };
     mount(<SideNav trigger={<span>trigger</span>} options={options} />);
-    expect(sideNavMock).toHaveBeenCalledWith(options);
+    expect(sideNavInitMock).toHaveBeenCalledWith(options);
+  });
+
+  test('should be destroyed when unmounted', () => {
+    const component = shallow(<SideNav className="red" />);
+    component.unmount();
+    expect(sideNavInstanceDestroyMock).toHaveBeenCalled();
   });
 });
diff --git a/test/__snapshots__/SideNav.spec.js.snap b/test/__snapshots__/SideNav.spec.js.snap
index 7dc1cbf..bcb2a2f 100644
--- a/test/__snapshots__/SideNav.spec.js.snap
+++ b/test/__snapshots__/SideNav.spec.js.snap
@@ -7,6 +7,15 @@ exports[`<SideNav /> can be \`fixed\` 1`] = `
 />
 `;
 
+exports[`<SideNav /> can render a \`trigger\` 1`] = `
+<button
+  className="trigger show-on-large sidenav-trigger"
+  data-target="sidenav_2"
+>
+  Show sidenav
+</button>
+`;
+
 exports[`<SideNav /> renders 1`] = `
 <ul
   className="sidenav"
@@ -17,30 +26,6 @@ exports[`<SideNav /> renders 1`] = `
 exports[`<SideNav /> should be fixed if no trigger is passed 1`] = `
 <ul
   className="sidenav sidenav-fixed red"
-  id="sidenav_4"
+  id="sidenav_3"
 />
 `;
-
-exports[`<SideNav /> should render fixed if not passed trigger or fixed 1`] = `
-<div>
-  <button
-    className="trigger show-on-large sidenav-trigger"
-    data-target="sidenav_2"
-  >
-    Show sidenav
-  </button>
-  <ul
-    className="sidenav red"
-    id="sidenav_2"
-  />
-</div>
-`;
-
-exports[`<SideNav /> should render trigger on large screens not fixed\` 1`] = `
-<button
-  className="trigger show-on-large sidenav-trigger"
-  data-target="sidenav_3"
->
-  Show sidenav
-</button>
-`;