@underverse-ui/underverse 0.2.109 → 0.2.110

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.d.cts CHANGED
@@ -818,6 +818,10 @@ interface TimePickerProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "
818
818
  label: string;
819
819
  time: string;
820
820
  }>;
821
+ /** Alias for minTime (e.g., "09:00") */
822
+ min?: string;
823
+ /** Alias for maxTime (e.g., "18:00") */
824
+ max?: string;
821
825
  /** Minimum allowed time (e.g., "09:00") */
822
826
  minTime?: string;
823
827
  /** Maximum allowed time (e.g., "18:00") */
@@ -837,7 +841,7 @@ interface TimePickerProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "
837
841
  /** Callback when popover closes */
838
842
  onClose?: () => void;
839
843
  }
840
- declare function TimePicker({ value, defaultValue, onChange, placeholder, disabled, size, label, required, format, includeSeconds, minuteStep, secondStep, clearable, variant, matchTriggerWidth, showNow, showPresets, allowManualInput, customPresets, minTime, maxTime, disabledTimes, error, success, helperText, animate, onOpen, onClose, className, ...rest }: TimePickerProps): react_jsx_runtime.JSX.Element;
844
+ declare function TimePicker({ value, defaultValue, onChange, placeholder, disabled, size, label, required, format, includeSeconds, minuteStep, secondStep, clearable, variant, matchTriggerWidth, showNow, showPresets, allowManualInput, customPresets, min, max, minTime, maxTime, disabledTimes, error, success, helperText, animate, onOpen, onClose, className, ...rest }: TimePickerProps): react_jsx_runtime.JSX.Element;
841
845
 
842
846
  type SelectMode = "single" | "multiple" | "range";
843
847
  type Variant$3 = "default" | "bordered" | "card" | "minimal";
package/dist/index.d.ts CHANGED
@@ -818,6 +818,10 @@ interface TimePickerProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "
818
818
  label: string;
819
819
  time: string;
820
820
  }>;
821
+ /** Alias for minTime (e.g., "09:00") */
822
+ min?: string;
823
+ /** Alias for maxTime (e.g., "18:00") */
824
+ max?: string;
821
825
  /** Minimum allowed time (e.g., "09:00") */
822
826
  minTime?: string;
823
827
  /** Maximum allowed time (e.g., "18:00") */
@@ -837,7 +841,7 @@ interface TimePickerProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "
837
841
  /** Callback when popover closes */
838
842
  onClose?: () => void;
839
843
  }
840
- declare function TimePicker({ value, defaultValue, onChange, placeholder, disabled, size, label, required, format, includeSeconds, minuteStep, secondStep, clearable, variant, matchTriggerWidth, showNow, showPresets, allowManualInput, customPresets, minTime, maxTime, disabledTimes, error, success, helperText, animate, onOpen, onClose, className, ...rest }: TimePickerProps): react_jsx_runtime.JSX.Element;
844
+ declare function TimePicker({ value, defaultValue, onChange, placeholder, disabled, size, label, required, format, includeSeconds, minuteStep, secondStep, clearable, variant, matchTriggerWidth, showNow, showPresets, allowManualInput, customPresets, min, max, minTime, maxTime, disabledTimes, error, success, helperText, animate, onOpen, onClose, className, ...rest }: TimePickerProps): react_jsx_runtime.JSX.Element;
841
845
 
842
846
  type SelectMode = "single" | "multiple" | "range";
843
847
  type Variant$3 = "default" | "bordered" | "card" | "minimal";
