panelgrid 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Tsuyoshi HARA
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,327 @@
1
+ # PanelGrid
2
+
3
+ A flexible and performant React grid layout library with drag-and-drop and resize capabilities.
4
+
5
+ ## Features
6
+
7
+ - 🎯 **Drag and Drop**: Intuitive panel repositioning with snap-to-grid behavior
8
+ - 📏 **Resizable**: Panels can be resized with visual feedback
9
+ - 🎨 **Ghost Panel**: Visual preview of panel placement during drag/resize operations
10
+ - ⚡ **Performance Optimized**: Direct DOM manipulation for high-frequency interactions
11
+ - 🔧 **TypeScript**: Full type safety with comprehensive type definitions
12
+ - 📦 **Tree-shakeable**: ESM and CommonJS builds available
13
+ - 🎛️ **Customizable Rearrangement**: Override default collision resolution logic
14
+
15
+ ## Requirements
16
+
17
+ - React 18.0.0 or higher
18
+ - React DOM 18.0.0 or higher
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install panelgrid
24
+ # or
25
+ yarn add panelgrid
26
+ # or
27
+ pnpm add panelgrid
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ```tsx
33
+ import { PanelGridProvider, PanelGridRenderer } from 'panelgrid';
34
+ import type { PanelCoordinate } from 'panelgrid';
35
+ import 'panelgrid/styles.css';
36
+
37
+ const initialPanels: PanelCoordinate[] = [
38
+ { id: 1, x: 0, y: 0, w: 2, h: 2 },
39
+ { id: 2, x: 2, y: 0, w: 1, h: 1 },
40
+ { id: 3, x: 0, y: 2, w: 1, h: 1 },
41
+ ];
42
+
43
+ function PanelContent({ id }: { id: number | string }) {
44
+ return <div>Panel {id}</div>;
45
+ }
46
+
47
+ function App() {
48
+ return (
49
+ <PanelGridProvider
50
+ panels={initialPanels}
51
+ columnCount={4}
52
+ gap={8}
53
+ >
54
+ <PanelGridRenderer itemRenderer={PanelContent} />
55
+ </PanelGridProvider>
56
+ );
57
+ }
58
+ ```
59
+
60
+ **Note:** Don't forget to import the CSS file to enable proper styling for the panels.
61
+
62
+ ## Advanced Usage
63
+
64
+ ### Custom Rearrangement Logic
65
+
66
+ You can override the default collision resolution logic by providing a custom `rearrangement` function:
67
+
68
+ ```tsx
69
+ import { PanelGridProvider, rearrangePanels } from 'panelgrid';
70
+ import type { RearrangementFunction, PanelCoordinate } from 'panelgrid';
71
+
72
+ // Example: Custom rearrangement that prevents vertical movement
73
+ const customRearrange: RearrangementFunction = (
74
+ movingPanel,
75
+ allPanels,
76
+ columnCount
77
+ ) => {
78
+ // Implement your custom collision resolution logic
79
+ // For example: only allow horizontal panel movement
80
+
81
+ // You can also wrap the default function
82
+ const result = rearrangePanels(movingPanel, allPanels, columnCount);
83
+
84
+ // Apply custom modifications
85
+ return result.map(panel => ({
86
+ ...panel,
87
+ // Your custom logic here
88
+ }));
89
+ };
90
+
91
+ function App() {
92
+ return (
93
+ <PanelGridProvider
94
+ panels={initialPanels}
95
+ columnCount={4}
96
+ gap={8}
97
+ rearrangement={customRearrange}
98
+ >
99
+ <PanelGridRenderer itemRenderer={PanelContent} />
100
+ </PanelGridProvider>
101
+ );
102
+ }
103
+ ```
104
+
105
+ #### Example: Disable Automatic Rearrangement
106
+
107
+ ```tsx
108
+ const noRearrangement: RearrangementFunction = (movingPanel, allPanels) => {
109
+ // Simply update the moving panel without affecting others
110
+ return allPanels.map(panel =>
111
+ panel.id === movingPanel.id ? movingPanel : panel
112
+ );
113
+ };
114
+ ```
115
+
116
+ #### Example: Fixed Zones
117
+
118
+ ```tsx
119
+ const zoneRearrangement: RearrangementFunction = (
120
+ movingPanel,
121
+ allPanels,
122
+ columnCount
123
+ ) => {
124
+ // Define zones where panels can be placed
125
+ const zones = {
126
+ left: { xMin: 0, xMax: 2 },
127
+ right: { xMin: 3, xMax: 5 }
128
+ };
129
+
130
+ // Use default rearrangement
131
+ const result = rearrangePanels(movingPanel, allPanels, columnCount);
132
+
133
+ // Constrain panels to their zones
134
+ return result.map(panel => {
135
+ const inLeftZone = panel.x < 3;
136
+ const zone = inLeftZone ? zones.left : zones.right;
137
+
138
+ return {
139
+ ...panel,
140
+ x: Math.max(zone.xMin, Math.min(panel.x, zone.xMax))
141
+ };
142
+ });
143
+ };
144
+ ```
145
+
146
+ ### Customizing Styles
147
+
148
+ PanelGrid uses non-scoped CSS classes with the `panelgrid-` prefix, allowing you to override the default styles to match your application's design.
149
+
150
+ #### Available CSS Classes
151
+
152
+ - `.panelgrid-renderer` - The main grid container
153
+ - `.panelgrid-panel-placeholder` - Grid cell placeholders (background visualization)
154
+ - `.panelgrid-panel` - Individual panel container
155
+ - `.panelgrid-panel-ghost` - Ghost panel shown during drag/resize operations
156
+ - `.panelgrid-panel--dragging` - Applied to a panel while it's being dragged
157
+ - `.panelgrid-panel--with-transition` - Applied to panels that are animating to new positions
158
+ - `.panelgrid-resize-handle` - Resize handle in the bottom-right corner of panels
159
+
160
+ #### Example: Custom Panel Styling
161
+
162
+ ```css
163
+ /* Import the base styles first */
164
+ @import 'panelgrid/styles.css';
165
+
166
+ /* Override panel appearance */
167
+ .panelgrid-panel {
168
+ border-radius: 8px;
169
+ border: 2px solid #3b82f6;
170
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
171
+ background-color: white;
172
+ }
173
+
174
+ /* Style the ghost panel */
175
+ .panelgrid-panel-ghost {
176
+ outline: 2px dashed #3b82f6;
177
+ background-color: rgba(59, 130, 246, 0.1);
178
+ }
179
+
180
+ /* Customize the resize handle */
181
+ .panelgrid-resize-handle {
182
+ background-color: #3b82f6;
183
+ width: 20px;
184
+ border-bottom-right-radius: 8px;
185
+ }
186
+
187
+ .panelgrid-resize-handle:hover {
188
+ background-color: #2563eb;
189
+ }
190
+
191
+ /* Style dragging state */
192
+ .panelgrid-panel--dragging {
193
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.2);
194
+ opacity: 0.8;
195
+ }
196
+
197
+ /* Customize grid placeholders */
198
+ .panelgrid-panel-placeholder {
199
+ background-color: #f3f4f6;
200
+ border-radius: 4px;
201
+ }
202
+ ```
203
+
204
+ #### Example: Dark Mode Support
205
+
206
+ ```css
207
+ @import 'panelgrid/styles.css';
208
+
209
+ @media (prefers-color-scheme: dark) {
210
+ .panelgrid-panel-placeholder {
211
+ background-color: rgba(255, 255, 255, 0.05);
212
+ }
213
+
214
+ .panelgrid-panel {
215
+ background-color: #1f2937;
216
+ border-color: #374151;
217
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
218
+ }
219
+
220
+ .panelgrid-panel-ghost {
221
+ outline-color: #60a5fa;
222
+ }
223
+
224
+ .panelgrid-resize-handle {
225
+ background-color: rgba(255, 255, 255, 0.2);
226
+ }
227
+ }
228
+ ```
229
+
230
+ #### CSS Custom Properties
231
+
232
+ The renderer uses CSS custom properties that you can use in your custom styles:
233
+
234
+ - `--column-count` - Number of grid columns (set automatically)
235
+ - `--gap` - Gap between panels in pixels
236
+
237
+ ```css
238
+ /* Example: Use custom properties in your styles */
239
+ .panelgrid-panel {
240
+ /* Add padding based on the gap size */
241
+ padding: calc(var(--gap) / 2);
242
+ }
243
+ ```
244
+
245
+ ## API
246
+
247
+ ### `<PanelGridProvider>`
248
+
249
+ The main provider component that manages panel state.
250
+
251
+ **Props:**
252
+
253
+ - `panels`: `PanelCoordinate[]` - Array of panel configurations
254
+ - `columnCount`: `number` - Number of columns in the grid
255
+ - `gap`: `number` - Gap between panels in pixels
256
+ - `rearrangement?`: `RearrangementFunction` - Optional custom rearrangement logic (see [Custom Rearrangement Logic](#custom-rearrangement-logic))
257
+
258
+ ### `<PanelGridRenderer>`
259
+
260
+ Renderer component that displays the panels.
261
+
262
+ **Props:**
263
+
264
+ - `itemRenderer`: `React.ComponentType<{ id: PanelId }>` - Component to render each panel
265
+
266
+ ### `usePanelGridControls()`
267
+
268
+ Hook to access panel control functions.
269
+
270
+ **Returns:**
271
+
272
+ - `addPanel(panel: Partial<PanelCoordinate>)`: Add a new panel
273
+ - `removePanel(id: PanelId)`: Remove a panel by ID
274
+ - `exportState()`: Export current panel state
275
+
276
+ ### Types
277
+
278
+ ```typescript
279
+ type PanelId = number | string;
280
+
281
+ interface PanelCoordinate {
282
+ id: PanelId;
283
+ x: number; // Column position (0-indexed)
284
+ y: number; // Row position (0-indexed)
285
+ w: number; // Width in columns
286
+ h: number; // Height in rows
287
+ }
288
+
289
+ type RearrangementFunction = (
290
+ movingPanel: PanelCoordinate,
291
+ allPanels: PanelCoordinate[],
292
+ columnCount: number
293
+ ) => PanelCoordinate[];
294
+ ```
295
+
296
+ ### Exported Functions
297
+
298
+ - `rearrangePanels(movingPanel, allPanels, columnCount)`: Default rearrangement function that can be imported and extended
299
+
300
+ ## Development
301
+
302
+ ```bash
303
+ # Install dependencies
304
+ yarn install
305
+
306
+ # Run development server
307
+ yarn dev
308
+
309
+ # Build package
310
+ yarn build
311
+
312
+ # Run tests
313
+ yarn test
314
+
315
+ # Type check
316
+ yarn typecheck
317
+
318
+ # Lint
319
+ yarn lint
320
+
321
+ # Format
322
+ yarn format
323
+ ```
324
+
325
+ ## License
326
+
327
+ MIT