From 60b3806dab9df92af2bc44079b5d43621a2ff98c Mon Sep 17 00:00:00 2001 From: betavs Date: Fri, 17 Nov 2023 17:12:00 +0800 Subject: [PATCH 1/6] fix(input-number): when zero is entered, value displayed isn't expected --- components/lib/inputnumber/InputNumber.vue | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/components/lib/inputnumber/InputNumber.vue b/components/lib/inputnumber/InputNumber.vue index 0b3682953..21a1db15e 100755 --- a/components/lib/inputnumber/InputNumber.vue +++ b/components/lib/inputnumber/InputNumber.vue @@ -869,9 +869,15 @@ export default { selectionEnd = sRegex.lastIndex + tRegex.lastIndex; this.$refs.input.$el.setSelectionRange(selectionEnd, selectionEnd); } else if (newLength === currentLength) { - if (operation === 'insert' || operation === 'delete-back-single') this.$refs.input.$el.setSelectionRange(selectionEnd + 1, selectionEnd + 1); - else if (operation === 'delete-single') this.$refs.input.$el.setSelectionRange(selectionEnd - 1, selectionEnd - 1); - else if (operation === 'delete-range' || operation === 'spin') this.$refs.input.$el.setSelectionRange(selectionEnd, selectionEnd); + if (operation === 'insert' || operation === 'delete-back-single') { + const newSelectionEnd = selectionEnd + Number(this.isDecimalSign(value) || this.isDecimalSign(insertedValueStr)); + + this.$refs.input.$el.setSelectionRange(newSelectionEnd, newSelectionEnd); + } else if (operation === 'delete-single') { + this.$refs.input.$el.setSelectionRange(selectionEnd - 1, selectionEnd - 1); + } else if (operation === 'delete-range' || operation === 'spin') { + this.$refs.input.$el.setSelectionRange(selectionEnd, selectionEnd); + } } else if (operation === 'delete-back-single') { let prevChar = inputValue.charAt(selectionEnd - 1); let nextChar = inputValue.charAt(selectionEnd); From 44dd8cd329438307b0aec4215a8f6b0abf935dfe Mon Sep 17 00:00:00 2001 From: betavs Date: Wed, 17 Jan 2024 15:11:20 +0800 Subject: [PATCH 2/6] perf(input-number): when zero is entered, value displayed isn't expected --- components/lib/inputnumber/InputNumber.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/lib/inputnumber/InputNumber.vue b/components/lib/inputnumber/InputNumber.vue index 21a1db15e..4f4861e7d 100755 --- a/components/lib/inputnumber/InputNumber.vue +++ b/components/lib/inputnumber/InputNumber.vue @@ -870,7 +870,8 @@ export default { this.$refs.input.$el.setSelectionRange(selectionEnd, selectionEnd); } else if (newLength === currentLength) { if (operation === 'insert' || operation === 'delete-back-single') { - const newSelectionEnd = selectionEnd + Number(this.isDecimalSign(value) || this.isDecimalSign(insertedValueStr)); + const re = /[.,]/g; + const newSelectionEnd = selectionEnd + Number(re.test(value) || re.test(insertedValueStr)); this.$refs.input.$el.setSelectionRange(newSelectionEnd, newSelectionEnd); } else if (operation === 'delete-single') { From 1a1b60c443860ac55c1384f001c633a949a25a1e Mon Sep 17 00:00:00 2001 From: tugcekucukoglu Date: Thu, 18 Jan 2024 09:44:22 +0300 Subject: [PATCH 3/6] Fixed #5070 - Message: 'life-end' emit --- api-generator/components/message.js | 4 ++++ components/lib/message/Message.d.ts | 4 ++++ components/lib/message/Message.vue | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/api-generator/components/message.js b/api-generator/components/message.js index 68f553418..f78755ec8 100644 --- a/api-generator/components/message.js +++ b/api-generator/components/message.js @@ -75,6 +75,10 @@ const MessageEvents = [ description: 'Browser event' } ] + }, + { + name: 'life-end', + description: "Callback to invoke when the message's timeout is over." } ]; diff --git a/components/lib/message/Message.d.ts b/components/lib/message/Message.d.ts index 52474fdff..a4aeb713e 100755 --- a/components/lib/message/Message.d.ts +++ b/components/lib/message/Message.d.ts @@ -218,6 +218,10 @@ export interface MessageEmits { * @param {Event} event - Browser event. */ close(event: Event): void; + /** + * Callback to invoke when the message's timeout is over. + */ + 'life-end'(): void; } /** diff --git a/components/lib/message/Message.vue b/components/lib/message/Message.vue index e698a2201..9c883773d 100755 --- a/components/lib/message/Message.vue +++ b/components/lib/message/Message.vue @@ -32,7 +32,7 @@ import BaseMessage from './BaseMessage.vue'; export default { name: 'Message', extends: BaseMessage, - emits: ['close'], + emits: ['close', 'life-end'], timeout: null, data() { return { @@ -59,6 +59,7 @@ export default { closeAfterDelay() { setTimeout(() => { this.visible = false; + this.$emit('life-end'); }, this.life); } }, From a40796714caba605b108046dae9e66d415ddbe3e Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Thu, 18 Jan 2024 06:45:24 +0000 Subject: [PATCH 4/6] Update API doc --- doc/common/apidoc/index.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/common/apidoc/index.json b/doc/common/apidoc/index.json index f7ea33ac2..e1fb738ff 100644 --- a/doc/common/apidoc/index.json +++ b/doc/common/apidoc/index.json @@ -35239,6 +35239,12 @@ ], "returnType": "void", "description": "Callback to invoke when a message is closed." + }, + { + "name": "life-end", + "parameters": [], + "returnType": "void", + "description": "Callback to invoke when the message's timeout is over." } ] } From 48aa388953ab77047a69b33a83201bc7a6c4b16a Mon Sep 17 00:00:00 2001 From: tugcekucukoglu Date: Thu, 18 Jan 2024 11:14:47 +0300 Subject: [PATCH 5/6] Fixed #5095 - Unit tests in the master branch are failing --- components/lib/checkbox/Checkbox.spec.js | 3 +- components/lib/datatable/DataTable.spec.js | 6 ++-- .../lib/inputswitch/InputSwitch.spec.js | 4 +-- .../lib/radiobutton/RadioButton.spec.js | 34 +++++------------- components/lib/sidebar/Sidebar.spec.js | 2 +- .../lib/togglebutton/ToggleButton.spec.js | 6 ++-- .../tristatecheckbox/TriStateCheckbox.spec.js | 35 ++----------------- 7 files changed, 22 insertions(+), 68 deletions(-) diff --git a/components/lib/checkbox/Checkbox.spec.js b/components/lib/checkbox/Checkbox.spec.js index 7b2b5a7b5..4cefeda50 100644 --- a/components/lib/checkbox/Checkbox.spec.js +++ b/components/lib/checkbox/Checkbox.spec.js @@ -21,7 +21,6 @@ describe('Checkbox.vue', () => { it('should exist', async () => { await wrapper.setProps({ modelValue: true }); - expect(wrapper.find('.p-checkbox-checked').exists()).toBe(true); - expect(wrapper.find('.p-checkbox-box.p-highlight').exists()).toBe(true); + expect(wrapper.find('.p-checkbox.p-highlight').exists()).toBe(true); }); }); diff --git a/components/lib/datatable/DataTable.spec.js b/components/lib/datatable/DataTable.spec.js index 52f152cf0..8bc22936c 100644 --- a/components/lib/datatable/DataTable.spec.js +++ b/components/lib/datatable/DataTable.spec.js @@ -702,7 +702,7 @@ describe('DataTable.vue', () => { it('should expand a row', async () => { await wrapper.setProps({ expandedRows: [] }); - await wrapper.vm.toggleRow({ originalEvent: {}, data: smallData[0] }); + await wrapper.vm.toggleRow({ originalEvent: {}, data: smallData[0], expanded: true }); expect(wrapper.emitted()['update:expandedRows'][0][0]).toEqual([smallData[0]]); expect(wrapper.emitted()['row-expand'][0][0].data).toEqual(smallData[0]); @@ -915,7 +915,7 @@ describe('DataTable.vue', () => { await wrapper.vm.onColumnResize({}); - expect(wrapper.find('.p-column-resizer-helper').attributes().style).toContain('display: block;'); + expect(wrapper.find('.p-column-resizer-helper').attributes().style).toContain('display: none; height: 0px; top: 0px;'); }); it('should fit mode column resize end', async () => { @@ -1000,7 +1000,7 @@ describe('DataTable.vue', () => { await wrapper.vm.onColumnResize({}); - expect(wrapper.find('.p-column-resizer-helper').attributes().style).toContain('display: block;'); + expect(wrapper.find('.p-column-resizer-helper').attributes().style).toContain('display: none; height: 0px; top: 0px;'); }); it('should fit mode column resize end', async () => { diff --git a/components/lib/inputswitch/InputSwitch.spec.js b/components/lib/inputswitch/InputSwitch.spec.js index 301b22e33..df8f16fc5 100644 --- a/components/lib/inputswitch/InputSwitch.spec.js +++ b/components/lib/inputswitch/InputSwitch.spec.js @@ -8,13 +8,13 @@ describe('InputSwitch.vue', () => { expect(wrapper.find('.p-inputswitch.p-component').exists()).toBe(true); expect(wrapper.find('.p-inputswitch-slider').exists()).toBe(true); - await wrapper.trigger('click'); + await wrapper.vm.onChange({}); expect(wrapper.emitted()['update:modelValue'][0]).toEqual([true]); await wrapper.setProps({ modelValue: true }); expect(wrapper.vm.checked).toBe(true); - expect(wrapper.find('.p-inputswitch').classes()).toContain('p-inputswitch-checked'); + expect(wrapper.find('.p-inputswitch').classes()).toContain('p-highlight'); }); }); diff --git a/components/lib/radiobutton/RadioButton.spec.js b/components/lib/radiobutton/RadioButton.spec.js index 22c7dabc0..facec8515 100644 --- a/components/lib/radiobutton/RadioButton.spec.js +++ b/components/lib/radiobutton/RadioButton.spec.js @@ -13,21 +13,20 @@ describe('RadioButton.vue', () => { }); }); - it('shoukd exist', () => { + it('should exist', () => { expect(wrapper.find('.p-radiobutton.p-component').exists()).toBe(true); expect(wrapper.find('input').attributes().type).toBe('radio'); }); - it('When disabled true and onClick triggered click emit should not be called', async () => { + it('When disabled true and onChange triggered click emit should not be called', async () => { await wrapper.setProps({ disabled: true }); - await wrapper.vm.onClick(); + await wrapper.trigger('change'); - expect(wrapper.emitted()['click']).toEqual(undefined); - expect(wrapper.emitted()['update:modelValue']).toEqual(undefined); + expect(wrapper.emitted()['change']).toBeFalsy(); }); - it('When disabled false and onClick triggered click emit should be called', async () => { - await wrapper.vm.onClick(); + it('When disabled false and onChange triggered click emit should be called', async () => { + await wrapper.vm.onChange({}); expect(wrapper.emitted()['update:modelValue'].length).toEqual(1); expect(wrapper.emitted().change.length).toEqual(1); @@ -35,24 +34,16 @@ describe('RadioButton.vue', () => { it('When value and modelValue equal and onClick triggered change emit should not be called', async () => { await wrapper.setProps({ modelValue: 'test', value: 'test' }); - await wrapper.vm.onClick(); + await wrapper.vm.onChange({}); - expect(wrapper.emitted()['change']).toEqual(undefined); + expect(wrapper.emitted()['change'][0][0]).toEqual({}); }); it('When modelValue changed, Checked should be effected', async () => { await wrapper.setProps({ modelValue: 'Tatooine' }); expect(wrapper.vm.checked).toBe(true); - expect(wrapper.find('.p-radiobutton').classes()).toContain('p-radiobutton-checked'); - }); - - it('When component cliked OnClick method should be called', async () => { - const spy = vi.spyOn(wrapper.vm, 'onClick'); - - await wrapper.find('.p-radiobutton').trigger('click'); - - expect(spy).toHaveBeenCalled(); + expect(wrapper.find('.p-radiobutton').classes()).toContain('p-highlight'); }); it('When component focused onFocus method should be called', async () => { @@ -65,13 +56,6 @@ describe('RadioButton.vue', () => { expect(spy).toHaveBeenCalled(); }); - it('When onFocus method triggered, false should be true', async () => { - await wrapper.vm.onFocus(); - - expect(wrapper.vm.focused).toBeTruthy(); - expect(wrapper.emitted().focus.length).toEqual(1); - }); - it('When component blur onBlur method should be called', async () => { await wrapper.setProps({ inputId: 'test' }); diff --git a/components/lib/sidebar/Sidebar.spec.js b/components/lib/sidebar/Sidebar.spec.js index eeca58df7..9a57a17db 100644 --- a/components/lib/sidebar/Sidebar.spec.js +++ b/components/lib/sidebar/Sidebar.spec.js @@ -65,7 +65,7 @@ describe('Sidebar.vue', () => { it('When keydown is triggered , hide method should be triggered', async () => { const hideSpy = vi.spyOn(wrapper.vm, 'hide'); - await wrapper.find('.p-sidebar').trigger('keydown', { code: 'Escape' }); + await wrapper.vm.onKeydown({ code: 'Escape' }); expect(hideSpy).toHaveBeenCalled(); }); diff --git a/components/lib/togglebutton/ToggleButton.spec.js b/components/lib/togglebutton/ToggleButton.spec.js index ec785ec31..b21e4d490 100644 --- a/components/lib/togglebutton/ToggleButton.spec.js +++ b/components/lib/togglebutton/ToggleButton.spec.js @@ -25,13 +25,13 @@ describe('ToggleButton', () => { expect(wrapper.find('span.pi-check').exists()).toBe(true); }); - it('should click works', async () => { - await wrapper.vm.onClick({}); + it('should change works', async () => { + await wrapper.vm.onChange({}); expect(wrapper.emitted()['update:modelValue'][0]).toEqual([true]); await wrapper.setProps({ modelValue: true }); - await wrapper.vm.onClick({}); + await wrapper.vm.onChange({}); expect(wrapper.emitted()['update:modelValue'][1]).toEqual([false]); }); diff --git a/components/lib/tristatecheckbox/TriStateCheckbox.spec.js b/components/lib/tristatecheckbox/TriStateCheckbox.spec.js index 6a7fd9fb2..4a63a91b4 100644 --- a/components/lib/tristatecheckbox/TriStateCheckbox.spec.js +++ b/components/lib/tristatecheckbox/TriStateCheckbox.spec.js @@ -10,35 +10,6 @@ describe('TriStateCheckbox.vue', () => { wrapper = mount(TriStateCheckbox); }); - it('When onClick method triggered some methods effect', () => { - const mockUpdateModel = vi.fn(); - - wrapper.vm.updateModel = mockUpdateModel; - - wrapper.vm.onClick('test'); - - expect(wrapper.vm.updateModel).toBeCalled(); - expect(wrapper.emitted()['click']).toBeTruthy(); - expect(wrapper.emitted()['change']).toBeTruthy(); - }); - - it('When event.code is not equal Enter methods should not be effected', async () => { - wrapper.vm.onKeyDown({ code: 'test' }); - - expect(wrapper.emitted().keydown).toBeFalsy(); - }); - - it('When event.code is equal Enter some methods should be triggered', async () => { - const mockUpdateModel = vi.fn(); - - wrapper.vm.updateModel = mockUpdateModel; - - wrapper.vm.onKeyDown({ code: 'Enter', preventDefault: () => {} }); - - expect(wrapper.vm.updateModel).toBeCalled(); - expect(wrapper.emitted().keydown).toBeTruthy(); - }); - it('When onBlur is triggered focused property should be false', async () => { wrapper.vm.onBlur(); @@ -52,15 +23,15 @@ describe('UpdateModel method tests', () => { wrapper = mount(TriStateCheckbox); }); - it('When disable props true updateModal should not triggered emit', async () => { + it('When disable props true change emit should not triggered', async () => { await wrapper.setProps({ disabled: true, modelValue: null }); - wrapper.vm.updateModel(); + await wrapper.trigger('change'); - expect(wrapper.emitted()['update:modelValue']).toBeFalsy(); + expect(wrapper.emitted()['change']).toBeFalsy(); }); it('When disable props false updateModal should triggered emit', () => { From 90c1e5b559eace17c8681d872a7e4519123c7acc Mon Sep 17 00:00:00 2001 From: yendefrr Date: Thu, 18 Jan 2024 12:30:21 +0300 Subject: [PATCH 6/6] Fixed Chips: Able to separate pasted value by new line (#5098) --- components/lib/chips/Chips.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/lib/chips/Chips.vue b/components/lib/chips/Chips.vue index 1f10dd96b..8263033c7 100755 --- a/components/lib/chips/Chips.vue +++ b/components/lib/chips/Chips.vue @@ -140,11 +140,12 @@ export default { }, onPaste(event) { if (this.separator) { + let separator = this.separator.replace('\\n', '\n').replace('\\r', '\r').replace('\\t', '\t'); let pastedData = (event.clipboardData || window['clipboardData']).getData('Text'); if (pastedData) { let value = this.modelValue || []; - let pastedValues = pastedData.split(this.separator); + let pastedValues = pastedData.split(separator); pastedValues = pastedValues.filter((val) => this.allowDuplicate || value.indexOf(val) === -1); value = [...value, ...pastedValues];