Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,12 @@ PanelGrid uses non-scoped CSS classes with the `panelgrid-` prefix, allowing you
- `.panelgrid-panel-ghost` - Ghost panel shown during drag/resize operations
- `.panelgrid-panel--dragging` - Applied to a panel while it's being dragged
- `.panelgrid-panel--with-transition` - Applied to panels that are animating to new positions
- `.panelgrid-resize-handle` - Resize handle in the bottom-right corner of panels
- `.panelgrid-panel--size-locked` - Applied to panels with `lockSize: true`
- `.panelgrid-panel--position-locked` - Applied to panels with `lockPosition: true`
- `.panelgrid-resize-handle` - Resize handle element
- `.panelgrid-resize-handle--{position}` - Position-specific resize handle (e.g. `--se`, `--nw`); see `ResizeHandlePosition` type for all values
- `.panelgrid-resizing` - Applied to `<body>` while a resize is in progress
- `.panelgrid-dragging` - Applied to `<body>` while a drag is in progress

#### Example: Custom Panel Styling

Expand Down Expand Up @@ -305,6 +310,7 @@ The renderer uses CSS custom properties that you can use in your custom styles:

- `--column-count` - Number of grid columns (set automatically)
- `--gap` - Gap between panels in pixels
- `--panelgrid-handle-color` - Color of the resize handle icon (default: `#000`)

```css
/* Example: Use custom properties in your styles */
Expand All @@ -325,6 +331,7 @@ The main provider component that manages panel state.
- `panels`: `PanelCoordinate[]` - Array of panel configurations
- `columnCount`: `number` - Number of columns in the grid
- `gap`: `number` - Gap between panels in pixels
- `resizeHandlePositions?`: `ResizeHandlePosition[]` - Positions to render resize handles (default: `["se"]`)
- `rearrangement?`: `RearrangementFunction` - Optional custom rearrangement logic (see [Custom Rearrangement Logic](#custom-rearrangement-logic))

### `<PanelGridRenderer>`
Expand Down Expand Up @@ -366,6 +373,10 @@ Hook to access panel control functions.

- `addPanel(panel: Partial<PanelCoordinate>)`: Add a new panel
- `removePanel(id: PanelId)`: Remove a panel by ID
- `lockPanelSize(id: PanelId)`: Prevent a panel from being resized
- `unlockPanelSize(id: PanelId)`: Allow a panel to be resized again
- `lockPanelPosition(id: PanelId)`: Prevent a panel from being moved or pushed by other panels
- `unlockPanelPosition(id: PanelId)`: Allow a panel to be moved again
- `exportState()`: Export current panel state

### Types
Expand All @@ -375,13 +386,16 @@ type PanelId = number | string;

interface PanelCoordinate {
id: PanelId;
x: number; // Column position (0-indexed)
y: number; // Row position (0-indexed)
w: number; // Width in columns
h: number; // Height in rows
lockSize?: boolean; // If true, prevents panel from being resized
x: number; // Column position (0-indexed)
y: number; // Row position (0-indexed)
w: number; // Width in columns
h: number; // Height in rows
lockSize?: boolean; // If true, prevents panel from being resized
lockPosition?: boolean; // If true, prevents panel from being moved or pushed
}

type ResizeHandlePosition = "n" | "e" | "s" | "w" | "ne" | "nw" | "se" | "sw";

type RearrangementFunction = (
movingPanel: PanelCoordinate,
allPanels: PanelCoordinate[],
Expand Down
3 changes: 2 additions & 1 deletion src/PanelGridRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ export function PanelGridRenderer({ children: ItemComponent }: PanelGridRenderer

{panels.map((panel) => {
const { panelProps, resizeHandleProps } = panel;
const { key, lockSize, lockPosition, style, positionData, ref, onMouseDown } = panelProps;
const { key, lockSize, lockPosition, isAnimating, style, positionData, ref, onMouseDown } = panelProps;

const className = [
"panelgrid-panel",
lockSize ? "panelgrid-panel--size-locked" : "",
lockPosition ? "panelgrid-panel--position-locked" : "",
isAnimating ? "panelgrid-panel--with-transition" : "",
]
.filter(Boolean)
.join(" ");
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { rearrangePanels, resolveWithLockRollback } from "./helpers/rearrangement";
export { PanelGridProvider, usePanelGridControls, usePanelGridState } from "./PanelGridProvider";
export { PanelGridRenderer } from "./PanelGridRenderer";
export type { PanelCoordinate, PanelId, RearrangementFunction } from "./types";
export type { PanelCoordinate, PanelId, RearrangementFunction, ResizeHandlePosition } from "./types";
export { usePanel } from "./usePanel";
3 changes: 3 additions & 0 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
z-index: calc(infinity);
}

.panelgrid-panel--size-locked {
}

.panelgrid-panel--position-locked {
cursor: default;
}
Expand Down
5 changes: 1 addition & 4 deletions src/usePanelGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ export function usePanelGrid({
key: panel.id,
lockSize: panel.lockSize,
lockPosition: panel.lockPosition,
isAnimating: isAnimating && !isActive,
positionData: {
x: panel.x,
y: panel.y,
Expand All @@ -510,10 +511,6 @@ export function usePanelGrid({
left: gridPositionToPixels(panel.x, baseSize, gap),
width: gridToPixels(panel.w, baseSize, gap),
height: gridToPixels(panel.h, baseSize, gap),
transition:
isAnimating && !isActive
? "top 0.3s ease-out, left 0.3s ease-out, width 0.3s ease-out, height 0.3s ease-out"
: undefined,
},
ref: createRefCallback(panel.id),
onMouseDown: createDragHandler(panel),
Expand Down