Skip to content

Commit 2ad35eb

Browse files
committed
add jsdocs and add test for query parameters
1 parent b7a5758 commit 2ad35eb

File tree

2 files changed

+62
-8
lines changed

2 files changed

+62
-8
lines changed

src/getResponsiveImageAttributes.ts

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,50 @@ const DEFAULT_DEVICE_BREAKPOINTS = [640, 750, 828, 1080, 1200, 1920, 2048, 3840]
66
const DEFAULT_IMAGE_BREAKPOINTS = [16, 32, 48, 64, 96, 128, 256, 384] as const
77

88
export interface GetImageAttributesOptions extends SrcOptions {
9-
width?: number // explicit rendered width
10-
sizes?: string // the HTML sizes value
11-
deviceBreakpoints?: number[] // override default device break‑points
12-
imageBreakpoints?: number[] // override tiny image break‑points
9+
/**
10+
* The intended display width (in pixels) of the image on screen.
11+
* Used for calculating `srcSet` with a pixel-density (DPR) strategy.
12+
* If omitted, a width-based strategy using breakpoints will be applied.
13+
*/
14+
width?: number
15+
16+
/**
17+
* The `sizes` attribute for the image element.
18+
* Typically used to indicate how the image will scale across different viewport sizes (e.g., "100vw").
19+
* Presence of `sizes` triggers a width-based `srcSet` strategy.
20+
*/
21+
sizes?: string
22+
23+
/**
24+
* An optional custom list of device width breakpoints (in pixels).
25+
* If not specified, defaults to `[640, 750, 828, 1080, 1200, 1920, 2048, 3840]`.
26+
* Recommended to align with your target audience's common screen widths.
27+
*/
28+
deviceBreakpoints?: number[]
29+
30+
/**
31+
* An optional list of custom image breakpoints (in pixels).
32+
* These are merged with the device breakpoints to compute the final list of candidate widths.
33+
* Defaults to `[16, 32, 48, 64, 96, 128, 256, 384]`.
34+
*/
35+
imageBreakpoints?: number[]
1336
}
1437

38+
/**
39+
* Resulting set of attributes suitable for an HTML `<img>` element.
40+
* Useful for enabling responsive image loading.
41+
*/
1542
export interface ResponsiveImageAttributes {
1643
src: string
1744
srcSet?: string
1845
sizes?: string
1946
width?: number
2047
}
2148

49+
/**
50+
* Generates a responsive image URL, `srcSet`, and `sizes` attributes
51+
* based on the input options such as `width`, `sizes`, and breakpoints.
52+
*/
2253
export function getResponsiveImageAttributes(
2354
opts: GetImageAttributesOptions
2455
): ResponsiveImageAttributes {
@@ -80,7 +111,7 @@ function computeCandidateWidths(params: {
80111
}): { candidates: number[]; descriptorKind: 'w' | 'x' } {
81112
const { allBreakpoints, deviceBreakpoints, explicitWidth, sizesAttr } = params
82113

83-
/* --- sizes attribute present ----------------------------------- */
114+
// Strategy 1: Width-based srcSet (`w`) using viewport `vw` hints
84115
if (sizesAttr) {
85116
const vwTokens = sizesAttr.match(/(^|\s)(1?\d{1,2})vw/g) || []
86117
const vwPercents = vwTokens.map((t) => parseInt(t, 10))
@@ -93,16 +124,17 @@ function computeCandidateWidths(params: {
93124
descriptorKind: 'w',
94125
}
95126
}
96-
/* no vw → give the full break‑point list */
127+
128+
// No usable `vw` found: fallback to all breakpoints
97129
return { candidates: allBreakpoints, descriptorKind: 'w' }
98130
}
99131

100-
/* --- no sizes attr ------------------------------------------------ */
132+
// Strategy 2: Fallback using explicit image width using device breakpoints
101133
if (typeof explicitWidth !== 'number') {
102134
return { candidates: deviceBreakpoints, descriptorKind: 'w' }
103135
}
104136

105-
/* DPR strategy: 1× & 2× nearest break‑points */
137+
// Strategy 3: Use 1x and 2x nearest breakpoints for `x` descriptor
106138
const nearest = (t: number) =>
107139
allBreakpoints.find((n) => n >= t) || allBreakpoints[allBreakpoints.length - 1]
108140

test/getResponsiveImageAttributes.test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,26 @@ describe.only('getResponsiveImageAttributes', () => {
120120
sizes: "(min-width: 800px) 33vw, 100vw"
121121
});
122122
});
123+
124+
it("Using queryParameters and transformationPosition", () => {
125+
const out = getResponsiveImageAttributes({
126+
src: 'sample.jpg',
127+
urlEndpoint: 'https://ik.imagekit.io/demo',
128+
width: 450,
129+
transformation: [
130+
{ height: 300 },
131+
{ aiRemoveBackground: true }
132+
],
133+
queryParameters: {
134+
key: "value"
135+
},
136+
transformationPosition: "path"
137+
});
138+
// The function should respect the transformation position and query parameters.
139+
expect(out).to.deep.equal({
140+
src: "https://ik.imagekit.io/demo/tr:h-300:e-bgremove:w-1080,c-at_max/sample.jpg?key=value",
141+
srcSet: "https://ik.imagekit.io/demo/tr:h-300:e-bgremove:w-640,c-at_max/sample.jpg?key=value 1x, https://ik.imagekit.io/demo/tr:h-300:e-bgremove:w-1080,c-at_max/sample.jpg?key=value 2x",
142+
width: 450
143+
});
144+
})
123145
});

0 commit comments

Comments
 (0)