Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## v2412.0.0

*Released 04.03.2025*

### Breaking Changes:

- Updated `schema.json` to CoreMedia Content Cloud v12 - 2604.0

### Features:

- Added navigation breadcrumb
- Added anchor links und table of contents for detail pages (articles)

### Bugfixes and Changes:

- Updated minor versions of dependencies

---

## v2406.0.1

*Released 13.08.2024*
Expand All @@ -19,7 +38,6 @@
- Updated pnpm to version 9
- Updated `schema.json` to CoreMedia Content Cloud v12 - 2604.0


### Features:

- Changed `.graphqlconfig` to new format `graphql.config.yml`
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![CoreMedia Labs Logo](https://documentation.coremedia.com/badges/banner_coremedia_labs_wide.png)

![CoreMedia Content Cloud Version](https://img.shields.io/static/v1?message=2406&label=CoreMedia%20Content%20Cloud&style=for-the-badge&labelColor=666666&color=672779
![CoreMedia Content Cloud Version](https://img.shields.io/static/v1?message=2412&label=CoreMedia%20Content%20Cloud&style=for-the-badge&labelColor=666666&color=672779
"This badge shows the CoreMedia version this project is compatible with.
Please read the versioning section of the project to see what other CoreMedia versions are supported and how to find them."
)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
75 changes: 39 additions & 36 deletions apps/spark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,34 @@
"version": "1.0.0",
"private": true,
"license": "CoreMedia Open Source License",
"type": "module",
"scripts": {
"start": "vite",
"serve": "vite preview",
"build": "pnpm set-version && vite build",
"set-version": "node ./bin/set-version.js",
"set-version": "node bin/set-version.cjs",
"test": "vitest run",
"lint": "eslint --fix \"src/**/*.+(ts|tsx)\"",
"lint:ci": "eslint \"src/**/*.+(ts|tsx)\"",
"docs": "typedoc src",
"download:crops": "node ./bin/download-crops.js",
"download:crops": "node bin/download-crops.cjs",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build -o dist/storybook"
},
"dependencies": {
"@apollo/client": "^3.11.4",
"@apollo/client": "^3.11.10",
"@coremedia-labs/graphql-layer": "workspace:^",
"@coremedia-labs/preview-integration": "workspace:^",
"@coremedia-labs/view-dispatcher": "workspace:^",
"@js-joda/core": "^5.6.3",
"@js-joda/timezone": "^2.21.1",
"country-flag-icons": "^1.5.12",
"country-flag-icons": "^1.5.13",
"crypto-hash": "^2.0.1",
"graphql": "^16.8.2",
"i18next": "^23.11.5",
"graphql": "^16.9.0",
"i18next": "^23.16.8",
"i18next-browser-languagedetector": "^7.2.1",
"i18next-http-backend": "^2.5.2",
"loglevel": "^1.9.1",
"i18next-http-backend": "^2.7.1",
"loglevel": "^1.9.2",
"query-string": "^7.1.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
Expand All @@ -39,47 +40,49 @@
"react-player": "^2.16.0",
"react-responsive": "^9.0.2",
"react-router-dom": "^5.3.4",
"react-router-hash-link": "^2.4.3",
"react-slick": "^0.30.2",
"require-from-string": "^2.0.2",
"slick-carousel": "^1.8.1",
"styled-components": "^5.3.11"
},
"devDependencies": {
"@chromatic-com/storybook": "^1.5.0",
"@storybook/addon-actions": "^8.1.10",
"@storybook/addon-backgrounds": "^8.1.10",
"@storybook/addon-docs": "^8.1.10",
"@storybook/addon-essentials": "^8.1.10",
"@storybook/addon-links": "^8.1.10",
"@storybook/addon-measure": "^8.1.10",
"@storybook/addon-outline": "^8.1.10",
"@storybook/client-logger": "^8.1.10",
"@storybook/node-logger": "^8.1.10",
"@storybook/react": "^8.1.10",
"@storybook/react-vite": "^8.1.10",
"@types/node": "^20.14.5",
"@types/react": "^17.0.80",
"@chromatic-com/storybook": "^3.2.2",
"@storybook/addon-actions": "^8.4.5",
"@storybook/addon-backgrounds": "^8.4.5",
"@storybook/addon-docs": "^8.4.5",
"@storybook/addon-essentials": "^8.4.5",
"@storybook/addon-links": "^8.4.5",
"@storybook/addon-measure": "^8.4.5",
"@storybook/addon-outline": "^8.4.5",
"@storybook/client-logger": "^8.4.5",
"@storybook/node-logger": "^8.4.5",
"@storybook/react": "^8.4.5",
"@storybook/react-vite": "^8.4.5",
"@types/node": "^20.17.6",
"@types/react": "^17.0.83",
"@types/react-dom": "^17.0.25",
"@types/react-router-dom": "^5.3.3",
"@types/react-router-hash-link": "^2.4.9",
"@types/react-slick": "^0.23.13",
"@types/styled-components": "^5.1.34",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@vitejs/plugin-react-swc": "^3.7.0",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"@vitejs/plugin-react-swc": "^3.7.1",
"dotenv": "^16.4.5",
"eslint": "^8.57.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.34.3",
"eslint-plugin-storybook": "^0.8.0",
"prettier": "^3.3.2",
"storybook": "^8.1.10",
"typedoc": "^0.25.13",
"eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-storybook": "^0.11.1",
"prettier": "^3.3.3",
"storybook": "^8.4.5",
"typedoc": "^0.26.11",
"typescript": "~5.2.2",
"vite": "^4.5.3",
"vitest": "^0.34.6"
"vite": "^5.4.17",
"vitest": "^2.1.9"
},
"browserslist": {
"production": [
Expand Down
6 changes: 6 additions & 0 deletions apps/spark/public/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@
"relatedProducts": "Produkte",
"related": "Ähnliche Inhalte"
},
"DetailTOC": {
"title": "Auf dieser Seite"
},
"ScrollTopLink": {
"text": "Nach oben scrollen"
},
"CheckoutPage": {
"successTitle": "Checkout abgeschlossen",
"successMessage": "<p>Danke für Ihre Bestellung.</p><p>Unser Team ist gerade dabei, Ihre Bestellung zu verpacken und zu versenden.</p><p>Wir werden Sie informieren, sobald die Ware auf dem Weg zu Ihnen ist.</p>",
Expand Down
6 changes: 6 additions & 0 deletions apps/spark/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@
"relatedProducts": "Products",
"related": "Related"
},
"DetailTOC": {
"title": "On this page"
},
"ScrollTopLink": {
"text": "Scroll to top"
},
"CheckoutPage": {
"successTitle": "Checkout Completed",
"successMessage": "<p>Thank you for your order.</p><p>Our team is currently packing and shipping your order.<br />We will inform you as soon as the goods are on their way to you.</p>",
Expand Down
6 changes: 6 additions & 0 deletions apps/spark/public/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@
"relatedProducts": "Produits",
"related": "Contenu connexe"
},
"DetailTOC": {
"title": "Sur cette page"
},
"ScrollTopLink": {
"text": "Haut de page"
},
"CheckoutPage": {
"successTitle": "Checkout terminé",
"successMessage": "<p>Merci pour votre commande.</p><p>Notre équipe est actuellement en train d'emballer et d'expédier votre commande.<br />Nous vous informerons dès que les marchandises seront en route vers vous.</p>",
Expand Down
6 changes: 6 additions & 0 deletions apps/spark/public/locales/it/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@
"relatedProducts": "Prodotti",
"related": "Contenuto relativo"
},
"DetailTOC": {
"title": "Su questa pagina"
},
"ScrollTopLink": {
"text": "Scorri in alto"
},
"CheckoutPage": {
"successTitle": "Checkout completato",
"successMessage": "<p>Grazie per il suo ordine.</p><p>Il nostro team sta attualmente imballando e spedendo il suo ordine.<br />La informeremo non appena la merce sarà in viaggio verso di lei.</p>",
Expand Down
1 change: 1 addition & 0 deletions apps/spark/src/components/App/GlobalStyle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const GlobalStyle = createGlobalStyle`
--color-turquoise: #6fc3b8;
--color-green: #2fac66;
--color-yellow: #efdf0f;
--color-grey: #919191;
--color-light-grey: #f4f4f4;
--color-black: #000;
--color-white: #fff;
Expand Down
17 changes: 11 additions & 6 deletions apps/spark/src/components/App/PageContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ import FooterNavigation from "../Footer/FooterNavigation";
import Footer from "../Footer/Footer";
import { metaDataForResponsiveDevices } from "../../utils/Preview/MetaData";
import { StyledGrid } from "../PageGrid/PageGrid";
import { BreadcrumbContextProvider } from "../../context/BreadcrumbContext";
import Breadcrumb from "../Breadcrumb/Breadcrumb";

const PageContext: FC = ({ children }) => {
return (
<StyledGrid className={"cm-grid "} {...metaDataForResponsiveDevices()}>
<Header />
{children}
<FooterNavigation />
<Footer />
</StyledGrid>
<BreadcrumbContextProvider>
<StyledGrid className={"cm-grid "} {...metaDataForResponsiveDevices()}>
<Header />
<Breadcrumb />
{children}
<FooterNavigation />
<Footer />
</StyledGrid>
</BreadcrumbContextProvider>
);
};
export default PageContext;
88 changes: 88 additions & 0 deletions apps/spark/src/components/Breadcrumb/Breadcrumb.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React from "react";
import styled from "styled-components";
import Link from "../Link/Link";
import { useBreadcrumbContext } from "../../context/BreadcrumbContext";
import { initializeMetadata, metaDataElement } from "../../utils/Preview/MetaData";
import HomeIcon from "./assets/house.svg";

export const BreadcrumbItem = styled.div`
display: inline-block;
`;

export const StyledBreadcrumb = styled.div`
display: flex;
flex-wrap: nowrap;
justify-content: flex-start;
justify-items: center;
align-items: stretch;
padding: 1em 0;
width: var(--screen-size-max);
max-width: 100%;
color: var(--color-grey);
font-size: var(--font-size-text-small);
font-family: var(--font-family-text);
margin-top: var(--padding-medium);
gap: 0;
border-top: 1px solid var(--color-light-grey);
border-bottom: 1px solid var(--color-light-grey);

${BreadcrumbItem}:not(:last-child):after {
content: ">";
margin: 0 0.5em;
}

img {
height: 1em;
aspect-ratio: 1/1;
}

a {
color: var(--color-grey);
text-decoration: none;
}

a:hover {
text-decoration: underline;
}
`;

const Breadcrumb: React.FC = () => {
const { navigationPath } = useBreadcrumbContext();
if (!navigationPath || navigationPath.length < 2) {
return null;
}

// Calculate breadcrumb items incl. link target
const breadcrumbItems = navigationPath.map((item, index) => {
return {
title: item.title,
linkTarget: item.segment
? "/" +
navigationPath
.slice(0, index + 1)
.map((i) => i.segment)
.join("/")
: "",
...initializeMetadata(item.id),
};
});

return (
<StyledBreadcrumb>
{breadcrumbItems.map((item, index) => {
return (
<BreadcrumbItem key={index} {...metaDataElement(item.metadata)}>
<Link to={item.linkTarget}>
<span>
{index == 0 && <img src={HomeIcon} alt="Home" />}
{index > 0 && item.title}
</span>
</Link>
</BreadcrumbItem>
);
})}
</StyledBreadcrumb>
);
};

export default Breadcrumb;
5 changes: 5 additions & 0 deletions apps/spark/src/components/Breadcrumb/assets/house.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/spark/src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Link from "../Link/Link";

interface Props {
linkTarget?: any;
anchor?: string;
clickHandler?: () => void;
text?: string;
additionalClass?: string;
Expand Down Expand Up @@ -55,6 +56,7 @@ export const StyledButton = styled.div<{ primary?: boolean }>`

const Button: React.FC<Props> = ({
linkTarget,
anchor,
clickHandler,
text,
additionalClass,
Expand All @@ -73,6 +75,7 @@ const Button: React.FC<Props> = ({
<StyledButton
as={Link}
to={linkTarget}
anchor={anchor}
clickHandler={clickHandler}
className={additionalClass}
role={"button"}
Expand Down
2 changes: 2 additions & 0 deletions apps/spark/src/components/CTA/CTA.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const CTA: React.FC<Props> = ({ targets, additionalClass, additionalButtonClass,
<Button
key={index}
linkTarget={target.linkTarget}
anchor={target.anchor}
clickHandler={target.clickHandler}
text={target.callToActionText}
additionalClass={additionalButtonClass}
openInNewTab={target.openInNewTab}
Expand Down
4 changes: 4 additions & 0 deletions apps/spark/src/components/Details/Detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import RichText from "../RichText/RichText";
import { ImageBox } from "../Media/ResponsiveImage";
import TagList from "../Tags/Taglist";
import DetailedMedia from "./DetailedMedia";
import DetailTOC from "./DetailTOC";

export const StyledDetail = styled.div`
@media screen and (min-width: 1200px) {
Expand Down Expand Up @@ -114,6 +115,9 @@ const Detail: React.FC<DetailModel> = ({
{readTime && <span>{readTime} min read</span>}
</MetaList>
{media && <DetailedMedia media={media} />}

{/* Table of contents */}
<DetailTOC structuredText={structuredText} />
{structuredText && (
<Text {...metaDataProperty(metadata.properties?.structuredText)}>
<RichText text={structuredText} embeddedItems={structuredTextLinks} />
Expand Down
Loading