Skip to content

Commit b1270a9

Browse files
🎨 add card compoent to sanity (#2178)
* 🎨 add card compoent to sanity * 🎨 update * 🎨 fix comments from review * 🎨 update margin bottom for h3 in the article prose
1 parent 1bf3d65 commit b1270a9

File tree

19 files changed

+687
-63
lines changed

19 files changed

+687
-63
lines changed

sanityv3/schemas/documents/page.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export default {
5050
of: [
5151
{ type: 'textBlock' },
5252
{ type: 'teaser' },
53+
{ type: 'cardsList' },
5354
{ type: 'figure' },
5455
{ type: 'fullWidthImage' },
5556
{ type: 'pullQuote', initialValue: { background: defaultColors[0] } },

sanityv3/schemas/editors/blockContentType.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { attach_file, external_link, format_color_text, link } from '@equinor/eds-icons'
2-
import type { BlockDefinition, Rule, ValidationContext } from 'sanity'
2+
import type { BlockDefinition, BlockStyleDefinition, Rule, ValidationContext } from 'sanity'
33
import { filterByPages, filterByPagesInOtherLanguages } from '../../helpers/referenceFilters'
44
import { EdsBlockEditorIcon, EdsIcon, IconSubScript, IconSuperScript } from '../../icons'
55
import { Flags } from '../../src/lib/datasetHelpers'
@@ -25,6 +25,7 @@ export type BlockContentProps = {
2525
value: 'normal'
2626
component?: ({ children }: { children: React.ReactNode }) => JSX.Element
2727
}
28+
extendedStyles?: BlockStyleDefinition[]
2829
}
2930

3031
export const textColorConfig = {
@@ -71,13 +72,14 @@ export const configureBlockContent = (options: BlockContentProps = {}): BlockDef
7172
lists = true,
7273
smallText = true,
7374
highlight = false,
75+
extendedStyles = [],
7476
normalTextOverride = { title: 'Normal', value: 'normal' },
7577
} = options
7678

7779
const config: BlockDefinition = {
7880
type: 'block',
7981
name: 'block',
80-
styles: [normalTextOverride],
82+
styles: [normalTextOverride, ...extendedStyles],
8183
lists: lists
8284
? [
8385
{ title: 'Numbered', value: 'number' },
@@ -116,7 +118,6 @@ export const configureBlockContent = (options: BlockContentProps = {}): BlockDef
116118
value: 'smallText',
117119
component: SmallTextRender,
118120
}
119-
120121
const externalLinkConfig = {
121122
name: 'link',
122123
type: 'object',

sanityv3/schemas/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ import themeList from './objects/themeList'
9090
import keyNumbers from './objects/keyNumbers'
9191
import keyNumberItem from './objects/keyNumberItem'
9292
import keyValue from './objects/keyValue'
93+
import card from './objects/card'
94+
import cardsList from './objects/cardsList'
9395

9496
const routeSchemas = languages.map(({ name, title }) => {
9597
return route(name, title)
@@ -174,6 +176,8 @@ const RemainingSchemas = [
174176
keyNumbers,
175177
keyNumberItem,
176178
keyValue,
179+
card,
180+
cardsList,
177181
]
178182

179183
// Then we give our schema to the builder and provide the result to Sanity

sanityv3/schemas/objects/card.tsx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* eslint-disable react/display-name */
2+
import { forwardRef } from 'react'
3+
import { configureBlockContent } from '../editors'
4+
import type { PortableTextBlock } from 'sanity'
5+
import { Stack, Text, Card } from '@sanity/ui'
6+
import blocksToText from '../../helpers/blocksToText'
7+
8+
const CardField = forwardRef((props: any, ref) => {
9+
return (
10+
<Stack>
11+
<Card padding={3} borderLeft>
12+
<Text muted size={2} align={'left'}>
13+
If only title are used it will render only title as statement. If content below are used, both title and
14+
content will be rendered.
15+
</Text>
16+
</Card>
17+
<>{props.renderDefault(props)}</>
18+
</Stack>
19+
)
20+
})
21+
22+
const blockConfig = {
23+
h2: false,
24+
h3: false,
25+
h4: false,
26+
internalLink: false,
27+
externalLink: false,
28+
attachment: false,
29+
lists: true,
30+
}
31+
32+
const blockContentType = configureBlockContent({ ...blockConfig })
33+
34+
export type Card = {
35+
_type: 'card'
36+
title?: PortableTextBlock[]
37+
content?: PortableTextBlock[]
38+
}
39+
40+
export default {
41+
name: 'card',
42+
title: 'Card',
43+
description: `If only title are used it will render as big title statement.
44+
If content below are used, they will have regular heading and paragraph styling`,
45+
type: 'object',
46+
localize: true,
47+
components: {
48+
input: CardField,
49+
},
50+
fields: [
51+
{
52+
name: 'title',
53+
type: 'text',
54+
},
55+
{
56+
name: 'content',
57+
type: 'array',
58+
title: 'Content',
59+
description: 'Optional',
60+
of: [blockContentType],
61+
},
62+
],
63+
preview: {
64+
select: {
65+
title: 'title',
66+
text: 'content',
67+
},
68+
prepare({ title, text }: { title: PortableTextBlock[]; text: PortableTextBlock[] }) {
69+
const plainTitle = blocksToText(title)
70+
return {
71+
title: plainTitle || 'Missing title',
72+
subtitle: blocksToText(text) || '',
73+
}
74+
},
75+
},
76+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/* eslint-disable react/display-name */
2+
import { grid_on } from '@equinor/eds-icons'
3+
import { configureTitleBlockContent } from '../editors'
4+
import CompactBlockEditor from '../components/CompactBlockEditor'
5+
import type { PortableTextBlock } from 'sanity'
6+
import blocksToText from '../../helpers/blocksToText'
7+
import { EdsIcon } from '../../icons'
8+
import { Card } from './card'
9+
import { ColorSelectorValue } from '../components/ColorSelector'
10+
import { defaultColors } from '../defaultColors'
11+
12+
const titleContentType = configureTitleBlockContent()
13+
14+
export type CardsList = {
15+
_type: 'cardsList'
16+
title?: PortableTextBlock[]
17+
cards?: Card[]
18+
background?: ColorSelectorValue
19+
}
20+
21+
export default {
22+
name: 'cardsList',
23+
title: 'List of cards',
24+
type: 'object',
25+
localize: true,
26+
fieldsets: [
27+
{
28+
title: 'Design options',
29+
name: 'design',
30+
options: {
31+
collapsible: true,
32+
collapsed: true,
33+
},
34+
},
35+
{
36+
title: 'List of cards',
37+
name: 'listOfCards',
38+
options: {
39+
collapsible: true,
40+
collapsed: true,
41+
},
42+
},
43+
],
44+
fields: [
45+
{
46+
name: 'title',
47+
type: 'array',
48+
title: 'Title for the list of cards',
49+
components: {
50+
input: CompactBlockEditor,
51+
},
52+
of: [titleContentType],
53+
},
54+
{
55+
title: 'Cards',
56+
fieldset: 'listOfCards',
57+
description: `On mobile cards will be rendered in 1 column. For larger screens;
58+
if 2 or 4 cards - 2 columns else if 3 or more than 4 cards - 3 columns. `,
59+
name: 'cards',
60+
type: 'array',
61+
of: [{ type: 'card' }],
62+
},
63+
{
64+
title: 'The background color on the cards',
65+
description: 'List title will be on default background. Default is White',
66+
name: 'background',
67+
type: 'colorlist',
68+
fieldset: 'design',
69+
initialValue: defaultColors[6],
70+
},
71+
],
72+
preview: {
73+
select: {
74+
title: 'title',
75+
},
76+
prepare({ title }: { title: PortableTextBlock[] }) {
77+
const plainTitle = blocksToText(title)
78+
return {
79+
title: plainTitle || 'Missing title',
80+
subtitle: 'Cardslist component',
81+
media: EdsIcon(grid_on),
82+
}
83+
},
84+
},
85+
}

web/core/Heading.tsx

Lines changed: 0 additions & 33 deletions
This file was deleted.

web/core/Typography/Heading.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { PortableText, PortableTextProps } from '@portabletext/react'
2+
import type { PortableTextBlock } from '@portabletext/types'
3+
import { Typography, TypographyProps } from './Typography'
4+
import isEmpty from '../../pageComponents/shared/portableText/helpers/isEmpty'
5+
import { Highlight } from '../../pageComponents/shared/portableText/components'
6+
7+
export type HeadingProps = PortableTextProps & TypographyProps
8+
9+
const defaultComponents = ({ variant, as: providedAs, className }: TypographyProps) => {
10+
return {
11+
block: {
12+
h1: ({ children }: PortableTextBlock) => {
13+
return (
14+
<Typography variant="h1" className={className}>
15+
<>{children}</>
16+
</Typography>
17+
)
18+
},
19+
h2: ({ children }: PortableTextBlock) => {
20+
return (
21+
<Typography variant="h2" className={className}>
22+
<>{children}</>
23+
</Typography>
24+
)
25+
},
26+
h3: ({ children }: PortableTextBlock) => {
27+
return (
28+
<Typography variant="h3" className={className}>
29+
<>{children}</>
30+
</Typography>
31+
)
32+
},
33+
extraLarge: ({ children }: PortableTextBlock) => {
34+
return (
35+
<Typography variant="5xl" as={providedAs} className={className}>
36+
<>{children}</>
37+
</Typography>
38+
)
39+
},
40+
normal: ({ children }: PortableTextBlock) => {
41+
if (isEmpty(children)) return null
42+
return (
43+
<Typography variant={variant} as={providedAs} className={className}>
44+
<>{children}</>
45+
</Typography>
46+
)
47+
},
48+
},
49+
marks: { highlight: Highlight },
50+
}
51+
}
52+
53+
/**
54+
* Component to use with portabletext headings
55+
*/
56+
export const Heading = ({ value, components = {}, variant, group, as, className, ...props }: HeadingProps) => {
57+
return (
58+
<PortableText
59+
value={value}
60+
// eslint-disable-next-line
61+
// @ts-ignore
62+
components={{ ...defaultComponents({ variant, group, as, className }), ...components }}
63+
{...props}
64+
/>
65+
)
66+
}

0 commit comments

Comments
 (0)