@ethlete/contentful 0.1.0-next.1 → 0.1.0-next.3

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.
Files changed (30) hide show
  1. package/esm2020/lib/components/audio/contentful-audio.component.mjs +36 -15
  2. package/esm2020/lib/components/file/contentful-file.component.mjs +30 -11
  3. package/esm2020/lib/components/image/contentful-image.component.mjs +31 -11
  4. package/esm2020/lib/components/rich-text-renderer/index.mjs +2 -0
  5. package/esm2020/lib/components/rich-text-renderer/public-api.mjs +3 -2
  6. package/esm2020/lib/components/rich-text-renderer/rich-text-renderer.component.mjs +16 -10
  7. package/esm2020/lib/components/rich-text-renderer/rich-text-renderer.constants.mjs +3 -0
  8. package/esm2020/lib/components/rich-text-renderer/rich-text-renderer.types.mjs +1 -1
  9. package/esm2020/lib/components/rich-text-renderer/rich-text-renderer.util.mjs +43 -15
  10. package/esm2020/lib/components/video/contentful-video.component.mjs +28 -13
  11. package/esm2020/lib/contentful.module.mjs +4 -4
  12. package/esm2020/lib/types/contentful.types.mjs +1 -1
  13. package/esm2020/lib/utils/contentful-config.mjs +1 -1
  14. package/fesm2015/ethlete-contentful.mjs +225 -117
  15. package/fesm2015/ethlete-contentful.mjs.map +1 -1
  16. package/fesm2020/ethlete-contentful.mjs +222 -116
  17. package/fesm2020/ethlete-contentful.mjs.map +1 -1
  18. package/lib/components/audio/contentful-audio.component.d.ts +11 -4
  19. package/lib/components/file/contentful-file.component.d.ts +9 -4
  20. package/lib/components/image/contentful-image.component.d.ts +10 -4
  21. package/lib/components/rich-text-renderer/index.d.ts +1 -0
  22. package/lib/components/rich-text-renderer/public-api.d.ts +2 -1
  23. package/lib/components/rich-text-renderer/rich-text-renderer.component.d.ts +2 -2
  24. package/lib/components/rich-text-renderer/rich-text-renderer.constants.d.ts +2 -0
  25. package/lib/components/rich-text-renderer/rich-text-renderer.types.d.ts +6 -0
  26. package/lib/components/rich-text-renderer/rich-text-renderer.util.d.ts +9 -7
  27. package/lib/components/video/contentful-video.component.d.ts +9 -4
  28. package/lib/types/contentful.types.d.ts +14 -2
  29. package/lib/utils/contentful-config.d.ts +1 -1
  30. package/package.json +2 -2
@@ -1,97 +1,114 @@
1
- import { NgIf, DOCUMENT } from '@angular/common';
1
+ import { NgIf, NgClass, DOCUMENT } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { Component, ChangeDetectionStrategy, ViewEncapsulation, Input, InjectionToken, inject, Renderer2, ElementRef, ViewContainerRef, ComponentFactoryResolver, ApplicationRef, Injector, NgModule } from '@angular/core';
3
+ import { InjectionToken, inject, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, Renderer2, ElementRef, ViewContainerRef, ComponentFactoryResolver, ApplicationRef, Injector, NgModule } from '@angular/core';
4
4
  import { DomPortalOutlet, ComponentPortal } from '@angular/cdk/portal';
5
5
  import { BLOCKS, INLINES } from '@contentful/rich-text-types';
6
6
 
