Skip to content

Commit 0b793fc

Browse files
committed
feat: sanity provider with angular directive
If you use the `provideSanity` function and gives a config object or a sanity client factory, makes optional using `provideSanityLoader` if you're using the the Sanity Image Directive and pass as a parameter the obj config
1 parent e546558 commit 0b793fc

9 files changed

Lines changed: 1289 additions & 957 deletions

File tree

package-lock.json

Lines changed: 1195 additions & 902 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@
3737
},
3838
"devDependencies": {
3939
"@angular-devkit/build-angular": "~18.1.1",
40-
"@angular-devkit/core": "~18.1.1",
4140
"@angular-devkit/schematics": "~18.1.1",
4241
"@angular-eslint/eslint-plugin": "^18.0.1",
4342
"@angular-eslint/eslint-plugin-template": "^18.0.1",
4443
"@angular-eslint/template-parser": "^18.0.1",
44+
"@angular/build": "~18.1.1",
4545
"@angular/cli": "~18.1.1",
4646
"@angular/compiler-cli": "~18.1.1",
4747
"@angular/language-service": "~18.1.1",

packages/sanity/channels/package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
"sideEffects": false,
77
"type": "module",
88
"dependencies": {
9-
"uuid": "^10.0.0"
10-
},
11-
"devDependencies": {
12-
"@types/uuid": "^10.0.0"
9+
"uuid": "^11.0.0-0"
1310
}
1411
}

packages/sanity/image-loader/src/loader.ts

Lines changed: 53 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Provider } from '@angular/core';
1+
import { inject, Provider } from '@angular/core';
22
import { IMAGE_LOADER, ImageLoaderConfig } from '@angular/common';
33

44
import imageUrlBuilder from '@sanity/image-url';
@@ -7,52 +7,61 @@ import { SANITY_CONFIG, SanityConfig } from '@limitless-angular/sanity/shared';
77

88
const DEFAULT_IMAGE_QUALITY = 75;
99

