Skip to content

Commit 4b51082

Browse files
first commit
0 parents  commit 4b51082

18 files changed

+6829
-0
lines changed

.browserslistrc

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
> 1%
2+
last 2 versions

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.DS_Store
2+
node_modules
3+
dist/*
4+
demo/demo*

.prettierrc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"semi": false,
3+
"singleQuote": true,
4+
"trailingComma": "es5"
5+
}

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Andrew Vasilchuk <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+215
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# vue-accessible-modal
2+
3+
> Vue.js component for accessible modals.
4+
5+
## ✨ Features
6+
7+
- 📟 fully accessible to screen readers;
8+
- ⌨️ supports keyboard navigation;
9+
- 🎯 focus trap;
10+
- restores focus when modal is closed;
11+
- simple API.
12+
13+
## Demo
14+
15+
[![Edit vue-accessible-modal](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/vue-accessible-modal-9m474?fontsize=14)
16+
17+
## 💿 Installation
18+
19+
### Via NPM
20+
21+
```bash
22+
npm install vue-accessible-modal --save
23+
```
24+
25+
### Via Yarn
26+
27+
```bash
28+
yarn add vue-accessible-modal
29+
```
30+
31+
## Initialization
32+
33+
### As a plugin
34+
35+
It must be called before `new Vue()`.
36+
37+
```javascript
38+
import Vue from 'vue'
39+
import VueAccessibleModal from 'vue-accessible-modal'
40+
41+
Vue.use(VueAccessibleModal)
42+
```
43+
44+
## 🚀 Usage
45+
46+
### Template
47+
48+
First off you should insert the `<vue-accessible-modal />` component into your `template`:
49+
50+
```html
51+
<template>
52+
<vue-accessible-modal />
53+
</template>
54+
```
55+
56+
### 🎨 Styles
57+
58+
Then don't forget to include core styles:
59+
60+
`SASS`:
61+
62+
```scss
63+
@import 'vue-accessible-modal/src/styles/core.scss';
64+
```
65+
66+
Or already compiled `CSS`:
67+
68+
`CSS`:
69+
70+
```scss
71+
@import 'vue-accessible-modal/dist/index.css';
72+
```
73+
74+
> ⚠️ Note that when you import already compiled CSS you don't have ability to override `SASS` variables during build process, so it preferable to use`.scss` file. But you still have ability to override default styles and change CSS custom properties during runtime.
75+
76+
There are `SASS` variables you can override during build process:
77+
78+
```scss
79+
$v-modal-holder-padding: 32px !default;
80+
$v-modal-backdrop-color: rgba(#333, 0.88) !default;
81+
$v-modal-content-background-color: #fff !default;
82+
```
83+
84+
And [`CSS` custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) you can override during runtime:
85+
86+
```scss
87+
:root {
88+
--v-modal-holder-padding: #{$v-modal-holder-padding};
89+
--v-modal-backdrop-color: #{$v-modal-backdrop-color};
90+
--v-modal-content-background-color: #{$v-modal-content-background-color};
91+
}
92+
```
93+
94+
### API
95+
96+
> 🌈 The main purpose of the library is just to give you a simple wrapper over your modal components that makes them accessible and provide you with simple **show**/**close** API over them.
97+
98+
When you install the plugin it provides `$modal` property into the `Vue.prototype`, so you can **show** or **close** modals through `this.$modal.show()` or `this.$modal.close()` methods appropriately.
99+
100+
> ⚠️ Note that your modal component should contain at least one focusable element to set focus on. There should be at least one button that closes the dialog `<button @click="$modal.close()">Close dialog</button>`.
101+
102+
`$modal.show(component: VueComponent, options: object)` method accepts two arguments:
103+
104+
1. `component`: Vue.js component you want to display in the modal.
105+
2. `options`: object through which you can customize the behaviour of the modal.
106+
107+
`options` object can contain the following properties:
108+
109+
| Property | Description |
110+
| ------------ | ------------------------------------------------------------------------------------------------- |
111+
| `props` | `props` that will be passed to provided component via `v-bind="props"` |
112+
| `listeners` | an object with listeners to listen to events emitted from passed component via `v-on="listeners"` |
113+
| `classes` | custom classes that will be applied to the modal |
114+
| `label` | value of `aria-label` attribute |
115+
| `attributes` | any attribute you want to bind to the modal |
116+
| `transition` | `name` of the transition that will be passed to `transition` component |
117+
118+
> ℹ️ Note that through `options.attributes` you can bind any HTML attribute to a modal.
119+
> For example if you want to bind `aria-labelledby` or `aria-describedby`, you can do the following:
120+
121+
```js
122+
{
123+
props: { },
124+
listeners: { },
125+
attributes: {
126+
id: 'foo',
127+
'aria-labelledby': 'foo',
128+
'aria-describedby': 'bar',
129+
},
130+
}
131+
```
132+
133+
To close modal from any place you should use `this.$modal.close()` method.
134+
135+
### ⬆ Emitted events
136+
137+
`<vue-accessible-modal>` component emits some events you can subscribe to:
138+
139+
| Event | Description |
140+
| ------- | ----------------------------------------- |
141+
| `show` | Emitted when a modal is completely shown |
142+
| `close` | Emitted when a modal is completely closed |
143+
144+
#### Example of subscribing to events
145+
146+
```html
147+
<template>
148+
<vue-accessible-modal
149+
@show="showHandler"
150+
@close="closeHandler"
151+
></vue-accessible-modal>
152+
</template>
153+
```
154+
155+
### Example of possible usage of the library
156+
157+
```js
158+
import YourAwesomeComponent from './YorAwesomeComponent.vue'
159+
160+
export default {
161+
// ...
162+
methods: {
163+
submitHandler(e) {
164+
console.log(e)
165+
},
166+
showModal() {
167+
this.$modal.show(YourAwesomeComponent, {
168+
props: { foo: 'bar' },
169+
listeners: { submit: this.submitHandler },
170+
classes: ['foo', 'bar'],
171+
label: 'My awesome modal',
172+
attributes: {
173+
id: 'modal',
174+
'data-attribute': 'foo',
175+
},
176+
transition: 'fade',
177+
})
178+
},
179+
},
180+
// ...
181+
}
182+
```
183+
184+
> ℹ️ Note that your modal component can contain property named `modal`, which value will be applied to the modal component:
185+
186+
```js
187+
export default {
188+
name: 'YourAwesomeComponent',
189+
data() {
190+
return {}
191+
},
192+
modal: {
193+
classes: ['foo', { bar: true }],
194+
label: 'foo',
195+
attributes: {
196+
id: 'baz',
197+
},
198+
transition: 'foo',
199+
},
200+
}
201+
```
202+
203+
This gives you a convenient way of providing custom `transition`, `classes` and `attributes` per modal component.
204+
205+
> ⚠️ Notice that values provided via `options` object will take precedence over values provided via component's `modal` property.
206+
207+
## Powered by
208+
209+
- `Vue.js`;
210+
- `Rollup` (and plugins);
211+
- `SASS`.
212+
213+
## 🔒 License
214+
215+
[MIT](http://opensource.org/licenses/MIT)

build/rollup.config.dev.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import path from 'path'
2+
import common from 'rollup-plugin-commonjs'
3+
import serve from 'rollup-plugin-serve'
4+
import livereload from 'rollup-plugin-livereload'
5+
import vue from 'rollup-plugin-vue'
6+
import resolve from 'rollup-plugin-node-resolve'
7+
import replace from 'rollup-plugin-replace'
8+
9+
export default {
10+
input: path.join(__dirname, '..', 'demo', 'index.js'),
11+
output: {
12+
file: path.join(__dirname, '..', 'demo', 'demo.js'),
13+
format: 'iife',
14+
name: 'demo',
15+
sourcemap: true,
16+
},
17+
plugins: [
18+
common(),
19+
// demo crashes on changes https://github.com/vuejs/rollup-plugin-vue/issues/238
20+
vue({ needMap: false }),
21+
replace({
22+
'process.env.NODE_ENV': JSON.stringify('development'),
23+
}),
24+
resolve(),
25+
serve({
26+
open: true,
27+
contentBase: path.join(__dirname, '..', 'demo'),
28+
port: 8080,
29+
}),
30+
livereload({
31+
verbose: true,
32+
watch: path.join(__dirname, '..', 'demo'),
33+
}),
34+
],
35+
}

build/rollup.config.prod.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import path from 'path'
2+
import vue from 'rollup-plugin-vue'
3+
import { terser } from 'rollup-plugin-terser'
4+
import replace from 'rollup-plugin-replace'
5+
import resolve from 'rollup-plugin-node-resolve'
6+
import common from 'rollup-plugin-commonjs'
7+
8+
const name = 'VueAccessibleModal'
9+
const plugins = [
10+
replace({
11+
'process.env.NODE_ENV': JSON.stringify('production'),
12+
}),
13+
resolve(),
14+
common(),
15+
vue(),
16+
terser(),
17+
]
18+
19+
export default [
20+
{
21+
input: path.join(__dirname, '..', 'src', 'index.js'),
22+
output: [
23+
{
24+
file: 'dist/vue-accessible-modal.js',
25+
format: 'umd',
26+
name,
27+
},
28+
{
29+
file: 'dist/vue-accessible-modal.common.js',
30+
format: 'cjs',
31+
},
32+
{
33+
file: 'dist/vue-accessible-modal.esm.js',
34+
format: 'esm',
35+
},
36+
],
37+
plugins,
38+
},
39+
{
40+
input: path.join(__dirname, '..', 'src', 'index.js'),
41+
output: {
42+
file: 'dist/vue-accessible-modal.min.js',
43+
format: 'umd',
44+
name,
45+
},
46+
plugins,
47+
},
48+
]

0 commit comments

Comments
 (0)