7
- class ContentfulAudioComponent {
7
+ const CONTENTFUL_CONFIG = new InjectionToken('TooltipConfig');
8
+
9
+ class ContentfulConfig {
8
10
  constructor() {
9
- this._data = null;
10
- }
11
- get data() {
12
- return this._data;
13
- }
14
- set data(v) {
15
- if (v && !v.contentType.startsWith('audio/')) {
16
- throw new Error('The provided asset is not an audio');
17
- }
18
- this._data = v;
11
+ /**
12
+ * Default components for rendering contentful assets
13
+ */
14
+ this.components = {
15
+ file: ContentfulFileComponent,
16
+ image: ContentfulImageComponent,
17
+ video: ContentfulVideoComponent,
18
+ audio: ContentfulAudioComponent,
19
+ };
20
+ /**
21
+ * Determines if the contentful rich text renderer should render the contentful rich text with tailwind css classes
22
+ */
23
+ this.useTailwindClasses = false;
19
24
  }
20
25
  }
21
- ContentfulAudioComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulAudioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
22
- ContentfulAudioComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: ContentfulAudioComponent, isStandalone: true, selector: "et-contentful-audio", inputs: { data: "data" }, ngImport: i0, template: `
23
- <figure *ngIf="data">
24
- <figcaption>{{ data.title }}</figcaption>
25
- <audio controls src="{{ data.url }}"></audio>
26
- </figure>
27
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
28
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulAudioComponent, decorators: [{
29
- type: Component,
30
- args: [{
31
- selector: 'et-contentful-audio',
32
- template: `
33
- <figure *ngIf="data">
34
- <figcaption>{{ data.title }}</figcaption>
35
- <audio controls src="{{ data.url }}"></audio>
36
- </figure>
37
- `,
38
- changeDetection: ChangeDetectionStrategy.OnPush,
39
- encapsulation: ViewEncapsulation.None,
40
- standalone: true,
41
- imports: [NgIf],
42
- }]
43
- }], propDecorators: { data: [{
44
- type: Input
45
- }] } });
26
+
27
+ const provideContentfulConfig = (contentfulConfig) => {
28
+ return { provide: CONTENTFUL_CONFIG, useValue: contentfulConfig };
29
+ };
30
+
31
+ const RICH_TEXT_RENDERER_COMPONENT_DATA = new InjectionToken('RICH_TEXT_RENDERER_COMPONENT_DATA');
46
32
 
47
33
  class ContentfulFileComponent {
48
34
  constructor() {
35
+ this._richTextData = inject(RICH_TEXT_RENDERER_COMPONENT_DATA, { optional: true });
49
36
  this._data = null;
37
+ this.fileClass = null;
50
38
  }
51
39
  get data() {
52
40
  return this._data;
53
41
  }
54
42
  set data(v) {
55
- this._data = v;
43
+ if (v && !v.contentType) {
44
+ this._data = null;
45
+ console.warn('The provided asset is invalid', v);
46
+ return;
47
+ }
48
+ this._data = v ?? null;
49
+ }
50
+ ngOnInit() {
51
+ if (this._richTextData) {
52
+ this.data = this._richTextData;
53
+ }
56
54
  }
57
55
  }
58
- ContentfulFileComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
59
- ContentfulFileComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: ContentfulFileComponent, isStandalone: true, selector: "et-contentful-file", inputs: { data: "data" }, ngImport: i0, template: `
60
- <a *ngIf="data" [href]="data.url" class="underline" target="_blank"> {{ data.title }} ({{ data.size }} Bytes) </a>
61
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
62
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulFileComponent, decorators: [{
56
+ ContentfulFileComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
57
+ ContentfulFileComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.9", type: ContentfulFileComponent, isStandalone: true, selector: "et-contentful-file", inputs: { data: "data", fileClass: "fileClass" }, ngImport: i0, template: `
58
+ <a *ngIf="data" [href]="data.url" [ngClass]="fileClass" class="underline" target="_blank">
59
+ {{ data.title }} ({{ data.size }} Bytes)
60
+ </a>
61
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
62
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulFileComponent, decorators: [{
63
63
  type: Component,
64
64
  args: [{
65
65
  selector: 'et-contentful-file',
66
66
  template: `
67
- <a *ngIf="data" [href]="data.url" class="underline" target="_blank"> {{ data.title }} ({{ data.size }} Bytes) </a>
67
+ <a *ngIf="data" [href]="data.url" [ngClass]="fileClass" class="underline" target="_blank">
68
+ {{ data.title }} ({{ data.size }} Bytes)
69
+ </a>
68
70
  `,
69
71
  changeDetection: ChangeDetectionStrategy.OnPush,
70
72
  encapsulation: ViewEncapsulation.None,
71
73
  standalone: true,
72
- imports: [NgIf],
74
+ imports: [NgIf, NgClass],
73
75
  }]
74
76
  }], propDecorators: { data: [{
75
77
  type: Input
78
+ }], fileClass: [{
79
+ type: Input
76
80
  }] } });
77
81
 
78
82
  class ContentfulImageComponent {
79
83
  constructor() {
84
+ this._richTextData = inject(RICH_TEXT_RENDERER_COMPONENT_DATA, { optional: true });
80
85
  this._data = null;
86
+ this.imgClass = null;
87
+ this.pictureClass = null;
81
88
  }
82
89
  get data() {
83
90
  return this._data;
84
91
  }
85
92
  set data(v) {
93
+ if (v && !v.contentType) {
94
+ this._data = null;
95
+ console.warn('The provided asset is invalid', v);
96
+ return;
97
+ }
86
98
  if (v && !v.contentType.startsWith('image/')) {
87
99
  throw new Error('The provided asset is not an image');
88
100
  }
89
- this._data = v;
101
+ this._data = v ?? null;
102
+ }
103
+ ngOnInit() {
104
+ if (this._richTextData) {
105
+ this.data = this._richTextData;
106
+ }
90
107
  }
91
108
  }
92
- ContentfulImageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulImageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
93
- ContentfulImageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: ContentfulImageComponent, isStandalone: true, selector: "et-contentful-image", inputs: { data: "data" }, ngImport: i0, template: `
94
- <picture *ngIf="data">
109
+ ContentfulImageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulImageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
110
+ ContentfulImageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.9", type: ContentfulImageComponent, isStandalone: true, selector: "et-contentful-image", inputs: { data: "data", imgClass: "imgClass", pictureClass: "pictureClass" }, ngImport: i0, template: `
111
+ <picture *ngIf="data" [ngClass]="pictureClass">
95
112
  <source srcset="{{ data.url }}?fm=avif" />
96
113
  <source srcset="{{ data.url }}?fm=webp" />
97
114
  <source srcset="{{ data.url }}?fm=jpg" />
@@ -99,16 +116,17 @@ ContentfulImageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0
99
116
  [attr.alt]="data.description ?? undefined"
100
117
  [attr.width]="data.width ?? undefined"
101
118
  [attr.height]="data.height ?? undefined"
119
+ [ngClass]="imgClass"
102
120
  src="{{ data.url }}"
103
121
  />
104
122
  </picture>
105
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
106
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulImageComponent, decorators: [{
123
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
124
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulImageComponent, decorators: [{
107
125
  type: Component,
108
126
  args: [{
109
127
  selector: 'et-contentful-image',
110
128
  template: `
111
- <picture *ngIf="data">
129
+ <picture *ngIf="data" [ngClass]="pictureClass">
112
130
  <source srcset="{{ data.url }}?fm=avif" />
113
131
  <source srcset="{{ data.url }}?fm=webp" />
114
132
  <source srcset="{{ data.url }}?fm=jpg" />
@@ -116,6 +134,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
116
134
  [attr.alt]="data.description ?? undefined"
117
135
  [attr.width]="data.width ?? undefined"
118
136
  [attr.height]="data.height ?? undefined"
137
+ [ngClass]="imgClass"
119
138
  src="{{ data.url }}"
120
139
  />
121
140
  </picture>
@@ -123,86 +142,77 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
123
142
  changeDetection: ChangeDetectionStrategy.OnPush,
124
143
  encapsulation: ViewEncapsulation.None,
125
144
  standalone: true,
126
- imports: [NgIf],
145
+ imports: [NgIf, NgClass],
127
146
  }]
128
147
  }], propDecorators: { data: [{
129
148
  type: Input
149
+ }], imgClass: [{
150
+ type: Input
151
+ }], pictureClass: [{
152
+ type: Input
130
153
  }] } });
131
154
 
132
- const CONTENTFUL_CONFIG = new InjectionToken('TooltipConfig');
133
-
134
- class ContentfulConfig {
135
- constructor() {
136
- /**
137
- * Default components for rendering contentful assets
138
- */
139
- this.components = {
140
- file: ContentfulFileComponent,
141
- image: ContentfulImageComponent,
142
- video: ContentfulVideoComponent,
143
- audio: ContentfulAudioComponent,
144
- };
145
- /**
146
- * Determines if the contentful rich text renderer should render the contentful rich text with tailwind css classes
147
- */
148
- this.useTailwindClasses = false;
149
- }
150
- }
151
-
152
- const provideContentfulConfig = (contentfulConfig) => {
153
- return { provide: CONTENTFUL_CONFIG, useValue: contentfulConfig };
154
- };
155
-
156
155
  class ContentfulVideoComponent {
157
156
  constructor() {
157
+ this._richTextData = inject(RICH_TEXT_RENDERER_COMPONENT_DATA, { optional: true });
158
158
  this._data = null;
159
+ this.videoClass = null;
159
160
  }
160
161
  get data() {
161
162
  return this._data;
162
163
  }
163
164
  set data(v) {
165
+ if (v && !v.contentType) {
166
+ this._data = null;
167
+ console.warn('The provided asset is invalid', v);
168
+ return;
169
+ }
164
170
  if (v && !v.contentType.startsWith('video/')) {
165
171
  throw new Error('The provided asset is not an video');
166
172
  }
167
- this._data = v;
173
+ this._data = v ?? null;
174
+ }
175
+ ngOnInit() {
176
+ if (this._richTextData) {
177
+ this.data = this._richTextData;
178
+ }
168
179
  }
169
180
  }
170
- ContentfulVideoComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulVideoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
171
- ContentfulVideoComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: ContentfulVideoComponent, isStandalone: true, selector: "et-contentful-video", inputs: { data: "data" }, ngImport: i0, template: `
172
- <video *ngIf="data" controls>
173
- <source src=" {{ data.url }} " type=" {{ data.contentType }}" />
181
+ ContentfulVideoComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulVideoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
182
+ ContentfulVideoComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.9", type: ContentfulVideoComponent, isStandalone: true, selector: "et-contentful-video", inputs: { data: "data", videoClass: "videoClass" }, ngImport: i0, template: `
183
+ <video *ngIf="data" [ngClass]="videoClass" controls>
184
+ <source src="{{ data.url }}" type="{{ data.contentType }}" />
174
185
  </video>
175
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
176
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulVideoComponent, decorators: [{
186
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
187
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulVideoComponent, decorators: [{
177
188
  type: Component,
178
189
  args: [{
179
190
  selector: 'et-contentful-video',
180
191
  template: `
181
- <video *ngIf="data" controls>
182
- <source src=" {{ data.url }} " type=" {{ data.contentType }}" />
192
+ <video *ngIf="data" [ngClass]="videoClass" controls>
193
+ <source src="{{ data.url }}" type="{{ data.contentType }}" />
183
194
  </video>
184
195
  `,
185
196
  changeDetection: ChangeDetectionStrategy.OnPush,
186
197
  encapsulation: ViewEncapsulation.None,
187
198
  standalone: true,
188
- imports: [NgIf],
199
+ imports: [NgIf, NgClass],
189
200
  }]
190
201
  }], propDecorators: { data: [{
191
202
  type: Input
203
+ }], videoClass: [{
204
+ type: Input
192
205
  }] } });
193
206
 
194
207
  const createRenderCommandsFromContentfulRichText = (options) => {
195
208
  const { data, config } = options;
196
209
  const commands = [];
197
- const assetMap = new Map();
198
210
  const assetComponents = getAssetComponentsFromConfig(config);
199
- for (const asset of data.links.assets.block) {
200
- assetMap.set(asset.sys.id, asset);
201
- }
202
- createContentfulRenderCommand(data.json, { children: commands, payload: data.json.nodeType }, assetMap, config.useTailwindClasses, assetComponents, config.customComponents);
211
+ const resourceMap = createContentfulResourceMap(data.links);
212
+ createContentfulRenderCommand(data.json, { children: commands, payload: data.json.nodeType }, resourceMap, config.useTailwindClasses, assetComponents, config.customComponents);
203
213
  return commands;
204
214
  };
205
- const createContentfulRenderCommand = (node, parent, assetMap, useTailwindClasses, assetComponents, customComponents) => {
215
+ const createContentfulRenderCommand = (node, parent, resourceMap, useTailwindClasses, assetComponents, customComponents) => {
206
216
  const { nodeType, data: nodeData } = node;
207
217
  const { children, marks, value } = getContentfulNodeProps(node);
208
218
  const command = {
@@ -218,8 +228,9 @@ const createContentfulRenderCommand = (node, parent, assetMap, useTailwindClasse
218
228
  },
219
229
  children: [],
220
230
  };
231
+ const entryId = nodeData['target']?.sys?.id;
221
232
  if (nodeType === BLOCKS.EMBEDDED_ASSET) {
222
- const asset = assetMap.get(nodeData['target']?.sys?.id);
233
+ const asset = resourceMap.assetsBlock.get(entryId);
223
234
  if (asset) {
224
235
  const isImage = asset.contentType.startsWith('image/');
225
236
  const isVideo = asset.contentType.startsWith('video/');
@@ -238,21 +249,30 @@ const createContentfulRenderCommand = (node, parent, assetMap, useTailwindClasse
238
249
  command.payload = assetComponents.file;
239
250
  }
240
251
  }
252
+ else {
253
+ console.warn(`No asset found for entry id "${entryId}"!`, nodeData);
254
+ }
241
255
  }
242
256
  else if (nodeType === BLOCKS.EMBEDDED_ENTRY || nodeType === INLINES.EMBEDDED_ENTRY) {
243
- const componentId = nodeData['target']?.sys?.contentType?.sys?.id;
244
- const component = customComponents?.[componentId];
245
- if (component) {
246
- command.payload = component;
247
- command.data = nodeData['target']?.fields;
257
+ const entry = resourceMap.entriesBlock.get(entryId) ?? resourceMap.entriesInline.get(entryId);
258
+ if (entry) {
259
+ const type = entry?.__typename ?? 'ET_UNKNOWN';
260
+ const component = customComponents?.[type];
261
+ if (component) {
262
+ command.payload = component;
263
+ command.data = entry;
264
+ }
265
+ else {
266
+ command.data = `ERROR: No component found for embedded entry "${type}" as "${nodeType}"!`;
267
+ }
248
268
  }
249
269
  else {
250
- command.data = `No component found for embedded entry ${componentId} as ${nodeType}!`;
270
+ console.warn(`No entry found for entry id "${entryId}"!`, nodeData);
251
271
  }
252
272
  }
253
273
  if (children && (children.length !== 1 || children[0].nodeType !== 'text')) {
254
274
  children.forEach((child) => {
255
- createContentfulRenderCommand(child, command, assetMap, useTailwindClasses, assetComponents, customComponents);
275
+ createContentfulRenderCommand(child, command, resourceMap, useTailwindClasses, assetComponents, customComponents);
256
276
  });
257
277
  }
258
278
  parent.children.push(command);
@@ -358,6 +378,27 @@ const translateContentfulNodeTypeToHtmlTag = (nodeType) => {
358
378
  return 'div';
359
379
  }
360
380
  };
381
+ const createContentfulResourceMap = (links) => {
382
+ const resourceMap = {
383
+ assetsBlock: createContentfulMap(links?.assets?.block),
384
+ entriesInline: createContentfulMap(links?.entries?.inline),
385
+ entriesBlock: createContentfulMap(links?.entries?.block),
386
+ };
387
+ return resourceMap;
388
+ };
389
+ const createContentfulMap = (links) => {
390
+ const assetMap = new Map();
391
+ if (links) {
392
+ for (const link of links) {
393
+ if (!link?.sys?.id) {
394
+ console.warn('Link has no sys.id property. Please include it inside your query.', link);
395
+ continue;
396
+ }
397
+ assetMap.set(link.sys.id, link);
398
+ }
399
+ }
400
+ return assetMap;
401
+ };
361
402
 
362
403
  class ContentfulRichTextRendererComponent {
363
404
  constructor() {
@@ -375,7 +416,7 @@ class ContentfulRichTextRendererComponent {
375
416
  return this._richText;
376
417
  }
377
418
  set richText(v) {
378
- this._richText = v;
419
+ this._richText = v ?? null;
379
420
  // clear the element
380
421
  this._viewContainerRef.clear();
381
422
  if (!v) {
@@ -413,13 +454,18 @@ class ContentfulRichTextRendererComponent {
413
454
  this._renderer.appendChild(parent, element);
414
455
  }
415
456
  else {
416
- const portal = new DomPortalOutlet(parent, this._componentFactoryResolver, this._appRef, this._injector, this._document);
457
+ const injector = Injector.create({
458
+ providers: [
459
+ {
460
+ provide: RICH_TEXT_RENDERER_COMPONENT_DATA,
461
+ useValue: data,
462
+ },
463
+ ],
464
+ parent: this._injector,
465
+ });
466
+ const portal = new DomPortalOutlet(parent, this._componentFactoryResolver, this._appRef, injector, this._document);
417
467
  const comp = new ComponentPortal(command.payload);
418
468
  const ref = comp.attach(portal);
419
- if (command.data) {
420
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
421
- ref.instance.data = command.data;
422
- }
423
469
  element = ref.location.nativeElement;
424
470
  }
425
471
  }
@@ -429,9 +475,9 @@ class ContentfulRichTextRendererComponent {
429
475
  }
430
476
  }
431
477
  }
432
- ContentfulRichTextRendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulRichTextRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
433
- ContentfulRichTextRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.3", type: ContentfulRichTextRendererComponent, isStandalone: true, selector: "et-contentful-rich-text-renderer", inputs: { richText: "richText" }, host: { classAttribute: "et-contentful-rich-text-renderer" }, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
434
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulRichTextRendererComponent, decorators: [{
478
+ ContentfulRichTextRendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulRichTextRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
479
+ ContentfulRichTextRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.9", type: ContentfulRichTextRendererComponent, isStandalone: true, selector: "et-contentful-rich-text-renderer", inputs: { richText: "richText" }, host: { classAttribute: "et-contentful-rich-text-renderer" }, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
480
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulRichTextRendererComponent, decorators: [{
435
481
  type: Component,
436
482
  args: [{
437
483
  selector: 'et-contentful-rich-text-renderer',
@@ -447,10 +493,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
447
493
  type: Input
448
494
  }] } });
449
495
 
496
+ class ContentfulAudioComponent {
497
+ constructor() {
498
+ this._richTextData = inject(RICH_TEXT_RENDERER_COMPONENT_DATA, { optional: true });
499
+ this._data = null;
500
+ this.audioClass = null;
501
+ this.figureClass = null;
502
+ this.figcaptionClass = null;
503
+ }
504
+ get data() {
505
+ return this._data;
506
+ }
507
+ set data(v) {
508
+ if (v && !v.contentType) {
509
+ this._data = null;
510
+ console.warn('The provided asset is invalid', v);
511
+ return;
512
+ }
513
+ if (v && !v.contentType.startsWith('audio/')) {
514
+ throw new Error('The provided asset is not an audio');
515
+ }
516
+ this._data = v ?? null;
517
+ }
518
+ ngOnInit() {
519
+ if (this._richTextData) {
520
+ this.data = this._richTextData;
521
+ }
522
+ }
523
+ }
524
+ ContentfulAudioComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulAudioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
525
+ ContentfulAudioComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.9", type: ContentfulAudioComponent, isStandalone: true, selector: "et-contentful-audio", inputs: { data: "data", audioClass: "audioClass", figureClass: "figureClass", figcaptionClass: "figcaptionClass" }, ngImport: i0, template: `
526
+ <figure *ngIf="data" [ngClass]="figureClass">
527
+ <figcaption [ngClass]="figcaptionClass">{{ data.title }}</figcaption>
528
+ <audio [ngClass]="audioClass" controls src="{{ data.url }}"></audio>
529
+ </figure>
530
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
531
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulAudioComponent, decorators: [{
532
+ type: Component,
533
+ args: [{
534
+ selector: 'et-contentful-audio',
535
+ template: `
536
+ <figure *ngIf="data" [ngClass]="figureClass">
537
+ <figcaption [ngClass]="figcaptionClass">{{ data.title }}</figcaption>
538
+ <audio [ngClass]="audioClass" controls src="{{ data.url }}"></audio>
539
+ </figure>
540
+ `,
541
+ changeDetection: ChangeDetectionStrategy.OnPush,
542
+ encapsulation: ViewEncapsulation.None,
543
+ standalone: true,
544
+ imports: [NgIf, NgClass],
545
+ }]
546
+ }], propDecorators: { data: [{
547
+ type: Input
548
+ }], audioClass: [{
549
+ type: Input
550
+ }], figureClass: [{
551
+ type: Input
552
+ }], figcaptionClass: [{
553
+ type: Input
554
+ }] } });
555
+
450
556
  class ContentfulModule {
451
557
  }
452
- ContentfulModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
453
- ContentfulModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.3", ngImport: i0, type: ContentfulModule, imports: [ContentfulAudioComponent,
558
+ ContentfulModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
559
+ ContentfulModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.9", ngImport: i0, type: ContentfulModule, imports: [ContentfulAudioComponent,
454
560
  ContentfulFileComponent,
455
561
  ContentfulImageComponent,
456
562
  ContentfulVideoComponent,
@@ -459,12 +565,12 @@ ContentfulModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", versio
459
565
  ContentfulImageComponent,
460
566
  ContentfulVideoComponent,
461
567
  ContentfulRichTextRendererComponent] });
462
- ContentfulModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulModule, imports: [ContentfulAudioComponent,
568
+ ContentfulModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulModule, imports: [ContentfulAudioComponent,
463
569
  ContentfulFileComponent,
464
570
  ContentfulImageComponent,
465
571
  ContentfulVideoComponent,
466
572
  ContentfulRichTextRendererComponent] });
467
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImport: i0, type: ContentfulModule, decorators: [{
573
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentfulModule, decorators: [{
468
574
  type: NgModule,
469
575
  args: [{
470
576
  imports: [
@@ -488,5 +594,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.3", ngImpor
488
594
  * Generated bundle index. Do not edit.
489
595
  */
490
596
 
491
- export { CONTENTFUL_CONFIG, ContentfulAudioComponent, ContentfulConfig, ContentfulFileComponent, ContentfulImageComponent, ContentfulModule, ContentfulRichTextRendererComponent, ContentfulVideoComponent, createContentfulRenderCommand, createRenderCommandsFromContentfulRichText, getAssetComponentsFromConfig, getContentfulNodeProps, provideContentfulConfig, transformContentfulMarks, translateContentfulNodeTypeToHtmlTag };
597
+ export { CONTENTFUL_CONFIG, ContentfulAudioComponent, ContentfulConfig, ContentfulFileComponent, ContentfulImageComponent, ContentfulModule, ContentfulRichTextRendererComponent, ContentfulVideoComponent, RICH_TEXT_RENDERER_COMPONENT_DATA, createContentfulMap, createContentfulRenderCommand, createContentfulResourceMap, createRenderCommandsFromContentfulRichText, getAssetComponentsFromConfig, getContentfulNodeProps, provideContentfulConfig, transformContentfulMarks, translateContentfulNodeTypeToHtmlTag };
492
598
  //# sourceMappingURL=ethlete-contentful.mjs.map