Skip to content

Commit

Permalink
fix(gatsby-plugin-image): Fix StaticImage props interface and add pro…
Browse files Browse the repository at this point in the history
…pTypes (#28372)

* Add proptypes and better props defs

* Fix compilation error
  • Loading branch information
ascorbic authored Dec 1, 2020
1 parent 91b0433 commit 93a1447
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import {
} from "./hooks"
import { PlaceholderProps } from "./placeholder"
import { MainImageProps } from "./main-image"
import { Layout } from "../utils"

export type GatsbyImageProps = Omit<
ImgHTMLAttributes<HTMLImageElement>,
"placeholder" | "onLoad" | "src" | "srcSet" | "width" | "height"
> & {
import { Layout } from "../image-utils"

// eslint-disable-next-line @typescript-eslint/interface-name-prefix
export interface GatsbyImageProps
extends Omit<
ImgHTMLAttributes<HTMLImageElement>,
"placeholder" | "onLoad" | "src" | "srcSet" | "width" | "height"
> {
alt: string
as?: ElementType
className?: string
Expand Down
7 changes: 5 additions & 2 deletions packages/gatsby-plugin-image/src/components/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ import {
import { Node } from "gatsby"
import { PlaceholderProps } from "./placeholder"
import { MainImageProps } from "./main-image"
import { Layout } from "../utils"
import type { IGatsbyImageData } from "./gatsby-image.browser"
import { IGatsbyImageHelperArgs, generateImageData } from "../image-utils"
import {
IGatsbyImageHelperArgs,
generateImageData,
Layout,
} from "../image-utils"
const imageCache = new Set<string>()

// Native lazy-loading support: https://addyosmani.com/blog/lazy-loading/
Expand Down
12 changes: 9 additions & 3 deletions packages/gatsby-plugin-image/src/components/layout-wrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* global SERVER */
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
/// <reference path="../global.d.ts" />

import React, { Fragment, FunctionComponent } from "react"
import terserMacro from "../../macros/terser.macro"
import { Layout } from "../utils"
import { Layout } from "../image-utils"

export interface ILayoutWrapperProps {
layout: Layout
Expand Down Expand Up @@ -71,7 +73,11 @@ export const LayoutWrapper: FunctionComponent<ILayoutWrapperProps> = function La
<Fragment>
{sizer}
{children}
{SERVER && <NativeScriptLoading />}

{
// eslint-disable-next-line no-undef
SERVER && <NativeScriptLoading />
}
</Fragment>
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
import React, { FunctionComponent } from "react"
import { StaticImageProps } from "../utils"
import { GatsbyImage as GatsbyImageServer } from "./gatsby-image.server"
import { GatsbyImageProps, IGatsbyImageData } from "./gatsby-image.browser"
import PropTypes from "prop-types"
import { ImageFormat, Layout, Fit } from "../image-utils"

export interface IStaticImageProps extends Omit<GatsbyImageProps, "image"> {
src: string
layout?: Layout
formats?: Array<ImageFormat>
placeholder?: "tracedSVG" | "dominantColor" | "blurred" | "none"
tracedSVGOptions?: Record<string, unknown>
width?: number
height?: number
maxWidth?: number
maxHeight?: number
sizes?: string
quality?: number
transformOptions: {
fit?: Fit
}
jpgOptions?: Record<string, unknown>
pngOptions?: Record<string, unknown>
webpOptions?: Record<string, unknown>
blurredOptions: Record<string, unknown>
}

// These values are added by Babel. Do not add them manually
interface IPrivateProps {
Expand All @@ -11,11 +33,26 @@ interface IPrivateProps {

export function _getStaticImage(
GatsbyImage: FunctionComponent<GatsbyImageProps>
): React.FC<StaticImageProps & IPrivateProps> {
): React.FC<IStaticImageProps & IPrivateProps> {
return function StaticImage({
src,
__imageData: imageData,
__error,
/* eslint-disable @typescript-eslint/no-unused-vars */
width,
maxWidth,
height,
maxHeight,
tracedSVGOptions,
placeholder,
formats,
quality,
transformOptions,
jpgOptions,
pngOptions,
webpOptions,
blurredOptions,
/* eslint-enable @typescript-eslint/no-unused-vars */
...props
}): JSX.Element {
if (__error) {
Expand All @@ -35,6 +72,55 @@ export function _getStaticImage(
}
}

export const StaticImage: React.FC<
StaticImageProps & IPrivateProps
const StaticImage: React.FC<
IStaticImageProps & IPrivateProps
> = _getStaticImage(GatsbyImageServer)

const checkDimensionProps: PropTypes.Validator<number> = (
props: IStaticImageProps & IPrivateProps,
propName: keyof IStaticImageProps & IPrivateProps,
...rest
) => {
if (props.layout === `fluid` || props.layout === `constrained`) {
if (propName === `maxWidth` && !props[propName]) {
return new Error(
`The prop "${propName}" is required when layout is "${props.layout}"`
)
}
if ((propName === `width` || propName === `height`) && props[propName]) {
return new Error(
`"${propName}" ${props[propName]} may not be passed when layout is "${props.layout}"`
)
}
} else {
if (
(propName === `maxWidth` || propName === `maxHeight`) &&
props[propName]
) {
return new Error(
`"${propName}" may not be passed when layout is "${props.layout}"`
)
}
if (propName === `width` && !props[propName]) {
return new Error(
`The prop "${propName}" is required when layout is "${props.layout}"`
)
}
}
return PropTypes.number(props, propName, ...rest)
}

export const propTypes = {
src: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
width: checkDimensionProps,
height: checkDimensionProps,
maxHeight: checkDimensionProps,
maxWidth: checkDimensionProps,
sizes: PropTypes.string,
}

StaticImage.displayName = `StaticImage`
StaticImage.propTypes = propTypes

export { StaticImage }
16 changes: 12 additions & 4 deletions packages/gatsby-plugin-image/src/components/static-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@ import {
GatsbyImage as GatsbyImageBrowser,
IGatsbyImageData,
} from "./gatsby-image.browser"
import { _getStaticImage } from "./static-image.server"
import { StaticImageProps } from "../utils"
import {
_getStaticImage,
propTypes,
IStaticImageProps,
} from "./static-image.server"
// These values are added by Babel. Do not add them manually
interface IPrivateProps {
__imageData?: IGatsbyImageData
__error?: string
}

export const StaticImage: React.FC<
StaticImageProps & IPrivateProps
const StaticImage: React.FC<
IStaticImageProps & IPrivateProps
> = _getStaticImage(GatsbyImageBrowser)

StaticImage.displayName = `StaticImage`
StaticImage.propTypes = propTypes

export { StaticImage }
3 changes: 1 addition & 2 deletions packages/gatsby-plugin-image/src/image-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const DEFAULT_FIXED_WIDTH = 400
export type Fit = "cover" | "fill" | "inside" | "outside" | "contain"

export type Layout = "fixed" | "fluid" | "constrained"
export type ImageFormat = "jpg" | "png" | "webp" | "avif" | "auto" | ""

/**
* The minimal required reporter, as we don't want to import it from gatsby-cli
Expand Down Expand Up @@ -66,8 +67,6 @@ export interface IImage {
format: ImageFormat
}

export type ImageFormat = "jpg" | "png" | "webp" | "avif" | "auto" | ""

export interface IGatsbyImageHelperArgs {
pluginName: string
generateImageSource: (
Expand Down
3 changes: 1 addition & 2 deletions packages/gatsby-plugin-image/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ImgHTMLAttributes, ElementType } from "react"

export type Layout = "fixed" | "fluid" | "constrained"
import { Layout } from "./image-utils"

export interface ICommonImageProps {
layout?: Layout
Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby-plugin-image/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
"skipLibCheck": true
// "jsxFactory": "createElement"
},
"include": ["./src/global.d.ts", "./src/index.ts", "./src/index.browser.ts"]
"files": ["./src/global.d.ts", "./src/index.ts", "./src/index.browser.ts"]
}

0 comments on commit 93a1447

Please sign in to comment.