diff --git a/assets/.gitkeep b/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/assets/sample-form-slider.png b/assets/sample-form-slider.png new file mode 100644 index 0000000..851557f Binary files /dev/null and b/assets/sample-form-slider.png differ diff --git a/assets/sample-form.png b/assets/sample-form.png new file mode 100644 index 0000000..aad04ae Binary files /dev/null and b/assets/sample-form.png differ diff --git a/composer.json b/composer.json index 6ff8a36..6481921 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "bastinald/laravel-livewire-forms", + "name": "osoobe/laravel-livewire-forms", "homepage": "https://github.com/bastinald/laravel-livewire-forms", "description": "Laravel Livewire form component with declarative Bootstrap 5 fields and buttons.", "license": "MIT", @@ -11,8 +11,8 @@ } ], "require": { - "laravel/framework": "^8.0", - "livewire/livewire": "^2.0" + "laravel/framework": "^8.0|^9.0|^10.0|^11.0|^12.0", + "livewire/livewire": "^2.0|^3.0" }, "autoload": { "psr-4": { diff --git a/examples.md b/examples.md new file mode 100644 index 0000000..83cf25c --- /dev/null +++ b/examples.md @@ -0,0 +1,82 @@ + +## Examples + + +### FormComponent Example + +```php +namespace App\Http\Livewire\Clients; + +use Bastinald\LaravelLivewireForms\Components\Button; +use Bastinald\LaravelLivewireForms\Components\FormComponent; +use Bastinald\LaravelLivewireForms\Components\Input; +use Bastinald\LaravelLivewireForms\Components\Select; + +class CreateClientForm extends FormComponent +{ + public $gridClass = 'row'; + + public function fields() + { + return [ + Row::make()->fields([ + Input::make('name', 'Name') + ->placeholder('Full Name'), + Input::make('email', 'Email') + ->type('email') + ->placeholder('Email, example: user@example.com'), + Select::make('gender', 'Gender') + ->placeholder('Gender') + ->options(['Male', 'Female']) + ->addAttrs(['class' => 'd-block w-full']), + Input::make('phone_no', 'Contact Number') + ->placeholder('(xxx) xxx xxxxx'), + Input::make('street_address', 'Street Address'), + Input::make('city', 'City'), + Input::make('state', 'State / Parist'), + Input::make('country', 'Country'), + ]) + ]; + } + + public function buttons() + { + return [ + Button::make('Cancel', 'secondary')->url(route('team.index')), + Button::make()->click('submit'), + ]; + } +} +``` + +#### Form View + + + + +### FormSliderComponent Example + +```php +namespace App\Http\Livewire\Clients; + +use Bastinald\LaravelLivewireForms\Components\Button; +use Bastinald\LaravelLivewireForms\Components\FormSliderComponent; +use Bastinald\LaravelLivewireForms\Components\Input; +use Bastinald\LaravelLivewireForms\Components\Select; + +class CreateClientForm extends FormSliderComponent +{ + + public $btnIcon = 'fa fa-user'; + public $btnText = 'Add Client'; + public $gridClass = 'row'; + + ... + +} +``` + + +#### Form Slider View + + diff --git a/readme.md b/readme.md index 5fa23dc..f8b73ce 100644 --- a/readme.md +++ b/readme.md @@ -91,6 +91,27 @@ class Login extends FormComponent ->name('login') ->middleware('guest'); } +} +``` + +## Form Slider + +Create a form that slides out by specifying a `title`, `layout` and `route` to use: + +```php +class Login extends FormSliderComponent +{ + public $title = 'Login'; + public $layout = 'layouts.card'; + public $btnText = 'Login'; + + public function route() + { + return Route::get('/login', static::class) + ->name('login') + ->middleware('guest'); + } +} ``` The `route` method is made available by using my [laravel-livewire-routes](https://github.com/bastinald/laravel-livewire-routes) package. @@ -115,6 +136,7 @@ class UpdateUserForm extends FormComponent { $this->data = $user->toArray(); } +} ``` ## Accessing Data @@ -144,6 +166,7 @@ Input::make('name', 'Name')->lazy(), // bind on change Input::make('name', 'Name')->debounce(500), // bind after 500ms delay ``` + ## Sizing Many fields also allow you to specify a size for the input e.g.: @@ -201,6 +224,26 @@ Arrayable::make('locations', 'Locations')->fields([ Available methods: `fields`, `help`, `disabled` + + +### Bootstrap Grid + +A bootstrap support to the form. + +#### Row `($label = null)` and RowColumn `($label = null)` + +An array of fields display in a Bootstrap Row or Column + +```php +Row::make()->fields([ + Input::make('city')->placeholder('City'), + Select::make('state')->placeholder('State')->options(['FL', 'TX']), +]), +``` + +Available methods: `fields`, `help`, `disabled`, `isColumn`, `col_class` + + ### Button `($label = 'Submit', $style = 'primary')` A button used for actions and links. @@ -227,7 +270,7 @@ Checkbox::make('active', 'This user is active')->switch(), Use the `switch` method to style the checkbox as a switch. -Available methods: `switch`, `help`, `instant`, `defer`, `lazy`, `debounce`, `disabled` +Available methods: `switch`, `help`, `instant`, `addAttrs`, `defer`, `lazy`, `debounce`, `disabled` ### Checkboxes `($name, $label = null)` @@ -237,7 +280,7 @@ An array of checkbox fields. Checkboxes::make('colors', 'Colors')->options(['Red', 'Green', 'Blue']), ``` -Available methods: `options`, `switch`, `help`, `instant`, `defer`, `lazy`, `debounce`, `disabled` +Available methods: `options`, `switch`, `help`, `instant`, `addAttrs`, `defer`, `lazy`, `debounce`, `disabled` ### Color `($name, $label = null)` @@ -247,7 +290,7 @@ A color picker field. Color::make('hair_color', 'Hair Color'), ``` -Available methods: `small`, `large`, `help`, `instant`, `defer`, `lazy`, `debounce`, `disabled`, `readonly` +Available methods: `small`, `large`, `containerSize`, `help`, `instant`, `addAttrs`, `defer`, `lazy`, `debounce`, `disabled`, `readonly` ### Conditional @@ -303,7 +346,7 @@ Input::make('price', 'Price')->type('number')->append('$')->prepend('.00'), The `type` method accepts a standard HTML input type. As with other inputs, use `small` or `large` to resize an input. Input fields also support appends/prepends, and even plaintext. -Available methods: `small`, `large`, `help`, `instant`, `defer`, `lazy`, `debounce`, `disabled`, `readonly`, `placeholder`, `type`, `append`, `prepend`, `plaintext` +Available methods: `small`, `large`, `containerSize`, `help`, `instant`, `addAttrs`, `defer`, `lazy`, `debounce`, `disabled`, `readonly`, `placeholder`, `type`, `append`, `prepend`, `plaintext` ### Radio `($name, $label = null)` @@ -313,7 +356,7 @@ A radio field. Radio::make('gender', 'Gender')->options(['Male', 'Female']), ``` -Available methods: `options`, `switch`, `help`, `instant`, `defer`, `lazy`, `debounce`, `disabled` +Available methods: `options`, `switch`, `help`, `instant`, `addAttrs`, `defer`, `lazy`, `debounce`, `disabled` ### Select `($name, $label = null)` @@ -329,7 +372,7 @@ Select::make('color', 'Color')->options([ Select::make('user_id', 'User')->options(User::pluck('name', 'id')->toArray()), ``` -Available methods: `options`, `small`, `large`, `help`, `instant`, `defer`, `lazy`, `debounce`, `disabled`, `placeholder` +Available methods: `options`, `small`, `large`, `containerSize`, `help`, `instant`, `addAttrs`, `defer`, `lazy`, `debounce`, `disabled`, `placeholder` ### Textarea `($name, $label = null)` @@ -340,7 +383,7 @@ Input::make('bio', 'Biography'), Input::make('bio', 'Biography')->rows(5), ``` -Available methods: `small`, `large`, `help`, `instant`, `defer`, `lazy`, `debounce`, `disabled`, `readonly`, `placeholder`, `rows` +Available methods: `small`, `large`, `containerSize`, `help`, `instant`, `addAttrs`, `defer`, `lazy`, `debounce`, `disabled`, `readonly`, `placeholder`, `rows` ### View `($name, $data = [])` @@ -349,3 +392,63 @@ Used to render a custom Blade view inside the form. ```php View::make('custom-view', ['hello' => 'world']), ``` + + +## Sameple Example + + +### Code + +```php +namespace App\Http\Livewire\Clients; + +use Bastinald\LaravelLivewireForms\Components\Button; +use Bastinald\LaravelLivewireForms\Components\FormComponent; +use Bastinald\LaravelLivewireForms\Components\Input; +use Bastinald\LaravelLivewireForms\Components\Select; + +class CreateClientForm extends FormComponent +{ + public $gridClass = 'row'; + + public function fields() + { + return [ + Row::make()->fields([ + Input::make('name', 'Name') + ->placeholder('Full Name'), + Input::make('email', 'Email') + ->type('email') + ->placeholder('Email, example: user@example.com'), + Select::make('gender', 'Gender') + ->placeholder('Gender') + ->options(['Male', 'Female']) + ->addAttrs(['class' => 'd-block w-full']), + Input::make('phone_no', 'Contact Number') + ->placeholder('(xxx) xxx xxxxx'), + Input::make('street_address', 'Street Address'), + Input::make('city', 'City'), + Input::make('state', 'State / Parist'), + Input::make('country', 'Country'), + ]) + ]; + } + + public function buttons() + { + return [ + Button::make('Cancel', 'secondary')->url(route('team.index')), + Button::make()->click('submit'), + ]; + } +} +``` + +### Form View + + + + +### Other Examples + +For more examples, read the [example.md](examples.md) document. diff --git a/src/Components/FormComponent.php b/src/Components/FormComponent.php index b202c4c..ba5d619 100644 --- a/src/Components/FormComponent.php +++ b/src/Components/FormComponent.php @@ -12,6 +12,13 @@ class FormComponent extends Component public $layout; public $data = []; + /** + * CSS Class for input wrapper. + * + * @var string + */ + public $gridClass = 'row'; + public function render() { return view('laravel-livewire-forms::form-component') diff --git a/src/Components/FormSliderComponent.php b/src/Components/FormSliderComponent.php new file mode 100644 index 0000000..8466fe2 --- /dev/null +++ b/src/Components/FormSliderComponent.php @@ -0,0 +1,33 @@ +sliderActive = ! $this->sliderActive; + } + + public function showSlider() { + $this->sliderActive = true; + } + + public function hideSlider() { + $this->sliderActive = false; + } + + public function render() + { + return view('laravel-livewire-forms::form-slider-component') + ->layout($this->layout ?? config('livewire.layout')); + } + +} + +?> diff --git a/src/Components/ModalFormComponent.php b/src/Components/ModalFormComponent.php new file mode 100644 index 0000000..c093a8f --- /dev/null +++ b/src/Components/ModalFormComponent.php @@ -0,0 +1,48 @@ +modalFormVisible = true; + } + + public function buttons() + { + return [ + Button::make('Cancel', 'dark')->click('$toggle("modalFormVisible")'), + Button::make()->click('submit'), + ]; + } + + public function submit() + { + $this->data = []; + $this->modalFormVisible = false; + + } + + public function render() + { + return view('laravel-livewire-forms::modal-form-component') + ->layout($this->layout ?? config('livewire.layout')); + } +} diff --git a/src/Components/Row.php b/src/Components/Row.php new file mode 100644 index 0000000..e743c96 --- /dev/null +++ b/src/Components/Row.php @@ -0,0 +1,60 @@ +props = [ + // 'name' => $name, + 'label' => $label, + 'fields' => [], + 'help' => null, + ]; + + $component->attrs = [ + 'disabled' => false, + ]; + + return $component; + } + + public function fields($fields = []) + { + $this->props['fields'] = $fields; + + return $this; + } + + public function isColumn($field) { + return Column::class == get_class($field); + } + + public function col_size($col="mb-2") { + $this->column_class = "$col mb-2 mb-md-0"; + return $this; + } + + public function render() + { + $row = $this; + return view('laravel-livewire-forms::row', compact('row')); + } +} diff --git a/src/Components/RowColumn.php b/src/Components/RowColumn.php new file mode 100644 index 0000000..321b37f --- /dev/null +++ b/src/Components/RowColumn.php @@ -0,0 +1,53 @@ +props = [ + // 'name' => $name, + // 'label' => $label, + 'fields' => [], + 'help' => null, + ]; + + $component->attrs = [ + 'disabled' => false, + ]; + + return $component; + } + + public function col_size($col="mb-2") { + $this->column_class = "$col mb-2 mb-md-0"; + return $this; + } + + public function fields($fields = []) + { + $this->props['fields'] = $fields; + + return $this; + } + + public function render() + { + return view('laravel-livewire-forms::column'); + } +} diff --git a/src/Traits/WithModel.php b/src/Traits/WithModel.php index 9719d8a..130e69b 100644 --- a/src/Traits/WithModel.php +++ b/src/Traits/WithModel.php @@ -2,6 +2,8 @@ namespace Bastinald\LaravelLivewireForms\Traits; +use Illuminate\Support\Arr; + trait WithModel { public function instant() @@ -31,4 +33,16 @@ public function debounce($ms = 500) return $this; } + + /** + * Add attributes to the input field. + * + * @return mixed|Illuminate\View\Component Return the current object. + */ + public function addAttrs(array $attrs) { + if (Arr::isAssoc($attrs)) { + $this->attrs = array_merge($this->attrs, $attrs); + } + return $this; + } } diff --git a/src/Traits/WithPrefix.php b/src/Traits/WithPrefix.php index 61e59bd..a8ebb8c 100644 --- a/src/Traits/WithPrefix.php +++ b/src/Traits/WithPrefix.php @@ -6,7 +6,9 @@ trait WithPrefix { public function prefix($prefix) { - $this->props['prefix'] = $prefix . '.'; + if ( !empty($prefix)) { + $this->props['prefix'] = $prefix . '.'; + } return $this; } diff --git a/src/Traits/WithSizing.php b/src/Traits/WithSizing.php index 8637aba..9ab27b7 100644 --- a/src/Traits/WithSizing.php +++ b/src/Traits/WithSizing.php @@ -4,17 +4,33 @@ trait WithSizing { - public function small() - { - $this->props['small'] = true; + /** + * CSS Class for input wrapper. + * + * @var string + */ + public $gridClass = 'd-block w-full'; + protected $colClasses = "col-md-6"; + public function setColClass($classes="") { + $this->colClasses = $classes; return $this; } - public function large() - { - $this->props['large'] = true; + public function getColClass() { + return $this->colClasses; + } + /** + * Set CSS Class for input wrapper. + * + * @param string $classes + * @return mixed|Illuminate\View\Component Return the current object. + */ + public function containerSize($classes='d-block w-full') { + $this->gridClass = $classes; return $this; } + + } diff --git a/views/arrayable.blade.php b/views/arrayable.blade.php index 91dc244..52b62d5 100644 --- a/views/arrayable.blade.php +++ b/views/arrayable.blade.php @@ -20,8 +20,9 @@ @endforeach