mirror of https://github.com/halo-dev/halo
feat: button component support loading state
Signed-off-by: Ryan Wang <i@ryanc.cc>pull/3445/head
parent
a3462c756c
commit
345c0bc3cb
|
@ -3,7 +3,7 @@
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"dev": "vite",
|
"dev": "vite --host",
|
||||||
"build": "vue-tsc --noEmit && vite build",
|
"build": "vue-tsc --noEmit && vite build",
|
||||||
"preview": "vite preview --port 5050",
|
"preview": "vite preview --port 5050",
|
||||||
"test:unit": "vitest --environment jsdom --run",
|
"test:unit": "vitest --environment jsdom --run",
|
||||||
|
|
|
@ -5,7 +5,33 @@
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
|
<span v-if="$slots.icon || loading" class="btn-icon self-center mr-3">
|
||||||
|
<svg
|
||||||
|
v-if="loading"
|
||||||
|
class="animate-spin h-5 w-5 text-white"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<circle
|
||||||
|
class="opacity-25"
|
||||||
|
cx="12"
|
||||||
|
cy="12"
|
||||||
|
r="10"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="4"
|
||||||
|
></circle>
|
||||||
|
<path
|
||||||
|
class="opacity-75"
|
||||||
|
fill="currentColor"
|
||||||
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
<slot v-else name="icon" />
|
||||||
|
</span>
|
||||||
|
<span class="btn-content self-center">
|
||||||
<slot />
|
<slot />
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -48,6 +74,7 @@ const classes = computed(() => {
|
||||||
`btn-${props.type}`,
|
`btn-${props.type}`,
|
||||||
{ "btn-circle": props.circle },
|
{ "btn-circle": props.circle },
|
||||||
{ "btn-block": props.block },
|
{ "btn-block": props.block },
|
||||||
|
{ "btn-loading": props.loading },
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -74,6 +101,8 @@ function handleClick() {
|
||||||
@apply px-4;
|
@apply px-4;
|
||||||
@apply outline-0;
|
@apply outline-0;
|
||||||
@apply border-none;
|
@apply border-none;
|
||||||
|
@apply appearance-none;
|
||||||
|
@apply align-middle;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@apply opacity-90;
|
@apply opacity-90;
|
||||||
|
@ -106,7 +135,13 @@ function handleClick() {
|
||||||
|
|
||||||
.btn-block {
|
.btn-block {
|
||||||
@apply w-full;
|
@apply w-full;
|
||||||
@apply block;
|
}
|
||||||
|
|
||||||
|
.btn-loading {
|
||||||
|
@apply cursor-not-allowed;
|
||||||
|
&:hover {
|
||||||
|
@apply opacity-100;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-lg {
|
.btn-lg {
|
||||||
|
|
|
@ -1,21 +1,61 @@
|
||||||
// Vitest Snapshot v1
|
// Vitest Snapshot v1
|
||||||
|
|
||||||
exports[`Button > should render 1`] = `"<button class=\\"btn btn-md btn-default\\"></button>"`;
|
exports[`Button > should render 1`] = `
|
||||||
|
"<button class=\\"btn btn-md btn-default\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content self-center\\"></span>
|
||||||
|
</button>"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Button > should work with block prop 1`] = `"<button class=\\"btn btn-md btn-default btn-block\\"></button>"`;
|
exports[`Button > should work with block prop 1`] = `
|
||||||
|
"<button class=\\"btn btn-md btn-default btn-block\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content self-center\\"></span>
|
||||||
|
</button>"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Button > should work with circle prop 1`] = `"<button class=\\"btn btn-md btn-default btn-circle\\"></button>"`;
|
exports[`Button > should work with circle prop 1`] = `
|
||||||
|
"<button class=\\"btn btn-md btn-default btn-circle\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content self-center\\"></span>
|
||||||
|
</button>"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Button > should work with disabled prop 1`] = `"<button class=\\"btn btn-md btn-default\\" disabled=\\"\\"></button>"`;
|
exports[`Button > should work with disabled prop 1`] = `
|
||||||
|
"<button class=\\"btn btn-md btn-default\\" disabled=\\"\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content self-center\\"></span>
|
||||||
|
</button>"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Button > should work with size prop 1`] = `"<button class=\\"btn btn-lg btn-default\\"></button>"`;
|
exports[`Button > should work with size prop 1`] = `
|
||||||
|
"<button class=\\"btn btn-lg btn-default\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content self-center\\"></span>
|
||||||
|
</button>"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Button > should work with size prop 2`] = `"<button class=\\"btn btn-sm btn-default\\"></button>"`;
|
exports[`Button > should work with size prop 2`] = `
|
||||||
|
"<button class=\\"btn btn-sm btn-default\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content self-center\\"></span>
|
||||||
|
</button>"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Button > should work with size prop 3`] = `"<button class=\\"btn btn-xs btn-default\\"></button>"`;
|
exports[`Button > should work with size prop 3`] = `
|
||||||
|
"<button class=\\"btn btn-xs btn-default\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content self-center\\"></span>
|
||||||
|
</button>"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Button > should work with type prop 1`] = `"<button class=\\"btn btn-md btn-primary\\"></button>"`;
|
exports[`Button > should work with type prop 1`] = `
|
||||||
|
"<button class=\\"btn btn-md btn-primary\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content self-center\\"></span>
|
||||||
|
</button>"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Button > should work with type prop 2`] = `"<button class=\\"btn btn-md btn-secondary\\"></button>"`;
|
exports[`Button > should work with type prop 2`] = `
|
||||||
|
"<button class=\\"btn btn-md btn-secondary\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content self-center\\"></span>
|
||||||
|
</button>"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Button > should work with type prop 3`] = `"<button class=\\"btn btn-md btn-danger\\"></button>"`;
|
exports[`Button > should work with type prop 3`] = `
|
||||||
|
"<button class=\\"btn btn-md btn-danger\\">
|
||||||
|
<!--v-if--><span class=\\"btn-content self-center\\"></span>
|
||||||
|
</button>"
|
||||||
|
`;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex h-full">
|
<div class="flex h-full">
|
||||||
<aside class="navbar h-full" style="background: #fff">
|
<aside class="navbar h-full" style="background: #fff">
|
||||||
<div class="logo flex justify-center py-6">
|
<div class="logo flex justify-center py-6 animate-pulse">
|
||||||
<img :src="logo" style="width: 80px" alt="Halo Logo" />
|
<img :src="logo" style="width: 80px" alt="Halo Logo" />
|
||||||
</div>
|
</div>
|
||||||
<VRoutesMenu :menus="menus" />
|
<VRoutesMenu :menus="menus" />
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
</div>
|
</div>
|
||||||
<h2 class="mb-1">Size:</h2>
|
<h2 class="mb-1">Size:</h2>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<VButton class="mr-2" size="lg" type="secondary"> Large</VButton>
|
<VButton class="mr-2" size="lg" type="secondary">Large</VButton>
|
||||||
<VButton class="mr-2" type="secondary"> Default</VButton>
|
<VButton class="mr-2" type="secondary"> Default</VButton>
|
||||||
<VButton class="mr-2" size="sm" type="secondary"> sm</VButton>
|
<VButton class="mr-2" size="sm" type="secondary"> sm</VButton>
|
||||||
<VButton size="xs" type="secondary"> xs</VButton>
|
<VButton size="xs" type="secondary"> xs</VButton>
|
||||||
|
@ -36,6 +36,46 @@
|
||||||
<VButton class="mr-2" disabled type="secondary"> Secondary</VButton>
|
<VButton class="mr-2" disabled type="secondary"> Secondary</VButton>
|
||||||
<VButton disabled type="danger"> Danger</VButton>
|
<VButton disabled type="danger"> Danger</VButton>
|
||||||
</div>
|
</div>
|
||||||
|
<h2 class="mb-1">Loading:</h2>
|
||||||
|
<div class="mb-3">
|
||||||
|
<VButton class="mr-2" type="primary" :loading="buttonLoading">
|
||||||
|
Primary
|
||||||
|
</VButton>
|
||||||
|
<VButton class="mr-2" type="secondary" :loading="buttonLoading">
|
||||||
|
Secondary
|
||||||
|
</VButton>
|
||||||
|
<VButton class="mr-2" type="danger" :loading="buttonLoading">
|
||||||
|
Danger
|
||||||
|
</VButton>
|
||||||
|
<VButton type="default" :loading="buttonLoading"> Default </VButton>
|
||||||
|
</div>
|
||||||
|
<h2 class="mb-1">Icon:</h2>
|
||||||
|
<div class="mb-3">
|
||||||
|
<VButton class="mr-2" size="lg" type="secondary">
|
||||||
|
<template #icon>
|
||||||
|
<IconSettings />
|
||||||
|
</template>
|
||||||
|
Large
|
||||||
|
</VButton>
|
||||||
|
<VButton class="mr-2" type="secondary">
|
||||||
|
<template #icon>
|
||||||
|
<IconSettings />
|
||||||
|
</template>
|
||||||
|
Default
|
||||||
|
</VButton>
|
||||||
|
<VButton class="mr-2" size="sm" type="secondary">
|
||||||
|
<template #icon>
|
||||||
|
<IconSettings />
|
||||||
|
</template>
|
||||||
|
sm
|
||||||
|
</VButton>
|
||||||
|
<VButton size="xs" type="secondary">
|
||||||
|
<template #icon>
|
||||||
|
<IconSettings />
|
||||||
|
</template>
|
||||||
|
xs
|
||||||
|
</VButton>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="box border-2 rounded p-2 mb-3">
|
<section class="box border-2 rounded p-2 mb-3">
|
||||||
<h1 class="text-xl font-bold mb-2">Input</h1>
|
<h1 class="text-xl font-bold mb-2">Input</h1>
|
||||||
|
@ -158,6 +198,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { IconSettings } from "@/core/icons";
|
||||||
import { FilledLayout } from "../layouts";
|
import { FilledLayout } from "../layouts";
|
||||||
import { VButton } from "@/components/base/button";
|
import { VButton } from "@/components/base/button";
|
||||||
import { VInput } from "@/components/base/input";
|
import { VInput } from "@/components/base/input";
|
||||||
|
@ -167,6 +208,7 @@ import { VRadio, VRadioGroup } from "@/components/base/radio";
|
||||||
import { VCheckbox, VCheckboxGroup } from "@/components/base/checkbox";
|
import { VCheckbox, VCheckboxGroup } from "@/components/base/checkbox";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
const buttonLoading = ref(true);
|
||||||
const inputValue = ref();
|
const inputValue = ref();
|
||||||
const selectValue = ref();
|
const selectValue = ref();
|
||||||
const radioValue = ref("apple");
|
const radioValue = ref("apple");
|
||||||
|
|
Loading…
Reference in New Issue