diff --git a/src/ui/widgets/Panel.ts b/src/ui/widgets/Panel.ts index 9310f59e..f5050f65 100644 --- a/src/ui/widgets/Panel.ts +++ b/src/ui/widgets/Panel.ts @@ -17,6 +17,8 @@ export class Panel extends Widget { /** Height of the title row – the floor for a panel that must stay grabbable when dragged shut. */ static readonly HEADER_HEIGHT = Theme.rowHeight + 4; private readonly bg = new Graphics(); + /** Drawn above the content: a row flush with the edge (padding 0) would otherwise paint over it. */ + private readonly frame = new Graphics(); readonly header: HStack; readonly content: VStack; private readonly titleLabel: Label | null = null; @@ -34,7 +36,7 @@ export class Panel extends Widget { this.addChild(this.header); } this.content = new VStack({ padding: options.padding ?? Theme.padding, gap: options.gap ?? Theme.gap }); - this.addChild(this.content); + this.addChild(this.content, this.frame); } /** Titles render upper-case. A no-op on panels created without a title (they have no header). */ @@ -60,10 +62,11 @@ export class Panel extends Widget { override redraw(): void { this.bg.clear(); + this.frame.clear(); if (!this.chrome) return; const c = Theme.colors; this.bg.rect(0, 0, this.w, this.h).fill(c.panel); if (this.titleLabel) this.bg.rect(0, 0, this.w, this.header.minHeight).fill(c.panelHeader); - this.bg.rect(0.5, 0.5, this.w - 1, this.h - 1).stroke({ width: 1, color: c.border }); + this.frame.rect(0.5, 0.5, this.w - 1, this.h - 1).stroke({ width: 1, color: c.border }); } }