@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
199 lines (198 loc) • 5.46 kB
JavaScript
import { h } from "vue";
import { returnFirstEl } from "../../../common/utils.js";
const _sfc_main = {
name: "DtScrollerItem",
inject: [
"vscrollData",
"vscrollParent",
"vscrollResizeObserver"
],
props: {
// eslint-disable-next-line vue/require-prop-types
item: {
required: true
},
watchData: {
type: Boolean,
default: false
},
/**
* Indicates if the view is actively used to display an item.
*/
active: {
type: Boolean,
required: true
},
index: {
type: Number,
default: void 0
},
sizeDependencies: {
type: [Array, Object],
default: null
},
tag: {
type: String,
default: "div"
}
},
computed: {
id() {
if (this.vscrollData.simpleArray) return this.index;
if (this.vscrollData.keyField in this.item) return this.item[this.vscrollData.keyField];
throw new Error(`keyField '${this.vscrollData.keyField}' not found in your item. You should set a valid keyField prop on your Scroller`);
},
size() {
return this.vscrollData.sizes[this.id] || 0;
},
finalActive() {
return this.active && this.vscrollData.active;
}
},
watch: {
watchData: "updateWatchData",
id(value, oldValue) {
returnFirstEl(this.$el).$_vs_id = this.id;
if (!this.size) {
this.onDataUpdate();
}
if (this.$_sizeObserved) {
const oldSize = this.vscrollData.sizes[oldValue];
const size = this.vscrollData.sizes[value];
if (oldSize != null && oldSize !== size) {
this.applySize(oldSize);
}
}
},
finalActive(value) {
if (!this.size) {
if (value) {
if (!this.vscrollParent.$_undefinedMap[this.id]) {
this.vscrollParent.$_undefinedSizes++;
this.vscrollParent.$_undefinedMap[this.id] = true;
}
} else {
if (this.vscrollParent.$_undefinedMap[this.id]) {
this.vscrollParent.$_undefinedSizes--;
this.vscrollParent.$_undefinedMap[this.id] = false;
}
}
}
if (this.vscrollResizeObserver) {
if (value) {
this.observeSize();
} else {
this.unobserveSize();
}
} else if (value && this.$_pendingVScrollUpdate === this.id) {
this.updateSize();
}
}
},
created() {
if (this.$isServer) return;
this.$_forceNextVScrollUpdate = null;
this.updateWatchData();
if (!this.vscrollResizeObserver) {
for (const k in this.sizeDependencies) {
this.$watch(() => this.sizeDependencies[k], this.onDataUpdate);
}
}
},
mounted() {
if (this.finalActive) {
this.updateSize();
this.observeSize();
}
},
beforeUnmount() {
this.unobserveSize();
},
methods: {
updateSize() {
if (this.finalActive) {
if (this.$_pendingSizeUpdate !== this.id) {
this.$_pendingSizeUpdate = this.id;
this.$_forceNextVScrollUpdate = null;
this.$_pendingVScrollUpdate = null;
this.computeSize(this.id);
}
} else {
this.$_forceNextVScrollUpdate = this.id;
}
},
updateWatchData() {
if (this.watchData && !this.vscrollResizeObserver) {
this.$_watchData = this.$watch("item", () => {
this.onDataUpdate();
}, {
deep: true
});
} else if (this.$_watchData) {
this.$_watchData();
this.$_watchData = null;
}
},
onVscrollUpdate({ force }) {
if (!this.finalActive && force) {
this.$_pendingVScrollUpdate = this.id;
}
if (this.$_forceNextVScrollUpdate === this.id || force || !this.size) {
this.updateSize();
}
},
onDataUpdate() {
this.updateSize();
},
computeSize(id) {
this.$nextTick(() => {
if (this.id === id) {
const width = returnFirstEl(this.$el).offsetWidth;
const height = returnFirstEl(this.$el).offsetHeight;
this.applyWidthHeight(width, height);
}
this.$_pendingSizeUpdate = null;
});
},
applyWidthHeight(width, height) {
const size = ~~(this.vscrollParent.direction === "vertical" ? height : width);
if (size && this.size !== size) {
this.applySize(size);
}
},
applySize(size) {
if (this.vscrollParent.$_undefinedMap[this.id]) {
this.vscrollParent.$_undefinedSizes--;
this.vscrollParent.$_undefinedMap[this.id] = void 0;
}
this.vscrollData.sizes[this.id] = size;
},
observeSize() {
if (!this.vscrollResizeObserver) return;
if (this.$_sizeObserved) return;
this.vscrollResizeObserver.observe(returnFirstEl(this.$el));
this.$el.$_vs_id = this.id;
this.$el.$_vs_onResize = this.onResize;
this.$_sizeObserved = true;
},
unobserveSize() {
if (!this.vscrollResizeObserver) return;
if (!this.$_sizeObserved) return;
this.vscrollResizeObserver.unobserve(returnFirstEl(this.$el));
this.$el.$_vs_onResize = void 0;
this.$_sizeObserved = false;
},
onResize(id, width, height) {
if (this.id === id) {
this.applyWidthHeight(width, height);
}
}
},
render() {
return h(this.tag, this.$slots.default());
}
};
export {
_sfc_main as default
};
//# sourceMappingURL=scroller_item.vue.js.map