@chiselandco/nexus 3.0.0 → 3.1.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/README.md +27 -62
- package/dist/FilteredPortfolio.d.ts +1 -1
- package/dist/FilteredPortfolio.d.ts.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Self-contained project portfolio components for Next.js App Router. Pass a `clientSlug`, `apiBase`, and `apiKey` — each component fetches, caches, and renders everything it needs with no client-side waterfall requests.
|
|
4
4
|
|
|
5
|
-
**Version:** 3.
|
|
5
|
+
**Version:** 3.1.0
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -29,7 +29,7 @@ The most common full setup — a filterable projects grid, a detail page with si
|
|
|
29
29
|
|
|
30
30
|
```tsx
|
|
31
31
|
// app/projects/page.tsx
|
|
32
|
-
import {
|
|
32
|
+
import { ProjectPortfolio } from "@chiselandco/nexus"
|
|
33
33
|
|
|
34
34
|
export default async function ProjectsPage({
|
|
35
35
|
searchParams,
|
|
@@ -37,7 +37,7 @@ export default async function ProjectsPage({
|
|
|
37
37
|
searchParams: Promise<Record<string, string | string[] | undefined>>
|
|
38
38
|
}) {
|
|
39
39
|
return (
|
|
40
|
-
<
|
|
40
|
+
<ProjectPortfolio
|
|
41
41
|
clientSlug="your-client-slug"
|
|
42
42
|
apiBase="https://your-api.com"
|
|
43
43
|
apiKey={process.env.YOUR_CLIENT_API_KEY!}
|
|
@@ -115,58 +115,11 @@ export function Nav() {
|
|
|
115
115
|
|
|
116
116
|
## Components
|
|
117
117
|
|
|
118
|
-
### `FilteredPortfolio`
|
|
119
|
-
|
|
120
|
-
Server component. The recommended primary projects grid. Fetches all projects once, reads `filter[key]=` URL params server-side to narrow results using AND-across-fields / OR-within-field logic, then renders a project count toolbar with a `FilterSidebar` trigger above a responsive card grid.
|
|
121
|
-
|
|
122
|
-
```tsx
|
|
123
|
-
import { FilteredPortfolio } from "@chiselandco/nexus"
|
|
124
|
-
|
|
125
|
-
export default async function ProjectsPage({
|
|
126
|
-
searchParams,
|
|
127
|
-
}: {
|
|
128
|
-
searchParams: Promise<Record<string, string | string[] | undefined>>
|
|
129
|
-
}) {
|
|
130
|
-
return (
|
|
131
|
-
<FilteredPortfolio
|
|
132
|
-
clientSlug="your-client-slug"
|
|
133
|
-
apiBase="https://your-api.com"
|
|
134
|
-
apiKey={process.env.YOUR_CLIENT_API_KEY!}
|
|
135
|
-
basePath="/projects"
|
|
136
|
-
searchParams={await searchParams}
|
|
137
|
-
/>
|
|
138
|
-
)
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
| Prop | Type | Required | Default | Description |
|
|
143
|
-
|---|---|---|---|---|
|
|
144
|
-
| `clientSlug` | `string` | Yes | — | Client identifier passed to the API |
|
|
145
|
-
| `apiBase` | `string` | Yes | — | Base URL of the Chisel API |
|
|
146
|
-
| `apiKey` | `string` | Yes | — | Client API key — always pass via environment variable, never hardcode |
|
|
147
|
-
| `searchParams` | `Record<string, string \| string[] \| undefined>` | Yes | — | Resolved Next.js `searchParams` — await it before passing in Next.js 16+ |
|
|
148
|
-
| `basePath` | `string` | No | `"/projects"` | Base path for project detail card links |
|
|
149
|
-
| `filterKeys` | `string[]` | No | All eligible fields | Ordered list of field keys to expose in the filter drawer |
|
|
150
|
-
| `font` | `string` | No | System font | Font family string |
|
|
151
|
-
| `noCache` | `boolean` | No | `false` | Sets `cache: "no-store"` — useful during development |
|
|
152
|
-
| `revalidate` | `number` | No | `86400` | Cache revalidation period in seconds |
|
|
153
|
-
| `filterBy` | `{ field: string; value: string }` | No | — | Pre-filter projects by any custom field value. See [Filtering by field](#filtering-by-field). |
|
|
154
|
-
|
|
155
|
-
#### URL param format
|
|
156
|
-
|
|
157
|
-
Filters are written to and read from URL params in the form `filter[fieldKey]=slug1,slug2`. Multiple values within a field are OR'd; multiple fields are AND'd.
|
|
158
|
-
|
|
159
|
-
```
|
|
160
|
-
/projects?filter[application]=hospitality,education&filter[systems]=spacematic
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
118
|
### `FilterSidebar`
|
|
166
119
|
|
|
167
120
|
Client component (`"use client"`). Renders an "Advanced Filters" trigger that opens a right-side drawer with one section per filterable field. Pills are solid black when active and outlined when inactive. Filter state is written to URL params so filtered views are shareable and survive page refresh.
|
|
168
121
|
|
|
169
|
-
|
|
122
|
+
Use alongside `ProjectPortfolio` when you want user-driven filtering — place it wherever suits your layout and pass the same `searchParams` to `ProjectPortfolio`.
|
|
170
123
|
|
|
171
124
|
```tsx
|
|
172
125
|
import { FilterSidebar } from "@chiselandco/nexus"
|
|
@@ -536,7 +489,7 @@ export function Nav() {
|
|
|
536
489
|
|
|
537
490
|
### `ProjectPortfolio`
|
|
538
491
|
|
|
539
|
-
Server component. Fetches all projects and renders a responsive
|
|
492
|
+
Server component. The primary projects grid. Fetches all projects, reads `filter[key]=` URL params server-side to narrow results, and renders a responsive card grid (1 col mobile / 2 col tablet / 3 col desktop). Pair with `FilterSidebar` when you want user-driven filtering — place it wherever suits your layout.
|
|
540
493
|
|
|
541
494
|
```tsx
|
|
542
495
|
// app/projects/page.tsx
|
|
@@ -617,11 +570,11 @@ export default function ProjectsPage() {
|
|
|
617
570
|
|
|
618
571
|
## Filtering by field
|
|
619
572
|
|
|
620
|
-
`
|
|
573
|
+
`ProjectPortfolio`, `ProjectPortfolioClient`, and `SimilarProjects` all accept an optional `filterBy` prop. It pre-filters the project list by any custom field value before any user-driven filters are applied.
|
|
621
574
|
|
|
622
575
|
```tsx
|
|
623
576
|
// Only show projects where custom field "side" equals "architectural" or "both"
|
|
624
|
-
<
|
|
577
|
+
<ProjectPortfolio
|
|
625
578
|
clientSlug="hollaender"
|
|
626
579
|
apiBase="https://your-api.com"
|
|
627
580
|
apiKey={process.env.HOLLAENDER_API_KEY!}
|
|
@@ -631,7 +584,7 @@ export default function ProjectsPage() {
|
|
|
631
584
|
/>
|
|
632
585
|
|
|
633
586
|
// Only show projects where custom field "side" equals "speedrail" or "both"
|
|
634
|
-
<
|
|
587
|
+
<ProjectPortfolio
|
|
635
588
|
clientSlug="hollaender"
|
|
636
589
|
apiBase="https://your-api.com"
|
|
637
590
|
apiKey={process.env.HOLLAENDER_API_KEY!}
|
|
@@ -655,10 +608,24 @@ The `"both"` fallback is built in — if a project's field value is `"both"` it
|
|
|
655
608
|
|
|
656
609
|
```tsx
|
|
657
610
|
// v2
|
|
658
|
-
<
|
|
611
|
+
<ProjectPortfolio side="architectural" />
|
|
659
612
|
|
|
660
613
|
// v3
|
|
661
|
-
<
|
|
614
|
+
<ProjectPortfolio filterBy={{ field: "side", value: "architectural" }} />
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### Migration from v3.0 `FilteredPortfolio`
|
|
618
|
+
|
|
619
|
+
`FilteredPortfolio` was removed in v3.1. Use `ProjectPortfolio` directly — it has the same props. Pair with `FilterSidebar` if you want a filter drawer.
|
|
620
|
+
|
|
621
|
+
```tsx
|
|
622
|
+
// v3.0
|
|
623
|
+
import { FilteredPortfolio } from "@chiselandco/nexus"
|
|
624
|
+
<FilteredPortfolio clientSlug="..." apiBase="..." apiKey={...} searchParams={searchParams} />
|
|
625
|
+
|
|
626
|
+
// v3.1
|
|
627
|
+
import { ProjectPortfolio } from "@chiselandco/nexus"
|
|
628
|
+
<ProjectPortfolio clientSlug="..." apiBase="..." apiKey={...} searchParams={searchParams} />
|
|
662
629
|
```
|
|
663
630
|
|
|
664
631
|
---
|
|
@@ -667,10 +634,9 @@ The `"both"` fallback is built in — if a project's field value is `"both"` it
|
|
|
667
634
|
|
|
668
635
|
| Component | Type | Notes |
|
|
669
636
|
|---|---|---|
|
|
670
|
-
| `
|
|
671
|
-
| `FilterSidebar` | Client |
|
|
672
|
-
| `
|
|
673
|
-
| `ProjectPortfolioClient` | Client | For use inside client trees |
|
|
637
|
+
| `ProjectPortfolio` | Server | Primary projects grid |
|
|
638
|
+
| `FilterSidebar` | Client | Optional filter drawer — pair with `ProjectPortfolio` |
|
|
639
|
+
| `ProjectPortfolioClient` | Client | For use inside client component trees |
|
|
674
640
|
| `ProjectDetail` | Server | Full project detail page |
|
|
675
641
|
| `GalleryCarousel` | Client | Used internally by `ProjectDetail` |
|
|
676
642
|
| `SimilarProjects` | Server | After `ProjectDetail` on detail pages |
|
|
@@ -685,7 +651,6 @@ All server components must be rendered in a server context. If your parent compo
|
|
|
685
651
|
|
|
686
652
|
| Component | Server cache | Client cache |
|
|
687
653
|
|---|---|---|
|
|
688
|
-
| `FilteredPortfolio` | 24h via `next.revalidate` | — |
|
|
689
654
|
| `ProjectPortfolio` | 24h via `next.revalidate` | — |
|
|
690
655
|
| `ProjectDetail` | 24h via `next.revalidate` | — |
|
|
691
656
|
| `SimilarProjects` | 24h via `next.revalidate` | — |
|
|
@@ -52,5 +52,5 @@ export interface FilteredPortfolioProps {
|
|
|
52
52
|
* )
|
|
53
53
|
* }
|
|
54
54
|
*/
|
|
55
|
-
export declare function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchParams, filterKeys, basePath, revalidate, noCache, font, filterBy, }: FilteredPortfolioProps): Promise<import("react").JSX.Element>;
|
|
55
|
+
export declare function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchParams, filterKeys, basePath, revalidate, noCache, font, filterBy, }: FilteredPortfolioProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
56
56
|
//# sourceMappingURL=FilteredPortfolio.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilteredPortfolio.d.ts","sourceRoot":"","sources":["../src/FilteredPortfolio.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IAC5D;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5C;AA8ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,UAAU,EACV,OAAO,EACP,MAAM,EACN,YAAiB,EACjB,UAAU,EACV,QAAsB,EACtB,UAAe,EACf,OAAe,EACf,IAAI,EACJ,QAAQ,GACT,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"FilteredPortfolio.d.ts","sourceRoot":"","sources":["../src/FilteredPortfolio.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IAC5D;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5C;AA8ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,UAAU,EACV,OAAO,EACP,MAAM,EACN,YAAiB,EACjB,UAAU,EACV,QAAsB,EACtB,UAAe,EACf,OAAe,EACf,IAAI,EACJ,QAAQ,GACT,EAAE,sBAAsB,oDAqGxB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,5 @@ export { ProjectCard } from "./ProjectCard";
|
|
|
16
16
|
export type { CardVariant } from "./ProjectCard";
|
|
17
17
|
export { FilterSidebar } from "./FilterSidebar";
|
|
18
18
|
export type { FilterSidebarProps } from "./FilterSidebar";
|
|
19
|
-
export { FilteredPortfolio } from "./FilteredPortfolio";
|
|
20
|
-
export type { FilteredPortfolioProps } from "./FilteredPortfolio";
|
|
21
19
|
export type { Project, CustomFieldSchema, CustomFieldValue, LocationValue, Media, } from "./types";
|
|
22
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AACjE,YAAY,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACpF,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AACjE,YAAY,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACpF,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,KAAK,GACN,MAAM,SAAS,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -7,4 +7,3 @@ export { ProjectMenu, fetchProjectMenuData, createMenuHandler } from "./ProjectM
|
|
|
7
7
|
export { ProjectMenuClient } from "./ProjectMenuClient";
|
|
8
8
|
export { ProjectCard } from "./ProjectCard";
|
|
9
9
|
export { FilterSidebar } from "./FilterSidebar";
|
|
10
|
-
export { FilteredPortfolio } from "./FilteredPortfolio";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chiselandco/nexus",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "Self-contained project portfolio components for Next.js App Router. Includes ProjectPortfolio, ProjectPortfolioClient, ProjectDetail, SimilarProjects, ProjectMenu, ProjectMenuClient, GalleryCarousel,
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "Self-contained project portfolio components for Next.js App Router. Includes ProjectPortfolio, ProjectPortfolioClient, ProjectDetail, SimilarProjects, ProjectMenu, ProjectMenuClient, GalleryCarousel, and FilterSidebar. Pass a clientSlug and apiBase — done.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nextjs",
|
|
7
7
|
"react",
|