跳到正文

样式与布局

在元素或 ui.Style() 上链式调用样式方法。用 .Child(...) 或 .Children(...) 追加子节点,用 .Style(shared) 复用样式。

return ui.View().Children(ui.Text("hello"), ui.Input().Value("xxx")).
	FlexCol().PaddingLeft(20).RoundedLg().TextAlign("center")

#样式方法

后写的值会覆盖同一属性。长度是逻辑像素;字符串也可以用百分比。

func Card() *ui.Element {
	return ui.View().Child(ui.Text("Hello").TextColor("#e2e8f0")).
		Padding(20).BorderRadius(12).Bg("#111827")
}

.FlexCol()、.P4()、.GridCols(3)、.RoundedLg() 等辅助方法与 TypeScript 预设对应。

#合并样式

.Style(base).Style(overrides) 按顺序应用声明。用 .Merge(...) 组合可复用的 builder。

func MergedCard() *ui.Element {
	base := ui.Style().Padding(20).BorderRadius(8).Bg("#111827")
	overrides := ui.Style().BorderRadius(12)
	return ui.View().Child("Merged styles").Style(base).Style(overrides)
}

#复用样式

ui.Style() 返回一个值。方法会返回新值,因此共享样式不会被修改。派生变体时请保存返回值。

func SharedCard() *ui.Element {
	card := ui.Style().Padding(20).BorderRadius(12)
	emphasized := card.PaddingLeft(28).Bg("#1e293b")
	return ui.View().Gap(12).Children(
		ui.View().Child("Hello").Style(card).Bg("#111827"),
		ui.View().Child("Another card").Style(emphasized),
	)
}

.When(condition, style) 在条件为真时应用额外样式。响应式条件请传入 getter:.When(selected, ui.Style().Bg("#2563eb"))。在构建时调用 width() 只会记下当前数字;需要保持更新时请传入 width。

#Flexbox

.Flex()、.FlexRow() 或 .FlexCol() 启动 flex 布局。给可滚动的子节点加上 .MinHeight(0) 或 .MinWidth(0),它们才能收缩。

func Row() *ui.Element {
	return ui.View().Children(
		ui.Text("Flexible content").Flex1().MinWidth(0),
		ui.Button().Child("Action").FlexShrink(0),
	).Flex().Gap(12).ItemsCenter()
}

#网格布局

func Grid() *ui.Element {
	return ui.View().Children(ui.Text("Sidebar"), ui.Text("Content")).
		Display("grid").GridTemplateColumns("220px 1fr").Gap(16)
}

也可以使用 .GridCols(3) 和 .ColSpanFull()。

#文本与颜色

排版会继承给子节点。颜色接受 hex、rgb() / rgba() 或打包的 RGBA 值。内边距和边框不会继承。

func TypographyExample() *ui.Element {
	return ui.View().Children(
		ui.Text("Inbox").FontSize(24).FontWeight(600),
		ui.Text("All caught up."),
	).TextColor("#334155").FontSize(14).Padding(20)
}

#交互状态

使用 .Hover(...)、.Active(...)、.FocusStyle(...)、.DisabledStyle(...) 和 .SelectedStyle(...)。在基础样式上添加 .Transition(...) 即可为绘制变化添加动画。见过渡与动画。

func SelectableButton() *ui.Element {
	selected, setSelected := ui.CreateSignal(false)
	button := ui.Style().Padding(12).Bg("#e5e7eb").
		Hover(func(s ui.StyleBuilder) ui.StyleBuilder { return s.Opacity(0.85) })
	return ui.Button().Child("Toggle selection").Style(button).
		When(selected(), ui.Style().Bg("#2563eb").TextColor("white")).
		OnClick(func() { setSelected(!selected()) })
}

#分组与具名分组悬停

.Group(true) 标记未命名分组;.Group("card") 给它命名。.GroupHover(...) 跟随最近的祖先分组。.GroupHoverNamed("card", ...) 跟随最近的同名祖先。

func GroupExample() *ui.Element {
	return ui.View().Child(
		ui.Text("Changes when the card is hovered").
			TextColor("#64748b").
			GroupHoverNamed("card", func(s ui.StyleBuilder) ui.StyleBuilder {
				return s.TextColor("#2563eb")
			}),
	).Group("card").Padding(20)
}

.GroupActive(...) 和 .FocusWithin(...) 对按下和聚焦分组同样有效。这些状态只接受绘制属性,不能设置光标。