diff --git a/src/components/base/checkbox/CheckBox.vue b/src/components/base/checkbox/CheckBox.vue
new file mode 100644
index 000000000..766cb2e37
--- /dev/null
+++ b/src/components/base/checkbox/CheckBox.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/base/checkbox/CheckBoxGroup.vue b/src/components/base/checkbox/CheckBoxGroup.vue
new file mode 100644
index 000000000..a9e91a578
--- /dev/null
+++ b/src/components/base/checkbox/CheckBoxGroup.vue
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
diff --git a/src/components/base/checkbox/__tests__/CheckBox.spec.ts b/src/components/base/checkbox/__tests__/CheckBox.spec.ts
new file mode 100644
index 000000000..813f40b92
--- /dev/null
+++ b/src/components/base/checkbox/__tests__/CheckBox.spec.ts
@@ -0,0 +1,61 @@
+import { describe, expect, it } from "vitest";
+import { VCheckbox } from "../index";
+import { mount } from "@vue/test-utils";
+
+describe("CheckBox", () => {
+ it("should render", () => {
+ expect(VCheckbox).toBeDefined();
+ expect(mount(VCheckbox).html()).toMatchSnapshot();
+ });
+
+ it("should work with v-model:checked", async function () {
+ const wrapper = mount({
+ data() {
+ return {
+ checked: false,
+ };
+ },
+ template: `
+
+ `,
+ components: {
+ VCheckbox,
+ },
+ });
+
+ expect(wrapper.find("input").element.checked).toBe(false);
+ expect(wrapper.findComponent(VCheckbox).classes()).not.toContain(
+ "checkbox-wrapper-checked"
+ );
+
+ // change checked value
+ await wrapper.setData({ checked: true });
+ expect(wrapper.find("input").element.checked).toBe(true);
+ expect(wrapper.findComponent(VCheckbox).classes()).toContain(
+ "checkbox-wrapper-checked"
+ );
+
+ // click on checkbox
+ await wrapper.find("input").setValue(false);
+ expect(wrapper.vm.checked).toBe(false);
+ expect(wrapper.find("input").element.checked).toBe(false);
+ expect(wrapper.findComponent(VCheckbox).classes()).not.toContain(
+ "checkbox-wrapper-checked"
+ );
+ });
+
+ it("should work with label prop", async function () {
+ const wrapper = mount(VCheckbox, {
+ props: {
+ checked: true,
+ },
+ });
+
+ expect(wrapper.html()).not.toContain("label");
+
+ await wrapper.setProps({ label: "label" });
+
+ expect(wrapper.html()).toContain("label");
+ expect(wrapper.find("label").text()).toBe("label");
+ });
+});
diff --git a/src/components/base/checkbox/__tests__/CheckBoxGroup.spec.ts b/src/components/base/checkbox/__tests__/CheckBoxGroup.spec.ts
new file mode 100644
index 000000000..6a302cb6c
--- /dev/null
+++ b/src/components/base/checkbox/__tests__/CheckBoxGroup.spec.ts
@@ -0,0 +1,124 @@
+import { describe, expect, it } from "vitest";
+import { VCheckbox, VCheckboxGroup } from "../index";
+import { mount } from "@vue/test-utils";
+
+const options = [
+ {
+ value: "foo",
+ label: "foo",
+ },
+ {
+ value: "bar",
+ label: "bar",
+ },
+];
+
+describe("CheckBoxGroup", () => {
+ it("should render", () => {
+ expect(VCheckboxGroup).toBeDefined();
+ expect(
+ mount(VCheckboxGroup, {
+ props: {
+ options,
+ },
+ }).html()
+ ).toMatchSnapshot();
+ });
+
+ it("should work with options prop", function () {
+ const wrapper = mount({
+ data() {
+ return {
+ options: options,
+ };
+ },
+ template: `
+
+ `,
+ components: {
+ VCheckboxGroup,
+ },
+ });
+
+ expect(wrapper.findAllComponents(VCheckbox).length).toBe(2);
+ expect(wrapper.findAllComponents(VCheckbox)[0].vm.$props.value).toBe("foo");
+ expect(wrapper.findAllComponents(VCheckbox)[0].vm.$props.label).toBe("foo");
+ expect(wrapper.findAllComponents(VCheckbox)[1].vm.$props.value).toBe("bar");
+ expect(wrapper.findAllComponents(VCheckbox)[1].vm.$props.label).toBe("bar");
+ });
+
+ it("should work with v-model", async function () {
+ const wrapper = mount({
+ data() {
+ return {
+ value: ["foo"],
+ options: options,
+ };
+ },
+ template: `
+
+ `,
+ components: {
+ VCheckboxGroup,
+ },
+ });
+
+ expect(wrapper.findAllComponents(VCheckbox)[0].classes()).toContain(
+ "checkbox-wrapper-checked"
+ );
+ expect(
+ wrapper.findAllComponents(VCheckbox)[0].find("input").element.checked
+ ).toBe(true);
+
+ // mock click event
+ await wrapper.findAllComponents(VCheckbox)[1].find("input").setValue(true);
+
+ expect(wrapper.findAllComponents(VCheckbox)[1].classes()).toContain(
+ "checkbox-wrapper-checked"
+ );
+ expect(
+ wrapper.findAllComponents(VCheckbox)[1].find("input").element.checked
+ ).toBe(true);
+ expect(wrapper.vm.value).toEqual(["foo", "bar"]);
+ });
+
+ it("should work with valueKey and labelKey props", async function () {
+ const wrapper = mount({
+ data() {
+ return {
+ value: ["foo"],
+ options: [
+ {
+ id: "foo",
+ name: "foo",
+ },
+ {
+ id: "bar",
+ name: "bar",
+ },
+ ],
+ };
+ },
+ template: `
+
+ `,
+ components: {
+ VCheckboxGroup,
+ },
+ });
+
+ expect(
+ wrapper.findAllComponents(VCheckbox)[0].find("input").attributes("value")
+ ).toBe("foo");
+ expect(
+ wrapper.findAllComponents(VCheckbox)[0].find(".checkbox-label").text()
+ ).toBe("foo");
+
+ await wrapper.findAllComponents(VCheckbox)[1].find("input").setValue(true);
+ expect(wrapper.findAllComponents(VCheckbox)[1].classes()).toContain(
+ "checkbox-wrapper-checked"
+ );
+
+ expect(wrapper.vm.value).toEqual(["foo", "bar"]);
+ });
+});
diff --git a/src/components/base/checkbox/__tests__/__snapshots__/CheckBox.spec.ts.snap b/src/components/base/checkbox/__tests__/__snapshots__/CheckBox.spec.ts.snap
new file mode 100644
index 000000000..8aaef497c
--- /dev/null
+++ b/src/components/base/checkbox/__tests__/__snapshots__/CheckBox.spec.ts.snap
@@ -0,0 +1,8 @@
+// Vitest Snapshot v1
+
+exports[`CheckBox > should render 1`] = `
+"
"
+`;
diff --git a/src/components/base/checkbox/__tests__/__snapshots__/CheckBoxGroup.spec.ts.snap b/src/components/base/checkbox/__tests__/__snapshots__/CheckBoxGroup.spec.ts.snap
new file mode 100644
index 000000000..3f947977d
--- /dev/null
+++ b/src/components/base/checkbox/__tests__/__snapshots__/CheckBoxGroup.spec.ts.snap
@@ -0,0 +1,12 @@
+// Vitest Snapshot v1
+
+exports[`CheckBoxGroup > should render 1`] = `
+""
+`;
diff --git a/src/components/base/checkbox/index.ts b/src/components/base/checkbox/index.ts
new file mode 100644
index 000000000..fc2c8cc59
--- /dev/null
+++ b/src/components/base/checkbox/index.ts
@@ -0,0 +1,2 @@
+export { default as VCheckbox } from "./CheckBox.vue";
+export { default as VCheckboxGroup } from "./CheckBoxGroup.vue";
diff --git a/src/components/base/radio/Radio.vue b/src/components/base/radio/Radio.vue
index 09e96ddd8..00b986373 100644
--- a/src/components/base/radio/Radio.vue
+++ b/src/components/base/radio/Radio.vue
@@ -31,18 +31,18 @@ function handleChange(e: Event) {
}
-
+
diff --git a/src/components/base/radio/__tests__/__snapshots__/Radio.spec.ts.snap b/src/components/base/radio/__tests__/__snapshots__/Radio.spec.ts.snap
index e6510e34b..8aa3732c3 100644
--- a/src/components/base/radio/__tests__/__snapshots__/Radio.spec.ts.snap
+++ b/src/components/base/radio/__tests__/__snapshots__/Radio.spec.ts.snap
@@ -1,8 +1,8 @@
// Vitest Snapshot v1
exports[`Radio > should render 1`] = `
-"
-
+"
"
`;
diff --git a/src/components/base/radio/__tests__/__snapshots__/RadioGroup.spec.ts.snap b/src/components/base/radio/__tests__/__snapshots__/RadioGroup.spec.ts.snap
index 224bcd3c1..32420c39f 100644
--- a/src/components/base/radio/__tests__/__snapshots__/RadioGroup.spec.ts.snap
+++ b/src/components/base/radio/__tests__/__snapshots__/RadioGroup.spec.ts.snap
@@ -3,10 +3,10 @@
exports[`RadioGroup > should render 1`] = `
"
"
`;
diff --git a/src/views/ViewComponents.vue b/src/views/ViewComponents.vue
index 9f0d2721a..b24e32092 100644
--- a/src/views/ViewComponents.vue
+++ b/src/views/ViewComponents.vue
@@ -90,7 +90,7 @@
-
+
Select
Size:
@@ -117,7 +117,7 @@
-
+
Radio
Radio:
@@ -132,7 +132,25 @@
Radio Group:
-
+
+
+
+
+ CheckBox
+ CheckBox:
+
+
+
+ CheckBox Group:
+
+
+
+ Checked: {{ checkboxGroupValue }}
+
@@ -146,11 +164,14 @@ import { VInput } from "@/components/base/input";
import { VOption, VSelect } from "@/components/base/select";
import { VTextarea } from "@/components/base/textarea";
import { VRadio, VRadioGroup } from "@/components/base/radio";
+import { VCheckbox, VCheckboxGroup } from "@/components/base/checkbox";
import { ref } from "vue";
const inputValue = ref();
const selectValue = ref();
const radioValue = ref("apple");
+const checkboxValue = ref(false);
+const checkboxGroupValue = ref(["apple"]);
const selectData = [
{
@@ -177,4 +198,19 @@ const radioData = [
label: "Orange",
},
];
+
+const checkboxData = [
+ {
+ value: "apple",
+ label: "Apple",
+ },
+ {
+ value: "banana",
+ label: "Banana",
+ },
+ {
+ value: "orange",
+ label: "Orange",
+ },
+];