Skip to content

Commit d3870fe

Browse files
committed
Added SearchResult DTO
1 parent 78170db commit d3870fe

File tree

4 files changed

+86
-28
lines changed

4 files changed

+86
-28
lines changed

README.md

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class ProductResource
137137
```php
138138

139139
use DefStudio\SearchableInput\Forms\Components\SearchableInput;
140+
use DefStudio\SearchableInput\DTO\SearchResult;
140141

141142
class ProductResource
142143
{
@@ -149,32 +150,24 @@ class ProductResource
149150
return Product::query()
150151
->where('description', 'like', "%$search%")
151152
->limit(15)
152-
->map(fn(Product $product) => [
153-
'value' => $product->description,
154-
'label' => $product->code . ' - ' . $product->description,
155-
'product_id' => $product->id,
156-
'product_code' => $product->code,
157-
])
153+
->map(fn(Product $product) => SearchResult::make($product->description, "[$product->code] $product->description")
154+
->withData('product_id', $product->id)
155+
->withData('product_code', $product->code)
156+
)
158157
->toArray()
159158

160159
})
161-
->onItemSelected(function(array $item){
162-
/*
163-
* $item = [
164-
* 'value' => // "product description",
165-
* 'label' => //the dropdown label
166-
* 'product_id' => eg. 42
167-
* 'product_code' => eg. "AB0042"
168-
* ]
169-
*/
160+
->onItemSelected(function(SearchResult $item){
161+
$item->value();
162+
$item->label();
163+
$item->get('product_id');
164+
$item->get('product_code');
170165
}),
171166
]);
172167
}
173168
}
174169
```
175170

176-
Note: in order for this to work, each item must have at least a `value` and a `label` key.
177-
178171

179172
## Filament Utility Injection
180173

resources/js/index.js

Whitespace-only changes.

src/DTO/SearchResult.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace DefStudio\SearchableInput\DTO;
4+
5+
use Illuminate\Contracts\Support\Arrayable;
6+
7+
class SearchResult implements Arrayable
8+
{
9+
protected array $data = [];
10+
11+
public function __construct(
12+
protected string $value,
13+
protected string $label,
14+
) {
15+
}
16+
17+
public static function make(string $value, string $label = null): self
18+
{
19+
return new static($value, $label ?? $value);
20+
}
21+
22+
public function withData(string|array $key, string $value): self
23+
{
24+
if (is_array($key)) {
25+
$this->data = $key;
26+
return $this;
27+
}
28+
29+
data_set($this->data, $key, $value);
30+
return $this;
31+
}
32+
33+
public function value(): string
34+
{
35+
return $this->value;
36+
}
37+
38+
public function label(): string
39+
{
40+
return $this->label;
41+
}
42+
43+
public function get(string $key, mixed $default = null): array
44+
{
45+
return data_get($this->data, $key, $default);
46+
}
47+
48+
public static function fromArray(array $item): self
49+
{
50+
$dto = new static($item['value'], $item['label'] ?? $item['value']);
51+
$dto->data = $item['data'] ?? [];
52+
53+
return $dto;
54+
}
55+
56+
public function toArray(): array
57+
{
58+
return [
59+
'value' => $this->value,
60+
'label' => $this->label,
61+
];
62+
}
63+
}

src/Forms/Components/SearchableInput.php

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
namespace DefStudio\SearchableInput\Forms\Components;
44

55
use Closure;
6+
use DefStudio\SearchableInput\DTO\SearchResult;
67
use Filament\Forms\Components\Actions\Action;
78
use Filament\Forms\Components\TextInput;
89

910
class SearchableInput extends TextInput
1011
{
11-
/** @var ?Closure(string): ?array<int|string, string|array{label: string, value: string}> */
12+
/** @var ?Closure(string): ?array<int|string, string|SearchResult> */
1213
protected ?Closure $searchUsing = null;
1314

14-
/** @var ?Closure(array{label: string, value: string}>:): void */
15+
/** @var ?Closure(SearchResult $item): void */
1516
protected ?Closure $onItemSelected = null;
1617

1718
/** @var array<array-key, string>|Closure(): ?array<array-key, string>|null */
@@ -43,16 +44,11 @@ protected function setUp(): void
4344
if (collect($results)->every(fn ($item) => is_string($item))) {
4445
if (array_is_list($results)) {
4546
$results = collect($results)
46-
->map(fn ($item) => [
47-
'value' => $item,
48-
'label' => $item,
49-
])->toArray();
47+
->map(fn ($item) => SearchResult::make($item))
48+
->toArray();
5049
} else {
5150
$results = collect($results)
52-
->map(fn ($item, $key) => [
53-
'value' => $key,
54-
'label' => $item,
55-
])->toArray();
51+
->map(fn ($item, $key) => SearchResult::make($key, $item))->toArray();
5652
}
5753
}
5854

@@ -61,7 +57,7 @@ protected function setUp(): void
6157

6258
Action::make('item_selected')->action(function ($arguments) {
6359
$this->evaluate($this->onItemSelected, [
64-
'item' => $arguments['item'],
60+
'item' => SearchResult::make($arguments['item']),
6561
]);
6662
}),
6763
]);
@@ -85,13 +81,19 @@ public function options(array | Closure | null $options): static
8581
return $this;
8682
}
8783

84+
/**
85+
* @param ?Closure(string): ?array<int|string, string|SearchResult> $searchUsing
86+
*/
8887
public function searchUsing(?Closure $searchUsing): static
8988
{
9089
$this->searchUsing = $searchUsing;
9190

9291
return $this;
9392
}
9493

94+
/**
95+
* @param ?Closure(SearchResult $item): void $callback
96+
*/
9597
public function onItemSelected(?Closure $callback): static
9698
{
9799
$this->onItemSelected = $callback;

0 commit comments

Comments
 (0)