import { HTMLWidget, Widget } from "@hpcc-js/common";
import { select as d3Select } from "d3-selection";
import "d3-transition";
import "../src/Carousel.css";
export class Carousel extends HTMLWidget {
protected _prevActive: number = 0;
protected _root;
activeWidget(): Widget {
return this.widgets()[this.active()];
}
enter(domNode, element) {
super.enter(domNode, element);
this._root = element.append("div")
.attr("id", `${this.id()}_root`)
;
}
update(domNode, element) {
super.update(domNode, element);
const active = this.active();
const width = this.width();
this._root
.style("width", `${width}px`)
.style("height", `${this.height()}px`)
;
const widgetElements = this._root.selectAll(`#${this.id()}_root > .carouselItem`).data(this.widgets(), d => d.id());
const update = widgetElements.enter().append("div")
.attr("class", "carouselItem")
.each(function (w) {
w.target(this);
})
.merge(widgetElements)
.style("left", (d, i) => `${(i - this._prevActive) * width}px`)
.style("width", `${width}px`)
;
if (this._prevActive !== active) {
update
.style("display", (d, i) => i === this._prevActive || i === active ? null : "none") // Must be called before render callback (not inside transition)
.transition().duration(this.transitionDuration())
.style("left", (d, i) => `${(i - active) * width}px`)
.on("end", function (d, i) {
d3Select(this).style("display", () => i === active ? null : "none");
})
;
this._prevActive = active;
}
widgetElements.exit()
.each(function (w) {
w.target(null);
})
.remove()
;
}
exit(domNode, element) {
this.widgets().forEach(w => w.target(null));
super.exit(domNode, element);
}
render(callback): this {
return super.render(w => {
if (!this.visible() || this.isDOMHidden()) {
if (callback) {
callback(w);
}
} else {
const aw = this.activeWidget();
if (aw) {
aw
.resize(this.size())
.render(w2 => {
if (callback) {
callback(w);
}
})
;
}
}
});
}
}
Carousel.prototype._class += " layout_Carousel";
export interface Carousel {
widgets(): Widget[];
widgets(_: Widget[]): this;
active(): number;
active(_: number): this;
transitionDuration(): Widget[];
transitionDuration(_: Widget[]): this;
}
Carousel.prototype.publish("widgets", [], "widgetArray", "Widgets", null, { render: false });
Carousel.prototype.publish("active", 0, "number", "Active widget");
Carousel.prototype.publish("transitionDuration", 500, "number", "Transition duration");