Vuejs-Vue a11y dialog 1.0.0: vue-a11y-dialog a11y-dialogvue-a11y-dialog - A Vue.js component wrapper for the accessible dialog a11y-dialog.

icon
Latest Release: 1.0.0

This is the first major release that introduces breaking changes. From 1.0.0 onwards the API will support Vue 3.

Changed

Removed

  • Removed dependency to portal-vue
Source code(tar.gz)
Source code(zip)

Vue A11yDialog Build Status

This is a Vue.js wrapper component for [email protected] (demo) using [email protected].

Install

npm install vue-a11y-dialog

Usage

In your main.js application file, install the component:

import VueA11yDialog from "vue-a11y-dialog";

Vue.use(VueA11yDialog);

Then use it as follows:

<template>
  <div id="app">
    <!-- ... -->
    <button type="button" @click="openDialog">
      Open dialog
    </button>

    <a11y-dialog
      id="app-dialog"
      app-root="#app"
      dialog-root="#dialog-root"
      @dialog-ref="assignDialogRef"
    >
      <template v-slot:title>
        <span>Your dialog title</span>
      </template>
      <div>
        <p>Your content</p>
      </div>
    </a11y-dialog>
  </div>
</template>
export default {
  name: "YourComponent",

  data: () => ({
    dialog: null
  }),

  methods: {
    openDialog() {
      if (this.dialog) {
        this.dialog.show();
      }
    },

    assignDialogRef(dialog) {
      this.dialog = dialog;
    }
  }
};

In your index.html, add a container where your dialog will be rendered into.

<!DOCTYPE html>
<html>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <div id="dialog-root"></div>
  </body>
</html>

It's important to assign the direct reference to the dialog instance via @dialog-ref, otherwise there is no way to call its methods.

Alternatively, you can also import the component directly into your file without installing it first:

import { A11yDialog } from "vue-a11y-dialog";
export default {
  name: "YourComponent",

  components: {
    "a11y-dialog": A11yDialog
  },

  methods: {
    // ...
  }
};

Multiple dialogs

It's possible to use multiple dialogs in the same component, just make sure to assign the different dialog instances separately.

In your <template>:

<template>
  <div id="app">
    <!-- First dialog -->
    <a11y-dialog
      id="first-dialog"
      app-root="#app"
      dialog-root="#dialog-root"
      @dialog-ref="dialog => assignDialogRef('first', dialog)"
    >
      <template v-slot:title>
        <span>First dialog title</span>
      </template>
      <div>
        <p>Your content</p>
      </div>
    </a11y-dialog>

    <!-- Second dialog -->
    <a11y-dialog
      id="second-dialog"
      app-root="#app"
      dialog-root="#dialog-root"
      @dialog-ref="dialog => assignDialogRef('second', dialog)"
    >
      <template v-slot:title>
        <span>Second dialog title</span>
      </template>
      <div>
        <p>Your content</p>
      </div>
    </a11y-dialog>
  </div>
</template>

In your <script>:

import { A11yDialog } from "vue-a11y-dialog";
export default {
  name: "YourComponent",

  data: () => ({
    dialogs: {}
  }),

  methods: {
    assignDialogRef(type, dialog) {
      this.dialogs[type] = dialog;
    }
  }
};

API

All a11y-dialog instance methods are available, see their docs for more.

disable-native

  • Property: disable-native
  • Type: Boolean
  • Default: false
  • Description: Per default we're using the native <dialog> element. However, if you want to disable that and use a <div role="dialog"> instead, you can just do that by adding this attribute. This gives you full control (and responsibilites) over styling. Read the a11y-dialog Styling layer documentation for more information.
  • Usage:
<a11y-dialog disable-native>
  <!-- ... -->
</a11y-dialog>

id

  • Property: id
  • Type: String
  • Required: true
  • Description: The unique HTML id attribute added to the dialog element, internally used by a11y-dialog to manipulate the dialog.
  • Usage:
