Skip to content

Commit b8f56d2

Browse files
Introduce SuggestionElement (#305)
Requires Icinga/ipl-html#148
1 parent 706e8c2 commit b8f56d2

4 files changed

Lines changed: 129 additions & 2 deletions

File tree

asset/css/compat.less

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,15 @@ form.icinga-form .control-group {
9292
}
9393
}
9494

95+
// suggestion-element style
96+
form.icinga-form .suggestion-element-group {
97+
flex: 1 1 auto;
98+
99+
.suggestion-element {
100+
border-radius: 0 0.25em 0.25em 0;
101+
}
102+
}
103+
95104
.module-icingadb {
96105
// Icinga DB Web (legacy) table header layout (e.g. in group details)
97106
> .controls {

asset/css/suggestion-element.less

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.suggestion-element-group {
2+
display: inline-flex;
3+
4+
.suggestion-element,
5+
.suggestion-element-icon {
6+
line-height: normal;
7+
height: 2.25em;
8+
padding: 0.5em;
9+
background-color: var(--default-input-bg, @default-input-bg);
10+
color: var(--default-text-color, @default-text-color);
11+
}
12+
13+
.suggestion-element {
14+
border: none;
15+
outline: none;
16+
border-radius: 0 0.25em 0.25em 0;
17+
}
18+
19+
.suggestion-element-icon {
20+
padding-right: 0;
21+
border-radius: 0.25em 0 0 0.25em;
22+
}
23+
24+
&:focus-within {
25+
border-radius: 0.25em;
26+
outline: 3px solid var(--default-input-outline-color, @default-input-outline-color);
27+
outline-offset: 1px;
28+
}
29+
}

asset/css/variables.less

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
@default-text-color-inverted: @default-bg;
4343
@default-input-bg: #404d72;
4444
@default-input-hover-bg: #434374;
45+
@default-input-outline-color: @base-primary-light;
4546
@default-remove-bg: @state-critical;
4647
@default-remove-color: @default-text-color-inverted;
4748
@default-delete-bg: @state-critical;
@@ -123,7 +124,7 @@
123124
@schedule-element-fields-selected-bg: @primary-button-bg;
124125
@schedule-element-fields-selected-color: @default-text-color-inverted;
125126
@schedule-element-fields-hover-bg: @base-primary-light;
126-
@schedule-element-fields-outline-color: fade(@base-primary-bg, 50%);
127+
@schedule-element-fields-outline-color: @default-input-outline-color;
127128
@schedule-element-fields-selected-outline-color: fade(#fff, 50%);
128129
@schedule-element-fields-selected-hover-bg: @primary-button-hover-bg;
129130
@schedule-element-fields-disabled-color: @base-gray;
@@ -152,6 +153,7 @@
152153
--default-text-color-inverted: #F5F9FA;
153154
--default-input-bg: #DEECF1;
154155
--default-input-hover-bg: #C0CCCD;
156+
--default-input-outline-color: @base-primary-light;
155157
--default-remove-bg: var(--base-remove-bg);
156158
--default-remove-color: var(--default-text-color-inverted);
157159
--default-delete-bg: var(--base-remove-bg);
@@ -219,7 +221,7 @@
219221
--schedule-element-fields-selected-bg: var(--primary-button-bg);
220222
--schedule-element-fields-selected-color: var(--default-text-color-inverted);
221223
--schedule-element-fields-hover-bg: @base-primary-light;
222-
--schedule-element-fields-outline-color: fade(@base-primary-bg, 50%);
224+
--schedule-element-fields-outline-color: @default-input-outline-color;
223225
--schedule-element-fields-selected-outline-color: fade(#fff, 50%);
224226
--schedule-element-fields-selected-hover-bg: var(--primary-button-hover-bg);
225227
--schedule-element-fields-disabled-color: var(--base-gray);
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
namespace ipl\Web\FormElement;
4+
5+
use ipl\Html\Attributes;
6+
use ipl\Html\FormElement\TextElement;
7+
use ipl\Html\HtmlDocument;
8+
use ipl\Html\HtmlElement;
9+
use ipl\Web\Url;
10+
use ipl\Web\Widget\Icon;
11+
12+
class SuggestionElement extends TextElement
13+
{
14+
protected $defaultAttributes = [
15+
'autocomplete' => 'off',
16+
'class' => 'suggestion-element',
17+
'data-enrichment-type' => 'completion'
18+
];
19+
20+
/** @var Url URL to fetch suggestions from */
21+
protected Url $suggestionsUrl;
22+
23+
/**
24+
* Create a new SuggestionElement
25+
*
26+
* @param string $name Name of the form element
27+
* @param Url $suggestionsUrl URL to fetch suggestions from
28+
* @param ?(array|Attributes) $attributes Attributes of the form element
29+
*/
30+
public function __construct(string $name, Url $suggestionsUrl, array|Attributes $attributes = null)
31+
{
32+
parent::__construct($name, $attributes);
33+
34+
$this->setSuggestionsUrl($suggestionsUrl);
35+
}
36+
37+
/**
38+
* Get the URL to fetch suggestions from
39+
*
40+
* @return Url
41+
*/
42+
public function getSuggestionsUrl(): Url
43+
{
44+
return $this->suggestionsUrl;
45+
}
46+
47+
/**
48+
* Set the URL to fetch suggestions from
49+
*
50+
* @param Url $suggestionsUrl
51+
*
52+
* @return $this
53+
*/
54+
public function setSuggestionsUrl(Url $suggestionsUrl): static
55+
{
56+
$this->suggestionsUrl = $suggestionsUrl;
57+
58+
return $this;
59+
}
60+
61+
/**
62+
* @return string If not set, returns a default placeholder
63+
*/
64+
public function getPlaceholder(): string
65+
{
66+
return $this->placeholder ?? $this->translate('Start typing to see suggestions…');
67+
}
68+
69+
protected function assemble(): void
70+
{
71+
$suggestionsId = uniqid('search-suggestions-');
72+
73+
$this->prependWrapper(
74+
new HtmlElement(
75+
'div',
76+
new Attributes(['class' => 'suggestion-element-group']),
77+
new HtmlElement('div', new Attributes(['id' => $suggestionsId, 'class' => 'search-suggestions'])),
78+
new HtmlElement('span', new Attributes(['class' => 'suggestion-element-icon']), new Icon('search'))
79+
)
80+
);
81+
82+
$this->getAttributes()->add([
83+
'data-term-suggestions' => '#' . $suggestionsId,
84+
'data-suggest-url' => $this->getSuggestionsUrl()
85+
]);
86+
}
87+
}

0 commit comments

Comments
 (0)