diff --git a/src/app/components/byline/byline.js b/src/app/components/byline/byline.js
deleted file mode 100644
index 0eb820402..000000000
--- a/src/app/components/byline/byline.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import React from 'react';
-import './byline.scss';
-import {formatDateForBlog} from '~/helpers/data';
-
-export default function Byline({date, author, source=undefined}) {
- return (
-
- {
- source ?
- {source} :
- {author}
- }
- {formatDateForBlog(date)}
-
- );
-}
diff --git a/src/app/components/byline/byline.tsx b/src/app/components/byline/byline.tsx
new file mode 100644
index 000000000..c94380c92
--- /dev/null
+++ b/src/app/components/byline/byline.tsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import './byline.scss';
+import {formatDateForBlog} from '~/helpers/data';
+
+export default function Byline({
+ date,
+ author,
+ source
+}: {
+ date: string;
+ author: string;
+ source?: string;
+}) {
+ return (
+
+ {source ? (
+ {source}
+ ) : (
+ {author}
+ )}
+ {formatDateForBlog(date)}
+
+ );
+}
diff --git a/src/app/components/carousel/carousel.js b/src/app/components/carousel/carousel.tsx
similarity index 51%
rename from src/app/components/carousel/carousel.js
rename to src/app/components/carousel/carousel.tsx
index 30d463de6..49fa69f59 100644
--- a/src/app/components/carousel/carousel.js
+++ b/src/app/components/carousel/carousel.tsx
@@ -1,15 +1,28 @@
import React from 'react';
-import {Carousel as BaseCarousel, CarouselButton, CarouselItem, CarouselScroller} from 'react-aria-carousel';
+import {
+ Carousel as BaseCarousel,
+ CarouselButton,
+ CarouselItem,
+ CarouselScroller
+} from 'react-aria-carousel';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faChevronLeft} from '@fortawesome/free-solid-svg-icons/faChevronLeft';
import {faChevronRight} from '@fortawesome/free-solid-svg-icons/faChevronRight';
import './carousel.scss';
+// FrameChanger was part of the homegrown carousel, but react-aria-carousel has such items
+// built-in, so this is only used by pdf-unit (body-units) now. Might be able to use
+// CarouselButton (from react-aria-carousel) for that.
export function FrameChanger({
chevronDirection,
onClick,
- hoverText = '',
- disable = false
+ hoverText,
+ disable
+}: {
+ chevronDirection: 'left' | 'right';
+ onClick: React.MouseEventHandler;
+ hoverText?: string;
+ disable?: boolean;
}) {
const icon = {
left: faChevronLeft,
@@ -22,25 +35,23 @@ export function FrameChanger({
return (
);
}
-function HoverText({which, thing}) {
+function HoverText({which, thing}: {which: string; thing: string}) {
if (!thing) {
return null;
}
- return (
- {`${which} ${thing}`}
- );
+ return {`${which} ${thing}`};
}
export default function Carousel({
@@ -48,27 +59,29 @@ export default function Carousel({
children,
hoverTextThing,
ref
-}) {
- const slides = React.useMemo(
- () => {
- return React.Children.toArray(children).map((child, i) =>
- {child});
- },
- [children]
- );
+}: React.PropsWithChildren<{
+ atATime?: number;
+ hoverTextThing: string;
+ ref?: Parameters[0]['ref'];
+}>) {
+ const slides = React.useMemo(() => {
+ return React.Children.toArray(children).map((child, i) => (
+
+ {child}
+
+ ));
+ }, [children]);
return (
-
- {slides}
-
+ {slides}
-
+
-
+
);
diff --git a/src/app/pages/subjects/new/specific/components/carousel-section.tsx b/src/app/pages/subjects/new/specific/components/carousel-section.tsx
index 5a4da5665..ec6cdfe35 100644
--- a/src/app/pages/subjects/new/specific/components/carousel-section.tsx
+++ b/src/app/pages/subjects/new/specific/components/carousel-section.tsx
@@ -14,7 +14,7 @@ export default function CarouselSection({
minWidth: number;
}>) {
const {innerWidth} = useWindowContext();
- const ref = React.useRef<{base: HTMLDivElement}>();
+ const ref = React.useRef(null);
const [atATime, setAtATime] = React.useState(1);
React.useEffect(
diff --git a/src/app/pages/webinars/webinar-cards/webinar-grid.tsx b/src/app/pages/webinars/webinar-cards/webinar-grid.tsx
index 656611cb9..c2652eb4c 100644
--- a/src/app/pages/webinars/webinar-cards/webinar-grid.tsx
+++ b/src/app/pages/webinars/webinar-cards/webinar-grid.tsx
@@ -28,7 +28,7 @@ function PastWebinar({data}: {data: Webinar}) {
return (
{data.title}
-
+
{data.description}
{data.registrationLinkText}
diff --git a/test/src/components/carousel.test.tsx b/test/src/components/carousel.test.tsx
new file mode 100644
index 000000000..fdedddf28
--- /dev/null
+++ b/test/src/components/carousel.test.tsx
@@ -0,0 +1,70 @@
+import React from 'react';
+import {render, screen} from '@testing-library/preact';
+import userEvent from '@testing-library/user-event';
+import Carousel, { FrameChanger } from '~/components/carousel/carousel';
+
+const mockReactCarousel = jest.fn();
+const mockCarouselButton = jest.fn();
+
+// react-aria-carousel does not play nice with Jest
+jest.mock('react-aria-carousel', () => ({
+ Carousel: ({children}: React.PropsWithChildren