浏览代码

:lipstick: dark theme

Van 6 年之前
父节点
当前提交
bb4defcd7f

+ 5 - 2
demo/demo.js

@@ -53,7 +53,8 @@ const vditor = new Vditor('vditor', {
       name: 'preview',
       tipPosition: 'ne',
     },
-    {
+    'br'
+    , {
       name: 'emoji',
       tail: '<a href="https://hacpai.com/settings/function" target="_blank">设置常用表情</a>',
     },
@@ -61,4 +62,6 @@ const vditor = new Vditor('vditor', {
   ],
 })
 
-const vditor2 = new Vditor('vditor2')
+const vditor2 = new Vditor('vditor2')
+
+console.log(vditor2)

+ 1 - 4
demo/demo.scss

@@ -1,4 +1 @@
-@import "../src/assets/classic";
-body {
-    background-color: #f1f7fe;
-}
+@import "../src/assets/scss/classic";

+ 0 - 41
src/assets/_toolbar.scss

@@ -1,41 +0,0 @@
-/**
- * toolbar.
- *
- * @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
- * @version 0.1.0.0, Jan 28, 2019
- */
-.vditor-toolbar {
-  background-color: #f6f8fa;
-  padding: 0 5px;
-  display: inline-flex;
-
-  & > div {
-    padding: 10px 5px;
-  }
-
-  svg {
-    fill: currentColor;
-    display: inline-block;
-    stroke-width: 0;
-    stroke: currentColor;
-    width: 14px;
-    height: 14px;
-  }
-
-  .vditor-tooltipped {
-    color: #616161;
-    &:hover {
-      color: #4285f4;
-    }
-  }
-}
-
-.vditor-menu {
-  &--current svg {
-    color: #4285f4;
-  }
-
-  &__divider {
-    width: 10px;
-  }
-}

+ 0 - 137
src/assets/classic.scss

@@ -1,137 +0,0 @@
-@import "tooltipped";
-@import "panel";
-@import "toolbar";
-
-.vditor {
-  display: flex;
-  flex-direction: column;
-
-  &--fullscreen {
-    position: fixed;
-    top: 0;
-    width: 100% !important;
-    left: 0;
-    height: 100vh !important;
-    z-index: 90;
-    background-color: #fff;
-  }
-
-  &-emojis {
-    display: inline-block;
-
-    &__tail {
-      font-size: 12px;
-      text-align: right;
-      color: #616161;
-      a {
-        text-decoration: none;
-        color: #616161;
-        &:hover {
-          color: #4285f4;
-        }
-      }
-    }
-
-    span {
-      cursor: pointer;
-      border-radius: 3px;
-      float: left;
-      height: 20px;
-      width: 20px;
-      text-align: center;
-      line-height: 20px;
-      padding: 3px;
-      &:hover {
-        background-color: #f1f7fe;
-      }
-    }
-
-    img {
-      height: 20px;
-      width: 20px;
-      display: inline-block;
-    }
-  }
-
-  &-content {
-    display: flex;
-    min-height: 60px;
-    flex: 1;
-    position: relative;
-  }
-
-  &-textarea {
-    flex: 1;
-    border: 0;
-    font-size: 14px;
-    resize: none;
-    padding: 10px;
-    box-sizing: border-box;
-    background-color: #fafbfc;
-
-    &:focus {
-      outline: none;
-      background-color: #fff;
-    }
-  }
-
-  &-preview {
-    flex: 1;
-    background-color: #fff;
-    overflow: auto;
-    padding: 10px;
-    box-shadow: inset 1px 0 hsla(0, 0%, 50.2%, .06);
-    box-sizing: border-box;
-
-    &::-webkit-scrollbar {
-      display: none;
-    }
-  }
-
-  &-counter {
-    position: absolute;
-    bottom: 10px;
-    right: 10px;
-    color: #616161;
-    background-color: hsla(0, 0%, 100%, .8);
-    border-radius: 3px;
-    font-size: 12px;
-    user-select: none;
-  }
-
-  &-drag {
-    padding: 1px 0;
-    border-radius: 5px;
-    cursor: row-resize;
-    color: rgba(0, 0, 0, .38);
-    transition: all .15s ease-in-out;
-    user-select: none;
-
-    &:hover {
-      background-color: rgba(66, 133, 244, .54);
-      color: rgba(0, 0, 0, .54);
-    }
-
-    svg {
-      width: 13px;
-      height: 3px;
-      display: block;
-      margin: 0 auto;
-    }
-  }
-
-  &-hint {
-    background-color: #fff;
-    line-height: 21px;
-    position: absolute;
-    box-shadow: 0 1px 2px rgba(0, 0, 0, .2);
-    border-radius: 3px;
-    padding: 5px 0;
-    z-index: 1;
-    font-size: 16px;
-
-    &--current {
-      background-color: lightblue;
-    }
-  }
-}

+ 90 - 0
src/assets/scss/_content.scss

@@ -0,0 +1,90 @@
+.vditor {
+  display: flex;
+  flex-direction: column;
+
+  &--fullscreen {
+    position: fixed;
+    top: 0;
+    width: 100% !important;
+    left: 0;
+    height: 100vh !important;
+    z-index: 90;
+    background-color: $fullscreenBg;
+  }
+
+  &-content {
+    display: flex;
+    min-height: 60px;
+    flex: 1;
+    position: relative;
+  }
+
+  &-textarea {
+    flex: 1;
+    border: 0;
+    resize: none;
+    padding: 10px;
+    box-sizing: border-box;
+    background-color: $textareaBg;
+    outline: 0 none;
+    font-size: 16px;
+    line-height: 22px;
+    color: $textareaColor;
+
+    &:focus {
+      background-color: $textareaFocusBg;
+    }
+  }
+
+  &-preview {
+    flex: 1;
+    background-color: $previewBg;
+    overflow: auto;
+    padding: 10px;
+    box-shadow: inset 1px 0 $borderColor;
+    box-sizing: border-box;
+
+    &::-webkit-scrollbar {
+      display: none;
+    }
+  }
+
+  &-counter {
+    padding: 0 3px;
+    position: absolute;
+    bottom: 10px;
+    right: 10px;
+    color: $textareaColor;
+    background-color: $countBg;
+    border-radius: 3px;
+    font-size: 12px;
+    user-select: none;
+  }
+
+  &-drag {
+    padding: 1px 0;
+    border-radius: 5px;
+    cursor: row-resize;
+    transition: all .15s ease-in-out;
+    user-select: none;
+    background-color: $dragBg;
+
+    &:hover {
+      background-color: $dragHoverBg;
+      svg {
+        color: $hoverColor;
+      }
+    }
+
+    svg {
+      fill: currentColor;
+      stroke-width: 0;
+      stroke: currentColor;
+      width: 13px;
+      height: 3px;
+      display: block;
+      margin: 0 auto;
+      color: $toolbarIcon;
+    }
+  }
+}

+ 38 - 0
src/assets/scss/_hint.scss

@@ -0,0 +1,38 @@
+.vditor-hint {
+  background-color: $layerBg;
+  position: absolute;
+  box-shadow: $layerShadow;
+  border-radius: 3px;
+  padding: 5px 0;
+  z-index: 1;
+  line-height: 20px;
+  list-style: none;
+  color: $textareaColor;
+  font-size: 12px;
+  margin: 0;
+  max-width: 200px;
+  min-width: 80px;
+  display: none;
+
+  li {
+    cursor: pointer;
+    padding: 3px 10px;
+    border-bottom: 1px solid $borderColor;
+    &:last-child {
+      border-bottom: 0;
+    }
+  }
+
+  &--current,
+  li:hover {
+    background-color: $hoverBg;
+    color: $layerBg;
+  }
+
+  img {
+    height: 20px;
+    width: 20px;
+    float: left;
+    margin-right: 3px;
+  }
+}

+ 5 - 3
src/assets/_panel.scss → src/assets/scss/_panel.scss

@@ -6,9 +6,9 @@
  */
 
 .vditor-panel {
-  background-color: #fff;
+  background-color: $layerBg;
   position: absolute;
-  box-shadow: 0 1px 2px rgba(0, 0, 0, .2);
+  box-shadow: $layerShadow;
   border-radius: 3px;
   padding: 5px;
   z-index: 1;
@@ -23,8 +23,10 @@
     cursor: pointer;
     padding: 3px 10px;
     border-radius: 3px;
+    line-height: normal;
     &:hover {
-      background-color: #f1f7fe;
+      background-color: $hoverBg;
+      color: $hoverColor;
     }
   }
 }

