@underverse-ui/underverse 0.1.5 → 0.1.7

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/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Underverse UI
2
2
 
3
+ Docs: https://underverse-sepia.vercel.app/vi/docs/underverse
4
+
3
5
  **Author:** Tran Van Bach
4
6
 
5
7
  A comprehensive UI component library for React/Next.js applications, extracted from the main project. Built with Tailwind CSS, `clsx`, and `tailwind-merge`. Some components support `next-intl` (optional).
package/dist/index.cjs CHANGED
@@ -2588,7 +2588,7 @@ var variantIcons = {
2588
2588
  warning: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(WarningIcon, { className: "h-4 w-4 text-warning" }),
2589
2589
  error: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ErrorIcon, { className: "h-4 w-4 text-destructive" })
2590
2590
  };
2591
- var Alert = ({ title, description, variant = "default", className, icon, dismissible = false, onClose, actions }) => {
2591
+ var Alert = ({ title, description, variant = "default", className, icon, dismissible = false, onClose, actions, closeAriaLabel }) => {
2592
2592
  const [open, setOpen] = (0, import_react7.useState)(true);
2593
2593
  const t = (0, import_next_intl2.useTranslations)("Common");
2594
2594
  if (!open) return null;
@@ -2614,7 +2614,7 @@ var Alert = ({ title, description, variant = "default", className, icon, dismiss
2614
2614
  {
2615
2615
  onClick: handleClose,
2616
2616
  className: "rounded-md p-1 hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2617
- "aria-label": t("closeAlert"),
2617
+ "aria-label": closeAriaLabel || t("closeAlert"),
2618
2618
  children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react9.X, { className: "h-4 w-4" })
2619
2619
  }
2620
2620
  )
@@ -2625,7 +2625,7 @@ var Alert = ({ title, description, variant = "default", className, icon, dismiss
2625
2625
  var Alert_default = Alert;
2626
2626
 
2627
2627
  // ../../components/ui/GlobalLoading.tsx
2628
- var import_react8 = require("react");
2628
+ var import_react8 = __toESM(require("react"), 1);
2629
2629
  var import_lucide_react10 = require("lucide-react");
2630
2630
 
2631
2631
  // ../../lib/utils/loading.ts
@@ -2744,21 +2744,24 @@ var ButtonLoading = ({
2744
2744
  disabled,
2745
2745
  loadingText
2746
2746
  }) => {
2747
+ const child = import_react8.default.isValidElement(children) ? import_react8.default.cloneElement(children, {
2748
+ disabled: (children.props?.disabled ?? false) || disabled || isLoading,
2749
+ "aria-busy": isLoading || void 0
2750
+ }) : children;
2747
2751
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2748
- "button",
2752
+ "div",
2749
2753
  {
2750
2754
  className: cn(
2751
- "relative",
2755
+ "relative inline-block",
2752
2756
  isLoading && "cursor-not-allowed",
2753
2757
  className
2754
2758
  ),
2755
- disabled: disabled || isLoading,
2756
2759
  children: [
2757
- isLoading && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "absolute inset-0 flex items-center justify-center", children: [
2760
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: [
2758
2761
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react10.Activity, { className: "w-4 h-4 animate-spin text-primary-foreground" }),
2759
2762
  loadingText && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ml-2 text-sm", children: loadingText })
2760
2763
  ] }),
2761
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cn(isLoading && "invisible"), children })
2764
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cn(isLoading && "opacity-50 pointer-events-none"), children: child })
2762
2765
  ]
2763
2766
  }
2764
2767
  );
@@ -3675,7 +3678,8 @@ var Pagination = ({
3675
3678
  pageSize,
3676
3679
  pageSizeOptions,
3677
3680
  onPageSizeChange,
3678
- totalItems
3681
+ totalItems,
3682
+ labels
3679
3683
  }) => {
3680
3684
  const t = (0, import_next_intl4.useTranslations)("Pagination");
3681
3685
  const createPageArray = () => {
@@ -3729,8 +3733,8 @@ var Pagination = ({
3729
3733
  }
3730
3734
  };
3731
3735
  if (totalPages <= 1) return null;
3732
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("nav", { className: cn("flex flex-col gap-4", className), "aria-label": t("navigationLabel"), children: [
3733
- showInfo && totalItems && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "text-sm text-muted-foreground text-center", children: t("showingResults", { startItem: startItem || 0, endItem: endItem || 0, totalItems }) }),
3736
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("nav", { className: cn("flex flex-col gap-4", className), "aria-label": labels?.navigationLabel || t("navigationLabel"), children: [
3737
+ showInfo && totalItems && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "text-sm text-muted-foreground text-center", children: labels?.showingResults ? labels.showingResults({ startItem: startItem || 0, endItem: endItem || 0, totalItems }) : t("showingResults", { startItem: startItem || 0, endItem: endItem || 0, totalItems }) }),
3734
3738
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
3735
3739
  showFirstLast && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3736
3740
  Button_default,
@@ -3741,8 +3745,8 @@ var Pagination = ({
3741
3745
  onClick: () => onChange(1),
3742
3746
  disabled: disabled || page === 1,
3743
3747
  className: "hidden sm:flex",
3744
- title: t("firstPage"),
3745
- "aria-label": t("firstPage"),
3748
+ title: labels?.firstPage || t("firstPage"),
3749
+ "aria-label": labels?.firstPage || t("firstPage"),
3746
3750
  "aria-disabled": disabled || page === 1
3747
3751
  }
3748
3752
  ),
@@ -3754,10 +3758,10 @@ var Pagination = ({
3754
3758
  icon: import_lucide_react13.ChevronLeft,
3755
3759
  onClick: () => onChange(Math.max(1, page - 1)),
3756
3760
  disabled: disabled || page === 1,
3757
- title: t("previousPage"),
3758
- "aria-label": t("previousPage"),
3761
+ title: labels?.previousPage || t("previousPage"),
3762
+ "aria-label": labels?.previousPage || t("previousPage"),
3759
3763
  "aria-disabled": disabled || page === 1,
3760
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "hidden sm:inline", children: t("previous") })
3764
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "hidden sm:inline", children: labels?.previous || t("previous") })
3761
3765
  }
3762
3766
  ),