<a11y-dialog id="main-dialog">
  <!-- ... -->
</a11y-dialog>

app-root

  • Property: app-root
  • Type: String, Array<String> — CSS Selector string.
  • Required: true
  • Description: The selector(s) a11y-dialog needs to disable when the dialog is open.
  • Usage:
<a11y-dialog app-root="#app">
  <!-- ... -->
</a11y-dialog>

dialog-root

  • Property: dialog-root
  • Type: String — CSS Selector string.
  • Required: true
  • Description: The container for the dialog to be rendered into.
  • Usage:
<a11y-dialog dialog-root="#dialog-root">
  <!-- ... -->
</a11y-dialog>

class-names

  • Property: class-names
  • Type: Object
  • Required: false
  • Default: {}
  • Description: Object of classes for each HTML element of the dialog element. Keys are: base, overlay, element, document, title, closeButton. See a11y-dialog docs for reference.
  • Usage:
<a11y-dialog :class-names="{ base: 'base-class', overlay: 'overlay-class' }">
  <!-- ... -->
</a11y-dialog>

title-id

  • Property: title-id
  • Type: String
  • Required: false
  • Default: Defaults to id + '-title'.
  • Description: The HTML id attribute of the dialog’s title element, used by assistive technologies to provide context and meaning to the dialog window.
  • Usage:
<a11y-dialog title-id="main-title">
  <!-- ... -->
</a11y-dialog>

close-button-label

  • Property: close-button-label
  • Type: String
  • Required: false
  • Default: 'Close this dialog window'
  • Description: The HTML aria-label attribute of the close button, used by assistive technologies to provide extra meaning to the usual cross-mark.
  • Usage:
<a11y-dialog close-button-label="Close this super dialog">
  <!-- ... -->
</a11y-dialog>

role

  • Property: role
  • Type: String
  • Required: false
  • Default: dialog
  • Description: The role attribute of the dialog element, either dialog (default) or alertdialog to make it a modal (preventing closing on click outside of ESC key).
  • Usage:
<a11y-dialog role="alertdialog">
  <!-- ... -->
</a11y-dialog>

Events

dialog-ref

  • Returns: An a11y-dialog instance or undefined.
  • Description: This event emits the a11y-dialog instance once the component has been initialised. When it gets destroyed, the event returns undefined. This is needed to call instance methods of the dialog, e.g. this.dialog.show().
  • Usage:
<a11y-dialog @dialog-ref="assignDialogRef">
  <!-- ... -->
</a11y-dialog>
export default {
  // ...
  methods: {
    assignDialogRef(dialog) {
      this.dialog = dialog;
    }
  }
};

Slots

title

  • Name: title
  • Description: The title of the dialog, mandatory in the document to provide context to assistive technology. Could be hidden with CSS (while remaining accessible).
  • Usage:
<a11y-dialog>
  <template v-slot:title>
    <span>Your dialog title</span>
  </template>
  <!-- ... -->
</a11y-dialog>

closeButtonContent

  • Name: closeButtonLabel
  • Default: \u00D7 (×)
  • Description: The string that is the inner HTML of the close button.
  • Usage:
<a11y-dialog>
  <template v-slot:closeButtonContent>
    <span>Close dialog</span>
  </template>
  <!-- ... -->
</a11y-dialog>

Server-side Rendering

This is a client-only component; a11y-dialog won't render anything on the server and wait for your bundle to be executed on the client.

