@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.
@@ -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
+ }