@griddle/vue 0.1.6 → 0.1.8
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.
- package/dist/GriddleGrid.vue.d.ts.map +1 -1
- package/dist/LoopGrid.vue.d.ts.map +1 -1
- package/dist/index.js +590 -532
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +49 -0
- package/dist/interaction.d.ts.map +1 -0
- package/dist/interaction.js +82 -0
- package/dist/interaction.js.map +1 -0
- package/package.json +3 -3
- package/src/GriddleGrid.vue +76 -29
- package/src/LoopGrid.vue +22 -13
- package/src/interaction.ts +153 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/LoopGrid.vue","../src/GriddleGrid.vue","../src/useGriddle.ts"],"sourcesContent":["<template>\n <div\n ref=\"viewportEl\"\n :class=\"className\"\n :style=\"viewportStyle\"\n @pointerdown=\"onContainerPointerDown\"\n @click.capture=\"onClickCapture\"\n >\n <div ref=\"planeEl\" :style=\"planeStyle\">\n <div\n v-if=\"indicatorRect\"\n class=\"griddle-drop-indicator\"\n :style=\"{\n position: 'absolute',\n left: indicatorRect.left + 'px',\n top: indicatorRect.top + 'px',\n width: indicatorRect.width + 'px',\n height: indicatorRect.height + 'px',\n boxSizing: 'border-box',\n border: '2px dashed rgba(59, 91, 219, 0.55)',\n background: 'rgba(59, 91, 219, 0.08)',\n borderRadius: (config.tileRadius ?? 4) + 'px',\n pointerEvents: 'none',\n zIndex: 5,\n }\"\n ></div>\n <template v-for=\"inst in instances\" :key=\"inst.key\">\n <div\n v-if=\"!(drag && inst.tile.id === drag.tileId)\"\n :data-griddle-tile=\"inst.tile.id\"\n :data-griddle-instance=\"inst.key\"\n :data-griddle-ghost=\"isGhost(inst) ? '' : undefined\"\n :aria-hidden=\"isBase(inst) ? undefined : true\"\n :class=\"['griddle-tile', {\n 'griddle-resizing': resize?.instanceKey === inst.key,\n 'griddle-selected': editable && isBase(inst) && selection.has(inst.tile.id),\n }]\"\n :style=\"instanceStyle(inst)\"\n :ref=\"(el) => registerNode(inst.key, el as HTMLDivElement | null)\"\n @pointerdown=\"(e) => onTilePointerDown(e, inst)\"\n >\n <slot name=\"tile\" :tile=\"inst.tile\" :selected=\"editable && isBase(inst) && selection.has(inst.tile.id)\" />\n <template v-if=\"editable && isBase(inst) && inst.tile.resizable !== false\">\n <div\n v-for=\"c in tileHandles(inst.tile)\"\n :key=\"c\"\n :data-griddle-handle=\"c\"\n :style=\"handleStyle(c)\"\n @pointerdown=\"(e) => onResizeHandleDown(e, inst, c)\"\n ></div>\n </template>\n </div>\n </template>\n <div\n v-if=\"drag && draggedTile\"\n :data-griddle-tile=\"draggedTile.id\"\n class=\"griddle-tile griddle-dragging\"\n :style=\"dragOverlayStyle\"\n >\n <slot name=\"tile\" :tile=\"draggedTile\" :selected=\"selection.has(draggedTile.id)\" />\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n// Loop-mode renderer (\"object looping\") — see @griddle/core loop.ts for the\n// coordinate model. Mirrors the React GriddleLoopGrid: an overflow-hidden\n// viewport, a transform-translated plane driven by an unbounded camera, and\n// NO native scrolling (wheel deltas feed the camera directly).\nimport { computed, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue';\nimport type { CameraState, CellPos, Corner, Tile } from '@griddle/core';\nimport {\n DragController,\n PanController,\n loopInstances,\n loopPeriod,\n resolveLoop,\n} from '@griddle/core';\nimport type { LoopTileInstance } from '@griddle/core';\nimport type { GriddleApi } from './useGriddle.js';\nimport { animateReposition } from './animation.js';\n\nconst props = defineProps<{\n api: GriddleApi;\n className?: string;\n height?: number | string;\n showGrid?: boolean;\n selection?: Set<string>;\n}>();\n\nconst emit = defineEmits<{\n (e: 'selectionChange', selection: Set<string>): void;\n (e: 'dragStart', tileId: string): void;\n (e: 'dragEnd', tileId: string, committed: boolean): void;\n (e: 'resizeStart', tileId: string): void;\n (e: 'resizeEnd', tileId: string, committed: boolean): void;\n (e: 'cameraChange', camera: CameraState): void;\n}>();\n\nconst DEFAULT_DRAG_IGNORE = 'a, button, input, textarea, select, [contenteditable]';\nconst PAN_THRESHOLD_PX = 4;\n\nconst viewportEl = ref<HTMLDivElement | null>(null);\nconst planeEl = ref<HTMLDivElement | null>(null);\n\nconst config = computed(() => props.api.config.value);\nconst loop = computed(() => resolveLoop(config.value));\nconst editable = computed(() => loop.value?.interaction === 'edit');\nconst gap = computed(() => config.value.gap ?? 0);\nconst halfGap = computed(() => gap.value / 2);\nconst colSize = computed(() => config.value.unitWidth + gap.value);\nconst rowSize = computed(() => config.value.unitHeight + gap.value);\nconst period = computed(() => loopPeriod(config.value, props.api.tiles.value));\n\n// ---- camera plumbing ------------------------------------------------------\nconst pan = new PanController();\nwatch(loop, (l) => {\n if (l) pan.setPhysics({ friction: l.friction, ease: l.ease, maxVelocity: l.maxVelocity });\n}, { immediate: true });\n\nconst view = ref({ cxCell: 0, cyCell: 0, vw: 1000, vh: 800 });\nlet lastCam: CameraState | null = null;\nlet raf = 0;\nlet resizeObserver: ResizeObserver | null = null;\n\nfunction onWheel(e: WheelEvent) {\n e.preventDefault();\n const k = e.deltaMode === 1 ? 16 : e.deltaMode === 2 ? 100 : 1;\n pan.scrollBy(e.deltaX * k, e.deltaY * k);\n}\n\nfunction frame(now: number) {\n raf = requestAnimationFrame(frame);\n const st = pan.tick(now);\n\n const plane = planeEl.value;\n if (plane) {\n plane.style.transform = `translate3d(${-st.x}px, ${-st.y}px, 0)`;\n }\n const el = viewportEl.value;\n if (el && props.showGrid !== false) {\n el.style.backgroundPosition = `${-st.x % colSize.value}px ${-st.y % rowSize.value}px`;\n }\n\n const cxCell = Math.floor(st.x / colSize.value);\n const cyCell = Math.floor(st.y / rowSize.value);\n const cur = view.value;\n if (cxCell !== cur.cxCell || cyCell !== cur.cyCell) {\n view.value = { ...cur, cxCell, cyCell };\n }\n\n if (\n !lastCam || lastCam.x !== st.x || lastCam.y !== st.y ||\n lastCam.isMoving !== st.isMoving || lastCam.isDragging !== st.isDragging\n ) {\n lastCam = st;\n emit('cameraChange', st);\n }\n}\n\nconst instances = computed(() => {\n void props.api.version.value; // re-run on grid changes\n const bufX = 2 * colSize.value;\n const bufY = 2 * rowSize.value;\n return loopInstances(config.value, props.api.tiles.value, {\n x: view.value.cxCell * colSize.value - bufX,\n y: view.value.cyCell * rowSize.value - bufY,\n width: view.value.vw + colSize.value + 2 * bufX,\n height: view.value.vh + rowSize.value + 2 * bufY,\n });\n});\n\n// ---- pan gesture ----------------------------------------------------------\nlet panGesture: { pointerId: number; startX: number; startY: number; moved: boolean } | null = null;\nlet suppressClick = false;\n\nfunction onContainerPointerDown(e: PointerEvent) {\n const onTile = !!(e.target as HTMLElement).closest('[data-griddle-tile]');\n if (editable.value && !onTile) setSelection(new Set());\n // Tiles that start drags stopPropagation, so reaching here from a tile\n // means it was not draggable — panning is the right fallback.\n if (!loop.value?.dragPan || e.button !== 0) return;\n const ignoreSelector = config.value.dragIgnoreFrom ?? DEFAULT_DRAG_IGNORE;\n if (ignoreSelector && (e.target as HTMLElement).closest(ignoreSelector)) return;\n panGesture = { pointerId: e.pointerId, startX: e.clientX, startY: e.clientY, moved: false };\n}\n\nfunction onClickCapture(e: MouseEvent) {\n if (suppressClick) {\n suppressClick = false;\n e.preventDefault();\n e.stopPropagation();\n }\n}\n\n// ---- selection ('edit' interaction) ---------------------------------------\nconst internalSelection = ref<Set<string>>(new Set());\nconst selection = computed(() => props.selection ?? internalSelection.value);\nfunction setSelection(next: Set<string>) {\n if (!props.selection) internalSelection.value = next;\n emit('selectionChange', next);\n}\n\n// ---- tile drag / resize ('edit' interaction) ------------------------------\nconst dragController = new DragController(props.api.grid);\n\ninterface LoopDragVisual {\n tileId: string;\n instanceLeft: number;\n instanceTop: number;\n pickupCol: number;\n pickupRow: number;\n deltaX: number;\n deltaY: number;\n indicatorCol: number | null;\n indicatorRow: number | null;\n}\nconst drag = ref<LoopDragVisual | null>(null);\nlet dragStartPointerX = 0;\nlet dragStartPointerY = 0;\n\ninterface LoopResizeState {\n tileId: string;\n instanceKey: string;\n instanceDx: number;\n instanceDy: number;\n corner: Corner;\n startPointerX: number;\n startPointerY: number;\n startW: number;\n startH: number;\n startCol: number;\n startRow: number;\n previewW: number;\n previewH: number;\n previewCol: number;\n previewRow: number;\n}\nconst resize = ref<LoopResizeState | null>(null);\n\nfunction syncTiles() {\n props.api.tiles.value = props.api.grid.tiles;\n props.api.version.value++;\n}\n\nfunction isBase(inst: LoopTileInstance): boolean {\n return inst.kx === 0 && inst.ky === 0;\n}\nfunction isGhost(inst: LoopTileInstance): boolean {\n return editable.value && !isBase(inst);\n}\n\nfunction onTilePointerDown(e: PointerEvent, inst: LoopTileInstance) {\n if (!editable.value) return; // pan mode: container pan handler takes it\n if (!isBase(inst)) return; // ghosts are display-only\n const tile = inst.tile;\n if (tile.draggable === false) return;\n if ((e.target as HTMLElement).dataset.griddleHandle) return;\n const ignoreSelector = config.value.dragIgnoreFrom ?? DEFAULT_DRAG_IGNORE;\n if (ignoreSelector && (e.target as HTMLElement).closest(ignoreSelector)) return;\n\n if (e.metaKey || e.ctrlKey) {\n e.preventDefault();\n const next = new Set(selection.value);\n if (next.has(tile.id)) next.delete(tile.id);\n else next.add(tile.id);\n setSelection(next);\n e.stopPropagation();\n return;\n }\n setSelection(new Set([tile.id]));\n\n // No pointer capture: the grabbed instance unmounts (drag renders as an\n // overlay), which would release the capture mid-gesture.\n if (!dragController.start(tile.id)) return;\n dragStartPointerX = e.clientX;\n dragStartPointerY = e.clientY;\n drag.value = {\n tileId: tile.id,\n instanceLeft: inst.left,\n instanceTop: inst.top,\n pickupCol: tile.col,\n pickupRow: tile.row,\n deltaX: 0,\n deltaY: 0,\n indicatorCol: tile.col,\n indicatorRow: tile.row,\n };\n emit('dragStart', tile.id);\n e.stopPropagation();\n}\n\nfunction onResizeHandleDown(e: PointerEvent, inst: LoopTileInstance, c: Corner) {\n if (!editable.value) return;\n const tile = inst.tile;\n if (tile.resizable === false) return;\n (e.currentTarget as HTMLDivElement).setPointerCapture(e.pointerId);\n const baseLeft = tile.col * colSize.value + halfGap.value;\n const baseTop = tile.row * rowSize.value + halfGap.value;\n resize.value = {\n tileId: tile.id,\n instanceKey: inst.key,\n instanceDx: inst.left - baseLeft,\n instanceDy: inst.top - baseTop,\n corner: c,\n startPointerX: e.clientX,\n startPointerY: e.clientY,\n startW: tile.w,\n startH: tile.h,\n startCol: tile.col,\n startRow: tile.row,\n previewW: tile.w,\n previewH: tile.h,\n previewCol: tile.col,\n previewRow: tile.row,\n };\n emit('resizeStart', tile.id);\n e.stopPropagation();\n}\n\nfunction onPointerMove(e: PointerEvent) {\n if (panGesture && e.pointerId === panGesture.pointerId) {\n const now = performance.now();\n if (!panGesture.moved) {\n const dist = Math.hypot(e.clientX - panGesture.startX, e.clientY - panGesture.startY);\n if (dist >= PAN_THRESHOLD_PX) {\n panGesture.moved = true;\n pan.dragStart(panGesture.startX, panGesture.startY, now);\n pan.dragMove(e.clientX, e.clientY, now);\n }\n } else {\n pan.dragMove(e.clientX, e.clientY, now);\n }\n return;\n }\n\n const d = drag.value;\n if (d) {\n // Ghost edit: plain grid semantics in the base copy — no wrapping.\n const dx = e.clientX - dragStartPointerX;\n const dy = e.clientY - dragStartPointerY;\n const candidate: CellPos = {\n col: d.pickupCol + Math.round(dx / colSize.value),\n row: d.pickupRow + Math.round(dy / rowSize.value),\n };\n const result = dragController.update(candidate);\n drag.value = {\n ...d,\n deltaX: dx,\n deltaY: dy,\n indicatorCol: result.indicatorCell ? result.indicatorCell.col : null,\n indicatorRow: result.indicatorCell ? result.indicatorCell.row : null,\n };\n if (result.changed) syncTiles();\n }\n\n const r = resize.value;\n if (r) {\n const dx = e.clientX - r.startPointerX;\n const dy = e.clientY - r.startPointerY;\n let dw = 0, dh = 0, dcol = 0, drow = 0;\n const stepsX = Math.round(dx / colSize.value);\n const stepsY = Math.round(dy / rowSize.value);\n if (r.corner === 'se' || r.corner === 'ne') dw = stepsX;\n if (r.corner === 'se' || r.corner === 'sw') dh = stepsY;\n if (r.corner === 'sw' || r.corner === 'nw') { dw = -stepsX; dcol = stepsX; }\n if (r.corner === 'ne' || r.corner === 'nw') { dh = -stepsY; drow = stepsY; }\n const tile = props.api.grid.getTile(r.tileId);\n const minW = tile?.minW ?? 1;\n const minH = tile?.minH ?? 1;\n const maxW = Math.min(tile?.maxW ?? Infinity, config.value.cols);\n const maxH = Math.min(tile?.maxH ?? Infinity, config.value.rows);\n const nW = Math.min(maxW, Math.max(minW, r.startW + dw));\n const nH = Math.min(maxH, Math.max(minH, r.startH + dh));\n const nC = r.startCol + dcol;\n const nR = r.startRow + drow;\n if (nW !== r.previewW || nH !== r.previewH || nC !== r.previewCol || nR !== r.previewRow) {\n resize.value = { ...r, previewW: nW, previewH: nH, previewCol: nC, previewRow: nR };\n }\n }\n}\n\nfunction onPointerUp(e: PointerEvent) {\n if (panGesture && e.pointerId === panGesture.pointerId) {\n if (panGesture.moved) {\n pan.dragEnd(performance.now());\n suppressClick = true;\n }\n panGesture = null;\n return;\n }\n\n if (drag.value) {\n const tileId = drag.value.tileId;\n const { committed } = dragController.end();\n drag.value = null;\n syncTiles();\n emit('dragEnd', tileId, committed);\n }\n const r = resize.value;\n if (r) {\n const t = props.api.grid.getTile(r.tileId);\n let committed = false;\n if (t) {\n const target = { col: r.previewCol, row: r.previewRow };\n if (target.col !== t.col || target.row !== t.row) {\n props.api.moveTile(r.tileId, target);\n }\n if (r.previewW !== t.w || r.previewH !== t.h) {\n committed = props.api.resizeTile(r.tileId, { w: r.previewW, h: r.previewH });\n } else {\n committed = r.previewCol !== r.startCol || r.previewRow !== r.startRow\n || r.previewW !== r.startW || r.previewH !== r.startH;\n }\n }\n resize.value = null;\n emit('resizeEnd', r.tileId, committed);\n }\n}\n\nfunction onKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape' && editable.value) setSelection(new Set());\n}\n\nonMounted(() => {\n const el = viewportEl.value;\n if (el) {\n el.addEventListener('wheel', onWheel, { passive: false });\n const measure = () => {\n const cur = view.value;\n if (el.clientWidth !== cur.vw || el.clientHeight !== cur.vh) {\n view.value = { ...cur, vw: el.clientWidth, vh: el.clientHeight };\n }\n };\n measure();\n resizeObserver = new ResizeObserver(measure);\n resizeObserver.observe(el);\n }\n raf = requestAnimationFrame(frame);\n window.addEventListener('pointermove', onPointerMove);\n window.addEventListener('pointerup', onPointerUp);\n window.addEventListener('pointercancel', onPointerUp);\n window.addEventListener('keydown', onKeyDown);\n});\nonBeforeUnmount(() => {\n cancelAnimationFrame(raf);\n viewportEl.value?.removeEventListener('wheel', onWheel);\n resizeObserver?.disconnect();\n window.removeEventListener('pointermove', onPointerMove);\n window.removeEventListener('pointerup', onPointerUp);\n window.removeEventListener('pointercancel', onPointerUp);\n window.removeEventListener('keydown', onKeyDown);\n});\n\n// ---- FLIP for edit-mode repacks (keyed by world key) ----------------------\nconst tileNodes = new Map<string, HTMLDivElement>();\nconst prevRects = new Map<string, { x: number; y: number }>();\nfunction registerNode(key: string, el: HTMLDivElement | null) {\n if (el) tileNodes.set(key, el);\n else tileNodes.delete(key);\n}\n\nwatch(() => props.api.version.value, async () => {\n await nextTick();\n const draggerId = drag.value?.tileId ?? null;\n const seen = new Set<string>();\n for (const inst of instances.value) {\n const key = inst.key;\n seen.add(key);\n const x = inst.left;\n const y = inst.top;\n if (editable.value && inst.tile.id !== draggerId) {\n const p = prevRects.get(key);\n const node = tileNodes.get(key);\n if (p && node) {\n const dx = p.x - x;\n const dy = p.y - y;\n if (\n (dx !== 0 || dy !== 0) &&\n Math.abs(dx) < period.value.width / 2 &&\n Math.abs(dy) < period.value.height / 2\n ) {\n animateReposition(node, dx, dy, config.value.animation);\n }\n }\n }\n prevRects.set(key, { x, y });\n }\n for (const key of prevRects.keys()) {\n if (!seen.has(key)) prevRects.delete(key);\n }\n});\n\n// ---- styles ----------------------------------------------------------------\nconst viewportStyle = computed(() => {\n const showGrid = props.showGrid !== false;\n const bg = showGrid\n ? {\n backgroundImage: `linear-gradient(to right, rgba(0,0,0,0.08) 1px, transparent 1px), linear-gradient(to bottom, rgba(0,0,0,0.08) 1px, transparent 1px)`,\n backgroundSize: `${colSize.value}px ${rowSize.value}px`,\n backgroundPosition: '0 0',\n }\n : {};\n return {\n position: 'relative' as const,\n overflow: 'hidden' as const,\n height: typeof props.height === 'number' ? props.height + 'px' : (props.height ?? '100%'),\n touchAction: 'none' as const,\n userSelect: 'none' as const,\n willChange: 'translate',\n cursor: !editable.value && loop.value?.dragPan ? 'grab' : undefined,\n ['--griddle-tile-radius' as string]: (config.value.tileRadius ?? 4) + 'px',\n ...bg,\n };\n});\n\nconst planeStyle = computed(() => ({\n position: 'absolute' as const,\n top: '0',\n left: '0',\n width: '0',\n height: '0',\n willChange: 'transform',\n}));\n\nfunction instanceStyle(inst: LoopTileInstance) {\n const r = resize.value;\n const isResizingInst = r?.instanceKey === inst.key;\n let left = inst.left;\n let top = inst.top;\n let width = inst.width;\n let heightPx = inst.height;\n if (isResizingInst && r) {\n left = r.previewCol * colSize.value + halfGap.value + r.instanceDx;\n top = r.previewRow * rowSize.value + halfGap.value + r.instanceDy;\n width = r.previewW * config.value.unitWidth + (r.previewW - 1) * gap.value;\n heightPx = r.previewH * config.value.unitHeight + (r.previewH - 1) * gap.value;\n }\n const ghost = isGhost(inst);\n const isSelected = editable.value && isBase(inst) && selection.value.has(inst.tile.id);\n return {\n position: 'absolute' as const,\n left: left + 'px',\n top: top + 'px',\n width: width + 'px',\n height: heightPx + 'px',\n boxSizing: 'border-box' as const,\n cursor: editable.value && isBase(inst) ? 'grab' : undefined,\n userSelect: 'none' as const,\n // Ghosts are display-only: pointer-transparent (so the gesture falls\n // through to drag-pan) and dimmed to mark the editable copy.\n pointerEvents: ghost ? ('none' as const) : undefined,\n zIndex: isResizingInst ? 10 : 1,\n opacity: isResizingInst ? 0.85 : ghost ? 0.55 : 1,\n boxShadow: isSelected\n ? '0 0 0 3px rgba(59, 91, 219, 0.85), inset 0 0 0 1px rgba(59, 91, 219, 0.3)'\n : '',\n borderRadius: (config.value.tileRadius ?? 4) + 'px',\n };\n}\n\nconst draggedTile = computed<Tile | null>(() =>\n drag.value ? props.api.grid.getTile(drag.value.tileId) ?? null : null,\n);\n\nconst dragOverlayStyle = computed(() => {\n const d = drag.value;\n const t = draggedTile.value;\n if (!d || !t) return {};\n return {\n position: 'absolute' as const,\n left: d.instanceLeft + 'px',\n top: d.instanceTop + 'px',\n width: t.w * config.value.unitWidth + (t.w - 1) * gap.value + 'px',\n height: t.h * config.value.unitHeight + (t.h - 1) * gap.value + 'px',\n boxSizing: 'border-box' as const,\n cursor: 'grabbing',\n userSelect: 'none' as const,\n zIndex: 20,\n opacity: 0.85,\n transform: `translate(${d.deltaX}px, ${d.deltaY}px)`,\n filter: 'drop-shadow(0 8px 16px rgba(0,0,0,0.18))',\n borderRadius: (config.value.tileRadius ?? 4) + 'px',\n pointerEvents: 'none' as const,\n };\n});\n\n// Drop indicator: rendered in the base copy (ghost edit is plain-grid).\nconst indicatorRect = computed(() => {\n const d = drag.value;\n if (!d || d.indicatorCol === null || d.indicatorRow === null) return null;\n const t = props.api.grid.getTile(d.tileId);\n if (!t) return null;\n return {\n left: d.indicatorCol * colSize.value + halfGap.value,\n top: d.indicatorRow * rowSize.value + halfGap.value,\n width: t.w * config.value.unitWidth + (t.w - 1) * gap.value,\n height: t.h * config.value.unitHeight + (t.h - 1) * gap.value,\n };\n});\n\nfunction tileHandles(tile: Tile): Corner[] {\n return tile.resizeHandles ?? config.value.resizeHandles ?? ['se'];\n}\n\nfunction handleStyle(c: Corner) {\n const size = 12;\n const base = {\n position: 'absolute' as const,\n width: size + 'px',\n height: size + 'px',\n background: 'rgba(60,60,60,0.7)',\n border: '2px solid white',\n borderRadius: '3px',\n cursor: `${c}-resize`,\n touchAction: 'none' as const,\n } as Record<string, unknown>;\n if (c === 'nw') return { ...base, top: -size / 2 + 'px', left: -size / 2 + 'px' };\n if (c === 'ne') return { ...base, top: -size / 2 + 'px', right: -size / 2 + 'px' };\n if (c === 'sw') return { ...base, bottom: -size / 2 + 'px', left: -size / 2 + 'px' };\n return { ...base, bottom: -size / 2 + 'px', right: -size / 2 + 'px' };\n}\n\nconst className = computed(() => props.className ?? '');\n</script>\n","<template>\n <GriddleLoopGrid\n v-if=\"loopOn\"\n :api=\"api\"\n :class-name=\"className\"\n :height=\"height\"\n :show-grid=\"showGrid\"\n :selection=\"props.selection\"\n @selection-change=\"(s) => emit('selectionChange', s)\"\n @drag-start=\"(id) => emit('dragStart', id)\"\n @drag-end=\"(id, c) => emit('dragEnd', id, c)\"\n @resize-start=\"(id) => emit('resizeStart', id)\"\n @resize-end=\"(id, c) => emit('resizeEnd', id, c)\"\n @camera-change=\"(cam) => emit('cameraChange', cam)\"\n >\n <template #tile=\"slotProps\">\n <slot name=\"tile\" v-bind=\"slotProps\" />\n </template>\n </GriddleLoopGrid>\n <div\n v-else\n ref=\"scrollEl\"\n :class=\"className\"\n :style=\"scrollStyle\"\n @pointerdown=\"onBackgroundPointerDown\"\n >\n <div :style=\"contentStyle\">\n <div\n v-if=\"indicatorRect\"\n class=\"griddle-drop-indicator\"\n :style=\"{\n position: 'absolute',\n left: indicatorRect.left + 'px',\n top: indicatorRect.top + 'px',\n width: indicatorRect.width + 'px',\n height: indicatorRect.height + 'px',\n boxSizing: 'border-box',\n border: '2px dashed rgba(59, 91, 219, 0.55)',\n background: 'rgba(59, 91, 219, 0.08)',\n borderRadius: (config.tileRadius ?? 4) + 'px',\n pointerEvents: 'none',\n zIndex: 5,\n }\"\n ></div>\n <div\n v-if=\"drawGhostRect\"\n class=\"griddle-draw-ghost\"\n :style=\"{\n position: 'absolute',\n left: drawGhostRect.left + 'px',\n top: drawGhostRect.top + 'px',\n width: drawGhostRect.width + 'px',\n height: drawGhostRect.height + 'px',\n boxSizing: 'border-box',\n border: '2px dashed rgba(59, 91, 219, 0.55)',\n background: 'rgba(59, 91, 219, 0.08)',\n borderRadius: (config.tileRadius ?? 4) + 'px',\n pointerEvents: 'none',\n zIndex: 5,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '14px',\n fontWeight: '600',\n color: 'rgba(59, 91, 219, 0.8)',\n userSelect: 'none',\n }\"\n >{{ drawGhostRect.label }}</div>\n <div\n v-for=\"tile in rendered\"\n :key=\"tile.id\"\n :data-griddle-tile=\"tile.id\"\n :class=\"['griddle-tile', {\n 'griddle-dragging': drag?.tileId === tile.id || pinDrag?.tileId === tile.id || (groupDrag !== null && groupDragSet.has(tile.id)),\n 'griddle-resizing': resize?.tileId === tile.id,\n 'griddle-selected': selection.has(tile.id),\n }]\"\n :style=\"tileStyle(tile)\"\n @pointerdown=\"(e) => onTilePointerDown(e, tile)\"\n :ref=\"(el) => registerNode(tile.id, el as HTMLDivElement | null)\"\n >\n <slot name=\"tile\" :tile=\"tile\" :selected=\"selection.has(tile.id)\" />\n <template v-if=\"tile.resizable !== false\">\n <div\n v-for=\"c in tileHandles(tile)\"\n :key=\"c\"\n :data-griddle-handle=\"c\"\n :style=\"handleStyle(c)\"\n @pointerdown=\"(e) => onResizeHandleDown(e, tile, c)\"\n ></div>\n </template>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue';\nimport type { CameraState, Corner, Tile } from '@griddle/core';\nimport GriddleLoopGrid from './LoopGrid.vue';\nimport {\n visibleRange,\n visibleTiles,\n gridContentSize,\n DragController,\n GroupDragController,\n computeTileLayout,\n resolveStickyStacking,\n isOutOfFlow,\n pixelsToPin,\n} from '@griddle/core';\nimport type { TileLayout } from '@griddle/core';\nimport type { GriddleApi } from './useGriddle.js';\nimport { animateReposition, liftTransition } from './animation.js';\n\nconst props = defineProps<{\n api: GriddleApi;\n className?: string;\n height?: number | string;\n showGrid?: boolean;\n /** Controlled selection. If omitted, managed internally. */\n selection?: Set<string>;\n}>();\n\nconst emit = defineEmits<{\n (e: 'selectionChange', selection: Set<string>): void;\n (e: 'drawCreate', rect: { col: number; row: number; w: number; h: number }): void;\n (e: 'dragStart', tileId: string): void;\n (e: 'dragEnd', tileId: string, committed: boolean): void;\n (e: 'resizeStart', tileId: string): void;\n (e: 'resizeEnd', tileId: string, committed: boolean): void;\n (e: 'cameraChange', camera: CameraState): void;\n}>();\n\n/** Loop mode delegates rendering to GriddleLoopGrid. */\nconst loopOn = computed(() => props.api.config.value.loop?.enabled === true);\n\nconst scrollEl = ref<HTMLDivElement | null>(null);\nconst viewport = ref({ scrollX: 0, scrollY: 0, width: 1000, height: 800 });\n\nconst config = computed(() => props.api.config.value);\nconst gap = computed(() => config.value.gap ?? 0);\nconst halfGap = computed(() => gap.value / 2);\nconst colSize = computed(() => config.value.unitWidth + gap.value);\nconst rowSize = computed(() => config.value.unitHeight + gap.value);\n\nconst range = computed(() => visibleRange(config.value, viewport.value, 4));\nconst rendered = computed(() => visibleTiles(props.api.tiles.value, range.value));\nconst contentSize = computed(() => gridContentSize(config.value, props.api.tiles.value));\n\nconst scrollStyle = computed(() => {\n // 'none' scroll mode: the grid sizes to content and lets the host page own\n // scrolling/panning — no internal scroll box, no touch-action lock.\n const contained = config.value.scroll !== 'none';\n const style: Record<string, string | number> = {\n position: 'relative',\n overflow: contained ? 'auto' : 'visible',\n height: contained ? (props.height ?? '100%') : (props.height ?? 'auto'),\n };\n if (contained) style.touchAction = 'none';\n return style;\n});\n\nconst contentStyle = computed(() => {\n const showGrid = props.showGrid !== false;\n const bg = showGrid\n ? {\n backgroundImage: `linear-gradient(to right, rgba(0,0,0,0.08) 1px, transparent 1px), linear-gradient(to bottom, rgba(0,0,0,0.08) 1px, transparent 1px)`,\n backgroundSize: `${colSize.value}px ${rowSize.value}px`,\n }\n : {};\n return {\n position: 'relative' as const,\n width: contentSize.value.width || '100%',\n height: contentSize.value.height || '100%',\n minWidth: '100%',\n minHeight: '100%',\n // Expose tile radius as a CSS variable so user tile content can pick it up.\n ['--griddle-tile-radius' as string]: (config.value.tileRadius ?? 4) + 'px',\n ...bg,\n };\n});\n\n// Selection state\nconst internalSelection = ref<Set<string>>(new Set());\nconst selection = computed(() => props.selection ?? internalSelection.value);\nconst groupDragSet = computed(() => new Set(groupDrag.value?.tileIds ?? []));\nfunction setSelection(next: Set<string>) {\n if (!props.selection) internalSelection.value = next;\n emit('selectionChange', next);\n}\n\nconst DEFAULT_DRAG_IGNORE = 'a, button, input, textarea, select, [contenteditable]';\nconst DRAG_START_THRESHOLD_PX = 12;\n\nconst dragController = new DragController(props.api.grid);\nconst groupDragController = new GroupDragController(props.api.grid);\n\ninterface DragVisual {\n tileId: string;\n pickupCol: number;\n pickupRow: number;\n deltaX: number;\n deltaY: number;\n indicatorCol: number | null;\n indicatorRow: number | null;\n}\nconst drag = ref<DragVisual | null>(null);\nlet dragStartPointerX = 0;\nlet dragStartPointerY = 0;\n\ninterface GroupDragVisual {\n tileIds: string[];\n deltaX: number;\n deltaY: number;\n committedDcol: number;\n committedDrow: number;\n}\nconst groupDrag = ref<GroupDragVisual | null>(null);\n\ninterface PinDragState {\n tileId: string;\n startPinPx: { x: number; y: number };\n startPointerX: number;\n startPointerY: number;\n}\nconst pinDrag = ref<PinDragState | null>(null);\n\ninterface ResizeState {\n tileId: string;\n corner: Corner;\n startPointerX: number;\n startPointerY: number;\n startW: number;\n startH: number;\n startCol: number;\n startRow: number;\n previewW: number;\n previewH: number;\n previewCol: number;\n previewRow: number;\n}\nconst resize = ref<ResizeState | null>(null);\n\ninterface DrawState {\n anchorCol: number;\n anchorRow: number;\n currentCol: number;\n currentRow: number;\n}\nconst drawState = ref<DrawState | null>(null);\n\ninterface PendingDragState {\n pointerId: number;\n tileId: string;\n tileElement: HTMLDivElement;\n startPointerX: number;\n startPointerY: number;\n mode: 'pin' | 'group' | 'single';\n groupTileIds: string[];\n}\nlet pendingDrag: PendingDragState | null = null;\n\nfunction beginPendingDrag(pending: PendingDragState): boolean {\n const tile = props.api.grid.getTile(pending.tileId);\n if (!tile) return false;\n\n // Capture only once movement proves this is a drag. Capturing on\n // pointer-down retargets pointer-up away from editable descendants and turns\n // ordinary clicks into drag start/end cycles.\n try {\n pending.tileElement.setPointerCapture(pending.pointerId);\n } catch {\n // The pointer may already have ended or the tile may have unmounted.\n return false;\n }\n\n dragStartPointerX = pending.startPointerX;\n dragStartPointerY = pending.startPointerY;\n\n if (pending.mode === 'pin') {\n const layout = computeTileLayout({\n tile,\n config: config.value,\n scrollX: viewport.value.scrollX,\n scrollY: viewport.value.scrollY,\n viewportWidth: viewport.value.width,\n viewportHeight: viewport.value.height,\n });\n const startPinPx =\n tile.position === 'fixed'\n ? { x: layout.left - viewport.value.scrollX, y: layout.top - viewport.value.scrollY }\n : { x: layout.left, y: layout.top };\n pinDrag.value = {\n tileId: tile.id,\n startPinPx,\n startPointerX: pending.startPointerX,\n startPointerY: pending.startPointerY,\n };\n emit('dragStart', tile.id);\n return true;\n }\n\n if (pending.mode === 'group') {\n if (!groupDragController.start(pending.groupTileIds)) return false;\n groupDrag.value = {\n tileIds: pending.groupTileIds,\n deltaX: 0,\n deltaY: 0,\n committedDcol: 0,\n committedDrow: 0,\n };\n emit('dragStart', tile.id);\n return true;\n }\n\n if (!dragController.start(tile.id)) return false;\n drag.value = {\n tileId: tile.id,\n pickupCol: tile.col,\n pickupRow: tile.row,\n deltaX: 0,\n deltaY: 0,\n indicatorCol: tile.col,\n indicatorRow: tile.row,\n };\n emit('dragStart', tile.id);\n return true;\n}\n\nfunction onTilePointerDown(e: PointerEvent, tile: Tile) {\n if (e.button !== 0) return;\n if (tile.draggable === false) return;\n if ((e.target as HTMLElement).dataset.griddleHandle) return;\n\n const ignoreSelector = config.value.dragIgnoreFrom ?? DEFAULT_DRAG_IGNORE;\n if (ignoreSelector && (e.target as HTMLElement).closest(ignoreSelector)) return;\n\n const metaKey = e.metaKey || e.ctrlKey;\n\n // Out-of-flow tiles get free-pixel drag (no selection).\n if (config.value.enablePositioning && isOutOfFlow(tile)) {\n pendingDrag = {\n pointerId: e.pointerId,\n tileId: tile.id,\n tileElement: e.currentTarget as HTMLDivElement,\n startPointerX: e.clientX,\n startPointerY: e.clientY,\n mode: 'pin',\n groupTileIds: [],\n };\n e.stopPropagation();\n return;\n }\n\n // Cmd/Ctrl+click toggles selection without starting a drag.\n if (metaKey) {\n e.preventDefault();\n const next = new Set(selection.value);\n if (next.has(tile.id)) {\n next.delete(tile.id);\n } else {\n next.add(tile.id);\n }\n setSelection(next);\n e.stopPropagation();\n return;\n }\n\n const tileIsSelected = selection.value.has(tile.id);\n\n if (!tileIsSelected) {\n setSelection(new Set([tile.id]));\n }\n\n // Defer capture and drag state until the pointer crosses the movement\n // threshold. A stationary pointer-down/up remains a normal click, including\n // when it starts inside contenteditable tile content.\n const effectiveSelection = tileIsSelected ? selection.value : new Set([tile.id]);\n const groupTileIds = Array.from(effectiveSelection);\n pendingDrag = {\n pointerId: e.pointerId,\n tileId: tile.id,\n tileElement: e.currentTarget as HTMLDivElement,\n startPointerX: e.clientX,\n startPointerY: e.clientY,\n mode: groupTileIds.length > 1 ? 'group' : 'single',\n groupTileIds,\n };\n e.stopPropagation();\n}\n\nfunction onBackgroundPointerDown(e: PointerEvent) {\n if ((e.target as HTMLElement).closest('[data-griddle-tile]')) return;\n // Draw-to-create is gated by config (default on). When disabled, empty-space\n // pointer-downs are a no-op so the host page keeps its native scroll/pan.\n if (config.value.interactive?.drawToCreate === false) return;\n setSelection(new Set());\n\n const el = scrollEl.value;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const x = e.clientX - rect.left + el.scrollLeft;\n const y = e.clientY - rect.top + el.scrollTop;\n const col = Math.floor(x / colSize.value);\n const row = Math.floor(y / rowSize.value);\n drawState.value = { anchorCol: col, anchorRow: row, currentCol: col, currentRow: row };\n (el as HTMLDivElement).setPointerCapture(e.pointerId);\n}\n\nfunction onResizeHandleDown(e: PointerEvent, tile: Tile, c: Corner) {\n if (tile.resizable === false) return;\n (e.currentTarget as HTMLDivElement).setPointerCapture(e.pointerId);\n resize.value = {\n tileId: tile.id,\n corner: c,\n startPointerX: e.clientX,\n startPointerY: e.clientY,\n startW: tile.w,\n startH: tile.h,\n startCol: tile.col,\n startRow: tile.row,\n previewW: tile.w,\n previewH: tile.h,\n previewCol: tile.col,\n previewRow: tile.row,\n };\n emit('resizeStart', tile.id);\n e.stopPropagation();\n}\n\nfunction onPointerMove(e: PointerEvent) {\n if (drawState.value) {\n const el = scrollEl.value;\n if (el) {\n const rect = el.getBoundingClientRect();\n const x = e.clientX - rect.left + el.scrollLeft;\n const y = e.clientY - rect.top + el.scrollTop;\n const col = Math.max(0, Math.floor(x / colSize.value));\n const row = Math.max(0, Math.floor(y / rowSize.value));\n drawState.value = { ...drawState.value, currentCol: col, currentRow: row };\n }\n return;\n }\n\n const pending = pendingDrag;\n if (pending && e.pointerId === pending.pointerId) {\n const distance = Math.hypot(\n e.clientX - pending.startPointerX,\n e.clientY - pending.startPointerY,\n );\n if (distance <= DRAG_START_THRESHOLD_PX) return;\n\n pendingDrag = null;\n if (!beginPendingDrag(pending)) return;\n e.preventDefault();\n }\n\n const pd = pinDrag.value;\n const gd = groupDrag.value;\n const d = drag.value;\n const r = resize.value;\n if (pd) {\n const dx = e.clientX - pd.startPointerX;\n const dy = e.clientY - pd.startPointerY;\n const newPinPx = { x: pd.startPinPx.x + dx, y: pd.startPinPx.y + dy };\n const newPin = pixelsToPin(newPinPx, config.value);\n props.api.grid.setTilePinned(pd.tileId, newPin);\n }\n if (gd) {\n const dx = e.clientX - dragStartPointerX;\n const dy = e.clientY - dragStartPointerY;\n const dcol = Math.round(dx / colSize.value);\n const drow = Math.round(dy / rowSize.value);\n const result = groupDragController.update({ dcol, drow });\n groupDrag.value = {\n ...gd,\n deltaX: dx,\n deltaY: dy,\n committedDcol: result.indicatorDelta?.dcol ?? gd.committedDcol,\n committedDrow: result.indicatorDelta?.drow ?? gd.committedDrow,\n };\n if (result.changed) syncTiles();\n }\n if (d) {\n const dx = e.clientX - dragStartPointerX;\n const dy = e.clientY - dragStartPointerY;\n const candidateCol = d.pickupCol + Math.round(dx / colSize.value);\n const candidateRow = d.pickupRow + Math.round(dy / rowSize.value);\n const result = dragController.update({ col: candidateCol, row: candidateRow });\n drag.value = {\n ...d,\n deltaX: dx,\n deltaY: dy,\n indicatorCol: result.indicatorCell ? result.indicatorCell.col : null,\n indicatorRow: result.indicatorCell ? result.indicatorCell.row : null,\n };\n // DragController.restoreTiles() doesn't emit change events, so when the\n // candidate cell changes (especially returning to pickup), force-sync the\n // reactive tiles ref so the FLIP animation picks up displaced tile resets.\n if (result.changed) syncTiles();\n }\n if (r) {\n const dx = e.clientX - r.startPointerX;\n const dy = e.clientY - r.startPointerY;\n let dw = 0, dh = 0, dcol = 0, drow = 0;\n const stepsX = Math.round(dx / colSize.value);\n const stepsY = Math.round(dy / rowSize.value);\n if (r.corner === 'se' || r.corner === 'ne') dw = stepsX;\n if (r.corner === 'se' || r.corner === 'sw') dh = stepsY;\n if (r.corner === 'sw' || r.corner === 'nw') { dw = -stepsX; dcol = stepsX; }\n if (r.corner === 'ne' || r.corner === 'nw') { dh = -stepsY; drow = stepsY; }\n const tile = props.api.grid.getTile(r.tileId);\n const minW = tile?.minW ?? 1;\n const minH = tile?.minH ?? 1;\n const maxW = tile?.maxW ?? Infinity;\n const maxH = tile?.maxH ?? Infinity;\n const nW = Math.min(maxW, Math.max(minW, r.startW + dw));\n const nH = Math.min(maxH, Math.max(minH, r.startH + dh));\n const nC = r.startCol + dcol;\n const nR = r.startRow + drow;\n if (nW !== r.previewW || nH !== r.previewH || nC !== r.previewCol || nR !== r.previewRow) {\n resize.value = { ...r, previewW: nW, previewH: nH, previewCol: nC, previewRow: nR };\n }\n }\n}\n\nfunction syncTiles() {\n // DragController/GroupDragController may restore grid snapshots without\n // emitting change events. Force-sync the reactive tiles ref so the UI\n // reflects the grid's true state after a drag ends.\n props.api.tiles.value = props.api.grid.tiles;\n props.api.version.value++;\n}\n\nfunction onPointerUp(e: PointerEvent) {\n if (pendingDrag?.pointerId === e.pointerId) {\n pendingDrag = null;\n return;\n }\n if (drawState.value) {\n const ds = drawState.value;\n const col = Math.min(ds.anchorCol, ds.currentCol);\n const row = Math.min(ds.anchorRow, ds.currentRow);\n const w = Math.max(1, Math.abs(ds.currentCol - ds.anchorCol) + 1);\n const h = Math.max(1, Math.abs(ds.currentRow - ds.anchorRow) + 1);\n drawState.value = null;\n emit('drawCreate', { col, row, w, h });\n return;\n }\n if (pinDrag.value) {\n const tileId = pinDrag.value.tileId;\n pinDrag.value = null;\n emit('dragEnd', tileId, true);\n }\n if (groupDrag.value) {\n const tileIds = groupDrag.value.tileIds;\n const { committed } = groupDragController.end();\n groupDrag.value = null;\n syncTiles();\n const firstId = tileIds[0];\n if (firstId !== undefined) emit('dragEnd', firstId, committed);\n }\n if (drag.value) {\n const tileId = drag.value.tileId;\n const { committed } = dragController.end();\n drag.value = null;\n syncTiles();\n emit('dragEnd', tileId, committed);\n }\n const r = resize.value;\n if (r) {\n const t = props.api.grid.getTile(r.tileId);\n let committed = false;\n if (t) {\n if (r.previewCol !== t.col || r.previewRow !== t.row) {\n props.api.moveTile(r.tileId, { col: r.previewCol, row: r.previewRow });\n }\n if (r.previewW !== t.w || r.previewH !== t.h) {\n committed = props.api.resizeTile(r.tileId, { w: r.previewW, h: r.previewH });\n } else {\n committed = r.previewCol !== r.startCol || r.previewRow !== r.startRow\n || r.previewW !== r.startW || r.previewH !== r.startH;\n }\n }\n resize.value = null;\n emit('resizeEnd', r.tileId, committed);\n }\n}\n\nfunction updateViewport() {\n const el = scrollEl.value;\n if (!el) return;\n viewport.value = {\n scrollX: el.scrollLeft,\n scrollY: el.scrollTop,\n width: el.clientWidth,\n height: el.clientHeight,\n };\n}\n\nfunction onKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape') setSelection(new Set());\n}\n\nlet ro: ResizeObserver | null = null;\nonMounted(() => {\n updateViewport();\n // scrollEl is absent while loop mode delegates to GriddleLoopGrid.\n const el = scrollEl.value;\n if (el) {\n el.addEventListener('scroll', updateViewport, { passive: true });\n ro = new ResizeObserver(updateViewport);\n ro.observe(el);\n }\n window.addEventListener('pointermove', onPointerMove);\n window.addEventListener('pointerup', onPointerUp);\n window.addEventListener('pointercancel', onPointerUp);\n window.addEventListener('keydown', onKeyDown);\n});\nonBeforeUnmount(() => {\n pendingDrag = null;\n const el = scrollEl.value;\n if (el) el.removeEventListener('scroll', updateViewport);\n ro?.disconnect();\n window.removeEventListener('pointermove', onPointerMove);\n window.removeEventListener('pointerup', onPointerUp);\n window.removeEventListener('pointercancel', onPointerUp);\n window.removeEventListener('keydown', onKeyDown);\n});\n\nconst tileNodes = new Map<string, HTMLDivElement>();\nconst prevRects = new Map<string, { x: number; y: number }>();\nfunction registerNode(id: string, el: HTMLDivElement | null) {\n if (el) tileNodes.set(id, el);\n else tileNodes.delete(id);\n}\n\nwatch(() => props.api.version.value, async () => {\n await nextTick();\n const draggerId = drag.value?.tileId ?? null;\n const gdSet = groupDragSet.value;\n for (const t of props.api.tiles.value) {\n const x = t.col * colSize.value + halfGap.value;\n const y = t.row * rowSize.value + halfGap.value;\n if (t.id === draggerId || gdSet.has(t.id)) {\n prevRects.set(t.id, { x, y });\n continue;\n }\n const p = prevRects.get(t.id);\n const node = tileNodes.get(t.id);\n if (p && node) {\n const dx = p.x - x;\n const dy = p.y - y;\n if (dx !== 0 || dy !== 0) {\n animateReposition(node, dx, dy, config.value.animation);\n }\n }\n prevRects.set(t.id, { x, y });\n }\n});\n\n// Compute layouts for all rendered tiles in one pass so resolveStickyStacking\n// can see every sticky tile and adjust them as a group. Recomputes whenever\n// rendered, config, viewport, drag, resize, or pinDrag change.\nconst tileLayouts = computed(() => {\n const out = new Map<string, TileLayout>();\n const stickyEntries: { tile: Tile; layout: TileLayout }[] = [];\n const gd = groupDrag.value;\n const gdIds = groupDragSet.value;\n for (const tile of rendered.value) {\n let layout: TileLayout;\n if (resize.value?.tileId === tile.id) {\n const w = resize.value.previewW;\n const h = resize.value.previewH;\n layout = {\n left: resize.value.previewCol * colSize.value + halfGap.value,\n top: resize.value.previewRow * rowSize.value + halfGap.value,\n width: w * config.value.unitWidth + (w - 1) * gap.value,\n height: h * config.value.unitHeight + (h - 1) * gap.value,\n zIndex: 10,\n effective: 'static',\n };\n } else if (drag.value?.tileId === tile.id) {\n const d = drag.value;\n layout = {\n left: d.pickupCol * colSize.value + halfGap.value,\n top: d.pickupRow * rowSize.value + halfGap.value,\n width: tile.w * config.value.unitWidth + (tile.w - 1) * gap.value,\n height: tile.h * config.value.unitHeight + (tile.h - 1) * gap.value,\n transform: `translate(${d.deltaX}px, ${d.deltaY}px)`,\n zIndex: 20,\n effective: 'static',\n };\n } else if (gd && gdIds.has(tile.id)) {\n const pickup = groupDragController.pickupCell(tile.id);\n const left = (pickup ? pickup.col * colSize.value : tile.col * colSize.value) + halfGap.value;\n const top = (pickup ? pickup.row * rowSize.value : tile.row * rowSize.value) + halfGap.value;\n layout = {\n left,\n top,\n width: tile.w * config.value.unitWidth + (tile.w - 1) * gap.value,\n height: tile.h * config.value.unitHeight + (tile.h - 1) * gap.value,\n transform: `translate(${gd.deltaX}px, ${gd.deltaY}px)`,\n zIndex: 20,\n effective: 'static',\n };\n } else {\n layout = computeTileLayout({\n tile,\n config: config.value,\n scrollX: viewport.value.scrollX,\n scrollY: viewport.value.scrollY,\n viewportWidth: viewport.value.width,\n viewportHeight: viewport.value.height,\n });\n if (layout.effective === 'sticky') {\n stickyEntries.push({ tile, layout });\n }\n }\n out.set(tile.id, layout);\n }\n if (stickyEntries.length > 1) resolveStickyStacking(stickyEntries);\n return out;\n});\n\nfunction tileStyle(tile: Tile) {\n const isDragging = drag.value?.tileId === tile.id;\n const isGroupDragging = groupDragSet.value.has(tile.id) && groupDrag.value !== null;\n const isPinDragging = pinDrag.value?.tileId === tile.id;\n const isResizing = resize.value?.tileId === tile.id;\n const isSelected = selection.value.has(tile.id);\n const layout = tileLayouts.value.get(tile.id) ?? {\n left: 0, top: 0, width: 0, height: 0, zIndex: 1, effective: 'static' as const,\n };\n const lifted = isDragging || isPinDragging || isGroupDragging;\n return {\n position: 'absolute' as const,\n left: layout.left + 'px',\n top: layout.top + 'px',\n width: layout.width + 'px',\n height: layout.height + 'px',\n boxSizing: 'border-box' as const,\n cursor: lifted ? 'grabbing' : 'grab',\n userSelect: 'none' as const,\n zIndex: layout.zIndex,\n opacity: lifted || isResizing ? 0.85 : 1,\n willChange: 'transform, translate',\n transform: layout.transform ?? '',\n filter: lifted ? 'drop-shadow(0 8px 16px rgba(0,0,0,0.18))' : '',\n transition: lifted ? liftTransition(config.value.animation) : '',\n boxShadow: isSelected\n ? '0 0 0 3px rgba(59, 91, 219, 0.85), inset 0 0 0 1px rgba(59, 91, 219, 0.3)'\n : '',\n borderRadius: (config.value.tileRadius ?? 4) + 'px',\n };\n}\n\n\nconst indicatorRect = computed(() => {\n const d = drag.value;\n if (!d || d.indicatorCol === null || d.indicatorRow === null) return null;\n const t = props.api.grid.getTile(d.tileId);\n if (!t) return null;\n return {\n left: d.indicatorCol * colSize.value + halfGap.value,\n top: d.indicatorRow * rowSize.value + halfGap.value,\n width: t.w * config.value.unitWidth + (t.w - 1) * gap.value,\n height: t.h * config.value.unitHeight + (t.h - 1) * gap.value,\n };\n});\n\nconst drawGhostRect = computed(() => {\n const ds = drawState.value;\n if (!ds) return null;\n const col = Math.min(ds.anchorCol, ds.currentCol);\n const row = Math.min(ds.anchorRow, ds.currentRow);\n const w = Math.max(1, Math.abs(ds.currentCol - ds.anchorCol) + 1);\n const h = Math.max(1, Math.abs(ds.currentRow - ds.anchorRow) + 1);\n return {\n left: col * colSize.value + halfGap.value,\n top: row * rowSize.value + halfGap.value,\n width: w * config.value.unitWidth + (w - 1) * gap.value,\n height: h * config.value.unitHeight + (h - 1) * gap.value,\n label: `${w}×${h}`,\n };\n});\n\nfunction tileHandles(tile: Tile): Corner[] {\n return tile.resizeHandles ?? config.value.resizeHandles ?? ['se'];\n}\n\nfunction handleStyle(c: Corner) {\n const size = 12;\n const base = {\n position: 'absolute' as const,\n width: size + 'px',\n height: size + 'px',\n background: 'rgba(60,60,60,0.7)',\n border: '2px solid white',\n borderRadius: '3px',\n cursor: `${c}-resize`,\n touchAction: 'none' as const,\n } as Record<string, unknown>;\n if (c === 'nw') return { ...base, top: -size / 2 + 'px', left: -size / 2 + 'px' };\n if (c === 'ne') return { ...base, top: -size / 2 + 'px', right: -size / 2 + 'px' };\n if (c === 'sw') return { ...base, bottom: -size / 2 + 'px', left: -size / 2 + 'px' };\n return { ...base, bottom: -size / 2 + 'px', right: -size / 2 + 'px' };\n}\n\nconst className = computed(() => props.className ?? '');\n</script>\n","// Vue composable that wraps a Grid instance with reactive state.\n\nimport { onScopeDispose, ref, shallowRef } from 'vue';\nimport { Grid } from '@griddle/core';\nimport type { GridConfig, GridSnapshot, ReflowOptions, Tile } from '@griddle/core';\n\nexport interface UseGriddleInit {\n config: GridConfig;\n tiles?: Tile[];\n}\n\nexport function useGriddle(init: UseGriddleInit) {\n const grid = new Grid(init.config, init.tiles ?? []);\n\n // Reactive mirrors of tiles and config. We re-assign on changes.\n const tiles = shallowRef<Tile[]>(grid.tiles);\n const config = shallowRef<GridConfig>(grid.config);\n const version = ref(0);\n\n const off = grid.changes.on(() => {\n tiles.value = grid.tiles;\n config.value = grid.config;\n version.value++;\n });\n onScopeDispose(off);\n\n const api = {\n grid,\n tiles,\n config,\n version,\n moveTile: (id: string, target: { col: number; row: number }) => grid.moveTile(id, target),\n resizeTile: (id: string, size: { w: number; h: number }) => grid.resizeTile(id, size),\n addTile: (t: Tile) => grid.addTile(t),\n removeTile: (id: string) => grid.removeTile(id),\n reflow: (options: ReflowOptions) => grid.reflow(options),\n updateConfig: (patch: Partial<GridConfig>) => grid.updateConfig(patch),\n toJSON: () => grid.toJSON(),\n loadJSON: (snap: GridSnapshot) => grid.loadJSON(snap),\n };\n return api;\n}\n\nexport type GriddleApi = ReturnType<typeof useGriddle>;\n"],"names":["DEFAULT_DRAG_IGNORE","PAN_THRESHOLD_PX","props","__props","emit","__emit","viewportEl","ref","planeEl","config","computed","loop","resolveLoop","editable","_a","gap","halfGap","colSize","rowSize","period","loopPeriod","pan","PanController","watch","l","view","lastCam","raf","resizeObserver","onWheel","k","frame","now","st","plane","el","cxCell","cyCell","cur","instances","bufX","bufY","loopInstances","panGesture","suppressClick","onContainerPointerDown","onTile","setSelection","ignoreSelector","onClickCapture","internalSelection","selection","next","dragController","DragController","drag","dragStartPointerX","dragStartPointerY","resize","syncTiles","isBase","inst","isGhost","onTilePointerDown","tile","onResizeHandleDown","c","baseLeft","baseTop","onPointerMove","d","dx","dy","candidate","result","r","dw","dh","dcol","drow","stepsX","stepsY","minW","minH","maxW","maxH","nW","nH","nC","nR","onPointerUp","tileId","committed","t","target","onKeyDown","onMounted","measure","onBeforeUnmount","tileNodes","prevRects","registerNode","key","nextTick","draggerId","seen","x","y","p","node","animateReposition","viewportStyle","bg","planeStyle","instanceStyle","isResizingInst","left","top","width","heightPx","ghost","isSelected","draggedTile","dragOverlayStyle","indicatorRect","tileHandles","handleStyle","base","className","_createElementBlock","_createElementVNode","_normalizeStyle","_Fragment","_renderList","_normalizeClass","e","_renderSlot","_ctx","_openBlock","DRAG_START_THRESHOLD_PX","loopOn","scrollEl","viewport","range","visibleRange","rendered","visibleTiles","contentSize","gridContentSize","scrollStyle","contained","style","contentStyle","groupDragSet","groupDrag","groupDragController","GroupDragController","pinDrag","drawState","pendingDrag","beginPendingDrag","pending","layout","computeTileLayout","startPinPx","metaKey","isOutOfFlow","tileIsSelected","effectiveSelection","groupTileIds","onBackgroundPointerDown","rect","col","row","pd","gd","newPinPx","newPin","pixelsToPin","_b","candidateCol","candidateRow","ds","w","h","tileIds","firstId","updateViewport","ro","id","gdSet","tileLayouts","out","stickyEntries","gdIds","pickup","resolveStickyStacking","tileStyle","isDragging","isGroupDragging","isPinDragging","isResizing","_c","lifted","liftTransition","drawGhostRect","_createBlock","GriddleLoopGrid","_cache","s","cam","_withCtx","slotProps","_toDisplayString","useGriddle","init","grid","Grid","tiles","shallowRef","version","off","onScopeDispose","size","options","patch","snap"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/LoopGrid.vue","../src/GriddleGrid.vue","../src/useGriddle.ts"],"sourcesContent":["<template>\n <div\n ref=\"viewportEl\"\n :class=\"className\"\n :style=\"viewportStyle\"\n @pointerdown=\"onContainerPointerDown\"\n @click.capture=\"onClickCapture\"\n >\n <div ref=\"planeEl\" :style=\"planeStyle\">\n <div\n v-if=\"indicatorRect\"\n class=\"griddle-drop-indicator\"\n :style=\"{\n position: 'absolute',\n left: indicatorRect.left + 'px',\n top: indicatorRect.top + 'px',\n width: indicatorRect.width + 'px',\n height: indicatorRect.height + 'px',\n boxSizing: 'border-box',\n border: '2px dashed rgba(59, 91, 219, 0.55)',\n background: 'rgba(59, 91, 219, 0.08)',\n borderRadius: (config.tileRadius ?? 4) + 'px',\n pointerEvents: 'none',\n zIndex: 5,\n }\"\n ></div>\n <template v-for=\"inst in instances\" :key=\"inst.key\">\n <div\n v-if=\"!(drag && inst.tile.id === drag.tileId)\"\n :data-griddle-tile=\"inst.tile.id\"\n :data-griddle-instance=\"inst.key\"\n :data-griddle-ghost=\"isGhost(inst) ? '' : undefined\"\n :aria-hidden=\"isBase(inst) ? undefined : true\"\n :class=\"['griddle-tile', {\n 'griddle-resizing': resize?.instanceKey === inst.key,\n 'griddle-selected': editable && isBase(inst) && selection.has(inst.tile.id),\n }]\"\n :style=\"instanceStyle(inst)\"\n :ref=\"(el) => registerNode(inst.key, el as HTMLDivElement | null)\"\n @pointerdown=\"(e) => onTilePointerDown(e, inst)\"\n >\n <slot name=\"tile\" :tile=\"inst.tile\" :selected=\"editable && isBase(inst) && selection.has(inst.tile.id)\" />\n <template v-if=\"editable && isBase(inst) && inst.tile.resizable !== false\">\n <div\n v-for=\"c in tileHandles(inst.tile)\"\n :key=\"c\"\n :data-griddle-handle=\"c\"\n :style=\"handleStyle(c)\"\n @pointerdown=\"(e) => onResizeHandleDown(e, inst, c)\"\n ></div>\n </template>\n </div>\n </template>\n <div\n v-if=\"drag && draggedTile\"\n :data-griddle-tile=\"draggedTile.id\"\n class=\"griddle-tile griddle-dragging\"\n :style=\"dragOverlayStyle\"\n >\n <slot name=\"tile\" :tile=\"draggedTile\" :selected=\"selection.has(draggedTile.id)\" />\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n// Loop-mode renderer (\"object looping\") — see @griddle/core loop.ts for the\n// coordinate model. Mirrors the React GriddleLoopGrid: an overflow-hidden\n// viewport, a transform-translated plane driven by an unbounded camera, and\n// NO native scrolling (wheel deltas feed the camera directly).\nimport { computed, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue';\nimport type { CameraState, CellPos, Corner, Tile } from '@griddle/core';\nimport {\n DragController,\n PanController,\n loopInstances,\n loopPeriod,\n resolveLoop,\n} from '@griddle/core';\nimport type { LoopTileInstance } from '@griddle/core';\nimport type { GriddleApi } from './useGriddle.js';\nimport { animateReposition } from './animation.js';\nimport { resolveResizePreview } from './interaction.js';\n\nconst props = defineProps<{\n api: GriddleApi;\n className?: string;\n height?: number | string;\n showGrid?: boolean;\n selection?: Set<string>;\n}>();\n\nconst emit = defineEmits<{\n (e: 'selectionChange', selection: Set<string>): void;\n (e: 'dragStart', tileId: string): void;\n (e: 'dragEnd', tileId: string, committed: boolean): void;\n (e: 'resizeStart', tileId: string): void;\n (e: 'resizeEnd', tileId: string, committed: boolean): void;\n (e: 'cameraChange', camera: CameraState): void;\n}>();\n\nconst DEFAULT_DRAG_IGNORE = 'a, button, input, textarea, select, [contenteditable]';\nconst PAN_THRESHOLD_PX = 4;\n\nconst viewportEl = ref<HTMLDivElement | null>(null);\nconst planeEl = ref<HTMLDivElement | null>(null);\n\nconst config = computed(() => props.api.config.value);\nconst loop = computed(() => resolveLoop(config.value));\nconst editable = computed(() => loop.value?.interaction === 'edit');\nconst gap = computed(() => config.value.gap ?? 0);\nconst halfGap = computed(() => gap.value / 2);\nconst colSize = computed(() => config.value.unitWidth + gap.value);\nconst rowSize = computed(() => config.value.unitHeight + gap.value);\nconst period = computed(() => loopPeriod(config.value, props.api.tiles.value));\n\n// ---- camera plumbing ------------------------------------------------------\nconst pan = new PanController();\nwatch(loop, (l) => {\n if (l) pan.setPhysics({ friction: l.friction, ease: l.ease, maxVelocity: l.maxVelocity });\n}, { immediate: true });\n\nconst view = ref({ cxCell: 0, cyCell: 0, vw: 1000, vh: 800 });\nlet lastCam: CameraState | null = null;\nlet raf = 0;\nlet resizeObserver: ResizeObserver | null = null;\n\nfunction onWheel(e: WheelEvent) {\n e.preventDefault();\n const k = e.deltaMode === 1 ? 16 : e.deltaMode === 2 ? 100 : 1;\n pan.scrollBy(e.deltaX * k, e.deltaY * k);\n}\n\nfunction frame(now: number) {\n raf = requestAnimationFrame(frame);\n const st = pan.tick(now);\n\n const plane = planeEl.value;\n if (plane) {\n plane.style.transform = `translate3d(${-st.x}px, ${-st.y}px, 0)`;\n }\n const el = viewportEl.value;\n if (el && props.showGrid !== false) {\n el.style.backgroundPosition = `${-st.x % colSize.value}px ${-st.y % rowSize.value}px`;\n }\n\n const cxCell = Math.floor(st.x / colSize.value);\n const cyCell = Math.floor(st.y / rowSize.value);\n const cur = view.value;\n if (cxCell !== cur.cxCell || cyCell !== cur.cyCell) {\n view.value = { ...cur, cxCell, cyCell };\n }\n\n if (\n !lastCam || lastCam.x !== st.x || lastCam.y !== st.y ||\n lastCam.isMoving !== st.isMoving || lastCam.isDragging !== st.isDragging\n ) {\n lastCam = st;\n emit('cameraChange', st);\n }\n}\n\nconst instances = computed(() => {\n void props.api.version.value; // re-run on grid changes\n const bufX = 2 * colSize.value;\n const bufY = 2 * rowSize.value;\n return loopInstances(config.value, props.api.tiles.value, {\n x: view.value.cxCell * colSize.value - bufX,\n y: view.value.cyCell * rowSize.value - bufY,\n width: view.value.vw + colSize.value + 2 * bufX,\n height: view.value.vh + rowSize.value + 2 * bufY,\n });\n});\n\n// ---- pan gesture ----------------------------------------------------------\nlet panGesture: { pointerId: number; startX: number; startY: number; moved: boolean } | null = null;\nlet suppressClick = false;\n\nfunction onContainerPointerDown(e: PointerEvent) {\n const onTile = !!(e.target as HTMLElement).closest('[data-griddle-tile]');\n if (editable.value && !onTile) setSelection(new Set());\n // Tiles that start drags stopPropagation, so reaching here from a tile\n // means it was not draggable — panning is the right fallback.\n if (!loop.value?.dragPan || e.button !== 0) return;\n const ignoreSelector = config.value.dragIgnoreFrom ?? DEFAULT_DRAG_IGNORE;\n if (ignoreSelector && (e.target as HTMLElement).closest(ignoreSelector)) return;\n panGesture = { pointerId: e.pointerId, startX: e.clientX, startY: e.clientY, moved: false };\n}\n\nfunction onClickCapture(e: MouseEvent) {\n if (suppressClick) {\n suppressClick = false;\n e.preventDefault();\n e.stopPropagation();\n }\n}\n\n// ---- selection ('edit' interaction) ---------------------------------------\nconst internalSelection = ref<Set<string>>(new Set());\nconst selection = computed(() => props.selection ?? internalSelection.value);\nfunction setSelection(next: Set<string>) {\n if (!props.selection) internalSelection.value = next;\n emit('selectionChange', next);\n}\n\n// ---- tile drag / resize ('edit' interaction) ------------------------------\nconst dragController = new DragController(props.api.grid);\n\ninterface LoopDragVisual {\n tileId: string;\n instanceLeft: number;\n instanceTop: number;\n pickupCol: number;\n pickupRow: number;\n deltaX: number;\n deltaY: number;\n indicatorCol: number | null;\n indicatorRow: number | null;\n}\nconst drag = ref<LoopDragVisual | null>(null);\nlet dragStartPointerX = 0;\nlet dragStartPointerY = 0;\n\ninterface LoopResizeState {\n tileId: string;\n instanceKey: string;\n instanceDx: number;\n instanceDy: number;\n corner: Corner;\n startPointerX: number;\n startPointerY: number;\n startW: number;\n startH: number;\n startCol: number;\n startRow: number;\n previewW: number;\n previewH: number;\n previewCol: number;\n previewRow: number;\n}\nconst resize = ref<LoopResizeState | null>(null);\n\nfunction syncTiles() {\n props.api.tiles.value = props.api.grid.tiles;\n props.api.version.value++;\n}\n\nfunction isBase(inst: LoopTileInstance): boolean {\n return inst.kx === 0 && inst.ky === 0;\n}\nfunction isGhost(inst: LoopTileInstance): boolean {\n return editable.value && !isBase(inst);\n}\n\nfunction onTilePointerDown(e: PointerEvent, inst: LoopTileInstance) {\n if (!editable.value) return; // pan mode: container pan handler takes it\n if (!isBase(inst)) return; // ghosts are display-only\n const tile = inst.tile;\n if (tile.draggable === false) return;\n if ((e.target as HTMLElement).dataset.griddleHandle) return;\n const ignoreSelector = config.value.dragIgnoreFrom ?? DEFAULT_DRAG_IGNORE;\n if (ignoreSelector && (e.target as HTMLElement).closest(ignoreSelector)) return;\n\n if (e.metaKey || e.ctrlKey) {\n e.preventDefault();\n const next = new Set(selection.value);\n if (next.has(tile.id)) next.delete(tile.id);\n else next.add(tile.id);\n setSelection(next);\n e.stopPropagation();\n return;\n }\n setSelection(new Set([tile.id]));\n\n // No pointer capture: the grabbed instance unmounts (drag renders as an\n // overlay), which would release the capture mid-gesture.\n if (!dragController.start(tile.id)) return;\n dragStartPointerX = e.clientX;\n dragStartPointerY = e.clientY;\n drag.value = {\n tileId: tile.id,\n instanceLeft: inst.left,\n instanceTop: inst.top,\n pickupCol: tile.col,\n pickupRow: tile.row,\n deltaX: 0,\n deltaY: 0,\n indicatorCol: tile.col,\n indicatorRow: tile.row,\n };\n emit('dragStart', tile.id);\n e.stopPropagation();\n}\n\nfunction onResizeHandleDown(e: PointerEvent, inst: LoopTileInstance, c: Corner) {\n if (!editable.value) return;\n const tile = inst.tile;\n if (tile.resizable === false) return;\n (e.currentTarget as HTMLDivElement).setPointerCapture(e.pointerId);\n const baseLeft = tile.col * colSize.value + halfGap.value;\n const baseTop = tile.row * rowSize.value + halfGap.value;\n resize.value = {\n tileId: tile.id,\n instanceKey: inst.key,\n instanceDx: inst.left - baseLeft,\n instanceDy: inst.top - baseTop,\n corner: c,\n startPointerX: e.clientX,\n startPointerY: e.clientY,\n startW: tile.w,\n startH: tile.h,\n startCol: tile.col,\n startRow: tile.row,\n previewW: tile.w,\n previewH: tile.h,\n previewCol: tile.col,\n previewRow: tile.row,\n };\n emit('resizeStart', tile.id);\n e.stopPropagation();\n}\n\nfunction onPointerMove(e: PointerEvent) {\n if (panGesture && e.pointerId === panGesture.pointerId) {\n const now = performance.now();\n if (!panGesture.moved) {\n const dist = Math.hypot(e.clientX - panGesture.startX, e.clientY - panGesture.startY);\n if (dist >= PAN_THRESHOLD_PX) {\n panGesture.moved = true;\n pan.dragStart(panGesture.startX, panGesture.startY, now);\n pan.dragMove(e.clientX, e.clientY, now);\n }\n } else {\n pan.dragMove(e.clientX, e.clientY, now);\n }\n return;\n }\n\n const d = drag.value;\n if (d) {\n // Ghost edit: plain grid semantics in the base copy — no wrapping.\n const dx = e.clientX - dragStartPointerX;\n const dy = e.clientY - dragStartPointerY;\n const candidate: CellPos = {\n col: d.pickupCol + Math.round(dx / colSize.value),\n row: d.pickupRow + Math.round(dy / rowSize.value),\n };\n const result = dragController.update(candidate);\n drag.value = {\n ...d,\n deltaX: dx,\n deltaY: dy,\n indicatorCol: result.indicatorCell ? result.indicatorCell.col : null,\n indicatorRow: result.indicatorCell ? result.indicatorCell.row : null,\n };\n if (result.changed) syncTiles();\n }\n\n const r = resize.value;\n if (r) {\n const dx = e.clientX - r.startPointerX;\n const dy = e.clientY - r.startPointerY;\n const stepsX = Math.round(dx / colSize.value);\n const stepsY = Math.round(dy / rowSize.value);\n const tile = props.api.grid.getTile(r.tileId);\n const preview = resolveResizePreview({\n corner: r.corner,\n startCol: r.startCol,\n startRow: r.startRow,\n startW: r.startW,\n startH: r.startH,\n stepsX,\n stepsY,\n minW: tile?.minW ?? 1,\n minH: tile?.minH ?? 1,\n maxW: tile?.maxW ?? Infinity,\n maxH: tile?.maxH ?? Infinity,\n cols: config.value.cols,\n rows: config.value.rows,\n infiniteX: config.value.infiniteX ?? config.value.cols === Infinity,\n infiniteY: config.value.infiniteY ?? config.value.rows === Infinity,\n });\n const nW = preview.w;\n const nH = preview.h;\n const nC = preview.col;\n const nR = preview.row;\n if (nW !== r.previewW || nH !== r.previewH || nC !== r.previewCol || nR !== r.previewRow) {\n resize.value = { ...r, previewW: nW, previewH: nH, previewCol: nC, previewRow: nR };\n }\n }\n}\n\nfunction onPointerUp(e: PointerEvent) {\n if (panGesture && e.pointerId === panGesture.pointerId) {\n if (panGesture.moved) {\n pan.dragEnd(performance.now());\n suppressClick = true;\n }\n panGesture = null;\n return;\n }\n\n if (drag.value) {\n const tileId = drag.value.tileId;\n const { committed } = dragController.end();\n drag.value = null;\n syncTiles();\n emit('dragEnd', tileId, committed);\n }\n const r = resize.value;\n if (r) {\n const t = props.api.grid.getTile(r.tileId);\n let committed = false;\n if (t) {\n const target = { col: r.previewCol, row: r.previewRow };\n if (target.col !== t.col || target.row !== t.row) {\n props.api.moveTile(r.tileId, target);\n }\n if (r.previewW !== t.w || r.previewH !== t.h) {\n committed = props.api.resizeTile(r.tileId, { w: r.previewW, h: r.previewH });\n } else {\n committed = r.previewCol !== r.startCol || r.previewRow !== r.startRow\n || r.previewW !== r.startW || r.previewH !== r.startH;\n }\n }\n resize.value = null;\n emit('resizeEnd', r.tileId, committed);\n }\n}\n\nfunction onKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape' && editable.value) setSelection(new Set());\n}\n\nonMounted(() => {\n const el = viewportEl.value;\n if (el) {\n el.addEventListener('wheel', onWheel, { passive: false });\n const measure = () => {\n const cur = view.value;\n if (el.clientWidth !== cur.vw || el.clientHeight !== cur.vh) {\n view.value = { ...cur, vw: el.clientWidth, vh: el.clientHeight };\n }\n };\n measure();\n resizeObserver = new ResizeObserver(measure);\n resizeObserver.observe(el);\n }\n raf = requestAnimationFrame(frame);\n window.addEventListener('pointermove', onPointerMove);\n window.addEventListener('pointerup', onPointerUp);\n window.addEventListener('pointercancel', onPointerUp);\n window.addEventListener('keydown', onKeyDown);\n});\nonBeforeUnmount(() => {\n cancelAnimationFrame(raf);\n viewportEl.value?.removeEventListener('wheel', onWheel);\n resizeObserver?.disconnect();\n window.removeEventListener('pointermove', onPointerMove);\n window.removeEventListener('pointerup', onPointerUp);\n window.removeEventListener('pointercancel', onPointerUp);\n window.removeEventListener('keydown', onKeyDown);\n});\n\n// ---- FLIP for edit-mode repacks (keyed by world key) ----------------------\nconst tileNodes = new Map<string, HTMLDivElement>();\nconst prevRects = new Map<string, { x: number; y: number }>();\nfunction registerNode(key: string, el: HTMLDivElement | null) {\n if (el) tileNodes.set(key, el);\n else tileNodes.delete(key);\n}\n\nwatch(() => props.api.version.value, async () => {\n await nextTick();\n const draggerId = drag.value?.tileId ?? null;\n const seen = new Set<string>();\n for (const inst of instances.value) {\n const key = inst.key;\n seen.add(key);\n const x = inst.left;\n const y = inst.top;\n if (editable.value && inst.tile.id !== draggerId) {\n const p = prevRects.get(key);\n const node = tileNodes.get(key);\n if (p && node) {\n const dx = p.x - x;\n const dy = p.y - y;\n if (\n (dx !== 0 || dy !== 0) &&\n Math.abs(dx) < period.value.width / 2 &&\n Math.abs(dy) < period.value.height / 2\n ) {\n animateReposition(node, dx, dy, config.value.animation);\n }\n }\n }\n prevRects.set(key, { x, y });\n }\n for (const key of prevRects.keys()) {\n if (!seen.has(key)) prevRects.delete(key);\n }\n});\n\n// ---- styles ----------------------------------------------------------------\nconst viewportStyle = computed(() => {\n const showGrid = props.showGrid !== false;\n const bg = showGrid\n ? {\n backgroundImage: `linear-gradient(to right, rgba(0,0,0,0.08) 1px, transparent 1px), linear-gradient(to bottom, rgba(0,0,0,0.08) 1px, transparent 1px)`,\n backgroundSize: `${colSize.value}px ${rowSize.value}px`,\n backgroundPosition: '0 0',\n }\n : {};\n return {\n position: 'relative' as const,\n overflow: 'hidden' as const,\n height: typeof props.height === 'number' ? props.height + 'px' : (props.height ?? '100%'),\n touchAction: 'none' as const,\n userSelect: 'none' as const,\n willChange: 'translate',\n cursor: !editable.value && loop.value?.dragPan ? 'grab' : undefined,\n ['--griddle-tile-radius' as string]: (config.value.tileRadius ?? 4) + 'px',\n ...bg,\n };\n});\n\nconst planeStyle = computed(() => ({\n position: 'absolute' as const,\n top: '0',\n left: '0',\n width: '0',\n height: '0',\n willChange: 'transform',\n}));\n\nfunction instanceStyle(inst: LoopTileInstance) {\n const r = resize.value;\n const isResizingInst = r?.instanceKey === inst.key;\n let left = inst.left;\n let top = inst.top;\n let width = inst.width;\n let heightPx = inst.height;\n if (isResizingInst && r) {\n left = r.previewCol * colSize.value + halfGap.value + r.instanceDx;\n top = r.previewRow * rowSize.value + halfGap.value + r.instanceDy;\n width = r.previewW * config.value.unitWidth + (r.previewW - 1) * gap.value;\n heightPx = r.previewH * config.value.unitHeight + (r.previewH - 1) * gap.value;\n }\n const ghost = isGhost(inst);\n const isSelected = editable.value && isBase(inst) && selection.value.has(inst.tile.id);\n return {\n position: 'absolute' as const,\n left: left + 'px',\n top: top + 'px',\n width: width + 'px',\n height: heightPx + 'px',\n boxSizing: 'border-box' as const,\n cursor: editable.value && isBase(inst) ? 'grab' : undefined,\n userSelect: 'none' as const,\n // Ghosts are display-only: pointer-transparent (so the gesture falls\n // through to drag-pan) and dimmed to mark the editable copy.\n pointerEvents: ghost ? ('none' as const) : undefined,\n zIndex: isResizingInst ? 10 : 1,\n opacity: isResizingInst ? 0.85 : ghost ? 0.55 : 1,\n boxShadow: isSelected\n ? '0 0 0 3px rgba(59, 91, 219, 0.85), inset 0 0 0 1px rgba(59, 91, 219, 0.3)'\n : '',\n borderRadius: (config.value.tileRadius ?? 4) + 'px',\n };\n}\n\nconst draggedTile = computed<Tile | null>(() =>\n drag.value ? props.api.grid.getTile(drag.value.tileId) ?? null : null,\n);\n\nconst dragOverlayStyle = computed(() => {\n const d = drag.value;\n const t = draggedTile.value;\n if (!d || !t) return {};\n return {\n position: 'absolute' as const,\n left: d.instanceLeft + 'px',\n top: d.instanceTop + 'px',\n width: t.w * config.value.unitWidth + (t.w - 1) * gap.value + 'px',\n height: t.h * config.value.unitHeight + (t.h - 1) * gap.value + 'px',\n boxSizing: 'border-box' as const,\n cursor: 'grabbing',\n userSelect: 'none' as const,\n zIndex: 20,\n opacity: 0.85,\n transform: `translate(${d.deltaX}px, ${d.deltaY}px)`,\n filter: 'drop-shadow(0 8px 16px rgba(0,0,0,0.18))',\n borderRadius: (config.value.tileRadius ?? 4) + 'px',\n pointerEvents: 'none' as const,\n };\n});\n\n// Drop indicator: rendered in the base copy (ghost edit is plain-grid).\nconst indicatorRect = computed(() => {\n const d = drag.value;\n if (!d || d.indicatorCol === null || d.indicatorRow === null) return null;\n const t = props.api.grid.getTile(d.tileId);\n if (!t) return null;\n return {\n left: d.indicatorCol * colSize.value + halfGap.value,\n top: d.indicatorRow * rowSize.value + halfGap.value,\n width: t.w * config.value.unitWidth + (t.w - 1) * gap.value,\n height: t.h * config.value.unitHeight + (t.h - 1) * gap.value,\n };\n});\n\nfunction tileHandles(tile: Tile): Corner[] {\n return tile.resizeHandles ?? config.value.resizeHandles ?? ['se'];\n}\n\nfunction handleStyle(c: Corner) {\n const size = 12;\n const base = {\n position: 'absolute' as const,\n width: size + 'px',\n height: size + 'px',\n background: 'rgba(60,60,60,0.7)',\n border: '2px solid white',\n borderRadius: '3px',\n cursor: `${c}-resize`,\n touchAction: 'none' as const,\n } as Record<string, unknown>;\n if (c === 'nw') return { ...base, top: -size / 2 + 'px', left: -size / 2 + 'px' };\n if (c === 'ne') return { ...base, top: -size / 2 + 'px', right: -size / 2 + 'px' };\n if (c === 'sw') return { ...base, bottom: -size / 2 + 'px', left: -size / 2 + 'px' };\n return { ...base, bottom: -size / 2 + 'px', right: -size / 2 + 'px' };\n}\n\nconst className = computed(() => props.className ?? '');\n</script>\n","<template>\n <GriddleLoopGrid\n v-if=\"loopOn\"\n :api=\"api\"\n :class-name=\"className\"\n :height=\"height\"\n :show-grid=\"showGrid\"\n :selection=\"props.selection\"\n @selection-change=\"(s) => emit('selectionChange', s)\"\n @drag-start=\"(id) => emit('dragStart', id)\"\n @drag-end=\"(id, c) => emit('dragEnd', id, c)\"\n @resize-start=\"(id) => emit('resizeStart', id)\"\n @resize-end=\"(id, c) => emit('resizeEnd', id, c)\"\n @camera-change=\"(cam) => emit('cameraChange', cam)\"\n >\n <template #tile=\"slotProps\">\n <slot name=\"tile\" v-bind=\"slotProps\" />\n </template>\n </GriddleLoopGrid>\n <div\n v-else\n ref=\"scrollEl\"\n :class=\"className\"\n :style=\"scrollStyle\"\n @pointerdown=\"onBackgroundPointerDown\"\n >\n <div :style=\"contentStyle\">\n <div\n v-if=\"indicatorRect\"\n class=\"griddle-drop-indicator\"\n :style=\"{\n position: 'absolute',\n left: indicatorRect.left + 'px',\n top: indicatorRect.top + 'px',\n width: indicatorRect.width + 'px',\n height: indicatorRect.height + 'px',\n boxSizing: 'border-box',\n border: '2px dashed rgba(59, 91, 219, 0.55)',\n background: 'rgba(59, 91, 219, 0.08)',\n borderRadius: (config.tileRadius ?? 4) + 'px',\n pointerEvents: 'none',\n zIndex: 5,\n }\"\n ></div>\n <div\n v-if=\"drawGhostRect\"\n class=\"griddle-draw-ghost\"\n :style=\"{\n position: 'absolute',\n left: drawGhostRect.left + 'px',\n top: drawGhostRect.top + 'px',\n width: drawGhostRect.width + 'px',\n height: drawGhostRect.height + 'px',\n boxSizing: 'border-box',\n border: '2px dashed rgba(59, 91, 219, 0.55)',\n background: 'rgba(59, 91, 219, 0.08)',\n borderRadius: (config.tileRadius ?? 4) + 'px',\n pointerEvents: 'none',\n zIndex: 5,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '14px',\n fontWeight: '600',\n color: 'rgba(59, 91, 219, 0.8)',\n userSelect: 'none',\n }\"\n >{{ drawGhostRect.label }}</div>\n <div\n v-for=\"tile in rendered\"\n :key=\"tile.id\"\n :data-griddle-tile=\"tile.id\"\n :class=\"['griddle-tile', {\n 'griddle-dragging': drag?.tileId === tile.id || pinDrag?.tileId === tile.id || (groupDrag !== null && groupDragSet.has(tile.id)),\n 'griddle-resizing': resize?.tileId === tile.id,\n 'griddle-selected': selection.has(tile.id),\n }]\"\n :style=\"tileStyle(tile)\"\n @pointerdown=\"(e) => onTilePointerDown(e, tile)\"\n :ref=\"(el) => registerNode(tile.id, el as HTMLDivElement | null)\"\n >\n <slot name=\"tile\" :tile=\"tile\" :selected=\"selection.has(tile.id)\" />\n <template v-if=\"tile.resizable !== false\">\n <div\n v-for=\"c in tileHandles(tile)\"\n :key=\"c\"\n :data-griddle-handle=\"c\"\n :style=\"handleStyle(c)\"\n @pointerdown=\"(e) => onResizeHandleDown(e, tile, c)\"\n ></div>\n </template>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue';\nimport type { CameraState, Corner, Tile } from '@griddle/core';\nimport GriddleLoopGrid from './LoopGrid.vue';\nimport {\n visibleRange,\n visibleTiles,\n gridContentSize,\n DragController,\n GroupDragController,\n computeTileLayout,\n resolveStickyStacking,\n isOutOfFlow,\n pixelsToPin,\n} from '@griddle/core';\nimport type { TileLayout } from '@griddle/core';\nimport type { GriddleApi } from './useGriddle.js';\nimport { animateReposition, liftTransition } from './animation.js';\nimport {\n measureInteractionScale,\n clampInteractionCell,\n resolveResizePreview,\n toLocalInteractionDelta,\n type InteractionScale,\n} from './interaction.js';\n\nconst props = defineProps<{\n api: GriddleApi;\n className?: string;\n height?: number | string;\n showGrid?: boolean;\n /** Controlled selection. If omitted, managed internally. */\n selection?: Set<string>;\n}>();\n\nconst emit = defineEmits<{\n (e: 'selectionChange', selection: Set<string>): void;\n (e: 'drawCreate', rect: { col: number; row: number; w: number; h: number }): void;\n (e: 'dragStart', tileId: string): void;\n (e: 'dragEnd', tileId: string, committed: boolean): void;\n (e: 'resizeStart', tileId: string): void;\n (e: 'resizeEnd', tileId: string, committed: boolean): void;\n (e: 'cameraChange', camera: CameraState): void;\n}>();\n\n/** Loop mode delegates rendering to GriddleLoopGrid. */\nconst loopOn = computed(() => props.api.config.value.loop?.enabled === true);\n\nconst scrollEl = ref<HTMLDivElement | null>(null);\nconst viewport = ref({ scrollX: 0, scrollY: 0, width: 1000, height: 800 });\n\nconst config = computed(() => props.api.config.value);\nconst gap = computed(() => config.value.gap ?? 0);\nconst halfGap = computed(() => gap.value / 2);\nconst colSize = computed(() => config.value.unitWidth + gap.value);\nconst rowSize = computed(() => config.value.unitHeight + gap.value);\n\nconst range = computed(() => visibleRange(config.value, viewport.value, 4));\nconst rendered = computed(() => visibleTiles(props.api.tiles.value, range.value));\nconst contentSize = computed(() => gridContentSize(config.value, props.api.tiles.value));\n\nconst scrollStyle = computed(() => {\n // 'none' scroll mode: the grid sizes to content and lets the host page own\n // scrolling/panning — no internal scroll box, no touch-action lock.\n const contained = config.value.scroll !== 'none';\n const style: Record<string, string | number> = {\n position: 'relative',\n overflow: contained ? 'auto' : 'visible',\n height: contained ? (props.height ?? '100%') : (props.height ?? 'auto'),\n };\n if (contained) style.touchAction = 'none';\n return style;\n});\n\nconst contentStyle = computed(() => {\n const showGrid = props.showGrid !== false;\n const bg = showGrid\n ? {\n backgroundImage: `linear-gradient(to right, rgba(0,0,0,0.08) 1px, transparent 1px), linear-gradient(to bottom, rgba(0,0,0,0.08) 1px, transparent 1px)`,\n backgroundSize: `${colSize.value}px ${rowSize.value}px`,\n }\n : {};\n return {\n position: 'relative' as const,\n width: contentSize.value.width || '100%',\n height: contentSize.value.height || '100%',\n minWidth: '100%',\n minHeight: '100%',\n // Expose tile radius as a CSS variable so user tile content can pick it up.\n ['--griddle-tile-radius' as string]: (config.value.tileRadius ?? 4) + 'px',\n ...bg,\n };\n});\n\n// Selection state\nconst internalSelection = ref<Set<string>>(new Set());\nconst selection = computed(() => props.selection ?? internalSelection.value);\nconst groupDragSet = computed(() => new Set(groupDrag.value?.tileIds ?? []));\nfunction setSelection(next: Set<string>) {\n if (!props.selection) internalSelection.value = next;\n emit('selectionChange', next);\n}\n\nconst DEFAULT_DRAG_IGNORE = 'a, button, input, textarea, select, [contenteditable]';\nconst DRAG_START_THRESHOLD_PX = 12;\n\nconst dragController = new DragController(props.api.grid);\nconst groupDragController = new GroupDragController(props.api.grid);\n\ninterface DragVisual {\n tileId: string;\n pickupCol: number;\n pickupRow: number;\n deltaX: number;\n deltaY: number;\n indicatorCol: number | null;\n indicatorRow: number | null;\n}\nconst drag = ref<DragVisual | null>(null);\nlet dragStartPointerX = 0;\nlet dragStartPointerY = 0;\nlet interactionScale: InteractionScale = { x: 1, y: 1 };\n\ninterface GroupDragVisual {\n tileIds: string[];\n deltaX: number;\n deltaY: number;\n committedDcol: number;\n committedDrow: number;\n}\nconst groupDrag = ref<GroupDragVisual | null>(null);\n\ninterface PinDragState {\n tileId: string;\n startPinPx: { x: number; y: number };\n startPointerX: number;\n startPointerY: number;\n}\nconst pinDrag = ref<PinDragState | null>(null);\n\ninterface ResizeState {\n tileId: string;\n corner: Corner;\n startPointerX: number;\n startPointerY: number;\n startW: number;\n startH: number;\n startCol: number;\n startRow: number;\n previewW: number;\n previewH: number;\n previewCol: number;\n previewRow: number;\n}\nconst resize = ref<ResizeState | null>(null);\n\ninterface DrawState {\n anchorCol: number;\n anchorRow: number;\n currentCol: number;\n currentRow: number;\n}\nconst drawState = ref<DrawState | null>(null);\n\ninterface PendingDragState {\n pointerId: number;\n tileId: string;\n tileElement: HTMLDivElement;\n startPointerX: number;\n startPointerY: number;\n mode: 'pin' | 'group' | 'single';\n groupTileIds: string[];\n}\nlet pendingDrag: PendingDragState | null = null;\n\nfunction beginPendingDrag(pending: PendingDragState): boolean {\n const tile = props.api.grid.getTile(pending.tileId);\n if (!tile) return false;\n\n // Capture only once movement proves this is a drag. Capturing on\n // pointer-down retargets pointer-up away from editable descendants and turns\n // ordinary clicks into drag start/end cycles.\n try {\n pending.tileElement.setPointerCapture(pending.pointerId);\n } catch {\n // The pointer may already have ended or the tile may have unmounted.\n return false;\n }\n\n dragStartPointerX = pending.startPointerX;\n dragStartPointerY = pending.startPointerY;\n interactionScale = measureInteractionScale(scrollEl.value);\n\n if (pending.mode === 'pin') {\n const layout = computeTileLayout({\n tile,\n config: config.value,\n scrollX: viewport.value.scrollX,\n scrollY: viewport.value.scrollY,\n viewportWidth: viewport.value.width,\n viewportHeight: viewport.value.height,\n });\n const startPinPx =\n tile.position === 'fixed'\n ? { x: layout.left - viewport.value.scrollX, y: layout.top - viewport.value.scrollY }\n : { x: layout.left, y: layout.top };\n pinDrag.value = {\n tileId: tile.id,\n startPinPx,\n startPointerX: pending.startPointerX,\n startPointerY: pending.startPointerY,\n };\n emit('dragStart', tile.id);\n return true;\n }\n\n if (pending.mode === 'group') {\n if (!groupDragController.start(pending.groupTileIds)) return false;\n groupDrag.value = {\n tileIds: pending.groupTileIds,\n deltaX: 0,\n deltaY: 0,\n committedDcol: 0,\n committedDrow: 0,\n };\n emit('dragStart', tile.id);\n return true;\n }\n\n if (!dragController.start(tile.id)) return false;\n drag.value = {\n tileId: tile.id,\n pickupCol: tile.col,\n pickupRow: tile.row,\n deltaX: 0,\n deltaY: 0,\n indicatorCol: tile.col,\n indicatorRow: tile.row,\n };\n emit('dragStart', tile.id);\n return true;\n}\n\nfunction onTilePointerDown(e: PointerEvent, tile: Tile) {\n if (e.button !== 0) return;\n if (tile.draggable === false) return;\n if ((e.target as HTMLElement).dataset.griddleHandle) return;\n\n const ignoreSelector = config.value.dragIgnoreFrom ?? DEFAULT_DRAG_IGNORE;\n if (ignoreSelector && (e.target as HTMLElement).closest(ignoreSelector)) return;\n\n const metaKey = e.metaKey || e.ctrlKey;\n\n // Out-of-flow tiles get free-pixel drag (no selection).\n if (config.value.enablePositioning && isOutOfFlow(tile)) {\n pendingDrag = {\n pointerId: e.pointerId,\n tileId: tile.id,\n tileElement: e.currentTarget as HTMLDivElement,\n startPointerX: e.clientX,\n startPointerY: e.clientY,\n mode: 'pin',\n groupTileIds: [],\n };\n e.stopPropagation();\n return;\n }\n\n // Cmd/Ctrl+click toggles selection without starting a drag.\n if (metaKey) {\n e.preventDefault();\n const next = new Set(selection.value);\n if (next.has(tile.id)) {\n next.delete(tile.id);\n } else {\n next.add(tile.id);\n }\n setSelection(next);\n e.stopPropagation();\n return;\n }\n\n const tileIsSelected = selection.value.has(tile.id);\n\n if (!tileIsSelected) {\n setSelection(new Set([tile.id]));\n }\n\n // Defer capture and drag state until the pointer crosses the movement\n // threshold. A stationary pointer-down/up remains a normal click, including\n // when it starts inside contenteditable tile content.\n const effectiveSelection = tileIsSelected ? selection.value : new Set([tile.id]);\n const groupTileIds = Array.from(effectiveSelection);\n pendingDrag = {\n pointerId: e.pointerId,\n tileId: tile.id,\n tileElement: e.currentTarget as HTMLDivElement,\n startPointerX: e.clientX,\n startPointerY: e.clientY,\n mode: groupTileIds.length > 1 ? 'group' : 'single',\n groupTileIds,\n };\n e.stopPropagation();\n}\n\nfunction onBackgroundPointerDown(e: PointerEvent) {\n if ((e.target as HTMLElement).closest('[data-griddle-tile]')) return;\n // Draw-to-create is gated by config (default on). When disabled, empty-space\n // pointer-downs are a no-op so the host page keeps its native scroll/pan.\n if (config.value.interactive?.drawToCreate === false) return;\n setSelection(new Set());\n\n const el = scrollEl.value;\n if (!el) return;\n interactionScale = measureInteractionScale(el);\n const rect = el.getBoundingClientRect();\n const x = (e.clientX - rect.left) / interactionScale.x + el.scrollLeft;\n const y = (e.clientY - rect.top) / interactionScale.y + el.scrollTop;\n const col = clampInteractionCell(\n Math.floor(x / colSize.value),\n config.value.cols,\n config.value.infiniteX ?? config.value.cols === Infinity,\n );\n const row = clampInteractionCell(\n Math.floor(y / rowSize.value),\n config.value.rows,\n config.value.infiniteY ?? config.value.rows === Infinity,\n );\n drawState.value = { anchorCol: col, anchorRow: row, currentCol: col, currentRow: row };\n (el as HTMLDivElement).setPointerCapture(e.pointerId);\n}\n\nfunction onResizeHandleDown(e: PointerEvent, tile: Tile, c: Corner) {\n if (tile.resizable === false) return;\n (e.currentTarget as HTMLDivElement).setPointerCapture(e.pointerId);\n interactionScale = measureInteractionScale(scrollEl.value);\n resize.value = {\n tileId: tile.id,\n corner: c,\n startPointerX: e.clientX,\n startPointerY: e.clientY,\n startW: tile.w,\n startH: tile.h,\n startCol: tile.col,\n startRow: tile.row,\n previewW: tile.w,\n previewH: tile.h,\n previewCol: tile.col,\n previewRow: tile.row,\n };\n emit('resizeStart', tile.id);\n e.stopPropagation();\n}\n\nfunction onPointerMove(e: PointerEvent) {\n if (drawState.value) {\n const el = scrollEl.value;\n if (el) {\n const rect = el.getBoundingClientRect();\n const x = (e.clientX - rect.left) / interactionScale.x + el.scrollLeft;\n const y = (e.clientY - rect.top) / interactionScale.y + el.scrollTop;\n const col = clampInteractionCell(\n Math.floor(x / colSize.value),\n config.value.cols,\n config.value.infiniteX ?? config.value.cols === Infinity,\n );\n const row = clampInteractionCell(\n Math.floor(y / rowSize.value),\n config.value.rows,\n config.value.infiniteY ?? config.value.rows === Infinity,\n );\n drawState.value = { ...drawState.value, currentCol: col, currentRow: row };\n }\n return;\n }\n\n const pending = pendingDrag;\n if (pending && e.pointerId === pending.pointerId) {\n const distance = Math.hypot(\n e.clientX - pending.startPointerX,\n e.clientY - pending.startPointerY,\n );\n if (distance <= DRAG_START_THRESHOLD_PX) return;\n\n pendingDrag = null;\n if (!beginPendingDrag(pending)) return;\n e.preventDefault();\n }\n\n const pd = pinDrag.value;\n const gd = groupDrag.value;\n const d = drag.value;\n const r = resize.value;\n if (pd) {\n const { dx, dy } = toLocalInteractionDelta(\n e.clientX - pd.startPointerX,\n e.clientY - pd.startPointerY,\n interactionScale,\n );\n const newPinPx = { x: pd.startPinPx.x + dx, y: pd.startPinPx.y + dy };\n const newPin = pixelsToPin(newPinPx, config.value);\n props.api.grid.setTilePinned(pd.tileId, newPin);\n }\n if (gd) {\n const { dx, dy } = toLocalInteractionDelta(\n e.clientX - dragStartPointerX,\n e.clientY - dragStartPointerY,\n interactionScale,\n );\n const dcol = Math.round(dx / colSize.value);\n const drow = Math.round(dy / rowSize.value);\n const result = groupDragController.update({ dcol, drow });\n groupDrag.value = {\n ...gd,\n deltaX: dx,\n deltaY: dy,\n committedDcol: result.indicatorDelta?.dcol ?? gd.committedDcol,\n committedDrow: result.indicatorDelta?.drow ?? gd.committedDrow,\n };\n if (result.changed) syncTiles();\n }\n if (d) {\n const { dx, dy } = toLocalInteractionDelta(\n e.clientX - dragStartPointerX,\n e.clientY - dragStartPointerY,\n interactionScale,\n );\n const candidateCol = d.pickupCol + Math.round(dx / colSize.value);\n const candidateRow = d.pickupRow + Math.round(dy / rowSize.value);\n const result = dragController.update({ col: candidateCol, row: candidateRow });\n drag.value = {\n ...d,\n deltaX: dx,\n deltaY: dy,\n indicatorCol: result.indicatorCell ? result.indicatorCell.col : null,\n indicatorRow: result.indicatorCell ? result.indicatorCell.row : null,\n };\n // DragController.restoreTiles() doesn't emit change events, so when the\n // candidate cell changes (especially returning to pickup), force-sync the\n // reactive tiles ref so the FLIP animation picks up displaced tile resets.\n if (result.changed) syncTiles();\n }\n if (r) {\n const { dx, dy } = toLocalInteractionDelta(\n e.clientX - r.startPointerX,\n e.clientY - r.startPointerY,\n interactionScale,\n );\n const stepsX = Math.round(dx / colSize.value);\n const stepsY = Math.round(dy / rowSize.value);\n const tile = props.api.grid.getTile(r.tileId);\n const preview = resolveResizePreview({\n corner: r.corner,\n startCol: r.startCol,\n startRow: r.startRow,\n startW: r.startW,\n startH: r.startH,\n stepsX,\n stepsY,\n minW: tile?.minW ?? 1,\n minH: tile?.minH ?? 1,\n maxW: tile?.maxW ?? Infinity,\n maxH: tile?.maxH ?? Infinity,\n cols: config.value.cols,\n rows: config.value.rows,\n infiniteX: config.value.infiniteX ?? config.value.cols === Infinity,\n infiniteY: config.value.infiniteY ?? config.value.rows === Infinity,\n });\n const nW = preview.w;\n const nH = preview.h;\n const nC = preview.col;\n const nR = preview.row;\n if (nW !== r.previewW || nH !== r.previewH || nC !== r.previewCol || nR !== r.previewRow) {\n resize.value = { ...r, previewW: nW, previewH: nH, previewCol: nC, previewRow: nR };\n }\n }\n}\n\nfunction syncTiles() {\n // DragController/GroupDragController may restore grid snapshots without\n // emitting change events. Force-sync the reactive tiles ref so the UI\n // reflects the grid's true state after a drag ends.\n props.api.tiles.value = props.api.grid.tiles;\n props.api.version.value++;\n}\n\nfunction onPointerUp(e: PointerEvent) {\n if (pendingDrag?.pointerId === e.pointerId) {\n pendingDrag = null;\n return;\n }\n if (drawState.value) {\n const ds = drawState.value;\n const col = Math.min(ds.anchorCol, ds.currentCol);\n const row = Math.min(ds.anchorRow, ds.currentRow);\n const w = Math.max(1, Math.abs(ds.currentCol - ds.anchorCol) + 1);\n const h = Math.max(1, Math.abs(ds.currentRow - ds.anchorRow) + 1);\n drawState.value = null;\n emit('drawCreate', { col, row, w, h });\n return;\n }\n if (pinDrag.value) {\n const tileId = pinDrag.value.tileId;\n pinDrag.value = null;\n emit('dragEnd', tileId, true);\n }\n if (groupDrag.value) {\n const tileIds = groupDrag.value.tileIds;\n const { committed } = groupDragController.end();\n groupDrag.value = null;\n syncTiles();\n const firstId = tileIds[0];\n if (firstId !== undefined) emit('dragEnd', firstId, committed);\n }\n if (drag.value) {\n const tileId = drag.value.tileId;\n const { committed } = dragController.end();\n drag.value = null;\n syncTiles();\n emit('dragEnd', tileId, committed);\n }\n const r = resize.value;\n if (r) {\n const t = props.api.grid.getTile(r.tileId);\n let committed = false;\n if (t) {\n if (r.previewCol !== t.col || r.previewRow !== t.row) {\n props.api.moveTile(r.tileId, { col: r.previewCol, row: r.previewRow });\n }\n if (r.previewW !== t.w || r.previewH !== t.h) {\n committed = props.api.resizeTile(r.tileId, { w: r.previewW, h: r.previewH });\n } else {\n committed = r.previewCol !== r.startCol || r.previewRow !== r.startRow\n || r.previewW !== r.startW || r.previewH !== r.startH;\n }\n }\n resize.value = null;\n emit('resizeEnd', r.tileId, committed);\n }\n}\n\nfunction updateViewport() {\n const el = scrollEl.value;\n if (!el) return;\n viewport.value = {\n scrollX: el.scrollLeft,\n scrollY: el.scrollTop,\n width: el.clientWidth,\n height: el.clientHeight,\n };\n}\n\nfunction onKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape') setSelection(new Set());\n}\n\nlet ro: ResizeObserver | null = null;\nonMounted(() => {\n updateViewport();\n // scrollEl is absent while loop mode delegates to GriddleLoopGrid.\n const el = scrollEl.value;\n if (el) {\n el.addEventListener('scroll', updateViewport, { passive: true });\n ro = new ResizeObserver(updateViewport);\n ro.observe(el);\n }\n window.addEventListener('pointermove', onPointerMove);\n window.addEventListener('pointerup', onPointerUp);\n window.addEventListener('pointercancel', onPointerUp);\n window.addEventListener('keydown', onKeyDown);\n});\nonBeforeUnmount(() => {\n pendingDrag = null;\n const el = scrollEl.value;\n if (el) el.removeEventListener('scroll', updateViewport);\n ro?.disconnect();\n window.removeEventListener('pointermove', onPointerMove);\n window.removeEventListener('pointerup', onPointerUp);\n window.removeEventListener('pointercancel', onPointerUp);\n window.removeEventListener('keydown', onKeyDown);\n});\n\nconst tileNodes = new Map<string, HTMLDivElement>();\nconst prevRects = new Map<string, { x: number; y: number }>();\nfunction registerNode(id: string, el: HTMLDivElement | null) {\n if (el) tileNodes.set(id, el);\n else tileNodes.delete(id);\n}\n\nwatch(() => props.api.version.value, async () => {\n await nextTick();\n const draggerId = drag.value?.tileId ?? null;\n const gdSet = groupDragSet.value;\n for (const t of props.api.tiles.value) {\n const x = t.col * colSize.value + halfGap.value;\n const y = t.row * rowSize.value + halfGap.value;\n if (t.id === draggerId || gdSet.has(t.id)) {\n prevRects.set(t.id, { x, y });\n continue;\n }\n const p = prevRects.get(t.id);\n const node = tileNodes.get(t.id);\n if (p && node) {\n const dx = p.x - x;\n const dy = p.y - y;\n if (dx !== 0 || dy !== 0) {\n animateReposition(node, dx, dy, config.value.animation);\n }\n }\n prevRects.set(t.id, { x, y });\n }\n});\n\n// Compute layouts for all rendered tiles in one pass so resolveStickyStacking\n// can see every sticky tile and adjust them as a group. Recomputes whenever\n// rendered, config, viewport, drag, resize, or pinDrag change.\nconst tileLayouts = computed(() => {\n const out = new Map<string, TileLayout>();\n const stickyEntries: { tile: Tile; layout: TileLayout }[] = [];\n const gd = groupDrag.value;\n const gdIds = groupDragSet.value;\n for (const tile of rendered.value) {\n let layout: TileLayout;\n if (resize.value?.tileId === tile.id) {\n const w = resize.value.previewW;\n const h = resize.value.previewH;\n layout = {\n left: resize.value.previewCol * colSize.value + halfGap.value,\n top: resize.value.previewRow * rowSize.value + halfGap.value,\n width: w * config.value.unitWidth + (w - 1) * gap.value,\n height: h * config.value.unitHeight + (h - 1) * gap.value,\n zIndex: 10,\n effective: 'static',\n };\n } else if (drag.value?.tileId === tile.id) {\n const d = drag.value;\n layout = {\n left: d.pickupCol * colSize.value + halfGap.value,\n top: d.pickupRow * rowSize.value + halfGap.value,\n width: tile.w * config.value.unitWidth + (tile.w - 1) * gap.value,\n height: tile.h * config.value.unitHeight + (tile.h - 1) * gap.value,\n transform: `translate(${d.deltaX}px, ${d.deltaY}px)`,\n zIndex: 20,\n effective: 'static',\n };\n } else if (gd && gdIds.has(tile.id)) {\n const pickup = groupDragController.pickupCell(tile.id);\n const left = (pickup ? pickup.col * colSize.value : tile.col * colSize.value) + halfGap.value;\n const top = (pickup ? pickup.row * rowSize.value : tile.row * rowSize.value) + halfGap.value;\n layout = {\n left,\n top,\n width: tile.w * config.value.unitWidth + (tile.w - 1) * gap.value,\n height: tile.h * config.value.unitHeight + (tile.h - 1) * gap.value,\n transform: `translate(${gd.deltaX}px, ${gd.deltaY}px)`,\n zIndex: 20,\n effective: 'static',\n };\n } else {\n layout = computeTileLayout({\n tile,\n config: config.value,\n scrollX: viewport.value.scrollX,\n scrollY: viewport.value.scrollY,\n viewportWidth: viewport.value.width,\n viewportHeight: viewport.value.height,\n });\n if (layout.effective === 'sticky') {\n stickyEntries.push({ tile, layout });\n }\n }\n out.set(tile.id, layout);\n }\n if (stickyEntries.length > 1) resolveStickyStacking(stickyEntries);\n return out;\n});\n\nfunction tileStyle(tile: Tile) {\n const isDragging = drag.value?.tileId === tile.id;\n const isGroupDragging = groupDragSet.value.has(tile.id) && groupDrag.value !== null;\n const isPinDragging = pinDrag.value?.tileId === tile.id;\n const isResizing = resize.value?.tileId === tile.id;\n const isSelected = selection.value.has(tile.id);\n const layout = tileLayouts.value.get(tile.id) ?? {\n left: 0, top: 0, width: 0, height: 0, zIndex: 1, effective: 'static' as const,\n };\n const lifted = isDragging || isPinDragging || isGroupDragging;\n return {\n position: 'absolute' as const,\n left: layout.left + 'px',\n top: layout.top + 'px',\n width: layout.width + 'px',\n height: layout.height + 'px',\n boxSizing: 'border-box' as const,\n cursor: lifted ? 'grabbing' : 'grab',\n userSelect: 'none' as const,\n zIndex: layout.zIndex,\n opacity: lifted || isResizing ? 0.85 : 1,\n willChange: 'transform, translate',\n transform: layout.transform ?? '',\n filter: lifted ? 'drop-shadow(0 8px 16px rgba(0,0,0,0.18))' : '',\n transition: lifted ? liftTransition(config.value.animation) : '',\n boxShadow: isSelected\n ? '0 0 0 3px rgba(59, 91, 219, 0.85), inset 0 0 0 1px rgba(59, 91, 219, 0.3)'\n : '',\n borderRadius: (config.value.tileRadius ?? 4) + 'px',\n };\n}\n\n\nconst indicatorRect = computed(() => {\n const d = drag.value;\n if (!d || d.indicatorCol === null || d.indicatorRow === null) return null;\n const t = props.api.grid.getTile(d.tileId);\n if (!t) return null;\n return {\n left: d.indicatorCol * colSize.value + halfGap.value,\n top: d.indicatorRow * rowSize.value + halfGap.value,\n width: t.w * config.value.unitWidth + (t.w - 1) * gap.value,\n height: t.h * config.value.unitHeight + (t.h - 1) * gap.value,\n };\n});\n\nconst drawGhostRect = computed(() => {\n const ds = drawState.value;\n if (!ds) return null;\n const col = Math.min(ds.anchorCol, ds.currentCol);\n const row = Math.min(ds.anchorRow, ds.currentRow);\n const w = Math.max(1, Math.abs(ds.currentCol - ds.anchorCol) + 1);\n const h = Math.max(1, Math.abs(ds.currentRow - ds.anchorRow) + 1);\n return {\n left: col * colSize.value + halfGap.value,\n top: row * rowSize.value + halfGap.value,\n width: w * config.value.unitWidth + (w - 1) * gap.value,\n height: h * config.value.unitHeight + (h - 1) * gap.value,\n label: `${w}×${h}`,\n };\n});\n\nfunction tileHandles(tile: Tile): Corner[] {\n return tile.resizeHandles ?? config.value.resizeHandles ?? ['se'];\n}\n\nfunction handleStyle(c: Corner) {\n const size = 12;\n const base = {\n position: 'absolute' as const,\n width: size + 'px',\n height: size + 'px',\n background: 'rgba(60,60,60,0.7)',\n border: '2px solid white',\n borderRadius: '3px',\n cursor: `${c}-resize`,\n touchAction: 'none' as const,\n } as Record<string, unknown>;\n if (c === 'nw') return { ...base, top: -size / 2 + 'px', left: -size / 2 + 'px' };\n if (c === 'ne') return { ...base, top: -size / 2 + 'px', right: -size / 2 + 'px' };\n if (c === 'sw') return { ...base, bottom: -size / 2 + 'px', left: -size / 2 + 'px' };\n return { ...base, bottom: -size / 2 + 'px', right: -size / 2 + 'px' };\n}\n\nconst className = computed(() => props.className ?? '');\n</script>\n","// Vue composable that wraps a Grid instance with reactive state.\n\nimport { onScopeDispose, ref, shallowRef } from 'vue';\nimport { Grid } from '@griddle/core';\nimport type { GridConfig, GridSnapshot, ReflowOptions, Tile } from '@griddle/core';\n\nexport interface UseGriddleInit {\n config: GridConfig;\n tiles?: Tile[];\n}\n\nexport function useGriddle(init: UseGriddleInit) {\n const grid = new Grid(init.config, init.tiles ?? []);\n\n // Reactive mirrors of tiles and config. We re-assign on changes.\n const tiles = shallowRef<Tile[]>(grid.tiles);\n const config = shallowRef<GridConfig>(grid.config);\n const version = ref(0);\n\n const off = grid.changes.on(() => {\n tiles.value = grid.tiles;\n config.value = grid.config;\n version.value++;\n });\n onScopeDispose(off);\n\n const api = {\n grid,\n tiles,\n config,\n version,\n moveTile: (id: string, target: { col: number; row: number }) => grid.moveTile(id, target),\n resizeTile: (id: string, size: { w: number; h: number }) => grid.resizeTile(id, size),\n addTile: (t: Tile) => grid.addTile(t),\n removeTile: (id: string) => grid.removeTile(id),\n reflow: (options: ReflowOptions) => grid.reflow(options),\n updateConfig: (patch: Partial<GridConfig>) => grid.updateConfig(patch),\n toJSON: () => grid.toJSON(),\n loadJSON: (snap: GridSnapshot) => grid.loadJSON(snap),\n };\n return api;\n}\n\nexport type GriddleApi = ReturnType<typeof useGriddle>;\n"],"names":["DEFAULT_DRAG_IGNORE","PAN_THRESHOLD_PX","props","__props","emit","__emit","viewportEl","ref","planeEl","config","computed","loop","resolveLoop","editable","_a","gap","halfGap","colSize","rowSize","period","loopPeriod","pan","PanController","watch","l","view","lastCam","raf","resizeObserver","onWheel","k","frame","now","st","plane","el","cxCell","cyCell","cur","instances","bufX","bufY","loopInstances","panGesture","suppressClick","onContainerPointerDown","onTile","setSelection","ignoreSelector","onClickCapture","internalSelection","selection","next","dragController","DragController","drag","dragStartPointerX","dragStartPointerY","resize","syncTiles","isBase","inst","isGhost","onTilePointerDown","tile","onResizeHandleDown","c","baseLeft","baseTop","onPointerMove","d","dx","dy","candidate","result","r","stepsX","stepsY","preview","resolveResizePreview","nW","nH","nC","nR","onPointerUp","tileId","committed","t","target","onKeyDown","onMounted","measure","onBeforeUnmount","tileNodes","prevRects","registerNode","key","nextTick","draggerId","seen","x","y","p","node","animateReposition","viewportStyle","bg","planeStyle","instanceStyle","isResizingInst","left","top","width","heightPx","ghost","isSelected","draggedTile","dragOverlayStyle","indicatorRect","tileHandles","handleStyle","base","className","_createElementBlock","_createElementVNode","_normalizeStyle","_Fragment","_renderList","_normalizeClass","e","_renderSlot","_ctx","_openBlock","DRAG_START_THRESHOLD_PX","loopOn","scrollEl","viewport","range","visibleRange","rendered","visibleTiles","contentSize","gridContentSize","scrollStyle","contained","style","contentStyle","groupDragSet","groupDrag","groupDragController","GroupDragController","interactionScale","pinDrag","drawState","pendingDrag","beginPendingDrag","pending","measureInteractionScale","layout","computeTileLayout","startPinPx","metaKey","isOutOfFlow","tileIsSelected","effectiveSelection","groupTileIds","onBackgroundPointerDown","rect","col","clampInteractionCell","row","pd","gd","toLocalInteractionDelta","newPinPx","newPin","pixelsToPin","dcol","drow","_b","candidateCol","candidateRow","ds","w","h","tileIds","firstId","updateViewport","ro","id","gdSet","tileLayouts","out","stickyEntries","gdIds","pickup","resolveStickyStacking","tileStyle","isDragging","isGroupDragging","isPinDragging","isResizing","_c","lifted","liftTransition","drawGhostRect","_createBlock","GriddleLoopGrid","_cache","s","cam","_withCtx","slotProps","_toDisplayString","useGriddle","init","grid","Grid","tiles","shallowRef","version","off","onScopeDispose","size","options","patch","snap"],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface InteractionScale {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
}
|
|
5
|
+
export interface ResizePreviewInput {
|
|
6
|
+
corner: 'nw' | 'ne' | 'sw' | 'se';
|
|
7
|
+
startCol: number;
|
|
8
|
+
startRow: number;
|
|
9
|
+
startW: number;
|
|
10
|
+
startH: number;
|
|
11
|
+
stepsX: number;
|
|
12
|
+
stepsY: number;
|
|
13
|
+
minW: number;
|
|
14
|
+
minH: number;
|
|
15
|
+
maxW: number;
|
|
16
|
+
maxH: number;
|
|
17
|
+
cols: number;
|
|
18
|
+
rows: number;
|
|
19
|
+
infiniteX: boolean;
|
|
20
|
+
infiniteY: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ResizePreview {
|
|
23
|
+
col: number;
|
|
24
|
+
row: number;
|
|
25
|
+
w: number;
|
|
26
|
+
h: number;
|
|
27
|
+
}
|
|
28
|
+
type MeasurableElement = Pick<HTMLElement, 'getBoundingClientRect' | 'offsetWidth' | 'offsetHeight'>;
|
|
29
|
+
/**
|
|
30
|
+
* Measure how CSS transforms map an element's local coordinate space into
|
|
31
|
+
* viewport pixels. PointerEvent.clientX/clientY are viewport coordinates,
|
|
32
|
+
* while Griddle's cells and inline transforms use the element's local CSS
|
|
33
|
+
* pixels, so drag math must cross this boundary explicitly.
|
|
34
|
+
*/
|
|
35
|
+
export declare function measureInteractionScale(element: MeasurableElement | null): InteractionScale;
|
|
36
|
+
/** Convert a viewport-space pointer delta into the grid's local CSS pixels. */
|
|
37
|
+
export declare function toLocalInteractionDelta(dx: number, dy: number, scale: InteractionScale): {
|
|
38
|
+
dx: number;
|
|
39
|
+
dy: number;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a corner resize while preserving the opposite edges and trimming
|
|
43
|
+
* the dragged edges at finite grid bounds.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveResizePreview({ corner, startCol, startRow, startW, startH, stepsX, stepsY, minW, minH, maxW, maxH, cols, rows, infiniteX, infiniteY, }: ResizePreviewInput): ResizePreview;
|
|
46
|
+
/** Clamp a pointer-derived cell index to the cells addressable by the grid. */
|
|
47
|
+
export declare function clampInteractionCell(cell: number, extent: number, infinite: boolean): number;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=interaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction.d.ts","sourceRoot":"","sources":["../src/interaction.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,KAAK,iBAAiB,GAAG,IAAI,CAC3B,WAAW,EACX,uBAAuB,GAAG,aAAa,GAAG,cAAc,CACzD,CAAC;AAMF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,iBAAiB,GAAG,IAAI,GAChC,gBAAgB,CAkBlB;AAED,+EAA+E;AAC/E,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,gBAAgB,GACtB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAK5B;AAOD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,SAAS,GACV,EAAE,kBAAkB,GAAG,aAAa,CAsCpC;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO,GAChB,MAAM,CAGR"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
function y(t) {
|
|
2
|
+
return Number.isFinite(t) && t > 0 ? t : null;
|
|
3
|
+
}
|
|
4
|
+
function z(t) {
|
|
5
|
+
if (!t) return { x: 1, y: 1 };
|
|
6
|
+
const i = t.getBoundingClientRect(), n = y(
|
|
7
|
+
t.offsetWidth > 0 ? i.width / t.offsetWidth : NaN
|
|
8
|
+
), e = y(
|
|
9
|
+
t.offsetHeight > 0 ? i.height / t.offsetHeight : NaN
|
|
10
|
+
);
|
|
11
|
+
return {
|
|
12
|
+
x: n ?? e ?? 1,
|
|
13
|
+
y: e ?? n ?? 1
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function D(t, i, n) {
|
|
17
|
+
return {
|
|
18
|
+
dx: t / n.x,
|
|
19
|
+
dy: i / n.y
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function a(t, i, n) {
|
|
23
|
+
return n < i ? n : Math.min(n, Math.max(i, t));
|
|
24
|
+
}
|
|
25
|
+
function F({
|
|
26
|
+
corner: t,
|
|
27
|
+
startCol: i,
|
|
28
|
+
startRow: n,
|
|
29
|
+
startW: e,
|
|
30
|
+
startH: N,
|
|
31
|
+
stepsX: u,
|
|
32
|
+
stepsY: r,
|
|
33
|
+
minW: m,
|
|
34
|
+
minH: d,
|
|
35
|
+
maxW: g,
|
|
36
|
+
maxH: x,
|
|
37
|
+
cols: I,
|
|
38
|
+
rows: B,
|
|
39
|
+
infiniteX: b,
|
|
40
|
+
infiniteY: v
|
|
41
|
+
}) {
|
|
42
|
+
const c = i + e, f = n + N, L = t === "ne" || t === "se", S = t === "se" || t === "sw";
|
|
43
|
+
let h = i, M = c;
|
|
44
|
+
if (L) {
|
|
45
|
+
const o = Math.min(
|
|
46
|
+
i + g,
|
|
47
|
+
b ? 1 / 0 : I
|
|
48
|
+
);
|
|
49
|
+
M = a(c + u, i + m, o);
|
|
50
|
+
} else {
|
|
51
|
+
const o = Math.max(c - g, 0);
|
|
52
|
+
h = a(i + u, o, c - m);
|
|
53
|
+
}
|
|
54
|
+
let s = n, l = f;
|
|
55
|
+
if (S) {
|
|
56
|
+
const o = Math.min(
|
|
57
|
+
n + x,
|
|
58
|
+
v ? 1 / 0 : B
|
|
59
|
+
);
|
|
60
|
+
l = a(f + r, n + d, o);
|
|
61
|
+
} else {
|
|
62
|
+
const o = Math.max(f - x, 0);
|
|
63
|
+
s = a(n + r, o, f - d);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
col: h,
|
|
67
|
+
row: s,
|
|
68
|
+
w: M - h,
|
|
69
|
+
h: l - s
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function P(t, i, n) {
|
|
73
|
+
const e = Math.max(0, t);
|
|
74
|
+
return n ? e : Math.min(i - 1, e);
|
|
75
|
+
}
|
|
76
|
+
export {
|
|
77
|
+
P as clampInteractionCell,
|
|
78
|
+
z as measureInteractionScale,
|
|
79
|
+
F as resolveResizePreview,
|
|
80
|
+
D as toLocalInteractionDelta
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction.js","sources":["../src/interaction.ts"],"sourcesContent":["export interface InteractionScale {\n x: number;\n y: number;\n}\n\nexport interface ResizePreviewInput {\n corner: 'nw' | 'ne' | 'sw' | 'se';\n startCol: number;\n startRow: number;\n startW: number;\n startH: number;\n stepsX: number;\n stepsY: number;\n minW: number;\n minH: number;\n maxW: number;\n maxH: number;\n cols: number;\n rows: number;\n infiniteX: boolean;\n infiniteY: boolean;\n}\n\nexport interface ResizePreview {\n col: number;\n row: number;\n w: number;\n h: number;\n}\n\ntype MeasurableElement = Pick<\n HTMLElement,\n 'getBoundingClientRect' | 'offsetWidth' | 'offsetHeight'\n>;\n\nfunction validScale(value: number): number | null {\n return Number.isFinite(value) && value > 0 ? value : null;\n}\n\n/**\n * Measure how CSS transforms map an element's local coordinate space into\n * viewport pixels. PointerEvent.clientX/clientY are viewport coordinates,\n * while Griddle's cells and inline transforms use the element's local CSS\n * pixels, so drag math must cross this boundary explicitly.\n */\nexport function measureInteractionScale(\n element: MeasurableElement | null,\n): InteractionScale {\n if (!element) return { x: 1, y: 1 };\n\n const rect = element.getBoundingClientRect();\n const measuredX = validScale(\n element.offsetWidth > 0 ? rect.width / element.offsetWidth : NaN,\n );\n const measuredY = validScale(\n element.offsetHeight > 0 ? rect.height / element.offsetHeight : NaN,\n );\n\n // A content-sized grid can temporarily report a zero height while mounting.\n // Prefer the other measured axis before falling back to an unscaled value;\n // this also handles the common uniform transform: scale(...) host.\n return {\n x: measuredX ?? measuredY ?? 1,\n y: measuredY ?? measuredX ?? 1,\n };\n}\n\n/** Convert a viewport-space pointer delta into the grid's local CSS pixels. */\nexport function toLocalInteractionDelta(\n dx: number,\n dy: number,\n scale: InteractionScale,\n): { dx: number; dy: number } {\n return {\n dx: dx / scale.x,\n dy: dy / scale.y,\n };\n}\n\nfunction clamp(value: number, lower: number, upper: number): number {\n if (upper < lower) return upper;\n return Math.min(upper, Math.max(lower, value));\n}\n\n/**\n * Resolve a corner resize while preserving the opposite edges and trimming\n * the dragged edges at finite grid bounds.\n */\nexport function resolveResizePreview({\n corner,\n startCol,\n startRow,\n startW,\n startH,\n stepsX,\n stepsY,\n minW,\n minH,\n maxW,\n maxH,\n cols,\n rows,\n infiniteX,\n infiniteY,\n}: ResizePreviewInput): ResizePreview {\n const startRight = startCol + startW;\n const startBottom = startRow + startH;\n const east = corner === 'ne' || corner === 'se';\n const south = corner === 'se' || corner === 'sw';\n\n let col = startCol;\n let right = startRight;\n if (east) {\n const maxRight = Math.min(\n startCol + maxW,\n infiniteX ? Infinity : cols,\n );\n right = clamp(startRight + stepsX, startCol + minW, maxRight);\n } else {\n const minLeft = Math.max(startRight - maxW, 0);\n col = clamp(startCol + stepsX, minLeft, startRight - minW);\n }\n\n let row = startRow;\n let bottom = startBottom;\n if (south) {\n const maxBottom = Math.min(\n startRow + maxH,\n infiniteY ? Infinity : rows,\n );\n bottom = clamp(startBottom + stepsY, startRow + minH, maxBottom);\n } else {\n const minTop = Math.max(startBottom - maxH, 0);\n row = clamp(startRow + stepsY, minTop, startBottom - minH);\n }\n\n return {\n col,\n row,\n w: right - col,\n h: bottom - row,\n };\n}\n\n/** Clamp a pointer-derived cell index to the cells addressable by the grid. */\nexport function clampInteractionCell(\n cell: number,\n extent: number,\n infinite: boolean,\n): number {\n const nonNegative = Math.max(0, cell);\n return infinite ? nonNegative : Math.min(extent - 1, nonNegative);\n}\n"],"names":["validScale","value","measureInteractionScale","element","rect","measuredX","measuredY","toLocalInteractionDelta","dx","dy","scale","clamp","lower","upper","resolveResizePreview","corner","startCol","startRow","startW","startH","stepsX","stepsY","minW","minH","maxW","maxH","cols","rows","infiniteX","infiniteY","startRight","startBottom","east","south","col","right","maxRight","minLeft","row","bottom","maxBottom","minTop","clampInteractionCell","cell","extent","infinite","nonNegative"],"mappings":"AAmCA,SAASA,EAAWC,GAA8B;AAChD,SAAO,OAAO,SAASA,CAAK,KAAKA,IAAQ,IAAIA,IAAQ;AACvD;AAQO,SAASC,EACdC,GACkB;AAClB,MAAI,CAACA,EAAS,QAAO,EAAE,GAAG,GAAG,GAAG,EAAA;AAEhC,QAAMC,IAAOD,EAAQ,sBAAA,GACfE,IAAYL;AAAA,IAChBG,EAAQ,cAAc,IAAIC,EAAK,QAAQD,EAAQ,cAAc;AAAA,EAAA,GAEzDG,IAAYN;AAAA,IAChBG,EAAQ,eAAe,IAAIC,EAAK,SAASD,EAAQ,eAAe;AAAA,EAAA;AAMlE,SAAO;AAAA,IACL,GAAGE,KAAaC,KAAa;AAAA,IAC7B,GAAGA,KAAaD,KAAa;AAAA,EAAA;AAEjC;AAGO,SAASE,EACdC,GACAC,GACAC,GAC4B;AAC5B,SAAO;AAAA,IACL,IAAIF,IAAKE,EAAM;AAAA,IACf,IAAID,IAAKC,EAAM;AAAA,EAAA;AAEnB;AAEA,SAASC,EAAMV,GAAeW,GAAeC,GAAuB;AAClE,SAAIA,IAAQD,IAAcC,IACnB,KAAK,IAAIA,GAAO,KAAK,IAAID,GAAOX,CAAK,CAAC;AAC/C;AAMO,SAASa,EAAqB;AAAA,EACnC,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,QAAAC;AAAA,EACA,QAAAC;AAAA,EACA,QAAAC;AAAA,EACA,MAAAC;AAAA,EACA,MAAAC;AAAA,EACA,MAAAC;AAAA,EACA,MAAAC;AAAA,EACA,MAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAAC;AAAA,EACA,WAAAC;AACF,GAAsC;AACpC,QAAMC,IAAad,IAAWE,GACxBa,IAAcd,IAAWE,GACzBa,IAAOjB,MAAW,QAAQA,MAAW,MACrCkB,IAAQlB,MAAW,QAAQA,MAAW;AAE5C,MAAImB,IAAMlB,GACNmB,IAAQL;AACZ,MAAIE,GAAM;AACR,UAAMI,IAAW,KAAK;AAAA,MACpBpB,IAAWQ;AAAA,MACXI,IAAY,QAAWF;AAAA,IAAA;AAEzB,IAAAS,IAAQxB,EAAMmB,IAAaV,GAAQJ,IAAWM,GAAMc,CAAQ;AAAA,EAC9D,OAAO;AACL,UAAMC,IAAU,KAAK,IAAIP,IAAaN,GAAM,CAAC;AAC7C,IAAAU,IAAMvB,EAAMK,IAAWI,GAAQiB,GAASP,IAAaR,CAAI;AAAA,EAC3D;AAEA,MAAIgB,IAAMrB,GACNsB,IAASR;AACb,MAAIE,GAAO;AACT,UAAMO,IAAY,KAAK;AAAA,MACrBvB,IAAWQ;AAAA,MACXI,IAAY,QAAWF;AAAA,IAAA;AAEzB,IAAAY,IAAS5B,EAAMoB,IAAcV,GAAQJ,IAAWM,GAAMiB,CAAS;AAAA,EACjE,OAAO;AACL,UAAMC,IAAS,KAAK,IAAIV,IAAcN,GAAM,CAAC;AAC7C,IAAAa,IAAM3B,EAAMM,IAAWI,GAAQoB,GAAQV,IAAcR,CAAI;AAAA,EAC3D;AAEA,SAAO;AAAA,IACL,KAAAW;AAAA,IACA,KAAAI;AAAA,IACA,GAAGH,IAAQD;AAAA,IACX,GAAGK,IAASD;AAAA,EAAA;AAEhB;AAGO,SAASI,EACdC,GACAC,GACAC,GACQ;AACR,QAAMC,IAAc,KAAK,IAAI,GAAGH,CAAI;AACpC,SAAOE,IAAWC,IAAc,KAAK,IAAIF,IAAS,GAAGE,CAAW;AAClE;"}
|