-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add asImageSrc
, asImageWidthSrcSet
, asImagePixelDensitySrcSet
#38
Merged
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
76fcf4c
feat: add `asImageSrc`, `asImageWidthSrcSet`, `asImagePixelDensitiesS…
angeloashmore 6e6e0c2
refactor: rename `asImagePixelDensitiesSrcSet` file
angeloashmore 8f333ba
test: image helpers
angeloashmore e699b79
chore(deps): update `imgix-url-builder`
angeloashmore 4cb984f
feat: add responsive-view-based image srcset builder
angeloashmore 8fdd824
Merge branch 'master' into aa/image-helpers
angeloashmore 8f59e98
Merge branch 'master' into aa/image-helpers
angeloashmore a30ee9a
feat: add default pixel densities
angeloashmore 7a182d1
refactor: `asImageWidthSrcSet()`
angeloashmore 7d78895
feat: return src and srcset from srcset helpers
angeloashmore 8aa3029
refactor: image helpers
angeloashmore 6b6dc0e
docs: update examples
angeloashmore eed57bf
Merge branch 'master' into aa/image-helpers
angeloashmore 4cc637c
chore(deps): update dependencies
angeloashmore e23e31e
test: remove snapshots
angeloashmore f827375
test: add snapshots
angeloashmore a37fe39
chore: force ava to run in non-ci mode
angeloashmore f4080e8
Revert "chore: force ava to run in non-ci mode"
angeloashmore b0612e0
chore: lock AVA to v4.0.0
angeloashmore a24b525
Revert "chore: lock AVA to v4.0.0"
angeloashmore a4c54fe
chore: remove nyc from `unit` script
angeloashmore d7a7b84
Revert "chore: remove nyc from `unit` script"
angeloashmore 2706938
chore: move snapshots adjacent to test files
angeloashmore d10995b
chore: revert to AVA 3
angeloashmore 4f272c9
Merge branch 'master' into aa/image-helpers
angeloashmore a36efc1
fix: use Next.js's default srcset widths
angeloashmore 8cb2dde
docs: reformat `pixelDensities` default value description
angeloashmore 61b4e9f
test: use non-default pixelDensities in test
angeloashmore 79ed950
docs: update `asImagePixelDensitySrcSet()` example with custom pixel …
angeloashmore a0adc62
Merge branch 'master' into aa/image-helpers
angeloashmore c685252
chore: fix package-lock.json
angeloashmore 80556b0
fix: apply width to base srcset image in `asImageWidthSrcSet()` with …
angeloashmore 3b66b0a
fix: reduce number of default widths in `asImageWidthSrcSet()`
angeloashmore File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { ImageFieldImage } from "@prismicio/types"; | ||
import { | ||
buildPixelDensitySrcSet, | ||
BuildPixelDensitySrcSetParams, | ||
buildURL, | ||
} from "imgix-url-builder"; | ||
|
||
import { imageThumbnail as isImageThumbnailFilled } from "./isFilled"; | ||
|
||
/** | ||
* The return type of `asImagePixelDensitySrcSet()`. | ||
*/ | ||
type AsImagePixelDensitySrcSetReturnType<Field extends ImageFieldImage> = | ||
Field extends ImageFieldImage<"empty"> | ||
? null | ||
: { | ||
/** | ||
* The Image field's image URL with Imgix URL parameters (if given). | ||
*/ | ||
src: string; | ||
|
||
/** | ||
* A pixel-densitye-based `srcset` attribute value for the Image field's | ||
* image with Imgix URL parameters (if given). | ||
*/ | ||
srcset: string; | ||
}; | ||
|
||
/** | ||
* Creates a pixel-density-based `srcset` from an Image field with optional | ||
* image transformations (via Imgix URL parameters). | ||
* | ||
* If a `pixelDensities` parameter is not given, the following pixel densities | ||
* will be used by default: 1, 2, 3. | ||
* | ||
* @example | ||
* | ||
* ```ts | ||
* const srcset = asImagePixelDensitySrcSet(document.data.imageField, { | ||
* pixelDensities: [1, 2], | ||
* sat: -100, | ||
* }); | ||
* // => { | ||
* // src: 'https://images.prismic.io/repo/image.png?sat=-100', | ||
* // srcset: 'https://images.prismic.io/repo/image.png?sat=-100&dpr=1 1x, ' + | ||
* // 'https://images.prismic.io/repo/image.png?sat=-100&dpr=2 2x' | ||
* // } | ||
* ``` | ||
* | ||
* @param field - Image field (or one of its responsive views) from which to get | ||
* an image URL. | ||
* @param params - An object of Imgix URL API parameters. The `pixelDensities` | ||
* parameter defines the resulting `srcset` widths. | ||
* | ||
* @returns A `srcset` attribute value for the Image field with Imgix URL | ||
* parameters (if given). If the Image field is empty, `null` is returned. | ||
* @see Imgix URL parameters reference: https://docs.imgix.com/apis/rendering | ||
*/ | ||
export const asImagePixelDensitySrcSet = <Field extends ImageFieldImage>( | ||
field: Field, | ||
params: Omit<BuildPixelDensitySrcSetParams, "pixelDensities"> & | ||
Partial<Pick<BuildPixelDensitySrcSetParams, "pixelDensities">> = {}, | ||
): AsImagePixelDensitySrcSetReturnType<Field> => { | ||
if (isImageThumbnailFilled(field)) { | ||
const { pixelDensities = [1, 2, 3], ...imgixParams } = params; | ||
|
||
return { | ||
src: buildURL(field.url, imgixParams), | ||
srcset: buildPixelDensitySrcSet(field.url, { | ||
...imgixParams, | ||
pixelDensities, | ||
}), | ||
} as AsImagePixelDensitySrcSetReturnType<Field>; | ||
} else { | ||
return null as AsImagePixelDensitySrcSetReturnType<Field>; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { ImageFieldImage } from "@prismicio/types"; | ||
import { buildURL, ImgixURLParams } from "imgix-url-builder"; | ||
|
||
import { imageThumbnail as isImageThumbnailFilled } from "./isFilled"; | ||
|
||
/** | ||
* The return type of `asImageSrc()`. | ||
*/ | ||
type AsImageSrcReturnType<Field extends ImageFieldImage> = | ||
Field extends ImageFieldImage<"empty"> ? null : string; | ||
|
||
/** | ||
* Returns the URL of an Image field with optional image transformations (via | ||
* Imgix URL parameters). | ||
* | ||
* @example | ||
* | ||
* ```ts | ||
* const src = asImageSrc(document.data.imageField, { sat: -100 }); | ||
* // => https://images.prismic.io/repo/image.png?sat=-100 | ||
* ``` | ||
* | ||
* @param field - Image field (or one of its responsive views) from which to get | ||
* an image URL. | ||
* @param params - An object of Imgix URL API parameters to transform the image. | ||
* | ||
* @returns The Image field's image URL with transformations applied (if given). | ||
* If the Image field is empty, `null` is returned. | ||
* @see Imgix URL parameters reference: https://docs.imgix.com/apis/rendering | ||
*/ | ||
export const asImageSrc = <Field extends ImageFieldImage>( | ||
field: Field, | ||
params: ImgixURLParams = {}, | ||
): AsImageSrcReturnType<Field> => { | ||
if (isImageThumbnailFilled(field)) { | ||
return buildURL(field.url, params) as AsImageSrcReturnType<Field>; | ||
} else { | ||
return null as AsImageSrcReturnType<Field>; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { ImageFieldImage } from "@prismicio/types"; | ||
import { | ||
buildURL, | ||
buildWidthSrcSet, | ||
BuildWidthSrcSetParams, | ||
} from "imgix-url-builder"; | ||
|
||
import { imageThumbnail as isImageThumbnailFilled } from "./isFilled"; | ||
|
||
/** | ||
* The return type of `asImageWidthSrcSet()`. | ||
*/ | ||
type AsImageWidthSrcSetReturnType<Field extends ImageFieldImage> = | ||
Field extends ImageFieldImage<"empty"> | ||
? null | ||
: { | ||
/** | ||
* The Image field's image URL with Imgix URL parameters (if given). | ||
*/ | ||
src: string; | ||
|
||
/** | ||
* A width-based `srcset` attribute value for the Image field's image | ||
* with Imgix URL parameters (if given). | ||
*/ | ||
srcset: string; | ||
}; | ||
angeloashmore marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Creates a width-based `srcset` from an Image field with optional image | ||
* transformations (via Imgix URL parameters). | ||
* | ||
* If the Image field contains responsive views, each responsive view is used as | ||
* a width in the resulting `srcset`. | ||
* | ||
* If a `widths` parameter is not given, the following widths will be used by | ||
* default: 640, 750, 828, 1080, 1200, 1920, 2048, 3840. | ||
* | ||
* @example | ||
* | ||
* ```ts | ||
* const srcset = asImageWidthSrcSet(document.data.imageField, { | ||
* widths: [400, 800, 1600], | ||
* sat: -100, | ||
* }); | ||
* // => { | ||
* // src: 'https://images.prismic.io/repo/image.png?sat=-100', | ||
* // srcset: 'https://images.prismic.io/repo/image.png?sat=-100&width=400 400w, ' + | ||
* // 'https://images.prismic.io/repo/image.png?sat=-100&width=800 800w,' + | ||
* // 'https://images.prismic.io/repo/image.png?sat=-100&width=1600 1600w' | ||
* // } | ||
* ``` | ||
* | ||
* @param field - Image field (or one of its responsive views) from which to get | ||
* an image URL. | ||
* @param params - An object of Imgix URL API parameters. The `widths` parameter | ||
* defines the resulting `srcset` widths. | ||
* | ||
* @returns A `srcset` attribute value for the Image field with Imgix URL | ||
* parameters (if given). If the Image field is empty, `null` is returned. | ||
* @see Imgix URL parameters reference: https://docs.imgix.com/apis/rendering | ||
*/ | ||
export const asImageWidthSrcSet = <Field extends ImageFieldImage>( | ||
field: Field, | ||
params: Omit<BuildWidthSrcSetParams, "widths"> & | ||
Partial<Pick<BuildWidthSrcSetParams, "widths">> = {}, | ||
): AsImageWidthSrcSetReturnType<Field> => { | ||
if (isImageThumbnailFilled(field)) { | ||
const { widths = [640, 828, 1200, 2048, 3840], ...urlParams } = params; | ||
const { | ||
url, | ||
dimensions, | ||
alt: _alt, | ||
copyright: _copyright, | ||
...responsiveViews | ||
} = field; | ||
|
||
// The Prismic Rest API will always return thumbnail values if | ||
// the base size is filled. | ||
const responsiveViewObjects: ImageFieldImage<"filled">[] = | ||
Object.values(responsiveViews); | ||
angeloashmore marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return { | ||
src: buildURL(url, urlParams), | ||
srcset: responsiveViewObjects.length | ||
? [ | ||
buildWidthSrcSet(url, { | ||
...urlParams, | ||
widths: [dimensions.width], | ||
}), | ||
...responsiveViewObjects.map((thumbnail) => { | ||
return buildWidthSrcSet(thumbnail.url, { | ||
...urlParams, | ||
widths: [thumbnail.dimensions.width], | ||
}); | ||
}), | ||
].join(", ") | ||
: buildWidthSrcSet(field.url, { | ||
...urlParams, | ||
widths, | ||
}), | ||
} as AsImageWidthSrcSetReturnType<Field>; | ||
} else { | ||
return null as AsImageWidthSrcSetReturnType<Field>; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { ImageField } from "@prismicio/types"; | ||
import test from "ava"; | ||
|
||
import { asImagePixelDensitySrcSet } from "../src"; | ||
|
||
test("returns an image field pixel-density-based srcset with [1, 2, 3] pxiel densities by default", (t) => { | ||
const field: ImageField = { | ||
url: "https://images.prismic.io/qwerty/image.png?auto=compress%2Cformat", | ||
alt: null, | ||
copyright: null, | ||
dimensions: { width: 400, height: 300 }, | ||
}; | ||
|
||
t.deepEqual(asImagePixelDensitySrcSet(field), { | ||
src: field.url, | ||
srcset: | ||
`${field.url}&dpr=1 1x, ` + | ||
`${field.url}&dpr=2 2x, ` + | ||
`${field.url}&dpr=3 3x`, | ||
}); | ||
}); | ||
|
||
test("supports custom pixel densities", (t) => { | ||
const field: ImageField = { | ||
url: "https://images.prismic.io/qwerty/image.png?auto=compress%2Cformat", | ||
alt: null, | ||
copyright: null, | ||
dimensions: { width: 400, height: 300 }, | ||
}; | ||
|
||
t.deepEqual( | ||
asImagePixelDensitySrcSet(field, { | ||
pixelDensities: [2, 4, 6], | ||
}), | ||
{ | ||
src: field.url, | ||
srcset: | ||
`${field.url}&dpr=2 2x, ` + | ||
`${field.url}&dpr=4 4x, ` + | ||
`${field.url}&dpr=6 6x`, | ||
}, | ||
); | ||
}); | ||
|
||
test("applies given Imgix URL parameters", (t) => { | ||
const field: ImageField = { | ||
url: "https://images.prismic.io/qwerty/image.png?auto=compress%2Cformat", | ||
alt: null, | ||
copyright: null, | ||
dimensions: { width: 400, height: 300 }, | ||
}; | ||
|
||
t.deepEqual( | ||
asImagePixelDensitySrcSet(field, { | ||
sat: 100, | ||
}), | ||
{ | ||
src: `${field.url}&sat=100`, | ||
srcset: | ||
`${field.url}&sat=100&dpr=1 1x, ` + | ||
`${field.url}&sat=100&dpr=2 2x, ` + | ||
`${field.url}&sat=100&dpr=3 3x`, | ||
}, | ||
); | ||
}); | ||
|
||
test("returns null when image field is empty", (t) => { | ||
const field: ImageField<null, "empty"> = {}; | ||
|
||
t.is(asImagePixelDensitySrcSet(field), null); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { ImageField } from "@prismicio/types"; | ||
import test from "ava"; | ||
|
||
import { asImageSrc } from "../src"; | ||
|
||
test("returns an image field URL", (t) => { | ||
const field: ImageField = { | ||
url: "https://images.prismic.io/qwerty/image.png?auto=compress%2Cformat", | ||
alt: null, | ||
copyright: null, | ||
dimensions: { width: 400, height: 300 }, | ||
}; | ||
|
||
t.is(asImageSrc(field), field.url); | ||
}); | ||
|
||
test("applies given Imgix URL parameters", (t) => { | ||
const field: ImageField = { | ||
url: "https://images.prismic.io/qwerty/image.png?auto=compress%2Cformat", | ||
alt: null, | ||
copyright: null, | ||
dimensions: { width: 400, height: 300 }, | ||
}; | ||
|
||
t.is(asImageSrc(field, { sat: 100 }), `${field.url}&sat=100`); | ||
}); | ||
|
||
test("returns null when image field is empty", (t) => { | ||
const field: ImageField<null, "empty"> = {}; | ||
|
||
t.is(asImageSrc(field), null); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side note but we should at some point update the other helpers to use those
isFilled()
functions too, great move!