+ 87 - 0
src/assets/scss/_toolbar.scss

@@ -0,0 +1,87 @@
+/**
+ * toolbar.
+ *
+ * @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
+ * @version 0.1.0.0, Jan 28, 2019
+ */
+.vditor {
+  &-toolbar {
+    background-color: $toolbarBg;
+    border-bottom: 1px solid $borderColor;
+    padding: 0 5px;
+
+    & > div {
+      padding: 10px 5px;
+      float: left;
+      line-height: 14px;
+    }
+
+    svg {
+      fill: currentColor;
+      display: inline-block;
+      stroke-width: 0;
+      stroke: currentColor;
+      width: 14px;
+      height: 14px;
+    }
+
+    .vditor-tooltipped {
+      color: $toolbarIcon;
+      &:hover {
+        color: $toolbarIconHover;
+      }
+    }
+  }
+
+  &-menu {
+    &--current svg {
+      color: $toolbarIconHover;
+    }
+
+    &__divider {
+      width: 10px;
+    }
+
+    &__br {
+      width: 100%;
+      padding: 0 !important;
+    }
+  }
+
+  &-emojis {
+    display: inline-block;
+
+    &__tail {
+      font-size: 12px;
+      text-align: right;
+      color: $toolbarIcon;
+      a {
+        text-decoration: none;
+        color: $toolbarIcon;
+        &:hover {
+          color: $hoverBg;
+        }
+      }
+    }
+
+    span {
+      cursor: pointer;
+      border-radius: 3px;
+      float: left;
+      height: 20px;
+      width: 20px;
+      text-align: center;
+      line-height: 20px;
+      padding: 3px;
+      &:hover {
+        background-color: $hoverBg;
+      }
+    }
+
+    img {
+      height: 20px;
+      width: 20px;
+      display: inline-block;
+    }
+  }
+}

