components: start implementing multiple selections

This commit is contained in:
Artur Tamborski 2020-11-30 22:28:29 +01:00
parent 96b4a3b72d
commit 0b72986461
4 changed files with 35 additions and 12 deletions

View File

@ -16,7 +16,7 @@ export default function App(): JSX.Element {
<Board <Board
numRows={10} numRows={10}
numCols={10} numCols={10}
numLines={1} numLines={5}
/> />
</div> </div>
<div /> <div />

View File

@ -36,8 +36,11 @@
color: brown; color: brown;
cursor: pointer; cursor: pointer;
&:focus, &:hover { &:hover {
border-color: #8b8be5; border-color: #8b8be5;
outline: none; outline: none;
} }
&:not(hover) {
border-color: #e5e5ea;
}
} }

View File

@ -12,6 +12,7 @@ export type Point = {
type Selection = { type Selection = {
start: Point; start: Point;
end: Point; end: Point;
visible: boolean;
} }
interface IBoardProps { interface IBoardProps {
@ -29,7 +30,7 @@ interface IBoardState {
} }
const Point0: Point = {x: 0, y: 0}; const Point0: Point = {x: 0, y: 0};
const Selection0: Selection = {start: Point0, end: Point0}; const Selection0: Selection = {start: Point0, end: Point0, visible: false};
export default class Board extends React.Component<IBoardProps, IBoardState> { export default class Board extends React.Component<IBoardProps, IBoardState> {
constructor(props: IBoardProps) { constructor(props: IBoardProps) {
@ -42,6 +43,10 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
start: Point0, start: Point0,
end: Point0, end: Point0,
} }
let s = this.state.selections.slice();
s[0].visible = true;
this.setState({...this.state})
} }
moveIsValid(pos: Point): boolean { moveIsValid(pos: Point): boolean {
@ -52,9 +57,19 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
return this.state.isSelecting && lineIsValid; return this.state.isSelecting && lineIsValid;
} }
updateSelection(start: Point, end: Point): Array<Selection> {
let selections = this.state.selections.slice();
let s = selections.find(s => s.visible);
if (s !== undefined)
[s.start, s.end, s.visible] = [start, end, true];
return selections;
}
handleMouseDown(start: Point) { handleMouseDown(start: Point) {
const end = start; const end = start;
let selections = [...this.state.selections]; const selections = this.updateSelection(start, start);
this.setState({...this.state, start, end, selections, isSelecting: true}); this.setState({...this.state, start, end, selections, isSelecting: true});
} }
@ -62,14 +77,16 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
if (!this.moveIsValid(end)) if (!this.moveIsValid(end))
return; return;
this.setState({...this.state, end, isSelecting: false}); const selections = this.updateSelection(this.state.start, end);
this.setState({...this.state, end, selections, isSelecting: false});
} }
handleMouseOver(end: Point) { handleMouseOver(end: Point) {
if (!this.moveIsValid(end)) if (!this.moveIsValid(end))
return; return;
this.setState({...this.state, end}); const selections = this.updateSelection(this.state.start, end);
this.setState({...this.state, end, selections});
} }
renderCell(s: string, pos: Point): JSX.Element { renderCell(s: string, pos: Point): JSX.Element {
@ -86,12 +103,13 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
); );
} }
renderLine(x: number): JSX.Element { renderLine(s: Selection, n: number): JSX.Element {
return ( return (
<Line <Line
key={`Line${x}`} key={`Line${n}`}
start={{...this.state.start}} start={s.start}
end={{...this.state.end}} end={s.end}
visible={s.visible}
cellSize={60} cellSize={60}
/> />
); );
@ -103,8 +121,8 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
oy.map((s, x) => oy.map((s, x) =>
this.renderCell(s, {x, y}))); this.renderCell(s, {x, y})));
let lines = this.state.selections.filter(x => x).map((ox, x) => let lines = this.state.selections.map((s, n) =>
this.renderLine(x)); this.renderLine(s, n));
return ( return (
<div className="Container"> <div className="Container">

View File

@ -20,6 +20,7 @@ interface ILineProps {
start: Point; start: Point;
end: Point; end: Point;
cellSize: number; cellSize: number;
visible: boolean;
} }
export default function Line(props: ILineProps): JSX.Element { export default function Line(props: ILineProps): JSX.Element {
@ -82,6 +83,7 @@ export default function Line(props: ILineProps): JSX.Element {
ry={margin - offset} ry={margin - offset}
{...{x, y, width, height}} {...{x, y, width, height}}
transform={`translate(${tx}, ${ty}), rotate(${r}, ${rx}, ${ry})`} transform={`translate(${tx}, ${ty}), rotate(${r}, ${rx}, ${ry})`}
visibility={props.visible ? 'visible' : 'hidden'}
/> />
); );
} }