WidgetWrapper.vue 2.45 KB
<script lang="ts" setup>
  import { onMounted } from 'vue';
  import { useUpdateCenter } from '../../hook/useUpdateCenter';
  import type { DataSource, WidgetWrapperRegister } from './type';

  const props = defineProps<{
    dataSource: DataSource[];
    register?: WidgetWrapperRegister;
  }>();

  const { update, add, remove } = useUpdateCenter();

  onMounted(() => {
    props.register && props.register(props.dataSource);
  });

  defineExpose({ update });
</script>

<template>
  <section class="widget">
    <slot name="header"></slot>

    <div class="widget-content">
      <div
        v-for="item in props.dataSource"
        :key="item.id"
        :style="{ width: `${item.width}%`, height: `${item.height}%` }"
        class="widget-item"
      >
        <div class="widget-box">
          <div class="widget-controls-container">
            <slot
              name="controls"
              :record="item"
              :add="add"
              :remove="remove"
              :update="update"
            ></slot>
          </div>
          <div class="widget-value">
            <slot name="value" :record="item"></slot>
          </div>
          <div class="widget-label">
            <slot name="label" :record="item"></slot>
          </div>
        </div>
      </div>
    </div>
    <slot name="footer"></slot>
  </section>
</template>

<style scoped>
  .widget {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
  }
  .widget-content {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;

    width: 100%;
    height: 100%;
  }

  .widget-box .widget-charts {
    display: flex;
  }

  .widget-item {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    justify-content: center;
    align-items: center;
  }

  .widget-box {
    position: relative;
    width: 100%;
    height: 100%;
  }

  .widget-controls-container {
    flex: 1 1 auto;
    width: 100%;
    height: calc(100% - 20px);
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .widget-controls-container > div {
    width: 100%;
    height: 100%;
    background-color: red;
  }

  .widget-value {
    font-size: 14px;
    position: absolute;
    width: 100%;
    top: 0;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .widget-label {
    font-size: 14px;
    line-height: 1.2;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
  }
</style>