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

/** 子项默认宽度 */
const itemWidth = ref(10);
/** 父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",
    titleTooltip: "排列方向",
    list: ["row", "row-reverse", "column", "column-reverse"],
    tooltip: ["主轴为水平方向，起点在左端", "row反方向", "主轴为垂直方向，起点在上沿", "column反方向"],
    modelValue: "row"
  },
  "flex-wrap": {
    title: "flex-wrap",
    titleTooltip: "排不下，换行",
    list: ["nowrap", "wrap", "wrap-reverse"],
    tooltip: ["不换行", "换行，第一行在上方", "换行，第一行在下方"],
    modelValue: "nowrap",
  },
  "justify-content": {
    title: "justify-content",
    titleTooltip: "主轴上的对齐方式",
    list: ["flex-start", "flex-end", "center", "space-between", "space-around"],
    tooltip: ["左对齐", "右对齐", "居中", "两端对齐，项目之间的间隔都相等", "每个项目两侧的间隔相等"],
    modelValue: "flex-start",
  },
  "align-items": {
    title: "align-items",
    titleTooltip: "交叉轴上如何对齐",
    list: ["stretch", "flex-start", "flex-end", "center", "baseline"],
    tooltip: ["项目未设置高度或设为auto，将占满整个容器的高度", "交叉轴的起点对齐", "交叉轴的终点对齐", "交叉轴的中点对齐", "目的第一行文字的基线对齐"],
    modelValue: "stretch",
  },
  "align-content": {
    title: "align-content",
    titleTooltip: "多根轴线的对齐方式",
    list: [
      "stretch",
      "flex-start",
      "flex-end",
      "center",
      "space-between",
      "space-around",
    ],
    tooltip: ["轴线占满整个交叉轴", "与交叉轴的起点对齐", "与交叉轴的终点对齐", "与交叉轴的中点对齐", "与交叉轴两端对齐，轴线之间的间隔平均分布", "每根轴线两侧的间隔都相等"],
    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",
];
const itemAlignSelfTooltip = [
  "为父元素的align-items值，没有父容器，则为stretch",
  "适合容器",
  "容器的中央",
  "容器的开头",
  "容器的末端",
  "容器的基线",
];

/** 子项列表 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"] = "100%";
    flexContainerFormStyle["minHeight"] = "160px";
    flexContainerFormStyle["padding"] = "10px";
    flexContainerFormStyle["backgroundColor"] = "goldenrod";
    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 = "item-" + (index + 1);
    html += `<div class="flex-item ${itemClass}">${itemClass}</div>`;
  });
  html += `</div>`;
  fiexBoxDomHtml.value = html;
};
/** 生成CSS方法{} */
const fiexSubmitCss = () => {
  /** 增加CSS外层{} */
  const addKuohao = (css: string) => {
    return `{` + '\n' + css + '\n' + `}`;
  };

  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();
};

