Browse Source

Make width and height adjustable

master
Dylan Baker 3 years ago
parent
commit
0dcf852dc5
3 changed files with 101 additions and 21 deletions
  1. 43
    12
      src/Board.tsx
  2. 43
    8
      src/Controls.tsx
  3. 15
    1
      src/index.css

+ 43
- 12
src/Board.tsx View File

@@ -3,29 +3,29 @@ import Cell from './Cell';
3 3
 import Controls from './Controls';
4 4
 import { generateNewGrid } from './lib';
5 5
 
6
-interface Props {
7
-  width?: number;
8
-  height?: number;
9
-  speed?: number;
10
-}
6
+const DEFAULT_WIDTH = 20;
7
+const DEFAULT_HEIGHT = 10;
8
+const DEFAULT_SPEED = 500;
11 9
 
12 10
 interface State {
13 11
   grid: boolean[][];
14 12
   running: boolean;
15 13
   speed: number;
14
+  width: number;
15
+  height: number;
16 16
 }
17 17
 
18
-class Board extends React.Component<Props, State> {
18
+class Board extends React.Component<{}, State> {
19 19
   timer: NodeJS.Timeout | null;
20 20
 
21
-  constructor(props: Props) {
21
+  constructor(props: {}) {
22 22
     super(props);
23
-    const height = props.height ?? 10;
24
-    const width = props.height ?? 20;
25 23
     this.state = {
26
-      grid: Array(height).fill(Array(width).fill(false)),
24
+      grid: Array(DEFAULT_HEIGHT).fill(Array(DEFAULT_WIDTH).fill(false)),
27 25
       running: false,
28
-      speed: 500,
26
+      speed: DEFAULT_SPEED,
27
+      width: DEFAULT_WIDTH,
28
+      height: DEFAULT_HEIGHT,
29 29
     };
30 30
     this.timer = null;
31 31
   }
@@ -63,8 +63,36 @@ class Board extends React.Component<Props, State> {
63 63
     }
64 64
   };
65 65
 
66
+  updateDimensions = (dimensions: { width?: number; height?: number }) => {
67
+    if (dimensions.width) {
68
+      this.setState({ width: dimensions.width });
69
+    }
70
+
71
+    if (dimensions.height) {
72
+      this.setState({ height: dimensions.height });
73
+    }
74
+
75
+    const width = dimensions.width ?? this.state.width;
76
+    const height = dimensions.height ?? this.state.height;
77
+
78
+    const grid = [...this.state.grid];
79
+    while (grid.length < height) {
80
+      grid.push(Array(width).fill(false));
81
+    }
82
+
83
+    const newGrid = grid.map((row) => {
84
+      while (row.length < width) {
85
+        row.push(false);
86
+      }
87
+
88
+      return row;
89
+    });
90
+
91
+    this.setState({ grid: newGrid });
92
+  };
93
+
66 94
   render() {
67
-    const { grid, running, speed } = this.state;
95
+    const { grid, running, speed, width, height } = this.state;
68 96
 
69 97
     return (
70 98
       <div className="board">
@@ -72,6 +100,9 @@ class Board extends React.Component<Props, State> {
72 100
           running={running}
73 101
           speed={speed}
74 102
           toggle={this.toggleRunning}
103
+          width={width}
104
+          height={height}
105
+          updateDimensions={this.updateDimensions}
75 106
           updateSpeed={this.updateSpeed}
76 107
         />
77 108
         {grid.map((row, y) => (

+ 43
- 8
src/Controls.tsx View File

@@ -3,12 +3,23 @@ import React from 'react';
3 3
 interface Props {
4 4
   running: boolean;
5 5
   speed: number;
6
+  width: number;
7
+  height: number;
6 8
   toggle: () => void;
7 9
   updateSpeed: (speed: number) => void;
10
+  updateDimensions: (dimensions: { width?: number; height?: number }) => void;
8 11
 }
9 12
 
10 13
 const Controls = (props: Props) => {
11
-  const { running, speed, toggle, updateSpeed } = props;
14
+  const {
15
+    running,
16
+    speed,
17
+    toggle,
18
+    updateSpeed,
19
+    width,
20
+    height,
21
+    updateDimensions,
22
+  } = props;
12 23
 
13 24
   const goSlower = () => {
14 25
     updateSpeed(speed + 100);
@@ -22,13 +33,37 @@ const Controls = (props: Props) => {
22 33
 
23 34
   return (
24 35
     <div className="controls">
25
-      <button onClick={toggle}>{running ? 'Pause' : 'Play'}</button>
26
-      <div className="speed">
27
-        <button onClick={goSlower}>Slower</button>
28
-        <button disabled={speed <= 100} onClick={goFaster}>
29
-          Faster
30
-        </button>
31
-        <span>{speed}ms</span>
36
+      <div className="controls__row --width">
37
+        <label>
38
+          Width{' '}
39
+          <input
40
+            type="number"
41
+            value={width}
42
+            onChange={(e) =>
43
+              updateDimensions({ width: parseInt(e.currentTarget.value, 10) })
44
+            }
45
+          />
46
+        </label>
47
+        <label>
48
+          Height{' '}
49
+          <input
50
+            type="number"
51
+            value={height}
52
+            onChange={(e) =>
53
+              updateDimensions({ height: parseInt(e.currentTarget.value, 10) })
54
+            }
55
+          />
56
+        </label>
57
+      </div>
58
+      <div className="controls__row">
59
+        <button onClick={toggle}>{running ? 'Pause' : 'Play'}</button>
60
+        <div className="speed">
61
+          <button onClick={goSlower}>Slower</button>
62
+          <button disabled={speed <= 100} onClick={goFaster}>
63
+            Faster
64
+          </button>
65
+          <span>{speed}ms</span>
66
+        </div>
32 67
       </div>
33 68
     </div>
34 69
   );

+ 15
- 1
src/index.css View File

@@ -56,7 +56,7 @@ code {
56 56
 
57 57
 .controls {
58 58
   display: flex;
59
-  margin-bottom: 1em;
59
+  flex-direction: column;
60 60
   width: 100%;
61 61
 }
62 62
 
@@ -80,6 +80,11 @@ code {
80 80
   color: white;
81 81
 }
82 82
 
83
+.controls .controls__row {
84
+  display: flex;
85
+  margin: 1em 0;
86
+}
87
+
83 88
 .controls .speed {
84 89
   align-items: center;
85 90
   display: flex;
@@ -101,3 +106,12 @@ code {
101 106
   cursor: not-allowed;
102 107
   opacity: 0.6;
103 108
 }
109
+
110
+.--width label {
111
+  flex: 1;
112
+}
113
+
114
+.--width input {
115
+  border: 1px solid black;
116
+  font-size: 16px;
117
+}

Loading…
Cancel
Save