@l3mpire/ui 2.21.1 → 2.23.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/USAGE.md CHANGED
@@ -963,6 +963,49 @@ import {
963
963
 
964
964
  **Advanced filter shortcut:** the PropertySelector footer shows an "Advanced filter · N rule(s)" item. Clicking it closes the property selector and opens the advanced popover directly in its initial empty state — where the user picks the first property inline via a "Where | [Select property ▾]" draft row. When no advanced filters exist yet, clicking this shortcut makes the AdvancedChip appear with the popover already open; closing without adding a filter removes the chip automatically.
965
965
 
966
+ **Pinned groups (hoist a group to root):** mark a property group as "primary" so its properties render flat at the top of the `PropertySelector` popover — no category click needed. Set `groupPinned: true` on any property and the entire group is hoisted; remaining groups stay nested as categories below. Search works across everything (pinned + nested). The popover has a max-height and the "Advanced filter" footer stays sticky at the bottom when the list scrolls. The same flattening is applied in `AdvancedRow`'s property-swap popover and in `InteractiveFilterChip`'s swap popover.
967
+
968
+ ```tsx
969
+ { id: "status", label: "Status", type: "enum", icon: faCircleOutline, group: "task", groupLabel: "Task", groupPinned: true, ... },
970
+ { id: "priority", label: "Priority", type: "enum", icon: faFlagOutline, group: "task", groupLabel: "Task", groupPinned: true, ... },
971
+ { id: "due_date", label: "Due date", type: "date", icon: faCalendarOutline, group: "task", groupLabel: "Task", groupPinned: true, ... },
972
+ // Other groups stay nested — click "Contact" to see its properties.
973
+ { id: "contact_name", label: "Contact name", type: "text", icon: faUserOutline, group: "contact", groupLabel: "Contact", ... },
974
+ ```
975
+
976
+ **Enum options with icons + intent dots:** `options` accepts either strings (backwards-compatible) or objects `{ value, label?, icon?, intent? }`. Set `icon` to render a FontAwesome icon left of the label; set `intent` (`primary` / `success` / `warning` / `critical` / `neutral`) to render a colored dot instead. The icon also appears as an adornment on the chip when the value is selected, so users recognize the option at a glance. Applied in the value popover, the `InteractiveFilterChip`, and `AdvancedRow`.
977
+
978
+ ```tsx
979
+ // Channel-type enum — icons everywhere
980
+ {
981
+ id: "task_type",
982
+ label: "Task type",
983
+ type: "enum",
984
+ options: [
985
+ { value: "call", label: "Call", icon: faPhoneOutline },
986
+ { value: "email", label: "Email", icon: faEnvelopeOutline },
987
+ { value: "linkedin", label: "LinkedIn", icon: faLinkedinOutline },
988
+ "Manual", // plain string still works
989
+ ],
990
+ // ...
991
+ }
992
+
993
+ // Status-type enum — intent dots
994
+ {
995
+ id: "task_status",
996
+ label: "Status",
997
+ type: "enum",
998
+ options: [
999
+ { value: "todo", label: "To do", intent: "neutral" },
1000
+ { value: "in_progress", label: "In progress", intent: "primary" },
1001
+ { value: "done", label: "Done", intent: "success" },
1002
+ { value: "blocked", label: "Blocked", intent: "warning" },
1003
+ { value: "cancelled", label: "Cancelled", intent: "critical" },
1004
+ ],
1005
+ // ...
1006
+ }
1007
+ ```
1008
+
966
1009
  **Dynamic options ("Me", "Unassigned", …):** enum/tags/relation properties accept a `dynamicOptions` array. Each entry is `{ value, label, description?, icon? }` and is rendered at the top of the SingleSelect / MultiSelect dropdown with a divider separating it from the regular options. The `value` is a sentinel string stored on `FilterCondition.value` — the DS only renders, the consuming app resolves it at query time (e.g. `"__me__"` → `currentUser.id`). This keeps session/business logic out of the DS while still getting a consistent visual treatment.
967
1010
 
968
1011
  ```tsx
package/dist/index.d.mts CHANGED
@@ -726,6 +726,22 @@ interface DynamicOption {
726
726
  label: string;
727
727
  description?: string;
728
728
  }
729
+ /**
730
+ * Visual intent for a colored dot next to an enum option. Used when no icon is
731
+ * provided — e.g. status-style enums where color carries the semantic meaning.
732
+ */
733
+ type EnumOptionIntent = "primary" | "success" | "warning" | "critical" | "neutral";
734
+ /**
735
+ * An enum option value. Plain strings are kept for backwards compatibility —
736
+ * the string is used as both the value and the label. Object form lets you
737
+ * attach an icon, a custom label, or a colored dot (via `intent`).
738
+ */
739
+ type EnumOption = string | {
740
+ value: string;
741
+ label?: string;
742
+ icon?: _l3mpire_icons.IconDefinition;
743
+ intent?: EnumOptionIntent;
744
+ };
729
745
  interface PropertyDefinition {
730
746
  id: string;
731
747
  label: string;
@@ -733,7 +749,14 @@ interface PropertyDefinition {
733
749
  icon: _l3mpire_icons.IconDefinition;
734
750
  group: string;
735
751
  groupLabel: string;
736
- options?: string[];
752
+ /**
753
+ * When true, this property's entire group is hoisted to the root of the
754
+ * PropertySelector popover (no category click needed). All properties in the
755
+ * same group share this behavior — setting it on any one property pins the
756
+ * whole group. Useful for "primary" groups that hold the most-used filters.
757
+ */
758
+ groupPinned?: boolean;
759
+ options?: EnumOption[];
737
760
  /**
738
761
  * Dynamic/smart options rendered at the top of the value selector with a
739
762
  * divider. Only used for enum, tags, and relation types. The app resolves
@@ -875,7 +898,7 @@ interface ValueInputProps {
875
898
  value: FilterValue;
876
899
  onChange: (value: FilterValue) => void;
877
900
  onSubmit?: () => void;
878
- options?: string[];
901
+ options?: EnumOption[];
879
902
  /** Dynamic/smart entries rendered at the top with a divider. */
880
903
  dynamicOptions?: DynamicOption[];
881
904
  className?: string;
package/dist/index.d.ts CHANGED
@@ -726,6 +726,22 @@ interface DynamicOption {
726
726
  label: string;
727
727
  description?: string;
728
728
  }
729
+ /**
730
+ * Visual intent for a colored dot next to an enum option. Used when no icon is
731
+ * provided — e.g. status-style enums where color carries the semantic meaning.
732
+ */
733
+ type EnumOptionIntent = "primary" | "success" | "warning" | "critical" | "neutral";
734
+ /**
735
+ * An enum option value. Plain strings are kept for backwards compatibility —
736
+ * the string is used as both the value and the label. Object form lets you
737
+ * attach an icon, a custom label, or a colored dot (via `intent`).
738
+ */
739
+ type EnumOption = string | {
740
+ value: string;
741
+ label?: string;
742
+ icon?: _l3mpire_icons.IconDefinition;
743
+ intent?: EnumOptionIntent;
744
+ };
729
745
  interface PropertyDefinition {
730
746
  id: string;
731
747
  label: string;
@@ -733,7 +749,14 @@ interface PropertyDefinition {
733
749
  icon: _l3mpire_icons.IconDefinition;
734
750
  group: string;
735
751
  groupLabel: string;
736
- options?: string[];
752
+ /**
753
+ * When true, this property's entire group is hoisted to the root of the
754
+ * PropertySelector popover (no category click needed). All properties in the
755
+ * same group share this behavior — setting it on any one property pins the
756
+ * whole group. Useful for "primary" groups that hold the most-used filters.
757
+ */
758
+ groupPinned?: boolean;
759
+ options?: EnumOption[];
737
760
  /**
738
761
  * Dynamic/smart options rendered at the top of the value selector with a
739
762
  * divider. Only used for enum, tags, and relation types. The app resolves
@@ -875,7 +898,7 @@ interface ValueInputProps {
875
898
  value: FilterValue;
876
899
  onChange: (value: FilterValue) => void;
877
900
  onSubmit?: () => void;
878
- options?: string[];
901
+ options?: EnumOption[];
879
902
  /** Dynamic/smart entries rendered at the top with a divider. */
880
903
  dynamicOptions?: DynamicOption[];
881
904
  className?: string;