Install the package via composer:
composer require nh/bs-component
Add this to your packages.json
"axios": "^1.1.2",
"@popperjs/core": "^2.6.0",
"bootstrap" : "^5.2.0",
"flatpickr" : "^4.6.7",
"@tiptap/core": "*",
"@tiptap/starter-kit": "*",
"@tiptap/extension-text-style": "*",
"@tiptap/extension-underline": "*",
"@tiptap/extension-link": "*",
"@tiptap/extension-table": "*",
"@tiptap/extension-table-cell": "*",
"@tiptap/extension-table-header": "*",
"@tiptap/extension-table-row": "*",
Publish the config
php artisan vendor:publish --tag=bs-component
Javascript to include
import '../../vendor/nh/bs-component/resources/js/bs-component';
SASS to include
@import '../../vendor/nh/bs-component/resources/scss/bs-component';
Available components:
- Alert
- Blockquote
- Breadcrumb
- Card
- Figure
- Loading (Spinner)
- Modal
- Modal Confirm
- Progress
- Toast
- Check (checkbox, radio or switch)
- Checklist (list of checkbox or radio)
- Datepicker
- Dynamic input
- Editor
- Input
- Input file
- Select
- Datalist
- Textarea
- Color
- Calendar
Available JS:
- Datepicker (Flatpickr)
- Editor (TipTap)
- Checkbox all
- Toggle switch
- Toggle select
- Autocomplete
- Table link
Attribute | Type | Default |
---|---|---|
color | string | primary |
closable | boolean | false |
<x-bs-alert color="success" closable>
Hey this is an alert !
</x-bs-alert>
Attribute | Type | Default |
---|---|---|
source | string | null |
align | string | start |
<x-bs-blockquote source="Natacha Herth" align="right">
Hey this a blockquote !
</x-bs-blockquote>
Attribute | Type | Default |
---|---|---|
items | array | null |
The keys in array are used to display the link text and the values are used for the href. The values can be an url or a route name.
<x-bs-breadcrumb :items="['First' => 'home', 'Seconde' => '#','Third' => null,'Fourth' => '#']"/>
Attribute | Type | Default |
---|---|---|
title | string | null |
footer | string | null |
The title and the footer can also be set as slot.
<x-bs-card title="My card title" footer="My card footer">
<x-slot name="before">
Before the card body.
</x-slot>
Hey this a card !
<x-slot name="after">
After the card body.
</x-slot>
</x-bs-card>
Attribute | Type | Default |
---|---|---|
caption | string | null |
align | string | start |
The align is for the caption.
<x-bs-figure caption="My caption" align="right">
<img src="https://fakeimg.pl/250x100/cccccc/">
</x-bs-figure>
Attribute | Type | Default |
---|---|---|
type | string | border |
color | string | primary |
title | string | Loading... |
size | string | md |
The default title is the 'bs-component::button.loading' translation.
<x-bs-loading type="grow" color="success" title="Custom loading text" size="sm"/>
Attribute | Type | Default |
---|---|---|
title | string | null |
footer | string | null |
size | string | md |
closable | boolean | false |
centered | boolean | false |
scrollable | boolean | false |
is-static | boolean | false |
fullscreen | boolean | false |
fullscreen-size | string | null |
<x-bs-modal id="myModal" title="My modal" footer="The footer of the modal" size="sm" closable centered scrollable is-static fullscreen fullscreen-size="md">
Hey this a modal !
</x-bs-modal>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#myModal">
Launch modal
</button>
You can load by axios the content of the modal:
Require
- JS:
import ModalLoad from '../../vendor/nh/bs-component/resources/js/_modal-load';
<x-bs-modal id="myModalLoad" class="modal-load"></x-bs-modal>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#myModalLoad" data-action="my-url-where-to-load">
Launch modal
</button>
Attribute | Type | Default |
---|---|---|
color | string | primary |
icon | string | null |
title | string | null |
action | string | # |
method | string | POST |
footer | string | null |
size | string | md |
centered | boolean | false |
scrollable | boolean | false |
fullscreen | boolean | false |
fullscreen-size | string | null |
with-file | boolean | false |
btn-cancel | array | [] |
btn-confirm | array | [] |
Require
- JS:
import ModalConfirm from '../../vendor/nh/bs-component/resources/js/_modal-confirm';
- SASS:
@import '../../vendor/nh/bs-component/resources/scss/modal-confirm';
The action can be overide by the data-action attribute in the link
<x-bs-modal-confirm id="myModalConfirm" color="danger" icon="icon-trash" title="My modal confirm" action="default.action" method="DELETE" size="md" centered >
<p>Hey this a modal for confirmation !</p>
</x-bs-modal>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#myModalConfirm" data-action="custom.action">
Launch modal confirm
</button>
You can globaly customize the buttons in the 'bs-component' config file. Or you can set an array with the custom values (class,label,value) for each button.
<x-bs-modal-confirm :btnConfirm="['class' => 'btn-success','label' => 'my.translation.path','value' => '<i class=icon-checkmark></i>']">
Hey this a modal for confirmation !
</x-bs-modal>
Attribute | Type | Default |
---|---|---|
color | string | primary |
value | int | 0 |
min | int | 0 |
max | int | 0 |
caption | string | null |
stripped | boolean | false |
animated | boolean | false |
<x-bs-progress color="success" value="25" min="0" max="100" caption="You got 25" stripped animated/>
Attribute | Type | Default |
---|---|---|
title | string | null |
time | string | null |
img | string | null |
closable | boolean | false |
autohide | boolean | false |
delay | int | 10000 |
<x-bs-toast class="show" title="My toast" time="11 min ago" img="https://fakeimg.pl/20x20/007bff/fff" closable autohide delay="100">
Hey this is a toast !
</x-bs-toast>
<x-bs-toast class="show" time="11 min ago" img="https://fakeimg.pl/20x20/007bff/fff" closable autohide delay="100">
Hey this is a toast !
</x-bs-toast>
Display a calendar with events that are loaded per month
Attribute | Type | Default |
---|---|---|
color | string | null |
events-load-url | string | null |
Require
- JS:
import Calendar from '../../vendor/nh/bs-component/resources/js/_calendar';
- SASS:
@import '../../vendor/nh/bs-component/resources/scss/calendar';
<x-bs-calendar class="calendar-automatic" color="success" :events-load-url="route('my-route-to-load-events-per-month')" />
In the controller you must return a JSON with the events:
/**
* Get the events for the calendar
*
* @param \Illuminate\Http\Request $request
* @return Illuminate\Database\Eloquent\Collection
*/
public function loadEventPerMonth(Request $request)
{
// Define the events for the month
$events[] = [
'title' => 'My event',
'content' => 'The description',
'color' => 'primary',
'days' => [14,15,16]
];
$events[] = [
'title' => 'Another event',
'content' => 'The description',
'color' => 'danger',
'days' => [28]
];
// Retune the JSON
return $events;
}
This is an exemple for add JS interaction on days and events:
new Calendar(document.querySelector('.calendar-automatic),{
onDayCreated: function(object,date){
object.addEventListener('click', function(e){
// Do something when day is created (For exemple add a modal interaction on click on the day)
// Check if there is any event : this.classList.contains('day-with-events')
});
},
onEventCreated: function(object,event){
// Do something when event is created (For exemple add a popover interaction on the event)
new Bootstrap.Popover(object,{
trigger: 'hover',
content: object.getAttribute('data-content'),
html: true
})
},
});
All the component manage the request old() value and the validation.
Here the default attributes:
Attribute | Type | Default |
---|---|---|
label | string | null |
name | string | null |
value | string | null |
help | string | null |
required | boolean | false |
disabled | boolean | false |
readonly | boolean | false |
before | string | null |
after | string | null |
errorRelated | string | null |
errorBag | string | null |
autocomplete | boolean | false |
You can enable the browser autocomplete only for the datalist, input and datepicker
Attribute | Type | Default |
---|---|---|
type | string | checkbox |
value | string | 1 |
checked | boolean | false |
boolean | boolean | false |
If the boolean option is set to true, a hidden input with the value opposite value is created.
<x-bs-check label="Boolean checkbox" type="checkbox" name="boolean" boolean required/>
<x-bs-check class="form-switch" label="Boolean switch" type="checkbox" name="switch" boolean />
<x-bs-check label="My check one" type="checkbox" name="checkbox[]" value="one" help="Help message." checked />
<x-bs-check label="My check two" type="checkbox" name="checkbox[]" value="two"/>
<x-bs-check label="My check three" type="checkbox" name="checkbox[]" value="three" disabled />
<x-bs-check label="My radio one" type="radio" name="radio" value="one" help="Help message." checked />
<x-bs-check label="My radio two" type="radio" name="radio" value="two" />
<x-bs-check label="My radio three" type="radio" name="radio" value="three" help="Help message." disabled />
Attribute | Type | Default | Option |
---|---|---|---|
disabled | mixed | false | boolean/array |
type | string | checkbox | checkbox/radio |
options | array | [] | |
checked | mixed | [] | string/array |
inline | boolean | false |
<x-bs-check-list label="My label" type="checkbox" name="checkbox_list[]" :options="[1 => 'one', 2 => 'two', 3 => 'three']" help="Help message" :checked="[2]" :disabled="[3]" required />
<x-bs-check-list label="My label" type="radio" name="radio_list[]" :options="[1 => 'one', 2 => 'two', 3 => 'three']" help="Help message" :checked="[2]" :disabled="[3]" required />
<x-bs-check-list label="My label" type="checkbox" name="checkbox_list_inline[]" :options="[1 => 'one', 2 => 'two', 3 => 'three']" help="Help message" inline />
<x-bs-check-list label="My label" type="radio" name="radio_list_inline[]" :options="[1 => 'one', 2 => 'two', 3 => 'three']" help="Help message" inline />
Attribute | Type | Default | Option |
---|---|---|---|
type | string | text | text/number/phone/email/password |
placeholder | string | null | |
size | string | null | |
step | float | 1 | |
min | float | null | |
max | float | null |
The step, min and max are only for input of type number.
<x-bs-input label="My input" type="text" name="myinput" value="Default value" placeholder="My placeholder" help="Help message" size="lg" readonly disabled required />
<x-bs-input label="My input" type="text" name="myinput" before="A" after="B" />
Attribute | Type | Default |
---|---|---|
size | string | null |
multiple | boolean | false |
<x-bs-input-file label="My input file" name="myinput" help="Help message" />
<x-bs-input-file label="My input file multiple" name="myinput" help="Help message" multiple/>
<x-bs-input-file label="My input file" name="myinput" help="Help message" size="lg" disabled required />
<x-bs-input-file label="My input file" name="myinput" before="A" after="B" />
Attribute | Type | Default | Option |
---|---|---|---|
disabled | mixed | false | boolean/array |
readonly | boolean | false | |
options | array | [] | |
size | string | null | |
selected | mixed | [] | string/array |
multiple | boolean | false |
You can pass a multi-level array for make optgroup: 'Label' => [1 => 'Name'] If the select is readonly, the value(s) will be set in hidden field(s)
<x-bs-select label="My label" name="myinput" :options="[1 => 'one', 2 => 'two']" help="Help message" size="lg" :selected="[2]" multiple disabled required />
<x-bs-select label="My label" name="myinput" :options="[1 => 'one', 2 => 'two']" before="A" after="B" />
Attribute | Type | Default |
---|---|---|
placeholder | string | null |
options | array | [] |
size | string | null |
with-hidden | boolean | false |
hidden-name | string | id |
hidden-field | string | null |
You can add an hidden input with custom name and value. To activate the functionality you have to add the class .datalist. You can transform a datalist to an autocomplete: Check the JS section for more information
Require
- JS:
import Datalist from '../../vendor/nh/bs-component/resources/js/_datalist';
<x-bs-datalist label="My label" name="myinput" value="Default value" placeholder="My placeholder" :options="[1 => 'one', 2 => 'two']" help="Help message" size="lg" readonly disabled required />
<x-bs-datalist label="My label" name="myinput" :options="[1 => 'one', 2 => 'two']" before="A" after="B" />
<x-bs-datalist class="datalist" label="My label" name="myinput" :options="[1 => 'one', 2 => 'two']" value="one" with-hidden hidden-name="hiddenid" hidden-value="1" />
Attribute | Type | Default |
---|---|---|
placeholder | string | null |
<x-bs-textarea label="My label" name="mytextarea" value="Default value" placeholder="My placeholder" help="Help message" readonly disabled required />
<x-bs-textarea label="My label" name="mytextarea" before="A" after="B" />
Attribute | Type | Default |
---|---|---|
options | array | [] |
<x-bs-color label="Choose a color" name="color" :options="['primary' => 'Primary','secondary' => 'Secondary','success' => 'Success']" help="Help message" required disabled />
To use the datepicker you need to install the JS plugin Flatpickr !
Attribute | Type | Default | Option |
---|---|---|---|
placeholder | string | null | |
size | string | null | |
mode | string | single | single/multiple/range |
format | string | datetime | datetime/datetime-short/date/time/time-short/db-datetime/db-date/db-time |
min | string | null | can be a date or the name of an input |
max | string | null | can be a date or the name of an input |
inline | boolean | false | |
static | boolean | false | |
input-from | string | null | |
input-to | string | null | |
disabled-dates | array | [] | |
events | array | [] |
You can set a min/max date or define by another input name. For range you can add 2 hidden input to set the from/to values You can set the disabled dates with an array, exemple ['2021-01-05','2021-05-11'] You can set some events dates with an array, exemple ['2021-01-05' => ['color' => 'danger'] ,'2021-05-11' => ['color' => 'warning']] Set static to true if the datepicker is in a parent with relative position
Require
- JS:
import Datepicker from '../../vendor/nh/bs-component/resources/js/_datepicker';
- SASS:
@import '../../vendor/nh/bs-component/resources/scss/datepicker';
<x-bs-datepicker class="datepicker-automatic" label="Start date" name="startInputName" value="2020-05-04" placeholder="Select a date" help="Help message" size="lg" readonly disabled required mode="single" format="datetime" min="2020-05-01" max="2020-05-30"/>
<x-bs-datepicker class="datepicker-automatic" label="End date" name="endInputName" mode="single" format="datetime" min="startInputName" />
<x-bs-datepicker class="datepicker-automatic" label="End date" name="range" mode="range" format="datetime" input-from="start_at" input-to="end_at"/>
With this component you can add/remove input to add multiple field in your form !
Attribute | Type | Default |
---|---|---|
legend | string | |
listing | string | null |
template | string | null |
min | int | null |
max | int | null |
name | string | dynamic |
type | string | dynamic |
sortable | boolean | false |
items | array | [] |
defaults | array | [] |
itemsDisabled | array | [] |
help | string | null |
btnConfig | string | bs-component.dynamic.buttons |
before | string | null |
after | string | null |
The legend is required. The listing and template are path to some includes views. The Drag&Drop is NOT initialize, you have to add the JS for that functionnality
Require
- JS:
import Dynamic from '../../vendor/nh/bs-component/resources/js/_dynamic';
- SASS:
@import '../../vendor/nh/bs-component/resources/scss/dynamic';
<x-bs-dynamic class="dynamic-automatic" legend="My dynamic field" listing="default.view.listing" template="default.view.template" min="1" max="5" name="mydynamic" type="mytype" sortable :items="[]" help="Help message" />
In the template view you have access to the $default; In the listing view you have acces to the $item
###Customization:
You can globaly customize the buttons in the 'bs-component' config file or you can specify a custom config file/array to use.
<x-bs-dynamic class="dynamic-automatic" legend="My custom dynamic" btnConfig="my.custom.config.file"/>
To use the editor you need to install the JS plugin TipTap !
Attribute | Type | Default | Available |
---|---|---|---|
label | string | null | |
name | string | null | |
value | string | null | |
help | string | null | |
required | boolean | false | |
toolbar | string | font|div|format|list|link|color| | font|format|list|link|color|table|emoji |
headings | string | 1|2|3 | 1|2|3|4|5|6 |
paragraphs | string | lead | free to add any class |
divs | string | blockquote | free to add any class |
formats | string | bold|italic|underline|strike | |
colors | string | primary|success|warning|danger | free to add any class |
emojis | string | bi-emoji-smile|bi-emoji-neutral|bi-emoji-frown|bi-emoji-heart-eyes|bi-emoji-wink|bi-hand-thumbs-up|bi-hand-thumbs-down | free to add any class |
error | string | null | |
errorBag | string | null |
The name is required. The colors classes will start by .text- The emojis will have a .emoji class
For global customization of the options, you can update the config file in config.bs-component.editor
If you want to remove the headings for one editor type :headings="false"
Require
- JS:
import Editor from '../../vendor/nh/bs-component/resources/js/_editor';
- SASS:
@import '../../vendor/nh/bs-component/resources/scss/editor';
<x-bs-editor label="My editor" name="editor" value="Default text" help="Help message" required toolbar="font|format|list|link|color|table" headings="1|2|3|4|5|6" paragraphs="lead|my-class" divs="blockquote|highlight" formats="bold|italic|underline|strike" colors="primary|success|warning|danger"/>
If you add some paragraphs and divs you can create a language file editor.php to display the name of your items.
For the emojis you can use the Bootstrap icon:
npm i bootstrap-icons
If you need a checkbox to check all his children:
<x-bs-check class="checkbox-all" label="Check them all" name="checkboxAll[]" value="my-children"/>
<x-bs-check class="checkbox-my-children" label="AAA" name="children[]" value="AAA"/>
<x-bs-check class="checkbox-my-children" label="BBB" name="children[]" value="BBB"/>
<x-bs-check class="checkbox-my-children" label="CCC" name="children[]" value="CCC"/>
The parent checkbox need the class checkbox-all and the value xxx The children checkbox need the class checkbox-xxx
Require
- JS:
import ToggleSwitch from '../../vendor/nh/bs-component/resources/js/_toggle-switch';
If you need a checkbox to show/hide some classes:
<div>
<x-bs-check class="form-switch toggle-switch" label="Toggle" type="checkbox" name="toggle" value="1" boolean/>
<div class="toggle-switch-false">
Display this div if toggle IS NOT checked
</div>
<div class="toggle-switch-true">
Display this div if toggle IS checked
</div>
</div>
The toggle switch and div to hide/show should be wrap in a parent div
Require
- JS:
import ToggleSelect from '../../vendor/nh/bs-component/resources/js/_toggle-select';
If you need a select to toggle some elements:
<div>
<x-bs-select class="mySelect toggle-select" label="Toggle" name="toggle" :options="['aaa' => 'Aaa','bbb'=> 'Bbb']" />
<div class="toggle-select-aaa">
Display this div if select option is Aaa
</div>
<div class="toggle-select-bbb">
Display this div if select option is Bbb
</div>
</div>
The toggle switch and div to hide/show should be wrap in a parent div
You can also toggle elements via the group label:
<div>
<x-bs-select id="customToggleSelect" class="mySelect" label="Toggle" name="toggle" :options="['first' => ['a' => 'A','b' => 'B'],'second'=> ['c' => 'C','d' => 'D']]" />
<div class="toggle-select-first">
Display this div if select option group is first
</div>
<div class="toggle-select-second">
Display this div if select option group is second
</div>
</div>
var myCustomSelect = new ToggleSelect(document.querySelector('#customToggleSelect'),{
field: 'group', // Otherwise set to 'option'
resetFormWhenHidden: true, // Make form fields as null when hidden
disabledFormWhenHidden : true, // Make form fields disabled in case you need to not send the fields to not send the fields when they are hidden
onChanged : function(e){}
});
Require
- JS:
import ToggleSelect from '../../vendor/nh/bs-component/resources/js/_toggle-select';
var selectField = document.getElementById('mySelect');
var myToggleSelect = new ToggleSelect(selectField, {
field : 'option',
parent : selectField.parentNode.parentNode,
changeOnInit : true, // Make a change() on the init
withDisabled : false, // Make fields (select, inputs and co) disabled in case you need to not send the fields when they are hidden
onChanged : function(e){},
});
field could be option or group, depend if you want to trigger by simple option or by option group parent determine where to look for div to hide/show
If you need an autocomplete datalist:
Require
- JS:
import Autocomplete from '../../vendor/nh/bs-component/resources/js/_autocomplete';
HTML:
<div>
<x-bs-datalist class="autocomplete mycustomautocomplete" label="My autocomplete" name="myautocomplete" with-hidden hidden-name="id" data-url="my_url_for_autocomplete" data-field="name" data-hidden-field="id"/>
<x-bs-input label="Hidden field" name="hiddenField" />
<x-bs-input label="Other field" name="otherField" />
</div>
<datalist id="myCustomDatalist"></datalist>
JS:
Option | Type | Default | Informations |
---|---|---|---|
url | string | el.getAttribute('data-url') | Url for the axio request (POST) |
field | string | el.getAttribute('data-field') | Field to use for the options value and input |
datalist | HTML | el.querySelector('datalist') | The datalist object |
hidden.input | HTML | el.querySelector('.input-hidden') | Input hidden to fill when option is selected |
hidden.field | string | el.getAttribute('data-hidden-field') | Field to use for the hidden input value |
onChanged | function | function(e){} | Callback function |
The url must return a JSON list You can set the data-url data-field and data-hidden-field over the js option
var autocompletes = document.querySelectorAll('.mycustomautocomplete');
Array.prototype.forEach.call(autocompletes, function(el, i) {
var autocomplete = new Autocomplete(el,{
url: 'myurlstring',
field: 'name',
datalist: document.querySelector('#myCustomDatalist'),
hidden: {
input: el.parentNode.querySelector('input[name="hiddenField"]'),
field: 'id'
},
onChanged: function(option){
el.parentNode.querySelector('input[name="otherField"]').value = option ? option.price : '';
}
});
});
In this exemple the #myCustomDatalist datalist options will be contruct via the url request. Exemple of datas items: { id: 1, name: 'My item', 'price': 10.00}
When the user will select an option, the Hidden field will be set with the id and the Other field will be set with the price of the JSON item.
If you need to make a row of a table as a link:
Require
- JS:
import TableLink from '../../vendor/nh/bs-component/resources/js/_table-link';
HTML:
<table id="myTableLink" class="table table-link">
<thead>
<tr>
<th>Title</th>
<th>Disabled</th>
</tr>
</thead>
<tbody>
<tr data-url="my-custom-url">
<td>My title</td>
<td class="table-link-disable">Disabled</td>
</tr>
</tbody>
</table>
By default the class .table-link make a new TableLink. But you can customize it in JS:
var table = document.getElementById('#myTableLink');
var myTable = new TableLink(table);
The tablelink will be automatic on table with class .table-link
If you need to make a row with children and contract/expand them:
Require
- JS:
import TableTree from '../../vendor/nh/bs-component/resources/js/_table-tree';
HTML:
<table id="myTableTree" class="table table-tree">
<thead>
<tr>
<th></th> <!-- For arrow -->
<th>Title</th>
</tr>
</thead>
<tbody>
<tr data-id="1" data-lvl="0" data-parent="0">
<td class="toggle-children"><i class="icon-chevron-right"></i></td>
<td>My title</td>
</tr>
<tr class="collapse" data-id="2" data-lvl="1" data-parent="1">
<td class="toggle-children"><i class="icon-chevron-right"></i></td>
<td>My children title</td>
</tr>
<tr class="collapse" data-id="3" data-lvl="1" data-parent="1">
<td class="toggle-children"><i class="icon-chevron-right"></i></td>
<td>My other children title</td>
</tr>
</tbody>
</table>
By default the class .table-link make a new TableLink. But you can customize it in JS:
var table = document.getElementById('#myTableLink');
var myTable = new TableLink(table);
The tablelink will be automatic on table with class .table-link