pesona-ui 1.0.28 → 1.0.30

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 CHANGED
@@ -8189,28 +8189,34 @@ const useDropdownPositionAndScroll = (isOpen, dropdownOptionsRef) => {
8189
8189
  }, [isOpen, dropdownOptionsRef]);
8190
8190
  };
8191
8191
 
8192
- const Select = React.forwardRef(({ name, label, message, selectLabel, size = 'md', floatingLabel = false, error, options, value = '', onChange, required, disabled, }, ref) => {
8192
+ const Select = React.forwardRef(({ name, label, message, selectLabel, size = 'md', floatingLabel = false, error, options, value = '', onChange, onBlur, required, disabled, }, ref) => {
8193
8193
  const [isOpen, setIsOpen] = React.useState(false);
8194
+ const [internalValue, setInternalValue] = React.useState(value);
8194
8195
  const dropdownRef = React.useRef(null);
8195
8196
  const dropdownOptionsRef = React.useRef(null);
8197
+ const selectRef = React.useRef(null);
8198
+ // Update internal value when value prop changes
8199
+ React.useEffect(() => {
8200
+ setInternalValue(value);
8201
+ }, [value]);
8202
+ // Expose selectRef to parent via forwardRef
8203
+ React.useImperativeHandle(ref, () => selectRef.current);
8204
+ // Handle option click
8196
8205
  const handleOptionClick = (optionValue) => {
8197
- const selectedOption = options.find((opt) => opt.value === optionValue);
8198
- // Gunakan nilai asli sesuai tipe (number/string)
8199
- const actualValue = typeof selectedOption?.value === 'number'
8200
- ? Number(selectedOption.value)
8201
- : selectedOption?.value;
8202
- if (onChange) {
8203
- onChange({
8204
- target: {
8205
- name,
8206
- value: actualValue,
8207
- },
8208
- });
8206
+ setInternalValue(optionValue);
8207
+ // Trigger onChange
8208
+ onChange?.({
8209
+ target: { name, value: optionValue, type: 'select-one' },
8210
+ });
8211
+ if (selectRef.current) {
8212
+ selectRef.current.value = optionValue.toString();
8213
+ selectRef.current.dispatchEvent(new Event('change', { bubbles: true }));
8209
8214
  }
8210
8215
  setIsOpen(false);
8211
8216
  };
8212
8217
  useOutsideClick([dropdownRef], () => {
8213
8218
  setIsOpen(false);
8219
+ selectRef.current?.blur();
8214
8220
  });
8215
8221
  useDropdownPositionAndScroll(isOpen, dropdownOptionsRef);
8216
8222
  React.useEffect(() => {
@@ -8218,19 +8224,29 @@ const Select = React.forwardRef(({ name, label, message, selectLabel, size = 'md
8218
8224
  setIsOpen(false);
8219
8225
  };
8220
8226
  }, []);
8221
- const displayText = value
8222
- ? options.find((option) => option.value === value)?.label
8227
+ const displayText = internalValue
8228
+ ? options.find((option) => option.value === internalValue)?.label
8223
8229
  : selectLabel || 'Select an option';
8224
8230
  return (React.createElement(React.Fragment, null,
8231
+ React.createElement("select", { ref: selectRef, name: name, value: internalValue || '', onChange: onChange, onBlur: onBlur, required: required, disabled: disabled, style: {
8232
+ position: 'absolute',
8233
+ left: '-9999px',
8234
+ opacity: 0,
8235
+ pointerEvents: 'none',
8236
+ width: '1px',
8237
+ height: '1px',
8238
+ }, tabIndex: -1, "aria-hidden": "true" },
8239
+ React.createElement("option", { value: "" }, "Select an option"),
8240
+ options.map((option) => (React.createElement("option", { key: option.value, value: option.value }, option.label)))),
8225
8241
  label && !floatingLabel && (React.createElement("label", { htmlFor: name },
8226
8242
  label,
8227
8243
  " ",
8228
8244
  required && React.createElement("span", { className: "text-danger" }, "*"))),
8229
8245
  React.createElement("div", { className: `dropdown-select-container ${size}`, ref: dropdownRef },
8230
- React.createElement("div", { className: `dropdown-header ${isOpen ? 'open' : ''} ${disabled ? 'disabled' : ''}`, onClick: () => !disabled && setIsOpen(!isOpen), ref: ref, "aria-haspopup": "listbox", "aria-expanded": isOpen },
8246
+ React.createElement("div", { className: `dropdown-header ${isOpen ? 'open' : ''} ${disabled ? 'disabled' : ''}`, onClick: () => !disabled && setIsOpen(!isOpen), "aria-haspopup": "listbox", "aria-expanded": isOpen },
8231
8247
  React.createElement("span", { className: "label" }, displayText),
8232
8248
  React.createElement(FiChevronDown, { className: "arrow" })),
8233
- 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 ${value === option.value ? 'selected' : ''}`, onClick: () => !disabled && handleOptionClick(option.value), role: "option", "aria-selected": value === option.value }, option.label)))))),
8249
+ 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)))))),
8234
8250
  label && floatingLabel && (React.createElement("label", { htmlFor: name },
8235
8251
  label,
8236
8252
  " ",
@@ -8583,12 +8599,15 @@ const RadioButtonGroup = React.forwardRef(({ name, label, message, size = 'md',
8583
8599
  });
8584
8600
  RadioButtonGroup.displayName = 'RadioButtonGroup';
8585
8601
 
8586
- const SelectMultiple = React.forwardRef(({ name, label, message, selectLabel, floatingLabel = false, error, options, value = [], onChange, required, disabled, className, }, ref) => {
8602
+ const SelectMultiple = React.forwardRef(({ name, label, message, selectLabel, floatingLabel = false, error, options, value = [], onChange, onBlur, required, disabled, className, }, ref) => {
8587
8603
  const [isOpen, setIsOpen] = React.useState(false);
8588
8604
  const [selectedValues, setSelectedValues] = React.useState(value);
8589
8605
  const dropdownRef = React.useRef(null);
8590
8606
  const dropdownOptionsRef = React.useRef(null);
8591
- // Update selectedValues hanya jika value dari props berubah
8607
+ const inputRef = React.useRef(null);
8608
+ // expose to RHF
8609
+ React.useImperativeHandle(ref, () => inputRef.current);
8610
+ // update when external value changes
8592
8611
  React.useEffect(() => {
8593
8612
  if (JSON.stringify(value) !== JSON.stringify(selectedValues)) {
8594
8613
  setSelectedValues(value);
@@ -8599,14 +8618,16 @@ const SelectMultiple = React.forwardRef(({ name, label, message, selectLabel, fl
8599
8618
  ? selectedValues.filter((val) => val !== optionValue)
8600
8619
  : [...selectedValues, optionValue];
8601
8620
  setSelectedValues(newSelectedValues);
8602
- if (onChange) {
8603
- onChange({
8604
- target: { name, value: newSelectedValues },
8605
- });
8606
- }
8621
+ onChange?.({
8622
+ target: {
8623
+ name,
8624
+ value: newSelectedValues,
8625
+ },
8626
+ });
8607
8627
  };
8608
8628
  useOutsideClick([dropdownRef], () => {
8609
8629
  setIsOpen(false);
8630
+ inputRef.current?.blur();
8610
8631
  });
8611
8632
  useDropdownPositionAndScroll(isOpen, dropdownOptionsRef);
8612
8633
  const selectedLabels = selectedValues
@@ -8614,12 +8635,13 @@ const SelectMultiple = React.forwardRef(({ name, label, message, selectLabel, fl
8614
8635
  .filter(Boolean)
8615
8636
  .join(', ');
8616
8637
  return (React.createElement(React.Fragment, null,
8638
+ React.createElement("input", { type: "hidden", name: name, value: selectedValues.join(','), ref: inputRef, onBlur: onBlur, required: required }),
8617
8639
  label && !floatingLabel && (React.createElement("label", { htmlFor: name },
8618
8640
  label,
8619
8641
  " ",
8620
8642
  required && React.createElement("span", { className: "text-danger" }, "*"))),
8621
8643
  React.createElement("div", { className: `dropdown-select-container ${className || ''}`, ref: dropdownRef },
8622
- React.createElement("div", { className: `dropdown-header ${isOpen ? 'open' : ''} ${disabled ? 'disabled' : ''}`, onClick: () => !disabled && setIsOpen(!isOpen), ref: ref },
8644
+ React.createElement("div", { className: `dropdown-header ${isOpen ? 'open' : ''} ${disabled ? 'disabled' : ''}`, onClick: () => !disabled && setIsOpen(!isOpen) },
8623
8645
  React.createElement("span", { className: "label" }, selectedLabels || selectLabel || 'Select an option'),
8624
8646
  React.createElement(FiChevronDown, { className: `arrow ${isOpen ? 'open' : ''}` })),
8625
8647
  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' : ''}` },