Skip to content
Snippets Groups Projects
ViewProvider.vue 2.25 KiB
<template>
  <div>
    <slot
      v-bind:views="views"
      v-bind:isCurrentView="isCurrentView"
      v-bind:toggleView="toggleView"
      v-bind:showView="showView"
      v-bind:setView="setView"
    ></slot>
  </div>
</template>

<script>
export default {
  props: {
    initial: {
      default: () => {}
    },
    syncLocation: {
      type: Boolean,
      default: false,
    },
    locationParam: {
      type: String,
      default: "view",
    }
  },
  data() {
    return {
      views: this.$props.initial,
      queryParams: null,
      keyListener: e => {
        // Esc
        if (e.keyCode === 27) {
          this.hideAllViews();
        }
      }
    };
  },
  watch: {
    routeView() {
      const queryParams = new URLSearchParams(window.location.search);
    }
  },
  methods: {
    setView(viewId, show, hideOthers = false) {
      if (hideOthers) {
        Object.keys(this.$data.views).forEach(key => {
          if (key !== viewId) {
            this.setView(key, false);
          }
        });
      }

      this.$data.views[viewId] = show;

      if (show && this.$props.syncLocation) {
        const queryParams = new URLSearchParams(window.location.search);

        queryParams.set(this.$props.locationParam, viewId);
        history.pushState(null, null, "?" + queryParams.toString());
      }
    },
    setViews(updates) {
      this.$data.views = Object.assign({}, this.data.views, updates);
    },
    toggleView(viewId) {
      this.setView(viewId, !this.isCurrentView(viewId), true);
    },
    showView(viewId) {
      this.setView(viewId, true, true);
    },
    isCurrentView(viewId) {
      return this.$data.views[viewId];
    },
    hideAllViews() {
      Object.keys(this.$data.views).forEach(key => {
        this.setView(key, false);
      });
    }
  },
  mounted() {
    window.addEventListener('keydown', this.$data.keyListener);

    if (this.$props.syncLocation) {
      const queryParams = new URLSearchParams(window.location.search);
      const locationView = queryParams.get(this.$props.locationParam);

      if (locationView && Object.keys(this.$data.views).indexOf(locationView) !== -1) {
        this.showView(locationView);
      }
    }
  },
  destroyed() {
    window.removeEventListener('keydown', this.$data.keyListener);
  }
}
</script>