diff --git a/src/components/base/textarea/Textarea.vue b/src/components/base/textarea/Textarea.vue new file mode 100644 index 00000000..51339ab4 --- /dev/null +++ b/src/components/base/textarea/Textarea.vue @@ -0,0 +1,73 @@ + + + diff --git a/src/components/base/textarea/__tests__/Textarea.spec.ts b/src/components/base/textarea/__tests__/Textarea.spec.ts new file mode 100644 index 00000000..eadbbd12 --- /dev/null +++ b/src/components/base/textarea/__tests__/Textarea.spec.ts @@ -0,0 +1,70 @@ +import { describe, expect, it, vi } from "vitest"; +import { VTextarea } from "../index"; +import { mount } from "@vue/test-utils"; + +describe("Textarea", () => { + it("should render", function () { + expect(VTextarea).toBeDefined(); + expect(mount(VTextarea).html()).toMatchSnapshot(); + }); + + it("should work with placeholder prop", async function () { + const textarea = mount(VTextarea); + expect( + textarea.find("textarea").attributes()["placeholder"] + ).toBeUndefined(); + + // set placeholder prop + const placeholderText = "Please enter your text"; + await textarea.setProps({ placeholder: placeholderText }); + expect(textarea.find("textarea").attributes()["placeholder"]).toBe( + placeholderText + ); + }); + + it("should work with disabled prop", async function () { + const textarea = mount(VTextarea); + expect(textarea.find("textarea").attributes()["disabled"]).toBeUndefined(); + + // set disabled prop + await textarea.setProps({ disabled: true }); + expect(textarea.find("textarea").attributes()["disabled"]).toBeDefined(); + }); + + it("should work with rows prop", function () { + const textarea = mount(VTextarea, { + propsData: { + rows: 5, + }, + }); + expect(textarea.find("textarea").attributes()["rows"]).toBe("5"); + }); + + it("should work with v-model", async function () { + const wrapper = mount({ + data() { + return { + value: "my name is ryanwang", + }; + }, + template: ` + + `, + components: { VTextarea }, + }); + + expect(wrapper.find("textarea").element.value).toBe("my name is ryanwang"); + + // change value + await wrapper.setData({ + value: "my name is ryanwang, my website is https://ryanc.cc", + }); + expect(wrapper.find("textarea").element.value).toBe( + "my name is ryanwang, my website is https://ryanc.cc" + ); + + // change modelValue by textarea element value + await wrapper.find("textarea").setValue("my name is ryanwang"); + expect(wrapper.vm.$data.value).toBe("my name is ryanwang"); + }); +}); diff --git a/src/components/base/textarea/__tests__/__snapshots__/Textarea.spec.ts.snap b/src/components/base/textarea/__tests__/__snapshots__/Textarea.spec.ts.snap new file mode 100644 index 00000000..bd7fea5c --- /dev/null +++ b/src/components/base/textarea/__tests__/__snapshots__/Textarea.spec.ts.snap @@ -0,0 +1,6 @@ +// Vitest Snapshot v1 + +exports[`Textarea > should render 1`] = ` +"
" +`; diff --git a/src/components/base/textarea/index.ts b/src/components/base/textarea/index.ts new file mode 100644 index 00000000..ebf6c0ae --- /dev/null +++ b/src/components/base/textarea/index.ts @@ -0,0 +1 @@ +export { default as VTextarea } from "./Textarea.vue"; diff --git a/src/views/ViewComponents.vue b/src/views/ViewComponents.vue index 400424b4..12b6e7ef 100644 --- a/src/views/ViewComponents.vue +++ b/src/views/ViewComponents.vue @@ -77,6 +77,19 @@ +
+

Textarea

+
+ +
+

Disabled:

+
+ +
+

Select

Size:

@@ -113,6 +126,7 @@ import { FilledLayout } from "../layouts"; import { VButton } from "@/components/base/button"; import { VInput } from "@/components/base/input"; import { VSelect, VOption } from "@/components/base/select"; +import { VTextarea } from "@/components/base/textarea"; import { ref } from "vue"; const inputValue = ref();