3763
3767
  showPageNumbers && createPageArray().map((p, i) => {
@@ -3774,7 +3778,7 @@ var Pagination = ({
3774
3778
  onClick: () => onChange(pageNumber),
3775
3779
  disabled,
3776
3780
  className: cn("min-w-[2.5rem]", isActive && "font-semibold"),
3777
- "aria-label": t("pageNumber", { page: pageNumber }),
3781
+ "aria-label": labels?.pageNumber ? labels.pageNumber(pageNumber) : t("pageNumber", { page: pageNumber }),
3778
3782
  "aria-current": isActive ? "page" : void 0,
3779
3783
  children: pageNumber
3780
3784
  },
@@ -3789,10 +3793,10 @@ var Pagination = ({
3789
3793
  iconRight: import_lucide_react13.ChevronRight,
3790
3794
  onClick: () => onChange(Math.min(totalPages, page + 1)),
3791
3795
  disabled: disabled || page === totalPages,
3792
- title: t("nextPage"),
3793
- "aria-label": t("nextPage"),
3796
+ title: labels?.nextPage || t("nextPage"),
3797
+ "aria-label": labels?.nextPage || t("nextPage"),
3794
3798
  "aria-disabled": disabled || page === totalPages,
3795
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "hidden sm:inline", children: t("next") })
3799
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "hidden sm:inline", children: labels?.next || t("next") })
3796
3800
  }
3797
3801
  ),
3798
3802
  showFirstLast && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
@@ -3804,15 +3808,15 @@ var Pagination = ({
3804
3808
  onClick: () => onChange(totalPages),
3805
3809
  disabled: disabled || page === totalPages,
3806
3810
  className: "hidden sm:flex",
3807
- title: t("lastPage"),
3808
- "aria-label": t("lastPage"),
3811
+ title: labels?.lastPage || t("lastPage"),
3812
+ "aria-label": labels?.lastPage || t("lastPage"),
3809
3813
  "aria-disabled": disabled || page === totalPages
3810
3814
  }
3811
3815
  )
3812
3816
  ] }),
3813
3817
  pageSizeOptions && onPageSizeChange && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-center gap-2 text-sm", children: [
3814
3818
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "text-muted-foreground", children: [
3815
- t("itemsPerPage"),
3819
+ labels?.itemsPerPage || t("itemsPerPage"),
3816
3820
  ":"
3817
3821
  ] }),
3818
3822
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "w-20", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
@@ -3822,8 +3826,8 @@ var Pagination = ({
3822
3826
  value: pageSize?.toString() || "10",
3823
3827
  onChange: handlePageSizeChange,
3824
3828
  placeholder: "10",
3825
- searchPlaceholder: t("search"),
3826
- emptyText: t("noOptions"),
3829
+ searchPlaceholder: labels?.search || t("search"),
3830
+ emptyText: labels?.noOptions || t("noOptions"),
3827
3831
  disabled
3828
3832
  }
3829
3833
  ) })
@@ -4079,7 +4083,10 @@ var DatePicker = ({
4079
4083
  disabled = false,
4080
4084
  size = "md",
4081
4085
  label,
4082
- required
4086
+ required,
4087
+ todayLabel,
4088
+ clearLabel,
4089
+ weekdayLabels
4083
4090
  }) => {
4084
4091
  const t = (0, import_next_intl5.useTranslations)("DatePicker");
4085
4092
  const locale = (0, import_next_intl5.useLocale)();
@@ -4220,10 +4227,10 @@ var DatePicker = ({
4220
4227
  children: [
4221
4228
  /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
4222
4229
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button_default, { variant: "ghost", size: "sm", onClick: () => navigateMonth("prev"), className: "p-1 h-auto", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.ChevronLeft, { className: "h-4 w-4" }) }),
4223
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-sm font-semibold", children: viewDate.toLocaleDateString(locale === "vi" /* VI */ ? "vi-VN" : "en-US", { month: "long", year: "numeric" }) }),
4230
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-sm font-semibold", children: viewDate.toLocaleDateString("en-US", { month: "long", year: "numeric" }) }),
4224
4231
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button_default, { variant: "ghost", size: "sm", onClick: () => navigateMonth("next"), className: "p-1 h-auto", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.ChevronRight, { className: "h-4 w-4" }) })
4225
4232
  ] }),
