### Clone and Install Dependencies with Bun Source: https://github.com/cminn10/react-trellis-gallery/blob/main/CONTRIBUTING.md Clone the repository and install project dependencies using Bun. This is the initial setup step for development. ```bash git clone https://github.com/cminn10/react-trellis-gallery.git cd react-trellis-gallery bun install ``` -------------------------------- ### Quick Start with TrellisGallery Source: https://github.com/cminn10/react-trellis-gallery/blob/main/README.md Basic setup for TrellisGallery with pagination mode, auto layout, and custom item rendering. Ensure the parent container has explicit width and height. ```tsx import { TrellisGallery } from 'react-trellis-gallery' const items = Array.from({ length: 20 }, (_, i) => ({ id: i, title: `Item ${i + 1}`, })) function App() { return (
{item.title}
} renderExpandedItem={(item) =>

{item.title}

Detail view

} />
) } ``` -------------------------------- ### Install react-trellis-gallery with Bun Source: https://github.com/cminn10/react-trellis-gallery/blob/main/README.md Use this command to add the package to your project if you are using Bun as your package manager. ```bash bun add react-trellis-gallery ``` -------------------------------- ### Run Playground Dev Server with Bun Source: https://github.com/cminn10/react-trellis-gallery/blob/main/CONTRIBUTING.md Start the playground development server using Bun. This allows for interactive testing of library changes. ```bash bun run dev:playground ``` -------------------------------- ### Install react-trellis-gallery with npm Source: https://github.com/cminn10/react-trellis-gallery/blob/main/README.md Use this command to add the package to your project if you are using npm as your package manager. ```bash npm install react-trellis-gallery ``` -------------------------------- ### Virtualized Scroll Mode Example Source: https://github.com/cminn10/react-trellis-gallery/blob/main/README.md Example of using TrellisGallery in 'scroll' mode for large datasets, utilizing react-window for virtualization. Adjust overscanCount for performance tuning. ```tsx
{item.title}
} renderExpandedItem={(item) =>
{item.title}
} /> ``` -------------------------------- ### Implement a Custom Task Board with useTrellisGallery Source: https://context7.com/cminn10/react-trellis-gallery/llms.txt This example demonstrates how to use the useTrellisGallery hook to create a paginated task board. It includes custom cell rendering and panel management. ```tsx import { useTrellisGallery, useCellInteraction } from 'react-trellis-gallery' interface Task { id: number title: string status: 'todo' | 'in-progress' | 'done' } const tasks: Task[] = [ { id: 1, title: 'Design mockups', status: 'done' }, { id: 2, title: 'Implement API', status: 'in-progress' }, { id: 3, title: 'Write tests', status: 'todo' }, { id: 4, title: 'Deploy to staging', status: 'todo' }, ] function TaskCell({ task, onOpen }: { task: Task; onOpen: () => void }) { const interaction = useCellInteraction({ onActivate: onOpen, activationCallback: (event) => event.type === 'dblclick', }) const statusColors = { 'todo': '#e3e3e3', 'in-progress': '#fff3cd', 'done': '#d4edda', } return (
{task.title}
{task.status}
) } function CustomTaskBoard() { const { containerRef, layout, pagination, panels } = useTrellisGallery({ items: tasks, mode: 'pagination', layout: { type: 'manual', rows: 2, cols: 2 }, gap: 8, pagination: { mode: 'uncontrolled' }, onPanelOpen: (index) => console.log('Opened task:', tasks[index]?.title), onPanelClose: (index) => console.log('Closed task:', tasks[index]?.title), }) const pageItems = tasks.slice(pagination.startIndex, pagination.endIndex) return (
{pageItems.map((task, i) => ( panels.open(pagination.startIndex + i)} /> ))}
{pagination.totalPages > 1 && (
Page {pagination.currentPage + 1} of {pagination.totalPages}
)} {panels.openPanels.length > 0 && (

{tasks[panels.openPanels[0]!.itemIndex]?.title}

Status: {tasks[panels.openPanels[0]!.itemIndex]?.status}

)}
) } ``` -------------------------------- ### Imperative Panel Control Example Source: https://context7.com/cminn10/react-trellis-gallery/llms.txt Use `useRef` to get a handle on the `TrellisGalleryHandle` for imperative panel management. Methods like `open`, `close`, `closeAll`, and `isOpen` can be called on `galleryRef.current.panels` to control panel states based on item data. ```tsx import { useRef } from 'react' import { TrellisGallery, type TrellisGalleryHandle } from 'react-trellis-gallery' interface Contact { id: number name: string email: string favorite: boolean department: string } const contacts: Contact[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', favorite: true, department: 'Engineering' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', favorite: false, department: 'Marketing' }, { id: 3, name: 'Carol Williams', email: 'carol@example.com', favorite: true, department: 'Engineering' }, { id: 4, name: 'David Brown', email: 'david@example.com', favorite: false, department: 'Sales' }, { id: 5, name: 'Eve Davis', email: 'eve@example.com', favorite: true, department: 'Engineering' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', favorite: false, department: 'Marketing' }, ] function ContactsApp() { const galleryRef = useRef | null>(null) const openFavorites = () => { galleryRef.current?.panels.open((contact) => contact.favorite) } const openByDepartment = (dept: string) => { galleryRef.current?.panels.open((contact) => contact.department === dept) } const closeNonFavorites = () => { galleryRef.current?.panels.close((contact) => !contact.favorite) } const closeAll = () => { galleryRef.current?.panels.closeAll() } const closeUnpinned = () => { galleryRef.current?.panels.closeUnpinned() } const checkIfOpen = (name: string) => { const isOpen = galleryRef.current?.panels.isOpen((contact) => contact.name === name) alert(`${name} panel is ${isOpen ? 'open' : 'closed'}`) } return (
(
{contact.name} {contact.favorite && '⭐'}
{contact.department}
)} renderExpandedItem={(contact) => (

{contact.name}

Email: {contact.email}

Department: {contact.department}

{contact.favorite ? '⭐ Favorite contact' : ''}

)} />
) } ``` -------------------------------- ### Basic TrellisGallery with Pagination Source: https://context7.com/cminn10/react-trellis-gallery/llms.txt Demonstrates the basic setup of the TrellisGallery component in pagination mode. It includes defining item data, layout, pagination controls, and render functions for grid items and expanded panels. Ensure the parent container has defined dimensions. ```tsx import { TrellisGallery } from 'react-trellis-gallery' interface PhotoItem { id: number title: string thumbnail: string fullImage: string description: string } const photos: PhotoItem[] = Array.from({ length: 50 }, (_, i) => ({ id: i, title: `Photo ${i + 1}`, thumbnail: `https://picsum.photos/seed/${i}/200/150`, fullImage: `https://picsum.photos/seed/${i}/800/600`, description: `A beautiful landscape photo number ${i + 1}`, })) function PhotoGallery() { return (
(
{photo.title}
)} renderExpandedItem={(photo) => (
{photo.title}

{photo.title}

{photo.description}

)} panelTitle={(photo) => photo.title} onPanelOpen={(photo, index) => console.log('Opened:', photo.title)} onPanelClose={(photo, index) => console.log('Closed:', photo.title)} />
) } ``` -------------------------------- ### Implement Controlled Pagination Source: https://context7.com/cminn10/react-trellis-gallery/llms.txt Use the `controlled` pagination mode to manage the page state externally. This example synchronizes the page with URL parameters and browser history. ```tsx import { useState, useEffect } from 'react' import { TrellisGallery } from 'react-trellis-gallery' interface Article { id: number title: string excerpt: string date: string } const articles: Article[] = Array.from({ length: 30 }, (_, i) => ({ id: i, title: `Article ${i + 1}: Important News`, excerpt: `This is the excerpt for article ${i + 1}. It contains a brief summary of the content.`, date: new Date(2024, 0, i + 1).toLocaleDateString(), })) function ArticleList() { const [page, setPage] = useState(() => { const params = new URLSearchParams(window.location.search) return parseInt(params.get('page') || '0', 10) }) useEffect(() => { const url = new URL(window.location.href) url.searchParams.set('page', String(page)) window.history.replaceState({}, '', url.toString()) }, [page]) return (
(

{article.title}

{article.excerpt}

{article.date}
)} renderExpandedItem={(article) => (

{article.title}

{article.date}

{article.excerpt}

Full article content would be displayed here...

)} />
) } ``` -------------------------------- ### Custom Cell Activation Logic Source: https://context7.com/cminn10/react-trellis-gallery/llms.txt Implement the `cellActivation` callback to define custom interactions like double-clicks, shift-clicks, or keyboard shortcuts (Enter, Space) for opening panels. This example shows how to handle different event types and key presses. ```tsx import { TrellisGallery, type CellActivationEvent } from 'react-trellis-gallery' interface Note { id: number title: string content: string color: string } const notes: Note[] = [ { id: 1, title: 'Meeting Notes', content: 'Discuss Q4 goals...', color: '#fff3cd' }, { id: 2, title: 'Shopping List', content: 'Milk, eggs, bread...', color: '#d4edda' }, { id: 3, title: 'Project Ideas', content: 'Build a React gallery...', color: '#cce5ff' }, { id: 4, title: 'Reminders', content: 'Call mom, pay bills...', color: '#f8d7da' }, ] function NotesApp() { const handleCellActivation = (event: CellActivationEvent): boolean => { // Double-click to open if (event.type === 'dblclick') return true // Shift + Click to open if (event.type === 'click' && event.shiftKey) return true // Enter key to open (when focused) if (event.type === 'keydown' && 'key' in event && event.key === 'Enter') return true // Space key to open (when focused) if (event.type === 'keydown' && 'key' in event && event.key === ' ') return true return false } return (

Double-click, Shift+Click, or press Enter/Space on a focused note to expand

(

{note.title}

{note.content}

)} renderExpandedItem={(note) => (

{note.title}