+ 7 - 7
src/assets/_tooltipped.scss → src/assets/scss/_tooltipped.scss

@@ -25,7 +25,7 @@
     font-size: 11px;
     font-weight: normal;
     -webkit-font-smoothing: subpixel-antialiased;
-    color: #fff;
+    color: $tooltipColor;
     text-align: center;
     text-decoration: none;
     text-shadow: none;
@@ -35,7 +35,7 @@
     white-space: pre;
     pointer-events: none;
     content: attr(aria-label);
-    background: rgba(0, 0, 0, 0.8);
+    background: $toolTipBg;
     border-radius: 3px;
     line-height: 16px;
     opacity: 0
@@ -47,7 +47,7 @@
     display: none;
     width: 0;
     height: 0;
-    color: rgba(0, 0, 0, 0.8);
+    color: $toolTipBg;
     pointer-events: none;
     content: "";
     border: 5px solid transparent;
@@ -86,7 +86,7 @@
     right: 50%;
     bottom: -5px;
     margin-right: -5px;
-    border-bottom-color: rgba(0, 0, 0, 0.8)
+    border-bottom-color: $toolTipBg
   }
 
   &__se::after {
@@ -114,7 +114,7 @@
     right: 50%;
     bottom: auto;
     margin-right: -5px;
-    border-top-color: rgba(0, 0, 0, 0.8)
+    border-top-color: $toolTipBg
   }
 
   &__ne::after {
@@ -144,7 +144,7 @@
     bottom: 50%;
     left: -5px;
     margin-top: -5px;
-    border-left-color: rgba(0, 0, 0, 0.8);
+    border-left-color: $toolTipBg;
   }
 
   &__e::after {
@@ -159,7 +159,7 @@
     right: -5px;
     bottom: 50%;
     margin-top: -5px;
-    border-right-color: rgba(0, 0, 0, 0.8)
+    border-right-color: $toolTipBg
   }
 }
 

