From 089cbe9c5f60fc7e95c418da4ae08919b0ea4835 Mon Sep 17 00:00:00 2001 From: Shea McKinney Date: Mon, 25 Nov 2024 11:57:41 -0800 Subject: [PATCH 1/9] NoJira: Linting upgrades. --- .eslintrc.json | 40 ++++- app/(storyblok)/[[...slug]]/not-found.tsx | 1 + app/(storyblok)/[[...slug]]/page.tsx | 4 +- app/(storyblok)/error.tsx | 4 +- app/(storyblok)/loading.tsx | 10 +- app/global-error.tsx | 4 +- app/loading.tsx | 10 +- app/not-found.tsx | 1 + app/sitemap.ts | 4 +- .../AnnotatedImage/ImageHotspot.styles.ts | 2 +- components/AnnotatedImage/ImageHotspot.tsx | 150 +++++++++--------- components/BasicCard/BasicCard.tsx | 1 - components/Bookshelf/BookAlt.tsx | 42 +++-- components/Bookshelf/BookshelfAlt.tsx | 1 - .../ChangemakerCard/ChangemakerCard.tsx | 4 +- components/CreateBloks.tsx | 2 +- components/CreateStories.tsx | 3 +- components/Cta/CtaLink.tsx | 2 - components/Embed/Embed.tsx | 4 +- components/EventBanner/EventBanner.tsx | 2 +- components/GlobalFooter/GlobalFooter.tsx | 1 - components/Heap.tsx | 5 +- components/Hero/StoryListHero.tsx | 2 +- components/InitiativeCard/InitiativeCard.tsx | 2 +- components/LocalFooter/LocalFooter.tsx | 2 +- components/Logo/LogoLockup.tsx | 2 +- components/Parallax/Parallax.tsx | 1 - .../Scrollytelling/ScrollyFullwidth.tsx | 4 +- .../Scrollytelling/ScrollytellingDemo.tsx | 28 ++-- components/SocialSharing/SocialSharing.tsx | 1 + components/Storyblok/ComponentNotFound.tsx | 8 +- components/Storyblok/SbChatBubble.tsx | 2 +- .../SbStoryFilterPage/SbStoryFilterPage.tsx | 12 +- .../SbStoryListNav/SbStoryListNav.tsx | 6 +- components/Storyblok/SbTypeform.tsx | 2 +- components/Storyblok/SbVerticalPoster.tsx | 2 +- components/Storyblok/Storyblok.types.ts | 3 +- components/VerticalPoster/VerticalPoster.tsx | 2 +- package.json | 2 +- utilities/data/getStoryData.ts | 3 +- utilities/data/getStoryblokRedirects.mjs | 2 +- utilities/sbStripSlugUrl.ts | 2 +- 42 files changed, 205 insertions(+), 180 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 16faa338..1d13e0d7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,5 +1,8 @@ { - "extends": "next/core-web-vitals", + "extends": [ + "next/core-web-vitals", + "next/typescript" + ], "rules": { "comma-dangle": ["error", { "objects": "always-multiline", @@ -19,30 +22,57 @@ "jsx-a11y/label-has-associated-control": [ 2, { "components": [ "Label" ], "required": { - "some": [ "nesting", "id" ] + "some": [ "nesting", "id" ] } }], + "jsx-quotes": ["error", "prefer-double"], "quotes": [2, "single", { "avoidEscape": true, "allowTemplateLiterals": true } ], "space-before-function-paren": 0, "react/jsx-props-no-spreading": 0, + "react/prop-types": 0, "react/jsx-handler-names": 0, + "react/jsx-filename-extension": [ + "error", + { + "extensions": [ + ".js", + ".ts", + ".jsx", + ".tsx" + ] + } + ], "react/jsx-fragments": 0, "react/jsx-one-expression-per-line": 0, "react/no-unused-prop-types": 0, "react/require-default-props": 0, - "react/function-component-definition": [2, { - "namedComponents": ["function-declaration", "arrow-function"] - }], + "react/jsx-no-useless-fragment": [2, { "allowExpressions": true }], // https://github.com/jsx-eslint/eslint-plugin-react/issues/2584 + "react/jsx-indent": [2, 2], "react/display-name": 0, + "class-methods-use-this": 0, "import/prefer-default-export": 0, "import/no-extraneous-dependencies": 0, "import/no-cycle": 0, "import/no-unresolved": 0, + "no-unused-vars": 0, + "no-multi-spaces": "error", + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "vars": "local", + "args": "none" + } + ], "import/export": 0, "func-names": 0, "semi": [1, "always"], // 1 is for warning "@next/next/no-img-element": 0 + }, + "settings": { + "tailwindcss": { + "callees": ["classnames", "clsx", "ctl", "cva", "tv", "cn", "dcnb", "cnb"] // Tailwind utility class detection for specific libraries + } } } diff --git a/app/(storyblok)/[[...slug]]/not-found.tsx b/app/(storyblok)/[[...slug]]/not-found.tsx index f3dfc36f..91bc6837 100644 --- a/app/(storyblok)/[[...slug]]/not-found.tsx +++ b/app/(storyblok)/[[...slug]]/not-found.tsx @@ -47,6 +47,7 @@ async function getStoryData(slug = 'momentum/page-not-found') { try { const story = await storyblokApi.get(`cdn/stories/${slug}`, sbParams); return story; + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { if (error && error.status && error.status === 404) { diff --git a/app/(storyblok)/[[...slug]]/page.tsx b/app/(storyblok)/[[...slug]]/page.tsx index 0e0649b1..c63239fb 100644 --- a/app/(storyblok)/[[...slug]]/page.tsx +++ b/app/(storyblok)/[[...slug]]/page.tsx @@ -59,7 +59,7 @@ export async function generateStaticParams() { const isProd = isProduction(); // Fetch new content from storyblok. const storyblokApi: StoryblokClient = getStoryblokApi(); - let sbParams: ISbStoriesParams = { + const sbParams: ISbStoriesParams = { version: isProd ? 'published' : 'draft', resolve_links: '0', resolve_assets: 0, @@ -79,7 +79,7 @@ export async function generateStaticParams() { // Filter out globals by filtering out the `global-components` folder. stories = stories.filter((link) => !link.slug.startsWith(getSlugPrefix() + '/global-components')); - let paths: PathsType[] = []; + const paths: PathsType[] = []; stories.forEach((story) => { diff --git a/app/(storyblok)/error.tsx b/app/(storyblok)/error.tsx index 11abe1e3..cf15943b 100644 --- a/app/(storyblok)/error.tsx +++ b/app/(storyblok)/error.tsx @@ -14,10 +14,10 @@ export default function Error({error, reset}: { }, [error]); return ( -
+
- +

Something went wrong.

Try refreshing your browser.

diff --git a/app/(storyblok)/loading.tsx b/app/(storyblok)/loading.tsx index c7713a80..639f0d2e 100644 --- a/app/(storyblok)/loading.tsx +++ b/app/(storyblok)/loading.tsx @@ -6,13 +6,13 @@ const Skeleton = DynamicLoad(() => import('react-loading-skeleton'), { ssr: fals const Loading = () => { return ( -
+
- - - - + + + +
diff --git a/app/global-error.tsx b/app/global-error.tsx index 486b8a15..7b074bf0 100644 --- a/app/global-error.tsx +++ b/app/global-error.tsx @@ -14,10 +14,10 @@ export default function Error({error, reset}: { }, [error]); return ( -
+
- +

Something went very wrong.

Try refreshing your browser.

diff --git a/app/loading.tsx b/app/loading.tsx index c7713a80..639f0d2e 100644 --- a/app/loading.tsx +++ b/app/loading.tsx @@ -6,13 +6,13 @@ const Skeleton = DynamicLoad(() => import('react-loading-skeleton'), { ssr: fals const Loading = () => { return ( -
+
- - - - + + + +
diff --git a/app/not-found.tsx b/app/not-found.tsx index f3dfc36f..91bc6837 100644 --- a/app/not-found.tsx +++ b/app/not-found.tsx @@ -47,6 +47,7 @@ async function getStoryData(slug = 'momentum/page-not-found') { try { const story = await storyblokApi.get(`cdn/stories/${slug}`, sbParams); return story; + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { if (error && error.status && error.status === 404) { diff --git a/app/sitemap.ts b/app/sitemap.ts index 2bfba559..5f3ac03e 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -18,7 +18,7 @@ export default async function sitemap(): Promise { const isProd = isProduction(); // Fetch new content from storyblok. - let sbParams: ISbStoriesParams = { + const sbParams: ISbStoriesParams = { version: isProd ? 'published' : 'draft', resolve_links: '0', resolve_assets: 0, @@ -47,7 +47,7 @@ export default async function sitemap(): Promise { const currentURL = process.env.URL || process.env.DEPLOY_PRIME_URL || 'https://momentum.stanford.edu'; const ret = indexStories.map((story) => { - const url = `${currentURL}${sbStripSlugURL(story.full_slug)}`; + const url = `${currentURL}${sbStripSlugURL(story.full_slug)}`; return { url: url.replace(/\/+$/, ''), lastModified: new Date(story.published_at), diff --git a/components/AnnotatedImage/ImageHotspot.styles.ts b/components/AnnotatedImage/ImageHotspot.styles.ts index 997d1435..73f3f21c 100644 --- a/components/AnnotatedImage/ImageHotspot.styles.ts +++ b/components/AnnotatedImage/ImageHotspot.styles.ts @@ -12,7 +12,7 @@ export const dialog = 'relative z-[150]'; export const srOnly = 'sr-only'; export const dialogOverlay = 'fixed inset-0 bg-gc-black/60 backdrop-blur-lg w-screen'; export const dialogWrapper = 'fixed inset-0 sm:py-30 w-screen overflow-y-auto overscroll-contain overflow-x-hidden'; -export const dialogPanel = (modalContentType: SbImageHotspotModalContentType) => cnb( +export const dialogPanel = (modalContentType: SbImageHotspotModalContentType) => cnb( 'relative sm:cc flex w-screen min-h-screen inset-0 break-words justify-center', (modalContentType === 'text-image' || modalContentType === 'text') ? 'items-start sm:items-center' : 'items-center text-white', ); diff --git a/components/AnnotatedImage/ImageHotspot.tsx b/components/AnnotatedImage/ImageHotspot.tsx index ac0fa8e4..94125edc 100644 --- a/components/AnnotatedImage/ImageHotspot.tsx +++ b/components/AnnotatedImage/ImageHotspot.tsx @@ -54,9 +54,9 @@ export const ImageHotspot = ({ : undefined; return ( - <> -
- - {!isClicked && ( -
- - setIsModalOpen(false)} className={styles.dialog}> - + + setIsModalOpen(false)} className={styles.dialog}> + -
- - + + -
- - {heading || ariaLabel} - {subhead && ( - {subhead} +
+ + {heading || ariaLabel} + {subhead && ( + {subhead} )} -
- - {/* Content for modals with text+image, fullwidth image or text only */} - {(modalContentType !== 'component' && modalContentType !== 'image-quote') && ( - - {(modalContentType === 'text-image' || modalContentType === 'text') && ( -
- {(heading || subhead) && ( -
- {heading && - {heading} + + {/* Content for modals with text+image, fullwidth image or text only */} + {(modalContentType !== 'component' && modalContentType !== 'image-quote') && ( + + {(modalContentType === 'text-image' || modalContentType === 'text') && ( +
+ {(heading || subhead) && ( +
+ {heading && + {heading} } - {subhead && - {subhead} + {subhead && + {subhead} } -
+
)} - {DescriptionRichText} -
+ {DescriptionRichText} +
)} - {(modalContentType === 'fullwidth-image' || modalContentType === 'text-image') && filename && ( -
- {modalContentType === 'fullwidth-image' && ( - - + {modalContentType === 'fullwidth-image' && ( + + - - - - {alt - + )} - {modalContentType === 'text-image' && ( - - {isVerticalCard ? ( - + {isVerticalCard ? ( + @@ -178,23 +178,23 @@ export const ImageHotspot = ({ /> )} - - - - - {alt - + )} - {hasRichText(caption) && ( -
- {Caption} -
+ {hasRichText(caption) && ( +
+ {Caption} +
)} -
+ )} -
- )} - {(modalContentType === 'component' || modalContentType === 'image-quote') && !!getNumBloks(content) && ( -
- -
+ )} + {(modalContentType === 'component' || modalContentType === 'image-quote') && !!getNumBloks(content) && ( +
+
- -
- -
-
- + )} +
+ +
+ + + + ); }; diff --git a/components/BasicCard/BasicCard.tsx b/components/BasicCard/BasicCard.tsx index 469dce4e..2dfdc3cb 100644 --- a/components/BasicCard/BasicCard.tsx +++ b/components/BasicCard/BasicCard.tsx @@ -6,7 +6,6 @@ import { Heading, type HeadingType, Text } from '@/components/Typography'; import { accentBgColors, type AccentColorType, - imageAspectRatios, type ImageAspectRatioType, } from '@/utilities/datasource'; import { getProcessedImage } from '@/utilities/getProcessedImage'; diff --git a/components/Bookshelf/BookAlt.tsx b/components/Bookshelf/BookAlt.tsx index c42809a6..2750cf69 100644 --- a/components/Bookshelf/BookAlt.tsx +++ b/components/Bookshelf/BookAlt.tsx @@ -1,9 +1,7 @@ -import { m, AnimatePresence, useWillChange } from 'framer-motion'; import { cnb } from 'cnbuilder'; import { FlexBox } from '../FlexBox'; -import { Heading, Text, Paragraph } from '../Typography'; +import { Text, Paragraph } from '../Typography'; import { HeroIcon } from '../HeroIcon'; -import { ImageOverlay } from '../ImageOverlay'; import { getProcessedImage } from '@/utilities/getProcessedImage'; type BookAltProps = { @@ -24,15 +22,12 @@ export const BookAlt = ({ expanded, setExpanded, buttonClassName, - contentClassName, imgSrc, }: BookAltProps) => { - const willChange = useWillChange(); const isOpen = i === expanded; return ( - <> - - + ); }; diff --git a/components/Bookshelf/BookshelfAlt.tsx b/components/Bookshelf/BookshelfAlt.tsx index 6b8d1604..adc3f680 100644 --- a/components/Bookshelf/BookshelfAlt.tsx +++ b/components/Bookshelf/BookshelfAlt.tsx @@ -2,7 +2,6 @@ import { useState } from 'react'; import { LayoutGroup } from 'framer-motion'; import { Container } from '../Container'; import { FlexBox } from '../FlexBox'; -import { Paragraph, Text } from '../Typography'; import { BookAlt } from './BookAlt'; export const BookshelfAlt = () => { diff --git a/components/ChangemakerCard/ChangemakerCard.tsx b/components/ChangemakerCard/ChangemakerCard.tsx index ad254f88..e54c31fa 100644 --- a/components/ChangemakerCard/ChangemakerCard.tsx +++ b/components/ChangemakerCard/ChangemakerCard.tsx @@ -189,7 +189,7 @@ export const ChangemakerCard = ({ > @@ -230,7 +230,7 @@ export const ChangemakerCard = ({ noBaseStyle focusable="false" strokeWidth={2} - icon='close' + icon="close" className={styles.modalIcon} /> diff --git a/components/CreateBloks.tsx b/components/CreateBloks.tsx index 8e256d12..556be192 100644 --- a/components/CreateBloks.tsx +++ b/components/CreateBloks.tsx @@ -3,7 +3,7 @@ import { StoryblokComponent, type SbBlokData } from '@storyblok/react/rsc'; type CreateBloksProps = { blokSection: SbBlokData[]; isListItems?: boolean; - [k: string]: any; + [k: string]: unknown; }; export const CreateBloks = ({ blokSection, isListItems, ...props }: CreateBloksProps) => { diff --git a/components/CreateStories.tsx b/components/CreateStories.tsx index f6167488..d740db7f 100644 --- a/components/CreateStories.tsx +++ b/components/CreateStories.tsx @@ -9,7 +9,7 @@ import { StoryblokComponent, type ISbStoryData } from '@storyblok/react/rsc'; type CreateStoriesProps = { stories: ISbStoryData[]; - [key: string]: any; + [key: string]: unknown; }; export const CreateStories = ({ stories, ...props }: CreateStoriesProps) => { @@ -20,6 +20,7 @@ export const CreateStories = ({ stories, ...props }: CreateStoriesProps) => { currentStory = story; return ; }); + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (error) { console.error('Could not create story', currentStory); } diff --git a/components/Cta/CtaLink.tsx b/components/Cta/CtaLink.tsx index 538c9bd6..2ace252c 100644 --- a/components/Cta/CtaLink.tsx +++ b/components/Cta/CtaLink.tsx @@ -26,8 +26,6 @@ export const CtaLink = React.forwardRef( } = props; const { - id, - fieldtype, linktype, cached_url: cachedUrl, url, diff --git a/components/Embed/Embed.tsx b/components/Embed/Embed.tsx index a3518e21..d12c0669 100644 --- a/components/Embed/Embed.tsx +++ b/components/Embed/Embed.tsx @@ -12,7 +12,7 @@ import React, { useRef, useEffect } from 'react'; import { WidthBox, type WidthType } from '../WidthBox'; import { type PaddingType } from '@/utilities/datasource'; -export interface EmbedProps extends React.HTMLAttributes { +export interface EmbedProps extends React.HTMLAttributes { id?: string; src?: string; content?: string; @@ -83,7 +83,7 @@ id, src, content, boundingWidth, spacingTop, spacingBottom, className, width, .. ); } - return (

You must provide either an src or content to the embed

); + return (

You must provide either an src or content to the embed

); }; export default Embed; diff --git a/components/EventBanner/EventBanner.tsx b/components/EventBanner/EventBanner.tsx index 25bfa1a9..13f3f539 100644 --- a/components/EventBanner/EventBanner.tsx +++ b/components/EventBanner/EventBanner.tsx @@ -180,7 +180,7 @@ export const EventBanner = ({ <> List of dates & locations - {dateLocation.map(({ date, location }) => { + {dateLocation.map(({ date, location }) => { const { dateTime, monthShort, day } = formatDate(date); return ( diff --git a/components/GlobalFooter/GlobalFooter.tsx b/components/GlobalFooter/GlobalFooter.tsx index 758e23f2..ea76b238 100644 --- a/components/GlobalFooter/GlobalFooter.tsx +++ b/components/GlobalFooter/GlobalFooter.tsx @@ -1,6 +1,5 @@ import { cnb } from 'cnbuilder'; import { StanfordLogo } from '../StanfordLogo'; -import { SrOnlyText } from '../Typography'; import { Container } from '../Container'; import { FlexBox } from '../FlexBox'; import * as styles from './GlobalFooter.styles'; diff --git a/components/Heap.tsx b/components/Heap.tsx index 68b90fb5..269b530a 100644 --- a/components/Heap.tsx +++ b/components/Heap.tsx @@ -1,3 +1,4 @@ +/* eslint-disable max-len */ 'use client'; import Script from 'next/script'; @@ -10,11 +11,11 @@ export const Heap = () => { if (process.env.CONTEXT && ['production'].includes(process.env.CONTEXT)) { return ( + ); } return null; diff --git a/components/Hero/StoryListHero.tsx b/components/Hero/StoryListHero.tsx index 93478a2c..444a5624 100644 --- a/components/Hero/StoryListHero.tsx +++ b/components/Hero/StoryListHero.tsx @@ -44,7 +44,7 @@ export const StoryListHero = ({ {subheading && ( diff --git a/components/LocalFooter/LocalFooter.tsx b/components/LocalFooter/LocalFooter.tsx index c4639ab5..b56501e8 100644 --- a/components/LocalFooter/LocalFooter.tsx +++ b/components/LocalFooter/LocalFooter.tsx @@ -102,5 +102,5 @@ export const LocalFooter = () => (
- + ); diff --git a/components/Logo/LogoLockup.tsx b/components/Logo/LogoLockup.tsx index babda304..8fbd550b 100644 --- a/components/Logo/LogoLockup.tsx +++ b/components/Logo/LogoLockup.tsx @@ -1,4 +1,4 @@ -import React, { AllHTMLAttributes } from 'react'; +import React from 'react'; import { cnb } from 'cnbuilder'; import { StanfordLogo } from '@/components/StanfordLogo'; import Link from 'next/link'; diff --git a/components/Parallax/Parallax.tsx b/components/Parallax/Parallax.tsx index fea59cdd..ba63efe3 100644 --- a/components/Parallax/Parallax.tsx +++ b/components/Parallax/Parallax.tsx @@ -6,7 +6,6 @@ import { useTransform, useSpring, useReducedMotion, - MotionValue, } from 'framer-motion'; type ParallaxProps = { diff --git a/components/Scrollytelling/ScrollyFullwidth.tsx b/components/Scrollytelling/ScrollyFullwidth.tsx index 506739d4..962fd243 100644 --- a/components/Scrollytelling/ScrollyFullwidth.tsx +++ b/components/Scrollytelling/ScrollyFullwidth.tsx @@ -99,7 +99,7 @@ export const ScrollyFullwidth = () => { Cras dui ipsum, aliquet eget nibh ut, sollicitudin pharetra risus. - Cras dui ipsum, aliquet eget nibh ut, sollicitudin pharetra risus. + Cras dui ipsum, aliquet eget nibh ut, sollicitudin pharetra risus.
@@ -115,7 +115,7 @@ export const ScrollyFullwidth = () => { overlay="black-70" /> -
+
Meowy Meowington diff --git a/components/Scrollytelling/ScrollytellingDemo.tsx b/components/Scrollytelling/ScrollytellingDemo.tsx index 654975ad..955fd86f 100644 --- a/components/Scrollytelling/ScrollytellingDemo.tsx +++ b/components/Scrollytelling/ScrollytellingDemo.tsx @@ -89,15 +89,15 @@ export const ScrollytellingDemo = () => {
- -
- - Chapter 2 - -
-
-
- {section4InView && ( + +
+ + Chapter 2 + +
+
+
+ {section4InView && ( <> { )} - {section5AtTop && ( + {section5AtTop && ( <> { )} - {section6AtTop && ( + {section6AtTop && ( // eslint-disable-next-line max-len //