1.0.5 • Published 9 days ago

@contensis/canvas-react v1.0.5

Weekly downloads
-
License
ISC
Repository
github
Last release
9 days ago

@contensis/canvas-react

Render content curated in a Contensis canvas field in your React projects.

Installation

Install with your project's preferred package manager

npm install --save @contensis/canvas-react
yarn add --save @contensis/canvas-react

Usage

Render canvas content with React

import React, { useState } from 'react';
import ReactDOM from 'react-dom/client';
import { RenderContextProvider, Renderer } from '@contensis/canvas-react';
import * as CanvasData from './canvas-data';

// Our React App
const App = () => {
  const [data] = useState(CanvasData.data); // Demo data

  return (
    <div className="content">
      <RenderContextProvider>
        <Renderer data={data} />
      </RenderContextProvider>
    </div>
  );
};

const element = document.getElementById('root') as HTMLElement;
ReactDOM.createRoot(element).render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);

You can override the default rendering for content blocks by adding your own render components when creating the canvas renderer

import React, { useState } from 'react';
import ReactDOM from 'react-dom/client';
import { Block, Image, ImageBlock, RenderBlockProps, RenderContextProvider, Renderer, Table, TableBlock } from '@contensis/canvas-react';
import * as CanvasData from './canvas-data';

const MyImage = (props: RenderBlockProps<ImageBlock>) => {
    // Embelish the image markup if a caption is included
    const caption = props.block?.value?.caption;
    // Set a className for the image in all cases
    return !!caption ? (
        <figure className="figure" style={{ display: 'block' }}>
            <Image {...props} className="figure-img img-fluid" />
            <figcaption className="figure-caption text-end">{caption}</figcaption>
        </figure>
    ) : (
        <Image {...props} className="img-fluid" />
    );
};

const MyTable = (props: RenderBlockProps<TableBlock>) => {
    // Set CSS className on tables
    return <Table {...props} className="table table-striped" />;
};

// Component wrapping a Renderer for simple usage
const SimpleRenderer = ({ data }: { data: Block[] }) => {
    return (
        <RenderContextProvider
            blocks={{
                _image: MyImage,
                _table: MyTable
            }}
        >
            <Renderer data={data} />
        </RenderContextProvider>
    );
};

// Our React App
const App = () => {
    const [data] = useState(CanvasData.data); // Demo data

    return (
        <div className="content">
            <SimpleRenderer data={data} />
        </div>
    );
};

const element = document.getElementById('root') as HTMLElement;
ReactDOM.createRoot(element).render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);

We can do the same for any Component fields present in the Canvas data

import React, { useState } from 'react';
import ReactDOM from 'react-dom/client';
import { Block, Image, RenderContextProvider, Renderer, Table } from '@contensis/canvas-react';
import * as CanvasData from './canvas-data';

type Book = { cover: string; name: string };

// Render a "book" component within the canvas data
const MyBookComponent = (props: RenderBlockProps<ComponentBlock<Book>) => {
  const book = props.block?.value;
  if (!book) return null;
  return (
    <div className="card mb-3">
      <div className="row g-0">
        <div className="col-md-8">
          <div className="card-body">
            <h5 className="card-title">{book.name}</h5>
            <p className="card-text">{book.name}</p>
          </div>
        </div>
        <div className="col-md-4">
          <img src={book.cover} className="img-fluid rounded-start" />
        </div>
      </div>
    </div>
  );
}

// Component wrapping a customised Renderer for use in our app
const SimpleRenderer = ({ data }: { data: Block[] }) => {
    return (
        <RenderContextProvider
            components={{
                book: MyBookComponent,
            }}
        >
            <Renderer data={data} />
        </RenderContextProvider>
    );
};

// Our React App
const App = () => {
    const [data] = useState(CanvasData.data); // Demo data

    return (
        <div className="content">
            <SimpleRenderer data={data} />
        </div>
    );
};

const element = document.getElementById('root') as HTMLElement;
ReactDOM.createRoot(element).render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);

You try this out with the React example project

1.0.5

9 days ago

1.0.4

4 months ago

1.0.3

4 months ago

1.0.2

5 months ago

1.0.1

5 months ago

1.0.0

5 months ago