Handling viewport/screen resizing
The builder automatically monitors changes in the dimensions of the parent element used for rendering the builder. This allows the builder to adapt to changes in the viewport dimensions. If you don't want the builder to monitor this automatically, you can disable that and manually handle the process.
You only need to use this feature when you want to disable automatic detection of viewport changes.
Disable automatic resizing
To disable monitoring viewport changes, use the disableResizing
property:
import { Builder } from "@tripetto/builder";
const builder = new Builder({
element: document.getElementById("CustomElement"),
disableResizing: true
});
builder.open();
Detecting viewport resize
The most common scenario is a browser window resize or screen orientation change. In both cases, you should monitor this and then invoke the resize
method of your builder instance. You can also use the ResizeObserver
API for this when you target modern browsers.
There is no need to debounce calls to the resize
method. This is already done inside the builder.
Example using global resize events
This example shows how to use the resize
and orientationchange
events of the browser.
import { Builder } from "@tripetto/builder";
const builder = new Builder({
element: document.getElementById("CustomElement"),
disableResizing: true
});
builder.open();
// Upon window resize notify the builder
window.addEventListener("resize", () => builder.resize());
window.addEventListener("orientationchange", () => builder.resize());
Example using ResizeObserver
If you target modern browsers, you can use the ResizeObserver
API to monitor changes in the dimensions of the host element. This can be more efficient than listening to the global resize event of the browser window. Especially in a component-based approach like when using React.
- Plain JS
- React
- Angular
import { Builder } from "@tripetto/builder";
// Let's assume you have a host element with the id `CustomElement`
const element = document.getElementById("CustomElement");
const builder = new Builder({
element,
disableResizing: true,
onClose: () => {
resizeObserver.disconnect();
}
});
const resizeObserver = new ResizeObserver(() => {
builder.resize();
});
resizeObserver.observe(element);
builder.open();
import React, { useEffect, useRef } from "react";
import { Builder, IDefinition } from "@tripetto/builder";
function TripettoBuilder() {
const elementRef = useRef<HTMLDivElement>(null);
const builderRef = useRef<Builder>();
useEffect(() => {
if (!builderRef.current) {
builderRef.current = new Builder({
element: elementRef.current,
disableResizing: true
});
}
}, []);
useEffect(() => {
const resizeObserver = new ResizeObserver(() => {
if (builderRef.current) {
builderRef.current.resize();
}
});
resizeObserver.observe(elementRef.current);
return () => {
resizeObserver.disconnect();
};
});
return (<div ref={elementRef}></div>);
}
import { Component, Input, Output, ElementRef, NgZone, EventEmitter, OnInit, OnDestroy, ChangeDetectionStrategy } from "@angular/core";
import { Builder, IDefinition } from "@tripetto/builder";
@Component({
selector: "tripetto-builder",
template: "",
styleUrls: ["./builder.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class BuilderComponent implements OnInit, OnDestroy {
private builder?: Builder;
private initialDefinition?: IDefinition;
private resizeObserver?: ResizeObserver;
/** Specifies the form definition. */
@Input() set definition(definition: IDefinition | undefined) {
if (this.builder) {
this.zone.runOutsideAngular(() => {
this.builder.definition = definition;
});
return;
}
this.initialDefinition = definition;
}
/** Retrieves the form definition. */
get definition(): IDefinition | undefined {
return (this.builder && this.builder.definition) || this.initialDefinition;
}
/**
* Invoked when the form definition is saved.
* @event
*/
@Output() saved = new EventEmitter<IDefinition>();
constructor(private element: ElementRef, private zone: NgZone) {}
ngOnInit() {
// Leave the builder outside of Angular to avoid unnecessary and costly change detection.
this.zone.runOutsideAngular(() => {
this.builder = Builder.open(this.definition, {
element: this.element.nativeElement,
disableResizing: true,
onSave: (definition) => {
this.saved.emit(definition);
}
});
// Monitor element resizing
this.resizeObserver = new ResizeObserver(() => {
this.builder?.resize();
});
this.resizeObserver.observe(this.element.nativeElement);
});
}
ngOnDestroy() {
this.resizeObserver.disconnect();
this.resizeObserver = undefined;
this.builder.destroy();
this.builder = undefined;
}
}