@snapgridjs/react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["Feedback","PointerSensor","KeyboardSensor","verticalCompactor","useDroppable","useDraggable","useDraggable","verticalCompactor"],"sources":["../src/context.ts","../src/dragFlow.ts","../src/grouping.ts","../src/hooks/dndShared.ts","../src/SnapGridProvider.tsx","../src/SnapGridGroup.tsx","../src/hooks/useGridContainer.ts","../src/hooks/useGridItem.ts","../src/hooks/useGridPlaceholder.ts","../src/hooks/useGridResizeHandle.ts","../src/hooks/useGridDragOverlay.ts","../src/hooks/useResponsiveLayout.ts","../src/GridDragOverlay.tsx","../src/GridItem.tsx","../src/GridPlaceholder.tsx","../src/GridLayout.tsx","../src/ResponsiveGridLayout.tsx","../src/hooks/useContainerWidth.ts"],"sourcesContent":["import type { Sensors } from \"@dnd-kit/dom\";\nimport type {\n DragSession,\n GridConfig,\n Layout,\n LayoutItem,\n PositionParams,\n ResizeHandleAxis,\n} from \"@snapgridjs/core\";\nimport { createContext, useContext } from \"react\";\n\n/** Data attached to the dnd-kit draggables snapgrid creates. */\nexport type SnapGridDragData =\n // `item` carries the full layout entry so a *different* grid can render/insert\n // it when the tile is dragged across grids.\n | { kind: \"move\"; itemId: string; item: LayoutItem }\n | { kind: \"resize\"; itemId: string; handle: ResizeHandleAxis };\n\n/**\n * Live grid state shared by {@link SnapGridProvider} with the headless hooks.\n * Holds no DOM and imposes no styling — just the data hooks need to produce\n * refs, positioning styles, and state flags.\n */\nexport interface GridRuntime {\n /** Stable id of the grid's droppable surface. */\n containerId: string;\n /** Measured container width in pixels. */\n width: number;\n /** Grow the container height to fit content. */\n autoSize: boolean;\n /** Resolved grid configuration. */\n gridConfig: GridConfig;\n /** Geometry params derived from gridConfig + width. */\n positionParams: PositionParams;\n /** The layout currently being rendered (drag preview if dragging, else the controlled layout). */\n renderedLayout: Layout;\n /** Fast lookup into {@link renderedLayout} by item id. */\n itemsById: ReadonlyMap<string, LayoutItem>;\n /** The in-progress drag session, or null. */\n session: DragSession | null;\n /** Whether the item with this id may be dragged. */\n isItemDraggable: (id: string) => boolean;\n /** Whether the item with this id may be resized. */\n isItemResizable: (id: string) => boolean;\n /** The resize handles to show for the item with this id. */\n resizeHandlesFor: (id: string) => readonly ResizeHandleAxis[];\n /** Sensors for item (move) draggables (threshold + handle/cancel gating). */\n itemSensors: Sensors;\n /** Called by {@link useGridContainer} to report the surface element (for cross-grid geometry). */\n setContainerElement: (element: Element | null) => void;\n /** The floating drag preview for this grid's active drag (source grid only), or null. */\n overlay: GridOverlayInfo | null;\n}\n\n/** Where/what to render as the floating drag preview (a body portal). */\nexport interface GridOverlayInfo {\n item: LayoutItem;\n /** Fixed (viewport) coordinates and size of the preview. */\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\nexport const GridContext = createContext<GridRuntime | null>(null);\n\n/** Read the grid runtime; throws if used outside a `SnapGridProvider`. */\nexport function useGridRuntime(): GridRuntime {\n const runtime = useContext(GridContext);\n if (!runtime) {\n throw new Error(\n \"snapgrid: hooks and components must be rendered inside a <SnapGridProvider> (or <GridLayout>).\",\n );\n }\n return runtime;\n}\n","import { type PositionParams, calcXY } from \"@snapgridjs/core\";\n\n/**\n * Pure decision helpers for the drag interaction, extracted from\n * {@link SnapGridProvider} so the tricky bits — grab-offset cell mapping and the\n * cross-grid drop lifecycle — are unit-testable without a DOM or dnd-kit.\n */\n\n/**\n * Map a client-space pointer to a grid cell, accounting for where *within* the\n * dragged tile the pointer grabbed it. Subtracting the grab offset means the\n * tile's top-left (not the cursor) maps to the cell, so a received tile's\n * placeholder aligns with the floating overlay instead of jumping its corner to\n * the cursor. External drops pass `{ x: 0, y: 0 }` (no meaningful grab point).\n */\nexport function receiveCell(\n pointer: { x: number; y: number },\n gridRect: { left: number; top: number },\n grabOffset: { x: number; y: number },\n w: number,\n h: number,\n pp: PositionParams,\n): { x: number; y: number } {\n return calcXY(\n pp,\n pointer.y - grabOffset.y - gridRect.top,\n pointer.x - grabOffset.x - gridRect.left,\n w,\n h,\n );\n}\n\n/** State gathered by the drag-end handler, fed to {@link classifyDrop}. */\nexport interface DropState {\n /** Kind of the in-progress session, or null if there is none. */\n kind: \"move\" | \"resize\" | null;\n /** Whether the drag was canceled (Esc / abort). */\n canceled: boolean;\n /** Does THIS grid own the dragged item (i.e. it is the source)? */\n ownsItem: boolean;\n /** Is the drag source a grid item (vs. an external draggable)? */\n hasData: boolean;\n /** Id of the grid under the drop pointer, or null if none. */\n dest: string | null;\n /** This grid's id. */\n myId: string;\n}\n\n/**\n * What the drag-end handler should do. Each action implies a specific set of\n * callbacks — encoded here so the cross-grid lifecycle contract is explicit and\n * testable:\n * - `commit-in-grid` / `remove-source` / `revert` all fire `onDragStop` (the\n * SOURCE grid owns the drag's start/stop pair);\n * - `commit-dest` fires only `onLayoutChange` — the destination grid never\n * fired `onDragStart`, so emitting `onDragStop` there would be unbalanced.\n */\nexport type DropAction =\n | \"cancel-resize\"\n | \"cancel-move\"\n | \"commit-resize\"\n | \"commit-in-grid\"\n | \"remove-source\"\n | \"revert\"\n | \"commit-dest\"\n | \"external-drop\"\n | \"noop\";\n\n/** Pure classification of a drag end. See {@link DropAction}. */\nexport function classifyDrop(s: DropState): DropAction {\n if (s.canceled) {\n if (s.kind === \"resize\") return \"cancel-resize\";\n if (s.ownsItem) return \"cancel-move\";\n return \"noop\";\n }\n if (s.kind === \"resize\") return \"commit-resize\";\n\n if (s.ownsItem && s.hasData) {\n if (s.dest === s.myId && s.kind === \"move\") return \"commit-in-grid\";\n if (s.dest) return \"remove-source\";\n return \"revert\";\n }\n\n // Not the owner: we can only be a receiving grid, and only with a session.\n if (s.dest === s.myId && s.kind === \"move\") {\n return s.hasData ? \"commit-dest\" : \"external-drop\";\n }\n return \"noop\";\n}\n","import { createContext } from \"react\";\n\n/**\n * Tracks the grids that share a {@link SnapGridGroup} so any grid can resolve\n * which grid a pointer is over. We use geometry (not dnd-kit's collision\n * target) because snapgrid drags with `feedback: 'none'`, under which dnd-kit\n * does not track a moving shape and never resolves a droppable target.\n */\nexport interface GridRegistry {\n /** Register a grid's id and a getter for its current client rect. Returns an unregister fn. */\n register(id: string, getRect: () => DOMRect | null): () => void;\n /** Id of the registered grid whose rect contains `point`, or null. */\n gridAt(point: { x: number; y: number }): string | null;\n /**\n * Record the pixel offset of the pointer within the dragged tile at drag\n * start (or `null` to clear). Shared so a *receiving* grid can place the tile\n * under the same point the user grabbed, not with its top-left at the cursor.\n */\n setGrabOffset(offset: { x: number; y: number } | null): void;\n /** The active drag's grab offset, or `{ x: 0, y: 0 }` when none is recorded. */\n getGrabOffset(): { x: number; y: number };\n}\n\nexport function createGridRegistry(): GridRegistry {\n const grids = new Map<string, () => DOMRect | null>();\n let grabOffset: { x: number; y: number } | null = null;\n return {\n register(id, getRect) {\n grids.set(id, getRect);\n return () => {\n if (grids.get(id) === getRect) grids.delete(id);\n };\n },\n gridAt(point) {\n for (const [id, getRect] of grids) {\n const r = getRect();\n if (\n r &&\n point.x >= r.left &&\n point.x <= r.right &&\n point.y >= r.top &&\n point.y <= r.bottom\n ) {\n return id;\n }\n }\n return null;\n },\n setGrabOffset(offset) {\n grabOffset = offset;\n },\n getGrabOffset() {\n return grabOffset ?? { x: 0, y: 0 };\n },\n };\n}\n\n/** Non-null when grids are wrapped in a `<SnapGridGroup>` (shared cross-grid registry). */\nexport const SnapGridGroupContext = createContext<GridRegistry | null>(null);\n","import {\n Feedback,\n KeyboardSensor,\n PointerActivationConstraints,\n PointerSensor,\n type Sensors,\n} from \"@dnd-kit/dom\";\nimport type { DragConfig } from \"../types.js\";\n\n/** Marker attribute placed on resize-handle elements. */\nexport const RESIZE_HANDLE_ATTR = \"data-snapgrid-resize-handle\";\n\n// `feedback: \"none\"` so dnd-kit doesn't move/transform the dragged element:\n// snapgrid hides the active tile in place and floats its own body-portal preview\n// (see GridDragOverlay). Module-level so the descriptor identity is stable across\n// re-renders.\nexport const NO_FEEDBACK = [Feedback.configure({ feedback: \"none\" })];\n\n/**\n * Whether a pointer-down on `target` should NOT start an item move. Pure and\n * exported for testing. Honors three rules, in order:\n * - never start a move from a resize handle;\n * - never start from a region matching `dragConfig.cancel`;\n * - if `dragConfig.handle` is set, only start from within it.\n */\nexport function shouldPreventItemDrag(\n target: EventTarget | null,\n cfg: DragConfig | undefined,\n): boolean {\n if (!(target instanceof Element)) return false;\n if (target.closest(`[${RESIZE_HANDLE_ATTR}]`)) return true;\n if (cfg?.cancel && target.closest(cfg.cancel)) return true;\n if (cfg?.handle && !target.closest(cfg.handle)) return true;\n return false;\n}\n\n/**\n * Sensors for item (move) draggables, built from the drag config: a distance\n * activation threshold (so clicks don't start drags) plus handle/cancel/resize\n * gating, with the keyboard sensor kept for accessibility.\n */\nexport function buildItemSensors(\n threshold: number,\n getDragConfig: () => DragConfig | undefined,\n): Sensors {\n return [\n PointerSensor.configure({\n activationConstraints: () =>\n threshold > 0\n ? [new PointerActivationConstraints.Distance({ value: threshold })]\n : undefined,\n preventActivation: (event: PointerEvent) =>\n shouldPreventItemDrag(event.target, getDragConfig()),\n }),\n KeyboardSensor,\n ];\n}\n","import { DragDropProvider, useDragDropMonitor } from \"@dnd-kit/react\";\nimport type { DragEndEvent, DragMoveEvent, DragStartEvent } from \"@dnd-kit/react\";\nimport {\n type Compactor,\n type DragSession,\n type GridConfig,\n type Layout,\n type LayoutItem,\n type PositionParams,\n beginDrag,\n beginReceive,\n beginResize,\n calcGridItemPosition,\n commitLayout,\n defaultGridConfig,\n dragResize,\n dragTo,\n nudge,\n removeItemWithCompactor,\n toPositionParams,\n verticalCompactor,\n} from \"@snapgridjs/core\";\nimport {\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n GridContext,\n type GridOverlayInfo,\n type GridRuntime,\n type SnapGridDragData,\n} from \"./context.js\";\nimport { classifyDrop, receiveCell } from \"./dragFlow.js\";\nimport { type GridRegistry, SnapGridGroupContext, createGridRegistry } from \"./grouping.js\";\nimport { buildItemSensors } from \"./hooks/dndShared.js\";\nimport type {\n DragConfig,\n DropConfig,\n GridDropData,\n GridEventCallback,\n ResizeConfig,\n} from \"./types.js\";\n\nconst DEFAULT_HANDLES = [\"se\"] as const;\n\ntype Point = { x: number; y: number };\n\n/** Read snapgrid's payload off a dnd-kit drag source. */\nfunction dragData(event: {\n operation: { source?: { data?: unknown } | null };\n}): SnapGridDragData | undefined {\n const data = event.operation.source?.data as { snapGrid?: SnapGridDragData } | undefined;\n return data?.snapGrid;\n}\n\n/** Size/id spec for an external (non-grid) draggable the grid may accept, or null. */\nexport function externalDropSpec(\n source: { id: string | number; type?: unknown; data?: unknown } | null | undefined,\n dropConfig: DropConfig | undefined,\n): { i?: string; w: number; h: number } | null {\n if (!dropConfig?.enabled || !source) return null;\n const data = source.data as { snapGrid?: unknown; snapGridDrop?: GridDropData } | undefined;\n if (data?.snapGrid) return null; // a grid item, not external\n if (dropConfig.accept && !dropConfig.accept(source)) return null;\n const spec = data?.snapGridDrop;\n return {\n i: spec?.i,\n // Fall back to react-grid-layout's `defaultDropConfig.defaultItem` (1×1) for parity.\n w: spec?.w ?? dropConfig.defaultItem?.w ?? 1,\n h: spec?.h ?? dropConfig.defaultItem?.h ?? 1,\n };\n}\n\nexport interface SnapGridProviderProps {\n children: ReactNode;\n /** Container width in pixels (e.g. from {@link useContainerWidth}). */\n width: number;\n /** Controlled layout. Never mutated. */\n layout: Layout;\n /** Called with the next layout after a drag/resize commits (incl. cross-grid add/remove). */\n onLayoutChange?: (layout: Layout) => void;\n gridConfig?: Partial<GridConfig>;\n dragConfig?: DragConfig;\n resizeConfig?: ResizeConfig;\n /** Accept external (non-grid) dnd-kit draggables dropped into this grid. */\n dropConfig?: DropConfig;\n compactor?: Compactor;\n /** Grid-level draggable toggle (item-level `isDraggable`/`static` override). @default true */\n isDraggable?: boolean;\n /** Grid-level resizable toggle (item-level `isResizable`/`static` override). @default true */\n isResizable?: boolean;\n /** Grow container height to fit content. @default true */\n autoSize?: boolean;\n /** Stable id for the grid's droppable surface (auto-generated if omitted). */\n id?: string;\n onDragStart?: GridEventCallback;\n onDrag?: GridEventCallback;\n onDragStop?: GridEventCallback;\n onResizeStart?: GridEventCallback;\n onResize?: GridEventCallback;\n onResizeStop?: GridEventCallback;\n /** Called when an external draggable is dropped into the grid: the next layout, the new item, and the event. */\n onDrop?: (layout: Layout, item: LayoutItem, event: Event | null) => void;\n}\n\n/**\n * Headless provider for a grid. Standalone grids get their own isolated dnd-kit\n * provider; grids inside a {@link SnapGridGroup} share that group's provider and\n * registry so tiles can be dragged between them. Owns this grid's drag/resize\n * session; the consumer owns all markup/styling.\n */\nexport function SnapGridProvider(props: SnapGridProviderProps): React.JSX.Element {\n const groupRegistry = useContext(SnapGridGroupContext);\n const runtime = <SnapGridRuntime groupRegistry={groupRegistry} {...props} />;\n // In a group, share the group's provider; otherwise self-provide (so\n // independent grids don't share a manager and collide item ids).\n return groupRegistry ? runtime : <DragDropProvider>{runtime}</DragDropProvider>;\n}\n\ntype RuntimeProps = SnapGridProviderProps & { groupRegistry: GridRegistry | null };\n\nfunction SnapGridRuntime(props: RuntimeProps): React.JSX.Element {\n const autoId = useId();\n const containerId = props.id ?? autoId;\n\n const gridConfig: GridConfig = useMemo(\n () => ({ ...defaultGridConfig, ...props.gridConfig }),\n [props.gridConfig],\n );\n const positionParams: PositionParams = useMemo(\n () => toPositionParams(gridConfig, props.width),\n [gridConfig, props.width],\n );\n const compactor: Compactor = props.compactor ?? verticalCompactor;\n\n const [session, setSession] = useState<DragSession | null>(null);\n // The floating preview (body portal) while this grid is the drag source.\n const [overlay, setOverlay] = useState<GridOverlayInfo | null>(null);\n\n // Refs read inside the stable monitor handlers so they never see stale values.\n const propsRef = useRef(props);\n propsRef.current = props;\n const ppRef = useRef(positionParams);\n ppRef.current = positionParams;\n const gridRef = useRef(gridConfig);\n gridRef.current = gridConfig;\n const compactorRef = useRef(compactor);\n compactorRef.current = compactor;\n const containerIdRef = useRef(containerId);\n containerIdRef.current = containerId;\n const sessionRef = useRef<DragSession | null>(null);\n const containerElRef = useRef<Element | null>(null);\n // True while the active move was started by the keyboard (Enter/Space on a\n // focused tile) rather than a pointer — drives the arrow-key drag path.\n const keyboardRef = useRef(false);\n // External-drop bookkeeping: a stable synthesized item id + size for the\n // in-flight external draggable this grid may receive.\n const dropSpecRef = useRef<{ i: string; w: number; h: number } | null>(null);\n const dropCounterRef = useRef(0);\n\n // Each grid registers with a shared registry (group) or its own (standalone)\n // so we can resolve which grid the pointer is over by geometry — dnd-kit's\n // collision target is unavailable under `feedback: 'none'`.\n const localRegistryRef = useRef<GridRegistry | null>(null);\n if (!localRegistryRef.current) localRegistryRef.current = createGridRegistry();\n const registry = props.groupRegistry ?? localRegistryRef.current;\n const registryRef = useRef(registry);\n registryRef.current = registry;\n\n useEffect(\n () =>\n registry.register(containerId, () => containerElRef.current?.getBoundingClientRect() ?? null),\n [registry, containerId],\n );\n\n const committedById = useMemo(\n () => new Map<string, LayoutItem>(props.layout.map((it) => [it.i, it])),\n [props.layout],\n );\n const committedByIdRef = useRef(committedById);\n committedByIdRef.current = committedById;\n\n const setSessionBoth = useCallback((next: DragSession | null) => {\n sessionRef.current = next;\n setSession(next);\n }, []);\n\n const setContainerElement = useCallback((element: Element | null) => {\n containerElRef.current = element;\n }, []);\n\n /**\n * Is THIS grid the one under `p` (client coords)? Resolved through the\n * registry (not a self-only rect test) so the move-phase preview and the\n * drop-phase commit — which both go through `gridAt` — always agree on which\n * grid wins when grids overlap (`gridAt` returns a single first match).\n */\n const overMe = useCallback(\n (p: Point) => registryRef.current.gridAt(p) === containerIdRef.current,\n [],\n );\n\n /** Map a client-space pointer to a grid cell within THIS grid (see {@link receiveCell}). */\n const cellFromPointer = useCallback((p: Point, item: LayoutItem) => {\n const el = containerElRef.current;\n if (!el) return null;\n const rect = el.getBoundingClientRect();\n return receiveCell(p, rect, registryRef.current.getGrabOffset(), item.w, item.h, ppRef.current);\n }, []);\n\n const ctx = useCallback(\n () => ({\n positionParams: ppRef.current,\n compactor: compactorRef.current,\n cols: gridRef.current.cols,\n }),\n [],\n );\n\n const handleDragStart = useCallback(\n (event: DragStartEvent) => {\n // Reset on every start (incl. the external/resize early-returns below) so a\n // keyboard flag can never leak from a prior drag into an unrelated one.\n keyboardRef.current = false;\n const data = dragData(event);\n if (!data) {\n // An external (non-grid) draggable: if we accept it, reserve a stable\n // synthesized id/size for the item this grid may receive on drop.\n const spec = externalDropSpec(event.operation.source, propsRef.current.dropConfig);\n if (spec) {\n dropCounterRef.current += 1;\n dropSpecRef.current = {\n // Prefix with this grid's id so two drop-enabled grids in a group\n // don't both mint `dropped-1` (colliding item ids).\n i: spec.i ?? `${containerIdRef.current}-dropped-${dropCounterRef.current}`,\n w: spec.w,\n h: spec.h,\n };\n } else {\n dropSpecRef.current = null;\n }\n return;\n }\n dropSpecRef.current = null;\n const layout = propsRef.current.layout;\n const item = layout.find((it) => it.i === data.itemId);\n const p = event.operation.position.current;\n const pointer = { x: p.x, y: p.y };\n if (data.kind === \"resize\") {\n if (!item) return; // resize only applies to the owning grid\n const rect = calcGridItemPosition(ppRef.current, item.x, item.y, item.w, item.h);\n setSessionBoth(beginResize(layout, { item, rect, pointer }, data.handle));\n propsRef.current.onResizeStart?.(\n layout,\n item,\n item,\n item,\n event.operation.activatorEvent,\n null,\n );\n return;\n }\n if (item) {\n // We own the item — this is the source grid.\n keyboardRef.current = event.operation.activatorEvent instanceof KeyboardEvent;\n const rect = calcGridItemPosition(ppRef.current, item.x, item.y, item.w, item.h);\n setSessionBoth(beginDrag(layout, { item, left: rect.left, top: rect.top, pointer }));\n // Capture the dragged element's client rect for the body-portal preview,\n // so it can float across grids without being clipped.\n const el = (event.operation.source as { element?: Element } | null)?.element;\n const cr = el?.getBoundingClientRect();\n if (cr) {\n // Share the grab offset (pointer position within the tile) so both this\n // grid's floating overlay and any receiving grid's placeholder align to\n // it rather than snapping the tile's corner to the cursor.\n registryRef.current.setGrabOffset({ x: pointer.x - cr.left, y: pointer.y - cr.top });\n setOverlay({ item, left: cr.left, top: cr.top, width: cr.width, height: cr.height });\n }\n propsRef.current.onDragStart?.(\n layout,\n item,\n item,\n item,\n event.operation.activatorEvent,\n null,\n );\n }\n // Otherwise the item belongs to another grid; we may receive it on move.\n },\n [setSessionBoth],\n );\n\n const handleDragMove = useCallback(\n (event: DragMoveEvent) => {\n // Keyboard moves are driven entirely by the arrow-key handler below; ignore\n // dnd-kit's (pointerless, therefore no-op) move events so they can't revert\n // a nudge back to the static activator cell.\n if (keyboardRef.current) return;\n const p = event.operation.position.current;\n const pointer = { x: p.x, y: p.y };\n const current = sessionRef.current;\n\n if (current?.kind === \"resize\") {\n const next = dragResize(current, pointer, ctx());\n setSessionBoth(next);\n propsRef.current.onResize?.(\n next.preview,\n next.anchor.item,\n next.placeholder,\n next.placeholder,\n event.operation.activatorEvent,\n null,\n );\n return;\n }\n\n const data = dragData(event);\n if (!data) {\n // External (non-grid) draggable: preview where it would land over us.\n const spec = dropSpecRef.current;\n if (spec && overMe(pointer)) {\n const foreign: LayoutItem = { i: spec.i, x: 0, y: 0, w: spec.w, h: spec.h };\n const committed = propsRef.current.layout;\n const cell = cellFromPointer(pointer, foreign) ?? { x: 0, y: 0 };\n setSessionBoth(beginReceive(committed, foreign, cell.x, cell.y, pointer, ctx()));\n } else if (sessionRef.current) {\n setSessionBoth(null);\n }\n return;\n }\n if (data.kind !== \"move\") return;\n const here = overMe(pointer);\n const ownsItem = committedByIdRef.current.has(data.itemId);\n\n if (ownsItem) {\n const source = current?.kind === \"move\" ? current : null;\n if (!source) return;\n let next: DragSession;\n if (here) {\n next = dragTo(source, pointer, ctx());\n } else {\n // Leaving this grid: keep the item in place and hide the placeholder\n // here; the floating overlay (body portal) tracks the pointer.\n next = {\n ...source,\n preview: source.committed as LayoutItem[],\n placeholder: null,\n };\n }\n setSessionBoth(next);\n // Position the floating tile. With `dragConfig.snapToGrid` it snaps onto\n // the target cell (the placeholder's pixel rect); otherwise it tracks the\n // pointer smoothly. (The placeholder always snaps either way.)\n const grab = registryRef.current.getGrabOffset();\n let oLeft = pointer.x - grab.x;\n let oTop = pointer.y - grab.y;\n if (propsRef.current.dragConfig?.snapToGrid && here && next.placeholder) {\n const rect = containerElRef.current?.getBoundingClientRect();\n if (rect) {\n const cell = calcGridItemPosition(\n ppRef.current,\n next.placeholder.x,\n next.placeholder.y,\n next.placeholder.w,\n next.placeholder.h,\n );\n oLeft = rect.left + cell.left;\n oTop = rect.top + cell.top;\n }\n }\n setOverlay((o) => (o ? { ...o, left: oLeft, top: oTop } : o));\n propsRef.current.onDrag?.(\n next.preview,\n next.anchor.item,\n next.placeholder,\n next.placeholder,\n event.operation.activatorEvent,\n null,\n );\n return;\n }\n\n // We don't own the item — maybe receive it.\n if (here) {\n const foreign = data.item;\n const committed = propsRef.current.layout;\n const cell = cellFromPointer(pointer, foreign) ?? { x: 0, y: 0 };\n setSessionBoth(beginReceive(committed, foreign, cell.x, cell.y, pointer, ctx()));\n } else if (sessionRef.current) {\n setSessionBoth(null); // pointer left; we're no longer receiving\n }\n },\n [setSessionBoth, overMe, cellFromPointer, ctx],\n );\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const current = sessionRef.current;\n const data = dragData(event);\n const p = event.operation.position.current;\n const myId = containerIdRef.current;\n // Keyboard drags are in-grid only (there is no pointer to land in another\n // grid), so a keyboard drop always commits to this grid.\n const dest = keyboardRef.current ? myId : registryRef.current.gridAt({ x: p.x, y: p.y });\n const ownsItem = data ? committedByIdRef.current.has(data.itemId) : false;\n setOverlay(null);\n registryRef.current.setGrabOffset(null);\n\n const native = event.nativeEvent ?? null;\n const p2 = propsRef.current;\n // Pure classification of what this drop means for THIS grid; the switch\n // below maps each action to its callbacks (see dragFlow.ts for the contract).\n const action = classifyDrop({\n kind: current?.kind ?? null,\n canceled: event.canceled,\n ownsItem,\n hasData: !!data,\n dest,\n myId,\n });\n\n switch (action) {\n case \"cancel-resize\":\n p2.onResizeStop?.(p2.layout, current?.anchor.item ?? null, null, null, native, null);\n break;\n case \"cancel-move\":\n p2.onDragStop?.(p2.layout, current?.anchor.item ?? null, null, null, native, null);\n break;\n case \"commit-resize\":\n if (current) {\n p2.onLayoutChange?.(commitLayout(current));\n p2.onResizeStop?.(\n current.preview,\n current.anchor.item,\n current.placeholder,\n current.placeholder,\n native,\n null,\n );\n }\n break;\n case \"commit-in-grid\":\n case \"remove-source\":\n case \"revert\": {\n // Source grid finishing its drag: all fire onDragStop, differing only in layout.\n if (action === \"commit-in-grid\" && current) {\n p2.onLayoutChange?.(commitLayout(current));\n } else if (action === \"remove-source\" && data) {\n const { compactor: c, cols } = ctx();\n p2.onLayoutChange?.(\n removeItemWithCompactor(p2.layout, data.itemId, { compactor: c, cols }),\n );\n } // \"revert\" → dropped outside any grid → no layout change.\n p2.onDragStop?.(\n current?.preview ?? p2.layout,\n current?.anchor.item ?? null,\n current?.placeholder ?? null,\n current?.placeholder ?? null,\n native,\n null,\n );\n break;\n }\n case \"commit-dest\":\n if (current) p2.onLayoutChange?.(commitLayout(current));\n break;\n case \"external-drop\":\n // Hand the synthesized item to onDrop so the consumer can add it.\n if (current) {\n const committed = commitLayout(current);\n const dropped = committed.find((it) => it.i === current.activeId);\n if (dropped) p2.onDrop?.(committed, dropped, native);\n }\n break;\n // \"noop\" → nothing to do.\n }\n dropSpecRef.current = null;\n keyboardRef.current = false;\n setSessionBoth(null);\n },\n [setSessionBoth, ctx],\n );\n\n // Keyboard dragging: while a keyboard-initiated move is active, arrow keys step\n // the tile one cell at a time and move the floating overlay to match. Enter /\n // Space (drop) and Escape (cancel) fall through to dnd-kit's KeyboardSensor.\n useEffect(() => {\n const STEP: Record<string, [number, number]> = {\n ArrowLeft: [-1, 0],\n ArrowRight: [1, 0],\n ArrowUp: [0, -1],\n ArrowDown: [0, 1],\n };\n const onKeyDown = (e: KeyboardEvent) => {\n if (!keyboardRef.current) return;\n const session = sessionRef.current;\n if (!session || session.kind !== \"move\") return;\n const step = STEP[e.key];\n if (!step) return; // Enter/Space/Escape → dnd-kit handles drop/cancel\n e.preventDefault();\n // Own the arrow: stop dnd-kit's KeyboardSensor (a document capture-phase\n // listener) from also moving — otherwise its internal operation position\n // drifts every keystroke. We run in capture on window, ahead of it.\n e.stopImmediatePropagation();\n const next = nudge(session, step[0], step[1], ctx());\n setSessionBoth(next);\n const cell = next.placeholder;\n const rect = containerElRef.current?.getBoundingClientRect();\n if (cell && rect) {\n const pos = calcGridItemPosition(ppRef.current, cell.x, cell.y, cell.w, cell.h);\n setOverlay((o) =>\n o\n ? {\n ...o,\n left: rect.left + pos.left,\n top: rect.top + pos.top,\n width: pos.width,\n height: pos.height,\n }\n : o,\n );\n }\n };\n window.addEventListener(\"keydown\", onKeyDown, true);\n return () => window.removeEventListener(\"keydown\", onKeyDown, true);\n }, [ctx, setSessionBoth]);\n\n // Stable handlers object: dnd-kit's monitor effect keys on the handlers\n // identity, so a fresh literal each render would tear down and re-add all\n // listeners on every render (i.e. every pointer move, for every grid).\n const monitorHandlers = useMemo(\n () => ({\n onDragStart: handleDragStart,\n onDragMove: handleDragMove,\n onDragEnd: handleDragEnd,\n }),\n [handleDragStart, handleDragMove, handleDragEnd],\n );\n useDragDropMonitor(monitorHandlers);\n\n const dragThreshold = props.dragConfig?.threshold ?? 3;\n const itemSensors = useMemo(\n () => buildItemSensors(dragThreshold, () => propsRef.current.dragConfig),\n [dragThreshold],\n );\n\n const renderedLayout: Layout = session ? session.preview : props.layout;\n const itemsById = useMemo(\n () => new Map<string, LayoutItem>(renderedLayout.map((it) => [it.i, it])),\n [renderedLayout],\n );\n\n const gridDraggable = props.isDraggable ?? true;\n const dragEnabled = props.dragConfig?.enabled ?? true;\n const isItemDraggable = useCallback(\n (id: string) => {\n const it = committedById.get(id);\n if (!it) return false;\n return gridDraggable && dragEnabled && (it.isDraggable ?? true) && !it.static;\n },\n [committedById, gridDraggable, dragEnabled],\n );\n\n const gridResizable = props.isResizable ?? true;\n const resizeEnabled = props.resizeConfig?.enabled ?? true;\n const isItemResizable = useCallback(\n (id: string) => {\n const it = committedById.get(id);\n if (!it) return false;\n return gridResizable && resizeEnabled && (it.isResizable ?? true) && !it.static;\n },\n [committedById, gridResizable, resizeEnabled],\n );\n const defaultHandles = props.resizeConfig?.handles;\n const resizeHandlesFor = useCallback(\n (id: string) => committedById.get(id)?.resizeHandles ?? defaultHandles ?? DEFAULT_HANDLES,\n [committedById, defaultHandles],\n );\n\n const runtime: GridRuntime = useMemo(\n () => ({\n containerId,\n width: props.width,\n autoSize: props.autoSize ?? true,\n gridConfig,\n positionParams,\n renderedLayout,\n itemsById,\n session,\n isItemDraggable,\n isItemResizable,\n resizeHandlesFor,\n itemSensors,\n setContainerElement,\n overlay,\n }),\n [\n containerId,\n props.width,\n props.autoSize,\n gridConfig,\n positionParams,\n renderedLayout,\n itemsById,\n session,\n isItemDraggable,\n isItemResizable,\n resizeHandlesFor,\n itemSensors,\n setContainerElement,\n overlay,\n ],\n );\n\n return <GridContext.Provider value={runtime}>{props.children}</GridContext.Provider>;\n}\n","import { DragDropProvider } from \"@dnd-kit/react\";\nimport { type ReactNode, useRef } from \"react\";\nimport { type GridRegistry, SnapGridGroupContext, createGridRegistry } from \"./grouping.js\";\n\nexport interface SnapGridGroupProps {\n children: ReactNode;\n}\n\n/**\n * Wrap multiple grids to let tiles be dragged **between** them. Provides one\n * shared dnd-kit `DragDropProvider` and a registry so each grid can tell which\n * grid the pointer is over.\n *\n * Item ids must be unique across all grids in a group (they share one manager).\n */\nexport function SnapGridGroup({ children }: SnapGridGroupProps): React.JSX.Element {\n const registryRef = useRef<GridRegistry | null>(null);\n if (!registryRef.current) registryRef.current = createGridRegistry();\n return (\n <DragDropProvider>\n <SnapGridGroupContext.Provider value={registryRef.current}>\n {children}\n </SnapGridGroupContext.Provider>\n </DragDropProvider>\n );\n}\n","import { useDroppable } from \"@dnd-kit/react\";\nimport { type GridConfig, bottom } from \"@snapgridjs/core\";\nimport { type CSSProperties, useCallback } from \"react\";\nimport { useGridRuntime } from \"../context.js\";\n\nexport interface GridContainerProps {\n /** Attach to your container element. */\n ref: (element: Element | null) => void;\n /** Positioning style (relative + width + auto-sized height). Spread onto your element. */\n style: CSSProperties;\n /** Present while a compatible draggable is over the grid. */\n \"data-drop-target\"?: true;\n}\n\nexport interface UseGridContainerResult {\n /** Spread onto your container element. */\n containerProps: GridContainerProps;\n /** True while a compatible draggable is over the grid. */\n isDropTarget: boolean;\n}\n\n/** Total container height in pixels for the given number of occupied rows. */\nfunction containerHeight(rows: number, grid: GridConfig): number {\n const padY = (grid.containerPadding ?? grid.margin)[1];\n if (rows <= 0) return padY * 2;\n return padY * 2 + rows * grid.rowHeight + (rows - 1) * grid.margin[1];\n}\n\n/**\n * Headless hook for the grid container. Registers the droppable surface (the\n * seam for cross-grid drops) and returns props (ref + sizing style) to spread\n * onto your own container element.\n */\nexport function useGridContainer(): UseGridContainerResult {\n const rt = useGridRuntime();\n const { ref, isDropTarget } = useDroppable({\n id: rt.containerId,\n type: \"grid\",\n accept: \"grid-item\",\n });\n\n // Merge dnd-kit's droppable ref with reporting the element to the provider\n // (used to map the pointer to a cell when receiving a tile from another grid).\n const setContainerElement = rt.setContainerElement;\n const setRef = useCallback(\n (element: Element | null) => {\n ref(element);\n setContainerElement(element);\n },\n [ref, setContainerElement],\n );\n\n const height = rt.autoSize\n ? containerHeight(bottom(rt.renderedLayout), rt.gridConfig)\n : undefined;\n\n return {\n containerProps: {\n ref: setRef,\n style: { position: \"relative\", width: rt.width, height },\n \"data-drop-target\": isDropTarget || undefined,\n },\n isDropTarget,\n };\n}\n","import { useDraggable } from \"@dnd-kit/react\";\nimport { type LayoutItem, calcGridItemPosition } from \"@snapgridjs/core\";\nimport type { CSSProperties } from \"react\";\nimport { useGridRuntime } from \"../context.js\";\nimport { NO_FEEDBACK } from \"./dndShared.js\";\n\nexport interface UseGridItemResult {\n /** Attach to the element that represents this grid item. */\n ref: (element: Element | null) => void;\n /** Positioning style to spread onto your element (left/top/size). */\n style: CSSProperties;\n /** True while this item is the active drag source. */\n isDragging: boolean;\n /** The item's current (possibly reflowed) layout entry. */\n item: LayoutItem | undefined;\n}\n\n// Animate the compositor-only `transform` (and the size, which only changes on\n// resize), never `left`/`top`. Animating `left`/`top` is a layout property —\n// reflow + repaint every frame for every tile that moves — which collapses large\n// grids to single-digit fps in WebKit/Safari. `translate()` stays on the GPU.\nconst REFLOW_TRANSITION = \"transform 150ms ease, width 150ms ease, height 150ms ease\";\n\n/**\n * Headless hook for a single grid item. Returns a ref, a positioning `style`,\n * and drag state — spread them onto whatever element you render. You own the\n * tag, className, content, and any cosmetic styling.\n */\nexport function useGridItem(id: string): UseGridItemResult {\n const rt = useGridRuntime();\n const item = rt.itemsById.get(id);\n const { ref, isDragging } = useDraggable({\n id,\n type: \"grid-item\",\n disabled: !rt.isItemDraggable(id),\n sensors: rt.itemSensors,\n plugins: NO_FEEDBACK,\n // Carry the full item so another grid can render/insert it on a cross-grid drop.\n data: { snapGrid: { kind: \"move\", itemId: id, item } },\n });\n const active = rt.session?.activeId === id;\n\n let style: CSSProperties = { position: \"absolute\", touchAction: \"none\" };\n if (item) {\n const pos = calcGridItemPosition(rt.positionParams, item.x, item.y, item.w, item.h);\n style = {\n position: \"absolute\",\n // Position via a GPU transform, not left/top — see REFLOW_TRANSITION. The\n // element is pinned at the origin and translated into its cell; size stays\n // as width/height (it only changes on resize, not on drag reflow).\n left: 0,\n top: 0,\n width: pos.width,\n height: pos.height,\n transform: `translate(${pos.left}px, ${pos.top}px)`,\n // While dragging, the floating preview is rendered in a body portal\n // (see GridDragOverlay), so the in-grid tile is hidden — it still holds\n // its (reflowed) cell. Non-active tiles animate their transform as they\n // reflow around it.\n visibility: active ? \"hidden\" : undefined,\n transition: active ? \"none\" : REFLOW_TRANSITION,\n touchAction: \"none\",\n };\n }\n\n return { ref, style, isDragging, item };\n}\n","import { type LayoutItem, calcGridItemPosition } from \"@snapgridjs/core\";\nimport type { CSSProperties } from \"react\";\nimport { useGridRuntime } from \"../context.js\";\n\nexport interface GridPlaceholderInfo {\n /** The layout entry marking where the dragged item will land. */\n item: LayoutItem;\n /** Positioning style (left/top/size) to spread onto your placeholder element. */\n style: CSSProperties;\n}\n\n/**\n * Headless hook returning where the drag placeholder should be rendered, or\n * `null` when no drag is in progress. You render the element however you like.\n */\nexport function useGridPlaceholder(): GridPlaceholderInfo | null {\n const rt = useGridRuntime();\n const placeholder = rt.session?.placeholder;\n if (!placeholder) return null;\n const pos = calcGridItemPosition(\n rt.positionParams,\n placeholder.x,\n placeholder.y,\n placeholder.w,\n placeholder.h,\n );\n const style: CSSProperties = {\n position: \"absolute\",\n // Transform-positioned to match grid items (see useGridItem) — the\n // placeholder slides as a GPU transform, not an animated left/top.\n left: 0,\n top: 0,\n width: pos.width,\n height: pos.height,\n transform: `translate(${pos.left}px, ${pos.top}px)`,\n pointerEvents: \"none\",\n };\n return { item: placeholder, style };\n}\n","import { useDraggable } from \"@dnd-kit/react\";\nimport type { ResizeHandleAxis } from \"@snapgridjs/core\";\nimport { useGridRuntime } from \"../context.js\";\nimport { NO_FEEDBACK, RESIZE_HANDLE_ATTR } from \"./dndShared.js\";\n\nexport interface UseGridResizeHandleResult {\n /** Attach to your resize-handle element. */\n ref: (element: Element | null) => void;\n /** Spread onto the handle element so item drags ignore pointer-downs on it. */\n handleProps: { [RESIZE_HANDLE_ATTR]: true };\n /** True while this item is actively being resized. */\n isResizing: boolean;\n}\n\n/**\n * Headless hook for a single resize handle. Model a handle as its own draggable;\n * dragging it resizes the item from the given edge/corner. Position and style\n * the handle however you like — spread `ref` and `handleProps` onto it.\n */\nexport function useGridResizeHandle(\n itemId: string,\n handle: ResizeHandleAxis,\n): UseGridResizeHandleResult {\n const rt = useGridRuntime();\n const { ref } = useDraggable({\n id: `${itemId}::resize::${handle}`,\n disabled: !rt.isItemResizable(itemId),\n plugins: NO_FEEDBACK,\n data: { snapGrid: { kind: \"resize\", itemId, handle } },\n });\n const isResizing = rt.session?.kind === \"resize\" && rt.session.activeId === itemId;\n return { ref, handleProps: { [RESIZE_HANDLE_ATTR]: true }, isResizing };\n}\n","import type { LayoutItem } from \"@snapgridjs/core\";\nimport type { CSSProperties } from \"react\";\nimport { useGridRuntime } from \"../context.js\";\n\nexport interface GridDragOverlay {\n /** The item being dragged from this grid. */\n item: LayoutItem;\n /** Fixed-position style for the floating preview; render it in a body portal. */\n style: CSSProperties;\n}\n\n/**\n * Headless hook for the floating drag preview. Returns `null` unless this grid\n * is the source of an in-progress drag. Render the returned `item` with `style`\n * in a portal at `document.body` so it can float across grids unclipped (see\n * {@link GridDragOverlay} for the convenience component).\n */\nexport function useGridDragOverlay(): GridDragOverlay | null {\n const rt = useGridRuntime();\n const o = rt.overlay;\n if (!o) return null;\n return {\n item: o.item,\n style: {\n position: \"fixed\",\n left: o.left,\n top: o.top,\n width: o.width,\n height: o.height,\n pointerEvents: \"none\",\n zIndex: 1000,\n },\n };\n}\n","import {\n type BreakpointCols,\n type Breakpoints,\n type Compactor,\n type Layout,\n type ResponsiveLayouts,\n findOrGenerateResponsiveLayout,\n getBreakpointFromWidth,\n getColsFromBreakpoint,\n verticalCompactor,\n} from \"@snapgridjs/core\";\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\n\n/** react-grid-layout's default breakpoints (px) and column counts. */\nexport const DEFAULT_BREAKPOINTS: Breakpoints = { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 };\nexport const DEFAULT_BREAKPOINT_COLS: BreakpointCols = { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 };\n\nexport interface UseResponsiveLayoutOptions {\n /** Current container width in pixels. */\n width: number;\n /** Controlled per-breakpoint layouts. Missing breakpoints are generated from the nearest one. */\n layouts: ResponsiveLayouts;\n /** Breakpoint → min width (px). @default lg/md/sm/xs/xxs */\n breakpoints?: Breakpoints;\n /** Breakpoint → column count. @default 12/10/6/4/2 */\n cols?: BreakpointCols;\n /** Compaction strategy used when generating a missing breakpoint's layout. */\n compactor?: Compactor;\n /** Called when a layout commits: the active layout and the updated map. */\n onLayoutChange?: (layout: Layout, layouts: ResponsiveLayouts) => void;\n /** Called when the active breakpoint changes. */\n onBreakpointChange?: (breakpoint: string, cols: number) => void;\n}\n\nexport interface UseResponsiveLayoutResult {\n /** The active breakpoint name. */\n breakpoint: string;\n /** Column count for the active breakpoint. */\n cols: number;\n /** The resolved layout for the active breakpoint (generated if absent). */\n layout: Layout;\n /** Pass to the grid's `onLayoutChange`; updates the active breakpoint's layout. */\n onLayoutChange: (layout: Layout) => void;\n}\n\n/**\n * Headless responsive layout engine: resolves the active breakpoint and its\n * column count/layout from the container width, generating a layout for the\n * active breakpoint from the nearest one when missing.\n */\nexport function useResponsiveLayout(\n options: UseResponsiveLayoutOptions,\n): UseResponsiveLayoutResult {\n const {\n width,\n layouts,\n breakpoints = DEFAULT_BREAKPOINTS,\n cols = DEFAULT_BREAKPOINT_COLS,\n compactor = verticalCompactor,\n onLayoutChange,\n onBreakpointChange,\n } = options;\n\n const breakpoint = getBreakpointFromWidth(breakpoints, width);\n const colCount = getColsFromBreakpoint(breakpoint, cols);\n\n // Memoized so the clone + compact over every item only runs when an input\n // actually changes (not on every render/width tick). The fallback source for\n // generating a missing breakpoint — used by findOrGenerateResponsiveLayout\n // only when no provided breakpoint sits at/above the target — is the widest\n // provided layout. Derived purely from inputs (no ref mutated in an effect),\n // so generation is a pure function of render inputs (StrictMode/concurrent\n // safe) and no longer depends on the order breakpoints were visited.\n const layout = useMemo(() => {\n let source = breakpoint;\n let sourceWidth = Number.NEGATIVE_INFINITY;\n for (const [bp, minWidth] of Object.entries(breakpoints)) {\n if (layouts[bp] && minWidth > sourceWidth) {\n sourceWidth = minWidth;\n source = bp;\n }\n }\n return findOrGenerateResponsiveLayout(\n layouts,\n breakpoints,\n breakpoint,\n source,\n colCount,\n compactor,\n );\n }, [layouts, breakpoints, breakpoint, colCount, compactor]);\n\n // Fire onBreakpointChange when the active breakpoint actually changes. This ref\n // is written only inside the effect (never read during render), so render stays pure.\n const onBreakpointChangeRef = useRef(onBreakpointChange);\n onBreakpointChangeRef.current = onBreakpointChange;\n const firedBreakpointRef = useRef(breakpoint);\n useEffect(() => {\n if (firedBreakpointRef.current !== breakpoint) {\n firedBreakpointRef.current = breakpoint;\n onBreakpointChangeRef.current?.(breakpoint, colCount);\n }\n }, [breakpoint, colCount]);\n\n const handleLayoutChange = useCallback(\n (next: Layout) => {\n onLayoutChange?.(next, { ...layouts, [breakpoint]: next });\n },\n [onLayoutChange, layouts, breakpoint],\n );\n\n return { breakpoint, cols: colCount, layout, onLayoutChange: handleLayoutChange };\n}\n","import type { LayoutItem } from \"@snapgridjs/core\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useGridDragOverlay } from \"./hooks/useGridDragOverlay.js\";\n\nexport interface GridDragOverlayProps {\n /** Render the floating preview for the dragged item. */\n children: (item: LayoutItem) => ReactNode;\n /** Appended to the default `snapgrid-overlay` class on the portal element. */\n className?: string;\n /** Merged over the positioning style. */\n style?: CSSProperties;\n}\n\n/**\n * Renders the floating drag preview in a portal at `document.body` — so it\n * follows the pointer across grids without being clipped by any container.\n * Renders nothing when this grid isn't the drag source.\n */\nexport function GridDragOverlay({ children, className, style }: GridDragOverlayProps) {\n const overlay = useGridDragOverlay();\n if (typeof document === \"undefined\" || !overlay) return null;\n return createPortal(\n <div\n className={className ? `snapgrid-overlay ${className}` : \"snapgrid-overlay\"}\n style={style ? { ...overlay.style, ...style } : overlay.style}\n >\n {children(overlay.item)}\n </div>,\n document.body,\n );\n}\n","import type { ResizeHandleAxis } from \"@snapgridjs/core\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { useGridRuntime } from \"./context.js\";\nimport { useGridItem } from \"./hooks/useGridItem.js\";\nimport { useGridResizeHandle } from \"./hooks/useGridResizeHandle.js\";\n\nexport interface GridItemProps {\n /** Matches the layout item's `i`. */\n id: string;\n children: ReactNode;\n /** Appended to the default `snapgrid-item` class. */\n className?: string;\n /** Merged over (and able to override) the positioning style. */\n style?: CSSProperties;\n}\n\nconst HANDLE_CURSOR: Record<ResizeHandleAxis, string> = {\n n: \"ns-resize\",\n s: \"ns-resize\",\n e: \"ew-resize\",\n w: \"ew-resize\",\n se: \"nwse-resize\",\n nw: \"nwse-resize\",\n ne: \"nesw-resize\",\n sw: \"nesw-resize\",\n};\n\nconst SIDE = 14;\nfunction handleStyle(handle: ResizeHandleAxis): CSSProperties {\n const s: CSSProperties = {\n position: \"absolute\",\n width: SIDE,\n height: SIDE,\n cursor: HANDLE_CURSOR[handle],\n touchAction: \"none\",\n zIndex: 4,\n };\n if (handle.includes(\"n\")) s.top = -SIDE / 2;\n if (handle.includes(\"s\")) s.bottom = -SIDE / 2;\n if (handle.includes(\"e\")) s.right = -SIDE / 2;\n if (handle.includes(\"w\")) s.left = -SIDE / 2;\n if (handle === \"n\" || handle === \"s\") {\n s.left = `calc(50% - ${SIDE / 2}px)`;\n }\n if (handle === \"e\" || handle === \"w\") {\n s.top = `calc(50% - ${SIDE / 2}px)`;\n }\n return s;\n}\n\nfunction DefaultResizeHandle({ itemId, handle }: { itemId: string; handle: ResizeHandleAxis }) {\n const { ref, handleProps } = useGridResizeHandle(itemId, handle);\n return (\n <span\n ref={ref}\n {...handleProps}\n className={`snapgrid-resize-handle snapgrid-resize-handle--${handle}`}\n style={handleStyle(handle)}\n />\n );\n}\n\n/**\n * Convenience wrapper over {@link useGridItem}: an absolutely-positioned `<div>`\n * with stable hooks (`.snapgrid-item`, `data-grid-id`, `data-dragging`) and the\n * configured resize handles. For full control, use the hooks directly.\n */\nexport function GridItem({ id, children, className, style }: GridItemProps) {\n const rt = useGridRuntime();\n const { ref, style: positionStyle, isDragging } = useGridItem(id);\n const handles = rt.isItemResizable(id) ? rt.resizeHandlesFor(id) : [];\n return (\n <div\n ref={ref}\n data-grid-id={id}\n data-dragging={isDragging || undefined}\n className={className ? `snapgrid-item ${className}` : \"snapgrid-item\"}\n style={style ? { ...positionStyle, ...style } : positionStyle}\n >\n {children}\n {handles.map((handle) => (\n <DefaultResizeHandle key={handle} itemId={id} handle={handle} />\n ))}\n </div>\n );\n}\n","import type { CSSProperties } from \"react\";\nimport { useGridPlaceholder } from \"./hooks/useGridPlaceholder.js\";\n\nexport interface GridPlaceholderProps {\n /** Appended to the default `snapgrid-placeholder` class. */\n className?: string;\n /** Merged over (and able to override) the default look. */\n style?: CSSProperties;\n}\n\nconst DEFAULT_LOOK: CSSProperties = {\n background: \"rgba(99, 102, 241, 0.2)\",\n border: \"1px dashed rgba(99, 102, 241, 0.6)\",\n borderRadius: 4,\n boxSizing: \"border-box\",\n zIndex: 2,\n transition: \"transform 150ms ease, width 150ms ease, height 150ms ease\",\n};\n\n/**\n * Convenience placeholder rendered from {@link useGridPlaceholder}. Renders\n * nothing when no drag is active. For a custom placeholder, call the hook\n * directly and render your own element with the returned `style`.\n */\nexport function GridPlaceholder({ className, style }: GridPlaceholderProps) {\n const placeholder = useGridPlaceholder();\n if (!placeholder) return null;\n return (\n <div\n aria-hidden=\"true\"\n className={className ? `snapgrid-placeholder ${className}` : \"snapgrid-placeholder\"}\n style={{ ...placeholder.style, ...DEFAULT_LOOK, ...style }}\n />\n );\n}\n","import {\n type CSSProperties,\n Children,\n type ReactElement,\n type ReactNode,\n isValidElement,\n} from \"react\";\nimport { GridDragOverlay } from \"./GridDragOverlay.js\";\nimport { GridItem } from \"./GridItem.js\";\nimport { GridPlaceholder } from \"./GridPlaceholder.js\";\nimport { SnapGridProvider, type SnapGridProviderProps } from \"./SnapGridProvider.js\";\nimport { useGridContainer } from \"./hooks/useGridContainer.js\";\n\nexport interface GridLayoutProps extends SnapGridProviderProps {\n /** Appended to the default `snapgrid` class on the surface. */\n className?: string;\n /** Merged over (and able to override) the surface's positioning style. */\n style?: CSSProperties;\n}\n\n/** Strip the namespacing prefix React applies to keys inside `Children.map`. */\nfunction keyToId(key: string): string {\n return key.startsWith(\".$\") ? key.slice(2) : key;\n}\n\n/** The default surface: positioned container + mapped items + placeholder. */\nfunction GridSurface({\n className,\n style,\n children,\n}: {\n className?: string;\n style?: CSSProperties;\n children: ReactNode;\n}) {\n const { containerProps } = useGridContainer();\n // Map item id -> child so the drag overlay can render the dragged tile's content.\n const childById = new Map<string, ReactElement>();\n Children.forEach(children, (child) => {\n if (isValidElement(child) && child.key != null) {\n childById.set(keyToId(String(child.key)), child);\n }\n });\n return (\n <div\n {...containerProps}\n className={className ? `snapgrid ${className}` : \"snapgrid\"}\n style={style ? { ...containerProps.style, ...style } : containerProps.style}\n >\n {Children.map(children, (child) => {\n if (!isValidElement(child) || child.key == null) return child;\n return (\n <GridItem key={child.key} id={keyToId(String(child.key))}>\n {child}\n </GridItem>\n );\n })}\n <GridPlaceholder />\n <GridDragOverlay>{(item) => childById.get(item.i) ?? null}</GridDragOverlay>\n </div>\n );\n}\n\n/**\n * Drop-in grid component: a controlled, react-grid-layout v2-compatible layout\n * backed by dnd-kit. A thin shell over {@link SnapGridProvider} and the headless\n * hooks — children are keyed by their layout item's `i`. For full control over\n * markup/styling, use the provider + hooks directly.\n */\nexport function GridLayout(props: GridLayoutProps): React.JSX.Element {\n const { className, style, children, ...providerProps } = props;\n return (\n <SnapGridProvider {...providerProps}>\n <GridSurface className={className} style={style}>\n {children}\n </GridSurface>\n </SnapGridProvider>\n );\n}\n","import type {\n BreakpointCols,\n Breakpoints,\n Compactor,\n Layout,\n ResponsiveLayouts,\n} from \"@snapgridjs/core\";\nimport { type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { GridLayout } from \"./GridLayout.js\";\nimport { useResponsiveLayout } from \"./hooks/useResponsiveLayout.js\";\nimport type { DragConfig, ResizeConfig } from \"./types.js\";\n\nexport interface ResponsiveGridLayoutProps {\n /** Container width in pixels (e.g. from {@link useContainerWidth}). */\n width: number;\n /** Controlled per-breakpoint layouts. Children are keyed by item `i`. */\n layouts: ResponsiveLayouts;\n /** Called when a layout commits: the active layout and the updated map. */\n onLayoutChange?: (layout: Layout, layouts: ResponsiveLayouts) => void;\n /** Called when the active breakpoint changes. */\n onBreakpointChange?: (breakpoint: string, cols: number) => void;\n /** Breakpoint → min width (px). @default lg/md/sm/xs/xxs */\n breakpoints?: Breakpoints;\n /** Breakpoint → column count. @default 12/10/6/4/2 */\n cols?: BreakpointCols;\n rowHeight?: number;\n margin?: [number, number];\n containerPadding?: [number, number] | null;\n compactor?: Compactor;\n dragConfig?: DragConfig;\n resizeConfig?: ResizeConfig;\n isDraggable?: boolean;\n isResizable?: boolean;\n autoSize?: boolean;\n className?: string;\n style?: CSSProperties;\n children: ReactNode;\n}\n\n/**\n * A responsive grid: switches column count and layout by breakpoint as `width`\n * changes, generating a breakpoint's layout from the nearest one when absent.\n * A thin wrapper over {@link useResponsiveLayout} + {@link GridLayout}; mirrors\n * react-grid-layout v2's `ResponsiveGridLayout`.\n */\nexport function ResponsiveGridLayout(props: ResponsiveGridLayoutProps): React.JSX.Element {\n const { cols, layout, onLayoutChange } = useResponsiveLayout({\n width: props.width,\n layouts: props.layouts,\n breakpoints: props.breakpoints,\n cols: props.cols,\n compactor: props.compactor,\n onLayoutChange: props.onLayoutChange,\n onBreakpointChange: props.onBreakpointChange,\n });\n\n // Stable object identity so SnapGridProvider's gridConfig/positionParams memos\n // aren't busted on every render (e.g. each width tick).\n const gridConfig = useMemo(\n () => ({\n cols,\n rowHeight: props.rowHeight ?? 150,\n margin: props.margin ?? ([10, 10] as [number, number]),\n containerPadding: props.containerPadding ?? null,\n }),\n [cols, props.rowHeight, props.margin, props.containerPadding],\n );\n\n return (\n // No explicit `id`: a stable per-instance id (useId, inside SnapGridProvider)\n // avoids droppable/registry identity churn when the breakpoint changes and\n // keeps two responsive grids in a group from colliding on the same id.\n <GridLayout\n layout={layout}\n width={props.width}\n onLayoutChange={onLayoutChange}\n gridConfig={gridConfig}\n compactor={props.compactor}\n dragConfig={props.dragConfig}\n resizeConfig={props.resizeConfig}\n isDraggable={props.isDraggable}\n isResizable={props.isResizable}\n autoSize={props.autoSize}\n className={props.className}\n style={props.style}\n >\n {props.children}\n </GridLayout>\n );\n}\n","import { useCallback, useEffect, useLayoutEffect, useState } from \"react\";\n\n// useLayoutEffect warns when run on the server; fall back to useEffect there so\n// the hook is SSR-safe (Next.js / Remix). The initial `width` is `initialWidth`\n// on both server and client, so the first render matches and there's no\n// hydration mismatch — the measured width is applied right after mount.\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\nexport interface UseContainerWidthOptions {\n /** Width to use until the element has been measured. @default 1280 */\n initialWidth?: number;\n}\n\nexport interface UseContainerWidthResult {\n /** Measured container width in pixels (or `initialWidth` before mount). */\n width: number;\n /** Whether the element has been measured at least once. */\n mounted: boolean;\n /** Attach to the element whose width should drive the grid. */\n containerRef: (element: HTMLElement | null) => void;\n}\n\n/**\n * Measure a container's width with a `ResizeObserver`. Replaces react-grid-layout's\n * `WidthProvider` HOC with a hook, mirroring RGL v2's `useContainerWidth`.\n */\nexport function useContainerWidth(options: UseContainerWidthOptions = {}): UseContainerWidthResult {\n const { initialWidth = 1280 } = options;\n const [width, setWidth] = useState(initialWidth);\n const [mounted, setMounted] = useState(false);\n // Track the element in state so the observer effect re-runs when it changes;\n // this is StrictMode-safe (the effect's cleanup disconnects the observer).\n const [element, setElement] = useState<HTMLElement | null>(null);\n const containerRef = useCallback((node: HTMLElement | null) => setElement(node), []);\n\n useIsomorphicLayoutEffect(() => {\n if (!element || typeof ResizeObserver === \"undefined\") return;\n const measure = () => {\n const next = element.getBoundingClientRect().width;\n if (next > 0) {\n setWidth(next);\n setMounted(true);\n }\n };\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [element]);\n\n return { width, mounted, containerRef };\n}\n"],"mappings":";;;;;;;AAgEA,MAAa,cAAc,cAAkC,IAAI;;AAGjE,SAAgB,iBAA8B;CAC5C,MAAM,UAAU,WAAW,WAAW;CACtC,IAAI,CAAC,SACH,MAAM,IAAI,MACR,gGACF;CAEF,OAAO;AACT;;;;;;;;;;;;;;;AC5DA,SAAgB,YACd,SACA,UACA,YACA,GACA,GACA,IAC0B;CAC1B,OAAO,OACL,IACA,QAAQ,IAAI,WAAW,IAAI,SAAS,KACpC,QAAQ,IAAI,WAAW,IAAI,SAAS,MACpC,GACA,CACF;AACF;;AAuCA,SAAgB,aAAa,GAA0B;CACrD,IAAI,EAAE,UAAU;EACd,IAAI,EAAE,SAAS,UAAU,OAAO;EAChC,IAAI,EAAE,UAAU,OAAO;EACvB,OAAO;CACT;CACA,IAAI,EAAE,SAAS,UAAU,OAAO;CAEhC,IAAI,EAAE,YAAY,EAAE,SAAS;EAC3B,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,QAAQ,OAAO;EACnD,IAAI,EAAE,MAAM,OAAO;EACnB,OAAO;CACT;CAGA,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,QAClC,OAAO,EAAE,UAAU,gBAAgB;CAErC,OAAO;AACT;;;ACjEA,SAAgB,qBAAmC;CACjD,MAAM,wBAAQ,IAAI,IAAkC;CACpD,IAAI,aAA8C;CAClD,OAAO;EACL,SAAS,IAAI,SAAS;GACpB,MAAM,IAAI,IAAI,OAAO;GACrB,aAAa;IACX,IAAI,MAAM,IAAI,EAAE,MAAM,SAAS,MAAM,OAAO,EAAE;GAChD;EACF;EACA,OAAO,OAAO;GACZ,KAAK,MAAM,CAAC,IAAI,YAAY,OAAO;IACjC,MAAM,IAAI,QAAQ;IAClB,IACE,KACA,MAAM,KAAK,EAAE,QACb,MAAM,KAAK,EAAE,SACb,MAAM,KAAK,EAAE,OACb,MAAM,KAAK,EAAE,QAEb,OAAO;GAEX;GACA,OAAO;EACT;EACA,cAAc,QAAQ;GACpB,aAAa;EACf;EACA,gBAAgB;GACd,OAAO,cAAc;IAAE,GAAG;IAAG,GAAG;GAAE;EACpC;CACF;AACF;;AAGA,MAAa,uBAAuB,cAAmC,IAAI;;;;AChD3E,MAAa,qBAAqB;AAMlC,MAAa,cAAc,CAACA,WAAS,UAAU,EAAE,UAAU,OAAO,CAAC,CAAC;;;;;;;;AASpE,SAAgB,sBACd,QACA,KACS;CACT,IAAI,EAAE,kBAAkB,UAAU,OAAO;CACzC,IAAI,OAAO,QAAQ,+BAAyB,GAAG,OAAO;CACtD,IAAI,KAAK,UAAU,OAAO,QAAQ,IAAI,MAAM,GAAG,OAAO;CACtD,IAAI,KAAK,UAAU,CAAC,OAAO,QAAQ,IAAI,MAAM,GAAG,OAAO;CACvD,OAAO;AACT;;;;;;AAOA,SAAgB,iBACd,WACA,eACS;CACT,OAAO,CACLC,gBAAc,UAAU;EACtB,6BACE,YAAY,IACR,CAAC,IAAI,6BAA6B,SAAS,EAAE,OAAO,UAAU,CAAC,CAAC,IAChE,KAAA;EACN,oBAAoB,UAClB,sBAAsB,MAAM,QAAQ,cAAc,CAAC;CACvD,CAAC,GACDC,gBACF;AACF;;;ACPA,MAAM,kBAAkB,CAAC,IAAI;;AAK7B,SAAS,SAAS,OAEe;CAE/B,QADa,MAAM,UAAU,QAAQ,OACxB;AACf;;AAGA,SAAgB,iBACd,QACA,YAC6C;CAC7C,IAAI,CAAC,YAAY,WAAW,CAAC,QAAQ,OAAO;CAC5C,MAAM,OAAO,OAAO;CACpB,IAAI,MAAM,UAAU,OAAO;CAC3B,IAAI,WAAW,UAAU,CAAC,WAAW,OAAO,MAAM,GAAG,OAAO;CAC5D,MAAM,OAAO,MAAM;CACnB,OAAO;EACL,GAAG,MAAM;EAET,GAAG,MAAM,KAAK,WAAW,aAAa,KAAK;EAC3C,GAAG,MAAM,KAAK,WAAW,aAAa,KAAK;CAC7C;AACF;;;;;;;AAwCA,SAAgB,iBAAiB,OAAiD;CAChF,MAAM,gBAAgB,WAAW,oBAAoB;CACrD,MAAM,UAAU,oBAAC,iBAAD;EAAgC;EAAe,GAAI;CAAQ,CAAA;CAG3E,OAAO,gBAAgB,UAAU,oBAAC,kBAAD,EAAA,UAAmB,QAA0B,CAAA;AAChF;AAIA,SAAS,gBAAgB,OAAwC;CAC/D,MAAM,SAAS,MAAM;CACrB,MAAM,cAAc,MAAM,MAAM;CAEhC,MAAM,aAAyB,eACtB;EAAE,GAAG;EAAmB,GAAG,MAAM;CAAW,IACnD,CAAC,MAAM,UAAU,CACnB;CACA,MAAM,iBAAiC,cAC/B,iBAAiB,YAAY,MAAM,KAAK,GAC9C,CAAC,YAAY,MAAM,KAAK,CAC1B;CACA,MAAM,YAAuB,MAAM,aAAaC;CAEhD,MAAM,CAAC,SAAS,cAAc,SAA6B,IAAI;CAE/D,MAAM,CAAC,SAAS,cAAc,SAAiC,IAAI;CAGnE,MAAM,WAAW,OAAO,KAAK;CAC7B,SAAS,UAAU;CACnB,MAAM,QAAQ,OAAO,cAAc;CACnC,MAAM,UAAU;CAChB,MAAM,UAAU,OAAO,UAAU;CACjC,QAAQ,UAAU;CAClB,MAAM,eAAe,OAAO,SAAS;CACrC,aAAa,UAAU;CACvB,MAAM,iBAAiB,OAAO,WAAW;CACzC,eAAe,UAAU;CACzB,MAAM,aAAa,OAA2B,IAAI;CAClD,MAAM,iBAAiB,OAAuB,IAAI;CAGlD,MAAM,cAAc,OAAO,KAAK;CAGhC,MAAM,cAAc,OAAmD,IAAI;CAC3E,MAAM,iBAAiB,OAAO,CAAC;CAK/B,MAAM,mBAAmB,OAA4B,IAAI;CACzD,IAAI,CAAC,iBAAiB,SAAS,iBAAiB,UAAU,mBAAmB;CAC7E,MAAM,WAAW,MAAM,iBAAiB,iBAAiB;CACzD,MAAM,cAAc,OAAO,QAAQ;CACnC,YAAY,UAAU;CAEtB,gBAEI,SAAS,SAAS,mBAAmB,eAAe,SAAS,sBAAsB,KAAK,IAAI,GAC9F,CAAC,UAAU,WAAW,CACxB;CAEA,MAAM,gBAAgB,cACd,IAAI,IAAwB,MAAM,OAAO,KAAK,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GACtE,CAAC,MAAM,MAAM,CACf;CACA,MAAM,mBAAmB,OAAO,aAAa;CAC7C,iBAAiB,UAAU;CAE3B,MAAM,iBAAiB,aAAa,SAA6B;EAC/D,WAAW,UAAU;EACrB,WAAW,IAAI;CACjB,GAAG,CAAC,CAAC;CAEL,MAAM,sBAAsB,aAAa,YAA4B;EACnE,eAAe,UAAU;CAC3B,GAAG,CAAC,CAAC;;;;;;;CAQL,MAAM,SAAS,aACZ,MAAa,YAAY,QAAQ,OAAO,CAAC,MAAM,eAAe,SAC/D,CAAC,CACH;;CAGA,MAAM,kBAAkB,aAAa,GAAU,SAAqB;EAClE,MAAM,KAAK,eAAe;EAC1B,IAAI,CAAC,IAAI,OAAO;EAEhB,OAAO,YAAY,GADN,GAAG,sBACS,GAAG,YAAY,QAAQ,cAAc,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,OAAO;CAChG,GAAG,CAAC,CAAC;CAEL,MAAM,MAAM,mBACH;EACL,gBAAgB,MAAM;EACtB,WAAW,aAAa;EACxB,MAAM,QAAQ,QAAQ;CACxB,IACA,CAAC,CACH;CAEA,MAAM,kBAAkB,aACrB,UAA0B;EAGzB,YAAY,UAAU;EACtB,MAAM,OAAO,SAAS,KAAK;EAC3B,IAAI,CAAC,MAAM;GAGT,MAAM,OAAO,iBAAiB,MAAM,UAAU,QAAQ,SAAS,QAAQ,UAAU;GACjF,IAAI,MAAM;IACR,eAAe,WAAW;IAC1B,YAAY,UAAU;KAGpB,GAAG,KAAK,KAAK,GAAG,eAAe,QAAQ,WAAW,eAAe;KACjE,GAAG,KAAK;KACR,GAAG,KAAK;IACV;GACF,OACE,YAAY,UAAU;GAExB;EACF;EACA,YAAY,UAAU;EACtB,MAAM,SAAS,SAAS,QAAQ;EAChC,MAAM,OAAO,OAAO,MAAM,OAAO,GAAG,MAAM,KAAK,MAAM;EACrD,MAAM,IAAI,MAAM,UAAU,SAAS;EACnC,MAAM,UAAU;GAAE,GAAG,EAAE;GAAG,GAAG,EAAE;EAAE;EACjC,IAAI,KAAK,SAAS,UAAU;GAC1B,IAAI,CAAC,MAAM;GAEX,eAAe,YAAY,QAAQ;IAAE;IAAM,MAD9B,qBAAqB,MAAM,SAAS,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAChC;IAAG;GAAQ,GAAG,KAAK,MAAM,CAAC;GACxE,SAAS,QAAQ,gBACf,QACA,MACA,MACA,MACA,MAAM,UAAU,gBAChB,IACF;GACA;EACF;EACA,IAAI,MAAM;GAER,YAAY,UAAU,MAAM,UAAU,0BAA0B;GAChE,MAAM,OAAO,qBAAqB,MAAM,SAAS,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;GAC/E,eAAe,UAAU,QAAQ;IAAE;IAAM,MAAM,KAAK;IAAM,KAAK,KAAK;IAAK;GAAQ,CAAC,CAAC;GAInF,MAAM,MADM,MAAM,UAAU,QAAyC,UACtD,sBAAsB;GACrC,IAAI,IAAI;IAIN,YAAY,QAAQ,cAAc;KAAE,GAAG,QAAQ,IAAI,GAAG;KAAM,GAAG,QAAQ,IAAI,GAAG;IAAI,CAAC;IACnF,WAAW;KAAE;KAAM,MAAM,GAAG;KAAM,KAAK,GAAG;KAAK,OAAO,GAAG;KAAO,QAAQ,GAAG;IAAO,CAAC;GACrF;GACA,SAAS,QAAQ,cACf,QACA,MACA,MACA,MACA,MAAM,UAAU,gBAChB,IACF;EACF;CAEF,GACA,CAAC,cAAc,CACjB;CAEA,MAAM,iBAAiB,aACpB,UAAyB;EAIxB,IAAI,YAAY,SAAS;EACzB,MAAM,IAAI,MAAM,UAAU,SAAS;EACnC,MAAM,UAAU;GAAE,GAAG,EAAE;GAAG,GAAG,EAAE;EAAE;EACjC,MAAM,UAAU,WAAW;EAE3B,IAAI,SAAS,SAAS,UAAU;GAC9B,MAAM,OAAO,WAAW,SAAS,SAAS,IAAI,CAAC;GAC/C,eAAe,IAAI;GACnB,SAAS,QAAQ,WACf,KAAK,SACL,KAAK,OAAO,MACZ,KAAK,aACL,KAAK,aACL,MAAM,UAAU,gBAChB,IACF;GACA;EACF;EAEA,MAAM,OAAO,SAAS,KAAK;EAC3B,IAAI,CAAC,MAAM;GAET,MAAM,OAAO,YAAY;GACzB,IAAI,QAAQ,OAAO,OAAO,GAAG;IAC3B,MAAM,UAAsB;KAAE,GAAG,KAAK;KAAG,GAAG;KAAG,GAAG;KAAG,GAAG,KAAK;KAAG,GAAG,KAAK;IAAE;IAC1E,MAAM,YAAY,SAAS,QAAQ;IACnC,MAAM,OAAO,gBAAgB,SAAS,OAAO,KAAK;KAAE,GAAG;KAAG,GAAG;IAAE;IAC/D,eAAe,aAAa,WAAW,SAAS,KAAK,GAAG,KAAK,GAAG,SAAS,IAAI,CAAC,CAAC;GACjF,OAAO,IAAI,WAAW,SACpB,eAAe,IAAI;GAErB;EACF;EACA,IAAI,KAAK,SAAS,QAAQ;EAC1B,MAAM,OAAO,OAAO,OAAO;EAG3B,IAFiB,iBAAiB,QAAQ,IAAI,KAAK,MAExC,GAAG;GACZ,MAAM,SAAS,SAAS,SAAS,SAAS,UAAU;GACpD,IAAI,CAAC,QAAQ;GACb,IAAI;GACJ,IAAI,MACF,OAAO,OAAO,QAAQ,SAAS,IAAI,CAAC;QAIpC,OAAO;IACL,GAAG;IACH,SAAS,OAAO;IAChB,aAAa;GACf;GAEF,eAAe,IAAI;GAInB,MAAM,OAAO,YAAY,QAAQ,cAAc;GAC/C,IAAI,QAAQ,QAAQ,IAAI,KAAK;GAC7B,IAAI,OAAO,QAAQ,IAAI,KAAK;GAC5B,IAAI,SAAS,QAAQ,YAAY,cAAc,QAAQ,KAAK,aAAa;IACvE,MAAM,OAAO,eAAe,SAAS,sBAAsB;IAC3D,IAAI,MAAM;KACR,MAAM,OAAO,qBACX,MAAM,SACN,KAAK,YAAY,GACjB,KAAK,YAAY,GACjB,KAAK,YAAY,GACjB,KAAK,YAAY,CACnB;KACA,QAAQ,KAAK,OAAO,KAAK;KACzB,OAAO,KAAK,MAAM,KAAK;IACzB;GACF;GACA,YAAY,MAAO,IAAI;IAAE,GAAG;IAAG,MAAM;IAAO,KAAK;GAAK,IAAI,CAAE;GAC5D,SAAS,QAAQ,SACf,KAAK,SACL,KAAK,OAAO,MACZ,KAAK,aACL,KAAK,aACL,MAAM,UAAU,gBAChB,IACF;GACA;EACF;EAGA,IAAI,MAAM;GACR,MAAM,UAAU,KAAK;GACrB,MAAM,YAAY,SAAS,QAAQ;GACnC,MAAM,OAAO,gBAAgB,SAAS,OAAO,KAAK;IAAE,GAAG;IAAG,GAAG;GAAE;GAC/D,eAAe,aAAa,WAAW,SAAS,KAAK,GAAG,KAAK,GAAG,SAAS,IAAI,CAAC,CAAC;EACjF,OAAO,IAAI,WAAW,SACpB,eAAe,IAAI;CAEvB,GACA;EAAC;EAAgB;EAAQ;EAAiB;CAAG,CAC/C;CAEA,MAAM,gBAAgB,aACnB,UAAwB;EACvB,MAAM,UAAU,WAAW;EAC3B,MAAM,OAAO,SAAS,KAAK;EAC3B,MAAM,IAAI,MAAM,UAAU,SAAS;EACnC,MAAM,OAAO,eAAe;EAG5B,MAAM,OAAO,YAAY,UAAU,OAAO,YAAY,QAAQ,OAAO;GAAE,GAAG,EAAE;GAAG,GAAG,EAAE;EAAE,CAAC;EACvF,MAAM,WAAW,OAAO,iBAAiB,QAAQ,IAAI,KAAK,MAAM,IAAI;EACpE,WAAW,IAAI;EACf,YAAY,QAAQ,cAAc,IAAI;EAEtC,MAAM,SAAS,MAAM,eAAe;EACpC,MAAM,KAAK,SAAS;EAGpB,MAAM,SAAS,aAAa;GAC1B,MAAM,SAAS,QAAQ;GACvB,UAAU,MAAM;GAChB;GACA,SAAS,CAAC,CAAC;GACX;GACA;EACF,CAAC;EAED,QAAQ,QAAR;GACE,KAAK;IACH,GAAG,eAAe,GAAG,QAAQ,SAAS,OAAO,QAAQ,MAAM,MAAM,MAAM,QAAQ,IAAI;IACnF;GACF,KAAK;IACH,GAAG,aAAa,GAAG,QAAQ,SAAS,OAAO,QAAQ,MAAM,MAAM,MAAM,QAAQ,IAAI;IACjF;GACF,KAAK;IACH,IAAI,SAAS;KACX,GAAG,iBAAiB,aAAa,OAAO,CAAC;KACzC,GAAG,eACD,QAAQ,SACR,QAAQ,OAAO,MACf,QAAQ,aACR,QAAQ,aACR,QACA,IACF;IACF;IACA;GACF,KAAK;GACL,KAAK;GACL,KAAK;IAEH,IAAI,WAAW,oBAAoB,SACjC,GAAG,iBAAiB,aAAa,OAAO,CAAC;SACpC,IAAI,WAAW,mBAAmB,MAAM;KAC7C,MAAM,EAAE,WAAW,GAAG,SAAS,IAAI;KACnC,GAAG,iBACD,wBAAwB,GAAG,QAAQ,KAAK,QAAQ;MAAE,WAAW;MAAG;KAAK,CAAC,CACxE;IACF;IACA,GAAG,aACD,SAAS,WAAW,GAAG,QACvB,SAAS,OAAO,QAAQ,MACxB,SAAS,eAAe,MACxB,SAAS,eAAe,MACxB,QACA,IACF;IACA;GAEF,KAAK;IACH,IAAI,SAAS,GAAG,iBAAiB,aAAa,OAAO,CAAC;IACtD;GACF,KAAK;IAEH,IAAI,SAAS;KACX,MAAM,YAAY,aAAa,OAAO;KACtC,MAAM,UAAU,UAAU,MAAM,OAAO,GAAG,MAAM,QAAQ,QAAQ;KAChE,IAAI,SAAS,GAAG,SAAS,WAAW,SAAS,MAAM;IACrD;IACA;EAEJ;EACA,YAAY,UAAU;EACtB,YAAY,UAAU;EACtB,eAAe,IAAI;CACrB,GACA,CAAC,gBAAgB,GAAG,CACtB;CAKA,gBAAgB;EACd,MAAM,OAAyC;GAC7C,WAAW,CAAC,IAAI,CAAC;GACjB,YAAY,CAAC,GAAG,CAAC;GACjB,SAAS,CAAC,GAAG,EAAE;GACf,WAAW,CAAC,GAAG,CAAC;EAClB;EACA,MAAM,aAAa,MAAqB;GACtC,IAAI,CAAC,YAAY,SAAS;GAC1B,MAAM,UAAU,WAAW;GAC3B,IAAI,CAAC,WAAW,QAAQ,SAAS,QAAQ;GACzC,MAAM,OAAO,KAAK,EAAE;GACpB,IAAI,CAAC,MAAM;GACX,EAAE,eAAe;GAIjB,EAAE,yBAAyB;GAC3B,MAAM,OAAO,MAAM,SAAS,KAAK,IAAI,KAAK,IAAI,IAAI,CAAC;GACnD,eAAe,IAAI;GACnB,MAAM,OAAO,KAAK;GAClB,MAAM,OAAO,eAAe,SAAS,sBAAsB;GAC3D,IAAI,QAAQ,MAAM;IAChB,MAAM,MAAM,qBAAqB,MAAM,SAAS,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IAC9E,YAAY,MACV,IACI;KACE,GAAG;KACH,MAAM,KAAK,OAAO,IAAI;KACtB,KAAK,KAAK,MAAM,IAAI;KACpB,OAAO,IAAI;KACX,QAAQ,IAAI;IACd,IACA,CACN;GACF;EACF;EACA,OAAO,iBAAiB,WAAW,WAAW,IAAI;EAClD,aAAa,OAAO,oBAAoB,WAAW,WAAW,IAAI;CACpE,GAAG,CAAC,KAAK,cAAc,CAAC;CAaxB,mBARwB,eACf;EACL,aAAa;EACb,YAAY;EACZ,WAAW;CACb,IACA;EAAC;EAAiB;EAAgB;CAAa,CAEhB,CAAC;CAElC,MAAM,gBAAgB,MAAM,YAAY,aAAa;CACrD,MAAM,cAAc,cACZ,iBAAiB,qBAAqB,SAAS,QAAQ,UAAU,GACvE,CAAC,aAAa,CAChB;CAEA,MAAM,iBAAyB,UAAU,QAAQ,UAAU,MAAM;CACjE,MAAM,YAAY,cACV,IAAI,IAAwB,eAAe,KAAK,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GACxE,CAAC,cAAc,CACjB;CAEA,MAAM,gBAAgB,MAAM,eAAe;CAC3C,MAAM,cAAc,MAAM,YAAY,WAAW;CACjD,MAAM,kBAAkB,aACrB,OAAe;EACd,MAAM,KAAK,cAAc,IAAI,EAAE;EAC/B,IAAI,CAAC,IAAI,OAAO;EAChB,OAAO,iBAAiB,gBAAgB,GAAG,eAAe,SAAS,CAAC,GAAG;CACzE,GACA;EAAC;EAAe;EAAe;CAAW,CAC5C;CAEA,MAAM,gBAAgB,MAAM,eAAe;CAC3C,MAAM,gBAAgB,MAAM,cAAc,WAAW;CACrD,MAAM,kBAAkB,aACrB,OAAe;EACd,MAAM,KAAK,cAAc,IAAI,EAAE;EAC/B,IAAI,CAAC,IAAI,OAAO;EAChB,OAAO,iBAAiB,kBAAkB,GAAG,eAAe,SAAS,CAAC,GAAG;CAC3E,GACA;EAAC;EAAe;EAAe;CAAa,CAC9C;CACA,MAAM,iBAAiB,MAAM,cAAc;CAC3C,MAAM,mBAAmB,aACtB,OAAe,cAAc,IAAI,EAAE,GAAG,iBAAiB,kBAAkB,iBAC1E,CAAC,eAAe,cAAc,CAChC;CAEA,MAAM,UAAuB,eACpB;EACL;EACA,OAAO,MAAM;EACb,UAAU,MAAM,YAAY;EAC5B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,IACA;EACE;EACA,MAAM;EACN,MAAM;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,OAAO,oBAAC,YAAY,UAAb;EAAsB,OAAO;YAAU,MAAM;CAA+B,CAAA;AACrF;;;;;;;;;;AC9lBA,SAAgB,cAAc,EAAE,YAAmD;CACjF,MAAM,cAAc,OAA4B,IAAI;CACpD,IAAI,CAAC,YAAY,SAAS,YAAY,UAAU,mBAAmB;CACnE,OACE,oBAAC,kBAAD,EAAA,UACE,oBAAC,qBAAqB,UAAtB;EAA+B,OAAO,YAAY;EAC/C;CAC4B,CAAA,EACf,CAAA;AAEtB;;;;ACHA,SAAS,gBAAgB,MAAc,MAA0B;CAC/D,MAAM,QAAQ,KAAK,oBAAoB,KAAK,QAAQ;CACpD,IAAI,QAAQ,GAAG,OAAO,OAAO;CAC7B,OAAO,OAAO,IAAI,OAAO,KAAK,aAAa,OAAO,KAAK,KAAK,OAAO;AACrE;;;;;;AAOA,SAAgB,mBAA2C;CACzD,MAAM,KAAK,eAAe;CAC1B,MAAM,EAAE,KAAK,iBAAiBC,eAAa;EACzC,IAAI,GAAG;EACP,MAAM;EACN,QAAQ;CACV,CAAC;CAID,MAAM,sBAAsB,GAAG;CAC/B,MAAM,SAAS,aACZ,YAA4B;EAC3B,IAAI,OAAO;EACX,oBAAoB,OAAO;CAC7B,GACA,CAAC,KAAK,mBAAmB,CAC3B;CAEA,MAAM,SAAS,GAAG,WACd,gBAAgB,OAAO,GAAG,cAAc,GAAG,GAAG,UAAU,IACxD,KAAA;CAEJ,OAAO;EACL,gBAAgB;GACd,KAAK;GACL,OAAO;IAAE,UAAU;IAAY,OAAO,GAAG;IAAO;GAAO;GACvD,oBAAoB,gBAAgB,KAAA;EACtC;EACA;CACF;AACF;;;AC3CA,MAAM,oBAAoB;;;;;;AAO1B,SAAgB,YAAY,IAA+B;CACzD,MAAM,KAAK,eAAe;CAC1B,MAAM,OAAO,GAAG,UAAU,IAAI,EAAE;CAChC,MAAM,EAAE,KAAK,eAAeC,eAAa;EACvC;EACA,MAAM;EACN,UAAU,CAAC,GAAG,gBAAgB,EAAE;EAChC,SAAS,GAAG;EACZ,SAAS;EAET,MAAM,EAAE,UAAU;GAAE,MAAM;GAAQ,QAAQ;GAAI;EAAK,EAAE;CACvD,CAAC;CACD,MAAM,SAAS,GAAG,SAAS,aAAa;CAExC,IAAI,QAAuB;EAAE,UAAU;EAAY,aAAa;CAAO;CACvE,IAAI,MAAM;EACR,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;EAClF,QAAQ;GACN,UAAU;GAIV,MAAM;GACN,KAAK;GACL,OAAO,IAAI;GACX,QAAQ,IAAI;GACZ,WAAW,aAAa,IAAI,KAAK,MAAM,IAAI,IAAI;GAK/C,YAAY,SAAS,WAAW,KAAA;GAChC,YAAY,SAAS,SAAS;GAC9B,aAAa;EACf;CACF;CAEA,OAAO;EAAE;EAAK;EAAO;EAAY;CAAK;AACxC;;;;;;;ACnDA,SAAgB,qBAAiD;CAC/D,MAAM,KAAK,eAAe;CAC1B,MAAM,cAAc,GAAG,SAAS;CAChC,IAAI,CAAC,aAAa,OAAO;CACzB,MAAM,MAAM,qBACV,GAAG,gBACH,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,CACd;CAYA,OAAO;EAAE,MAAM;EAAa,OAAA;GAV1B,UAAU;GAGV,MAAM;GACN,KAAK;GACL,OAAO,IAAI;GACX,QAAQ,IAAI;GACZ,WAAW,aAAa,IAAI,KAAK,MAAM,IAAI,IAAI;GAC/C,eAAe;EAEe;CAAE;AACpC;;;;;;;;ACnBA,SAAgB,oBACd,QACA,QAC2B;CAC3B,MAAM,KAAK,eAAe;CAC1B,MAAM,EAAE,QAAQC,eAAa;EAC3B,IAAI,GAAG,OAAO,YAAY;EAC1B,UAAU,CAAC,GAAG,gBAAgB,MAAM;EACpC,SAAS;EACT,MAAM,EAAE,UAAU;GAAE,MAAM;GAAU;GAAQ;EAAO,EAAE;CACvD,CAAC;CACD,MAAM,aAAa,GAAG,SAAS,SAAS,YAAY,GAAG,QAAQ,aAAa;CAC5E,OAAO;EAAE;EAAK,aAAa,GAAG,qBAAqB,KAAK;EAAG;CAAW;AACxE;;;;;;;;;ACfA,SAAgB,qBAA6C;CAE3D,MAAM,IADK,eACA,EAAE;CACb,IAAI,CAAC,GAAG,OAAO;CACf,OAAO;EACL,MAAM,EAAE;EACR,OAAO;GACL,UAAU;GACV,MAAM,EAAE;GACR,KAAK,EAAE;GACP,OAAO,EAAE;GACT,QAAQ,EAAE;GACV,eAAe;GACf,QAAQ;EACV;CACF;AACF;;;;ACnBA,MAAa,sBAAmC;CAAE,IAAI;CAAM,IAAI;CAAK,IAAI;CAAK,IAAI;CAAK,KAAK;AAAE;AAC9F,MAAa,0BAA0C;CAAE,IAAI;CAAI,IAAI;CAAI,IAAI;CAAG,IAAI;CAAG,KAAK;AAAE;;;;;;AAmC9F,SAAgB,oBACd,SAC2B;CAC3B,MAAM,EACJ,OACA,SACA,cAAc,qBACd,OAAO,yBACP,YAAYC,qBACZ,gBACA,uBACE;CAEJ,MAAM,aAAa,uBAAuB,aAAa,KAAK;CAC5D,MAAM,WAAW,sBAAsB,YAAY,IAAI;CASvD,MAAM,SAAS,cAAc;EAC3B,IAAI,SAAS;EACb,IAAI,cAAc,OAAO;EACzB,KAAK,MAAM,CAAC,IAAI,aAAa,OAAO,QAAQ,WAAW,GACrD,IAAI,QAAQ,OAAO,WAAW,aAAa;GACzC,cAAc;GACd,SAAS;EACX;EAEF,OAAO,+BACL,SACA,aACA,YACA,QACA,UACA,SACF;CACF,GAAG;EAAC;EAAS;EAAa;EAAY;EAAU;CAAS,CAAC;CAI1D,MAAM,wBAAwB,OAAO,kBAAkB;CACvD,sBAAsB,UAAU;CAChC,MAAM,qBAAqB,OAAO,UAAU;CAC5C,gBAAgB;EACd,IAAI,mBAAmB,YAAY,YAAY;GAC7C,mBAAmB,UAAU;GAC7B,sBAAsB,UAAU,YAAY,QAAQ;EACtD;CACF,GAAG,CAAC,YAAY,QAAQ,CAAC;CASzB,OAAO;EAAE;EAAY,MAAM;EAAU;EAAQ,gBAPlB,aACxB,SAAiB;GAChB,iBAAiB,MAAM;IAAE,GAAG;KAAU,aAAa;GAAK,CAAC;EAC3D,GACA;GAAC;GAAgB;GAAS;EAAU,CAGwC;CAAE;AAClF;;;;;;;;AC7FA,SAAgB,gBAAgB,EAAE,UAAU,WAAW,SAA+B;CACpF,MAAM,UAAU,mBAAmB;CACnC,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,OAAO;CACxD,OAAO,aACL,oBAAC,OAAD;EACE,WAAW,YAAY,oBAAoB,cAAc;EACzD,OAAO,QAAQ;GAAE,GAAG,QAAQ;GAAO,GAAG;EAAM,IAAI,QAAQ;YAEvD,SAAS,QAAQ,IAAI;CACnB,CAAA,GACL,SAAS,IACX;AACF;;;ACfA,MAAM,gBAAkD;CACtD,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAEA,MAAM,OAAO;AACb,SAAS,YAAY,QAAyC;CAC5D,MAAM,IAAmB;EACvB,UAAU;EACV,OAAO;EACP,QAAQ;EACR,QAAQ,cAAc;EACtB,aAAa;EACb,QAAQ;CACV;CACA,IAAI,OAAO,SAAS,GAAG,GAAG,EAAE,MAAM,MAAQ;CAC1C,IAAI,OAAO,SAAS,GAAG,GAAG,EAAE,SAAS,MAAQ;CAC7C,IAAI,OAAO,SAAS,GAAG,GAAG,EAAE,QAAQ,MAAQ;CAC5C,IAAI,OAAO,SAAS,GAAG,GAAG,EAAE,OAAO,MAAQ;CAC3C,IAAI,WAAW,OAAO,WAAW,KAC/B,EAAE,OAAO,cAAc,OAAO,EAAE;CAElC,IAAI,WAAW,OAAO,WAAW,KAC/B,EAAE,MAAM,cAAc,OAAO,EAAE;CAEjC,OAAO;AACT;AAEA,SAAS,oBAAoB,EAAE,QAAQ,UAAwD;CAC7F,MAAM,EAAE,KAAK,gBAAgB,oBAAoB,QAAQ,MAAM;CAC/D,OACE,oBAAC,QAAD;EACO;EACL,GAAI;EACJ,WAAW,kDAAkD;EAC7D,OAAO,YAAY,MAAM;CAC1B,CAAA;AAEL;;;;;;AAOA,SAAgB,SAAS,EAAE,IAAI,UAAU,WAAW,SAAwB;CAC1E,MAAM,KAAK,eAAe;CAC1B,MAAM,EAAE,KAAK,OAAO,eAAe,eAAe,YAAY,EAAE;CAChE,MAAM,UAAU,GAAG,gBAAgB,EAAE,IAAI,GAAG,iBAAiB,EAAE,IAAI,CAAC;CACpE,OACE,qBAAC,OAAD;EACO;EACL,gBAAc;EACd,iBAAe,cAAc,KAAA;EAC7B,WAAW,YAAY,iBAAiB,cAAc;EACtD,OAAO,QAAQ;GAAE,GAAG;GAAe,GAAG;EAAM,IAAI;YALlD,CAOG,UACA,QAAQ,KAAK,WACZ,oBAAC,qBAAD;GAAkC,QAAQ;GAAY;EAAS,GAArC,MAAqC,CAChE,CACE;;AAET;;;AC3EA,MAAM,eAA8B;CAClC,YAAY;CACZ,QAAQ;CACR,cAAc;CACd,WAAW;CACX,QAAQ;CACR,YAAY;AACd;;;;;;AAOA,SAAgB,gBAAgB,EAAE,WAAW,SAA+B;CAC1E,MAAM,cAAc,mBAAmB;CACvC,IAAI,CAAC,aAAa,OAAO;CACzB,OACE,oBAAC,OAAD;EACE,eAAY;EACZ,WAAW,YAAY,wBAAwB,cAAc;EAC7D,OAAO;GAAE,GAAG,YAAY;GAAO,GAAG;GAAc,GAAG;EAAM;CAC1D,CAAA;AAEL;;;;ACbA,SAAS,QAAQ,KAAqB;CACpC,OAAO,IAAI,WAAW,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI;AAC/C;;AAGA,SAAS,YAAY,EACnB,WACA,OACA,YAKC;CACD,MAAM,EAAE,mBAAmB,iBAAiB;CAE5C,MAAM,4BAAY,IAAI,IAA0B;CAChD,SAAS,QAAQ,WAAW,UAAU;EACpC,IAAI,eAAe,KAAK,KAAK,MAAM,OAAO,MACxC,UAAU,IAAI,QAAQ,OAAO,MAAM,GAAG,CAAC,GAAG,KAAK;CAEnD,CAAC;CACD,OACE,qBAAC,OAAD;EACE,GAAI;EACJ,WAAW,YAAY,YAAY,cAAc;EACjD,OAAO,QAAQ;GAAE,GAAG,eAAe;GAAO,GAAG;EAAM,IAAI,eAAe;YAHxE;GAKG,SAAS,IAAI,WAAW,UAAU;IACjC,IAAI,CAAC,eAAe,KAAK,KAAK,MAAM,OAAO,MAAM,OAAO;IACxD,OACE,oBAAC,UAAD;KAA0B,IAAI,QAAQ,OAAO,MAAM,GAAG,CAAC;eACpD;IACO,GAFK,MAAM,GAEX;GAEd,CAAC;GACD,oBAAC,iBAAD,CAAkB,CAAA;GAClB,oBAAC,iBAAD,EAAA,WAAmB,SAAS,UAAU,IAAI,KAAK,CAAC,KAAK,KAAsB,CAAA;EACxE;;AAET;;;;;;;AAQA,SAAgB,WAAW,OAA2C;CACpE,MAAM,EAAE,WAAW,OAAO,UAAU,GAAG,kBAAkB;CACzD,OACE,oBAAC,kBAAD;EAAkB,GAAI;YACpB,oBAAC,aAAD;GAAwB;GAAkB;GACvC;EACU,CAAA;CACG,CAAA;AAEtB;;;;;;;;;ACjCA,SAAgB,qBAAqB,OAAqD;CACxF,MAAM,EAAE,MAAM,QAAQ,mBAAmB,oBAAoB;EAC3D,OAAO,MAAM;EACb,SAAS,MAAM;EACf,aAAa,MAAM;EACnB,MAAM,MAAM;EACZ,WAAW,MAAM;EACjB,gBAAgB,MAAM;EACtB,oBAAoB,MAAM;CAC5B,CAAC;CAID,MAAM,aAAa,eACV;EACL;EACA,WAAW,MAAM,aAAa;EAC9B,QAAQ,MAAM,UAAW,CAAC,IAAI,EAAE;EAChC,kBAAkB,MAAM,oBAAoB;CAC9C,IACA;EAAC;EAAM,MAAM;EAAW,MAAM;EAAQ,MAAM;CAAgB,CAC9D;CAEA,OAIE,oBAAC,YAAD;EACU;EACR,OAAO,MAAM;EACG;EACJ;EACZ,WAAW,MAAM;EACjB,YAAY,MAAM;EAClB,cAAc,MAAM;EACpB,aAAa,MAAM;EACnB,aAAa,MAAM;EACnB,UAAU,MAAM;EAChB,WAAW,MAAM;EACjB,OAAO,MAAM;YAEZ,MAAM;CACG,CAAA;AAEhB;;;ACnFA,MAAM,4BAA4B,OAAO,WAAW,cAAc,kBAAkB;;;;;AAoBpF,SAAgB,kBAAkB,UAAoC,CAAC,GAA4B;CACjG,MAAM,EAAE,eAAe,SAAS;CAChC,MAAM,CAAC,OAAO,YAAY,SAAS,YAAY;CAC/C,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAG5C,MAAM,CAAC,SAAS,cAAc,SAA6B,IAAI;CAC/D,MAAM,eAAe,aAAa,SAA6B,WAAW,IAAI,GAAG,CAAC,CAAC;CAEnF,gCAAgC;EAC9B,IAAI,CAAC,WAAW,OAAO,mBAAmB,aAAa;EACvD,MAAM,gBAAgB;GACpB,MAAM,OAAO,QAAQ,sBAAsB,EAAE;GAC7C,IAAI,OAAO,GAAG;IACZ,SAAS,IAAI;IACb,WAAW,IAAI;GACjB;EACF;EACA,QAAQ;EACR,MAAM,WAAW,IAAI,eAAe,OAAO;EAC3C,SAAS,QAAQ,OAAO;EACxB,aAAa,SAAS,WAAW;CACnC,GAAG,CAAC,OAAO,CAAC;CAEZ,OAAO;EAAE;EAAO;EAAS;CAAa;AACxC"}
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@snapgridjs/react",
3
+ "version": "0.1.0",
4
+ "description": "React grid-layout components built on dnd-kit — a react-grid-layout v2 alternative.",
5
+ "license": "MIT",
6
+ "author": "Edmond Leung",
7
+ "homepage": "https://snapgrid.dev",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/eleung/snapgrid.git",
11
+ "directory": "packages/grid-react"
12
+ },
13
+ "bugs": "https://github.com/eleung/snapgrid/issues",
14
+ "keywords": [
15
+ "react",
16
+ "grid",
17
+ "grid-layout",
18
+ "react-grid-layout",
19
+ "drag-and-drop",
20
+ "draggable",
21
+ "resizable",
22
+ "responsive",
23
+ "dashboard",
24
+ "kanban",
25
+ "dnd-kit",
26
+ "snapgrid"
27
+ ],
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "publishConfig": {
31
+ "access": "public",
32
+ "registry": "https://registry.npmjs.org"
33
+ },
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "exports": {
38
+ ".": {
39
+ "import": {
40
+ "types": "./dist/index.d.mts",
41
+ "default": "./dist/index.mjs"
42
+ },
43
+ "require": {
44
+ "types": "./dist/index.d.cts",
45
+ "default": "./dist/index.cjs"
46
+ }
47
+ },
48
+ "./package.json": "./package.json"
49
+ },
50
+ "main": "./dist/index.cjs",
51
+ "module": "./dist/index.mjs",
52
+ "types": "./dist/index.d.mts",
53
+ "dependencies": {
54
+ "@snapgridjs/core": "0.1.0"
55
+ },
56
+ "peerDependencies": {
57
+ "react": ">=18",
58
+ "react-dom": ">=18",
59
+ "@dnd-kit/abstract": "^0.4.0",
60
+ "@dnd-kit/collision": "^0.4.0",
61
+ "@dnd-kit/dom": "^0.4.0",
62
+ "@dnd-kit/geometry": "^0.4.0",
63
+ "@dnd-kit/helpers": "^0.4.0",
64
+ "@dnd-kit/react": "^0.4.0"
65
+ },
66
+ "devDependencies": {
67
+ "@dnd-kit/abstract": "^0.4.0",
68
+ "@dnd-kit/collision": "^0.4.0",
69
+ "@dnd-kit/dom": "^0.4.0",
70
+ "@dnd-kit/geometry": "^0.4.0",
71
+ "@dnd-kit/helpers": "^0.4.0",
72
+ "@dnd-kit/react": "^0.4.0"
73
+ },
74
+ "scripts": {
75
+ "build": "tsdown",
76
+ "typecheck": "tsc --noEmit"
77
+ }
78
+ }