Current position:
Is modal:
Closes on outside click:
Install @divriots/riots-dialog
using NPM (or use a CDN).
// CE definitions
import '@divriots/riots-dialog/define';
import '@divriots/riots-dialog/define-arrow';
// Classes, e.g. for extending
import { RiotsDialog, RiotsDialogArrow } from '@divriots/riots-dialog';
<riots-dialog has-arrow closes-on-outside-click id="modal">
<button class="modal-invoker" slot="invoker">Open Dialog</button>
<form slot="content" method="dialog">
<label>
First Name
<input type="text" name="first_name" />
</label>
<button type="submit" value="confirm">Confirm</button>
<button type="button" data-pos-btn>Switch Position</button>
<riots-dialog-arrow riots-dialog-arrow></riots-dialog-arrow>
</form>
</riots-dialog>
I wanted to see if I can use the native <dialog>
in
combination with @floating-ui
, my main goal was
a locally anchored popover that works like a dialog with backdrop,
using the platform where possible.
I found out it wasn't so trivial to get all the features I wanted in it so I built a wrapper webcomponent around it to give myself a nicer developer experience.
Disclaimer: This is mostly a POC / experiment, so I recommend using this as inspiration for your own project rather than directly extending/consuming it. I have no tests right now and didn't cross-browser test any of this. I have not done proper a11y audit yet, so unknown at the moment how accessible this is, and it's debatable whether a dialog, even if not modal, should be locally anchored/positioned at all. Types done with JSDocs, linted/type declaration files created with TSC, so you're not forced into a compile-step but can still use it in Typescript.
Disclaimer 2: opening a native dialog, with show or showModal, seems to lock scrolling (although page does remain active). I haven't found a way around that so this is not configurable at the moment, it seems to happen on browser level at least on Chrome. This kind of goes against my idea of using it as a locally anchored popover, but oh well.
Also, thanks to @argyleink for Open Props which is what I used to get some normalized default styles for this page.
This list is not complete, my demo doesn't show all features and I plan to
expand with more features for easier customization like passing your own
@floating-ui
middleware, but here's the most important
things:
opened
attribute opens the dialog, removing it closes it,
alternatively, use .open()
or .close()
placement
attribute changes the floating-ui placement
property
is-modal
attribute makes it a modal dialog instead, this
makes page inert, adds a stylable backdrop, etc.
prevent-invoker
attribute makes it so the
invokerNode
doesn't actually open the dialog, in case you
want to handle this with JavaScript imperatively. The invokerNode in
this case is just the reference node.
closes-on-outside-click
attribute makes it so that the
dialog closes on outside click. ESC key works by default.
dialog-opening
,
dialog-opened
, dialog-closing
,
dialog-closed
, which take into account
animations/transitions.
has-arrow
, it will search
for an element with riots-dialog-arrow
attribute. Ensure
you set a width and height property on this element, so we can position
it properly.
position-strategy
attribute to either
absolute
(default) or fixed
which sets the
@floating-ui
positioning strategy.
See their docs about it.