refactor(plugin-ideal-image): migrate package to TS (#5940)

This commit is contained in:
Armano 2021-11-17 14:10:23 +01:00 committed by GitHub
parent 3bf59a65a9
commit ac1df888ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 139 additions and 14 deletions

View file

@ -5,8 +5,11 @@
"main": "lib/index.js",
"types": "src/plugin-ideal-image.d.ts",
"scripts": {
"build": "tsc && node copyUntypedFiles.js",
"watch": "node copyUntypedFiles.js && tsc --watch"
"build": "yarn build:server && yarn build:browser && yarn build:copy && yarn build:prettier",
"build:server": "tsc --project tsconfig.server.json",
"build:browser": "tsc --project tsconfig.browser.json",
"build:copy": "node copyUntypedFiles.js",
"build:prettier": "prettier --config ../../.prettierrc --write \"lib/**/*.js\""
},
"publishConfig": {
"access": "public"

View file

@ -5,4 +5,97 @@
* LICENSE file in the root directory of this source tree.
*/
declare module '@endiliey/react-ideal-image';
/**
* @see https://github.com/endiliey/react-ideal-image/blob/master/index.d.ts
*/
declare module '@endiliey/react-ideal-image' {
export type LoadingState = 'initial' | 'loading' | 'loaded' | 'error';
export type IconKey =
| 'load'
| 'loading'
| 'loaded'
| 'error'
| 'noicon'
| 'offline';
export interface SrcType {
width: number;
src?: string;
size?: number;
format?: 'webp' | 'jpeg' | 'png' | 'gif';
}
type ThemeKey = 'placeholder' | 'img' | 'icon' | 'noscript';
export interface ImageProps {
/**
* This function decides what icon to show based on the current state of the component.
*/
getIcon?: (state: LoadingState) => IconKey;
/**
* This function decides what message to show based on the icon (returned from getIcon prop) and
* the current state of the component.
*/
getMessage?: (icon: IconKey, state: LoadingState) => string;
/**
* This function is called as soon as the component enters the viewport and is used to generate urls
* based on width and format if props.srcSet doesn't provide src field.
*/
getUrl?: (srcType: SrcType) => string;
/**
* The Height of the image in px.
*/
height: number;
/**
* This provides a map of the icons. By default, the component uses icons from material design,
* implemented as React components with the SVG element. You can customize icons
*/
icons: Partial<Record<IconKey, ComponentType>>;
/**
* This prop takes one of the 2 options, xhr and image.
* Read more about it:
* https://github.com/stereobooster/react-ideal-image/blob/master/introduction.md#cancel-download
*/
loader?: 'xhr' | 'image';
/**
* https://github.com/stereobooster/react-ideal-image/blob/master/introduction.md#lqip
*/
placeholder: {color: string} | {lqip: string};
/**
* This function decides if image should be downloaded automatically. The default function
* returns false for a 2g network, for a 3g network it decides based on props.threshold
* and for a 4g network it returns true by default.
*/
shouldAutoDownload?: (options: {
connection?: 'slow-2g' | '2g' | '3g' | '4g';
size?: number;
threshold?: number;
possiblySlowNetwork?: boolean;
}) => boolean;
/**
* This provides an array of sources of different format and size of the image.
* Read more about it:
* https://github.com/stereobooster/react-ideal-image/blob/master/introduction.md#srcset
*/
srcSet: SrcType[];
/**
* This provides a theme to the component. By default, the component uses inline styles,
* but it is also possible to use CSS modules and override all styles.
*/
theme?: Partial<Record<ThemeKey, string | CSSProperties>>;
/**
* Tells how much to wait in milliseconds until consider the download to be slow.
*/
threshold?: number;
/**
* Width of the image in px.
*/
width: number;
}
type IdealImageComponent = ComponentClass<ImageProps>;
declare const IdealImage: IdealImageComponent;
export default IdealImage;
}

View file

@ -41,8 +41,23 @@ declare module '@docusaurus/plugin-ideal-image' {
declare module '@theme/IdealImage' {
import type {ComponentProps} from 'react';
export interface Props extends ComponentProps<'img'> {
img: any;
}
export type SrcType = {
width: number;
path?: string;
size?: number;
format?: 'webp' | 'jpeg' | 'png' | 'gif';
};
export type SrcImage = {
height?: number;
width?: number;
preSrc: string;
src: string;
images: SrcType[];
};
export type Props = ComponentProps<'img'> & {
img: {default: string} | {src: SrcImage; preSrc: string} | string;
};
export default function IdealImage(props: Props): JSX.Element;
}

View file

@ -6,16 +6,18 @@
*/
import React from 'react';
import IdealImage from '@endiliey/react-ideal-image';
import ReactIdealImage from '@endiliey/react-ideal-image';
function Image(props) {
import type {Props} from '@theme/IdealImage';
function IdealImage(props: Props): JSX.Element {
const {alt, className, img} = props;
// In dev env just use regular img with original file
if (typeof img === 'string' || typeof img.default === 'string') {
if (typeof img === 'string' || 'default' in img) {
return (
<img
src={img?.default ?? img}
src={typeof img === 'string' ? img : img.default}
className={className}
alt={alt}
{...props}
@ -24,7 +26,7 @@ function Image(props) {
}
return (
<IdealImage
<ReactIdealImage
{...props}
alt={alt}
className={className}
@ -40,4 +42,4 @@ function Image(props) {
);
}
export default Image;
export default IdealImage;

View file

@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "esnext",
"jsx": "react-native"
},
"include": ["src/theme/", "src/*.d.ts"]
}

View file

@ -1,9 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "./lib/.tsbuildinfo",
"lib": ["DOM", "ES2019"],
"rootDir": "src",
"baseUrl": "src",
"outDir": "lib"
}
}

View file

@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"include": ["src/*.ts"]
}