Skip to content
This repository was archived by the owner on Sep 9, 2024. It is now read-only.

Commit 1641630

Browse files
authored
feat: custom collection card template (#433)
1 parent c6994ea commit 1641630

File tree

22 files changed

+1441
-497
lines changed

22 files changed

+1441
-497
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"test:ci": "lerna run test:ci",
1515
"test:integration:ci": "lerna run test:integration:ci",
1616
"test:integration": "lerna run test:integration",
17-
"test": "lerna run test"
17+
"test": "lerna run test",
18+
"type-check": "lerna run type-check --scope @staticcms/core"
1819
},
1920
"devDependencies": {
2021
"husky": "8.0.3",

packages/core/dev-test/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99
_posts: {
1010
'2015-02-14-this-is-a-post.md': {
1111
content:
12-
'---\ntitle: This is a YAML front matter post\nimage: /assets/uploads/moby-dick.jpg\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
12+
'---\ntitle: This is a YAML front matter post\ndraft: true\nimage: /assets/uploads/moby-dick.jpg\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
1313
},
1414
'2015-02-15-this-is-a-json-frontmatter-post.md': {
1515
content:
16-
'{\n"title": "This is a JSON front matter post",\n"image": "/assets/uploads/moby-dick.jpg",\n"date": "2015-02-15T00:00:00.000Z"\n}\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
16+
'{\n"title": "This is a JSON front matter post",\n"draft": false,\n"image": "/assets/uploads/moby-dick.jpg",\n"date": "2015-02-15T00:00:00.000Z"\n}\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
1717
},
1818
'2015-02-16-this-is-a-toml-frontmatter-post.md': {
1919
content:
2020
'+++\ntitle = "This is a TOML front matter post"\nimage = "/assets/uploads/moby-dick.jpg"\ndate = "2015-02-16T00:00:00.000Z"\n+++\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
2121
},
2222
'2015-02-14-this-is-a-post-with-a-different-extension.other': {
2323
content:
24-
'---\ntitle: This post should not appear because the extension is different\nimage: /assets/uploads/moby-dick.jpg\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
24+
'---\ntitle: This post should not appear because the extension is different\ndraft: false\nimage: /assets/uploads/moby-dick.jpg\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n',
2525
},
2626
},
2727
_faqs: {

packages/core/dev-test/index.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,59 @@ const PostPreview = ({ entry, widgetFor }) => {
1111
);
1212
};
1313

14+
const PostPreviewCard = ({ entry, widgetFor, viewStyle }) => {
15+
return h(
16+
'div',
17+
{ style: { width: '100%' } },
18+
viewStyle === 'grid' ? widgetFor('image') : null,
19+
h(
20+
'div',
21+
{ style: { padding: '16px', width: '100%' } },
22+
h(
23+
'div',
24+
{
25+
style: {
26+
display: 'flex',
27+
width: '100%',
28+
justifyContent: 'space-between',
29+
alignItems: 'start',
30+
},
31+
},
32+
h(
33+
'div',
34+
{
35+
style: {
36+
display: 'flex',
37+
flexDirection: viewStyle === 'grid' ? 'column' : 'row',
38+
alignItems: 'baseline',
39+
gap: '8px',
40+
},
41+
},
42+
h('strong', { style: { fontSize: '24px' } }, entry.data.title),
43+
h('span', { style: { fontSize: '16px' } }, entry.data.date),
44+
),
45+
h(
46+
'div',
47+
{
48+
style: {
49+
backgroundColor: entry.data.draft === true ? 'blue' : 'green',
50+
color: 'white',
51+
border: 'none',
52+
padding: '4px 8px',
53+
textAlign: 'center',
54+
textDecoration: 'none',
55+
display: 'inline-block',
56+
cursor: 'pointer',
57+
borderRadius: '4px',
58+
},
59+
},
60+
entry.data.draft === true ? 'Draft' : 'Published',
61+
),
62+
),
63+
),
64+
);
65+
};
66+
1467
const GeneralPreview = ({ widgetsFor, entry, collection }) => {
1568
const title = entry.data.site_title;
1669
const posts = entry.data.posts;
@@ -80,6 +133,7 @@ const CustomPage = () => {
80133
};
81134

82135
CMS.registerPreviewTemplate('posts', PostPreview);
136+
CMS.registerPreviewCard('posts', PostPreviewCard);
83137
CMS.registerPreviewTemplate('general', GeneralPreview);
84138
CMS.registerPreviewTemplate('authors', AuthorsPreview);
85139
// Pass the name of a registered control to reuse with a new widget preview.

packages/core/src/components/Collection/Entries/EntryCard.tsx

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,16 @@ import { Link } from 'react-router-dom';
1010
import { getAsset as getAssetAction } from '@staticcms/core/actions/media';
1111
import { VIEW_STYLE_GRID, VIEW_STYLE_LIST } from '@staticcms/core/constants/collectionViews';
1212
import useMediaAsset from '@staticcms/core/lib/hooks/useMediaAsset';
13-
import { selectEntryCollectionTitle } from '@staticcms/core/lib/util/collection.util';
13+
import { getPreviewCard } from '@staticcms/core/lib/registry';
14+
import {
15+
selectEntryCollectionTitle,
16+
selectFields,
17+
selectTemplateName,
18+
} from '@staticcms/core/lib/util/collection.util';
19+
import { selectConfig } from '@staticcms/core/reducers/selectors/config';
1420
import { selectIsLoadingAsset } from '@staticcms/core/reducers/selectors/medias';
21+
import { useAppSelector } from '@staticcms/core/store/hooks';
22+
import useWidgetsFor from '../../common/widget/useWidgetsFor';
1523

1624
import type { CollectionViewStyle } from '@staticcms/core/constants/collectionViews';
1725
import type { Collection, Entry, Field } from '@staticcms/core/interface';
@@ -29,8 +37,45 @@ const EntryCard = ({
2937
}: NestedCollectionProps) => {
3038
const summary = useMemo(() => selectEntryCollectionTitle(collection, entry), [collection, entry]);
3139

40+
const fields = selectFields(collection, entry.slug);
3241
const imageUrl = useMediaAsset(image, collection, imageField, entry);
3342

43+
const config = useAppSelector(selectConfig);
44+
45+
const { widgetFor, widgetsFor } = useWidgetsFor(config, collection, fields, entry);
46+
47+
const PreviewCardComponent = useMemo(
48+
() => getPreviewCard(selectTemplateName(collection, entry.slug)) ?? null,
49+
[collection, entry.slug],
50+
);
51+
52+
if (PreviewCardComponent) {
53+
return (
54+
<Card>
55+
<CardActionArea
56+
component={Link}
57+
to={path}
58+
sx={{
59+
height: '100%',
60+
position: 'relative',
61+
display: 'flex',
62+
width: '100%',
63+
justifyContent: 'start',
64+
}}
65+
>
66+
<PreviewCardComponent
67+
collection={collection}
68+
fields={fields}
69+
entry={entry}
70+
viewStyle={viewStyle === VIEW_STYLE_LIST ? 'list' : 'grid'}
71+
widgetFor={widgetFor}
72+
widgetsFor={widgetsFor}
73+
/>
74+
</CardActionArea>
75+
</Card>
76+
);
77+
}
78+
3479
return (
3580
<Card>
3681
<CardActionArea component={Link} to={path}>

packages/core/src/components/Editor/EditorPreviewPane/EditorPreview.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { styled } from '@mui/material/styles';
22
import React from 'react';
33

4-
import type { TemplatePreviewProps } from '@staticcms/core/interface';
4+
import type { ObjectValue, TemplatePreviewProps } from '@staticcms/core/interface';
55

66
const PreviewContainer = styled('div')`
77
overflow-y: auto;
@@ -10,7 +10,7 @@ const PreviewContainer = styled('div')`
1010
font-family: Roboto, 'Helvetica Neue', HelveticaNeue, Helvetica, Arial, sans-serif;
1111
`;
1212

13-
const Preview = ({ collection, fields, widgetFor }: TemplatePreviewProps) => {
13+
const Preview = ({ collection, fields, widgetFor }: TemplatePreviewProps<ObjectValue>) => {
1414
if (!collection || !fields) {
1515
return null;
1616
}

0 commit comments

Comments
 (0)