create-sitecore-jss 22.2.0-canary.7 → 22.2.0-canary.71

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 (108) hide show
  1. package/dist/bin.js +17 -43
  2. package/dist/common/processes/next.js +4 -1
  3. package/dist/common/processes/transform.js +2 -12
  4. package/dist/common/prompts/base.js +0 -13
  5. package/dist/common/prompts/proxy.js +35 -0
  6. package/dist/common/prompts/sxp.js +16 -2
  7. package/dist/common/utils/helpers.js +27 -2
  8. package/dist/init-runner.js +1 -1
  9. package/dist/initializers/angular/prompts.js +4 -4
  10. package/dist/initializers/angular-xmcloud/index.js +21 -7
  11. package/dist/initializers/node-xmcloud-proxy/index.js +2 -1
  12. package/dist/templates/angular/.env +4 -5
  13. package/dist/templates/angular/.eslintrc +1 -0
  14. package/dist/templates/angular/gitignore +5 -0
  15. package/dist/templates/angular/package.json +0 -2
  16. package/dist/templates/angular/scripts/config/plugins/fallback.ts +0 -1
  17. package/dist/templates/angular/scripts/generate-component-factory.ts +8 -0
  18. package/dist/templates/angular/scripts/generate-config.ts +25 -6
  19. package/dist/templates/angular/scripts/update-graphql-fragment-data.ts +21 -30
  20. package/dist/templates/angular/server.bundle.ts +3 -23
  21. package/dist/templates/angular/server.exports.ts +13 -0
  22. package/dist/templates/angular/src/app/JssState.ts +2 -9
  23. package/dist/templates/angular/src/app/app.module.ts +5 -4
  24. package/dist/templates/angular/src/app/app.server.module.ts +9 -6
  25. package/dist/templates/angular/src/app/i18n/jss-translation-client-loader.service.ts +15 -7
  26. package/dist/templates/angular/src/app/i18n/jss-translation-server-loader.service.ts +14 -2
  27. package/dist/templates/angular/src/app/jss-context.server-side.service.ts +4 -2
  28. package/dist/templates/angular/src/app/jss-context.service.ts +14 -11
  29. package/dist/templates/angular/src/app/jss-graphql.service.ts +7 -7
  30. package/dist/templates/angular/src/app/layout/jss-layout.service.ts +2 -2
  31. package/dist/templates/angular/src/app/lib/dictionary-service-factory.ts +4 -1
  32. package/dist/templates/angular/src/app/lib/graphql-client-factory/config.ts +21 -0
  33. package/dist/templates/angular/src/app/lib/graphql-client-factory/index.ts +16 -0
  34. package/dist/templates/angular/src/app/lib/layout-service-factory.ts +1 -1
  35. package/dist/templates/angular/src/app/routing/layout/layout.component.ts +10 -9
  36. package/dist/templates/angular/src/environments/gitignore +2 -1
  37. package/dist/templates/angular-sxp/.env +2 -0
  38. package/dist/templates/angular-sxp/scripts/config/plugins/disconnected.ts +4 -2
  39. package/dist/templates/angular-sxp/src/app/components/graph-ql-layout/graph-ql-layout.component.ts +1 -1
  40. package/dist/templates/angular-xmcloud/.env +8 -2
  41. package/dist/templates/angular-xmcloud/angular.json +0 -1
  42. package/dist/templates/angular-xmcloud/scripts/bootstrap.ts +28 -0
  43. package/dist/templates/angular-xmcloud/scripts/config/plugins/xmcloud.ts +16 -0
  44. package/dist/templates/angular-xmcloud/scripts/generate-metadata.ts +25 -0
  45. package/dist/templates/angular-xmcloud/server.exports.ts +24 -0
  46. package/dist/templates/angular-xmcloud/src/app/components/app-components.shared.module.ts +21 -0
  47. package/dist/templates/angular-xmcloud/src/app/components/column-splitter/column-splitter.component.html +5 -0
  48. package/dist/templates/angular-xmcloud/src/app/components/column-splitter/column-splitter.component.ts +40 -0
  49. package/dist/templates/angular-xmcloud/src/app/components/container/container.component.html +14 -0
  50. package/dist/templates/angular-xmcloud/src/app/components/container/container.component.ts +30 -0
  51. package/dist/templates/angular-xmcloud/src/app/components/image/image.component.html +36 -0
  52. package/dist/templates/angular-xmcloud/src/app/components/image/image.component.ts +67 -0
  53. package/dist/templates/angular-xmcloud/src/app/components/link-list/link-list.component.html +15 -0
  54. package/dist/templates/angular-xmcloud/src/app/components/link-list/link-list.component.ts +41 -0
  55. package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation-item.component.html +23 -0
  56. package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation-item.component.ts +65 -0
  57. package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation.component.html +21 -0
  58. package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation.component.ts +49 -0
  59. package/dist/templates/angular-xmcloud/src/app/components/page-content/page-content.component.html +5 -0
  60. package/dist/templates/angular-xmcloud/src/app/components/page-content/page-content.component.ts +39 -0
  61. package/dist/templates/angular-xmcloud/src/app/components/partial-design-dynamic-placeholder/partial-design-dynamic-placeholder.component.html +1 -0
  62. package/dist/templates/angular-xmcloud/src/app/components/partial-design-dynamic-placeholder/partial-design-dynamic-placeholder.component.ts +15 -0
  63. package/dist/templates/angular-xmcloud/src/app/components/promo/promo.component.html +21 -0
  64. package/dist/templates/angular-xmcloud/src/app/components/promo/promo.component.ts +13 -0
  65. package/dist/templates/angular-xmcloud/src/app/components/richtext/richtext.component.html +7 -12
  66. package/dist/templates/angular-xmcloud/src/app/components/richtext/richtext.component.ts +6 -1
  67. package/dist/templates/angular-xmcloud/src/app/components/row-splitter/row-splitter.component.html +11 -0
  68. package/dist/templates/angular-xmcloud/src/app/components/row-splitter/row-splitter.component.ts +35 -0
  69. package/dist/templates/angular-xmcloud/src/app/components/sxa.component.ts +4 -4
  70. package/dist/templates/angular-xmcloud/src/app/components/title/title.component.html +10 -0
  71. package/dist/templates/angular-xmcloud/src/app/components/title/title.component.ts +56 -0
  72. package/dist/templates/angular-xmcloud/src/app/jss-link.service.ts +55 -0
  73. package/dist/templates/angular-xmcloud/src/app/lib/config.ts +2 -0
  74. package/dist/templates/angular-xmcloud/src/app/lib/graphql-client-factory/config.ts +58 -0
  75. package/dist/templates/angular-xmcloud/src/app/routing/layout/layout.component.html +38 -0
  76. package/dist/templates/angular-xmcloud/src/app/routing/layout/layout.component.ts +104 -0
  77. package/dist/templates/angular-xmcloud/src/app/routing/scripts/scripts.component.html +3 -0
  78. package/dist/templates/angular-xmcloud/src/app/routing/scripts/scripts.module.ts +10 -0
  79. package/dist/templates/angular-xmcloud/src/assets/styles/basic/_header.scss +3 -1
  80. package/dist/templates/angular-xmcloud/src/assets/styles/main.scss +10 -0
  81. package/dist/templates/angular-xmcloud/src/assets/styles/sass/components/_component-image.scss +1 -1
  82. package/dist/templates/nextjs/package.json +1 -1
  83. package/dist/templates/nextjs/scripts/config/plugins/fallback.ts +0 -1
  84. package/dist/templates/nextjs/scripts/generate-config.ts +8 -1
  85. package/dist/templates/nextjs/src/lib/page-props-factory/plugins/component-props.ts +2 -1
  86. package/dist/templates/nextjs-styleguide/scripts/config/plugins/disconnected.ts +1 -0
  87. package/dist/templates/nextjs-sxa/src/assets/sass/components/_component-image.scss +1 -1
  88. package/dist/templates/nextjs-sxa/src/assets/sass/components/common/_alignment.scss +66 -7
  89. package/dist/templates/nextjs-sxa/src/components/Container.tsx +6 -14
  90. package/dist/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/component-themes.ts +2 -1
  91. package/dist/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/preview-mode.ts +2 -1
  92. package/dist/templates/node-headless-ssr-experience-edge/gitignore +19 -0
  93. package/dist/templates/node-headless-ssr-proxy/gitignore +19 -0
  94. package/dist/templates/node-headless-ssr-proxy/src/config.ts +3 -3
  95. package/dist/templates/node-headless-ssr-proxy/src/httpAgents.ts +2 -2
  96. package/dist/templates/node-headless-ssr-proxy/src/index.ts +9 -2
  97. package/dist/templates/node-xmcloud-proxy/.env +7 -1
  98. package/dist/templates/node-xmcloud-proxy/README.md +1 -1
  99. package/dist/templates/node-xmcloud-proxy/gitignore +33 -0
  100. package/dist/templates/node-xmcloud-proxy/package.json +3 -2
  101. package/dist/templates/node-xmcloud-proxy/src/config.ts +9 -3
  102. package/dist/templates/node-xmcloud-proxy/src/index.ts +54 -5
  103. package/dist/templates/node-xmcloud-proxy/src/types.ts +10 -42
  104. package/dist/templates/react/scripts/generate-config.js +10 -3
  105. package/dist/templates/vue/scripts/generate-config.js +5 -0
  106. package/package.json +2 -2
  107. package/dist/templates/angular/src/app/lib/graphql-client-factory.ts +0 -28
  108. package/dist/templates/angular-xmcloud/src/app/lib/graphql-client-factory.ts +0 -44
