Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3 - enforce no-explicit-any #662

Merged
merged 2 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ module.exports = {
},
},
rules: {
"@typescript-eslint/no-explicit-any": "off", // TODO
"unused-imports/no-unused-imports": "error",
"import/no-named-as-default": "off",
"import/no-unresolved": "error",
Expand Down
2 changes: 1 addition & 1 deletion src/app/(main)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { loadQuery } from "studio/lib/store";

import styles from "./layout.module.css";

const hasValidData = (data: any) => data && Object.keys(data).length > 0;
const hasValidData = (data: unknown) => data && Object.keys(data).length > 0;

export default async function Layout({
children,
Expand Down
2 changes: 1 addition & 1 deletion src/app/api/fetchData/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const clientWithToken = client.withConfig({ token });

interface FetchRequestBody {
query: string;
params?: Record<string, any>;
params?: Record<string, unknown>;
}

export async function POST(req: Request) {
Expand Down
10 changes: 8 additions & 2 deletions src/blog/components/legal/Legal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Link from "next/link";
import { PortableTextBlock } from "sanity";

import { PortableTextBlock, RichText } from "src/components/richText/RichText";
import { RichText } from "src/components/richText/RichText";
import Text from "src/components/text/Text";
import { LegalDocument } from "studio/lib/interfaces/legalDocuments";

Expand All @@ -9,7 +10,12 @@ import styles from "./legal.module.css";
const extractHeadings = (blocks: PortableTextBlock[]) => {
return blocks
.filter((block) => block.style === "h2")
.map((block) => block.children?.map((child) => child.text).join(" ") || "");
.map(
(block) =>
(Array.isArray(block.children) &&
block.children?.map((child) => child.text).join(" ")) ||
"",
);
};

const Legal = ({ document }: { document: LegalDocument }) => {
Expand Down
16 changes: 13 additions & 3 deletions src/blog/components/postPreview/PostPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"use client";
import { PortableTextBlock } from "sanity";

import CustomLink from "src/components/link/CustomLink";
import { PortableTextBlock, RichText } from "src/components/richText/RichText";
import { RichText } from "src/components/richText/RichText";
import Text from "src/components/text/Text";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { LinkType } from "studio/lib/interfaces/navigation";
Expand Down Expand Up @@ -32,12 +34,20 @@ const PostPreview = ({
},
};

const truncateFirstBlock = (richText: PortableTextBlock[], limit: number) => {
const truncateFirstBlock = (
richText: PortableTextBlock[],
limit: number,
): PortableTextBlock[] => {
if (!richText || richText.length === 0) return richText;

const firstBlock = richText[0];
let charCount = 0;
const truncatedChildren = firstBlock?.children?.map((child) => {

if (!("children" in firstBlock) || !Array.isArray(firstBlock.children)) {
return [firstBlock];
}

const truncatedChildren = firstBlock.children?.map((child) => {
if (charCount >= limit) return { ...child, text: "" };
const remainingChars = limit - charCount;
const truncatedText = child.text.slice(0, remainingChars);
Expand Down
3 changes: 2 additions & 1 deletion src/blog/components/postPreview/mockData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PortableTextBlock } from "src/components/richText/RichText";
import { PortableTextBlock } from "sanity";

import placeholder from "src/stories/assets/image-placeholder.png";

// Common rich text for lead and main content
Expand Down
2 changes: 1 addition & 1 deletion src/components/forms/checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PortableText } from "@portabletext/react";
import { PortableTextBlock } from "sanity";

import { PortableTextBlock } from "src/components/richText/RichText";
import Text from "src/components/text/Text";
import textStyles from "src/components/text/text.module.css";

Expand Down
53 changes: 15 additions & 38 deletions src/components/richText/RichText.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,18 @@
"use client";

import { PortableText } from "@portabletext/react";
import { PortableText, PortableTextReactComponents } from "@portabletext/react";
import { ReactNode } from "react";
import { PortableTextBlock } from "sanity";

import Text from "src/components/text/Text";
import textStyles from "src/components/text/text.module.css";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { getReactNodeTextContent } from "src/utils/reactNode";

import styles from "./richText.module.css";

type Children = {
_type: string;
marks: any[];
text: string;
_key: string;
};

export type RichTextType = "h1" | "h2" | "h3" | "normal" | "blockquote";

export type PortableTextBlock = {
children?: Children[];
_type: string;
style?: RichTextType;
_key: string;
asset?: {
_ref: string;
_type: string;
};
alt?: string;
markDefs?: any[];
};

const formatId = (children: any): string => {
const text = children.join(" ");
const formatId = (children: ReactNode): string => {
const text = getReactNodeTextContent(children);

return text
.toLowerCase()
Expand All @@ -44,36 +25,32 @@ const SanityImage = ({ value }: { value: PortableTextBlock }) => {
return <div className={styles.image}>{ImageElement}</div>;
};

const myPortableTextComponents = {
const myPortableTextComponents: Partial<PortableTextReactComponents> = {
block: {
h2: ({ children }: any) => (
h2: ({ children }) => (
<Text type="h2" id={formatId(children)}>
{children}
</Text>
),
h3: ({ children }: any) => (
h3: ({ children }) => (
<Text type="h3" id={formatId(children)}>
{children}
</Text>
),
normal: ({ children }: any) => <Text type="body">{children}</Text>,
blockquote: ({ children }: any) => (
normal: ({ children }) => <Text type="body">{children}</Text>,
blockquote: ({ children }) => (
<blockquote className={`${styles.blockquote} ${textStyles.body}`}>
{children}
</blockquote>
),
},
list: {
bullet: ({ children }: any) => <ul className={styles.list}>{children}</ul>,
number: ({ children }: any) => <ol className={styles.list}>{children}</ol>,
bullet: ({ children }) => <ul className={styles.list}>{children}</ul>,
number: ({ children }) => <ol className={styles.list}>{children}</ol>,
},
listItem: {
bullet: ({ children }: any) => (
<li className={textStyles.body}>{children}</li>
),
number: ({ children }: any) => (
<li className={textStyles.body}>{children}</li>
),
bullet: ({ children }) => <li className={textStyles.body}>{children}</li>,
number: ({ children }) => <li className={textStyles.body}>{children}</li>,
},
types: {
image: SanityImage,
Expand Down
3 changes: 2 additions & 1 deletion src/components/sections/article/mockData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PortableTextBlock } from "src/components/richText/RichText";
import { PortableTextBlock } from "sanity";

import placeholder from "src/stories/assets/image-placeholder.png";
import { LinkType } from "studio/lib/interfaces/navigation";
import { ArticleSection } from "studio/lib/interfaces/pages";
Expand Down
6 changes: 3 additions & 3 deletions src/components/sections/callout/Callout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PortableText } from "@portabletext/react";
import { PortableText, PortableTextReactComponents } from "@portabletext/react";

import CustomLink from "src/components/link/CustomLink";
import Text from "src/components/text/Text";
Expand All @@ -10,8 +10,8 @@ interface CalloutProps {
callout: CalloutSection;
}

const myPortableTextComponents = {
block: ({ children }: any) => <Text type="bodySuperLarge">{children}</Text>,
const myPortableTextComponents: Partial<PortableTextReactComponents> = {
block: ({ children }) => <Text type="bodySuperLarge">{children}</Text>,
};

const Callout = ({ callout }: CalloutProps) => {
Expand Down
3 changes: 2 additions & 1 deletion src/components/sections/callout/mockData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PortableTextBlock } from "src/components/richText/RichText";
import { PortableTextBlock } from "sanity";

import { LinkType } from "studio/lib/interfaces/navigation";

const RichTextMock: PortableTextBlock[] = [
Expand Down
8 changes: 4 additions & 4 deletions src/components/sections/grid/Grid.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";
import { PortableText } from "@portabletext/react";
import { PortableText, PortableTextReactComponents } from "@portabletext/react";
import { PortableTextBlock } from "sanity";

import { PortableTextBlock } from "src/components/richText/RichText";
import Text from "src/components/text/Text";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { IImage } from "studio/lib/interfaces/media";
Expand Down Expand Up @@ -54,6 +54,6 @@ const Element = ({
);
};

const myPortableTextComponents = {
block: ({ children }: any) => <Text type="small">{children}</Text>,
const myPortableTextComponents: Partial<PortableTextReactComponents> = {
block: ({ children }) => <Text type="small">{children}</Text>,
};
3 changes: 2 additions & 1 deletion src/components/sections/grid/mockdata.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PortableTextBlock } from "src/components/richText/RichText";
import { PortableTextBlock } from "sanity";

import placeholder from "src/stories/assets/image-placeholder.png";

const commonRichText: PortableTextBlock[] = [
Expand Down
6 changes: 3 additions & 3 deletions src/components/sections/logoSalad/LogoSalad.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PortableText } from "@portabletext/react";
import { PortableText, PortableTextReactComponents } from "@portabletext/react";

import Text from "src/components/text/Text";
import { LogoSaladSection } from "studio/lib/interfaces/pages";
Expand All @@ -10,8 +10,8 @@ interface LogoSaladProps {
logoSalad: LogoSaladSection;
}

const myPortableTextComponents = {
block: ({ children }: any) => <Text type="bodySuperLarge">{children}</Text>,
const myPortableTextComponents: Partial<PortableTextReactComponents> = {
block: ({ children }) => <Text type="bodySuperLarge">{children}</Text>,
};

export const LogoSalad = ({ logoSalad }: LogoSaladProps) => {
Expand Down
8 changes: 4 additions & 4 deletions src/post/lead/Lead.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
"use client";
import { PortableText } from "@portabletext/react";
import { PortableText, PortableTextReactComponents } from "@portabletext/react";
import { PortableTextBlock } from "sanity";

import { PortableTextBlock } from "src/components/richText/RichText";
import Text from "src/components/text/Text";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { IImage } from "studio/lib/interfaces/media";

import styles from "./lead.module.css";

const myPortableTextComponents = {
block: ({ children }: any) => <Text type="bodyLarge">{children}</Text>,
const myPortableTextComponents: Partial<PortableTextReactComponents> = {
block: ({ children }) => <Text type="bodyLarge">{children}</Text>,
};

const Lead = ({
Expand Down
20 changes: 20 additions & 0 deletions src/utils/reactNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ReactNode, isValidElement } from "react";

export function getReactNodeTextContent(node: ReactNode): string {
if (typeof node === "string" || typeof node === "number") {
return node.toString();
}

if (Array.isArray(node)) {
return node.map(getReactNodeTextContent).join("");
}

if (isValidElement(node)) {
const children = node.props.children;
if (children) {
return getReactNodeTextContent(children);
}
}

return "";
}
7 changes: 4 additions & 3 deletions src/utils/seo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { toPlainText } from "@portabletext/toolkit";
import type { QueryParams } from "@sanity/client";
import { Metadata } from "next";
import { PortableTextBlock } from "sanity";

import { PortableTextBlock } from "src/components/richText/RichText";
import { urlFor } from "studio/lib/image";
import { BrandAssets } from "studio/lib/interfaces/brandAssets";
import { CompanyInfo } from "studio/lib/interfaces/companyDetails";
Expand Down Expand Up @@ -32,7 +33,7 @@ export const OPEN_GRAPH_IMAGE_DIMENSIONS = {

export async function fetchSeoData(
query: string,
variables?: any,
variables?: QueryParams | undefined,
): Promise<SeoData | null> {
try {
const { data } = await loadQuery<SeoData>(query, variables);
Expand All @@ -45,7 +46,7 @@ export async function fetchSeoData(

export async function fetchPostSeoData(
query: string,
variables?: any,
variables?: QueryParams | undefined,
): Promise<SeoData | null> {
try {
const { data } = await loadQuery<PostSeoData>(query, variables);
Expand Down
12 changes: 2 additions & 10 deletions studio/components/AnchorSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { Button, Select, Stack } from "@sanity/ui";
import React, { useEffect, useState } from "react";
import { PatchEvent, set, unset, useFormValue } from "sanity";
import { PatchEvent, StringInputProps, set, unset, useFormValue } from "sanity";

import { fetchWithToken } from "studio/lib/fetchWithToken";

interface AnchorSelectProps {
value?: string;
type: any;
onChange: (event: PatchEvent) => void;
path: any[];
schemaType: any;
}

interface AnchorItem {
basicTitle?: string;
value: string;
Expand All @@ -30,7 +22,7 @@ function fromCamelCase(value?: string) {
}); // Capitalize the first letter
}

const AnchorSelect = ({ value, onChange, path }: AnchorSelectProps) => {
const AnchorSelect = ({ value, onChange, path }: StringInputProps) => {
const [listItems, setListItems] = useState<AnchorItem[]>([]);

// Extract the internal link reference from the form value
Expand Down
Loading