Skip to content

About

Clay meets Roc

Resources

Contributing

Stars

7 stars

Watchers

0 watching

Forks

Latest commit

 

History

391 Commits

Folders and files

Repository files navigation

Terrocotta - Clay meets Roc

Rocotta

Terrocotta is a library for building native applications in Roc.

It is an experimental project used to explore Roc, immediate-mode UI architecture, layout, rendering, and native application development. Its API is still evolving.

Terrocotta IDE example with a file explorer, document tabs, and syntax-highlighted source code

Terrocotta IDE demo with a file explorer, document tabs, and syntax-highlighted source code

Features

  • Model-View-Update (MVU) architecture.
  • Immediate mode UI.
  • 4 core elements: box(attributes, children), text(content), image(texture) and canvas(callback).
  • Clay layout engine ported to Roc: flexbox, floating, stack-based node layout.
  • raylib Rendering: using the roc-ray platform.
  • Theming: 6 seed colors generate 35 role-based color palette
  • Widgets: see examples

NB: Theming and widgets are just proof of concept implementations. Users are likely to build their own UI toolkit.

Documentation

Examples

Quick counter example:

import terrocotta.Element exposing [box, text, style]
import terrocotta.Program exposing [View]

AppModel : { count : I32 }

Msg : [Decrement, Increment]

init! : Config => Try(AppModel, [Exit(I64), ..])
init! = |_config| Ok({ count: 0 })

update! : AppModel, Msg => AppModel
update! = |model, msg| match msg {
	Decrement => { ..model, count: model.count - 1 }
	Increment => { ..model, count: model.count + 1 }
}

white = 0xFFFFFF.Color
blue = 0x2196F3.Color

button : Str, Msg -> View(Msg)
button = |label, msg| {
	box(
		{
			id: Auto,
			style: |status| style
				.width(Fit({}))
				.pad(8, 8, 8, 8)
				.background(if status.hovered { blue.darken(50) } else { blue })
				.font_color(white)
				.font_size(16),
			events: [OnClick(msg)],
		},
		[
			text(label),
		],
	)
}

view : AppModel -> View(Msg)
view = |model| {
	box(
		{ style: |_| style.direction(Row).height(Fit({})).gap(8).font_size(16) },
		[
			button("-", Decrement),
			text("Count: ${model.count.to_str()}"),
			button("+", Increment),
		],
	)
}

More examples

Counter
Terrocotta counter example
Todos
Terrocotta todo-list example
Widgets
Terrocotta widget gallery

Run the examples with:

  • roc examples/counter.roc: key and pointer event handling
  • roc examples/todos.roc: nested components, input-text/toggle state management
  • roc examples/widgets.roc: button, toggle, checkbox, slider, text-input
  • roc examples/tutorial/main.roc: interactive tutorial on layout, floating, text, image, canvas
  • roc examples/ide/main.roc: an IDE-like demo with files, tabs, editing, overlays, and asynchronous effects
  • roc examples/screwbot/main.roc: a CAD-like app demo

Interactive tutorial

Explore box layout, floating elements, text, images, and canvas rendering in the interactive tutorial:

Interactive Terrocotta tutorial

About

Clay meets Roc

Resources

Contributing

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages