本文へスキップ

コンポーネント

*ui.Element を返す関数を書きます。View、Text、Button から始め、残りのコントロールも同じように組み立てます。

#コンポーネントの定義

普通の Go の値を渡します。引数がシグナルを読む場合、そのバインディングは関数が返ったあとも生き続けます。追加の注釈は不要です。

func CounterLabel(count int) *ui.Element {
	return ui.Text("Count: ", count).FontSize(20)
}

func ComponentExample() *ui.Element {
	count, setCount := ui.CreateSignal(0)
	return ui.View().Children(
		CounterLabel(count()),
		ui.Button().Child("Increment").OnClick(func() { setCount(count() + 1) }),
	)
}

構造体も同じです。quantity を更新するとテキストが変わり、LineItem はマウントされたままです。

type Product struct {
	ID    string
	Name  string
	Price int
}

func LineItem(product Product, quantity int) *ui.Element {
	return ui.Text(product.Name, " × ", quantity, " = $", product.Price*quantity)
}

func Cart() *ui.Element {
	quantity, setQuantity := ui.CreateSignal(1)
	return ui.View().Children(
		LineItem(Product{ID: "mug", Name: "Mug", Price: 12}, quantity()),
		ui.Button().Child("Add one").OnClick(func() { setQuantity(quantity() + 1) }),
	)
}

コンテナは ui.View() で始め、.Child(...) または .Children(...) で内容を追加します。

func CardComponent(title string, children ...any) *ui.Element {
	return ui.View().FlexCol().Padding(20).Gap(12).Children(
		ui.Text(title).FontWeight(600),
		children,
	)
}

#プリミティブ

View、Text、Button、Input でほとんどのレイアウトとテキストをカバーします。スタイル、プロパティ、ハンドラーは同じ要素にチェーンします。

任意の extensions/editor パッケージは、CGO や別のネイティブライブラリを追加せず、Rust コアの Editor、CodeBlock、DiffView を提供します。

任意の extensions/markdown パッケージは、ストリーミング差分更新と CodeBlock 描画を含む保持型 Markdown を提供します。

func ButtonExample(save func()) *ui.Element {
	return ui.Button().Child("Save changes").
		Height(40).
		PaddingLeft(16).
		PaddingRight(16).
		BackgroundColor("#2563eb").
		TextColor("white").
		BorderRadius(8).
		Hover(func(s ui.StyleBuilder) ui.StyleBuilder { return s.BackgroundColor("#3b82f6") }).
		OnClick(save)
}

#複合コンポーネント

インスタンスを作り、名前付きパーツを組み立てます。文字列も子として使えます。

func TabsExample() *ui.Element {
	tabs := ui.NewTabs().DefaultValue("account")
	return tabs.Root().Children(
		tabs.List().Children(
			tabs.Tab("account").Child("Account"),
			tabs.Tab("security").Child("Security"),
		),
		tabs.Panel("account").Child("Account settings"),
		tabs.Panel("security").Child("Security settings"),
	)
}

振る舞いはインスタンスに、スタイルは各パーツに設定します。パーツは他の子と同じように入れ子にします。

#制御された状態

現在の値を渡し、変更コールバックから次の値を書き込みます。インスタンスは、それを所有するコンポーネントの中で作ってください。

func CheckboxExample() *ui.Element {
	checked, setChecked := ui.CreateSignal(false)
	checkbox := ui.NewCheckbox().Checked(checked()).OnCheckedChange(
		func(next bool, _ *native.Event) { setChecked(next) },
	)
	return checkbox.Root().FlexRow().Gap(8).Children(
		checkbox.Indicator().Child("✓"),
		"Remember me",
	)
}

#コンポーネントの種類

コンポーネントリファレンス はフォーム、オーバーレイ、メニュー、テーブル、ツリーなどを扱います。このリポジトリからギャラリーを実行します:

bun packages/cli/src/cli.ts dev --project examples/components

#各パーツのスタイル

スタイルはパーツ自身に付けるか、ui.Style() の値を共有します:

triggerStyle := ui.Style().Padding(12).RoundedLg().Bg("#2563eb")
return popover.Trigger().Style(triggerStyle).TextColor("#ffffff").Child("Account")

OnClick を追加しても、パーツの既定の動作は残ります。キャンセルするときは OnClickEvent で PreventDefault() を呼び出してください。