Move theme selector to the header and improved about page and styling

This commit is contained in:
2019-09-09 11:49:39 +02:00
parent ee610cc9b6
commit 9fc48df1ce
13 changed files with 265 additions and 100 deletions

11
src/components/Code.js Normal file
View File

@@ -0,0 +1,11 @@
import styled from "styled-components";
export const Code = styled.code`
display: inline-block;
color: white;
background-color: gray;
padding: 0 0.2rem;
line-height: 1.4rem;
`;
export default Code;

View File

@@ -23,43 +23,12 @@ const HorizontalStack = styled.div`
place-content: space-between;
`;
const ThemeSelector = styled.select`
appearance: none;
border: 1px solid transparent;
background: none;
border-radius: 3px;
// padding: 5px;
line-height: 1.5em;
color: ${({ theme }) => theme.body.color};
font-size: ${({ theme }) => theme.body.fontSize};
font-family: ${({ theme }) => theme.body.fontFamily};
height: 100%;
width: 100%;
cursor: pointer;
background-image: url('data:image/svg+xml;utf8,
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<polygon points="0,3 16,3 8,13" fill="${({ theme }) => theme.select.color.replace("#", "%23")}" />
</svg>');
background-repeat: no-repeat;
background-position: right 0 center;
background-size: 1rem 1rem;
outline-offset: 3px;
&:active,
&:focus,
&:hover {
outline: 1px solid silver;
}
`;
export const ControlPanel = ({
paused,
started,
pauseSnake,
stopSnake,
startSnake,
theme,
changeTheme,
fps,
zoom,
setFps,
@@ -67,14 +36,6 @@ export const ControlPanel = ({
zoomOut
}) => (
<Layout>
<HorizontalStack style={{ minHeight: "2rem", lineHeight: "2rem" }}>
<ThemeSelector onChange={e => changeTheme(e.target.value)} value={theme}>
<option value="light">Light</option>
<option value="dark">Miami Night</option>
<option value="darkOcean">Dark Ocean</option>
<option value="default">Black / White</option>
</ThemeSelector>
</HorizontalStack>
<HorizontalStack style={{ minHeight: "2rem", lineHeight: "2rem" }}>
<span>
Zoom: <b>{zoom}</b>

View File

@@ -0,0 +1,10 @@
import React from "react";
import styled from "styled-components";
const Section = styled.div``;
export const PageSection = ({ children }) => {
return <Section>{children}</Section>;
};
export default PageSection;

View File

@@ -1,6 +1,7 @@
import React from "react";
import styled from "styled-components";
import { NavLink } from "react-router-dom";
import ThemeSelector from "./ThemeSelector.js";
const MenuPanel = styled.ul`
display: flex;
@@ -8,17 +9,18 @@ const MenuPanel = styled.ul`
const MenuItem = styled.li`
display: inline-block;
margin-right: 0.5rem;
min-width: 3.125rem;
`;
const MenuButton = styled(NavLink)`
display: inline-block;
text-align: center;
text-decoration: none;
border: 1px solid silver;
border: 1px solid ${({ theme }) => theme.button.borderColor};
background: ${props => props.theme.header.menuButton.background};
color: ${props => props.theme.header.menuButton.color};
padding: 0.3125rem;
margin-right: 0.5rem;
border-radius: 0.125rem;
min-width: 3.125rem;
&.active {
@@ -44,6 +46,9 @@ const HeaderMenu = () => (
About
</MenuButton>
</MenuItem>
<MenuItem>
<ThemeSelector border />
</MenuItem>
</MenuPanel>
);

View File

@@ -1,9 +1,5 @@
import styled from "styled-components";
const Page = styled.div`
max-width: 60rem;
margin: 0 auto;
padding: 0.5em;
`;
const Page = styled.div``;
export default Page;

View File

@@ -0,0 +1,30 @@
import React from "react";
import styled, { css } from "styled-components";
export const Content = styled.div`
${({ content }) =>
content === PageSection.content.center &&
css`
max-width: 60rem;
margin: 0 auto;
// padding: 0.5em;
`}
`;
const contentPosition = {
center: "center",
stretch: "stretch"
};
export const PageSection = ({ content, children, className } = { content: contentPosition.stretch }) => {
return (
<div className={className}>
<Content content={content}>{children}</Content>
</div>
);
};
PageSection.content = contentPosition;
PageSection.Content = Content;
export default PageSection;

View File

@@ -0,0 +1,58 @@
import React from "react";
import { connect } from "react-redux";
import styled from "styled-components";
import { module as uiModule, changeTheme } from "../redux/ui.js";
const StyledSelect = styled.select`
appearance: none;
border: 1px solid ${({ border, theme }) => (border ? theme.select.borderColor : "transparent")};
background: none;
border-radius: 3px;
padding: 0 1.8rem 0 .5rem;
line-height: 1.5em;
color: ${({ theme }) => theme.body.color};
font-size: ${({ theme }) => theme.body.fontSize};
font-family: ${({ theme }) => theme.body.fontFamily};
height: 100%;
min-width: 8.375rem;
// width: 100%;
cursor: pointer;
background-image: url('data:image/svg+xml;utf8,
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<polygon points="0,3 16,3 8,13" fill="${({ theme }) => theme.select.color.replace("#", "%23")}" />
</svg>');
background-repeat: no-repeat;
background-position: right ${({ border }) => (border ? ".5rem" : 0)} center;
background-size: 1rem 1rem;
outline-offset: ${({ border }) => (border ? 0 : ".1875rem")};
&:active,
&:focus,
&:hover {
outline: 1px solid silver;
}
`;
const ThemeSelector = ({ theme, changeTheme, border }) => {
return (
<StyledSelect border={border} onChange={e => changeTheme(e.target.value)} value={theme}>
<option value="light">Light</option>
<option value="dark">Miami Night</option>
<option value="darkOcean">Dark Ocean</option>
<option value="default">Black / White</option>
</StyledSelect>
);
};
const mapStateToProps = state => ({
...state[uiModule.name]
});
const mapActionsToProps = {
changeTheme
};
export default connect(
mapStateToProps,
mapActionsToProps
)(ThemeSelector);

View File

@@ -1,7 +1,31 @@
import styled from "styled-components";
import styled, { css } from "styled-components";
const Title = styled.h1`
font-size: ${props => (props.large ? "3rem" : "1.5rem")};
margin: 0;
font-size: 1.5rem;
line-height: 4rem;
${props =>
props.large &&
css`
font-size: 3rem;
line-height: 4rem;
`}
${props =>
props.larger &&
css`
font-size: 5rem;
line-height: 6rem;
`}
${props =>
props.sub &&
css`
text-transform: uppercase;
font-size: 1.4rem;
line-height: 1.3rem;
`};
`;
export default Title;

View File

@@ -1,16 +1,71 @@
import React from "react";
import styled from "styled-components";
import styled, { css } from "styled-components";
import Title from "../components/Title.js";
import PageSection from "../components/PageSection.js";
import Code from "../components/Code.js";
const Code = styled.code`
font-weight: bold;
color: white;
const MainPageSection = styled(PageSection)`
background-color: ${({ theme }) => theme.colors.pageSectionMainColor};
min-height: 20rem;
${PageSection.Content} {
box-sizing: border-box;
padding: 1rem 2rem;
}
`;
const StandardPageSection = styled(PageSection)`
background-color: ${({ theme }) => theme.colors.pageSectionStandardColor};
${PageSection.Content} {
box-sizing: border-box;
padding: 2rem 8rem;
}
`;
const AlternatePageSection = styled(PageSection)`
background-color: ${({ theme }) => theme.colors.pageSectionAlternateColor};
${PageSection.Content} {
box-sizing: border-box;
padding: 2rem 8rem;
}
`;
const Icon = styled.div`
font-size: 150pt;
display: inline-block;
`;
const Layout = styled.div`
display: flex;
width: 100%;
// place-content: center;
// justify-content: space-around;
// align-content: space-around;
margin-top: 2rem;
${({ direction }) =>
direction === "horizontal" &&
css`
flex-direction: row;
`}
${({ direction }) =>
direction === "vertical" &&
css`
flex-direction: column;
`}
`;
export const About = () => (
<React.Fragment>
<Title large>About Crafity Snake</Title>
<p>Play snake in your browser using HTML 5 and Javascript.</p>
<MainPageSection content={PageSection.content.center}>
<Layout style={{ justifyContent: "center" }} direction={"horizontal"}>
<Layout style={{ width: "30rem", placeContent: "center" }} direction={"vertical"}>
<Title larger>Crafity Snake</Title>
<Title sub>Play snake with HTML 5 and Javascript.</Title>
</Layout>
<Icon>🐍</Icon>
</Layout>
</MainPageSection>
<StandardPageSection content={PageSection.content.center}>
<Title>Introduction</Title>
<p>
This experiment has been created to test out React, Redux and Styled Components and see if it is possible to
@@ -18,9 +73,11 @@ export const About = () => (
change.
</p>
<p>
A couple of noticable features in this game are resumable game play using local storage. The page can be reloaded
or reopened any time and the game should continue from where it was left.
A couple of noticable features in this game are resumable game play using local storage. The page can be
reloaded or reopened any time and the game should continue from where it was left.
</p>
</StandardPageSection>
<AlternatePageSection content={PageSection.content.center}>
<Title>How to play</Title>
<p>
You control the snake using the arrow keys or the <Code>hjkl</Code> keys. Everytime the snake eats an apple the
@@ -30,6 +87,8 @@ export const About = () => (
Other keys to control the game are <Code>r</Code> to (re)start the game. The <Code>s</Code> key to stop the game
and <Code>p</Code> to pause the game.
</p>
</AlternatePageSection>
<StandardPageSection content={PageSection.content.center}>
<Title>Technology</Title>
<p>Snake has been developed with the folowing technologies.</p>
<ul>
@@ -42,6 +101,8 @@ export const About = () => (
<li>pre-commit</li>
<li>Docker</li>
</ul>
</StandardPageSection>
<AlternatePageSection content={PageSection.content.center}>
<Title>Source Code</Title>
<p>The source code is hosted on Crafity&apos;s git repositories at the following location:</p>
<p>
@@ -54,6 +115,7 @@ export const About = () => (
<p>
<Code>npm run dev</Code>
</p>
</AlternatePageSection>
</React.Fragment>
);

View File

@@ -9,6 +9,7 @@ const GlobalStyle = createGlobalStyle`
background: ${props => props.theme.body.background};
color: ${props => props.theme.body.color};
min-height: 100vh;
-webkit-font-smoothing: antialiased;
}
body, input, select {
font-family: ${({ theme }) => theme.body.fontFamily};

View File

@@ -11,7 +11,7 @@ export const colors = {
colorInactive: "#97727e",
colorAlternate: "#ecb1c5",
shadowColor: "#222",
borderColor: "#222",
borderColor: "silver",
borderColorActive: "#e6b4c4",
borderColorInactive: "#97727e",
spinnerShadow: "#444",

View File

@@ -21,7 +21,10 @@ export const defaultColors = {
snakePartHueAlive: "340",
snakePartHueDied: "0",
snakePartLightness: "0%",
selectColor: "black"
selectColor: "black",
pageSectionMainColor: "#eaeaea",
pageSectionStandardColor: "white",
pageSectionAlternateColor: "#fafafa"
};
const mapRange = (l, i, min, max) => Math.round((max - min) * ((l - i) / l) + min);
@@ -45,6 +48,7 @@ export const renderTheme = themeColors => {
borderWidth: `${1 / 16}rem`
},
select: {
borderColor: colors.borderColor,
color: colors.selectColor
},
header: {

View File

@@ -18,7 +18,10 @@ export const colors = {
spinnerHighlight: "#db7093",
cardFoldHighlight: "#ad5a75",
cardFoldShadow: "#bdb19a",
selectColor: "#db7093"
selectColor: "#db7093",
pageSectionMainColor: "papayawhip",
pageSectionStandardColor: "white",
pageSectionAlternateColor: "#fafafa"
};
const mapRange = (l, i, min, max) => Math.round((max - min) * ((l - i) / l) + min);