@dxos/react-ui-mosaic 0.10.0 → 0.11.1
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/lib/chunk-Mosaic.mjs +1024 -0
- package/dist/lib/chunk-Mosaic.mjs.map +1 -0
- package/dist/lib/index.mjs +653 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/playwright.mjs +200 -0
- package/dist/lib/playwright.mjs.map +1 -0
- package/dist/lib/testing.mjs +127 -0
- package/dist/lib/testing.mjs.map +1 -0
- package/dist/lib/translations.mjs +11 -0
- package/dist/lib/translations.mjs.map +1 -0
- package/dist/types/src/components/Board/Board.d.ts +7 -27
- package/dist/types/src/components/Board/Board.d.ts.map +1 -1
- package/dist/types/src/components/Board/Board.stories.d.ts.map +1 -1
- package/dist/types/src/components/Board/BoardColumnContext.d.ts +10 -0
- package/dist/types/src/components/Board/BoardColumnContext.d.ts.map +1 -0
- package/dist/types/src/components/Board/BoardContext.d.ts +26 -0
- package/dist/types/src/components/Board/BoardContext.d.ts.map +1 -0
- package/dist/types/src/components/Board/Column.d.ts +2 -7
- package/dist/types/src/components/Board/Column.d.ts.map +1 -1
- package/dist/types/src/components/Board/index.d.ts +2 -0
- package/dist/types/src/components/Board/index.d.ts.map +1 -1
- package/dist/types/src/components/Focus/Focus.d.ts.map +1 -1
- package/dist/types/src/components/Mosaic/Container.d.ts +6 -34
- package/dist/types/src/components/Mosaic/Container.d.ts.map +1 -1
- package/dist/types/src/components/Mosaic/Mosaic.d.ts +10 -15
- package/dist/types/src/components/Mosaic/Mosaic.d.ts.map +1 -1
- package/dist/types/src/components/Mosaic/MosaicContainerContext.d.ts +34 -0
- package/dist/types/src/components/Mosaic/MosaicContainerContext.d.ts.map +1 -0
- package/dist/types/src/components/Mosaic/MosaicTileContext.d.ts +31 -0
- package/dist/types/src/components/Mosaic/MosaicTileContext.d.ts.map +1 -0
- package/dist/types/src/components/Mosaic/Placeholder.d.ts +3 -3
- package/dist/types/src/components/Mosaic/Placeholder.d.ts.map +1 -1
- package/dist/types/src/components/Mosaic/Stack.d.ts +8 -2
- package/dist/types/src/components/Mosaic/Stack.d.ts.map +1 -1
- package/dist/types/src/components/Mosaic/Stack.stories.d.ts.map +1 -1
- package/dist/types/src/components/Mosaic/Tile.d.ts +6 -32
- package/dist/types/src/components/Mosaic/Tile.d.ts.map +1 -1
- package/dist/types/src/components/Mosaic/VirtualStackPagination.stories.d.ts +13 -0
- package/dist/types/src/components/Mosaic/VirtualStackPagination.stories.d.ts.map +1 -0
- package/dist/types/src/components/Mosaic/index.d.ts +0 -1
- package/dist/types/src/components/Mosaic/index.d.ts.map +1 -1
- package/dist/types/src/components/SearchStack/SearchStack.d.ts +1 -1
- package/dist/types/src/components/SearchStack/SearchStack.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useDefaultColumnEventHandler.d.ts +2 -2
- package/dist/types/src/hooks/useDefaultColumnEventHandler.d.ts.map +1 -1
- package/dist/types/src/hooks/useEventHandlerAdapter.d.ts +3 -3
- package/dist/types/src/hooks/useEventHandlerAdapter.d.ts.map +1 -1
- package/dist/types/src/hooks/useVirtualizerPagination.d.ts +60 -0
- package/dist/types/src/hooks/useVirtualizerPagination.d.ts.map +1 -0
- package/dist/types/src/hooks/useVirtualizerPagination.test.d.ts +2 -0
- package/dist/types/src/hooks/useVirtualizerPagination.test.d.ts.map +1 -0
- package/dist/types/src/hooks/useVisibleItems.d.ts +2 -2
- package/dist/types/src/hooks/useVisibleItems.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -37
- package/src/components/Board/Board.stories.tsx +7 -6
- package/src/components/Board/Board.tsx +9 -54
- package/src/components/Board/BoardColumnContext.ts +25 -0
- package/src/components/Board/BoardContext.ts +43 -0
- package/src/components/Board/Column.tsx +13 -27
- package/src/components/Board/Item.tsx +2 -2
- package/src/components/Board/index.ts +3 -0
- package/src/components/Mosaic/Container.tsx +31 -53
- package/src/components/Mosaic/DragHandle.tsx +1 -1
- package/src/components/Mosaic/{Mosaic.tsx → Mosaic.ts} +5 -16
- package/src/components/Mosaic/MosaicContainerContext.ts +44 -0
- package/src/components/Mosaic/MosaicTileContext.ts +34 -0
- package/src/components/Mosaic/Placeholder.tsx +7 -8
- package/src/components/Mosaic/ResizeHandle.stories.tsx +4 -4
- package/src/components/Mosaic/ResizeHandle.tsx +2 -2
- package/src/components/Mosaic/Stack.stories.tsx +49 -13
- package/src/components/Mosaic/Stack.tsx +30 -9
- package/src/components/Mosaic/Tile.tsx +33 -33
- package/src/components/Mosaic/VirtualStackPagination.stories.tsx +423 -0
- package/src/components/Mosaic/index.ts +0 -1
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useDefaultColumnEventHandler.ts +2 -2
- package/src/hooks/useEventHandlerAdapter.ts +4 -5
- package/src/hooks/useVirtualizerPagination.test.tsx +105 -0
- package/src/hooks/useVirtualizerPagination.ts +473 -0
- package/src/hooks/useVisibleItems.ts +2 -2
- package/src/playwright/smoke.spec.ts +4 -1
- package/src/testing/DefaultStackTile.tsx +1 -1
- package/src/testing/decorator.tsx +3 -3
- package/dist/lib/browser/chunk-OBVIYZLR.mjs +0 -1119
- package/dist/lib/browser/chunk-OBVIYZLR.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -701
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/playwright/index.mjs +0 -256
- package/dist/lib/browser/playwright/index.mjs.map +0 -7
- package/dist/lib/browser/testing/index.mjs +0 -136
- package/dist/lib/browser/testing/index.mjs.map +0 -7
- package/dist/lib/browser/translations.mjs +0 -18
- package/dist/lib/browser/translations.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-4IEMCMIV.mjs +0 -1121
- package/dist/lib/node-esm/chunk-4IEMCMIV.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -702
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/playwright/index.mjs +0 -258
- package/dist/lib/node-esm/playwright/index.mjs.map +0 -7
- package/dist/lib/node-esm/testing/index.mjs +0 -137
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/lib/node-esm/translations.mjs +0 -20
- package/dist/lib/node-esm/translations.mjs.map +0 -7
- package/dist/types/src/components/Mosaic/Root.d.ts +0 -35
- package/dist/types/src/components/Mosaic/Root.d.ts.map +0 -1
- package/dist/types/src/components/Mosaic/types.d.ts +0 -86
- package/dist/types/src/components/Mosaic/types.d.ts.map +0 -1
- package/src/components/Mosaic/Root.tsx +0 -288
- package/src/components/Mosaic/types.ts +0 -94
- /package/src/components/Focus/{Focus.tsx → Focus.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-Mosaic.mjs","names":[],"sources":["../../src/hooks/useVirtualizerPagination.ts","../../src/hooks/useVisibleItems.ts","../../src/components/Mosaic/styles.ts","../../src/components/Mosaic/MosaicContainerContext.ts","../../src/components/Mosaic/Container.tsx","../../src/components/Mosaic/MosaicTileContext.ts","../../src/components/Mosaic/DragHandle.tsx","../../src/components/Mosaic/Placeholder.tsx","../../src/components/Mosaic/ResizeHandle.tsx","../../src/components/Mosaic/Stack.tsx","../../src/components/Mosaic/Tile.tsx","../../src/components/Mosaic/Mosaic.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { type Virtualizer } from '@tanstack/react-virtual';\nimport { type MutableRefObject, useCallback, useLayoutEffect, useRef, useState } from 'react';\n\nimport { type GetId } from '@dxos/react-ui-dnd';\n\n/** Rows from either loaded edge at which the next/previous page is requested. */\nconst DEFAULT_THRESHOLD = 12;\n\n/** Index at/above which `getNext` fires; small windows clamp to the last row only. */\nconst nextPageIndexThreshold = (itemCount: number, threshold: number): number =>\n itemCount > threshold ? itemCount - threshold : itemCount - 1;\n\n/** True when loaded content exceeds the scroll viewport (user can actually scroll). */\nconst isScrollable = (virtualizer: Virtualizer<any, any>): boolean => {\n const viewportHeight = virtualizer.scrollElement?.clientHeight ?? 0;\n return viewportHeight > 0 && virtualizer.getTotalSize() > viewportHeight + 1;\n};\n\nexport type VirtualizerPaginationController = {\n /** Requests the next (e.g. older) page. Omit to disable the bottom-edge trigger. */\n getNext?: () => void;\n /** Requests the previous (e.g. newer) page. Omit to disable the top-edge trigger. */\n getPrevious?: () => void;\n /** When true, suppresses the top-edge trigger (window is anchored at the live head). */\n atHead?: boolean;\n /** When true, suppresses both edge triggers while a page is in flight. */\n isLoading?: boolean;\n};\n\nexport type UseVirtualizerPaginationProps<TItem = any> = {\n /** Currently loaded window, in the order rendered by the virtualizer. */\n items: readonly TItem[] | TItem[] | undefined;\n\n /** ID getter, aligned with the virtualizer's own `getId`/`getItemKey`. */\n getId: GetId<TItem>;\n\n /** Load-next/load-previous callbacks. Both edges are inert while omitted. */\n pagination?: VirtualizerPaginationController;\n\n /** Rows from either loaded edge at which the adjacent page is requested. @default 12. */\n threshold?: number;\n};\n\nexport type UseVirtualizerPaginationResult = {\n onChange: (virtualizer: Virtualizer<any, any>) => void;\n /** Extra scrollable space (px) to feed into the virtualizer's `paddingStart`. */\n leadingSpace: number;\n};\n\n//\n// Edge-trigger evaluation\n//\n\n/** A retained item's identity and pre-change offset. */\ntype Anchor = { id: string; start: number };\n\n/** Position of the loaded window relative to the viewport, independent of what's rendered. */\ntype EdgeGeometry = {\n scrollOffset: number;\n viewportHeight: number;\n /** Index of the topmost/bottommost *rendered* row; undefined if nothing overlaps the viewport. */\n firstVisibleIndex: number | undefined;\n lastVisibleIndex: number | undefined;\n /** Absolute start/end of the whole loaded window, defined even when nothing is rendered there. */\n windowStart: number | undefined;\n windowEnd: number | undefined;\n};\n\nconst readEdgeGeometry = (virtualizer: Virtualizer<any, any>): EdgeGeometry => {\n const virtualItems = virtualizer.getVirtualItems();\n // `measurementsCache` covers the whole array even when nothing is rendered (deep in the spacer).\n const measurements = virtualizer.measurementsCache;\n return {\n scrollOffset: virtualizer.scrollOffset ?? 0,\n viewportHeight: virtualizer.scrollElement?.clientHeight ?? 0,\n firstVisibleIndex: virtualItems.at(0)?.index,\n lastVisibleIndex: virtualItems.at(-1)?.index,\n windowStart: measurements[0]?.start,\n windowEnd: measurements.at(-1)?.end,\n };\n};\n\nconst isNearBottomEdge = (geometry: EdgeGeometry, itemCount: number, threshold: number): boolean =>\n geometry.lastVisibleIndex !== undefined\n ? geometry.lastVisibleIndex >= nextPageIndexThreshold(itemCount, threshold)\n : geometry.windowEnd != null && geometry.scrollOffset + geometry.viewportHeight > geometry.windowEnd;\n\nconst isNearTopEdge = (geometry: EdgeGeometry, threshold: number): boolean =>\n geometry.firstVisibleIndex !== undefined\n ? geometry.firstVisibleIndex < threshold\n : geometry.windowStart != null && geometry.scrollOffset < geometry.windowStart;\n\n/** Loaded content doesn't reach the viewport's top edge (e.g. scrolled into the leading spacer). */\nconst isBlankAbove = (geometry: EdgeGeometry): boolean =>\n geometry.windowStart != null && geometry.windowStart > geometry.scrollOffset;\n\n/** Loaded content doesn't reach the viewport's bottom edge. */\nconst isBlankBelow = (geometry: EdgeGeometry): boolean =>\n geometry.windowEnd != null && geometry.windowEnd < geometry.scrollOffset + geometry.viewportHeight;\n\n/** Per-direction dedup/throttle state for `evaluateTriggers`, independent of item type. */\ntype TriggerState = {\n lastNextRequestedItemsRef: MutableRefObject<unknown>;\n lastPreviousRequestedItemsRef: MutableRefObject<unknown>;\n lastGetNextScrollRef: MutableRefObject<number | null>;\n lastGetPreviousScrollRef: MutableRefObject<number | null>;\n paginationRef: MutableRefObject<VirtualizerPaginationController | undefined>;\n};\n\n/** Not fired at this exact scroll offset since the edge was last left, unless blank re-arms it. */\nconst canRequestNext = (state: TriggerState, geometry: EdgeGeometry): boolean =>\n state.lastGetNextScrollRef.current === null ||\n geometry.scrollOffset !== state.lastGetNextScrollRef.current ||\n isBlankBelow(geometry);\n\nconst canRequestPrevious = (state: TriggerState, geometry: EdgeGeometry): boolean =>\n state.lastGetPreviousScrollRef.current === null ||\n geometry.scrollOffset !== state.lastGetPreviousScrollRef.current ||\n isBlankAbove(geometry);\n\nconst requestNext = (state: TriggerState, items: unknown, scrollOffset: number): void => {\n state.lastNextRequestedItemsRef.current = items;\n state.lastGetNextScrollRef.current = scrollOffset;\n const getNext = state.paginationRef.current?.getNext;\n queueMicrotask(() => getNext?.());\n};\n\nconst requestPrevious = (state: TriggerState, items: unknown, scrollOffset: number): void => {\n state.lastPreviousRequestedItemsRef.current = items;\n state.lastGetPreviousScrollRef.current = scrollOffset;\n const getPrevious = state.paginationRef.current?.getPrevious;\n queueMicrotask(() => getPrevious?.());\n};\n\ntype EvaluateTriggersOptions = {\n virtualizer: Virtualizer<any, any>;\n items: unknown;\n pagination: VirtualizerPaginationController | undefined;\n itemCount: number;\n threshold: number;\n state: TriggerState;\n};\n\n/**\n * Requests `getNext`/`getPrevious` once the loaded window's edge nears the viewport. Deduped per\n * direction and per `items` snapshot; re-armed while the viewport sits in blank space so a chain\n * of pages loads back-to-back without further user scrolling.\n */\nconst evaluateTriggers = ({ virtualizer, items, pagination, itemCount, threshold, state }: EvaluateTriggersOptions) => {\n const geometry = readEdgeGeometry(virtualizer);\n const scrollable = isScrollable(virtualizer);\n const smallWindow = itemCount <= threshold;\n const nearBottom = isNearBottomEdge(geometry, itemCount, threshold);\n const nearTop = isNearTopEdge(geometry, threshold);\n\n if (!nearBottom) {\n state.lastGetNextScrollRef.current = null;\n }\n if (!nearTop) {\n state.lastGetPreviousScrollRef.current = null;\n }\n\n const triggerNext =\n !!pagination?.getNext &&\n !pagination.isLoading &&\n scrollable &&\n nearBottom &&\n (!smallWindow || geometry.scrollOffset > 0) &&\n canRequestNext(state, geometry);\n const triggerPrevious =\n !!pagination?.getPrevious &&\n !pagination.isLoading &&\n scrollable &&\n nearTop &&\n pagination.atHead !== true &&\n canRequestPrevious(state, geometry);\n\n if (!triggerNext) {\n state.lastNextRequestedItemsRef.current = undefined;\n }\n if (!triggerPrevious) {\n state.lastPreviousRequestedItemsRef.current = undefined;\n }\n\n if (triggerNext && state.lastNextRequestedItemsRef.current !== items) {\n requestNext(state, items, geometry.scrollOffset);\n } else if (triggerPrevious && state.lastPreviousRequestedItemsRef.current !== items) {\n requestPrevious(state, items, geometry.scrollOffset);\n }\n};\n\n//\n// Front-edge (eviction/prepend) reconciliation\n//\n\n/** Total height (px) of `prevItems[0, oldIndexOfNewFirst)`, per its outgoing measurements. */\nconst evictedPrefixHeight = (virtualizer: Virtualizer<any, any>, oldIndexOfNewFirst: number): number => {\n const measurements = virtualizer.measurementsCache;\n return (measurements[oldIndexOfNewFirst]?.start ?? 0) - (measurements[0]?.start ?? 0);\n};\n\n/**\n * True when `items` is `prevItems` sliced from `oldIndexOfNewFirst` (a genuine slide/eviction/append).\n * False for a reorder -- e.g. a conversation bumped to the head by a mid-sync reply -- whose old\n * mid-list offset would otherwise be misread as evicted height and grow the spacer for good.\n */\nconst isContiguousSlide = <TItem>(\n prevItems: readonly TItem[],\n items: readonly TItem[],\n oldIndexOfNewFirst: number,\n getId: GetId<TItem>,\n): boolean => {\n const overlap = Math.min(items.length, prevItems.length - oldIndexOfNewFirst);\n for (let index = 0; index < overlap; index++) {\n if (getId(items[index]) !== getId(prevItems[oldIndexOfNewFirst + index])) {\n return false;\n }\n }\n return true;\n};\n\n/**\n * Finds an item retained across a prepend, anchored on its pre-change offset. Scans from the tail\n * (the common case -- a prepend leaves the rest of the window untouched) and doesn't require the\n * item to be currently rendered, since `measurementsCache` covers the whole array.\n */\nconst findRetainedAnchor = <TItem>(\n prevItems: readonly TItem[],\n newIds: Set<unknown>,\n getId: GetId<TItem>,\n virtualizer: Virtualizer<any, any>,\n): Anchor | null => {\n for (let index = prevItems.length - 1; index >= 0; index--) {\n const id = getId(prevItems[index]);\n if (newIds.has(id)) {\n const start = virtualizer.measurementsCache[index]?.start;\n return start != null ? { id, start } : null;\n }\n }\n return null;\n};\n\ntype FrontEdgeChange =\n | { kind: 'none' }\n | { kind: 'evicted'; evictedHeight: number }\n | { kind: 'prepended'; anchor: Anchor | null };\n\n/**\n * Classifies how `items` changed at the front, relative to `prevItems`, using only the outgoing\n * window's own measurements (no need to wait for the incoming render). `'evicted'` covers both a\n * prefix eviction (the window slid forward) and a pure append (the window grew) -- either way the\n * item now at the front was already loaded, so its height is already known, *and* the retained\n * items keep their old relative order (`isContiguousSlide`). `'prepended'` covers everything else:\n * a `getPrevious` prepend, a reset to a disjoint range, or an existing item reordered to the head\n * (e.g. conversation grouping bumping a thread on a new reply) -- despite the new head having been\n * loaded before, nothing was actually evicted.\n */\nconst classifyFrontEdgeChange = <TItem>(\n prevItems: readonly TItem[] | TItem[] | undefined,\n items: readonly TItem[] | TItem[] | undefined,\n getId: GetId<TItem>,\n virtualizer: Virtualizer<any, any> | null,\n): FrontEdgeChange => {\n if (!virtualizer || !prevItems) {\n return { kind: 'none' };\n }\n const firstNewId = items?.[0] != null ? getId(items[0]) : undefined;\n const oldIndexOfNewFirst = firstNewId != null ? prevItems.findIndex((item) => getId(item) === firstNewId) : -1;\n if (oldIndexOfNewFirst >= 0 && items && isContiguousSlide(prevItems, items, oldIndexOfNewFirst, getId)) {\n return { kind: 'evicted', evictedHeight: evictedPrefixHeight(virtualizer, oldIndexOfNewFirst) };\n }\n const newIds = new Set(items?.map((item) => getId(item)));\n return { kind: 'prepended', anchor: findRetainedAnchor(prevItems, newIds, getId, virtualizer) };\n};\n\n//\n// Prepend correction (deferred to a layout effect; see the hook's own doc comment for why)\n//\n\ntype PrependCorrection =\n | { kind: 'no-overlap' }\n | { kind: 'pending' }\n | { kind: 'absorbed'; nextSpace: number }\n | { kind: 'snap'; nextSpace: number; scrollAdjust: number };\n\n/**\n * `'no-overlap'`: the anchor isn't in the new `items` (e.g. a reset) -- the spacer no longer\n * describes anything. `'pending'`: the incoming render hasn't measured the anchor yet. `'absorbed'`:\n * the shift is fully absorbed by the spacer, no scroll rewrite needed. `'snap'`: growing past an\n * empty spacer (or the `atHead` reset) leaves a remainder that has to move the scroll offset.\n */\nconst computePrependCorrection = <TItem>(\n virtualizer: Virtualizer<any, any>,\n items: readonly TItem[] | TItem[],\n getId: GetId<TItem>,\n anchor: Anchor,\n currentSpace: number,\n atHead: boolean,\n): PrependCorrection => {\n const newIndex = items.findIndex((item) => getId(item) === anchor.id);\n if (newIndex < 0) {\n return { kind: 'no-overlap' };\n }\n const newStart = virtualizer.measurementsCache[newIndex]?.start;\n if (newStart == null) {\n return { kind: 'pending' };\n }\n const shift = newStart - anchor.start;\n const nextSpace = atHead ? 0 : Math.max(0, currentSpace - shift);\n const scrollAdjust = shift + (nextSpace - currentSpace);\n return scrollAdjust === 0 ? { kind: 'absorbed', nextSpace } : { kind: 'snap', nextSpace, scrollAdjust };\n};\n\n//\n// Hook\n//\n\n/**\n * Wires a paginated data source into a `Mosaic.VirtualStack`: requests the next/previous page near\n * either loaded edge (`evaluateTriggers`), and keeps the scrollbar stable across the resulting\n * `items` change by maintaining a leading spacer instead of rewriting the scroll offset.\n *\n * Called internally by `Mosaic.VirtualStack` when its `pagination` prop is set -- not normally\n * called directly.\n *\n * `@tanstack/react-virtual` recomputes every item's pixel offset from the current array on each\n * render, with no compensation for insertion/removal at the front -- rewriting the scroll offset\n * to chase that shift visibly jumps the scrollbar thumb. Instead, `leadingSpace` (fed back into\n * `paddingStart`) grows by exactly the evicted height and shrinks by exactly the prepended height,\n * so retained items keep their absolute position and the thumb only scales as the total grows.\n *\n * Eviction (`classifyFrontEdgeChange`'s `'evicted'`) is corrected synchronously during the same\n * render that observes the new `items`, since the evicted height is already known -- deferring it\n * would let the browser observe (and clamp `scrollTop` against) a momentary, too-short frame.\n * Prepending (`'prepended'`) is corrected one render later, from a layout effect\n * (`computePrependCorrection`), since the prepended items' heights aren't known until the incoming\n * render measures them; that lag is safe because prepending only ever grows content before the\n * spacer shrinks to match.\n *\n * The layout effect also re-runs `evaluateTriggers` on every `items` change, evicted/appended or\n * prepended alike -- `@tanstack/react-virtual` only calls `onChange` when the visible range (or\n * `isScrolling`) changes, not merely when `items` does. Once the loaded window's tail is already\n * fully rendered and the scrollbar sits at its physical max, further scrolling can't move that\n * range at all, so `onChange` stops firing -- relying on it alone would permanently stall a\n * `getNext` chain right after its own page lands, before the user scrolls again.\n *\n * Assumes the stack renders with `draggable={false}` (virtual indices map 1:1 onto `items`).\n */\nexport const useVirtualizerPagination = <TItem = any>({\n items,\n getId,\n pagination,\n threshold = DEFAULT_THRESHOLD,\n}: UseVirtualizerPaginationProps<TItem>): UseVirtualizerPaginationResult => {\n const itemCount = items?.length ?? 0;\n\n const [leadingSpace, setLeadingSpace] = useState(0);\n const leadingSpaceRef = useRef(leadingSpace);\n const setSpacer = useCallback((nextSpace: number) => {\n if (nextSpace !== leadingSpaceRef.current) {\n leadingSpaceRef.current = nextSpace;\n setLeadingSpace(nextSpace);\n }\n }, []);\n\n const virtualizerRef = useRef<Virtualizer<any, any> | null>(null);\n const anchorRef = useRef<Anchor | null>(null);\n const prevItemsRef = useRef(items);\n // Suppresses trigger evaluation for the scroll event that our own correction below causes.\n const restoringRef = useRef(false);\n\n const triggerState: TriggerState = {\n lastNextRequestedItemsRef: useRef<unknown>(undefined),\n lastPreviousRequestedItemsRef: useRef<unknown>(undefined),\n lastGetNextScrollRef: useRef<number | null>(null),\n lastGetPreviousScrollRef: useRef<number | null>(null),\n paginationRef: useRef(pagination),\n };\n triggerState.paginationRef.current = pagination;\n\n const rearmTriggers = useCallback(\n (virtualizer: Virtualizer<any, any>) => {\n evaluateTriggers({\n virtualizer,\n items,\n pagination: triggerState.paginationRef.current,\n itemCount,\n threshold,\n state: triggerState,\n });\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [items, itemCount, threshold],\n );\n\n // Classifies the front-edge change during render, before `Mosaic.VirtualStack` re-renders with\n // the new `items` -- at this point `virtualizerRef.current` still reflects the outgoing array.\n // Skipped entirely when `pagination` is unset, so a caller not using pagination never gets\n // spacer/anchor bookkeeping for an unrelated `items` change (e.g. a sort or filter).\n if (prevItemsRef.current !== items) {\n if (pagination) {\n const change = classifyFrontEdgeChange(prevItemsRef.current, items, getId, virtualizerRef.current);\n if (change.kind === 'evicted') {\n setSpacer(leadingSpaceRef.current + change.evictedHeight);\n anchorRef.current = null;\n } else if (change.kind === 'prepended') {\n anchorRef.current = change.anchor;\n if (!change.anchor) {\n // No retained item to anchor on (a disjoint reset): the layout effect below still\n // re-arms triggers for this case, but its own correction/reset is anchor-driven, so\n // clear the spacer here instead of waiting on it.\n setSpacer(0);\n }\n }\n }\n prevItemsRef.current = items;\n }\n\n const onChange = useCallback(\n (virtualizer: Virtualizer<any, any>) => {\n virtualizerRef.current = virtualizer;\n if (restoringRef.current) {\n restoringRef.current = false;\n return;\n }\n rearmTriggers(virtualizer);\n },\n [rearmTriggers],\n );\n\n useLayoutEffect(() => {\n const virtualizer = virtualizerRef.current;\n const anchor = anchorRef.current;\n anchorRef.current = null;\n if (!virtualizer || !items) {\n return;\n }\n if (!anchor) {\n // Evicted/appended (a `getNext` page or a slide), or an unclassified change -- no prepend to\n // correct, but still re-arm (see the hook doc for why this can't be skipped).\n rearmTriggers(virtualizer);\n return;\n }\n const atHead = triggerState.paginationRef.current?.atHead === true;\n const correction = computePrependCorrection(virtualizer, items, getId, anchor, leadingSpaceRef.current, atHead);\n switch (correction.kind) {\n case 'pending':\n return;\n case 'no-overlap':\n setSpacer(0);\n rearmTriggers(virtualizer);\n return;\n case 'absorbed':\n setSpacer(correction.nextSpace);\n rearmTriggers(virtualizer);\n return;\n case 'snap':\n // A one-shot move, not a chain, so `rearmTriggers` is skipped: `virtualizer.scrollOffset`\n // won't reflect this until the (suppressed) scroll event fires.\n setSpacer(correction.nextSpace);\n restoringRef.current = true;\n virtualizer.scrollToOffset((virtualizer.scrollOffset ?? 0) + correction.scrollAdjust);\n return;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [items, getId, setSpacer, rearmTriggers]);\n\n return { onChange, leadingSpace };\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useMemo } from 'react';\n\nimport { type DndTileData, type GetId } from '@dxos/react-ui-dnd';\n\nexport type UseVisibleItemsProps<TItem = any> = {\n /** Container id. */\n id: string;\n\n /** Current items. */\n items?: readonly TItem[] | TItem[];\n\n /** Currently dragging item. */\n dragging: DndTileData<TItem> | undefined;\n\n /** ID getter */\n getId: GetId<TItem>;\n};\n\n/**\n * Returns items with the dragging item removed.\n */\nexport const useVisibleItems = <TItem = any>({\n id,\n items,\n dragging,\n getId,\n}: UseVisibleItemsProps<TItem>): readonly TItem[] | TItem[] => {\n const visibleItems = useMemo(() => {\n if (!items || !dragging || id !== dragging.containerId) {\n return items ?? [];\n }\n\n const idx = items.findIndex((item) => getId(item) === dragging.id);\n if (idx === -1) {\n return items;\n }\n\n const visibleItems = items.slice();\n visibleItems.splice(idx, 1);\n return visibleItems;\n }, [id, items, dragging, getId]);\n\n return visibleItems;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type ClassNameValue } from '@dxos/react-ui';\n\nexport const styles = {\n placeholder: {\n root: [\n 'group opacity-0',\n 'group-data-[mosaic-debug=\"true\"]:opacity-100',\n 'group-data-[mosaic-debug=\"true\"]:bg-orange-500',\n 'data-[mosaic-placeholder-state=active]:opacity-100',\n 'data-[mosaic-placeholder-orientation=vertical]:snap-start', // TODO(burdon): Option.\n 'data-[mosaic-placeholder-orientation=vertical]:py-1',\n 'data-[mosaic-placeholder-orientation=vertical]:data-[mosaic-placeholder-state=active]:py-2.5',\n 'data-[mosaic-placeholder-orientation=horizontal]:px-1',\n 'data-[mosaic-placeholder-orientation=horizontal]:data-[mosaic-placeholder-state=active]:px-2.5',\n ],\n content: [\n 'transition-all duration-0',\n // Placeholders open instantly (`duration-0`). The source slot is reserved on drag start by\n // activating its placeholder (see Stack.tsx), so the stack no longer collapses/flickers when the\n // dragged item is removed. NOTE: if the open animation below is ever enabled, exempt the source\n // placeholder — animating its reserved gap from 0 would reintroduce the start-of-drag flicker.\n // 'group-data-[mosaic-placeholder-state=active]:duration-200',\n 'group-data-[mosaic-placeholder-orientation=vertical]:h-0',\n 'group-data-[mosaic-placeholder-orientation=vertical]:group-data-[mosaic-placeholder-state=active]:h-[var(--mosaic-placeholder-height)]',\n 'group-data-[mosaic-placeholder-orientation=horizontal]:w-0',\n 'group-data-[mosaic-placeholder-orientation=horizontal]:group-data-[mosaic-placeholder-state=active]:w-[var(--mosaic-placeholder-width)]',\n ],\n },\n} satisfies Record<string, Record<string, ClassNameValue>>;\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { createContext } from '@radix-ui/react-context';\n\nimport { type AllowedAxis } from '@dxos/react-ui';\nimport { type DndContainerHandler, type DndDraggingState, type DndLocation } from '@dxos/react-ui-dnd';\n\n// Kept out of `Container.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so the context and hook exported beside them force a full page reload on every edit.\n\nexport const MOSAIC_CONTAINER_NAME = 'Mosaic.Container';\n\nexport type MosaicContainerState = { type: 'idle' } | { type: 'active'; bounds?: DOMRect };\n\nexport type MosaicContainerContextValue<TData = any, Location = DndLocation> = {\n id: string;\n eventHandler: DndContainerHandler<TData>;\n orientation?: AllowedAxis;\n dragging?: DndDraggingState;\n scrolling?: boolean;\n state: MosaicContainerState;\n\n /** Active drop location. */\n activeLocation?: Location;\n setActiveLocation: (location: Location | undefined) => void;\n\n /** ID of the current (aria-current) item. */\n currentId?: string;\n /** Set the current item by ID. */\n setCurrentId: (id: string | undefined) => void;\n\n /** IDs of selected (aria-selected) items. */\n selectedIds?: ReadonlySet<string>;\n /** Request to set or unset selection on an item by ID. */\n setSelected: (id: string, selected: boolean) => void;\n\n /** Register a scroll-to-item callback (provided by Stack/VirtualStack). */\n registerScrollTo: (fn: ((id: string) => void) | undefined) => void;\n};\n\nexport const [MosaicContainerContextProvider, useMosaicContainerContext] =\n createContext<MosaicContainerContextValue>('MosaicContainer');\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';\nimport { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';\nimport { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { Slot } from '@radix-ui/react-slot';\nimport { bind } from 'bind-event-listener';\nimport React, {\n type CSSProperties,\n type PropsWithChildren,\n type ReactNode,\n type Ref,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { composable, composableProps } from '@dxos/react-ui';\nimport {\n type DndContainerData,\n type DndLocation,\n type DndTileData,\n getSourceData,\n useDndRootContext,\n} from '@dxos/react-ui-dnd';\nimport { isTruthy } from '@dxos/util';\n\nimport { useFocus } from '../Focus';\nimport {\n MOSAIC_CONTAINER_NAME,\n MosaicContainerContextProvider,\n type MosaicContainerContextValue,\n type MosaicContainerState,\n} from './MosaicContainerContext';\n\n//\n// Container\n//\n\n// State attribute: [&:has(>_[data-mosaic-container-state=active])]\nconst MOSAIC_CONTAINER_STATE_ATTR = 'mosaic-container-state';\n\n// Debug flag on the container's `group` element; Placeholder reads it via `group-data-[mosaic-debug=true]` (see styles.ts).\nconst MOSAIC_CONTAINER_DEBUG_ATTR = 'mosaic-debug';\n\n// CSS variables: [var(--mosaic-placeholder-xxx)]\nconst MOSAIC_CONTAINER_PLACEHOLDER_WIDTH = '--mosaic-placeholder-width';\nconst MOSAIC_CONTAINER_PLACEHOLDER_HEIGHT = '--mosaic-placeholder-height';\n\nlet counter = 0;\n\n/** Imperative handle for scrolling a stack to an item without changing the current/selected item. */\nexport type MosaicScrollController = {\n scrollToItem: (id: string) => void;\n};\n\ntype MosaicContainerProps = PropsWithChildren<\n Partial<Pick<MosaicContainerContextValue, 'eventHandler' | 'orientation'>> & {\n asChild?: boolean;\n /** Support autoscrolling container when dragging. */\n autoScroll?: HTMLElement | null;\n withFocus?: boolean;\n /** Imperative handle to scroll the stack to an item (decoupled from selection). */\n controllerRef?: Ref<MosaicScrollController>;\n /** Controlled current-item ID. */\n currentId?: string;\n /** Called when a tile requests to become current. */\n onCurrentChange?: (id: string | undefined) => void;\n /** Controlled set of selected item IDs. */\n selectedIds?: ReadonlySet<string>;\n /** Called when a tile requests to toggle selection. */\n onSelectionChange?: (id: string, selected: boolean) => void;\n debug?: () => ReactNode;\n /** Toggles the `group` target that Placeholder's debug-highlight selectors read (see styles.ts). */\n placeholderDebug?: boolean;\n }\n>;\n\n/**\n * Container for a Mosaic layout.\n */\n// TODO(burdon): Make generic.\nconst MosaicContainer = composable<HTMLDivElement, MosaicContainerProps>(\n (\n {\n children,\n eventHandler: eventHandlerProp,\n orientation = 'vertical',\n asChild,\n autoScroll: autoscrollElement,\n withFocus,\n controllerRef,\n currentId,\n onCurrentChange,\n selectedIds,\n onSelectionChange,\n debug,\n placeholderDebug,\n ...props\n },\n forwardedRef,\n ) => {\n const Comp = asChild ? Slot : Primitive.div;\n const rootRef = useRef<HTMLDivElement>(null);\n const composedRef = useComposedRefs<HTMLDivElement>(rootRef, forwardedRef);\n\n // Handler.\n const eventHandler = useMemo(\n () =>\n eventHandlerProp ?? {\n id: `mosaic-container-${counter++}`,\n },\n [eventHandlerProp],\n );\n\n // State.\n const { dragging } = useDndRootContext(MOSAIC_CONTAINER_NAME);\n const [state, setState] = useState<MosaicContainerState>({ type: 'idle' });\n const [activeLocation, setActiveLocation] = useState<DndLocation | undefined>();\n const [scrolling, setScrolling] = useState(false);\n const setCurrentId = useCallback((id: string | undefined) => onCurrentChange?.(id), [onCurrentChange]);\n const setSelected = useCallback(\n (id: string, selected: boolean) => onSelectionChange?.(id, selected),\n [onSelectionChange],\n );\n\n // Scroll-to-item: Stack/VirtualStack registers its implementation.\n const scrollToRef = useRef<((id: string) => void) | undefined>(undefined);\n const registerScrollTo = useCallback((fn: ((id: string) => void) | undefined) => {\n scrollToRef.current = fn;\n }, []);\n\n // Imperative scroll-to-item, decoupled from selection (e.g. a calendar scrolling the stack to a day).\n useImperativeHandle(controllerRef, () => ({ scrollToItem: (id: string) => scrollToRef.current?.(id) }), []);\n\n // When currentId changes, scroll the matching item into view.\n useEffect(() => {\n if (currentId) {\n scrollToRef.current?.(currentId);\n }\n }, [currentId]);\n\n // Focus container.\n const { setFocus } = useFocus();\n useEffect(() => {\n if (withFocus) {\n setFocus?.(state.type === 'active' ? 'active' : undefined);\n }\n }, [setFocus, withFocus, state]);\n\n // Register handler.\n const { addContainer, removeContainer } = useDndRootContext(eventHandler.id);\n useEffect(() => {\n addContainer(eventHandler);\n return () => removeContainer(eventHandler.id);\n }, [eventHandler]);\n\n const data = useMemo<DndContainerData>(\n () =>\n ({\n type: 'container',\n id: eventHandler.id,\n }) satisfies DndContainerData,\n [eventHandler.id],\n );\n\n useEffect(() => {\n if (!rootRef.current) {\n return;\n }\n\n // Determine if scrolling (pause drag/drop handlers).\n let timeout: ReturnType<typeof setTimeout>;\n const handleScroll = () => {\n setScrolling(true);\n clearTimeout(timeout);\n timeout = setTimeout(() => {\n setScrolling(false);\n }, 500);\n };\n\n return combine(\n ...[\n /**\n * Custom event for dragging cancellation.\n */\n bind(rootRef.current, {\n type: 'dnd:cancel',\n listener: () => {\n setState({ type: 'idle' });\n },\n }),\n\n // Target.\n dropTargetForElements({\n element: rootRef.current,\n getData: () => data,\n\n /**\n * Test if permitted to drop here.\n * NOTE: Contained Tile and Placeholder elements do the same.\n */\n canDrop: ({ source }) => {\n const data = getSourceData(source);\n return (data && eventHandler.canDrop?.({ source: data })) || false;\n },\n\n // Reorder is a move, not a copy — otherwise the browser shows the green \"+\" copy cursor.\n getDropEffect: () => 'move',\n\n /**\n * Dragging started in this container.\n */\n onDragStart: ({ source }) => {\n const sourceData = source.data as DndTileData;\n setState({ type: 'active', bounds: sourceData.bounds });\n },\n /**\n * Dragging entered this container.\n */\n onDragEnter: ({ source }) => {\n const sourceData = source.data as DndTileData;\n setState({ type: 'active', bounds: sourceData.bounds });\n },\n /**\n * Dragging left this container.\n * NOTE: If the container isn't full-height, then when the dragged item is temporarily removed the container will shrink,\n * triggering `onDragLeave`, which then causes the item to be added and removed continually (flickering).\n */\n onDragLeave: ({ source }) => {\n const sourceData = source.data as DndTileData;\n if (sourceData.containerId !== eventHandler.id) {\n setState({ type: 'idle' });\n }\n },\n /**\n * Dropped in this container.\n */\n onDrop: () => {\n setState({ type: 'idle' });\n },\n }),\n\n // Autoscroll.\n // NOTE: When used with Scrollable we get a spurious warning (in dev mode).\n // \"Auto scrolling has been attached to an element that appears not to be scrollable.\"\n autoscrollElement && [\n autoScrollForElements({\n element: autoscrollElement,\n // Only autoscroll for tile (reorder) drags. Resize-handle drags carry no tile data, so\n // resizing a tile near a viewport edge must not scroll the container.\n canScroll: ({ source }) => getSourceData(source) != null,\n getAllowedAxis: () => orientation,\n getConfiguration: () => ({\n maxScrollSpeed: 'fast',\n }),\n }),\n\n bind(autoscrollElement, {\n type: 'scroll',\n listener: handleScroll,\n }),\n\n () => setScrolling(false),\n ],\n ]\n .filter(isTruthy)\n .flatMap((x) => x),\n );\n }, [rootRef, eventHandler, data, autoscrollElement]);\n\n return (\n <MosaicContainerContextProvider\n id={eventHandler.id}\n eventHandler={eventHandler}\n orientation={orientation}\n state={state}\n dragging={state.type === 'active' ? dragging : undefined}\n scrolling={scrolling}\n activeLocation={activeLocation}\n setActiveLocation={setActiveLocation}\n currentId={currentId}\n setCurrentId={setCurrentId}\n selectedIds={selectedIds}\n setSelected={setSelected}\n registerScrollTo={registerScrollTo}\n >\n <Comp\n {...composableProps(props, {\n classNames: 'h-full group',\n style: {\n [MOSAIC_CONTAINER_PLACEHOLDER_WIDTH]:\n state.type === 'active' && state.bounds ? `${state.bounds.width}px` : '0px',\n [MOSAIC_CONTAINER_PLACEHOLDER_HEIGHT]:\n state.type === 'active' && state.bounds ? `${state.bounds.height}px` : '0px',\n } as CSSProperties,\n })}\n {...{\n [`data-${MOSAIC_CONTAINER_STATE_ATTR}`]: state.type,\n [`data-${MOSAIC_CONTAINER_DEBUG_ATTR}`]: placeholderDebug,\n }}\n ref={composedRef}\n >\n {children}\n </Comp>\n {debug?.()}\n </MosaicContainerContextProvider>\n );\n },\n);\n\nMosaicContainer.displayName = MOSAIC_CONTAINER_NAME;\n\nexport { MosaicContainer };\n\nexport type { MosaicContainerProps };\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';\nimport { createContext } from '@radix-ui/react-context';\n\nimport { type Size } from '@dxos/react-ui-dnd';\n\n// Kept out of `Tile.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so the context and hook exported beside them force a full page reload on every edit.\n\nexport const MOSAIC_TILE_NAME = 'Mosaic.Tile';\n\nexport type MosaicTileState =\n | { type: 'idle' }\n | { type: 'preview'; container: HTMLElement; rect: DOMRect }\n | { type: 'dragging' }\n | { type: 'target'; closestEdge: Edge | null };\n\nexport type MosaicTileContextValue = {\n state: MosaicTileState;\n /** Register the element that initiates dragging; set by a child `Mosaic.DragHandle`. */\n setDragHandle: (element: HTMLElement | null) => void;\n /** Current extent (rem) during/after resize; undefined when the tile is not sized. */\n size?: Size;\n /** Update the tile extent. A `commit` (drop) propagates to the consumer's `onSizeChange`. */\n setSize: (size: Size, commit?: boolean) => void;\n /** Resize bounds (rem) declared by the tile; consumed by `Mosaic.ResizeHandle`. */\n minSize?: number;\n maxSize?: number;\n};\n\nexport const [MosaicTileContextProvider, useMosaicTileContext] = createContext<MosaicTileContextValue>('MosaicTile');\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { composeRefs } from '@radix-ui/react-compose-refs';\nimport React, { type ReactNode, forwardRef } from 'react';\n\nimport { Button, IconButton, type IconButtonProps, type ThemedClassName, useTranslation } from '@dxos/react-ui';\n\nimport { useMosaicTileContext } from './MosaicTileContext';\n\nconst MOSAIC_DRAG_HANDLE_NAME = 'Mosaic.DragHandle';\n\nconst REACT_UI_TRANSLATION_KEY = '@dxos/react-ui';\n\nexport type MosaicDragHandleProps = ThemedClassName<\n Partial<Pick<IconButtonProps, 'icon' | 'label' | 'variant'>> & {\n testId?: string;\n /**\n * Inline glyph rendered in place of the sprite icon. The browser does not rasterize external SVG\n * sprite `<use>` icons into a native drag image, so a tile that appears in its own drag preview\n * (the clone follows the cursor) must use an inline-SVG handle here to stay visible while dragging.\n */\n children?: ReactNode;\n }\n>;\n\n/**\n * Affordance that initiates dragging the enclosing {@link MosaicTile}. Renders a button and\n * registers itself with the tile (via context), so consumers only need to drop it inside a\n * `Mosaic.Tile` — no `dragHandle` ref plumbing required.\n */\nexport const MosaicDragHandle = forwardRef<HTMLButtonElement, MosaicDragHandleProps>(\n (\n { icon = 'ph--dots-six-vertical--regular', label, variant = 'ghost', classNames, testId, children },\n forwardedRef,\n ) => {\n const { t } = useTranslation(REACT_UI_TRANSLATION_KEY);\n const { setDragHandle } = useMosaicTileContext(MOSAIC_DRAG_HANDLE_NAME);\n const ref = composeRefs(forwardedRef, setDragHandle);\n const testIdProps = testId ? { 'data-testid': testId } : {};\n\n // Inline-glyph variant: stays visible in the tile's own native drag image (sprite icons do not).\n if (children) {\n return (\n <Button\n ref={ref}\n variant={variant}\n tabIndex={-1}\n classNames={['grid place-items-center cursor-grab', classNames]}\n {...testIdProps}\n >\n {children}\n <span className='sr-only'>{label ?? t('toolbar-drag-handle.label')}</span>\n </Button>\n );\n }\n\n return (\n <IconButton\n ref={ref}\n iconOnly\n noTooltip\n tabIndex={-1}\n variant={variant}\n icon={icon}\n label={label ?? t('toolbar-drag-handle.label')}\n classNames={['cursor-grab', classNames]}\n {...testIdProps}\n />\n );\n },\n);\n\nMosaicDragHandle.displayName = MOSAIC_DRAG_HANDLE_NAME;\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport {\n DropIndicator as NaturalDropIndicator,\n type DropIndicatorProps as NaturalDropIndicatorProps,\n} from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';\nimport { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { Slot } from '@radix-ui/react-slot';\nimport React, { type PropsWithChildren, useLayoutEffect, useMemo, useRef } from 'react';\n\nimport { type Axis, type ThemedClassName } from '@dxos/react-ui';\nimport { type DndLocation, type DndPlaceholderData, getSourceData } from '@dxos/react-ui-dnd';\nimport { mx } from '@dxos/ui-theme';\n\nimport { useMosaicContainerContext } from './MosaicContainerContext';\nimport { useMosaicTileContext } from './MosaicTileContext';\n\n//\n// Placeholder\n//\n\nconst MOSAIC_PLACEHOLDER_NAME = 'Mosaic.Placeholder';\n\n// Orientation: data-[mosaic-placeholder-orientation=vertical]\nconst MOSAIC_PLACEHOLDER_ORIENTATION_ATTR = 'mosaic-placeholder-orientation';\n\n// State attribute: data-[mosaic-placeholder-state=active]\nconst MOSAIC_PLACEHOLDER_STATE_ATTR = 'mosaic-placeholder-state';\n\n// Location attribute: data-[mosaic-placeholder-location=0.5]. Identifies the\n// placeholder's slot in its container (0.5, 1.5, 2.5, …) so tests can target\n// a specific gap unambiguously without relying on layout-dependent indices.\nconst MOSAIC_PLACEHOLDER_LOCATION_ATTR = 'mosaic-placeholder-location';\n\ntype MosaicPlaceholderProps<Location = DndLocation> = ThemedClassName<\n PropsWithChildren<{\n asChild?: boolean;\n orientation?: Axis;\n location: Location;\n }>\n>;\n\nconst MosaicPlaceholder = <Location extends DndLocation = DndLocation>({\n classNames,\n children,\n asChild,\n orientation = 'vertical',\n location,\n}: MosaicPlaceholderProps<Location>) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const Comp = asChild ? Slot : Primitive.div;\n const {\n id: containerId,\n eventHandler,\n scrolling,\n activeLocation,\n setActiveLocation,\n } = useMosaicContainerContext(MOSAIC_PLACEHOLDER_NAME);\n const data = useMemo<DndPlaceholderData<Location>>(\n () =>\n ({\n type: 'placeholder',\n containerId,\n location,\n }) satisfies DndPlaceholderData<Location>,\n [containerId, location],\n );\n\n useLayoutEffect(() => {\n const root = rootRef.current;\n if (!root || scrolling) {\n return;\n }\n\n return dropTargetForElements({\n element: root,\n getData: () => data,\n canDrop: ({ source }) => {\n const data = getSourceData(source);\n return (data && eventHandler.canDrop?.({ source: data })) || false;\n },\n // Reorder is a move, not a copy — otherwise the browser shows the green \"+\" copy cursor.\n getDropEffect: () => 'move',\n onDragEnter: () => {\n setActiveLocation(data.location);\n },\n onDragLeave: () => {\n setActiveLocation(undefined);\n },\n onDrop: () => {\n setActiveLocation(undefined);\n },\n });\n }, [rootRef, data, scrolling, setActiveLocation]);\n\n return (\n <Comp\n {...{\n [`data-${MOSAIC_PLACEHOLDER_ORIENTATION_ATTR}`]: orientation,\n [`data-${MOSAIC_PLACEHOLDER_STATE_ATTR}`]: data.location === activeLocation ? 'active' : 'idle',\n [`data-${MOSAIC_PLACEHOLDER_LOCATION_ATTR}`]: String(location),\n }}\n className={mx('relative', classNames)}\n ref={rootRef}\n >\n {children}\n </Comp>\n );\n};\n\nMosaicPlaceholder.displayName = MOSAIC_PLACEHOLDER_NAME;\n\n//\n// DropIndicator\n// TODO(burdon): Support DropIndicator or Placeholder variants.\n//\n\nconst DROP_INDICATOR_NAME = 'Mosaic.DropIndicator';\n\ntype MosaicDropIndicatorProps = Omit<NaturalDropIndicatorProps, 'edge'>;\n\nconst MosaicDropIndicator = (props: MosaicDropIndicatorProps) => {\n const { state } = useMosaicTileContext(DROP_INDICATOR_NAME);\n return state.type === 'target' && state.closestEdge ? (\n <NaturalDropIndicator {...props} edge={state.closestEdge} />\n ) : null;\n};\n\nMosaicDropIndicator.displayName = DROP_INDICATOR_NAME;\n\n//\n// Exports\n//\n\nexport { MosaicDropIndicator, MosaicPlaceholder };\n\nexport type { MosaicDropIndicatorProps, MosaicPlaceholderProps };\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport { ResizeHandle } from '@dxos/react-ui-dnd';\n\nimport { useMosaicContainerContext } from './MosaicContainerContext';\nimport { useMosaicTileContext } from './MosaicTileContext';\n\nconst MOSAIC_RESIZE_HANDLE_NAME = 'Mosaic.ResizeHandle';\n\n// Lower bounds for a tile's extent (rem); below these the content stops being usable.\nconst MIN_WIDTH = 20;\nconst MIN_HEIGHT = 3;\n// Extent assumed when the subject hasn't been measured yet (matches the deck plank default).\nconst DEFAULT_EXTRINSIC_SIZE = 50;\n\nexport type MosaicResizeHandleProps = {\n /** Lower bound in rem; overrides the tile's `minSize`, else a sensible per-axis minimum. */\n minSize?: number;\n /** Upper bound in rem; overrides the tile's `maxSize`. */\n maxSize?: number;\n /** Extent assumed before the subject is first measured. */\n fallbackSize?: number;\n};\n\n/**\n * Edge affordance that resizes the enclosing {@link MosaicTile}. The axis tracks the container\n * orientation (width when horizontal, height when vertical); the tile must be given a `size` so the\n * dragged extent is reflected and persisted via its `onSizeChange`. Resize bounds default to the\n * tile's `minSize`/`maxSize` and can be overridden per handle.\n */\nexport const MosaicResizeHandle = ({\n minSize,\n maxSize,\n fallbackSize = DEFAULT_EXTRINSIC_SIZE,\n}: MosaicResizeHandleProps) => {\n const { orientation = 'vertical' } = useMosaicContainerContext(MOSAIC_RESIZE_HANDLE_NAME);\n const { size, setSize, minSize: tileMinSize, maxSize: tileMaxSize } = useMosaicTileContext(MOSAIC_RESIZE_HANDLE_NAME);\n const horizontal = orientation === 'horizontal';\n\n return (\n <ResizeHandle\n side={horizontal ? 'inline-end' : 'block-end'}\n fallbackSize={fallbackSize}\n minSize={minSize ?? tileMinSize ?? (horizontal ? MIN_WIDTH : MIN_HEIGHT)}\n maxSize={maxSize ?? tileMaxSize}\n size={size}\n onSizeChange={setSize}\n />\n );\n};\n\nMosaicResizeHandle.displayName = MOSAIC_RESIZE_HANDLE_NAME;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { type ReactVirtualizerOptions, type Virtualizer, useVirtualizer } from '@tanstack/react-virtual';\nimport React, {\n type FC,\n Fragment,\n type ReactElement,\n type Ref,\n forwardRef,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n} from 'react';\n\nimport { invariant } from '@dxos/invariant';\nimport { type Axis, type ThemedClassName, composable, composableProps } from '@dxos/react-ui';\nimport { type GetId } from '@dxos/react-ui-dnd';\nimport { mx } from '@dxos/ui-theme';\n\nimport { type VirtualizerPaginationController, useVirtualizerPagination, useVisibleItems } from '../../hooks';\nimport { useMosaicContainerContext } from './MosaicContainerContext';\nimport { MosaicPlaceholder, type MosaicPlaceholderProps } from './Placeholder';\nimport { styles } from './styles';\nimport { type MosaicTileProps } from './Tile';\n\n//\n// Mosaic Drag-and-drop\n//\n// Drop targets:\n// - Placeholders exist to allow gaps but prevent deadspace when dragging within a container.\n// - When dragging over a Tile, the placeholder next to the closest edge is activated.\n// - Placeholders expand when active; event handlers are disabled while the container is scrolling.\n//\n// [Container]\n// - [Placeholder 0.5]\n// - [Tile 1 ]\n// - [Placeholder 1.5]\n// - [Tile 2 ]\n// - [Placeholder 2.5]\n// - [Tile 3 ]\n// - [Placeholder 3.5]\n//\n// Implementation Notes\n// - We use [Radix composition](https://www.radix-ui.com/primitives/docs/guides/composition) to factor out composible aspects (e.g., Focus, Mosaic, etc.)\n// - NOTE: Use Slottable only if needed to disambiguate; otherwise a suspected Radix bug causes compositional problems.\n\nconst MOSAIC_STACK_NAME = 'MosaicStack';\n\ntype MosaicStackTileComponent<TData = any> = FC<MosaicTileProps<TData>>;\n\ntype MosaicStackProps<TData = any> = ThemedClassName<\n {\n role?: string;\n orientation?: Axis;\n getId: GetId<TData>;\n items?: readonly TData[];\n scrollIntoView?: boolean;\n Tile: MosaicStackTileComponent<TData>;\n } & Pick<MosaicTileProps<TData>, 'draggable' | 'debug'>\n>;\n\n/**\n * Linear layout of Mosaic tiles.\n * NOTE: This is a low-level component and should be wrapped by a scrollable container.\n */\nconst MosaicStackInner = composable<HTMLDivElement, MosaicStackProps>(\n (\n {\n orientation: orientationProp = 'vertical',\n getId,\n items,\n scrollIntoView = true,\n Tile,\n draggable = true,\n debug,\n ...props\n },\n forwardedRef,\n ) => {\n const {\n id,\n orientation = orientationProp,\n dragging,\n currentId,\n selectedIds,\n registerScrollTo,\n setActiveLocation,\n } = useMosaicContainerContext(MOSAIC_STACK_NAME);\n const visibleItems = useVisibleItems({ id, items, dragging: dragging?.source.data, getId });\n invariant(orientation === 'vertical' || orientation === 'horizontal', `Invalid orientation: ${orientation}`);\n\n // Reserve the dragged item's slot the instant it leaves `visibleItems`. The source is removed a frame\n // before any placeholder becomes active (the pointer still sits over the source, so no `onDragEnter`\n // has fired), which collapses the stack by the item's height and flickers the following tiles upward.\n // Activating the source-slot placeholder (location `index + 0.5`) in a layout effect fills the gap in\n // the same commit, before paint.\n const draggingSource = dragging?.source.data;\n const sourceIndex = useMemo(() => {\n if (!items || !draggingSource || draggingSource.containerId !== id) {\n return -1;\n }\n return items.findIndex((item) => getId(item) === draggingSource.id);\n }, [items, draggingSource, id, getId]);\n useLayoutEffect(() => {\n if (sourceIndex >= 0) {\n setActiveLocation(sourceIndex + 0.5);\n }\n }, [sourceIndex, setActiveLocation]);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const scrollToId = useCallback(\n (targetId: string) => {\n if (!scrollIntoView) {\n return;\n }\n\n const el = rootRef.current?.querySelector<HTMLElement>(`[data-object-id=\"${CSS.escape(targetId)}\"]`);\n el?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n },\n [scrollIntoView],\n );\n\n useEffect(() => {\n registerScrollTo(scrollToId);\n return () => registerScrollTo(undefined);\n }, [registerScrollTo, scrollToId]);\n\n const composedRef = useComposedRefs(rootRef, forwardedRef);\n return (\n <div\n {...composableProps(props, {\n role: 'list',\n classNames: [\n 'flex',\n orientation === 'horizontal' && 'h-full [&>*]:shrink-0',\n orientation === 'vertical' && 'flex-col',\n ],\n })}\n ref={composedRef}\n >\n {draggable && <InternalPlaceholder orientation={orientation} location={0.5} />}\n {visibleItems?.map((item, index) => (\n <Fragment key={getId(item)}>\n <Tile\n id={getId(item)}\n data={item}\n location={index + 1}\n draggable={draggable}\n current={getId(item) === currentId}\n selected={selectedIds?.has(getId(item))}\n debug={debug}\n />\n {draggable && <InternalPlaceholder orientation={orientation} location={index + 1.5} />}\n </Fragment>\n ))}\n </div>\n );\n },\n);\n\nMosaicStackInner.displayName = MOSAIC_STACK_NAME;\n\nconst MosaicStack = MosaicStackInner as <TData = any>(\n props: MosaicStackProps<TData> & { ref?: Ref<HTMLDivElement> },\n) => ReactElement;\n\n//\n// VirtualStack\n//\n\nconst MOSAIC_VIRTUAL_STACK_NAME = 'MosaicVirtualStack';\n\ntype MosaicVirtualStackProps<TData = any> = MosaicStackProps<TData> &\n Pick<\n ReactVirtualizerOptions<HTMLElement, HTMLDivElement>,\n 'estimateSize' | 'gap' | 'getScrollElement' | 'overscan' | 'onChange'\n > & {\n /** Enables paginated loading; see `useVirtualizerPagination`. Requires `draggable={false}`. */\n pagination?: VirtualizerPaginationController;\n /** Rows from either loaded edge at which the adjacent page is requested. @default 12. */\n paginationThreshold?: number;\n };\n\nconst MosaicVirtualStackInner = forwardRef<HTMLDivElement, MosaicVirtualStackProps>(\n (\n {\n orientation = 'vertical',\n getId,\n items,\n scrollIntoView = true,\n Tile,\n estimateSize,\n getScrollElement,\n overscan = 8,\n gap,\n pagination,\n paginationThreshold,\n onChange,\n draggable = true,\n debug,\n ...props\n },\n forwardedRef,\n ) => {\n invariant(Tile);\n invariant(!pagination || !draggable, 'pagination requires draggable={false}');\n const { id, dragging, currentId, selectedIds, registerScrollTo } =\n useMosaicContainerContext(MOSAIC_VIRTUAL_STACK_NAME);\n const visibleItems = useVisibleItems({ id, items, dragging: dragging?.source.data, getId });\n // In draggable mode virtual indices alternate: even=placeholder, odd=tile.\n // Wrap estimateSize so placeholders get 0 (their actual negligible height) and\n // tile slots receive the caller's estimate at the correct tile index.\n // This keeps getTotalSize() stable as items are measured → no scrollbar drift.\n const wrappedEstimateSize = draggable\n ? (index: number) => (index % 2 === 0 ? 0 : estimateSize(Math.floor(index / 2)))\n : estimateSize;\n\n const { onChange: handlePaginationChange, leadingSpace } = useVirtualizerPagination({\n items: visibleItems,\n getId,\n pagination,\n threshold: paginationThreshold,\n });\n const handleChange = useCallback(\n (nextVirtualizer: Virtualizer<any, any>, sync: boolean) => {\n handlePaginationChange(nextVirtualizer);\n onChange?.(nextVirtualizer, sync);\n },\n [handlePaginationChange, onChange],\n );\n\n const virtualizer = useVirtualizer({\n // NOTE: When draggable we double the number of items to allow for placeholders.\n count: draggable ? visibleItems.length * 2 + 1 : visibleItems.length,\n estimateSize: wrappedEstimateSize,\n gap,\n // Inset by `gap` (inter-item spacing) plus any pagination spacer; see `useVirtualizerPagination`.\n paddingStart: (gap ?? 0) + leadingSpace,\n paddingEnd: gap,\n // Key measurements by stable item ID so the size cache survives scrolling;\n // without this, measurements are indexed by position and are lost when items reorder.\n getItemKey: draggable\n ? (index) => (index % 2 === 0 ? `ph-${index}` : getId(visibleItems![Math.floor(index / 2)]))\n : (index) => getId(visibleItems![index]),\n getScrollElement,\n overscan,\n onChange: handleChange,\n });\n\n // Register scroll-to-item via virtualizer index lookup.\n const scrollToId = useCallback(\n (targetId: string) => {\n const itemIndex = visibleItems.findIndex((item) => getId(item) === targetId);\n if (itemIndex >= 0) {\n if (!scrollIntoView) {\n return;\n }\n\n const virtualIndex = draggable ? itemIndex * 2 + 1 : itemIndex;\n // Align to the item's start, but offset by the inter-item `gap` so the tile lands\n // one gap below the viewport edge rather than flush against it (a plain\n // `scrollToIndex({ align: 'start' })` scrolls the preceding gap out of view).\n const [offset] = virtualizer.getOffsetForIndex(virtualIndex, 'start') ?? [];\n if (offset != null) {\n virtualizer.scrollToOffset(Math.max(0, offset - (gap ?? 0)), { behavior: 'smooth' });\n }\n }\n },\n [visibleItems, getId, draggable, virtualizer, scrollIntoView, gap],\n );\n\n useEffect(() => {\n registerScrollTo(scrollToId);\n return () => registerScrollTo(undefined);\n }, [registerScrollTo, scrollToId]);\n\n const virtualItems = virtualizer.getVirtualItems();\n const getData = (index: number): { data?: any; location: number } => {\n if (draggable) {\n if (index % 2 === 0) {\n return { location: Math.floor(index / 2) + 0.5 };\n } else {\n return { data: visibleItems![Math.floor(index / 2)], location: Math.floor(index / 2) + 1 };\n }\n } else {\n return { data: visibleItems![index], location: index + 1 };\n }\n };\n\n return (\n <div\n {...composableProps(props, {\n role: 'list',\n classNames: [\n // shrink-0 is required: this div sets an explicit height via inline style (getTotalSize).\n // Without it, a parent flex container (e.g. ScrollArea.Viewport) would shrink this div\n // to the viewport height, collapsing the scroll content and causing scrollbar drift.\n 'flex shrink-0',\n orientation === 'horizontal' && 'h-full [&>*]:shrink-0',\n orientation === 'vertical' && 'flex-col',\n ],\n })}\n style={{\n position: 'relative',\n ...(orientation === 'vertical'\n ? {\n width: '100%',\n height: virtualizer.getTotalSize(),\n }\n : {\n width: virtualizer.getTotalSize(),\n height: '100%',\n }),\n }}\n ref={forwardedRef}\n >\n {virtualItems.map(({ key, index, start }) => {\n const { data, location } = getData(index);\n return (\n <div\n key={key}\n data-index={index}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n ...(orientation === 'vertical'\n ? {\n width: '100%',\n transform: `translateY(${start}px)`,\n }\n : {\n height: '100%',\n transform: `translateX(${start}px)`,\n }),\n }}\n ref={virtualizer.measureElement}\n >\n {data ? (\n <Tile\n id={getId(data)}\n data={data}\n location={location}\n draggable={draggable}\n current={getId(data) === currentId}\n selected={selectedIds?.has(getId(data))}\n debug={debug}\n />\n ) : (\n <InternalPlaceholder orientation={orientation} location={location} />\n )}\n </div>\n );\n })}\n </div>\n );\n },\n);\n\nMosaicVirtualStackInner.displayName = MOSAIC_VIRTUAL_STACK_NAME;\n\nconst MosaicVirtualStack = MosaicVirtualStackInner as <TData = any>(\n props: MosaicVirtualStackProps<TData> & { ref?: Ref<HTMLDivElement> },\n) => ReactElement;\n\n(MosaicVirtualStack as any)[Symbol.for('dxos.composable')] = true;\n\n//\n// InternalPlaceholder\n//\n\nconst InternalPlaceholder = (props: MosaicPlaceholderProps<number>) => {\n return (\n <MosaicPlaceholder {...props} classNames={styles.placeholder.root}>\n <div\n className={mx(\n 'flex h-full bg-base-surface border border-dashed border-separator rounded-xs',\n styles.placeholder.content,\n )}\n />\n </MosaicPlaceholder>\n );\n};\n\nInternalPlaceholder.displayName = 'InternalPlaceholder';\n\n//\n// Exports\n//\n\nexport { MosaicStack, MosaicVirtualStack };\n\nexport type { MosaicStackProps, MosaicStackTileComponent, MosaicVirtualStackProps };\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport {\n type Edge,\n attachClosestEdge,\n extractClosestEdge,\n} from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';\nimport { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';\nimport {\n type ElementDragPayload,\n draggable,\n dropTargetForElements,\n} from '@atlaskit/pragmatic-drag-and-drop/element/adapter';\nimport { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';\nimport { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';\nimport { type DropTargetRecord } from '@atlaskit/pragmatic-drag-and-drop/types';\nimport { composeRefs } from '@radix-ui/react-compose-refs';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { Slot } from '@radix-ui/react-slot';\nimport React, {\n type PropsWithChildren,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport { composableProps, slottable } from '@dxos/react-ui';\nimport {\n type DndLocation,\n type DndTileData,\n type Size,\n getSourceData,\n resizeAttributes,\n sizeStyle,\n} from '@dxos/react-ui-dnd';\n\nimport { useMosaicContainerContext } from './MosaicContainerContext';\nimport { MOSAIC_TILE_NAME, MosaicTileContextProvider, type MosaicTileState } from './MosaicTileContext';\n\n//\n// Tile\n//\n\n// State attribute: data-[mosaic-tile-state=dragging]\nconst MOSAIC_TILE_STATE_ATTR = 'mosaic-tile-state';\n\ntype MosaicTileProps<TData = any, TLocation = DndLocation> = ThemedClassName<\n PropsWithChildren<{\n className?: string;\n dragHandle?: HTMLElement | null;\n allowedEdges?: Edge[];\n id: string;\n data: TData;\n location: TLocation;\n draggable?: boolean;\n /** Whether this tile is the current (aria-current) item. */\n current?: boolean;\n /** Whether this tile is selected (aria-selected). */\n selected?: boolean;\n /**\n * Initial extent in rem (width when the container is horizontal, height when vertical).\n * Pair with a child `Mosaic.ResizeHandle` to make the tile user-resizable; the consumer\n * persists committed sizes via {@link MosaicTileProps.onSizeChange}.\n */\n size?: Size;\n /** Called when the user commits a resize (on drop). */\n onSizeChange?: (size: Size) => void;\n /** Lower bound for the resizable extent in rem; enforced during drag and as a CSS min constraint. */\n minSize?: number;\n /** Upper bound for the resizable extent in rem; enforced during drag and as a CSS max constraint. */\n maxSize?: number;\n debug?: boolean;\n }>\n>;\n\nconst MosaicTile = slottable<HTMLDivElement, MosaicTileProps>(\n (\n {\n children,\n asChild,\n dragHandle: dragHandleProp,\n allowedEdges: allowedEdgesProp,\n location,\n id,\n data: dataProp,\n draggable: draggableProp,\n current,\n selected,\n size: sizeProp,\n onSizeChange,\n minSize,\n maxSize,\n debug: _,\n ...props\n },\n forwardedRef,\n ) => {\n const Comp = asChild ? Slot : Primitive.div;\n const rootRef = useRef<HTMLDivElement>(null);\n const composedRef = composeRefs<HTMLDivElement>(rootRef, forwardedRef);\n\n // State.\n const {\n id: containerId,\n eventHandler,\n orientation,\n scrolling,\n setActiveLocation,\n } = useMosaicContainerContext(MOSAIC_TILE_NAME);\n const [state, setState] = useState<MosaicTileState>({ type: 'idle' });\n\n // A child `Mosaic.DragHandle` registers its element here; an explicit `dragHandle` prop wins.\n const [registeredDragHandle, setRegisteredDragHandle] = useState<HTMLElement | null>(null);\n const dragHandle = dragHandleProp ?? registeredDragHandle;\n\n // Live extent during a resize drag. Seeded from the prop; the consumer persists committed\n // sizes via `onSizeChange` and feeds the result back as `size` on the next render.\n const [size, setInternalSize] = useState<Size | undefined>(sizeProp);\n const setSize = useCallback(\n (nextSize: Size, commit?: boolean) => {\n setInternalSize(nextSize);\n if (commit) {\n onSizeChange?.(nextSize);\n }\n },\n [onSizeChange],\n );\n // The `size` prop is the source of truth; internal state exists only to reflect the live extent\n // during a drag (which commits back through `onSizeChange`). Re-sync when the prop changes so a\n // tile that first rendered without a size — e.g. before the breakpoint settled, or a\n // mobile/fullbleed → sliding branch switch that swaps `size` in — applies it once it arrives,\n // instead of staying stuck at its initial (often `undefined`) extent. A live drag never changes\n // the prop (only the committed drop does), so this does not fight the drag.\n useEffect(() => {\n setInternalSize(sizeProp);\n }, [sizeProp]);\n\n const allowedEdges = useMemo<Edge[]>(\n () => allowedEdgesProp || (orientation === 'vertical' ? ['top', 'bottom'] : ['left', 'right']),\n [allowedEdgesProp, orientation],\n );\n\n const data = useMemo<DndTileData>(\n () =>\n ({\n type: 'tile',\n id,\n containerId,\n data: dataProp,\n location,\n }) satisfies DndTileData,\n [containerId, location, dataProp],\n );\n\n useLayoutEffect(() => {\n const root = rootRef.current;\n if (!draggableProp || !root || !containerId || scrolling) {\n return;\n }\n\n const handleChange = ({ self, source }: { self: DropTargetRecord; source: ElementDragPayload }) => {\n if (source.data.id !== dataProp.id) {\n const closestEdge = extractClosestEdge(self.data);\n const location = data.location + (closestEdge === 'top' || closestEdge === 'left' ? -0.5 : 0.5);\n setActiveLocation(location);\n setState({ type: 'target', closestEdge });\n }\n };\n\n // Mark the drag as a move at the native level. pragmatic-drag-and-drop only sets `dropEffect` (on\n // dragover via `getDropEffect`), never `effectAllowed`, so the first dragstart frame shows the\n // browser's default green \"+\" copy cursor until the first drop target is entered.\n const handleNativeDragStart = (event: DragEvent) => {\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n }\n };\n root.addEventListener('dragstart', handleNativeDragStart);\n\n return combine(\n () => root.removeEventListener('dragstart', handleNativeDragStart),\n // Source.\n draggable({\n element: root,\n dragHandle: dragHandle && state.type !== 'preview' ? dragHandle : undefined,\n canDrag: () => true,\n getInitialData: () => data,\n onGenerateDragPreview: ({ location, nativeSetDragImage }) => {\n setCustomNativeDragPreview({\n nativeSetDragImage,\n getOffset: preserveOffsetOnSource({\n element: root,\n input: location.current.input,\n }),\n render: ({ container }) => {\n data.bounds = root.getBoundingClientRect();\n setState({\n type: 'preview',\n container,\n rect: root.getBoundingClientRect(),\n });\n return () => setState({ type: 'dragging' });\n },\n });\n },\n\n onDragStart: () => {\n setState({ type: 'dragging' });\n },\n onDrop: () => {\n setState({ type: 'idle' });\n },\n }),\n\n // Target.\n dropTargetForElements({\n element: root,\n getData: ({ input, element }) => attachClosestEdge(data, { input, element, allowedEdges }),\n canDrop: ({ source }) => {\n const data = getSourceData(source);\n return (data && eventHandler.canDrop?.({ source: data })) || false;\n },\n // Reorder is a move, not a copy — otherwise the browser shows the green \"+\" copy cursor.\n getDropEffect: () => 'move',\n onDragEnter: ({ self, source }) => {\n handleChange({ self, source });\n },\n onDragLeave: () => {\n setState({ type: 'idle' });\n setActiveLocation(undefined);\n },\n onDrag: ({ self, source }) => {\n handleChange({ self, source });\n },\n onDrop: () => {\n setState({ type: 'idle' });\n setActiveLocation(undefined);\n },\n }),\n );\n }, [\n rootRef,\n forwardedRef,\n containerId,\n dragHandle,\n eventHandler,\n data,\n scrolling,\n allowedEdges,\n setActiveLocation,\n ]);\n\n const { className, ...rest } = composableProps(props, { classNames: 'relative outline-none' });\n\n // Apply the resize subject marker + explicit extent/bounds only when sized or bounded, so plain\n // tiles keep their intrinsic layout. The axis follows the container orientation (width vs height).\n const vertical = orientation === 'vertical';\n const sized = size != null;\n const bounded = sized || minSize != null || maxSize != null;\n const sizeStyles = {\n ...(sized && sizeStyle(size, vertical ? 'vertical' : 'horizontal')),\n ...(minSize != null && { [vertical ? 'minBlockSize' : 'minInlineSize']: `${minSize}rem` }),\n ...(maxSize != null && { [vertical ? 'maxBlockSize' : 'maxInlineSize']: `${maxSize}rem` }),\n };\n\n // NOTE: Ensure no gaps between cells (prevent drop indicators flickering).\n // NOTE: Ensure padding doesn't change position of cursor when dragging (no margins).\n return (\n <MosaicTileContextProvider\n state={state}\n setDragHandle={setRegisteredDragHandle}\n size={size}\n setSize={setSize}\n minSize={minSize}\n maxSize={maxSize}\n >\n <Comp\n {...rest}\n {...(bounded && resizeAttributes)}\n {...(bounded && { style: { ...rest.style, ...sizeStyles } })}\n {...{\n 'data-object-id': id,\n [`data-${MOSAIC_TILE_STATE_ATTR}`]: state.type,\n }}\n role='listitem'\n // Pair `current` / `selected` props with `aria-current` / `aria-selected`\n // so the `dx-current` / `dx-selected` / `dx-hover` utilities (which key\n // off those attributes) actually fire. Without this the props are purely\n // advisory and the corresponding styling silently no-ops.\n aria-current={current ? 'true' : undefined}\n aria-selected={selected ? 'true' : undefined}\n className={className}\n ref={composedRef}\n >\n {children}\n </Comp>\n\n {/* Dragging preview. Cloned at the source size; the live tile is removed from the list while\n dragging, so this clone is what the user sees following the cursor. NOTE: external SVG sprite\n `<use>` icons do not rasterize here — use inline SVG (see Mosaic.DragHandle) for drag affordances. */}\n {state.type === 'preview' &&\n createPortal(\n <Comp\n {...{\n // NOTE: Use to control appearance while dragging.\n [`data-${MOSAIC_TILE_STATE_ATTR}`]: state.type,\n }}\n className={className}\n style={{\n width: `${state.rect.width}px`,\n height: `${state.rect.height}px`,\n }}\n >\n {children}\n </Comp>,\n state.container,\n )}\n </MosaicTileContextProvider>\n );\n },\n);\n\nMosaicTile.displayName = MOSAIC_TILE_NAME;\n\nexport { MosaicTile };\n\nexport type { MosaicTileProps };\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { MosaicContainer, type MosaicContainerProps, type MosaicScrollController } from './Container';\nimport { MosaicDragHandle, type MosaicDragHandleProps } from './DragHandle';\nimport { type MosaicContainerState, useMosaicContainerContext } from './MosaicContainerContext';\nimport { type MosaicTileState, useMosaicTileContext } from './MosaicTileContext';\nimport {\n MosaicDropIndicator,\n type MosaicDropIndicatorProps,\n MosaicPlaceholder,\n type MosaicPlaceholderProps,\n} from './Placeholder';\nimport { MosaicResizeHandle, type MosaicResizeHandleProps } from './ResizeHandle';\nimport { MosaicStack, type MosaicStackProps, type MosaicStackTileComponent, MosaicVirtualStack } from './Stack';\nimport { MosaicTile, type MosaicTileProps } from './Tile';\n\n//\n// Mosaic\n//\n\nexport const Mosaic = {\n Container: MosaicContainer,\n Tile: MosaicTile,\n DragHandle: MosaicDragHandle,\n ResizeHandle: MosaicResizeHandle,\n Placeholder: MosaicPlaceholder,\n DropIndicator: MosaicDropIndicator,\n Stack: MosaicStack,\n VirtualStack: MosaicVirtualStack,\n};\n\nexport type {\n MosaicContainerProps,\n MosaicContainerState,\n MosaicDragHandleProps,\n MosaicDropIndicatorProps,\n MosaicPlaceholderProps,\n MosaicResizeHandleProps,\n MosaicScrollController,\n MosaicStackProps,\n MosaicStackTileComponent,\n MosaicTileProps,\n MosaicTileState,\n};\n\nexport { useMosaicContainerContext as useMosaicContainer, useMosaicTileContext as useMosaicTile };\n"],"mappings":"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"}
|