a11y-vue-dialog

An accessibility-first renderless (headless) dialog component made for Vue https://renatodeleao.github.io/a11y-vue-dialog/

MIT License

Downloads
294
Stars
12

Bot releases are hidden (Show)

a11y-vue-dialog - v0.11.1 Latest Release

Published by renatodeleao about 1 year ago

The [workaround introduced on release v0.4.4](https://github.com/renatodeleao/a11y-vue-dialog/releases/tag/v0.4.4) came back to haunt me. Even though I could probably find another workaround not to produce a breaking change I decided to go the simpler way and fix it without workarounds.

The side-effect is now that this package requires a new rootRef binding besides the already mandatory dialogRef, and backdropRef can no longer be used as root as present in the documentation.

So new dialogs MUST HAVE the following structure

<a11y-vue-dialog #default="{ rootRef, dialogRef, backdropRef }">
   <div v-bind="rootRef.props">
       <div v-bind="backdropRef.props" v-on="backdropRef.listeners" /> <!-- optional -->
       <div v-bind="dialogRef.props" v-on="dialogRef.listeners">
       </div>
  </div>
</a11y-vue-dialog>

as usual, you're free to use any elements/components of your choice and everything else is optional (but not for long, since this is a11y dialog I'll be more strict and throw errors if, for example, the mandatory titleRef is not binding.

a11y-vue-dialog - v0.9.0-beta.1 "Another focus-trap update"

Published by renatodeleao over 1 year ago

focus-trap was bumped to 7.3.1 with bugfixes from the underlying tabbable package bumped to 6.1.1.
Changes are mostly related with support for HTML inert attribute.

Check their releases for more info:

a11y-vue-dialog - v0.9.0-beta.0 "The focus trap update"

Published by renatodeleao almost 2 years ago

Just upgrades focus-trap dependency from 6.9.4 to 7.2.0. Since it's a breaking change from the underlying package, bump this packages version as new minor pre-release.

None of my examples/demos were impacted by this change, but if yours do, please refer to focus-trap releases

a11y-vue-dialog -

Published by renatodeleao about 2 years ago

💚 with @vue/compat

this patch enables the component to work correctly when in a vue 3 environment paired @vue/compat (aka migration build).

It does so by forcing MODE: 3 in their compatConfig option, which makes vue treat it as regular vue3 component.

a11y-vue-dialog - v0.8.0-beta.2

Published by renatodeleao about 2 years ago

From this version on we provide universal support for vue 2 and vue 3 with the same package 🎊

Full Changelog: https://github.com/renatodeleao/a11y-vue-dialog/compare/v0.8.0-beta.1...v0.8.0-beta.2

a11y-vue-dialog - v0.8.0-beta.1

Published by renatodeleao about 2 years ago

Fixing dialogs breaking when null was provided as initialFocus value. New focus-trap does not allow it.

Full Changelog: https://github.com/renatodeleao/a11y-vue-dialog/compare/v0.8.0-beta.0...v0.8.0-beta.1

a11y-vue-dialog - 0.8.0-beta.0

Published by renatodeleao about 2 years ago

Warning

This version has one bug: it requires to have at least on focusRef binding. Because focus-trap version does not accept initialFocus config to be null and breaks instead of finding the first tabbable element. Fixed in the next version.

Breaking

  • Removes portal-vue as dependency: no longer ships any portal as a dependency, as this component should work with any user land one. closed #11 and #16
  • Renamed renderless export from A11yVueDialogRenderless to simply A11yDialog. We no longer provided any styled solution, so there's no need to make the name state that fact. We're assumedly headless/renderless now.
  • No longer ships a Vue plugin as default export: since we don't provided any styled solution, this package is no longer a plug-and-play solution and, as such, it doesn't make sense to keep it. Consumers can still provide this as a global component via Vue.component('name', A11yDialog') which was everything that our plugin was doing to be honest.

Maintenance

Full Changelog: https://github.com/renatodeleao/a11y-vue-dialog/compare/v0.7.0...v0.8.0-beta.0

a11y-vue-dialog - Prevent leaking implementations

Published by renatodeleao over 3 years ago

  • Since we have complete freedom on markup, most common implementations apply the v-if on the slot content root as was suggested in readme examples. That being said, it's not wrong to apply v-if to the a11y-vue-dialog itself, to a wrapper element, to the <portal> element or the <transition> element itself. Before this minor, if any of these cases happened, the handleClose handler would not be called, and some leaks could occur. Now we call it correctly on beforeDestroy, meaning that consumers can safely implement in any way.
  • Now forwards the event object that triggers @close

Also tested usage with portal-vue-simple and it works flawlessly, I will probably make this as the official peer-dependency for the official 1.0 release as it's more than enough for our dialog needs and only 3k (1.3k gzip).

a11y-vue-dialog -

Published by renatodeleao almost 4 years ago

Remove preventBackgroundScroll prop.

  • Currently it was naively applying overflow: hidden to body but we all know that preventing backgroundScroll in a cross-browser/device world is far more complicated than that.
  • Adding overflow:hidden to body assumed that the consumer app "scroller" was body, when it might not be the case.
  • Replaced with custom events, @show, @hide and added example so of how to achieve previous behaviour using them in your compositions.
a11y-vue-dialog -

Published by renatodeleao about 4 years ago

Allow close on Esc even if role="alertdialog" as per wai-aria guideline example

Note that backdrop click to close is still prevented, because technically it's outside the dialog element (and we haven't tested another way so), probably in the next release we'll have smarter prevention.

Content authors SHOULD make alert dialogs modal by ensuring that, while the alertdialog is shown, keyboard and mouse interactions only operate within the dialog.
https://www.w3.org/TR/wai-aria-1.1/#alertdialog

a11y-vue-dialog - v0.5.1

Published by renatodeleao about 4 years ago

Fixes focus-trap initialFocus option handling of autofocus elements. Here's the default focus order:

1. focusRef` binding 
2. elements with `[autofocus]` attribute  — (`document.querySelector('[autofocus]'))
3. first focusable element
4. use focus-trap fallback (dialogRef)

