@l3mpire/ui 2.18.0 → 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.mjs CHANGED
@@ -5211,7 +5211,7 @@ var DEFAULT_OPERATOR_BY_TYPE = {
5211
5211
  text: "contains",
5212
5212
  number: "=",
5213
5213
  date: "is between",
5214
- enum: "is",
5214
+ enum: "is any of",
5215
5215
  tags: "contains",
5216
5216
  boolean: "is true",
5217
5217
  relation: "is"
@@ -5248,7 +5248,7 @@ function getValueInputType(type, operator) {
5248
5248
  return ["is any of", "is none of"].includes(operator) ? "MultiRelationPicker" : "RelationPicker";
5249
5249
  return null;
5250
5250
  }
5251
- function formatFilterValue(value, dynamicOptions) {
5251
+ function formatFilterValue(value, dynamicOptions, full) {
5252
5252
  if (value == null) return void 0;
5253
5253
  if (typeof value === "boolean") return value ? "Yes" : "No";
5254
5254
  if (value instanceof Date) {
@@ -5267,6 +5267,9 @@ function formatFilterValue(value, dynamicOptions) {
5267
5267
  const fmt = (d) => d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
5268
5268
  return `${fmt(value[0])} \u2013 ${value[1] instanceof Date ? fmt(value[1]) : "\u2026"}`;
5269
5269
  }
5270
+ if (full) {
5271
+ return value.map((v) => resolveDynamic(String(v), dynamicOptions)).join(", ");
5272
+ }
5270
5273
  const resolved = resolveDynamic(String(value[0]), dynamicOptions);
5271
5274
  return resolved;
5272
5275
  }
@@ -5407,7 +5410,7 @@ var FilterBar = React38.forwardRef(
5407
5410
  {
5408
5411
  ref,
5409
5412
  className: cn(
5410
- "flex items-center justify-between w-full",
5413
+ "flex items-start justify-between w-full",
5411
5414
  className
5412
5415
  ),
5413
5416
  role: "toolbar",
@@ -6460,7 +6463,9 @@ var DateCalendarValueInput = ({
6460
6463
  if (isRange) {
6461
6464
  if (Array.isArray(value) && value.length === 2) {
6462
6465
  const [from, to] = value;
6463
- return { from, to };
6466
+ if (from instanceof Date) {
6467
+ return { from, to: to instanceof Date ? to : void 0 };
6468
+ }
6464
6469
  }
6465
6470
  return void 0;
6466
6471
  }
@@ -6475,7 +6480,7 @@ var DateCalendarValueInput = ({
6475
6480
  if (range.from && range.to) {
6476
6481
  onChange([range.from, range.to]);
6477
6482
  } else if (range.from) {
6478
- onChange([range.from, range.from]);
6483
+ onChange([range.from, null]);
6479
6484
  }
6480
6485
  }
6481
6486
  };
@@ -6645,7 +6650,6 @@ var MultiSelectValueInput = ({
6645
6650
  },
6646
6651
  opt.value
6647
6652
  )),
6648
- dynamicOptions && dynamicOptions.length > 0 && options.length > 0 && /* @__PURE__ */ jsx47(DynamicOptionsDivider, {}),
6649
6653
  options.map((opt) => {
6650
6654
  const isSelected = selected.includes(opt);
6651
6655
  return /* @__PURE__ */ jsxs42(
@@ -7805,6 +7809,27 @@ var AdvancedRow = ({
7805
7809
  ] }),
7806
7810
  condition.operator && !isNoValueOperator(condition.operator) && (() => {
7807
7811
  const inputType = getValueInputType(propertyDef.type, condition.operator);
7812
+ const isInline = inputType === "TextInput" || inputType === "NumberInput";
7813
+ if (isInline) {
7814
+ return /* @__PURE__ */ jsx56(
7815
+ "input",
7816
+ {
7817
+ type: inputType === "NumberInput" ? "number" : "text",
7818
+ value: condition.value ?? "",
7819
+ onChange: (e) => handleValueChange(
7820
+ inputType === "NumberInput" ? e.target.value === "" ? null : Number(e.target.value) : e.target.value
7821
+ ),
7822
+ placeholder: "Enter value...",
7823
+ className: cn(
7824
+ "flex-1 min-w-[80px] px-base py-sm",
7825
+ "bg-[var(--color-background)] border border-[var(--color-input)] rounded-base",
7826
+ "text-sm font-regular leading-sm text-[var(--color-foreground)]",
7827
+ "placeholder:text-[var(--color-muted-foreground)]",
7828
+ "focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)] focus:ring-offset-0"
7829
+ )
7830
+ }
7831
+ );
7832
+ }
7808
7833
  const dateWide = inputType === "DatePicker" || inputType === "DateRange";
7809
7834
  return /* @__PURE__ */ jsxs50(PopoverPrimitive11.Root, { open: valueOpen, onOpenChange: setValueOpen, children: [
7810
7835
  /* @__PURE__ */ jsx56(PopoverPrimitive11.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs50(
@@ -7820,7 +7845,8 @@ var AdvancedRow = ({
7820
7845
  "text-sm font-regular leading-sm whitespace-nowrap truncate text-left",
7821
7846
  hasValue ? "text-[var(--color-foreground)]" : "text-[var(--color-muted-foreground)]"
7822
7847
  ),
7823
- children: hasValue ? displayValue : "Enter a value"
7848
+ title: hasValue ? displayValue : void 0,
7849
+ children: hasValue ? displayValue : "Select a value"
7824
7850
  }
7825
7851
  ),
7826
7852
  /* @__PURE__ */ jsxs50("span", { className: "flex items-center gap-xs shrink-0", children: [
@@ -8247,6 +8273,7 @@ var DraftRow = ({
8247
8273
  // src/components/ui/filter/summary-chip.tsx
8248
8274
  import * as React52 from "react";
8249
8275
  import * as PopoverPrimitive13 from "@radix-ui/react-popover";
8276
+ import * as TooltipPrimitive3 from "@radix-ui/react-tooltip";
8250
8277
  import { Icon as Icon36, faFilterOutline as faFilterOutline6, faPlusOutline as faPlusOutline4, faChevronDownOutline as faChevronDownOutline4, faXmarkOutline as faXmarkOutline5 } from "@l3mpire/icons";
8251
8278
  import { jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
8252
8279
  var ghostBtn2 = [
@@ -8265,7 +8292,8 @@ var SummaryChip = ({
8265
8292
  className,
8266
8293
  open: openProp,
8267
8294
  onOpenChange,
8268
- collisionBoundary
8295
+ collisionBoundary,
8296
+ tooltipContent
8269
8297
  }) => {
8270
8298
  const [uncontrolledOpen, setUncontrolledOpen] = React52.useState(false);
8271
8299
  const isControlled = openProp !== void 0;
@@ -8406,24 +8434,37 @@ var SummaryChip = ({
8406
8434
  node.id
8407
8435
  );
8408
8436
  };
8409
- return /* @__PURE__ */ jsxs53(PopoverPrimitive13.Root, { open, onOpenChange: setOpen, children: [
8410
- /* @__PURE__ */ jsx59(PopoverPrimitive13.Trigger, { asChild: true, children: children ?? /* @__PURE__ */ jsxs53(
8411
- "button",
8437
+ const trigger = children ?? /* @__PURE__ */ jsxs53(
8438
+ "button",
8439
+ {
8440
+ type: "button",
8441
+ className: cn(
8442
+ "inline-flex items-center gap-sm px-base py-sm",
8443
+ "min-h-[32px] max-h-[32px]",
8444
+ "bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
8445
+ "border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
8446
+ "cursor-pointer transition-colors",
8447
+ "hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
8448
+ className
8449
+ ),
8450
+ children: [
8451
+ /* @__PURE__ */ jsx59(Icon36, { icon: faFilterOutline6, size: "sm", className: "shrink-0 text-[var(--color-foreground)]" }),
8452
+ /* @__PURE__ */ jsx59("span", { className: "text-sm font-semibold leading-sm whitespace-nowrap text-[var(--color-foreground)]", children: "Filters" }),
8453
+ count > 0 && /* @__PURE__ */ jsx59("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ jsx59("span", { className: "text-[10px] font-semibold leading-2xs text-filter-chip-badge-text", children: count }) })
8454
+ ]
8455
+ }
8456
+ );
8457
+ const hasTooltip = tooltipContent && !open;
8458
+ return /* @__PURE__ */ jsx59(TooltipPrimitive3.Provider, { delayDuration: 300, children: /* @__PURE__ */ jsx59(TooltipPrimitive3.Root, { open: hasTooltip ? void 0 : false, children: /* @__PURE__ */ jsxs53(PopoverPrimitive13.Root, { open, onOpenChange: setOpen, children: [
8459
+ /* @__PURE__ */ jsx59(TooltipPrimitive3.Trigger, { asChild: true, children: /* @__PURE__ */ jsx59(PopoverPrimitive13.Trigger, { asChild: true, children: trigger }) }),
8460
+ hasTooltip && /* @__PURE__ */ jsx59(TooltipPrimitive3.Portal, { children: /* @__PURE__ */ jsxs53(
8461
+ TooltipPrimitive3.Content,
8412
8462
  {
8413
- type: "button",
8414
- className: cn(
8415
- "inline-flex items-center gap-sm px-base py-sm",
8416
- "min-h-[32px] max-h-[32px]",
8417
- "bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
8418
- "border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
8419
- "cursor-pointer transition-colors",
8420
- "hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
8421
- className
8422
- ),
8463
+ sideOffset: 4,
8464
+ 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]",
8423
8465
  children: [
8424
- /* @__PURE__ */ jsx59(Icon36, { icon: faFilterOutline6, size: "sm", className: "shrink-0 text-[var(--color-foreground)]" }),
8425
- /* @__PURE__ */ jsx59("span", { className: "text-sm font-semibold leading-sm whitespace-nowrap text-[var(--color-foreground)]", children: "Filters" }),
8426
- count > 0 && /* @__PURE__ */ jsx59("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ jsx59("span", { className: "text-[10px] font-semibold leading-2xs text-filter-chip-badge-text", children: count }) })
8466
+ tooltipContent,
8467
+ /* @__PURE__ */ jsx59(TooltipPrimitive3.Arrow, { className: "fill-tooltip-default-bg" })
8427
8468
  ]
8428
8469
  }
8429
8470
  ) }),
@@ -8492,7 +8533,7 @@ var SummaryChip = ({
8492
8533
  ]
8493
8534
  }
8494
8535
  ) })
8495
- ] });
8536
+ ] }) }) });
8496
8537
  };
8497
8538
  SummaryChip.displayName = "SummaryChip";
8498
8539
  var DraftRow2 = ({ properties, onSelect, open: openProp, onOpenChange }) => {
@@ -8654,7 +8695,7 @@ var FilterSystem = ({
8654
8695
  const advancedFilterCount = filterState.advancedFilters.length;
8655
8696
  const showAdvancedChip = hasAdvanced || advancedOpen;
8656
8697
  return /* @__PURE__ */ jsxs54(FilterBar, { ref: containerRef, className, children: [
8657
- /* @__PURE__ */ jsxs54(FilterBarLeft, { className: "flex-nowrap flex-1 min-w-0 overflow-x-auto scrollbar-none outline-none [&>*]:shrink-0", children: [
8698
+ /* @__PURE__ */ jsxs54(FilterBarLeft, { className: "flex-wrap flex-1 min-w-0", children: [
8658
8699
  children,
8659
8700
  sortFields && filterState.sort && /* @__PURE__ */ jsx60(
8660
8701
  SortButton,
@@ -8683,12 +8724,12 @@ var FilterSystem = ({
8683
8724
  open: summaryOpen,
8684
8725
  onOpenChange: setSummaryOpen,
8685
8726
  collisionBoundary,
8727
+ tooltipContent: totalCount > 0 ? buildFilterTooltip([...filterState.basicFilters, ...filterState.advancedFilters], properties) : void 0,
8686
8728
  children: /* @__PURE__ */ jsx60(
8687
8729
  FilterBarButton,
8688
8730
  {
8689
8731
  iconOnly: isIconOnly,
8690
- count: totalCount > 0 ? totalCount : void 0,
8691
- title: buildFilterSummary(filterState.basicFilters, filterState.advancedFilters.length, properties)
8732
+ count: totalCount > 0 ? totalCount : void 0
8692
8733
  }
8693
8734
  )
8694
8735
  }
@@ -8765,23 +8806,46 @@ var FilterSystem = ({
8765
8806
  }
8766
8807
  )
8767
8808
  ] }),
8768
- actions && /* @__PURE__ */ jsx60(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 })
8809
+ actions && /* @__PURE__ */ jsx60(FilterBarRight, { className: "shrink-0", children: actions })
8769
8810
  ] });
8770
8811
  };
8771
8812
  FilterSystem.displayName = "FilterSystem";
8772
- function buildFilterSummary(filters, advancedCount, properties) {
8773
- if (filters.length === 0 && advancedCount === 0) return void 0;
8774
- const lines = [];
8775
- for (const f of filters) {
8776
- const prop = properties.find((p) => p.id === f.propertyId);
8777
- if (!prop) continue;
8778
- const val = formatFilterValue(f.value, prop.dynamicOptions);
8779
- lines.push(val ? `${prop.label} ${f.operator} ${val}` : `${prop.label} ${f.operator ?? ""}`);
8780
- }
8781
- if (advancedCount > 0) {
8782
- lines.push(`+ ${advancedCount} advanced filter${advancedCount > 1 ? "s" : ""}`);
8783
- }
8784
- return lines.join("\n");
8813
+ function buildFilterTooltip(nodes, properties) {
8814
+ const renderNodes = (items, depth) => {
8815
+ const result = [];
8816
+ for (let i = 0; i < items.length; i++) {
8817
+ const node = items[i];
8818
+ const connector = i > 0 ? (node.logicOperator ?? "and").toUpperCase() : null;
8819
+ if ("children" in node && node.type === "group") {
8820
+ if (connector) {
8821
+ result.push(
8822
+ /* @__PURE__ */ jsx60("div", { style: { paddingLeft: depth * 8 }, children: /* @__PURE__ */ jsx60("span", { className: "opacity-50 text-xs", children: connector }) }, `${node.id}-conn`)
8823
+ );
8824
+ }
8825
+ result.push(...renderNodes(node.children, depth + 1));
8826
+ } else {
8827
+ const f = node;
8828
+ const prop = properties.find((p) => p.id === f.propertyId);
8829
+ if (!prop) continue;
8830
+ const val = formatFilterValue(f.value, prop.dynamicOptions, true);
8831
+ result.push(
8832
+ /* @__PURE__ */ jsxs54("div", { style: { paddingLeft: depth * 8 }, children: [
8833
+ connector && /* @__PURE__ */ jsxs54("span", { className: "opacity-50 text-xs", children: [
8834
+ connector,
8835
+ " "
8836
+ ] }),
8837
+ /* @__PURE__ */ jsx60("span", { className: "font-semibold", children: prop.label }),
8838
+ " ",
8839
+ /* @__PURE__ */ jsx60("span", { className: "opacity-60", children: f.operator }),
8840
+ " ",
8841
+ val && /* @__PURE__ */ jsx60("span", { children: val })
8842
+ ] }, f.id)
8843
+ );
8844
+ }
8845
+ }
8846
+ return result;
8847
+ };
8848
+ return /* @__PURE__ */ jsx60("div", { className: "flex flex-col gap-2xs", children: renderNodes(nodes, 0) });
8785
8849
  }
8786
8850
  export {
8787
8851
  AdvancedChip,