mirror of https://github.com/halo-dev/halo
parent
2bb7a1e963
commit
1e350ecad4
|
@ -1,5 +1,25 @@
|
||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup>
|
||||||
|
import { computed, inject } from "vue";
|
||||||
|
import type { ComputedRef } from "vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const activeId = inject<ComputedRef<string | number | undefined>>("activeId");
|
||||||
|
|
||||||
|
const isActive = computed(() => {
|
||||||
|
return activeId?.value === props.id;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>tab item</div>
|
<div v-if="isActive">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|
|
@ -3,11 +3,11 @@ import { VTabbar } from "./index";
|
||||||
|
|
||||||
function initState() {
|
function initState() {
|
||||||
return {
|
return {
|
||||||
active: "johnniang",
|
activeId: "johnniang",
|
||||||
items: [
|
items: [
|
||||||
{ label: "Ryan Wang", value: "ryanwang" },
|
{ label: "Ryan Wang", id: "ryanwang" },
|
||||||
{ label: "JohnNiang", value: "johnniang" },
|
{ label: "JohnNiang", id: "johnniang" },
|
||||||
{ label: "guqing", value: "guqing" },
|
{ label: "guqing", id: "guqing" },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -16,20 +16,20 @@ function initState() {
|
||||||
<Story title="Tabbar" :init-state="initState">
|
<Story title="Tabbar" :init-state="initState">
|
||||||
<template #default="{ state }">
|
<template #default="{ state }">
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<VTabbar :items="state.items" v-model:active="state.active" />
|
<VTabbar :items="state.items" v-model:activeId="state.activeId" />
|
||||||
</div>
|
</div>
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<VTabbar
|
<VTabbar
|
||||||
type="pills"
|
type="pills"
|
||||||
:items="state.items"
|
:items="state.items"
|
||||||
v-model:active="state.active"
|
v-model:activeId="state.activeId"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<VTabbar
|
<VTabbar
|
||||||
type="outline"
|
type="outline"
|
||||||
:items="state.items"
|
:items="state.items"
|
||||||
v-model:active="state.active"
|
v-model:activeId="state.activeId"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { computed } from "vue";
|
||||||
import type { Type } from "./interface";
|
import type { Type } from "./interface";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
active: {
|
activeId: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
},
|
},
|
||||||
items: {
|
items: {
|
||||||
|
@ -14,9 +14,9 @@ const props = defineProps({
|
||||||
type: String as PropType<Type>,
|
type: String as PropType<Type>,
|
||||||
default: "default",
|
default: "default",
|
||||||
},
|
},
|
||||||
valueKey: {
|
idKey: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "value",
|
default: "id",
|
||||||
},
|
},
|
||||||
labelKey: {
|
labelKey: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -24,15 +24,15 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["update:active", "change"]);
|
const emit = defineEmits(["update:activeId", "change"]);
|
||||||
|
|
||||||
const classes = computed(() => {
|
const classes = computed(() => {
|
||||||
return [`tabbar-${props.type}`];
|
return [`tabbar-${props.type}`];
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleChange = (value: number | string) => {
|
const handleChange = (id: number | string) => {
|
||||||
emit("update:active", value);
|
emit("update:activeId", id);
|
||||||
emit("change", value);
|
emit("change", id);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
@ -42,8 +42,8 @@ const handleChange = (value: number | string) => {
|
||||||
v-for="(item, index) in items"
|
v-for="(item, index) in items"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="tabbar-item"
|
class="tabbar-item"
|
||||||
:class="{ 'tabbar-item-active': item[valueKey] === active }"
|
:class="{ 'tabbar-item-active': item[idKey] === activeId }"
|
||||||
@click="handleChange(item[valueKey])"
|
@click="handleChange(item[idKey])"
|
||||||
>
|
>
|
||||||
<div v-if="item.icon" class="tabbar-item-icon">
|
<div v-if="item.icon" class="tabbar-item-icon">
|
||||||
<component :is="item.icon" />
|
<component :is="item.icon" />
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { VTabs, VTabItem } from "./index";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Story title="Tabs" :init-state="() => ({ activeId: 'ryanwang' })">
|
||||||
|
<template #default="{ state }">
|
||||||
|
<div class="p-3">
|
||||||
|
<VTabs v-model:activeId="state.activeId">
|
||||||
|
<VTabItem label="JohnNiang" id="johnniang">
|
||||||
|
This is JohnNiang's Item
|
||||||
|
</VTabItem>
|
||||||
|
<VTabItem label="Ryan Wang" id="ryanwang">
|
||||||
|
This is Ryan Wang's Item
|
||||||
|
</VTabItem>
|
||||||
|
<VTabItem label="guqing" id="guqing">
|
||||||
|
This is guqing's Item
|
||||||
|
</VTabItem>
|
||||||
|
</VTabs>
|
||||||
|
</div>
|
||||||
|
<div class="p-3">
|
||||||
|
<VTabs v-model:activeId="state.activeId" type="pills">
|
||||||
|
<VTabItem label="JohnNiang" id="johnniang">
|
||||||
|
This is JohnNiang's Item
|
||||||
|
</VTabItem>
|
||||||
|
<VTabItem label="Ryan Wang" id="ryanwang">
|
||||||
|
This is Ryan Wang's Item
|
||||||
|
</VTabItem>
|
||||||
|
<VTabItem label="guqing" id="guqing">
|
||||||
|
This is guqing's Item
|
||||||
|
</VTabItem>
|
||||||
|
</VTabs>
|
||||||
|
</div>
|
||||||
|
<div class="p-3">
|
||||||
|
<VTabs v-model:activeId="state.activeId" type="outline">
|
||||||
|
<VTabItem label="JohnNiang" id="johnniang">
|
||||||
|
This is JohnNiang's Item
|
||||||
|
</VTabItem>
|
||||||
|
<VTabItem label="Ryan Wang" id="ryanwang">
|
||||||
|
This is Ryan Wang's Item
|
||||||
|
</VTabItem>
|
||||||
|
<VTabItem label="guqing" id="guqing">
|
||||||
|
This is guqing's Item
|
||||||
|
</VTabItem>
|
||||||
|
</VTabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Story>
|
||||||
|
</template>
|
|
@ -1,5 +1,63 @@
|
||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup>
|
||||||
|
import { computed, provide, useSlots } from "vue";
|
||||||
|
import type { PropType, ComputedRef } from "vue";
|
||||||
|
import { VTabbar } from "./index";
|
||||||
|
import type { Type } from "@/components/base/tabs/interface";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
activeId: {
|
||||||
|
type: [Number, String],
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String as PropType<Type>,
|
||||||
|
default: "default",
|
||||||
|
},
|
||||||
|
idKey: {
|
||||||
|
type: String,
|
||||||
|
default: "id",
|
||||||
|
},
|
||||||
|
labelKey: {
|
||||||
|
type: String,
|
||||||
|
default: "label",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
provide<ComputedRef<string | number | undefined>>(
|
||||||
|
"activeId",
|
||||||
|
computed(() => props.activeId)
|
||||||
|
);
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:activeId", "change"]);
|
||||||
|
|
||||||
|
const slots = useSlots();
|
||||||
|
|
||||||
|
const tabItems = computed(() => {
|
||||||
|
return slots.default?.().map(({ props: slotProps }) => {
|
||||||
|
return {
|
||||||
|
id: slotProps?.[props.idKey],
|
||||||
|
label: slotProps?.[props.labelKey],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleChange = (id: string | number) => {
|
||||||
|
emit("update:activeId", id);
|
||||||
|
emit("change", id);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>tabs</div>
|
<div class="tabs-wrapper">
|
||||||
|
<div class="tabs-bar-wrapper">
|
||||||
|
<VTabbar
|
||||||
|
:activeId="activeId"
|
||||||
|
:items="tabItems"
|
||||||
|
:type="type"
|
||||||
|
@change="handleChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="tabs-items-wrapper">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|
Loading…
Reference in New Issue