2
0

editor-code.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <template lang='pug'>
  2. .editor-code
  3. .editor-code-toolbar
  4. .editor-code-toolbar-group
  5. .editor-code-toolbar-item
  6. svg.icons.is-18(role='img')
  7. title Bold
  8. use(xlink:href='#fa-bold')
  9. .editor-code-toolbar-item
  10. svg.icons.is-18(role='img')
  11. title Italic
  12. use(xlink:href='#fa-italic')
  13. .editor-code-toolbar-item
  14. svg.icons.is-18(role='img')
  15. title Strikethrough
  16. use(xlink:href='#fa-strikethrough')
  17. .editor-code-toolbar-group
  18. .editor-code-toolbar-item.is-dropdown
  19. svg.icons.is-18(role='img')
  20. title Heading
  21. use(xlink:href='#fa-heading')
  22. .editor-code-toolbar-group
  23. .editor-code-toolbar-item
  24. svg.icons.is-18(role='img')
  25. title Unordered List
  26. use(xlink:href='#fa-list-ul')
  27. .editor-code-toolbar-item
  28. svg.icons.is-18(role='img')
  29. title Ordered List
  30. use(xlink:href='#fa-list-ol')
  31. .editor-code-toolbar-group
  32. .editor-code-toolbar-item
  33. svg.icons.is-18(role='img')
  34. title Link
  35. use(xlink:href='#fa-link')
  36. .editor-code-toolbar-group
  37. .editor-code-toolbar-item
  38. svg.icons.is-18(role='img')
  39. title Horizontal Bar
  40. use(xlink:href='#fa-minus')
  41. .editor-code-main
  42. .editor-code-editor
  43. .editor-code-editor-title Editor
  44. codemirror(ref='cm', v-model='code', :options='cmOptions', @ready="onCmReady")
  45. .editor-code-preview
  46. .editor-code-preview-title Preview
  47. v-speed-dial(:hover='true', direction='left', transition='slide-y-reverse-transition', :fixed='true', :right='true', :bottom='true')
  48. v-btn(color='green', fab, dark, slot='activator')
  49. v-icon save
  50. v-icon close
  51. v-btn(color='red', fab, dark, small): v-icon not_interested
  52. v-btn(color='orange', fab, dark, small): v-icon vpn_lock
  53. v-btn(color='indigo', fab, dark, small): v-icon restore
  54. v-btn(color='brown', fab, dark, small): v-icon archive
  55. </template>
  56. <script>
  57. import { codemirror } from 'vue-codemirror'
  58. import 'codemirror/lib/codemirror.css'
  59. // Theme
  60. import 'codemirror/theme/base16-dark.css'
  61. // Language
  62. import 'codemirror/mode/markdown/markdown.js'
  63. // Addons
  64. import 'codemirror/addon/selection/active-line.js'
  65. import 'codemirror/addon/display/fullscreen.js'
  66. import 'codemirror/addon/display/fullscreen.css'
  67. import 'codemirror/addon/selection/mark-selection.js'
  68. import 'codemirror/addon/scroll/annotatescrollbar.js'
  69. import 'codemirror/addon/search/matchesonscrollbar.js'
  70. import 'codemirror/addon/search/searchcursor.js'
  71. import 'codemirror/addon/search/match-highlighter.js'
  72. export default {
  73. components: {
  74. codemirror
  75. },
  76. data() {
  77. return {
  78. code: 'const a = 10',
  79. cmOptions: {
  80. tabSize: 2,
  81. mode: 'text/markdown',
  82. theme: 'base16-dark',
  83. lineNumbers: true,
  84. lineWrapping: true,
  85. line: true,
  86. styleActiveLine: true,
  87. highlightSelectionMatches: {
  88. annotateScrollbar: true
  89. },
  90. viewportMargin: 50,
  91. extraKeys: {
  92. 'F11'(cm) {
  93. cm.setOption('fullScreen', !cm.getOption('fullScreen'))
  94. },
  95. 'Esc'(cm) {
  96. if (cm.getOption('fullScreen')) cm.setOption('fullScreen', false)
  97. }
  98. }
  99. }
  100. }
  101. },
  102. computed: {
  103. cm() {
  104. return this.$refs.cm.codemirror
  105. }
  106. },
  107. methods: {
  108. onCmReady(cm) {
  109. cm.setSize(null, 'calc(100vh - 50px)')
  110. },
  111. onCmFocus(cm) {
  112. console.log('the editor is focus!', cm)
  113. },
  114. onCmCodeChange(newCode) {
  115. console.log('this is new code', newCode)
  116. this.code = newCode
  117. }
  118. }
  119. }
  120. </script>
  121. <style lang='scss'>
  122. .editor-code {
  123. &-main {
  124. display: flex;
  125. width: 100%;
  126. }
  127. &-editor {
  128. flex: 1 1 50%;
  129. display: block;
  130. min-height: calc(100vh - 50px);
  131. position: relative;
  132. &-title {
  133. background-color: mc('grey', '800');
  134. border-bottom-left-radius: 5px;
  135. display: inline-flex;
  136. height: 30px;
  137. justify-content: center;
  138. align-items: center;
  139. padding: 0 1rem;
  140. color: mc('grey', '500');
  141. position: absolute;
  142. top: 0;
  143. right: 0;
  144. z-index: 2;
  145. text-transform: uppercase;
  146. font-size: .7rem;
  147. }
  148. }
  149. &-preview {
  150. flex: 1 1 50%;
  151. background-color: mc('grey', '100');
  152. position: relative;
  153. padding: 30px 1rem 1rem 1rem;
  154. &-title {
  155. background-color: mc('blue', '100');
  156. border-bottom-right-radius: 5px;
  157. display: inline-flex;
  158. height: 30px;
  159. justify-content: center;
  160. align-items: center;
  161. padding: 0 1rem;
  162. color: mc('blue', '800');
  163. position: absolute;
  164. top: 0;
  165. left: 0;
  166. z-index: 2;
  167. text-transform: uppercase;
  168. font-size: .7rem;
  169. }
  170. }
  171. &-toolbar {
  172. background-color: mc('blue', '700');
  173. background-image: linear-gradient(to bottom, mc('blue', '700') 0%, mc('blue','800') 100%);
  174. height: 50px;
  175. color: #FFF;
  176. display: flex;
  177. &-group {
  178. display: flex;
  179. + .editor-code-toolbar-group {
  180. border-left: 1px solid rgba(mc('blue', '900'), .75);
  181. }
  182. }
  183. &-item {
  184. width: 40px;
  185. height: 50px;
  186. display: flex;
  187. justify-content: center;
  188. align-items: center;
  189. transition: all .4s ease;
  190. cursor: pointer;
  191. &:first-child {
  192. padding-left: .5rem;
  193. }
  194. &:last-child {
  195. padding-right: .5rem;
  196. }
  197. &:hover {
  198. background-color: mc('blue', '600');
  199. }
  200. }
  201. svg {
  202. use {
  203. color: #FFF;
  204. }
  205. }
  206. }
  207. }
  208. .CodeMirror {
  209. height: auto;
  210. }
  211. .CodeMirror-focused .cm-matchhighlight {
  212. background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);
  213. background-position: bottom;
  214. background-repeat: repeat-x;
  215. }
  216. .cm-matchhighlight {
  217. background-color: mc('grey', '800');
  218. }
  219. .CodeMirror-selection-highlight-scrollbar {
  220. background-color: mc('green', '600');
  221. }
  222. </style>