add DirectionProvider#650
Conversation
|
Test Environment for snehilvj/dash-mantine-components-650 |
|
Here's the code for the sample app hosted on PyCafe import dash
import dash_mantine_components as dmc
from dash import Dash, Input, Output, State, callback
from dash_iconify import DashIconify
app = Dash()
logo = "https://github.com/user-attachments/assets/c1ff143b-4365-4fd1-880f-3e97aab5c302"
main = dmc.Box([
dmc.Select(data=["A", "B", "C"], value="B", label="select"),
dmc.Slider(
id="slider-callback",
value=26,
marks=[
{"value": 20, "label": "20%"},
{"value": 50, "label": "50%"},
{"value": 80, "label": "80%"},
],
mt=35,
),
], p="xl")
layout = dmc.AppShell(
[
dmc.AppShellHeader(
dmc.Group(
[
dmc.Burger(id="burger", size="sm", hiddenFrom="sm", opened=False),
dmc.Image(src=logo, h=40, flex=0),
dmc.Title("Demo App", c="blue"),
dmc.ActionIcon(DashIconify(icon="tabler:text-direction-ltr", width=18),id="rtl-toggle", variant="outline", color="gray")
],
h="100%",
px="md",
)
),
dmc.AppShellNavbar(
id="navbar",
children=[
"Navbar",
*[dmc.Skeleton(height=28, mt="sm", animate=False) for _ in range(15)],
],
p="md",
),
dmc.AppShellMain(main),
],
header={"height": 60},
padding="md",
navbar={
"width": 300,
"breakpoint": "sm",
"collapsed": {"mobile": True},
},
id="appshell",
)
#
app.layout = dmc.DirectionProvider(dmc.MantineProvider(layout), id="direction", persistence=True, direction="ltr")
@callback(
Output("appshell", "navbar"),
Input("burger", "opened"),
State("appshell", "navbar"),
prevent_initial_call=True
)
def navbar_is_open(opened, navbar):
navbar["collapsed"] = {"mobile": not opened}
return navbar
@callback(
Output("rtl-toggle", "children"),
Output("direction", "direction"),
Input("rtl-toggle", "n_clicks"),
State("direction", "direction")
)
def toggle_direction(n, d):
if n is None:
return dash.no_update
new_dir = "ltr" if d == "rtl" else "rtl"
return DashIconify(icon=f"tabler:text-direction-{d}", width=18), new_dir
if __name__ == "__main__":
app.run(debug=True) |
| useEffect(() => { | ||
| if (direction && typeof document !== 'undefined') { | ||
| document.documentElement.dir = direction; | ||
| } | ||
| }, [direction]); |
There was a problem hiding this comment.
Would it make sense to use Mantine's useDirection hook here rather than directly manipulating the DOM?
There was a problem hiding this comment.
yeah, I started with that but had some issues with setting it initially and the timing with the theme switch. But that might have been solved by upgrading to 8.3.0, so I'll give it another try.
There was a problem hiding this comment.
Ah OK - not a big deal, particularly if this code is essentially what happens inside useDirection anyway. I was concerned they might have covered more edge cases so using their hook would be more robust, but it sounds like the opposite may be true!
There was a problem hiding this comment.
looks like they are setting the direction in the same way: https://github.com/mantinedev/mantine/blob/ece602c7d023513add4c6ce56af45332f059c1f6/packages/%40mantine/core/src/core/DirectionProvider/DirectionProvider.tsx#L43
There are some other features like toggle, but in Dash I think that's easier to do in a callback.
So, do you think this is OK as-is?
alexcjohnson
left a comment
There was a problem hiding this comment.
Looks good, thanks for investigating the hook, I agree it's better as you have it.
Closes #648
DirectionProvidercomponent to handle RTL (right-to-left) directionDirectionProviderdirectionprop in a callbackNote - needed to update to the latest Mantine 8.3.0 to get this working with multi-page apps and a theme switch consistently.
New in 8.3.0:
DirectionProvidernow automatically subscribes to the dir attribute mutations of the root element (usually<html />) and updates internal state automatically.docs PR: snehilvj/dmc-docs#245