Skip to content

Commit

Permalink
[new feature] Stepper: support long press gesture (#3711)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan committed Jul 1, 2019
1 parent e4ce613 commit 3d0c6ae
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 15 deletions.
71 changes: 57 additions & 14 deletions src/stepper/index.js
Expand Up @@ -2,6 +2,9 @@ import { createNamespace, isDef, suffixPx } from '../utils';

const [createComponent, bem] = createNamespace('stepper');

const LONG_PRESS_START_TIME = 600;
const LONG_PRESS_INTERVAL = 200;

export default createComponent({
props: {
value: null,
Expand Down Expand Up @@ -78,19 +81,21 @@ export default createComponent({
const { value } = event.target;
const formatted = this.format(value);

if (!this.asyncChange) {
if (this.asyncChange) {
event.target.value = this.currentValue;
this.$emit('input', formatted);
this.$emit('change', formatted);
} else {
if (+value !== formatted) {
event.target.value = formatted;
}
this.currentValue = formatted;
} else {
event.target.value = this.currentValue;
this.$emit('input', formatted);
this.$emit('change', formatted);
}
},

onChange(type) {
onChange() {
const { type } = this;

if (this[`${type}Disabled`]) {
this.$emit('overlimit', type);
return;
Expand All @@ -99,12 +104,13 @@ export default createComponent({
const diff = type === 'minus' ? -this.step : +this.step;
const value = Math.round((this.currentValue + diff) * 100) / 100;

if (!this.asyncChange) {
this.currentValue = this.range(value);
} else {
if (this.asyncChange) {
this.$emit('input', value);
this.$emit('change', value);
} else {
this.currentValue = this.range(value);
}

this.$emit(type);
},

Expand All @@ -120,19 +126,56 @@ export default createComponent({
if (this.currentValue === 0) {
event.target.value = this.currentValue;
}
},

longPressStep() {
this.longPressTimer = setTimeout(() => {
this.onChange(this.type);
this.longPressStep(this.type);
}, LONG_PRESS_INTERVAL);
},

onTouchStart(type) {
clearTimeout(this.longPressTimer);
this.isLongPress = false;

this.longPressTimer = setTimeout(() => {
this.isLongPress = true;
this.onChange();
this.longPressStep();
}, LONG_PRESS_START_TIME);
},

onTouchEnd(event) {
clearTimeout(this.longPressTimer);

if (this.isLongPress) {
event.preventDefault();
}
}
},

render(h) {
const onChange = type => () => {
this.onChange(type);
};
const createListeners = type => ({
on: {
click: () => {
this.type = type;
this.onChange();
},
touchstart: () => {
this.type = type;
this.onTouchStart(type);
},
touchend: this.onTouchEnd,
touchcancel: this.onTouchEnd
}
});

return (
<div class={bem()}>
<button
class={bem('minus', { disabled: this.minusDisabled })}
onClick={onChange('minus')}
{...createListeners('minus')}
/>
<input
type="number"
Expand All @@ -150,7 +193,7 @@ export default createComponent({
/>
<button
class={bem('plus', { disabled: this.plusDisabled })}
onClick={onChange('plus')}
{...createListeners('plus')}
/>
</div>
);
Expand Down
61 changes: 60 additions & 1 deletion src/stepper/test/index.spec.js
@@ -1,5 +1,5 @@
import Stepper from '..';
import { mount } from '../../../test/utils';
import { mount, later } from '../../../test/utils';

test('disabled stepper', () => {
const wrapper = mount(Stepper, {
Expand Down Expand Up @@ -39,6 +39,27 @@ test('click button', () => {
expect(wrapper.emitted('overlimit')).toEqual([['plus'], ['minus']]);
});

test('long press', async () => {
const wrapper = mount(Stepper, {
propsData: {
value: 1
}
});

const plus = wrapper.find('.van-stepper__plus');

plus.trigger('touchstart');
plus.trigger('touchend');
plus.trigger('click');

expect(wrapper.emitted('input')[0][0]).toEqual(2);

plus.trigger('touchstart');
await later(1000);
plus.trigger('touchend');
expect(wrapper.emitted('input')).toEqual([[2], [3], [4]]);
});

test('correct value when value is not correct', () => {
const wrapper = mount(Stepper, {
propsData: {
Expand Down Expand Up @@ -117,3 +138,41 @@ test('input width', () => {
});
expect(wrapper).toMatchSnapshot();
});

test('async change', () => {
const wrapper = mount(Stepper, {
propsData: {
value: 1,
asyncChange: true
}
});

const plus = wrapper.find('.van-stepper__plus');
plus.trigger('click');

expect(wrapper.emitted('input')[0][0]).toEqual(2);
expect(wrapper.emitted('change')[0][0]).toEqual(2);

const input = wrapper.find('input');
input.element.value = '3';
input.trigger('input');

expect(wrapper.emitted('input')[1][0]).toEqual(3);
expect(wrapper.emitted('change')[1][0]).toEqual(3);
});

test('min value is 0', () => {
const wrapper = mount(Stepper, {
propsData: {
value: 1,
min: 0
}
});

const input = wrapper.find('input');
input.element.value = '';
input.trigger('input');
input.trigger('blur');

expect(wrapper.emitted('input')[0][0]).toEqual(0);
});

0 comments on commit 3d0c6ae

Please sign in to comment.