Larastrap

Opinionated Bootstrap 5 components for Laravel

There are lots of Laravel packages pretending to wrap the widely popular Bootstrap CSS design system. Most of them are limited just to forms formatting (while Bootstrap provides so many different tools), and all of them have an elaborated syntax, so the code required to format your component is no so less verbose (nor more readable) then the actual resulting HTML.

Larastrap provides a conspicuous amount of (configurable) defaults and many out-of-the-box common behaviours. And, leveraging the Laravel's native Blade Components system, provides a few handy automatisms and the ability to define your own reusable Custom Elements. To reduce to the bare minimum the code you have to actually write (and read, and maintain...) to obtain your desidered layout.


Intro

To install it in your Laravel project, run
composer require madbob/larastrap; php artisan vendor:publish --tag=config

This will generate the config/larastrap.php file where you can find (and modify) the default behaviours. From here, you can define a default value for each property of each component, and define custom presets.

Each component can be included into your Blade template using
<x-larastrap::componentname>
and it is possible to inline overwrite all of his attributes using the common notation for Blade components
<x-larastrap::componentname id="a_static_string" :name="$a_php_variable">

Attributes can be also packed in a single indexed array and passed as :params. This is in particular useful when dynamically setting up and loading a component
<x-dynamic-component
    :component="sprintf('larastrap::%s', $a_component_type)"
    :params="['id' => 'a_static_string', 'name' => $a_php_variable]" />

It is recommended to execute php artisan view:clear after each update of the library.

Remeber to include the Bootstrap assets (both CSS and JS) in your page! It is suggested to use the laravel/ui package to start up your new application.
composer require laravel/ui

Larastrap is opensource, MIT licensed: grab the code and contribute on the Gitlab repository.

A navbar.
For each item you can specify just a label and an url, or a sub-array with more informations. Eventually even the children (for dropdowns).
If none of the items has the active attribute set to true, tries to guess the active item through the actual Laravel route. On the contrary, if a child is set to active, his parent is marked active as well
Bootstrap documentation

Code

<x-larastrap::navbar :options="[
    'Home' => '/',
    'Navbar' => ['url' => '#navbar', 'active' => true],
    'More' => ['children' => ['Forms' => '#forms', 'Modals' => '#modals', 'All' => '#props']]
]" />
<nav class="navbar navbar-light bg-light navbar-expand-lg">
  <div class="container-fluid">
    <div class="collapse navbar-collapse position-relative" id="navbar-dd47e21793c3e4493d24a10e132c93db">
      <ul class="navbar-nav">
        <li class="nav-item">
          <a class="nav-link" href="/">Home</a>
        </li>
        <li class="nav-item">
          <a class="nav-link active" href="#navbar">Navbar</a>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">More</a>
          <ul class="dropdown-menu">
            <li>
              <a class="dropdown-item" href="#forms">Forms</a>
            </li>
            <li>
              <a class="dropdown-item" href="#modals">Modals</a>
            </li>
            <li>
              <a class="dropdown-item" href="#props">All</a>
            </li>
          </ul>
        </li>
      </ul>
    </div>
  </div>
</nav>

Forms

Open a form, specifying a reference obj and an action URL, them populate it with the preferred inputs.
For each of them you have to specify at least a label and a name (matching with an attribute of the reference object) or an explicit value.
By default the POST method is used, the CSRF token is properly added, Bootstrap validation is leveraged, label_width and input_width are applied from the configuration, and a submit button is appended (using the array buttons, containing details for all desired buttons).
Bootstrap documentation
Must be a valid email address

Code

<?php $obj = (object) ['id' => 1234, 'name' => 'Foo', 'bio' => 'A very smart guy!', 'email' => 'foo@bar.baz', 'country' => 'it', 'colors' => ['red', 'green']] ?>
<x-larastrap::form :obj="$obj" action="/user/save" label_width="4" input_width="8">
  <x-larastrap::hidden name="id" />
  <x-larastrap::number name="id" label="ID" disabled="true" />
  <x-larastrap::text name="name" label="Name" />
  <x-larastrap::text name="surname" label="Surname" value="Bar" />
  <x-larastrap::textarea name="bio" label="Bio" />
  <x-larastrap::email name="email" label="EMail" help="Must be a valid email address" />

  <?php $countries = ['fr' => 'France', 'de' => 'Germany', 'it' => 'Italy'] ?>
  <x-larastrap::select name="country" label="Country (as select)" :options="$countries" />
  <x-larastrap::radios name="country" label="Country (as radio)" :options="$countries" color="danger" />
  <x-larastrap::radiolist name="other_country" label="Country (as radio list)" :options="$countries" />

  <?php $colors = ['red' => 'Red', 'green' => 'Green', 'blue' => 'Blue'] ?>
  <x-larastrap::checks name="colors" label="Colors" :options="$colors" color="warning" />
</x-larastrap::form>
<form id="form-efa21619175d87a10d609ac0e218c048" class="" method="post" action="/user/save" name="form-efa21619175d87a10d609ac0e218c048">
  <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg"> <input id="hidden-54744cb0c3e7f3f1e02984c469f13025" type="hidden" class="" name="id" value="1234">
  <div class="row mb-3">
    <label for="input-4048d55894a3811c6efc233bfe7de077" class="col-4 col-form-label">ID</label>
    <div class="col-8">
      <input id="input-4048d55894a3811c6efc233bfe7de077" type="number" class="form-control-plaintext" name="id" value="1234" step="1" min="-9223372036854775808" max="9223372036854775807" disabled>
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-abcf9089b1b9b886e36574fe84dcca12" class="col-4 col-form-label">Name</label>
    <div class="col-8">
      <input id="input-abcf9089b1b9b886e36574fe84dcca12" type="text" class="form-control" name="name" value="Foo">
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-abf6bc495b3e733799ababe95a3abead" class="col-4 col-form-label">Surname</label>
    <div class="col-8">
      <input id="input-abf6bc495b3e733799ababe95a3abead" type="text" class="form-control" name="surname" value="Bar">
    </div>
  </div>
  <div class="row mb-3">
    <label for="textarea-c8142e07123efc1def95fc8c7e269e4c" class="col-4 col-form-label">Bio</label>
    <div class="col-8">
      <textarea id="textarea-c8142e07123efc1def95fc8c7e269e4c" class="form-control" name="bio">A very smart guy!</textarea>
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-569e3db533b843998e4d39748da33b1d" class="col-4 col-form-label">EMail</label>
    <div class="col-8">
      <input id="input-569e3db533b843998e4d39748da33b1d" type="email" class="form-control" name="email" value="foo@bar.baz">
      <div class="form-text">
        Must be a valid email address
      </div>
    </div>
  </div>
  <div class="row mb-3">
    <label for="select-13646c45210b136934fc44c5c8e109cc" class="col-4 col-form-label">Country (as select)</label>
    <div class="col-8">
      <select class="form-select" name="country">
        <option value="fr">
          France
        </option>
        <option value="de">
          Germany
        </option>
        <option value="it" selected>
          Italy
        </option>
      </select>
    </div>
  </div>
  <div class="row mb-3">
    <label for="radios-786584b7d5a1dde1236cab3cf605d5f6" class="col-4 col-form-label col-4 col-form-label">Country (as radio)</label>
    <div class="col-8">
      <div class="btn-group" role="group">
        <input type="radio" class="btn-check" name="country" id="radios-786584b7d5a1dde1236cab3cf605d5f6-0309a6c666a7a803fdb9db95de71cf01" autocomplete="off" value="fr"> <label class="btn btn-danger" for="radios-786584b7d5a1dde1236cab3cf605d5f6-0309a6c666a7a803fdb9db95de71cf01">France</label> <input type="radio" class="btn-check" name="country" id="radios-786584b7d5a1dde1236cab3cf605d5f6-d8b00929dec65d422303256336ada04f" autocomplete="off" value="de"> <label class="btn btn-danger" for="radios-786584b7d5a1dde1236cab3cf605d5f6-d8b00929dec65d422303256336ada04f">Germany</label> <input type="radio" class="btn-check" name="country" id="radios-786584b7d5a1dde1236cab3cf605d5f6-1007e1b7f894dfbf72a0eaa80f3bc57e" autocomplete="off" value="it" checked> <label class="btn btn-danger" for="radios-786584b7d5a1dde1236cab3cf605d5f6-1007e1b7f894dfbf72a0eaa80f3bc57e">Italy</label>
      </div>
    </div>
  </div>
  <div class="row mb-3">
    <label for="radiolist-8a58fbd107c8b3a2ffc20919536fe8c1" class="col-4 col-form-label">Country (as radio list)</label>
    <div class="col-8">
      <div class="form-check">
        <input class="form-check-input" type="radio" name="other_country" id="radiolist-8a58fbd107c8b3a2ffc20919536fe8c1-0309a6c666a7a803fdb9db95de71cf01" value="fr"> <label class="form-check-label" for="radiolist-8a58fbd107c8b3a2ffc20919536fe8c1-0309a6c666a7a803fdb9db95de71cf01">France</label>
      </div>
      <div class="form-check">
        <input class="form-check-input" type="radio" name="other_country" id="radiolist-8a58fbd107c8b3a2ffc20919536fe8c1-d8b00929dec65d422303256336ada04f" value="de"> <label class="form-check-label" for="radiolist-8a58fbd107c8b3a2ffc20919536fe8c1-d8b00929dec65d422303256336ada04f">Germany</label>
      </div>
      <div class="form-check">
        <input class="form-check-input" type="radio" name="other_country" id="radiolist-8a58fbd107c8b3a2ffc20919536fe8c1-1007e1b7f894dfbf72a0eaa80f3bc57e" value="it"> <label class="form-check-label" for="radiolist-8a58fbd107c8b3a2ffc20919536fe8c1-1007e1b7f894dfbf72a0eaa80f3bc57e">Italy</label>
      </div>
    </div>
  </div>
  <div class="row mb-3">
    <label for="checks-064b41926b54322824286f62a67ec14f" class="col-4 col-form-label col-4 col-form-label">Colors</label>
    <div class="col-8">
      <div class="btn-group" role="group">
        <input type="checkbox" class="btn-check" name="colors[]" id="checks-064b41926b54322824286f62a67ec14f-ee38e4d5dd68c4e440825018d549cb47" autocomplete="off" value="red" checked> <label class="btn btn-warning" for="checks-064b41926b54322824286f62a67ec14f-ee38e4d5dd68c4e440825018d549cb47">Red</label> <input type="checkbox" class="btn-check" name="colors[]" id="checks-064b41926b54322824286f62a67ec14f-d382816a3cbeed082c9e216e7392eed1" autocomplete="off" value="green" checked> <label class="btn btn-warning" for="checks-064b41926b54322824286f62a67ec14f-d382816a3cbeed082c9e216e7392eed1">Green</label> <input type="checkbox" class="btn-check" name="colors[]" id="checks-064b41926b54322824286f62a67ec14f-9594eec95be70e7b1710f730fdda33d9" autocomplete="off" value="blue"> <label class="btn btn-warning" for="checks-064b41926b54322824286f62a67ec14f-9594eec95be70e7b1710f730fdda33d9">Blue</label>
      </div>
    </div>
  </div>
  <div class="col-12 text-end">
    <button id="button-ef2a8487c1aff197f0fab6da30d3b4c1" class="btn btn-primary" type="submit">Save</button>
  </div>
