<script setup lang="ts">
import {ref, watch, onMounted, reactive} from "vue";

/** 子项默认宽度 */
const itemWidth = ref(18);
/** 父Flex属性–Flex容器 默认值 */
const flexContainerForm: { [key: string]: any } = reactive({
  "flex-direction": "row",
  "flex-wrap": "nowrap",
  "justify-content": "flex-start",
  "align-items": "stretch",
  "align-content": "stretch",
});

/** 选项值，默认值 */
const flexContainerList = {
  "flex-direction": {
    title: "flex-direction",
    list: ["row", "row-reverse", "column", "column-reverse"],
    modelValue: "row",
  },
  "flex-wrap": {
    title: "flex-wrap",
    list: ["nowrap", "wrap", "wrap-reverse"],
    modelValue: "nowrap",
  },
  "justify-content": {
    title: "justify-content",
    list: ["flex-start", "flex-end", "center", "space-between", "space-around"],
    modelValue: "flex-start",
  },
  "align-items": {
    title: "align-items",
    list: ["stretch", "flex-start", "flex-end", "center", "baseline"],
    modelValue: "stretch",
  },
  "align-content": {
    title: "align-content",
    list: [
      "stretch",
      "flex-start",
      "flex-end",
      "center",
      "space-between",
      "space-around",
    ],
    modelValue: "stretch",
  },
};

/** 子项初始个数 */
const itemCount = 5;
/** 当前子项总数 */
let itemListCount = ref(itemCount);
/** 子项-单项默认值 */
const itemFormDefaultValue: { [key: string]: number | string } = {
  order: 0,
  "flex-grow": 0,
  "flex-shrink": 1,
  "flex-basis": "auto",
  "align-self": "auto",
};

/** align-self 选项 */
const itemAlignSelf = [
  "auto",
  "stretch",
  "center",
  "flex-start",
  "flex-end",
  "baseline",
];

/** 子项列表 JSON 数据 */
let flexItemForm: {
  [key: string]: any;
} = reactive({});

/** 增加子项 */
const addItem = () => {
  itemListCount.value++;
  flexItemForm[`item-` + itemListCount.value] = JSON.parse(
      JSON.stringify(itemFormDefaultValue)
  );
};

/** 减少子项 */
const removeItem = (key: string | number) => {
  delete flexItemForm[key];
  delete flexItemFormStyle[key];
};

/** 横杆后的字母变大写 */
const toUp = (str: string) => {
  let newStr = "";
  let arr = str.split("-"); //先用字符串分割成数组

  arr.forEach((item, index) => {
    if (index > 0) {
      return (newStr += item.replace(item[0], item[0].toUpperCase()));
    } else {
      return (newStr += item);
    }
  });
  return newStr;
};

/** flexBox style */
let flexContainerFormStyle: { [key: string]: any } = reactive({});
const flexContainerFormStyleFun = () => {
  Object.keys(flexContainerForm).forEach((key) => {
    flexContainerFormStyle["display"] = "flex";
    flexContainerFormStyle["height"] = "95%";
    flexContainerFormStyle[toUp(key)] = flexContainerForm[key];
  });
};
/** flexContainerForm 父属性 默认值监听*/
watch(flexContainerForm, () => {
  // flexContainerFormStyle = {};
  flexContainerFormStyleFun();
});

/** 子项 style 生成 */
let flexItemFormStyle: { [key: string]: any } = reactive({});
const flexItemFormStyleFun = () => {
  Object.keys(flexItemForm).forEach((ikey) => {
    let valueObj: any = {};
    let flexItemFormIkey = flexItemForm[ikey];
    Object.keys(flexItemFormIkey).forEach((_ikeys) => {
      // valueObj['backgroundColor'] = 'cornsilk';
      valueObj["width"] = itemWidth.value + "%";
      // valueObj['minHeight'] = '80px';
      // valueObj['display'] = 'inline-block';
      valueObj[toUp(_ikeys)] = flexItemFormIkey[_ikeys];
    });
    flexItemFormStyle[ikey] = valueObj;
  });
};
/** 监听子项 和 宽度样式变化 */
watch([flexItemForm, itemWidth], () => {
  // flexItemFormStyle = {};
  flexItemFormStyleFun();
});

/** 初始 子项 默认值 */
const initialFlexItemForm = () => {
  for (let index = 0; index < itemCount; index++) {
    flexItemForm[`item-` + index] = JSON.parse(
        JSON.stringify(itemFormDefaultValue)
    );
  }
}

/**
 * 准备html和css 打印准备
 */
