Pass HTML into custom Component

Issue

I’ve created a custom component to simply layout content inside IonCardContent. This works great for my needs so far:

interface ContainerProps {
    position?: string;
    content?: string,
    colour?: string;
    custClass?: string;
}

const CardContainer: React.FC<ContainerProps> = ({ position = "right", content = "n/a", colour = "", custClass = "" }) => {
    
    if ( position.trim().toLowerCase() === "right" ) {
        return <><div className={"ion-float-right " + custClass} >{content}</div><div className="clear-right"></div></>
    } else if ( position.trim().toLowerCase() === "left" ) {
        return <div className={"ion-float-left " + custClass}>{content}</div> 
    } else if ( position.trim().toLowerCase() === "full" ) {
        return <div className={""  + custClass}>{content}</div>
    } else if ( position.trim().toLowerCase() === "empty" ) { 
        return <div className={""  + custClass}>&nbsp;</div> 
    } else {
        return null
    }  
};

export default CardContainer;

However, I’d now like to start passing in some html elements to the component so I can do things like highlight sections of text by making it bold or by wrapping part of the string in a span and adding a css class to it.

At present, adding html to the content attribute just results in this being displayed as a literal string. This is obviously due to "content" being declared as a string.

Is the solution to displaying html simply changing the type declaration in the Interface? If so, what to? Or is a more complex solution required?

Thanks.

Solution

Passing all my html output plus dynamic content passed in via variable, into the santizer meant that the variables were either stripped out or their calls were displayed as literal markup.

Therefore, it was necessary to just sanitize the variable that contained the html content passed to the component.

import React from 'react';
import './CardContainer.css';
import sanitizeHtml from 'sanitize-html';

interface ContainerProps {
    position?: string;
    content?: string,
    colour?: string;
    custClass?: string;
}

const CardContainer: React.FC<ContainerProps> = ({ position = "right", content = "n/a", colour = "", custClass = "" }) => {
    
    const clean = sanitizeHtml(content, {
        allowedTags: ['b', 'i', 'em', 'strong', 'a', 'div', 'span'],
        allowedAttributes: {
          a: ['href', 'target'],
          div: ['class', 'className'],
          span: ['style', 'class', 'className']
        }
    });
    


    if ( position.trim().toLowerCase() === "right" ) {
        return <><div className={"ion-float-right " + custClass} dangerouslySetInnerHTML={{__html: clean}}/><div className="clear-right"></div></>
    } else if ( position.trim().toLowerCase() === "left" ) {
        return <div className={"ion-float-left " + custClass} dangerouslySetInnerHTML={{__html: clean}}/>
    } else if ( position.trim().toLowerCase() === "full" ) {
        return <div className={""  + custClass} dangerouslySetInnerHTML={{__html: clean}}/>
    } else if ( position.trim().toLowerCase() === "empty" ) { 
        return <div className={""  + custClass}>&nbsp;</div> 
    } else {
        return null
    }  
};

export default CardContainer;

Answered By – Phill Healey

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published