diff --git a/src/views/components/common/Tooltip.tsx b/src/views/components/common/Tooltip.tsx new file mode 100644 index 00000000..36e1cc6f --- /dev/null +++ b/src/views/components/common/Tooltip.tsx @@ -0,0 +1,44 @@ +import clsx from 'clsx'; +import type { PropsWithChildren, ReactNode } from 'react'; +import React from 'react'; + +interface TooltipProps { + className?: string; + contentClassName?: string; + content: ReactNode; + offsetX: number; + offsetY: number; + maxWidth?: number; +} + +/** + * Tooltip that displays content on hover + */ +export default function Tooltip({ + className, + contentClassName, + content, + offsetX, + offsetY, + maxWidth, + children, +}: PropsWithChildren): JSX.Element { + return ( + + {children} + + {content} + + + ); +} diff --git a/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx b/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx index 2548107c..0f6defd6 100644 --- a/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx +++ b/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx @@ -3,6 +3,7 @@ import type { Distribution, LetterGrade } from '@shared/types/Distribution'; import { extendedColors } from '@shared/types/ThemeColors'; import Link from '@views/components/common/Link'; import Text from '@views/components/common/Text/Text'; +import Tooltip from '@views/components/common/Tooltip'; import { NoDataError, queryAggregateDistribution, @@ -12,10 +13,12 @@ import Highcharts from 'highcharts'; import HighchartsReact from 'highcharts-react-official'; import type { ChangeEvent } from 'react'; import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { renderToStaticMarkup } from 'react-dom/server'; import Skeleton from 'react-loading-skeleton'; const UT_GRADE_DISTRIBUTION_URL = 'https://reports.utexas.edu/spotlight-data/ut-course-grade-distributions'; - +const TOOLTIP_CONTENT = + "The 'Other' grade category includes all non-standard letter grades, including: In Progress, Incomplete, Permanent Incomplete, Oblit, Q-Drop, Withdrawn, Credit, No Credit, Satisfactory, Unsatisfactory, and Registered on CR/F or CR/NC basis."; interface GradeDistributionProps { course: Course; } @@ -126,6 +129,25 @@ export default function GradeDistribution({ course }: GradeDistributionProps): J lineHeight: 'normal', fontStyle: 'normal', }, + useHTML: true, + formatter() { + // eslint-disable-next-line react/no-this-in-sfc + const val = `${this.value}`; + + return val === 'Other' + ? renderToStaticMarkup( + + Other + + ) + : val; + }, }, title: { text: 'Grades', @@ -135,6 +157,7 @@ export default function GradeDistribution({ course }: GradeDistributionProps): J fontWeight: '400', }, }, + categories: ['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'D-', 'F', 'Other'], tickInterval: 1, tickWidth: 1, diff --git a/src/views/components/settings/ContributorCardSkeleton.tsx b/src/views/components/settings/ContributorCardSkeleton.tsx index bdc70913..a1f79c80 100644 --- a/src/views/components/settings/ContributorCardSkeleton.tsx +++ b/src/views/components/settings/ContributorCardSkeleton.tsx @@ -4,10 +4,10 @@ import React from 'react'; * Lightweight skeleton placeholder for contributor cards while data loads */ export const ContributorCardSkeleton: React.FC = () => ( -
-
-
-
+
+
+
+
);