PricingDocsAcademy
Bluesky ...
Wed, Dec 11, 9:54 PM

Approaching dialog design and reusability

  • Tom Ireland

    15 days ago

    This might seem a bit like a noob question but I'm trying to figure out a good approach to developing a dialog component that encapsulates the show/hide functionality without having to utilise page variables to set state e.g. dialog shown/hidden. The idea being that I can reuse this component in various places without any prerequisite configuration on the page and just configure the component accordingly.

    I developed something last year but it still requires capturing the state on the page and I'm thinking there must be a way to do this in the context of a component, particularly if you have multiple dialogs that need to be shown depending on the action taken.

    I tried to reverse engineer a couple of examples I've seen e.g. Andreas' color-picker panel, Max's dialog example for Spark, etc., but not having much luck. I just can't seem to figure this problem out.

    I could use the Popover API but that's not really the best for a dialog where some kind of input is required (better for tooltips, etc.) and it also means that the page is not inert either, so you can still interact with elements behind the dialog.

    I could also forego the dialog and opt for a separate page for CRUD operations but some are simple e.g. one field to input, so better suited to a dialog for UX instead of loading a new page.
  • Max

    15 days ago

    Hi Tom! Dialogs are easy. Proper dialogs are hard 😁
    For my implementation I needed:
    - Provider context for the whole site (to prevent body scroll)
    - A dialog component that does not render anything but holds the context and states
    - A portal (this is a popover used as a portal so that is always rendered in the top layer)
    - The actual dialog content
    - A trigger button that hooks into the dialog context and opens the dialog
  • Tom Ireland

    15 days ago


    πŸ˜‚ Yeah.

    Have you thought about doing any videos on your approach? I know I’d greatly appreciate something like that.

    Would also be cool to something on the toddle YT.

    If I can figure it out, I’ll certainly share something.
  • Max

    15 days ago

    I don't like making videos, but I might release a package
  • Tom Ireland

    15 days ago

    Yeah, I get that. Face on the camera is not for everyone.

    A package would be amazing. Would be fun to dig into the details and reverse engineer it a wee bit.
  • Janis

    15 days ago

    When you use the popover api, you can set the backdrop to blur for instance or disabled it completely, so that user cannot interact with the background
  • Also what is your issue with inputs, im using it for quite a few popovers just fine - perhaps I can be of help for a change πŸ˜‚
  • Tom Ireland

    15 days ago

    Thanks for sharing. I was aware of the backdrop blur but not the ability to disable it. I know I can do that by setting popover to manual on the target div but that means you have to handle hide logic without the benefit of light dismiss when using auto; otherwise, I’m not aware of a way to make the rest of the content inert behind the popover.

    I haven’t had any challenges around using an input with the Popover API; it was more about best practice choices on when to use it. I’m no expert though so open to discussion on that.

    It would certainly be simpler if I could use Popover API if I could prevent background interaction and still have the light dismiss on background click, escape, etc., because you’d just have to specify a target id as an attribute for the component and have that dynamically linked to the div id attribute in the component.
  • Janis

    15 days ago

    Hmm I thought I read somewhere on mdn that you can disable the background dismissal click but keep the esc key dismissal etc.
  • Janis

    15 days ago

    Perhaps another way to think about it: is it like such an important criteria to you that you cannot work with the perceived downsides of the popover api? At least in my opinion it is so much easier that I prefer using it, although I’m still not an expert. Just found out the other week about the backdrop attribute πŸ™ˆ
  • Tom Ireland

    15 days ago

    Yeah, I had a good scour on MDN but no dice. The Popover API (unlike dialog's showModal() ) does not render background content inert i.e. it's non-modal as I understand it. It is possible to set the inert property to true on the root element and I have tested that before, but you need a way to unset it and also still handle that in the context of the component without tracking a page variable e.g. isInert for the root element.

    It is important that other content is not editable for a few reasons e.g. focusing out of the modal, you click something during an API call, some stuff around accessibility that I don't fully understand yet, etc.
  • Tom Ireland

    13 days ago

    @Janis / @Max

    Okay, so might have identified a simple way to handle this. Dialog component receives an attribute of dialog-id for the popover, which is used to populate an id attribute for the dialog element in the component. Use any normal button on the page where you have your cta and set popovertarget to the id of the popover. In the dialog component, set an event of toggle on the dialog element and trigger one line of custom code:

    function toggleInert (args, ctx) {
    document.getElementById("main").toggleAttribute("inert");
    }


    You just need to ensure that your page root element is not the main div, so serves as a wrapper around the main content so that your dialog component is a sibling to the main, which means that only the main div content is set inert and the dialog is ignored. You need to make sure the main div has an id attribute of "main" though.

    Seems less complicated but not bulletproof.

    Any issues with this approach do you think?

    Inspiration: https://blog.logrocket.com/developing-modals-using-only-css-popover-api/#making-dialog-toggleable-using-popover-api
  • Tom Ireland

    13 days ago

    I did think of an alternative to using App as the id, which is the main wrapper that toddle applies so unlikely to change and would mean set and forget, but then couldn't figure out how to set the dialog to not be inert as inert descends to all children.

    Would be cool if there was a reasonably simple toddle-only and no custom action approach.

Stop scrolling. Start building.

toddle is a visual web app builder that rivals custom code β€” but accessible to your entire team!

Try toddle β€” it's free!

Β© Copyright 2024 toddle. All rights reserved.