components: rewrite layout with CSS Grid, add line drawing

This commit is contained in:
Artur Tamborski 2020-11-27 19:00:24 +01:00
parent 6468f94c61
commit 9001deaf3a
4 changed files with 131 additions and 46 deletions

View File

@ -1,5 +1,9 @@
.App {
max-width: 80vw;
max-height: 100vh;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 1fr;
grid-column-gap: 0;
grid-row-gap: 0;
}

View File

@ -8,8 +8,15 @@ import './App.scss';
export default function App(): JSX.Element {
return (
<div className="App">
<Logo />
<Board />
<div />
<div>
<Logo />
<Board
numRows={10}
numCols={10}
/>
</div>
<div />
</div>
);
}

View File

@ -1,24 +1,56 @@
$LetterBaseColor: ghostwhite;
$LetterHoverColor: #d9d9ff;
.Container {
display: grid;
}
.Content, .Overlay {
grid-area: 1 / 1;
}
.Overlay {
user-select: none;
pointer-events: none;
}
.Canvas {
width: 100%;
height: 100%;
}
.Line {
stroke: red;
stroke-width: 10px;
opacity: 0.3;
}
.Board {
display: grid;
justify-content: center;
grid-template-columns: repeat(8, 8vw);
column-gap: 15px;
row-gap: 15px;
user-select: none;
text-align: center;
grid-template-columns: repeat(10, 60px);
}
.Letter {
width: 60px;
height: 60px;
font-weight: bold;
font-size: larger;
padding: 20px;
background: ghostwhite;
border-radius: 1rem;
border-color: #e5e5ea;
font-size: x-large;
font-family: monospace;
padding: 15px;
background: $LetterBaseColor;
text-align: center;
border: 5px solid #e5e5ea;
border-radius: 100%;
color: brown;
cursor: pointer;
&:hover {
background: #e4e4ff;
border-color: $LetterHoverColor;
}
&:focus {
border-color: #8b8be5;
}
}

View File

@ -1,48 +1,90 @@
import React from 'react';
import PropTypes from 'prop-types';
import './Board.scss';
export default class Board extends React.Component {
interface IBoardProps {
numRows: number;
numCols: number;
}
static propTypes = {
clickHandler: PropTypes.func,
};
type Position = [x: number, y: number];
genSquares() {
let squares = [];
for (let i = 0; i < 64; i++) {
let x = String.fromCharCode(i % 8 + 65);
let y = String.fromCharCode(i / 8 + 49);
let letter = x + y;
squares.push(
<div
id={letter}
className="Letter"
>
{letter}
</div>
);
interface IBoardState {
board: string[][];
isSelectingWord: boolean;
startPos: Position;
}
export default class Board extends React.Component<IBoardProps, IBoardState> {
private line: React.RefObject<SVGLineElement>;
private line_x1: string;
private line_y1: string;
constructor(props: IBoardProps) {
super(props);
this.state = {
board: Array(props.numCols).fill(Array(props.numRows).fill('·')),
isSelectingWord: false,
startPos: [0, 0],
}
return squares;
this.line = React.createRef();
this.line_x1 = "0px";
this.line_y1 = "0px";
}
onMouseMove() {
return 1;
handleMouseDown(startPos: Position) {
this.setState({...this.state, startPos, isSelectingWord: true});
}
onMouseDown() {
return 1;
handleMouseUp(startPos: Position) {
let [x, y] = startPos;
this.line_x1 = `${y * 100}px`;
this.line_y1 = `${x * 100}px`;
this.setState({...this.state, startPos, isSelectingWord: false});
}
render() {
handleMouseOver(currentPos: Position) {
if (!this.state.isSelectingWord)
return;
}
render(): JSX.Element {
let letters =
this.state.board.map((ox, x) =>
ox.map((s, y) =>
<button
key={`${x}${y}`}
className="Letter"
onMouseUp={() => this.handleMouseUp([x, y])}
onMouseDown={() => this.handleMouseDown([x, y])}
onMouseOver={() => this.handleMouseOver([x, y])}
>
{s}
</button>
));
return (
<div
className="Board"
onMouseDown={this.onMouseDown}
onMouseMove={this.onMouseMove}
>
{this.genSquares()}
<div className="Container">
<div className="Content">
<div className="Board">
{letters}
</div>
</div>
<div className="Overlay">
<svg className="Canvas">
<line
className="Line"
ref={this.line}
x1={this.line_x1}
y1={this.line_y1}
x2="0"
y2="0"
/>
</svg>
</div>
</div>
);
}