funda-ui 4.7.101 → 4.7.103
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/Stepper/index.css +108 -32
- package/Stepper/index.js +48 -1
- package/lib/cjs/Stepper/index.js +48 -1
- package/lib/css/Stepper/index.css +108 -32
- package/lib/esm/Stepper/index.scss +134 -34
- package/lib/esm/Stepper/index.tsx +49 -1
- package/package.json +1 -1
package/Stepper/index.css
CHANGED
|
@@ -5,19 +5,23 @@
|
|
|
5
5
|
--stepper-color-default: #333;
|
|
6
6
|
--stepper-color-active: white;
|
|
7
7
|
--stepper-color-complete: #2563eb;
|
|
8
|
-
--stepper-
|
|
9
|
-
--stepper-
|
|
10
|
-
--stepper-
|
|
8
|
+
--stepper-indicator-default: white;
|
|
9
|
+
--stepper-indicator-active: #2563eb;
|
|
10
|
+
--stepper-indicator-complete: #22c55e;
|
|
11
11
|
--stepper-border-default: #ccc;
|
|
12
12
|
--stepper-border-active: #2563eb;
|
|
13
13
|
--stepper-border-complete: #22c55e;
|
|
14
|
+
--stepper-line-default: #dfdfdf;
|
|
15
|
+
--stepper-line-active: #2563eb;
|
|
16
|
+
--stepper-line-complete: #22c55e;
|
|
14
17
|
--stepper-indicator-size: 0.875rem;
|
|
18
|
+
--stepper-indicator-offset: 100px;
|
|
15
19
|
--stepper-title-size: 0.875rem;
|
|
16
20
|
position: relative;
|
|
17
|
-
/*
|
|
18
|
-
/* Main Navigation */
|
|
19
|
-
/*
|
|
20
|
-
/*
|
|
21
|
+
/* Navigation Header (only horizontal) */
|
|
22
|
+
/* Main Navigation - Each step item (with circle + title) */
|
|
23
|
+
/* Line */
|
|
24
|
+
/* Indicator */
|
|
21
25
|
/* Title */
|
|
22
26
|
/* Panels Area */
|
|
23
27
|
/* Buttons */
|
|
@@ -28,15 +32,43 @@
|
|
|
28
32
|
align-items: center;
|
|
29
33
|
margin-bottom: 1.5rem;
|
|
30
34
|
flex-wrap: nowrap;
|
|
35
|
+
position: relative;
|
|
36
|
+
/* background line */
|
|
37
|
+
}
|
|
38
|
+
.stepper-container .stepper-header::before {
|
|
39
|
+
content: "";
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: calc(50% - 0.875rem); /* Subtract the height of the title */
|
|
42
|
+
left: 14px;
|
|
43
|
+
right: 0;
|
|
44
|
+
height: 2px;
|
|
45
|
+
background-color: var(--stepper-line-default);
|
|
46
|
+
z-index: 1;
|
|
47
|
+
width: calc(100% - var(--stepper-indicator-offset) / 2);
|
|
48
|
+
}
|
|
49
|
+
.stepper-container .stepper-header::after {
|
|
50
|
+
content: "";
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: calc(50% - 0.875rem); /* Subtract the height of the title */
|
|
53
|
+
left: 14px;
|
|
54
|
+
height: 2px;
|
|
55
|
+
background-color: var(--stepper-line-complete);
|
|
56
|
+
z-index: 2;
|
|
57
|
+
transition: width 0.3s ease-in-out;
|
|
58
|
+
width: 0;
|
|
59
|
+
}
|
|
60
|
+
.stepper-container .stepper-header::after {
|
|
61
|
+
width: var(--stepper-progress-width, 0%);
|
|
62
|
+
max-width: calc(100% - var(--stepper-indicator-offset) / 2);
|
|
31
63
|
}
|
|
32
64
|
.stepper-container .step-item {
|
|
33
65
|
flex: none;
|
|
34
66
|
display: flex;
|
|
35
67
|
flex-direction: column;
|
|
36
68
|
align-items: center;
|
|
37
|
-
max-width:
|
|
69
|
+
max-width: var(--stepper-indicator-offset);
|
|
38
70
|
position: relative;
|
|
39
|
-
z-index:
|
|
71
|
+
z-index: 3;
|
|
40
72
|
}
|
|
41
73
|
.stepper-container .step-item.step-item--clickable {
|
|
42
74
|
cursor: pointer;
|
|
@@ -44,17 +76,34 @@
|
|
|
44
76
|
.stepper-container .step-line {
|
|
45
77
|
flex: 1;
|
|
46
78
|
height: 2px;
|
|
47
|
-
background-color:
|
|
79
|
+
background-color: var(--stepper-line-default);
|
|
48
80
|
margin: 0 4px;
|
|
49
81
|
position: relative;
|
|
50
82
|
top: -10px;
|
|
51
83
|
z-index: 0;
|
|
84
|
+
overflow: hidden;
|
|
85
|
+
opacity: 0;
|
|
86
|
+
}
|
|
87
|
+
.stepper-container .step-line--active {
|
|
88
|
+
background-color: var(--stepper-line-default);
|
|
52
89
|
}
|
|
53
90
|
.stepper-container .step-line--complete {
|
|
54
|
-
background-color: var(--stepper-
|
|
91
|
+
background-color: var(--stepper-line-default);
|
|
55
92
|
}
|
|
56
|
-
.stepper-container .step-line
|
|
57
|
-
|
|
93
|
+
.stepper-container .step-line::after {
|
|
94
|
+
content: "";
|
|
95
|
+
position: absolute;
|
|
96
|
+
top: 0;
|
|
97
|
+
left: 0;
|
|
98
|
+
width: 100%;
|
|
99
|
+
height: 100%;
|
|
100
|
+
background-color: var(--stepper-line-complete);
|
|
101
|
+
transform: scaleX(0);
|
|
102
|
+
transform-origin: left;
|
|
103
|
+
transition: transform 0.3s ease-in-out;
|
|
104
|
+
}
|
|
105
|
+
.stepper-container .step-line--active::after, .stepper-container .step-line--complete::after {
|
|
106
|
+
transform: scaleX(1);
|
|
58
107
|
}
|
|
59
108
|
.stepper-container .step-indicator {
|
|
60
109
|
width: 32px;
|
|
@@ -67,17 +116,17 @@
|
|
|
67
116
|
border: 2px solid #ccc;
|
|
68
117
|
font-size: var(--stepper-indicator-size);
|
|
69
118
|
/* default */
|
|
70
|
-
background-color: var(--stepper-
|
|
119
|
+
background-color: var(--stepper-indicator-default);
|
|
71
120
|
color: var(--stepper-color-default);
|
|
72
121
|
border-color: var(--stepper-border-default);
|
|
73
122
|
}
|
|
74
123
|
.stepper-container .step-indicator--active {
|
|
75
|
-
background-color: var(--stepper-
|
|
124
|
+
background-color: var(--stepper-indicator-active);
|
|
76
125
|
color: var(--stepper-color-active);
|
|
77
126
|
border-color: var(--stepper-border-active);
|
|
78
127
|
}
|
|
79
128
|
.stepper-container .step-indicator--complete {
|
|
80
|
-
background-color: var(--stepper-
|
|
129
|
+
background-color: var(--stepper-indicator-complete);
|
|
81
130
|
color: var(--stepper-color-active);
|
|
82
131
|
border-color: var(--stepper-border-complete);
|
|
83
132
|
}
|
|
@@ -109,19 +158,51 @@
|
|
|
109
158
|
|
|
110
159
|
/*------ Verticle ------*/
|
|
111
160
|
.stepper-container.stepper-container--vertical {
|
|
161
|
+
--stepper-indicator-offset: 50px;
|
|
112
162
|
display: flex;
|
|
113
163
|
flex-direction: column;
|
|
114
|
-
gap: 1rem;
|
|
164
|
+
gap: 1rem; /* line length */
|
|
165
|
+
/* background line */
|
|
166
|
+
/* Layout */
|
|
167
|
+
/* Title */
|
|
168
|
+
/* Panel */
|
|
169
|
+
/* Line */
|
|
170
|
+
}
|
|
171
|
+
.stepper-container.stepper-container--vertical::before {
|
|
172
|
+
content: "";
|
|
173
|
+
position: absolute;
|
|
174
|
+
top: 20px;
|
|
175
|
+
left: 24px;
|
|
176
|
+
width: 2px;
|
|
177
|
+
height: calc(100% - var(--stepper-indicator-offset));
|
|
178
|
+
background-color: var(--stepper-line-default);
|
|
179
|
+
z-index: 1;
|
|
180
|
+
}
|
|
181
|
+
.stepper-container.stepper-container--vertical::after {
|
|
182
|
+
content: "";
|
|
183
|
+
position: absolute;
|
|
184
|
+
top: 20px;
|
|
185
|
+
left: 24px;
|
|
186
|
+
width: 2px;
|
|
187
|
+
background-color: var(--stepper-line-complete);
|
|
188
|
+
z-index: 2;
|
|
189
|
+
transition: height 0.3s ease-in-out;
|
|
190
|
+
height: 0;
|
|
191
|
+
}
|
|
192
|
+
.stepper-container.stepper-container--vertical::after {
|
|
193
|
+
height: var(--stepper-progress-height, 0%);
|
|
194
|
+
max-height: calc(100% - var(--stepper-indicator-offset));
|
|
115
195
|
}
|
|
116
196
|
.stepper-container.stepper-container--vertical .vertical-step-row {
|
|
117
197
|
display: flex;
|
|
118
198
|
align-items: flex-start;
|
|
119
|
-
margin-bottom: 1rem;
|
|
120
199
|
}
|
|
121
200
|
.stepper-container.stepper-container--vertical .vertical-step-left {
|
|
122
201
|
flex-shrink: 0;
|
|
123
|
-
width:
|
|
202
|
+
width: var(--stepper-indicator-offset);
|
|
124
203
|
position: relative;
|
|
204
|
+
/* Main Navigation - Each step item (with circle + title) */
|
|
205
|
+
/* Line */
|
|
125
206
|
}
|
|
126
207
|
.stepper-container.stepper-container--vertical .vertical-step-left .step-item {
|
|
127
208
|
margin-top: 20px;
|
|
@@ -129,6 +210,7 @@
|
|
|
129
210
|
.stepper-container.stepper-container--vertical .vertical-step-left .step-line {
|
|
130
211
|
position: absolute;
|
|
131
212
|
left: 20px;
|
|
213
|
+
opacity: 0;
|
|
132
214
|
}
|
|
133
215
|
.stepper-container.stepper-container--vertical .vertical-step-right {
|
|
134
216
|
flex: 1;
|
|
@@ -144,19 +226,6 @@
|
|
|
144
226
|
.stepper-container.stepper-container--vertical .stepper-panel-header {
|
|
145
227
|
display: block;
|
|
146
228
|
}
|
|
147
|
-
.stepper-container.stepper-container--vertical .stepper-header {
|
|
148
|
-
display: flex;
|
|
149
|
-
flex-direction: column;
|
|
150
|
-
position: relative;
|
|
151
|
-
padding-left: 2rem;
|
|
152
|
-
}
|
|
153
|
-
.stepper-container.stepper-container--vertical .stepper-header .step-item {
|
|
154
|
-
flex-direction: row;
|
|
155
|
-
max-width: 150px;
|
|
156
|
-
}
|
|
157
|
-
.stepper-container.stepper-container--vertical .stepper-header .step-item:not(:first-child) {
|
|
158
|
-
margin-top: 8px;
|
|
159
|
-
}
|
|
160
229
|
.stepper-container.stepper-container--vertical .step-line {
|
|
161
230
|
flex: auto;
|
|
162
231
|
width: 2px;
|
|
@@ -165,3 +234,10 @@
|
|
|
165
234
|
top: auto;
|
|
166
235
|
left: -24px;
|
|
167
236
|
}
|
|
237
|
+
.stepper-container.stepper-container--vertical .step-line::after {
|
|
238
|
+
transform-origin: top;
|
|
239
|
+
transform: scaleY(0);
|
|
240
|
+
}
|
|
241
|
+
.stepper-container.stepper-container--vertical .step-line--active::after, .stepper-container.stepper-container--vertical .step-line--complete::after {
|
|
242
|
+
transform: scaleY(1);
|
|
243
|
+
}
|
package/Stepper/index.js
CHANGED
|
@@ -326,6 +326,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
326
326
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
327
327
|
/* harmony import */ var funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(188);
|
|
328
328
|
/* harmony import */ var funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_1__);
|
|
329
|
+
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
330
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
331
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
332
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
333
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
|
334
|
+
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
329
335
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
330
336
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
331
337
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
@@ -373,6 +379,7 @@ var Stepper = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(fun
|
|
|
373
379
|
disableCompleteIcon = _props$disableComplet === void 0 ? true : _props$disableComplet,
|
|
374
380
|
onChange = props.onChange,
|
|
375
381
|
children = props.children;
|
|
382
|
+
var rootRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
376
383
|
var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false),
|
|
377
384
|
_useState2 = _slicedToArray(_useState, 2),
|
|
378
385
|
isLastStepComplete = _useState2[0],
|
|
@@ -485,6 +492,34 @@ var Stepper = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(fun
|
|
|
485
492
|
}, panels[activeIndex]));
|
|
486
493
|
}));
|
|
487
494
|
};
|
|
495
|
+
|
|
496
|
+
// Calculate the width/height of the progress line
|
|
497
|
+
var calculateProgressStyle = function calculateProgressStyle() {
|
|
498
|
+
if (!panels.length || rootRef.current === null) return {};
|
|
499
|
+
var stepItems = rootRef.current.querySelectorAll('.step-item');
|
|
500
|
+
if (!stepItems.length) return {};
|
|
501
|
+
if (isVertical) {
|
|
502
|
+
var totalHeight = stepItems[0].clientHeight * (panels.length - 1);
|
|
503
|
+
var progress = activeIndex / (panels.length - 1) * 100;
|
|
504
|
+
return {
|
|
505
|
+
'--stepper-progress-height': "".concat(progress, "%")
|
|
506
|
+
};
|
|
507
|
+
} else {
|
|
508
|
+
var firstItem = stepItems[0];
|
|
509
|
+
var lastItem = stepItems[stepItems.length - 1];
|
|
510
|
+
if (!firstItem || !lastItem) return {};
|
|
511
|
+
var firstCenter = firstItem.offsetLeft + firstItem.clientWidth / 2;
|
|
512
|
+
var lastCenter = lastItem.offsetLeft + lastItem.clientWidth / 2;
|
|
513
|
+
var totalWidth = lastCenter - firstCenter;
|
|
514
|
+
var currentItem = stepItems[activeIndex];
|
|
515
|
+
if (!currentItem) return {};
|
|
516
|
+
var currentCenter = currentItem.offsetLeft + currentItem.clientWidth / 2;
|
|
517
|
+
var _progress = (currentCenter - firstCenter) / totalWidth * 100;
|
|
518
|
+
return {
|
|
519
|
+
'--stepper-progress-width': "".concat(_progress, "%")
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
};
|
|
488
523
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
|
|
489
524
|
// Only trigger onChange if values actually changed from previous values
|
|
490
525
|
if (prevActiveIndexRef.current !== activeIndex || prevIsLastStepCompleteRef.current !== isLastStepComplete) {
|
|
@@ -493,11 +528,23 @@ var Stepper = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(fun
|
|
|
493
528
|
onChange === null || onChange === void 0 ? void 0 : onChange(activeIndex, isLastStepComplete);
|
|
494
529
|
}
|
|
495
530
|
}, [activeIndex, isLastStepComplete]);
|
|
531
|
+
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
|
|
532
|
+
// Force a recalculation of the progress line
|
|
533
|
+
var timer = setTimeout(function () {
|
|
534
|
+
setActiveIndex(function (prev) {
|
|
535
|
+
return prev;
|
|
536
|
+
});
|
|
537
|
+
}, 0);
|
|
538
|
+
return function () {
|
|
539
|
+
return clearTimeout(timer);
|
|
540
|
+
};
|
|
541
|
+
}, []);
|
|
496
542
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
|
543
|
+
ref: rootRef,
|
|
497
544
|
className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_1__.combinedCls)('stepper-container', (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_1__.clsWrite)(wrapperClassName, ''), {
|
|
498
545
|
'stepper-container--vertical': isVertical
|
|
499
546
|
}),
|
|
500
|
-
style: style
|
|
547
|
+
style: _objectSpread(_objectSpread({}, style), calculateProgressStyle())
|
|
501
548
|
}, !isVertical && horizontalPanelsGenerator(), isVertical && verticalPanelsGenerator());
|
|
502
549
|
});
|
|
503
550
|
|
package/lib/cjs/Stepper/index.js
CHANGED
|
@@ -326,6 +326,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
326
326
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
327
327
|
/* harmony import */ var funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(188);
|
|
328
328
|
/* harmony import */ var funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_1__);
|
|
329
|
+
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
330
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
331
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
332
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
333
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
|
334
|
+
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
329
335
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
330
336
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
331
337
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
@@ -373,6 +379,7 @@ var Stepper = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(fun
|
|
|
373
379
|
disableCompleteIcon = _props$disableComplet === void 0 ? true : _props$disableComplet,
|
|
374
380
|
onChange = props.onChange,
|
|
375
381
|
children = props.children;
|
|
382
|
+
var rootRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
376
383
|
var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false),
|
|
377
384
|
_useState2 = _slicedToArray(_useState, 2),
|
|
378
385
|
isLastStepComplete = _useState2[0],
|
|
@@ -485,6 +492,34 @@ var Stepper = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(fun
|
|
|
485
492
|
}, panels[activeIndex]));
|
|
486
493
|
}));
|
|
487
494
|
};
|
|
495
|
+
|
|
496
|
+
// Calculate the width/height of the progress line
|
|
497
|
+
var calculateProgressStyle = function calculateProgressStyle() {
|
|
498
|
+
if (!panels.length || rootRef.current === null) return {};
|
|
499
|
+
var stepItems = rootRef.current.querySelectorAll('.step-item');
|
|
500
|
+
if (!stepItems.length) return {};
|
|
501
|
+
if (isVertical) {
|
|
502
|
+
var totalHeight = stepItems[0].clientHeight * (panels.length - 1);
|
|
503
|
+
var progress = activeIndex / (panels.length - 1) * 100;
|
|
504
|
+
return {
|
|
505
|
+
'--stepper-progress-height': "".concat(progress, "%")
|
|
506
|
+
};
|
|
507
|
+
} else {
|
|
508
|
+
var firstItem = stepItems[0];
|
|
509
|
+
var lastItem = stepItems[stepItems.length - 1];
|
|
510
|
+
if (!firstItem || !lastItem) return {};
|
|
511
|
+
var firstCenter = firstItem.offsetLeft + firstItem.clientWidth / 2;
|
|
512
|
+
var lastCenter = lastItem.offsetLeft + lastItem.clientWidth / 2;
|
|
513
|
+
var totalWidth = lastCenter - firstCenter;
|
|
514
|
+
var currentItem = stepItems[activeIndex];
|
|
515
|
+
if (!currentItem) return {};
|
|
516
|
+
var currentCenter = currentItem.offsetLeft + currentItem.clientWidth / 2;
|
|
517
|
+
var _progress = (currentCenter - firstCenter) / totalWidth * 100;
|
|
518
|
+
return {
|
|
519
|
+
'--stepper-progress-width': "".concat(_progress, "%")
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
};
|
|
488
523
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
|
|
489
524
|
// Only trigger onChange if values actually changed from previous values
|
|
490
525
|
if (prevActiveIndexRef.current !== activeIndex || prevIsLastStepCompleteRef.current !== isLastStepComplete) {
|
|
@@ -493,11 +528,23 @@ var Stepper = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(fun
|
|
|
493
528
|
onChange === null || onChange === void 0 ? void 0 : onChange(activeIndex, isLastStepComplete);
|
|
494
529
|
}
|
|
495
530
|
}, [activeIndex, isLastStepComplete]);
|
|
531
|
+
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
|
|
532
|
+
// Force a recalculation of the progress line
|
|
533
|
+
var timer = setTimeout(function () {
|
|
534
|
+
setActiveIndex(function (prev) {
|
|
535
|
+
return prev;
|
|
536
|
+
});
|
|
537
|
+
}, 0);
|
|
538
|
+
return function () {
|
|
539
|
+
return clearTimeout(timer);
|
|
540
|
+
};
|
|
541
|
+
}, []);
|
|
496
542
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
|
543
|
+
ref: rootRef,
|
|
497
544
|
className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_1__.combinedCls)('stepper-container', (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_1__.clsWrite)(wrapperClassName, ''), {
|
|
498
545
|
'stepper-container--vertical': isVertical
|
|
499
546
|
}),
|
|
500
|
-
style: style
|
|
547
|
+
style: _objectSpread(_objectSpread({}, style), calculateProgressStyle())
|
|
501
548
|
}, !isVertical && horizontalPanelsGenerator(), isVertical && verticalPanelsGenerator());
|
|
502
549
|
});
|
|
503
550
|
|
|
@@ -5,19 +5,23 @@
|
|
|
5
5
|
--stepper-color-default: #333;
|
|
6
6
|
--stepper-color-active: white;
|
|
7
7
|
--stepper-color-complete: #2563eb;
|
|
8
|
-
--stepper-
|
|
9
|
-
--stepper-
|
|
10
|
-
--stepper-
|
|
8
|
+
--stepper-indicator-default: white;
|
|
9
|
+
--stepper-indicator-active: #2563eb;
|
|
10
|
+
--stepper-indicator-complete: #22c55e;
|
|
11
11
|
--stepper-border-default: #ccc;
|
|
12
12
|
--stepper-border-active: #2563eb;
|
|
13
13
|
--stepper-border-complete: #22c55e;
|
|
14
|
+
--stepper-line-default: #dfdfdf;
|
|
15
|
+
--stepper-line-active: #2563eb;
|
|
16
|
+
--stepper-line-complete: #22c55e;
|
|
14
17
|
--stepper-indicator-size: 0.875rem;
|
|
18
|
+
--stepper-indicator-offset: 100px;
|
|
15
19
|
--stepper-title-size: 0.875rem;
|
|
16
20
|
position: relative;
|
|
17
|
-
/*
|
|
18
|
-
/* Main Navigation */
|
|
19
|
-
/*
|
|
20
|
-
/*
|
|
21
|
+
/* Navigation Header (only horizontal) */
|
|
22
|
+
/* Main Navigation - Each step item (with circle + title) */
|
|
23
|
+
/* Line */
|
|
24
|
+
/* Indicator */
|
|
21
25
|
/* Title */
|
|
22
26
|
/* Panels Area */
|
|
23
27
|
/* Buttons */
|
|
@@ -28,15 +32,43 @@
|
|
|
28
32
|
align-items: center;
|
|
29
33
|
margin-bottom: 1.5rem;
|
|
30
34
|
flex-wrap: nowrap;
|
|
35
|
+
position: relative;
|
|
36
|
+
/* background line */
|
|
37
|
+
}
|
|
38
|
+
.stepper-container .stepper-header::before {
|
|
39
|
+
content: "";
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: calc(50% - 0.875rem); /* Subtract the height of the title */
|
|
42
|
+
left: 14px;
|
|
43
|
+
right: 0;
|
|
44
|
+
height: 2px;
|
|
45
|
+
background-color: var(--stepper-line-default);
|
|
46
|
+
z-index: 1;
|
|
47
|
+
width: calc(100% - var(--stepper-indicator-offset) / 2);
|
|
48
|
+
}
|
|
49
|
+
.stepper-container .stepper-header::after {
|
|
50
|
+
content: "";
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: calc(50% - 0.875rem); /* Subtract the height of the title */
|
|
53
|
+
left: 14px;
|
|
54
|
+
height: 2px;
|
|
55
|
+
background-color: var(--stepper-line-complete);
|
|
56
|
+
z-index: 2;
|
|
57
|
+
transition: width 0.3s ease-in-out;
|
|
58
|
+
width: 0;
|
|
59
|
+
}
|
|
60
|
+
.stepper-container .stepper-header::after {
|
|
61
|
+
width: var(--stepper-progress-width, 0%);
|
|
62
|
+
max-width: calc(100% - var(--stepper-indicator-offset) / 2);
|
|
31
63
|
}
|
|
32
64
|
.stepper-container .step-item {
|
|
33
65
|
flex: none;
|
|
34
66
|
display: flex;
|
|
35
67
|
flex-direction: column;
|
|
36
68
|
align-items: center;
|
|
37
|
-
max-width:
|
|
69
|
+
max-width: var(--stepper-indicator-offset);
|
|
38
70
|
position: relative;
|
|
39
|
-
z-index:
|
|
71
|
+
z-index: 3;
|
|
40
72
|
}
|
|
41
73
|
.stepper-container .step-item.step-item--clickable {
|
|
42
74
|
cursor: pointer;
|
|
@@ -44,17 +76,34 @@
|
|
|
44
76
|
.stepper-container .step-line {
|
|
45
77
|
flex: 1;
|
|
46
78
|
height: 2px;
|
|
47
|
-
background-color:
|
|
79
|
+
background-color: var(--stepper-line-default);
|
|
48
80
|
margin: 0 4px;
|
|
49
81
|
position: relative;
|
|
50
82
|
top: -10px;
|
|
51
83
|
z-index: 0;
|
|
84
|
+
overflow: hidden;
|
|
85
|
+
opacity: 0;
|
|
86
|
+
}
|
|
87
|
+
.stepper-container .step-line--active {
|
|
88
|
+
background-color: var(--stepper-line-default);
|
|
52
89
|
}
|
|
53
90
|
.stepper-container .step-line--complete {
|
|
54
|
-
background-color: var(--stepper-
|
|
91
|
+
background-color: var(--stepper-line-default);
|
|
55
92
|
}
|
|
56
|
-
.stepper-container .step-line
|
|
57
|
-
|
|
93
|
+
.stepper-container .step-line::after {
|
|
94
|
+
content: "";
|
|
95
|
+
position: absolute;
|
|
96
|
+
top: 0;
|
|
97
|
+
left: 0;
|
|
98
|
+
width: 100%;
|
|
99
|
+
height: 100%;
|
|
100
|
+
background-color: var(--stepper-line-complete);
|
|
101
|
+
transform: scaleX(0);
|
|
102
|
+
transform-origin: left;
|
|
103
|
+
transition: transform 0.3s ease-in-out;
|
|
104
|
+
}
|
|
105
|
+
.stepper-container .step-line--active::after, .stepper-container .step-line--complete::after {
|
|
106
|
+
transform: scaleX(1);
|
|
58
107
|
}
|
|
59
108
|
.stepper-container .step-indicator {
|
|
60
109
|
width: 32px;
|
|
@@ -67,17 +116,17 @@
|
|
|
67
116
|
border: 2px solid #ccc;
|
|
68
117
|
font-size: var(--stepper-indicator-size);
|
|
69
118
|
/* default */
|
|
70
|
-
background-color: var(--stepper-
|
|
119
|
+
background-color: var(--stepper-indicator-default);
|
|
71
120
|
color: var(--stepper-color-default);
|
|
72
121
|
border-color: var(--stepper-border-default);
|
|
73
122
|
}
|
|
74
123
|
.stepper-container .step-indicator--active {
|
|
75
|
-
background-color: var(--stepper-
|
|
124
|
+
background-color: var(--stepper-indicator-active);
|
|
76
125
|
color: var(--stepper-color-active);
|
|
77
126
|
border-color: var(--stepper-border-active);
|
|
78
127
|
}
|
|
79
128
|
.stepper-container .step-indicator--complete {
|
|
80
|
-
background-color: var(--stepper-
|
|
129
|
+
background-color: var(--stepper-indicator-complete);
|
|
81
130
|
color: var(--stepper-color-active);
|
|
82
131
|
border-color: var(--stepper-border-complete);
|
|
83
132
|
}
|
|
@@ -109,19 +158,51 @@
|
|
|
109
158
|
|
|
110
159
|
/*------ Verticle ------*/
|
|
111
160
|
.stepper-container.stepper-container--vertical {
|
|
161
|
+
--stepper-indicator-offset: 50px;
|
|
112
162
|
display: flex;
|
|
113
163
|
flex-direction: column;
|
|
114
|
-
gap: 1rem;
|
|
164
|
+
gap: 1rem; /* line length */
|
|
165
|
+
/* background line */
|
|
166
|
+
/* Layout */
|
|
167
|
+
/* Title */
|
|
168
|
+
/* Panel */
|
|
169
|
+
/* Line */
|
|
170
|
+
}
|
|
171
|
+
.stepper-container.stepper-container--vertical::before {
|
|
172
|
+
content: "";
|
|
173
|
+
position: absolute;
|
|
174
|
+
top: 20px;
|
|
175
|
+
left: 24px;
|
|
176
|
+
width: 2px;
|
|
177
|
+
height: calc(100% - var(--stepper-indicator-offset));
|
|
178
|
+
background-color: var(--stepper-line-default);
|
|
179
|
+
z-index: 1;
|
|
180
|
+
}
|
|
181
|
+
.stepper-container.stepper-container--vertical::after {
|
|
182
|
+
content: "";
|
|
183
|
+
position: absolute;
|
|
184
|
+
top: 20px;
|
|
185
|
+
left: 24px;
|
|
186
|
+
width: 2px;
|
|
187
|
+
background-color: var(--stepper-line-complete);
|
|
188
|
+
z-index: 2;
|
|
189
|
+
transition: height 0.3s ease-in-out;
|
|
190
|
+
height: 0;
|
|
191
|
+
}
|
|
192
|
+
.stepper-container.stepper-container--vertical::after {
|
|
193
|
+
height: var(--stepper-progress-height, 0%);
|
|
194
|
+
max-height: calc(100% - var(--stepper-indicator-offset));
|
|
115
195
|
}
|
|
116
196
|
.stepper-container.stepper-container--vertical .vertical-step-row {
|
|
117
197
|
display: flex;
|
|
118
198
|
align-items: flex-start;
|
|
119
|
-
margin-bottom: 1rem;
|
|
120
199
|
}
|
|
121
200
|
.stepper-container.stepper-container--vertical .vertical-step-left {
|
|
122
201
|
flex-shrink: 0;
|
|
123
|
-
width:
|
|
202
|
+
width: var(--stepper-indicator-offset);
|
|
124
203
|
position: relative;
|
|
204
|
+
/* Main Navigation - Each step item (with circle + title) */
|
|
205
|
+
/* Line */
|
|
125
206
|
}
|
|
126
207
|
.stepper-container.stepper-container--vertical .vertical-step-left .step-item {
|
|
127
208
|
margin-top: 20px;
|
|
@@ -129,6 +210,7 @@
|
|
|
129
210
|
.stepper-container.stepper-container--vertical .vertical-step-left .step-line {
|
|
130
211
|
position: absolute;
|
|
131
212
|
left: 20px;
|
|
213
|
+
opacity: 0;
|
|
132
214
|
}
|
|
133
215
|
.stepper-container.stepper-container--vertical .vertical-step-right {
|
|
134
216
|
flex: 1;
|
|
@@ -144,19 +226,6 @@
|
|
|
144
226
|
.stepper-container.stepper-container--vertical .stepper-panel-header {
|
|
145
227
|
display: block;
|
|
146
228
|
}
|
|
147
|
-
.stepper-container.stepper-container--vertical .stepper-header {
|
|
148
|
-
display: flex;
|
|
149
|
-
flex-direction: column;
|
|
150
|
-
position: relative;
|
|
151
|
-
padding-left: 2rem;
|
|
152
|
-
}
|
|
153
|
-
.stepper-container.stepper-container--vertical .stepper-header .step-item {
|
|
154
|
-
flex-direction: row;
|
|
155
|
-
max-width: 150px;
|
|
156
|
-
}
|
|
157
|
-
.stepper-container.stepper-container--vertical .stepper-header .step-item:not(:first-child) {
|
|
158
|
-
margin-top: 8px;
|
|
159
|
-
}
|
|
160
229
|
.stepper-container.stepper-container--vertical .step-line {
|
|
161
230
|
flex: auto;
|
|
162
231
|
width: 2px;
|
|
@@ -165,3 +234,10 @@
|
|
|
165
234
|
top: auto;
|
|
166
235
|
left: -24px;
|
|
167
236
|
}
|
|
237
|
+
.stepper-container.stepper-container--vertical .step-line::after {
|
|
238
|
+
transform-origin: top;
|
|
239
|
+
transform: scaleY(0);
|
|
240
|
+
}
|
|
241
|
+
.stepper-container.stepper-container--vertical .step-line--active::after, .stepper-container.stepper-container--vertical .step-line--complete::after {
|
|
242
|
+
transform: scaleY(1);
|
|
243
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
|
|
2
|
+
|
|
2
3
|
/* ======================================================
|
|
3
4
|
<!-- Stepper -->
|
|
4
5
|
/* ====================================================== */
|
|
@@ -8,36 +9,70 @@
|
|
|
8
9
|
--stepper-color-default: #333;
|
|
9
10
|
--stepper-color-active: white;
|
|
10
11
|
--stepper-color-complete: #2563eb;
|
|
11
|
-
--stepper-
|
|
12
|
-
--stepper-
|
|
13
|
-
--stepper-
|
|
12
|
+
--stepper-indicator-default: white;
|
|
13
|
+
--stepper-indicator-active: #2563eb;
|
|
14
|
+
--stepper-indicator-complete: #22c55e;
|
|
14
15
|
--stepper-border-default: #ccc;
|
|
15
16
|
--stepper-border-active: #2563eb;
|
|
16
17
|
--stepper-border-complete: #22c55e;
|
|
18
|
+
--stepper-line-default: #dfdfdf;
|
|
19
|
+
--stepper-line-active: #2563eb;
|
|
20
|
+
--stepper-line-complete: #22c55e;
|
|
17
21
|
--stepper-indicator-size: 0.875rem;
|
|
22
|
+
--stepper-indicator-offset: 100px;
|
|
18
23
|
--stepper-title-size: 0.875rem;
|
|
19
|
-
|
|
24
|
+
|
|
20
25
|
|
|
21
26
|
position: relative;
|
|
22
27
|
|
|
23
|
-
/*
|
|
28
|
+
/* Navigation Header (only horizontal) */
|
|
24
29
|
.stepper-header {
|
|
25
30
|
display: flex;
|
|
26
31
|
align-items: center;
|
|
27
32
|
margin-bottom: 1.5rem;
|
|
28
33
|
flex-wrap: nowrap;
|
|
34
|
+
position: relative;
|
|
35
|
+
|
|
36
|
+
/* background line */
|
|
37
|
+
&::before {
|
|
38
|
+
content: '';
|
|
39
|
+
position: absolute;
|
|
40
|
+
top: calc(50% - 0.875rem); /* Subtract the height of the title */
|
|
41
|
+
left: 14px;
|
|
42
|
+
right: 0;
|
|
43
|
+
height: 2px;
|
|
44
|
+
background-color: var(--stepper-line-default);
|
|
45
|
+
z-index: 1;
|
|
46
|
+
width: calc(100% - calc(var(--stepper-indicator-offset)/2));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&::after {
|
|
50
|
+
content: '';
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: calc(50% - 0.875rem); /* Subtract the height of the title */
|
|
53
|
+
left: 14px;
|
|
54
|
+
height: 2px;
|
|
55
|
+
background-color: var(--stepper-line-complete);
|
|
56
|
+
z-index: 2;
|
|
57
|
+
transition: width 0.3s ease-in-out;
|
|
58
|
+
width: 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&::after {
|
|
62
|
+
width: var(--stepper-progress-width, 0%);
|
|
63
|
+
max-width: calc(100% - calc(var(--stepper-indicator-offset)/2));
|
|
64
|
+
}
|
|
29
65
|
}
|
|
30
66
|
|
|
31
|
-
/* Main Navigation */
|
|
32
|
-
/* Each step item (with circle + title) */
|
|
67
|
+
/* Main Navigation - Each step item (with circle + title) */
|
|
33
68
|
.step-item {
|
|
34
69
|
flex: none;
|
|
35
70
|
display: flex;
|
|
36
71
|
flex-direction: column;
|
|
37
72
|
align-items: center;
|
|
38
|
-
max-width:
|
|
73
|
+
max-width: var(--stepper-indicator-offset);
|
|
39
74
|
position: relative;
|
|
40
|
-
z-index:
|
|
75
|
+
z-index: 3;
|
|
41
76
|
|
|
42
77
|
&.step-item--clickable {
|
|
43
78
|
cursor: pointer;
|
|
@@ -45,26 +80,49 @@
|
|
|
45
80
|
|
|
46
81
|
}
|
|
47
82
|
|
|
83
|
+
|
|
84
|
+
/* Line */
|
|
48
85
|
.step-line {
|
|
49
86
|
flex: 1;
|
|
50
87
|
height: 2px;
|
|
51
|
-
background-color:
|
|
88
|
+
background-color: var(--stepper-line-default);
|
|
52
89
|
margin: 0 4px;
|
|
53
90
|
position: relative;
|
|
54
91
|
top: -10px;
|
|
55
92
|
z-index: 0;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
opacity: 0;
|
|
95
|
+
|
|
96
|
+
&--active {
|
|
97
|
+
background-color: var(--stepper-line-default);
|
|
98
|
+
}
|
|
56
99
|
|
|
57
100
|
&--complete {
|
|
58
|
-
background-color: var(--stepper-
|
|
101
|
+
background-color: var(--stepper-line-default);
|
|
59
102
|
}
|
|
103
|
+
|
|
104
|
+
&::after {
|
|
105
|
+
content: '';
|
|
106
|
+
position: absolute;
|
|
107
|
+
top: 0;
|
|
108
|
+
left: 0;
|
|
109
|
+
width: 100%;
|
|
110
|
+
height: 100%;
|
|
111
|
+
background-color: var(--stepper-line-complete);
|
|
112
|
+
transform: scaleX(0);
|
|
113
|
+
transform-origin: left;
|
|
114
|
+
transition: transform 0.3s ease-in-out;
|
|
115
|
+
}
|
|
60
116
|
|
|
61
|
-
&--active
|
|
62
|
-
|
|
117
|
+
&--active::after,
|
|
118
|
+
&--complete::after {
|
|
119
|
+
transform: scaleX(1);
|
|
63
120
|
}
|
|
64
|
-
|
|
65
121
|
}
|
|
66
122
|
|
|
67
|
-
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
/* Indicator */
|
|
68
126
|
.step-indicator {
|
|
69
127
|
width: 32px;
|
|
70
128
|
height: 32px;
|
|
@@ -77,18 +135,18 @@
|
|
|
77
135
|
font-size: var(--stepper-indicator-size);
|
|
78
136
|
|
|
79
137
|
/* default */
|
|
80
|
-
background-color: var(--stepper-
|
|
138
|
+
background-color: var(--stepper-indicator-default);
|
|
81
139
|
color: var(--stepper-color-default);
|
|
82
140
|
border-color: var(--stepper-border-default);
|
|
83
141
|
|
|
84
142
|
&--active {
|
|
85
|
-
background-color: var(--stepper-
|
|
143
|
+
background-color: var(--stepper-indicator-active);
|
|
86
144
|
color: var(--stepper-color-active);
|
|
87
145
|
border-color: var(--stepper-border-active);
|
|
88
146
|
}
|
|
89
147
|
|
|
90
148
|
&--complete {
|
|
91
|
-
background-color: var(--stepper-
|
|
149
|
+
background-color: var(--stepper-indicator-complete);
|
|
92
150
|
color: var(--stepper-color-active);
|
|
93
151
|
border-color: var(--stepper-border-complete);
|
|
94
152
|
}
|
|
@@ -143,28 +201,65 @@
|
|
|
143
201
|
|
|
144
202
|
/*------ Verticle ------*/
|
|
145
203
|
.stepper-container.stepper-container--vertical {
|
|
204
|
+
|
|
205
|
+
--stepper-indicator-offset: 50px;
|
|
206
|
+
|
|
146
207
|
display: flex;
|
|
147
208
|
flex-direction: column;
|
|
148
|
-
gap: 1rem;
|
|
209
|
+
gap: 1rem; /* line length */
|
|
210
|
+
|
|
211
|
+
/* background line */
|
|
212
|
+
&::before {
|
|
213
|
+
content: '';
|
|
214
|
+
position: absolute;
|
|
215
|
+
top: 20px;
|
|
216
|
+
left: 24px;
|
|
217
|
+
width: 2px;
|
|
218
|
+
height: calc(100% - calc(var(--stepper-indicator-offset)));
|
|
219
|
+
background-color: var(--stepper-line-default);
|
|
220
|
+
z-index: 1;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
&::after {
|
|
224
|
+
content: '';
|
|
225
|
+
position: absolute;
|
|
226
|
+
top: 20px;
|
|
227
|
+
left: 24px;
|
|
228
|
+
width: 2px;
|
|
229
|
+
background-color: var(--stepper-line-complete);
|
|
230
|
+
z-index: 2;
|
|
231
|
+
transition: height 0.3s ease-in-out;
|
|
232
|
+
height: 0;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
&::after {
|
|
236
|
+
height: var(--stepper-progress-height, 0%);
|
|
237
|
+
max-height: calc(100% - calc(var(--stepper-indicator-offset)));
|
|
238
|
+
}
|
|
149
239
|
|
|
150
240
|
|
|
241
|
+
/* Layout */
|
|
151
242
|
.vertical-step-row {
|
|
152
243
|
display: flex;
|
|
153
244
|
align-items: flex-start;
|
|
154
|
-
margin-bottom: 1rem;
|
|
155
245
|
}
|
|
156
246
|
.vertical-step-left {
|
|
157
247
|
flex-shrink: 0;
|
|
158
|
-
width:
|
|
248
|
+
width: var(--stepper-indicator-offset);
|
|
159
249
|
position: relative;
|
|
160
250
|
|
|
251
|
+
/* Main Navigation - Each step item (with circle + title) */
|
|
161
252
|
.step-item {
|
|
162
253
|
margin-top: 20px;
|
|
163
254
|
}
|
|
255
|
+
|
|
256
|
+
/* Line */
|
|
164
257
|
.step-line {
|
|
165
258
|
position: absolute;
|
|
166
259
|
left: 20px;
|
|
260
|
+
opacity: 0;
|
|
167
261
|
}
|
|
262
|
+
|
|
168
263
|
}
|
|
169
264
|
|
|
170
265
|
.vertical-step-right {
|
|
@@ -175,26 +270,20 @@
|
|
|
175
270
|
top: 1.5rem;
|
|
176
271
|
}
|
|
177
272
|
|
|
273
|
+
/* Title */
|
|
178
274
|
.step-title {
|
|
179
275
|
display: none;
|
|
180
276
|
margin-left: .3rem;
|
|
181
277
|
}
|
|
278
|
+
|
|
279
|
+
/* Panel */
|
|
182
280
|
.stepper-panel-header {
|
|
183
281
|
display: block;
|
|
184
282
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
padding-left: 2rem;
|
|
190
|
-
.step-item {
|
|
191
|
-
flex-direction: row;
|
|
192
|
-
max-width: 150px;
|
|
193
|
-
&:not(:first-child) {
|
|
194
|
-
margin-top: 8px;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
/* Line */
|
|
198
287
|
.step-line {
|
|
199
288
|
flex: auto;
|
|
200
289
|
width: 2px;
|
|
@@ -202,5 +291,16 @@
|
|
|
202
291
|
margin-top: 4px;
|
|
203
292
|
top: auto;
|
|
204
293
|
left: -24px;
|
|
294
|
+
|
|
295
|
+
&::after {
|
|
296
|
+
transform-origin: top;
|
|
297
|
+
transform: scaleY(0);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
&--active::after,
|
|
301
|
+
&--complete::after {
|
|
302
|
+
transform: scaleY(1);
|
|
303
|
+
}
|
|
304
|
+
|
|
205
305
|
}
|
|
206
306
|
}
|
|
@@ -2,6 +2,7 @@ import React, { useRef, useEffect, forwardRef, useImperativeHandle, useState } f
|
|
|
2
2
|
|
|
3
3
|
import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
interface StepperPanelProps {
|
|
6
7
|
header: React.ReactNode;
|
|
7
8
|
children?: React.ReactNode;
|
|
@@ -55,6 +56,7 @@ const Stepper = forwardRef<StepperRef, StepperProps>((props, ref) => {
|
|
|
55
56
|
} = props;
|
|
56
57
|
|
|
57
58
|
|
|
59
|
+
const rootRef = useRef<HTMLDivElement>(null);
|
|
58
60
|
const [isLastStepComplete, setIsLastStepComplete] = useState<boolean>(false);
|
|
59
61
|
const [activeIndex, setActiveIndex] = useState<number>(initialStep);
|
|
60
62
|
const panels = React.Children.toArray(children) as React.ReactElement<StepperPanelProps>[];
|
|
@@ -230,6 +232,39 @@ const Stepper = forwardRef<StepperRef, StepperProps>((props, ref) => {
|
|
|
230
232
|
</>;
|
|
231
233
|
};
|
|
232
234
|
|
|
235
|
+
// Calculate the width/height of the progress line
|
|
236
|
+
const calculateProgressStyle = () => {
|
|
237
|
+
if (!panels.length || rootRef.current === null) return {};
|
|
238
|
+
|
|
239
|
+
const stepItems = rootRef.current.querySelectorAll('.step-item');
|
|
240
|
+
if (!stepItems.length) return {};
|
|
241
|
+
|
|
242
|
+
if (isVertical) {
|
|
243
|
+
const totalHeight = stepItems[0].clientHeight * (panels.length - 1);
|
|
244
|
+
const progress = (activeIndex / (panels.length - 1)) * 100;
|
|
245
|
+
return {
|
|
246
|
+
'--stepper-progress-height': `${progress}%`
|
|
247
|
+
} as React.CSSProperties;
|
|
248
|
+
} else {
|
|
249
|
+
const firstItem = stepItems[0] as HTMLDivElement;
|
|
250
|
+
const lastItem = stepItems[stepItems.length - 1] as HTMLDivElement;
|
|
251
|
+
if (!firstItem || !lastItem) return {};
|
|
252
|
+
|
|
253
|
+
const firstCenter = firstItem.offsetLeft + (firstItem.clientWidth / 2);
|
|
254
|
+
const lastCenter = lastItem.offsetLeft + (lastItem.clientWidth / 2);
|
|
255
|
+
const totalWidth = lastCenter - firstCenter;
|
|
256
|
+
|
|
257
|
+
const currentItem = stepItems[activeIndex] as HTMLDivElement;
|
|
258
|
+
if (!currentItem) return {};
|
|
259
|
+
|
|
260
|
+
const currentCenter = currentItem.offsetLeft + (currentItem.clientWidth / 2);
|
|
261
|
+
const progress = ((currentCenter - firstCenter) / totalWidth) * 100;
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
'--stepper-progress-width': `${progress}%`
|
|
265
|
+
} as React.CSSProperties;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
233
268
|
|
|
234
269
|
useEffect(() => {
|
|
235
270
|
// Only trigger onChange if values actually changed from previous values
|
|
@@ -243,8 +278,18 @@ const Stepper = forwardRef<StepperRef, StepperProps>((props, ref) => {
|
|
|
243
278
|
}
|
|
244
279
|
}, [activeIndex, isLastStepComplete]);
|
|
245
280
|
|
|
281
|
+
|
|
282
|
+
useEffect(() => {
|
|
283
|
+
// Force a recalculation of the progress line
|
|
284
|
+
const timer = setTimeout(() => {
|
|
285
|
+
setActiveIndex(prev => prev);
|
|
286
|
+
}, 0);
|
|
287
|
+
return () => clearTimeout(timer);
|
|
288
|
+
}, []);
|
|
289
|
+
|
|
246
290
|
return (
|
|
247
291
|
<div
|
|
292
|
+
ref={rootRef}
|
|
248
293
|
className={combinedCls(
|
|
249
294
|
'stepper-container',
|
|
250
295
|
clsWrite(wrapperClassName, ''),
|
|
@@ -252,7 +297,10 @@ const Stepper = forwardRef<StepperRef, StepperProps>((props, ref) => {
|
|
|
252
297
|
'stepper-container--vertical': isVertical
|
|
253
298
|
}
|
|
254
299
|
)}
|
|
255
|
-
style={
|
|
300
|
+
style={{
|
|
301
|
+
...style,
|
|
302
|
+
...calculateProgressStyle()
|
|
303
|
+
}}
|
|
256
304
|
>
|
|
257
305
|
{!isVertical && horizontalPanelsGenerator()}
|
|
258
306
|
{isVertical && verticalPanelsGenerator()}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "UIUX Lab",
|
|
3
3
|
"email": "uiuxlab@gmail.com",
|
|
4
4
|
"name": "funda-ui",
|
|
5
|
-
"version": "4.7.
|
|
5
|
+
"version": "4.7.103",
|
|
6
6
|
"description": "React components using pure Bootstrap 5+ which does not contain any external style and script libraries.",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|