+ 31 - 0
src/assets/scss/classic.scss

@@ -0,0 +1,31 @@
+$borderColor: #d1d5da !default;
+
+$toolbarBg: #f6f8fa !default;
+$toolbarIcon: #586069 !default;
+$toolbarIconHover: #4285f4 !default;
+
+$textareaBg: #fafbfc !default;
+$textareaColor: #24292e !default;
+$textareaFocusBg: #fff !default;
+
+$tooltipColor:#fff !default;
+$toolTipBg: rgba(0, 0, 0, 0.8) !default;
+
+$layerBg: #fff !default;
+$layerShadow:  0 1px 2px rgba(0, 0, 0, .2) !default;
+
+$hoverBg: #4285f4 !default;
+$hoverColor: #fff !default;
+
+$dragBg: #f6f8fa !default;
+$dragHoverBg: #4285f4 !default;
+
+$fullscreenBg: #fff !default;
+$previewBg: #fff !default;
+$countBg: rgba(255, 255, 255, 0.8) !default;
+
+@import "tooltipped";
+@import "panel";
+@import "toolbar";
+@import "content";
+@import "hint";

+ 31 - 0
src/assets/scss/dark.scss

@@ -0,0 +1,31 @@
+$borderColor: #fff !default;
+
+$toolbarBg: #2c2c2c !default;
+$toolbarIcon: #b9b9b9 !default;
+$toolbarIconHover: #fff !default;
+
+$textareaBg: #fff !default;
+$textareaColor: rgba(0,0,0,.8) !default;
+$textareaFocusBg: #fff !default;
+
+$tooltipColor:#fff !default;
+$toolTipBg: rgba(0, 0, 0, 0.8) !default;
+
+$layerBg: #fff !default;
+$layerShadow:  0 1px 2px rgba(0, 0, 0, .2) !default;
+
+$dragBg: #f3f3f3 !default;
+$dragHoverBg: #2c2c2c !default;
+
+$hoverBg: #2c2c2c !default;
+$hoverColor: #fff !default;
+
+$fullscreenBg: #fff !default;
+$previewBg: #f3f3f3 !default;
+$countBg: rgba(255, 255, 255, 0.8) !default;
+
+@import "tooltipped";
+@import "panel";
+@import "toolbar";
+@import "content";
+@import "hint";

+ 0 - 1
src/index.ts

@@ -22,7 +22,6 @@ class VditorClass {
         this.vditor = {
             id,
             options: mergedOptions,
-            timeId: -1
         }
 
         if (mergedOptions.counter > 0) {

+ 9 - 4
src/ts/editor/index.ts

@@ -37,11 +37,16 @@ class Editor {
             }
         })
 