</form>
Instead of an action you can define a baseaction, used as a prefix for default Laravel's resource controller routing. In this example, if obj is null it will assign as action the value route('user.store'); otherwise, if obj is populated, it will become route('user.update', $obj->id). Handy to have a single edit form to both create and update the same kind of model!
Of course, when in update mode, the proper PUT method is used.

Code

<?php $obj = null ?>

<x-larastrap::form :obj="$obj" baseaction="user">
  <x-larastrap::text name="name" label="Name" />
  <x-larastrap::email name="email" label="EMail" />
</x-larastrap::form>
<form id="form-MO18dHueh8lWYmNjypRB" class="" method="post" action="https://larastrap.madbob.org/user/save" name="form-MO18dHueh8lWYmNjypRB">
  <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg">
  <div class="row mb-3">
    <label for="input-f47be7ac40c10a4c84e096b88745879b" class="col-2 col-form-label">Name</label>
    <div class="col-10">
      <input id="input-f47be7ac40c10a4c84e096b88745879b" type="text" class="form-control" name="name" value="">
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-81c9979365584eced84a915f42e125fc" class="col-2 col-form-label">EMail</label>
    <div class="col-10">
      <input id="input-81c9979365584eced84a915f42e125fc" type="email" class="form-control" name="email" value="">
    </div>
  </div>
  <div class="col-12 text-end">
    <button id="button-1a55bb8b464361ca8ac425dc59a773bf" class="btn btn-primary" type="submit">Save</button>
  </div>
</form>
Feedback for native Laravel validation is built-in: inputs that fail to validate are marked and the error message is shown below. You can also explicitely define a named error bag.
To enable client-side Bootstrap validation, set the client_side_errors attribute to true.
Bootstrap documentation

Code

<x-larastrap::form action="/validated" error_bag="special">
  <x-larastrap::text name="name" label="Name" />
  <x-larastrap::email name="email" label="EMail" />
</x-larastrap::form>
<form id="form-0598b7b15905e090ca354aafd41fc41c" class="" method="post" action="/validated" name="form-0598b7b15905e090ca354aafd41fc41c">
  <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg">
  <div class="row mb-3">
    <label for="input-02adb6d43411876c14a84a2723a4a001" class="col-2 col-form-label">Name</label>
    <div class="col-10">
      <input id="input-02adb6d43411876c14a84a2723a4a001" type="text" class="form-control" name="name" value="">
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-d4cf51b33175022bcace61cbd6d979b5" class="col-2 col-form-label">EMail</label>
    <div class="col-10">
      <input id="input-d4cf51b33175022bcace61cbd6d979b5" type="email" class="form-control" name="email" value="">
    </div>
  </div>
  <div class="col-12 text-end">
    <button id="button-daacd2677cc5ec0ba55d1874f0449f4b" class="btn btn-primary" type="submit">Save</button>
  </div>
</form>
For a different layout, use the formview parameter. Or modify the default configuration in larastrap.elements.form.formview to change them all.

Code

<?php $obj = (object) ['id' => 1234, 'name' => 'Mario', 'email' => 'mario@mailinator.com'] ?>
<x-larastrap::form :obj="$obj" action="/user/save" formview="vertical">
  <x-larastrap::number name="id" label="ID" disabled="true" />
  <x-larastrap::text name="name" label="Name" />
  <x-larastrap::email name="email" label="EMail" />
</x-larastrap::form>
<form id="form-efa21619175d87a10d609ac0e218c048" class="" method="post" action="/user/save" name="form-efa21619175d87a10d609ac0e218c048">
  <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg">
  <div class="mb-3">
    <label for="input-4048d55894a3811c6efc233bfe7de077" class="form-label">ID</label> <input id="input-4048d55894a3811c6efc233bfe7de077" type="number" class="form-control-plaintext" name="id" value="1234" step="1" min="-9223372036854775808" max="9223372036854775807" disabled>
  </div>
  <div class="mb-3">
    <label for="input-abcf9089b1b9b886e36574fe84dcca12" class="form-label">Name</label> <input id="input-abcf9089b1b9b886e36574fe84dcca12" type="text" class="form-control" name="name" value="Mario">
  </div>
  <div class="mb-3">
    <label for="input-c296d236883b67141754fe715fbbb5d1" class="form-label">EMail</label> <input id="input-c296d236883b67141754fe715fbbb5d1" type="email" class="form-control" name="email" value="mario@mailinator.com">
  </div>
  <div class="col-12 text-end">
    <button id="button-ef2a8487c1aff197f0fab6da30d3b4c1" class="btn btn-primary" type="submit">Save</button>
  </div>
</form>
The formview: inline mode displays the form on a single row, with hidden labels.
Bootstrap documentation

Code

<?php $obj = (object) ['id' => 1234, 'name' => 'Mario', 'email' => 'mario@mailinator.com'] ?>
<x-larastrap::form :obj="$obj" action="/user/save" formview="inline">
  <x-larastrap::number name="id" label="ID" disabled="true" />
  <x-larastrap::text name="name" label="Name" />
  <x-larastrap::email name="email" label="EMail" />
</x-larastrap::form>
<form id="form-efa21619175d87a10d609ac0e218c048" class="row row-cols-lg-auto g-3 align-items-center" method="post" action="/user/save" name="form-efa21619175d87a10d609ac0e218c048">
  <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg">
  <div class="col-12">
    <label for="input-4048d55894a3811c6efc233bfe7de077" class="d-none">ID</label> <input id="input-4048d55894a3811c6efc233bfe7de077" type="number" class="form-control-plaintext" name="id" value="1234" step="1" min="-9223372036854775808" max="9223372036854775807" disabled>
  </div>
  <div class="col-12">
    <label for="input-abcf9089b1b9b886e36574fe84dcca12" class="d-none">Name</label> <input id="input-abcf9089b1b9b886e36574fe84dcca12" type="text" class="form-control" name="name" value="Mario">
  </div>
  <div class="col-12">
    <label for="input-c296d236883b67141754fe715fbbb5d1" class="d-none">EMail</label> <input id="input-c296d236883b67141754fe715fbbb5d1" type="email" class="form-control" name="email" value="mario@mailinator.com">
  </div>
  <div class="col-12 text-end">
    <button id="button-ef2a8487c1aff197f0fab6da30d3b4c1" class="btn btn-primary" type="submit">Save</button>
  </div>
