"use strict";
const vue = require("vue");
const classes = require("./classes-DA6TfAZg.js");
const useAlignment = require("./useAlignment-BKpl8Nif.js");
const useDefaults = require("./useDefaults-YXpmugKp.js");
const constants = require("./constants-DxId_i-P.js");
const event = require("./event-BbcvB460.js");
const dom = require("./dom-BgEUZpKg.js");
require("./BootstrapVueOptions-B17IcLXU.js");
const index = require("./index-JJEBhaXq.js");
const _hoisted_1 = ["aria-disabled", "aria-label"];
const _hoisted_2 = ["displayIndex"];
const DEFAULT_PER_PAGE = 20;
const DEFAULT_TOTAL_ROWS = 0;
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  __name: "BPagination",
  props: /* @__PURE__ */ vue.mergeModels({
    align: { default: "start" },
    ariaControls: { default: void 0 },
    ariaLabel: { default: "Pagination" },
    disabled: { type: Boolean, default: false },
    ellipsisClass: { default: void 0 },
    ellipsisText: { default: "…" },
    firstClass: { default: void 0 },
    firstNumber: { type: Boolean, default: false },
    firstText: { default: "«" },
    noEllipsis: { type: Boolean, default: false },
    noGotoEndButtons: { type: Boolean, default: false },
    labelFirstPage: { default: "Go to first page" },
    labelLastPage: { default: "Go to last page" },
    labelNextPage: { default: "Go to next page" },
    labelPage: { default: "Go to page" },
    labelPrevPage: { default: "Go to previous page" },
    lastClass: { default: void 0 },
    lastNumber: { type: Boolean, default: false },
    lastText: { default: "»" },
    limit: { default: 5 },
    nextClass: { default: void 0 },
    nextText: { default: "›" },
    pageClass: { default: void 0 },
    perPage: { default: DEFAULT_PER_PAGE },
    pills: { type: Boolean, default: false },
    prevClass: { default: void 0 },
    prevText: { default: "‹" },
    size: { default: void 0 },
    totalRows: { default: DEFAULT_TOTAL_ROWS }
  }, {
    "modelValue": {
      default: 1
    },
    "modelModifiers": {}
  }),
  emits: /* @__PURE__ */ vue.mergeModels(["page-click"], ["update:modelValue"]),
  setup(__props, { emit: __emit }) {
    const ELLIPSIS_THRESHOLD = 3;
    const FIRST_BUTTON = -1;
    const PREV_BUTTON = -2;
    const NEXT_BUTTON = -3;
    const LAST_BUTTON = -4;
    const FIRST_ELLIPSIS = -5;
    const LAST_ELLIPSIS = -6;
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BPagination");
    const emit = __emit;
    const modelValue = vue.useModel(__props, "modelValue");
    const pageElements = vue.useTemplateRef("_pageElements");
    const limitNumber = index.useToNumber(() => props.limit, { nanToZero: true, method: "parseInt" });
    const perPageNumber = index.useToNumber(() => props.perPage, { nanToZero: true, method: "parseInt" });
    const totalRowsNumber = index.useToNumber(() => props.totalRows, { nanToZero: true, method: "parseInt" });
    const modelValueNumber = index.useToNumber(modelValue, { nanToZero: true, method: "parseInt" });
    const perPageSanitized = vue.computed(() => Math.max(perPageNumber.value || DEFAULT_PER_PAGE, 1));
    const totalRowsSanitized = vue.computed(() => Math.max(totalRowsNumber.value || DEFAULT_TOTAL_ROWS, 0));
    const numberOfPages = vue.computed(() => Math.ceil(totalRowsSanitized.value / perPageSanitized.value));
    const computedFill = vue.computed(() => props.align === "fill");
    const justifyAlign = vue.computed(() => props.align === "fill" ? "start" : props.align);
    const alignment = useAlignment.useAlignment(justifyAlign);
    const isActivePage = (pageNumber) => pageNumber === computedModelValue.value;
    const getTabIndex = (num) => props.disabled ? null : isActivePage(num) ? "0" : "-1";
    const checkDisabled = (num) => props.disabled || isActivePage(num) || computedModelValue.value < 1 || // Check if the number is out of bounds
    num < 1 || num > numberOfPages.value;
    const firstDisabled = vue.computed(() => checkDisabled(1));
    const prevDisabled = vue.computed(() => checkDisabled(computedModelValue.value - 1));
    const lastDisabled = vue.computed(() => checkDisabled(numberOfPages.value));
    const nextDisabled = vue.computed(() => checkDisabled(computedModelValue.value + 1));
    const getBaseButtonProps = ({
      page,
      classVal,
      disabled,
      slotName,
      textValue,
      tabIndex,
      label,
      position,
      isActive,
      hidden,
      isSmHidden
    }) => ({
      li: {
        "class": [
          "page-item",
          {
            "active": isActive,
            disabled,
            "bv-d-sm-down-none": isSmHidden,
            "flex-fill": computedFill.value,
            "d-flex": computedFill.value && !disabled
          },
          classVal
        ],
        "role": "presentation",
        "aria-hidden": hidden
      },
      button: {
        "is": disabled ? "span" : "button",
        "class": ["page-link", "text-center", { "flex-grow-1": !disabled && computedFill.value }],
        "aria-label": label,
        "aria-controls": props.ariaControls || void 0,
        "aria-disabled": disabled ? true : void 0,
        "aria-posinset": position,
        "aria-setsize": position ? numberOfPages.value : void 0,
        "role": "menuitem",
        "type": disabled ? void 0 : "button",
        "tabindex": disabled ? void 0 : tabIndex
      },
      text: {
        name: slotName,
        active: isActive,
        value: textValue ?? page,
        page,
        disabled,
        index: page - 1,
        content: textValue ? void 0 : String(page)
      },
      clickHandler: (e) => pageClick(e, page)
    });
    const getButtonProps = ({
      page,
      classVal,
      disabled,
      slotName,
      textValue,
      label
    }) => getBaseButtonProps({ page, classVal, disabled, slotName, textValue, label, tabIndex: "-1" });
    const getPageButtonProps = (page, isSmHidden) => getBaseButtonProps({
      page,
      disabled: props.disabled,
      classVal: props.pageClass,
      slotName: "page",
      label: props.labelPage ? `${props.labelPage} ${page}` : void 0,
      tabIndex: getTabIndex(page) ?? void 0,
      position: page,
      isActive: isActivePage(page),
      isSmHidden
    });
    const firstButtonProps = vue.computed(
      () => getButtonProps({
        page: 1,
        disabled: firstDisabled.value,
        classVal: props.firstClass,
        slotName: "first-text",
        textValue: props.firstText,
        label: props.labelFirstPage
      })
    );
    const prevButtonProps = vue.computed(
      () => getButtonProps({
        page: Math.max(computedModelValue.value - 1, 1),
        disabled: prevDisabled.value,
        classVal: props.prevClass,
        slotName: "prev-text",
        textValue: props.prevText,
        label: props.labelPrevPage
      })
    );
    const nextButtonProps = vue.computed(
      () => getButtonProps({
        page: Math.min(computedModelValue.value + 1, numberOfPages.value),
        disabled: nextDisabled.value,
        classVal: props.nextClass,
        slotName: "next-text",
        textValue: props.nextText,
        label: props.labelNextPage
      })
    );
    const lastButtonProps = vue.computed(
      () => getButtonProps({
        page: numberOfPages.value,
        disabled: lastDisabled.value,
        classVal: props.lastClass,
        slotName: "last-text",
        textValue: props.lastText,
        label: props.labelLastPage
      })
    );
    const ellipsisProps = vue.computed(() => ({
      li: {
        class: [
          "page-item",
          "disabled",
          "text-center",
          "bv-d-sm-down-none",
          computedFill.value ? "flex-fill" : "",
          props.ellipsisClass
        ],
        role: "separator"
      },
      span: {
        class: ["page-link"]
      }
    }));
    const computedWrapperClasses = vue.computed(() => [
      alignment.value,
      {
        [`pagination-${props.size}`]: props.size !== void 0,
        "b-pagination-pills": props.pills
      }
    ]);
    const pagination = vue.computed(() => ({
      pageSize: perPageSanitized.value,
      totalRows: totalRowsNumber.value,
      numberOfPages: numberOfPages.value
    }));
    const pageClick = (event2, pageNumber) => {
      if (pageNumber === computedModelValue.value) return;
      const clickEvent = new classes.BvEvent("page-click", {
        cancelable: true,
        target: event2.target
      });
      emit("page-click", clickEvent, pageNumber);
      if (clickEvent.defaultPrevented) return;
      modelValue.value = pageNumber;
      vue.nextTick(() => {
        if (pageNumber === 1) {
          focusFirst();
        } else if (pageNumber === pagination.value.numberOfPages) {
          focusLast();
        }
      });
    };
    const isDisabled = (el) => {
      const isElement = !!(el && el.nodeType === Node.ELEMENT_NODE);
      const hasAttr = isElement ? el.hasAttribute("disabled") : null;
      const hasClass = isElement && el.classList ? el.classList.contains("disabled") : false;
      return !isElement || el.disabled || hasAttr || hasClass;
    };
    const getButtons = () => [...pageElements.value ?? []].sort(
      (a, b) => Number.parseInt(a.getAttribute("displayIndex") || "0") - Number.parseInt(b.getAttribute("displayIndex") || "0")
    ).map((page) => page.children[0]).filter((el) => {
      if (el.getAttribute("display") === "none" || el.tagName.toUpperCase() !== "BUTTON") {
        return false;
      }
      const bcr = el.getBoundingClientRect();
      return !!(bcr && bcr.height > 0 && bcr.width > 0);
    }).map((el) => el);
    const focusFirst = () => {
      vue.nextTick(() => {
        const btn = getButtons().find((el) => !isDisabled(el));
        btn?.focus();
      });
    };
    const focusPrev = () => {
      vue.nextTick(() => {
        const buttons = getButtons();
        const index2 = buttons.indexOf(dom.getActiveElement());
        if (index2 > 0 && !isDisabled(buttons[index2 - 1])) {
          buttons[index2 - 1]?.focus();
        }
      });
    };
    const focusLast = () => {
      vue.nextTick(() => {
        const btn = getButtons().reverse().find((el) => !isDisabled(el));
        btn?.focus();
      });
    };
    const focusNext = () => {
      vue.nextTick(() => {
        const buttons = getButtons();
        const index2 = buttons.indexOf(dom.getActiveElement());
        if (index2 < buttons.length - 1 && !isDisabled(buttons[index2 + 1])) {
          buttons[index2 + 1]?.focus();
        }
      });
    };
    const handleKeyNav = (event$1) => {
      const { code, shiftKey } = event$1;
      if (code === constants.CODE_LEFT || code === constants.CODE_UP) {
        event.stopEvent(event$1);
        if (shiftKey) {
          focusFirst();
        } else {
          focusPrev();
        }
      } else if (code === constants.CODE_RIGHT || code === constants.CODE_DOWN) {
        event.stopEvent(event$1);
        if (shiftKey) {
          focusLast();
        } else {
          focusNext();
        }
      }
    };
    const computedModelValue = vue.computed(() => {
      const page = modelValueNumber.value || 1;
      return page > numberOfPages.value ? numberOfPages.value : page < 1 ? 1 : page;
    });
    vue.watch(pagination, (oldValue, newValue) => {
      if (newValue.pageSize !== oldValue.pageSize && newValue.totalRows === oldValue.totalRows) {
        modelValue.value = 1;
      }
    });
    const noFirstButton = vue.computed(() => props.noGotoEndButtons && !props.firstNumber ? 1 : 0);
    const noLastButton = vue.computed(() => props.noGotoEndButtons && !props.lastNumber ? 1 : 0);
    const showFirstButton = vue.computed(() => noFirstButton.value ? 0 : 1);
    const showLastButton = vue.computed(() => noLastButton.value ? 0 : 1);
    const firstPage = vue.computed(() => props.firstNumber ? 1 : 0);
    const lastPage = vue.computed(() => props.lastNumber ? 1 : 0);
    const halfLimit = vue.computed(() => Math.floor(limitNumber.value / 2));
    const pages = vue.computed(() => {
      const { value } = computedModelValue;
      const els = elements.value.map((p) => {
        switch (p) {
          case FIRST_BUTTON:
            return { id: p, ...firstButtonProps.value };
          case PREV_BUTTON:
            return { id: p, ...prevButtonProps.value };
          case NEXT_BUTTON:
            return { id: p, ...nextButtonProps.value };
          case LAST_BUTTON:
            return { id: p, ...lastButtonProps.value };
          case FIRST_ELLIPSIS:
          case LAST_ELLIPSIS:
            return { id: p, ...ellipsisProps.value };
          default:
            return { id: p, ...getPageButtonProps(p) };
        }
      });
      if (numberOfPages.value > 3) {
        if (value > numberOfPages.value - halfLimit.value - lastPage.value) {
          const idx = 2 + showFirstButton.value;
          els[idx] = { id: els[idx].id, ...getPageButtonProps(els[idx].id, true) };
        }
        if (value <= halfLimit.value + firstPage.value) {
          const idx = els.length - (3 + showLastButton.value);
          els[idx] = { id: els[idx].id, ...getPageButtonProps(els[idx].id, true) };
        }
      }
      return els;
    });
    const elements = vue.computed(() => {
      const pages2 = numberOfPages.value;
      const { value } = computedModelValue;
      const limit = limitNumber.value;
      const noEllipsis = props.noEllipsis || limit <= ELLIPSIS_THRESHOLD;
      if (pages2 < limit + firstPage.value + lastPage.value) {
        return [
          !firstPage.value && !noFirstButton.value ? FIRST_BUTTON : null,
          PREV_BUTTON,
          ...Array.from({ length: pages2 }, (_, index2) => index2 + 1),
          NEXT_BUTTON,
          !lastPage.value && !noLastButton.value ? LAST_BUTTON : null
        ].filter((x) => x !== null);
      }
      const buttons = Array.from({ length: limit + 4 - (noFirstButton.value + noLastButton.value) });
      if (!noFirstButton.value) {
        if (!firstPage.value) {
          buttons[0] = FIRST_BUTTON;
          buttons[1] = PREV_BUTTON;
        } else {
          buttons[0] = PREV_BUTTON;
          buttons[1] = 1;
        }
      } else {
        buttons[0] = PREV_BUTTON;
      }
      if (!noLastButton.value) {
        if (!lastPage.value) {
          buttons[buttons.length - 1] = LAST_BUTTON;
          buttons[buttons.length - 2] = NEXT_BUTTON;
        } else {
          buttons[buttons.length - 1] = NEXT_BUTTON;
          buttons[buttons.length - 2] = pages2;
        }
      } else {
        buttons[buttons.length - 1] = NEXT_BUTTON;
      }
      if (value <= halfLimit.value + firstPage.value) {
        for (let index2 = 1; index2 <= limit; index2++) {
          buttons[index2 + 1 - noFirstButton.value] = index2 + firstPage.value;
        }
        if (!noEllipsis) {
          buttons[buttons.length - (2 + showLastButton.value)] = LAST_ELLIPSIS;
        }
      }
      if (value > pages2 - halfLimit.value - lastPage.value) {
        const start = pages2 - (limit - 1) - lastPage.value;
        for (let index2 = 0; index2 < limit; index2++) {
          buttons[index2 + 2 - noFirstButton.value] = start + index2;
        }
        if (!noEllipsis) {
          buttons[1 + showFirstButton.value] = FIRST_ELLIPSIS;
        }
      }
      if (!buttons[2]) {
        const start = value - Math.floor(limit / 2);
        for (let index2 = 0; index2 < limit; index2++) {
          buttons[index2 + 2 - noFirstButton.value] = start + index2;
        }
        if (!noEllipsis) {
          buttons[1 + showFirstButton.value] = FIRST_ELLIPSIS;
          buttons[buttons.length - (2 + showLastButton.value)] = LAST_ELLIPSIS;
        }
      }
      return buttons.filter((x) => x !== null);
    });
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createElementBlock("ul", {
        class: vue.normalizeClass(["pagination", computedWrapperClasses.value]),
        role: "menubar",
        "aria-disabled": vue.unref(props).disabled,
        "aria-label": vue.unref(props).ariaLabel || void 0,
        onKeydown: handleKeyNav
      }, [
        (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(pages.value, (page, index2) => {
          return vue.openBlock(), vue.createElementBlock("li", vue.mergeProps({
            key: `page-${page.id}`
          }, { ref_for: true }, page.li, {
            ref_for: true,
            ref: "_pageElements",
            displayIndex: index2
          }), [
            page.id === FIRST_ELLIPSIS || page.id === LAST_ELLIPSIS ? (vue.openBlock(), vue.createElementBlock("span", vue.mergeProps({
              key: 0,
              ref_for: true
            }, ellipsisProps.value.span), [
              vue.renderSlot(_ctx.$slots, "ellipsis-text", {}, () => [
                vue.createTextVNode(vue.toDisplayString(vue.unref(props).ellipsisText || "..."), 1)
              ])
            ], 16)) : "button" in page ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(page.button.is), vue.mergeProps({
              key: 1,
              ref_for: true
            }, page.button, {
              onClick: page.clickHandler
            }), {
              default: vue.withCtx(() => [
                vue.renderSlot(_ctx.$slots, page.text.name, {
                  disabled: page.text.disabled,
                  page: page.text.page,
                  index: page.text.index,
                  active: page.text.active ?? false,
                  content: page.text.value
                }, () => [
                  vue.createTextVNode(vue.toDisplayString(page.text.value), 1)
                ])
              ]),
              _: 2
            }, 1040, ["onClick"])) : vue.createCommentVNode("", true)
          ], 16, _hoisted_2);
        }), 128))
      ], 42, _hoisted_1);
    };
  }
});
exports._sfc_main = _sfc_main;
//# sourceMappingURL=BPagination.vue_vue_type_script_setup_true_lang-CQ3cScCU.js.map
