@gez/date-time-kit
Version:
282 lines (281 loc) • 10.4 kB
JavaScript
var __freeze = Object.freeze;
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __freeze(raw || cooked.slice()) }));
var _a, _b, _c, _d;
import { closestByEvent, debounce, html } from "../../utils/index.mjs";
import {
UiBase
} from "../web-component-base/index.mjs";
import styleStr from "./index.css.mjs";
export class Ele extends UiBase {
constructor() {
super(...arguments);
__publicField(this, "_createItem", (num, currentNum = this.currentNum) => {
const ele = document.createElement("div");
ele.setAttribute("part", ele.className = "item");
ele.classList.toggle("item-current", num === currentNum);
ele.part.toggle("item-current", num === currentNum);
ele.dataset.number = num + "";
ele.textContent = this.formatter(num);
return ele;
});
__publicField(this, "_intersectionOb", null);
__publicField(this, "_loadBefore", debounce(() => {
var _a2, _b2, _c2, _d2;
const container = this._els.container;
const firstItem = container.firstElementChild;
const lastItem = container.lastElementChild;
const firstNum = Number(firstItem.dataset.number);
const curNum = this.currentNum;
const pageSize = this._pageSize;
const itemHeight = this._itemHeight;
const items = [...Array(pageSize * 2)].map(
(_, i) => this._createItem(firstNum - pageSize * 2 + i, curNum)
);
(_a2 = this._intersectionOb) == null ? void 0 : _a2.unobserve(firstItem);
(_b2 = this._intersectionOb) == null ? void 0 : _b2.unobserve(lastItem);
const scrollTop = this.scrollTop;
container.prepend(...items);
for (let i = 0; i < items.length; ++i) {
container.removeChild(container.lastElementChild);
}
const addedHeight = items.length * itemHeight;
this.scrollTo({
top: scrollTop + addedHeight,
behavior: "instant"
});
(_c2 = this._intersectionOb) == null ? void 0 : _c2.observe(items[0]);
(_d2 = this._intersectionOb) == null ? void 0 : _d2.observe(container.lastElementChild);
if (this._isScrolling) this.scrollToCurrent();
}));
__publicField(this, "_loadAfter", debounce(() => {
var _a2, _b2, _c2, _d2;
const container = this._els.container;
const firstItem = container.firstElementChild;
const lastItem = container.lastElementChild;
const curNum = this.currentNum;
const pageSize = this._pageSize;
const itemHeight = this._itemHeight;
const lastNum = Number(lastItem.textContent);
const items = [...Array(pageSize * 2)].map(
(_, i) => this._createItem(lastNum + i + 1, curNum)
);
(_a2 = this._intersectionOb) == null ? void 0 : _a2.unobserve(firstItem);
(_b2 = this._intersectionOb) == null ? void 0 : _b2.unobserve(lastItem);
const scrollTop = this.scrollTop;
container.append(...items);
for (let i = 0; i < items.length; ++i) {
container.removeChild(container.firstElementChild);
}
const addedHeight = items.length * itemHeight;
this.scrollTo({
top: scrollTop - addedHeight,
behavior: "instant"
});
(_c2 = this._intersectionOb) == null ? void 0 : _c2.observe(container.firstElementChild);
(_d2 = this._intersectionOb) == null ? void 0 : _d2.observe(items[items.length - 1]);
if (this._isScrolling) this.scrollToCurrent();
}));
__publicField(this, "_isScrolling", false);
__publicField(this, "scrollToCurrent", () => {
var _a2;
const ele = this._els.currentItem;
if (!ele) return;
const thisRect = this.getBoundingClientRect();
if (thisRect.height === 0) return;
(_a2 = this._intersectionOb) == null ? void 0 : _a2.observe(ele);
this._isScrolling = true;
const eleRect = ele.getBoundingClientRect();
const offsetTop = eleRect.top - thisRect.top + this.scrollTop;
this.scrollTo({
top: offsetTop
});
});
__publicField(this, "_render", super._genRenderFn(() => {
this._destroyOb();
const container = this._els.container;
container.innerHTML = "";
if (!this.hasAttribute("current-num")) return;
const currentNum = this.currentNum;
const minNum = this.minNum;
const maxNum = this.maxNum;
if (minNum === Number.NEGATIVE_INFINITY && maxNum === Number.POSITIVE_INFINITY) {
this._initOb();
const pageSize = this._pageSize;
for (let i = -pageSize * 2; i <= pageSize * 2; ++i) {
container.appendChild(
this._createItem(currentNum + i, currentNum)
);
}
} else
for (let i = minNum; i <= maxNum; ++i) {
container.appendChild(this._createItem(i, currentNum));
}
setTimeout(this.scrollToCurrent, 0);
}));
__publicField(this, "_onClick", (e) => {
var _a2;
if (!this.isConnected) return;
const container = this._els.container;
const oldCurrent = container.querySelector(".item-current");
const item = closestByEvent(e, ".item", this);
if (!item || item === oldCurrent) return;
oldCurrent == null ? void 0 : oldCurrent.classList.remove("item-current");
oldCurrent == null ? void 0 : oldCurrent.part.remove("item-current");
item.classList.add("item-current");
item.part.add("item-current");
this.scrollToCurrent();
super.dispatchEvent(
"select-num",
{
oldNum: +((_a2 = oldCurrent == null ? void 0 : oldCurrent.dataset.number) != null ? _a2 : this.currentNum),
newNum: +item.dataset.number
},
true
);
});
__publicField(this, "formatter", (num) => "" + num);
}
static get observedAttributes() {
return [
...super.observedAttributes,
"current-num",
"min-num",
"max-num"
];
}
get _staticEls() {
return {
...super._staticEls,
container: this.$0(_b || (_b = __template([".container"])))
};
}
get _dynamicEls() {
return {
...super._dynamicEls,
currentItem: this.$0(_c || (_c = __template([".item-current"]))),
items: this.$(_d || (_d = __template([".item"])))
};
}
get currentNum() {
return Number(this._getAttr("current-num"));
}
set currentNum(val) {
this.setAttribute("current-num", String(val));
}
get minNum() {
return Number(this._getAttr("min-num", "-Infinity"));
}
set minNum(val) {
let min = +val;
if (Number.isNaN(min)) min = Number.NEGATIVE_INFINITY;
if (min > this.maxNum) [this.maxNum, min] = [min, this.maxNum];
this.setAttribute("min-num", String(val));
}
get maxNum() {
return Number(this._getAttr("max-num", "Infinity"));
}
set maxNum(val) {
let max = +val;
if (Number.isNaN(max)) max = Number.POSITIVE_INFINITY;
if (max < this.minNum) [this.minNum, max] = [max, this.minNum];
this.setAttribute("max-num", String(val));
}
_destroyOb() {
var _a2;
(_a2 = this._intersectionOb) == null ? void 0 : _a2.disconnect();
this._intersectionOb = null;
}
_initOb() {
this._destroyOb();
if (!this.shadowRoot) return;
this._intersectionOb = new IntersectionObserver(
(entries, observer) => {
const container = this._els.container;
const firstItem = container.firstElementChild;
const lastItem = container.lastElementChild;
for (const {
target,
isIntersecting,
intersectionRatio,
rootBounds,
boundingClientRect
} of entries) {
if (!isIntersecting) continue;
observer.unobserve(target);
if (target === this._els.currentItem) {
observer.observe(firstItem);
observer.observe(lastItem);
if (intersectionRatio !== 1 || rootBounds && boundingClientRect && Math.abs(
rootBounds.top - boundingClientRect.top
) > 2) {
observer.observe(target);
} else {
this._isScrolling = false;
}
}
if (target === firstItem) {
this._loadBefore();
} else if (target === lastItem) {
this._loadAfter();
}
}
},
{ root: this }
);
}
connectedCallback() {
if (!super.connectedCallback()) return;
this._render();
this.addEventListener("click", this._onClick);
}
disconnectedCallback() {
this.removeEventListener("click", this._onClick);
this._destroyOb();
return super.disconnectedCallback();
}
_onAttrChanged(name, oldValue, newValue) {
var _a2;
super._onAttrChanged(name, oldValue, newValue);
if (name === "current-num" && newValue === ((_a2 = this._els.currentItem) == null ? void 0 : _a2.dataset.number)) {
return;
}
this._render();
}
get _itemHeight() {
const container = this._els.container;
const items = Array.from(
container.querySelectorAll(".item")
);
const len = items.length;
if (len === 1) {
container.append(this._createItem(0, 1));
} else if (len === 0) {
container.append(this._createItem(0, 1), this._createItem(0, 1));
}
const h = container.firstElementChild.offsetHeight;
const itemNum = Math.max(2, len);
const gap = Math.max(
0,
(container.clientHeight - h * itemNum) / (itemNum - 1)
);
if (len === 0) {
container.removeChild(container.lastElementChild);
container.removeChild(container.lastElementChild);
} else if (len === 1) {
container.removeChild(container.lastElementChild);
}
return h + gap;
}
get _pageSize() {
const thisHeight = this.clientHeight;
if (thisHeight === 0) return 10;
return Math.min(10, Math.ceil(thisHeight / this._itemHeight));
}
}
__publicField(Ele, "tagName", "dt-num-list");
__publicField(Ele, "_style", styleStr);
__publicField(Ele, "_template", html(_a || (_a = __template(['<div class="container" part="container"></div>']))));
Ele.define();