UNPKG

activator-oce-exporter

Version:

Extract Activator binder and convert it to valid OCE mono pacakge

652 lines (582 loc) 16.9 kB
import { html } from '@polymer/lit-element'; import { FusionBase } from '../../base'; import { FusionApi } from '../../api'; import { applyMixins, Font, SlideComponent } from '../../mixins'; import { FusionText } from '../text'; import { getPartial, debounce } from '../../utils'; class FusionTableCell extends applyMixins(FusionText, [Font]) { static get properties() { const properties = ['width', 'font-size', 'font-family', 'font-weight', 'font-style', 'line-height', 'letter-spacing', 'color', 'background-color']; const filteredProp = getPartial(FusionText.properties, properties); return { ...filteredProp, 'padding-top': { type: String, fieldType: 'Number', value: '10px', }, 'padding-bottom': { type: String, fieldType: 'Number', value: '10px', }, 'padding-left': { type: String, fieldType: 'Number', value: '10px', }, 'padding-right': { type: String, fieldType: 'Number', value: '10px', }, }; } static get options() { return { componentName: 'fusion-table-cell', componentType: 'static', componentCategory: 'data', componentUIName: 'Table Cell', componentScope: 'standard', componentDescription: 'Basic table cell component', componentDomain: 'slide', isTextEdit: true, isRootNested: false, nestedTypes: ['*'], nestedComponents: ['*'], defaultTemplate: '<p>Cell text</p>', resizable: 'e', draggable: false, rotatable: false, sortable: false, }; } connectedCallback() { super.connectedCallback(); this.emitCustomEvent(`${this.constructor.options.componentName}:added`); } disconnectedCallback() { super.disconnectedCallback(); this.emitCustomEvent(`${this.constructor.options.componentName}:removed`); } update(changedProps) { super.update(changedProps); if (changedProps.has('background-color')) { this.emitCustomEvent(`${this.constructor.options.componentName}:bg-changed`); } } checkSizes(sizeProps) { super.checkSizes(sizeProps); this.triggerEvent(); } triggerEvent() { this.emitCustomEvent(`${this.constructor.options.componentName}:resized`); } static getStyle() { const styleRoot = super.getStyle(); return ` ${styleRoot} :host { position: relative; height: 100%; }`; } render() { super.render(); return html` <style> ${FusionTableCell.getStyle()} </style> <div class='content'> <slot></slot> </div> ${FusionTableCell.getSystemSlotTemplate()} `; } } class FusionTable extends applyMixins(FusionBase, [Font, SlideComponent]) { static get properties() { return { ...super.properties, columns: { type: String, fieldType: 'Number', value: '3', min: 0, prop: true, }, rows: { type: String, fieldType: 'Number', value: '3', min: 0, prop: true, }, color: { type: String, fieldType: 'ColorPicker', value: 'rgba(0, 0, 0, 1)', }, 'padding-top': { type: String, fieldType: 'Number', value: '10px', }, 'padding-bottom': { type: String, fieldType: 'Number', value: '10px', }, 'padding-left': { type: String, fieldType: 'Number', value: '10px', }, 'padding-right': { type: String, fieldType: 'Number', value: '10px', }, 'border-color': { type: String, fieldType: 'ColorPicker', value: 'rgba(0, 0, 0, 1)', }, 'background-color': { type: String, fieldType: 'ColorPicker', value: 'rgba(255, 255, 255, 1)', }, 'border-width': { type: String, fieldType: 'Number', value: '1px', }, 'border-radius': { type: String, fieldType: 'Number', value: '0px', }, }; } static get options() { return { componentName: 'fusion-table', componentType: 'static', componentCategory: 'data', componentUIName: 'Table', componentScope: 'standard', componentDescription: 'Basic table component', componentDomain: 'slide', isTextEdit: true, isRootNested: true, nestedTypes: [], nestedComponents: [], defaultTemplate: '', resizable: false, draggable: 'xy', rotatable: true, sortable: false, }; } static getChildComponent(component) { const { componentName } = component.options; return { component, name: componentName, events: { add: `${componentName}:added`, remove: `${componentName}:removed`, resize: `${componentName}:resized`, bgChange: `${componentName}:bg-changed`, }, }; } constructor() { super(); this.cell = FusionTable.getChildComponent(FusionTableCell); this.prevTableOffsetWidth = 0; this.generateMissedCells = this.isCellsExist(); this.saveUpdatedColumnCells = debounce((currentCell) => { this.columnCells.map(cell => FusionApi.saveStyles(`#${cell.id}`, { width: currentCell.width })); }); } getExistCells() { return Array.from(this.getElementsByTagName(this.cell.name)); } isCellsExist() { return this.getExistCells().length > 0; } connectedCallback() { super.connectedCallback(); this.addEventListener(this.cell.events.resize, this.cellResizeHandler.bind(this)); this.addEventListener(this.cell.events.add, this.cellAddHandler.bind(this)); } shouldCellResize(targetCell) { return this.columnCells.some(item => item.width !== targetCell.width); } static getColumnIndex(cell) { return cell.getAttribute('slot').split('_')[1]; } getColumnCells(columnIndex, arr = this.getExistCells()) { return arr .filter(cell => this.constructor.getColumnIndex(cell) === columnIndex); } cellResizeHandler(e) { const targetCell = e.target; const columnIndex = this.constructor.getColumnIndex(targetCell); this.columnCells = this.getColumnCells(columnIndex); if (this.shouldCellResize(targetCell)) { this.updateColumnCellsWidth(targetCell); this.saveUpdatedColumnCells(targetCell); this.updateColumnTdsWidth(targetCell, columnIndex); } } updateColumnCellsWidth(currentCell) { this.columnCells.forEach((cell) => { cell.width = currentCell.width; }); } updateColumnTdsWidth(currentCell, columnIndex) { [...this.table.querySelectorAll('td')] .filter(cell => cell.dataset.slot.split('_')[1] === columnIndex) .forEach((cell) => { cell.style.setProperty('width', currentCell.width); }); } cellAddHandler(e) { const curItem = e.target; curItem.addEventListener(this.cell.events.remove, this.cellRemoveHandler.bind(this)); curItem.addEventListener(this.cell.events.bgChange, this.cellBgChangeHandler.bind(this)); } getTableCell(fusionCell) { const curCellSlot = fusionCell.slot; return this.table.querySelector(`[data-slot="${curCellSlot}"]`); } cellRemoveHandler(e) { const curCell = e.target; const cell = this.getTableCell(curCell); if (cell) { const cellSlot = cell.querySelector(`[name="${curCell.slot}"]`); cellSlot.removeAttribute('name'); cell.removeAttribute('data-slot'); } } cellBgChangeHandler(e) { const fusionCell = e.target; const cell = this.getTableCell(fusionCell); if (cell) { FusionTable.setTableCellBg(cell, fusionCell); } } static setTableCellBg(cell, fusionCell) { cell.style.background = fusionCell['background-color']; } initTable() { this.table = document.createElement('table'); this.table.appendChild(this.initThead()); this.table.appendChild(this.initTbody()); } clearTable() { this.table.innerHTML = ''; this.deleteAllFusionCells(); } static getSlotKey(rowIndex, cellIndex) { return `${rowIndex}_${cellIndex}`; } static addCellSlot(cell, key) { const slot = document.createElement('slot'); slot.setAttribute('name', key); cell.appendChild(slot); } addFusionCell(key) { const { componentName, defaultTemplate } = this.cell.component.options; const unit = 'px'; FusionApi.createElement( componentName, { width: { value: `100${unit}`, }, color: { value: this.color, }, 'font-size': { value: this['font-size'], }, slot: { value: key, }, }, defaultTemplate, this, `#${this.id}`, {}, ); } addCustomCell(cell, rowIndex, cellIndex) { const key = FusionTable.getSlotKey(rowIndex, cellIndex); if (this.generateMissedCells) { this.generateMissedSlots(cell, key); } else { FusionTable.setCellSlotAttr(cell, key); this.addFusionCell(key); } } generateMissedSlots(cell, key) { const fusionCell = this.getExistCells().find(currentCell => currentCell.slot === key); if (fusionCell) { FusionTable.setCellSlotAttr(cell, key); FusionTable.setTableCellBg(cell, fusionCell); } } static setCellSlotAttr(cell, key) { cell.setAttribute('data-slot', key); FusionTable.addCellSlot(cell, key); } initThead() { this.thead = document.createElement('thead'); const row = this.thead.insertRow(0); this.addRowCells(row, 0); return this.thead; } initTbody() { this.tbody = document.createElement('tbody'); this.addRows(); return this.tbody; } addRows() { for (let index = 0; index < this.rows - 1; index += 1) { if (!this.tbody.rows[index]) { const tr = this.tbody.insertRow(index); const rowIndex = index + 1; this.addRowCells(tr, rowIndex); } } } deleteRows(count) { const { rows } = this.tbody; for (let index = 0; index < count; index += 1) { const rowIndex = rows.length - 1; const row = rows[rowIndex]; this.tbody.deleteRow(rowIndex); this.deleteRowFusionCells(row); } } addRowCells(row, rowIndex) { for (let index = 0; index < parseInt(this.columns, 10); index += 1) { if (!row.cells[index]) { const cell = row.insertCell(index); this.addCustomCell(cell, rowIndex, cell.cellIndex); } } } deleteRowFusionCells(row) { const cells = Array.from(row.cells); cells.forEach((cell) => { this.deleteFusionCell(cell.dataset.slot); }); } addCellsListeners() { this.getExistCells().forEach((cell) => { cell.addEventListener(this.cell.events.remove, this.cellRemoveHandler.bind(this)); cell.addEventListener(this.cell.events.bgChange, this.cellBgChangeHandler.bind(this)); }); } deleteAllFusionCells() { this.getExistCells().forEach((cell) => { this.removeChild(cell); }); } deleteFusionCell(key) { const cell = this.getExistCells().find(currentCell => currentCell.slot === key); this.removeChild(cell); } deleteFusionCells(row, count) { const { cells } = row; for (let index = 0; index < count; index += 1) { const cellIndex = cells.length - 1; const cell = cells[cellIndex]; row.deleteCell(cellIndex); this.deleteFusionCell(cell.dataset.slot); } } addCells(parent) { const rows = Array.from(parent.rows); rows.forEach((row) => { this.addRowCells(row, row.rowIndex); }); } addColumns() { this.addCells(this.thead); this.addCells(this.tbody); } deleteCells(parent, count) { const rows = Array.from(parent.rows); rows.forEach((row) => { this.deleteFusionCells(row, count); }); } deleteColumns(count) { this.deleteCells(this.thead, count); this.deleteCells(this.tbody, count); } static isCountIncreased(oldVal, newVal) { return newVal > oldVal; } updateContent(attr, oldVal, newVal) { const isIncreased = FusionTable.isCountIncreased(oldVal, newVal); const difference = FusionTable.checkDifference(oldVal, newVal); switch (attr) { case 'rows': this.updateRows(difference, isIncreased); break; case 'columns': this.updateColumns(difference, isIncreased); break; default: break; } } static checkDifference(oldVal, newVal) { return Math.abs(oldVal - newVal); } updateRows(count, isIncreased) { isIncreased ? this.addRows() : this.deleteRows(count); } updateColumns(count, isIncreased) { isIncreased ? this.addColumns() : this.deleteColumns(count); } fillTable(prop, oldV, newV) { (!oldV) ? this.initTable() : this.updateContent(prop, oldV, newV); } updateTable(changedProps) { Array.from(changedProps.keys()).every((prop) => { const newV = +this[prop]; const oldV = +changedProps.get(prop); (!newV) ? this.clearTable() : this.fillTable(prop, oldV, newV); return true; }); } setWidthValue(value) { return (this.prevTableOffsetWidth > value) ? this.prevTableOffsetWidth : value; } isMinTableWidth() { return this.prevTableOffsetWidth === this.table.offsetWidth; } compareWidth(value) { if (this.table) { if (value < this.table.offsetWidth) { this.isMinTableWidth() ? this.setMinWidth(this.prevTableOffsetWidth) : this.setMinWidth(); } this.prevTableOffsetWidth = this.table.offsetWidth; } } static isStructureAttr(changedProps) { return changedProps.has('rows') || changedProps.has('columns'); } static isTableStyleAttrs(changedProps) { const tableStyleProps = [ 'border-color', 'border-width', 'background-color', ]; return tableStyleProps.filter(prop => changedProps.has(prop)).pop(); } static isCellStyleAttrs(changedProps) { const cellStyleProps = [ 'color', 'font-size', 'font-family', 'font-weight', 'font-style', 'padding-top', 'padding-bottom', 'padding-left', 'padding-right', ]; return cellStyleProps.filter(prop => changedProps.has(prop)).pop(); } update(changedProps) { const tableStyleProps = FusionTable.isTableStyleAttrs(changedProps); const cellsStyleProps = FusionTable.isCellStyleAttrs(changedProps); if (!this.isRendered) { this.initTable(); } else if (FusionTable.isStructureAttr(changedProps)) { this.updateTable(changedProps); } else if (tableStyleProps) { this.setAttribute(tableStyleProps, this[tableStyleProps]); } else if (cellsStyleProps) { this.setupItemsStyles(cellsStyleProps); } super.update(changedProps); } setupItemsStyles(prop) { const items = this.getExistCells(); items.forEach((item) => { item.setAttribute(prop, this[prop]); }); } setMinWidth(value = 0) { this.style['min-width'] = `${value}px`; } firstUpdated(changedProps) { super.firstUpdated(changedProps); this.addCellsListeners(); this.generateMissedCells = false; } static getStyle() { const styleRoot = super.getStyle(); return ` ${styleRoot} :host { display: block; } :host table { width:100%; height: 100%; border-collapse: separate; border-spacing: 0; background: var(--background-color); border-radius: var(--border-radius); } :host thead td { font-weight: bold; } :host thead tr:first-child td{ border-top: var(--border-width) solid var(--border-color); } :host tr td:first-child { border-left: var(--border-width) solid var(--border-color); } :host thead tr:first-child td:first-child { border-top-left-radius: var(--border-radius); } :host thead tr:first-child td:last-child { border-top-right-radius: var(--border-radius); } :host tbody tr:last-child td:first-child { border-bottom-left-radius: var(--border-radius); } :host tbody tr:last-child td:last-child { border-bottom-right-radius: var(--border-radius); } :host td { position: relative; border-right: var(--border-width) solid var(--border-color); border-bottom: var(--border-width) solid var(--border-color); color: var(--color); font-size: var(--font-size); }`; } render() { super.render(); return html` <style> ${FusionTable.getStyle()} </style> ${this.table} ${FusionTable.getSystemSlotTemplate()} `; } } export { FusionTableCell, FusionTable };