</form>
When a file input is involved, the enctype is automatically added to the parent form.

Code

<x-larastrap::form action="/document/save">
  <x-larastrap::file name="document" label="Attach Document" />
</x-larastrap::form>
<form id="form-727393f8c27471a02cd050bbc52653a8" class="" method="post" action="/document/save" enctype="multipart/form-data" name="form-727393f8c27471a02cd050bbc52653a8">
  <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg">
  <div class="row mb-3">
    <label for="input-6dda9f5367c5d697608992e18f7b7180" class="col-2 col-form-label">Attach Document</label>
    <div class="col-10">
      <input id="input-6dda9f5367c5d697608992e18f7b7180" type="file" class="form-control" name="document" value="">
    </div>
  </div>
  <div class="col-12 text-end">
    <button id="button-82b3e92181a76925597037044e994d23" class="btn btn-primary" type="submit">Save</button>
  </div>
</form>
If you have some special HTML block to align into the form, just leverage the x-larastrap::field component to format whatever you want.
example

Code

<x-larastrap::form action="/do/nothing">
  <x-larastrap::field label="Image">
    <img src="https://picsum.photos/100" class="img-fluid" alt="example">
  </x-larastrap::field>
</x-larastrap::form>
<form id="form-a1ebb26fd37dea35a7412172356c4d84" class="" method="post" action="/do/nothing" name="form-a1ebb26fd37dea35a7412172356c4d84">
  <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg">
  <div class="row mb-3">
    <label for="field-c912b8c76953bdd504b1f564249a938d" class="col-2 col-form-label">Image</label>
    <div class="col-10">
      <img src="https://picsum.photos/100" class="img-fluid" alt="example">
    </div>
  </div>
  <div class="col-12 text-end">
    <button id="button-bcef772e25ffda89f4da44d1ada2c0dc" class="btn btn-primary" type="submit">Save</button>
  </div>
</form>
There are a few bult-in utilities that can be used out-of-the-box, both to enrich the visualization and customize the behaviour of the fields. Those do not cover all combinations provided by Bootstrap, but still are handy in most cases.
@

Code

<?php $obj = (object) ['id' => 1234, 'name' => 'Foo', 'email' => 'foo@bar.baz', 'country' => 'it'] ?>
<x-larastrap::form :obj="$obj" action="/user/save">
  <x-larastrap::text name="name" label="Name" :classes="['is-invalid']" />
  <x-larastrap::text name="surname" label="Surname" pophelp="This is an extensive description text about the field, displayed only on hover. Requires initialization of Bootstrap's popovers" />
  <x-larastrap::email name="email" label="EMail" textappend="@" />
  <x-larastrap::text name="danger" label="Warning!" label_class="text-danger" value="Yes, this has a custom CSS class for the label" />

  <?php $countries = ['fr' => 'France', 'de' => 'Germany', 'it' => 'Italy'] ?>
  <x-larastrap::select name="country" npostfix="[]" label="First Array of Countries" :options="$countries" />
  <x-larastrap::select name="country" npostfix="[]" label="Second Array of Countries" :options="$countries" />
</x-larastrap::form>
<form id="form-efa21619175d87a10d609ac0e218c048" class="" method="post" action="/user/save" name="form-efa21619175d87a10d609ac0e218c048">
  <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg">
  <div class="row mb-3">
    <label for="input-353a3542ce5bb4d1c1a40c828c174c8b" class="col-2 col-form-label">Name</label>
    <div class="col-10">
      <input id="input-353a3542ce5bb4d1c1a40c828c174c8b" type="text" class="is-invalid form-control" name="name" value="Foo">
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-c710868e92d84bcf0bea591b5d15e98c" class="col-2 col-form-label">Surname <span class="badge rounded-pill bg-primary" data-bs-toggle="popover" data-bs-trigger="hover" data-bs-content="This is an extensive description text about the field, displayed only on hover. Requires initialization of Bootstrap's popovers">?</span></label>
    <div class="col-10">
      <input id="input-c710868e92d84bcf0bea591b5d15e98c" type="text" class="form-control" name="surname" value="">
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-c296d236883b67141754fe715fbbb5d1" class="col-2 col-form-label">EMail</label>
    <div class="col-10">
      <div class="input-group has-validation">
        <input id="input-c296d236883b67141754fe715fbbb5d1" type="email" class="form-control" name="email" value="foo@bar.baz"> <span class="input-group-text">@</span>
      </div>
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-9b979d5c6cbce63daabc9be53005d094" class="text-danger col-2 col-form-label">Warning!</label>
    <div class="col-10">
      <input id="input-9b979d5c6cbce63daabc9be53005d094" type="text" class="form-control" name="danger" value="Yes, this has a custom CSS class for the label">
    </div>
  </div>
  <div class="row mb-3">
    <label for="select-2a598ab1f580c4c478c93a9ecd17a346" class="col-2 col-form-label">First Array of Countries</label>
    <div class="col-10">
      <select class="form-select" name="country[]">
        <option value="fr">
          France
        </option>
        <option value="de">
          Germany
        </option>
        <option value="it" selected>
          Italy
        </option>
      </select>
    </div>
  </div>
  <div class="row mb-3">
    <label for="select-134270bf1a43e990598307df329570e7" class="col-2 col-form-label">Second Array of Countries</label>
    <div class="col-10">
      <select class="form-select" name="country[]">
        <option value="fr">
          France
        </option>
        <option value="de">
          Germany
        </option>
        <option value="it" selected>
          Italy
        </option>
      </select>
    </div>
  </div>
  <div class="col-12 text-end">
    <button id="button-ef2a8487c1aff197f0fab6da30d3b4c1" class="btn btn-primary" type="submit">Save</button>
  </div>
</form>

With Models

There are a few special widgets included in Larastrap that permit to pass as options and value one or more Eloquent Models.
The first is x-larastrap::select-model: a regular select input able translate a Collection of Models (fetched with a query or from a relationship) into an array of IDs and values.

Code

<?php $user = App\Models\User::inRandomOrder()->first() ?>
<x-larastrap::select-model name="user_id" label="Select a User" :options="App\Models\User::all()" :value="$user->id" />
<div class="row mb-3">
  <label for="select-f7ef1b6b660795af8e49a8edc33e8d4c" class="col-2 col-form-label">Select a User</label>
  <div class="col-10">
    <select class="form-select" name="user_id">
      <option value="1">
        Adrian Conroy
      </option>
      <option value="2">
        Rodrick Emard
      </option>
      <option value="3">
        Harold Little
      </option>
      <option value="4">
        Shakira Barrows IV
      </option>
      <option value="5">
        Cole Tillman
      </option>
      <option value="6">
        Mrs. Ursula Keeling MD
      </option>
      <option value="7">
        Ransom D'Amore
      </option>
      <option value="8">
        Zion Morar
      </option>
      <option value="9">
        Cicero Mitchell
      </option>
      <option value="10">
        Dean Shields
      </option>
    </select>
  </div>
</div>
Another component is x-larastrap::checks-model.
In those kind of widgets, $obj->id becomes the value of the option and $obj->name is used for its content, but you can customize this behaviour using a provided translateCallback function used to retrieve them for each model. An idea is to provide your own custom elements for frequently selectable Models, and reuse them across your codebase.

Code

<?php $translate = function($obj) { return [$obj->id, $obj->email]; } ?>
<x-larastrap::checks-model classes="d-flex flex-column" name="user_id" label="Select Multiple Users" :options="App\Models\User::inRandomOrder()->limit(3)->get()" :translateCallback="$translate" />
<div class="row mb-3">
  <label for="checks-587e4a6b97fffb103d15a1537dc38301" class="col-2 col-form-label col-2 col-form-label">Select Multiple Users</label>
  <div class="col-10">
    <div class="d-flex flex-column btn-group" role="group">
      <input type="checkbox" class="btn-check" name="user_id[]" id="checks-587e4a6b97fffb103d15a1537dc38301-31f63266a428a760fca09451a6d6cfad" autocomplete="off" value="3"> <label class="btn btn-outline-primary" for="checks-587e4a6b97fffb103d15a1537dc38301-31f63266a428a760fca09451a6d6cfad">skiles.hester@example.com</label> <input type="checkbox" class="btn-check" name="user_id[]" id="checks-587e4a6b97fffb103d15a1537dc38301-70a14ae348fd147ce8712993026915f2" autocomplete="off" value="2"> <label class="btn btn-outline-primary" for="checks-587e4a6b97fffb103d15a1537dc38301-70a14ae348fd147ce8712993026915f2">macejkovic.haven@example.net</label> <input type="checkbox" class="btn-check" name="user_id[]" id="checks-587e4a6b97fffb103d15a1537dc38301-31f01b1cdc4a54650200ff96769d577d" autocomplete="off" value="6"> <label class="btn btn-outline-primary" for="checks-587e4a6b97fffb103d15a1537dc38301-31f01b1cdc4a54650200ff96769d577d">wbauch@example.com</label>
    </div>
  </div>
