@l3mpire/ui 2.18.1 → 2.19.0

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.mts CHANGED
@@ -1013,6 +1013,7 @@ interface SummaryChipProps {
1013
1013
  open?: boolean;
1014
1014
  onOpenChange?: (open: boolean) => void;
1015
1015
  collisionBoundary?: Element | null;
1016
+ tooltipContent?: React.ReactNode;
1016
1017
  }
1017
1018
  declare const SummaryChip: React.FC<SummaryChipProps>;
1018
1019
 
package/dist/index.d.ts CHANGED
@@ -1013,6 +1013,7 @@ interface SummaryChipProps {
1013
1013
  open?: boolean;
1014
1014
  onOpenChange?: (open: boolean) => void;
1015
1015
  collisionBoundary?: Element | null;
1016
+ tooltipContent?: React.ReactNode;
1016
1017
  }
1017
1018
  declare const SummaryChip: React.FC<SummaryChipProps>;
1018
1019
 
package/dist/index.js CHANGED
@@ -5323,7 +5323,7 @@ var DEFAULT_OPERATOR_BY_TYPE = {
5323
5323
  text: "contains",
5324
5324
  number: "=",
5325
5325
  date: "is between",
5326
- enum: "is",
5326
+ enum: "is any of",
5327
5327
  tags: "contains",
5328
5328
  boolean: "is true",
5329
5329
  relation: "is"
@@ -5360,7 +5360,7 @@ function getValueInputType(type, operator) {
5360
5360
  return ["is any of", "is none of"].includes(operator) ? "MultiRelationPicker" : "RelationPicker";
5361
5361
  return null;
5362
5362
  }
5363
- function formatFilterValue(value, dynamicOptions) {
5363
+ function formatFilterValue(value, dynamicOptions, full) {
5364
5364
  if (value == null) return void 0;
5365
5365
  if (typeof value === "boolean") return value ? "Yes" : "No";
5366
5366
  if (value instanceof Date) {
@@ -5379,6 +5379,9 @@ function formatFilterValue(value, dynamicOptions) {
5379
5379
  const fmt = (d) => d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
5380
5380
  return `${fmt(value[0])} \u2013 ${value[1] instanceof Date ? fmt(value[1]) : "\u2026"}`;
5381
5381
  }
5382
+ if (full) {
5383
+ return value.map((v) => resolveDynamic(String(v), dynamicOptions)).join(", ");
5384
+ }
5382
5385
  const resolved = resolveDynamic(String(value[0]), dynamicOptions);
5383
5386
  return resolved;
5384
5387
  }
@@ -5519,7 +5522,7 @@ var FilterBar = React38.forwardRef(
5519
5522
  {
5520
5523
  ref,
5521
5524
  className: cn(
5522
- "flex items-center justify-between w-full",
5525
+ "flex items-start justify-between w-full",
5523
5526
  className
5524
5527
  ),
5525
5528
  role: "toolbar",
@@ -6563,7 +6566,9 @@ var DateCalendarValueInput = ({
6563
6566
  if (isRange) {
6564
6567
  if (Array.isArray(value) && value.length === 2) {
6565
6568
  const [from, to] = value;
6566
- return { from, to };
6569
+ if (from instanceof Date) {
6570
+ return { from, to: to instanceof Date ? to : void 0 };
6571
+ }
6567
6572
  }
6568
6573
  return void 0;
6569
6574
  }
@@ -6578,7 +6583,7 @@ var DateCalendarValueInput = ({
6578
6583
  if (range.from && range.to) {
6579
6584
  onChange([range.from, range.to]);
6580
6585
  } else if (range.from) {
6581
- onChange([range.from, range.from]);
6586
+ onChange([range.from, null]);
6582
6587
  }
6583
6588
  }
6584
6589
  };
@@ -6748,7 +6753,6 @@ var MultiSelectValueInput = ({
6748
6753
  },
6749
6754
  opt.value
6750
6755
  )),
6751
- dynamicOptions && dynamicOptions.length > 0 && options.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(DynamicOptionsDivider, {}),
6752
6756
  options.map((opt) => {
6753
6757
  const isSelected = selected.includes(opt);
6754
6758
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
@@ -7931,6 +7935,7 @@ var AdvancedRow = ({
7931
7935
  "text-sm font-regular leading-sm whitespace-nowrap truncate text-left",
7932
7936
  hasValue ? "text-[var(--color-foreground)]" : "text-[var(--color-muted-foreground)]"
7933
7937
  ),
7938
+ title: hasValue ? displayValue : void 0,
7934
7939
  children: hasValue ? displayValue : "Select a value"
7935
7940
  }
7936
7941
  ),
@@ -8358,6 +8363,7 @@ var DraftRow = ({
8358
8363
  // src/components/ui/filter/summary-chip.tsx
8359
8364
  var React52 = __toESM(require("react"));
8360
8365
  var PopoverPrimitive13 = __toESM(require("@radix-ui/react-popover"));
8366
+ var TooltipPrimitive3 = __toESM(require("@radix-ui/react-tooltip"));
8361
8367
  var import_icons37 = require("@l3mpire/icons");
8362
8368
  var import_jsx_runtime59 = require("react/jsx-runtime");
8363
8369
  var ghostBtn2 = [
@@ -8376,7 +8382,8 @@ var SummaryChip = ({
8376
8382
  className,
8377
8383
  open: openProp,
8378
8384
  onOpenChange,
8379
- collisionBoundary
8385
+ collisionBoundary,
8386
+ tooltipContent
8380
8387
  }) => {
8381
8388
  const [uncontrolledOpen, setUncontrolledOpen] = React52.useState(false);
8382
8389
  const isControlled = openProp !== void 0;
@@ -8517,24 +8524,37 @@ var SummaryChip = ({
8517
8524
  node.id
8518
8525
  );
8519
8526
  };
8520
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(PopoverPrimitive13.Root, { open, onOpenChange: setOpen, children: [
8521
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(PopoverPrimitive13.Trigger, { asChild: true, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
8522
- "button",
8527
+ const trigger = children ?? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
8528
+ "button",
8529
+ {
8530
+ type: "button",
8531
+ className: cn(
8532
+ "inline-flex items-center gap-sm px-base py-sm",
8533
+ "min-h-[32px] max-h-[32px]",
8534
+ "bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
8535
+ "border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
8536
+ "cursor-pointer transition-colors",
8537
+ "hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
8538
+ className
8539
+ ),
8540
+ children: [
8541
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_icons37.Icon, { icon: import_icons37.faFilterOutline, size: "sm", className: "shrink-0 text-[var(--color-foreground)]" }),
8542
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-sm font-semibold leading-sm whitespace-nowrap text-[var(--color-foreground)]", children: "Filters" }),
8543
+ count > 0 && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-[10px] font-semibold leading-2xs text-filter-chip-badge-text", children: count }) })
8544
+ ]
8545
+ }
8546
+ );
8547
+ const hasTooltip = tooltipContent && !open;
8548
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TooltipPrimitive3.Provider, { delayDuration: 300, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TooltipPrimitive3.Root, { open: hasTooltip ? void 0 : false, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(PopoverPrimitive13.Root, { open, onOpenChange: setOpen, children: [
8549
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TooltipPrimitive3.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(PopoverPrimitive13.Trigger, { asChild: true, children: trigger }) }),
8550
+ hasTooltip && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TooltipPrimitive3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
8551
+ TooltipPrimitive3.Content,
8523
8552
  {
8524
- type: "button",
8525
- className: cn(
8526
- "inline-flex items-center gap-sm px-base py-sm",
8527
- "min-h-[32px] max-h-[32px]",
8528
- "bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
8529
- "border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
8530
- "cursor-pointer transition-colors",
8531
- "hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
8532
- className
8533
- ),
8553
+ sideOffset: 4,
8554
+ className: "z-50 px-base py-sm rounded-md shadow-lg bg-tooltip-default-bg text-tooltip-default-text text-sm font-regular leading-sm max-w-[320px] data-[state=delayed-open]:animate-[tooltip-in_150ms_ease-out] data-[state=closed]:animate-[tooltip-out_100ms_ease-in]",
8534
8555
  children: [
8535
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_icons37.Icon, { icon: import_icons37.faFilterOutline, size: "sm", className: "shrink-0 text-[var(--color-foreground)]" }),
8536
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-sm font-semibold leading-sm whitespace-nowrap text-[var(--color-foreground)]", children: "Filters" }),
8537
- count > 0 && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-[10px] font-semibold leading-2xs text-filter-chip-badge-text", children: count }) })
8556
+ tooltipContent,
8557
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TooltipPrimitive3.Arrow, { className: "fill-tooltip-default-bg" })
8538
8558
  ]
8539
8559
  }
8540
8560
  ) }),
@@ -8603,7 +8623,7 @@ var SummaryChip = ({
8603
8623
  ]
8604
8624
  }
8605
8625
  ) })
8606
- ] });
8626
+ ] }) }) });
8607
8627
  };
