jam411 3 лет назад
Родитель
Сommit
dad51eadbd

+ 228 - 0
packages/app/src/components/PageEditor/Editor.module.scss

@@ -0,0 +1,228 @@
+@use '~/styles/mixins' as ms;
+@use '~/styles/bootstrap/init' as bs;
+@use '~/styles/bootstrap/variables' as var;
+
+// TODO: Refactor Scss improt bellow. This classes from _editor-overlay.scss
+
+// TODO: Move to ~/styles/mixins.
+// @mixin overlay-processing-style($additionalSelector, $contentFontSize: inherit, $contentPadding: inherit) {
+//   .overlay.#{$additionalSelector} {
+//     background: rgba(255, 255, 255, 0.5);
+//     .overlay-content {
+//       padding: $contentPadding;
+//       font-size: $contentFontSize;
+//       color: $gray-700;
+//       background: rgba(200, 200, 200, 0.5);
+//     }
+//   }
+// }
+
+// overlay in .editor-container
+.editor-container :global {
+  .overlay {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    z-index: 7; // forward than .CodeMirror-vscrollbar
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  // loading keymap
+  @include ms.overlay-processing-style(overlay-loading-keymap, 2.5em, 0.3em);
+
+  // cheat sheat
+  .overlay.overlay-gfm-cheatsheet {
+    align-items: flex-end;
+    justify-content: flex-end;
+
+    pointer-events: none;
+
+    .card.gfm-cheatsheet {
+      box-shadow: unset;
+      opacity: 0.6;
+      .card-body {
+        min-width: 30em;
+        padding-bottom: 0;
+        font-family: monospace;
+        color: bs.$text-muted;
+      }
+      ul > li {
+        list-style: none;
+      }
+    }
+
+    .gfm-cheatsheet-modal-link {
+      color: bs.$text-muted;
+      pointer-events: all;
+      cursor: pointer;
+      background-color: transparent;
+      border: none;
+
+      opacity: 0.6;
+
+      &:hover,
+      &:focus {
+        opacity: 1;
+      }
+    }
+  }
+
+
+  // TODO: Refactor Scss improt bellow. This classes from _editor-attachment.scss
+  // for Dropzone
+  .dropzone {
+    // TODO: Move to ~/styles/mixins.
+    // @mixin insertSimpleLineIcons($code) {
+    //   &:before {
+    //     margin-right: 0.2em;
+    //     font-family: 'simple-line-icons';
+    //     content: $code;
+    //   }
+    // }
+
+    position: relative; // against .overlay position: absolute
+
+    @include ms.overlay-processing-style(overlay-dropzone-active, 2.5em, 0.5em);
+
+    // unuploadable or rejected
+    &.dropzone-unuploadable,
+    &.dropzone-rejected {
+      .overlay.overlay-dropzone-active {
+        background: rgba(200, 200, 200, 0.8);
+
+        .overlay-content {
+          color: var.$gray-300;
+        }
+      }
+    }
+
+    // uploading
+    &.dropzone-uploading {
+      @include ms.overlay-processing-style(overlay-dropzone-active, 2.5em, 0.5em);
+    }
+
+    // unuploadable
+    &.dropzone-unuploadable {
+      .overlay.overlay-dropzone-active {
+        .overlay-content {
+          // insert content
+          @include ms.insertSimpleLineIcons('\e617'); // icon-exclamation
+
+          &:after {
+            content: 'File uploading is disabled';
+          }
+        }
+      }
+    }
+
+    // uploadable
+    &.dropzone-uploadable {
+      // accepted
+      &.dropzone-accepted:not(.dropzone-rejected) {
+        .overlay.overlay-dropzone-active {
+          border: 4px dashed var.$gray-300;
+
+          .overlay-content {
+            // insert content
+            @include ms.insertSimpleLineIcons('\e084'); // icon-cloud-upload
+
+            &:after {
+              content: 'Drop here to upload';
+            }
+
+            // style
+            color: bs.$secondary;
+            background: rgba(200, 200, 200, 0.8);
+          }
+        }
+      }
+
+      // file type mismatch
+      &.dropzone-rejected:not(.dropzone-uploadablefile) {
+        .overlay.overlay-dropzone-active {
+          .overlay-content {
+            // insert content
+            @include ms.insertSimpleLineIcons('\e032'); // icon-picture
+
+            &:after {
+              content: 'Only an image file is allowed';
+            }
+          }
+        }
+      }
+
+      // multiple files
+      &.dropzone-accepted.dropzone-rejected {
+        .overlay.overlay-dropzone-active {
+          .overlay-content {
+            // insert content
+            @include ms.insertSimpleLineIcons('\e617'); // icon-exclamation
+
+            &:after {
+              content: 'Only 1 file is allowed';
+            }
+          }
+        }
+      }
+    }
+
+    /* end of.dropzone */
+  }
+
+  .btn.btn-open-dropzone {
+    z-index: 2;
+    padding-top: 3px;
+    padding-bottom: 3px;
+    font-size: small;
+    border: none;
+    border-top: 1px dotted var.$gray-300;
+    border-bottom: none;
+
+    &:hover,
+    &:focus {
+      border-bottom: none;
+    }
+  }
+
+
+  // TODO: Refactor Scss improt bellow. This classes from _editor-navbar.scss
+  .navbar-editor {
+    height: 30px;
+    padding: 0;
+
+    border-bottom: 1px solid transparent;
+
+    li {
+      display: inline-block;
+      i {
+        font-size: 16px;
+      }
+    }
+
+    button {
+      padding: 0px;
+      margin: 0 2px;
+      font-size: 1rem;
+      line-height: 1;
+      background-color: transparent;
+      border: none;
+    }
+
+    img {
+      vertical-align: bottom;
+    }
+  }
+}
+
+// TODO: Refactor Scss improt bellow. This classes from _editor-overlay.scss
+.modal-gfm-cheatsheet :global {
+  .modal-body {
+    .hljs {
+      font-family: bs.$font-family-monospace;
+    }
+  }
+}

+ 4 - 2
packages/app/src/components/PageEditor/Editor.tsx

@@ -20,6 +20,8 @@ import CodeMirrorEditor from './CodeMirrorEditor';
 import pasteHelper from './PasteHelper';
 import TextAreaEditor from './TextAreaEditor';
 
+import styles from './Editor.module.scss';
+
 type EditorPropsType = {
   value?: string,
   isGfmMode?: boolean,
@@ -257,7 +259,7 @@ const Editor = React.forwardRef((props: EditorPropsType, ref): JSX.Element => {
     };
 
     return (
-      <Modal isOpen={isCheatsheetModalShown} toggle={hideCheatsheetModal} className="modal-gfm-cheatsheet">
+      <Modal isOpen={isCheatsheetModalShown} toggle={hideCheatsheetModal} className={`modal-gfm-cheatsheet ${styles['modal-gfm-cheatsheet']}`} >
         <ModalHeader tag="h4" toggle={hideCheatsheetModal} className="bg-primary text-light">
           <i className="icon-fw icon-question" />Markdown help
         </ModalHeader>
@@ -280,7 +282,7 @@ const Editor = React.forwardRef((props: EditorPropsType, ref): JSX.Element => {
 
   return (
     <>
-      <div style={flexContainer} className="editor-container">
+      <div style={flexContainer} className={`editor-container ${styles['editor-container']}`} >
         <Dropzone
           ref={dropzoneRef}
           accept={getAcceptableType()}

+ 1 - 1
packages/app/src/styles/_editor-overlay.scss

@@ -11,7 +11,7 @@
 }
 
 // overlay in .editor-container
-.editor-container {
+.editor-container :global {
   .overlay {
     position: absolute;
     top: 0;

+ 21 - 0
packages/app/src/styles/_mixins.scss

@@ -1,4 +1,5 @@
 @use './bootstrap/init' as bs;
+@use './bootstrap/variables' as var;
 
 @mixin variable-font-size($basesize) {
   font-size: $basesize * 0.6;
@@ -198,3 +199,23 @@
     }
   }
 }
+
+@mixin overlay-processing-style($additionalSelector, $contentFontSize: inherit, $contentPadding: inherit) {
+  .overlay.#{$additionalSelector} {
+    background: rgba(255, 255, 255, 0.5);
+    .overlay-content {
+      padding: $contentPadding;
+      font-size: $contentFontSize;
+      color: var.$gray-700;
+      background: rgba(200, 200, 200, 0.5);
+    }
+  }
+}
+
+@mixin insertSimpleLineIcons($code) {
+  &:before {
+    margin-right: 0.2em;
+    font-family: 'simple-line-icons';
+    content: $code;
+  }
+}