diff --git a/FeatureFlags.js b/FeatureFlags.js
index 97bd8a7fd..af178b6f3 100644
--- a/FeatureFlags.js
+++ b/FeatureFlags.js
@@ -47,6 +47,7 @@ const MAGAZINE = [...GLOBAL_PROD, ...GLOBAL_DEV]
/* Allows same slug for different languages */
const SAME_SLUG = [...GLOBAL_DEV, 'japan', 'southkorea']
const LINE_BREAK_TYPO = ['southkorea']
+const CAMPAIGN = [...GLOBAL_PROD, ...GLOBAL_DEV]
/**
* @param {string} dataset
@@ -72,4 +73,5 @@ export default (dataset) => ({
IS_GLOBAL_PROD: GLOBAL_PROD.includes(dataset),
IS_DEV: GLOBAL_DEV.includes(dataset),
IS_SATELLITE: SATELLITES.includes(dataset),
+ HAS_CAMPAIGN_BLOCKS: CAMPAIGN.includes(dataset),
})
diff --git a/sanityv3/schemas/components/ThemeSelector/themeColors.ts b/sanityv3/schemas/components/ThemeSelector/themeColors.ts
index b87d0923b..fcff2c7b1 100644
--- a/sanityv3/schemas/components/ThemeSelector/themeColors.ts
+++ b/sanityv3/schemas/components/ThemeSelector/themeColors.ts
@@ -10,7 +10,9 @@ export const themeColors = [
{ title: 'Mid Orange', value: 5 },
{ title: 'Mid Blue 1', value: 6 },
{ title: 'Mid Blue 2', value: 7 },
- { title: 'Mid Green', value: 8 },
+ { title: 'Mid Blue 3', value: 8 },
+ { title: 'Mid Green', value: 9 },
+ { title: 'Mist Blue 2', value: 10 },
]
//Keep in sync with web/pageComponents/shared/textTeaser/theme
@@ -91,6 +93,17 @@ export const getColorForTheme = (pattern: number) => {
},
}
case 8:
+ return {
+ background: {
+ value: defaultColors[6].value,
+ key: defaultColors[6].key,
+ },
+ highlight: {
+ value: defaultColors[0].value,
+ key: defaultColors[0].key,
+ },
+ }
+ case 9:
return {
background: {
value: defaultColors[7].value,
@@ -98,6 +111,17 @@ export const getColorForTheme = (pattern: number) => {
},
highlight: {},
}
+ case 10:
+ return {
+ background: {
+ value: defaultColors[3].value,
+ key: defaultColors[3].key,
+ },
+ highlight: {
+ value: defaultColors[6].value,
+ key: defaultColors[6].key,
+ },
+ }
case 0:
default:
diff --git a/sanityv3/schemas/documents/header/sharedHeaderFields.ts b/sanityv3/schemas/documents/header/sharedHeaderFields.ts
index 64792a3e1..2e7847e99 100644
--- a/sanityv3/schemas/documents/header/sharedHeaderFields.ts
+++ b/sanityv3/schemas/documents/header/sharedHeaderFields.ts
@@ -42,7 +42,7 @@ const heroBigTitleDefault = {
of: [
configureTitleBlockContent({
highlight: true,
- styles: defaultBannerBigTitletStyle,
+ extendedStyles: defaultBannerBigTitletStyle,
}),
],
hidden: ({ parent }: DocumentType) => !parent.isBigTitle || parent.heroType !== HeroTypes.DEFAULT,
@@ -64,7 +64,7 @@ const heroBigTitleFiftyFifty = {
title: 'Hero Title',
type: 'array',
fieldset: 'header',
- of: [configureTitleBlockContent({ styles: fiftyFiftyBigTitleStyle })],
+ of: [configureTitleBlockContent({ extendedStyles: fiftyFiftyBigTitleStyle })],
hidden: ({ parent }: DocumentType) => !parent.isBigTitle || parent.heroType !== HeroTypes.FIFTY_FIFTY,
validation: (Rule: Rule) =>
Rule.custom((value: PortableTextBlock[], ctx: ValidationContext) =>
diff --git a/sanityv3/schemas/documents/page.ts b/sanityv3/schemas/documents/page.ts
index b869fe417..9e59fcf48 100644
--- a/sanityv3/schemas/documents/page.ts
+++ b/sanityv3/schemas/documents/page.ts
@@ -43,6 +43,12 @@ export default {
fieldset: 'metadata',
},
...sharedHeroFields,
+ {
+ title: 'Is Campain',
+ name: 'isCampaign',
+ description: 'Set this to true if the page should be treated as campaign. the header title h1 will be hidden.',
+ type: 'boolean',
+ },
{
name: 'content',
type: 'array',
@@ -68,6 +74,8 @@ export default {
{ type: 'videoPlayer' },
{ type: 'videoPlayerCarousel' },
{ type: 'table' },
+ Flags.HAS_CAMPAIGN_BLOCKS && { type: 'grid' },
+ Flags.HAS_CAMPAIGN_BLOCKS && { type: 'campaignBanner' },
Flags.HAS_FORMS && { type: 'form' },
Flags.HAS_NEWS && { type: 'newsList' },
{ type: 'stockValuesApi' },
diff --git a/sanityv3/schemas/editors/blockContentType.tsx b/sanityv3/schemas/editors/blockContentType.tsx
index e1dc5159b..2646aded1 100644
--- a/sanityv3/schemas/editors/blockContentType.tsx
+++ b/sanityv3/schemas/editors/blockContentType.tsx
@@ -19,6 +19,8 @@ export type BlockContentProps = {
attachment?: boolean
lists?: boolean
smallText?: boolean
+ largeText?: boolean
+ extraLargeText?: boolean
highlight?: boolean
normalTextOverride?: {
title: string
@@ -42,20 +44,28 @@ const round = (num: number) =>
.toFixed(7)
.replace(/(\.[0-9]+?)0+$/, '$1')
.replace(/\.0$/, '')
-const em = (px: number, base: number) => `${round(px / base)}em`
+export const em = (px: number, base: number) => `${round(px / base)}em`
const SmallTextRender = (props: any) => {
const { children } = props
return {children}
}
+export const LargeTextRender = (props: any) => {
+ const { children } = props
+ return {children}
+}
+export const ExtraLargeTextRender = (props: any) => {
+ const { children } = props
+ return {children}
+}
const Level2BaseStyle = (props: any) => {
const { children } = props
- return
{children}
+ return {children}
}
const Level3BaseStyle = (props: any) => {
const { children } = props
- return {children}
+ return {children}
}
// H1 not allowed in block content since it should be a document title.
@@ -70,6 +80,8 @@ export const configureBlockContent = (options: BlockContentProps = {}): BlockDef
externalLink = true,
attachment = false,
lists = true,
+ largeText = false,
+ extraLargeText = false,
smallText = true,
highlight = false,
extendedStyles = [],
@@ -119,6 +131,16 @@ export const configureBlockContent = (options: BlockContentProps = {}): BlockDef
value: 'smallText',
component: SmallTextRender,
}
+ const largeTextConfig = {
+ title: 'Large text',
+ value: 'largeText',
+ component: LargeTextRender,
+ }
+ const extraLargeTextConfig = {
+ title: 'Extra large text',
+ value: 'extraLargeText',
+ component: ExtraLargeTextRender,
+ }
const externalLinkConfig = {
name: 'link',
type: 'object',
@@ -267,6 +289,12 @@ export const configureBlockContent = (options: BlockContentProps = {}): BlockDef
if (smallText) {
config?.styles?.push(smallTextConfig)
}
+ if (largeText) {
+ config?.styles?.push(largeTextConfig)
+ }
+ if (extraLargeText) {
+ config?.styles?.push(extraLargeTextConfig)
+ }
if (externalLink) {
config?.marks?.annotations?.push(externalLinkConfig)
diff --git a/sanityv3/schemas/editors/titleEditorContentType.tsx b/sanityv3/schemas/editors/titleEditorContentType.tsx
index bd904c3a2..d4ae51bb2 100644
--- a/sanityv3/schemas/editors/titleEditorContentType.tsx
+++ b/sanityv3/schemas/editors/titleEditorContentType.tsx
@@ -4,30 +4,37 @@ import { StrikethroughIcon } from '@sanity/icons'
import { BlockDefinition, BlockStyleDefinition } from 'sanity'
import { format_color_text } from '@equinor/eds-icons'
import { defaultColors } from '../defaultColors'
+import { em, ExtraLargeTextRender, LargeTextRender } from './blockContentType'
export type TitleContentProps = {
- styles?: BlockStyleDefinition[]
+ extendedStyles?: BlockStyleDefinition[]
highlight?: boolean
highlightTitle?: string
+ largeText?: boolean
+ extraLargeText?: boolean
+ twoXLText?: boolean
+}
+
+const TwoXLTextRender = (props: any) => {
+ const { children } = props
+ return {children}
}
// TODO: Add relevant styles for titles (i.e. highlighted text)
-export const configureTitleBlockContent = (
- options: TitleContentProps = {
- styles: [
- {
- title: 'Normal',
- value: 'normal',
- },
- ],
- },
-): BlockDefinition => {
- const { highlight = false, styles, highlightTitle = 'Highlight' } = options
+export const configureTitleBlockContent = (options: TitleContentProps = {}): BlockDefinition => {
+ const {
+ highlight = false,
+ highlightTitle = 'Highlight',
+ largeText = false,
+ extraLargeText = false,
+ twoXLText = false,
+ extendedStyles = [],
+ } = options
const config: BlockDefinition = {
type: 'block',
name: 'block',
- styles: styles,
+ styles: [{ title: 'Normal', value: 'normal' }, ...extendedStyles],
lists: [],
marks: {
decorators: [
@@ -56,6 +63,22 @@ export const configureTitleBlockContent = (
},
}
+ const largeTextConfig = {
+ title: 'Large text',
+ value: 'largeText',
+ component: LargeTextRender,
+ }
+ const extraLargeTextConfig = {
+ title: 'Extra large text',
+ value: 'extraLargeText',
+ component: ExtraLargeTextRender,
+ }
+ const twoXLTextConfig = {
+ title: '2XL text',
+ value: 'twoXLText',
+ component: TwoXLTextRender,
+ }
+
const textColorConfig = {
title: highlightTitle,
value: 'highlight',
@@ -68,6 +91,15 @@ export const configureTitleBlockContent = (
if (highlight) {
config.marks?.decorators?.push(textColorConfig)
}
+ if (largeText) {
+ config?.styles?.push(largeTextConfig)
+ }
+ if (extraLargeText) {
+ config?.styles?.push(extraLargeTextConfig)
+ }
+ if (twoXLText) {
+ config?.styles?.push(twoXLTextConfig)
+ }
return config
}
diff --git a/sanityv3/schemas/index.js b/sanityv3/schemas/index.js
index 253bf2314..1b4a7283c 100644
--- a/sanityv3/schemas/index.js
+++ b/sanityv3/schemas/index.js
@@ -94,6 +94,14 @@ import card from './objects/card'
import cardsList from './objects/cardsList'
import backgroundOptions from './objects/background/backgroundOptions'
import imageBackground from './objects/background/imageBackground'
+import grid from './objects/grid/index'
+import span3 from './objects/grid/rowTypes/span3'
+import span2and1 from './objects/grid/rowTypes/span2and1'
+import gridTextBlock from './objects/grid/cellTypes/gridTextBlock'
+import campaignBanner from './objects/campaignBanner'
+import gridTeaser from './objects/grid/cellTypes/gridTeaser'
+import threeColumns from './objects/grid/rowTypes/3columns'
+import gridColorTheme from './objects/grid/theme'
const routeSchemas = languages.map(({ name, title }) => {
return route(name, title)
@@ -182,6 +190,14 @@ const RemainingSchemas = [
cardsList,
backgroundOptions,
imageBackground,
+ grid,
+ span3,
+ span2and1,
+ gridTextBlock,
+ campaignBanner,
+ gridTeaser,
+ threeColumns,
+ gridColorTheme,
]
// Then we give our schema to the builder and provide the result to Sanity
diff --git a/sanityv3/schemas/objects/campaignBanner/index.tsx b/sanityv3/schemas/objects/campaignBanner/index.tsx
new file mode 100644
index 000000000..69f960962
--- /dev/null
+++ b/sanityv3/schemas/objects/campaignBanner/index.tsx
@@ -0,0 +1,107 @@
+/* eslint-disable react/display-name */
+import blocksToText from '../../../helpers/blocksToText'
+import { configureBlockContent } from '../../editors'
+import { validateCharCounterEditor } from '../../validations/validateCharCounterEditor'
+
+import type { Image, PortableTextBlock, Reference, Rule, ValidationContext } from 'sanity'
+import type { ColorSelectorValue } from '../../components/ColorSelector'
+
+const blockConfigTitle = {
+ h2: false,
+ h3: false,
+ h4: false,
+ internalLink: false,
+ externalLink: false,
+ attachment: false,
+ lists: false,
+ smallText: true,
+ largeText: true,
+ extraLargeText: true,
+}
+const blockConfigContent = {
+ h2: false,
+ h3: false,
+ h4: false,
+ internalLink: false,
+ externalLink: false,
+ attachment: false,
+ lists: false,
+ smallText: true,
+}
+
+const blockTitleType = configureBlockContent({ ...blockConfigTitle })
+const blockContentType = configureBlockContent({ ...blockConfigContent })
+
+export type CampaignBanner = {
+ _type: 'campaignBanner'
+ overline?: string
+ title?: PortableTextBlock[]
+ text?: PortableTextBlock[]
+ image: Image
+ imagePosition?: string
+ imageSize?: string
+ background?: ColorSelectorValue
+}
+
+export default {
+ name: 'campaignBanner',
+ title: 'Campaign Banner',
+ type: 'object',
+ localize: true,
+ fieldsets: [
+ {
+ title: 'Background image',
+ name: 'backgroundImage',
+ description: 'Settings for the background image',
+ options: {
+ collapsible: true,
+ collapsed: true,
+ },
+ },
+ ],
+ fields: [
+ {
+ name: 'title',
+ title: 'Title content',
+ type: 'array',
+ of: [blockTitleType],
+ validation: (Rule: Rule) =>
+ Rule.custom((value: PortableTextBlock[], ctx: ValidationContext) => {
+ return validateCharCounterEditor(value, 600)
+ }).warning(),
+ },
+ {
+ title: 'Image',
+ name: 'backgroundImage',
+ type: 'image',
+ options: {
+ hotspot: true,
+ collapsed: false,
+ },
+ fieldset: 'backgroundImage',
+ },
+ {
+ title: 'Background Color',
+ description: 'Fallback if no background image. Default is white.',
+ name: 'backgroundColor',
+ type: 'colorlist',
+ fieldset: 'backgroundImage',
+ },
+ ],
+ preview: {
+ select: {
+ title: 'title',
+ text: 'text',
+ image: 'backgroundImage.asset',
+ },
+ prepare({ title, text, image }: { title: PortableTextBlock[]; text: PortableTextBlock[]; image: Reference }) {
+ const plainTitle = blocksToText(title || text)
+
+ return {
+ title: plainTitle || 'Missing title/content',
+ subtitle: 'Campaign banner component',
+ media: image,
+ }
+ },
+ },
+}
diff --git a/sanityv3/schemas/objects/grid/cellTypes/gridTeaser.tsx b/sanityv3/schemas/objects/grid/cellTypes/gridTeaser.tsx
new file mode 100644
index 000000000..772dbb45f
--- /dev/null
+++ b/sanityv3/schemas/objects/grid/cellTypes/gridTeaser.tsx
@@ -0,0 +1,163 @@
+/* eslint-disable react/display-name */
+import blocksToText from '../../../../helpers/blocksToText'
+import { configureBlockContent } from '../../../editors'
+import { validateCharCounterEditor } from '../../../validations/validateCharCounterEditor'
+
+import type { PortableTextBlock, Reference, Rule, ValidationContext } from 'sanity'
+import type { DownloadableImage } from './../../downloadableImage'
+import type { DownloadableFile } from '../../files'
+import type { ImageWithAlt } from '../../imageWithAlt'
+import type { LinkSelector } from '../../linkSelector'
+import type { ColorSelectorValue } from '../../../components/ColorSelector'
+import { LeftAlignedImage, RightAlignedImage } from '../../../../icons'
+import { RadioIconSelector } from '../../../components'
+
+const blockContentType = configureBlockContent({
+ smallText: true,
+ largeText: true,
+ extraLargeText: true,
+})
+
+const imageAlignmentOptions = [
+ { value: 'left', icon: LeftAlignedImage },
+ { value: 'right', icon: RightAlignedImage },
+]
+
+export type GridTeaser = {
+ _type: 'gridTeaser'
+ content?: PortableTextBlock[]
+ quote: string
+ author: string
+ authorTitle?: string
+ action?: (LinkSelector | DownloadableFile | DownloadableImage)[]
+ image: ImageWithAlt
+ imagePosition?: string
+ background?: ColorSelectorValue
+}
+
+export default {
+ name: 'gridTeaser',
+ title: 'Grid Teaser',
+ type: 'object',
+ localize: true,
+ fieldsets: [
+ {
+ title: 'Quote',
+ name: 'quote',
+ description: '',
+ options: {
+ collapsible: true,
+ collapsed: true,
+ },
+ },
+ {
+ name: 'link',
+ title: 'Link',
+ description: 'Select either an internal link or external URL.',
+ },
+ {
+ name: 'design',
+ title: 'Design options',
+ },
+ ],
+ fields: [
+ {
+ name: 'content',
+ title: 'Content',
+ type: 'array',
+ of: [blockContentType],
+ validation: (Rule: Rule) =>
+ Rule.custom((value: PortableTextBlock[], ctx: ValidationContext) => {
+ return validateCharCounterEditor(value, 600)
+ }).warning(),
+ },
+ {
+ name: 'quote',
+ type: 'text',
+ title: 'Quote',
+ description: 'Highlighted quote from the article.',
+ rows: 5,
+ },
+ {
+ name: 'author',
+ type: 'string',
+ title: 'Name',
+ },
+ {
+ name: 'authorTitle',
+ type: 'string',
+ title: 'Title',
+ description: 'Optional title for the author.',
+ },
+ {
+ name: 'action',
+ title: 'Link/action',
+ description: 'Select the link or downloadable file for the teaser',
+ type: 'array',
+ of: [
+ { type: 'linkSelector', title: 'Link' },
+ { type: 'downloadableImage', title: 'Downloadable image' },
+ { type: 'downloadableFile', title: 'Downloadable file' },
+ ],
+ validation: (Rule: Rule) => Rule.max(1).error('Only one action is permitted'),
+ },
+ {
+ name: 'image',
+ title: 'Image',
+ type: 'imageWithAlt',
+ validation: (Rule: Rule) => Rule.required(),
+ },
+ {
+ name: 'imagePosition',
+ title: 'Image position',
+ description:
+ 'On span 3 one can select which side the image will be on for larger screens. On mobile and single column the image will be above',
+ type: 'string',
+ components: {
+ input: function ({ onChange, value }: { onChange: any; value: string }) {
+ return (
+
+ )
+ },
+ },
+ },
+ {
+ name: 'theme',
+ title: 'Theme',
+ description: 'If no theme set, normal text color is set',
+ type: 'themeList',
+ },
+ ],
+ preview: {
+ select: {
+ title: 'content',
+ text: 'quote',
+ image: 'image.asset',
+ },
+ prepare({
+ title,
+ text,
+ image,
+ }: {
+ title: PortableTextBlock[]
+ text: PortableTextBlock[]
+ isBigText: boolean
+ bigText: PortableTextBlock[]
+ image: Reference
+ }) {
+ const plainTitle = blocksToText(title || text)
+
+ return {
+ title: plainTitle || 'Missing content/quote',
+ subtitle: 'Grid Teaser component',
+ media: image,
+ }
+ },
+ },
+}
diff --git a/sanityv3/schemas/objects/grid/cellTypes/gridTextBlock.tsx b/sanityv3/schemas/objects/grid/cellTypes/gridTextBlock.tsx
new file mode 100644
index 000000000..91edbab3e
--- /dev/null
+++ b/sanityv3/schemas/objects/grid/cellTypes/gridTextBlock.tsx
@@ -0,0 +1,83 @@
+/* eslint-disable @typescript-eslint/ban-ts-comment */
+import { text_field } from '@equinor/eds-icons'
+import type { PortableTextBlock, Reference, Rule } from 'sanity'
+import type { ColorSelectorValue } from '../../../components/ColorSelector'
+import blocksToText from '../../../../helpers/blocksToText'
+import { EdsIcon } from '../../../../icons'
+import { configureBlockContent } from '../../../editors'
+
+const blockContentType = configureBlockContent({
+ smallText: true,
+ largeText: true,
+ extraLargeText: true,
+})
+
+type GridTextBlock = {
+ content?: string
+ action?: Reference[]
+ background?: ColorSelectorValue
+}
+
+export default {
+ name: 'gridTextBlock',
+ title: 'Grid Text block',
+ type: 'object',
+ fields: [
+ {
+ name: 'content',
+ title: 'Content',
+ type: 'array',
+ of: [blockContentType],
+ },
+ {
+ title: 'Text Alignment',
+ name: 'textAlignment',
+ description: 'Overrides background image alignment',
+ type: 'string',
+ options: {
+ list: [
+ { title: 'Left', value: 'left' },
+ { title: 'Right', value: 'right' },
+ { title: 'Center', value: 'center' },
+ ],
+ },
+ initialValue: 'left',
+ },
+ {
+ name: 'action',
+ title: 'Link/action',
+ description: 'Select the link or downloadable file',
+ type: 'array',
+ of: [
+ { type: 'linkSelector', title: 'Link' },
+ { type: 'downloadableImage', title: 'Downloadable image' },
+ { type: 'downloadableFile', title: 'Downloadable file' },
+ ],
+ validation: (Rule: Rule) => Rule.max(1).error('Only one action is permitted'),
+ },
+ {
+ name: 'theme',
+ type: 'themeList',
+ },
+ {
+ name: 'backgroundImage',
+ type: 'imageBackground',
+ title: 'Background Image',
+ description: 'Content alignment is ignored on this',
+ },
+ ].filter((e) => e),
+ preview: {
+ select: {
+ title: 'content',
+ },
+ prepare({ title }: { title: PortableTextBlock[] }) {
+ const plainTitle = blocksToText(title)
+
+ return {
+ title: plainTitle || 'Missing title/content',
+ subtitle: 'Grid text block component',
+ media: EdsIcon(text_field),
+ }
+ },
+ },
+}
diff --git a/sanityv3/schemas/objects/grid/index.tsx b/sanityv3/schemas/objects/grid/index.tsx
new file mode 100644
index 000000000..9fe2bc528
--- /dev/null
+++ b/sanityv3/schemas/objects/grid/index.tsx
@@ -0,0 +1,64 @@
+import { configureBlockContent } from '../../editors'
+import { PortableTextBlock } from 'sanity'
+import { EdsIcon } from '../../../icons'
+import { table_chart } from '@equinor/eds-icons'
+
+export type Grid = {
+ _type: 'grid'
+}
+
+export default {
+ title: 'Grid',
+ name: 'grid',
+ type: 'object',
+ fieldsets: [
+ {
+ title: 'Design options',
+ name: 'design',
+ description: 'Some options for design',
+ options: {
+ collapsible: true,
+ collapsed: false,
+ },
+ },
+ ],
+ fields: [
+ {
+ name: 'gridRows',
+ title: 'Grid rows',
+ description: 'Add different types of rows',
+ type: 'array',
+ of: [
+ {
+ type: 'span3',
+ title: 'Span 3 columns',
+ name: 'span3',
+ },
+ {
+ type: 'span2and1',
+ title: 'Span 2 columns and one single column',
+ name: 'span2and1',
+ },
+ {
+ type: 'threeColumns',
+ title: '3 columns',
+ name: 'threeColumns',
+ },
+ ],
+ },
+ ],
+ preview: {
+ select: {
+ title: 'title',
+ },
+ prepare({ title = [] }: { title: PortableTextBlock[] }) {
+ const plainTitle = 'Grid'
+
+ return {
+ title: plainTitle,
+ subtitle: 'Grid component',
+ media: () => EdsIcon(table_chart),
+ }
+ },
+ },
+}
diff --git a/sanityv3/schemas/objects/grid/rowTypes/3columns.tsx b/sanityv3/schemas/objects/grid/rowTypes/3columns.tsx
new file mode 100644
index 000000000..c6a9cefac
--- /dev/null
+++ b/sanityv3/schemas/objects/grid/rowTypes/3columns.tsx
@@ -0,0 +1,41 @@
+import blocksToText from '../../../../helpers/blocksToText'
+import { PortableTextBlock, Rule } from 'sanity'
+import { EdsIcon } from '../../../../icons'
+import { table_chart } from '@equinor/eds-icons'
+
+export type Span2And1 = {
+ _type: 'threeColumns'
+}
+
+export default {
+ title: '3 columns',
+ name: 'threeColumns',
+ type: 'object',
+ fields: [
+ {
+ name: 'columns',
+ title: 'List of 3 columns',
+ type: 'array',
+ of: [
+ { name: 'gridTextBlock', type: 'gridTextBlock', title: 'Text block' },
+ { type: 'figure' },
+ { type: 'gridTeaser' },
+ ],
+ validation: (Rule: Rule) => Rule.max(3).error('Only three is permitted'),
+ },
+ ],
+ preview: {
+ select: {
+ title: 'title',
+ },
+ prepare({ title = [] }: { title: PortableTextBlock[] }) {
+ const plainTitle = title.length > 0 ? blocksToText(title) : '3 columns type'
+
+ return {
+ title: plainTitle,
+ subtitle: '3 columns component',
+ media: () => EdsIcon(table_chart),
+ }
+ },
+ },
+}
diff --git a/sanityv3/schemas/objects/grid/rowTypes/span2and1.tsx b/sanityv3/schemas/objects/grid/rowTypes/span2and1.tsx
new file mode 100644
index 000000000..791e9357c
--- /dev/null
+++ b/sanityv3/schemas/objects/grid/rowTypes/span2and1.tsx
@@ -0,0 +1,61 @@
+import blocksToText from '../../../../helpers/blocksToText'
+import { configureBlockContent } from '../../../editors'
+
+import { PortableTextBlock, Rule } from 'sanity'
+import { EdsIcon } from '../../../../icons'
+import { table_chart } from '@equinor/eds-icons'
+
+export type Span2And1 = {
+ _type: 'span2and1'
+}
+
+export default {
+ title: 'Span 2 and 1 column',
+ name: 'span2and1',
+ type: 'object',
+ fields: [
+ {
+ name: 'span2',
+ title: 'The span 2 content',
+ type: 'array',
+ of: [
+ { name: 'gridTextBlock', type: 'gridTextBlock', title: 'Text block' },
+ { type: 'videoPlayer' },
+ { type: 'iframe' },
+ { type: 'figure' },
+ ],
+ validation: (Rule: Rule) => Rule.max(1).error('Only one is permitted'),
+ },
+ {
+ title: 'Align Span 2 on the right',
+ name: 'alignSpan2Right',
+ description: 'Will align the span 2 on the right side. If not selected on the left',
+ type: 'boolean',
+ },
+ {
+ name: 'singleColumn',
+ title: 'The single column content',
+ type: 'array',
+ of: [
+ { name: 'gridTextBlock', type: 'gridTextBlock', title: 'Text block' },
+ { type: 'figure' },
+ { type: 'gridTeaser' },
+ ],
+ validation: (Rule: Rule) => Rule.max(1).error('Only one is permitted'),
+ },
+ ],
+ preview: {
+ select: {
+ title: 'title',
+ },
+ prepare({ title = [] }: { title: PortableTextBlock[] }) {
+ const plainTitle = title.length > 0 ? blocksToText(title) : 'Span 2 and 1 type'
+
+ return {
+ title: plainTitle,
+ subtitle: 'Span 2 and 1 component',
+ media: () => EdsIcon(table_chart),
+ }
+ },
+ },
+}
diff --git a/sanityv3/schemas/objects/grid/rowTypes/span3.tsx b/sanityv3/schemas/objects/grid/rowTypes/span3.tsx
new file mode 100644
index 000000000..82bd7afa4
--- /dev/null
+++ b/sanityv3/schemas/objects/grid/rowTypes/span3.tsx
@@ -0,0 +1,44 @@
+import blocksToText from '../../../../helpers/blocksToText'
+import { PortableTextBlock, Rule } from 'sanity'
+import { EdsIcon } from '../../../../icons'
+import { table_chart } from '@equinor/eds-icons'
+
+export type Span3 = {
+ _type: 'span3'
+}
+
+export default {
+ title: 'Span 3',
+ name: 'span3',
+ type: 'object',
+ fields: [
+ {
+ name: 'content',
+ title: 'Span 3 type',
+ description: 'Select one type of content for span 3 type',
+ type: 'array',
+ of: [
+ { name: 'gridTextBlock', type: 'gridTextBlock', title: 'Text block' },
+ { type: 'videoPlayer' },
+ { type: 'iframe' },
+ { type: 'figure' },
+ { type: 'gridTeaser' },
+ ],
+ validation: (Rule: Rule) => Rule.max(1).error('Only one is permitted'),
+ },
+ ],
+ preview: {
+ select: {
+ title: 'title',
+ },
+ prepare({ title = [] }: { title: PortableTextBlock[] }) {
+ const plainTitle = title.length > 0 ? blocksToText(title) : 'Span 3 type'
+
+ return {
+ title: plainTitle,
+ subtitle: 'Span 3 component',
+ media: () => EdsIcon(table_chart),
+ }
+ },
+ },
+}
diff --git a/sanityv3/schemas/objects/grid/theme.tsx b/sanityv3/schemas/objects/grid/theme.tsx
new file mode 100644
index 000000000..6d00e2da7
--- /dev/null
+++ b/sanityv3/schemas/objects/grid/theme.tsx
@@ -0,0 +1,15 @@
+export default {
+ name: 'gridColorTheme',
+ title: 'Grid Color theme',
+ description: 'Text color on background color. Call to actions will be black or white text',
+ type: 'string',
+ options: {
+ list: [
+ { title: 'normal', value: 'normal' },
+ { title: 'red on white', value: 'redOnWhite' },
+ { title: 'white on dark blue', value: 'whiteOnDarkBlue' },
+ { title: 'dark blue on light blue', value: 'darkBlueOnLightBlue' },
+ ],
+ },
+ initialValue: 'normal',
+}
diff --git a/sanityv3/schemas/objects/teaser.tsx b/sanityv3/schemas/objects/teaser.tsx
index e738943ec..bcdaef655 100644
--- a/sanityv3/schemas/objects/teaser.tsx
+++ b/sanityv3/schemas/objects/teaser.tsx
@@ -142,15 +142,21 @@ export default {
},
{
name: 'action',
- title: 'Link/action',
- description: 'Select the link or downloadable file for the teaser',
+ title: 'Links/actions',
+ description: 'Select links or downloadable files for the teaser',
type: 'array',
of: [
{ type: 'linkSelector', title: 'Link' },
{ type: 'downloadableImage', title: 'Downloadable image' },
{ type: 'downloadableFile', title: 'Downloadable file' },
],
- validation: (Rule: Rule) => Rule.max(1).error('Only one action is permitted'),
+ validation: (Rule: Rule) => Rule.max(2).error('Only two action is permitted'),
+ },
+ {
+ title: 'Use resource link style',
+ description: 'Default is read more link style',
+ name: 'useResourceLinks',
+ type: 'boolean',
},
{
name: 'image',
diff --git a/sanityv3/schemas/objects/textBlock.tsx b/sanityv3/schemas/objects/textBlock.tsx
index b844c8367..9e7915f2e 100644
--- a/sanityv3/schemas/objects/textBlock.tsx
+++ b/sanityv3/schemas/objects/textBlock.tsx
@@ -6,7 +6,6 @@ import blocksToText from '../../helpers/blocksToText'
import { EdsIcon } from '../../icons'
import CompactBlockEditor from '../components/CompactBlockEditor'
import { configureBlockContent, configureTitleBlockContent } from '../editors'
-import { validateComponentAnchor } from '../validations/validateAnchorReference'
const blockContentType = configureBlockContent({
h2: false,
@@ -28,22 +27,27 @@ const blockContentTypeForBigText = configureBlockContent({
h4: false,
attachment: false,
smallText: false,
+ largeText: true,
+ extraLargeText: true,
normalTextOverride: {
title: 'Normal',
value: 'normal',
component: ({ children }: { children: React.ReactNode }) => {children},
},
})
-
-const titleContentType = configureTitleBlockContent()
+const titleContentType = configureTitleBlockContent({
+ largeText: true,
+ extraLargeText: true,
+ twoXLText: true,
+})
type TextBlock = {
overline?: string
title?: string
- anchor?: string
ingress?: string
text?: string
isBigText?: boolean
+ useBrandTheme?: boolean
bigText?: PortableTextBlock[]
action?: Reference[]
splitList?: boolean
@@ -86,26 +90,20 @@ export default {
name: 'actions',
options: {
collapsible: true,
- collapsed: false,
+ collapsed: true,
},
},
{
- name: 'anchor',
- title: 'Additional anchor point reference (Deprecated)',
- description:
- 'If the anchor reference to this component is set using anchor link component, the value here will be overridden',
+ name: 'titleOptions',
+ title: 'Title',
+ description: '',
options: {
collapsible: true,
- collapsed: true,
+ collapsed: false,
},
},
],
fields: [
- {
- title: 'Big text',
- name: 'isBigText',
- type: 'boolean',
- },
{
name: 'image',
type: 'imageWithAlt',
@@ -123,45 +121,53 @@ export default {
{
name: 'title',
type: 'array',
+ fieldset: 'titleOptions',
components: {
input: CompactBlockEditor,
},
of: [titleContentType],
validation: (Rule: Rule) =>
Rule.custom((value: PortableTextBlock[], ctx: ValidationContext) =>
- !value && !(ctx.parent as TextBlock)?.isBigText ? 'A title is recommended' : true,
+ !value ? 'A title is recommended' : true,
).warning(),
- hidden: ({ parent }: TextBlockDocument) => parent.isBigText,
},
{
- name: 'anchor',
- type: 'anchorReferenceField',
- title: 'Anchor reference',
- validation: (Rule: Rule) => [
- Rule.max(0).warning('Clear this field and use anchor link component instead.'),
- // @ts-ignore
- Rule.custom((value: string, context: any) => validateComponentAnchor(value, context)),
- ],
- fieldset: 'anchor',
- readOnly: ({ value }: { value?: string }) => !value,
+ title: 'Use brand theme for title',
+ description: 'Sets background to white and text color to brand red. Will disable other background options',
+ name: 'useBrandTheme',
+ type: 'boolean',
+ fieldset: 'titleOptions',
},
{
- name: 'ingress',
- title: 'Ingress',
- type: 'array',
- of: [ingressContentType],
- hidden: ({ parent }: TextBlockDocument) => parent.isBigText,
+ title: 'Big text (Deprecated)',
+ description: 'Set big text to false. Will be removed after a transition period',
+ name: 'isBigText',
+ type: 'boolean',
+ fieldset: 'titleOptions',
+ readOnly: ({ value }: { value?: string }) => !value,
},
{
name: 'bigTitle',
- title: 'Title',
+ title: 'Title (Deprecated)',
+ description: 'Use regular title and set big text to false. Will be removed after a transition period',
+ fieldset: 'titleOptions',
type: 'array',
of: [blockContentTypeForBigText],
hidden: ({ parent }: TextBlockDocument) => !parent.isBigText,
validation: (Rule: Rule) =>
Rule.custom((value: PortableTextBlock[], ctx: ValidationContext) =>
- !value && (ctx.parent as TextBlock)?.isBigText ? 'Title is required' : true,
- ),
+ value && (ctx.parent as TextBlock)?.isBigText
+ ? 'Clear this field and use regular title without big text boolean'
+ : true,
+ ).warning(),
+ readOnly: ({ value }: { value?: string }) => !value,
+ },
+ {
+ name: 'ingress',
+ title: 'Ingress',
+ type: 'array',
+ of: [ingressContentType],
+ hidden: ({ parent }: TextBlockDocument) => parent.isBigText,
},
{
name: 'text',
@@ -204,6 +210,7 @@ export default {
{
name: 'designOptions',
type: 'backgroundOptions',
+ readOnly: ({ parent }: { parent: TextBlock }) => parent.useBrandTheme,
},
{
title: 'Background (Deprecated)',
diff --git a/sanityv3/schemas/objects/textTeaser.tsx b/sanityv3/schemas/objects/textTeaser.tsx
index b69fae311..65310e636 100644
--- a/sanityv3/schemas/objects/textTeaser.tsx
+++ b/sanityv3/schemas/objects/textTeaser.tsx
@@ -15,7 +15,7 @@ import { ThemeSelectorValue } from '../components/ThemeSelector'
const titleContentType = configureTitleBlockContent({
highlight: true,
highlightTitle: 'Highlight text selected from theme below',
- styles: [
+ extendedStyles: [
{
title: 'Normal',
value: 'normal',
diff --git a/sanityv3/schemas/objects/videoPlayer.tsx b/sanityv3/schemas/objects/videoPlayer.tsx
index 5f02cf524..a3ab6f0dc 100644
--- a/sanityv3/schemas/objects/videoPlayer.tsx
+++ b/sanityv3/schemas/objects/videoPlayer.tsx
@@ -20,6 +20,17 @@ export default {
name: 'videoPlayer',
title: 'Video Player',
type: 'object',
+ fieldsets: [
+ {
+ name: 'designOptions',
+ title: 'Design options',
+ description: '',
+ options: {
+ collapsible: true,
+ collapsed: false,
+ },
+ },
+ ],
fields: [
{
name: 'title',
@@ -72,20 +83,43 @@ export default {
layout: 'dropdown',
},
initialValue: '16:9',
+ fieldset: 'designOptions',
validation: (Rule: Rule) => Rule.required(),
},
+ {
+ name: 'width',
+ type: 'string',
+ title: 'Width',
+ options: {
+ list: [
+ { title: 'Normal', value: 'normal' },
+ { title: 'Extra wide', value: 'extraWide' },
+ ],
+ layout: 'dropdown',
+ },
+ fieldset: 'designOptions',
+ initialValue: 'normal',
+ },
{
name: 'height',
type: 'number',
title: 'Height',
+ fieldset: 'designOptions',
description: 'Set a fixed height in pixels for the video. Note: this will override the aspect ratio setting.',
validation: (Rule: Rule) => Rule.positive().greaterThan(0).precision(0),
},
-
+ {
+ title: 'Use brand theme for video',
+ description: 'Make play button bigger and brand red.',
+ name: 'useBrandTheme',
+ type: 'boolean',
+ fieldset: 'designOptions',
+ },
{
title: 'Background',
description: 'Pick a colour for the background. Default is white.',
name: 'background',
+ fieldset: 'designOptions',
type: 'colorlist',
},
],
diff --git a/search/pnpm-lock.yaml b/search/pnpm-lock.yaml
index 7b344feca..150a93630 100644
--- a/search/pnpm-lock.yaml
+++ b/search/pnpm-lock.yaml
@@ -1,9 +1,5 @@
lockfileVersion: '6.0'
-settings:
- autoInstallPeers: true
- excludeLinksFromLockfile: false
-
dependencies:
'@azure/storage-blob':
specifier: ^12.15.0
@@ -3752,3 +3748,7 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
dev: true
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
diff --git a/web/components/src/Backgrounds/ColouredContainer.tsx b/web/components/src/Backgrounds/ColouredContainer.tsx
index cdb596b41..f169ef540 100644
--- a/web/components/src/Backgrounds/ColouredContainer.tsx
+++ b/web/components/src/Backgrounds/ColouredContainer.tsx
@@ -25,7 +25,7 @@ const ColourContainer = styled.div`
`
export const ColouredContainer = forwardRef(function BackgroundContainer(
- { backgroundColor = 'White', backgroundUtility, dark, style, children, className, ...rest },
+ { backgroundColor = 'White', backgroundUtility, dark, style, children, className = '', ...rest },
ref,
) {
const styleVariant = getContainerColor(backgroundColor)
@@ -38,7 +38,7 @@ export const ColouredContainer = forwardRef, 'src'> & {
src: string
playButton?: boolean
videoDescription?: string
+ /* setting this will sett fluid mode to video player */
aspectRatio?: string
+ /** Ignores aspect ratio to enable fill mode */
+ useFillMode?: boolean
loadingSpinner?: boolean
+ useBrandTheme?: boolean
onReady?: (player: Player) => void
}
export const VideoJS: React.FC = ({
@@ -27,6 +31,8 @@ export const VideoJS: React.FC = ({
aspectRatio,
onReady,
loadingSpinner,
+ useBrandTheme = false,
+ useFillMode = false,
poster,
allowFullScreen,
...rest
@@ -71,7 +77,7 @@ export const VideoJS: React.FC = ({
autoplay: autoPlay,
preload: autoPlay ? 'auto' : 'none',
controls: showControls,
- aspectRatio,
+ ...(!useFillMode && { aspectRatio: aspectRatio }),
bigPlayButton: !controls,
controlbar: true,
loadingSpinner: !autoPlay,
@@ -109,17 +115,19 @@ export const VideoJS: React.FC = ({
return (
<>
{/* eslint-disable-next-line */}
-
+
{showPlayButton && (