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`
|
||||
from { transform: scale(.7) }
|
||||
@@ -20,7 +20,12 @@ const Apple = styled.div.attrs(({ theme, zoom }) => ({
|
||||
&:after {
|
||||
content: "${props => (!props.died ? "🍎" : "🐛")}";
|
||||
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;
|
||||
display: inline-block;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
outline: ${({ disabled }) => (!disabled ? "1px solid silver" : "none")};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledButton = styled.button`
|
||||
@@ -49,13 +54,16 @@ const StyledNavLink = styled(NavLink)`
|
||||
${SharedStyle}
|
||||
`;
|
||||
|
||||
export const Button = (props, refs) => {
|
||||
export const Button = props => {
|
||||
const [hover, setHover] = React.useState(false);
|
||||
const updatedProps = { ...props };
|
||||
const disabled = props.disabled || props.toggle;
|
||||
let tooltip = null;
|
||||
|
||||
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) {
|
||||
@@ -72,13 +80,19 @@ export const Button = (props, refs) => {
|
||||
|
||||
if (props.icon) {
|
||||
return (
|
||||
<ButtonWrapper onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}>
|
||||
<ButtonWrapper
|
||||
onMouseEnter={() => setHover(true)}
|
||||
onMouseLeave={() => setHover(false)}
|
||||
onKeyUp={updatedProps.onKeyUp}
|
||||
onClick={updatedProps.onClick}
|
||||
disabled={disabled}>
|
||||
<i
|
||||
disabled={disabled}
|
||||
onClick={updatedProps.onClick}
|
||||
className={`fas fa-${props.icon} ${props.className}`}
|
||||
style={{ display: "inline-block", fontSize: `${props.size || 1}rem` }}
|
||||
/>
|
||||
{tooltip}
|
||||
{!disabled && tooltip}
|
||||
</ButtonWrapper>
|
||||
);
|
||||
}
|
||||
@@ -98,6 +112,7 @@ export const IconButton = styled(Button)`
|
||||
|
||||
&:before {
|
||||
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")}" />
|
||||
</svg>');
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 0.625rem center;
|
||||
background-position: right 0 center;
|
||||
background-size: 1rem 1rem;
|
||||
outline-offset: 3px;
|
||||
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
outline: 1px solid silver;
|
||||
}
|
||||
|
||||
@@ -25,15 +25,20 @@ const MenuButton = styled(NavLink)`
|
||||
background: ${props => props.theme.header.menuButton.active.background};
|
||||
color: ${props => props.theme.header.menuButton.active.color};
|
||||
}
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
outline: 1px solid silver;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeaderMenu = () => (
|
||||
<MenuPanel>
|
||||
<MenuItem>
|
||||
<MenuButton to="/snake">Snake</MenuButton>
|
||||
<MenuButton to="/">Snake</MenuButton>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<MenuButton to="/" exact>
|
||||
<MenuButton to="/about" exact>
|
||||
About
|
||||
</MenuButton>
|
||||
</MenuItem>
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
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 { 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 */
|
||||
import Header from "./Header";
|
||||
import Footer from "./Footer";
|
||||
@@ -10,20 +16,26 @@ import Page from "../components/Page";
|
||||
import Home from "./Home";
|
||||
import Snake from "./Snake";
|
||||
|
||||
const App = ({ title, onNewTitle, getKeyboards, keyboards }) => (
|
||||
<React.Fragment>
|
||||
<Header />
|
||||
<Page>
|
||||
<Switch>
|
||||
<Route exact path="/" component={Home} />
|
||||
<Route path="/snake" exact component={Snake} />
|
||||
</Switch>
|
||||
</Page>
|
||||
<Footer />
|
||||
</React.Fragment>
|
||||
const App = ({ theme }) => (
|
||||
<ThemeProvider theme={themes[theme]}>
|
||||
<React.Fragment>
|
||||
<GlobalStyle />
|
||||
<Header />
|
||||
<Page>
|
||||
<Switch>
|
||||
<Route exact path="/" component={Snake} />
|
||||
<Route path="/snake" exact component={Snake} />
|
||||
<Route path="/about" exact component={Home} />
|
||||
</Switch>
|
||||
</Page>
|
||||
<Footer />
|
||||
</React.Fragment>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
const mapState = () => ({});
|
||||
const mapState = state => ({
|
||||
theme: state[UI_MODULE_NAME].theme || "light"
|
||||
});
|
||||
|
||||
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 { keyPress } from "./redux/game";
|
||||
|
||||
import Document from "./containers/Document.js";
|
||||
import App from "./containers/App.js";
|
||||
|
||||
const store = createStore();
|
||||
@@ -16,9 +15,7 @@ window.store = store;
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<ConnectedRouter history={store.history}>
|
||||
<Document>
|
||||
<App />
|
||||
</Document>
|
||||
<App />
|
||||
</ConnectedRouter>
|
||||
</Provider>,
|
||||
document.getElementById("root")
|
||||
|
||||
@@ -101,6 +101,7 @@ module.middleware(INIT, (dispatch, { loopId }) => {
|
||||
module.middleware(
|
||||
KEY_PRESS,
|
||||
(dispatch, { keyPressSubscribers = [], fps }, { key, altKey, ctrlKey, metaKey, shiftKey }) => {
|
||||
console.log("key", key);
|
||||
keyPressSubscribers.forEach(subscriber => dispatch({ type: subscriber, key, altKey, ctrlKey, metaKey, shiftKey }));
|
||||
|
||||
if (key === keys.PLUS || key === keys.EQUAL) {
|
||||
|
||||
Reference in New Issue
Block a user