@l3mpire/ui 2.18.1 → 2.19.1

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)(
@@ -7805,23 +7809,20 @@ var AdvancedRow = ({
7805
7809
  const badgeCount = getBadgeCount(condition.value);
7806
7810
  const hasValue = displayValue != null;
7807
7811
  return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-base w-full min-w-0", children: [
7808
- connector === "Where" ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: "Where" }) }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
7812
+ connector === "Where" ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: "Where" }) }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
7809
7813
  "button",
7810
7814
  {
7811
7815
  type: "button",
7812
- onClick: onConnectorToggle,
7816
+ disabled: true,
7817
+ title: "Coming soon",
7813
7818
  className: cn(
7814
- "shrink-0 flex items-center justify-center gap-xs",
7819
+ "shrink-0 flex items-center justify-center",
7815
7820
  "min-w-[64px] min-h-[32px] max-h-[32px] px-base py-sm",
7816
7821
  "bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
7817
7822
  "border border-[var(--color-btn-outlined-neutral-border-default)] rounded-base shadow-sm",
7818
- "cursor-pointer transition-colors text-xs font-semibold leading-xs text-[var(--color-foreground)]",
7819
- "hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
7823
+ "text-xs font-semibold leading-xs text-[var(--color-foreground)] opacity-60 cursor-not-allowed"
7820
7824
  ),
7821
- children: [
7822
- connector,
7823
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_icons34.Icon, { icon: import_icons34.faRefreshOutline, size: "xs", className: "text-[var(--color-foreground)]" })
7824
- ]
7825
+ children: connector
7825
7826
  }
7826
7827
  ),
7827
7828
  /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(PopoverPrimitive11.Root, { open: propertyOpen, onOpenChange: setPropertyOpen, children: [
@@ -7931,6 +7932,7 @@ var AdvancedRow = ({
7931
7932
  "text-sm font-regular leading-sm whitespace-nowrap truncate text-left",
7932
7933
  hasValue ? "text-[var(--color-foreground)]" : "text-[var(--color-muted-foreground)]"
7933
7934
  ),
7935
+ title: hasValue ? displayValue : void 0,
7934
7936
  children: hasValue ? displayValue : "Select a value"
7935
7937
  }
7936
7938
  ),
@@ -8010,23 +8012,20 @@ var AdvancedGroup = ({
8010
8012
  }) => {
8011
8013
  const [addOpen, setAddOpen] = React50.useState(false);
8012
8014
  return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-start gap-base w-full min-w-0", children: [
8013
- connector === "Where" ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end pt-base", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: "Where" }) }) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end pt-base", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
8015
+ connector === "Where" ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end pt-base", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: "Where" }) }) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end pt-base", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
8014
8016
  "button",
8015
8017
  {
8016
8018
  type: "button",
8017
- onClick: onConnectorToggle,
8019
+ disabled: true,
8020
+ title: "Coming soon",
8018
8021
  className: cn(
8019
- "flex items-center justify-center gap-xs",
8022
+ "flex items-center justify-center",
8020
8023
  "min-w-[64px] min-h-[32px] max-h-[32px] px-base py-sm",
8021
8024
  "bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
8022
8025
  "border border-[var(--color-btn-outlined-neutral-border-default)] rounded-base shadow-sm",
8023
- "cursor-pointer transition-colors text-xs font-semibold leading-xs text-[var(--color-foreground)]",
8024
- "hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
8026
+ "text-xs font-semibold leading-xs text-[var(--color-foreground)] opacity-60 cursor-not-allowed"
8025
8027
  ),
8026
- children: [
8027
- connector,
8028
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_icons35.Icon, { icon: import_icons35.faRefreshOutline, size: "xs", className: "text-[var(--color-foreground)]" })
8029
- ]
8028
+ children: connector
8030
8029
  }
8031
8030
  ) }),
8032
8031
  /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-base p-base border border-[var(--color-border)] rounded-md bg-[var(--color-secondary,var(--color-accent))]", children: [
