filtercn 0.1.0 → 0.1.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 +103 -0
- package/dist/templates/index.js +24 -8
- package/dist/templates/index.js.map +1 -1
- package/package.json +1 -1
- package/src/templates/index.ts +24 -8
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# FilterCN CLI
|
|
2
|
+
|
|
3
|
+
The official CLI tool to automatically install the [FilterCN](https://github.com/tmduoc/filtercn) component into your Next.js project.
|
|
4
|
+
|
|
5
|
+
FilterCN is a comprehensive, fully-customizable filter component built on top of [shadcn/ui](https://ui.shadcn.com/). It provides a visual filter builder UI that syncs state to URL search parameters, ideal for REST API-powered data tables.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
Before using this CLI, your project must have **Next.js**, **React**, and **shadcn/ui** installed and configured.
|
|
10
|
+
|
|
11
|
+
You also need the following shadcn/ui components installed in your project:
|
|
12
|
+
```bash
|
|
13
|
+
npx shadcn@latest add button input select popover calendar command badge
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
You do not need to install this CLI globally. Instead, run it directly using your preferred package manager's executor:
|
|
21
|
+
|
|
22
|
+
**Using npm:**
|
|
23
|
+
```bash
|
|
24
|
+
npx filtercn init
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Using pnpm:**
|
|
28
|
+
```bash
|
|
29
|
+
pnpm dlx filtercn init
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Using bun:**
|
|
33
|
+
```bash
|
|
34
|
+
bunx filtercn init
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Using yarn:**
|
|
38
|
+
```bash
|
|
39
|
+
yarn dlx filtercn init
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### What happens when I run this?
|
|
43
|
+
|
|
44
|
+
The CLI will interactively guide you through the setup:
|
|
45
|
+
1. **Detects Environment:** It automatically finds your `src/components` (or `components`) folder and your TypeScript import aliases (e.g., `@/`).
|
|
46
|
+
2. **Prompts for Confirmation:** It asks if you want to proceed with writing files.
|
|
47
|
+
3. **Scaffolds Files:** It creates a `conditional-filter` folder with all 19 necessary files (Types, Hooks, Helpers, Context Provider, and UI components).
|
|
48
|
+
4. **Installs Dependencies:** It checks if you have `lucide-react` and `date-fns` installed. If you don't, it will ask to automatically install them for you using your detected package manager.
|
|
49
|
+
|
|
50
|
+
## Post-Installation Usage
|
|
51
|
+
|
|
52
|
+
Once the CLI finishes, you can immediately start using the component in your pages.
|
|
53
|
+
|
|
54
|
+
Here is a quick example of how to wrap your data table with the filter:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
"use client";
|
|
58
|
+
|
|
59
|
+
import { FilterProvider, FilterRoot } from "@/components/conditional-filter";
|
|
60
|
+
import type { FilterFieldDefinition } from "@/components/conditional-filter";
|
|
61
|
+
|
|
62
|
+
// 1. Define the fields your users can filter by
|
|
63
|
+
const filterFields: FilterFieldDefinition[] = [
|
|
64
|
+
{ name: "title", label: "Project Title", type: "text" },
|
|
65
|
+
{
|
|
66
|
+
name: "status",
|
|
67
|
+
label: "Status",
|
|
68
|
+
type: "select",
|
|
69
|
+
options: [
|
|
70
|
+
{ label: "Active", value: "active" },
|
|
71
|
+
{ label: "Archived", value: "archived" },
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
{ name: "price", label: "Budget", type: "number" },
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
export default function MyPage() {
|
|
78
|
+
return (
|
|
79
|
+
<div className="p-8 space-y-4">
|
|
80
|
+
<h1 className="text-2xl font-bold">Projects</h1>
|
|
81
|
+
|
|
82
|
+
{/* 2. Wrap the filter root in the provider */}
|
|
83
|
+
<FilterProvider config={{ fields: filterFields, paramStyle: "underscore" }}>
|
|
84
|
+
<FilterRoot />
|
|
85
|
+
</FilterProvider>
|
|
86
|
+
|
|
87
|
+
{/* Your data table goes here */}
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Options
|
|
94
|
+
|
|
95
|
+
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:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npx filtercn init --force
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
MIT
|
package/dist/templates/index.js
CHANGED
|
@@ -1087,26 +1087,42 @@ export function FilterRowComponent({ rowId }: FilterRowProps) {
|
|
|
1087
1087
|
import { Plus, RotateCcw, Check } from "lucide-react";
|
|
1088
1088
|
import { Button } from "${alias}components/ui/button";
|
|
1089
1089
|
import { useFilterContext } from "../provider/filter-context";
|
|
1090
|
+
import { PopoverClose } from "${alias}components/ui/popover";
|
|
1091
|
+
import { isValidFilterRow } from "../helpers/validators";
|
|
1090
1092
|
|
|
1091
1093
|
export function FilterFooter() {
|
|
1092
1094
|
const { config, state, addRow, reset, apply } = useFilterContext();
|
|
1093
1095
|
const maxRows = config.maxRows || 10;
|
|
1094
1096
|
const canAdd = state.rows.length < maxRows;
|
|
1095
1097
|
|
|
1098
|
+
// Determine if there is at least one valid filter row
|
|
1099
|
+
const hasValidFilters = state.rows.some(isValidFilterRow);
|
|
1100
|
+
|
|
1096
1101
|
return (
|
|
1097
1102
|
<div className="flex items-center gap-2 pt-2">
|
|
1098
1103
|
<Button variant="outline" size="sm" onClick={addRow} disabled={!canAdd}>
|
|
1099
1104
|
<Plus className="mr-1 h-4 w-4" />
|
|
1100
1105
|
{config.locale?.addFilter || "+ Add filter"}
|
|
1101
1106
|
</Button>
|
|
1102
|
-
<
|
|
1103
|
-
<
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1107
|
+
<PopoverClose asChild>
|
|
1108
|
+
<Button variant="ghost" size="sm" onClick={reset}>
|
|
1109
|
+
<RotateCcw className="mr-1 h-4 w-4" />
|
|
1110
|
+
{config.locale?.reset || "Reset"}
|
|
1111
|
+
</Button>
|
|
1112
|
+
</PopoverClose>
|
|
1113
|
+
{hasValidFilters ? (
|
|
1114
|
+
<PopoverClose asChild>
|
|
1115
|
+
<Button size="sm" onClick={apply}>
|
|
1116
|
+
<Check className="mr-1 h-4 w-4" />
|
|
1117
|
+
{config.locale?.apply || "Apply"}
|
|
1118
|
+
</Button>
|
|
1119
|
+
</PopoverClose>
|
|
1120
|
+
) : (
|
|
1121
|
+
<Button size="sm" disabled>
|
|
1122
|
+
<Check className="mr-1 h-4 w-4" />
|
|
1123
|
+
{config.locale?.apply || "Apply"}
|
|
1124
|
+
</Button>
|
|
1125
|
+
)}
|
|
1110
1126
|
</div>
|
|
1111
1127
|
);
|
|
1112
1128
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,KAAK,GAAG,WAAW,CAAC;AAE1B,uDAAuD;AACvD,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4Fb,CAAC;AAEF,2DAA2D;AAC3D,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBjB,CAAC;AAEF,mEAAmE;AACnE,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BjB,CAAC;AAEF,oEAAoE;AACpE,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BlB,CAAC;AAEF,uEAAuE;AACvE,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DrB,CAAC;AAEF,oEAAoE;AACpE,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoFlB,CAAC;AAEF,wEAAwE;AACxE,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0ExB,CAAC;AAEF,2EAA2E;AAC3E,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgD3B,CAAC;AAEF,0EAA0E;AAC1E,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B1B,CAAC;AAEF,yEAAyE;AACzE,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCtB,CAAC;AAEF,2EAA2E;AAC3E,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwFvB,CAAC;AAEF,uDAAuD;AACvD,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;CAmBb,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,iEAAiE;IACjE,MAAM,YAAY,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAE3E,OAAO;QACL,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC;QAC/B,cAAc,EAAE,YAAY,CAAC,SAAS,CAAC;QACvC,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC;QAC/B,sBAAsB,EAAE,YAAY,CAAC,SAAS,CAAC;QAC/C,uBAAuB,EAAE,YAAY,CAAC,UAAU,CAAC;QACjD,0BAA0B,EAAE,YAAY,CAAC,aAAa,CAAC;QACvD,uBAAuB,EAAE,YAAY,CAAC,UAAU,CAAC;QACjD,2BAA2B,EAAE,YAAY,CAAC,gBAAgB,CAAC;QAC3D,8BAA8B,EAAE,YAAY,CAAC,mBAAmB,CAAC;QACjE,6BAA6B,EAAE,YAAY,CAAC,kBAAkB,CAAC;QAC/D,4BAA4B,EAAE,YAAY,CAAC,cAAc,CAAC;QAC1D,8BAA8B,EAAE,YAAY,CAAC,eAAe,CAAC;QAC7D,GAAG,cAAc,CAAC,KAAK,CAAC;KACzB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,YAAY,GAAG;;;;0BAIG,KAAK;;;;;;;;UAQrB,KAAK;;;;;UAKL,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDd,CAAC;IAEA,MAAM,eAAe,GAAG;;;;;;;;UAQhB,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDd,CAAC;IAEA,MAAM,WAAW,GAAG;;;yBAGG,KAAK;;;;;;;UAOpB,KAAK;;;;;UAKL,KAAK;0BACW,KAAK;4BACH,KAAK;;;;;yBAKR,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmO7B,CAAC;IAEA,MAAM,UAAU,GAAG;;;0BAGK,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B9B,CAAC;IAEA,MAAM,aAAa,GAAG;;;0BAGE,KAAK;;gCAEC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCpC,CAAC;IAEA,MAAM,YAAY,GAAG;;;yBAGE,KAAK;;;;;;;CAO7B,CAAC;IAEA,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCrB,CAAC;IAEA,OAAO;QACL,qBAAqB,EAAE,YAAY;QACnC,wBAAwB,EAAE,eAAe;QACzC,oBAAoB,EAAE,WAAW;QACjC,mBAAmB,EAAE,UAAU;QAC/B,sBAAsB,EAAE,aAAa;QACrC,qBAAqB,EAAE,YAAY;QACnC,oBAAoB,EAAE,WAAW;KAClC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
package/src/templates/index.ts
CHANGED
|
@@ -1107,26 +1107,42 @@ export function FilterRowComponent({ rowId }: FilterRowProps) {
|
|
|
1107
1107
|
import { Plus, RotateCcw, Check } from "lucide-react";
|
|
1108
1108
|
import { Button } from "${alias}components/ui/button";
|
|
1109
1109
|
import { useFilterContext } from "../provider/filter-context";
|
|
1110
|
+
import { PopoverClose } from "${alias}components/ui/popover";
|
|
1111
|
+
import { isValidFilterRow } from "../helpers/validators";
|
|
1110
1112
|
|
|
1111
1113
|
export function FilterFooter() {
|
|
1112
1114
|
const { config, state, addRow, reset, apply } = useFilterContext();
|
|
1113
1115
|
const maxRows = config.maxRows || 10;
|
|
1114
1116
|
const canAdd = state.rows.length < maxRows;
|
|
1115
1117
|
|
|
1118
|
+
// Determine if there is at least one valid filter row
|
|
1119
|
+
const hasValidFilters = state.rows.some(isValidFilterRow);
|
|
1120
|
+
|
|
1116
1121
|
return (
|
|
1117
1122
|
<div className="flex items-center gap-2 pt-2">
|
|
1118
1123
|
<Button variant="outline" size="sm" onClick={addRow} disabled={!canAdd}>
|
|
1119
1124
|
<Plus className="mr-1 h-4 w-4" />
|
|
1120
1125
|
{config.locale?.addFilter || "+ Add filter"}
|
|
1121
1126
|
</Button>
|
|
1122
|
-
<
|
|
1123
|
-
<
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1127
|
+
<PopoverClose asChild>
|
|
1128
|
+
<Button variant="ghost" size="sm" onClick={reset}>
|
|
1129
|
+
<RotateCcw className="mr-1 h-4 w-4" />
|
|
1130
|
+
{config.locale?.reset || "Reset"}
|
|
1131
|
+
</Button>
|
|
1132
|
+
</PopoverClose>
|
|
1133
|
+
{hasValidFilters ? (
|
|
1134
|
+
<PopoverClose asChild>
|
|
1135
|
+
<Button size="sm" onClick={apply}>
|
|
1136
|
+
<Check className="mr-1 h-4 w-4" />
|
|
1137
|
+
{config.locale?.apply || "Apply"}
|
|
1138
|
+
</Button>
|
|
1139
|
+
</PopoverClose>
|
|
1140
|
+
) : (
|
|
1141
|
+
<Button size="sm" disabled>
|
|
1142
|
+
<Check className="mr-1 h-4 w-4" />
|
|
1143
|
+
{config.locale?.apply || "Apply"}
|
|
1144
|
+
</Button>
|
|
1145
|
+
)}
|
|
1130
1146
|
</div>
|
|
1131
1147
|
);
|
|
1132
1148
|
}
|