@web-atoms/core-docs
Version:
273 lines • 10.2 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "../../core/AtomBridge", "./AtomControl"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AtomGridView = void 0;
const AtomBridge_1 = require("../../core/AtomBridge");
const AtomControl_1 = require("./AtomControl");
/**
* GridView columns or rows can accept comma separated strings with
* absolute pixel value, percent value and star (*).
*
* For example, 20% of total width for first column, 200 pixel for last column
* and rest of the space is for middle = "20%, *, 200"
*
* You can have only one star specification.
* @example
* <AtomGridView
* rows="50,*"
* columns="20%, 5, *, 200">
*
* <!-- Header spans for three columns in first row -->
* <header row="0" column="0:3"></header>
*
* <!-- menu is on first column -->
* <menu row="1" column="0"></menu>
*
* <!-- Grid splitter splits 1st and 3rd column and itself lies in 2nd column -->
* <AtomGridSplitter row="1" column="1" direction="vertical" />
*
* <!-- Section fills remaining area -->
* <section row="1" column="2"></section>
*
* <!-- Help sits on last column -->
* <Help row="1" column="3"></Help>
* </AtomGridView>
*/
class AtomGridView extends AtomControl_1.AtomControl {
constructor() {
super(...arguments);
this.attempt = 0;
this.availableRect = null;
this.childrenReady = false;
}
static getCellInfo(e) {
let row = 0;
let column = 0;
let rowSpan = 1;
let colSpan = 1;
const cell = e.cell;
if (cell) {
// tslint:disable-next-line:no-console
console.warn("Attribute `cell` is obsolete, please use row and column attributes separately");
const tokens = cell.split(",")
.map((s) => s.trim().split(":").map((st) => parseInt(st.trim(), 10)));
column = tokens[0][0];
row = tokens[1][0];
colSpan = tokens[0][1] || 1;
rowSpan = tokens[1][1] || 1;
}
else {
let c = ((e.row) || "0");
let tokens = c.split(":").map((st) => parseInt(st.trim(), 10));
row = tokens[0];
rowSpan = tokens[1] || 1;
c = ((e.column) || "0");
tokens = c.split(":").map((st) => parseInt(st.trim(), 10));
column = tokens[0];
colSpan = tokens[1] || 1;
}
return {
row,
rowSpan,
column,
colSpan,
};
}
append(e) {
const ee = e instanceof AtomControl_1.AtomControl ? e.element : e;
ee._logicalParent = this.element;
this.children = this.children || [];
this.children.push(e instanceof AtomControl_1.AtomControl ? e.element : e);
return this;
}
onUpdateUI() {
this.attempt++;
// this.removeAllChildren(this.element);
let child = this.element.firstElementChild;
while (child) {
const c = child;
child = child.nextElementSibling;
c.remove();
}
const width = this.element.offsetWidth ||
this.element.clientWidth ||
parseFloat(this.element.style.width) ||
0;
const height = this.element.offsetHeight ||
this.element.clientHeight ||
parseFloat(this.element.style.height) ||
0;
if (!(width && height)) {
if (this.childrenReady) {
// this is the time parent is hidden
setTimeout(() => {
this.invalidate();
}, 5000);
return;
}
if (this.attempt > 100) {
// tslint:disable-next-line:no-console
console.error(`AtomDockPanel (${width}, ${height}) must both have non zero width and height`);
return;
}
// AtomDispatcher.instance.callLater(() => this.invalidate());
setTimeout(() => {
this.invalidate();
}, 100);
return;
}
if (!this.children) {
return;
}
this.attempt = 0;
this.availableRect = { width, height, x: 0, y: 0 };
this.columnSizes = (this.columns || "*").split(",")
.map((s) => this.toSize(s.trim(), this.availableRect.width));
this.rowSizes = (this.rows || "*").split(",")
.map((s) => this.toSize(s.trim(), this.availableRect.height));
this.assignOffsets(this.columnSizes, this.availableRect.width);
this.assignOffsets(this.rowSizes, this.availableRect.height);
for (const iterator of this.children) {
const host = document.createElement("section");
host.appendChild(iterator);
this.element.appendChild(host);
}
super.onUpdateUI();
this.updateSize();
this.childrenReady = true;
}
resize(item, index, delta) {
const a = item === "column" ? this.columnSizes : this.rowSizes;
const prev = a[index - 1];
const next = a[index + 1];
if ((!prev) || (!next)) {
throw new Error("Grid Splitter cannot be start or end element in GridView");
}
const current = a[index];
prev.size += delta;
current.offset += delta;
next.offset += delta;
next.size -= delta;
this.updateSize();
}
onPropertyChanged(name) {
switch (name) {
case "rows":
case "columns":
if (this.childrenReady) {
this.invalidate();
}
break;
}
}
onUpdateSize() {
if (!this.children) {
return;
}
for (const iterator of this.children) {
this.updateStyle(iterator);
}
}
preCreate() {
this.columns = null;
this.rows = null;
const style = this.element.style;
style.position = "absolute";
style.left = style.right = style.top = style.bottom = "0";
style.overflow = "hidden";
this.bindEvent(window, "resize", () => {
this.updateSize();
});
this.bindEvent(document.body, "resize", () => {
this.updateSize();
});
}
updateStyle(e) {
const { colSpan, column, row, rowSpan } = AtomGridView.getCellInfo(e);
const host = e.parentElement;
if (!host) {
return;
}
host.style.position = "absolute";
host.style.overflow = "hidden";
host.style.padding = "0";
host.style.margin = "0";
if (this.rowSizes.length <= row || this.columnSizes.length <= column) {
return;
}
const rowStart = this.rowSizes[row].offset;
let rowSize = 0;
for (let i = row; i < row + rowSpan; i++) {
rowSize += this.rowSizes[i].size;
}
host.style.top = `${rowStart}px`;
host.style.height = `${rowSize}px`;
const colStart = this.columnSizes[column].offset;
let colSize = 0;
for (let i = column; i < column + colSpan; i++) {
colSize += this.columnSizes[i].size;
}
host.style.left = `${colStart}px`;
host.style.width = `${colSize}px`;
AtomBridge_1.AtomBridge.instance.visitDescendents(host, (el, ac) => {
if (ac) {
ac.invalidate();
return false;
}
return true;
});
}
toSize(s, total) {
if (!s || s === "*") {
return { offset: -1, size: NaN };
}
let n = 0;
if (s.endsWith("%")) {
s = s.substr(0, s.length - 1);
n = parseFloat(s);
return { offset: -1, size: total * n / 100 };
}
return { offset: -1, size: parseFloat(s) };
}
assignOffsets(a, end) {
let start = 0;
let fill = null;
for (const item of a) {
item.offset = start;
if (isNaN(item.size)) {
fill = item;
break;
}
start += item.size;
}
if (!fill) {
return;
}
const lastStart = start;
start = end;
const r = a.map((x) => x).reverse();
for (const item of r) {
if (isNaN(item.size)) {
if (fill !== item) {
throw new Error("Multiple * cannot be defined");
}
break;
}
start -= item.size;
item.offset = start;
}
fill.offset = lastStart;
fill.size = start - lastStart;
}
}
exports.AtomGridView = AtomGridView;
});
//# sourceMappingURL=AtomGridView.js.map