8608
8628
  SummaryChip.displayName = "SummaryChip";
8609
8629
  var DraftRow2 = ({ properties, onSelect, open: openProp, onOpenChange }) => {
@@ -8765,7 +8785,7 @@ var FilterSystem = ({
8765
8785
  const advancedFilterCount = filterState.advancedFilters.length;
8766
8786
  const showAdvancedChip = hasAdvanced || advancedOpen;
8767
8787
  return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(FilterBar, { ref: containerRef, className, children: [
8768
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(FilterBarLeft, { className: "flex-nowrap flex-1 min-w-0 overflow-x-auto scrollbar-none outline-none [&>*]:shrink-0", children: [
8788
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(FilterBarLeft, { className: "flex-wrap flex-1 min-w-0", children: [
8769
8789
  children,
8770
8790
  sortFields && filterState.sort && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8771
8791
  SortButton,
@@ -8794,12 +8814,12 @@ var FilterSystem = ({
8794
8814
  open: summaryOpen,
8795
8815
  onOpenChange: setSummaryOpen,
8796
8816
  collisionBoundary,
8817
+ tooltipContent: totalCount > 0 ? buildFilterTooltip([...filterState.basicFilters, ...filterState.advancedFilters], properties) : void 0,
8797
8818
  children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8798
8819
  FilterBarButton,
8799
8820
  {
8800
8821
  iconOnly: isIconOnly,
8801
- count: totalCount > 0 ? totalCount : void 0,
8802
- title: buildFilterSummary(filterState.basicFilters, filterState.advancedFilters.length, properties)
8822
+ count: totalCount > 0 ? totalCount : void 0
8803
8823
  }
8804
8824
  )
8805
8825
  }
@@ -8876,23 +8896,46 @@ var FilterSystem = ({
8876
8896
  }
8877
8897
  )
8878
8898
  ] }),
8879
- actions && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(FilterBarRight, { className: "shrink-0 -ml-2xl pl-2xl relative z-10 bg-[linear-gradient(to_right,transparent_0px,var(--filter-bar-bg,var(--color-background,#fff))_24px)]", children: actions })
8899
+ actions && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(FilterBarRight, { className: "shrink-0", children: actions })
8880
8900
  ] });
8881
8901
  };
8882
8902
  FilterSystem.displayName = "FilterSystem";
8883
- function buildFilterSummary(filters, advancedCount, properties) {
8884
- if (filters.length === 0 && advancedCount === 0) return void 0;
8885
- const lines = [];
8886
- for (const f of filters) {
8887
- const prop = properties.find((p) => p.id === f.propertyId);
8888
- if (!prop) continue;
8889
- const val = formatFilterValue(f.value, prop.dynamicOptions);
8890
- lines.push(val ? `${prop.label} ${f.operator} ${val}` : `${prop.label} ${f.operator ?? ""}`);
8891
- }
8892
- if (advancedCount > 0) {
8893
- lines.push(`+ ${advancedCount} advanced filter${advancedCount > 1 ? "s" : ""}`);
8894
- }
8895
- return lines.join("\n");
8903
+ function buildFilterTooltip(nodes, properties) {
8904
+ const renderNodes = (items, depth) => {
8905
+ const result = [];
8906
+ for (let i = 0; i < items.length; i++) {
8907
+ const node = items[i];
8908
+ const connector = i > 0 ? (node.logicOperator ?? "and").toUpperCase() : null;
8909
+ if ("children" in node && node.type === "group") {
8910
+ if (connector) {
8911
+ result.push(
8912
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { style: { paddingLeft: depth * 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "opacity-50 text-xs", children: connector }) }, `${node.id}-conn`)
8913
+ );
8914
+ }
8915
+ result.push(...renderNodes(node.children, depth + 1));
8916
+ } else {
8917
+ const f = node;
8918
+ const prop = properties.find((p) => p.id === f.propertyId);
8919
+ if (!prop) continue;
8920
+ const val = formatFilterValue(f.value, prop.dynamicOptions, true);
8921
+ result.push(
8922
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { style: { paddingLeft: depth * 8 }, children: [
8923
+ connector && /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "opacity-50 text-xs", children: [
8924
+ connector,
8925
+ " "
8926
+ ] }),
8927
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "font-semibold", children: prop.label }),
8928
+ " ",
8929
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "opacity-60", children: f.operator }),
8930
+ " ",
8931
+ val && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { children: val })
8932
+ ] }, f.id)
8933
+ );
8934
+ }
8935
+ }
8936
+ return result;
8937
+ };
8938
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "flex flex-col gap-2xs", children: renderNodes(nodes, 0) });
8896
8939
  }
8897
8940
  // Annotate the CommonJS export names for ESM import in node:
8898
8941
  0 && (module.exports = {