</div>
And yet another component is x-larastrap::radios-model.
Need to push some extra option, perhaps to permit to select 'none'? Use the extra_options attribute to pass an addictional array of values!

Code

<x-larastrap::radios-model name="user_id" label="Select a User" :options="App\Models\User::inRandomOrder()->limit(2)->get()" :extra_options="[0 => 'None']" />
<div class="row mb-3">
  <label for="radios-d167dad57d959716f8f2acc4b71eeb0c" class="col-2 col-form-label col-2 col-form-label">Select a User</label>
  <div class="col-10">
    <div class="btn-group" role="group">
      <input type="radio" class="btn-check" name="user_id" id="radios-d167dad57d959716f8f2acc4b71eeb0c-6adf97f83acf6453d4a6a4b1070f3754" autocomplete="off" value="0"> <label class="btn btn-outline-primary" for="radios-d167dad57d959716f8f2acc4b71eeb0c-6adf97f83acf6453d4a6a4b1070f3754">None</label> <input type="radio" class="btn-check" name="user_id" id="radios-d167dad57d959716f8f2acc4b71eeb0c-b83d3b0411edf8ef78ddfd3de8425742" autocomplete="off" value="3"> <label class="btn btn-outline-primary" for="radios-d167dad57d959716f8f2acc4b71eeb0c-b83d3b0411edf8ef78ddfd3de8425742">Harold Little</label> <input type="radio" class="btn-check" name="user_id" id="radios-d167dad57d959716f8f2acc4b71eeb0c-abc1046a47bf14d40586bd9bb3ff6d42" autocomplete="off" value="9"> <label class="btn btn-outline-primary" for="radios-d167dad57d959716f8f2acc4b71eeb0c-abc1046a47bf14d40586bd9bb3ff6d42">Cicero Mitchell</label>
    </div>
  </div>
</div>

Modals

The classic Bootstrap modal. The x-larastrap::button component has a special triggers_modal property to rapidly setup a trigger.
Bootstrap documentation

Code

<x-larastrap::button label="Open Modal" triggers_modal="#test-modal" />

<x-larastrap::modal title="Test" id="test-modal">
  <p>Ciao</p>
</x-larastrap::modal>
<button id="button-3891f7af354d17a6450a0afba1276e2a" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#test-modal">Open Modal</button>
<div class="modal fade" id="test-modal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-none">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">
          Test
        </h5>
      </div>
      <div class="modal-body">
        <p>
          Ciao
        </p>
      </div>
      <div class="modal-footer">
        <button id="button-7d346ba4960c9d83a431f407770bf281" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>
A form into a modal is a special (automatically managed) case, in which buttons for the form are merged into the modal's footer.

Code

<x-larastrap::button label="Open Modal with Form" triggers_modal="#save-modal" />

<x-larastrap::modal title="Test" id="save-modal">
  <?php $obj = (object) ['id' => 1234, 'name' => 'Foo', 'email' => 'foo@bar.baz'] ?>
  <x-larastrap::form :obj="$obj" action="/user/save">
    <x-larastrap::hidden name="id" />
    <x-larastrap::text name="name" label="Name" />
    <x-larastrap::email name="email" label="EMail" />
  </x-larastrap::form>
</x-larastrap::modal>
<button id="button-d0ec6b1dadc5d9a4201cae14c173d47e" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#save-modal">Open Modal with Form</button>
<div class="modal fade" id="save-modal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-none">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">
          Test
        </h5>
      </div>
      <div class="modal-body">
        <form id="form-79637ad0553c59bc31ed130d13432ecf" class="" method="post" action="/user/save" name="form-79637ad0553c59bc31ed130d13432ecf">
          <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg"> <input id="hidden-34d860976605381038f169623bb6b401" type="hidden" class="" name="id" value="1234">
          <div class="row mb-3">
            <label for="input-21cc72708834f5d8d3f51bcc59d955f1" class="col-2 col-form-label">Name</label>
            <div class="col-10">
              <input id="input-21cc72708834f5d8d3f51bcc59d955f1" type="text" class="form-control" name="name" value="Foo">
            </div>
          </div>
          <div class="row mb-3">
            <label for="input-d134773e17aa20c080614bab91ac953e" class="col-2 col-form-label">EMail</label>
            <div class="col-10">
              <input id="input-d134773e17aa20c080614bab91ac953e" type="email" class="form-control" name="email" value="foo@bar.baz">
            </div>
          </div>
        </form>
      </div>
      <div class="modal-footer">
        <button id="button-fb91209730e7b544ccd4b075e9ee965e" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button id="button-3cbf8566a02facfacf7539ba8abf89cd" class="btn btn-primary" type="submit" form="form-79637ad0553c59bc31ed130d13432ecf">Save</button>
      </div>
    </div>
  </div>
</div>

Tabs

Tabs are managed as a hiearchy of elements: the options associative array permits to specify the contents of the tabs, and each x-larastrap::tabpane is a tab page. By default, the first tab is active.
Remember that you can alter the classes attribute (both inline or once in the configuration file) to pass formatting classes for the tab panes (useful for padding and margins).
Bootstrap documentation

This is the first tab!

This is the second tab!

Code

<x-larastrap::tabs>
  <x-larastrap::tabpane label="First">
    <p>This is the first tab!</p>
  </x-larastrap::tabpane>

  <x-larastrap::tabpane label="Second" active="true">
    <p>This is the second tab!</p>
  </x-larastrap::tabpane>
</x-larastrap::tabs>
<ul class="nav nav-tabs" id="tabs-d72e5ee9b367833956ed9f88a960c686" role="tablist">
  <li class="nav-item" role="presentation">
    <button id="tabpane-55ed49db9bc53ffed58be607672007eb-7fb55ed0b7a30342ba6da306428cae04" class="nav-link" role="tab" data-bs-toggle="tab" data-bs-target="#tabpane-55ed49db9bc53ffed58be607672007eb">First</button>
  </li>
  <li class="nav-item" role="presentation">
    <button id="tabpane-fcb568dc5758e3932b3cb45abbc28c68-c22cf8376b1893dcfcef0649fe1a7d87" class="nav-link active" role="tab" data-bs-toggle="tab" data-bs-target="#tabpane-fcb568dc5758e3932b3cb45abbc28c68">Second</button>
  </li>
</ul>
<div class="tab-content" id="tabs-d72e5ee9b367833956ed9f88a960c686_contents">
  <div class="p-3 tab-pane fade" id="tabpane-55ed49db9bc53ffed58be607672007eb" role="tabpanel">
    <p>
      This is the first tab!
    </p>
  </div>
  <div class="p-3 tab-pane fade show active" id="tabpane-fcb568dc5758e3932b3cb45abbc28c68" role="tabpanel">
    <p>
      This is the second tab!
    </p>
  </div>
</div>
Different styles for the tabs are possibile.
Remember to always define as active one of the tabpanes, or an active index to the parent tabs!
Bootstrap documentation

This is the first tab!

This is the second tab!

Code

<x-larastrap::tabs tabview="pills" active="0">
  <x-larastrap::tabpane label="First">
    <p>This is the first tab!</p>
  </x-larastrap::tabpane>

  <x-larastrap::tabpane label="Second">
    <p>This is the second tab!</p>
  </x-larastrap::tabpane>
</x-larastrap::tabs>
<ul class="nav nav-pills" id="tabs-d72e5ee9b367833956ed9f88a960c686" role="tablist">
  <li class="nav-item" role="presentation">
    <button id="tabpane-55ed49db9bc53ffed58be607672007eb-7fb55ed0b7a30342ba6da306428cae04" class="nav-link active" role="tab" data-bs-toggle="tab" data-bs-target="#tabpane-55ed49db9bc53ffed58be607672007eb">First</button>
  </li>
  <li class="nav-item" role="presentation">
    <button id="tabpane-fcb568dc5758e3932b3cb45abbc28c68-c22cf8376b1893dcfcef0649fe1a7d87" class="nav-link" role="tab" data-bs-toggle="tab" data-bs-target="#tabpane-fcb568dc5758e3932b3cb45abbc28c68">Second</button>
  </li>
