diff --git a/source/php/Component/Select/Select.php b/source/php/Component/Select/Select.php
index d35dd03d..1b21117d 100644
--- a/source/php/Component/Select/Select.php
+++ b/source/php/Component/Select/Select.php
@@ -4,6 +4,8 @@
class Select extends \ComponentLibrary\Component\BaseController
{
+ public const AUTO_ENABLE_SEARCH_THRESHOLD = 7;
+
public function init()
{
//Extract array for eazy access (fetch only)
@@ -106,6 +108,19 @@ public function init()
}
return $boolean ? false : '';
};
+
+ $this->data = $this->mapSearch($this->data);
+ }
+
+ private function mapSearch(array $data): array {
+
+ if(!isset($data['search']) || is_null($data['search'])) {
+ if(count($data['options']) > static::AUTO_ENABLE_SEARCH_THRESHOLD) {
+ $data['search'] = true;
+ }
+ }
+
+ return $data;
}
private function getIconSize($fieldSize = 'md'): string
diff --git a/source/php/Component/Select/SelectTest.php b/source/php/Component/Select/SelectTest.php
new file mode 100644
index 00000000..f8e0e5cf
--- /dev/null
+++ b/source/php/Component/Select/SelectTest.php
@@ -0,0 +1,68 @@
+assertInstanceOf(Select::class, $select);
+ }
+
+ /**
+ * @testdox auto enables search when options exceed threshold
+ */
+ public function testAutoEnablesSearchWhenOptionsExceedThreshold(): void {
+ $createOption = fn(int $i) => [ 'value' => "option_{$i}", 'label' => "Option {$i}" ];
+ $options = array_map($createOption, range(0, Select::AUTO_ENABLE_SEARCH_THRESHOLD));
+
+ $select = new Select(
+ static::getData(['options' => $options]),
+ static::createCache(),
+ static::createTagSanitizer()
+ );
+
+ $this->assertTrue($select->getData()['search']);
+ }
+
+ static function getData(array $merge = []): array {
+ return array_merge([
+ 'size' => 'md',
+ 'options' => [],
+ 'preselected' => false
+ ], $merge);
+ }
+
+ private static function createCache():CacheInterface {
+ return new class implements CacheInterface {
+ public function get(string $key, ?string $group = null): mixed
+ {
+ return null;
+ }
+ public function set(string $key, mixed $data, ?string $group = null): void
+ {
+ }
+ };
+ }
+
+ private static function createTagSanitizer() {
+ return new class implements TagSanitizerInterface{
+ public function removeATags(string $string): string
+ {
+ return $string;
+ }
+ };
+ }
+}
+
\ No newline at end of file
diff --git a/source/php/Component/Select/partials/action.blade.php b/source/php/Component/Select/partials/action.blade.php
index 969fe7e4..0ecd2c83 100644
--- a/source/php/Component/Select/partials/action.blade.php
+++ b/source/php/Component/Select/partials/action.blade.php
@@ -1,5 +1,5 @@
-
- {{ $placeholder && $isMultiSelect ? $placeholder : '' }}
-
+
+ {{ $placeholder && $isMultiSelect ? $placeholder : '' }}
+
\ No newline at end of file
diff --git a/source/php/Component/Select/partials/dropdown.blade.php b/source/php/Component/Select/partials/dropdown.blade.php
index a8d59eb8..c70359b0 100644
--- a/source/php/Component/Select/partials/dropdown.blade.php
+++ b/source/php/Component/Select/partials/dropdown.blade.php
@@ -5,4 +5,5 @@
@include('Select.partials.dropdown_item')
@endforeach
+ @includeWhen($search, 'Select.partials.searchNoResults')
\ No newline at end of file
diff --git a/source/php/Component/Select/partials/search.blade.php b/source/php/Component/Select/partials/search.blade.php
new file mode 100644
index 00000000..0f8d8314
--- /dev/null
+++ b/source/php/Component/Select/partials/search.blade.php
@@ -0,0 +1,8 @@
+@field([
+ 'type' => 'search',
+ 'icon' => ['icon' => 'search'],
+ 'placeholder' => "Search",
+ 'classList' => [ $baseClass . '__search-field' ],
+ 'attributeList' => [ 'data-js-select-search-input' => true ],
+ 'size' => 'sm',
+]) @endfield
\ No newline at end of file
diff --git a/source/php/Component/Select/partials/searchNoResults.blade.php b/source/php/Component/Select/partials/searchNoResults.blade.php
new file mode 100644
index 00000000..03462496
--- /dev/null
+++ b/source/php/Component/Select/partials/searchNoResults.blade.php
@@ -0,0 +1,7 @@
+@typography([
+ 'element' => 'div',
+ 'classList' => [ $baseClass . '__search-no-results' ],
+ 'attributeList' => ['aria-hidden' => 'true']
+])
+ {{ $searchNoResultsText }}
+@endtypography
diff --git a/source/php/Component/Select/select.blade.php b/source/php/Component/Select/select.blade.php
index 71eb8764..6aa18d38 100644
--- a/source/php/Component/Select/select.blade.php
+++ b/source/php/Component/Select/select.blade.php
@@ -53,6 +53,7 @@
@includeWhen($clearButtonEnabled, 'Select.partials.clear')
@include('Select.partials.action')
+ @includeWhen($search, 'Select.partials.search')
@include('Select.partials.dropdown')
@include('Select.partials.error')
diff --git a/source/php/Component/Select/select.json b/source/php/Component/Select/select.json
index bf127fe2..d32cb305 100644
--- a/source/php/Component/Select/select.json
+++ b/source/php/Component/Select/select.json
@@ -16,7 +16,9 @@
"size": "md",
"maxSelections": false,
"hidePlaceholder": false,
- "selectAttributeList": []
+ "selectAttributeList": [],
+ "search": null,
+ "searchNoResultsText": "No results found"
},
"description": {
"label": "The placeholder of the dropdown",
@@ -33,7 +35,9 @@
"size": "The size of the select component (sm, md, lg)",
"maxSelections": "The maximum number of selections allowed. Will only be applied if \"multiple\" is true.",
"hidePlaceholder": "Hides the placeholder but keeps the label",
- "selectAttributeList": "Ann array with attributes that will be set on the actual select element."
+ "selectAttributeList": "Ann array with attributes that will be set on the actual select element.",
+ "search": "Enables a search input within the select dropdown.",
+ "searchNoResultsText": "The text to show when no results are found in the search."
},
"view": "select.blade.php",
"dependency": {