@nonphoto/sanity-image 0.0.6 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,14 +1,30 @@
1
- import { SanityImageSource, SanityClientLike, SanityProjectDetails, SanityModernClientLike } from '@sanity/image-url/lib/types/types.js';
1
+ import { SanityAsset, SanityImageDimensions, SanityImageCrop, SanityImageHotspot, SanityClientLike, SanityProjectDetails, SanityModernClientLike } from '@sanity/image-url/lib/types/types.js';
2
2
 
3
+ type SanityAssetWithMetadata = SanityAsset & {
4
+ metadata?: {
5
+ lqip?: string;
6
+ dimensions?: SanityImageDimensions;
7
+ };
8
+ };
9
+ interface SanityImageObjectWithMetadata {
10
+ asset: SanityAssetWithMetadata;
11
+ crop?: SanityImageCrop;
12
+ hotspot?: SanityImageHotspot;
13
+ }
14
+ type Size = {
15
+ width: number;
16
+ height: number;
17
+ };
3
18
  declare const defaultWidths: number[];
4
19
  declare const lowResWidth = 24;
5
20
  declare const defaultMetaImageWidth = 1200;
6
21
  declare const defaultQuality = 90;
7
- declare function imageProps({ image, client, widths, quality, }: {
8
- image: SanityImageSource;
22
+ declare function imageProps({ image, client, widths, quality, aspectRatio, }: {
23
+ image: SanityImageObjectWithMetadata;
9
24
  client: SanityClientLike | SanityProjectDetails | SanityModernClientLike;
10
25
  widths: number[];
11
26
  quality?: number;
27
+ aspectRatio?: number;
12
28
  }): {
13
29
  src: string;
14
30
  srcset: string;
@@ -16,10 +32,10 @@ declare function imageProps({ image, client, widths, quality, }: {
16
32
  naturalHeight?: number;
17
33
  };
18
34
  declare function metaImageUrl({ image, client, width, quality, }: {
19
- image: SanityImageSource;
35
+ image: SanityImageObjectWithMetadata;
20
36
  client: SanityClientLike | SanityProjectDetails | SanityModernClientLike;
21
37
  width: number;
22
38
  quality?: number;
23
39
  }): string;
24
40
 
25
- export { defaultMetaImageWidth, defaultQuality, defaultWidths, imageProps, lowResWidth, metaImageUrl };
41
+ export { type SanityAssetWithMetadata, type SanityImageObjectWithMetadata, type Size, defaultMetaImageWidth, defaultQuality, defaultWidths, imageProps, lowResWidth, metaImageUrl };
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
- import imageUrlBuilder from '@sanity/image-url';
2
-
3
1
  // src/index.ts
2
+ import imageUrlBuilder from "@sanity/image-url";
4
3
  var defaultWidths = [
5
4
  6016,
6
5
  // 6K
@@ -36,32 +35,49 @@ var defaultWidths = [
36
35
  var lowResWidth = 24;
37
36
  var defaultMetaImageWidth = 1200;
38
37
  var defaultQuality = 90;
39
- function cropAxis(length, insetStart, insetEnd) {
40
- return length ? length * (1 - (insetStart ?? 0) - (insetEnd ?? 0)) : void 0;
38
+ var fitComparators = {
39
+ cover: Math.max,
40
+ contain: Math.min,
41
+ mean: (a, b) => (a + b) / 2
42
+ };
43
+ function fit(containee, container, mode) {
44
+ const sx = container.width / containee.width;
45
+ const sy = container.height / containee.height;
46
+ const s = fitComparators[mode](sx, sy);
47
+ return {
48
+ width: containee.width * s,
49
+ height: containee.height * s
50
+ };
51
+ }
52
+ function buildAspectRatio(builder, width, aspectRatio) {
53
+ if (aspectRatio) {
54
+ return builder.width(width).height(Math.round(width * aspectRatio));
55
+ } else {
56
+ return builder.width(width);
57
+ }
41
58
  }
42
59
  function imageProps({
43
60
  image,
44
61
  client,
45
62
  widths,
46
- quality = defaultQuality
63
+ quality = defaultQuality,
64
+ aspectRatio
47
65
  }) {
48
66
  const sortedWidths = Array.from(widths).sort((a, b) => a - b);
49
67
  const builder = imageUrlBuilder(client).image(image).quality(quality).auto("format");
50
- const metadata = typeof image === "object" && "asset" in image ? image.asset.metadata : void 0;
51
- const crop = typeof image === "object" && "crop" in image ? image.crop : void 0;
68
+ const metadata = image.asset.metadata;
69
+ const cropSize = metadata?.dimensions ? image.crop ? {
70
+ width: metadata.dimensions.width - image.crop.left - image.crop.right,
71
+ height: metadata.dimensions.height - image.crop.top - image.crop.bottom
72
+ } : metadata.dimensions : void 0;
73
+ const naturalSize = cropSize ? aspectRatio ? fit({ width: 1, height: aspectRatio }, cropSize, "contain") : cropSize : void 0;
52
74
  return {
53
- src: metadata?.lqip ?? builder.width(lowResWidth).url().toString(),
54
- srcset: sortedWidths.map((width) => `${builder.width(width).url()} ${width}w`).join(","),
55
- naturalWidth: cropAxis(
56
- metadata?.dimensions?.width,
57
- crop?.left,
58
- crop?.right
59
- ),
60
- naturalHeight: cropAxis(
61
- metadata?.dimensions?.height,
62
- crop?.top,
63
- crop?.bottom
64
- )
75
+ src: metadata?.lqip ?? buildAspectRatio(builder, lowResWidth, aspectRatio).url(),
76
+ srcset: sortedWidths.map(
77
+ (width) => `${buildAspectRatio(builder, width, aspectRatio).url()} ${width}w`
78
+ ).join(","),
79
+ naturalWidth: naturalSize?.width,
80
+ naturalHeight: naturalSize?.height
65
81
  };
66
82
  }
67
83
  function metaImageUrl({
@@ -72,5 +88,11 @@ function metaImageUrl({
72
88
  }) {
73
89
  return imageUrlBuilder(client).image(image).quality(quality).auto("format").width(width).url();
74
90
  }
75
-
76
- export { defaultMetaImageWidth, defaultQuality, defaultWidths, imageProps, lowResWidth, metaImageUrl };
91
+ export {
92
+ defaultMetaImageWidth,
93
+ defaultQuality,
94
+ defaultWidths,
95
+ imageProps,
96
+ lowResWidth,
97
+ metaImageUrl
98
+ };
package/package.json CHANGED
@@ -1,54 +1,48 @@
1
1
  {
2
2
  "name": "@nonphoto/sanity-image",
3
- "version": "0.0.6",
3
+ "version": "0.1.0",
4
4
  "type": "module",
5
- "files": [
6
- "dist"
7
- ],
8
- "private": false,
9
5
  "sideEffects": false,
10
- "devDependencies": {
11
- "@changesets/cli": "2.26.1",
12
- "@types/node": "18.14.6",
13
- "prettier": "2.8.7",
14
- "tsup": "6.7.0",
15
- "tsup-preset-solid": "0.1.8",
16
- "typescript": "^4.9.4",
17
- "vite": "^4.0.4",
18
- "vitest": "0.29.8"
19
- },
20
- "dependencies": {
21
- "@sanity/image-url": "1.0.2"
22
- },
23
- "packageManager": "pnpm@7.29.1",
24
6
  "publishConfig": {
25
7
  "access": "public"
26
8
  },
27
- "browser": {},
28
9
  "exports": {
29
- "development": {
10
+ ".": {
30
11
  "import": {
31
12
  "types": "./dist/index.d.ts",
32
- "default": "./dist/dev.js"
33
- },
34
- "require": "./dist/dev.cjs"
13
+ "default": "./dist/index.js"
14
+ }
35
15
  },
36
- "import": {
37
- "types": "./dist/index.d.ts",
38
- "default": "./dist/index.js"
39
- },
40
- "require": "./dist/index.cjs"
16
+ "./src/*": "./src/*"
41
17
  },
42
- "typesVersions": {},
43
- "main": "./dist/index.cjs",
18
+ "files": [
19
+ "./dist/*",
20
+ "./src/*"
21
+ ],
44
22
  "module": "./dist/index.js",
45
23
  "types": "./dist/index.d.ts",
46
24
  "scripts": {
47
- "dev": "vite serve dev",
48
- "build": "tsup",
49
- "test": "vitest",
50
- "format": "prettier --ignore-path .gitignore -w \"src/**/*.{js,ts,json,css,tsx,jsx}\" \"dev/**/*.{js,ts,json,css,tsx,jsx}\"",
51
- "update-deps": "pnpm up -Li",
52
- "typecheck": "tsc --noEmit"
25
+ "prepare": "pnpm build",
26
+ "build": "tsup ./src/index.ts --dts --format esm --clean",
27
+ "release": "semantic-release"
28
+ },
29
+ "keywords": [
30
+ "spring",
31
+ "physics",
32
+ "animation"
33
+ ],
34
+ "author": "Jonas Luebbers <jonas@jonasluebbers.com> (https://www.jonasluebbers.com)",
35
+ "license": "MIT",
36
+ "devDependencies": {
37
+ "semantic-release": "24.2.3",
38
+ "tsup": "8.4.0",
39
+ "typescript": "5.8.2"
40
+ },
41
+ "engines": {
42
+ "node": ">=20",
43
+ "pnpm": ">=9"
44
+ },
45
+ "dependencies": {
46
+ "@sanity/image-url": "1.0.2"
53
47
  }
54
- }
48
+ }
package/src/index.ts ADDED
@@ -0,0 +1,164 @@
1
+ import imageUrlBuilder from "@sanity/image-url";
2
+ import { ImageUrlBuilder } from "@sanity/image-url/lib/types/builder";
3
+ import type {
4
+ SanityAsset,
5
+ SanityClientLike,
6
+ SanityImageCrop,
7
+ SanityImageDimensions,
8
+ SanityImageHotspot,
9
+ SanityModernClientLike,
10
+ SanityProjectDetails,
11
+ } from "@sanity/image-url/lib/types/types.js";
12
+
13
+ export type SanityAssetWithMetadata = SanityAsset & {
14
+ metadata?: {
15
+ lqip?: string;
16
+ dimensions?: SanityImageDimensions;
17
+ };
18
+ };
19
+
20
+ export interface SanityImageObjectWithMetadata {
21
+ asset: SanityAssetWithMetadata;
22
+ crop?: SanityImageCrop;
23
+ hotspot?: SanityImageHotspot;
24
+ }
25
+
26
+ export type Size = {
27
+ width: number;
28
+ height: number;
29
+ };
30
+
31
+ export const defaultWidths = [
32
+ 6016, // 6K
33
+ 5120, // 5K
34
+ 4480, // 4.5K
35
+ 3840, // 4K
36
+ 3200, // QHD+
37
+ 2560, // WQXGA
38
+ 2048, // QXGA
39
+ 1920, // 1080p
40
+ 1668, // iPad
41
+ 1280, // 720p
42
+ 1080, // iPhone 6-8 Plus
43
+ 960,
44
+ 720, // iPhone 6-8
45
+ 640, // 480p
46
+ 480,
47
+ 360,
48
+ 240,
49
+ ];
50
+
51
+ export const lowResWidth = 24;
52
+
53
+ export const defaultMetaImageWidth = 1200;
54
+
55
+ export const defaultQuality = 90;
56
+
57
+ const fitComparators = {
58
+ cover: Math.max,
59
+ contain: Math.min,
60
+ mean: (a: number, b: number) => (a + b) / 2,
61
+ };
62
+
63
+ function fit(
64
+ containee: Size,
65
+ container: Size,
66
+ mode: keyof typeof fitComparators
67
+ ) {
68
+ const sx = container.width / containee.width;
69
+ const sy = container.height / containee.height;
70
+ const s = fitComparators[mode](sx, sy);
71
+ return {
72
+ width: containee.width * s,
73
+ height: containee.height * s,
74
+ };
75
+ }
76
+
77
+ function buildAspectRatio(
78
+ builder: ImageUrlBuilder,
79
+ width: number,
80
+ aspectRatio?: number
81
+ ) {
82
+ if (aspectRatio) {
83
+ return builder.width(width).height(Math.round(width * aspectRatio));
84
+ } else {
85
+ return builder.width(width);
86
+ }
87
+ }
88
+
89
+ export function imageProps({
90
+ image,
91
+ client,
92
+ widths,
93
+ quality = defaultQuality,
94
+ aspectRatio,
95
+ }: {
96
+ image: SanityImageObjectWithMetadata;
97
+ client: SanityClientLike | SanityProjectDetails | SanityModernClientLike;
98
+ widths: number[];
99
+ quality?: number;
100
+ aspectRatio?: number;
101
+ }): {
102
+ src: string;
103
+ srcset: string;
104
+ naturalWidth?: number;
105
+ naturalHeight?: number;
106
+ } {
107
+ const sortedWidths = Array.from(widths).sort((a, b) => a - b);
108
+
109
+ const builder = imageUrlBuilder(client)
110
+ .image(image)
111
+ .quality(quality)
112
+ .auto("format");
113
+
114
+ const metadata = image.asset.metadata;
115
+
116
+ const cropSize = metadata?.dimensions
117
+ ? image.crop
118
+ ? {
119
+ width: metadata.dimensions.width - image.crop.left - image.crop.right,
120
+ height:
121
+ metadata.dimensions.height - image.crop.top - image.crop.bottom,
122
+ }
123
+ : metadata.dimensions
124
+ : undefined;
125
+
126
+ const naturalSize = cropSize
127
+ ? aspectRatio
128
+ ? fit({ width: 1, height: aspectRatio }, cropSize, "contain")
129
+ : cropSize
130
+ : undefined;
131
+
132
+ return {
133
+ src:
134
+ metadata?.lqip ??
135
+ buildAspectRatio(builder, lowResWidth, aspectRatio).url(),
136
+ srcset: sortedWidths
137
+ .map(
138
+ (width) =>
139
+ `${buildAspectRatio(builder, width, aspectRatio).url()} ${width}w`
140
+ )
141
+ .join(","),
142
+ naturalWidth: naturalSize?.width,
143
+ naturalHeight: naturalSize?.height,
144
+ };
145
+ }
146
+
147
+ export function metaImageUrl({
148
+ image,
149
+ client,
150
+ width = defaultMetaImageWidth,
151
+ quality = defaultQuality,
152
+ }: {
153
+ image: SanityImageObjectWithMetadata;
154
+ client: SanityClientLike | SanityProjectDetails | SanityModernClientLike;
155
+ width: number;
156
+ quality?: number;
157
+ }) {
158
+ return imageUrlBuilder(client)
159
+ .image(image)
160
+ .quality(quality)
161
+ .auto("format")
162
+ .width(width)
163
+ .url();
164
+ }
package/dist/dev.cjs DELETED
@@ -1,83 +0,0 @@
1
- 'use strict';
2
-
3
- var imageUrlBuilder = require('@sanity/image-url');
4
-
5
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
-
7
- var imageUrlBuilder__default = /*#__PURE__*/_interopDefault(imageUrlBuilder);
8
-
9
- // src/index.ts
10
- exports.defaultWidths = [
11
- 6016,
12
- // 6K
13
- 5120,
14
- // 5K
15
- 4480,
16
- // 4.5K
17
- 3840,
18
- // 4K
19
- 3200,
20
- // QHD+
21
- 2560,
22
- // WQXGA
23
- 2048,
24
- // QXGA
25
- 1920,
26
- // 1080p
27
- 1668,
28
- // iPad
29
- 1280,
30
- // 720p
31
- 1080,
32
- // iPhone 6-8 Plus
33
- 960,
34
- 720,
35
- // iPhone 6-8
36
- 640,
37
- // 480p
38
- 480,
39
- 360,
40
- 240
41
- ];
42
- exports.lowResWidth = 24;
43
- exports.defaultMetaImageWidth = 1200;
44
- exports.defaultQuality = 90;
45
- function cropAxis(length, insetStart, insetEnd) {
46
- return length ? length * (1 - (insetStart ?? 0) - (insetEnd ?? 0)) : void 0;
47
- }
48
- function imageProps({
49
- image,
50
- client,
51
- widths,
52
- quality = exports.defaultQuality
53
- }) {
54
- const sortedWidths = Array.from(widths).sort((a, b) => a - b);
55
- const builder = imageUrlBuilder__default.default(client).image(image).quality(quality).auto("format");
56
- const metadata = typeof image === "object" && "asset" in image ? image.asset.metadata : void 0;
57
- const crop = typeof image === "object" && "crop" in image ? image.crop : void 0;
58
- return {
59
- src: metadata?.lqip ?? builder.width(exports.lowResWidth).url().toString(),
60
- srcset: sortedWidths.map((width) => `${builder.width(width).url()} ${width}w`).join(","),
61
- naturalWidth: cropAxis(
62
- metadata?.dimensions?.width,
63
- crop?.left,
64
- crop?.right
65
- ),
66
- naturalHeight: cropAxis(
67
- metadata?.dimensions?.height,
68
- crop?.top,
69
- crop?.bottom
70
- )
71
- };
72
- }
73
- function metaImageUrl({
74
- image,
75
- client,
76
- width = exports.defaultMetaImageWidth,
77
- quality = exports.defaultQuality
78
- }) {
79
- return imageUrlBuilder__default.default(client).image(image).quality(quality).auto("format").width(width).url();
80
- }
81
-
82
- exports.imageProps = imageProps;
83
- exports.metaImageUrl = metaImageUrl;
package/dist/dev.js DELETED
@@ -1,76 +0,0 @@
1
- import imageUrlBuilder from '@sanity/image-url';
2
-
3
- // src/index.ts
4
- var defaultWidths = [
5
- 6016,
6
- // 6K
7
- 5120,
8
- // 5K
9
- 4480,
10
- // 4.5K
11
- 3840,
12
- // 4K
13
- 3200,
14
- // QHD+
15
- 2560,
16
- // WQXGA
17
- 2048,
18
- // QXGA
19
- 1920,
20
- // 1080p
21
- 1668,
22
- // iPad
23
- 1280,
24
- // 720p
25
- 1080,
26
- // iPhone 6-8 Plus
27
- 960,
28
- 720,
29
- // iPhone 6-8
30
- 640,
31
- // 480p
32
- 480,
33
- 360,
34
- 240
35
- ];
36
- var lowResWidth = 24;
37
- var defaultMetaImageWidth = 1200;
38
- var defaultQuality = 90;
39
- function cropAxis(length, insetStart, insetEnd) {
40
- return length ? length * (1 - (insetStart ?? 0) - (insetEnd ?? 0)) : void 0;
41
- }
42
- function imageProps({
43
- image,
44
- client,
45
- widths,
46
- quality = defaultQuality
47
- }) {
48
- const sortedWidths = Array.from(widths).sort((a, b) => a - b);
49
- const builder = imageUrlBuilder(client).image(image).quality(quality).auto("format");
50
- const metadata = typeof image === "object" && "asset" in image ? image.asset.metadata : void 0;
51
- const crop = typeof image === "object" && "crop" in image ? image.crop : void 0;
52
- return {
53
- src: metadata?.lqip ?? builder.width(lowResWidth).url().toString(),
54
- srcset: sortedWidths.map((width) => `${builder.width(width).url()} ${width}w`).join(","),
55
- naturalWidth: cropAxis(
56
- metadata?.dimensions?.width,
57
- crop?.left,
58
- crop?.right
59
- ),
60
- naturalHeight: cropAxis(
61
- metadata?.dimensions?.height,
62
- crop?.top,
63
- crop?.bottom
64
- )
65
- };
66
- }
67
- function metaImageUrl({
68
- image,
69
- client,
70
- width = defaultMetaImageWidth,
71
- quality = defaultQuality
72
- }) {
73
- return imageUrlBuilder(client).image(image).quality(quality).auto("format").width(width).url();
74
- }
75
-
76
- export { defaultMetaImageWidth, defaultQuality, defaultWidths, imageProps, lowResWidth, metaImageUrl };
package/dist/index.cjs DELETED
@@ -1,83 +0,0 @@
1
- 'use strict';
2
-
3
- var imageUrlBuilder = require('@sanity/image-url');
4
-
5
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
-
7
- var imageUrlBuilder__default = /*#__PURE__*/_interopDefault(imageUrlBuilder);
8
-
9
- // src/index.ts
10
- exports.defaultWidths = [
11
- 6016,
12
- // 6K
13
- 5120,
14
- // 5K
15
- 4480,
16
- // 4.5K
17
- 3840,
18
- // 4K
19
- 3200,
20
- // QHD+
21
- 2560,
22
- // WQXGA
23
- 2048,
24
- // QXGA
25
- 1920,
26
- // 1080p
27
- 1668,
28
- // iPad
29
- 1280,
30
- // 720p
31
- 1080,
32
- // iPhone 6-8 Plus
33
- 960,
34
- 720,
35
- // iPhone 6-8
36
- 640,
37
- // 480p
38
- 480,
39
- 360,
40
- 240
41
- ];
42
- exports.lowResWidth = 24;
43
- exports.defaultMetaImageWidth = 1200;
44
- exports.defaultQuality = 90;
45
- function cropAxis(length, insetStart, insetEnd) {
46
- return length ? length * (1 - (insetStart ?? 0) - (insetEnd ?? 0)) : void 0;
47
- }
48
- function imageProps({
49
- image,
50
- client,
51
- widths,
52
- quality = exports.defaultQuality
53
- }) {
54
- const sortedWidths = Array.from(widths).sort((a, b) => a - b);
55
- const builder = imageUrlBuilder__default.default(client).image(image).quality(quality).auto("format");
56
- const metadata = typeof image === "object" && "asset" in image ? image.asset.metadata : void 0;
57
- const crop = typeof image === "object" && "crop" in image ? image.crop : void 0;
58
- return {
59
- src: metadata?.lqip ?? builder.width(exports.lowResWidth).url().toString(),
60
- srcset: sortedWidths.map((width) => `${builder.width(width).url()} ${width}w`).join(","),
61
- naturalWidth: cropAxis(
62
- metadata?.dimensions?.width,
63
- crop?.left,
64
- crop?.right
65
- ),
66
- naturalHeight: cropAxis(
67
- metadata?.dimensions?.height,
68
- crop?.top,
69
- crop?.bottom
70
- )
71
- };
72
- }
73
- function metaImageUrl({
74
- image,
75
- client,
76
- width = exports.defaultMetaImageWidth,
77
- quality = exports.defaultQuality
78
- }) {
79
- return imageUrlBuilder__default.default(client).image(image).quality(quality).auto("format").width(width).url();
80
- }
81
-
82
- exports.imageProps = imageProps;
83
- exports.metaImageUrl = metaImageUrl;