bethuxs / blade-bootstrap-components
Bootstrap 5 components for Laravel Blade
Package info
github.com/bethuxs/BladeBootstrapComponents
pkg:composer/bethuxs/blade-bootstrap-components
Requires
- php: ^8.0
- laravel/framework: ^11.0.0
- spatie/laravel-flash: ^1.10
Requires (Dev)
- orchestra/testbench: ^9.0
- pestphp/pest: ^2.34
- pestphp/pest-plugin-laravel: ^2.4
- phpstan/phpstan: ^1.10
This package is auto-updated.
Last update: 2026-03-11 14:49:58 UTC
README
A lightweight and flexible library of Blade components designed to integrate seamlessly with Bootstrap 5. This library simplifies building responsive UIs in Laravel by encapsulating Bootstrap 5 components into reusable Blade templates.
Features
- β¨ Prebuilt components for common Bootstrap 5 elements
- π§ Fully customizable with dynamic attributes
- π¦ Easy integration with Laravel projects
- βΏ Accessibility-first design (ARIA labels, semantic HTML)
- π Internationalization (i18n) support built-in
- π¨ Supports Bootstrap's utility classes
- π‘ Well-typed component props
Installation
Requirements
- Laravel: 11.x (PHP 8.0+)
- PHP: 8.0 or higher
- Bootstrap: 5.x
Steps
-
Install the package via Composer:
composer require bethuxs/blade-bootstrap-components
-
The components are automatically registered. No need to publish!
-
Include the Bootstrap 5 assets in your application:
<!-- Add in your main layout file --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
Components
Form Components
<x-bs::form>
Main form wrapper with automatic CSRF and method handling.
<x-bs::form method="POST" route="products.store"> <!-- Form content here --> </x-bs::form>
Props:
method(string, default:"POST") - HTTP methodroute(string) - Route name for actionsubmit(string) - Submit button text (optional)
<x-bs::form.input>
Text input with label and error handling.
<x-bs::form.input name="email" label="Email" type="email" value="{{ old('email') }}" />
Props:
name(required) - Input name attributelabel(string) - Label textvalue(mixed) - Input valuetype(string, default:"text") - Input typeplaceholder(string) - Placeholder text
<x-bs::form.textarea>
Multi-line text input with customizable rows.
<x-bs::form.textarea name="description" label="Description" rows="5" value="{{ old('description') }}" />
Props:
name(required) - Textarea namelabel(string) - Label textvalue(mixed) - Textarea contentrows(int, default:3) - Number of rows
<x-bs::form.button
Styled button with Bootstrap classes.
<x-bs::form.button label="Save" type="submit" contextual="success" />
Props:
label(string) - Button texttype(string, default:"button") - Button typecontextual(string, default:"primary") - Bootstrap color (primary, success, danger, etc.)size(string) - Size (sm, lg)
<x-bs::form.select
Dropdown select with error handling.
<x-bs::form.select name="status" label="Status" :options="['active' => 'Active', 'inactive' => 'Inactive']" placeholder="Select a status" />
Props:
name(required) - Select namelabel(string) - Label textoptions(array, default:[]) - Options key => valueplaceholder(string) - Placeholder option textvalue(mixed) - Selected value
<x-bs::form.countries
Select component pre-filled with world countries.
<x-bs::form.countries name="country" label="Country" useIso="false" />
Props:
name(required) - Select namelabel(string) - Label textuseIso(bool, default:false) - Use ISO code (true) or emoji (false)placeholder(string, default:__('Select a country'))value(mixed) - Selected value
<x-bs::form.checkbox
Single checkbox input with label.
<x-bs::form.checkbox name="agree" label="I agree to the terms" value="1" />
Props:
name(required) - Checkbox namelabel(string) - Checkbox labelvalue(mixed) - Checkbox valuechecked(bool, default:false) - Is checked
<x-bs::form.radio
Single radio button input.
<x-bs::form.radio name="gender" label="Male" value="male" />
Props:
name(required) - Radio namelabel(string) - Radio labelvalue(mixed, required) - Radio valuechecked(bool) - Is checked
<x-bs::form.checkbox-group
Multiple checkboxes with label.
<x-bs::form.checkbox-group name="interests" label="Your Interests" :options="['sports' => 'Sports', 'music' => 'Music', 'reading' => 'Reading']" :values="old('interests', [])" inline />
Props:
name(required) - Group name (stored as array)label(string) - Group labeloptions(array, default:[]) - Options key => valuevalues(array, default:[]) - Selected valuesinline(bool, default:false) - Display inline
<x-bs::form.radio-group
Multiple radio buttons with label.
<x-bs::form.radio-group name="level" label="Skill Level" :options="['beginner' => 'Beginner', 'intermediate' => 'Intermediate', 'advanced' => 'Advanced']" value="{{ old('level') }}" inline />
Props:
name(required) - Group namelabel(string) - Group labeloptions(array, default:[]) - Options key => valuevalue(mixed) - Selected valueinline(bool, default:false) - Display inline
<x-bs::form.file
File input with validation support.
<x-bs::form.file name="avatar" label="Profile Picture" accept="image/*" multiple />
Props:
name(required) - File input namelabel(string) - Input labelaccept(string) - Accepted file typesmultiple(bool, default:false) - Allow multiple files
Message Components
<x-bs::messages.all
Display both flash and validation messages.
<x-bs::messages.all />
<x-bs::messages.flash
Session flash messages with auto-dismiss.
<x-bs::messages.flash />
<x-bs::messages.validation
Validation error summaries.
<x-bs::messages.validation />
<x-bs::messages.error
Field-specific error message.
<x-bs::messages.error field="email" />
Alert & Feedback
<x-bs::alert
Dismissible alert component.
<x-bs::alert type="success" title="Success!"> Your changes have been saved. </x-bs::alert>
Props:
type(string, default:"info") - Alert type (success, danger, warning, info)title(string) - Alert titledismissible(bool, default:true) - Show close button
<x-bs::badge
Badge/label component.
<x-bs::badge variant="primary" pill> New </x-bs::badge>
Props:
variant(string, default:"primary") - Badge colorpill(bool, default:false) - Rounded corners
<x-bs::progress
Progress bar.
<x-bs::progress value="65" max="100" variant="success" striped />
Props:
value(int, default:0) - Current valuemax(int, default:100) - Maximum valuevariant(string, default:"primary") - Colorstriped(bool) - Striped patternanimated(bool) - Animation effectlabel(string) - Custom label
<x-bs::spinner
Loading spinner.
<x-bs::spinner type="border" size="sm" />
Props:
type(string, default:"border") - Type (border, grow)size(string) - Size (sm, lg)label(string) - Accessibility label
Navigation & Layout
<x-bs::breadcrumb
Breadcrumb navigation.
<x-bs::breadcrumb :items="[ ['label' => 'Home', 'url' => route('home')], ['label' => 'Products', 'url' => route('products.index')], ['label' => 'Edit', 'url' => null], ]" />
Props:
items(array) - Breadcrumb items with label and optional url
<x-bs::modal
Bootstrap modal dialog.
<x-bs::modal id="confirmModal" title="Confirm Action" centered> <p>Are you sure?</p> </x-bs::modal>
Props:
id(required) - Modal IDtitle(string) - Modal titlesize(string) - Size (sm, lg, xl)centered(bool) - Center modal verticallyscrollable(bool) - Scrollable content
<x-bs::table
Styled table wrapper.
<x-bs::table :thead="'<tr><th>Name</th><th>Email</th></tr>'"> @foreach($users as $user) <tr> <td>{{ $user->name }}</td> <td>{{ $user->email }}</td> </tr> @endforeach </x-bs::table>
<x-bs::table.actions
Action buttons for table rows.
<x-bs::table.actions viewRoute="{{ route('users.show', $user->id) }}" editRoute="{{ route('users.edit', $user->id) }}" deleteRoute="{{ route('users.destroy', $user->id) }}" />
Props:
viewRoute(string) - View link (optional)editRoute(string) - Edit link (optional)deleteRoute(string) - Delete form action (optional, shows confirmation)
Layout Components
<x-bs::card
Card component for content grouping.
<x-bs::card title="User Information" subtitle="Personal details"> <p>Content goes here</p> </x-bs::card>
Props:
title(string) - Card titlesubtitle(string) - Card subtitlefooter(string) - Footer content
<x-bs::tabs
Tabbed interface with content.
<x-bs::tabs :items="[ [ 'id' => 'tab1', 'label' => 'Tab 1', 'content' => '<p>Content 1</p>', 'active' => true, ], [ 'id' => 'tab2', 'label' => 'Tab 2', 'content' => '<p>Content 2</p>', ], ]" />
Props:
items(array, required) - Tab items with id, label, content, active
<x-bs::accordion
Collapsible accordion component.
<x-bs::accordion id="myAccordion" :items="[ [ 'title' => 'Section 1', 'content' => '<p>Content 1</p>', 'open' => true, ], [ 'title' => 'Section 2', 'content' => '<p>Content 2</p>', ], ]" />
Props:
items(array, required) - Accordion items with title, content, id, openflush(bool, default:false) - Remove borders
<x-bs::collapse
Collapse/expandable section.
<x-bs::collapse title="Show Details"> <p>Detailed content here</p> </x-bs::collapse>
Props:
title(string) - Collapse header textid(string) - Unique ID
<x-bs::dropdown
Dropdown menu component.
<x-bs::dropdown label="Actions" :items="[ ['label' => 'Edit', 'url' => '#edit'], ['label' => 'Delete', 'url' => '#delete'], ['divider' => true], ['label' => 'Settings', 'url' => '#settings'], ]" />
Props:
label(string, required) - Button labelitems(array) - Menu items with label, url, divider, headersplit(bool) - Split dropdown button
<x-bs::list-group
List group component with optional badges.
<x-bs::list-group :items="[ ['id' => '1', 'label' => 'Item 1', 'url' => '#1', 'active' => true], ['id' => '2', 'label' => 'Item 2', 'url' => '#2', 'badge' => 'New'], ]" />
Props:
items(array) - List items with label, url, badge, id, activeflush(bool) - Remove bordersactive(string) - Active item id
<x-bs::navbar
Navigation bar component.
<x-bs::navbar brand="MyApp" :items="[ ['id' => 'home', 'label' => 'Home', 'url' => route('home')], ['id' => 'about', 'label' => 'About', 'url' => route('about')], ]" dark />
Props:
brand(string) - Brand namebrandUrl(string, default:"/") - Brand linkitems(array) - Navigation itemsdark(bool) - Dark themeactive(string) - Active item id
<x-bs::pagination
Paginated results navigation.
<x-bs::pagination :paginator="$users" />
Props:
paginator(LengthAwarePaginator) - Laravel paginator instance
<x-bs::offcanvas
Offcanvas sidebar component.
<x-bs::offcanvas id="sidebar" title="Menu" placement="start"> <p>Sidebar content</p> </x-bs::offcanvas>
Props:
id(required) - Unique IDtitle(string) - Sidebar titleplacement(string, default:"start") - Position (start, end, top, bottom)backdrop(bool, default:true) - Hide on backdrop click
<x-bs::empty-state
Empty state placeholder.
<x-bs::empty-state title="No results"> Try adjusting your search terms </x-bs::empty-state>
Props:
title(string) - Empty state title
<x-bs::skeleton
Loading skeleton placeholder.
<x-bs::skeleton height="100px" count="3" />
Props:
height(string, default:"100px") - Skeleton heightcount(int, default:3) - Number of skeletons
Helpers
CountriesHelper
Utility class for working with country data.
use Bethuxs\BladeBootstrapComponents\CountriesHelper; // Get all countries $countries = CountriesHelper::all(); // Get as select options (iso => name) $options = CountriesHelper::asOptions(); // Get as emoji options $emojiOptions = CountriesHelper::asEmojiOptions(); // Find by ISO code $country = CountriesHelper::findByIso('US'); // Find by emoji $country = CountriesHelper::findByEmoji('πΊπΈ');
Complete Form Example
<x-bs::form method="POST" route="users.store"> <div class="row"> <div class="col-md-6"> <x-bs::form.input name="name" label="Full Name" type="text" required /> </div> <div class="col-md-6"> <x-bs::form.input name="email" label="Email Address" type="email" required /> </div> </div> <div class="row"> <div class="col-md-6"> <x-bs::form.select name="country" label="Country" :options="CountriesHelper::asOptions()" /> </div> <div class="col-md-6"> <x-bs::form.input name="phone" label="Phone Number" type="tel" /> </div> </div> <x-bs::form.textarea name="bio" label="Biography" rows="4" /> <div class="mt-3"> <x-bs::form.button label="Save" type="submit" contextual="success" /> <x-bs::form.button label="Cancel" contextual="secondary" /> </div> </x-bs::form>
Customization
Components follow Bootstrap 5 conventions and accept standard HTML attributes through $attributes. You can override individual components by creating files in your app's resources/views/components/ directory.
Contributing
Contributions are welcome! Please submit pull requests to improve components and documentation.
License
This project is open-sourced software licensed under the MIT license.
Changelog
v1.1.0 (Current)
- β¨ Added Alert component
- β¨ Added Modal component
- β¨ Added Badge component
- β¨ Added Progress component
- β¨ Added Spinner component
- β¨ Added Breadcrumb component
- β¨ Added CountriesHelper utility class
- π Fixed countries component key mapping
- β Added i18n support to all components
- βΏ Improved accessibility (ARIA labels, semantic HTML)
- π Enhanced documentation
Acknowledgments
Built with β€οΈ for the Laravel community. Special thanks to Bootstrap for the amazing CSS framework.