Skip to content

Commit

Permalink
feat: add headless richtext schema field (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenle authored Dec 11, 2023
1 parent ac2fb6b commit 66d7e76
Show file tree
Hide file tree
Showing 19 changed files with 1,028 additions and 237 deletions.
6 changes: 6 additions & 0 deletions .changeset/spotty-coats-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@blinkk/root-cms': minor
'@blinkk/root': minor
---

feat: add richtext schema field
5 changes: 5 additions & 0 deletions examples/blog/collections/BlogPosts.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export default schema.collection({
id: 'content',
label: 'Content',
fields: [
schema.richtext({
id: 'richtext',
label: 'Blog content',
translate: true,
}),
schema.string({
id: 'body',
label: 'Body copy',
Expand Down
236 changes: 115 additions & 121 deletions examples/blog/root-cms.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
/** Root.js CMS types. This file is autogenerated. */

export interface RootCMSImage {
src: string;
width?: number;
height?: number;
alt?: string;
}

export type RootCMSOneOf<T = any> = T & {
_type: string;
}

export interface RootCMSRichTextBlock {
type: string;
data: any;
}

export interface RootCMSRichText {
blocks: RootCMSRichTextBlock[];
}

export interface RootCMSDoc<Fields extends {}> {
/** The id of the doc, e.g. "Pages/foo-bar". */
id: string;
Expand All @@ -25,124 +45,113 @@ export interface RootCMSDoc<Fields extends {}> {

/** Generated from `/collections/BlogPosts.schema.ts`. */
export interface BlogPostsFields {
/** Internal Description. Use this field to leave internal notes, etc. */
internalDesc?: string;
/** Meta */
meta?: {
/** Title */
title?: string;
/** Description. Description for SEO and social shares. */
description?: string;
/** Image. Meta image for social shares. Recommended size: 1200x600. */
image?: {
src: string;
width: number;
height: number;
alt?: string;
};
/** Featured?. Check the box to mark the blog post as a featured blog post. */
featured?: boolean;
/** Tags. Category tags for searching and filtering. */
tags?: string[];
};
/** Content */
content?: {
/** Body copy. Markdown supported. */
body?: string;
};
/** Advanced */
advanced?: {
/**
* Custom CSS. Optional CSS to inject into the page.
* @deprecated
*/
customCss?: string;
/** PDF. PDF version of the post. */
pdf?: {
src: string;
};
/** Published Date Override. Override for the "Published" date. */
publishedAtOverride?: number;
/** Internal Description. Use this field to leave internal notes, etc. */
internalDesc?: string;
/** Meta */
meta?: {
/** Title */
title?: string;
/** Description. Description for SEO and social shares. */
description?: string;
/** Image. Meta image for social shares. Recommended size: 1200x600. */
image?: RootCMSImage;
/** Featured?. Check the box to mark the blog post as a featured blog post. */
featured?: boolean;
/** Tags. Category tags for searching and filtering. */
tags?: string[];
};
/** Content */
content?: {
/** Blog content */
richtext?: RootCMSRichText;
/** Body copy. Markdown supported. */
body?: string;
};
/** Advanced */
advanced?: {
/**
* Custom CSS. Optional CSS to inject into the page.
* @deprecated
*/
customCss?: string;
/** PDF. PDF version of the post. */
pdf?: {
src: string;
};
/** Published Date Override. Override for the "Published" date. */
publishedAtOverride?: number;
};
}

/** Generated from `/collections/BlogPosts.schema.ts`. */
export type BlogPostsDoc = RootCMSDoc<BlogPostsFields>;

/** Generated from `/collections/BlogPostsSandbox.schema.ts`. */
export interface BlogPostsSandboxFields {
/** Internal Description. Use this field to leave internal notes, etc. */
internalDesc?: string;
/** Meta */
meta?: {
/** Title */
title?: string;
/** Description. Description for SEO and social shares. */
description?: string;
/** Image. Meta image for social shares. Recommended size: 1200x600. */
image?: {
src: string;
width: number;
height: number;
alt?: string;
};
/** Featured?. Check the box to mark the blog post as a featured blog post. */
featured?: boolean;
/** Tags. Category tags for searching and filtering. */
tags?: string[];
};
/** Content */
content?: {
/** Body copy. Markdown supported. */
body?: string;
};
/** Advanced */
advanced?: {
/**
* Custom CSS. Optional CSS to inject into the page.
* @deprecated
*/
customCss?: string;
/** PDF. PDF version of the post. */
pdf?: {
src: string;
};
/** Published Date Override. Override for the "Published" date. */
publishedAtOverride?: number;
/** Internal Description. Use this field to leave internal notes, etc. */
internalDesc?: string;
/** Meta */
meta?: {
/** Title */
title?: string;
/** Description. Description for SEO and social shares. */
description?: string;
/** Image. Meta image for social shares. Recommended size: 1200x600. */
image?: RootCMSImage;
/** Featured?. Check the box to mark the blog post as a featured blog post. */
featured?: boolean;
/** Tags. Category tags for searching and filtering. */
tags?: string[];
};
/** Content */
content?: {
/** Blog content */
richtext?: RootCMSRichText;
/** Body copy. Markdown supported. */
body?: string;
};
/** Advanced */
advanced?: {
/**
* Custom CSS. Optional CSS to inject into the page.
* @deprecated
*/
customCss?: string;
/** PDF. PDF version of the post. */
pdf?: {
src: string;
};
/** Published Date Override. Override for the "Published" date. */
publishedAtOverride?: number;
};
}

/** Generated from `/collections/BlogPostsSandbox.schema.ts`. */
export type BlogPostsSandboxDoc = RootCMSDoc<BlogPostsSandboxFields>;

/** Generated from `/collections/Pages.schema.ts`. */
export interface PagesFields {
/** [INTERNAL] Description. Internal-only field. Used for notes, etc. */
internalDesc?: string;
/** Meta */
meta?: {
/** Title. Page title. */
title?: string;
/** Description. Description for SEO and social shares. */
description?: string;
/** Image. Meta image for social shares. Recommended: 1400x600 JPG. */
image?: {
src: string;
width: number;
height: number;
alt?: string;
};
};
/** Content */
content?: {
/** Modules. Compose the page by adding one or more modules. */
modules?: unknown[];
};
/** Advanced */
advanced?: {
/** Analytics. HTML injected into the page for custom analytics. */
analtyics?: string;
};
/** [INTERNAL] Description. Internal-only field. Used for notes, etc. */
internalDesc?: string;
/** Meta */
meta?: {
/** Title. Page title. */
title?: string;
/** Description. Description for SEO and social shares. */
description?: string;
/** Image. Meta image for social shares. Recommended: 1400x600 JPG. */
image?: RootCMSImage;
};
/** Content */
content?: {
/** Modules. Compose the page by adding one or more modules. */
modules?: RootCMSOneOf[];
};
/** Advanced */
advanced?: {
/** Analytics. HTML injected into the page for custom analytics. */
analtyics?: string;
};
}

/** Generated from `/collections/Pages.schema.ts`. */
Expand All @@ -161,25 +170,15 @@ export interface SpacerFields {
/** Generated from `/templates/Template5050/5050assets/ImageAsset.schema.ts`. */
export interface ImageAssetFields {
/** Image to embed. Optional. If not provided, the default YT thumbnail is used. */
image?: {
src: string;
width: number;
height: number;
alt?: string;
};
image?: RootCMSImage;
}

/** Generated from `/templates/Template5050/5050assets/YouTubeAsset.schema.ts`. */
export interface YouTubeAssetFields {
/** YouTube URL */
youtubeUrl?: string;
/** Thumbnail image. Optional. If not provided, the default YT thumbnail is used. */
thumbnail?: {
src: string;
width: number;
height: number;
alt?: string;
};
thumbnail?: RootCMSImage;
}

/** Generated from `/templates/Template5050/Template5050.schema.ts`. */
Expand All @@ -191,7 +190,7 @@ export interface Template5050Fields {
/** Body */
body?: string;
/** Asset */
asset?: unknown;
asset?: RootCMSOneOf;
}

/** Generated from `/templates/TemplateFeaturedBlogPosts/TemplateFeaturedBlogPosts.schema.ts`. */
Expand All @@ -213,10 +212,5 @@ export interface TemplateHeroFields {
/** Title */
title?: string;
/** Image */
image?: {
src: string;
width: number;
height: number;
alt?: string;
};
image?: RootCMSImage;
}
7 changes: 6 additions & 1 deletion examples/blog/routes/blog/[blog-post].tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Handler, HandlerContext, Request} from '@blinkk/root';
import {getDoc} from '@blinkk/root-cms';

import {RichText} from '@blinkk/root-cms/richtext';
import {Container} from '@/components/Container/Container.js';
import {BaseLayout} from '@/layouts/BaseLayout.js';
import {BlogPostsDoc} from '@/root-cms.js';
Expand All @@ -16,6 +16,11 @@ export default function Page(props: Props) {
<BaseLayout title={fields.meta?.title || 'Blog Post'}>
<Container>
<h1>Blog Post</h1>
<div>
{fields.content?.richtext && (
<RichText data={fields.content.richtext} />
)}
</div>
<pre><code>{JSON.stringify(props, null, 2)}</code></pre>
</Container>
</BaseLayout>
Expand Down
Loading

0 comments on commit 66d7e76

Please sign in to comment.