├── .eslintignore
├── .npmignore
├── src
├── authoring
│ ├── image
│ │ └── v2
│ │ │ ├── ImageV2IsEmptyFn.ts
│ │ │ ├── ImageV2.tsx
│ │ │ └── ImageV2.test.tsx
│ ├── list
│ │ └── v2
│ │ │ ├── ListV2IsEmptyFn.ts
│ │ │ ├── ListV2.test.tsx
│ │ │ ├── ListV2.tsx
│ │ │ ├── expected-list.html
│ │ │ ├── expected-routed-list.html
│ │ │ └── ListV2TestMockItems.ts
│ ├── text
│ │ └── v2
│ │ │ ├── TextV2IsEmptyFn.ts
│ │ │ ├── TextV2.tsx
│ │ │ └── TextV2.test.tsx
│ ├── button
│ │ └── v1
│ │ │ ├── ButtonV1IsEmptyFn.ts
│ │ │ ├── ButtonV1.tsx
│ │ │ └── ButtonV1.test.tsx
│ ├── separator
│ │ └── v1
│ │ │ ├── SeparatorV1IsEmptyFn.ts
│ │ │ ├── SeparatorV1.test.tsx
│ │ │ └── SeparatorV1.tsx
│ ├── title
│ │ └── v2
│ │ │ ├── TitleV2IsEmptyFn.ts
│ │ │ ├── TitleV2.tsx
│ │ │ └── TitleV2.test.tsx
│ ├── download
│ │ └── v1
│ │ │ ├── DownloadV1IsEmptyFn.ts
│ │ │ ├── DownloadV1.test.tsx
│ │ │ └── DownloadV1.tsx
│ └── teaser
│ │ └── v1
│ │ ├── TeaserV1IsEmptyFn.ts
│ │ ├── TeaserV1.test.tsx
│ │ └── TeaserV1.tsx
├── default
│ └── v1
│ │ ├── DefaultV1ComponentIsEmptyFn.ts
│ │ ├── DefaultV1Component.tsx
│ │ └── DefaultV1Component.test.tsx
├── layout
│ ├── breadcrumb
│ │ └── v2
│ │ │ ├── BreadCrumbV2IsEmptyFn.ts
│ │ │ ├── BreadCrumbV2.test.tsx
│ │ │ └── BreadCrumbV2.tsx
│ ├── navigation
│ │ └── v1
│ │ │ ├── NavigationV1IsEmptyFn.ts
│ │ │ ├── NavigationV1.test.tsx
│ │ │ ├── NavigationV1.tsx
│ │ │ └── NavigationV1TestMockItems.ts
│ └── language-navigation
│ │ └── v1
│ │ ├── LanguageNavigationV1IsEmptyFn.ts
│ │ ├── LanguageNavigationV1.test.tsx
│ │ ├── LanguageNavigationV1TestMockItems.ts
│ │ └── LanguageNavigationV1.tsx
├── index.test.ts
├── tsconfig.base.json
├── tsconfig.types.json
├── types.ts
├── setupTests.ts
├── routing
│ ├── RoutedCoreComponent.tsx
│ ├── RoutedLink.tsx
│ └── RoutedLink.test.tsx
├── isEmptyFunctions.ts
├── common
│ └── placeholder.tsx
├── AbstractCoreComponent.tsx
├── index.ts
└── AbstractCoreComponent.test.tsx
├── .gitignore
├── .github
├── workflows
│ ├── security.yml
│ ├── release.yml
│ └── ci.yml
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
└── renovate.json
├── tsconfig.json
├── config
├── webpack.config.core.js
├── webpack.config.lib.js
└── webpack.config.base.js
├── jest.config.js
├── README.md
├── package.json
└── LICENSE
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist/
2 | config/
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | config
2 | node
3 | node_modules
4 | .eslintignore
5 | .gitignore
6 | *.iml
7 | jest.config.js
8 | pom.xml
9 | tsconfig.json
10 | src
--------------------------------------------------------------------------------
/src/authoring/image/v2/ImageV2IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {ImageV2Model} from "./ImageV2";
2 |
3 | export function ImageV2IsEmptyFn(props:ImageV2Model) {
4 | return (!props.src) || props.src.trim().length === 0;
5 | }
6 |
--------------------------------------------------------------------------------
/src/authoring/list/v2/ListV2IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {ListV2Model} from "./ListV2";
2 |
3 | export function ListV2IsEmptyFn(props:ListV2Model): boolean{
4 | return props.items == null || props.items.length === 0;
5 | }
--------------------------------------------------------------------------------
/src/authoring/text/v2/TextV2IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {TextV2Model} from "./TextV2";
2 |
3 | export function TextV2IsEmptyFn(props:TextV2Model): boolean{
4 | return props.text == null || props.text.length === 0;
5 | }
--------------------------------------------------------------------------------
/src/authoring/button/v1/ButtonV1IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {ButtonV1Model} from "./ButtonV1";
2 |
3 | export function ButtonV1IsEmptyFn(props:ButtonV1Model): boolean{
4 | return props.text == null || props.text.length === 0;
5 | }
--------------------------------------------------------------------------------
/src/authoring/separator/v1/SeparatorV1IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {CoreComponentModel} from "../../../AbstractCoreComponent";
2 |
3 | export function SeparatorV1IsEmptyFn(props:CoreComponentModel): boolean{
4 | return false
5 | }
--------------------------------------------------------------------------------
/src/authoring/title/v2/TitleV2IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {TitleV2Model} from "./TitleV2";
2 |
3 | export function TitleV2IsEmptyFn(props:TitleV2Model): boolean{
4 | return props.text == null || props.text.trim().length === 0;
5 | }
--------------------------------------------------------------------------------
/src/default/v1/DefaultV1ComponentIsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {DefaultV1Model} from "./DefaultV1Component";
2 |
3 | export function DefaultV1IsEmptyFn(props:DefaultV1Model): boolean{
4 | return props.html == null || props.html.trim().length === 0;
5 | }
--------------------------------------------------------------------------------
/src/layout/breadcrumb/v2/BreadCrumbV2IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {BreadCrumbV2Model} from "./BreadCrumbV2";
2 |
3 | export function BreadCrumbV2IsEmptyFn(props:BreadCrumbV2Model): boolean{
4 | return props.items == null || props.items.length === 0;
5 | }
--------------------------------------------------------------------------------
/src/layout/navigation/v1/NavigationV1IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {NavigationV1Model} from "./NavigationV1";
2 |
3 | export function NavigationV1IsEmptyFn(props:NavigationV1Model): boolean{
4 | return props.items == null || props.items.length === 0;
5 | }
--------------------------------------------------------------------------------
/src/authoring/download/v1/DownloadV1IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {DownloadV1Model} from "./DownloadV1";
2 |
3 |
4 | export function DownloadV1IsEmptyFn(props:DownloadV1Model): boolean{
5 | return (props.url == null || props.url.length === 0) && props.handleOnClick == null;
6 | }
--------------------------------------------------------------------------------
/src/layout/language-navigation/v1/LanguageNavigationV1IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | import {LanguageNavigationV1Model} from "./LanguageNavigationV1";
2 |
3 | export function LanguageNavigationV1IsEmptyFn(props:LanguageNavigationV1Model): boolean{
4 | return props.items == null || props.items.length === 0;
5 | }
6 |
--------------------------------------------------------------------------------
/src/index.test.ts:
--------------------------------------------------------------------------------
1 | import * as CoreComponents from "./index";
2 | import * as Types from "./types";
3 | import * as EmptyFunctions from "./isEmptyFunctions";
4 |
5 | it('Imports everything property', () => {
6 | expect(CoreComponents).toBeDefined();
7 | expect(EmptyFunctions).toBeDefined();
8 | expect(Types).toBeDefined();
9 | });
--------------------------------------------------------------------------------
/src/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "noEmit": false,
5 | "baseUrl": ".",
6 | "paths": {
7 | "@adobe/aem-react-editable-components": ["./"],
8 | "@adobe/aem-react-editable-components/*": ["./*"]
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | .idea
3 | .classpath
4 | .metadata
5 | .project
6 | .settings
7 | .externalToolBuilders
8 | maven-eclipse.xml
9 | *.swp
10 | *.iml
11 | *.ipr
12 | *.iws
13 | *.bak
14 | .vlt
15 | .DS_Store
16 | jcr.log
17 | atlassian-ide-plugin.xml
18 | .vlt-sync.log
19 | .vlt-sync-config.properties
20 | node
21 | node_modules
22 | lib
23 | dist
24 | coverage
25 |
26 | src/tsconfig.types.tsbuildinfo
27 |
--------------------------------------------------------------------------------
/src/tsconfig.types.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "compilerOptions": {
4 | "composite": true,
5 | "module": "es2015",
6 | "target": "esnext",
7 | "importHelpers": true,
8 | "removeComments": false,
9 | "declaration": true,
10 | "declarationMap": true,
11 | "declarationDir": "../dist",
12 | "emitDeclarationOnly": true
13 | },
14 |
15 | "exclude": [
16 | "./internal/umd.ts"
17 | ]
18 | }
--------------------------------------------------------------------------------
/.github/workflows/security.yml:
--------------------------------------------------------------------------------
1 | name: Vulnerability check
2 | on:
3 | push:
4 | branches:
5 | - master
6 | pull_request_target:
7 |
8 | jobs:
9 | security:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout source code
13 | uses: actions/checkout@master
14 | - name: Run Snyk to check for vulnerabilities
15 | uses: snyk/actions/node@master
16 | env:
17 | SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
18 | with:
19 | command: monitor --all-projects --exclude=examples,pom.xml
20 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | export * from "./index";
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "inlineSourceMap": true,
10 | "inlineSources": true,
11 | "experimentalDecorators": true,
12 | "allowJs": true,
13 | "skipLibCheck": true,
14 | "esModuleInterop": true,
15 | "allowSyntheticDefaultImports": true,
16 | "strict": true,
17 | "forceConsistentCasingInFileNames": true,
18 | "module": "esnext",
19 | "moduleResolution": "node",
20 | "resolveJsonModule": true,
21 | "isolatedModules": true,
22 | "jsx": "react"
23 | },
24 | "include": [
25 | "src"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[feature] "
5 | labels: feature-request
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[bug]"
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **Package version**
14 | Provide a package version where the bug occurs.
15 |
16 | **To Reproduce**
17 | Steps to reproduce the behavior:
18 | 1. Go to '...'
19 | 2. Click on '....'
20 | 3. Scroll down to '....'
21 | 4. See error
22 |
23 | **Expected behavior**
24 | A clear and concise description of what you expected to happen.
25 |
26 | **Screenshots**
27 | If applicable, add screenshots to help explain your problem.
28 |
29 | **Additional context**
30 | Add any other context about the problem here.
31 |
--------------------------------------------------------------------------------
/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {configure} from 'enzyme';
18 | import Adapter from 'enzyme-adapter-react-16';
19 |
20 | configure({ adapter: new Adapter()});
21 |
22 |
--------------------------------------------------------------------------------
/src/authoring/teaser/v1/TeaserV1IsEmptyFn.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
18 | import {TeaserV1Model} from "./TeaserV1";
19 |
20 | export function TeaserV1IsEmptyFn(props:TeaserV1Model): boolean{
21 | return (!props.imagePath && !props.description && props.actions.length == 0)
22 | }
23 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 | on:
3 | push:
4 | branches:
5 | - master
6 | jobs:
7 | release:
8 | name: Release and publish module
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Checkout source code
12 | uses: actions/checkout@v2
13 | with:
14 | fetch-depth: 0
15 | - name: Setup Node.js
16 | uses: actions/setup-node@v2
17 | with:
18 | node-version: 12
19 | - name: Install dependencies
20 | run: npm ci
21 | - name: Build the project
22 | run: npm run build:production
23 | - name: Run tests and do code coverage check
24 | run: npm run test:coverage
25 | - name: Release module and publish it in github.com and npmjs.com
26 | env:
27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28 | NPM_TOKEN: ${{ secrets.ADOBE_BOT_NPM_TOKEN }}
29 | run: npm run semantic-release
30 |
--------------------------------------------------------------------------------
/src/routing/RoutedCoreComponent.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from "react";
18 | import {CoreComponentModel} from "../AbstractCoreComponent";
19 |
20 | export interface RoutedModel {
21 | routed?: boolean
22 | }
23 |
24 | export interface RoutedCoreComponentModel extends CoreComponentModel, RoutedModel{
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "timezone": "Europe/Zurich",
3 | "masterIssue": true,
4 | "packageRules": [
5 | {
6 | "groupName": "@adobe fixes",
7 | "updateTypes": ["patch", "pin", "digest", "minor"],
8 | "automerge": true,
9 | "packagePatterns": ["^@adobe/"],
10 | "schedule": ["at any time"]
11 | },
12 | {
13 | "groupName": "@adobe major",
14 | "updateTypes": ["major"],
15 | "packagePatterns": ["^@adobe/"],
16 | "automerge": false,
17 | "schedule": ["at any time"]
18 | },
19 | {
20 | "groupName": "external fixes",
21 | "updateTypes": ["patch", "pin", "digest", "minor"],
22 | "automerge": false,
23 | "schedule": ["after 1pm on Monday"],
24 | "packagePatterns": ["^.+"],
25 | "excludePackagePatterns": ["^@adobe/"]
26 | },
27 | {
28 | "groupName": "external major",
29 | "updateTypes": ["major"],
30 | "automerge": false,
31 | "packagePatterns": ["^.+"],
32 | "excludePackagePatterns": ["^@adobe/"],
33 | "schedule": ["after 1pm on Monday"]
34 | }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Continuous Integration
2 | on: pull_request_target
3 |
4 | jobs:
5 | test-react-base-components:
6 | name: test react-base-components
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Checkout source code
10 | uses: actions/checkout@v2
11 | - name: Setup Node.js
12 | uses: actions/setup-node@v1
13 | with:
14 | node-version: '12'
15 | - name: Install dependencies
16 | run: npm ci
17 | - name: Build the project
18 | run: npm run build:production
19 | - name: Run tests and do code coverage check
20 | run: npm run test:coverage
21 | - name: Run code linter
22 | uses: hallee/eslint-action@1.0.3
23 | if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }}
24 | with:
25 | repo-token: ${{ secrets.GITHUB_TOKEN }}
26 | - name: Upload code coverage report to workflow as an artifact
27 | uses: actions/upload-artifact@v2
28 | with:
29 | name: base-coverage.zip
30 | path: coverage
31 | - name: Upload code coverage report to codecov.io and comment in pull request
32 | uses: codecov/codecov-action@v1
33 |
--------------------------------------------------------------------------------
/config/webpack.config.core.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | const DllPlugin = require("webpack").DllPlugin;
18 | const config = require('./webpack.config.base');
19 | const path = require('path');
20 | const { CleanWebpackPlugin } = require('clean-webpack-plugin');
21 |
22 | config.output.library = 'AbstractCoreComponent';
23 |
24 | config.entry = {
25 | 'AbstractCoreComponent': ['./src/AbstractCoreComponent.tsx'],
26 | };
27 |
28 | config.plugins.push(new CleanWebpackPlugin());
29 | config.plugins.push(
30 | new DllPlugin({
31 | context: path.join(__dirname, '..'),
32 | name: "[name]",
33 | path: path.resolve(__dirname, `./../dist/manifest/[name].json`),
34 | })
35 | );
36 |
37 | module.exports = config;
--------------------------------------------------------------------------------
/src/authoring/separator/v1/SeparatorV1.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import ReactDOM from "react-dom";
18 |
19 | import React from "react";
20 | import SeparatorV1 from "./SeparatorV1";
21 | import {mount} from "enzyme";
22 |
23 | it('Renders without crashing', () => {
24 | const div = document.createElement('div');
25 | ReactDOM.render(
26 | ,
27 | div
28 | );
29 | ReactDOM.unmountComponentAtNode(div);
30 | expect(1).toBe(1);
31 | });
32 |
33 | it('Renders as expected', ()=> {
34 | const element = mount();
35 |
36 | const html = "
";
37 | expect(element.html()).toEqual(html);
38 | })
39 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | module.exports = {
20 | preset: "ts-jest",
21 | setupFilesAfterEnv: ['/src/setupTests.ts'],
22 | testEnvironment: 'jsdom',
23 | transform: {
24 | "^.+\\.tsx?$": "ts-jest"
25 | },
26 | testMatch: ['/**/*.test.ts','/**/*.test.tsx'],
27 | testPathIgnorePatterns: ['node_modules','lib', 'dist', 'node'],
28 | collectCoverageFrom: [
29 | '**/*.{ts,tsx}'
30 | ],
31 | coveragePathIgnorePatterns: [
32 | "/node_modules/",
33 | "/lib/",
34 | "/dist/",
35 | "/node/"
36 | ],
37 | moduleFileExtensions: [
38 | "ts",
39 | "tsx",
40 | "js",
41 | "jsx",
42 | "json",
43 | "node"
44 | ],
45 | };
--------------------------------------------------------------------------------
/src/default/v1/DefaultV1Component.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {CoreComponentModel, withConditionalPlaceHolder} from "../../AbstractCoreComponent";
18 | import React, {Component} from "react";
19 | import {DefaultV1IsEmptyFn} from "./DefaultV1ComponentIsEmptyFn";
20 |
21 | export interface DefaultV1Model extends CoreComponentModel{
22 | html: string
23 | }
24 |
25 | const DefaultV1ComponentImpl = (props:DefaultV1Model) => ;
26 |
27 | const DefaultV1Component = (props:DefaultV1Model) => {
28 | const Wrapped = withConditionalPlaceHolder(DefaultV1ComponentImpl, DefaultV1IsEmptyFn, "cmp-default", "Default SPA Component")
29 | return
30 | };
31 |
32 | export default DefaultV1Component;
--------------------------------------------------------------------------------
/src/authoring/separator/v1/SeparatorV1.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, {Component} from "react";
18 | import {CoreComponentModel, withConditionalPlaceHolder, withStandardBaseCssClass} from "../../../AbstractCoreComponent";
19 | import {SeparatorV1IsEmptyFn} from "./SeparatorV1IsEmptyFn";
20 |
21 | const SeparatorV1Impl = (props:CoreComponentModel) => {
22 |
23 | return (
24 |
25 |
26 |
27 | )
28 |
29 | };
30 |
31 | const SeparatorV1 = (props:CoreComponentModel) => {
32 | const Wrapped = withConditionalPlaceHolder(withStandardBaseCssClass(SeparatorV1Impl, "cmp-separator"), SeparatorV1IsEmptyFn, "Separator V1")
33 | return
34 | };
35 |
36 | export default SeparatorV1;
--------------------------------------------------------------------------------
/src/isEmptyFunctions.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | //exports is empty functions for react suspense
17 |
18 | export * from "./default/v1/DefaultV1ComponentIsEmptyFn";
19 | export * from "./authoring/list/v2/ListV2IsEmptyFn"
20 | export * from "./authoring/text/v2/TextV2IsEmptyFn";
21 | export * from './authoring/button/v1/ButtonV1IsEmptyFn';
22 | export * from "./authoring/title/v2/TitleV2IsEmptyFn";
23 | export * from "./authoring/image/v2/ImageV2IsEmptyFn";
24 | export * from "./authoring/teaser/v1/TeaserV1IsEmptyFn";
25 | export * from "./authoring/download/v1/DownloadV1IsEmptyFn";
26 | export * from "./authoring/separator/v1/SeparatorV1IsEmptyFn";
27 | export * from './layout/breadcrumb/v2/BreadCrumbV2IsEmptyFn';
28 | export * from "./layout/navigation/v1/NavigationV1IsEmptyFn";
29 | export * from "./layout/language-navigation/v1/LanguageNavigationV1IsEmptyFn";
--------------------------------------------------------------------------------
/src/common/placeholder.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import React, {Component} from 'react';
17 |
18 | export interface PlaceHolderModel {
19 | componentTitle?: string
20 | classAppend?: string
21 | emptyTextAppend?: string
22 | }
23 | const DEFAULT_EMPTY_TEXT_LABEL = 'Please configure the component';
24 |
25 | export const EditorPlaceHolder = (props:PlaceHolderModel) => {
26 |
27 | const part1: string = (props.componentTitle != null && props.componentTitle.length > 0) ? props.componentTitle + ' - ' : '';
28 | const part2: string = (props.emptyTextAppend != null) ? props.emptyTextAppend : DEFAULT_EMPTY_TEXT_LABEL;
29 | const emptyText = part1 + part2;
30 |
31 | return (
32 |
34 | {emptyText}
35 |
36 | )
37 | };
--------------------------------------------------------------------------------
/src/routing/RoutedLink.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import {Link as RouterLink} from 'react-router-dom';
19 |
20 | export interface LinkProps {
21 | to?: string;
22 | isRouted?: boolean;
23 | [prop: string]: any
24 | }
25 | export const RoutedLink = (props:LinkProps) => {
26 | const {to, isRouted, ...otherProps} = props;
27 |
28 | const isRoutedChecked = typeof props.isRouted === 'boolean' ? props.isRouted : true;
29 |
30 | if(to === undefined || to.trim().length === 0){
31 | return ;
34 | }
35 | const isExternal = /^https?:\/\//.test(to);
36 |
37 | return isExternal || !isRoutedChecked?
38 | ()
42 | :
43 | ( )
46 | };
--------------------------------------------------------------------------------
/config/webpack.config.lib.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | const config = require('./webpack.config.base');
18 |
19 | config.output.library = '@adobe/aem-core-components-react-base';
20 |
21 | config.entry = {
22 | 'index': ['./src/index.ts'],
23 | 'isEmptyFunctions': ['./src/isEmptyFunctions.ts'],
24 | 'authoring/list/v2/ListV2': ['./src/authoring/list/v2/ListV2'],
25 | 'authoring/button/v1/ButtonV1': ['./src/authoring/button/v1/ButtonV1'],
26 | 'authoring/text/v2/TextV2': ['./src/authoring/text/v2/TextV2'],
27 | 'authoring/title/v2/TitleV2': ['./src/authoring/title/v2/TitleV2'],
28 | 'authoring/image/v2/ImageV2': ['./src/authoring/image/v2/ImageV2'],
29 | 'authoring/teaser/v1/TeaserV1': ['./src/authoring/teaser/v1/TeaserV1'],
30 | 'authoring/download/v1/DownloadV1': ['./src/authoring/download/v1/DownloadV1'],
31 | 'authoring/separator/v1/SeparatorV1': ['./src/authoring/separator/v1/SeparatorV1'],
32 | 'layout/breadcrumb/v2/BreadCrumbV2': ['./src/layout/breadcrumb/v2/BreadCrumbV2'],
33 | 'layout/navigation/v1/NavigationV1': ['./src/layout/navigation/v1/NavigationV1'],
34 | 'layout/language-navigation/v1/LanguageNavigationV1': ['./src/layout/language-navigation/v1/LanguageNavigationV1']
35 | };
36 |
37 | module.exports = config;
--------------------------------------------------------------------------------
/src/authoring/text/v2/TextV2.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, {Component} from 'react';
18 | import {CoreComponentModel, withConditionalPlaceHolder, withStandardBaseCssClass} from "../../../AbstractCoreComponent";
19 | import {TextV2IsEmptyFn} from "./TextV2IsEmptyFn";
20 |
21 | export interface TextV2Model extends CoreComponentModel{
22 | text?: string;
23 | richText?: boolean
24 | cqPath?:string
25 | id?: string
26 | }
27 |
28 | export const TextV2RichText = (props:TextV2Model) => {
29 | const text:string = props.text as string;
30 | const id = (props.id) ? props.id : (props.cqPath ? props.cqPath.substr(props.cqPath.lastIndexOf('/') + 1) : "");
31 |
32 | return
33 | };
34 |
35 | export const TextV2PlainText = (props:TextV2Model) => {
36 | return
{props.text}
37 | };
38 |
39 | const TextV2Impl = (props:TextV2Model) => {
40 | const {richText = false} = props;
41 | return (richText) ? : ;
42 | };
43 |
44 | const TextV2 = (props:TextV2Model) => {
45 | const Wrapped = withConditionalPlaceHolder(withStandardBaseCssClass(TextV2Impl, "cmp-text"), TextV2IsEmptyFn, "Text V2")
46 | return
47 | };
48 |
49 | export default TextV2;
--------------------------------------------------------------------------------
/src/default/v1/DefaultV1Component.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import ReactDOM from 'react-dom';
19 | import {mount} from 'enzyme';
20 |
21 | import DefaultV1Component, {DefaultV1Model} from "./DefaultV1Component";
22 | import {DefaultV1IsEmptyFn} from "./DefaultV1ComponentIsEmptyFn";
23 |
24 | it('Renders without crashing', () => {
25 | const div = document.createElement('div');
26 | ReactDOM.render(
27 | test"} />,
28 | div
29 | );
30 | ReactDOM.unmountComponentAtNode(div);
31 | expect(1).toBe(1);
32 | });
33 |
34 | it('Has a proper isEmpty function', () => {
35 |
36 | const props1:DefaultV1Model = {
37 | html:"
63 | )
64 | };
65 |
66 | const TitleV2 = (props:TitleV2Model) => {
67 | const Wrapped = withConditionalPlaceHolder(withStandardBaseCssClass(TitleV2Impl, "cmp-title"), TitleV2IsEmptyFn, "TitleV2")
68 | return
69 | };
70 |
71 | export default TitleV2;
--------------------------------------------------------------------------------
/src/AbstractCoreComponent.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import * as React from 'react';
18 | import {ComponentType} from 'react';
19 |
20 | import {EditorPlaceHolder} from "./common/placeholder";
21 |
22 | export interface HasBaseCssClass {
23 | baseCssClass?: string
24 | }
25 |
26 | export interface CoreComponentModel extends HasBaseCssClass{
27 | hidePlaceHolder?: boolean
28 | isInEditor?:boolean
29 | }
30 |
31 | export interface CoreComponentState {
32 |
33 | }
34 |
35 | export const withStandardBaseCssClass =
36 | (
37 | Component:ComponentType,
38 | defaultBaseCssClass:string
39 | ):React.ComponentType => {
40 | return (props:M) => {
41 |
42 | const baseCssClass = props.baseCssClass;
43 | const toBeUsedCssClass = baseCssClass && baseCssClass.trim().length > 0 ? baseCssClass : defaultBaseCssClass;
44 |
45 | const mergedProps: M= {
46 | ...props,
47 | baseCssClass: toBeUsedCssClass
48 | };
49 |
50 | return ;
51 | }
52 | };
53 |
54 | export const withConditionalPlaceHolder =
55 | (
56 | Component:ComponentType,
57 | isEmpty:(props:M) => boolean,
58 | componentTitle?:string, emptyText?:string
59 | ):React.ComponentType => {
60 | return (props:M) => {
61 |
62 | const isEmptyResult:boolean = isEmpty(props);
63 | const {hidePlaceHolder = false, isInEditor = false} = props;
64 |
65 | return (
66 | <>
67 | { !isEmptyResult &&
68 |
69 | }
70 | {
71 | (isEmptyResult && isInEditor && !hidePlaceHolder) &&
72 |
76 | }
77 | >
78 | );
79 | }
80 | };
--------------------------------------------------------------------------------
/src/authoring/button/v1/ButtonV1.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, {MouseEvent} from 'react';
18 | import {withConditionalPlaceHolder, withStandardBaseCssClass} from "../../../AbstractCoreComponent";
19 | import {RoutedCoreComponentModel} from "../../../routing/RoutedCoreComponent";
20 | import {RoutedLink} from "../../../routing/RoutedLink";
21 | import {ButtonV1IsEmptyFn} from "./ButtonV1IsEmptyFn";
22 |
23 |
24 | export interface ButtonV1Model extends RoutedCoreComponentModel{
25 | text?: string;
26 | link?: string;
27 | icon?: string;
28 | ariaLabel?: string;
29 | handleOnClick?(event: MouseEvent): void
30 | }
31 |
32 | export const ButtonV1Content = (props:ButtonV1Model) => {
33 | return (
34 | <>
35 | { props.icon && }
36 | {props.text}
37 | >
38 | );
39 | };
40 |
41 | const ButtonV1Impl = (props:ButtonV1Model) => {
42 |
43 | const handleOnClick = (event:MouseEvent) =>{
44 | if(props.handleOnClick){
45 | props.handleOnClick(event);
46 | }
47 | };
48 |
49 | const generateAttributes = (isLink: boolean) => {
50 | const computedAttrs: any = {
51 | className: props.baseCssClass,
52 | onClick: handleOnClick
53 | };
54 |
55 | if (isLink) {
56 | computedAttrs['aria-label'] = props.ariaLabel;
57 | computedAttrs['href'] = props.link;
58 | }
59 | return computedAttrs;
60 | };
61 |
62 | const isLink = (!!props.link);
63 | const attrs = generateAttributes(isLink);
64 |
65 | if(isLink){
66 | return
67 | }else{
68 | return
69 | }
70 | };
71 |
72 | const ButtonV1 = (props:ButtonV1Model) => {
73 | const Wrapped = withConditionalPlaceHolder(withStandardBaseCssClass(ButtonV1Impl,"cmp-button"), ButtonV1IsEmptyFn, "Button V1");
74 | return
75 | };
76 |
77 | export default ButtonV1;
--------------------------------------------------------------------------------
/src/authoring/image/v2/ImageV2.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, {Component} from 'react';
18 | import {withConditionalPlaceHolder, withStandardBaseCssClass} from "../../../AbstractCoreComponent";
19 | import {RoutedCoreComponentModel} from "../../../routing/RoutedCoreComponent";
20 | import {RoutedLink} from "../../../routing/RoutedLink";
21 | import {ImageV2IsEmptyFn} from "./ImageV2IsEmptyFn";
22 |
23 |
24 | export interface ImageV2Model extends RoutedCoreComponentModel{
25 | src: string
26 | alt: string
27 | displayPopupTitle?: boolean
28 | title?: string
29 | link?: string
30 | }
31 |
32 | const ImageV2InnerContents = (props:ImageV2Model) => {
33 | return (
34 | <>
35 |
38 | {
39 | !!(props.title) && {props.title}
40 | }
41 | {
42 | props.displayPopupTitle && (!!props.title) &&
43 | }
44 | >
45 | );
46 | };
47 |
48 | const ImageV2Contents = (props:ImageV2Model) => {
49 | if( props.link && props.link.trim().length > 0){
50 | return (
51 |
52 |
53 |
54 | )
55 | }
56 | return
57 | };
58 |
59 | const ImageV2Impl = (props:ImageV2Model) => {
60 |
61 | const {isInEditor = false} = props;
62 | const cssClassName = (isInEditor) ? props.baseCssClass + ' cq-dd-image' : props.baseCssClass;
63 |
64 | return (
65 |
66 |
67 |
68 | )
69 |
70 | };
71 |
72 | const ImageV2 = (props:ImageV2Model) => {
73 |
74 | const Wrapped = withConditionalPlaceHolder(withStandardBaseCssClass(ImageV2Impl, "cmp-image"), ImageV2IsEmptyFn, "Image V2");
75 | return
76 | };
77 |
78 | export default ImageV2;
--------------------------------------------------------------------------------
/src/authoring/title/v2/TitleV2.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import ReactDOM from 'react-dom';
19 | import {mount} from 'enzyme';
20 | import TitleV2, {TitleV2Model} from "./TitleV2";
21 |
22 | it('Renders without crashing', () => {
23 | const div = document.createElement('div');
24 |
25 | const props:TitleV2Model = {
26 | hidePlaceHolder: false,
27 | isInEditor: false,
28 | linkDisabled: false,
29 | routed: false,
30 | text: 'Hello World'
31 | };
32 |
33 | ReactDOM.render(
34 | ,
35 | div
36 | );
37 | ReactDOM.unmountComponentAtNode(div);
38 | expect(1).toBe(1);
39 | });
40 |
41 |
42 | it('Renders without link', () => {
43 |
44 | const props:TitleV2Model = {
45 | hidePlaceHolder: false,
46 | isInEditor: false,
47 | routed: false,
48 | linkDisabled: false,
49 | text: 'My awesome title'
50 | };
51 |
52 | const element = mount();
53 |
54 | const heading = element.find("h3");
55 |
56 | expect(heading).toHaveLength(1);
57 |
58 | });
59 |
60 | it('Renders a custom type without link', () => {
61 |
62 | const props:TitleV2Model = {
63 | hidePlaceHolder: false,
64 | isInEditor: false,
65 | linkDisabled: false,
66 | routed: false,
67 | type: 'h2',
68 | text: 'My awesome title'
69 | };
70 |
71 | const element = mount();
72 |
73 | const heading = element.find("h2");
74 |
75 | expect(heading).toHaveLength(1);
76 |
77 | });
78 |
79 |
80 | it('Renders a custom type with a link', () => {
81 |
82 | const props:TitleV2Model = {
83 | hidePlaceHolder: false,
84 | isInEditor: false,
85 | linkDisabled: false,
86 | routed: false,
87 | type: 'h2',
88 | text: 'My awesome title',
89 | linkURL: '/content/some/page.html'
90 | };
91 |
92 | const element = mount();
93 |
94 | const heading = element.find("h2");
95 |
96 | expect(heading).toHaveLength(1);
97 |
98 | const anchor = element.find("a.cmp-title__link");
99 |
100 | expect(anchor).toHaveLength(1);
101 |
102 | });
103 |
104 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | //general
17 | export * from "./AbstractCoreComponent";
18 |
19 | export * from "./default/v1/DefaultV1Component";
20 | export * from "./default/v1/DefaultV1ComponentIsEmptyFn";
21 | export { default as DefaultV1Component } from "./default/v1/DefaultV1Component";
22 |
23 | export * from "./authoring/list/v2/ListV2";
24 | export * from "./authoring/list/v2/ListV2IsEmptyFn"
25 | export { default as ListV2 } from "./authoring/list/v2/ListV2";
26 |
27 |
28 | export * from "./authoring/text/v2/TextV2";
29 | export * from "./authoring/text/v2/TextV2IsEmptyFn";
30 | export { default as TextV2 } from "./authoring/text/v2/TextV2";
31 |
32 | export * from './authoring/button/v1/ButtonV1';
33 | export * from './authoring/button/v1/ButtonV1IsEmptyFn';
34 | export { default as ButtonV1 } from './authoring/button/v1/ButtonV1';
35 |
36 | export * from "./authoring/title/v2/TitleV2";
37 | export * from "./authoring/title/v2/TitleV2IsEmptyFn";
38 | export { default as TitleV2 } from "./authoring/title/v2/TitleV2";
39 |
40 | export * from "./authoring/image/v2/ImageV2";
41 | export * from "./authoring/image/v2/ImageV2IsEmptyFn";
42 | export { default as ImageV2 } from "./authoring/image/v2/ImageV2";
43 |
44 | export * from "./authoring/teaser/v1/TeaserV1";
45 | export * from "./authoring/teaser/v1/TeaserV1IsEmptyFn";
46 | export { default as TeaserV1 } from "./authoring/teaser/v1/TeaserV1";
47 |
48 | export * from "./authoring/download/v1/DownloadV1";
49 | export * from "./authoring/download/v1/DownloadV1IsEmptyFn";
50 | export { default as DownloadV1 } from "./authoring/download/v1/DownloadV1";
51 |
52 | export * from "./authoring/separator/v1/SeparatorV1";
53 | export * from "./authoring/separator/v1/SeparatorV1IsEmptyFn";
54 | export { default as SeparatorV1 } from "./authoring/separator/v1/SeparatorV1";
55 |
56 | //layout
57 | export * from './layout/breadcrumb/v2/BreadCrumbV2';
58 | export * from './layout/breadcrumb/v2/BreadCrumbV2IsEmptyFn';
59 | export { default as BreadCrumbV2 } from "./layout/breadcrumb/v2/BreadCrumbV2";
60 |
61 | export * from "./layout/navigation/v1/NavigationV1";
62 | export * from "./layout/navigation/v1/NavigationV1IsEmptyFn";
63 |
64 | export * from "./layout/language-navigation/v1/LanguageNavigationV1";
65 | export * from "./layout/language-navigation/v1/LanguageNavigationV1IsEmptyFn";
66 | export { default as LanguageNavigationV1 } from "./layout/language-navigation/v1/LanguageNavigationV1";
--------------------------------------------------------------------------------
/src/authoring/image/v2/ImageV2.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import ReactDOM from 'react-dom';
19 | import {mount} from 'enzyme';
20 |
21 | import ImageV2, {ImageV2Model} from "./ImageV2";
22 | import {ImageV2IsEmptyFn} from "./ImageV2IsEmptyFn";
23 |
24 | it('Has a proper isEmpty function', () => {
25 |
26 | const props1:ImageV2Model = {
27 | src: "/content/dam/image.jpg",
28 | alt: "Some Image"
29 | };
30 |
31 | expect(ImageV2IsEmptyFn(props1)).toEqual(false);
32 |
33 | const props2:ImageV2Model = {
34 | src: " ",
35 | alt: "Some Image"
36 | };
37 |
38 | expect(ImageV2IsEmptyFn(props2)).toEqual(true);
39 |
40 | });
41 |
42 | it('Renders without crashing', () => {
43 | const div = document.createElement('div');
44 |
45 | ReactDOM.render(
46 | ,
47 | div
48 | );
49 | ReactDOM.unmountComponentAtNode(div);
50 | expect(1).toBe(1);
51 | });
52 |
53 | it('Renders with a cq-dd-image in edit mode', () => {
54 |
55 | //let captured = false;
56 | const props:ImageV2Model = {
57 | src: "/content/dam/image.jpg",
58 | alt: "Some Image",
59 | isInEditor: true
60 | };
61 |
62 | const image = mount();
63 |
64 | expect(image.find(".cq-dd-image")).toHaveLength(1);
65 |
66 | expect(image).toBeDefined();
67 | });
68 |
69 |
70 | it('Renders without link', () => {
71 |
72 | //let captured = false;
73 | const props:ImageV2Model = {
74 | src: "/content/dam/image.jpg",
75 | alt: "Some Image"
76 | };
77 |
78 | const image = mount();
79 |
80 | expect(image).toBeDefined();
81 |
82 | const anchor = image.find("a");
83 |
84 | expect(anchor).toHaveLength(0);
85 |
86 | const title = image.find(".cmp-image__title");
87 |
88 | expect(title).toHaveLength(0);
89 |
90 | const img = image.find("img");
91 |
92 |
93 | expect(img.prop("alt")).toEqual(props.alt);
94 | expect(img.prop("src")).toEqual(props.src);
95 |
96 |
97 | });
98 |
99 | it('Renders with title', () => {
100 |
101 | //let captured = false;
102 | const props:ImageV2Model = {
103 | src: "/content/dam/image.jpg",
104 | alt: "Some Image",
105 | title: "Awesome Title!"
106 | };
107 |
108 | const image = mount();
109 |
110 | const title = image.find(".cmp-image__title");
111 |
112 | expect(title).toHaveLength(1);
113 | expect(title.text()).toEqual(props.title);
114 |
115 |
116 | });
117 |
118 |
119 |
--------------------------------------------------------------------------------
/src/authoring/button/v1/ButtonV1.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import ReactDOM from 'react-dom';
19 | import {mount} from 'enzyme';
20 |
21 | import ButtonV1, {ButtonV1Model} from './ButtonV1';
22 | import {MemoryRouter} from 'react-router-dom';
23 |
24 |
25 | it('Renders without crashing', () => {
26 | const div = document.createElement('div');
27 | ReactDOM.render(
28 | ,
29 | div
30 | );
31 | ReactDOM.unmountComponentAtNode(div);
32 | expect(1).toBe(1);
33 | });
34 |
35 |
36 | it('Renders a proper button with link', () => {
37 |
38 | let captured = false;
39 |
40 | const properties:ButtonV1Model = {
41 | ariaLabel: "ThisIsAButton",
42 | icon: "iconCSSCls",
43 | link: "/content/some/link.html",
44 | text: "SomeText",
45 | routed:true,
46 | handleOnClick(event): void {
47 | captured = true;
48 | }
49 | };
50 |
51 | const wrapper = mount();
52 |
53 | const button = wrapper.find('a.cmp-button');
54 | expect(button).toHaveLength(1);
55 | button.simulate('click');
56 | expect(captured).toEqual(true);
57 |
58 | const anchor = button.find("a");
59 | expect(anchor).toHaveLength(1);
60 | expect(anchor.prop("aria-label")).toEqual("ThisIsAButton");
61 | expect(anchor.prop("href")).toEqual("/content/some/link.html");
62 |
63 | const iconSpan = anchor.find("span.cmp-button__icon.cmp-button__icon--iconCSSCls");
64 | expect(iconSpan).toHaveLength(1);
65 |
66 | const textSpan = anchor.find("span.cmp-button__text");
67 | expect(textSpan.text()).toEqual("SomeText");
68 | });
69 |
70 |
71 | it('Renders a proper button with link', () => {
72 |
73 | let captured = false;
74 |
75 | const properties:ButtonV1Model = {
76 | ariaLabel: "ThisIsAButton",
77 | icon: "iconCSSCls",
78 | text: "SomeText",
79 | handleOnClick(event): void {
80 | captured = true;
81 | }
82 | };
83 |
84 | const wrapper = mount();
85 |
86 | const button = wrapper.find('.cmp-button');
87 | expect(button).toHaveLength(1);
88 | button.simulate('click');
89 | expect(captured).toEqual(true);
90 |
91 | const anchor = button.find("a");
92 | expect(anchor).toHaveLength(0);
93 |
94 |
95 | const iconSpan = button.find("span.cmp-button__icon.cmp-button__icon--iconCSSCls");
96 | expect(iconSpan).toHaveLength(1);
97 |
98 | const textSpan = button.find("span.cmp-button__text");
99 | expect(textSpan.text()).toEqual("SomeText");
100 | });
--------------------------------------------------------------------------------
/src/AbstractCoreComponent.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, {Component} from 'react';
18 | import ReactDOM from 'react-dom';
19 | import {mount} from 'enzyme';
20 |
21 |
22 | import {CoreComponentModel,withStandardBaseCssClass, withConditionalPlaceHolder} from './AbstractCoreComponent';
23 |
24 | interface TestType extends CoreComponentModel{
25 | forceEmptyFlag:boolean
26 | }
27 |
28 | class ImplementingClass extends Component{
29 |
30 | render(): JSX.Element {
31 | return
My awesome component
;
32 | }
33 |
34 | }
35 |
36 | const WrappedClass = withConditionalPlaceHolder(withStandardBaseCssClass(ImplementingClass,"base-class"), (props) => props.forceEmptyFlag, "AwesomeComponent");
37 |
38 | it('Renders without crashing', () => {
39 | const div = document.createElement('div');
40 | ReactDOM.render(
41 | ,
42 | div
43 | );
44 | ReactDOM.unmountComponentAtNode(div);
45 | expect(1).toBe(1);
46 | });
47 |
48 | it('Should show our awesome text if the component is not empty', () => {
49 | const wrapper = mount();
50 | expect(wrapper.html()).toEqual("
My awesome component
");
51 | });
52 |
53 | it('Should not show anything if wcmmode is disabled and component is empty', () => {
54 | const wrapper = mount();
55 | expect(wrapper.html()).toBeNull();
56 | });
57 |
58 | it('Should show the proper placeholder with a custom text if wcmmode is edit and component is empty', () => {
59 |
60 | const WrappedOverride = withConditionalPlaceHolder(ImplementingClass, (props) => props.forceEmptyFlag, "AwesomeComponent", "Custom Configure Text");
61 |
62 | const wrapper = mount();
63 | expect(wrapper.html()).toEqual("
AwesomeComponent - Custom Configure Text
");
64 | });
65 |
66 | it('Should NOT show the proper placeholder if wcmmode is edit and component is empty, and hidePlaceHolder is set to true.', () => {
67 | const wrapper = mount();
68 | expect(wrapper.html()).toBeNull();
69 | });
70 |
71 | it('Should change the baseClass if we specify it with properties', () => {
72 | const wrapper = mount();
73 | expect(wrapper.html()).toEqual("
My awesome component
");
74 | });
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AEM WCM Components - React Core implementation
2 |
3 | This module provides a React implementation for the [AEM core components](https://www.aemcomponents.dev/).
4 | This enables you to use the core components:
5 | -In the [AEM SPA editor](https://docs.adobe.com/content/help/en/experience-manager-64/developing/headless/spas/spa-overview.html) with React
6 | -In [React web components](https://www.npmjs.com/package/@adobe/react-webcomponent)
7 | -Or in any other React context, provided you have the input needed to instantiate the components.
8 |
9 | [Introduction Video and Demo](https://www.youtube.com/watch?v=9759AhM7fAc)
10 |
11 | Current supported / exported components:
12 |
13 | ### Page Authoring
14 | - Button (V1)
15 | - Download (V1)
16 | - Image (V2)
17 | - List (V2)
18 | - Separator (V1)
19 | - Teaser (V1)
20 | - Text (V2)
21 | - Title (V2)
22 |
23 | ### Layout
24 | - BreadCrumb (V2)
25 | - Language Navigation (V1)
26 | - Navigation (V1)
27 |
28 | ### Abstraction
29 | - AbstractCoreComponent
30 | - CoreComponentModel (interface)
31 |
32 | ### Containers
33 | For the containers (Accordion,Tabs,Carousel,Container) we do not provide any implementation in this project.
34 | It does not make sense to provide it for web-components as you can leverage the normal Core Components implementation such as a Tab Container, and drag your web components in there.
35 | Instead we provide them for the SPA editor only, introducing a dependency, and therefore we moved it into a [separate project](https://www.npmjs.com/package/@adobe/aem-core-components-react-spa).
36 |
37 |
38 | ## Usage
39 |
40 | You can choose to import the entire library at once OR import components individually.
41 | The latter is useful if you want to only enable a few components and you want to save your javascript footprint.
42 | Also, if you want to load all core components, but you want to lazyload them with react suspense, you will need to import them individually.
43 |
44 | ### Importing the whole library:
45 |
46 | ```
47 | import * as BaseCoreComponents from "@adobe/aem-core-components-react-base";
48 | const {ButtonV1, ButtonV1Model, ButtonV1IsEmptyFn} = BaseCoreComponents;
49 | ```
50 |
51 | ### Importing the button component individually:
52 |
53 | ```
54 | import ButtonV1, {ButtonV1Model, ButtonV1IsEmptyFn} from "@adobe/aem-core-components-react-base/dist/authoring/button/v1/ButtonV1";
55 | ```
56 |
57 | ### Using the imported code
58 |
59 | Now that you have the Button and ButtonV1IsEmptyFn imported, you can use them in your project.
60 | The properties of the Button 1 on 1 correspond to the Sling Model Exporter (.model.json) output.
61 |
62 | Note: There are some exceptions where some extra properties are added (mainly i18n labels) that are currently not present in the OOTB sling model exports.
63 | These can be added by the project itself with delegation. If they are not present, the default (English) values will be used.
64 |
65 | #### Button - Direct instantiation with TypeScript:
66 | ```
67 | const modelProps:ButtonV1Model = {
68 | text: 'Example Button',
69 | link: '/content/my/awesome/page.html',
70 | icon: 'iconCssCLass'
71 | };
72 |
73 | const html:JSX.Element = ();
74 | ```
75 |
76 |
77 | #### Button - Example with the spa editor:
78 |
79 | ```
80 | MapTo('my-project/wcm/components/button')(ButtonV1, {isEmpty: ButtonV1IsEmptyFn});
81 | ```
82 |
83 | For a complete project with examples, visit the [github page](https://github.com/adobe/aem-react-core-wcm-components/tree/master/examples).
--------------------------------------------------------------------------------
/src/authoring/teaser/v1/TeaserV1.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Adobe
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import ReactDOM from "react-dom";
18 |
19 | import React from "react";
20 | import TeaserV1, {TeaserV1Model} from "./TeaserV1";
21 | import {mount} from "enzyme";
22 |
23 | const defaultProps:TeaserV1Model = {
24 | imageAlt: "snowy mountains",
25 | imagePath: "/some/image.png",
26 | description: '
69 |
70 |
71 |
72 |
73 |
74 |
75 | )
76 | }
77 | };
78 |
79 | let oldConsoleError:()=>void;
80 |
81 | beforeAll(() => {
82 | oldConsoleError = console.error;
83 | console.error = jest.fn();
84 | });
85 |
86 | afterAll(() => {
87 | console.error = oldConsoleError;
88 | });
89 |
90 | it('Renders and routes properly', () => {
91 |
92 |
93 | const { container } = createRoutedDummyComponent("/page2");
94 |
95 | const image:HTMLElement|null = container.querySelector('.routedDummyComponent');
96 |
97 | expect(image).toBeDefined();
98 |
99 | const anchor = container.querySelector('a.dummyLink');
100 |
101 | expect(anchor).toBeDefined();
102 |
103 | if(anchor != null){
104 | fireEvent.click(anchor);
105 | }
106 |
107 | const h1 = container.querySelector("h1.dummy");
108 | expect(h1).toBeDefined();
109 |
110 | });
111 |
112 | it('Does route if the link is relative and isRouted is not specified', () => {
113 |
114 | const { container } = createUnspecifiedDummyComponent("/page3");
115 |
116 | const image:HTMLElement|null = container.querySelector('.routedDummyComponent');
117 |
118 | expect(image).toBeDefined();
119 |
120 | const anchor = container.querySelector('a.dummyLink');
121 |
122 | expect(anchor).toBeDefined();
123 |
124 | if(anchor != null){
125 | fireEvent.click(anchor);
126 | }
127 |
128 | const h1 = container.querySelector("h1.dummy");
129 | expect(h1).toBeDefined();
130 |
131 | });
132 |
133 | it('Does NOT route if the link is empty', () => {
134 |
135 |
136 | const { container } = createRoutedDummyComponent("", false);
137 |
138 | const image:HTMLElement|null = container.querySelector('.routedDummyComponent');
139 |
140 | expect(image).toBeDefined();
141 |
142 | const anchor = container.querySelector('a.dummyLink');
143 |
144 | expect(anchor).toBeDefined();
145 |
146 | let found = false;
147 |
148 | if(anchor != null){
149 | const href:Attr | null = anchor.attributes.getNamedItem("href");
150 |
151 | if(href != null){
152 | expect(href.value).toEqual("#");
153 | found = true;
154 | }
155 | }
156 |
157 | expect(found).toEqual(true);
158 |
159 | if(anchor != null){
160 | fireEvent.click(anchor);
161 | }
162 |
163 | const h1 = container.querySelector("h1.dummy");
164 | expect(h1).toBeNull();
165 |
166 | });
167 |
168 |
169 | it('Does NOT route if we tell it to', () => {
170 |
171 |
172 | const { container } = createRoutedDummyComponent("/page2", false);
173 |
174 | const image:HTMLElement|null = container.querySelector('.routedDummyComponent');
175 |
176 | expect(image).toBeDefined();
177 |
178 | const anchor = container.querySelector('a.dummyLink');
179 |
180 | expect(anchor).toBeDefined();
181 |
182 | if(anchor != null){
183 | fireEvent.click(anchor);
184 | }
185 |
186 | const h1 = container.querySelector("h1.dummy");
187 | expect(h1).toBeNull();
188 |
189 | });
190 |
191 |
192 | it('Will never route external URLs', () => {
193 |
194 |
195 | const { container } = createRoutedDummyComponent("https://adobe.com", true);
196 |
197 | const image:HTMLElement|null = container.querySelector('.routedDummyComponent');
198 |
199 | expect(image).toBeDefined();
200 |
201 | const anchor = container.querySelector('a.dummyLink');
202 |
203 | expect(anchor).toBeDefined();
204 |
205 | if(anchor != null){
206 | fireEvent.click(anchor);
207 | }
208 |
209 | const h1 = container.querySelector("h1.dummy");
210 | expect(h1).toBeNull();
211 |
212 | });
213 |
214 |
--------------------------------------------------------------------------------
/src/authoring/list/v2/ListV2TestMockItems.ts:
--------------------------------------------------------------------------------
1 | import {ListV2Item, ListV2Model} from './ListV2';
2 |
3 |
4 | export const mockItems:ListV2Item[] = [
5 | {
6 | "url": "/content/core-components-examples/library/page-authoring/title.html",
7 | "lastModified": 1547642198741,
8 | "description": "Display a page heading",
9 | "title": "Title",
10 | "path": "/content/core-components-examples/library/page-authoring/title"
11 | },
12 | {
13 | "url": "/content/core-components-examples/library/page-authoring/text.html",
14 | "lastModified": 1548159422163,
15 | "description": "Display a rich text paragraph",
16 | "title": "Text",
17 | "path": "/content/core-components-examples/library/page-authoring/text"
18 | },
19 | {
20 | "url": "/content/core-components-examples/library/page-authoring/image.html",
21 | "lastModified": 1550255022224,
22 | "description": "Display an image asset",
23 | "title": "Image",
24 | "path": "/content/core-components-examples/library/page-authoring/image"
25 | },
26 | {
27 | "url": "/content/core-components-examples/library/page-authoring/button.html",
28 | "lastModified": 1547062227177,
29 | "description": "Display a button or anchor button",
30 | "title": "Button",
31 | "path": "/content/core-components-examples/library/page-authoring/button"
32 | },
33 | {
34 | "url": "/content/core-components-examples/library/page-authoring/teaser.html",
35 | "lastModified": 1575799718587,
36 | "description": "Link an image and text",
37 | "title": "Teaser",
38 | "path": "/content/core-components-examples/library/page-authoring/teaser"
39 | },
40 | {
41 | "url": "/content/core-components-examples/library/page-authoring/download.html",
42 | "lastModified": 1558992253683,
43 | "description": "Display an asset for download",
44 | "title": "Download",
45 | "path": "/content/core-components-examples/library/page-authoring/download"
46 | },
47 | {
48 | "url": "/content/core-components-examples/library/page-authoring/list.html",
49 | "lastModified": 1547642282466,
50 | "description": "Display a list of pages",
51 | "title": "List",
52 | "path": "/content/core-components-examples/library/page-authoring/list"
53 | },
54 | {
55 | "url": "/content/core-components-examples/library/page-authoring/experience-fragment.html",
56 | "lastModified": 1566294323252,
57 | "description": "Display an experience fragment",
58 | "title": "Experience Fragment",
59 | "path": "/content/core-components-examples/library/page-authoring/experience-fragment"
60 | },
61 | {
62 | "url": "/content/core-components-examples/library/page-authoring/content-fragment.html",
63 | "lastModified": 1547644839952,
64 | "description": "Display a content fragment asset",
65 | "title": "Content Fragment",
66 | "path": "/content/core-components-examples/library/page-authoring/content-fragment"
67 | },
68 | {
69 | "url": "/content/core-components-examples/library/page-authoring/content-fragment-list.html",
70 | "lastModified": 1554130037469,
71 | "description": "Display a list of content fragments",
72 | "title": "Content Fragment List",
73 | "path": "/content/core-components-examples/library/page-authoring/content-fragment-list"
74 | },
75 | {
76 | "url": "/content/core-components-examples/library/page-authoring/embed.html",
77 | "lastModified": 1567092519658,
78 | "description": "Embed a third-party widget",
79 | "title": "Embed",
80 | "path": "/content/core-components-examples/library/page-authoring/embed"
81 | },
82 | {
83 | "url": "/content/core-components-examples/library/page-authoring/social-sharing.html",
84 | "lastModified": 1547062206375,
85 | "description": "Add social sharing links",
86 | "title": "Social Sharing",
87 | "path": "/content/core-components-examples/library/page-authoring/social-sharing"
88 | },
89 | {
90 | "url": "/content/core-components-examples/library/page-authoring/separator.html",
91 | "lastModified": 1547062195738,
92 | "description": "Display a section divider",
93 | "title": "Separator",
94 | "path": "/content/core-components-examples/library/page-authoring/separator"
95 | }
96 | ];
97 |
98 |
99 | export const mockItemsWithRouting:ListV2Item[] = [
100 | {
101 | "url": "/content/core-components-examples/library/page-authoring/title.html",
102 | "lastModified": 1547642198741,
103 | "description": "Display a page heading",
104 | "title": "Title",
105 | "path": "/content/core-components-examples/library/page-authoring/title",
106 | "routed": true
107 | },
108 | {
109 | "url": "/content/core-components-examples/library/page-authoring/text.html",
110 | "lastModified": 1548159422163,
111 | "description": "Display a rich text paragraph",
112 | "title": "Text",
113 | "path": "/content/core-components-examples/library/page-authoring/text",
114 | "routed": true
115 | },
116 | {
117 | "url": "/content/core-components-examples/library/page-authoring/image.html",
118 | "lastModified": 1550255022224,
119 | "description": "Display an image asset",
120 | "title": "Image",
121 | "path": "/content/core-components-examples/library/page-authoring/image",
122 | "routed": true
123 | },
124 | {
125 | "url": "/content/core-components-examples/library/page-authoring/button.html",
126 | "lastModified": 1547062227177,
127 | "description": "Display a button or anchor button",
128 | "title": "Button",
129 | "path": "/content/core-components-examples/library/page-authoring/button",
130 | "routed": true
131 | },
132 | {
133 | "url": "/content/core-components-examples/library/page-authoring/teaser.html",
134 | "lastModified": 1575799718587,
135 | "description": "Link an image and text",
136 | "title": "Teaser",
137 | "path": "/content/core-components-examples/library/page-authoring/teaser",
138 | "routed": true
139 | },
140 | {
141 | "url": "/content/core-components-examples/library/page-authoring/download.html",
142 | "lastModified": 1558992253683,
143 | "description": "Display an asset for download",
144 | "title": "Download",
145 | "path": "/content/core-components-examples/library/page-authoring/download",
146 | "routed": true
147 | },
148 | {
149 | "url": "/content/core-components-examples/library/page-authoring/list.html",
150 | "lastModified": 1547642282466,
151 | "description": "Display a list of pages",
152 | "title": "List",
153 | "path": "/content/core-components-examples/library/page-authoring/list",
154 | "routed": true
155 | },
156 | {
157 | "url": "/content/core-components-examples/library/page-authoring/experience-fragment.html",
158 | "lastModified": 1566294323252,
159 | "description": "Display an experience fragment",
160 | "title": "Experience Fragment",
161 | "path": "/content/core-components-examples/library/page-authoring/experience-fragment",
162 | "routed": true
163 | },
164 | {
165 | "url": "/content/core-components-examples/library/page-authoring/content-fragment.html",
166 | "lastModified": 1547644839952,
167 | "description": "Display a content fragment asset",
168 | "title": "Content Fragment",
169 | "path": "/content/core-components-examples/library/page-authoring/content-fragment",
170 | "routed": true
171 | },
172 | {
173 | "url": "/content/core-components-examples/library/page-authoring/content-fragment-list.html",
174 | "lastModified": 1554130037469,
175 | "description": "Display a list of content fragments",
176 | "title": "Content Fragment List",
177 | "path": "/content/core-components-examples/library/page-authoring/content-fragment-list",
178 | "routed": true
179 | },
180 | {
181 | "url": "/content/core-components-examples/library/page-authoring/embed.html",
182 | "lastModified": 1567092519658,
183 | "description": "Embed a third-party widget",
184 | "title": "Embed",
185 | "path": "/content/core-components-examples/library/page-authoring/embed",
186 | "routed": true
187 | },
188 | {
189 | "url": "/content/core-components-examples/library/page-authoring/social-sharing.html",
190 | "lastModified": 1547062206375,
191 | "description": "Add social sharing links",
192 | "title": "Social Sharing",
193 | "path": "/content/core-components-examples/library/page-authoring/social-sharing",
194 | "routed": true
195 | },
196 | {
197 | "url": "/content/core-components-examples/library/page-authoring/separator.html",
198 | "lastModified": 1547062195738,
199 | "description": "Display a section divider",
200 | "title": "Separator",
201 | "path": "/content/core-components-examples/library/page-authoring/separator",
202 | "routed": true
203 | }
204 | ];
205 |
206 | export const dummyProps:ListV2Model = {
207 | hidePlaceHolder: false,
208 | isInEditor: false,
209 | dateFormatString: "yyyy-MM-dd",
210 | showDescription: true,
211 | showModificationDate: true,
212 | linkItems: true,
213 | routed: false,
214 | items: mockItems
215 | };
216 |
217 | export const dummyPropsWithDefaultRouting:ListV2Model = {
218 | hidePlaceHolder: false,
219 | isInEditor: false,
220 | dateFormatString: "yyyy-MM-dd",
221 | showDescription: true,
222 | showModificationDate: true,
223 | linkItems: true,
224 | routed: true,
225 | items: mockItems
226 | };
227 |
228 | export const dummyPropsWithRoutedItems:ListV2Model = {
229 | hidePlaceHolder: false,
230 | isInEditor: false,
231 | dateFormatString: "yyyy-MM-dd",
232 | showDescription: true,
233 | showModificationDate: true,
234 | linkItems: true,
235 | items: mockItemsWithRouting
236 | };
237 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/src/layout/navigation/v1/NavigationV1TestMockItems.ts:
--------------------------------------------------------------------------------
1 | import {NavigationV1Item} from "./NavigationV1";
2 |
3 | export const items:NavigationV1Item[] = [
4 | {
5 | "children": [
6 | {
7 | "children": [
8 | {
9 | "children": [],
10 | "level": 2,
11 | "active": true,
12 | "url": "/content/core-components-examples/library/templating/navigation.html",
13 | "lastModified": 1558694278229,
14 | "description": "Display a site navigation menu",
15 | "title": "Navigation",
16 | "path": "/content/core-components-examples/library/templating/navigation"
17 | },
18 | {
19 | "children": [],
20 | "level": 2,
21 | "active": false,
22 | "url": "/content/core-components-examples/library/templating/language-navigation/language-structure/us/en/language-navigation.html",
23 | "lastModified": 1559807944878,
24 | "description": "Display a language switcher",
25 | "title": "Language Navigation",
26 | "path": "/content/core-components-examples/library/templating/language-navigation/language-structure/us/en/language-navigation"
27 | },
28 | {
29 | "children": [],
30 | "level": 2,
31 | "active": false,
32 | "url": "/content/core-components-examples/library/templating/breadcrumb/hidden/level-1/level-2/breadcrumb.html",
33 | "lastModified": 1558607623701,
34 | "description": "Display a breadcrumb navigation",
35 | "title": "Breadcrumb",
36 | "path": "/content/core-components-examples/library/templating/breadcrumb/hidden/level-1/level-2/breadcrumb"
37 | }
38 | ],
39 | "level": 1,
40 | "active": true,
41 | "url": "/content/core-components-examples/library/templating.html",
42 | "lastModified": 1544121656470,
43 | "description": "",
44 | "title": "Templating",
45 | "path": "/content/core-components-examples/library/templating"
46 | },
47 | {
48 | "children": [
49 | {
50 | "children": [],
51 | "level": 2,
52 | "active": false,
53 | "url": "/content/core-components-examples/library/page-authoring/title.html",
54 | "lastModified": 1547642198741,
55 | "description": "Display a page heading",
56 | "title": "Title",
57 | "path": "/content/core-components-examples/library/page-authoring/title"
58 | },
59 | {
60 | "children": [],
61 | "level": 2,
62 | "active": false,
63 | "url": "/content/core-components-examples/library/page-authoring/text.html",
64 | "lastModified": 1548159422163,
65 | "description": "Display a rich text paragraph",
66 | "title": "Text",
67 | "path": "/content/core-components-examples/library/page-authoring/text"
68 | },
69 | {
70 | "children": [],
71 | "level": 2,
72 | "active": false,
73 | "url": "/content/core-components-examples/library/page-authoring/image.html",
74 | "lastModified": 1550255022224,
75 | "description": "Display an image asset",
76 | "title": "Image",
77 | "path": "/content/core-components-examples/library/page-authoring/image"
78 | },
79 | {
80 | "children": [],
81 | "level": 2,
82 | "active": false,
83 | "url": "/content/core-components-examples/library/page-authoring/button.html",
84 | "lastModified": 1547062227177,
85 | "description": "Display a button or anchor button",
86 | "title": "Button",
87 | "path": "/content/core-components-examples/library/page-authoring/button"
88 | },
89 | {
90 | "children": [],
91 | "level": 2,
92 | "active": false,
93 | "url": "/content/core-components-examples/library/page-authoring/teaser.html",
94 | "lastModified": 1575799718587,
95 | "description": "Link an image and text",
96 | "title": "Teaser",
97 | "path": "/content/core-components-examples/library/page-authoring/teaser"
98 | },
99 | {
100 | "children": [],
101 | "level": 2,
102 | "active": false,
103 | "url": "/content/core-components-examples/library/page-authoring/download.html",
104 | "lastModified": 1558992253683,
105 | "description": "Display an asset for download",
106 | "title": "Download",
107 | "path": "/content/core-components-examples/library/page-authoring/download"
108 | },
109 | {
110 | "children": [],
111 | "level": 2,
112 | "active": false,
113 | "url": "/content/core-components-examples/library/page-authoring/list.html",
114 | "lastModified": 1547642282466,
115 | "description": "Display a list of pages",
116 | "title": "List",
117 | "path": "/content/core-components-examples/library/page-authoring/list"
118 | },
119 | {
120 | "children": [],
121 | "level": 2,
122 | "active": false,
123 | "url": "/content/core-components-examples/library/page-authoring/experience-fragment.html",
124 | "lastModified": 1566294323252,
125 | "description": "Display an experience fragment",
126 | "title": "Experience Fragment",
127 | "path": "/content/core-components-examples/library/page-authoring/experience-fragment"
128 | },
129 | {
130 | "children": [],
131 | "level": 2,
132 | "active": false,
133 | "url": "/content/core-components-examples/library/page-authoring/content-fragment.html",
134 | "lastModified": 1547644839952,
135 | "description": "Display a content fragment asset",
136 | "title": "Content Fragment",
137 | "path": "/content/core-components-examples/library/page-authoring/content-fragment"
138 | },
139 | {
140 | "children": [],
141 | "level": 2,
142 | "active": false,
143 | "url": "/content/core-components-examples/library/page-authoring/content-fragment-list.html",
144 | "lastModified": 1554130037469,
145 | "description": "Display a list of content fragments",
146 | "title": "Content Fragment List",
147 | "path": "/content/core-components-examples/library/page-authoring/content-fragment-list"
148 | },
149 | {
150 | "children": [],
151 | "level": 2,
152 | "active": false,
153 | "url": "/content/core-components-examples/library/page-authoring/embed.html",
154 | "lastModified": 1567092519658,
155 | "description": "Embed a third-party widget",
156 | "title": "Embed",
157 | "path": "/content/core-components-examples/library/page-authoring/embed"
158 | },
159 | {
160 | "children": [],
161 | "level": 2,
162 | "active": false,
163 | "url": "/content/core-components-examples/library/page-authoring/social-sharing.html",
164 | "lastModified": 1547062206375,
165 | "description": "Add social sharing links",
166 | "title": "Social Sharing",
167 | "path": "/content/core-components-examples/library/page-authoring/social-sharing"
168 | },
169 | {
170 | "children": [],
171 | "level": 2,
172 | "active": false,
173 | "url": "/content/core-components-examples/library/page-authoring/separator.html",
174 | "lastModified": 1547062195738,
175 | "description": "Display a section divider",
176 | "title": "Separator",
177 | "path": "/content/core-components-examples/library/page-authoring/separator"
178 | }
179 | ],
180 | "level": 1,
181 | "active": false,
182 | "url": "/content/core-components-examples/library/page-authoring.html",
183 | "lastModified": 1544121656470,
184 | "description": "",
185 | "title": "Page Authoring",
186 | "path": "/content/core-components-examples/library/page-authoring"
187 | },
188 | {
189 | "children": [
190 | {
191 | "children": [],
192 | "level": 2,
193 | "active": false,
194 | "url": "/content/core-components-examples/library/container/container.html",
195 | "lastModified": 1560275793712,
196 | "description": "Group and layout components",
197 | "title": "Container",
198 | "path": "/content/core-components-examples/library/container/container"
199 | },
200 | {
201 | "children": [],
202 | "level": 2,
203 | "active": false,
204 | "url": "/content/core-components-examples/library/container/carousel.html",
205 | "lastModified": 1550252345916,
206 | "description": "Cycle through content panels",
207 | "title": "Carousel",
208 | "path": "/content/core-components-examples/library/container/carousel"
209 | },
210 | {
211 | "children": [],
212 | "level": 2,
213 | "active": false,
214 | "url": "/content/core-components-examples/library/container/tabs.html",
215 | "lastModified": 1548157896096,
216 | "description": "Switchable content panels",
217 | "title": "Tabs",
218 | "path": "/content/core-components-examples/library/container/tabs"
219 | },
220 | {
221 | "children": [],
222 | "level": 2,
223 | "active": false,
224 | "url": "/content/core-components-examples/library/container/accordion.html",
225 | "lastModified": 1548157896096,
226 | "description": "Toggle panels of related content",
227 | "title": "Accordion",
228 | "path": "/content/core-components-examples/library/container/accordion"
229 | }
230 | ],
231 | "level": 1,
232 | "active": false,
233 | "url": "/content/core-components-examples/library/container.html",
234 | "lastModified": 1544121656470,
235 | "description": "",
236 | "title": "Container",
237 | "path": "/content/core-components-examples/library/container"
238 | },
239 | {
240 | "children": [
241 | {
242 | "children": [],
243 | "level": 2,
244 | "active": false,
245 | "url": "/content/core-components-examples/library/form/container.html",
246 | "lastModified": 1576771730790,
247 | "description": "Group and Layout Form Components",
248 | "title": "Container",
249 | "path": "/content/core-components-examples/library/form/container"
250 | },
251 | {
252 | "children": [],
253 | "level": 2,
254 | "active": false,
255 | "url": "/content/core-components-examples/library/form/input.html",
256 | "lastModified": 1576767461500,
257 | "description": "Display an input field",
258 | "title": "Input",
259 | "path": "/content/core-components-examples/library/form/input"
260 | },
261 | {
262 | "children": [],
263 | "level": 2,
264 | "active": false,
265 | "url": "/content/core-components-examples/library/form/options.html",
266 | "lastModified": 1579192036788,
267 | "description": "Display different options to choose from",
268 | "title": "Options",
269 | "path": "/content/core-components-examples/library/form/options"
270 | },
271 | {
272 | "children": [],
273 | "level": 2,
274 | "active": false,
275 | "url": "/content/core-components-examples/library/form/hidden.html",
276 | "lastModified": 1576771327704,
277 | "description": "Hidden Form Component ",
278 | "title": "Hidden",
279 | "path": "/content/core-components-examples/library/form/hidden"
280 | },
281 | {
282 | "children": [],
283 | "level": 2,
284 | "active": false,
285 | "url": "/content/core-components-examples/library/form/button.html",
286 | "lastModified": 1576770945395,
287 | "description": "Display a form button",
288 | "title": "Button",
289 | "path": "/content/core-components-examples/library/form/button"
290 | }
291 | ],
292 | "level": 1,
293 | "active": false,
294 | "url": "/content/core-components-examples/library/form.html",
295 | "lastModified": 1544121656470,
296 | "description": "null",
297 | "title": "Form",
298 | "path": "/content/core-components-examples/library/form"
299 | }
300 | ],
301 | "level": 0,
302 | "active": true,
303 | "url": "/content/core-components-examples/library.html",
304 | "lastModified": 1559143556781,
305 | "description": "AEM Core Components - Component Library",
306 | "title": "Component Library",
307 | "path": "/content/core-components-examples/library"
308 | }
309 | ];
310 |
311 |
--------------------------------------------------------------------------------