Controller

Generated by website/scripts/generate-api.ts from packages/gridla/src. Do not edit by hand; run bun run generate in website/.

createGridController owns layout and gesture state for one canvas without any framework: a store to render from, imperative actions, the gesture API, projection onto the measured size, and controlled or uncontrolled layout sync.

import { createGridController, createGridStore, observeSize, renderLayout, resolveControllerConfig } from 'gridla/interaction'
import type { GridController, GridControllerOptions, GridStore, GridStoreListener } from 'gridla/interaction'
ExportKindSummary
createGridControllerfunctionCreate a GridController.
createGridStorefunctionCreate a GridStore holding initial.
GridControllertypeFramework-neutral owner of one canvas: layout state, projection onto the measured size, the gesture API, and the imperative actions.
GridControllerOptionstypeOptions for createGridController: every SolveOptions field, a controlled or uncontrolled layout, change and transfer callbacks, and the settings that make up GridControllerConfig.
GridStoretypeMinimal external store: a snapshot getter, a subscribe function, and a setter.
GridStoreListenertypeCallback invoked after the store state changes.
observeSizefunctionReport an element's content box size: once synchronously, then on every ResizeObserver notification.
renderLayoutfunctionProject source onto the measured size (when config.responsive), then fit the canvas to its content.
resolveControllerConfigfunctionResolve GridControllerConfig from controller options by applying the defaults (responsive: true, dragThreshold: 4, keyboardStep: 8, gap: 0).

Functions

createGridController

function · interaction/controller.ts:196

Create a GridController. Give it a layout (controlled: every accepted change is reported through onLayoutChange and the store follows the next setOptions(\{ layout \})) or a defaultLayout (uncontrolled: the controller owns the layout and still reports changes). Call setSize with the measured canvas size (see observeSize) and destroy when the canvas goes away.

export function createGridController<TData = unknown>(
  options: GridControllerOptions<TData> = {},
): GridController<TData>

createGridStore

function · interaction/store.ts:25

Create a GridStore holding initial. Listeners fire only when set changes the state reference (compared with Object.is).

export function createGridStore<S>(initial: S): GridStore<S>

observeSize

function · interaction/measure.ts:10

Report an element's content box size: once synchronously, then on every ResizeObserver notification. A hidden or detached element measures 0x0 and is ignored so the last real size stays in effect. Returns an unsubscribe function. Safe to import during server rendering; call it only with a mounted element.

export function observeSize(element: Element, callback: (size: GridSize) => void): () => void

renderLayout

function · interaction/controller.ts:128

Project source onto the measured size (when config.responsive), then fit the canvas to its content. Without a size, or when not responsive, the layout is only normalized. This is the layout a controller stores in GridState.layout.

export function renderLayout<TData>(
  source: GridLayout<TData>,
  size: GridSize | null,
  config: GridControllerConfig,
): GridLayout<TData>

resolveControllerConfig

function · interaction/controller.ts:153

Resolve GridControllerConfig from controller options by applying the defaults (responsive: true, dragThreshold: 4, keyboardStep: 8, gap: 0).

export function resolveControllerConfig<TData>(
  options: GridControllerOptions<TData>,
): GridControllerConfig

Types

GridController

type · interaction/controller.ts:81

Framework-neutral owner of one canvas: layout state, projection onto the measured size, the gesture API, and the imperative actions. Adapters render from store and feed input through gesture (or createPointerGesture).

export type GridController<TData = unknown> = {
  /** Id of this controller. Used by transfer scopes. */
  id: string
  /** State store. Subscribe to it to render. */
  store: GridStore<GridState<TData>>
  /** Imperative layout and selection API. Stable for the controller's lifetime. */
  actions: GridActions<TData>
  /** Low-level gesture API. Stable for the controller's lifetime. */
  gesture: GridGestureApi<TData>
  /** The resolved configuration currently in effect. */
  getConfig: () => GridControllerConfig
  /**
   * Replace the configuration. When a value changed, the layout is projected
   * again onto the measured size.
   */
  setConfig: (config: GridControllerConfig) => void
  /**
   * Apply changed options: callbacks, config fields, the controlled `layout`
   * and `selectedId`, and the transfer `scope`. Cheap to call on every render.
   */
  setOptions: (options: GridControllerOptions<TData>) => void
  /** Sync a controlled layout into the store (no-op when it is already current). */
  setLayout: (layout: GridLayout<TData>) => void
  /** Update the measured canvas size and project the layout onto it. */
  setSize: (size: GridSize | null) => void
  /** Unregister from the transfer scope and drop the gesture in progress. */
  destroy: () => void
}
MemberTypeDescription
idstringId of this controller. Used by transfer scopes.
storeGridStore\<GridState\<TData\>\>State store. Subscribe to it to render.
actionsGridActions\<TData\>Imperative layout and selection API. Stable for the controller's lifetime.
gestureGridGestureApi\<TData\>Low-level gesture API. Stable for the controller's lifetime.
getConfig() =\> GridControllerConfigThe resolved configuration currently in effect.
setConfig(config: GridControllerConfig) =\> voidReplace the configuration. When a value changed, the layout is projected again onto the measured size.
setOptions(options: GridControllerOptions\<TData\>) =\> voidApply changed options: callbacks, config fields, the controlled layout and selectedId, and the transfer scope. Cheap to call on every render.
setLayout(layout: GridLayout\<TData\>) =\> voidSync a controlled layout into the store (no-op when it is already current).
setSize`(size: GridSize \null) => void`
destroy() =\> voidUnregister from the transfer scope and drop the gesture in progress.

