@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
JavaScript
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
};