filtercn 0.2.0 → 0.2.2
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/README.md +20 -5
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +44 -23
- package/dist/templates/index.js.map +1 -1
- package/package.json +1 -1
- package/src/templates/index.ts +44 -23
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ Here is a quick example of how to wrap your data table with the filter:
|
|
|
56
56
|
```tsx
|
|
57
57
|
"use client";
|
|
58
58
|
|
|
59
|
-
import { FilterProvider,
|
|
59
|
+
import { FilterProvider, FilterBar } from "@/components/conditional-filter";
|
|
60
60
|
import type { FilterFieldDefinition } from "@/components/conditional-filter";
|
|
61
61
|
|
|
62
62
|
// 1. Define the fields your users can filter by
|
|
@@ -72,6 +72,7 @@ const filterFields: FilterFieldDefinition[] = [
|
|
|
72
72
|
]
|
|
73
73
|
},
|
|
74
74
|
{ name: "price", label: "Budget", type: "number" },
|
|
75
|
+
{ name: "created_at", label: "Created", type: "date" }, // Now supports shadcn Calendar
|
|
75
76
|
];
|
|
76
77
|
|
|
77
78
|
export default function MyPage() {
|
|
@@ -79,17 +80,31 @@ export default function MyPage() {
|
|
|
79
80
|
<div className="p-8 space-y-4">
|
|
80
81
|
<h1 className="text-2xl font-bold">Projects</h1>
|
|
81
82
|
|
|
82
|
-
{/* 2. Wrap the
|
|
83
|
-
<FilterProvider
|
|
84
|
-
|
|
83
|
+
{/* 2. Wrap the toolbar in the provider */}
|
|
84
|
+
<FilterProvider
|
|
85
|
+
config={{
|
|
86
|
+
fields: filterFields,
|
|
87
|
+
paramStyle: "underscore",
|
|
88
|
+
allowConjunctionToggle: true, // Show AND/OR toggle
|
|
89
|
+
searchParamName: "q" // Global search param tracking
|
|
90
|
+
}}
|
|
91
|
+
>
|
|
92
|
+
<FilterBar searchPlaceholder="Search projects..." />
|
|
85
93
|
</FilterProvider>
|
|
86
94
|
|
|
87
|
-
{/* Your data table goes here */}
|
|
95
|
+
{/* Your data table goes here. It should read from the URL parameters. */}
|
|
88
96
|
</div>
|
|
89
97
|
);
|
|
90
98
|
}
|
|
91
99
|
```
|
|
92
100
|
|
|
101
|
+
### New in v0.2.0
|
|
102
|
+
- **Global Search:** `FilterBar` now includes a full-text search input with a built-in 300ms debounce.
|
|
103
|
+
- **Date Pickers:** Date fields now automatically render using the `shadcn/ui` Calendar component.
|
|
104
|
+
- **Param Prefixes:** Use `paramPrefix: "filter_"` in your config to namespace all query params.
|
|
105
|
+
- **AND/OR Conjunction:** Users can now toggle between mapping filters with `AND` or `OR` logic.
|
|
106
|
+
- **Async Comboboxes:** Full debounce support for `useFilterOptions` when fetching dynamic records from your API.
|
|
107
|
+
|
|
93
108
|
## Options
|
|
94
109
|
|
|
95
110
|
If you have modified the component files and want to reset them to their original state, or if the installation failed halfway and you want to try again, use the `--force` flag:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAy1CH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAyBtE"}
|
package/dist/templates/index.js
CHANGED
|
@@ -714,9 +714,9 @@ export function FieldSelect({ rowId, selectedField }: FieldSelectProps) {
|
|
|
714
714
|
variant="outline"
|
|
715
715
|
role="combobox"
|
|
716
716
|
aria-expanded={open}
|
|
717
|
-
className="w-[
|
|
717
|
+
className="w-[160px] justify-between font-normal"
|
|
718
718
|
>
|
|
719
|
-
{selectedField ? selectedField.label : "Select field..."}
|
|
719
|
+
<span className="truncate">{selectedField ? selectedField.label : "Select field..."}</span>
|
|
720
720
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
|
721
721
|
</Button>
|
|
722
722
|
</PopoverTrigger>
|
|
@@ -781,6 +781,11 @@ export interface FilterBarProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
781
781
|
searchValue?: string;
|
|
782
782
|
onSearchChange?: (value: string) => void;
|
|
783
783
|
hideSearch?: boolean;
|
|
784
|
+
/**
|
|
785
|
+
* Defines the layout order: "search-filters" or "filters-search"
|
|
786
|
+
* @default "search-filters"
|
|
787
|
+
*/
|
|
788
|
+
layout?: "search-filters" | "filters-search";
|
|
784
789
|
}
|
|
785
790
|
|
|
786
791
|
export const FilterBar = React.forwardRef<HTMLDivElement, FilterBarProps>(
|
|
@@ -791,6 +796,7 @@ export const FilterBar = React.forwardRef<HTMLDivElement, FilterBarProps>(
|
|
|
791
796
|
searchValue: externalSearchValue,
|
|
792
797
|
onSearchChange,
|
|
793
798
|
hideSearch = false,
|
|
799
|
+
layout = "search-filters",
|
|
794
800
|
...props
|
|
795
801
|
},
|
|
796
802
|
ref,
|
|
@@ -847,25 +853,40 @@ export const FilterBar = React.forwardRef<HTMLDivElement, FilterBarProps>(
|
|
|
847
853
|
}, 300);
|
|
848
854
|
};
|
|
849
855
|
|
|
856
|
+
const searchComponent = !hideSearch && (
|
|
857
|
+
<div className="flex-1 max-w-sm">
|
|
858
|
+
<div className="relative">
|
|
859
|
+
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
|
860
|
+
<Input
|
|
861
|
+
type="search"
|
|
862
|
+
placeholder={searchPlaceholder}
|
|
863
|
+
className="pl-8"
|
|
864
|
+
value={localValue}
|
|
865
|
+
onChange={(e) => handleSearchChange(e.target.value)}
|
|
866
|
+
/>
|
|
867
|
+
</div>
|
|
868
|
+
</div>
|
|
869
|
+
);
|
|
870
|
+
|
|
871
|
+
const filtersComponent = (
|
|
872
|
+
<div className="flex items-center gap-2">
|
|
873
|
+
<FilterRoot />
|
|
874
|
+
</div>
|
|
875
|
+
);
|
|
876
|
+
|
|
850
877
|
return (
|
|
851
878
|
<div ref={ref} className={cn("flex items-center justify-between gap-4", className)} {...props}>
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
</div>
|
|
864
|
-
)}
|
|
865
|
-
</div>
|
|
866
|
-
<div className="flex items-center gap-2">
|
|
867
|
-
<FilterRoot />
|
|
868
|
-
</div>
|
|
879
|
+
{layout === "filters-search" ? (
|
|
880
|
+
<>
|
|
881
|
+
{filtersComponent}
|
|
882
|
+
{searchComponent}
|
|
883
|
+
</>
|
|
884
|
+
) : (
|
|
885
|
+
<>
|
|
886
|
+
{searchComponent}
|
|
887
|
+
{filtersComponent}
|
|
888
|
+
</>
|
|
889
|
+
)}
|
|
869
890
|
</div>
|
|
870
891
|
);
|
|
871
892
|
},
|
|
@@ -955,7 +976,7 @@ export function FilterRoot() {
|
|
|
955
976
|
<FilterBadge />
|
|
956
977
|
</Button>
|
|
957
978
|
</PopoverTrigger>
|
|
958
|
-
<PopoverContent className="w-[
|
|
979
|
+
<PopoverContent className="w-[95vw] sm:w-[720px] p-4" align="end">
|
|
959
980
|
<ScrollArea className="max-h-[400px] pr-4">
|
|
960
981
|
<div className="flex flex-col gap-2">
|
|
961
982
|
{state.rows.length === 0 ? (
|
|
@@ -1008,7 +1029,7 @@ export function FilterRowComponent({ rowId }: FilterRowProps) {
|
|
|
1008
1029
|
variant="ghost"
|
|
1009
1030
|
size="icon"
|
|
1010
1031
|
onClick={() => removeRow(row.id)}
|
|
1011
|
-
className="ml-auto
|
|
1032
|
+
className="ml-auto shrink-0"
|
|
1012
1033
|
aria-label="Remove filter"
|
|
1013
1034
|
>
|
|
1014
1035
|
<Trash2 className="h-4 w-4 text-muted-foreground" />
|
|
@@ -1054,7 +1075,7 @@ export function OperatorSelect({ rowId, selectedField, selectedOperator }: Opera
|
|
|
1054
1075
|
if (!fieldDef) {
|
|
1055
1076
|
return (
|
|
1056
1077
|
<Select disabled>
|
|
1057
|
-
<SelectTrigger className="w-[
|
|
1078
|
+
<SelectTrigger className="w-[160px]">
|
|
1058
1079
|
<SelectValue placeholder="Operator" />
|
|
1059
1080
|
</SelectTrigger>
|
|
1060
1081
|
</Select>
|
|
@@ -1065,7 +1086,7 @@ export function OperatorSelect({ rowId, selectedField, selectedOperator }: Opera
|
|
|
1065
1086
|
|
|
1066
1087
|
return (
|
|
1067
1088
|
<Select value={selectedOperator || ""} onValueChange={(val) => updateOperator(rowId, val as OperatorType)}>
|
|
1068
|
-
<SelectTrigger className="w-[
|
|
1089
|
+
<SelectTrigger className="w-[160px]">
|
|
1069
1090
|
<SelectValue placeholder="Select operator..." />
|
|
1070
1091
|
</SelectTrigger>
|
|
1071
1092
|
<SelectContent>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,KAAK,GAAG,WAAW,CAAC;AAE1B,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsB7B,CAAC;AAEF,MAAM,6BAA6B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BrC,CAAC;AAEF,MAAM,iCAAiC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DzC,CAAC;AAEF,MAAM,8BAA8B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8FtC,CAAC;AAEF,MAAM,8BAA8B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BtC,CAAC;AAEF,MAAM,oCAAoC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2C5C,CAAC;AAEF,MAAM,kCAAkC,GAAG;;;;;;;;;;;;;;;;;;;;CAoB1C,CAAC;AAEF,MAAM,kCAAkC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqE1C,CAAC;AAEF,MAAM,qCAAqC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmE7C,CAAC;AAEF,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;CAmBzB,CAAC;AAEF,MAAM,mCAAmC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmC3C,CAAC;AAEF,MAAM,qCAAqC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmF7C,CAAC;AAEF,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqGzB,CAAC;AAEF,MAAM,4BAA4B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DpC,CAAC;AAEF,MAAM,4BAA4B,GAAG;;;;;;;;;;;;;;;;CAgBpC,CAAC;AAEF,MAAM,0BAA0B,GAAG
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/templates/index.ts
CHANGED
|
@@ -729,9 +729,9 @@ export function FieldSelect({ rowId, selectedField }: FieldSelectProps) {
|
|
|
729
729
|
variant="outline"
|
|
730
730
|
role="combobox"
|
|
731
731
|
aria-expanded={open}
|
|
732
|
-
className="w-[
|
|
732
|
+
className="w-[160px] justify-between font-normal"
|
|
733
733
|
>
|
|
734
|
-
{selectedField ? selectedField.label : "Select field..."}
|
|
734
|
+
<span className="truncate">{selectedField ? selectedField.label : "Select field..."}</span>
|
|
735
735
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
|
736
736
|
</Button>
|
|
737
737
|
</PopoverTrigger>
|
|
@@ -798,6 +798,11 @@ export interface FilterBarProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
798
798
|
searchValue?: string;
|
|
799
799
|
onSearchChange?: (value: string) => void;
|
|
800
800
|
hideSearch?: boolean;
|
|
801
|
+
/**
|
|
802
|
+
* Defines the layout order: "search-filters" or "filters-search"
|
|
803
|
+
* @default "search-filters"
|
|
804
|
+
*/
|
|
805
|
+
layout?: "search-filters" | "filters-search";
|
|
801
806
|
}
|
|
802
807
|
|
|
803
808
|
export const FilterBar = React.forwardRef<HTMLDivElement, FilterBarProps>(
|
|
@@ -808,6 +813,7 @@ export const FilterBar = React.forwardRef<HTMLDivElement, FilterBarProps>(
|
|
|
808
813
|
searchValue: externalSearchValue,
|
|
809
814
|
onSearchChange,
|
|
810
815
|
hideSearch = false,
|
|
816
|
+
layout = "search-filters",
|
|
811
817
|
...props
|
|
812
818
|
},
|
|
813
819
|
ref,
|
|
@@ -864,25 +870,40 @@ export const FilterBar = React.forwardRef<HTMLDivElement, FilterBarProps>(
|
|
|
864
870
|
}, 300);
|
|
865
871
|
};
|
|
866
872
|
|
|
873
|
+
const searchComponent = !hideSearch && (
|
|
874
|
+
<div className="flex-1 max-w-sm">
|
|
875
|
+
<div className="relative">
|
|
876
|
+
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
|
877
|
+
<Input
|
|
878
|
+
type="search"
|
|
879
|
+
placeholder={searchPlaceholder}
|
|
880
|
+
className="pl-8"
|
|
881
|
+
value={localValue}
|
|
882
|
+
onChange={(e) => handleSearchChange(e.target.value)}
|
|
883
|
+
/>
|
|
884
|
+
</div>
|
|
885
|
+
</div>
|
|
886
|
+
);
|
|
887
|
+
|
|
888
|
+
const filtersComponent = (
|
|
889
|
+
<div className="flex items-center gap-2">
|
|
890
|
+
<FilterRoot />
|
|
891
|
+
</div>
|
|
892
|
+
);
|
|
893
|
+
|
|
867
894
|
return (
|
|
868
895
|
<div ref={ref} className={cn("flex items-center justify-between gap-4", className)} {...props}>
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
</div>
|
|
881
|
-
)}
|
|
882
|
-
</div>
|
|
883
|
-
<div className="flex items-center gap-2">
|
|
884
|
-
<FilterRoot />
|
|
885
|
-
</div>
|
|
896
|
+
{layout === "filters-search" ? (
|
|
897
|
+
<>
|
|
898
|
+
{filtersComponent}
|
|
899
|
+
{searchComponent}
|
|
900
|
+
</>
|
|
901
|
+
) : (
|
|
902
|
+
<>
|
|
903
|
+
{searchComponent}
|
|
904
|
+
{filtersComponent}
|
|
905
|
+
</>
|
|
906
|
+
)}
|
|
886
907
|
</div>
|
|
887
908
|
);
|
|
888
909
|
},
|
|
@@ -974,7 +995,7 @@ export function FilterRoot() {
|
|
|
974
995
|
<FilterBadge />
|
|
975
996
|
</Button>
|
|
976
997
|
</PopoverTrigger>
|
|
977
|
-
<PopoverContent className="w-[
|
|
998
|
+
<PopoverContent className="w-[95vw] sm:w-[720px] p-4" align="end">
|
|
978
999
|
<ScrollArea className="max-h-[400px] pr-4">
|
|
979
1000
|
<div className="flex flex-col gap-2">
|
|
980
1001
|
{state.rows.length === 0 ? (
|
|
@@ -1028,7 +1049,7 @@ export function FilterRowComponent({ rowId }: FilterRowProps) {
|
|
|
1028
1049
|
variant="ghost"
|
|
1029
1050
|
size="icon"
|
|
1030
1051
|
onClick={() => removeRow(row.id)}
|
|
1031
|
-
className="ml-auto
|
|
1052
|
+
className="ml-auto shrink-0"
|
|
1032
1053
|
aria-label="Remove filter"
|
|
1033
1054
|
>
|
|
1034
1055
|
<Trash2 className="h-4 w-4 text-muted-foreground" />
|
|
@@ -1075,7 +1096,7 @@ export function OperatorSelect({ rowId, selectedField, selectedOperator }: Opera
|
|
|
1075
1096
|
if (!fieldDef) {
|
|
1076
1097
|
return (
|
|
1077
1098
|
<Select disabled>
|
|
1078
|
-
<SelectTrigger className="w-[
|
|
1099
|
+
<SelectTrigger className="w-[160px]">
|
|
1079
1100
|
<SelectValue placeholder="Operator" />
|
|
1080
1101
|
</SelectTrigger>
|
|
1081
1102
|
</Select>
|
|
@@ -1086,7 +1107,7 @@ export function OperatorSelect({ rowId, selectedField, selectedOperator }: Opera
|
|
|
1086
1107
|
|
|
1087
1108
|
return (
|
|
1088
1109
|
<Select value={selectedOperator || ""} onValueChange={(val) => updateOperator(rowId, val as OperatorType)}>
|
|
1089
|
-
<SelectTrigger className="w-[
|
|
1110
|
+
<SelectTrigger className="w-[160px]">
|
|
1090
1111
|
<SelectValue placeholder="Select operator..." />
|
|
1091
1112
|
</SelectTrigger>
|
|
1092
1113
|
<SelectContent>
|