Skip to content

Commit

Permalink
Merge branch 'padms/2010' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
padms committed Jan 25, 2024
2 parents f9bdd10 + 24dae91 commit 21f6673
Show file tree
Hide file tree
Showing 19 changed files with 527 additions and 9 deletions.
103 changes: 103 additions & 0 deletions sanityv3/schemas/components/ThemeSelector/ThemeSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Box, Card, Flex, Stack, Tooltip, Text } from '@sanity/ui'
import { useCallback } from 'react'
import { set } from 'sanity'
import type { ObjectInputProps } from 'sanity'
import styled from 'styled-components'
import { defaultColors, getColorForTheme } from './defaultColors'
import { EdsIcon } from '../../../icons'
import { text_field } from '@equinor/eds-icons'

const Circle = styled.div<{ active: boolean }>`
display: inline-block;
border: solid 2px ${({ active }) => (active ? 'var(--card-focus-ring-color)' : 'transparent')};
border-radius: 50%;
padding: 4px;
cursor: pointer;
`

const InnerCircle = styled.div<{ color: string; fillColor: string }>`
display: flex;
background-color: ${({ color }) => color};
border: 1px solid var(--card-hairline-soft-color);
padding: 15px;
border-radius: 50%;
color: ${({ fillColor }) => fillColor};
`

export type ThemeSelectorValue = {
title: string
value: number
}

type ColorCircleProps = {
color: ThemeSelectorValue
active: boolean
onClickHandler: (val: ThemeSelectorValue) => void
}

const ColorCircle = ({ color, active, onClickHandler }: ColorCircleProps) => {
const { background, highlight } = getColorForTheme(color.value)
return (
<Card paddingY={1}>
<Tooltip
content={
<Box padding={2}>
<Text muted size={1}>
{color.title}
</Text>
</Box>
}
fallbackPlacements={['right', 'left']}
placement="top"
portal
>
<Circle active={active} onClick={() => onClickHandler(color)}>
<InnerCircle color={background} fillColor={highlight}>
<EdsIcon {...text_field} />
</InnerCircle>
</Circle>
</Tooltip>
</Card>
)
}

type ThemeSelectorProps = ObjectInputProps

export const ThemeSelector = ({ value, onChange, schemaType }: ThemeSelectorProps) => {
const { options } = schemaType
const colors = (options?.colors as ThemeSelectorValue[]) || defaultColors

const handleSelect = useCallback(
(selected: ThemeSelectorValue) => {
if (selected === value) return

onChange(set(selected.title, ['title']))
onChange(set(selected.value, ['value']))
},
[onChange, value],
)

return (
<Stack space={3}>
{colors && (
<Card>
<Flex direction={'row'} wrap={'wrap'}>
{colors.map((colorItem: ThemeSelectorValue) => {
const { background } = getColorForTheme(colorItem.value)
return (
<ColorCircle
key={background}
color={colorItem}
active={colorItem.value === value?.value}
onClickHandler={handleSelect}
/>
)
})}
</Flex>
</Card>
)}
</Stack>
)
}

export default ThemeSelector
36 changes: 36 additions & 0 deletions sanityv3/schemas/components/ThemeSelector/defaultColors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export const defaultColors = [
{ title: 'White', value: 0 },
{ title: 'Moss Green Light', value: 1 },
{ title: 'Spruce Wood', value: 2 },
{ title: 'Mist Blue', value: 3 },
{ title: 'Mid Yellow', value: 4 },
{ title: 'Mid Orange', value: 5 },
{ title: 'Mid Blue 1', value: 6 },
{ title: 'Mid Blue 2', value: 7 },
{ title: 'Mid Green', value: 8 },
]

