@arcblock/ux 2.9.22 → 2.9.24

Sign up to get free protection for your applications and to get access to all the features.
@@ -25,6 +25,7 @@ const colors = {
25
25
  // border
26
26
  strokeBorderBase: 'rgba(229, 231, 235, 1)',
27
27
  strokeBorderStrong: 'rgba(209, 213, 219, 1)',
28
+ strokeSep: 'rgba(229, 231, 235, 1)',
28
29
  lineStep: 'rgba(18, 22, 24, 0.06)',
29
30
  lineBorderStrong: 'rgba(18, 22, 24, 0.12)',
30
31
  lineBorderBase: 'rgba(18, 22, 24, 0.06)',
package/es/Empty/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import PropTypes from 'prop-types';
2
+ import { Box } from '@mui/material';
2
3
  import EmptyIcon from '@arcblock/icons/lib/EmptyIcon';
3
4
  import { styled } from '../Theme';
4
5
  import { jsx as _jsx } from "react/jsx-runtime";
5
6
  import { jsxs as _jsxs } from "react/jsx-runtime";
6
- const Wrapper = styled('div')`
7
+ const Wrapper = styled(Box)`
7
8
  display: flex;
8
9
  justify-content: center;
9
10
  align-items: center;
@@ -45,7 +46,7 @@ function Empty({
45
46
  color
46
47
  },
47
48
  className: "empty-icon"
48
- }), /*#__PURE__*/_jsx("div", {
49
+ }), /*#__PURE__*/_jsx(Box, {
49
50
  className: "empty-content",
50
51
  children: children
51
52
  })]
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
2
2
  import relativeTime from 'dayjs/plugin/relativeTime';
3
3
  import dayjs from 'dayjs';
4
4
  import 'dayjs/locale/zh-cn';
5
- import Tooltip from '@mui/material/Tooltip';
5
+ import { Tooltip } from '@mui/material';
6
6
  import localizedFormat from 'dayjs/plugin/localizedFormat';
7
7
  import utc from 'dayjs/plugin/utc';
8
8
  import timezone from 'dayjs/plugin/timezone';
