UNPKG

@iobroker/adapter-react-v5

Version:

React components to develop ioBroker interfaces with react.

204 lines 9.28 kB
/** * Copyright 2022-2024, Denis Haev <dogafox@gmail.com> * * MIT License * */ import React, { Component } from 'react'; import { Table, Skeleton } from '@mui/material'; export class TableResize extends Component { resizerRefTable; resizerActiveIndex; resizerActiveDiv; resizerCurrentWidths; widthFilled = false; installTimeout = null; resizerMin = 0; resizerMinNext = 0; resizerPosition = 0; resizerOldWidth = 0; resizerOldWidthNext = 0; constructor(props) { super(props); this.resizerRefTable = React.createRef(); this.resizerActiveIndex = null; this.resizerActiveDiv = null; this.resizerCurrentWidths = []; } componentDidMount() { this.resizerInstall(); } componentWillUnmount() { this.resizerUninstall(); } resizerInstall() { if (this.resizerRefTable.current && !this.resizerRefTable.current._installed) { this.resizerRefTable.current._installed = true; const ths = this.resizerRefTable.current.querySelectorAll('th'); const widthsStored = (window._localStorage || window.localStorage).getItem(`App.${this.props.name || 'history'}.table`); this.widthFilled = false; if (widthsStored) { try { this.resizerCurrentWidths = JSON.parse(widthsStored); this.widthFilled = true; } catch { // ignore } } if (this.widthFilled) { if (this.resizerCurrentWidths.length !== ths.length) { this.resizerCurrentWidths = []; this.widthFilled = false; } else { const tableWidth = this.resizerRefTable.current.offsetWidth; let storedWidth = 0; for (let w = 0; w < this.resizerCurrentWidths.length; w++) { if (window.isFinite(this.resizerCurrentWidths[w])) { storedWidth += this.resizerCurrentWidths[w]; } else { storedWidth = null; break; } } if (storedWidth !== null && Math.abs(storedWidth - tableWidth) > 20) { this.resizerCurrentWidths = []; this.widthFilled = false; } } } for (let i = 0; i < ths.length; i++) { !this.widthFilled && this.resizerCurrentWidths.push(ths[i].offsetWidth); // last column does need a handle if (i < ths.length - 1) { const div = window.document.createElement('div'); div.dataset.index = i.toString(); div.onmousedown = this.resizerMouseDown; div.ondblclick = this.resizerReset; div.title = this.props.dblTitle || 'Double click to reset table layout'; div.className = 'resize-handle'; ths[i].appendChild(div); } } if (this.widthFilled) { this.resizerApplyWidths(); } } else { this.installTimeout = setTimeout(() => { this.installTimeout = null; this.resizerInstall(); }, 100); } } resizerReset = () => { for (let c = 0; c < this.resizerCurrentWidths.length; c++) { this.resizerCurrentWidths[c] = (this.props.initialWidths || [])[c] || 'auto'; } (window._localStorage || window.localStorage).setItem(`App.${this.props.name || 'history'}.table`, JSON.stringify(this.resizerCurrentWidths)); this.resizerApplyWidths(); }; resizerUninstall() { this.installTimeout && clearTimeout(this.installTimeout); this.installTimeout = null; // resizer if (this.resizerRefTable.current && this.resizerRefTable.current._installed) { this.resizerRefTable.current._installed = false; const ths = this.resizerRefTable.current.querySelectorAll('th'); for (let i = 0; i < ths.length; i++) { const div = ths[i].querySelector('.resize-handle'); if (div) { div.onmousedown = null; div.remove(); } } } } resizerApplyWidths() { const gridTemplateColumns = []; if (this.resizerCurrentWidths.length) { for (let c = 0; c < this.resizerCurrentWidths.length; c++) { if (this.resizerCurrentWidths[c]) { gridTemplateColumns.push(this.resizerCurrentWidths[c] !== 'auto' ? `${this.resizerCurrentWidths[c]}px` : 'auto'); } else if (this.props.initialWidths && this.props.initialWidths[c]) { gridTemplateColumns.push(this.props.initialWidths[c] !== 'auto' ? `${this.props.initialWidths[c]}px` : 'auto'); } else { gridTemplateColumns.push('auto'); } } } else if (this.props.initialWidths) { for (let c = 0; c < this.props.initialWidths.length; c++) { if (this.props.initialWidths[c]) { gridTemplateColumns.push(this.props.initialWidths[c] !== 'auto' ? `${this.props.initialWidths[c]}px` : 'auto'); } else { gridTemplateColumns.push('auto'); } } } if (this.resizerRefTable.current && gridTemplateColumns.length) { this.resizerRefTable.current.style.gridTemplateColumns = gridTemplateColumns.join(' '); } return gridTemplateColumns.length ? gridTemplateColumns.join(' ') : undefined; } resizerMouseMove = (e) => { if (this.resizerActiveDiv && this.resizerActiveIndex !== null) { const width = this.resizerOldWidth + e.clientX - this.resizerPosition; const widthNext = this.resizerOldWidthNext - e.clientX + this.resizerPosition; if ((!this.resizerMin || width > this.resizerMin) && (!this.resizerMinNext || widthNext > this.resizerMinNext)) { this.resizerCurrentWidths[this.resizerActiveIndex] = width; this.resizerCurrentWidths[this.resizerActiveIndex + 1] = widthNext; this.resizerApplyWidths(); } } }; resizerMouseUp = () => { (window._localStorage || window.localStorage).setItem(`App.${this.props.name || 'history'}.table`, JSON.stringify(this.resizerCurrentWidths)); this.resizerActiveIndex = null; this.resizerActiveDiv = null; window.removeEventListener('mousemove', this.resizerMouseMove); window.removeEventListener('mouseup', this.resizerMouseUp); }; resizerMouseDown = (e) => { if (this.resizerActiveIndex === null || this.resizerActiveIndex === undefined) { console.log(`Mouse down ${e.target?.dataset.index}`); this.resizerActiveIndex = parseInt(e.target?.dataset.index || '0', 10); this.resizerActiveDiv = e.target; this.resizerMin = this.props.minWidths ? this.props.minWidths[this.resizerActiveIndex] : 0; this.resizerMinNext = this.props.minWidths ? this.props.minWidths[this.resizerActiveIndex + 1] : 0; this.resizerPosition = e.clientX; let ths; if (this.resizerCurrentWidths[this.resizerActiveIndex] === 'auto') { ths = this.resizerRefTable.current?.querySelectorAll('th'); if (ths) { this.resizerCurrentWidths[this.resizerActiveIndex] = ths[this.resizerActiveIndex].offsetWidth; } } if (this.resizerCurrentWidths[this.resizerActiveIndex + 1] === 'auto') { ths = ths || this.resizerRefTable.current?.querySelectorAll('th'); if (ths) { this.resizerCurrentWidths[this.resizerActiveIndex + 1] = ths[this.resizerActiveIndex + 1].offsetWidth; } } this.resizerOldWidth = this.resizerCurrentWidths[this.resizerActiveIndex]; this.resizerOldWidthNext = this.resizerCurrentWidths[this.resizerActiveIndex + 1]; window.addEventListener('mousemove', this.resizerMouseMove); window.addEventListener('mouseup', this.resizerMouseUp); } }; render() { if (this.props.ready === false) { return React.createElement(Skeleton, null); } const style = { gridTemplateColumns: this.resizerApplyWidths() }; return (React.createElement(Table, { stickyHeader: this.props.stickyHeader, size: this.props.size || 'small', className: this.props.className, sx: this.props.sx, ref: this.resizerRefTable, style: { ...(this.props.style || undefined), ...style } }, this.props.children)); } } //# sourceMappingURL=TableResize.js.map