diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index a8bc1c8..d019ce9 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -38,6 +38,7 @@ module.exports = { '/guide/', '/guide/announcer.md', '/guide/announcer-router.md', + '/guide/plugins.md', '/guide/accessibility.md', '/guide/support.md', ] diff --git a/docs/guide/plugins.md b/docs/guide/plugins.md new file mode 100644 index 0000000..a0e7ce4 --- /dev/null +++ b/docs/guide/plugins.md @@ -0,0 +1,49 @@ +--- + +announcer: Announcer plugins page has loaded + +--- + +# Plugins + +Plugin is an interesting resource for you to create different ways to use the announcer and adapt to a specific problem in your app. + + +```javascript +// e.g. plugins/announcer/myPlugin.js +export default { + name: 'myPlugin', + handler () { + console.log('myPlugin') + } +} +``` + +::: warning +The handler function takes `$announcer` as a context (this), so you can use `this.assertive('my text')` +::: + +```javascript +// src/main.js +import Vue from 'vue' +import VueAnnouncer from '@vue-a11y/announcer' + +import myPlugin from '@plugins/announcer/myPlugin' + +Vue.use(VueAnnouncer, { + plugins: [myPlugin] +}) +``` + +```javascript +// e.g. component.vue +export default { + name: 'myComponent' + + methods: { + test () { + this.$announcer.plugins.myPlugin() + } + } +} +``` \ No newline at end of file diff --git a/index.d.ts b/index.d.ts index f6c3f8f..23e30b8 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,11 +1,16 @@ import { PluginFunction } from 'vue'; -export interface Announcer -{ +export interface AnnouncerPlugins { + name: string, + handler: any +} +export interface Announcer { data: Record; options: Record; + plugins?: AnnouncerPlugins[]; + set(message: string, politeness: string): void; polite(message: string): void; @@ -15,18 +20,17 @@ export interface Announcer reset(): void; setComplementRoute(complementRoute: string): void; + } -declare module 'vue/types/vue' -{ +declare module 'vue/types/vue' { interface Vue { $announcer: Announcer; } } -declare class VueAnnouncer -{ +declare class VueAnnouncer { static install: PluginFunction; } diff --git a/src/index.js b/src/index.js index 2426055..06899c0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,8 @@ import VueAnnouncer from './vue-announcer.vue' import { draf, defaultOptions } from './utils' +const announcerPlugins = {} + export default function install (Vue, options = {}, router = null) { if (install.installed) return install.installed = true @@ -38,12 +40,21 @@ export default function install (Vue, options = {}, router = null) { this.data.politeness = this.options.politeness }, + plugins: announcerPlugins, + setComplementRoute (complementRoute) { if (typeof complementRoute !== 'string') return options.complementRoute = complementRoute } } + // Register plugins + if (options.plugins.length) { + options.plugins.forEach(({ name, handler }) => { + announcerPlugins[name] = handler.bind(Vue.prototype.$announcer) + }) + } + // If set the router, will be announced the change of route if (router) { router.afterEach(to => { diff --git a/src/plugins/spell.js b/src/plugins/spell.js new file mode 100644 index 0000000..a8b19e5 --- /dev/null +++ b/src/plugins/spell.js @@ -0,0 +1,6 @@ +export default { + name: 'spell', + handler (pass) { + if (pass) pass.split('').forEach((char, index) => setTimeout(() => this.polite(char), index * 100)) + } +} diff --git a/src/utils.js b/src/utils.js index 78d4073..89a6c95 100644 --- a/src/utils.js +++ b/src/utils.js @@ -2,5 +2,6 @@ export const draf = (cb) => requestAnimationFrame(() => requestAnimationFrame(cb export const defaultOptions = { politeness: 'polite', - complementRoute: 'has loaded' + complementRoute: 'has loaded', + plugins: [] }