Improved button handling and styling
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import styled, { keyframes } from "styled-components";
|
import styled, { keyframes, css } from "styled-components";
|
||||||
|
|
||||||
const fade = keyframes`
|
const fade = keyframes`
|
||||||
from { transform: scale(.7) }
|
from { transform: scale(.7) }
|
||||||
@@ -20,7 +20,12 @@ const Apple = styled.div.attrs(({ theme, zoom }) => ({
|
|||||||
&:after {
|
&:after {
|
||||||
content: "${props => (!props.died ? "🍎" : "🐛")}";
|
content: "${props => (!props.died ? "🍎" : "🐛")}";
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
animation: ${fade} 1s ease-out alternate infinite;
|
animation: ${props =>
|
||||||
|
props.died
|
||||||
|
? "none"
|
||||||
|
: css`
|
||||||
|
${fade} 1s ease-out alternate infinite
|
||||||
|
`};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,14 @@ const SharedStyle = () => `
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ButtonWrapper = styled.div`
|
const ButtonWrapper = styled.div.attrs(({ disabled }) => ({ tabIndex: disabled ? null : 0 }))`
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
outline: ${({ disabled }) => (!disabled ? "1px solid silver" : "none")};
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledButton = styled.button`
|
const StyledButton = styled.button`
|
||||||
@@ -49,13 +54,16 @@ const StyledNavLink = styled(NavLink)`
|
|||||||
${SharedStyle}
|
${SharedStyle}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Button = (props, refs) => {
|
export const Button = props => {
|
||||||
const [hover, setHover] = React.useState(false);
|
const [hover, setHover] = React.useState(false);
|
||||||
const updatedProps = { ...props };
|
const updatedProps = { ...props };
|
||||||
|
const disabled = props.disabled || props.toggle;
|
||||||
let tooltip = null;
|
let tooltip = null;
|
||||||
|
|
||||||
if (props.onClick) {
|
if (props.onClick) {
|
||||||
updatedProps.onClick = e => e.preventDefault() || props.onClick();
|
updatedProps.onKeyUp = e =>
|
||||||
|
!disabled && (e.which === 13 || e.which === 32) && (e.preventDefault() || props.onClick());
|
||||||
|
updatedProps.onClick = e => (!disabled && e.preventDefault()) || props.onClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.href) {
|
if (props.href) {
|
||||||
@@ -72,13 +80,19 @@ export const Button = (props, refs) => {
|
|||||||
|
|
||||||
if (props.icon) {
|
if (props.icon) {
|
||||||
return (
|
return (
|
||||||
<ButtonWrapper onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}>
|
<ButtonWrapper
|
||||||
|
onMouseEnter={() => setHover(true)}
|
||||||
|
onMouseLeave={() => setHover(false)}
|
||||||
|
onKeyUp={updatedProps.onKeyUp}
|
||||||
|
onClick={updatedProps.onClick}
|
||||||
|
disabled={disabled}>
|
||||||
<i
|
<i
|
||||||
|
disabled={disabled}
|
||||||
onClick={updatedProps.onClick}
|
onClick={updatedProps.onClick}
|
||||||
className={`fas fa-${props.icon} ${props.className}`}
|
className={`fas fa-${props.icon} ${props.className}`}
|
||||||
style={{ display: "inline-block", fontSize: `${props.size || 1}rem` }}
|
style={{ display: "inline-block", fontSize: `${props.size || 1}rem` }}
|
||||||
/>
|
/>
|
||||||
{tooltip}
|
{!disabled && tooltip}
|
||||||
</ButtonWrapper>
|
</ButtonWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -98,6 +112,7 @@ export const IconButton = styled(Button)`
|
|||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
text-shadow: 0 0 1px black, 1px 1px 3px #d0bfa3;
|
text-shadow: 0 0 1px black, 1px 1px 3px #d0bfa3;
|
||||||
|
text-shadow: 0 0 1px gray, 0 0 1px #d0bfa3;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -41,9 +41,12 @@ const ThemeSelector = styled.select`
|
|||||||
<polygon points="0,3 16,3 8,13" fill="${({ theme }) => theme.select.color.replace("#", "%23")}" />
|
<polygon points="0,3 16,3 8,13" fill="${({ theme }) => theme.select.color.replace("#", "%23")}" />
|
||||||
</svg>');
|
</svg>');
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: right 0.625rem center;
|
background-position: right 0 center;
|
||||||
background-size: 1rem 1rem;
|
background-size: 1rem 1rem;
|
||||||
outline-offset: 3px;
|
outline-offset: 3px;
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
&:hover {
|
&:hover {
|
||||||
outline: 1px solid silver;
|
outline: 1px solid silver;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,15 +25,20 @@ const MenuButton = styled(NavLink)`
|
|||||||
background: ${props => props.theme.header.menuButton.active.background};
|
background: ${props => props.theme.header.menuButton.active.background};
|
||||||
color: ${props => props.theme.header.menuButton.active.color};
|
color: ${props => props.theme.header.menuButton.active.color};
|
||||||
}
|
}
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
outline: 1px solid silver;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const HeaderMenu = () => (
|
const HeaderMenu = () => (
|
||||||
<MenuPanel>
|
<MenuPanel>
|
||||||
<MenuItem>
|
<MenuItem>
|
||||||
<MenuButton to="/snake">Snake</MenuButton>
|
<MenuButton to="/">Snake</MenuButton>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem>
|
<MenuItem>
|
||||||
<MenuButton to="/" exact>
|
<MenuButton to="/about" exact>
|
||||||
About
|
About
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Route, Switch } from "react-router"; // react-router v4/v5
|
import { Route, Switch } from "react-router";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { hot } from "react-hot-loader/root";
|
import { hot } from "react-hot-loader/root";
|
||||||
|
|
||||||
|
import { MODULE_NAME as UI_MODULE_NAME } from "../redux/ui.js";
|
||||||
|
|
||||||
|
import { ThemeProvider } from "styled-components";
|
||||||
|
import { themes } from "../theming/theme.js";
|
||||||
|
import GlobalStyle from "../theming/GlobalStyle.js";
|
||||||
|
|
||||||
/* Containers */
|
/* Containers */
|
||||||
import Header from "./Header";
|
import Header from "./Header";
|
||||||
import Footer from "./Footer";
|
import Footer from "./Footer";
|
||||||
@@ -10,20 +16,26 @@ import Page from "../components/Page";
|
|||||||
import Home from "./Home";
|
import Home from "./Home";
|
||||||
import Snake from "./Snake";
|
import Snake from "./Snake";
|
||||||
|
|
||||||
const App = ({ title, onNewTitle, getKeyboards, keyboards }) => (
|
const App = ({ theme }) => (
|
||||||
<React.Fragment>
|
<ThemeProvider theme={themes[theme]}>
|
||||||
<Header />
|
<React.Fragment>
|
||||||
<Page>
|
<GlobalStyle />
|
||||||
<Switch>
|
<Header />
|
||||||
<Route exact path="/" component={Home} />
|
<Page>
|
||||||
<Route path="/snake" exact component={Snake} />
|
<Switch>
|
||||||
</Switch>
|
<Route exact path="/" component={Snake} />
|
||||||
</Page>
|
<Route path="/snake" exact component={Snake} />
|
||||||
<Footer />
|
<Route path="/about" exact component={Home} />
|
||||||
</React.Fragment>
|
</Switch>
|
||||||
|
</Page>
|
||||||
|
<Footer />
|
||||||
|
</React.Fragment>
|
||||||
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const mapState = () => ({});
|
const mapState = state => ({
|
||||||
|
theme: state[UI_MODULE_NAME].theme || "light"
|
||||||
|
});
|
||||||
|
|
||||||
const mapActions = {};
|
const mapActions = {};
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import { hot } from "react-hot-loader/root";
|
|
||||||
import { MODULE_NAME as UI_MODULE_NAME } from "../redux/ui.js";
|
|
||||||
|
|
||||||
import { ThemeProvider } from "styled-components";
|
|
||||||
import { themes } from "../theming/theme.js";
|
|
||||||
import GlobalStyle from "../theming/GlobalStyle.js";
|
|
||||||
|
|
||||||
const Document = ({ theme, children }) => (
|
|
||||||
<ThemeProvider theme={themes[theme]}>
|
|
||||||
<React.Fragment>
|
|
||||||
<GlobalStyle />
|
|
||||||
{children}
|
|
||||||
</React.Fragment>
|
|
||||||
</ThemeProvider>
|
|
||||||
);
|
|
||||||
|
|
||||||
const ConnectedDocument = connect(
|
|
||||||
state => ({
|
|
||||||
theme: state[UI_MODULE_NAME].theme || "light"
|
|
||||||
}),
|
|
||||||
{}
|
|
||||||
)(Document);
|
|
||||||
|
|
||||||
export default (process.env.NODE_ENV === "development" ? hot(ConnectedDocument) : ConnectedDocument);
|
|
||||||
// export default (process.env.NODE_ENV === "development" ? hot(Document) : Document);
|
|
||||||
@@ -7,7 +7,6 @@ import { createStore } from "./redux/store";
|
|||||||
import { initSnake } from "./redux/snake";
|
import { initSnake } from "./redux/snake";
|
||||||
import { keyPress } from "./redux/game";
|
import { keyPress } from "./redux/game";
|
||||||
|
|
||||||
import Document from "./containers/Document.js";
|
|
||||||
import App from "./containers/App.js";
|
import App from "./containers/App.js";
|
||||||
|
|
||||||
const store = createStore();
|
const store = createStore();
|
||||||
@@ -16,9 +15,7 @@ window.store = store;
|
|||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<ConnectedRouter history={store.history}>
|
<ConnectedRouter history={store.history}>
|
||||||
<Document>
|
<App />
|
||||||
<App />
|
|
||||||
</Document>
|
|
||||||
</ConnectedRouter>
|
</ConnectedRouter>
|
||||||
</Provider>,
|
</Provider>,
|
||||||
document.getElementById("root")
|
document.getElementById("root")
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ module.middleware(INIT, (dispatch, { loopId }) => {
|
|||||||
module.middleware(
|
module.middleware(
|
||||||
KEY_PRESS,
|
KEY_PRESS,
|
||||||
(dispatch, { keyPressSubscribers = [], fps }, { key, altKey, ctrlKey, metaKey, shiftKey }) => {
|
(dispatch, { keyPressSubscribers = [], fps }, { key, altKey, ctrlKey, metaKey, shiftKey }) => {
|
||||||
|
console.log("key", key);
|
||||||
keyPressSubscribers.forEach(subscriber => dispatch({ type: subscriber, key, altKey, ctrlKey, metaKey, shiftKey }));
|
keyPressSubscribers.forEach(subscriber => dispatch({ type: subscriber, key, altKey, ctrlKey, metaKey, shiftKey }));
|
||||||
|
|
||||||
if (key === keys.PLUS || key === keys.EQUAL) {
|
if (key === keys.PLUS || key === keys.EQUAL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user