This repository has been archived on 2025-01-01. You can view files and clone it, but cannot push or open issues or pull requests.
moodle-local_treestudyplan/amd/src/util/psidebar-vue.js
2024-05-10 15:22:52 +02:00

138 lines
No EOL
5 KiB
JavaScript

/*eslint no-unused-vars: warn */
/*eslint max-len: ["error", { "code": 160 }] */
/*eslint-disable no-trailing-spaces */
/*eslint-disable no-console */
/*eslint-env es6*/
import Debugger from './debugger';
let debug = new Debugger("p-sidebar");
export default {
install(Vue/*,options*/){
Vue.component('p-sidebar',{
props: {
value: {
type: Boolean,
default: true,
},
right: {
type: Boolean,
default: false,
},
shadow: {
type: Boolean,
default: false,
},
target: {
type: String,
default: 'body',
},
offsetRef: {
type: String,
default: '',
}
},
data() {
return {
wrapper: null,
contentwrapper: null,
resizeobserver: null,
};
},
computed: {
},
methods: {
initWrappers(target) {
let initializeWrapperContent = false;
// First check if the sidebar wrapper already exists.
// Creating the wrappers over and over again is a recipe for disaster.
this.wrapper = document.querySelector("#p-sidebar-wrapper");
if (!this.wrapper) {
initializeWrapperContent = true;
// Otherwise, create it.
this.wrapper = document.createElement("div");
this.wrapper.setAttribute("id","p-sidebar-wrapper");
}
// First check if the contentwrapper already exists
this.contentwrapper = document.querySelector("#p-sidebar-contentwrapper");
if (!this.contentwrapper) {
initializeWrapperContent = true;
// Otherwise, create it.
this.contentwrapper = document.createElement("div");
this.contentwrapper.setAttribute("id","p-sidebar-contentwrapper");
this.wrapper.appendChild(this.contentwrapper);
}
if (initializeWrapperContent) {
// Find containing target (otherwise use body)
let targetEl = document.querySelector(target);
console.info(`Targeting '${target}' to `,targetEl);
if (!targetEl || targetEl.nodeType == "HTML") {
targetEl = document.querySelector("body");
}
debug.warn(`Initializing wrappers with content of target `,targetEl);
// Move all target content parts to content wrapper....
while (targetEl.childNodes.length >0) {
this.contentwrapper.appendChild(targetEl.childNodes[0]);
}
// Add sidebar wrapper to target Element
targetEl.appendChild(this.wrapper);
}
},
rePosition(right) {
// Place the container elsewhere in the DOM.
const el = this.$refs.container;
if(right) {
this.wrapper.insertBefore(el,this.contentwrapper.nextSibling);
} else {
this.wrapper.insertBefore(el,this.contentwrapper);
}
},
setOffset(reference) {
const ref = reference?document.querySelector(reference):null;
console.info(`Setting offset from '${reference}'`,ref);
let offsetTop = (ref?ref.offsetTop:0);
offsetTop+=(offsetTop!=0)?"px":"";
const el = this.$refs.container;
el.style.height=`calc( 100vh - ${offsetTop})`;
el.style.marginTop=offsetTop;
}
},
watch: {
right(newVal) {
this.rePosition(newVal);
},
offsetRef(reference) {
this.setOffset(reference);
}
},
mounted() {
const self = this;
const el = self.$refs.container;
this.initWrappers(this.target);
this.setOffset(this.offsetRef);
this.rePosition(this.right,this.besides);
this.resizeObserver = new ResizeObserver(() => {
let wx = 0 - el.getBoundingClientRect().width;
wx += (wx!=0)?"px":"";
el.style.setProperty("--p-sidebar-hideoffset",wx);
});
this.resizeObserver.observe(el);
},
unmounted() {
if(this.resizeObserver) {
this.resizeObserver.disconnect();
}
},
template: `
<div>
<div ref='container'
:class="'p-sidebar ' + (right?'p-sidebar-right ':'') + (shadow?'p-sidebar-shadow ':'') + (value?'shown ':'hidden ')"
><slot></slot></div>
</div>
`,
});
},
};