Skip to content
This repository was archived by the owner on Dec 26, 2018. It is now read-only.

Commit 49b5e91

Browse files
committed
Merge branch 'feature/options_prop' into develop
2 parents 7295d5d + 04832df commit 49b5e91

35 files changed

+18185
-222
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
node_modules
22
.DS_Store
33
example/example.build.js
4+
example/vendor.build.js
5+
example/*.map
6+
npm-debug.log

README.md

Lines changed: 165 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,155 @@
11
# vue-touch
22

33
> Touch events plugin for Vue.js
4+
> this is a BETA Release
45
5-
This is a directive wrapper for Hammer.js 2.0.
6+
This is a component wrapper for Hammer.js 2.0.
67

78
## Install
89

9-
#### CommonJS
10+
> This plugin requires Vue >= 2.0. For the Vue 1.\*-compatible version, see the `1.0` branch
1011
11-
- Available through npm as `vue-touch`.
1212

13-
``` js
14-
var VueTouch = require('vue-touch')
15-
Vue.use(VueTouch)
16-
```
13+
### npm
14+
15+
Available through npm as `vue-touch`. As this version is currently in BETA, you have to install with the `next` tag.
16+
17+
```bash
18+
npm install vue-touch@next
19+
```
20+
21+
```Javascript
22+
var VueTouch = require('vue-touch')
23+
Vue.use(VueTouch, {name: 'v-touch'})
24+
```
25+
You can pass an options object as the second argument, which at the moment accepts one property, `name`. It's used to define the name of the component that is registered with Vue and defaults to `'v-touch'`.
1726

1827
#### Direct include
1928

20-
- You can also directly include it with a `<script>` tag when you have Vue and Hammer.js already included globally. It will automatically install itself, and will add a global `VueTouch`.
29+
You can also directly include it with a `<script>` tag when you have Vue and Hammer.js already included globally. It will automatically install itself, and will add a global `VueTouch`.
2130

2231
## Usage
2332

24-
#### Using the `v-touch` directive
33+
Using the `<v-touch>` component
2534

2635
``` html
27-
<a v-touch:tap="onTap">Tap me!</a>
36+
<!-- Renders a div element by default -->
37+
<v-touch v-on:swipeleft="onSwipeLeft">Swipe me!</v-touch>
38+
39+
<!-- Render as other elements with the 'tag' prop -->
40+
<v-touch tag="a" v-on:tap="onTap">Tap me!</v-touch>
41+
```
42+
43+
## API
44+
45+
### Component Events
46+
47+
vue-touch supports all Hammer Events ot of the box, just bind a listener to the component with `v-on` and vue-touch will setup the Hammer Manager & Recognizer for you.
48+
49+
|Recognizer|Events|Example|
50+
|---|----|----|----|
51+
|**Pan**|`pan`, `panstart`, `panmove`, `panend`, `pancancel`, `panleft`, `panright`, `panup`, `pandown` |`v-on:panstart="callback"`|
52+
|**Pinch**|`pinch`, `pinchstart`, `pinchmove`,`pinchend`, `pinchcancel`, `pinchin`, `pinchout`| `v-on:pinchout="callback"`|
53+
|**Press**|`press`, `pressup`|`v-on:pressup="callback"`|
54+
|**Rotate**|`rotate`, `rotatestart`, `rotatemove`, `rotateend`, `rotatecancel`, |`v-on:rotateend="callback"`|
55+
|**Swipe**|`swipe`, `swipeleft`, `swiperight`, `swipeup`, `swipedown`|`v-on:swipeleft="callback"`|
56+
|**Tap**|`tap`|`v-on:tap="callback"`|
57+
58+
### Component Props
59+
60+
61+
#### Event Option Props
62+
63+
You can use the matching `*-options` props to pass Hammer options such as `direction` and `threshold`:
64+
65+
``` html
66+
<!-- detect only horizontal pans with a threshold of 100 -->
67+
<v-touch
68+
v-on:panstart="onPanStart"
69+
v-bind:pan-options="{ direction: 'horizontal', threshold: 100 }">
70+
</v-touch>
71+
```
72+
There's one prop per `Recognizer` available.
73+
74+
|Recognizer|Prop|
75+
|----------|----|
76+
|**Pan**|`v-bind:pan-options`|
77+
|**Pinch**|`v-bind:pinch-options`|
78+
|**Rotate**|`v-bind:rotate-options`|
79+
|**Swipe**|`v-bind:swipe-options`|
80+
|**Tap**|`v-bind:tap-options`|
81+
82+
See [Hammer.js documentation](http://hammerjs.github.io/getting-started/) for all available options for events.
83+
84+
**About Directions:**
85+
86+
In the above example, not that we used `direction: 'horizontal'`. Hammer's directions interface is a little ugly (Hammer['DIRECTION_HORIZONTAL']).
87+
88+
VueTouch keeps that from you and accepts simple strings as directions:
89+
90+
```javascript
91+
const directions = ['up', 'down', 'left', 'right', 'horizontal', 'vertical', 'all']
92+
```
93+
94+
#### The 'enabled' Prop
95+
96+
|Prop|allowed Values|
97+
|----|--------------|
98+
|enabled| Boolean or Object (see below)|
99+
100+
You can enable and disable all or some of the event recognizers via the `enabled` prop:
28101

29-
<div v-touch:swipeleft="onSwipeLeft">Swipe me!</div>
30102
```
103+
<v-touch
104+
<!-- enable all recognizers -->
105+
v-bind:enabled="true"
31106
32-
#### Configuring Recognizer Options
107+
<!-- disable all recognizers -->
108+
v-bind:enabled="false"
33109
34-
There are two ways to customize recognizer options such as `direction` and `threshold`. The first one is setting global options:
110+
<!-- pass an object to enable and disable recognizers individually -->
111+
v-bind:enabled="{ pinch: true, rotate: false }"
112+
113+
></v-touch>
114+
```
115+
116+
117+
### Public Component Methods
118+
119+
The component exposes a few convenience methods to enable and disable Recognizers, and check if a recognizer is enabled:
120+
121+
|Method|Explanation|
122+
|------|-----------|
123+
|`disable(event)`|disable event's recognizer|
124+
|`enable(event)`|disable event's recognizer|
125+
|`toggle(event)`|Toogle the 'enable' state of event's recognizer|
126+
|`disableAll()`|disable all Recognizers|
127+
|`enableAll()`|enable all Recognizers|
128+
|`isEnabled(event)`|returns `true` if Recognizer for `event` is currently enabled|
129+
130+
```html
131+
<template>
132+
<v-touch ref="tapper" @tap="callback"></v-touch>
133+
</template>
134+
<script>
135+
export default {
136+
methods: {
137+
disableTap() {
138+
this.$refs.tapper.disable('tap')
139+
},
140+
enableTap() {
141+
this.$refs.tapper.enable('tap')
142+
}
143+
}
144+
}
145+
</script>
146+
```
147+
148+
### Plugin Methods
149+
150+
#### Global Event Options
151+
152+
You can define global defaults for the builtin recognizers
35153

36154
``` js
37155
// change the threshold for all swipe recognizers
@@ -40,18 +158,10 @@ VueTouch.config.swipe = {
40158
}
41159
```
42160

43-
Or, you can use the `v-touch-options` directive to configure the behavior on a specific element:
44-
45-
``` html
46-
<!-- detect only horizontal pans with a threshold of 100 -->
47-
<a
48-
v-touch:pan="onPan"
49-
v-touch-options:pan="{ direction: 'horizontal', threshold: 100 }">
50-
</a>
51-
```
52-
53161
#### Registering Custom Events
54162

163+
You can register custom events with vue-touch.
164+
55165
``` js
56166
// example registering a custom doubletap event.
57167
// the `type` indicates the base recognizer to use from Hammer
@@ -61,14 +171,43 @@ VueTouch.registerCustomEvent('doubletap', {
61171
taps: 2
62172
})
63173
```
174+
> **Warning**: You have to register your custom events *before* installing the plugin with `Vue.use(VueTouch)`.
175+
VueTouch will log a warning to the console (in dev mode) if you try to do that afterwards, and the event will not work.
176+
177+
This will make it possible to listen for this event on `<v-touch>`. Additionally, just like for "normal" events, you can pass further options as the corresponding prop.
178+
64179
``` html
65-
<a v-touch:doubletap="onDoubleTap"></a>
180+
<v-touch v-on:doubletap="onDoubleTap"></v-touch>
181+
<!-- with local options -->
182+
<v-touch v-on:doubletap="onDoubleTap" v-bind:doubletap-options="{intervall: 250}"></v-touch>
66183
```
67184

68-
See [Hammer.js documentation](http://hammerjs.github.io/getting-started/) for all available events.
69-
70185
See `/example` for a multi-event demo. To build it, run `npm install && npm run build`.
71186

187+
## Server-Side Rendering (SSR)
188+
189+
As of the moment of this writing, requiring HammerJS in a non-browser-environment (like during the build process of your SSR bundle) throws an error ([hammerjs/hammerjs#1060](https://github.com/hammerjs/hammer.js/issues/1060)).
190+
191+
The easiest fix to that is to use a webpack alias to replace the hammerjs package with a module that just exports a stub, i.e. an empty object. vue-touch comes with such a module, called `hammer-ssr.js`
192+
```JavaScript
193+
alias: {
194+
'hammerjs$': 'vue-touch/dist/hammer-ssr.js'
195+
}
196+
```
197+
198+
Once this issue has been resolved HammerJS, this alias is no longer nessessary and can be removed.
199+
200+
The `<v-touch>` component itself will never try to setup any Hamer Manangers or Recognizers if it detects that it is running in an SSR environment (seeVue.js API docs for [vm.$isServer](https://vuejs.org/v2/api/#vm-isServer)). The component will only render a normal `<div>` element (or whatever element you defined with the `tag` prop).
201+
202+
## Known Limitations & Bugs
203+
204+
* Curently, changing `-options` props will not change recogizer settings. The initial values will stay in place until the component is re-created.
205+
206+
## TODO
207+
208+
* [ ] Support updating recognizer options when props change.
209+
* [ ] Find out if e2e tests are possible(contribution welcome)
210+
72211
## License
73212

74213
[MIT](http://opensource.org/licenses/MIT)

build/devserver.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var webpack = require('webpack')
2+
var DevServer = require('webpack-dev-server')
3+
var config = require('./webpack.config.dev.js')
4+
config.entry.example.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");
5+
var compiler = webpack(config)
6+
var server = new DevServer(compiler, {
7+
contentBase: './example/',
8+
clientLogLevel: 'warning',
9+
hot: true,
10+
stats: {
11+
chunks: false,
12+
colors: true
13+
}
14+
})
15+
16+
server.listen(8080)
17+
18+
module.exports = server

build/rollup.config.prod.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import buble from 'rollup-plugin-buble'
2+
import commonjs from 'rollup-plugin-commonjs'
3+
import nodeResolve from 'rollup-plugin-node-resolve'
4+
import cleanup from 'rollup-plugin-cleanup'
5+
6+
export default {
7+
entry: './src/index.js',
8+
dest: './dist/vue-touch.js',
9+
// Module settings
10+
format: 'umd',
11+
external: ['hammerjs'],
12+
globals: {
13+
hammerjs: 'Hammer'
14+
},
15+
moduleName: 'VueTouch',
16+
17+
plugins: [
18+
buble(),
19+
nodeResolve({ jsnext: true, main: true }),
20+
commonjs(),
21+
cleanup()
22+
]
23+
}

build/webpack.config.dev.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
var path = require('path')
2+
var webpack = require('webpack')
3+
4+
const config = {
5+
entry: {
6+
example: ['./example/example.js'],
7+
vendor: ['vue', 'hammerjs'],
8+
},
9+
output: {
10+
path: path.resolve(__dirname, "../example"),
11+
publicPath: '/',
12+
library: 'VueTouch',
13+
libraryTarget: 'umd',
14+
filename: '[name].build.js'
15+
},
16+
resolve: {
17+
alias: {
18+
'vue$': 'vue/dist/vue.common'
19+
}
20+
},
21+
module: {
22+
rules: [
23+
{
24+
test: /\.js$/,
25+
loader: 'buble-loader',
26+
exclude: path.resolve(__dirname, "../node_modules")
27+
},
28+
{
29+
test: /\.css$/,
30+
loader: 'style-loader!css-loader',
31+
exclude: path.resolve(__dirname, "../node_modules")
32+
}
33+
]
34+
},
35+
plugins: [
36+
new webpack.HotModuleReplacementPlugin(),
37+
new webpack.DefinePlugin({
38+
'process.env': {
39+
NODE_ENV: process.env.NODE_ENV ? JSON.stringify(process.env.NODE_ENV) : "'development'"
40+
}
41+
}),
42+
new webpack.optimize.CommonsChunkPlugin({
43+
name: 'vendor'
44+
})
45+
],
46+
devtool: 'source-map',
47+
performance: {
48+
hints: false
49+
},
50+
/*devServer: {
51+
contentBase: '/example/'
52+
}*/
53+
}
54+
55+
module.exports = config

dist/hammer-ssr.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default class Hammer {
2+
contructor() {
3+
console.log(`[vue-touch] Your should never see this message.
4+
When you do, your code tried to call 'new Hammer(), but your app has included a stub for HammerJS, provided by vue-touch, instead of the actual HammerJS library.
5+
`)
6+
}
7+
}

0 commit comments

Comments
 (0)