diff --git a/packages/website/src/components/Button/index.module.css b/packages/website/src/components/Button/index.module.css index 07bd5704f..a976e1af5 100644 --- a/packages/website/src/components/Button/index.module.css +++ b/packages/website/src/components/Button/index.module.css @@ -10,14 +10,15 @@ border: none; font-family: var(--font-family-regular); - font-size: 0.75rem; + font-size: 0.75em; color: var(--gray-1); font-weight: var(--weight-medium); cursor: pointer; &[data-size="minor"] { - font-size: 0.75rem; + font-size: 0.75em; + padding: var(--space-2) var(--space-3); } &[data-array="true"] { diff --git a/packages/website/src/components/DropdownMenu/index.module.css b/packages/website/src/components/DropdownMenu/index.module.css index e69de29bb..9af9f452c 100644 --- a/packages/website/src/components/DropdownMenu/index.module.css +++ b/packages/website/src/components/DropdownMenu/index.module.css @@ -0,0 +1,2 @@ +.Trigger { +} diff --git a/packages/website/src/components/Flex/index.module.css b/packages/website/src/components/Flex/index.module.css index fb60a78f2..367d38bce 100644 --- a/packages/website/src/components/Flex/index.module.css +++ b/packages/website/src/components/Flex/index.module.css @@ -4,4 +4,61 @@ &[data-column="true"] { flex-direction: column; } + &[data-wrap="true"] { + flex-wrap: wrap; + } + + &[data-justify="start"] { + justify-content: flex-start; + } + &[data-justify="center"] { + justify-content: center; + } + &[data-justify="end"] { + justify-content: flex-end; + } + &[data-justify="between"] { + justify-content: space-between; + } + + &[data-align="start"] { + align-items: flex-start; + } + &[data-align="center"] { + align-items: center; + } + &[data-align="end"] { + align-items: flex-end; + } + + &[data-gap="0"] { + gap: var(--space-0); + } + &[data-gap="1"] { + gap: var(--space-1); + } + &[data-gap="2"] { + gap: var(--space-2); + } + &[data-gap="3"] { + gap: var(--space-3); + } + &[data-gap="4"] { + gap: var(--space-4); + } + &[data-gap="5"] { + gap: var(--space-5); + } + &[data-gap="6"] { + gap: var(--space-6); + } + &[data-gap="7"] { + gap: var(--space-7); + } + &[data-gap="8"] { + gap: var(--space-8); + } + &[data-gap="9"] { + gap: var(--space-9); + } } diff --git a/packages/website/src/components/Flex/index.tsx b/packages/website/src/components/Flex/index.tsx index dc2e6b180..d201933c7 100644 --- a/packages/website/src/components/Flex/index.tsx +++ b/packages/website/src/components/Flex/index.tsx @@ -4,17 +4,34 @@ import { classNames } from "../../ui/classNames"; import styles from "./index.module.css"; interface Props extends ComponentProps<"div"> { - gap?: Space; column?: boolean; + wrap?: boolean; + + align?: "start" | "center" | "end"; + justify?: "start" | "center" | "end" | "between"; + + gap?: Space; } -export function Flex({ children, column, className, gap, ...props }: Props) { +export function Flex({ + children, + column, + className, + gap, + justify, + align, + wrap, + ...props +}: Props) { return (
{children}
diff --git a/packages/website/src/components/LinkI18nWrapper/index.module.css b/packages/website/src/components/LinkI18nWrapper/index.module.css new file mode 100644 index 000000000..4c5ce3e91 --- /dev/null +++ b/packages/website/src/components/LinkI18nWrapper/index.module.css @@ -0,0 +1,3 @@ +.wrapper { + display: contents; +} diff --git a/packages/website/src/components/LinkI18nWrapper/index.tsx b/packages/website/src/components/LinkI18nWrapper/index.tsx new file mode 100644 index 000000000..ab32ad4de --- /dev/null +++ b/packages/website/src/components/LinkI18nWrapper/index.tsx @@ -0,0 +1,21 @@ +import locales from "@blitzkit/i18n/locales.json"; +import { LinkWrapper, type LinkWrapperProps } from "../LinkWrapper"; +import styles from "./index.module.css"; + +export interface LinkI18nWrapperProps extends LinkWrapperProps { + locale: string; +} + +export function LinkI18nWrapper({ + locale, + href, + ...props +}: LinkI18nWrapperProps) { + return ( + + ); +} diff --git a/packages/website/src/components/LinkWrapper/index.module.css b/packages/website/src/components/LinkWrapper/index.module.css new file mode 100644 index 000000000..4c5ce3e91 --- /dev/null +++ b/packages/website/src/components/LinkWrapper/index.module.css @@ -0,0 +1,3 @@ +.wrapper { + display: contents; +} diff --git a/packages/website/src/components/LinkWrapper/index.tsx b/packages/website/src/components/LinkWrapper/index.tsx new file mode 100644 index 000000000..2dc93fb1b --- /dev/null +++ b/packages/website/src/components/LinkWrapper/index.tsx @@ -0,0 +1,9 @@ +import type { ComponentProps } from "react"; +import { classNames } from "../../ui/classNames"; +import styles from "./index.module.css"; + +export interface LinkWrapperProps extends ComponentProps<"a"> {} + +export function LinkWrapper({ className, ...props }: LinkWrapperProps) { + return ; +} diff --git a/packages/website/src/components/TankCard/index.css b/packages/website/src/components/TankCard/index.css deleted file mode 100644 index 6cc92e4a2..000000000 --- a/packages/website/src/components/TankCard/index.css +++ /dev/null @@ -1,43 +0,0 @@ -.tank-search-card { - user-select: none; - display: flex; - flex-direction: column; - align-items: center; - gap: var(--space-2); - background-position: top left; - background-size: contain; - background-repeat: no-repeat; - overflow: hidden; -} - -.tank-search-card[data-provide-link='true'] { - cursor: pointer; -} - -.tank-search-card .link { - width: 100%; - display: flex; - flex-direction: column; - color: inherit; -} - -.tank-search-card .image { - width: 100%; - height: 8rem; - object-position: center right; - object-fit: contain; - filter: drop-shadow(-1px -1px 4px black); -} - -.tank-search-card .class-icon { - width: 1em; - height: 1em; - min-width: 1em; - min-height: 1em; -} - -.tank-search-card .name { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} diff --git a/packages/website/src/components/TankCard/index.module.css b/packages/website/src/components/TankCard/index.module.css new file mode 100644 index 000000000..61013fb85 --- /dev/null +++ b/packages/website/src/components/TankCard/index.module.css @@ -0,0 +1,15 @@ +.image-wrapper { + overflow: hidden; + + box-sizing: border-box; + + background-size: auto 100%; + background-repeat: no-repeat; + + height: 6rem; +} + +.icon { + width: 1em; + height: 1em; +} diff --git a/packages/website/src/components/TankCard/index.tsx b/packages/website/src/components/TankCard/index.tsx index 5472bff2d..cedf69ed4 100644 --- a/packages/website/src/components/TankCard/index.tsx +++ b/packages/website/src/components/TankCard/index.tsx @@ -1,15 +1,15 @@ import { alias, TankType, type TankDefinition } from "@blitzkit/core"; import { uniq } from "lodash-es"; -import { forwardRef, type ReactNode } from "react"; +import { type ReactNode } from "react"; import { api } from "../../core/blitzkit/api"; import { useLocale } from "../../hooks/useLocale"; import { TankopediaPersistent } from "../../stores/tankopediaPersistent"; import { classIcons } from "../ClassIcon"; import { Flex } from "../Flex"; -import { LinkI18n } from "../LinkI18n"; +import { LinkI18nWrapper } from "../LinkI18nWrapper"; import { MAX_RECENTLY_VIEWED } from "../TankSearch/constants"; import { Text, type TextProps } from "../Text"; -import "./index.css"; +import styles from "./index.module.css"; type TankCardProps = TextProps & { tank: TankDefinition; @@ -20,100 +20,80 @@ type TankCardProps = TextProps & { const tankDefinitions = await api.tankDefinitions(); -export const TankCard = forwardRef( - ( - { - tank, - discriminator, - onTankSelect: onSelect, - noLink, - style, - ...props - }: TankCardProps, - ref, - ) => { - const { unwrap, locale } = useLocale(); - const provideLink = !noLink && onSelect === undefined; +export const TankCard = ({ + tank, + discriminator, + onTankSelect: onSelect, + noLink, + style, + ...props +}: TankCardProps) => { + const { unwrap, locale } = useLocale(); - const Icon = classIcons[tank.class]; + const provideLink = !noLink && onSelect === undefined; + const name = unwrap(tank.name!); - return ( - { - onSelect?.(tank); - TankopediaPersistent.mutate((draft) => { - draft.recentlyViewed = uniq([tank.id, ...draft.recentlyViewed]) - .filter((id) => id in tankDefinitions.tanks) - .slice(0, MAX_RECENTLY_VIEWED); - }); - }} - className="tank-search-card" - data-provide-link={provideLink} + const color: TextProps["color"] = + tank.type === TankType.TANK_TYPE_COLLECTOR + ? "blue" + : tank.type === TankType.TANK_TYPE_PREMIUM + ? "amber" + : "gray"; + const lowContrast = tank.type !== TankType.TANK_TYPE_RESEARCHABLE; + + const Icon = classIcons[tank.class]; + + const content = ( + { + onSelect?.(tank); + TankopediaPersistent.mutate((draft) => { + draft.recentlyViewed = uniq([tank.id, ...draft.recentlyViewed]) + .filter((id) => id in tankDefinitions.tanks) + .slice(0, MAX_RECENTLY_VIEWED); + }); + }} + > + - { - if (!provideLink) event.preventDefault(); - }} - > - {unwrap(tank.name!)} + {name} + - - - - {unwrap(tank.name!)} - - - - {discriminator && ( - - {discriminator} - - )} - + + + + {name} + + + {discriminator && ( + + {discriminator} + + )} + + ); + + if (provideLink) { + return ( + + {content} + ); - }, -); + } + + return content; +}; diff --git a/packages/website/src/components/TankCardWrapper/index.module.css b/packages/website/src/components/TankCardWrapper/index.module.css index 0c3b69244..8c6541797 100644 --- a/packages/website/src/components/TankCardWrapper/index.module.css +++ b/packages/website/src/components/TankCardWrapper/index.module.css @@ -1,7 +1,8 @@ .wrapper { - /* py="4" - columns="repeat(auto-fill, minmax(7rem, 1fr))" - flow="dense" - gap="4" - gapY="8" */ + display: grid; + + gap: var(--space-4); + row-gap: var(--space-5); + + grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); } diff --git a/packages/website/src/components/TankSearch/components/Sort.tsx b/packages/website/src/components/TankSearch/components/Sort.tsx index d7ef3b2f1..814d6994a 100644 --- a/packages/website/src/components/TankSearch/components/Sort.tsx +++ b/packages/website/src/components/TankSearch/components/Sort.tsx @@ -5,6 +5,7 @@ import type { TankopediaSortDirection, } from "../../../stores/tankopediaPersistent"; import { TankSort } from "../../../stores/tankopediaSort"; +import { Button } from "../../Button"; import { DropdownMenu } from "../../DropdownMenu"; interface ItemProps { @@ -39,9 +40,11 @@ export function Sort() { return ( - - {strings.website.common.tank_search.sort_dropdown.label} - + + diff --git a/packages/website/src/components/TankSearch/index.module.css b/packages/website/src/components/TankSearch/index.module.css index ee5f702cb..e358f19b6 100644 --- a/packages/website/src/components/TankSearch/index.module.css +++ b/packages/website/src/components/TankSearch/index.module.css @@ -1,19 +1,11 @@ -.container { - display: flex; - flex-direction: column; +.tanks { + /* mt="2" gap="1" align="center" justify="center" direction="column" */ - gap: var(--space-2); - flex-grow: 1; - - .tanks { - /* mt="2" gap="1" align="center" justify="center" direction="column" */ - - .count { - /* gap="2" */ - } - } - - .test-warning { - /* justify="center" mt="4" */ + .count { + /* gap="2" */ } } + +.test-warning { + /* justify="center" mt="4" */ +} diff --git a/packages/website/src/components/TankSearch/index.tsx b/packages/website/src/components/TankSearch/index.tsx index 2facbcc93..ffab0be8c 100644 --- a/packages/website/src/components/TankSearch/index.tsx +++ b/packages/website/src/components/TankSearch/index.tsx @@ -9,7 +9,7 @@ import { import { literals } from "@blitzkit/i18n/src/literals"; import fuzzysort from "fuzzysort"; import { times, uniq } from "lodash-es"; -import { memo, useEffect, useMemo, useState, type ComponentProps } from "react"; +import { memo, useEffect, useMemo, useState } from "react"; import usePromise from "react-promise-suspense"; import { awaitableTankNames } from "../../core/awaitables/tankNames"; import { api } from "../../core/blitzkit/api"; @@ -24,6 +24,7 @@ import { TankSort } from "../../stores/tankopediaSort"; import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps"; import { Callout } from "../Callout"; import { ExperimentIcon } from "../ExperimentIcon"; +import { Flex } from "../Flex"; import { Link } from "../Link"; import { RecentlyViewedTanks } from "../RecentlyViewedTanks"; import { TankCardSkeleton } from "../TankCardSkeleton"; @@ -36,12 +37,11 @@ import { NoResults } from "./components/NoResults"; import { MAX_RECENTLY_VIEWED } from "./constants"; import styles from "./index.module.css"; -export type TankSearchProps = MaybeSkeletonComponentProps & - ComponentProps<"div"> & { - compact?: boolean; - onSelect?: (tank: TankDefinition) => void; - onSelectAll?: (tanks: TankDefinition[]) => void; - }; +export type TankSearchProps = MaybeSkeletonComponentProps & { + compact?: boolean; + onSelect?: (tank: TankDefinition) => void; + onSelectAll?: (tanks: TankDefinition[]) => void; +}; const PREVIEW_COUNT = 20; const DEFAULT_LOADED_CARDS = 64; @@ -55,7 +55,7 @@ const [gameDefinitions, modelDefinitions, tankDefinitions, tankNames] = ]); export const TankSearch = memo( - ({ compact, onSelect, onSelectAll, skeleton, ...props }) => { + ({ compact, onSelect, onSelectAll, skeleton }) => { const { strings, locale } = useLocale(); const wargaming = App.use((state) => state.logins.wargaming); const awaitedTanksDefinitionsArray = Object.values(tankDefinitions.tanks); @@ -430,7 +430,7 @@ export const TankSearch = memo( }, [tankFilters, tankopediaSort]); return ( -
+ ( )} )} -
+ ); }, ); diff --git a/packages/website/src/components/TankSearchBar/index.module.css b/packages/website/src/components/TankSearchBar/index.module.css index 63bb3aae5..e69de29bb 100644 --- a/packages/website/src/components/TankSearchBar/index.module.css +++ b/packages/website/src/components/TankSearchBar/index.module.css @@ -1,7 +0,0 @@ -.search-bar { - /* justify="center" */ - - .wrapper { - /* gap="2" flexGrow="1" */ - } -} diff --git a/packages/website/src/components/TankSearchBar/index.tsx b/packages/website/src/components/TankSearchBar/index.tsx index 253d4ca9b..a07eacdb9 100644 --- a/packages/website/src/components/TankSearchBar/index.tsx +++ b/packages/website/src/components/TankSearchBar/index.tsx @@ -5,10 +5,10 @@ import { type KeyboardEventHandler, useCallback, useRef } from "react"; import { useLocale } from "../../hooks/useLocale"; import { TankFilters } from "../../stores/tankFilters"; import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps"; +import { Flex } from "../Flex"; import { Spinner } from "../Spinner"; import { Sort } from "../TankSearch/components/Sort"; import { TextField } from "../TextField"; -import styles from "./index.module.css"; type SearchBarProps = MaybeSkeletonComponentProps & { topResult?: TankDefinition; @@ -65,22 +65,20 @@ export function TankSearchBar({ ); return ( -
-
- - {searching ? : } - + + + {searching ? : } + - -
-
+ + ); } diff --git a/packages/website/src/components/TankSearchFilters/index.tsx b/packages/website/src/components/TankSearchFilters/index.tsx index ef9fd08ed..bf4b9a7cc 100644 --- a/packages/website/src/components/TankSearchFilters/index.tsx +++ b/packages/website/src/components/TankSearchFilters/index.tsx @@ -21,6 +21,7 @@ import { api } from "../../core/blitzkit/api"; import { useLocale } from "../../hooks/useLocale"; import { App } from "../../stores/app"; import { TankFilters, type CaseType } from "../../stores/tankFilters"; +import { Button } from "../Button"; import { classIcons } from "../ClassIcon"; import { DropdownMenu } from "../DropdownMenu"; import { Flex } from "../Flex"; @@ -173,7 +174,7 @@ const TIERS = times(10, (i) => 10 - i); export function TankSearchFilters() { return ( -
+ @@ -189,7 +190,7 @@ export function TankSearchFilters() { -
+ ); } @@ -214,22 +215,24 @@ function TiersFilter() { return ( - - - {tiers.slice(0, MAX_ICONS).map((tier) => ( - - {TIER_ROMAN_NUMERALS[tier]} - - ))} + + @@ -287,21 +290,23 @@ function NationsFilter() { return ( - - - {nations.map((nation, index) => ( - 0 ? "-0.5em" : undefined, - width: "1.25em", - height: "1.25em", - }} - src={alias("api", `/flags/circle/${nation}.webp`)} - /> - ))} - + + @@ -369,25 +374,27 @@ function ClassFilter() { return ( - - - {classes.map((tankClass, index) => { - const Icon = classIcons[tankClass]; - return ( - 0 ? "-0.5em" : undefined, - width: "1.25em", - height: "1.25em", - }} - /> - ); - })} - + + @@ -447,25 +454,27 @@ function GunTypeFilter() { return ( - - - {gunTypes.map((gunType) => { - const Icon = GUN_TYPE_ICONS[gunType]; + + @@ -523,25 +532,27 @@ function TypeFilter() { return ( - - - {types.map((tankType) => { - return ( - - ); - })} - + + @@ -622,21 +633,34 @@ function IndividualShellFilter({ return ( - - {shells[index] === null && ( - - - - )} - {shells[index] !== null && ( - - )} + + + {shells[index] === null && ( + + + + )} + {shells[index] !== null && ( + + )} + @@ -825,30 +849,32 @@ function ConsumablesFilter() { return ( - - - {consumables.slice(0, MAX_ICONS).map((consumable, index) => ( - 0 ? "-0.5em" : undefined, - width: "1.25em", - height: "1.25em", - objectFit: "contain", - }} - src={alias("api", `/icons/consumables/${consumable}.webp`)} - /> - ))} + + @@ -917,30 +943,32 @@ function ProvisionsFilter() { return ( - - - {provisions.slice(0, MAX_ICONS).map((provision, index) => ( - 0 ? "-0.5em" : undefined, - width: "1.25em", - height: "1.25em", - objectFit: "contain", - }} - src={alias("api", `/icons/provisions/${provision}.webp`)} - /> - ))} + + @@ -1024,30 +1052,32 @@ function GameModeAbilitiesFilter() { return ( - - - {icons.slice(0, MAX_ICONS).map((icon, index) => ( - 0 ? "-0.5em" : undefined, - width: "1.25em", - height: "1.25em", - objectFit: "contain", - }} - src={icon} - /> - ))} + + diff --git a/packages/website/src/components/ToolCard.astro b/packages/website/src/components/ToolCard.astro index c4e89eb5c..0f48d3ee5 100644 --- a/packages/website/src/components/ToolCard.astro +++ b/packages/website/src/components/ToolCard.astro @@ -77,7 +77,7 @@ const toolStrings =
diff --git a/packages/website/src/pages/[...chunk_default]/[...locale]/tanks/index.astro b/packages/website/src/pages/[...chunk_default]/[...locale]/tanks/index.astro index 4f8b4e87b..c9aea8507 100644 --- a/packages/website/src/pages/[...chunk_default]/[...locale]/tanks/index.astro +++ b/packages/website/src/pages/[...chunk_default]/[...locale]/tanks/index.astro @@ -1,4 +1,5 @@ --- +import ColorScale from "../../../../components/ColorScale.astro"; import { Section } from "../../../../components/Section"; import ToolBanner from "../../../../components/ToolBanner.astro"; import { tools } from "../../../../constants/tools"; @@ -11,6 +12,9 @@ const { locale } = Astro.props; --- + + +
diff --git a/packages/website/src/ui/compose.tsx b/packages/website/src/ui/compose.tsx index 2b405a00d..cf3243a82 100644 --- a/packages/website/src/ui/compose.tsx +++ b/packages/website/src/ui/compose.tsx @@ -27,7 +27,7 @@ export function composeRadixComponents< mapped[key] = composeRadixComponent( components[key] as FC, - styles[key], + `radix__${styles[key]}`, ) as Components[Extract]; }