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.esm.js CHANGED
@@ -8187,55 +8187,41 @@ const useDropdownPositionAndScroll = (isOpen, dropdownOptionsRef) => {
8187
8187
  }, [isOpen, dropdownOptionsRef]);
8188
8188
  };
8189
8189
 
8190
- const Select = forwardRef(({ name, label, message, selectLabel, size = 'md', floatingLabel = false, error, options, value = '', onChange, onBlur, required, disabled, }, ref) => {
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
- // Handle option click
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
- setInternalValue(optionValue);
8205
- // Trigger onChange
8206
- onChange?.({
8207
- target: { name, value: optionValue, type: 'select-one' },
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.toString();
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: internalValue || '', onChange: onChange, onBlur: onBlur, required: required, disabled: disabled, style: {
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((option) => (React.createElement("option", { key: option.value, value: option.value }, option.label)))),
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: `dropdown-options scrollbar ${disabled ? 'disabled' : ''}`, ref: dropdownOptionsRef, role: "listbox" }, options.map((option, index) => (React.createElement("div", { key: `${option.value}-${index}`, className: `option ${internalValue === option.value ? 'selected' : ''}`, onClick: () => !disabled && handleOptionClick(option.value), role: "option", "aria-selected": internalValue === option.value }, option.label)))))),
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, onBlur, required, disabled, className, }, ref) => {
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
- const inputRef = useRef(null);
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
- target: {
8621
- name,
8622
- value: newSelectedValues,
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(({ name, label, message, selectLabel, size = 'md', floatingLabel = false, error, options = [], value = '', onChange, required, disabled, selectSearch = '', setSelectSearch, isLoading = false, }, ref) => {
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
- if (onChange) {
8661
- onChange({
8662
- target: { name, value: optionValue },
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), ref: ref, "aria-haspopup": "listbox", "aria-expanded": 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: `dropdown-options scrollbar ${disabled ? 'disabled' : ''}`, ref: dropdownOptionsRef, role: "listbox" },
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", autoComplete: "off", autoCorrect: "off", autoCapitalize: "off", spellCheck: false, role: "textbox", value: selectSearch, autoFocus: true, onChange: (e) => setSelectSearch && setSelectSearch(e.currentTarget.value) })),
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((option) => (React.createElement("div", { key: String(option.value), className: `option ${value === option.value ? 'selected' : ''}`, onClick: () => !disabled && handleOptionClick(String(option.value)), role: "option", "aria-selected": value === option.value }, option.label))))))),
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
  " ",