@@ -8358,6 +8357,7 @@ var DraftRow = ({
8358
8357
  // src/components/ui/filter/summary-chip.tsx
8359
8358
  var React52 = __toESM(require("react"));
8360
8359
  var PopoverPrimitive13 = __toESM(require("@radix-ui/react-popover"));
8360
+ var TooltipPrimitive3 = __toESM(require("@radix-ui/react-tooltip"));
8361
8361
  var import_icons37 = require("@l3mpire/icons");
8362
8362
  var import_jsx_runtime59 = require("react/jsx-runtime");
8363
8363
  var ghostBtn2 = [
@@ -8376,7 +8376,8 @@ var SummaryChip = ({
8376
8376
  className,
8377
8377
  open: openProp,
8378
8378
  onOpenChange,
8379
- collisionBoundary
8379
+ collisionBoundary,
8380
+ tooltipContent
8380
8381
  }) => {
8381
8382
  const [uncontrolledOpen, setUncontrolledOpen] = React52.useState(false);
8382
8383
  const isControlled = openProp !== void 0;
@@ -8517,24 +8518,37 @@ var SummaryChip = ({
8517
8518
  node.id
8518
8519
  );
8519
8520
  };
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",
8521
+ const trigger = children ?? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
8522
+ "button",
8523
+ {
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
+ ),
8534
+ 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 }) })
8538
+ ]
8539
+ }
8540
+ );
8541
+ const hasTooltip = tooltipContent && !open;
8542
+ 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: [
8543
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TooltipPrimitive3.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(PopoverPrimitive13.Trigger, { asChild: true, children: trigger }) }),
8544
+ hasTooltip && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TooltipPrimitive3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
8545
+ TooltipPrimitive3.Content,
8523
8546
  {
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
- ),
8547
+ sideOffset: 4,
8548
+ 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
8549
  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 }) })
8550
+ tooltipContent,
8551
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(TooltipPrimitive3.Arrow, { className: "fill-tooltip-default-bg" })
8538
8552
  ]
8539
8553
  }
8540
8554
  ) }),
@@ -8603,7 +8617,7 @@ var SummaryChip = ({
8603
8617
  ]
8604
8618
  }
8605
8619
  ) })
8606
- ] });
8620
+ ] }) }) });
8607
8621
  };
8608
8622
  SummaryChip.displayName = "SummaryChip";
8609
8623
  var DraftRow2 = ({ properties, onSelect, open: openProp, onOpenChange }) => {
@@ -8765,7 +8779,7 @@ var FilterSystem = ({
8765
8779
  const advancedFilterCount = filterState.advancedFilters.length;
8766
8780
  const showAdvancedChip = hasAdvanced || advancedOpen;
8767
8781
  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: [
8782
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(FilterBarLeft, { className: "flex-wrap flex-1 min-w-0", children: [
8769
8783
  children,
8770
8784
  sortFields && filterState.sort && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8771
8785
  SortButton,
@@ -8794,12 +8808,12 @@ var FilterSystem = ({
8794
8808
  open: summaryOpen,
8795
8809
  onOpenChange: setSummaryOpen,
8796
8810
  collisionBoundary,
8811
+ tooltipContent: totalCount > 0 ? buildFilterTooltip([...filterState.basicFilters, ...filterState.advancedFilters], properties) : void 0,
8797
8812
  children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8798
8813
  FilterBarButton,
8799
8814
  {
8800
8815
  iconOnly: isIconOnly,
8801
- count: totalCount > 0 ? totalCount : void 0,
8802
- title: buildFilterSummary(filterState.basicFilters, filterState.advancedFilters.length, properties)
8816
+ count: totalCount > 0 ? totalCount : void 0
8803
8817
  }
8804
8818
  )
8805
8819
  }
@@ -8876,23 +8890,46 @@ var FilterSystem = ({
8876
8890
  }
8877
8891
  )
8878
8892
  ] }),
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 })
8893
+ actions && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(FilterBarRight, { className: "shrink-0", children: actions })
8880
8894
  ] });
8881
8895
  };
8882
8896
  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");
8897
+ function buildFilterTooltip(nodes, properties) {
8898
+ const renderNodes = (items, depth) => {
8899
+ const result = [];
8900
+ for (let i = 0; i < items.length; i++) {
8901
+ const node = items[i];
8902
+ const connector = i > 0 ? (node.logicOperator ?? "and").toUpperCase() : null;
8903
+ if ("children" in node && node.type === "group") {
8904
+ if (connector) {
8905
+ result.push(
8906
+ /* @__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`)
8907
+ );
8908
+ }
8909
+ result.push(...renderNodes(node.children, depth + 1));
8910
+ } else {
8911
+ const f = node;
8912
+ const prop = properties.find((p) => p.id === f.propertyId);
8913
+ if (!prop) continue;
8914
+ const val = formatFilterValue(f.value, prop.dynamicOptions, true);
8915
+ result.push(
8916
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { style: { paddingLeft: depth * 8 }, children: [
8917
+ connector && /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "opacity-50 text-xs", children: [
8918
+ connector,
8919
+ " "
8920
+ ] }),
8921
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "font-semibold", children: prop.label }),
8922
+ " ",
8923
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "opacity-60", children: f.operator }),
8924
+ " ",
8925
+ val && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { children: val })
8926
+ ] }, f.id)
8927
+ );
8928
+ }
8929
+ }
8930
+ return result;
8931
+ };
8932
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "flex flex-col gap-2xs", children: renderNodes(nodes, 0) });
8896
8933
  }
8897
8934
  // Annotate the CommonJS export names for ESM import in node:
8898
8935
  0 && (module.exports = {