vue-golden-layout
Version:
Integration of the golden-layout to Vue
116 lines (105 loc) • 3.71 kB
text/typescript
import { Vue } from './imports'
import {Component, Prop, Watch, Emit} from 'vue-property-decorator'
export class goldenContainer extends Vue {
config: any = {
content: []
}
glObject: any = null
registerComponent(component/*: Vue|()=>any*/, name?: string): string { throw 'unimplemented'; }
childPath(comp: Vue): string {
var rv = this.nodePath?`${this.nodePath()}.`:'';
var ndx = this.$children.indexOf(comp);
console.assert(~ndx, 'Children exists');
return rv+ndx;
}
getChild(path: string) {
var nrs = path.split('.');
var ndx = nrs.shift();
var next = this.$children[ndx];
console.assert(next, "Vue structure correspond to loaded GL configuration");
return nrs.length ? next.getChild(nrs.join('.')) : next;
}
addGlChild(child, comp, index?: number) {
if(comp && 'component'=== child.type) {
if(!child.componentName)
child.componentName = this.registerComponent(comp);
if(!child.componentState)
child.componentState = {};
}
var ci = this.glObject;
if(ci)
ci.addChild(child, index);
else if(undefined=== index)
this.config.content.push(child);
else
this.config.content.splice(index, 0, child);
}
removeGlChild(index: number) {
var ci = this.glObject;
if(ci) {
ci.removeChild(ci.contentItems[index]);
for(; index< ci.contentItems.length; ++index)
ci.contentItems[index].index = index;
} else {
this.config.content.splice(index, 1);
for(; index< this.config.content.length; ++index)
this.config.content[index].index = index;
}
}
get glChildren() {
return this.glObject.contentItems.map(x=> x.vueObject);
}
onGlInitialise(cb: ()=> void): void { throw 'Not implemented'; }
events: string[] = ['open', 'resize', 'destroy', 'close', 'tab', 'hide', 'show']
}
export class goldenChild extends Vue {
width: number
height: number
reWidth(w) { this.container && this.container.setSize(w, false); }
reHeight(h) { this.container && this.container.setSize(false, h); }
tabId: string
glObject: any = null
get childConfig() { return null; }
get childEl() { return null; }
get glParent() { return this.glObject.parent.vueObject; }
container = null;
hide() { this.container && this.container.hide(); }
show() { this.container && this.container.show(); }
hidden: boolean
setContainer(c) {
this.container && this.container[this.hidden?'hide':'show']();
}
closable: boolean
close() {
this.container && this.container.close();
}
$parent: goldenContainer
created() {
if(!this.$parent instanceof goldenContainer)
throw new Error('gl-component can only appear directly in a golden-layout container');
}
nodePath() {
return this.$parent.childPath(this);
}
mounted() {
var dimensions:any = {};
if(undefined!== this.width) dimensions.width = this.width;
if(undefined!== this.height) dimensions.height = this.height;
this.$parent.addGlChild({
...dimensions,
...this.childConfig,
vue: this.nodePath()
}, this, this.$parent.$children.indexOf(this));
}
beforeDestroy() {
if(this.glObject) //It can be destroyed in reaction of the removal of the glObject too
this.$parent.removeGlChild(this.glParent.glChildren.indexOf(this));
}
destroy(v) { return !v; }
events: string[] = ['stateChanged', 'titleChanged', 'activeContentItemChanged', 'itemDestroyed', 'itemCreated',
'componentCreated', 'rowCreated', 'columnCreated', 'stackCreated', 'destroy', 'destroyed']
}