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'
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
}
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
}
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
}
GridStoreListener
type · interaction/store.ts:8
Callback invoked after the store state changes.
export type GridStoreListener = () => void