@l3mpire/ui 2.11.0 → 2.13.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 +29 -3
- package/dist/index.d.mts +44 -5
- package/dist/index.d.ts +44 -5
- package/dist/index.js +2364 -1948
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2375 -1953
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/USAGE.md
CHANGED
|
@@ -946,12 +946,38 @@ import {
|
|
|
946
946
|
| `SummaryChip` | Minimal mode: "Filters (N)" with interactive popover |
|
|
947
947
|
|
|
948
948
|
**Responsive:** FilterSystem auto-detects container width via `ResizeObserver`:
|
|
949
|
-
- **Default** (>
|
|
950
|
-
- **Minimal** (≤
|
|
949
|
+
- **Default** (>breakpoint): full chips, labels, "Filters" button
|
|
950
|
+
- **Minimal** (≤breakpoint): SummaryChip "Filters (N)" with interactive popover, icon-only Sort/Filter buttons
|
|
951
|
+
- The breakpoint is configurable via the `breakpoint` prop on `FilterSystem` (default: `600`).
|
|
951
952
|
|
|
952
953
|
**Built-in Clear:** appears inline after the last filter chip ("Clear" text in default, × icon in minimal). Separate from "Discard changes" which goes in `actions` (right side) to revert a saved view.
|
|
953
954
|
|
|
954
|
-
**And/Or toggle:** each row in the advanced popover has an independent And/Or toggle button (
|
|
955
|
+
**And/Or toggle:** each row in the advanced popover has an independent And/Or toggle button. The choice is **persisted on each `FilterCondition` as `logicOperator: "and" | "or"`** (defaults to `"and"` when undefined), so it survives remounts and can be serialized.
|
|
956
|
+
|
|
957
|
+
**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.
|
|
958
|
+
|
|
959
|
+
**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.
|
|
960
|
+
|
|
961
|
+
```tsx
|
|
962
|
+
{
|
|
963
|
+
id: "contact_owner",
|
|
964
|
+
label: "Contact owner",
|
|
965
|
+
type: "enum",
|
|
966
|
+
icon: faUserOutline,
|
|
967
|
+
group: "contact",
|
|
968
|
+
groupLabel: "Contact",
|
|
969
|
+
options: ["Quentin", "Simon", "Philippe"],
|
|
970
|
+
dynamicOptions: [
|
|
971
|
+
{
|
|
972
|
+
value: "__me__",
|
|
973
|
+
label: "Me",
|
|
974
|
+
description: "This value is dynamically applied to the current user",
|
|
975
|
+
icon: faBoltOutline,
|
|
976
|
+
},
|
|
977
|
+
{ value: "__deactivated__", label: "All deactivated and removed owners", icon: faBoltOutline },
|
|
978
|
+
],
|
|
979
|
+
}
|
|
980
|
+
```
|
|
955
981
|
|
|
956
982
|
| Utility | Purpose |
|
|
957
983
|
|---|---|
|
package/dist/index.d.mts
CHANGED
|
@@ -357,7 +357,7 @@ interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputEleme
|
|
|
357
357
|
declare const NumberInput: React.ForwardRefExoticComponent<NumberInputProps & React.RefAttributes<HTMLInputElement>>;
|
|
358
358
|
|
|
359
359
|
declare const typographyVariants: (props?: ({
|
|
360
|
-
variant?: "xs" | "sm" | "md" | "lg" | "
|
|
360
|
+
variant?: "xs" | "sm" | "md" | "lg" | "h1" | "h2" | "h3" | null | undefined;
|
|
361
361
|
weight?: "bold" | "regular" | "semibold" | null | undefined;
|
|
362
362
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
363
363
|
interface TypographyProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof typographyVariants> {
|
|
@@ -676,12 +676,28 @@ declare const FilterChip: React.ForwardRefExoticComponent<FilterChipProps & Reac
|
|
|
676
676
|
type DataType = "text" | "number" | "date" | "enum" | "tags" | "boolean" | "relation";
|
|
677
677
|
type TextOperator = "contains" | "does not contain" | "is" | "is not" | "starts with" | "ends with" | "is empty" | "is not empty";
|
|
678
678
|
type NumberOperator = "=" | "≠" | ">" | "<" | "≥" | "≤" | "is between" | "is empty" | "is not empty";
|
|
679
|
-
type DateOperator = "is" | "is before" | "is after" | "is on or before" | "is on or after" | "is between" | "is
|
|
679
|
+
type DateOperator = "is" | "is before" | "is after" | "is on or before" | "is on or after" | "is between" | "is empty" | "is not empty";
|
|
680
680
|
type EnumOperator = "is" | "is not" | "is any of" | "is none of" | "is empty" | "is not empty";
|
|
681
681
|
type TagsOperator = "contains" | "does not contain" | "contains any of" | "contains all of" | "is empty" | "is not empty";
|
|
682
682
|
type BooleanOperator = "is true" | "is false";
|
|
683
683
|
type RelationOperator = "is" | "is not" | "is any of" | "is none of" | "is empty" | "is not empty";
|
|
684
684
|
type OperatorType = TextOperator | NumberOperator | DateOperator | EnumOperator | TagsOperator | BooleanOperator | RelationOperator;
|
|
685
|
+
/**
|
|
686
|
+
* A "smart" / dynamic option shown at the top of a relation or enum selector
|
|
687
|
+
* (e.g. "Me", "My team", "Unassigned"). The value is a sentinel string that
|
|
688
|
+
* the consuming app resolves at query time (e.g. `__me__` → `currentUser.id`).
|
|
689
|
+
*
|
|
690
|
+
* The design system only handles the rendering (icon + label + description +
|
|
691
|
+
* divider above the regular options). Resolving the sentinels is an app
|
|
692
|
+
* concern.
|
|
693
|
+
*/
|
|
694
|
+
interface DynamicOption {
|
|
695
|
+
/** Sentinel value stored on FilterCondition.value (e.g. "__me__"). */
|
|
696
|
+
value: string;
|
|
697
|
+
label: string;
|
|
698
|
+
description?: string;
|
|
699
|
+
icon?: _l3mpire_icons.IconDefinition;
|
|
700
|
+
}
|
|
685
701
|
interface PropertyDefinition {
|
|
686
702
|
id: string;
|
|
687
703
|
label: string;
|
|
@@ -690,6 +706,12 @@ interface PropertyDefinition {
|
|
|
690
706
|
group: string;
|
|
691
707
|
groupLabel: string;
|
|
692
708
|
options?: string[];
|
|
709
|
+
/**
|
|
710
|
+
* Dynamic/smart options rendered at the top of the value selector with a
|
|
711
|
+
* divider. Only used for enum, tags, and relation types. The app resolves
|
|
712
|
+
* the sentinel values at query time.
|
|
713
|
+
*/
|
|
714
|
+
dynamicOptions?: DynamicOption[];
|
|
693
715
|
relationConfig?: {
|
|
694
716
|
entity: string;
|
|
695
717
|
displayProperty: string;
|
|
@@ -698,11 +720,14 @@ interface PropertyDefinition {
|
|
|
698
720
|
};
|
|
699
721
|
}
|
|
700
722
|
type FilterValue = string | number | boolean | Date | [number, number] | [Date, Date] | string[] | null;
|
|
723
|
+
type LogicOperator = "and" | "or";
|
|
701
724
|
interface FilterCondition {
|
|
702
725
|
id: string;
|
|
703
726
|
propertyId: string;
|
|
704
727
|
operator: OperatorType | null;
|
|
705
728
|
value: FilterValue;
|
|
729
|
+
/** Logic connector to the previous filter. Defaults to "and". */
|
|
730
|
+
logicOperator?: LogicOperator;
|
|
706
731
|
}
|
|
707
732
|
interface FilterState {
|
|
708
733
|
basicFilters: FilterCondition[];
|
|
@@ -811,6 +836,8 @@ interface ValueInputProps {
|
|
|
811
836
|
onChange: (value: FilterValue) => void;
|
|
812
837
|
onSubmit?: () => void;
|
|
813
838
|
options?: string[];
|
|
839
|
+
/** Dynamic/smart entries rendered at the top with a divider. */
|
|
840
|
+
dynamicOptions?: DynamicOption[];
|
|
814
841
|
className?: string;
|
|
815
842
|
}
|
|
816
843
|
declare const ValueInput: React.FC<ValueInputProps>;
|
|
@@ -821,6 +848,13 @@ interface PropertySelectorProps {
|
|
|
821
848
|
open?: boolean;
|
|
822
849
|
onOpenChange?: (open: boolean) => void;
|
|
823
850
|
children?: React.ReactNode;
|
|
851
|
+
/**
|
|
852
|
+
* When provided, renders an "Advanced filter" item at the bottom of the
|
|
853
|
+
* popover with a divider above it.
|
|
854
|
+
*/
|
|
855
|
+
onAdvancedFilter?: () => void;
|
|
856
|
+
/** Count of existing advanced filter rules, displayed next to the item. */
|
|
857
|
+
advancedFilterCount?: number;
|
|
824
858
|
}
|
|
825
859
|
declare const PropertySelector: React.FC<PropertySelectorProps>;
|
|
826
860
|
|
|
@@ -865,10 +899,10 @@ declare const InteractiveFilterChip: React.FC<InteractiveFilterChipProps>;
|
|
|
865
899
|
type FilterBarMode = "default" | "minimal";
|
|
866
900
|
/**
|
|
867
901
|
* Observes the container width and returns the appropriate FilterBar mode.
|
|
868
|
-
* - default: >
|
|
869
|
-
* - minimal: ≤
|
|
902
|
+
* - default: > breakpoint
|
|
903
|
+
* - minimal: ≤ breakpoint
|
|
870
904
|
*/
|
|
871
|
-
declare function useFilterBarMode(ref: React.RefObject<HTMLElement | null>, override?: FilterBarMode): FilterBarMode;
|
|
905
|
+
declare function useFilterBarMode(ref: React.RefObject<HTMLElement | null>, override?: FilterBarMode, breakpoint?: number): FilterBarMode;
|
|
872
906
|
|
|
873
907
|
interface FilterSystemProps {
|
|
874
908
|
properties: PropertyDefinition[];
|
|
@@ -877,6 +911,8 @@ interface FilterSystemProps {
|
|
|
877
911
|
sortFields?: SortField[];
|
|
878
912
|
/** Force a specific mode instead of auto-detecting via ResizeObserver. */
|
|
879
913
|
mode?: FilterBarMode;
|
|
914
|
+
/** Width breakpoint (px) for switching to minimal mode. Default: 600. */
|
|
915
|
+
breakpoint?: number;
|
|
880
916
|
children?: React.ReactNode;
|
|
881
917
|
actions?: React.ReactNode;
|
|
882
918
|
className?: string;
|
|
@@ -924,6 +960,9 @@ interface SummaryChipProps {
|
|
|
924
960
|
/** Custom trigger element. When omitted, renders the default "Filters (N)" button. */
|
|
925
961
|
children?: React.ReactNode;
|
|
926
962
|
className?: string;
|
|
963
|
+
/** Controlled open state. */
|
|
964
|
+
open?: boolean;
|
|
965
|
+
onOpenChange?: (open: boolean) => void;
|
|
927
966
|
}
|
|
928
967
|
declare const SummaryChip: React.FC<SummaryChipProps>;
|
|
929
968
|
|
package/dist/index.d.ts
CHANGED
|
@@ -357,7 +357,7 @@ interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputEleme
|
|
|
357
357
|
declare const NumberInput: React.ForwardRefExoticComponent<NumberInputProps & React.RefAttributes<HTMLInputElement>>;
|
|
358
358
|
|
|
359
359
|
declare const typographyVariants: (props?: ({
|
|
360
|
-
variant?: "xs" | "sm" | "md" | "lg" | "
|
|
360
|
+
variant?: "xs" | "sm" | "md" | "lg" | "h1" | "h2" | "h3" | null | undefined;
|
|
361
361
|
weight?: "bold" | "regular" | "semibold" | null | undefined;
|
|
362
362
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
363
363
|
interface TypographyProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof typographyVariants> {
|
|
@@ -676,12 +676,28 @@ declare const FilterChip: React.ForwardRefExoticComponent<FilterChipProps & Reac
|
|
|
676
676
|
type DataType = "text" | "number" | "date" | "enum" | "tags" | "boolean" | "relation";
|
|
677
677
|
type TextOperator = "contains" | "does not contain" | "is" | "is not" | "starts with" | "ends with" | "is empty" | "is not empty";
|
|
678
678
|
type NumberOperator = "=" | "≠" | ">" | "<" | "≥" | "≤" | "is between" | "is empty" | "is not empty";
|
|
679
|
-
type DateOperator = "is" | "is before" | "is after" | "is on or before" | "is on or after" | "is between" | "is
|
|
679
|
+
type DateOperator = "is" | "is before" | "is after" | "is on or before" | "is on or after" | "is between" | "is empty" | "is not empty";
|
|
680
680
|
type EnumOperator = "is" | "is not" | "is any of" | "is none of" | "is empty" | "is not empty";
|
|
681
681
|
type TagsOperator = "contains" | "does not contain" | "contains any of" | "contains all of" | "is empty" | "is not empty";
|
|
682
682
|
type BooleanOperator = "is true" | "is false";
|
|
683
683
|
type RelationOperator = "is" | "is not" | "is any of" | "is none of" | "is empty" | "is not empty";
|
|
684
684
|
type OperatorType = TextOperator | NumberOperator | DateOperator | EnumOperator | TagsOperator | BooleanOperator | RelationOperator;
|
|
685
|
+
/**
|
|
686
|
+
* A "smart" / dynamic option shown at the top of a relation or enum selector
|
|
687
|
+
* (e.g. "Me", "My team", "Unassigned"). The value is a sentinel string that
|
|
688
|
+
* the consuming app resolves at query time (e.g. `__me__` → `currentUser.id`).
|
|
689
|
+
*
|
|
690
|
+
* The design system only handles the rendering (icon + label + description +
|
|
691
|
+
* divider above the regular options). Resolving the sentinels is an app
|
|
692
|
+
* concern.
|
|
693
|
+
*/
|
|
694
|
+
interface DynamicOption {
|
|
695
|
+
/** Sentinel value stored on FilterCondition.value (e.g. "__me__"). */
|
|
696
|
+
value: string;
|
|
697
|
+
label: string;
|
|
698
|
+
description?: string;
|
|
699
|
+
icon?: _l3mpire_icons.IconDefinition;
|
|
700
|
+
}
|
|
685
701
|
interface PropertyDefinition {
|
|
686
702
|
id: string;
|
|
687
703
|
label: string;
|
|
@@ -690,6 +706,12 @@ interface PropertyDefinition {
|
|
|
690
706
|
group: string;
|
|
691
707
|
groupLabel: string;
|
|
692
708
|
options?: string[];
|
|
709
|
+
/**
|
|
710
|
+
* Dynamic/smart options rendered at the top of the value selector with a
|
|
711
|
+
* divider. Only used for enum, tags, and relation types. The app resolves
|
|
712
|
+
* the sentinel values at query time.
|
|
713
|
+
*/
|
|
714
|
+
dynamicOptions?: DynamicOption[];
|
|
693
715
|
relationConfig?: {
|
|
694
716
|
entity: string;
|
|
695
717
|
displayProperty: string;
|
|
@@ -698,11 +720,14 @@ interface PropertyDefinition {
|
|
|
698
720
|
};
|
|
699
721
|
}
|
|
700
722
|
type FilterValue = string | number | boolean | Date | [number, number] | [Date, Date] | string[] | null;
|
|
723
|
+
type LogicOperator = "and" | "or";
|
|
701
724
|
interface FilterCondition {
|
|
702
725
|
id: string;
|
|
703
726
|
propertyId: string;
|
|
704
727
|
operator: OperatorType | null;
|
|
705
728
|
value: FilterValue;
|
|
729
|
+
/** Logic connector to the previous filter. Defaults to "and". */
|
|
730
|
+
logicOperator?: LogicOperator;
|
|
706
731
|
}
|
|
707
732
|
interface FilterState {
|
|
708
733
|
basicFilters: FilterCondition[];
|
|
@@ -811,6 +836,8 @@ interface ValueInputProps {
|
|
|
811
836
|
onChange: (value: FilterValue) => void;
|
|
812
837
|
onSubmit?: () => void;
|
|
813
838
|
options?: string[];
|
|
839
|
+
/** Dynamic/smart entries rendered at the top with a divider. */
|
|
840
|
+
dynamicOptions?: DynamicOption[];
|
|
814
841
|
className?: string;
|
|
815
842
|
}
|
|
816
843
|
declare const ValueInput: React.FC<ValueInputProps>;
|
|
@@ -821,6 +848,13 @@ interface PropertySelectorProps {
|
|
|
821
848
|
open?: boolean;
|
|
822
849
|
onOpenChange?: (open: boolean) => void;
|
|
823
850
|
children?: React.ReactNode;
|
|
851
|
+
/**
|
|
852
|
+
* When provided, renders an "Advanced filter" item at the bottom of the
|
|
853
|
+
* popover with a divider above it.
|
|
854
|
+
*/
|
|
855
|
+
onAdvancedFilter?: () => void;
|
|
856
|
+
/** Count of existing advanced filter rules, displayed next to the item. */
|
|
857
|
+
advancedFilterCount?: number;
|
|
824
858
|
}
|
|
825
859
|
declare const PropertySelector: React.FC<PropertySelectorProps>;
|
|
826
860
|
|
|
@@ -865,10 +899,10 @@ declare const InteractiveFilterChip: React.FC<InteractiveFilterChipProps>;
|
|
|
865
899
|
type FilterBarMode = "default" | "minimal";
|
|
866
900
|
/**
|
|
867
901
|
* Observes the container width and returns the appropriate FilterBar mode.
|
|
868
|
-
* - default: >
|
|
869
|
-
* - minimal: ≤
|
|
902
|
+
* - default: > breakpoint
|
|
903
|
+
* - minimal: ≤ breakpoint
|
|
870
904
|
*/
|
|
871
|
-
declare function useFilterBarMode(ref: React.RefObject<HTMLElement | null>, override?: FilterBarMode): FilterBarMode;
|
|
905
|
+
declare function useFilterBarMode(ref: React.RefObject<HTMLElement | null>, override?: FilterBarMode, breakpoint?: number): FilterBarMode;
|
|
872
906
|
|
|
873
907
|
interface FilterSystemProps {
|
|
874
908
|
properties: PropertyDefinition[];
|
|
@@ -877,6 +911,8 @@ interface FilterSystemProps {
|
|
|
877
911
|
sortFields?: SortField[];
|
|
878
912
|
/** Force a specific mode instead of auto-detecting via ResizeObserver. */
|
|
879
913
|
mode?: FilterBarMode;
|
|
914
|
+
/** Width breakpoint (px) for switching to minimal mode. Default: 600. */
|
|
915
|
+
breakpoint?: number;
|
|
880
916
|
children?: React.ReactNode;
|
|
881
917
|
actions?: React.ReactNode;
|
|
882
918
|
className?: string;
|
|
@@ -924,6 +960,9 @@ interface SummaryChipProps {
|
|
|
924
960
|
/** Custom trigger element. When omitted, renders the default "Filters (N)" button. */
|
|
925
961
|
children?: React.ReactNode;
|
|
926
962
|
className?: string;
|
|
963
|
+
/** Controlled open state. */
|
|
964
|
+
open?: boolean;
|
|
965
|
+
onOpenChange?: (open: boolean) => void;
|
|
927
966
|
}
|
|
928
967
|
declare const SummaryChip: React.FC<SummaryChipProps>;
|
|
929
968
|
|