@l3mpire/ui 2.8.0 → 2.9.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/USAGE.md +13 -4
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +157 -132
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +160 -135
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/USAGE.md
CHANGED
|
@@ -875,13 +875,13 @@ import {
|
|
|
875
875
|
type FilterState, type PropertyDefinition, type SortField,
|
|
876
876
|
} from "@l3mpire/ui";
|
|
877
877
|
|
|
878
|
-
// Full interactive system (manages state
|
|
878
|
+
// Full interactive system (manages state, Clear button, responsive)
|
|
879
879
|
<FilterSystem
|
|
880
880
|
properties={PROPERTIES}
|
|
881
881
|
filterState={filterState}
|
|
882
882
|
onFilterStateChange={setFilterState}
|
|
883
883
|
sortFields={SORT_FIELDS}
|
|
884
|
-
actions={
|
|
884
|
+
actions={<SaveViewButton />}
|
|
885
885
|
>
|
|
886
886
|
<SearchBar size="sm" className="w-[200px]" />
|
|
887
887
|
</FilterSystem>
|
|
@@ -909,9 +909,18 @@ import {
|
|
|
909
909
|
| `FilterChip` | Presentational segmented chip |
|
|
910
910
|
| `InteractiveFilterChip` | FilterChip with per-segment popovers (property, operator, value, kebab) |
|
|
911
911
|
| `PropertySelector` | 2-level popover: categories → properties with search |
|
|
912
|
-
| `AdvancedChip` | "Advanced
|
|
913
|
-
| `AdvancedPopover` |
|
|
912
|
+
| `AdvancedChip` | Split button "Advanced filters (N)" + close (outlined neutral) |
|
|
913
|
+
| `AdvancedPopover` | Popover with Where/And/Or rows, property/operator selects, inline value input |
|
|
914
914
|
| `SaveViewButton` | Split button (Save view + dropdown chevron) |
|
|
915
|
+
| `SummaryChip` | Minimal mode: "Filters (N)" with interactive popover |
|
|
916
|
+
|
|
917
|
+
**Responsive:** FilterSystem auto-detects container width via `ResizeObserver`:
|
|
918
|
+
- **Default** (>600px): full chips, labels, "Filters" button
|
|
919
|
+
- **Minimal** (≤600px): SummaryChip "Filters (N)" with interactive popover, icon-only Sort/Filter buttons
|
|
920
|
+
|
|
921
|
+
**Built-in Clear:** appears automatically when filters are active ("Clear" text in default, × icon in minimal).
|
|
922
|
+
|
|
923
|
+
**And/Or toggle:** each row in the advanced popover has an independent And/Or toggle button (click to switch).
|
|
915
924
|
|
|
916
925
|
| Utility | Purpose |
|
|
917
926
|
|---|---|
|
package/dist/index.d.mts
CHANGED
|
@@ -883,8 +883,10 @@ interface AdvancedChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement
|
|
|
883
883
|
declare const AdvancedChip: React.ForwardRefExoticComponent<AdvancedChipProps & React.RefAttributes<HTMLButtonElement>>;
|
|
884
884
|
|
|
885
885
|
interface AdvancedRowProps {
|
|
886
|
-
/** "Where" for the first row, "And" for subsequent. */
|
|
887
|
-
connector: "Where" | "And";
|
|
886
|
+
/** "Where" for the first row, "And"/"Or" for subsequent. */
|
|
887
|
+
connector: "Where" | "And" | "Or";
|
|
888
|
+
/** Called when the And/Or toggle is clicked. */
|
|
889
|
+
onConnectorToggle?: () => void;
|
|
888
890
|
propertyDef: PropertyDefinition;
|
|
889
891
|
condition: FilterCondition;
|
|
890
892
|
properties: PropertyDefinition[];
|
package/dist/index.d.ts
CHANGED
|
@@ -883,8 +883,10 @@ interface AdvancedChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement
|
|
|
883
883
|
declare const AdvancedChip: React.ForwardRefExoticComponent<AdvancedChipProps & React.RefAttributes<HTMLButtonElement>>;
|
|
884
884
|
|
|
885
885
|
interface AdvancedRowProps {
|
|
886
|
-
/** "Where" for the first row, "And" for subsequent. */
|
|
887
|
-
connector: "Where" | "And";
|
|
886
|
+
/** "Where" for the first row, "And"/"Or" for subsequent. */
|
|
887
|
+
connector: "Where" | "And" | "Or";
|
|
888
|
+
/** Called when the And/Or toggle is clicked. */
|
|
889
|
+
onConnectorToggle?: () => void;
|
|
888
890
|
propertyDef: PropertyDefinition;
|
|
889
891
|
condition: FilterCondition;
|
|
890
892
|
properties: PropertyDefinition[];
|
package/dist/index.js
CHANGED
|
@@ -6428,68 +6428,82 @@ InteractiveFilterChip.displayName = "InteractiveFilterChip";
|
|
|
6428
6428
|
|
|
6429
6429
|
// src/components/ui/filter/filter-system.tsx
|
|
6430
6430
|
var React48 = __toESM(require("react"));
|
|
6431
|
+
var import_icons34 = require("@l3mpire/icons");
|
|
6431
6432
|
|
|
6432
6433
|
// src/components/ui/filter/advanced-chip.tsx
|
|
6433
6434
|
var React43 = __toESM(require("react"));
|
|
6434
6435
|
var import_icons30 = require("@l3mpire/icons");
|
|
6435
6436
|
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
6437
|
+
var btnBase = [
|
|
6438
|
+
"flex items-center justify-center",
|
|
6439
|
+
"min-h-[32px] max-h-[32px]",
|
|
6440
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
6441
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] shadow-sm",
|
|
6442
|
+
"cursor-pointer transition-colors",
|
|
6443
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
6444
|
+
];
|
|
6436
6445
|
var AdvancedChip = React43.forwardRef(
|
|
6437
|
-
({ className, count, onClear, onClick, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
"
|
|
6448
|
-
{
|
|
6449
|
-
ref,
|
|
6450
|
-
type: "button",
|
|
6451
|
-
onClick,
|
|
6452
|
-
className: "flex items-center gap-sm px-base py-sm cursor-pointer transition-colors hover:bg-[var(--color-primary)]/10",
|
|
6453
|
-
...props,
|
|
6454
|
-
children: [
|
|
6455
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-medium leading-sm whitespace-nowrap text-[var(--color-primary)]", children: "Advanced filter" }),
|
|
6456
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-[10px] font-medium leading-2xs text-filter-chip-badge-text", children: count }) })
|
|
6457
|
-
]
|
|
6458
|
-
}
|
|
6446
|
+
({ className, count, onClear, onClick, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cn("inline-flex items-center", className), children: [
|
|
6447
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
6448
|
+
"button",
|
|
6449
|
+
{
|
|
6450
|
+
ref,
|
|
6451
|
+
type: "button",
|
|
6452
|
+
onClick,
|
|
6453
|
+
className: cn(
|
|
6454
|
+
btnBase,
|
|
6455
|
+
"gap-sm px-base py-sm min-w-[80px]",
|
|
6456
|
+
"rounded-l-md -mr-px"
|
|
6459
6457
|
),
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6458
|
+
...props,
|
|
6459
|
+
children: [
|
|
6460
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-medium leading-sm whitespace-nowrap text-[var(--color-foreground)]", children: "Advanced filters" }),
|
|
6461
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-[10px] font-medium leading-2xs text-filter-chip-badge-text", children: count }) })
|
|
6462
|
+
]
|
|
6463
|
+
}
|
|
6464
|
+
),
|
|
6465
|
+
onClear && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6466
|
+
"button",
|
|
6467
|
+
{
|
|
6468
|
+
type: "button",
|
|
6469
|
+
onClick: (e) => {
|
|
6470
|
+
e.stopPropagation();
|
|
6471
|
+
onClear();
|
|
6472
|
+
},
|
|
6473
|
+
className: cn(
|
|
6474
|
+
btnBase,
|
|
6475
|
+
"p-sm",
|
|
6476
|
+
"rounded-r-md -ml-px"
|
|
6477
|
+
),
|
|
6478
|
+
"aria-label": "Clear all advanced filters",
|
|
6479
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_icons30.Icon, { icon: import_icons30.faXmarkOutline, size: "sm", className: "text-[var(--color-foreground)]" })
|
|
6480
|
+
}
|
|
6481
|
+
)
|
|
6482
|
+
] })
|
|
6479
6483
|
);
|
|
6480
6484
|
AdvancedChip.displayName = "AdvancedChip";
|
|
6481
6485
|
|
|
6482
6486
|
// src/components/ui/filter/advanced-popover.tsx
|
|
6483
6487
|
var React45 = __toESM(require("react"));
|
|
6484
6488
|
var PopoverPrimitive10 = __toESM(require("@radix-ui/react-popover"));
|
|
6489
|
+
var import_icons32 = require("@l3mpire/icons");
|
|
6485
6490
|
|
|
6486
6491
|
// src/components/ui/filter/advanced-row.tsx
|
|
6487
6492
|
var React44 = __toESM(require("react"));
|
|
6488
6493
|
var PopoverPrimitive9 = __toESM(require("@radix-ui/react-popover"));
|
|
6489
6494
|
var import_icons31 = require("@l3mpire/icons");
|
|
6490
6495
|
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
6496
|
+
var selectBtnStyle = [
|
|
6497
|
+
"flex items-center gap-base",
|
|
6498
|
+
"px-base py-sm",
|
|
6499
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
6500
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
6501
|
+
"cursor-pointer transition-colors",
|
|
6502
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
6503
|
+
];
|
|
6491
6504
|
var AdvancedRow = ({
|
|
6492
6505
|
connector,
|
|
6506
|
+
onConnectorToggle,
|
|
6493
6507
|
propertyDef,
|
|
6494
6508
|
condition,
|
|
6495
6509
|
properties,
|
|
@@ -6498,7 +6512,6 @@ var AdvancedRow = ({
|
|
|
6498
6512
|
onDelete
|
|
6499
6513
|
}) => {
|
|
6500
6514
|
const [operatorOpen, setOperatorOpen] = React44.useState(false);
|
|
6501
|
-
const [valueOpen, setValueOpen] = React44.useState(false);
|
|
6502
6515
|
const [propertyOpen, setPropertyOpen] = React44.useState(false);
|
|
6503
6516
|
const handleOperatorSelect = (op) => {
|
|
6504
6517
|
if (isNoValueOperator(op)) {
|
|
@@ -6513,46 +6526,36 @@ var AdvancedRow = ({
|
|
|
6513
6526
|
onUpdate({ ...condition, value: val });
|
|
6514
6527
|
};
|
|
6515
6528
|
const displayValue = condition.value == null ? "" : typeof condition.value === "string" ? condition.value : String(condition.value);
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
const arr = map.get(p.group) ?? [];
|
|
6520
|
-
arr.push(p);
|
|
6521
|
-
map.set(p.group, arr);
|
|
6522
|
-
}
|
|
6523
|
-
return map;
|
|
6524
|
-
}, [properties]);
|
|
6525
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "group flex items-center gap-base py-xs", children: [
|
|
6526
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
6527
|
-
"span",
|
|
6529
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-base w-full", children: [
|
|
6530
|
+
connector === "Where" ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-xs font-medium leading-xs text-[var(--color-muted-foreground)]", children: "Where" }) }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
6531
|
+
"button",
|
|
6528
6532
|
{
|
|
6533
|
+
type: "button",
|
|
6534
|
+
onClick: onConnectorToggle,
|
|
6529
6535
|
className: cn(
|
|
6530
|
-
"shrink-0
|
|
6531
|
-
|
|
6536
|
+
"shrink-0 flex items-center justify-center gap-xs",
|
|
6537
|
+
"min-w-[64px] min-h-[24px] max-h-[24px] p-xs",
|
|
6538
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
6539
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-base shadow-sm",
|
|
6540
|
+
"cursor-pointer transition-colors text-xs font-medium leading-xs text-[var(--color-foreground)]",
|
|
6541
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
6532
6542
|
),
|
|
6533
|
-
children:
|
|
6543
|
+
children: [
|
|
6534
6544
|
connector,
|
|
6535
|
-
|
|
6536
|
-
]
|
|
6545
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_icons31.Icon, { icon: import_icons31.faRefreshOutline, size: "xs", className: "text-[var(--color-foreground)]" })
|
|
6546
|
+
]
|
|
6537
6547
|
}
|
|
6538
6548
|
),
|
|
6539
6549
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(PopoverPrimitive9.Root, { open: propertyOpen, onOpenChange: setPropertyOpen, children: [
|
|
6540
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverPrimitive9.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
6541
|
-
"
|
|
6542
|
-
{
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
" \u203A ",
|
|
6550
|
-
propertyDef.label
|
|
6551
|
-
] }),
|
|
6552
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "currentColor", className: "text-[var(--color-muted-foreground)]", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "M2.5 4L5 6.5L7.5 4", stroke: "currentColor", strokeWidth: "1.2", fill: "none", strokeLinecap: "round" }) })
|
|
6553
|
-
]
|
|
6554
|
-
}
|
|
6555
|
-
) }),
|
|
6550
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverPrimitive9.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("button", { type: "button", className: cn(selectBtnStyle, "shrink-0 min-w-[80px]"), children: [
|
|
6551
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_icons31.Icon, { icon: propertyDef.icon, size: "sm", className: "shrink-0 text-[var(--color-muted-foreground)]" }),
|
|
6552
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)] whitespace-nowrap", children: [
|
|
6553
|
+
propertyDef.groupLabel,
|
|
6554
|
+
" > ",
|
|
6555
|
+
propertyDef.label
|
|
6556
|
+
] }),
|
|
6557
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_icons31.Icon, { icon: import_icons31.faChevronDownOutline, size: "xs", className: "shrink-0 text-[var(--color-foreground)]" })
|
|
6558
|
+
] }) }),
|
|
6556
6559
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverPrimitive9.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
6557
6560
|
PopoverPrimitive9.Content,
|
|
6558
6561
|
{
|
|
@@ -6565,7 +6568,7 @@ var AdvancedRow = ({
|
|
|
6565
6568
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
|
|
6566
6569
|
"min-w-[200px]"
|
|
6567
6570
|
),
|
|
6568
|
-
children:
|
|
6571
|
+
children: properties.map((p) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
6569
6572
|
"button",
|
|
6570
6573
|
{
|
|
6571
6574
|
type: "button",
|
|
@@ -6584,22 +6587,15 @@ var AdvancedRow = ({
|
|
|
6584
6587
|
]
|
|
6585
6588
|
},
|
|
6586
6589
|
p.id
|
|
6587
|
-
))
|
|
6590
|
+
))
|
|
6588
6591
|
}
|
|
6589
6592
|
) })
|
|
6590
6593
|
] }),
|
|
6591
6594
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(PopoverPrimitive9.Root, { open: operatorOpen, onOpenChange: setOperatorOpen, children: [
|
|
6592
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverPrimitive9.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
6593
|
-
"
|
|
6594
|
-
{
|
|
6595
|
-
|
|
6596
|
-
className: "flex items-center gap-xs px-base py-sm rounded-base border border-[var(--color-input)] bg-[var(--color-background)] cursor-pointer hover:bg-[var(--color-accent)] transition-colors",
|
|
6597
|
-
children: [
|
|
6598
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)] whitespace-nowrap", children: condition.operator ?? "select" }),
|
|
6599
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "currentColor", className: "text-[var(--color-muted-foreground)]", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "M2.5 4L5 6.5L7.5 4", stroke: "currentColor", strokeWidth: "1.2", fill: "none", strokeLinecap: "round" }) })
|
|
6600
|
-
]
|
|
6601
|
-
}
|
|
6602
|
-
) }),
|
|
6595
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverPrimitive9.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("button", { type: "button", className: cn(selectBtnStyle, "shrink-0 w-[103px]"), children: [
|
|
6596
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-[var(--color-foreground)] whitespace-nowrap text-left", children: condition.operator ?? "Select" }),
|
|
6597
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_icons31.Icon, { icon: import_icons31.faChevronDownOutline, size: "xs", className: "shrink-0 text-[var(--color-foreground)]" })
|
|
6598
|
+
] }) }),
|
|
6603
6599
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverPrimitive9.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
6604
6600
|
PopoverPrimitive9.Content,
|
|
6605
6601
|
{
|
|
@@ -6629,9 +6625,10 @@ var AdvancedRow = ({
|
|
|
6629
6625
|
type: "text",
|
|
6630
6626
|
value: displayValue,
|
|
6631
6627
|
onChange: (e) => handleValueChange(e.target.value),
|
|
6632
|
-
placeholder: "
|
|
6628
|
+
placeholder: "Placeholder",
|
|
6633
6629
|
className: cn(
|
|
6634
|
-
"
|
|
6630
|
+
"w-[160px] shrink-0 px-base py-sm rounded-md",
|
|
6631
|
+
"border border-[var(--color-input)]",
|
|
6635
6632
|
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
6636
6633
|
"placeholder:text-[var(--color-muted-foreground)]",
|
|
6637
6634
|
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)] focus:ring-offset-0"
|
|
@@ -6643,9 +6640,9 @@ var AdvancedRow = ({
|
|
|
6643
6640
|
{
|
|
6644
6641
|
type: "button",
|
|
6645
6642
|
onClick: onDelete,
|
|
6646
|
-
className: "shrink-0 flex items-center justify-center p-sm rounded-
|
|
6643
|
+
className: "ml-auto shrink-0 flex items-center justify-center p-sm rounded-md cursor-pointer transition-colors hover:bg-[var(--color-accent)]",
|
|
6647
6644
|
"aria-label": "Remove filter",
|
|
6648
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_icons31.Icon, { icon: import_icons31.
|
|
6645
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_icons31.Icon, { icon: import_icons31.faXmarkOutline, size: "sm", className: "text-[var(--color-foreground)]" })
|
|
6649
6646
|
}
|
|
6650
6647
|
)
|
|
6651
6648
|
] });
|
|
@@ -6654,6 +6651,14 @@ AdvancedRow.displayName = "AdvancedRow";
|
|
|
6654
6651
|
|
|
6655
6652
|
// src/components/ui/filter/advanced-popover.tsx
|
|
6656
6653
|
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
6654
|
+
var outlinedBtn = [
|
|
6655
|
+
"flex items-center gap-sm px-base py-sm",
|
|
6656
|
+
"min-h-[32px] max-h-[32px] min-w-[80px]",
|
|
6657
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
6658
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
6659
|
+
"cursor-pointer transition-colors text-sm font-medium leading-sm text-[var(--color-foreground)]",
|
|
6660
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
6661
|
+
];
|
|
6657
6662
|
var AdvancedPopover = ({
|
|
6658
6663
|
filters,
|
|
6659
6664
|
properties,
|
|
@@ -6663,6 +6668,7 @@ var AdvancedPopover = ({
|
|
|
6663
6668
|
children
|
|
6664
6669
|
}) => {
|
|
6665
6670
|
const [addSelectorOpen, setAddSelectorOpen] = React45.useState(false);
|
|
6671
|
+
const [logicOps, setLogicOps] = React45.useState({});
|
|
6666
6672
|
const getPropertyDef = (propertyId) => properties.find((p) => p.id === propertyId);
|
|
6667
6673
|
const handleUpdateFilter = (updated) => {
|
|
6668
6674
|
onFiltersChange(filters.map((f) => f.id === updated.id ? updated : f));
|
|
@@ -6685,6 +6691,12 @@ var AdvancedPopover = ({
|
|
|
6685
6691
|
onFiltersChange([]);
|
|
6686
6692
|
onOpenChange?.(false);
|
|
6687
6693
|
};
|
|
6694
|
+
const toggleLogicOp = (filterId) => {
|
|
6695
|
+
setLogicOps((prev) => ({
|
|
6696
|
+
...prev,
|
|
6697
|
+
[filterId]: (prev[filterId] ?? "and") === "and" ? "or" : "and"
|
|
6698
|
+
}));
|
|
6699
|
+
};
|
|
6688
6700
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(PopoverPrimitive10.Root, { open, onOpenChange, children: [
|
|
6689
6701
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(PopoverPrimitive10.Trigger, { asChild: true, children }),
|
|
6690
6702
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(PopoverPrimitive10.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
@@ -6693,22 +6705,22 @@ var AdvancedPopover = ({
|
|
|
6693
6705
|
sideOffset: 4,
|
|
6694
6706
|
align: "start",
|
|
6695
6707
|
className: cn(
|
|
6696
|
-
"z-50 flex flex-col
|
|
6697
|
-
"bg-[var(--color-
|
|
6708
|
+
"z-50 flex flex-col",
|
|
6709
|
+
"bg-[var(--color-background)] rounded-md shadow-lg",
|
|
6698
6710
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6699
6711
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
6700
|
-
"data-[side=bottom]:slide-in-from-top-2"
|
|
6701
|
-
"min-w-[520px] max-w-[90vw]"
|
|
6712
|
+
"data-[side=bottom]:slide-in-from-top-2"
|
|
6702
6713
|
),
|
|
6703
6714
|
children: [
|
|
6704
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-col
|
|
6715
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-col gap-base p-base", children: [
|
|
6705
6716
|
filters.map((filter, i) => {
|
|
6706
6717
|
const propDef = getPropertyDef(filter.propertyId);
|
|
6707
6718
|
if (!propDef) return null;
|
|
6708
6719
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6709
6720
|
AdvancedRow,
|
|
6710
6721
|
{
|
|
6711
|
-
connector: i === 0 ? "Where" : "And",
|
|
6722
|
+
connector: i === 0 ? "Where" : (logicOps[filter.id] ?? "and") === "and" ? "And" : "Or",
|
|
6723
|
+
onConnectorToggle: i > 0 ? () => toggleLogicOp(filter.id) : void 0,
|
|
6712
6724
|
propertyDef: propDef,
|
|
6713
6725
|
condition: filter,
|
|
6714
6726
|
properties,
|
|
@@ -6721,7 +6733,7 @@ var AdvancedPopover = ({
|
|
|
6721
6733
|
}),
|
|
6722
6734
|
filters.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "py-base text-sm text-[var(--color-muted-foreground)]", children: "No advanced filters yet." })
|
|
6723
6735
|
] }),
|
|
6724
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center justify-between
|
|
6736
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center justify-between p-base border-t border-[var(--color-border)]", children: [
|
|
6725
6737
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6726
6738
|
PropertySelector,
|
|
6727
6739
|
{
|
|
@@ -6729,14 +6741,10 @@ var AdvancedPopover = ({
|
|
|
6729
6741
|
onSelect: handleAddFilter,
|
|
6730
6742
|
open: addSelectorOpen,
|
|
6731
6743
|
onOpenChange: setAddSelectorOpen,
|
|
6732
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime48.
|
|
6733
|
-
"
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
className: "text-sm font-regular leading-sm text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)] cursor-pointer transition-colors",
|
|
6737
|
-
children: "+ Add filter"
|
|
6738
|
-
}
|
|
6739
|
-
)
|
|
6744
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("button", { type: "button", className: cn(outlinedBtn), children: [
|
|
6745
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_icons32.Icon, { icon: import_icons32.faPlusOutline, size: "sm", className: "text-[var(--color-foreground)]" }),
|
|
6746
|
+
"Add filter"
|
|
6747
|
+
] })
|
|
6740
6748
|
}
|
|
6741
6749
|
),
|
|
6742
6750
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
@@ -6744,7 +6752,7 @@ var AdvancedPopover = ({
|
|
|
6744
6752
|
{
|
|
6745
6753
|
type: "button",
|
|
6746
6754
|
onClick: handleClearAll,
|
|
6747
|
-
className: "text-sm font-
|
|
6755
|
+
className: "text-sm font-medium leading-sm text-[var(--color-foreground)] cursor-pointer transition-colors hover:opacity-70 px-base py-sm",
|
|
6748
6756
|
children: "Clear all filters"
|
|
6749
6757
|
}
|
|
6750
6758
|
)
|
|
@@ -6759,7 +6767,7 @@ AdvancedPopover.displayName = "AdvancedPopover";
|
|
|
6759
6767
|
// src/components/ui/filter/summary-chip.tsx
|
|
6760
6768
|
var React46 = __toESM(require("react"));
|
|
6761
6769
|
var PopoverPrimitive11 = __toESM(require("@radix-ui/react-popover"));
|
|
6762
|
-
var
|
|
6770
|
+
var import_icons33 = require("@l3mpire/icons");
|
|
6763
6771
|
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
6764
6772
|
var SummaryChip = ({
|
|
6765
6773
|
count,
|
|
@@ -6771,6 +6779,7 @@ var SummaryChip = ({
|
|
|
6771
6779
|
}) => {
|
|
6772
6780
|
const [open, setOpen] = React46.useState(false);
|
|
6773
6781
|
const [addSelectorOpen, setAddSelectorOpen] = React46.useState(false);
|
|
6782
|
+
const [logicOps, setLogicOps] = React46.useState({});
|
|
6774
6783
|
const getPropertyDef = (propertyId) => properties.find((p) => p.id === propertyId);
|
|
6775
6784
|
const handleUpdateFilter = (updated) => {
|
|
6776
6785
|
onFiltersChange(filters.map((f) => f.id === updated.id ? updated : f));
|
|
@@ -6799,24 +6808,23 @@ var SummaryChip = ({
|
|
|
6799
6808
|
className: cn(
|
|
6800
6809
|
"inline-flex items-center gap-sm px-base py-sm",
|
|
6801
6810
|
"min-h-[32px] max-h-[32px]",
|
|
6802
|
-
|
|
6803
|
-
"
|
|
6804
|
-
"cursor-pointer transition-colors
|
|
6811
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
6812
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
6813
|
+
"cursor-pointer transition-colors",
|
|
6814
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
|
|
6805
6815
|
className
|
|
6806
6816
|
),
|
|
6807
6817
|
children: [
|
|
6808
6818
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6809
|
-
|
|
6819
|
+
import_icons33.Icon,
|
|
6810
6820
|
{
|
|
6811
|
-
icon:
|
|
6821
|
+
icon: import_icons33.faSlidersOutline,
|
|
6812
6822
|
size: "sm",
|
|
6813
|
-
className:
|
|
6823
|
+
className: "shrink-0 text-[var(--color-foreground)]"
|
|
6814
6824
|
}
|
|
6815
6825
|
),
|
|
6816
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.
|
|
6817
|
-
|
|
6818
|
-
count > 0 && ` (${count})`
|
|
6819
|
-
] })
|
|
6826
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-sm font-medium leading-sm whitespace-nowrap text-[var(--color-foreground)]", children: "Filters" }),
|
|
6827
|
+
count > 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-[10px] font-medium leading-2xs text-filter-chip-badge-text", children: count }) })
|
|
6820
6828
|
]
|
|
6821
6829
|
}
|
|
6822
6830
|
) }),
|
|
@@ -6834,14 +6842,15 @@ var SummaryChip = ({
|
|
|
6834
6842
|
"min-w-[420px] max-w-[90vw]"
|
|
6835
6843
|
),
|
|
6836
6844
|
children: [
|
|
6837
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col
|
|
6845
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col gap-base p-base", children: [
|
|
6838
6846
|
filters.map((filter, i) => {
|
|
6839
6847
|
const propDef = getPropertyDef(filter.propertyId);
|
|
6840
6848
|
if (!propDef) return null;
|
|
6841
6849
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6842
6850
|
AdvancedRow,
|
|
6843
6851
|
{
|
|
6844
|
-
connector: i === 0 ? "Where" : "And",
|
|
6852
|
+
connector: i === 0 ? "Where" : (logicOps[filter.id] ?? "and") === "and" ? "And" : "Or",
|
|
6853
|
+
onConnectorToggle: i > 0 ? () => setLogicOps((prev) => ({ ...prev, [filter.id]: (prev[filter.id] ?? "and") === "and" ? "or" : "and" })) : void 0,
|
|
6845
6854
|
propertyDef: propDef,
|
|
6846
6855
|
condition: filter,
|
|
6847
6856
|
properties,
|
|
@@ -6854,7 +6863,7 @@ var SummaryChip = ({
|
|
|
6854
6863
|
}),
|
|
6855
6864
|
filters.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: "py-base text-sm text-[var(--color-muted-foreground)]", children: "No active filters." })
|
|
6856
6865
|
] }),
|
|
6857
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center justify-between
|
|
6866
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center justify-between p-base border-t border-[var(--color-border)]", children: [
|
|
6858
6867
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6859
6868
|
PropertySelector,
|
|
6860
6869
|
{
|
|
@@ -6866,9 +6875,16 @@ var SummaryChip = ({
|
|
|
6866
6875
|
"button",
|
|
6867
6876
|
{
|
|
6868
6877
|
type: "button",
|
|
6869
|
-
className:
|
|
6878
|
+
className: cn(
|
|
6879
|
+
"flex items-center gap-sm px-base py-sm",
|
|
6880
|
+
"min-h-[32px] max-h-[32px] min-w-[80px]",
|
|
6881
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
6882
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
6883
|
+
"cursor-pointer transition-colors text-sm font-medium leading-sm text-[var(--color-foreground)]",
|
|
6884
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
6885
|
+
),
|
|
6870
6886
|
children: [
|
|
6871
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6887
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_icons33.Icon, { icon: import_icons33.faPlusOutline, size: "sm", className: "text-[var(--color-foreground)]" }),
|
|
6872
6888
|
"Add filter"
|
|
6873
6889
|
]
|
|
6874
6890
|
}
|
|
@@ -6883,7 +6899,7 @@ var SummaryChip = ({
|
|
|
6883
6899
|
onClearAll();
|
|
6884
6900
|
setOpen(false);
|
|
6885
6901
|
},
|
|
6886
|
-
className: "text-sm font-
|
|
6902
|
+
className: "text-sm font-medium leading-sm text-[var(--color-foreground)] cursor-pointer transition-colors hover:opacity-70 px-base py-sm",
|
|
6887
6903
|
children: "Clear all filters"
|
|
6888
6904
|
}
|
|
6889
6905
|
)
|
|
@@ -7103,6 +7119,15 @@ var FilterSystem = ({
|
|
|
7103
7119
|
}
|
|
7104
7120
|
)
|
|
7105
7121
|
] })
|
|
7122
|
+
),
|
|
7123
|
+
totalCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7124
|
+
"button",
|
|
7125
|
+
{
|
|
7126
|
+
type: "button",
|
|
7127
|
+
onClick: handleClearAll,
|
|
7128
|
+
className: "flex items-center gap-sm px-base py-sm min-h-[32px] max-h-[32px] rounded-md cursor-pointer transition-colors hover:bg-[var(--color-accent)]",
|
|
7129
|
+
children: isMinimal ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_icons34.Icon, { icon: import_icons34.faXmarkOutline, size: "sm", className: "text-[var(--color-foreground)]" }) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-sm font-medium leading-sm text-[var(--color-foreground)]", children: "Clear" })
|
|
7130
|
+
}
|
|
7106
7131
|
)
|
|
7107
7132
|
] }),
|
|
7108
7133
|
actions && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(FilterBarRight, { children: actions })
|
|
@@ -7113,7 +7138,7 @@ FilterSystem.displayName = "FilterSystem";
|
|
|
7113
7138
|
// src/components/ui/date-picker.tsx
|
|
7114
7139
|
var React49 = __toESM(require("react"));
|
|
7115
7140
|
var PopoverPrimitive12 = __toESM(require("@radix-ui/react-popover"));
|
|
7116
|
-
var
|
|
7141
|
+
var import_icons35 = require("@l3mpire/icons");
|
|
7117
7142
|
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
7118
7143
|
function getDaysInMonth(year, month) {
|
|
7119
7144
|
return new Date(year, month + 1, 0).getDate();
|
|
@@ -7281,19 +7306,19 @@ var DatePickerSelects = React49.forwardRef(({ className, formatDate = defaultFor
|
|
|
7281
7306
|
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-base w-full", children: [
|
|
7282
7307
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex-1 flex items-center gap-base min-w-0 px-base py-sm bg-gradient-to-t from-[var(--color-select-bg-default)] to-[var(--color-select-bg-gradient-to)] border border-[var(--color-select-border-default)] rounded-base shadow-sm", children: [
|
|
7283
7308
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-datepicker-header-text truncate", children: fromDate ? formatDate(fromDate) : "Start date" }),
|
|
7284
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7309
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_icons35.Icon, { icon: import_icons35.faCalendarOutline, size: "sm", className: "shrink-0 text-datepicker-header-text" })
|
|
7285
7310
|
] }),
|
|
7286
7311
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7287
|
-
|
|
7312
|
+
import_icons35.Icon,
|
|
7288
7313
|
{
|
|
7289
|
-
icon:
|
|
7314
|
+
icon: import_icons35.faArrowRightOutline,
|
|
7290
7315
|
size: "sm",
|
|
7291
7316
|
className: "shrink-0 text-datepicker-header-weekday"
|
|
7292
7317
|
}
|
|
7293
7318
|
),
|
|
7294
7319
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex-1 flex items-center gap-base min-w-0 px-base py-sm bg-gradient-to-t from-[var(--color-select-bg-default)] to-[var(--color-select-bg-gradient-to)] border border-[var(--color-select-border-default)] rounded-base shadow-sm", children: [
|
|
7295
7320
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-datepicker-header-text truncate", children: toDate ? formatDate(toDate) : "End date" }),
|
|
7296
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7321
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_icons35.Icon, { icon: import_icons35.faCalendarOutline, size: "sm", className: "shrink-0 text-datepicker-header-text" })
|
|
7297
7322
|
] })
|
|
7298
7323
|
] })
|
|
7299
7324
|
}
|
|
@@ -7403,7 +7428,7 @@ var DatePickerCalendar = React49.forwardRef(({ className, header, ...props }, re
|
|
|
7403
7428
|
onClick: goToPrevMonth,
|
|
7404
7429
|
className: "flex items-center justify-center p-xs rounded-base hover:bg-datepicker-day-bg-hover transition-colors cursor-pointer",
|
|
7405
7430
|
"aria-label": "Previous month",
|
|
7406
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7431
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_icons35.Icon, { icon: import_icons35.faChevronLeftOutline, size: "xs", className: "text-datepicker-header-nav" })
|
|
7407
7432
|
}
|
|
7408
7433
|
),
|
|
7409
7434
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
@@ -7413,7 +7438,7 @@ var DatePickerCalendar = React49.forwardRef(({ className, header, ...props }, re
|
|
|
7413
7438
|
onClick: goToNextMonth,
|
|
7414
7439
|
className: "flex items-center justify-center p-xs rounded-base hover:bg-datepicker-day-bg-hover transition-colors cursor-pointer",
|
|
7415
7440
|
"aria-label": "Next month",
|
|
7416
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7441
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_icons35.Icon, { icon: import_icons35.faChevronRightOutline, size: "xs", className: "text-datepicker-header-nav" })
|
|
7417
7442
|
}
|
|
7418
7443
|
)
|
|
7419
7444
|
] })
|