Skip to content

Commit

Permalink
feat(contentful): add support image corner radius (#32333)
Browse files Browse the repository at this point in the history
closes #29784

Co-authored-by: axe312ger <opensource@axe312.dev>
  • Loading branch information
axe312ger and axe312ger committed Jul 15, 2021
1 parent 8838862 commit 848b56e
Show file tree
Hide file tree
Showing 3 changed files with 282 additions and 1 deletion.
Expand Up @@ -4,6 +4,56 @@ exports[`contentful extend node type createUrl allows you to create URls 1`] = `

exports[`contentful extend node type createUrl ignores options it doesn't understand 1`] = `"//images.contentful.com/dsf/bl.jpg?"`;

exports[`contentful extend node type generateImageSource default 1`] = `
Object {
"format": "webp",
"height": 210,
"src": "test.png?w=420&h=210&fm=webp",
"width": 420,
}
`;

exports[`contentful extend node type generateImageSource does not include corner by default 1`] = `
Object {
"format": "webp",
"height": 210,
"src": "test.png?w=420&h=210&fm=webp",
"width": 420,
}
`;

exports[`contentful extend node type generateImageSource supports corner radius 1`] = `
Object {
"format": "webp",
"height": 210,
"src": "test.png?w=420&h=210&fm=webp&r=10",
"width": 420,
}
`;

exports[`contentful extend node type generateImageSource transforms corner radius -1 to max 1`] = `
Object {
"format": "webp",
"height": 210,
"src": "test.png?w=420&h=210&fm=webp&r=max",
"width": 420,
}
`;

exports[`contentful extend node type resolveFixed does not include corner by default 1`] = `
Object {
"aspectRatio": 0.75,
"baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg",
"height": 533,
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400",
"srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400&h=533 1x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=600&h=800 1.5x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=800&h=1067 2x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1200&h=1600 3x",
"width": 400,
}
`;

exports[`contentful extend node type resolveFixed filters out sizes larger than the image's width 1`] = `
Object {
"aspectRatio": 0.75,
Expand Down Expand Up @@ -57,6 +107,49 @@ Object {
}
`;

exports[`contentful extend node type resolveFixed supports corner radius 1`] = `
Object {
"aspectRatio": 0.75,
"baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg",
"height": 533,
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400&r=10",
"srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400&h=533&r=10 1x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=600&h=800&r=10 1.5x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=800&h=1067&r=10 2x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1200&h=1600&r=10 3x",
"width": 400,
}
`;

exports[`contentful extend node type resolveFixed transforms corner radius -1 to max 1`] = `
Object {
"aspectRatio": 0.75,
"baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg",
"height": 533,
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400&r=max",
"srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400&h=533&r=max 1x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=600&h=800&r=max 1.5x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=800&h=1067&r=max 2x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1200&h=1600&r=max 3x",
"width": 400,
}
`;

exports[`contentful extend node type resolveFluid does not include corner by default 1`] = `
Object {
"aspectRatio": 0.75,
"baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg",
"sizes": "(max-width: 800px) 100vw, 800px",
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=800",
"srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=200&h=267 200w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400&h=533 400w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=800&h=1067 800w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1200&h=1600 1200w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1600&h=2133 1600w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=2400&h=3200 2400w",
}
`;

exports[`contentful extend node type resolveFluid filters out sizes larger than the image's width 1`] = `
Object {
"aspectRatio": 0.75,
Expand Down Expand Up @@ -129,6 +222,46 @@ Object {
}
`;

exports[`contentful extend node type resolveFluid supports corner radius 1`] = `
Object {
"aspectRatio": 0.75,
"baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg",
"sizes": "(max-width: 800px) 100vw, 800px",
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=800&r=10",
"srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=200&h=267&r=10 200w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400&h=533&r=10 400w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=800&h=1067&r=10 800w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1200&h=1600&r=10 1200w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1600&h=2133&r=10 1600w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=2400&h=3200&r=10 2400w",
}
`;

exports[`contentful extend node type resolveFluid transforms corner radius -1 to max 1`] = `
Object {
"aspectRatio": 0.75,
"baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg",
"sizes": "(max-width: 800px) 100vw, 800px",
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=800&r=max",
"srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=200&h=267&r=max 200w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400&h=533&r=max 400w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=800&h=1067&r=max 800w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1200&h=1600&r=max 1200w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1600&h=2133&r=max 1600w,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=2400&h=3200&r=max 2400w",
}
`;

exports[`contentful extend node type resolveResize does not include corner by default 1`] = `
Object {
"aspectRatio": 0.75,
"baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg",
"height": 533,
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400",
"width": 400,
}
`;

exports[`contentful extend node type resolveResize generates resized images given a certain height 1`] = `
Object {
"aspectRatio": 0.75,
Expand Down Expand Up @@ -168,3 +301,23 @@ Object {
"width": 450,
}
`;

exports[`contentful extend node type resolveResize supports corner radius 1`] = `
Object {
"aspectRatio": 0.75,
"baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg",
"height": 533,
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400&r=10",
"width": 400,
}
`;

exports[`contentful extend node type resolveResize transforms corner radius -1 to max 1`] = `
Object {
"aspectRatio": 0.75,
"baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg",
"height": 533,
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=400&r=max",
"width": 400,
}
`;
Expand Up @@ -3,6 +3,7 @@ const {
resolveFixed,
resolveFluid,
resolveResize,
generateImageSource,
} = require(`../extend-node-type`)

describe(`contentful extend node type`, () => {
Expand Down Expand Up @@ -40,6 +41,35 @@ describe(`contentful extend node type`, () => {
file: null,
}

describe(`generateImageSource`, () => {
it(`default`, () => {
const resp = generateImageSource(`test.png`, 420, 210, `webp`, null, {})
expect(resp.src).toContain(`w=420`)
expect(resp.src).toContain(`h=210`)
expect(resp.src).toContain(`fm=webp`)
expect(resp).toMatchSnapshot()
})
it(`supports corner radius`, async () => {
const resp = generateImageSource(`test.png`, 420, 210, `webp`, null, {
cornerRadius: 10,
})
expect(resp.src).toContain(`r=10`)
expect(resp).toMatchSnapshot()
})
it(`transforms corner radius -1 to max`, async () => {
const resp = generateImageSource(`test.png`, 420, 210, `webp`, null, {
cornerRadius: -1,
})
expect(resp.src).toContain(`r=max`)
expect(resp).toMatchSnapshot()
})
it(`does not include corner by default`, async () => {
const resp = generateImageSource(`test.png`, 420, 210, `webp`, null, {})
expect(resp.src).not.toContain(`r=`)
expect(resp).toMatchSnapshot()
})
})

describe(`resolveFixed`, () => {
it(`generates responsive resolution data for images using width option`, async () => {
const resp = await resolveFixed(image, { width: 400 })
Expand Down Expand Up @@ -109,6 +139,25 @@ describe(`contentful extend node type`, () => {
expect(resp.srcSet.split(`,`).length).toBe(1)
expect(resp).toMatchSnapshot()
})
it(`supports corner radius`, async () => {
const resp = await resolveFixed(image, {
cornerRadius: 10,
})
expect(resp.srcSet).toContain(`r=10`)
expect(resp).toMatchSnapshot()
})
it(`transforms corner radius -1 to max`, async () => {
const resp = await resolveFixed(image, {
cornerRadius: -1,
})
expect(resp.srcSet).toContain(`r=max`)
expect(resp).toMatchSnapshot()
})
it(`does not include corner by default`, async () => {
const resp = await resolveFixed(image, {})
expect(resp.srcSet).not.toContain(`r=`)
expect(resp).toMatchSnapshot()
})
})

describe(`resolveFluid`, () => {
Expand Down Expand Up @@ -150,6 +199,25 @@ describe(`contentful extend node type`, () => {
expect(resp.srcSet.split(`,`).length).toBe(3)
expect(resp).toMatchSnapshot()
})
it(`supports corner radius`, async () => {
const resp = await resolveFluid(image, {
cornerRadius: 10,
})
expect(resp.srcSet).toContain(`r=10`)
expect(resp).toMatchSnapshot()
})
it(`transforms corner radius -1 to max`, async () => {
const resp = await resolveFluid(image, {
cornerRadius: -1,
})
expect(resp.srcSet).toContain(`r=max`)
expect(resp).toMatchSnapshot()
})
it(`does not include corner by default`, async () => {
const resp = await resolveFluid(image, {})
expect(resp.srcSet).not.toContain(`r=`)
expect(resp).toMatchSnapshot()
})
})

describe(`resolveResize`, () => {
Expand Down Expand Up @@ -178,5 +246,24 @@ describe(`contentful extend node type`, () => {
const resp = await resolveResize(nullFileImage, { width: 400 })
expect(resp).toBe(null)
})
it(`supports corner radius`, async () => {
const resp = await resolveResize(image, {
cornerRadius: 10,
})
expect(resp.src).toContain(`r=10`)
expect(resp).toMatchSnapshot()
})
it(`transforms corner radius -1 to max`, async () => {
const resp = await resolveResize(image, {
cornerRadius: -1,
})
expect(resp.src).toContain(`r=max`)
expect(resp).toMatchSnapshot()
})
it(`does not include corner by default`, async () => {
const resp = await resolveResize(image, {})
expect(resp.src).not.toContain(`r=`)
expect(resp).toMatchSnapshot()
})
})
})
43 changes: 42 additions & 1 deletion packages/gatsby-source-contentful/src/extend-node-type.js
Expand Up @@ -166,6 +166,10 @@ const getBasicImageProps = (image, args) => {
}

const createUrl = (imgUrl, options = {}) => {
// If radius is -1, we need to pass `max` to the API
const cornerRadius =
options.cornerRadius === -1 ? `max` : options.cornerRadius

// Convert to Contentful names and filter out undefined/null values.
const urlArgs = {
w: options.width || undefined,
Expand All @@ -179,6 +183,7 @@ const createUrl = (imgUrl, options = {}) => {
fit: options.resizingBehavior || undefined,
f: options.cropFocus || undefined,
bg: options.background || undefined,
r: cornerRadius || undefined,
}

// Note: qs will ignore keys that are `undefined`. `qs.stringify({a: undefined, b: null, c: 1})` => `b=&c=1`
Expand All @@ -192,7 +197,14 @@ const generateImageSource = (
height,
toFormat,
_fit, // We use resizingBehavior instead
{ jpegProgressive, quality, cropFocus, backgroundColor, resizingBehavior }
{
jpegProgressive,
quality,
cropFocus,
backgroundColor,
resizingBehavior,
cornerRadius,
}
) => {
// Ensure we stay within Contentfuls Image API limits
if (width > CONTENTFUL_IMAGE_MAX_SIZE) {
Expand Down Expand Up @@ -221,6 +233,7 @@ const generateImageSource = (
quality,
jpegProgressive,
cropFocus,
cornerRadius,
})
return { width, height, format: toFormat, src }
}
Expand Down Expand Up @@ -550,6 +563,13 @@ const fixedNodeType = ({ name, getTracedSVG, reporter }) => {
type: ImageCropFocusType,
defaultValue: null,
},
cornerRadius: {
type: GraphQLInt,
defaultValue: 0,
description: stripIndent`
Desired corner radius in pixels. Results in an image with rounded corners.
Pass \`-1\` for a full circle/ellipse.`,
},
background: {
type: GraphQLString,
defaultValue: null,
Expand Down Expand Up @@ -644,6 +664,13 @@ const fluidNodeType = ({ name, getTracedSVG, reporter }) => {
type: ImageCropFocusType,
defaultValue: null,
},
cornerRadius: {
type: GraphQLInt,
defaultValue: 0,
description: stripIndent`
Desired corner radius in pixels. Results in an image with rounded corners.
Pass \`-1\` for a full circle/ellipse.`,
},
background: {
type: GraphQLString,
defaultValue: null,
Expand Down Expand Up @@ -815,6 +842,13 @@ exports.extendNodeType = ({ type, store, reporter }) => {
cropFocus: {
type: ImageCropFocusType,
},
cornerRadius: {
type: GraphQLInt,
defaultValue: 0,
description: stripIndent`
Desired corner radius in pixels. Results in an image with rounded corners.
Pass \`-1\` for a full circle/ellipse.`,
},
quality: {
type: GraphQLInt,
defaultValue: 50,
Expand Down Expand Up @@ -910,6 +944,13 @@ exports.extendNodeType = ({ type, store, reporter }) => {
type: GraphQLString,
defaultValue: null,
},
cornerRadius: {
type: GraphQLInt,
defaultValue: 0,
description: stripIndent`
Desired corner radius in pixels. Results in an image with rounded corners.
Pass \`-1\` for a full circle/ellipse.`,
},
},
resolve(image, options) {
return resolveResize(image, options)
Expand Down

0 comments on commit 848b56e

Please sign in to comment.