Yuki Takei 6 лет назад
Родитель
Сommit
25b4c81d80

+ 3 - 0
src/client/js/bootstrap.jsx

@@ -4,6 +4,7 @@ import loggerFactory from '@alias/logger';
 import Xss from '@commons/service/xss';
 
 import HeaderSearchBox from './components/HeaderSearchBox';
+import NavbarToggler from './components/Navbar/NavbarToggler';
 import PersonalDropdown from './components/Navbar/PersonalDropdown';
 import Sidebar from './components/Sidebar';
 import StaffCredit from './components/StaffCredit/StaffCredit';
@@ -37,6 +38,8 @@ appContainer.injectToWindow();
  *  value: React Element
  */
 const componentMappings = {
+  'grw-navbar-toggler': <NavbarToggler />,
+
   'search-top': <HeaderSearchBox />,
   'search-sidebar': <HeaderSearchBox crowi={appContainer} />,
   'personal-dropdown': <PersonalDropdown />,

+ 33 - 0
src/client/js/components/Navbar/NavbarToggler.jsx

@@ -0,0 +1,33 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { withTranslation } from 'react-i18next';
+
+import { createSubscribedElement } from '../UnstatedUtils';
+import AppContainer from '../../services/AppContainer';
+
+const NavbarToggler = (props) => {
+  const { appContainer } = props;
+
+  return (
+    <button className="navbar-toggler grw-navbar-toggler border-0" type="button" aria-expanded="false" aria-label="Toggle navigation">
+      <i className="icon-menu"></i>
+    </button>
+  );
+
+};
+
+/**
+ * Wrapper component for using unstated
+ */
+const NavbarTogglerWrapper = (props) => {
+  return createSubscribedElement(NavbarToggler, props, [AppContainer]);
+};
+
+
+NavbarToggler.propTypes = {
+  t: PropTypes.func.isRequired, //  i18next
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+};
+
+export default withTranslation()(NavbarTogglerWrapper);

+ 5 - 0
src/client/styles/scss/_navbar.scss

@@ -1,4 +1,9 @@
 .grw-navbar {
+  .grw-navbar-toggler {
+    padding: 0.5rem;
+    font-size: 1.5em;
+  }
+
   .nav-link,
   .nav-item.confidential {
     display: flex;

+ 8 - 6
src/server/views/layout/layout.html

@@ -74,25 +74,27 @@
 <div id="wrapper">
 
   {% block layout_head_nav %}
-  <nav class="navbar grw-navbar navbar-expand navbar-dark fixed-top mb-0 p-0">
+  <nav class="navbar grw-navbar navbar-expand-sm navbar-dark fixed-top mb-0 p-sm-0">
+    <div id="grw-navbar-toggler" class="d-sm-none mr-auto"></div>
+
     {# Brand Logo #}
-    <div class="navbar-brand">
+    <div class="navbar-brand mr-sm-auto">
       <a class="grw-logo d-block" href="/">
         {% include '../widget/logo.html' %}
       </a>
     </div>
 
-    {# Navbar Left #}
-    <ul class="navbar-nav ml-auto mr-auto">
+    {# Navbar Center #}
+    <ul class="navbar-nav d-none d-md-block">
       <li>
         {% if isSearchServiceConfigured() %}
-        <div class="navbar-form navbar-left search-top" role="search" id="search-top"></div>
+        <div class="search-top" role="search" id="search-top"></div>
         {% endif %}
       </li>
     </ul>
 
     {# Navbar Right #}
-    <ul class="navbar-nav">
+    <ul class="navbar-nav ml-auto">
       {% if user and user.admin %}
       <li class="nav-item d-none d-md-block">
         <a class="nav-link" href="/admin">