pesona-ui 1.0.15 → 1.0.16

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
@@ -8220,46 +8220,77 @@ const Select = forwardRef(({ name, label, selectLabel, size = 'md', floatingLabe
8220
8220
  });
8221
8221
  Select.displayName = 'Select';
8222
8222
 
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();
8223
+ const DropdownDatePicker = React.forwardRef(({ name, label, floatingLabel, locale = 'id', error, value, ...rest }, ref) => {
8224
+ // Helper function to safely parse date
8225
+ const parseDate = (dateString) => {
8226
+ if (!dateString)
8227
+ return new Date();
8228
+ const parsed = new Date(dateString);
8229
+ return isNaN(parsed.getTime()) ? new Date() : parsed;
8230
+ };
8231
+ // Initial date state
8232
+ const initialDate = parseDate(value);
8226
8233
  const [dateValues, setDateValues] = useState({
8227
- day: selectedDate.getDate(),
8228
- month: selectedDate.getMonth() + 1,
8229
- year: selectedDate.getFullYear(),
8234
+ day: initialDate.getDate(),
8235
+ month: initialDate.getMonth() + 1,
8236
+ year: initialDate.getFullYear(),
8230
8237
  });
8231
- const dayOptions = generateDayOptions(dateValues.month, dateValues.year);
8232
- const monthOptions = generateMonthOptions(locale);
8233
- const yearOptions = generateYearOptions();
8238
+ // Sync when external value changes
8239
+ useEffect(() => {
8240
+ if (value) {
8241
+ const d = parseDate(value);
8242
+ setDateValues({
8243
+ day: d.getDate(),
8244
+ month: d.getMonth() + 1,
8245
+ year: d.getFullYear(),
8246
+ });
8247
+ }
8248
+ }, [value]);
8249
+ // Ensure day is valid for the selected month and year
8250
+ useEffect(() => {
8251
+ const maxDay = new Date(dateValues.year, dateValues.month, 0).getDate();
8252
+ if (dateValues.day > maxDay) {
8253
+ setDateValues(prev => ({ ...prev, day: maxDay }));
8254
+ }
8255
+ // eslint-disable-next-line react-hooks/exhaustive-deps
8256
+ }, [dateValues.month, dateValues.year]);
8257
+ // Handle change for day, month, year with validation
8234
8258
  const handleChange = (field, newValue) => {
8235
- const newDateValues = { ...dateValues, [field]: newValue };
8259
+ const numericValue = parseInt(newValue, 10);
8260
+ if (isNaN(numericValue))
8261
+ return; // Guard against invalid input
8262
+ const newDateValues = { ...dateValues, [field]: numericValue };
8236
8263
  setDateValues(newDateValues);
8237
8264
  if (rest.onChange) {
8265
+ const formattedDate = `${newDateValues.year}-${String(newDateValues.month).padStart(2, '0')}-${String(newDateValues.day).padStart(2, '0')}`;
8238
8266
  rest.onChange({
8239
8267
  target: {
8240
8268
  name,
8241
- value: `${newDateValues.year}-${newDateValues.month}-${newDateValues.day}`,
8269
+ value: formattedDate,
8242
8270
  },
8243
8271
  });
8244
8272
  }
8245
8273
  };
8274
+ // Memoized options to prevent unnecessary re-calculations
8275
+ const dayOptions = useMemo(() => generateDayOptions(dateValues.month - 1, dateValues.year), [dateValues.month, dateValues.year]);
8276
+ const monthOptions = useMemo(() => generateMonthOptions(locale), [locale]);
8277
+ const yearOptions = useMemo(() => generateYearOptions(), []);
8278
+ // Label rendering
8279
+ const renderLabel = (React.createElement("label", { htmlFor: name },
8280
+ label,
8281
+ " ",
8282
+ rest.required && React.createElement("span", { className: "text-danger" }, "*")));
8246
8283
  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" }, "*"))),
8284
+ !floatingLabel && renderLabel,
8251
8285
  React.createElement("div", { className: "row", ref: ref },
8252
8286
  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" })),
8287
+ 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
8288
  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" })),
8289
+ 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
8290
  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)));
8291
+ 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" }))),
8292
+ floatingLabel && renderLabel,
8293
+ error && React.createElement("small", { className: "form-message text-danger" }, error)));
8263
8294
  });
8264
8295
  DropdownDatePicker.displayName = 'DropdownDatePicker';
8265
8296
 
@@ -8494,17 +8525,16 @@ const Radio = React.forwardRef(({ name, label, options, error, ...rest }, ref) =
8494
8525
  error && React.createElement("small", { className: "form-message" }, error)));
8495
8526
  });
8496
8527
 
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,
8528
+ const RadioButtonGroup = React.forwardRef(({ name, label, size = 'md', options, selectedValue, error, required, ...rest }, ref) => {
8529
+ return (React.createElement(React.Fragment, null,
8530
+ label && (React.createElement("label", { htmlFor: name },
8502
8531
  label,
8532
+ " ",
8503
8533
  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 }),
8534
+ 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' : ''}` },
8535
+ React.createElement("input", { type: "radio", id: option.value.toString(), name: name, value: option.value, ref: ref, ...rest }),
8506
8536
  React.createElement("span", null, option.label))))),
8507
- error && React.createElement("small", { className: "form-message" }, error)));
8537
+ error !== undefined && React.createElement("small", { className: "form-message" }, error)));
8508
8538
  });
8509
8539
  RadioButtonGroup.displayName = 'RadioButtonGroup';
8510
8540