funda-ui 4.7.755 → 4.7.770
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/Accordion/index.js +17 -3
- package/LiveSearch/index.js +19 -8
- package/Select/index.js +17 -6
- package/lib/cjs/Accordion/index.js +17 -3
- package/lib/cjs/LiveSearch/index.js +19 -8
- package/lib/cjs/Select/index.js +17 -6
- package/lib/esm/Accordion/AccordionItem.tsx +18 -3
- package/lib/esm/LiveSearch/index.tsx +19 -10
- package/lib/esm/Select/index.tsx +24 -8
- package/package.json +1 -1
package/Accordion/index.js
CHANGED
|
@@ -332,7 +332,7 @@ var external_root_React_commonjs2_react_commonjs_react_amd_react_default = /*#__
|
|
|
332
332
|
// EXTERNAL MODULE: ../Utils/dist/cjs/cls.js
|
|
333
333
|
var cls = __webpack_require__(188);
|
|
334
334
|
;// CONCATENATED MODULE: ./src/AccordionItem.tsx
|
|
335
|
-
var _excluded = ["heightObserver", "index", "animSpeed", "easing", "arrowOnly", "itemClassName", "itemContentWrapperClassName", "itemContentClassName", "itemTriggerClassName", "itemHeaderClassName", "itemTriggerIcon", "itemStyle", "activeItem", "title", "onToggleEv", "onTransitionEnd", "onItemCollapse", "isExpanded", "children"];
|
|
335
|
+
var _excluded = ["heightObserver", "index", "animSpeed", "easing", "arrowOnly", "itemClassName", "itemContentWrapperClassName", "itemContentClassName", "itemTriggerClassName", "itemHeaderClassName", "itemTriggerIcon", "itemStyle", "activeItem", "title", "onToggleEv", "onTransitionEnd", "onItemCollapse", "isExpanded", "forceExpanded", "children"];
|
|
336
336
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
337
337
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
338
338
|
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."); }
|
|
@@ -363,6 +363,7 @@ var AccordionItem = function AccordionItem(props) {
|
|
|
363
363
|
onTransitionEnd = props.onTransitionEnd,
|
|
364
364
|
onItemCollapse = props.onItemCollapse,
|
|
365
365
|
controlledExpanded = props.isExpanded,
|
|
366
|
+
forceExpanded = props.forceExpanded,
|
|
366
367
|
children = props.children,
|
|
367
368
|
attributes = _objectWithoutProperties(props, _excluded);
|
|
368
369
|
var _useState = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useState)(false),
|
|
@@ -371,9 +372,12 @@ var AccordionItem = function AccordionItem(props) {
|
|
|
371
372
|
setInternalExpanded = _useState2[1];
|
|
372
373
|
var isFirstRender = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(true);
|
|
373
374
|
var initialHeightSet = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(false);
|
|
375
|
+
var hasUserInteracted = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(false);
|
|
374
376
|
|
|
375
|
-
// Use controlled or uncontrolled expanded state
|
|
376
|
-
|
|
377
|
+
// Use forceExpanded if provided and user hasn't interacted, otherwise use controlled or uncontrolled expanded state
|
|
378
|
+
// forceExpanded takes priority over isExpanded from parent, but only before user interaction
|
|
379
|
+
var actualExpanded = controlledExpanded !== undefined ? controlledExpanded : internalExpanded;
|
|
380
|
+
var isExpanded = forceExpanded !== undefined && !hasUserInteracted.current ? forceExpanded : actualExpanded;
|
|
377
381
|
var observer = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(null);
|
|
378
382
|
var contentWrapperRef = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(null);
|
|
379
383
|
var contentRef = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(null);
|
|
@@ -382,6 +386,9 @@ var AccordionItem = function AccordionItem(props) {
|
|
|
382
386
|
var handleToggle = function handleToggle(e) {
|
|
383
387
|
e.preventDefault();
|
|
384
388
|
e.stopPropagation();
|
|
389
|
+
|
|
390
|
+
// Mark that user has interacted, so forceExpanded will be ignored
|
|
391
|
+
hasUserInteracted.current = true;
|
|
385
392
|
if (controlledExpanded === undefined) {
|
|
386
393
|
setInternalExpanded(function (prev) {
|
|
387
394
|
return !prev;
|
|
@@ -399,6 +406,13 @@ var AccordionItem = function AccordionItem(props) {
|
|
|
399
406
|
overflow: 'hidden'
|
|
400
407
|
};
|
|
401
408
|
};
|
|
409
|
+
|
|
410
|
+
// Reset user interaction flag when forceExpanded changes externally
|
|
411
|
+
(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function () {
|
|
412
|
+
if (forceExpanded !== undefined) {
|
|
413
|
+
hasUserInteracted.current = false;
|
|
414
|
+
}
|
|
415
|
+
}, [forceExpanded]);
|
|
402
416
|
(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function () {
|
|
403
417
|
if (triggerRef.current && typeof onItemCollapse === 'function') {
|
|
404
418
|
if (isFirstRender.current) {
|
package/LiveSearch/index.js
CHANGED
|
@@ -3853,30 +3853,41 @@ var LiveSearch = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(
|
|
|
3853
3853
|
if (listRef.current === null || !rootRef.current.classList.contains('active')) return;
|
|
3854
3854
|
var options = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide)'));
|
|
3855
3855
|
// Avoid selecting options that are disabled
|
|
3856
|
-
options = options.filter(function (
|
|
3857
|
-
return !
|
|
3856
|
+
options = options.filter(function (option) {
|
|
3857
|
+
return !option.classList.contains('disabled');
|
|
3858
3858
|
});
|
|
3859
|
+
if (!options.length) return;
|
|
3860
|
+
var activeNode = listRef.current.querySelector('.list-group-item.active');
|
|
3859
3861
|
var currentIndex = options.findIndex(function (e) {
|
|
3860
|
-
return e ===
|
|
3862
|
+
return e === activeNode;
|
|
3861
3863
|
});
|
|
3862
3864
|
|
|
3863
3865
|
// get the next element in the list, "%" will loop around to 0
|
|
3864
|
-
var nextIndex;
|
|
3866
|
+
var nextIndex = -1;
|
|
3865
3867
|
if (type === 'increase') {
|
|
3866
|
-
|
|
3868
|
+
// ArrowDown
|
|
3869
|
+
nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % options.length;
|
|
3867
3870
|
} else {
|
|
3868
|
-
|
|
3871
|
+
// ArrowUp
|
|
3872
|
+
nextIndex = currentIndex === -1 ? options.length - 1 : (currentIndex - 1 + options.length) % options.length;
|
|
3869
3873
|
}
|
|
3870
3874
|
|
|
3871
3875
|
//only one
|
|
3872
3876
|
if (options.length === 1) nextIndex = 0;
|
|
3873
|
-
if (
|
|
3874
|
-
options.forEach(function (node
|
|
3877
|
+
if (nextIndex >= 0 && nextIndex < options.length) {
|
|
3878
|
+
options.forEach(function (node) {
|
|
3875
3879
|
node === null || node === void 0 ? void 0 : node.classList.remove('active');
|
|
3876
3880
|
});
|
|
3877
3881
|
var targetOption = options[nextIndex];
|
|
3878
3882
|
if (typeof targetOption !== 'undefined' && !targetOption.classList.contains('no-match')) {
|
|
3879
3883
|
targetOption.classList.add('active');
|
|
3884
|
+
|
|
3885
|
+
// Ensure the focused option is visible in the scroll area
|
|
3886
|
+
if (typeof targetOption.scrollIntoView === 'function') {
|
|
3887
|
+
targetOption.scrollIntoView({
|
|
3888
|
+
block: 'nearest'
|
|
3889
|
+
});
|
|
3890
|
+
}
|
|
3880
3891
|
resolve(targetOption);
|
|
3881
3892
|
}
|
|
3882
3893
|
}
|
package/Select/index.js
CHANGED
|
@@ -5721,28 +5721,39 @@ var Select = /*#__PURE__*/(0,external_root_React_commonjs2_react_commonjs_react_
|
|
|
5721
5721
|
|
|
5722
5722
|
// Avoid selecting options that are disabled
|
|
5723
5723
|
var options = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide):not(.custom-select-multi__control-option-item--select-all):not(.custom-select-multi__control-option-item--clear)'));
|
|
5724
|
+
if (!options.length) return;
|
|
5725
|
+
var activeNode = listRef.current.querySelector('.list-group-item.active');
|
|
5724
5726
|
var currentIndex = options.findIndex(function (e) {
|
|
5725
|
-
return e ===
|
|
5727
|
+
return e === activeNode;
|
|
5726
5728
|
});
|
|
5727
5729
|
|
|
5728
5730
|
// get the next element in the list, "%" will loop around to 0
|
|
5729
|
-
var nextIndex;
|
|
5731
|
+
var nextIndex = -1;
|
|
5730
5732
|
if (type === 'increase') {
|
|
5731
|
-
|
|
5733
|
+
// ArrowDown
|
|
5734
|
+
nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % options.length;
|
|
5732
5735
|
} else {
|
|
5733
|
-
|
|
5736
|
+
// ArrowUp
|
|
5737
|
+
nextIndex = currentIndex === -1 ? options.length - 1 : (currentIndex - 1 + options.length) % options.length;
|
|
5734
5738
|
}
|
|
5735
5739
|
|
|
5736
5740
|
//only one
|
|
5737
5741
|
if (options.length === 1) nextIndex = 0;
|
|
5738
|
-
if (
|
|
5739
|
-
options.forEach(function (node
|
|
5742
|
+
if (nextIndex >= 0 && nextIndex < options.length) {
|
|
5743
|
+
options.forEach(function (node) {
|
|
5740
5744
|
node === null || node === void 0 ? void 0 : node.classList.remove('active');
|
|
5741
5745
|
});
|
|
5742
5746
|
var targetOption = options[nextIndex];
|
|
5743
5747
|
if (typeof targetOption !== 'undefined' && !targetOption.classList.contains('no-match')) {
|
|
5744
5748
|
targetOption.classList.add('active');
|
|
5745
5749
|
keyboardSelectedItem.current = targetOption;
|
|
5750
|
+
|
|
5751
|
+
// Ensure the focused option is visible in the scroll area
|
|
5752
|
+
if (typeof targetOption.scrollIntoView === 'function') {
|
|
5753
|
+
targetOption.scrollIntoView({
|
|
5754
|
+
block: 'nearest'
|
|
5755
|
+
});
|
|
5756
|
+
}
|
|
5746
5757
|
resolve(targetOption);
|
|
5747
5758
|
}
|
|
5748
5759
|
}
|
|
@@ -332,7 +332,7 @@ var external_root_React_commonjs2_react_commonjs_react_amd_react_default = /*#__
|
|
|
332
332
|
// EXTERNAL MODULE: ../Utils/dist/cjs/cls.js
|
|
333
333
|
var cls = __webpack_require__(188);
|
|
334
334
|
;// CONCATENATED MODULE: ./src/AccordionItem.tsx
|
|
335
|
-
var _excluded = ["heightObserver", "index", "animSpeed", "easing", "arrowOnly", "itemClassName", "itemContentWrapperClassName", "itemContentClassName", "itemTriggerClassName", "itemHeaderClassName", "itemTriggerIcon", "itemStyle", "activeItem", "title", "onToggleEv", "onTransitionEnd", "onItemCollapse", "isExpanded", "children"];
|
|
335
|
+
var _excluded = ["heightObserver", "index", "animSpeed", "easing", "arrowOnly", "itemClassName", "itemContentWrapperClassName", "itemContentClassName", "itemTriggerClassName", "itemHeaderClassName", "itemTriggerIcon", "itemStyle", "activeItem", "title", "onToggleEv", "onTransitionEnd", "onItemCollapse", "isExpanded", "forceExpanded", "children"];
|
|
336
336
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
337
337
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
338
338
|
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."); }
|
|
@@ -363,6 +363,7 @@ var AccordionItem = function AccordionItem(props) {
|
|
|
363
363
|
onTransitionEnd = props.onTransitionEnd,
|
|
364
364
|
onItemCollapse = props.onItemCollapse,
|
|
365
365
|
controlledExpanded = props.isExpanded,
|
|
366
|
+
forceExpanded = props.forceExpanded,
|
|
366
367
|
children = props.children,
|
|
367
368
|
attributes = _objectWithoutProperties(props, _excluded);
|
|
368
369
|
var _useState = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useState)(false),
|
|
@@ -371,9 +372,12 @@ var AccordionItem = function AccordionItem(props) {
|
|
|
371
372
|
setInternalExpanded = _useState2[1];
|
|
372
373
|
var isFirstRender = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(true);
|
|
373
374
|
var initialHeightSet = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(false);
|
|
375
|
+
var hasUserInteracted = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(false);
|
|
374
376
|
|
|
375
|
-
// Use controlled or uncontrolled expanded state
|
|
376
|
-
|
|
377
|
+
// Use forceExpanded if provided and user hasn't interacted, otherwise use controlled or uncontrolled expanded state
|
|
378
|
+
// forceExpanded takes priority over isExpanded from parent, but only before user interaction
|
|
379
|
+
var actualExpanded = controlledExpanded !== undefined ? controlledExpanded : internalExpanded;
|
|
380
|
+
var isExpanded = forceExpanded !== undefined && !hasUserInteracted.current ? forceExpanded : actualExpanded;
|
|
377
381
|
var observer = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(null);
|
|
378
382
|
var contentWrapperRef = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(null);
|
|
379
383
|
var contentRef = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(null);
|
|
@@ -382,6 +386,9 @@ var AccordionItem = function AccordionItem(props) {
|
|
|
382
386
|
var handleToggle = function handleToggle(e) {
|
|
383
387
|
e.preventDefault();
|
|
384
388
|
e.stopPropagation();
|
|
389
|
+
|
|
390
|
+
// Mark that user has interacted, so forceExpanded will be ignored
|
|
391
|
+
hasUserInteracted.current = true;
|
|
385
392
|
if (controlledExpanded === undefined) {
|
|
386
393
|
setInternalExpanded(function (prev) {
|
|
387
394
|
return !prev;
|
|
@@ -399,6 +406,13 @@ var AccordionItem = function AccordionItem(props) {
|
|
|
399
406
|
overflow: 'hidden'
|
|
400
407
|
};
|
|
401
408
|
};
|
|
409
|
+
|
|
410
|
+
// Reset user interaction flag when forceExpanded changes externally
|
|
411
|
+
(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function () {
|
|
412
|
+
if (forceExpanded !== undefined) {
|
|
413
|
+
hasUserInteracted.current = false;
|
|
414
|
+
}
|
|
415
|
+
}, [forceExpanded]);
|
|
402
416
|
(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function () {
|
|
403
417
|
if (triggerRef.current && typeof onItemCollapse === 'function') {
|
|
404
418
|
if (isFirstRender.current) {
|
|
@@ -3853,30 +3853,41 @@ var LiveSearch = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(
|
|
|
3853
3853
|
if (listRef.current === null || !rootRef.current.classList.contains('active')) return;
|
|
3854
3854
|
var options = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide)'));
|
|
3855
3855
|
// Avoid selecting options that are disabled
|
|
3856
|
-
options = options.filter(function (
|
|
3857
|
-
return !
|
|
3856
|
+
options = options.filter(function (option) {
|
|
3857
|
+
return !option.classList.contains('disabled');
|
|
3858
3858
|
});
|
|
3859
|
+
if (!options.length) return;
|
|
3860
|
+
var activeNode = listRef.current.querySelector('.list-group-item.active');
|
|
3859
3861
|
var currentIndex = options.findIndex(function (e) {
|
|
3860
|
-
return e ===
|
|
3862
|
+
return e === activeNode;
|
|
3861
3863
|
});
|
|
3862
3864
|
|
|
3863
3865
|
// get the next element in the list, "%" will loop around to 0
|
|
3864
|
-
var nextIndex;
|
|
3866
|
+
var nextIndex = -1;
|
|
3865
3867
|
if (type === 'increase') {
|
|
3866
|
-
|
|
3868
|
+
// ArrowDown
|
|
3869
|
+
nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % options.length;
|
|
3867
3870
|
} else {
|
|
3868
|
-
|
|
3871
|
+
// ArrowUp
|
|
3872
|
+
nextIndex = currentIndex === -1 ? options.length - 1 : (currentIndex - 1 + options.length) % options.length;
|
|
3869
3873
|
}
|
|
3870
3874
|
|
|
3871
3875
|
//only one
|
|
3872
3876
|
if (options.length === 1) nextIndex = 0;
|
|
3873
|
-
if (
|
|
3874
|
-
options.forEach(function (node
|
|
3877
|
+
if (nextIndex >= 0 && nextIndex < options.length) {
|
|
3878
|
+
options.forEach(function (node) {
|
|
3875
3879
|
node === null || node === void 0 ? void 0 : node.classList.remove('active');
|
|
3876
3880
|
});
|
|
3877
3881
|
var targetOption = options[nextIndex];
|
|
3878
3882
|
if (typeof targetOption !== 'undefined' && !targetOption.classList.contains('no-match')) {
|
|
3879
3883
|
targetOption.classList.add('active');
|
|
3884
|
+
|
|
3885
|
+
// Ensure the focused option is visible in the scroll area
|
|
3886
|
+
if (typeof targetOption.scrollIntoView === 'function') {
|
|
3887
|
+
targetOption.scrollIntoView({
|
|
3888
|
+
block: 'nearest'
|
|
3889
|
+
});
|
|
3890
|
+
}
|
|
3880
3891
|
resolve(targetOption);
|
|
3881
3892
|
}
|
|
3882
3893
|
}
|
package/lib/cjs/Select/index.js
CHANGED
|
@@ -5721,28 +5721,39 @@ var Select = /*#__PURE__*/(0,external_root_React_commonjs2_react_commonjs_react_
|
|
|
5721
5721
|
|
|
5722
5722
|
// Avoid selecting options that are disabled
|
|
5723
5723
|
var options = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide):not(.custom-select-multi__control-option-item--select-all):not(.custom-select-multi__control-option-item--clear)'));
|
|
5724
|
+
if (!options.length) return;
|
|
5725
|
+
var activeNode = listRef.current.querySelector('.list-group-item.active');
|
|
5724
5726
|
var currentIndex = options.findIndex(function (e) {
|
|
5725
|
-
return e ===
|
|
5727
|
+
return e === activeNode;
|
|
5726
5728
|
});
|
|
5727
5729
|
|
|
5728
5730
|
// get the next element in the list, "%" will loop around to 0
|
|
5729
|
-
var nextIndex;
|
|
5731
|
+
var nextIndex = -1;
|
|
5730
5732
|
if (type === 'increase') {
|
|
5731
|
-
|
|
5733
|
+
// ArrowDown
|
|
5734
|
+
nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % options.length;
|
|
5732
5735
|
} else {
|
|
5733
|
-
|
|
5736
|
+
// ArrowUp
|
|
5737
|
+
nextIndex = currentIndex === -1 ? options.length - 1 : (currentIndex - 1 + options.length) % options.length;
|
|
5734
5738
|
}
|
|
5735
5739
|
|
|
5736
5740
|
//only one
|
|
5737
5741
|
if (options.length === 1) nextIndex = 0;
|
|
5738
|
-
if (
|
|
5739
|
-
options.forEach(function (node
|
|
5742
|
+
if (nextIndex >= 0 && nextIndex < options.length) {
|
|
5743
|
+
options.forEach(function (node) {
|
|
5740
5744
|
node === null || node === void 0 ? void 0 : node.classList.remove('active');
|
|
5741
5745
|
});
|
|
5742
5746
|
var targetOption = options[nextIndex];
|
|
5743
5747
|
if (typeof targetOption !== 'undefined' && !targetOption.classList.contains('no-match')) {
|
|
5744
5748
|
targetOption.classList.add('active');
|
|
5745
5749
|
keyboardSelectedItem.current = targetOption;
|
|
5750
|
+
|
|
5751
|
+
// Ensure the focused option is visible in the scroll area
|
|
5752
|
+
if (typeof targetOption.scrollIntoView === 'function') {
|
|
5753
|
+
targetOption.scrollIntoView({
|
|
5754
|
+
block: 'nearest'
|
|
5755
|
+
});
|
|
5756
|
+
}
|
|
5746
5757
|
resolve(targetOption);
|
|
5747
5758
|
}
|
|
5748
5759
|
}
|
|
@@ -2,7 +2,6 @@ import React, { useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
export type AccordionItemProps = {
|
|
7
6
|
heightObserver?: number[];
|
|
8
7
|
index?: number;
|
|
@@ -29,6 +28,8 @@ export type AccordionItemProps = {
|
|
|
29
28
|
onItemCollapse?: (trigger: HTMLElement, icon: HTMLElement, isExpanded: boolean) => void;
|
|
30
29
|
/** Control expanded state from parent */
|
|
31
30
|
isExpanded?: boolean;
|
|
31
|
+
/** Force expanded state, takes priority over isExpanded from parent */
|
|
32
|
+
forceExpanded?: boolean;
|
|
32
33
|
/** -- */
|
|
33
34
|
children: React.ReactNode;
|
|
34
35
|
};
|
|
@@ -56,6 +57,7 @@ const AccordionItem = (props: AccordionItemProps) => {
|
|
|
56
57
|
onTransitionEnd,
|
|
57
58
|
onItemCollapse,
|
|
58
59
|
isExpanded: controlledExpanded,
|
|
60
|
+
forceExpanded,
|
|
59
61
|
children,
|
|
60
62
|
...attributes
|
|
61
63
|
} = props;
|
|
@@ -63,9 +65,12 @@ const AccordionItem = (props: AccordionItemProps) => {
|
|
|
63
65
|
const [internalExpanded, setInternalExpanded] = useState<boolean>(false);
|
|
64
66
|
const isFirstRender = useRef<boolean>(true);
|
|
65
67
|
const initialHeightSet = useRef<boolean>(false);
|
|
68
|
+
const hasUserInteracted = useRef<boolean>(false);
|
|
66
69
|
|
|
67
|
-
// Use controlled or uncontrolled expanded state
|
|
68
|
-
|
|
70
|
+
// Use forceExpanded if provided and user hasn't interacted, otherwise use controlled or uncontrolled expanded state
|
|
71
|
+
// forceExpanded takes priority over isExpanded from parent, but only before user interaction
|
|
72
|
+
const actualExpanded = controlledExpanded !== undefined ? controlledExpanded : internalExpanded;
|
|
73
|
+
const isExpanded = (forceExpanded !== undefined && !hasUserInteracted.current) ? forceExpanded : actualExpanded;
|
|
69
74
|
|
|
70
75
|
const observer = useRef<ResizeObserver | null>(null);
|
|
71
76
|
const contentWrapperRef = useRef<HTMLDivElement | null>(null);
|
|
@@ -77,6 +82,9 @@ const AccordionItem = (props: AccordionItemProps) => {
|
|
|
77
82
|
e.preventDefault();
|
|
78
83
|
e.stopPropagation();
|
|
79
84
|
|
|
85
|
+
// Mark that user has interacted, so forceExpanded will be ignored
|
|
86
|
+
hasUserInteracted.current = true;
|
|
87
|
+
|
|
80
88
|
if (controlledExpanded === undefined) {
|
|
81
89
|
setInternalExpanded(prev => !prev);
|
|
82
90
|
}
|
|
@@ -96,6 +104,13 @@ const AccordionItem = (props: AccordionItemProps) => {
|
|
|
96
104
|
};
|
|
97
105
|
|
|
98
106
|
|
|
107
|
+
// Reset user interaction flag when forceExpanded changes externally
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (forceExpanded !== undefined) {
|
|
110
|
+
hasUserInteracted.current = false;
|
|
111
|
+
}
|
|
112
|
+
}, [forceExpanded]);
|
|
113
|
+
|
|
99
114
|
useEffect(() => {
|
|
100
115
|
if (triggerRef.current && typeof onItemCollapse === 'function') {
|
|
101
116
|
if (isFirstRender.current) {
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
|
|
21
20
|
export interface OptionConfig {
|
|
22
21
|
disabled?: boolean;
|
|
23
22
|
label: any;
|
|
@@ -740,35 +739,45 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
|
|
|
740
739
|
if (listRef.current === null || !rootRef.current.classList.contains('active')) return;
|
|
741
740
|
|
|
742
741
|
|
|
743
|
-
let options = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide)'));
|
|
742
|
+
let options = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide)')) as HTMLElement[];
|
|
744
743
|
// Avoid selecting options that are disabled
|
|
745
|
-
options = options.filter((
|
|
744
|
+
options = options.filter((option: HTMLElement) => !option.classList.contains('disabled'));
|
|
745
|
+
|
|
746
|
+
if (!options.length) return;
|
|
746
747
|
|
|
747
|
-
const
|
|
748
|
+
const activeNode = listRef.current.querySelector('.list-group-item.active') as HTMLElement | null;
|
|
749
|
+
const currentIndex = options.findIndex((e: HTMLElement) => e === activeNode);
|
|
748
750
|
|
|
749
751
|
|
|
750
752
|
// get the next element in the list, "%" will loop around to 0
|
|
751
|
-
let nextIndex;
|
|
753
|
+
let nextIndex = -1;
|
|
752
754
|
if (type === 'increase') {
|
|
753
|
-
|
|
755
|
+
// ArrowDown
|
|
756
|
+
nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % options.length;
|
|
754
757
|
} else {
|
|
755
|
-
|
|
758
|
+
// ArrowUp
|
|
759
|
+
nextIndex = currentIndex === -1 ? options.length - 1 : (currentIndex - 1 + options.length) % options.length;
|
|
756
760
|
}
|
|
757
761
|
|
|
758
762
|
|
|
759
|
-
|
|
760
763
|
//only one
|
|
761
764
|
if (options.length === 1) nextIndex = 0;
|
|
762
765
|
|
|
763
766
|
|
|
764
|
-
if (
|
|
765
|
-
options.forEach((node: any
|
|
767
|
+
if (nextIndex >= 0 && nextIndex < options.length) {
|
|
768
|
+
options.forEach((node: any) => {
|
|
766
769
|
node?.classList.remove('active');
|
|
767
770
|
});
|
|
768
771
|
|
|
769
772
|
const targetOption = options[nextIndex] as HTMLElement;
|
|
770
773
|
if (typeof targetOption !== 'undefined' && !targetOption.classList.contains('no-match')) {
|
|
771
774
|
targetOption.classList.add('active');
|
|
775
|
+
|
|
776
|
+
// Ensure the focused option is visible in the scroll area
|
|
777
|
+
if (typeof (targetOption as any).scrollIntoView === 'function') {
|
|
778
|
+
(targetOption as any).scrollIntoView({ block: 'nearest' });
|
|
779
|
+
}
|
|
780
|
+
|
|
772
781
|
resolve(targetOption);
|
|
773
782
|
}
|
|
774
783
|
|
package/lib/esm/Select/index.tsx
CHANGED
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
|
|
50
51
|
export interface MultiSelectValue {
|
|
51
52
|
items: { label: string; value: string }[];
|
|
52
53
|
labels: string[];
|
|
@@ -2012,26 +2013,35 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2012
2013
|
|
|
2013
2014
|
|
|
2014
2015
|
// Avoid selecting options that are disabled
|
|
2015
|
-
const options = [].slice.call(
|
|
2016
|
-
|
|
2016
|
+
const options = [].slice.call(
|
|
2017
|
+
listRef.current.querySelectorAll(
|
|
2018
|
+
'.list-group-item:not(.hide):not(.custom-select-multi__control-option-item--select-all):not(.custom-select-multi__control-option-item--clear)'
|
|
2019
|
+
)
|
|
2020
|
+
);
|
|
2021
|
+
|
|
2022
|
+
if (!options.length) return;
|
|
2023
|
+
|
|
2024
|
+
const activeNode = listRef.current.querySelector('.list-group-item.active');
|
|
2025
|
+
const currentIndex = options.findIndex((e: HTMLElement) => e === activeNode);
|
|
2017
2026
|
|
|
2018
2027
|
|
|
2019
2028
|
// get the next element in the list, "%" will loop around to 0
|
|
2020
|
-
let nextIndex;
|
|
2029
|
+
let nextIndex = -1;
|
|
2021
2030
|
if (type === 'increase') {
|
|
2022
|
-
|
|
2031
|
+
// ArrowDown
|
|
2032
|
+
nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % options.length;
|
|
2023
2033
|
} else {
|
|
2024
|
-
|
|
2034
|
+
// ArrowUp
|
|
2035
|
+
nextIndex = currentIndex === -1 ? options.length - 1 : (currentIndex - 1 + options.length) % options.length;
|
|
2025
2036
|
}
|
|
2026
2037
|
|
|
2027
2038
|
|
|
2028
|
-
|
|
2029
2039
|
//only one
|
|
2030
2040
|
if (options.length === 1) nextIndex = 0;
|
|
2031
2041
|
|
|
2032
2042
|
|
|
2033
|
-
if (
|
|
2034
|
-
options.forEach((node: any
|
|
2043
|
+
if (nextIndex >= 0 && nextIndex < options.length) {
|
|
2044
|
+
options.forEach((node: any) => {
|
|
2035
2045
|
node?.classList.remove('active');
|
|
2036
2046
|
});
|
|
2037
2047
|
|
|
@@ -2040,6 +2050,12 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2040
2050
|
targetOption.classList.add('active');
|
|
2041
2051
|
|
|
2042
2052
|
keyboardSelectedItem.current = targetOption;
|
|
2053
|
+
|
|
2054
|
+
// Ensure the focused option is visible in the scroll area
|
|
2055
|
+
if (typeof targetOption.scrollIntoView === 'function') {
|
|
2056
|
+
targetOption.scrollIntoView({ block: 'nearest' });
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2043
2059
|
resolve(targetOption);
|
|
2044
2060
|
}
|
|
2045
2061
|
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.
|
|
1
|
+
{"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.770","description":"React components using pure Bootstrap 5+ which does not contain any external style and script libraries.","repository":{"type":"git","url":"git+https://github.com/xizon/funda-ui.git"},"scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["bootstrap","react-bootstrap","react-components","components","components-react","react-bootstrap-components","react","funda-ui","fundaui","uikit","ui-kit","ui-components"],"bugs":{"url":"https://github.com/xizon/funda-ui/issues"},"homepage":"https://github.com/xizon/funda-ui#readme","main":"all.js","license":"MIT","dependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"types":"all.d.ts","publishConfig":{"directory":"lib"},"directories":{"lib":"lib"}}
|