Props

Props

Props are the primary way to share data with a component when rendering it. A component can accept any props without maintaining a list of allowed props.

views/components/input.edge
<input
type="{{ type || 'text' }}"
placeholder="{{ placeholder || '' }}"
name="{{ name }}"
id="{{ name }}"
value="{{ value: '' }}"
/>

Let's render the input component and pass it some props.

@!input({
name: 'title',
placeholder: 'Enter post title'
})
@!input({
name: 'slug',
placeholder: 'Enter post slug'
})

Serializing props to HTML attributes

Right now, we are manually binding props to HTML attributes on the input element. This approach cannot scale because we must explicitly add support for every single HTML attribute.

You may use the $props object to serialize all the props to HTML attributes using the toAttrs method. All props will be serialized to a string and applied to the input element in the following example.

<input {{ $props.toAttrs() }} />

Let's take a step further and assign default styling classes to our input element using the .merge method. If you pass any additional classes when using the component, they will be merged with the default classes.

<input {{
$props.merge({ class: ['input'] }).toAttrs()
}} />
Input Output
@input({
type: 'text',
name: 'title',
id: 'title',
})
<input
type="text"
name="title"
id="title"
class="input"
/>
@input({
type: 'text',
name: 'title',
id: 'title',
class: [
'input-medium',
'input-rounded'
]
})
<input
type="text"
name="title"
id="title"
class="input input-medium input-rounded"
/>

Removing existing classes

Props serialization offers no inbuilt APIs to remove existing classes using the merge method. However, you can use an additional prop someone can pass to ignore existing classes.

<input {{
$props
.mergeUnless(removeExistingStyles, { class: ['input'] })
.except(['removeExistingStyles'])
.toAttrs()
}} />

The default classes will be applied unless you pass the removeExistingStyles prop when rendering the component.

@!input({
removeExistingStyles: true,
class: ['flex', 'mt-2', 'mb-4', 'border']
})

Props API

Following is the list of methods available on the $props object.

has

Find if a given prop exists.

{{ $props.has('text') }}

get

Get value for a given prop.

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

only

Get a new props object with only the mentioned keys.

{{ $props.only(['text', 'class']).get('text') }}

except

Get a new props object except for the mentioned keys.

{{ $props.except(['text', 'size']) }}

merge/mergeIf/mergeUnless

Merge custom properties with the props values. The props values have priority over custom properties.

In the following example, the value of the type property will be text unless an explicit value is provided at the time of rendering the component.

<button {{ $props.merge({ type: 'text' }).toAttrs() }}>
</button>
@!component('components/button', { type: 'reset' })

Output HTML

<button type="reset">
</button>