diff --git a/src/components/Homepage/BodySection/BodySection.tsx b/src/components/Homepage/BodySection/BodySection.tsx index 0e37c6154e..6fe43d87ea 100644 --- a/src/components/Homepage/BodySection/BodySection.tsx +++ b/src/components/Homepage/BodySection/BodySection.tsx @@ -1,6 +1,5 @@ -import React from 'react'; import cn from 'classnames'; -import { ImageProps } from 'src/components/Image'; +import { ImageProps, getImageFromList } from 'src/components/Image'; import { SectionProps } from '../HomepageContent'; import { BodySectionDescription } from './BodySectionDescription'; import { HeroCard } from './Card/HeroCard'; @@ -33,16 +32,6 @@ const gridGapVariants = { 4: 'gap-24', }; -const getImage = (images = [], name): { images: ImageProps[]; name: string } => { - const result = images.find((image) => image.base === name); - - if (name && result === undefined) { - console.warn(`Could not find image '${name}' in list`, images); - } - - return result; -}; - export const BodySection = ({ section, images }: { section: SectionProps; images: ImageProps[] }) => { const cards = section.cards ?? []; const cardsExist = cards.length > 0; @@ -50,8 +39,6 @@ export const BodySection = ({ section, images }: { section: SectionProps; images const singleColumn = columns == 1; const bottomMargin = sectionBottomMarginVariants[section.bottomMargin]; - console.log(images); - return (
{section.title &&

{section.title}

} @@ -64,8 +51,13 @@ export const BodySection = ({ section, images }: { section: SectionProps; images > {cards.map((card, index) => { const Card = cardTypes[card.type]; - const image = getImage(images, card.image); - return ; + return ( + + ); })} )} diff --git a/src/components/Homepage/BodySection/Card/FeatureCard.tsx b/src/components/Homepage/BodySection/Card/FeatureCard.tsx index 8c05068cb3..5ba0041bc8 100644 --- a/src/components/Homepage/BodySection/Card/FeatureCard.tsx +++ b/src/components/Homepage/BodySection/Card/FeatureCard.tsx @@ -4,13 +4,13 @@ import { Image } from '../../../Image'; export const FeatureCard = ({ title, content, image, links }: CardProps) => (
- +

{title}

{content}

- +
); diff --git a/src/components/Homepage/HomepageContent.tsx b/src/components/Homepage/HomepageContent.tsx index 881214e716..45f59d9e9f 100644 --- a/src/components/Homepage/HomepageContent.tsx +++ b/src/components/Homepage/HomepageContent.tsx @@ -5,7 +5,7 @@ import { ImageProps } from 'src/components/Image'; export type CardProps = { title: string; content: string; - image: string; + image: ImageProps; type: 'hero' | 'feature' | 'sdk'; links?: LinkProps[]; callToAction?: CallToActionProps; diff --git a/src/components/Image.tsx b/src/components/Image.tsx index 78f581cfba..cb4d6d7923 100644 --- a/src/components/Image.tsx +++ b/src/components/Image.tsx @@ -1,17 +1,30 @@ -import { GatsbyImage, GatsbyImageData, getImage } from 'gatsby-plugin-image'; +import { GatsbyImage, IGatsbyImageData, getImage } from 'gatsby-plugin-image'; import { ComponentProps } from 'react'; -export type ImageProp = { - childImageSharp: GatsbyImageData; +export type ImageProps = { + childImageSharp: IGatsbyImageData; extension: string; publicURL: string; + src?: string; + base?: string; }; export type ImageComponentProps = ComponentProps<'img'> & { - image: ImageProp; + image: ImageProps; }; -export const Image = ({ image, src, ...attribs }: ImageProps) => { +export const getImageFromList = (images: ImageProps[] = [], name?: string | ImageProps): ImageProps | undefined => { + const imageName = typeof name === 'string' ? name : name?.base; + const result = images.find((image) => image.base === imageName); + + if (name && result === undefined) { + console.warn(`Could not find image '${name}' in list`, images); + } + + return result; +}; + +export const Image = ({ image, src, ...attribs }: ImageComponentProps) => { if (!image) { return; } @@ -27,8 +40,11 @@ export const Image = ({ image, src, ...attribs }: ImageProps) => { return ; } - const { alt } = attribs ?? ''; - delete attribs.alt; + const { alt, className } = attribs ?? {}; + const imageAttributes = { alt: alt ?? '', className }; + const fetchedImage = getImage(image.childImageSharp); - return ; + if (fetchedImage) { + return ; + } }; diff --git a/src/components/Link.tsx b/src/components/Link.tsx index 420c5bc330..cf278a7375 100644 --- a/src/components/Link.tsx +++ b/src/components/Link.tsx @@ -6,7 +6,7 @@ export default function Link({ to, external, ...props -}: React.PropsWithoutRef>) { +}: React.PropsWithoutRef> & { external?: boolean }) { const isInternal = checkLinkIsInternal(to); const isOnPage = to?.startsWith('#'); @@ -14,7 +14,6 @@ export default function Link({ * Relevant page of documentation: https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-link/#recommendations-for-programmatic-in-app-navigation * "If you need this (in-app navigation) behavior, you should either use an anchor tag or import the navigate helper from gatsby" */ - /* console.log(to, isInternal, !external, !isOnPage); */ if (isInternal && !external && !isOnPage) { const href = normalizeLegacyDocsLink(to); diff --git a/src/components/ProductPage/BodySection/BodySection.tsx b/src/components/ProductPage/BodySection/BodySection.tsx index 8b051fa31f..873a2aa8aa 100644 --- a/src/components/ProductPage/BodySection/BodySection.tsx +++ b/src/components/ProductPage/BodySection/BodySection.tsx @@ -6,6 +6,7 @@ import { QuickstartCard } from './Card/QuickstartCard'; import { ExampleCard } from './Card/ExampleCard'; import { TutorialCard } from './Card/TutorialCard'; import { CallToAction } from './CallToAction'; +import { ImageProps, getImageFromList } from 'src/components/Image'; const cardTypes = { feature: FeatureCard, @@ -22,16 +23,6 @@ const betaPillStyle = { paddingTop: '0.313rem', }; -const getImage = (images = [], name): { images: ImageProps[]; name: string } => { - const result = images.find((image) => image.base === name); - - if (name && result === undefined) { - console.warn(`Could not find image '${name}' in list`, images); - } - - return result; -}; - export const BodySection = ({ section, images }: { section: SectionProps; images: ImageProps[] }) => { const cards = section.cards ?? []; const cardsExist = cards.length > 0; @@ -64,8 +55,14 @@ export const BodySection = ({ section, images }: { section: SectionProps; images > {cards.map((card, index) => { const Card = cardTypes[card.type as keyof typeof cardTypes]; - const image = getImage(images, card.image); - return ; + + return ( + + ); })} )} diff --git a/src/components/ProductPage/BodySection/Card/ExampleCard.tsx b/src/components/ProductPage/BodySection/Card/ExampleCard.tsx index fbaff91558..2d62fcd374 100644 --- a/src/components/ProductPage/BodySection/Card/ExampleCard.tsx +++ b/src/components/ProductPage/BodySection/Card/ExampleCard.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { CardProps } from '../../ProductPageContent'; import { Image } from '../../../Image'; import Link from '../../../Link'; @@ -9,7 +8,7 @@ export const ExampleCard = ({ title, image, link, external }: CardProps) => ( external={external} className="items-center border border-extra-light-grey rounded-lg bg-extra-light-grey flex flex-col h-full hover:border-mid-grey hover:text-cool-black group" > - +

{title}

diff --git a/src/components/ProductPage/BodySection/Card/FeatureCard.tsx b/src/components/ProductPage/BodySection/Card/FeatureCard.tsx index 9dcb9eb9e6..dae89bbe7c 100644 --- a/src/components/ProductPage/BodySection/Card/FeatureCard.tsx +++ b/src/components/ProductPage/BodySection/Card/FeatureCard.tsx @@ -1,10 +1,9 @@ -import React from 'react'; import { CardProps } from '../../ProductPageContent'; import { Links } from './Links'; import { Image } from '../../../Image'; export const FeatureCard = ({ title, content, image, links }: CardProps) => ( -
+
@@ -13,9 +12,9 @@ export const FeatureCard = ({ title, content, image, links }: CardProps) => ( {content}

- +
- +
); diff --git a/src/components/ProductPage/BodySection/Card/Links.tsx b/src/components/ProductPage/BodySection/Card/Links.tsx index 07c8f1fd8d..959a6fe832 100644 --- a/src/components/ProductPage/BodySection/Card/Links.tsx +++ b/src/components/ProductPage/BodySection/Card/Links.tsx @@ -2,46 +2,49 @@ import Icon from '@ably/ui/core/Icon'; import { LinkProps } from '../../ProductPageContent'; import Link from '../../../Link'; -export const Links = ({ links }: { links: LinkProps[] }) => ( -
- {links && links?.length == 1 && ( -
- {links.map(({ href, external, text }, index) => { - return ( -
- - {text} - - -
- ); - })} +export const Links = ({ links }: { links?: LinkProps[] }) => + links ? ( + <> +
+ {links.length === 1 && ( +
+ {links.map(({ href, external, text }, index) => { + return ( +
+ + {text} + + +
+ ); + })} +
+ )} + {links.length > 1 && ( +
    + {links.map(({ href, external, text }, index) => { + return ( +
  • + + {text} + +
  • + ); + })} +
+ )}
- )} - {links && links?.length > 1 && ( -
    - {links.map(({ href, external, text }, index) => { - return ( -
  • - - {text} - -
  • - ); - })} -
- )} -
-); + + ) : null; diff --git a/src/components/ProductPage/BodySection/Card/QuickstartCard.tsx b/src/components/ProductPage/BodySection/Card/QuickstartCard.tsx index 1511b4496e..4beb5bf6af 100644 --- a/src/components/ProductPage/BodySection/Card/QuickstartCard.tsx +++ b/src/components/ProductPage/BodySection/Card/QuickstartCard.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { CardProps } from '../../ProductPageContent'; import { Image } from '../../../Image'; import { Links } from './Links'; @@ -6,7 +5,7 @@ import { Links } from './Links'; export const QuickstartCard = ({ title, content, image, links }: CardProps) => (
- {`${title}`} + {title}

{title}

@@ -15,6 +14,6 @@ export const QuickstartCard = ({ title, content, image, links }: CardProps) => ( {content}

- +
); diff --git a/src/components/ProductPage/BodySection/Card/TutorialCard.tsx b/src/components/ProductPage/BodySection/Card/TutorialCard.tsx index 4fcc8ed7ca..f6eaade7e8 100644 --- a/src/components/ProductPage/BodySection/Card/TutorialCard.tsx +++ b/src/components/ProductPage/BodySection/Card/TutorialCard.tsx @@ -1,10 +1,9 @@ -import React from 'react'; import { CardProps } from '../../ProductPageContent'; import { Image } from '../../../Image'; import { Links } from './Links'; export const TutorialCard = ({ title, image, links }: CardProps) => ( -
+
{title}

diff --git a/src/components/ProductPage/ProductPageContent.tsx b/src/components/ProductPage/ProductPageContent.tsx index a04bc14ba6..2a1fd36a4b 100644 --- a/src/components/ProductPage/ProductPageContent.tsx +++ b/src/components/ProductPage/ProductPageContent.tsx @@ -1,11 +1,10 @@ -import React from 'react'; import { BodySection } from './BodySection/BodySection'; import { ImageProps } from 'src/components/Image'; export type LinkProps = { text: string; href: string; - external: string; + external: boolean; }; export type CallToActionProps = { @@ -19,7 +18,7 @@ export type CardProps = { title: string; type: string; content: string; - image: string; + image: ImageProps; link: string; external: boolean; links: LinkProps[]; diff --git a/src/components/SDKsPage/index.tsx b/src/components/SDKsPage/index.tsx index f6c46f1171..2497996e3d 100644 --- a/src/components/SDKsPage/index.tsx +++ b/src/components/SDKsPage/index.tsx @@ -13,7 +13,7 @@ const Content = ({ tab }: { tab: string }) => {

{data.hero.title}

{data.hero.subtitle}

- +
diff --git a/src/components/StaticImage.tsx b/src/components/StaticImage.tsx index 344e899c23..2a683e7e42 100644 --- a/src/components/StaticImage.tsx +++ b/src/components/StaticImage.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { graphql, useStaticQuery, withPrefix } from 'gatsby'; import { ComponentProps } from 'react'; @@ -10,6 +9,11 @@ export const StaticImage = ({ src, ...attribs }: ComponentProps<'img'>) => { } } `); + + if (!src) { + return; + } + const assetPrefix = result?.site.assetPrefix ?? ''; const srcUrl = `${assetPrefix}${withPrefix(src)}`; diff --git a/src/components/blocks/external-references/Img.tsx b/src/components/blocks/external-references/Img.tsx index acbb2576c2..f401d83224 100644 --- a/src/components/blocks/external-references/Img.tsx +++ b/src/components/blocks/external-references/Img.tsx @@ -1,4 +1,4 @@ -import React, { ReactElement } from 'react'; +import { ReactElement, ReactNode } from 'react'; import Zoom from 'react-medium-image-zoom'; import { StaticImage } from 'src/components/StaticImage'; import { GatsbyImage, getImage } from 'gatsby-plugin-image'; @@ -9,7 +9,7 @@ import { useContentImages } from 'src/contexts/content-images-context'; import 'react-medium-image-zoom/dist/styles.css'; import { classDialog } from './Img.module.css'; -const Wrapper = ({ children }) => ( +const Wrapper = ({ children }: { children: ReactNode }) => ( {children} @@ -19,6 +19,10 @@ const Img = ({ attribs }: Pick, 'attribs'>): ReactElem const rawSrc = attribs?.src; const { findImage } = useContentImages(); + if (!rawSrc) { + return <>; + } + if (rawSrc.startsWith('@')) { const image = findImage(rawSrc); const { childImageSharp, publicURL } = image ?? {}; @@ -31,11 +35,19 @@ const Img = ({ attribs }: Pick, 'attribs'>): ReactElem ); } - return ( - - - - ); + if (image) { + const imageData = getImage(image?.childImageSharp); + const { alt, className } = attribs ?? {}; + const imageAttributes = { alt: alt ?? '', className }; + + if (imageData) { + return ( + + + + ); + } + } } return ( diff --git a/src/contexts/content-images-context.tsx b/src/contexts/content-images-context.tsx index bf905351f0..fd28f9b63d 100644 --- a/src/contexts/content-images-context.tsx +++ b/src/contexts/content-images-context.tsx @@ -1,16 +1,16 @@ import { FC, ReactNode, createContext, useContext } from 'react'; import { graphql } from 'gatsby'; -import { GatsbyImageData } from 'gatsby-plugin-image'; +import { IGatsbyImageData } from 'gatsby-plugin-image'; export type Image = { - childImageSharp: GatsbyImageData; + childImageSharp: IGatsbyImageData; extension: string; publicURL: string; relativePath: string; }; -export const findImage: (rawSrc: string) => Image | undefined = (images: Image[]) => { - return (rawSrc): Image | undefined => { +export const findImage = (images: Image[]) => { + return (rawSrc: string) => { const src = rawSrc.replace('@', ''); return images.find((image) => image.relativePath === src); diff --git a/src/globals.d.ts b/src/globals.d.ts new file mode 100644 index 0000000000..e2937d470e --- /dev/null +++ b/src/globals.d.ts @@ -0,0 +1 @@ +declare module '*.png'; diff --git a/src/utilities/link-checks.ts b/src/utilities/link-checks.ts index 5847a1ecc1..531f7c1485 100644 --- a/src/utilities/link-checks.ts +++ b/src/utilities/link-checks.ts @@ -9,7 +9,7 @@ const legacyDocsUrlPattern = /^(https?:\/\/(?:www\.)?ably.com\/docs).*/; * This function will drop the protocol, host & `/docs` path from legacy * docs links that might have been hard coded somewhere in the content */ -export const normalizeLegacyDocsLink = (link: string): link is string => { +export const normalizeLegacyDocsLink = (link: string) => { const match = legacyDocsUrlPattern.exec(link); if (match !== null) {