@buildinams/react-storyblok
Advanced tools
Comparing version 0.1.0 to 0.1.1
@@ -1,2 +0,2 @@ | ||
export { getSectionsRenderer } from "./getSectionsRenderer"; | ||
export { getBlocksRenderer } from "./getBlocksRenderer"; | ||
export { withStoryblokPreviewHOC } from "./withStoryblokPreviewHOC"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.withStoryblokPreviewHOC = exports.getSectionsRenderer = void 0; | ||
var getSectionsRenderer_1 = require("./getSectionsRenderer"); | ||
Object.defineProperty(exports, "getSectionsRenderer", { enumerable: true, get: function () { return getSectionsRenderer_1.getSectionsRenderer; } }); | ||
exports.withStoryblokPreviewHOC = exports.getBlocksRenderer = void 0; | ||
var getBlocksRenderer_1 = require("./getBlocksRenderer"); | ||
Object.defineProperty(exports, "getBlocksRenderer", { enumerable: true, get: function () { return getBlocksRenderer_1.getBlocksRenderer; } }); | ||
var withStoryblokPreviewHOC_1 = require("./withStoryblokPreviewHOC"); | ||
Object.defineProperty(exports, "withStoryblokPreviewHOC", { enumerable: true, get: function () { return withStoryblokPreviewHOC_1.withStoryblokPreviewHOC; } }); |
@@ -1,1 +0,1 @@ | ||
export { getSectionsRenderer, withStoryblokPreviewHOC } from "./client"; | ||
export { getBlocksRenderer, withStoryblokPreviewHOC } from "./client"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.withStoryblokPreviewHOC = exports.getSectionsRenderer = void 0; | ||
exports.withStoryblokPreviewHOC = exports.getBlocksRenderer = void 0; | ||
var client_1 = require("./client"); | ||
Object.defineProperty(exports, "getSectionsRenderer", { enumerable: true, get: function () { return client_1.getSectionsRenderer; } }); | ||
Object.defineProperty(exports, "getBlocksRenderer", { enumerable: true, get: function () { return client_1.getBlocksRenderer; } }); | ||
Object.defineProperty(exports, "withStoryblokPreviewHOC", { enumerable: true, get: function () { return client_1.withStoryblokPreviewHOC; } }); |
@@ -109,9 +109,9 @@ import { ISbCache, ISbComponentType, ISbStoriesParams, ISbStoryData, ISbStoryParams } from "storyblok-js-client"; | ||
export interface EditableContentAttributes { | ||
"data-blok-c": string; | ||
"data-blok-uid": string; | ||
"data-blok-c"?: string; | ||
"data-blok-uid"?: string; | ||
} | ||
export type SectionsRendererComponents = Record<string, any>; | ||
export interface SectionsRendererProps<T> { | ||
export type BlocksRendererComponents = Record<string, any>; | ||
export interface BlocksRendererProps<T> { | ||
items: Item[]; | ||
propsPerItem: (item: Item) => T; | ||
propsPerItem: (item: Item, index: number) => T; | ||
} | ||
@@ -122,3 +122,3 @@ export interface Item { | ||
component: string; | ||
editable: string; | ||
_editable: string; | ||
} |
{ | ||
"name": "@buildinams/react-storyblok", | ||
"description": "Opinionated Reactjs Storyblok wrapper", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"license": "MIT", | ||
@@ -48,4 +48,4 @@ "author": "Build in Amsterdam <development@buildinamsterdam.com> (https://www.buildinamsterdam.com/)", | ||
"dependencies": { | ||
"@storyblok/js": "^2.0.12", | ||
"storyblok-js-client": "^5.3.8" | ||
"@storyblok/js": "^2.0.15", | ||
"storyblok-js-client": "^5.4.1" | ||
}, | ||
@@ -58,3 +58,3 @@ "devDependencies": { | ||
"@types/jest": "^29.4.0", | ||
"@types/node": "^18.11.18", | ||
"@types/node": "^18.13.0", | ||
"@types/react": "^18.0.27", | ||
@@ -64,6 +64,6 @@ "@types/react-dom": "^18.0.10", | ||
"expect-type": "^0.15.0", | ||
"jest": "^29.4.1", | ||
"jest-environment-jsdom": "^29.4.1", | ||
"jest": "^29.4.2", | ||
"jest-environment-jsdom": "^29.4.2", | ||
"npm-run-all": "^4.1.5", | ||
"prettier": "^2.8.2", | ||
"prettier": "^2.8.4", | ||
"react-dom": "^18.0.0", | ||
@@ -70,0 +70,0 @@ "ts-jest": "^29.0.3", |
@@ -257,11 +257,11 @@ # react-storyblok | ||
### getSectionsRenderer | ||
### getBlocksRenderer | ||
This is the final part of the puzzle and semi-optional. Now that we have data + real time updates the final hurdle is getting the green line indicators in the CMS preview. This is done by wrapping blocks that are rendered have the `_editable` identifier. However this is only needed when we are in preview mode. | ||
This is the final part of the puzzle and semi-optional. Now that we have data + real time updates the final hurdle is getting the green line indicators in the CMS preview. This is done by wrapping blocks that are rendered with the `_editable` identifier. However this is _only_ needed when we are in preview mode. Outside of preview mode `_editable` is never set and the blocks will not be wrapped. | ||
To make this process a bit less manual we have the helper function: `getSectionsRenderer`. This will create a React component that loops our items. It works as following: | ||
To make this process a bit less manual we have the helper function: `getBlocksRenderer`. This will create a React component that loops our items. It works as following: | ||
```js | ||
const Renderer = getSectionsRenderer({ | ||
section_content_key: SectionComponent, | ||
```jsx | ||
const Renderer = getBlocksRenderer({ | ||
foo_block: FooBlock, | ||
}); | ||
@@ -271,3 +271,3 @@ | ||
<main> | ||
<Renderer items={items} /> | ||
<Renderer items={items} title="Hello World 👋" /> | ||
</main> | ||
@@ -277,8 +277,16 @@ ); | ||
On initialising the Renderer we pass it an object containing a key / value lookup. Then when rendering the component will use this map to render the correct component. Whenever the list of items gets a value that isn't available in the lookup it will not render anything. | ||
The renderer supports the following props: | ||
Within this renderer there is a hook that will provide all props to make an HTML element show up as the editable element. We still need to attach this to whichever element you want to use in your `SectionComponent`. This can be done like so: | ||
- `items`: _Required_ - The list of items ('blocks') to render. | ||
- `propsPerItem`: Optional - A function that will be called for every item. It will receive the item being rendered as the first argument and the index as the second argument. The return value of this function will be passed to the block as props that you can spread on the element. | ||
- `...rest`: Optional - Any other props will be passed to the block. | ||
#### Using `containerSpread` | ||
On initialising the Renderer we pass it an object containing a key / value lookup. Then when rendering the component we use this map to render the correct component. Whenever the list of items gets a value that isn't available in the lookup it will not render anything. | ||
Within this renderer there is a hook that will provide all props to make an HTML element show up as the editable element. We still need to attach this to whichever element you want to use in your block. This can be done like so: | ||
```js | ||
const SectionComponent = ({ containerSpread, title }) => ( | ||
const FooBlock = ({ containerSpread, title }) => ( | ||
<h1 {...containerSpread}>{title}</h1> | ||
@@ -288,4 +296,37 @@ ); | ||
Make sure every component rendered by the `getSectionsRenderer` is provided the containerSpread prop. By passing this down it gives you control over what element you want to have the indicator around. | ||
**Note**: Make sure every component rendered by the `getBlocksRenderer` is provided the `containerSpread` prop. Without this you won't get real time updates in Storyblok. | ||
#### Using `propsPerItem` | ||
The `getBlocksRenderer` also provides a `propsPerItem` prop. This is an object that contains the props that are passed to the component. This is useful when you want to pass additional props to a specific child component and not all. For example: | ||
```jsx | ||
const BlocksRenderer = getBlocksRenderer({ | ||
foo_block: FooBlock, | ||
bar_block: BarBlock, | ||
}); | ||
const Page = ({ blocks }) => { | ||
return ( | ||
<BlocksRenderer | ||
items={blocks} | ||
propsPerItem={(item, index) => { | ||
if (item.component === "foo_block") { | ||
return { isFoo: true }; | ||
} | ||
if (index === 1) { | ||
return { isBar: true }; | ||
} | ||
}} | ||
/> | ||
); | ||
}; | ||
``` | ||
Here you can see: | ||
- We pass the `isFoo` prop only to the `FooBlock` component via a `item.component` check. | ||
- We pass the `isBar` prop only to the `BarBlock` component via a `index` check. | ||
## Requirements | ||
@@ -292,0 +333,0 @@ |
@@ -1,2 +0,2 @@ | ||
export { getSectionsRenderer } from "./getSectionsRenderer"; | ||
export { getBlocksRenderer } from "./getBlocksRenderer"; | ||
export { withStoryblokPreviewHOC } from "./withStoryblokPreviewHOC"; |
@@ -1,1 +0,1 @@ | ||
export { getSectionsRenderer, withStoryblokPreviewHOC } from "./client"; | ||
export { getBlocksRenderer, withStoryblokPreviewHOC } from "./client"; |
@@ -191,12 +191,12 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
export interface EditableContentAttributes { | ||
"data-blok-c": string; | ||
"data-blok-uid": string; | ||
"data-blok-c"?: string; | ||
"data-blok-uid"?: string; | ||
} | ||
// TODO: Type this properly | ||
export type SectionsRendererComponents = Record<string, any>; | ||
export type BlocksRendererComponents = Record<string, any>; | ||
export interface SectionsRendererProps<T> { | ||
export interface BlocksRendererProps<T> { | ||
items: Item[]; | ||
propsPerItem: (item: Item) => T; | ||
propsPerItem: (item: Item, index: number) => T; | ||
} | ||
@@ -208,3 +208,3 @@ | ||
component: string; | ||
editable: string; | ||
_editable: string; | ||
} |
104153
2001
342
Updated@storyblok/js@^2.0.15
Updatedstoryblok-js-client@^5.4.1