</ul>
<div class="tab-content" id="tabs-d72e5ee9b367833956ed9f88a960c686_contents">
  <div class="p-3 tab-pane fade show active" id="tabpane-55ed49db9bc53ffed58be607672007eb" role="tabpanel">
    <p>
      This is the first tab!
    </p>
  </div>
  <div class="p-3 tab-pane fade" id="tabpane-fcb568dc5758e3932b3cb45abbc28c68" role="tabpanel">
    <p>
      This is the second tab!
    </p>
  </div>
</div>

Accordion

Accordions are not much different from tabs: there is a wrapper component and child components, one for panel. Each sub panel can be individually opened through the active attribute.
Bootstrap documentation

This is the first accordion!

This is the second accordion!

Code

<x-larastrap::accordion always_open="true">
  <x-larastrap::accordionitem label="First">
    <p>This is the first accordion!</p>
  </x-larastrap::accordionitem>

  <x-larastrap::accordionitem label="Second" active="true">
    <p>This is the second accordion!</p>
  </x-larastrap::accordionitem>
</x-larastrap::accordion>
<div class="accordion" id="accordion-bdf5f1cc5cb974c1d4e6a753320085dc">
  <div class="accordion-item">
    <h2 class="accordion-header" id="head-accordionitem-9fcaf329f46a1e5dfde9f072d773e456">
      <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordionitem-9fcaf329f46a1e5dfde9f072d773e456" aria-expanded="false" aria-controls="accordionitem-9fcaf329f46a1e5dfde9f072d773e456">First</button>
    </h2>
    <div id="accordionitem-9fcaf329f46a1e5dfde9f072d773e456" class="accordion-collapse collapse" aria-labelledby="head-accordionitem-9fcaf329f46a1e5dfde9f072d773e456">
      <div class="accordion-body">
        <p>
          This is the first accordion!
        </p>
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h2 class="accordion-header" id="head-accordionitem-456a4acd23535465f4b6f73b489d6387">
      <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#accordionitem-456a4acd23535465f4b6f73b489d6387" aria-expanded="true" aria-controls="accordionitem-456a4acd23535465f4b6f73b489d6387">Second</button>
    </h2>
    <div id="accordionitem-456a4acd23535465f4b6f73b489d6387" class="accordion-collapse collapse show" aria-labelledby="head-accordionitem-456a4acd23535465f4b6f73b489d6387">
      <div class="accordion-body">
        <p>
          This is the second accordion!
        </p>
      </div>
    </div>
  </div>
</div>

Collapse

Collapse are collapsible panels, usually attached to a button or a link to toggle their status. A collapse can individually be opened through the open attribute.
Bootstrap documentation
Toggle Collapse

This is a collapse!

Code

<x-larastrap::link triggers_collapse="test_collapse" label="Toggle Collapse" />
<x-larastrap::collapse id="test_collapse">
  <p>This is a collapse!</p>
</x-larastrap::accordion>
<a id="link-f76fbe0c96869b715094bbe5bfa1f25f" class="btn btn-primary" data-bs-toggle="collapse" data-bs-target="#test_collapse" href="#">Toggle Collapse</a>
<div id="test_collapse" class="collapse">
  <div class="card card-body">
    <p>
      This is a collapse!
    </p>
  </div>
</div>
A collapse can be also paired to a x-larastrap::check: the status of the checkbox determines the open/closed status of the collapse.

This is a collapse!

Code

<x-larastrap::check triggers_collapse="test_checkbox_collapse" label="Toggle Collapse" checked />
<x-larastrap::collapse id="test_checkbox_collapse">
  <p>This is a collapse!</p>
</x-larastrap::accordion>
<div class="row mb-3">
  <label for="check-f8076478b93b1224d9785589f1ef3d0a" class="col-2 col-form-label">Toggle Collapse</label>
  <div class="col-10">
    <div class="form-check mt-1">
      <input id="check-f8076478b93b1224d9785589f1ef3d0a" type="checkbox" class="form-check-input" name="" value="" data-bs-toggle="collapse" data-bs-target="#test_checkbox_collapse" checked>
    </div>
  </div>
</div>
<div id="test_checkbox_collapse" class="collapse show">
  <div class="card card-body">
    <p>
      This is a collapse!
    </p>
  </div>
</div>

Encloses

Among the other types of containers, x-larastrap::enclose is a particular one: it provides no HTML output, but is useful to provide a context for inner inputs.

Code

<table class="table">
    @foreach(App\Models\User::take(3)->get() as $user)
        <x-larastrap::enclose :obj="$user">
            <tr>
                <td><x-larastrap::text name="name" readonly squeeze="true" /></td>
                <td><x-larastrap::email name="email" squeeze="true" /></td>
            </tr>
        </x-larastrap::enclose>
    @endforeach
</table>
<table class="table">
  <tr>
    <td>
      <input id="input-29d2a38bc55f40c53d56a75d461905f2" type="text" class="form-control-plaintext" name="name" value="Adrian Conroy" readonly>
    </td>
    <td>
      <input id="input-8e0ec167ceb986bc34178d33a997806f" type="email" class="form-control" name="email" value="alta01@example.com">
    </td>
  </tr>
  <tr>
    <td>
      <input id="input-6d6bc6a3912024e713ead6769823c872" type="text" class="form-control-plaintext" name="name" value="Rodrick Emard" readonly>
    </td>
    <td>
      <input id="input-4ad9d3e62005c960191647cc12d0296a" type="email" class="form-control" name="email" value="macejkovic.haven@example.net">
    </td>
  </tr>
  <tr>
    <td>
      <input id="input-72024a8a039526cf142f1b4f820f2601" type="text" class="form-control-plaintext" name="name" value="Harold Little" readonly>
    </td>
    <td>
      <input id="input-90a058ff43337553ae2fe97e67f0337d" type="email" class="form-control" name="email" value="skiles.hester@example.com">
    </td>
  </tr>
</table>

Miscellaneous

Code

<x-larastrap::button label="Yes, this is a button" color="warning" />
<button id="button-2d3b3b9bd404e283a852c7d019d1b8ab" class="btn btn-warning">Yes, this is a button</button>
Links! Mostly like buttons, but with href!

Code

<x-larastrap::link label="Yes, this is an anchor" color="info" href="https://larastrap.madbob.org/" />
Button groups!
Bootstrap documentation

Code

<x-larastrap::btngroup>
  <x-larastrap::button label="First" />
  <x-larastrap::button label="Second" />
  <x-larastrap::button label="Third" />
</x-larastrap::btngroup>
<div class="btn-group" role="group">
  <button id="button-d8463d0eb79630f825971f1131f9630a" class="btn btn-primary">First</button> <button id="button-f1f6a471e2bb06d465eae0aad2450c49" class="btn btn-primary">Second</button> <button id="button-d59e87126cf5f98aa75ba391d130bd80" class="btn btn-primary">Third</button>
</div>
More input fields!

Code

<x-larastrap::form action="/do/nothing">
  <x-larastrap::check label="Checkbox" />
  <x-larastrap::check label="Switch" switch />
  <x-larastrap::url label="URL" />
  <x-larastrap::range label="Range" min="0" max="100" step="5" />
  <x-larastrap::date label="Date" />
  <x-larastrap::time label="Time" />
  <x-larastrap::datetime label="Date and Time" />
  <x-larastrap::color label="Color" />
</x-larastrap::form>
<form id="form-a1ebb26fd37dea35a7412172356c4d84" class="" method="post" action="/do/nothing" name="form-a1ebb26fd37dea35a7412172356c4d84">
  <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg">
  <div class="row mb-3">
    <label for="check-1a12c7340fbf30ef11c8758cad5d1166" class="col-2 col-form-label">Checkbox</label>
    <div class="col-10">
      <div class="form-check mt-1">
        <input id="check-1a12c7340fbf30ef11c8758cad5d1166" type="checkbox" class="form-check-input" name="" value="">
      </div>
    </div>
  </div>
  <div class="row mb-3">
    <label for="check-ec3d90ad3e2737c5d55f0dcdeeed5824" class="col-2 col-form-label">Switch</label>
    <div class="col-10">
      <div class="form-check form-switch mt-1">
        <input id="check-ec3d90ad3e2737c5d55f0dcdeeed5824" type="checkbox" class="form-check-input" name="" value="">
      </div>
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-feb688bd6812548ac2149fbee8018c16" class="col-2 col-form-label">URL</label>
    <div class="col-10">
      <input id="input-feb688bd6812548ac2149fbee8018c16" type="url" class="form-control" name="" value="">
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-28b5d4e75081986d75c662c566158f0e" class="col-2 col-form-label">Range</label>
    <div class="col-10">
      <input id="input-28b5d4e75081986d75c662c566158f0e" type="range" class="form-range" name="" value="" step="5" min="0" max="100">
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-a89904c3f2988d252b6c8870c8f885e9" class="col-2 col-form-label">Date</label>
    <div class="col-10">
      <input id="input-a89904c3f2988d252b6c8870c8f885e9" type="date" class="form-control" name="" value="">
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-78e63ea76cf3dc072b5c2d0ac4ef9b32" class="col-2 col-form-label">Time</label>
    <div class="col-10">
      <input id="input-78e63ea76cf3dc072b5c2d0ac4ef9b32" type="time" class="form-control" name="" value="">
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-af90efad9c16e14ec3d7e81fa0fcfb80" class="col-2 col-form-label">Date and Time</label>
    <div class="col-10">
      <input id="input-af90efad9c16e14ec3d7e81fa0fcfb80" type="datetime-local" class="form-control" name="" value="">
    </div>
  </div>
  <div class="row mb-3">
    <label for="input-e1cb4a7d746fbe16c1eb9b50871362f1" class="col-2 col-form-label">Color</label>
    <div class="col-10">
      <input id="input-e1cb4a7d746fbe16c1eb9b50871362f1" type="color" class="form-control" name="" value="">
    </div>
  </div>
  <div class="col-12 text-end">
    <button id="button-bcef772e25ffda89f4da44d1ada2c0dc" class="btn btn-primary" type="submit">Save</button>
  </div>
