Building Components with Surface

Let's Learn how to use Surface to build complex components.

So far in this course, we’ve built our own LiveView components from scratch. While this has allowed us to build layered and organized user interfaces, we’ve also seen that complex markup leads to mistakes. Passing the wrong values or incomplete data will break a component, sometimes with an obscure error.

The templating syntax can also be error-prone. For example, forgetting to close a tag can change the structure of a document and lead to more potential pitfalls as LiveView tries to stitch the right values into the DOM at the right time.

Benefits of Surface components

The Surface Library solves all of these problems. The surface is a component library for LiveView that provides:

  • Syntactic sugar for defining and rendering components.
  • Type checking to enforce both HTML structure and component input types.
  • Out-of-the-box organization and type checking for public and private data.
  • Syntax highlighting in some editors, like VSCode.

But before we jump into building Surface components, let’s make a plan.

Planning the Presentation layer

When we built the admin dashboard, we used the Contex library to produce SVG. That approach hid graphics presentation details from us. Now, it’s time to work on those graphical details. We’ll divide the game into layers and represent each part of the game with its own Surface component. Each of these Surface components will construct and render some hand-crafted SVG markup. We’ll dig into Surface in greater detail later on. For now, it’s enough to understand that a Surface component behaves no differently from a LiveView component, Surface merely provides some syntactic sugar and additional functionality on top of LiveView components. When we write about components, we’ll refer to Surface components with the <ComponentName> syntax, and plain LiveView components with the ComponentName syntax.

The overall game display will consist of the game’s puzzle board along with the palette of available shapes. The entry point for this display will be a LiveView, GameLive. This LiveView will render a stateful top-level Surface component, <Board>. The <Board> component will, in turn, render some stateless children—a <Canvas> component to display the puzzle board and a <Palette> component to display the pentomino shapes that the user can use to solve the puzzle.

Here’s a look at the overall architecture of our layered components:

Get hands-on with 1400+ tech skills courses.