-        if (vditor.options.blur) {
-            this.element.addEventListener('blur', () => {
+
+        this.element.addEventListener('blur', () => {
+            if (vditor.options.blur) {
                 vditor.options.blur(this.element.value)
-            })
-        }
+            }
+            if (vditor.hint && vditor.hint.element) {
+                vditor.hint.element.style.display = 'none'
+            }
+        })
+
         if (vditor.options.select) {
             this.element.onselect = () => {
                 vditor.options.select(this.element.value.substring(

+ 8 - 9
src/ts/hint/index.ts

@@ -43,18 +43,18 @@ export class Hint {
                 import(/* webpackChunkName: "allEmoji" */ '../emoji/allEmoji')
                     .then(allEmoji => {
                         let emojiHint = emojiKey === '' ? this.commonEmoji : allEmoji.default
-                        let matchEmojiData:Array<any> = []
+                        let matchEmojiData: Array<any> = []
                         Object.keys(emojiHint).forEach((key) => {
                             if (key.indexOf(emojiKey.toLowerCase()) === 0) {
                                 if (emojiHint[key].indexOf('.') > -1) {
                                     matchEmojiData.push({
                                         value: `:${key}:`,
-                                        html: `<img src="${emojiHint[key]}"/>`
+                                        html: `<img src="${emojiHint[key]}" title=":${key}:"/> :${key}:`
                                     })
                                 } else {
                                     matchEmojiData.push({
                                         value: emojiHint[key],
-                                        html: emojiHint[key]
+                                        html: `${emojiHint[key]} ${key}`
                                     })
                                 }
                             }
@@ -104,8 +104,8 @@ export class Hint {
             return
         }
         const textareaPosition = getTextareaPosition(this.editorElement)
-        const x = textareaPosition.left + 2
-        const y = textareaPosition.top + 29
+        const x = textareaPosition.left
+        const y = textareaPosition.top - 4
         let hintsHTML = ''
 
         data.forEach((hintData, i) => {
@@ -131,11 +131,10 @@ export class Hint {
                 insertText(this.editorElement, value, '', true)
             })
         })
-
         // hint 展现在上部
-        if (y + this.element.offsetHeight > this.editorElement.offsetHeight + 68) {
-            this.element.style.top = `${y - this.element.offsetHeight - 18}px`
+        if (y + this.element.offsetHeight - this.editorElement.offsetHeight >
+            window.innerHeight - (this.editorElement.parentElement.offsetHeight + this.editorElement.parentElement.offsetTop - document.documentElement.scrollTop)) {
+            this.element.style.top = `${y - this.element.offsetHeight}px`
         }
     }
-
 }

+ 2 - 1
src/ts/toolbar/Br.ts

@@ -2,6 +2,7 @@ export class Br {
     element: HTMLElement
 
     constructor() {
-        this.element = document.createElement('br')
+        this.element = document.createElement('div')
+        this.element.className = 'vditor-menu__br'
     }
 }

+ 2 - 2
src/ts/toolbar/Emoji.ts

@@ -16,9 +16,9 @@ export class Emoji extends MenuItemClass {
         Object.keys(vditor.options.commonEmoji).forEach((key) => {
             const emojiValue = vditor.options.commonEmoji[key]
             if (emojiValue.indexOf('.') > -1) {
-                commonEmojiHTML += `<span data-value=":${key}: "><img data-value=":${key}: " src="${emojiValue}"/></span>`
+                commonEmojiHTML += `<span data-value=":${key}: " title=":${key}:"><img data-value=":${key}: " src="${emojiValue}"/></span>`
             } else {
-                commonEmojiHTML += `<span data-value="${emojiValue} ">${emojiValue}</span>`
+                commonEmojiHTML += `<span data-value="${emojiValue} " title="${key}">${emojiValue}</span>`
             }
         })
 

+ 2 - 2
src/ts/util/OptionsClass.ts

@@ -63,7 +63,7 @@ export class OptionsClass {
         }, {
             name: 'quote',
             prefix: '> ',
-            hotkey: '⌘-r',
+            hotkey: '⌘-.',
             tipPosition: 'n'
         }, {
             name: '|'
@@ -132,7 +132,7 @@ export class OptionsClass {
             tipPosition: 'nw'
         }, {
             name: 'help',
-            hotkey: '⌘-.',
+            hotkey: '⌘-/',
             tipPosition: 'nw'
         }, {
             name: 'br'

+ 2 - 1
webpack.config.js

@@ -98,7 +98,8 @@ const baseConfig = [
   }, {
     mode: 'production',
     entry: {
-      'index.classic': './src/assets/classic.scss',
+      'index.classic': './src/assets/scss/classic.scss',
+      'index.dark': './src/assets/scss/dark.scss',
     },
     resolve: {
       extensions: ['.scss'],