Resizable
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:
- Handle Creation: Based on the
handles
input (which can specify 'all', individual sides like 'top', 'right', 'bottom', 'left', or a detailedLmnResizableHandles
object), the directive renders the appropriate handle elements. Custom HTML elements can also be used as handles. - 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 adata-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 aresized
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 theresized
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.
- 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. - 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.
- Applies
- 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
(aliashandles
): 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 booleantrue
will render a default handle; anHTMLElement
instance can be provided to use a custom element as a handle.
lmnResizableDisabled
(aliasdisabled
): Optional (boolean
, default:false
). Whentrue
, disables the resizing functionality and removes handles.lmnResizableNegative
(aliasnegative
): Optional (boolean
, default:false
). Iftrue
, applies a negative style variant to the default handles (e.g., for better visibility on dark backgrounds).
Outputs:
resized
: EmitsLmnResizeEvent
({ width: number, height: number, element: HTMLElement }
) continuously as the user drags a handle. The emittedwidth
andheight
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).