From b2680c6e9eee67bb7d9bd80265df9b9ceb438610 Mon Sep 17 00:00:00 2001 From: Yannis Barlas <yannisbarlas@gmail.com> Date: Wed, 16 Sep 2020 13:41:32 +0300 Subject: [PATCH] backup --- stories/tables/Grid.stories.js | 2 +- stories/tables/TableTool.stories.js | 11 +- .../src/ui/tables/Grid.js | 269 +++----- .../src/ui/tables/TableTool.js | 586 +++++++----------- 4 files changed, 322 insertions(+), 546 deletions(-) diff --git a/stories/tables/Grid.stories.js b/stories/tables/Grid.stories.js index e8d157b59..e64d49e24 100644 --- a/stories/tables/Grid.stories.js +++ b/stories/tables/Grid.stories.js @@ -10,7 +10,7 @@ const Wrapper = styled.div` export const Base = () => ( <Wrapper> - <Grid intialRows={5} initialColumns={5} />; + <Grid /> </Wrapper> ); diff --git a/stories/tables/TableTool.stories.js b/stories/tables/TableTool.stories.js index 3c5d69c75..6fd78c8e9 100644 --- a/stories/tables/TableTool.stories.js +++ b/stories/tables/TableTool.stories.js @@ -1,9 +1,18 @@ import React from 'react'; +import styled from 'styled-components'; // import { lorem } from 'faker' import TableTool from '../../wax-prosemirror-components/src/ui/tables/TableTool'; -export const Base = () => <TableTool />; +const Wrapper = styled.div` + height: 450px; +`; + +export const Base = () => ( + <Wrapper> + <TableTool /> + </Wrapper> +); export default { component: TableTool, diff --git a/wax-prosemirror-components/src/ui/tables/Grid.js b/wax-prosemirror-components/src/ui/tables/Grid.js index 8a54ec75a..05f4f3122 100644 --- a/wax-prosemirror-components/src/ui/tables/Grid.js +++ b/wax-prosemirror-components/src/ui/tables/Grid.js @@ -3,43 +3,20 @@ import PropTypes from 'prop-types'; import styled, { css } from 'styled-components'; import { range } from 'lodash'; -import GridCell from './GridCell'; - -const INITIAL_GRID_SIZE = 5; +const MIN_GRID_SIZE = 20; +const MAX_GRID_SIZE = 20; +const INITIAL_ACTIVE_GRID_SIZE = 1; const CELL_SIZE = 12; const GUTTER = 4; const Wrapper = styled.div` - /* flex-direction: column; */ position: relative; - /* height: 100px; - width: 100px; */ - /* background: turquoise; */ - - border: 1px solid gray; - border-radius: 5px; - box-sizing: border-box; - height: ${props => `${16 + props.rows * (CELL_SIZE + GUTTER)}px`}; + height: ${props => `${props.rows * (CELL_SIZE + GUTTER)}px`}; width: ${props => `${props.columns * (CELL_SIZE + GUTTER)}px`}; - padding: 8px; `; -const StyledRow = styled.div` - display: flex; - flex-direction: row; -`; - -const StyledGridCell = styled(GridCell)` - margin: 1px; -`; - -// .attrs(props => ({ -// style: { -// background: props.active && 'skyblue', -// }, -// })) const StyledCell = styled.div.attrs(({ top, left }) => ({ style: { top, @@ -57,38 +34,19 @@ const StyledCell = styled.div.attrs(({ top, left }) => ({ // top: ${props => props.top}; // left: ${props => props.left}; -/* ${props => props.active && `background: skyblue;`} */ -// const Cell = props => { -// const { active, className, onMouseEnter, rowIndex, columnIndex } = props; - -// return ( -// <StyledCell -// row={rowIndex} -// column={columnIndex} -// active={active} -// className={className} -// onMouseEnter={onMouseEnter} -// /> -// ); -// }; - class Cell extends React.PureComponent { render() { - // console.log('render!'); + console.log('render!'); const { active, // className, - onMouseEnter, + // onMouseEnter, // rowIndex, // columnIndex, top, left, } = this.props; - // if (rowIndex === 0 && columnIndex === 0) { - // console.log(this.props); - // } - return ( <StyledCell style={{ @@ -97,8 +55,7 @@ class Cell extends React.PureComponent { // row={rowIndex} // column={columnIndex} active={active} - // className={className} - onMouseEnter={onMouseEnter} + // onMouseEnter={onMouseEnter} top={top} left={left} /> @@ -106,164 +63,104 @@ class Cell extends React.PureComponent { } } -const Row = props => { - const { activeRows, activeColumns, columns, rowIndex, updateActive } = props; - - return ( - <StyledRow> - {range(columns).map(columnIndex => ( - <StyledGridCell - active={rowIndex < activeRows && columnIndex < activeColumns} - onMouseEnter={() => updateActive(rowIndex + 1, columnIndex + 1)} - key={columnIndex} - /> - ))} - </StyledRow> - ); -}; - -const Grid = props => { - const { className, initialRows, initialColumns } = props; - - const [rows, setRows] = useState(INITIAL_GRID_SIZE); - const [columns, setColumns] = useState(INITIAL_GRID_SIZE); - - const [activeRows, setActiveRows] = useState(1); - const [activeColumns, setActiveColumns] = useState(1); - - // const [state, setState] = useState({ - // rows: 5, - // columns: 5, - // activeRows: 1, - // activeColumns: 1, - // }); +// const Cell = props => { +// console.log('render!'); +// const { +// active, +// // className, +// // onMouseEnter, +// // rowIndex, +// // columnIndex, +// top, +// left, +// } = props; - const updateActive = (rowPosition, columnPosition) => { - console.log('run!'); - // console.log(rowPosition, columnPosition); - // console.log(rowPosition, rows); - // expand - // const newRowCount = - // rowPosition === rows && rowPosition < 20 ? rows + 1 : rows; - // setRows(newRowCount); - // rowPosition === rows && rowPosition < 20 && setRows(rows + 1); - // const newColumnCount = - // columnPosition === columns && columnPosition < 20 ? columns + 1 : columns; - // setColumns(newColumnCount); - // columnPosition === columns && - // columnPosition < 20 && - // setColumns(columns + 1); - setActiveRows(rowPosition); - // setActiveColumns(columnPosition); - // contract - // rowPosition < rows && rows < 20 && rowPosition > 5 && setRows(rows - 1); - // setState({ - // activeRows: rowPosition, - // activeColumns: columnPosition, - // rows: rowPosition === rows && rowPosition < 20 ? rows + 1 : rows, - // columns, - // }); - }; +// return ( +// <StyledCell +// style={{ +// background: active && 'skyblue', +// }} +// // row={rowIndex} +// // column={columnIndex} +// active={active} +// // onMouseEnter={onMouseEnter} +// top={top} +// left={left} +// /> +// ); +// }; - // console.log('render me'); +let counter = 0; - // const { rows, columns, activeRows, activeColumns } = state; +const Grid = props => { + const { className } = props; - // return ( - // <Wrapper className={className}> - // {range(rows).map(rowIndex => { - // return ( - // <Row - // activeRows={activeRows} - // activeColumns={activeColumns} - // columns={columns} - // rowIndex={rowIndex} - // key={rowIndex} - // updateActive={updateActive} - // /> - // ); - // })} + const [rows, setRows] = useState(MIN_GRID_SIZE); + const [columns, setColumns] = useState(MIN_GRID_SIZE); - // <span> - // {activeColumns} x {activeRows} - // </span> - // </Wrapper> - // ); + const [activeRows, setActiveRows] = useState(INITIAL_ACTIVE_GRID_SIZE); + const [activeColumns, setActiveColumns] = useState(INITIAL_ACTIVE_GRID_SIZE); const onMouseMove = e => { - // console.log(e.nativeEvent.offsetX); - // const { offsetX, offsetY } = e.nativeEvent; - // console.log(offsetX, offsetY); - - // console.log(e.clientX, e.clientY); - - // console.log(e_offsetX, e_offsetY); - + counter++; + // console.log(counter); + // const startTime = performance.now(); // get position of our Wrapper within page const container = e.currentTarget.getBoundingClientRect(); const containerX = e.pageX - container.left; const containerY = e.pageY - container.top; const overRow = Math.ceil(containerY / (CELL_SIZE + GUTTER)); - // console.log('offsetY', offsetY, 'overRow', overRow); - const overColumn = Math.ceil(containerX / (CELL_SIZE + GUTTER)); - setActiveRows(overRow); - setActiveColumns(overColumn); - - // overRow === rows && overRow < 20 && setRows(rows + 1); - // overRow + 1 < rows && overRow > 3 && setRows(rows - 1); + // const endTime = performance.now(); + // console.log(endTime - startTime); - if (overColumn < 5) { - setColumns(5); - } else if (overColumn >= 5 && overColumn <= 20) { - setColumns(overColumn + 1); - } - // overColumn < 5 && setColumns(5); - // overColumn >= 5 && overColumn <= 20 && setColumns(overColumn + 1); - - if (overRow < 5) { - setRows(5); - } else if (overRow >= 5 && overRow <= 20) { - setRows(overRow + 1); - } + // if (overColumn < MIN_GRID_SIZE) { + // setColumns(MIN_GRID_SIZE); + // } else if (overColumn >= MIN_GRID_SIZE && overColumn < MAX_GRID_SIZE) { + // setColumns(overColumn + 1); + // } - // overRow < 5 && setRows(5); - // overRow >= 5 && overRow <= 20 && setRows(overRow + 1); + // if (overRow < MIN_GRID_SIZE) { + // setRows(MIN_GRID_SIZE); + // } else if (overRow >= MIN_GRID_SIZE && overRow < MAX_GRID_SIZE) { + // setRows(overRow + 1); + // } - // overColumn === columns && overColumn < 20 && setColumns(columns + 1); - // overColumn + 1 < columns && overColumn > 3 && setColumns(columns - 1); + setActiveRows(overRow); + setActiveColumns(overColumn); }; return ( - <Wrapper - className={className} - onMouseMove={onMouseMove} - columns={columns} - rows={rows} - > - {range(rows).map(rowIndex => - range(columns).map(columnIndex => { - // console.log(rowIndex, columnIndex); - return ( - <Cell - active={rowIndex < activeRows && columnIndex < activeColumns} - key={`${rowIndex}:${columnIndex}`} - rowIndex={rowIndex} - columnIndex={columnIndex} - // onMouseEnter={() => updateActive(rowIndex, columnIndex)} - top={`${rowIndex * CELL_SIZE + rowIndex * GUTTER}px`} - left={`${columnIndex * 12 + columnIndex * GUTTER}px`} - /> - ); - }), - )} - - {/* <span> + <> + <Wrapper + className={className} + onMouseMove={onMouseMove} + columns={columns} + rows={rows} + > + {range(rows).map(rowIndex => + range(columns).map(columnIndex => { + return ( + <Cell + active={rowIndex < activeRows && columnIndex < activeColumns} + key={`${rowIndex}:${columnIndex}`} + rowIndex={rowIndex} + columnIndex={columnIndex} + // onMouseEnter={() => updateActive(rowIndex, columnIndex)} + top={`${rowIndex * CELL_SIZE + rowIndex * GUTTER}px`} + left={`${columnIndex * 12 + columnIndex * GUTTER}px`} + /> + ); + }), + )} + </Wrapper> + + <span> {activeColumns} x {activeRows} - </span> */} - </Wrapper> + </span> + </> ); }; diff --git a/wax-prosemirror-components/src/ui/tables/TableTool.js b/wax-prosemirror-components/src/ui/tables/TableTool.js index 97fd04316..783ed3416 100644 --- a/wax-prosemirror-components/src/ui/tables/TableTool.js +++ b/wax-prosemirror-components/src/ui/tables/TableTool.js @@ -1,11 +1,75 @@ /* eslint-disable react/prop-types */ +/* eslint-disable react/jsx-handler-names */ +/* eslint-disable react/destructuring-assignment */ +/* eslint-disable no-underscore-dangle */ +/* eslint-disable no-plusplus */ +/* eslint-disable prefer-template */ +/* eslint-disable prefer-destructuring */ +/* eslint-disable max-classes-per-file */ +/* eslint-disable jsx-a11y/no-static-element-interactions */ // import cx from 'classnames'; import React, { useState } from 'react'; -// import ReactDOM from 'react-dom'; +import ReactDOM from 'react-dom'; import styled from 'styled-components'; // import clamp from './clamp'; + +const clamp = (min, val, max) => { + if (val < min) { + return min; + } + if (val > max) { + return max; + } + return val; +}; + +const isIntersected = (r1, r2, padding) => { + const pp = padding || 0; + return !( + r2.x - pp > r1.x + r1.w + pp || + r2.x + r2.w + pp < r1.x - pp || + r2.y - pp > r1.y + r1.h + pp || + r2.y + r2.h + pp < r1.y - pp + ); +}; + +const fromXY = (x, y, padding) => { + padding = padding || 0; + return { + x: x - padding, + y: y - padding, + w: padding * 2, + h: padding * 2, + }; +}; + +const fromHTMlElement = el => { + const display = document.defaultView.getComputedStyle(el).display; + if (display === 'contents' && el.children.length === 1) { + // el has no layout at all, use its children instead. + return fromHTMlElement(el.children[0]); + } + const rect = el.getBoundingClientRect(); + return { + x: rect.left, + y: rect.top, + w: rect.width, + h: rect.height, + }; +}; + +const htmlElementToRect = el => { + const rect = el.getBoundingClientRect(); + return { + x: rect.left, + y: rect.top, + w: rect.width, + h: rect.height, + }; +}; + // import htmlElementToRect from './htmlElementToRect'; // import { fromHTMlElement, fromXY, isIntersected } from './rects'; @@ -20,251 +84,45 @@ const GUTTER_SIZE = 5; const CELL_SIZE = 16; const MAX_SIZE = 20; -// class GridCell extends React.PureComponent<any, any, any> { -// render(): React.Element<any> { -// const { x, y, selected } = this.props; -// const style = { -// left: x + 'px', -// top: y + 'px', -// width: CELL_SIZE + 'px', -// height: CELL_SIZE + 'px', -// }; -// const className = cx('czi-table-grid-size-editor-cell', { -// selected, -// }); -// return <div className={className} style={style} />; -// } -// } - -const StyledGridCell = styled.div` - left: ${props => `${props.x}px`}; - top: ${props => `${props.y}px`}; - width: ${props => `${CELL_SIZE}px`}; - height: ${props => `${CELL_SIZE}px`}; -`; - -const GridCell = props => { - const { className, x, y, selected } = props; - - // const className = cx('czi-table-grid-size-editor-cell', { - // selected, - // }); - - return <StyledGridCell x={x} y={y} className={className} />; -}; - -// class TableGridSizeEditor extends React.PureComponent<any, any, any> { -// _ex = 0; -// _ey = 0; -// _mx = 0; -// _my = 0; -// _rafID = 0; -// _ref = null; -// _entered = false; - -// props: { -// close: (val: TableGridSizeEditorValue) => void, -// }; - -// state: TableGridSizeEditorValue = { -// rows: 1, -// cols: 1, -// }; - -// componentWillUnmount(): void { -// if (this._entered) { -// document.removeEventListener('mousemove', this._onMouseMove, true); -// } -// this._rafID && cancelAnimationFrame(this._rafID); -// } - -// render(): React.Element<any> { -// const { rows, cols } = this.state; -// let rr = Math.max(5, rows); -// let cc = Math.max(5, cols); -// if (rr === rows) { -// rr = Math.min(MAX_SIZE, rr + 1); -// } -// if (cc === cols) { -// cc = Math.min(MAX_SIZE, cc + 1); -// } -// const cells = []; -// let ii = 0; -// let y = 0; -// let w = 0; -// let h = 0; -// while (ii < rr) { -// y += GUTTER_SIZE; -// let jj = 0; -// let x = 0; -// while (jj < cc) { -// x += GUTTER_SIZE; -// const selected = ii < rows && jj < cols; -// cells.push( -// <GridCell -// key={`${String(ii)}-${String(jj)}`} -// selected={selected} -// x={x} -// y={y} -// />, -// ); -// x += CELL_SIZE; -// w = x + GUTTER_SIZE; -// jj++; -// } -// y += CELL_SIZE; -// h = y + GUTTER_SIZE; -// ii++; -// } -// const bodyStyle = { width: w + 'px', height: h + 'px' }; - -// return ( -// <div className="czi-table-grid-size-editor" ref={this._onRef}> -// <div -// className="czi-table-grid-size-editor-body" -// onMouseDown={this._onMouseDown} -// onMouseEnter={this._onMouseEnter} -// style={bodyStyle} -// > -// {cells} -// </div> -// <div className="czi-table-grid-size-editor-footer"> -// {rows} X {cols} -// </div> -// </div> -// ); -// } - -// _onRef = (ref: any): void => { -// this._ref = ref; -// }; - -// _onMouseEnter = (e: MouseEvent): void => { -// const node = e.currentTarget; -// if (node instanceof HTMLElement) { -// const rect = fromHTMlElement(node); -// const mx = Math.round(e.clientX); -// const my = Math.round(e.clientY); -// this._ex = rect.x; -// this._ey = rect.y; -// this._mx = mx; -// this._my = my; -// if (!this._entered) { -// this._entered = true; -// document.addEventListener('mousemove', this._onMouseMove, true); -// } -// } -// }; - -// _onMouseMove = (e: MouseEvent): void => { -// const el = this._ref && ReactDOM.findDOMNode(this._ref); -// const elRect = el ? htmlElementToRect(el) : null; -// const mouseRect = fromXY(e.screenX, e.screenY, 10); - -// if (elRect && mouseRect && isIntersected(elRect, mouseRect, 50)) { -// // This prevents `PopUpManager` from collapsing the editor. -// e.preventDefault(); -// e.stopImmediatePropagation(); -// } - -// const mx = Math.round(e.clientX); -// const my = Math.round(e.clientY); -// if (mx !== this._mx || my !== this._my) { -// this._mx = mx; -// this._my = my; -// this._rafID && cancelAnimationFrame(this._rafID); -// this._rafID = requestAnimationFrame(this._updateGridSize); -// } -// }; - -// _updateGridSize = (): void => { -// this._rafID = 0; -// const mx = this._mx; -// const my = this._my; -// const x = mx - this._ex; -// const y = my - this._ey; -// const rr = clamp(1, Math.ceil(y / (CELL_SIZE + GUTTER_SIZE)), MAX_SIZE); -// const cc = clamp(1, Math.ceil(x / (CELL_SIZE + GUTTER_SIZE)), MAX_SIZE); -// const { rows, cols } = this.state; -// if (rows !== rr || cols !== cc) { -// this.setState({ rows: rr, cols: cc }); -// } -// }; - -// _onMouseDown = (e: SyntheticEvent): void => { -// e.preventDefault(); -// this.props.close(this.state); -// }; -// } - -const TableGridSizeEditor = props => { - const [rows, setRows] = useState(1); - const [columns, setColumns] = useState(1); - - let rr = Math.max(5, rows); - let cc = Math.max(5, columns); - if (rr === rows) { - rr = Math.min(MAX_SIZE, rr + 1); +class GridCell extends React.PureComponent { + render() { + console.log('render!'); + const { x, y, selected } = this.props; + const style = { + left: x + 'px', + top: y + 'px', + width: CELL_SIZE + 'px', + height: CELL_SIZE + 'px', + border: '1px solid gray', + boxSizing: 'border-box', + position: 'absolute', + zIndex: 2, + }; + + if (selected) style.background = 'skyblue'; + // const className = cx('czi-table-grid-size-editor-cell', { + // selected, + // }); + return <div style={style} />; } - if (cc === columns) { - cc = Math.min(MAX_SIZE, cc + 1); +} + +class TableGridSizeEditor extends React.PureComponent { + _ex = 0; + _ey = 0; + _mx = 0; + _my = 0; + _rafID = 0; + _ref = null; + _entered = false; + + constructor(props) { + super(props); + this.state = { + rows: 1, + cols: 1, + }; } - const cells = []; - let ii = 0; - let y = 0; - let w = 0; - let h = 0; - while (ii < rr) { - y += GUTTER_SIZE; - let jj = 0; - let x = 0; - while (jj < cc) { - x += GUTTER_SIZE; - const selected = ii < rows && jj < columns; - cells.push( - <GridCell - key={`${String(ii)}-${String(jj)}`} - selected={selected} - x={x} - y={y} - />, - ); - x += CELL_SIZE; - w = x + GUTTER_SIZE; - jj++; - } - y += CELL_SIZE; - h = y + GUTTER_SIZE; - ii++; - } - const bodyStyle = { width: w + 'px', height: h + 'px' }; - - return ( - <div - // className="czi-table-grid-size-editor" - // ref={this._onRef} - > - <div - // className="czi-table-grid-size-editor-body" - // onMouseDown={this._onMouseDown} - // onMouseEnter={this._onMouseEnter} - // style={bodyStyle} - > - {cells} - </div> - <div className="czi-table-grid-size-editor-footer"> - {rows} X {columns} - </div> - </div> - ); - - // _ex = 0; - // _ey = 0; - // _mx = 0; - // _my = 0; - // _rafID = 0; - // _ref = null; - // _entered = false; // props: { // close: (val: TableGridSizeEditorValue) => void, @@ -277,123 +135,135 @@ const TableGridSizeEditor = props => { // this._rafID && cancelAnimationFrame(this._rafID); // } - // render(): React.Element<any> { - // const { rows, cols } = this.state; - // let rr = Math.max(5, rows); - // let cc = Math.max(5, cols); - // if (rr === rows) { - // rr = Math.min(MAX_SIZE, rr + 1); - // } - // if (cc === cols) { - // cc = Math.min(MAX_SIZE, cc + 1); - // } - // const cells = []; - // let ii = 0; - // let y = 0; - // let w = 0; - // let h = 0; - // while (ii < rr) { - // y += GUTTER_SIZE; - // let jj = 0; - // let x = 0; - // while (jj < cc) { - // x += GUTTER_SIZE; - // const selected = ii < rows && jj < cols; - // cells.push( - // <GridCell - // key={`${String(ii)}-${String(jj)}`} - // selected={selected} - // x={x} - // y={y} - // />, - // ); - // x += CELL_SIZE; - // w = x + GUTTER_SIZE; - // jj++; - // } - // y += CELL_SIZE; - // h = y + GUTTER_SIZE; - // ii++; - // } - // const bodyStyle = { width: w + 'px', height: h + 'px' }; - - // return ( - // <div className="czi-table-grid-size-editor" ref={this._onRef}> - // <div - // className="czi-table-grid-size-editor-body" - // onMouseDown={this._onMouseDown} - // onMouseEnter={this._onMouseEnter} - // style={bodyStyle} - // > - // {cells} - // </div> - // <div className="czi-table-grid-size-editor-footer"> - // {rows} X {cols} - // </div> - // </div> - // ); - // } - - // _onRef = (ref: any): void => { - // this._ref = ref; - // }; - - // _onMouseEnter = (e: MouseEvent): void => { - // const node = e.currentTarget; - // if (node instanceof HTMLElement) { - // const rect = fromHTMlElement(node); - // const mx = Math.round(e.clientX); - // const my = Math.round(e.clientY); - // this._ex = rect.x; - // this._ey = rect.y; - // this._mx = mx; - // this._my = my; - // if (!this._entered) { - // this._entered = true; - // document.addEventListener('mousemove', this._onMouseMove, true); - // } - // } - // }; - - // _onMouseMove = (e: MouseEvent): void => { - // const el = this._ref && ReactDOM.findDOMNode(this._ref); - // const elRect = el ? htmlElementToRect(el) : null; - // const mouseRect = fromXY(e.screenX, e.screenY, 10); + _onRef = (ref: any): void => { + this._ref = ref; + }; + + _onMouseEnter = e => { + const node = e.currentTarget; + if (node instanceof HTMLElement) { + const rect = fromHTMlElement(node); + const mx = Math.round(e.clientX); + const my = Math.round(e.clientY); + this._ex = rect.x; + this._ey = rect.y; + this._mx = mx; + this._my = my; + if (!this._entered) { + this._entered = true; + document.addEventListener('mousemove', this._onMouseMove, true); + } + } + }; - // if (elRect && mouseRect && isIntersected(elRect, mouseRect, 50)) { - // // This prevents `PopUpManager` from collapsing the editor. - // e.preventDefault(); - // e.stopImmediatePropagation(); - // } + _onMouseMove = e => { + const el = this._ref && ReactDOM.findDOMNode(this._ref); + const elRect = el ? htmlElementToRect(el) : null; + const mouseRect = fromXY(e.screenX, e.screenY, 10); - // const mx = Math.round(e.clientX); - // const my = Math.round(e.clientY); - // if (mx !== this._mx || my !== this._my) { - // this._mx = mx; - // this._my = my; - // this._rafID && cancelAnimationFrame(this._rafID); - // this._rafID = requestAnimationFrame(this._updateGridSize); - // } - // }; + if (elRect && mouseRect && isIntersected(elRect, mouseRect, 50)) { + // This prevents `PopUpManager` from collapsing the editor. + e.preventDefault(); + e.stopImmediatePropagation(); + } - // _updateGridSize = (): void => { - // this._rafID = 0; - // const mx = this._mx; - // const my = this._my; - // const x = mx - this._ex; - // const y = my - this._ey; - // const rr = clamp(1, Math.ceil(y / (CELL_SIZE + GUTTER_SIZE)), MAX_SIZE); - // const cc = clamp(1, Math.ceil(x / (CELL_SIZE + GUTTER_SIZE)), MAX_SIZE); - // const { rows, cols } = this.state; - // if (rows !== rr || cols !== cc) { - // this.setState({ rows: rr, cols: cc }); - // } - // }; + const mx = Math.round(e.clientX); + const my = Math.round(e.clientY); + if (mx !== this._mx || my !== this._my) { + this._mx = mx; + this._my = my; + this._rafID && cancelAnimationFrame(this._rafID); + this._rafID = requestAnimationFrame(this._updateGridSize); + } + }; + + _updateGridSize = () => { + this._rafID = 0; + const mx = this._mx; + const my = this._my; + const x = mx - this._ex; + const y = my - this._ey; + const rr = clamp(1, Math.ceil(y / (CELL_SIZE + GUTTER_SIZE)), MAX_SIZE); + const cc = clamp(1, Math.ceil(x / (CELL_SIZE + GUTTER_SIZE)), MAX_SIZE); + const { rows, cols } = this.state; + if (rows !== rr || cols !== cc) { + this.setState({ rows: rr, cols: cc }); + } + }; + + _onMouseDown = e => { + e.preventDefault(); + this.props.close(this.state); + }; + + render() { + const { rows, cols } = this.state; + let rr = Math.max(5, rows); + let cc = Math.max(5, cols); + if (rr === rows) { + rr = Math.min(MAX_SIZE, rr + 1); + } + if (cc === cols) { + cc = Math.min(MAX_SIZE, cc + 1); + } + const cells = []; + let ii = 0; + let y = 0; + let w = 0; + let h = 0; + while (ii < rr) { + y += GUTTER_SIZE; + let jj = 0; + let x = 0; + while (jj < cc) { + x += GUTTER_SIZE; + const selected = ii < rows && jj < cols; + cells.push( + <GridCell + key={`${String(ii)}-${String(jj)}`} + selected={selected} + x={x} + y={y} + />, + ); + x += CELL_SIZE; + w = x + GUTTER_SIZE; + jj++; + } + y += CELL_SIZE; + h = y + GUTTER_SIZE; + ii++; + } - // _onMouseDown = (e: SyntheticEvent): void => { - // e.preventDefault(); - // this.props.close(this.state); - // }; -}; + const wrapperStyle = { + border: '1px solid gray', + boxSizing: 'border-box', + position: 'absolute', + zIndex: 2, + }; + + const bodyStyle = { + width: w + 'px', + height: h + 'px', + position: 'relative', + }; + + return ( + <div style={wrapperStyle} ref={this._onRef}> + <div + // className="czi-table-grid-size-editor-body" + onMouseDown={this._onMouseDown} + onMouseEnter={this._onMouseEnter} + style={bodyStyle} + > + {cells} + </div> + <div className="czi-table-grid-size-editor-footer"> + {rows} X {cols} + </div> + </div> + ); + } +} export default TableGridSizeEditor; -- GitLab