Something went wrong. Try again.
An atproto Tilemap editor
Something went wrong. Try again.
4.3 kB · 113 lines
TSX
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114import NodeProperties from './NodeProperties'import { findNode, useMapStore } from '../store/mapStore'import { Button } from '@/components/ui/button'import { Input } from '@/components/ui/input'
/** Right-pane tooling when a group node is selected. A plain group only * organises the scene, so there is nothing to draw — but a *composite* group * also sorts its whole subtree as one depth unit (e.g. a sign pinned to a * house), with an optional manual depth anchor. */export default function GroupInspector() { const nodes = useMapStore((s) => s.nodes) const activeNodeId = useMapStore((s) => s.activeNodeId) const toggleComposite = useMapStore((s) => s.toggleComposite) const setCompositeAnchor = useMapStore((s) => s.setCompositeAnchor)
const node = activeNodeId ? findNode(nodes, activeNodeId) : null const group = node && node.kind === 'group' ? node : null if (!group) return null
const anchor = group.anchor ?? null
return ( <section className="flex flex-col gap-4"> <p className="text-xs text-muted-foreground"> A group organises nodes. Drag nodes into it in the tree on the left. It carries no art of its own. </p>
<div className="flex flex-col gap-2 border-t border-border pt-3"> <h3 className="text-[11px] font-medium tracking-wide text-muted-foreground uppercase"> Compositing </h3> <Button type="button" variant={group.composite ? 'default' : 'outline'} size="sm" className="w-full" onClick={() => toggleComposite(group.id)} > Composite: {group.composite ? 'on' : 'off'} </Button> <p className="text-[11px] text-muted-foreground"> {group.composite ? 'Members sort as one unit (in panel order, first = back) instead of interleaving by their own depth.' : 'Turn on to keep this group’s nodes together in depth — e.g. a sign stays on its house.'} </p> </div>
{group.composite && ( <div className="flex flex-col gap-2 border-t border-border pt-3"> <h3 className="text-[11px] font-medium tracking-wide text-muted-foreground uppercase"> Depth anchor </h3> {anchor ? ( <> <div className="flex gap-2"> <label className="flex flex-1 flex-col gap-0.5"> <span className="text-[11px] text-muted-foreground">X (px)</span> <Input type="number" className="h-7 text-sm" value={anchor.x} onChange={(e) => setCompositeAnchor(group.id, { x: Number(e.target.value) || 0, y: anchor.y }) } /> </label> <label className="flex flex-1 flex-col gap-0.5"> <span className="text-[11px] text-muted-foreground">Y (px)</span> <Input type="number" className="h-7 text-sm" value={anchor.y} onChange={(e) => setCompositeAnchor(group.id, { x: anchor.x, y: Number(e.target.value) || 0 }) } /> </label> </div> <Button type="button" variant="outline" size="sm" className="w-full" onClick={() => setCompositeAnchor(group.id, null)} > Clear anchor (use deepest member) </Button> </> ) : ( <> <p className="text-[11px] text-muted-foreground"> The unit sorts by its deepest member’s far edge. Set a manual anchor to override where the whole composite sits in depth. </p> <Button type="button" variant="outline" size="sm" className="w-full" onClick={() => setCompositeAnchor(group.id, { x: 0, y: 0 })} > Set manual anchor </Button> </> )} </div> )}
<NodeProperties /> </section> )}