Question about dmc.HoverCard

Hi Everybody, would love your help on smoething:

No matter what I do, I can’t get the target width to be bigger (say, 100% of the div).
Would love any help, here is my code:

dmc.HoverCard([
                dmc.HoverCardTarget(
                    html.Div(dmc.Paper([
                        dmc.Group([
                            dmc.Avatar(children=DashIconify(icon='mdi:user'),radius='xl',color=color_dict['blue'],style={'border': '1px solid white','backgroundColor':'white'}),
                        ],justify='space-between') if chat_layout else None,
                        shown_content,
                        reference_div if chat_layout else None,
                        attchment_div if chat_layout else None,
                        tools_div if chat_layout else None,
                        ], 
                        radius='lg',
                        withBorder=True if chat_layout else False,
                        p='sm',
                        shadow = 'xs' if chat_layout else None,
                        style={
                            'backgroundColor': color_dict['blue'],
                            'marginLeft': 'auto',
                            'marginRight': 5,
                            # 'maxWidth': '85%',
                            'width': 'fit-content',       # <—— ADD THIS
                            'display': 'block'          # <—— ADD THIS
                        } if chat_layout else 
                        {'display': 'flex','justifyContent': 'center', 'width': '100%','direction':language_dict[i['metadata']['language']]['direction']}),
                        style={'display': 'flex', 'justifyContent': 'flex-end', 'width': '100%'}
                        ),
                ),
                dmc.HoverCardDropdown(
                    dmc.Group([
                        dmc.ActionIcon(DashIconify(icon='mdi:pencil'),id={'type':'edit','index':str(n)},variant='transparent',color='lightgray',n_clicks=None),
                        dmc.ActionIcon(DashIconify(icon='mdi:delete'),id={'type':'delete','index':str(n)},variant='transparent',color='red',n_clicks=None),
                    ]),
                ),
            ],position='left')

Hello @odedloe87

Have you looked into using the styles api? It gives a more robust way to style the components.

Mantine components are a group of nested dom components, so the styles allow you to target each and make adjustments to it.

Hi @odedloe87

Try using the width prop

Here’s the first example from the docs with the width=100%




import dash_mantine_components as dmc
from dash import Dash

app = Dash()

component = dmc.HoverCard(
    withArrow=True,
    width='100%',
    shadow="md",
    children=[
        dmc.HoverCardTarget(dmc.Button("Hover to reveal the card")),
        dmc.HoverCardDropdown(
            dmc.Text(
                "Hover card is revealed when user hovers over target element, it will be hidden once mouse is not over",
                size="sm",
            )
        ),
    ],
)


app.layout = dmc.MantineProvider(
    component
)


if __name__ == "__main__":
    app.run(debug=True)



1 Like

Hi @jinnyzor,

Thanks, I tried that but there is no styles api for the target component.
Thanks for your response and help!

After experimenting a bit more, I realized the width issue happens because shown_content is rendered inside an html.Iframe.

This leads me to a follow-up question: when using the html output from the RichTextEditor, the only way I initially found to display the content without showing raw HTML tags was by using an iframe. I’ve now switched to converting the HTML into Markdown and rendering it with dcc.Markdown, which works — but I’m wondering if there a simpler or more direct way to display the RichTextEditor’s HTML output (e.g., in dmc.Text or another Mantine component) without an iframe and without exposing raw HTML?

Here is how I did it:

from bs4 import BeautifulSoup
from dash import html
def rte_html_to_dash(html_string):

    soup = BeautifulSoup(html_string, "html.parser")

    # recursive conversion
    def convert(node):
        if node.name is None:
            return node.string

        tag = node.name.lower()
        children = [convert(c) for c in node.children]

        # basic mappings
        mapping = {
            "p": html.P,
            "strong": html.Strong,
            "em": html.Em,
            "ul": html.Ul,
            "ol": html.Ol,
            "li": html.Li,
            "h1": html.H1,
            "h2": html.H2,
            "h3": html.H3,
            "h4": html.H4,
            "h5": html.H5,
            "h6": html.H6,
            "a": lambda **props: html.A(children, **props),
            "img": lambda **props: html.Img(**props),
            "code": html.Code,
            "pre": html.Pre,
            "blockquote": html.Blockquote,
            "hr": html.Hr,
        }

        if tag in mapping:
            # process attributes
            attrs = node.attrs
            if tag == "a":
                return html.A(children, href=attrs.get("href"), target="_blank")
            if tag == "img":
                return html.Img(src=attrs.get("src"), style={"maxWidth":"100%"})

            return mapping[tag](children)
        
        # fallback: wrap unknown tags as Div
        return html.Div(children)

    return html.Div(convert(soup.body or soup))

Thanks for your help!

In DMC 2.4, you can set editable=False on the RichTextEditor and it will display the html content without the toolbar.


Alternately, you can use the dcc.Markdown. It will render raw html using by setting dangerously_allow_html=True . No need to convert to markdown format.

dcc.Markdown( 
    children=your_html_from_RTE
    dangerously_allow_html=True
)