@akinon/ui-tabs 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.ts +16 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +126 -0
- package/dist/cjs/types.d.ts +124 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +122 -0
- package/dist/esm/types.d.ts +124 -0
- package/package.json +46 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ITabsProps, TabItem } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Tabs component for Akinon UI.
|
|
5
|
+
*
|
|
6
|
+
* This versatile component provides a tabbed interface for organizing and displaying content in separate panels.
|
|
7
|
+
* It allows users to navigate between different content sections within the same page, enhancing user experience
|
|
8
|
+
* and content accessibility. Each tab features an icon and label combination with visual feedback for active states.
|
|
9
|
+
*
|
|
10
|
+
* The component accepts default <a href="https://react.dev/reference/react-dom/components/common#common-props" target="_blank" rel="noopener noreferrer">React HTML attributes</a>,
|
|
11
|
+
* as well as attributes specific to <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes" target="_blank" rel="noopener noreferrer">HTMLDivElement</a>,
|
|
12
|
+
* providing flexible integration within the Akinon design system with support for icon-based navigation and customizable layouts.
|
|
13
|
+
*/
|
|
14
|
+
export declare const Tabs: ({ items, centered, ...restProps }: ITabsProps) => React.JSX.Element;
|
|
15
|
+
export type { ITabsProps, TabItem };
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,IAAI,GAAI,mCAIlB,UAAU,sBAiHZ,CAAC;AAEF,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.Tabs = void 0;
|
|
15
|
+
const icons_1 = require("@akinon/icons");
|
|
16
|
+
const ui_theme_1 = require("@akinon/ui-theme");
|
|
17
|
+
const cssinjs_1 = require("@ant-design/cssinjs");
|
|
18
|
+
const antd_1 = require("antd");
|
|
19
|
+
const React = require("react");
|
|
20
|
+
/**
|
|
21
|
+
* Tabs component for Akinon UI.
|
|
22
|
+
*
|
|
23
|
+
* This versatile component provides a tabbed interface for organizing and displaying content in separate panels.
|
|
24
|
+
* It allows users to navigate between different content sections within the same page, enhancing user experience
|
|
25
|
+
* and content accessibility. Each tab features an icon and label combination with visual feedback for active states.
|
|
26
|
+
*
|
|
27
|
+
* The component accepts default <a href="https://react.dev/reference/react-dom/components/common#common-props" target="_blank" rel="noopener noreferrer">React HTML attributes</a>,
|
|
28
|
+
* as well as attributes specific to <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes" target="_blank" rel="noopener noreferrer">HTMLDivElement</a>,
|
|
29
|
+
* providing flexible integration within the Akinon design system with support for icon-based navigation and customizable layouts.
|
|
30
|
+
*/
|
|
31
|
+
const Tabs = (_a) => {
|
|
32
|
+
var { items = [], centered = true } = _a, restProps = __rest(_a, ["items", "centered"]);
|
|
33
|
+
const tabsItemsWithIcons = items.map(item => (Object.assign(Object.assign({}, item), { icon: item.icon ? React.createElement(icons_1.Icon, { icon: item.icon }) : undefined })));
|
|
34
|
+
const { getPrefixCls, theme } = React.useContext(antd_1.ConfigProvider.ConfigContext);
|
|
35
|
+
const { token, hashId } = (0, ui_theme_1.useToken)();
|
|
36
|
+
const prefixClsWithoutHash = `.${getPrefixCls()}-tabs`;
|
|
37
|
+
const prefixCls = `:where(.${hashId})${prefixClsWithoutHash}`;
|
|
38
|
+
const customTokens = (0, ui_theme_1.getSafeCustomTokens)(theme);
|
|
39
|
+
const tabsTokens = token.Tabs;
|
|
40
|
+
const menuBarTabGap = tabsTokens.menuGap;
|
|
41
|
+
const useStyle = (0, cssinjs_1.useStyleRegister)({
|
|
42
|
+
token: token,
|
|
43
|
+
path: ['Tabs'],
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
theme: theme
|
|
46
|
+
}, () => {
|
|
47
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
|
|
48
|
+
return {
|
|
49
|
+
[`${prefixCls}`]: {},
|
|
50
|
+
[`${prefixCls} ${prefixClsWithoutHash}-ink-bar`]: {
|
|
51
|
+
display: (_a = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _a === void 0 ? void 0 : _a.displayNone
|
|
52
|
+
},
|
|
53
|
+
[`${prefixCls} ${prefixClsWithoutHash}-nav`]: {
|
|
54
|
+
borderBottom: (_b = customTokens === null || customTokens === void 0 ? void 0 : customTokens.border) === null || _b === void 0 ? void 0 : _b.borderNone,
|
|
55
|
+
['::before']: {
|
|
56
|
+
borderBottom: (_c = customTokens === null || customTokens === void 0 ? void 0 : customTokens.border) === null || _c === void 0 ? void 0 : _c.borderNone
|
|
57
|
+
},
|
|
58
|
+
['&-wrap']: {
|
|
59
|
+
padding: tabsTokens.navWrapperPadding
|
|
60
|
+
},
|
|
61
|
+
['&-list']: {
|
|
62
|
+
gap: menuBarTabGap
|
|
63
|
+
},
|
|
64
|
+
[`${prefixClsWithoutHash}-tab`]: {
|
|
65
|
+
margin: (_d = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _d === void 0 ? void 0 : _d.valueZero,
|
|
66
|
+
position: (_e = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _e === void 0 ? void 0 : _e.positionRelative,
|
|
67
|
+
color: tabsTokens.textColor,
|
|
68
|
+
fontWeight: (_f = customTokens === null || customTokens === void 0 ? void 0 : customTokens.typography) === null || _f === void 0 ? void 0 : _f.fontWeightBold,
|
|
69
|
+
[`&-btn`]: {
|
|
70
|
+
display: (_g = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _g === void 0 ? void 0 : _g.displayFlex,
|
|
71
|
+
flexDirection: (_h = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _h === void 0 ? void 0 : _h.flexDirectionColumn,
|
|
72
|
+
alignItems: (_j = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _j === void 0 ? void 0 : _j.flexCenter,
|
|
73
|
+
justifyContent: (_k = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _k === void 0 ? void 0 : _k.flexCenter,
|
|
74
|
+
position: (_l = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _l === void 0 ? void 0 : _l.positionRelative,
|
|
75
|
+
[`${prefixClsWithoutHash}-tab-icon`]: {
|
|
76
|
+
background: tabsTokens.tabIconBg,
|
|
77
|
+
borderRadius: (_m = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _m === void 0 ? void 0 : _m.valueHalf,
|
|
78
|
+
width: tabsTokens.tabIconWrapperSize,
|
|
79
|
+
height: tabsTokens.tabIconWrapperSize,
|
|
80
|
+
marginRight: (_o = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _o === void 0 ? void 0 : _o.valueZero,
|
|
81
|
+
transition: tabsTokens.tabIconBgTransition,
|
|
82
|
+
display: (_p = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _p === void 0 ? void 0 : _p.displayFlex,
|
|
83
|
+
alignItems: (_q = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _q === void 0 ? void 0 : _q.flexCenter,
|
|
84
|
+
justifyContent: (_r = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _r === void 0 ? void 0 : _r.flexCenter,
|
|
85
|
+
['svg']: {
|
|
86
|
+
width: tabsTokens.tabIconSize,
|
|
87
|
+
height: tabsTokens.tabIconSize,
|
|
88
|
+
fill: tabsTokens.tabIconFill,
|
|
89
|
+
transition: tabsTokens.tabIconFillTransition
|
|
90
|
+
},
|
|
91
|
+
['+ span']: {
|
|
92
|
+
position: (_s = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _s === void 0 ? void 0 : _s.positionAbsolute,
|
|
93
|
+
bottom: (_t = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _t === void 0 ? void 0 : _t.valueZero,
|
|
94
|
+
transform: tabsTokens.tabLabelTransform
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
[`+ ${prefixClsWithoutHash}-tab::before`]: {
|
|
99
|
+
content: (_u = customTokens === null || customTokens === void 0 ? void 0 : customTokens.others) === null || _u === void 0 ? void 0 : _u.emptyContent,
|
|
100
|
+
position: (_v = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _v === void 0 ? void 0 : _v.positionAbsolute,
|
|
101
|
+
top: (_w = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _w === void 0 ? void 0 : _w.valueHalf,
|
|
102
|
+
left: (_x = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _x === void 0 ? void 0 : _x.valueZero,
|
|
103
|
+
transform: `translate(-${(_y = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _y === void 0 ? void 0 : _y.valueFull}, -${(_z = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _z === void 0 ? void 0 : _z.valueHalf})`,
|
|
104
|
+
height: tabsTokens.separatorHeight,
|
|
105
|
+
width: menuBarTabGap,
|
|
106
|
+
backgroundColor: tabsTokens.separatorColor
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
[`${prefixCls} ${prefixClsWithoutHash}-tab${prefixClsWithoutHash}-tab-active ${prefixClsWithoutHash}-tab-btn`]: {
|
|
111
|
+
color: tabsTokens.textColor,
|
|
112
|
+
[`${prefixClsWithoutHash}-tab-icon`]: {
|
|
113
|
+
backgroundColor: tabsTokens.tabIconActiveBg,
|
|
114
|
+
['svg']: {
|
|
115
|
+
fill: tabsTokens.tabIconActiveFill
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
[`${prefixCls}${prefixClsWithoutHash}-centered ${prefixClsWithoutHash}-nav-wrap`]: {
|
|
120
|
+
paddingLeft: (_0 = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _0 === void 0 ? void 0 : _0.valueZero
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
return useStyle(React.createElement(antd_1.Tabs, Object.assign({}, restProps, { items: tabsItemsWithIcons, centered: centered })));
|
|
125
|
+
};
|
|
126
|
+
exports.Tabs = Tabs;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { IconName } from '@akinon/icons';
|
|
2
|
+
import { type DO_NOT_USE_OR_YOU_WILL_BE_FIRED_INTERNAL_STYLE } from '@akinon/ui-theme';
|
|
3
|
+
import { type TabsProps as AntTabsProps } from 'antd';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
|
|
6
|
+
type SMergedHTMLAttributes = React.HTMLAttributes<HTMLElement> &
|
|
7
|
+
React.ButtonHTMLAttributes<HTMLButtonElement> &
|
|
8
|
+
React.AnchorHTMLAttributes<HTMLAnchorElement>;
|
|
9
|
+
|
|
10
|
+
export type TabBarSize = 'small' | 'middle' | 'large';
|
|
11
|
+
export type Direction = 'left' | 'right' | 'top' | 'bottom';
|
|
12
|
+
|
|
13
|
+
export type TabItem = {
|
|
14
|
+
/**
|
|
15
|
+
* Whether destroy inactive TabPane when change tab.
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
destroyOnHidden?: boolean;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Set TabPane disabled.
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Forced render of content in tabs, not lazy render after clicking on tabs.
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
forceRender?: boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* TabPane's key.
|
|
34
|
+
* @required
|
|
35
|
+
*/
|
|
36
|
+
key: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Tab header text element.
|
|
40
|
+
* @required
|
|
41
|
+
*/
|
|
42
|
+
label: ReactNode;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Tab content element.
|
|
46
|
+
*/
|
|
47
|
+
children?: ReactNode;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Tab header icon element.
|
|
51
|
+
* @required
|
|
52
|
+
*/
|
|
53
|
+
icon: IconName;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export interface ITabsProps extends SMergedHTMLAttributes {
|
|
57
|
+
/**
|
|
58
|
+
* Current TabPane's key.
|
|
59
|
+
**/
|
|
60
|
+
activeKey?: string;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Initial active TabPane's key, if activeKey is not set.
|
|
64
|
+
* @default key of tabpane at index 0
|
|
65
|
+
**/
|
|
66
|
+
defaultActiveKey?: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Configure tab content.
|
|
70
|
+
* @default []
|
|
71
|
+
**/
|
|
72
|
+
items?: TabItem[];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Replace the TabBar with a custom one.
|
|
76
|
+
*/
|
|
77
|
+
renderTabBar?: AntTabsProps['renderTabBar'];
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Preset tab bar size.
|
|
81
|
+
* @default 'middle'
|
|
82
|
+
*/
|
|
83
|
+
size?: TabBarSize;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Whether the tabs should be centered.
|
|
87
|
+
* @default true
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
centered?: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Whether destroy inactive TabPane when change tabs.
|
|
94
|
+
* @default false
|
|
95
|
+
*/
|
|
96
|
+
destroyOnHidden?: boolean;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Trigger when Tab is changed.
|
|
100
|
+
*/
|
|
101
|
+
onChange?: (activeKey: string) => void;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Callback executed when tab is clicked.
|
|
105
|
+
*/
|
|
106
|
+
onTabClick?: (key: string, event: MouseEvent) => void;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Trigger when tab scroll.
|
|
110
|
+
*/
|
|
111
|
+
onTabScroll?: ({ direction }: { direction: Direction }) => void;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Never use this prop. Akinon design system does not allow custom styles.
|
|
115
|
+
* @ignore
|
|
116
|
+
*/
|
|
117
|
+
tabBarStyle: DO_NOT_USE_OR_YOU_WILL_BE_FIRED_INTERNAL_STYLE;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Never use this prop. Akinon design system does not allow custom styles.
|
|
121
|
+
* @ignore
|
|
122
|
+
*/
|
|
123
|
+
style?: DO_NOT_USE_OR_YOU_WILL_BE_FIRED_INTERNAL_STYLE;
|
|
124
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ITabsProps, TabItem } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Tabs component for Akinon UI.
|
|
5
|
+
*
|
|
6
|
+
* This versatile component provides a tabbed interface for organizing and displaying content in separate panels.
|
|
7
|
+
* It allows users to navigate between different content sections within the same page, enhancing user experience
|
|
8
|
+
* and content accessibility. Each tab features an icon and label combination with visual feedback for active states.
|
|
9
|
+
*
|
|
10
|
+
* The component accepts default <a href="https://react.dev/reference/react-dom/components/common#common-props" target="_blank" rel="noopener noreferrer">React HTML attributes</a>,
|
|
11
|
+
* as well as attributes specific to <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes" target="_blank" rel="noopener noreferrer">HTMLDivElement</a>,
|
|
12
|
+
* providing flexible integration within the Akinon design system with support for icon-based navigation and customizable layouts.
|
|
13
|
+
*/
|
|
14
|
+
export declare const Tabs: ({ items, centered, ...restProps }: ITabsProps) => React.JSX.Element;
|
|
15
|
+
export type { ITabsProps, TabItem };
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,IAAI,GAAI,mCAIlB,UAAU,sBAiHZ,CAAC;AAEF,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { Icon } from '@akinon/icons';
|
|
13
|
+
import { getSafeCustomTokens, useToken } from '@akinon/ui-theme';
|
|
14
|
+
import { useStyleRegister } from '@ant-design/cssinjs';
|
|
15
|
+
import { ConfigProvider, Tabs as AntTabs } from 'antd';
|
|
16
|
+
import * as React from 'react';
|
|
17
|
+
/**
|
|
18
|
+
* Tabs component for Akinon UI.
|
|
19
|
+
*
|
|
20
|
+
* This versatile component provides a tabbed interface for organizing and displaying content in separate panels.
|
|
21
|
+
* It allows users to navigate between different content sections within the same page, enhancing user experience
|
|
22
|
+
* and content accessibility. Each tab features an icon and label combination with visual feedback for active states.
|
|
23
|
+
*
|
|
24
|
+
* The component accepts default <a href="https://react.dev/reference/react-dom/components/common#common-props" target="_blank" rel="noopener noreferrer">React HTML attributes</a>,
|
|
25
|
+
* as well as attributes specific to <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes" target="_blank" rel="noopener noreferrer">HTMLDivElement</a>,
|
|
26
|
+
* providing flexible integration within the Akinon design system with support for icon-based navigation and customizable layouts.
|
|
27
|
+
*/
|
|
28
|
+
export const Tabs = (_a) => {
|
|
29
|
+
var { items = [], centered = true } = _a, restProps = __rest(_a, ["items", "centered"]);
|
|
30
|
+
const tabsItemsWithIcons = items.map(item => (Object.assign(Object.assign({}, item), { icon: item.icon ? React.createElement(Icon, { icon: item.icon }) : undefined })));
|
|
31
|
+
const { getPrefixCls, theme } = React.useContext(ConfigProvider.ConfigContext);
|
|
32
|
+
const { token, hashId } = useToken();
|
|
33
|
+
const prefixClsWithoutHash = `.${getPrefixCls()}-tabs`;
|
|
34
|
+
const prefixCls = `:where(.${hashId})${prefixClsWithoutHash}`;
|
|
35
|
+
const customTokens = getSafeCustomTokens(theme);
|
|
36
|
+
const tabsTokens = token.Tabs;
|
|
37
|
+
const menuBarTabGap = tabsTokens.menuGap;
|
|
38
|
+
const useStyle = useStyleRegister({
|
|
39
|
+
token: token,
|
|
40
|
+
path: ['Tabs'],
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
+
theme: theme
|
|
43
|
+
}, () => {
|
|
44
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
|
|
45
|
+
return {
|
|
46
|
+
[`${prefixCls}`]: {},
|
|
47
|
+
[`${prefixCls} ${prefixClsWithoutHash}-ink-bar`]: {
|
|
48
|
+
display: (_a = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _a === void 0 ? void 0 : _a.displayNone
|
|
49
|
+
},
|
|
50
|
+
[`${prefixCls} ${prefixClsWithoutHash}-nav`]: {
|
|
51
|
+
borderBottom: (_b = customTokens === null || customTokens === void 0 ? void 0 : customTokens.border) === null || _b === void 0 ? void 0 : _b.borderNone,
|
|
52
|
+
['::before']: {
|
|
53
|
+
borderBottom: (_c = customTokens === null || customTokens === void 0 ? void 0 : customTokens.border) === null || _c === void 0 ? void 0 : _c.borderNone
|
|
54
|
+
},
|
|
55
|
+
['&-wrap']: {
|
|
56
|
+
padding: tabsTokens.navWrapperPadding
|
|
57
|
+
},
|
|
58
|
+
['&-list']: {
|
|
59
|
+
gap: menuBarTabGap
|
|
60
|
+
},
|
|
61
|
+
[`${prefixClsWithoutHash}-tab`]: {
|
|
62
|
+
margin: (_d = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _d === void 0 ? void 0 : _d.valueZero,
|
|
63
|
+
position: (_e = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _e === void 0 ? void 0 : _e.positionRelative,
|
|
64
|
+
color: tabsTokens.textColor,
|
|
65
|
+
fontWeight: (_f = customTokens === null || customTokens === void 0 ? void 0 : customTokens.typography) === null || _f === void 0 ? void 0 : _f.fontWeightBold,
|
|
66
|
+
[`&-btn`]: {
|
|
67
|
+
display: (_g = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _g === void 0 ? void 0 : _g.displayFlex,
|
|
68
|
+
flexDirection: (_h = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _h === void 0 ? void 0 : _h.flexDirectionColumn,
|
|
69
|
+
alignItems: (_j = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _j === void 0 ? void 0 : _j.flexCenter,
|
|
70
|
+
justifyContent: (_k = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _k === void 0 ? void 0 : _k.flexCenter,
|
|
71
|
+
position: (_l = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _l === void 0 ? void 0 : _l.positionRelative,
|
|
72
|
+
[`${prefixClsWithoutHash}-tab-icon`]: {
|
|
73
|
+
background: tabsTokens.tabIconBg,
|
|
74
|
+
borderRadius: (_m = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _m === void 0 ? void 0 : _m.valueHalf,
|
|
75
|
+
width: tabsTokens.tabIconWrapperSize,
|
|
76
|
+
height: tabsTokens.tabIconWrapperSize,
|
|
77
|
+
marginRight: (_o = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _o === void 0 ? void 0 : _o.valueZero,
|
|
78
|
+
transition: tabsTokens.tabIconBgTransition,
|
|
79
|
+
display: (_p = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _p === void 0 ? void 0 : _p.displayFlex,
|
|
80
|
+
alignItems: (_q = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _q === void 0 ? void 0 : _q.flexCenter,
|
|
81
|
+
justifyContent: (_r = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _r === void 0 ? void 0 : _r.flexCenter,
|
|
82
|
+
['svg']: {
|
|
83
|
+
width: tabsTokens.tabIconSize,
|
|
84
|
+
height: tabsTokens.tabIconSize,
|
|
85
|
+
fill: tabsTokens.tabIconFill,
|
|
86
|
+
transition: tabsTokens.tabIconFillTransition
|
|
87
|
+
},
|
|
88
|
+
['+ span']: {
|
|
89
|
+
position: (_s = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _s === void 0 ? void 0 : _s.positionAbsolute,
|
|
90
|
+
bottom: (_t = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _t === void 0 ? void 0 : _t.valueZero,
|
|
91
|
+
transform: tabsTokens.tabLabelTransform
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
[`+ ${prefixClsWithoutHash}-tab::before`]: {
|
|
96
|
+
content: (_u = customTokens === null || customTokens === void 0 ? void 0 : customTokens.others) === null || _u === void 0 ? void 0 : _u.emptyContent,
|
|
97
|
+
position: (_v = customTokens === null || customTokens === void 0 ? void 0 : customTokens.layout) === null || _v === void 0 ? void 0 : _v.positionAbsolute,
|
|
98
|
+
top: (_w = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _w === void 0 ? void 0 : _w.valueHalf,
|
|
99
|
+
left: (_x = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _x === void 0 ? void 0 : _x.valueZero,
|
|
100
|
+
transform: `translate(-${(_y = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _y === void 0 ? void 0 : _y.valueFull}, -${(_z = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _z === void 0 ? void 0 : _z.valueHalf})`,
|
|
101
|
+
height: tabsTokens.separatorHeight,
|
|
102
|
+
width: menuBarTabGap,
|
|
103
|
+
backgroundColor: tabsTokens.separatorColor
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
[`${prefixCls} ${prefixClsWithoutHash}-tab${prefixClsWithoutHash}-tab-active ${prefixClsWithoutHash}-tab-btn`]: {
|
|
108
|
+
color: tabsTokens.textColor,
|
|
109
|
+
[`${prefixClsWithoutHash}-tab-icon`]: {
|
|
110
|
+
backgroundColor: tabsTokens.tabIconActiveBg,
|
|
111
|
+
['svg']: {
|
|
112
|
+
fill: tabsTokens.tabIconActiveFill
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
[`${prefixCls}${prefixClsWithoutHash}-centered ${prefixClsWithoutHash}-nav-wrap`]: {
|
|
117
|
+
paddingLeft: (_0 = customTokens === null || customTokens === void 0 ? void 0 : customTokens.sizing) === null || _0 === void 0 ? void 0 : _0.valueZero
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
return useStyle(React.createElement(AntTabs, Object.assign({}, restProps, { items: tabsItemsWithIcons, centered: centered })));
|
|
122
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { IconName } from '@akinon/icons';
|
|
2
|
+
import { type DO_NOT_USE_OR_YOU_WILL_BE_FIRED_INTERNAL_STYLE } from '@akinon/ui-theme';
|
|
3
|
+
import { type TabsProps as AntTabsProps } from 'antd';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
|
|
6
|
+
type SMergedHTMLAttributes = React.HTMLAttributes<HTMLElement> &
|
|
7
|
+
React.ButtonHTMLAttributes<HTMLButtonElement> &
|
|
8
|
+
React.AnchorHTMLAttributes<HTMLAnchorElement>;
|
|
9
|
+
|
|
10
|
+
export type TabBarSize = 'small' | 'middle' | 'large';
|
|
11
|
+
export type Direction = 'left' | 'right' | 'top' | 'bottom';
|
|
12
|
+
|
|
13
|
+
export type TabItem = {
|
|
14
|
+
/**
|
|
15
|
+
* Whether destroy inactive TabPane when change tab.
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
destroyOnHidden?: boolean;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Set TabPane disabled.
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Forced render of content in tabs, not lazy render after clicking on tabs.
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
forceRender?: boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* TabPane's key.
|
|
34
|
+
* @required
|
|
35
|
+
*/
|
|
36
|
+
key: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Tab header text element.
|
|
40
|
+
* @required
|
|
41
|
+
*/
|
|
42
|
+
label: ReactNode;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Tab content element.
|
|
46
|
+
*/
|
|
47
|
+
children?: ReactNode;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Tab header icon element.
|
|
51
|
+
* @required
|
|
52
|
+
*/
|
|
53
|
+
icon: IconName;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export interface ITabsProps extends SMergedHTMLAttributes {
|
|
57
|
+
/**
|
|
58
|
+
* Current TabPane's key.
|
|
59
|
+
**/
|
|
60
|
+
activeKey?: string;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Initial active TabPane's key, if activeKey is not set.
|
|
64
|
+
* @default key of tabpane at index 0
|
|
65
|
+
**/
|
|
66
|
+
defaultActiveKey?: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Configure tab content.
|
|
70
|
+
* @default []
|
|
71
|
+
**/
|
|
72
|
+
items?: TabItem[];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Replace the TabBar with a custom one.
|
|
76
|
+
*/
|
|
77
|
+
renderTabBar?: AntTabsProps['renderTabBar'];
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Preset tab bar size.
|
|
81
|
+
* @default 'middle'
|
|
82
|
+
*/
|
|
83
|
+
size?: TabBarSize;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Whether the tabs should be centered.
|
|
87
|
+
* @default true
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
centered?: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Whether destroy inactive TabPane when change tabs.
|
|
94
|
+
* @default false
|
|
95
|
+
*/
|
|
96
|
+
destroyOnHidden?: boolean;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Trigger when Tab is changed.
|
|
100
|
+
*/
|
|
101
|
+
onChange?: (activeKey: string) => void;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Callback executed when tab is clicked.
|
|
105
|
+
*/
|
|
106
|
+
onTabClick?: (key: string, event: MouseEvent) => void;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Trigger when tab scroll.
|
|
110
|
+
*/
|
|
111
|
+
onTabScroll?: ({ direction }: { direction: Direction }) => void;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Never use this prop. Akinon design system does not allow custom styles.
|
|
115
|
+
* @ignore
|
|
116
|
+
*/
|
|
117
|
+
tabBarStyle: DO_NOT_USE_OR_YOU_WILL_BE_FIRED_INTERNAL_STYLE;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Never use this prop. Akinon design system does not allow custom styles.
|
|
121
|
+
* @ignore
|
|
122
|
+
*/
|
|
123
|
+
style?: DO_NOT_USE_OR_YOU_WILL_BE_FIRED_INTERNAL_STYLE;
|
|
124
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@akinon/ui-tabs",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/esm/index.js",
|
|
7
|
+
"module": "dist/esm/index.js",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@ant-design/cssinjs": "^1.24.0",
|
|
13
|
+
"antd": "^5.27.0",
|
|
14
|
+
"@akinon/icons": "1.2.1",
|
|
15
|
+
"@akinon/ui-theme": "1.2.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"clean-package": "2.2.0",
|
|
19
|
+
"copyfiles": "^2.4.1",
|
|
20
|
+
"rimraf": "^5.0.5",
|
|
21
|
+
"typescript": "*",
|
|
22
|
+
"@akinon/typescript-config": "1.1.1"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"react": "^18 || ^19",
|
|
26
|
+
"react-dom": "^18 || ^19"
|
|
27
|
+
},
|
|
28
|
+
"clean-package": "../../../clean-package.config.json",
|
|
29
|
+
"types": "dist/esm/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/esm/index.d.ts",
|
|
33
|
+
"import": "./dist/esm/index.js",
|
|
34
|
+
"require": "./dist/cjs/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./package.json": "./package.json"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "pnpm run build:esm && pnpm run build:commonjs && pnpm run copy:files",
|
|
40
|
+
"build:commonjs": "tsc --module commonjs --outDir dist/cjs",
|
|
41
|
+
"build:esm": "tsc --outDir dist/esm",
|
|
42
|
+
"clean": "rimraf dist/",
|
|
43
|
+
"copy:files": "copyfiles -u 1 \"src/**/*.!(ts|tsx)\" dist/esm && copyfiles -u 1 \"src/**/*.!(ts|tsx)\" dist/cjs",
|
|
44
|
+
"typecheck": "tsc --noEmit"
|
|
45
|
+
}
|
|
46
|
+
}
|