import { mergeProps as _mergeProps, createVNode as _createVNode } from "vue";
import "./styles/table.css";
import { computed, ref } from "vue";
import { convertToUnit, downloadCSV, getObjectValueByPath, throttle, useRender, wrapInArray } from "@veno-ui/utils";
import { defineComponent } from "../../utils";
import { makePaperProps, usePaper } from "../../composables/paper";
import { makeScrollbar, useScrollbar } from "../../composables/scrollbar";
import { makeDataIteratorProps, useDataIterator } from "../../composables/data-iterator";
import { Progress } from "../progress";
import { Pagination } from "../pagination";
import { Checkbox } from "../checkbox";
import { useProxiedModel } from "../../composables/proxied-model";
import { TableTh, filterTableThProps } from "./table-th";
import { TableNoData } from "./table-no-data";
const Table = defineComponent({
  name: "VeTable",
  props: {
    /**
     * @zh 隐藏边框
     */
    hideBorder: Boolean,
    /**
     * @zh 隐藏表头
     */
    hideHeader: Boolean,
    /**
     * @zh 固定表头
     */
    fixedHeader: Boolean,
    /**
     * @zh 表头
     */
    headers: {
      type: Array,
      default: () => []
    },
    /**
     * @zh 已选择的
     */
    selected: {
      type: Array,
      default: () => []
    },
    /**
     * @zh 排序的图标
     */
    sortIcon: {
      type: String,
      default: "$sort"
    },
    /**
     * @zh 排序激活时的颜色
     */
    sortActiveColor: {
      type: String,
      default: "primary"
    },
    /**
     * @zh 加载中
     */
    loading: Boolean,
    /**
     * @zh 唯一键
     */
    itemKey: {
      type: String,
      default: "id"
    },
    /**
     * @zh 隐藏分页
     */
    hidePagination: Boolean,
    ...makeDataIteratorProps(),
    ...makePaperProps({
      border: true,
      shape: "rounded-sm"
    }),
    ...makeScrollbar()
  },
  emits: {
    "update:pagination": (_) => true,
    "update:sortBy": (_) => true,
    "update:sortDesc": (_) => true,
    "update:options": (_) => true,
    "update:selected": (_) => true
  },
  setup(props, {
    slots
  }) {
    const containerRef = ref();
    const scrollLeft = ref(0);
    const selected = useProxiedModel(props, "selected");
    const isAllSelected = computed(() => {
      return selected.value.map((v) => v[props.itemKey]).sort().join("") === props.items.map((v) => v[props.itemKey]).sort().join("");
    });
    const {
      paperClasses,
      paperStyles
    } = usePaper(props, "ve-table__table");
    const {
      scrollbarClasses
    } = useScrollbar(props);
    const {
      items,
      pagination,
      sortBy: rawSortBy,
      sortDesc: rawSortDesc,
      sort,
      updateOptions
    } = useDataIterator(props);
    const headers = computed(() => {
      const length = props.headers.length;
      return props.headers.map((header, index) => {
        return {
          ...header,
          fixed: header.fixed === true ? index < (length - 1) / 2 ? "start" : "end" : header.fixed
        };
      });
    });
    const sortBy = computed(() => wrapInArray(rawSortBy.value));
    const sortDesc = computed(() => wrapInArray(rawSortDesc.value));
    const scrollPositionClasses = computed(() => {
      if (containerRef.value && scrollLeft.value === 0) {
        return "ve-table--scroll-position-start";
      } else if (containerRef.value && scrollLeft.value + containerRef.value.offsetWidth >= containerRef.value.scrollWidth) {
        return "ve-table--scroll-position-end";
      } else {
        return "ve-table--scroll-position-center";
      }
    });
    function handleScroll({
      target
    }) {
      scrollLeft.value = target.scrollLeft;
    }
    function genColProps(header) {
      const styles = {
        width: convertToUnit(header.width),
        minWidth: convertToUnit(header.minWidth ?? header.width),
        maxWidth: convertToUnit(header.maxWidth ?? header.width)
      };
      return {
        style: styles
      };
    }
    function isSortDesc(header) {
      return sortDesc.value[sortBy.value.findIndex((v) => v === header.value)];
    }
    useRender(() => {
      const hasColgroup = !slots.colgroup && props.headers.length > 0;
      const hasThead = !slots.header && !props.hideHeader && props.headers.length > 0;
      const hasTbody = !slots.default;
      const hasPagination = hasTbody && !props.hidePagination;
      return _createVNode(props.tag, {
        "class": ["ve-table", {
          "ve-table--fixed-header": props.fixedHeader
        }, scrollPositionClasses.value]
      }, {
        default: () => [_createVNode("div", {
          "ref": containerRef,
          "onScroll": throttle(handleScroll, 128),
          "class": ["ve-table__table", paperClasses.value, scrollbarClasses.value],
          "style": paperStyles.value
        }, [_createVNode("table", null, [hasColgroup && _createVNode("colgroup", null, [headers.value.map((header) => {
          return _createVNode("col", genColProps(header), null);
        })]), slots.colgroup?.(), hasThead && _createVNode("thead", null, [props.loading && _createVNode("tr", {
          "class": "ve-table__progress"
        }, [_createVNode("th", {
          "colspan": props.headers.length
        }, [_createVNode(Progress, {
          "color": "primary",
          "indeterminate": true,
          "stroke-width": 3
        }, null)])]), _createVNode("tr", null, [headers.value.map((header, index) => {
          return _createVNode(TableTh, _mergeProps(filterTableThProps(header)[0], {
            "sort-icon": props.sortIcon,
            "sort-active-color": props.sortActiveColor,
            "sort-desc": isSortDesc(header),
            "onClick": () => header.sortable && sort(header.value)
          }), {
            default: () => [header.$type === "selection" ? _createVNode(Checkbox, {
              "indeterminate": selected.value.length > 0 && !isAllSelected.value,
              "onUpdate:indeterminate": (val) => {
                if (!val) {
                  selected.value = props.items;
                }
              },
              "modelValue": isAllSelected.value,
              "onUpdate:modelValue": (val) => {
                if (val) {
                  selected.value = props.items;
                } else {
                  selected.value = [];
                }
              }
            }, null) : slots[`header.${header.value}`]?.({
              header,
              index
            }) ?? header.text ?? header.value]
          });
        })])]), slots.header?.(), hasTbody && _createVNode("tbody", null, [items.value.map((item, index) => _createVNode("tr", {
          "key": item[props.itemKey] ?? index
        }, [headers.value.map((header) => {
          return _createVNode("td", {
            "class": ["ve-table-td", {
              "ve-table-td--sorted": isSortDesc(header) !== void 0,
              "ve-table-td--fixed-start": header.fixed === "start",
              "ve-table-td--fixed-end": header.fixed === "end"
            }]
          }, [header.$type === "selection" ? _createVNode(Checkbox, {
            "modelValue": selected.value.findIndex((v) => v[props.itemKey] === item[props.itemKey]) > -1,
            "onUpdate:modelValue": (val) => {
              if (val) {
                selected.value.push(item);
              } else {
                selected.value = selected.value.filter((v) => v[props.itemKey] !== item[props.itemKey]);
              }
            }
          }, null) : slots[`item.${header.value}`]?.({
            item,
            index
          }) ?? getObjectValueByPath(item, header.value)]);
        })])), !items.value.length && _createVNode("tr", null, [_createVNode("td", {
          "colspan": props.headers.length
        }, [slots.nodata?.() ?? _createVNode(TableNoData, null, null)])])]), slots.default?.()])]), hasPagination && _createVNode(Pagination, _mergeProps({
          "class": "ve-table__pagination"
        }, pagination.value, {
          "modelValue": pagination.value.page,
          "onUpdate:modelValue": (v) => {
            pagination.value.page = v;
            updateOptions();
          },
          "onUpdate:perPage": (v) => {
            pagination.value.perPage = v;
            updateOptions();
          }
        }), null)]
      });
    });
    return {
      exportCSV(name) {
        downloadCSV(name, props.headers, items.value);
      }
    };
  }
});
export {
  Table
};
//# sourceMappingURL=table.mjs.map
