public/lib/model/special-formats.ts (73 lines of code) (raw):
import { ComposerContentType, ContentType, DisplayHintArticleFormat, ListElementArticleFormat, ListElementContentType, Stub, NonListElementDisplayHint } from "./stub";
// eslint-disable-next-line no-undef -- Need to set up typescript-eslint
const listElementArticleFormats: Readonly<ListElementArticleFormat[]> = [
{ label: 'Key Takeaways', value: 'keyTakeaways' },
{ label: 'Q&A Explainer', value: 'qAndA' },
{ label: 'Timeline', value: 'timeline' },
{ label: 'Mini profiles', value: 'miniProfiles' },
{ label: 'Multi-byline', value: 'multiByline' },
]
// In addition to the below, the following are valid display hints:
// - 'column'. Deprecated: https://github.com/guardian/flexible-content/pull/3821)
// - 'splash'. Deprecated: https://github.com/guardian/flexible-content/pull/3369)
// eslint-disable-next-line no-undef -- Need to set up typescript-eslint
const nonListElementDisplayHintsFormats: Readonly<DisplayHintArticleFormat[]> = [
{
value: 'immersive',
label: 'Immersive',
},
{
value: 'photoEssay',
label: 'Photo essay',
},
{
value: 'numberedList',
label: 'Numbered list',
},
];
const setDisplayHintForFormat = (stub: Stub): Stub => {
const maybeMatchingFormat = listElementArticleFormats.find(format => format.value === stub.contentType)
if (maybeMatchingFormat) {
stub.displayHint = maybeMatchingFormat.value
}
return stub
}
const getListElementFormatFromLabel = (label: string): ListElementArticleFormat | undefined =>
listElementArticleFormats.find(format => format.label === label)
const contentTypeToComposerContentType = (type: ContentType): ComposerContentType => {
switch (type) {
case "article":
case "liveblog":
case "gallery":
case "interactive":
case "picture":
case "video":
case "audio":
return type;
default:
return 'article'
}
}
const findFormatByByDisplayHint = (displayHint: string): ListElementArticleFormat | DisplayHintArticleFormat | undefined => {
return [...nonListElementDisplayHintsFormats, ...listElementArticleFormats]
.find(format => format.value === displayHint)
}
const getArticleFormat = (contentType: ComposerContentType, displayHint?: string): ComposerContentType | ListElementContentType | NonListElementDisplayHint => {
if (!displayHint || !['article', 'interactive'].includes(contentType)) {
return contentType
}
return findFormatByByDisplayHint(displayHint)?.value ?? contentType
}
function toTitleCase(str: string) {
return str.replace(/\b\w/g, function (txt) { return txt.toUpperCase(); });
}
const getArticleFormatTitle = (contentType: ComposerContentType, displayHint?: string): string => {
if (!displayHint || !['article', 'interactive'].includes(contentType)) {
return toTitleCase(contentType)
}
return findFormatByByDisplayHint(displayHint)?.label ?? toTitleCase(contentType)
}
export {
listElementArticleFormats,
nonListElementDisplayHintsFormats,
setDisplayHintForFormat,
getListElementFormatFromLabel,
contentTypeToComposerContentType,
getArticleFormat,
getArticleFormatTitle
}