<script>
/**
 * vs-panel 2022-07-13
 * 
 * 面板组件内部使用了vs-dialog组件，并进行中转，vs-dialog组件所需props可直接使用
 * 
 * panelTop 面板距离顶部位位置 120
 * leftSideWidth 面板左侧宽度 350
 * rightSideWidth 面板右侧宽度 350
 * 
 * isSlot 是否使用插槽形式 false  //使用插槽形式则移除默认的vs-dialog组件方式 compsLeft,compsRight参数无效
 * 
 * template #left 左侧内容
 * template #right 右侧内容
 *
 * compsLeft 面板左侧组件集合 
 * [
 *  {
 *    comps: defineAsyncComponent(() => import('./line.vue')), //组件异步引入
      height: 350, //当前模块高度
      title: '折线图' //当前模块名称
      class:'' //当前模块自定义类名
 *  }
 * ]
 * 
 * isMask 是否使用蒙版
 * 
 * compsRight  面板右侧组件集合  数据同上
 * 
 * 面板展示动画 须配合<transition name="?">标签使用 标签的name值  （vslr|左右渐入动画 vsfade|淡入淡出 vstb|上下渐入动画）
 * 
 * 
 * 
 */
export default {
  name: "vs-panel",
};
</script>
<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, computed, watch } from "vue";
const props = defineProps({
  panelTop: {
    type: Number,
    default: 120,
  },
  leftSideWidth: {
    type: Number,
    default: 350,
  },
  rightSideWidth: {
    type: Number,
    default: 350,
  },
  compsLeft: {
    type: Array,
    default: () => [],
  },
  compsRight: {
    type: Array,
    default: () => [],
  },
  isSlot: {
    type: Boolean,
    default: false,
  },
  isMask: {
    type: Boolean,
    default: false,
  }
});

const style = reactive({
  panel: {
    top: props.panelTop + "px",
    '--lswidth': (-props.leftSideWidth - 20) + 'px',
    '--rswidth': (props.rightSideWidth + 20) + 'px',
  },
  leftSide: {
    width: props.leftSideWidth + 'px'
  },
  rightSide: {
    width: props.rightSideWidth + 'px',
    left: `calc(100vw - ${props.rightSideWidth + 20}px)`,
  },
  maskLeft: {
    height: `calc(100vh + ${props.panelTop}px )`,
    top: `-${props.panelTop}px`
  },
  maskRight: {
    height: `calc(100vh + ${props.panelTop}px )`,
    left: `calc(100vw - 470px)`,
    top: `-${props.panelTop}px`
  }
});

onMounted(() => {
});

const setItemHeight = computed(() => (data, index) => {
  let height = 0;
  let i = 0;
  while (i < index) {
    height += data[i].height + 10;
    i++
  }

  return height + 'px'
})

</script>

<template>
  <div class="vs-panel" :style="style.panel">
    <div v-if="props.isMask" class="vs-panel-mask--left" :style="style.maskLeft"></div>
    <div class="vs-panel--left" :style="style.leftSide">
      <slot name="left" v-if="props.isSlot" />
      <template v-else>
        <div class="vs-panel--left--item" :class="item.class" v-for="(item, index) in props.compsLeft" :key="index">
          <vs-dialog :top="setItemHeight(props.compsLeft, index)" v-bind="$attrs" :width="`${props.leftSideWidth}px`"
            :height="`${item.height || 200}px`" :isMini="false" :isFullScreen="false" :isClose="false" :isDrag="false"
            :title="item.title">
            <component :is="item.comps"></component>
          </vs-dialog>
        </div>
      </template>
    </div>
    <div v-if="props.isMask" class="vs-panel-mask--right" :style="style.maskRight"></div>
    <div ref="panelRightRef" class="vs-panel--right" :style="style.rightSide">
      <slot name="right" v-if="props.isSlot" />
      <template v-else>
        <div class="vs-panel--right--item" :class="item.class" v-for="(item, index) in props.compsRight" :key="index">
          <vs-dialog :top="setItemHeight(props.compsRight, index)" v-bind="$attrs" :width="`${props.rightSideWidth}px`"
            :height="`${item.height || 200}px`" :isMini="false" :isFullScreen="false" :isClose="false" :isDrag="false"
            :title="item.title">
            <component :is="item.comps"></component>
          </vs-dialog>
        </div>
      </template>
    </div>
  </div>
