1- # React JS Components
1+ # Crystallize React components
22
3- This brings Image, Grid and Content Transformer component to ease your rendering when using React JS .
3+ Typed React components for rendering Crystallize content: Image, Video, Grid, and Content Transformer .
44
55## Installation
66
7- With NPM :
7+ Use your favorite package manager :
88
99``` bash
10+ # pnpm
11+ pnpm add @crystallize/reactjs-components
12+
13+ # npm
1014npm install @crystallize/reactjs-components
15+
16+ # yarn
17+ yarn add @crystallize/reactjs-components
1118```
1219
13- With Yarn:
20+ All components are exported from the package root and ship with TypeScript types.
1421
15- ``` bash
16- yarn add @crystallize/reactjs-components
22+ ``` typescript
23+ import { Image , Video , GridRenderer , GridRenderingType , ContentTransformer } from ' @crystallize/reactjs-components' ;
1724```
1825
1926## Image
2027
21- This output an ` img ` tag with different source variations from Crystallize using _ srcset_ . Use this to easily build responsive images powered by Crystallize.
28+ Responsive <img > wrapped in a <picture > with srcset support. Pass the image object you get from Crystallize.
29+
30+ ``` typescript
31+ import { Image } from ' @crystallize/reactjs-components' ;
2232
23- ``` javascript
24- import { Image } from ' @crystallize/reactjs-components/dist/image' ;
2533const imageFromCrystallize = {
26- url: ' ...' ,
27- variants: [... ]
28- }
34+ url: ' https://media.crystallize.com/.../image.jpg' ,
35+ altText: ' A nice product' ,
36+ variants: [
37+ // ImageVariant[] from @crystallize/schema
38+ { url:
' .../[email protected] ' , width:
400 },
39+ { url:
' .../[email protected] ' , width:
700 },
40+ { url:
' .../[email protected] ' , width:
1000 },
41+ ],
42+ };
2943
30- < Image
31- {... imageFromCrystallize}
32- sizes= " (max-width: 400px) 300w, 700px"
33- / >
44+ export function ProductImage() {
45+ return <Image {... imageFromCrystallize } sizes =" (max-width: 600px) 90vw, 700px" className =" product-image" />;
46+ }
3447```
3548
36- There is a live demo: https://crystallizeapi.github.io/libraries/reactjs-components/image
49+ Notes
50+
51+ - If the API returns caption in json/html/plainText, the component renders it as <figcaption >.
52+ - You can provide width/height to avoid layout shift; otherwise the largest variant's dimensions are used when available.
53+
54+ Live demo: https://crystallizeapi.github.io/libraries/reactjs-components/image
3755
3856## Video
3957
40- This output videos from Crystallize using the native video element.
58+ Progressive video player that prefers HLS (m3u8) and falls back to MPEG-DASH (mpd). Renders a thumbnail and a play button, then hydrates the player.
59+
60+ Important
4161
42- ``` javascript
43- import { Video } from ' @crystallize/reactjs-components/dist/video' ;
62+ - This component is client-side only (it contains 'use client'). In Next.js, place it in a client component.
63+ - Include the provided styles once in your app:
64+
65+ ``` typescript
4466import ' @crystallize/reactjs-components/assets/video/styles.css' ;
67+ ```
68+
69+ Usage
70+
71+ ``` typescript
72+ import { Video } from ' @crystallize/reactjs-components' ;
73+
4574const videoFromCrystallize = {
46- playlists: [... ],
47- thumbnails: [... ]
48- }
75+ playlists: [' https://media.crystallize.com/.../master.m3u8' , ' https://media.crystallize.com/.../stream.mpd' ],
76+ thumbnails: [
77+ {
78+ url: ' https://media.crystallize.com/.../thumb.jpg' ,
79+ variants: [{ url:
' .../[email protected] ' , width:
700 }],
80+ },
81+ ],
82+ };
4983
50- < Video
51- {... videoFromCrystallize}
52- thumbnmailProps= {{ sizes: " (max-width: 700px) 90vw, 700px" }}
53- / >
84+ export function HeroVideo() {
85+ return (
86+ < Video
87+ {... videoFromCrystallize }
88+ autoPlay
89+ muted
90+ controls
91+ className = " hero-video"
92+ videoProps = {{ playsInline : true }}
93+ / >
94+ );
95+ }
5496```
5597
56- There is a live demo: https://crystallizeapi.github.io/libraries/reactjs-components/video
98+ Live demo: https://crystallizeapi.github.io/libraries/reactjs-components/video
5799
58100## Grid
59101
60- That makes it easy to render Crystallize grids with React JS. In order to use the grid renderer you'll need to have fetched your grid model. This can be fetched fairly easily from Crystallize's API via GraphQL .
102+ Render Crystallize grids in React using CSS Grid (default), a semantic table, or row/col wrappers .
61103
62- At the minimum you will need to fetch layout of each column and some properties on the item. Your query might look something like this :
104+ Fetch the grid via GraphQL (minimum shape shown) :
63105
64106``` graphql
65107query grid ($id : Int ! , $language : String ! ) {
@@ -81,49 +123,54 @@ query grid($id: Int!, $language: String!) {
81123}
82124```
83125
84- Then, inside your component, render the Grid, passing through the grid model as a prop. By default, the grid is rendered using CSS grid but it could also be a Table.
126+ Render
85127
86- ``` javascript
87- < GridRenderer grid= {grid} type= {GridRenderingType .Div } cellComponent= {Cell} / >
88- < GridRenderer grid= {grid} type= {GridRenderingType .Table } cellComponent= {Cell} / >
89- < GridRenderer grid= {grid} type= {GridRenderingType .RowCol } cellComponent= {Cell} / >
90- ```
128+ ``` typescript
129+ import { GridRenderer , GridRenderingType } from ' @crystallize/reactjs-components' ;
91130
92- There is a live demo: https://crystallizeapi.github.io/libraries/reactjs-components/grid
131+ const Cell = ({ cell } : { cell : any }) => < div >{cell.item?. name } < / div > ;
93132
94- ### To go further
133+ <>
134+ {/* CSS Grid */ }
135+ < GridRenderer grid = {grid } type = {GridRenderingType.Div } cellComponent = {Cell } / >
95136
96- If you want full control over each of the cells, you can instead supply a function as the children of the grid component. This will allow you to iterate over each of the cells and mutate them as you please.
137+ {/* Table */ }
138+ < GridRenderer grid = {grid } type = {GridRenderingType.Table } cellComponent = {Cell } / >
97139
98- ``` javascript
99- const children = ({ cells }) => {
100- return cells .map ((cell ) => (
101- < div
102- style= {{
103- gridColumn: ` span ${ cell .layout .colspan } ` ,
104- gridRow: ` span ${ cell .layout .rowspan } ` ,
105- }}
106- >
107- {cell .item .name }
108- < / div>
109- ));
110- };
140+ {/* Row/Col wrappers */ }
141+ < GridRenderer grid = {grid } type = {GridRenderingType.RowCol } cellComponent = {Cell } / >
142+ < / > ;
143+ ```
111144
112- return (
113- < GridRenderer grid= {grid} type= {GridRenderingType .Div } cellComponent= {Cell}>
114- {children}
115- < / GridRenderer>
116- );
145+ Customize per cell via a render-prop or styleForCell
146+
147+ ``` tsx
148+ <GridRenderer grid = { grid } type = { GridRenderingType .Div } cellComponent = { Cell } >
149+ { ({ cells }) =>
150+ cells .map ((cell ) => (
151+ <div
152+ key = { ` ${cell .layout .rowIndex }-${cell .layout .colIndex } ` }
153+ style = { { gridColumn: ` span ${cell .layout .colspan } ` , gridRow: ` span ${cell .layout .rowspan } ` }}
154+ >
155+ { cell .item .name }
156+ </div >
157+ ))
158+ }
159+ </GridRenderer >
117160```
118161
162+ Live demo: https://crystallizeapi.github.io/libraries/reactjs-components/grid
163+
119164## Content Transformer
120165
121- This helps you to transform Crystallize rich text json to React html components.
166+ Render Crystallize rich text JSON to React elements with optional per-node overrides.
167+
168+ ``` tsx
169+ import { ContentTransformer , NodeContent , type Overrides , type NodeProps } from ' @crystallize/reactjs-components' ;
122170
123- ``` javascript
124171const overrides: Overrides = {
125172 link : (props : NodeProps ) => (
126- < a href= {props .metadata ? .href }>
173+ <a href = { props .metadata ?.href } rel = { props . metadata ?. rel } target = { props . metadata ?. target } >
127174 <NodeContent { ... props } />
128175 </a >
129176 ),
@@ -132,6 +179,13 @@ const overrides: Overrides = {
132179<ContentTransformer json = { richTextJson } overrides = { overrides } />;
133180```
134181
135- There is a live demo: https://crystallizeapi.github.io/libraries/reactjs-components/content-transformer
182+ Live demo: https://crystallizeapi.github.io/libraries/reactjs-components/content-transformer
183+
184+ ## Notes on SSR
185+
186+ - Image, Grid, and Content Transformer are SSR-friendly.
187+ - Video must run on the client. In Next.js, put the usage in a Client Component.
188+
189+ ## License
136190
137- [crystallizeobject]: crystallize_marketing|folder|6269c9819161f671155d939d
191+ MIT © Crystallize
0 commit comments