From f88bdf2108164400a440e431993603d618776453 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Sun, 5 May 2024 21:38:22 +0200 Subject: [PATCH] fix: align the naming of render types --- README.md | 92 +++++++++++++++++++++++++++-------------- package.json | 4 ++ src/UmbracoRichText.tsx | 15 ++++--- src/index.ts | 6 ++- 4 files changed, 79 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index fdca925..ef0a2d8 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,13 @@ [![npm version][npm-version-src]][npm-version-href] [![License][license-src]][license-href] -A collection of React components for working with the -Umbraco [Content Delivery API](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api). +A collection of React components for working with the Umbraco +[Content Delivery API](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api). ## Install -Install the `@charlietango/react-umbraco` package with your package manager of choice. +Install the `@charlietango/react-umbraco` package with your package manager of +choice. ```sh npm install @charlietango/react-umbraco @@ -16,51 +17,78 @@ npm install @charlietango/react-umbraco ### `` -Takes the rich text property from the Umbraco Content Delivery API and renders it with React. +Takes the rich text property from the Umbraco Content Delivery API and renders +it with React. ### Props - `element`: The rich text property from the Umbraco Content Delivery API. - `renderBlock`: Render a specific block type. -- `renderNode`: Overwrite the default rendering of a node. Return `undefined` to render the default node. Return `null` to skip rendering the node. +- `renderNode`: Overwrite the default rendering of a node. Return `undefined` to + render the default node. Return `null` to skip rendering the node. + +When passing the `renderBlock` and `renderNode` props, consider making them +static functions (move them outside the consuming component) to avoid +unnecessary re-renders. ```tsx -import { UmbracoRichText } from "@charlietango/react-umbraco"; +import { + UmbracoRichText, + RenderBlockContext, + RenderNodeContext, +} from "@charlietango/react-umbraco"; import Image from "next/image"; import Link from "next/link"; -const MyComponent = ({ data }) => { +function renderNode({ tag, children, attributes }: RenderNodeContext) { + switch (tag) { + case "a": + return {children}; + case "p": + return ( +

+ {children} +

+ ); + default: + // Return `undefined` to render the default HTML node + return undefined; + } +} + +function renderBlock({ content }: RenderBlockContext) { + switch (content?.contentType) { + // Switch over your Umbraco document types that can be rendered in the Rich Text blocks + case "imageBlock": + return ; + default: + return null; + } +} + +function RichText({ data }) { return ( { - switch (tag) { - case "a": - return {children}; - default: - return undefined; - } - }} - renderBlock={({ content }) => { - switch (content?.contentType) { - case "imageBlock": - return ; - default: - return null; - } - }} + renderNode={renderNode} + renderBlock={renderBlock} /> ); -}; +} ``` #### Blocks -You can augment the `renderBlock` method with the generated OpenAPI types for the Umbraco Content Delivery API. -That way you can correctly filter the blocks you are rendering, based on the `contentType`, and get the -associated `properties`. -Create `types/react-umbraco.d.ts`, and augment the `UmbracoBlockItemModel` interface with your applications definition -for `ApiBlockItemModel`. +You can augment the `renderBlock` method with the generated OpenAPI types from +Umbraco Content Delivery API. That way you can correctly filter the blocks you +are rendering, based on the `contentType`, and get the associated `properties`. +Create `types/react-umbraco.d.ts`, and augment the `UmbracoBlockItemModel` +interface with your applications definition for `ApiBlockItemModel`. + +To generate the types, you'll want to use the +[Delivery Api Extensions](https://marketplace.umbraco.com/package/umbraco.community.deliveryapiextensions) +package, alongside a tool to generate the types from the OpenAPI schema, like +[openapi-typescript](https://openapi-ts.pages.dev/). **types/react-umbraco.d.ts** @@ -77,7 +105,9 @@ declare module "@charlietango/react-umbraco" { -[npm-version-src]: https://img.shields.io/npm/v/@charlietango/react-umbraco?style=flat&colorA=080f12&colorB=1fa669 +[npm-version-src]: + https://img.shields.io/npm/v/@charlietango/react-umbraco?style=flat&colorA=080f12&colorB=1fa669 [npm-version-href]: https://npmjs.com/package/@charlietango/react-umbraco -[license-src]: https://img.shields.io/github/license/charlie-tango/react-umbraco.svg?style=flat&colorA=080f12&colorB=1fa669 +[license-src]: + https://img.shields.io/github/license/charlie-tango/react-umbraco.svg?style=flat&colorA=080f12&colorB=1fa669 [license-href]: https://github.com/charlie-tango/react-umbraco/blob/main/LICENSE diff --git a/package.json b/package.json index c201c86..2e5ace6 100644 --- a/package.json +++ b/package.json @@ -73,5 +73,9 @@ "biome check --apply --no-errors-on-unmatched" ], "*.md": ["prettier --write"] + }, + "prettier": { + "proseWrap": "always", + "printWidth": 80 } } diff --git a/src/UmbracoRichText.tsx b/src/UmbracoRichText.tsx index 58e5332..595e12b 100644 --- a/src/UmbracoRichText.tsx +++ b/src/UmbracoRichText.tsx @@ -36,7 +36,10 @@ interface BaseBlockItemModel { */ export type UmbracoBlockItemModel = {}; -type BlockItemModel = Overwrite; +export type RenderBlockContext = Overwrite< + BaseBlockItemModel, + UmbracoBlockItemModel +>; interface RouteAttributes { path: string; @@ -59,7 +62,7 @@ interface NodeMeta { * Props for rendering a single node in the rich text. * A node is any HTML element that is part of the rich text. */ -export type RenderNodeProps = { +export type RenderNodeContext = { children?: React.ReactNode; meta: NodeMeta; } & ( @@ -84,16 +87,16 @@ interface RichTextProps { tag: string; attributes?: Record; elements?: RichTextElementModel[]; - blocks?: Array; + blocks?: Array; } | undefined; - renderBlock?: (block: BlockItemModel) => React.ReactNode; + renderBlock?: (block: RenderBlockContext) => React.ReactNode; /** * Render an HTML node with custom logic. * @param node * @returns A React node, `null` to render nothing, or `undefined` to fallback to the default element */ - renderNode?: (node: RenderNodeProps) => React.ReactNode | undefined; + renderNode?: (node: RenderNodeContext) => React.ReactNode | undefined; } type RichTextElementModel = @@ -129,7 +132,7 @@ function RichTextElement({ meta, }: { element: RichTextElementModel; - blocks: Array | undefined; + blocks: Array | undefined; meta: | { ancestor?: string; diff --git a/src/index.ts b/src/index.ts index 86ad07c..ab07505 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,6 @@ export { UmbracoRichText } from "./UmbracoRichText"; -export type { UmbracoBlockItemModel, RenderNodeProps } from "./UmbracoRichText"; +export type { + UmbracoBlockItemModel, + RenderBlockContext, + RenderNodeContext, +} from "./UmbracoRichText";