</form>
Optgroups in selects!

Code

<?php

$options = [
    'first' => (object) [
        'label' => 'First Group',
        'children' => [
            'first_1' => 'First Item in First Group',
            'first_2' => 'Second Item in First Group',
        ],
    ],
    'second' => (object) [
        'label' => 'Second Group',
        'children' => [
            'second_1' => 'First Item in Second Group',
            'second_2' => (object) [
                'label' => 'Second Item in Second Group (disabled)',
                'disabled' => true,
            ],
            'second_3' => 'Third Item in Second Group',
        ],
    ],
];

?>

<x-larastrap::select label="Select in groups" :options="$options" />
<div class="row mb-3">
  <label for="select-2a944934c0277ec825e2b0976e9949e2" class="col-2 col-form-label">Select in groups</label>
  <div class="col-10">
    <select class="form-select" name="">
      <optgroup label="First Group">
        <option value="first_1">
          First Item in First Group
        </option>
        <option value="first_2">
          Second Item in First Group
        </option>
      </optgroup>
      <optgroup label="Second Group">
        <option value="second_1">
          First Item in Second Group
        </option>
        <option value="second_2" disabled>
          Second Item in Second Group (disabled)
        </option>
        <option value="second_3">
          Third Item in Second Group
        </option>
      </optgroup>
    </select>
  </div>
</div>
Complex radio selections! The same applies for x-larastrap::checks and x-larastrap::checklist, too!

Code

<?php

$options = [
    'first' => 'First',
    'second' => 'Second',
    'third' => (object) [
        'label' => 'Third (disabled)',
        'disabled' => true,
    ],
    'fourth' => (object) [
        'label' => 'Fourth (hidden)',
        'hidden' => true,
    ],
    'fifth' => (object) [
        'label' => 'Fifth (with data attributes)',
        'button_attributes' => ['data-example' => 'test'],
    ],
];

?>

<x-larastrap::radios name="choose" label="Choose one" :options="$options" value="second" classes="d-flex flex-column" />
<x-larastrap::radiolist name="other_choose" label="Choose one" :options="$options" value="fifth" />
<div class="row mb-3">
  <label for="radios-618fb2e2878e3dd5eb1562df802a44ba" class="col-2 col-form-label col-2 col-form-label">Choose one</label>
  <div class="col-10">
    <div class="d-flex flex-column btn-group" role="group">
      <input type="radio" class="btn-check" name="choose" id="radios-618fb2e2878e3dd5eb1562df802a44ba-7fb55ed0b7a30342ba6da306428cae04" autocomplete="off" value="first"> <label class="btn btn-outline-primary" for="radios-618fb2e2878e3dd5eb1562df802a44ba-7fb55ed0b7a30342ba6da306428cae04">First</label> <input type="radio" class="btn-check" name="choose" id="radios-618fb2e2878e3dd5eb1562df802a44ba-c22cf8376b1893dcfcef0649fe1a7d87" autocomplete="off" value="second" checked> <label class="btn btn-outline-primary" for="radios-618fb2e2878e3dd5eb1562df802a44ba-c22cf8376b1893dcfcef0649fe1a7d87">Second</label> <input type="radio" class="btn-check" name="choose" id="radios-618fb2e2878e3dd5eb1562df802a44ba-98c3ade1588014f2e7a6eefed3683385" autocomplete="off" value="third"> <label class="btn btn-outline-primary disabled" for="radios-618fb2e2878e3dd5eb1562df802a44ba-98c3ade1588014f2e7a6eefed3683385">Third (disabled)</label> <input type="radio" class="btn-check" name="choose" id="radios-618fb2e2878e3dd5eb1562df802a44ba-dca120157ca6fa00f2fdae57b1f283ad" autocomplete="off" value="fourth"> <input type="radio" class="btn-check" name="choose" id="radios-618fb2e2878e3dd5eb1562df802a44ba-36e930319217e145ca1bd9d09da124c2" autocomplete="off" value="fifth"> <label class="btn btn-outline-primary" for="radios-618fb2e2878e3dd5eb1562df802a44ba-36e930319217e145ca1bd9d09da124c2" data-example="test">Fifth (with data attributes)</label>
    </div>
  </div>
</div>
<div class="row mb-3">
  <label for="radiolist-1084ab199c030864eb74f218b313cae8" class="col-2 col-form-label">Choose one</label>
  <div class="col-10">
    <div class="form-check">
      <input class="form-check-input" type="radio" name="other_choose" id="radiolist-1084ab199c030864eb74f218b313cae8-7fb55ed0b7a30342ba6da306428cae04" value="first"> <label class="form-check-label" for="radiolist-1084ab199c030864eb74f218b313cae8-7fb55ed0b7a30342ba6da306428cae04">First</label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="radio" name="other_choose" id="radiolist-1084ab199c030864eb74f218b313cae8-c22cf8376b1893dcfcef0649fe1a7d87" value="second"> <label class="form-check-label" for="radiolist-1084ab199c030864eb74f218b313cae8-c22cf8376b1893dcfcef0649fe1a7d87">Second</label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="radio" name="other_choose" id="radiolist-1084ab199c030864eb74f218b313cae8-98c3ade1588014f2e7a6eefed3683385" value="third"> <label class="form-check-label" for="radiolist-1084ab199c030864eb74f218b313cae8-98c3ade1588014f2e7a6eefed3683385">Third (disabled)</label>
    </div>
    <div class="form-check" hidden="">
      <input class="form-check-input" type="radio" name="other_choose" id="radiolist-1084ab199c030864eb74f218b313cae8-dca120157ca6fa00f2fdae57b1f283ad" value="fourth"> <label class="form-check-label" for="radiolist-1084ab199c030864eb74f218b313cae8-dca120157ca6fa00f2fdae57b1f283ad">Fourth (hidden)</label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="radio" name="other_choose" id="radiolist-1084ab199c030864eb74f218b313cae8-36e930319217e145ca1bd9d09da124c2" value="fifth" checked> <label class="form-check-label" for="radiolist-1084ab199c030864eb74f218b313cae8-36e930319217e145ca1bd9d09da124c2">Fifth (with data attributes)</label>
    </div>
  </div>
</div>

Custom Elements

In the config/larastrap.php file is possible to define custom presets, to be reused across the application using a specific set of configurations. Those are defined by a Blade component name, the name of the extended element type, and your own parameters.

Are you sure you want to delete this element?

Code

<!--

You find this example in the default config/larastrap.php file

'customs' => [
  'deleteform' => [  \\ <--- This is the name of your custom component!
    'extends' => 'form',
    'params' => [
      'classes' => ['text-center'],
      'method' => 'DELETE',
      'form_buttons' => [['color' => 'danger', 'label' => 'Yes, delete it', 'attributes' => ['type' => 'submit']]]
    ],
  ],
],

-->

<x-larastrap::deleteform action="/user/delete">
  <x-larastrap::hidden name="id" value="123" />
  <p>Are you sure you want to delete this element?</p>
</x-larastrap::deleteform>
<form id="form-bc9f139cce8450083fa6c793f83c5e51" class="text-center" method="post" action="/user/delete" name="form-bc9f139cce8450083fa6c793f83c5e51">
  <input type="hidden" name="_token" value="ZKjcrip7LUQx1d7mVGwg1PC1PnS3TnlgAvpXcsGg"> <input id="hidden-c0b5c5146f156dcca103778f2b522b6c" type="hidden" class="" name="id" value="123">
  <p>
    Are you sure you want to delete this element?
  </p>
  <div class="col-12 text-center">
    <button id="button-6867323c853a4a4fdd4fc722567053c4" class="btn btn-danger" type="submit">Yes, delete it</button>
  </div>