watch([flexContainerFormStyle, flexItemFormStyle], () => {
  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>
  <a-layout class="layout">
    <a-layout-header>
      <a-typography-title bold>CSS3 Flexbox 在线演示</a-typography-title>
    </a-layout-header>
    <a-layout-content>
      <a-row class="layout-content-box" justify="justify-content" :wrap="false" :gutter="15"
             :style="{ alignItems: 'stretch',flexGrow:1}">
        <a-col :md="12" :span="24">
          <div class="mainContent">
            <a-typography-title :heading="4" bold>子项宽度</a-typography-title>
            <a-space fill size="medium" class="itemWidth">
              <a-typography-text>宽度</a-typography-text>
              <a-input-number
                  :style="{ width: '80px' }"
                  :min="10"
                  :max="100"
                  v-model="itemWidth">
                <template #suffix>%</template>
              </a-input-number>
              <a-slider
                  v-model="itemWidth"
                  :min="10"
                  :max="100"
                  :step="1"
                  show-ticks
              />
            </a-space>
            <a-typography-title :heading="4" bold>父Flex属性–Flex容器</a-typography-title>
            <a-row justify="justify-content" :wrap="false">
              <a-col
                  class="containerCol"
                  v-for="(item, key) in flexContainerList"
                  :key="key"
              >
                <a-typography-title :heading="6" bold>
                  <a-tooltip
                      :content="item.titleTooltip"
                      background-color="goldenrod"
                      mini>
                    <strong>{{ item.title }}</strong>
                  </a-tooltip>
                </a-typography-title>
                <a-radio-group
                    direction="vertical"
                    v-model="flexContainerForm[key]"
                >
                  <a-tooltip
                      v-for="(value, keys) in item.list"
                      :key="keys"
                      :content="item.tooltip[keys]"
                      background-color="#00bd7e"
                      mini
                  >
                    <a-radio :value="value">
                      {{ value }}
                    </a-radio>
                  </a-tooltip>
                </a-radio-group>
              </a-col>
            </a-row>
            <a-button
                @click="fiexSubmit"
                :style="{margin:'1em 0'}"
                type="primary"
                status="success" long>
              生成
            </a-button>
            <div class="mainContentBox">
              <a-split :style="{
                          height: '100%',
                          width: '100%',
                          backgroundColor:'var(--color-neutral-2)',
                          maxHeight:'358px'
                        }">
                <template #first>
                  <a-split direction="vertical" :style="{height: '99.9%'}">
                    <template #first>
                      <a-typography-paragraph copyable>
                        <highlightjs language="html" :autodetect="false" :code="fiexBoxDomHtml"></highlightjs>
                      </a-typography-paragraph>
                    </template>
                    <template #second>
                      <a-typography-paragraph copyable>
                        <highlightjs language="css" :autodetect="false" :code="fiexBoxCssString"></highlightjs>
                      </a-typography-paragraph>
                    </template>
                  </a-split>
                </template>
                <template #second>
                  <a-typography-paragraph copyable>
                    <highlightjs language="css" :autodetect="false" :code="fiexItemCssString"></highlightjs>
                  </a-typography-paragraph>
                </template>
              </a-split>
            </div>
          </div>

        </a-col>
        <a-col :md="12" :span="24">
          <div class="mainContent">
            <a-typography-title :heading="4" bold>
              实现效果
              <a-button
                  type="primary"
                  @click="addItem"
                  :style="{ float: 'right' }"
              >
                <template #icon>
                  <icon-plus/>
                </template>
                新增子项
              </a-button>
            </a-typography-title>
            <div class="mainContentBox">
              <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"
                          :header-style="{backgroundColor:'azure',fontWeight:'bold'}">
                    <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：排列顺序，数值越小，排列越靠前" mini>
                          <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：项目的放大比例" mini>
                          <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：项目的缩小比例" mini>
                          <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：计算主轴是否有多余空间，设为跟width或height属性一样的值，将占据固定空间"
                            mini>
                          <a-input
                              v-model="flexItemForm[indexKey]['flex-basis']"
                              allow-clear
                          />
                        </a-tooltip>
                      </a-list-item>
                      <a-list-item>
                        <a-tooltip content="align-self：单个项目有与其他项目不一样的对齐方式，覆盖align-items属性"
                                   mini>
                          <a-select
                              v-model="flexItemForm[indexKey]['align-self']"
                          >
                            <a-tooltip
                                v-for="(ivalue,ikeys) in itemAlignSelf"
                                :key="ikeys"
                                :content="itemAlignSelfTooltip[ikeys]"
                                mini
                                background-color="#00bd7e">
                              <a-option>
                                {{ ivalue }}
                              </a-option>
                            </a-tooltip>
                          </a-select>
                        </a-tooltip>
                      </a-list-item>
                    </a-list>
                  </a-card>
                </div>
              </div>
            </div>
          </div>
        </a-col>
      </a-row>
    </a-layout-content>
    <a-layout-footer ref="showTimeDom">
      <a-divider :margin="10" :size="2">
        <icon-heart/>
      </a-divider>
      <a-row class="footer" :gutter="24">
        <a-col :span="12">
          <a-typography-text type="success">{{ showTime }}</a-typography-text>
        </a-col>
        <a-col :span="12">
          <a-typography-text type="success">
            Copyright © 2015-{{ showTimeYear }}
            <a-link target="_blank" href="https://beian.miit.gov.cn/" status="success" rel="noopener">鲁ICP备10001546号
            </a-link>
          </a-typography-text>
        </a-col>
      </a-row>

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

<style lang="less" scoped>
.arco-layout {
  height: 100vh;

  .arco-layout-header,
  .arco-layout-footer,
  .arco-layout-content {
    display: flex;
    /*垂直排列*/
    flex-direction: column;
    justify-content: center;
    font-stretch: condensed;
    text-align: center;
    padding: 15px;
  }

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

  //头部
  :deep(.arco-layout-header) {
    .arco-typography {
      margin: 0;
    }
  }

  //底部
  .arco-layout-footer {
    background-color: transparent;

    .arco-link {
      font-size: initial;
    }
  }
}

//内容
.arco-layout :deep(.arco-layout-content) {
  text-align: left;
  height: calc(100vh - 64px - 64px);
  padding-top: 0;

  .layout-content-box {
    .itemWidth .arco-space-item:last-child {
      flex-grow: 1;

      .arco-slider-ticks .arco-slider-tick {
        margin-top: 5px;
      }
    }

    .containerCol {
      flex: 1 0 20%;
      width: 20%;
      flex-basis: 0;
    }

    .mainContent {
      display: flex;
      flex-direction: column;
      height: 100%;

      .mainContentBox {
        flex-grow: 1;

        pre {
          white-space: normal;

          code {
            background: #23241f;
            color: #f8f8f2;
            //padding: 10px;
            border: none;
          }
        }


        .flexbox {
          min-height: 300px;

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

            .arco-card {
              background: transparent;

              .arco-card-body {
                padding: 5px;

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

                .arco-list-bordered {
                  border: none;

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

      }
    }
  }
}


@media (max-width: 768px) {
  .arco-layout :deep(.arco-layout-content) {
    height: auto;

    .layout-content-box {
      flex-wrap: nowrap;
    }
  }
}

</style>
