create-sitecore-jss 20.0.0-canary.78
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/LICENSE.MD +202 -0
- package/dist/InitializerFactory.js +49 -0
- package/dist/common/Initializer.js +2 -0
- package/dist/common/args/base.js +2 -0
- package/dist/common/args/styleguide.js +2 -0
- package/dist/common/prompts/base.js +40 -0
- package/dist/common/prompts/styleguide.js +28 -0
- package/dist/common/steps/index.js +13 -0
- package/dist/common/steps/install.js +46 -0
- package/dist/common/steps/next.js +60 -0
- package/dist/common/steps/transform.js +185 -0
- package/dist/common/utils/cmd.js +39 -0
- package/dist/common/utils/helpers.js +92 -0
- package/dist/index.js +91 -0
- package/dist/init-runner.js +50 -0
- package/dist/initializers/nextjs/args.js +2 -0
- package/dist/initializers/nextjs/index.js +65 -0
- package/dist/initializers/nextjs/prompts.js +19 -0
- package/dist/initializers/nextjs/remove-dev-dependencies.js +24 -0
- package/dist/initializers/nextjs-styleguide/index.js +49 -0
- package/dist/templates/nextjs/.env +49 -0
- package/dist/templates/nextjs/.eslintrc +25 -0
- package/dist/templates/nextjs/.gitattributes +11 -0
- package/dist/templates/nextjs/.gitignore +33 -0
- package/dist/templates/nextjs/.graphql-let.yml +10 -0
- package/dist/templates/nextjs/.prettierignore +1 -0
- package/dist/templates/nextjs/.prettierrc +8 -0
- package/dist/templates/nextjs/LICENSE.txt +202 -0
- package/dist/templates/nextjs/README.md +3 -0
- package/dist/templates/nextjs/next-env.d.ts +6 -0
- package/dist/templates/nextjs/next.config.js +56 -0
- package/dist/templates/nextjs/package.json +88 -0
- package/dist/templates/nextjs/public/favicon.ico +0 -0
- package/dist/templates/nextjs/public/sc_logo.svg +20 -0
- package/dist/templates/nextjs/scripts/bootstrap.ts +40 -0
- package/dist/templates/nextjs/scripts/fetch-graphql-introspection-data.ts +49 -0
- package/dist/templates/nextjs/scripts/generate-component-factory.ts +95 -0
- package/dist/templates/nextjs/scripts/generate-config.ts +85 -0
- package/dist/templates/nextjs/scripts/generate-plugins.ts +103 -0
- package/dist/templates/nextjs/scripts/scaffold-component.ts +89 -0
- package/dist/templates/nextjs/scripts/templates/component-factory.ts +119 -0
- package/dist/templates/nextjs/scripts/templates/component-src.ts +27 -0
- package/dist/templates/nextjs/scripts/utils.ts +59 -0
- package/dist/templates/nextjs/sitecore/config/{{appName}}.config +151 -0
- package/dist/templates/nextjs/src/Layout.tsx +53 -0
- package/dist/templates/nextjs/src/Navigation.tsx +27 -0
- package/dist/templates/nextjs/src/NotFound.tsx +19 -0
- package/dist/templates/nextjs/src/assets/app.css +28 -0
- package/dist/templates/nextjs/src/components/ContentBlock.tsx +24 -0
- package/dist/templates/nextjs/src/lib/component-props/index.ts +23 -0
- package/dist/templates/nextjs/src/lib/data-fetcher.ts +16 -0
- package/dist/templates/nextjs/src/lib/dictionary-service-factory.ts +30 -0
- package/dist/templates/nextjs/src/lib/layout-service-factory.ts +25 -0
- package/dist/templates/nextjs/src/lib/next-config/plugins/graphql.js +32 -0
- package/dist/templates/nextjs/src/lib/next-config/plugins/monorepo.js +27 -0
- package/dist/templates/nextjs/src/lib/page-props-factory/index.ts +50 -0
- package/dist/templates/nextjs/src/lib/page-props-factory/plugins/componentProps.ts +38 -0
- package/dist/templates/nextjs/src/lib/page-props-factory/plugins/normalMode.ts +75 -0
- package/dist/templates/nextjs/src/lib/page-props-factory/plugins/previewMode.ts +27 -0
- package/dist/templates/nextjs/src/lib/page-props.ts +16 -0
- package/dist/templates/nextjs/src/lib/sitemap-fetcher/index.ts +25 -0
- package/dist/templates/nextjs/src/lib/sitemap-fetcher/plugins/graphqlSitemapService.ts +36 -0
- package/dist/templates/nextjs/src/pages/404.tsx +5 -0
- package/dist/templates/nextjs/src/pages/[[...path]].tsx +91 -0
- package/dist/templates/nextjs/src/pages/_app.tsx +19 -0
- package/dist/templates/nextjs/src/pages/_error.tsx +35 -0
- package/dist/templates/nextjs/src/pages/api/editing/data/[key].ts +24 -0
- package/dist/templates/nextjs/src/pages/api/editing/render.ts +30 -0
- package/dist/templates/nextjs/src/temp/.gitignore +3 -0
- package/dist/templates/nextjs/src/temp/GraphQLIntrospectionResult.json +22216 -0
- package/dist/templates/nextjs/tsconfig.json +42 -0
- package/dist/templates/nextjs/tsconfig.scripts.json +6 -0
- package/dist/templates/nextjs-styleguide/data/component-content/.gitignore +0 -0
- package/dist/templates/nextjs-styleguide/data/component-content/Styleguide/ContentReuse/LoremIpsumContentBlock/en.yml +9 -0
- package/dist/templates/nextjs-styleguide/data/content/.gitignore +0 -0
- package/dist/templates/nextjs-styleguide/data/content/Styleguide/ContentListField/Item1/en.yml +6 -0
- package/dist/templates/nextjs-styleguide/data/content/Styleguide/ContentListField/Item2/en.yml +6 -0
- package/dist/templates/nextjs-styleguide/data/content/Styleguide/ItemLinkField/Item1/en.yml +6 -0
- package/dist/templates/nextjs-styleguide/data/content/Styleguide/ItemLinkField/Item2/en.yml +6 -0
- package/dist/templates/nextjs-styleguide/data/dictionary/en.yml +4 -0
- package/dist/templates/nextjs-styleguide/data/dictionary/{{language}}.yml +4 -0
- package/dist/templates/nextjs-styleguide/data/media/files/jss.pdf +0 -0
- package/dist/templates/nextjs-styleguide/data/media/img/jss_logo.png +0 -0
- package/dist/templates/nextjs-styleguide/data/media/img/sc_logo.png +0 -0
- package/dist/templates/nextjs-styleguide/data/routes/en.yml +63 -0
- package/dist/templates/nextjs-styleguide/data/routes/graphql/en.yml +27 -0
- package/dist/templates/nextjs-styleguide/data/routes/graphql/sample-1/en.yml +9 -0
- package/dist/templates/nextjs-styleguide/data/routes/graphql/sample-2/en.yml +9 -0
- package/dist/templates/nextjs-styleguide/data/routes/styleguide/custom-route-type/en.yml +12 -0
- package/dist/templates/nextjs-styleguide/data/routes/styleguide/en.yml +246 -0
- package/dist/templates/nextjs-styleguide/data/routes/styleguide/{{language}}.yml +25 -0
- package/dist/templates/nextjs-styleguide/data/routes/{{language}}.yml +4 -0
- package/dist/templates/nextjs-styleguide/package.json +13 -0
- package/dist/templates/nextjs-styleguide/scripts/disconnected-mode-proxy.ts +48 -0
- package/dist/templates/nextjs-styleguide/scripts/scaffold-component.ts +130 -0
- package/dist/templates/nextjs-styleguide/scripts/templates/component-manifest.ts +30 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/component-content.sitecore.ts +117 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/ContentBlock.sitecore.ts +19 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Checkbox.sitecore.ts +23 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-ContentList.sitecore.ts +32 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Custom.sitecore.ts +23 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Date.sitecore.ts +23 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-File.sitecore.ts +20 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Image.sitecore.ts +23 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-ItemLink.sitecore.ts +32 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Link.sitecore.ts +25 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Number.sitecore.ts +20 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-RichText.sitecore.ts +28 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Text.sitecore.ts +28 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/graphql/GraphQL-ConnectedDemo.sitecore.ts +18 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/graphql/GraphQL-IntegratedDemo.sitecore.graphql +71 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/graphql/GraphQL-IntegratedDemo.sitecore.ts +25 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/graphql/GraphQL-Layout.sitecore.ts +15 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-ComponentParams.sitecore.ts +20 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-CustomRouteType.sitecore.ts +31 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Layout-Reuse.sitecore.ts +20 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Layout-Tabs-Tab.sitecore.ts +23 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Layout-Tabs.sitecore.ts +20 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Layout.sitecore.ts +15 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Multilingual.sitecore.ts +26 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-RouteFields.sitecore.ts +22 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Section.sitecore.ts +16 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-SitecoreContext.sitecore.ts +19 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Tracking.sitecore.ts +19 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/config.js +5 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/content.sitecore.ts +117 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/dictionary.sitecore.ts +52 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/placeholders.sitecore.ts +21 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/routes.sitecore.ts +88 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/templates/Styleguide-ContentList-Template.sitecore.ts +12 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/templates/Styleguide-Explanatory-Component.sitecore.ts +20 -0
- package/dist/templates/nextjs-styleguide/sitecore/definitions/templates/Styleguide-ItemLink-Template.sitecore.ts +13 -0
- package/dist/templates/nextjs-styleguide/src/Navigation.tsx +41 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Checkbox.tsx +52 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-ContentList.tsx +58 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Custom.tsx +25 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Date.tsx +55 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-File.tsx +30 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Image.tsx +58 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-ItemLink.tsx +50 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Link.tsx +46 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Number.tsx +34 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-RichText.tsx +35 -0
- package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Text.tsx +43 -0
- package/dist/templates/nextjs-styleguide/src/components/graphql/GraphQL-ConnectedDemo.dynamic.graphql +69 -0
- package/dist/templates/nextjs-styleguide/src/components/graphql/GraphQL-ConnectedDemo.dynamic.tsx +148 -0
- package/dist/templates/nextjs-styleguide/src/components/graphql/GraphQL-IntegratedDemo.tsx +130 -0
- package/dist/templates/nextjs-styleguide/src/components/graphql/GraphQL-Layout.tsx +37 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-ComponentParams.tsx +47 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-CustomRouteType.tsx +37 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Layout-Reuse.tsx +45 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Layout-Tabs-Tab.tsx +41 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Layout-Tabs.tsx +111 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Layout.tsx +68 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Multilingual.tsx +50 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-RouteFields.tsx +37 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Section.tsx +22 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-SitecoreContext.tsx +25 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Specimen.tsx +41 -0
- package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Tracking.tsx +341 -0
- package/dist/templates/nextjs-styleguide/src/lib/component-props/styleguide.ts +11 -0
- package/dist/templates/nextjs-styleguide/src/lib/next-config/plugins/disconnected.js +43 -0
- package/dist/templates/nextjs-styleguide/src/lib/next-config/plugins/styleguide.js +10 -0
- package/dist/templates/nextjs-styleguide/src/lib/sitemap-fetcher/plugins/disconnectedSitemapService.ts +46 -0
- package/dist/templates/nextjs-styleguide/src/pages/_app.tsx +33 -0
- package/package.json +61 -0
package/dist/templates/nextjs-styleguide/src/components/graphql/GraphQL-ConnectedDemo.dynamic.tsx
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Text,
|
|
4
|
+
Link,
|
|
5
|
+
GetServerSideComponentProps,
|
|
6
|
+
GetStaticComponentProps,
|
|
7
|
+
useComponentProps,
|
|
8
|
+
constants,
|
|
9
|
+
GraphQLRequestClient,
|
|
10
|
+
withDatasourceCheck,
|
|
11
|
+
resetEditorChromes,
|
|
12
|
+
} from '@sitecore-jss/sitecore-jss-nextjs';
|
|
13
|
+
import NextLink from 'next/link';
|
|
14
|
+
import {
|
|
15
|
+
ConnectedDemoQueryDocument,
|
|
16
|
+
<%- appPrefix ? `${helper.getPascalCaseName(appName)}` : "" %>AppRoute as AppRoute,
|
|
17
|
+
Item,
|
|
18
|
+
<%- appPrefix ? `${helper.getPascalCaseName(appName)}` : "" %>GraphQlConnectedDemo as GrapQLConnectedDemoDatasource,
|
|
19
|
+
} from './GraphQL-ConnectedDemo.dynamic.graphql';
|
|
20
|
+
import { ComponentProps } from 'lib/component-props';
|
|
21
|
+
import config from 'temp/config';
|
|
22
|
+
|
|
23
|
+
type RouteItem = AppRoute & Item;
|
|
24
|
+
|
|
25
|
+
type GraphQLConnectedDemoData = {
|
|
26
|
+
datasource: GrapQLConnectedDemoDatasource;
|
|
27
|
+
contextItem: RouteItem;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const GraphQLConnectedDemo = (props: ComponentProps): JSX.Element => {
|
|
31
|
+
const data = useComponentProps<GraphQLConnectedDemoData>(props.rendering.uid);
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
resetEditorChromes();
|
|
35
|
+
}, []);
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div data-e2e-id="graphql-connected">
|
|
39
|
+
<h2>GraphQL Connected Demo</h2>
|
|
40
|
+
|
|
41
|
+
<p>
|
|
42
|
+
Connected GraphQL executes GraphQL queries directly against the Sitecore GraphQL endpoint.
|
|
43
|
+
This example runs the query server-side using component-level <code>getStaticProps</code>/
|
|
44
|
+
<code>getServerSideProps</code>, a feature of the Sitecore JSS Next.js SDK. These are
|
|
45
|
+
aggregated during the the Next.js page-level <code>getStaticProps</code>/
|
|
46
|
+
<code>getServerSideProps</code> execution.
|
|
47
|
+
</p>
|
|
48
|
+
|
|
49
|
+
{data && data.datasource && (
|
|
50
|
+
<div>
|
|
51
|
+
<h4>Datasource Item (via Connected GraphQL)</h4>
|
|
52
|
+
id: {data.datasource.id}
|
|
53
|
+
<br />
|
|
54
|
+
name: {data.datasource.name}
|
|
55
|
+
<br />
|
|
56
|
+
sample1: {data.datasource.sample1?.value}
|
|
57
|
+
<br />
|
|
58
|
+
sample1 (editable): <Text field={data.datasource.sample1?.jsonValue} />
|
|
59
|
+
<br />
|
|
60
|
+
sample2:
|
|
61
|
+
<br />
|
|
62
|
+
<ul>
|
|
63
|
+
<li>text: {data.datasource.sample2?.text}</li>
|
|
64
|
+
<li>url: {data.datasource.sample2?.url}</li>
|
|
65
|
+
<li>target: {data.datasource.sample2?.target}</li>
|
|
66
|
+
<li>
|
|
67
|
+
editable: <Link field={data.datasource.sample2?.jsonValue} />
|
|
68
|
+
</li>
|
|
69
|
+
<li>field type: {data.datasource.sample2?.definition?.type}</li>
|
|
70
|
+
<li>field is shared?: {data.datasource.sample2?.definition?.shared.toString()}</li>
|
|
71
|
+
</ul>
|
|
72
|
+
</div>
|
|
73
|
+
)}
|
|
74
|
+
{data && data.contextItem && (
|
|
75
|
+
<div>
|
|
76
|
+
<h4>Route Item (via Connected GraphQL)</h4>
|
|
77
|
+
id: {data.contextItem.id}
|
|
78
|
+
<br />
|
|
79
|
+
page title: {data.contextItem.pageTitle?.value}
|
|
80
|
+
<br />
|
|
81
|
+
children:
|
|
82
|
+
<ul>
|
|
83
|
+
{data.contextItem.children.results.map((child) => {
|
|
84
|
+
const routeItem = child as RouteItem;
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<li key={routeItem.id}>
|
|
88
|
+
<NextLink href={routeItem.url.path}>{routeItem.pageTitle?.value}</NextLink>
|
|
89
|
+
(editable title too! <Text field={routeItem.pageTitle?.jsonValue} />)
|
|
90
|
+
</li>
|
|
91
|
+
);
|
|
92
|
+
})}
|
|
93
|
+
</ul>
|
|
94
|
+
</div>
|
|
95
|
+
)}
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Will be called during SSG
|
|
102
|
+
* @param {ComponentRendering} rendering
|
|
103
|
+
* @param {LayoutServiceData} layoutData
|
|
104
|
+
* @param {GetStaticPropsContext} context
|
|
105
|
+
*/
|
|
106
|
+
export const getStaticProps: GetStaticComponentProps = async (rendering, layoutData) => {
|
|
107
|
+
if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const graphQLClient = new GraphQLRequestClient(config.graphQLEndpoint, {
|
|
112
|
+
apiKey: config.sitecoreApiKey,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const result = await graphQLClient.request<GraphQLConnectedDemoData>(ConnectedDemoQueryDocument, {
|
|
116
|
+
datasource: rendering.dataSource,
|
|
117
|
+
contextItem: layoutData?.sitecore?.route?.itemId,
|
|
118
|
+
language: layoutData?.sitecore?.context?.language,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
return result;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Will be called during SSR
|
|
126
|
+
* @param {ComponentRendering} rendering
|
|
127
|
+
* @param {LayoutServiceData} layoutData
|
|
128
|
+
* @param {GetServerSidePropsContext} context
|
|
129
|
+
*/
|
|
130
|
+
export const getServerSideProps: GetServerSideComponentProps = async (rendering, layoutData) => {
|
|
131
|
+
if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const graphQLClient = new GraphQLRequestClient(config.graphQLEndpoint, {
|
|
136
|
+
apiKey: config.sitecoreApiKey,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const result = await graphQLClient.request<GraphQLConnectedDemoData>(ConnectedDemoQueryDocument, {
|
|
140
|
+
datasource: rendering.dataSource,
|
|
141
|
+
contextItem: layoutData?.sitecore?.route?.itemId,
|
|
142
|
+
language: layoutData?.sitecore?.context?.language,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
return result;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export default withDatasourceCheck()<ComponentProps>(GraphQLConnectedDemo);
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Text, Link, withDatasourceCheck } from '@sitecore-jss/sitecore-jss-nextjs';
|
|
2
|
+
import { ComponentProps } from 'lib/component-props';
|
|
3
|
+
import NextLink from 'next/link';
|
|
4
|
+
|
|
5
|
+
type DataSource = {
|
|
6
|
+
sample1: {
|
|
7
|
+
jsonValue: {
|
|
8
|
+
value: string;
|
|
9
|
+
};
|
|
10
|
+
value: string;
|
|
11
|
+
};
|
|
12
|
+
sample2: {
|
|
13
|
+
definition: {
|
|
14
|
+
type: string;
|
|
15
|
+
shared: boolean;
|
|
16
|
+
};
|
|
17
|
+
jsonValue: {
|
|
18
|
+
value: {
|
|
19
|
+
href: string;
|
|
20
|
+
linktype: string;
|
|
21
|
+
target: string;
|
|
22
|
+
text: string;
|
|
23
|
+
url: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
target: string;
|
|
27
|
+
text: string;
|
|
28
|
+
url: string;
|
|
29
|
+
};
|
|
30
|
+
name: string;
|
|
31
|
+
id: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type Item = {
|
|
35
|
+
id: string;
|
|
36
|
+
url: {
|
|
37
|
+
path: string;
|
|
38
|
+
};
|
|
39
|
+
pageTitle: {
|
|
40
|
+
value: string;
|
|
41
|
+
jsonValue: {
|
|
42
|
+
value: string;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type ItemSearchResults = {
|
|
48
|
+
results: Item[];
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
type GraphQlIntegratedDemoProps = ComponentProps & {
|
|
52
|
+
fields: {
|
|
53
|
+
data: {
|
|
54
|
+
datasource: DataSource;
|
|
55
|
+
contextItem: {
|
|
56
|
+
id: string;
|
|
57
|
+
children: ItemSearchResults;
|
|
58
|
+
pageTitle: {
|
|
59
|
+
value: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const GraphQLIntegratedDemo = (props: GraphQlIntegratedDemoProps): JSX.Element => {
|
|
67
|
+
// Query results in integrated GraphQL replace the normal `fields` data
|
|
68
|
+
// i.e. with { data, }
|
|
69
|
+
const { datasource, contextItem } = props.fields.data;
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<div data-e2e-id="graphql-integrated">
|
|
73
|
+
<h2>GraphQL Integrated Demo</h2>
|
|
74
|
+
|
|
75
|
+
<p>
|
|
76
|
+
Integrated GraphQL executes GraphQL queries within the Layout Service endpoint, and merges
|
|
77
|
+
the query results into the Layout Service result JSON. The query results can be seen by
|
|
78
|
+
inspecting the Layout Service response.
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
{datasource && (
|
|
82
|
+
<div>
|
|
83
|
+
<h4>Datasource Item (via Integrated GraphQL)</h4>
|
|
84
|
+
id: {datasource.id}
|
|
85
|
+
<br />
|
|
86
|
+
name: {datasource.name}
|
|
87
|
+
<br />
|
|
88
|
+
sample1: {datasource.sample1.value}
|
|
89
|
+
<br />
|
|
90
|
+
sample1 (editable): <Text field={datasource.sample1.jsonValue} />
|
|
91
|
+
<br />
|
|
92
|
+
sample2:
|
|
93
|
+
<br />
|
|
94
|
+
<ul>
|
|
95
|
+
<li>text: {datasource.sample2.text}</li>
|
|
96
|
+
<li>url: {datasource.sample2.url}</li>
|
|
97
|
+
<li>target: {datasource.sample2.target}</li>
|
|
98
|
+
<li>
|
|
99
|
+
editable: <Link field={datasource.sample2.jsonValue} />
|
|
100
|
+
</li>
|
|
101
|
+
<li>field type: {datasource.sample2.definition.type}</li>
|
|
102
|
+
<li>field is shared?: {datasource.sample2.definition.shared.toString()}</li>
|
|
103
|
+
</ul>
|
|
104
|
+
</div>
|
|
105
|
+
)}
|
|
106
|
+
{contextItem && (
|
|
107
|
+
<div>
|
|
108
|
+
<h4>Route Item (via Integrated GraphQL)</h4>
|
|
109
|
+
id: {contextItem.id}
|
|
110
|
+
<br />
|
|
111
|
+
page title: {contextItem.pageTitle.value}
|
|
112
|
+
<br />
|
|
113
|
+
children:
|
|
114
|
+
<ul>
|
|
115
|
+
{contextItem.children.results.map((child: Item) => (
|
|
116
|
+
<li key={child.id}>
|
|
117
|
+
<NextLink href={child.url.path}>
|
|
118
|
+
<a>{child.pageTitle.value}</a>
|
|
119
|
+
</NextLink>
|
|
120
|
+
(editable title too! <Text field={child.pageTitle.jsonValue} />)
|
|
121
|
+
</li>
|
|
122
|
+
))}
|
|
123
|
+
</ul>
|
|
124
|
+
</div>
|
|
125
|
+
)}
|
|
126
|
+
</div>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export default withDatasourceCheck()<GraphQlIntegratedDemoProps>(GraphQLIntegratedDemo);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Placeholder, useSitecoreContext } from '@sitecore-jss/sitecore-jss-nextjs';
|
|
2
|
+
import { ComponentProps } from 'lib/component-props';
|
|
3
|
+
|
|
4
|
+
const GraphQLLayout = ({ rendering }: ComponentProps): JSX.Element => {
|
|
5
|
+
const { sitecoreContext } = useSitecoreContext();
|
|
6
|
+
|
|
7
|
+
const disconnectedMode =
|
|
8
|
+
sitecoreContext.route && sitecoreContext.route.layoutId === 'available-in-connected-mode';
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<div data-e2e-id="graphql-layout">
|
|
12
|
+
{disconnectedMode && (
|
|
13
|
+
<>
|
|
14
|
+
<p>
|
|
15
|
+
This app is running in disconnected mode. GraphQL requires connected mode, headless
|
|
16
|
+
connected mode, or integrated mode to work.
|
|
17
|
+
</p>
|
|
18
|
+
<p>
|
|
19
|
+
Libraries such as <code>graphql-tools</code> can provide GraphQL API mocking
|
|
20
|
+
capabilities, which could enable disconnected GraphQL. This is not supported out of the
|
|
21
|
+
box, however.
|
|
22
|
+
</p>
|
|
23
|
+
<p>
|
|
24
|
+
To view the GraphQL samples, restart the app using <code>jss start:connected</code>
|
|
25
|
+
or deploy the app to Sitecore to run in integrated mode per the JSS
|
|
26
|
+
documentation.
|
|
27
|
+
</p>
|
|
28
|
+
</>
|
|
29
|
+
)}
|
|
30
|
+
{!disconnectedMode && (
|
|
31
|
+
<Placeholder name="<%- helper.getAppPrefix(appPrefix, appName) %>jss-graphql-layout" rendering={rendering} />
|
|
32
|
+
)}
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default GraphQLLayout;
|
package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-ComponentParams.tsx
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import StyleguideSpecimen from './Styleguide-Specimen';
|
|
2
|
+
import { ComponentProps } from 'lib/component-props';
|
|
3
|
+
import { StyleguideSpecimenFields } from 'lib/component-props/styleguide';
|
|
4
|
+
|
|
5
|
+
type StyleguideComponentParamsProps = ComponentProps &
|
|
6
|
+
StyleguideSpecimenFields & {
|
|
7
|
+
params: {
|
|
8
|
+
cssClass: string;
|
|
9
|
+
columns: string;
|
|
10
|
+
useCallToAction: 'false' | 'true';
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const StyleguideComponentParams = (props: StyleguideComponentParamsProps): JSX.Element => {
|
|
15
|
+
// props.params (i.e. props.params.cssClass without destructuring) contains the component's params
|
|
16
|
+
const { cssClass, columns, useCallToAction } = props.params;
|
|
17
|
+
|
|
18
|
+
const columnsArray = columns && [...Array(parseInt(columns))];
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<StyleguideSpecimen {...props} e2eId="styleguide-componentparams">
|
|
22
|
+
<p className={cssClass}>
|
|
23
|
+
The CSS class of this paragraph (<code>{cssClass}</code>) is set using a param
|
|
24
|
+
</p>
|
|
25
|
+
<div>
|
|
26
|
+
{/* Note that all params come in as string values, like this boolean-like param here: */}
|
|
27
|
+
useCallToAction param: <code>{useCallToAction}</code>
|
|
28
|
+
<br />
|
|
29
|
+
param type: <code>{typeof useCallToAction}</code>
|
|
30
|
+
{useCallToAction === 'true' && (
|
|
31
|
+
<div className="alert alert-info">the call to action is shown</div>
|
|
32
|
+
)}
|
|
33
|
+
</div>
|
|
34
|
+
<p>columns param: {columns}</p>
|
|
35
|
+
<div className="row">
|
|
36
|
+
{columnsArray &&
|
|
37
|
+
columnsArray.map((_, index) => (
|
|
38
|
+
<div key={`col-${index}`} className="col-sm">
|
|
39
|
+
Column {index}
|
|
40
|
+
</div>
|
|
41
|
+
))}
|
|
42
|
+
</div>
|
|
43
|
+
</StyleguideSpecimen>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default StyleguideComponentParams;
|
package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-CustomRouteType.tsx
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Link from 'next/link';
|
|
2
|
+
import { useSitecoreContext, Text, RichText, Field } from '@sitecore-jss/sitecore-jss-nextjs';
|
|
3
|
+
|
|
4
|
+
type StyleguideCustomRouteTypeFields = {
|
|
5
|
+
headline: Field<string>;
|
|
6
|
+
author: Field<string>;
|
|
7
|
+
content: Field<string>;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const StyleguideCustomRouteType = (): JSX.Element => {
|
|
11
|
+
// useSitecoreContext() is the magical glue that gives you route-level context access
|
|
12
|
+
// see the context examples in the styleguide for more details.
|
|
13
|
+
// this fancy destructure syntax is essentially equivalent to
|
|
14
|
+
// const fields = props.sitecoreContext.route.fields
|
|
15
|
+
const value = useSitecoreContext();
|
|
16
|
+
const fields = value.sitecoreContext.route?.fields as StyleguideCustomRouteTypeFields;
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div data-e2e-id="styleguide-customroutetype">
|
|
20
|
+
<Text tag="h3" field={fields.headline} />
|
|
21
|
+
|
|
22
|
+
<p>
|
|
23
|
+
<em>
|
|
24
|
+
By <Text field={fields.author} />
|
|
25
|
+
</em>
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
<RichText field={fields.content} />
|
|
29
|
+
|
|
30
|
+
<Link href="/styleguide">
|
|
31
|
+
<a>Return to the Styleguide</a>
|
|
32
|
+
</Link>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default StyleguideCustomRouteType;
|
package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Layout-Reuse.tsx
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Placeholder } from '@sitecore-jss/sitecore-jss-nextjs';
|
|
2
|
+
import StyleguideSpecimen from './Styleguide-Specimen';
|
|
3
|
+
import { ComponentProps } from 'lib/component-props';
|
|
4
|
+
import { StyleguideSpecimenFields } from 'lib/component-props/styleguide';
|
|
5
|
+
|
|
6
|
+
type StyleguideLayoutReuseProps = ComponentProps & StyleguideSpecimenFields;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Demonstrates how to reuse content within JSS. See /data/routes/styleguide/en.yml
|
|
10
|
+
* for the reused content definition sample. This component also demonstrates how to use
|
|
11
|
+
* the Placeholder component's render props API to wrap all components in the placeholder
|
|
12
|
+
* in a column tag (thus creating a horizontally laid out placeholder)
|
|
13
|
+
*/
|
|
14
|
+
const StyleguideLayoutReuse = (props: StyleguideLayoutReuseProps): JSX.Element => (
|
|
15
|
+
<StyleguideSpecimen {...props} e2eId="styleguide-layout-reuse">
|
|
16
|
+
<div className="row">
|
|
17
|
+
{/*
|
|
18
|
+
This placeholder is using _render props_ to enable customizing the markup for each component within.
|
|
19
|
+
In this case, it's placing each component in its own column of a flexbox layout - giving an n-up columnar layout.
|
|
20
|
+
The component itself does not need to know it's living in a columnar layout.
|
|
21
|
+
|
|
22
|
+
There are three render props available:
|
|
23
|
+
renderEach - called once for each content component
|
|
24
|
+
Sitecore Experience Editor markup is automatically rendered in between content components when present
|
|
25
|
+
renderEmpty - called when the placeholder contains no content components. Can be used to wrap the Sitecore EE empty placeholder
|
|
26
|
+
markup in something that's visually correct, like here where we need to wrap it in a column div to make it selectable.
|
|
27
|
+
render - called once and passed _all_ components in the placeholder. Allows custom iteration. EE code markup must be accounted for.
|
|
28
|
+
|
|
29
|
+
Generally speaking stick to renderEach and renderEmpty unless doing something really custom.
|
|
30
|
+
*/}
|
|
31
|
+
<Placeholder
|
|
32
|
+
rendering={props.rendering}
|
|
33
|
+
name="<%- helper.getAppPrefix(appPrefix, appName) %>jss-reuse-example"
|
|
34
|
+
renderEach={(component, index) => (
|
|
35
|
+
<div className="col-sm" key={index}>
|
|
36
|
+
{component}
|
|
37
|
+
</div>
|
|
38
|
+
)}
|
|
39
|
+
renderEmpty={(components) => <div className="col-sm">{components}</div>}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
</StyleguideSpecimen>
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
export default StyleguideLayoutReuse;
|
package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Layout-Tabs-Tab.tsx
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Text,
|
|
3
|
+
RichText,
|
|
4
|
+
Field,
|
|
5
|
+
useSitecoreContext,
|
|
6
|
+
withDatasourceCheck,
|
|
7
|
+
} from '@sitecore-jss/sitecore-jss-nextjs';
|
|
8
|
+
import { ComponentProps } from 'lib/component-props';
|
|
9
|
+
|
|
10
|
+
type StyleguideLayoutTabsTabProps = ComponentProps & {
|
|
11
|
+
fields: {
|
|
12
|
+
content: Field<string>;
|
|
13
|
+
title: Field<string>;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* This is a single tab within the tabs sample component. These are added to the tabs placeholder.
|
|
19
|
+
* This component demonstrates conditionally altering rendering when in the Sitecore Experience Editor to improve
|
|
20
|
+
* author experience.
|
|
21
|
+
*/
|
|
22
|
+
const StyleguideLayoutTabsTab = (props: StyleguideLayoutTabsTabProps): JSX.Element => {
|
|
23
|
+
const { sitecoreContext } = useSitecoreContext();
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div data-e2e-class="styleguide-layout-tabs-tab">
|
|
27
|
+
{/*
|
|
28
|
+
When we're editing the tabs we stack each tab vertically,
|
|
29
|
+
which means there's no regular tab titles rendered.
|
|
30
|
+
So we conditionally render the tab title here, when editing. */}
|
|
31
|
+
{sitecoreContext && sitecoreContext.pageEditing && (
|
|
32
|
+
<Text tag="h5" field={props.fields.title} />
|
|
33
|
+
)}
|
|
34
|
+
|
|
35
|
+
{/* React.Fragment tells React to not use any wrapping tag for the component */}
|
|
36
|
+
<RichText field={props.fields.content} />
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default withDatasourceCheck()<StyleguideLayoutTabsTabProps>(StyleguideLayoutTabsTab);
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import React, { ReactElement } from 'react';
|
|
2
|
+
import { withPlaceholder, withSitecoreContext, Text } from '@sitecore-jss/sitecore-jss-nextjs';
|
|
3
|
+
import StyleguideSpecimen from './Styleguide-Specimen';
|
|
4
|
+
import { ComponentWithContextProps } from 'lib/component-props';
|
|
5
|
+
import { StyleguideSpecimenFields } from 'lib/component-props/styleguide';
|
|
6
|
+
|
|
7
|
+
interface StyleguideLayoutTabsState {
|
|
8
|
+
activeTabIndex: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type StyleguideLayoutTabsProps = ComponentWithContextProps &
|
|
12
|
+
StyleguideSpecimenFields & {
|
|
13
|
+
name: string;
|
|
14
|
+
tabsPlaceholder: ReactElement[];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Demonstrates advanced component techniques in JSS.
|
|
19
|
+
* This example implements a simple-looking tabs component.
|
|
20
|
+
* Each tab is itself a child component added to a placeholder defined on the tabs component.
|
|
21
|
+
* The tab component introspects its child components to render the tab headings (i.e. the tab children render partial content in two places).
|
|
22
|
+
* When this component is edited in Sitecore Experience Editor, the tabbing behavior is turned off and each tab stacks on top of each other
|
|
23
|
+
* for easy inline editing.
|
|
24
|
+
*/
|
|
25
|
+
class StyleguideLayoutTabs extends React.Component<
|
|
26
|
+
StyleguideLayoutTabsProps,
|
|
27
|
+
StyleguideLayoutTabsState
|
|
28
|
+
> {
|
|
29
|
+
constructor(props: StyleguideLayoutTabsProps) {
|
|
30
|
+
super(props);
|
|
31
|
+
|
|
32
|
+
this.state = {
|
|
33
|
+
activeTabIndex: 0,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
this.setActiveTab = this.setActiveTab.bind(this);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
setActiveTab(index: number) {
|
|
40
|
+
this.setState({ activeTabIndex: index });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
render() {
|
|
44
|
+
const { tabsPlaceholder, sitecoreContext } = this.props;
|
|
45
|
+
|
|
46
|
+
let validTabIndex = 0;
|
|
47
|
+
const isEditing = sitecoreContext && sitecoreContext.pageEditing;
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<StyleguideSpecimen {...this.props} e2eId="styleguide-layout-tabs">
|
|
51
|
+
<ul className="nav nav-tabs">
|
|
52
|
+
{/*
|
|
53
|
+
When the page is editing, we hide the tab headings, because they are not updated when xEditor adds or removes a tab rendering.
|
|
54
|
+
Instead, we show the tab header inline with the tab contents (see Styleguide-Layout-Tabs-Tab).
|
|
55
|
+
*/}
|
|
56
|
+
{!isEditing &&
|
|
57
|
+
(tabsPlaceholder || [])
|
|
58
|
+
.filter((tab: ReactElement) => tab.props && tab.props.fields)
|
|
59
|
+
.map((tab: ReactElement, index: number) => (
|
|
60
|
+
<li className="nav-item" key={`tab${index}`}>
|
|
61
|
+
<a
|
|
62
|
+
className={`nav-link ${index === this.state.activeTabIndex ? 'active' : null}`}
|
|
63
|
+
onClick={() => this.setActiveTab(index)}
|
|
64
|
+
href="#t"
|
|
65
|
+
>
|
|
66
|
+
<Text field={tab.props.fields.title} />
|
|
67
|
+
</a>
|
|
68
|
+
</li>
|
|
69
|
+
))}
|
|
70
|
+
</ul>
|
|
71
|
+
<div className="p-3 border-left border-right border-bottom">
|
|
72
|
+
{(tabsPlaceholder || []).map((tab: ReactElement) => {
|
|
73
|
+
const isValid = tab.props && tab.props.fields;
|
|
74
|
+
|
|
75
|
+
// allow experience editor markup components to render
|
|
76
|
+
if (!isValid && isEditing) return tab;
|
|
77
|
+
|
|
78
|
+
validTabIndex += 1;
|
|
79
|
+
|
|
80
|
+
// we render the tab either if it's active - or we're editing,
|
|
81
|
+
// in which case we stack all tabs for visual editing
|
|
82
|
+
if (this.state.activeTabIndex === validTabIndex - 1 || isEditing) {
|
|
83
|
+
return tab;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return null;
|
|
87
|
+
})}
|
|
88
|
+
</div>
|
|
89
|
+
</StyleguideSpecimen>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// This is a _higher order component_ that will wrap our component and inject placeholder
|
|
95
|
+
// data into it as a prop (in this case, props.tabsPlaceholder).
|
|
96
|
+
// this another option compared to using the <Placeholder> component;
|
|
97
|
+
// in this case, chosen because we primarily need access to the _data_
|
|
98
|
+
// of the placeholder.
|
|
99
|
+
const tabsComponentWithPlaceholderInjected = withPlaceholder({
|
|
100
|
+
placeholder: '<%- helper.getAppPrefix(appPrefix, appName) %>jss-tabs',
|
|
101
|
+
prop: 'tabsPlaceholder',
|
|
102
|
+
})(StyleguideLayoutTabs);
|
|
103
|
+
|
|
104
|
+
// We need to know if experience editor is active, to disable the dynamic tab behavior for editing.
|
|
105
|
+
// Using the same technique as injecting the placeholder, we wrap the component again to inject the
|
|
106
|
+
// `sitecoreContext` prop.
|
|
107
|
+
const tabsWithPlaceholderAndSitecoreContext = withSitecoreContext()<StyleguideLayoutTabsProps>(
|
|
108
|
+
tabsComponentWithPlaceholderInjected
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
export default tabsWithPlaceholderAndSitecoreContext;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Placeholder,
|
|
3
|
+
getChildPlaceholder,
|
|
4
|
+
getFieldValue,
|
|
5
|
+
ComponentRendering,
|
|
6
|
+
HtmlElementRendering,
|
|
7
|
+
} from '@sitecore-jss/sitecore-jss-nextjs';
|
|
8
|
+
import { ComponentProps } from 'lib/component-props';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The main layout (columns) of the styleguide.
|
|
12
|
+
* Navigation is automatically generated based on the components added to the layout,
|
|
13
|
+
* and does not need to be manually maintained.
|
|
14
|
+
*/
|
|
15
|
+
const StyleguideLayout = (props: ComponentProps): JSX.Element => {
|
|
16
|
+
const getRendering = (section: ComponentRendering | HtmlElementRendering) =>
|
|
17
|
+
section as ComponentRendering;
|
|
18
|
+
|
|
19
|
+
const convertUID = (uid?: string) => {
|
|
20
|
+
if (!uid) return '';
|
|
21
|
+
return uid.replace(/[{}]/g, '');
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// this code reads the components in the child placeholders of this component,
|
|
25
|
+
// and projects them into the left navigation column for the styleguide
|
|
26
|
+
const sections = getChildPlaceholder(props.rendering, '<%- helper.getAppPrefix(appPrefix, appName) %>jss-styleguide-layout')
|
|
27
|
+
.filter((section) => getFieldValue(getRendering(section), 'heading'))
|
|
28
|
+
.map((section) => ({
|
|
29
|
+
heading: getFieldValue<string>(getRendering(section), 'heading'),
|
|
30
|
+
id: `i${convertUID(getRendering(section).uid)}`,
|
|
31
|
+
children: getChildPlaceholder(getRendering(section), '<%- helper.getAppPrefix(appPrefix, appName) %>jss-styleguide-section')
|
|
32
|
+
.filter((component) => getFieldValue(getRendering(component), 'heading'))
|
|
33
|
+
.map((component) => ({
|
|
34
|
+
heading: getFieldValue<string>(getRendering(component), 'heading'),
|
|
35
|
+
id: `i${convertUID(getRendering(component).uid)}`,
|
|
36
|
+
})),
|
|
37
|
+
}))
|
|
38
|
+
.map((section) => (
|
|
39
|
+
<nav key={section.heading} className="nav flex-column pt-2">
|
|
40
|
+
<a href={`#${section.id}`} className="nav-item font-weight-bold">
|
|
41
|
+
{section.heading}
|
|
42
|
+
</a>
|
|
43
|
+
{section.children && (
|
|
44
|
+
<nav className="nav flex-column">
|
|
45
|
+
{section.children.map(
|
|
46
|
+
(child) =>
|
|
47
|
+
child.heading && (
|
|
48
|
+
<a key={child.id} href={`#${child.id}`}>
|
|
49
|
+
{child.heading}
|
|
50
|
+
</a>
|
|
51
|
+
)
|
|
52
|
+
)}
|
|
53
|
+
</nav>
|
|
54
|
+
)}
|
|
55
|
+
</nav>
|
|
56
|
+
));
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<div className="row">
|
|
60
|
+
<div className="col-sm-8 col-lg-10">
|
|
61
|
+
<Placeholder name="<%- helper.getAppPrefix(appPrefix, appName) %>jss-styleguide-layout" rendering={props.rendering} />
|
|
62
|
+
</div>
|
|
63
|
+
<div className="col-sm-4 col-lg-2 order-sm-first pt-2">{sections}</div>
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default StyleguideLayout;
|