pesona-ui 1.0.30 → 1.0.31
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 +58 -68
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +58 -68
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/Form/Select/SelectMultiple.d.ts +3 -4
- package/dist/types/components/Form/Select/SelectWithSearch.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -8187,55 +8187,41 @@ const useDropdownPositionAndScroll = (isOpen, dropdownOptionsRef) => {
|
|
|
8187
8187
|
}, [isOpen, dropdownOptionsRef]);
|
|
8188
8188
|
};
|
|
8189
8189
|
|
|
8190
|
-
const Select = forwardRef((
|
|
8190
|
+
const Select = forwardRef((props, ref) => {
|
|
8191
|
+
const { name, label, message, selectLabel = 'Select an option', size = 'md', floatingLabel = false, error, options, value = '', onChange, onBlur, required, disabled, } = props;
|
|
8191
8192
|
const [isOpen, setIsOpen] = useState(false);
|
|
8192
|
-
const [internalValue, setInternalValue] = useState(value);
|
|
8193
8193
|
const dropdownRef = useRef(null);
|
|
8194
8194
|
const dropdownOptionsRef = useRef(null);
|
|
8195
8195
|
const selectRef = useRef(null);
|
|
8196
|
-
// Update internal value when value prop changes
|
|
8197
|
-
useEffect(() => {
|
|
8198
|
-
setInternalValue(value);
|
|
8199
|
-
}, [value]);
|
|
8200
|
-
// Expose selectRef to parent via forwardRef
|
|
8201
8196
|
useImperativeHandle(ref, () => selectRef.current);
|
|
8202
|
-
|
|
8197
|
+
useEffect(() => setIsOpen(false), []);
|
|
8198
|
+
useOutsideClick([dropdownRef], () => {
|
|
8199
|
+
setIsOpen(false);
|
|
8200
|
+
selectRef.current?.blur(); // Trigger onBlur RHF
|
|
8201
|
+
});
|
|
8202
|
+
useDropdownPositionAndScroll(isOpen, dropdownOptionsRef);
|
|
8203
|
+
const displayText = value
|
|
8204
|
+
? options.find((opt) => opt.value === value)?.label
|
|
8205
|
+
: selectLabel;
|
|
8203
8206
|
const handleOptionClick = (optionValue) => {
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8207
|
+
const syntheticEvent = {
|
|
8208
|
+
target: {
|
|
8209
|
+
name,
|
|
8210
|
+
value: optionValue,
|
|
8211
|
+
},
|
|
8212
|
+
};
|
|
8213
|
+
onChange?.(syntheticEvent);
|
|
8214
|
+
// Change the select value to trigger onChange in RHF
|
|
8209
8215
|
if (selectRef.current) {
|
|
8210
|
-
selectRef.current.value = optionValue
|
|
8216
|
+
selectRef.current.value = String(optionValue);
|
|
8211
8217
|
selectRef.current.dispatchEvent(new Event('change', { bubbles: true }));
|
|
8212
8218
|
}
|
|
8213
8219
|
setIsOpen(false);
|
|
8214
8220
|
};
|
|
8215
|
-
useOutsideClick([dropdownRef], () => {
|
|
8216
|
-
setIsOpen(false);
|
|
8217
|
-
selectRef.current?.blur();
|
|
8218
|
-
});
|
|
8219
|
-
useDropdownPositionAndScroll(isOpen, dropdownOptionsRef);
|
|
8220
|
-
useEffect(() => {
|
|
8221
|
-
return () => {
|
|
8222
|
-
setIsOpen(false);
|
|
8223
|
-
};
|
|
8224
|
-
}, []);
|
|
8225
|
-
const displayText = internalValue
|
|
8226
|
-
? options.find((option) => option.value === internalValue)?.label
|
|
8227
|
-
: selectLabel || 'Select an option';
|
|
8228
8221
|
return (React.createElement(React.Fragment, null,
|
|
8229
|
-
React.createElement("select", { ref: selectRef, name: name, value:
|
|
8230
|
-
position: 'absolute',
|
|
8231
|
-
left: '-9999px',
|
|
8232
|
-
opacity: 0,
|
|
8233
|
-
pointerEvents: 'none',
|
|
8234
|
-
width: '1px',
|
|
8235
|
-
height: '1px',
|
|
8236
|
-
}, tabIndex: -1, "aria-hidden": "true" },
|
|
8222
|
+
React.createElement("select", { ref: selectRef, name: name, value: value, onChange: onChange, onBlur: onBlur, required: required, disabled: disabled, style: { position: 'absolute', left: '-9999px' }, tabIndex: -1, "aria-hidden": "true" },
|
|
8237
8223
|
React.createElement("option", { value: "" }, "Select an option"),
|
|
8238
|
-
options.map((
|
|
8224
|
+
options.map((opt) => (React.createElement("option", { key: opt.value, value: opt.value }, opt.label)))),
|
|
8239
8225
|
label && !floatingLabel && (React.createElement("label", { htmlFor: name },
|
|
8240
8226
|
label,
|
|
8241
8227
|
" ",
|
|
@@ -8244,7 +8230,7 @@ const Select = forwardRef(({ name, label, message, selectLabel, size = 'md', flo
|
|
|
8244
8230
|
React.createElement("div", { className: `dropdown-header ${isOpen ? 'open' : ''} ${disabled ? 'disabled' : ''}`, onClick: () => !disabled && setIsOpen(!isOpen), "aria-haspopup": "listbox", "aria-expanded": isOpen },
|
|
8245
8231
|
React.createElement("span", { className: "label" }, displayText),
|
|
8246
8232
|
React.createElement(FiChevronDown, { className: "arrow" })),
|
|
8247
|
-
isOpen && (React.createElement("div", { className:
|
|
8233
|
+
isOpen && (React.createElement("div", { className: "dropdown-options scrollbar", ref: dropdownOptionsRef, role: "listbox" }, options.map((opt) => (React.createElement("div", { key: opt.value, className: `option ${opt.value === value ? 'selected' : ''}`, onClick: () => handleOptionClick(opt.value), role: "option", "aria-selected": opt.value === value }, opt.label)))))),
|
|
8248
8234
|
label && floatingLabel && (React.createElement("label", { htmlFor: name },
|
|
8249
8235
|
label,
|
|
8250
8236
|
" ",
|
|
@@ -8597,15 +8583,12 @@ const RadioButtonGroup = React.forwardRef(({ name, label, message, size = 'md',
|
|
|
8597
8583
|
});
|
|
8598
8584
|
RadioButtonGroup.displayName = 'RadioButtonGroup';
|
|
8599
8585
|
|
|
8600
|
-
const SelectMultiple = forwardRef(({ name, label, message, selectLabel, floatingLabel = false, error, options, value = [], onChange,
|
|
8586
|
+
const SelectMultiple = forwardRef(({ name, label, message, selectLabel, floatingLabel = false, error, options, value = [], onChange, required, disabled, className, }, ref) => {
|
|
8601
8587
|
const [isOpen, setIsOpen] = useState(false);
|
|
8602
8588
|
const [selectedValues, setSelectedValues] = useState(value);
|
|
8603
8589
|
const dropdownRef = useRef(null);
|
|
8604
8590
|
const dropdownOptionsRef = useRef(null);
|
|
8605
|
-
|
|
8606
|
-
// expose to RHF
|
|
8607
|
-
useImperativeHandle(ref, () => inputRef.current);
|
|
8608
|
-
// update when external value changes
|
|
8591
|
+
// Update selectedValues hanya jika value dari props berubah
|
|
8609
8592
|
useEffect(() => {
|
|
8610
8593
|
if (JSON.stringify(value) !== JSON.stringify(selectedValues)) {
|
|
8611
8594
|
setSelectedValues(value);
|
|
@@ -8616,16 +8599,14 @@ const SelectMultiple = forwardRef(({ name, label, message, selectLabel, floating
|
|
|
8616
8599
|
? selectedValues.filter((val) => val !== optionValue)
|
|
8617
8600
|
: [...selectedValues, optionValue];
|
|
8618
8601
|
setSelectedValues(newSelectedValues);
|
|
8619
|
-
onChange
|
|
8620
|
-
|
|
8621
|
-
name,
|
|
8622
|
-
|
|
8623
|
-
|
|
8624
|
-
});
|
|
8602
|
+
if (onChange) {
|
|
8603
|
+
onChange({
|
|
8604
|
+
target: { name, value: newSelectedValues },
|
|
8605
|
+
});
|
|
8606
|
+
}
|
|
8625
8607
|
};
|
|
8626
8608
|
useOutsideClick([dropdownRef], () => {
|
|
8627
8609
|
setIsOpen(false);
|
|
8628
|
-
inputRef.current?.blur();
|
|
8629
8610
|
});
|
|
8630
8611
|
useDropdownPositionAndScroll(isOpen, dropdownOptionsRef);
|
|
8631
8612
|
const selectedLabels = selectedValues
|
|
@@ -8633,13 +8614,12 @@ const SelectMultiple = forwardRef(({ name, label, message, selectLabel, floating
|
|
|
8633
8614
|
.filter(Boolean)
|
|
8634
8615
|
.join(', ');
|
|
8635
8616
|
return (React.createElement(React.Fragment, null,
|
|
8636
|
-
React.createElement("input", { type: "hidden", name: name, value: selectedValues.join(','), ref: inputRef, onBlur: onBlur, required: required }),
|
|
8637
8617
|
label && !floatingLabel && (React.createElement("label", { htmlFor: name },
|
|
8638
8618
|
label,
|
|
8639
8619
|
" ",
|
|
8640
8620
|
required && React.createElement("span", { className: "text-danger" }, "*"))),
|
|
8641
8621
|
React.createElement("div", { className: `dropdown-select-container ${className || ''}`, ref: dropdownRef },
|
|
8642
|
-
React.createElement("div", { className: `dropdown-header ${isOpen ? 'open' : ''} ${disabled ? 'disabled' : ''}`, onClick: () => !disabled && setIsOpen(!isOpen) },
|
|
8622
|
+
React.createElement("div", { className: `dropdown-header ${isOpen ? 'open' : ''} ${disabled ? 'disabled' : ''}`, onClick: () => !disabled && setIsOpen(!isOpen), ref: ref },
|
|
8643
8623
|
React.createElement("span", { className: "label" }, selectedLabels || selectLabel || 'Select an option'),
|
|
8644
8624
|
React.createElement(FiChevronDown, { className: `arrow ${isOpen ? 'open' : ''}` })),
|
|
8645
8625
|
isOpen && !disabled && (React.createElement("div", { className: "dropdown-options scrollbar", ref: dropdownOptionsRef, role: "listbox" }, options?.map((option) => (React.createElement("div", { key: option.value, className: `option ${selectedValues.includes(option.value) ? 'selected' : ''}` },
|
|
@@ -8652,39 +8632,49 @@ const SelectMultiple = forwardRef(({ name, label, message, selectLabel, floating
|
|
|
8652
8632
|
});
|
|
8653
8633
|
SelectMultiple.displayName = 'SelectMultiple';
|
|
8654
8634
|
|
|
8655
|
-
const SelectWithSearch = forwardRef((
|
|
8635
|
+
const SelectWithSearch = forwardRef((props, ref) => {
|
|
8636
|
+
const { name, label, message, selectLabel = 'Select an option', size = 'md', floatingLabel = false, error, options = [], value = '', onChange, required, disabled, selectSearch = '', setSelectSearch, isLoading = false, } = props;
|
|
8656
8637
|
const [isOpen, setIsOpen] = useState(false);
|
|
8657
8638
|
const dropdownRef = useRef(null);
|
|
8658
8639
|
const dropdownOptionsRef = useRef(null);
|
|
8640
|
+
const selectRef = useRef(null);
|
|
8641
|
+
useImperativeHandle(ref, () => selectRef.current);
|
|
8642
|
+
useOutsideClick([dropdownRef], () => setIsOpen(false));
|
|
8643
|
+
useDropdownPositionAndScroll(isOpen, dropdownOptionsRef);
|
|
8644
|
+
const displayText = value
|
|
8645
|
+
? options.find((opt) => opt.value === value)?.label
|
|
8646
|
+
: selectLabel;
|
|
8659
8647
|
const handleOptionClick = (optionValue) => {
|
|
8660
|
-
|
|
8661
|
-
|
|
8662
|
-
|
|
8663
|
-
|
|
8648
|
+
const syntheticEvent = {
|
|
8649
|
+
target: {
|
|
8650
|
+
name,
|
|
8651
|
+
value: optionValue,
|
|
8652
|
+
},
|
|
8653
|
+
};
|
|
8654
|
+
onChange?.(syntheticEvent);
|
|
8655
|
+
// Change the select value to trigger onChange in RHF
|
|
8656
|
+
if (selectRef.current) {
|
|
8657
|
+
selectRef.current.value = String(optionValue);
|
|
8658
|
+
selectRef.current.dispatchEvent(new Event('change', { bubbles: true }));
|
|
8664
8659
|
}
|
|
8665
8660
|
setIsOpen(false);
|
|
8666
8661
|
};
|
|
8667
|
-
useOutsideClick([dropdownRef], () => setIsOpen(false));
|
|
8668
|
-
useDropdownPositionAndScroll(isOpen, dropdownOptionsRef);
|
|
8669
|
-
useEffect(() => {
|
|
8670
|
-
return () => setIsOpen(false);
|
|
8671
|
-
}, []);
|
|
8672
|
-
const displayText = value
|
|
8673
|
-
? options.find((option) => option.value === value)?.label
|
|
8674
|
-
: selectLabel || 'Select an option';
|
|
8675
8662
|
return (React.createElement(React.Fragment, null,
|
|
8663
|
+
React.createElement("select", { ref: selectRef, name: name, value: value, onChange: onChange, style: { position: 'absolute', left: '-9999px' }, tabIndex: -1, "aria-hidden": "true" },
|
|
8664
|
+
React.createElement("option", { value: "" }, "Select an option"),
|
|
8665
|
+
options.map((opt) => (React.createElement("option", { key: opt.value, value: opt.value }, opt.label)))),
|
|
8676
8666
|
label && !floatingLabel && (React.createElement("label", { htmlFor: name },
|
|
8677
8667
|
label,
|
|
8678
8668
|
" ",
|
|
8679
8669
|
required && React.createElement("span", { className: "text-danger" }, "*"))),
|
|
8680
8670
|
React.createElement("div", { className: `dropdown-select-container ${size}`, ref: dropdownRef },
|
|
8681
|
-
React.createElement("div", { className: `dropdown-header ${isOpen ? 'open' : ''} ${disabled ? 'disabled' : ''}`, onClick: () => !disabled && setIsOpen(!isOpen),
|
|
8671
|
+
React.createElement("div", { className: `dropdown-header ${isOpen ? 'open' : ''} ${disabled ? 'disabled' : ''}`, onClick: () => !disabled && setIsOpen(!isOpen), "aria-haspopup": "listbox", "aria-expanded": isOpen },
|
|
8682
8672
|
React.createElement("span", { className: "label" }, displayText),
|
|
8683
8673
|
React.createElement(FiChevronDown, { className: "arrow" })),
|
|
8684
|
-
isOpen && (React.createElement("div", { className:
|
|
8674
|
+
isOpen && (React.createElement("div", { className: "dropdown-options scrollbar", ref: dropdownOptionsRef, role: "listbox" },
|
|
8685
8675
|
React.createElement("div", { className: "search-input" },
|
|
8686
|
-
React.createElement(Input, { name: "search", placeholder: "Ketik untuk mencari..", type: "search",
|
|
8687
|
-
isLoading ? (React.createElement("div", { className: "p-10 text-center" }, "Loading options...")) : options.length === 0 ? (React.createElement("div", { className: "p-10 text-center" }, "Tidak ada hasil ditemukan")) : (options.map((
|
|
8676
|
+
React.createElement(Input, { name: "search", placeholder: "Ketik untuk mencari..", type: "search", autoFocus: true, value: selectSearch, onChange: (e) => setSelectSearch?.(e.currentTarget.value) })),
|
|
8677
|
+
isLoading ? (React.createElement("div", { className: "p-10 text-center" }, "Loading options...")) : options.length === 0 ? (React.createElement("div", { className: "p-10 text-center" }, "Tidak ada hasil ditemukan")) : (options.map((opt) => (React.createElement("div", { key: opt.value, className: `option ${value === opt.value ? 'selected' : ''}`, onClick: () => handleOptionClick(opt.value), role: "option", "aria-selected": value === opt.value }, opt.label))))))),
|
|
8688
8678
|
label && floatingLabel && (React.createElement("label", { htmlFor: name },
|
|
8689
8679
|
label,
|
|
8690
8680
|
" ",
|