/** 盒子dom */
let fiexBoxDom: any = ref(null);
/** 要输出的html */
let fiexBoxDomHtml: any = ref(``);
/** 外层 CSS */
let fiexBoxCssString: any = ref(``);
/** 子项 CSS */
let fiexItemCssString: any = ref(``);
/** 生成HTML方法 */
const fiexSubmitHtml = () => {
  let html = `<div class="flexbox">`;
  // 获取所有子项
  Object.keys(flexItemForm).forEach((ikey, index) => {
    const itemClass = "flex-item item-" + (index + 1);
    html += `<div class="${itemClass}">${itemClass}</div>`;
  });
  html += `</div>`;
  fiexBoxDomHtml.value = html;
};
/** 生成CSS方法{} */
const fiexSubmitCss = () => {
  /** 增加CSS外层{} */
  const addKuohao = (css: string) => {
    return `{` + css + `}`;
  };
  const flexboxitemDom = fiexBoxDom.value.querySelectorAll(".flexboxitem");
  let css: string = ".flex-item{display: inline-block; min-height: 80px; background-color: cornsilk; margin: 5px; overflow: hidden;}";
  flexboxitemDom.forEach((dom: any, index: string) => {
    css += `.item-` + (index + 1) + addKuohao(dom.style.cssText);
  });

  fiexBoxCssString.value = `.flexbox{` + fiexBoxDom.value.style.cssText + `}`;
  fiexItemCssString.value = css;
};
/** 获取打印html和css */
const fiexSubmit = () => {
  fiexSubmitHtml();
  fiexSubmitCss();
};

/** 初始页面加载后只执行一次 */
onMounted(() => {
  initialFlexItemForm();
  flexContainerFormStyleFun();
  flexItemFormStyleFun();
});

/**
 * 底部
 */
const showTime: any = ref('');
const showTimeYear: any = ref(0);
const checkTime = function (i: any) {
  if (i < 10) {
    i = "0" + i;
  }
  return i;
};
const showTimeFun = function () {
  const nowdate = new Date();
  let year = nowdate.getFullYear(),
      month = nowdate.getMonth() + 1,
      date = nowdate.getDate(),
      day = nowdate.getDay(),
      week = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
      h: string | number = nowdate.getHours(),
      m: string | number = nowdate.getMinutes(),
      s: string | number = nowdate.getSeconds();
  h = checkTime(h);
  m = checkTime(m);
  s = checkTime(s);
  // 年
  showTimeYear.value = year.toString();
  // 日期时间
  showTime.value = year + "年" + month + "月" + date + "日" + week[day] + " " + h + ":" + m + ":" + s;
};

showTimeFun();
setInterval(() => {
  showTimeFun();
}, 1000);  //反复执行函数

</script>

