Dash Mantine Components 2.4.1 is now available
-
Added
withAlignedLabelsprop to support offsetting the selected check icon inSelectandMultiSelect#675 by @AnnMarieW. -
Updated to Mantine (8.3.10), Recharts (2.15.4), and TipTap (3.14.0) #675
-
Added
anchorPropstoAnchorallowing to pass any valid attribute (likedownload) to theAnchorcomponent. Thanks to first time contributor @jksinton for PR #676.
The update to the latest TipTap enables features like image resize in the RichTextEditor
import dash_mantine_components as dmc
from dash import Dash, html
app = Dash(__name__)
initial_content = """
<h2 style="text-align: center;">Resizable Image Demo</h2>
<p>Click and drag the resize handles on the image corners to resize:</p>
<img src="https://placehold.co/800x400/6366f1/white?text=Drag+corners+to+resize" />
<p>Try adding more images and resizing them!</p>
"""
app.layout = dmc.MantineProvider(
html.Div([
dmc.RichTextEditor(
id="rte-resizable",
html=initial_content,
extensions=[
"StarterKit",
{
"Image": {
"resize": {
"enabled": True,
"directions": ["top", "bottom", "left", "right"],
"minWidth": 50,
"minHeight": 50,
"alwaysPreserveAspectRatio": True
}
}
},
],
# "alwaysPreserveAspectRatio": True,
editable=True,
toolbar={
"sticky": True,
"controlsGroups": [
["Bold", "Italic", "Underline"],
["H1", "H2", "H3"],
["BulletList", "OrderedList"],
],
},
),
], )
)
if __name__ == "__main__":
app.run(debug=True)
Hereβs the .css file
.tiptap :first-child {
margin-top: 0;
}
.tiptap img {
display: block;
}
.tiptap [data-resize-handle] {
position: absolute;
background: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.8);
border-radius: 2px;
z-index: 10;
}
.tiptap [data-resize-handle]:hover {
background: rgba(0, 0, 0, 0.8);
}
/* Corner handles - always visible */
.tiptap [data-resize-handle='top-left'],
.tiptap [data-resize-handle='top-right'],
.tiptap [data-resize-handle='bottom-left'],
.tiptap [data-resize-handle='bottom-right'] {
width: 8px;
height: 8px;
}
.tiptap [data-resize-handle='top-left'] {
top: -4px;
left: -4px;
cursor: nwse-resize;
}
.tiptap [data-resize-handle='top-right'] {
top: -4px;
right: -4px;
cursor: nesw-resize;
}
.tiptap [data-resize-handle='bottom-left'] {
bottom: -4px;
left: -4px;
cursor: nesw-resize;
}
.tiptap [data-resize-handle='bottom-right'] {
bottom: -4px;
right: -4px;
cursor: nwse-resize;
}
/* Edge handles - hidden by default */
.tiptap [data-resize-handle='top'],
.tiptap [data-resize-handle='bottom'] {
height: 6px;
left: 8px;
right: 8px;
opacity: 0;
transition: opacity 0.2s;
}
.tiptap [data-resize-handle='left'],
.tiptap [data-resize-handle='right'] {
width: 6px;
top: 8px;
bottom: 8px;
opacity: 0;
transition: opacity 0.2s;
}
/* Show edge handles on wrapper hover */
.tiptap [data-resize-wrapper]:hover [data-resize-handle='top'],
.tiptap [data-resize-wrapper]:hover [data-resize-handle='bottom'],
.tiptap [data-resize-wrapper]:hover [data-resize-handle='left'],
.tiptap [data-resize-wrapper]:hover [data-resize-handle='right'] {
opacity: 1;
}
.tiptap [data-resize-handle='top'] {
top: -3px;
cursor: ns-resize;
}
.tiptap [data-resize-handle='bottom'] {
bottom: -3px;
cursor: ns-resize;
}
.tiptap [data-resize-handle='left'] {
left: -3px;
cursor: ew-resize;
}
.tiptap [data-resize-handle='right'] {
right: -3px;
cursor: ew-resize;
}
.tiptap [data-resize-state='true'] [data-resize-wrapper] {
outline: 1px solid rgba(0, 0, 0, 0.25);
border-radius: 0.125rem;
}

