Skip to content

Commit

Permalink
v3 - enforce no-explicit-any (#662)
Browse files Browse the repository at this point in the history
* refactor: no explicit any

enabled eslint rule no-explicit-any and fixed reported errors

* feat(RichText): replace custom RichTextBlock with Sanity type
  • Loading branch information
mathiazom authored Sep 19, 2024
1 parent 326cf9e commit 52fdfa9
Show file tree
Hide file tree
Showing 26 changed files with 115 additions and 169 deletions.
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

0 comments on commit 52fdfa9

Please sign in to comment.