@adea-ai/ui 0.97.7 → 0.98.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"split-layout.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"names":[],"mappings":"AACA,OAAO,EAQL,KAAK,QAAQ,EACb,KAAK,GAAG,EACT,MAAM,UAAU,CAAA;AAKjB,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAE5C,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAA;AAEhB,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,eAAe,IAAI;IACxD,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;IACjC,yFAAyF;IACzF,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IAC9C,yFAAyF;IACzF,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IACpD,+GAA+G;IAC/G,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IACrB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;IAC5D,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,sFAAsF;IACtF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAChD,qGAAqG;IACrG,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,CAAA;IAC3E,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AASD,mGAAmG;AACnG,wBAAgB,WAAW,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,eAuShF"}
1
+ {"version":3,"file":"split-layout.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"names":[],"mappings":"AACA,OAAO,EAQL,KAAK,QAAQ,EACb,KAAK,GAAG,EACT,MAAM,UAAU,CAAA;AAKjB,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAE5C,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAA;AAEhB,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,eAAe,IAAI;IACxD,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;IACjC,yFAAyF;IACzF,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IAC9C,yFAAyF;IACzF,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IACpD,+GAA+G;IAC/G,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IACrB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;IAC5D,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,sFAAsF;IACtF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAChD,qGAAqG;IACrG,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,CAAA;IAC3E,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AASD,mGAAmG;AACnG,wBAAgB,WAAW,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,eAuThF"}
@@ -9,7 +9,7 @@ import { For, createComputed, createMemo, createSignal, createUniqueId, on, onCl
9
9
  import Resizable from "@corvu/resizable";
10
10
  //#region src/components/layout/split-layout/split-layout.tsx
11
11
  var _tmpl$ = /*#__PURE__*/ template(`<div role=group data-slot=split-layout><span class=sr-only role=status>`);
12
- var _tmpl$2 = /*#__PURE__*/ template(`<section role=region class="absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"><header class="flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2"><span data-pane-drag-handle class="flex min-w-0 flex-1 items-center gap-2 truncate text-sm"><span class="min-w-0 flex-1 truncate"></span></span></header><div class="min-h-0 min-w-0 flex-1 overflow-auto">`);
12
+ var _tmpl$2 = /*#__PURE__*/ template(`<section role=region class="absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border transition-opacity data-[drag-source]:opacity-40 data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"><header class="flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2"><span data-pane-drag-handle><span class="min-w-0 flex-1 truncate"></span></span></header><div class="min-h-0 min-w-0 flex-1 overflow-auto">`);
13
13
  var _tmpl$3 = /*#__PURE__*/ template(`<div aria-hidden=true>`);
14
14
  var PANE_DRAG_TYPE = "application/x-adea-pane-move";
15
15
  function rectStyle(rect) {
@@ -161,6 +161,9 @@ function SplitLayout(props) {
161
161
  });
162
162
  event.dataTransfer.setData(PANE_DRAG_TYPE, token);
163
163
  event.dataTransfer.effectAllowed = "move";
164
+ const source = refs.get(id);
165
+ const frame = source?.getBoundingClientRect();
166
+ if (source && frame && typeof event.dataTransfer.setDragImage === "function") event.dataTransfer.setDragImage(source, Math.max(0, Math.round(event.clientX - frame.left)), Math.max(0, Math.round(event.clientY - frame.top)));
164
167
  });
165
168
  insert(_el$5, (() => {
166
169
  var _c$ = memo(() => !!props.onMove);
@@ -200,21 +203,23 @@ function SplitLayout(props) {
200
203
  })() : null;
201
204
  })(), null);
202
205
  effect((_p$) => {
203
- var _v$3 = domId(id), _v$4 = props.labelForLeaf(leaf()), _v$5 = props.paneTabIndex ?? -1, _v$6 = props.state.focusedLeafId === id ? "" : void 0, _v$7 = intent()?.direction, _v$8 = intent()?.placement, _v$9 = rectStyle(frames().get(id)?.rect ?? {
206
+ var _v$4 = domId(id), _v$5 = props.labelForLeaf(leaf()), _v$6 = props.paneTabIndex ?? -1, _v$7 = props.state.focusedLeafId === id ? "" : void 0, _v$8 = drag()?.id === id ? "" : void 0, _v$9 = intent()?.direction, _v$0 = intent()?.placement, _v$1 = rectStyle(frames().get(id)?.rect ?? {
204
207
  x: 0,
205
208
  y: 0,
206
209
  width: 0,
207
210
  height: 0
208
- }), _v$0 = Boolean(props.onMove), _v$1 = props.onMove ? `Drag ${props.labelForLeaf(leaf())} to move` : void 0;
209
- _v$3 !== _p$.e && setAttribute(_el$3, "id", _p$.e = _v$3);
210
- _v$4 !== _p$.t && setAttribute(_el$3, "aria-label", _p$.t = _v$4);
211
- _v$5 !== _p$.a && setAttribute(_el$3, "tabindex", _p$.a = _v$5);
212
- _v$6 !== _p$.o && setAttribute(_el$3, "data-focused", _p$.o = _v$6);
213
- _v$7 !== _p$.i && setAttribute(_el$3, "data-drop-direction", _p$.i = _v$7);
214
- _v$8 !== _p$.n && setAttribute(_el$3, "data-drop-placement", _p$.n = _v$8);
215
- _p$.s = style(_el$3, _v$9, _p$.s);
216
- _v$0 !== _p$.h && setAttribute(_el$5, "draggable", _p$.h = _v$0);
217
- _v$1 !== _p$.r && setAttribute(_el$5, "title", _p$.r = _v$1);
211
+ }), _v$10 = Boolean(props.onMove), _v$11 = cn("flex min-w-0 flex-1 items-center gap-2 truncate text-sm", { "cursor-grab": Boolean(props.onMove) }), _v$12 = props.onMove ? `Drag ${props.labelForLeaf(leaf())} to move` : void 0;
212
+ _v$4 !== _p$.e && setAttribute(_el$3, "id", _p$.e = _v$4);
213
+ _v$5 !== _p$.t && setAttribute(_el$3, "aria-label", _p$.t = _v$5);
214
+ _v$6 !== _p$.a && setAttribute(_el$3, "tabindex", _p$.a = _v$6);
215
+ _v$7 !== _p$.o && setAttribute(_el$3, "data-focused", _p$.o = _v$7);
216
+ _v$8 !== _p$.i && setAttribute(_el$3, "data-drag-source", _p$.i = _v$8);
217
+ _v$9 !== _p$.n && setAttribute(_el$3, "data-drop-direction", _p$.n = _v$9);
218
+ _v$0 !== _p$.s && setAttribute(_el$3, "data-drop-placement", _p$.s = _v$0);
219
+ _p$.h = style(_el$3, _v$1, _p$.h);
220
+ _v$10 !== _p$.r && setAttribute(_el$5, "draggable", _p$.r = _v$10);
221
+ _v$11 !== _p$.d && className(_el$5, _p$.d = _v$11);
222
+ _v$12 !== _p$.l && setAttribute(_el$5, "title", _p$.l = _v$12);
218
223
  return _p$;
219
224
  }, {
220
225
  e: void 0,
@@ -225,7 +230,9 @@ function SplitLayout(props) {
225
230
  n: void 0,
226
231
  s: void 0,
227
232
  h: void 0,
228
- r: void 0
233
+ r: void 0,
234
+ d: void 0,
235
+ l: void 0
229
236
  });
230
237
  return _el$3;
231
238
  })();
@@ -296,13 +303,15 @@ function SplitLayout(props) {
296
303
  }
297
304
  }), null);
298
305
  effect((_p$) => {
299
- var _v$ = props.label, _v$2 = cn("relative size-full min-h-0 min-w-0", props.class);
306
+ var _v$ = props.label, _v$2 = drag() ? "" : void 0, _v$3 = cn("relative size-full min-h-0 min-w-0 data-[dragging]:cursor-grabbing", props.class);
300
307
  _v$ !== _p$.e && setAttribute(_el$, "aria-label", _p$.e = _v$);
301
- _v$2 !== _p$.t && className(_el$, _p$.t = _v$2);
308
+ _v$2 !== _p$.t && setAttribute(_el$, "data-dragging", _p$.t = _v$2);
309
+ _v$3 !== _p$.a && className(_el$, _p$.a = _v$3);
302
310
  return _p$;
303
311
  }, {
304
312
  e: void 0,
305
- t: void 0
313
+ t: void 0,
314
+ a: void 0
306
315
  });
307
316
  return _el$;
