Skip to content

Commit

Permalink
Fix auto layout, allow new variadic layout API
Browse files Browse the repository at this point in the history
  • Loading branch information
dvlpp committed Nov 26, 2024
1 parent 029dd9c commit 907a047
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 47 deletions.
2 changes: 1 addition & 1 deletion demo/app/Sharp/Posts/PostForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
Expand Down
6 changes: 3 additions & 3 deletions demo/app/Sharp/Posts/PostShow.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
})
Expand Down
39 changes: 25 additions & 14 deletions docs/guide/building-form.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down
35 changes: 30 additions & 5 deletions src/Form/Layout/HasFieldRows.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Closure;
use Code16\Sharp\Utils\Layout\LayoutField;
use Illuminate\Support\Collection;
use Illuminate\Support\Traits\Conditionable;

trait HasFieldRows
Expand All @@ -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;
Expand All @@ -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(),
);
Expand 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(),
]);
Expand Down Expand Up @@ -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();
}
}
7 changes: 1 addition & 6 deletions src/Show/Layout/ShowLayoutColumn.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
24 changes: 11 additions & 13 deletions src/Utils/Layout/LayoutField.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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]
Expand Down
77 changes: 73 additions & 4 deletions tests/Unit/Form/Layout/FormLayoutColumnTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/Form/Layout/FormLayoutFieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down

0 comments on commit 907a047

Please sign in to comment.