feat: navigation

This commit is contained in:
2026-04-01 16:04:06 +02:00
parent a0a5f18128
commit a95594f446
7 changed files with 312 additions and 6 deletions

View File

@@ -8,7 +8,7 @@ from uframe.ir import (
Gauge, Sparkline, Status, Table,
Form, Field, Password, Radio, Checkbox, FormButton,
Let, Source, IfBlock, ForLoop, CacheControl, OnSubmit, StateDecl,
BigTitle, ImageNode,
BigTitle, ImageNode, HNav, VNav,
)
from uframe.fonts import FONT_HEIGHTS, get_text_width
from uframe.imaging import get_image_height
@@ -246,6 +246,33 @@ def measure(node: IRNode, available_width: int) -> None:
node.pref_height = 1
node.min_height = 1
elif isinstance(node, HNav):
# Height: 3 for bar/tabs/pills (top border + items + bottom border), 2 for underline/breadcrumb
if node.nav_style in ("underline",):
node.pref_height = 2
elif node.nav_style in ("breadcrumb",):
node.pref_height = 1
else:
node.pref_height = 3
node.pref_width = available_width
node.min_width = 10
node.min_height = 1
elif isinstance(node, VNav):
count = sum(1 for it in node.items if it.kind in ("item", "heading"))
sep_count = sum(1 for it in node.items if it.kind == "separator")
h = count + sep_count
if node.nav_style == "boxed":
h += 2 # top + bottom border
node.pref_height = max(h, 1)
if node.nav_width > 0:
node.pref_width = node.nav_width
else:
max_label = max((len(it.label) for it in node.items if it.label), default=8)
node.pref_width = max_label + 6 # marker + padding
node.min_width = 8
node.min_height = 1
elif isinstance(node, ImageNode):
h = get_image_height(node.path, node.mode, node.img_width)
if node.caption: