next-spinks-posts
v1.1.1
Published
Flexible and generic React & Next.js product grid component library supporting custom API mappers, pagination, and detail views.
Maintainers
Readme
next-spinks-posts
A powerful, high-performance, and ultra-flexible React & Next.js catalog component package designed to display product catalogs, posts, and publications from Spinks World JSON APIs with minimal required setup. Supports 7 display layouts, touch-enabled slider/carousel, sortable tables, vertical timeline views, masonry grids, category/tag filtering, dark mode, and customizable card styling.
Key Features
- ⚡ Minimal Setup: Simply pass
catalogGroupId={13}and the component automatically constructs API endpoints, resolves asset base URLs (static.spinksworld.com), generates thumbnails, and handles PDF downloads! - 🎨 7 Display Layouts:
- Responsive Grid (
layout="grid"): 2, 3, 4, or 5 columns. - List / Row View (
layout="list"): Horizontal cards for dense list views. - Carousel / Slider View (
layout="slider"): Touch/swipe enabled, infinite loop, autoplay, keyboard arrows, and pagination dots. - Masonry / Pinterest (
layout="masonry"): Multi-column layout for variable height cards. - Compact View (
layout="compact"): High-density catalog layout. - Table View (
layout="table"): Accessible table layout with click-to-sort columns (Title, Category, Date). - Timeline View (
layout="timeline"): Vertical timeline layout for blogs, release notes, or event sequences.
- Responsive Grid (
- 🎛️ Interactive Layout Switcher: Enable end-user layout toggle buttons with
allowLayoutSwitching. - 🔍 Filtering & Sorting: Multi-field search, category dropdowns/pills, tag filters, and title/date sorting.
- 📄 3 Pagination Modes: Traditional page numbers, "Load More" button, and Infinite Scroll auto-loading.
- 🌙 Dark Mode & Themeable: Built-in CSS variables and dark mode support (
theme="dark" | "light" | "auto"). - 📱 Interactive Detail Modal: Built-in product detail modal for extended product views.
- 🛠️ TypeScript Powered: Fully typed with generic parameter support and backward compatibility.
Installation
npm install next-spinks-posts
# or
yarn add next-spinks-posts
# or
pnpm add next-spinks-postsInclude styles in your _app.tsx, layout.tsx, or global CSS:
import "next-spinks-posts/styles.css";Quick Start (Minimal Zero-Config)
Simply pass your catalogGroupId:
import { ProductGrid } from "next-spinks-posts";
import "next-spinks-posts/styles.css";
export default function CatalogPage() {
return (
<ProductGrid catalogGroupId={13} showSearch />
);
}Usage Examples
1. Interactive Layout Switcher & Filtering
Allow users to switch between Grid, List, Slider, Masonry, Table, and Timeline views on the fly:
import { ProductGrid } from "next-spinks-posts";
export default function AdvancedCatalogPage() {
return (
<ProductGrid
catalogGroupId={13}
layout="grid"
columns={3}
allowLayoutSwitching
availableLayouts={["grid", "list", "slider", "masonry", "table", "timeline"]}
showSearch
showCategoryFilter
showTagFilter
showSort
paginationMode="infinite"
theme="auto"
/>
);
}2. Carousel / Slider View
Touch-enabled responsive carousel slider:
import { ProductGrid } from "next-spinks-posts";
export default function FeaturedSlider() {
return (
<ProductGrid
catalogGroupId={13}
layout="slider"
sliderConfig={{
loop: true,
autoplay: true,
autoplayInterval: 3500,
showArrows: true,
showDots: true,
slidesPerView: { sm: 1, md: 2, lg: 3 },
swipeable: true,
keyboardNav: true,
}}
/>
);
}3. Sortable Table View
Accessible table view with sortable columns for product catalog listings:
import { ProductGrid } from "next-spinks-posts";
export default function CatalogTablePage() {
return (
<ProductGrid
catalogGroupId={13}
layout="table"
showSearch
showSort
pageSize={20}
/>
);
}4. Vertical Timeline View
Great for release notes, publication archives, or event sequences:
import { ProductGrid } from "next-spinks-posts";
export default function PublicationTimeline() {
return (
<ProductGrid
catalogGroupId={13}
layout="timeline"
showSort
/>
);
}5. Server Components (Next.js App Router async/await)
Fetch products directly inside Server Components using getProducts(13):
import { getProducts, ProductGrid } from "next-spinks-posts";
export default async function ServerPage() {
// Automatically fetches from https://www.spinksworld.com/cgroup/json/13
const products = await getProducts(13);
return <ProductGrid products={products} layout="masonry" columns={4} />;
}6. Custom Client Hook (useProducts)
Build a custom UI layout using the headless useProducts hook:
"use client";
import { useProducts, ProductCard } from "next-spinks-posts";
export function CustomProductList() {
const { paginatedProducts, loading, searchQuery, setSearchQuery } = useProducts({
catalogGroupId: 13,
pageSize: 8,
});
if (loading) return <div>Loading catalog items...</div>;
return (
<div>
<input
type="text"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder="Filter..."
/>
<div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "16px" }}>
{paginatedProducts.map((p) => (
<ProductCard key={p.id} product={p} />
))}
</div>
</div>
);
}API Reference
<ProductGrid /> Props
| Prop | Type | Default | Description |
|---|---|---|---|
| catalogGroupId | number \| string | undefined | Catalog Category Group ID (e.g., 13). API endpoint is constructed internally automatically. |
| layout | "grid" \| "list" \| "slider" \| "masonry" \| "compact" \| "table" \| "timeline" | "grid" | Initial display layout mode. |
| columns | 2 \| 3 \| 4 \| 5 \| Object | 3 | Grid column counts for responsive layouts. |
| allowLayoutSwitching | boolean | false | Enables view switcher toolbar buttons. |
| availableLayouts | ProductLayout[] | all | Array of layouts available in view switcher. |
| cardSize | "sm" \| "md" \| "lg" | "md" | Card sizing padding and font dimensions. |
| aspectRatio | "1:1" \| "4:3" \| "16:9" \| "auto" | "4:3" | Card image aspect ratio. |
| hoverAnimation | "zoom" \| "lift" \| "glow" \| "float" \| "none" | "lift" | Hover effect animation style. |
| showSearch | boolean | false | Enables search bar input. |
| showCategoryFilter | boolean | false | Enables category dropdown filter. |
| showTagFilter | boolean | false | Enables tag filter pills. |
| showSort | boolean | false | Enables sorting dropdown. |
| paginationMode | "traditional" \| "loadMore" \| "infinite" | "traditional" | Pagination strategy. |
| loadMoreText | string | "Load More Products" | Custom text for Load More button. |
| sliderConfig | SliderConfig | {} | Carousel slider configuration options. |
| theme | "light" \| "dark" \| "auto" | "light" | Component theme. |
| renderCard | (product, idx) => ReactNode | undefined | Custom card render override. |
| renderEmpty | ReactNode | undefined | Custom empty state element. |
CSS Variables Customization
Customize theme colors and typography by overriding CSS variables in your stylesheet:
:root {
--sp-primary: #2563eb;
--sp-primary-hover: #1d4ed8;
--sp-primary-light: #eff6ff;
--sp-text: #1e293b;
--sp-text-muted: #64748b;
--sp-bg: #f8fafc;
--sp-card-bg: #ffffff;
--sp-border: #e2e8f0;
--sp-radius: 12px;
}
[data-theme="dark"] {
--sp-bg: #0f172a;
--sp-card-bg: #1e293b;
--sp-text: #f1f5f9;
--sp-border: #334155;
}License
MIT © Next Spinks Posts
