You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2021/09/10 02:49:57 UTC

[echarts-examples] 05/15: feat: add ts and js switch. add prettier

This is an automated email from the ASF dual-hosted git repository.

shenyi pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/echarts-examples.git

commit 85dfdafbd3a7349dfdacd4c7b060c8d40abcb634
Author: pissang <bm...@gmail.com>
AuthorDate: Tue Sep 7 13:40:05 2021 +0800

    feat: add ts and js switch. add prettier
---
 package.json              |   4 +-
 src/common/config.js      |   4 +-
 src/common/i18n.js        |  21 ++++--
 src/common/route.js       |  30 ++++++++
 src/common/store.js       |   2 +-
 src/editor/CodeMonaco.vue |  25 ++++++-
 src/editor/Editor.vue     | 177 +++++++++++++++++++++++++++++++++++++++++-----
 src/editor/Preview.vue    |  25 +++++--
 8 files changed, 253 insertions(+), 35 deletions(-)

diff --git a/package.json b/package.json
index 26fe6df..cbc49e1 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,6 @@
     "open": "^7.1.0",
     "pixelmatch": "^5.2.1",
     "pngjs": "^6.0.0",
-    "prettier": "^2.3.2",
     "sass.js": "^0.11.1",
     "sassjs-loader": "^2.0.0",
     "seedrandom": "^3.0.5",
@@ -67,6 +66,7 @@
     "sucrase": "^3.17.0",
     "vanilla-lazyload": "^12.5.1",
     "vue-i18n": "^8.18.2",
-    "vue-scrollactive": "^0.9.3"
+    "vue-scrollactive": "^0.9.3",
+    "prettier": "^2.3.2"
   }
 }
diff --git a/src/common/config.js b/src/common/config.js
index e46cf9f..472658a 100644
--- a/src/common/config.js
+++ b/src/common/config.js
@@ -134,5 +134,7 @@ export const SCRIPT_URLS = {
   datGUIMinJS:
     'https://cdn.jsdelivr.net/npm/dat.gui@0.6.5/build/dat.gui.min.js',
   monacoDir: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.27.0/min/vs',
-  aceDir: 'https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict'
+  aceDir: 'https://cdn.jsdelivr.net/npm/ace-builds@1.4.12/src-min-noconflict',
+
+  prettierDir: 'https://cdn.jsdelivr.net/npm/prettier@2.3.2'
 };
