Introduction

Components

Components allows you to split the application UI into reusable pieces with isolated state. You can use components to define layouts or create a collection of different UI elements.

Before we talk more about components, let's understand how they differ from components in the frontend ecosystem.

  • No reactivity: Since Edge is a backend template engine, there is no concept of reactivity in Edge or its components layer.

  • No support CSS or frontend JavaScript: Edge templates are not processed using build tools. Therefore we do not process inline CSS or create frontend bundles.

Creating components

Components are regular Edge templates created with the purpose of reuse. Components can access additional runtime properties like $props and $slots, which are unavailable to other Edge templates.

We recommend you create components inside the components directory of your template's root path. This helps create a visual boundary between the components and the rest of the templates used by your application.

Let's start by creating a button component. We will store it inside the components/button.edge file.

views/components/button.edge
<button type="{{ type || 'submit' }}"> {{ text }} </button>

Using components

You must use the @component tag to render a component inside your templates. The component tag accepts the template path as the first parameter and props as the second parameter.

<form>
@!component('components/button', { text: 'Login' })
@!component('components/button', { text: 'Cancel', type: 'reset' })
</form>

Output

<form>
<button type="submit"> Login </button>
<button type="reset"> Cancel </button>
</form>

Components from named disks can be referenced by prefixing the disk name.

@!component('uikit::components/button', { text: 'Login' })

Passing props

The component props are passed as the second parameter using the @component tag. Props are always represented as an object, and you can access them inside the component's template using the object property name.

See also: Props reference

@component('components/button', {
type: 'submit',
class: 'btn btn-large',
text: 'Login'
})
Within the component
{{ type }}
{{ class }}
{{ text }}

Another way to access props is using the $props property. For example:

{{ $props.get('type') }}
{{ $props.get('class') }}
{{ $props.get('text') }}

Using Slots

Slots are named outlets with markup inside them. Since writing HTML markup within props can quickly become messy, the slots provide a better authoring experience.

In the following example, we render the contents of the main slots using the $slots.main function.

See also: Slots reference

<button {{ $props.toAttrs() }}>
{{{ await $slots.main() }}}
</button>

The contents of the main slot are place between the opening and the closing tags.

@component('components/button', {
class: ['flex', 'align-center', 'space-x-4']
})
<i class="fa-lock"></i>
<span> Login </span>
@end

Components as tags

Edge allows you to reference components as tags. So, instead of using the @component tag, you can use the component filename as the tag name to render it.

Components as tags only work for components stored inside the components directory.

views/component/modal.edge
<div class="modal">
<header>
{{{ await $slots.header() }}}
</header>
<main>
{{{ await $slots.content() }}}
</main>
<footer>
{{{ await $slots.footer() }}}
</footer>
</div>

Given the above template is stored inside the modal.edge file, you can render it as follows.

@modal()
@slot('header')
<h2> Delete post </h2>
@end
@slot('content')
<p> You are about to delete the post permanently </p>
@end
@slot('footer')
<button> Yes, delete it </button>
<button> Cancel </button>
@end
@end

You can reference components as tags from named disks by prefixing the disk name with a dot separator.

{{-- Component as a tag from the uikit disk --}}
@!uikit.input()
{{-- Via component tag --}}
@!component('uikit::input')

Filename to tagName conversion

You can reference the files stored within the components directory as tags inside your edge templates. The following transformation rules are applied when creating a tag from the file name.

Template pathTag name
form/input.edge@form.input
tool_tip.edge@toolTip
checkout_form/input.edge@checkoutForm.input
modal/index.edge@modal