diff --git a/CHANGELOG.md b/CHANGELOG.md index bb7e51473..5ca43a5ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ Changelog is rather internal in nature. See release notes for the public overvie ## Version 4.x.x (`release-v4` branch) +- [#591] + - **Description:** Added a clearable prop to KTextbox + - **Products impact:** - + - **Addresses:** https://github.com/learningequality/kolibri-design-system/issues/584 + - **Components:** `KTextbox` + - **Breaking:** no + - **Impacts a11y:** no + - **Guidance:** - + +[#591]: https://github.com/learningequality/kolibri-design-system/pull/591 + - [#582] - **Description:** Upgrade popper.js from 1.14.6 to 1.16.1 - **Products impact:** - diff --git a/docs/pages/playground.vue b/docs/pages/playground.vue index bf32354b2..686423285 100644 --- a/docs/pages/playground.vue +++ b/docs/pages/playground.vue @@ -24,9 +24,6 @@ - - - diff --git a/lib/KTextbox/__tests__/KTextbox.spec.js b/lib/KTextbox/__tests__/KTextbox.spec.js index 010bbd49e..20d0d8eb6 100644 --- a/lib/KTextbox/__tests__/KTextbox.spec.js +++ b/lib/KTextbox/__tests__/KTextbox.spec.js @@ -155,4 +155,60 @@ describe('KTextbox component', () => { expect(wrapper.emitted().input).toBeTruthy(); }); }); + describe('KTextbox with clearable', () => { + it('should have the clear button when clearable is true and there is text in the input', async () => { + const wrapper = mount(KTextbox, { + propsData: { + clearable: true, + }, + }); + const input = wrapper.find('input'); + input.element.value = 'test'; + input.trigger('input'); + await wrapper.vm.$nextTick(); + const clearButton = wrapper.find('[data-test="clearIcon"]'); + expect(clearButton.exists()).toBeTruthy(); + }); + it('should not show the clear button when clearable is true and there is no text in the input', async () => { + const wrapper = mount(KTextbox, { + propsData: { + clearable: true, + }, + }); + + const input = wrapper.find('input'); + input.element.value = ''; + input.trigger('input'); + await wrapper.vm.$nextTick(); + expect(wrapper.find('[data-test="clearIcon"]').exists()).toBeFalsy(); + }); + + it('should not show the clear button when clearable is false and there is text in the input', async () => { + const wrapper = mount(KTextbox, { + propsData: { + clearable: false, + }, + }); + const input = wrapper.find('input'); + input.element.value = 'test'; + input.trigger('input'); + await wrapper.vm.$nextTick(); + expect(wrapper.find('[data-test="clearIcon"]').exists()).toBeFalsy(); + }); + it('should clear the input when clear button is clicked', async () => { + const wrapper = mount(KTextbox, { + propsData: { + clearable: true, + }, + }); + const input = wrapper.find('input'); + input.element.value = 'test'; + input.trigger('input'); + await wrapper.vm.$nextTick(); + const clearButton = wrapper.find('[data-test="clearIcon"]'); + clearButton.trigger('click'); + await wrapper.vm.$nextTick(); + expect(wrapper.find('input').element.value).toBe(''); + }); + }); }); diff --git a/lib/KTextbox/index.vue b/lib/KTextbox/index.vue index 1dea289cd..34c0233e3 100644 --- a/lib/KTextbox/index.vue +++ b/lib/KTextbox/index.vue @@ -7,6 +7,8 @@ class="textbox" :label="label" :disabled="disabled" + :clearAriaLabel="clearAriaLabel" + :clearable="clearable" :invalid="showInvalidMessage" :error="invalidText" :autofocus="autofocus" @@ -50,6 +52,10 @@ type: String, required: true, }, + /** + * Value of the aria-label for clear button + */ + clearAriaLabel: { type: String, default: 'Clear' }, /** * Value of the text field */ @@ -142,6 +148,13 @@ type: Boolean, default: false, }, + /** + * When set to `true`, the component displays a clear button inside the input field. + */ + clearable: { + type: Boolean, + default: false, + }, /** * @ignore * Whether or not to display as a floating label. diff --git a/lib/keen/UiTextbox.vue b/lib/keen/UiTextbox.vue index a22c06629..72234dac2 100644 --- a/lib/keen/UiTextbox.vue +++ b/lib/keen/UiTextbox.vue @@ -9,6 +9,7 @@ functionality. -->