Skip to content

Commit

Permalink
Merge pull request #734 from ShachiniMekala/lan-spinner-issue
Browse files Browse the repository at this point in the history
LAN - goal weights number component issue fix
  • Loading branch information
amilaw authored Aug 26, 2023
2 parents 4e8cbb3 + e9b0ece commit 0df12ae
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 91 deletions.
94 changes: 52 additions & 42 deletions components/src/core/components/Input/Number/Number.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ export default defineComponent({
}),
},
modelValue: {
type: Number as PropType<number | undefined>,
},
defaultValue: {
type: Number as PropType<number | undefined>,
type: String,
default: '',
},
disabled: {
type: Boolean,
Expand All @@ -35,10 +33,6 @@ export default defineComponent({
type: Boolean,
default: false,
},
requiredDefaultValue: {
type: Boolean,
default: false,
},
min: {
type: Number as PropType<number>,
default: 0,
Expand All @@ -50,7 +44,7 @@ export default defineComponent({
},
setup(props, {emit}) {
const focused = ref(false);
const number = ref<number | null | undefined>(props.modelValue);
const number = ref<number | string | undefined>(props.modelValue);
const outerClasses = computed((): object => {
return {
'oxd-number-input-wrapper d-flex justify-between align-center': true,
Expand All @@ -60,6 +54,25 @@ export default defineComponent({
'input-outer--error': props.hasError,
};
});
const getValidatedValue = (value: string) => {
if (props.min < 0) {
let matchingNumber = value.match(/^[-]?[0-9]*(?:\.[0-9]+)?/);
return matchingNumber ? matchingNumber[0] : '';
}
let matchingNumber = value.match(/^[0-9]*(?:\.[0-9]+)?/);
return matchingNumber ? matchingNumber[0] : '';
};
const getModifiedValue = (value: number) => {
var modifiedValue = value;
if (props.min > value) {
modifiedValue = props.min;
}
if (props.max < value) {
modifiedValue = props.max;
}
return modifiedValue;
};
watch(
() => props.modelValue,
value => {
Expand All @@ -80,11 +93,19 @@ export default defineComponent({
class: 'number-min-btn',
disabled: props.disabled || props.readonly,
onClick: () => {
if (!(number.value === undefined || number.value === null)) {
if (number.value <= props.min) return true;
number.value--;
if (
!(
number.value === undefined ||
number.value === null ||
number.value === ''
)
) {
number.value = Number(number.value);
if (!Number.isNaN(number.value)) {
number.value = getModifiedValue(number.value + 1);
}
} else {
number.value = 0;
number.value = props.min;
}
emit('update:modelValue', number.value);
},
Expand All @@ -93,11 +114,8 @@ export default defineComponent({
id: props.id,
disabled: props.disabled,
readonly: props.readonly,
type: 'number',
class: 'oxd-number-input',
value: number.value,
min: props.min,
max: props.max,
onFocus: ($event: Event) => {
focused.value = true;
emit('focus', $event);
Expand All @@ -106,28 +124,12 @@ export default defineComponent({
focused.value = false;
emit('blur', $event);
},
onKeyup: ($event: any) => {
const value:
| number
| string
| null = ($event.target as HTMLInputElement).value;
if (value) {
number.value = Number(value);
if (!(number.value === undefined || number.value === null)) {
if (number.value <= props.min) {
number.value = props.defaultValue || 0;
}
if (number.value >= props.max) {
number.value = props.defaultValue || 0;
}
}
} else {
if (props.requiredDefaultValue) {
number.value = props.defaultValue;
} else {
number.value = null;
}
}
onInput: ($event: any) => {
const value: string = getValidatedValue(
($event.target as HTMLInputElement).value,
);
($event.target as HTMLInputElement).value = value;
number.value = value;
emit('update:modelValue', number.value);
},
}),
Expand All @@ -137,11 +139,19 @@ export default defineComponent({
class: 'number-max-btn',
disabled: props.disabled || props.readonly,
onClick: () => {
if (number.value) {
if (number.value >= props.max) return true;
number.value++;
if (
!(
number.value === undefined ||
number.value === null ||
number.value === ''
)
) {
number.value = Number(number.value);
if (!Number.isNaN(number.value)) {
number.value = getModifiedValue(number.value + 1);
}
} else {
number.value = 1;
number.value = props.min;
}
emit('update:modelValue', number.value);
},
Expand Down
2 changes: 1 addition & 1 deletion components/src/core/components/Input/Number/number.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
border-radius: 33px;
padding: 4px;
min-height: 24px;
input[type='number'] {
input {
box-sizing: border-box;
outline: none;
border: none;
Expand Down
77 changes: 73 additions & 4 deletions components/src/core/components/Input/__tests__/number.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,82 @@ describe('Number.vue', () => {
await nextTick();
expect(wrapper.vm.modelValue).toBe(1);
});
it('required true with a default value', () => {

it('type invalid value', async () => {
const wrapper = mount(Number, {
props: {
max: 10,
},
});

const inputElement = wrapper.find('input');
(inputElement.element as HTMLInputElement).value = 'abcd';
inputElement.trigger('input');
expect((inputElement.element as HTMLInputElement).value).toBe('');
});

it('type valid positive', async () => {
const wrapper = mount(Number, {
props: {
max: 10,
},
});

const inputElement = wrapper.find('input');
(inputElement.element as HTMLInputElement).value = '11';
inputElement.trigger('input');
expect((inputElement.element as HTMLInputElement).value).toBe('11');
});

it('type valid value with invalid part', async () => {
const wrapper = mount(Number, {
props: {
max: 10,
},
});

const inputElement = wrapper.find('input');
(inputElement.element as HTMLInputElement).value = '100+';
inputElement.trigger('input');
expect((inputElement.element as HTMLInputElement).value).toBe('100');
});

it('type negative', async () => {
const wrapper = mount(Number, {
props: {
requiredWithDefaultValue: true,
defaultValue: 5,
max: 10,
},
});
expect(wrapper.vm.defaultValue).toBe(5);

const inputElement = wrapper.find('input');
(inputElement.element as HTMLInputElement).value = '-10';
inputElement.trigger('input');
expect((inputElement.element as HTMLInputElement).value).toBe('');
});

it('type negative valid', async () => {
const wrapper = mount(Number, {
props: {
max: 10,
min: -5,
},
});

const inputElement = wrapper.find('input');
(inputElement.element as HTMLInputElement).value = '-10';
inputElement.trigger('input');
expect((inputElement.element as HTMLInputElement).value).toBe('-10');
});

it('type minus number within range', async () => {
const wrapper = mount(Number, {
props: {
max: 10,
min: -5,
modelValue: -2,
},
});

expect(wrapper.vm.modelValue).toBe(-2);
});
});
44 changes: 1 addition & 43 deletions storybook/stories/core/components/Input/Number.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default {
},
modelValue: {
control: {type: 'number'},
defaultValue: 1,
defaultValue: "",
table: {
type: {summary: 'Set value to the Number element'},
},
Expand Down Expand Up @@ -52,24 +52,6 @@ export default {
},
},
},
requiredDefaultValue: {
control: {type: 'boolean'},
defaultValue: false,
table: {
type: {
summary: 'Set the required with default value state',
},
},
},
defaultValue: {
control: {type: 'number'},
table: {
type: {
summary: 'Set a default value when cleared the model value',
},
},
defaultValue: 5,
},
id: {
control: {type: 'text'},
table: {
Expand Down Expand Up @@ -138,30 +120,6 @@ Default.parameters = {
},
};

export const RequiredWithDefaultValue = Template.bind({});
RequiredWithDefaultValue.args = {
style: {
'max-width': '100px',
},
requiredDefaultValue: true,
defaultValue: 5,
};

RequiredWithDefaultValue.parameters = {
docs: {
source: {
code: `
<oxd-number-input
id="oxd-number-input-1"
:style="{'max-width': '100px'}"
:requiredDefaultValue="true"
:defaultValue="1"
/>
`,
},
},
};

export const Disabled = Template.bind({});
Disabled.args = {
disabled: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,11 +444,15 @@ Advance.args = {
style: {
'max-width': '100px',
},
props: {
min: -4,
max: 5
},
listeners: {
'onUpdate:modelValue': (value) => {
weight.value = value;
},
},
}
},
{
name: 'certificate',
Expand Down

0 comments on commit 0df12ae

Please sign in to comment.