Comments

  • Vue i18n functions not available inside dialog
    Vue i18n functions not available inside dialog

    Jul 22, 2019

    I use this plugin to display a form that use various calls to Vue i18n $t function. It systematically throws the following error:

    TypeError: i18n is undefined
    

    If I move my code outside of the Dialog, it works just fine. I've found related issues here and there about Vue i18n and Portal Vue mounting-portal component (https://github.com/LinusBorg/portal-vue/issues/199, https://github.com/kazupon/vue-i18n/issues/184#issuecomment-483166528) so I decided to try adapting it and see if it works.

    I was surprised to see that just by copying your source A11yDialog component within my project solved the issue. Could it be something in the compiled version that cause this?

    I don't know if you have an idea about what it could be? In any case providing the source component into the npm package would actually be enough for me and avoid having to copy it manually within my project.

    Reply
  • Events emitted when modal is opened and closed
    Events emitted when modal is opened and closed

    Aug 2, 2019

    Thank you for the wrapper, it made my day! I just added a couple (possibly) useful events, fired when the modal is opening/closing and after the show/hide methods have been called on the A11yDialog instance.

    Reply
  • odd issue with dialog root element not existing
    odd issue with dialog root element not existing

    Oct 28, 2019

    my app uses vue-a11y-dialog in a nested component while the #dialog-root is in the main app. i am getting a [portal-vue]: Mount Point '#dialog-root' not found in document error only in circumstances where the dialog component is being rendered straight away. it works if i wait for the component to be created (eg put a v-if="$el" in the dialog component). is this the expected behavior?

    app.vue:

    <template>
      <div id="app">
        <MyDialog v-if="$el" />
        <div id="dialog-root"></div>
      </div>
    </template>
    
    <script>
    import MyDialog from 'components/MyDialog'
    
    export default {
      components: { MyDialog }
    }
    </script>
    

    components/MyDialog.vue:

    <template>
      <div>
        <button type="button" @click="openDialog">
          Show dialog
        </button>
        <a11y-dialog
          id="my-dialog"
          app-root="#app"
          dialog-root="#dialog-root"
          @dialog-ref="assignDialogRef"
        >
        ... more stuff here 
        </a11y-dialog>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return { dialog: null }
      },
      methods: {
        assignDialogRef(dialog) {
          this.dialog = dialog
        },
        openDialog() {
          if (this.dialog) {
            this.dialog.show()
          }
        },
      }
    }
    </script>
    

    in the code above, removing v-if="$el" will produce (error slightly edited):

    [portal-vue]: Mount Point '#dialog-root' not found in document vue-a11y-dialog.js:499
    [portal-vue] Target wasn't mounted vue-a11y-dialog.js:528
    [Vue warn]: Error in nextTick: "TypeError: a is undefined"
    
    found in
    
    ---> <VueA11yDialog>
           <MyDialog> at app/javascript/src/components/MyDialog.vue
               <App> at app/javascript/src/app.vue
                 <Root> vue.runtime.esm.js:640
    TypeError: "a is undefined"
        b vue-a11y-dialog.js:79
        mounted vue-a11y-dialog.js:614
        VueJS 2
    [portal-vue] Target wasn't mounted
    

    in case it is relevant, Vue itself is invoked in JS via:

    import Vue from 'vue'
    import VueA11yDialog from 'vue-a11y-dialog'
    Vue.use(VueA11yDialog)
    
    import App from 'app'
    
    document.addEventListener('DOMContentLoaded', () => {
      const app = new Vue({
        render: (h) => h(App)
      }).$mount()
      document.body.appendChild(app.$el)
    })
    

    right now my app works but it seems odd that i need to wait for $el to be available since i did not see it mentioned anywhere in the docs.

    Reply
  • Version 1.0.0 seems to be broken: a._self in render function is undefined
    Version 1.0.0 seems to be broken: a._self in render function is undefined

    Mar 7, 2021

    See: https://codesandbox.io/s/compassionate-dewdney-nrsxs?file=/src/App.vue (minimal demo)

    Vue: 3.0.7 Vue-A11y-Dialog: 1.0.0

    Which really confuses me, because back when I added PR #25 it was working (otherwise my PR would not have happened).

    Error stack:

    Uncaught TypeError: a._self is undefined
        render vue-a11y-dialog.js:1
        renderComponentRoot runtime-core.esm-bundler.js:732
        componentEffect runtime-core.esm-bundler.js:4225
        reactiveEffect reactivity.esm-bundler.js:42
        effect reactivity.esm-bundler.js:17
        setupRenderEffect runtime-core.esm-bundler.js:4208
        mountComponent runtime-core.esm-bundler.js:4167
        processComponent runtime-core.esm-bundler.js:4127
        patch runtime-core.esm-bundler.js:3745
        mountChildren runtime-core.esm-bundler.js:3927
        processFragment runtime-core.esm-bundler.js:4087
        patch runtime-core.esm-bundler.js:3738
        componentEffect runtime-core.esm-bundler.js:4243
        reactiveEffect reactivity.esm-bundler.js:42
        effect reactivity.esm-bundler.js:17
        setupRenderEffect runtime-core.esm-bundler.js:4208
        mountComponent runtime-core.esm-bundler.js:4167
        processComponent runtime-core.esm-bundler.js:4127
        patch runtime-core.esm-bundler.js:3745
        render runtime-core.esm-bundler.js:4828
        mount runtime-core.esm-bundler.js:3046
        mount runtime-dom.esm-bundler.js:1234
        <anonymous> main.js:5
        js app.js:1159
        __webpack_require__ app.js:849
        fn app.js:151
        1 app.js:1172
        __webpack_require__ app.js:849
        checkDeferredModules app.js:46
        <anonymous> app.js:925
        <anonymous> app.js:928
    

    On top of that, my local setup seems to be broken somehow. I've been fighting with Cannot find module 'eslint-plugin-import' when trying to debug this problem with npm link locally

    Reply
  • Migrate to version 7 of a11y-dialog
    Migrate to version 7 of a11y-dialog

    Apr 29, 2021

    Version 7 is out and based on the changelog, adds some fundamental improvement regarding the fallback to the native dialog element (by removing it).

    (btw. the README currently mentions that the vue wrapper is based on version 5 of the a11y-dialog but seems the code uses v6 already)

    Reply
  • Add an event that fires on close
    Add an event that fires on close

    Jul 1, 2021

    Instead of only firing an event when the dialog is created it would be great to be able to watch for an event when the user hides the dialog. As in by adding @hide on the component, not by having to add an event listener on the dialog object.

    Reply
  • added `emits` prop to support Vue 3 syntax
    added `emits` prop to support Vue 3 syntax

    Nov 30, 2021

    prevents warnings from being reported in the console

    Reply
  • Release 1.1.0
    Release 1.1.0

    Jan 24, 2022

    null

                                                                                                                                                                                                           
    Reply
  • 1.1.0 build issue from esm
    1.1.0 build issue from esm

    Jan 24, 2022

    I'm having trouble building 1.1.0 and consuming from AgnosticUI's agnostic-vue package. Let me provide some context…

    To test the 1.1.0 PR I did as mentioned here: https://github.com/morkro/vue-a11y-dialog/pull/31#issuecomment-1013066815

    For posterity this was that tester's package.json:

    {
      "name": "package_test",
      "version": "0.0.0",
      "scripts": {
        "dev": "vite",
        "build": "vite build",
        "preview": "vite preview"
      },
      "dependencies": {
        "vue": "^3.2.25",
        "vue-a11y-dialog": "file:../vue-a11y-dialog-v1.1.0.tgz"
      },
      "devDependencies": {
        "@vitejs/plugin-vue": "^2.0.0",
        "vite": "^2.7.2"
      }
    }
    

    This works fine.

    However, I've tried to consume my PR's topic branch late last night and ran into an issue which appears to be some sort of UMD inside an ESM env issue.

    I'm going to try to experiment with the vite.config.js build setup and package.json pointers as well. Something must be off.

    Here's errors as both image and text for posterity…

    image

    This is caused by consumer doing: import { Vue3A11yDialog } from "vue-a11y-dialog";

    yarn dev
    
    changed 1 package, and audited 38 packages in 961ms
    
    3 packages are looking for funding
      run `npm fund` for details
    
    1 moderate severity vulnerability
    
    To address all issues, run:
      npm audit fix
    
    Run `npm audit` for details.
    yarn run v1.22.17
    warning package.json: No license field
    $ vite
    Pre-bundling dependencies:
      vue
      agnostic-vue
    (this will be run only when your dependencies or config have changed)
     > node_modules/agnostic-vue/dist/agnostic-vue.esm.js:1:7: error: No matching export in "node_modules/vue/dist/vue.runtime.esm-bundler.js" for import "default"
        1 │ import require$$0, { openBlock, createElementBlock, normalizeClass, rend...
          ╵        ~~~~~~~~~~
    
    error when starting dev server:
    Error: Build failed with 1 error:
    node_modules/agnostic-vue/dist/agnostic-vue.esm.js:1:7: error: No matching export in "node_modules/vue/dist/vue.runtime.esm-bundler.js" for import "default"
        at failureErrorWithLog (/Users/roblevin/workspace/opensource/agnosticui/agnostic-vue/examples/node_modules/esbuild/lib/main.js:1493:15)
        at /Users/roblevin/workspace/opensource/agnosticui/agnostic-vue/examples/node_modules/esbuild/lib/main.js:1151:28
        at runOnEndCallbacks (/Users/roblevin/workspace/opensource/agnosticui/agnostic-vue/examples/node_modules/esbuild/lib/main.js:941:63)
        at buildResponseToResult (/Users/roblevin/workspace/opensource/agnosticui/agnostic-vue/examples/node_modules/esbuild/lib/main.js:1149:7)
        at /Users/roblevin/workspace/opensource/agnosticui/agnostic-vue/examples/node_modules/esbuild/lib/main.js:1258:14
        at /Users/roblevin/workspace/opensource/agnosticui/agnostic-vue/examples/node_modules/esbuild/lib/main.js:629:9
        at handleIncomingPacket (/Users/roblevin/workspace/opensource/agnosticui/agnostic-vue/examples/node_modules/esbuild/lib/main.js:726:9)
        at Socket.readFromStdout (/Users/roblevin/workspace/opensource/agnosticui/agnostic-vue/examples/node_modules/esbuild/lib/main.js:596:7)
        at Socket.emit (node:events:390:28)
        at addChunk (node:internal/streams/readable:315:12)
    error Command failed with exit code 1.
    
    Reply
  • Vue 3 version with fixed Cypress Spec and Other Updates
    Vue 3 version with fixed Cypress Spec and Other Updates

    Jan 24, 2022

    @morkro I'm pointing this towards main

    Because pointing towards current 1.1.0 has a bunch of conflicts. Maybe there's a way for you to cut a new temp topic branch off of main?

    Tests:

    npm run test:ci (headless ... omit :ci to run in browser fwiw):

    image

    Tester app (in /package_test which I've just went ahead and checked in to the repository because it's so helpful in verifying npm builds):

    image

    How to run:

    npm run build && npm pack # from top-level
    

    and then install this tarball from the package_test directory with:

    npm i <GENERATED.tgz> # from previous npm pack step -- this installs tarball which pretty faithfully replicates an npm install
    npm run dev
    
    Reply
  • ⬆️ Bump ini from 1.3.5 to 1.3.7
    ⬆️ Bump ini from 1.3.5 to 1.3.7

    Dec 10, 2020

    Bumps ini from 1.3.5 to 1.3.7.

    Commits
    • c74c8af 1.3.7
    • 024b8b5 update deps, add linting
    • 032fbaf Use Object.create(null) to avoid default object property hazards
    • 2da9039 1.3.6
    • cfea636 better git push script, before publish instead of after
    • 56d2805 do not allow invalid hazardous string as section name
    • See full diff in compare view
    Maintainer changes

    This version was pushed to npm by isaacs, a new releaser for ini since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    Reply
  • ⬆️ Bump js-yaml from 3.12.0 to 3.13.1
    ⬆️ Bump js-yaml from 3.12.0 to 3.13.1

    Jun 5, 2019

    Bumps js-yaml from 3.12.0 to 3.13.1.

    Changelog

    Sourced from js-yaml's changelog.

    3.13.1 / 2019-04-05

    • Fix possible code execution in (already unsafe) .load(), #480.

    3.13.0 / 2019-03-20

    • Security fix: safeLoad() can hang when arrays with nested refs used as key. Now throws exception for nested arrays. #475.

    3.12.2 / 2019-02-26

    • Fix noArrayIndent option for root level, #468.

    3.12.1 / 2019-01-05

    • Added noArrayIndent option, #432.
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot ignore this [patch|minor|major] version will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language
    dependencies 
    Reply
  • aria-labelledby is missed if titleId property is not specified
    aria-labelledby is missed if titleId property is not specified

    Apr 13, 2020

    It seems that You missed to define checked fullTitleIdid to the aria-labelledby attribute.

    Reply
  • Dialog title implementation and README example mismatched
    Dialog title implementation and README example mismatched

    Jan 11, 2019

    Hi Moritz! Thanks for this excellent implementation — really works well.

    The current example in the README suggests the following use inside <a11y-dialog>:

    <h1 slot="title">Your dialog title</h1>
    

    But this will actually render:

    <h1>
      <h1>
        Your dialog title
      </h1>
    <h1>
    

    Because the title slot is defined as an <h1> element already:

    https://github.com/morkro/vue-a11y-dialog/blob/6005d7ffd5cc9d075d26d90c000f7d653c464de7/src/A11yDialog.vue#L26-L28

    I can imagine that an <h1> tag is a semantically good idea inside the dialog, in which case perhaps it should be enforced and the README example changed (e.g. to <span slot="title">).

    On the other hand, given that a title isn’t required by the dialog, perhaps it would be better to give users more flexibility? For example, <header> could be used for the slot, which would usually bring less style defaults with it, while still maintaining decent semantics.

    Reply
  • remarks on implementation
    remarks on implementation

    Feb 7, 2019

    1. You shouldn't be using a function to display your dialog, rather use a v-if which is less verbose and more optimized : your way of implementating will result in the dialog being rendered and inserted to the dom wether or not it's shown, killing the entire benefit of Vue's vdom diffing logic. On a side effect, it will probably make it harder to implement custom transitions also, since "appear/disappear" cycles won't be triggered. A simple way to fix this would be to remove some logic and using v-if on the consumer side instead of using your own flow.

    2. A span for title is arguable, but it's very neat that you made it a <slot /> so it's consumer's discretion to choose what to use.

    3. In case you want to have a more granular separation of concern, you may want to leave the discretion of insertion point to the consumer of your component - meaning that the portal should not be included inside your component ; a dialog is a dialog, the way to use it, the place to insert it can depend on each project. That last point is very debattable since it could be also an explicit implementation constraint but it seems to be that the benefit of embedding portal is not a lot compared to the modularity brought by leaving this choice to your end user.

    An ideal implementation should be :

    <template>
      <div id="app">
        <!-- ... -->
        <button type="button" @click="dialog = true">
          Open dialog
        </button>
    
        <portal to="the-dialog-place">
          <a11y-dialog ref="dialog" v-if="dialog">
            <span slot="title">Your dialog title</span>
            <div>
              <p>Your content</p>
            </div>
          </a11y-dialog>
        </portal>
      </div>
    </template>
    
    <script>
    export default {
      name: 'YourComponent',
    
      data: () => ({
        dialog: false
      }),
    }
    </script>
    
    Reply
  • Vue 3 version of vue-a11y-dialog
    Vue 3 version of vue-a11y-dialog

    Jan 11, 2022

    See https://github.com/morkro/vue-a11y-dialog/issues/28 for discussion

    I've placed as a draft for now to prevent accidental merge. I believe the following should be done first before this is ready:

    • [x] Bump version to 1.1.0
    • [x] Incorporate linting
    • [x] Prune some unused files e.g. Cypress boilerplates
    • [x] Regenerate builds one last time
    • [x] Verify build locally. I can yarn build && yarn pack and then install this tarball e.g. npm i generatedtarball.tgz and verify.

    I think the actually publishing to npm and what not should/would be handled by maintainer once the proper release is done upstream in morko's repo. Maybe this goes without saying 😃

    Reply
  • vue-a11y-dialog not working in MS Edge
    vue-a11y-dialog not working in MS Edge

    Sep 28, 2018

    I note the demo referenced in this document -> https://codesandbox.io/s/rj20wr1kpp is not working as expected in MS Edge (see attached screenshot). Noticed the error after failing to implement the component, and tried to see weather the demo in this project worked as expected. It does not, however seem to be a problem with the package a11y-dialog itself, and I currently don´t have the answer why this is failing. Therefor opening an issue instead of a PR here. I´ll be happy to contribute, btw.

    skjermbilde 2018-09-28 kl 11 11 45

    Reply
  • API documentation: app-root=
    API documentation: app-root="#app" may not be the best example

    Dec 5, 2018

    In the project's readme, there is a example of the app-root prop and an explanation of what it does:

    <a11y-dialog app-root="#app">
      <!-- ... -->
    </a11y-dialog>
    
    Description: The selector(s) a11y-dialog needs to disable when the dialog is open.
    

    The problem is that, once you apply aria-hidden=true to <div id="app" />, everything inside it will be removed from the accessibility tree, including the modal itself. You can see this behaviour in your official demo: https://rj20wr1kpp.codesandbox.io/

    As WAI ARIA Authoring Practices, Modal Dialogs, state (see green note box, lower part):

    aria-hidden is set to true on each element containing a portion of the inert layer. ... The dialog element is not a descendant of any element that has aria-hidden set to true.

    Therefore, at least the readme should be changed. If possible you should rename app-root to its actual function, maybe render-inert.

    I wrote a blog post on how to use your component differently (circa last third of the article): https://marcus.io/blog/a11y-app-dialogs-modals

    But nevertheless, thanks for your handy wrapper of a11y-dialog!

    Reply
  • issue rendering two dialogs on the same page.
    issue rendering two dialogs on the same page.

    Jan 23, 2019

    Thanks for the wrapper, i'm fan of the original plugin, and will be of this wrapper for sure :)

    This sounds like a dumb question (and probably is), but i want to render [2..n] dialogs in one page. For demo purposes i went with 2, and currently it's only rendering the last one. For the first i'm getting the following error for the first :

    DOMException: Failed to execute 'showModal' on 'HTMLDialogElement': The element is not in a Document.
    

    Demo link

    My suspicions go to the portal-target. Since we're using the "html" version of it i suspect we don't get the multiple option that comes with the component version <portal-target multiple>, but i might be wrong, so I wanted to get your input on this.

    Thanks for your time! ✋

    known; fix incoming 
    Reply
  • Update to Vue3: Using new plugin install, teleport, removing portal
    Update to Vue3: Using new plugin install, teleport, removing portal

    Oct 24, 2020

    Hi,

    this PR makes vue-a11y-dialog compatible with Vue 3 by:

    • Using its new syntax for installing plugins
    • Using Vue3's native teleport instead of vue-portal (which hence won't get an update for Vue3)
    • Adapting the tests to my knowledge, namely
      • stubbing teleport
      • Removing wrapper.vm.$destroy call in the test, since this method call got removed in Vue3 https://v3.vuejs.org/guide/migration/introduction.html#removed-apis

    Also updates to [email protected]

    Reply