package/dist/index.js CHANGED
@@ -6021,8 +6021,8 @@ var DatePicker = ({
6021
6021
  "div",
6022
6022
  {
6023
6023
  className: cn(
6024
- "flex items-center justify-center rounded-lg p-1.5 transition-all duration-300",
6025
- isOpen ? "bg-primary/15 text-primary" : "bg-muted/50 text-muted-foreground group-hover:bg-primary/10 group-hover:text-primary"
6024
+ "flex items-center justify-center transition-colors duration-300",
6025
+ isOpen ? "text-primary" : "text-muted-foreground group-hover:text-primary"
6026
6026
  ),
6027
6027
  children: /* @__PURE__ */ jsx29(Calendar, { className: cn(size === "sm" ? "h-3.5 w-3.5" : "h-4 w-4", "transition-transform duration-300", isOpen && "scale-110") })
6028
6028
  }
@@ -6317,9 +6317,8 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
6317
6317
  "div",
6318
6318
  {
6319
6319
  className: cn(
6320
- "flex items-center justify-center rounded-lg transition-all duration-300",
6321
- size === "sm" ? "p-1" : "p-1.5",
6322
- isOpen ? "bg-primary/15 text-primary" : "bg-muted/50 text-muted-foreground group-hover:bg-primary/10 group-hover:text-primary"
6320
+ "flex items-center justify-center transition-colors duration-300",
6321
+ isOpen ? "text-primary" : "text-muted-foreground group-hover:text-primary"
6323
6322
  ),
6324
6323
  children: /* @__PURE__ */ jsx29(Calendar, { className: cn("transition-transform duration-300", size === "sm" ? "h-3 w-3" : "h-4 w-4", isOpen && "scale-110") })
6325
6324
  }
@@ -7393,6 +7392,8 @@ function TimePicker({
7393
7392
  showPresets = false,
7394
7393
  allowManualInput = false,
7395
7394
  customPresets = [],
7395
+ min,
7396
+ max,
7396
7397
  minTime,
7397
7398
  maxTime,
7398
7399
  disabledTimes,
@@ -7429,37 +7430,65 @@ function TimePicker({
7429
7430
  },
7430
7431
  [disabledTimes]
7431
7432
  );
7433
+ const resolvedMinTime = minTime ?? min;
7434
+ const resolvedMaxTime = maxTime ?? max;
7435
+ const toSeconds = React25.useCallback(
7436
+ (p) => {
7437
+ let h = p.h;
7438
+ if (format === "12") {
7439
+ const period = p.p ?? (h >= 12 ? "PM" : "AM");
7440
+ const base = h % 12;
7441
+ h = period === "PM" ? base + 12 : base;
7442
+ }
7443
+ return h * 3600 + p.m * 60 + (includeSeconds ? p.s : 0);
7444
+ },
7445
+ [format, includeSeconds]
7446
+ );
7432
7447
  const isTimeInRange = React25.useCallback(
7433
7448
  (timeStr) => {
7434
- if (!minTime && !maxTime) return true;
7449
+ if (!resolvedMinTime && !resolvedMaxTime) return true;
7435
7450
  const parsed = parseTime(timeStr, format, includeSeconds);
7436
7451
  if (!parsed) return true;
7437
- if (minTime) {
7438
- const min = parseTime(minTime, format, includeSeconds);
7439
- if (min) {
7440
- const currentMinutes = parsed.h * 60 + parsed.m;
7441
- const minMinutes = min.h * 60 + min.m;
7442
- if (currentMinutes < minMinutes) return false;
7443
- }
7452
+ const current = toSeconds(parsed);
7453
+ if (resolvedMinTime) {
7454
+ const minParsed = parseTime(resolvedMinTime, format, includeSeconds);
7455
+ if (minParsed && current < toSeconds(minParsed)) return false;
7444
7456
  }
7445
- if (maxTime) {
7446
- const max = parseTime(maxTime, format, includeSeconds);
7447
- if (max) {
7448
- const currentMinutes = parsed.h * 60 + parsed.m;
7449
- const maxMinutes = max.h * 60 + max.m;
7450
- if (currentMinutes > maxMinutes) return false;
7451
- }
7457
+ if (resolvedMaxTime) {
7458
+ const maxParsed = parseTime(resolvedMaxTime, format, includeSeconds);
7459
+ if (maxParsed && current > toSeconds(maxParsed)) return false;
7452
7460
  }
7453
7461
  return true;
7454
7462
  },
7455
- [minTime, maxTime, format, includeSeconds]
7463
+ [format, includeSeconds, resolvedMaxTime, resolvedMinTime, toSeconds]
7464
+ );
7465
+ const canEmit = React25.useCallback(
7466
+ (next) => {
7467
+ const timeStr = next ? formatTime(next, format, includeSeconds) : void 0;
7468
+ if (!timeStr) return true;
7469
+ if (!isTimeInRange(timeStr)) return false;
7470
+ if (isTimeDisabled(timeStr)) return false;
7471
+ return true;
7472
+ },
7473
+ [format, includeSeconds, isTimeDisabled, isTimeInRange]
7474
+ );
7475
+ const emit = React25.useCallback(
7476
+ (next) => {
7477
+ const timeStr = next ? formatTime(next, format, includeSeconds) : void 0;
7478
+ if (!canEmit(next)) return;
7479
+ onChange?.(timeStr);
7480
+ },
7481
+ [canEmit, format, includeSeconds, onChange]
7482
+ );
7483
+ const tryUpdate = React25.useCallback(
7484
+ (next) => {
7485
+ if (!canEmit(next)) return false;
7486
+ setParts(next);
7487
+ emit(next);
7488
+ return true;
7489
+ },
7490
+ [canEmit, emit]
7456
7491
  );
7457
- const emit = (next) => {
7458
- const timeStr = next ? formatTime(next, format, includeSeconds) : void 0;
7459
- if (timeStr && !isTimeInRange(timeStr)) return;
7460
- if (timeStr && isTimeDisabled(timeStr)) return;
7461
- onChange?.(timeStr);
7462
- };
7463
7492
  const handleOpenChange = (newOpen) => {
7464
7493
  setOpen(newOpen);
7465
7494
  if (newOpen) {
@@ -7510,8 +7539,7 @@ function TimePicker({
7510
7539
  if (e.key === "ArrowLeft") setFocusedColumn(includeSeconds ? "second" : "minute");
7511
7540
  break;
7512
7541
  }
7513
- setParts(newParts);
7514
- emit(newParts);
7542
+ tryUpdate(newParts);
7515
7543
  };
7516
7544
  const setNow = () => {
7517
7545
  const now2 = /* @__PURE__ */ new Date();
@@ -7524,8 +7552,7 @@ function TimePicker({
7524
7552
  } else {
7525
7553
  next = { h, m, s };
7526
7554
  }
7527
- setParts(next);
7528
- emit(next);
7555
+ tryUpdate(next);
7529
7556
  };
7530
7557
  const setPreset = (preset) => {
7531
7558
  const { h, m, s } = PRESETS[preset];
@@ -7535,8 +7562,7 @@ function TimePicker({
7535
7562
  } else {
7536
7563
  next = { h, m, s };
7537
7564
  }
7538
- setParts(next);
7539
- emit(next);
7565
+ tryUpdate(next);
7540
7566
  };
7541
7567
  const handleManualInput = (input) => {
7542
7568
  setManualInput(input);
@@ -7544,16 +7570,14 @@ function TimePicker({
7544
7570
  if (parsed) {
7545
7571
  const timeStr = formatTime(parsed, format, includeSeconds);
7546
7572
  if (isTimeInRange(timeStr) && !isTimeDisabled(timeStr)) {
7547
- setParts(parsed);
7548
- emit(parsed);
7573
+ tryUpdate(parsed);
7549
7574
  }
7550
7575
  }
7551
7576
  };
7552
7577
  const handleCustomPreset = (time) => {
7553
7578
  const parsed = parseTime(time, format, includeSeconds);
7554
7579
  if (parsed) {
7555
- setParts(parsed);
7556
- emit(parsed);
7580
+ tryUpdate(parsed);
7557
7581
  }
7558
7582
  };
7559
7583
  const hours = format === "24" ? Array.from({ length: 24 }, (_, i) => i) : Array.from({ length: 12 }, (_, i) => i + 1);
@@ -7674,8 +7698,7 @@ function TimePicker({
7674
7698
  return period === "PM" ? base + 12 : base;
7675
7699
  })();
7676
7700
  const next = { ...parts, h: nextH, p: format === "12" ? period : parts.p };
7677
- setParts(next);
7678
- emit(next);
7701
+ tryUpdate(next);
7679
7702
  };
7680
7703
  const timePickerContent = /* @__PURE__ */ jsxs26("div", { className: panelSz.stackGap, children: [
7681
7704
  /* @__PURE__ */ jsx31("div", { className: "flex items-center justify-center py-1", children: /* @__PURE__ */ jsx31("span", { className: cn(panelSz.timeText, "font-bold tabular-nums tracking-wide text-foreground underline underline-offset-8 decoration-primary/60"), children: display }) }),
@@ -7781,8 +7804,7 @@ function TimePicker({
7781
7804
  valueIndex: minuteIndex,
7782
7805
  onSelect: (m) => {
7783
7806
  const next = { ...parts, m };
7784
- setParts(next);
7785
- emit(next);
7807
+ tryUpdate(next);
7786
7808
  },
7787
7809
  scrollRef: minuteScrollRef,
7788
7810
  itemHeight,
@@ -7810,8 +7832,7 @@ function TimePicker({
7810
7832
  valueIndex: secondIndex,
7811
7833
  onSelect: (s) => {
7812
7834
  const next = { ...parts, s };
7813
- setParts(next);
7814
- emit(next);
7835
+ tryUpdate(next);
7815
7836
  },
7816
7837
  scrollRef: secondScrollRef,
7817
7838
  itemHeight,
@@ -7864,8 +7885,7 @@ function TimePicker({
7864
7885
  if (pVal === "AM" && hour >= 12) hour -= 12;
7865
7886
  if (pVal === "PM" && hour < 12) hour += 12;
7866
7887
  const next = { ...parts, p: pVal, h: hour };
7867
- setParts(next);
7868
- emit(next);
7888
+ tryUpdate(next);
7869
7889
  },
7870
7890
  children: [
7871
7891
  isSelected && /* @__PURE__ */ jsx31("div", { className: "absolute inset-0 bg-linear-to-tr from-white/20 to-transparent" }),