sfc-utils 1.3.65 → 1.3.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/captioncredit.mjs +21 -21
- package/components/helpers/utilfunctions.mjs +71 -8
- package/components/layout/layouthelmet.mjs +125 -0
- package/components/layout/layoutscript.mjs +12 -0
- package/components/ogpubdate.mjs +18 -0
- package/components/slideshow/captioncreditslideshow.mjs +7 -4
- package/components/slideshow/imageslideshow.mjs +17 -2
- package/components/topper2.mjs +184 -23
- package/components/topperimage.mjs +7 -2
- package/example/gatsby-node.js +3 -4
- package/example/package-lock.json +18566 -133
- package/example/src/components/layout.js +19 -159
- package/example/src/html.js +2 -2
- package/example/src/pages/index.js +3 -10
- package/package.json +1 -1
- package/settings.js +1 -1
- package/styles/brandStylesCommon.less +5 -9
- package/styles/modules/imageslideshow.module.less +45 -0
- package/styles/modules/topper2.module.less +239 -0
- package/styles/modules/topperimage.module.less +85 -0
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
// import * as capcredStyles from "../styles/modules/captioncredit.module.less"
|
|
3
2
|
|
|
4
|
-
const CaptionCredit = (
|
|
5
|
-
let
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
const CaptionCredit = ({ caption, credit, extraStyles, creditStyles = [] }) => {
|
|
4
|
+
let captionCss = ["topper-image", "caption"];
|
|
5
|
+
if (extraStyles) {
|
|
6
|
+
captionCss = captionCss.concat(extraStyles);
|
|
7
|
+
}
|
|
9
8
|
|
|
9
|
+
let creditCss = `credit ${creditStyles.join(" ")}`
|
|
10
10
|
return (
|
|
11
11
|
<>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
12
|
+
{caption && credit && (
|
|
13
|
+
<figcaption className={captionCss.join(' ')}>
|
|
14
|
+
{caption} <span className={creditCss}>{credit}</span>
|
|
15
|
+
</figcaption>
|
|
16
|
+
)}
|
|
17
|
+
{!caption && credit && (
|
|
18
|
+
<figcaption className={captionCss.join(' ')}>
|
|
19
|
+
<span className={creditCss}>{credit}</span>
|
|
20
|
+
</figcaption>
|
|
21
|
+
)}
|
|
22
|
+
{caption && !credit && (
|
|
23
|
+
<figcaption className={captionCss.join(' ')}>
|
|
24
|
+
{caption}
|
|
25
|
+
</figcaption>
|
|
26
|
+
)}
|
|
27
27
|
</>
|
|
28
28
|
)
|
|
29
29
|
}
|
|
@@ -1,12 +1,75 @@
|
|
|
1
|
+
import { getBlueconic } from "../../blueconic"
|
|
2
|
+
import { appCheck, blendHDN } from "../../index"
|
|
3
|
+
|
|
4
|
+
/** Used for resizing the WCM Image */
|
|
1
5
|
function debounce(fn, ms) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
let timer
|
|
7
|
+
return _ => {
|
|
8
|
+
clearTimeout(timer)
|
|
9
|
+
timer = setTimeout(_ => {
|
|
10
|
+
timer = null
|
|
11
|
+
fn.apply(this, arguments)
|
|
12
|
+
}, ms)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function appendLayoutScripts(isEmbedded, isAdRemoved) {
|
|
17
|
+
const isApp = appCheck();
|
|
18
|
+
|
|
19
|
+
// React Helmet is actually terrible and runs these scripts twice, so we are including them async ourselves
|
|
20
|
+
// Run analytics and resizing scripts right away so we take care of that
|
|
21
|
+
if (!isEmbedded) {
|
|
22
|
+
let script = document.createElement('script');
|
|
23
|
+
script.type = 'text/javascript';
|
|
24
|
+
script.src = 'https://nexus.ensighten.com/hearst/news/Bootstrap.js';
|
|
25
|
+
document.body.appendChild(script);
|
|
26
|
+
} else {
|
|
27
|
+
let script = document.createElement('script');
|
|
28
|
+
script.type = 'text/javascript';
|
|
29
|
+
script.src = 'https://projects.sfchronicle.com/shared/js/responsive-child.js';
|
|
30
|
+
document.body.appendChild(script);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!isEmbedded && !isAdRemoved) {
|
|
34
|
+
let script = document.createElement('script');
|
|
35
|
+
script.type = 'text/javascript';
|
|
36
|
+
script.id = 'adPositionManagerScriptTag';
|
|
37
|
+
script.src = 'https://aps.hearstnp.com/Scripts/loadAds.js';
|
|
38
|
+
document.body.appendChild(script);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Wait a beat, then add to body so it doesn't mess with the head (which Helmet seems to want to manage)
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
if (!isEmbedded && !isApp) {
|
|
44
|
+
let blueconicURL = getBlueconic(window.location.origin)
|
|
45
|
+
let script = document.createElement('script');
|
|
46
|
+
script.type = 'text/javascript';
|
|
47
|
+
script.defer = true;
|
|
48
|
+
script.src = blueconicURL;
|
|
49
|
+
document.body.appendChild(script);
|
|
50
|
+
}
|
|
51
|
+
}, 5000)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function formatHDN(isEmbedded, url_add, meta) {
|
|
55
|
+
const isApp = appCheck();
|
|
56
|
+
|
|
57
|
+
// Combine our settings with what Hearst puts on page
|
|
58
|
+
let stringHDN = ''
|
|
59
|
+
if (!isEmbedded) {
|
|
60
|
+
// Put url_add into a new meta object to pass in
|
|
61
|
+
const metaHDN = Object.assign({}, meta)
|
|
62
|
+
metaHDN.URL_ADD = url_add
|
|
63
|
+
// Make sure this is free on app
|
|
64
|
+
if (isApp) {
|
|
65
|
+
metaHDN.PAYWALL_SETTING = "free"
|
|
9
66
|
}
|
|
67
|
+
// Allow gift button to appear next to sharebuttons
|
|
68
|
+
metaHDN.GIFT_ENABLED = true
|
|
69
|
+
let blended = blendHDN(metaHDN)
|
|
70
|
+
stringHDN = blended.stringHDN
|
|
10
71
|
}
|
|
72
|
+
return stringHDN;
|
|
73
|
+
}
|
|
11
74
|
|
|
12
|
-
export { debounce }
|
|
75
|
+
export { debounce, appendLayoutScripts, formatHDN }
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { Helmet } from 'react-helmet'
|
|
4
|
+
import { appCheck, getBrands2 } from "../../index"
|
|
5
|
+
|
|
6
|
+
const LayoutHelmet = ({ meta, url_add }) => {
|
|
7
|
+
let {
|
|
8
|
+
EMBEDDED,
|
|
9
|
+
MAIN_DOMAIN,
|
|
10
|
+
PROJECT: {
|
|
11
|
+
AUTHORS,
|
|
12
|
+
DESCRIPTION,
|
|
13
|
+
IMAGE,
|
|
14
|
+
ISO_MODDATE,
|
|
15
|
+
ISO_PUBDATE,
|
|
16
|
+
OPT_SLASH,
|
|
17
|
+
SLUG,
|
|
18
|
+
SOCIAL_TITLE,
|
|
19
|
+
SUBFOLDER,
|
|
20
|
+
TITLE,
|
|
21
|
+
MARKET_KEY,
|
|
22
|
+
CANONICAL_URL
|
|
23
|
+
},
|
|
24
|
+
} = meta
|
|
25
|
+
|
|
26
|
+
const isApp = appCheck()
|
|
27
|
+
const thisBrand = getBrands2(MARKET_KEY);
|
|
28
|
+
|
|
29
|
+
// Get stylesheet id from market key
|
|
30
|
+
let styleSheetID
|
|
31
|
+
if ((MARKET_KEY === "SFC") || (MARKET_KEY === "Houston") || (MARKET_KEY === "Albany")) {
|
|
32
|
+
styleSheetID = MARKET_KEY
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
styleSheetID = "default"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Handle author data
|
|
39
|
+
let authorObj = []
|
|
40
|
+
let newAuthor = {}
|
|
41
|
+
try {
|
|
42
|
+
AUTHORS.forEach(author => {
|
|
43
|
+
newAuthor = {
|
|
44
|
+
'@type': 'Person',
|
|
45
|
+
name: author.AUTHOR_NAME,
|
|
46
|
+
url: author.AUTHOR_PAGE,
|
|
47
|
+
}
|
|
48
|
+
authorObj.push(newAuthor)
|
|
49
|
+
})
|
|
50
|
+
} catch (err) {
|
|
51
|
+
// If it errored, just set to neutral default
|
|
52
|
+
authorObj = {
|
|
53
|
+
'@type': 'Person',
|
|
54
|
+
name: thisBrand.attributes.siteName,
|
|
55
|
+
url: MAIN_DOMAIN,
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<Helmet>
|
|
61
|
+
<title>{TITLE}</title>
|
|
62
|
+
<meta name="description" content={DESCRIPTION} />
|
|
63
|
+
<link
|
|
64
|
+
rel="shortcut icon"
|
|
65
|
+
href="/favicon.ico"
|
|
66
|
+
type="image/x-icon"
|
|
67
|
+
/>
|
|
68
|
+
<link rel="canonical" href={`${CANONICAL_URL}/${url_add}`} />
|
|
69
|
+
<link rel="stylesheet" href={`https://files.sfchronicle.com/brand-styles/${styleSheetID}.css`} />
|
|
70
|
+
|
|
71
|
+
{(isApp || EMBEDDED) ? (
|
|
72
|
+
<meta name="robots" content="noindex, nofollow" />
|
|
73
|
+
) : (
|
|
74
|
+
<meta name="robots" content="max-image-preview:large" />
|
|
75
|
+
)}
|
|
76
|
+
|
|
77
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
78
|
+
<meta name="twitter:title" content={SOCIAL_TITLE} />
|
|
79
|
+
<meta name="twitter:site" content={"@" + thisBrand.attributes.twitter} />
|
|
80
|
+
<meta
|
|
81
|
+
name="twitter:url"
|
|
82
|
+
content={`${MAIN_DOMAIN}/${SUBFOLDER}${OPT_SLASH}${SLUG}/${url_add}`}
|
|
83
|
+
/>
|
|
84
|
+
<meta name="twitter:image" content={IMAGE} />
|
|
85
|
+
<meta name="twitter:description" content={DESCRIPTION} />
|
|
86
|
+
|
|
87
|
+
<meta property="og:type" content="article" />
|
|
88
|
+
<meta property="og:title" content={SOCIAL_TITLE} />
|
|
89
|
+
<meta property="og:site_name" content={thisBrand.attributes.siteName} />
|
|
90
|
+
<meta property="og:url" content={`${MAIN_DOMAIN}/${SUBFOLDER}${OPT_SLASH}${SLUG}/${url_add}`} />
|
|
91
|
+
<meta property="og:image" content={IMAGE} />
|
|
92
|
+
<meta property="og:description" content={DESCRIPTION} />
|
|
93
|
+
|
|
94
|
+
<script data-schema="NewsArticle" type="application/ld+json">{`{
|
|
95
|
+
"@context": "http://schema.org",
|
|
96
|
+
"@type": "NewsArticle",
|
|
97
|
+
"mainEntityOfPage": {
|
|
98
|
+
"@type": "WebPage",
|
|
99
|
+
"@id": "${MAIN_DOMAIN}/${SUBFOLDER}${OPT_SLASH}${SLUG}/${url_add}"
|
|
100
|
+
},
|
|
101
|
+
"headline": "${TITLE}",
|
|
102
|
+
"image": {
|
|
103
|
+
"@type": "ImageObject",
|
|
104
|
+
"url": "${IMAGE}"
|
|
105
|
+
},
|
|
106
|
+
"datePublished": "${ISO_PUBDATE}",
|
|
107
|
+
"dateModified": "${ISO_MODDATE}",
|
|
108
|
+
"author": ${JSON.stringify(authorObj)},
|
|
109
|
+
"publisher": {
|
|
110
|
+
"@type": "Organization",
|
|
111
|
+
"name": "${thisBrand.attributes.siteName}",
|
|
112
|
+
"logo": {
|
|
113
|
+
"@type": "ImageObject",
|
|
114
|
+
"url": "/apple-touch-icon.png",
|
|
115
|
+
"width": "180",
|
|
116
|
+
"height": "180"
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"description": "${DESCRIPTION}"
|
|
120
|
+
}`}</script>
|
|
121
|
+
</Helmet>
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export default LayoutHelmet
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
const LayoutScript = () => {
|
|
4
|
+
return (
|
|
5
|
+
<>
|
|
6
|
+
<script src="https://projects.sfchronicle.com/shared/js/jquery.min.js"></script>
|
|
7
|
+
<script src="https://treg.hearstnp.com/treg.js"></script>
|
|
8
|
+
</>
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default LayoutScript
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
pubdateString,
|
|
5
|
+
moddateString
|
|
6
|
+
} from './helpers/datehelpers.mjs'
|
|
7
|
+
|
|
8
|
+
const OgPubDate = ({ settings }) => {
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
{moddateString &&
|
|
12
|
+
<p><i>Originally published on {pubdateString}</i></p>
|
|
13
|
+
}
|
|
14
|
+
</>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default OgPubDate
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React, { useEffect, useState, useRef } from "react"
|
|
2
2
|
|
|
3
|
-
const CaptionCreditSlideshow = ({ captionList, creditList, extraStyles }) => {
|
|
3
|
+
const CaptionCreditSlideshow = ({ captionList, creditList, extraStyles, creditStyles = [] }) => {
|
|
4
4
|
let captionCss = ["topper-image", "caption"];
|
|
5
|
-
if (extraStyles)
|
|
5
|
+
if (extraStyles) {
|
|
6
|
+
captionCss = extraStyles.concat(captionCss);
|
|
7
|
+
}
|
|
6
8
|
|
|
7
9
|
const [index, setIndex] = useState(0);
|
|
8
10
|
const timeoutRef = useRef(null);
|
|
@@ -29,16 +31,17 @@ const CaptionCreditSlideshow = ({ captionList, creditList, extraStyles }) => {
|
|
|
29
31
|
|
|
30
32
|
const hasCaption = (captionList.length > 0)
|
|
31
33
|
const hasCredit = (creditList.length > 0)
|
|
34
|
+
let creditCss = `credit ${creditStyles.join(" ")}`
|
|
32
35
|
return (
|
|
33
36
|
<>
|
|
34
37
|
{hasCaption && hasCredit && (
|
|
35
38
|
<figcaption className={captionCss.join(' ')}>
|
|
36
|
-
{captionList[index]} <span className=
|
|
39
|
+
{captionList[index]} <span className={creditCss}>{creditList[index]}</span>
|
|
37
40
|
</figcaption>
|
|
38
41
|
)}
|
|
39
42
|
{!hasCaption && hasCredit && (
|
|
40
43
|
<figcaption className={captionCss.join(' ')}>
|
|
41
|
-
<span className=
|
|
44
|
+
<span className={creditCss}>{creditList[index]}</span>
|
|
42
45
|
</figcaption>
|
|
43
46
|
)}
|
|
44
47
|
{hasCaption && !hasCredit && (
|
|
@@ -4,7 +4,7 @@ import * as styles from "../../styles/modules/imageslideshow.module.less"
|
|
|
4
4
|
import * as imageStyles from "../../styles/modules/topperimage.module.less"
|
|
5
5
|
import { TransitionGroup, CSSTransition } from "react-transition-group"
|
|
6
6
|
|
|
7
|
-
const ImageSlideshow = ({ wcmData, imageList, altList, topperStyle }) => {
|
|
7
|
+
const ImageSlideshow = ({ wcmData, imageList, altList, topperStyle, isLayoutInverted = false }) => {
|
|
8
8
|
const [index, setIndex] = useState(0);
|
|
9
9
|
const timeoutRef = useRef(null);
|
|
10
10
|
|
|
@@ -31,7 +31,6 @@ const ImageSlideshow = ({ wcmData, imageList, altList, topperStyle }) => {
|
|
|
31
31
|
const getContainerClass = () => {
|
|
32
32
|
switch (topperStyle) {
|
|
33
33
|
case "stacked":
|
|
34
|
-
return styles.containerStacked;
|
|
35
34
|
case "full-screen":
|
|
36
35
|
return styles.containerStacked;
|
|
37
36
|
default:
|
|
@@ -45,6 +44,10 @@ const ImageSlideshow = ({ wcmData, imageList, altList, topperStyle }) => {
|
|
|
45
44
|
return styles.imageWrapperStacked;
|
|
46
45
|
case "full-screen":
|
|
47
46
|
return styles.imageWrapperFullscreen;
|
|
47
|
+
case "side-by-side":
|
|
48
|
+
return styles.imageWrapperSideBySide;
|
|
49
|
+
case "side-by-side-portrait":
|
|
50
|
+
return styles.imageWrapperSideBySidePortrait;
|
|
48
51
|
default:
|
|
49
52
|
return "";
|
|
50
53
|
}
|
|
@@ -56,6 +59,18 @@ const ImageSlideshow = ({ wcmData, imageList, altList, topperStyle }) => {
|
|
|
56
59
|
return [imageStyles.cForceAspectRatio];
|
|
57
60
|
case "full-screen":
|
|
58
61
|
return [imageStyles.cImgSlideshowFullscreen];
|
|
62
|
+
case "side-by-side":
|
|
63
|
+
return [imageStyles.cImgSlideshowSideBySide].concat(
|
|
64
|
+
// Add styling for left padding on topper image
|
|
65
|
+
(isLayoutInverted) ? [imageStyles.cLargePaddingLeft] : [imageStyles.cLargePaddingRight]
|
|
66
|
+
);
|
|
67
|
+
case "side-by-side-portrait":
|
|
68
|
+
return [imageStyles.cImgSlideshowSideBySidePortrait].concat(
|
|
69
|
+
[
|
|
70
|
+
// Add styling for left padding on image caption
|
|
71
|
+
(isLayoutInverted) ? [] : [styles.sideBySidePortraitMarginLeft]
|
|
72
|
+
]
|
|
73
|
+
);
|
|
59
74
|
default:
|
|
60
75
|
return [""];
|
|
61
76
|
}
|
package/components/topper2.mjs
CHANGED
|
@@ -10,7 +10,9 @@ import * as imageStyles from "../styles/modules/topperimage.module.less"
|
|
|
10
10
|
const Topper2 = ({ settings, wcmData }) => {
|
|
11
11
|
const {
|
|
12
12
|
Topper_Style, Title, Title_Style, Deck, Image, Image_Alt, Image_Caption, Image_Credits,
|
|
13
|
-
HeaderDek_Vertical_Position, HeaderDek_Vertical_Offset, HeaderDek_Horizontal_Offset,
|
|
13
|
+
HeaderDek_Vertical_Position, HeaderDek_Vertical_Offset, HeaderDek_Horizontal_Offset,
|
|
14
|
+
HeaderDek_Horizontal_Position, Inverted_Colors, Inverted_Layout, Inverted_Text_Color,
|
|
15
|
+
Topper_Background_Color
|
|
14
16
|
} = settings
|
|
15
17
|
|
|
16
18
|
const headerDekStyleList = () => {
|
|
@@ -35,6 +37,19 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
35
37
|
... (Inverted_Colors === "black-text-white-bg") ? [topperStyles.blackTextWhiteBg] : [topperStyles.whiteTextBlackBg]
|
|
36
38
|
];
|
|
37
39
|
case "side-by-side":
|
|
40
|
+
return [
|
|
41
|
+
topperStyles.headerDekSideBySide,
|
|
42
|
+
// Add styling for left padding on header-deck
|
|
43
|
+
... (Inverted_Layout === "headerdek-right-image-left") ? [topperStyles.largePaddingRight] : [topperStyles.largePaddingLeft]
|
|
44
|
+
];
|
|
45
|
+
case "side-by-side-portrait":
|
|
46
|
+
return [
|
|
47
|
+
topperStyles.headerDekSideBySide,
|
|
48
|
+
// Add styling for left padding on header-deck
|
|
49
|
+
... (Inverted_Layout === "headerdek-right-image-left") ? [topperStyles.largePaddingRight] : [topperStyles.largePaddingLeft]
|
|
50
|
+
];
|
|
51
|
+
default:
|
|
52
|
+
console.error(`${Topper_Style} is not a valid topper style!`)
|
|
38
53
|
return [];
|
|
39
54
|
}
|
|
40
55
|
}
|
|
@@ -49,7 +64,7 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
49
64
|
}
|
|
50
65
|
|
|
51
66
|
const headerStyleList = () => {
|
|
52
|
-
let defaultStyles;
|
|
67
|
+
let defaultStyles = [];
|
|
53
68
|
switch (Topper_Style) {
|
|
54
69
|
case "stacked":
|
|
55
70
|
defaultStyles = [];
|
|
@@ -61,7 +76,8 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
61
76
|
defaultStyles = [topperStyles.hedFullScreen, fullScreenTextAlignCss()];
|
|
62
77
|
break;
|
|
63
78
|
case "side-by-side":
|
|
64
|
-
|
|
79
|
+
case "side-by-side-portrait":
|
|
80
|
+
defaultStyles = ["left"];
|
|
65
81
|
break;
|
|
66
82
|
}
|
|
67
83
|
|
|
@@ -83,11 +99,14 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
83
99
|
case "full-screen":
|
|
84
100
|
return ["deck", topperStyles.deckFullScreen, fullScreenTextAlignCss()];
|
|
85
101
|
case "side-by-side":
|
|
86
|
-
|
|
102
|
+
case "side-by-side-portrait":
|
|
103
|
+
return ["deck left"];
|
|
104
|
+
default:
|
|
105
|
+
return [""]
|
|
87
106
|
}
|
|
88
107
|
}
|
|
89
108
|
|
|
90
|
-
/**
|
|
109
|
+
/** Get text alignment based on header-deck position **/
|
|
91
110
|
const fullScreenTextAlignCss = () => {
|
|
92
111
|
switch (HeaderDek_Horizontal_Position) {
|
|
93
112
|
case "left": return topperStyles.textAlignLeft;
|
|
@@ -96,6 +115,27 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
96
115
|
}
|
|
97
116
|
}
|
|
98
117
|
|
|
118
|
+
/** Add styling for text color on topper slideshow captions. Note that the credits
|
|
119
|
+
* are grey when the caption is black and white when the captions are white. */
|
|
120
|
+
const sideBySideCapCredColorCss = () => {
|
|
121
|
+
return (Inverted_Text_Color === "black") ? topperStyles.captionTextColor : topperStyles.captionTextColorImportant;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Add styling for left padding on topper slideshow captions */
|
|
125
|
+
const sideBySideCapCredPaddingCss = () => {
|
|
126
|
+
return (Inverted_Layout === "headerdek-right-image-left") ? topperStyles.captionLargePaddingLeft : topperStyles.captionLargePaddingRight
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Add styling for left padding on topper slideshow captions */
|
|
130
|
+
const sideBySidePortraitCapCredPaddingCss = () => {
|
|
131
|
+
return (Inverted_Layout === "headerdek-right-image-left") ? topperStyles.captionSmallPaddingLeft : topperStyles.captionSideBySidePortraitPadding;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Add styling for float position for side-by-side-portrait image */
|
|
135
|
+
const sideBySidePortraitFloatCss = () => {
|
|
136
|
+
return (Inverted_Layout === "headerdek-right-image-left") ? topperStyles.floatLeftWhenDesktop : topperStyles.floatRightWhenDesktop;
|
|
137
|
+
}
|
|
138
|
+
|
|
99
139
|
/** Converts wcm string from spreadsheet into a list of WCM ids */
|
|
100
140
|
const getWcmIdList = (listStr) => {
|
|
101
141
|
return listStr.split(";").map((d) => parseInt(d));
|
|
@@ -119,15 +159,52 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
119
159
|
return list;
|
|
120
160
|
}
|
|
121
161
|
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
162
|
+
/* Returns the corresponding image HTML for each topper style and slideshow status */
|
|
163
|
+
const getImageHTML = (isSlideshow) => {
|
|
164
|
+
if (isSlideshow) return (
|
|
165
|
+
<ImageSlideshow
|
|
166
|
+
wcmData={wcmData}
|
|
167
|
+
imageList={wcmIdList}
|
|
168
|
+
altList={convertStringToList(Image_Alt, wcmIdList.length)}
|
|
169
|
+
topperStyle={Topper_Style}
|
|
170
|
+
isLayoutInverted={(Inverted_Layout === "headerdek-right-image-left")}
|
|
171
|
+
/>
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
switch (Topper_Style) {
|
|
175
|
+
case "stacked":
|
|
176
|
+
return (<TopperImage wcm={Image} alt={Image_Alt} wcmData={wcmData} />)
|
|
177
|
+
case "full-screen":
|
|
178
|
+
return (<TopperImage
|
|
179
|
+
wcm={Image}
|
|
180
|
+
alt={Image_Alt}
|
|
181
|
+
wcmData={wcmData}
|
|
182
|
+
overrideCssList={[imageStyles.cImgFullscreen]}
|
|
183
|
+
/>)
|
|
184
|
+
case "side-by-side":
|
|
185
|
+
return (
|
|
186
|
+
<TopperImage
|
|
187
|
+
wcm={Image}
|
|
188
|
+
alt={Image_Alt}
|
|
189
|
+
wcmData={wcmData}
|
|
190
|
+
containerCssList={[imageStyles.cContainerSideBySide]}
|
|
191
|
+
overrideCssList={[imageStyles.cImgSideBySide]}
|
|
192
|
+
/>)
|
|
193
|
+
case "side-by-side-portrait":
|
|
194
|
+
return (
|
|
195
|
+
<TopperImage
|
|
196
|
+
wcm={Image}
|
|
197
|
+
alt={Image_Alt}
|
|
198
|
+
wcmData={wcmData}
|
|
199
|
+
containerCssList={[imageStyles.cContainerSideBySidePortrait, sideBySidePortraitFloatCss()]}
|
|
200
|
+
overrideCssList={[imageStyles.cImgSideBySidePortrait]}
|
|
201
|
+
/>
|
|
202
|
+
)
|
|
203
|
+
case "no-visual":
|
|
204
|
+
default:
|
|
205
|
+
return null
|
|
206
|
+
}
|
|
207
|
+
}
|
|
131
208
|
|
|
132
209
|
const wcmIdList = getWcmIdList(Image);
|
|
133
210
|
const TopperHtml = () => {
|
|
@@ -138,15 +215,14 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
138
215
|
<>
|
|
139
216
|
<div className={containerCss}>
|
|
140
217
|
<figure className={`topper-image ${topperStyles.imageFullScreen}`} aria-labelledby="topperCaptionText">
|
|
141
|
-
{isSlideshow(wcmIdList)
|
|
142
|
-
{!isSlideshow(wcmIdList) && <FullScreenImageHTML />}
|
|
218
|
+
{getImageHTML(isSlideshow(wcmIdList))}
|
|
143
219
|
|
|
144
220
|
{/* This caption-credit only shows when the screen size is tablet or mobile */}
|
|
145
221
|
{isSlideshow(wcmIdList) &&
|
|
146
222
|
<CaptionCreditSlideshow
|
|
147
223
|
captionList={convertStringToList(Image_Caption, wcmIdList.length)}
|
|
148
224
|
creditList={convertStringToList(Image_Credits, wcmIdList.length)}
|
|
149
|
-
extraStyles={topperStyles.hideWhenDesktop}
|
|
225
|
+
extraStyles={[topperStyles.hideWhenDesktop]}
|
|
150
226
|
/>
|
|
151
227
|
}
|
|
152
228
|
{!isSlideshow(wcmIdList) && <CaptionCredit caption={Image_Caption} credit={Image_Credits} extraStyles={topperStyles.hideWhenDesktop} />}
|
|
@@ -193,8 +269,8 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
193
269
|
/>
|
|
194
270
|
</div>
|
|
195
271
|
<figure className={`mw-xl ml-auto mr-auto ${topperStyles.imageStacked}`}>
|
|
196
|
-
{isSlideshow(wcmIdList)
|
|
197
|
-
|
|
272
|
+
{getImageHTML(isSlideshow(wcmIdList))}
|
|
273
|
+
|
|
198
274
|
{isSlideshow(wcmIdList) &&
|
|
199
275
|
<CaptionCreditSlideshow
|
|
200
276
|
captionList={convertStringToList(Image_Caption, wcmIdList.length)}
|
|
@@ -202,7 +278,7 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
202
278
|
extraStyles={[topperStyles.smallPaddingLeftWhenTablet]}
|
|
203
279
|
/>
|
|
204
280
|
}
|
|
205
|
-
{!isSlideshow(wcmIdList) && <CaptionCredit caption={Image_Caption} credit={Image_Credits} extraStyles={[topperStyles.smallPaddingLeftWhenTablet]}/>}
|
|
281
|
+
{!isSlideshow(wcmIdList) && <CaptionCredit caption={Image_Caption} credit={Image_Credits} extraStyles={[topperStyles.smallPaddingLeftWhenTablet]} />}
|
|
206
282
|
</figure>
|
|
207
283
|
</div>
|
|
208
284
|
</>
|
|
@@ -227,18 +303,90 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
227
303
|
</div>
|
|
228
304
|
</>
|
|
229
305
|
);
|
|
306
|
+
|
|
307
|
+
case "side-by-side":
|
|
308
|
+
let figureCss = isSlideshow(wcmIdList) ? `${topperStyles.imageSideBySideSlideshow}` : `${topperStyles.imageSideBySide}`;
|
|
309
|
+
let sideBySideContainerCss = (Inverted_Layout === "headerdek-right-image-left") ? `${topperStyles.topperContainerSideBySide} ${topperStyles.reverseFlexbox}` : `${topperStyles.topperContainerSideBySide}`;
|
|
310
|
+
setBackgroundAndTextColor();
|
|
311
|
+
return (
|
|
312
|
+
<div className={sideBySideContainerCss}>
|
|
313
|
+
<div className={headerDekStyleList().join(' ')}>
|
|
314
|
+
<Heading
|
|
315
|
+
level={1}
|
|
316
|
+
text={Title}
|
|
317
|
+
className={headerStyleList().join(' ')}
|
|
318
|
+
/>
|
|
319
|
+
<Heading
|
|
320
|
+
level={2}
|
|
321
|
+
text={Deck}
|
|
322
|
+
className={deckStyleList().join(' ')}
|
|
323
|
+
/>
|
|
324
|
+
</div>
|
|
325
|
+
<figure className={figureCss}>
|
|
326
|
+
{getImageHTML(isSlideshow(wcmIdList))}
|
|
327
|
+
|
|
328
|
+
{isSlideshow(wcmIdList) &&
|
|
329
|
+
<CaptionCreditSlideshow
|
|
330
|
+
captionList={convertStringToList(Image_Caption, wcmIdList.length)}
|
|
331
|
+
creditList={convertStringToList(Image_Credits, wcmIdList.length)}
|
|
332
|
+
extraStyles={[topperStyles.slideshowCaptionSideBySide, sideBySideCapCredColorCss(), sideBySideCapCredPaddingCss()]}
|
|
333
|
+
creditStyles={[sideBySideCapCredColorCss()]}
|
|
334
|
+
/>
|
|
335
|
+
}
|
|
336
|
+
{!isSlideshow(wcmIdList) && <CaptionCredit caption={Image_Caption} credit={Image_Credits} extraStyles={[topperStyles.captionSideBySide, sideBySideCapCredColorCss()]} creditStyles={[sideBySideCapCredColorCss()]} />}
|
|
337
|
+
</figure>
|
|
338
|
+
</div>
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
case "side-by-side-portrait":
|
|
342
|
+
let portraitFigureCss = isSlideshow(wcmIdList) ? `${topperStyles.imageSideBySidePortraitSlideshow}` : `${topperStyles.imageSideBySidePortrait}`;
|
|
343
|
+
let sideBySidePortraitContainerCss = (Inverted_Layout === "headerdek-right-image-left") ? `${topperStyles.topperContainerSideBySidePortrait} ${topperStyles.reverseFlexbox}` : `${topperStyles.topperContainerSideBySidePortrait}`;
|
|
344
|
+
setBackgroundAndTextColor();
|
|
345
|
+
return (
|
|
346
|
+
<div className={topperStyles.fullWidthContainer}>
|
|
347
|
+
<div className={sideBySidePortraitContainerCss}>
|
|
348
|
+
<div className={headerDekStyleList().join(' ')}>
|
|
349
|
+
<Heading
|
|
350
|
+
level={1}
|
|
351
|
+
text={Title}
|
|
352
|
+
className={headerStyleList().join(' ')}
|
|
353
|
+
/>
|
|
354
|
+
<Heading
|
|
355
|
+
level={2}
|
|
356
|
+
text={Deck}
|
|
357
|
+
className={deckStyleList().join(' ')}
|
|
358
|
+
/>
|
|
359
|
+
</div>
|
|
360
|
+
<figure className={portraitFigureCss}>
|
|
361
|
+
{getImageHTML(isSlideshow(wcmIdList))}
|
|
362
|
+
|
|
363
|
+
{isSlideshow(wcmIdList) &&
|
|
364
|
+
<CaptionCreditSlideshow
|
|
365
|
+
captionList={convertStringToList(Image_Caption, wcmIdList.length)}
|
|
366
|
+
creditList={convertStringToList(Image_Credits, wcmIdList.length)}
|
|
367
|
+
extraStyles={[topperStyles.slideshowCaptionSideBySidePortrait, sideBySideCapCredColorCss(), sideBySidePortraitCapCredPaddingCss()]}
|
|
368
|
+
creditStyles={[sideBySideCapCredColorCss()]}
|
|
369
|
+
/>
|
|
370
|
+
}
|
|
371
|
+
{!isSlideshow(wcmIdList) && <CaptionCredit caption={Image_Caption} credit={Image_Credits} extraStyles={[topperStyles.captionSideBySidePortrait, sideBySideCapCredColorCss(), sideBySidePortraitFloatCss()]} creditStyles={[sideBySideCapCredColorCss()]} />}
|
|
372
|
+
</figure>
|
|
373
|
+
</div>
|
|
374
|
+
</div>
|
|
375
|
+
);
|
|
230
376
|
}
|
|
231
377
|
}
|
|
232
378
|
|
|
233
379
|
/** Calculate offsets for header-deck container based on the spreadsheet, for full-screen toppers only **/
|
|
234
380
|
const calculatefullScreenOffsets = () => {
|
|
235
|
-
|
|
381
|
+
let r = (typeof window != "undefined") ? document.querySelector(':root') : null;
|
|
236
382
|
|
|
237
383
|
let verticalOffset = convertStringToNumber(HeaderDek_Vertical_Offset, (HeaderDek_Vertical_Position === "bottom"));
|
|
238
384
|
let horizontalOffset = convertStringToNumber(HeaderDek_Horizontal_Offset, (HeaderDek_Horizontal_Position === "right"));
|
|
239
385
|
|
|
240
|
-
r
|
|
241
|
-
|
|
386
|
+
if (r) {
|
|
387
|
+
r.style.setProperty('--headerDek-vertical-offset', verticalOffset + "px");
|
|
388
|
+
r.style.setProperty('--headerDek-horizontal-offset', horizontalOffset + "px");
|
|
389
|
+
}
|
|
242
390
|
}
|
|
243
391
|
|
|
244
392
|
/** Convert offset values from the spreadsheet into Number type **/
|
|
@@ -257,6 +405,19 @@ const Topper2 = ({ settings, wcmData }) => {
|
|
|
257
405
|
return num;
|
|
258
406
|
}
|
|
259
407
|
|
|
408
|
+
/** Sets the background and text color in topper for side-by-side and side-by-side-portrait topper styles **/
|
|
409
|
+
const setBackgroundAndTextColor = () => {
|
|
410
|
+
let r = (typeof window != "undefined") ? document.querySelector(':root') : null;
|
|
411
|
+
|
|
412
|
+
if (r && Topper_Background_Color) {
|
|
413
|
+
r.style.setProperty('--container-background-color', Topper_Background_Color)
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (r && Inverted_Text_Color) {
|
|
417
|
+
r.style.setProperty('--side-by-side-text-color', Inverted_Text_Color)
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
260
421
|
return (
|
|
261
422
|
<TopperHtml />
|
|
262
423
|
)
|