@underverse-ui/underverse 0.2.91 → 0.2.92

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
@@ -840,8 +840,10 @@ declare function TimePicker({ value, defaultValue, onChange, placeholder, disabl
840
840
  type SelectMode = "single" | "multiple" | "range";
841
841
  type Variant$3 = "default" | "bordered" | "card" | "minimal";
842
842
  type DisplayMode = "month" | "week" | "year";
843
+ type CellMode = "compact" | "events";
843
844
  interface CalendarEvent {
844
845
  date: Date | string;
846
+ id?: string | number;
845
847
  title?: string;
846
848
  color?: string;
847
849
  badge?: string;
@@ -906,8 +908,19 @@ interface CalendarProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "de
906
908
  showEventBadges?: boolean;
907
909
  /** Highlight weekends */
908
910
  highlightWeekends?: boolean;
911
+ /** Render mode for each day cell (compact dots vs large cell with event list) */
912
+ cellMode?: CellMode;
913
+ /** Max events shown per day (events cell mode) */
914
+ maxEventsPerDay?: number;
915
+ /** Fired when clicking an event in a day cell (events cell mode) */
916
+ onEventClick?: (event: CalendarEvent, date: Date) => void;
917
+ /** Customize event rendering (events cell mode) */
918
+ renderEvent?: (args: {
919
+ event: CalendarEvent;
920
+ date: Date;
921
+ }) => React$1.ReactNode;
909
922
  }
910
- declare function Calendar({ month, defaultMonth, onMonthChange, value, defaultValue, onSelect, selectMode, weekStartsOn, showWeekdays, showHeader, size, variant, events, renderDay, labels, className, display, months, showToday, showClear, minDate, maxDate, disabledDates, dense, animate, showEventBadges, highlightWeekends, ...rest }: CalendarProps): react_jsx_runtime.JSX.Element;
923
+ declare function Calendar({ month, defaultMonth, onMonthChange, value, defaultValue, onSelect, selectMode, weekStartsOn, showWeekdays, showHeader, size, variant, events, renderDay, labels, className, display, months, showToday, showClear, minDate, maxDate, disabledDates, dense, animate, showEventBadges, highlightWeekends, cellMode, maxEventsPerDay, onEventClick, renderEvent, ...rest }: CalendarProps): react_jsx_runtime.JSX.Element;
911
924
 
912
925
  type CalendarTimelineView = "month" | "week" | "day";
913
926
  type CalendarTimelineDateInput = Date | string | number;
package/dist/index.d.ts CHANGED
@@ -840,8 +840,10 @@ declare function TimePicker({ value, defaultValue, onChange, placeholder, disabl
840
840
  type SelectMode = "single" | "multiple" | "range";
841
841
  type Variant$3 = "default" | "bordered" | "card" | "minimal";
842
842
  type DisplayMode = "month" | "week" | "year";
843
+ type CellMode = "compact" | "events";
843
844
  interface CalendarEvent {
844
845
  date: Date | string;
846
+ id?: string | number;
845
847
  title?: string;
846
848
  color?: string;
847
849
  badge?: string;
@@ -906,8 +908,19 @@ interface CalendarProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "de
906
908
  showEventBadges?: boolean;
907
909
  /** Highlight weekends */
908
910
  highlightWeekends?: boolean;
911
+ /** Render mode for each day cell (compact dots vs large cell with event list) */
912
+ cellMode?: CellMode;
913
+ /** Max events shown per day (events cell mode) */
914
+ maxEventsPerDay?: number;
915
+ /** Fired when clicking an event in a day cell (events cell mode) */
916
+ onEventClick?: (event: CalendarEvent, date: Date) => void;
917
+ /** Customize event rendering (events cell mode) */
918
+ renderEvent?: (args: {
919
+ event: CalendarEvent;
920
+ date: Date;
921
+ }) => React$1.ReactNode;
909
922
  }
910
- declare function Calendar({ month, defaultMonth, onMonthChange, value, defaultValue, onSelect, selectMode, weekStartsOn, showWeekdays, showHeader, size, variant, events, renderDay, labels, className, display, months, showToday, showClear, minDate, maxDate, disabledDates, dense, animate, showEventBadges, highlightWeekends, ...rest }: CalendarProps): react_jsx_runtime.JSX.Element;
923
+ declare function Calendar({ month, defaultMonth, onMonthChange, value, defaultValue, onSelect, selectMode, weekStartsOn, showWeekdays, showHeader, size, variant, events, renderDay, labels, className, display, months, showToday, showClear, minDate, maxDate, disabledDates, dense, animate, showEventBadges, highlightWeekends, cellMode, maxEventsPerDay, onEventClick, renderEvent, ...rest }: CalendarProps): react_jsx_runtime.JSX.Element;
911
924
 
912
925
  type CalendarTimelineView = "month" | "week" | "day";
913
926
  type CalendarTimelineDateInput = Date | string | number;
package/dist/index.js CHANGED
@@ -6421,6 +6421,10 @@ function Calendar2({
6421
6421
  animate = false,
6422
6422
  showEventBadges = false,
6423
6423
  highlightWeekends = false,
6424
+ cellMode = "compact",
6425
+ maxEventsPerDay = 3,
6426
+ onEventClick,
6427
+ renderEvent,
6424
6428
  ...rest
6425
6429
  }) {
6426
6430
  const isControlledMonth = month != null;
@@ -6513,6 +6517,13 @@ function Calendar2({
6513
6517
  xl: { day: "w-14 h-14 text-lg", grid: dense ? "gap-2" : "gap-2.5", head: "text-base", header: "text-lg" }
6514
6518
  };
6515
6519
  const sz = SIZE_STYLES3[size];
6520
+ const CELL_EVENT_STYLES = {
6521
+ sm: { cell: dense ? "min-h-20 p-1.5" : "min-h-24 p-2", day: "text-[12px]" },
6522
+ md: { cell: dense ? "min-h-28 p-2" : "min-h-32 p-2.5", day: "text-sm" },
6523
+ lg: { cell: dense ? "min-h-36 p-2.5" : "min-h-40 p-3", day: "text-base" },
6524
+ xl: { cell: dense ? "min-h-44 p-3" : "min-h-52 p-3.5", day: "text-lg" }
6525
+ };
6526
+ const cellSz = CELL_EVENT_STYLES[size];
6516
6527
  const VARIANT_STYLES2 = {
6517
6528
  default: "border border-border rounded-2xl bg-card",
6518
6529
  bordered: "border-2 border-border rounded-2xl bg-card shadow-sm",
@@ -6536,6 +6547,84 @@ function Calendar2({
6536
6547
  const k = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
6537
6548
  const dayEvents = byDay.get(k) || [];
6538
6549
  const disabled = isDateDisabled(d);
6550
+ const isWeekend = d.getDay() === 0 || d.getDay() === 6;
6551
+ const customDay = renderDay?.({ date: d, isCurrentMonth: inMonth, isToday: isToday2, isSelected: selectedDay, events: dayEvents });
6552
+ if (customDay) return /* @__PURE__ */ jsx30(React24.Fragment, { children: customDay }, `${monthLabel}-${idx}`);
6553
+ if (cellMode === "events") {
6554
+ const limit = Math.max(0, maxEventsPerDay);
6555
+ const visibleEvents = dayEvents.slice(0, limit);
6556
+ const hiddenCount = Math.max(0, dayEvents.length - visibleEvents.length);
6557
+ return /* @__PURE__ */ jsxs25(
6558
+ "div",
6559
+ {
6560
+ className: cn(
6561
+ "rounded-xl border border-border/50 bg-background/40 overflow-hidden",
6562
+ "transition-colors duration-150",
6563
+ animate && "will-change-transform",
6564
+ cellSz.cell,
6565
+ !inMonth && "opacity-60",
6566
+ disabled && "opacity-40",
6567
+ highlightWeekends && isWeekend && "bg-accent/10",
6568
+ isToday2 && !selectedDay && "ring-1 ring-primary/40",
6569
+ selectedDay && "border-primary/50 bg-primary/10"
6570
+ ),
6571
+ children: [
6572
+ /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between gap-2", children: [
6573
+ /* @__PURE__ */ jsx30(
6574
+ "button",
6575
+ {
6576
+ type: "button",
6577
+ onClick: () => !disabled && handleClickDay(d),
6578
+ disabled,
6579
+ className: cn(
6580
+ "inline-flex items-center justify-center rounded-lg px-2 py-1",
6581
+ "transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
6582
+ cellSz.day,
6583
+ selectedDay ? "bg-primary text-primary-foreground" : "hover:bg-accent hover:text-accent-foreground",
6584
+ disabled && "cursor-not-allowed hover:bg-transparent"
6585
+ ),
6586
+ title: d.toDateString(),
6587
+ children: d.getDate()
6588
+ }
6589
+ ),
6590
+ dayEvents.length > 0 && /* @__PURE__ */ jsx30("span", { className: "text-[11px] text-muted-foreground tabular-nums", children: dayEvents.length })
6591
+ ] }),
6592
+ /* @__PURE__ */ jsxs25("div", { className: cn("mt-2 space-y-1", dense ? "mt-1.5" : "mt-2"), children: [
6593
+ visibleEvents.map((e, i) => {
6594
+ const key = e.id ?? `${k}-${i}`;
6595
+ const node = renderEvent?.({ event: e, date: d });
6596
+ if (node) return /* @__PURE__ */ jsx30("div", { children: node }, String(key));
6597
+ return /* @__PURE__ */ jsxs25(
6598
+ "button",
6599
+ {
6600
+ type: "button",
6601
+ onClick: () => onEventClick?.(e, d),
6602
+ className: cn(
6603
+ "w-full text-left rounded-lg px-2 py-1",
6604
+ "transition-colors duration-150 hover:bg-accent/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
6605
+ "text-xs flex items-center gap-2"
6606
+ ),
6607
+ title: e.title,
6608
+ children: [
6609
+ /* @__PURE__ */ jsx30("span", { className: "h-2 w-2 rounded-full shrink-0", style: { backgroundColor: e.color || "hsl(var(--primary))" } }),
6610
+ /* @__PURE__ */ jsx30("span", { className: "truncate flex-1", children: e.title ?? "Event" }),
6611
+ showEventBadges && e.badge && /* @__PURE__ */ jsx30("span", { className: "shrink-0 rounded-full bg-muted px-2 py-0.5 text-[10px] text-muted-foreground", children: e.badge })
6612
+ ]
6613
+ },
6614
+ String(key)
6615
+ );
6616
+ }),
6617
+ hiddenCount > 0 && /* @__PURE__ */ jsxs25("div", { className: "px-2 text-[11px] text-muted-foreground", children: [
6618
+ "+",
6619
+ hiddenCount,
6620
+ " more"
6621
+ ] })
6622
+ ] })
6623
+ ]
6624
+ },
6625
+ `${monthLabel}-${idx}`
6626
+ );
6627
+ }
6539
6628
  return /* @__PURE__ */ jsxs25(
6540
6629
  "button",
6541
6630
  {
@@ -6546,6 +6635,7 @@ function Calendar2({
6546
6635
  sz.day,
6547
6636
  !inMonth && "text-muted-foreground/60",
6548
6637
  disabled && "opacity-40 cursor-not-allowed",
6638
+ highlightWeekends && isWeekend && "bg-accent/10",
6549
6639
  isToday2 && !selectedDay && "ring-1 ring-primary/50",
6550
6640
  selectedDay && "bg-primary text-primary-foreground hover:bg-primary/90",
6551
6641
  !selectedDay && "hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
@@ -6553,7 +6643,14 @@ function Calendar2({
6553
6643
  title: d.toDateString(),
6554
6644
  children: [
6555
6645
  d.getDate(),
6556
- dayEvents.length > 0 && /* @__PURE__ */ jsx30("span", { className: "absolute -bottom-1 inline-flex gap-0.5", children: dayEvents.slice(0, 3).map((e, i) => /* @__PURE__ */ jsx30("span", { className: "h-1.5 w-1.5 rounded-full", style: { backgroundColor: e.color || "hsl(var(--primary))" } }, i)) })
6646
+ dayEvents.length > 0 && /* @__PURE__ */ jsx30("span", { className: "absolute -bottom-1 inline-flex gap-0.5", children: dayEvents.slice(0, 3).map((e, i) => /* @__PURE__ */ jsx30(
6647
+ "span",
6648
+ {
6649
+ className: "h-1.5 w-1.5 rounded-full",
6650
+ style: { backgroundColor: e.color || "hsl(var(--primary))" }
6651
+ },
6652
+ String(e.id ?? i)
6653
+ )) })
6557
6654
  ]
6558
6655
  },
6559
6656
  `${monthLabel}-${idx}`
@@ -6616,6 +6713,82 @@ function Calendar2({
6616
6713
  const k = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
6617
6714
  const dayEvents = byDay.get(k) || [];
6618
6715
  const disabled = isDateDisabled(d);
6716
+ const isWeekend = d.getDay() === 0 || d.getDay() === 6;
6717
+ const customDay = renderDay?.({ date: d, isCurrentMonth: inMonth, isToday: isToday2, isSelected: selectedDay, events: dayEvents });
6718
+ if (customDay) return /* @__PURE__ */ jsx30(React24.Fragment, { children: customDay }, `wd-${idx}`);
6719
+ if (cellMode === "events") {
6720
+ const limit = Math.max(0, maxEventsPerDay);
6721
+ const visibleEvents = dayEvents.slice(0, limit);
6722
+ const hiddenCount = Math.max(0, dayEvents.length - visibleEvents.length);
6723
+ return /* @__PURE__ */ jsxs25(
6724
+ "div",
6725
+ {
6726
+ className: cn(
6727
+ "rounded-xl border border-border/50 bg-background/40 overflow-hidden",
6728
+ "transition-colors duration-150",
6729
+ cellSz.cell,
6730
+ disabled && "opacity-40",
6731
+ highlightWeekends && isWeekend && "bg-accent/10",
6732
+ isToday2 && !selectedDay && "ring-1 ring-primary/40",
6733
+ selectedDay && "border-primary/50 bg-primary/10"
6734
+ ),
6735
+ children: [
6736
+ /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between gap-2", children: [
6737
+ /* @__PURE__ */ jsx30(
6738
+ "button",
6739
+ {
6740
+ type: "button",
6741
+ onClick: () => !disabled && handleClickDay(d),
6742
+ disabled,
6743
+ className: cn(
6744
+ "inline-flex items-center justify-center rounded-lg px-2 py-1",
6745
+ "transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
6746
+ cellSz.day,
6747
+ selectedDay ? "bg-primary text-primary-foreground" : "hover:bg-accent hover:text-accent-foreground",
6748
+ disabled && "cursor-not-allowed hover:bg-transparent"
6749
+ ),
6750
+ title: d.toDateString(),
6751
+ children: d.getDate()
6752
+ }
6753
+ ),
6754
+ dayEvents.length > 0 && /* @__PURE__ */ jsx30("span", { className: "text-[11px] text-muted-foreground tabular-nums", children: dayEvents.length })
6755
+ ] }),
6756
+ /* @__PURE__ */ jsxs25("div", { className: cn("mt-2 space-y-1", dense ? "mt-1.5" : "mt-2"), children: [
6757
+ visibleEvents.map((e, i) => {
6758
+ const key = e.id ?? `${k}-${i}`;
6759
+ const node = renderEvent?.({ event: e, date: d });
6760
+ if (node) return /* @__PURE__ */ jsx30("div", { children: node }, String(key));
6761
+ return /* @__PURE__ */ jsxs25(
6762
+ "button",
6763
+ {
6764
+ type: "button",
6765
+ onClick: () => onEventClick?.(e, d),
6766
+ className: cn(
6767
+ "w-full text-left rounded-lg px-2 py-1",
6768
+ "transition-colors duration-150 hover:bg-accent/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
6769
+ "text-xs flex items-center gap-2"
6770
+ ),
6771
+ title: e.title,
6772
+ children: [
6773
+ /* @__PURE__ */ jsx30("span", { className: "h-2 w-2 rounded-full shrink-0", style: { backgroundColor: e.color || "hsl(var(--primary))" } }),
6774
+ /* @__PURE__ */ jsx30("span", { className: "truncate flex-1", children: e.title ?? "Event" }),
6775
+ showEventBadges && e.badge && /* @__PURE__ */ jsx30("span", { className: "shrink-0 rounded-full bg-muted px-2 py-0.5 text-[10px] text-muted-foreground", children: e.badge })
6776
+ ]
6777
+ },
6778
+ String(key)
6779
+ );
6780
+ }),
6781
+ hiddenCount > 0 && /* @__PURE__ */ jsxs25("div", { className: "px-2 text-[11px] text-muted-foreground", children: [
6782
+ "+",
6783
+ hiddenCount,
6784
+ " more"
6785
+ ] })
6786
+ ] })
6787
+ ]
6788
+ },
6789
+ `wd-${idx}`
6790
+ );
6791
+ }
6619
6792
  return /* @__PURE__ */ jsxs25(
6620
6793
  "button",
6621
6794
  {
@@ -6625,6 +6798,7 @@ function Calendar2({
6625
6798
  "rounded-lg flex items-center justify-center relative cursor-pointer",
6626
6799
  sz.day,
6627
6800
  disabled && "opacity-40 cursor-not-allowed",
6801
+ highlightWeekends && isWeekend && "bg-accent/10",
6628
6802
  isToday2 && !selectedDay && "ring-1 ring-primary/50",
6629
6803
  selectedDay && "bg-primary text-primary-foreground hover:bg-primary/90",
6630
6804
  !selectedDay && "hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
@@ -6632,7 +6806,7 @@ function Calendar2({
6632
6806
  title: d.toDateString(),
6633
6807
  children: [
6634
6808
  d.getDate(),
6635
- dayEvents.length > 0 && /* @__PURE__ */ jsx30("span", { className: "absolute -bottom-1 inline-flex gap-0.5", children: dayEvents.slice(0, 3).map((e, i) => /* @__PURE__ */ jsx30("span", { className: "h-1.5 w-1.5 rounded-full", style: { backgroundColor: e.color || "hsl(var(--primary))" } }, i)) })
6809
+ dayEvents.length > 0 && /* @__PURE__ */ jsx30("span", { className: "absolute -bottom-1 inline-flex gap-0.5", children: dayEvents.slice(0, 3).map((e, i) => /* @__PURE__ */ jsx30("span", { className: "h-1.5 w-1.5 rounded-full", style: { backgroundColor: e.color || "hsl(var(--primary))" } }, String(e.id ?? i))) })
6636
6810
  ]
6637
6811
  },
6638
6812
  `wd-${idx}`