@@ -0,0 +1,21 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { TranslateModule } from '@ngx-translate/core';
5
+ import { RouterModule } from '@angular/router';
6
+ import { JssModule } from '@sitecore-jss/sitecore-jss-angular';
7
+ import { NavigationItemComponent } from './navigation/navigation-item.component';
8
+
9
+ /*
10
+ This module is imported by the generated app-components.module.ts.
11
+ You can use this module to provide shared Angular components that are not
12
+ JSS components, etc to the generated module.
13
+
14
+ Don't want code generation? See ./.gitignore for instructions to turn it off.
15
+ */
16
+ @NgModule({
17
+ imports: [CommonModule, TranslateModule, RouterModule, JssModule, FormsModule],
18
+ exports: [CommonModule, TranslateModule, RouterModule, FormsModule, NavigationItemComponent],
19
+ declarations: [NavigationItemComponent],
20
+ })
21
+ export class AppComponentsSharedModule {}
@@ -0,0 +1,5 @@
1
+ <div *ngFor="let ph of enabledPlaceholders" [ngClass]="getColumnClass(+ph - 1)">
2
+ <div class="row">
3
+ <sc-placeholder [name]="getPlaceholderName(ph)" [rendering]="rendering"> </sc-placeholder>
4
+ </div>
5
+ </div>
@@ -0,0 +1,40 @@
1
+ import { Component } from '@angular/core';
2
+ import { SxaComponent } from '../sxa.component';
3
+
4
+ @Component({
5
+ selector: 'app-column-splitter',
6
+ templateUrl: './column-splitter.component.html',
7
+ host: {
8
+ 'class': 'row component column-splitter',
9
+ '[class]': 'columnSplitterStyles',
10
+ '[id]' : 'id'
11
+ }
12
+ })
13
+ export class ColumnSplitterComponent extends SxaComponent {
14
+ get columnSplitterStyles(): string {
15
+ return `${this.rendering.params.GridParameters ?? ''} ${this.rendering.params.Styles ??
16
+ ''}`.trimEnd();
17
+ }
18
+
19
+ get columnWidths(): string[] {
20
+ return Array.from({ length: 8 }, (_, i) => this.rendering.params[`ColumnWidth${i + 1}`]);
21
+ }
22
+
23
+ get columnStyles(): string[] {
24
+ return Array.from({ length: 8 }, (_, i) => this.rendering.params[`Styles${i + 1}`]);
25
+ }
26
+
27
+ get enabledPlaceholders(): string[] {
28
+ return this.rendering.params.EnabledPlaceholders.split(',');
29
+ }
30
+
31
+ getColumnClass(index: number): string {
32
+ const widthClass = this.columnWidths[index] || '';
33
+ const styleClass = this.columnStyles[index] || '';
34
+ return `${widthClass} ${styleClass}`.trim();
35
+ }
36
+
37
+ getPlaceholderName(ph: string): string {
38
+ return `column-${ph}-{*}`;
39
+ }
40
+ }
@@ -0,0 +1,14 @@
1
+ <div class="container-wrapper" *ngIf="wrapped; else default">
2
+ <ng-container *ngTemplateOutlet="default"></ng-container>
3
+ </div>
4
+ <ng-template #default>
5
+ <div class="component container-default {{ styles }}" [attr.id]="id">
6
+ <div class="component-content" [ngStyle]="backgroundStyle">
7
+ <sc-placeholder
8
+ [name]="placeholderName"
9
+ [rendering]="rendering"
10
+ class="row">
11
+ </sc-placeholder>
12
+ </div>
13
+ </div>
14
+ </ng-template>
@@ -0,0 +1,30 @@
1
+ import { Component, OnInit } from '@angular/core';
2
+ import { SxaComponent } from '../sxa.component';
3
+
4
+ @Component({
5
+ selector: 'app-container',
6
+ templateUrl: './container.component.html',
7
+ })
8
+ export class ContainerComponent extends SxaComponent implements OnInit {
9
+ placeholderName: string;
10
+ wrapped: boolean;
11
+
12
+ override ngOnInit() {
13
+ super.ngOnInit();
14
+
15
+ this.placeholderName = `container-${this.rendering.params?.DynamicPlaceholderId}`;
16
+ this.wrapped = this.rendering.params?.Styles?.split(' ').includes('container');
17
+ }
18
+
19
+ get backgroundStyle() {
20
+ const backgroundImage = this.rendering.params?.BackgroundImage;
21
+ const mediaUrlPattern = new RegExp(/mediaurl=\"([^"]*)\"/, 'i');
22
+ if (!backgroundImage || !backgroundImage.match(mediaUrlPattern)) {
23
+ return {};
24
+ }
25
+ const mediaUrl = backgroundImage.match(mediaUrlPattern)[1];
26
+ return {
27
+ backgroundImage: `url('${mediaUrl}')`,
28
+ };
29
+ }
30
+ }
@@ -0,0 +1,36 @@
1
+ <ng-container [ngTemplateOutlet]="variant"></ng-container>
2
+
3
+ <ng-template #default>
4
+ <div class="component image {{ styles }}" [attr.id]="id" *ngIf="rendering.fields; else empty">
5
+ <div class="component-content">
6
+ <ng-container *ngIf="isEditing || !rendering.fields.TargetUrl?.value?.href; else withLink">
7
+ <img *scImage="rendering.fields.Image" />
8
+ </ng-container>
9
+ <span class="image-caption field-imagecaption" *scText="rendering.fields.ImageCaption"></span>
10
+ </div>
11
+ </div>
12
+ </ng-template>
13
+
14
+ <ng-template #banner>
15
+ <div class="component hero-banner {{ styles }} {{ classHeroBannerEmpty }}" [attr.id]="id">
16
+ <div class="component-content sc-sxa-image-hero-banner" [ngStyle]="backgroundStyle">
17
+ <ng-container *ngIf="isEditing">
18
+ <img *scImage="modifyImageProps" />
19
+ </ng-container>
20
+ </div>
21
+ </div>
22
+ </ng-template>
23
+
24
+ <ng-template #withLink>
25
+ <a *scLink="rendering.fields.TargetUrl">
26
+ <img *scImage="rendering.fields.Image" />
27
+ </a>
28
+ </ng-template>
29
+
30
+ <ng-template #empty>
31
+ <div class="component image {{ styles }}">
32
+ <div class="component-content">
33
+ <span class="is-empty-hint">Image</span>
34
+ </div>
35
+ </div>
36
+ </ng-template>
@@ -0,0 +1,67 @@
1
+ import { Component, OnInit, OnDestroy, ViewChild, TemplateRef } from '@angular/core';
2
+ import { Subscription } from 'rxjs';
3
+ import { EditMode, ImageField } from '@sitecore-jss/sitecore-jss-angular';
4
+ import { SxaComponent } from '../sxa.component';
5
+ import { JssContextService } from '../../jss-context.service';
6
+
7
+ @Component({
8
+ selector: 'app-image',
9
+ templateUrl: './image.component.html',
10
+ })
11
+ export class ImageComponent extends SxaComponent implements OnInit, OnDestroy {
12
+ @ViewChild('default', { static: true }) defaultVariant: TemplateRef<any>;
13
+ @ViewChild('banner', { static: true }) bannerVariant: TemplateRef<any>;
14
+ classHeroBannerEmpty = '';
15
+ backgroundStyle = {};
16
+ modifyImageProps = {};
17
+ isEditing = false;
18
+ private contextSubscription: Subscription;
19
+
20
+ constructor(private jssContext: JssContextService) {
21
+ super();
22
+ }
23
+
24
+ ngOnInit() {
25
+ super.ngOnInit();
26
+
27
+ const imageField = this.rendering.fields?.Image as ImageField;
28
+ this.backgroundStyle = imageField?.value?.src && {
29
+ 'background-image': `url('${imageField.value.src}')`,
30
+ };
31
+
32
+ this.contextSubscription = this.jssContext.state.subscribe((newState) => {
33
+ this.isEditing = newState.sitecore && newState.sitecore.context.pageEditing;
34
+
35
+ this.classHeroBannerEmpty =
36
+ this.isEditing && imageField?.value?.class === 'scEmptyImage' ? 'hero-banner-empty' : '';
37
+
38
+ const isMetadataMode = newState.sitecore?.context?.editMode === EditMode.Metadata;
39
+ this.modifyImageProps = !isMetadataMode
40
+ ? {
41
+ ...imageField,
42
+ editable: imageField?.editable
43
+ ?.replace(`width="${imageField?.value?.width}"`, 'width="100%"')
44
+ .replace(`height="${imageField?.value?.height}"`, 'height="100%"'),
45
+ }
46
+ : {
47
+ ...imageField,
48
+ value: {
49
+ ...imageField?.value,
50
+ style: { width: '100%', height: '100%' },
51
+ },
52
+ };
53
+ });
54
+ }
55
+
56
+ ngOnDestroy() {
57
+ if (this.contextSubscription) {
58
+ this.contextSubscription.unsubscribe();
59
+ }
60
+ }
61
+
62
+ public get variant(): TemplateRef<any> {
63
+ return this.rendering.params?.FieldNames === 'Banner'
64
+ ? this.bannerVariant
65
+ : this.defaultVariant;
66
+ }
67
+ }
@@ -0,0 +1,15 @@
1
+ <div class="component-content">
2
+ <ng-container *ngIf="title; else defaultTitle">
3
+ <h3 *scText="title"></h3>
4
+ </ng-container>
5
+ <ul>
6
+ <li *ngFor="let fieldLink of fieldLinks; index as i" [ngClass]="getFieldLinkClass(i)">
7
+ <div class="field-link">
8
+ <a *scLink="fieldLink"></a>
9
+ </div>
10
+ </li>
11
+ </ul>
12
+ </div>
13
+ <ng-template #defaultTitle>
14
+ <span class="is-empty-hint">Link list</span>
15
+ </ng-template>
@@ -0,0 +1,41 @@
1
+ import { Component, OnInit } from '@angular/core';
2
+ import { SxaComponent } from '../sxa.component';
3
+ import { Field, LinkField, SxaLinkListFields } from '@sitecore-jss/sitecore-jss-angular';
4
+
5
+ @Component({
6
+ selector: 'app-link-list',
7
+ templateUrl: './link-list.component.html',
8
+ host: {
9
+ 'class': 'component link-list',
10
+ '[class]': 'styles',
11
+ '[attr.id]': 'id',
12
+ }
13
+ })
14
+ export class LinkListComponent extends SxaComponent<SxaLinkListFields> implements OnInit {
15
+ title?: Field<string>;
16
+ fieldLinks: LinkField[] = [];
17
+
18
+ getFieldLinkClass(index: number): string {
19
+ let className = `item${index}`;
20
+ className += (index + 1) % 2 == 0 ? ' even' : ' odd';
21
+ if (index === 0) {
22
+ className += ' first';
23
+ }
24
+ if (index + 1 === this.fieldLinks.length) {
25
+ className += ' last';
26
+ }
27
+ return className;
28
+ }
29
+
30
+ ngOnInit() {
31
+ super.ngOnInit();
32
+ const datasource = this.rendering.fields?.data?.datasource;
33
+ if (datasource) {
34
+ this.title = datasource.field?.title as Field<string>;
35
+ datasource.children.results.forEach(item => {
36
+ if (item.field?.link)
37
+ this.fieldLinks.push(item.field.link as LinkField);
38
+ });
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,23 @@
1
+ <li [class]="cssClasses" [ngClass]="{ active: isActive }" tabIndex="0">
2
+ <div [ngClass]="{ 'navigation-title': true, child: hasChildren }" (click)="isActive = !isActive">
3
+ <a *scLink="linkField" (click)="onClick($event)">
4
+ <ng-container *ngIf="navItemFields.NavigationTitle"
5
+ ><span *scText="navItemFields.NavigationTitle"></span
6
+ ></ng-container>
7
+ <ng-container *ngIf="!navItemFields.NavigationTitle && navItemFields.Title">
8
+ <span *scText="navItemFields.Title"></span
9
+ ></ng-container>
10
+ <ng-container *ngIf="!navItemFields.NavigationTitle && !navItemFields.Title">{{
11
+ navItemFields.DisplayName
12
+ }}</ng-container>
13
+ </a>
14
+ </div>
15
+ <ul *ngIf="hasChildren" class="clearfix">
16
+ <app-navigation-item
17
+ *ngFor="let childNavItemFields of navItemFields.Children"
18
+ [navItemFields]="childNavItemFields"
19
+ [relativeLevel]="childrenRelativeLevel"
20
+ (childLinkClickEvent)="onClick($event)"
21
+ ></app-navigation-item>
22
+ </ul>
23
+ </li>
@@ -0,0 +1,65 @@
1
+ import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
2
+ import { LinkField } from '@sitecore-jss/sitecore-jss-angular';
3
+ import { Field } from '@sitecore-jss/sitecore-jss-angular';
4
+
5
+ export interface NavItemFields {
6
+ Id: string;
7
+ DisplayName: string;
8
+ Title: Field<string>;
9
+ NavigationTitle: Field<string>;
10
+ Href: string;
11
+ Querystring: string;
12
+ Children: Array<NavItemFields>;
13
+ Styles: string[];
14
+ }
15
+
16
+ @Component({
17
+ selector: 'app-navigation-item',
18
+ templateUrl: './navigation-item.component.html',
19
+ })
20
+ export class NavigationItemComponent implements OnInit {
21
+ @Input() navItemFields: NavItemFields;
22
+ @Input() relativeLevel: number;
23
+ @Output() childLinkClickEvent: EventEmitter<Event> = new EventEmitter<Event>();
24
+ cssClasses = '';
25
+ isActive = false;
26
+ linkField = {};
27
+ childrenRelativeLevel = 0;
28
+ hasChildren = false;
29
+
30
+ constructor() {}
31
+
32
+ ngOnInit() {
33
+ this.cssClasses = `${this.navItemFields.Styles.concat('rel-level' + this.relativeLevel).join(
34
+ ' '
35
+ )}`;
36
+ this.linkField = this.getLinkField(this.navItemFields);
37
+ this.hasChildren = this.navItemFields.Children && this.navItemFields.Children.length != 0;
38
+ this.childrenRelativeLevel = this.relativeLevel + 1;
39
+ }
40
+
41
+ onClick(event: Event) {
42
+ this.childLinkClickEvent.emit(event);
43
+ }
44
+
45
+ private getLinkField = (navItemFields: NavItemFields): LinkField => ({
46
+ value: {
47
+ href: navItemFields.Href,
48
+ title: this.getLinkTitle(navItemFields),
49
+ querystring: navItemFields.Querystring,
50
+ },
51
+ });
52
+
53
+ private getLinkTitle = (navItemFields: NavItemFields): string | undefined => {
54
+ let title;
55
+ if (navItemFields.NavigationTitle?.value) {
56
+ title = navItemFields.NavigationTitle.value.toString();
57
+ } else if (navItemFields.Title?.value) {
58
+ title = navItemFields.Title.value.toString();
59
+ } else {
60
+ title = navItemFields.DisplayName;
61
+ }
62
+
63
+ return title;
64
+ };
65
+ }
@@ -0,0 +1,21 @@
1
+ <label class="menu-mobile-navigate-wrapper">
2
+ <input
3
+ type="checkbox"
4
+ class="menu-mobile-navigate"
5
+ [checked]="isOpenMenu"
6
+ (change)="toggleMenu($event)"
7
+ />
8
+ <div class="menu-humburger"></div>
9
+ <div class="component-content">
10
+ <nav>
11
+ <ul class="clearfix">
12
+ <app-navigation-item
13
+ *ngFor="let navItemFields of rendering.fields"
14
+ [navItemFields]="navItemFields"
15
+ [relativeLevel]="baseLevel"
16
+ (childLinkClickEvent)="toggleMenu($event, false)"
17
+ ></app-navigation-item>
18
+ </ul>
19
+ </nav>
20
+ </div>
21
+ </label>
@@ -0,0 +1,49 @@
1
+ import { Component, OnInit, OnDestroy } from '@angular/core';
2
+ import { Subscription } from 'rxjs';
3
+ import { SxaComponent } from '../sxa.component';
4
+ import { JssContextService } from '../../jss-context.service';
5
+
6
+ @Component({
7
+ selector: 'app-navigation',
8
+ templateUrl: './navigation.component.html',
9
+ host: {
10
+ 'class': 'component navigation',
11
+ '[id]': 'id',
12
+ '[class]': 'styles + " " + rendering.params?.GridParameters',
13
+ },
14
+ })
15
+ export class NavigationComponent extends SxaComponent implements OnInit, OnDestroy {
16
+ isEditing = false;
17
+ private contextSubscription: Subscription;
18
+ isOpenMenu = false;
19
+ baseLevel = 1;
20
+
21
+ constructor(private jssContext: JssContextService) {
22
+ super();
23
+ }
24
+
25
+ ngOnInit() {
26
+ super.ngOnInit();
27
+ this.contextSubscription = this.jssContext.state.subscribe((newState) => {
28
+ this.isEditing = newState.sitecore && newState.sitecore.context.pageEditing;
29
+ });
30
+ }
31
+
32
+ ngOnDestroy() {
33
+ if (this.contextSubscription) {
34
+ this.contextSubscription.unsubscribe();
35
+ }
36
+ }
37
+
38
+ toggleMenu(event: Event, flag?: boolean) {
39
+ if (event && this.isEditing) {
40
+ event.preventDefault();
41
+ }
42
+
43
+ if (flag !== undefined) {
44
+ this.isOpenMenu = flag;
45
+ }
46
+
47
+ this.isOpenMenu = !this.isOpenMenu;
48
+ }
49
+ }
@@ -0,0 +1,5 @@
1
+ <div class="component-content">
2
+ <div class="field-content">
3
+ <div *scRichText="content || contextContent"></div>
4
+ </div>
5
+ </div>
@@ -0,0 +1,39 @@
1
+ import { Component, OnDestroy, OnInit } from '@angular/core';
2
+ import { RichTextField } from '@sitecore-jss/sitecore-jss-angular';
3
+ import { JssContextService } from '../../jss-context.service';
4
+ import { SxaComponent } from './../sxa.component';
5
+ import { Subscription } from 'rxjs';
6
+
7
+ @Component({
8
+ selector: 'app-page-content',
9
+ templateUrl: './page-content.component.html',
10
+ host: {
11
+ 'class': 'component content',
12
+ '[class]': 'styles',
13
+ '[id]': 'id',
14
+ }
15
+ })
16
+ export class PageContentComponent extends SxaComponent implements OnInit, OnDestroy {
17
+ content?: RichTextField;
18
+ contextContent?: RichTextField;
19
+ private contextSubscription: Subscription;
20
+
21
+ constructor(private jssContext: JssContextService) {
22
+ super();
23
+ }
24
+ ngOnInit() {
25
+ super.ngOnInit();
26
+
27
+ this.content = this.rendering.fields?.Content as RichTextField;
28
+ this.contextSubscription = this.jssContext.state.subscribe((newState) => {
29
+ this.contextContent =
30
+ newState.sitecore && (newState.sitecore.route.fields.Content as RichTextField);
31
+ });
32
+ }
33
+
34
+ ngOnDestroy() {
35
+ if (this.contextSubscription) {
36
+ this.contextSubscription.unsubscribe();
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,15 @@
1
+ import { Component, OnInit } from '@angular/core';
2
+ import { SxaComponent } from '../sxa.component';
3
+
4
+ @Component({
5
+ selector: 'app-partial-design-dynamic-placeholder',
6
+ templateUrl: './partial-design-dynamic-placeholder.component.html',
7
+ })
8
+ export class PartialDesignDynamicPlaceholderComponent extends SxaComponent implements OnInit {
9
+ sig: string;
10
+ ngOnInit() {
11
+ super.ngOnInit();
12
+
13
+ this.sig = this.rendering.params?.sig || '';
14
+ }
15
+ }
@@ -0,0 +1,21 @@
1
+ <div class="component-content">
2
+ <ng-container *ngIf="rendering.fields; else empty">
3
+ <div class="field-promoicon">
4
+ <img *scImage="rendering.fields.PromoIcon" />
5
+ </div>
6
+ <div class="promo-text">
7
+ <div>
8
+ <div class="field-promotext">
9
+ <div *scRichText="rendering.fields.PromoText"></div>
10
+ </div>
11
+ </div>
12
+ <div class="field-promolink">
13
+ <a *scLink="rendering.fields.PromoLink"></a>
14
+ </div>
15
+ </div>
16
+ </ng-container>
17
+ </div>
18
+
19
+ <ng-template #empty>
20
+ <span className="is-empty-hint">Promo</span>
21
+ </ng-template>
@@ -0,0 +1,13 @@
1
+ import { Component } from '@angular/core';
2
+ import { SxaComponent } from '../sxa.component';
3
+
4
+ @Component({
5
+ selector: 'app-promo',
6
+ templateUrl: './promo.component.html',
7
+ host: {
8
+ 'class': 'component promo',
9
+ '[class]': "styles",
10
+ '[id]': "id",
11
+ },
12
+ })
13
+ export class PromoComponent extends SxaComponent {}
@@ -1,13 +1,8 @@
1
- <div
2
- class="component rich-text {{ styles }}"
3
- [attr.id]="id"
4
- >
5
- <div class="component-content">
6
- <ng-container *ngIf="text; else emptyHint">
7
- <div *scRichText="text"></div>
8
- </ng-container>
9
- <ng-template #emptyHint>
10
- <span class="is-empty-hint">Rich text</span>
11
- </ng-template>
12
- </div>
1
+ <div class="component-content">
2
+ <ng-container *ngIf="text; else emptyHint">
3
+ <div *scRichText="text"></div>
4
+ </ng-container>
5
+ <ng-template #emptyHint>
6
+ <span class="is-empty-hint">Rich text</span>
7
+ </ng-template>
13
8
  </div>
@@ -1,10 +1,15 @@
1
- import { Component, OnInit } from '@angular/core';
1
+ import { Component, OnInit } from '@angular/core';
2
2
  import { Field } from '@sitecore-jss/sitecore-jss-angular';
3
3
  import { SxaComponent } from '../sxa.component';
4
4
 
5
5
  @Component({
6
6
  selector: 'app-richtext',
7
7
  templateUrl: './richtext.component.html',
8
+ host: {
9
+ 'class': 'component rich-text',
10
+ '[class]': "styles",
11
+ "[attr.id]": "id"
12
+ },
8
13
  })
9
14
  export class RichTextComponent extends SxaComponent implements OnInit {
10
15
  text?: Field<string>;
@@ -0,0 +1,11 @@
1
+ <div
2
+ *ngFor="let ph of enabledPlaceholders"
3
+ class="container-fluid"
4
+ [ngClass]="getRowClass(+ph - 1)"
5
+ >
6
+ <div>
7
+ <div class="row">
8
+ <sc-placeholder [name]="getPlaceholderName(ph)" [rendering]="rendering"> </sc-placeholder>
9
+ </div>
10
+ </div>
11
+ </div>
@@ -0,0 +1,35 @@
1
+ import { Component } from '@angular/core';
2
+ import { SxaComponent } from '../sxa.component';
3
+
4
+ @Component({
5
+ selector: 'app-row-splitter',
6
+ templateUrl: './row-splitter.component.html',
7
+ host: {
8
+ "class": "component row-splitter",
9
+ "[class]": "rowSplitterStyles",
10
+ "[id]": "id"
11
+ }
12
+ })
13
+ export class RowSplitterComponent extends SxaComponent {
14
+ get rowSplitterStyles(): string {
15
+ return `${this.rendering.params.GridParameters ?? ''} ${this.rendering.params.Styles ??
16
+ ''}`.trimEnd();
17
+ }
18
+
19
+ get rowStyles(): string[] {
20
+ return Array.from({ length: 8 }, (_, i) => this.rendering.params[`Styles${i + 1}`]);
21
+ }
22
+
23
+ get enabledPlaceholders(): string[] {
24
+ return this.rendering.params.EnabledPlaceholders.split(',');
25
+ }
26
+
27
+ getRowClass(index: number): string {
28
+ const styleClass = this.rowStyles[index] || '';
29
+ return `${styleClass}`.trim();
30
+ }
31
+
32
+ getPlaceholderName(ph: string): string {
33
+ return `row-${ph}-{*}`;
34
+ }
35
+ }
@@ -1,9 +1,9 @@
1
- import { OnInit, Input, Directive } from '@angular/core';
2
- import { ComponentRendering } from '@sitecore-jss/sitecore-jss-angular';
1
+ import { OnInit, Input, Directive } from '@angular/core';
2
+ import { ComponentFields, ComponentRendering } from '@sitecore-jss/sitecore-jss-angular';
3
3
 
4
4
  @Directive()
5
- export abstract class SxaComponent implements OnInit {
6
- @Input() rendering: ComponentRendering;
5
+ export abstract class SxaComponent<FieldType = ComponentFields> implements OnInit {
6
+ @Input() rendering: ComponentRendering<FieldType>;
7
7
 
8
8
  id?: string;
9
9
  styles?: string;
@@ -0,0 +1,10 @@
1
+ <div clas="component-content">
2
+ <div class="field-title">
3
+ <ng-container *ngIf="!pageEditing; else textOnly">
4
+ <a *scLink="link"></a>
5
+ </ng-container>
6
+ </div>
7
+ </div>
8
+ <ng-template #textOnly>
9
+ <span *scText="text"></span>
10
+ </ng-template>