Skip to content

Commit

Permalink
create and implement ModsTableTooltip component
Browse files Browse the repository at this point in the history
-still doesn't work when the `ModsTable` is scrolled down
-haven't figured out how to make the `multiline` functionality of the `Tooltip` work yet
  • Loading branch information
otobot1 committed Apr 14, 2024
1 parent e4157d3 commit 7b4ce19
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 25 deletions.
105 changes: 80 additions & 25 deletions src/components/mods/modsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ import { DataTable, DataTableSortStatus } from "mantine-datatable";
import { Dispatch, SetStateAction, useEffect, useMemo, useRef, useState, createContext } from "react";
import { createPortal } from "react-dom";
import ExpandedMod from "~/components/mods/expandedMod";
import { createStyles } from "@mantine/core";
import { createStyles, Text, Tooltip } from "@mantine/core";
import { useDebouncedValue } from "@mantine/hooks";
import { Difficulty, Quality } from "~/components/mods/types";
import { type ModType, type Publisher as PrismaPublisher, type Mod } from "@prisma/client";
import { StringSearch } from "~/components/filterPopovers/stringSearch";
import { NumberSearch } from "~/components/filterPopovers/numberSearch";
import { ListSelect } from "~/components/filterPopovers/listSelect";
import { ModsTableTooltip } from "./modsTableTooltip";
import { truncateString } from "~/utils/truncateString";
import type { ModWithInfo, Tech } from "~/components/mods/types";
import { noRatingsFoundMessage } from "~/consts/noRatingsFoundMessage";
import { defaultToLocaleDateStringOptions } from "~/consts/defaultToLocaleDateStringOptions";
import { colorsForDifficultyIndex, greatestValidDifficultyIndex } from "~/styles/modsColors";
import { canonicalDifficultyNames, difficultyColors, type DifficultyColor } from "~/styles/difficultyColors";
import { expandedModColors } from "~/styles/expandedModColors";
Expand Down Expand Up @@ -144,12 +146,18 @@ const useStyles = createStyles(
modCell: {
// 4 ampersands to increase selectivity of class to ensure it overrides any other css
"&&&&": {
/* top | left and right | bottom */
padding: `${theme.spacing.sm} ${theme.spacing.xl} ${theme.spacing.sm}`,
/* top and bottom | left and right */
padding: `${theme.spacing.sm} ${theme.spacing.xl}`,
backgroundColor: expandedModColors.default.backgroundColor,
color: expandedModColors.default.textColor,
borderWidth: 0,
fontWeight: "bold",
".mantine-Tooltip-tooltip": { // TODO: figure out how to move this styling into the ModsTableTooltip component
backgroundColor: colors.primaryHover.backgroundColor,
color: colors.primaryHover.textColor,
borderColor: colors.primaryHover.textColor,
border: "2px solid",
},
},
},
expandedModCell: {
Expand Down Expand Up @@ -895,7 +903,19 @@ export const ModsTable = ({ qualities, difficulties, techs, modsWithInfo, isLoad
title: "Name",
sortable: true,
ellipsis: true,
render: (modWithInfo) => truncateString(modWithInfo.name, NAME_COLUMN_MAX_LETTERS),
render: (modWithInfo) => {
const modTypeString = (modWithInfo.type !== "Normal" && modWithInfo.type !== "LobbyOther") ?
modWithInfo.type : (
modWithInfo.type === "Normal" ? "Campaign" : "Other Lobby"
);

return (
<ModsTableTooltip
targetString={truncateString(modWithInfo.name, NAME_COLUMN_MAX_LETTERS)}
dropdownString={`${modWithInfo.name}: ${modTypeString} Mod`}
/>
);
},
filter: (
<StringSearch
value={nameQuery}
Expand All @@ -922,7 +942,15 @@ export const ModsTable = ({ qualities, difficulties, techs, modsWithInfo, isLoad
title: "Publisher",
sortable: true,
ellipsis: true,
render: (modWithInfo) => truncateString(modWithInfo.publisherName, PUBLISHER_COLUMN_MAX_LETTERS),
render: (modWithInfo) => {
const publicationDate = new Date(modWithInfo.timeCreatedGamebanana * 1000); // convert from seconds to milliseconds
return (
<ModsTableTooltip
targetString={truncateString(modWithInfo.publisherName, PUBLISHER_COLUMN_MAX_LETTERS)}
dropdownString={`${modWithInfo.publisherName}: ${publicationDate.toLocaleDateString(undefined, defaultToLocaleDateStringOptions)}`}
/>
);
},
filter: (
<StringSearch
value={publisherQuery}
Expand All @@ -942,7 +970,12 @@ export const ModsTable = ({ qualities, difficulties, techs, modsWithInfo, isLoad
title: "Quality",
sortable: true,
ellipsis: true,
render: (modWithInfo) => modWithInfo.Quality.name,
render: (modWithInfo) => (
<ModsTableTooltip
targetString={modWithInfo.Quality.name}
dropdownString={`${modWithInfo.Quality.name}: ${modWithInfo.Quality.count} ratings`}
/>
),
filter: (
<ListSelect
permittedStrings={qualityNames}
Expand All @@ -959,7 +992,20 @@ export const ModsTable = ({ qualities, difficulties, techs, modsWithInfo, isLoad
title: "Difficulty",
sortable: true,
ellipsis: true,
render: (modWithInfo) => modWithInfo.Difficulty.name,
render: (modWithInfo) => {
const difficultyNameFromMod = modWithInfo.Difficulty.name;

const splitDifficultyNamesArray = difficultyNameFromMod.split(": ");
const [parentDifficulty, childDifficulty] = splitDifficultyNamesArray;
if (parentDifficulty === undefined || childDifficulty === undefined) return "";

return (
<ModsTableTooltip
targetString={childDifficulty}
dropdownString={`${childDifficulty}: ${modWithInfo.Difficulty.count} ratings`}
/>
);
},
filter: (
<ListSelect
permittedStrings={childDifficultyNames}
Expand Down Expand Up @@ -1001,9 +1047,33 @@ export const ModsTable = ({ qualities, difficulties, techs, modsWithInfo, isLoad
sortable: false,
ellipsis: true,
render: (modWithInfo) => {
const techsString = modWithInfo.TechsAny.join(", ");

return techsString === "" ? undefined : truncateString(techsString, TECHS_COLUMN_MAX_LETTERS);
const techsAnyString = modWithInfo.TechsAny.join(", ");
const techsFCString = modWithInfo.TechsFC.join(", ");

return (
<ModsTableTooltip
multiline={true}
maxWidth={200}
targetString={
techsAnyString === "" ? (
techsFCString === "" ? "" : truncateString(`Full Clear: ${techsFCString}`, TECHS_COLUMN_MAX_LETTERS)
) : (
truncateString(techsAnyString, TECHS_COLUMN_MAX_LETTERS)
)
}
dropdownString={
techsAnyString === "" ? (
techsFCString === "" ?
"None" :
`Any%: None. Full Clear: ${techsFCString}.`
) : (
techsFCString === "" ?
`Any%: ${techsAnyString}.` :
`Any%: ${techsAnyString}. Full Clear: ${techsFCString}.`
)
}
/>
);
},
filter: (
<ListSelect
Expand All @@ -1023,21 +1093,6 @@ export const ModsTable = ({ qualities, difficulties, techs, modsWithInfo, isLoad
);
},
},
// {
// accessor: "type",
// title: "Type",
// sortable: true,
// filter: (
// <ListSelect
// permittedStrings={getNonEmptyArray(modTypes)}
// selectedStrings={selectedModTypes}
// setSelectedStrings={setSelectedModTypes}
// difficultyIndex={currentTabIndex}
// />
// ),
// filtering: isModTypeFiltered,
// titleClassName: isModTypeFiltered ? classes.filteredColumnTitle : classes.unfilteredColumnTitle
// },
]}
sortStatus={sortStatus}
onSortStatusChange={setSortStatus as Dispatch<SetStateAction<DataTableSortStatus>>} // un-narrow type to match types in DataTable
Expand Down
52 changes: 52 additions & 0 deletions src/components/mods/modsTableTooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Tooltip, Text } from "@mantine/core";
import { useDebouncedValue, useDisclosure } from "@mantine/hooks";




type ModsTableTooltipProps = {
targetString: string;
dropdownString: string;
multiline?: boolean;
maxWidth?: number;
};



/** `target` must be able to accept a `ref`. */
export const ModsTableTooltip = ({
targetString,
dropdownString,
multiline = false, //TODO!!!: figure out how to make multiline work
maxWidth,
}: ModsTableTooltipProps) => {
const [isOpened, { close, open }] = useDisclosure(false);

// Since there is a gap between the link and the tooltip,
// debouncing prevents the tooltip from closing when we move from the link to tooltip.
const [debouncedIsOpened] = useDebouncedValue(isOpened, 200);

return (
<Tooltip
offset={21}
opened={debouncedIsOpened}
label={
<Text // TODO!!!: figure out why onMouseEnter and onMouseLeave don't work
size="xs"
onMouseEnter={open}
onMouseLeave={close}
>
{dropdownString}
</Text>
}
>
<Text
size="sm"
onMouseEnter={open}
onMouseLeave={close}
>
{targetString}
</Text>
</Tooltip>
);
};
5 changes: 5 additions & 0 deletions src/consts/defaultToLocaleDateStringOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const defaultToLocaleDateStringOptions: Intl.DateTimeFormatOptions = {
year: "numeric",
month: "long",
day: "numeric",
};

0 comments on commit 7b4ce19

Please sign in to comment.