@@ -41,6 +41,7 @@ export default function RelativeTime({
41
41
  to,
42
42
  type,
43
43
  tz,
44
+ relativeRange,
44
45
  ...rest
45
46
  }) {
46
47
  if (!value) {
@@ -51,18 +52,24 @@ export default function RelativeTime({
51
52
  if (tz) {
52
53
  datetime.tz(tz);
53
54
  }
55
+ const absoluteString = formatToDatetime(value, {
56
+ locale: localeOption,
57
+ tz
58
+ });
54
59
  let relativeString;
55
60
  if (from) {
56
61
  relativeString = datetime.from(from, withoutSuffix);
57
62
  } else if (to) {
58
63
  relativeString = datetime.to(to, withoutSuffix);
59
- } else {
64
+ } else if (relativeRange) {
65
+ const diffTime = datetime.diff(dayjs());
66
+ if (Math.abs(diffTime) > relativeRange) {
67
+ relativeString = absoluteString;
68
+ }
69
+ }
70
+ if (!relativeString) {
60
71
  relativeString = datetime.fromNow(withoutSuffix);
61
72
  }
62
- const absoluteString = formatToDatetime(value, {
63
- locale: localeOption,
64
- tz
65
- });
66
73
  let innerContent = relativeString;
67
74
  let popContent = absoluteString;
68
75
  if (type === 'absolute') {
@@ -86,7 +93,8 @@ RelativeTime.propTypes = {
86
93
  from: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
87
94
  to: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
88
95
  type: PropTypes.oneOf(['relative', 'absolute']),
89
- tz: PropTypes.string
96
+ tz: PropTypes.string,
97
+ relativeRange: PropTypes.number
90
98
  };
91
99
  RelativeTime.defaultProps = {
92
100
  locale: 'en',
@@ -94,5 +102,6 @@ RelativeTime.defaultProps = {
94
102
  from: '',
95
103
  to: '',
96
104
  type: 'relative',
97
- tz: undefined
105
+ tz: undefined,
106
+ relativeRange: undefined
98
107
  };
@@ -0,0 +1,175 @@
1
+ import PropTypes from 'prop-types';
2
+ import { Box } from '@mui/material';
3
+
4
+ // FIXME: @zhanghan 目前无法适配各种 size,后续优化
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { jsxs as _jsxs } from "react/jsx-runtime";
7
+ export default function Success({
8
+ size,
9
+ backgroundColor,
10
+ borderWidth
11
+ }) {
12
+ const contentSize = size - borderWidth * 2;
13
+ return /*#__PURE__*/_jsxs(Box, {
14
+ className: "check-icon",
15
+ sx: {
16
+ width: contentSize,
17
+ height: contentSize,
18
+ position: 'relative',
19
+ borderRadius: '100%',
20
+ '&, *, *::before, *::after': {
21
+ boxSizing: 'content-box !important'
22
+ },
23
+ border: theme => `${borderWidth}px solid ${theme.palette.success.main}`,
24
+ '&::before, &::after': {
25
+ content: '""',
26
+ height: '125%',
27
+ position: 'absolute',
28
+ background: backgroundColor,
29
+ transform: 'rotate(-45deg)'
30
+ },
31
+ '&::before': {
32
+ top: `${borderWidth / 2 + 1}px`,
33
+ left: `-${borderWidth / 2}px`,
34
+ width: `calc(32.5% + ${borderWidth}px)`,
35
+ transformOrigin: '100% 50%',
36
+ borderRadius: '100% 0 0 100%'
37
+ },
38
+ '&::after': {
39
+ top: 0,
40
+ left: '37.5%',
41
+ width: `calc(70% + ${borderWidth}px)`,
42
+ transformOrigin: '0 50%',
43
+ borderRadius: '0 100% 100% 0',
44
+ animation: 'rotate-circle 4.25s ease-in'
45
+ },
46
+ '.icon-line': {
47
+ height: `${borderWidth + 1}px`,
48
+ backgroundColor: theme => theme.palette.success.main,
49
+ display: 'block',
50
+ borderRadius: '100vw',
51
+ position: 'absolute',
52
+ zIndex: 10
53
+ },
54
+ '@keyframes rotate-circle': {
55
+ '0%': {
56
+ transform: 'rotate(-45deg)'
57
+ },
58
+ '5%': {
59
+ transform: 'rotate(-45deg)'
60
+ },
61
+ '12%': {
62
+ transform: 'rotate(-405deg)'
63
+ },
64
+ '100%': {
65
+ transform: 'rotate(-405deg)'
66
+ }
67
+ }
68
+ },
69
+ children: [/*#__PURE__*/_jsx(Box, {
70
+ component: "span",
71
+ className: "icon-line line-tip",
72
+ sx: {
73
+ top: '57.5%',
74
+ left: '17.5%',
75
+ width: '31.25%',
76
+ transform: 'rotate(45deg)',
77
+ animation: 'icon-line-tip 0.75s',
78
+ '@keyframes icon-line-tip': {
79
+ '0%': {
80
+ width: '0',
81
+ left: '1px',
82
+ top: '23.75%'
83
+ },
84
+ '54%': {
85
+ width: '0',
86
+ left: '1px',
87
+ top: '23.75%'
88
+ },
89
+ '70%': {
90
+ width: '62.5%',
91
+ left: '-10%',
92
+ top: '46.25%'
93
+ },
94
+ '84%': {
95
+ width: '21.25%',
96
+ left: '26.25%',
97
+ top: '60%'
98
+ },
99
+ '100%': {
100
+ width: '31.25',
101
+ left: '17.5%',
102
+ top: '56.25%'
103
+ }
104
+ }
105
+ }
106
+ }), /*#__PURE__*/_jsx(Box, {
107
+ component: "span",
108
+ className: "icon-line line-long",
109
+ sx: {
110
+ top: '47.5%',
111
+ right: '10%',
112
+ width: '58.75%',
113
+ transform: 'rotate(-45deg)',
114
+ animation: 'icon-line-long 0.75s',
115
+ '@keyframes icon-line-long': {
116
+ '0%': {
117
+ width: '0',
118
+ right: '57.5%',
119
+ top: '67.5%'
120
+ },
121
+ '65%': {
122
+ width: '0',
123
+ right: '57.5%',
124
+ top: '67.5%'
125
+ },
126
+ '84%': {
127
+ width: '68.75%',
128
+ right: '0px',
129
+ top: '43.75%'
130
+ },
131
+ '100%': {
132
+ width: '58.75%',
133
+ right: '10%',
134
+ top: '47.5%'
135
+ }
136
+ }
137
+ }
138
+ }), /*#__PURE__*/_jsx(Box, {
139
+ className: "icon-circle",
140
+ sx: {
141
+ top: `-${borderWidth}px`,
142
+ left: `-${borderWidth}px`,
143
+ zIndex: 10,
144
+ width: contentSize,
145
+ height: contentSize,
146
+ borderRadius: '100%',
147
+ position: 'absolute',
148
+ boxSizing: 'contentBox',
149
+ border: `${borderWidth}px solid rgba(76, 175, 80, 0.5)`
150
+ }
151
+ }), /*#__PURE__*/_jsx(Box, {
152
+ className: "icon-fix",
153
+ sx: {
154
+ top: `calc(8% - ${Math.sqrt(borderWidth)}px)`,
155
+ width: borderWidth + 1,
156
+ left: `calc(32% - ${Math.sqrt(borderWidth)}px)`,
157
+ zIndex: 1,
158
+ height: contentSize + borderWidth * 2,
159
+ position: 'absolute',
160
+ transform: 'rotate(-45deg)',
161
+ backgroundColor
162
+ }
163
+ })]
164
+ });
165
+ }
166
+ Success.propTypes = {
167
+ size: PropTypes.number,
168
+ borderWidth: PropTypes.number,
169
+ backgroundColor: PropTypes.string
170
+ };
171
+ Success.defaultProps = {
172
+ size: 64,
173
+ borderWidth: 4,
174
+ backgroundColor: 'white'
175
+ };
package/es/Tabs/index.js CHANGED
@@ -83,12 +83,81 @@ CardTabs.propTypes = {
83
83
  current: PropTypes.string.isRequired,
84
84
  onChange: PropTypes.func.isRequired
85
85
  };
86
+ function LineTabs({
87
+ tabs,
88
+ current,
89
+ onChange,
90
+ ...rest
91
+ }) {
92
+ return /*#__PURE__*/_jsx(MuiTabs, {
93
+ scrollButtons: "auto",
94
+ value: current,
95
+ onChange: (_, newValue) => onChange(newValue),
96
+ ...rest,
97
+ variant: "scrollable",
98
+ sx: {
99
+ minHeight: 'auto',
100
+ '.MuiTabs-scrollButtons.Mui-disabled': {
101
+ opacity: 0.3,
102
+ cursor: 'not-allowed',
103
+ pointerEvents: 'auto'
104
+ },
105
+ '.MuiTabs-scroller': {
106
+ '&::after': {
107
+ content: '""',
108
+ display: 'block',
109
+ width: '100%',
110
+ height: '1px',
111
+ backgroundColor: colors.strokeBorderStrong,
112
+ bottom: 0
113
+ }
114
+ },
115
+ '.MuiTabs-flexContainer': {
116
+ display: 'inline-flex',
117
+ columnGap: 2.5,
118
+ px: 0,
119
+ pb: 0.5
120
+ },
121
+ '.MuiTab-root': {
122
+ border: '1px solid transparent',
123
+ minHeight: 'auto',
124
+ lineHeight: 1,
125
+ py: 1,
126
+ px: 0,
127
+ color: colors.foregroundsFgSubtile,
128
+ fontSize: '14px',
129
+ fontWeight: 500,
130
+ textTransform: 'capitalize',
131
+ minWidth: 'auto',
132
+ '&.Mui-selected, &:hover': {
133
+ color: colors.foregroundsFgBase
134
+ }
135
+ },
136
+ '.MuiTabs-indicator': {
137
+ height: '1px',
138
+ backgroundColor: colors.foregroundsFgBase
139
+ },
140
+ ...rest.sx
141
+ },
142
+ children: tabs.map(x => /*#__PURE__*/_jsx(MuiTab, {
143
+ className: classes.tab,
144
+ value: x.value,
145
+ label: x.label,
146
+ icon: x.icon || null
147
+ }, x.value))
148
+ });
149
+ }
150
+ LineTabs.propTypes = {
151
+ tabs: PropTypes.array.isRequired,
152
+ current: PropTypes.string.isRequired,
153
+ onChange: PropTypes.func.isRequired
154
+ };
86
155
 
87
156
  /**
88
157
  * @typedef {import('@mui/material').TabsProps & {
89
158
  * tabs: string[];
90
159
  * onChange: (value) => {};
91
- * variant: 'card' | 'fullWidth' | 'scrollable' | 'standard'
160
+ * variant: 'line' | 'card' | 'fullWidth' | 'scrollable' | 'standard'
92
161
  * }} TabsProps
93
162
  */
94
163
 
@@ -106,6 +175,15 @@ export default function Tabs({
106
175
  }) {
107
176
  if (rest.variant === 'card') {
108
177
  return /*#__PURE__*/_jsx(CardTabs, {
178
+ ...rest,
179
+ tabs: tabs,
180
+ current: current,
181
+ onChange: onChange
182
+ });
183
+ }
184
+ if (rest.variant === 'line') {
185
+ return /*#__PURE__*/_jsx(LineTabs, {
186
+ ...rest,
109
187
  tabs: tabs,
110
188
  current: current,
111
189
  onChange: onChange
@@ -31,6 +31,7 @@ const colors = {
31
31
  // border
32
32
  strokeBorderBase: 'rgba(229, 231, 235, 1)',
33
33
  strokeBorderStrong: 'rgba(209, 213, 219, 1)',
34
+ strokeSep: 'rgba(229, 231, 235, 1)',
34
35
  lineStep: 'rgba(18, 22, 24, 0.06)',
35
36
  lineBorderStrong: 'rgba(18, 22, 24, 0.12)',
36
37
  lineBorderBase: 'rgba(18, 22, 24, 0.06)',
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _propTypes = _interopRequireDefault(require("prop-types"));
8
+ var _material = require("@mui/material");
8
9
  var _EmptyIcon = _interopRequireDefault(require("@arcblock/icons/lib/EmptyIcon"));
9
10
  var _Theme = require("../Theme");
10
11
  var _jsxRuntime = require("react/jsx-runtime");
@@ -19,7 +20,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
19
20
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
20
21
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
21
22
  function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
22
- const Wrapper = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n height: 100%;\n min-height: 100px;\n color: #999;\n .empty-icon {\n margin: 10px 0;\n }\n"])));
23
+ const Wrapper = (0, _Theme.styled)(_material.Box)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n height: 100%;\n min-height: 100px;\n color: #999;\n .empty-icon {\n margin: 10px 0;\n }\n"])));
23
24
 
24
25
  /**
25
26
  * Empty component to display empty state
@@ -50,7 +51,7 @@ function Empty(_ref) {
50
51
  color
51
52
  },
52
53
  className: "empty-icon"
53
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
54
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
54
55
  className: "empty-content",
55
56
  children: children
56
57
  })]
@@ -8,14 +8,14 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
8
8
  var _relativeTime = _interopRequireDefault(require("dayjs/plugin/relativeTime"));
9
9
  var _dayjs = _interopRequireDefault(require("dayjs"));
10
10
  require("dayjs/locale/zh-cn");
11
- var _Tooltip = _interopRequireDefault(require("@mui/material/Tooltip"));
11
+ var _material = require("@mui/material");
12
12
  var _localizedFormat = _interopRequireDefault(require("dayjs/plugin/localizedFormat"));
13
13
  var _utc = _interopRequireDefault(require("dayjs/plugin/utc"));
14
14
  var _timezone = _interopRequireDefault(require("dayjs/plugin/timezone"));
15
15
  var _updateLocale = _interopRequireDefault(require("dayjs/plugin/updateLocale"));
16
16
  var _Util = require("../Util");
17
17
  var _jsxRuntime = require("react/jsx-runtime");
18
- const _excluded = ["value", "locale", "withoutSuffix", "from", "to", "type", "tz"];
18
+ const _excluded = ["value", "locale", "withoutSuffix", "from", "to", "type", "tz", "relativeRange"];
19
19
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
20
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
21
21
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -56,7 +56,8 @@ function RelativeTime(_ref) {
56
56
  from,
57
57
  to,
58
58
  type,
59
- tz
59
+ tz,
60
+ relativeRange
60
61
  } = _ref,
61
62
  rest = _objectWithoutProperties(_ref, _excluded);
62
63
  if (!value) {
@@ -67,25 +68,31 @@ function RelativeTime(_ref) {
67
68
  if (tz) {
68
69
  datetime.tz(tz);
69
70
  }
71
+ const absoluteString = (0, _Util.formatToDatetime)(value, {
72
+ locale: localeOption,
73
+ tz
74
+ });
70
75
  let relativeString;
71
76
  if (from) {
72
77
  relativeString = datetime.from(from, withoutSuffix);
73
78
  } else if (to) {
74
79
  relativeString = datetime.to(to, withoutSuffix);
75
- } else {
80
+ } else if (relativeRange) {
81
+ const diffTime = datetime.diff((0, _dayjs.default)());
82
+ if (Math.abs(diffTime) > relativeRange) {
83
+ relativeString = absoluteString;
84
+ }
85
+ }
86
+ if (!relativeString) {
76
87
  relativeString = datetime.fromNow(withoutSuffix);
77
88
  }
78
- const absoluteString = (0, _Util.formatToDatetime)(value, {
79
- locale: localeOption,
80
- tz
81
- });
82
89
  let innerContent = relativeString;
83
90
  let popContent = absoluteString;
84
91
  if (type === 'absolute') {
85
92
  innerContent = absoluteString;
86
93
  popContent = relativeString;
87
94
  }
88
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, {
95
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, {
89
96
  title: popContent,
90
97
  placement: "top-end",
91
98
  enterTouchDelay: 0,
@@ -101,7 +108,8 @@ RelativeTime.propTypes = {
101
108
  from: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
102
109
  to: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
103
110
  type: _propTypes.default.oneOf(['relative', 'absolute']),
104
- tz: _propTypes.default.string
111
+ tz: _propTypes.default.string,
112
+ relativeRange: _propTypes.default.number
105
113
  };
106
114
  RelativeTime.defaultProps = {
107
115
  locale: 'en',
@@ -109,5 +117,6 @@ RelativeTime.defaultProps = {
109
117
  from: '',
110
118
  to: '',
111
119
  type: 'relative',
112
- tz: undefined
120
+ tz: undefined,
121
+ relativeRange: undefined
113
122
  };
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = Success;
7
+ var _propTypes = _interopRequireDefault(require("prop-types"));
8
+ var _material = require("@mui/material");
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ // FIXME: @zhanghan 目前无法适配各种 size,后续优化
12
+ function Success(_ref) {
13
+ let {
14
+ size,
15
+ backgroundColor,
16
+ borderWidth
17
+ } = _ref;
18
+ const contentSize = size - borderWidth * 2;
19
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
20
+ className: "check-icon",
21
+ sx: {
22
+ width: contentSize,
23
+ height: contentSize,
24
+ position: 'relative',
25
+ borderRadius: '100%',
26
+ '&, *, *::before, *::after': {
27
+ boxSizing: 'content-box !important'
28
+ },
29
+ border: theme => "".concat(borderWidth, "px solid ").concat(theme.palette.success.main),
30
+ '&::before, &::after': {
31
+ content: '""',
32
+ height: '125%',
33
+ position: 'absolute',
34
+ background: backgroundColor,
35
+ transform: 'rotate(-45deg)'
36
+ },
37
+ '&::before': {
38
+ top: "".concat(borderWidth / 2 + 1, "px"),
39
+ left: "-".concat(borderWidth / 2, "px"),
40
+ width: "calc(32.5% + ".concat(borderWidth, "px)"),
41
+ transformOrigin: '100% 50%',
42
+ borderRadius: '100% 0 0 100%'
43
+ },
44
+ '&::after': {
45
+ top: 0,
46
+ left: '37.5%',
47
+ width: "calc(70% + ".concat(borderWidth, "px)"),
48
+ transformOrigin: '0 50%',
49
+ borderRadius: '0 100% 100% 0',
50
+ animation: 'rotate-circle 4.25s ease-in'
51
+ },
52
+ '.icon-line': {
53
+ height: "".concat(borderWidth + 1, "px"),
54
+ backgroundColor: theme => theme.palette.success.main,
55
+ display: 'block',
56
+ borderRadius: '100vw',
57
+ position: 'absolute',
58
+ zIndex: 10
59
+ },
60
+ '@keyframes rotate-circle': {
61
+ '0%': {
62
+ transform: 'rotate(-45deg)'
63
+ },
64
+ '5%': {
65
+ transform: 'rotate(-45deg)'
66
+ },
67
+ '12%': {
68
+ transform: 'rotate(-405deg)'
69
+ },
70
+ '100%': {
71
+ transform: 'rotate(-405deg)'
72
+ }
73
+ }
74
+ },
75
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
76
+ component: "span",
77
+ className: "icon-line line-tip",
78
+ sx: {
79
+ top: '57.5%',
80
+ left: '17.5%',
81
+ width: '31.25%',
82
+ transform: 'rotate(45deg)',
83
+ animation: 'icon-line-tip 0.75s',
84
+ '@keyframes icon-line-tip': {
85
+ '0%': {
86
+ width: '0',
87
+ left: '1px',
88
+ top: '23.75%'
89
+ },
90
+ '54%': {
91
+ width: '0',
92
+ left: '1px',
93
+ top: '23.75%'
94
+ },
95
+ '70%': {
96
+ width: '62.5%',
97
+ left: '-10%',
98
+ top: '46.25%'
99
+ },
100
+ '84%': {
101
+ width: '21.25%',
102
+ left: '26.25%',
103
+ top: '60%'
104
+ },
105
+ '100%': {
106
+ width: '31.25',
107
+ left: '17.5%',
108
+ top: '56.25%'
109
+ }
110
+ }
111
+ }
112
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
113
+ component: "span",
114
+ className: "icon-line line-long",
115
+ sx: {
116
+ top: '47.5%',
117
+ right: '10%',
118
+ width: '58.75%',
119
+ transform: 'rotate(-45deg)',
120
+ animation: 'icon-line-long 0.75s',
121
+ '@keyframes icon-line-long': {
122
+ '0%': {
123
+ width: '0',
124
+ right: '57.5%',
125
+ top: '67.5%'
126
+ },
127
+ '65%': {
128
+ width: '0',
129
+ right: '57.5%',
130
+ top: '67.5%'
131
+ },
132
+ '84%': {
133
+ width: '68.75%',
134
+ right: '0px',
135
+ top: '43.75%'
136
+ },
137
+ '100%': {
138
+ width: '58.75%',
139
+ right: '10%',
140
+ top: '47.5%'
141
+ }
142
+ }
143
+ }
144
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
145
+ className: "icon-circle",
146
+ sx: {
147
+ top: "-".concat(borderWidth, "px"),
148
+ left: "-".concat(borderWidth, "px"),
149
+ zIndex: 10,
150
+ width: contentSize,
151
+ height: contentSize,
152
+ borderRadius: '100%',
153
+ position: 'absolute',
154
+ boxSizing: 'contentBox',
155
+ border: "".concat(borderWidth, "px solid rgba(76, 175, 80, 0.5)")
156
+ }
157
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
158
+ className: "icon-fix",
159
+ sx: {
160
+ top: "calc(8% - ".concat(Math.sqrt(borderWidth), "px)"),
161
+ width: borderWidth + 1,
162
+ left: "calc(32% - ".concat(Math.sqrt(borderWidth), "px)"),
163
+ zIndex: 1,
164
+ height: contentSize + borderWidth * 2,
165
+ position: 'absolute',
166
+ transform: 'rotate(-45deg)',
167
+ backgroundColor
168
+ }
169
+ })]
170
+ });
171
+ }
172
+ Success.propTypes = {
173
+ size: _propTypes.default.number,
174
+ borderWidth: _propTypes.default.number,
175
+ backgroundColor: _propTypes.default.string
176
+ };
177
+ Success.defaultProps = {
178
+ size: 64,
179
+ borderWidth: 4,
180
+ backgroundColor: 'white'
181
+ };
package/lib/Tabs/index.js CHANGED
@@ -10,7 +10,8 @@ var _Colors = require("../Colors");
10
10
  var _Theme = require("../Theme");
11
11
  var _jsxRuntime = require("react/jsx-runtime");
12
12
  const _excluded = ["tabs", "current", "onChange"],
13
- _excluded2 = ["tabs", "current", "onChange"];
13
+ _excluded2 = ["tabs", "current", "onChange"],
14
+ _excluded3 = ["tabs", "current", "onChange"];
14
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
16
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
16
17
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -102,12 +103,81 @@ CardTabs.propTypes = {
102
103
  current: _propTypes.default.string.isRequired,
103
104
  onChange: _propTypes.default.func.isRequired
104
105
  };
106
+ function LineTabs(_ref3) {
107
+ let {
108
+ tabs,
109
+ current,
110
+ onChange: _onChange2
111
+ } = _ref3,
112
+ rest = _objectWithoutProperties(_ref3, _excluded2);
113
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tabs, _objectSpread(_objectSpread({
114
+ scrollButtons: "auto",
115
+ value: current,
116
+ onChange: (_, newValue) => _onChange2(newValue)
117
+ }, rest), {}, {
118
+ variant: "scrollable",
119
+ sx: _objectSpread({
120
+ minHeight: 'auto',
121
+ '.MuiTabs-scrollButtons.Mui-disabled': {
122
+ opacity: 0.3,
123
+ cursor: 'not-allowed',
124
+ pointerEvents: 'auto'
125
+ },
126
+ '.MuiTabs-scroller': {
127
+ '&::after': {
128
+ content: '""',
129
+ display: 'block',
130
+ width: '100%',
131
+ height: '1px',
132
+ backgroundColor: _Colors.temp.strokeBorderStrong,
133
+ bottom: 0
134
+ }
135
+ },
136
+ '.MuiTabs-flexContainer': {
137
+ display: 'inline-flex',
138
+ columnGap: 2.5,
139
+ px: 0,
140
+ pb: 0.5
141
+ },
142
+ '.MuiTab-root': {
143
+ border: '1px solid transparent',
144
+ minHeight: 'auto',
145
+ lineHeight: 1,
146
+ py: 1,
147
+ px: 0,
148
+ color: _Colors.temp.foregroundsFgSubtile,
149
+ fontSize: '14px',
150
+ fontWeight: 500,
151
+ textTransform: 'capitalize',
152
+ minWidth: 'auto',
153
+ '&.Mui-selected, &:hover': {
154
+ color: _Colors.temp.foregroundsFgBase
155
+ }
156
+ },
157
+ '.MuiTabs-indicator': {
158
+ height: '1px',
159
+ backgroundColor: _Colors.temp.foregroundsFgBase
160
+ }
161
+ }, rest.sx),
162
+ children: tabs.map(x => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tab, {
163
+ className: classes.tab,
164
+ value: x.value,
165
+ label: x.label,
166
+ icon: x.icon || null
167
+ }, x.value))
168
+ }));
169
+ }
170
+ LineTabs.propTypes = {
171
+ tabs: _propTypes.default.array.isRequired,
172
+ current: _propTypes.default.string.isRequired,
173
+ onChange: _propTypes.default.func.isRequired
174
+ };
105
175
 
106
176
  /**
107
177
  * @typedef {import('@mui/material').TabsProps & {
108
178
  * tabs: string[];
109
179
  * onChange: (value) => {};
110
- * variant: 'card' | 'fullWidth' | 'scrollable' | 'standard'
180
+ * variant: 'line' | 'card' | 'fullWidth' | 'scrollable' | 'standard'
111
181
  * }} TabsProps
112
182
  */
113
183
 
@@ -117,25 +187,32 @@ CardTabs.propTypes = {
117
187
  * @return {import('react').ReactNode}
118
188
  */
119
189
 
120
- function Tabs(_ref3) {
190
+ function Tabs(_ref4) {
121
191
  let {
122
192
  tabs,
123
193
  current,
124
- onChange: _onChange2
125
- } = _ref3,
126
- rest = _objectWithoutProperties(_ref3, _excluded2);
194
+ onChange: _onChange3
195
+ } = _ref4,
196
+ rest = _objectWithoutProperties(_ref4, _excluded3);
127
197
  if (rest.variant === 'card') {
128
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(CardTabs, {
198
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(CardTabs, _objectSpread(_objectSpread({}, rest), {}, {
129
199
  tabs: tabs,
130
200
  current: current,
131
- onChange: _onChange2
132
- });
201
+ onChange: _onChange3
202
+ }));
203
+ }
204
+ if (rest.variant === 'line') {
205
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(LineTabs, _objectSpread(_objectSpread({}, rest), {}, {
206
+ tabs: tabs,
207
+ current: current,
208
+ onChange: _onChange3
209
+ }));
133
210
  }
134
211
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledMuiTabs, _objectSpread(_objectSpread({
135
212
  scrollButtons: "auto",
136
213
  variant: "scrollable",
137
214
  value: current,
138
- onChange: (_, newValue) => _onChange2(newValue),
215
+ onChange: (_, newValue) => _onChange3(newValue),
139
216
  indicatorColor: "primary"
140
217
  }, rest), {}, {
141
218
  className: [classes.tabs, rest.className || ''].join(' '),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.9.22",
3
+ "version": "2.9.24",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -279,6 +279,10 @@
279
279
  "import": "./es/SplitButton/index.js",
280
280
  "require": "./lib/SplitButton/index.js"
281
281
  },
282
+ "./lib/Success": {
283
+ "import": "./es/Success/index.js",
284
+ "require": "./lib/Success/index.js"
285
+ },
282
286
  "./lib/Switch": {
283
287
  "import": "./es/Switch/index.js",
284
288
  "require": "./lib/Switch/index.js"
@@ -348,12 +352,12 @@
348
352
  "peerDependencies": {
349
353
  "react": ">=18.1.0"
350
354
  },
351
- "gitHead": "c0d8c18928702f304f394df6f14a103136cb6efa",
355
+ "gitHead": "94aad922389471c9ed9f66528b8a712cfd02edbc",
352
356
  "dependencies": {
353
357
  "@arcblock/did-motif": "^1.1.13",
354
- "@arcblock/icons": "^2.9.22",
355
- "@arcblock/nft-display": "^2.9.22",
356
- "@arcblock/react-hooks": "^2.9.22",
358
+ "@arcblock/icons": "^2.9.24",
359
+ "@arcblock/nft-display": "^2.9.24",
360
+ "@arcblock/react-hooks": "^2.9.24",
357
361
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
358
362
  "@emotion/react": "^11.10.4",
359
363
  "@emotion/styled": "^11.10.4",
@@ -29,6 +29,7 @@ const colors = {
29
29
  // border
30
30
  strokeBorderBase: 'rgba(229, 231, 235, 1)',
31
31
  strokeBorderStrong: 'rgba(209, 213, 219, 1)',
32
+ strokeSep: 'rgba(229, 231, 235, 1)',
32
33
  lineStep: 'rgba(18, 22, 24, 0.06)',
33
34
  lineBorderStrong: 'rgba(18, 22, 24, 0.12)',
34
35
  lineBorderBase: 'rgba(18, 22, 24, 0.06)',
@@ -1,8 +1,9 @@
1
1
  import PropTypes from 'prop-types';
2
+ import { Box } from '@mui/material';
2
3
  import EmptyIcon from '@arcblock/icons/lib/EmptyIcon';
3
4
  import { styled } from '../Theme';
4
5
 
5
- const Wrapper = styled('div')`
6
+ const Wrapper = styled(Box)`
6
7
  display: flex;
7
8
  justify-content: center;
8
9
  align-items: center;
@@ -33,7 +34,7 @@ function Empty({ color, size, children, ...rest }) {
33
34
  return (
34
35
  <Wrapper {...rest}>
35
36
  <EmptyIcon style={{ width: size, height: size, color }} className="empty-icon" />
36
- <div className="empty-content">{children}</div>
37
+ <Box className="empty-content">{children}</Box>
37
38
  </Wrapper>
38
39
  );
39
40
  }
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
2
2
  import relativeTime from 'dayjs/plugin/relativeTime';
3
3
  import dayjs from 'dayjs';
4
4
  import 'dayjs/locale/zh-cn';
5
- import Tooltip from '@mui/material/Tooltip';
5
+ import { Tooltip } from '@mui/material';
6
6
  import localizedFormat from 'dayjs/plugin/localizedFormat';
7
7
  import utc from 'dayjs/plugin/utc';
8
8
  import timezone from 'dayjs/plugin/timezone';
@@ -34,7 +34,7 @@ dayjs.updateLocale('zh-cn', {
34
34
  });
35
35
  setDateTool(dayjs);
36
36
 
37
- export default function RelativeTime({ value, locale, withoutSuffix, from, to, type, tz, ...rest }) {
37
+ export default function RelativeTime({ value, locale, withoutSuffix, from, to, type, tz, relativeRange, ...rest }) {
38
38
  if (!value) {
39
39
  return '-';
40
40
  }
@@ -46,17 +46,24 @@ export default function RelativeTime({ value, locale, withoutSuffix, from, to, t
46
46
  datetime.tz(tz);
47
47
  }
48
48
 
49
+ const absoluteString = formatToDatetime(value, { locale: localeOption, tz });
50
+
49
51
  let relativeString;
50
52
 
51
53
  if (from) {
52
54
  relativeString = datetime.from(from, withoutSuffix);
53
55
  } else if (to) {
54
56
  relativeString = datetime.to(to, withoutSuffix);
55
- } else {
56
- relativeString = datetime.fromNow(withoutSuffix);
57
+ } else if (relativeRange) {
58
+ const diffTime = datetime.diff(dayjs());
59
+ if (Math.abs(diffTime) > relativeRange) {
60
+ relativeString = absoluteString;
61
+ }
57
62
  }
58
63
 
59
- const absoluteString = formatToDatetime(value, { locale: localeOption, tz });
64
+ if (!relativeString) {
65
+ relativeString = datetime.fromNow(withoutSuffix);
66
+ }
60
67
 
61
68
  let innerContent = relativeString;
62
69
  let popContent = absoluteString;
@@ -81,6 +88,7 @@ RelativeTime.propTypes = {
81
88
  to: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
82
89
  type: PropTypes.oneOf(['relative', 'absolute']),
83
90
  tz: PropTypes.string,
91
+ relativeRange: PropTypes.number,
84
92
  };
85
93
 
86
94
  RelativeTime.defaultProps = {
@@ -90,4 +98,5 @@ RelativeTime.defaultProps = {
90
98
  to: '',
91
99
  type: 'relative',
92
100
  tz: undefined,
101
+ relativeRange: undefined,
93
102
  };
@@ -0,0 +1,176 @@
1
+ import PropTypes from 'prop-types';
2
+ import { Box } from '@mui/material';
3
+
4
+ // FIXME: @zhanghan 目前无法适配各种 size,后续优化
5
+ export default function Success({ size, backgroundColor, borderWidth }) {
6
+ const contentSize = size - borderWidth * 2;
7
+
8
+ return (
9
+ <Box
10
+ className="check-icon"
11
+ sx={{
12
+ width: contentSize,
13
+ height: contentSize,
14
+ position: 'relative',
15
+ borderRadius: '100%',
16
+ '&, *, *::before, *::after': {
17
+ boxSizing: 'content-box !important',
18
+ },
19
+ border: (theme) => `${borderWidth}px solid ${theme.palette.success.main}`,
20
+ '&::before, &::after': {
21
+ content: '""',
22
+ height: '125%',
23
+ position: 'absolute',
24
+ background: backgroundColor,
25
+ transform: 'rotate(-45deg)',
26
+ },
27
+ '&::before': {
28
+ top: `${borderWidth / 2 + 1}px`,
29
+ left: `-${borderWidth / 2}px`,
30
+ width: `calc(32.5% + ${borderWidth}px)`,
31
+ transformOrigin: '100% 50%',
32
+ borderRadius: '100% 0 0 100%',
33
+ },
34
+ '&::after': {
35
+ top: 0,
36
+ left: '37.5%',
37
+ width: `calc(70% + ${borderWidth}px)`,
38
+ transformOrigin: '0 50%',
39
+ borderRadius: '0 100% 100% 0',
40
+ animation: 'rotate-circle 4.25s ease-in',
41
+ },
42
+ '.icon-line': {
43
+ height: `${borderWidth + 1}px`,
44
+ backgroundColor: (theme) => theme.palette.success.main,
45
+ display: 'block',
46
+ borderRadius: '100vw',
47
+ position: 'absolute',
48
+ zIndex: 10,
49
+ },
50
+ '@keyframes rotate-circle': {
51
+ '0%': {
52
+ transform: 'rotate(-45deg)',
53
+ },
54
+ '5%': {
55
+ transform: 'rotate(-45deg)',
56
+ },
57
+ '12%': {
58
+ transform: 'rotate(-405deg)',
59
+ },
60
+ '100%': {
61
+ transform: 'rotate(-405deg)',
62
+ },
63
+ },
64
+ }}>
65
+ <Box
66
+ component="span"
67
+ className="icon-line line-tip"
68
+ sx={{
69
+ top: '57.5%',
70
+ left: '17.5%',
71
+ width: '31.25%',
72
+ transform: 'rotate(45deg)',
73
+ animation: 'icon-line-tip 0.75s',
74
+ '@keyframes icon-line-tip': {
75
+ '0%': {
76
+ width: '0',
77
+ left: '1px',
78
+ top: '23.75%',
79
+ },
80
+ '54%': {
81
+ width: '0',
82
+ left: '1px',
83
+ top: '23.75%',
84
+ },
85
+ '70%': {
86
+ width: '62.5%',
87
+ left: '-10%',
88
+ top: '46.25%',
89
+ },
90
+ '84%': {
91
+ width: '21.25%',
92
+ left: '26.25%',
93
+ top: '60%',
94
+ },
95
+ '100%': {
96
+ width: '31.25',
97
+ left: '17.5%',
98
+ top: '56.25%',
99
+ },
100
+ },
101
+ }}
102
+ />
103
+ <Box
104
+ component="span"
105
+ className="icon-line line-long"
106
+ sx={{
107
+ top: '47.5%',
108
+ right: '10%',
109
+ width: '58.75%',
110
+ transform: 'rotate(-45deg)',
111
+ animation: 'icon-line-long 0.75s',
112
+ '@keyframes icon-line-long': {
113
+ '0%': {
114
+ width: '0',
115
+ right: '57.5%',
116
+ top: '67.5%',
117
+ },
118
+ '65%': {
119
+ width: '0',
120
+ right: '57.5%',
121
+ top: '67.5%',
122
+ },
123
+ '84%': {
124
+ width: '68.75%',
125
+ right: '0px',
126
+ top: '43.75%',
127
+ },
128
+ '100%': {
129
+ width: '58.75%',
130
+ right: '10%',
131
+ top: '47.5%',
132
+ },
133
+ },
134
+ }}
135
+ />
136
+ <Box
137
+ className="icon-circle"
138
+ sx={{
139
+ top: `-${borderWidth}px`,
140
+ left: `-${borderWidth}px`,
141
+ zIndex: 10,
142
+ width: contentSize,
143
+ height: contentSize,
144
+ borderRadius: '100%',
145
+ position: 'absolute',
146
+ boxSizing: 'contentBox',
147
+ border: `${borderWidth}px solid rgba(76, 175, 80, 0.5)`,
148
+ }}
149
+ />
150
+ <Box
151
+ className="icon-fix"
152
+ sx={{
153
+ top: `calc(8% - ${Math.sqrt(borderWidth)}px)`,
154
+ width: borderWidth + 1,
155
+ left: `calc(32% - ${Math.sqrt(borderWidth)}px)`,
156
+ zIndex: 1,
157
+ height: contentSize + borderWidth * 2,
158
+ position: 'absolute',
159
+ transform: 'rotate(-45deg)',
160
+ backgroundColor,
161
+ }}
162
+ />
163
+ </Box>
164
+ );
165
+ }
166
+
167
+ Success.propTypes = {
168
+ size: PropTypes.number,
169
+ borderWidth: PropTypes.number,
170
+ backgroundColor: PropTypes.string,
171
+ };
172
+ Success.defaultProps = {
173
+ size: 64,
174
+ borderWidth: 4,
175
+ backgroundColor: 'white',
176
+ };
@@ -82,11 +82,76 @@ CardTabs.propTypes = {
82
82
  onChange: PropTypes.func.isRequired,
83
83
  };
84
84
 
85
+ function LineTabs({ tabs, current, onChange, ...rest }) {
86
+ return (
87
+ <MuiTabs
88
+ scrollButtons="auto"
89
+ value={current}
90
+ onChange={(_, newValue) => onChange(newValue)}
91
+ {...rest}
92
+ variant="scrollable"
93
+ sx={{
94
+ minHeight: 'auto',
95
+ '.MuiTabs-scrollButtons.Mui-disabled': {
96
+ opacity: 0.3,
97
+ cursor: 'not-allowed',
98
+ pointerEvents: 'auto',
99
+ },
100
+ '.MuiTabs-scroller': {
101
+ '&::after': {
102
+ content: '""',
103
+ display: 'block',
104
+ width: '100%',
105
+ height: '1px',
106
+ backgroundColor: colors.strokeBorderStrong,
107
+ bottom: 0,
108
+ },
109
+ },
110
+ '.MuiTabs-flexContainer': {
111
+ display: 'inline-flex',
112
+ columnGap: 2.5,
113
+ px: 0,
114
+ pb: 0.5,
115
+ },
116
+ '.MuiTab-root': {
117
+ border: '1px solid transparent',
118
+ minHeight: 'auto',
119
+ lineHeight: 1,
120
+ py: 1,
121
+ px: 0,
122
+ color: colors.foregroundsFgSubtile,
123
+ fontSize: '14px',
124
+ fontWeight: 500,
125
+ textTransform: 'capitalize',
126
+ minWidth: 'auto',
127
+ '&.Mui-selected, &:hover': {
128
+ color: colors.foregroundsFgBase,
129
+ },
130
+ },
131
+ '.MuiTabs-indicator': {
132
+ height: '1px',
133
+ backgroundColor: colors.foregroundsFgBase,
134
+ },
135
+ ...rest.sx,
136
+ }}>
137
+ {tabs.map((x) => (
138
+ <MuiTab className={classes.tab} key={x.value} value={x.value} label={x.label} icon={x.icon || null} />
139
+ ))}
140
+ </MuiTabs>
141
+ );
142
+ }
143
+
144
+ LineTabs.propTypes = {
145
+ tabs: PropTypes.array.isRequired,
146
+ current: PropTypes.string.isRequired,
147
+ onChange: PropTypes.func.isRequired,
148
+ };
149
+
85
150
  /**
86
151
  * @typedef {import('@mui/material').TabsProps & {
87
152
  * tabs: string[];
88
153
  * onChange: (value) => {};
89
- * variant: 'card' | 'fullWidth' | 'scrollable' | 'standard'
154
+ * variant: 'line' | 'card' | 'fullWidth' | 'scrollable' | 'standard'
90
155
  * }} TabsProps
91
156
  */
92
157
 
@@ -98,7 +163,11 @@ CardTabs.propTypes = {
98
163
 
99
164
  export default function Tabs({ tabs, current, onChange, ...rest }) {
100
165
  if (rest.variant === 'card') {
101
- return <CardTabs tabs={tabs} current={current} onChange={onChange} />;
166
+ return <CardTabs {...rest} tabs={tabs} current={current} onChange={onChange} />;
167
+ }
168
+
169
+ if (rest.variant === 'line') {
170
+ return <LineTabs {...rest} tabs={tabs} current={current} onChange={onChange} />;
102
171
  }
103
172
 
104
173
  return (