@underverse-ui/underverse 0.2.42 → 0.2.43

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.js CHANGED
@@ -4630,7 +4630,7 @@ var DropdownMenu_default = DropdownMenu;
4630
4630
 
4631
4631
  // ../../components/ui/Pagination.tsx
4632
4632
  import * as React21 from "react";
4633
- import { ChevronLeft, ChevronRight as ChevronRight2, MoreHorizontal as MoreHorizontal2, ChevronsLeft, ChevronsRight } from "lucide-react";
4633
+ import { ChevronLeft, ChevronRight as ChevronRight2, ChevronsLeft, ChevronsRight } from "lucide-react";
4634
4634
 
4635
4635
  // ../../components/ui/Combobox.tsx
4636
4636
  import * as React20 from "react";
@@ -4946,13 +4946,11 @@ var Pagination = ({
4946
4946
  onChange,
4947
4947
  className,
4948
4948
  size = "md",
4949
- variant = "outline",
4950
4949
  showFirstLast = true,
4951
4950
  showPrevNext = true,
4952
4951
  showPageNumbers = true,
4953
4952
  showInfo = false,
4954
4953
  disabled = false,
4955
- alignment = "left",
4956
4954
  pageSize,
4957
4955
  pageSizeOptions,
4958
4956
  onPageSizeChange,
@@ -4960,35 +4958,6 @@ var Pagination = ({
4960
4958
  labels
4961
4959
  }) => {
4962
4960
  const t = useTranslations("Pagination");
4963
- const getTextAlignmentClass = (align) => {
4964
- switch (align) {
4965
- case "left":
4966
- return "text-left";
4967
- case "center":
4968
- return "text-center";
4969
- case "right":
4970
- return "text-right";
4971
- }
4972
- };
4973
- const textAlignmentClass = getTextAlignmentClass(alignment);
4974
- const createPageArray = () => {
4975
- const delta = 2;
4976
- const range = [];
4977
- const left = Math.max(2, page - delta);
4978
- const right = Math.min(totalPages - 1, page + delta);
4979
- range.push(1);
4980
- if (left > 2) range.push("...");
4981
- for (let i = left; i <= right; i++) {
4982
- range.push(i);
4983
- }
4984
- if (right < totalPages - 1) range.push("...");
4985
- if (totalPages > 1) range.push(totalPages);
4986
- return range;
4987
- };
4988
- const getButtonVariant = (isActive) => {
4989
- if (isActive) return "primary";
4990
- return variant === "default" ? "default" : variant;
4991
- };
4992
4961
  React21.useEffect(() => {
4993
4962
  if (disabled) return;
4994
4963
  const handleKey = (e) => {
@@ -5022,116 +4991,135 @@ var Pagination = ({
5022
4991
  }
5023
4992
  };
5024
4993
  if (totalPages <= 1) return null;
5025
- return /* @__PURE__ */ jsxs23("nav", { className: cn("flex flex-col gap-4", className), "aria-label": labels?.navigationLabel || t("navigationLabel"), children: [
5026
- showInfo && totalItems && /* @__PURE__ */ jsx26("div", { className: cn("text-sm text-muted-foreground", textAlignmentClass), children: labels?.showingResults ? labels.showingResults({ startItem: startItem || 0, endItem: endItem || 0, totalItems }) : t("showingResults", { startItem: startItem || 0, endItem: endItem || 0, totalItems }) }),
5027
- /* @__PURE__ */ jsxs23(
5028
- "div",
5029
- {
5030
- className: cn("flex items-center justify-between", {
5031
- "flex-row-reverse": alignment === "right" || alignment === "center"
5032
- }),
5033
- children: [
5034
- /* @__PURE__ */ jsxs23("div", { className: cn("flex items-center gap-1"), children: [
5035
- showFirstLast && /* @__PURE__ */ jsx26(
5036
- Button_default,
5037
- {
5038
- variant: getButtonVariant(false),
5039
- size,
5040
- icon: ChevronsLeft,
5041
- onClick: () => onChange(1),
5042
- disabled: disabled || page === 1,
5043
- className: "hidden sm:flex",
5044
- title: labels?.firstPage || t("firstPage"),
5045
- "aria-label": labels?.firstPage || t("firstPage"),
5046
- "aria-disabled": disabled || page === 1
5047
- }
5048
- ),
5049
- showPrevNext && /* @__PURE__ */ jsx26(
5050
- Button_default,
5051
- {
5052
- variant: getButtonVariant(false),
5053
- size,
5054
- icon: ChevronLeft,
5055
- onClick: () => onChange(Math.max(1, page - 1)),
5056
- disabled: disabled || page === 1,
5057
- title: labels?.previousPage || t("previousPage"),
5058
- "aria-label": labels?.previousPage || t("previousPage"),
5059
- "aria-disabled": disabled || page === 1,
5060
- children: /* @__PURE__ */ jsx26("span", { className: "hidden sm:inline", children: labels?.previous || t("previous") })
5061
- }
5062
- ),
5063
- showPageNumbers && createPageArray().map((p, i) => {
5064
- if (p === "...") {
5065
- return /* @__PURE__ */ jsx26(Button_default, { variant: "ghost", size, disabled: true, icon: MoreHorizontal2, className: "cursor-default" }, i);
5066
- }
5067
- const pageNumber = p;
5068
- const isActive = page === pageNumber;
5069
- return /* @__PURE__ */ jsx26(
5070
- Button_default,
5071
- {
5072
- variant: getButtonVariant(isActive),
5073
- size,
5074
- onClick: () => onChange(pageNumber),
5075
- disabled,
5076
- className: cn("min-w-10", isActive && "font-semibold"),
5077
- "aria-label": labels?.pageNumber ? labels.pageNumber(pageNumber) : t("pageNumber", { page: pageNumber }),
5078
- "aria-current": isActive ? "page" : void 0,
5079
- children: pageNumber
5080
- },
5081
- i
5082
- );
5083
- }),
5084
- showPrevNext && /* @__PURE__ */ jsx26(
5085
- Button_default,
5086
- {
5087
- variant: getButtonVariant(false),
5088
- size,
5089
- iconRight: ChevronRight2,
5090
- onClick: () => onChange(Math.min(totalPages, page + 1)),
5091
- disabled: disabled || page === totalPages,
5092
- title: labels?.nextPage || t("nextPage"),
5093
- "aria-label": labels?.nextPage || t("nextPage"),
5094
- "aria-disabled": disabled || page === totalPages,
5095
- children: /* @__PURE__ */ jsx26("span", { className: "hidden sm:inline", children: labels?.next || t("next") })
5096
- }
5097
- ),
5098
- showFirstLast && /* @__PURE__ */ jsx26(
5099
- Button_default,
4994
+ const createCompactPageArray = () => {
4995
+ const pages = [];
4996
+ if (totalPages <= 5) {
4997
+ for (let i = 1; i <= totalPages; i++) pages.push(i);
4998
+ } else {
4999
+ pages.push(1);
5000
+ if (page > 3) pages.push("...");
5001
+ const start = Math.max(2, page - 1);
5002
+ const end = Math.min(totalPages - 1, page + 1);
5003
+ for (let i = start; i <= end; i++) pages.push(i);
5004
+ if (page < totalPages - 2) pages.push("...");
5005
+ pages.push(totalPages);
5006
+ }
5007
+ return pages;
5008
+ };
5009
+ const sizeClasses2 = {
5010
+ sm: { btn: "h-7 w-7", text: "text-xs", page: "h-7 min-w-7 px-1.5" },
5011
+ md: { btn: "h-8 w-8", text: "text-sm", page: "h-8 min-w-8 px-2" },
5012
+ lg: { btn: "h-9 w-9", text: "text-base", page: "h-9 min-w-9 px-2.5" }
5013
+ };
5014
+ const sizeClass = sizeClasses2[size];
5015
+ return /* @__PURE__ */ jsxs23(
5016
+ "nav",
5017
+ {
5018
+ className: cn("flex items-center justify-between gap-2", sizeClass.text, "text-muted-foreground", className),
5019
+ "aria-label": labels?.navigationLabel || t("navigationLabel"),
5020
+ children: [
5021
+ showInfo && totalItems && startItem && endItem ? /* @__PURE__ */ jsxs23("div", { className: "tabular-nums shrink-0", children: [
5022
+ startItem,
5023
+ "-",
5024
+ endItem,
5025
+ "/",
5026
+ totalItems
5027
+ ] }) : /* @__PURE__ */ jsx26("div", {}),
5028
+ /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-0.5", children: [
5029
+ showFirstLast && /* @__PURE__ */ jsx26(
5030
+ "button",
5031
+ {
5032
+ onClick: () => onChange(1),
5033
+ disabled: disabled || page === 1,
5034
+ className: cn(
5035
+ sizeClass.btn,
5036
+ "p-0 rounded transition-colors hidden sm:flex items-center justify-center",
5037
+ disabled || page === 1 ? "opacity-40 cursor-not-allowed" : "hover:bg-accent hover:text-accent-foreground"
5038
+ ),
5039
+ title: labels?.firstPage || t("firstPage"),
5040
+ "aria-label": labels?.firstPage || t("firstPage"),
5041
+ children: /* @__PURE__ */ jsx26(ChevronsLeft, { className: "h-4 w-4" })
5042
+ }
5043
+ ),
5044
+ showPrevNext && /* @__PURE__ */ jsx26(
5045
+ "button",
5046
+ {
5047
+ onClick: () => onChange(Math.max(1, page - 1)),
5048
+ disabled: disabled || page === 1,
5049
+ className: cn(
5050
+ sizeClass.btn,
5051
+ "p-0 rounded transition-colors flex items-center justify-center",
5052
+ disabled || page === 1 ? "opacity-40 cursor-not-allowed" : "hover:bg-accent hover:text-accent-foreground"
5053
+ ),
5054
+ title: labels?.previousPage || t("previousPage"),
5055
+ "aria-label": labels?.previousPage || t("previousPage"),
5056
+ children: /* @__PURE__ */ jsx26(ChevronLeft, { className: "h-4 w-4" })
5057
+ }
5058
+ ),
5059
+ showPageNumbers && createCompactPageArray().map(
5060
+ (p, i) => p === "..." ? /* @__PURE__ */ jsx26("span", { className: "px-1 text-muted-foreground/60", children: "\u2026" }, `dots-${i}`) : /* @__PURE__ */ jsx26(
5061
+ "button",
5100
5062
  {
5101
- variant: getButtonVariant(false),
5102
- size,
5103
- icon: ChevronsRight,
5104
- onClick: () => onChange(totalPages),
5105
- disabled: disabled || page === totalPages,
5106
- className: "hidden sm:flex",
5107
- title: labels?.lastPage || t("lastPage"),
5108
- "aria-label": labels?.lastPage || t("lastPage"),
5109
- "aria-disabled": disabled || page === totalPages
5110
- }
5063
+ onClick: () => onChange(p),
5064
+ disabled,
5065
+ className: cn(
5066
+ sizeClass.page,
5067
+ "rounded font-medium transition-colors",
5068
+ page === p ? "bg-primary text-primary-foreground" : "hover:bg-accent hover:text-accent-foreground",
5069
+ disabled && "opacity-40 cursor-not-allowed"
5070
+ ),
5071
+ "aria-label": labels?.pageNumber ? labels.pageNumber(p) : t("pageNumber", { page: p }),
5072
+ "aria-current": page === p ? "page" : void 0,
5073
+ children: p
5074
+ },
5075
+ p
5111
5076
  )
5112
- ] }),
5113
- pageSizeOptions && onPageSizeChange && /* @__PURE__ */ jsxs23("div", { className: cn("flex items-center gap-2 text-sm"), children: [
5114
- /* @__PURE__ */ jsxs23("span", { className: "text-muted-foreground", children: [
5115
- labels?.itemsPerPage || t("itemsPerPage"),
5116
- ":"
5117
- ] }),
5118
- /* @__PURE__ */ jsx26("div", { className: "w-20", children: /* @__PURE__ */ jsx26(
5119
- Combobox,
5120
- {
5121
- options: pageSizeOptionsStrings,
5122
- value: pageSize?.toString() || "10",
5123
- onChange: handlePageSizeChange,
5124
- placeholder: "10",
5125
- searchPlaceholder: labels?.search || t("search"),
5126
- emptyText: labels?.noOptions || t("noOptions"),
5127
- disabled
5128
- }
5129
- ) })
5130
- ] })
5131
- ]
5132
- }
5133
- )
5134
- ] });
5077
+ ),
5078
+ showPrevNext && /* @__PURE__ */ jsx26(
5079
+ "button",
5080
+ {
5081
+ onClick: () => onChange(Math.min(totalPages, page + 1)),
5082
+ disabled: disabled || page === totalPages,
5083
+ className: cn(
5084
+ sizeClass.btn,
5085
+ "p-0 rounded transition-colors flex items-center justify-center",
5086
+ disabled || page === totalPages ? "opacity-40 cursor-not-allowed" : "hover:bg-accent hover:text-accent-foreground"
5087
+ ),
5088
+ title: labels?.nextPage || t("nextPage"),
5089
+ "aria-label": labels?.nextPage || t("nextPage"),
5090
+ children: /* @__PURE__ */ jsx26(ChevronRight2, { className: "h-4 w-4" })
5091
+ }
5092
+ ),
5093
+ showFirstLast && /* @__PURE__ */ jsx26(
5094
+ "button",
5095
+ {
5096
+ onClick: () => onChange(totalPages),
5097
+ disabled: disabled || page === totalPages,
5098
+ className: cn(
5099
+ sizeClass.btn,
5100
+ "p-0 rounded transition-colors hidden sm:flex items-center justify-center",
5101
+ disabled || page === totalPages ? "opacity-40 cursor-not-allowed" : "hover:bg-accent hover:text-accent-foreground"
5102
+ ),
5103
+ title: labels?.lastPage || t("lastPage"),
5104
+ "aria-label": labels?.lastPage || t("lastPage"),
5105
+ children: /* @__PURE__ */ jsx26(ChevronsRight, { className: "h-4 w-4" })
5106
+ }
5107
+ )
5108
+ ] }),
5109
+ pageSizeOptions && onPageSizeChange ? /* @__PURE__ */ jsx26(
5110
+ Combobox,
5111
+ {
5112
+ options: pageSizeOptionsStrings,
5113
+ value: pageSize?.toString() || "10",
5114
+ onChange: handlePageSizeChange,
5115
+ size: "sm",
5116
+ className: "w-14",
5117
+ disabled
5118
+ }
5119
+ ) : /* @__PURE__ */ jsx26("div", {})
5120
+ ]
5121
+ }
5122
+ );
5135
5123
  };
5136
5124
  var SimplePagination = ({
5137
5125
  page,
@@ -5139,103 +5127,128 @@ var SimplePagination = ({
5139
5127
  onChange,
5140
5128
  className,
5141
5129
  size = "md",
5142
- variant = "outline",
5143
5130
  disabled = false,
5144
5131
  showInfo = false,
5145
5132
  totalItems,
5146
5133
  pageSize = 10
5147
5134
  }) => {
5148
5135
  if (totalPages <= 1) return null;
5149
- return /* @__PURE__ */ jsxs23("div", { className: cn("flex flex-col gap-2", className), children: [
5150
- showInfo && totalItems && /* @__PURE__ */ jsxs23("div", { className: "text-sm text-muted-foreground text-center", children: [
5151
- "Page ",
5152
- page,
5153
- " of ",
5154
- totalPages,
5155
- " (",
5156
- totalItems,
5157
- " total items)"
5158
- ] }),
5159
- /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between", children: [
5160
- /* @__PURE__ */ jsx26(Button_default, { variant, size, icon: ChevronLeft, onClick: () => onChange(Math.max(1, page - 1)), disabled: disabled || page === 1, children: "Previous" }),
5161
- /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
5162
- /* @__PURE__ */ jsx26("span", { children: "Page" }),
5163
- /* @__PURE__ */ jsx26("span", { className: "font-medium text-foreground", children: page }),
5164
- /* @__PURE__ */ jsx26("span", { children: "of" }),
5165
- /* @__PURE__ */ jsx26("span", { className: "font-medium text-foreground", children: totalPages })
5136
+ const sizeClasses2 = {
5137
+ sm: { btn: "h-7 w-7", text: "text-xs" },
5138
+ md: { btn: "h-8 w-8", text: "text-sm" },
5139
+ lg: { btn: "h-9 w-9", text: "text-base" }
5140
+ };
5141
+ const sizeClass = sizeClasses2[size];
5142
+ const startItem = totalItems ? (page - 1) * pageSize + 1 : null;
5143
+ const endItem = totalItems ? Math.min(page * pageSize, totalItems) : null;
5144
+ return /* @__PURE__ */ jsxs23("div", { className: cn("flex items-center justify-between gap-2", sizeClass.text, "text-muted-foreground", className), children: [
5145
+ showInfo && totalItems && startItem && endItem ? /* @__PURE__ */ jsxs23("div", { className: "tabular-nums", children: [
5146
+ startItem,
5147
+ "-",
5148
+ endItem,
5149
+ "/",
5150
+ totalItems
5151
+ ] }) : /* @__PURE__ */ jsx26("div", {}),
5152
+ /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-0.5", children: [
5153
+ /* @__PURE__ */ jsx26(
5154
+ "button",
5155
+ {
5156
+ onClick: () => onChange(Math.max(1, page - 1)),
5157
+ disabled: disabled || page === 1,
5158
+ className: cn(
5159
+ sizeClass.btn,
5160
+ "p-0 rounded transition-colors flex items-center justify-center",
5161
+ disabled || page === 1 ? "opacity-40 cursor-not-allowed" : "hover:bg-accent hover:text-accent-foreground"
5162
+ ),
5163
+ "aria-label": "Previous page",
5164
+ children: /* @__PURE__ */ jsx26(ChevronLeft, { className: "h-4 w-4" })
5165
+ }
5166
+ ),
5167
+ /* @__PURE__ */ jsxs23("span", { className: "px-2 tabular-nums font-medium text-foreground", children: [
5168
+ page,
5169
+ "/",
5170
+ totalPages
5166
5171
  ] }),
5167
5172
  /* @__PURE__ */ jsx26(
5168
- Button_default,
5173
+ "button",
5169
5174
  {
5170
- variant,
5171
- size,
5172
- iconRight: ChevronRight2,
5173
5175
  onClick: () => onChange(Math.min(totalPages, page + 1)),
5174
5176
  disabled: disabled || page === totalPages,
5175
- children: "Next"
5177
+ className: cn(
5178
+ sizeClass.btn,
5179
+ "p-0 rounded transition-colors flex items-center justify-center",
5180
+ disabled || page === totalPages ? "opacity-40 cursor-not-allowed" : "hover:bg-accent hover:text-accent-foreground"
5181
+ ),
5182
+ "aria-label": "Next page",
5183
+ children: /* @__PURE__ */ jsx26(ChevronRight2, { className: "h-4 w-4" })
5176
5184
  }
5177
5185
  )
5178
- ] })
5186
+ ] }),
5187
+ /* @__PURE__ */ jsx26("div", {})
5179
5188
  ] });
5180
5189
  };
5181
- var CompactPagination = ({
5182
- page,
5183
- totalPages,
5184
- onChange,
5185
- className,
5186
- variant = "outline",
5187
- disabled = false
5188
- }) => {
5190
+ var CompactPagination = ({ page, totalPages, onChange, className, disabled = false }) => {
5189
5191
  if (totalPages <= 1) return null;
5190
- return /* @__PURE__ */ jsxs23("nav", { className: cn("flex items-center gap-1", className), "aria-label": "Compact Pagination", children: [
5192
+ return /* @__PURE__ */ jsxs23("nav", { className: cn("flex items-center gap-0.5 text-xs text-muted-foreground", className), "aria-label": "Compact Pagination", children: [
5191
5193
  /* @__PURE__ */ jsx26(
5192
- Button_default,
5194
+ "button",
5193
5195
  {
5194
- variant,
5195
- size: "icon",
5196
- icon: ChevronsLeft,
5197
5196
  onClick: () => onChange(1),
5198
5197
  disabled: disabled || page === 1,
5198
+ className: cn(
5199
+ "h-6 w-6 p-0 rounded transition-colors flex items-center justify-center",
5200
+ disabled || page === 1 ? "opacity-40 cursor-not-allowed" : "hover:bg-accent hover:text-accent-foreground"
5201
+ ),
5199
5202
  title: "First page",
5200
- "aria-label": "First page"
5203
+ "aria-label": "First page",
5204
+ children: /* @__PURE__ */ jsx26(ChevronsLeft, { className: "h-3.5 w-3.5" })
5201
5205
  }
5202
5206
  ),
5203
5207
  /* @__PURE__ */ jsx26(
5204
- Button_default,
5208
+ "button",
5205
5209
  {
5206
- variant,
5207
- size: "icon",
5208
- icon: ChevronLeft,
5209
5210
  onClick: () => onChange(Math.max(1, page - 1)),
5210
5211
  disabled: disabled || page === 1,
5211
- title: "Previous page"
5212
+ className: cn(
5213
+ "h-6 w-6 p-0 rounded transition-colors flex items-center justify-center",
5214
+ disabled || page === 1 ? "opacity-40 cursor-not-allowed" : "hover:bg-accent hover:text-accent-foreground"
5215
+ ),
5216
+ title: "Previous page",
5217
+ "aria-label": "Previous page",
5218
+ children: /* @__PURE__ */ jsx26(ChevronLeft, { className: "h-3.5 w-3.5" })
5212
5219
  }
5213
5220
  ),
5214
- /* @__PURE__ */ jsxs23("div", { className: "px-2 py-1 text-sm text-muted-foreground min-w-16 text-center", children: [
5221
+ /* @__PURE__ */ jsxs23("span", { className: "px-1.5 tabular-nums", children: [
5215
5222
  page,
5216
- " / ",
5223
+ "/",
5217
5224
  totalPages
5218
5225
  ] }),
5219
5226
  /* @__PURE__ */ jsx26(
5220
- Button_default,
5227
+ "button",
5221
5228
  {
5222
- variant,
5223
- size: "icon",
5224
- icon: ChevronRight2,
5225
5229
  onClick: () => onChange(Math.min(totalPages, page + 1)),
5226
5230
  disabled: disabled || page === totalPages,
5227
- title: "Next page"
5231
+ className: cn(
5232
+ "h-6 w-6 p-0 rounded transition-colors flex items-center justify-center",
5233
+ disabled || page === totalPages ? "opacity-40 cursor-not-allowed" : "hover:bg-accent hover:text-accent-foreground"
5234
+ ),
5235
+ title: "Next page",
5236
+ "aria-label": "Next page",
5237
+ children: /* @__PURE__ */ jsx26(ChevronRight2, { className: "h-3.5 w-3.5" })
5228
5238
  }
5229
5239
  ),
5230
5240
  /* @__PURE__ */ jsx26(
5231
- Button_default,
5241
+ "button",
5232
5242
  {
5233
- variant,
5234
- size: "icon",
5235
- icon: ChevronsRight,
5236
5243
  onClick: () => onChange(totalPages),
5237
5244
  disabled: disabled || page === totalPages,
5238
- title: "Last page"
5245
+ className: cn(
5246
+ "h-6 w-6 p-0 rounded transition-colors flex items-center justify-center",
5247
+ disabled || page === totalPages ? "opacity-40 cursor-not-allowed" : "hover:bg-accent hover:text-accent-foreground"
5248
+ ),
5249
+ title: "Last page",
5250
+ "aria-label": "Last page",
5251
+ children: /* @__PURE__ */ jsx26(ChevronsRight, { className: "h-3.5 w-3.5" })
5239
5252
  }
5240
5253
  )
5241
5254
  ] });
@@ -5344,7 +5357,8 @@ var DatePicker = ({
5344
5357
  required,
5345
5358
  todayLabel,
5346
5359
  clearLabel,
5347
- weekdayLabels
5360
+ weekdayLabels,
5361
+ disablePastDates = false
5348
5362
  }) => {
5349
5363
  const t = useTranslations("DatePicker");
5350
5364
  const locale = useLocale();
@@ -5448,17 +5462,21 @@ var DatePicker = ({
5448
5462
  for (let i = 0; i < firstDayOfMonth; i++) {
5449
5463
  days.push(/* @__PURE__ */ jsx29("div", { className: "w-8 h-8" }, `empty-${i}`));
5450
5464
  }
5465
+ const today = /* @__PURE__ */ new Date();
5466
+ today.setHours(0, 0, 0, 0);
5451
5467
  for (let day = 1; day <= daysInMonth; day++) {
5452
5468
  const date = new Date(viewDate.getFullYear(), viewDate.getMonth(), day);
5453
5469
  const isSelected = value && date.getDate() === value.getDate() && date.getMonth() === value.getMonth() && date.getFullYear() === value.getFullYear();
5454
5470
  const isToday2 = date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
5471
+ const isPastDate = disablePastDates && date < today;
5455
5472
  const totalDaysFromStart = firstDayOfMonth + day - 1;
5456
5473
  const rowIndex = Math.floor(totalDaysFromStart / 7);
5457
5474
  days.push(
5458
5475
  /* @__PURE__ */ jsx29(
5459
5476
  "button",
5460
5477
  {
5461
- onClick: () => handleDateSelect(date),
5478
+ onClick: () => !isPastDate && handleDateSelect(date),
5479
+ disabled: isPastDate,
5462
5480
  style: {
5463
5481
  animationDelay: isOpen ? `${rowIndex * 50}ms` : "0ms"
5464
5482
  },
@@ -5466,7 +5484,8 @@ var DatePicker = ({
5466
5484
  size === "sm" ? "w-7 h-7 text-[12px]" : "w-8 h-8 text-sm",
5467
5485
  "datepicker-day rounded-md focus:outline-none",
5468
5486
  "transition-colors",
5469
- isSelected ? "bg-primary! text-primary-foreground font-bold ring-2 ring-primary-foreground/60 shadow-lg scale-105 z-10 hover:bg-primary! focus:bg-primary! focus:text-primary-foreground" : "hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
5487
+ isPastDate && "opacity-40 cursor-not-allowed text-muted-foreground",
5488
+ isSelected ? "bg-primary! text-primary-foreground font-bold ring-2 ring-primary-foreground/60 shadow-lg scale-105 z-10 hover:bg-primary! focus:bg-primary! focus:text-primary-foreground" : !isPastDate && "hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
5470
5489
  isToday2 && !isSelected && "bg-accent text-accent-foreground font-semibold"
5471
5490
  ),
5472
5491
  children: day
@@ -5617,7 +5636,7 @@ var DatePicker = ({
5617
5636
  isOpen && dropdownPosition && typeof window !== "undefined" && createPortal7(datePickerContent, document.body)
5618
5637
  ] });
5619
5638
  };
5620
- var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select date range...", className }) => {
5639
+ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select date range...", className, disablePastDates = false }) => {
5621
5640
  const locale = useLocale();
5622
5641
  const [isOpen, setIsOpen] = React23.useState(false);
5623
5642
  const [dropdownPosition, setDropdownPosition] = React23.useState(null);
@@ -5678,16 +5697,17 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
5678
5697
  const getDaysInMonth = (d) => new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
5679
5698
  const getFirstDayOfMonth = (d) => new Date(d.getFullYear(), d.getMonth(), 1).getDay();
5680
5699
  const handleSelect = (date) => {
5700
+ const localDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
5681
5701
  if (!tempStart || tempStart && tempEnd) {
5682
- setTempStart(date);
5702
+ setTempStart(localDate);
5683
5703
  setTempEnd(null);
5684
5704
  setHoveredDate(null);
5685
5705
  } else if (tempStart && !tempEnd) {
5686
- if (date < tempStart) {
5687
- setTempStart(date);
5706
+ if (localDate < tempStart) {
5707
+ setTempStart(localDate);
5688
5708
  } else {
5689
- setTempEnd(date);
5690
- onChange(tempStart, date);
5709
+ setTempEnd(localDate);
5710
+ onChange(tempStart, localDate);
5691
5711
  setIsOpen(false);
5692
5712
  }
5693
5713
  }
@@ -5696,9 +5716,12 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
5696
5716
  const nodes = [];
5697
5717
  const daysInMonth = getDaysInMonth(viewDate);
5698
5718
  const firstDay = getFirstDayOfMonth(viewDate);
5719
+ const today = /* @__PURE__ */ new Date();
5720
+ today.setHours(0, 0, 0, 0);
5699
5721
  for (let i = 0; i < firstDay; i++) nodes.push(/* @__PURE__ */ jsx29("div", { className: "w-8 h-8" }, `e-${i}`));
5700
5722
  for (let d = 1; d <= daysInMonth; d++) {
5701
5723
  const date = new Date(viewDate.getFullYear(), viewDate.getMonth(), d);
5724
+ const isPastDate = disablePastDates && date < today;
5702
5725
  const isSelectedStart = isSameDay2(date, tempStart);
5703
5726
  const isSelectedEnd = isSameDay2(date, tempEnd);
5704
5727
  const isHovering = hoveredDate && tempStart && !tempEnd;
@@ -5724,13 +5747,16 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
5724
5747
  /* @__PURE__ */ jsx29(
5725
5748
  "button",
5726
5749
  {
5727
- onClick: () => handleSelect(date),
5728
- onMouseEnter: () => tempStart && !tempEnd && setHoveredDate(date),
5750
+ onClick: () => !isPastDate && handleSelect(date),
5751
+ disabled: isPastDate,
5752
+ onMouseEnter: () => !isPastDate && tempStart && !tempEnd && setHoveredDate(date),
5729
5753
  onMouseLeave: () => tempStart && !tempEnd && setHoveredDate(null),
5730
5754
  className: cn(
5731
5755
  "w-8 h-8 text-sm transition-all duration-200 focus:outline-none relative font-medium",
5756
+ // Disabled/past date state
5757
+ isPastDate && "opacity-40 cursor-not-allowed text-muted-foreground",
5732
5758
  // Default state
5733
- !isInRange && !isRangeStart && !isRangeEnd && "hover:bg-accent hover:text-accent-foreground rounded-md",
5759
+ !isPastDate && !isInRange && !isRangeStart && !isRangeEnd && "hover:bg-accent hover:text-accent-foreground rounded-md",
5734
5760
  // Range selection styling - smooth continuous background
5735
5761
  isInRange && "bg-primary/15 text-foreground shadow-sm",
5736
5762
  (isRangeStart || isRangeEnd) && "bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm",
@@ -5740,8 +5766,8 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
5740
5766
  isRangeStart && isRangeEnd && "rounded-md",
5741
5767
  // Single day selection
5742
5768
  // Hover effects for range
5743
- isInRange && "hover:bg-primary/25",
5744
- "focus:bg-accent focus:text-accent-foreground focus:z-10 focus:shadow-md"
5769
+ isInRange && !isPastDate && "hover:bg-primary/25",
5770
+ !isPastDate && "focus:bg-accent focus:text-accent-foreground focus:z-10 focus:shadow-md"
5745
5771
  ),
5746
5772
  children: d
5747
5773
  },
@@ -12214,23 +12240,71 @@ function DataTable({
12214
12240
  ]
12215
12241
  }
12216
12242
  ) }),
12217
- totalItems > 0 && /* @__PURE__ */ jsx56("div", { className: "border-t bg-muted/30 p-4 rounded-b-md", children: /* @__PURE__ */ jsx56(
12218
- Pagination,
12219
- {
12220
- page: curPage,
12221
- totalPages: Math.ceil(totalItems / curPageSize),
12222
- onChange: (p) => setCurPage(p),
12223
- className: "",
12224
- showInfo: true,
12225
- totalItems,
12226
- pageSize: curPageSize,
12227
- pageSizeOptions,
12228
- onPageSizeChange: (s) => {
12229
- setCurPage(1);
12230
- setCurPageSize(s);
12243
+ totalItems > 0 && Math.ceil(totalItems / curPageSize) > 1 && /* @__PURE__ */ jsxs50("div", { className: "flex items-center justify-between gap-2 px-1 pt-3 text-xs text-muted-foreground", children: [
12244
+ /* @__PURE__ */ jsxs50("div", { className: "tabular-nums", children: [
12245
+ (curPage - 1) * curPageSize + 1,
12246
+ "-",
12247
+ Math.min(curPage * curPageSize, totalItems),
12248
+ "/",
12249
+ totalItems
12250
+ ] }),
12251
+ /* @__PURE__ */ jsxs50("div", { className: "flex items-center gap-0.5", children: [
12252
+ /* @__PURE__ */ jsx56(Button_default, { variant: "ghost", size: "sm", className: "h-7 w-7 p-0", onClick: () => setCurPage(Math.max(1, curPage - 1)), disabled: curPage === 1, children: /* @__PURE__ */ jsx56("svg", { className: "h-4 w-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx56("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) }) }),
12253
+ (() => {
12254
+ const totalPages = Math.ceil(totalItems / curPageSize);
12255
+ const pages = [];
12256
+ if (totalPages <= 5) {
12257
+ for (let i = 1; i <= totalPages; i++) pages.push(i);
12258
+ } else {
12259
+ pages.push(1);
12260
+ if (curPage > 3) pages.push("...");
12261
+ const start = Math.max(2, curPage - 1);
12262
+ const end = Math.min(totalPages - 1, curPage + 1);
12263
+ for (let i = start; i <= end; i++) pages.push(i);
12264
+ if (curPage < totalPages - 2) pages.push("...");
12265
+ pages.push(totalPages);
12266
+ }
12267
+ return pages.map(
12268
+ (p, i) => p === "..." ? /* @__PURE__ */ jsx56("span", { className: "px-1 text-muted-foreground/60", children: "\u2026" }, `dots-${i}`) : /* @__PURE__ */ jsx56(
12269
+ "button",
12270
+ {
12271
+ onClick: () => setCurPage(p),
12272
+ className: cn(
12273
+ "h-7 min-w-7 px-1.5 rounded text-xs font-medium transition-colors",
12274
+ curPage === p ? "bg-primary text-primary-foreground" : "hover:bg-accent hover:text-accent-foreground"
12275
+ ),
12276
+ children: p
12277
+ },
12278
+ p
12279
+ )
12280
+ );
12281
+ })(),
12282
+ /* @__PURE__ */ jsx56(
12283
+ Button_default,
12284
+ {
12285
+ variant: "ghost",
12286
+ size: "sm",
12287
+ className: "h-7 w-7 p-0",
12288
+ onClick: () => setCurPage(Math.min(Math.ceil(totalItems / curPageSize), curPage + 1)),
12289
+ disabled: curPage === Math.ceil(totalItems / curPageSize),
12290
+ children: /* @__PURE__ */ jsx56("svg", { className: "h-4 w-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx56("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
12291
+ }
12292
+ )
12293
+ ] }),
12294
+ pageSizeOptions && /* @__PURE__ */ jsx56(
12295
+ Combobox,
12296
+ {
12297
+ options: pageSizeOptions.map(String),
12298
+ value: String(curPageSize),
12299
+ onChange: (v) => {
12300
+ setCurPage(1);
12301
+ setCurPageSize(Number(v));
12302
+ },
12303
+ size: "sm",
12304
+ className: "w-14 h-7"
12231
12305
  }
12232
- }
12233
- ) })
12306
+ )
12307
+ ] })
12234
12308
  ] });
12235
12309
  }
12236
12310
  var DataTable_default = DataTable;