export const getColorForTheme = (pattern: number) => {
switch (pattern) {
case 1:
return { background: 'hsl(184, 30%, 96%)', highlight: 'hsl(348, 100%, 54%)' }
case 2:
return { background: 'hsl(25, 100%, 94%)', highlight: 'hsl(348, 100%, 54%)' }
case 3:
return { background: 'hsl(199, 58%, 90%)', highlight: 'hsl(348, 100%, 54%)' }
case 4:
return { background: '#FFF5B8', highlight: 'hsl(348, 100%, 54%)' }
case 5:
return { background: '#F8D1AF', highlight: 'hsl(348, 100%, 54%)' }
case 6:
return { background: '#49709C', highlight: '#F8D1AF' }
case 7:
return { background: '#49709C', highlight: '#FFF5B8' }
case 8:
return { background: '#C3E4CE', highlight: 'hsl(348, 100%, 54%)' }

case 0:
default:
return { background: 'hsl(0, 0%, 100%)', highlight: 'hsl(348, 100%, 54%)' }
}
}
2 changes: 2 additions & 0 deletions sanityv3/schemas/components/ThemeSelector/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './ThemeSelector'
export * from './defaultColors'
2 changes: 1 addition & 1 deletion sanityv3/schemas/components/renderers.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ReactNode} from 'react'
import { ReactNode } from 'react'

