pesona-ui 1.0.15 → 1.0.17

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
@@ -8200,6 +8200,9 @@ const Select = forwardRef(({ name, label, selectLabel, size = 'md', floatingLabe
8200
8200
  setIsOpen(false);
8201
8201
  };
8202
8202
  }, []);
8203
+ const displayText = value
8204
+ ? options.find((option) => option.value === value)?.label
8205
+ : selectLabel || 'Select an option';
8203
8206
  return (React.createElement(React.Fragment, null,
8204
8207
  label && !floatingLabel && (React.createElement("label", { htmlFor: name },
8205
8208
  label,
@@ -8207,10 +8210,8 @@ const Select = forwardRef(({ name, label, selectLabel, size = 'md', floatingLabe
8207
8210
  required && React.createElement("span", { className: "text-danger" }, "*"))),
8208
8211
  React.createElement("div", { className: `dropdown-select-container ${size}`, ref: dropdownRef },
8209
8212
  React.createElement("div", { className: `dropdown-header ${isOpen ? 'open' : ''} ${disabled ? 'disabled' : ''}`, onClick: () => !disabled && setIsOpen(!isOpen), ref: ref, "aria-haspopup": "listbox", "aria-expanded": isOpen },
8210
- value
8211
- ? options.find((option) => option.value === value)?.label
8212
- : selectLabel || 'Select an option',
8213
- React.createElement(FiChevronDown, null)),
8213
+ React.createElement("span", { className: "label" }, displayText),
8214
+ React.createElement(FiChevronDown, { className: "arrow" })),
8214
8215
  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.toString()), role: "option", "aria-selected": value === option.value }, option.label)))))),
8215
8216
  label && floatingLabel && (React.createElement("label", { htmlFor: name },
8216
8217
  label,
@@ -8220,46 +8221,77 @@ const Select = forwardRef(({ name, label, selectLabel, size = 'md', floatingLabe
8220
8221
  });
8221
8222
  Select.displayName = 'Select';
8222
8223
 
8223
- const DropdownDatePicker = React.forwardRef(({ name, label, floatingLabel, error, ...rest }, ref) => {
8224
- const [locale] = useState('en-US'); // Assuming locale is set to 'en-US' for simplicity
8225
- const selectedDate = rest.value ? new Date(rest.value) : new Date();
8224
+ const DropdownDatePicker = React.forwardRef(({ name, label, floatingLabel, locale = 'id', error, value, ...rest }, ref) => {
8225
+ // Helper function to safely parse date
8226
+ const parseDate = (dateString) => {
8227
+ if (!dateString)
8228
+ return new Date();
8229
+ const parsed = new Date(dateString);
8230
+ return isNaN(parsed.getTime()) ? new Date() : parsed;
8231
+ };
8232
+ // Initial date state
8233
+ const initialDate = parseDate(value);
8226
8234
  const [dateValues, setDateValues] = useState({
8227
- day: selectedDate.getDate(),
8228
- month: selectedDate.getMonth() + 1,
8229
- year: selectedDate.getFullYear(),
8235
+ day: initialDate.getDate(),
8236
+ month: initialDate.getMonth() + 1,
8237
+ year: initialDate.getFullYear(),
8230
8238
  });
8231
- const dayOptions = generateDayOptions(dateValues.month, dateValues.year);
8232
- const monthOptions = generateMonthOptions(locale);
8233
- const yearOptions = generateYearOptions();
8239
+ // Sync when external value changes
8240
+ useEffect(() => {
8241
+ if (value) {
8242
+ const d = parseDate(value);
8243
+ setDateValues({
8244
+ day: d.getDate(),
8245
+ month: d.getMonth() + 1,
8246
+ year: d.getFullYear(),
8247
+ });
8248
+ }
8249
+ }, [value]);
8250
+ // Ensure day is valid for the selected month and year
8251
+ useEffect(() => {
8252
+ const maxDay = new Date(dateValues.year, dateValues.month, 0).getDate();
8253
+ if (dateValues.day > maxDay) {
8254
+ setDateValues(prev => ({ ...prev, day: maxDay }));
8255
+ }
8256
+ // eslint-disable-next-line react-hooks/exhaustive-deps
8257
+ }, [dateValues.month, dateValues.year]);
8258
+ // Handle change for day, month, year with validation
8234
8259
  const handleChange = (field, newValue) => {
8235
- const newDateValues = { ...dateValues, [field]: newValue };
8260
+ const numericValue = parseInt(newValue, 10);
8261
+ if (isNaN(numericValue))
8262
+ return; // Guard against invalid input
8263
+ const newDateValues = { ...dateValues, [field]: numericValue };
8236
8264
  setDateValues(newDateValues);
8237
8265
  if (rest.onChange) {
8266
+ const formattedDate = `${newDateValues.year}-${String(newDateValues.month).padStart(2, '0')}-${String(newDateValues.day).padStart(2, '0')}`;
8238
8267
  rest.onChange({
8239
8268
  target: {
8240
8269
  name,
8241
- value: `${newDateValues.year}-${newDateValues.month}-${newDateValues.day}`,
8270
+ value: formattedDate,
8242
8271
  },
8243
8272
  });
8244
8273
  }
8245
8274
  };
8275
+ // Memoized options to prevent unnecessary re-calculations
8276
+ const dayOptions = useMemo(() => generateDayOptions(dateValues.month - 1, dateValues.year), [dateValues.month, dateValues.year]);
8277
+ const monthOptions = useMemo(() => generateMonthOptions(locale), [locale]);
8278
+ const yearOptions = useMemo(() => generateYearOptions(), []);
8279
+ // Label rendering
8280
+ const renderLabel = (React.createElement("label", { htmlFor: name },
8281
+ label,
8282
+ " ",
8283
+ rest.required && React.createElement("span", { className: "text-danger" }, "*")));
8246
8284
  return (React.createElement(React.Fragment, null,
8247
- !floatingLabel && (React.createElement("label", { htmlFor: name },
8248
- label,
8249
- " ",
8250
- rest.required && React.createElement("span", { className: "text-danger" }, "*"))),
8285
+ !floatingLabel && renderLabel,
8251
8286
  React.createElement("div", { className: "row", ref: ref },
8252
8287
  React.createElement("div", { className: "col-md-3" },
8253
- React.createElement(Select, { name: "day", disabled: rest.disabled, options: dayOptions, value: dateValues.day.toString(), onChange: (e) => handleChange('day', e.target.value), role: "day" })),
8288
+ React.createElement(Select, { name: `${name}-day`, disabled: rest.disabled, options: dayOptions, value: dateValues.day.toString(), onChange: (e) => handleChange('day', e.target.value), "aria-label": "Day" })),
8254
8289
  React.createElement("div", { className: "col-md-5" },
8255
- React.createElement(Select, { name: "month", disabled: rest.disabled, options: monthOptions, value: dateValues.month.toString(), onChange: (e) => handleChange('month', e.target.value), role: "month" })),
8290
+ React.createElement(Select, { name: `${name}-month`, disabled: rest.disabled, options: monthOptions, value: dateValues.month.toString(), onChange: (e) => handleChange('month', e.target.value), "aria-label": "Month" })),
8256
8291
  React.createElement("div", { className: "col-md-4" },
8257
- React.createElement(Select, { name: "year", disabled: rest.disabled, options: yearOptions, value: dateValues.year.toString(), onChange: (e) => handleChange('year', e.target.value), role: "year" }))),
8258
- floatingLabel && (React.createElement("label", { htmlFor: name },
8259
- label,
8260
- " ",
8261
- rest.required && React.createElement("span", { className: "text-danger" }, "*"))),
8262
- error && React.createElement("small", { className: "form-message" }, error)));
8292
+ React.createElement(Select, { name: `${name}-year`, disabled: rest.disabled, options: yearOptions, value: dateValues.year.toString(), onChange: (e) => handleChange('year', e.target.value), "aria-label": "Year" }))),
8293
+ floatingLabel && renderLabel,
8294
+ error && React.createElement("small", { className: "form-message text-danger" }, error)));
8263
8295
  });
