diff --git a/src/components/Apple.js b/src/components/Apple.js
new file mode 100644
index 0000000..104b15a
--- /dev/null
+++ b/src/components/Apple.js
@@ -0,0 +1,17 @@
+import styled from "styled-components";
+
+export const Apple = styled.div.attrs({ role: "img", "aria-label": "apple" })`
+ width: ${({ theme }) => theme.snake.cell.size};
+ height: ${({ theme }) => theme.snake.cell.size};
+ display: inline-block;
+ font-size: 1.3rem;
+ vertical-align: top;
+ line-height: 1.8rem;
+ padding-left: 0.0625rem;
+ &:after {
+ content: "${props => (!props.died ? "🍎" : "🐛")}";
+ display: inline-block;
+ }
+`;
+
+export default Apple;
diff --git a/src/components/SnakePart.js b/src/components/SnakePart.js
new file mode 100644
index 0000000..a8763db
--- /dev/null
+++ b/src/components/SnakePart.js
@@ -0,0 +1,29 @@
+import styled, { css } from "styled-components";
+
+export const SnakePart = styled.div`
+ width: ${({ theme }) => theme.snake.cell.size};
+ height: ${({ theme }) => theme.snake.cell.size};
+ display: inline-block;
+ font-size: 1.3rem;
+ vertical-align: top;
+ line-height: 1.8rem;
+ padding-left: 0.0625rem;
+
+ ${props =>
+ !props.died
+ ? css`
+ background-color: ${props => props.value && `hsl(340, ${props.value.brightness}%, 65%)`};
+ box-shadow: 1px 1px 2px #ddd inset, -1px -1px 2px gray inset;
+ `
+ : css`
+ background-color: ${props => props.value && `hsl(0, 0%, ${100 - props.value.brightness}% )`};
+ box-shadow: 1px 1px 2px #ddd inset, -1px -1px 2px gray inset;
+
+ &:after {
+ content: "${props => props.value && props.value.index === 0 && "💀"}";
+ display: inline-block;
+ }
+ `}
+`;
+
+export default SnakePart;
diff --git a/src/components/Stage.js b/src/components/Stage.js
index e69de29..4330ab9 100644
--- a/src/components/Stage.js
+++ b/src/components/Stage.js
@@ -0,0 +1,30 @@
+import React from "react";
+import styled from "styled-components";
+
+const Row = styled.div`
+ white-space: nowrap;
+`;
+
+const Cell = styled.div`
+ width: ${({ theme }) => theme.snake.cell.size};
+ height: ${({ theme }) => theme.snake.cell.size};
+ border: ${({ theme }) => theme.snake.cell.border};
+ display: inline-block;
+ vertical-align: top;
+ text-align: center;
+ box-shadow: 1px 1px 4px gray inset, -1px -1px 4px #fff inset;
+`;
+
+export const Stage = ({ data, children }) => (
+
+ {data.map((r, y) => (
+
+ {r.map((c, x) => (
+ | {children(c)} |
+ ))}
+
+ ))}
+
+);
+
+export default Stage;
diff --git a/src/containers/Snake.js b/src/containers/Snake.js
index 246d1da..3c3c1f6 100644
--- a/src/containers/Snake.js
+++ b/src/containers/Snake.js
@@ -17,6 +17,9 @@ import {
/* Components */
import ControlPanel from "../components/ControlPanel.js";
import Scoreboard from "../components/Scoreboard.js";
+import Stage from "../components/Stage.js";
+import SnakePart from "../components/SnakePart.js";
+import Apple from "../components/Apple.js";
const Layout = styled.div`
display: flex;
@@ -29,74 +32,6 @@ const SidePanel = styled.div`
flex-direction: column;
`;
-const Row = styled.div`
- white-space: nowrap;
-`;
-
-const Cell = styled.div`
- width: ${({ theme }) => theme.snake.cell.size};
- height: ${({ theme }) => theme.snake.cell.size};
- border: ${({ theme }) => theme.snake.cell.border};
- display: inline-block;
- vertical-align: top;
- text-align: center;
- background-color: ${props => props.theme.snake.cellColors[" "]};
- box-shadow: 1px 1px 4px gray inset, -1px -1px 4px #fff inset;
-`;
-
-const SnakePart = styled.div`
- width: ${({ theme }) => theme.snake.cell.size};
- height: ${({ theme }) => theme.snake.cell.size};
- background-color: ${props => props.value && `hsl(340, ${props.value.brightness}%, 65%)`};
- box-shadow: 1px 1px 2px #ddd inset, -1px -1px 2px gray inset;
-`;
-
-const Apple = styled.div.attrs({ role: "img", "aria-label": "apple" })`
- width: ${({ theme }) => theme.snake.cell.size};
- height: ${({ theme }) => theme.snake.cell.size};
- display: inline-block;
- font-size: 1.3rem;
- vertical-align: top;
- line-height: 1.8rem;
- padding-left: 0.0625rem;
- &:after {
- content: "${props => (!props.died ? "🍎" : "🐛")}";
- display: inline-block;
- }
-`;
-
-const Skull = styled.div.attrs({ role: "img", "aria-label": "skull" })`
- width: ${({ theme }) => theme.snake.cell.size};
- height: ${({ theme }) => theme.snake.cell.size};
- display: inline-block;
- font-size: 1.3rem;
- vertical-align: top;
- line-height: 1.8rem;
- background-color: ${props => props.value && `hsl(0, 0%, ${100 - props.value.brightness}% )`};
- padding-left: 0.0625rem;
- box-shadow: 1px 1px 2px #ddd inset, -1px -1px 2px gray inset;
- &:after {
- content: "${props => props.value && props.value.index === 0 && "💀"}";
- display: inline-block;
- }
-`;
-
-const Grid = ({ data, died }) => (
-
- {data.map((r, y) => (
-
- {r.map((c, x) => (
- |
- {c.type === "apple" && }
- {!died && c.type === "snake" && }
- {died && c.type === "snake" && }
- |
- ))}
-
- ))}
-
-);
-
class Snake extends React.Component {
constructor(props) {
super(props);
@@ -132,7 +67,12 @@ class Snake extends React.Component {
return (
-
+
+ {cell =>
+ (cell.type === "apple" && ) ||
+ (cell.type === "snake" && )
+ }
+