mirror of https://github.com/halo-dev/halo-admin
parent
28ea197230
commit
55f23cb961
@ -0,0 +1,73 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
},
|
||||
rows: {
|
||||
type: Number,
|
||||
default: 3,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:modelValue"]);
|
||||
|
||||
function handleInput(e: Event) {
|
||||
const { value } = e.target as HTMLInputElement;
|
||||
emit("update:modelValue", value);
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="textarea-wrapper">
|
||||
<textarea
|
||||
:placeholder="placeholder"
|
||||
:value="modelValue"
|
||||
@input="handleInput"
|
||||
:disabled="disabled"
|
||||
:rows="rows"
|
||||
>
|
||||
</textarea>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
.textarea-wrapper {
|
||||
@apply box-border;
|
||||
@apply relative;
|
||||
@apply w-full;
|
||||
@apply inline-flex;
|
||||
textarea {
|
||||
@apply outline-0;
|
||||
@apply bg-white;
|
||||
@apply antialiased;
|
||||
@apply w-full;
|
||||
@apply text-black;
|
||||
@apply block;
|
||||
@apply transition-all;
|
||||
@apply appearance-none;
|
||||
|
||||
@apply p-3;
|
||||
@apply text-sm;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 4px;
|
||||
|
||||
&:active {
|
||||
border-color: #4ccba0;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: #4ccba0;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
@apply opacity-50;
|
||||
@apply cursor-not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -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: `
|
||||
<v-textarea v-model="value" />
|
||||
`,
|
||||
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");
|
||||
});
|
||||
});
|
@ -0,0 +1,6 @@
|
||||
// Vitest Snapshot v1
|
||||
|
||||
exports[`Textarea > should render 1`] = `
|
||||
"<div class=\\"textarea-wrapper\\"><textarea rows=\\"3\\">
|
||||
</textarea></div>"
|
||||
`;
|
@ -0,0 +1 @@
|
||||
export { default as VTextarea } from "./Textarea.vue";
|
Loading…
Reference in new issue