refactor: tabs #6288
parent
6240ab2885
commit
47385347ee
|
|
@ -2,7 +2,7 @@
|
||||||
category: Components
|
category: Components
|
||||||
type: Data Display
|
type: Data Display
|
||||||
title: Tabs
|
title: Tabs
|
||||||
cover: https://gw.alipayobjects.com/zos/antfincdn/lkI2hNEDr2V/Tabs.svg
|
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*72NDQqXkyOEAAAAAAAAAAAAADrJ8AQ/original
|
||||||
---
|
---
|
||||||
|
|
||||||
Tabs make it easy to switch between different views.
|
Tabs make it easy to switch between different views.
|
||||||
|
|
@ -25,7 +25,7 @@ Ant Design has 3 types of Tabs for different situations.
|
||||||
| animated | Whether to change tabs with animation. Only works while tabPosition=`"top"` \| `"bottom"` | boolean \| {inkBar:boolean, tabPane:boolean} | `true`, `false` when `type="card"` | |
|
| animated | Whether to change tabs with animation. Only works while tabPosition=`"top"` \| `"bottom"` | boolean \| {inkBar:boolean, tabPane:boolean} | `true`, `false` when `type="card"` | |
|
||||||
| destroyInactiveTabPane | Whether destroy inactive TabPane when change tab | boolean | false | |
|
| destroyInactiveTabPane | Whether destroy inactive TabPane when change tab | boolean | false | |
|
||||||
| hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | `false` | } |
|
| hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | `false` | } |
|
||||||
| size | preset tab bar size | `large` \| `default` \| `small` | `default` | |
|
| size | preset tab bar size | `large` \| `middle` \| `small` | `middle` | |
|
||||||
| tabBarGutter | The gap between tabs | number | - | |
|
| tabBarGutter | The gap between tabs | number | - | |
|
||||||
| tabBarStyle | Tab bar style object | CSSProperties | - | |
|
| tabBarStyle | Tab bar style object | CSSProperties | - | |
|
||||||
| tabPosition | Position of tabs | `top` \| `right` \| `bottom` \| `left` | `top` | |
|
| tabPosition | Position of tabs | `top` \| `right` \| `bottom` \| `left` | `top` | |
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ category: Components
|
||||||
subtitle: 标签页
|
subtitle: 标签页
|
||||||
type: 数据展示
|
type: 数据展示
|
||||||
title: Tabs
|
title: Tabs
|
||||||
cover: https://gw.alipayobjects.com/zos/antfincdn/lkI2hNEDr2V/Tabs.svg
|
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*72NDQqXkyOEAAAAAAAAAAAAADrJ8AQ/original
|
||||||
---
|
---
|
||||||
|
|
||||||
选项卡切换组件。
|
选项卡切换组件。
|
||||||
|
|
@ -29,7 +29,7 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
|
||||||
| centered | 标签居中展示 | boolean | false | 3.0 | |
|
| centered | 标签居中展示 | boolean | false | 3.0 | |
|
||||||
| destroyInactiveTabPane | 被隐藏时是否销毁 DOM 结构 | boolean | false | | |
|
| destroyInactiveTabPane | 被隐藏时是否销毁 DOM 结构 | boolean | false | | |
|
||||||
| hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false | | |
|
| hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false | | |
|
||||||
| size | 大小,提供 `large` `default` 和 `small` 三种大小 | string | `default` | | |
|
| size | 大小,提供 `large` `middle` 和 `small` 三种大小 | string | `middle` | | |
|
||||||
| tabBarGutter | tabs 之间的间隙 | number | 无 | | |
|
| tabBarGutter | tabs 之间的间隙 | number | 无 | | |
|
||||||
| tabBarStyle | tab bar 的样式对象 | CSSProperties | - | | |
|
| tabBarStyle | tab bar 的样式对象 | CSSProperties | - | | |
|
||||||
| tabPosition | 页签位置,可选值有 `top` `right` `bottom` `left` | string | `top` | | |
|
| tabPosition | 页签位置,可选值有 `top` `right` `bottom` `left` | string | `top` | | |
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import Dropdown from '../../../vc-dropdown';
|
||||||
import type { Tab, TabsLocale, EditableConfig } from '../interface';
|
import type { Tab, TabsLocale, EditableConfig } from '../interface';
|
||||||
import AddButton from './AddButton';
|
import AddButton from './AddButton';
|
||||||
import type { Key } from '../../../_util/type';
|
import type { Key } from '../../../_util/type';
|
||||||
|
import { functionType } from '../../../_util/type';
|
||||||
import KeyCode from '../../../_util/KeyCode';
|
import KeyCode from '../../../_util/KeyCode';
|
||||||
import type { CSSProperties, ExtractPropTypes, PropType } from 'vue';
|
import type { CSSProperties, ExtractPropTypes, PropType } from 'vue';
|
||||||
import classNames from '../../../_util/classNames';
|
import classNames from '../../../_util/classNames';
|
||||||
|
|
@ -10,6 +11,7 @@ import { defineComponent, watch, computed, onMounted } from 'vue';
|
||||||
import PropTypes from '../../../_util/vue-types';
|
import PropTypes from '../../../_util/vue-types';
|
||||||
import useState from '../../../_util/hooks/useState';
|
import useState from '../../../_util/hooks/useState';
|
||||||
import EllipsisOutlined from '@ant-design/icons-vue/EllipsisOutlined';
|
import EllipsisOutlined from '@ant-design/icons-vue/EllipsisOutlined';
|
||||||
|
import { useProvideOverride } from '../../../menu/src/OverrideContext';
|
||||||
|
|
||||||
export const operationNodeProps = {
|
export const operationNodeProps = {
|
||||||
prefixCls: { type: String },
|
prefixCls: { type: String },
|
||||||
|
|
@ -25,6 +27,10 @@ export const operationNodeProps = {
|
||||||
locale: { type: Object as PropType<TabsLocale>, default: undefined as TabsLocale },
|
locale: { type: Object as PropType<TabsLocale>, default: undefined as TabsLocale },
|
||||||
removeAriaLabel: String,
|
removeAriaLabel: String,
|
||||||
onTabClick: { type: Function as PropType<(key: Key, e: MouseEvent | KeyboardEvent) => void> },
|
onTabClick: { type: Function as PropType<(key: Key, e: MouseEvent | KeyboardEvent) => void> },
|
||||||
|
popupClassName: String,
|
||||||
|
getPopupContainer: functionType<
|
||||||
|
((triggerNode?: HTMLElement | undefined) => HTMLElement) | undefined
|
||||||
|
>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OperationNodeProps = Partial<ExtractPropTypes<typeof operationNodeProps>>;
|
export type OperationNodeProps = Partial<ExtractPropTypes<typeof operationNodeProps>>;
|
||||||
|
|
@ -117,7 +123,7 @@ export default defineComponent({
|
||||||
setSelectedKey(null);
|
setSelectedKey(null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
useProvideOverride({});
|
||||||
return () => {
|
return () => {
|
||||||
const {
|
const {
|
||||||
prefixCls,
|
prefixCls,
|
||||||
|
|
@ -131,6 +137,7 @@ export default defineComponent({
|
||||||
tabBarGutter,
|
tabBarGutter,
|
||||||
rtl,
|
rtl,
|
||||||
onTabClick,
|
onTabClick,
|
||||||
|
popupClassName,
|
||||||
} = props;
|
} = props;
|
||||||
const dropdownPrefix = `${prefixCls}-dropdown`;
|
const dropdownPrefix = `${prefixCls}-dropdown`;
|
||||||
|
|
||||||
|
|
@ -147,17 +154,19 @@ export default defineComponent({
|
||||||
|
|
||||||
const overlayClassName = classNames({
|
const overlayClassName = classNames({
|
||||||
[`${dropdownPrefix}-rtl`]: rtl,
|
[`${dropdownPrefix}-rtl`]: rtl,
|
||||||
|
[`${popupClassName}`]: true,
|
||||||
});
|
});
|
||||||
const moreNode = mobile ? null : (
|
const moreNode = mobile ? null : (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
prefixCls={dropdownPrefix}
|
prefixCls={dropdownPrefix}
|
||||||
trigger={['hover']}
|
trigger={['hover']}
|
||||||
visible={open.value}
|
open={open.value}
|
||||||
transitionName={moreTransitionName}
|
transitionName={moreTransitionName}
|
||||||
onVisibleChange={setOpen}
|
onOpenChange={setOpen}
|
||||||
overlayClassName={overlayClassName}
|
overlayClassName={overlayClassName}
|
||||||
mouseEnterDelay={0.1}
|
mouseEnterDelay={0.1}
|
||||||
mouseLeaveDelay={0.1}
|
mouseLeaveDelay={0.1}
|
||||||
|
getPopupContainer={props.getPopupContainer}
|
||||||
v-slots={{
|
v-slots={{
|
||||||
overlay: () => (
|
overlay: () => (
|
||||||
<Menu
|
<Menu
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import { useInjectTabs } from '../TabContext';
|
||||||
import useTouchMove from '../hooks/useTouchMove';
|
import useTouchMove from '../hooks/useTouchMove';
|
||||||
import AddButton from './AddButton';
|
import AddButton from './AddButton';
|
||||||
import type { Key } from '../../../_util/type';
|
import type { Key } from '../../../_util/type';
|
||||||
|
import { objectType, functionType } from '../../../_util/type';
|
||||||
import type { ExtractPropTypes, PropType, CSSProperties } from 'vue';
|
import type { ExtractPropTypes, PropType, CSSProperties } from 'vue';
|
||||||
import { onBeforeUnmount, defineComponent, ref, watch, watchEffect, computed } from 'vue';
|
import { onBeforeUnmount, defineComponent, ref, watch, watchEffect, computed } from 'vue';
|
||||||
import PropTypes from '../../../_util/vue-types';
|
import PropTypes from '../../../_util/vue-types';
|
||||||
|
|
@ -36,14 +37,18 @@ export const tabNavListProps = () => {
|
||||||
tabPosition: { type: String as PropType<TabPosition> },
|
tabPosition: { type: String as PropType<TabPosition> },
|
||||||
activeKey: { type: [String, Number] },
|
activeKey: { type: [String, Number] },
|
||||||
rtl: { type: Boolean },
|
rtl: { type: Boolean },
|
||||||
animated: { type: Object as PropType<AnimatedConfig>, default: undefined as AnimatedConfig },
|
animated: objectType<AnimatedConfig>(),
|
||||||
editable: { type: Object as PropType<EditableConfig> },
|
editable: objectType<EditableConfig>(),
|
||||||
moreIcon: PropTypes.any,
|
moreIcon: PropTypes.any,
|
||||||
moreTransitionName: { type: String },
|
moreTransitionName: { type: String },
|
||||||
mobile: { type: Boolean },
|
mobile: { type: Boolean },
|
||||||
tabBarGutter: { type: Number },
|
tabBarGutter: { type: Number },
|
||||||
renderTabBar: { type: Function as PropType<RenderTabBar> },
|
renderTabBar: { type: Function as PropType<RenderTabBar> },
|
||||||
locale: { type: Object as PropType<TabsLocale>, default: undefined as TabsLocale },
|
locale: objectType<TabsLocale>(),
|
||||||
|
popupClassName: String,
|
||||||
|
getPopupContainer: functionType<
|
||||||
|
((triggerNode?: HTMLElement | undefined) => HTMLElement) | undefined
|
||||||
|
>(),
|
||||||
onTabClick: {
|
onTabClick: {
|
||||||
type: Function as PropType<(activeKey: Key, e: MouseEvent | KeyboardEvent) => void>,
|
type: Function as PropType<(activeKey: Key, e: MouseEvent | KeyboardEvent) => void>,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import type {
|
||||||
OnTabScroll,
|
OnTabScroll,
|
||||||
Tab,
|
Tab,
|
||||||
} from './interface';
|
} from './interface';
|
||||||
import type { CSSProperties, PropType, ExtractPropTypes } from 'vue';
|
import type { CSSProperties, ExtractPropTypes } from 'vue';
|
||||||
import { defineComponent, computed, onMounted, watchEffect, camelize } from 'vue';
|
import { defineComponent, computed, onMounted, watchEffect, camelize } from 'vue';
|
||||||
import { flattenChildren, initDefaultProps, isValidElement } from '../../_util/props-util';
|
import { flattenChildren, initDefaultProps, isValidElement } from '../../_util/props-util';
|
||||||
import useConfigInject from '../../config-provider/hooks/useConfigInject';
|
import useConfigInject from '../../config-provider/hooks/useConfigInject';
|
||||||
|
|
@ -24,6 +24,14 @@ import devWarning from '../../vc-util/devWarning';
|
||||||
import type { SizeType } from '../../config-provider';
|
import type { SizeType } from '../../config-provider';
|
||||||
import { useProvideTabs } from './TabContext';
|
import { useProvideTabs } from './TabContext';
|
||||||
import type { Key } from '../../_util/type';
|
import type { Key } from '../../_util/type';
|
||||||
|
import {
|
||||||
|
arrayType,
|
||||||
|
stringType,
|
||||||
|
someType,
|
||||||
|
functionType,
|
||||||
|
objectType,
|
||||||
|
booleanType,
|
||||||
|
} from '../../_util/type';
|
||||||
import pick from 'lodash-es/pick';
|
import pick from 'lodash-es/pick';
|
||||||
import PropTypes from '../../_util/vue-types';
|
import PropTypes from '../../_util/vue-types';
|
||||||
import type { MouseEventHandler } from '../../_util/EventInterface';
|
import type { MouseEventHandler } from '../../_util/EventInterface';
|
||||||
|
|
@ -39,36 +47,33 @@ export const tabsProps = () => {
|
||||||
return {
|
return {
|
||||||
prefixCls: { type: String },
|
prefixCls: { type: String },
|
||||||
id: { type: String },
|
id: { type: String },
|
||||||
|
popupClassName: String,
|
||||||
|
getPopupContainer: functionType<
|
||||||
|
((triggerNode?: HTMLElement | undefined) => HTMLElement) | undefined
|
||||||
|
>(),
|
||||||
activeKey: { type: [String, Number] },
|
activeKey: { type: [String, Number] },
|
||||||
defaultActiveKey: { type: [String, Number] },
|
defaultActiveKey: { type: [String, Number] },
|
||||||
direction: { type: String as PropType<'ltr' | 'rtl'> },
|
direction: stringType<'ltr' | 'rtl'>(),
|
||||||
animated: { type: [Boolean, Object] as PropType<boolean | AnimatedConfig> },
|
animated: someType<boolean | AnimatedConfig>([Boolean, Object]),
|
||||||
renderTabBar: { type: Function as PropType<RenderTabBar> },
|
renderTabBar: functionType<RenderTabBar>(),
|
||||||
tabBarGutter: { type: Number },
|
tabBarGutter: { type: Number },
|
||||||
tabBarStyle: { type: Object as PropType<CSSProperties> },
|
tabBarStyle: objectType<CSSProperties>(),
|
||||||
tabPosition: { type: String as PropType<TabPosition> },
|
tabPosition: stringType<TabPosition>(),
|
||||||
destroyInactiveTabPane: { type: Boolean },
|
destroyInactiveTabPane: booleanType(),
|
||||||
|
|
||||||
hideAdd: Boolean,
|
hideAdd: Boolean,
|
||||||
type: { type: String as PropType<TabsType> },
|
type: stringType<TabsType>(),
|
||||||
size: { type: String as PropType<SizeType> },
|
size: stringType<SizeType>(),
|
||||||
centered: Boolean,
|
centered: Boolean,
|
||||||
onEdit: {
|
onEdit: functionType<(e: MouseEvent | KeyboardEvent | Key, action: 'add' | 'remove') => void>(),
|
||||||
type: Function as PropType<
|
onChange: functionType<(activeKey: Key) => void>(),
|
||||||
(e: MouseEvent | KeyboardEvent | Key, action: 'add' | 'remove') => void
|
onTabClick: functionType<(activeKey: Key, e: KeyboardEvent | MouseEvent) => void>(),
|
||||||
>,
|
onTabScroll: functionType<OnTabScroll>(),
|
||||||
},
|
'onUpdate:activeKey': functionType<(activeKey: Key) => void>(),
|
||||||
onChange: { type: Function as PropType<(activeKey: Key) => void> },
|
|
||||||
onTabClick: {
|
|
||||||
type: Function as PropType<(activeKey: Key, e: KeyboardEvent | MouseEvent) => void>,
|
|
||||||
},
|
|
||||||
onTabScroll: { type: Function as PropType<OnTabScroll> },
|
|
||||||
'onUpdate:activeKey': { type: Function as PropType<(activeKey: Key) => void> },
|
|
||||||
// Accessibility
|
// Accessibility
|
||||||
locale: { type: Object as PropType<TabsLocale>, default: undefined as TabsLocale },
|
locale: objectType<TabsLocale>(),
|
||||||
onPrevClick: Function as PropType<MouseEventHandler>,
|
onPrevClick: functionType<MouseEventHandler>(),
|
||||||
onNextClick: Function as PropType<MouseEventHandler>,
|
onNextClick: functionType<MouseEventHandler>(),
|
||||||
tabBarExtraContent: PropTypes.any,
|
tabBarExtraContent: PropTypes.any,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -126,7 +131,7 @@ const InternalTabs = defineComponent({
|
||||||
tabPane: false,
|
tabPane: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
tabs: { type: Array as PropType<Tab[]> },
|
tabs: arrayType<Tab[]>(),
|
||||||
},
|
},
|
||||||
slots: [
|
slots: [
|
||||||
'tabBarExtraContent',
|
'tabBarExtraContent',
|
||||||
|
|
@ -154,7 +159,10 @@ const InternalTabs = defineComponent({
|
||||||
'Tabs',
|
'Tabs',
|
||||||
'`tabBarExtraContent` slot is deprecated. Please use `rightExtra` slot instead.',
|
'`tabBarExtraContent` slot is deprecated. Please use `rightExtra` slot instead.',
|
||||||
);
|
);
|
||||||
const { prefixCls, direction, size, rootPrefixCls } = useConfigInject('tabs', props);
|
const { prefixCls, direction, size, rootPrefixCls, getPopupContainer } = useConfigInject(
|
||||||
|
'tabs',
|
||||||
|
props,
|
||||||
|
);
|
||||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
const rtl = computed(() => direction.value === 'rtl');
|
const rtl = computed(() => direction.value === 'rtl');
|
||||||
const mergedAnimated = computed<AnimatedConfig>(() => {
|
const mergedAnimated = computed<AnimatedConfig>(() => {
|
||||||
|
|
@ -284,6 +292,8 @@ const InternalTabs = defineComponent({
|
||||||
onTabClick: onInternalTabClick,
|
onTabClick: onInternalTabClick,
|
||||||
onTabScroll,
|
onTabScroll,
|
||||||
style: tabBarStyle,
|
style: tabBarStyle,
|
||||||
|
getPopupContainer: getPopupContainer.value,
|
||||||
|
popupClassName: classNames(props.popupClassName, hashId.value),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (renderTabBar) {
|
if (renderTabBar) {
|
||||||
|
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
|
||||||
|
|
||||||
export const tabsCardStyle:{tabsCardGutter:string}={
|
|
||||||
tabsCardGutter: '2px'
|
|
||||||
}
|
|
||||||
export const genTabscardStyle = (token): CSSObject => {
|
|
||||||
const { componentCls } = token;
|
|
||||||
|
|
||||||
return {
|
|
||||||
[` ${componentCls}-nav,
|
|
||||||
div > ${componentCls}-nav `]: {
|
|
||||||
[`${componentCls}-tab `]: {
|
|
||||||
margin: 0,
|
|
||||||
background: `${token.colorFillAlter}`,
|
|
||||||
padding: `${token.paddingXS}px ${token.padding}px`,
|
|
||||||
border:`${token.lineWidth}px ${token.colorBorder} ${token.lineType} `,
|
|
||||||
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOut} `,
|
|
||||||
|
|
||||||
[`&-active `]: {
|
|
||||||
color: ` ${token.colorInfoActive}`,
|
|
||||||
background: `${token.colorBgContainer}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-ink-bar`]: {
|
|
||||||
visibility: `hidden`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ========================== Top & Bottom ==========================
|
|
||||||
[`&${componentCls}-top,
|
|
||||||
&${componentCls}-bottom`]: {
|
|
||||||
[`${componentCls}-nav,
|
|
||||||
div > ${componentCls}-nav `]: {
|
|
||||||
[` ${componentCls}-tab + ${componentCls}-tab `]: {
|
|
||||||
marginLeft: `${tabsCardStyle.tabsCardGutter} `,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&${componentCls}-top `]: {
|
|
||||||
[`${componentCls}-nav,
|
|
||||||
div > ${componentCls}-nav `]: {
|
|
||||||
[`${componentCls}-tab `]: {
|
|
||||||
borderRadius: ` ${token.radiusBase}px ${token.radiusBase}px 0 0`,
|
|
||||||
[`&-active `]: {
|
|
||||||
borderBottomColor: `${token.colorBgContainer}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[`&${componentCls}-bottom`]: {
|
|
||||||
[`${componentCls}-nav,
|
|
||||||
div > ${componentCls}-nav`]: {
|
|
||||||
[` ${componentCls}-tab `]: {
|
|
||||||
borderRadius: `0 0 ${token.radiusBase}px ${token.radiusBase}px`,
|
|
||||||
|
|
||||||
[` &-active `]: {
|
|
||||||
borderTopColor: `${token.colorBgContainer}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ========================== Left & Right ==========================
|
|
||||||
[`&${componentCls}-left,
|
|
||||||
&${componentCls}-right`]: {
|
|
||||||
[` ${componentCls}-nav,
|
|
||||||
div > ${componentCls}-nav `]: {
|
|
||||||
[` ${componentCls}-tab + ${componentCls}-tab`]: {
|
|
||||||
marginTop: `${tabsCardStyle.tabsCardGutter}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&${componentCls}-left`]: {
|
|
||||||
[` > ${componentCls}-nav,
|
|
||||||
> div > ${componentCls}-nav`]: {
|
|
||||||
[` ${componentCls}-tab`]: {
|
|
||||||
borderRadius: `${token.radiusBase}px 0 0 ${token.radiusBase}px`,
|
|
||||||
|
|
||||||
[` &-active`]: {
|
|
||||||
borderRightColor: `${token.colorBgContainer}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[` &${componentCls}-right `]: {
|
|
||||||
[` ${componentCls}-nav,
|
|
||||||
div > ${componentCls}-nav `]: {
|
|
||||||
[` ${componentCls}-tab `]: {
|
|
||||||
borderRadius: `0 ${token.radiusBase}px ${token.radiusBase}px 0`,
|
|
||||||
|
|
||||||
[` &-active `]: {
|
|
||||||
borderLeftColor:`${token.colorBgContainer}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
|
||||||
import { resetComponent, clearFix } from '../../_style';
|
|
||||||
const dropdownStyle={
|
|
||||||
dropdownVerticalPadding:'5px',
|
|
||||||
itemHoverBg:'#f5f5f5',
|
|
||||||
}
|
|
||||||
export const genTabsDropdownStyle = (token): CSSObject => {
|
|
||||||
return {
|
|
||||||
...resetComponent(token),
|
|
||||||
position: `absolute`,
|
|
||||||
top: `-9999px`,
|
|
||||||
left: `-9999px`,
|
|
||||||
zIndex:` ${token.zIndexPopupBase}`,
|
|
||||||
display: `block`,
|
|
||||||
[` &-hidden`] :{
|
|
||||||
display: `none`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[` &-menu `]:{
|
|
||||||
maxHeight:' 200px',
|
|
||||||
margin: 0,
|
|
||||||
padding: `${token.padding}px 0`,
|
|
||||||
overflowx: 'hidden',
|
|
||||||
overflowY: 'auto',
|
|
||||||
textAlign: 'left',
|
|
||||||
listStyleType: 'none',
|
|
||||||
backgroundColor: ` ${token.colorBgBase}`,
|
|
||||||
backgroundClip: `padding-box`,
|
|
||||||
borderRadius: ` ${token.radiusBase}px`,
|
|
||||||
outline: `none`,
|
|
||||||
boxShadow: `${token.boxShadow}`,
|
|
||||||
|
|
||||||
[`&-item`]: {
|
|
||||||
display: `flex`,
|
|
||||||
alignItems: `center`,
|
|
||||||
minWidth: `120px`,
|
|
||||||
margin: 0,
|
|
||||||
padding: `${dropdownStyle.dropdownVerticalPadding} ${token.paddingSM}px`,
|
|
||||||
overflow: `hidden`,
|
|
||||||
color:` ${token.colorText}`,
|
|
||||||
fontWeight: `normal`,
|
|
||||||
fontSize:` ${token.fontSize}px`,
|
|
||||||
lineHeight: `${token.lineHeight} `,
|
|
||||||
whiteSpace: `nowrap`,
|
|
||||||
textOverflow: `ellipsis`,
|
|
||||||
cursor: `pointer`,
|
|
||||||
transition: `all 0.3s`,
|
|
||||||
|
|
||||||
[` > span`] :{
|
|
||||||
flex: 1,
|
|
||||||
whiteSpace: `nowrap`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[` &-remove `]:{
|
|
||||||
flex: `none`,
|
|
||||||
marginLeft:` ${token.marginSM}px`,
|
|
||||||
color:` ${token.colorTextSecondary}`,
|
|
||||||
fontSize: `${token.fontSizeSM}px`,
|
|
||||||
background: `transparent`,
|
|
||||||
border: 0,
|
|
||||||
cursor: `pointer`,
|
|
||||||
[` &:hover `]:{
|
|
||||||
color:`${token.colorInfoHover}`,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&:hover `]:{
|
|
||||||
background:` ${dropdownStyle.itemHoverBg}`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[` &-disabled `]:{
|
|
||||||
[` &,
|
|
||||||
&:hover`]: {
|
|
||||||
color:` ${token.colorTextDisabled}`,
|
|
||||||
background: `transparent`,
|
|
||||||
cursor: `not-allowed`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
@ -0,0 +1,902 @@
|
||||||
|
import { CSSObject } from '../../_util/cssinjs';
|
||||||
|
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||||
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
|
import { genFocusStyle, resetComponent, textEllipsis } from '../../_style';
|
||||||
|
import genMotionStyle from './motion';
|
||||||
|
|
||||||
|
export interface ComponentToken {
|
||||||
|
zIndexPopup: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TabsToken extends FullToken<'Tabs'> {
|
||||||
|
tabsCardHorizontalPadding: string;
|
||||||
|
tabsCardHeight: number;
|
||||||
|
tabsCardGutter: number;
|
||||||
|
tabsHoverColor: string;
|
||||||
|
tabsActiveColor: string;
|
||||||
|
tabsHorizontalGutter: number;
|
||||||
|
tabsCardHeadBackground: string;
|
||||||
|
dropdownEdgeChildVerticalPadding: number;
|
||||||
|
tabsNavWrapPseudoWidth: number;
|
||||||
|
tabsActiveTextShadow: string;
|
||||||
|
tabsDropdownHeight: number;
|
||||||
|
tabsDropdownWidth: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const genCardStyle: GenerateStyle<TabsToken> = (token: TabsToken): CSSObject => {
|
||||||
|
const {
|
||||||
|
componentCls,
|
||||||
|
tabsCardHorizontalPadding,
|
||||||
|
tabsCardHeadBackground,
|
||||||
|
tabsCardGutter,
|
||||||
|
colorSplit,
|
||||||
|
} = token;
|
||||||
|
return {
|
||||||
|
[`${componentCls}-card`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
margin: 0,
|
||||||
|
padding: tabsCardHorizontalPadding,
|
||||||
|
background: tabsCardHeadBackground,
|
||||||
|
border: `${token.lineWidth}px ${token.lineType} ${colorSplit}`,
|
||||||
|
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-tab-active`]: {
|
||||||
|
color: token.colorPrimary,
|
||||||
|
background: token.colorBgContainer,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-ink-bar`]: {
|
||||||
|
visibility: 'hidden',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// ========================== Top & Bottom ==========================
|
||||||
|
[`&${componentCls}-top, &${componentCls}-bottom`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab + ${componentCls}-tab`]: {
|
||||||
|
marginLeft: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `${tabsCardGutter}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-top`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-tab-active`]: {
|
||||||
|
borderBottomColor: token.colorBgContainer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-bottom`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
borderRadius: `0 0 ${token.borderRadiusLG}px ${token.borderRadiusLG}px`,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-tab-active`]: {
|
||||||
|
borderTopColor: token.colorBgContainer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// ========================== Left & Right ==========================
|
||||||
|
[`&${componentCls}-left, &${componentCls}-right`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab + ${componentCls}-tab`]: {
|
||||||
|
marginTop: `${tabsCardGutter}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-left`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
borderRadius: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `${token.borderRadiusLG}px 0 0 ${token.borderRadiusLG}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-tab-active`]: {
|
||||||
|
borderRightColor: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: token.colorBgContainer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-right`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
borderRadius: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `0 ${token.borderRadiusLG}px ${token.borderRadiusLG}px 0`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-tab-active`]: {
|
||||||
|
borderLeftColor: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: token.colorBgContainer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const genDropdownStyle: GenerateStyle<TabsToken> = (token: TabsToken): CSSObject => {
|
||||||
|
const { componentCls, tabsHoverColor, dropdownEdgeChildVerticalPadding } = token;
|
||||||
|
return {
|
||||||
|
[`${componentCls}-dropdown`]: {
|
||||||
|
...resetComponent(token),
|
||||||
|
|
||||||
|
position: 'absolute',
|
||||||
|
top: -9999,
|
||||||
|
left: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: -9999,
|
||||||
|
},
|
||||||
|
zIndex: token.zIndexPopup,
|
||||||
|
display: 'block',
|
||||||
|
|
||||||
|
'&-hidden': {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-dropdown-menu`]: {
|
||||||
|
maxHeight: token.tabsDropdownHeight,
|
||||||
|
margin: 0,
|
||||||
|
padding: `${dropdownEdgeChildVerticalPadding}px 0`,
|
||||||
|
overflowX: 'hidden',
|
||||||
|
overflowY: 'auto',
|
||||||
|
textAlign: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 'left',
|
||||||
|
},
|
||||||
|
listStyleType: 'none',
|
||||||
|
backgroundColor: token.colorBgContainer,
|
||||||
|
backgroundClip: 'padding-box',
|
||||||
|
borderRadius: token.borderRadiusLG,
|
||||||
|
outline: 'none',
|
||||||
|
boxShadow: token.boxShadowSecondary,
|
||||||
|
|
||||||
|
'&-item': {
|
||||||
|
...textEllipsis,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
minWidth: token.tabsDropdownWidth,
|
||||||
|
margin: 0,
|
||||||
|
padding: `${token.paddingXXS}px ${token.paddingSM}px`,
|
||||||
|
color: token.colorText,
|
||||||
|
fontWeight: 'normal',
|
||||||
|
fontSize: token.fontSize,
|
||||||
|
lineHeight: token.lineHeight,
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: `all ${token.motionDurationSlow}`,
|
||||||
|
|
||||||
|
'> span': {
|
||||||
|
flex: 1,
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
},
|
||||||
|
|
||||||
|
'&-remove': {
|
||||||
|
flex: 'none',
|
||||||
|
marginLeft: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: token.marginSM,
|
||||||
|
},
|
||||||
|
color: token.colorTextDescription,
|
||||||
|
fontSize: token.fontSizeSM,
|
||||||
|
background: 'transparent',
|
||||||
|
border: 0,
|
||||||
|
cursor: 'pointer',
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
color: tabsHoverColor,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
background: token.controlItemBgHover,
|
||||||
|
},
|
||||||
|
|
||||||
|
'&-disabled': {
|
||||||
|
'&, &:hover': {
|
||||||
|
color: token.colorTextDisabled,
|
||||||
|
background: 'transparent',
|
||||||
|
cursor: 'not-allowed',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const genPositionStyle: GenerateStyle<TabsToken> = (token: TabsToken): CSSObject => {
|
||||||
|
const { componentCls, margin, colorSplit } = token;
|
||||||
|
return {
|
||||||
|
// ========================== Top & Bottom ==========================
|
||||||
|
[`${componentCls}-top, ${componentCls}-bottom`]: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
margin: `0 0 ${margin}px 0`,
|
||||||
|
|
||||||
|
'&::before': {
|
||||||
|
position: 'absolute',
|
||||||
|
right: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
borderBottom: `${token.lineWidth}px ${token.lineType} ${colorSplit}`,
|
||||||
|
content: "''",
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-ink-bar`]: {
|
||||||
|
height: token.lineWidthBold,
|
||||||
|
|
||||||
|
'&-animated': {
|
||||||
|
transition: `width ${token.motionDurationSlow}, left ${token.motionDurationSlow},
|
||||||
|
right ${token.motionDurationSlow}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-nav-wrap`]: {
|
||||||
|
'&::before, &::after': {
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
width: token.controlHeight,
|
||||||
|
},
|
||||||
|
|
||||||
|
'&::before': {
|
||||||
|
left: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
boxShadow: token.boxShadowTabsOverflowLeft,
|
||||||
|
},
|
||||||
|
|
||||||
|
'&::after': {
|
||||||
|
right: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
boxShadow: token.boxShadowTabsOverflowRight,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-nav-wrap-ping-left::before`]: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
[`&${componentCls}-nav-wrap-ping-right::after`]: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-top`]: {
|
||||||
|
[`> ${componentCls}-nav,
|
||||||
|
> div > ${componentCls}-nav`]: {
|
||||||
|
'&::before': {
|
||||||
|
bottom: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-ink-bar`]: {
|
||||||
|
bottom: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-bottom`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
order: 1,
|
||||||
|
marginTop: `${margin}px`,
|
||||||
|
marginBottom: 0,
|
||||||
|
|
||||||
|
'&::before': {
|
||||||
|
top: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-ink-bar`]: {
|
||||||
|
top: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-content-holder, > div > ${componentCls}-content-holder`]: {
|
||||||
|
order: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// ========================== Left & Right ==========================
|
||||||
|
[`${componentCls}-left, ${componentCls}-right`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
minWidth: token.controlHeight * 1.25,
|
||||||
|
|
||||||
|
// >>>>>>>>>>> Tab
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
padding: `${token.paddingXS}px ${token.paddingLG}px`,
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-tab + ${componentCls}-tab`]: {
|
||||||
|
margin: `${token.margin}px 0 0 0`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// >>>>>>>>>>> Nav
|
||||||
|
[`${componentCls}-nav-wrap`]: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
|
||||||
|
'&::before, &::after': {
|
||||||
|
right: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
height: token.controlHeight,
|
||||||
|
},
|
||||||
|
|
||||||
|
'&::before': {
|
||||||
|
top: 0,
|
||||||
|
boxShadow: token.boxShadowTabsOverflowTop,
|
||||||
|
},
|
||||||
|
|
||||||
|
'&::after': {
|
||||||
|
bottom: 0,
|
||||||
|
boxShadow: token.boxShadowTabsOverflowBottom,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-nav-wrap-ping-top::before`]: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-nav-wrap-ping-bottom::after`]: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// >>>>>>>>>>> Ink Bar
|
||||||
|
[`${componentCls}-ink-bar`]: {
|
||||||
|
width: token.lineWidthBold,
|
||||||
|
|
||||||
|
'&-animated': {
|
||||||
|
transition: `height ${token.motionDurationSlow}, top ${token.motionDurationSlow}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-nav-list, ${componentCls}-nav-operations`]: {
|
||||||
|
flex: '1 0 auto', // fix safari scroll problem
|
||||||
|
flexDirection: 'column',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-left`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-ink-bar`]: {
|
||||||
|
right: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-content-holder, > div > ${componentCls}-content-holder`]: {
|
||||||
|
marginLeft: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `-${token.lineWidth}px`,
|
||||||
|
},
|
||||||
|
borderLeft: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `${token.lineWidth}px ${token.lineType} ${token.colorBorder}`,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-content > ${componentCls}-tabpane`]: {
|
||||||
|
paddingLeft: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: token.paddingLG,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-right`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
order: 1,
|
||||||
|
|
||||||
|
[`${componentCls}-ink-bar`]: {
|
||||||
|
left: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-content-holder, > div > ${componentCls}-content-holder`]: {
|
||||||
|
order: 0,
|
||||||
|
marginRight: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: -token.lineWidth,
|
||||||
|
},
|
||||||
|
borderRight: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `${token.lineWidth}px ${token.lineType} ${token.colorBorder}`,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-content > ${componentCls}-tabpane`]: {
|
||||||
|
paddingRight: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: token.paddingLG,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const genSizeStyle: GenerateStyle<TabsToken> = (token: TabsToken): CSSObject => {
|
||||||
|
const { componentCls, padding } = token;
|
||||||
|
return {
|
||||||
|
[componentCls]: {
|
||||||
|
'&-small': {
|
||||||
|
[`> ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
padding: `${token.paddingXS}px 0`,
|
||||||
|
fontSize: token.fontSize,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'&-large': {
|
||||||
|
[`> ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
padding: `${padding}px 0`,
|
||||||
|
fontSize: token.fontSizeLG,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-card`]: {
|
||||||
|
[`&${componentCls}-small`]: {
|
||||||
|
[`> ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
padding: `${token.paddingXXS * 1.5}px ${padding}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[`&${componentCls}-bottom`]: {
|
||||||
|
[`> ${componentCls}-nav ${componentCls}-tab`]: {
|
||||||
|
borderRadius: `0 0 ${token.borderRadius}px ${token.borderRadius}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[`&${componentCls}-top`]: {
|
||||||
|
[`> ${componentCls}-nav ${componentCls}-tab`]: {
|
||||||
|
borderRadius: `${token.borderRadius}px ${token.borderRadius}px 0 0`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[`&${componentCls}-right`]: {
|
||||||
|
[`> ${componentCls}-nav ${componentCls}-tab`]: {
|
||||||
|
borderRadius: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `0 ${token.borderRadius}px ${token.borderRadius}px 0`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[`&${componentCls}-left`]: {
|
||||||
|
[`> ${componentCls}-nav ${componentCls}-tab`]: {
|
||||||
|
borderRadius: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `${token.borderRadius}px 0 0 ${token.borderRadius}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-large`]: {
|
||||||
|
[`> ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
padding: `${token.paddingXS}px ${padding}px ${token.paddingXXS * 1.5}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const genTabStyle: GenerateStyle<TabsToken, CSSObject> = (token: TabsToken) => {
|
||||||
|
const { componentCls, tabsActiveColor, tabsHoverColor, iconCls, tabsHorizontalGutter } = token;
|
||||||
|
|
||||||
|
const tabCls = `${componentCls}-tab`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[tabCls]: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'inline-flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
padding: `${token.paddingSM}px 0`,
|
||||||
|
fontSize: `${token.fontSize}px`,
|
||||||
|
background: 'transparent',
|
||||||
|
border: 0,
|
||||||
|
outline: 'none',
|
||||||
|
cursor: 'pointer',
|
||||||
|
'&-btn, &-remove': {
|
||||||
|
'&:focus:not(:focus-visible), &:active': {
|
||||||
|
color: tabsActiveColor,
|
||||||
|
},
|
||||||
|
...genFocusStyle(token),
|
||||||
|
},
|
||||||
|
'&-btn': {
|
||||||
|
outline: 'none',
|
||||||
|
transition: 'all 0.3s',
|
||||||
|
},
|
||||||
|
'&-remove': {
|
||||||
|
flex: 'none',
|
||||||
|
marginRight: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: -token.marginXXS,
|
||||||
|
},
|
||||||
|
marginLeft: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: token.marginXS,
|
||||||
|
},
|
||||||
|
color: token.colorTextDescription,
|
||||||
|
fontSize: token.fontSizeSM,
|
||||||
|
background: 'transparent',
|
||||||
|
border: 'none',
|
||||||
|
outline: 'none',
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: `all ${token.motionDurationSlow}`,
|
||||||
|
'&:hover': {
|
||||||
|
color: token.colorTextHeading,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'&:hover': {
|
||||||
|
color: tabsHoverColor,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${tabCls}-active ${tabCls}-btn`]: {
|
||||||
|
color: token.colorPrimary,
|
||||||
|
textShadow: token.tabsActiveTextShadow,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${tabCls}-disabled`]: {
|
||||||
|
color: token.colorTextDisabled,
|
||||||
|
cursor: 'not-allowed',
|
||||||
|
},
|
||||||
|
[`&${tabCls}-disabled ${tabCls}-btn, &${tabCls}-disabled ${componentCls}-remove`]: {
|
||||||
|
'&:focus, &:active': {
|
||||||
|
color: token.colorTextDisabled,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[`& ${tabCls}-remove ${iconCls}`]: {
|
||||||
|
margin: 0,
|
||||||
|
},
|
||||||
|
[iconCls]: {
|
||||||
|
marginRight: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: token.marginSM,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${tabCls} + ${tabCls}`]: {
|
||||||
|
margin: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `0 0 0 ${tabsHorizontalGutter}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const genRtlStyle: GenerateStyle<TabsToken, CSSObject> = (token: TabsToken) => {
|
||||||
|
const { componentCls, tabsHorizontalGutter, iconCls, tabsCardGutter } = token;
|
||||||
|
const rtlCls = `${componentCls}-rtl`;
|
||||||
|
return {
|
||||||
|
[rtlCls]: {
|
||||||
|
direction: 'rtl',
|
||||||
|
|
||||||
|
[`${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab`]: {
|
||||||
|
margin: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `0 0 0 ${tabsHorizontalGutter}px`,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-tab:last-of-type`]: {
|
||||||
|
marginLeft: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[iconCls]: {
|
||||||
|
marginRight: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
marginLeft: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `${token.marginSM}px`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-tab-remove`]: {
|
||||||
|
marginRight: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `${token.marginXS}px`,
|
||||||
|
},
|
||||||
|
marginLeft: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `-${token.marginXXS}px`,
|
||||||
|
},
|
||||||
|
|
||||||
|
[iconCls]: {
|
||||||
|
margin: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-left`]: {
|
||||||
|
[`> ${componentCls}-nav`]: {
|
||||||
|
order: 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-content-holder`]: {
|
||||||
|
order: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`&${componentCls}-right`]: {
|
||||||
|
[`> ${componentCls}-nav`]: {
|
||||||
|
order: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`> ${componentCls}-content-holder`]: {
|
||||||
|
order: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// ====================== Card ======================
|
||||||
|
[`&${componentCls}-card${componentCls}-top, &${componentCls}-card${componentCls}-bottom`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-tab + ${componentCls}-tab`]: {
|
||||||
|
marginRight: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `${tabsCardGutter}px`,
|
||||||
|
},
|
||||||
|
marginLeft: { _skip_check_: true, value: 0 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-dropdown-rtl`]: {
|
||||||
|
direction: 'rtl',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-menu-item`]: {
|
||||||
|
[`${componentCls}-dropdown-rtl`]: {
|
||||||
|
textAlign: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 'right',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const genTabsStyle: GenerateStyle<TabsToken> = (token: TabsToken): CSSObject => {
|
||||||
|
const {
|
||||||
|
componentCls,
|
||||||
|
tabsCardHorizontalPadding,
|
||||||
|
tabsCardHeight,
|
||||||
|
tabsCardGutter,
|
||||||
|
tabsHoverColor,
|
||||||
|
tabsActiveColor,
|
||||||
|
colorSplit,
|
||||||
|
} = token;
|
||||||
|
|
||||||
|
return {
|
||||||
|
[componentCls]: {
|
||||||
|
...resetComponent(token),
|
||||||
|
display: 'flex',
|
||||||
|
|
||||||
|
// ========================== Navigation ==========================
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
flex: 'none',
|
||||||
|
alignItems: 'center',
|
||||||
|
|
||||||
|
[`${componentCls}-nav-wrap`]: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
flex: 'auto',
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
transform: 'translate(0)', // Fix chrome render bug
|
||||||
|
|
||||||
|
// >>>>> Ping shadow
|
||||||
|
'&::before, &::after': {
|
||||||
|
position: 'absolute',
|
||||||
|
zIndex: 1,
|
||||||
|
opacity: 0,
|
||||||
|
transition: `opacity ${token.motionDurationSlow}`,
|
||||||
|
content: "''",
|
||||||
|
pointerEvents: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-nav-list`]: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
transition: `opacity ${token.motionDurationSlow}`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// >>>>>>>> Operations
|
||||||
|
[`${componentCls}-nav-operations`]: {
|
||||||
|
display: 'flex',
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-nav-operations-hidden`]: {
|
||||||
|
position: 'absolute',
|
||||||
|
visibility: 'hidden',
|
||||||
|
pointerEvents: 'none',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-nav-more`]: {
|
||||||
|
position: 'relative',
|
||||||
|
padding: tabsCardHorizontalPadding,
|
||||||
|
background: 'transparent',
|
||||||
|
border: 0,
|
||||||
|
|
||||||
|
'&::after': {
|
||||||
|
position: 'absolute',
|
||||||
|
right: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
bottom: 0,
|
||||||
|
left: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
height: token.controlHeightLG / 8,
|
||||||
|
transform: 'translateY(100%)',
|
||||||
|
content: "''",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-nav-add`]: {
|
||||||
|
minWidth: `${tabsCardHeight}px`,
|
||||||
|
marginLeft: {
|
||||||
|
_skip_check_: true,
|
||||||
|
value: `${tabsCardGutter}px`,
|
||||||
|
},
|
||||||
|
padding: `0 ${token.paddingXS}px`,
|
||||||
|
background: 'transparent',
|
||||||
|
border: `${token.lineWidth}px ${token.lineType} ${colorSplit}`,
|
||||||
|
borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`,
|
||||||
|
outline: 'none',
|
||||||
|
cursor: 'pointer',
|
||||||
|
color: token.colorText,
|
||||||
|
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
color: tabsHoverColor,
|
||||||
|
},
|
||||||
|
|
||||||
|
'&:active, &:focus:not(:focus-visible)': {
|
||||||
|
color: tabsActiveColor,
|
||||||
|
},
|
||||||
|
|
||||||
|
...genFocusStyle(token),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-extra-content`]: {
|
||||||
|
flex: 'none',
|
||||||
|
},
|
||||||
|
|
||||||
|
// ============================ InkBar ============================
|
||||||
|
[`${componentCls}-ink-bar`]: {
|
||||||
|
position: 'absolute',
|
||||||
|
background: token.colorPrimary,
|
||||||
|
pointerEvents: 'none',
|
||||||
|
},
|
||||||
|
|
||||||
|
// ============================= Tabs =============================
|
||||||
|
...genTabStyle(token),
|
||||||
|
|
||||||
|
// =========================== TabPanes ===========================
|
||||||
|
[`${componentCls}-content`]: {
|
||||||
|
position: 'relative',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-content-holder`]: {
|
||||||
|
flex: 'auto',
|
||||||
|
minWidth: 0,
|
||||||
|
minHeight: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-tabpane`]: {
|
||||||
|
outline: 'none',
|
||||||
|
'&-hidden': {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-centered`]: {
|
||||||
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
|
[`${componentCls}-nav-wrap`]: {
|
||||||
|
[`&:not([class*='${componentCls}-nav-wrap-ping'])`]: {
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================== Export ==============================
|
||||||
|
export default genComponentStyleHook(
|
||||||
|
'Tabs',
|
||||||
|
token => {
|
||||||
|
const tabsCardHeight = token.controlHeightLG;
|
||||||
|
|
||||||
|
const tabsToken = mergeToken<TabsToken>(token, {
|
||||||
|
tabsHoverColor: token.colorPrimaryHover,
|
||||||
|
tabsActiveColor: token.colorPrimaryActive,
|
||||||
|
|
||||||
|
tabsCardHorizontalPadding: `${
|
||||||
|
(tabsCardHeight - Math.round(token.fontSize * token.lineHeight)) / 2 - token.lineWidth
|
||||||
|
}px ${token.padding}px`,
|
||||||
|
tabsCardHeight,
|
||||||
|
tabsCardGutter: token.marginXXS / 2,
|
||||||
|
tabsHorizontalGutter: 32, // Fixed Value
|
||||||
|
tabsCardHeadBackground: token.colorFillAlter,
|
||||||
|
dropdownEdgeChildVerticalPadding: token.paddingXXS,
|
||||||
|
tabsActiveTextShadow: '0 0 0.25px currentcolor',
|
||||||
|
tabsDropdownHeight: 200,
|
||||||
|
tabsDropdownWidth: 120,
|
||||||
|
});
|
||||||
|
|
||||||
|
return [
|
||||||
|
genSizeStyle(tabsToken),
|
||||||
|
genRtlStyle(tabsToken),
|
||||||
|
genPositionStyle(tabsToken),
|
||||||
|
genDropdownStyle(tabsToken),
|
||||||
|
genCardStyle(tabsToken),
|
||||||
|
genTabsStyle(tabsToken),
|
||||||
|
genMotionStyle(tabsToken),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
token => ({
|
||||||
|
zIndexPopup: token.zIndexPopupBase + 50,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
@ -1,258 +0,0 @@
|
||||||
// import '../../style/index.less';
|
|
||||||
// import './index.less';
|
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
|
||||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
|
||||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
|
||||||
import { resetComponent, clearFix } from '../../_style';
|
|
||||||
import Token from 'markdown-it/lib/token';
|
|
||||||
import { genTabsPositionStyle } from './position';
|
|
||||||
import { genTabsSizeStyle } from './size';
|
|
||||||
import { genRtlStyle } from './rtl';
|
|
||||||
import { genTabsDropdownStyle } from './dropdown';
|
|
||||||
import { genTabscardStyle } from './card';
|
|
||||||
import {tabsCardStyle } from './card'
|
|
||||||
|
|
||||||
/** Component only token. Which will handle additional calculation of alias token */
|
|
||||||
export interface ComponentToken {}
|
|
||||||
interface tabsToken extends FullToken<'Tabs'> {
|
|
||||||
tabsCardHeight: string;
|
|
||||||
tabsCardGutter: string;
|
|
||||||
tabsHorizontalMarginRtl: string;
|
|
||||||
}
|
|
||||||
// ============================== Shared ==============================
|
|
||||||
|
|
||||||
export const genTabsSmallStyle = (token: tabsToken): CSSObject => {
|
|
||||||
const { componentCls } = token;
|
|
||||||
|
|
||||||
return {
|
|
||||||
[componentCls]: {
|
|
||||||
...genTabsSizeStyle(token),
|
|
||||||
...genTabsPositionStyle(token),
|
|
||||||
...resetComponent(token),
|
|
||||||
display: 'flex',
|
|
||||||
// ========================== Navigation ==========================
|
|
||||||
[`&-card`]: {
|
|
||||||
...genTabscardStyle(token),
|
|
||||||
},
|
|
||||||
[`&-rtl`]: {
|
|
||||||
...genRtlStyle(token),
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-dropdown`]: {
|
|
||||||
...genTabsDropdownStyle(token),
|
|
||||||
},
|
|
||||||
[`${componentCls}-nav,
|
|
||||||
div > ${componentCls}-nav`]: {
|
|
||||||
position: 'relative',
|
|
||||||
display: 'flex',
|
|
||||||
flex: 'none',
|
|
||||||
alignItems: 'center',
|
|
||||||
[`${componentCls}-nav-wrap`]: {
|
|
||||||
position: 'relative',
|
|
||||||
display: 'flex',
|
|
||||||
flex: 'auto',
|
|
||||||
alignSelf: 'stretch',
|
|
||||||
overflow: 'hidden',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
transform: 'translate(0)', // Fix chrome render bug
|
|
||||||
// >>>>> Ping shadow
|
|
||||||
[`&::before ,
|
|
||||||
&::after `]: {
|
|
||||||
position: 'absolute',
|
|
||||||
zIndex: 1,
|
|
||||||
opacity: 0,
|
|
||||||
transition: `opacity ${token.motionDurationSlow}`,
|
|
||||||
content: '""',
|
|
||||||
pointerEvents: 'none',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-nav-list`]: {
|
|
||||||
position: 'relative',
|
|
||||||
display: 'flex',
|
|
||||||
transition: `transform ${token.motionDurationSlow}`,
|
|
||||||
},
|
|
||||||
|
|
||||||
// >>>>>>>> Operations
|
|
||||||
[`${componentCls}-nav-operations`]: {
|
|
||||||
display: 'flex',
|
|
||||||
alignSelf: 'stretch',
|
|
||||||
[`&-hidden`]: {
|
|
||||||
position: 'absolute',
|
|
||||||
visibility: 'hidden',
|
|
||||||
pointerEvents: 'none',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-nav-more`]: {
|
|
||||||
position: 'relative',
|
|
||||||
padding: `${token.paddingXS}px ${token.padding}px`,
|
|
||||||
background: 'transparent',
|
|
||||||
border: 0,
|
|
||||||
[`&::after`]: {
|
|
||||||
position: 'absolute',
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
left: 0,
|
|
||||||
height: '5px',
|
|
||||||
transform: 'translateY(100%)',
|
|
||||||
content: '""',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[`${componentCls}-nav-add`]: {
|
|
||||||
minWidth: `${token.tabsCardHeight}`,
|
|
||||||
marginLeft: `${token.tabsCardGutter}`,
|
|
||||||
padding: `0 ${token.paddingXS}px `,
|
|
||||||
background: `${token.colorFillAlter}`,
|
|
||||||
border: `${token.lineWidth}px ${token.colorBorder} ${token.lineType} `,
|
|
||||||
borderRadius: ` ${token.borderRadius}e ${token.borderRadius} 0 0`,
|
|
||||||
outline: 'none',
|
|
||||||
cursor: 'pointer',
|
|
||||||
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOut} `,
|
|
||||||
[` &:hover `]: {
|
|
||||||
color: `${token.colorPrimaryActive}`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[` &:active,
|
|
||||||
&:focus`]: {
|
|
||||||
color: `${token.colorPrimaryActive}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-extra-content `]: {
|
|
||||||
flex: 'none',
|
|
||||||
},
|
|
||||||
[`&-centered`]: {
|
|
||||||
[`${componentCls}-nav,
|
|
||||||
div > ${componentCls}-nav`]: {
|
|
||||||
[`${componentCls}-nav-wrap`]: {
|
|
||||||
[`&:not([class*='@:${componentCls}-nav-wrap-ping'])`]: {
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ============================ InkBar ============================
|
|
||||||
[`${componentCls}-ink-bar`]: {
|
|
||||||
position: 'absolute',
|
|
||||||
background: `${token.colorPrimary}`,
|
|
||||||
pointerEvents: 'none',
|
|
||||||
},
|
|
||||||
|
|
||||||
// ============================= Tabs =============================
|
|
||||||
[`${componentCls}-tab `]: {
|
|
||||||
position: 'relative',
|
|
||||||
display: 'inline-flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
padding: `${token.paddingSM}px 0`,
|
|
||||||
fontSize: `${token.fontSize}px`,
|
|
||||||
background: 'transparent',
|
|
||||||
border: 0,
|
|
||||||
outline: 'none',
|
|
||||||
cursor: 'pointer',
|
|
||||||
|
|
||||||
[`&-btn,
|
|
||||||
&-remove`]: {
|
|
||||||
[` &:focus,
|
|
||||||
&:active `]: {
|
|
||||||
color: `${token.colorInfoActive}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[` &-btn `]: {
|
|
||||||
outline: 'none',
|
|
||||||
transition: `all 0.3s`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-remove `]: {
|
|
||||||
flex: 'none',
|
|
||||||
marginRight: `-${token.marginXXS}px`,
|
|
||||||
marginLeft: `${tabsCardStyle.tabsCardGutter}`,
|
|
||||||
color: `${token.colorTextSecondary} `,
|
|
||||||
fontSize: ` ${token.fontSizeSM}px`,
|
|
||||||
background: 'transparent',
|
|
||||||
border: 'none',
|
|
||||||
outline: 'none',
|
|
||||||
cursor: 'pointer',
|
|
||||||
transition: `all ${token.motionDurationSlow} `,
|
|
||||||
|
|
||||||
[` &:hover `]: {
|
|
||||||
color: `${token.colorTextHeading} `,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[` &:hover `]: {
|
|
||||||
color: `${token.colorLinkHover}`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-active &-btn `]: {
|
|
||||||
color: `${token.colorHighlight}`,
|
|
||||||
textShadow: '0 0 0.25px currentcolor',
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-disabled `]: {
|
|
||||||
color: `${token.colorTextDisabled}`,
|
|
||||||
cursor: 'not-allowed',
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-disabled &-btn,
|
|
||||||
&-disabled &-remove`]: {
|
|
||||||
[` &:focus,
|
|
||||||
&:active `]: {
|
|
||||||
color: `${token.colorTextDisabled}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[` &-remove ${token.iconCls}`]: {
|
|
||||||
margin: 0,
|
|
||||||
},
|
|
||||||
|
|
||||||
[` ${token.iconCls} `]: {
|
|
||||||
marginRight: `${token.marginSM}px`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-tab + ${componentCls}-tab `]: {
|
|
||||||
margin: `${token.tabsHorizontalMarginRtl}`,
|
|
||||||
},
|
|
||||||
|
|
||||||
// =========================== TabPanes ===========================
|
|
||||||
[`${componentCls}-content`]: {
|
|
||||||
[`&-holder`]: {
|
|
||||||
flex: 'auto',
|
|
||||||
minWidth: 0,
|
|
||||||
minHeight: 0,
|
|
||||||
|
|
||||||
},
|
|
||||||
display: 'flex',
|
|
||||||
width: '100%',
|
|
||||||
[`${componentCls}-animated`]: {
|
|
||||||
transition: `margin ${token.motionDurationSlow}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[` ${componentCls}-tabpane `]: {
|
|
||||||
flex: 'none',
|
|
||||||
width: ' 100%',
|
|
||||||
outline: 'none',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================== Export ==============================
|
|
||||||
export default genComponentStyleHook(
|
|
||||||
'Tabs',
|
|
||||||
token => {
|
|
||||||
const tabsToken = mergeToken<tabsToken>(token, {
|
|
||||||
tabsCardHeight: '40px',
|
|
||||||
tabsCardGutter: '5px',
|
|
||||||
tabsHorizontalMarginRtl: '0 0 0 32px',
|
|
||||||
});
|
|
||||||
return [genTabsSmallStyle(tabsToken)];
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import type { TabsToken } from '.';
|
||||||
|
import { initSlideMotion } from '../../_style/motion';
|
||||||
|
import type { GenerateStyle } from '../../theme/internal';
|
||||||
|
|
||||||
|
const genMotionStyle: GenerateStyle<TabsToken> = token => {
|
||||||
|
const { componentCls, motionDurationSlow } = token;
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
[componentCls]: {
|
||||||
|
[`${componentCls}-switch`]: {
|
||||||
|
'&-appear, &-enter': {
|
||||||
|
transition: 'none',
|
||||||
|
|
||||||
|
'&-start': {
|
||||||
|
opacity: 0,
|
||||||
|
},
|
||||||
|
'&-active': {
|
||||||
|
opacity: 1,
|
||||||
|
transition: `opacity ${motionDurationSlow}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'&-leave': {
|
||||||
|
position: 'absolute',
|
||||||
|
transition: 'none',
|
||||||
|
inset: 0,
|
||||||
|
|
||||||
|
'&-start': {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
'&-active': {
|
||||||
|
opacity: 0,
|
||||||
|
transition: `opacity ${motionDurationSlow}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Follow code may reuse in other components
|
||||||
|
[initSlideMotion(token, 'slide-up'), initSlideMotion(token, 'slide-down')],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default genMotionStyle;
|
||||||
|
|
@ -1,191 +0,0 @@
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
|
||||||
|
|
||||||
export const genTabsPositionStyle = (token): CSSObject => {
|
|
||||||
const { componentCls } = token;
|
|
||||||
|
|
||||||
return {
|
|
||||||
[`&-top,
|
|
||||||
&-bottom`]: {
|
|
||||||
flexDirection: 'column',
|
|
||||||
[`${componentCls}-nav, div >${componentCls}-nav`]: {
|
|
||||||
margin: ` 0 0 ${token.margin}px `,
|
|
||||||
[`&::before`]: {
|
|
||||||
position: 'absolute',
|
|
||||||
right:0,
|
|
||||||
left: 0,
|
|
||||||
borderBottom: `${token.lineWidth}px ${token.colorBorder} ${token.lineType} `,
|
|
||||||
content: '""',
|
|
||||||
},
|
|
||||||
[`${componentCls}-ink-bar`]: {
|
|
||||||
height: ' 2px',
|
|
||||||
[`&-animated`]: {
|
|
||||||
transition: `width ${token.motionDurationSlow} , left ${token.motionDurationSlow},
|
|
||||||
right `,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-nav-wrap`]: {
|
|
||||||
[`&::before,
|
|
||||||
&::after`]: {
|
|
||||||
top: 0,
|
|
||||||
bottom: 0,
|
|
||||||
width:'30px',
|
|
||||||
},
|
|
||||||
|
|
||||||
[` &::before`]: {
|
|
||||||
left: 0,
|
|
||||||
boxShadow: `${token.boxShadowTabsOverflowBottom}`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[` &::after`]: {
|
|
||||||
right: 0,
|
|
||||||
boxShadow: `${token.boxShadowTabsOverflowRight}`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&${componentCls}-nav-wrap-ping-left::before`]: {
|
|
||||||
opacity: 1,
|
|
||||||
},
|
|
||||||
[`&${componentCls}-nav-wrap-ping-right::after`]: {
|
|
||||||
opacity: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-top`]: {
|
|
||||||
[`${componentCls}-nav,
|
|
||||||
div >${componentCls}-nav`]: {
|
|
||||||
[`&::before`]: {
|
|
||||||
bottom: 0,
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-ink-bar`]: {
|
|
||||||
bottom: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-bottom`]: {
|
|
||||||
|
|
||||||
[`${componentCls}-nav,
|
|
||||||
div >${componentCls}-nav`]: {
|
|
||||||
order: 1,
|
|
||||||
marginTop: ` ${token.margin}px`,
|
|
||||||
marginBottom: 0,
|
|
||||||
[` &::before`]: {
|
|
||||||
top: 0,
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-ink-bar`]: {
|
|
||||||
top: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-content-holder,
|
|
||||||
div >${componentCls}-content-holder`]: {
|
|
||||||
order: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ========================== Left & Right ==========================
|
|
||||||
[`&-left,
|
|
||||||
&-right`]: {
|
|
||||||
[`${componentCls}-nav, div>${componentCls}-nav`]: {
|
|
||||||
flexDirection: 'column',
|
|
||||||
minWidth: '50px',
|
|
||||||
// >>>>>>>>>>> Tab
|
|
||||||
[`${componentCls}-tab`]: {
|
|
||||||
padding: ` ${token.padding}px`,
|
|
||||||
textAlign: 'center',
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-tab + ${componentCls}-tab`]: {
|
|
||||||
margin: ` ${token.margin}px 0 0 0`,
|
|
||||||
},
|
|
||||||
|
|
||||||
// >>>>>>>>>>> Nav
|
|
||||||
[`${componentCls}-nav-wrap`]: {
|
|
||||||
flexDirection: 'column',
|
|
||||||
[`&::before,
|
|
||||||
&::after`]: {
|
|
||||||
right: 0,
|
|
||||||
left: 0,
|
|
||||||
height: '30px',
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&::before`]: {
|
|
||||||
top: 0,
|
|
||||||
boxShadow: `${token.boxShadowTabsOverflowTop}`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&::after`]: {
|
|
||||||
bottom: 0,
|
|
||||||
boxShadow: `${token.boxShadowTabsOverflowBottom}`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&${componentCls}-nav-wrap-ping-top::before`]: {
|
|
||||||
opacity: 1,
|
|
||||||
},
|
|
||||||
[`&${componentCls}-nav-wrap-ping-bottom::after`]: {
|
|
||||||
opacity: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// >>>>>>>>>>> Ink Bar
|
|
||||||
[`${componentCls}-ink-bar`]: {
|
|
||||||
width: `2px`,
|
|
||||||
|
|
||||||
[`&-animated`]: {
|
|
||||||
transition: `height ${token.motionDurationSlow}, top ${token.motionDurationSlow}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-nav-list,
|
|
||||||
${componentCls}-nav-operations`]: {
|
|
||||||
// color: '#fff',
|
|
||||||
flex: `1 0 auto`, // fix safari scroll problem
|
|
||||||
flexDirection: `column`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-left`]: {
|
|
||||||
[`${componentCls}-nav,
|
|
||||||
div >${componentCls}-nav`]: {
|
|
||||||
[`${componentCls}-ink-bar`]: {
|
|
||||||
right: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`${componentCls}-content-holder,
|
|
||||||
div >&-content-holder`]: {
|
|
||||||
marginLeft: `-${token.lineWidth}px`,
|
|
||||||
borderLeft: `${token.lineWidth}px ${token.colorBorder} ${token.lineType} `,
|
|
||||||
[` ${componentCls}-content > ${componentCls}-tabpane`]: {
|
|
||||||
paddingLeft: `${token.paddingLG}px`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-right`]: {
|
|
||||||
[` ${componentCls}-nav,
|
|
||||||
div >${componentCls}-nav`]: {
|
|
||||||
order: 1,
|
|
||||||
|
|
||||||
[`${componentCls}-ink-bar`]: {
|
|
||||||
left: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[`${componentCls}-content-holder,
|
|
||||||
div >${componentCls}-content-holder`]: {
|
|
||||||
order: 0,
|
|
||||||
marginLeft: ` -${token.lineWidth}px`,
|
|
||||||
borderRight: `${token.lineWidth}px ${token.colorBorder} ${token.lineType} `,
|
|
||||||
|
|
||||||
[`${componentCls}-content >${componentCls}-tabpane`]: {
|
|
||||||
paddingLeft: ` ${token.paddingLG}px`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
|
||||||
import {tabsCardStyle } from './card'
|
|
||||||
export const genRtlStyle = (token): CSSObject => {
|
|
||||||
const { componentCls } = token;
|
|
||||||
|
|
||||||
return {
|
|
||||||
[`&-rtl `]: {
|
|
||||||
direction: 'rtl',
|
|
||||||
[`${componentCls}-nav `]: {
|
|
||||||
[` ${componentCls}-tab `]: {
|
|
||||||
margin: ` ${token.tabsHorizontalMarginRtl}`,
|
|
||||||
|
|
||||||
[` &:last-of-type`]: {
|
|
||||||
marginLeft: 0,
|
|
||||||
},
|
|
||||||
|
|
||||||
[` ${token.iconCls}`]: {
|
|
||||||
marginRight: 0,
|
|
||||||
marginLeft: `${token.marginSM}`,
|
|
||||||
},
|
|
||||||
|
|
||||||
[` ${componentCls}-tab-remove `]: {
|
|
||||||
marginRight: `${token.marginXS}`,
|
|
||||||
marginLeft: `${token.marginXXS}`,
|
|
||||||
[` ${token.iconCls} ${token.ico}`]: {
|
|
||||||
margin: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`& ${componentCls}-left`]: {
|
|
||||||
[`${componentCls}-nav`]: {
|
|
||||||
order: 1,
|
|
||||||
},
|
|
||||||
[`${componentCls}-content-holder `]: {
|
|
||||||
order: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[` & ${componentCls}-right `]: {
|
|
||||||
[`${componentCls}-nav `]: {
|
|
||||||
order: 0,
|
|
||||||
},
|
|
||||||
[`${componentCls}-content-holder`]: {
|
|
||||||
order: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ====================== Card ======================
|
|
||||||
[`&-card`]: {
|
|
||||||
[` & ${componentCls}-top,
|
|
||||||
& ${componentCls}-bottom`]: {
|
|
||||||
[` ${componentCls}-nav,
|
|
||||||
div >${componentCls}-nav `]: {
|
|
||||||
[` ${componentCls}-tab +${componentCls}-tab`]: {
|
|
||||||
[` ${componentCls}-rtl& `]: {
|
|
||||||
marginRight: `${tabsCardStyle.tabsCardGutter}`,
|
|
||||||
marginLeft: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[` ${componentCls}-nav-add`]: {
|
|
||||||
[` ${componentCls}-rtl& `]: {
|
|
||||||
marginRight: `${tabsCardStyle.tabsCardGutter}`,
|
|
||||||
marginLeft: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[` ${componentCls}-dropdown `]: {
|
|
||||||
[` &-rtl `]: {
|
|
||||||
direction: 'rtl',
|
|
||||||
},
|
|
||||||
[` &-menu-item `]: {
|
|
||||||
[`${componentCls}-dropdown-rtl & `]: {
|
|
||||||
textAlign: 'right',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
import type { CSSObject } from '../../_util/cssinjs';
|
|
||||||
|
|
||||||
export const genTabsSizeStyle = (token): CSSObject => {
|
|
||||||
const { componentCls } = token;
|
|
||||||
|
|
||||||
return {
|
|
||||||
[`&-small`]: {
|
|
||||||
[`${componentCls}-nav`]: {
|
|
||||||
[`${componentCls}-tab`]: {
|
|
||||||
padding: ` ${token.paddingXS}px 0`,
|
|
||||||
fontSize: ` ${token.fontSize}px`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-large`]: {
|
|
||||||
[`${componentCls}-nav `]: {
|
|
||||||
[` ${componentCls}-tab`]: {
|
|
||||||
padding: ` ${token.paddingLG}px 0`,
|
|
||||||
fontSize: ` ${token.fontSizeLG}px`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-card `]: {
|
|
||||||
[`& ${componentCls}-small `]: {
|
|
||||||
[`${componentCls}-nav`]: {
|
|
||||||
[` ${componentCls}-tab`]: {
|
|
||||||
padding: ` ${token.paddingSM}px`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
[`&-large`]: {
|
|
||||||
[` > ${componentCls}-nav `]: {
|
|
||||||
[`${componentCls}-tab`]: {
|
|
||||||
padding: ` ${token.paddingLG}px 0`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
Loading…
Reference in New Issue