Просмотр исходного кода

Merge pull request #1539 from weseek/support/apply-bootstrap4-export-page

Support/apply bootstrap4 import page (mistake branch name export -> import)
itizawa 6 лет назад
Родитель
Сommit
716aec9ce3

+ 7 - 7
src/client/js/components/Admin/ImportData/GrowiArchive/ErrorViewer.jsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
-import Modal from 'react-bootstrap/es/Modal';
+import { Modal, ModalHeader, ModalBody } from 'reactstrap';
 
 import { createSubscribedElement } from '../../../UnstatedUtils';
 
@@ -20,13 +20,13 @@ class ErrorViewer extends React.Component {
     }
 
     return (
-      <Modal show={this.props.isOpen} onHide={this.props.onClose}>
-        <Modal.Header closeButton className="bg-danger">
-          <Modal.Title className="text-white">Errors</Modal.Title>
-        </Modal.Header>
-        <Modal.Body>
+      <Modal isOpen={this.props.isOpen} toggle={this.props.onClose}>
+        <ModalHeader toggle={this.props.onClose} className="bg-danger text-white">
+          Errors
+        </ModalHeader>
+        <ModalBody>
           <textarea className="form-control" rows="8" readOnly wrap="off" defaultValue={value}></textarea>
-        </Modal.Body>
+        </ModalBody>
       </Modal>
     );
   }

+ 15 - 10
src/client/js/components/Admin/ImportData/GrowiArchive/ImportCollectionConfigurationModal.jsx

@@ -3,7 +3,12 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
-import { Modal } from 'reactstrap';
+import {
+  Modal,
+  ModalHeader,
+  ModalBody,
+  ModalFooter,
+} from 'reactstrap';
 
 import GrowiArchiveImportOption from '@commons/models/admin/growi-archive-import-option';
 
@@ -188,19 +193,19 @@ class ImportCollectionConfigurationModal extends React.Component {
     }
 
     return (
-      <Modal show={this.props.isOpen} onHide={this.props.onClose} onEnter={this.initialize}>
-        <Modal.Header closeButton>
-          <Modal.Title>{`'${collectionName}'`} Configuration</Modal.Title>
-        </Modal.Header>
+      <Modal isOpen={this.props.isOpen} toggle={this.props.onClose} onEnter={this.initialize}>
+        <ModalHeader toggle={this.props.onClose}>
+          {`'${collectionName}'`} Configuration
+        </ModalHeader>
 
-        <Modal.Body>
+        <ModalBody>
           {contents}
-        </Modal.Body>
+        </ModalBody>
 
-        <Modal.Footer>
-          <button type="button" className="btn btn-sm btn-default" onClick={this.props.onClose}>{t('Cancel')}</button>
+        <ModalFooter>
+          <button type="button" className="btn btn-sm btn-light" onClick={this.props.onClose}>{t('Cancel')}</button>
           <button type="button" className="btn btn-sm btn-primary" onClick={this.updateOption}>{t('Update')}</button>
-        </Modal.Footer>
+        </ModalFooter>
       </Modal>
     );
   }

+ 17 - 17
src/client/js/components/Admin/ImportData/GrowiArchive/ImportCollectionItem.jsx

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
 // eslint-disable-next-line no-unused-vars
 import { withTranslation } from 'react-i18next';
 
-import ProgressBar from 'react-bootstrap/es/ProgressBar';
+import { Progress } from 'reactstrap';
 
 import GrowiArchiveImportOption from '@commons/models/admin/growi-archive-import-option';
 
