Bladeren bron

[ui] Vue 3 - Migrated EditorResizer components

sreenaths 4 jaren geleden
bovenliggende
commit
5bd19c62d4

+ 89 - 63
desktop/core/src/desktop/js/apps/editor/components/EditorResizer.vue

@@ -17,13 +17,13 @@
 -->
 
 <template>
-  <div class="snippet-code-resizer" @mousedown="start"><i class="fa fa-ellipsis-h" /></div>
+  <div ref="root" class="snippet-code-resizer" @mousedown="start">
+    <i class="fa fa-ellipsis-h" />
+  </div>
 </template>
 
 <script lang="ts">
-  import Vue from 'vue';
-  import Component from 'vue-class-component';
-  import { Prop } from 'vue-property-decorator';
+  import { defineComponent, PropType } from 'vue';
 
   import { HIDE_FIXED_HEADERS_EVENT, REDRAW_FIXED_HEADERS_EVENT } from 'apps/editor/events';
   import SubscriptionTracker from 'components/utils/SubscriptionTracker';
@@ -34,77 +34,103 @@
   const TARGET_ELEMENT_SELECTOR = '.ace-editor-component';
   const CONTENT_PANEL_SELECTOR = '.content-panel';
 
-  @Component
-  export default class EditorResizer extends Vue {
-    @Prop({ required: false })
-    editor?: Ace.Editor | null = null;
-
-    @Prop({ required: false })
-    panelSelector?: string;
-
-    subTracker = new SubscriptionTracker();
-
-    newHeight = 0;
-    startHeight = 0;
-    startY = 0;
-
-    targetElement: HTMLElement | null = null;
-
-    onMouseMove = this.drag.bind(this);
-    onMouseUp = this.stop.bind(this);
-
-    destroyed(): void {
+  export default defineComponent({
+    props: {
+      editor: {
+        type: Object as PropType<Ace.Editor | null>,
+        required: false,
+        default: null
+      }
+    },
+
+    setup(): {
+      subTracker: SubscriptionTracker;
+    } {
+      return {
+        subTracker: new SubscriptionTracker()
+      };
+    },
+
+    data(
+      thisComp
+    ): {
+      newHeight: number;
+      startHeight: number;
+      startY: number;
+
+      targetElement: HTMLElement | null;
+
+      onMouseMove: (event: Event) => void;
+      onMouseUp: (event: Event) => void;
+    } {
+      return {
+        newHeight: 0,
+        startHeight: 0,
+        startY: 0,
+
+        targetElement: null,
+
+        onMouseMove: thisComp.drag.bind(this),
+        onMouseUp: thisComp.stop.bind(this)
+      };
+    },
+
+    unmounted(): void {
       document.removeEventListener('mousemove', this.onMouseMove);
       document.removeEventListener('mouseup', this.onMouseUp);
       this.subTracker.dispose();
-    }
+    },
 
-    drag(event: MouseEvent): void {
-      if (!this.targetElement || !this.editor) {
-        return;
-      }
-      const diff = event.clientY - this.startY;
+    methods: {
+      drag(event: MouseEvent): void {
+        if (!this.targetElement || !this.editor) {
+          return;
+        }
+        const diff = event.clientY - this.startY;
 
-      this.newHeight = Math.max(this.startHeight + diff, 128);
-      this.targetElement.style.height = this.newHeight + 'px';
-      this.editor.resize();
-    }
+        this.newHeight = Math.max(this.startHeight + diff, 128);
+        this.targetElement.style.height = this.newHeight + 'px';
+        this.editor.resize();
+      },
 
-    findTarget(): void {
-      const contentPanel = this.$el.closest<HTMLElement>(CONTENT_PANEL_SELECTOR);
-      if (contentPanel) {
-        this.targetElement = contentPanel.querySelector<HTMLElement>(TARGET_ELEMENT_SELECTOR);
-      }
-      if (!this.targetElement) {
-        console.warn(
-          `EditorResizer could not find the target element '${TARGET_ELEMENT_SELECTOR}'.`
+      findTarget(): void {
+        const contentPanel = (this.$refs.root as HTMLElement).closest<HTMLElement>(
+          CONTENT_PANEL_SELECTOR
         );
-        return;
-      }
-    }
-
-    start(event: MouseEvent): void {
-      if (!this.targetElement) {
-        this.findTarget();
+        if (contentPanel) {
+          this.targetElement = contentPanel.querySelector<HTMLElement>(TARGET_ELEMENT_SELECTOR);
+        }
         if (!this.targetElement) {
+          console.warn(
+            `EditorResizer could not find the target element '${TARGET_ELEMENT_SELECTOR}'.`
+          );
           return;
         }
-      }
-      this.startY = event.clientY;
-      this.startHeight = this.targetElement.offsetHeight;
-      document.addEventListener('mousemove', this.onMouseMove);
-      document.addEventListener('mouseup', this.onMouseUp);
-      huePubSub.publish(HIDE_FIXED_HEADERS_EVENT);
-    }
+      },
 
-    stop(): void {
-      huePubSub.publish(REDRAW_FIXED_HEADERS_EVENT);
-      document.dispatchEvent(new Event('editorSizeChanged')); // TODO: Who listens?
-      document.removeEventListener('mousemove', this.onMouseMove);
-      document.removeEventListener('mouseup', this.onMouseUp);
-      localStorage.setItem(CUSTOM_HEIGHT_STORAGE_KEY, String(this.newHeight));
+      start(event: MouseEvent): void {
+        if (!this.targetElement) {
+          this.findTarget();
+          if (!this.targetElement) {
+            return;
+          }
+        }
+        this.startY = event.clientY;
+        this.startHeight = this.targetElement.offsetHeight;
+        document.addEventListener('mousemove', this.onMouseMove);
+        document.addEventListener('mouseup', this.onMouseUp);
+        huePubSub.publish(HIDE_FIXED_HEADERS_EVENT);
+      },
+
+      stop(): void {
+        huePubSub.publish(REDRAW_FIXED_HEADERS_EVENT);
+        document.dispatchEvent(new Event('editorSizeChanged')); // TODO: Who listens?
+        document.removeEventListener('mousemove', this.onMouseMove);
+        document.removeEventListener('mouseup', this.onMouseUp);
+        localStorage.setItem(CUSTOM_HEIGHT_STORAGE_KEY, String(this.newHeight));
+      }
     }
-  }
+  });
 </script>
 
 <style lang="scss" scoped>

+ 37 - 16
desktop/core/src/desktop/js/apps/editor/components/EditorResizerKoBridge.vue

@@ -21,25 +21,44 @@
 </template>
 
 <script lang="ts">
+  import { defineComponent, PropType } from 'vue';
+
   import { Ace } from 'ext/ace';
-  import Vue from 'vue';
-  import Component from 'vue-class-component';
-  import { Prop } from 'vue-property-decorator';
-  import { wrap } from 'vue/webComponentWrapper';
+
+  import { wrap } from 'vue/webComponentWrap';
 
   import EditorResizer from 'apps/editor/components/EditorResizer.vue';
   import SubscriptionTracker from 'components/utils/SubscriptionTracker';
 
-  @Component({
-    components: { EditorResizer }
-  })
-  export default class EditorResizerKoBridge extends Vue {
-    @Prop()
-    editorObservable?: KnockoutObservable<Ace.Editor | undefined>;
+  const EditorResizerKoBridge = defineComponent({
+    components: {
+      EditorResizer
+    },
+
+    props: {
+      editorObservable: {
+        type: Object as PropType<KnockoutObservable<Ace.Editor | undefined>>,
+        required: true
+      }
+    },
 
-    editor: Ace.Editor | null = null;
-    subTracker = new SubscriptionTracker();
-    initialized = false;
+    setup(): {
+      subTracker: SubscriptionTracker;
+    } {
+      return {
+        subTracker: new SubscriptionTracker()
+      };
+    },
+
+    data(): {
+      editor: Ace.Editor | null;
+      initialized: boolean;
+    } {
+      return {
+        editor: null,
+        initialized: false
+      };
+    },
 
     updated(): void {
       if (!this.initialized && this.editorObservable) {
@@ -49,13 +68,15 @@
         });
         this.initialized = true;
       }
-    }
+    },
 
-    destroyed(): void {
+    unmounted(): void {
       this.subTracker.dispose();
     }
-  }
+  });
 
   export const COMPONENT_NAME = 'editor-resizer-ko-bridge';
   wrap(COMPONENT_NAME, EditorResizerKoBridge);
+
+  export default EditorResizerKoBridge;
 </script>