diff --git a/docs/src/app/app-routes.jsx b/docs/src/app/app-routes.jsx
index 21fb52b16302d1..dff25ca006a208 100644
--- a/docs/src/app/app-routes.jsx
+++ b/docs/src/app/app-routes.jsx
@@ -36,6 +36,7 @@ let Paper = require('./components/pages/components/paper');
let Progress = require('./components/pages/components/progress');
let RefreshIndicator = require('./components/pages/components/refresh-indicator');
let Sliders = require('./components/pages/components/sliders');
+let SideNav = require('./components/pages/components/side-nav');
let Snackbar = require('./components/pages/components/snackbar');
let Switches = require('./components/pages/components/switches');
let Table = require('./components/pages/components/table');
@@ -89,6 +90,7 @@ let AppRoutes = (
+
diff --git a/docs/src/app/components/pages/components.jsx b/docs/src/app/components/pages/components.jsx
index 6fce441c4e70d9..26f821b19c4cd5 100644
--- a/docs/src/app/components/pages/components.jsx
+++ b/docs/src/app/components/pages/components.jsx
@@ -22,6 +22,7 @@ class Components extends React.Component {
{ route: 'progress', text: 'Progress'},
{ route: 'refresh-indicator', text: 'Refresh Indicator'},
{ route: 'sliders', text: 'Sliders'},
+ { route: 'side-nav', text: 'Side Nav'},
{ route: 'switches', text: 'Switches'},
{ route: 'snackbar', text: 'Snackbar'},
{ route: 'table', text: 'Table'},
diff --git a/docs/src/app/components/pages/components/side-nav.jsx b/docs/src/app/components/pages/components/side-nav.jsx
new file mode 100644
index 00000000000000..b2d965b964cb8e
--- /dev/null
+++ b/docs/src/app/components/pages/components/side-nav.jsx
@@ -0,0 +1,241 @@
+let React = require('react');
+let { Avatar,
+ SideNav,
+ SideNavItem,
+ SideNavHeader,
+ SideNavDivider,
+ SideNavSubheader,
+ ListItem,
+ MenuItem,
+ Styles,
+ RaisedButton,
+ FlatButton,
+ FontIcon,
+} = require('material-ui');
+let ComponentDoc = require('../../component-doc');
+
+let ActionAssignment = require('svg-icons/action/assignment');
+let ArrowDropRight = require('svg-icons/navigation-arrow-drop-right');
+let ContentInbox = require('svg-icons/content/inbox');
+let ActionInfo = require('svg-icons/action/info');
+
+
+class SideNavPage extends React.Component {
+
+ render() {
+ let code = '\n'
+ +'\n '
+ +'\n HEADER {/*same as primaryText="HEADER"*/}'
+ +'\n '
+ +'\n '
+ +'\n '
+ +'\n '
+ +'\n '
+ +'\n '
+ +'\n AWESOME SUBHEADER'
+ +'\n '
+ +'\n } />'
+ +'\n } />'
+ +'\n }'
+ +'\n primaryText="And" />'
+ +'\n '
+ +'\n } />'
+ +'\n } backgroundColor="#3f51b5"/>}/>'
+ +'\n '
+ +'\n '
+ +'\n GitHub
'
+ +'\n '
+ +'\n\n'
+
+ +'\n'
+ +'\n '
+ +'\n material ui'
+ +'\n '
+ +'\n '
+ +'\n '
+ +'\n '
+ +'\n Components'
+ +'\n '
+ +'\n '
+ +'\n '
+ +'\n Resources'
+ +'\n '
+ +'\n '
+ +'\n '
+ +'\n '
+ +'\n'
+
+ let componentInfo = [
+ {
+ name: 'Props',
+ infoArray: [
+ {
+ name: 'disableSwipeToOpen',
+ type: 'bool',
+ header: 'default: false',
+ desc: 'Indicates whether swiping sideways when the nav is closed ' +
+ 'should open the nav.'
+ },
+ {
+ name: 'docked',
+ type: 'bool',
+ header: 'default: true',
+ desc: 'Indicates that the left nav should be docked. In this state, the ' +
+ 'overlay won\'t show and clicking on a menu item will not close the left nav.'
+ },
+ {
+ name: 'header',
+ type: 'element',
+ header: 'optional',
+ desc: 'A react component that will be displayed above all the menu items. ' +
+ 'Usually, this is used for a logo or a profile image.'
+ },
+ {
+ name: 'openRight',
+ type: 'boole',
+ header: 'default: false',
+ desc: 'Positions the SideNav to open from the right side.'
+ },
+ {
+ name: 'style',
+ type: 'object',
+ header: 'optional',
+ desc: 'Override the inline-styles of SideNav\'s root element.'
+ }
+ ]
+ },
+ {
+ name: 'Methods',
+ infoArray: [
+ {
+ name: 'close',
+ header: 'SideNav.close()',
+ desc: 'Closes the component, hiding it from view.'
+ },
+ {
+ name: 'toggle',
+ header: 'SideNav.toggle()',
+ desc: 'Toggles between the open and closed states.'
+ }
+ ]
+ },
+ {
+ name: 'Events',
+ infoArray: [
+ {
+ name: 'onChange',
+ header: 'function(e, selectedIndex, menuItem)',
+ desc: 'Fired when a menu item is clicked that is not the one currently ' +
+ 'selected. Note that this requires the injectTapEventPlugin component. ' +
+ 'See the "Get Started" section for more detail.'
+ },
+ {
+ name: 'onNavOpen',
+ header: 'function()',
+ desc: 'Fired when the component is opened'
+ },
+ {
+ name: 'onNavClose',
+ header: 'function()',
+ desc: 'Fired when the component is closed'
+ }
+ ]
+ }
+ ];
+
+ const exampleFlatButtonIcon = {
+ height: '100%',
+ display: 'inline-block',
+ verticalAlign: 'middle',
+ float: 'left',
+ paddingLeft: '12px',
+ lineHeight: '36px',
+ color: Styles.Colors.cyan500
+ };
+ return (
+
+
+
+
+
+
+
+
+
+ HEADER {/*same as primaryText="HEADER"*/}
+
+
+
+
+
+
+ AWESOME SUBHEADER
+
+ } />
+ } />
+ }
+ primaryText="And" />
+
+ } />
+ } backgroundColor="#3f51b5"/>}/>
+
+
+ GitHub
+
+
+
+
+
+ material ui
+
+
+
+
+ Components
+
+
+
+ Resources
+
+
+
+
+
+
+
+
+ );
+ }
+
+ _showOverlaySideNavClick() {
+ this.refs.sideNav.toggle();
+ }
+
+ _toggleDockedSideNavClick() {
+ this.refs.dockedSideNav.toggle();
+ }
+
+}
+
+module.exports = SideNavPage;
diff --git a/src/index.js b/src/index.js
index c8783205d1c4c7..bc3f7aa872c74d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -41,6 +41,11 @@ module.exports = {
Ripples: require('./ripples/'),
SelectField: require('./select-field'),
Slider: require('./slider'),
+ SideNav: require('./side-nav/side-nav'),
+ SideNavDivider: require('./side-nav/side-nav-divider'),
+ SideNavItem: require('./side-nav/side-nav-item'),
+ SideNavHeader: require('./side-nav/side-nav-header'),
+ SideNavSubheader: require('./side-nav/side-nav-subheader'),
SvgIcon: require('./svg-icon'),
Icons: {
NavigationMenu: require('./svg-icons/navigation/menu'),
diff --git a/src/side-nav/index.js b/src/side-nav/index.js
new file mode 100644
index 00000000000000..cd4036e2bbff0b
--- /dev/null
+++ b/src/side-nav/index.js
@@ -0,0 +1,7 @@
+module.exports = {
+ SideNav: require('./side-nav'),
+ SideNavDivider: require('./side-nav-divider'),
+ SideNavItem: require('./side-nav-item'),
+ SideNavHeader: require('./side-nav-header'),
+ SideNavSubheader: require('./side-nav-subheader'),
+};
diff --git a/src/side-nav/side-nav-divider.jsx b/src/side-nav/side-nav-divider.jsx
new file mode 100644
index 00000000000000..22a9293ec63733
--- /dev/null
+++ b/src/side-nav/side-nav-divider.jsx
@@ -0,0 +1,29 @@
+let React = require('react/addons');
+let StylePropable = require('../mixins/style-propable');
+let MenuDivider = require('../menus/menu-divider');
+
+let SideNavDivider = React.createClass({
+
+ mixins: [StylePropable],
+
+ contextTypes: {
+ muiTheme: React.PropTypes.object,
+ },
+
+ render() {
+ let {
+ style,
+ ...other,
+ } = this.props;
+
+ let mergedStyles = this.mergeAndPrefix({
+ /*TODO*/
+ }, style);
+
+ return (
+
+ );
+ },
+});
+
+module.exports = SideNavDivider;
diff --git a/src/side-nav/side-nav-header.jsx b/src/side-nav/side-nav-header.jsx
new file mode 100644
index 00000000000000..3830b35855d91e
--- /dev/null
+++ b/src/side-nav/side-nav-header.jsx
@@ -0,0 +1,67 @@
+let React = require('react/addons');
+let StylePropable = require('../mixins/style-propable');
+let MenuItem = require('../lists/list-item');
+
+let SideNavHeader = React.createClass({
+
+ mixins: [StylePropable],
+
+ contextTypes: {
+ muiTheme: React.PropTypes.object,
+ },
+
+ propTypes: {
+ disabled: React.PropTypes.bool,
+ lineHeight: React.PropTypes.string,
+ innerDivStyle: React.PropTypes.object,
+ insetChildren: React.PropTypes.bool,
+ },
+
+ getTheme() {
+ if(this.context.muiTheme.component.sideNav)
+ return this.context.muiTheme.component.sideNav;
+ else
+ return {
+ headerItemBackgroundColor: '#2196f3',
+ headerItemTextColor: '#000000',
+ };
+ },
+
+ getDefaultProps() {
+ return {
+ disabled: true,
+ };
+ },
+
+ render() {
+ let {
+ disabled,
+ innerDivStyle,
+ style,
+ lineHeight,
+ ...other,
+ } = this.props;
+
+ let mergedStyles = this.mergeAndPrefix({
+ color: this.getTheme().headerItemTextColor,
+ backgroundColor: this.getTheme().headerItemBackgroundColor,
+ fontSize: '22px',
+ lineHeight: lineHeight? lineHeight : '32px',
+ }, style);
+
+ let mergedInnerDivStyles = this.mergeAndPrefix({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ }, mergedStyles, innerDivStyle);
+
+ return (
+
+ );
+ },
+});
+
+module.exports = SideNavHeader;
diff --git a/src/side-nav/side-nav-item.jsx b/src/side-nav/side-nav-item.jsx
new file mode 100644
index 00000000000000..350318d23d2a0f
--- /dev/null
+++ b/src/side-nav/side-nav-item.jsx
@@ -0,0 +1,68 @@
+let React = require('react/addons');
+let StylePropable = require('../mixins/style-propable');
+let MenuItem = require('../menus/menu-item');
+
+let SideNavItem = React.createClass({
+
+ mixins: [StylePropable],
+
+ contextTypes: {
+ muiTheme: React.PropTypes.object,
+ },
+
+ propTypes: {
+ disabled: React.PropTypes.bool,
+ active: React.PropTypes.bool,
+ innerDivStyle: React.PropTypes.object,
+ insetChildren: React.PropTypes.bool,
+ },
+
+ getTheme() {
+ if(this.context.muiTheme.component.sideNav)
+ return this.context.muiTheme.component.sideNav;
+ else
+ return {
+ navItemBackgroundColor: '#FFFFFF',
+ navItemTextColor: '#000000',
+ navItemActiveTextColor: '#e91e63',
+ };
+ },
+
+ getDefaultProps() {
+ return {
+ disabled: false,
+ active: false,
+ };
+ },
+
+ render() {
+ let {
+ disabled,
+ innerDivStyle,
+ style,
+ active,
+ ...other,
+ } = this.props;
+
+ let mergedStyles = this.mergeAndPrefix({
+ color: active? this.getTheme().navItemActiveTextColor: this.getTheme().navItemTextColor,
+ fontSize: '13px',
+ }, style);
+
+ let mergedInnerDivStyles = this.mergeAndPrefix({
+ display: 'flex',
+ alignItems: 'center',
+ }, mergedStyles, innerDivStyle);
+
+ return (
+
+ );
+ },
+});
+
+module.exports = SideNavItem;
diff --git a/src/side-nav/side-nav-subheader.jsx b/src/side-nav/side-nav-subheader.jsx
new file mode 100644
index 00000000000000..9f8d46c4853406
--- /dev/null
+++ b/src/side-nav/side-nav-subheader.jsx
@@ -0,0 +1,64 @@
+let React = require('react/addons');
+let StylePropable = require('../mixins/style-propable');
+let MenuItem = require('../lists/list-item');
+
+let SideNavSubheader = React.createClass({
+
+ mixins: [StylePropable],
+
+ contextTypes: {
+ muiTheme: React.PropTypes.object,
+ },
+
+ propTypes: {
+ disabled: React.PropTypes.bool,
+ lineHeight: React.PropTypes.string,
+ innerDivStyle: React.PropTypes.object,
+ insetChildren: React.PropTypes.bool,
+ },
+
+ getTheme() {
+ if(this.context.muiTheme.component.sideNav)
+ return this.context.muiTheme.component.sideNav;
+ else
+ return {
+ subheaderItemBackgroundColor: '#FFFFFF',
+ subheaderItemTextColor: '#000000',
+ };
+ },
+
+ getDefaultProps() {
+ return {
+ disabled: true,
+ };
+ },
+
+ render() {
+ let {
+ disabled,
+ innerDivStyle,
+ style,
+ ...other,
+ } = this.props;
+
+ let mergedStyles = this.mergeAndPrefix({
+ color: this.getTheme().subheaderItemTextColor,
+ backgroundColor: this.getTheme().subheaderItemBackgroundColor,
+ fontSize: '13px',
+ fontWeight: 'bold',
+ }, style);
+
+ let mergedInnerDivStyles = this.mergeAndPrefix({
+ display: 'flex',
+ alignItems: 'center',
+ }, mergedStyles, innerDivStyle);
+
+ return (
+
+ );
+ },
+});
+
+module.exports = SideNavSubheader;
diff --git a/src/side-nav/side-nav.jsx b/src/side-nav/side-nav.jsx
new file mode 100644
index 00000000000000..5a362dad1cb763
--- /dev/null
+++ b/src/side-nav/side-nav.jsx
@@ -0,0 +1,370 @@
+import React from 'react';
+import { AutoPrefix, Transitions } from '../styles';
+import Overlay from '../overlay';
+import Menu from '../menus/menu';
+import Paper from '../paper';
+import KeyCode from '../utils/key-code';
+import StylePropable from '../mixins/style-propable';
+import WindowListenable from '../mixins/window-listenable';
+
+let openNavEventHandler = null;
+
+let SideNav = React.createClass({
+
+ mixins: [StylePropable, WindowListenable],
+
+ contextTypes: {
+ muiTheme: React.PropTypes.object,
+ },
+
+ propTypes: {
+ className: React.PropTypes.string,
+ /*open type currently supports: docked/overlay */
+ openType: React.PropTypes.oneOf([
+ 'none',
+ 'docked',
+ 'overlay',
+ ]),
+ defaultOpen: React.PropTypes.bool,
+ header: React.PropTypes.element,
+ onChange: React.PropTypes.func,
+ onNavOpen: React.PropTypes.func,
+ onNavClose: React.PropTypes.func,
+ openRight: React.PropTypes.bool,
+ menuStyle: React.PropTypes.object,
+ listStyle: React.PropTypes.object,
+ disableSwipeToOpen: React.PropTypes.bool,
+ },
+
+ windowListeners: {
+ 'keyup': '_onWindowKeyUp',
+ 'resize': '_onWindowResize',
+ },
+
+ getDefaultProps() {
+ return {
+ openType:'docked',
+ defaultOpen: false,
+ disableSwipeToOpen: false,
+ zDepth: 0,
+ };
+ },
+
+ getInitialState() {
+ this._maybeSwiping = false;
+ this._touchStartX = null;
+ this._touchStartY = null;
+ this._swipeStartX = null;
+
+ return {
+ open: this.props.defaultOpen,
+ swiping: null,
+ };
+ },
+
+ componentDidMount() {
+ this._updateMenuHeight();
+ this._enableSwipeHandling();
+ },
+
+ componentDidUpdate() {
+ this._updateMenuHeight();
+ this._enableSwipeHandling();
+ },
+
+ componentWillUnmount() {
+ this._disableSwipeHandling();
+ },
+
+ toggle() {
+ this.setState({ open: !this.state.open });
+ return this;
+ },
+
+ close() {
+ this.setState({ open: false });
+ if (this.props.onNavClose) this.props.onNavClose();
+ return this;
+ },
+
+ open() {
+ this.setState({ open: true });
+ if (this.props.onNavOpen) this.props.onNavOpen();
+ return this;
+ },
+
+ getThemePalette() {
+ return this.context.muiTheme.palette;
+ },
+
+ getTheme() {
+ if(this.context.muiTheme.component.sideNav)
+ return this.context.muiTheme.component.sideNav;
+ else
+ return {
+ width: 256,
+ backgroundColor: '#FFFFFF',
+ };
+ },
+
+ getStyles() {
+ let x = this._getTranslateMultiplier() * (this.state.open ? 0 : this._getMaxTranslateX());
+ let styles = {
+ root: {
+ height: '100%',
+ width: this.props.width? this.props.width : this.getTheme().width,
+ backgroundColor: this.props.backgroundColor? this.props.backgroundColor : this.getTheme().backgroundColor,
+ position: 'fixed',
+ zIndex: 10,
+ left: 0,
+ top: 0,
+ transform: 'translate3d(' + x + 'px, 0, 0)',
+ transition: !this.state.swiping && Transitions.easeOut(),
+ overflow: 'hidden',
+ },
+ menu: {
+ backgroundColor: this.props.backgroundColor? this.props.backgroundColor : this.getTheme().backgroundColor,
+ overflowY: 'auto',
+ overflowX: 'hidden',
+ height: '100%',
+ width: this.props.width? this.props.width : this.getTheme().width,
+ borderRadius: '0',
+ },
+ list: {
+ width: this.props.width? this.props.width : this.getTheme().width,
+ paddingTop: 0,
+ },
+ rootWhenOpenRight: {
+ left: 'auto',
+ right: 0,
+ },
+ };
+
+ return styles;
+ },
+
+ render() {
+ let overlay;
+
+ let {
+ className,
+ openType,
+ defaultOpen,
+ header,
+ onChange,
+ onNavOpen,
+ onNavClose,
+ openRight,
+ disableSwipeToOpen,
+ style,
+ listStyle,
+ menuStyle,
+ zDepth,
+ ...other,
+ } = this.props;
+
+ let styles = this.getStyles();
+ if (openType==='overlay') {
+ overlay = (
+
+ );
+ }
+
+ return (
+
+ {overlay}
+
+ {header}
+
+
+
+ );
+ },
+
+ _updateMenuHeight() {
+ if (this.props.header) {
+ let container = React.findDOMNode(this.refs.container);
+ let menu = React.findDOMNode(this.refs.menu);
+ let menuHeight = container.clientHeight - menu.offsetTop;
+ menu.style.height = menuHeight + 'px';
+ }
+ },
+
+ _onMenuItemClick(e, item) {
+ if (this.props.onChange) {
+ this.props.onChange(e, item);
+ }
+ if (this.props.openType==='overlay') this.close();
+ },
+
+ _onOverlayTouchTap() {
+ this.close();
+ },
+
+ _onWindowKeyUp(e) {
+ if (e.keyCode === KeyCode.ESC &&
+ (this.props.openType==='overlay') &&
+ this.state.open) {
+ this.close();
+ }
+ },
+
+ _onWindowResize() {
+ this._updateMenuHeight();
+ },
+
+ _getMaxTranslateX() {
+ return this.getTheme().width + 10;
+ },
+
+ _getTranslateMultiplier() {
+ return this.props.openRight ? 1 : -1;
+ },
+
+ _enableSwipeHandling() {
+ if (this.props.openType==='overlay') {
+ document.body.addEventListener('touchstart', this._onBodyTouchStart);
+ if (!openNavEventHandler) {
+ openNavEventHandler = this._onBodyTouchStart;
+ }
+ } else {
+ this._disableSwipeHandling();
+ }
+ },
+
+ _disableSwipeHandling() {
+ document.body.removeEventListener('touchstart', this._onBodyTouchStart);
+ if (openNavEventHandler === this._onBodyTouchStart) {
+ openNavEventHandler = null;
+ }
+ },
+
+ _onBodyTouchStart(e) {
+ if (!this.state.open && openNavEventHandler !== this._onBodyTouchStart) {
+ return;
+ }
+
+ let touchStartX = e.touches[0].pageX;
+ let touchStartY = e.touches[0].pageY;
+
+ this._maybeSwiping = true;
+ this._touchStartX = touchStartX;
+ this._touchStartY = touchStartY;
+
+ document.body.addEventListener('touchmove', this._onBodyTouchMove);
+ document.body.addEventListener('touchend', this._onBodyTouchEnd);
+ document.body.addEventListener('touchcancel', this._onBodyTouchEnd);
+ },
+
+ _setPosition(translateX) {
+ let leftNav = React.findDOMNode(this.refs.container);
+ leftNav.style[AutoPrefix.single('transform')] =
+ 'translate3d(' + (this._getTranslateMultiplier() * translateX) + 'px, 0, 0)';
+ this.refs.overlay.setOpacity(1 - translateX / this._getMaxTranslateX());
+ },
+
+ _getTranslateX(currentX) {
+ return Math.min(
+ Math.max(
+ this.state.swiping === 'closing' ?
+ this._getTranslateMultiplier() * (currentX - this._swipeStartX) :
+ this._getMaxTranslateX() - this._getTranslateMultiplier() * (this._swipeStartX - currentX),
+ 0
+ ),
+ this._getMaxTranslateX()
+ );
+ },
+
+ _onBodyTouchMove(e) {
+ let currentX = e.touches[0].pageX;
+ let currentY = e.touches[0].pageY;
+
+ if (this.state.swiping) {
+ e.preventDefault();
+ this._setPosition(this._getTranslateX(currentX));
+ }
+ else if (this._maybeSwiping) {
+ let dXAbs = Math.abs(currentX - this._touchStartX);
+ let dYAbs = Math.abs(currentY - this._touchStartY);
+ // If the user has moved his thumb ten pixels in either direction,
+ // we can safely make an assumption about whether he was intending
+ // to swipe or scroll.
+ let threshold = 10;
+
+ if (dXAbs > threshold && dYAbs <= threshold) {
+ this._swipeStartX = currentX;
+ this.setState({
+ swiping: this.state.open ? 'closing' : 'opening',
+ });
+ this._setPosition(this._getTranslateX(currentX));
+ }
+ else if (dXAbs <= threshold && dYAbs > threshold) {
+ this._onBodyTouchEnd();
+ }
+ }
+ },
+
+ _onBodyTouchEnd(e) {
+ if (this.state.swiping) {
+ let currentX = e.changedTouches[0].pageX;
+ let translateRatio = this._getTranslateX(currentX) / this._getMaxTranslateX();
+
+ this._maybeSwiping = false;
+ let swiping = this.state.swiping;
+ this.setState({
+ swiping: null,
+ });
+
+ // We have to open or close after setting swiping to null,
+ // because only then CSS transition is enabled.
+ if (translateRatio > 0.5) {
+ if (swiping === 'opening') {
+ this._setPosition(this._getMaxTranslateX());
+ } else {
+ this.close();
+ }
+ }
+ else {
+ if (swiping === 'opening') {
+ this.open();
+ } else {
+ this._setPosition(0);
+ }
+ }
+ }
+ else {
+ this._maybeSwiping = false;
+ }
+
+ document.body.removeEventListener('touchmove', this._onBodyTouchMove);
+ document.body.removeEventListener('touchend', this._onBodyTouchEnd);
+ document.body.removeEventListener('touchcancel', this._onBodyTouchEnd);
+ },
+
+});
+
+
+export default SideNav;
diff --git a/src/styles/themes/light-theme.js b/src/styles/themes/light-theme.js
index 614c297d4b6202..cb8ceb9247baba 100644
--- a/src/styles/themes/light-theme.js
+++ b/src/styles/themes/light-theme.js
@@ -137,6 +137,16 @@ let LightTheme = {
selectionColor: palette.primary3Color,
rippleColor: palette.primary1Color,
},
+ sideNav: {
+ width: spacing.desktopKeylineIncrement * 4,
+ backgroundColor: Colors.white,
+ headerItemBackgroundColor: palette.primary1Color,
+ headerItemTextColor: Colors.white,
+ subheaderItemTextColor: palette.primary2Color,
+ subheaderItemBackgroundColor: Colors.white,
+ navItemTextColor: Colors.black,
+ navItemActiveTextColor: palette.accent1Color,
+ },
snackbar: {
textColor: Colors.white,
backgroundColor: '#323232',