Added scaling to map and token select for small screens

This commit is contained in:
Mitchell McCaffrey 2020-09-06 13:20:05 +10:00
parent 9bdbb9cb4c
commit 24a3387b51
7 changed files with 183 additions and 75 deletions

View File

@ -7,6 +7,7 @@ function StyledModal({
onRequestClose, onRequestClose,
children, children,
allowClose, allowClose,
style,
...props ...props
}) { }) {
const { theme } = useThemeUI(); const { theme } = useThemeUI();
@ -26,6 +27,7 @@ function StyledModal({
marginRight: "-50%", marginRight: "-50%",
transform: "translate(-50%, -50%)", transform: "translate(-50%, -50%)",
maxHeight: "100%", maxHeight: "100%",
...style,
}, },
}} }}
{...props} {...props}
@ -44,6 +46,7 @@ function StyledModal({
StyledModal.defaultProps = { StyledModal.defaultProps = {
allowClose: true, allowClose: true,
style: {},
}; };
export default StyledModal; export default StyledModal;

View File

@ -16,6 +16,7 @@ function MapTile({
onMapRemove, onMapRemove,
onMapReset, onMapReset,
onDone, onDone,
large,
}) { }) {
const [isMapTileMenuOpen, setIsTileMenuOpen] = useState(false); const [isMapTileMenuOpen, setIsTileMenuOpen] = useState(false);
const isDefault = map.type === "default"; const isDefault = map.type === "default";
@ -46,7 +47,7 @@ function MapTile({
}} }}
bg="overlay" bg="overlay"
sx={{ borderRadius: "50%" }} sx={{ borderRadius: "50%" }}
m={1} m={2}
> >
<ExpandMoreDotIcon /> <ExpandMoreDotIcon />
</IconButton> </IconButton>
@ -65,7 +66,7 @@ function MapTile({
}} }}
bg="overlay" bg="overlay"
sx={{ borderRadius: "50%" }} sx={{ borderRadius: "50%" }}
m={1} m={2}
> >
<RemoveMapIcon /> <RemoveMapIcon />
</IconButton> </IconButton>
@ -85,7 +86,7 @@ function MapTile({
}} }}
bg="overlay" bg="overlay"
sx={{ borderRadius: "50%" }} sx={{ borderRadius: "50%" }}
m={1} m={2}
> >
<ResetMapIcon /> <ResetMapIcon />
</IconButton> </IconButton>
@ -96,18 +97,17 @@ function MapTile({
<Flex <Flex
key={map.id} key={map.id}
sx={{ sx={{
borderColor: "primary",
borderStyle: isSelected ? "solid" : "none",
borderWidth: "4px",
position: "relative", position: "relative",
width: "150px", width: large ? "49%" : "32%",
height: "150px", height: "0",
paddingTop: large ? "49%" : "32%",
borderRadius: "4px", borderRadius: "4px",
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "center",
cursor: "pointer", cursor: "pointer",
overflow: "hidden",
}} }}
m={2} my={1}
bg="muted" bg="muted"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
@ -123,7 +123,14 @@ function MapTile({
}} }}
> >
<UIImage <UIImage
sx={{ width: "100%", height: "100%", objectFit: "contain" }} sx={{
width: "100%",
height: "100%",
objectFit: "contain",
position: "absolute",
top: 0,
left: 0,
}}
src={mapSource} src={mapSource}
/> />
<Flex <Flex
@ -149,6 +156,20 @@ function MapTile({
{map.name} {map.name}
</Text> </Text>
</Flex> </Flex>
<Box
sx={{
width: "100%",
height: "100%",
position: "absolute",
top: 0,
left: 0,
borderColor: "primary",
borderStyle: isSelected ? "solid" : "none",
borderWidth: "4px",
pointerEvents: "none",
borderRadius: "4px",
}}
/>
{/* Show expand button only if both reset and remove is available */} {/* Show expand button only if both reset and remove is available */}
{isSelected && ( {isSelected && (
<Box sx={{ position: "absolute", top: 0, right: 0 }}> <Box sx={{ position: "absolute", top: 0, right: 0 }}>

View File

@ -1,6 +1,7 @@
import React, { useContext } from "react"; import React, { useContext } from "react";
import { Flex, Box, Text } from "theme-ui"; import { Flex, Box, Text } from "theme-ui";
import SimpleBar from "simplebar-react"; import SimpleBar from "simplebar-react";
import { useMedia } from "react-media";
import AddIcon from "../../icons/AddIcon"; import AddIcon from "../../icons/AddIcon";
@ -20,16 +21,18 @@ function MapTiles({
onDone, onDone,
}) { }) {
const { databaseStatus } = useContext(DatabaseContext); const { databaseStatus } = useContext(DatabaseContext);
const isSmallScreen = useMedia({ query: "(max-width: 500px)" });
return ( return (
<Box sx={{ position: "relative" }}> <Box sx={{ position: "relative" }}>
<SimpleBar style={{ maxHeight: "300px", width: "500px" }}> <SimpleBar style={{ maxHeight: "300px" }}>
<Flex <Flex
py={2} p={2}
bg="muted" bg="muted"
sx={{ sx={{
flexWrap: "wrap", flexWrap: "wrap",
width: "500px",
borderRadius: "4px", borderRadius: "4px",
justifyContent: "space-between",
}} }}
onClick={() => onMapSelect(null)} onClick={() => onMapSelect(null)}
> >
@ -45,19 +48,31 @@ function MapTiles({
":active": { ":active": {
color: "secondary", color: "secondary",
}, },
width: "150px", width: isSmallScreen ? "49%" : "32%",
height: "150px", height: "0",
paddingTop: isSmallScreen ? "49%" : "32%",
borderRadius: "4px", borderRadius: "4px",
justifyContent: "center", position: "relative",
alignItems: "center",
cursor: "pointer", cursor: "pointer",
}} }}
m={2} my={1}
bg="muted" bg="muted"
aria-label="Add Map" aria-label="Add Map"
title="Add Map" title="Add Map"
> >
<AddIcon large /> <Flex
sx={{
width: "100%",
height: "100%",
position: "absolute",
top: 0,
left: 0,
justifyContent: "center",
alignItems: "center",
}}
>
<AddIcon large />
</Flex>
</Flex> </Flex>
{maps.map((map) => { {maps.map((map) => {
const isSelected = selectedMap && map.id === selectedMap.id; const isSelected = selectedMap && map.id === selectedMap.id;
@ -73,6 +88,7 @@ function MapTiles({
onMapRemove={onMapRemove} onMapRemove={onMapRemove}
onMapReset={onMapReset} onMapReset={onMapReset}
onDone={onDone} onDone={onDone}
large={isSmallScreen}
/> />
); );
})} })}

View File

@ -9,7 +9,7 @@ import {
unknownSource, unknownSource,
} from "../../tokens"; } from "../../tokens";
function TokenTile({ token, isSelected, onTokenSelect, onTokenRemove }) { function TokenTile({ token, isSelected, onTokenSelect, onTokenRemove, large }) {
const tokenSource = useDataSource(token, defaultTokenSources, unknownSource); const tokenSource = useDataSource(token, defaultTokenSources, unknownSource);
const isDefault = token.type === "default"; const isDefault = token.type === "default";
@ -17,22 +17,28 @@ function TokenTile({ token, isSelected, onTokenSelect, onTokenRemove }) {
<Flex <Flex
onClick={() => onTokenSelect(token)} onClick={() => onTokenSelect(token)}
sx={{ sx={{
borderColor: "primary",
borderStyle: isSelected ? "solid" : "none",
borderWidth: "4px",
position: "relative", position: "relative",
width: "150px", width: large ? "49%" : "32%",
height: "150px", height: "0",
paddingTop: large ? "49%" : "32%",
borderRadius: "4px", borderRadius: "4px",
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "center",
cursor: "pointer", cursor: "pointer",
overflow: "hidden",
}} }}
m={2} my={1}
bg="muted" bg="muted"
> >
<Image <Image
sx={{ width: "100%", height: "100%", objectFit: "contain" }} sx={{
width: "100%",
height: "100%",
objectFit: "contain",
position: "absolute",
top: 0,
left: 0,
}}
src={tokenSource} src={tokenSource}
/> />
<Flex <Flex
@ -58,6 +64,20 @@ function TokenTile({ token, isSelected, onTokenSelect, onTokenRemove }) {
{token.name} {token.name}
</Text> </Text>
</Flex> </Flex>
<Box
sx={{
width: "100%",
height: "100%",
position: "absolute",
top: 0,
left: 0,
borderColor: "primary",
borderStyle: isSelected ? "solid" : "none",
borderWidth: "4px",
pointerEvents: "none",
borderRadius: "4px",
}}
/>
{isSelected && !isDefault && ( {isSelected && !isDefault && (
<Box sx={{ position: "absolute", top: 0, right: 0 }}> <Box sx={{ position: "absolute", top: 0, right: 0 }}>
<IconButton <IconButton
@ -68,7 +88,7 @@ function TokenTile({ token, isSelected, onTokenSelect, onTokenRemove }) {
}} }}
bg="overlay" bg="overlay"
sx={{ borderRadius: "50%" }} sx={{ borderRadius: "50%" }}
m={1} m={2}
> >
<RemoveTokenIcon /> <RemoveTokenIcon />
</IconButton> </IconButton>

View File

@ -1,10 +1,14 @@
import React from "react"; import React, { useContext } from "react";
import { Flex } from "theme-ui"; import { Flex, Box, Text } from "theme-ui";
import SimpleBar from "simplebar-react"; import SimpleBar from "simplebar-react";
import { useMedia } from "react-media";
import AddIcon from "../../icons/AddIcon"; import AddIcon from "../../icons/AddIcon";
import TokenTile from "./TokenTile"; import TokenTile from "./TokenTile";
import Link from "../Link";
import DatabaseContext from "../../contexts/DatabaseContext";
function TokenTiles({ function TokenTiles({
tokens, tokens,
@ -13,54 +17,90 @@ function TokenTiles({
selectedToken, selectedToken,
onTokenRemove, onTokenRemove,
}) { }) {
const { databaseStatus } = useContext(DatabaseContext);
const isSmallScreen = useMedia({ query: "(max-width: 500px)" });
return ( return (
<SimpleBar style={{ maxHeight: "300px", width: "500px" }}> <Box sx={{ position: "relative" }}>
<Flex <SimpleBar style={{ maxHeight: "300px" }}>
py={2}
bg="muted"
sx={{
flexWrap: "wrap",
width: "500px",
borderRadius: "4px",
}}
>
<Flex <Flex
onClick={onTokenAdd} p={2}
sx={{
":hover": {
color: "primary",
},
":focus": {
outline: "none",
},
":active": {
color: "secondary",
},
width: "150px",
height: "150px",
borderRadius: "4px",
justifyContent: "center",
alignItems: "center",
cursor: "pointer",
}}
m={2}
bg="muted" bg="muted"
aria-label="Add Token" sx={{
title="Add Token" flexWrap: "wrap",
borderRadius: "4px",
justifyContent: "space-between",
}}
> >
<AddIcon large /> <Box
onClick={onTokenAdd}
sx={{
":hover": {
color: "primary",
},
":focus": {
outline: "none",
},
":active": {
color: "secondary",
},
width: isSmallScreen ? "49%" : "32%",
height: "0",
paddingTop: isSmallScreen ? "49%" : "32%",
borderRadius: "4px",
position: "relative",
cursor: "pointer",
}}
my={1}
bg="muted"
aria-label="Add Token"
title="Add Token"
>
<Flex
sx={{
width: "100%",
height: "100%",
position: "absolute",
top: 0,
left: 0,
justifyContent: "center",
alignItems: "center",
}}
>
<AddIcon large />
</Flex>
</Box>
{tokens.map((token) => (
<TokenTile
key={token.id}
token={token}
isSelected={selectedToken && token.id === selectedToken.id}
onTokenSelect={onTokenSelect}
onTokenRemove={onTokenRemove}
large={isSmallScreen}
/>
))}
</Flex> </Flex>
{tokens.map((token) => ( </SimpleBar>
<TokenTile {databaseStatus === "disabled" && (
key={token.id} <Box
token={token} sx={{
isSelected={selectedToken && token.id === selectedToken.id} position: "absolute",
onTokenSelect={onTokenSelect} top: 0,
onTokenRemove={onTokenRemove} left: 0,
/> right: 0,
))} textAlign: "center",
</Flex> }}
</SimpleBar> bg="highlight"
p={1}
>
<Text as="p" variant="body2">
Token saving is unavailable. See <Link to="/faq#saving">FAQ</Link>{" "}
for more information.
</Text>
</Box>
)}
</Box>
); );
} }

View File

@ -272,7 +272,11 @@ function SelectMapModal({
}; };
return ( return (
<Modal isOpen={isOpen} onRequestClose={handleClose}> <Modal
isOpen={isOpen}
onRequestClose={handleClose}
style={{ maxWidth: "542px", width: "100%" }}
>
<ImageDrop onDrop={handleImagesUpload} dropText="Drop map to upload"> <ImageDrop onDrop={handleImagesUpload} dropText="Drop map to upload">
<input <input
onChange={(event) => handleImagesUpload(event.target.files)} onChange={(event) => handleImagesUpload(event.target.files)}

View File

@ -131,7 +131,11 @@ function SelectTokensModal({ isOpen, onRequestClose }) {
const selectedTokenWithChanges = { ...selectedToken, ...tokenSettingChanges }; const selectedTokenWithChanges = { ...selectedToken, ...tokenSettingChanges };
return ( return (
<Modal isOpen={isOpen} onRequestClose={handleRequestClose}> <Modal
isOpen={isOpen}
onRequestClose={handleRequestClose}
style={{ maxWidth: "542px", width: "100%" }}
>
<ImageDrop onDrop={handleImagesUpload} dropText="Drop token to upload"> <ImageDrop onDrop={handleImagesUpload} dropText="Drop token to upload">
<input <input
onChange={(event) => handleImagesUpload(event.target.files)} onChange={(event) => handleImagesUpload(event.target.files)}