Skip to content

Components

hop implements a strongly typed component system.

Defining and rendering components

Components are defined by placing them at the top-level scope of a .hop file. They are rendered by referencing them from another component.

hop
<UserList {users: Array[String]}>
  <div>All users: {users.join(", ")}</div>
</UserList>

<Index>
  <UserList {users: ["loki", "jane", "tobi"]} />
</Index>

Importing components

In hop, every .hop file corresponds to a module.

The import directive imports a component from another module.

hop
import {UserList} from "@/user_list.hop"

<Index>
  <UserList {users: ["loki", "jane", "tobi"]} />
</Index>

Styling components with CSS

hop uses Tailwind 4 as its CSS framework. The hop compiler compiles Tailwind 4 to CSS natively, so no external dependencies need to be installed.

To add CSS classes to a HTML element, use the class attribute.

The class attribute of HTML elements accepts multiple arguments which are merged and deduplicated during compilation.

hop
<Component {css: String}>
    <div class={"p-2 bg-green-300", css}>

    </div>
</Component>

<!-- Compiles to <div class="p-2 bg-green-300 mb-4"></div> -->
<Component {css: "mb-4"} />

If you have a large number of classes you can break them up into separate strings to improve readability.

hop
<div class={
  "inline-flex",
  "items-center",
  "justify-center",
  "rounded-full",
  "border",
  "px-2",
  "py-0.5",
  "text-xs",
  "font-medium",
  "w-fit",
  "whitespace-nowrap",
  "overflow-hidden",
}>

Iteration

The <for> tag iterates over an array. The content of the <for> tag is evaluated once for each item of the array.

hop
<UserList {users: Array[String]}>
  <for {item in items}>
    <div>{item}</div>
  </for>
</UserList>

Conditional rendering

The <if> tag renders its content when a condition is true.

hop
<UserList {user: Array[User]}>
  <for {user in users}>
    <if {user.role == "admin"}>
      <div>{user.name} is an administrator</div>
    </if>
  </div>
</UserList>