4226
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("grid grid-cols-7 gap-1", size === "sm" ? "mb-1" : "mb-2"), children: (locale === "vi" /* VI */ ? t("weekdays").split(",") : ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]).map((day) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("text-muted-foreground text-center font-medium", size === "sm" ? "text-[10px] py-0.5" : "text-xs py-1"), children: day }, day)) }),
4233
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("grid grid-cols-7 gap-1", size === "sm" ? "mb-1" : "mb-2"), children: (weekdayLabels || ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]).map((day) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("text-muted-foreground text-center font-medium", size === "sm" ? "text-[10px] py-0.5" : "text-xs py-1"), children: day }, day)) }),
4227
4234
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "grid grid-cols-7 gap-1", children: renderCalendar() })
4228
4235
  ]
4229
4236
  }
@@ -5746,7 +5753,8 @@ function DataTable({
5746
5753
  enableDensityToggle = true,
5747
5754
  striped = true,
5748
5755
  // Mặc định bật màu nền sẽn kẽ cho các dòng
5749
- className
5756
+ className,
5757
+ labels
5750
5758
  }) {
5751
5759
  const t = (0, import_next_intl7.useTranslations)("Common");
5752
5760
  const [visibleCols, setVisibleCols] = import_react20.default.useState(() => columns.filter((c) => c.visible !== false).map((c) => c.key));
@@ -5926,12 +5934,12 @@ function DataTable({
5926
5934
  {
5927
5935
  trigger: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
5928
5936
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
5929
- t("density")
5937
+ labels?.density || t("density")
5930
5938
  ] }),
5931
5939
  items: [
5932
- { label: t("compact"), onClick: () => setDensity("compact") },
5933
- { label: t("normal"), onClick: () => setDensity("normal") },
5934
- { label: t("comfortable"), onClick: () => setDensity("comfortable") }
5940
+ { label: labels?.compact || t("compact"), onClick: () => setDensity("compact") },
5941
+ { label: labels?.normal || t("normal"), onClick: () => setDensity("normal") },
5942
+ { label: labels?.comfortable || t("comfortable"), onClick: () => setDensity("comfortable") }
5935
5943
  ]
5936
5944
  }
5937
5945
  ),
@@ -5948,7 +5956,7 @@ function DataTable({
5948
5956
  d: "M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2"
5949
5957
  }
5950
5958
  ) }),
5951
- t("columns")
5959
+ labels?.columns || t("columns")
5952
5960
  ] }),
5953
5961
  children: columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
5954
5962
  DropdownMenuItem,
@@ -6028,7 +6036,7 @@ var DataTable_default = DataTable;
6028
6036
  var import_lucide_react21 = require("lucide-react");
6029
6037
  var import_next_intl8 = require("next-intl");
6030
6038
  var import_jsx_runtime39 = require("react/jsx-runtime");
6031
- function NotificationModal({ isOpen, onClose, notification }) {
6039
+ function NotificationModal({ isOpen, onClose, notification, titleText, openLinkText, closeText }) {
6032
6040
  const t = (0, import_next_intl8.useTranslations)("Common");
6033
6041
  if (!notification) return null;
6034
6042
  const formatTime2 = (dateString) => {
@@ -6053,7 +6061,7 @@ function NotificationModal({ isOpen, onClose, notification }) {
6053
6061
  {
6054
6062
  isOpen,
6055
6063
  onClose,
6056
- title: t("notifications"),
6064
+ title: titleText || t("notifications"),
6057
6065
  size: "md",
6058
6066
  children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "space-y-4", children: [
6059
6067
  /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-center gap-2 pb-2 border-b border-border", children: [
@@ -6076,7 +6084,7 @@ function NotificationModal({ isOpen, onClose, notification }) {
6076
6084
  className: "gap-2",
6077
6085
  children: [
6078
6086
  /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react21.ExternalLink, { className: "w-4 h-4" }),
6079
- t("openLink")
6087
+ openLinkText || t("openLink")
6080
6088
  ]
6081
6089
  }
6082
6090
  ),
@@ -6086,7 +6094,7 @@ function NotificationModal({ isOpen, onClose, notification }) {
6086
6094
  variant: "ghost",
6087
6095
  size: "sm",
6088
6096
  onClick: onClose,
6089
- children: t("close")
6097
+ children: closeText || t("close")
6090
6098
  }
6091
6099
  )
6092
6100
  ] })