</form>
It is possible to dinamically create custom elements at runtime, accessing the LarastrapStack singleton inited by the Larastrap Service Provider.

Code

<?php

/*
    Call this before Blade rendering, e.g. in the parent Controller or in a Service Provider
*/
app()->make('LarastrapStack')->addCustomElement('jerkbutton', [
    'extends' => 'button',
    'params' => [
        'color' => 'secondary',
        'postlabel' => ' (Click Here!)',
    ],
]);

?>

<x-larastrap::jerkbutton label="A Button" />
<button id="button-13d5d783f1795f19a4ef2ae1bfbed09c" class="btn btn-secondary">A Button (Click Here!)</button>

All Elements and Properties

Your can include any component using the proper Blade directive, and passing attributes to it. All the attributes here listed are processed internally and may not appear in the final rendered node; those that are not managed (e.g. your own data attributes) are simply translated into the final HTML.

Some attributes are valid for every kind of component, such as:

  • id
    The ID of the HTML node. If not specified, a random one is generated so that all items are properly marked
  • attributes
    An associative array which is translated to an extra set of attributes to the node. Useful to attach your data attributes, custom attributes, hooks for your preferred Javascript framework and so on
  • classes
    An array of CSS classes to be added to the HTML node, in addiction to those automatically generated. Can be defined as an array or a space separated string
  • override_classes
    An array of CSS classes to be applied to the HTML node, overriding those automatically generated. Can be defined as an array or a space separated string
  • hidden
    A boolean attribute which hides the element
  • reviewCallback
    A function to be called for manually handle and transform the parameters of the node. This have to take two parameters (the first is the instance of the component, the second is the indexed array of parameters) and returns the (eventually modified) array of parameters. Mostly intended for Custom Elements

Some components are Containers, so have an opening and a closing tag. Their behaviour may be altered by child elements. Those always accept the following attributes:

  • obj
    A PHP object (eventually, an Eloquent model) used to automatically populate the value of inner input fields

Then there are Inputs, used (usually into x-larastrap::form) to take user inputs. Those are automatically wrapped by a x-larastap::field to format them within the parent Container. Common attributes:

  • label
    The label to be displayed within the input field into the form, accordly to his formview
  • label_html
    Use this attribute if you want to use HTML code in the label (plain label is escaped by Blade)
  • label_class
    CSS classes to be applied to the label, aside those automatically generated
  • label_width
    Width, in Bootstrap columns, of the label column. Can be a simple integer, to be used once for all Bootstrap's breakpoints, or an associative array containing the desired width for each target breackpoint, such as ["xs" => 4, "sm" => 3, "md" => 2]
  • input_width
    Width, in Bootstrap columns, of the input field column. Same rules as label_width
  • help
    An optional text to be displayed below the input field
  • pophelp
    An optional text to be displayed in a popover, aside the label. This is intended for long text, as an alternative to help. If you use this, remember to init Bootstrap's popovers
  • squeeze
    If true, the wrapping x-larastap::field (including the label) is omitted and just the input field is rendered
  • name
    HTML name of the input field. If matches with a property of the obj set into the parent Container, the input field is inited with the same value
  • nprefix
    Optional text to prepend to the name
  • npostfix
    Optional text to append to the name
  • value
    Value of the input field. If defined, will override the same value got from the obj object set into the parent Container
  • required
    True or false, if the input field has to be marked as mandatory for the user
  • disabled
    True or false, if the input field has to be marked as disabled for the user
  • readonly
    True or false, if the input field has to be marked as read only for the user
  • asplaintext
    True or false, valid only if disabled or readonly are true: if the input field has to be displayed as plaintext instead as a disabled input
  • placeholder
    Optional placeholder to display when the input field is empty
  • textappend
    If defined and not empty, will create a Bootstrap input group with this text appended to the input
  • error_handling
    True or false, if you want to display feedback after native Laravel validation. Usually you want to set this parameter in the parent form
  • error_bag
    The name of the Laravel error bag to look for errors related to this input. Usually you want to set this parameter in the parent form

Following, a complete list of components with their custom properties and notes about how common properties are managed in special cases.

x-larastrap::accordion Container
  • always_open
    Set to true if opening an inner panel will not close all others
x-larastrap::accordionitem Container
  • active
    Set to true to display the panel opened
  • label
    Text to be displayed into the opening header
  • label_html
    Use this attribute if you want to use HTML code in the header (plain label is escaped by Blade)
x-larastrap::btngroup Container
  • orientation
    Orientation of the button group. Valid values: horizontal (default), vertical
x-larastrap::button
  • color
    One of the colors described by Bootstrap. Of course you can define your own custom CSS classes and add more colors
  • label
    Text to be displayed into the button
  • postlabel
    A static text to be placed after the label
  • prelabel
    A static text to be placed before the label
  • triggers_collapse
    If set, the button will be set up to trigger the collapse identified by the selector here specified
  • triggers_modal
    If set, the button will be set up to trigger the modal identified by the selector here specified
x-larastrap::check Input
  • checked
    If set, overrides the content of value to determine if the checkbox must be flagged
  • switch
    True to render the checkbox as a switch
  • triggers_collapse
    If set, the checkbox will be set up to trigger the collapse identified by the selector here specified. When the checkbox is checked, the collapse is displayed as open
  • value
    The value of the checkbox. If it is a boolean, is it used to set the checkbox as flagged or not
x-larastrap::checklist
  • options
    Associative array of options. May be a simple [value => label] array, otherwise "label" may be replaced by an object including the properties:
    • label: for the actual label
    • id: a unique ID for the option. Note that each option needs a unique ID: if not specificed, one is automatically assigned
    • disabled: if set to true, the option is disabled
    • hidden: if set to true, the option is rendered in HTML with a "hidden" attribute
    • label_classes: array of CSS classes to be applied to the label; those are merged with the label_class applied to the whole component
    • label_attributes: associative array of additional attributes for the label
x-larastrap::checklist-model
  • extra_options
    Optional associative array for addictional options into the component
  • options
    Associative array of options. May be a simple [value => label] array, otherwise "label" may be replaced by an object including the properties:
    • label: for the actual label
    • id: a unique ID for the option. Note that each option needs a unique ID: if not specificed, one is automatically assigned
    • disabled: if set to true, the option is disabled
    • hidden: if set to true, the label is not displayed (but an invisible input radio is still rendered in HTML)
    • button_classes: array of CSS classes to be applied to the button; those are merged with the button_classes applied to the whole component
    • button_attributes: associative array of additional attributes for the label
  • translateCallback
    Optional function to provide the value and the content for each selectable option into the component. Takes an Eloquent Model as parameter, returns an array with two values: the first will be the value, the second will be the content
x-larastrap::checks
  • button_classes
    Array of additional CSS classes to apply to all buttons within the component
  • color
    One of the colors described by Bootstrap. Of course you can define your own custom CSS classes and add more colors
  • npostfix
    If not defined, this is set to [] to enforce handling of submitted checked options as an array
  • options
    Associative array of options. May be a simple [value => label] array, otherwise "label" may be replaced by an object including the properties:
    • label: for the actual label
    • id: a unique ID for the option. Note that each option needs a unique ID: if not specificed, one is automatically assigned
    • disabled: if set to true, the option is disabled
    • hidden: if set to true, the label is not displayed (but an invisible input radio is still rendered in HTML)
    • button_classes: array of CSS classes to be applied to the button; those are merged with the button_classes applied to the whole component
    • button_attributes: associative array of additional attributes for the label
x-larastrap::checks-model
  • button_classes
    Array of additional CSS classes to apply to all buttons within the component
  • color
    One of the colors described by Bootstrap. Of course you can define your own custom CSS classes and add more colors
  • extra_options
    Optional associative array for addictional options into the component
  • options
    Associative array of options. May be a simple [value => label] array, otherwise "label" may be replaced by an object including the properties:
    • label: for the actual label
    • id: a unique ID for the option. Note that each option needs a unique ID: if not specificed, one is automatically assigned
    • disabled: if set to true, the option is disabled
    • hidden: if set to true, the label is not displayed (but an invisible input radio is still rendered in HTML)
    • button_classes: array of CSS classes to be applied to the button; those are merged with the button_classes applied to the whole component
    • button_attributes: associative array of additional attributes for the label
  • translateCallback
    Optional function to provide the value and the content for each selectable option into the component. Takes an Eloquent Model as parameter, returns an array with two values: the first will be the value, the second will be the content
