tdesign-vue
Version:
269 lines (265 loc) • 9.68 kB
JavaScript
/**
* tdesign v1.15.0
* (c) 2026 tdesign
* @license MIT
*/
import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _regeneratorRuntime from '@babel/runtime/regenerator';
import Vue from 'vue';
import { isFunction } from 'lodash-es';
import { ANCHOR_SHARP_REGEXP, getOffsetTop } from './utils.js';
import { off, getScrollContainer, on, getScroll, scrollTo } from '../utils/dom.js';
import props from './props.js';
import { renderTNodeJSX } from '../utils/render-tnode.js';
import { getClassPrefixMixins } from '../config-provider/config-receiver.js';
import mixins from '../utils/mixins.js';
import { Affix } from '../affix/index.js';
import 'raf';
import '../utils/easing.js';
import '@babel/runtime/helpers/readOnlyError';
import '@babel/runtime/helpers/typeof';
import '@vue/composition-api';
import '../config-provider/context.js';
import '../_common/js/global-config/default-config.js';
import '../_common/js/global-config/locale/zh_CN.js';
import '../_chunks/dep-e5d497fb.js';
import '../_chunks/dep-1618e1d6.js';
import 'dayjs';
import '../_common/js/global-config/t.js';
import '@babel/runtime/helpers/slicedToArray';
import '../affix/affix.js';
import '../affix/props.js';
import '../utils/withInstall.js';
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var classPrefixMixins = getClassPrefixMixins("anchor");
var _Anchor = mixins(Vue, classPrefixMixins).extend({
name: "TAnchor",
props: _objectSpread({}, props),
provide: function provide() {
return {
tAnchor: this
};
},
data: function data() {
return {
links: [],
active: "",
activeLineStyle: false
};
},
watch: {
attach: function attach() {
if (this.scrollContainer) {
off(this.scrollContainer, "scroll", this.handleScroll);
}
this.getScrollContainer();
}
},
methods: {
getScrollContainer: function getScrollContainer$1() {
var container = this.container;
this.scrollContainer = getScrollContainer(container);
on(this.scrollContainer, "scroll", this.handleScroll);
this.handleScroll();
},
getAnchorTarget: function getAnchorTarget(link) {
var matcher = link.match(ANCHOR_SHARP_REGEXP);
if (!matcher) {
return;
}
var anchor = document.getElementById(matcher[1]);
if (!anchor) {
return;
}
return anchor;
},
registerLink: function registerLink(link) {
var links = this.links;
if (!ANCHOR_SHARP_REGEXP.test(link) || links.indexOf(link) !== -1) {
return;
}
links.push(link);
},
unregisterLink: function unregisterLink(link) {
this.links = this.links.filter(function (each) {
return each !== link;
});
},
setCurrentActiveLink: function setCurrentActiveLink(link) {
var _this = this;
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
var active;
return _regeneratorRuntime.wrap(function (_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
active = _this.active;
if (!(active === link)) {
_context.next = 1;
break;
}
return _context.abrupt("return");
case 1:
_this.active = link;
_this.emitChange(link, active);
_context.next = 2;
return Vue.nextTick();
case 2:
_this.updateActiveLine();
case 3:
case "end":
return _context.stop();
}
}, _callee);
}))();
},
updateActiveLine: function updateActiveLine() {
var ele = this.$el.querySelector(".".concat(this.commonStatusClassName.active, ">a"));
if (!ele) {
this.activeLineStyle = false;
return;
}
var top = ele.offsetTop,
height = ele.offsetHeight;
this.activeLineStyle = {
top: "".concat(top, "px"),
height: "".concat(height, "px"),
opacity: 1
};
},
emitChange: function emitChange(currentLink, prevLink) {
this.$emit("change", currentLink, prevLink);
if (this.onChange) {
this.onChange(currentLink, prevLink);
}
},
handleLinkClick: function handleLinkClick(link) {
var _this$onClick;
this.$emit("click", link);
(_this$onClick = this.onClick) === null || _this$onClick === void 0 || _this$onClick.call(this, link);
var getCurrentAnchor = this.$props.getCurrentAnchor;
var newHref = isFunction(getCurrentAnchor) ? getCurrentAnchor(link.href) : link.href;
this.handleScrollTo(newHref);
},
handleScrollTo: function handleScrollTo(link) {
var _this2 = this;
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
var anchor, scrollContainer, targetOffset, scrollTop, offsetTop, top;
return _regeneratorRuntime.wrap(function (_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
anchor = _this2.getAnchorTarget(link);
_this2.setCurrentActiveLink(link);
if (anchor) {
_context2.next = 1;
break;
}
return _context2.abrupt("return");
case 1:
_this2.handleScrollLock = true;
scrollContainer = _this2.scrollContainer, targetOffset = _this2.targetOffset;
scrollTop = getScroll(scrollContainer);
offsetTop = getOffsetTop(anchor, scrollContainer);
top = scrollTop + offsetTop - targetOffset;
_context2.next = 2;
return scrollTo(top, {
container: scrollContainer
});
case 2:
_this2.handleScrollLock = false;
case 3:
case "end":
return _context2.stop();
}
}, _callee2);
}))();
},
handleScroll: function handleScroll() {
var _this3 = this;
if (this.handleScrollLock) return;
var links = this.links,
bounds = this.bounds,
targetOffset = this.targetOffset;
var filters = [];
var active = "";
links.forEach(function (link) {
var anchor = _this3.getAnchorTarget(link);
if (!anchor) {
return;
}
var top = getOffsetTop(anchor, _this3.scrollContainer);
if (top < bounds + targetOffset) {
filters.push({
link: link,
top: top
});
}
});
if (filters.length) {
var latest = filters.reduce(function (prev, cur) {
return prev.top > cur.top ? prev : cur;
});
active = latest.link;
}
this.setCurrentActiveLink(active);
},
renderCursor: function renderCursor() {
var h = this.$createElement;
var titleContent = renderTNodeJSX(this, "cursor");
return titleContent || h("div", {
"class": "".concat(this.componentName, "__line-cursor")
});
}
},
mounted: function mounted() {
var _this4 = this;
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
var getCurrentAnchor, _window, href;
return _regeneratorRuntime.wrap(function (_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
_this4.getScrollContainer();
getCurrentAnchor = _this4.$props.getCurrentAnchor;
if (isFunction(getCurrentAnchor)) {
_this4.setCurrentActiveLink(getCurrentAnchor(_this4.active));
} else {
href = (_window = window) === null || _window === void 0 ? void 0 : _window.location.hash;
_this4.setCurrentActiveLink(decodeURIComponent(href));
}
case 1:
case "end":
return _context3.stop();
}
}, _callee3);
}))();
},
destroyed: function destroyed() {
if (!this.scrollContainer) return;
off(this.scrollContainer, "scroll", this.handleScroll);
},
render: function render() {
var h = arguments[0];
var children = this.$scopedSlots["default"],
size = this.size,
affixProps = this.affixProps,
activeLineStyle = this.activeLineStyle;
var className = [this.componentName, this.commonSizeClassName[size]];
var content = h("div", {
"class": className
}, [h("div", {
"class": "".concat(this.componentName, "__line")
}, [h("div", {
"class": "".concat(this.componentName, "__line-cursor-wrapper"),
"style": activeLineStyle
}, [this.renderCursor()])]), children && children(null)]);
if (affixProps) {
return h(Affix, {
"props": _objectSpread({}, affixProps)
}, [content]);
}
return content;
}
});
export { _Anchor as default };
//# sourceMappingURL=anchor.js.map