mirror of https://github.com/halo-dev/halo-admin
parent
db32465a04
commit
aa861c3783
|
@ -11,6 +11,12 @@ body {
|
|||
overflow-y: overlay;
|
||||
background: #eff4f9;
|
||||
}
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track-piece {
|
||||
background-color: #f8f8f8;
|
||||
-webkit-border-radius: 2em;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<script lang="ts" setup></script>
|
||||
<template>
|
||||
<div>tab item</div>
|
||||
</template>
|
||||
<style lang="scss"></style>
|
|
@ -0,0 +1,37 @@
|
|||
<script lang="ts" setup>
|
||||
import { VTabbar } from "./index";
|
||||
|
||||
function initState() {
|
||||
return {
|
||||
active: "johnniang",
|
||||
items: [
|
||||
{ label: "Ryan Wang", value: "ryanwang" },
|
||||
{ label: "JohnNiang", value: "johnniang" },
|
||||
{ label: "guqing", value: "guqing" },
|
||||
],
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<Story title="Tabbar" :init-state="initState">
|
||||
<template #default="{ state }">
|
||||
<div class="p-3">
|
||||
<VTabbar :items="state.items" v-model:active="state.active" />
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<VTabbar
|
||||
type="pills"
|
||||
:items="state.items"
|
||||
v-model:active="state.active"
|
||||
/>
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<VTabbar
|
||||
type="outline"
|
||||
:items="state.items"
|
||||
v-model:active="state.active"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</Story>
|
||||
</template>
|
|
@ -0,0 +1,159 @@
|
|||
<script lang="ts" setup>
|
||||
import type { PropType } from "vue";
|
||||
import { computed } from "vue";
|
||||
import type { Type } from "./interface";
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
type: [Number, String],
|
||||
},
|
||||
items: {
|
||||
type: Object as PropType<Array<Record<string, string>>>,
|
||||
},
|
||||
type: {
|
||||
type: String as PropType<Type>,
|
||||
default: "default",
|
||||
},
|
||||
valueKey: {
|
||||
type: String,
|
||||
default: "value",
|
||||
},
|
||||
labelKey: {
|
||||
type: String,
|
||||
default: "label",
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:active", "change"]);
|
||||
|
||||
const classes = computed(() => {
|
||||
return [`tabbar-${props.type}`];
|
||||
});
|
||||
|
||||
const handleChange = (value: number | string) => {
|
||||
emit("update:active", value);
|
||||
emit("change", value);
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="tabbar-wrapper" :class="classes">
|
||||
<div class="tabbar-items">
|
||||
<div
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
class="tabbar-item"
|
||||
:class="{ 'tabbar-item-active': item[valueKey] === active }"
|
||||
@click="handleChange(item[valueKey])"
|
||||
>
|
||||
<div v-if="item.icon" class="tabbar-item-icon">
|
||||
<component :is="item.icon" />
|
||||
</div>
|
||||
<div class="tabbar-item-label">
|
||||
{{ item[labelKey] }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
.tabbar-wrapper {
|
||||
.tabbar-items {
|
||||
@apply flex;
|
||||
@apply items-center;
|
||||
}
|
||||
|
||||
.tabbar-item {
|
||||
@apply flex;
|
||||
@apply cursor-pointer;
|
||||
@apply self-center;
|
||||
@apply transition-all;
|
||||
@apply text-base;
|
||||
@apply w-full;
|
||||
@apply justify-center;
|
||||
|
||||
.tabbar-item-label,
|
||||
.tabbar-item-icon {
|
||||
@apply self-center;
|
||||
}
|
||||
|
||||
.tabbar-item-icon {
|
||||
@apply mr-2;
|
||||
}
|
||||
}
|
||||
|
||||
&.tabbar-default {
|
||||
border-bottom-width: 2px;
|
||||
@apply border-b-gray-100;
|
||||
|
||||
.tabbar-items {
|
||||
margin-bottom: -2px;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.tabbar-item {
|
||||
@apply h-10;
|
||||
@apply px-5;
|
||||
@apply py-1;
|
||||
@apply border-b-gray-100;
|
||||
|
||||
border-bottom-width: 2px;
|
||||
|
||||
&.tabbar-item-active {
|
||||
color: #0e1731;
|
||||
border-bottom-color: #0e1731;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.tabbar-pills {
|
||||
.tabbar-items {
|
||||
@apply gap-1;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.tabbar-item {
|
||||
@apply h-10;
|
||||
@apply px-9;
|
||||
@apply py-1;
|
||||
@apply opacity-70;
|
||||
border-radius: 4px;
|
||||
|
||||
&.tabbar-item-active {
|
||||
@apply bg-gray-100;
|
||||
@apply opacity-100;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@apply bg-gray-100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.tabbar-outline {
|
||||
@apply p-1;
|
||||
@apply bg-gray-100;
|
||||
border-radius: 4px;
|
||||
|
||||
.tabbar-items {
|
||||
@apply gap-1;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.tabbar-item {
|
||||
@apply h-10;
|
||||
@apply px-9;
|
||||
@apply py-1;
|
||||
@apply opacity-70;
|
||||
border-radius: 4px;
|
||||
|
||||
&.tabbar-item-active {
|
||||
@apply bg-white;
|
||||
@apply opacity-100;
|
||||
@apply shadow-sm;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@apply bg-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,5 @@
|
|||
<script lang="ts" setup></script>
|
||||
<template>
|
||||
<div>tabs</div>
|
||||
</template>
|
||||
<style lang="scss"></style>
|
|
@ -0,0 +1,8 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { VTabItem } from "../index";
|
||||
|
||||
describe("TabItem", () => {
|
||||
it("should render", () => {
|
||||
expect(VTabItem).toBeDefined();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { VTabbar } from "../index";
|
||||
|
||||
describe("Tabbar", () => {
|
||||
it("should render", () => {
|
||||
expect(VTabbar).toBeDefined();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { VTabs } from "../index";
|
||||
|
||||
describe("Tabs", () => {
|
||||
it("should render", () => {
|
||||
expect(VTabs).toBeDefined();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
export { default as VTabs } from "./Tabs.vue";
|
||||
export { default as VTabItem } from "./TabItem.vue";
|
||||
export { default as VTabbar } from "./Tabbar.vue";
|
|
@ -0,0 +1 @@
|
|||
export type Type = "default" | "pills" | "outline";
|
Loading…
Reference in New Issue