diff options
| author | Adam Malczewski <[email protected]> | 2026-10-15 14:38:50 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-10-15 14:38:50 +0900 |
| commit | c4c1d76fec972e5d902a669f0cb1953eaa528f16 (patch) | |
| tree | d5d85b8500157dd690e13954216a61a6aac64a8a /src/features/tabs/ui/TabGroupBox.svelte | |
| parent | 3d3c28b10de06aae7e2ad474e8931a3fdd88b41c (diff) | |
| download | dispatch-web-c4c1d76fec972e5d902a669f0cb1953eaa528f16.tar.gz dispatch-web-c4c1d76fec972e5d902a669f0cb1953eaa528f16.zip | |
feat(tabs): 2-column tab grid with nestable subagent groups + tab menu (add/remove from group)
Diffstat (limited to 'src/features/tabs/ui/TabGroupBox.svelte')
| -rw-r--r-- | src/features/tabs/ui/TabGroupBox.svelte | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/features/tabs/ui/TabGroupBox.svelte b/src/features/tabs/ui/TabGroupBox.svelte new file mode 100644 index 0000000..5cbfb27 --- /dev/null +++ b/src/features/tabs/ui/TabGroupBox.svelte @@ -0,0 +1,53 @@ +<script lang="ts"> + import type { Snippet } from "svelte"; + import type { TabGroupNode } from "../tab-groups"; + import { groupBleedPx } from "../tab-groups"; + import type { Tab } from "../tabs"; + import TabGroupBox from "./TabGroupBox.svelte"; + + /** + * A subagent group: a darker box spanning both grid columns that wraps the + * group parent's (double-width) card + its subagents' cards. Recursive — + * a subagent with its own subagents renders a nested box. The box BLEEDS + * outward (negative margin + equal padding, `groupBleedPx`) so the cards + * inside stay on the same two columns as top-level cards: every card keeps + * identical dimensions at every depth. The translucent black background + * compounds, so each nesting level reads darker than the one around it. + */ + let { + node, + level, + maxDepth, + card, + }: { + node: TabGroupNode; + /** Nesting level of THIS box (1 = outermost). */ + level: number; + maxDepth: number; + /** Renders one card: (tab, wide, subagentCount). */ + card: Snippet<[Tab, boolean, number]>; + } = $props(); + + const bleed = $derived(groupBleedPx(level, maxDepth)); +</script> + +<div + class="col-span-2 rounded-lg border border-black/50 bg-black/40 py-1.5 shadow-inner" + style:margin-inline="-{bleed}px" + style:padding-inline="{bleed}px" + role="group" + aria-label={`Subagents of ${node.tab.title}`} + data-tab-group={node.tab.conversationId} + data-level={level} +> + <div class="grid grid-flow-row-dense grid-cols-2 gap-1.5"> + {@render card(node.tab, true, node.children.length)} + {#each node.children as child (child.tab.conversationId)} + {#if child.children.length > 0} + <TabGroupBox node={child} level={level + 1} {maxDepth} {card} /> + {:else} + {@render card(child.tab, false, 0)} + {/if} + {/each} + </div> +</div> |