@@ -74,7 +74,7 @@ export default class ImportCollectionItem extends React.Component {
   renderModeLabel(mode, isColorized = false) {
     const attrMap = MODE_ATTR_MAP[mode];
     const className = isColorized ? `text-${attrMap.color}` : '';
-    return <span className={className}><i className={attrMap.icon}></i> {attrMap.label}</span>;
+    return <span className={`text-nowrap ${className}`}><i className={attrMap.icon}></i> {attrMap.label}</span>;
   }
 
   renderCheckbox() {
@@ -116,7 +116,7 @@ export default class ImportCollectionItem extends React.Component {
         Mode:&nbsp;
         <div className="dropdown d-inline-block">
           <button
-            className={`btn ${btnColor} btn-xs dropdown-toggle`}
+            className={`btn ${btnColor} btn-sm dropdown-toggle`}
             type="button"
             id="ddmMode"
             disabled={isImporting}
@@ -149,7 +149,7 @@ export default class ImportCollectionItem extends React.Component {
     return (
       <button
         type="button"
-        className="btn btn-default btn-xs ml-2"
+        className="btn btn-light btn-sm p-1 ml-2"
         disabled={isImporting || !isConfigButtonAvailable}
         onClick={isConfigButtonAvailable ? this.configButtonClickedHandler : null}
       >
@@ -166,11 +166,11 @@ export default class ImportCollectionItem extends React.Component {
     const total = insertedCount + modifiedCount + errorsCount;
 
     return (
-      <ProgressBar className="mb-0">
-        <ProgressBar max={total} striped={isImporting} active={isImporting} now={insertedCount} bsStyle="info" />
-        <ProgressBar max={total} striped={isImporting} active={isImporting} now={modifiedCount} bsStyle="success" />
-        <ProgressBar max={total} striped={isImporting} active={isImporting} now={errorsCount} bsStyle="danger" />
-      </ProgressBar>
+      <Progress multi className="mb-0">
+        <Progress bar max={total} color="info" striped={isImporting} animated={isImporting} value={insertedCount} />
+        <Progress bar max={total} color="success" striped={isImporting} animated={isImporting} value={modifiedCount} />
+        <Progress bar max={total} color="danger" striped={isImporting} animated={isImporting} value={errorsCount} />
+      </Progress>
     );
   }
 
@@ -201,11 +201,13 @@ export default class ImportCollectionItem extends React.Component {
     } = this.props;
 
     return (
-      <div className="panel panel-default">
-        <div className="panel-heading">
+      <div className="card border-light">
+        <div className="card-header bg-light">
           <div className="d-flex justify-content-between align-items-center">
             {/* left */}
-            {this.renderCheckbox()}
+            <div className="pl-4">
+              {this.renderCheckbox()}
+            </div>
             {/* right */}
             <span className="d-flex align-items-center">
               {this.renderModeSelector()}
@@ -213,14 +215,12 @@ export default class ImportCollectionItem extends React.Component {
             </span>
           </div>
         </div>
-        { isSelected && (
+        {isSelected && (
           <>
             {this.renderProgressBar()}
-            <div className="panel-body">
-              {this.renderBody()}
-            </div>
+            <div className="card-body">{this.renderBody()}</div>
           </>
-        ) }
+        )}
       </div>
     );
   }

+ 25 - 23
src/client/js/components/Admin/ImportData/GrowiArchive/ImportForm.jsx

@@ -343,17 +343,19 @@ class ImportForm extends React.Component {
     }
 
     return (
-      <div className="mt-4">
-        <legend>{groupName} Collections</legend>
-        { wellContent != null && (
-          <div className="well well-sm small">
-            <ul>
-              <li>{wellContent}</li>
-            </ul>
-          </div>
-        ) }
-        { this.renderImportItems(collectionNames) }
-        { this.renderWarnForGroups(errors, `warnFor${groupName}`) }
+      <div className="mt-4 row">
+        <div className="col-12">
+          <legend>{groupName} Collections</legend>
+          { wellContent != null && (
+            <div className="card well small" role="alert">
+              <ul>
+                <li>{wellContent}</li>
+              </ul>
+            </div>
+          )}
+          {this.renderImportItems(collectionNames)}
+          {this.renderWarnForGroups(errors, `warnFor${groupName}`)}
+        </div>
       </div>
     );
   }
@@ -385,7 +387,7 @@ class ImportForm extends React.Component {
           const isConfigButtonAvailable = Object.keys(IMPORT_OPTION_CLASS_MAPPING).includes(collectionName);
 
           return (
-            <div className="col-xs-6 my-1" key={collectionName}>
+            <div className="col-6 my-1" key={collectionName}>
               <ImportCollectionItem
                 isImporting={isImporting}
                 isImported={collectionProgress ? isImported : false}
@@ -453,33 +455,33 @@ class ImportForm extends React.Component {
       <>
         <form className="form-inline">
           <div className="form-group">
-            <button type="button" className="btn btn-sm btn-default mr-2" onClick={this.checkAll}>
+            <button type="button" className="btn btn-sm btn-light mr-2" onClick={this.checkAll}>
               <i className="fa fa-check-square-o"></i> {t('export_management.check_all')}
             </button>
           </div>
           <div className="form-group">
-            <button type="button" className="btn btn-sm btn-default mr-2" onClick={this.uncheckAll}>
+            <button type="button" className="btn btn-sm btn-light mr-2" onClick={this.uncheckAll}>
               <i className="fa fa-square-o"></i> {t('export_management.uncheck_all')}
             </button>
           </div>
         </form>
 
-        { this.renderGroups(GROUPS_PAGE, 'Page', warnForPageGroups, { wellContent: t('importer_management.growi_settings.overwrite_documents') }) }
-        { this.renderGroups(GROUPS_USER, 'User', warnForUserGroups) }
-        { this.renderGroups(GROUPS_CONFIG, 'Config', warnForConfigGroups) }
-        { this.renderOthers() }
+        {this.renderGroups(GROUPS_PAGE, 'Page', warnForPageGroups, { wellContent: t('importer_management.growi_settings.overwrite_documents') })}
+        {this.renderGroups(GROUPS_USER, 'User', warnForUserGroups)}
+        {this.renderGroups(GROUPS_CONFIG, 'Config', warnForConfigGroups)}
+        {this.renderOthers()}
 
         <div className="mt-4 text-center">
-          <button type="button" className="btn btn-default mx-1" onClick={this.props.onDiscard}>
-            { t('importer_management.growi_settings.discard') }
+          <button type="button" className="btn btn-light mx-1" onClick={this.props.onDiscard}>
+            {t('importer_management.growi_settings.discard')}
           </button>
           <button type="button" className="btn btn-primary mx-1" onClick={this.import} disabled={!canImport || isImporting}>
-            { t('importer_management.import') }
+            {t('importer_management.import')}
           </button>
         </div>
 
-        { this.renderConfigurationModal() }
-        { this.renderErrorsViewer() }
+        {this.renderConfigurationModal()}
+        {this.renderErrorsViewer()}
       </>
     );
   }

+ 6 - 6
src/client/js/components/Admin/ImportData/GrowiArchive/UploadForm.jsx

@@ -48,11 +48,11 @@ class UploadForm extends React.Component {
     const { t } = this.props;
 
     return (
-      <form className="form-horizontal" onSubmit={this.uploadZipFile}>
+      <form onSubmit={this.uploadZipFile}>
         <fieldset>
-          <div className="form-group">
-            <label htmlFor="file" className="col-xs-3 control-label">{t('importer_management.growi_settings.growi_archive_file')}</label>
-            <div className="col-xs-6">
+          <div className="form-group row">
+            <label htmlFor="file" className="col-3 control-label">{t('importer_management.growi_settings.growi_archive_file')}</label>
+            <div className="col-6">
               <input
                 type="file"
                 name="file"
@@ -63,8 +63,8 @@ class UploadForm extends React.Component {
               />
             </div>
           </div>
-          <div className="form-group">
-            <div className="col-xs-offset-3 col-xs-6">
+          <div className="form-group row">
+            <div className="offset-3 col-6">
               <button type="submit" className="btn btn-primary" disabled={!this.validateForm()}>
                 {t('importer_management.growi_settings.upload')}
               </button>

+ 26 - 26
src/client/js/components/Admin/ImportDataPage.jsx

@@ -138,7 +138,7 @@ class ImportDataPage extends React.Component {
         <GrowiArchiveSection />
 
         <form
-          className="form-horizontal mt-5"
+          className="mt-5"
           id="importerSettingFormEsa"
           role="form"
         >
@@ -171,37 +171,37 @@ class ImportDataPage extends React.Component {
               </tbody>
             </table>
 
-            <div className="well well-sm mb-0 small">
+            <div className="card well mb-0 small">
               <ul>
                 <li>{ t('importer_management.page_skip') }</li>
               </ul>
             </div>
 
-            <div className="form-group">
+            <div className="form-group row">
               <input type="password" name="dummypass" style={{ display: 'none', top: '-100px', left: '-100px' }} />
             </div>
 
-            <div className="form-group">
-              <label htmlFor="settingForm[importer:esa:team_name]" className="col-xs-3 control-label">
+            <div className="form-group row">
+              <label htmlFor="settingForm[importer:esa:team_name]" className="col-3 col-form-label">
                 { t('importer_management.esa_settings.team_name') }
               </label>
-              <div className="col-xs-6">
+              <div className="col-6">
                 <input className="form-control" type="text" name="esaTeamName" value={esaTeamName} onChange={this.handleInputValue} />
               </div>
 
             </div>
 
-            <div className="form-group">
-              <label htmlFor="settingForm[importer:esa:access_token]" className="col-xs-3 control-label">
+            <div className="form-group row">
+              <label htmlFor="settingForm[importer:esa:access_token]" className="col-3 col-form-label">
                 { t('importer_management.esa_settings.access_token') }
               </label>
-              <div className="col-xs-6">
+              <div className="col-6">
                 <input className="form-control" type="password" name="esaAccessToken" value={esaAccessToken} onChange={this.handleInputValue} />
               </div>
             </div>
 
-            <div className="form-group">
-              <div className="col-xs-offset-3 col-xs-6">
+            <div className="form-group row">
+              <div className="offset-3 col-6">
                 <input
                   id="testConnectionToEsa"
                   type="button"
@@ -211,12 +211,12 @@ class ImportDataPage extends React.Component {
                   value={t('importer_management.import')}
                 />
                 <input type="button" className="btn btn-secondary" onClick={this.esaHandleSubmitUpdate} value={t('Update')} />
-                <span className="col-xs-offset-1">
+                <span className="offset-1">
                   <input
                     name="Esa"
                     type="button"
                     id="importFromEsa"
-                    className="btn btn-default btn-esa"
+                    className="btn btn-light btn-esa"
                     onClick={this.esaHandleSubmitTest}
                     value={t('importer_management.esa_settings.test_connection')}
                   />
@@ -228,7 +228,7 @@ class ImportDataPage extends React.Component {
         </form>
 
         <form
-          className="form-horizontal mt-5"
+          className="mt-5"
           id="importerSettingFormQiita"
           role="form"
         >
@@ -265,36 +265,36 @@ class ImportDataPage extends React.Component {
                 </tr>
               </tbody>
             </table>
-            <div className="well well-sm mb-0 small">
+            <div className="card well mb-0 small">
               <ul>
                 <li>{ t('importer_management.page_skip') }</li>
               </ul>
             </div>
 
-            <div className="form-group">
+            <div className="form-group row">
               <input type="password" name="dummypass" style={{ display: 'none', top: '-100px', left: '-100px' }} />
             </div>
-            <div className="form-group">
-              <label htmlFor="settingForm[importer:qiita:team_name]" className="col-xs-3 control-label">
+            <div className="form-group row">
+              <label htmlFor="settingForm[importer:qiita:team_name]" className="col-3 col-form-label">
                 { t('importer_management.qiita_settings.team_name') }
               </label>
-              <div className="col-xs-6">
+              <div className="col-6">
                 <input className="form-control" type="text" name="qiitaTeamName" value={qiitaTeamName} onChange={this.handleInputValue} />
               </div>
             </div>
 
-            <div className="form-group">
-              <label htmlFor="settingForm[importer:qiita:access_token]" className="col-xs-3 control-label">
+            <div className="form-group row">
+              <label htmlFor="settingForm[importer:qiita:access_token]" className="col-3 col-form-label">
                 { t('importer_management.qiita_settings.access_token') }
               </label>
-              <div className="col-xs-6">
+              <div className="col-6">
                 <input className="form-control" type="password" name="qiitaAccessToken" value={qiitaAccessToken} onChange={this.handleInputValue} />
               </div>
             </div>
 
 
-            <div className="form-group">
-              <div className="col-xs-offset-3 col-xs-6">
+            <div className="form-group row">
+              <div className="offset-3 col-6">
                 <input
                   id="testConnectionToQiita"
                   type="button"
@@ -304,12 +304,12 @@ class ImportDataPage extends React.Component {
                   value={t('importer_management.import')}
                 />
                 <input type="button" className="btn btn-secondary" onClick={this.qiitaHandleSubmitUpdate} value={t('Update')} />
-                <span className="col-xs-offset-1">
+                <span className="offset-1">
                   <input
                     name="Qiita"
                     type="button"
                     id="importFromQiita"
-                    className="btn btn-default btn-qiita"
+                    className="btn btn-light btn-qiita"
                     onClick={this.qiitaHandleSubmitTest}
                     value={t('importer_management.qiita_settings.test_connection')}
                   />

+ 1 - 1
src/client/js/components/PageEditor/HandsontableModal.jsx

@@ -437,7 +437,7 @@ export default class HandsontableModal extends React.PureComponent {
         <ModalHeader toggle={this.cancel} close={buttons}>Edit Table</ModalHeader>
         <ModalBody className="p-0 d-flex flex-column">
           <div className="px-4 py-3 modal-navbar bg-light">
-            <Button className="mr-4 data-import-button" onClick={this.toggleDataImportArea}>
+            <Button className="mr-4 data-import-button bg-light" onClick={this.toggleDataImportArea}>
               <span className="mr-3">Data Import</span><i className={this.state.isDataImportAreaExpanded ? 'fa fa-angle-up' : 'fa fa-angle-down'}></i>
 
             </Button>

+ 0 - 1
src/client/styles/scss/_handsontable.scss

@@ -43,7 +43,6 @@
 
   .data-import-form {
     color: $headingtext;
-    background-color: $navbar-default-bg;
 
     .btn + .btn {
       margin-left: 5px;

+ 50 - 5
src/client/styles/scss/_override-bootstrap-variables.scss

@@ -4,6 +4,14 @@
 
 //== Colors
 //
+$primary: #112744;
+$secondary: #6c757d;
+$info: #0d8ea5;
+$success: #00bb83;
+$warning: #ee773b;
+$danger: #ff0a54;
+$light: #dee2e6;
+$dark: #343a40;
 //## Gray and brand colors for use across Bootstrap.
 $gray-base:              #000 !default;
 $gray-darker:            lighten($gray-base, 13.5%); // #222
@@ -19,17 +27,16 @@ $brand-info:            $info;
 $brand-warning:         $warning;
 $brand-danger:          $danger;
 
-
-
 //== Typography
 //
 //## Font, line-height, and color for body text, headings, and more.
 $font-family-sans-serif:  Lato, -apple-system, BlinkMacSystemFont, 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif;
 $font-family-serif:       Georgia, "Times New Roman", Times, serif;
-$font-family-monospace:   SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;
+$font-family-monospace: Osaka-Mono, 'MS Gothic', Monaco, Menlo, Consolas, 'Courier New', monospace;
 $font-family-base:        $font-family-sans-serif;
 
-
+$font-size-root: 14px;
+$line-height-base: 1.42857;
 
 //== Components
 //
@@ -44,13 +51,45 @@ $border-radius-small: 0;
 //## For each of Bootstrap's buttons, define text, background and border color.
 
 $btn-default-bg: $btn-default-bgcolor;
+$btn-border-radius: 0;
+$btn-border-radius-lg: 0;
+$btn-border-radius-sm: 0;
 
 
 
 //== Forms
 //
-//##
+$input-border-radius: 0;
+$input-border-radius-lg: 0;
+$input-border-radius-sm: 0;
+
+//== Navs
+
+$nav-link-padding-y: 0.75rem;
+$nav-link-padding-x: 1rem;
+$nav-tabs-border-radius: 0;
 
+//== Navbar
+$navbar-padding-y: 0;
+$navbar-brand-padding-y: 0;
+$navbar-nav-link-padding-x: 1rem;
+
+//== Dropdowns
+$dropdown-border-radius: 0;
+
+//== card
+$card-border-radius: 0;
+$card-spacer-y: 7px;
+$card-spacer-x: 15px;
+
+//== Modals
+$modal-content-border-width: 0;
+$modal-content-border-radius: 0;
+$modal-header-padding-y: 0.75rem;
+$modal-header-padding-x: 1rem;
+
+//== Alerts
+$alert-border-radius: 0;
 //** `<input>` background color
 $input-bg:                       $bodycolor;
 //** `<input disabled>` background color
@@ -58,3 +97,9 @@ $input-bg-disabled:              $btn-default-bgcolor;
 
 //** `<input>` border color
 $input-border:                   $border;
+
+//== Progress bar
+$progress-height: 4px;
+$progress-border-radius: 0;
+$progress-bg: #f0f0f0;
+$progress-box-shadow: none;

+ 115 - 0
src/client/styles/scss/_override-bootstrap.scss

@@ -13,6 +13,29 @@
   }
 }
 
+// card (substitute panel of bootstrap3)
+.card {
+  margin-bottom: 20px;
+  border-radius: $card-border-radius;
+}
+
+.card-header {
+  font-weight: 700;
+  text-transform: none;
+  border-radius: $card-border-radius;
+}
+
+.card-header:first-child {
+  border-radius: $card-border-radius;
+}
+
+// Well (substitute Well of bootstrap3)
+.card.well {
+  min-height: 20px;
+  padding: $card-spacer-y $card-spacer-x;
+  border-radius: 3px;
+}
+
 // Dropdowns
 .dropdown {
   .dropdown-toggle.btn.disabled {
@@ -20,7 +43,99 @@
   }
 }
 
+// agile-admin style
+.dropdown-menu {
+  padding-bottom: 8px;
+  margin-top: 0px;
+  border: 1px solid $border;
+  border-radius: $radius;
+  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.05) !important;
+}
+
+.dropdown-menu > li > a {
+  width: 100%;
+  padding: 9px 20px;
+}
+
+.dropdown-menu > li > a:focus,
+.dropdown-menu > li > a:hover {
+  background: $extralight;
+}
+
+// btn-light (substitute for btn-default of bootstrap3)  (agile-admin style)
+.btn-light,
+.btn-light.disabled {
+  color: $bodytext;
+  $this-color: $btn-default-bgcolor;
+  background: $this-color;
+  border: 1px solid $this-color;
+
+  &:hover,
+  &:focus,
+  &.focus {
+    color: $bodytext;
+    background: $this-color;
+    border: 1px solid $this-color;
+    opacity: 0.8;
+  }
+
+  &:active &.active {
+    box-shadow: none;
+  }
+}
+
+.btn-light.btn-outline {
+  background-color: transparent;
+
+  &:hover,
+  &:focus,
+  &.focus {
+    background: $btn-default-bgcolor;
+  }
+}
+
 //Modals
 .modal-content {
   box-shadow: 0 0.3rem 1rem rgba(0, 0, 0, 0.1);
 }
+
+.modal-header {
+  border-bottom: 1px solid #e5e5e5;
+}
+
+.modal-footer {
+  border-top: 1px solid #e5e5e5;
+}
+
+// col-form-label (substitute for control-label of bootstrap3)
+.col-form-label {
+  text-align: right;
+}
+
+// label
+label {
+  font-weight: 700;
+}
+
+// disabled button (reproduction from bootstrap3.)
+// see https://cccabinet.jpn.org/bootstrap4/components/buttons#disabled-state
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+  cursor: not-allowed;
+}
+
+// input form (disabled box-shadow added in bootstrap4)
+.form-group .form-control {
+
+  &:focus,
+  &.focus {
+    box-shadow: none;
+  }
+}
+
+// progress bar
+.progress {
+  margin-bottom: 18px;
+  overflow: hidden;
+}

+ 0 - 69
src/client/styles/scss/_variables-bootstrap.scss

@@ -1,69 +0,0 @@
-//
-// Variables
-// --------------------------------------------------
-
-//== Colors
-//
-$primary: #112744;
-$secondary: #6c757d;
-$info: #0d8ea5;
-$success: #00bb83;
-$warning: #ee773b;
-$danger: #ff0a54;
-$light: #dee2e6;
-$dark: #343a40;
-
-//== Typography
-//
-//## Font, line-height, and color for body text, headings, and more.
-$font-family-sans-serif: Lato, -apple-system, BlinkMacSystemFont, 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif;
-$font-family-serif: Georgia, 'Times New Roman', Times, serif;
-$font-family-monospace: Osaka-Mono, 'MS Gothic', Monaco, Menlo, Consolas, 'Courier New', monospace;
-$font-family-base: $font-family-sans-serif;
-
-$font-size-root: 14px;
-$line-height-base: 1.42857;
-
-//== Components
-//
-//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
-$border-radius-base: 0;
-$border-radius-large: 0;
-$border-radius-small: 0;
-
-//== Buttons
-//
-//## For each of Bootstrap's buttons, define text, background and border color.
-
-$btn-border-radius: 0;
-$btn-border-radius-lg: 0;
-$btn-border-radius-sm: 0;
-
-//== Forms
-
-$input-border-radius: 0;
-$input-border-radius-lg: 0;
-$input-border-radius-sm: 0;
-
-//== Navs
-
-$nav-link-padding-y: 0.75rem;
-$nav-link-padding-x: 1rem;
-$nav-tabs-border-radius: 0;
-
-//== Navbar
-$navbar-padding-y: 0;
-$navbar-brand-padding-y: 0;
-$navbar-nav-link-padding-x: 1rem;
-
-//== Dropdowns
-$dropdown-border-radius: 0;
-
-//== Modals
-$modal-content-border-width: 0;
-$modal-content-border-radius: 0;
-$modal-header-padding-y: 0.75rem;
-$modal-header-padding-x: 1rem;
-
-//== Alerts
-$alert-border-radius: 0;

+ 6 - 1
src/client/styles/scss/_variables.scss

@@ -2,7 +2,12 @@
 $growi-green: #74bc46;
 $growi-blue: #175fa5;
 
-$font-family-monospace-not-strictly: Monaco, Menlo, Consolas, 'Courier New', MeiryoKe_Gothic, monospace;
+$font-family-monospace-not-strictly: Monaco,
+  Menlo,
+  Consolas,
+  'Courier New',
+  MeiryoKe_Gothic,
+  monospace;
 
 //== Layout
 $grw-navbar-height: 50px;

+ 1 - 1
src/client/styles/scss/style-app.scss

@@ -1,9 +1,9 @@
 // import variables
 @import '../agile-admin/inverse/variables';
 @import 'variables';
-@import 'variables-bootstrap';
 
 @import 'mixins';
+@import 'override-bootstrap-variables';
 
 // vendor
 @import 'vendor';

+ 2 - 2
src/client/styles/scss/theme/_apply-colors-dark.scss

@@ -8,7 +8,7 @@
 /*
  * Button
  */
-.btn-default {
+.btn-light {
   &:hover,
   &:focus,
   &.active,
@@ -139,7 +139,7 @@ header.affix {
  */
 .search-page {
   .input-group-btn {
-    .btn-default {
+    .btn-light {
       border: 1px solid darken($border, 30%); // fit to input.form-control
     }
   }

+ 46 - 15
src/client/styles/scss/theme/_apply-colors.scss

@@ -3,20 +3,27 @@
 //
 @import '~bootstrap/scss/bootstrap-reboot';
 
-@each $color, $value in $theme-colors {
+@each $color,
+  $value in $theme-colors {
   @include bg-variant('.bg-#{$color}', $value);
 }
-@each $color, $value in $theme-colors {
+
+@each $color,
+  $value in $theme-colors {
   .btn-#{$color} {
     @include button-variant($value, $value);
   }
 }
-@each $color, $value in $theme-colors {
+
+@each $color,
+  $value in $theme-colors {
   .btn-outline-#{$color} {
     @include button-outline-variant($value);
   }
 }
-@each $theme-color, $color in $theme-colors {
+
+@each $theme-color,
+  $color in $theme-colors {
   .alert.alert-#{$theme-color} {
     color: white;
     background: $color;
@@ -33,6 +40,11 @@
   }
 }
 
+// Border light
+.border-light {
+  border-color: $light !important;
+}
+
 // Link buttons
 .btn-link {
   color: $link-color;
@@ -44,6 +56,7 @@
 
 // Dropdown
 .dropdown-item {
+
   &.active,
   &:active {
     @include gradient-bg($dropdown-link-active-bg);
@@ -59,6 +72,7 @@
 .nav.nav-tabs {
   > li > a {
     color: $color-link;
+
     &:hover,
     &:focus {
       color: $color-link-hover;
@@ -75,6 +89,7 @@ body {
 }
 
 .logo {
+
   // set transition for fill
   svg * {
     transition: fill 0.8s ease-out;
@@ -90,6 +105,7 @@ body {
         .group1 {
           fill: $growi-green;
         }
+
         .group2 {
           fill: $growi-blue;
         }
@@ -127,46 +143,48 @@ legend {
 .modal {
   .modal-header {
     border-bottom-color: $border;
+
     &.bg-primary,
     &.bg-info,
     &.bg-success,
     &.bg-warning,
     &.bg-danger {
       color: white;
+
       .close {
         color: white;
       }
     }
+
     .close {
       opacity: 0.5;
+
       &:hover {
         opacity: 0.9;
       }
     }
   }
+
   .modal-content {
     background-color: $bgcolor-global;
   }
+
   .modal-footer {
     border-top-color: $border;
   }
 }
 
 /*
- * Panel
+ * cards
  */
-.panel {
-  .panel-body {
-    background-color: $bgcolor-global;
-  }
+.card-header {
+  border: 0;
 }
 
-/*
- * Wells
- */
-.well {
-  background-color: darken($bgcolor-global, 5%);
-  border-color: $border;
+.card.well {
+  background-color: $bgcolor-card;
+  border-color: $light;
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
 }
 
 /*
@@ -175,13 +193,16 @@ legend {
 .admin-page {
   span.slider {
     background-color: #ccc;
+
     &:before {
       background-color: white;
     }
   }
+
   input:checked + .slider {
     background-color: #007bff;
   }
+
   input:focus + .slider {
     box-shadow: 0 0 1px #007bff;
   }
@@ -193,6 +214,7 @@ legend {
 .crowi-sidebar {
   background-color: darken($bgcolor-global, 4%);
   border-left: solid 1px $border;
+
   .system-version {
     background-color: darken($bgcolor-global, 4%);
   }
@@ -204,6 +226,7 @@ legend {
 .wiki {
   a {
     color: $color-link-wiki;
+
     &:hover {
       color: $color-link-wiki-hover;
     }
@@ -214,6 +237,7 @@ legend {
     button {
       color: $color-link-wiki;
     }
+
     button:hover {
       color: $color-link-wiki-hover;
     }
@@ -236,11 +260,13 @@ body.on-edit {
 
     .page-editor-editor-container {
       border-right-color: $navbar-border;
+
       .navbar-editor {
         background-color: $bgcolor-global; // same color with active tab
         border-bottom-color: $border;
       }
     }
+
     .page-editor-preview-container {
       background-color: $bgcolor-global;
     }
@@ -258,12 +284,15 @@ body.on-edit {
   .page-comments-row {
     border-top-color: $border;
   }
+
   .page-comment .page-comment-main,
   .page-comment-form .comment-form-main {
     background-color: darken($bgcolor-global, 4%);
+
     &:before {
       border-right-color: darken($bgcolor-global, 4%);
     }
+
     .nav.nav-tabs {
       > li.active > a {
         background: transparent;
@@ -284,9 +313,11 @@ body.on-edit {
         > li > a {
           background-color: transparent;
         }
+
         li:hover {
           background-color: darken($bgcolor-global, 4%);
         }
+
         li.active {
           background-color: darken($bgcolor-global, 8%);
           border-color: theme-color('primary');

+ 8 - 7
src/client/styles/scss/theme/default.scss

@@ -1,5 +1,4 @@
 @import '../variables';
-@import '../variables-bootstrap';
 
 // == Define colors
 //
@@ -11,13 +10,14 @@ $secondary: #ced4da;
 // $success: #;
 // $warning: #;
 // $danger: #;
-// $light: #;
+$light: #f0f0f0;
 // $dark: #;
 
 // Background colors
 $bgcolor-global: white;
 $bgcolor-navbar: #334455;
 $bgcolor-inline-code: #f9f2f4;
+$bgcolor-card: #f5f5f5;
 
 // Font colors
 $color-global: #333333;
@@ -41,21 +41,22 @@ $link-color: $color-link;
 $link-hover-color: $color-link-hover;
 
 // light mode colors
-@media (prefers-color-scheme: no-preference), (prefers-color-scheme: light) {
-}
+@media (prefers-color-scheme: no-preference),
+  (prefers-color-scheme: light) {}
 
 // dark mode colors
-@media (prefers-color-scheme: dark) {
-}
+@media (prefers-color-scheme: dark) {}
 
 //== Apply
 //
 @import 'apply-colors';
 
 // apply for no-preference or light mode
-@media (prefers-color-scheme: no-preference), (prefers-color-scheme: light) {
+@media (prefers-color-scheme: no-preference),
+  (prefers-color-scheme: light) {
   @import 'apply-colors-light';
 }
+
 // apply for dark mode
 @media (prefers-color-scheme: dark) {
   @import 'apply-colors-dark';