Skip to content

Commit

Permalink
Style account list a bit for dark theme, use components
Browse files Browse the repository at this point in the history
  • Loading branch information
cheshire137 committed Feb 1, 2020
1 parent 7d315ad commit 7846a4e
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 81 deletions.
4 changes: 0 additions & 4 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ code {
border-color: #464f59 !important;
}

.theme-dark .text-gray {
color: #d1d5da !important;
}

.theme-dark .text-gray-dark {
color: #e1e4e8 !important;
}
Expand Down
48 changes: 48 additions & 0 deletions src/components/AccountListItem/AccountAvatarStack.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import styled from 'styled-components';
import { AvatarStack } from "@primer/components";
import HeroImageTag from "../HeroImageTag";

interface Props {
threePlus: boolean;
}

const AccountAvatarStack = styled(AvatarStack).attrs({
alignRight: true
})<Props>`
height: 45px;
${props => props.threePlus ? "min-width: 69px;" : ""}
${HeroImageTag} {
width: 45px;
height: 45px;
background-color: transparent;
margin-left: -25px;
border-left: 0;
}
${HeroImageTag} + ${HeroImageTag} {
opacity: 0.5;
width: 40px;
height: 40px;
+ ${HeroImageTag} {
opacity: 0.3;
width: 35px;
height: 35px;
}
}
&:hover {
${HeroImageTag} {
margin-left: -5px;
}
${HeroImageTag} + ${HeroImageTag} {
opacity: 1;
width: 45px;
height: 45px;
}
}
`;

export default AccountAvatarStack;
47 changes: 0 additions & 47 deletions src/components/AccountListItem/AccountListItem.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,11 @@
max-height: 1.1em;
}

.account-meta .separator {
display: inline-block;
padding-left: 0.75em;
padding-right: 0.75em;
}

.btn-rank.btn-link:hover,
.btn-rank.btn-link:focus {
text-decoration: none;
}

.AvatarStack-body .avatar.account-hero-avatar {
width: 45px;
height: 45px;
background-color: transparent;
}

.AvatarStack.AvatarStack--three-plus.account-avatar-stack {
min-width: 69px;
}

.AvatarStack.account-avatar-stack {
height: 45px;
}

.AvatarStack.account-avatar-stack .avatar + .avatar {
opacity: 0.5;
width: 40px;
height: 40px;
}

.AvatarStack.account-avatar-stack .avatar + .avatar + .avatar {
opacity: 0.3;
width: 35px;
height: 35px;
}

.AvatarStack.account-avatar-stack .AvatarStack-body:hover .avatar + .avatar {
opacity: 1;
width: 45px;
height: 45px;
}

.account-avatar-stack.AvatarStack--right .avatar {
margin-left: -25px;
border-left: 0;
}

.account-avatar-stack.AvatarStack--right .AvatarStack-body:hover .avatar {
margin-left: -5px;
}

.theme-dark .Box .AvatarStack-body .avatar.account-hero-avatar {
background-color: #2f363d;
}
15 changes: 15 additions & 0 deletions src/components/AccountListItem/AccountMeta.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import styled from 'styled-components';
import { Flex } from "@primer/components";

interface Props {
appTheme: string;
}

const AccountMeta = styled(Flex).attrs({
alignItems: "center"
})<Props>`
font-size: 16px;
color: ${props => props.appTheme === "dark" ? "#d1d5da" : "#586069"} !important;
`;

export default AccountMeta;
9 changes: 9 additions & 0 deletions src/components/AccountListItem/Separator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import styled from 'styled-components';

const Separator = styled("span")`
display: inline-block;
padding-left: 0.75em;
padding-right: 0.75em;
`;

export default Separator;
45 changes: 20 additions & 25 deletions src/components/AccountListItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import MatchRankImage from "../MatchRankImage";
import HeroImage from "../HeroImage";
import "./AccountListItem.css";
import Account from "../../models/Account";
import { Flex, Tooltip } from "@primer/components";
import { Hero } from "../../models/Hero";
import { showSaveDialog } from "../../utils/electronUtils";
import LinkButton from "../LinkButton";
import BattletagButton from "./BattletagButton";
import AccountListItemStyle from "./AccountListItemStyle";
import ButtonShownOnHover from "./ButtonShownOnHover";
import RankButton from "./RankButton";
import AccountMeta from "./AccountMeta";
import Separator from "./Separator";
import AccountAvatarStack from "./AccountAvatarStack";

