feat: filter tooltips

This commit is contained in:
TrèsAbhi committed 2024-08-25 18:45:01 -05:00
1 parent da6691928e
commit 2e97ccd40d
2 files changed
+248 -201

No files matched your search

@@ -1,7 +1,7 @@
'use client'; 'use client';
import { ReloadIcon } from '@radix-ui/react-icons'; import { ReloadIcon } from '@radix-ui/react-icons';
import { Box, Flex, IconButton, Text } from '@radix-ui/themes'; import { Box, Flex, IconButton, Text, Tooltip } from '@radix-ui/themes';
import { times } from 'lodash'; import { times } from 'lodash';
import { use } from 'react'; import { use } from 'react';
import { classIcons } from '../../../../components/ClassIcon'; import { classIcons } from '../../../../components/ClassIcon';
@@ -14,6 +14,7 @@ import { asset } from '../../../../core/blitzkit/asset';
import { gameDefinitions } from '../../../../core/blitzkit/gameDefinitions'; import { gameDefinitions } from '../../../../core/blitzkit/gameDefinitions';
import { Tier } from '../../../../core/blitzkit/tankDefinitions'; import { Tier } from '../../../../core/blitzkit/tankDefinitions';
import { TIER_ROMAN_NUMERALS } from '../../../../core/blitzkit/tankDefinitions/constants'; import { TIER_ROMAN_NUMERALS } from '../../../../core/blitzkit/tankDefinitions/constants';
import strings from '../../../../lang/en-US.json';
import * as TankFilters from '../../../../stores/tankFilters'; import * as TankFilters from '../../../../stores/tankFilters';
interface FilterControlProps { interface FilterControlProps {
@@ -39,24 +40,26 @@ export function FilterControl({ compact }: FilterControlProps) {
const selected = filters.tiers?.includes(tier); const selected = filters.tiers?.includes(tier);
return ( return (
<IconButton <Tooltip key={tier} content={`Tier ${tier}`}>
key={tier} <IconButton
variant={selected ? 'solid' : 'soft'} key={tier}
radius="none" variant={selected ? 'solid' : 'soft'}
color={selected ? undefined : 'gray'} radius="none"
highContrast color={selected ? undefined : 'gray'}
onClick={() => highContrast
mutateTankFilters((draft) => { onClick={() =>
if (draft.tiers?.includes(tier)) { mutateTankFilters((draft) => {
draft.tiers = draft.tiers?.filter((t) => t !== tier); if (draft.tiers?.includes(tier)) {
} else { draft.tiers = draft.tiers?.filter((t) => t !== tier);
draft.tiers = [...(draft.tiers ?? []), tier]; } else {
} draft.tiers = [...(draft.tiers ?? []), tier];
}) }
} })
> }
<Text size="2">{TIER_ROMAN_NUMERALS[tier]}</Text> >
</IconButton> <Text size="2">{TIER_ROMAN_NUMERALS[tier]}</Text>
</IconButton>
</Tooltip>
); );
})} })}
</Flex> </Flex>
@@ -66,24 +69,26 @@ export function FilterControl({ compact }: FilterControlProps) {
const selected = filters.tiers?.includes(tier); const selected = filters.tiers?.includes(tier);
return ( return (
<IconButton <Tooltip key={tier} content={`Tier ${tier}`}>
key={tier} <IconButton
variant={selected ? 'solid' : 'soft'} key={tier}
radius="none" variant={selected ? 'solid' : 'soft'}
color={selected ? undefined : 'gray'} radius="none"
highContrast color={selected ? undefined : 'gray'}
onClick={() => highContrast
mutateTankFilters((draft) => { onClick={() =>
if (draft.tiers?.includes(tier)) { mutateTankFilters((draft) => {
draft.tiers = draft.tiers?.filter((t) => t !== tier); if (draft.tiers?.includes(tier)) {
} else { draft.tiers = draft.tiers?.filter((t) => t !== tier);
draft.tiers = [...(draft.tiers ?? []), tier]; } else {
} draft.tiers = [...(draft.tiers ?? []), tier];
}) }
} })
> }
<Text size="2">{TIER_ROMAN_NUMERALS[tier]}</Text> >
</IconButton> <Text size="2">{TIER_ROMAN_NUMERALS[tier]}</Text>
</IconButton>
</Tooltip>
); );
})} })}
</Flex> </Flex>
@@ -101,29 +106,37 @@ export function FilterControl({ compact }: FilterControlProps) {
const selected = filters.nations?.includes(nation); const selected = filters.nations?.includes(nation);
return ( return (
<IconButton <Tooltip
key={nation} content={
variant={selected ? 'solid' : 'soft'} strings.common.nations[
color={selected ? undefined : 'gray'} nation as keyof typeof strings.common.nations
highContrast ]
radius="none"
onClick={() =>
mutateTankFilters((draft) => {
if (draft.nations?.includes(nation)) {
draft.nations = draft.nations?.filter(
(n) => n !== nation,
);
} else {
draft.nations = [...(draft.nations ?? []), nation];
}
})
} }
key={nation}
> >
<img <IconButton
style={{ width: '1em', height: '1em' }} variant={selected ? 'solid' : 'soft'}
src={asset(`flags/circle/${nation}.webp`)} color={selected ? undefined : 'gray'}
/> highContrast
</IconButton> radius="none"
onClick={() =>
mutateTankFilters((draft) => {
if (draft.nations?.includes(nation)) {
draft.nations = draft.nations?.filter(
(n) => n !== nation,
);
} else {
draft.nations = [...(draft.nations ?? []), nation];
}
})
}
>
<img
style={{ width: '1em', height: '1em' }}
src={asset(`flags/circle/${nation}.webp`)}
/>
</IconButton>
</Tooltip>
); );
})} })}
</Flex> </Flex>
@@ -134,30 +147,39 @@ export function FilterControl({ compact }: FilterControlProps) {
const selected = filters.nations?.includes(nation); const selected = filters.nations?.includes(nation);
return ( return (
<IconButton <Tooltip
key={nation} content={
style={{ flex: 1 }} strings.common.nations[
variant={selected ? 'solid' : 'soft'} nation as keyof typeof strings.common.nations
color={selected ? undefined : 'gray'} ]
highContrast
radius="none"
onClick={() =>
mutateTankFilters((draft) => {
if (draft.nations?.includes(nation)) {
draft.nations = draft.nations?.filter(
(n) => n !== nation,
);
} else {
draft.nations = [...(draft.nations ?? []), nation];
}
})
} }
key={nation}
> >
<img <IconButton
style={{ width: '1em', height: '1em' }} key={nation}
src={asset(`flags/circle/${nation}.webp`)} style={{ flex: 1 }}
/> variant={selected ? 'solid' : 'soft'}
</IconButton> color={selected ? undefined : 'gray'}
highContrast
radius="none"
onClick={() =>
mutateTankFilters((draft) => {
if (draft.nations?.includes(nation)) {
draft.nations = draft.nations?.filter(
(n) => n !== nation,
);
} else {
draft.nations = [...(draft.nations ?? []), nation];
}
})
}
>
<img
style={{ width: '1em', height: '1em' }}
src={asset(`flags/circle/${nation}.webp`)}
/>
</IconButton>
</Tooltip>
); );
})} })}
</Flex> </Flex>
@@ -173,26 +195,30 @@ export function FilterControl({ compact }: FilterControlProps) {
const selected = filters.classes?.includes(tankClass); const selected = filters.classes?.includes(tankClass);
return ( return (
<IconButton <Tooltip
content={strings.common.tank_class_medium[tankClass]}
key={tankClass} key={tankClass}
variant={selected ? 'solid' : 'soft'}
radius="none"
color={selected ? undefined : 'gray'}
highContrast
onClick={() =>
mutateTankFilters((draft) => {
if (draft.classes?.includes(tankClass)) {
draft.classes = draft.classes?.filter(
(c) => c !== tankClass,
);
} else {
draft.classes = [...(draft.classes ?? []), tankClass];
}
})
}
> >
<Icon style={{ width: '1em', height: '1em' }} /> <IconButton
</IconButton> variant={selected ? 'solid' : 'soft'}
radius="none"
color={selected ? undefined : 'gray'}
highContrast
onClick={() =>
mutateTankFilters((draft) => {
if (draft.classes?.includes(tankClass)) {
draft.classes = draft.classes?.filter(
(c) => c !== tankClass,
);
} else {
draft.classes = [...(draft.classes ?? []), tankClass];
}
})
}
>
<Icon style={{ width: '1em', height: '1em' }} />
</IconButton>
</Tooltip>
); );
})} })}
</Flex> </Flex>
@@ -202,67 +228,75 @@ export function FilterControl({ compact }: FilterControlProps) {
style={{ borderRadius: 'var(--radius-full)' }} style={{ borderRadius: 'var(--radius-full)' }}
direction={compact ? 'column' : { sm: 'row', initial: 'column' }} direction={compact ? 'column' : { sm: 'row', initial: 'column' }}
> >
<IconButton <Tooltip content="Researchable">
variant={filters.types?.includes('researchable') ? 'solid' : 'soft'} <IconButton
radius="none" variant={filters.types?.includes('researchable') ? 'solid' : 'soft'}
color={filters.types?.includes('researchable') ? undefined : 'gray'} radius="none"
highContrast color={filters.types?.includes('researchable') ? undefined : 'gray'}
onClick={() => highContrast
mutateTankFilters((draft) => { onClick={() =>
if (draft.types?.includes('researchable')) { mutateTankFilters((draft) => {
draft.types = draft.types?.filter((t) => t !== 'researchable'); if (draft.types?.includes('researchable')) {
} else { draft.types = draft.types?.filter(
draft.types = [...(draft.types ?? []), 'researchable']; (t) => t !== 'researchable',
} );
}) } else {
} draft.types = [...(draft.types ?? []), 'researchable'];
> }
<ResearchedIcon style={{ width: '1em', height: '1em' }} /> })
</IconButton> }
<IconButton
variant={filters.types?.includes('premium') ? 'solid' : 'soft'}
radius="none"
color={filters.types?.includes('premium') ? 'amber' : 'gray'}
highContrast
onClick={() =>
mutateTankFilters((draft) => {
if (draft.types?.includes('premium')) {
draft.types = draft.types?.filter((t) => t !== 'premium');
} else {
draft.types = [...(draft.types ?? []), 'premium'];
}
})
}
>
<Text
color={filters.types?.includes('premium') ? undefined : 'amber'}
style={{ display: 'flex', justifyContent: 'center' }}
> >
<ResearchedIcon style={{ width: '1em', height: '1em' }} /> <ResearchedIcon style={{ width: '1em', height: '1em' }} />
</Text> </IconButton>
</IconButton> </Tooltip>
<IconButton <Tooltip content="Premium">
variant={filters.types?.includes('collector') ? 'solid' : 'soft'} <IconButton
radius="none" variant={filters.types?.includes('premium') ? 'solid' : 'soft'}
color={filters.types?.includes('collector') ? 'blue' : 'gray'} radius="none"
highContrast color={filters.types?.includes('premium') ? 'amber' : 'gray'}
onClick={() => highContrast
mutateTankFilters((draft) => { onClick={() =>
if (draft.types?.includes('collector')) { mutateTankFilters((draft) => {
draft.types = draft.types?.filter((t) => t !== 'collector'); if (draft.types?.includes('premium')) {
} else { draft.types = draft.types?.filter((t) => t !== 'premium');
draft.types = [...(draft.types ?? []), 'collector']; } else {
} draft.types = [...(draft.types ?? []), 'premium'];
}) }
} })
> }
<Text
color={filters.types?.includes('collector') ? undefined : 'blue'}
style={{ display: 'flex', justifyContent: 'center' }}
> >
<ResearchedIcon style={{ width: '1em', height: '1em' }} /> <Text
</Text> color={filters.types?.includes('premium') ? undefined : 'amber'}
</IconButton> style={{ display: 'flex', justifyContent: 'center' }}
>
<ResearchedIcon style={{ width: '1em', height: '1em' }} />
</Text>
</IconButton>
</Tooltip>
<Tooltip content="Collector">
<IconButton
variant={filters.types?.includes('collector') ? 'solid' : 'soft'}
radius="none"
color={filters.types?.includes('collector') ? 'blue' : 'gray'}
highContrast
onClick={() =>
mutateTankFilters((draft) => {
if (draft.types?.includes('collector')) {
draft.types = draft.types?.filter((t) => t !== 'collector');
} else {
draft.types = [...(draft.types ?? []), 'collector'];
}
})
}
>
<Text
color={filters.types?.includes('collector') ? undefined : 'blue'}
style={{ display: 'flex', justifyContent: 'center' }}
>
<ResearchedIcon style={{ width: '1em', height: '1em' }} />
</Text>
</IconButton>
</Tooltip>
</Flex> </Flex>
<Flex <Flex
@@ -270,51 +304,57 @@ export function FilterControl({ compact }: FilterControlProps) {
style={{ borderRadius: 'var(--radius-full)' }} style={{ borderRadius: 'var(--radius-full)' }}
direction={compact ? 'column' : { sm: 'row', initial: 'column' }} direction={compact ? 'column' : { sm: 'row', initial: 'column' }}
> >
<IconButton <Tooltip content="Include test tank">
variant={filters.testing === 'include' ? 'solid' : 'soft'} <IconButton
radius="none" variant={filters.testing === 'include' ? 'solid' : 'soft'}
color={filters.testing === 'include' ? undefined : 'gray'} radius="none"
highContrast color={filters.testing === 'include' ? undefined : 'gray'}
onClick={() => highContrast
mutateTankFilters((draft) => { onClick={() =>
draft.testing = 'include'; mutateTankFilters((draft) => {
}) draft.testing = 'include';
} })
> }
<ExperimentIcon >
style={{ width: '1em', height: '1em', color: 'currentColor' }} <ExperimentIcon
/> style={{ width: '1em', height: '1em', color: 'currentColor' }}
</IconButton> />
<IconButton </IconButton>
variant={filters.testing === 'exclude' ? 'solid' : 'soft'} </Tooltip>
radius="none" <Tooltip content="Exclude test tank">
color={filters.testing === 'exclude' ? undefined : 'gray'} <IconButton
highContrast variant={filters.testing === 'exclude' ? 'solid' : 'soft'}
onClick={() => radius="none"
mutateTankFilters((draft) => { color={filters.testing === 'exclude' ? undefined : 'gray'}
draft.testing = 'exclude'; highContrast
}) onClick={() =>
} mutateTankFilters((draft) => {
> draft.testing = 'exclude';
<ScienceOffIcon })
style={{ width: '1em', height: '1em', color: 'currentColor' }} }
/> >
</IconButton> <ScienceOffIcon
<IconButton style={{ width: '1em', height: '1em', color: 'currentColor' }}
variant={filters.testing === 'only' ? 'solid' : 'soft'} />
radius="none" </IconButton>
color={filters.testing === 'only' ? undefined : 'gray'} </Tooltip>
highContrast <Tooltip content="Only test tank">
onClick={() => <IconButton
mutateTankFilters((draft) => { variant={filters.testing === 'only' ? 'solid' : 'soft'}
draft.testing = 'only'; radius="none"
}) color={filters.testing === 'only' ? undefined : 'gray'}
} highContrast
> onClick={() =>
<ScienceIcon mutateTankFilters((draft) => {
style={{ width: '1em', height: '1em', color: 'currentColor' }} draft.testing = 'only';
/> })
</IconButton> }
>
<ScienceIcon
style={{ width: '1em', height: '1em', color: 'currentColor' }}
/>
</IconButton>
</Tooltip>
</Flex> </Flex>
<Box> <Box>
+7
View File
@@ -58,6 +58,13 @@
"AT-SPG": "TD" "AT-SPG": "TD"
}, },
"tank_class_medium": {
"lightTank": "Light",
"mediumTank": "Medium",
"heavyTank": "Heavy",
"AT-SPG": "Tank destroyer"
},
"tree_type": { "tree_type": {
"researchable": "Tech tree", "researchable": "Tech tree",
"premium": "Premium", "premium": "Premium",