mirror of https://github.com/halo-dev/halo-admin
parent
dc01a11738
commit
e96ca64cb5
|
@ -0,0 +1,22 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { VEmpty } from "./index";
|
||||||
|
import { VButton } from "@/components/button";
|
||||||
|
import { VSpace } from "@/components/space";
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<Story title="Empty">
|
||||||
|
<template #default>
|
||||||
|
<VEmpty
|
||||||
|
message="没有找到与搜索条件匹配的文章,你可以清空搜索条件或者新建文章"
|
||||||
|
title="没有找到与搜索条件匹配的文章"
|
||||||
|
>
|
||||||
|
<template #actions>
|
||||||
|
<VSpace>
|
||||||
|
<VButton>清空搜索</VButton>
|
||||||
|
<VButton type="primary">新建文章</VButton>
|
||||||
|
</VSpace>
|
||||||
|
</template>
|
||||||
|
</VEmpty>
|
||||||
|
</template>
|
||||||
|
</Story>
|
||||||
|
</template>
|
|
@ -0,0 +1,90 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 558.095 475.798">
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
d="M555.536,328.049c-15.243-76.866-104.547-138.3-121.965-218.4C401.914,7.74,297.57-8.372,229.765,35.887c-107.437,70.129,7.176,87.532-203.473,253.453-52.014,40.969-35.44,221.817,128.193,180.313,88.06-22.336,114.83-25.47,154.44-29.148C408.763,431.236,581.123,457.079,555.536,328.049Z"
|
||||||
|
fill="#367cff" opacity="0.1"></path>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<polygon points="436.267 347.314 281.957 428.813 127.88 347.314 127.88 224.244 436.267 224.244 436.267 347.314"
|
||||||
|
fill="#fff"></polygon>
|
||||||
|
<path
|
||||||
|
d="M281.957,430.063a1.237,1.237,0,0,1-.585-.146L127.3,348.418a1.249,1.249,0,0,1-.666-1.1V224.244a1.25,1.25,0,0,1,1.25-1.25H436.267a1.25,1.25,0,0,1,1.25,1.25v123.07a1.249,1.249,0,0,1-.666,1.1l-154.31,81.5A1.244,1.244,0,0,1,281.957,430.063Zm-152.827-83.5L281.957,427.4l153.06-80.839V225.494H129.13Zm307.137.753h0Z"
|
||||||
|
fill="#262626"></path>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon points="436.267 197.835 281.957 116.336 351.298 82.913 505.608 164.413 436.267 197.835"
|
||||||
|
fill="#fff"></polygon>
|
||||||
|
<path
|
||||||
|
d="M436.267,199.085a1.255,1.255,0,0,1-.584-.144l-154.31-81.5a1.251,1.251,0,0,1,.041-2.232l69.341-33.423a1.244,1.244,0,0,1,1.127.021l154.31,81.5a1.25,1.25,0,0,1-.041,2.231L436.81,198.961A1.246,1.246,0,0,1,436.267,199.085Zm-151.537-82.7,151.563,80.048,66.542-32.073L351.272,84.314Z"
|
||||||
|
fill="#262626"></path>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon points="127.88 197.835 282.19 116.336 212.849 82.913 58.539 164.413 127.88 197.835"
|
||||||
|
fill="#fff"></polygon>
|
||||||
|
<path
|
||||||
|
d="M127.88,199.085a1.249,1.249,0,0,1-.543-.124L58,165.538a1.25,1.25,0,0,1-.041-2.231l154.31-81.5a1.244,1.244,0,0,1,1.127-.021l69.341,33.423a1.251,1.251,0,0,1,.041,2.232l-154.31,81.5A1.252,1.252,0,0,1,127.88,199.085ZM61.312,164.362l66.542,32.073,151.563-80.048L212.875,84.314Z"
|
||||||
|
fill="#262626"></path>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon points="127.88 197.835 282.19 279.335 202.849 322.757 48.539 241.258 127.88 197.835"
|
||||||
|
fill="#fff"></polygon>
|
||||||
|
<path
|
||||||
|
d="M202.849,324.007a1.244,1.244,0,0,1-.584-.145l-154.31-81.5a1.25,1.25,0,0,1-.016-2.2l79.341-43.423a1.246,1.246,0,0,1,1.184-.008l154.31,81.5a1.25,1.25,0,0,1,.016,2.2l-79.341,43.423A1.251,1.251,0,0,1,202.849,324.007ZM51.179,241.238l151.659,80.1,76.713-41.984-151.66-80.1Z"
|
||||||
|
fill="#262626"></path>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon points="436.267 197.835 281.957 279.335 361.298 322.757 515.608 241.258 436.267 197.835"
|
||||||
|
fill="#fff"></polygon>
|
||||||
|
<path
|
||||||
|
d="M361.3,324.007a1.254,1.254,0,0,1-.6-.153l-79.341-43.423a1.25,1.25,0,0,1,.016-2.2l154.31-81.5a1.246,1.246,0,0,1,1.184.008l79.341,43.423a1.25,1.25,0,0,1-.016,2.2l-154.31,81.5A1.244,1.244,0,0,1,361.3,324.007Zm-76.7-44.653,76.712,41.984,151.66-80.1-76.713-41.984Z"
|
||||||
|
fill="#262626"></path>
|
||||||
|
</g>
|
||||||
|
<polygon points="282.19 116.336 127.88 197.835 281.957 279.335 436.267 197.835 282.19 116.336"
|
||||||
|
fill="#262626"></polygon>
|
||||||
|
<rect x="280.707" y="279.334" width="2.5" height="149.479" fill="#262626"></rect>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
d="M195.5,190.436a.99.99,0,0,1-.577-.185,1,1,0,0,1-.238-1.394c.185-.261,18.258-26.389-1.918-50.209a38.006,38.006,0,0,0-29.095-13.516H163.4c1.916,6.656,1.574,12.574-1.139,17.114a12.645,12.645,0,0,1-11.68,6.42,10.041,10.041,0,0,1-8.679-6.752c-2.219-5.788.1-11.4,6.212-15.017a29.5,29.5,0,0,1,12.589-3.621,53.3,53.3,0,0,0-5.566-10.821c-7.285-11.126-20.562-18.828-36.428-21.131-13.446-1.951-26.332.347-32.833,5.853a1,1,0,0,1-1.292-1.527c6.918-5.859,20.425-8.336,34.412-6.3,16.433,2.386,30.215,10.409,37.815,22.014a54.285,54.285,0,0,1,5.968,11.816,39.976,39.976,0,0,1,31.509,14.18c21.193,25.019,2.217,52.385,2.023,52.659A1,1,0,0,1,195.5,190.436Zm-34.148-65.231a27.826,27.826,0,0,0-12.215,3.414c-5.276,3.122-7.23,7.708-5.363,12.58a8.108,8.108,0,0,0,6.984,5.476,10.669,10.669,0,0,0,9.791-5.454C163.039,137.051,163.267,131.508,161.349,125.205Z"
|
||||||
|
fill="#292a2e"></path>
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
d="M68.617,113.3a6.809,6.809,0,1,1,.684-.246A6.652,6.652,0,0,1,68.617,113.3Zm-3.325-11.112a4.689,4.689,0,0,0-.477.172,4.791,4.791,0,1,0,.477-.172Z"
|
||||||
|
fill="#292a2e"></path>
|
||||||
|
<path
|
||||||
|
d="M68.605,97.63a6.8,6.8,0,0,1-8.216-3.885h0a6.8,6.8,0,1,1,8.9,3.64A6.964,6.964,0,0,1,68.605,97.63ZM65.284,86.517a4.889,4.889,0,0,0-.483.173,4.8,4.8,0,0,0-2.568,6.281h0a4.8,4.8,0,1,0,3.051-6.455Z"
|
||||||
|
fill="#292a2e"></path>
|
||||||
|
<ellipse cx="66.664" cy="98.763" rx="8.892" ry="5.939" fill="#fff"></ellipse>
|
||||||
|
<path
|
||||||
|
d="M70.6,105.139a13.754,13.754,0,0,1-3.927.564c-5.548,0-9.9-3.04-9.9-6.931s4.339-6.942,9.885-6.948a12.424,12.424,0,0,1,6.845,1.9,5.676,5.676,0,0,1,.009,10.063A10.872,10.872,0,0,1,70.6,105.139ZM63.338,94.3c-2.672.8-4.566,2.527-4.565,4.467,0,2.677,3.617,4.936,7.9,4.932a10.417,10.417,0,0,0,5.732-1.576,3.706,3.706,0,0,0-.006-6.735,10.4,10.4,0,0,0-5.734-1.566A11.607,11.607,0,0,0,63.338,94.3Z"
|
||||||
|
fill="#292a2e"></path>
|
||||||
|
<polygon points="68.845 104.521 68.635 92.971 65.763 92.855 65.562 104.656 68.845 104.521"
|
||||||
|
fill="#292a2e"></polygon>
|
||||||
|
<circle cx="54.867" cy="100.358" r="0.918" fill="#292a2e"></circle>
|
||||||
|
<circle cx="55.584" cy="95.446" r="0.918" fill="#292a2e"></circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
d="M352.625,132.766a1,1,0,0,1-.956-.707,99.236,99.236,0,0,1-2.606-38.021c2.585-18.6,12.843-43.011,47.03-53.7a88.364,88.364,0,0,1,14.748-3.381c1.611-10.061,7.739-20.975,21.444-28.505,32.562-17.892,54.557-1.839,54.775-1.675a1,1,0,0,1-1.2,1.6c-.208-.156-21.228-15.417-52.611,1.829-12.806,7.037-18.668,17.137-20.335,26.513,15.079-1.485,22.3,3.545,25.541,7.344A15.488,15.488,0,0,1,440.769,61a12.094,12.094,0,0,1-11.835,6.909c-8.421-.494-15.39-7.578-17.752-18.048a34.03,34.03,0,0,1-.614-10.8,85.533,85.533,0,0,0-13.877,3.191c-26.645,8.331-42,25.85-45.648,52.067a96.986,96.986,0,0,0,2.538,37.16,1,1,0,0,1-.956,1.293Zm59.982-93.955a32.014,32.014,0,0,0,.526,10.609c2.161,9.578,8.409,16.051,15.918,16.492a10.178,10.178,0,0,0,9.928-5.8,13.494,13.494,0,0,0-2.048-14.749C432.255,39.876,423.722,37.66,412.607,38.811Z"
|
||||||
|
fill="#292a2e"></path>
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
d="M510.354,16.884a7.142,7.142,0,1,1,6.994-8.659h0a7.156,7.156,0,0,1-6.994,8.659ZM510.369,4.6a5.141,5.141,0,1,0,5.024,4.051A5.111,5.111,0,0,0,510.369,4.6Z"
|
||||||
|
fill="#292a2e"></path>
|
||||||
|
<path
|
||||||
|
d="M507.343,33.205a7.162,7.162,0,1,1,1.529-.165A7.171,7.171,0,0,1,507.343,33.205Zm.025-12.285a5.164,5.164,0,0,0-1.1.119,5.112,5.112,0,1,0,1.1-.119Z"
|
||||||
|
fill="#292a2e"></path>
|
||||||
|
<ellipse cx="508.827" cy="18.098" rx="6.289" ry="9.416" transform="translate(398.692 515.192) rotate(-79.545)"
|
||||||
|
fill="#fff"></ellipse>
|
||||||
|
<path
|
||||||
|
d="M510.2,25.516a14.966,14.966,0,0,1-2.7-.25,13.1,13.1,0,0,1-6.729-3.286,6.419,6.419,0,0,1-2.191-5.772,6.422,6.422,0,0,1,4.107-4.61,13.946,13.946,0,0,1,14.187,2.618,6.419,6.419,0,0,1,2.191,5.772,6.422,6.422,0,0,1-4.107,4.61A12.088,12.088,0,0,1,510.2,25.516Zm-2.762-12.838a10.072,10.072,0,0,0-3.961.757,4.506,4.506,0,0,0-2.93,3.136,4.506,4.506,0,0,0,1.618,3.975,11.966,11.966,0,0,0,12,2.215,4.506,4.506,0,0,0,2.93-3.136h0a4.5,4.5,0,0,0-1.618-3.975,11.084,11.084,0,0,0-5.7-2.753A12.957,12.957,0,0,0,507.442,12.678Z"
|
||||||
|
fill="#292a2e"></path>
|
||||||
|
<polygon points="507.668 11.682 505.657 23.748 508.624 24.424 511.112 12.175 507.668 11.682"
|
||||||
|
fill="#292a2e"></polygon>
|
||||||
|
<circle cx="519.723" cy="23.691" r="0.972" fill="#292a2e"></circle>
|
||||||
|
<circle cx="521.417" cy="18.715" r="0.972" fill="#292a2e"></circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 7.6 KiB |
|
@ -0,0 +1,57 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import Empty from "./Empty.svg";
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
title?: string;
|
||||||
|
message?: string;
|
||||||
|
image?: string;
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="empty-wrapper">
|
||||||
|
<div class="empty-image h-32 w-32">
|
||||||
|
<slot name="image">
|
||||||
|
<img :src="image || Empty" alt="Empty" />
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
<div class="empty-title">{{ title }}</div>
|
||||||
|
<div class="empty-message">
|
||||||
|
<slot name="message">
|
||||||
|
{{ message }}
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
<div class="empty-actions">
|
||||||
|
<slot name="actions"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style lang="scss">
|
||||||
|
.empty-wrapper {
|
||||||
|
@apply flex
|
||||||
|
flex-col
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
my-10
|
||||||
|
px-10;
|
||||||
|
|
||||||
|
.empty-title {
|
||||||
|
@apply text-sm
|
||||||
|
text-gray-900
|
||||||
|
text-center
|
||||||
|
font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-message {
|
||||||
|
@apply text-gray-500
|
||||||
|
text-xs
|
||||||
|
text-center
|
||||||
|
mt-1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-actions {
|
||||||
|
@apply flex
|
||||||
|
flex-row
|
||||||
|
mt-5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,95 @@
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { mount } from "@vue/test-utils";
|
||||||
|
import { VEmpty } from "../index";
|
||||||
|
import { VButton } from "../../button";
|
||||||
|
import { h } from "vue";
|
||||||
|
|
||||||
|
describe("Empty", () => {
|
||||||
|
it("should render", () => {
|
||||||
|
expect(mount(VEmpty)).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should match snapshot", () => {
|
||||||
|
expect(
|
||||||
|
mount(VEmpty, {
|
||||||
|
props: { title: "Not found", message: "No posts found" },
|
||||||
|
slots: {
|
||||||
|
actions: h(VButton, { type: "primary" }, "New Post"),
|
||||||
|
},
|
||||||
|
}).html()
|
||||||
|
).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work with title prop", () => {
|
||||||
|
const wrapper = mount(VEmpty, { props: { title: "Not found" } });
|
||||||
|
expect(wrapper.find(".empty-title").text()).toEqual("Not found");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work with message prop", () => {
|
||||||
|
const wrapper = mount(VEmpty, { props: { message: "No posts found" } });
|
||||||
|
expect(wrapper.find(".empty-message").text()).toEqual("No posts found");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work with message slot", () => {
|
||||||
|
const wrapper = mount(VEmpty, {
|
||||||
|
props: { message: "empty" },
|
||||||
|
slots: { message: h("span", h("storage", "No posts found")) },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.find(".empty-message")).not.toEqual("Empty");
|
||||||
|
expect(wrapper.find(".empty-message > span > storage").text()).toEqual(
|
||||||
|
"No posts found"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work with actions slot", () => {
|
||||||
|
const wrapper = mount(VEmpty, {
|
||||||
|
slots: {
|
||||||
|
actions: h(VButton, { type: "primary" }, "New Post"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.findComponent(VButton)).toBeDefined();
|
||||||
|
expect(wrapper.findComponent(VButton).find(".btn-content").text()).toEqual(
|
||||||
|
"New Post"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work with image prop", async () => {
|
||||||
|
const wrapper = mount({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
image: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return h(VEmpty, {
|
||||||
|
image: this.image,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.find(".empty-image > img").attributes().src).toEqual(
|
||||||
|
"/src/components/empty/Empty.svg"
|
||||||
|
);
|
||||||
|
|
||||||
|
await wrapper.setData({ image: "./empty.png" });
|
||||||
|
|
||||||
|
expect(wrapper.find(".empty-image > img").attributes().src).toEqual(
|
||||||
|
"./empty.png"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should work with image slot", () => {
|
||||||
|
const wrapper = mount(VEmpty, {
|
||||||
|
slots: { image: h("img", { src: "./empty", alt: "Empty Status" }) },
|
||||||
|
});
|
||||||
|
|
||||||
|
const attributes = wrapper.find(".empty-image > img").attributes();
|
||||||
|
|
||||||
|
expect(attributes.src).not.toEqual("/src/components/empty/Empty.svg");
|
||||||
|
|
||||||
|
expect(attributes.src).toEqual("./empty");
|
||||||
|
expect(attributes.alt).toEqual("Empty Status")
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Vitest Snapshot v1
|
||||||
|
|
||||||
|
exports[`Empty > should match snapshot 1`] = `
|
||||||
|
"<div class=\\"empty-wrapper\\">
|
||||||
|
<div class=\\"empty-image h-32 w-32\\"><img src=\\"/src/components/empty/Empty.svg\\" alt=\\"Empty\\"></div>
|
||||||
|
<div class=\\"empty-title\\">Not found</div>
|
||||||
|
<div class=\\"empty-message\\">No posts found</div>
|
||||||
|
<div class=\\"empty-actions\\"><button class=\\"btn-md btn-primary btn\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content\\">New Post</span>
|
||||||
|
</button></div>
|
||||||
|
</div>"
|
||||||
|
`;
|
|
@ -0,0 +1 @@
|
||||||
|
export { default as VEmpty } from "./Empty.vue";
|
Loading…
Reference in New Issue