Skip to content

Commit

Permalink
feat: add comparison table block (payloadcms#437)
Browse files Browse the repository at this point in the history
* add comparison table block

* fix sass warning

* add comparison block to reusable blocks collection
  • Loading branch information
tylandavis authored Feb 26, 2025
1 parent 8e2bc33 commit 2e71b58
Show file tree
Hide file tree
Showing 11 changed files with 527 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/app/(payload)/admin/importMap.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

146 changes: 146 additions & 0 deletions src/blocks/ComparisonTable/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { blockFields } from '@root/fields/blockFields'
import { Block } from 'payload'

export const ComparisonTable: Block = {
slug: 'comparisonTable',
interfaceName: 'ComparisonTableType',
fields: [
blockFields({
name: 'comparisonTableFields',
fields: [
{
name: 'introContent',
label: 'Intro Content',
type: 'richText',
},
{
name: 'style',
label: 'Style',
type: 'select',
defaultValue: 'default',
options: [
{
label: 'Default',
value: 'default',
},
{
label: 'Centered',
value: 'centered',
},
],
},
{
name: 'header',
label: 'Table Header',
type: 'group',
admin: {
hideGutter: true,
},
fields: [
{
type: 'row',
fields: [
{
name: 'tableTitle',
type: 'text',
label: 'Title',
required: true,
admin: {
width: '40%',
placeholder: 'Compare Features',
},
},
{
name: 'columnOneHeader',
type: 'text',
label: 'Column One Header',
required: true,
admin: {
width: '30%',
placeholder: 'Payload',
},
},
{
name: 'columnTwoHeader',
type: 'text',
label: 'Column Two Header',
required: true,
admin: {
width: '30%',
placeholder: 'The other guys',
},
},
],
},
],
},
{
name: 'rows',
type: 'array',
label: 'Rows',
minRows: 1,
maxRows: 10,
fields: [
{
type: 'row',
fields: [
{
name: 'feature',
type: 'text',
label: false,
required: true,
admin: {
width: '40%',
placeholder: 'Feature',
},
},
{
name: 'columnOneCheck',
type: 'checkbox',
label: false,
admin: {
components: {
Field: '@root/components/TableCheckboxField',
},
},
},
{
name: 'columnOne',
type: 'text',
label: false,
admin: {
width: 'calc(30% - 50px)',
style: {
alignSelf: 'flex-end',
},
},
},
{
name: 'columnTwoCheck',
type: 'checkbox',
label: false,
admin: {
components: {
Field: '@root/components/TableCheckboxField',
},
},
},
{
name: 'columnTwo',
type: 'text',
label: false,
admin: {
width: 'calc(30% - 50px)',
style: {
alignSelf: 'flex-end',
},
},
},
],
},
],
},
],
}),
],
}
2 changes: 2 additions & 0 deletions src/collections/Pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { fullTitle } from '../fields/fullTitle'
import { hero } from '../fields/hero'
import { slugField } from '../fields/slug'
import { formatPreviewURL } from '../utilities/formatPreviewURL'
import { ComparisonTable } from '../blocks/ComparisonTable'

export const Pages: CollectionConfig = {
slug: 'pages',
Expand Down Expand Up @@ -92,6 +93,7 @@ export const Pages: CollectionConfig = {
CodeFeature,
Content,
ContentGrid,
ComparisonTable,
Form,
HoverCards,
HoverHighlights,
Expand Down
2 changes: 2 additions & 0 deletions src/collections/ReusableContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CaseStudyCards } from '../blocks/CaseStudyCards'
import { CaseStudyParallax } from '../blocks/CaseStudyParallax'
import { Code } from '../blocks/Code'
import { CodeFeature } from '../blocks/CodeFeature'
import { ComparisonTable } from '../blocks/ComparisonTable'
import { Content } from '../blocks/Content'
import { ContentGrid } from '../blocks/ContentGrid'
import { ExampleTabs } from '../blocks/ExampleTabs'
Expand Down Expand Up @@ -62,6 +63,7 @@ export const ReusableContent: CollectionConfig = {
CaseStudyParallax,
Code,
CodeFeature,
ComparisonTable,
Content,
ContentGrid,
ExampleTabs,
Expand Down
2 changes: 2 additions & 0 deletions src/components/RenderBlocks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { getFieldsKeyFromBlock } from '@components/RenderBlocks/utilities.js'
import { useThemePreference } from '@root/providers/Theme/index.js'
import { toKebabCase } from '@utilities/to-kebab-case.js'
import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react'
import { ComparisonTable } from '@blocks/ComparisonTable'

type ReusableContentBlockType = Extract<Page['layout'][0], { blockType: 'reusableContentBlock' }>

Expand All @@ -51,6 +52,7 @@ const blockComponents = {
caseStudyParallax: CaseStudyParallax,
code: CodeBlock,
codeFeature: CodeFeature,
comparisonTable: ComparisonTable,
content: ContentBlock,
contentGrid: ContentGrid,
cta: CallToAction,
Expand Down
43 changes: 43 additions & 0 deletions src/components/TableCheckboxField/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.toggle {
display: flex;
height: 40px;
width: 40px;
align-items: center;
justify-content: center;
border: 1px solid var(--theme-border-color);
border-radius: 3px;
background-color: var(--theme-input-bg);
margin: 0 5px;
transition-property: border-color, background-color, outline;
transition-duration: 0.1s;
transition-timing-function: ease-in-out;
cursor: pointer;
outline: 2px solid transparent;
box-shadow: 0px 2px 2px -1px rgba(0, 0, 0, 0.1);

&:hover {
border-color: var(--theme-elevation-250);
background-color: var(--theme-elevation-50);
}

&:focus {
border-color: var(--theme-elevation-500);
background-color: var(--theme-elevation-50);
outline: 2px solid var(--theme-elevation-250);
}

&[data-checked='true'] {
border-color: var(--theme-success-250);

&:hover {
border-color: var(--theme-success-450);
background-color: var(--theme-success-50);
}

&:focus {
border-color: var(--theme-success-500);
background-color: var(--theme-success-50);
outline: 2px solid var(--theme-success-250);
}
}
}
25 changes: 25 additions & 0 deletions src/components/TableCheckboxField/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use client'
import type { TextFieldClientComponent } from 'payload'
import { useField } from '@payloadcms/ui'

import classes from './index.module.scss'
import { TableIcon } from '@blocks/ComparisonTable/Icons'

const TableCheckboxField: TextFieldClientComponent = ({ path }) => {
const { value, setValue } = useField({ path })

return (
<button
type="button"
onClick={() => {
setValue(!value)
}}
className={classes.toggle}
data-checked={value}
>
<TableIcon checked={Boolean(value)} />
</button>
)
}

export default TableCheckboxField
39 changes: 39 additions & 0 deletions src/components/blocks/ComparisonTable/Icons/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import classes from '../index.module.scss'

const TableXIcon = () => (
<svg
width="26"
height="26"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={classes.icon}
>
<path
d="M17.2116 17.3607L8.89475 9.04388M8.89553 17.3606L17.2124 9.04379M25 13C25 19.6274 19.6274 25 13 25C6.37258 25 1 19.6274 1 13C1 6.37258 6.37258 1 13 1C19.6274 1 25 6.37258 25 13Z"
strokeWidth={2}
stroke="var(--theme-error-500)"
/>
</svg>
)

const TableCheckIcon = () => (
<svg
width="26"
height="26"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={classes.icon}
>
<path
d="M9.4 13L11.8 15.4L16.6 10.6M25 13C25 19.6274 19.6274 25 13 25C6.37258 25 1 19.6274 1 13C1 6.37258 6.37258 1 13 1C19.6274 1 25 6.37258 25 13Z"
strokeWidth={2}
stroke="var(--theme-success-600)"
strokeLinecap="square"
/>
</svg>
)

export const TableIcon: React.FC<{ checked: boolean }> = ({ checked }) =>
checked ? <TableCheckIcon /> : <TableXIcon />
Loading

0 comments on commit 2e71b58

Please sign in to comment.