commit a5252e2e8b65d8611e7b9f706a356ec532fe160c
parent ee74b3c9cd1bb4c43a21c861c57fb5103635be7e
Author: ashermorgan <59518073+ashermorgan@users.noreply.github.com>
Date: Mon, 23 Aug 2021 13:41:19 -0700
Add step & wrap props in IntInput and DecimalInput
Diffstat:
5 files changed, 237 insertions(+), 25 deletions(-)
diff --git a/src/components/DecimalInput.vue b/src/components/DecimalInput.vue
@@ -37,6 +37,22 @@ export default {
},
/**
+ * The step value
+ */
+ step: {
+ type: Number,
+ default: 1,
+ },
+
+ /**
+ * Whether to wrap around at the minimum and maximum values
+ */
+ wrap: {
+ type: Boolean,
+ default: false,
+ },
+
+ /**
* The number of digits to show before the decimal point
*/
padding: {
@@ -168,10 +184,18 @@ export default {
*/
onkeydown(e) {
if (e.key === 'ArrowUp') {
- this.decValue += 1;
+ if (this.decValue === this.max && this.wrap && this.min !== null) {
+ this.decValue = this.min;
+ } else {
+ this.decValue += this.step;
+ }
e.preventDefault();
} else if (e.key === 'ArrowDown') {
- this.decValue -= 1;
+ if (this.decValue === this.min && this.wrap && this.max !== null) {
+ this.decValue = this.max;
+ } else {
+ this.decValue -= this.step;
+ }
e.preventDefault();
}
},
diff --git a/src/components/IntInput.vue b/src/components/IntInput.vue
@@ -37,6 +37,22 @@ export default {
},
/**
+ * The step value
+ */
+ step: {
+ type: Number,
+ default: 1,
+ },
+
+ /**
+ * Whether to wrap around at the minimum and maximum values
+ */
+ wrap: {
+ type: Boolean,
+ default: false,
+ },
+
+ /**
* The number of digits to show before the decimal point
*/
padding: {
@@ -157,10 +173,18 @@ export default {
*/
onkeydown(e) {
if (e.key === 'ArrowUp') {
- this.intValue += 1;
+ if (this.intValue === this.max && this.wrap && this.min !== null) {
+ this.intValue = this.min;
+ } else {
+ this.intValue += this.step;
+ }
e.preventDefault();
} else if (e.key === 'ArrowDown') {
- this.intValue -= 1;
+ if (this.intValue === this.min && this.wrap && this.max !== null) {
+ this.intValue = this.max;
+ } else {
+ this.intValue -= this.step;
+ }
e.preventDefault();
}
},
diff --git a/src/components/TimeInput.vue b/src/components/TimeInput.vue
@@ -1,13 +1,13 @@
<template>
<div class="time-input">
<int-input class="hours" aria-label="hours"
- :min="0" :max="23" :padding="1" v-model="hours"/>
+ :min="0" :max="99" :padding="1" v-model="hours"/>
<span>:</span>
<int-input class="minutes" aria-label="minutes"
- :min="0" :max="59" :padding="2" v-model="minutes"/>
+ :min="0" :max="59" wrap :padding="2" v-model="minutes"/>
<span>:</span>
<decimal-input class="seconds" aria-label="seconds"
- :min="0" :max="59.99" :padding="2" :digits="2" v-model="seconds"/>
+ :min="0" :max="59.99" wrap :padding="2" :digits="2" v-model="seconds"/>
</div>
</template>
diff --git a/tests/unit/components/DecimalInput.spec.js b/tests/unit/components/DecimalInput.spec.js
@@ -21,28 +21,32 @@ describe('components/DecimalInput.vue', () => {
expect(wrapper.find('input').element.value).to.equal('1.0');
});
- it('up arrow should increment value', async () => {
+ it('up arrow should increment value by step', async () => {
// Initialize component
- const wrapper = mount(DecimalInput);
+ const wrapper = mount(DecimalInput, {
+ propsData: { step: 0.2 },
+ });
// Press up arrow
await wrapper.trigger('keydown', { key: 'ArrowUp' });
- // Assert value is 1.0 and input event was emitted
- expect(wrapper.find('input').element.value).to.equal('1.0');
- expect(wrapper.emitted().input).to.deep.equal([[1.0]]);
+ // Assert value is 0.2 and input event was emitted
+ expect(wrapper.find('input').element.value).to.equal('0.2');
+ expect(wrapper.emitted().input).to.deep.equal([[0.2]]);
});
- it('down arrow should increment value', async () => {
+ it('down arrow should increment value by step', async () => {
// Initialize component
- const wrapper = mount(DecimalInput);
+ const wrapper = mount(DecimalInput, {
+ propsData: { step: 0.2 },
+ });
// Press down arrow
await wrapper.trigger('keydown', { key: 'ArrowDown' });
- // Assert value is -1.0 and input event was emitted
- expect(wrapper.find('input').element.value).to.equal('-1.0');
- expect(wrapper.emitted().input).to.deep.equal([[-1.0]]);
+ // Assert value is -0.2 and input event was emitted
+ expect(wrapper.find('input').element.value).to.equal('-0.2');
+ expect(wrapper.emitted().input).to.deep.equal([[-0.2]]);
});
it('should fire input event when value changes', async () => {
@@ -248,6 +252,84 @@ describe('components/DecimalInput.vue', () => {
expect(wrapper.emitted().input).to.deep.equal([[10.0]]);
});
+ it('should not wrap to the maximum if it is null', async () => {
+ // Initialize component
+ const wrapper = mount(DecimalInput, {
+ propsData: {
+ min: -1.0, max: null, value: -1.0, step: 0.2, wrap: true,
+ },
+ });
+
+ // Try to decrement value
+ await wrapper.trigger('keydown', { key: 'ArrowDown' });
+
+ // Assert value is still -1.0 and no events were emitted
+ expect(wrapper.find('input').element.value).to.equal('-1.0');
+ expect(wrapper.emitted().input).to.equal(undefined);
+ });
+
+ it('should not wrap to the minimum if it is null', async () => {
+ // Initialize component
+ const wrapper = mount(DecimalInput, {
+ propsData: {
+ min: null, max: 1.0, value: 1.0, step: 0.2, wrap: true,
+ },
+ });
+
+ // Try to increment value
+ await wrapper.trigger('keydown', { key: 'ArrowUp' });
+
+ // Assert value is still 1.0 and no events were emitted
+ expect(wrapper.find('input').element.value).to.equal('1.0');
+ expect(wrapper.emitted().input).to.equal(undefined);
+ });
+
+ it('should correctly wrap from the minimum to maximum', async () => {
+ // Initialize component
+ const wrapper = mount(DecimalInput, {
+ propsData: {
+ min: -1.0, max: 1.0, value: -0.9, step: 0.2, wrap: true,
+ },
+ });
+
+ // Decrement value
+ await wrapper.trigger('keydown', { key: 'ArrowDown' });
+
+ // Assert value is -1.0 and input event was emitted
+ expect(wrapper.find('input').element.value).to.equal('-1.0');
+ expect(wrapper.emitted().input).to.deep.equal([[-1.0]]);
+
+ // Decrement value
+ await wrapper.trigger('keydown', { key: 'ArrowDown' });
+
+ // Assert value is 1.0 and input event was emitted
+ expect(wrapper.find('input').element.value).to.equal('1.0');
+ expect(wrapper.emitted().input).to.deep.equal([[-1.0], [1.0]]);
+ });
+
+ it('should correctly wrap from the maximum to minimum', async () => {
+ // Initialize component
+ const wrapper = mount(DecimalInput, {
+ propsData: {
+ min: -1.0, max: 1.0, value: 0.9, step: 0.2, wrap: true,
+ },
+ });
+
+ // Increment value
+ await wrapper.trigger('keydown', { key: 'ArrowUp' });
+
+ // Assert value is 1.0 and input event was emitted
+ expect(wrapper.find('input').element.value).to.equal('1.0');
+ expect(wrapper.emitted().input).to.deep.equal([[1.0]]);
+
+ // Increment value
+ await wrapper.trigger('keydown', { key: 'ArrowUp' });
+
+ // Assert value is -1.0 and input event was emitted
+ expect(wrapper.find('input').element.value).to.equal('-1.0');
+ expect(wrapper.emitted().input).to.deep.equal([[1.0], [-1.0]]);
+ });
+
it('should format value according to padding and digits props', async () => {
// Initialize component
const wrapper = mount(DecimalInput, {
diff --git a/tests/unit/components/IntInput.spec.js b/tests/unit/components/IntInput.spec.js
@@ -21,28 +21,32 @@ describe('components/IntInput.vue', () => {
expect(wrapper.find('input').element.value).to.equal('1');
});
- it('up arrow should increment value', async () => {
+ it('up arrow should increment value by step', async () => {
// Initialize component
- const wrapper = mount(IntInput);
+ const wrapper = mount(IntInput, {
+ propsData: { step: 2 },
+ });
// Press up arrow
await wrapper.trigger('keydown', { key: 'ArrowUp' });
// Assert value is 1 and input event was emitted
- expect(wrapper.find('input').element.value).to.equal('1');
- expect(wrapper.emitted().input).to.deep.equal([[1]]);
+ expect(wrapper.find('input').element.value).to.equal('2');
+ expect(wrapper.emitted().input).to.deep.equal([[2]]);
});
- it('down arrow should increment value', async () => {
+ it('down arrow should increment value by step', async () => {
// Initialize component
- const wrapper = mount(IntInput);
+ const wrapper = mount(IntInput, {
+ propsData: { step: 2 },
+ });
// Press down arrow
await wrapper.trigger('keydown', { key: 'ArrowDown' });
// Assert value is -1 and input event was emitted
- expect(wrapper.find('input').element.value).to.equal('-1');
- expect(wrapper.emitted().input).to.deep.equal([[-1]]);
+ expect(wrapper.find('input').element.value).to.equal('-2');
+ expect(wrapper.emitted().input).to.deep.equal([[-2]]);
});
it('should fire input event when value changes', async () => {
@@ -226,6 +230,84 @@ describe('components/IntInput.vue', () => {
expect(wrapper.emitted().input).to.deep.equal([[10]]);
});
+ it('should not wrap to the maximum if it is null', async () => {
+ // Initialize component
+ const wrapper = mount(IntInput, {
+ propsData: {
+ min: -10, max: null, value: -10, step: 2, wrap: true,
+ },
+ });
+
+ // Try to decrement value
+ await wrapper.trigger('keydown', { key: 'ArrowDown' });
+
+ // Assert value is still -10 and no events were emitted
+ expect(wrapper.find('input').element.value).to.equal('-10');
+ expect(wrapper.emitted().input).to.equal(undefined);
+ });
+
+ it('should not wrap to the minimum if it is null', async () => {
+ // Initialize component
+ const wrapper = mount(IntInput, {
+ propsData: {
+ min: null, max: 10, value: 10, step: 2, wrap: true,
+ },
+ });
+
+ // Try to increment value
+ await wrapper.trigger('keydown', { key: 'ArrowUp' });
+
+ // Assert value is still 10 and no events were emitted
+ expect(wrapper.find('input').element.value).to.equal('10');
+ expect(wrapper.emitted().input).to.equal(undefined);
+ });
+
+ it('should correctly wrap from the minimum to maximum', async () => {
+ // Initialize component
+ const wrapper = mount(IntInput, {
+ propsData: {
+ min: -10, max: 10, value: -9, step: 2, wrap: true,
+ },
+ });
+
+ // Decrement value
+ await wrapper.trigger('keydown', { key: 'ArrowDown' });
+
+ // Assert value is -10 and input event was emitted
+ expect(wrapper.find('input').element.value).to.equal('-10');
+ expect(wrapper.emitted().input).to.deep.equal([[-10]]);
+
+ // Decrement value
+ await wrapper.trigger('keydown', { key: 'ArrowDown' });
+
+ // Assert value is 10 and input event was emitted
+ expect(wrapper.find('input').element.value).to.equal('10');
+ expect(wrapper.emitted().input).to.deep.equal([[-10], [10]]);
+ });
+
+ it('should correctly wrap from the maximum to minimum', async () => {
+ // Initialize component
+ const wrapper = mount(IntInput, {
+ propsData: {
+ min: -10, max: 10, value: 9, step: 2, wrap: true,
+ },
+ });
+
+ // Increment value
+ await wrapper.trigger('keydown', { key: 'ArrowUp' });
+
+ // Assert value is 10 and input event was emitted
+ expect(wrapper.find('input').element.value).to.equal('10');
+ expect(wrapper.emitted().input).to.deep.equal([[10]]);
+
+ // Increment value
+ await wrapper.trigger('keydown', { key: 'ArrowUp' });
+
+ // Assert value is -10 and input event was emitted
+ expect(wrapper.find('input').element.value).to.equal('-10');
+ expect(wrapper.emitted().input).to.deep.equal([[10], [-10]]);
+ });
+
it('should format value according to padding prop', async () => {
// Initialize component
const wrapper = mount(IntInput, {