10-
export function provideSanityLoader(config: SanityConfig): Provider {
10+
export function sanityImageLoader(config?: SanityConfig | null) {
11+
return (loaderConfig: ImageLoaderConfig) => {
12+
const {
13+
src,
14+
loaderParams = {},
15+
width = loaderParams['width'],
16+
isPlaceholder,
17+
} = loaderConfig;
18+
const builder = imageUrlBuilder(config ?? undefined);
19+
let imageBuilder = builder
20+
.image(src)
21+
.auto('format')
22+
.fit((loaderParams['fit'] ?? loaderParams['height']) ? 'min' : 'max');
23+
24+
if (width && loaderParams['height'] && loaderParams['width']) {
25+
imageBuilder = imageBuilder.height(
26+
Math.round((loaderParams['height'] / loaderParams['width']) * width),
27+
);
28+
}
29+
30+
if (width) {
31+
imageBuilder = imageBuilder.width(width);
32+
}
33+
34+
// Use loaderParams for additional configuration
35+
if (loaderParams['quality']) {
36+
imageBuilder = imageBuilder.quality(loaderParams['quality']);
37+
} else {
38+
imageBuilder = imageBuilder.quality(DEFAULT_IMAGE_QUALITY);
39+
}
40+
41+
if (loaderParams['blur']) {
42+
imageBuilder = imageBuilder.blur(loaderParams['blur']);
43+
}
44+
45+
if (isPlaceholder) {
46+
imageBuilder = imageBuilder.blur(50).quality(20);
47+
}
48+
49+
return imageBuilder.url() || '';
50+
};
51+
}
52+
53+
export function provideSanityLoader(config?: SanityConfig): Provider {
54+
const configProviders = config
55+
? [{ provide: SANITY_CONFIG, useValue: config }]
56+
: [];
57+
1158
return [
12-
{ provide: SANITY_CONFIG, useValue: config },
59+
...configProviders,
1360
{
1461
provide: IMAGE_LOADER,
15-
useValue: (loaderConfig: ImageLoaderConfig) => {
16-
const {
17-
src,
18-
loaderParams = {},
19-
width = loaderParams['width'],
20-
isPlaceholder,
21-
} = loaderConfig;
22-
const builder = imageUrlBuilder(config);
23-
let imageBuilder = builder
24-
.image(src)
25-
.auto('format')
26-
.fit((loaderParams['fit'] ?? loaderParams['height']) ? 'min' : 'max');
27-
28-
if (width && loaderParams['height'] && loaderParams['width']) {
29-
imageBuilder = imageBuilder.height(
30-
Math.round(
31-
(loaderParams['height'] / loaderParams['width']) * width,
32-
),
33-
);
34-
}
35-
36-
if (width) {
37-
imageBuilder = imageBuilder.width(width);
38-
}
39-
40-
// Use loaderParams for additional configuration
41-
if (loaderParams['quality']) {
42-
imageBuilder = imageBuilder.quality(loaderParams['quality']);
43-
} else {
44-
imageBuilder = imageBuilder.quality(DEFAULT_IMAGE_QUALITY);
45-
}
46-
47-
if (loaderParams['blur']) {
48-
imageBuilder = imageBuilder.blur(loaderParams['blur']);
49-
}
50-
51-
if (isPlaceholder) {
52-
imageBuilder = imageBuilder.blur(50).quality(20);
53-
}
54-
55-
return imageBuilder.url() || '';
62+
useFactory: () => {
63+
const config = inject(SANITY_CONFIG, { optional: true });
64+
return sanityImageLoader(config);
5665
},
5766
},
5867
];

packages/sanity/image-loader/src/sanity-image.directive.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,43 @@ import {
66
input,
77
OnInit,
88
} from '@angular/core';
9-
import { NgOptimizedImage } from '@angular/common';
9+
import {
10+
IMAGE_LOADER,
11+
type ImageLoaderConfig,
12+
NgOptimizedImage,
13+
} from '@angular/common';
1014

1115
import type { SanityImageSource } from '@sanity/image-url/lib/types/types';
1216
import imageUrlBuilder from '@sanity/image-url';
1317

1418
import { SANITY_CONFIG } from '@limitless-angular/sanity/shared';
19+
import { sanityImageLoader } from './loader';
20+
21+
function getNoopImageLoader() {
22+
return (
23+
IMAGE_LOADER.ɵprov as {
24+
factory: () => (config: ImageLoaderConfig) => string;
25+
}
26+
).factory();
27+
}
1528

1629
@Directive({
1730
// eslint-disable-next-line @angular-eslint/directive-selector
1831
selector: 'img[sanityImage]',
1932
standalone: true,
33+
providers: [
34+
{
35+
provide: IMAGE_LOADER,
36+
useFactory: () => {
37+
const config = inject(SANITY_CONFIG);
38+
const imageLoader = inject(IMAGE_LOADER, { skipSelf: true });
39+
const noopImageLoader = getNoopImageLoader();
40+
return imageLoader !== noopImageLoader
41+
? imageLoader
42+
: sanityImageLoader(config);
43+
},
44+
},
45+
],
2046
})
2147
// eslint-disable-next-line @angular-eslint/directive-class-suffix
2248
export class SanityImage extends NgOptimizedImage implements OnInit {

packages/sanity/ng-package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
33
"dest": "../../dist/packages/sanity",
44
"lib": {
5-
"entryFile": "src/public-api.ts"
5+
"entryFile": "src/index.ts"
66
},
77
"allowedNonPeerDependencies": [
88
"@portabletext/toolkit",

packages/sanity/shared/src/tokens.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { InjectionToken } from '@angular/core';
22

3-
import { type SanityClientFactory, SanityConfig } from './types';
3+
import { type SanityClientFactory, type SanityConfig } from './types';
44

55
export const SANITY_CONFIG = new InjectionToken<SanityConfig>('SANITY_CONFIG');
66

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
*/
44

55
export * from '@limitless-angular/sanity/shared';
6-
export * from './providers';
6+
export { provideSanity, withLivePreview } from './providers';

packages/sanity/src/providers.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import { LIVE_PREVIEW_REFRESH_INTERVAL } from '@limitless-angular/sanity/preview
99

1010
import {
1111
SANITY_CLIENT_FACTORY,
12+
SANITY_CONFIG,
1213
type SanityClientFactory,
14+
type SanityConfig,
1315
} from '@limitless-angular/sanity/shared';
1416

1517
const DEFAULT_LIVE_PREVIEW_REFRESH_INTERVAL = 10000;
@@ -19,11 +21,16 @@ export interface LivePreviewOptions {
1921
}
2022

2123
export function provideSanity(
22-
factory: SanityClientFactory,
24+
factoryOrConfig: SanityClientFactory | SanityConfig,
2325
...features: SanityFeatures[]
2426
): EnvironmentProviders {
2527
return makeEnvironmentProviders([
26-
{ provide: SANITY_CLIENT_FACTORY, useValue: factory },
28+
...(typeof factoryOrConfig === 'function'
29+
? [
30+
{ provide: SANITY_CLIENT_FACTORY, useValue: factoryOrConfig },
31+
{ provide: SANITY_CONFIG, useValue: factoryOrConfig()?.config() },
32+
]
33+
: [{ provide: SANITY_CONFIG, useValue: factoryOrConfig }]),
2734
{
2835
provide: ENVIRONMENT_INITIALIZER,
2936
multi: true,

0 commit comments

Comments
 (0)