<Feat>:标签基本功能提交
This commit is contained in:
parent
fc79738ccb
commit
42e6c8c0e6
|
@ -8,6 +8,7 @@ export const tabPageProps = {
|
|||
title: { type: String, default: '' },
|
||||
selected: { type: Boolean, default: false },
|
||||
disabled: { type: Boolean, default: false },
|
||||
removeable: { type: Boolean, default: false }
|
||||
removeable: { type: Boolean, default: false },
|
||||
show: { type: Boolean, default: true }
|
||||
};
|
||||
export type TabPageProps = ExtractPropTypes<typeof tabPageProps>;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import { computed, ComputedRef, Ref, ref, SetupContext, watch } from 'vue';
|
||||
import { TabsProps } from '../tabs.props';
|
||||
|
||||
export function useTabs(
|
||||
props: TabsProps,
|
||||
context: SetupContext
|
||||
): any {
|
||||
|
||||
function setActiveId(tabs: Ref<any[]>, activeId: Ref) {
|
||||
const index = tabs.value.findIndex(tab => tab.show !== false && !activeId.value && !tab.disabled)
|
||||
if (!activeId.value && index !== -1) {
|
||||
activeId.value = tabs.value[index].id
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
setActiveId
|
||||
};
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
import { computed, defineComponent, ref, SetupContext } from 'vue';
|
||||
import { TabsProps, tabsProps } from './tabs.props';
|
||||
import './tabs.css'
|
||||
import { useTabs } from './composition/use-tabs';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FTabs',
|
||||
props: tabsProps,
|
||||
emits: [],
|
||||
setup(props: TabsProps, context: SetupContext) {
|
||||
const hideButtons = ref(false);
|
||||
const hideButtons = ref(true);
|
||||
|
||||
const hideDropDown = ref(false);
|
||||
|
||||
|
@ -20,7 +22,9 @@ export default defineComponent({
|
|||
|
||||
const position = ref(props.position);
|
||||
|
||||
const tabs = ref([]);
|
||||
const tabs = ref([] as any[]);
|
||||
|
||||
const activeId = ref(props.activeId);
|
||||
|
||||
const shouldShowNavFill = computed(() => {
|
||||
fill.value || tabType.value === 'fill';
|
||||
|
@ -28,6 +32,8 @@ export default defineComponent({
|
|||
|
||||
const shouldShowNavPills = computed(() => {});
|
||||
|
||||
const { setActiveId } = useTabs(props, context)
|
||||
|
||||
const tabsHeaderClass = computed(() => ({
|
||||
'farris-tabs-header': true,
|
||||
'farris-tabs-inHead': hasInHeadClass.value,
|
||||
|
@ -64,16 +70,39 @@ export default defineComponent({
|
|||
'flex-row': position.value === 'top' || position.value === 'bottom',
|
||||
'flex-column': position.value === 'left' || position.value === 'right',
|
||||
}));
|
||||
|
||||
let tabPages = context.slots.default && context.slots.default()
|
||||
|
||||
tabPages?.forEach((tabPage: any) => {
|
||||
tabs.value.push(tabPage.props)
|
||||
})
|
||||
|
||||
setActiveId(tabs, activeId)
|
||||
|
||||
const tabsContainerClass = computed(() => ({
|
||||
'farris-tabs': true,
|
||||
'farris-tabs-top': position.value === 'top',
|
||||
'farris-tabs-bottom': position.value === 'bottom',
|
||||
'farris-tabs-left': position.value === 'left',
|
||||
'farris-tabs-right': position.value === 'right'
|
||||
}))
|
||||
|
||||
function getTabClass(tab: any) {
|
||||
return {
|
||||
'nav-item': true,
|
||||
'd-none': !tab.show,
|
||||
'f-state-active': tab.id === activeId,
|
||||
'd-none': tab.show !== undefined ? !tab.show : false,
|
||||
'f-state-active': tab.id === activeId.value,
|
||||
'f-state-disable': tab.disabled,
|
||||
};
|
||||
}
|
||||
|
||||
function getTabPageStyle(tabPage) {
|
||||
const props: any = tabPage.props
|
||||
return {
|
||||
display: props.id === activeId.value ? '' : 'none'
|
||||
}
|
||||
}
|
||||
|
||||
function getTabStyle(tab: any) {
|
||||
return { width: `${tab.tabWidth}px` };
|
||||
}
|
||||
|
@ -81,13 +110,17 @@ export default defineComponent({
|
|||
function getTabNavLinkClass(tab: any) {
|
||||
return {
|
||||
'nav-link': true,
|
||||
'tabs-text-truncate': true,
|
||||
active: tab.id === activeId,
|
||||
// 'tabs-text-truncate': true,
|
||||
active: tab.id === activeId.value,
|
||||
disabled: tab.disabled,
|
||||
};
|
||||
}
|
||||
|
||||
function selectTabByIndex($event: Event, targetTabId: string) {}
|
||||
function selectTabByIndex($event: Event, targetTabId: string) {
|
||||
activeId.value = targetTabId
|
||||
$event.preventDefault();
|
||||
$event.stopPropagation();
|
||||
}
|
||||
|
||||
function getTabTextClass(tab: any) {
|
||||
return {
|
||||
|
@ -97,33 +130,52 @@ export default defineComponent({
|
|||
};
|
||||
}
|
||||
|
||||
function removeTab($event: Event, targetTabId: string) {
|
||||
tabs.value = tabs.value.filter(tab => tab.id !== targetTabId)
|
||||
tabPages = tabPages?.filter(tabPage => (tabPage.props as any).id !== targetTabId)
|
||||
if (activeId.value === targetTabId) {
|
||||
activeId.value = ''
|
||||
setActiveId(tabs, activeId)
|
||||
}
|
||||
$event.preventDefault();
|
||||
$event.stopPropagation();
|
||||
}
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<>
|
||||
<div class={tabsHeaderClass.value}>
|
||||
<div class="farris-tabs-title scroll-tabs" style={tabsTitleStyle.value}>
|
||||
<button type="button" class={tabsTitleButtonClass.value}></button>
|
||||
<div class={tabParentClass.value} style="width:100%">
|
||||
<ul class={tabContainerClass.value}>
|
||||
{tabs.value.forEach((tab: any, tabIndex) => {
|
||||
return (
|
||||
<li class={getTabClass(tab)} style={getTabStyle(tab)}>
|
||||
<a class={getTabNavLinkClass(tab)} onClick={($event) => selectTabByIndex($event, tab.id)}>
|
||||
<span class={getTabTextClass(tab)}>{tab.title}</span>
|
||||
{tab.removeable && (
|
||||
<span class="st-drop-close">
|
||||
<i class="f-icon f-icon-close"></i>
|
||||
</span>
|
||||
)}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
<div class={tabsContainerClass.value}>
|
||||
<div class={tabsHeaderClass.value}>
|
||||
<div class="farris-tabs-title scroll-tabs" style={tabsTitleStyle.value}>
|
||||
<button type="button" class={tabsTitleButtonClass.value}></button>
|
||||
<div class={tabParentClass.value} style="width:100%">
|
||||
<ul class={tabContainerClass.value}>
|
||||
{tabs.value.map((tab: any) => {
|
||||
return (
|
||||
<li class={getTabClass(tab)} style={getTabStyle(tab)}>
|
||||
<a class={getTabNavLinkClass(tab)} onClick={($event) => selectTabByIndex($event, tab.id)}>
|
||||
<span class={getTabTextClass(tab)}>{tab.title}</span>
|
||||
{tab.removeable && (
|
||||
<span class="st-drop-close" onClick={($event) => removeTab($event, tab.id)}>
|
||||
<i class="f-icon f-icon-close"></i>
|
||||
</span>
|
||||
)}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="farris-tabs-content">
|
||||
{
|
||||
tabPages?.map(tabPage => {
|
||||
return <div class="farris-tab-page" style={getTabPageStyle(tabPage)}>{tabPage}</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{context.slots.default && context.slots.default()}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
.farris-tabs {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #000000d9;
|
||||
font-size: 14px;
|
||||
font-variant: tabular-nums;
|
||||
line-height: 1.5715;
|
||||
list-style: none;
|
||||
font-feature-settings: "tnum";
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.farris-tabs.farris-tabs-top {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.farris-tabs.farris-tabs-top .farris-tabs-header{
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.farris-tabs.farris-tabs-bottom {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.farris-tabs.farris-tabs-left {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.farris-tabs.farris-tabs-right {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.farris-tabs-header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.farris-tabs-header .nav-item {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
background: transparent;
|
||||
border: 1px solid #ddd;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
margin-right: 30px;
|
||||
line-height: 20px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.farris-tabs-header .nav-item.f-state-active {
|
||||
border-bottom: 1px solid #1890ff;
|
||||
}
|
||||
|
||||
.farris-tabs-header .nav-item .nav-link {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.farris-tabs-header .nav-item.f-state-active .nav-link {
|
||||
color: #1890ff;
|
||||
text-shadow: 0 0 .25px #f1f1f1;
|
||||
}
|
||||
|
||||
.farris-tabs-header .nav-item.f-state-disable {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.farris-tabs-content {
|
||||
flex: auto;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.farris-tabs-content .farris-tab-page {
|
||||
flex: none;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ export const tabsProps = {
|
|||
searchBoxVisible: { type: Boolean, default: true },
|
||||
titleWidth: { type: Number, default: 0 },
|
||||
customClass: { type: String, default: '' },
|
||||
activeId: { type: String }
|
||||
};
|
||||
|
||||
export type TabsProps = ExtractPropTypes<typeof tabsProps>;
|
||||
|
|
|
@ -5,6 +5,7 @@ import { ref } from "vue";
|
|||
import HelloWorld from './components/hello-world.vue';
|
||||
import ButtonEdit from "../components/button-edit/src/button-edit.component";
|
||||
import Avatar from './components/avatar.vue';
|
||||
import Tabs from './components/tabs.vue'
|
||||
|
||||
const canEdit = ref(true);
|
||||
const canAutoComplete = ref(false);
|
||||
|
@ -27,6 +28,7 @@ const canAutoComplete = ref(false);
|
|||
<HelloWorld msg="Vite + Vue" />
|
||||
<ButtonEdit :editable="canEdit" :auto-complete="canAutoComplete" :enable-clear="true"></ButtonEdit>
|
||||
<Avatar></Avatar>
|
||||
<Tabs />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
import FTab from '../../components/tabs/src/tabs.component'
|
||||
import FTabPage from '../../components/tabs/src/components/tab-page.component'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FTab>
|
||||
<FTabPage id="Tab0" title="Tab0" :show="false">Content of Tab Page 0</FTabPage>
|
||||
<FTabPage id="Tab1" title="Tab1" :removeable="true">Content of Tab Page 1</FTabPage>
|
||||
<FTabPage id="Tab2" title="Tab2" :disabled="true" :removeable="true">Content of Tab Page 2</FTabPage>
|
||||
<FTabPage id="Tab3" title="Tab3" :removeable="true">Content of Tab Page 3</FTabPage>
|
||||
</FTab>
|
||||
</template>
|
Loading…
Reference in New Issue