Skip to content

Commit

Permalink
Organize types export
Browse files Browse the repository at this point in the history
  • Loading branch information
Legend-Master committed Aug 14, 2024
1 parent 6a32f1d commit 1ac5a91
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 67 deletions.
62 changes: 12 additions & 50 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,22 @@
import path from 'node:path'
import type { LoadContext, Plugin, OptionValidationContext } from '@docusaurus/types'
import type { ComponentProps } from 'react'
import {
DEFAULT_LOADER_OPTIONS,
type OutputDataForFormat,
type SupportedOutputMimeTypes,
type SupportedOutputTypes,
} from './loader.js'
import { DEFAULT_LOADER_OPTIONS, type LoaderOptions } from './loader.js'
// import { Compilation, Compiler, NormalModule, type LoaderContext } from 'webpack'
// import { fileURLToPath } from 'node:url'

export type Preset = {
sizes?: number | number[]
formats?: SupportedOutputTypes | SupportedOutputTypes[]
lqip?: boolean
}

export type LoaderOptions = {
/**
* File name template for output files
*/
fileNameTemplate: string
/**
* Image loader presets
*/
presets: Record<string, Preset>
/**
* Low quality image placeholder format
*/
lqipFormat: SupportedOutputTypes
/**
* Disable in dev mode for faster compile time
*/
disableInDev: boolean
}
export type { NativeIdealImageProps } from './theme/NativeIdealImage.js'
export type {
LoaderOutput,
DEFAULT_LOADER_OPTIONS,
SrcSetData,
SupportedOutputMimeTypes,
SupportedOutputTypes,
OutputDataForFormat,
LoaderOptions,
Preset,
} from './loader.js'
export type NativeIdealImageOptions = Partial<LoaderOptions>

export type LoaderOutput = {
formats: OutputDataForFormat[]
// src: {
// fileName: string
// width: number
// height: number
// }
lqip?: string
}

export type NativeIdealImageProps = Omit<ComponentProps<'img'>, 'ref'> & {
readonly img: { default: string | LoaderOutput } | string | LoaderOutput
/**
* Swap (fade in) the actual image after it's fully loaded,
* requires JavaScript to work, so this might cause the image to load a bit slower
* */
swapOnLoad?: boolean
}

export default function pluginNativeIdealImage(
context: LoadContext,
options: NativeIdealImageOptions
Expand Down
38 changes: 36 additions & 2 deletions src/loader.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { LoaderContext } from 'webpack'
import { readFile } from 'node:fs/promises'
import sharp from 'sharp'
import loaderUtils from 'loader-utils'
import { type LoaderOutput, type LoaderOptions } from './index.js'
import sharp from 'sharp'

const MIMES = {
jpeg: 'image/jpeg',
Expand All @@ -24,6 +23,41 @@ export type OutputDataForFormat = {
srcSet: SrcSetData[]
}

export type Preset = {
sizes?: number | number[]
formats?: SupportedOutputTypes | SupportedOutputTypes[]
lqip?: boolean
}

export type LoaderOptions = {
/**
* File name template for output files
*/
fileNameTemplate: string
/**
* Image loader presets
*/
presets: Record<string, Preset>
/**
* Low quality image placeholder format
*/
lqipFormat: SupportedOutputTypes
/**
* Disable in dev mode for faster compile time
*/
disableInDev: boolean
}

export type LoaderOutput = {
formats: OutputDataForFormat[]
// src: {
// fileName: string
// width: number
// height: number
// }
lqip?: string
}

export const DEFAULT_LOADER_OPTIONS = {
fileNameTemplate: 'assets/native-ideal-image/[name]-[hash:hex:5]-[width].[format]',
lqipFormat: 'webp',
Expand Down
37 changes: 22 additions & 15 deletions src/theme/NativeIdealImage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import React, { useEffect, useRef, useState } from 'react'
import React, { useEffect, useRef, useState, type ComponentProps } from 'react'
import clsx from 'clsx'
import type { NativeIdealImageProps } from '../index.js'
import type { LoaderOutput } from '../index.js'
import type { SrcSetData } from '../loader.js'

import './NativeIdealImage.css'

export type NativeIdealImageProps = Omit<ComponentProps<'img'>, 'ref'> & {
readonly img: { default: string | LoaderOutput } | string | LoaderOutput
/**
* Swap (fade in) the actual image after it's fully loaded,
* requires JavaScript to work, so this might cause the image to load a bit slower
* */
swapOnLoad?: boolean
}

// This is kinda messy handling all those posibilities at a single place >.<
export default function NativeIdealImage(props: NativeIdealImageProps): JSX.Element {
const { img, swapOnLoad, src, srcSet, width, height, sizes, loading, ...propsRest } = props
Expand Down Expand Up @@ -47,25 +57,15 @@ export default function NativeIdealImage(props: NativeIdealImageProps): JSX.Elem
onLoad={() => setLoaded(true)}
>
{sources?.map((format) => (
<source
srcSet={
isSingleImage
? encodeURI(format.srcSet[0]!.path)
: format.srcSet.map((image) => `${encodeURI(image.path)} ${image.width}w`).join(',')
}
type={format.mime}
key={format.mime}
/>
<source srcSet={getSource(format.srcSet)} type={format.mime} key={format.mime} />
))}
<img
loading={loading ?? 'lazy'}
src={src ?? enabled ? (isSingleImage ? lastFormat!.srcSet[0]!.path : undefined) : data}
src={src ?? enabled ? (isSingleImage ? getSource(lastFormat!.srcSet) : undefined) : data}
srcSet={
srcSet ?? enabled
? !isSingleImage
? lastFormat!.srcSet
.map((image) => `${encodeURI(image.path)} ${image.width}w`)
.join(',')
? getSource(lastFormat!.srcSet)
: undefined
: undefined
}
Expand All @@ -80,3 +80,10 @@ export default function NativeIdealImage(props: NativeIdealImageProps): JSX.Elem
</picture>
)
}

function getSource(srcSet: SrcSetData[]) {
if (srcSet.length === 1) {
return encodeURI(srcSet[0]!.path)
}
return srcSet.map((image) => `${encodeURI(image.path)} ${image.width}w`).join(',')
}

0 comments on commit 1ac5a91

Please sign in to comment.