diff --git a/src/common/i18n.js b/src/common/i18n.js
index 88e6493..206515a 100644
--- a/src/common/i18n.js
+++ b/src/common/i18n.js
@@ -2,6 +2,7 @@ export default {
   en: {
     editor: {
       run: 'Run',
+      format: 'Format',
       errorInEditor: 'Errors exist in code!',
       chartOK: 'Chart has been generated successfully, ',
 
@@ -16,12 +17,16 @@ export default {
       download: 'Download',
 
       edit: 'Edit',
-      monacoMode: 'Enable Type Checking',
 
-      tabEditor: 'Edit Example',
+      tabEditor: 'Edit Code',
       tabFullCodePreview: 'Full Code',
       tabOptionPreview: 'Option Preview',
-      minimalBundle: 'Minimal Bundle'
+      minimalBundle: 'Minimal Bundle',
+
+      tooltip: {
+        jsMode: 'JavaScript',
+        tsMode: 'TypeScript. Provides Better Intelligent'
+      }
     },
 
     chartTypes: {
@@ -69,6 +74,7 @@ export default {
   zh: {
     editor: {
       run: '运行',
+      format: '格式化',
       errorInEditor: '编辑器内容有误!',
       chartOK: '图表已生成, ',
 
@@ -84,10 +90,15 @@ export default {
       edit: '编辑',
       monacoMode: '开启类型检查',
 
-      tabEditor: '示例编辑',
+      tabEditor: '代码编辑',
       tabFullCodePreview: '完整代码',
       tabOptionPreview: '配置项',
-      minimalBundle: '按需引入'
+      minimalBundle: '按需引入',
+
+      tooltip: {
+        jsMode: 'JavaScript 代码编辑',
+        tsMode: 'TypeScript 代码编辑,提供更好的代码补全和类型检查。'
+      }
     },
 
     chartTypes: {
diff --git a/src/common/route.js b/src/common/route.js
new file mode 100644
index 0000000..4ede915
--- /dev/null
+++ b/src/common/route.js
@@ -0,0 +1,30 @@
+export function getURL(params) {
+  const searchUrlParts = [];
+  for (let key in params) {
+    if (params.hasOwnProperty(key)) {
+      let part = key;
+      if (params[key] != null) {
+        part += '=' + params[key];
+      }
+      searchUrlParts.push(part);
+    }
+  }
+  const searchUrl = searchUrlParts.join('&');
+
+  return (
+    location.protocol +
+    '//' +
+    location.hostname +
+    (location.port ? ':' + location.port : '') +
+    location.pathname +
+    (searchUrl ? '?' + searchUrl : '')
+  );
+}
+
+export function goto(params, pushHistory) {
+  if (pushHistory) {
+    history.pushState({}, getURL(params));
+  } else {
+    location.href = getURL(params);
+  }
+}
diff --git a/src/common/store.js b/src/common/store.js
index de6d12b..f6a56df 100644
--- a/src/common/store.js
+++ b/src/common/store.js
@@ -10,7 +10,7 @@ export const store = {
   enableDecal: 'decal' in URL_PARAMS,
   renderer: URL_PARAMS.renderer || 'canvas',
 
-  typeCheck: 'ts' in URL_PARAMS,
+  typeCheck: (URL_PARAMS.lang || '').toLowerCase() === 'ts',
   useDirtyRect: 'useDirtyRect' in URL_PARAMS,
 
   runCode: '',
diff --git a/src/editor/CodeMonaco.vue b/src/editor/CodeMonaco.vue
index ab68cb8..85224a7 100644
--- a/src/editor/CodeMonaco.vue
+++ b/src/editor/CodeMonaco.vue
@@ -97,6 +97,9 @@ function ensureMonacoAndTsTransformer() {
         return new Promise((resolve) => {
           window.require(['vs/editor/editor.main'], function () {
             loadTypes().then(() => {
+              // Disable AMD. Which will break other libs.
+              // FIXME
+              window.define.amd = null;
               resolve();
             });
           });
@@ -163,7 +166,27 @@ export default {
   methods: {
     setInitialCode(code) {
       if (this._editor && code) {
-        this._editor.setValue(code || '');
+        // this._editor.setValue(code || '');
+
+        // https://github.com/microsoft/monaco-editor/issues/299#issuecomment-268423927
+        this._editor.executeEdits('replace', [
+          {
+            identifier: 'delete',
+            range: new monaco.Range(1, 1, 10000, 1),
+            text: '',
+            forceMoveMarkers: true
+          }
+        ]);
+        this._editor.executeEdits('replace', [
+          {
+            identifier: 'insert',
+            range: new monaco.Range(1, 1, 1, 1),
+            text: code,
+            forceMoveMarkers: true
+          }
+        ]);
+        this._editor.setSelection(new monaco.Range(0, 0, 0, 0));
+        // this._editor.setPosition(currentPosition);
       }
     }
   },
diff --git a/src/editor/Editor.vue b/src/editor/Editor.vue
index b8162f7..f0f8abd 100644
--- a/src/editor/Editor.vue
+++ b/src/editor/Editor.vue
@@ -10,13 +10,67 @@
           <span slot="label">{{ $t('editor.tabEditor') }}</span>
           <el-container>
             <el-header id="editor-control-panel">
-              <div class="editor-controls">
-                <a
-                  href="javascript:;"
-                  class="btn btn-default btn-sm"
-                  @click="disposeAndRun"
-                  >{{ $t('editor.run') }}</a
+              <div class="languages">
+                <el-tooltip
+                  :content="$t('editor.tooltip.jsMode')"
+                  placement="bottom"
+                >
+                  <a
+                    :class="{ js: true, active: !shared.typeCheck }"
+                    @click="changeLang('js')"
+                    >JS</a
+                  >
+                </el-tooltip>
+                <el-tooltip
+                  :content="$t('editor.tooltip.tsMode')"
+                  placement="bottom"
                 >
+                  <a
+                    @click="changeLang('ts')"
+                    :class="{ ts: true, active: shared.typeCheck }"
+                    >TS</a
+                  >
+                </el-tooltip>
+              </div>
+              <div class="editor-controls">
+                <a class="btn btn-sm format" @click="format">
+                  <svg
+                    xmlns="http://www.w3.org/2000/svg"
+                    fill="none"
+                    viewBox="0 0 24 24"
+                    stroke="currentColor"
+                  >
+                    <path
+                      stroke-linecap="round"
+                      stroke-linejoin="round"
+                      stroke-width="2"
+                      d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
+                    />
+                  </svg>
+                  <span>{{ $t('editor.format') }}</span>
+                </a>
+                <a class="btn btn-default btn-sm run" @click="disposeAndRun">
+                  <svg
+                    xmlns="http://www.w3.org/2000/svg"
+                    fill="none"
+                    viewBox="0 0 24 24"
+                    stroke="currentColor"
+                  >
+                    <path
+                      stroke-linecap="round"
+                      stroke-linejoin="round"
+                      stroke-width="2"
+                      d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"
+                    />
+                    <path
+                      stroke-linecap="round"
+                      stroke-linejoin="round"
+                      stroke-width="2"
+                      d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
+                    />
+                  </svg>
+                  <span>{{ $t('editor.run') }}</span>
+                </a>
               </div>
             </el-header>
             <el-main>
@@ -51,6 +105,7 @@
               >
               </el-switch>
               <el-switch
+                v-if="!shared.typeCheck"
                 v-model="fullCodeConfig.esm"
                 active-text="ES Modules"
                 :inactive-text="''"
@@ -62,6 +117,7 @@
             </el-main>
           </el-container>
         </el-tab-pane>
+
         <el-tab-pane :label="$t('editor.tabOptionPreview')" name="full-option">
           <div id="option-outline"></div>
         </el-tab-pane>
@@ -93,10 +149,23 @@ import FullCodePreview from './FullCodePreview.vue';
 import Preview from './Preview.vue';
 import { store, loadExampleCode, parseSourceCode } from '../common/store';
 import { collectDeps, buildExampleCode } from '../../common/buildCode';
+import { goto } from '../common/route';
 import { mount } from '@lang/object-visualizer';
 
 import './object-visualizer.css';
-
+import { SCRIPT_URLS, URL_PARAMS } from '../common/config';
+import { loadScriptsAsync } from '../common/helper';
+
+function ensurePrettier() {
+  if (typeof prettier === 'undefined') {
+    return loadScriptsAsync([
+      SCRIPT_URLS.prettierDir + '/standalone.js',
+      SCRIPT_URLS.prettierDir +
+        (store.typeCheck ? '/parser-typescript.js' : '/parser-babel.js')
+    ]).then(([_, parser]) => {});
+  }
+  return Promise.resolve();
+}
 export default {
   components: {
     CodeAce,
@@ -220,15 +289,35 @@ export default {
       } else if (tab === 'full-option') {
         this.updateOptionOutline();
       }
+    },
+    changeLang(lang) {
+      if ((URL_PARAMS.lang || 'js').toLowerCase() !== lang) {
+        goto(
+          Object.assign({}, URL_PARAMS, {
+            lang
+          })
+        );
+      }
+    },
+    format() {
+      ensurePrettier().then(() => {
+        this.initialCode = prettier.format(store.sourceCode, {
+          singleQuote: true,
+          tabWidth: 2,
+          printWidth: 80,
+          semi: true,
+          trailingComma: 'none',
+          // tabWidth: +this.formatCodeSettings.tabSize,
+          // printWidth: +this.formatCodeSettings.maxLineWidth,
+          parser: store.typeCheck ? 'typescript' : 'babel',
+          plugins: prettierPlugins
+        });
+        this.updateFullCode();
+      });
     }
   },
 
   watch: {
-    'shared.typeCheck'(enableTypeCheck) {
-      // Update initialCode to avoid code changed when switching editor
-      this.initialCode = store.sourceCode;
-      this.updateFullCode();
-    },
     currentTab(tab) {
       this.updateTabContent(tab);
     },
@@ -393,6 +482,43 @@ $handler-width: 5px;
     }
   }
 
+  .languages {
+    display: inline-block;
+    padding: 2px 10px;
+    font-weight: bold;
+
+    a {
+      display: inline-block;
+      padding: 3px 10px;
+      margin-left: 5px;
+      vertical-align: middle;
+      cursor: pointer;
+
+      &.ts {
+        color: #3178c6;
+      }
+
+      &.js {
+        color: #000;
+      }
+
+      &.active {
+        font-size: 12px;
+        border-radius: 3px;
+
+        &.js {
+          background: #f7df1e;
+          color: #000;
+        }
+
+        &.ts {
+          background: #3178c6;
+          color: #fff;
+        }
+      }
+    }
+  }
+
   .editor-controls {
     float: right;
 
@@ -404,16 +530,31 @@ $handler-width: 5px;
     }
 
     .btn {
-      color: #fff;
       border-radius: 0;
-      background-color: #409eff;
       margin-left: $pd-basic;
       border: none;
       height: 30px;
-      width: 50px;
-    }
-    .btn:hover {
-      background-color: lighten($color: #409eff, $amount: 5);
+
+      background: none;
+      color: $clr-text;
+
+      & > * {
+        display: inline-block;
+        vertical-align: middle;
+      }
+
+      svg {
+        width: 15px;
+        height: 15px;
+      }
+
+      &.run {
+        color: #fff;
+        background-color: #409eff;
+      }
+      &.run:hover {
+        background-color: lighten($color: #409eff, $amount: 5);
+      }
     }
   }
 }
diff --git a/src/editor/Preview.vue b/src/editor/Preview.vue
index 46d9535..dd573d5 100644
--- a/src/editor/Preview.vue
+++ b/src/editor/Preview.vue
@@ -26,7 +26,6 @@
           :inactive-text="''"
         >
         </el-switch>
-
         <el-popover
           placement="bottom"
           width="450"
@@ -72,9 +71,19 @@
         >
           {{ $t('editor.download') }}
         </button>
-        <a class="screenshot" @click="screenshot" target="_blank"
-          ><i class="el-icon-camera-solid"></i
-        ></a>
+        <a class="screenshot" @click="screenshot" target="_blank">
+          <svg
+            xmlns="http://www.w3.org/2000/svg"
+            viewBox="0 0 20 20"
+            fill="currentColor"
+          >
+            <path
+              fill-rule="evenodd"
+              d="M4 5a2 2 0 00-2 2v8a2 2 0 002 2h12a2 2 0 002-2V7a2 2 0 00-2-2h-1.586a1 1 0 01-.707-.293l-1.121-1.121A2 2 0 0011.172 3H8.828a2 2 0 00-1.414.586L6.293 4.707A1 1 0 015.586 5H4zm6 9a3 3 0 100-6 3 3 0 000 6z"
+              clip-rule="evenodd"
+            />
+          </svg>
+        </a>
       </template>
       <a :href="editLink" target="_blank" v-else class="edit btn btn-sm">{{
         $t('editor.edit')
@@ -98,7 +107,7 @@ import { SCRIPT_URLS, URL_PARAMS } from '../common/config';
 import { loadScriptsAsync } from '../common/helper';
 import { createSandbox } from './sandbox';
 import debounce from 'lodash/debounce';
-import { addListener, removeListener } from 'resize-detector';
+import { addListener } from 'resize-detector';
 import CHART_LIST from '../data/chart-list-data';
 import CHART_LIST_GL from '../data/chart-list-data-gl';
 import { download } from './downloadExample';
@@ -416,8 +425,10 @@ export default {
     cursor: pointer;
   }
   .screenshot {
-    font-size: 22px;
-    margin-right: 10px;
+    margin-right: 5px;
+    width: 25px;
+    height: 25px;
+    margin-top: 2px;
   }
 }
 

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org