308
317
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"split-layout.js","names":["Resizable","For","createMemo","createComputed","createUniqueId","createSignal","onCleanup","on","Accessor","JSX","X","GripVertical","Button","cn","computeLayoutFrames","LayoutRect","paneDropIntent","PaneDropIntent","PANE_DRAG_TYPE","listLeaves","MIN_SPLIT_RATIO","MAX_SPLIT_RATIO","SplitLayoutBranch","SplitLayoutLeaf","SplitLayoutState","SplitLayoutProps","state","L","label","labelForLeaf","leaf","renderLeaf","Element","renderPaneLabel","paneTabIndex","labelForSeparator","branch","onResize","splitId","ratio","onFocus","leafId","onClose","onMove","targetId","intent","renderPaneActions","class","rectStyle","rect","CSSProperties","left","x","top","y","width","height","SplitLayout","props","root","HTMLDivElement","pendingFrame","refs","Map","HTMLElement","domIds","prefix","nextDomId","nextDragId","drag","setDrag","id","token","drop","setDrop","clearDrag","undefined","domId","existing","get","created","set","leaves","center","leafMap","map","frames","branches","Array","from","values","flatMap","frame","node","kind","current","has","target","allowedTarget","transfer","DataTransfer","types","includes","dropLabel","placement","branchMap","schedule","action","cancelAnimationFrame","requestAnimationFrame","active","ownerDocument","activeElement","contains","field","HTMLTextAreaElement","HTMLInputElement","selection","start","selectionStart","end","selectionEnd","direction","selectionDirection","isConnected","body","focus","preventScroll","setSelectionRange","clear","close","next","_el$","_tmpl$","_el$2","firstChild","_$use","el","_$insert","_$createComponent","each","children","initial","content","paneLabel","actions","delete","_el$3","_tmpl$2","_el$4","_el$5","_el$6","_el$7","nextSibling","$$focusin","addEventListener","event","dataTransfer","clientX","clientY","currentTarget","getBoundingClientRect","accepted","getData","preventDefault","relatedTarget","Node","dropEffect","_$setAttribute","setData","effectAllowed","_c$","_$memo","_c$2","variant","size","aria-label","onClick","_c$3","_el$8","_tmpl$3","_$effect","_$className","_p$","_v$3","_v$4","_v$5","_v$6","focusedLeafId","_v$7","_v$8","_v$9","_v$0","Boolean","_v$1","e","t","a","o","i","n","s","_$style","h","r","orientation","sizes","keyboardDelta","onSizesChange","getClientRects","length","some","Number","isFinite","Math","abs","style","Panel","minSize","maxSize","Handle","aria-orientation","aria-controls","join","aria-valuenow","round","_v$","_v$2","_$delegateEvents","_$createComponent","_$memo","_$className","_$setAttribute","_$style","_$delegateEvents"],"sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"sourcesContent":["import Resizable from '@corvu/resizable'\nimport {\n For,\n createMemo,\n createComputed,\n createUniqueId,\n createSignal,\n onCleanup,\n on,\n type Accessor,\n type JSX,\n} from 'solid-js'\nimport { X, GripVertical } from 'lucide-solid'\nimport { Button } from '../../ui/button'\nimport { cn } from '#lib/utils'\nimport { computeLayoutFrames, type LayoutRect } from './geometry'\nimport { paneDropIntent, type PaneDropIntent } from './drop'\nexport type { PaneDropIntent } from './drop'\nconst PANE_DRAG_TYPE = 'application/x-adea-pane-move'\nimport {\n listLeaves,\n MIN_SPLIT_RATIO,\n MAX_SPLIT_RATIO,\n type SplitLayoutBranch,\n type SplitLayoutLeaf,\n type SplitLayoutState,\n} from './model'\n\nexport type SplitLayoutProps<L extends SplitLayoutLeaf> = {\n state: SplitLayoutState<L>\n label: string\n /** Accessible name for a pane region and its close button. */\n labelForLeaf: (leaf: L) => string\n /** Called once per stable leaf owner; the accessor tracks opaque payload replacement. */\n renderLeaf: (leaf: Accessor<L>) => JSX.Element\n /** Inline visible header composition, separate from the region and close-button name. */\n renderPaneLabel?: (leaf: Accessor<L>) => JSX.Element\n /** Whether pane regions participate in sequential keyboard navigation; defaults to programmatic focus only. */\n paneTabIndex?: 0 | -1\n /** Accessible splitter name; defaults to the current orientation-specific label. */\n labelForSeparator?: (branch: SplitLayoutBranch<L>) => string\n onResize: (splitId: string, ratio: number) => void\n onFocus?: (leafId: string) => void\n /** Host performs the model transition and returns the surviving focus destination. */\n onClose?: (leafId: string) => string | undefined\n /** Pointer placement only; the host supplies keyboard commands and performs the model transition. */\n onMove?: (leafId: string, targetId: string, intent: PaneDropIntent) => void\n /** Stable header composition for host-owned keyboard actions/capability feedback. */\n renderPaneActions?: (leaf: Accessor<L>) => JSX.Element\n class?: string\n}\nfunction rectStyle(rect: LayoutRect): JSX.CSSProperties {\n return {\n left: `${rect.x * 100}%`,\n top: `${rect.y * 100}%`,\n width: `${rect.width * 100}%`,\n height: `${rect.height * 100}%`,\n }\n}\n/** Muxy frame geometry keeps leaf owners stable; Corvu owns constrained separator interactions. */\nexport function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L>) {\n let root: HTMLDivElement | undefined\n let pendingFrame: number | undefined\n const refs = new Map<string, HTMLElement>()\n const domIds = new Map<string, string>()\n const prefix = createUniqueId()\n let nextDomId = 0\n let nextDragId = 0\n const [drag, setDrag] = createSignal<{ id: string; token: string }>()\n const [drop, setDrop] = createSignal<{ id: string; intent: PaneDropIntent }>()\n const clearDrag = () => {\n setDrag(undefined)\n setDrop(undefined)\n }\n const domId = (id: string) => {\n const existing = domIds.get(id)\n if (existing) return existing\n const created = `${prefix}-pane-${nextDomId++}`\n domIds.set(id, created)\n return created\n }\n const leaves = createMemo(() => listLeaves(props.state.center))\n const leafMap = createMemo(() => new Map(leaves().map((leaf) => [leaf.id, leaf])))\n const frames = createMemo(() => computeLayoutFrames(props.state.center))\n const branches = createMemo(() =>\n Array.from(frames().values()).flatMap((frame) =>\n frame.node.kind === 'split' ? [frame.node] : []\n )\n )\n createComputed(() => {\n const current = drag()\n if (current && (!props.onMove || !leafMap().has(current.id))) clearDrag()\n const target = drop()\n if (target && !leafMap().has(target.id)) setDrop(undefined)\n })\n const allowedTarget = (id: string, transfer: DataTransfer | null) => {\n const current = drag()\n return props.onMove &&\n current &&\n current.id !== id &&\n leafMap().has(current.id) &&\n leafMap().has(id) &&\n transfer?.types.includes(PANE_DRAG_TYPE)\n ? current\n : undefined\n }\n const dropLabel = createMemo(() => {\n const target = drop()\n const leaf = target ? leafMap().get(target.id) : undefined\n return target && leaf\n ? `Drop to place pane ${target.intent.placement} ${props.labelForLeaf(leaf)}`\n : ''\n })\n const branchMap = createMemo(() => new Map(branches().map((branch) => [branch.id, branch])))\n const schedule = (action: () => void) => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n pendingFrame = requestAnimationFrame(() => {\n pendingFrame = undefined\n action()\n })\n }\n // Register before keyed children update: capture a focused editor before an\n // ordered DOM move can blur it. Never override a newer focus outside this root.\n createComputed(\n on(\n () => props.state.center,\n () => {\n const active = root?.ownerDocument.activeElement\n if (!root || !(active instanceof HTMLElement) || !root.contains(active)) return\n const field =\n active instanceof HTMLTextAreaElement || active instanceof HTMLInputElement\n ? active\n : undefined\n const selection = field\n ? {\n start: field.selectionStart,\n end: field.selectionEnd,\n direction: field.selectionDirection,\n }\n : undefined\n schedule(() => {\n if (!active.isConnected || !root?.contains(active)) return\n const current = active.ownerDocument.activeElement\n if (current !== active && current !== active.ownerDocument.body) return\n active.focus({ preventScroll: true })\n if (field && selection?.start !== null && selection?.end !== null && selection)\n field.setSelectionRange(\n selection.start,\n selection.end,\n selection.direction ?? undefined\n )\n })\n }\n )\n )\n onCleanup(() => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n clearDrag()\n refs.clear()\n domIds.clear()\n })\n const close = (id: string) => {\n const next = props.onClose?.(id)\n if (next) schedule(() => refs.get(next)?.focus({ preventScroll: true }))\n }\n return (\n <div\n ref={(el) => {\n root = el\n }}\n role=\"group\"\n aria-label={props.label}\n data-slot=\"split-layout\"\n class={cn('relative size-full min-h-0 min-w-0', props.class)}\n >\n <For each={leaves().map((leaf) => leaf.id)}>\n {(id) => {\n const initial = leafMap().get(id)!\n const leaf = () => leafMap().get(id) ?? initial\n const content = props.renderLeaf(leaf)\n const paneLabel = props.renderPaneLabel?.(leaf)\n const actions = props.renderPaneActions?.(leaf)\n const intent = () => (drop()?.id === id ? drop()?.intent : undefined)\n onCleanup(() => {\n refs.delete(id)\n domIds.delete(id)\n })\n return (\n <section\n ref={(el) => refs.set(id, el)}\n id={domId(id)}\n role=\"region\"\n aria-label={props.labelForLeaf(leaf())}\n tabIndex={props.paneTabIndex ?? -1}\n data-pane-id={id}\n data-focused={props.state.focusedLeafId === id ? '' : undefined}\n data-drop-direction={intent()?.direction}\n data-drop-placement={intent()?.placement}\n onDragOver={(event) => {\n if (!allowedTarget(id, event.dataTransfer)) return\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n if (!next) {\n setDrop(undefined)\n return\n }\n event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'\n setDrop({ id, intent: next })\n }}\n onDragLeave={(event) => {\n if (\n event.relatedTarget instanceof Node &&\n event.currentTarget.contains(event.relatedTarget)\n )\n return\n if (drop()?.id === id) setDrop(undefined)\n }}\n onDrop={(event) => {\n const current = allowedTarget(id, event.dataTransfer)\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n const accepted =\n current && next && event.dataTransfer?.getData(PANE_DRAG_TYPE) === current.token\n clearDrag()\n if (!accepted) return\n event.preventDefault()\n props.onMove?.(current.id, id, next)\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring\"\n onFocusIn={() => props.onFocus?.(id)}\n >\n <header class=\"flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2\">\n <span\n data-pane-drag-handle=\"\"\n draggable={Boolean(props.onMove)}\n class=\"flex min-w-0 flex-1 items-center gap-2 truncate text-sm\"\n title={props.onMove ? `Drag ${props.labelForLeaf(leaf())} to move` : undefined}\n onDragStart={(event) => {\n if (!props.onMove || !event.dataTransfer) {\n event.preventDefault()\n return\n }\n const token = `${prefix}-${++nextDragId}`\n setDrag({ id, token })\n event.dataTransfer.setData(PANE_DRAG_TYPE, token)\n event.dataTransfer.effectAllowed = 'move'\n }}\n onDragEnd={clearDrag}\n >\n {props.onMove ? (\n <GripVertical class=\"size-3 shrink-0\" aria-hidden=\"true\" />\n ) : null}\n <span class=\"min-w-0 flex-1 truncate\">\n {paneLabel ?? props.labelForLeaf(leaf())}\n </span>\n </span>\n {actions}\n {props.onClose ? (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={`Close ${props.labelForLeaf(leaf())}`}\n onClick={() => close(id)}\n >\n <X />\n </Button>\n ) : null}\n </header>\n <div class=\"min-h-0 min-w-0 flex-1 overflow-auto\">{content}</div>\n {intent() ? (\n <div\n aria-hidden=\"true\"\n class={cn('pointer-events-none absolute border-2 border-primary bg-primary/10', {\n 'inset-y-0 left-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'before',\n 'inset-y-0 right-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'after',\n 'inset-x-0 top-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'before',\n 'inset-x-0 bottom-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'after',\n })}\n />\n ) : null}\n </section>\n )\n }}\n </For>\n <span class=\"sr-only\" role=\"status\">\n {dropLabel()}\n </span>\n <For each={branches().map((branch) => branch.id)}>\n {(id) => {\n const initial = branchMap().get(id)!\n const branch: Accessor<SplitLayoutBranch<L>> = () => branchMap().get(id) ?? initial\n return (\n <Resizable\n orientation={branch().direction === 'row' ? 'horizontal' : 'vertical'}\n sizes={[branch().ratio, 1 - branch().ratio]}\n keyboardDelta={0.05}\n onSizesChange={(sizes) => {\n // Corvu also reports panel registration/unregistration while\n // mounting or disposing a controller. Those incomplete or\n // hidden-host sizes are not user resize intent.\n if (!root?.isConnected || root.getClientRects().length === 0) return\n if (\n sizes.length !== 2 ||\n sizes.some((size) => !Number.isFinite(size)) ||\n Math.abs(sizes[0]! + sizes[1]! - 1) > 0.000001\n )\n return\n if (sizes[0] !== undefined && Math.abs(sizes[0] - branch().ratio) > 0.000001)\n props.onResize(id, sizes[0])\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"pointer-events-none absolute flex min-h-0 min-w-0 data-[orientation=vertical]:flex-col\"\n >\n <Resizable.Panel\n minSize={MIN_SPLIT_RATIO}\n maxSize={MAX_SPLIT_RATIO}\n aria-hidden=\"true\"\n />\n <Resizable.Handle\n aria-label={\n props.labelForSeparator?.(branch()) ??\n (branch().direction === 'row' ? 'Resize pane columns' : 'Resize pane rows')\n }\n aria-orientation={branch().direction === 'row' ? 'vertical' : 'horizontal'}\n aria-controls={listLeaves(branch())\n .map((leaf) => domId(leaf.id))\n .join(' ')}\n aria-valuemin={10}\n aria-valuemax={90}\n aria-valuenow={Math.round(branch().ratio * 100)}\n class=\"pointer-events-auto relative w-px shrink-0 bg-border after:absolute after:inset-y-0 after:-inset-x-1 after:w-3 focus-visible:bg-primary focus-visible:outline-none hover:bg-primary data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:inset-x-0 data-[orientation=vertical]:after:-inset-y-1 data-[orientation=vertical]:after:h-3 data-[orientation=vertical]:after:w-full\"\n />\n <Resizable.Panel\n minSize={MIN_SPLIT_RATIO}\n maxSize={MAX_SPLIT_RATIO}\n aria-hidden=\"true\"\n />\n </Resizable>\n )\n }}\n </For>\n </div>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"split-layout.js","names":["Resizable","For","createMemo","createComputed","createUniqueId","createSignal","onCleanup","on","Accessor","JSX","X","GripVertical","Button","cn","computeLayoutFrames","LayoutRect","paneDropIntent","PaneDropIntent","PANE_DRAG_TYPE","listLeaves","MIN_SPLIT_RATIO","MAX_SPLIT_RATIO","SplitLayoutBranch","SplitLayoutLeaf","SplitLayoutState","SplitLayoutProps","state","L","label","labelForLeaf","leaf","renderLeaf","Element","renderPaneLabel","paneTabIndex","labelForSeparator","branch","onResize","splitId","ratio","onFocus","leafId","onClose","onMove","targetId","intent","renderPaneActions","class","rectStyle","rect","CSSProperties","left","x","top","y","width","height","SplitLayout","props","root","HTMLDivElement","pendingFrame","refs","Map","HTMLElement","domIds","prefix","nextDomId","nextDragId","drag","setDrag","id","token","drop","setDrop","clearDrag","undefined","domId","existing","get","created","set","leaves","center","leafMap","map","frames","branches","Array","from","values","flatMap","frame","node","kind","current","has","target","allowedTarget","transfer","DataTransfer","types","includes","dropLabel","placement","branchMap","schedule","action","cancelAnimationFrame","requestAnimationFrame","active","ownerDocument","activeElement","contains","field","HTMLTextAreaElement","HTMLInputElement","selection","start","selectionStart","end","selectionEnd","direction","selectionDirection","isConnected","body","focus","preventScroll","setSelectionRange","clear","close","next","_el$","_tmpl$","_el$2","firstChild","_$use","el","_$insert","_$createComponent","each","children","initial","content","paneLabel","actions","delete","_el$3","_tmpl$2","_el$4","_el$5","_el$6","_el$7","nextSibling","$$focusin","addEventListener","event","dataTransfer","clientX","clientY","currentTarget","getBoundingClientRect","accepted","getData","preventDefault","relatedTarget","Node","dropEffect","_$setAttribute","setData","effectAllowed","source","setDragImage","Math","max","round","_c$","_$memo","_c$2","variant","size","aria-label","onClick","_c$3","_el$8","_tmpl$3","_$effect","_$className","_p$","_v$4","_v$5","_v$6","_v$7","focusedLeafId","_v$8","_v$9","_v$0","_v$1","_v$10","Boolean","_v$11","_v$12","e","t","a","o","i","n","s","h","_$style","r","d","l","orientation","sizes","keyboardDelta","onSizesChange","getClientRects","length","some","Number","isFinite","abs","style","Panel","minSize","maxSize","Handle","aria-orientation","aria-controls","join","aria-valuenow","_v$","_v$2","_v$3","_$delegateEvents","_$createComponent","_$memo","_$className","_$setAttribute","_$style","_$delegateEvents"],"sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"sourcesContent":["import Resizable from '@corvu/resizable'\nimport {\n For,\n createMemo,\n createComputed,\n createUniqueId,\n createSignal,\n onCleanup,\n on,\n type Accessor,\n type JSX,\n} from 'solid-js'\nimport { X, GripVertical } from 'lucide-solid'\nimport { Button } from '../../ui/button'\nimport { cn } from '#lib/utils'\nimport { computeLayoutFrames, type LayoutRect } from './geometry'\nimport { paneDropIntent, type PaneDropIntent } from './drop'\nexport type { PaneDropIntent } from './drop'\nconst PANE_DRAG_TYPE = 'application/x-adea-pane-move'\nimport {\n listLeaves,\n MIN_SPLIT_RATIO,\n MAX_SPLIT_RATIO,\n type SplitLayoutBranch,\n type SplitLayoutLeaf,\n type SplitLayoutState,\n} from './model'\n\nexport type SplitLayoutProps<L extends SplitLayoutLeaf> = {\n state: SplitLayoutState<L>\n label: string\n /** Accessible name for a pane region and its close button. */\n labelForLeaf: (leaf: L) => string\n /** Called once per stable leaf owner; the accessor tracks opaque payload replacement. */\n renderLeaf: (leaf: Accessor<L>) => JSX.Element\n /** Inline visible header composition, separate from the region and close-button name. */\n renderPaneLabel?: (leaf: Accessor<L>) => JSX.Element\n /** Whether pane regions participate in sequential keyboard navigation; defaults to programmatic focus only. */\n paneTabIndex?: 0 | -1\n /** Accessible splitter name; defaults to the current orientation-specific label. */\n labelForSeparator?: (branch: SplitLayoutBranch<L>) => string\n onResize: (splitId: string, ratio: number) => void\n onFocus?: (leafId: string) => void\n /** Host performs the model transition and returns the surviving focus destination. */\n onClose?: (leafId: string) => string | undefined\n /** Pointer placement only; the host supplies keyboard commands and performs the model transition. */\n onMove?: (leafId: string, targetId: string, intent: PaneDropIntent) => void\n /** Stable header composition for host-owned keyboard actions/capability feedback. */\n renderPaneActions?: (leaf: Accessor<L>) => JSX.Element\n class?: string\n}\nfunction rectStyle(rect: LayoutRect): JSX.CSSProperties {\n return {\n left: `${rect.x * 100}%`,\n top: `${rect.y * 100}%`,\n width: `${rect.width * 100}%`,\n height: `${rect.height * 100}%`,\n }\n}\n/** Muxy frame geometry keeps leaf owners stable; Corvu owns constrained separator interactions. */\nexport function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L>) {\n let root: HTMLDivElement | undefined\n let pendingFrame: number | undefined\n const refs = new Map<string, HTMLElement>()\n const domIds = new Map<string, string>()\n const prefix = createUniqueId()\n let nextDomId = 0\n let nextDragId = 0\n const [drag, setDrag] = createSignal<{ id: string; token: string }>()\n const [drop, setDrop] = createSignal<{ id: string; intent: PaneDropIntent }>()\n const clearDrag = () => {\n setDrag(undefined)\n setDrop(undefined)\n }\n const domId = (id: string) => {\n const existing = domIds.get(id)\n if (existing) return existing\n const created = `${prefix}-pane-${nextDomId++}`\n domIds.set(id, created)\n return created\n }\n const leaves = createMemo(() => listLeaves(props.state.center))\n const leafMap = createMemo(() => new Map(leaves().map((leaf) => [leaf.id, leaf])))\n const frames = createMemo(() => computeLayoutFrames(props.state.center))\n const branches = createMemo(() =>\n Array.from(frames().values()).flatMap((frame) =>\n frame.node.kind === 'split' ? [frame.node] : []\n )\n )\n createComputed(() => {\n const current = drag()\n if (current && (!props.onMove || !leafMap().has(current.id))) clearDrag()\n const target = drop()\n if (target && !leafMap().has(target.id)) setDrop(undefined)\n })\n const allowedTarget = (id: string, transfer: DataTransfer | null) => {\n const current = drag()\n return props.onMove &&\n current &&\n current.id !== id &&\n leafMap().has(current.id) &&\n leafMap().has(id) &&\n transfer?.types.includes(PANE_DRAG_TYPE)\n ? current\n : undefined\n }\n const dropLabel = createMemo(() => {\n const target = drop()\n const leaf = target ? leafMap().get(target.id) : undefined\n return target && leaf\n ? `Drop to place pane ${target.intent.placement} ${props.labelForLeaf(leaf)}`\n : ''\n })\n const branchMap = createMemo(() => new Map(branches().map((branch) => [branch.id, branch])))\n const schedule = (action: () => void) => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n pendingFrame = requestAnimationFrame(() => {\n pendingFrame = undefined\n action()\n })\n }\n // Register before keyed children update: capture a focused editor before an\n // ordered DOM move can blur it. Never override a newer focus outside this root.\n createComputed(\n on(\n () => props.state.center,\n () => {\n const active = root?.ownerDocument.activeElement\n if (!root || !(active instanceof HTMLElement) || !root.contains(active)) return\n const field =\n active instanceof HTMLTextAreaElement || active instanceof HTMLInputElement\n ? active\n : undefined\n const selection = field\n ? {\n start: field.selectionStart,\n end: field.selectionEnd,\n direction: field.selectionDirection,\n }\n : undefined\n schedule(() => {\n if (!active.isConnected || !root?.contains(active)) return\n const current = active.ownerDocument.activeElement\n if (current !== active && current !== active.ownerDocument.body) return\n active.focus({ preventScroll: true })\n if (field && selection?.start !== null && selection?.end !== null && selection)\n field.setSelectionRange(\n selection.start,\n selection.end,\n selection.direction ?? undefined\n )\n })\n }\n )\n )\n onCleanup(() => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n clearDrag()\n refs.clear()\n domIds.clear()\n })\n const close = (id: string) => {\n const next = props.onClose?.(id)\n if (next) schedule(() => refs.get(next)?.focus({ preventScroll: true }))\n }\n return (\n <div\n ref={(el) => {\n root = el\n }}\n role=\"group\"\n aria-label={props.label}\n data-slot=\"split-layout\"\n data-dragging={drag() ? '' : undefined}\n class={cn('relative size-full min-h-0 min-w-0 data-[dragging]:cursor-grabbing', props.class)}\n >\n <For each={leaves().map((leaf) => leaf.id)}>\n {(id) => {\n const initial = leafMap().get(id)!\n const leaf = () => leafMap().get(id) ?? initial\n const content = props.renderLeaf(leaf)\n const paneLabel = props.renderPaneLabel?.(leaf)\n const actions = props.renderPaneActions?.(leaf)\n const intent = () => (drop()?.id === id ? drop()?.intent : undefined)\n onCleanup(() => {\n refs.delete(id)\n domIds.delete(id)\n })\n return (\n <section\n ref={(el) => refs.set(id, el)}\n id={domId(id)}\n role=\"region\"\n aria-label={props.labelForLeaf(leaf())}\n tabIndex={props.paneTabIndex ?? -1}\n data-pane-id={id}\n data-focused={props.state.focusedLeafId === id ? '' : undefined}\n data-drag-source={drag()?.id === id ? '' : undefined}\n data-drop-direction={intent()?.direction}\n data-drop-placement={intent()?.placement}\n onDragOver={(event) => {\n if (!allowedTarget(id, event.dataTransfer)) return\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n if (!next) {\n setDrop(undefined)\n return\n }\n event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'\n setDrop({ id, intent: next })\n }}\n onDragLeave={(event) => {\n if (\n event.relatedTarget instanceof Node &&\n event.currentTarget.contains(event.relatedTarget)\n )\n return\n if (drop()?.id === id) setDrop(undefined)\n }}\n onDrop={(event) => {\n const current = allowedTarget(id, event.dataTransfer)\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n const accepted =\n current && next && event.dataTransfer?.getData(PANE_DRAG_TYPE) === current.token\n clearDrag()\n if (!accepted) return\n event.preventDefault()\n props.onMove?.(current.id, id, next)\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border transition-opacity data-[drag-source]:opacity-40 data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring\"\n onFocusIn={() => props.onFocus?.(id)}\n >\n <header class=\"flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2\">\n <span\n data-pane-drag-handle=\"\"\n draggable={Boolean(props.onMove)}\n class={cn('flex min-w-0 flex-1 items-center gap-2 truncate text-sm', {\n 'cursor-grab': Boolean(props.onMove),\n })}\n title={props.onMove ? `Drag ${props.labelForLeaf(leaf())} to move` : undefined}\n onDragStart={(event) => {\n if (!props.onMove || !event.dataTransfer) {\n event.preventDefault()\n return\n }\n const token = `${prefix}-${++nextDragId}`\n setDrag({ id, token })\n event.dataTransfer.setData(PANE_DRAG_TYPE, token)\n event.dataTransfer.effectAllowed = 'move'\n // The ghost is the pane itself, not the handle strip: the\n // browser snapshots the region before the drag state dims\n // this section, so the dragged pane stays readable while\n // its source visibly recedes.\n const source = refs.get(id)\n const frame = source?.getBoundingClientRect()\n if (source && frame && typeof event.dataTransfer.setDragImage === 'function')\n event.dataTransfer.setDragImage(\n source,\n Math.max(0, Math.round(event.clientX - frame.left)),\n Math.max(0, Math.round(event.clientY - frame.top))\n )\n }}\n onDragEnd={clearDrag}\n >\n {props.onMove ? (\n <GripVertical class=\"size-3 shrink-0\" aria-hidden=\"true\" />\n ) : null}\n <span class=\"min-w-0 flex-1 truncate\">\n {paneLabel ?? props.labelForLeaf(leaf())}\n </span>\n </span>\n {actions}\n {props.onClose ? (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={`Close ${props.labelForLeaf(leaf())}`}\n onClick={() => close(id)}\n >\n <X />\n </Button>\n ) : null}\n </header>\n <div class=\"min-h-0 min-w-0 flex-1 overflow-auto\">{content}</div>\n {intent() ? (\n <div\n aria-hidden=\"true\"\n class={cn('pointer-events-none absolute border-2 border-primary bg-primary/10', {\n 'inset-y-0 left-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'before',\n 'inset-y-0 right-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'after',\n 'inset-x-0 top-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'before',\n 'inset-x-0 bottom-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'after',\n })}\n />\n ) : null}\n </section>\n )\n }}\n </For>\n <span class=\"sr-only\" role=\"status\">\n {dropLabel()}\n </span>\n <For each={branches().map((branch) => branch.id)}>\n {(id) => {\n const initial = branchMap().get(id)!\n const branch: Accessor<SplitLayoutBranch<L>> = () => branchMap().get(id) ?? initial\n return (\n <Resizable\n orientation={branch().direction === 'row' ? 'horizontal' : 'vertical'}\n sizes={[branch().ratio, 1 - branch().ratio]}\n keyboardDelta={0.05}\n onSizesChange={(sizes) => {\n // Corvu also reports panel registration/unregistration while\n // mounting or disposing a controller. Those incomplete or\n // hidden-host sizes are not user resize intent.\n if (!root?.isConnected || root.getClientRects().length === 0) return\n if (\n sizes.length !== 2 ||\n sizes.some((size) => !Number.isFinite(size)) ||\n Math.abs(sizes[0]! + sizes[1]! - 1) > 0.000001\n )\n return\n if (sizes[0] !== undefined && Math.abs(sizes[0] - branch().ratio) > 0.000001)\n props.onResize(id, sizes[0])\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"pointer-events-none absolute flex min-h-0 min-w-0 data-[orientation=vertical]:flex-col\"\n >\n <Resizable.Panel\n minSize={MIN_SPLIT_RATIO}\n maxSize={MAX_SPLIT_RATIO}\n aria-hidden=\"true\"\n />\n <Resizable.Handle\n aria-label={\n props.labelForSeparator?.(branch()) ??\n (branch().direction === 'row' ? 'Resize pane columns' : 'Resize pane rows')\n }\n aria-orientation={branch().direction === 'row' ? 'vertical' : 'horizontal'}\n aria-controls={listLeaves(branch())\n .map((leaf) => domId(leaf.id))\n .join(' ')}\n aria-valuemin={10}\n aria-valuemax={90}\n aria-valuenow={Math.round(branch().ratio * 100)}\n class=\"pointer-events-auto relative w-px shrink-0 bg-border after:absolute after:inset-y-0 after:-inset-x-1 after:w-3 focus-visible:bg-primary focus-visible:outline-none hover:bg-primary data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:inset-x-0 data-[orientation=vertical]:after:-inset-y-1 data-[orientation=vertical]:after:h-3 data-[orientation=vertical]:after:w-full\"\n />\n <Resizable.Panel\n minSize={MIN_SPLIT_RATIO}\n maxSize={MAX_SPLIT_RATIO}\n aria-hidden=\"true\"\n />\n </Resizable>\n )\n }}\n </For>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;AAkBA,IAAMkB,iBAAiB;AAiCvB,SAAS8B,UAAUC,MAAqC;CACtD,OAAO;EACLE,MAAM,GAAGF,KAAKG,IAAI,IAAG;EACrBC,KAAK,GAAGJ,KAAKK,IAAI,IAAG;EACpBC,OAAO,GAAGN,KAAKM,QAAQ,IAAG;EAC1BC,QAAQ,GAAGP,KAAKO,SAAS,IAAG;CAC9B;AACF;;AAEA,SAAgBC,YAAuCC,OAA4B;CACjF,IAAIC;CACJ,IAAIE;CACJ,MAAMC,uBAAO,IAAIC,IAAyB;CAC1C,MAAME,yBAAS,IAAIF,IAAoB;CACvC,MAAMG,SAAS9D,eAAe;CAC9B,IAAI+D,YAAY;CAChB,IAAIC,aAAa;CACjB,MAAM,CAACC,MAAMC,WAAWjE,aAA4C;CACpE,MAAM,CAACoE,MAAMC,WAAWrE,aAAqD;CAC7E,MAAMsE,kBAAkB;EACtBL,QAAQM,KAAAA,CAAS;EACjBF,QAAQE,KAAAA,CAAS;CACnB;CACA,MAAMC,SAASN,OAAe;EAC5B,MAAMO,WAAWb,OAAOc,IAAIR,EAAE;EAC9B,IAAIO,UAAU,OAAOA;EACrB,MAAME,UAAU,GAAGd,OAAM,QAASC;EAClCF,OAAOgB,IAAIV,IAAIS,OAAO;EACtB,OAAOA;CACT;CACA,MAAME,SAAShF,iBAAiBiB,WAAWuC,MAAMhC,MAAMyD,MAAM,CAAC;CAC9D,MAAMC,UAAUlF,iBAAiB,IAAI6D,IAAImB,OAAO,CAAC,CAACG,KAAKvD,SAAS,CAACA,KAAKyC,IAAIzC,IAAI,CAAC,CAAC,CAAC;CACjF,MAAMwD,SAASpF,iBAAiBY,oBAAoB4C,MAAMhC,MAAMyD,MAAM,CAAC;CACvE,MAAMI,WAAWrF,iBACfsF,MAAMC,KAAKH,OAAO,CAAC,CAACI,OAAO,CAAC,CAAC,CAACC,SAASC,UACrCA,MAAMC,KAAKC,SAAS,UAAU,CAACF,MAAMC,IAAI,IAAI,CAAA,CAC/C,CACF;CACA1F,qBAAqB;EACnB,MAAM4F,UAAU1B,KAAK;EACrB,IAAI0B,YAAY,CAACrC,MAAMf,UAAU,CAACyC,QAAQ,CAAC,CAACY,IAAID,QAAQxB,EAAE,IAAII,UAAU;EACxE,MAAMsB,SAASxB,KAAK;EACpB,IAAIwB,UAAU,CAACb,QAAQ,CAAC,CAACY,IAAIC,OAAO1B,EAAE,GAAGG,QAAQE,KAAAA,CAAS;CAC5D,CAAC;CACD,MAAMsB,iBAAiB3B,IAAY4B,aAAkC;EACnE,MAAMJ,UAAU1B,KAAK;EACrB,OAAOX,MAAMf,UACXoD,WACAA,QAAQxB,OAAOA,MACfa,QAAQ,CAAC,CAACY,IAAID,QAAQxB,EAAE,KACxBa,QAAQ,CAAC,CAACY,IAAIzB,EAAE,KAChB4B,UAAUE,MAAMC,SAASpF,cAAc,IACrC6E,UACAnB,KAAAA;CACN;CACA,MAAM2B,YAAYrG,iBAAiB;EACjC,MAAM+F,SAASxB,KAAK;EACpB,MAAM3C,OAAOmE,SAASb,QAAQ,CAAC,CAACL,IAAIkB,OAAO1B,EAAE,IAAIK,KAAAA;EACjD,OAAOqB,UAAUnE,OACb,sBAAsBmE,OAAOpD,OAAO2D,UAAS,GAAI9C,MAAM7B,aAAaC,IAAI,MACxE;CACN,CAAC;CACD,MAAM2E,YAAYvG,iBAAiB,IAAI6D,IAAIwB,SAAS,CAAC,CAACF,KAAKjD,WAAW,CAACA,OAAOmC,IAAInC,MAAM,CAAC,CAAC,CAAC;CAC3F,MAAMsE,YAAYC,WAAuB;EACvC,IAAI9C,iBAAiBe,KAAAA,GAAWgC,qBAAqB/C,YAAY;EACjEA,eAAegD,4BAA4B;GACzChD,eAAee,KAAAA;GACf+B,OAAO;EACT,CAAC;CACH;CAGAxG,eACEI,SACQmD,MAAMhC,MAAMyD,cACZ;EACJ,MAAM2B,SAASnD,MAAMoD,cAAcC;EACnC,IAAI,CAACrD,QAAQ,EAAEmD,kBAAkB9C,gBAAgB,CAACL,KAAKsD,SAASH,MAAM,GAAG;EACzE,MAAMI,QACJJ,kBAAkBK,uBAAuBL,kBAAkBM,mBACvDN,SACAlC,KAAAA;EACN,MAAMyC,YAAYH,QACd;GACEI,OAAOJ,MAAMK;GACbC,KAAKN,MAAMO;GACXC,WAAWR,MAAMS;EACnB,IACA/C,KAAAA;EACJ8B,eAAe;GACb,IAAI,CAACI,OAAOc,eAAe,CAACjE,MAAMsD,SAASH,MAAM,GAAG;GACpD,MAAMf,UAAUe,OAAOC,cAAcC;GACrC,IAAIjB,YAAYe,UAAUf,YAAYe,OAAOC,cAAcc,MAAM;GACjEf,OAAOgB,MAAM,EAAEC,eAAe,KAAK,CAAC;GACpC,IAAIb,SAASG,WAAWC,UAAU,QAAQD,WAAWG,QAAQ,QAAQH,WACnEH,MAAMc,kBACJX,UAAUC,OACVD,UAAUG,KACVH,UAAUK,aAAa9C,KAAAA,CACzB;EACJ,CAAC;CACH,CACF,CACF;CACAtE,gBAAgB;EACd,IAAIuD,iBAAiBe,KAAAA,GAAWgC,qBAAqB/C,YAAY;EACjEc,UAAU;EACVb,KAAKmE,MAAM;EACXhE,OAAOgE,MAAM;CACf,CAAC;CACD,MAAMC,SAAS3D,OAAe;EAC5B,MAAM4D,OAAOzE,MAAMhB,UAAU6B,EAAE;EAC/B,IAAI4D,MAAMzB,eAAe5C,KAAKiB,IAAIoD,IAAI,CAAC,EAAEL,MAAM,EAAEC,eAAe,KAAK,CAAC,CAAC;CACzE;CACA,cAAA;EAAA,IAAAK,OAAAC,OAAA,GAAAC,QAAAF,KAAAG;EAAAC,KAEUC,OAAO;GACX9E,OAAO8E;EACT,GAACL,IAAA;EAAAM,OAAAN,MAAAO,gBAOA1I,KAAG;GAAA,IAAC2I,OAAI;IAAA,OAAE1D,OAAO,CAAC,CAACG,KAAKvD,SAASA,KAAKyC,EAAE;GAAC;GAAAsE,WACtCtE,OAAO;IACP,MAAMuE,UAAU1D,QAAQ,CAAC,CAACL,IAAIR,EAAE;IAChC,MAAMzC,aAAasD,QAAQ,CAAC,CAACL,IAAIR,EAAE,KAAKuE;IACxC,MAAMC,UAAUrF,MAAM3B,WAAWD,IAAI;IACrC,MAAMkH,YAAYtF,MAAMzB,kBAAkBH,IAAI;IAC9C,MAAMmH,UAAUvF,MAAMZ,oBAAoBhB,IAAI;IAC9C,MAAMe,eAAgB4B,KAAK,CAAC,EAAEF,OAAOA,KAAKE,KAAK,CAAC,EAAE5B,SAAS+B,KAAAA;IAC3DtE,gBAAgB;KACdwD,KAAKoF,OAAO3E,EAAE;KACdN,OAAOiF,OAAO3E,EAAE;IAClB,CAAC;IACD,cAAA;KAAA,IAAA4E,QAAAC,QAAA,GAAAC,QAAAF,MAAAZ,YAAAe,QAAAD,MAAAd,YAAAgB,QAAAD,MAAAf,YAAAiB,QAAAH,MAAAI;KAAAN,MAAAO,kBAmDqBhG,MAAMlB,UAAU+B,EAAE;KAAC4E,MAAAQ,iBAAA,SAhB3BC,UAAU;MACjB,MAAM7D,UAAUG,cAAc3B,IAAIqF,MAAMC,YAAY;MACpD,MAAM1B,OAAOnH,eACX4I,MAAME,SACNF,MAAMG,SACNH,MAAMI,cAAcC,sBAAsB,CAC5C;MACA,MAAMC,WACJnE,WAAWoC,QAAQyB,MAAMC,cAAcM,QAAQjJ,cAAc,MAAM6E,QAAQvB;MAC7EG,UAAU;MACV,IAAI,CAACuF,UAAU;MACfN,MAAMQ,eAAe;MACrB1G,MAAMf,SAASoD,QAAQxB,IAAIA,IAAI4D,IAAI;KACrC,CAAC;KAAAgB,MAAAQ,iBAAA,cArBaC,UAAU;MACtB,IACEA,MAAMS,yBAAyBC,QAC/BV,MAAMI,cAAc/C,SAAS2C,MAAMS,aAAa,GAEhD;MACF,IAAI5F,KAAK,CAAC,EAAEF,OAAOA,IAAIG,QAAQE,KAAAA,CAAS;KAC1C,CAAC;KAAAuE,MAAAQ,iBAAA,aAtBYC,UAAU;MACrB,IAAI,CAAC1D,cAAc3B,IAAIqF,MAAMC,YAAY,GAAG;MAC5C,MAAM1B,OAAOnH,eACX4I,MAAME,SACNF,MAAMG,SACNH,MAAMI,cAAcC,sBAAsB,CAC5C;MACA,IAAI,CAAC9B,MAAM;OACTzD,QAAQE,KAAAA,CAAS;OACjB;MACF;MACAgF,MAAMQ,eAAe;MACrB,IAAIR,MAAMC,cAAcD,MAAMC,aAAaU,aAAa;MACxD7F,QAAQ;OAAEH;OAAI1B,QAAQsF;MAAK,CAAC;KAC9B,CAAC;KAAAK,KAxBKC,OAAO3E,KAAKmB,IAAIV,IAAIkE,EAAE,GAACU,KAAA;KAAAqB,aAAArB,OAAA,gBAKf5E,EAAE;KAAA+E,MAAAK,iBAAA,WA4EDhF,SAAS;KAAA2E,MAAAK,iBAAA,cAtBNC,UAAU;MACtB,IAAI,CAAClG,MAAMf,UAAU,CAACiH,MAAMC,cAAc;OACxCD,MAAMQ,eAAe;OACrB;MACF;MACA,MAAM5F,QAAQ,GAAGN,OAAM,GAAI,EAAEE;MAC7BE,QAAQ;OAAEC;OAAIC;MAAM,CAAC;MACrBoF,MAAMC,aAAaY,QAAQvJ,gBAAgBsD,KAAK;MAChDoF,MAAMC,aAAaa,gBAAgB;MAKnC,MAAMC,SAAS7G,KAAKiB,IAAIR,EAAE;MAC1B,MAAMqB,QAAQ+E,QAAQV,sBAAsB;MAC5C,IAAIU,UAAU/E,SAAS,OAAOgE,MAAMC,aAAae,iBAAiB,YAChEhB,MAAMC,aAAae,aACjBD,QACAE,KAAKC,IAAI,GAAGD,KAAKE,MAAMnB,MAAME,UAAUlE,MAAMzC,IAAI,CAAC,GAClD0H,KAAKC,IAAI,GAAGD,KAAKE,MAAMnB,MAAMG,UAAUnE,MAAMvC,GAAG,CAAC,CACnD;KACJ,CAAC;KAAAqF,OAAAY,cAAA;MAAA,IAAA0B,MAAAC,WAAA,CAAA,CAGAvH,MAAMf,MAAM;MAAA,aAAZqI,IAAA,IAAArC,gBACEhI,cAAY;OAAA,SAAA;OAAA,eAAA;MAAA,CAAA,IACX;KAAI,EAAA,CAAA,GAAA4I,KAAA;KAAAb,OAAAa,aAELP,aAAatF,MAAM7B,aAAaC,KAAK,CAAC,CAAC;KAAA4G,OAAAW,OAG3CJ,SAAO,IAAA;KAAAP,OAAAW,cAAA;MAAA,IAAA6B,OAAAD,WAAA,CAAA,CACPvH,MAAMhB,OAAO;MAAA,aAAbwI,KAAA,IAAAvC,gBACE/H,QAAM;OACLuK,SAAO;OACPC,MAAI;OAAA,KAAA,gBAAA;QAAA,OACQ,SAAS1H,MAAM7B,aAAaC,KAAK,CAAC;OAAG;OACjDwJ,eAAepD,MAAM3D,EAAE;OAAC,IAAAsE,WAAA;QAAA,OAAAF,gBAEvBjI,GAAC,CAAA,CAAA;OAAA;MAAA,CAAA,IAEF;KAAI,EAAA,CAAA,GAAA,IAAA;KAAAgI,OAAAc,OAEyCT,OAAO;KAAAL,OAAAS,cAAA;MAAA,IAAAoC,OAAAN,WAAA,CAAA,CACzDpI,OAAO,CAAC;MAAA,aAAR0I,KAAA,WAAA;OAAA,IAAAC,QAAAC,QAAA;OAAAC,aAAAC,UAAAH,OAGU3K,GAAG,sEAAsE;QAC9E,0BACEgC,OAAO,CAAC,EAAE6E,cAAc,SAAS7E,OAAO,CAAC,EAAE2D,cAAc;QAC3D,2BACE3D,OAAO,CAAC,EAAE6E,cAAc,SAAS7E,OAAO,CAAC,EAAE2D,cAAc;QAC3D,yBACE3D,OAAO,CAAC,EAAE6E,cAAc,YAAY7E,OAAO,CAAC,EAAE2D,cAAc;QAC9D,4BACE3D,OAAO,CAAC,EAAE6E,cAAc,YAAY7E,OAAO,CAAC,EAAE2D,cAAc;OAChE,CAAC,CAAC,CAAA;OAAA,OAAAgF;MAAA,EAAA,CAAA,IAEF;KAAI,EAAA,CAAA,GAAA,IAAA;KAAAE,QAAAE,QAAA;MAAA,IAAAC,OApHJhH,MAAMN,EAAE,GAACuH,OAEDpI,MAAM7B,aAAaC,KAAK,CAAC,GAACiK,OAC5BrI,MAAMxB,gBAAgB,IAAE8J,OAEpBtI,MAAMhC,MAAMuK,kBAAkB1H,KAAK,KAAKK,KAAAA,GAASsH,OAC7C7H,KAAK,CAAC,EAAEE,OAAOA,KAAK,KAAKK,KAAAA,GAASuH,OAC/BtJ,OAAO,CAAC,EAAE6E,WAAS0E,OACnBvJ,OAAO,CAAC,EAAE2D,WAAS6F,OAsCjCrJ,UAAUsC,OAAO,CAAC,CAACP,IAAIR,EAAE,CAAC,EAAEtB,QAAQ;OAAEG,GAAG;OAAGE,GAAG;OAAGC,OAAO;OAAGC,QAAQ;MAAE,CAAC,GAAC8I,QAOhEC,QAAQ7I,MAAMf,MAAM,GAAC6J,QACzB3L,GAAG,2DAA2D,EACnE,eAAe0L,QAAQ7I,MAAMf,MAAM,EACrC,CAAC,GAAC8J,QACK/I,MAAMf,SAAS,QAAQe,MAAM7B,aAAaC,KAAK,CAAC,EAAC,YAAa8C,KAAAA;MAASiH,SAAAD,IAAAc,KAAAlC,aAAArB,OAAA,MAAAyC,IAAAc,IAAAb,IAAA;MAAAC,SAAAF,IAAAe,KAAAnC,aAAArB,OAAA,cAAAyC,IAAAe,IAAAb,IAAA;MAAAC,SAAAH,IAAAgB,KAAApC,aAAArB,OAAA,YAAAyC,IAAAgB,IAAAb,IAAA;MAAAC,SAAAJ,IAAAiB,KAAArC,aAAArB,OAAA,gBAAAyC,IAAAiB,IAAAb,IAAA;MAAAE,SAAAN,IAAAkB,KAAAtC,aAAArB,OAAA,oBAAAyC,IAAAkB,IAAAZ,IAAA;MAAAC,SAAAP,IAAAmB,KAAAvC,aAAArB,OAAA,uBAAAyC,IAAAmB,IAAAZ,IAAA;MAAAC,SAAAR,IAAAoB,KAAAxC,aAAArB,OAAA,uBAAAyC,IAAAoB,IAAAZ,IAAA;MAAAR,IAAAqB,IAAAC,MAAA/D,OAAAkD,MAAAT,IAAAqB,CAAA;MAAAX,UAAAV,IAAAuB,KAAA3C,aAAAlB,OAAA,aAAAsC,IAAAuB,IAAAb,KAAA;MAAAE,UAAAZ,IAAAwB,KAAAzB,UAAArC,OAAAsC,IAAAwB,IAAAZ,KAAA;MAAAC,UAAAb,IAAAyB,KAAA7C,aAAAlB,OAAA,SAAAsC,IAAAyB,IAAAZ,KAAA;MAAA,OAAAb;KAAA,GAAA;MAAAc,GAAA9H,KAAAA;MAAA+H,GAAA/H,KAAAA;MAAAgI,GAAAhI,KAAAA;MAAAiI,GAAAjI,KAAAA;MAAAkI,GAAAlI,KAAAA;MAAAmI,GAAAnI,KAAAA;MAAAoI,GAAApI,KAAAA;MAAAqI,GAAArI,KAAAA;MAAAuI,GAAAvI,KAAAA;MAAAwI,GAAAxI,KAAAA;MAAAyI,GAAAzI,KAAAA;KAAA,CAAA;KAAA,OAAAuE;IAAA,EAAA,CAAA;GA8DxF;EAAC,CAAA,GAAAb,KAAA;EAAAI,OAAAJ,OAGA/B,SAAS;EAAAmC,OAAAN,MAAAO,gBAEX1I,KAAG;GAAA,IAAC2I,OAAI;IAAA,OAAErD,SAAS,CAAC,CAACF,KAAKjD,WAAWA,OAAOmC,EAAE;GAAC;GAAAsE,WAC5CtE,OAAO;IACP,MAAMuE,UAAUrC,UAAU,CAAC,CAAC1B,IAAIR,EAAE;IAClC,MAAMnC,eAA+CqE,UAAU,CAAC,CAAC1B,IAAIR,EAAE,KAAKuE;IAC5E,OAAAH,gBACG3I,WAAS;KAAA,IACRsN,cAAW;MAAA,OAAElL,OAAO,CAAC,CAACsF,cAAc,QAAQ,eAAe;KAAU;KAAA,IACrE6F,QAAK;MAAA,OAAE,CAACnL,OAAO,CAAC,CAACG,OAAO,IAAIH,OAAO,CAAC,CAACG,KAAK;KAAC;KAC3CiL,eAAe;KACfC,gBAAgBF,UAAU;MAIxB,IAAI,CAAC5J,MAAMiE,eAAejE,KAAK+J,eAAe,CAAC,CAACC,WAAW,GAAG;MAC9D,IACEJ,MAAMI,WAAW,KACjBJ,MAAMK,MAAMxC,SAAS,CAACyC,OAAOC,SAAS1C,IAAI,CAAC,KAC3CP,KAAKkD,IAAIR,MAAM,KAAMA,MAAM,KAAM,CAAC,IAAI,MAEtC;MACF,IAAIA,MAAM,OAAO3I,KAAAA,KAAaiG,KAAKkD,IAAIR,MAAM,KAAKnL,OAAO,CAAC,CAACG,KAAK,IAAI,MAClEmB,MAAMrB,SAASkC,IAAIgJ,MAAM,EAAE;KAC/B;KAAC,IACDS,QAAK;MAAA,OAAEhL,UAAUsC,OAAO,CAAC,CAACP,IAAIR,EAAE,CAAC,EAAEtB,QAAQ;OAAEG,GAAG;OAAGE,GAAG;OAAGC,OAAO;OAAGC,QAAQ;MAAE,CAAC;KAAC;KAAA,SAAA;KAAA,IAAAqF,WAAA;MAAA,OAAA;OAAAF,gBAG9E3I,UAAUiO,OAAK;QACdC,SAAS9M;QACT+M,SAAS9M;QAAe,eAAA;OAAA,CAAA;OAAAsH,gBAGzB3I,UAAUoO,QAAM;QAAA,KAAA,gBAAA;SAAA,OAEb1K,MAAMvB,oBAAoBC,OAAO,CAAC,MACjCA,OAAO,CAAC,CAACsF,cAAc,QAAQ,wBAAwB;QAAmB;QAAA,KAAA,sBAAA;SAAA,OAE3DtF,OAAO,CAAC,CAACsF,cAAc,QAAQ,aAAa;QAAY;QAAA,KAAA,mBAAA;SAAA,OAC3DvG,WAAWiB,OAAO,CAAC,CAAC,CAChCiD,KAAKvD,SAAS+C,MAAM/C,KAAKyC,EAAE,CAAC,CAAC,CAC7BgK,KAAK,GAAG;QAAC;QAAA,iBACG;QAAE,iBACF;QAAE,KAAA,mBAAA;SAAA,OACF1D,KAAKE,MAAM3I,OAAO,CAAC,CAACG,QAAQ,GAAG;QAAC;QAAA,SAAA;OAAA,CAAA;OAAAoG,gBAGhD3I,UAAUiO,OAAK;QACdC,SAAS9M;QACT+M,SAAS9M;QAAe,eAAA;OAAA,CAAA;MAAA;KAAA;IAAA,CAAA;GAKhC;EAAC,CAAA,GAAA,IAAA;EAAAqK,QAAAE,QAAA;GAAA,IAAA6C,MApMS/K,MAAM9B,OAAK8M,OAERrK,KAAK,IAAI,KAAKO,KAAAA,GAAS+J,OAC/B9N,GAAG,sEAAsE6C,MAAMX,KAAK;GAAC0L,QAAA7C,IAAAc,KAAAlC,aAAApC,MAAA,cAAAwD,IAAAc,IAAA+B,GAAA;GAAAC,SAAA9C,IAAAe,KAAAnC,aAAApC,MAAA,iBAAAwD,IAAAe,IAAA+B,IAAA;GAAAC,SAAA/C,IAAAgB,KAAAjB,UAAAvD,MAAAwD,IAAAgB,IAAA+B,IAAA;GAAA,OAAA/C;EAAA,GAAA;GAAAc,GAAA9H,KAAAA;GAAA+H,GAAA/H,KAAAA;GAAAgI,GAAAhI,KAAAA;EAAA,CAAA;EAAA,OAAAwD;CAAA,EAAA,CAAA;AAqMlG;AAACwG,eAAA,CAAA,SAAA,CAAA"}
@@ -171,7 +171,8 @@ export function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L
171
171
  role="group"
