UNPKG

@varlet/ui

Version:

A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.

224 lines (223 loc) • 7.53 kB
var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; import { computed, defineComponent, onActivated, onBeforeUnmount, onDeactivated, ref, watch } from "vue"; import { call, doubleRaf, getRect, getScrollLeft, getScrollTop, isPlainObject, requestAnimationFrame, toNumber } from "@varlet/shared"; import { onSmartMounted } from "@varlet/use"; import { createNamespace } from "../utils/components.mjs"; import { getParentScroller, toPxNum, scrollTo as varScrollTo } from "../utils/elements.mjs"; import { easeInOutCubic } from "../utils/shared.mjs"; import { props } from "./props.mjs"; import { useIndexAnchors } from "./provide.mjs"; const { name, n, classes } = createNamespace("index-bar"); import { renderSlot as _renderSlot, renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, normalizeClass as _normalizeClass, normalizeStyle as _normalizeStyle, createElementVNode as _createElementVNode } from "vue"; const _hoisted_1 = ["onClick"]; function __render__(_ctx, _cache) { return _openBlock(), _createElementBlock( "div", { ref: "barEl", class: _normalizeClass(_ctx.n()) }, [ _renderSlot(_ctx.$slots, "default"), _createElementVNode( "ul", { class: _normalizeClass(_ctx.n("anchor-list")), style: _normalizeStyle({ zIndex: _ctx.toNumber(_ctx.zIndex) + 2, display: _ctx.hideList ? "none" : "block" }) }, [ (_openBlock(true), _createElementBlock( _Fragment, null, _renderList(_ctx.anchorNameList, (anchorName) => { return _openBlock(), _createElementBlock("li", { key: anchorName, class: _normalizeClass(_ctx.classes(_ctx.n("anchor-item"), [_ctx.active === anchorName, _ctx.n("anchor-item--active")])), style: _normalizeStyle({ color: _ctx.active === anchorName && _ctx.highlightColor ? _ctx.highlightColor : void 0 }), onClick: ($event) => _ctx.anchorClick({ anchorName, manualCall: true }) }, [ _renderSlot(_ctx.$slots, "anchor-name", { anchorName }, () => [ _createTextVNode( _toDisplayString(anchorName), 1 /* TEXT */ ) ]) ], 14, _hoisted_1); }), 128 /* KEYED_FRAGMENT */ )) ], 6 /* CLASS, STYLE */ ) ], 2 /* CLASS */ ); } const __sfc__ = defineComponent({ name, props, setup(props2) { const clickedName = ref(""); const barEl = ref(null); const anchorNameList = ref([]); const active = ref(); const sticky = computed(() => props2.sticky); const cssMode = computed(() => props2.stickyCssMode); const stickyOffsetTop = computed(() => toPxNum(props2.stickyOffsetTop)); const zIndex = computed(() => props2.zIndex); const { length, indexAnchors, bindIndexAnchors } = useIndexAnchors(); let scroller = null; let isDeactivated = false; const indexBarProvider = { active, sticky, cssMode, stickyOffsetTop, zIndex }; watch( () => length.value, () => __async(this, null, function* () { yield doubleRaf(); anchorNameList.value = indexAnchors.filter(({ name: name2 }) => name2.value != null).map(({ name: name2 }) => name2.value); }) ); onSmartMounted(setupScroller); onBeforeUnmount(removeScrollerListener); onDeactivated(() => { isDeactivated = true; removeScrollerListener(); }); onActivated(() => { if (!isDeactivated || active.value === void 0) { return; } anchorClick({ anchorName: active.value, options: { event: false } }); isDeactivated = false; }); bindIndexAnchors(indexBarProvider); function emitEvent(anchor, options) { const anchorName = isPlainObject(anchor) ? anchor.name.value : anchor; if (anchorName === active.value || anchorName === void 0) { return; } active.value = anchorName; if ((options == null ? void 0 : options.event) !== false) { call(props2.onChange, anchorName); } } function getOffsetTop() { const { top: parentTop } = getRect(scroller); const { top: targetTop } = getRect(barEl.value); const scrollTop = getScrollTop(scroller); return scrollTop - parentTop + targetTop; } function handleScroll() { const scrollTop = getScrollTop(scroller); const scrollHeight = scroller === window ? document.body.scrollHeight : scroller.scrollHeight; const offsetTop = getOffsetTop(); indexAnchors.forEach((anchor, index) => { const anchorTop = anchor.getOffsetTop(); const top = scrollTop - anchorTop + stickyOffsetTop.value - offsetTop; const distance = index === indexAnchors.length - 1 ? scrollHeight : indexAnchors[index + 1].getOffsetTop() - anchor.getOffsetTop(); anchor.setDisabled(true); if (top >= 0 && top < distance && clickedName.value === "") { anchor.setDisabled(false); emitEvent(anchor); } }); } function anchorClick(_0) { return __async(this, arguments, function* ({ anchorName, manualCall = false, options }) { if (manualCall) { call(props2.onClick, anchorName); } if (anchorName === active.value && !isDeactivated) { return; } const indexAnchor = indexAnchors.find(({ name: name2 }) => anchorName === name2.value); if (!indexAnchor) { return; } const offsetTop = getOffsetTop(); const indexAnchorTop = indexAnchor.getOffsetTop(); const top = indexAnchorTop - stickyOffsetTop.value + offsetTop; const left = getScrollLeft(scroller); clickedName.value = anchorName; emitEvent(anchorName, options); yield varScrollTo(scroller, { left, top, animation: easeInOutCubic, duration: toNumber(props2.duration) }); yield doubleRaf(); clickedName.value = ""; }); } function setupScroller() { scroller = getParentScroller(barEl.value); scroller.addEventListener("scroll", handleScroll); } function removeScrollerListener() { if (!scroller) { return; } scroller.removeEventListener("scroll", handleScroll); } function scrollTo(index, options) { requestAnimationFrame(() => anchorClick({ anchorName: index, options })); } return { barEl, active, zIndex, anchorNameList, n, classes, toNumber, scrollTo, anchorClick }; } }); __sfc__.render = __render__; var stdin_default = __sfc__; export { stdin_default as default };