The problem was that we weren't checking if 2 was a valid candidate for the autofocus attribute — input, select, button and textarea to be precise — and I faced a bug where a vue input component wrapper didn't have inheritAttrs: false, so a magic <div autofocus> was trying to be erroneously focused, not focusing the actual input.

Note that if you want to focus an invalid element you can still do

<div tabindex="0" v-bind="focusRef.attrs">
If you're that kind of person, don't forget the tabindex!
</div>
a11y-vue-dialog - v0.5.0

Published by renatodeleao about 4 years ago

Focus management like a pro!

a11y-vue-dialog - v0.4.9

Published by renatodeleao about 4 years ago

  • Fix incorrect usage of package.json main field, that would break systems without specific setup for transpilling our source code... i mean why the heck was i shipping a package point to the src in the first place?
  • Updates rollup config accordingly
  • adds upkg field that points to minified version
  • Bump dependecies

Thanks to Dependabot, you're tha bot!

a11y-vue-dialog - And this kids, is why you shouldn't do OSS after 10hours of work

Published by renatodeleao over 4 years ago

It's the same as the previous release, but with actual build or dist code in it.

a11y-vue-dialog - focus-visible breaking focusTrap 🚨

Published by renatodeleao over 4 years ago

🚨🚨🚨 This release was published without the build code, use the next patch.🚨🚨🚨
Another day, another exception.

On a project of mine i've added focus-visible polyfill as to match a ui requirement on focus styles and suddenly the dialog was broken. focus-visible polyfill adds attributes to elements and attaches focus and blur events to the document: those attribute changes were triggering mutations, and the events were setting document.activeElement to body for a brief moment. Our mutationObserver was catching that brief moment as "the focused item was removed/hidden and it's not focus anymore, do the focus trap magic to find the next focusable element" But the next focusable element to body is always the first focusable element of the dialog, so we're stuck in a loop.