</template>

<style  lang="scss" scope>
$main: var(--main);
$auxiliary: var(--auxiliary);
$light: var(--light);

.vs-panel {
  position: absolute;

  .vs-panel-mask--left {
    width: 470px;
    height: 100vh;
    position: absolute;
    left: 0px;
    top: 0px;
    z-index: 9;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("../icon/sysleft.png");
  }

  .vs-panel-mask--right {
    width: 470px;
    height: 100vh;
    position: absolute;
    right: 0px;
    top: 0px;
    z-index: 9;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("../icon/sysright.png");
  }

  .vs-panel--left {
    height: 100vh;
    left: 20px;
    position: absolute;
  }

  .vs-panel--right {
    height: 100vh;
    position: absolute;
  }


}

//左右渐入
.vslr {

  &-enter-from,
  &-leave-to {

    .vs-panel--left,
    .vs-panel-mask--left {
      transform: translateX(var(--lswidth));
    }

    .vs-panel--right,
    .vs-panel-mask--right {
      transform: translateX(var(--rswidth));
    }
  }

  &-enter-active,
  &-leave-active {
    transition: transform 0.3s ease-in;

    .vs-panel--left,
    .vs-panel--right,
    .vs-panel-mask--left,
    .vs-panel-mask--right {
      transition: transform 0.3s ease-in
    }
  }

  &-enter-to,
  &-leave-from {

    .vs-panel--left,
    .vs-panel--right,
    .vs-panel-mask--left,
    .vs-panel-mask--right {
      transform: translateX(0px);
    }
  }
}

//上下渐入
.vstb {

  &-enter-from,
  &-leave-to {

    .vs-panel--left,
    .vs-panel-mask--left {
      transform: translateY(1080px);
    }

    .vs-panel--right,
    .vs-panel-mask--right {
      transform: translateY(1080px);
    }
  }

  &-enter-active,
  &-leave-active {
    transition: transform 0.3s ease-in;

    .vs-panel--left,
    .vs-panel--right,
    .vs-panel-mask--left,
    .vs-panel-mask--right {
      transition: transform 0.3s ease-in
    }
  }

  &-enter-to,
  &-leave-from {

    .vs-panel--left,
    .vs-panel--right,
    .vs-panel-mask--left,
    .vs-panel-mask--right {
      transform: translateY(0px);
    }
  }
}

//淡入淡出
.vsfade {

  &-enter-from,
  &-leave-to {

    .vs-panel--left,
    .vs-panel--right,
    .vs-panel-mask--left,
    .vs-panel-mask--right {
      opacity: 0;
    }
  }

  &-enter-active {
    transition: transform 0.5s ease-in;

    .vs-panel--left,
    .vs-panel--right,
    .vs-panel-mask--left,
    .vs-panel-mask--right {
      animation: vsin .5s
    }
  }

  &-leave-active {
    transition: transform 0.5s ease-in;

    .vs-panel--left,
    .vs-panel--right,
    .vs-panel-mask--left,
    .vs-panel-mask--right {
      animation: vsout .5s
    }
  }

  &-enter-to,
  &-leave-from {

    .vs-panel--left,
    .vs-panel--right,
    .vs-panel-mask--left,
    .vs-panel-mask--right {
      opacity: 1;
    }
  }

  @keyframes vsin {
    0% {
      opacity: 0;
    }

    100% {
      opacity: 1;
    }
  }

  @keyframes vsout {
    0% {
      opacity: 1;
    }

    100% {
      opacity: 0;
    }
  }
}
</style>
