@idds/react 1.5.44 → 1.5.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +1 -1
- package/dist/index.css +1 -1
- package/dist/index.es.js +147 -66
- package/dist/index.umd.js +1 -1
- package/dist/types/components/BasicDropdown.d.ts.map +1 -1
- package/dist/types/components/Modal.d.ts.map +1 -1
- package/dist/types/components/SelectDropdown.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.es.js
CHANGED
|
@@ -2397,6 +2397,13 @@ function BasicDropdown({
|
|
|
2397
2397
|
if (disabled) return;
|
|
2398
2398
|
handleOpenChange(!isOpen);
|
|
2399
2399
|
};
|
|
2400
|
+
const handleKeyDown = (e) => {
|
|
2401
|
+
if (disabled) return;
|
|
2402
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
2403
|
+
e.preventDefault();
|
|
2404
|
+
handleOpenChange(!isOpen);
|
|
2405
|
+
}
|
|
2406
|
+
};
|
|
2400
2407
|
useEffect(() => {
|
|
2401
2408
|
const handleClickOutside = (event) => {
|
|
2402
2409
|
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
@@ -2405,11 +2412,18 @@ function BasicDropdown({
|
|
|
2405
2412
|
}
|
|
2406
2413
|
}
|
|
2407
2414
|
};
|
|
2415
|
+
const handleEscape = (event) => {
|
|
2416
|
+
if (event.key === "Escape" && isOpen) {
|
|
2417
|
+
handleOpenChange(false);
|
|
2418
|
+
}
|
|
2419
|
+
};
|
|
2408
2420
|
document.addEventListener("mousedown", handleClickOutside);
|
|
2409
2421
|
document.addEventListener("touchstart", handleClickOutside);
|
|
2422
|
+
document.addEventListener("keydown", handleEscape);
|
|
2410
2423
|
return () => {
|
|
2411
2424
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
2412
2425
|
document.removeEventListener("touchstart", handleClickOutside);
|
|
2426
|
+
document.removeEventListener("keydown", handleEscape);
|
|
2413
2427
|
};
|
|
2414
2428
|
}, [isOpen, onOpenChange]);
|
|
2415
2429
|
const isPrimitiveTrigger = typeof trigger === "string" || typeof trigger === "number";
|
|
@@ -2420,11 +2434,18 @@ function BasicDropdown({
|
|
|
2420
2434
|
ref: triggerRef,
|
|
2421
2435
|
className: clsx("ina-basic-dropdown__trigger", triggerClassName),
|
|
2422
2436
|
onClick: toggle,
|
|
2437
|
+
tabIndex: !isPrimitiveTrigger ? 0 : -1,
|
|
2438
|
+
role: !isPrimitiveTrigger ? "button" : void 0,
|
|
2439
|
+
"aria-haspopup": !isPrimitiveTrigger ? "true" : void 0,
|
|
2440
|
+
"aria-expanded": !isPrimitiveTrigger ? isOpen : void 0,
|
|
2441
|
+
onKeyDown: !isPrimitiveTrigger ? handleKeyDown : void 0,
|
|
2423
2442
|
children: isPrimitiveTrigger ? /* @__PURE__ */ jsxs(
|
|
2424
2443
|
"button",
|
|
2425
2444
|
{
|
|
2426
2445
|
type: "button",
|
|
2427
2446
|
disabled,
|
|
2447
|
+
"aria-haspopup": "true",
|
|
2448
|
+
"aria-expanded": isOpen,
|
|
2428
2449
|
className: clsx(
|
|
2429
2450
|
"ina-basic-dropdown__trigger-button",
|
|
2430
2451
|
isOpen && "ina-basic-dropdown__trigger-button--open"
|
|
@@ -3658,10 +3679,12 @@ function Modal({
|
|
|
3658
3679
|
const [isVisible, setIsVisible] = useState(false);
|
|
3659
3680
|
const closeBtnRef = useRef(null);
|
|
3660
3681
|
const labelId = useRef(`modal-title-${Math.random().toString(36).slice(2)}`);
|
|
3682
|
+
const previousFocus = useRef(null);
|
|
3661
3683
|
useEffect(() => setMounted(true), []);
|
|
3662
3684
|
useEffect(() => {
|
|
3663
3685
|
if (open) {
|
|
3664
3686
|
setShouldRender(true);
|
|
3687
|
+
previousFocus.current = document.activeElement;
|
|
3665
3688
|
requestAnimationFrame(() => {
|
|
3666
3689
|
requestAnimationFrame(() => {
|
|
3667
3690
|
setIsVisible(true);
|
|
@@ -3669,6 +3692,10 @@ function Modal({
|
|
|
3669
3692
|
});
|
|
3670
3693
|
} else {
|
|
3671
3694
|
setIsVisible(false);
|
|
3695
|
+
if (previousFocus.current) {
|
|
3696
|
+
previousFocus.current.focus();
|
|
3697
|
+
previousFocus.current = null;
|
|
3698
|
+
}
|
|
3672
3699
|
const timer = setTimeout(() => {
|
|
3673
3700
|
setShouldRender(false);
|
|
3674
3701
|
}, 300);
|
|
@@ -3686,13 +3713,39 @@ function Modal({
|
|
|
3686
3713
|
}
|
|
3687
3714
|
}, [shouldRender, mounted]);
|
|
3688
3715
|
useEffect(() => {
|
|
3689
|
-
var _a;
|
|
3690
3716
|
if (!shouldRender || !mounted) return;
|
|
3691
3717
|
if (isVisible) {
|
|
3692
|
-
(
|
|
3718
|
+
setTimeout(() => {
|
|
3719
|
+
var _a;
|
|
3720
|
+
(_a = closeBtnRef.current) == null ? void 0 : _a.focus();
|
|
3721
|
+
}, 50);
|
|
3693
3722
|
}
|
|
3694
3723
|
const onKey = (e) => {
|
|
3695
|
-
if (e.key === "Escape" && isVisible)
|
|
3724
|
+
if (e.key === "Escape" && isVisible) {
|
|
3725
|
+
onClose();
|
|
3726
|
+
return;
|
|
3727
|
+
}
|
|
3728
|
+
if (e.key === "Tab" && isVisible) {
|
|
3729
|
+
const modalElement = document.querySelector(".ina-modal__dialog");
|
|
3730
|
+
if (!modalElement) return;
|
|
3731
|
+
const focusableElements = modalElement.querySelectorAll(
|
|
3732
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
3733
|
+
);
|
|
3734
|
+
if (focusableElements.length === 0) return;
|
|
3735
|
+
const firstElement = focusableElements[0];
|
|
3736
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
3737
|
+
if (e.shiftKey) {
|
|
3738
|
+
if (document.activeElement === firstElement) {
|
|
3739
|
+
e.preventDefault();
|
|
3740
|
+
lastElement.focus();
|
|
3741
|
+
}
|
|
3742
|
+
} else {
|
|
3743
|
+
if (document.activeElement === lastElement) {
|
|
3744
|
+
e.preventDefault();
|
|
3745
|
+
firstElement.focus();
|
|
3746
|
+
}
|
|
3747
|
+
}
|
|
3748
|
+
}
|
|
3696
3749
|
};
|
|
3697
3750
|
document.addEventListener("keydown", onKey);
|
|
3698
3751
|
return () => document.removeEventListener("keydown", onKey);
|
|
@@ -5278,10 +5331,13 @@ const SelectDropdown = ({
|
|
|
5278
5331
|
required,
|
|
5279
5332
|
selectionTitle
|
|
5280
5333
|
}) => {
|
|
5334
|
+
var _a;
|
|
5281
5335
|
const [isOpen, setIsOpen] = useState(false);
|
|
5282
5336
|
const [internalSearchTerm, setInternalSearchTerm] = useState("");
|
|
5337
|
+
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
5283
5338
|
const containerRef = useRef(null);
|
|
5284
5339
|
const scrollContainerRef = useRef(null);
|
|
5340
|
+
const optionsRefs = useRef([]);
|
|
5285
5341
|
const searchTimeoutRef = useRef(null);
|
|
5286
5342
|
const selectedLabelsCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
5287
5343
|
const isSearchControlled = searchValue !== void 0;
|
|
@@ -5308,19 +5364,11 @@ const SelectDropdown = ({
|
|
|
5308
5364
|
setInternalSearchTerm(searchValue);
|
|
5309
5365
|
}
|
|
5310
5366
|
}, [searchValue, isSearchControlled, internalSearchTerm]);
|
|
5311
|
-
const handleLoadMoreClick = () => {
|
|
5312
|
-
if (disabled || !hasMore || loading || !onLoadMore) return;
|
|
5313
|
-
onLoadMore(currentPage + 1);
|
|
5314
|
-
};
|
|
5315
5367
|
useEffect(() => {
|
|
5316
5368
|
const handleClickOutside = (e) => {
|
|
5317
5369
|
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
5318
5370
|
setIsOpen(false);
|
|
5319
|
-
|
|
5320
|
-
onSearchChange == null ? void 0 : onSearchChange("");
|
|
5321
|
-
} else {
|
|
5322
|
-
setInternalSearchTerm("");
|
|
5323
|
-
}
|
|
5371
|
+
setFocusedIndex(-1);
|
|
5324
5372
|
onClose == null ? void 0 : onClose();
|
|
5325
5373
|
}
|
|
5326
5374
|
};
|
|
@@ -5423,6 +5471,18 @@ const SelectDropdown = ({
|
|
|
5423
5471
|
const filteredOptions = onSearch ? options : !searchable ? options : options.filter(
|
|
5424
5472
|
(o) => o.label.toLowerCase().includes(searchTerm.toLowerCase())
|
|
5425
5473
|
);
|
|
5474
|
+
useEffect(() => {
|
|
5475
|
+
setFocusedIndex(-1);
|
|
5476
|
+
}, [filteredOptions]);
|
|
5477
|
+
useEffect(() => {
|
|
5478
|
+
var _a2;
|
|
5479
|
+
if (isOpen && focusedIndex >= 0 && optionsRefs.current[focusedIndex]) {
|
|
5480
|
+
(_a2 = optionsRefs.current[focusedIndex]) == null ? void 0 : _a2.scrollIntoView({
|
|
5481
|
+
block: "nearest",
|
|
5482
|
+
inline: "nearest"
|
|
5483
|
+
});
|
|
5484
|
+
}
|
|
5485
|
+
}, [focusedIndex, isOpen]);
|
|
5426
5486
|
const handleSearchChange = (e) => {
|
|
5427
5487
|
const newValue = e.target.value;
|
|
5428
5488
|
if (isSearchControlled) {
|
|
@@ -5540,11 +5600,11 @@ const SelectDropdown = ({
|
|
|
5540
5600
|
return "";
|
|
5541
5601
|
};
|
|
5542
5602
|
const handleTriggerClick = () => {
|
|
5543
|
-
var
|
|
5603
|
+
var _a2;
|
|
5544
5604
|
if (!isOpen && !disabled) {
|
|
5545
5605
|
setIsOpen(true);
|
|
5546
5606
|
}
|
|
5547
|
-
const input = (
|
|
5607
|
+
const input = (_a2 = containerRef.current) == null ? void 0 : _a2.querySelector("input");
|
|
5548
5608
|
if (input) {
|
|
5549
5609
|
input.focus();
|
|
5550
5610
|
}
|
|
@@ -5553,9 +5613,62 @@ const SelectDropdown = ({
|
|
|
5553
5613
|
if (!isOpen) setIsOpen(true);
|
|
5554
5614
|
handleSearchChange(e);
|
|
5555
5615
|
};
|
|
5616
|
+
const handleOptionSelect = (option) => {
|
|
5617
|
+
var _a2;
|
|
5618
|
+
if (disabled || option.disabled) return;
|
|
5619
|
+
if (multiple) {
|
|
5620
|
+
const prev = Array.isArray(selected) ? [...selected] : [];
|
|
5621
|
+
const newSelected = prev.includes(option.value) ? prev.filter((v) => v !== option.value) : [...prev, option.value];
|
|
5622
|
+
if (prev.includes(option.value)) {
|
|
5623
|
+
selectedLabelsCacheRef.current.delete(option.value);
|
|
5624
|
+
} else {
|
|
5625
|
+
selectedLabelsCacheRef.current.set(option.value, option.label);
|
|
5626
|
+
}
|
|
5627
|
+
onSelect(newSelected);
|
|
5628
|
+
const input = (_a2 = containerRef.current) == null ? void 0 : _a2.querySelector("input");
|
|
5629
|
+
if (input) input.focus();
|
|
5630
|
+
} else {
|
|
5631
|
+
const isSelected = option.value === singleSelected;
|
|
5632
|
+
if (isSelected) {
|
|
5633
|
+
selectedLabelsCacheRef.current.delete(option.value);
|
|
5634
|
+
onSelect(null, option);
|
|
5635
|
+
} else {
|
|
5636
|
+
selectedLabelsCacheRef.current.set(option.value, option.label);
|
|
5637
|
+
onSelect(option.value, option);
|
|
5638
|
+
}
|
|
5639
|
+
setIsOpen(false);
|
|
5640
|
+
setFocusedIndex(-1);
|
|
5641
|
+
if (isSearchControlled) {
|
|
5642
|
+
onSearchChange == null ? void 0 : onSearchChange("");
|
|
5643
|
+
} else {
|
|
5644
|
+
setInternalSearchTerm("");
|
|
5645
|
+
}
|
|
5646
|
+
onClose == null ? void 0 : onClose();
|
|
5647
|
+
}
|
|
5648
|
+
};
|
|
5556
5649
|
const handleInputKeyDown = (e) => {
|
|
5557
|
-
if (e.key === "
|
|
5650
|
+
if (e.key === "ArrowDown") {
|
|
5651
|
+
e.preventDefault();
|
|
5652
|
+
if (!isOpen) {
|
|
5653
|
+
setIsOpen(true);
|
|
5654
|
+
setFocusedIndex(0);
|
|
5655
|
+
} else {
|
|
5656
|
+
setFocusedIndex(
|
|
5657
|
+
(prev) => prev < filteredOptions.length - 1 ? prev + 1 : prev
|
|
5658
|
+
);
|
|
5659
|
+
}
|
|
5660
|
+
} else if (e.key === "ArrowUp") {
|
|
5661
|
+
e.preventDefault();
|
|
5662
|
+
setFocusedIndex((prev) => prev > 0 ? prev - 1 : prev);
|
|
5663
|
+
} else if (e.key === "Enter") {
|
|
5664
|
+
e.preventDefault();
|
|
5665
|
+
if (isOpen && focusedIndex >= 0 && focusedIndex < filteredOptions.length) {
|
|
5666
|
+
handleOptionSelect(filteredOptions[focusedIndex]);
|
|
5667
|
+
}
|
|
5668
|
+
} else if (e.key === "Escape") {
|
|
5558
5669
|
e.preventDefault();
|
|
5670
|
+
setIsOpen(false);
|
|
5671
|
+
setFocusedIndex(-1);
|
|
5559
5672
|
}
|
|
5560
5673
|
};
|
|
5561
5674
|
return /* @__PURE__ */ jsxs(
|
|
@@ -5592,7 +5705,8 @@ const SelectDropdown = ({
|
|
|
5592
5705
|
onChange: onInputChange,
|
|
5593
5706
|
onKeyDown: handleInputKeyDown,
|
|
5594
5707
|
disabled,
|
|
5595
|
-
"aria-autocomplete": "list"
|
|
5708
|
+
"aria-autocomplete": "list",
|
|
5709
|
+
"aria-activedescendant": isOpen && focusedIndex >= 0 ? `option-${(_a = filteredOptions[focusedIndex]) == null ? void 0 : _a.value}` : void 0
|
|
5596
5710
|
}
|
|
5597
5711
|
) : /* @__PURE__ */ jsx(
|
|
5598
5712
|
"span",
|
|
@@ -5638,6 +5752,12 @@ const SelectDropdown = ({
|
|
|
5638
5752
|
{
|
|
5639
5753
|
ref: scrollContainerRef,
|
|
5640
5754
|
className: "ina-select-dropdown__options",
|
|
5755
|
+
onScroll: (e) => {
|
|
5756
|
+
const target = e.currentTarget;
|
|
5757
|
+
if (target.scrollHeight - target.scrollTop - target.clientHeight < 50 && !loading && hasMore && onLoadMore && !disabled) {
|
|
5758
|
+
onLoadMore(currentPage + 1);
|
|
5759
|
+
}
|
|
5760
|
+
},
|
|
5641
5761
|
children: [
|
|
5642
5762
|
selectionTitle && /* @__PURE__ */ jsx("div", { className: "ina-select-dropdown__selection-title", children: selectionTitle }),
|
|
5643
5763
|
filteredOptions.map((option, index) => {
|
|
@@ -5675,56 +5795,26 @@ const SelectDropdown = ({
|
|
|
5675
5795
|
}
|
|
5676
5796
|
);
|
|
5677
5797
|
}
|
|
5678
|
-
const handleOptionClick = (e) => {
|
|
5679
|
-
var _a;
|
|
5680
|
-
e.preventDefault();
|
|
5681
|
-
e.stopPropagation();
|
|
5682
|
-
if (disabled || option.disabled) return;
|
|
5683
|
-
if (multiple) {
|
|
5684
|
-
const prev = Array.isArray(selected) ? [...selected] : [];
|
|
5685
|
-
const newSelected = prev.includes(option.value) ? prev.filter((v) => v !== option.value) : [...prev, option.value];
|
|
5686
|
-
if (prev.includes(option.value)) {
|
|
5687
|
-
selectedLabelsCacheRef.current.delete(option.value);
|
|
5688
|
-
} else {
|
|
5689
|
-
selectedLabelsCacheRef.current.set(
|
|
5690
|
-
option.value,
|
|
5691
|
-
option.label
|
|
5692
|
-
);
|
|
5693
|
-
}
|
|
5694
|
-
onSelect(newSelected);
|
|
5695
|
-
const input = (_a = containerRef.current) == null ? void 0 : _a.querySelector("input");
|
|
5696
|
-
if (input) input.focus();
|
|
5697
|
-
} else {
|
|
5698
|
-
if (isSelected) {
|
|
5699
|
-
selectedLabelsCacheRef.current.delete(option.value);
|
|
5700
|
-
onSelect(null, option);
|
|
5701
|
-
} else {
|
|
5702
|
-
selectedLabelsCacheRef.current.set(
|
|
5703
|
-
option.value,
|
|
5704
|
-
option.label
|
|
5705
|
-
);
|
|
5706
|
-
onSelect(option.value, option);
|
|
5707
|
-
}
|
|
5708
|
-
setIsOpen(false);
|
|
5709
|
-
if (isSearchControlled) {
|
|
5710
|
-
onSearchChange == null ? void 0 : onSearchChange("");
|
|
5711
|
-
} else {
|
|
5712
|
-
setInternalSearchTerm("");
|
|
5713
|
-
}
|
|
5714
|
-
onClose == null ? void 0 : onClose();
|
|
5715
|
-
}
|
|
5716
|
-
};
|
|
5717
5798
|
return /* @__PURE__ */ jsxs(
|
|
5718
5799
|
"button",
|
|
5719
5800
|
{
|
|
5801
|
+
ref: (el) => {
|
|
5802
|
+
optionsRefs.current[index] = el;
|
|
5803
|
+
},
|
|
5804
|
+
id: `option-${option.value}`,
|
|
5720
5805
|
type: "button",
|
|
5721
|
-
onClick:
|
|
5806
|
+
onClick: (e) => {
|
|
5807
|
+
e.preventDefault();
|
|
5808
|
+
e.stopPropagation();
|
|
5809
|
+
handleOptionSelect(option);
|
|
5810
|
+
},
|
|
5722
5811
|
disabled: disabled || option.disabled,
|
|
5723
5812
|
className: clsx(
|
|
5724
5813
|
"ina-select-dropdown__option",
|
|
5725
5814
|
!multiple && isSelected && "ina-select-dropdown__option--selected-single",
|
|
5726
5815
|
multiple && isSelected && "ina-select-dropdown__option--selected-multiple",
|
|
5727
|
-
(disabled || option.disabled) && "ina-select-dropdown__option--disabled"
|
|
5816
|
+
(disabled || option.disabled) && "ina-select-dropdown__option--disabled",
|
|
5817
|
+
index === focusedIndex && "ina-select-dropdown__option--focused"
|
|
5728
5818
|
),
|
|
5729
5819
|
children: [
|
|
5730
5820
|
/* @__PURE__ */ jsx("div", { className: "ina-select-dropdown__option-content", children: labelContent }),
|
|
@@ -5735,15 +5825,6 @@ const SelectDropdown = ({
|
|
|
5735
5825
|
);
|
|
5736
5826
|
}),
|
|
5737
5827
|
filteredOptions.length === 0 && !loading && /* @__PURE__ */ jsx("div", { className: "ina-select-dropdown__empty", children: "No results" }),
|
|
5738
|
-
hasMore && !loading && filteredOptions.length > 0 && onLoadMore && !disabled && /* @__PURE__ */ jsx("div", { className: "ina-select-dropdown__load-more", children: /* @__PURE__ */ jsx(
|
|
5739
|
-
"button",
|
|
5740
|
-
{
|
|
5741
|
-
type: "button",
|
|
5742
|
-
onClick: handleLoadMoreClick,
|
|
5743
|
-
className: "ina-select-dropdown__load-more-button",
|
|
5744
|
-
children: "Tampilkan Lebih Banyak"
|
|
5745
|
-
}
|
|
5746
|
-
) }),
|
|
5747
5828
|
loading && /* @__PURE__ */ jsxs("div", { className: "ina-select-dropdown__loading", children: [
|
|
5748
5829
|
/* @__PURE__ */ jsx("div", { className: "ina-select-dropdown__loading-spinner", children: /* @__PURE__ */ jsx(IconLoader2, { size: 20 }) }),
|
|
5749
5830
|
/* @__PURE__ */ jsx("span", { className: "ina-select-dropdown__loading-text", children: "Loading..." })
|