GridControllerOptions

type · interaction/controller.ts:36

Options for createGridController: every SolveOptions field, a controlled or uncontrolled layout, change and transfer callbacks, and the settings that make up GridControllerConfig. Framework adapters map their props onto this shape and forward later changes with setOptions.

export type GridControllerOptions<TData = unknown> = SolveOptions & {
  /**
   * Stable id of this controller, unique within a `TransferScope`. Generated
   * when omitted.
   */
  id?: string
  /**
   * Controlled layout. Pair with `onLayoutChange` and forward updates with
   * `setOptions`. Accepted changes render immediately; passing the emitted
   * layout back is a no-op, passing a different one overrides it.
   */
  layout?: GridLayout<TData>
  /** Initial layout for uncontrolled use. */
  defaultLayout?: GridLayout<TData>
  /**
   * Called with the next layout after every accepted change. The layout is
   * expressed in the canvas size it was rendered at.
   */
  onLayoutChange?: (layout: GridLayout<TData>, detail: GridChangeDetail) => void
  /** Fires with the solver strategy on every accepted interactive commit. */
  onCommit?: (detail: GridChangeDetail) => void
  /** Called when an item moves to another canvas inside the `scope`. */
  onTransferOut?: (itemId: string, targetId: string) => void
  /** Called when an item arrives from another canvas. */
  onTransferIn?: (item: GridItem<TData>, sourceId: string) => void
  /** Whether items from other canvases may be dropped here. Default `true`. */
  acceptTransfers?: boolean | ((item: GridItem<TData>, sourceId: string) => boolean)
  /** Transfer scope to register with. Items can move between controllers sharing one. */
  scope?: TransferScope | null
  /** Project the layout onto the measured size. Default `true`. */
  responsive?: boolean
  /** Minimum pointer travel before a press becomes a drag. Default `4`. */
  dragThreshold?: number
  /** Pixels moved per arrow key press. Default `8`. */
  keyboardStep?: number
  /** Controlled selection. */
  selectedId?: string | null
  onSelectedIdChange?: (itemId: string | null) => void
}
MemberTypeDescription
id?stringStable id of this controller, unique within a TransferScope. Generated when omitted.
layout?GridLayout\<TData\>Controlled layout. Pair with onLayoutChange and forward updates with setOptions. Accepted changes render immediately; passing the emitted layout back is a no-op, passing a different one overrides it.
defaultLayout?GridLayout\<TData\>Initial layout for uncontrolled use.
onLayoutChange?((layout: GridLayout\<TData\>, detail: GridChangeDetail) =\> void)Called with the next layout after every accepted change. The layout is expressed in the canvas size it was rendered at.
onCommit?((detail: GridChangeDetail) =\> void)Fires with the solver strategy on every accepted interactive commit.
onTransferOut?((itemId: string, targetId: string) =\> void)Called when an item moves to another canvas inside the scope.
onTransferIn?((item: GridItem\<TData\>, sourceId: string) =\> void)Called when an item arrives from another canvas.
acceptTransfers?`boolean \((item: GridItem<TData>, sourceId: string) => boolean)`
scope?`TransferScope \null`
responsive?booleanProject the layout onto the measured size. Default true.
dragThreshold?numberMinimum pointer travel before a press becomes a drag. Default 4.
keyboardStep?numberPixels moved per arrow key press. Default 8.
selectedId?`string \null`
onSelectedIdChange?`((itemId: string \null) => void)`

GridStore

type · interaction/store.ts:14

Minimal external store: a snapshot getter, a subscribe function, and a setter. Shaped for useSyncExternalStore.

export type GridStore<S> = {
  getSnapshot: () => S
  subscribe: (listener: GridStoreListener) => () => void
  /** Replace the state. Listeners fire only when the reference changes. */
  set: (next: S | ((prev: S) => S)) => void
}
MemberTypeDescription
getSnapshot() =\> S
subscribe(listener: GridStoreListener) =\> () =\> void
set`(next: S \((prev: S) => S)) => void`

GridStoreListener

type · interaction/store.ts:8

Callback invoked after the store state changes.

export type GridStoreListener = () => void