UNPKG

@vuesax-alpha/nightly

Version:
337 lines (334 loc) • 11.4 kB
import { defineComponent, getCurrentInstance, computed, ref, watch, provide, h } from 'vue'; import '../../../utils/index.mjs'; import '../../../hooks/index.mjs'; import '../../../tokens/index.mjs'; import { ChevronLeft, ChevronRight } from '@vuesax-alpha/icons-vue'; import Next from './components/next.mjs'; import Prev from './components/prev2.mjs'; import Sizes from './components/sizes2.mjs'; import Jumper from './components/jumper2.mjs'; import Total from './components/total.mjs'; import Pager from './components/pager2.mjs'; import { buildProps, definePropType } from '../../../utils/vue/props/runtime.mjs'; import { useColorProp } from '../../../hooks/use-common-props/index.mjs'; import { isNumber } from '../../../utils/types.mjs'; import { mutable } from '../../../utils/typescript.mjs'; import { iconPropType } from '../../../utils/vue/icon.mjs'; import { useNamespace } from '../../../hooks/use-namespace/index.mjs'; import { paginationContextKey } from '../../../tokens/pagination.mjs'; import { debugWarn } from '../../../utils/error.mjs'; import { getVsColor } from '../../../utils/color.mjs'; const isAbsent = (v) => typeof v !== "number"; const paginationProps = buildProps({ color: useColorProp, total: { type: Number }, defaultCurrentPage: { type: Number }, currentPage: { type: Number }, defaultPageSize: { type: Number }, pageSize: { type: Number }, pageCount: { type: Number }, pagerCount: { type: Number, validator: (value) => { return isNumber(value) && Math.trunc(value) === value && value > 4 && value < 22 && value % 2 === 1; }, default: 7 }, layout: { type: definePropType([String, Array]), default: () => mutable([ "prev", "pager", "next", "jumper", "->", "total", "slot", "sizes" ]) }, pageSizes: { type: definePropType(Array), default: () => mutable([10, 20, 30, 40, 50, 100]) }, hideOnSinglePage: { type: Boolean }, prevText: { type: String, default: "" }, prevIcon: { type: iconPropType, default: () => ChevronLeft }, nextText: { type: String, default: "" }, nextIcon: { type: iconPropType, default: () => ChevronRight }, infinite: { type: Boolean, default: false }, progress: { type: Boolean }, notMargin: { type: Boolean }, buttonsDotted: { type: Boolean, default: false }, shape: { type: String, values: ["circle", "square"], default: "" }, disabled: { type: Boolean, default: false }, disabledItems: { type: definePropType(Array), default: () => [] }, loadingItems: { type: definePropType(Array), default: () => [] } }); const paginationEmits = { "update:current-page": (val) => isNumber(val), "update:page-size": (val) => isNumber(val), "size-change": (val) => isNumber(val), "page-change": (val) => isNumber(val), "prev-click": (val) => isNumber(val), "next-click": (val) => isNumber(val) }; const COMPONENT_NAME = "VsPagination"; var Pagination = defineComponent({ name: COMPONENT_NAME, props: paginationProps, emits: paginationEmits, setup(props, { emit, slots }) { const ns = useNamespace("pagination"); const vnodeProps = getCurrentInstance().vnode.props || {}; const hasCurrentPageListener = "onUpdate:currentPage" in vnodeProps || "onUpdate:current-page" in vnodeProps || "onCurrentChange" in vnodeProps; const hasPageSizeListener = "onUpdate:pageSize" in vnodeProps || "onUpdate:page-size" in vnodeProps || "onSizeChange" in vnodeProps; const assertValidUsage = computed(() => { if (isAbsent(props.total) && isAbsent(props.pageCount)) return "need to set props `total` or `pageCount`, otherwise count of pages cannot be determined."; if (!isAbsent(props.currentPage) && !hasCurrentPageListener) return "You have to use v-model binding of `currentPage`.\nIf you just want to provide a default value, `defaultCurrentPage` is here for you."; if (props.layout.includes("sizes")) { if (!isAbsent(props.pageCount)) { if (!hasPageSizeListener) return "Your layout having `sizes`. If `pageCount` is assign, then you have to watch `pageSize` change and recalculate `pageCount`."; } else if (!isAbsent(props.total)) { if (!isAbsent(props.pageSize)) { if (!hasPageSizeListener) { return "Your layout having `sizes`. If you have `pageSize` defined, meaning you want to have `pageSize` controlled yourself from component. Thus page size `listener` is required, you are account for `pageSize` changed."; } } else { } } } return true; }); const innerPageSize = ref( isAbsent(props.defaultPageSize) ? 10 : props.defaultPageSize ); const innerCurrentPage = ref( isAbsent(props.defaultCurrentPage) ? 1 : props.defaultCurrentPage ); const pageSizeBridge = computed({ get() { return isAbsent(props.pageSize) ? innerPageSize.value : props.pageSize; }, set(v) { if (isAbsent(props.pageSize)) { innerPageSize.value = v; } if (hasPageSizeListener) { emit("update:page-size", v); emit("size-change", v); } } }); const pageCountBridge = computed(() => { let pageCount = 0; if (!isAbsent(props.pageCount)) { pageCount = props.pageCount; } else if (!isAbsent(props.total)) { pageCount = Math.max(1, Math.ceil(props.total / pageSizeBridge.value)); } return pageCount; }); const currentPageBridge = computed({ get() { return isAbsent(props.currentPage) ? innerCurrentPage.value : props.currentPage; }, set(v) { let newCurrentPage = v; if (v < 1) { newCurrentPage = props.infinite ? pageCountBridge.value : 1; } else if (v > pageCountBridge.value) { newCurrentPage = props.infinite ? 1 : pageCountBridge.value; } if (isAbsent(props.currentPage)) { innerCurrentPage.value = newCurrentPage; } if (hasCurrentPageListener) { emit("update:current-page", newCurrentPage); emit("page-change", newCurrentPage); } } }); watch(currentPageBridge, (newValue, oldValue) => { if (isPagerDisabled(newValue) || isPagerLoading(newValue)) { let newVal = newValue; if (newValue > oldValue) { newVal += 1; } else { newVal -= 1; } if (newVal > pageCountBridge.value) { newVal = props.infinite ? 1 : oldValue; } else if (newVal <= 0) { newVal = props.infinite ? pageCountBridge.value : newValue + 1; } currentPageBridge.value = newVal; } }); watch(pageCountBridge, (val) => { if (currentPageBridge.value > val) currentPageBridge.value = val; }); const isPagerLoading = (pager = Number.NaN) => props.loadingItems.includes(pager); const isPagerDisabled = (pager = Number.NaN) => props.disabled || props.disabledItems.includes(pager); function handleCurrentChange(val) { currentPageBridge.value = val; } function handleSizeChange(val) { pageSizeBridge.value = val; const newPageCount = pageCountBridge.value; if (currentPageBridge.value > newPageCount) { currentPageBridge.value = newPageCount; } } function prev() { if (props.disabled) return; currentPageBridge.value -= 1; emit("prev-click", currentPageBridge.value); } function next() { if (props.disabled) return; currentPageBridge.value += 1; emit("next-click", currentPageBridge.value); } function addClass(element, cls) { if (element) { if (!element.props) { element.props = {}; } element.props.class = [element.props.class, cls].join(" "); } } provide(paginationContextKey, { pageCount: pageCountBridge, disabled: computed(() => props.disabled), currentPage: currentPageBridge, buttonsDotted: computed(() => props.buttonsDotted), infinite: computed(() => props.infinite), loadingItems: computed(() => props.loadingItems), disabledItems: computed(() => props.disabledItems), isPagerDisabled, isPagerLoading, changeEvent: handleCurrentChange, handleSizeChange }); return () => { var _a, _b; if (assertValidUsage.value != true) { debugWarn(COMPONENT_NAME, assertValidUsage.value); return null; } if (!props.layout.length) return null; if (props.hideOnSinglePage && pageCountBridge.value <= 1) return null; const rootChildren = []; const rightWrapperChildren = []; const rightWrapperRoot = h( "div", { class: ns.e("rightwrapper") }, rightWrapperChildren ); const TEMPLATE_MAP = { prev: h(Prev, { prevText: props.prevText, prevIcon: props.prevIcon, onClick: prev }), jumper: h(Jumper), pager: h(Pager, { color: props.color, progress: props.progress, pagerCount: props.pagerCount, onChange: handleCurrentChange }), next: h(Next, { nextText: props.nextText, nextIcon: props.nextIcon, onClick: next }), sizes: h(Sizes, { pageSize: pageSizeBridge.value, pageSizes: props.pageSizes }), slot: (_b = (_a = slots == null ? void 0 : slots.default) == null ? void 0 : _a.call(slots, { currentPage: currentPageBridge.value, total: props.total, pageSize: pageSizeBridge.value, pageSizes: props.pageSizes, pagerCount: props.pagerCount })) != null ? _b : null, total: h(Total, { total: isAbsent(props.total) ? 0 : props.total }) }; const components = props.layout.toString().split(",").map((item) => item.trim()); let haveRightWrapper = false; components.forEach((c) => { if (c === "->") { haveRightWrapper = true; return; } if (!haveRightWrapper) { rootChildren.push(TEMPLATE_MAP[c]); } else { rightWrapperChildren.push(TEMPLATE_MAP[c]); } }); addClass(rootChildren[0], ns.is("first")); addClass(rootChildren[rootChildren.length - 1], ns.is("last")); if (haveRightWrapper && rightWrapperChildren.length > 0) { addClass(rightWrapperChildren[0], ns.is("first")); addClass( rightWrapperChildren[rightWrapperChildren.length - 1], ns.is("last") ); rootChildren.push(rightWrapperRoot); } return h( "div", { role: "pagination", "aria-label": "pagination", class: [ ns.b(), ns.is(props.shape), ns.is("buttons-dotted", props.buttonsDotted), ns.is("not-margin", props.notMargin) ], style: ns.cssVar({ color: getVsColor(props.color) }) }, rootChildren ); }; } }); export { Pagination as default, paginationEmits, paginationProps }; //# sourceMappingURL=pagination.mjs.map