interface Props {
account: Account;
Expand Down Expand Up @@ -131,9 +135,9 @@ const AccountListItem = ({

return (
<AccountListItemStyle>
<div className="d-flex flex-justify-between flex-items-center">
<Flex justifyContent="space-between" alignItems="center">
<div className="width-full mb-2 mt-1">
<div className="d-flex flex-items-center flex-justify-between">
<Flex justifyContent="space-between" alignItems="center">
{showEditForm ? (
<>
<AccountForm
Expand Down Expand Up @@ -163,37 +167,37 @@ const AccountListItem = ({
onDelete={() => onAccountUpdate()}
battletag={battletag}
/>
</div>
<div className="text-gray f4 account-meta d-flex flex-items-center">
</Flex>
<AccountMeta appTheme={theme}>
{haveLatestResult && !haveLatestRank && latestMatch && (
<span>Last match: {latestMatch.result}</span>
)}
{latestMatch && latestMatch.playedAt ? (
<>
{haveLatestResult && !haveLatestRank ? (
<span className="separator" />
<Separator />
) : null}
Last played {latestMatch.playedAt.toLocaleDateString()}
</>
) : latestMatch && latestMatch.createdAt ? (
<>
{haveLatestResult && !haveLatestRank ? (
<span className="separator" />
<Separator />
) : null}
Last logged {latestMatch.createdAt.toLocaleDateString()}
</>
) : null}
{totalMatches > 0 ? (
<>
<span className="separator" />
<Separator />
<span>
{totalMatches} match{totalMatches === 1 ? null : "es"}
</span>
</>
) : (
<span>No matches in season {season}</span>
)}
</div>
</AccountMeta>
<ButtonShownOnHover
appTheme={theme}
onClick={() => setShowEditForm(!showEditForm)}
Expand All @@ -220,7 +224,7 @@ const AccountListItem = ({
</>
) : null}
</div>
<div className="d-flex flex-items-center">
<Flex alignItems="center">
{haveLatestRank && latestMatch && (
<RankButton
appTheme={theme}
Expand All @@ -239,31 +243,22 @@ const AccountListItem = ({
)}
<div className="ml-3 text-right">
{topHeroes && topHeroes.length > 0 && (
<div
className={`AvatarStack account-avatar-stack AvatarStack--right ${
topHeroes.length >= 3
? "AvatarStack--three-plus"
: "AvatarStack--two"
}`}
>
<div
className="AvatarStack-body tooltipped tooltipped-n"
aria-label={topHeroes.join(", ")}
>
<Tooltip direction="n" aria-label={topHeroes.join(", ")}>
<AccountAvatarStack threePlus={topHeroes.length >= 3}>
{topHeroes.map(hero => (
<HeroImage
key={hero}
hero={hero}
className="avatar account-hero-avatar"
size={40}
theme={theme}
/>
))}
</div>
</div>
</AccountAvatarStack>
</Tooltip>
)}
</div>
</div>
</div>
</Flex>
</Flex>
</AccountListItemStyle>
);
};
Expand Down
5 changes: 4 additions & 1 deletion src/components/HeroCheckbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface Props {
isAvailable: boolean;
hero: Hero;
isChecked: boolean;
theme: string;
unavailableReason?: string;
onToggle: (hero: Hero, isSelected: boolean) => void;
}
Expand All @@ -17,7 +18,8 @@ const HeroCheckbox = ({
hero,
onToggle,
unavailableReason,
isChecked
isChecked,
theme
}: Props) => {
const containerClass = () => {
let classes = ["form-checkbox", "mb-0", "mt-1"];
Expand Down Expand Up @@ -59,6 +61,7 @@ const HeroCheckbox = ({
/>
<HeroImage
hero={hero}
theme={theme}
className="d-inline-block rounded-2 flex-shrink-0 mx-2"
/>
<div className="no-wrap">
Expand Down
5 changes: 4 additions & 1 deletion src/components/HeroCheckboxList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Hero } from "../models/Hero";

interface Props {
heroes: Hero[];
theme: string;
isChecked: (hero: Hero) => boolean;
onToggle: (hero: Hero, isSelected: boolean) => void;
getUnavailableReason: (hero: Hero) => string | undefined;
Expand All @@ -13,14 +14,16 @@ const HeroCheckboxList = ({
heroes,
getUnavailableReason,
isChecked,
onToggle
onToggle,
theme
}: Props) => (
<>
{heroes.map(hero => {
const unavailableReason = getUnavailableReason(hero);
return (
<HeroCheckbox
key={hero}
theme={theme}
isAvailable={typeof unavailableReason !== "string"}
unavailableReason={unavailableReason}
isChecked={isChecked(hero)}
Expand Down
7 changes: 5 additions & 2 deletions src/components/HeroImage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import HeroUtil from "../models/HeroUtil";
import HeroImageTag from "./HeroImageTag";

const knownHeroes = [
"ana",
Expand Down Expand Up @@ -39,10 +40,11 @@ interface Props {
hero: string;
className?: string;
size?: number;
theme: string;
}

const HeroImage = (props: Props) => {
const { hero, className, size } = props;
const { hero, className, size, theme } = props;
const slug = HeroUtil.slugify(hero);
if (knownHeroes.indexOf(slug) < 0) {
return <span>{hero}</span>;
Expand All @@ -51,7 +53,8 @@ const HeroImage = (props: Props) => {
const src = require(`../images/heroes/${slug}.png`);

return (
<img
<HeroImageTag
appTheme={theme}
src={src}
alt={hero}
className={className}
Expand Down
11 changes: 11 additions & 0 deletions src/components/HeroImageTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styled from 'styled-components';

interface Props {
appTheme: string;
}

const HeroImageTag = styled("img")<Props>`
background-color: ${props => props.appTheme === "dark" ? "#2f363d" : "inherit"};
`;

export default HeroImageTag;
Loading

0 comments on commit 7846a4e

Please sign in to comment.