Templates Props API

Props & Attributes API

Props are the primary way to share data with a component when rendering it. Nimbus supports a powerful prop serialization engine that allows you to easily forward HTML attributes to elements without manual boilerplate.

§ Basic Props Usage

A component can accept any props passed to it at render time. Let's create an input component at resources/views/components/input.nimbus:

<input 
  type="{{ type || 'text' }}"
  placeholder="{{ placeholder || '' }}"
  name="{{ name }}"
  id="{{ name }}"
  value="{{ value || '' }}"
/>

Render the input component and pass custom props to configure it:

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

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

§ Serializing Props to HTML Attributes

Binding each individual prop manually does not scale well if you need to support many standard HTML attributes (like autocomplete, minlength, autofocus, etc.).

Nimbus provides the $props helper to serialize all properties into standard HTML attributes using the toAttrs() method:

<!-- Serializes all passed properties to standard HTML attributes -->
<input {{ $props.toAttrs() }} />

Merging Classes

You can assign default classes to your component while keeping the ability to append custom classes passed by the consumer. Use the .merge() method to combine classes:

<input {{
  $props.merge({ class: ['form-input', 'border', 'rounded-md'] }).toAttrs()
}} />

If the consumer passes custom classes, they will be cleanly appended to the output:

Input Markup Output HTML
@!input-styled({
  name: 'title'
})
<input name="title" class="form-input border rounded-md" />
@!input-styled({
  name: 'title',
  class: ['w-full', 'bg-slate-100']
})
<input name="title" class="form-input border rounded-md w-full bg-slate-100" />

§ Removing Existing Classes

If the consumer wants to override the default styles entirely, you can check for a custom prop (like removeExistingStyles) using mergeUnless():

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

Render component with overrides:

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

§ Props API Reference

The following methods are available on the $props helper object:

Method Description Example
has(key) Returns true if a given prop was passed to the component. $props.has('label')
get(key, fallback) Gets the value of a specific prop, optionally specifying a default fallback. $props.get('type', 'text')
only(keys) Returns a new props object containing only the specified keys. $props.only(['id', 'class'])
except(keys) Returns a new props object excluding the specified keys (useful to drop non-HTML attributes). $props.except(['label', 'removeExistingStyles'])
merge(defaults) Merges default parameters with user-provided props. Props passed at render take priority. $props.merge({ type: 'button' })