8264
8296
  DropdownDatePicker.displayName = 'DropdownDatePicker';
8265
8297
 
@@ -8494,17 +8526,16 @@ const Radio = React.forwardRef(({ name, label, options, error, ...rest }, ref) =
8494
8526
  error && React.createElement("small", { className: "form-message" }, error)));
8495
8527
  });
8496
8528
 
8497
- const RadioButtonGroup = forwardRef(({ label, required, options, error, defaultValue, ...rest }, ref) => {
8498
- // Convert boolean value to string
8499
- const stringDefaultValue = typeof defaultValue === 'boolean' ? (defaultValue ? 'true' : 'false') : defaultValue;
8500
- return (React.createElement("div", null,
8501
- label && (React.createElement("label", null,
8529
+ const RadioButtonGroup = React.forwardRef(({ name, label, size = 'md', options, selectedValue, error, required, ...rest }, ref) => {
8530
+ return (React.createElement(React.Fragment, null,
8531
+ label && (React.createElement("label", { htmlFor: name },
8502
8532
  label,
8533
+ " ",
8503
8534
  required && React.createElement("span", { className: "text-danger" }, "*"))),
8504
- React.createElement("div", { className: "btn-group", "data-toggle": "buttons" }, options.map((option) => (React.createElement("label", { key: `${option.value}`, className: `btn auto btn-default btn-md ${option.value === stringDefaultValue ? 'active' : ''}` },
8505
- React.createElement("input", { type: "radio", ref: ref, value: option.value, defaultChecked: option.value === stringDefaultValue, ...rest }),
8535
+ React.createElement("div", { className: "btn-group", "data-toggle": "buttons" }, options.map((option) => (React.createElement("label", { key: option.value, className: `btn auto btn-default btn-${size} ${option.value === selectedValue ? 'active' : ''}` },
8536
+ React.createElement("input", { type: "radio", id: option.value.toString(), name: name, value: option.value, ref: ref, ...rest }),
8506
8537
  React.createElement("span", null, option.label))))),
8507
- error && React.createElement("small", { className: "form-message" }, error)));
8538
+ error !== undefined && React.createElement("small", { className: "form-message" }, error)));
8508
8539
  });
8509
8540
  RadioButtonGroup.displayName = 'RadioButtonGroup';
8510
8541