172
172
  aria-label={props.label}
173
173
  data-slot="split-layout"
174
- class={cn('relative size-full min-h-0 min-w-0', props.class)}
174
+ data-dragging={drag() ? '' : undefined}
175
+ class={cn('relative size-full min-h-0 min-w-0 data-[dragging]:cursor-grabbing', props.class)}
175
176
  >
176
177
  <For each={leaves().map((leaf) => leaf.id)}>
177
178
  {(id) => {
@@ -194,6 +195,7 @@ export function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L
194
195
  tabIndex={props.paneTabIndex ?? -1}
195
196
  data-pane-id={id}
196
197
  data-focused={props.state.focusedLeafId === id ? '' : undefined}
198
+ data-drag-source={drag()?.id === id ? '' : undefined}
197
199
  data-drop-direction={intent()?.direction}
198
200
  data-drop-placement={intent()?.placement}
199
201
  onDragOver={(event) => {
@@ -234,14 +236,16 @@ export function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L
234
236
  props.onMove?.(current.id, id, next)
235
237
  }}
236
238
  style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}
237
- class="absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
239
+ class="absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border transition-opacity data-[drag-source]:opacity-40 data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
238
240
  onFocusIn={() => props.onFocus?.(id)}
239
241
  >
240
242
  <header class="flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2">
241
243
  <span
242
244
  data-pane-drag-handle=""
243
245
  draggable={Boolean(props.onMove)}
244
- class="flex min-w-0 flex-1 items-center gap-2 truncate text-sm"
246
+ class={cn('flex min-w-0 flex-1 items-center gap-2 truncate text-sm', {
247
+ 'cursor-grab': Boolean(props.onMove),
248
+ })}
245
249
  title={props.onMove ? `Drag ${props.labelForLeaf(leaf())} to move` : undefined}
246
250
  onDragStart={(event) => {
247
251
  if (!props.onMove || !event.dataTransfer) {
@@ -252,6 +256,18 @@ export function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L
252
256
  setDrag({ id, token })
253
257
  event.dataTransfer.setData(PANE_DRAG_TYPE, token)
254
258
  event.dataTransfer.effectAllowed = 'move'
259
+ // The ghost is the pane itself, not the handle strip: the
260
+ // browser snapshots the region before the drag state dims
261
+ // this section, so the dragged pane stays readable while
262
+ // its source visibly recedes.
263
+ const source = refs.get(id)
264
+ const frame = source?.getBoundingClientRect()
265
+ if (source && frame && typeof event.dataTransfer.setDragImage === 'function')
266
+ event.dataTransfer.setDragImage(
267
+ source,
268
+ Math.max(0, Math.round(event.clientX - frame.left)),
269
+ Math.max(0, Math.round(event.clientY - frame.top))
270
+ )
255
271
  }}
256
272
  onDragEnd={clearDrag}
257
273
  >
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adea-ai/ui",
3
- "version": "0.97.7",
3
+ "version": "0.98.0",
4
4
  "description": "The Adea design system: Kobalte-backed Solid components, semantic OKLCH tokens, and the app-shell layout primitives shared by Adea and Cortana.",
5
5
  "keywords": [
6
6
  "adea",
@@ -171,7 +171,8 @@ export function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L
171
171
  role="group"
172
172
  aria-label={props.label}
173
173
  data-slot="split-layout"
174
- class={cn('relative size-full min-h-0 min-w-0', props.class)}
174
+ data-dragging={drag() ? '' : undefined}
175
+ class={cn('relative size-full min-h-0 min-w-0 data-[dragging]:cursor-grabbing', props.class)}
175
176
  >
176
177
  <For each={leaves().map((leaf) => leaf.id)}>
177
178
  {(id) => {
@@ -194,6 +195,7 @@ export function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L
194
195
  tabIndex={props.paneTabIndex ?? -1}
195
196
  data-pane-id={id}
196
197
  data-focused={props.state.focusedLeafId === id ? '' : undefined}
198
+ data-drag-source={drag()?.id === id ? '' : undefined}
197
199
  data-drop-direction={intent()?.direction}
198
200
  data-drop-placement={intent()?.placement}
199
201
  onDragOver={(event) => {
@@ -234,14 +236,16 @@ export function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L
234
236
  props.onMove?.(current.id, id, next)
235
237
  }}
236
238
  style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}
237
- class="absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
239
+ class="absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border transition-opacity data-[drag-source]:opacity-40 data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
238
240
  onFocusIn={() => props.onFocus?.(id)}
239
241
  >
240
242
  <header class="flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2">
241
243
  <span
242
244
  data-pane-drag-handle=""
243
245
  draggable={Boolean(props.onMove)}
244
- class="flex min-w-0 flex-1 items-center gap-2 truncate text-sm"
246
+ class={cn('flex min-w-0 flex-1 items-center gap-2 truncate text-sm', {
247
+ 'cursor-grab': Boolean(props.onMove),
248
+ })}
245
249
  title={props.onMove ? `Drag ${props.labelForLeaf(leaf())} to move` : undefined}
246
250
  onDragStart={(event) => {
247
251
  if (!props.onMove || !event.dataTransfer) {
@@ -252,6 +256,18 @@ export function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L
252
256
  setDrag({ id, token })
253
257
  event.dataTransfer.setData(PANE_DRAG_TYPE, token)
254
258
  event.dataTransfer.effectAllowed = 'move'
259
+ // The ghost is the pane itself, not the handle strip: the
260
+ // browser snapshots the region before the drag state dims
261
+ // this section, so the dragged pane stays readable while
262
+ // its source visibly recedes.
263
+ const source = refs.get(id)
264
+ const frame = source?.getBoundingClientRect()
265
+ if (source && frame && typeof event.dataTransfer.setDragImage === 'function')
266
+ event.dataTransfer.setDragImage(
267
+ source,
268
+ Math.max(0, Math.round(event.clientX - frame.left)),
269
+ Math.max(0, Math.round(event.clientY - frame.top))
270
+ )
255
271
  }}
256
272
  onDragEnd={clearDrag}
257
273
  >