diff --git a/README.md b/README.md index 9f7d107..45889cc 100644 --- a/README.md +++ b/README.md @@ -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 `` while a resize is in progress +- `.panelgrid-dragging` - Applied to `` while a drag is in progress #### Example: Custom Panel Styling @@ -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 */ @@ -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)) ### `` @@ -366,6 +373,10 @@ Hook to access panel control functions. - `addPanel(panel: Partial)`: 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 @@ -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[], diff --git a/src/PanelGridRenderer.tsx b/src/PanelGridRenderer.tsx index 1f75c22..76830b8 100644 --- a/src/PanelGridRenderer.tsx +++ b/src/PanelGridRenderer.tsx @@ -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(" "); diff --git a/src/index.ts b/src/index.ts index 578a5d7..78e781f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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"; diff --git a/src/styles.css b/src/styles.css index 56f2a94..d517eed 100644 --- a/src/styles.css +++ b/src/styles.css @@ -54,6 +54,9 @@ z-index: calc(infinity); } +.panelgrid-panel--size-locked { +} + .panelgrid-panel--position-locked { cursor: default; } diff --git a/src/usePanelGrid.ts b/src/usePanelGrid.ts index b0d056d..9687875 100644 --- a/src/usePanelGrid.ts +++ b/src/usePanelGrid.ts @@ -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, @@ -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),