Select to view content in your preferred language

How to use the Storybook UI Components in your own custom Experience Builder Widget?

1745
3
Jump to solution
06-23-2023 10:04 AM
JeroenCaarls
Occasional Contributor

Hi there,

I'm trying to create a custom Experience Builder widget. In this widget I would like to use the Jimu UI Library as described here. My starting point was the 'simple' widget in the latest Experience Builder developer edition. In my widget I would like to show a simple card as in described in Storybook.

 

 

 

/** @jsx jsx */ // <-- make sure to include the jsx pragma
import { React, AllWidgetProps, jsx } from 'jimu-core'
import { Card, CardBody } from 'jimu-ui'
import { IMConfig } from '../config'

export default class Widget extends React.PureComponent<AllWidgetProps<{}>, any>{
  render(){
    return (
      <div className="widget-demo jimu-widget m-2" >
      <div>
    <Card>
      <img
        alt="Card image cap"
        src="https://source.unsplash.com/300x200?city"
        width="100%"
      />
      <CardBody>
        <h5>Custom Footer</h5>
        <p>Example text for the card content.</p>
      </CardBody>
    </Card>
    </div>
    </div>
    )
  }
}

 

 

 

I'm new to React/Jimu-UI and it seems like I'm doing it wrong. I'm getting this error:

 

 

'CardBody' cannot be used as a JSX component.
  Its instance type 'CardBody' is not a valid JSX element.
    The types returned by 'render()' are incompatible between these types.
      Type 'React.ReactNode' is not assignable to type 'import("c:/ArcGISExperienceBuilder/client/your-extensions/widgets-sample-code/Workflow/node_modules/@types/react/index").ReactNode'.
        Type '{}' is not assignable to type 'ReactNode'.

 

 

The card won't render properly. I didn't find any proper example on how to do this. Can somebody give me a hint on how to use components in my widget.

Thanks for your help!

 

0 Kudos
1 Solution

Accepted Solutions
JeroenCaarls
Occasional Contributor

Seems like these VS Code errors can be ignored, will figure out later how to fix this.

Modified my code a little bit I'm, my tiles/cards are now stored in an array, added Col and CardImg. Layout is fine now.

        <div>
          <Row>
            {this.tiles.map((tile) => (
              <Col sm="12" md="6" lg="4">                
                  <Card className='m-3' onClick={() => this.handleClick(tile.link,tile.target)}>                  
                    <CardImg
                    
                      src={tile.imageSrc}
                      alt={tile.imageAlt}
                      style={{
                        height: "180px",
                        marginLeft: "auto",
                        marginRight: "auto"
                      }}
                      top
                    />
                    <CardBody className='widget-card-content'>
                      <h5>{tile.title}</h5>
                      <p>{tile.description}</p>
                    </CardBody>
                  </Card>
              </Col>
            ))}
          </Row>
        </div>

 

View solution in original post

0 Kudos
3 Replies
JeffreyThompson2
MVP Regular Contributor

Did you import CardBody?

import {CardBody} from 'jimu-ui'

<CapitalizedElements></CapitalizedElements> in React are React components and need to be defined or imported in the TSX/JSX file they are used in.

GIS Developer
City of Arlington, Texas
0 Kudos
JeroenCaarls
Occasional Contributor

Yes, I did. My fault for not mentioning it updated my code sample in the post. It doesn't complain about Card, only Cardbody.

0 Kudos
JeroenCaarls
Occasional Contributor

Seems like these VS Code errors can be ignored, will figure out later how to fix this.

Modified my code a little bit I'm, my tiles/cards are now stored in an array, added Col and CardImg. Layout is fine now.

        <div>
          <Row>
            {this.tiles.map((tile) => (
              <Col sm="12" md="6" lg="4">                
                  <Card className='m-3' onClick={() => this.handleClick(tile.link,tile.target)}>                  
                    <CardImg
                    
                      src={tile.imageSrc}
                      alt={tile.imageAlt}
                      style={{
                        height: "180px",
                        marginLeft: "auto",
                        marginRight: "auto"
                      }}
                      top
                    />
                    <CardBody className='widget-card-content'>
                      <h5>{tile.title}</h5>
                      <p>{tile.description}</p>
                    </CardBody>
                  </Card>
              </Col>
            ))}
          </Row>
        </div>

 

0 Kudos