@underverse-ui/underverse 2.0.0 → 2.0.2

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
@@ -2116,7 +2116,7 @@ interface CategoryTreeSelectBaseProps {
2116
2116
  leafOnlySelect?: boolean;
2117
2117
  /** Virtualize the dropdown tree by rendering only visible rows. Inline/view-only trees keep recursive rendering. */
2118
2118
  virtualized?: boolean;
2119
- /** Estimated tree row height used by virtualized rendering. Default: `44`. */
2119
+ /** Estimated tree row height used by virtualized rendering. Default: `36`. */
2120
2120
  estimatedItemHeight?: number;
2121
2121
  /** Number of extra rows rendered above and below the visible range. Default: `8`. */
2122
2122
  overscan?: number;
@@ -2149,7 +2149,7 @@ interface CategoryTreeSelectBaseProps {
2149
2149
  */
2150
2150
  renderItemActions?: (category: Category) => React__default.ReactNode;
2151
2151
  /**
2152
- * Base left padding in rem applied to every node regardless of depth. Default: `0.75`.
2152
+ * Base left padding in rem applied to every node regardless of depth. Default: `0`.
2153
2153
  *
2154
2154
  * @remarks
2155
2155
  * Combined with `indentSize`, the final padding of a node at a given depth is:
@@ -2161,7 +2161,7 @@ interface CategoryTreeSelectBaseProps {
2161
2161
  */
2162
2162
  baseIndent?: number;
2163
2163
  /**
2164
- * Additional left padding in rem added per depth level. Default: `1`.
2164
+ * Additional left padding in rem added per depth level. Default: `0.75`.
2165
2165
  *
2166
2166
  * @remarks
2167
2167
  * Set to a smaller value (e.g. `0.75`) to reduce the visual gap between
@@ -2172,6 +2172,8 @@ interface CategoryTreeSelectBaseProps {
2172
2172
  * <CategoryTreeSelect baseIndent={0.25} indentSize={0.75} />
2173
2173
  */
2174
2174
  indentSize?: number;
2175
+ /** Show dashed vertical guide lines between parent and child levels. Default: `true`. */
2176
+ showTreeLines?: boolean;
2175
2177
  borderMode?: BorderMode;
2176
2178
  }
2177
2179
  /** Multi-select mode. This is the default when `singleSelect` is omitted. */
@@ -2784,7 +2786,10 @@ type DataTableColumn<T> = {
2784
2786
  };
2785
2787
  render?: (value: any, record: T, index: number) => React__default.ReactNode;
2786
2788
  width?: number | string;
2789
+ /** Body cell alignment for this column. Defaults to `"left"`. */
2787
2790
  align?: "left" | "center" | "right";
2791
+ /** Header alignment for this column. Defaults to the table header alignment (`"center"` initially). */
2792
+ headerAlign?: "left" | "center" | "right";
2788
2793
  /** Vị trí của icon sort/filter: "inline" (ngay sát text) hoặc "end" (cuối dòng). Mặc định là "end". */
2789
2794
  iconPosition?: "inline" | "end";
2790
2795
  visible?: boolean;
package/dist/index.d.ts CHANGED
@@ -2116,7 +2116,7 @@ interface CategoryTreeSelectBaseProps {
2116
2116
  leafOnlySelect?: boolean;
2117
2117
  /** Virtualize the dropdown tree by rendering only visible rows. Inline/view-only trees keep recursive rendering. */
2118
2118
  virtualized?: boolean;
2119
- /** Estimated tree row height used by virtualized rendering. Default: `44`. */
2119
+ /** Estimated tree row height used by virtualized rendering. Default: `36`. */
2120
2120
  estimatedItemHeight?: number;
2121
2121
  /** Number of extra rows rendered above and below the visible range. Default: `8`. */
2122
2122
  overscan?: number;
@@ -2149,7 +2149,7 @@ interface CategoryTreeSelectBaseProps {
2149
2149
  */
2150
2150
  renderItemActions?: (category: Category) => React__default.ReactNode;
2151
2151
  /**
2152
- * Base left padding in rem applied to every node regardless of depth. Default: `0.75`.
2152
+ * Base left padding in rem applied to every node regardless of depth. Default: `0`.
2153
2153
  *
2154
2154
  * @remarks
2155
2155
  * Combined with `indentSize`, the final padding of a node at a given depth is:
@@ -2161,7 +2161,7 @@ interface CategoryTreeSelectBaseProps {
2161
2161
  */
2162
2162
  baseIndent?: number;
2163
2163
  /**
2164
- * Additional left padding in rem added per depth level. Default: `1`.
2164
+ * Additional left padding in rem added per depth level. Default: `0.75`.
2165
2165
  *
2166
2166
  * @remarks
2167
2167
  * Set to a smaller value (e.g. `0.75`) to reduce the visual gap between
@@ -2172,6 +2172,8 @@ interface CategoryTreeSelectBaseProps {
2172
2172
  * <CategoryTreeSelect baseIndent={0.25} indentSize={0.75} />
2173
2173
  */
2174
2174
  indentSize?: number;
2175
+ /** Show dashed vertical guide lines between parent and child levels. Default: `true`. */
2176
+ showTreeLines?: boolean;
2175
2177
  borderMode?: BorderMode;
2176
2178
  }
2177
2179
  /** Multi-select mode. This is the default when `singleSelect` is omitted. */
@@ -2784,7 +2786,10 @@ type DataTableColumn<T> = {
2784
2786
  };
2785
2787
  render?: (value: any, record: T, index: number) => React__default.ReactNode;
2786
2788
  width?: number | string;
2789
+ /** Body cell alignment for this column. Defaults to `"left"`. */
2787
2790
  align?: "left" | "center" | "right";
2791
+ /** Header alignment for this column. Defaults to the table header alignment (`"center"` initially). */
2792
+ headerAlign?: "left" | "center" | "right";
2788
2793
  /** Vị trí của icon sort/filter: "inline" (ngay sát text) hoặc "end" (cuối dòng). Mặc định là "end". */
2789
2794
  iconPosition?: "inline" | "end";
2790
2795
  visible?: boolean;
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  extractImageSrcsFromHtml,
5
5
  normalizeImageUrl,
6
6
  prepareUEditorContentForSave
7
- } from "./chunk-QIMAN4VF.js";
7
+ } from "./chunk-Y7SQKJ7X.js";
8
8
  import {
9
9
  EmojiPicker_default
10
10
  } from "./chunk-A7XL4RDV.js";
