diff --git a/demo/app/Sharp/Posts/PostForm.php b/demo/app/Sharp/Posts/PostForm.php index a3fa24b09..1b51b8f5a 100644 --- a/demo/app/Sharp/Posts/PostForm.php +++ b/demo/app/Sharp/Posts/PostForm.php @@ -171,7 +171,7 @@ public function buildFormLayout(FormLayout $formLayout): void ->withFields('published_at', 'categories') ->withField('cover') ->withListField('attachments', function (FormLayoutColumn $item) { - $item->withFields('title|8', 'is_link|4') + $item->withFields(title: 8, is_link: 4) ->withField('link_url') ->withField('document'); }); diff --git a/demo/app/Sharp/Posts/PostShow.php b/demo/app/Sharp/Posts/PostShow.php index 6082f94c7..f7b90d411 100644 --- a/demo/app/Sharp/Posts/PostShow.php +++ b/demo/app/Sharp/Posts/PostShow.php @@ -75,10 +75,10 @@ protected function buildShowLayout(ShowLayout $showLayout): void $section ->addColumn(7, function (ShowLayoutColumn $column) { $column - ->withField('categories') - ->withField('author') + ->withFields(categories: 5, author: 7) ->withListField('attachments', function (ShowLayoutColumn $item) { - $item->withField('title')->withField('link_url') + $item->withField('title') + ->withField('link_url') ->withField('document'); }); }) diff --git a/docs/guide/building-form.md b/docs/guide/building-form.md index a70901ed7..29ebb165d 100644 --- a/docs/guide/building-form.md +++ b/docs/guide/building-form.md @@ -148,7 +148,7 @@ class ProductForm extends SharpForm ##### Displaying fields on the same row -One final way is to put fields side by side on the same column: +Here’s how to put fields side by side on the same row, using the `withFields()` (notice the final S) method: ```php class ProductForm extends SharpForm @@ -164,27 +164,38 @@ class ProductForm extends SharpForm } ``` -This will align the two fields on the row. They'll have the same width (50%), but we can act on this adding a special suffix: +This will align the two fields on the row. They'll have the same width (50%), but we can act on this referencing a 12-based grid system with either variadic arguments: ```php -$column->withFields('name|8', 'capacity|4'); +class ProductForm extends SharpForm +{ + // ... + + public function buildFormLayout(FormLayout $formLayout): void + { + $formLayout->addColumn(6, function (FormLayoutColumn $column) { + $column->withFields(name: 8, capacity: 4); + }); + } +} ``` -Once again, it's a 12-based grid, so `name` will take 2/3 of the width, and `capacity` 1/3. - -##### A word on small screens - -Columns are only used in medium to large screens (768 pixels and up). - -Same for fields put on the same row: on smaller screens, they'll be placed on different rows, except if another layout is intentionally configured, using this convention: +... or using the special `|` character instead: ```php -$column->withFields('name|8,6', 'capacity|4,6'); +class ProductForm extends SharpForm +{ + // ... + + public function buildFormLayout(FormLayout $formLayout): void + { + $formLayout->addColumn(6, function (FormLayoutColumn $column) { + $column->withFields('name|8', 'capacity|4'); + }); + } +} ``` -Here, `name` will take 8/12 of the width on large screens, and 6/12 on smaller one. - - #### Fieldsets Fieldsets are useful to group some fields in a labelled block. Here's how they work: diff --git a/src/Form/Layout/HasFieldRows.php b/src/Form/Layout/HasFieldRows.php index bd1991dba..4e797dad9 100644 --- a/src/Form/Layout/HasFieldRows.php +++ b/src/Form/Layout/HasFieldRows.php @@ -4,6 +4,7 @@ use Closure; use Code16\Sharp\Utils\Layout\LayoutField; +use Illuminate\Support\Collection; use Illuminate\Support\Traits\Conditionable; trait HasFieldRows @@ -25,7 +26,7 @@ public function withSingleField(string $fieldKey, ?\Closure $subLayoutCallback = public function withField(string $fieldKey): self { $this->addRowLayout([ - $this->newLayoutField($fieldKey), + $this->newLayoutField($this->normalizedFieldsRow([$fieldKey])->first()), ]); return $this; @@ -40,11 +41,11 @@ public function withListField(string $fieldKey, Closure $subLayoutCallback): sel return $this; } - public function withFields(string ...$fieldKeys): self + public function withFields(string|int ...$fieldKeys): self { $this ->addRowLayout( - collect($fieldKeys) + $this->normalizedFieldsRow($fieldKeys) ->map(fn ($key) => $this->newLayoutField($key)) ->all(), ); @@ -65,7 +66,7 @@ public function insertFieldsAt(int $index, string ...$fieldKeys): self { $rows = collect($this->rows); $rows->splice($index, 0, [ - collect($fieldKeys) + $this->normalizedFieldsRow($fieldKeys) ->map(fn ($key) => $this->newLayoutField($key)) ->all(), ]); @@ -97,8 +98,32 @@ public function hasFields(): bool ->firstWhere(fn ($row) => count($row) > 0) !== null; } - protected function newLayoutField(string $fieldKey, ?\Closure $subLayoutCallback = null): LayoutField + protected function newLayoutField(string|array $fieldKey, ?\Closure $subLayoutCallback = null): LayoutField { return new FormLayoutField($fieldKey, $subLayoutCallback); } + + private function normalizedFieldsRow(array $fieldKeys): Collection + { + return collect($fieldKeys) + ->map(function ($value, $key) use ($fieldKeys) { + if (! is_string($key)) { + // ['name'] or ['name|6'] cases + return strpos($value, '|') + ? collect(explode('|', $value)) + ->map(fn ($v, $k) => $k == 1 ? (int) $v : $v) + ->all() + : [$value, match (count($fieldKeys)) { + 2 => 6, + 3 => 4, + 4 => 3, + 6 => 2, + default => 12, + }]; + } + + return [$key, $value]; + }) + ->values(); + } } diff --git a/src/Show/Layout/ShowLayoutColumn.php b/src/Show/Layout/ShowLayoutColumn.php index cdfb90e36..310b6323d 100644 --- a/src/Show/Layout/ShowLayoutColumn.php +++ b/src/Show/Layout/ShowLayoutColumn.php @@ -8,12 +8,7 @@ class ShowLayoutColumn extends LayoutColumn implements HasLayout { - /** - * Override HasLayout::newLayoutField. - * - * @return \Code16\Sharp\Form\Layout\FormLayoutField|ShowLayoutField - */ - protected function newLayoutField(string $fieldKey, ?\Closure $subLayoutCallback = null): LayoutField + protected function newLayoutField(string|array $fieldKey, ?\Closure $subLayoutCallback = null): LayoutField { return new ShowLayoutField($fieldKey, $subLayoutCallback); } diff --git a/src/Utils/Layout/LayoutField.php b/src/Utils/Layout/LayoutField.php index 9e940c693..75c951c04 100644 --- a/src/Utils/Layout/LayoutField.php +++ b/src/Utils/Layout/LayoutField.php @@ -7,25 +7,23 @@ abstract class LayoutField { protected string $fieldKey; - protected int $size = 12; - protected int $sizeXS = 12; + protected ?int $size = null; protected array $itemLayout = []; - public function __construct(string $fieldKey, ?Closure $subLayoutCallback = null) + public function __construct(string|array $fieldKey, ?Closure $subLayoutCallback = null) { - if (strpos($fieldKey, '|')) { - [$this->fieldKey, $sizes] = explode('|', $fieldKey); - - if (strpos($fieldKey, ',')) { - [$this->size, $this->sizeXS] = collect(explode(',', $sizes)) - ->map(fn ($size) => (int) $size); - } else { - $this->size = (int) $sizes; - } + $size = null; + + if (is_array($fieldKey)) { + [$this->fieldKey, $size] = $fieldKey; + } elseif (strpos($fieldKey, '|')) { + [$this->fieldKey, $size] = explode('|', $fieldKey); } else { $this->fieldKey = $fieldKey; } + $this->size = $size ? (int) $size : null; + if ($subLayoutCallback) { $itemFormLayout = $this->getLayoutColumn(); $subLayoutCallback($itemFormLayout); @@ -40,7 +38,7 @@ public function toArray(): array return array_merge( [ 'key' => $this->fieldKey, - 'size' => $this->size, + 'size' => $this->size ?: 12, ], $this->itemLayout ? ['item' => $this->itemLayout] diff --git a/tests/Unit/Form/Layout/FormLayoutColumnTest.php b/tests/Unit/Form/Layout/FormLayoutColumnTest.php index 61b0c565e..5a1880f09 100644 --- a/tests/Unit/Form/Layout/FormLayoutColumnTest.php +++ b/tests/Unit/Form/Layout/FormLayoutColumnTest.php @@ -14,15 +14,84 @@ $formTab->withField('name'); expect($formTab->toArray()['fields']) - ->toHaveCount(1); + ->toEqual([[ + ['key' => 'name', 'size' => 12], + ]]); +}); + +it('allows to add a field with a specific size', function () { + $formTabLegacy = new FormLayoutColumn(2); + $formTabLegacy->withField('name|4'); + + expect($formTabLegacy->toArray()['fields']) + ->toEqual([[ + ['key' => 'name', 'size' => 4], + ]]); }); -it('allows to add multiple fields', function () { +it('allows to add multiple fields with default size', function () { + $formTab2 = new FormLayoutColumn(2); + $formTab2->withFields('name', 'age'); + + expect($formTab2->toArray()['fields'][0]) + ->toEqual([ + ['key' => 'name', 'size' => 6], + ['key' => 'age', 'size' => 6], + ]); + + $formTab3 = new FormLayoutColumn(2); + $formTab3->withFields('name', 'age', 'weight'); + + expect($formTab3->toArray()['fields'][0]) + ->toEqual([ + ['key' => 'name', 'size' => 4], + ['key' => 'age', 'size' => 4], + ['key' => 'weight', 'size' => 4], + ]); + + $formTab4 = new FormLayoutColumn(2); + $formTab4->withFields('name', 'age', 'weight', 'height'); + + expect($formTab4->toArray()['fields'][0]) + ->toEqual([ + ['key' => 'name', 'size' => 3], + ['key' => 'age', 'size' => 3], + ['key' => 'weight', 'size' => 3], + ['key' => 'height', 'size' => 3], + ]); + + $formTab6 = new FormLayoutColumn(2); + $formTab6->withFields('name', 'age', 'weight', 'height', 'gender', 'eyes'); + + expect($formTab6->toArray()['fields'][0]) + ->toEqual([ + ['key' => 'name', 'size' => 2], + ['key' => 'age', 'size' => 2], + ['key' => 'weight', 'size' => 2], + ['key' => 'height', 'size' => 2], + ['key' => 'gender', 'size' => 2], + ['key' => 'eyes', 'size' => 2], + ]); +}); + +it('allows to add multiple fields with specific size', function () { $formTab = new FormLayoutColumn(2); - $formTab->withFields('name', 'age'); + $formTab->withFields(name: 4, age: 8); expect($formTab->toArray()['fields'][0]) - ->toHaveCount(2); + ->toEqual([ + ['key' => 'name', 'size' => 4], + ['key' => 'age', 'size' => 8], + ]); + + $formTabLegacy = new FormLayoutColumn(2); + $formTabLegacy->withFields('name|4', 'age|8'); + + expect($formTabLegacy->toArray()['fields'][0]) + ->toEqual([ + ['key' => 'name', 'size' => 4], + ['key' => 'age', 'size' => 8], + ]); }); it('allows to insert a field', function () { diff --git a/tests/Unit/Form/Layout/FormLayoutFieldTest.php b/tests/Unit/Form/Layout/FormLayoutFieldTest.php index 2248a6414..6d408207c 100644 --- a/tests/Unit/Form/Layout/FormLayoutFieldTest.php +++ b/tests/Unit/Form/Layout/FormLayoutFieldTest.php @@ -9,7 +9,7 @@ ->toEqual('name'); }); -it('allows to set a general size', function () { +it('allows to define a size', function () { $formTab = new FormLayoutField('name|6'); expect($formTab->toArray())