import type { CSSProperties, HTMLAttributes, Ref } from "react";
export type PanelSize = {
asPercentage: number;
inPixels: number;
};
export type GroupResizeBehavior =
| "preserve-relative-size"
| "preserve-pixel-size";
/**
* Numeric Panel constraints are represented as numeric percentages (0..100)
* Values specified using other CSS units must be pre-converted.
*/
export type PanelConstraints = {
collapsedSize: number;
collapsible: boolean;
defaultSize: number | undefined;
disabled: boolean | undefined;
groupResizeBehavior?: GroupResizeBehavior | undefined;
maxSize: number;
minSize: number;
panelId: string;
};
export type SizeUnit = "px" | "%" | "em" | "rem" | "vh" | "vw";
export type RegisteredPanel = {
id: string;
idIsStable: boolean;
element: HTMLDivElement;
mutableValues: {
expandToSize: number | undefined;
prevSize: PanelSize | undefined;
};
onResize: OnPanelResize | undefined;
panelConstraints: PanelConstraintProps;
};
/**
* Imperative Panel API
*
* ℹ️ The `usePanelRef` and `usePanelCallbackRef` hooks are exported for convenience use in TypeScript projects.
*/
export interface PanelImperativeHandle {
/**
* Collapse the Panel to it's `collapsedSize`.
*
* ⚠️ This method will do nothing if the Panel is not `collapsible` or if it is already collapsed.
*/
collapse: () => void;
/**
* Expand a collapsed Panel to its most recent size.
*
* ⚠️ This method will do nothing if the Panel is not currently collapsed.
*/
expand: () => void;
/**
* Get the current size of the Panel in pixels as well as a percentage of the parent group (0..100).
*
* @return Panel size (in pixels and as a percentage of the parent group)
*/
getSize: () => {
asPercentage: number;
inPixels: number;
};
/**
* The Panel is currently collapsed.
*/
isCollapsed: () => boolean;
/**
* Update the Panel's size.
*
* Size can be in the following formats:
* - Percentage of the parent Group (0..100)
* - Pixels
* - Relative font units (em, rem)
* - Viewport relative units (vh, vw)
*
* ℹ️ Numeric values are assumed to be pixels.
* Strings without explicit units are assumed to be percentages (0%..100%).
* Percentages may also be specified as strings ending with "%" (e.g. "33%")
* Pixels may also be specified as strings ending with the unit "px".
* Other units should be specified as strings ending with their CSS property units (e.g. 1rem, 50vh)
*
* @param size New panel size
* @return Applied size (after validation)
*/
resize: (size: number | string) => void;
}
type BasePanelAttributes = Omit, "onResize">;
export type PanelProps = BasePanelAttributes & {
/**
* CSS class name.
*
* ⚠️ Class is applied to nested `HTMLDivElement` to avoid styles that interfere with Flex layout.
*/
className?: string | undefined;
/**
* Panel size when collapsed; defaults to 0%.
*/
collapsedSize?: number | string | undefined;
/**
* This panel can be collapsed.
*
* ℹ️ A collapsible panel will collapse when it's size is less than of the specified `minSize`
*/
collapsible?: boolean | undefined;
/**
* Default size of Panel within its parent group; default is auto-assigned based on the total number of Panels.
*
* ℹ️ Interpretation rules:
* - Numbers are interpreted as pixels (e.g. `defaultSize={200}` is 200 pixels)
* - Strings without explicit units are interpreted as percentage (e.g. `defaultSize="50"` is 50 percent)
* - Use explicit units (e.g. "px", "%", "em", "rem", "vh", or "vw") to change interpretation
*
* ⚠️ Percentage based sizes may cause slight layout shift when server-rendering.
* For more information see the documentation.
*/
defaultSize?: number | string | undefined;
/**
* When disabled, a panel cannot be resized either directly or indirectly (by resizing another panel).
*/
disabled?: boolean | undefined;
/**
* Ref attached to the root `HTMLDivElement`.
*/
elementRef?: Ref | undefined;
/**
* How should this Panel behave if the parent Group is resized?
* Defaults to `preserve-relative-size`.
*
* - `preserve-relative-size`: Retain the current relative size (as a percentage of the Group)
* - `preserve-pixel-size`: Retain its current size (in pixels)
*
* ℹ️ Panel min/max size constraints may impact this behavior.
*
* ⚠️ A Group must contain at least one Panel with `preserve-relative-size` resize behavior.
*/
groupResizeBehavior?:
| "preserve-relative-size"
| "preserve-pixel-size"
| undefined;
/**
* Uniquely identifies this panel within the parent group.
* Falls back to `useId` when not provided.
*
* ℹ️ This prop is used to associate persisted group layouts with the original panel.
*
* ℹ️ This value will also be assigned to the `data-panel` attribute.
*/
id?: string | number | undefined;
/**
* Maximum size of Panel within its parent group; defaults to `"100%"`.
*
* ℹ️ Interpretation rules:
* - Numbers are interpreted as pixels (e.g. `maxSize={200}` is 200 pixels)
* - Strings without explicit units are interpreted as percentage (e.g. `maxSize="50"` is 50 percent)
* - Use explicit units (e.g. "px", "%", "em", "rem", "vh", or "vw") to change interpretation
*/
maxSize?: number | string | undefined;
/**
* Minimum size of Panel within its parent group; defaults to 0%.
*
* ℹ️ Interpretation rules:
* - Numbers are interpreted as pixels (e.g. `minSize={200}` is 200 pixels)
* - Strings without explicit units are interpreted as percentage (e.g. `minSize="50"` is 50 percent)
* - Use explicit units (e.g. "px", "%", "em", "rem", "vh", or "vw") to change interpretation
*/
minSize?: number | string | undefined;
/**
* Called when panel sizes change.
*
* @param panelSize Panel size (both as a percentage of the parent Group and in pixels)
* @param id Panel id (if one was provided as a prop)
* @param prevPanelSize Previous panel size (will be undefined on mount)
*/
onResize?:
| ((
panelSize: PanelSize,
id: string | number | undefined,
prevPanelSize: PanelSize | undefined
) => void)
| undefined;
/**
* Exposes the following imperative API:
* - `collapse(): void`
* - `expand(): void`
* - `getSize(): number`
* - `isCollapsed(): boolean`
* - `resize(size: number): void`
*
* ℹ️ The `usePanelRef` and `usePanelCallbackRef` hooks are exported for convenience use in TypeScript projects.
*/
panelRef?: Ref | undefined;
/**
* CSS properties.
*
* ⚠️ Style is applied to nested `HTMLDivElement` to avoid styles that interfere with Flex layout.
*/
style?: CSSProperties | undefined;
};
export type OnPanelResize = PanelProps["onResize"];
/**
* Size constraints may be specified in a variety of ways:
* - Percentage of the parent Group (0..100)
* - Pixels
* - Relative font units (em, rem)
* - Viewport relative units (vh, vw)
*
* Numeric values are assumed to be pixels.
* Strings without explicit units are assumed to be percentages (0%..100%).
*
* Percentages may also be specified as strings ending with "%" (e.g. "33%")
* Pixels may also be specified as strings ending with the unit "px".
*
* Other units should be specified as strings ending with their CSS property units (e.g. 1rem, 50vh)
*/
export type PanelConstraintProps = Pick<
PanelProps,
| "collapsedSize"
| "collapsible"
| "defaultSize"
| "disabled"
| "groupResizeBehavior"
| "maxSize"
| "minSize"
>;