@chiselandco/nexus 2.6.1 → 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 +52 -71
- package/dist/FilteredPortfolio.d.ts +10 -6
- package/dist/FilteredPortfolio.d.ts.map +1 -1
- package/dist/FilteredPortfolio.js +4 -4
- package/dist/ProjectPortfolio.d.ts +9 -6
- package/dist/ProjectPortfolio.d.ts.map +1 -1
- package/dist/ProjectPortfolio.js +4 -4
- package/dist/ProjectPortfolioClient.d.ts +9 -6
- package/dist/ProjectPortfolioClient.d.ts.map +1 -1
- package/dist/ProjectPortfolioClient.js +7 -7
- package/dist/SimilarProjects.d.ts +9 -6
- package/dist/SimilarProjects.d.ts.map +1 -1
- package/dist/SimilarProjects.js +5 -5
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -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:**
|
|
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
|
-
| `side` | `"architectural" \| "speedrail"` | No | — | Filter projects by website side. When omitted all projects are shown. See [Filtering by side](#filtering-by-side). |
|
|
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"
|
|
@@ -403,7 +356,7 @@ Use `variant="card"` to render baseball-card style instead of the default list s
|
|
|
403
356
|
| `font` | `string` | No | System font stack | Font family string |
|
|
404
357
|
| `revalidate` | `number` | No | `86400` | Cache revalidation period in seconds |
|
|
405
358
|
| `noCache` | `boolean` | No | `false` | Sets `cache: "no-store"` — useful during development |
|
|
406
|
-
| `
|
|
359
|
+
| `filterBy` | `{ field: string; value: string }` | No | — | Pre-filter projects by any custom field value. See [Filtering by field](#filtering-by-field). |
|
|
407
360
|
|
|
408
361
|
---
|
|
409
362
|
|
|
@@ -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
|
|
@@ -568,7 +521,7 @@ export default async function ProjectsPage({
|
|
|
568
521
|
| `searchParams` | `Record<string, string \| string[] \| undefined>` | No | `{}` | Filter params — pass Next.js `searchParams` directly |
|
|
569
522
|
| `revalidate` | `number` | No | `86400` | Cache revalidation period in seconds |
|
|
570
523
|
| `noCache` | `boolean` | No | `false` | Sets `cache: "no-store"` — useful during development |
|
|
571
|
-
| `
|
|
524
|
+
| `filterBy` | `{ field: string; value: string }` | No | — | Pre-filter projects by any custom field value. See [Filtering by field](#filtering-by-field). |
|
|
572
525
|
|
|
573
526
|
---
|
|
574
527
|
|
|
@@ -611,39 +564,69 @@ export default function ProjectsPage() {
|
|
|
611
564
|
| `filters` | `Record<string, string>` | No | `{}` | Active filters — filtering is instant, no API call on change |
|
|
612
565
|
| `columns` | `2 \| 3` | No | `3` | Number of grid columns |
|
|
613
566
|
| `font` | `string` | No | System font stack | Font family string |
|
|
614
|
-
| `
|
|
567
|
+
| `filterBy` | `{ field: string; value: string }` | No | — | Pre-filter projects by any custom field value. See [Filtering by field](#filtering-by-field). |
|
|
615
568
|
|
|
616
569
|
---
|
|
617
570
|
|
|
618
|
-
## Filtering by
|
|
619
|
-
|
|
620
|
-
Every project returned by the API includes a `side` field: `"architectural"`, `"speedrail"`, or `"both"`. This reflects which section of the client's website a project belongs to.
|
|
571
|
+
## Filtering by field
|
|
621
572
|
|
|
622
|
-
|
|
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.
|
|
623
574
|
|
|
624
575
|
```tsx
|
|
625
|
-
//
|
|
626
|
-
<
|
|
576
|
+
// Only show projects where custom field "side" equals "architectural" or "both"
|
|
577
|
+
<ProjectPortfolio
|
|
627
578
|
clientSlug="hollaender"
|
|
628
579
|
apiBase="https://your-api.com"
|
|
629
580
|
apiKey={process.env.HOLLAENDER_API_KEY!}
|
|
630
581
|
basePath="/architectural/projects"
|
|
631
582
|
searchParams={searchParams}
|
|
632
|
-
|
|
583
|
+
filterBy={{ field: "side", value: "architectural" }}
|
|
633
584
|
/>
|
|
634
585
|
|
|
635
|
-
//
|
|
636
|
-
<
|
|
586
|
+
// Only show projects where custom field "side" equals "speedrail" or "both"
|
|
587
|
+
<ProjectPortfolio
|
|
637
588
|
clientSlug="hollaender"
|
|
638
589
|
apiBase="https://your-api.com"
|
|
639
590
|
apiKey={process.env.HOLLAENDER_API_KEY!}
|
|
640
591
|
basePath="/speedrail/projects"
|
|
641
592
|
searchParams={searchParams}
|
|
642
|
-
|
|
593
|
+
filterBy={{ field: "side", value: "speedrail" }}
|
|
594
|
+
/>
|
|
595
|
+
|
|
596
|
+
// Works with any field — not just "side"
|
|
597
|
+
<ProjectPortfolio
|
|
598
|
+
clientSlug="acme"
|
|
599
|
+
apiBase="https://your-api.com"
|
|
600
|
+
apiKey={process.env.ACME_API_KEY!}
|
|
601
|
+
filterBy={{ field: "region", value: "northeast" }}
|
|
643
602
|
/>
|
|
644
603
|
```
|
|
645
604
|
|
|
646
|
-
|
|
605
|
+
The `"both"` fallback is built in — if a project's field value is `"both"` it matches any `filterBy.value`. When `filterBy` is omitted all projects are shown. No extra API calls are made — filtering happens in memory after the standard fetch.
|
|
606
|
+
|
|
607
|
+
### Migration from v2 `side` prop
|
|
608
|
+
|
|
609
|
+
```tsx
|
|
610
|
+
// v2
|
|
611
|
+
<ProjectPortfolio side="architectural" />
|
|
612
|
+
|
|
613
|
+
// v3
|
|
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} />
|
|
629
|
+
```
|
|
647
630
|
|
|
648
631
|
---
|
|
649
632
|
|
|
@@ -651,10 +634,9 @@ When `side` is omitted the component behaves exactly as before — all projects
|
|
|
651
634
|
|
|
652
635
|
| Component | Type | Notes |
|
|
653
636
|
|---|---|---|
|
|
654
|
-
| `
|
|
655
|
-
| `FilterSidebar` | Client |
|
|
656
|
-
| `
|
|
657
|
-
| `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 |
|
|
658
640
|
| `ProjectDetail` | Server | Full project detail page |
|
|
659
641
|
| `GalleryCarousel` | Client | Used internally by `ProjectDetail` |
|
|
660
642
|
| `SimilarProjects` | Server | After `ProjectDetail` on detail pages |
|
|
@@ -669,7 +651,6 @@ All server components must be rendered in a server context. If your parent compo
|
|
|
669
651
|
|
|
670
652
|
| Component | Server cache | Client cache |
|
|
671
653
|
|---|---|---|
|
|
672
|
-
| `FilteredPortfolio` | 24h via `next.revalidate` | — |
|
|
673
654
|
| `ProjectPortfolio` | 24h via `next.revalidate` | — |
|
|
674
655
|
| `ProjectDetail` | 24h via `next.revalidate` | — |
|
|
675
656
|
| `SimilarProjects` | 24h via `next.revalidate` | — |
|
|
@@ -20,12 +20,16 @@ export interface FilteredPortfolioProps {
|
|
|
20
20
|
noCache?: boolean;
|
|
21
21
|
font?: string;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
23
|
+
* Pre-filter projects by any custom field value before rendering.
|
|
24
|
+
* Useful for splitting a portfolio by a routing field (e.g. site section).
|
|
25
|
+
* e.g. filterBy={{ field: "side", value: "architectural" }}
|
|
26
|
+
* Projects where the field value equals the given value OR "both" are shown.
|
|
27
|
+
* When omitted all projects are shown.
|
|
27
28
|
*/
|
|
28
|
-
|
|
29
|
+
filterBy?: {
|
|
30
|
+
field: string;
|
|
31
|
+
value: string;
|
|
32
|
+
};
|
|
29
33
|
}
|
|
30
34
|
/**
|
|
31
35
|
* FilteredPortfolio — server component.
|
|
@@ -48,5 +52,5 @@ export interface FilteredPortfolioProps {
|
|
|
48
52
|
* )
|
|
49
53
|
* }
|
|
50
54
|
*/
|
|
51
|
-
export declare function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchParams, filterKeys, basePath, revalidate, noCache, font,
|
|
55
|
+
export declare function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchParams, filterKeys, basePath, revalidate, noCache, font, filterBy, }: FilteredPortfolioProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
52
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
|
|
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"}
|
|
@@ -74,7 +74,7 @@ async function fetchSchema(apiBase, clientSlug, apiKey, fetchOpts) {
|
|
|
74
74
|
* )
|
|
75
75
|
* }
|
|
76
76
|
*/
|
|
77
|
-
export async function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchParams = {}, filterKeys, basePath = "/projects", revalidate = 60, noCache = false, font,
|
|
77
|
+
export async function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchParams = {}, filterKeys, basePath = "/projects", revalidate = 60, noCache = false, font, filterBy, }) {
|
|
78
78
|
const fetchOpts = noCache
|
|
79
79
|
? { cache: "no-store" }
|
|
80
80
|
: { next: { revalidate } };
|
|
@@ -95,11 +95,11 @@ export async function FilteredPortfolio({ clientSlug, apiBase, apiKey, searchPar
|
|
|
95
95
|
fetchSchema(apiBase, clientSlug, apiKey, fetchOpts),
|
|
96
96
|
]);
|
|
97
97
|
const activeCount = Object.values(activeFilters).reduce((n, ids) => n + ids.length, 0);
|
|
98
|
-
const visible =
|
|
98
|
+
const visible = filterBy
|
|
99
99
|
? projects.filter((p) => {
|
|
100
100
|
var _a;
|
|
101
|
-
const
|
|
102
|
-
return
|
|
101
|
+
const v = (_a = p.custom_field_values) === null || _a === void 0 ? void 0 : _a[filterBy.field];
|
|
102
|
+
return v === filterBy.value || v === "both";
|
|
103
103
|
})
|
|
104
104
|
: projects;
|
|
105
105
|
return (_jsxs(_Fragment, { children: [_jsx("style", { children: `
|
|
@@ -25,12 +25,15 @@ export interface ProjectPortfolioProps {
|
|
|
25
25
|
*/
|
|
26
26
|
noCache?: boolean;
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
28
|
+
* Pre-filter projects by any custom field value before rendering.
|
|
29
|
+
* e.g. filterBy={{ field: "side", value: "architectural" }}
|
|
30
|
+
* Projects where the field value equals the given value OR "both" are shown.
|
|
31
|
+
* When omitted all projects are shown.
|
|
32
32
|
*/
|
|
33
|
-
|
|
33
|
+
filterBy?: {
|
|
34
|
+
field: string;
|
|
35
|
+
value: string;
|
|
36
|
+
};
|
|
34
37
|
}
|
|
35
38
|
/**
|
|
36
39
|
* ProjectPortfolio — pure self-fetching card grid.
|
|
@@ -47,5 +50,5 @@ export interface ProjectPortfolioProps {
|
|
|
47
50
|
* apiBase="https://your-api.com"
|
|
48
51
|
* />
|
|
49
52
|
*/
|
|
50
|
-
export declare function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath, searchParams, revalidate, noCache,
|
|
53
|
+
export declare function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath, searchParams, revalidate, noCache, filterBy, }: ProjectPortfolioProps): Promise<import("react").JSX.Element>;
|
|
51
54
|
//# sourceMappingURL=ProjectPortfolio.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectPortfolio.d.ts","sourceRoot":"","sources":["../src/ProjectPortfolio.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IAC5D;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;OAKG;IACH,
|
|
1
|
+
{"version":3,"file":"ProjectPortfolio.d.ts","sourceRoot":"","sources":["../src/ProjectPortfolio.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IAC5D;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5C;AA0ED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAsB,EACtB,YAAiB,EACjB,UAAe,EACf,OAAe,EACf,QAAQ,GACT,EAAE,qBAAqB,wCAsIvB"}
|
package/dist/ProjectPortfolio.js
CHANGED
|
@@ -65,7 +65,7 @@ const fetchPortfolioData = cache(async (apiBase, clientSlug, apiKey, revalidate,
|
|
|
65
65
|
* apiBase="https://your-api.com"
|
|
66
66
|
* />
|
|
67
67
|
*/
|
|
68
|
-
export async function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath = "/projects", searchParams = {}, revalidate = 60, noCache = false,
|
|
68
|
+
export async function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath = "/projects", searchParams = {}, revalidate = 60, noCache = false, filterBy, }) {
|
|
69
69
|
// Parse filter[key]=value from searchParams into { key: value }
|
|
70
70
|
const filters = {};
|
|
71
71
|
Object.entries(searchParams).forEach(([key, val]) => {
|
|
@@ -77,11 +77,11 @@ export async function ProjectPortfolio({ clientSlug, apiBase, apiKey, basePath =
|
|
|
77
77
|
});
|
|
78
78
|
const filtersKey = JSON.stringify(filters);
|
|
79
79
|
const { projects, schema, fieldOptionsMap } = await fetchPortfolioData(apiBase, clientSlug, apiKey, revalidate, filtersKey, noCache);
|
|
80
|
-
const visible =
|
|
80
|
+
const visible = filterBy
|
|
81
81
|
? projects.filter((p) => {
|
|
82
82
|
var _a;
|
|
83
|
-
const
|
|
84
|
-
return
|
|
83
|
+
const v = (_a = p.custom_field_values) === null || _a === void 0 ? void 0 : _a[filterBy.field];
|
|
84
|
+
return v === filterBy.value || v === "both";
|
|
85
85
|
})
|
|
86
86
|
: projects;
|
|
87
87
|
const hasFilters = Object.keys(filters).length > 0;
|
|
@@ -20,12 +20,15 @@ export interface ProjectPortfolioClientProps {
|
|
|
20
20
|
/** Max columns in the grid. 2 or 3. Defaults to 3 */
|
|
21
21
|
columns?: 2 | 3;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
23
|
+
* Pre-filter projects by any custom field value before rendering.
|
|
24
|
+
* e.g. filterBy={{ field: "side", value: "architectural" }}
|
|
25
|
+
* Projects where the field value equals the given value OR "both" are shown.
|
|
26
|
+
* When omitted all projects are shown.
|
|
27
27
|
*/
|
|
28
|
-
|
|
28
|
+
filterBy?: {
|
|
29
|
+
field: string;
|
|
30
|
+
value: string;
|
|
31
|
+
};
|
|
29
32
|
}
|
|
30
|
-
export declare function ProjectPortfolioClient({ clientSlug, apiBase, apiKey, basePath, filters, font, columns,
|
|
33
|
+
export declare function ProjectPortfolioClient({ clientSlug, apiBase, apiKey, basePath, filters, font, columns, filterBy, }: ProjectPortfolioClientProps): React.JSX.Element;
|
|
31
34
|
//# sourceMappingURL=ProjectPortfolioClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectPortfolioClient.d.ts","sourceRoot":"","sources":["../src/ProjectPortfolioClient.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAuC,MAAM,OAAO,CAAA;AAM3D,MAAM,WAAW,2BAA2B;IAC1C,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qDAAqD;IACrD,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACf;;;;;OAKG;IACH,
|
|
1
|
+
{"version":3,"file":"ProjectPortfolioClient.d.ts","sourceRoot":"","sources":["../src/ProjectPortfolioClient.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAuC,MAAM,OAAO,CAAA;AAM3D,MAAM,WAAW,2BAA2B;IAC1C,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qDAAqD;IACrD,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACf;;;;;OAKG;IACH,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5C;AAyDD,wBAAgB,sBAAsB,CAAC,EACrC,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAsB,EACtB,OAAY,EACZ,IAAmB,EACnB,OAAW,EACX,QAAQ,GACT,EAAE,2BAA2B,qBAyJ7B"}
|
|
@@ -39,7 +39,7 @@ function matchesFilters(project, filters, schema, fieldOptionsMap) {
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
// ─── Component ───────────────────────────────────────────────────────────────
|
|
42
|
-
export function ProjectPortfolioClient({ clientSlug, apiBase, apiKey, basePath = "/projects", filters = {}, font = DEFAULT_FONT, columns = 3,
|
|
42
|
+
export function ProjectPortfolioClient({ clientSlug, apiBase, apiKey, basePath = "/projects", filters = {}, font = DEFAULT_FONT, columns = 3, filterBy, }) {
|
|
43
43
|
const [data, setData] = useState(null);
|
|
44
44
|
useEffect(() => {
|
|
45
45
|
const cacheKey = `${clientSlug}:${apiBase}:${apiKey}`;
|
|
@@ -90,18 +90,18 @@ export function ProjectPortfolioClient({ clientSlug, apiBase, apiKey, basePath =
|
|
|
90
90
|
const filteredProjects = useMemo(() => {
|
|
91
91
|
if (!data)
|
|
92
92
|
return [];
|
|
93
|
-
const
|
|
93
|
+
const byField = filterBy
|
|
94
94
|
? data.projects.filter((p) => {
|
|
95
95
|
var _a;
|
|
96
|
-
const
|
|
97
|
-
return
|
|
96
|
+
const v = (_a = p.custom_field_values) === null || _a === void 0 ? void 0 : _a[filterBy.field];
|
|
97
|
+
return v === filterBy.value || v === "both";
|
|
98
98
|
})
|
|
99
99
|
: data.projects;
|
|
100
100
|
const hasActiveFilters = Object.values(filters).some(Boolean);
|
|
101
101
|
if (!hasActiveFilters)
|
|
102
|
-
return
|
|
103
|
-
return
|
|
104
|
-
}, [data, filters,
|
|
102
|
+
return byField;
|
|
103
|
+
return byField.filter((p) => matchesFilters(p, filters, data.schema, data.fieldOptionsMap));
|
|
104
|
+
}, [data, filters, filterBy]);
|
|
105
105
|
const gridCols = columns === 2
|
|
106
106
|
? "repeat(2, 1fr)"
|
|
107
107
|
: "repeat(3, 1fr)";
|
|
@@ -44,12 +44,15 @@ export interface SimilarProjectsProps {
|
|
|
44
44
|
/** Small label above the heading. Defaults to "More Work" */
|
|
45
45
|
subtitle?: string;
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
47
|
+
* Pre-filter projects by any custom field value before rendering.
|
|
48
|
+
* e.g. filterBy={{ field: "side", value: "architectural" }}
|
|
49
|
+
* Projects where the field value equals the given value OR "both" are shown.
|
|
50
|
+
* When omitted all projects are shown.
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
filterBy?: {
|
|
53
|
+
field: string;
|
|
54
|
+
value: string;
|
|
55
|
+
};
|
|
53
56
|
}
|
|
54
|
-
export declare function SimilarProjects({ filters, excludeSlug, clientSlug, apiBase, apiKey, basePath, maxItems, revalidate, noCache, variant, projectSlugs, title, subtitle,
|
|
57
|
+
export declare function SimilarProjects({ filters, excludeSlug, clientSlug, apiBase, apiKey, basePath, maxItems, revalidate, noCache, variant, projectSlugs, title, subtitle, filterBy, }: SimilarProjectsProps): Promise<import("react").JSX.Element | null>;
|
|
55
58
|
//# sourceMappingURL=SimilarProjects.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimilarProjects.d.ts","sourceRoot":"","sources":["../src/SimilarProjects.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,
|
|
1
|
+
{"version":3,"file":"SimilarProjects.d.ts","sourceRoot":"","sources":["../src/SimilarProjects.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5C;AA6DD,wBAAsB,eAAe,CAAC,EACpC,OAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAsB,EACtB,QAAY,EACZ,UAAe,EACf,OAAe,EACf,OAAgB,EAChB,YAAY,EACZ,KAA0B,EAC1B,QAAsB,EACtB,QAAQ,GACT,EAAE,oBAAoB,+CA4KtB"}
|
package/dist/SimilarProjects.js
CHANGED
|
@@ -49,14 +49,14 @@ async function fetchSimilarData(apiBase, clientSlug, apiKey, revalidate, noCache
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
// ─── Component ────────────────────────────────────────────────────────────────
|
|
52
|
-
export async function SimilarProjects({ filters = {}, excludeSlug, clientSlug, apiBase, apiKey, basePath = "/projects", maxItems = 3, revalidate = 60, noCache = false, variant = "list", projectSlugs, title = "Similar Projects", subtitle = "More Work",
|
|
52
|
+
export async function SimilarProjects({ filters = {}, excludeSlug, clientSlug, apiBase, apiKey, basePath = "/projects", maxItems = 3, revalidate = 60, noCache = false, variant = "list", projectSlugs, title = "Similar Projects", subtitle = "More Work", filterBy, }) {
|
|
53
53
|
const { allProjects: allProjectsRaw, schema, fieldOptionsMap } = await fetchSimilarData(apiBase, clientSlug, apiKey, revalidate, noCache);
|
|
54
|
-
// Apply
|
|
55
|
-
const allProjects =
|
|
54
|
+
// Apply filterBy before any other filtering
|
|
55
|
+
const allProjects = filterBy
|
|
56
56
|
? allProjectsRaw.filter((p) => {
|
|
57
57
|
var _a;
|
|
58
|
-
const
|
|
59
|
-
return
|
|
58
|
+
const v = (_a = p.custom_field_values) === null || _a === void 0 ? void 0 : _a[filterBy.field];
|
|
59
|
+
return v === filterBy.value || v === "both";
|
|
60
60
|
})
|
|
61
61
|
: allProjectsRaw;
|
|
62
62
|
const badgeField = schema.find((f) => f.display_position === "badge_overlay");
|
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/dist/types.d.ts
CHANGED
|
@@ -39,8 +39,6 @@ export interface Project {
|
|
|
39
39
|
image_url: string | null;
|
|
40
40
|
is_featured: boolean;
|
|
41
41
|
is_published?: boolean;
|
|
42
|
-
/** Which website side this project belongs to. Omitted = show on all sides. */
|
|
43
|
-
side?: "architectural" | "speedrail" | "both";
|
|
44
42
|
custom_field_values: Record<string, CustomFieldValue>;
|
|
45
43
|
created_at: string;
|
|
46
44
|
updated_at: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,GAAG,UAAU,CAAA;IAChE,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAA;CACpE;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;CAC/D;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,aAAa,GAAG,IAAI,CAAA;AAEhF,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,GAAG,UAAU,CAAA;IAChE,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAA;CACpE;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;CAC/D;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,aAAa,GAAG,IAAI,CAAA;AAEhF,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACrD,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,KAAK,EAAE,CAAA;CACf"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chiselandco/nexus",
|
|
3
|
-
"version": "
|
|
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",
|