CDK Resizable

Resizable

Overview API Examples

The LmnResizableDirective allows an HTML element to be interactively resized by the user. It achieves this by dynamically adding visual handles to the element's borders and corners, which can be dragged to change the element's dimensions. The directive offers various configurations for handle placement and emits events when resizing occurs.

Technical Overview

The lmnResizable directive, when applied to an HTML element, enhances it with resizing capabilities. It dynamically creates and manages <span> elements that serve as resize handles, styled according to _resizable.scss. These handles are positioned absolutely around the host element.

The core logic involves:

  1. Handle Creation: Based on the handles input (which can specify 'all', individual sides like 'top', 'right', 'bottom', 'left', or a detailed LmnResizableHandles object), the directive renders the appropriate handle elements. Custom HTML elements can also be used as handles.
  2. Event Handling:
    • mousedown on a handle: Initiates the resize operation. It records the initial dimensions and mouse position, changes the body cursor to indicate resizing, and adds a data-lmn-resizable-dragging attribute to the document body.
    • mousemove on the document: Calculates the change in mouse position and determines the new width and height. It then emits a resized event with the new dimensions and a reference to the element. Note: The directive itself does not directly apply the new width/height to the element; the consumer of the resized event is responsible for updating the element's style.
    • mouseup on the document: Terminates the resize operation, cleans up event listeners, and restores the body cursor.
  3. State Management: The directive uses a signal (dragging) to track whether a resize operation is currently in progress, applying a .lmn-resizing class to the host element accordingly.
  4. RTL Support: Styles for handles (e.g., left/right positioning and cursor types) include RTL considerations.

The directive relies on LmnResizableHandles and LmnResizeEvent types defined in resizable.model.ts for its configuration and event emissions.

Key Features

  • Interactive Resizing: Allows users to resize an element by dragging handles.
  • Configurable Handles: Supports resizing from any side (top, right, bottom, left) or corner (topLeft, topRight, bottomLeft, bottomRight), or all simultaneously. Custom HTML elements can be designated as handles.
  • Event Emission: Emits an LmnResizeEvent ({ width: number, height: number, element: HTMLElement }) during the resize operation, providing the new calculated dimensions. The consumer is responsible for applying these dimensions.
  • Disabled State: Resizing functionality can be disabled via an input.
  • Negative Styling: Supports a negative input to apply alternative styling to handles (e.g., for dark backgrounds).
  • Visual Feedback:
    • Applies .lmn-resizable class to the host element.
    • Applies .lmn-resizing class to the host element during a drag operation.
    • Changes mouse cursor appropriately over handles and during drag.
    • Handles have hover and dragging states for visual indication.
  • RTL Awareness: Handle positioning and cursor styles adapt to LTR/RTR page direction.

When to Use

Use the LmnResizableDirective when:

  • You need to provide users with the ability to dynamically change the dimensions of an element on the page (e.g., panels, text areas, images, widgets).
  • You want a declarative way to add resizing capabilities to elements.
  • You need to react to resize events to perform custom logic, such as persisting new dimensions or adjusting internal layouts.

Implementation

Apply the [lmnResizable] directive to the HTML element you want to make resizable.

Inputs:

  • lmnResizable (alias handles): Optional ('top' | 'right' | 'bottom' | 'left' | 'all' | LmnResizableHandles, default: 'all'). Defines which resize handles are available.
    • 'all': Enables all eight handles (sides and corners).
    • 'top', 'right', 'bottom', 'left': Enables only the specified side handle.
    • LmnResizableHandles object: Allows fine-grained control, e.g., { top: true, bottomRight: true }. A boolean true will render a default handle; an HTMLElement instance can be provided to use a custom element as a handle.
  • lmnResizableDisabled (alias disabled): Optional (boolean, default: false). When true, disables the resizing functionality and removes handles.
  • lmnResizableNegative (alias negative): Optional (boolean, default: false). If true, applies a negative style variant to the default handles (e.g., for better visibility on dark backgrounds).

Outputs:

  • resized: Emits LmnResizeEvent ({ width: number, height: number, element: HTMLElement }) continuously as the user drags a handle. The emitted width and height are the new calculated dimensions. It is the responsibility of the component using this directive to listen to this event and apply the new dimensions to the element's style.

Host Classes:

  • .lmn-resizable: Always applied to the host element.
  • .lmn-resizing: Applied to the host element while a resize operation is in progress (i.e., a handle is being dragged).