Skip to content

Commit 0749fcc

Browse files
authored
Merge pull request #160 from episerver/bugfix/CMS-46517-loose-tuples
Accept components only with tags (without default)
2 parents 4c0aaec + b2f1fd8 commit 0749fcc

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-11
lines changed

__test__/test-website/src/app/en/layout.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ import {
1010
Component2A,
1111
Component3,
1212
Component3C,
13+
Component6,
14+
Component7,
1315
ct1,
1416
ct2,
1517
ct3,
18+
ct6,
19+
ct7,
1620
dt1,
1721
dt2,
1822
dt3,
@@ -28,7 +32,7 @@ import {
2832
} from '@optimizely/cms-sdk';
2933
import { initReactComponentRegistry } from '@optimizely/cms-sdk/react/server';
3034

31-
initContentTypeRegistry([ct1, ct2, ct3]);
35+
initContentTypeRegistry([ct1, ct2, ct3, ct6, ct7]);
3236
initDisplayTemplateRegistry([dt1, dt2, dt3, dt4, dt5, dt6]);
3337
initReactComponentRegistry({
3438
resolver: {
@@ -57,6 +61,15 @@ initReactComponentRegistry({
5761
},
5862
_Column: Column,
5963
'_Column:tagA': ColumnA,
64+
65+
// Content type "test_ct6" only has a component with tag
66+
'test_c6:tagA': Component6,
67+
test_c7: {
68+
// default: Component7,
69+
tags: {
70+
tagA: Component7,
71+
},
72+
},
6073
},
6174
});
6275

__test__/test-website/src/components/with-display-templates.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ export const ct3 = contentType({
3333
baseType: '_experience',
3434
});
3535

36+
export const ct6 = contentType({
37+
key: 'test_c6',
38+
baseType: '_component',
39+
compositionBehaviors: ['elementEnabled', 'sectionEnabled'],
40+
});
41+
42+
export const ct7 = contentType({
43+
key: 'test_c7',
44+
baseType: '_component',
45+
compositionBehaviors: ['elementEnabled', 'sectionEnabled'],
46+
});
47+
3648
export const dt1 = displayTemplate({
3749
key: 'test_dt1',
3850
baseType: '_component',
@@ -90,6 +102,8 @@ export const dt6 = displayTemplate({
90102
type Props1 = { opti: Infer<typeof ct1> };
91103
type Props2 = { opti: Infer<typeof ct2> };
92104
type Props3 = { opti: Infer<typeof ct3> };
105+
type Props6 = { opti: Infer<typeof ct6> };
106+
type Props7 = { opti: Infer<typeof ct7> };
93107

94108
type BlankSectionProps = {
95109
opti: Infer<typeof BlankSectionContentType>;
@@ -124,6 +138,13 @@ export function Component3({ opti }: Props3) {
124138
);
125139
}
126140

141+
export function Component6({}: Props6) {
142+
return <div>This is Component6</div>;
143+
}
144+
145+
export function Component7({}: Props7) {
146+
return <div>This is Component7</div>;
147+
}
127148
export function Component3C({ opti }: Props3) {
128149
return (
129150
<div>

packages/optimizely-cms-sdk/src/render/componentRegistry.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*/
1515
type ComponentWithVariants<C> = {
1616
/** Default component */
17-
default: C;
17+
default?: C;
1818

1919
/**
2020
* Tagged variants, where the keys are tag names and the values are the corresponding components.
@@ -47,13 +47,11 @@ type ComponentMap<C> = Record<string, ComponentEntry<C>>;
4747

4848
/** Returns true if `obj` is type {@linkcode ComponentWithVariants} */
4949
function hasVariants(obj: unknown): obj is ComponentWithVariants<unknown> {
50-
return (
51-
typeof obj === 'object' && obj !== null && 'default' in obj && 'tags' in obj
52-
);
50+
return typeof obj === 'object' && obj !== null && 'tags' in obj;
5351
}
5452

5553
/** Returns the default component in an {@linkcode ComponentEntry} */
56-
function getDefaultComponent<C>(entry: ComponentEntry<C>): C {
54+
function getDefaultComponent<C>(entry: ComponentEntry<C>): C | undefined {
5755
if (hasVariants(entry)) {
5856
return entry.default;
5957
} else {
@@ -100,21 +98,23 @@ export class ComponentRegistry<T> {
10098

10199
const entry = this.resolver[contentType];
102100

103-
if (!entry) {
104-
return undefined;
105-
}
106-
107101
if (!options.tag) {
102+
if (!entry) {
103+
return undefined;
104+
}
108105
return getDefaultComponent(entry);
109106
}
110107

111-
// Search for the component `${contentType}:${tag}`
112108
const taggedEntry = this.resolver[`${contentType}:${options.tag}`];
113109

114110
if (taggedEntry) {
115111
return getDefaultComponent(taggedEntry);
116112
}
117113

114+
if (!entry) {
115+
return undefined;
116+
}
117+
118118
return (
119119
// Search for the component with the tag in the component definition
120120
getTagComponent(entry, options.tag) ??

0 commit comments

Comments
 (0)