@@ -16,7 +16,7 @@ import {
16
16
  import "./chunk-4TYW5K4J.js";
17
17
  import {
18
18
  Modal_default
19
- } from "./chunk-MNZVW2QX.js";
19
+ } from "./chunk-UNDGI6ZI.js";
20
20
  import {
21
21
  DropdownMenuItem,
22
22
  DropdownMenuSeparator,
@@ -34,7 +34,7 @@ import {
34
34
  shadcnAnimationStyles,
35
35
  useShadCNAnimations,
36
36
  useUnderverseUIConfig
37
- } from "./chunk-LTIU5FQY.js";
37
+ } from "./chunk-Z6WE65J2.js";
38
38
  import {
39
39
  ForceInternalTranslationsProvider,
40
40
  NextIntlAdapter,
@@ -4208,19 +4208,19 @@ var variantStyles4 = {
4208
4208
  },
4209
4209
  underline: {
4210
4210
  container: "relative border-b border-border/60",
4211
- tab: "relative transition-colors duration-200 pb-3 border-b-2 border-transparent hover:border-primary/30",
4211
+ tab: "relative transition-colors duration-200 border-b-2 border-transparent hover:border-primary/30",
4212
4212
  activeTab: "text-primary border-primary font-semibold",
4213
4213
  inactiveTab: "text-muted-foreground hover:text-foreground"
4214
4214
  },
4215
4215
  card: {
4216
- container: "space-y-1.5 bg-muted/20 p-2 rounded-2xl border border-border/30",
4216
+ container: "bg-muted/20 p-1.5 rounded-2xl border border-border/30",
4217
4217
  tab: "rounded-xl border border-transparent transition-all duration-200",
4218
4218
  activeTab: "bg-primary text-primary-foreground border-primary shadow-md",
4219
4219
  inactiveTab: "text-muted-foreground hover:text-foreground hover:bg-accent/50 hover:border-border/50"
4220
4220
  },
4221
4221
  "underline-card": {
4222
4222
  container: "border-b border-border/60 bg-card/80 backdrop-blur-sm rounded-t-2xl p-1",
4223
- tab: "relative transition-all duration-200 pb-3 px-4 rounded-t-xl border-b-2 border-transparent hover:border-primary/30 hover:bg-accent/30",
4223
+ tab: "relative transition-all duration-200 rounded-t-xl border-b-2 border-transparent hover:border-primary/30 hover:bg-accent/30",
4224
4224
  activeTab: "text-primary border-primary font-semibold bg-accent/30",
4225
4225
  inactiveTab: "text-muted-foreground hover:text-foreground"
4226
4226
  }
@@ -4330,7 +4330,7 @@ var Tabs = ({
4330
4330
  }, [baseId, tabs]);
4331
4331
  const containerClasses = cn(
4332
4332
  "relative",
4333
- orientation === "horizontal" ? "w-full flex space-x-1 overflow-x-auto" : "flex flex-col space-y-1 shrink-0",
4333
+ orientation === "horizontal" ? "w-full flex items-center space-x-1 overflow-x-auto" : "flex flex-col space-y-1 shrink-0",
4334
4334
  variantStyles4[variant].container,
4335
4335
  className
4336
4336
  );
@@ -4365,10 +4365,7 @@ var Tabs = ({
4365
4365
  tab.href && tab.disabled && "pointer-events-none cursor-not-allowed opacity-50"
4366
4366
  );
4367
4367
  const sharedStyle = {
4368
- boxShadow: "none",
4369
- transform: "none",
4370
- outline: "none",
4371
- border: "none"
4368
+ outline: "none"
4372
4369
  };
4373
4370
  const sharedProps = {
4374
4371
  ref: (el) => {
@@ -15251,7 +15248,7 @@ var MultiCombobox = ({
15251
15248
  );
15252
15249
  }),
15253
15250
  hiddenCount > 0 && /* @__PURE__ */ jsx39("span", { className: cn("inline-flex items-center bg-muted text-muted-foreground rounded-lg shrink-0", sizeStyles7[size].tag), children: gi18n.moreCount ? gi18n.moreCount(hiddenCount) : `+${hiddenCount} more` })
15254
- ] }) : /* @__PURE__ */ jsx39("span", { className: cn(formControlValueClass, "font-medium"), children: gi18n.selectedCount ? gi18n.selectedCount(value.length) : `${value.length} item${value.length > 1 ? "s" : ""} selected` }) : /* @__PURE__ */ jsx39("span", { className: cn(formControlValueClass, "text-muted-foreground"), children: placeholder }) }),
15251
+ ] }) : /* @__PURE__ */ jsx39("span", { className: cn(formControlValueClass, "font-medium"), children: gi18n.selectedCount ? gi18n.selectedCount(value.length) : `${value.length} item${value.length > 1 ? "s" : ""} selected` }) : /* @__PURE__ */ jsx39("span", { className: cn(formControlValueClass, "text-left text-muted-foreground"), children: placeholder }) }),
15255
15252
  /* @__PURE__ */ jsxs32("div", { className: "flex items-center gap-1.5 shrink-0", children: [
15256
15253
  showClear && value.length > 0 && /* @__PURE__ */ jsx39(
15257
15254
  "div",
@@ -16685,9 +16682,8 @@ var defaultLabels = {
16685
16682
  searchPlaceholder: "Search...",
16686
16683
  noResultsText: "No results found"
16687
16684
  };
16688
- var TREE_NODE_BASE_PADDING_REM = 0.75;
16689
- var TREE_NODE_INDENT_REM = 1;
16690
- var TREE_BRANCH_OFFSET_CLASS = "ml-1.5 pl-1.5";
16685
+ var TREE_NODE_BASE_PADDING_REM = 0;
16686
+ var TREE_NODE_INDENT_REM = 0.75;
16691
16687
  var TREE_NODE_GAP_CLASS = "gap-1.5";
16692
16688
  var TREE_EXPANDER_PLACEHOLDER_CLASS = "w-5";
16693
16689
  var CATEGORY_TREE_DROPDOWN_MAX_HEIGHT = 320;
@@ -16817,7 +16813,7 @@ function CategoryTreeSelect(props) {
16817
16813
  useOverlayScrollbar = false,
16818
16814
  leafOnlySelect = false,
16819
16815
  virtualized = false,
16820
- estimatedItemHeight = 44,
16816
+ estimatedItemHeight = 36,
16821
16817
  overscan = 8,
16822
16818
  maxInitialOptions,
16823
16819
  searchMode = "auto",
@@ -16827,6 +16823,7 @@ function CategoryTreeSelect(props) {
16827
16823
  showSearchPromptWhenEmptyQuery = false,
16828
16824
  baseIndent = TREE_NODE_BASE_PADDING_REM,
16829
16825
  indentSize = TREE_NODE_INDENT_REM,
16826
+ showTreeLines = true,
16830
16827
  renderItemActions,
16831
16828
  singleSelect = false,
16832
16829
  borderMode
@@ -17114,7 +17111,7 @@ function CategoryTreeSelect(props) {
17114
17111
  {
17115
17112
  ref: virtualItem ? treeVirtualizer.measureElement : void 0,
17116
17113
  "data-index": virtualItem?.index,
17117
- className: cn("min-w-0 [content-visibility:auto] [contain-intrinsic-size:44px]", !virtualItem && "animate-in fade-in-50 duration-200"),
17114
+ className: cn("min-w-0 [content-visibility:auto] [contain-intrinsic-size:36px]", !virtualItem && "animate-in fade-in-50 duration-200"),
17118
17115
  style: { animationDelay: virtualItem ? void 0 : `${level * 30}ms`, ...rowStyle },
17119
17116
  children: [
17120
17117
  /* @__PURE__ */ jsxs36(
@@ -17126,7 +17123,7 @@ function CategoryTreeSelect(props) {
17126
17123
  "aria-selected": viewOnly ? void 0 : isSelected,
17127
17124
  onClick: () => !viewOnly && handleSelect(category.id, category),
17128
17125
  className: cn(
17129
- "relative flex min-w-0 items-center px-3 py-2.5 min-h-11 transition-all duration-200 rounded-3xl",
17126
+ "relative flex min-h-9 min-w-0 items-center rounded-3xl transition-all duration-200",
17130
17127
  TREE_NODE_GAP_CLASS,
17131
17128
  !viewOnly && (isSelectable ? "cursor-pointer" : "cursor-default"),
17132
17129
  isSelectable && !isSelected && "hover:bg-accent/50",
@@ -17136,6 +17133,16 @@ function CategoryTreeSelect(props) {
17136
17133
  ),
17137
17134
  style: { paddingLeft: `${level * indentSize + baseIndent}rem` },
17138
17135
  children: [
17136
+ virtualItem && showTreeLines && Array.from({ length: level }, (_, ancestorLevel) => /* @__PURE__ */ jsx43(
17137
+ "span",
17138
+ {
17139
+ "data-tree-line": true,
17140
+ "aria-hidden": "true",
17141
+ className: "pointer-events-none absolute inset-y-0 w-px border-l border-dashed border-border/50",
17142
+ style: { left: `${ancestorLevel * indentSize + baseIndent + 0.5}rem` }
17143
+ },
17144
+ ancestorLevel
17145
+ )),
17139
17146
  hasChildren ? /* @__PURE__ */ jsx43(
17140
17147
  "button",
17141
17148
  {
@@ -17184,16 +17191,23 @@ function CategoryTreeSelect(props) {
17184
17191
  ]
17185
17192
  }
17186
17193
  ),
17187
- !virtualItem && hasChildren && isExpanded && /* @__PURE__ */ jsx43(
17194
+ !virtualItem && hasChildren && isExpanded && /* @__PURE__ */ jsxs36(
17188
17195
  "div",
17189
17196
  {
17190
17197
  role: "group",
17191
- className: cn(
17192
- TREE_BRANCH_OFFSET_CLASS,
17193
- "border-l-2 border-dashed border-border/50",
17194
- "animate-in slide-in-from-top-2 fade-in-50 duration-200"
17195
- ),
17196
- children: children.map((child) => renderCategoryRow(child, level + 1))
17198
+ className: "relative animate-in fade-in-50 slide-in-from-top-2 duration-200",
17199
+ children: [
17200
+ showTreeLines && /* @__PURE__ */ jsx43(
17201
+ "span",
17202
+ {
17203
+ "data-tree-line": true,
17204
+ "aria-hidden": "true",
17205
+ className: "pointer-events-none absolute inset-y-0 w-px border-l border-dashed border-border/50",
17206
+ style: { left: `${level * indentSize + baseIndent + 0.5}rem` }
17207
+ }
17208
+ ),
17209
+ children.map((child) => renderCategoryRow(child, level + 1))
17210
+ ]
17197
17211
  }
17198
17212
  )
17199
17213
  ]
@@ -21327,6 +21341,7 @@ function DataTableBodyRows({
21327
21341
  style: getStickyColumnStyle(col),
21328
21342
  className: cn(
21329
21343
  cellPadding,
21344
+ (!col.align || col.align === "left") && "text-left",
21330
21345
  col.align === "right" && "text-right",
21331
21346
  col.align === "center" && "text-center",
21332
21347
  showBorderLeft && "border-l border-border/60",
@@ -21528,16 +21543,17 @@ function DataTableHeader({
21528
21543
  className: cn(
21529
21544
  "flex items-center gap-1",
21530
21545
  headerMinHeightClass,
21531
- col.align === "right" && "justify-end",
21532
- col.align === "center" && "justify-center",
21533
- !col.align && "justify-start"
21546
+ (col.headerAlign ?? headerAlign) === "right" && "justify-end",
21547
+ (col.headerAlign ?? headerAlign) === "center" && "justify-center",
21548
+ (col.headerAlign ?? headerAlign) === "left" && "justify-start"
21534
21549
  ),
21535
21550
  children: /* @__PURE__ */ jsx58("span", { className: cn("font-medium whitespace-nowrap select-text", headerTitleClass), children: col.title })
21536
21551
  }
21537
21552
  );
21538
21553
  }
21539
- const isRightAlign = col.align === "right" || !col.align && headerAlign === "right";
21540
- const isCenterAlign = col.align === "center" || !col.align && headerAlign === "center";
21554
+ const resolvedHeaderAlign = col.headerAlign ?? headerAlign;
21555
+ const isRightAlign = resolvedHeaderAlign === "right";
21556
+ const isCenterAlign = resolvedHeaderAlign === "center";
21541
21557
  const columnLabel = getColumnLabel(col.title) || col.key;
21542
21558
  const sortByText = sortByLabel ?? gi18n.sortBy ?? "Sort by";
21543
21559
  const sortLabel = `${sortByText} ${columnLabel}`;
@@ -21699,8 +21715,8 @@ function DataTableHeader({
21699
21715
  },
21700
21716
  className: cn(
21701
21717
  "relative",
21702
- (col.align === "right" || !col.align && headerAlign === "right") && "text-right",
21703
- (col.align === "center" || !col.align && headerAlign === "center") && "text-center",
21718
+ (col.headerAlign ?? headerAlign) === "right" && "text-right",
21719
+ (col.headerAlign ?? headerAlign) === "center" && "text-center",
21704
21720
  showBorderLeft && "border-l border-border/60",
21705
21721
  getStickyHeaderClass(col)
21706
21722
  ),
@@ -22220,7 +22236,7 @@ function useDataTableState({
22220
22236
  const allLeafColumns = React56.useMemo(() => getLeafColumns(columns), [columns]);
22221
22237
  const defaultVisibleLeafKeys = React56.useMemo(() => allLeafColumns.filter((column) => column.visible !== false).map((column) => column.key), [allLeafColumns]);
22222
22238
  const knownLeafKeysRef = React56.useRef(new Set(defaultVisibleLeafKeys));
22223
- const [headerAlign, setHeaderAlign] = React56.useState("left");
22239
+ const [headerAlign, setHeaderAlign] = React56.useState("center");
22224
22240
  const [visibleCols, setVisibleCols] = React56.useState(defaultVisibleLeafKeys);
22225
22241
  const [filters, setFilters] = React56.useState({});
22226
22242
  const [sort, setSort] = React56.useState(null);