<template>
  <div class="layout">
    <a-layout>
      <a-layout-header>
        <h1><strong>CSS3 Flexbox 在线演示</strong></h1>
      </a-layout-header>
      <a-layout-content>
        <a-row class="flexrow">
          <a-col class="arcocol">
            <h3>子项宽度</h3>
            <div>
              <span>Width：{{ itemWidth }}</span>
              <a-slider
                  v-model="itemWidth"
                  :min="18"
                  :max="100"
                  :step="1"
                  :style="{ paddingLeft: '10px', width: '90%' }"
              />
            </div>
            <a-divider :margin="20" :size="2">
              <icon-heart/>
            </a-divider>
            <h3>父Flex属性–Flex容器</h3>
            <div>
              <a-form :model="flexContainerForm">
                <a-row class="flexcontainer">
                  <a-col
                      class="acol"
                      v-for="(item, key) in flexContainerList"
                      :key="key"
                  >
                    <h4>
                      <strong>{{ item.title }}</strong>
                    </h4>
                    <a-radio-group
                        direction="vertical"
                        v-model="flexContainerForm[key]"
                    >
                      <a-radio
                          v-for="(value, keys) in item.list"
                          :value="value"
                          :key="keys"
                      >
                        {{ value }}
                      </a-radio>
                    </a-radio-group>
                  </a-col>
                </a-row>
                <a-button
                    @click="fiexSubmit"
                    :style="{ marginTop: '15px' }"
                    type="primary"
                    status="success"
                >获取
                </a-button
                >
                <a-alert
                    type="success"
                    :show-icon="false"
                    :style="{ padding: '20px', marginTop: '15px' }"
                    v-if="fiexBoxDomHtml || fiexBoxCssString || fiexItemCssString"
                >
                  {{ fiexBoxDomHtml }}
                  <a-divider/>
                  {{ fiexBoxCssString }}
                  <a-divider/>
                  {{ fiexItemCssString }}
                  <a-divider/>
                </a-alert>
              </a-form>
            </div>
          </a-col>
          <a-col class="arcocol" :style="{ padding: '20px 5px' }">
            <h3>
              实现效果
              <a-button
                  type="primary"
                  @click="addItem"
                  :style="{ float: 'right' }"
              >
                <template #icon>
                  <icon-plus/>
                </template>
                新增子项
              </a-button>
            </h3>
            <div :style="{ height: '100%' }">
              <div
                  class="flexbox"
                  :style="flexContainerFormStyle"
                  ref="fiexBoxDom"
              >
                <div
                    class="flexboxitem"
                    v-for="(_, indexKey, index) in flexItemForm"
                    :key="index"
                    :style="flexItemFormStyle[indexKey]"
                >
                  <a-card :title="(index + 1).toString()" :bordered="false">
                    <template #extra>
                      <a-button
                          type="text"
                          shape="circle"
                          @click="removeItem(indexKey)"
                      >
                        <icon-close/>
                      </a-button>
                    </template>
                    <a-list>
                      <a-list-item>
                        <a-tooltip content="order">
                          <a-input-number
                              v-model="flexItemForm[indexKey].order"
                              :min="0"
                              model-event="input"
                          />
                        </a-tooltip>
                      </a-list-item>
                      <a-list-item>
                        <a-tooltip content="flex-grow">
                          <a-input-number
                              v-model="flexItemForm[indexKey]['flex-grow']"
                              :min="0"
                              model-event="input"
                          />
                        </a-tooltip>
                      </a-list-item>
                      <a-list-item>
                        <a-tooltip content="flex-shrink">
                          <a-input-number
                              v-model="flexItemForm[indexKey]['flex-shrink']"
                              :min="1"
                              :max="100"
                              model-event="input"
                          />
                        </a-tooltip>
                      </a-list-item>
                      <a-list-item>
                        <a-tooltip content="flex-basis">
                          <a-input
                              v-model="flexItemForm[indexKey]['flex-basis']"
                              allow-clear
                          />
                        </a-tooltip>
                      </a-list-item>
                      <a-list-item>
                        <a-tooltip content="align-self">
                          <a-select
                              v-model="flexItemForm[indexKey]['align-self']"
                          >
                            <a-option
                                v-for="ikeys in itemAlignSelf"
                                :key="ikeys"
                            >
                              {{ ikeys }}
                            </a-option>
                          </a-select>
                        </a-tooltip>
                      </a-list-item>
                    </a-list>
                  </a-card>
                </div>
              </div>
            </div>
          </a-col>
        </a-row>
      </a-layout-content>
      <a-layout-footer ref="showTimeDom">
        <a-row class="footer" :gutter="24">
          <a-col :span="12">
            <div>{{ showTime }}</div>
          </a-col>
          <a-col :span="12">
            <span :style="{padding:'0 10px'}">Copyright © 2015-{{ showTimeYear }}</span>
            <a target="_blank" rel="noopener" href="https://beian.miit.gov.cn/"> 鲁ICP备10001546号 </a>
          </a-col>
        </a-row>

      </a-layout-footer>
    </a-layout>
  </div>
</template>

<style scoped>
h3 {
  font-weight: 700;
  padding-bottom: 15px;
}

/**
效果实现
 */
.flexbox {
  padding: 10px;
  background-color: goldenrod;
}

.flexbox :deep(.arco-card-size-medium .arco-card-body) {
  padding: 5px;
}

.flexbox :deep(.arco-list-bordered) {
  border: none;
}

.flexbox :deep(.arco-input-wrapper),
.flexbox :deep(.arco-select-view-single) {
  background-color: transparent;
}

.flexboxitem {
  min-height: 80px;
  background-color: cornsilk;
  display: inline-block;
  margin: 5px;
  overflow: hidden;
}

.flexboxitem :deep(.arco-card) {
  background: transparent;
}

.flexboxitem :deep(.arco-list-wrapper),
.flexboxitem :deep(.arco-list-medium .arco-list-content-wrapper .arco-list-content > .arco-list-item) {
  padding: 0;
}

.layout,
.layout :deep(.arco-layout) {
  height: 100%;
}

.layout :deep(.arco-layout-header),
.layout :deep(.arco-layout-footer),
.layout :deep(.arco-layout-content) {
  display: flex;
  flex-direction: column;
  justify-content: center;
  /*color: var(--color-white);*/
  font-size: 16px;
  font-stretch: condensed;
  text-align: center;
}

.layout :deep(.arco-layout-header),
.layout :deep(.arco-layout-footer) {
  height: 64px;
  background-color: #00bd7e;
}

.layout :deep(.arco-layout-footer) {
  background-color: transparent;
}

.layout :deep(.arco-layout-content) {
  /*background-color: goldenrod;*/
}

.flexrow,
.flexcontainer {
  /*color: var(--color-white);*/
  align-items: stretch;
  height: 100%;
  text-align: left;
}

.flexrow .arcocol {
  flex: 1 1 50%;
  padding: 20px;
  color: #181818;
}

.flexcontainer .acol {
  flex: 1 0 20%;
  /*flex-basis: 0;*/
}

.footer {
  color: hsla(160, 100%, 37%, 1);
}

</style>
