v1.0
Primitive API / Page 04·03

FlexiWidget

A component, such as a tile, that lives inside a target. You can move a widget within its target or to another target.

FlexiWidget (component)

Props
NameDescription
controller
Optional Bindable
FlexiWidgetController | undefined

The controller managing this component's state and behaviour. Bind to it to access the component's imperative API.

onfirstcreate
Optional
((instance: FlexiWidgetController) => void) | undefined

Fires when the component's controller is first created.

component
Optional
(Component)

The component that is rendered by this widget.

draggability
Optional
'none' | 'movable' | 'full' | undefined

The draggability of the widget.

Default: full

resizability
Optional
'none' | 'horizontal' | 'vertical' | 'both' | undefined

The resizability of the widget.

Default: none

componentProps
Optional
Record<string, any> | undefined

The props applied to the component rendered, if it has one.

transition
Optional
FlexiWidgetTransitionConfiguration | undefined

The transition configuration for this widget.

grabTrigger
Optional
FlexiWidgetTriggerConfiguration | undefined

The configuration for how pointer events should trigger a grab event on the widget. E.g. a long press.

resizeTrigger
Optional
FlexiWidgetTriggerConfiguration | undefined

The configuration for how pointer events should trigger a resize event on the widget. E.g. a long press.

minWidth
Optional
number | undefined

The minimum width of the widget in units. Defaults to 1, cannot be less than 1.

minHeight
Optional
number | undefined

The minimum height of the widget in units. Defaults to 1, cannot be less than 1.

maxWidth
Optional
number | undefined

The maximum width of the widget in units. Defaults to Infinity, cannot be less than 1.

maxHeight
Optional
number | undefined

The maximum height of the widget in units. Defaults to Infinity, cannot be less than 1.

id
Optional
string | undefined

A stable identifier for this widget, used for persistence and layout import/export. Read when the widget is created.

type
Optional
string | undefined

The registry key used when creating this widget. Changing the prop does not recreate it.

x
Optional
number | undefined

The starting column (x-coordinate) of the widget. After creation, use moveTo() to move it.

y
Optional
number | undefined

The starting row (y-coordinate) of the widget. After creation, use moveTo() to move it.

width
Optional
number | undefined

The initial width of the widget in grid units. Changing the prop does not resize an existing widget.

height
Optional
number | undefined

The initial height of the widget in grid units. Changing the prop does not resize an existing widget.

metadata
Optional
Record<string, any> | undefined

Arbitrary metadata associated with this widget, carried through layout export/import.

class
Optional Bindable
(ClassValue | ((widget: FlexiWidgetController) => ClassValue))

The class names to apply to this widget. Either a class value, or a function deriving one from the widget's state.

children
Optional Bindable
(Snippet<[{ widget: FlexiWidgetController }]>)

The content rendered within the widget.

Widget content is rendered either from children, which receives the widget’s controller, or from the component prop (with componentProps), or both.

<script lang="ts">
	import { FlexiWidget } from '@flexiboards/svelte';
</script>

<FlexiWidget
	draggability="full"
	resizability="both"
	width={2}
	height={1}
	class={(widget) => ['rounded-lg border p-4', widget.isGrabbed && 'opacity-50']}
