profectus-template/src/components/system/Sticky.vue
thepaperpilot 0afcd1cd3d First pass at typescript support
Oh man did this end up requiring a *ton* of other work as well.
There's still a few typing issues I still can't quite work out,
and others I'd like to improve when I have time. In fact, this version
doesn't even really work, it has a stack overflow error caused by
a tooltip for some reason have a tree inside it, which in turn has
another tooltip, etc. There's also 17 errors that I *really* feel like
shouldn't be there, but they are, and 113 warnings - mostly using !
to assert that things are non-null. Lots of work left to do, to sum up.

The reason I'm committing this now is because I really need to get to
work on my game jam, and since it won't use a tree or really many of
TMT-X's features, I can get away with using a broken engine :)
2021-08-16 23:30:54 -05:00

73 lines
1.7 KiB
Vue

<template>
<div class="sticky" :style="{ top }" ref="sticky" data-v-sticky>
<slot />
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "sticky",
data() {
return {
top: "0",
observer: null
} as {
top: string;
observer: ResizeObserver | null;
};
},
mounted() {
this.setup();
},
methods: {
setup() {
this.$nextTick(() => {
if (this.$refs.sticky == undefined) {
this.$nextTick(this.setup);
} else {
this.updateTop();
this.observer = new ResizeObserver(this.updateTop);
this.observer.observe((this.$refs.sticky as HTMLElement).parentElement!);
}
});
},
updateTop() {
let el = this.$refs.sticky as HTMLElement;
if (el == undefined) {
return;
}
let top = 0;
while (el.previousSibling) {
const sibling = el.previousSibling as HTMLElement;
if (sibling.dataset && "vSticky" in sibling.dataset) {
top += sibling.offsetHeight;
}
el = sibling;
}
this.top = top + "px";
}
}
});
</script>
<style scoped>
.sticky {
position: sticky;
background: var(--background);
margin-left: -7px;
margin-right: -7px;
padding-left: 7px;
padding-right: 7px;
z-index: 3;
}
.modal-body .sticky {
margin-left: 0;
margin-right: 0;
padding-left: 0;
padding-right: 0;
}
</style>