type Props = {
children: ReactNode
Expand Down
1 change: 1 addition & 0 deletions sanityv3/schemas/documents/magazine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export default {
of: [
{ type: 'textBlock' },
{ type: 'teaser' },
{ type: 'textTeaser' },
{ type: 'fullWidthImage' },
{ type: 'fullWidthVideo' },
{ type: 'figure' },
Expand Down
3 changes: 1 addition & 2 deletions sanityv3/schemas/documents/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import { HeroTypes } from '../HeroTypes'
import sharedHeroFields from './header/sharedHeaderFields'
import { EdsIcon } from '../../icons'
import { paste } from '@equinor/eds-icons'
// import { done } from '@equinor/eds-icons'

// export default ({ topicPrefix, title }: { topicPrefix: Topics; title: string }) => {
export default {
type: 'document',
name: 'page',
Expand Down Expand Up @@ -61,6 +59,7 @@ export default {
{ type: 'fullWidthVideo' },
{ type: 'textWithIconArray' },
{ type: 'keyNumbers' },
{ type: 'textTeaser' },
{ type: 'promotion' },
{ type: 'anchorLink' },
{ type: 'imageCarousel' },
Expand Down
17 changes: 14 additions & 3 deletions sanityv3/schemas/editors/titleEditorContentType.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { SuperScriptRenderer, SubScriptRenderer, StrikeThroughRenderer } from '../components'
import { IconSuperScript, IconSubScript } from '../../icons'
import { IconSuperScript, IconSubScript, EdsBlockEditorIcon } from '../../icons'
import { StrikethroughIcon } from '@sanity/icons'
import { BlockDefinition, BlockStyleDefinition } from 'sanity'
import { textColorConfig } from './blockContentType'
import { format_color_text } from '@equinor/eds-icons'

export type TitleContentProps = {
styles?: BlockStyleDefinition[]
highlight?: boolean
highlightTitle?: string
}

// TODO: Add relevant styles for titles (i.e. highlighted text)
Expand All @@ -20,7 +21,7 @@ export const configureTitleBlockContent = (
],
},
): BlockDefinition => {
const { highlight = false, styles } = options
const { highlight = false, styles, highlightTitle = 'Highlight' } = options

const config: BlockDefinition = {
type: 'block',
Expand Down Expand Up @@ -54,9 +55,19 @@ export const configureTitleBlockContent = (
},
}

const textColorConfig = {
title: highlightTitle,
value: 'highlight',
icon: EdsBlockEditorIcon(format_color_text),
component: ({ children }: { children: React.ReactNode }) => {
return <span style={{ color: 'hsl(348, 100%, 54%)' }}>{children}</span>
},
}

if (highlight) {
config.marks?.decorators?.push(textColorConfig)
}

return config
}

Expand Down
4 changes: 4 additions & 0 deletions sanityv3/schemas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import stockValuesApi from './objects/stockValuesApi'
import table from './objects/table'
import tableRichText from './objects/table/tableRichText'
import teaser from './objects/teaser'
import textTeaser from './objects/textTeaser'
import textBlock from './objects/textBlock'
import textWithIcon from './objects/textWithIcon'
import textWithIconArray from './objects/textWithIconArray'
Expand All @@ -85,6 +86,7 @@ import videoPlayer from './objects/videoPlayer'
import videoPlayerCarousel from './objects/videoPlayerCarousel'
import videoControls from './objects/videoControls'
import hlsVideo from './objects/hlsVideo'
import themeList from './objects/themeList'

const routeSchemas = languages.map(({ name, title }) => {
return route(name, title)
Expand Down Expand Up @@ -122,6 +124,7 @@ const RemainingSchemas = [
downloadableFile,
downloadableImage,
teaser,
textTeaser,
textBlock,
accordion,
accordionItem,
Expand Down Expand Up @@ -164,6 +167,7 @@ const RemainingSchemas = [
videoPlayerCarousel,
videoControls,
hlsVideo,
themeList,
]

// Then we give our schema to the builder and provide the result to Sanity
Expand Down
144 changes: 144 additions & 0 deletions sanityv3/schemas/objects/textTeaser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/* eslint-disable react/display-name */
import blocksToText from '../../helpers/blocksToText'
import { LeftAlignedImage, RightAlignedImage } from '../../icons'
import { RadioIconSelector } from '../components'
import CompactBlockEditor from '../components/CompactBlockEditor'
import { configureBlockContent, configureTitleBlockContent } from '../editors'
import { validateCharCounterEditor } from '../validations/validateCharCounterEditor'

import type { PortableTextBlock, Rule } from 'sanity'
import type { DownloadableImage } from './downloadableImage'
import type { DownloadableFile } from './files'
import type { LinkSelector } from './linkSelector'
import { ThemeSelectorValue } from '../components/ThemeSelector'

const titleContentType = configureTitleBlockContent({
highlight: true,
highlightTitle: 'Highlight text selected from theme below',
styles: [
{
title: 'Normal',
value: 'normal',
},
],
})

const titleAlignmentOptions = [
{ value: 'left', icon: LeftAlignedImage },
{ value: 'right', icon: RightAlignedImage },
]

const blockConfig = {
h1: false,
h2: false,
h3: false,
h4: false,
internalLink: false,
externalLink: false,
attachment: false,
lists: true,
}

const blockContentType = configureBlockContent({ ...blockConfig })

export type TextTeaser = {
_type: 'textTeaser'
title?: PortableTextBlock[]
text?: PortableTextBlock[]
action?: (LinkSelector | DownloadableFile | DownloadableImage)[]
titlePosition?: string
theme?: ThemeSelectorValue
}

export default {
name: 'textTeaser',
title: 'Text Teaser',
type: 'object',
localize: true,
fieldsets: [
{
name: 'link',
title: 'Link',
description: 'Select either an internal link or external URL.',
},
{
name: 'design',
title: 'Design options',
},
],
fields: [
{
name: 'title',
type: 'array',
components: {
input: CompactBlockEditor,
},
of: [titleContentType],
validation: (Rule: Rule) => Rule.required(),
},
{
name: 'text',
title: 'Text content',
type: 'array',
of: [blockContentType],
validation: (Rule: Rule) =>
Rule.custom((value: PortableTextBlock[]) => {
return validateCharCounterEditor(value, 600)
}).warning(),
},

{
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: 'titlePosition',
title: 'Title position',
description: 'Select which side of the teaser the title should be displayed at on larger screens.',
type: 'string',
fieldset: 'design',
components: {
input: function ({ onChange, value }: { onChange: any; value: string }) {
return (
<RadioIconSelector
name="imageAlignmentSelector"
options={titleAlignmentOptions}
defaultValue="left"
currentValue={value}
onChange={onChange}
/>
)
},
},
},
{
title: 'Theme (for title)',
description:
'When you have selected highlight in the title, choose colour combination for the title text/background. If no highlighted is selected colour will be black or white (on blue background) If no theme is selected the default is white background with black text.',
name: 'theme',
type: 'themeList',
fieldset: 'design',
},
],
preview: {
select: {
title: 'title',
text: 'text',
},
prepare({ title, text }: { title: PortableTextBlock[]; text: PortableTextBlock[] }) {
const plainTitle = blocksToText(title)
return {
title: plainTitle || 'Missing teaser title',
subtitle: blocksToText(text) || 'Mising teaser text',
}
},
},
}
Loading

0 comments on commit 21f6673

Please sign in to comment.