>
	{#snippet children({ widget })}
		<span>{widget.width} × {widget.height}</span>
	{/snippet}
</FlexiWidget>

Adding widgets later

You can mount new FlexiWidget declarations after the target has loaded. Each declaration uses the same placement rules as target.createWidget(): flow grids follow their placement strategy, and free-form grids check coordinates, dimensions, and collisions.

Svelte Example.svelte
Press Enter to grab or resize widgets. Once grabbed, use Arrow keys to move/resize the widget, Enter to confirm the action, or Esc to cancel it.
Note 1

Keep list keys stable. A declaration registers once per mount; rerendering it updates its props without adding another widget. The board owns the created widget, so removing its declaration does not delete it. Use widget.delete() or target.clear() to remove widgets.

An accepted addition fires onfirstcreate and reports the new layout through onLayoutChange. If placement fails, the widget is not created and a warning explains the failure. Freeing space later does not automatically retry a rejected declaration.

FlexiWidgetController

You can access the controller by binding to the controller prop, from the onfirstcreate callback, or from the children snippet parameter. Inside a component rendered by the component prop, call getFlexiwidgetCtx().

<script lang="ts">
	import { getFlexiwidgetCtx } from '@flexiboards/svelte';

	const widget = getFlexiwidgetCtx();
</script>

<span>{widget.isGrabbed ? 'Moving' : 'Idle'}</span>

Use the FlexiWidgetController to read widget state directly.

Properties
NameDescription
target
FlexiTargetController | undefined

The target this widget is under. Undefined until the widget is dropped in the board.

ref
HTMLElement | undefined

The DOM element bound to this widget.

isShadow
boolean

Whether this widget is a shadow dropzone widget.

isGrabbed
Readonly
boolean

Whether this widget is grabbed.

isResizing
Readonly
boolean

Whether this widget is being resized.

dropRejected
boolean

Whether the widget is being grabbed or resized over a target that cannot accept it where it is: the drop would be rejected on release and the widget would return to where it came from.

isInterpolating
Readonly
boolean

Whether the widget is currently animating to a new position or size, e.g. mid drop flight. Useful for styling that should only apply at rest, such as hover effects that would otherwise fire as the widget lands under the pointer.

currentAction
WidgetAction | null

When the widget is being grabbed, this contains information that includes its position, size and offset. When this is null, the widget is not being grabbed.

draggable
Readonly
boolean

Whether the widget can move at all: its `draggability` is not `'none'`. Read-only; set `draggability` to change it.

draggability
'none' | 'movable' | 'full'

The draggability of the widget.

isGrabbable
Readonly
boolean

Whether the widget can be grabbed.

isMovable
Readonly
boolean

Whether the widget can be moved.

resizability
'none' | 'horizontal' | 'vertical' | 'both'

The resizability of the widget.

resizable
Readonly
boolean

Whether the widget is resizable.

width
Readonly
number

The width in units of the widget.

height
Readonly
number

The height in units of the widget.

component
(Component) | undefined

The component that is rendered by this widget.

componentProps
Record<string, any> | undefined

The props applied to the component rendered, if it has one.

snippet
(Snippet<[{ widget: FlexiWidgetController }]>) | undefined

The render function used for this widget's content.

className
unknown

The class name that is applied to this widget.

x
Readonly
number

Gets the column (x-coordinate) of the widget. This value is readonly and is managed by the target.

y
Readonly
number

Gets the row (y-coordinate) of the widget. This value is readonly and is managed by the target.

metadata
Record<string, any> | undefined

The metadata associated with this widget, if any.

grabTrigger
Readonly
FlexiWidgetTriggerConfiguration

Gets the configuration for how pointer events should trigger widget grabs (either on the widget directly or on a grabber).

resizeTrigger
Readonly
FlexiWidgetTriggerConfiguration

Gets the configuration for how pointer events should trigger widget resizing on a resizer.

transitionConfig
Readonly
FlexiWidgetTransitionConfiguration

Gets the transition configuration for this widget.

hasGrabbers
Readonly
boolean

Whether the widget has any grabbers attached.

hasResizers
Readonly
boolean

Whether the widget has any resizers attached

isBeingDropped
boolean

Whether the widget is currently being dropped after a drag operation.

minWidth
Readonly
number

The minimum width of the widget in units.

minHeight
Readonly
number

The minimum height of the widget in units.

maxWidth
Readonly
number

The maximum width of the widget in units.

maxHeight
Readonly
number

The maximum height of the widget in units.

userProvidedId
Readonly
string | undefined

The user-provided stable identifier for this widget, if any. This is used for persistence and layout import/export.

type
Readonly
string | undefined

The type of this widget (registry key for looking up configuration).

Methods
NameDescription
delete
() => void

Deletes this widget from its target and board. Fires the board's `onWidgetDelete` and `onLayoutChange`.

moveTo
(options: { target?: FlexiTargetController; x?: number; y?: number }) => boolean

Moves this widget through the controller API, with no user interaction: to a position in its own target, to another target (at a position, or wherever that target's grid puts it), or both. Runs the grid's placement rules but not `canDrop`, which is for user drops. Fires `onLayoutChange`.

FlexiWidgetConfiguration

FlexiWidget accepts configuration as props. Changes to rendering, metadata, interaction options, size limits, and transitions update the existing widget. id, type, x, y, width, and height initialize the widget; changing those props does not recreate or reposition it. Use moveTo() for movement, or import a layout to replace widget positions and sizes. See Configuration reactivity.

Properties
NameDescription
draggability
Optional
'none' | 'movable' | 'full' | undefined

The draggability of the widget.

Default: full

resizability
Optional
'none' | 'horizontal' | 'vertical' | 'both' | undefined

The resizability of the widget.

Default: none

snippet
Optional
(Snippet<[{ widget: FlexiWidgetController }]>)

The render function used for this widget's content.

component
Optional
(Component)

The component that is rendered by this widget.

componentProps
Optional
Record<string, any> | undefined

The props applied to the component rendered, if it has one.

className
Optional
(ClassValue | ((widget: FlexiWidgetController) => ClassValue)) | undefined

The class names to apply to this widget.

transition
Optional
FlexiWidgetTransitionConfiguration | undefined

The transition configuration for this widget.

grabTrigger
Optional
FlexiWidgetTriggerConfiguration | undefined

The configuration for how pointer events should trigger a grab event on the widget. E.g. a long press.

resizeTrigger
Optional
FlexiWidgetTriggerConfiguration | undefined

The configuration for how pointer events should trigger a resize event on the widget. E.g. a long press.

minWidth
Optional
number | undefined

The minimum width of the widget in units. Defaults to 1, cannot be less than 1.

minHeight
Optional
number | undefined

The minimum height of the widget in units. Defaults to 1, cannot be less than 1.

maxWidth
Optional
number | undefined

The maximum width of the widget in units. Defaults to Infinity, cannot be less than 1.

maxHeight
Optional
number | undefined

The maximum height of the widget in units. Defaults to Infinity, cannot be less than 1.

id
Optional
string | undefined

A stable identifier for this widget, used for persistence and layout import/export. Read when the widget is created.

type
Optional
string | undefined

The registry key used when creating this widget. Changing the prop does not recreate it.

x
Optional
number | undefined

The starting column (x-coordinate) of the widget. After creation, use moveTo() to move it.

y
Optional
number | undefined

The starting row (y-coordinate) of the widget. After creation, use moveTo() to move it.

width
Optional
number | undefined

The initial width of the widget in grid units. Changing the prop does not resize an existing widget.

height
Optional
number | undefined

The initial height of the widget in grid units. Changing the prop does not resize an existing widget.

metadata
Optional
Record<string, any> | undefined

Arbitrary metadata associated with this widget, carried through layout export/import.

FlexiWidgetTransitionConfiguration

The transition property of a widget’s configuration (or of widgetDefaults). See the Transitions guide for presets and the animation adapters.

Properties
NameDescription
move
Optional
({ duration?: number; easing?: string } | AnimationAdapter)

Plays when a widget moves between cells of a grid, including when it is pushed aside by another widget. Omit to play no animation.

drop
Optional
({ duration?: number; easing?: string } | AnimationAdapter)

Plays when a grabbed widget is released and settles into its cell. Omit to play no animation.

resize
Optional
({ duration?: number; easing?: string } | AnimationAdapter)

Plays when a widget is released from a resize and settles at its new size. Omit to play no animation.

Accessibility

Each placed widget renders as role="gridcell" with one-based aria-colindex and aria-rowindex, plus aria-colspan and aria-rowspan. The held widget temporarily uses role="group"; its preview is hidden and inert. The data-flexi-widget attribute remains present in every state. A grabbable widget is in the tab order unless it contains a FlexiGrab, in which case the handle is.

KeyEffect
EnterGrabs the focused widget; while grabbed, drops it.
Arrow keysMoves the grabbed widget. Shift for larger steps, Ctrl / Cmd for finer ones.
EscapeCancels a grab or resize.

Grabs, resizes, releases, and rejected drops are announced through the board’s live region. Styling the isGrabbed, isShadow, and dropRejected states is up to you; see Widget Rendering. Full details in Accessibility.