x-larastrap::collapse Container
  • open
    Set to true to display the collapse contents
x-larastrap::color Input
x-larastrap::date Input
x-larastrap::datetime Input
x-larastrap::email Input
x-larastrap::enclose Container
x-larastrap::field Container
x-larastrap::file Input
x-larastrap::form Container
  • action
    The action URL of the form
  • baseaction
    The prefix for the resource controller routes involved, to be defined in place of action. If obj is null, this will translate in route($baseaction . ".store"); otherwise, route($baseaction . ".update", $obj->id)
  • buttons
    An array of associative arrays for each buttons to display at the end of the form. Same properties as for the x-larastrap::button component. If you override the default buttons, remember to always add one having a ["type" => "submit"] attribute!
  • buttons_align
    Alignment of form buttons. Valid values: start, end, center
  • client_side_errors
    If set to true, Boostrap validation functions are leveraged: needs-validation CSS class is appended to the form and the novalidate attribute is added. Please note that you still have to init the basic JS code to add the was-validated CSS class on form submit. Default: false
  • enctype
    The enctype of the form. Please note that file component already handles this transparently
  • error_bag
    The name of the Laravel error bag where to look for errors. Default: "default"
  • error_handling
    If set to true, Laravel validation functions are leveraged: if an input field fails to validate, the is-invalid CSS class is appended and the error message is displayed just below. Default: true
  • formview
    Style to be applied to the form, determines layout of inner fields. Valid values: horizontal, vertical, inline, grid
  • gutter
    Used for fields spacing when formview is inline or grid
  • method
    The HTML method (GET, POST, DELETE, PUT...) of the form. If it is not GET, the @method and @csrf Blade directives are automatically managed
x-larastrap::hidden
x-larastrap::link
  • color
    One of the colors described by Bootstrap. Of course you can define your own custom CSS classes and add more colors
  • href
    URL to link. Default: #
  • label
    Text to be displayed into the link
  • postlabel
    A static text to be placed after the label
  • prelabel
    A static text to be placed before the label
  • triggers_collapse
    If set, the link will be set up to trigger the collapse identified by the selector here specified
  • triggers_modal
    If set, the link will be set up to trigger the modal identified by the selector here specified
x-larastrap::modal Container
  • buttons
    An array containing associative arrays for each buttons to display at the end of the modal. Same properties as for the button component. If you override the default buttons, keep in mind to have one button with a ["attributes" => ["data-bs-dismiss" => "modal"]] attribute to close the modal!
  • scrollable
    True if the modal has to be set as scrollable
  • size
    The size of the modal. Can be a string (sm, lg, xl...) or an array of Bootstrap classes, to include also fullscreen behaviours
  • title
    Title of the modal
x-larastrap::navbar
  • collapse
    Bootstrap's breakpoint at which the navbar have to collapse. Valid values: never, md, lg, xl, xxl
  • color
    One of the colors described by Bootstrap for navbars. Of course you can define your own custom CSS classes and add more colors
  • end_options
    Same as options, but buttons are displayed on the end side of the navbar
  • options
    Associative array of menu items. May be a simple [label => url] array, otherwise "url" may be replaced by an associative array including the properties:
    • url: the actual URL to link
    • active: if the menu item has to be highlighted. Note that Larastrap already tries to determine the currently active menu item, accordly to the current Route
    • attributes: associative array of additional attributes for the button
    • children: if a dropdown menu has be to generated, this must include another associative array recursively handled
  • title
    Title of the navbar
  • title_link
    Optional URL to link in the navbar title
x-larastrap::number Input
  • max
    The maximum value for the input
  • min
    The minimum value for the input
  • step
    The step value for the input
x-larastrap::password Input
x-larastrap::pophelp
  • text
    Text to display into the popover
x-larastrap::radiolist
  • options
    Associative array of options. May be a simple [value => label] array, otherwise "label" may be replaced by an object including the properties:
    • label: for the actual label
    • id: a unique ID for the option. Note that each option needs a unique ID: if not specificed, one is automatically assigned
    • disabled: if set to true, the option is disabled
    • hidden: if set to true, the option is rendered in HTML with a "hidden" attribute
    • label_classes: array of CSS classes to be applied to the label; those are merged with the label_class applied to the whole component
    • label_attributes: associative array of additional attributes for the label
x-larastrap::radiolist-model
  • extra_options
    Optional associative array for addictional options into the component
  • options
    Associative array of options. May be a simple [value => label] array, otherwise "label" may be replaced by an object including the properties:
    • label: for the actual label
    • id: a unique ID for the option. Note that each option needs a unique ID: if not specificed, one is automatically assigned
    • disabled: if set to true, the option is disabled
    • hidden: if set to true, the label is not displayed (but an invisible input radio is still rendered in HTML)
    • button_classes: array of CSS classes to be applied to the button; those are merged with the button_classes applied to the whole component
    • button_attributes: associative array of additional attributes for the label
  • translateCallback
    Optional function to provide the value and the content for each selectable option into the component. Takes an Eloquent Model as parameter, returns an array with two values: the first will be the value, the second will be the content
x-larastrap::radios
  • button_classes
    Array of additional CSS classes to apply to all buttons within the component
  • color
    One of the colors described by Bootstrap. Of course you can define your own custom CSS classes and add more colors
  • options
    Associative array of options. May be a simple [value => label] array, otherwise "label" may be replaced by an object including the properties:
    • label: for the actual label
    • id: a unique ID for the option. Note that each option needs a unique ID: if not specificed, one is automatically assigned
    • disabled: if set to true, the option is disabled
    • hidden: if set to true, the label is not displayed (but an invisible input radio is still rendered in HTML)
    • button_classes: array of CSS classes to be applied to the button; those are merged with the button_classes applied to the whole component
    • button_attributes: associative array of additional attributes for the label
x-larastrap::radios-model
  • button_classes
    Array of additional CSS classes to apply to all buttons within the component
  • color
    One of the colors described by Bootstrap. Of course you can define your own custom CSS classes and add more colors
  • extra_options
    Optional associative array for addictional options into the component
  • options
    Associative array of options. May be a simple [value => label] array, otherwise "label" may be replaced by an object including the properties:
    • label: for the actual label
    • id: a unique ID for the option. Note that each option needs a unique ID: if not specificed, one is automatically assigned
    • disabled: if set to true, the option is disabled
    • hidden: if set to true, the label is not displayed (but an invisible input radio is still rendered in HTML)
    • button_classes: array of CSS classes to be applied to the button; those are merged with the button_classes applied to the whole component
    • button_attributes: associative array of additional attributes for the label
  • translateCallback
    Optional function to provide the value and the content for each selectable option into the component. Takes an Eloquent Model as parameter, returns an array with two values: the first will be the value, the second will be the content
x-larastrap::range Input
  • max
    The maximum value for the input
  • min
    The minimum value for the input
  • step
    The step value for the input
x-larastrap::select Input
  • multiple
    True for a multiple selection
  • npostfix
    If not defined, and multiple is active, this is set to [] to enforce handling of submitted selected options as an array
  • options
    Associative array of options. May be a simple [value => label] array, otherwise "label" may be replaced by an object including the properties:
    • label: for the actual label
    • disabled: if set to true, the option is disabled
    • children: if an optgroup has be to generated, this must include another associative array recursively handled
  • readonly
    If set to true, this forces the select to display as a static text with the selected option's label
x-larastrap::select-model
  • extra_options
    Optional associative array for addictional options into the component
  • multiple
    See x-larastrap::select
  • npostfix
    See x-larastrap::select
  • options
    A Collection of Eloquent Models; each will provide an option into the select
  • readonly
    See x-larastrap::select
  • translateCallback
    Optional function to provide the value and the content for each selectable option into the component. Takes an Eloquent Model as parameter, returns an array with two values: the first will be the value, the second will be the content
x-larastrap::tabpane Container
  • active
    Set to true to display the pane. Only one active pane is opened at once in tabs, and at least one pane have to be active. If set on at least one x-larastrap::tabpane within a x-larastrap::tabs, overrides the active property of the parent tabs
  • button_attributes
    Additional associative array of attributes for the tab
  • button_classes
    Additional array of CSS classes for the tab
x-larastrap::tabs Container
  • active
    Index of the tab you want to make active by default. To be used instead of the active property of child x-larastrap::tabpane. Usually you may want to set this to 0 (by default it is undefined)
  • tabview
    Style to be applied to the tabs. Valid values: tabs, pills
  • use_anchors
    Use <a> tags for tabs instead of <button>. Useful when you have tabs inside a form, to avoid triggering unwanted submit
x-larastrap::text Input
x-larastrap::textarea Input
x-larastrap::time Input
x-larastrap::url Input