Fix was just moving our observer verifications into a setTimeout() call, moving them to the next queue, after the focus-visible and other focus attaching plugins/polyfills done their things

a11y-vue-dialog - FOCUS FOCUS FOCUS 2.0

Published by renatodeleao over 4 years ago

Make the naive patch on v0.4.5 not so naive, by keeping track of mutated focus elements positions and continue the expected tab sequence even after focus is lost to body (out of the trap) due to a mutation event (could be v-if, v-show, class that hidden, setting the button disabled
— basically anything that makes an interactive/focusable element inert).

This is the TL;DR and https://github.com/renatodeleao/a11y-vue-dialog/commit/bfade5bb292fc6a1e8e01ace815f62d33bd8667f description and comments might help with details if interested.


I've spent more time on this than i should, got a couple of grey hairs and I imagine that there's probably a better/faster/stronger/simpler way of doing it. At this point I just don't fucking care. I've reached the breaking point and managed to get out of there and that's all that matters to me.

Yes it still doesn't work as expected for all possible scenarios, but it doesn't break either. I'll bump this to a minor as soon as i've got a definitive solution, but I don't want to hear about dialogs in the next month, just want to go back to my job now. Check https://github.com/renatodeleao/a11y-vue-dialog/issues/22 for progress.

☮️ :shipit:

a11y-vue-dialog - v-if or v-show (or css similars) within dialog and focus management

Published by renatodeleao over 4 years ago

This release patches a bug that happened when focused element was removed/hidden from the dom after an action on itself. #21

Note: this is not a perfect solution, but at least we can close the dialog 🤷‍♂️ afterwards.

I'll release a more robust solution on next patch.

a11y-vue-dialog - Edge case on pseudo-drag closing

Published by renatodeleao over 4 years ago

A user found this edge case while "pseudo-dragging2 text selection from within to outside dialog (backdrop). Since its dialog backdrop was allso the root (wrapper) of the dialogRef itself, mouseup event bubbled and triggered click event at backdropRef (note: expected native behaviour) and closing the dialog.

Although it's the native behaviour, it's apparently not user-friend.

I wasn't sure if i should write code to handle this edge case or add a note to the docs, saying:

if you don't want this behaviour, make sure your backdropRef is not the same element as your dialog wrapper (root).

I end up including it, till some-else complains, hopefully after v1.0.0 will have more feedback for the expected usage.

Uff, this was long: now this doesn't happen by default ⬇

edge-case-pseudo-drag

Implementation

https://github.com/renatodeleao/a11y-vue-dialog/commit/f61af1afe4a914a37ec138e99641bf848b5ada63

a11y-vue-dialog - remove opinionated scroll preventing behavior

Published by renatodeleao over 4 years ago

adding overflow hidden to this.$root was assuming too much of it's html markup structure and could create unwanted side effects (like empty scrollbars on non-full-width root divs).

This was added to prevent modal jump, but adding overflow-y: scroll to html is way more common now.

Anyways, if you need that kind of control, add watcher the open prop of your composition, and perform your custom side-effects there.

a11y-vue-dialog - Focus focus focus

Published by renatodeleao over 4 years ago

  • More closely aligned with WAI ARIA guidelines on focus: now it gives priority to autofocus elements instead of just focusing on the first focusable element (fallback)
  • Adds focusRef to delegate consumer what's the appropriate element to focus for each dialog scenario
  • Improves and fixes focusTrap error.
  • Adds specs for the features and band-aids failing ones
  • Tapping esc while on focused on an <input type="search"> will not close the dialog unless the input is empty (default behaviour of this input is to reset the input value and we don't want to interfere with that)
  • Fixes a bug where selecting text content within the dialog would remove the possibility of closing the dialog using keyboard

References